Skip to content

Commit

Permalink
fix: bad contract txs publishing contract data
Browse files Browse the repository at this point in the history
  • Loading branch information
alexghr committed Oct 4, 2023
1 parent 248be1b commit 9e78aad
Show file tree
Hide file tree
Showing 8 changed files with 332 additions and 9 deletions.
23 changes: 22 additions & 1 deletion yarn-project/end-to-end/src/e2e_deploy_contract.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { AztecAddress, Contract, ContractDeployer, Fr, Wallet, isContractDeployed } from '@aztec/aztec.js';
import { CompleteAddress, getContractDeploymentInfo } from '@aztec/circuits.js';
import { DebugLogger } from '@aztec/foundation/log';
import { TestContractAbi } from '@aztec/noir-contracts/artifacts';
import { TestAssertContractAbi, TestContractAbi } from '@aztec/noir-contracts/artifacts';
import { PXE, TxStatus } from '@aztec/types';

import { setup } from './fixtures/utils.js';
Expand Down Expand Up @@ -111,4 +111,25 @@ describe('e2e_deploy_contract', () => {
);
}
}, 30_000);

it('it should not deploy a bad contract', async () => {
const goodDeploy = new ContractDeployer(TestAssertContractAbi, wallet).deploy(0);
const badDeploy = new ContractDeployer(TestAssertContractAbi, wallet).deploy(1);

const [goodTx, badTx] = [
goodDeploy.send({ skipPublicSimulation: true }),
badDeploy.send({ skipPublicSimulation: true }),
];

const [goodTxPromiseResult, badTxReceiptResult] = await Promise.allSettled([goodTx.wait(), badTx.wait()]);

expect(goodTxPromiseResult.status).toBe('fulfilled');
expect(badTxReceiptResult.status).toBe('rejected');

await expect(pxe.getExtendedContractData(goodDeploy.completeAddress!.address)).resolves.toBeDefined();
await expect(pxe.getExtendedContractData(goodDeploy.completeAddress!.address)).resolves.toBeDefined();

await expect(pxe.getContractData(badDeploy.completeAddress!.address)).resolves.toBeUndefined();
await expect(pxe.getExtendedContractData(badDeploy.completeAddress!.address)).resolves.toBeUndefined();
});
});
1 change: 1 addition & 0 deletions yarn-project/noir-contracts/Nargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ members = [
"src/contracts/schnorr_single_key_account_contract",
"src/contracts/stateful_test_contract",
"src/contracts/test_contract",
"src/contracts/test_assert_contract",
"src/contracts/token_contract",
"src/contracts/token_bridge_contract",
"src/contracts/uniswap_contract",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
name = "test_assert_contract"
authors = [""]
compiler_version = "0.1"
type = "contract"

[dependencies]
aztec = { path = "../../../../aztec-nr/aztec" }
Original file line number Diff line number Diff line change
@@ -0,0 +1,276 @@
/* Autogenerated file, do not edit! */

use dep::std;
use dep::aztec::context::{ PrivateContext, PublicContext };
use dep::aztec::constants_gen::RETURN_VALUES_LENGTH;

struct AStructTestCodeGenStruct {
amount: Field,
secretHash: Field,
}

struct ADeepStructTestCodeGenStruct {
aField: Field,
aBool: bool,
aNote: ANoteADeepStructTestCodeGenStruct,
manyNotes: [ManyNotesADeepStructTestCodeGenStruct;3],
}

struct ANoteADeepStructTestCodeGenStruct {
amount: Field,
secretHash: Field,
}

struct ManyNotesADeepStructTestCodeGenStruct {
amount: Field,
secretHash: Field,
}


// Interface for calling Test functions from a private context
struct TestPrivateContextInterface {
address: Field,
}

impl TestPrivateContextInterface {
fn at(address: Field) -> Self {
Self {
address,
}
}

fn assert_is_zero(
self,
context: &mut PrivateContext,
value: Field
) {
let mut serialized_args = [0; 1];
serialized_args[0] = value;

context.call_public_function(self.address, 0x5438565f, serialized_args)
}


fn createL2ToL1MessagePublic(
self,
context: &mut PrivateContext,
amount: Field,
secretHash: Field
) {
let mut serialized_args = [0; 2];
serialized_args[0] = amount;
serialized_args[1] = secretHash;

context.call_public_function(self.address, 0xbac98727, serialized_args)
}


fn createNullifierPublic(
self,
context: &mut PrivateContext,
amount: Field,
secretHash: Field
) {
let mut serialized_args = [0; 2];
serialized_args[0] = amount;
serialized_args[1] = secretHash;

context.call_public_function(self.address, 0x42040a24, serialized_args)
}


fn emit_nullifier(
self,
context: &mut PrivateContext,
nullifier: Field
) -> [Field; RETURN_VALUES_LENGTH] {
let mut serialized_args = [0; 1];
serialized_args[0] = nullifier;

context.call_private_function(self.address, 0x82a8b183, serialized_args)
}


fn emit_unencrypted(
self,
context: &mut PrivateContext,
value: Field
) {
let mut serialized_args = [0; 1];
serialized_args[0] = value;

context.call_public_function(self.address, 0x817a64cb, serialized_args)
}


fn getPortalContractAddress(
self,
context: &mut PrivateContext,
aztec_address: Field
) -> [Field; RETURN_VALUES_LENGTH] {
let mut serialized_args = [0; 1];
serialized_args[0] = aztec_address;

context.call_private_function(self.address, 0xaf15a45f, serialized_args)
}


fn getPublicKey(
self,
context: &mut PrivateContext,
address: Field
) -> [Field; RETURN_VALUES_LENGTH] {
let mut serialized_args = [0; 1];
serialized_args[0] = address;

context.call_private_function(self.address, 0x88f0753b, serialized_args)
}


fn getThisAddress(
self,
context: &mut PrivateContext
) -> [Field; RETURN_VALUES_LENGTH] {
let mut serialized_args = [0; 0];

context.call_private_function(self.address, 0xd3953822, serialized_args)
}


fn getThisPortalAddress(
self,
context: &mut PrivateContext
) -> [Field; RETURN_VALUES_LENGTH] {
let mut serialized_args = [0; 0];

context.call_private_function(self.address, 0x82cc9431, serialized_args)
}


fn isTimeEqual(
self,
context: &mut PrivateContext,
time: Field
) {
let mut serialized_args = [0; 1];
serialized_args[0] = time;

context.call_public_function(self.address, 0xfff6026c, serialized_args)
}


fn testCodeGen(
self,
context: &mut PrivateContext,
aField: Field,
aBool: bool,
aNumber: u32,
anArray: [Field;2],
aStruct: AStructTestCodeGenStruct,
aDeepStruct: ADeepStructTestCodeGenStruct
) -> [Field; RETURN_VALUES_LENGTH] {
let mut serialized_args = [0; 17];
serialized_args[0] = aField;
serialized_args[1] = aBool as Field;
serialized_args[2] = aNumber as Field;
serialized_args[3] = anArray[0];
serialized_args[4] = anArray[1];
serialized_args[5] = aStruct.amount;
serialized_args[6] = aStruct.secretHash;
serialized_args[7] = aDeepStruct.aField;
serialized_args[8] = aDeepStruct.aBool as Field;
serialized_args[9] = aDeepStruct.aNote.amount;
serialized_args[10] = aDeepStruct.aNote.secretHash;
serialized_args[11] = aDeepStruct.manyNotes[0].amount;
serialized_args[12] = aDeepStruct.manyNotes[0].secretHash;
serialized_args[13] = aDeepStruct.manyNotes[1].amount;
serialized_args[14] = aDeepStruct.manyNotes[1].secretHash;
serialized_args[15] = aDeepStruct.manyNotes[2].amount;
serialized_args[16] = aDeepStruct.manyNotes[2].secretHash;

context.call_private_function(self.address, 0x81d7c118, serialized_args)
}

}




// Interface for calling Test functions from a public context
struct TestPublicContextInterface {
address: Field,
}

impl TestPublicContextInterface {
fn at(address: Field) -> Self {
Self {
address,
}
}

fn assert_is_zero(
self,
context: PublicContext,
value: Field
) -> [Field; RETURN_VALUES_LENGTH] {
let mut serialized_args = [0; 1];
serialized_args[0] = value;

context.call_public_function(self.address, 0x5438565f, serialized_args)
}


fn createL2ToL1MessagePublic(
self,
context: PublicContext,
amount: Field,
secretHash: Field
) -> [Field; RETURN_VALUES_LENGTH] {
let mut serialized_args = [0; 2];
serialized_args[0] = amount;
serialized_args[1] = secretHash;

context.call_public_function(self.address, 0xbac98727, serialized_args)
}


fn createNullifierPublic(
self,
context: PublicContext,
amount: Field,
secretHash: Field
) -> [Field; RETURN_VALUES_LENGTH] {
let mut serialized_args = [0; 2];
serialized_args[0] = amount;
serialized_args[1] = secretHash;

context.call_public_function(self.address, 0x42040a24, serialized_args)
}


fn emit_unencrypted(
self,
context: PublicContext,
value: Field
) -> [Field; RETURN_VALUES_LENGTH] {
let mut serialized_args = [0; 1];
serialized_args[0] = value;

context.call_public_function(self.address, 0x817a64cb, serialized_args)
}


fn isTimeEqual(
self,
context: PublicContext,
time: Field
) -> [Field; RETURN_VALUES_LENGTH] {
let mut serialized_args = [0; 1];
serialized_args[0] = time;

context.call_public_function(self.address, 0xfff6026c, serialized_args)
}

}


Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// A contract used in end to end tests
contract TestAssert {
use dep::aztec::{
oracle::compute_selector::compute_selector,
};

#[aztec(private)]
fn constructor(value: Field) {
let selector = compute_selector("assert_is_zero(Field)");
context.call_public_function(context.this_address(), selector, [value]);
}

#[aztec(public)]
fn assert_is_zero(value: Field) {
assert(0 == value);
}
}
6 changes: 4 additions & 2 deletions yarn-project/sequencer-client/src/sequencer/processed_tx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ import {
PublicKernelPublicInputs,
makeEmptyProof,
} from '@aztec/circuits.js';
import { Tx, TxHash, TxL2Logs } from '@aztec/types';
import { ExtendedContractData, Tx, TxHash, TxL2Logs } from '@aztec/types';

/**
* Represents a tx that has been processed by the sequencer public processor,
* so its kernel circuit public inputs are filled in.
*/
export type ProcessedTx = Pick<Tx, 'proof' | 'encryptedLogs' | 'unencryptedLogs'> & {
export type ProcessedTx = Pick<Tx, 'proof' | 'encryptedLogs' | 'unencryptedLogs' | 'newContracts'> & {
/**
* Output of the public kernel circuit for this tx.
*/
Expand Down Expand Up @@ -78,6 +78,7 @@ export async function makeProcessedTx(
proof: proof ?? tx.proof,
encryptedLogs: tx.encryptedLogs,
unencryptedLogs: tx.unencryptedLogs,
newContracts: tx.newContracts,
isEmpty: false,
};
}
Expand All @@ -104,6 +105,7 @@ export function makeEmptyProcessedTx(
unencryptedLogs: new TxL2Logs([]),
data: emptyKernelOutput,
proof: emptyProof,
newContracts: [ExtendedContractData.random()],
isEmpty: true,
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ describe('public_processor', () => {
proof: tx.proof,
encryptedLogs: tx.encryptedLogs,
unencryptedLogs: tx.unencryptedLogs,
newContracts: tx.newContracts,
},
]);
expect(failed).toEqual([]);
Expand Down
Loading

0 comments on commit 9e78aad

Please sign in to comment.