Skip to content

Commit

Permalink
Merge pull request #1938 from o1-labs/fix/update-network-id
Browse files Browse the repository at this point in the history
Deprecate 'testnet' network id in favor of 'devnet'
  • Loading branch information
hattyhattington17 authored Jan 7, 2025
2 parents 4e4692b + f9ab3ab commit f7d522e
Show file tree
Hide file tree
Showing 22 changed files with 491 additions and 37 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm

- Compiling stuck in the browser for recursive zkprograms https://github.com/o1-labs/o1js/pull/1906
- Error message in `rangeCheck16` gadget https://github.com/o1-labs/o1js/pull/1920
- Deprecate `testnet` `networkId` in favor of `devnet` https://github.com/o1-labs/o1js/pull/1938

## [2.1.0](https://github.com/o1-labs/o1js/compare/b04520d...e1bac02) - 2024-11-13

Expand Down
4 changes: 2 additions & 2 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion generate-keys.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env node
import Client from './dist/node/mina-signer/mina-signer.js';

let client = new Client({ network: 'testnet' });
let client = new Client({ network: 'devnet' });

console.log(client.genKeys());
2 changes: 1 addition & 1 deletion src/lib/mina/local-blockchain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ async function LocalBlockchain({
const originalProofsEnabled = proofsEnabled;

return {
getNetworkId: () => 'testnet' as NetworkId,
getNetworkId: () => 'devnet' as NetworkId,
proofsEnabled,
getNetworkConstants() {
return {
Expand Down
2 changes: 1 addition & 1 deletion src/lib/mina/mina-instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ let activeInstance: Mina = {
fetchActions: noActiveInstance,
getActions: noActiveInstance,
proofsEnabled: true,
getNetworkId: () => 'testnet',
getNetworkId: () => 'devnet',
};

/**
Expand Down
2 changes: 1 addition & 1 deletion src/lib/mina/mina.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ function Network(
}
| string
): Mina {
let minaNetworkId: NetworkId = 'testnet';
let minaNetworkId: NetworkId = 'devnet';
let minaGraphqlEndpoint: string;
let archiveEndpoint: string;
let lightnetAccountManagerEndpoint: string;
Expand Down
3 changes: 2 additions & 1 deletion src/lib/mina/token/forest-iterator.unit-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
import assert from 'assert';
import { Field, Bool } from '../../provable/wrapped.js';
import { PublicKey } from '../../provable/crypto/signature.js';
import { NetworkId } from '../../../mina-signer/index.js';

// RANDOM NUMBER GENERATORS for account updates

Expand Down Expand Up @@ -56,7 +57,7 @@ test.custom({ timeBudget: 1000 })(
(flatUpdatesBigint) => {
// reference: bigint callforest hash from mina-signer
let forestBigint = accountUpdatesToCallForest(flatUpdatesBigint);
let expectedHash = callForestHash(forestBigint, 'testnet');
let expectedHash = callForestHash(forestBigint, 'devnet');

let flatUpdates = flatUpdatesBigint.map(accountUpdateFromBigint);
let forest = AccountUpdateForest.fromFlatArray(flatUpdates);
Expand Down
10 changes: 5 additions & 5 deletions src/lib/provable/crypto/signature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -266,22 +266,22 @@ class Signature extends CircuitValue {
let publicKey = PublicKey.fromPrivateKey(privKey).toGroup();
let d = privKey.s;

// we chose an arbitrary prefix for the signature, and it happened to be 'testnet'
// we chose an arbitrary prefix for the signature
// there's no consequences in practice and the signatures can be used with any network
// if there needs to be a custom nonce, include it in the message itself
let kPrime = Scalar.from(
deriveNonce(
{ fields: msg.map((f) => f.toBigInt()) },
{ x: publicKey.x.toBigInt(), y: publicKey.y.toBigInt() },
d.toBigInt(),
'testnet'
'devnet'
)
);

let { x: r, y: ry } = Group.generator.scale(kPrime);
let k = ry.isOdd().toBoolean() ? kPrime.neg() : kPrime;
let h = hashWithPrefix(
signaturePrefix('testnet'),
signaturePrefix('devnet'),
msg.concat([publicKey.x, publicKey.y, r])
);
let e = Scalar.fromField(h);
Expand All @@ -296,11 +296,11 @@ class Signature extends CircuitValue {
verify(publicKey: PublicKey, msg: Field[]): Bool {
let point = publicKey.toGroup();

// we chose an arbitrary prefix for the signature, and it happened to be 'testnet'
// we chose an arbitrary prefix for the signature
// there's no consequences in practice and the signatures can be used with any network
// if there needs to be a custom nonce, include it in the message itself
let h = hashWithPrefix(
signaturePrefix('testnet'),
signaturePrefix('devnet'),
msg.concat([point.x, point.y, this.r])
);

Expand Down
4 changes: 2 additions & 2 deletions src/mina-signer/mina-signer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ class Client {
*/
signFields(fields: bigint[], privateKey: Json.PrivateKey): Signed<bigint[]> {
let privateKey_ = PrivateKey.fromBase58(privateKey);
let signature = sign({ fields }, privateKey_, 'testnet');
let signature = sign({ fields }, privateKey_, 'devnet');
return {
signature: Signature.toBase58(signature),
publicKey: PublicKey.toBase58(PrivateKey.toPublicKey(privateKey_)),
Expand All @@ -172,7 +172,7 @@ class Client {
Signature.fromBase58(signature),
{ fields: data },
PublicKey.fromBase58(publicKey),
'testnet'
'devnet'
);
}

Expand Down
2 changes: 1 addition & 1 deletion src/mina-signer/src/random-transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ const RandomTransaction = {
zkappCommand,
zkappCommandAndFeePayerKey,
zkappCommandJson,
networkId: Random.oneOf<NetworkId[]>('testnet', 'mainnet', {
networkId: Random.oneOf<NetworkId[]>('testnet', 'mainnet', 'devnet', {
custom: 'other',
}),
accountUpdateWithCallDepth: accountUpdate,
Expand Down
16 changes: 14 additions & 2 deletions src/mina-signer/src/sign-legacy.unit-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@ import { RandomTransaction } from './random-transaction.js';
import { NetworkId } from './types.js';

let { privateKey, publicKey } = keypair;
let networks: NetworkId[] = ['testnet', 'mainnet'];
let networks: NetworkId[] = ['devnet', 'testnet', 'mainnet'];

// test hard-coded cases against reference signature

for (let network of networks) {
let i = 0;
let reference = signatures[NetworkId.toString(network)];
let reference = NetworkId.toString(network) === 'testnet'
? signatures['devnet']
: signatures[NetworkId.toString(network)];

for (let payment of payments) {
let signature = signPayment(payment, privateKey, network);
Expand Down Expand Up @@ -73,16 +75,26 @@ test(
verifyPayment(payment, sig, publicKey, network);

// valid signatures & verification matrix
let devnet = signPayment(payment, privateKey, 'devnet');
let testnet = signPayment(payment, privateKey, 'testnet');
let mainnet = signPayment(payment, privateKey, 'mainnet');
assert(verify(devnet, 'testnet') === true);
assert(verify(testnet, 'devnet') === true);

assert(verify(testnet, 'testnet') === true);
assert(verify(testnet, 'mainnet') === false);
assert(verify(mainnet, 'testnet') === false);

assert(verify(devnet, 'devnet') === true);
assert(verify(devnet, 'mainnet') === false);
assert(verify(mainnet, 'devnet') === false);
assert(verify(mainnet, 'mainnet') === true);

// fails when signing with wrong private key
let testnetWrong = signPayment(payment, otherKey, 'testnet');
let devnetWrong = signPayment(payment, otherKey, 'devnet');
let mainnetWrong = signPayment(payment, otherKey, 'mainnet');
assert(verify(devnetWrong, 'devnet') === false);
assert(verify(testnetWrong, 'testnet') === false);
assert(verify(mainnetWrong, 'mainnet') === false);
}
Expand Down
16 changes: 16 additions & 0 deletions src/mina-signer/src/sign-zkapp-command.unit-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,12 @@ test(
expect(hash).toEqual(hashSnarky.toBigInt());

// check against different network hash
expect(hash).not.toEqual(
accountUpdateHash(
accountUpdate,
NetworkId.toString(networkId) === 'mainnet' ? 'devnet' : 'mainnet'
)
);
expect(hash).not.toEqual(
accountUpdateHash(
accountUpdate,
Expand Down Expand Up @@ -262,6 +268,9 @@ test(
expect(
verify(sigFieldElements, networkId === 'mainnet' ? 'testnet' : 'mainnet')
).toEqual(false);
expect(
verify(sigFieldElements, networkId === 'mainnet' ? 'devnet' : 'mainnet')
).toEqual(false);

// full end-to-end test: sign a zkapp transaction
let sig = signZkappCommand(zkappCommandJson, feePayerKeyBase58, networkId);
Expand All @@ -278,6 +287,13 @@ test(
networkId === 'mainnet' ? 'testnet' : 'mainnet'
)
).toEqual(false);
expect(
verifyZkappCommandSignature(
sig,
feePayerAddressBase58,
networkId === 'mainnet' ? 'devnet' : 'mainnet'
)
).toEqual(false);
}
);

Expand Down
9 changes: 6 additions & 3 deletions src/mina-signer/src/signature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export {
};

const networkIdMainnet = 0x01n;
const networkIdTestnet = 0x00n;
const networkIdDevnet = 0x00n;

type Signature = { r: Field; s: Scalar };
type SignatureJson = { field: string; scalar: string };
Expand Down Expand Up @@ -111,7 +111,7 @@ function verifyFieldElement(
* @param privateKey The `privateKey` represents an element of the Pallas scalar field, and should be given as a native bigint.
* It can be converted from the base58 string representation using {@link PrivateKey.fromBase58}.
*
* @param networkId The `networkId` is either "testnet" or "mainnet" and ensures that testnet transactions can
* @param networkId The `networkId` is either "devnet" or "mainnet" and ensures that testnet transactions can
* never be used as valid mainnet transactions.
*
* @see {@link deriveNonce} and {@link hashMessage} for details on how the nonce and hash are computed.
Expand Down Expand Up @@ -331,8 +331,9 @@ function getNetworkIdHashInput(network: NetworkId): [bigint, number] {
switch (s) {
case 'mainnet':
return [networkIdMainnet, 8];
case 'devnet':
case 'testnet':
return [networkIdTestnet, 8];
return [networkIdDevnet, 8];
default:
return networkIdOfString(s);
}
Expand All @@ -356,6 +357,7 @@ const signaturePrefix = (network: NetworkId) => {
switch (s) {
case 'mainnet':
return prefixes.signatureMainnet;
case 'devnet':
case 'testnet':
return prefixes.signatureTestnet;
default:
Expand All @@ -368,6 +370,7 @@ const zkAppBodyPrefix = (network: NetworkId) => {
switch (s) {
case 'mainnet':
return prefixes.zkappBodyMainnet;
case 'devnet':
case 'testnet':
return prefixes.zkappBodyTestnet;
default:
Expand Down
29 changes: 22 additions & 7 deletions src/mina-signer/src/signature.unit-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ function checkConsistentSingle(
// verify
expect(verifyFieldElement(sig, msg, pk, networkId)).toEqual(true);

// verify against different network
// if the signature was generated with networkId=mainnet, the signature should not verify against testnet or devnet
expect(
verifyFieldElement(
sig,
Expand All @@ -42,6 +42,14 @@ function checkConsistentSingle(
networkId === 'mainnet' ? 'testnet' : 'mainnet'
)
).toEqual(false);
expect(
verifyFieldElement(
sig,
msg,
pk,
networkId === 'mainnet' ? 'devnet' : 'mainnet'
)
).toEqual(false);

// consistent with OCaml
let msgMl = FieldConst.fromBigint(msg);
Expand All @@ -56,16 +64,21 @@ function checkConsistentSingle(

// check that various multi-field hash inputs can be verified
function checkCanVerify(msg: HashInput, key: PrivateKey, pk: PublicKey) {
let sigDev = sign(msg, key, 'devnet');
let sigTest = sign(msg, key, 'testnet');
let sigMain = sign(msg, key, 'mainnet');
// verify
let okTestnetTestnet = verify(sigTest, msg, pk, 'testnet');
let okMainnetTestnet = verify(sigMain, msg, pk, 'testnet');
let okTestnetMainnet = verify(sigTest, msg, pk, 'mainnet');
let okTestnetDevnet = verify(sigTest, msg, pk, 'devnet');
let okDevnetTestnet = verify(sigDev, msg, pk, 'testnet');
let okDevnetDevnet = verify(sigDev, msg, pk, 'devnet');
let okMainnetDevnet = verify(sigMain, msg, pk, 'devnet');
let okDevnetMainnet = verify(sigDev, msg, pk, 'mainnet');
let okMainnetMainnet = verify(sigMain, msg, pk, 'mainnet');
expect(okTestnetTestnet).toEqual(true);
expect(okMainnetTestnet).toEqual(false);
expect(okTestnetMainnet).toEqual(false);
expect(okTestnetDevnet).toEqual(true);
expect(okDevnetTestnet).toEqual(true);
expect(okDevnetDevnet).toEqual(true);
expect(okMainnetDevnet).toEqual(false);
expect(okDevnetMainnet).toEqual(false);
expect(okMainnetMainnet).toEqual(true);
}

Expand Down Expand Up @@ -105,13 +118,15 @@ for (let i = 0; i < 10; i++) {
// hard coded single field elements
let hardcoded = [0n, 1n, 2n, p - 1n];
for (let x of hardcoded) {
checkConsistentSingle(x, key, keySnarky, publicKey, 'devnet');
checkConsistentSingle(x, key, keySnarky, publicKey, 'testnet');
checkConsistentSingle(x, key, keySnarky, publicKey, 'mainnet');
checkConsistentSingle(x, key, keySnarky, publicKey, { custom: 'other' });
}
// random single field elements
for (let i = 0; i < 10; i++) {
let x = randomFields[i];
checkConsistentSingle(x, key, keySnarky, publicKey, 'devnet');
checkConsistentSingle(x, key, keySnarky, publicKey, 'testnet');
checkConsistentSingle(x, key, keySnarky, publicKey, 'mainnet');
checkConsistentSingle(x, key, keySnarky, publicKey, { custom: 'other' });
Expand Down
2 changes: 1 addition & 1 deletion src/mina-signer/src/test-vectors/legacySignatures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ let strings = [
* - the 3 strings.
*/
let signatures: { [k: string]: { field: string; scalar: string }[] } = {
testnet: [
devnet: [
{
field:
'3925887987173883783388058255268083382298769764463609405200521482763932632383',
Expand Down
4 changes: 3 additions & 1 deletion src/mina-signer/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ export type Field = number | bigint | string;
export type PublicKey = string;
export type PrivateKey = string;
export type Signature = SignatureJson;
export type NetworkId = 'mainnet' | 'testnet' | { custom: string };

// testnet is deprecated in favor of devnet
export type NetworkId = 'mainnet' | 'devnet' | 'testnet' | { custom: string };

export const NetworkId = {
toString(network: NetworkId) {
Expand Down
7 changes: 6 additions & 1 deletion src/mina-signer/tests/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@ describe('Client Class Initialization', () => {
expect(client).toBeDefined();
});

it('should throw an error if a value that is not `mainnet` or `testnet` is specified', () => {
it('should accept `devnet` as a valid network parameter', () => {
client = new Client({ network: 'devnet' });
expect(client).toBeDefined();
});

it('should throw an error if a value that is not `mainnet`, `devnet`, or `testnet` is specified', () => {
try {
//@ts-ignore
client = new Client({ network: 'new-network' });
Expand Down
Loading

0 comments on commit f7d522e

Please sign in to comment.