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

Commit

Permalink
Merge branch 'fix_outputs_call_contract' of github.com:lambdaclass/st…
Browse files Browse the repository at this point in the history
…arknet_in_rust into fix_outputs_call_contract
  • Loading branch information
juanbono committed Aug 16, 2023
2 parents fda8a55 + c4687e0 commit b9d7025
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 133 deletions.
239 changes: 109 additions & 130 deletions rpc_state_reader/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,15 @@ impl RpcState {
)
.unwrap();

Transaction::InvokeFunction(tx)
// Note: we skip nonce checking because it can be increased twice in a single block
// and it leads to a buggy behaviour when that's the case because the get_nonce_at method
// returns a possibly higher nonce than the one we have in the transaction.
// Example: Block contains 2 transactions that execute the same entrypoint with nonce=20.
// - First tx has entrypoint with nonce=20
// - Second tx has nonce=21
// If we want to execute the first transaction the nonce check fails
// since get_nonce_at for that block returns 21 and the first tx has 20.
tx.create_for_simulation(false, false, false, false, true)
}

_ => unimplemented!(),
Expand Down Expand Up @@ -729,41 +737,33 @@ mod transaction_tests {
DEFAULT_VALIDATE_MAX_N_STEPS,
},
},
execution::TransactionExecutionInfo,
felt::felt_str,
state::cached_state::CachedState,
};
use std::sync::Arc;

/// - Transaction Hash: `0x014640564509873cf9d24a311e1207040c8b60efd38d96caef79855f0b0075d5`
/// - Network: `mainnet`
/// - Type: `Invoke`
/// - Contract: StarkGate `0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7`
/// - Entrypoint: `transfer(recipient, amount)`
/// - Fee discrepancy: test=83714806176032, explorer=67749104314311, diff=15965701861721 (23%)
/// - Link to Explorer: https://starkscan.co/tx/0x014640564509873cf9d24a311e1207040c8b60efd38d96caef79855f0b0075d5
#[test]
fn test_invoke_0x014640564509873cf9d24a311e1207040c8b60efd38d96caef79855f0b0075d5() {
let tx_hash = "014640564509873cf9d24a311e1207040c8b60efd38d96caef79855f0b0075d5";
fn test_tx(
tx_hash: &str,
network: RpcChain,
block_number: u64,
gas_price: u128,
) -> TransactionExecutionInfo {
let tx_hash = tx_hash.strip_prefix("0x").unwrap();

// Instantiate the RPC StateReader and the CachedState
let rpc_state = Arc::new(RpcState::new(
RpcChain::MainNet,
BlockValue::Number(serde_json::to_value(90_006).unwrap()),
));
let block = BlockValue::Number(serde_json::to_value(block_number).unwrap());
let rpc_state = Arc::new(RpcState::new(network, block));
let mut state = CachedState::new(rpc_state.clone(), None, None);

// BlockContext with mainnet data.
// TODO look how to get this value from RPC call.
let gas_price_str = "13563643256";
let gas_price_u128 = gas_price_str.parse::<u128>().unwrap();

let fee_token_address = Address(felt_str!(
"049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7",
16
));

let network: StarknetChainId = rpc_state.chain.into();
let starknet_os_config =
StarknetOsConfig::new(network.to_felt(), fee_token_address, gas_price_u128);
StarknetOsConfig::new(network.to_felt(), fee_token_address, gas_price);

let block_info = rpc_state.get_block_info(starknet_os_config.clone());

Expand All @@ -780,7 +780,26 @@ mod transaction_tests {
);

let tx = rpc_state.get_transaction(tx_hash);
let result = tx.execute(&mut state, &block_context, 0).unwrap();

tx.execute(&mut state, &block_context, 0).unwrap()
}

/// - Transaction Hash: `0x014640564509873cf9d24a311e1207040c8b60efd38d96caef79855f0b0075d5`
/// - Network: `mainnet`
/// - Type: `Invoke`
/// - Contract: StarkGate `0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7`
/// - Entrypoint: `transfer(recipient, amount)`
/// - Fee discrepancy: test=83714806176032, explorer=67749104314311, diff=15965701861721 (23%)
/// - Link to Explorer: https://starkscan.co/tx/0x014640564509873cf9d24a311e1207040c8b60efd38d96caef79855f0b0075d5
#[test]
fn test_invoke_0x014640564509873cf9d24a311e1207040c8b60efd38d96caef79855f0b0075d5() {
let result = test_tx(
"0x014640564509873cf9d24a311e1207040c8b60efd38d96caef79855f0b0075d5",
RpcChain::MainNet,
90_006,
13563643256,
);

dbg!(&result.actual_resources);
dbg!(&result.actual_fee); // test=83714806176032, explorer=67749104314311, diff=15965701861721 (23%)
dbg!(&result.call_info.clone().unwrap().execution_resources); // Ok with explorer
Expand All @@ -796,45 +815,13 @@ mod transaction_tests {
/// - Link to Explorer: https://starkscan.co/tx/0x06da92cfbdceac5e5e94a1f40772d6c79d34f011815606742658559ec77b6955
#[test]
fn test_invoke_mainnet_0x06da92cfbdceac5e5e94a1f40772d6c79d34f011815606742658559ec77b6955() {
// Tx Hash without the "0x" prefix.
let tx_hash = "06da92cfbdceac5e5e94a1f40772d6c79d34f011815606742658559ec77b6955";

// Create RPC StateReader and CachedState
let rpc_state = Arc::new(RpcState::new(
let result = test_tx(
"0x06da92cfbdceac5e5e94a1f40772d6c79d34f011815606742658559ec77b6955",
RpcChain::MainNet,
BlockValue::Number(serde_json::to_value(90_002).unwrap()),
));
let mut state = CachedState::new(rpc_state.clone(), None, None);

// BlockContext with mainnet data.
// TODO look how to get this value from RPC call.
let gas_price_str = "13572248835"; // from block 90_002
let gas_price_u128 = gas_price_str.parse::<u128>().unwrap();

let fee_token_address = Address(felt_str!(
"049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7",
16
));
let network: StarknetChainId = rpc_state.chain.into();
let starknet_os_config =
StarknetOsConfig::new(network.to_felt(), fee_token_address, gas_price_u128);

let block_info = rpc_state.get_block_info(starknet_os_config.clone());

let block_context = BlockContext::new(
starknet_os_config,
DEFAULT_CONTRACT_STORAGE_COMMITMENT_TREE_HEIGHT,
DEFAULT_GLOBAL_STATE_COMMITMENT_TREE_HEIGHT,
DEFAULT_CAIRO_RESOURCE_FEE_WEIGHTS.clone(),
DEFAULT_INVOKE_TX_MAX_N_STEPS,
DEFAULT_VALIDATE_MAX_N_STEPS,
block_info,
Default::default(),
true,
90_002,
13572248835,
);

let tx = rpc_state.get_transaction(tx_hash);
let result = tx.execute(&mut state, &block_context, 0).unwrap();
dbg!(&result.actual_resources);
dbg!(&result.actual_fee); // test=267319013054160, explorer=219298652474858, diff=48020360579302 (22%)
dbg!(&result.call_info.clone().unwrap().execution_resources); // Ok with explorer
Expand All @@ -849,47 +836,14 @@ mod transaction_tests {
/// - Fee discrepancy: test=7252831227950, explorer=7207614784695, diff=45216443255 (0.06%)
/// - Link to Explorer: https://testnet.starkscan.co/tx/0x074dab0828ec1b6cfde5188c41d41af1c198192a7d118217f95a802aa923dacf
#[test]
fn test_invoke_mainnet_0x074dab0828ec1b6cfde5188c41d41af1c198192a7d118217f95a802aa923dacf() {
// Tx Hash without the "0x" prefix.
let tx_hash_str = "074dab0828ec1b6cfde5188c41d41af1c198192a7d118217f95a802aa923dacf";

// Instantiate CachedState
let rpc_state = Arc::new(RpcState::new(
fn test_0x074dab0828ec1b6cfde5188c41d41af1c198192a7d118217f95a802aa923dacf() {
let result = test_tx(
"0x074dab0828ec1b6cfde5188c41d41af1c198192a7d118217f95a802aa923dacf",
RpcChain::TestNet,
BlockValue::Number(serde_json::to_value(838683).unwrap()),
));

let mut state = CachedState::new(rpc_state.clone(), None, None);

// BlockContext with mainnet data.
// TODO look how to get this value from RPC call.
let gas_price_str = "2917470325"; // from block 838683
let gas_price_u128 = gas_price_str.parse::<u128>().unwrap();

let fee_token_address = Address(felt_str!(
"049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7",
16
));
let network: StarknetChainId = rpc_state.chain.into();
let starknet_os_config =
StarknetOsConfig::new(network.to_felt(), fee_token_address, gas_price_u128);

let block_info = rpc_state.get_block_info(starknet_os_config.clone());

let block_context = BlockContext::new(
starknet_os_config,
DEFAULT_CONTRACT_STORAGE_COMMITMENT_TREE_HEIGHT,
DEFAULT_GLOBAL_STATE_COMMITMENT_TREE_HEIGHT,
DEFAULT_CAIRO_RESOURCE_FEE_WEIGHTS.clone(),
DEFAULT_INVOKE_TX_MAX_N_STEPS,
DEFAULT_VALIDATE_MAX_N_STEPS,
block_info,
Default::default(),
true,
838683,
2917470325,
);
let tx = rpc_state.get_transaction(tx_hash_str);

let result = tx.execute(&mut state, &block_context, 0).unwrap();
dbg!(&result.actual_resources);
dbg!(&result.actual_fee); // test=7252831227950, explorer=7207614784695, diff=45216443255 (0.06%)
dbg!(&result.call_info.clone().unwrap().execution_resources); // Ok with explorer
Expand All @@ -905,49 +859,74 @@ mod transaction_tests {
/// - Link to Explorer: https://testnet-2.starkscan.co/tx/0x019feb888a2d53ffddb7a1750264640afab8e9c23119e648b5259f1b5e7d51bc
#[test]
fn test_invoke_testnet2_0x019feb888a2d53ffddb7a1750264640afab8e9c23119e648b5259f1b5e7d51bc() {
// Tx Hash without the "0x" prefix.
let tx_hash_str = "019feb888a2d53ffddb7a1750264640afab8e9c23119e648b5259f1b5e7d51bc";

// Instantiate the RPC StateReader and the CachedState
let rpc_state = Arc::new(RpcState::new(
let result = test_tx(
"0x019feb888a2d53ffddb7a1750264640afab8e9c23119e648b5259f1b5e7d51bc",
RpcChain::TestNet2,
BlockValue::Number(serde_json::to_value(123001).unwrap()),
));

// BlockContext with mainnet data.
// TODO look how to get this value from RPC call.
let gas_price_str = "272679647"; // from block 123001
let gas_price_u128 = gas_price_str.parse::<u128>().unwrap();

let fee_token_address = Address(felt_str!(
"49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7",
16
));
123001,
272679647,
);

let mut state = CachedState::new(rpc_state.clone(), None, None);
dbg!(&result.actual_resources);
dbg!(&result.actual_fee); // test=6361070805216, explorer=47292465953700, diff=5888146145679 (0.13%)
dbg!(&result.call_info.clone().unwrap().execution_resources); // Ok with explorer
dbg!(&result.call_info.unwrap().internal_calls.len()); // Ok with explorer
}

let network: StarknetChainId = rpc_state.chain.into();
let starknet_os_config =
StarknetOsConfig::new(network.to_felt(), fee_token_address, gas_price_u128);
/// - Transaction Hash: 0x02e31c976f649ba05da82e4c6a054a9a41961adda4c3dea26e6b523f4f18b382
/// - Network: testnet
/// - Type: Invoke
/// - Entrypoint: freeMint
/// - Fee discrepancy: test=4940000049400, explorer=6191000061910, diff=25%
/// - Link to explorer: https://testnet.starkscan.co/tx/0x02e31c976f649ba05da82e4c6a054a9a41961adda4c3dea26e6b523f4f18b382
#[test]
fn test_0x02e31c976f649ba05da82e4c6a054a9a41961adda4c3dea26e6b523f4f18b382() {
let result = test_tx(
"0x02e31c976f649ba05da82e4c6a054a9a41961adda4c3dea26e6b523f4f18b382",
RpcChain::TestNet,
846582,
1000000010,
);

let block_info = rpc_state.get_block_info(starknet_os_config.clone());
dbg!(&result.actual_resources);
dbg!(&result.actual_fee); // test=6361070805216, explorer=47292465953700, diff=5888146145679 (0.13%)
dbg!(&result.call_info.clone().unwrap().execution_resources); // Ok with explorer
dbg!(&result.call_info.unwrap().internal_calls.len()); // Ok with explorer
}

let block_context = BlockContext::new(
starknet_os_config,
DEFAULT_CONTRACT_STORAGE_COMMITMENT_TREE_HEIGHT,
DEFAULT_GLOBAL_STATE_COMMITMENT_TREE_HEIGHT,
DEFAULT_CAIRO_RESOURCE_FEE_WEIGHTS.clone(),
DEFAULT_INVOKE_TX_MAX_N_STEPS,
DEFAULT_VALIDATE_MAX_N_STEPS,
block_info,
Default::default(),
true,
/// - Transaction Hash: 0x26a1a5b5f2b3390302ade67c766cc94804fd41c86c5ee37e20c6415dc39358c
/// - Network: mainnet
/// - Type: Invoke
/// - Entrypoint: evolve(game_id)
/// - Fee discrepancy: test=263050867669716, explorer=306031925226186, diff=16%
/// - Link to explorer: https://starkscan.co/tx/0x026a1a5b5f2b3390302ade67c766cc94804fd41c86c5ee37e20c6415dc39358c
#[test]
fn test_0x26a1a5b5f2b3390302ade67c766cc94804fd41c86c5ee37e20c6415dc39358c() {
let result = test_tx(
"0x26a1a5b5f2b3390302ade67c766cc94804fd41c86c5ee37e20c6415dc39358c",
RpcChain::MainNet,
155054,
33977120598,
);
let tx = rpc_state.get_transaction(tx_hash_str);
let result = tx.execute(&mut state, &block_context, 0).unwrap();

dbg!(&result.actual_resources);
dbg!(&result.actual_fee); // test=6361070805216, explorer=47292465953700, diff=5888146145679 (0.13%)
dbg!(&result.call_info.clone().unwrap().execution_resources); // Ok with explorer
dbg!(&result.call_info.unwrap().internal_calls.len()); // Ok with explorer
}

// Fails because there is a problem with get_compiled_class_hash
// #[test]
// fn test_0x00eef6ba6741da8769192fac9d28c6631cf66f9e7c4e880b886ef6a2e550e4e2() {
// let result = test_tx(
// "0x00eef6ba6741da8769192fac9d28c6631cf66f9e7c4e880b886ef6a2e550e4e2",
// RpcChain::MainNet,
// 156105,
// 18348936116,
// );

// dbg!(&result.actual_resources);
// dbg!(&result.actual_fee);
// dbg!(&result.call_info.clone().unwrap().execution_resources);
// dbg!(&result.call_info.unwrap().internal_calls.len());
// }
}
5 changes: 5 additions & 0 deletions src/core/transaction_hash/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use cairo_vm::felt::{felt_str, Felt252};
use num_traits::Zero;

#[derive(Debug)]
/// Enum representing the different types of transaction hash prefixes.
pub enum TransactionHashPrefix {
Declare,
Deploy,
Expand All @@ -16,6 +17,7 @@ pub enum TransactionHashPrefix {
L1Handler,
}

// Returns the associated prefix value for a given transaction type.
impl TransactionHashPrefix {
fn get_prefix(&self) -> Felt252 {
match self {
Expand Down Expand Up @@ -71,6 +73,7 @@ pub fn calculate_transaction_hash_common(
compute_hash_on_elements(&data_to_hash)
}

/// Calculate the hash for deploying a transaction.
pub fn calculate_deploy_transaction_hash(
version: Felt252,
contract_address: &Address,
Expand All @@ -89,6 +92,7 @@ pub fn calculate_deploy_transaction_hash(
)
}

/// Calculate the hash for deploying an account transaction.
#[allow(clippy::too_many_arguments)]
pub fn calculate_deploy_account_transaction_hash(
version: Felt252,
Expand All @@ -115,6 +119,7 @@ pub fn calculate_deploy_account_transaction_hash(
)
}

/// Calculate the hash for a declared transaction.
pub fn calculate_declare_transaction_hash(
contract_class: &ContractClass,
chain_id: Felt252,
Expand Down
Loading

0 comments on commit b9d7025

Please # to comment.