Skip to content

Commit

Permalink
fix(l1_receipt): trimmed hash (madara-alliance#470)
Browse files Browse the repository at this point in the history
  • Loading branch information
Trantorian1 authored and heemankv committed Feb 1, 2025
1 parent aa8f061 commit 4d174b2
Showing 1 changed file with 53 additions and 1 deletion.
54 changes: 53 additions & 1 deletion crates/madara/primitives/receipt/src/to_starknet_types.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use primitive_types::H256;
use starknet_types_core::felt::Felt;

use crate::{
Expand Down Expand Up @@ -59,7 +60,9 @@ impl L1HandlerTransactionReceipt {
finality_status: starknet_types_rpc::TxnFinalityStatus,
) -> starknet_types_rpc::L1HandlerTxnReceipt<Felt> {
starknet_types_rpc::L1HandlerTxnReceipt::<Felt> {
message_hash: self.message_hash.to_string(),
// We have to manually convert the H256 bytes to a hex hash as the
// impl of Display for H256 skips the middle bytes.
message_hash: hash_as_string(self.message_hash),
common_receipt_properties: starknet_types_rpc::CommonReceiptProperties {
actual_fee: self.actual_fee.into(),
events: self.events.into_iter().map(starknet_types_rpc::Event::from).collect(),
Expand All @@ -73,6 +76,23 @@ impl L1HandlerTransactionReceipt {
}
}

/// Gets the **full** string hex representation of an [H256].
///
/// This is necessary as the default implementation of [ToString] for [H256]
/// will keep only the first and last 2 bytes, eliding the rest with '...'.
fn hash_as_string(message_hash: H256) -> String {
use std::fmt::Write;

// 32 bytes x 2 (1 hex char = 4 bits) + 2 (for 0x)
let mut acc = String::with_capacity(68);
acc.push_str("0x");

message_hash.as_fixed_bytes().iter().fold(acc, |mut acc, b| {
write!(&mut acc, "{b:02x}").expect("Pre-allocated");
acc
})
}

impl DeclareTransactionReceipt {
pub fn to_starknet_types(
self,
Expand Down Expand Up @@ -201,3 +221,35 @@ impl From<ExecutionResult> for starknet_types_rpc::ExecutionStatus {
}
}
}

#[cfg(test)]
mod test {
use primitive_types::H256;

use crate::{to_starknet_types::hash_as_string, L1HandlerTransactionReceipt};

#[test]
fn test_hash_as_string() {
let mut hash = String::with_capacity(68);
hash.push_str("0x");
hash.push_str(&"f".repeat(64));
assert_eq!(hash_as_string(H256::from_slice(&[u8::MAX; 32])), hash);
}

/// The default implementation of [ToString] for [H256] will keep only the
/// first and last 2 bytes, eliding the rest with '...'. This test makes
/// sure this is not the case and we are using [hash_as_string] instead.
#[test]
fn test_l1_tx_receipt_full_hash() {
let l1_transaction_receipt =
L1HandlerTransactionReceipt { message_hash: H256::from_slice(&[u8::MAX; 32]), ..Default::default() };
let message_hash =
l1_transaction_receipt.to_starknet_types(starknet_types_rpc::TxnFinalityStatus::L1).message_hash;

let mut hash = String::with_capacity(68);
hash.push_str("0x");
hash.push_str(&"f".repeat(64));
assert_eq!(message_hash, hash);
assert!(!message_hash.contains("."));
}
}

0 comments on commit 4d174b2

Please sign in to comment.