Skip to content

Commit

Permalink
[saya] demo (#1883)
Browse files Browse the repository at this point in the history
* refactor in progress

* proving pipeline

* remove commented test

* remove genesis init

* remove unused imports

* add https

* Revert "add https"

This reverts commit 0397a01.

* add world entrypoint function

* fmt

* enhance readme

* add world tests

* fmt

* fix: fix tests and merge main

* fix: bindings and fmt

* fix: ensure type aliases are used for World config

* docs: update readme

---------

Co-authored-by: glihm <[email protected]>
  • Loading branch information
neotheprogramist and glihm authored May 2, 2024
1 parent 048d6dc commit 8f8bdd3
Show file tree
Hide file tree
Showing 51 changed files with 1,640 additions and 4,437 deletions.
297 changes: 232 additions & 65 deletions Cargo.lock

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,11 @@ cairo-lang-test-plugin = "=2.5.4"
cairo-lang-test-runner = "=2.5.4"
cairo-lang-test-utils = "=2.5.4"
cairo-lang-utils = "=2.5.4"
cairo-proof-parser = { git = "https://github.com/cartridge-gg/cairo-proof-parser.git", version = "0.1.2" }
cairo-proof-parser = { git = "https://github.com/cartridge-gg/cairo-proof-parser", tag = "v0.3.0" }
cairo-vm = "0.9.2"
camino = { version = "1.1.2", features = [ "serde1" ] }
chrono = { version = "0.4.24", features = [ "serde" ] }
clap = { version = "4.5", features = [ "derive" ] }
clap = { version = "4.5.4", features = [ "derive" ] }
clap_complete = "4.3"
console = "0.15.7"
convert_case = "0.6.0"
Expand All @@ -137,7 +137,7 @@ flate2 = "1.0.24"
futures = "0.3.28"
hex = "0.4.3"
indoc = "1.0.7"
itertools = "0.10.3"
itertools = "0.12.1"
jsonrpsee = { version = "0.16.2", default-features = false }
lazy_static = "1.4.0"
metrics = "0.21.1"
Expand Down Expand Up @@ -170,6 +170,7 @@ toml = "0.7.4"
tracing = "0.1.34"
tracing-subscriber = { version = "0.3.16", features = [ "env-filter", "json" ] }
url = { version = "2.4.0", features = [ "serde" ] }
reqwest = "0.12.4"

rstest = "0.18.2"
rstest_reuse = "0.6.0"
Expand Down
65 changes: 51 additions & 14 deletions bin/saya/README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,58 @@
# Saya executable

Saya executable runs Saya service with CLI configurations.
# Saya Executable Documentation

Currently, Saya fetches some Katana blocks, and can publish the state update on a Celestia node.
This documentation outlines the operation of the Saya executable, a CLI-based service designed to interact with blockchain components for state management and updates. Saya supports operations on Celestia nodes and integrates with Katana blocks to provide a streamlined blockchain interaction process.

Example:
## Key Features
- **Celestia Node Integration**: Allows publishing state updates to a Celestia node (WIP).
- **Katana Block Fetching**: Saya can fetch blocks from Katana, aiding in local blockchain simulations and testing.

## Prerequisites
Ensure you have the following set up:
- Rust and Cargo installed on your system.
- Access to Celestia and/or Katana node URLs if needed.

## Basic Usage Example
Below is a command-line example that demonstrates how to run the Saya executable with necessary parameters:

```bash
cargo run --bin saya -- --rpc-url http://localhost:5050 --da-chain celestia --celestia-node-url http://127.0.0.1:26658 --celestia-namespace mynm --celestia-node-auth-token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.....
```

## Detailed Workflow

### 1. Deploy a New World Contract
First, deploy a new smart contract using the Saya framework:
```bash
cargo run -r -p sozo -- build --manifest-path examples/spawn-and-move/Scarb.toml

cargo run -r -p sozo -- migrate apply --manifest-path examples/spawn-and-move/Scarb.toml --rpc-url <> --fee-estimate-multiplier 1000 --private-key <> --account-address <> --name saya-world-v1
```

### 2. Initialize a Local Katana Instance
Start a local instance of Katana configured to work with the newly deployed contract:
```bash
cargo run -r -p katana -- -b 30000 --rpc-url <> --fork-block-number <block number after world deployment>
```

### 3. Launch the Saya Service
Execute the Saya process to interact with the blockchain network:
```bash
cargo run -r --bin saya -- --rpc-url http://localhost:5050 --registry 0x217746a5f74c2e5b6fa92c97e902d8cd78b1fabf1e8081c4aa0d2fe159bc0eb --world <> --start-block <>
```

Currently the Stone prover in use is optimized for AMD64. Hence, running it on a ARM64 machine will be relatively slow or even not compatible if emulation is now available.
If you can't run Saya on a AMD64 machine, you may choose to use the HTTP wrapper currently proposed by Visoft.
```bash
cargo run -r --bin saya -- --rpc-url http://localhost:5050 --prover-url http://prover.visoft.dev:3618/prove/state-diff-commitment --registry 0x217746a5f74c2e5b6fa92c97e902d8cd78b1fabf1e8081c4aa0d2fe159bc0eb --world <> --start-block <>
```

### 4. Modify the World State Using `sozo`
Finally, modify the state of the world using specific actions:
```bash
cargo run --bin saya -- \
--rpc-url http://localhost:5050 \
--da-chain celestia \
--celestia-node-url http://127.0.0.1:26658 \
--celestia-namespace mynm \
--celestia-node-auth-token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.....
cargo run -r -p sozo -- execute --rpc-url http://localhost:5050 --private-key <> --account-address <> --world <> dojo_examples::actions::actions spawn
```

## WIP
After this command, Saya will pick up the blocks with transactions, generate the proof for the state transition, and send it to the base layer world contract.

1. Enhance how options are used for each one of the possible DA.
2. Add a all-in-one toml file to configure the whole Saya service (DA, prover, etc...) to avoid a huge command line.
3. Add subcommands along with saya development for a better experience.
Ensure to replace placeholders (`<>`) with appropriate values for your configuration and environment. This documentation provides a comprehensive overview for developers and operators to effectively utilize the Saya service in blockchain applications.
20 changes: 16 additions & 4 deletions bin/saya/src/args/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ pub struct SayaArgs {
#[arg(default_value = "http://localhost:5050")]
pub rpc_url: Url,

/// Specify the Prover URL.
#[arg(long)]
#[arg(value_name = "PROVER URL")]
#[arg(help = "The Prover URL for remote proving.")]
pub prover_url: Url,

/// Enable JSON logging.
#[arg(long)]
#[arg(help = "Output logs in JSON format.")]
Expand Down Expand Up @@ -55,7 +61,7 @@ pub struct SayaArgs {

impl SayaArgs {
pub fn init_logging(&self) -> Result<(), Box<dyn std::error::Error>> {
const DEFAULT_LOG_FILTER: &str = "info,saya_core=trace,blockchain=trace,provider=trace";
const DEFAULT_LOG_FILTER: &str = "info,saya::core=trace,blockchain=trace,provider=trace";

let builder = fmt::Subscriber::builder().with_env_filter(
EnvFilter::try_from_default_env().or(EnvFilter::try_new(DEFAULT_LOG_FILTER))?,
Expand Down Expand Up @@ -113,10 +119,11 @@ impl TryFrom<SayaArgs> for SayaConfig {

Ok(SayaConfig {
katana_rpc: args.rpc_url,
prover_url: args.prover_url,
start_block: args.start_block,
data_availability: da_config,
prover: args.proof.prover.into(),
verifier: args.proof.verifier.into(),
world_address: args.proof.world_address,
fact_registry_address: args.proof.fact_registry_address,
})
}
}
Expand All @@ -138,6 +145,7 @@ mod tests {
let args = SayaArgs {
config_file: Some(config_file_path.clone()),
rpc_url: Url::parse("http://localhost:5050").unwrap(),
prover_url: Url::parse("http://localhost:5050").unwrap(),
json_log: false,
start_block: 0,
data_availability: DataAvailabilityOptions {
Expand All @@ -148,12 +156,16 @@ mod tests {
celestia_namespace: None,
},
},
proof: ProofOptions { prover: Default::default(), verifier: Default::default() },
proof: ProofOptions {
world_address: Default::default(),
fact_registry_address: Default::default(),
},
};

let config: SayaConfig = args.try_into().unwrap();

assert_eq!(config.katana_rpc.as_str(), "http://localhost:5050/");
assert_eq!(config.prover_url.as_str(), "http://localhost:1234/");
assert_eq!(config.start_block, 0);
if let Some(DataAvailabilityConfig::Celestia(celestia_config)) = config.data_availability {
assert_eq!(celestia_config.node_url.as_str(), "http://localhost:26657/");
Expand Down
138 changes: 8 additions & 130 deletions bin/saya/src/args/proof.rs
Original file line number Diff line number Diff line change
@@ -1,135 +1,13 @@
//! Selecting prover and verifier.
use std::fmt::Display;
use std::str::FromStr;

use anyhow::Result;
use clap::builder::PossibleValue;
use clap::{Args, ValueEnum};
use saya_core::prover::ProverIdentifier;
use saya_core::verifier::VerifierIdentifier;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Prover {
Stone,
}

impl From<Prover> for ProverIdentifier {
fn from(p: Prover) -> Self {
match p {
Prover::Stone => ProverIdentifier::Stone,
}
}
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Verifier {
StoneLocal,
HerodotusStarknetSepolia,
}

impl From<Verifier> for VerifierIdentifier {
fn from(p: Verifier) -> Self {
match p {
Verifier::StoneLocal => VerifierIdentifier::StoneLocal,
Verifier::HerodotusStarknetSepolia => VerifierIdentifier::HerodotusStarknetSepolia,
}
}
}
use clap::Args;
use katana_primitives::FieldElement;

#[derive(Debug, Args, Clone)]
pub struct ProofOptions {
#[arg(long)]
#[arg(help = "Prover to generated the proof from the provable program.")]
pub prover: Prover,

#[arg(long)]
#[arg(help = "Verifier on which the proof should be sent to.")]
pub verifier: Verifier,
}

// -- Prover.
impl Default for Prover {
fn default() -> Self {
Self::Stone
}
}

impl ValueEnum for Prover {
fn value_variants<'a>() -> &'a [Self] {
&[Self::Stone]
}

fn to_possible_value(&self) -> Option<PossibleValue> {
match self {
Self::Stone => Some(PossibleValue::new("stone").alias("Stone")),
}
}
}

impl FromStr for Prover {
type Err = anyhow::Error;

fn from_str(s: &str) -> Result<Self> {
match s {
"stone" | "Stone" => Ok(Self::Stone),
_ => Err(anyhow::anyhow!("unknown prover: {}", s)),
}
}
}

impl Display for Prover {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Prover::Stone => write!(f, "stone"),
}
}
}

// -- Verifier.
impl Default for Verifier {
fn default() -> Self {
Self::StoneLocal
}
}

impl ValueEnum for Verifier {
fn value_variants<'a>() -> &'a [Self] {
&[Self::StoneLocal, Self::HerodotusStarknetSepolia]
}

fn to_possible_value(&self) -> Option<PossibleValue> {
match self {
Self::StoneLocal => {
Some(PossibleValue::new("stone-local").alias("stone_local").alias("StoneLocal"))
}
Self::HerodotusStarknetSepolia => Some(
PossibleValue::new("herodotus_starknet_sepolia")
.alias("herodotus-starknet-sepolia")
.alias("HerodotusStarknetSepolia"),
),
}
}
}

impl FromStr for Verifier {
type Err = anyhow::Error;

fn from_str(s: &str) -> Result<Self> {
match s {
"stone-local" | "stone_local" | "StoneLocal" => Ok(Self::StoneLocal),
"herodotus-starknet-sepolia"
| "herodotus_starknet_sepolia"
| "HerodotusStarknetSepolia" => Ok(Self::HerodotusStarknetSepolia),
_ => Err(anyhow::anyhow!("unknown verifier: {}", s)),
}
}
}
#[arg(help = "The address of the World contract.")]
#[arg(long = "world")]
pub world_address: FieldElement,

impl Display for Verifier {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Verifier::StoneLocal => write!(f, "local-stone"),
Verifier::HerodotusStarknetSepolia => write!(f, "herodotus-starknet-sepolia"),
}
}
#[arg(help = "The address of the Fact Registry contract.")]
#[arg(long = "registry")]
pub fact_registry_address: FieldElement,
}
25 changes: 14 additions & 11 deletions bin/saya/src/args/test_saya_config_file.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
{
"katana_rpc": "http://localhost:5050",
"start_block": 0,
"data_availability": {
"Celestia": {
"node_url": "http://localhost:26657",
"node_auth_token": "your_auth_token",
"namespace": "katana"
}
},
"prover": "Stone",
"verifier": "StoneLocal"
"katana_rpc": "http://localhost:5050",
"prover_url": "http://localhost:1234",
"world_address": "0x332b8ff41b1b026991fa9b7f0ec352909f8bc33416b65a80527edc988a9b082",
"fact_registry_address": "0x217746a5f74c2e5b6fa92c97e902d8cd78b1fabf1e8081c4aa0d2fe159bc0eb",
"start_block": 0,
"data_availability": {
"Celestia": {
"node_url": "http://localhost:26657",
"node_auth_token": "your_auth_token",
"namespace": "katana"
}
},
"prover": "Stone",
"verifier": "StoneLocal"
}
2 changes: 1 addition & 1 deletion crates/dojo-core/src/base_test.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ mod invalid_model {
// Pre-computed address of a contract deployed through the world.
// To print this addres, run:
// sozo test --manifest-path crates/dojo-core/Scarb.toml -f test_deploy_from_world_invalid_model
0x647d90f9663c37478a5fba689fc7166d957f782ea4a8316e0042929d48cf8be
0x7e40f4ebb8008ae9a80d9afde360978bfa4ef5c33bc9689941abc7ae4455573
}
}
}
Expand Down
Loading

0 comments on commit 8f8bdd3

Please sign in to comment.