Refactor check_witness_commitment

Currently function contains nested `if` clauses that arguably obfuscate
the code. We can make the code easier to read by pulling out the error
paths and returning them higher up in the function.

Refactor only, no logic changes.
This commit is contained in:
Tobin Harding 2022-03-09 11:12:36 +11:00
parent 337caad880
commit 5464848f45
1 changed files with 24 additions and 20 deletions

View File

@ -182,33 +182,37 @@ impl Block {
} }
} }
/// check if witness commitment in coinbase is matching the transaction list /// Checks if witness commitment in coinbase matches the transaction list.
pub fn check_witness_commitment(&self) -> bool { pub fn check_witness_commitment(&self) -> bool {
const MAGIC: [u8; 6] = [0x6a, 0x24, 0xaa, 0x21, 0xa9, 0xed];
// witness commitment is optional if there are no transactions using SegWit in the block // Witness commitment is optional if there are no transactions using SegWit in the block.
if self.txdata.iter().all(|t| t.input.iter().all(|i| i.witness.is_empty())) { if self.txdata.iter().all(|t| t.input.iter().all(|i| i.witness.is_empty())) {
return true; return true;
} }
if !self.txdata.is_empty() {
let coinbase = &self.txdata[0]; if self.txdata.is_empty() {
if coinbase.is_coin_base() { return false;
// commitment is in the last output that starts with below magic }
if let Some(pos) = coinbase.output.iter()
.rposition(|o| { let coinbase = &self.txdata[0];
o.script_pubkey.len () >= 38 if !coinbase.is_coin_base() {
&& o.script_pubkey[0..6] == [0x6a, 0x24, 0xaa, 0x21, 0xa9, 0xed] }) { return false;
let commitment = WitnessCommitment::from_slice(&coinbase.output[pos].script_pubkey.as_bytes()[6..38]).unwrap(); }
// witness reserved value is in coinbase input witness
let witness_vec: Vec<_> = coinbase.input[0].witness.iter().collect(); // Commitment is in the last output that starts with magic bytes.
if witness_vec.len() == 1 && witness_vec[0].len() == 32 { if let Some(pos) = coinbase.output.iter()
match self.witness_root() { .rposition(|o| o.script_pubkey.len () >= 38 && o.script_pubkey[0..6] == MAGIC)
Some(witness_root) => return commitment == Self::compute_witness_commitment(&witness_root, witness_vec[0]), {
None => return false, let commitment = WitnessCommitment::from_slice(&coinbase.output[pos].script_pubkey.as_bytes()[6..38]).unwrap();
} // Witness reserved value is in coinbase input witness.
} let witness_vec: Vec<_> = coinbase.input[0].witness.iter().collect();
if witness_vec.len() == 1 && witness_vec[0].len() == 32 {
if let Some(witness_root) = self.witness_root() {
return commitment == Self::compute_witness_commitment(&witness_root, witness_vec[0]);
} }
} }
} }
false false
} }