@@ -25,7 +25,7 @@ use std::{error, fmt};
25
25
pub use self :: correctness:: { Base , Correctness , Input } ;
26
26
pub use self :: extra_props:: ExtData ;
27
27
pub use self :: malleability:: { Dissat , Malleability } ;
28
- use super :: ScriptContext ;
28
+ use super :: { limits :: SEQUENCE_LOCKTIME_DISABLE_FLAG , ScriptContext } ;
29
29
use MiniscriptKey ;
30
30
use Terminal ;
31
31
@@ -38,8 +38,8 @@ fn return_none<T>(_: usize) -> Option<T> {
38
38
/// Detailed type of a typechecker error
39
39
#[ derive( Copy , Clone , PartialEq , Eq , PartialOrd , Ord , Hash , Debug ) ]
40
40
pub enum ErrorKind {
41
- /// Relative or absolute timelock had a time value of 0
42
- ZeroTime ,
41
+ /// Relative or absolute timelock had an invalid time value (either 0, or >=0x80000000)
42
+ InvalidTime ,
43
43
/// Passed a `z` argument to a `d` wrapper when `z` was expected
44
44
NonZeroDupIf ,
45
45
/// Multisignature or threshold policy had a `k` value of 0
@@ -117,9 +117,9 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> error::Error for Error<Pk, Ctx> {
117
117
impl < Pk : MiniscriptKey , Ctx : ScriptContext > fmt:: Display for Error < Pk , Ctx > {
118
118
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
119
119
match self . error {
120
- ErrorKind :: ZeroTime => write ! (
120
+ ErrorKind :: InvalidTime => write ! (
121
121
f,
122
- "fragment «{}» represents a 0-valued timelock (use `1` instead )" ,
122
+ "fragment «{}» represents a timelock which value is invalid (time must be in [1; 0x80000000] )" ,
123
123
self . fragment,
124
124
) ,
125
125
ErrorKind :: NonZeroDupIf => write ! (
@@ -426,20 +426,22 @@ pub trait Property: Sized {
426
426
Ok ( Self :: from_multi ( k, pks. len ( ) ) )
427
427
}
428
428
Terminal :: After ( t) => {
429
- if t == 0 {
429
+ // Note that for CLTV this is a limitation not of Bitcoin but Miniscript. The
430
+ // number on the stack would be a 5 bytes signed integer but Miniscript's B type
431
+ // only consumes 4 bytes from the stack.
432
+ if t == 0 || ( t & SEQUENCE_LOCKTIME_DISABLE_FLAG ) == 1 {
430
433
return Err ( Error {
431
434
fragment : fragment. clone ( ) ,
432
- error : ErrorKind :: ZeroTime ,
435
+ error : ErrorKind :: InvalidTime ,
433
436
} ) ;
434
437
}
435
438
Ok ( Self :: from_after ( t) )
436
439
}
437
440
Terminal :: Older ( t) => {
438
- // FIXME check if t > 2^31 - 1
439
- if t == 0 {
441
+ if t == 0 || ( t & SEQUENCE_LOCKTIME_DISABLE_FLAG ) == 1 {
440
442
return Err ( Error {
441
443
fragment : fragment. clone ( ) ,
442
- error : ErrorKind :: ZeroTime ,
444
+ error : ErrorKind :: InvalidTime ,
443
445
} ) ;
444
446
}
445
447
Ok ( Self :: from_older ( t) )
@@ -803,20 +805,22 @@ impl Property for Type {
803
805
Ok ( Self :: from_multi ( k, pks. len ( ) ) )
804
806
}
805
807
Terminal :: After ( t) => {
806
- // FIXME check if t > 2^31 - 1
807
- if t == 0 {
808
+ // Note that for CLTV this is a limitation not of Bitcoin but Miniscript. The
809
+ // number on the stack would be a 5 bytes signed integer but Miniscript's B type
810
+ // only consumes 4 bytes from the stack.
811
+ if t == 0 || ( t & SEQUENCE_LOCKTIME_DISABLE_FLAG ) == 1 {
808
812
return Err ( Error {
809
813
fragment : fragment. clone ( ) ,
810
- error : ErrorKind :: ZeroTime ,
814
+ error : ErrorKind :: InvalidTime ,
811
815
} ) ;
812
816
}
813
817
Ok ( Self :: from_after ( t) )
814
818
}
815
819
Terminal :: Older ( t) => {
816
- if t == 0 {
820
+ if t == 0 || ( t & SEQUENCE_LOCKTIME_DISABLE_FLAG ) == 1 {
817
821
return Err ( Error {
818
822
fragment : fragment. clone ( ) ,
819
- error : ErrorKind :: ZeroTime ,
823
+ error : ErrorKind :: InvalidTime ,
820
824
} ) ;
821
825
}
822
826
Ok ( Self :: from_older ( t) )
0 commit comments