Skip to content

Commit

Permalink
fix: calculate l1 gas consumed
Browse files Browse the repository at this point in the history
  • Loading branch information
yoavGrs committed May 19, 2024
1 parent 111bdf8 commit d4f5e94
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 21 deletions.
66 changes: 52 additions & 14 deletions src/block_hash/receipt_commitment.rs
Original file line number Diff line number Diff line change
@@ -1,40 +1,64 @@
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<H: HashFunction>(
transactions_receipt: &[TransactionReceipt],
transaction_version: &TransactionVersion,
l1_data_gas_price_per_token: GasPricePerToken,
l1_gas_price_per_token: GasPricePerToken,
) -> ReceiptCommitment {
ReceiptCommitment(calculate_root::<H>(
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(),
))
}

// Poseidon(
// 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(
Expand Down Expand Up @@ -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::<u64>()
* 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
}
}
31 changes: 24 additions & 7 deletions src/block_hash/receipt_commitment_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
Expand All @@ -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]
Expand All @@ -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,
Expand All @@ -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::<PoseidonHashCalculator>(&[transaction_receipt]),
calculate_receipt_commitment::<PoseidonHashCalculator>(
&[transaction_receipt],
&TransactionVersion::THREE,
l1_data_gas_price,
l1_gas_price
),
expected_root
);
}
Expand Down

0 comments on commit d4f5e94

Please sign in to comment.