Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: calculate l1 gas consumed #257

Merged
merged 1 commit into from
May 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
67 changes: 53 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,33 @@ 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())
}

// TODO(yoav): move this function to transaction.rs and make it public.
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(123), price_in_wei: GasPrice(456) };
let l1_gas_price =
GasPricePerToken { price_in_fri: GasPrice(456), 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("0x03a0af1272fc3b0b83894fd7b6b70d89acb07772bc28efc9091e3cc1c2c72493")
.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
Loading