diff --git a/src/block.rs b/src/block.rs index df71ead..a4037db 100644 --- a/src/block.rs +++ b/src/block.rs @@ -6,6 +6,7 @@ use std::fmt::Display; use derive_more::Display; use serde::{Deserialize, Serialize}; +use starknet_types_core::hash::{Poseidon, StarkHash as CoreStarkHash}; use crate::core::{ EventCommitment, GlobalRoot, ReceiptCommitment, SequencerContractAddress, SequencerPublicKey, @@ -13,7 +14,7 @@ use crate::core::{ }; use crate::crypto::utils::{verify_message_hash_signature, CryptoError, Signature}; use crate::data_availability::L1DataAvailabilityMode; -use crate::hash::{poseidon_hash_array, StarkHash}; +use crate::hash::StarkHash; use crate::serde_utils::{BytesAsHex, PrefixedBytesAsHex}; use crate::transaction::{Transaction, TransactionHash, TransactionOutput}; @@ -233,8 +234,8 @@ pub fn verify_block_signature( state_diff_commitment: &GlobalRoot, block_hash: &BlockHash, ) -> Result { - let message_hash = poseidon_hash_array(&[block_hash.0, state_diff_commitment.0]); - verify_message_hash_signature(&message_hash.0, &signature.0, &sequencer_pub_key.0).map_err( + let message_hash = Poseidon::hash_array(&[block_hash.0, state_diff_commitment.0]); + verify_message_hash_signature(&message_hash, &signature.0, &sequencer_pub_key.0).map_err( |err| BlockVerificationError::BlockSignatureVerificationFailed { block_hash: *block_hash, error: err, diff --git a/src/block_hash/block_hash_calculator.rs b/src/block_hash/block_hash_calculator.rs index 02015e1..87afbf6 100644 --- a/src/block_hash/block_hash_calculator.rs +++ b/src/block_hash/block_hash_calculator.rs @@ -1,4 +1,6 @@ use once_cell::sync::Lazy; +use starknet_types_core::felt::Felt; +use starknet_types_core::hash::Poseidon; use super::event_commitment::{calculate_events_commitment, EventLeafElement}; use super::receipt_commitment::{calculate_receipt_commitment, ReceiptElement}; @@ -8,7 +10,6 @@ use crate::block::{BlockHash, BlockHeaderWithoutHash, GasPricePerToken}; use crate::core::{EventCommitment, ReceiptCommitment, StateDiffCommitment, TransactionCommitment}; use crate::crypto::utils::HashChain; use crate::data_availability::L1DataAvailabilityMode; -use crate::hash::{PoseidonHashCalculator, StarkFelt}; use crate::state::ThinStateDiff; use crate::transaction::{ TransactionHash, TransactionOutputCommon, TransactionSignature, TransactionVersion, @@ -19,7 +20,7 @@ use crate::transaction_hash::ascii_as_felt; #[path = "block_hash_calculator_test.rs"] mod block_hash_calculator_test; -static STARKNET_BLOCK_HASH0: Lazy = Lazy::new(|| { +static STARKNET_BLOCK_HASH0: Lazy = Lazy::new(|| { ascii_as_felt("STARKNET_BLOCK_HASH0").expect("ascii_as_felt failed for 'STARKNET_BLOCK_HASH0'") }); @@ -36,7 +37,7 @@ pub struct BlockHeaderCommitments { pub events_commitment: EventCommitment, pub receipts_commitment: ReceiptCommitment, pub state_diff_commitment: StateDiffCommitment, - pub concatenated_counts: StarkFelt, + pub concatenated_counts: Felt, } /// Poseidon ( @@ -66,7 +67,7 @@ pub fn calculate_block_hash( .chain(&header.l1_data_gas_price.price_in_wei.0.into()) .chain(&header.l1_data_gas_price.price_in_fri.0.into()) .chain(&ascii_as_felt(&header.starknet_version.0).expect("Expect ASCII version")) - .chain(&StarkFelt::ZERO) + .chain(&Felt::ZERO) .chain(&header.parent_hash.0) .get_poseidon_hash(), ) @@ -83,7 +84,7 @@ pub fn calculate_block_commitments( let transaction_leaf_elements: Vec = transactions_data.iter().map(TransactionLeafElement::from).collect(); let transactions_commitment = - calculate_transactions_commitment::(&transaction_leaf_elements); + calculate_transactions_commitment::(&transaction_leaf_elements); let event_leaf_elements: Vec = transactions_data .iter() @@ -94,12 +95,11 @@ pub fn calculate_block_commitments( }) }) .collect(); - let events_commitment = - calculate_events_commitment::(&event_leaf_elements); + let events_commitment = calculate_events_commitment::(&event_leaf_elements); let receipt_elements: Vec = transactions_data.iter().map(ReceiptElement::from).collect(); - let receipts_commitment = calculate_receipt_commitment::( + let receipts_commitment = calculate_receipt_commitment::( &receipt_elements, l1_data_gas_price_per_token, l1_gas_price_per_token, @@ -129,7 +129,7 @@ fn concat_counts( event_count: usize, state_diff_length: usize, l1_data_availability_mode: L1DataAvailabilityMode, -) -> StarkFelt { +) -> Felt { let l1_data_availability_byte: u8 = match l1_data_availability_mode { L1DataAvailabilityMode::Calldata => 0, L1DataAvailabilityMode::Blob => 0b10000000, @@ -142,7 +142,7 @@ fn concat_counts( &[0_u8; 7], // zero padding ] .concat(); - StarkFelt::new_unchecked(concat_bytes.try_into().expect("Expect 32 bytes")) + Felt::from_bytes_be_slice(concat_bytes.as_slice()) } fn to_64_bits(num: usize) -> [u8; 8] { diff --git a/src/block_hash/block_hash_calculator_test.rs b/src/block_hash/block_hash_calculator_test.rs index ff3baae..0d6d465 100644 --- a/src/block_hash/block_hash_calculator_test.rs +++ b/src/block_hash/block_hash_calculator_test.rs @@ -1,3 +1,5 @@ +use starknet_types_core::felt::Felt; + use super::concat_counts; use crate::block::{ BlockHash, BlockHeaderWithoutHash, BlockNumber, BlockTimestamp, GasPrice, GasPricePerToken, @@ -9,14 +11,15 @@ use crate::block_hash::block_hash_calculator::{ use crate::block_hash::test_utils::{get_state_diff, get_transaction_output}; use crate::core::{ContractAddress, GlobalRoot, PatriciaKey, SequencerContractAddress}; use crate::data_availability::L1DataAvailabilityMode; -use crate::hash::StarkFelt; +use crate::felt; +use crate::hash::{FeltConverter, TryIntoFelt}; use crate::transaction::{TransactionHash, TransactionSignature, TransactionVersion}; #[test] fn test_block_hash_regression() { let block_header = BlockHeaderWithoutHash { block_number: BlockNumber(1_u64), - state_root: GlobalRoot(StarkFelt::from(2_u8)), + state_root: GlobalRoot(Felt::from(2_u8)), sequencer: SequencerContractAddress(ContractAddress(PatriciaKey::from(3_u8))), timestamp: BlockTimestamp(4), l1_da_mode: L1DataAvailabilityMode::Blob, @@ -26,12 +29,12 @@ fn test_block_hash_regression() { price_in_wei: GasPrice(9), }, starknet_version: StarknetVersion("10".to_owned()), - parent_hash: BlockHash(StarkFelt::from(11_u8)), + parent_hash: BlockHash(Felt::from(11_u8)), }; let transactions_data = vec![TransactionHashingData { - transaction_signature: Some(TransactionSignature(vec![StarkFelt::TWO, StarkFelt::THREE])), + transaction_signature: Some(TransactionSignature(vec![Felt::TWO, Felt::THREE])), transaction_output: get_transaction_output(), - transaction_hash: TransactionHash(StarkFelt::ONE), + transaction_hash: TransactionHash(Felt::ONE), transaction_version: TransactionVersion::THREE, }]; @@ -44,9 +47,7 @@ fn test_block_hash_regression() { block_header.l1_da_mode, ); - let expected_hash = - StarkFelt::try_from("0x061e4998d51a248f1d0288d7e17f6287757b0e5e6c5e1e58ddf740616e312134") - .unwrap(); + let expected_hash = felt!("0x061e4998d51a248f1d0288d7e17f6287757b0e5e6c5e1e58ddf740616e312134"); assert_eq!(BlockHash(expected_hash), calculate_block_hash(block_header, block_commitments),); } @@ -54,8 +55,6 @@ fn test_block_hash_regression() { #[test] fn concat_counts_test() { let concated = concat_counts(4, 3, 2, L1DataAvailabilityMode::Blob); - let expected_felt = - StarkFelt::try_from("0x0000000000000004000000000000000300000000000000028000000000000000") - .unwrap(); + let expected_felt = felt!("0x0000000000000004000000000000000300000000000000028000000000000000"); assert_eq!(concated, expected_felt) } diff --git a/src/block_hash/event_commitment.rs b/src/block_hash/event_commitment.rs index f0e66b2..344dc25 100644 --- a/src/block_hash/event_commitment.rs +++ b/src/block_hash/event_commitment.rs @@ -1,7 +1,9 @@ +use starknet_types_core::felt::Felt; +use starknet_types_core::hash::StarkHash; + use crate::core::EventCommitment; use crate::crypto::patricia_hash::calculate_root; use crate::crypto::utils::HashChain; -use crate::hash::{HashFunction, StarkFelt}; use crate::transaction::{Event, TransactionHash}; #[cfg(test)] @@ -16,7 +18,7 @@ pub struct EventLeafElement { } /// Returns the root of a Patricia tree where each leaf is an event hash. -pub fn calculate_events_commitment( +pub fn calculate_events_commitment( event_leaf_elements: &[EventLeafElement], ) -> EventCommitment { let event_leaves = event_leaf_elements.iter().map(calculate_event_hash).collect(); @@ -28,9 +30,8 @@ pub fn calculate_events_commitment( // num_keys, key0, key1, ..., // num_contents, content0, content1, ... // ). -fn calculate_event_hash(event_leaf_element: &EventLeafElement) -> StarkFelt { - let keys = - &event_leaf_element.event.content.keys.iter().map(|k| k.0).collect::>(); +fn calculate_event_hash(event_leaf_element: &EventLeafElement) -> Felt { + let keys = &event_leaf_element.event.content.keys.iter().map(|k| k.0).collect::>(); let data = &event_leaf_element.event.content.data.0; HashChain::new() .chain(event_leaf_element.event.from_address.0.key()) diff --git a/src/block_hash/event_commitment_test.rs b/src/block_hash/event_commitment_test.rs index 80c0739..777d2b7 100644 --- a/src/block_hash/event_commitment_test.rs +++ b/src/block_hash/event_commitment_test.rs @@ -1,22 +1,22 @@ -use super::{calculate_event_hash, EventLeafElement}; -use crate::block_hash::event_commitment::calculate_events_commitment; +use starknet_types_core::felt::Felt; +use starknet_types_core::hash::Poseidon; + +use super::{calculate_event_hash, calculate_events_commitment, EventLeafElement}; use crate::core::{ContractAddress, EventCommitment, PatriciaKey}; -use crate::hash::{PoseidonHashCalculator, StarkFelt, StarkHash}; +use crate::hash::{FeltConverter, TryIntoFelt}; use crate::transaction::{Event, EventContent, EventData, EventKey, TransactionHash}; -use crate::{contract_address, patricia_key, stark_felt}; +use crate::{contract_address, felt, patricia_key}; #[test] fn test_events_commitment_regression() { let event_leaf_elements = [get_event_leaf_element(0), get_event_leaf_element(1), get_event_leaf_element(2)]; - let expected_root = - StarkFelt::try_from("0x069bb140ddbbeb01d81c7201ecfb933031306e45dab9c77ff9f9ba3cd4c2b9c3") - .unwrap(); + let expected_root = felt!("0x069bb140ddbbeb01d81c7201ecfb933031306e45dab9c77ff9f9ba3cd4c2b9c3"); assert_eq!( EventCommitment(expected_root), - calculate_events_commitment::(&event_leaf_elements), + calculate_events_commitment::(&event_leaf_elements), ); } @@ -24,9 +24,7 @@ fn test_events_commitment_regression() { fn test_event_hash_regression() { let event_leaf_element = get_event_leaf_element(2); - let expected_hash = - StarkFelt::try_from("0x367807f532742a4dcbe2d8a47b974b22dd7496faa75edc64a3a5fdb6709057") - .unwrap(); + let expected_hash = felt!("0x367807f532742a4dcbe2d8a47b974b22dd7496faa75edc64a3a5fdb6709057"); assert_eq!(expected_hash, calculate_event_hash(&event_leaf_element)); } @@ -34,14 +32,14 @@ fn test_event_hash_regression() { fn get_event_leaf_element(seed: u8) -> EventLeafElement { EventLeafElement { event: Event { - from_address: contract_address!(seed + 8), + from_address: contract_address!(format!("{:x}", seed + 8).as_str()), content: EventContent { - keys: [seed, seed + 1].iter().map(|key| EventKey(stark_felt!(*key))).collect(), + keys: [seed, seed + 1].iter().map(|key| EventKey(Felt::from(*key))).collect(), data: EventData( - [seed + 2, seed + 3, seed + 4].into_iter().map(StarkFelt::from).collect(), + [seed + 2, seed + 3, seed + 4].into_iter().map(Felt::from).collect(), ), }, }, - transaction_hash: TransactionHash(stark_felt!("0x1234")), + transaction_hash: TransactionHash(felt!("0x1234")), } } diff --git a/src/block_hash/receipt_commitment.rs b/src/block_hash/receipt_commitment.rs index 58f1306..e509ea3 100644 --- a/src/block_hash/receipt_commitment.rs +++ b/src/block_hash/receipt_commitment.rs @@ -1,9 +1,12 @@ +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, HashFunction, StarkFelt}; +use crate::hash::starknet_keccak_hash; use crate::transaction::{ ExecutionResources, Fee, MessageToL1, TransactionExecutionStatus, TransactionHash, TransactionOutputCommon, TransactionVersion, @@ -32,7 +35,7 @@ impl From<&TransactionHashingData> for ReceiptElement { } /// Returns the root of a Patricia tree where each leaf is a receipt hash. -pub fn calculate_receipt_commitment( +pub fn calculate_receipt_commitment( receipt_elements: &[ReceiptElement], l1_data_gas_price_per_token: GasPricePerToken, l1_gas_price_per_token: GasPricePerToken, @@ -55,7 +58,7 @@ fn calculate_receipt_hash( receipt_element: &ReceiptElement, l1_data_gas_price_per_token: GasPricePerToken, l1_gas_price_per_token: GasPricePerToken, -) -> StarkFelt { +) -> Felt { let l1_gas_price = get_price_by_version(l1_gas_price_per_token, &receipt_element.transaction_version); let l1_data_gas_price = @@ -80,7 +83,7 @@ fn calculate_receipt_hash( // 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) -> StarkFelt { +fn calculate_messages_sent_hash(messages_sent: &Vec) -> 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 @@ -92,9 +95,9 @@ fn calculate_messages_sent_hash(messages_sent: &Vec) -> StarkFelt { } // Returns starknet-keccak of the revert reason ASCII string, or 0 if the transaction succeeded. -fn get_revert_reason_hash(execution_status: &TransactionExecutionStatus) -> StarkFelt { +fn get_revert_reason_hash(execution_status: &TransactionExecutionStatus) -> Felt { match execution_status { - TransactionExecutionStatus::Succeeded => StarkFelt::ZERO, + TransactionExecutionStatus::Succeeded => Felt::ZERO, TransactionExecutionStatus::Reverted(reason) => { starknet_keccak_hash(reason.revert_reason.as_bytes()) } @@ -118,7 +121,7 @@ fn chain_execution_resources( - (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(&Felt::ZERO) // L2 gas consumed .chain(&l1_gas_consumed.into()) .chain(&execution_resources.da_l1_data_gas_consumed.into()) } diff --git a/src/block_hash/receipt_commitment_test.rs b/src/block_hash/receipt_commitment_test.rs index eb49f7b..fb34219 100644 --- a/src/block_hash/receipt_commitment_test.rs +++ b/src/block_hash/receipt_commitment_test.rs @@ -1,3 +1,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::{ @@ -5,7 +8,8 @@ use crate::block_hash::receipt_commitment::{ }; use crate::block_hash::test_utils::{generate_message_to_l1, get_transaction_output}; use crate::core::ReceiptCommitment; -use crate::hash::{PoseidonHashCalculator, StarkFelt}; +use crate::felt; +use crate::hash::{FeltConverter, TryIntoFelt}; use crate::transaction::{ RevertedTransactionExecutionStatus, TransactionExecutionStatus, TransactionHash, TransactionVersion, @@ -14,7 +18,7 @@ use crate::transaction::{ #[test] fn test_receipt_hash_regression() { let mut transaction_receipt = ReceiptElement { - transaction_hash: TransactionHash(StarkFelt::from(1234_u16)), + transaction_hash: TransactionHash(Felt::from(1234_u16)), transaction_output: get_transaction_output(), transaction_version: TransactionVersion::TWO, }; @@ -23,23 +27,20 @@ fn test_receipt_hash_regression() { let l1_gas_price = GasPricePerToken { price_in_fri: GasPrice(456), price_in_wei: GasPrice(789) }; - let expected_hash = - StarkFelt::try_from("0x06cb27bfc55dee54e6d0fc7a6790e39f0f3c003576d50f7b8e8a1be24c351bcf") - .unwrap(); + let expected_hash = felt!("0x06cb27bfc55dee54e6d0fc7a6790e39f0f3c003576d50f7b8e8a1be24c351bcf"); assert_eq!( calculate_receipt_hash(&transaction_receipt, l1_data_gas_price, l1_gas_price), expected_hash ); - let expected_root = ReceiptCommitment( - StarkFelt::try_from("0x03a0af1272fc3b0b83894fd7b6b70d89acb07772bc28efc9091e3cc1c2c72493") - .unwrap(), - ); + let expected_root = ReceiptCommitment(felt!( + "0x03a0af1272fc3b0b83894fd7b6b70d89acb07772bc28efc9091e3cc1c2c72493" + )); // Test for a V3 transactions. transaction_receipt.transaction_version = TransactionVersion::THREE; assert_eq!( - calculate_receipt_commitment::( + calculate_receipt_commitment::( &[transaction_receipt], l1_data_gas_price, l1_gas_price @@ -52,22 +53,18 @@ fn test_receipt_hash_regression() { 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!("0x00c89474a9007dc060aed76caf8b30b927cfea1ebce2d134b943b8d7121004e4"); assert_eq!(messages_hash, expected_hash); } #[test] fn test_revert_reason_hash_regression() { let execution_succeeded = TransactionExecutionStatus::Succeeded; - assert_eq!(get_revert_reason_hash(&execution_succeeded), StarkFelt::ZERO); + assert_eq!(get_revert_reason_hash(&execution_succeeded), Felt::ZERO); let execution_reverted = TransactionExecutionStatus::Reverted(RevertedTransactionExecutionStatus { revert_reason: "ABC".to_string(), }); - let expected_hash = - StarkFelt::try_from("0x01629b9dda060bb30c7908346f6af189c16773fa148d3366701fbaa35d54f3c8") - .unwrap(); + let expected_hash = felt!("0x01629b9dda060bb30c7908346f6af189c16773fa148d3366701fbaa35d54f3c8"); assert_eq!(get_revert_reason_hash(&execution_reverted), expected_hash); } diff --git a/src/block_hash/state_diff_hash.rs b/src/block_hash/state_diff_hash.rs index b881879..d588992 100644 --- a/src/block_hash/state_diff_hash.rs +++ b/src/block_hash/state_diff_hash.rs @@ -1,9 +1,10 @@ use indexmap::IndexMap; use once_cell::sync::Lazy; +use starknet_types_core::felt::Felt; use crate::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce, StateDiffCommitment}; use crate::crypto::utils::HashChain; -use crate::hash::{PoseidonHash, StarkFelt}; +use crate::hash::PoseidonHash; use crate::state::{StorageKey, ThinStateDiff}; use crate::transaction_hash::ascii_as_felt; @@ -11,7 +12,7 @@ use crate::transaction_hash::ascii_as_felt; #[path = "state_diff_hash_test.rs"] mod state_diff_hash_test; -static STARKNET_STATE_DIFF0: Lazy = Lazy::new(|| { +static STARKNET_STATE_DIFF0: Lazy = Lazy::new(|| { ascii_as_felt("STARKNET_STATE_DIFF0").expect("ascii_as_felt failed for 'STARKNET_STATE_DIFF0'") }); @@ -30,8 +31,8 @@ pub fn calculate_state_diff_hash(state_diff: &ThinStateDiff) -> StateDiffCommitm hash_chain = chain_declared_classes(&state_diff.declared_classes, hash_chain); hash_chain = chain_deprecated_declared_classes(&state_diff.deprecated_declared_classes, hash_chain); - hash_chain = hash_chain.chain(&StarkFelt::ONE) // placeholder. - .chain(&StarkFelt::ZERO); // placeholder. + hash_chain = hash_chain.chain(&Felt::ONE) // placeholder. + .chain(&Felt::ZERO); // placeholder. hash_chain = chain_storage_diffs(&state_diff.storage_diffs, hash_chain); hash_chain = chain_nonces(&state_diff.nonces, hash_chain); StateDiffCommitment(PoseidonHash(hash_chain.get_poseidon_hash())) @@ -82,7 +83,7 @@ fn chain_deprecated_declared_classes( // contract_address_1, number_of_updates_in_contract_1, key_0, value0, key1, value1, ..., // ] fn chain_storage_diffs( - storage_diffs: &IndexMap>, + storage_diffs: &IndexMap>, hash_chain: HashChain, ) -> HashChain { let mut n_updated_contracts = 0_u64; diff --git a/src/block_hash/state_diff_hash_test.rs b/src/block_hash/state_diff_hash_test.rs index 2c2cacc..6efe553 100644 --- a/src/block_hash/state_diff_hash_test.rs +++ b/src/block_hash/state_diff_hash_test.rs @@ -7,16 +7,16 @@ use crate::block_hash::state_diff_hash::{ use crate::block_hash::test_utils::get_state_diff; use crate::core::{ClassHash, CompiledClassHash, Nonce, StateDiffCommitment}; use crate::crypto::utils::HashChain; -use crate::hash::{PoseidonHash, StarkFelt}; +use crate::felt; +use crate::hash::{FeltConverter, PoseidonHash, TryIntoFelt}; #[test] fn test_state_diff_hash_regression() { let state_diff = get_state_diff(); - let expected_hash = StateDiffCommitment(PoseidonHash( - StarkFelt::try_from("0x0281f5966e49ad7dad9323826d53d1d27c0c4e6ebe5525e2e2fbca549bfa0a67") - .unwrap(), - )); + let expected_hash = StateDiffCommitment(PoseidonHash(felt!( + "0x0281f5966e49ad7dad9323826d53d1d27c0c4e6ebe5525e2e2fbca549bfa0a67" + ))); assert_eq!(expected_hash, calculate_state_diff_hash(&state_diff)); } diff --git a/src/block_hash/test_utils.rs b/src/block_hash/test_utils.rs index 35e9899..2bd7820 100644 --- a/src/block_hash/test_utils.rs +++ b/src/block_hash/test_utils.rs @@ -2,9 +2,9 @@ use std::collections::HashMap; use indexmap::indexmap; use primitive_types::H160; +use starknet_types_core::felt::Felt; use crate::core::{ClassHash, CompiledClassHash, ContractAddress, EthAddress, Nonce}; -use crate::hash::StarkFelt; use crate::state::ThinStateDiff; use crate::transaction::{ Builtin, ExecutionResources, Fee, L2ToL1Payload, MessageToL1, @@ -36,7 +36,7 @@ pub(crate) 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)]), } } diff --git a/src/block_hash/transaction_commitment.rs b/src/block_hash/transaction_commitment.rs index e766090..11a1a40 100644 --- a/src/block_hash/transaction_commitment.rs +++ b/src/block_hash/transaction_commitment.rs @@ -1,8 +1,10 @@ +use starknet_types_core::felt::Felt; +use starknet_types_core::hash::StarkHash as CoreStarkHash; + use super::block_hash_calculator::TransactionHashingData; 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)] @@ -28,7 +30,7 @@ impl From<&TransactionHashingData> for TransactionLeafElement { /// Returns the root of a Patricia tree where each leaf is /// H(transaction_hash, transaction_signature). /// The leaf of a transaction types without a signature field is: H(transaction_hash, 0). -pub fn calculate_transactions_commitment( +pub fn calculate_transactions_commitment( transaction_leaf_elements: &[TransactionLeafElement], ) -> TransactionCommitment { let transaction_leaves = @@ -36,14 +38,14 @@ pub fn calculate_transactions_commitment( TransactionCommitment(calculate_root::(transaction_leaves)) } -fn calculate_transaction_leaf(transaction_leaf_elements: &TransactionLeafElement) -> StarkFelt { +fn calculate_transaction_leaf(transaction_leaf_elements: &TransactionLeafElement) -> Felt { HashChain::new() .chain(&transaction_leaf_elements.transaction_hash.0) .chain_iter( transaction_leaf_elements .transaction_signature .as_ref() - .unwrap_or(&TransactionSignature(vec![StarkFelt::ZERO])) + .unwrap_or(&TransactionSignature(vec![Felt::ZERO])) .0 .iter(), ) diff --git a/src/block_hash/transaction_commitment_test.rs b/src/block_hash/transaction_commitment_test.rs index 1f7131e..0d4a330 100644 --- a/src/block_hash/transaction_commitment_test.rs +++ b/src/block_hash/transaction_commitment_test.rs @@ -1,17 +1,19 @@ +use starknet_types_core::felt::Felt; +use starknet_types_core::hash::Poseidon; + use super::TransactionLeafElement; use crate::block_hash::transaction_commitment::{ calculate_transaction_leaf, calculate_transactions_commitment, }; use crate::core::TransactionCommitment; -use crate::hash::{PoseidonHashCalculator, StarkFelt}; +use crate::felt; +use crate::hash::{FeltConverter, TryIntoFelt}; use crate::transaction::{TransactionHash, TransactionSignature}; #[test] fn test_transaction_leaf_regression() { let transaction_leaf_elements = get_transaction_leaf_element(); - let expected_leaf = - StarkFelt::try_from("0x2f0d8840bcf3bc629598d8a6cc80cb7c0d9e52d93dab244bbf9cd0dca0ad082") - .unwrap(); + let expected_leaf = felt!("0x2f0d8840bcf3bc629598d8a6cc80cb7c0d9e52d93dab244bbf9cd0dca0ad082"); assert_eq!(expected_leaf, calculate_transaction_leaf(&transaction_leaf_elements)); } @@ -19,12 +21,10 @@ fn test_transaction_leaf_regression() { #[test] fn test_transaction_leaf_without_signature_regression() { let transaction_leaf_elements = TransactionLeafElement { - transaction_hash: TransactionHash(StarkFelt::ONE), + transaction_hash: TransactionHash(Felt::ONE), transaction_signature: None, }; - let expected_leaf = - StarkFelt::try_from("0x00a93bf5e58b9378d093aa86ddc2f61a3295a1d1e665bd0ef3384dd07b30e033") - .unwrap(); + let expected_leaf = felt!("0x00a93bf5e58b9378d093aa86ddc2f61a3295a1d1e665bd0ef3384dd07b30e033"); assert_eq!(expected_leaf, calculate_transaction_leaf(&transaction_leaf_elements)); } @@ -32,21 +32,19 @@ fn test_transaction_leaf_without_signature_regression() { #[test] fn test_transactions_commitment_regression() { let transaction_leaf_elements = get_transaction_leaf_element(); - let expected_root = - StarkFelt::try_from("0x0282b635972328bd1cfa86496fe920d20bd9440cd78ee8dc90ae2b383d664dcf") - .unwrap(); + let expected_root = felt!("0x0282b635972328bd1cfa86496fe920d20bd9440cd78ee8dc90ae2b383d664dcf"); assert_eq!( TransactionCommitment(expected_root), - calculate_transactions_commitment::(&[ + calculate_transactions_commitment::(&[ transaction_leaf_elements.clone(), transaction_leaf_elements - ],) + ]) ); } fn get_transaction_leaf_element() -> TransactionLeafElement { - 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]); TransactionLeafElement { transaction_hash, transaction_signature: Some(transaction_signature) } } diff --git a/src/block_test.rs b/src/block_test.rs index 753c56d..0705918 100644 --- a/src/block_test.rs +++ b/src/block_test.rs @@ -2,8 +2,8 @@ use super::verify_block_signature; use crate::block::{BlockHash, BlockNumber, BlockSignature}; use crate::core::{GlobalRoot, SequencerPublicKey}; use crate::crypto::utils::{PublicKey, Signature}; -use crate::hash::StarkFelt; -use crate::stark_felt; +use crate::felt; +use crate::hash::{FeltConverter, TryIntoFelt}; #[test] fn test_block_number_iteration() { @@ -30,15 +30,14 @@ fn test_block_number_iteration() { fn block_signature_verification() { // Values taken from Mainnet. let block_hash = - BlockHash(stark_felt!("0x7d5db04c5ca2aea828180dc441afb1580e3cee7547a3567ced3aa5bb8b273c0")); - let state_commitment = GlobalRoot(stark_felt!( - "0x64689c12248e1110af4b3af0e2b43cd51ad13e8855f10e37669e2a4baf919c6" - )); + BlockHash(felt!("0x7d5db04c5ca2aea828180dc441afb1580e3cee7547a3567ced3aa5bb8b273c0")); + let state_commitment = + GlobalRoot(felt!("0x64689c12248e1110af4b3af0e2b43cd51ad13e8855f10e37669e2a4baf919c6")); let signature = BlockSignature(Signature { - r: stark_felt!("0x1b382bbfd693011c9b7692bc932b23ed9c288deb27c8e75772e172abbe5950c"), - s: stark_felt!("0xbe4438085057e1a7c704a0da3b30f7b8340fe3d24c86772abfd24aa597e42"), + r: felt!("0x1b382bbfd693011c9b7692bc932b23ed9c288deb27c8e75772e172abbe5950c"), + s: felt!("0xbe4438085057e1a7c704a0da3b30f7b8340fe3d24c86772abfd24aa597e42"), }); - let sequencer_pub_key = SequencerPublicKey(PublicKey(stark_felt!( + let sequencer_pub_key = SequencerPublicKey(PublicKey(felt!( "0x48253ff2c3bed7af18bde0b611b083b39445959102d4947c51c4db6aa4f4e58" ))); diff --git a/src/core.rs b/src/core.rs index d7bc8f9..d3349e0 100644 --- a/src/core.rs +++ b/src/core.rs @@ -9,10 +9,11 @@ use derive_more::Display; use once_cell::sync::Lazy; use primitive_types::H160; use serde::{Deserialize, Deserializer, Serialize, Serializer}; -use starknet_crypto::FieldElement; +use starknet_types_core::felt::{Felt, NonZeroFelt}; +use starknet_types_core::hash::{Pedersen, StarkHash as CoreStarkHash}; use crate::crypto::utils::PublicKey; -use crate::hash::{pedersen_hash_array, PoseidonHash, StarkFelt, StarkHash}; +use crate::hash::{PoseidonHash, StarkHash}; use crate::serde_utils::{BytesAsHex, PrefixedBytesAsHex}; use crate::transaction::{Calldata, ContractAddressSalt}; use crate::{impl_from_through_intermediate, StarknetApiError}; @@ -94,8 +95,8 @@ pub const BLOCK_HASH_TABLE_ADDRESS: ContractAddress = ContractAddress(PatriciaKe )] pub struct ContractAddress(pub PatriciaKey); -impl From for StarkFelt { - fn from(contract_address: ContractAddress) -> StarkFelt { +impl From for Felt { + fn from(contract_address: ContractAddress) -> Felt { **contract_address } } @@ -113,13 +114,10 @@ pub const MAX_STORAGE_ITEM_SIZE: u16 = 256; /// The prefix used in the calculation of a contract address. pub const CONTRACT_ADDRESS_PREFIX: &str = "STARKNET_CONTRACT_ADDRESS"; /// The size of the contract address domain. -pub static CONTRACT_ADDRESS_DOMAIN_SIZE: Lazy = Lazy::new(|| { - StarkFelt::try_from(PATRICIA_KEY_UPPER_BOUND) - .unwrap_or_else(|_| panic!("Failed to convert {PATRICIA_KEY_UPPER_BOUND} to StarkFelt")) -}); +pub const CONTRACT_ADDRESS_DOMAIN_SIZE: Felt = Felt::from_hex_unchecked(PATRICIA_KEY_UPPER_BOUND); /// The address upper bound; it is defined to be congruent with the storage var address upper bound. -pub static L2_ADDRESS_UPPER_BOUND: Lazy = Lazy::new(|| { - FieldElement::from(*CONTRACT_ADDRESS_DOMAIN_SIZE) - FieldElement::from(MAX_STORAGE_ITEM_SIZE) +pub static L2_ADDRESS_UPPER_BOUND: Lazy = Lazy::new(|| { + NonZeroFelt::try_from(CONTRACT_ADDRESS_DOMAIN_SIZE - Felt::from(MAX_STORAGE_ITEM_SIZE)).unwrap() }); impl TryFrom for ContractAddress { @@ -136,18 +134,20 @@ pub fn calculate_contract_address( constructor_calldata: &Calldata, deployer_address: ContractAddress, ) -> Result { - let constructor_calldata_hash = pedersen_hash_array(&constructor_calldata.0); + let constructor_calldata_hash = Pedersen::hash_array(&constructor_calldata.0); let contract_address_prefix = format!("0x{}", hex::encode(CONTRACT_ADDRESS_PREFIX)); - let mut address = FieldElement::from(pedersen_hash_array(&[ - StarkFelt::try_from(contract_address_prefix.as_str())?, + let address = Pedersen::hash_array(&[ + Felt::from_hex(contract_address_prefix.as_str()).map_err(|_| { + StarknetApiError::OutOfRange { string: contract_address_prefix.clone() } + })?, *deployer_address.0.key(), salt.0, class_hash.0, constructor_calldata_hash, - ])); - address = address % *L2_ADDRESS_UPPER_BOUND; + ]); + let (_, address) = address.div_rem(&L2_ADDRESS_UPPER_BOUND); - ContractAddress::try_from(StarkFelt::from(address)) + ContractAddress::try_from(address) } /// The hash of a ContractClass. @@ -200,17 +200,16 @@ pub struct CompiledClassHash(pub StarkHash); Ord, derive_more::Deref, )] -pub struct Nonce(pub StarkFelt); +pub struct Nonce(pub Felt); impl Nonce { pub fn try_increment(&self) -> Result { - let current_nonce = FieldElement::from(self.0); - // Check if an overflow occurred during increment. - match StarkFelt::from(current_nonce + FieldElement::ONE) { - StarkFelt::ZERO => Err(StarknetApiError::OutOfRange { string: format!("{:?}", self) }), - incremented_felt => Ok(Self(incremented_felt)), + let incremented = self.0 + Felt::ONE; + if incremented == Felt::ZERO { + return Err(StarknetApiError::OutOfRange { string: format!("{:?}", self) }); } + Ok(Self(incremented)) } } @@ -289,9 +288,7 @@ pub struct EventCommitment(pub StarkHash); )] pub struct ReceiptCommitment(pub StarkHash); -#[derive( - Debug, Copy, Clone, Default, Eq, PartialEq, Hash, Deserialize, Serialize, PartialOrd, Ord, -)] +#[derive(Debug, Clone, Default, Eq, PartialEq, Hash, Deserialize, Serialize, PartialOrd, Ord)] pub struct StateDiffCommitment(pub PoseidonHash); /// A key for nodes of a Patricia tree. @@ -323,7 +320,7 @@ impl PatriciaKey { impl From for PatriciaKey { fn from(val: u128) -> Self { - PatriciaKey::try_from(StarkFelt::from(val)).expect("Failed to convert u128 to PatriciaKey.") + PatriciaKey::try_from(Felt::from(val)).expect("Failed to convert u128 to PatriciaKey.") } } @@ -333,7 +330,7 @@ impl TryFrom for PatriciaKey { type Error = StarknetApiError; fn try_from(value: StarkHash) -> Result { - if value < *CONTRACT_ADDRESS_DOMAIN_SIZE { + if value < CONTRACT_ADDRESS_DOMAIN_SIZE { return Ok(PatriciaKey(value)); } Err(StarknetApiError::OutOfRange { string: format!("[0x0, {PATRICIA_KEY_UPPER_BOUND})") }) @@ -351,7 +348,7 @@ impl Debug for PatriciaKey { #[macro_export] macro_rules! patricia_key { ($s:expr) => { - PatriciaKey::try_from(StarkHash::try_from($s).unwrap()).unwrap() + PatriciaKey::try_from(felt!($s)).unwrap() }; } @@ -360,7 +357,7 @@ macro_rules! patricia_key { #[macro_export] macro_rules! class_hash { ($s:expr) => { - ClassHash(StarkHash::try_from($s).unwrap()) + ClassHash(felt!($s)) }; } @@ -381,12 +378,13 @@ macro_rules! contract_address { #[serde(try_from = "PrefixedBytesAsHex<20_usize>", into = "PrefixedBytesAsHex<20_usize>")] pub struct EthAddress(pub H160); -impl TryFrom for EthAddress { +impl TryFrom for EthAddress { type Error = StarknetApiError; - fn try_from(felt: StarkFelt) -> Result { - const COMPLIMENT_OF_H160: usize = std::mem::size_of::() - H160::len_bytes(); + fn try_from(felt: Felt) -> Result { + const COMPLIMENT_OF_H160: usize = std::mem::size_of::() - H160::len_bytes(); - let (rest, h160_bytes) = felt.bytes().split_at(COMPLIMENT_OF_H160); + let bytes = felt.to_bytes_be(); + let (rest, h160_bytes) = bytes.split_at(COMPLIMENT_OF_H160); if rest != [0u8; COMPLIMENT_OF_H160] { return Err(StarknetApiError::OutOfRange { string: felt.to_string() }); } @@ -395,12 +393,9 @@ impl TryFrom for EthAddress { } } -impl From for StarkFelt { +impl From for Felt { fn from(value: EthAddress) -> Self { - let mut bytes = [0u8; 32]; - // Padding H160 with zeros to 32 bytes (big endian) - bytes[12..32].copy_from_slice(value.0.as_bytes()); - StarkFelt::new_unchecked(bytes) + Felt::from_bytes_be_slice(value.0.as_bytes()) } } diff --git a/src/core_test.rs b/src/core_test.rs index 4058783..538bffc 100644 --- a/src/core_test.rs +++ b/src/core_test.rs @@ -1,17 +1,18 @@ use assert_matches::assert_matches; -use starknet_crypto::FieldElement; +use starknet_types_core::felt::Felt; +use starknet_types_core::hash::{Pedersen, StarkHash as CoreStarkHash}; use crate::core::{ calculate_contract_address, ClassHash, ContractAddress, EthAddress, Nonce, PatriciaKey, StarknetApiError, CONTRACT_ADDRESS_PREFIX, L2_ADDRESS_UPPER_BOUND, }; -use crate::hash::{pedersen_hash_array, StarkFelt, StarkHash}; +use crate::hash::{FeltConverter, StarkHash, TryIntoFelt}; use crate::transaction::{Calldata, ContractAddressSalt}; -use crate::{class_hash, patricia_key, stark_felt}; +use crate::{class_hash, felt, patricia_key}; #[test] fn patricia_key_valid() { - let hash = stark_felt!("0x123"); + let hash = felt!("0x123"); let patricia_key = PatriciaKey::try_from(hash).unwrap(); assert_eq!(patricia_key.0, hash); } @@ -19,7 +20,7 @@ fn patricia_key_valid() { #[test] fn patricia_key_out_of_range() { // 2**251 - let hash = stark_felt!("0x800000000000000000000000000000000000000000000000000000000000000"); + let hash = felt!("0x800000000000000000000000000000000000000000000000000000000000000"); let err = PatriciaKey::try_from(hash); assert_matches!(err, Err(StarknetApiError::OutOfRange { string: _err_str })); } @@ -28,47 +29,43 @@ fn patricia_key_out_of_range() { fn patricia_key_macro() { assert_eq!( patricia_key!("0x123"), - PatriciaKey::try_from( - StarkHash::new([ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0x1, 0x23 - ]) - .unwrap() - ) + PatriciaKey::try_from(StarkHash::from_bytes_be(&[ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0x1, 0x23 + ])) .unwrap() ); } #[test] fn test_calculate_contract_address() { - let salt = ContractAddressSalt(stark_felt!(1337_u16)); + let salt = ContractAddressSalt(Felt::from(1337_u16)); let class_hash = class_hash!("0x110"); let deployer_address = ContractAddress::default(); let constructor_calldata = - Calldata(vec![stark_felt!(60_u16), stark_felt!(70_u16), FieldElement::MAX.into()].into()); + Calldata(vec![Felt::from(60_u16), Felt::from(70_u16), Felt::MAX].into()); let actual_address = calculate_contract_address(salt, class_hash, &constructor_calldata, deployer_address) .unwrap(); - let constructor_calldata_hash = pedersen_hash_array(&constructor_calldata.0); - let address = pedersen_hash_array(&[ - StarkFelt::try_from(format!("0x{}", hex::encode(CONTRACT_ADDRESS_PREFIX)).as_str()) - .unwrap(), + let constructor_calldata_hash = Pedersen::hash_array(&constructor_calldata.0); + let address = Pedersen::hash_array(&[ + Felt::from_hex_unchecked(format!("0x{}", hex::encode(CONTRACT_ADDRESS_PREFIX)).as_str()), *deployer_address.0.key(), salt.0, class_hash.0, constructor_calldata_hash, ]); - let mod_address = FieldElement::from(address) % *L2_ADDRESS_UPPER_BOUND; - let expected_address = ContractAddress::try_from(StarkFelt::from(mod_address)).unwrap(); + let (_, mod_address) = address.div_rem(&L2_ADDRESS_UPPER_BOUND); + let expected_address = ContractAddress::try_from(mod_address).unwrap(); assert_eq!(actual_address, expected_address); } #[test] fn eth_address_serde() { - let eth_address = EthAddress::try_from(StarkFelt::try_from("0x001").unwrap()).unwrap(); + let eth_address = EthAddress::try_from(felt!("0x001")).unwrap(); let serialized = serde_json::to_string(ð_address).unwrap(); assert_eq!(serialized, r#""0x1""#); @@ -79,7 +76,7 @@ fn eth_address_serde() { #[test] fn nonce_overflow() { // Increment on this value should overflow back to 0. - let max_nonce = Nonce(StarkFelt::from(FieldElement::MAX)); + let max_nonce = Nonce(Felt::MAX); let overflowed_nonce = max_nonce.try_increment(); assert_matches!(overflowed_nonce, Err(StarknetApiError::OutOfRange { string: _err_str })); diff --git a/src/crypto/crypto_test.rs b/src/crypto/crypto_test.rs index 0807002..24d6042 100644 --- a/src/crypto/crypto_test.rs +++ b/src/crypto/crypto_test.rs @@ -1,25 +1,27 @@ // Unittest for verify_message_signature +use starknet_types_core::hash::{Poseidon, StarkHash}; + use crate::crypto::utils::{verify_message_hash_signature, PublicKey, Signature}; -use crate::hash::{poseidon_hash_array, StarkFelt}; -use crate::stark_felt; +use crate::felt; +use crate::hash::{FeltConverter, TryIntoFelt}; #[test] fn signature_verification() { // The signed message of block 4256. - let message_hash = poseidon_hash_array(&[ - stark_felt!("0x7d5db04c5ca2aea828180dc441afb1580e3cee7547a3567ced3aa5bb8b273c0"), - stark_felt!("0x64689c12248e1110af4b3af0e2b43cd51ad13e8855f10e37669e2a4baf919c6"), + let message_hash = Poseidon::hash_array(&[ + felt!("0x7d5db04c5ca2aea828180dc441afb1580e3cee7547a3567ced3aa5bb8b273c0"), + felt!("0x64689c12248e1110af4b3af0e2b43cd51ad13e8855f10e37669e2a4baf919c6"), ]); // The signature of the message. let signature = Signature { - r: stark_felt!("0x1b382bbfd693011c9b7692bc932b23ed9c288deb27c8e75772e172abbe5950c"), - s: stark_felt!("0xbe4438085057e1a7c704a0da3b30f7b8340fe3d24c86772abfd24aa597e42"), + r: felt!("0x1b382bbfd693011c9b7692bc932b23ed9c288deb27c8e75772e172abbe5950c"), + s: felt!("0xbe4438085057e1a7c704a0da3b30f7b8340fe3d24c86772abfd24aa597e42"), }; // The public key of the sequencer. let public_key = - PublicKey(stark_felt!("0x48253ff2c3bed7af18bde0b611b083b39445959102d4947c51c4db6aa4f4e58")); + PublicKey(felt!("0x48253ff2c3bed7af18bde0b611b083b39445959102d4947c51c4db6aa4f4e58")); - let result = verify_message_hash_signature(&message_hash.0, &signature, &public_key).unwrap(); + let result = verify_message_hash_signature(&message_hash, &signature, &public_key).unwrap(); assert!(result); } diff --git a/src/crypto/patricia_hash.rs b/src/crypto/patricia_hash.rs index bdf9597..41acf4e 100644 --- a/src/crypto/patricia_hash.rs +++ b/src/crypto/patricia_hash.rs @@ -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 as CoreStarkHash; const TREE_HEIGHT: u8 = 64; type BitPath = BitArray<[u8; 8], Msb0>; @@ -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, @@ -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(values: Vec) -> StarkFelt { +pub fn calculate_root(values: Vec) -> Felt { if values.is_empty() { - return StarkFelt::ZERO; + return Felt::ZERO; } let leaves: Vec = values .into_iter() @@ -74,7 +73,7 @@ pub fn calculate_root(values: Vec) -> 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(sub_tree: SubTree<'_>) -> StarkFelt { +fn get_hash(sub_tree: SubTree<'_>) -> Felt { if sub_tree.height == TREE_HEIGHT { return sub_tree.leaves.first().expect("a leaf should not be empty").value; } @@ -87,16 +86,16 @@ fn get_hash(sub_tree: SubTree<'_>) -> StarkFelt { } // Hash on a '0's sequence with the bottom sub tree. -fn get_edge_hash(sub_tree: SubTree<'_>, n_zeros: u8) -> StarkFelt { +fn get_edge_hash(sub_tree: SubTree<'_>, n_zeros: u8) -> Felt { let child_hash = get_hash::(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); + 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(sub_tree: SubTree<'_>, partition_point: usize) -> StarkFelt { +fn get_binary_hash(sub_tree: SubTree<'_>, partition_point: usize) -> Felt { let zero_hash = get_hash::(SubTree { leaves: &sub_tree.leaves[..partition_point], height: sub_tree.height + 1, @@ -105,7 +104,7 @@ fn get_binary_hash(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 diff --git a/src/crypto/patricia_hash_test.rs b/src/crypto/patricia_hash_test.rs index 8cdacd0..92c03bb 100644 --- a/src/crypto/patricia_hash_test.rs +++ b/src/crypto/patricia_hash_test.rs @@ -1,36 +1,28 @@ +use starknet_types_core::felt::Felt; +use starknet_types_core::hash::Poseidon; + use super::calculate_root; -use crate::hash::{PoseidonHashCalculator, StarkFelt}; +use crate::felt; +use crate::hash::{FeltConverter, TryIntoFelt}; #[test] fn test_patricia_regression() { - let root = calculate_root::(vec![ - StarkFelt::from(1_u8), - StarkFelt::from(2_u8), - StarkFelt::from(3_u8), - ]); - let expected_root = - StarkFelt::try_from("0x3b5cc7f1292eb3847c3f902d048a7e5dc7702d1c191ccd17c2d33f797e6fc32") - .unwrap(); + let root = + calculate_root::(vec![Felt::from(1_u8), Felt::from(2_u8), Felt::from(3_u8)]); + let expected_root = felt!("0x3b5cc7f1292eb3847c3f902d048a7e5dc7702d1c191ccd17c2d33f797e6fc32"); assert_eq!(root, expected_root); } #[test] fn test_edge_patricia_regression() { - let root = calculate_root::(vec![StarkFelt::from(1_u8)]); - let expected_root = - StarkFelt::try_from("0x7752582c54a42fe0fa35c40f07293bb7d8efe90e21d8d2c06a7db52d7d9b7e1") - .unwrap(); + let root = calculate_root::(vec![Felt::from(1_u8)]); + let expected_root = felt!("0x7752582c54a42fe0fa35c40f07293bb7d8efe90e21d8d2c06a7db52d7d9b7e1"); assert_eq!(root, expected_root); } #[test] fn test_binary_patricia_regression() { - let root = calculate_root::(vec![ - StarkFelt::from(1_u8), - StarkFelt::from(2_u8), - ]); - let expected_root = - StarkFelt::try_from("0x1c1ba983ee0a0de87d87d67ea3cbee7023aa65f6b7bcf71259f122ea3af80bf") - .unwrap(); + let root = calculate_root::(vec![Felt::from(1_u8), Felt::from(2_u8)]); + let expected_root = felt!("0x1c1ba983ee0a0de87d87d67ea3cbee7023aa65f6b7bcf71259f122ea3af80bf"); assert_eq!(root, expected_root); } diff --git a/src/crypto/utils.rs b/src/crypto/utils.rs index cc0bd1f..170de7e 100644 --- a/src/crypto/utils.rs +++ b/src/crypto/utils.rs @@ -2,52 +2,68 @@ //! This module provides cryptographic utilities. #[cfg(test)] #[path = "crypto_test.rs"] +#[allow(clippy::explicit_auto_deref)] mod crypto_test; +use std::fmt; +use std::fmt::LowerHex; + use serde::{Deserialize, Serialize}; -use starknet_crypto::{pedersen_hash, poseidon_hash_many, FieldElement}; +use starknet_types_core::felt::Felt; +use starknet_types_core::hash::{Pedersen, Poseidon, StarkHash as CoreStarkHash}; -use crate::hash::{StarkFelt, StarkHash}; +use crate::hash::StarkHash; /// An error that can occur during cryptographic operations. + #[derive(thiserror::Error, Clone, Debug)] pub enum CryptoError { - #[error("Invalid public key {0:?}.")] + #[error("Invalid public key {0:#x}.")] InvalidPublicKey(PublicKey), - #[error("Invalid message hash {0:?}.")] - InvalidMessageHash(StarkFelt), - #[error("Invalid r {0:?}.")] - InvalidR(StarkFelt), - #[error("Invalid s {0:?}.")] - InvalidS(StarkFelt), + #[error("Invalid message hash {0:#x}.")] + InvalidMessageHash(Felt), + #[error("Invalid r {0}.")] + InvalidR(Felt), + #[error("Invalid s {0}.")] + InvalidS(Felt), } /// A public key. #[derive( Debug, Default, Copy, Clone, Eq, PartialEq, Hash, Deserialize, Serialize, PartialOrd, Ord, )] -pub struct PublicKey(pub StarkFelt); +pub struct PublicKey(pub Felt); + +impl LowerHex for PublicKey { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::LowerHex::fmt(&self.0, f) + } +} /// A signature. #[derive( Debug, Default, Copy, Clone, Eq, PartialEq, Hash, Deserialize, Serialize, PartialOrd, Ord, )] pub struct Signature { - pub r: StarkFelt, - pub s: StarkFelt, + pub r: Felt, + pub s: Felt, +} + +fn to_field_element(felt: &Felt) -> starknet_crypto::FieldElement { + starknet_crypto::FieldElement::from_mont(felt.to_raw_reversed()) } /// Verifies the authenticity of a signed message hash given the public key of the signer. pub fn verify_message_hash_signature( - message_hash: &StarkFelt, + message_hash: &Felt, signature: &Signature, public_key: &PublicKey, ) -> Result { starknet_crypto::verify( - &public_key.0.into(), - &FieldElement::from(*message_hash), - &signature.r.into(), - &signature.s.into(), + &to_field_element(&public_key.0), + &to_field_element(message_hash), + &to_field_element(&signature.r), + &to_field_element(&signature.s), ) .map_err(|err| match err { starknet_crypto::VerifyError::InvalidPublicKey => { @@ -63,7 +79,7 @@ pub fn verify_message_hash_signature( // Collect elements for applying hash chain. pub(crate) struct HashChain { - elements: Vec, + elements: Vec, } impl HashChain { @@ -72,13 +88,13 @@ impl HashChain { } // Chains a felt to the hash chain. - pub fn chain(mut self, felt: &StarkFelt) -> Self { - self.elements.push(FieldElement::from(*felt)); + pub fn chain(mut self, felt: &Felt) -> Self { + self.elements.push(*felt); self } // Chains the result of a function to the hash chain. - pub fn chain_if_fn Option>(self, f: F) -> Self { + pub fn chain_if_fn Option>(self, f: F) -> Self { match f() { Some(felt) => self.chain(&felt), None => self, @@ -86,12 +102,12 @@ impl HashChain { } // Chains many felts to the hash chain. - pub fn chain_iter<'a>(self, felts: impl Iterator) -> Self { + pub fn chain_iter<'a>(self, felts: impl Iterator) -> Self { felts.fold(self, |current, felt| current.chain(felt)) } // Chains the number of felts followed by the felts themselves to the hash chain. - pub fn chain_size_and_elements(self, felts: &[StarkFelt]) -> Self { + pub fn chain_size_and_elements(self, felts: &[Felt]) -> Self { self.chain(&felts.len().into()).chain_iter(felts.iter()) } @@ -103,16 +119,11 @@ impl HashChain { // Returns the pedersen hash of the chained felts, hashed with the length of the chain. pub fn get_pedersen_hash(&self) -> StarkHash { - let current_hash = self - .elements - .iter() - .fold(FieldElement::ZERO, |current_hash, felt| pedersen_hash(¤t_hash, felt)); - let n_elements = FieldElement::from(self.elements.len()); - pedersen_hash(¤t_hash, &n_elements).into() + Pedersen::hash_array(self.elements.as_slice()) } // Returns the poseidon hash of the chained felts. pub fn get_poseidon_hash(&self) -> StarkHash { - poseidon_hash_many(&self.elements).into() + Poseidon::hash_array(self.elements.as_slice()) } } diff --git a/src/data_availability.rs b/src/data_availability.rs index 0b5ec76..0fc3f94 100644 --- a/src/data_availability.rs +++ b/src/data_availability.rs @@ -1,6 +1,6 @@ use serde::{Deserialize, Serialize}; +use starknet_types_core::felt::Felt; -use crate::hash::StarkFelt; use crate::StarknetApiError; #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] @@ -39,25 +39,27 @@ impl TryFrom for DataAvailabilityMode { } } -impl TryFrom for DataAvailabilityMode { +impl TryFrom for DataAvailabilityMode { type Error = StarknetApiError; - fn try_from(felt: StarkFelt) -> Result { - match felt { - StarkFelt::ZERO => Ok(DataAvailabilityMode::L1), - StarkFelt::ONE => Ok(DataAvailabilityMode::L2), - _ => Err(StarknetApiError::OutOfRange { - string: format!("Invalid data availability mode: {felt}."), - }), + fn try_from(felt: Felt) -> Result { + if felt == Felt::ZERO { + return Ok(DataAvailabilityMode::L1); + } + if felt == Felt::ONE { + return Ok(DataAvailabilityMode::L2); } + Err(StarknetApiError::OutOfRange { + string: format!("Invalid data availability mode: {felt}."), + }) } } -impl From for StarkFelt { - fn from(data_availability_mode: DataAvailabilityMode) -> StarkFelt { +impl From for Felt { + fn from(data_availability_mode: DataAvailabilityMode) -> Felt { match data_availability_mode { - DataAvailabilityMode::L1 => StarkFelt::ZERO, - DataAvailabilityMode::L2 => StarkFelt::ONE, + DataAvailabilityMode::L1 => Felt::ZERO, + DataAvailabilityMode::L2 => Felt::ONE, } } } diff --git a/src/deprecated_contract_class.rs b/src/deprecated_contract_class.rs index 99f5a0b..eb5de5d 100644 --- a/src/deprecated_contract_class.rs +++ b/src/deprecated_contract_class.rs @@ -8,6 +8,7 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde_json::Value; use crate::core::EntryPointSelector; +use crate::hash::StarkHash; use crate::serde_utils::deserialize_optional_contract_class_abi_entry_vector; use crate::StarknetApiError; @@ -193,7 +194,7 @@ impl TryFrom for EntryPoint { fn try_from(value: CasmContractEntryPoint) -> Result { Ok(EntryPoint { - selector: EntryPointSelector(value.selector.to_str_radix(16).as_str().try_into()?), + selector: EntryPointSelector(StarkHash::from(value.selector)), offset: EntryPointOffset(value.offset), }) } diff --git a/src/external_transaction_test.rs b/src/external_transaction_test.rs index 1b93d17..39b8169 100644 --- a/src/external_transaction_test.rs +++ b/src/external_transaction_test.rs @@ -2,6 +2,7 @@ use std::collections::BTreeMap; use std::sync::Arc; use rstest::rstest; +use starknet_types_core::felt::Felt; use crate::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce, PatriciaKey}; use crate::external_transaction::{ @@ -9,12 +10,12 @@ use crate::external_transaction::{ ExternalDeployAccountTransaction, ExternalDeployAccountTransactionV3, ExternalInvokeTransaction, ExternalInvokeTransactionV3, ExternalTransaction, }; -use crate::hash::{StarkFelt, StarkHash}; +use crate::hash::{FeltConverter, TryIntoFelt}; use crate::transaction::{ AccountDeploymentData, Calldata, ContractAddressSalt, PaymasterData, Resource, ResourceBounds, ResourceBoundsMapping, Tip, TransactionSignature, }; -use crate::{contract_address, patricia_key, stark_felt}; +use crate::{contract_address, felt, patricia_key}; fn create_resource_bounds() -> ResourceBoundsMapping { let mut map = BTreeMap::new(); @@ -28,14 +29,14 @@ fn create_declare_v3() -> ExternalDeclareTransaction { contract_class: ContractClass::default(), resource_bounds: create_resource_bounds(), tip: Tip(1), - signature: TransactionSignature(vec![StarkFelt::ONE, StarkFelt::TWO]), - nonce: Nonce(stark_felt!("0x1")), - compiled_class_hash: CompiledClassHash(stark_felt!("0x2")), + signature: TransactionSignature(vec![Felt::ONE, Felt::TWO]), + nonce: Nonce(Felt::ONE), + compiled_class_hash: CompiledClassHash(Felt::TWO), sender_address: contract_address!("0x3"), nonce_data_availability_mode: DataAvailabilityMode::L1, fee_data_availability_mode: DataAvailabilityMode::L2, - paymaster_data: PaymasterData(vec![StarkFelt::ZERO]), - account_deployment_data: AccountDeploymentData(vec![StarkFelt::THREE]), + paymaster_data: PaymasterData(vec![Felt::ZERO]), + account_deployment_data: AccountDeploymentData(vec![Felt::THREE]), }) } @@ -43,14 +44,14 @@ fn create_deploy_account_v3() -> ExternalDeployAccountTransaction { ExternalDeployAccountTransaction::V3(ExternalDeployAccountTransactionV3 { resource_bounds: create_resource_bounds(), tip: Tip::default(), - contract_address_salt: ContractAddressSalt(stark_felt!("0x23")), - class_hash: ClassHash(stark_felt!("0x2")), - constructor_calldata: Calldata(Arc::new(vec![StarkFelt::ZERO])), - nonce: Nonce(stark_felt!("0x60")), - signature: TransactionSignature(vec![StarkFelt::TWO]), + contract_address_salt: ContractAddressSalt(felt!("0x23")), + class_hash: ClassHash(Felt::TWO), + constructor_calldata: Calldata(Arc::new(vec![Felt::ZERO])), + nonce: Nonce(felt!("0x60")), + signature: TransactionSignature(vec![Felt::TWO]), nonce_data_availability_mode: DataAvailabilityMode::L2, fee_data_availability_mode: DataAvailabilityMode::L1, - paymaster_data: PaymasterData(vec![StarkFelt::TWO, StarkFelt::ZERO]), + paymaster_data: PaymasterData(vec![Felt::TWO, Felt::ZERO]), }) } @@ -58,14 +59,14 @@ fn create_invoke_v3() -> ExternalInvokeTransaction { ExternalInvokeTransaction::V3(ExternalInvokeTransactionV3 { resource_bounds: create_resource_bounds(), tip: Tip(50), - calldata: Calldata(Arc::new(vec![stark_felt!("0x2000"), stark_felt!("0x1000")])), + calldata: Calldata(Arc::new(vec![felt!("0x2000"), felt!("0x1000")])), sender_address: contract_address!("0x53"), - nonce: Nonce(stark_felt!("0x32")), + nonce: Nonce(felt!("0x32")), signature: TransactionSignature::default(), nonce_data_availability_mode: DataAvailabilityMode::L1, fee_data_availability_mode: DataAvailabilityMode::L1, - paymaster_data: PaymasterData(vec![StarkFelt::TWO, StarkFelt::ZERO]), - account_deployment_data: AccountDeploymentData(vec![stark_felt!("0x87")]), + paymaster_data: PaymasterData(vec![Felt::TWO, Felt::ZERO]), + account_deployment_data: AccountDeploymentData(vec![felt!("0x87")]), }) } diff --git a/src/hash.rs b/src/hash.rs index 94363f9..c3be938 100644 --- a/src/hash.rs +++ b/src/hash.rs @@ -1,374 +1,51 @@ -#[cfg(test)] -#[path = "hash_test.rs"] -mod hash_test; - -use std::fmt::{Debug, Display}; -use std::io::Error; +use std::fmt::Debug; use serde::{Deserialize, Serialize}; use sha3::{Digest, Keccak256}; -use starknet_crypto::FieldElement; use starknet_types_core::felt::Felt; -use starknet_types_core::hash::{Pedersen, Poseidon, StarkHash as StarknetTypesStarkHash}; - -use crate::serde_utils::{bytes_from_hex_str, hex_str_from_bytes, BytesAsHex, PrefixedBytesAsHex}; -use crate::{impl_from_through_intermediate, StarknetApiError}; - -/// Genesis state hash. -pub const GENESIS_HASH: &str = "0x0"; - -// Felt encoding constants. -const CHOOSER_FULL: u8 = 15; -const CHOOSER_HALF: u8 = 14; - -/// An alias for [`StarkFelt`]. -/// The output of the [Pedersen hash](https://docs.starknet.io/documentation/architecture_and_concepts/Hashing/hash-functions/#pedersen_hash). -pub type StarkHash = StarkFelt; - -/// Computes Pedersen hash using STARK curve on two elements, as defined -/// in -pub fn pedersen_hash(felt0: &StarkFelt, felt1: &StarkFelt) -> StarkHash { - Pedersen::hash(&Felt::from(felt0), &Felt::from(felt1)).into() -} - -/// Computes Pedersen hash using STARK curve on an array of elements, as defined -/// in -pub fn pedersen_hash_array(felts: &[StarkFelt]) -> StarkHash { - let current_hash = felts.iter().fold(Felt::from(0_u8), |current_hash, stark_felt| { - Pedersen::hash(¤t_hash, &Felt::from(stark_felt)) - }); - let data_len = Felt::from(u128::try_from(felts.len()).expect("Got 2^128 felts or more.")); - Pedersen::hash(¤t_hash, &data_len).into() -} -/// A Poseidon hash. -#[derive( - Copy, Clone, Eq, PartialEq, Default, Hash, Deserialize, Serialize, PartialOrd, Ord, Debug, -)] -pub struct PoseidonHash(pub StarkFelt); +pub type StarkHash = Felt; -impl Display for PoseidonHash { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - std::fmt::Display::fmt(&self.0, f) - } -} - -/// Computes the Poseidon hash of two Felts, as defined -/// in -pub fn poseidon_hash(felt0: &StarkFelt, felt1: &StarkFelt) -> PoseidonHash { - PoseidonHash(Poseidon::hash(&Felt::from(felt0), &Felt::from(felt1)).into()) -} - -/// Computes the Poseidon hash of an array of Felts, as defined -/// in -pub fn poseidon_hash_array(stark_felts: &[StarkFelt]) -> PoseidonHash { - // TODO(yair): Avoid allocating the vector of Felts. - let as_felts = stark_felts.iter().map(Felt::from).collect::>(); - PoseidonHash(Poseidon::hash_array(as_felts.as_slice()).into()) -} - -/// An interface for hash function calculations. -pub trait HashFunction { - /// Computes hash of two Felts. - fn hash_pair(felt0: &StarkFelt, felt1: &StarkFelt) -> StarkHash; - /// Computes hash of array of Felts. - fn hash_array(stark_felts: &[StarkFelt]) -> StarkHash; -} +#[derive(Debug, Clone, Default, Eq, PartialEq, Hash, Deserialize, Serialize, PartialOrd, Ord)] +pub struct PoseidonHash(pub Felt); /// Computes the first 250 bits of the Keccak256 hash, in order to fit into a field element. -pub fn starknet_keccak_hash(input: &[u8]) -> StarkFelt { +pub fn starknet_keccak_hash(input: &[u8]) -> Felt { let mut keccak = Keccak256::default(); keccak.update(input); let mut hashed_bytes: [u8; 32] = keccak.finalize().into(); hashed_bytes[0] &= 0b00000011_u8; // Discard the six MSBs. - StarkFelt::new_unchecked(hashed_bytes) -} - -pub struct PoseidonHashCalculator; - -impl HashFunction for PoseidonHashCalculator { - // Note that the hash_pair function differs from the hash_array function, even when the array - // size equals to 2. - fn hash_pair(felt0: &StarkFelt, felt1: &StarkFelt) -> StarkHash { - poseidon_hash(felt0, felt1).0 - } - - fn hash_array(stark_felts: &[StarkFelt]) -> StarkHash { - poseidon_hash_array(stark_felts).0 - } -} - -// TODO: Move to a different crate. -/// The StarkNet [field element](https://docs.starknet.io/documentation/architecture_and_concepts/Hashing/hash-functions/#domain_and_range). -#[derive(Copy, Clone, Eq, PartialEq, Default, Hash, Deserialize, Serialize, PartialOrd, Ord)] -#[serde(try_from = "PrefixedBytesAsHex<32_usize>", into = "PrefixedBytesAsHex<32_usize>")] -pub struct StarkFelt([u8; 32]); - -impl StarkFelt { - /// Returns a new [`StarkFelt`]. - pub fn new(bytes: [u8; 32]) -> Result { - // msb nibble must be 0. This is not a tight bound. - if bytes[0] < 0x10 { - return Ok(Self(bytes)); - } - Err(StarknetApiError::OutOfRange { string: hex_str_from_bytes::<32, true>(bytes) }) - } - - /// Returns a new *unchecked* [`StarkFelt`] - /// - /// # Safety - /// - /// To avoid undefined behavior, refer to [`StarkFelt`] struct's docstring - /// for the required constraints on the `bytes` argument, or use [`StarkFelt::new`] instead of - /// this method. - /// - /// # Usage - /// - /// Most of the time you should use `new` instead, but it comes in handy for a few cases: - /// - creating instances of `StarkFelt` at compile time - /// - implementing `From for StarkFelt` for types that have a smaller binary representation - /// than `StarkFelt` - pub const fn new_unchecked(bytes: [u8; 32]) -> StarkFelt { - Self(bytes) - } - - /// [StarkFelt] constant that's equal to 0. - pub const ZERO: Self = { Self::from_u128(0_u128) }; - - /// [StarkFelt] constant that's equal to 1. - pub const ONE: Self = { Self::from_u128(1_u128) }; - - /// [StarkFelt] constant that's equal to 2. - pub const TWO: Self = { Self::from_u128(2_u128) }; - - /// [StarkFelt] constant that's equal to 3. - pub const THREE: Self = { Self::from_u128(3_u128) }; - - pub const fn from_u128(val: u128) -> Self { - let mut bytes = [0u8; 32]; - let val_bytes = val.to_be_bytes(); - let mut index = 16; - while index < 32 { - bytes[index] = val_bytes[index - 16]; - index += 1; - } - Self(bytes) - } - - /// Storage efficient serialization for field elements. - pub fn serialize(&self, res: &mut impl std::io::Write) -> Result<(), Error> { - // We use the fact that bytes[0] < 0x10 and encode the size of the felt in the 4 most - // significant bits of the serialization, which we call `chooser`. We assume that 128 bit - // felts are prevalent (because of how uint256 is encoded in felts). - - // The first i for which nibbles 2i+1, 2i+2 are nonzero. Note that the first nibble is - // always 0. - let mut first_index = 31; - for i in 0..32 { - let value = self.0[i]; - if value == 0 { - continue; - } else if value < 16 { - // Can encode the chooser and the value on a single byte. - first_index = i; - } else { - // The chooser is encoded with the first nibble of the value. - first_index = i - 1; - } - break; - } - let chooser = if first_index < 15 { - // For 34 up to 63 nibble felts: chooser == 15, serialize using 32 bytes. - first_index = 0; - CHOOSER_FULL - } else if first_index < 18 { - // For 28 up to 33 nibble felts: chooser == 14, serialize using 17 bytes. - first_index = 15; - CHOOSER_HALF - } else { - // For up to 27 nibble felts: serialize the lower 1 + (chooser * 2) nibbles of the felt - // using chooser + 1 bytes. - (31 - first_index) as u8 - }; - res.write_all(&[(chooser << 4) | self.0[first_index]])?; - res.write_all(&self.0[first_index + 1..])?; - Ok(()) - } - - /// Storage efficient deserialization for field elements. - pub fn deserialize(bytes: &mut impl std::io::Read) -> Option { - let mut res = [0u8; 32]; - - bytes.read_exact(&mut res[..1]).ok()?; - let first = res[0]; - let chooser: u8 = first >> 4; - let first = first & 0x0f; - - let first_index = if chooser == CHOOSER_FULL { - 0 - } else if chooser == CHOOSER_HALF { - 15 - } else { - (31 - chooser) as usize - }; - res[0] = 0; - res[first_index] = first; - bytes.read_exact(&mut res[first_index + 1..]).ok()?; - Some(Self(res)) - } - - pub fn bytes(&self) -> &[u8; 32] { - &self.0 - } - - fn str_format(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let s = format!("0x{}", hex::encode(self.0)); - f.debug_tuple("StarkFelt").field(&s).finish() - } + Felt::from_bytes_be(&hashed_bytes) } -impl TryFrom> for StarkFelt { - type Error = StarknetApiError; - fn try_from(val: PrefixedBytesAsHex<32_usize>) -> Result { - StarkFelt::new(val.0) - } -} - -impl TryFrom<&str> for StarkFelt { - type Error = StarknetApiError; - fn try_from(val: &str) -> Result { - let val = val.trim_start_matches("0x"); - let bytes = bytes_from_hex_str::<32, false>(val)?; - Self::new(bytes) - } -} - -impl From for StarkFelt { - fn from(val: u128) -> Self { - Self::from_u128(val) - } -} - -impl_from_through_intermediate!(u128, StarkFelt, u8, u16, u32, u64); - -impl From for StarkFelt { - fn from(felt: Felt) -> Self { - // Should not fail. - Self::new(felt.to_bytes_be()).expect("Convert Felt to StarkFelt.") - } -} - -impl From for StarkFelt { - fn from(val: usize) -> Self { - Felt::from(val).into() - } -} - -impl From<&StarkFelt> for Felt { - fn from(felt: &StarkFelt) -> Self { - Self::from_bytes_be(&felt.0) - } -} - -impl From for StarkFelt { - fn from(fe: FieldElement) -> Self { - // Should not fail. - Self::new(fe.to_bytes_be()).expect("Convert FieldElement to StarkFelt.") - } -} - -impl From for FieldElement { - fn from(felt: StarkFelt) -> Self { - // Should not fail. - Self::from_bytes_be(&felt.0).expect("Convert StarkFelf to FieldElement.") - } -} - -impl From for PrefixedBytesAsHex<32_usize> { - fn from(felt: StarkFelt) -> Self { - BytesAsHex(felt.0) - } -} - -// TODO(Arni, 25/6/2023): Remove impl TryFrom for usize. Leave only one conversion from -// StarkFelt to integer type. -impl TryFrom for usize { - type Error = StarknetApiError; - fn try_from(felt: StarkFelt) -> Result { - const COMPLIMENT_OF_USIZE: usize = - std::mem::size_of::() - std::mem::size_of::(); - - let (rest, usize_bytes) = felt.bytes().split_at(COMPLIMENT_OF_USIZE); - if rest != [0u8; COMPLIMENT_OF_USIZE] { - return Err(StarknetApiError::OutOfRange { string: felt.to_string() }); - } - - Ok(usize::from_be_bytes( - usize_bytes.try_into().expect("usize_bytes should be of size usize."), - )) - } -} - -impl TryFrom for u32 { - type Error = StarknetApiError; - fn try_from(felt: StarkFelt) -> Result { - const COMPLIMENT_OF_U32: usize = 28; // 32 - 4 - let (rest, u32_bytes) = felt.bytes().split_at(COMPLIMENT_OF_U32); - if rest != [0u8; COMPLIMENT_OF_U32] { - return Err(StarknetApiError::OutOfRange { string: felt.to_string() }); - } - - let bytes: [u8; 4] = u32_bytes.try_into().unwrap(); - Ok(u32::from_be_bytes(bytes)) - } -} - -// TODO(Arni, 1/1/2024): This is a Hack. Remove this and implement arethmetics for StarkFelt. -impl TryFrom for u64 { - type Error = StarknetApiError; - fn try_from(felt: StarkFelt) -> Result { - const COMPLIMENT_OF_U64: usize = 24; // 32 - 8 - let (rest, u64_bytes) = felt.bytes().split_at(COMPLIMENT_OF_U64); - if rest != [0u8; COMPLIMENT_OF_U64] { - return Err(StarknetApiError::OutOfRange { string: felt.to_string() }); - } - - let bytes: [u8; 8] = u64_bytes.try_into().unwrap(); - Ok(u64::from_be_bytes(bytes)) - } -} - -impl TryFrom for u128 { - type Error = StarknetApiError; - fn try_from(felt: StarkFelt) -> Result { - const COMPLIMENT_OF_U128: usize = 16; // 32 - 16 - let (rest, u128_bytes) = felt.bytes().split_at(COMPLIMENT_OF_U128); - if rest != [0u8; COMPLIMENT_OF_U128] { - return Err(StarknetApiError::OutOfRange { string: felt.to_string() }); - } +#[cfg(any(feature = "testing", test))] +pub struct FeltConverter; - let bytes: [u8; 16] = u128_bytes.try_into().unwrap(); - Ok(u128::from_be_bytes(bytes)) - } +#[cfg(any(feature = "testing", test))] +pub trait TryIntoFelt { + fn to_felt_unchecked(v: V) -> Felt; } -impl Debug for StarkFelt { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.str_format(f) +#[cfg(any(feature = "testing", test))] +impl TryIntoFelt for FeltConverter { + fn to_felt_unchecked(v: u128) -> Felt { + Felt::from(v) } } -impl Display for StarkFelt { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "0x{}", hex::encode(self.0)) +#[cfg(any(feature = "testing", test))] +impl TryIntoFelt<&str> for FeltConverter { + fn to_felt_unchecked(v: &str) -> Felt { + Felt::from_hex_unchecked(v) } } -/// A utility macro to create a [`StarkFelt`] from a hex string representation. +/// A utility macro to create a [`starknet_types_core::felt::Felt`] from an intergert or a hex +/// string representation. #[cfg(any(feature = "testing", test))] #[macro_export] -macro_rules! stark_felt { +macro_rules! felt { ($s:expr) => { - StarkFelt::try_from($s).unwrap() + FeltConverter::to_felt_unchecked($s) }; } diff --git a/src/hash_test.rs b/src/hash_test.rs deleted file mode 100644 index f510aef..0000000 --- a/src/hash_test.rs +++ /dev/null @@ -1,93 +0,0 @@ -use assert_matches::assert_matches; - -use crate::hash::{pedersen_hash, pedersen_hash_array, StarkFelt}; -use crate::transaction::Fee; -use crate::{stark_felt, StarknetApiError}; - -#[test] -fn pedersen_hash_correctness() { - // Test vectors from https://github.com/starkware-libs/crypto-cpp/blob/master/src/starkware/crypto/pedersen_hash_test.cc - let a = stark_felt!("0x03d937c035c878245caf64531a5756109c53068da139362728feb561405371cb"); - let b = stark_felt!("0x0208a0a10250e382e1e4bbe2880906c2791bf6275695e02fbbc6aeff9cd8b31a"); - let expected = - stark_felt!("0x030e480bed5fe53fa909cc0f8c4d99b8f9f2c016be4c41e13a4848797979c662"); - assert_eq!(pedersen_hash(&a, &b), expected); -} - -#[test] -fn pedersen_hash_array_correctness() { - let a = stark_felt!("0xaa"); - let b = stark_felt!("0xbb"); - let c = stark_felt!("0xcc"); - let expected = pedersen_hash( - &pedersen_hash(&pedersen_hash(&pedersen_hash(&stark_felt!("0x0"), &a), &b), &c), - &stark_felt!("0x3"), - ); - assert_eq!(pedersen_hash_array(&[a, b, c]), expected); -} - -#[test] -fn hash_macro() { - assert_eq!( - stark_felt!("0x123"), - StarkFelt::new([ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0x1, 0x23 - ]) - .unwrap() - ); -} - -#[test] -fn hash_json_serde() { - let hash = stark_felt!("0x123"); - assert_eq!(hash, serde_json::from_str(&serde_json::to_string(&hash).unwrap()).unwrap()); -} - -#[test] -fn hash_serde() { - fn enc_len(n_nibbles: usize) -> usize { - match n_nibbles { - 0..=27 => n_nibbles / 2 + 1, - 28..=33 => 17, - _ => 32, - } - } - - // 64 nibbles are invalid. - for n_nibbles in 0..64 { - let mut bytes = [0u8; 32]; - // Set all nibbles to 0xf. - for i in 0..n_nibbles { - bytes[31 - (i >> 1)] |= 15 << (4 * (i & 1)); - } - let h = StarkFelt::new(bytes).unwrap(); - let mut res = Vec::new(); - assert!(h.serialize(&mut res).is_ok()); - assert_eq!(res.len(), enc_len(n_nibbles)); - let mut reader = &res[..]; - let d = StarkFelt::deserialize(&mut reader).unwrap(); - assert_eq!(bytes, d.0); - } -} - -#[test] -fn fee_to_starkfelt() { - let fee = Fee(u128::MAX); - assert_eq!(format!("{}", StarkFelt::from(fee)), format!("{:#066x}", fee.0)); -} - -#[test] -fn felt_to_u64_and_back() { - // Positive flow. - let value = u64::MAX; - let felt: StarkFelt = value.into(); - let new_value: u64 = felt.try_into().unwrap(); - assert_eq!(value, new_value); - - // Negative flow. - let value: u128 = u128::from(u64::MAX) + 1; - let another_felt: StarkFelt = value.into(); - let err = u64::try_from(another_felt).unwrap_err(); - assert_matches!(err, StarknetApiError::OutOfRange { .. }); -} diff --git a/src/serde_utils_test.rs b/src/serde_utils_test.rs index 91122d4..711de14 100644 --- a/src/serde_utils_test.rs +++ b/src/serde_utils_test.rs @@ -155,7 +155,7 @@ fn deserialize_valid_optional_contract_class_abi_entry_vector() { outputs: vec![], state_mutability: None, r#type: ConstructorType::Constructor, - },)]) + })]) } ); } diff --git a/src/state.rs b/src/state.rs index d55049f..599b654 100644 --- a/src/state.rs +++ b/src/state.rs @@ -7,6 +7,7 @@ use std::fmt::Debug; use indexmap::IndexMap; use serde::{Deserialize, Serialize}; +use starknet_types_core::felt::Felt; use crate::block::{BlockHash, BlockNumber}; use crate::core::{ @@ -14,7 +15,7 @@ use crate::core::{ PatriciaKey, }; use crate::deprecated_contract_class::ContractClass as DeprecatedContractClass; -use crate::hash::{StarkFelt, StarkHash}; +use crate::hash::StarkHash; use crate::{impl_from_through_intermediate, StarknetApiError}; pub type DeclaredClasses = IndexMap; @@ -37,7 +38,7 @@ pub struct StateUpdate { #[derive(Debug, Default, Clone, Eq, PartialEq, Deserialize, Serialize)] pub struct StateDiff { pub deployed_contracts: IndexMap, - pub storage_diffs: IndexMap>, + pub storage_diffs: IndexMap>, pub declared_classes: IndexMap, pub deprecated_declared_classes: IndexMap, pub nonces: IndexMap, @@ -50,7 +51,7 @@ pub struct StateDiff { #[derive(Debug, Default, Clone, Eq, PartialEq, Deserialize, Serialize)] pub struct ThinStateDiff { pub deployed_contracts: IndexMap, - pub storage_diffs: IndexMap>, + pub storage_diffs: IndexMap>, pub declared_classes: IndexMap, pub deprecated_declared_classes: Vec, pub nonces: IndexMap, @@ -174,8 +175,8 @@ impl StateNumber { )] pub struct StorageKey(pub PatriciaKey); -impl From for StarkFelt { - fn from(storage_key: StorageKey) -> StarkFelt { +impl From for Felt { + fn from(storage_key: StorageKey) -> Felt { **storage_key } } @@ -199,7 +200,7 @@ impl_from_through_intermediate!(u128, StorageKey, u8, u16, u32, u64); /// A contract class. #[derive(Debug, Clone, Default, Eq, PartialEq, Deserialize, Serialize)] pub struct ContractClass { - pub sierra_program: Vec, + pub sierra_program: Vec, pub entry_points_by_type: HashMap>, pub abi: String, } diff --git a/src/transaction.rs b/src/transaction.rs index 8fe2c04..8dc5a1a 100644 --- a/src/transaction.rs +++ b/src/transaction.rs @@ -4,6 +4,7 @@ use std::sync::Arc; use derive_more::From; use serde::{Deserialize, Deserializer, Serialize, Serializer}; +use starknet_types_core::felt::Felt; use strum::IntoEnumIterator; use strum_macros::EnumIter; @@ -12,7 +13,7 @@ use crate::core::{ ChainId, ClassHash, CompiledClassHash, ContractAddress, EntryPointSelector, EthAddress, Nonce, }; use crate::data_availability::DataAvailabilityMode; -use crate::hash::{StarkFelt, StarkHash}; +use crate::hash::StarkHash; use crate::serde_utils::PrefixedBytesAsHex; use crate::transaction_hash::{ get_declare_transaction_v0_hash, get_declare_transaction_v1_hash, @@ -185,15 +186,13 @@ impl TransactionHasher for DeclareTransactionV0V1 { chain_id: &ChainId, transaction_version: &TransactionVersion, ) -> Result { - match *transaction_version { - TransactionVersion::ZERO => { - get_declare_transaction_v0_hash(self, chain_id, transaction_version) - } - TransactionVersion::ONE => { - get_declare_transaction_v1_hash(self, chain_id, transaction_version) - } - _ => panic!("Illegal transaction version."), + if *transaction_version == TransactionVersion::ZERO { + return get_declare_transaction_v0_hash(self, chain_id, transaction_version); + } + if *transaction_version == TransactionVersion::ONE { + return get_declare_transaction_v1_hash(self, chain_id, transaction_version); } + panic!("Illegal transaction version."); } } @@ -693,7 +692,7 @@ impl From for PrefixedBytesAsHex<16_usize> { } } -impl From for StarkFelt { +impl From for Felt { fn from(fee: Fee) -> Self { Self::from(fee.0) } @@ -730,7 +729,7 @@ pub struct ContractAddressSalt(pub StarkHash); /// A transaction signature. #[derive(Debug, Clone, Default, Eq, PartialEq, Hash, Deserialize, Serialize, PartialOrd, Ord)] -pub struct TransactionSignature(pub Vec); +pub struct TransactionSignature(pub Vec); /// A transaction version. #[derive( @@ -747,25 +746,25 @@ pub struct TransactionSignature(pub Vec); Ord, derive_more::Deref, )] -pub struct TransactionVersion(pub StarkFelt); +pub struct TransactionVersion(pub Felt); impl TransactionVersion { /// [TransactionVersion] constant that's equal to 0. - pub const ZERO: Self = { Self(StarkFelt::ZERO) }; + pub const ZERO: Self = { Self(Felt::ZERO) }; /// [TransactionVersion] constant that's equal to 1. - pub const ONE: Self = { Self(StarkFelt::ONE) }; + pub const ONE: Self = { Self(Felt::ONE) }; /// [TransactionVersion] constant that's equal to 2. - pub const TWO: Self = { Self(StarkFelt::TWO) }; + pub const TWO: Self = { Self(Felt::TWO) }; /// [TransactionVersion] constant that's equal to 3. - pub const THREE: Self = { Self(StarkFelt::THREE) }; + pub const THREE: Self = { Self(Felt::THREE) }; } /// The calldata of a transaction. #[derive(Debug, Clone, Default, Eq, PartialEq, Hash, Deserialize, Serialize, PartialOrd, Ord)] -pub struct Calldata(pub Arc>); +pub struct Calldata(pub Arc>); #[macro_export] macro_rules! calldata { @@ -791,11 +790,11 @@ pub struct MessageToL1 { /// The payload of [`MessageToL2`]. #[derive(Debug, Clone, Default, Eq, PartialEq, Hash, Deserialize, Serialize, PartialOrd, Ord)] -pub struct L1ToL2Payload(pub Vec); +pub struct L1ToL2Payload(pub Vec); /// The payload of [`MessageToL1`]. #[derive(Debug, Clone, Default, Eq, PartialEq, Hash, Deserialize, Serialize, PartialOrd, Ord)] -pub struct L2ToL1Payload(pub Vec); +pub struct L2ToL1Payload(pub Vec); /// An event. #[derive(Debug, Clone, Default, Eq, PartialEq, Hash, Deserialize, Serialize, PartialOrd, Ord)] @@ -815,11 +814,11 @@ pub struct EventContent { /// An event key. #[derive(Debug, Clone, Default, Eq, PartialEq, Hash, Deserialize, Serialize, PartialOrd, Ord)] -pub struct EventKey(pub StarkFelt); +pub struct EventKey(pub Felt); /// An event data. #[derive(Debug, Clone, Default, Eq, PartialEq, Hash, Deserialize, Serialize, PartialOrd, Ord)] -pub struct EventData(pub Vec); +pub struct EventData(pub Vec); /// The index of a transaction in [BlockBody](`crate::block::BlockBody`). #[derive( @@ -863,7 +862,7 @@ impl From for PrefixedBytesAsHex<8_usize> { } } -impl From for StarkFelt { +impl From for Felt { fn from(tip: Tip) -> Self { Self::from(tip.0) } @@ -952,12 +951,12 @@ impl TryFrom> for ResourceBoundsMapping { /// Paymaster-related data. #[derive(Clone, Debug, Default, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] -pub struct PaymasterData(pub Vec); +pub struct PaymasterData(pub Vec); /// If nonempty, will contain the required data for deploying and initializing an account contract: /// its class hash, address salt and constructor calldata. #[derive(Debug, Clone, Default, Eq, PartialEq, Hash, Deserialize, Serialize, PartialOrd, Ord)] -pub struct AccountDeploymentData(pub Vec); +pub struct AccountDeploymentData(pub Vec); /// The execution resources used by a transaction. #[derive(Debug, Default, Deserialize, Serialize, Clone, Eq, PartialEq)] diff --git a/src/transaction_hash.rs b/src/transaction_hash.rs index 52b11db..7b00c49 100644 --- a/src/transaction_hash.rs +++ b/src/transaction_hash.rs @@ -1,10 +1,10 @@ use once_cell::sync::Lazy; +use starknet_types_core::felt::Felt; use crate::block::BlockNumber; use crate::core::{calculate_contract_address, ChainId, ContractAddress}; use crate::crypto::utils::HashChain; use crate::data_availability::DataAvailabilityMode; -use crate::hash::StarkFelt; use crate::transaction::{ DeclareTransaction, DeclareTransactionV0V1, DeclareTransactionV2, DeclareTransactionV3, DeployAccountTransaction, DeployAccountTransactionV1, DeployAccountTransactionV3, @@ -20,21 +20,19 @@ const DATA_AVAILABILITY_MODE_BITS: usize = 32; const L1_GAS: &ResourceName = b"\0L1_GAS"; const L2_GAS: &ResourceName = b"\0L2_GAS"; -static DECLARE: Lazy = +static DECLARE: Lazy = Lazy::new(|| ascii_as_felt("declare").expect("ascii_as_felt failed for 'declare'")); -static DEPLOY: Lazy = +static DEPLOY: Lazy = Lazy::new(|| ascii_as_felt("deploy").expect("ascii_as_felt failed for 'deploy'")); -static DEPLOY_ACCOUNT: Lazy = Lazy::new(|| { +static DEPLOY_ACCOUNT: Lazy = Lazy::new(|| { ascii_as_felt("deploy_account").expect("ascii_as_felt failed for 'deploy_account'") }); -static INVOKE: Lazy = +static INVOKE: Lazy = Lazy::new(|| ascii_as_felt("invoke").expect("ascii_as_felt failed for 'invoke'")); -static L1_HANDLER: Lazy = +static L1_HANDLER: Lazy = Lazy::new(|| ascii_as_felt("l1_handler").expect("ascii_as_felt failed for 'l1_handler'")); -static CONSTRUCTOR_ENTRY_POINT_SELECTOR: Lazy = Lazy::new(|| { - StarkFelt::try_from("0x28ffe4ff0f226a9107253e17a904099aa4f63a02a5621de0576e5aa71bc5194") - .expect("Failed to create StarkFelt from value") -}); +const CONSTRUCTOR_ENTRY_POINT_SELECTOR: Felt = + Felt::from_hex_unchecked("0x28ffe4ff0f226a9107253e17a904099aa4f63a02a5621de0576e5aa71bc5194"); /// Calculates hash of a Starknet transaction. pub fn get_transaction_hash( @@ -154,15 +152,17 @@ pub fn validate_transaction_hash( Ok(possible_hashes.contains(&expected_hash)) } -pub(crate) fn ascii_as_felt(ascii_str: &str) -> Result { - StarkFelt::try_from(hex::encode(ascii_str).as_str()) +// TODO: should be part of core::Felt +pub(crate) fn ascii_as_felt(ascii_str: &str) -> Result { + Felt::from_hex(hex::encode(ascii_str).as_str()) + .map_err(|_| StarknetApiError::OutOfRange { string: ascii_str.to_string() }) } // An implementation of the SNIP: https://github.com/EvyatarO/SNIPs/blob/snip-8/SNIPS/snip-8.md fn get_tip_resource_bounds_hash( resource_bounds_mapping: &ResourceBoundsMapping, tip: &Tip, -) -> Result { +) -> Result { let l1_resource_bounds = resource_bounds_mapping.0.get(&Resource::L1Gas).expect("Missing l1 resource"); let l1_resource = get_concat_resource(l1_resource_bounds, L1_GAS)?; @@ -184,13 +184,13 @@ fn get_tip_resource_bounds_hash( fn get_concat_resource( resource_bounds: &ResourceBounds, resource_name: &ResourceName, -) -> Result { +) -> Result { let max_amount = resource_bounds.max_amount.to_be_bytes(); let max_price = resource_bounds.max_price_per_unit.to_be_bytes(); let concat_bytes = [[0_u8].as_slice(), resource_name.as_slice(), max_amount.as_slice(), max_price.as_slice()] .concat(); - StarkFelt::new(concat_bytes.try_into().expect("Expect 32 bytes")) + Ok(Felt::from_bytes_be(&concat_bytes.try_into().expect("Expect 32 bytes"))) } // Receives nonce_mode and fee_mode and returns: @@ -199,7 +199,7 @@ fn get_concat_resource( fn concat_data_availability_mode( nonce_mode: &DataAvailabilityMode, fee_mode: &DataAvailabilityMode, -) -> StarkFelt { +) -> Felt { (data_availability_mode_index(fee_mode) + (data_availability_mode_index(nonce_mode) << DATA_AVAILABILITY_MODE_BITS)) .into() @@ -261,7 +261,7 @@ fn get_common_deploy_transaction_hash( // No fee in deploy transaction. .chain_if_fn(|| { if !is_deprecated { - Some(StarkFelt::ZERO) + Some(Felt::ZERO) } else { None } @@ -316,7 +316,7 @@ pub(crate) fn get_invoke_transaction_v1_hash( .chain(&INVOKE) .chain(&transaction_version.0) .chain(transaction.sender_address.0.key()) - .chain(&StarkFelt::ZERO) // No entry point selector in invoke transaction. + .chain(&Felt::ZERO) // No entry point selector in invoke transaction. .chain(&HashChain::new().chain_iter(transaction.calldata.0.iter()).get_pedersen_hash()) .chain(&transaction.max_fee.0.into()) .chain(&ascii_as_felt(chain_id.to_string().as_str())?) @@ -429,7 +429,7 @@ fn get_common_l1_handler_transaction_hash( // No fee in l1 handler transaction. .chain_if_fn(|| { if version > L1HandlerVersions::V0Deprecated { - Some(StarkFelt::ZERO) + Some(Felt::ZERO) } else { None } @@ -456,7 +456,7 @@ pub(crate) fn get_declare_transaction_v0_hash( .chain(&DECLARE) .chain(&transaction_version.0) .chain(transaction.sender_address.0.key()) - .chain(&StarkFelt::ZERO) // No entry point selector in declare transaction. + .chain(&Felt::ZERO) // No entry point selector in declare transaction. .chain(&HashChain::new().get_pedersen_hash()) .chain(&transaction.max_fee.0.into()) .chain(&ascii_as_felt(chain_id.to_string().as_str())?) @@ -475,7 +475,7 @@ pub(crate) fn get_declare_transaction_v1_hash( .chain(&DECLARE) .chain(&transaction_version.0) .chain(transaction.sender_address.0.key()) - .chain(&StarkFelt::ZERO) // No entry point selector in declare transaction. + .chain(&Felt::ZERO) // No entry point selector in declare transaction. .chain(&HashChain::new().chain(&transaction.class_hash.0).get_pedersen_hash()) .chain(&transaction.max_fee.0.into()) .chain(&ascii_as_felt(chain_id.to_string().as_str())?) @@ -494,7 +494,7 @@ pub(crate) fn get_declare_transaction_v2_hash( .chain(&DECLARE) .chain(&transaction_version.0) .chain(transaction.sender_address.0.key()) - .chain(&StarkFelt::ZERO) // No entry point selector in declare transaction. + .chain(&Felt::ZERO) // No entry point selector in declare transaction. .chain(&HashChain::new().chain(&transaction.class_hash.0).get_pedersen_hash()) .chain(&transaction.max_fee.0.into()) .chain(&ascii_as_felt(chain_id.to_string().as_str())?) @@ -561,7 +561,7 @@ pub(crate) fn get_deploy_account_transaction_v1_hash( .chain(&DEPLOY_ACCOUNT) .chain(&transaction_version.0) .chain(contract_address.0.key()) - .chain(&StarkFelt::ZERO) // No entry point selector in deploy account transaction. + .chain(&Felt::ZERO) // No entry point selector in deploy account transaction. .chain(&calldata_hash) .chain(&transaction.max_fee.0.into()) .chain(&ascii_as_felt(chain_id.to_string().as_str())?)