Skip to content

Commit

Permalink
Merge pull request #1387 from o1-labs/mainnet-support
Browse files Browse the repository at this point in the history
(WIP) Add support for mainnet.
  • Loading branch information
shimkiv authored Jan 29, 2024
2 parents f60ef63 + e5d1e0f commit a165821
Show file tree
Hide file tree
Showing 13 changed files with 79 additions and 40 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- Improve performance of Field inverse https://github.com/o1-labs/o1js/pull/1373
- Speeds up proving by ~2-4%

### Added

- Target `network ID` configuration. https://github.com/o1-labs/o1js/pull/1387
- Defaults to the `testnet` (as it was before).

## [0.15.3](https://github.com/o1-labs/o1js/compare/1ad7333e9e...be748e42e)

### Breaking changes
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "o1js",
"description": "TypeScript framework for zk-SNARKs and zkApps",
"version": "0.15.3",
"version": "0.15.4",
"license": "Apache-2.0",
"homepage": "https://github.com/o1-labs/o1js/",
"keywords": [
Expand Down
4 changes: 2 additions & 2 deletions src/lib/account_update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1934,7 +1934,7 @@ function addMissingSignatures(
let signature = signFieldElement(
fullCommitment,
privateKey.toBigInt(),
'testnet'
Mina.getNetworkId()
);
return { body, authorization: Signature.toBase58(signature) };
}
Expand Down Expand Up @@ -1967,7 +1967,7 @@ function addMissingSignatures(
let signature = signFieldElement(
transactionCommitment,
privateKey.toBigInt(),
'testnet'
Mina.getNetworkId()
);
Authorization.setSignature(accountUpdate, Signature.toBase58(signature));
return accountUpdate as AccountUpdate & { lazyAuthorization: undefined };
Expand Down
71 changes: 47 additions & 24 deletions src/lib/mina.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import {
transactionCommitments,
verifyAccountUpdateSignature,
} from '../mina-signer/src/sign-zkapp-command.js';
import { NetworkId } from '../mina-signer/src/TSTypes.js';

export {
createTransaction,
Expand All @@ -51,6 +52,7 @@ export {
getAccount,
hasAccount,
getBalance,
getNetworkId,
getNetworkConstants,
getNetworkState,
accountCreationFee,
Expand All @@ -65,7 +67,7 @@ export {
getProofsEnabled,
// for internal testing only
filterGroups,
type NetworkConstants
type NetworkConstants,
};

interface TransactionId {
Expand Down Expand Up @@ -374,6 +376,7 @@ interface Mina {
tokenId?: Field
) => { hash: string; actions: string[][] }[];
proofsEnabled: boolean;
getNetworkId(): NetworkId;
}

const defaultAccountCreationFee = 1_000_000_000;
Expand All @@ -389,12 +392,14 @@ const defaultNetworkConstants: NetworkConstants = {
function LocalBlockchain({
proofsEnabled = true,
enforceTransactionLimits = true,
networkId = 'testnet' as NetworkId,
} = {}) {
const slotTime = 3 * 60 * 1000;
const startTime = Date.now();
const genesisTimestamp = UInt64.from(startTime);
const ledger = Ledger.create();
let networkState = defaultNetworkState();
let minaNetworkId: NetworkId = networkId;

function addAccount(publicKey: PublicKey, balance: string) {
ledger.addAccount(Ml.fromPublicKey(publicKey), balance);
Expand All @@ -421,6 +426,7 @@ function LocalBlockchain({
> = {};

return {
getNetworkId: () => minaNetworkId,
proofsEnabled,
/**
* @deprecated use {@link Mina.getNetworkConstants}
Expand Down Expand Up @@ -494,7 +500,8 @@ function LocalBlockchain({
account,
update,
commitments,
this.proofsEnabled
this.proofsEnabled,
this.getNetworkId()
);
}
}
Expand Down Expand Up @@ -689,57 +696,63 @@ LocalBlockchain satisfies (...args: any) => Mina;
* Represents the Mina blockchain running on a real network
*/
function Network(graphqlEndpoint: string): Mina;
function Network(endpoints: {
function Network(options: {
networkId?: NetworkId;
mina: string | string[];
archive?: string | string[];
lightnetAccountManager?: string;
}): Mina;
function Network(
input:
options:
| {
networkId?: NetworkId;
mina: string | string[];
archive?: string | string[];
lightnetAccountManager?: string;
}
| string
): Mina {
let minaNetworkId: NetworkId = 'testnet';
let minaGraphqlEndpoint: string;
let archiveEndpoint: string;
let lightnetAccountManagerEndpoint: string;

if (input && typeof input === 'string') {
minaGraphqlEndpoint = input;
if (options && typeof options === 'string') {
minaGraphqlEndpoint = options;
Fetch.setGraphqlEndpoint(minaGraphqlEndpoint);
} else if (input && typeof input === 'object') {
if (!input.mina)
} else if (options && typeof options === 'object') {
if (options.networkId) {
minaNetworkId = options.networkId;
}
if (!options.mina)
throw new Error(
"Network: malformed input. Please provide an object with 'mina' endpoint."
);
if (Array.isArray(input.mina) && input.mina.length !== 0) {
minaGraphqlEndpoint = input.mina[0];
if (Array.isArray(options.mina) && options.mina.length !== 0) {
minaGraphqlEndpoint = options.mina[0];
Fetch.setGraphqlEndpoint(minaGraphqlEndpoint);
Fetch.setMinaGraphqlFallbackEndpoints(input.mina.slice(1));
} else if (typeof input.mina === 'string') {
minaGraphqlEndpoint = input.mina;
Fetch.setMinaGraphqlFallbackEndpoints(options.mina.slice(1));
} else if (typeof options.mina === 'string') {
minaGraphqlEndpoint = options.mina;
Fetch.setGraphqlEndpoint(minaGraphqlEndpoint);
}

if (input.archive !== undefined) {
if (Array.isArray(input.archive) && input.archive.length !== 0) {
archiveEndpoint = input.archive[0];
if (options.archive !== undefined) {
if (Array.isArray(options.archive) && options.archive.length !== 0) {
archiveEndpoint = options.archive[0];
Fetch.setArchiveGraphqlEndpoint(archiveEndpoint);
Fetch.setArchiveGraphqlFallbackEndpoints(input.archive.slice(1));
} else if (typeof input.archive === 'string') {
archiveEndpoint = input.archive;
Fetch.setArchiveGraphqlFallbackEndpoints(options.archive.slice(1));
} else if (typeof options.archive === 'string') {
archiveEndpoint = options.archive;
Fetch.setArchiveGraphqlEndpoint(archiveEndpoint);
}
}

if (
input.lightnetAccountManager !== undefined &&
typeof input.lightnetAccountManager === 'string'
options.lightnetAccountManager !== undefined &&
typeof options.lightnetAccountManager === 'string'
) {
lightnetAccountManagerEndpoint = input.lightnetAccountManager;
lightnetAccountManagerEndpoint = options.lightnetAccountManager;
Fetch.setLightnetAccountManagerEndpoint(lightnetAccountManagerEndpoint);
}
} else {
Expand All @@ -749,6 +762,7 @@ function Network(
}

return {
getNetworkId: () => minaNetworkId,
/**
* @deprecated use {@link Mina.getNetworkConstants}
*/
Expand Down Expand Up @@ -1013,6 +1027,7 @@ function BerkeleyQANet(graphqlEndpoint: string) {
}

let activeInstance: Mina = {
getNetworkId: () => 'testnet',
/**
* @deprecated use {@link Mina.getNetworkConstants}
*/
Expand Down Expand Up @@ -1199,6 +1214,13 @@ function hasAccount(publicKey: PublicKey, tokenId?: Field): boolean {
return activeInstance.hasAccount(publicKey, tokenId);
}

/**
* @return The current Mina network ID.
*/
function getNetworkId() {
return activeInstance.getNetworkId();
}

/**
* @return Data associated with the current Mina network constants.
*/
Expand Down Expand Up @@ -1298,7 +1320,8 @@ async function verifyAccountUpdate(
account: Account,
accountUpdate: AccountUpdate,
transactionCommitments: { commitment: bigint; fullCommitment: bigint },
proofsEnabled: boolean
proofsEnabled: boolean,
networkId: NetworkId
): Promise<void> {
// check that that top-level updates have mayUseToken = No
// (equivalent check exists in the Mina node)
Expand Down Expand Up @@ -1406,7 +1429,7 @@ async function verifyAccountUpdate(
isValidSignature = verifyAccountUpdateSignature(
TypesBigint.AccountUpdate.fromJSON(accountUpdateJson),
transactionCommitments,
'testnet'
networkId
);
} catch (error) {
errorTrace += '\n\n' + (error as Error).message;
Expand Down
15 changes: 12 additions & 3 deletions src/mina-signer/MinaSigner.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { PrivateKey, PublicKey } from '../provable/curve-bigint.js';
import * as Json from './src/TSTypes.js';
import type { SignedLegacy, Signed, Network } from './src/TSTypes.js';
import type { SignedLegacy, Signed, NetworkId } from './src/TSTypes.js';

import {
isPayment,
Expand Down Expand Up @@ -39,9 +39,9 @@ export { Client as default };
const defaultValidUntil = '4294967295';

class Client {
private network: Network;
private network: NetworkId; // TODO: Rename to "networkId" for consistency with remaining codebase.

constructor(options: { network: Network }) {
constructor(options: { network: NetworkId }) {
if (!options?.network) {
throw Error('Invalid Specified Network');
}
Expand Down Expand Up @@ -493,6 +493,15 @@ class Client {
let sk = PrivateKey.fromBase58(privateKeyBase58);
return createNullifier(message, sk);
}

/**
* Returns the network ID.
*
* @returns {NetworkId} The network ID.
*/
get networkId(): NetworkId {
return this.network;
}
}

function validNonNegative(n: number | string | bigint): string {
Expand Down
2 changes: 1 addition & 1 deletion src/mina-signer/src/TSTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export type Field = number | bigint | string;
export type PublicKey = string;
export type PrivateKey = string;
export type Signature = SignatureJson;
export type Network = 'mainnet' | 'testnet';
export type NetworkId = 'mainnet' | 'testnet';

export type Keypair = {
readonly privateKey: PrivateKey;
Expand Down
3 changes: 2 additions & 1 deletion src/mina-signer/src/random-transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import {
ZkappCommand,
} from '../../bindings/mina-transaction/gen/transaction-bigint.js';
import { PrivateKey } from '../../provable/curve-bigint.js';
import { NetworkId, Signature } from './signature.js';
import { Signature } from './signature.js';
import { NetworkId } from './TSTypes.js';

export { RandomTransaction };

Expand Down
2 changes: 1 addition & 1 deletion src/mina-signer/src/sign-legacy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import { HashInputLegacy } from '../../provable/poseidon-bigint.js';
import { Memo } from './memo.js';
import {
SignatureJson,
NetworkId,
Signature,
signLegacy,
verifyLegacy,
} from './signature.js';
import { Json } from '../../bindings/mina-transaction/gen/transaction-bigint.js';
import { bytesToBits, stringToBytes } from '../../bindings/lib/binable.js';
import { NetworkId } from './TSTypes.js';

export {
signPayment,
Expand Down
3 changes: 2 additions & 1 deletion src/mina-signer/src/sign-legacy.unit-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ import {
verifyStakeDelegation,
verifyStringSignature,
} from './sign-legacy.js';
import { NetworkId, Signature, SignatureJson } from './signature.js';
import { Signature, SignatureJson } from './signature.js';
import { expect } from 'expect';
import { PublicKey, Scalar } from '../../provable/curve-bigint.js';
import { Field } from '../../provable/field-bigint.js';
import { Random, test } from '../../lib/testing/property.js';
import { RandomTransaction } from './random-transaction.js';
import { NetworkId } from './TSTypes.js';

let { privateKey, publicKey } = keypair;
let networks: NetworkId[] = ['testnet', 'mainnet'];
Expand Down
2 changes: 1 addition & 1 deletion src/mina-signer/src/sign-zkapp-command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ import {
} from '../../provable/poseidon-bigint.js';
import { Memo } from './memo.js';
import {
NetworkId,
Signature,
signFieldElement,
verifyFieldElement,
} from './signature.js';
import { mocks } from '../../bindings/crypto/constants.js';
import { NetworkId } from './TSTypes.js';

// external API
export { signZkappCommand, verifyZkappCommandSignature };
Expand Down
2 changes: 1 addition & 1 deletion src/mina-signer/src/sign-zkapp-command.unit-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ import {
import { packToFields as packToFieldsSnarky } from '../../lib/hash.js';
import { Memo } from './memo.js';
import {
NetworkId,
Signature,
signFieldElement,
verifyFieldElement,
Expand All @@ -44,6 +43,7 @@ import { RandomTransaction } from './random-transaction.js';
import { Ml, MlHashInput } from '../../lib/ml/conversion.js';
import { FieldConst } from '../../lib/field.js';
import { mocks } from '../../bindings/crypto/constants.js';
import { NetworkId } from './TSTypes.js';

// monkey-patch bigint to json
(BigInt.prototype as any).toJSON = function () {
Expand Down
4 changes: 2 additions & 2 deletions src/mina-signer/src/signature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
import { base58 } from '../../lib/base58.js';
import { versionBytes } from '../../bindings/crypto/constants.js';
import { Pallas } from '../../bindings/crypto/elliptic_curve.js';
import { NetworkId } from './TSTypes.js';

export {
sign,
Expand All @@ -35,15 +36,14 @@ export {
verifyFieldElement,
Signature,
SignatureJson,
NetworkId,
signLegacy,
verifyLegacy,
deriveNonce,
};

const networkIdMainnet = 0x01n;
const networkIdTestnet = 0x00n;
type NetworkId = 'mainnet' | 'testnet';

type Signature = { r: Field; s: Scalar };
type SignatureJson = { field: string; scalar: string };

Expand Down

0 comments on commit a165821

Please sign in to comment.