Skip to content

Commit 2f1ae91

Browse files
committed
wip: Use LockTime
1 parent 0ac479f commit 2f1ae91

File tree

18 files changed

+98
-106
lines changed

18 files changed

+98
-106
lines changed

Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,17 @@ compiler = []
1515
trace = []
1616
unstable = []
1717
default = []
18-
use-serde = ["serde", "bitcoin/use-serde"]
18+
use-serde = ["serde", "bitcoin/serde"]
1919
rand = ["bitcoin/rand"]
2020

2121
[dependencies]
22-
bitcoin = "0.28.0"
22+
bitcoin = { git = "https://github.com/tcharding/rust-bitcoin", branch = "05-17-timelock" }
2323
serde = { version = "1.0", optional = true}
2424

2525
[dev-dependencies]
2626
bitcoind = {version = "0.26.1", features=["22_0"]}
2727
actual-rand = { package = "rand", version = "0.8.4"}
28-
bitcoin = { version = "0.28", features = ["rand"]}
28+
bitcoin = { git = "https://github.com/tcharding/rust-bitcoin", branch = "05-17-timelock", features = ["rand"] }
2929

3030
[[example]]
3131
name = "htlc"

examples/sign_multisig.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use std::collections::HashMap;
1818
use std::str::FromStr;
1919

2020
use bitcoin::blockdata::witness::Witness;
21-
use bitcoin::secp256k1;
21+
use bitcoin::{secp256k1, LockTime};
2222

2323
fn main() {
2424
let mut tx = spending_transaction();
@@ -91,7 +91,7 @@ fn main() {
9191
fn spending_transaction() -> bitcoin::Transaction {
9292
bitcoin::Transaction {
9393
version: 2,
94-
lock_time: 0,
94+
lock_time: LockTime::from(0),
9595
input: vec![bitcoin::TxIn {
9696
previous_output: Default::default(),
9797
script_sig: bitcoin::Script::new(),

examples/verify_tx.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
1717
use std::str::FromStr;
1818

19+
use bitcoin::LockTime;
1920
use bitcoin::consensus::Decodable;
2021
use bitcoin::secp256k1::{self, Secp256k1};
2122
use bitcoin::util::sighash;
@@ -33,7 +34,7 @@ fn main() {
3334
&spk_input_1,
3435
&tx.input[0].script_sig,
3536
&tx.input[0].witness,
36-
0,
37+
LockTime::from(0),
3738
0,
3839
)
3940
.unwrap();

src/descriptor/tr.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,7 @@ impl<Pk: MiniscriptKey> Tr<Pk> {
262262
TaprootBuilderError::EmptyTree => {
263263
unreachable!("Taptree is a well formed tree with atleast 1 element")
264264
}
265+
_ => panic!("Unknown error, non_exhaustive catch all"),
265266
},
266267
}
267268
};

src/interpreter/error.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ use super::BitcoinKey;
2626
pub enum Error {
2727
/// Could not satisfy, absolute locktime not met
2828
AbsoluteLocktimeNotMet(u32),
29+
/// Could not satisfy, lock time values are different units
30+
AbsoluteLocktimeComparisonInvalid(u32, u32),
2931
/// Cannot Infer a taproot descriptor
3032
/// Key spends cannot infer the internal key of the descriptor
3133
/// Inferring script spends is possible, but is hidden nodes are currently
@@ -188,6 +190,7 @@ impl fmt::Display for Error {
188190
Error::VerifyFailed => {
189191
f.write_str("Expected Satisfied Boolean at stack top for VERIFY")
190192
}
193+
_ => f.write_str("Unknown error, non_exhaustive catch all"),
191194
}
192195
}
193196
}
@@ -234,6 +237,7 @@ impl error::Error for Error {
234237
Secp(e) => Some(e),
235238
SchnorrSig(e) => Some(e),
236239
SighashError(e) => Some(e),
240+
_ => None // non_exhaustive catch all.
237241
}
238242
}
239243
}

src/interpreter/mod.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use std::str::FromStr;
2626
use bitcoin::blockdata::witness::Witness;
2727
use bitcoin::hashes::{hash160, ripemd160, sha256, sha256d};
2828
use bitcoin::util::{sighash, taproot};
29-
use bitcoin::{self, secp256k1, TxOut};
29+
use bitcoin::{self, secp256k1, TxOut, LockTime};
3030

3131
use crate::miniscript::context::NoChecks;
3232
use crate::miniscript::ScriptContext;
@@ -48,7 +48,7 @@ pub struct Interpreter<'txin> {
4848
/// For non-Taproot spends, the scriptCode; for Taproot script-spends, this
4949
/// is the leaf script; for key-spends it is `None`.
5050
script_code: Option<bitcoin::Script>,
51-
age: u32,
51+
age: LockTime,
5252
height: u32,
5353
}
5454

@@ -169,7 +169,7 @@ impl<'txin> Interpreter<'txin> {
169169
spk: &bitcoin::Script,
170170
script_sig: &'txin bitcoin::Script,
171171
witness: &'txin Witness,
172-
age: u32,
172+
age: LockTime,
173173
height: u32,
174174
) -> Result<Self, Error> {
175175
let (inner, stack, script_code) = inner::from_txdata(spk, script_sig, witness)?;
@@ -492,7 +492,7 @@ pub enum SatisfiedConstraint {
492492
///Absolute Timelock for CLTV.
493493
AbsoluteTimelock {
494494
/// The value of Absolute timelock
495-
time: u32,
495+
time: LockTime,
496496
},
497497
}
498498

@@ -527,7 +527,7 @@ pub struct Iter<'intp, 'txin: 'intp> {
527527
public_key: Option<&'intp BitcoinKey>,
528528
state: Vec<NodeEvaluationState<'intp>>,
529529
stack: Stack<'txin>,
530-
age: u32,
530+
age: LockTime,
531531
height: u32,
532532
has_errored: bool,
533533
}
@@ -1130,7 +1130,7 @@ mod tests {
11301130
n_evaluated: 0,
11311131
n_satisfied: 0,
11321132
}],
1133-
age: 1002,
1133+
age: LockTime::from(1002),
11341134
height: 1002,
11351135
has_errored: false,
11361136
}
@@ -1197,7 +1197,7 @@ mod tests {
11971197
let after_satisfied: Result<Vec<SatisfiedConstraint>, Error> = constraints.collect();
11981198
assert_eq!(
11991199
after_satisfied.unwrap(),
1200-
vec![SatisfiedConstraint::AbsoluteTimelock { time: 1000 }]
1200+
vec![SatisfiedConstraint::AbsoluteTimelock { time: LockTime::from(1000) }]
12011201
);
12021202

12031203
//Check Older

src/interpreter/stack.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use bitcoin;
1818
use bitcoin::blockdata::{opcodes, script};
1919
use bitcoin::hashes::{hash160, ripemd160, sha256, sha256d, Hash};
20+
use bitcoin::{locktime, LockTime};
2021

2122
use super::error::PkEvalErrInner;
2223
use super::{
@@ -230,14 +231,16 @@ impl<'txin> Stack<'txin> {
230231
/// booleans
231232
pub(super) fn evaluate_after(
232233
&mut self,
233-
n: &u32,
234-
age: u32,
234+
n: &LockTime,
235+
age: LockTime,
235236
) -> Option<Result<SatisfiedConstraint, Error>> {
236-
if age >= *n {
237-
self.push(Element::Satisfied);
238-
Some(Ok(SatisfiedConstraint::AbsoluteTimelock { time: *n }))
239-
} else {
240-
Some(Err(Error::AbsoluteLocktimeNotMet(*n)))
237+
match locktime::is_satisfied(*n, age) {
238+
Ok(true) => {
239+
self.push(Element::Satisfied);
240+
Some(Ok(SatisfiedConstraint::AbsoluteTimelock { time: *n }))
241+
},
242+
Ok(false) => Some(Err(Error::AbsoluteLocktimeNotMet(n.to_u32()))),
243+
Err(_) => Some(Err(Error::AbsoluteLocktimeComparisonInvalid(n.to_u32(), age.to_u32()))),
241244
}
242245
}
243246

src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,6 @@ pub mod interpreter;
104104
pub mod miniscript;
105105
pub mod policy;
106106
pub mod psbt;
107-
pub mod timelock;
108107

109108
mod util;
110109

src/miniscript/astelem.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use std::str::FromStr;
2323
use std::sync::Arc;
2424
use std::{fmt, str};
2525

26+
use bitcoin::LockTime;
2627
use bitcoin::blockdata::{opcodes, script};
2728
use bitcoin::hashes::hex::FromHex;
2829
use bitcoin::hashes::{hash160, ripemd160, sha256, sha256d, Hash};
@@ -491,7 +492,7 @@ where
491492
expression::terminal(&top.args[0], |x| Pk::Hash::from_str(x).map(Terminal::PkH))
492493
}
493494
("after", 1) => expression::terminal(&top.args[0], |x| {
494-
expression::parse_num(x).map(Terminal::After)
495+
expression::parse_num(x).map(|x| Terminal::After(LockTime::from(x)))
495496
}),
496497
("older", 1) => expression::terminal(&top.args[0], |x| {
497498
expression::parse_num(x).map(Terminal::Older)
@@ -653,7 +654,7 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Terminal<Pk, Ctx> {
653654
.push_slice(&Pk::hash_to_hash160(hash)[..])
654655
.push_opcode(opcodes::all::OP_EQUALVERIFY),
655656
Terminal::After(t) => builder
656-
.push_int(t as i64)
657+
.push_int(t.to_u32() as i64)
657658
.push_opcode(opcodes::all::OP_CLTV),
658659
Terminal::Older(t) => builder.push_int(t as i64).push_opcode(opcodes::all::OP_CSV),
659660
Terminal::Sha256(h) => builder
@@ -788,7 +789,7 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Terminal<Pk, Ctx> {
788789
match *self {
789790
Terminal::PkK(ref pk) => Ctx::pk_len(pk),
790791
Terminal::PkH(..) => 24,
791-
Terminal::After(n) => script_num_size(n as usize) + 1,
792+
Terminal::After(n) => script_num_size(n.to_u32() as usize) + 1,
792793
Terminal::Older(n) => script_num_size(n as usize) + 1,
793794
Terminal::Sha256(..) => 33 + 6,
794795
Terminal::Hash256(..) => 33 + 6,

src/miniscript/decode.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ use bitcoin::hashes::{hash160, ripemd160, sha256, sha256d, Hash};
2626

2727
use crate::miniscript::lex::{Token as Tk, TokenIter};
2828
use crate::miniscript::limits::MAX_PUBKEYS_PER_MULTISIG;
29+
use crate::bitcoin::locktime::LockTime;
2930
use crate::miniscript::types::extra_props::ExtData;
3031
use crate::miniscript::types::{Property, Type};
3132
use crate::miniscript::ScriptContext;
@@ -133,7 +134,7 @@ pub enum Terminal<Pk: MiniscriptKey, Ctx: ScriptContext> {
133134
PkH(Pk::Hash),
134135
// timelocks
135136
/// `n CHECKLOCKTIMEVERIFY`
136-
After(u32),
137+
After(LockTime),
137138
/// `n CHECKSEQUENCEVERIFY`
138139
Older(u32),
139140
// hashlocks
@@ -388,7 +389,7 @@ pub fn parse<Ctx: ScriptContext>(
388389
Tk::CheckSequenceVerify, Tk::Num(n)
389390
=> term.reduce0(Terminal::Older(n))?,
390391
Tk::CheckLockTimeVerify, Tk::Num(n)
391-
=> term.reduce0(Terminal::After(n))?,
392+
=> term.reduce0(Terminal::After(LockTime::from(n)))?,
392393
// hashlocks
393394
Tk::Equal => match_token!(
394395
tokens,

0 commit comments

Comments
 (0)