From 769d5ff7b606843f124318b10e820f054df92b44 Mon Sep 17 00:00:00 2001 From: Victor Graf Date: Tue, 8 Aug 2023 17:36:37 -0700 Subject: [PATCH] use backport and update README and exmaple --- .gitmodules | 3 +- Cargo.lock | 120 +++++---------- Cargo.toml | 9 +- README.md | 119 +++++++-------- lib/risc0 | 2 +- methods/guest/Cargo.lock | 138 +++++++++++++----- methods/guest/Cargo.toml | 3 +- .../{publish.rs => callback_request.rs} | 39 +++-- relay/src/lib.rs | 17 ++- 9 files changed, 250 insertions(+), 200 deletions(-) rename relay/examples/{publish.rs => callback_request.rs} (59%) diff --git a/.gitmodules b/.gitmodules index a8d7fab2..2f30827b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,4 +13,5 @@ [submodule "lib/risc0"] path = lib/risc0 url = https://github.com/risc0/risc0 - branch = d636116f6547cbb02b24a51edfceb8bbadc0cba9 + # DO NOT MERGE: Update this to a release tag + branch = capossele/governance-example diff --git a/Cargo.lock b/Cargo.lock index 394306e1..dd13bc62 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -29,13 +29,7 @@ version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" dependencies = [ - "cpp_demangle", - "fallible-iterator", "gimli", - "memmap2", - "object", - "rustc-demangle", - "smallvec 1.11.0", ] [[package]] @@ -609,7 +603,7 @@ dependencies = [ [[package]] name = "bonsai-ethereum-contracts" version = "0.1.0" -source = "git+https://github.com/risc0/risc0?branch=victor/governance-showcase#bdcd1388dfe38775fd512c6395d56f646d0175d3" +source = "git+https://github.com/risc0/risc0?branch=capossele/governance-example#4f525afc9072494bd91aa9b19c968e16fcbb5c23" dependencies = [ "anyhow", "clap", @@ -620,7 +614,7 @@ dependencies = [ [[package]] name = "bonsai-ethereum-relay" version = "0.2.0" -source = "git+https://github.com/risc0/risc0?branch=victor/governance-showcase#bdcd1388dfe38775fd512c6395d56f646d0175d3" +source = "git+https://github.com/risc0/risc0?branch=capossele/governance-example#4f525afc9072494bd91aa9b19c968e16fcbb5c23" dependencies = [ "anyhow", "async-trait", @@ -679,7 +673,7 @@ dependencies = [ [[package]] name = "bonsai-rest-api-mock" version = "0.2.0" -source = "git+https://github.com/risc0/risc0?branch=victor/governance-showcase#bdcd1388dfe38775fd512c6395d56f646d0175d3" +source = "git+https://github.com/risc0/risc0?branch=capossele/governance-example#4f525afc9072494bd91aa9b19c968e16fcbb5c23" dependencies = [ "anyhow", "axum", @@ -703,7 +697,7 @@ dependencies = [ [[package]] name = "bonsai-sdk" version = "0.2.0" -source = "git+https://github.com/risc0/risc0?branch=victor/governance-showcase#bdcd1388dfe38775fd512c6395d56f646d0175d3" +source = "git+https://github.com/risc0/risc0?branch=capossele/governance-example#4f525afc9072494bd91aa9b19c968e16fcbb5c23" dependencies = [ "reqwest", "serde", @@ -1205,15 +1199,6 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" -[[package]] -name = "cpp_demangle" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee34052ee3d93d6d8f3e6f81d85c47921f6653a19a7b70e939e3e602d893a674" -dependencies = [ - "cfg-if", -] - [[package]] name = "cpufeatures" version = "0.2.9" @@ -1565,6 +1550,25 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" +[[package]] +name = "dyn_partial_eq" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a07039d197226c4b9a3810c4f165328fb4e715258a4b8584f143d38e9de04301" +dependencies = [ + "dyn_partial_eq_derive", +] + +[[package]] +name = "dyn_partial_eq_derive" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e217c6c1435ebf9b88662354589d339192b8eaf506edd22951e75e045c8e8bd" +dependencies = [ + "quote", + "syn 1.0.109", +] + [[package]] name = "ecdsa" version = "0.16.8" @@ -2346,12 +2350,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "fallible-iterator" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" - [[package]] name = "fastrand" version = "2.0.0" @@ -2958,10 +2956,6 @@ name = "gimli" version = "0.27.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" -dependencies = [ - "fallible-iterator", - "stable_deref_trait", -] [[package]] name = "git2" @@ -4465,9 +4459,7 @@ version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" dependencies = [ - "flate2", "memchr", - "ruzstd", ] [[package]] @@ -5405,29 +5397,15 @@ dependencies = [ "digest 0.10.7", ] -[[package]] -name = "risc0-binfmt" -version = "0.16.1" -source = "git+https://github.com/risc0/risc0?branch=victor/governance-showcase#bdcd1388dfe38775fd512c6395d56f646d0175d3" -dependencies = [ - "anyhow", - "elf", - "log", - "risc0-zkp", - "risc0-zkvm-platform", - "serde", -] - [[package]] name = "risc0-build" version = "0.16.1" -source = "git+https://github.com/risc0/risc0?branch=victor/governance-showcase#bdcd1388dfe38775fd512c6395d56f646d0175d3" +source = "git+https://github.com/risc0/risc0?branch=capossele/governance-example#4f525afc9072494bd91aa9b19c968e16fcbb5c23" dependencies = [ "cargo_metadata 0.15.4", "directories", "downloader", - "risc0-binfmt", - "risc0-zkp", + "risc0-zkvm", "risc0-zkvm-platform", "serde", "serde_json", @@ -5439,7 +5417,7 @@ dependencies = [ [[package]] name = "risc0-build-kernel" version = "0.16.1" -source = "git+https://github.com/risc0/risc0?branch=victor/governance-showcase#bdcd1388dfe38775fd512c6395d56f646d0175d3" +source = "git+https://github.com/risc0/risc0?branch=capossele/governance-example#4f525afc9072494bd91aa9b19c968e16fcbb5c23" dependencies = [ "cc", "directories", @@ -5452,7 +5430,7 @@ dependencies = [ [[package]] name = "risc0-circuit-rv32im" version = "0.16.1" -source = "git+https://github.com/risc0/risc0?branch=victor/governance-showcase#bdcd1388dfe38775fd512c6395d56f646d0175d3" +source = "git+https://github.com/risc0/risc0?branch=capossele/governance-example#4f525afc9072494bd91aa9b19c968e16fcbb5c23" dependencies = [ "anyhow", "log", @@ -5469,7 +5447,7 @@ dependencies = [ [[package]] name = "risc0-circuit-rv32im-sys" version = "0.16.1" -source = "git+https://github.com/risc0/risc0?branch=victor/governance-showcase#bdcd1388dfe38775fd512c6395d56f646d0175d3" +source = "git+https://github.com/risc0/risc0?branch=capossele/governance-example#4f525afc9072494bd91aa9b19c968e16fcbb5c23" dependencies = [ "glob", "risc0-build-kernel", @@ -5480,7 +5458,7 @@ dependencies = [ [[package]] name = "risc0-core" version = "0.16.1" -source = "git+https://github.com/risc0/risc0?branch=victor/governance-showcase#bdcd1388dfe38775fd512c6395d56f646d0175d3" +source = "git+https://github.com/risc0/risc0?branch=capossele/governance-example#4f525afc9072494bd91aa9b19c968e16fcbb5c23" dependencies = [ "bytemuck", "rand_core", @@ -5489,7 +5467,7 @@ dependencies = [ [[package]] name = "risc0-sys" version = "0.16.1" -source = "git+https://github.com/risc0/risc0?branch=victor/governance-showcase#bdcd1388dfe38775fd512c6395d56f646d0175d3" +source = "git+https://github.com/risc0/risc0?branch=capossele/governance-example#4f525afc9072494bd91aa9b19c968e16fcbb5c23" dependencies = [ "cc", "glob", @@ -5500,7 +5478,7 @@ dependencies = [ [[package]] name = "risc0-zkp" version = "0.16.1" -source = "git+https://github.com/risc0/risc0?branch=victor/governance-showcase#bdcd1388dfe38775fd512c6395d56f646d0175d3" +source = "git+https://github.com/risc0/risc0?branch=capossele/governance-example#4f525afc9072494bd91aa9b19c968e16fcbb5c23" dependencies = [ "anyhow", "blake2", @@ -5520,21 +5498,23 @@ dependencies = [ "risc0-zkvm-platform", "serde", "sha2 0.10.7", + "thiserror", "tracing", ] [[package]] name = "risc0-zkvm" version = "0.16.1" -source = "git+https://github.com/risc0/risc0?branch=victor/governance-showcase#bdcd1388dfe38775fd512c6395d56f646d0175d3" +source = "git+https://github.com/risc0/risc0?branch=capossele/governance-example#4f525afc9072494bd91aa9b19c968e16fcbb5c23" dependencies = [ - "addr2line", "anyhow", "bincode", "bonsai-sdk", "bytemuck", "cfg-if", "crypto-bigint", + "dyn_partial_eq", + "elf", "generic-array", "getrandom", "hex", @@ -5545,7 +5525,6 @@ dependencies = [ "num-traits", "rand", "rayon", - "risc0-binfmt", "risc0-circuit-rv32im", "risc0-core", "risc0-zkp", @@ -5561,7 +5540,7 @@ dependencies = [ [[package]] name = "risc0-zkvm-platform" version = "0.16.1" -source = "git+https://github.com/risc0/risc0?branch=victor/governance-showcase#bdcd1388dfe38775fd512c6395d56f646d0175d3" +source = "git+https://github.com/risc0/risc0?branch=capossele/governance-example#4f525afc9072494bd91aa9b19c968e16fcbb5c23" [[package]] name = "rlp" @@ -5913,17 +5892,6 @@ dependencies = [ "wait-timeout", ] -[[package]] -name = "ruzstd" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a15e661f0f9dac21f3494fe5d23a6338c0ac116a2d22c2b63010acd89467ffe" -dependencies = [ - "byteorder", - "thiserror", - "twox-hash", -] - [[package]] name = "ryu" version = "1.0.15" @@ -6433,12 +6401,6 @@ dependencies = [ "der", ] -[[package]] -name = "stable_deref_trait" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" - [[package]] name = "static_assertions" version = "1.1.0" @@ -7167,16 +7129,6 @@ dependencies = [ "webpki", ] -[[package]] -name = "twox-hash" -version = "1.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" -dependencies = [ - "cfg-if", - "static_assertions", -] - [[package]] name = "typed-builder" version = "0.12.0" diff --git a/Cargo.toml b/Cargo.toml index 51010647..7e6fb286 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,10 +2,11 @@ members = ["methods", "relay"] [workspace.dependencies] -risc0-build = { git = "https://github.com/risc0/risc0", branch = "victor/governance-showcase" } -risc0-zkvm = { git = "https://github.com/risc0/risc0", branch = "victor/governance-showcase", default-features = false } -bonsai-sdk = { git = "https://github.com/risc0/risc0", branch = "victor/governance-showcase" } -bonsai-ethereum-relay = { git = "https://github.com/risc0/risc0", branch = "victor/governance-showcase" } +# DO NOT MERGE: Update this to a release tag +risc0-build = { git = "https://github.com/risc0/risc0", branch = "capossele/governance-example" } +risc0-zkvm = { git = "https://github.com/risc0/risc0", branch ="capossele/governance-example", default-features = false } +bonsai-sdk = { git = "https://github.com/risc0/risc0", branch = "capossele/governance-example"} +bonsai-ethereum-relay = { git = "https://github.com/risc0/risc0", branch = "capossele/governance-example"} methods = { path = "./methods", package = "bonsai-starter-methods" } # Always optimize; building and running the guest takes much longer without optimization. diff --git a/README.md b/README.md index a9f7b759..71841652 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,7 @@ Starter template for writing an application using [Bonsai]. This repository implements an application on Ethereum utilizing Bonsai as a coprocessor to the smart contract application. -It provides a starting point for building powerful new applications on Ethereum that offload computationally intensive -(or difficult to implement) tasks to be proven by the [RISC Zero] [zkVM], with verifiable results sent to your Ethereum contract. +It provides a starting point for building powerful new applications on Ethereum that offload computationally intensive, or difficult to implement, tasks to be proven by the [RISC Zero] [zkVM], with verifiable results sent to your Ethereum contract. *For a 60 second overview of how this template and off-chain computation with Bonsai work, [check out the video here](https://www.youtube.com/watch?v=WDS8X8H9mIk).* @@ -43,7 +42,7 @@ Associated build configuration files and tests are discussed along with the [pro ## Test Your Project -With this Foundry template, you can write a zkVM Rust program in the `/methods/guest` directory which Solidity contracts in `/contracts` can call into and in return receive a proof or 'receipt' of execution. +With this Foundry template, you can write a zkVM Rust program, in the `/methods/guest` directory, which Solidity contracts in `/contracts` can call into and in return receive a proof or '[receipt]' of execution. ### Test your zkVM program @@ -69,13 +68,13 @@ To test both your Solidity contracts and their interaction with your zkVM progra forge test ``` -***Tip:*** *To learn more about Foundry's `forge` command and the other helpful utilities Foundry provides, visit their docs: https://book.getfoundry.sh/forge/tests.* +***Tip:*** *To learn more about Foundry's `forge` command and the other helpful utilities Foundry provides, visit their docs: [https://book.getfoundry.sh/forge/tests].* ### Deploy your project on a local network You can deploy your contracts and run an end-to-end test or demo as follows: -1. Start an anvil instance, if you want a local testnet, by running: +1. Start a local testnet with `anvil` by running: ```bash anvil @@ -83,40 +82,46 @@ You can deploy your contracts and run an end-to-end test or demo as follows: Once anvil is started, keep it running in the terminal, and switch to a new terminal. -2. Deploy the `BonsaiRelay` contract by running: +2. Deploy an `IBonsaiRelay` contract by running: ```bash - RISC0_DEV_MODE= forge script script/Deploy.s.sol --rpc-url http://localhost:8545 --broadcast + RISC0_DEV_MODE=true forge script script/Deploy.s.sol --rpc-url http://localhost:8545 --broadcast ``` - Check the logs for the address of the `BonsaiRelay` contract. +3. Check the logs for the address of the deployed `BonsaiTestRelay` contract and your application contract. + Save them to a couple of environment variables to reference later. -3. Start the Bonsai Ethereum Relay by running: + ```bash + export BONSAI_RELAY_ADDRESS="#copy relay address from the deploy logs#" + export APP_ADDRESS="#copy app address from the deploy logs#" + ``` + +4. Start the Bonsai Ethereum Relay by running: ```bash - RISC0_DEV_MODE= cargo run --bin bonsai-ethereum-relay-cli -- run --relay-address 0x5FbDB2315678afecb367f032d93F642f64180aa3 + RISC0_DEV_MODE=true cargo run --bin bonsai-ethereum-relay-cli -- run --relay-address "$BONSAI_RELAY_ADDRESS" ``` - The relay will keep monitoring the chain for callback requests and relay their result back after computing them. - You should keep this terminal instance running the relay in the foreground and switch to a new terminal. - When setting the env variable `RISC0_DEV_MODE`, the relay will start a mock version of Bonsai that will only return a journal of the execution without any cryptographic proof. - If needed, you should modify the environment variables to reflect your setup. - For instance, if you want to prove remotely via Bonsai, unset `RISC0_DEV_MODE` and set `BONSAI_API_URL` and `BONSAI_API_KEY` accordingly. - Moreover, if you want to run the relay on a remote Ethereum network, you can use a different `ETH_NODE`, `ETH_CHAIN_ID` and `PRIVATE_KEY`. - If you want to know more about the relay, you can follow this [link](https://github.com/risc0/risc0/tree/main/bonsai/ethereum-relay). + The relay will keep monitoring the chain for callback requests, generated when your contract calls `bonsaiRelay.requestCallback(...)`, and relay their result back to your contract after computing them. + Keep the relay running and switch to a new terminal. -**Now you can test your deployment as follows:** + Setting `RISC0_DEV_MODE=true` deploys the `BonsaiTestRelay`, for use in local development and testing, instead of the fully verifying `BonsaiRelay` contract. + See the section below on using the fully-verifying relay for more information on this setting and testnet deployment. + +**Interact with your deployment:** + +You now have a locally running testnet and relay deployment that you can interact with using `cast`, a wallet, or any application you write. 1. Send a transaction to the starter contract: ```bash - cast send --private-key 0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d --gas-limit 100000 0xe7f1725e7734ce288f8367e1bb143e90bb3f0512 'calculateFibonacci(uint256)' 5 + cast send --private-key 0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d --gas-limit 100000 "$APP_ADDRESS" 'calculateFibonacci(uint256)' 5 ``` 2. Check the relayed result: ```bash - cast call 0xe7f1725e7734ce288f8367e1bb143e90bb3f0512 'fibonacci(uint256)' 5 + cast call "$APP_ADDRESS" 'fibonacci(uint256)' 5 ``` **Deploy a new version of your application:** @@ -125,72 +130,66 @@ When you want to deploy a new version of the application contract, run the follo Set `DEPLOY_UPLOAD_IMAGES=true` if you modified your guest and need to upload a new version to Bonsai. ```bash -DEPLOY_RELAY_ADDRESS=0x5FbDB2315678afecb367f032d93F642f64180aa3 DEPLOY_UPLOAD_IMAGES=true forge script script/Deploy.s.sol --rpc-url http://localhost:8545 --broadcast +RISC0_DEV_MODE=true DEPLOY_RELAY_ADDRESS="$APP_ADDRESS" DEPLOY_UPLOAD_IMAGES=true forge script script/Deploy.s.sol --rpc-url http://localhost:8545 --broadcast ``` This will deploy only your application address and upload any updated images. -The existing relay contract and the running relay will continue to be used. +The existing relay contract and, by setting `DEPLOY_RELAY_ADDRESS`, the running relay will continue to be used. **Use the fully verifying relay:** -If you want to use Bonsai and the on-chain SNARK verifier in your local or testnet deployment, set `BONSAI_PROVING=bonsai` and rerun the steps for deployment. -When `BONSAI_PROVING=bonsai`, the zkVM guest images will be uploaded to Bonsai and the relay will use Bonsai for executing and proving the guest. -With this setup, the fully verifying relay will be used and a SNARK proof will be required to send a callback to your application. +In each of the commands above, the environment variable `RISC0_DEV_MODE=true` is added. +With this environment variable set, the `BonsaiTestRelay` contract is used, which does not check callbacks for authentication. +This provides fast development, allowing you to iterate on your application. + +When it's time to deploy you application to a live chain, such as the Sepolia testnet, you should remove this environment or set `RISC0_DEV_MODE=false`. +When unset, or set to `false`, the fully-verifying `BonsaiRelay` contract will be used and all callbacks will require a [Groth16 SNARK proof] for authentication. +This is what provides the security guarantees of Bonsai, that only legitimate outputs from your guest program can be sent to your application contract. +Producing SNARK receipts that are verifiable on-chain requires the Bonsai proving service. See the [Configuring Bonsai](#Configuring Bonsai) section below for more information about using the Bonsai proving service. +When you want to deploy to a testnet, configure the relay with `ETH_NODE`, `ETH_CHAIN_ID` and `PRIVATE_KEY` environment variables. +If you want to know more about the relay, you can follow this [link](https://github.com/risc0/risc0/tree/main/bonsai/ethereum-relay). + ### Off-chain Callback Request -The Relay exposes an HTTP REST API interface that can be used to directly send *off-chain* Callback requests to it, as an alternative to the on-chain requests. -It also provides an SDK in `rust` that can be used to interact with it. You can check out this [example](relay/examples/publish.rs). +The Relay exposes an HTTP REST API interface that can be used to directly send *off-chain* callback requests to it, as an alternative to the on-chain requests. +It also provides an SDK in Rust that can be used to interact with it. You can check out this [example](relay/examples/callback_request.rs.rs). -Assuming that Anvil and the Relay are running and both the `BonsaiRelay` and `BonsaiStarter` are deployed (first 4 steps of the previous section), you can send a `Callback` request directly to the Relay by running: +Assuming that Anvil and the Relay are running and both an `IBonsaiRelay` and the `BonsaiStarter` app contract are deployed (first 4 steps of the previous section), you can send a callback request directly to the Relay by running: ```bash -cargo run --example publish 288ea9093b9000870ccd8cef93d24bba3cc5f67b14b6f9b651072e23984a379c 0xe7f1725e7734ce288f8367e1bb143e90bb3f0512 10 +cargo run --example callback_request "$APP_ADDRESS" 10 ``` -The first argument is the `image_id`, then the `BonsaiStarter` address and finally the number to compute the Fibonacci sequence. +This example's arguments are the `BonsaiStarter` contract address and the number, N, to compute the Nth Fibonacci number. You may need to change these values accordingly. -Once again, you can check the relayed result +Just as with on-chain callback requests, you can check the relayed result ```bash -cast call 0xe7f1725e7734ce288f8367e1bb143e90bb3f0512 'fibonacci(uint256)' 10 +cast call "$APP_ADDRESS" 'fibonacci(uint256)' 10 ``` -The Relay source code with its SDK can be found in the [risc0/risc0](https://github.com/risc0/risc0/tree/main/bonsai/ethereum-relay) github repo. - -## Proving Modes - -The foundry template supports two different proving modes: +The Relay source code with its SDK can be found in the [risc0/risc0] github repo. -1. `local` - By default, only the [executor](https://www.dev.risczero.com/docs/terminology#executor) runs your zkVM program and no proof is generated. - Because there is no proving, this will be the fastest way to test. - In the local, execution-only, mode a mock version of the `BonsaiRelay` will be used that does not verify proofs for callbacks. +### Configuring Bonsai -2. `bonsai` - A proof of execution is generated by the Bonsai API. - When using the `bonsai` proving mode, the real `BonsaiRelay` will be used and all callbacks will require a SNARK proof. +***Note:*** *The Bonsai proving service is still in early Alpha. To request an API key [complete the form here](https://bonsai.xyz/apply).* -Configure your preferred mode by setting the `BONSAI_PROVING` env variable. +With the Bonsai proving service, you can produce a [Groth16 SNARK proof] that is verifiable on-chain. +You can get started by setting the following environment variables with your API key and associated URL. ```bash -export BONSAI_PROVING=bonsai +export BONSAI_API_KEY="YOUR_API_KEY" # see form linked above +export BONSAI_API_URL="BONSAI_URL" # provided with your api key ``` -After setting your preferred proving mode, use `forge test` to build and run your application. - -### Configuring Bonsai - -***Note:*** *The Bonsai proving service is still in early Alpha. To request an API key [complete the form here](https://bonsai.xyz/apply).* - -To prove in `bonsai` mode, two additional environment variables are required +Now if you run `forge test` with `RISC0_DEV_MODE=false`, the test will run as before, but will additionally use the fully verifying `BonsaiRelay` contract instead of `BonsaiTestRelay` and will request a SNARK receipt from Bonsai. ```bash -export BONSAI_API_KEY="YOUR_API_KEY" #see form linked above -export BONSAI_API_URL="BONSAI_URL" #provided with your api key -export BONSAI_PROVING=bonsai -forge test +RISC0_DEV_MODE=false forge test ``` ## Project Structure @@ -242,9 +241,13 @@ The image ID will be included in the deployment of the smart contracts to refere Build configuration for the methods is included in `methods/build.rs`. [Bonsai]: https://dev.bonsai.xyz/ -[RISC Zero]: https://www.risczero.com/ +[Foundry]: https://getfoundry.sh/ +[Groth16 SNARK proof]: https://www.risczero.com/news/on-chain-verification [RISC Zero examples]: https://github.com/risc0/risc0/tree/main/examples +[RISC Zero]: https://www.risczero.com/ [RISC-V]: https://www.risczero.com/docs/reference-docs/about-risc-v -[Foundry]: https://getfoundry.sh/ -[zkVM]: https://www.dev.risczero.com/terminology#zero-knowledge-virtual-machine-zkvm +[https://book.getfoundry.sh/forge/tests]: https://book.getfoundry.sh/forge/tests +[receipt]: https://dev.risczero.com/zkvm/developer-guide/receipts +[risc0/risc0]: https://github.com/risc0/risc0/tree/main/bonsai/ethereum-relay [zkVM guest program]: https://www.dev.risczero.com/terminology#guest-program +[zkVM]: https://www.dev.risczero.com/terminology#zero-knowledge-virtual-machine-zkvm diff --git a/lib/risc0 b/lib/risc0 index bdcd1388..64dcd473 160000 --- a/lib/risc0 +++ b/lib/risc0 @@ -1 +1 @@ -Subproject commit bdcd1388dfe38775fd512c6395d56f646d0175d3 +Subproject commit 64dcd473427fe2347fbf70ebb156a9e032a7c6ce diff --git a/methods/guest/Cargo.lock b/methods/guest/Cargo.lock index 644924c8..76ba758b 100644 --- a/methods/guest/Cargo.lock +++ b/methods/guest/Cargo.lock @@ -58,7 +58,7 @@ checksum = "fdde5c9cd29ebd706ce1b35600920a33550e402fc998a2e53ad3b42c3c47a192" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.18", ] [[package]] @@ -73,12 +73,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "const-oid" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "795bc6e66a8e340f075fcf6227e417a2dc976b92b91f3cdc778bb858778b6747" - [[package]] name = "cpufeatures" version = "0.2.7" @@ -111,16 +105,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", - "const-oid", "crypto-common", "subtle", ] [[package]] -name = "elf" -version = "0.7.2" +name = "dyn_partial_eq" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a07039d197226c4b9a3810c4f165328fb4e715258a4b8584f143d38e9de04301" +dependencies = [ + "dyn_partial_eq_derive", +] + +[[package]] +name = "dyn_partial_eq_derive" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2b183d6ce6ca4cf30e3db37abf5b52568b5f9015c97d9fbdd7026aa5dcdd758" +checksum = "0e217c6c1435ebf9b88662354589d339192b8eaf506edd22951e75e045c8e8bd" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "erased-serde" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6984864d65d092d9e9ada107007a846a09f75d2e24046bcce9a38d14aa52052" +dependencies = [ + "serde", +] [[package]] name = "ethabi" @@ -182,6 +197,12 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "inventory" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a53088c87cf71c9d4f3372a2cb9eea1e7b8a0b1bf8b7f7d23fe5b76dbb07e63b" + [[package]] name = "keccak" version = "0.1.4" @@ -217,7 +238,7 @@ checksum = "9e6a0fd4f737c707bd9086cc16c925f294943eb62eb71499e9fd4cf71f8b9f4e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.18", ] [[package]] @@ -229,6 +250,12 @@ dependencies = [ "autocfg", ] +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + [[package]] name = "paste" version = "1.0.12" @@ -280,23 +307,10 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -[[package]] -name = "risc0-binfmt" -version = "0.16.1" -source = "git+https://github.com/risc0/risc0?branch=victor/governance-showcase#0976e2f69151dfb6ffa5bceea5d51ec373944d8f" -dependencies = [ - "anyhow", - "elf", - "log", - "risc0-zkp", - "risc0-zkvm-platform", - "serde", -] - [[package]] name = "risc0-circuit-rv32im" version = "0.16.1" -source = "git+https://github.com/risc0/risc0?branch=victor/governance-showcase#0976e2f69151dfb6ffa5bceea5d51ec373944d8f" +source = "git+https://github.com/risc0/risc0?branch=capossele/governance-example#01ac692586914ccbac850b851609759173216f57" dependencies = [ "anyhow", "log", @@ -309,7 +323,7 @@ dependencies = [ [[package]] name = "risc0-core" version = "0.16.1" -source = "git+https://github.com/risc0/risc0?branch=victor/governance-showcase#0976e2f69151dfb6ffa5bceea5d51ec373944d8f" +source = "git+https://github.com/risc0/risc0?branch=capossele/governance-example#01ac692586914ccbac850b851609759173216f57" dependencies = [ "bytemuck", "rand_core", @@ -318,7 +332,7 @@ dependencies = [ [[package]] name = "risc0-zkp" version = "0.16.1" -source = "git+https://github.com/risc0/risc0?branch=victor/governance-showcase#0976e2f69151dfb6ffa5bceea5d51ec373944d8f" +source = "git+https://github.com/risc0/risc0?branch=capossele/governance-example#01ac692586914ccbac850b851609759173216f57" dependencies = [ "anyhow", "blake2", @@ -332,36 +346,39 @@ dependencies = [ "risc0-zkvm-platform", "serde", "sha2", + "thiserror", "tracing", ] [[package]] name = "risc0-zkvm" version = "0.16.1" -source = "git+https://github.com/risc0/risc0?branch=victor/governance-showcase#0976e2f69151dfb6ffa5bceea5d51ec373944d8f" +source = "git+https://github.com/risc0/risc0?branch=capossele/governance-example#01ac692586914ccbac850b851609759173216f57" dependencies = [ "anyhow", "bytemuck", "cfg-if", + "dyn_partial_eq", "getrandom", "hex", "libm", "log", "num-derive", "num-traits", - "risc0-binfmt", "risc0-circuit-rv32im", "risc0-core", "risc0-zkp", "risc0-zkvm-platform", "serde", + "thiserror", "tracing", + "typetag", ] [[package]] name = "risc0-zkvm-platform" version = "0.16.1" -source = "git+https://github.com/risc0/risc0?branch=victor/governance-showcase#0976e2f69151dfb6ffa5bceea5d51ec373944d8f" +source = "git+https://github.com/risc0/risc0?branch=capossele/governance-example#01ac692586914ccbac850b851609759173216f57" [[package]] name = "rustc-hex" @@ -386,7 +403,7 @@ checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.18", ] [[package]] @@ -422,6 +439,17 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "syn" version = "2.0.18" @@ -433,6 +461,26 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "thiserror" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.18", +] + [[package]] name = "tracing" version = "0.1.37" @@ -453,7 +501,7 @@ checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.18", ] [[package]] @@ -468,6 +516,30 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +[[package]] +name = "typetag" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6898cc6f6a32698cc3e14d5632a14d2b23ed9f7b11e6b8e05ce685990acc22" +dependencies = [ + "erased-serde", + "inventory", + "once_cell", + "serde", + "typetag-impl", +] + +[[package]] +name = "typetag-impl" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c3e1c30cedd24fc597f7d37a721efdbdc2b1acae012c1ef1218f4c7c2c0f3e7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.18", +] + [[package]] name = "uint" version = "0.9.5" diff --git a/methods/guest/Cargo.toml b/methods/guest/Cargo.toml index c4fb6a43..975184dc 100644 --- a/methods/guest/Cargo.toml +++ b/methods/guest/Cargo.toml @@ -11,7 +11,8 @@ path = "src/bin/fibonacci.rs" ethabi = { version = "18.0", default-features = false } # Directly import radium to silence warning about unused patch. See https://github.com/risc0/risc0/issues/549 radium = "=0.7.1" -risc0-zkvm = { git = "https://github.com/risc0/risc0", branch = "victor/governance-showcase", default-features = false, features = ["std"] } +# DO NOT MERGE: Update this to a release tag +risc0-zkvm = { git = "https://github.com/risc0/risc0", branch = "capossele/governance-example", default-features = false, features = ["std"] } [patch.crates-io] radium = { git = "https://github.com/bitvecto-rs/radium", rev = "723bed5abd75994ee4b7221b8b12c9f4e77ce408" } diff --git a/relay/examples/publish.rs b/relay/examples/callback_request.rs similarity index 59% rename from relay/examples/publish.rs rename to relay/examples/callback_request.rs index c69d7627..cd5e04a2 100644 --- a/relay/examples/publish.rs +++ b/relay/examples/callback_request.rs @@ -12,44 +12,57 @@ // See the License for the specific language governing permissions and // limitations under the License. +use anyhow::Context; use bonsai_ethereum_relay::sdk::client::{CallbackRequest, Client}; use clap::Parser; use ethers::{abi::ethabi, types::Address}; +use methods::FIBONACCI_ID; +use risc0_zkvm::sha::Digest; +/// Exmaple code for sending a REST API request to the Bonsai relay service to +/// requests, execution, proving, and on-chain callback for a zkVM guest +/// application. #[derive(Parser, Debug)] -#[command(author, version, about, long_about = None)] +#[command(author, version, about, long_about)] struct Args { - image_id: String, + /// Adress for the BonsaiStarter application contract. address: Address, + + /// Input N for calculating the Nth Fibonacci number. number: u64, + + /// Bonsai Relay API URL. + #[arg(long, env, default_value = "http://localhost:8080")] + bonsai_relay_api_url: String, + + /// Bonsai API key. Used by the relay to send requests to the Bonsai proving + /// service. Defaults to empty, providing no authentication. + #[arg(long, env, default_value = "")] + bonsai_api_key: String, } #[tokio::main] -async fn main() { +async fn main() -> anyhow::Result<()> { let args = Args::parse(); // initialize a relay client let relay_client = Client::from_parts( - "http://localhost:8080".to_string(), // here goes the actual url of the Bonsai Relay - "BONSAI_API_KEY".to_string(), // here goes the actual Bonsai API-Key + args.bonsai_relay_api_url.clone(), // Set BONSAI_API_URL or replace this line. + args.bonsai_api_key.clone(), // Set BONSAI_API_KEY or replace this line. ) - .expect("Failed to initialize the relay client"); + .context("Failed to initialize the relay client")?; // Initialize the input for the FIBONACCI guest. let input = ethabi::encode(&[ethers::abi::Token::Uint(args.number.into())]); // Create a CallbackRequest for your contract // example: (contracts/BonsaiStarter.sol). - let image_id: [u8; 32] = hex::decode(args.image_id) - .expect("unable to decode") - .try_into() - .expect("unable to convert image id"); let request = CallbackRequest { callback_contract: args.address, // you can use the command `solc --hashes contracts/BonsaiStarter.sol` // to get the value for your actual contract (9f2275c0: storeResult(uint256,uint256)) function_selector: [0x9f, 0x22, 0x75, 0xc0], gas_limit: 3000000, - image_id: image_id.into(), + image_id: Digest::from(FIBONACCI_ID).into(), input, }; @@ -57,5 +70,7 @@ async fn main() { relay_client .callback_request(request) .await - .expect("Callback request failed"); + .context("Callback request failed")?; + + Ok(()) } diff --git a/relay/src/lib.rs b/relay/src/lib.rs index b1798c13..314471ed 100644 --- a/relay/src/lib.rs +++ b/relay/src/lib.rs @@ -18,7 +18,8 @@ use anyhow::{anyhow, bail, Context, Result}; use bonsai_sdk::alpha::{responses::SnarkProof, Client, SdkErr}; use risc0_build::GuestListEntry; use risc0_zkvm::{ - Executor, ExecutorEnv, MemoryImage, Program, Receipt, ReceiptMetadata, MEM_SIZE, PAGE_SIZE, + Executor, ExecutorEnv, LocalExecutor, MemoryImage, Program, ReceiptMetadata, SessionReceipt, + MEM_SIZE, PAGE_SIZE, }; /// Result of executing a guest image, possibly containing a proof. @@ -42,7 +43,7 @@ pub fn execute_locally(elf: &[u8], input: Vec) -> Result { .add_input(&input) .build() .context("Failed to build exec env")?; - let mut exec = Executor::from_elf(env, elf).context("Failed to instantiate executor")?; + let mut exec = LocalExecutor::from_elf(env, elf).context("Failed to instantiate executor")?; let session = exec .run() .context(format!("Failed to run executor {:?}", &input))?; @@ -80,7 +81,7 @@ pub fn prove_alpha(elf: &[u8], input: Vec) -> Result { .context("Failed to create remote proving session")?; // Poll and await the result of the STARK rollup proving session. - let receipt: Receipt = (|| { + let receipt: SessionReceipt = (|| { loop { let res = match session.status(&client) { Ok(res) => res, @@ -101,8 +102,8 @@ pub fn prove_alpha(elf: &[u8], input: Vec) -> Result { .context("Missing 'receipt_url' on status response")?, ) .context("Failed to download receipt")?; - let receipt: Receipt = bincode::deserialize(&receipt_buf) - .context("Failed to deserialize Receipt")?; + let receipt: SessionReceipt = bincode::deserialize(&receipt_buf) + .context("Failed to deserialize SessionReceipt")?; // eprintln!("Completed STARK proof on bonsai alpha backend!"); return Ok(receipt); } @@ -115,7 +116,11 @@ pub fn prove_alpha(elf: &[u8], input: Vec) -> Result { } } })()?; - let metadata = receipt.get_metadata()?; + let metadata = receipt + .segments + .last() + .ok_or(anyhow!("no segments found in receipt"))? + .get_metadata()?; let snark_session = client.create_snark(session.uuid)?; let snark_proof: SnarkProof = (|| loop {