Skip to content

Commit 92ff2fa

Browse files
authored
feat: TXE nr deployments, dependency cleanup for CLI (#7548)
This PR eliminates unnecessary dependencies from TXE (namely `@aztec/noir-contracts.js`) and introduces a new format for simulated contract deployments in tests. Leveraging two new variables introduced in nargo foreign calls that provide context to TXE (`root_path` and `package_name`), we are able to directly locate the `.json` artifacts resulting from compilation and use those to deploy bytecode. The API looks like this: ```rust // The contract we're testing env.deploy_self("ContractName").with{out/_public/_private}_initializer(...); // We have to provide ContractName since nargo it's ready to support multi-contract files // A contract from a workspace env.deploy("../path/to/workspace@package_name", "ContractName").with{out/_public/_private}_initializer(...); // This format allows locating the artifact in the root workspace target folder, regardless of internal code organization // An isolated contract env.deploy("../path/to/contract", "ContractName").with{out/_public/_private}_initializer(...); ``` All paths originate and point to a program root (where `Nargo.toml` lives)
1 parent a316fcd commit 92ff2fa

45 files changed

Lines changed: 401 additions & 241 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

aztec-up/bin/docker-compose.test.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ services:
66
HOST_WORKDIR: "${PWD}" # Loaded from the user shell to show log files absolute path in host
77
volumes:
88
- ./log:/usr/src/yarn-project/aztec/log:rw
9+
- ${HOME}:${HOME}
910
command: start --txe
1011

1112
aztec-nargo:

docs/docs/guides/smart_contracts/testing_contracts/index.md

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,18 @@ Writing tests in contracts requires importing additional modules from Aztec.nr.
7070
### Deploying contracts
7171

7272
```rust
73-
let deployer = env.deploy("path_to_contract_ts_interface");
73+
74+
// Deploy the contract we're currently on
75+
76+
let deployer = env.deploy_self("ContractName");
77+
78+
// Deploy a standalone contract in a path relative to the current one (always from the location of Nargo.toml)
79+
80+
let deployer = env.deploy("path_to_contract_root_folder_where_nargo_toml_is", "ContractName");
81+
82+
// Deploy a contract in a workspace
83+
84+
let deployer = env.deploy("path_to_workspace_root_folder_where_main_nargo_toml_is@package_name", "ContractName");
7485

7586
// Now one of these can be called, depending on the contract and their possible initialization options.
7687
// Remember a contract can only be initialized once.
@@ -89,7 +100,7 @@ let my_contract_instance = deployer.without_initializer();
89100
```
90101

91102
:::warning
92-
At the moment, TXE uses the generated contract TypeScript interfaces to perform deployments, and they must be provided as either an absolute path, a relative path to TXE's location or a module in an npm direct dependency such as `@aztec/noir-contracts.js`. It is not always necessary to deploy a contract in order to test it, but sometimes it's inevitable (when testing functions that depend on the contract being initialized, or contracts that call others for example) **It is important to keep them up to date**, as TXE cannot recompile them on changes. This will be improved in the future.
103+
It is not always necessary to deploy a contract in order to test it, but sometimes it's inevitable (when testing functions that depend on the contract being initialized, or contracts that call others for example) **It is important to keep them up to date**, as TXE cannot recompile them on changes. Think of it as regenerating the bytecode and ABI so it becomes accessible externally.
93104
:::
94105

95106
### Calling functions

docs/docs/migration_notes.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,29 @@ keywords: [sandbox, aztec, notes, migration, updating, upgrading]
77
Aztec is in full-speed development. Literally every version breaks compatibility with the previous ones. This page attempts to target errors and difficulties you might encounter when upgrading, and how to resolve them.
88

99
## 0.xx.0
10+
11+
# [Aztec sandbox] TXE deployment changes
12+
13+
The way simulated deployments are done in TXE tests has changed to avoid relying on TS interfaces. It is now possible to do it by directly pointing to a Noir standalone contract or workspace:
14+
15+
```diff
16+
-let deployer = env.deploy("path_to_contract_ts_interface");
17+
+let deployer = env.deploy("path_to_contract_root_folder_where_nargo_toml_is", "ContractName");
18+
```
19+
20+
Extended syntax for more use cases:
21+
22+
```rust
23+
// The contract we're testing
24+
env.deploy_self("ContractName"); // We have to provide ContractName since nargo it's ready to support multi-contract files
25+
26+
// A contract in a workspace
27+
env.deploy("../path/to/workspace@package_name", "ContractName"); // This format allows locating the artifact in the root workspace target folder, regardless of internal code organization
28+
```
29+
30+
The deploy function returns a `Deployer`, which requires performing a subsequent call to `without_initializer()`, `with_private_initializer()` or `with_public_initializer()` just like before in order to **actually** deploy the contract.
31+
32+
## 0.46.3
1033
### [Aztec sandbox] Command refactor and unification + `aztec test`
1134

1235
Sandbox commands have been cleaned up and simplified. Doing `aztec-up` now gets you the following top-level commands:

noir-projects/aztec-nr/aztec/src/test/helpers/cheatcodes.nr

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,14 @@ unconstrained pub fn get_public_context_inputs() -> PublicContextInputs {
2626
oracle_get_public_context_inputs()
2727
}
2828

29-
unconstrained pub fn deploy<let N: u32, let M: u32>(
29+
unconstrained pub fn deploy<let N: u32, let M: u32, let P: u32>(
3030
path: str<N>,
31-
initializer: str<M>,
31+
name: str<M>,
32+
initializer: str<P>,
3233
args: [Field],
3334
public_keys_hash: Field
3435
) -> ContractInstance {
35-
let instance_fields = oracle_deploy(path, initializer, args, public_keys_hash);
36+
let instance_fields = oracle_deploy(path, name, initializer, args, public_keys_hash);
3637
ContractInstance::deserialize(instance_fields)
3738
}
3839

@@ -44,8 +45,8 @@ unconstrained pub fn create_account() -> TestAccount {
4445
oracle_create_account()
4546
}
4647

47-
unconstrained pub fn add_account(secret: Field, partial_address: PartialAddress) -> TestAccount {
48-
oracle_add_account(secret, partial_address)
48+
unconstrained pub fn add_account(secret: Field) -> TestAccount {
49+
oracle_add_account(secret)
4950
}
5051

5152
unconstrained pub fn derive_keys(secret: Field) -> PublicKeys {
@@ -122,9 +123,10 @@ unconstrained fn oracle_get_private_context_inputs(historical_block_number: u32)
122123
unconstrained fn oracle_get_public_context_inputs() -> PublicContextInputs {}
123124

124125
#[oracle(deploy)]
125-
unconstrained fn oracle_deploy<let N: u32, let M: u32>(
126+
unconstrained fn oracle_deploy<let N: u32, let M: u32, let P: u32>(
126127
path: str<N>,
127-
initializer: str<M>,
128+
name: str<M>,
129+
initializer: str<P>,
128130
args: [Field],
129131
public_keys_hash: Field
130132
) -> [Field; CONTRACT_INSTANCE_LENGTH] {}
@@ -140,7 +142,7 @@ unconstrained fn direct_storage_write_oracle<let N: u32>(
140142
unconstrained fn oracle_create_account() -> TestAccount {}
141143

142144
#[oracle(addAccount)]
143-
unconstrained fn oracle_add_account(secret: Field, partial_address: PartialAddress) -> TestAccount {}
145+
unconstrained fn oracle_add_account(secret: Field) -> TestAccount {}
144146

145147
#[oracle(deriveKeys)]
146148
unconstrained fn oracle_derive_keys(secret: Field) -> PublicKeys {}

noir-projects/aztec-nr/aztec/src/test/helpers/test_environment.nr

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -85,27 +85,11 @@ impl TestEnvironment {
8585
}
8686

8787
fn create_account_contract(&mut self, secret: Field) -> AztecAddress {
88-
let public_keys = cheatcodes::derive_keys(secret);
89-
let args = [public_keys.ivpk_m.x, public_keys.ivpk_m.y];
90-
let instance = cheatcodes::deploy(
91-
"@aztec/noir-contracts.js/SchnorrAccount",
92-
"constructor",
93-
args.as_slice(),
94-
public_keys.hash().to_field()
95-
);
88+
let test_account = cheatcodes::add_account(secret);
89+
let address = test_account.address;
9690
cheatcodes::advance_blocks_by(1);
97-
let test_account = cheatcodes::add_account(
98-
secret,
99-
PartialAddress::compute(
100-
instance.contract_class_id,
101-
instance.salt,
102-
instance.initialization_hash,
103-
instance.deployer
104-
)
105-
);
106-
let keys = test_account.keys;
10791

108-
let address = instance.to_address();
92+
let keys = test_account.keys;
10993

11094
keys::store_master_key(NULLIFIER_INDEX, address, keys.npk_m);
11195
keys::store_master_key(INCOMING_INDEX, address, keys.ivpk_m);
@@ -115,14 +99,18 @@ impl TestEnvironment {
11599
let selector = FunctionSelector::from_signature("constructor(Field,Field)");
116100

117101
let mut context = self.private_at(get_block_number());
118-
102+
let args = [test_account.keys.ivpk_m.x, test_account.keys.ivpk_m.y];
119103
let _ = context.call_private_function(address, selector, args);
120104

121105
address
122106
}
123107

124-
fn deploy<let N: u32>(_self: Self, path: str<N>) -> Deployer<N> {
125-
Deployer { path, public_keys_hash: 0 }
108+
fn deploy<N, M>(self, path: str<N>, name: str<M>) -> Deployer<N, M> {
109+
Deployer { path, name, public_keys_hash: 0 }
110+
}
111+
112+
fn deploy_self<M>(self, name: str<M>) -> Deployer<0, M> {
113+
Deployer { path: "", name, public_keys_hash: 0 }
126114
}
127115

128116
fn call_private<C, let M: u32, T, Env, let N: u32>(

noir-projects/aztec-nr/aztec/src/test/helpers/utils.nr

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,20 @@ pub fn apply_side_effects_private(contract_address: AztecAddress, public_inputs:
2929
cheatcodes::add_note_hashes(contract_address, note_hashes);
3030
}
3131

32-
struct Deployer<let N: u32> {
33-
path: str<N>,
34-
public_keys_hash: Field
35-
}
32+
struct Deployer<let N: u32, let M: u32> {
33+
path: str<N>,
34+
name: str<M>,
35+
public_keys_hash: Field
36+
}
3637

37-
impl<let N: u32> Deployer<N> {
38-
pub fn with_private_initializer<C, let M: u32, Env>(
38+
impl<let N: u32, let M: u32> Deployer<N, M> {
39+
pub fn with_private_initializer<C, let P: u32, Env>(
3940
self,
4041
call_interface: C
41-
) -> ContractInstance where C: CallInterface<M, PrivateContextInputs, PrivateCircuitPublicInputs, Env> {
42+
) -> ContractInstance where C: CallInterface<P, PrivateContextInputs, PrivateCircuitPublicInputs, Env> {
4243
let instance = cheatcodes::deploy(
4344
self.path,
45+
self.name,
4446
call_interface.get_name(),
4547
call_interface.get_args(),
4648
self.public_keys_hash
@@ -64,12 +66,13 @@ impl<let N: u32> Deployer<N> {
6466
instance
6567
}
6668

67-
pub fn with_public_initializer<C, let M: u32, T, Env>(
69+
pub fn with_public_initializer<C, let P: u32, T, Env>(
6870
self,
6971
call_interface: C
70-
) -> ContractInstance where C: CallInterface<M, PublicContextInputs, T, Env> {
72+
) -> ContractInstance where C: CallInterface<P, PublicContextInputs, T, Env> {
7173
let instance = cheatcodes::deploy(
7274
self.path,
75+
self.name,
7376
call_interface.get_name(),
7477
call_interface.get_args(),
7578
self.public_keys_hash
@@ -94,7 +97,7 @@ impl<let N: u32> Deployer<N> {
9497
}
9598

9699
pub fn without_initializer(self) -> ContractInstance {
97-
cheatcodes::deploy(self.path, "", &[], self.public_keys_hash)
100+
cheatcodes::deploy(self.path, self.name, "", &[], self.public_keys_hash)
98101
}
99102
}
100103

noir-projects/noir-contracts/contracts/counter_contract/src/main.nr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ contract Counter {
5757

5858
// Deploy contract and initialize
5959
let initializer = Counter::interface().initialize(initial_value as u64, owner, outgoing_viewer);
60-
let counter_contract = env.deploy("@aztec/noir-contracts.js/Counter").with_private_initializer(initializer);
60+
let counter_contract = env.deploy_self("Counter").with_private_initializer(initializer);
6161
let contract_address = counter_contract.to_address();
6262

6363
// docs:start:txe_test_read_notes

noir-projects/noir-contracts/contracts/parent_contract/src/main.nr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ contract Parent {
257257
let owner = env.create_account();
258258

259259
// Deploy child contract
260-
let child_contract = env.deploy("@aztec/noir-contracts.js/Child").without_initializer();
260+
let child_contract = env.deploy("./@child_contract", "Child").without_initializer();
261261
let child_contract_address = child_contract.to_address();
262262
cheatcodes::advance_blocks_by(1);
263263

noir-projects/noir-contracts/contracts/private_token_contract/src/test/utils.nr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ pub fn setup(with_account_contracts: bool) -> (&mut TestEnvironment, AztecAddres
1616
let owner = env.create_account_contract(1);
1717
let recipient = env.create_account_contract(2);
1818
// Deploy canonical auth registry
19-
let _auth_registry = env.deploy("@aztec/noir-contracts.js/AuthRegistry").without_initializer();
19+
let _auth_registry = env.deploy("./@auth_registry_contract", "AuthRegistry").without_initializer();
2020
(owner, recipient)
2121
} else {
2222
let owner = env.create_account();
@@ -34,7 +34,7 @@ pub fn setup(with_account_contracts: bool) -> (&mut TestEnvironment, AztecAddres
3434
"TT00000000000000000000000000000",
3535
18
3636
);
37-
let token_contract = env.deploy("@aztec/noir-contracts.js/PrivateToken").with_public_initializer(initializer_call_interface);
37+
let token_contract = env.deploy_self("PrivateToken").with_public_initializer(initializer_call_interface);
3838
let token_contract_address = token_contract.to_address();
3939
env.advance_block_by(6);
4040
(&mut env, token_contract_address, owner, recipient)

noir-projects/noir-contracts/contracts/token_contract/src/test/utils.nr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ pub fn setup(with_account_contracts: bool) -> (&mut TestEnvironment, AztecAddres
1515
let owner = env.create_account_contract(1);
1616
let recipient = env.create_account_contract(2);
1717
// Deploy canonical auth registry
18-
let _auth_registry = env.deploy("@aztec/noir-contracts.js/AuthRegistry").without_initializer();
18+
let _auth_registry = env.deploy("./@auth_registry_contract", "AuthRegistry").without_initializer();
1919
(owner, recipient)
2020
} else {
2121
let owner = env.create_account();
@@ -33,7 +33,7 @@ pub fn setup(with_account_contracts: bool) -> (&mut TestEnvironment, AztecAddres
3333
"TT00000000000000000000000000000",
3434
18
3535
);
36-
let token_contract = env.deploy("@aztec/noir-contracts.js/Token").with_public_initializer(initializer_call_interface);
36+
let token_contract = env.deploy_self("Token").with_public_initializer(initializer_call_interface);
3737
let token_contract_address = token_contract.to_address();
3838
env.advance_block_by(1);
3939
(&mut env, token_contract_address, owner, recipient)

0 commit comments

Comments
 (0)