Skip to content
Merged
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
3 changes: 2 additions & 1 deletion crates/apollo_gateway/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,8 @@ fn convert_sn_api_error(err: StarknetApiError) -> StarknetError {
| StarknetApiError::BlockHashVersion { .. }
| StarknetApiError::ParseSierraVersionError(..)
| StarknetApiError::ResourceHexToFeltConversion(..)
| StarknetApiError::OutOfRange { .. } => StarknetError {
| StarknetApiError::OutOfRange { .. }
| StarknetApiError::InvalidChainIdHex(..) => StarknetError {
code: StarknetErrorCode::KnownErrorCode(KnownStarknetErrorCode::MalformedRequest),
message: err.to_string(),
},
Expand Down
23 changes: 23 additions & 0 deletions crates/blockifier_reexecution/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,29 @@ The blockier reexecution crate is intended to verify blockifier changes do not b
## CLI Commands
Using the different CLI commands, it is possible to run reexecution tests in different modes, to download (permisionless) files for offline reexecution from the GC bucket, and to upload (permissioned) files for offline reexecution to the GC bucket.

### Chain ID Option
Commands that use RPC (`rpc-test`, `reexecute-single-tx`, `write-to-file`) accept optional chain ID arguments. If not provided, the chain ID is guessed from the node URL.

There are two mutually exclusive options for specifying the chain ID:

**Option 1: `-c/--chain-id` (enum)**
For standard chain IDs, use the `-c` flag with one of the supported values:
- `mainnet` - Starknet Mainnet (SN_MAIN)
- `testnet` - Sepolia testnet (SN_SEPOLIA)
- `integration` - Integration Sepolia (SN_INTEGRATION_SEPOLIA)

```
cargo run --bin blockifier_reexecution rpc-test -n <node_url> -b <block_number> -c mainnet
```

**Option 2: `--custom-chain-id` (hex string)**
For custom/private networks, use the `--custom-chain-id` flag with a hex-encoded chain ID string:
```
cargo run --bin blockifier_reexecution rpc-test -n <node_url> -b <block_number> --custom-chain-id 0x505249564154455f534e
```
Note: The hex string is the ASCII encoding of the chain ID name. For example, `0x534e5f4d41494e` decodes to `SN_MAIN`.


### Reexecution Modes

Reexecution can be run via CLI in the following modes:
Expand Down
22 changes: 17 additions & 5 deletions crates/blockifier_reexecution/src/state_reader/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::fs::read_to_string;

use clap::{Args, Parser, Subcommand};
use starknet_api::block::BlockNumber;
use starknet_api::core::ChainId;
use starknet_api::core::{chain_id_from_hex_str, ChainId};

use crate::state_reader::errors::{ReexecutionError, ReexecutionResult};

Expand Down Expand Up @@ -38,22 +38,34 @@ impl From<SupportedChainId> for ChainId {
}

#[derive(Clone, Debug, Args)]
#[clap(group(
clap::ArgGroup::new("chain_id_group")
.args(&["chain_id", "custom_chain_id"])
))]
pub struct RpcArgs {
/// Node url.
#[clap(long, short = 'n')]
pub node_url: String,

/// Optional chain ID (if not provided, it will be guessed from the node url).
/// Supported values: mainnet, testnet, integration.
#[clap(long, short = 'c')]
pub chain_id: Option<SupportedChainId>,

/// Optional custom chain ID as hex string (e.g., "0x534e5f4d41494e").
#[clap(long)]
pub custom_chain_id: Option<String>,
}

impl RpcArgs {
pub fn parse_chain_id(&self) -> ChainId {
self.chain_id
.clone()
.map(ChainId::from)
.unwrap_or(guess_chain_id_from_node_url(self.node_url.as_str()).unwrap())
if let Some(chain_id) = &self.chain_id {
return chain_id.clone().into();
}
if let Some(hex_str) = &self.custom_chain_id {
return chain_id_from_hex_str(hex_str).expect("Failed to parse hex chain id");
}
guess_chain_id_from_node_url(self.node_url.as_str()).unwrap()
}
}

Expand Down
27 changes: 19 additions & 8 deletions crates/starknet_api/src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use crate::crypto::utils::PublicKey;
use crate::hash::{PoseidonHash, StarkHash};
use crate::serde_utils::{BytesAsHex, PrefixedBytesAsHex};
use crate::transaction::fields::{Calldata, ContractAddressSalt};
use crate::{impl_from_through_intermediate, StarknetApiError};
use crate::{impl_from_through_intermediate, StarknetApiError, StarknetApiResult};

/// Felt.
pub fn ascii_as_felt(ascii_str: &str) -> Result<Felt, StarknetApiError> {
Expand Down Expand Up @@ -87,20 +87,31 @@ impl ChainId {
}
}

pub fn deserialize_chain_id_from_hex<'de, D>(deserializer: D) -> Result<ChainId, D::Error>
where
D: Deserializer<'de>,
{
let hex_str = String::deserialize(deserializer)?;
/// Parses a hex string (e.g., "0x534e5f4d41494e") into a ChainId.
pub fn chain_id_from_hex_str(hex_str: &str) -> StarknetApiResult<ChainId> {
let chain_id_str =
std::str::from_utf8(&hex::decode(hex_str.trim_start_matches("0x")).map_err(|e| {
D::Error::custom(format!("Failed to decode the hex string {hex_str}. Error: {e:?}"))
StarknetApiError::InvalidChainIdHex(format!(
"Failed to decode the hex string {hex_str}. Error: {e:?}"
))
})?)
.map_err(|e| D::Error::custom(format!("Failed to convert to UTF-8 string. Error: {e:?}")))?
.map_err(|e| {
StarknetApiError::InvalidChainIdHex(format!(
"Failed to convert to UTF-8 string. Error: {e}"
))
})?
.to_string();
Ok(ChainId::from(chain_id_str))
}

pub fn deserialize_chain_id_from_hex<'de, D>(deserializer: D) -> Result<ChainId, D::Error>
where
D: Deserializer<'de>,
{
let hex_str = String::deserialize(deserializer)?;
chain_id_from_hex_str(&hex_str).map_err(D::Error::custom)
}

/// The address of a contract, used for example in [StateDiff](`crate::state::StateDiff`),
/// [DeclareTransaction](`crate::transaction::DeclareTransaction`), and
/// [BlockHeader](`crate::block::BlockHeader`).
Expand Down
2 changes: 2 additions & 0 deletions crates/starknet_api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ pub enum StarknetApiError {
version {cairo_version:?}.", **declare_version
)]
ContractClassVersionMismatch { declare_version: TransactionVersion, cairo_version: u64 },
#[error("Failed to parse chain ID from hex: {0}")]
InvalidChainIdHex(String),
#[error("Failed to parse Sierra version: {0}")]
ParseSierraVersionError(String),
#[error("Unsupported transaction type: {0}")]
Expand Down
Loading