Skip to content

Commit da806be

Browse files
authored
refactor: check the node syntax before size limit
1 parent 4d913ee commit da806be

File tree

1 file changed

+57
-24
lines changed

1 file changed

+57
-24
lines changed

src/miniscript/context.rs

+57-24
Original file line numberDiff line numberDiff line change
@@ -394,11 +394,8 @@ impl ScriptContext for Legacy {
394394
fn check_global_consensus_validity<Pk: MiniscriptKey>(
395395
ms: &Miniscript<Pk, Self>,
396396
) -> Result<(), ScriptContextError> {
397-
if ms.ext.pk_cost > MAX_SCRIPT_ELEMENT_SIZE {
398-
return Err(ScriptContextError::MaxRedeemScriptSizeExceeded);
399-
}
400-
401-
match ms.node {
397+
// 1. Check the node first, throw an error on the language itself
398+
let node_checked = match ms.node {
402399
Terminal::PkK(ref pk) => Self::check_pk(pk),
403400
Terminal::Multi(ref thresh) => {
404401
for pk in thresh.iter() {
@@ -408,6 +405,17 @@ impl ScriptContext for Legacy {
408405
}
409406
Terminal::MultiA(..) => Err(ScriptContextError::MultiANotAllowed),
410407
_ => Ok(()),
408+
};
409+
// 2. After fragment and param check, validate the script size finally
410+
match node_checked {
411+
Ok(_) => {
412+
if ms.ext.pk_cost > MAX_SCRIPT_ELEMENT_SIZE {
413+
Err(ScriptContextError::MaxRedeemScriptSizeExceeded)
414+
} else {
415+
Ok(())
416+
}
417+
}
418+
Err(_) => node_checked,
411419
}
412420
}
413421

@@ -492,11 +500,8 @@ impl ScriptContext for Segwitv0 {
492500
fn check_global_consensus_validity<Pk: MiniscriptKey>(
493501
ms: &Miniscript<Pk, Self>,
494502
) -> Result<(), ScriptContextError> {
495-
if ms.ext.pk_cost > MAX_SCRIPT_SIZE {
496-
return Err(ScriptContextError::MaxWitnessScriptSizeExceeded);
497-
}
498-
499-
match ms.node {
503+
// 1. Check the node first, throw an error on the language itself
504+
let node_checked = match ms.node {
500505
Terminal::PkK(ref pk) => Self::check_pk(pk),
501506
Terminal::Multi(ref thresh) => {
502507
for pk in thresh.iter() {
@@ -506,6 +511,17 @@ impl ScriptContext for Segwitv0 {
506511
}
507512
Terminal::MultiA(..) => Err(ScriptContextError::MultiANotAllowed),
508513
_ => Ok(()),
514+
};
515+
// 2. After fragment and param check, validate the script size finally
516+
match node_checked {
517+
Ok(_) => {
518+
if ms.ext.pk_cost > MAX_SCRIPT_SIZE {
519+
Err(ScriptContextError::MaxWitnessScriptSizeExceeded)
520+
} else {
521+
Ok(())
522+
}
523+
}
524+
Err(_) => node_checked,
509525
}
510526
}
511527

@@ -598,16 +614,8 @@ impl ScriptContext for Tap {
598614
fn check_global_consensus_validity<Pk: MiniscriptKey>(
599615
ms: &Miniscript<Pk, Self>,
600616
) -> Result<(), ScriptContextError> {
601-
// No script size checks for global consensus rules
602-
// Should we really check for block limits here.
603-
// When the transaction sizes get close to block limits,
604-
// some guarantees are not easy to satisfy because of knapsack
605-
// constraints
606-
if ms.ext.pk_cost as u64 > Weight::MAX_BLOCK.to_wu() {
607-
return Err(ScriptContextError::MaxWitnessScriptSizeExceeded);
608-
}
609-
610-
match ms.node {
617+
// 1. Check the node first, throw an error on the language itself
618+
let node_checked = match ms.node {
611619
Terminal::PkK(ref pk) => Self::check_pk(pk),
612620
Terminal::MultiA(ref thresh) => {
613621
for pk in thresh.iter() {
@@ -617,6 +625,22 @@ impl ScriptContext for Tap {
617625
}
618626
Terminal::Multi(..) => Err(ScriptContextError::TaprootMultiDisabled),
619627
_ => Ok(()),
628+
};
629+
// 2. After fragment and param check, validate the script size finally
630+
match node_checked {
631+
Ok(_) => {
632+
// No script size checks for global consensus rules
633+
// Should we really check for block limits here.
634+
// When the transaction sizes get close to block limits,
635+
// some guarantees are not easy to satisfy because of knapsack
636+
// constraints
637+
if ms.ext.pk_cost as u64 > Weight::MAX_BLOCK.to_wu() {
638+
Err(ScriptContextError::MaxWitnessScriptSizeExceeded)
639+
} else {
640+
Ok(())
641+
}
642+
}
643+
Err(_) => node_checked,
620644
}
621645
}
622646

@@ -700,10 +724,8 @@ impl ScriptContext for BareCtx {
700724
fn check_global_consensus_validity<Pk: MiniscriptKey>(
701725
ms: &Miniscript<Pk, Self>,
702726
) -> Result<(), ScriptContextError> {
703-
if ms.ext.pk_cost > MAX_SCRIPT_SIZE {
704-
return Err(ScriptContextError::MaxWitnessScriptSizeExceeded);
705-
}
706-
match ms.node {
727+
// 1. Check the node first, throw an error on the language itself
728+
let node_checked = match ms.node {
707729
Terminal::PkK(ref key) => Self::check_pk(key),
708730
Terminal::Multi(ref thresh) => {
709731
for pk in thresh.iter() {
@@ -713,6 +735,17 @@ impl ScriptContext for BareCtx {
713735
}
714736
Terminal::MultiA(..) => Err(ScriptContextError::MultiANotAllowed),
715737
_ => Ok(()),
738+
};
739+
// 2. After fragment and param check, validate the script size finally
740+
match node_checked {
741+
Ok(_) => {
742+
if ms.ext.pk_cost > MAX_SCRIPT_SIZE {
743+
Err(ScriptContextError::MaxWitnessScriptSizeExceeded)
744+
} else {
745+
Ok(())
746+
}
747+
}
748+
Err(_) => node_checked,
716749
}
717750
}
718751

0 commit comments

Comments
 (0)