Skip to content

Commit

Permalink
Merge pull request #1367 from o1-labs/use-network-genesis-constants
Browse files Browse the repository at this point in the history
Use actual network genesis constants (genesisTimestamp, slotTime, accountCreationFee).
  • Loading branch information
shimkiv committed Jan 21, 2024
2 parents 659c203 + 18f0d55 commit 4b2f32a
Show file tree
Hide file tree
Showing 17 changed files with 303 additions and 67 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm

## [Unreleased](https://github.com/o1-labs/o1js/compare/08ba27329...HEAD)

### Breaking changes

- `Mina.accountCreationFee()` is deprecated in favor of `Mina.getNetworkConstants().accountCreationFee`. https://github.com/o1-labs/o1js/pull/1367
- `Mina.getNetworkConstants()` returns:
- [default](https://github.com/o1-labs/o1js/pull/1367/files#diff-ef2c3547d64a8eaa8253cd82b3623288f3271e14f1dc893a0a3ddc1ff4b9688fR7) network constants if used outside of the transaction scope.
- [actual](https://github.com/o1-labs/o1js/pull/1367/files#diff-437f2c15df7c90ad8154c5de1677ec0838d51859bcc0a0cefd8a0424b5736f31R1051) network constants if used within the transaction scope.

### Added

- **SHA256 hash function** exposed via `Hash.SHA2_256` or `Gadgets.SHA256`. https://github.com/o1-labs/o1js/pull/1285
Expand Down
9 changes: 9 additions & 0 deletions run-ci-live-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ echo ""
HELLO_WORLD_PROC=$!
./run src/examples/zkapps/dex/run_live.ts --bundle | add_prefix "DEX" &
DEX_PROC=$!
./run src/examples/fetch_live.ts --bundle | add_prefix "FETCH" &
FETCH_PROC=$!

# Wait for each process and capture their exit statuses
FAILURE=0
Expand All @@ -34,6 +36,13 @@ if [ $? -ne 0 ]; then
echo ""
FAILURE=1
fi
wait $FETCH_PROC
if [ $? -ne 0 ]; then
echo ""
echo "FETCH test failed."
echo ""
FAILURE=1
fi

# Exit with failure if any process failed
if [ $FAILURE -ne 0 ]; then
Expand Down
92 changes: 92 additions & 0 deletions src/examples/fetch_live.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { expect } from 'expect';
import { Lightnet, Mina, PrivateKey, UInt64, fetchAccount } from 'o1js';

const useCustomLocalNetwork = process.env.USE_CUSTOM_LOCAL_NETWORK === 'true';
Mina.setActiveInstance(configureMinaNetwork());
const transactionFee = 100_000_000;
let defaultNetworkConstants: Mina.NetworkConstants = {
genesisTimestamp: UInt64.from(0),
slotTime: UInt64.from(3 * 60 * 1000),
accountCreationFee: UInt64.from(1_000_000_000),
};
const { sender } = await configureFeePayer();

await checkDefaultNetworkConstantsFetching();
await checkActualNetworkConstantsFetching();

await tearDown();

async function checkDefaultNetworkConstantsFetching() {
console.log(
'\nCase #1: check that default network constants can be fetched outside of the transaction scope.'
);
const networkConstants = Mina.getNetworkConstants();
expect(defaultNetworkConstants).toEqual(networkConstants);
logNetworkConstants(networkConstants);
}

async function checkActualNetworkConstantsFetching() {
console.log(
'\nCase #2: check that actual network constants can be fetched within the transaction scope.'
);
let networkConstants: Mina.NetworkConstants | undefined;
await Mina.transaction({ sender, fee: transactionFee }, () => {
networkConstants = Mina.getNetworkConstants();
});
expect(networkConstants?.slotTime).not.toBeUndefined();
expect(networkConstants?.genesisTimestamp).not.toBeUndefined();
expect(defaultNetworkConstants).not.toEqual(networkConstants);
logNetworkConstants(networkConstants);
}

function configureMinaNetwork() {
const minaGraphQlEndpoint = useCustomLocalNetwork
? 'http://localhost:8080/graphql'
: 'https://berkeley.minascan.io/graphql';
return Mina.Network({
mina: minaGraphQlEndpoint,
archive: useCustomLocalNetwork
? 'http://localhost:8282'
: 'https://api.minascan.io/archive/berkeley/v1/graphql',
lightnetAccountManager: 'http://localhost:8181',
});
}

async function configureFeePayer() {
const senderKey = useCustomLocalNetwork
? (await Lightnet.acquireKeyPair()).privateKey
: PrivateKey.random();
const sender = senderKey.toPublicKey();
if (!useCustomLocalNetwork) {
console.log(`\nFunding the fee payer account.`);
await Mina.faucet(sender);
}
console.log(`\nFetching the fee payer account information.`);
const accountDetails = (await fetchAccount({ publicKey: sender })).account;
console.log(
`Using the fee payer account ${sender.toBase58()} with nonce: ${
accountDetails?.nonce
} and balance: ${accountDetails?.balance}.`
);
return { sender, senderKey };
}

async function tearDown() {
const keyPairReleaseMessage = await Lightnet.releaseKeyPair({
publicKey: sender.toBase58(),
});
if (keyPairReleaseMessage) console.info('\n' + keyPairReleaseMessage);
}

function logNetworkConstants(
networkConstants: Mina.NetworkConstants | undefined
) {
console.log(`Account creation fee: ${networkConstants?.accountCreationFee}`);
console.log(`Slot time: ${networkConstants?.slotTime}`);
console.log(`Genesis timestamp: ${networkConstants?.genesisTimestamp}`);
console.log(
`Genesis date: ${new Date(
Number(networkConstants?.genesisTimestamp.toString() ?? '0')
)}`
);
}
9 changes: 6 additions & 3 deletions src/examples/zkapps/dex/arbitrary_token_interaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { TokenContract, addresses, keys, tokenIds } from './dex.js';
let doProofs = true;
let Local = Mina.LocalBlockchain({ proofsEnabled: doProofs });
Mina.setActiveInstance(Local);
let accountFee = Mina.accountCreationFee();

let [{ privateKey: userKey, publicKey: userAddress }] = Local.testAccounts;
let tx;
Expand All @@ -26,7 +25,9 @@ console.log('deploy & init token contracts...');
tx = await Mina.transaction(userAddress, () => {
// pay fees for creating 2 token contract accounts, and fund them so each can create 1 account themselves
let feePayerUpdate = AccountUpdate.createSigned(userAddress);
feePayerUpdate.balance.subInPlace(accountFee.mul(1));
feePayerUpdate.balance.subInPlace(
Mina.getNetworkConstants().accountCreationFee.mul(1)
);
tokenX.deploy();
});
await tx.prove();
Expand All @@ -36,7 +37,9 @@ await tx.send();
console.log('arbitrary token minting...');
tx = await Mina.transaction(userAddress, () => {
// pay fees for creating user's token X account
AccountUpdate.createSigned(userAddress).balance.subInPlace(accountFee.mul(1));
AccountUpdate.createSigned(userAddress).balance.subInPlace(
Mina.getNetworkConstants().accountCreationFee.mul(1)
);
// 😈😈😈 mint any number of tokens to our account 😈😈😈
let tokenContract = new TokenContract(addresses.tokenX);
tokenContract.token.mint({
Expand Down
4 changes: 2 additions & 2 deletions src/examples/zkapps/dex/dex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ class TokenContract extends SmartContract {
// assert that the receiving account is new, so this can be only done once
receiver.account.isNew.requireEquals(Bool(true));
// pay fees for opened account
this.balance.subInPlace(Mina.accountCreationFee());
this.balance.subInPlace(Mina.getNetworkConstants().accountCreationFee);
}

/**
Expand All @@ -410,7 +410,7 @@ class TokenContract extends SmartContract {
// assert that the receiving account is new, so this can be only done once
receiver.account.isNew.requireEquals(Bool(true));
// pay fees for opened account
this.balance.subInPlace(Mina.accountCreationFee());
this.balance.subInPlace(Mina.getNetworkConstants().accountCreationFee);
}

// this is a very standardized deploy method. instead, we could also take the account update from a callback
Expand Down
2 changes: 1 addition & 1 deletion src/examples/zkapps/dex/erc20.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class TrivialCoin extends SmartContract implements Erc20 {
// assert that the receiving account is new, so this can be only done once
receiver.account.isNew.requireEquals(Bool(true));
// pay fees for opened account
this.balance.subInPlace(Mina.accountCreationFee());
this.balance.subInPlace(Mina.getNetworkConstants().accountCreationFee);

// since this is the only method of this zkApp that resets the entire state, provedState: true implies
// that this function was run. Since it can be run only once, this implies it was run exactly once
Expand Down
4 changes: 2 additions & 2 deletions src/examples/zkapps/dex/happy-path-with-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ let Local = Mina.LocalBlockchain({
enforceTransactionLimits: true,
});
Mina.setActiveInstance(Local);
let accountFee = Mina.accountCreationFee();
let [{ privateKey: feePayerKey, publicKey: feePayerAddress }] =
Local.testAccounts;
let tx, balances, oldBalances;
Expand All @@ -44,6 +43,7 @@ let dexTokenHolderY = new DexTokenHolder(addresses.dex, tokenIds.Y);

tic('deploy & init token contracts');
tx = await Mina.transaction(feePayerAddress, () => {
const accountFee = Mina.getNetworkConstants().accountCreationFee;
// pay fees for creating 2 token contract accounts, and fund them so each can create 1 account themselves
let feePayerUpdate = AccountUpdate.createSigned(feePayerAddress);
feePayerUpdate.balance.subInPlace(accountFee.mul(2));
Expand All @@ -61,7 +61,7 @@ tic('deploy dex contracts');
tx = await Mina.transaction(feePayerAddress, () => {
// pay fees for creating 3 dex accounts
AccountUpdate.createSigned(feePayerAddress).balance.subInPlace(
accountFee.mul(3)
Mina.getNetworkConstants().accountCreationFee.mul(3)
);
dex.deploy();
dexTokenHolderX.deploy();
Expand Down
4 changes: 2 additions & 2 deletions src/examples/zkapps/dex/happy-path-with-proofs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ let Local = Mina.LocalBlockchain({
enforceTransactionLimits: false,
});
Mina.setActiveInstance(Local);
let accountFee = Mina.accountCreationFee();
let [{ privateKey: feePayerKey, publicKey: feePayerAddress }] =
Local.testAccounts;
let tx, balances, oldBalances;
Expand Down Expand Up @@ -46,6 +45,7 @@ let dexTokenHolderY = new DexTokenHolder(addresses.dex, tokenIds.Y);

tic('deploy & init token contracts');
tx = await Mina.transaction(feePayerAddress, () => {
const accountFee = Mina.getNetworkConstants().accountCreationFee;
// pay fees for creating 2 token contract accounts, and fund them so each can create 1 account themselves
let feePayerUpdate = AccountUpdate.createSigned(feePayerAddress);
feePayerUpdate.balance.subInPlace(accountFee.mul(2));
Expand All @@ -63,7 +63,7 @@ tic('deploy dex contracts');
tx = await Mina.transaction(feePayerAddress, () => {
// pay fees for creating 3 dex accounts
AccountUpdate.createSigned(feePayerAddress).balance.subInPlace(
accountFee.mul(3)
Mina.getNetworkConstants().accountCreationFee.mul(3)
);
dex.deploy();
dexTokenHolderX.deploy();
Expand Down
16 changes: 11 additions & 5 deletions src/examples/zkapps/dex/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ let Local = Mina.LocalBlockchain({
enforceTransactionLimits: false,
});
Mina.setActiveInstance(Local);
let accountFee = Mina.accountCreationFee();
let [{ privateKey: feePayerKey, publicKey: feePayerAddress }] =
Local.testAccounts;
let tx, balances, oldBalances;
Expand Down Expand Up @@ -77,6 +76,7 @@ async function main({ withVesting }: { withVesting: boolean }) {

console.log('deploy & init token contracts...');
tx = await Mina.transaction(feePayerAddress, () => {
const accountFee = Mina.getNetworkConstants().accountCreationFee;
// pay fees for creating 2 token contract accounts, and fund them so each can create 2 accounts themselves
let feePayerUpdate = AccountUpdate.fundNewAccount(feePayerAddress, 2);
feePayerUpdate.send({ to: addresses.tokenX, amount: accountFee.mul(2) });
Expand Down Expand Up @@ -110,7 +110,10 @@ async function main({ withVesting }: { withVesting: boolean }) {

console.log('transfer tokens to user');
tx = await Mina.transaction(
{ sender: feePayerAddress, fee: accountFee.mul(1) },
{
sender: feePayerAddress,
fee: Mina.getNetworkConstants().accountCreationFee.mul(1),
},
() => {
let feePayer = AccountUpdate.fundNewAccount(feePayerAddress, 4);
feePayer.send({ to: addresses.user, amount: 20e9 }); // give users MINA to pay fees
Expand All @@ -133,7 +136,10 @@ async function main({ withVesting }: { withVesting: boolean }) {
// supply the initial liquidity where the token ratio can be arbitrary
console.log('supply liquidity -- base');
tx = await Mina.transaction(
{ sender: feePayerAddress, fee: accountFee },
{
sender: feePayerAddress,
fee: Mina.getNetworkConstants().accountCreationFee,
},
() => {
AccountUpdate.fundNewAccount(feePayerAddress);
dex.supplyLiquidityBase(UInt64.from(10_000), UInt64.from(10_000));
Expand Down Expand Up @@ -437,7 +443,7 @@ async function main({ withVesting }: { withVesting: boolean }) {
);
tx = await Mina.transaction(addresses.user2, () => {
AccountUpdate.createSigned(addresses.user2).balance.subInPlace(
accountFee.mul(2)
Mina.getNetworkConstants().accountCreationFee.mul(2)
);
dex.redeemLiquidity(UInt64.from(USER_DL));
dex.redeemLiquidity(UInt64.from(USER_DL));
Expand All @@ -451,7 +457,7 @@ async function main({ withVesting }: { withVesting: boolean }) {
console.log('user2 redeem liquidity');
tx = await Mina.transaction(addresses.user2, () => {
AccountUpdate.createSigned(addresses.user2).balance.subInPlace(
accountFee.mul(2)
Mina.getNetworkConstants().accountCreationFee.mul(2)
);
dex.redeemLiquidity(UInt64.from(USER_DL));
});
Expand Down
6 changes: 4 additions & 2 deletions src/examples/zkapps/dex/run_live.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ const network = Mina.Network({
lightnetAccountManager: 'http://localhost:8181',
});
Mina.setActiveInstance(network);
let accountFee = Mina.accountCreationFee();

let tx, pendingTx: Mina.TransactionId, balances, oldBalances;

Expand Down Expand Up @@ -74,6 +73,7 @@ let userSpec = { sender: addresses.user, fee: 0.1e9 };
if (successfulTransactions <= 0) {
tic('deploy & init token contracts');
tx = await Mina.transaction(senderSpec, () => {
const accountFee = Mina.getNetworkConstants().accountCreationFee;
// pay fees for creating 2 token contract accounts, and fund them so each can create 1 account themselves
let feePayerUpdate = AccountUpdate.createSigned(sender);
feePayerUpdate.balance.subInPlace(accountFee.mul(2));
Expand All @@ -97,7 +97,9 @@ if (successfulTransactions <= 1) {
tic('deploy dex contracts');
tx = await Mina.transaction(senderSpec, () => {
// pay fees for creating 3 dex accounts
AccountUpdate.createSigned(sender).balance.subInPlace(accountFee.mul(3));
AccountUpdate.createSigned(sender).balance.subInPlace(
Mina.getNetworkConstants().accountCreationFee.mul(3)
);
dex.deploy();
dexTokenHolderX.deploy();
tokenX.approveUpdate(dexTokenHolderX.self);
Expand Down
18 changes: 13 additions & 5 deletions src/examples/zkapps/dex/upgradability.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ async function atomicActionsTest({ withVesting }: { withVesting: boolean }) {
enforceTransactionLimits: false,
});
Mina.setActiveInstance(Local);
let accountFee = Mina.accountCreationFee();
let [{ privateKey: feePayerKey, publicKey: feePayerAddress }] =
Local.testAccounts;
let tx, balances;
Expand Down Expand Up @@ -51,6 +50,7 @@ async function atomicActionsTest({ withVesting }: { withVesting: boolean }) {

console.log('deploy & init token contracts...');
tx = await Mina.transaction(feePayerAddress, () => {
const accountFee = Mina.getNetworkConstants().accountCreationFee;
// pay fees for creating 2 token contract accounts, and fund them so each can create 2 accounts themselves
let feePayerUpdate = AccountUpdate.fundNewAccount(feePayerAddress, 2);
feePayerUpdate.send({ to: addresses.tokenX, amount: accountFee.mul(2) });
Expand Down Expand Up @@ -227,7 +227,6 @@ async function upgradeabilityTests({ withVesting }: { withVesting: boolean }) {
enforceTransactionLimits: false,
});
Mina.setActiveInstance(Local);
let accountFee = Mina.accountCreationFee();
let [{ privateKey: feePayerKey, publicKey: feePayerAddress }] =
Local.testAccounts;
let tx, balances, oldBalances;
Expand Down Expand Up @@ -259,6 +258,7 @@ async function upgradeabilityTests({ withVesting }: { withVesting: boolean }) {

console.log('deploy & init token contracts...');
tx = await Mina.transaction(feePayerAddress, () => {
const accountFee = Mina.getNetworkConstants().accountCreationFee;
// pay fees for creating 2 token contract accounts, and fund them so each can create 2 accounts themselves
let feePayerUpdate = AccountUpdate.createSigned(feePayerAddress);
feePayerUpdate.balance.subInPlace(accountFee.mul(2));
Expand Down Expand Up @@ -309,10 +309,15 @@ async function upgradeabilityTests({ withVesting }: { withVesting: boolean }) {

console.log('transfer tokens to user');
tx = await Mina.transaction(
{ sender: feePayerAddress, fee: accountFee.mul(1) },
{
sender: feePayerAddress,
fee: Mina.getNetworkConstants().accountCreationFee.mul(1),
},
() => {
let feePayer = AccountUpdate.createSigned(feePayerAddress);
feePayer.balance.subInPlace(Mina.accountCreationFee().mul(4));
feePayer.balance.subInPlace(
Mina.getNetworkConstants().accountCreationFee.mul(4)
);
feePayer.send({ to: addresses.user, amount: 20e9 }); // give users MINA to pay fees
feePayer.send({ to: addresses.user2, amount: 20e9 });
// transfer to fee payer so they can provide initial liquidity
Expand Down Expand Up @@ -364,7 +369,10 @@ async function upgradeabilityTests({ withVesting }: { withVesting: boolean }) {

console.log('supply liquidity -- base');
tx = await Mina.transaction(
{ sender: feePayerAddress, fee: accountFee.mul(1) },
{
sender: feePayerAddress,
fee: Mina.getNetworkConstants().accountCreationFee.mul(1),
},
() => {
AccountUpdate.fundNewAccount(feePayerAddress);
modifiedDex.supplyLiquidityBase(UInt64.from(10_000), UInt64.from(10_000));
Expand Down
2 changes: 1 addition & 1 deletion src/lib/account_update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1273,7 +1273,7 @@ class AccountUpdate implements Types.AccountUpdate {
) {
let accountUpdate = AccountUpdate.createSigned(feePayer as PrivateKey);
accountUpdate.label = 'AccountUpdate.fundNewAccount()';
let fee = Mina.accountCreationFee();
let fee = Mina.getNetworkConstants().accountCreationFee;
numberOfAccounts ??= 1;
if (typeof numberOfAccounts === 'number') fee = fee.mul(numberOfAccounts);
else fee = fee.add(UInt64.from(numberOfAccounts.initialBalance ?? 0));
Expand Down

0 comments on commit 4b2f32a

Please sign in to comment.