diff --git a/circuits/cpp/src/aztec3/constants.hpp b/circuits/cpp/src/aztec3/constants.hpp index 24007139653..e12367a17bb 100644 --- a/circuits/cpp/src/aztec3/constants.hpp +++ b/circuits/cpp/src/aztec3/constants.hpp @@ -39,6 +39,7 @@ constexpr size_t RETURN_VALUES_LENGTH = 4; * */ +// docs:start:constants // "PER CALL" CONSTANTS constexpr size_t MAX_NEW_COMMITMENTS_PER_CALL = 4; constexpr size_t MAX_NEW_NULLIFIERS_PER_CALL = 4; @@ -63,6 +64,7 @@ constexpr size_t MAX_OPTIONALLY_REVEALED_DATA_LENGTH_PER_TX = 4; constexpr size_t MAX_READ_REQUESTS_PER_TX = MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL * MAX_READ_REQUESTS_PER_CALL; constexpr size_t NUM_ENCRYPTED_LOGS_HASHES_PER_TX = 1; constexpr size_t NUM_UNENCRYPTED_LOGS_HASHES_PER_TX = 1; +// docs:end:constants //////////////////////////////////////////////////////////////////////////////// // ROLLUP CONTRACT CONSTANTS - constants used only in l1-contracts diff --git a/docs/README.md b/docs/README.md index 46724437cf9..625823e2be1 100644 --- a/docs/README.md +++ b/docs/README.md @@ -118,3 +118,8 @@ You can embed code snippets into a `.md`/`.mdx` file from code which lives elsew - You can add as a last optional parameter a comma-separated list of options to tweak the display of the code block, for example: - `#include_code hello path/from/repo/root/to/file.ts typescript noTitle,noLineNumbers,noSourceLink` - Ironically, we can't show you a rendering of these examples, because this README.md file doesn't support the `#include_code` macro! + + +### Another way to include code. + +See [here](./src/components/GithubCode/index.js), although this approach is flakier, so the above `#include_code` macro is preferred. \ No newline at end of file diff --git a/docs/docs/about_aztec/roadmap/engineering_roadmap.md b/docs/docs/about_aztec/roadmap/engineering_roadmap.md new file mode 100644 index 00000000000..f5f3c8fadd1 --- /dev/null +++ b/docs/docs/about_aztec/roadmap/engineering_roadmap.md @@ -0,0 +1,265 @@ +# Engineering Wishlist + +The engineering roadmap is long. There are no timings assigned here. In a loose priority order: + +## Sandbox Community Support + +- Triage on discord / discourse / github. +- Iterating on the docs and code, given people's issues. +- Encouraging contributions to 'good first issue' issues. +- Release notes. +- Versioning. +- Aztec Improvement Proposals (AZIPs) +- Aztec Requests for Comment (AZRCs) + +## Benchmarking + +- Gather metrics about everything, to guide future decisions. + +## Standardisation efforts + +- Recommended Aztec smart contract coding patterns +- Access Control (whitelists/blacklists) - probably needs the Slow Updates tree (or something similar). +- Basic _example_ private tokens + - Including recursive calls to 'get_notes'. +- Compliant private tokens +- Private NFTs +- Public tokens +- Depositing and withdrawing tokens + - L1<\>L2 + - public<\>private +- The Aztec Connect bridging pattern +- Using Keys (the fully-featured version of keys that we want to build) +- Plume nullifiers +- Negative reputation example +- Anti-denial-of-service +- Combining Aztec with MPC + +## Polishing what we have + +- Refactoring sprints. + - Reduce tech debt. + - More tests. + +## Enforcing correct ordering Public & Private State Transitions + +## Enforcing correct ordering of other 'side effects' +- Log ordering +- Enqueued public function calls + +## What data actually needs to be submitted on-chain? +- For Public Functions: + - Just emit the initially-enqueued public function request data? (The 'inputs' of the tx); + - I.e. contract address, function selector, args, call_context. + - OR, Just emit the final state transitions? (The 'outputs' of the tx) + - I.e. the leaf indices and new values of the public data tree; and the new commitments/nullifiers of the private data tree; and logs; and l2->L1 messages. + +## Proper specs + +- Write detailed specs, given recent protocol changes. +- Review the code to ensure it matches what we _think_ the protocol is. +- Open issues to ensure the code matches the spec. +- (Note: bringing cryptographers into the fold (to review specs) is a separate section, later in this doc). + +## Iterate on the Sandbox + +Based on community feedback, we'll need some teams to iterate on Sandbox features and fix bugs. + +## Iterate on the Aztec Smart Contract Library + +## Iterating on CI + +CI takes up a significant amount of time. It gets its own section here, so we remember it exists. + +## Sequencer & Prover Selection protocols + +- Decide on protocol +- Spec +- Build. + +## Upgradeability + +- Decide on protocol +- Spec +- Build. + +## Fees + +- Design the Protocol + - Interdependence on the Sequencer & Upgradeability protocols. + - Pay fees in 1 currency, or fee abstraction? + - Escrowing fees + - Rebates + - L1->L2 message fees. + - L2->L1 fees + - Etc. +- Build it. + - Gas metering + - Etc. + +## Note Discovery + +- Note Discovery RFP +- Decide on the protocol +- Spec +- Build it. + +## Privacy-preserving queries to public nodes + +- Explore PIR +- Explore alternatives +- Implement + +## Keys + +- Write up keys spec +- Get internal comments +- Do a RFC from the external community +- Implement + +## Slow Updates tree? + +We _need_ a way to read mutable public data from a private function. + +## Contract classes and instances? + +- There's a suggestion to introduce contract classes. + +## Delegatecalls vs SetCode +- Which? (if at all) + +## Remove the contracts tree? 🤯 + +- There's a suggestion to remove the notion of a contracts tree. What do we actually need the tree for? To check that a vk hash exists for a particular contract address? +- If the contract address contains the function tree, and it also contains data about the constructor args to that contract, then perhaps we don't need the contract tree to exist. +- We might still need the notion of a 'deployment': + - to broadcast a contract's bytecode; + - to 'reserve' a contract address; + - and possibly to prevent a constructor from being executed twice (although an app could do this ("constructor abstraction")). + +## Cryptography review checkpoint + +- Once we have specs (see above), we should review the rigour and secureness to our protocol. + - Choice of hashes + - Domain separation + - Choice of encryption scheme + - Keys + - A security review of the protocol as a whole + +## Testing UX team + +A team focussed on testing and debugging UX. +This team should have free rein to design and add any features they see fit. + +Some example features: +- Writing contract tests in Noir. + - Mocking oracles. +- Taking inspiration from other testing frameworks. +- Much more detailed logging if things go wrong. +- Errors which only spit out opaque 254-bit hex numbers are bad. + - Ensure all circuits are fed the human-readable information underlying all of these hex numbers. + - If tree root comparisons (expected vs actual) fail, human-readable details about the leaves in trees should be provided. + +## Tooling + +## Proper Circuits + +### Redesign +- The Bus + - The bus will have an impact on the way we design the circuit logic. + - We can hopefully avoid hashing in circuit 1 and unpacking that hash in circuit 2. + - Understand the 'bus' and how we can use it to pass variable amounts of data between recursive circuit iterations. + - Redesign all circuit logic to allow for the variable-sized arrays that the 'bus' enables. +- Enable 'dynamic/variable-sized **loops**' + - allow each `for` loop (eg read requests, insertions, commitment squashing, call stack processing, bip32 key derivation, etc.) to vary in size, by deferring each loop to its own final circuit. This would require complex folding stuff. + - This would give much more flexibility over the sizes of various arrays that a circuit can output. Without it, if one array of an app circuit needs to be size 2000, but other arrays aren't used, we'd use a kernel where every array is size 2048, meaning a huge amount of unnecessary loops of computation for those empty arrays. +- Improvements + - We can definitely change how call stacks are processed within a kernel, to reduce hashing. + - Squash pending commitments/nullifiers in every kernel iteration, to enable a deeper nested call depth. +- Topology of a rollup + - Revisit the current topology: + - We can make the rollup trees 'wonky' (rather than balanced), meaning a sequencer doesn't need to prove a load of pointless 'padding' proofs? + - This would also enable new txs (entering the tx pool) to be added to a rollup block 'on-the-fly' (mid way through a rollup being proven) - but of course, the sequencer selection protocol might require an up-front commitment, so this might not be possible for that reason (sad face). + - We can definitely redesign the public kernel circuit to be a '2x2' topology (i.e. a tree of public kernel proofs), to get a logarithmic speed-up (parallelism). The question is, with folding schemes, do we need that optimisation? + +#### Refactor of packing & unpacking data in circuits + +We often pack data in circuit A, and then unpack it again in circuit B. +- args_hash +- return_values_hash +- call stacks +- read requests +- etc. + +Also, for logs in particular, we allow arbitrary-sized logs. But this requires sha256 packing inside an app circuit (which is slow) (and sha256 unpacking in Solidity (which is relatively cheap)). Perhaps we also use the bus ideas for logs, to give _some_ variability in log length, but up to an upper bound. + +Also, we do a lot of sha256-compressing in our kernel and rollup circuits for data which must be checked on-chain, but grows exponentially with every round of iteration. E.g.: new contract deployment data, new nullifiers, new commitments, public state transition data, etc. This might be unavoidable. Maybe all we can do is use polynomial commitments when the EIP-4844 work is done. But maybe we can use the bus for this stuff too. + +### Write proper circuits + +### The Public VM Circuit + +- Design it +- Build it + +### The Brillig Bytecode Commitment Circuit + +- A circuit which proves the brillig bytecode being emitted matches the polynomial commitment to that bytecode. + +### Decide on constants! + +### Honk -> Ultra Squisher Circuit + +### Ultra -> Standard Squisher Circuit + +## Authentication: access to private data +- Private data must not be returned to an app, unless the user authorises it. + +## Validation: preventing execution of malicious bytecode +- A node should check that the bytecode provided by an application for a given app matches the leaf in the contract tree to ensure that user doesn't execute unplanned code which might access their notes. + +## Fuzz Testing + +## Formal Verification + +An investigation into how formal verification techniques might improve the security of Aztec software. + +## P2P network + +- A robust p2p network for the tx pool and the proof pool. + +## Hashes + +- An improved, standardised Pedersen hash in barretenberg. +- Poseidon hashing in barretenberg. + +## Tree epochs +- Nullifier tree epochs +- Maybe other tree epochs. + +## Chaining txs +- We have the ability to spend pending notes (which haven't-yet been added to the tree) _within the context of a single tx_. +- We need the ability to spend pending notes (which haven't yet been added to the tree) across different txs, within the context of a single rollup. + - This happens if Alice generates two txs X & Y, where tx Y spends notes from tx X. If we want Alice to be able to generate these txs in parallel (without interacting with the network at all), we need a way for tx Y to spend notes before they've been added to the tree. The 'chaining tx' concepts from Aztec Connect can enable this. +- This added _a lot_ of complexity to Aztec Connect. Especially around fees, iirc. Caution needed. + +## EIP-4844 + +- Understand it. Spec it. Build it. +- Includes: + - Smart Contract changes + - Circuit changes + - A circuit to prove equivalence vs a BLS12-381 polynomial commitment. + +## Make it all work in a browser + +## Code Freeze + +## Internal Audit + +## External Audits + + + + + diff --git a/docs/docs/about_aztec/roadmap/features_initial_ldt.md b/docs/docs/about_aztec/roadmap/features_initial_ldt.md index 223eecb410e..f85c0bc28bf 100644 --- a/docs/docs/about_aztec/roadmap/features_initial_ldt.md +++ b/docs/docs/about_aztec/roadmap/features_initial_ldt.md @@ -1,14 +1,10 @@ --- -title: Sandbox +title: Initial Sandbox Features --- -:::info -We're aiming for a minimal version of an Aztec Sandbox -- with the below features -- in Q3. -::: +The Aztec Sandbox is intended to provide developers with a lightweight & fast node, with features similar to Ethereum's Ganache or Anvil 'local node' packages. -The Aztec Sandbox Node is intended to provide developers with a lightweight & fast node, with features similar to Ethereum's Ganache or Anvil 'local node' packages. - -Devs should be able to quickly spin up local, emulated instances of an Ethereum blockchain and an Aztec encrypted rollup, and start deploying confidential contracts and submitting confidential txs. +Devs should be able to quickly spin up local, emulated instances of an Ethereum blockchain and an Aztec encrypted rollup, and start deploying private contracts and submitting private txs. Here's a summary of the features we intend to support with the first release of the Aztec Sandbox. @@ -16,22 +12,22 @@ Here's a summary of the features we intend to support with the first release of - Noir `contract` scopes. - Declare a `contract`, containing a collection of state variables and functions. -- `secret` state variables: - - `read`, `write`, and `delete` `secret` state variables within `secret` functions. -- public (non-`secret`) state variables: +- private state variables: + - `read`, `write`, and `delete` private state variables within private functions. +- public (non-private) state variables: - Manipulate 'public' state in a familiar way to Ethereum state. -- `secret` functions - - May read and modify `secret` state. +- private functions + - May read and modify private state. - public functions - May read and modify public state. - `constructor` functions, for initialising contract state. - `import` other Noir contracts, so their functions may be called. - Nested function calls, for contract composability - - `secret` functions can call `secret` functions of other contracts, and receive return values. - - `secret` functions can call public functions any contract. - - public functions can call `secret` functions of any contract. + - private functions can call private functions of other contracts, and receive return values. + - private functions can call public functions any contract. + - public functions can call private functions of any contract. - public functions can call public functions of other contracts, and receive return values. - - `secret` functions can be called recursively. + - private functions can be called recursively. - public functions can be called recursively. - Send messages from Noir contracts to Ethereum L1, for consumption by L1 smart contracts. - Useful, for example, if writing an app to withdraw funds from L2 to L1. @@ -63,7 +59,7 @@ A typescript wrapper for making RPC calls to an Aztec LDT node. A bundle of packages which emulate the actions of all eventual Aztec network participants. The goal is for developer experience to be akin to Ganache / Anvil. - Aztec RPC Client - - Simulate and/or execute `secret` functions locally. + - Simulate and/or execute private functions locally. - Aztec Public Node - Broadcasts a user's txs to the tx pool. - Simulate public functions locally. diff --git a/docs/docs/about_aztec/roadmap/main.md b/docs/docs/about_aztec/roadmap/main.md index e69de29bb2d..b54fb257263 100644 --- a/docs/docs/about_aztec/roadmap/main.md +++ b/docs/docs/about_aztec/roadmap/main.md @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/docs/docs/about_aztec/roadmap/milestone1_1.md b/docs/docs/about_aztec/roadmap/milestone1_1.md deleted file mode 100644 index 289e4b1afa5..00000000000 --- a/docs/docs/about_aztec/roadmap/milestone1_1.md +++ /dev/null @@ -1,529 +0,0 @@ ---- -title: Milestone 1.1 - Deploying a contract ---- - -See [here](./) for draft milestones. - -See [here](https://drive.google.com/file/d/1riqr23R-VOAwOAzpgRj40tsAfq0ZA5yO/view?usp=share_link) for an unfinished (but maybe helpful) contract deployment sequence diagram, and other tabs for other useful diagrams. - -See [here](../../concepts/advanced/contract_creation) for more on Contract Creation. - -## Reminder of the milestone: - -> As a developer, I can write a Noir++ contract scope, which contains a collection of pure functions (circuits) (no state variables yet). -> -> I can type `noir my_contract.nr` to compile a Noir contract to a JSON abi (or, hand craft the JSON abi). -> -> I can type `aztec-cli deploy_contract my_contract_abi.json` and have a contract deployed to my local network. -> -> I can type `aztec-cli get_code address` to verify my contract has been deployed successfully. - -The aim is to keep the implementation _as simple as possible_. We want to achieve the appropriate state shift on L1, and avoid anything that feels like unnecessary boiler-plate, or just "vanilla engineering". We're avoiding databases, network io, optimisations etc. Most of the code in this milestone should be directly related to computing and making the requisite state shift, otherwise we maybe going out of scope. - -## Further explanation: - -It'll basically require the infrastructure needed to maintain the contracts tree, and the ability to construct and insert a leaf into it: - -![](https://hackmd.io/_uploads/ryuFWjFco.png) - -Note: some other data will also need to be broadcast as calldata on-chain, for data availability purposes. E.g. the ACIR opcodes of each newly-deployed contract. - -## High Level Architecture - -Greyed out components don't need to exist at all for this milestone, but basically everything will need to exist in some capacity (even if some parts are heavily simulated). - -![](https://hackmd.io/_uploads/SJuHodIJn.png) - -This spec uses `snake_case` for it's naming, however in the world of TypeScript we should adapt these names as appropriate to be `camelCase`. - -## Communications Layer - -Although we often speak about "JSON RPC", this is a transport layer concept, and is not actually needed for this milestone. - -The various services and modules should be defined as TypeScript interfaces. Functions that take arguments and return results. We will start by just implementing these interfaces directly, and running the stack as a single monolith. We can then implement them as individual services a bit later by just auto-generating the JSON RPC http client code and server handlers. We have this pattern already between e.g. falafel and halloumi. Halloumi can just be run as a module within the falafel process, or run as a separate service. - -## Proving System - -There will be no proofs generated in early milestones. Functions that would normally build an actual proof can be skipped (or be no-ops). The simulators should produce output that is identical to a proof output, just without the actual proof data (e.g. just the `public_inputs`). The kernel simulator and rollup simulator, will use the exact same C++ circuit logic, only the simulator will use native machine types so it's fast. - -## Thinking About State - -The lowest level system state is represented by one or more streams of data. In AC this was the calldata and the off-chain data. Aztec will likely have it's state also represented as more than one stream of data. For this milestone we could just adopt a similar separation of data, although longer term some state might make it's way into [danksharding](https://ethereum.org/en/roadmap/danksharding/) blobs, and maybe some state won't go to the ethereum network at all. - -Regardless, there should be a separation of concern between the stream of data, and how/where it's stored. Data should be stored unprocessed, in an implementation of a simple key-value store interface. So e.g. there maybe a component that when pointed at the rollup contract, stores the calldata for each rollup in a key-value implementation that just saves it to a file named by rollup number. - -A higher level component can take those multiple streams of data, and reconcile them to produce another single stream of data, the full data to describe a single rollup. These tasks will be handled by the data archiver, allowing querying of the data archiver for rollups > n. - -The Private Client will have different methods for acquiring the data needed to produce its own data streams (one stream of data per account, effectively filtering the full chain state down to just the events relevant to that account). - -- Brute force. -- Nym message protocol. -- Oblivious Message retrieval. -- Hybrids and new wonderful things? - -The output streams of these technologies are the same, making them interchangeable. This stream of data represents the state shifts from the perspective of a single account. For this milestone we will just brute force. - -There are a few considerations to make when processing state: - -- State events are immutable (save and forget, idempotent). -- New state events can arrive at any time (consumers need to wake-to-handle). -- It grows unbounded, meaning it won't scale to "load and process all state at once". -- Traditional stream/channel concepts lend themselves well to ingesting, transforming, and outputting state. - -Think of something like "Go channels" in terms of design (our MemoryFifo was written to leverage this pattern). Whereas a stream is often thought of as a buffered stream of bytes, channels are more like a buffered stream of messages. The SDK in AC has an example of how to do this. The BlockDownloader is told to start from a certain block number. It will build up an internal buffer of rollups in its "channel" (queue) till it hits some limit. A consumer calls `getRollup` which will block until a rollup is returned. Thus the consumer can have simple "synchronous" control flow loop. The code can also then be run naturally against a fixed size data store (it would just never block). It can act as a simple transformer, ingesting a directory of files and outputting another directory of files. This should also make isolated unit testing simple. - -From an account perspective, as we process the accounts data stream, we will need to process the data through a simulator to execute contract specific filtering logic. This kind of transform changes the stream of data events into a snapshot. The final data representation thus maybe a set of key-values where a key is a storage slot, and a value maybe e.g. the sum of all UTXOs (the accounts balance). - -The takeaway of this is to not get carried away with high level databases and indexes at this point, but to think of data as streams of data with simple low level representations. The transformations should be simple, modular, easily testable, and reusable in different environments (via storage abstraction). - -## Interfaces and Responsibilities - -It's important to define some key concepts as interfaces. These can be categorised as either data, or logic based interfaces. - -Data interfaces are about retrieving and/or updating state. By using the right abstractions, it will be possible to: - -- Mock sources of data for use in unit/integration tests. -- Keep logic narrowly scoped to dealing with specific bits of data. -- Avoid dealing with databases for now. -- Take shortcuts that allow us to focus on protocol development and not get bogged down in privacy concerns. e.g: - - Use a `SiblingPathSource` that just queries the remote `PublicClient` for a contracts sibling path. - - This normally would be a privacy concern, but it may not be if: - - Technologies like Nym work out over the longer term. - - The dapp can provide the paths as they're immutable. - - Otherwise we can substitute in a local cache of the contract tree at a later date. - -Logic interfaces are about executing specific bits of functionality. By using the right abstractions it will be possible to: - -- Mock and dependency inject functionality for use in unit/integration tests. -- Ignore the writing of network code for now. -- Allow complete flexibility in terms of which components run in process, and which become remote. -- Run the stack quickly as a monolith for development and integration testing. - -### KeyStore - -Responsibilities: - -- Holds and never exposes private keys. -- Provides sign/decrypt functionality. - -Interface: - -- `create_account(): PublicKey` - - Creates and stores a (ecdsa?) keypair and returns public key. -- `get_accounts(): PublicKey[]` - - Returns all the public keys. -- `sign_tx_request(account_pub_key, tx_request): Signature` - - Produces a signature over the given `tx_request`. -- `decrypt(account_pub_key, data, eph_pub_key): Buffer` - - Decrypts data with a shared secret derived from an account private key and given ephemeral public key. - - Will need to be scoped in some way, such that the user can authorize a particular domain, to decrypt a particular scope of data. - -### AztecRpcClient (Previously Wallet/Private Client) - -Responsibilities: - -- Shields any upstream entities (dapp) from private information. -- Shields any downstream entities (Public Client) from private information. -- Maintains an up-to-date view of required parts of the global state from state streams to generate a tx. -- Maintains an up-to-date view of state for accounts in a `KeyStore`. - -Interface: - -- `create_account(): PublicKey` - - Forward to `KeyStore` -- `get_accounts(): PublicKey[]` - - Forward to `KeyStore` -- `sign_tx_request(account_pub_key, tx_request): Signature` - - Forward to `KeyStore` -- `simulate_tx(tx_request): SimulationResponse` - - Simulates the execution of a transaction. Returns: - - If the simulation succeeded. - - The `public_inputs` of the kernel circuit. - - In the future, gas estimates. -- `create_tx(tx_request): Tx` - - Simulates the execution of a transaction to produce all data needed to generate a proof. - - Generates and returns the actual kernel proof. -- `send_tx(tx): void` - - Forwards the given tx to the `PublicClient`. - -### PublicClient - -Responsibilities: - -- Acts largely as a facade to sub-systems. -- Provide methods for access Merkle Tree data (`SiblingPathSource`). -- Provide methods for requesting storage slot data for public state. -- Provide methods for requesting published rollup data (`RollupSource`). -- Receives txs and broadcasts them to the network via the `P2PClient`. - -Interface: - -- `send_tx(tx)` - - Forwards the tx to the tx pool via `send_tx`. -- `get_rollups(from, take)` - - Returns all rollup data in the requested range. -- `get_sibling_path(tree_id, index): SiblingPath` - - Returns the sibling path for the given index in a given tree. -- `get_storage_slot(address): Buffer32` - - For public state, we can request values at given storage slot addresses. - -### P2PClient - -Responsibilities: - -- Receives txs from the `PublicClient`. -- Receives txs from other `P2PClient` instances in the network. -- Verifies received txs meet criteria to be added to the pool. -- Forwards all valid txs to other `P2PClient` instances in the network. -- Receives rollups and purges settled or now invalid txs from local pool. -- Purges txs that are older than a certain threshold from the local pool. - -Interface: - -- `send_tx(tx)` - - Verifies the `tx`, if valid, add to local pool and forward to other peers. - - Passes proof verification. - - No conflicting commitments/nullifiers in tx pool and existing trees. - - Sane fee. - - Txs data root reference is still within the window (Tree of data roots). -- `get_txs(): Tx[]` - - Returns all transactions in the transaction pool. -- `send_proof_request` - - TBD. Not for this milestone. -- `get_proof_requests` - - TBD. Not for this milestone. - -### SiblingPathSource - -Responsibilities: - -- Returns the sibling path for the given `tree_id` at the given leaf `index`. -- Can be injected into any context that requires path queries for a particular tree. Might be backed by implementations that call out to a server (where privacy doesn't matter, or during early development), or leverages some privacy tech (query via Nym), or could just point to a local `WorldStateSynchroniser`. - -Interface: - -- `get_sibling_path(tree_id, index): SiblingPath` - -### RollupSource - -Responsibilities: - -- Can be queried for `Rollup` data. - -Interface: - -- `get_latest_rollup_id()` -- `get_rollups(from, take): Rollup[]` - -### RollupReceiver - -Responsibilities: - -- Given the necessary rollup data, verifies it, and updates the underlying state accordingly to advance the state of the system. - -Interface: - -- `process_rollup(rollup_data): boolean` - -### TxReceiver - -Responsibilities: - -- Receives a tx, performs necessary validation, and makes it available to `SequencerClient` instances for rolling up. - -Interface: - -- `send_tx(tx): boolean` - -### TxPool - -Responsibilities: - -- Gives a view of the pending transaction pool. - -Interface: - -- `get_txs(): Tx[]` - -## Module Implementation Notes - -### Noir - -These tasks are lower priority than providing a handcrafted ABI. - -- The ability for a dev to enclose a collection of Noir functions in a 'contract scope'. -- The ability to create a Noir contract abi from the above. - -Design a Noir Contract ABI, similar to a Solidity ABI which is output by Solc (see [here](https://docs.soliditylang.org/en/v0.8.13/abi-spec.html#json)). It might include for each function: - -- ACIR opcodes (akin to Solidity bytecode). -- Function name and parameter names & types. -- Public input/output witness indices? -- Sourcemap information, allowing building of stack traces in simulator error cases. - -### aztec-cli - -Provides the `aztec-cli` binary for interacting with network from the command line. It's a thin wrapper around `aztec.js` to make calls out to the client services. It's stateless. - -### aztec.js - -![](https://hackmd.io/_uploads/ryRmLLL12.png) - -Should provide sensible API, that provides the following functionalities. Start by writing the single e2e test that will check for the successful contract deployment. We don't need to get this perfect, but think hard about making the process feel very natural to a user of the library. - -aztec.js should always be stateless. It offers the ability to interact with stateful systems such as the public and private clients. - -The analogous AC component would be the AztecSdk (wraps the CoreSdk which is more analogous to the private client). - -- Allows a user to create an Aztec keypair. Call `create_account` on Wallet. -- Create a `Contract` instance (similar to web3.js), given a path to a Noir Contract ABI. -- Construct `tx_request` by calling e.g. `contract.get_deployment_request(constructor_args)`. -- Call wallet `sign_tx_request(tx_request)` to get signature. -- Call `simulate_tx(signed_tx_request)` on the Private Client. In future this would help compute gas, for now we won't actually return gas (it's hard). Returns success or failure, so client knows if it should proceed, and computed kernel circuit public outputs. -- Call `create_tx(signed_tx_request)` on Private Client to produce kernel proof. Can be skipped for this milestone. In future should be able to generate either mock (few constraints) or real proof. -- Call `send_tx(tx)` on Private Client to send kernel proof to Public Client. Get back a receipt. -- Wait until the receipt is settled with repeated calls to `get_tx_receipt` on the Private Client. - -### ethereum.js - -L1 client library. No ethers.js. Uses our existing and new L1 client code. - -### TestKeyStore - -Interfaces Implemented: - -- `KeyStore` - -Implementation notes for this milestone: - -- Exposes a single account, created by a private key given in the ctor, that defaults to some test key. -- Can be used as both the spending and decryption key for early development. - -### AztecRpcServer (Previously Wallet/Private Client) - -![](https://hackmd.io/_uploads/ryS0sOLyh.png) - -Implements: - -- `AztecRpcClient` (The server is a client, when used directly) - -Injected: - -- `KeyStore` - -Implementation notes for this milestone: - -- Avoid saving any state for now. Just resync from the `PublicClient` on startup. -- Avoid needing to sync the merkle trees for now. Just use `SiblingPathSource` that queries the paths from the `PublicClient`. -- `simulate_tx` - - Can compute the contract's leaf (which will be inserted into the contract tree). See diagram linked at top of page. - - Can spin-up a simulator instance for the constructor function. - - (Note, executing an _interesting_ constructor function is not until the next milestone, but we still need to execute a no-op constructor function for a contract deployment, since the public inputs of the constructor carry some contract deployment info, and need to passed into the kernel circuit). - - Simulator will check whether the tx will succeed. It will return all public inputs/outputs. - - Can collect/generate additional data required for kernel circuit execution. - - Can pass the fake constructor proof, public inputs, and other kernel circuit data into a kernel simulator. - - Returns if the simulation succeeded, and the public inputs/outputs of the kernel circuit. -- `create_tx` - - For this milestone, will just do the same as `simulate_tx`. - - Returns a `tx` that can be sent to `send_tx` with everything but actual proof data. -- `send_tx` - - Forwards the given tx to the Public Client. - -### PublicClientImpl - -![](https://hackmd.io/_uploads/Sksg3u8kh.png) - -Implements: - -- `PublicClient` - -Injected: - -- `P2PClient` -- `RollupSource` -- `MerkleTreeDb` - -Implementation notes for this milestone: - -- Mostly acting as a facade for other components, forwards requests as necessary. -- A `WorldStateSynchroniser` will ingest rollups from the `RollupSource` and maintain an up-to-date `MerkleTreeDb`. - - - -### MemoryP2PClient - -Implements: - -- `P2PClient` - -Injected: - -- `RollupSource` -- `MerkleTreeDb` - -Implementation notes for this milestone: - -- For this milestone there won't be any p2p network. -- Perform relevant validations possible in this milestone (e.g. check no tree conflicts, skip proof verification). -- Purge relevant txs from pool on rollup receipt. -- Store txs in an in memory map of txId -> tx. - -### Sequencer Client - -![](https://hackmd.io/_uploads/Hk823d81h.png) - -Responsibilities: - -- Wins a period of time to become the sequencer (depending on finalised protocol). -- Chooses a set of txs from the tx pool to be in the rollup. -- Simulate the rollup of txs. -- Adds proof requests to the request pool (not for this milestone). -- Receives results to those proofs from the network (repeats as necessary) (not for this milestone). -- Publishes L1 tx(s) to the rollup contract via `RollupPublisher`. - -For this milestone, the sequencer will just simulate and publish a 1x1 rollup and publish it to L1. - -### MerkleTreeDb - -Implements: - -- `SiblingPathSource` - -Implementation notes for this milestone: - -Closest analogous component in AC is the `WorldStateDb` in bb.js. We can configure the backing store (probably leveldb) to be an in-memory only store. We don't need persistence, we will rebuild the tree at startup. This will ensure we have appropriate sync-from-zero behaviour. - -Responsibilities: - -- "Persists" the various merkle trees (configurable). - - For this milestone 1.1, we'll need the following trees: - - Contract Tree - - Contract Tree Roots Tree (the tree whose leaves are the roots of historic rollups' contract trees) - - Nullifier Tree (so that the contract address can never be re-registered in a future deployment) - - Note: Suyash has implemented C++ for the 'new' kind of nullifier tree. -- Provides methods for updating the trees with commit, rollback semantics. -- Provides methods for getting hash paths to leafs in the trees. - -Interface: - -- `get_root` -- `get_num_leaves` -- `get_sibling_path` -- `append_leaves` - -### WorldStateSynchroniser - -Injected: - -- `RollupSource` -- `MerkleTreeDb` - -Responsibilities: - -- Receives new rollups from the `RollupSource` and updates trees in the `MerkleTreeDb`. - -### Rollup Archiver - -Implements: - -- `RollupSource` - -Responsibilities: - -- Pulls data in from whatever sources are needed, to fully describe a rollup e.g. - - L1 calldata (`provessRollup` and `offchainData` for this milestone.) - - ETH blobs (not before they are released). - - Other sources that have archived historical ETH blobs (not before they are released). -- Combines these sources of data to describe a `Rollup`. -- Can be queried for the rollup data. - -Interface: - -- `get_latest_rollup_id` -- `get_rollups(from, take)` - -### Rollup Publisher - -Implements: - -- `RollupReceiver` - -Implementation notes for this milestone: - -- We can leverage most of the logic from Falafels old `RollupPublisher`. -- On receipt of a rollup, will publish to L1 and respond with success or failure. - -### Rollup Smart Contract - -Interface: - -- `processRollup(proofData, l1Data)` -- `offchainData(data)` - -Implementation notes for this milestone: - -The rollup contract in AC holds data in two places that are reconciled when processing the rollup. The calldata passed into the `processRollup` function, and the calldata passed into the `offchainData` function. They were separated, as only the data given to `processRollup` is needed to ensure rollup liveness (i.e. if the "offchain data" were not published, we could still produce rollups). Ultimately the plan was to move the offchain data off of L1 altogether to reduce costs. - -For this milestone, we will want to leverage a similar separation of data. The data to `processData` will consist of: - -- `proofData` - The proof data to be fed to the verifier. Likely will have a public inputs that represent: - - The hash of the data in the offchain data (should use whatever commitment scheme Eth Blobs will use). - - Recursion point fields. -- `l1Data` - Data that is needed for making L2 - L1 function calls. - -For logic: - -- Can receive a rollup proof and verify it (verifier just returns true for this milestone). -- Can update the state hash (which would only represent an update to the contract tree, at this milestone). - -For `offchainData`: - -- Receives relevant calldata that needs to be broadcast. For contract deployment, this might be: - - Acir opcodes. - - Constructor arguments. - - Contract address & contract leaf. - -### Kernel Circuit functionality - -- Can validate the signature of a signed tx object. -- Can verify a 'previous' mock kernel circuit (this code is already in there). -- Can verify the constructor function's proof (this functionality is already in there). -- Can check contract deployment logic. (Note: it won't contain checks for private circuit execution logic, as that's for a future milestone). - -### Rollup Circuit functionality - -- TODO: more discussion needed to understand exactly what's needed here. -- Can verify a kernel circuit proof -- Can compute the contract's address -- Can compute a 'nullifier' for the contract's address, to prevent it being used again (possibly defer this, because we don't want to care about a nullifier tree in this milestone). -- Can compute the contract leaf for the contract (see diagrams). -- Can insert the contract's leaf into the contract tree. -- Can insert the contract tree's root into a "tree of contract tree roots". -- ???? Verifies the ACIR Verification proof (see Contract Creation doc by Zac) - -## Glossary - -- `witness`: Any value within the circuit, by default these are private, and thus not visible on the proof. Some witnesses may be made public (visible on the proof), at which point they also become `public_inputs`. -- `[circuit_]input`: Data that is computed outside the circuit and is fed in at the beginning as a `witness`. Note: if the context of this relating to a 'circuit' is already clear, we can omit `circuit_`, as is done in the `aztec3_circuits` repo. -- `oracle_input`: Data that, during execution, is fetched from the oracle, and made a `witness`. -- `computed_public_input`: Data that is computed within the circuit, and set to be a `public_input`. -- `public_input`: Data that is set to be public by the circuit. This could include some `circuit_input` data, and/or some `computed_public_input` data, and/or some `oracle_input` data. - -## Participate - -Keep up with the latest discussion and join the conversation in the [Aztec forum](https://discourse.aztec.network). - -import Disclaimer from "../../misc/common/\_disclaimer.mdx"; - \ No newline at end of file diff --git a/docs/docs/about_aztec/roadmap/milestones.md b/docs/docs/about_aztec/roadmap/milestones.md deleted file mode 100644 index 842a3f7fe7e..00000000000 --- a/docs/docs/about_aztec/roadmap/milestones.md +++ /dev/null @@ -1,493 +0,0 @@ ---- -title: Milestones Overview ---- - -The milestones are written as sets of user stories to make it clear what functionality will be available as we work through each one. - -## Development Strategy - -The goal is that all software components of Aztec can be developed as independent modules (e.g. private client, public client, simulators, data sources/sinks, circuit architecture, RPC, cryptography). - -When modules need to communicate across module boundaries, they do so via clearly defined APIs. - -When developing a module, these external API calls can be mocked. Each module's suite of unit tests ideally are completely independent of other module implementations (i.e. all external API calls are mocked). - -The goal is to enable parallel development of these milestones, where teams are not bottlenecked by the progress of other teams. - -For a milestone to be complete, full integration tests must be implemented that interact across module boundaries. - ---- - -### 1.0 - Repo setup ✅ - -Separate Barretenberg into its own repository. - -Create a monorepo (`aztec3-packages`) for the Local Developer Testnet codebase. - ---- - -### 1.1 - Deploy a contract ✅ - -See granular tasks [here](./milestone1_1). - -As a developer, I can write a Noir `contract` scope, which contains a collection of pure functions (circuits) and a noop `constructor` function (no state variables yet). - -I can compile my contract with Noir, and receive a contract ABI JSON. - -I can deploy my new Noir Contract via `aztec.js`. - -I can verify, via `aztec.js`, that my Noir Contract has been deployed successfully to the Local Developer Testnet. - ---- - -### 1.2 - Nullifier functionality ✅ - -We need nullifier infrastructure, and it's complex enough to be its own milestone. It makes most sense to develop it at this stage. Here's an attempt to shoe-horn it into a user story: - -As a developer, I can only deploy to an Aztec contract address once. Attempts to duplicate a contract address will be rejected by the network. - -Each tx request contains a nonce. For private functions, such a nonce will be emitted as a nullifier (to prevent re-use of that nonce). - ---- - -### 1.3 - Private Constructor ✅ - -As a developer, I can declare private state variables in the global `contract` scope of my Noir Contract. - -I can write a `constructor` function in Noir, which initialises private states within my contract (i.e. which pushes new commitments to the network). For this milestone, these private states will only be owned by the deployer. - -I can deploy my new contract, which calls a constructor function to initialise private state. - -> Note: the constructor arguments could be included in the abi.json, similar to a Solidity ABI. - -I can verify, via `aztec.js`, that my private state(s) were initialised correctly. (Note: obviously a user can only do this if they own the state at that storage slot). - ---- - -### 1.4 - A single Private Function Call ✅ - -As a developer, I can write a `secret` function in Noir. This function can read private states, modify (nullify) private states, and store updates to private states. - -I can deploy a contract containing such functions to the network. - -As a user, I can create a tx request to execute any external, private function (by name, via `aztec.js`). I can generate a zk-proof of having executed the private function, then a private kernel proof that the execution adheres to network rules, and send that kernel proof to the network. In the Local Developer Testnet, that tx will be included in the next block. The private function can initially only create commitments owned by the caller. - -I can view the status of my transaction on the local network, via `aztec.js`. - ---- - -### 1.5 - A single Private Function Call (editing others' states) ⚙️ - -As per the previous milestone, but with the ability to call a function which edits other people's private states. - -As a developer, I can write `unconstrained` functions in Noir, which allow me to query Aztec state variables without broadcasting a tx to the network (much like the `getBalance()` function of an ERC20 contract). - -As a user, I can share the preimages of private state edits with the owners of those private states (e.g. by broadcasting the encrypted preimage on-chain). - -As a recipient of an edited state, my RPC Client can update it's DB with this state update (e.g. via trial-decryption). - -As a recipient of an edited state, I can query the current value of my state variable(s) via `unconstrained` function(s), to verify that they've been edited. - ---- - -## 2: L1-L2 Communication - -### 2.1 - Deploy a Portal Contract - -As a developer, I can write a Portal Contract to accompany my Noir++ contract. - -I can deploy the Portal Contract to Ethereum, and then deploy and Aztec L2 contract which links with the Portal Contract. - -I can make a query to the Private Client to learn the Portal Contract address of an L2 contract. - -I can make a query to L1 to learn the L2 address for a particular Portal Contract. - -Components: l1-contracts, kernel-circuit, aztec-rpc, - ---- - -### 2.2 - L1->L2 Calls - -As a developer, I can deploy a 'Portal Contract' to Ethereum (L1), which allows me to write logic across L1 and L2 for my dapp. - -I can write Solidity code in my Portal Contract which can 'send messages' to a particular function of the linked L2 contract. - -I can write Noir code which can 'read' messages from the L1->L2 message box. - -I can send an Ethereum tx which calls a function of the Portal Contract, which in-turn sends an L1->L2 message. - -I can then send an L2 tx which calls an L2 function, which 'reads' (consumes) the message. - ---- - -### 2.3 - L2->L1 Calls - -As a developer, I can write Noir code (in my Noir Contract) which can 'send messages' to my Noir Contract's corresponding Portal Contract (on L1). - -I can send an Aztec tx which calls a private (or public) function, which can send the intended message to L1, via the Rollup Contract. - -I can then send an Ethereum tx to my Portal Contract (or some other contract), which can 'read' (consume) the message. - -> Note: We might need to submit an encryption of L2->L1 messages to the `unverifiedData` on-chain (so that a user can re-sync and still find the messages they sent!) - ---- - -## 3: Private call stacks - -### 3.1 - Inter-contract Private -> Private Calls ⚙️ - -> Note: intRA private->private calls can be inlined, in most cases. - -As a developer, I can deploy 2 Noir Contracts. One contract can `import` the interface of the other. - -A `private` function of the importing contract can call a `private` function of the imported contract, passing arguments, and receive return values. - -As a user, I send a tx which calls the function described. - -I can view the status of my transaction on the local network. - -> Note: both functions which are executed in the one tx will need to use the same snapshot of the network's state, so pause/ignore tree updates whilst the tx is being generated. - -### 3.2 - Recursive private calls - -As a developer, I can write a private function which calls itself. - -> Note: this requires changes to the private kernel circuit, to allow notes to be 'read' even before they've been finalised on L1. - ---- - -:rocket: First release candidate for the local developer testnet - ---- - -## 4: Public Functions - -### 4.1 - Public Constructor - -As a developer, I can declare `public` state variablesin the global `contract` scope of my Noir Contract. - -I can write a `public` function in Noir, which can read and write state from/to the public data tree. - -I can write a `constructor` function in Noir, which can _make a call_ to a `public` function _in the same_ `contract` scope, which can be used to initialise `public` state. - -I can deploy a contract (via `aztec.js`) which calls a constructor function (which in-turn calls a public function) to initialise _public_ state. - -> Note: the constructor arguments could be included in the abi.json, similar to a Solidity ABI. - -I can call and `unconstrained` function to verify that the state was set correctly for public state. - ---- - -### 4.2 - A single Public Function Call ⚙️ - -As a developer, I can write a `public` function in Noir. This function can do public `state_reads`, and push new `state_transitions` to the public data tree. - -I can send a tx request to the network, which calls a single public function, to be included in the next block. - -I can view the status of my transaction on the local network. - ---- - -:rocket: New release of the local developer testnet - ---- - -## 5: More Composability - -### 5.1 - IntRA-contract Private->Public Calls - -A `private` function can call a `public` function of the same contract, passing arguments, but NOT receiving return values. - ---- - -### 5.2 - IntER-contract Private->Public Calls - -A `private` function of the importing contract can call a `public` function of the imported contract, passing arguments, but NOT receiving return values. - ---- - -### 5.3 - IntER-contract Public->Public Calls - -A `public` function of the importing contract can call a `public` function of the imported contract, passing arguments, and receiving return values. - ---- - -### 5.4 - IntRA-contract Public->Private calls - -(Note: intRA private->private calls can just be inlined). - -As a developer, I can write Noir++ code to call a `private` function from a `public` function; within the same contract scope. - -I can write a `private` function which can 'read' a message from a `public` function. - -I can call a public function, which adds a message to some message box, for a particular private function to consume. - -I can call a private function (in a later rollup) which consumes that message. - ---- - -:rocket: New release of the local developer testnet - ---- - -## 6: Introducing fees - -**NOTE: these milestones might change, as we think more about fees, and the best things to tackle first.** - -### 6.1 - Estimating Gas - L1->L2 message - -As a developer, I can estimate the L2 gas costs associated with posting a message to the L1->L2 message box. - -> Note: This might need further discussion. The L1 component is forcing the Sequencer to add data to the message tree in the next rollup, so ought to cover that L2 cost somehow by providing a payment to the Sequencer (rather than the L1 validator). Tricky. - ---- - -### 6.2 - Estimating Gas - Private Kernel - -As a developer, I can estimate the L2 gas costs associated with a private kernel snark's submission to the local test blockchain. - ---- - -### 6.3 - Estimating Gas - Public Function - -As a developer, I can estimate the L2 gas costs associated with executing a public circuit. - ---- - -### 6.4 - Fees from L1 - -As a developer, I must now pay for the 'L2 component' of an L1->L2 tx. - -I can pay for the 'L2 component' of an L1->L2 tx using L1 ETH. - -I can pay for the 'L2 component' of an L1->L2 tx using any ERC20 token. - ---- - -### 6.5 - Fees from Public L2 - -As a developer, I can write a public L2 token contract. - -As a user, I can pay for L2 txs using some public L2 token. - ---- - -### 6.6 - Fees from Private L2 - -As a developer, I can write a private L2 token contract. - -As a user, I can pay for L2 txs using some private L2 token. - ---- - -:rocket: New release of the local developer testnet - ---- - -## 7: Introduce actual circuits, proofs and verifiers - -Up until now, milestones will have been using "simulated circuits", which contain the logic (checks and calculations) we'll need from our circuits, but without any of the computational overhead of actual circuits. -This decision was intentional, to make the Local Developer Testnet as fast as possible, so that users (devs) can play and iterate as quickly as possible. - -But ultimately, we need all these transactions to be actual proofs which can be verified. We have most of the code and expertise (from Aztec Connect), we just need to plug it in! - -### 7.1 Actual Kernel & Rollup circuits - -Write circuit versions of the Private and Public Kernel circuits, and the Base, Merge and Root Rollup circuits. - -Turn on proof validation within each of these circuits, and within the Rollup Contract on L1. - -The proving scheme might initially be UltraPlonk, which might be a problem in WASM. Benchmarking needed. - -### 7.2 Swap UltraPlonk for Honk - -Once ready, we can swap-in the Honk proving scheme, for much faster recursive proofs. - -### 7.3 Public VM Circuit - -The opcode-trace of a public function will ultimately need to be verified via a Public VM Circuit. This will be quite a complicated circuit to design and build. - -### 7.4 Public Function bytecode-validation circuit - -The opcodes of a public function need to be provably 'linked' with a commitment to those opcodes. - -## 8: Public testnet via a centralised Sequencer - -> These aren't currently written as developer stories, as the developer's experience shouldn't change much from interacting with the local network. Instead, they're mostly Sequencer stories here. - -### 8.1 - A centralised tx pool - -As a Sequencer, I should be able to see all incoming tx requests in a 'stubbed' tx pool (can just be an http endpoint, perhaps). - ---- - -### 8.2 - Rollups done by a Sequencer - -As a Sequencer, I can rollup a set of private kernel proofs into a single proof, and submit that to L1. - ---- - -### 8.3 - Simulating and submitting a public function - -As a sequencer, I can simulate a public function's opcodes. - -I can then prove execution of that function, run it through a kernel snark, and add it to the rollup. - ---- - -### 8.4 - Collecting L1->L2 message fees - -As a Sequencer, I can collect a fee for adding an L1->L2 message to the message tree. - ---- - -### 8.5 - Collecting L1 fees - -As a Sequencer, I can identify when an L2 tx is being paid-for via L1 (e.g. in the case of the L2 tx component of an L1->L2 tx). - -I can see the L1 fees being offered for such a tx. - -I can convert the L1 currency into ETH. - -I can simulate a single-function L2 tx. - -I can process the L2 tx, and receive L1 tokens for doing so. - ---- - -### 8.6 - Collecting Public L2 fees - -As a Sequencer, I can identify when an L2 tx is being paid-for via a public L2 tx. - -I can see the L2 fees being offered for such a tx. - -I can interpret those fees, based on some Aztec L2 Public fungible token standard. - -I can simulate the fee-paying tx, to validate that I'll be paid. - -I can simulate the accompanying tx. - -I can process the L2 tx, and receive public L2 tokens from the fee-paying tx. - ---- - -### 8.8 - Collecting Private L2 fees - -As a Sequencer, I can identify when an L2 tx is being paid-for via a private L2 tx. - -I can see the L2 fees being offered for such a tx. - -I can interpret those fees, based on some Aztec L2 Private fungible token standard. - -I can simulate the fee-paying tx, to validate that I'll be paid. - -I can simulate the accompanying tx. - -I can process the L2 tx, and receive public L2 tokens from the fee-paying tx. - ---- - -### 8.8 - Prover client - -As a Sequencer, I can delegate proof generation to my own Prover Client (descendant of Halloumi). - ---- - -### 8.9 - Actual proof generation! - -We actually construct circuits and generate zk-snarks at all stages. - ---- - -:rocket: Launch centralised sequencer testnet - ---- - -## 9: 1st Sequencer testnet - -### 9.0 - More Sequencers - -> Note: depending on Honk progress, this might be UltraPlonk initially. - -As a Sequencer (amongst many Sequencers), I can query whether I'm the current Sequencer. - -> Note: this can be coordinated via some central endpoint at this stage. - -I can access a centralised pool of txs, in order to generate rollups when it's my turn. - ---- - -### 9.1 - P2P tx pool - -As a user, I can connect to a p2p tx pool. - -As a user, I can submit a tx to the pool. - -As a Sequencer, I can read txs from the tx pool. - -As a network participant, my local copy of the tx pool can be maintained: adding new txs, and removing already-processed txs. - ---- - -:rocket: Launch 1st Sequencer testnet - ---- - -## 10: 2nd Sequencer testnet - -### 10.0 - Sequencer Selection Protocol - -As a Sequencer, I can determine whether I'm the Sequencer in a decentralised way. - -I'll know some time in advance that I'll be the sequencer for a particular rollup, so I can prepare in advance. - -I can submit a rollup only when I'm the chosen Sequencer. - -If I fail to submit a rollup I might (TBD) be penalised. - -> Other milestones are hazy, until we decide on the sequencer selection protocol. - ---- - -:rocket: Launch 2nd Sequencer testnet - ---- - -## 11: Prover testnet - -We introduce a new type of network participant: a Prover: someone other than the Sequencer who runs a Prover Client. - -### 11.0 - Prover Selection Protocol - -> TBD: selection criteria. - -### 11.1 - Proof delegation - -As a Sequencer I can delegate proofs to Provers. - -As a Prover I can be paid for generating proofs for the current Sequencer. - ---- - -:rocket: Launch Prover testnet - ---- - -## 12: Refactoring / Optimisations - -- Nullifier Epochs -- Commitment (UTXO) Epochs -- More Efficient Kernel Recursion Topology (in a binary tree) -- Flexible Rollup Topology / Streaming new txs into the rollup -- Decrypting Notes - - OMR? PIR? FMD? -- Plug Honk into the circuits -- Account Abstraction -- More efficient, newer hashes for trees - -## Participate - -Keep up with the latest discussion and join the conversation in the [Aztec forum](https://discourse.aztec.network). - -import Disclaimer from "../../misc/common/\_disclaimer.mdx"; - diff --git a/docs/docs/dev_docs/contracts/abi.md b/docs/docs/dev_docs/contracts/abi.md index d5fbe20bc04..fe493910cec 100644 --- a/docs/docs/dev_docs/contracts/abi.md +++ b/docs/docs/dev_docs/contracts/abi.md @@ -1,3 +1,5 @@ +# Aztec Function ABIs + Discuss: - Public Inputs ABIs for functions. - Args & args hashes @@ -15,4 +17,6 @@ Discuss: ### Num key pair validations -### No gas or fees yet \ No newline at end of file +### No gas or fees yet + +(See also [Limitations](../limitations/main.md)) \ No newline at end of file diff --git a/docs/docs/dev_docs/contracts/contract.md b/docs/docs/dev_docs/contracts/contract.md index 60062cdbcf3..9e94abb09ff 100644 --- a/docs/docs/dev_docs/contracts/contract.md +++ b/docs/docs/dev_docs/contracts/contract.md @@ -1,4 +1,8 @@ -# `contract` +--- +title: Contract +--- + +# Contract A contract is a collection of persistent [state variables](#state-variables), and [functions](#functions) which may modify these persistent states. Functions and states within a contract's scope are said to belong to that contract. A contract can only access and modify its own state. If a contract wishes to access or modify another contract's state, it must make a [call](#calling-functions) to an external function of that other contract. For anything to happen on the Aztec network, an external function of a contract needs to be called. diff --git a/docs/docs/dev_docs/contracts/deploying.md b/docs/docs/dev_docs/contracts/deploying.md index 569884cc8cb..a80e3b8c31f 100644 --- a/docs/docs/dev_docs/contracts/deploying.md +++ b/docs/docs/dev_docs/contracts/deploying.md @@ -169,4 +169,4 @@ const contract = await PrivateTokenContract.deploy(wallet, initialBalance, owner the resulting address will be deterministic. -> **NOTE**: You can try running the deployment with the same salt the second time in which case the transaction will fail because the address has been already deployed to. \ No newline at end of file +> **NOTE**: You can try running the deployment with the same salt the second time in which case the transaction will fail because the address has been already deployed to. diff --git a/docs/docs/dev_docs/contracts/events.md b/docs/docs/dev_docs/contracts/events.md index e115cd4a277..1f12b91c8e5 100644 --- a/docs/docs/dev_docs/contracts/events.md +++ b/docs/docs/dev_docs/contracts/events.md @@ -85,7 +85,7 @@ aztec-cli get-logs --from 5 --limit 1 -### Costs +## Costs All event data is pushed to Ethereum as calldata by the sequencer and for this reason the cost of emitting an event is non-trivial. diff --git a/docs/docs/dev_docs/contracts/globals.md b/docs/docs/dev_docs/contracts/globals.md index f90edd0d8de..91b8c72fb6a 100644 --- a/docs/docs/dev_docs/contracts/globals.md +++ b/docs/docs/dev_docs/contracts/globals.md @@ -1,3 +1,5 @@ +# Globals + - timestamp - block number - chain id diff --git a/docs/docs/dev_docs/contracts/main.md b/docs/docs/dev_docs/contracts/main.md index acbfa8f5fd5..04238411395 100644 --- a/docs/docs/dev_docs/contracts/main.md +++ b/docs/docs/dev_docs/contracts/main.md @@ -1,52 +1,39 @@ -# Contracts +# Aztec.nr -## What is a Noir Contract? +## What is Aztec.nr? -**Noir** is a domain specific language for creating and verifying proofs. It's design choices are influenced heavily by Rust. +**Aztec.nr** is a library for writing Aztec smart contracts. -We've extended the Noir language to understand the notion of an **'Aztec smart contract'**. +## Nomenclature -- A **smart contract** is just a collection of persistent state variables, and a collection of functions which may edit those state variables. -- An **Aztec smart contract** is a smart contract with **private** state variables and **private** functions. -- A **Noir Contract** is just an Aztec smart contract, written in Noir syntax. +[**Noir**](https://noir-lang.org/) is a domain specific language for creating and verifying proofs. It's design choices are influenced heavily by Rust. +A **smart contract** is just a collection of persistent state variables, and a collection of functions which may edit those state variables. -:::info -Throughout these docs, we'll refer to "Vanilla Noir" as being the version of Noir without the Noir Contract syntax. -::: +An **Aztec smart contract** is a smart contract with **private** state variables and **private** functions. -# Getting started +**Aztec.nr** is a library for writing Aztec smart contracts, written in Noir. -Please consider using the [TUTORIAL-TEMPLATE](../../TUTORIAL_TEMPLATE.md) for standalone guides / tutorials. +# Getting started -## Installing Noir +## Install Noir To write a Noir Contract, you need to write Noir, and to write Noir, you need to [install Nargo](https://noir-lang.org/getting_started/nargo_installation). -## Installing Noir tooling +## Install Noir tooling There are a number of tools to make writing Noir Contracts more pleasant. See [here](https://github.com/noir-lang/awesome-noir#get-coding). ## Quick start -Download an Aztec Box. (Josh / Ze to build :) ). - -@Josh what's the best way to enable a 'one-command' creation of a noir project? (akin to https://noir-lang.org/getting_started/hello_world). I wonder if @aztec/cli should have this functionality? - -@Josh I wonder if @aztec/cli would be a good place to hold 'Aztec Boxes'? -- `aztec-cli unbox` -- `aztec-cli unbox private_token`. - -Or, if you don't want to do that, here's more detail on doing it all yourself: - :::danger TODO -TODO +Starter kit ::: ## Example Noir Contract -In keeping with the origins of blockchain, here's an example of a simple token contract. But here, the balances are private. +In keeping with the origins of blockchain, here's an example of a simple private token contract. Everyone's balances are private. #include_code easy_private_token_storage /yarn-project/noir-contracts/src/contracts/easy_private_token_contract/src/storage.nr rust @@ -55,6 +42,3 @@ In keeping with the origins of blockchain, here's an example of a simple token c :::info Disclaimer Please note that any example contract set out herein is provided solely for informational purposes only and does not constitute any inducement to use or deploy. Any implementation of any such contract with an interface or any other infrastructure should be used in accordance with applicable laws and regulations. ::: - -## Next steps -You can read more about writing contracts [here](./syntax.md), and then move to compiling it which is detailed [here](./compiling.md). \ No newline at end of file diff --git a/docs/docs/dev_docs/contracts/syntax.md b/docs/docs/dev_docs/contracts/syntax.md index 288a46cb380..45557873862 100644 --- a/docs/docs/dev_docs/contracts/syntax.md +++ b/docs/docs/dev_docs/contracts/syntax.md @@ -1,23 +1,18 @@ -# Noir Contract Syntax +# Aztec.nr Syntax -[Vanilla Noir](https://noir-lang.org/) is a language which is agnostic to proof systems and use cases. Rather than baking Aztec-specific keywords and smart contract types directly into Noir (which would break this agnosticism), we have developed a library -- written in Vanilla Noir -- whose types and methods provide rich smart contract semantics. +[Noir](https://noir-lang.org/) is a language which is agnostic to proof systems and use cases. Rather than baking Aztec-specific keywords and smart contract types directly into Noir (which would break this agnosticism), we have developed a library -- written in Noir -- whose types and methods provide rich smart contract semantics. -## Aztec stdlib +On top of [Noir's stdlib](https://noir-lang.org/standard_library/array_methods), we provide [Aztec.nr](https://github.com/AztecProtocol/aztec-packages/tree/master/yarn-project/noir-libs) for writing contracts on Aztec. -On top of ['Vanialla Noir's' stdlib](https://noir-lang.org/standard_library/array_methods), we provide an [Aztec stdlib](https://github.com/AztecProtocol/aztec-packages/tree/master/yarn-project/noir-libs) for writing Noir Contracts. The Aztec stdlib contains abstractions which remove the need to understand the low-level Aztec protocol. Notably, it provides: +Aztec.nr contains abstractions which remove the need to understand the low-level Aztec protocol. Notably, it provides: - Public and private [state variable types](./types.md) -- Ready-made notes. +- Some pre-designed notes. - Functions for [emitting](./events.md) encrypted and unencrypted logs - [Oracle functions](./functions.md#oracle-calls) for accessing: - private state - secrets - Functions for communicating with Ethereum L1 - -To import the Aztec stdlib into your Noir Contract project, simply include it as a dependency: - -:::danger TODO -https://github.com/AztecProtocol/aztec-packages/issues/1335 -::: +To import Aztec.nr into your Aztec contract project, simply include it as a dependency. #include_code importing-aztec /yarn-project/noir-contracts/src/contracts/private_token_contract/Nargo.toml toml \ No newline at end of file diff --git a/docs/docs/dev_docs/contracts/workflow.md b/docs/docs/dev_docs/contracts/workflow.md new file mode 100644 index 00000000000..f208a34e33b --- /dev/null +++ b/docs/docs/dev_docs/contracts/workflow.md @@ -0,0 +1,21 @@ +# Noir contract workflow + + ## Write + + [Write a contract](./syntax.md) + + ## Compile + + [Compile a contract](./compiling.md). + + ## Test + + [Test individual noir functions](https://noir-lang.org/nargo/testing). + + ## Deploy + + [Deploy a contract](./deploying.md). + + ## Test + + [Test a deployed contract](../testing/main.md) \ No newline at end of file diff --git a/docs/docs/dev_docs/limitations/main.md b/docs/docs/dev_docs/limitations/main.md new file mode 100644 index 00000000000..a8e64411d00 --- /dev/null +++ b/docs/docs/dev_docs/limitations/main.md @@ -0,0 +1,223 @@ +# Limitations + +The Aztec Sandbox and the Aztec Smart Contract Library are **prototypes**, and should be treated as such. They've been released early, to gather feedback on the capabilities of the protocol and user experiences. + + +## What to expect? + +- Regular Breaking Changes; +- Missing features; +- Bugs; +- An 'unpolished' UX; +- Missing information. + + +## Why isn't it working perfectly yet? + +These things take time :) + + +## Why participate? + +Front-run the future! + +Help shape and define: +- Previously-impossible smart contracts and applications +- Network tooling; +- Network standards; +- Smart contract syntax; +- Educational content; +- Core protocol improvements; + + + +## Limitations + +There are plans to resolve all of the below. See also the [engineering roadmap](../../about_aztec/roadmap/engineering_roadmap.md). + + +### It is not audited. + +None of the Sandbox code is audited. It's being iterated-on every day. It will not be audited for quite some time. + + +### No Proofs! + +That's right, the Sandbox doesn't actually generate or verify any zk-SNARKs yet! + +The main goal of the Sandbox is to enable developers to experiment with building apps, and hopefully to provide feedback. We want the developer experience to be as fast as possible, much like how Ethereum developers use Ganache or Anvil to get super-fast block times, instead of the slow-but-realistic 12-second block times that they'll encounter in production. A fast Sandbox enables fast testing, which enables developers to iterate quickly. + +That's not to say a super-fast proving system isn't being worked on [as we speak](../../about_aztec/roadmap/cryptography_roadmap.md). + +#### What are the consequences? + +By the time mainnet comes around, zk-SNARKs will be needed in order to validate the correctness of every function that's executed on Aztec. In other words, in order for the execution of a function to be registered as part of the Aztec blockchain's history, a proof of correct execution will need to be furnished. Each proof will be an attestation that the rules of a particular function were followed correctly. + +But proofs are really only needed as a protection against malicious behaviour. The Sandbox is an emulated ecosystem; entirely contained within your laptop, and it follows the network's rules out of the box. So as long as its inner workings aren't tampered-with, it will act 'honestly'. Since you'll be the only person interacting with the Sandbox on your own laptop, and with a healthy assumption that you should be honest with yourself, you won't need proofs when testing. + + +### No Circuits! + +This is kind-of a repetition of ['No Proofs!'](#no-proofs) above, but for the sake of clarity, there aren't yet any arithmetic circuits in the Sandbox. We might refer to certain components of the core protocol as being 'circuits', and we might refer to user-defined smart contract functions as being compiled to 'circuits', but the Sandbox doesn't actually contain any circuits yet. Instead, there is code which emulates the logic of a circuit. This is intentional, to make execution of the Sandbox as fast as possible. + +Obviously, as development continues, the so-called 'circuits' will actually become proper circuits, and actual proofs will be generated. + +#### What are the consequences? + +The Sandbox will execute more quickly. The logic of all 'circuits' is still in place*. Smart contract logic will be executed, and core protocol logic will be executed*. So invalid transactions will be caught* and rejected. + +*Note: some core protocol circuit assertions and constraints still need to be written (see [GitHub](https://github.com/AztecProtocol/aztec-packages/issues)). This would be bad in an adversarial environment, but the Sandbox is not that. Naturally, proper circuits will need to be written - see the [engineering roadmap](../../about_aztec/roadmap/engineering_roadmap.md). + + +### No Fees! + +That's right, there are no L2 network fees yet! + +The Sandbox can currently be thought of as a bare-minimum execution layer. We'll be speccing and implementing gas metering and fees soon! + +> Note: there is still a notion of an L1 fee in the Sandbox, because it uses Anvil to emulate the Ethereum blockchain. + +#### What are the consequences? + +Apps won't yet be able to allow for any L2 fee logic. Once fees are introduced, this will cause breaking changes to in-progress apps, which will need to be updated to accommodate the notion of paying network fees for transactions. Clear documentation will be provided. + + +### Basic Keys and Addresses! + +The way in which keypairs and addresses are currently derived and implemented (inside the Sandbox) is greatly over-simplified, relative to future plans. + +They're so over-simplified that they're known to be insecure. Other features have been prioritised so-far in Sandbox development. Please refer to the [future roadmap](../../about_aztec/roadmap/engineering_roadmap.md) + +#### What are the consequences? + +This will impact the kinds of apps that you can build with the Sandbox, as it is today: + +- The management of keys when designing account contracts and wallets will be affected. +- The keys used when generating nullifiers will be affected. (Although the machinery relating to nullifiers is mostly abstracted away from developers who use [Aztec.nr](../contracts/main.md)). + - In particular the current, over-simplified key derivation scheme is known to be **insecure**: + - Currently, the same nullifier secret key is used by _every_ smart contract on the network. This would enable malicious apps to trivially emit a user's nullifier secret key to the world! + - In future, there are detailed plans to 'silo' a nullifier key per contract address (and per user), to fix this obvious vulnerability. +- The keys used when encrypting and decrypting logs will be affected. + - In particular the current, over-simplified key derivation scheme is known to be **insecure**: + - Currently, a user's nullifier secret key is the same as their encryption secret key. And as stated above, this would enable malicious apps to trivially emit a user's secret key to the world! + - In future there are also plans to have incoming and outgoing viewing keys, inspired by [ZCash Sapling](https://electriccoin.co/blog/explaining-viewing-keys/). + - If developers wish to design apps which incorporate certain auditability patterns, the current over-simplification of keys might not be sufficient. + +Please open new discussions on [discourse](http://discourse.aztec.network) or open issues on [github](http://github.com/AztecProtocol/aztec-packages), if you have requirements that aren't-yet being met by the Sandbox's current key derivation scheme. + + +### It's not-yet decentralised + +It's an emulated blockchain entirely contained within your own laptop! It's centralised by design! +As for deploying this all to mainnet, a decentralised sequencer selection and prover selection protocols are still [being discussed](https://discourse.aztec.network/t/request-for-proposals-decentralized-sequencer-selection/350). There are plans for decentralised testnets in 2024. + + +### You can't read mutable public state from a private function + +Private smart contract functions won't be able to read mutable public state yet. We have some [ideas](https://discourse.aztec.network/t/accessing-historic-public-state-from-private-functions/241/7?u=mike) for how to solve this, and will look to implement something very soon. + +#### What are the consequences? + +Reading public state from a private contract will be a common pattern. For example, it's needed if you want to maintain a public whitelist/blacklist, but prove you are/aren't on that blacklist privately. This will be a high priority, coming soon. + + +### No delegatecalls + +A contract can't perform a delegatecall yet (if ever). Delegatecalls are quite a controversial feature of the EVM. + +### No privacy-preserving queries to nodes + +Ethereum has a notion of a 'full node' which keeps-up with the blockchain and stores the full chain state. Many users don't wish to run full nodes, so rely on 3rd-party 'full-node-as-a-service' infrastructure providers, who service blockchain queries from their users. + +This pattern is likely to develop in Aztec as well, except there's a problem: privacy. If a privacy-seeking user makes a query to a 3rd-party 'full node', that user might leak data about who they are, or about their historic network activity, or about their future intentions. One solution to this problem is "always run a full node", but pragmatically, not everyone will. To protect less-advanced users' privacy, [research is underway](../../about_aztec/roadmap/engineering_roadmap.md) to explore how a privacy-seeking user may request and receive data from a 3rd-party node without revealing what that data is, nor who is making the request. + + +### No private data authentication + +Private data should not be returned to an app, unless the user authorises such access to the app. An authorisation layer is not-yet in place. + +#### What are the consequences? + +Any app can request and receive any private user data relating to any other private app. Obviously this sounds bad. But the Sandbox is a sandbox, and no meaningful value or credentials should be stored there; only test values and test credentials. + +An auth layer will be added in due course. + + +### No bytecode validation + +Bytecode should not be executed, unless the Sandbox has validated that the user's intentions (the function signature and contract address) match the bytecode. + +#### What are the consequences? + +Without such 'bytecode validation', if the incorrect bytecode is executed, and that bytecode is malicious, it could read private data from some other contract and emit that private data to the world. Obviously this would be bad in production. But the Sandbox is a sandbox, and no meaningful value or credentials should be stored there; only test values and test credentials. + +There are plans to add bytecode validation soon. + + +### Insecure hashes + +Currently, Pedersen hashes are being used pretty-much everywhere. To any cryptographers reading this, don't panic. A thorough review of which hashes to use in which part of the protocol will be conducted soon. + +Additionally, domain separation of hashes needs some review. + +#### What are the consequences? + +Collisions and other hash-related attacks might be possible in the Sandbox. Obviously that would be bad in production. But it's unlikely to cause problems at this early stage of testing. + + +### `msg_sender` is leaked when making a private -> public call + +There are [ongoing discussions](https://discourse.aztec.network/t/who-is-msg-sender-when-making-private-public-function-calls/242) around how to address this. + +#### What are the consequences? + +When a private function makes a call to a public function, the `msg_sender` of the calling function will be given to the public world. Most critically, this includes if the `msg_sender` is an account contract. +This will be patched in the near future, but unfortunately, app developers might need to 'overlook' this privacy leakage until then, with the assumption that it will be fixed. But note, one possible 'patch' might be to set `msg_sender` to `0` for all private -> public calls. This might cause breaking changes to your public functions, if they rely on reading `msg_sender`. There are patterns to work around this, but they wouldn't be pretty, and we won't go into details until a solution is chosen. Sorry about this, and thanks for your patience whilst we work this out :) + + +### New Privacy Standards are required + +There are many [patterns](../privacy/main.md) which can leak privacy, even on Aztec. Standards haven't been developed yet, to encourage best practices when designing private smart contracts. + +#### What are the consequences? + +For example, until community standards are developed to reduce the uniqueness of ['Tx Fingerprints'](../privacy/main.md#function-fingerprints-and-tx-fingerprints) app developers might accidentally forfeit some function privacy. + + +## Circuit limitations + +### Upper limits on function outputs and tx outputs + +Due to the rigidity of zk-SNARK circuits, there are upper bounds on the amount of computation a circuit can perform, and on the amount of data that can be passed into and out of a function. See [Aztec function ABIs](../contracts/abi.md) for more information. + +> Blockchain developers are no stranger to restrictive computational environments. Ethereum has gas limits, local variable stack limits, call stack limits, contract deployment size limits, log size limits, etc. + +Here are the current constants: + +#include_code constants circuits/cpp/src/aztec3/constants.hpp cpp + +#### What are the consequences? + +When you write an [Aztec.nr](../contracts/main.md) [function](../contracts/functions.md), there will be upper bounds on the following: +- The number of public state reads and writes; +- The number of note reads and nullifications; +- The number of new notes that may be created; +- The number of encrypted logs that may be emitted; +- The number of unencrypted logs that may be emitted; +- The number of L1->L2 messages that may be consumed; +- The number of L2->L1 messages that may be submitted to L1; +- The number of private function calls; +- The number of public function calls that may be enqueued; + +Not only are there limits on a _per function_ basis, there are also limits on a _per transaction_ basis. + +**In particular, these _per-transaction_ limits will limit transaction call stack depths** in the Sandbox. That means if a function call results in a cascade of nested function calls, and each of those function calls outputs lots of state reads and writes, or logs (etc.), then all of that accumulated output data might exceed the per-transaction limits that we currently have. This would cause such transactions to fail. + +There are [plans](../../about_aztec/roadmap/engineering_roadmap.md#proper-circuits) to relax all of this rigidity, by providing many 'sizes' of [kernel circuit](../../concepts/advanced/circuits/kernels/main.md), and introducing a 'bus' to ferry varying lengths of data between kernel iterations. But that'll all take some time. + +> **In the mean time**, if you encounter a per-transaction limit when testing, and you're feeling adventurous, you could 'hack' the Sandbox to increase the limits. See here (TODO: link) for a guide. **However**, the limits cannot be increased indefinitely. So although we do anticipate that we'll be able to increase them a little bit, don't go mad and provide yourself with 1 million state transitions per transaction. That would be as unrealistic as artificially increasing Ethereum gas limits to 1 trillion. + + +## There's more + +See the [GitHub issues](https://github.com/AztecProtocol/aztec-packages/issues) for all known bugs fixes and features currently being worked on. \ No newline at end of file diff --git a/docs/docs/dev_docs/privacy/main.md b/docs/docs/dev_docs/privacy/main.md new file mode 100644 index 00000000000..38debb833e8 --- /dev/null +++ b/docs/docs/dev_docs/privacy/main.md @@ -0,0 +1,147 @@ +# Privacy Considerations + +Privacy is important. + +Keeping information private is difficult. + +Once information is leaked, it cannot be unleaked. + +--- + +## What can Aztec keep private? + +Aztec provides a set of tools to enable developers to build private smart contracts. The following can be kept private: + +**Private persistent state** + +Store state variables in an encrypted form, so that no one can see what those variables are, except those with the decryption key. + +**Private events and messages** + +Emit encrypted events, or encrypted messages from a private smart contract function. Only those with the decryption key will learn the message. + +**Private function execution** + +Execute a private function without the world knowing which function you've executed. + + + +:::danger +Privacy is not guaranteed without care. +Although Aztec provides the tools for private smart contracts, information can still be leaked unless the dapp developer is careful. +This page outlines some best practices to aid dapp developers. +::: + + +--- + +## Leaky practices + +There are many caveats to the above. Since Aztec also enables interaction with the _public_ world (public L2 functions and L1 functions), private information can be accidentally leaked if developers aren't careful. + + +### Crossing the private -> public boundary + +Any time a private function makes a call to a public function, information is leaked. Now, that might be perfectly fine in some use cases (it's up to the smart contract developer). Indeed, most interesting apps will require some public state. But let's have a look at some leaky patterns: + +- Calling a public function from a private function. The public function execution will be publicly visible. +- Calling a public function from a private function, without anonymising the `msg_sender` of that call. (Otherwise the `msg_sender` will be publicly visible). +- Passing arguments to a public function from a private function. All of those arguments will be publicly visible. +- Calling an internal public function from a private function. The fact that the call originated from a private function of that same contract will be trivially known. +- Emitting unencrypted events from a private function. The unencrypted event name and arguments will be publicly visible. +- Sending L2->L1 messages from a private function. The entire message, and the resulting L1 function execution will all be publicly visible. + + +### Crossing the public -> private boundary + +If a public function sends a message to be consumed by a private function, the act of consuming that message might be leaked if not following recommended patterns. See [here](../contracts/portals/inbox.md) for more details. + + +### Timing of transactions + +Information about the nature of a transaction can be leaked based on the timing of that transaction. + +If a transaction is executed at 8am GMT, it's much less likely to have been made by someone in the USA. That's information, right there. + +If there's a spike in transactions on the last day of every month, those might be salaries. + +Suppose that every time Alice sends Bob a private token, 1 minute later a transaction is always submitted to the tx pool with the same kind of 'fingerprint'. Alice might deduce that these transactions are automated reactions by Bob. (Here, 'fingerprint' is an intentionally vague term. It could be a public function call, or a private tx proof with a particular number of nonzero public inputs, or some other discernible pattern that Alice sees). + +Tl;dr: app developers should think about the _timing_ of user transactions, and how this might leak information. + + +### Function Fingerprints and Tx Fingerprints + +A 'Function Fingerprint' is any data which is exposed by a function to the outside world. A 'Tx Fingerprint' is any data which is exposed by a tx to the outside world. We're interested in minimising leakages of information from private txs. The leakiness of a Tx Fingerprint depends on the leakiness of its consituent functions' Function Fingerprints _and_ on the appearance of the tx's Tx Fingerprint as a whole. For a private function (and by extension, for a private tx), the following information _could_ be leaked (depending on the function, of course): + +- All calls to public functions. + - The contract address of the private function (if it calls an internal public function). + - This could be the address of the transactor themselves, if the calling contract is an account contract. + - All arguments which are passed to public functions. +- All calls to L1 functions (in the form of L2 -> L1 messages). + - The contents of L2 -> L1 messages. +- All unencrypted logs (topics and arguments). +- The roots of all trees which have been read from. +- The _number_ of ['side effects'](https://en.wikipedia.org/wiki/Side_effect_(computer_science)): + - \# new commitments + - \# new nullifiers + - \# bytes of encrypted logs + - \# public function calls + - \# L2->L1 messages + - \# nonzero roots[^1] + + + +> Note: many of these were mentioned in the ["Crossing the private -> public boundary"](#crossing-the-private---public-boundary) section. + +> Note: the calldata submitted to L1 is [encoded](https://github.com/AztecProtocol/aztec-packages/blob/master/l1-contracts/src/core/libraries/Decoder.sol) in such a way that all categories of data are packed together, when submitted. E.g. all commitments from all txs in a block are arranged as contiguous bytes of calldata. But that _doesn't_ mean the data from a particular tx is garbled in with all other txs' calldata: the distinct Tx Fingerprint of each tx can is publicly visible when a tx is submitted to the L2 tx pool. + + +#### Standardising Fingerprints + +If each private function were to have a unique Fingerprint, then all private functions would be distinguishable from each-other, and all of the efforts of the Aztec protocol to enable 'private function execution' would have been pointless. Standards need to be developed, to encourage smart contract developers to adhere to a restricted set of Tx Fingerprints. For example, a standard might propose that the number of new commitments, nullifiers, logs, etc. must always be equal, and must always equal a power of two. Such a standard would effectively group private functions/txs into 'privacy sets', where all functions/txs in a particular 'privacy set' would look indistinguishable from each-other, when executed. + + +### Data queries + +It's not just the broadcasting of transactions to the network that can leak data. + +Ethereum has a notion of a 'full node' which keeps-up with the blockchain and stores the full chain state. Many users don't wish to run full nodes, so rely on 3rd-party 'full-node-as-a-service' infrastructure providers, who service blockchain queries from their users. + +This pattern is likely to develop in Aztec as well, except there's a problem: privacy. If a privacy-seeking user makes a query to a 3rd-party 'full node', that user might leak data about who they are; about their historic network activity; or about their future intentions. One solution to this problem is "always run a full node", but pragmatically, not everyone will. To protect less-advanced users' privacy, research is underway to explore how a privacy-seeking user may request and receive data from a 3rd-party node without revealing what that data is, nor who is making the request. + +App developers should be aware of this avenue for private data leakage. **Whenever an app requests information from a node, the entity running that node is unlikely be your user!** + +#### What kind of queries can be leaky? + +##### Querying for up-to-date note sibling paths + +To read a private state is to read a note from the private data tree. To read a note is to prove existence of that note in the private data tree. And to prove existence is to re-compute the root of the private data tree using the leaf value, the leaf index, and the sibling path of that leaf. This computed root is then exposed to the world, as a way of saying "This note exists", or more precisely "This note has existed at least since this historic snapshot time". + +If an old historic snapshot is used, then that old historic root will be exposed, and this leaks some information about the nature of your transaction: it leaks that your note was created before the snapshot date. It shrinks the 'anonymity set' of the transaction to a smaller window of time than the entire history of the network. + +So for maximal privacy, it's in a user's best interest to read from the very-latest snapshot of the data tree. + +Naturally, the private data tree is continuously changing as new transactions take place and their new notes are appended. Most notably, the sibling path for every leaf in the tree changes every time a new leaf is appended. + +If a user runs their own node, there's no problem: they can query the latest sibling path for their note(s) from their own machine without leaking any information to the outside world. + +But if a user is not running their own node, they would need to query the very-latest sibling path of their note(s) from some 3rd-party node. In order to query the sibling path of a leaf, the leaf's index needs to be provided as an argument. Revealing the leaf's index to a 3rd-party trivially reveals exactly the note(s) you're about to read. And since those notes were created in some prior transaction, the 3rd-party will be able to link you with that prior transaction. Suppose then that the 3rd-party also serviced the creator of said prior transaction: the 3rd-party will slowly be able to link more and more transactions, and gain more and more insight into a network which is meant to be private! + +We're [researching](../../about_aztec/roadmap/engineering_roadmap.md) cryptographic ways to enable users to retrieve sibling paths from 3rd-parties without revealing leaf indices. + +> \* Note: due to the non-uniformity of Aztec transactions, the 'anonymity set' of a transaction might not be the entire set of transactions that came before. See here (LINK). + +##### Any query + +Any query to a node leaks information to that node. + +We're [researching](../../about_aztec/roadmap/engineering_roadmap.md) cryptographic ways to enable users to query any data privately. + + + + +--- +Footnotes + +[^1]: All txs should set the kernel circuit public inputs for all roots to _valid_, _up-to-date_ nonzero values, so as to mask which trees have _actually_ been read from. The Sandbox will eventually automate this (see this [issue](https://github.com/AztecProtocol/aztec-packages/issues/1676)). \ No newline at end of file diff --git a/docs/docs/embedding_github_code.md b/docs/docs/embedding_github_code.md deleted file mode 100644 index ee8e1e6524b..00000000000 --- a/docs/docs/embedding_github_code.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: Embedding Github Code ---- - -# Copied directly from the local codebase, when building the docs: - -Here's an example of some code: - - - - - - - - -# Fetched from github, when loading the page: - -Here's an example of embedding code from a file of a branch of a github repo: - -import GithubCode from '../src/components/GithubCode'; - - - - - - - - - - - diff --git a/docs/docs/intro.md b/docs/docs/intro.md index 5507b610eaa..111bf2af038 100644 --- a/docs/docs/intro.md +++ b/docs/docs/intro.md @@ -11,27 +11,21 @@ On Ethereum today, everything is publicly visible, by everyone. In the real world, people enjoy privacy. Aztec brings privacy to Ethereum. - - - - --- # Build with confidence. -Design, build, and deploy confidential smart contracts. +Design, build, and deploy private smart contracts. -- Confidential functions -- Confidential arguments -- Confidential persistent state -- Confidential bytecode -- Confidential deployments -- Confidential execution -- Confidential transactions -- Confidential contract composability +- Private functions +- Private arguments +- Private persistent state +- Private bytecode +- Private deployments +- Private execution +- Private transactions +- Private contract composability - Encrypted state transitions - Encrypted logs @@ -57,8 +51,6 @@ Plus: Aztec encrypts Ethereum. -Aztec is the confidentiality layer of Ethereum. - Aztec is the privacy layer of Ethereum. Aztec is a private smart contract platform. diff --git a/docs/docs/misc/common/_disclaimer.mdx b/docs/docs/misc/common/_disclaimer.mdx index f854966ee17..2bd4a3a0cfc 100644 --- a/docs/docs/misc/common/_disclaimer.mdx +++ b/docs/docs/misc/common/_disclaimer.mdx @@ -3,6 +3,8 @@ :::caution Disclaimer We are building Aztec as transparently as we can. The documents published here are living documents. The protocol, sandbox, language, and tools are all subject to change over time. +Please see [here](../../dev_docs/limitations/main.md) for details of known Aztec protocol and Aztec Sandbox limitations. + If you would like to help us build Aztec: - Contribute code on [GitHub](https://github.com/AztecProtocol); or - Join in [forum](https://discourse.aztec.network/) discussions. diff --git a/docs/sidebars.js b/docs/sidebars.js index 23f556b9ebc..046e13f50e1 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -43,7 +43,7 @@ const sidebars = { }, items: [ "about_aztec/roadmap/features_initial_ldt", - "about_aztec/roadmap/milestones", + "about_aztec/roadmap/engineering_roadmap", "about_aztec/roadmap/cryptography_roadmap", ], }, @@ -206,6 +206,7 @@ const sidebars = { id: "dev_docs/contracts/main", }, items: [ + "dev_docs/contracts/workflow", "dev_docs/contracts/syntax", "dev_docs/contracts/contract", "dev_docs/contracts/layout", @@ -220,6 +221,7 @@ const sidebars = { "dev_docs/contracts/constrain", "dev_docs/contracts/compiling", "dev_docs/contracts/deploying", + "dev_docs/contracts/abi", { label: "Portals", type: "category", @@ -319,6 +321,9 @@ const sidebars = { ], }, + "dev_docs/limitations/main", + "dev_docs/privacy/main", + { type: "html", value: '', @@ -338,8 +343,6 @@ const sidebars = { }, "misc/aztec_connect_sunset", - - "embedding_github_code", ], }; diff --git a/docs/src/components/GithubCode/index.js b/docs/src/components/GithubCode/index.js index dc9a26d76eb..f7c41e9797c 100644 --- a/docs/src/components/GithubCode/index.js +++ b/docs/src/components/GithubCode/index.js @@ -4,6 +4,17 @@ import Highlight, { defaultProps } from "prism-react-renderer"; import github from "prism-react-renderer/themes/github"; //import vsDark from 'prism-react-renderer/themes/vsDark'; +/** + * NOTE: See the docs/README.md for a better (more robust) way to embed code snippets from the codebase into your docs. + * + * + * EXAMPLE USAGE: + * Inside a markdown file: + * + * import GithubCode from '../src/components/GithubCode'; + * + */ + const GithubCode = ({ owner, repo, diff --git a/docs/yarn.lock b/docs/yarn.lock index dcf071c443b..5e2702cf9b8 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -2896,9 +2896,9 @@ caniuse-api@^3.0.0: lodash.uniq "^4.5.0" caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001426, caniuse-lite@^1.0.30001449: - version "1.0.30001462" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001462.tgz#b2e801e37536d453731286857c8520d3dcee15fe" - integrity sha512-PDd20WuOBPiasZ7KbFnmQRyuLE7cFXW2PVd7dmALzbkUXEP46upAuCDm9eY9vho8fgNMGmbAX92QBZHzcnWIqw== + version "1.0.30001525" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001525.tgz" + integrity sha512-/3z+wB4icFt3r0USMwxujAqRvaD/B7rvGTsKhbhSQErVrJvkZCLhgNLJxU8MevahQVH6hCU9FsHdNUFbiwmE7Q== ccount@^1.0.0: version "1.1.0"