Skip to content

Commit

Permalink
feat: add l1_gas_consumed for block hash
Browse files Browse the repository at this point in the history
  • Loading branch information
yoavGrs committed Jun 3, 2024
1 parent 2347430 commit e5f4bc7
Show file tree
Hide file tree
Showing 6 changed files with 20 additions and 96 deletions.
15 changes: 3 additions & 12 deletions src/block_hash/block_hash_calculator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,12 @@ use super::event_commitment::{calculate_events_commitment, EventLeafElement};
use super::receipt_commitment::{calculate_receipt_commitment, ReceiptElement};
use super::state_diff_hash::calculate_state_diff_hash;
use super::transaction_commitment::{calculate_transactions_commitment, TransactionLeafElement};
use crate::block::{BlockHash, BlockHeaderWithoutHash, GasPricePerToken};
use crate::block::{BlockHash, BlockHeaderWithoutHash};
use crate::core::{EventCommitment, ReceiptCommitment, StateDiffCommitment, TransactionCommitment};
use crate::crypto::utils::HashChain;
use crate::data_availability::L1DataAvailabilityMode;
use crate::state::ThinStateDiff;
use crate::transaction::{
TransactionHash, TransactionOutputCommon, TransactionSignature, TransactionVersion,
};
use crate::transaction::{TransactionHash, TransactionOutputCommon, TransactionSignature};
use crate::transaction_hash::ascii_as_felt;

#[cfg(test)]
Expand All @@ -28,7 +26,6 @@ pub struct TransactionHashingData {
pub transaction_signature: Option<TransactionSignature>,
pub transaction_output: TransactionOutputCommon,
pub transaction_hash: TransactionHash,
pub transaction_version: TransactionVersion,
}

/// Commitments of a block.
Expand Down Expand Up @@ -77,8 +74,6 @@ pub fn calculate_block_hash(
pub fn calculate_block_commitments(
transactions_data: &[TransactionHashingData],
state_diff: &ThinStateDiff,
l1_data_gas_price_per_token: GasPricePerToken,
l1_gas_price_per_token: GasPricePerToken,
l1_da_mode: L1DataAvailabilityMode,
) -> BlockHeaderCommitments {
let transaction_leaf_elements: Vec<TransactionLeafElement> =
Expand All @@ -99,11 +94,7 @@ pub fn calculate_block_commitments(

let receipt_elements: Vec<ReceiptElement> =
transactions_data.iter().map(ReceiptElement::from).collect();
let receipts_commitment = calculate_receipt_commitment::<Poseidon>(
&receipt_elements,
l1_data_gas_price_per_token,
l1_gas_price_per_token,
);
let receipts_commitment = calculate_receipt_commitment::<Poseidon>(&receipt_elements);
let state_diff_commitment = calculate_state_diff_hash(state_diff);
let concatenated_counts = concat_counts(
transactions_data.len(),
Expand Down
12 changes: 3 additions & 9 deletions src/block_hash/block_hash_calculator_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::core::{ContractAddress, GlobalRoot, PatriciaKey, SequencerContractAdd
use crate::data_availability::L1DataAvailabilityMode;
use crate::felt;
use crate::hash::{FeltConverter, TryIntoFelt};
use crate::transaction::{TransactionHash, TransactionSignature, TransactionVersion};
use crate::transaction::{TransactionHash, TransactionSignature};

#[test]
fn test_block_hash_regression() {
Expand All @@ -35,17 +35,11 @@ fn test_block_hash_regression() {
transaction_signature: Some(TransactionSignature(vec![Felt::TWO, Felt::THREE])),
transaction_output: get_transaction_output(),
transaction_hash: TransactionHash(Felt::ONE),
transaction_version: TransactionVersion::THREE,
}];

let state_diff = get_state_diff();
let block_commitments = calculate_block_commitments(
&transactions_data,
&state_diff,
block_header.l1_data_gas_price,
block_header.l1_gas_price,
block_header.l1_da_mode,
);
let block_commitments =
calculate_block_commitments(&transactions_data, &state_diff, block_header.l1_da_mode);

let expected_hash = felt!("0x061e4998d51a248f1d0288d7e17f6287757b0e5e6c5e1e58ddf740616e312134");

Expand Down
57 changes: 7 additions & 50 deletions src/block_hash/receipt_commitment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@ use starknet_types_core::felt::Felt;
use starknet_types_core::hash::StarkHash;

use super::block_hash_calculator::TransactionHashingData;
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;
use crate::transaction::{
ExecutionResources, Fee, MessageToL1, TransactionExecutionStatus, TransactionHash,
TransactionOutputCommon, TransactionVersion,
ExecutionResources, MessageToL1, TransactionExecutionStatus, TransactionHash,
TransactionOutputCommon,
};

#[cfg(test)]
Expand All @@ -21,61 +20,38 @@ mod receipt_commitment_test;
pub struct ReceiptElement {
pub transaction_hash: TransactionHash,
pub transaction_output: TransactionOutputCommon,
pub transaction_version: TransactionVersion,
}

impl From<&TransactionHashingData> for ReceiptElement {
fn from(transaction_data: &TransactionHashingData) -> Self {
Self {
transaction_hash: transaction_data.transaction_hash,
transaction_output: transaction_data.transaction_output.clone(),
transaction_version: transaction_data.transaction_version,
}
}
}

/// Returns the root of a Patricia tree where each leaf is a receipt hash.
pub fn calculate_receipt_commitment<H: StarkHash>(
receipt_elements: &[ReceiptElement],
l1_data_gas_price_per_token: GasPricePerToken,
l1_gas_price_per_token: GasPricePerToken,
) -> ReceiptCommitment {
ReceiptCommitment(calculate_root::<H>(
receipt_elements
.iter()
.map(|receipt| {
calculate_receipt_hash(receipt, l1_data_gas_price_per_token, l1_gas_price_per_token)
})
.collect(),
receipt_elements.iter().map(calculate_receipt_hash).collect(),
))
}

// Poseidon(
// transaction hash, amount of fee paid, hash of messages sent, revert reason,
// execution resources
// ).
fn calculate_receipt_hash(
receipt_element: &ReceiptElement,
l1_data_gas_price_per_token: GasPricePerToken,
l1_gas_price_per_token: GasPricePerToken,
) -> Felt {
let l1_gas_price =
get_price_by_version(l1_gas_price_per_token, &receipt_element.transaction_version);
let l1_data_gas_price =
get_price_by_version(l1_data_gas_price_per_token, &receipt_element.transaction_version);
fn calculate_receipt_hash(receipt_element: &ReceiptElement) -> Felt {
let hash_chain = HashChain::new()
.chain(&receipt_element.transaction_hash)
.chain(&receipt_element.transaction_output.actual_fee.0.into())
.chain(&calculate_messages_sent_hash(&receipt_element.transaction_output.messages_sent))
.chain(&get_revert_reason_hash(&receipt_element.transaction_output.execution_status));
chain_execution_resources(
hash_chain,
&receipt_element.transaction_output.execution_resources,
receipt_element.transaction_output.actual_fee,
l1_data_gas_price,
l1_gas_price,
)
.get_poseidon_hash()
chain_execution_resources(hash_chain, &receipt_element.transaction_output.execution_resources)
.get_poseidon_hash()
}

// Poseidon(
Expand Down Expand Up @@ -108,32 +84,13 @@ fn get_revert_reason_hash(execution_status: &TransactionExecutionStatus) -> Felt
// 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.
// 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: 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(&Felt::ZERO) // L2 gas consumed
.chain(&l1_gas_consumed.into())
.chain(&execution_resources.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
}
}
30 changes: 5 additions & 25 deletions src/block_hash/receipt_commitment_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use starknet_types_core::felt::Felt;
use starknet_types_core::hash::Poseidon;

use super::calculate_messages_sent_hash;
use crate::block::{GasPrice, GasPricePerToken};
use crate::block_hash::receipt_commitment::{
calculate_receipt_commitment, calculate_receipt_hash, get_revert_reason_hash, ReceiptElement,
};
Expand All @@ -12,41 +11,22 @@ use crate::felt;
use crate::hash::{FeltConverter, TryIntoFelt};
use crate::transaction::{
RevertedTransactionExecutionStatus, TransactionExecutionStatus, TransactionHash,
TransactionVersion,
};

#[test]
fn test_receipt_hash_regression() {
let mut transaction_receipt = ReceiptElement {
let transaction_receipt = ReceiptElement {
transaction_hash: TransactionHash(Felt::from(1234_u16)),
transaction_output: get_transaction_output(),
transaction_version: TransactionVersion::TWO,
};
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 = felt!("0x06cb27bfc55dee54e6d0fc7a6790e39f0f3c003576d50f7b8e8a1be24c351bcf");
assert_eq!(
calculate_receipt_hash(&transaction_receipt, l1_data_gas_price, l1_gas_price),
expected_hash
);
let expected_hash = felt!("0x6276abf21e7c68b2eecfdc8a845b11b44401901f5f040efe10c60d625049646");
assert_eq!(calculate_receipt_hash(&transaction_receipt), expected_hash);

let expected_root = ReceiptCommitment(felt!(
"0x03a0af1272fc3b0b83894fd7b6b70d89acb07772bc28efc9091e3cc1c2c72493"
"0x31963cb891ebb825e83514deb748c89b6967b5368cbc48a9b56193a1464ca87"
));

// Test for a V3 transactions.
transaction_receipt.transaction_version = TransactionVersion::THREE;
assert_eq!(
calculate_receipt_commitment::<Poseidon>(
&[transaction_receipt],
l1_data_gas_price,
l1_gas_price
),
expected_root
);
assert_eq!(calculate_receipt_commitment::<Poseidon>(&[transaction_receipt]), expected_root);
}

#[test]
Expand Down
1 change: 1 addition & 0 deletions src/block_hash/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub(crate) fn get_transaction_output() -> TransactionOutputCommon {
memory_holes: 76,
da_l1_gas_consumed: 54,
da_l1_data_gas_consumed: 32,
l1_gas_consumed: 16580,
};
TransactionOutputCommon {
actual_fee: Fee(99804),
Expand Down
1 change: 1 addition & 0 deletions src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -966,6 +966,7 @@ pub struct ExecutionResources {
pub memory_holes: u64,
pub da_l1_gas_consumed: u64,
pub da_l1_data_gas_consumed: u64,
pub l1_gas_consumed: u64,
}

#[derive(Hash, Debug, Deserialize, Serialize, Clone, Eq, PartialEq)]
Expand Down

0 comments on commit e5f4bc7

Please sign in to comment.