Skip to content

Commit

Permalink
build: blockifier regression test serde rpc tx to starknet api tx (#1021
Browse files Browse the repository at this point in the history
)

<!-- Reviewable:start -->
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/starkware-libs/sequencer/1021)
<!-- Reviewable:end -->
  • Loading branch information
AvivYossef-starkware authored Oct 1, 2024
1 parent 8ebda40 commit 32dc924
Show file tree
Hide file tree
Showing 5 changed files with 200 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
{
"invoke_v1": {
"calldata": [
"0x1",
"0x422d33a3638dcc4c62e72e1d6942cd31eb643ef596ccac2351e0e21f6cd4bf4",
"0xcaffbd1bd76bd7f24a3fa1d69d1b2588a86d1f9d2359b13f6a84b7e1cbd126",
"0x5",
"0x5265736f6c766552616e646f6d4576656e74",
"0x3",
"0x0",
"0x1",
"0x10c3"
],
"max_fee": "0x65f2d0057b2",
"nonce": "0x4d8",
"sender_address": "0x4e6989d518d5eb7e516dc5673f855fe7c5cfece1880a1047d6a8e8465be0d69",
"signature": [
"0x59b7462ea9566750ab7d7d08acbb6d339bfda921b053f1f8a5fd6b96c3656f9",
"0x2f11c36d10a03f21be918a5feeeb9922c11a2713fecd51f5e6bac5167856ecb"
],
"transaction_hash": "0x47165a9a9c97e8829a4778f2a4b6fae4366aefc35b51d484bf04c458168351b",
"type": "INVOKE",
"version": "0x1"
},
"invoke_v3": {
"account_deployment_data": [],
"calldata": [
"0x2",
"0x4878d1148318a31829523ee9c6a5ee563af6cd87f90a30809e5b0d27db8a9b",
"0xa72371689866be053cc37a071de4216af73c9ffff96319b2576f7bf1e15290",
"0x4",
"0x2cb8f1439c83d9856179cbeae626e676bbb9b68e0bdda5423aa1988018acebe",
"0xba43b7400",
"0x2750a0009",
"0x422d33a3638dcc4c62e72e1d6942cd31eb643ef596ccac2351e0e21f6cd4bf4",
"0x422d33a3638dcc4c62e72e1d6942cd31eb643ef596ccac2351e0e21f6cd4bf4",
"0xcaffbd1bd76bd7f24a3fa1d69d1b2588a86d1f9d2359b13f6a84b7e1cbd126",
"0x6",
"0x41636365707444656c6976657279",
"0x4",
"0x9",
"0x2750a",
"0x1",
"0xcf"
],
"fee_data_availability_mode": "L1",
"nonce": "0x1412",
"nonce_data_availability_mode": "L1",
"paymaster_data": [],
"resource_bounds": {
"l1_gas": {
"max_amount": "0x368",
"max_price_per_unit": "0x13bca990eeea"
},
"l2_gas": {
"max_amount": "0x0",
"max_price_per_unit": "0x0"
}
},
"sender_address": "0x614872dd2f3324f3e9a047d0cfaab9e9573bbdfa6081877f49f7108116b8ae0",
"signature": [
"0x1",
"0x0",
"0x61050eb8efaa6db97248c8c987c1a9df82527c26c204681396108cbd5babaf8",
"0x358bc995a221c3aa96cf2a1e6b5b8959b6d626b6fe89381d627f378dc39402a",
"0xf247079c5e0c5be56f4c0f37452304dc63b4b883b89d5a66e3202a855515ef"
],
"tip": "0x0",
"transaction_hash": "0xa7c7db686c7f756ceb7ca85a759caef879d425d156da83d6a836f86851983",
"type": "INVOKE",
"version": "0x3"
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
use assert_matches::assert_matches;
use blockifier::blockifier::block::BlockInfo;
use pretty_assertions::assert_eq;
use rstest::{fixture, rstest};
use starknet_api::block::BlockNumber;
use starknet_api::test_utils::read_json_file;
use starknet_api::transaction::{InvokeTransaction, Transaction};
use starknet_core::types::ContractClass;
use starknet_gateway::rpc_objects::BlockHeader;

use crate::state_reader::compile::legacy_to_contract_class_v0;
use crate::state_reader::utils::deserialize_transaction_json_to_starknet_api_tx;

#[fixture]
fn block_header() -> BlockHeader {
Expand Down Expand Up @@ -45,3 +48,20 @@ fn test_compile_deprecated_contract_class(deprecated_contract_class: ContractCla
_ => panic!("Expected a legacy contract class"),
}
}

#[test]
fn deserialize_invoke_txs() {
let invoke_tx_v1 = deserialize_transaction_json_to_starknet_api_tx(
read_json_file("raw_rpc_json_objects/transactions.json")["invoke_v1"].clone(),
)
.expect("Failed to deserialize invoke v1 tx");

assert_matches!(invoke_tx_v1, Transaction::Invoke(InvokeTransaction::V1(..)));

let invoke_tx_v3 = deserialize_transaction_json_to_starknet_api_tx(
read_json_file("raw_rpc_json_objects/transactions.json")["invoke_v3"].clone(),
)
.expect("Failed to deserialize invoke v3 tx");

assert_matches!(invoke_tx_v3, Transaction::Invoke(InvokeTransaction::V3(..)));
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,24 @@ use rstest::{fixture, rstest};
use starknet_api::block::BlockNumber;
use starknet_api::core::ClassHash;
use starknet_api::test_utils::read_json_file;
use starknet_api::transaction::Transaction;
use starknet_api::{class_hash, felt};
use starknet_core::types::ContractClass::{Legacy, Sierra};

use crate::state_reader::compile::legacy_to_contract_class_v0;
use crate::state_reader::test_state_reader::TestStateReader;

const EXAMPLE_INVOKE_TX_HASH: &str =
"0xa7c7db686c7f756ceb7ca85a759caef879d425d156da83d6a836f86851983";

const EXAMPLE_BLOCK_NUMBER: u64 = 700000;

const EXAMPLE_CONTACT_CLASS_HASH: &str =
"0x3131fa018d520a037686ce3efddeab8f28895662f019ca3ca18a626650f7d1e";

#[fixture]
pub fn test_block_number() -> BlockNumber {
BlockNumber(700000)
BlockNumber(EXAMPLE_BLOCK_NUMBER)
}

#[fixture]
Expand All @@ -38,8 +47,7 @@ pub fn test_get_starknet_version(test_state_reader: TestStateReader) {
#[rstest]
pub fn test_get_contract_class(test_state_reader: TestStateReader, test_block_number: BlockNumber) {
// An example of existing class hash in Mainnet.
let class_hash =
class_hash!("0x3131fa018d520a037686ce3efddeab8f28895662f019ca3ca18a626650f7d1e");
let class_hash = class_hash!(EXAMPLE_CONTACT_CLASS_HASH);

// Test getting the contract class using RPC request.
let deprecated_contract_class =
Expand Down Expand Up @@ -74,3 +82,9 @@ pub fn test_get_tx_hashes(test_state_reader: TestStateReader, test_block_number:
});
assert_eq!(actual_tx_hashes, expected_tx_hashes);
}

#[rstest]
pub fn test_get_tx_by_hash(test_state_reader: TestStateReader) {
let actual_tx = test_state_reader.get_tx_by_hash(EXAMPLE_INVOKE_TX_HASH).unwrap();
assert_matches!(actual_tx, Transaction::Invoke(..));
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use serde_json::{json, to_value};
use starknet_api::block::{BlockNumber, GasPrice};
use starknet_api::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce};
use starknet_api::state::StorageKey;
use starknet_api::transaction::Transaction;
use starknet_core::types::ContractClass as StarknetContractClass;
use starknet_core::types::ContractClass::{Legacy, Sierra};
use starknet_gateway::config::RpcStateReaderConfig;
Expand All @@ -21,7 +22,11 @@ use starknet_gateway::rpc_state_reader::RpcStateReader;
use starknet_types_core::felt::Felt;

use crate::state_reader::compile::{legacy_to_contract_class_v0, sierra_to_contact_class_v1};
use crate::state_reader::utils::{get_chain_info, get_rpc_state_reader_config};
use crate::state_reader::utils::{
deserialize_transaction_json_to_starknet_api_tx,
get_chain_info,
get_rpc_state_reader_config,
};

pub struct TestStateReader(RpcStateReader);

Expand Down Expand Up @@ -120,6 +125,15 @@ impl TestStateReader {
serde_json::from_value(raw_tx_hashes).map_err(serde_err_to_state_err)
}

pub fn get_tx_by_hash(&self, tx_hash: &str) -> StateResult<Transaction> {
let method = "starknet_getTransactionByHash";
let params = json!({
"transaction_hash": tx_hash,
});
deserialize_transaction_json_to_starknet_api_tx(self.0.send_rpc_request(method, params)?)
.map_err(serde_err_to_state_err)
}

pub fn get_contract_class(&self, class_hash: &ClassHash) -> StateResult<StarknetContractClass> {
let params = json!({
"block_id": self.0.block_id,
Expand All @@ -131,6 +145,16 @@ impl TestStateReader {
Ok(contract_class)
}

pub fn get_all_txs_in_block(&self) -> StateResult<Vec<Transaction>> {
// TODO(Aviv): Use batch request to get all txs in a block.
let txs: Vec<_> = self
.get_tx_hashes()?
.iter()
.map(|tx_hash| self.get_tx_by_hash(tx_hash))
.collect::<Result<_, _>>()?;
Ok(txs)
}

pub fn get_versioned_constants(&self) -> StateResult<&'static VersionedConstants> {
Ok(self.get_starknet_version()?.into())
}
Expand Down
65 changes: 65 additions & 0 deletions crates/blockifier_regression_test/src/state_reader/utils.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
use blockifier::context::{ChainInfo, FeeTokenAddresses};
use papyrus_execution::{ETH_FEE_CONTRACT_ADDRESS, STRK_FEE_CONTRACT_ADDRESS};
use serde_json::Value;
use starknet_api::core::{ChainId, ContractAddress, PatriciaKey};
use starknet_api::transaction::{
DeclareTransaction,
DeployAccountTransaction,
InvokeTransaction,
Transaction,
};
use starknet_api::{contract_address, felt, patricia_key};
use starknet_gateway::config::RpcStateReaderConfig;

Expand All @@ -27,3 +34,61 @@ pub fn get_rpc_state_reader_config() -> RpcStateReaderConfig {
pub fn get_chain_info() -> ChainInfo {
ChainInfo { chain_id: ChainId::Mainnet, fee_token_addresses: get_fee_token_addresses() }
}

pub fn deserialize_transaction_json_to_starknet_api_tx(
mut raw_transaction: Value,
) -> serde_json::Result<Transaction> {
let tx_type: String = serde_json::from_value(raw_transaction["type"].clone())?;
let tx_version: String = serde_json::from_value(raw_transaction["version"].clone())?;

match (tx_type.as_str(), tx_version.as_str()) {
("INVOKE", "0x0") => {
Ok(Transaction::Invoke(InvokeTransaction::V0(serde_json::from_value(raw_transaction)?)))
}
("INVOKE", "0x1") => {
Ok(Transaction::Invoke(InvokeTransaction::V1(serde_json::from_value(raw_transaction)?)))
}
("INVOKE", "0x3") => {
let resource_bounds = raw_transaction
.get_mut("resource_bounds")
.expect("Invoke v3 tx should contain resource_bounds field")
.as_object_mut()
.expect("resource_bounds should be an object");

// In old invoke v3 transaction, the resource bounds names are lowercase.
// need to convert to uppercase for deserialization to work.
if let Some(l1_gas_value) = resource_bounds.remove("l1_gas") {
resource_bounds.insert("L1_GAS".to_string(), l1_gas_value);

let l2_gas_value = resource_bounds
.remove("l2_gas")
.expect("If invoke v3 tx contains l1_gas, it should contain l2_gas");
resource_bounds.insert("L2_GAS".to_string(), l2_gas_value);
}

Ok(Transaction::Invoke(InvokeTransaction::V3(serde_json::from_value(raw_transaction)?)))
}
("DEPLOY_ACCOUNT", "0x1") => Ok(Transaction::DeployAccount(DeployAccountTransaction::V1(
serde_json::from_value(raw_transaction)?,
))),
("DEPLOY_ACCOUNT", "0x3") => Ok(Transaction::DeployAccount(DeployAccountTransaction::V3(
serde_json::from_value(raw_transaction)?,
))),
("DECLARE", "0x0") => Ok(Transaction::Declare(DeclareTransaction::V0(
serde_json::from_value(raw_transaction)?,
))),
("DECLARE", "0x1") => Ok(Transaction::Declare(DeclareTransaction::V1(
serde_json::from_value(raw_transaction)?,
))),
("DECLARE", "0x2") => Ok(Transaction::Declare(DeclareTransaction::V2(
serde_json::from_value(raw_transaction)?,
))),
("DECLARE", "0x3") => Ok(Transaction::Declare(DeclareTransaction::V3(
serde_json::from_value(raw_transaction)?,
))),
("L1_HANDLER", _) => Ok(Transaction::L1Handler(serde_json::from_value(raw_transaction)?)),
(tx_type, tx_version) => Err(serde::de::Error::custom(format!(
"unimplemented transaction type: {tx_type} version: {tx_version}"
))),
}
}

0 comments on commit 32dc924

Please sign in to comment.