Skip to content
This repository has been archived by the owner on Jun 20, 2024. It is now read-only.

feat: improve block hashes fetching #62

Closed
wants to merge 16 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,19 +205,20 @@ cargo r --release --bin leader jerigon --help

Reads input from a Jerigon node and writes output to stdout

Usage: leader jerigon [OPTIONS] --rpc-url <RPC_URL> --block-number <BLOCK_NUMBER>
Usage: leader jerigon [OPTIONS] --rpc-url <RPC_URL> --block-numbers <BLOCK_NUMBERS>

Options:
-u, --rpc-url <RPC_URL>

-b, --block-number <BLOCK_NUMBER>
The block number for which to generate a proof
-b, --block-numbers <BLOCK_NUMBERS>
The block number or a block numbers range for which to generate a proof. If range is provided
it should be inclusive i.e. `{from_block_number}..={to_block_number}`
-c, --checkpoint-block-number <CHECKPOINT_BLOCK_NUMBER>
The checkpoint block number [default: 0]
-f, --previous-proof <PREVIOUS_PROOF>
The previous proof output
-o, --proof-output-path <PROOF_OUTPUT_PATH>
If provided, write the generated proof to this file instead of stdout
-o, --proof-output-dir <PROOF_OUTPUT_DIR>
If provided, write the generated proofs to this directory instead of stdout
-h, --help
Print help
-s, --save-inputs-on-error
Expand Down Expand Up @@ -343,7 +344,7 @@ Options:
Example:

```bash
cargo r --release --bin rpc fetch --rpc-url <RPC_URL> --block-number 16 > ./output/block-16.json
cargo r --release --bin rpc fetch --rpc-url <RPC_URL> --block-numbers 16 > ./output/block-16.json
```

## Docker
Expand Down
70 changes: 66 additions & 4 deletions leader/src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
use std::path::PathBuf;
use std::{
ops::RangeInclusive,
str::{FromStr, Split},
};

use anyhow::{anyhow, Context, Result};
use clap::{Parser, Subcommand, ValueHint};
use common::prover_state::cli::CliProverStateConfig;

Expand All @@ -18,6 +23,63 @@ pub(crate) struct Cli {
pub(crate) prover_state_config: CliProverStateConfig,
}

#[derive(Clone, Debug)]
pub(super) enum BlockNumbers {
Single(u64),
RangeInclusive(RangeInclusive<u64>),
}

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

/// Parses input block numbers to determine a specific block or a range of
/// blocks.
fn from_str(s: &str) -> Result<Self, Self::Err> {
Self::from_str_intern(s)
.with_context(|| {
format!(
"Expected a single value or a range, but instead got \"{}\".",
s
)
})
.map_err(|e| anyhow!("{e:#}"))
}
}

impl BlockNumbers {
fn from_str_intern(s: &str) -> anyhow::Result<Self> {
// Did we get passed a single value?
if let Ok(v) = s.parse::<u64>() {
return Ok(Self::Single(v));
}

// Check if it's a range.
let mut range_vals = s.split("..=");
vladimir-trifonov marked this conversation as resolved.
Show resolved Hide resolved

let start = Self::next_and_try_parse(&mut range_vals)?;
let end = Self::next_and_try_parse(&mut range_vals)?;

if range_vals.count() > 0 {
return Err(anyhow!(
"Parsed a range but there were unexpected characters afterwards!"
));
}

Ok(Self::RangeInclusive(start..=end))
}

fn next_and_try_parse(range_vals: &mut Split<&str>) -> anyhow::Result<u64> {
let unparsed_val = range_vals
.next()
.with_context(|| "Parsing a value as a `RangeInclusive`")?;
let res = unparsed_val
.parse()
.with_context(|| format!("Parsing the range val \"{}\" into a usize", unparsed_val))?;

Ok(res)
}
}

#[derive(Subcommand)]
pub(crate) enum Command {
/// Reads input from stdin and writes output to stdout.
Expand All @@ -34,9 +96,9 @@ pub(crate) enum Command {
// The Jerigon RPC URL.
#[arg(long, short = 'u', value_hint = ValueHint::Url)]
rpc_url: String,
/// The block number for which to generate a proof.
/// The block numbers for which to generate a proof.
#[arg(short, long)]
block_number: u64,
block_numbers: BlockNumbers,
/// The checkpoint block number.
#[arg(short, long, default_value_t = 0)]
checkpoint_block_number: u64,
Expand All @@ -45,8 +107,8 @@ pub(crate) enum Command {
previous_proof: Option<PathBuf>,
/// If provided, write the generated proof to this file instead of
/// stdout.
#[arg(long, short = 'o', value_hint = ValueHint::FilePath)]
proof_output_path: Option<PathBuf>,
#[arg(long, short = 'o', value_hint = ValueHint::DirPath)]
proof_output_dir: Option<PathBuf>,
/// If true, save the public inputs to disk on error.
#[arg(short, long, default_value_t = false)]
save_inputs_on_error: bool,
Expand Down
66 changes: 61 additions & 5 deletions leader/src/jerigon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,89 @@ use std::{
};

use anyhow::Result;
use ethereum_types::H256;
use paladin::runtime::Runtime;
use proof_gen::types::PlonkyProofIntern;

use crate::cli::BlockNumbers;

/// The main function for the jerigon mode.
pub(crate) async fn jerigon_main(
runtime: Runtime,
rpc_url: &str,
block_number: u64,
block_numbers: BlockNumbers,
checkpoint_block_number: u64,
previous: Option<PlonkyProofIntern>,
proof_output_path_opt: Option<PathBuf>,
proof_output_dir_opt: Option<PathBuf>,
save_inputs_on_error: bool,
) -> Result<()> {
let mut previous = previous;

let block_range = match block_numbers {
BlockNumbers::Single(block_number) => block_number..=block_number,
BlockNumbers::RangeInclusive(block_range) => block_range,
};

let mut prev_hashes = rpc::fetch_previous_block_hashes(rpc_url, *block_range.start()).await?;

for block_number in block_range {
let (curr_hash, curr_proof) = process_block(
&runtime,
rpc_url,
block_number,
checkpoint_block_number,
previous,
&prev_hashes,
&proof_output_dir_opt,
save_inputs_on_error,
)
.await?;

previous = curr_proof;
prev_hashes.remove(0);
prev_hashes.push(curr_hash);
}

runtime.close().await?;

Ok(())
}

#[allow(clippy::too_many_arguments)]
async fn process_block(
runtime: &Runtime,
rpc_url: &str,
block_number: u64,
checkpoint_block_number: u64,
previous: Option<PlonkyProofIntern>,
prev_hashes: &Vec<H256>,
proof_output_dir_opt: &Option<PathBuf>,
save_inputs_on_error: bool,
) -> Result<(H256, Option<PlonkyProofIntern>)> {
let prover_input = rpc::fetch_prover_input(rpc::FetchProverInputRequest {
rpc_url,
block_number,
checkpoint_block_number,
prev_hashes,
})
.await?;

let curr_hash = prover_input.other_data.b_data.b_hashes.cur_hash;
let proof = prover_input
.prove(&runtime, previous, save_inputs_on_error)
.prove(runtime, previous, save_inputs_on_error)
.await;
runtime.close().await?;

let proof = serde_json::to_vec(&proof?.intern)?;
write_proof(proof, proof_output_path_opt)
let proof_intern = proof?.intern;
let proof_json = serde_json::to_vec(&proof_intern)?;
write_proof(
proof_json,
proof_output_dir_opt
.as_ref()
.map(|p| p.join(format!("b{}.zkproof", block_number))),
)?;

Ok((curr_hash, Some(proof_intern)))
}

fn write_proof(proof: Vec<u8>, proof_output_path_opt: Option<PathBuf>) -> Result<()> {
Expand Down
8 changes: 4 additions & 4 deletions leader/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,21 +89,21 @@ async fn main() -> Result<()> {
}
Command::Jerigon {
rpc_url,
block_number,
block_numbers,
checkpoint_block_number,
previous_proof,
proof_output_path,
proof_output_dir,
save_inputs_on_error,
} => {
let previous_proof = get_previous_proof(previous_proof)?;

jerigon::jerigon_main(
runtime,
&rpc_url,
block_number,
block_numbers,
checkpoint_block_number,
previous_proof,
proof_output_path,
proof_output_dir,
save_inputs_on_error,
)
.await?;
Expand Down
2 changes: 1 addition & 1 deletion rpc/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
mod rpc;
pub use rpc::{fetch_prover_input, FetchProverInputRequest};
pub use rpc::{fetch_previous_block_hashes, fetch_prover_input, FetchProverInputRequest};
5 changes: 4 additions & 1 deletion rpc/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::io::Write;
use anyhow::Result;
use clap::Parser;
use cli::Commands;
use rpc::{fetch_prover_input, FetchProverInputRequest};
use rpc::{fetch_previous_block_hashes, fetch_prover_input, FetchProverInputRequest};

mod cli;
mod init;
Expand All @@ -20,10 +20,13 @@ async fn main() -> Result<()> {
block_number,
checkpoint_block_number,
} => {
let prev_hashes = fetch_previous_block_hashes(&rpc_url, block_number).await?;

let prover_input = fetch_prover_input(FetchProverInputRequest {
rpc_url: &rpc_url,
block_number,
checkpoint_block_number,
prev_hashes: &prev_hashes,
})
.await?;
std::io::stdout().write_all(&serde_json::to_vec(&prover_input)?)?;
Expand Down
23 changes: 15 additions & 8 deletions rpc/src/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ impl EthGetBlockByNumberResponse {
Ok(parsed)
}

async fn fetch_previous_block_hashes<U: IntoUrl + Copy>(
pub async fn fetch_previous_block_hashes<U: IntoUrl + Copy>(
rpc_url: U,
block_number: u64,
) -> Result<Vec<H256>> {
Expand Down Expand Up @@ -244,16 +244,15 @@ impl EthChainIdResponse {
struct RpcBlockMetadata {
block_by_number: EthGetBlockByNumberResponse,
chain_id: EthChainIdResponse,
prev_hashes: Vec<H256>,
prev_hashes: Option<Vec<H256>>,
checkpoint_state_trie_root: H256,
}

impl RpcBlockMetadata {
async fn fetch(rpc_url: &str, block_number: u64, checkpoint_block_number: u64) -> Result<Self> {
let (block_result, chain_id_result, prev_hashes, checkpoint_state_trie_root) = try_join!(
let (block_result, chain_id_result, checkpoint_state_trie_root) = try_join!(
EthGetBlockByNumberResponse::fetch(rpc_url, block_number),
EthChainIdResponse::fetch(rpc_url),
EthGetBlockByNumberResponse::fetch_previous_block_hashes(rpc_url, block_number),
EthGetBlockByNumberResponse::fetch_checkpoint_state_trie_root(
rpc_url,
checkpoint_block_number
Expand All @@ -263,7 +262,7 @@ impl RpcBlockMetadata {
Ok(Self {
block_by_number: block_result,
chain_id: chain_id_result,
prev_hashes,
prev_hashes: None,
checkpoint_state_trie_root,
})
}
Expand Down Expand Up @@ -313,7 +312,7 @@ impl From<RpcBlockMetadata> for OtherBlockData {
b_data: BlockLevelData {
b_meta: block_metadata,
b_hashes: BlockHashes {
prev_hashes,
prev_hashes: prev_hashes.unwrap_or_default(),
cur_hash: block_by_number.result.hash,
},
withdrawals,
Expand All @@ -327,20 +326,24 @@ pub struct FetchProverInputRequest<'a> {
pub rpc_url: &'a str,
pub block_number: u64,
pub checkpoint_block_number: u64,
pub prev_hashes: &'a Vec<H256>,
}

pub async fn fetch_prover_input(
FetchProverInputRequest {
rpc_url,
block_number,
checkpoint_block_number,
prev_hashes,
}: FetchProverInputRequest<'_>,
) -> Result<ProverInput> {
let (trace_result, rpc_block_metadata) = try_join!(
let (trace_result, mut rpc_block_metadata) = try_join!(
JerigonTraceResponse::fetch(rpc_url, block_number),
RpcBlockMetadata::fetch(rpc_url, block_number, checkpoint_block_number),
RpcBlockMetadata::fetch(rpc_url, block_number, checkpoint_block_number,),
)?;

rpc_block_metadata.prev_hashes = Some(prev_hashes.clone());

debug!("Got block result: {:?}", rpc_block_metadata.block_by_number);
debug!("Got trace result: {:?}", trace_result);
debug!("Got chain_id: {:?}", rpc_block_metadata.chain_id);
Expand All @@ -350,3 +353,7 @@ pub async fn fetch_prover_input(
other_data: rpc_block_metadata.into(),
})
}

pub async fn fetch_previous_block_hashes(rpc_url: &str, block_number: u64) -> Result<Vec<H256>> {
EthGetBlockByNumberResponse::fetch_previous_block_hashes(rpc_url, block_number).await
}
5 changes: 2 additions & 3 deletions tools/debug_block.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ OUT_LOG_PATH="${OUTPUT_DIR}/b${1}.log"
echo "Testing block ${1}..."
mkdir -p $OUTPUT_DIR

cargo r --release --features test_only --bin leader -- -n 1 --runtime in-memory jerigon --rpc-url "$2" --block-number "$1" --checkpoint-block-number "$(($1-1))" --proof-output-path $OUT_DUMMY_PROOF_PATH > $OUT_LOG_PATH 2>&1
cargo r --release --features test_only --bin leader -- -n 1 --runtime in-memory jerigon --rpc-url "$2" --block-numbers "$1" --checkpoint-block-number "$(($1-1))" --proof-output-dir $OUTPUT_DIR > $OUT_LOG_PATH 2>&1
retVal=$?
if [ $retVal -ne 0 ]; then
# Some error occured.
Expand All @@ -35,5 +35,4 @@ else
# Remove the log / dummy proof on success.
rm $OUT_DUMMY_PROOF_PATH
rm $OUT_LOG_PATH
fi

fi
Loading
Loading