@@ -25,7 +25,7 @@ use std::{error, fmt};
2525pub use self :: correctness:: { Base , Correctness , Input } ;
2626pub use self :: extra_props:: ExtData ;
2727pub use self :: malleability:: { Dissat , Malleability } ;
28- use super :: ScriptContext ;
28+ use super :: { limits :: SEQUENCE_LOCKTIME_DISABLE_FLAG , ScriptContext } ;
2929use MiniscriptKey ;
3030use Terminal ;
3131
@@ -38,8 +38,8 @@ fn return_none<T>(_: usize) -> Option<T> {
3838/// Detailed type of a typechecker error
3939#[ derive( Copy , Clone , PartialEq , Eq , PartialOrd , Ord , Hash , Debug ) ]
4040pub 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 ,
4343 /// Passed a `z` argument to a `d` wrapper when `z` was expected
4444 NonZeroDupIf ,
4545 /// 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> {
117117impl < Pk : MiniscriptKey , Ctx : ScriptContext > fmt:: Display for Error < Pk , Ctx > {
118118 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
119119 match self . error {
120- ErrorKind :: ZeroTime => write ! (
120+ ErrorKind :: InvalidTime => write ! (
121121 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] )" ,
123123 self . fragment,
124124 ) ,
125125 ErrorKind :: NonZeroDupIf => write ! (
@@ -426,20 +426,22 @@ pub trait Property: Sized {
426426 Ok ( Self :: from_multi ( k, pks. len ( ) ) )
427427 }
428428 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 {
430433 return Err ( Error {
431434 fragment : fragment. clone ( ) ,
432- error : ErrorKind :: ZeroTime ,
435+ error : ErrorKind :: InvalidTime ,
433436 } ) ;
434437 }
435438 Ok ( Self :: from_after ( t) )
436439 }
437440 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 {
440442 return Err ( Error {
441443 fragment : fragment. clone ( ) ,
442- error : ErrorKind :: ZeroTime ,
444+ error : ErrorKind :: InvalidTime ,
443445 } ) ;
444446 }
445447 Ok ( Self :: from_older ( t) )
@@ -803,20 +805,22 @@ impl Property for Type {
803805 Ok ( Self :: from_multi ( k, pks. len ( ) ) )
804806 }
805807 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 {
808812 return Err ( Error {
809813 fragment : fragment. clone ( ) ,
810- error : ErrorKind :: ZeroTime ,
814+ error : ErrorKind :: InvalidTime ,
811815 } ) ;
812816 }
813817 Ok ( Self :: from_after ( t) )
814818 }
815819 Terminal :: Older ( t) => {
816- if t == 0 {
820+ if t == 0 || ( t & SEQUENCE_LOCKTIME_DISABLE_FLAG ) == 1 {
817821 return Err ( Error {
818822 fragment : fragment. clone ( ) ,
819- error : ErrorKind :: ZeroTime ,
823+ error : ErrorKind :: InvalidTime ,
820824 } ) ;
821825 }
822826 Ok ( Self :: from_older ( t) )
0 commit comments