From d4f5e940585443acad3286a5347eda0255a340ed Mon Sep 17 00:00:00 2001 From: Yoav Gross Date: Sun, 19 May 2024 14:10:40 +0300 Subject: [PATCH] fix: calculate l1 gas consumed --- src/block_hash/receipt_commitment.rs | 66 ++++++++++++++++++----- src/block_hash/receipt_commitment_test.rs | 31 ++++++++--- 2 files changed, 76 insertions(+), 21 deletions(-) diff --git a/src/block_hash/receipt_commitment.rs b/src/block_hash/receipt_commitment.rs index eda4dce..b704c1c 100644 --- a/src/block_hash/receipt_commitment.rs +++ b/src/block_hash/receipt_commitment.rs @@ -1,25 +1,36 @@ +use crate::block::{GasPrice, GasPricePerToken}; use crate::core::ReceiptCommitment; use crate::crypto::patricia_hash::calculate_root; use crate::crypto::utils::HashChain; use crate::hash::{starknet_keccak_hash, HashFunction, StarkFelt}; use crate::transaction::{ - ExecutionResources, MessageToL1, TransactionExecutionStatus, TransactionReceipt, + ExecutionResources, Fee, MessageToL1, TransactionExecutionStatus, TransactionReceipt, + TransactionVersion, }; #[cfg(test)] #[path = "receipt_commitment_test.rs"] mod receipt_commitment_test; -// TODO(yoav): Get these values from versioned constants. -const L1_GAS_PER_STEP: u64 = 1; -const L1_GAS_PER_BUILTIN_INSTANCE: u64 = 1; - /// Returns the root of a Patricia tree where each leaf is a receipt hash. pub fn calculate_receipt_commitment( transactions_receipt: &[TransactionReceipt], + transaction_version: &TransactionVersion, + l1_data_gas_price_per_token: GasPricePerToken, + l1_gas_price_per_token: GasPricePerToken, ) -> ReceiptCommitment { ReceiptCommitment(calculate_root::( - transactions_receipt.iter().map(calculate_receipt_hash).collect(), + transactions_receipt + .iter() + .map(|receipt| { + calculate_receipt_hash( + receipt, + transaction_version, + l1_data_gas_price_per_token, + l1_gas_price_per_token, + ) + }) + .collect(), )) } @@ -27,14 +38,27 @@ pub fn calculate_receipt_commitment( // transaction hash, amount of fee paid, hash of messages sent, revert reason, // execution resources // ). -fn calculate_receipt_hash(transaction_receipt: &TransactionReceipt) -> StarkFelt { +fn calculate_receipt_hash( + transaction_receipt: &TransactionReceipt, + transaction_version: &TransactionVersion, + l1_data_gas_price_per_token: GasPricePerToken, + l1_gas_price_per_token: GasPricePerToken, +) -> StarkFelt { + let l1_gas_price = get_price_by_version(l1_gas_price_per_token, transaction_version); + let l1_data_gas_price = get_price_by_version(l1_data_gas_price_per_token, transaction_version); let hash_chain = HashChain::new() .chain(&transaction_receipt.transaction_hash) .chain(&transaction_receipt.output.actual_fee().0.into()) .chain(&calculate_messages_sent_hash(transaction_receipt.output.messages_sent())) .chain(&get_revert_reason_hash(transaction_receipt.output.execution_status())); - chain_execution_resources(hash_chain, transaction_receipt.output.execution_resources()) - .get_poseidon_hash() + chain_execution_resources( + hash_chain, + transaction_receipt.output.execution_resources(), + transaction_receipt.output.actual_fee(), + l1_data_gas_price, + l1_gas_price, + ) + .get_poseidon_hash() } // Poseidon( @@ -66,18 +90,32 @@ fn get_revert_reason_hash(execution_status: &TransactionExecutionStatus) -> Star // Chains: // L2 gas consumed (In the current RPC: always 0), // L1 gas consumed (In the current RPC: -// L1 gas consumed for calldata + L1 gas consumed for steps and builtins), +// L1 gas consumed for calldata + L1 gas consumed for steps and builtins. +// Calculated as: (actual_fee - actual_l1_data_gas_fee) / l1_gas_price // L1 data gas consumed (In the current RPC: L1 data gas consumed for blob). fn chain_execution_resources( hash_chain: HashChain, execution_resources: &ExecutionResources, + actual_fee: Fee, + l1_data_gas_price: GasPrice, + l1_gas_price: GasPrice, ) -> HashChain { - let l1_gas_consumed = execution_resources.da_l1_gas_consumed - + execution_resources.steps * L1_GAS_PER_STEP - + execution_resources.builtin_instance_counter.values().sum::() - * L1_GAS_PER_BUILTIN_INSTANCE; + let l1_gas_consumed: u128 = (actual_fee.0 + - (l1_data_gas_price.0) * u128::from(execution_resources.da_l1_data_gas_consumed)) + / l1_gas_price.0; hash_chain .chain(&StarkFelt::ZERO) // L2 gas consumed .chain(&l1_gas_consumed.into()) .chain(&execution_resources.da_l1_data_gas_consumed.into()) } + +fn get_price_by_version( + price_per_token: GasPricePerToken, + transaction_version: &TransactionVersion, +) -> GasPrice { + if transaction_version >= &TransactionVersion::THREE { + price_per_token.price_in_fri + } else { + price_per_token.price_in_wei + } +} diff --git a/src/block_hash/receipt_commitment_test.rs b/src/block_hash/receipt_commitment_test.rs index dbbae08..aa7a224 100644 --- a/src/block_hash/receipt_commitment_test.rs +++ b/src/block_hash/receipt_commitment_test.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use primitive_types::H160; use super::calculate_messages_sent_hash; -use crate::block::{BlockHash, BlockNumber}; +use crate::block::{BlockHash, BlockNumber, GasPrice, GasPricePerToken}; use crate::block_hash::receipt_commitment::{ calculate_receipt_commitment, calculate_receipt_hash, get_revert_reason_hash, }; @@ -12,7 +12,7 @@ use crate::hash::{PoseidonHashCalculator, StarkFelt}; use crate::transaction::{ Builtin, ExecutionResources, Fee, InvokeTransactionOutput, L2ToL1Payload, MessageToL1, RevertedTransactionExecutionStatus, TransactionExecutionStatus, TransactionHash, - TransactionOutput, TransactionReceipt, + TransactionOutput, TransactionReceipt, TransactionVersion, }; #[test] @@ -29,7 +29,7 @@ fn test_receipt_hash_regression() { da_l1_data_gas_consumed: 32, }; let invoke_output = TransactionOutput::Invoke(InvokeTransactionOutput { - actual_fee: Fee(12), + actual_fee: Fee(99804), messages_sent: vec![generate_message_to_l1(34), generate_message_to_l1(56)], events: vec![], execution_status, @@ -41,18 +41,35 @@ fn test_receipt_hash_regression() { block_number: BlockNumber(99), output: invoke_output, }; + let l1_data_gas_price = + GasPricePerToken { price_in_fri: GasPrice(456), price_in_wei: GasPrice(456) }; + let l1_gas_price = + GasPricePerToken { price_in_fri: GasPrice(789), price_in_wei: GasPrice(789) }; let expected_hash = - StarkFelt::try_from("0x06720e8f1cd4543ae25714f0c79e592d98b16747a92962406ab08b6d46e10fd2") + StarkFelt::try_from("0x06cb27bfc55dee54e6d0fc7a6790e39f0f3c003576d50f7b8e8a1be24c351bcf") .unwrap(); - assert_eq!(calculate_receipt_hash(&transaction_receipt), expected_hash); + assert_eq!( + calculate_receipt_hash( + &transaction_receipt, + &TransactionVersion::TWO, + l1_data_gas_price, + l1_gas_price + ), + expected_hash + ); let expected_root = ReceiptCommitment( - StarkFelt::try_from("0x035481a28b3ea40ddfbc80f3eabc924c9c5edf64f1dd7467d80c5c5290cf48ad") + StarkFelt::try_from("0x071cd6ee5b2a9686d0cf42818922b632cbf6940892b47ea2ac454b9938e929a0") .unwrap(), ); assert_eq!( - calculate_receipt_commitment::(&[transaction_receipt]), + calculate_receipt_commitment::( + &[transaction_receipt], + &TransactionVersion::THREE, + l1_data_gas_price, + l1_gas_price + ), expected_root ); }