Skip to content

Commit

Permalink
Merge pull request #2130 from eqlabs/krisztian/versioned-constants-cli
Browse files Browse the repository at this point in the history
feat: add `--rpc.custom-versioned-constants-json-path` CLI option
  • Loading branch information
kkovaacs authored Jul 22, 2024
2 parents f1c7119 + d17888e commit d57cbea
Show file tree
Hide file tree
Showing 23 changed files with 145 additions and 21 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added

- Pathfinder now creates a new directory if the database path specified does not exist.
- Pathfinder now has a CLI option (`--rpc.custom-versioned-constants-json-path`) to allow loading a custom versioned constants JSON file. When specified the contents of the file is then used instead of the _latest_ constants built into the blockifier crate during execution of Cairo code.

### Fixed

Expand Down
2 changes: 1 addition & 1 deletion crates/executor/src/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use super::execution_state::ExecutionState;
use super::felt::{IntoFelt, IntoStarkFelt};

pub fn call(
mut execution_state: ExecutionState<'_>,
execution_state: ExecutionState<'_>,
contract_address: ContractAddress,
entry_point_selector: EntryPoint,
calldata: Vec<CallParam>,
Expand Down
2 changes: 1 addition & 1 deletion crates/executor/src/estimate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use super::execution_state::ExecutionState;
use super::types::FeeEstimate;

pub fn estimate(
mut execution_state: ExecutionState<'_>,
execution_state: ExecutionState<'_>,
transactions: Vec<Transaction>,
skip_validate: bool,
) -> Result<Vec<FeeEstimate>, TransactionExecutionError> {
Expand Down
33 changes: 24 additions & 9 deletions crates/executor/src/execution_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ pub const STRK_FEE_TOKEN_ADDRESS: ContractAddress =
contract_address!("0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d");

mod versioned_constants {
use std::borrow::Cow;

use pathfinder_common::StarknetVersion;

use super::VersionedConstants;
Expand Down Expand Up @@ -57,16 +59,21 @@ mod versioned_constants {
serde_json::from_slice(BLOCKIFIER_VERSIONED_CONSTANTS_JSON_0_13_1_1).unwrap();
}

pub(super) fn for_version(version: &StarknetVersion) -> &'static VersionedConstants {
pub(super) fn for_version(
version: &StarknetVersion,
custom_versioned_constants: Option<VersionedConstants>,
) -> Cow<'static, VersionedConstants> {
// We use 0.13.0 for all blocks _before_ 0.13.1.
if version < &STARKNET_VERSION_0_13_1 {
&BLOCKIFIER_VERSIONED_CONSTANTS_0_13_0
Cow::Borrowed(&BLOCKIFIER_VERSIONED_CONSTANTS_0_13_0)
} else if version < &STARKNET_VERSION_0_13_1_1 {
&BLOCKIFIER_VERSIONED_CONSTANTS_0_13_1
Cow::Borrowed(&BLOCKIFIER_VERSIONED_CONSTANTS_0_13_1)
} else if version < &STARKNET_VERSION_0_13_2 {
&BLOCKIFIER_VERSIONED_CONSTANTS_0_13_1_1
Cow::Borrowed(&BLOCKIFIER_VERSIONED_CONSTANTS_0_13_1_1)
} else {
VersionedConstants::latest_constants()
custom_versioned_constants
.map(Cow::Owned)
.unwrap_or_else(|| Cow::Borrowed(VersionedConstants::latest_constants()))
}
}
}
Expand All @@ -78,13 +85,14 @@ pub struct ExecutionState<'tx> {
execute_on_parent_state: bool,
pending_state: Option<Arc<StateUpdate>>,
allow_use_kzg_data: bool,
custom_versioned_constants: Option<VersionedConstants>,
}

impl<'tx> ExecutionState<'tx> {
pub(super) fn starknet_state(
&mut self,
self,
) -> anyhow::Result<(
CachedState<PendingStateReader<PathfinderStateReader<'_>>>,
CachedState<PendingStateReader<PathfinderStateReader<'tx>>>,
BlockContext,
)> {
let block_number = if self.execute_on_parent_state {
Expand Down Expand Up @@ -126,7 +134,10 @@ impl<'tx> ExecutionState<'tx> {
None
};

let versioned_constants = versioned_constants::for_version(&self.header.starknet_version);
let versioned_constants = versioned_constants::for_version(
&self.header.starknet_version,
self.custom_versioned_constants,
);

pre_process_block(
&mut cached_state,
Expand All @@ -137,7 +148,7 @@ impl<'tx> ExecutionState<'tx> {
let block_context = BlockContext::new(
block_info,
chain_info,
versioned_constants.to_owned(),
versioned_constants.into_owned(),
BouncerConfig::max(),
);

Expand Down Expand Up @@ -230,6 +241,7 @@ impl<'tx> ExecutionState<'tx> {
chain_id: ChainId,
header: BlockHeader,
pending_state: Option<Arc<StateUpdate>>,
custom_versioned_constants: Option<VersionedConstants>,
) -> Self {
Self {
transaction,
Expand All @@ -238,6 +250,7 @@ impl<'tx> ExecutionState<'tx> {
pending_state,
execute_on_parent_state: true,
allow_use_kzg_data: true,
custom_versioned_constants,
}
}

Expand All @@ -247,6 +260,7 @@ impl<'tx> ExecutionState<'tx> {
header: BlockHeader,
pending_state: Option<Arc<StateUpdate>>,
l1_blob_data_availability: L1BlobDataAvailability,
custom_versioned_constants: Option<VersionedConstants>,
) -> Self {
Self {
transaction,
Expand All @@ -255,6 +269,7 @@ impl<'tx> ExecutionState<'tx> {
pending_state,
execute_on_parent_state: false,
allow_use_kzg_data: l1_blob_data_availability == L1BlobDataAvailability::Enabled,
custom_versioned_constants,
}
}
}
Expand Down
1 change: 1 addition & 0 deletions crates/executor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub mod types;
pub use blockifier::execution::contract_class::ClassInfo;
pub use blockifier::transaction::account_transaction::AccountTransaction;
pub use blockifier::transaction::transaction_execution::Transaction;
pub use blockifier::versioned_constants::VersionedConstants;
pub use call::call;
pub use class::{parse_casm_definition, parse_deprecated_class_definition};
pub use error::{CallError, TransactionExecutionError};
Expand Down
4 changes: 2 additions & 2 deletions crates/executor/src/simulate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ impl Default for TraceCache {
}

pub fn simulate(
mut execution_state: ExecutionState<'_>,
execution_state: ExecutionState<'_>,
transactions: Vec<Transaction>,
skip_validate: bool,
skip_fee_charge: bool,
Expand Down Expand Up @@ -140,7 +140,7 @@ pub fn simulate(
}

pub fn trace(
mut execution_state: ExecutionState<'_>,
execution_state: ExecutionState<'_>,
cache: TraceCache,
block_hash: BlockHash,
transactions: Vec<Transaction>,
Expand Down
1 change: 1 addition & 0 deletions crates/pathfinder/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ pathfinder-common = { path = "../common" }
pathfinder-compiler = { path = "../compiler" }
pathfinder-crypto = { path = "../crypto" }
pathfinder-ethereum = { path = "../ethereum" }
pathfinder-executor = { path = "../executor" }
pathfinder-merkle-tree = { path = "../merkle-tree" }
pathfinder-retry = { path = "../retry" }
pathfinder-rpc = { path = "../rpc" }
Expand Down
2 changes: 1 addition & 1 deletion crates/pathfinder/examples/re_execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ fn execute(storage: &mut Storage, chain_id: ChainId, work: Work) {

let db_tx = connection.transaction().expect("Create transaction");

let execution_state = ExecutionState::trace(&db_tx, chain_id, work.header.clone(), None);
let execution_state = ExecutionState::trace(&db_tx, chain_id, work.header.clone(), None, None);

let transactions = work
.transactions
Expand Down
3 changes: 3 additions & 0 deletions crates/pathfinder/resources/invalid_versioned_constants.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"invalid": "contents"
}
71 changes: 70 additions & 1 deletion crates/pathfinder/src/bin/pathfinder/config.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::collections::HashSet;
use std::fs::File;
use std::net::SocketAddr;
use std::num::NonZeroUsize;
use std::path::PathBuf;
Expand All @@ -11,6 +12,7 @@ use ipnet::IpNet;
use p2p::libp2p::Multiaddr;
use pathfinder_common::consts::VERGEN_GIT_DESCRIBE;
use pathfinder_common::AllowedOrigins;
use pathfinder_executor::VersionedConstants;
use pathfinder_storage::JournalMode;
use reqwest::Url;

Expand Down Expand Up @@ -256,6 +258,13 @@ This should only be enabled for debugging purposes as it adds substantial proces
value_parser = parse_state_tries
)]
state_tries: Option<StateTries>,

#[arg(
long = "rpc.custom-versioned-constants-json-path",
long_help = "Path to a JSON file containing the versioned constants to use for execution",
env = "PATHFINDER_RPC_CUSTOM_VERSIONED_CONSTANTS_JSON_PATH"
)]
custom_versioned_constants_path: Option<PathBuf>,
}

#[derive(clap::ValueEnum, Debug, Clone, Copy, PartialEq)]
Expand Down Expand Up @@ -618,6 +627,35 @@ enum RpcCorsDomainsParseError {
WildcardAmongOtherValues,
}

fn parse_versioned_constants(
path: PathBuf,
) -> Result<VersionedConstants, ParseVersionedConstantsError> {
let file = File::open(path)?;
let reader = std::io::BufReader::new(file);
let versioned_constants = serde_json::from_reader(reader)?;

Ok(versioned_constants)
}

pub fn parse_versioned_constants_or_exit(path: PathBuf) -> VersionedConstants {
use clap::error::ErrorKind;

match parse_versioned_constants(path) {
Ok(versioned_constants) => versioned_constants,
Err(error) => Cli::command()
.error(ErrorKind::ValueValidation, error)
.exit(),
}
}

#[derive(Debug, thiserror::Error)]
enum ParseVersionedConstantsError {
#[error("IO error while reading versioned constants: {0}.")]
Io(#[from] std::io::Error),
#[error("Parse error while loading versioned constants: {0}.")]
Parse(#[from] serde_json::Error),
}

pub struct Config {
pub data_directory: PathBuf,
pub ethereum: Ethereum,
Expand All @@ -644,6 +682,7 @@ pub struct Config {
pub get_events_max_blocks_to_scan: NonZeroUsize,
pub get_events_max_uncached_bloom_filters_to_load: NonZeroUsize,
pub state_tries: Option<StateTries>,
pub custom_versioned_constants: Option<VersionedConstants>,
}

pub struct Ethereum {
Expand Down Expand Up @@ -928,6 +967,9 @@ impl Config {
.get_events_max_uncached_bloom_filters_to_load,
gateway_timeout: Duration::from_secs(cli.gateway_timeout.get()),
state_tries: cli.state_tries,
custom_versioned_constants: cli
.custom_versioned_constants_path
.map(parse_versioned_constants_or_exit),
}
}
}
Expand Down Expand Up @@ -966,8 +1008,10 @@ pub struct WebsocketConfig {

#[cfg(test)]
mod tests {
use assert_matches::assert_matches;

use super::{AllowedOrigins, RpcCorsDomainsParseError};
use crate::config::parse_cors;
use crate::config::{parse_cors, ParseVersionedConstantsError};

#[test]
fn parse_cors_domains() {
Expand Down Expand Up @@ -1043,4 +1087,29 @@ mod tests {
)
});
}

#[test]
fn parse_versioned_constants_fails_if_file_not_found() {
assert_matches!(
super::parse_versioned_constants("./nonexistent_versioned_constants.json".into()).unwrap_err(),
ParseVersionedConstantsError::Io(err) => assert_eq!(err.kind(), std::io::ErrorKind::NotFound)
);
}

#[test]
fn parse_versioned_constants_fails_on_parse_error() {
assert_matches!(
super::parse_versioned_constants("resources/invalid_versioned_constants.json".into())
.unwrap_err(),
ParseVersionedConstantsError::Parse(_)
)
}

#[test]
fn parse_versioned_constants_success() {
super::parse_versioned_constants(
"../executor/resources/versioned_constants_13_1_1.json".into(),
)
.unwrap();
}
}
3 changes: 2 additions & 1 deletion crates/pathfinder/src/bin/pathfinder/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ async fn async_main() -> anyhow::Result<()> {
std::env::set_var("RUST_LOG", "pathfinder=info");
}

let config = config::Config::parse();
let mut config = config::Config::parse();

setup_tracing(config.color, config.debug.pretty_log);

Expand Down Expand Up @@ -209,6 +209,7 @@ Hint: This is usually caused by exceeding the file descriptor limit of your syst
get_events_max_blocks_to_scan: config.get_events_max_blocks_to_scan,
get_events_max_uncached_bloom_filters_to_load: config
.get_events_max_uncached_bloom_filters_to_load,
custom_versioned_constants: config.custom_versioned_constants.take(),
};

let context = pathfinder_rpc::context::RpcContext::new(
Expand Down
4 changes: 3 additions & 1 deletion crates/rpc/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::num::NonZeroUsize;
use std::sync::Arc;

use pathfinder_common::ChainId;
use pathfinder_executor::TraceCache;
use pathfinder_executor::{TraceCache, VersionedConstants};
use pathfinder_storage::Storage;

pub use crate::jsonrpc::websocket::WebsocketContext;
Expand All @@ -17,6 +17,7 @@ pub struct RpcConfig {
pub batch_concurrency_limit: NonZeroUsize,
pub get_events_max_blocks_to_scan: NonZeroUsize,
pub get_events_max_uncached_bloom_filters_to_load: NonZeroUsize,
pub custom_versioned_constants: Option<VersionedConstants>,
}

#[derive(Clone)]
Expand Down Expand Up @@ -100,6 +101,7 @@ impl RpcContext {
batch_concurrency_limit: NonZeroUsize::new(8).unwrap(),
get_events_max_blocks_to_scan: NonZeroUsize::new(1000).unwrap(),
get_events_max_uncached_bloom_filters_to_load: NonZeroUsize::new(1000).unwrap(),
custom_versioned_constants: None,
};

Self::new(
Expand Down
1 change: 1 addition & 0 deletions crates/rpc/src/v04/method/simulate_transactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ pub async fn simulate_transactions(
header,
pending,
pathfinder_executor::L1BlobDataAvailability::Disabled,
context.config.custom_versioned_constants,
);

let transactions = input
Expand Down
1 change: 1 addition & 0 deletions crates/rpc/src/v05/method/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ pub async fn call(context: RpcContext, input: CallInput) -> Result<CallOutput, C
header,
pending,
L1BlobDataAvailability::Disabled,
context.config.custom_versioned_constants,
);

let result = pathfinder_executor::call(
Expand Down
1 change: 1 addition & 0 deletions crates/rpc/src/v05/method/estimate_fee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ pub async fn estimate_fee(
header,
pending,
L1BlobDataAvailability::Disabled,
context.config.custom_versioned_constants,
);

let transactions = input
Expand Down
1 change: 1 addition & 0 deletions crates/rpc/src/v05/method/simulate_transactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ pub async fn simulate_transactions(
header,
pending,
L1BlobDataAvailability::Disabled,
context.config.custom_versioned_constants,
);

let transactions = input
Expand Down
8 changes: 7 additions & 1 deletion crates/rpc/src/v05/method/trace_block_transactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,13 @@ pub async fn trace_block_transactions(
.collect::<Result<Vec<_>, _>>()?;

let hash = header.hash;
let state = ExecutionState::trace(&db, context.chain_id, header, None);
let state = ExecutionState::trace(
&db,
context.chain_id,
header,
None,
context.config.custom_versioned_constants,
);
let traces =
match pathfinder_executor::trace(state, cache, hash, executor_transactions, true, true)
{
Expand Down
Loading

0 comments on commit d57cbea

Please sign in to comment.