@@ -65,6 +65,8 @@ pub enum ScriptContextError {
6565 ImpossibleSatisfaction ,
6666 /// No Multi Node in Taproot context
6767 TaprootMultiDisabled ,
68+ /// Stack size exceeded in script execution
69+ StackSizeLimitExceeded ,
6870}
6971
7072impl fmt:: Display for ScriptContextError {
@@ -122,6 +124,12 @@ impl fmt::Display for ScriptContextError {
122124 ScriptContextError :: TaprootMultiDisabled => {
123125 write ! ( f, "No Multi node in taproot context" )
124126 }
127+ ScriptContextError :: StackSizeLimitExceeded => {
128+ write ! (
129+ f,
130+ "Stack limit can exceed in atleast one script path during script execution"
131+ )
132+ }
125133 }
126134 }
127135}
@@ -525,7 +533,7 @@ impl ScriptContext for Tap {
525533 }
526534
527535 fn check_local_consensus_validity < Pk : MiniscriptKey , Ctx : ScriptContext > (
528- _ms : & Miniscript < Pk , Ctx > ,
536+ ms : & Miniscript < Pk , Ctx > ,
529537 ) -> Result < ( ) , ScriptContextError > {
530538 // Taproot introduces the concept of sigops budget.
531539 // All valid miniscripts satisfy the sigops constraint
@@ -536,6 +544,14 @@ impl ScriptContext for Tap {
536544 // will have it's corresponding 64 bytes signature.
537545 // sigops budget = witness_script.len() + witness.size() + 50
538546 // Each signature will cover it's own cost(64 > 50) and thus will will never exceed the budget
547+ if let ( Some ( s) , Some ( h) ) = (
548+ ms. ext . exec_stack_elem_count_sat ,
549+ ms. ext . stack_elem_count_sat ,
550+ ) {
551+ if s + h > MAX_STACK_SIZE {
552+ return Err ( ScriptContextError :: StackSizeLimitExceeded ) ;
553+ }
554+ }
539555 Ok ( ( ) )
540556 }
541557
@@ -549,7 +565,6 @@ impl ScriptContext for Tap {
549565 fn check_local_policy_validity < Pk : MiniscriptKey , Ctx : ScriptContext > (
550566 _ms : & Miniscript < Pk , Ctx > ,
551567 ) -> Result < ( ) , ScriptContextError > {
552- // TODO: check for policy execution.
553568 Ok ( ( ) )
554569 }
555570
0 commit comments