Skip to content

Commit

Permalink
fix(block_hash): Block hash mismatch for transaction with an empty si…
Browse files Browse the repository at this point in the history
…gnature (#354)
  • Loading branch information
Trantorian1 authored Oct 21, 2024
1 parent de11ced commit 166ec29
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 52 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Next release

- fix(block_hash): block hash mismatch on transaction with an empty signature
- feat: declare v0, l1 handler support added
- feat: strk gas price cli param added
- fix(snos): added special address while closing block for SNOS
Expand Down
1 change: 1 addition & 0 deletions crates/primitives/block/src/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ impl Header {
self.parent_block_hash,
])
} else {
// Based off https://github.com/starkware-libs/sequencer/blob/78ceca6aa230a63ca31f29f746fbb26d312fe381/crates/starknet_api/src/block_hash/block_hash_calculator.rs#L67
Poseidon::hash_array(&[
Felt::from_bytes_be_slice(b"STARKNET_BLOCK_HASH0"),
Felt::from(self.block_number),
Expand Down
104 changes: 52 additions & 52 deletions crates/primitives/transactions/src/compute_hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ const L1_HANDLER_PREFIX: Felt = Felt::from_hex_unchecked("0x6c315f68616e646c6572

const L1_GAS: &[u8] = b"L1_GAS";
const L2_GAS: &[u8] = b"L2_GAS";
const PEDERSEN_EMPTY: Felt =
Felt::from_hex_unchecked("0x49ee3eba8c1600700ee1b87eb599f16716b0b1022947733551fde4050ca6804");

impl Transaction {
pub fn compute_hash(&self, chain_id: Felt, version: StarknetVersion, offset_version: bool) -> Felt {
Expand Down Expand Up @@ -58,60 +60,53 @@ impl Transaction {
/// computing the transaction commitent uses a hash value that combines
/// the transaction hash with the array of signature values.
pub fn compute_hash_with_signature(&self, tx_hash: Felt, starknet_version: StarknetVersion) -> Felt {
let include_signature = starknet_version >= StarknetVersion::V0_11_1;

let leaf = match self {
Transaction::Invoke(tx) => {
// Include signatures for Invoke transactions or for all transactions
if starknet_version < StarknetVersion::V0_13_2 {
let signature_hash = tx.compute_hash_signature::<Pedersen>();
Pedersen::hash(&tx_hash, &signature_hash)
} else {
let elements: Vec<Felt> = std::iter::once(tx_hash).chain(tx.signature().iter().copied()).collect();
Poseidon::hash_array(&elements)
}
}
Transaction::Declare(tx) => {
if include_signature {
if starknet_version < StarknetVersion::V0_13_2 {
let signature_hash = tx.compute_hash_signature::<Pedersen>();
Pedersen::hash(&tx_hash, &signature_hash)
} else {
let elements: Vec<Felt> =
std::iter::once(tx_hash).chain(tx.signature().iter().copied()).collect();
Poseidon::hash_array(&elements)
}
} else {
let signature_hash = Pedersen::hash_array(&[]);
Pedersen::hash(&tx_hash, &signature_hash)
}
}
Transaction::DeployAccount(tx) => {
if include_signature {
if starknet_version < StarknetVersion::V0_13_2 {
let signature_hash = tx.compute_hash_signature::<Pedersen>();
Pedersen::hash(&tx_hash, &signature_hash)
} else {
let elements: Vec<Felt> =
std::iter::once(tx_hash).chain(tx.signature().iter().copied()).collect();
Poseidon::hash_array(&elements)
}
} else {
let signature_hash = Pedersen::hash_array(&[]);
Pedersen::hash(&tx_hash, &signature_hash)
}
}
_ => {
if starknet_version < StarknetVersion::V0_13_2 {
let signature_hash = Pedersen::hash_array(&[]);
Pedersen::hash(&tx_hash, &signature_hash)
} else {
Poseidon::hash_array(&[tx_hash, Felt::ZERO])
}
}
if starknet_version < StarknetVersion::V0_11_1 {
self.compute_hash_with_signature_pre_v0_11_1(tx_hash)
} else if starknet_version < StarknetVersion::V0_13_2 {
self.compute_hash_with_signature_pre_v0_13_2(tx_hash)
} else {
self.compute_hash_with_signature_latest(tx_hash)
}
}

fn compute_hash_with_signature_pre_v0_11_1(&self, tx_hash: Felt) -> Felt {
let signature_hash = match self {
Transaction::Invoke(tx) => tx.compute_hash_signature::<Pedersen>(),
Transaction::Declare(_)
| Transaction::DeployAccount(_)
| Transaction::Deploy(_)
| Transaction::L1Handler(_) => PEDERSEN_EMPTY,
};

Pedersen::hash(&tx_hash, &signature_hash)
}

fn compute_hash_with_signature_pre_v0_13_2(&self, tx_hash: Felt) -> Felt {
let signature_hash = match self {
Transaction::Invoke(tx) => tx.compute_hash_signature::<Pedersen>(),
Transaction::Declare(tx) => tx.compute_hash_signature::<Pedersen>(),
Transaction::DeployAccount(tx) => tx.compute_hash_signature::<Pedersen>(),
Transaction::Deploy(_) | Transaction::L1Handler(_) => PEDERSEN_EMPTY,
};

Pedersen::hash(&tx_hash, &signature_hash)
}

fn compute_hash_with_signature_latest(&self, tx_hash: Felt) -> Felt {
let signature = match self {
Transaction::Invoke(tx) => tx.signature(),
Transaction::Declare(tx) => tx.signature(),
Transaction::DeployAccount(tx) => tx.signature(),
Transaction::Deploy(_) | Transaction::L1Handler(_) => &[],
};

leaf
let elements = if signature.is_empty() {
vec![tx_hash, Felt::ZERO]
} else {
std::iter::once(tx_hash).chain(signature.iter().copied()).collect()
};

Poseidon::hash_array(&elements)
}
}

Expand Down Expand Up @@ -707,4 +702,9 @@ mod tests {
Felt::from_hex_unchecked("0x734743d11641ecb3d92bafae091346fec3b2c75f7808e39f8b23d9287636e45");
assert_eq!(contract_address, expected_contract_address,);
}

#[test]
fn test_pedersen_empty() {
assert_eq!(PEDERSEN_EMPTY, Pedersen::hash_array(&[]))
}
}

0 comments on commit 166ec29

Please sign in to comment.