Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/lde/serialize_inf' into lde/seri…
Browse files Browse the repository at this point in the history
…alize_inf
  • Loading branch information
ludamad committed Jun 7, 2024
2 parents 714232e + 5d98323 commit 308154b
Show file tree
Hide file tree
Showing 43 changed files with 381 additions and 136 deletions.
2 changes: 2 additions & 0 deletions docs/docs/aztec/concepts/smart_contracts/functions/context.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
---
title: Understanding Function Context
sidebar_position: 1
tags: [functions, context]
---

## What is the context
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,29 @@
---
title: Public, Private, and Unconstrained Functions
title: Function Macros
sidebar_position: 2
tags: [functions, macros]
---

This page explains the three types of functions that exist on Aztec - public, private, and unconstrained. For a deeper dive into how these functions work under the hood, check out the [Inner Workings](./inner_workings.md) page.
This page explains three types of functions that exist on Aztec - public, private, and unconstrained; as well as all macros.

## All Aztec macros

In addition to the function macros in Noir, Aztec also has its own macros for specific functions. An Aztec contract function can be annotated with more than 1 macro.
It is also worth mentioning Noir's `unconstrained` function type [here](https://noir-lang.org/docs/noir/concepts/unconstrained/).

- `#[aztec(public)]` or `#[aztec(private)]` - Whether the function is public or private (more in next section)
- `#[aztec(initializer)]` - If one or more functions are marked as an initializer, then one of them must be called before any non-initilizer functions
- `#[aztec(noinitcheck)]` - The function is able to be called before an initializer (if one exists)
- `#[aztec(view)]` - Makes calls to the function static (see also [Static calls](../../../../protocol-specs/calls/static-calls))
- `#[aztec(internal)]` - Function can only be called from within the contract

## Example

See [Private token contract](./../../../../tutorials/contract_tutorials/token_contract.md).

# Public, Private, and unconstrained types

For a deeper dive into how some of these functions work under the hood, check out the [Inner Workings](./inner_workings.md) page.

## `Public` Functions

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ There are also special oracle functions, which can get data from outside of the
Explore this section to learn:

- [How function visibility works in Aztec](./visibility.md)
- [Public, private, and unconstrained functions](./public_private_unconstrained.md), and how to write them
- [Function types and Macros](./function_types_macros.md), and how to write them
- How to write an [initializer function](../../../../guides/smart_contracts/writing_contracts/initializers.md)
- [Calling functions from within the same smart contract and from different contracts](../../../../guides/smart_contracts/writing_contracts/call_functions.md), including calling private functions from private functions, public from public, and even private from public
- [Oracles](../oracles/index.md) and how Aztec smart contracts might use them
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
---
title: Inner Workings of Functions
sidebar_position: 3
tags: [functions]
---

Below, we go more into depth of what is happening under the hood when you create a function in an Aztec contract and what the attributes are really doing.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
---
title: Visibility
sidebar_position: 0
tags: [functions]
---

In Aztec there are multiple different types of visibility that can be applied to functions. Namely we have `data visibility` and `function visibility`. This page explains these types of visibility.
Expand Down
4 changes: 2 additions & 2 deletions docs/docs/tutorials/contract_tutorials/token_contract.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,9 @@ This specifies the interface of the `Token` contract. Don't worry if you get som

Before we through the interface and implement each function, let's review the functions to get a sense of what the contract does.

### Constructor interface
### Initializer interface

There is a `constructor` function that will be executed once, when the contract is deployed, similar to the constructor function in Solidity. This is marked private, so the function logic will not be transparent. To execute public function logic in the constructor, this function will call `_initialize` (marked internal, more detail below).
There is one `initilizer` function in this contract, and it will be selected and executed once when the contract is deployed, similar to a constructor in Solidity. This is marked private, so the function logic will not be transparent. To execute public function logic in the constructor, this function will call `_initialize` (marked internal, more detail below).

### Public functions

Expand Down
4 changes: 3 additions & 1 deletion noir/noir-repo/docs/docs/noir/concepts/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,14 +184,16 @@ See [Lambdas](./lambdas.md) for more details.

Attributes are metadata that can be applied to a function, using the following syntax: `#[attribute(value)]`.

Supported attributes include:
A few supported attributes include:

- **builtin**: the function is implemented by the compiler, for efficiency purposes.
- **deprecated**: mark the function as _deprecated_. Calling the function will generate a warning: `warning: use of deprecated function`
- **field**: Used to enable conditional compilation of code depending on the field size. See below for more details
- **oracle**: mark the function as _oracle_; meaning it is an external unconstrained function, implemented in noir_js. See [Unconstrained](./unconstrained.md) and [NoirJS](../../reference/NoirJS/noir_js/index.md) for more details.
- **test**: mark the function as unit tests. See [Tests](../../tooling/testing.md) for more details

See the Noir compiler for the full list of supported attributes [here](https://github.com/noir-lang/noir/blob/master/compiler/noirc_frontend/src/lexer/token.rs) (inside `let attribute = match &word_segments[..]` at the time of writing).

### Field Attribute

The field attribute defines which field the function is compatible for. The function is conditionally compiled, under the condition that the field attribute matches the Noir native field.
Expand Down
1 change: 1 addition & 0 deletions yarn-project/archiver/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
"ws": "^8.13.0"
},
"devDependencies": {
"@aztec/noir-contracts.js": "workspace:^",
"@jest/globals": "^29.5.0",
"@types/debug": "^4.1.7",
"@types/jest": "^29.5.0",
Expand Down
9 changes: 9 additions & 0 deletions yarn-project/archiver/src/archiver/archiver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
isValidUnconstrainedFunctionMembershipProof,
} from '@aztec/circuits.js/contract';
import { createEthereumChain } from '@aztec/ethereum';
import { type ContractArtifact } from '@aztec/foundation/abi';
import { type AztecAddress } from '@aztec/foundation/aztec-address';
import { type EthAddress } from '@aztec/foundation/eth-address';
import { Fr } from '@aztec/foundation/fields';
Expand Down Expand Up @@ -489,4 +490,12 @@ export class Archiver implements ArchiveSource {
getContractClassIds(): Promise<Fr[]> {
return this.store.getContractClassIds();
}

addContractArtifact(address: AztecAddress, artifact: ContractArtifact): Promise<void> {
return this.store.addContractArtifact(address, artifact);
}

getContractArtifact(address: AztecAddress): Promise<ContractArtifact | undefined> {
return this.store.getContractArtifact(address);
}
}
4 changes: 4 additions & 0 deletions yarn-project/archiver/src/archiver/archiver_store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
type UnencryptedL2BlockL2Logs,
} from '@aztec/circuit-types';
import { type Fr } from '@aztec/circuits.js';
import { type ContractArtifact } from '@aztec/foundation/abi';
import { type AztecAddress } from '@aztec/foundation/aztec-address';
import {
type ContractClassPublic,
Expand Down Expand Up @@ -191,4 +192,7 @@ export interface ArchiverDataStore {

/** Returns the list of all class ids known by the archiver. */
getContractClassIds(): Promise<Fr[]>;

addContractArtifact(address: AztecAddress, contract: ContractArtifact): Promise<void>;
getContractArtifact(address: AztecAddress): Promise<ContractArtifact | undefined>;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { AztecAddress } from '@aztec/circuits.js';
import { openTmpStore } from '@aztec/kv-store/utils';
import { BenchmarkingContractArtifact } from '@aztec/noir-contracts.js/Benchmarking';

import { beforeEach } from '@jest/globals';

import { KVArchiverDataStore } from './kv_archiver_store.js';

describe('Contract Artifact Store', () => {
let archiverStore: KVArchiverDataStore;

beforeEach(() => {
archiverStore = new KVArchiverDataStore(openTmpStore());
});

it('Should add and return contract artifacts', async () => {
const artifact = BenchmarkingContractArtifact;
const address = AztecAddress.random();
await archiverStore.addContractArtifact(address, artifact);
await expect(archiverStore.getContractArtifact(address)).resolves.toEqual(artifact);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { type AztecAddress } from '@aztec/circuits.js';
import { type ContractArtifact } from '@aztec/foundation/abi';
import { type AztecKVStore, type AztecMap } from '@aztec/kv-store';
import { contractArtifactFromBuffer, contractArtifactToBuffer } from '@aztec/types/abi';

export class ContractArtifactsStore {
#contractArtifacts: AztecMap<string, Buffer>;

constructor(db: AztecKVStore) {
this.#contractArtifacts = db.openMap('archiver_contract_artifacts');
}

addContractArtifact(address: AztecAddress, contractArtifact: ContractArtifact): Promise<void> {
return this.#contractArtifacts.set(address.toString(), contractArtifactToBuffer(contractArtifact));
}

getContractArtifact(address: AztecAddress): ContractArtifact | undefined {
const contractArtifact = this.#contractArtifacts.get(address.toString());
// TODO(@spalladino): AztecMap lies and returns Uint8Arrays instead of Buffers, hence the extra Buffer.from.
return contractArtifact && contractArtifactFromBuffer(Buffer.from(contractArtifact));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
type UnencryptedL2BlockL2Logs,
} from '@aztec/circuit-types';
import { type Fr } from '@aztec/circuits.js';
import { type ContractArtifact } from '@aztec/foundation/abi';
import { type AztecAddress } from '@aztec/foundation/aztec-address';
import { createDebugLogger } from '@aztec/foundation/log';
import { type AztecKVStore } from '@aztec/kv-store';
Expand All @@ -29,6 +30,7 @@ import { type ArchiverDataStore, type ArchiverL1SynchPoint } from '../archiver_s
import { type DataRetrieval } from '../data_retrieval.js';
import { BlockBodyStore } from './block_body_store.js';
import { BlockStore } from './block_store.js';
import { ContractArtifactsStore } from './contract_artifacts_store.js';
import { ContractClassStore } from './contract_class_store.js';
import { ContractInstanceStore } from './contract_instance_store.js';
import { LogStore } from './log_store.js';
Expand All @@ -44,6 +46,7 @@ export class KVArchiverDataStore implements ArchiverDataStore {
#messageStore: MessageStore;
#contractClassStore: ContractClassStore;
#contractInstanceStore: ContractInstanceStore;
#contractArtifactStore: ContractArtifactsStore;

#log = createDebugLogger('aztec:archiver:data-store');

Expand All @@ -54,6 +57,15 @@ export class KVArchiverDataStore implements ArchiverDataStore {
this.#messageStore = new MessageStore(db);
this.#contractClassStore = new ContractClassStore(db);
this.#contractInstanceStore = new ContractInstanceStore(db);
this.#contractArtifactStore = new ContractArtifactsStore(db);
}

getContractArtifact(address: AztecAddress): Promise<ContractArtifact | undefined> {
return Promise.resolve(this.#contractArtifactStore.getContractArtifact(address));
}

addContractArtifact(address: AztecAddress, contract: ContractArtifact): Promise<void> {
return this.#contractArtifactStore.addContractArtifact(address, contract);
}

getContractClass(id: Fr): Promise<ContractClassPublic | undefined> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
type UnencryptedL2BlockL2Logs,
} from '@aztec/circuit-types';
import { Fr, INITIAL_L2_BLOCK_NUM } from '@aztec/circuits.js';
import { type ContractArtifact } from '@aztec/foundation/abi';
import { type AztecAddress } from '@aztec/foundation/aztec-address';
import {
type ContractClassPublic,
Expand Down Expand Up @@ -71,6 +72,8 @@ export class MemoryArchiverStore implements ArchiverDataStore {
*/
private l1ToL2Messages = new L1ToL2MessageStore();

private contractArtifacts: Map<string, ContractArtifact> = new Map();

private contractClasses: Map<string, ContractClassPublic> = new Map();

private privateFunctions: Map<string, ExecutablePrivateFunctionWithMembershipProof[]> = new Map();
Expand Down Expand Up @@ -438,4 +441,13 @@ export class MemoryArchiverStore implements ArchiverDataStore {
messagesSynchedTo: this.lastL1BlockNewMessages,
});
}

public addContractArtifact(address: AztecAddress, contract: ContractArtifact): Promise<void> {
this.contractArtifacts.set(address.toString(), contract);
return Promise.resolve();
}

public getContractArtifact(address: AztecAddress): Promise<ContractArtifact | undefined> {
return Promise.resolve(this.contractArtifacts.get(address.toString()));
}
}
3 changes: 3 additions & 0 deletions yarn-project/archiver/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
},
{
"path": "../types"
},
{
"path": "../noir-contracts.js"
}
],
"include": ["src"]
Expand Down
5 changes: 5 additions & 0 deletions yarn-project/aztec-node/src/aztec-node/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import {
} from '@aztec/circuits.js';
import { computePublicDataTreeLeafSlot } from '@aztec/circuits.js/hash';
import { type L1ContractAddresses, createEthereumChain } from '@aztec/ethereum';
import { type ContractArtifact } from '@aztec/foundation/abi';
import { AztecAddress } from '@aztec/foundation/aztec-address';
import { createDebugLogger } from '@aztec/foundation/log';
import { type AztecKVStore } from '@aztec/kv-store';
Expand Down Expand Up @@ -764,6 +765,10 @@ export class AztecNodeService implements AztecNode {
});
}

public addContractArtifact(address: AztecAddress, artifact: ContractArtifact): Promise<void> {
return this.contractDataSource.addContractArtifact(address, artifact);
}

/**
* Returns an instance of MerkleTreeOperations having first ensured the world state is fully synched
* @param blockNumber - The block number at which to get the data.
Expand Down
6 changes: 3 additions & 3 deletions yarn-project/aztec-node/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
{
"path": "../p2p"
},
{
"path": "../protocol-contracts"
},
{
"path": "../prover-client"
},
Expand All @@ -50,9 +53,6 @@
},
{
"path": "../world-state"
},
{
"path": "../protocol-contracts"
}
],
"include": ["src"]
Expand Down
3 changes: 1 addition & 2 deletions yarn-project/bb-prover/src/prover/bb_prover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import {
type PublicInputsAndRecursiveProof,
type PublicKernelNonTailRequest,
type PublicKernelTailRequest,
PublicKernelType,
type ServerCircuitProver,
makePublicInputsAndRecursiveProof,
} from '@aztec/circuit-types';
Expand Down Expand Up @@ -181,7 +180,7 @@ export class BBNativeRollupProver implements ServerCircuitProver {
): Promise<PublicInputsAndRecursiveProof<PublicKernelCircuitPublicInputs>> {
const kernelOps = PublicKernelArtifactMapping[kernelRequest.type];
if (kernelOps === undefined) {
throw new Error(`Unable to prove kernel type ${PublicKernelType[kernelRequest.type]}`);
throw new Error(`Unable to prove kernel type ${kernelRequest.type}`);
}

// We may need to convert the recursive proof into fields format
Expand Down
3 changes: 1 addition & 2 deletions yarn-project/bb-prover/src/test/test_circuit_prover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import {
type PublicInputsAndRecursiveProof,
type PublicKernelNonTailRequest,
type PublicKernelTailRequest,
PublicKernelType,
type ServerCircuitProver,
makePublicInputsAndRecursiveProof,
} from '@aztec/circuit-types';
Expand Down Expand Up @@ -265,7 +264,7 @@ export class TestCircuitProver implements ServerCircuitProver {
const timer = new Timer();
const kernelOps = SimulatedPublicKernelArtifactMapping[kernelRequest.type];
if (kernelOps === undefined) {
throw new Error(`Unable to prove for kernel type ${PublicKernelType[kernelRequest.type]}`);
throw new Error(`Unable to prove for kernel type ${kernelRequest.type}`);
}
const witnessMap = kernelOps.convertInputs(kernelRequest.inputs);

Expand Down
22 changes: 11 additions & 11 deletions yarn-project/circuit-types/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
export { CompleteAddress, GrumpkinPrivateKey, type PartialAddress, type PublicKey } from '@aztec/circuits.js';
export * from './auth_witness.js';
export * from './aztec_node/rpc/index.js';
export * from './body.js';
export * from './function_call.js';
export * from './notes/index.js';
export * from './messaging/index.js';
export * from './interfaces/index.js';
export * from './l2_block.js';
export * from './body.js';
export * from './l2_block_downloader/index.js';
export * from './l2_block_source.js';
export * from './public_data_witness.js';
export * from './tx_effect.js';
export * from './logs/index.js';
export * from './merkle_tree_id.js';
export * from './messaging/index.js';
export * from './mocks.js';
export * from './notes/index.js';
export * from './packed_values.js';
export * from './public_data_witness.js';
export * from './public_data_write.js';
export * from './simulation_error.js';
export * from './sibling_path/index.js';
export * from './simulation_error.js';
export * from './tx/index.js';
export * from './tx_effect.js';
export * from './tx_execution_request.js';
export * from './packed_values.js';
export * from './interfaces/index.js';
export * from './auth_witness.js';
export * from './aztec_node/rpc/index.js';
export { CompleteAddress, type PublicKey, type PartialAddress, GrumpkinPrivateKey } from '@aztec/circuits.js';
8 changes: 8 additions & 0 deletions yarn-project/circuit-types/src/interfaces/aztec-node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
type PUBLIC_DATA_TREE_HEIGHT,
} from '@aztec/circuits.js';
import { type L1ContractAddresses } from '@aztec/ethereum';
import { type ContractArtifact } from '@aztec/foundation/abi';
import { type AztecAddress } from '@aztec/foundation/aztec-address';
import { type Fr } from '@aztec/foundation/fields';
import {
Expand Down Expand Up @@ -218,6 +219,13 @@ export interface AztecNode {
*/
getProtocolContractAddresses(): Promise<ProtocolContractAddresses>;

/**
* Method to add a contract artifact to the database.
* @param aztecAddress
* @param artifact
*/
addContractArtifact(address: AztecAddress, artifact: ContractArtifact): Promise<void>;

/**
* Gets up to `limit` amount of logs starting from `from`.
* @param from - Number of the L2 block to which corresponds the first logs to be returned.
Expand Down
Loading

0 comments on commit 308154b

Please sign in to comment.