Merge rust-bitcoin/rust-bitcoin#1999: Fix witness display bug

84614d9997 Unit test debug print of witness with empty instruction (Tobin C. Harding)
e96be5ee6e Fix Witness debug display bug (Tobin C. Harding)

Pull request description:

  When we introduce a custom `Debug` implementation for the `Witness` we introduced a bug that causes code to panic if the witness contains an empty instruction.

  The bug can be verified by putting patch 2 first or by running `cargo run --example sighash` on master.

ACKs for top commit:
  apoelstra:
    ACK 84614d9997
  RCasatta:
    ACK 84614d9997

Tree-SHA512: d51891206ab15f74dda07eb29ff3f6c69dc3f983a5a5abb55685688548481a19f7c1d33aa1183a89c553ff2bc86cf41057c2bae33d75e8a7f3b801056775bf9e
This commit is contained in:
Riccardo Casatta 2023-08-30 11:47:35 +02:00
commit feafac3c65
No known key found for this signature in database
GPG Key ID: FD986A969E450397
1 changed files with 29 additions and 13 deletions

View File

@ -68,20 +68,26 @@ fn fmt_debug(w: &Witness, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error>
f.write_str("witnesses: [")?; f.write_str("witnesses: [")?;
let instructions = w.iter(); let instructions = w.iter();
let last_instruction = instructions.len() - 1; if instructions.len() > 0 {
let last_instruction = instructions.len() - 1;
for (i, instruction) in instructions.enumerate() { for (i, instruction) in instructions.enumerate() {
let bytes = instruction.iter(); let bytes = instruction.iter();
let last_byte = bytes.len() - 1; if bytes.len() > 0 {
let last_byte = bytes.len() - 1;
f.write_str("[")?; f.write_str("[")?;
for (j, byte) in bytes.enumerate() {
for (j, byte) in bytes.enumerate() { write!(f, "{:#04x}", byte)?;
write!(f, "{:#04x}", byte)?; f.write_str(comma_or_close(j, last_byte))?;
f.write_str(comma_or_close(j, last_byte))?; }
} else {
// This is possible because the varint is not part of the instruction (see Iter).
write!(f, "[]")?;
}
f.write_str(comma_or_close(i, last_instruction))?;
} }
} else {
f.write_str(comma_or_close(i, last_instruction))?; // Witnesses can be empty because the 0x00 var int is not stored in content.
write!(f, "]")?;
} }
f.write_str(" }") f.write_str(" }")
@ -529,6 +535,16 @@ mod test {
v v
} }
#[test]
fn witness_debug_can_display_empty_instruction() {
let witness = Witness {
witness_elements: 1,
content: append_u32_vec(vec![], &[0]),
indices_start: 2,
};
println!("{:?}", witness);
}
#[test] #[test]
fn test_push() { fn test_push() {
let mut witness = Witness::default(); let mut witness = Witness::default();