Skip to content

Commit

Permalink
changes after the rebase
Browse files Browse the repository at this point in the history
  • Loading branch information
maciejka committed May 8, 2024
1 parent 355af0a commit b5fac83
Show file tree
Hide file tree
Showing 11 changed files with 129 additions and 117 deletions.
5 changes: 3 additions & 2 deletions src/block_hash/event_hash.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use starknet_types_core::felt::Felt;

use crate::core::EventCommitment;
use crate::crypto::utils::HashChain;
use crate::hash::StarkFelt;
use crate::transaction::{Event, TransactionHash};

#[cfg(test)]
Expand All @@ -13,7 +14,7 @@ mod event_hash_test;
/// num_contents, content0, content1, ...
/// ).
pub fn calculate_event_hash(event: &Event, transaction_hash: &TransactionHash) -> EventCommitment {
let keys = &event.content.keys.iter().map(|k| k.0).collect::<Vec<StarkFelt>>();
let keys = &event.content.keys.iter().map(|k| k.0).collect::<Vec<Felt>>();
let data = &event.content.data.0;
EventCommitment(
HashChain::new()
Expand Down
21 changes: 11 additions & 10 deletions src/block_hash/event_hash_test.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
use starknet_types_core::felt::Felt;

use super::calculate_event_hash;
use crate::core::{ContractAddress, EventCommitment, PatriciaKey};
use crate::hash::{StarkFelt, StarkHash};
use crate::hash::StarkHash;
use crate::transaction::{Event, EventContent, EventData, EventKey, TransactionHash};
use crate::{contract_address, patricia_key, stark_felt};
use crate::{contract_address, patricia_key};

#[test]
fn test_event_hash_regression() {
let event = Event {
from_address: contract_address!(10_u8),
from_address: contract_address!("0xA"),
content: EventContent {
keys: [2_u8, 3].iter().map(|key| EventKey(stark_felt!(*key))).collect(),
data: EventData([4_u8, 5, 6].into_iter().map(StarkFelt::from).collect()),
keys: [2_u8, 3].iter().map(|key| EventKey(Felt::from(*key))).collect(),
data: EventData([4_u8, 5, 6].into_iter().map(Felt::from).collect()),
},
};
let tx_hash = TransactionHash(stark_felt!("0x1234"));
let tx_hash = TransactionHash(Felt::from_hex_unchecked("0x1234"));

let expected_hash = EventCommitment(
StarkFelt::try_from("0x367807f532742a4dcbe2d8a47b974b22dd7496faa75edc64a3a5fdb6709057")
.unwrap(),
);
let expected_hash = EventCommitment(Felt::from_hex_unchecked(
"0x367807f532742a4dcbe2d8a47b974b22dd7496faa75edc64a3a5fdb6709057",
));

assert_eq!(expected_hash, calculate_event_hash(&event, &tx_hash));
}
16 changes: 9 additions & 7 deletions src/block_hash/receipt_commitment.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use starknet_types_core::felt::Felt;
use starknet_types_core::hash::StarkHash;

use crate::core::ReceiptCommitment;
use crate::crypto::patricia_hash::calculate_root;
use crate::crypto::utils::HashChain;
use crate::hash::{HashFunction, StarkFelt};
use crate::transaction::{
ExecutionResources, MessageToL1, TransactionExecutionStatus, TransactionReceipt,
};
Expand All @@ -16,7 +18,7 @@ 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>(
pub fn calculate_receipt_commitment<H: StarkHash>(
transactions_receipt: &[TransactionReceipt],
) -> ReceiptCommitment {
ReceiptCommitment(calculate_root::<H>(
Expand All @@ -28,7 +30,7 @@ pub fn calculate_receipt_commitment<H: HashFunction>(
// 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) -> Felt {
let hash_chain = HashChain::new()
.chain(&transaction_receipt.transaction_hash)
.chain(&transaction_receipt.output.actual_fee().0.into())
Expand All @@ -43,7 +45,7 @@ fn calculate_receipt_hash(transaction_receipt: &TransactionReceipt) -> StarkFelt
// from_address_0, to_address_0, payload_length_0, payload_0,
// from_address_1, to_address_1, payload_length_1, payload_1, ...
// ).
fn calculate_messages_sent_hash(messages_sent: &Vec<MessageToL1>) -> StarkFelt {
fn calculate_messages_sent_hash(messages_sent: &Vec<MessageToL1>) -> Felt {
let mut messages_hash_chain = HashChain::new().chain(&messages_sent.len().into());
for message_sent in messages_sent {
messages_hash_chain = messages_hash_chain
Expand All @@ -55,9 +57,9 @@ fn calculate_messages_sent_hash(messages_sent: &Vec<MessageToL1>) -> StarkFelt {
}

// Returns starknet-keccak of the revert reason ASCII string, or 0 if the transaction succeeded.
fn get_revert_reason(execution_status: &TransactionExecutionStatus) -> StarkFelt {
fn get_revert_reason(execution_status: &TransactionExecutionStatus) -> Felt {
match execution_status {
TransactionExecutionStatus::Succeeded => StarkFelt::ZERO,
TransactionExecutionStatus::Succeeded => Felt::ZERO,
// TODO(yoav): Wrap the ASCII with a keccak.
TransactionExecutionStatus::Reverted(reason) => {
ascii_as_felt(&reason.revert_reason).expect("ascii_as_felt failed for revert reason")
Expand All @@ -79,7 +81,7 @@ fn chain_execution_resources(
+ execution_resources.builtin_instance_counter.values().sum::<u64>()
* L1_GAS_PER_BUILTIN_INSTANCE;
hash_chain
.chain(&StarkFelt::ZERO) // L2 gas consumed
.chain(&Felt::ZERO) // L2 gas consumed
.chain(&l1_gas_consumed.into())
.chain(&execution_resources.da_l1_data_gas_consumed.into())
}
37 changes: 17 additions & 20 deletions src/block_hash/receipt_commitment_test.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
use std::collections::HashMap;

use primitive_types::H160;
use starknet_types_core::felt::Felt;
use starknet_types_core::hash::Poseidon;

use super::calculate_messages_sent_hash;
use crate::block::{BlockHash, BlockNumber};
use crate::block_hash::receipt_commitment::{
calculate_receipt_commitment, calculate_receipt_hash, get_revert_reason,
};
use crate::core::{ContractAddress, EthAddress, ReceiptCommitment};
use crate::hash::{PoseidonHashCalculator, StarkFelt};
use crate::transaction::{
Builtin, ExecutionResources, Fee, InvokeTransactionOutput, L2ToL1Payload, MessageToL1,
RevertedTransactionExecutionStatus, TransactionExecutionStatus, TransactionHash,
Expand Down Expand Up @@ -36,52 +37,48 @@ fn test_receipt_hash_regression() {
execution_resources,
});
let transaction_receipt = TransactionReceipt {
transaction_hash: TransactionHash(StarkFelt::from(1234_u16)),
block_hash: BlockHash(StarkFelt::from(5678_u16)),
transaction_hash: TransactionHash(Felt::from(1234_u16)),
block_hash: BlockHash(Felt::from(5678_u16)),
block_number: BlockNumber(99),
output: invoke_output,
};

let expected_hash =
StarkFelt::try_from("0x0144fc581761cdaa8327d6d32d4120cddda36be0fda68e463efe0d49f141ccc7")
.unwrap();
let expected_hash = Felt::from_hex_unchecked(
"0x0144fc581761cdaa8327d6d32d4120cddda36be0fda68e463efe0d49f141ccc7",
);
assert_eq!(calculate_receipt_hash(&transaction_receipt), expected_hash);

let expected_root = ReceiptCommitment(
StarkFelt::try_from("0x03db8b2c479130ff1f1d718c593ee164849f89686e1a4c82e8a6abbf506852e8")
.unwrap(),
);
assert_eq!(
calculate_receipt_commitment::<PoseidonHashCalculator>(&[transaction_receipt]),
expected_root
);
let expected_root = ReceiptCommitment(Felt::from_hex_unchecked(
"0x03db8b2c479130ff1f1d718c593ee164849f89686e1a4c82e8a6abbf506852e8",
));
assert_eq!(calculate_receipt_commitment::<Poseidon>(&[transaction_receipt]), expected_root);
}

#[test]
fn test_messages_sent_regression() {
let messages_sent = vec![generate_message_to_l1(0), generate_message_to_l1(1)];
let messages_hash = calculate_messages_sent_hash(&messages_sent);
let expected_hash =
StarkFelt::try_from("0x00c89474a9007dc060aed76caf8b30b927cfea1ebce2d134b943b8d7121004e4")
.unwrap();
let expected_hash = Felt::from_hex_unchecked(
"0x00c89474a9007dc060aed76caf8b30b927cfea1ebce2d134b943b8d7121004e4",
);
assert_eq!(messages_hash, expected_hash);
}

fn generate_message_to_l1(seed: u64) -> MessageToL1 {
MessageToL1 {
from_address: ContractAddress::from(seed),
to_address: EthAddress(H160::from_low_u64_be(seed + 1)),
payload: L2ToL1Payload(vec![StarkFelt::from(seed + 2), StarkFelt::from(seed + 3)]),
payload: L2ToL1Payload(vec![Felt::from(seed + 2), Felt::from(seed + 3)]),
}
}

#[test]
fn test_revert_reason_regression() {
let execution_succeeded = TransactionExecutionStatus::Succeeded;
assert_eq!(get_revert_reason(&execution_succeeded), StarkFelt::ZERO);
assert_eq!(get_revert_reason(&execution_succeeded), Felt::ZERO);
let execution_reverted =
TransactionExecutionStatus::Reverted(RevertedTransactionExecutionStatus {
revert_reason: "ABC".to_string(),
});
assert_eq!(get_revert_reason(&execution_reverted), StarkFelt::from(0x414243_u32));
assert_eq!(get_revert_reason(&execution_reverted), Felt::from(0x414243_u32));
}
8 changes: 5 additions & 3 deletions src/block_hash/transaction_commitment.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use starknet_types_core::felt::Felt;
use starknet_types_core::hash::StarkHash;

use crate::core::TransactionCommitment;
use crate::crypto::patricia_hash::calculate_root;
use crate::crypto::utils::HashChain;
use crate::hash::{HashFunction, StarkFelt};
use crate::transaction::{TransactionHash, TransactionSignature};

#[cfg(test)]
Expand All @@ -17,15 +19,15 @@ pub struct TransactionLeafElements {

/// Returns the root of a Patricia tree where each leaf is
/// Poseidon(transaction_hash, transaction_signature).
pub fn calculate_transactions_commitment<H: HashFunction>(
pub fn calculate_transactions_commitment<H: StarkHash>(
transaction_leaf_elements: &[TransactionLeafElements],
) -> TransactionCommitment {
let transaction_leaves =
transaction_leaf_elements.iter().map(calculate_transaction_leaf).collect();
TransactionCommitment(calculate_root::<H>(transaction_leaves))
}

fn calculate_transaction_leaf(transaction_leaf_elements: &TransactionLeafElements) -> StarkFelt {
fn calculate_transaction_leaf(transaction_leaf_elements: &TransactionLeafElements) -> Felt {
HashChain::new()
.chain(&transaction_leaf_elements.transaction_hash.0)
.chain_iter(transaction_leaf_elements.transaction_signature.0.iter())
Expand Down
26 changes: 14 additions & 12 deletions src/block_hash/transaction_commitment_test.rs
Original file line number Diff line number Diff line change
@@ -1,38 +1,40 @@
use starknet_types_core::felt::Felt;
use starknet_types_core::hash::Poseidon;

use crate::block_hash::transaction_commitment::{
calculate_transaction_leaf, calculate_transactions_commitment, TransactionLeafElements,
};
use crate::core::TransactionCommitment;
use crate::hash::{PoseidonHashCalculator, StarkFelt};
use crate::transaction::{TransactionHash, TransactionSignature};

#[test]
fn test_transaction_leaf_regression() {
let transaction_hash = TransactionHash(StarkFelt::ONE);
let transaction_signature = TransactionSignature(vec![StarkFelt::TWO, StarkFelt::THREE]);
let transaction_hash = TransactionHash(Felt::ONE);
let transaction_signature = TransactionSignature(vec![Felt::TWO, Felt::THREE]);
let transaction_leaf_elements =
TransactionLeafElements { transaction_hash, transaction_signature };

let expected_leaf =
StarkFelt::try_from("0x2f0d8840bcf3bc629598d8a6cc80cb7c0d9e52d93dab244bbf9cd0dca0ad082")
.unwrap();
let expected_leaf = Felt::from_hex_unchecked(
"0x2f0d8840bcf3bc629598d8a6cc80cb7c0d9e52d93dab244bbf9cd0dca0ad082",
);

assert_eq!(expected_leaf, calculate_transaction_leaf(&transaction_leaf_elements));
}

#[test]
fn test_transactions_commitment_regression() {
let transaction_hash = TransactionHash(StarkFelt::ONE);
let transaction_signature = TransactionSignature(vec![StarkFelt::TWO, StarkFelt::THREE]);
let transaction_hash = TransactionHash(Felt::ONE);
let transaction_signature = TransactionSignature(vec![Felt::TWO, Felt::THREE]);
let transaction_leaf_elements =
TransactionLeafElements { transaction_hash, transaction_signature };

let expected_root =
StarkFelt::try_from("0x0282b635972328bd1cfa86496fe920d20bd9440cd78ee8dc90ae2b383d664dcf")
.unwrap();
let expected_root = Felt::from_hex_unchecked(
"0x0282b635972328bd1cfa86496fe920d20bd9440cd78ee8dc90ae2b383d664dcf",
);

assert_eq!(
TransactionCommitment(expected_root),
calculate_transactions_commitment::<PoseidonHashCalculator>(&[
calculate_transactions_commitment::<Poseidon>(&[
transaction_leaf_elements.clone(),
transaction_leaf_elements
],)
Expand Down
2 changes: 1 addition & 1 deletion src/block_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use starknet_types_core::felt::Felt;
use super::verify_block_signature;
use crate::block::{BlockHash, BlockNumber, BlockSignature};
use crate::core::{GlobalRoot, SequencerPublicKey};
use crate::crypto::{PublicKey, Signature};
use crate::crypto::utils::{PublicKey, Signature};

#[test]
fn test_block_number_iteration() {
Expand Down
21 changes: 10 additions & 11 deletions src/crypto/patricia_hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ mod patricia_hash_test;

use bitvec::prelude::{BitArray, Msb0};
use starknet_types_core::felt::Felt;

use crate::hash::{HashFunction, StarkFelt};
use starknet_types_core::hash::StarkHash;

const TREE_HEIGHT: u8 = 64;
type BitPath = BitArray<[u8; 8], Msb0>;
Expand All @@ -36,7 +35,7 @@ type BitPath = BitArray<[u8; 8], Msb0>;
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Entry {
key: BitPath,
value: StarkFelt,
value: Felt,
}

// A sub-tree is defined by a sub-sequence of leaves with a common ancestor at the specified height,
Expand All @@ -57,9 +56,9 @@ enum SubTreeSplitting {

/// Calculates Patricia hash root on the given values.
/// The values are keyed by consecutive numbers, starting from 0.
pub fn calculate_root<H: HashFunction>(values: Vec<StarkFelt>) -> StarkFelt {
pub fn calculate_root<H: StarkHash>(values: Vec<Felt>) -> Felt {
if values.is_empty() {
return StarkFelt::ZERO;
return Felt::ZERO;
}
let leaves: Vec<Entry> = values
.into_iter()
Expand All @@ -74,7 +73,7 @@ pub fn calculate_root<H: HashFunction>(values: Vec<StarkFelt>) -> StarkFelt {
// - Edge: All the keys start with a longest common ('0's) prefix. NOTE: We assume that the keys are
// a continuous range, and hence the case of '1's in the longest common prefix is impossible.
// - Binary: Some keys start with '0' bit and some start with '1' bit.
fn get_hash<H: HashFunction>(sub_tree: SubTree<'_>) -> StarkFelt {
fn get_hash<H: StarkHash>(sub_tree: SubTree<'_>) -> Felt {
if sub_tree.height == TREE_HEIGHT {
return sub_tree.leaves.first().expect("a leaf should not be empty").value;
}
Expand All @@ -87,16 +86,16 @@ fn get_hash<H: HashFunction>(sub_tree: SubTree<'_>) -> StarkFelt {
}

// Hash on a '0's sequence with the bottom sub tree.
fn get_edge_hash<H: HashFunction>(sub_tree: SubTree<'_>, n_zeros: u8) -> StarkFelt {
fn get_edge_hash<H: StarkHash>(sub_tree: SubTree<'_>, n_zeros: u8) -> Felt {
let child_hash =
get_hash::<H>(SubTree { leaves: sub_tree.leaves, height: sub_tree.height + n_zeros });
let child_and_path_hash = H::hash_pair(&child_hash, &StarkFelt::ZERO);
StarkFelt::from(Felt::from(&child_and_path_hash) + Felt::from(n_zeros))
let child_and_path_hash = H::hash(&child_hash, &Felt::ZERO);
Felt::from(child_and_path_hash + Felt::from(n_zeros))
}

// Hash on both sides: starts with '0' bit and starts with '1' bit.
// Assumes: 0 < partition point < sub_tree.len().
fn get_binary_hash<H: HashFunction>(sub_tree: SubTree<'_>, partition_point: usize) -> StarkFelt {
fn get_binary_hash<H: StarkHash>(sub_tree: SubTree<'_>, partition_point: usize) -> Felt {
let zero_hash = get_hash::<H>(SubTree {
leaves: &sub_tree.leaves[..partition_point],
height: sub_tree.height + 1,
Expand All @@ -105,7 +104,7 @@ fn get_binary_hash<H: HashFunction>(sub_tree: SubTree<'_>, partition_point: usiz
leaves: &sub_tree.leaves[partition_point..],
height: sub_tree.height + 1,
});
H::hash_pair(&zero_hash, &one_hash)
H::hash(&zero_hash, &one_hash)
}

// Returns the manner the keys of a subtree are splitting: some keys start with '1' or all keys
Expand Down
Loading

0 comments on commit b5fac83

Please sign in to comment.