Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 26 additions & 10 deletions src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -354,11 +354,18 @@ impl NotU8Pushable for usize {
}
impl NotU8Pushable for Vec<u8> {
fn bitcoin_script_push(self, builder: StructuredScript) -> StructuredScript {
// Push the element with a minimal opcode if it is a single number.
if self.len() == 1 {
builder.push_int(self[0].into())
} else {
builder.push_slice(PushBytesBuf::try_from(self.to_vec()).unwrap())
match self[..] {
[x] if (1..=16).contains(&x) => {
// use decicated opcode for pushing a single byte with value 1 <= x <= 16.
// Note that we don't use a special opcode used for pushing the value 0 - pushing this
// as an integer would push an empty array rather than a 0x00 value
builder.push_int(x.into())
}
[129] => {
// 129 is equivalent to -1 when interpreting as signed - use dedicated opcode for pushing this
builder.push_int(-1)
}
_ => builder.push_slice(PushBytesBuf::try_from(self).unwrap()),
}
}
}
Expand All @@ -375,11 +382,20 @@ impl NotU8Pushable for ::bitcoin::XOnlyPublicKey {
impl NotU8Pushable for Witness {
fn bitcoin_script_push(self, mut builder: StructuredScript) -> StructuredScript {
for element in self.into_iter() {
// Push the element with a minimal opcode if it is a single number.
if element.len() == 1 {
builder = builder.push_int(element[0].into());
} else {
builder = builder.push_slice(PushBytesBuf::try_from(element.to_vec()).unwrap());
match element[..] {
[x] if (1..=16).contains(&x) => {
// use decicated opcode for pushing a single byte with value 1 <= x <= 16.
// Note that we don't use a special opcode used for pushing the value 0 - pushing this
// as an integer would push an empty array rather than a 0x00 value
builder = builder.push_int(x.into());
}
[129] => {
// 129 is equivalent to -1 when interpreting as signed - use dedicated opcode for pushing this
builder = builder.push_int(-1);
}
_ => {
builder = builder.push_slice(PushBytesBuf::try_from(element.to_vec()).unwrap());
}
}
}
builder
Expand Down
36 changes: 20 additions & 16 deletions tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,24 +260,27 @@ fn test_non_optimal_opcodes() {
#[test]
fn test_push_witness() {
for i in 0..512 {
let mut witness = Witness::new();
let vec = vec![129u8; i];
witness.push(vec.clone());
let script = script! {
{ witness }
};
let reference_script = script! {
{ vec }
};
assert_eq!(
script.compile().as_bytes(),
reference_script.compile().as_bytes(),
"here"
);
for x in vec![0, 37, 42, 127, 128, 129, 211, 255] {
let mut witness = Witness::new();
let vec = vec![x; i];
witness.push(vec.clone());
let script = script! {
{ witness }
};
let reference_script = script! {
{ vec }
};
assert_eq!(
script.compile().as_bytes(),
reference_script.compile().as_bytes(),
"here"
);
}
}

let mut witness = Witness::new();
for i in 0..16 {
witness.push([]); //presentation of 0 with `consensus_encode` is [0] instead of [], but `push_int` in this repository encodes 0 as []
for i in 1..16 {
let mut varint = Vec::new();
encode::VarInt(i).consensus_encode(&mut varint).unwrap();
witness.push(varint);
Expand Down Expand Up @@ -308,7 +311,8 @@ fn test_push_witness() {
fn test_push_scriptbuf() {
let script_buf = script! {
{ 1 }
}.compile();
}
.compile();
let script = script! {
{ script_buf.clone() }
};
Expand Down