Skip to content
This repository was archived by the owner on Jul 22, 2024. It is now read-only.

Execute Declare transactions using the RpcState + Various fixes related to Declare txs #1094

Merged
merged 59 commits into from
Oct 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
c22eb56
Add test case
fmoletta Oct 18, 2023
855d516
Fix get_onchain_data_segment_length
fmoletta Oct 18, 2023
d163fdb
Debug setup
fmoletta Oct 18, 2023
ced01c4
Fix get_onchain_data_segment_length
fmoletta Oct 18, 2023
1e7efff
Add StorageChangesCount struct
fmoletta Oct 18, 2023
2347431
Update test values
fmoletta Oct 18, 2023
ac56f81
Update test values
fmoletta Oct 19, 2023
cc55c5c
Merge branch 'fix-get_onchain_data_segment_length' into fix-count_act…
fmoletta Oct 19, 2023
5d2e5e3
fmt
fmoletta Oct 19, 2023
ba8cf16
Merge branch 'fix-get_onchain_data_segment_length' into fix-count_act…
fmoletta Oct 19, 2023
0df3007
Use StorageChangesCount struct in state method
fmoletta Oct 19, 2023
fed2162
Fix implicated code
fmoletta Oct 19, 2023
413dfa1
Update doc
fmoletta Oct 19, 2023
d680546
Update test values
fmoletta Oct 19, 2023
6a2bd15
Rename method for consistency
fmoletta Oct 19, 2023
94804d2
Add note comment
fmoletta Oct 19, 2023
5ae787e
Remove hardcoded contract address
fmoletta Oct 19, 2023
e75750b
Remove txt files
fmoletta Oct 19, 2023
7ddad62
Remove dbg prints
fmoletta Oct 19, 2023
c70a509
Remove dbg prints
fmoletta Oct 19, 2023
14576a6
Format
fmoletta Oct 19, 2023
bc06dbd
Restore blockifier version
fmoletta Oct 19, 2023
11f9f00
Restore tests
fmoletta Oct 19, 2023
52fb298
Restore newlines
fmoletta Oct 19, 2023
b0673c4
Restore newlines
fmoletta Oct 19, 2023
c82c682
Remove txt file
fmoletta Oct 19, 2023
0a517fc
Merge branch 'main' of github.com:lambdaclass/starknet_in_rust into r…
fmoletta Oct 19, 2023
fd99568
Merge remote-tracking branch 'origin/fix-count_actual_storage_changes…
fmoletta Oct 19, 2023
3a0b7fe
fmt
fmoletta Oct 19, 2023
d2bbe9b
Merge branch 'main' into fix-get_onchain_data_segment_length
fmoletta Oct 19, 2023
1bfa497
Merge branch 'fix-get_onchain_data_segment_length' into fix-count_act…
fmoletta Oct 19, 2023
f6295c9
Merge branch 'fix-count_actual_storage_changes' into rpc-state-reader…
fmoletta Oct 19, 2023
882b751
Merge branch 'main' into fix-get_onchain_data_segment_length
juanbono Oct 23, 2023
620abe3
Add test case with declare
fmoletta Oct 23, 2023
0fb938d
Deserialize Declare transactions
fmoletta Oct 23, 2023
f2a164c
Create blockifier Declare transaction
fmoletta Oct 23, 2023
41c09cd
Fix/Refactor `State::count actual storage changes` (#1086)
fmoletta Oct 23, 2023
2fed600
Add the ability to execute `DeployAccount` transactions using the `Rp…
fmoletta Oct 23, 2023
bff5b45
fetch class hash from the next block in declare tx
fmoletta Oct 23, 2023
219633d
Return an error if a class_hash is not declared + add tests for decla…
fmoletta Oct 23, 2023
3422eec
Fix error msg
fmoletta Oct 23, 2023
fb5f2b4
Add support for DeclareV0-1 in sir_tests
fmoletta Oct 23, 2023
e26aa30
Make Sierra class optional in declare v2 + other changes
fmoletta Oct 23, 2023
6a70c11
Add support for DeclareV2
fmoletta Oct 23, 2023
bf55785
Uncomment test
fmoletta Oct 23, 2023
5893af0
fix
fmoletta Oct 23, 2023
200e8de
Use new_with_sierra_class_hash_and_tx_hash
fmoletta Oct 24, 2023
2fefb3d
use CompiledClassHash instead of CompiledClass where applicatble
fmoletta Oct 24, 2023
dc60e6b
Handle nonce in declare v2 + run fmt
fmoletta Oct 24, 2023
163e7ca
Set casm class before counting state changes in declare v2
fmoletta Oct 24, 2023
35154ff
Changes
fmoletta Oct 24, 2023
ab0a4f3
Make sierra class hash non-optional
fmoletta Oct 24, 2023
cd010fd
fix + clippy
fmoletta Oct 24, 2023
debc149
Merge branch 'main' of github.com:lambdaclass/starknet_in_rust into f…
fmoletta Oct 24, 2023
2ba0145
Use state_reader instead of creating a state to fetch the next block …
fmoletta Oct 24, 2023
6e3dc4c
Merge remote-tracking branch 'origin/fix-get_onchain_data_segment_len…
fmoletta Oct 24, 2023
3c5f3cf
Add removed test
fmoletta Oct 24, 2023
5d2a42f
Update test values
fmoletta Oct 24, 2023
d1245e2
Merge branch 'main' of github.com:lambdaclass/starknet_in_rust into r…
fmoletta Oct 24, 2023
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
4 changes: 2 additions & 2 deletions rpc_state_reader/src/rpc_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -401,12 +401,12 @@ impl RpcState {
}
}

pub fn get_contract_class(&self, class_hash: &ClassHash) -> SNContractClass {
pub fn get_contract_class(&self, class_hash: &ClassHash) -> Option<SNContractClass> {
self.rpc_call_result(
"starknet_getClass",
&json!([self.block.to_value().unwrap(), class_hash.0.to_string()]),
)
.unwrap()
.ok()
}

pub fn get_class_hash_at(&self, contract_address: &ContractAddress) -> ClassHash {
Expand Down
16 changes: 15 additions & 1 deletion rpc_state_reader/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use starknet_api::{
core::EntryPointSelector,
deprecated_contract_class::{EntryPoint, EntryPointOffset, EntryPointType},
hash::{StarkFelt, StarkHash},
transaction::{InvokeTransaction, Transaction},
transaction::{DeclareTransaction, InvokeTransaction, Transaction},
};

#[derive(Debug, Deserialize)]
Expand Down Expand Up @@ -85,6 +85,20 @@ pub fn deserialize_transaction_json(
"DEPLOY_ACCOUNT" => Ok(Transaction::DeployAccount(serde_json::from_value(
transaction,
)?)),
"DECLARE" => match tx_version.as_str() {
"0x0" => Ok(Transaction::Declare(DeclareTransaction::V0(
serde_json::from_value(transaction)?,
))),
"0x1" => Ok(Transaction::Declare(DeclareTransaction::V1(
serde_json::from_value(transaction)?,
))),
"0x2" => Ok(Transaction::Declare(DeclareTransaction::V2(
serde_json::from_value(transaction)?,
))),
x => Err(serde::de::Error::custom(format!(
"unimplemented declare version: {x}"
))),
},
x => Err(serde::de::Error::custom(format!(
"unimplemented transaction type deserialization: {x}"
))),
Expand Down
54 changes: 51 additions & 3 deletions rpc_state_reader/tests/blockifier_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ use blockifier::{
execution::{contract_class::ContractClass, entry_point::CallInfo},
state::{
cached_state::{CachedState, GlobalContractCache},
errors::StateError,
state_api::{StateReader, StateResult},
},
transaction::{
account_transaction::AccountTransaction,
objects::TransactionExecutionInfo,
transactions::{DeployAccountTransaction, ExecutableTransaction},
transactions::{DeclareTransaction, DeployAccountTransaction, ExecutableTransaction},
},
};
use blockifier::{
Expand Down Expand Up @@ -66,7 +67,7 @@ impl StateReader for RpcStateReader {
class_hash: &ClassHash,
) -> StateResult<ContractClass> {
Ok(match self.0.get_contract_class(class_hash) {
SNContractClass::Legacy(compressed_legacy_cc) => {
Some(SNContractClass::Legacy(compressed_legacy_cc)) => {
let as_str = utils::decode_reader(compressed_legacy_cc.program).unwrap();
let program = Program::from_bytes(as_str.as_bytes(), None).unwrap();
let entry_points_by_type = utils::map_entry_points_by_type_legacy(
Expand All @@ -78,7 +79,7 @@ impl StateReader for RpcStateReader {
});
BlockifierContractClass::V0(ContractClassV0(inner))
}
SNContractClass::Sierra(flattened_sierra_cc) => {
Some(SNContractClass::Sierra(flattened_sierra_cc)) => {
let middle_sierra: utils::MiddleSierraContractClass = {
let v = serde_json::to_value(flattened_sierra_cc).unwrap();
serde_json::from_value(v).unwrap()
Expand All @@ -93,6 +94,7 @@ impl StateReader for RpcStateReader {
let casm_cc = CasmContractClass::from_contract_class(sierra_cc, false).unwrap();
BlockifierContractClass::V1(casm_cc.try_into().unwrap())
}
None => return Err(StateError::UndeclaredClassHash(*class_hash)),
})
}

Expand Down Expand Up @@ -194,6 +196,17 @@ pub fn execute_tx(
contract_address,
})
}
SNTransaction::Declare(tx) => {
// Fetch the contract_class from the next block (as we don't have it in the previous one)
let mut next_block_state_reader =
RpcStateReader(RpcState::new_infura(network, (block_number.next()).into()));
let contract_class = next_block_state_reader
.get_compiled_contract_class(&tx.class_hash())
.unwrap();

let declare = DeclareTransaction::new(tx, tx_hash, contract_class).unwrap();
AccountTransaction::Declare(declare)
}
_ => unimplemented!(),
};

Expand Down Expand Up @@ -385,3 +398,38 @@ fn blockifier_test_case_reverted_tx(hash: &str, block_number: u64, chain: RpcCha
);
}
}

#[test_case(
// Declare tx
"0x60506c49e65d84e2cdd0e9142dc43832a0a59cb6a9cbcce1ab4f57c20ba4afb",
347899, // real block 347900
RpcChain::MainNet
)]
#[test_case(
// Declare tx
"0x1088aa18785779e1e8eef406dc495654ad42a9729b57969ad0dbf2189c40bee",
271887, // real block 271888
RpcChain::MainNet
)]
fn blockifier_test_case_declare_tx(hash: &str, block_number: u64, chain: RpcChain) {
let (tx_info, _trace, receipt) = execute_tx(hash, chain, BlockNumber(block_number));
let TransactionExecutionInfo {
execute_call_info,
actual_fee,
..
} = tx_info;

assert!(execute_call_info.is_none());

let actual_fee = actual_fee.0;
if receipt.actual_fee != actual_fee {
let diff = 100 * receipt.actual_fee.abs_diff(actual_fee) / receipt.actual_fee;

if diff >= 5 {
assert_eq!(
actual_fee, receipt.actual_fee,
"actual_fee mismatch differs from the baseline by more than 5% ({diff}%)",
);
}
}
}
103 changes: 99 additions & 4 deletions rpc_state_reader/tests/sir_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ use starknet_api::{
hash::{StarkFelt, StarkHash},
stark_felt,
state::StorageKey,
transaction::{Transaction as SNTransaction, TransactionHash},
transaction::{Transaction as SNTransaction, TransactionHash, TransactionVersion},
};
use starknet_in_rust::{
core::errors::state_errors::StateError,
core::{contract_address::compute_casm_class_hash, errors::state_errors::StateError},
definitions::{
block_context::{BlockContext, StarknetChainId, StarknetOsConfig},
constants::{
Expand All @@ -28,7 +28,7 @@ use starknet_in_rust::{
state_cache::StorageEntry,
BlockInfo,
},
transaction::{DeployAccount, InvokeFunction},
transaction::{Declare, DeclareV2, DeployAccount, InvokeFunction},
utils::{Address, ClassHash},
};

Expand All @@ -42,7 +42,9 @@ pub struct RpcStateReader(RpcState);
impl StateReader for RpcStateReader {
fn get_contract_class(&self, class_hash: &ClassHash) -> Result<CompiledClass, StateError> {
let hash = SNClassHash(StarkHash::new(*class_hash).unwrap());
Ok(CompiledClass::from(self.0.get_contract_class(&hash)))
Ok(CompiledClass::from(
self.0.get_contract_class(&hash).unwrap(),
))
}

fn get_class_hash_at(&self, contract_address: &Address) -> Result<ClassHash, StateError> {
Expand Down Expand Up @@ -148,6 +150,64 @@ pub fn execute_tx_configurable(
.unwrap()
.create_for_simulation(skip_validate, false, false, false)
}
SNTransaction::Declare(tx) => {
// Fetch the contract_class from the next block (as we don't have it in the previous one)
let next_block_state_reader =
RpcStateReader(RpcState::new_infura(network, (block_number.next()).into()));
let contract_class = next_block_state_reader
.get_contract_class(tx.class_hash().0.bytes().try_into().unwrap())
.unwrap();

if tx.version() != TransactionVersion(2_u8.into()) {
let contract_class = match contract_class {
CompiledClass::Deprecated(cc) => cc.as_ref().clone(),
_ => unreachable!(),
};

let declare = Declare::new_with_tx_and_class_hash(
contract_class,
Address(Felt252::from_bytes_be(tx.sender_address().0.key().bytes())),
tx.max_fee().0,
Felt252::from_bytes_be(tx.version().0.bytes()),
tx.signature()
.0
.iter()
.map(|f| Felt252::from_bytes_be(f.bytes()))
.collect(),
Felt252::from_bytes_be(tx.nonce().0.bytes()),
Felt252::from_bytes_be(tx_hash.0.bytes()),
tx.class_hash().0.bytes().try_into().unwrap(),
)
.unwrap();
declare.create_for_simulation(skip_validate, false, false, false)
} else {
let contract_class = match contract_class {
CompiledClass::Casm(cc) => cc.as_ref().clone(),
_ => unreachable!(),
};

let compiled_class_hash = compute_casm_class_hash(&contract_class).unwrap();

let declare = DeclareV2::new_with_sierra_class_hash_and_tx_hash(
None,
Felt252::from_bytes_be(tx.class_hash().0.bytes()),
Some(contract_class),
compiled_class_hash,
Address(Felt252::from_bytes_be(tx.sender_address().0.key().bytes())),
tx.max_fee().0,
Felt252::from_bytes_be(tx.version().0.bytes()),
tx.signature()
.0
.iter()
.map(|f| Felt252::from_bytes_be(f.bytes()))
.collect(),
Felt252::from_bytes_be(tx.nonce().0.bytes()),
Felt252::from_bytes_be(tx_hash.0.bytes()),
)
.unwrap();
declare.create_for_simulation(skip_validate, false, false, false)
}
}
_ => unimplemented!(),
};

Expand Down Expand Up @@ -421,3 +481,38 @@ fn test_validate_fee(hash: &str, block_number: u64, chain: RpcChain) {
assert_eq!(tx_info.actual_fee, receipt.actual_fee);
assert!(tx_info_without_fee.actual_fee < tx_info.actual_fee);
}

#[test_case(
// Declare tx
"0x60506c49e65d84e2cdd0e9142dc43832a0a59cb6a9cbcce1ab4f57c20ba4afb",
347899, // real block 347900
RpcChain::MainNet
)]
#[test_case(
// Declare tx
"0x1088aa18785779e1e8eef406dc495654ad42a9729b57969ad0dbf2189c40bee",
271887, // real block 271888
RpcChain::MainNet
)]
fn starknet_in_rust_test_case_declare_tx(hash: &str, block_number: u64, chain: RpcChain) {
let (tx_info, _trace, receipt) = execute_tx(hash, chain, BlockNumber(block_number));
let TransactionExecutionInfo {
call_info,
actual_fee,
..
} = tx_info;

assert!(call_info.is_none());

let actual_fee = actual_fee;
if receipt.actual_fee != actual_fee {
let diff = 100 * receipt.actual_fee.abs_diff(actual_fee) / receipt.actual_fee;

if diff >= 5 {
assert_eq!(
actual_fee, receipt.actual_fee,
"actual_fee mismatch differs from the baseline by more than 5% ({diff}%)",
);
}
}
}
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -870,7 +870,7 @@ mod test {
nonce: 0.into(),
hash_value: 0.into(),
compiled_class_hash: TEST_FIB_COMPILED_CONTRACT_CLASS_HASH.clone(),
sierra_contract_class,
sierra_contract_class: Some(sierra_contract_class),
sierra_class_hash,
casm_class: Default::default(),
skip_execute: false,
Expand Down
2 changes: 1 addition & 1 deletion src/state/cached_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ impl<T: StateReader> State for CachedState<T> {
let compiled_class_hash = compiled_class_hash.to_be_bytes();

self.cache
.class_hash_to_compiled_class_hash
.compiled_class_hash_writes
.insert(class_hash, compiled_class_hash);
Ok(())
}
Expand Down
9 changes: 5 additions & 4 deletions src/state/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ pub mod state_cache;

use crate::{
core::errors::state_errors::StateError,
services::api::contract_classes::compiled_class::CompiledClass,
utils::{get_keys, to_cache_state_storage_mapping, to_state_diff_storage_mapping},
utils::{
get_keys, to_cache_state_storage_mapping, to_state_diff_storage_mapping, CompiledClassHash,
},
};
use cairo_vm::{felt::Felt252, vm::runners::cairo_runner::ExecutionResources};
use getset::Getters;
Expand Down Expand Up @@ -106,15 +107,15 @@ impl ExecutionResourcesManager {
pub struct StateDiff {
pub(crate) address_to_class_hash: HashMap<Address, ClassHash>,
pub(crate) address_to_nonce: HashMap<Address, Felt252>,
pub(crate) class_hash_to_compiled_class: HashMap<ClassHash, CompiledClass>,
pub(crate) class_hash_to_compiled_class: HashMap<ClassHash, CompiledClassHash>,
pub(crate) storage_updates: HashMap<Address, HashMap<Felt252, Felt252>>,
}

impl StateDiff {
pub const fn new(
address_to_class_hash: HashMap<Address, ClassHash>,
address_to_nonce: HashMap<Address, Felt252>,
class_hash_to_compiled_class: HashMap<ClassHash, CompiledClass>,
class_hash_to_compiled_class: HashMap<ClassHash, CompiledClassHash>,
storage_updates: HashMap<Address, HashMap<Felt252, Felt252>>,
) -> Self {
StateDiff {
Expand Down
Loading