-
Notifications
You must be signed in to change notification settings - Fork 62
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge #122: Add utility to validate
GetMerkleRes
54fd52d Add test coverage for `validate_merkle_proof` (Elias Rohrer) fe33e19 Add utility for validating a Merkle inclusion proof (Elias Rohrer) dd872d6 Make response types `Clone` (Elias Rohrer) Pull request description: I recently needed to validate a Merkle inclusion proof as retrieved via `transaction_get_merkle`. As I figured it might be useful to other people, too, we add it here as a simple utility method. ACKs for top commit: notmandatory: ACK 54fd52d Tree-SHA512: aac12160d5b91a011988f45013eb92924c2dfb244c1720e73dc5bcb731e69065c38e022502c756100d8ee6c9af06efa0de9bbfbb2b9e3c2e34d3223539206e1c
- Loading branch information
Showing
4 changed files
with
85 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
//! Utilities helping to handle Electrum-related data. | ||
use bitcoin::hash_types::TxMerkleNode; | ||
use bitcoin::hashes::sha256d::Hash as Sha256d; | ||
use bitcoin::hashes::Hash; | ||
use bitcoin::Txid; | ||
use types::GetMerkleRes; | ||
|
||
/// Verifies a Merkle inclusion proof as retrieved via [`transaction_get_merkle`] for a transaction with the | ||
/// given `txid` and `merkle_root` as included in the [`BlockHeader`]. | ||
/// | ||
/// Returns `true` if the transaction is included in the corresponding block, and `false` | ||
/// otherwise. | ||
/// | ||
/// [`transaction_get_merkle`]: crate::ElectrumApi::transaction_get_merkle | ||
/// [`BlockHeader`]: bitcoin::BlockHeader | ||
pub fn validate_merkle_proof( | ||
txid: &Txid, | ||
merkle_root: &TxMerkleNode, | ||
merkle_res: &GetMerkleRes, | ||
) -> bool { | ||
let mut index = merkle_res.pos; | ||
let mut cur = txid.to_raw_hash(); | ||
for bytes in &merkle_res.merkle { | ||
let mut reversed = [0u8; 32]; | ||
reversed.copy_from_slice(bytes); | ||
reversed.reverse(); | ||
// unwrap() safety: `reversed` has len 32 so `from_slice` can never fail. | ||
let next_hash = Sha256d::from_slice(&reversed).unwrap(); | ||
|
||
let (left, right) = if index % 2 == 0 { | ||
(cur, next_hash) | ||
} else { | ||
(next_hash, cur) | ||
}; | ||
|
||
let data = [&left[..], &right[..]].concat(); | ||
cur = Sha256d::hash(&data); | ||
index /= 2; | ||
} | ||
|
||
cur == merkle_root.to_raw_hash() | ||
} |