Skip to content

Commit

Permalink
feat: add nonces
Browse files Browse the repository at this point in the history
  • Loading branch information
LHerskind committed Sep 8, 2023
1 parent dac4a7d commit de9ec7f
Show file tree
Hide file tree
Showing 8 changed files with 203 additions and 102 deletions.
5 changes: 3 additions & 2 deletions yarn-project/acir-simulator/src/client/private_execution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,15 +161,16 @@ export class PrivateFunctionExecution {
return Promise.resolve(ZERO_ACVM_FIELD);
},
enqueuePublicFunctionCall: async ([acvmContractAddress], [acvmFunctionSelector], [acvmArgsHash]) => {
const selector = frToAztecAddress(fromACVMField(acvmContractAddress));
const enqueuedRequest = await this.enqueuePublicFunctionCall(
frToAztecAddress(fromACVMField(acvmContractAddress)),
selector,
FunctionSelector.fromField(fromACVMField(acvmFunctionSelector)),
this.context.packedArgsCache.unpack(fromACVMField(acvmArgsHash)),
this.callContext,
);

this.log(
`Enqueued call to public function (with side-effect counter #${enqueuedRequest.sideEffectCounter}) ${acvmContractAddress}:${acvmFunctionSelector}`,
`Enqueued call to public function (with side-effect counter #${enqueuedRequest.sideEffectCounter}) ${acvmContractAddress}:${selector}`,
);
enqueuedPublicFunctionCalls.push(enqueuedRequest);
return toAcvmEnqueuePublicFunctionResult(enqueuedRequest);
Expand Down
5 changes: 3 additions & 2 deletions yarn-project/acir-simulator/src/public/executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,11 @@ export class PublicExecutor {
},
callPublicFunction: async ([address], [functionSelector], [argsHash]) => {
const args = packedArgs.unpack(fromACVMField(argsHash));
this.log(`Public function call: addr=${address} selector=${functionSelector} args=${args.join(',')}`);
const selector = FunctionSelector.fromField(fromACVMField(functionSelector));
this.log(`Public function call: addr=${address} selector=${selector} args=${args.join(',')}`);
const childExecutionResult = await this.callPublicFunction(
frToAztecAddress(fromACVMField(address)),
FunctionSelector.fromField(fromACVMField(functionSelector)),
selector,
args,
execution.callContext,
globalVariables,
Expand Down
6 changes: 1 addition & 5 deletions yarn-project/aztec.js/src/abis/ecdsa_account_contract.json

Large diffs are not rendered by default.

6 changes: 1 addition & 5 deletions yarn-project/aztec.js/src/abis/schnorr_account_contract.json

Large diffs are not rendered by default.

Large diffs are not rendered by default.

195 changes: 149 additions & 46 deletions yarn-project/end-to-end/src/e2e_token_contract.test.ts

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ mod util;
// The designated caller is ALWAYS used here, and not based on a flag as cross-chain.
// message hash = H([caller, selector, , ...args])
// To be read as `caller` calls function defined by `selector` with `args`
// Including a nonce in the message hash ensures that the message can only be used once.

contract Token {
// Libs
Expand Down Expand Up @@ -35,9 +36,7 @@ contract Token {

use crate::types::{AztecAddress, TransparentNote, TransparentNoteMethods, TRANSPARENT_NOTE_LEN};
use crate::account_interface::AccountContract;
use crate::util::compute_message_hash;


use crate::util::{compute_message_hash};

struct Storage {
admin: PublicState<Field, FIELD_SERIALISED_LEN>,
Expand Down Expand Up @@ -169,13 +168,18 @@ contract Token {
from: AztecAddress,
amount: Field,
secret_hash: Field,
nonce: Field,
) -> Field {
let storage = Storage::init(Option::none(), Option::some(&mut context));

if (from.address != context.msg_sender()) {
let selector = compute_selector("shield((Field),Field,Field)");
let message_field = compute_message_hash([context.msg_sender(), selector, from.address, amount, secret_hash]);
// The redeem is only spendable once, so we need to ensure that you cannot insert multiple shields from the same message.
let selector = compute_selector("shield((Field),Field,Field,Field)");
let message_field = compute_message_hash([context.msg_sender(), selector, from.address, amount, secret_hash, nonce]);
assert(AccountContract::at(from.address).is_valid(Option::none(), Option::some(context), message_field) == 0xe86ab4ff, "invalid call");
context.push_new_nullifier(message_field, 0);
} else {
assert(nonce == 0, "invalid nonce");
}

let amount = SafeU120::new(amount);
Expand All @@ -194,13 +198,17 @@ contract Token {
from: AztecAddress,
to: AztecAddress,
amount: Field,
nonce: Field,
) -> Field {
let storage = Storage::init(Option::none(), Option::some(&mut context));

if (from.address != context.msg_sender()) {
let selector = compute_selector("transfer_public((Field),(Field),Field)");
let message_field = compute_message_hash([context.msg_sender(), selector, from.address, to.address, amount]);
let selector = compute_selector("transfer_public((Field),(Field),Field,Field)");
let message_field = compute_message_hash([context.msg_sender(), selector, from.address, to.address, amount, nonce]);
assert(AccountContract::at(from.address).is_valid(Option::none(), Option::some(context), message_field) == 0xe86ab4ff, "invalid call");
context.push_new_nullifier(message_field, 0);
} else {
assert(nonce == 0, "invalid nonce");
}

let amount = SafeU120::new(amount);
Expand Down Expand Up @@ -232,13 +240,17 @@ contract Token {
from: AztecAddress,
to: AztecAddress,
amount: Field,
nonce: Field,
) -> Field {
let storage = Storage::init(Option::some(&mut context), Option::none());

if (from.address != context.msg_sender()) {
let selector = compute_selector("unshield((Field),(Field),Field)");
let message_field = compute_message_hash([context.msg_sender(), selector, from.address, to.address, amount]);
let selector = compute_selector("unshield((Field),(Field),Field,Field)");
let message_field = compute_message_hash([context.msg_sender(), selector, from.address, to.address, amount, nonce]);
assert(AccountContract::at(from.address).is_valid(Option::some(&mut context), Option::none(), message_field) == 0xe86ab4ff, "invalid call");
context.push_new_nullifier(message_field, 0);
} else {
assert(nonce == 0, "invalid nonce");
}

let from_balance = storage.balances.at(from.address);
Expand All @@ -253,13 +265,17 @@ contract Token {
from: AztecAddress,
to: AztecAddress,
amount: Field,
nonce: Field,
) -> Field {
let storage = Storage::init(Option::some(&mut context), Option::none());

if (from.address != context.msg_sender()) {
let selector = compute_selector("transfer((Field),(Field),Field)");
let message_field = compute_message_hash([context.msg_sender(), selector, from.address, to.address, amount]);
let selector = compute_selector("transfer((Field),(Field),Field,Field)");
let message_field = compute_message_hash([context.msg_sender(), selector, from.address, to.address, amount, nonce]);
assert(AccountContract::at(from.address).is_valid(Option::some(&mut context), Option::none(), message_field) == 0xe86ab4ff, "invalid call");
context.push_new_nullifier(message_field, 0);
} else {
assert(nonce == 0, "invalid nonce");
}

let from_balance = storage.balances.at(from.address);
Expand Down
12 changes: 10 additions & 2 deletions yarn-project/sequencer-client/src/sequencer/sequencer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,8 +282,16 @@ export class Sequencer {
const allTxs = [...txs, ...times(emptyTxCount, () => emptyTx)];
this.log(`Building block ${globalVariables.blockNumber}`);

const [block] = await this.blockBuilder.buildL2Block(globalVariables, allTxs, newL1ToL2Messages);
return block;
// If the block is invalid, drop the transactions
try {
const [block] = await this.blockBuilder.buildL2Block(globalVariables, allTxs, newL1ToL2Messages);
return block;
} catch (err) {
const hashes = txs.map(tx => tx.hash);
this.log.error(`Dropping failed txs ${hashes.join(', ')}`);
await this.p2pClient.deleteTxs(hashes);
throw err;
}
}

/**
Expand Down

0 comments on commit de9ec7f

Please sign in to comment.