Separate private `Script` methods
These will need a private extension trait and to make the review easier, we separate them.
This commit is contained in:
parent
27adc09e9f
commit
5a461545c7
|
@ -406,29 +406,6 @@ impl Script {
|
|||
self.minimal_non_dust_internal(dust_relay_fee.to_sat_per_kwu() * 4)
|
||||
}
|
||||
|
||||
fn minimal_non_dust_internal(&self, dust_relay_fee: u64) -> crate::Amount {
|
||||
// This must never be lower than Bitcoin Core's GetDustThreshold() (as of v0.21) as it may
|
||||
// otherwise allow users to create transactions which likely can never be broadcast/confirmed.
|
||||
let sats = dust_relay_fee
|
||||
.checked_mul(if self.is_op_return() {
|
||||
0
|
||||
} else if self.is_witness_program() {
|
||||
32 + 4 + 1 + (107 / 4) + 4 + // The spend cost copied from Core
|
||||
8 + // The serialized size of the TxOut's amount field
|
||||
self.consensus_encode(&mut sink()).expect("sinks don't error").to_u64() // The serialized size of this script_pubkey
|
||||
} else {
|
||||
32 + 4 + 1 + 107 + 4 + // The spend cost copied from Core
|
||||
8 + // The serialized size of the TxOut's amount field
|
||||
self.consensus_encode(&mut sink()).expect("sinks don't error").to_u64() // The serialized size of this script_pubkey
|
||||
})
|
||||
.expect("dust_relay_fee or script length should not be absurdly large")
|
||||
/ 1000; // divide by 1000 like in Core to get value as it cancels out DEFAULT_MIN_RELAY_TX_FEE
|
||||
// Note: We ensure the division happens at the end, since Core performs the division at the end.
|
||||
// This will make sure none of the implicit floor operations mess with the value.
|
||||
|
||||
crate::Amount::from_sat(sats)
|
||||
}
|
||||
|
||||
/// Counts the sigops for this Script using accurate counting.
|
||||
///
|
||||
/// In Bitcoin Core, there are two ways to count sigops, "accurate" and "legacy".
|
||||
|
@ -459,46 +436,6 @@ impl Script {
|
|||
/// so do not use this to try and estimate if a Taproot script goes over the sigop budget.)
|
||||
pub fn count_sigops_legacy(&self) -> usize { self.count_sigops_internal(false) }
|
||||
|
||||
fn count_sigops_internal(&self, accurate: bool) -> usize {
|
||||
let mut n = 0;
|
||||
let mut pushnum_cache = None;
|
||||
for inst in self.instructions() {
|
||||
match inst {
|
||||
Ok(Instruction::Op(opcode)) => {
|
||||
match opcode {
|
||||
// p2pk, p2pkh
|
||||
OP_CHECKSIG | OP_CHECKSIGVERIFY => {
|
||||
n += 1;
|
||||
}
|
||||
OP_CHECKMULTISIG | OP_CHECKMULTISIGVERIFY => {
|
||||
match (accurate, pushnum_cache) {
|
||||
(true, Some(pushnum)) => {
|
||||
// Add the number of pubkeys in the multisig as sigop count
|
||||
n += usize::from(pushnum);
|
||||
}
|
||||
_ => {
|
||||
// MAX_PUBKEYS_PER_MULTISIG from Bitcoin Core
|
||||
// https://github.com/bitcoin/bitcoin/blob/v25.0/src/script/script.h#L29-L30
|
||||
n += 20;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
pushnum_cache = opcode.decode_pushnum();
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(Instruction::PushBytes(_)) => {
|
||||
pushnum_cache = None;
|
||||
}
|
||||
// In Bitcoin Core it does `if (!GetOp(pc, opcode)) break;`
|
||||
Err(_) => break,
|
||||
}
|
||||
}
|
||||
|
||||
n
|
||||
}
|
||||
|
||||
/// Iterates over the script instructions.
|
||||
///
|
||||
/// Each returned item is a nested enum covering opcodes, datapushes and errors.
|
||||
|
@ -564,6 +501,71 @@ impl Script {
|
|||
pub fn first_opcode(&self) -> Option<Opcode> {
|
||||
self.as_bytes().first().copied().map(From::from)
|
||||
}
|
||||
}
|
||||
|
||||
impl Script {
|
||||
fn minimal_non_dust_internal(&self, dust_relay_fee: u64) -> crate::Amount {
|
||||
// This must never be lower than Bitcoin Core's GetDustThreshold() (as of v0.21) as it may
|
||||
// otherwise allow users to create transactions which likely can never be broadcast/confirmed.
|
||||
let sats = dust_relay_fee
|
||||
.checked_mul(if self.is_op_return() {
|
||||
0
|
||||
} else if self.is_witness_program() {
|
||||
32 + 4 + 1 + (107 / 4) + 4 + // The spend cost copied from Core
|
||||
8 + // The serialized size of the TxOut's amount field
|
||||
self.consensus_encode(&mut sink()).expect("sinks don't error").to_u64() // The serialized size of this script_pubkey
|
||||
} else {
|
||||
32 + 4 + 1 + 107 + 4 + // The spend cost copied from Core
|
||||
8 + // The serialized size of the TxOut's amount field
|
||||
self.consensus_encode(&mut sink()).expect("sinks don't error").to_u64() // The serialized size of this script_pubkey
|
||||
})
|
||||
.expect("dust_relay_fee or script length should not be absurdly large")
|
||||
/ 1000; // divide by 1000 like in Core to get value as it cancels out DEFAULT_MIN_RELAY_TX_FEE
|
||||
// Note: We ensure the division happens at the end, since Core performs the division at the end.
|
||||
// This will make sure none of the implicit floor operations mess with the value.
|
||||
|
||||
crate::Amount::from_sat(sats)
|
||||
}
|
||||
|
||||
fn count_sigops_internal(&self, accurate: bool) -> usize {
|
||||
let mut n = 0;
|
||||
let mut pushnum_cache = None;
|
||||
for inst in self.instructions() {
|
||||
match inst {
|
||||
Ok(Instruction::Op(opcode)) => {
|
||||
match opcode {
|
||||
// p2pk, p2pkh
|
||||
OP_CHECKSIG | OP_CHECKSIGVERIFY => {
|
||||
n += 1;
|
||||
}
|
||||
OP_CHECKMULTISIG | OP_CHECKMULTISIGVERIFY => {
|
||||
match (accurate, pushnum_cache) {
|
||||
(true, Some(pushnum)) => {
|
||||
// Add the number of pubkeys in the multisig as sigop count
|
||||
n += usize::from(pushnum);
|
||||
}
|
||||
_ => {
|
||||
// MAX_PUBKEYS_PER_MULTISIG from Bitcoin Core
|
||||
// https://github.com/bitcoin/bitcoin/blob/v25.0/src/script/script.h#L29-L30
|
||||
n += 20;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
pushnum_cache = opcode.decode_pushnum();
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(Instruction::PushBytes(_)) => {
|
||||
pushnum_cache = None;
|
||||
}
|
||||
// In Bitcoin Core it does `if (!GetOp(pc, opcode)) break;`
|
||||
Err(_) => break,
|
||||
}
|
||||
}
|
||||
|
||||
n
|
||||
}
|
||||
|
||||
/// Iterates the script to find the last opcode.
|
||||
///
|
||||
|
|
Loading…
Reference in New Issue