Skip to content

Commit 9b49fec

Browse files
committed
miniscript: add CONSENSUS and SANE consts to all contexts
We are going to move all of the logic currently ad-hoc spread across the various "global"/"local" "consensus"/"policy" checks and other related checks into a single validate() method implemented on Miniscript, Policy, Semantic and possibly other types. This validate() method will have an understanding of which checks are "local" (i.e. computable from a single node) and which are "global" (i.e. require looking at the whole script). This distinction is not meaningful to an end user and it's hard for even developers to keep track of. For a user, all the checks are just checks, and their knob belongs in the big ValidationParams structure.
1 parent 9320f36 commit 9b49fec

1 file changed

Lines changed: 75 additions & 1 deletion

File tree

src/miniscript/context.rs

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use crate::miniscript::limits::{
1515
};
1616
use crate::miniscript::types;
1717
use crate::prelude::*;
18-
use crate::{hash256, Error, ForEachKey, Miniscript, MiniscriptKey, Terminal};
18+
use crate::{hash256, Error, ForEachKey, Miniscript, MiniscriptKey, Terminal, ValidationParams};
1919

2020
/// Error for Script Context
2121
#[derive(Clone, PartialEq, Eq, Debug)]
@@ -176,6 +176,18 @@ where
176176
{
177177
/// The consensus key associated with the type. Must be a parseable key
178178
type Key: ParseableKey;
179+
180+
/// The validation parameters enforcing consensus limits in this context, and
181+
/// nothing further.
182+
const CONSENSUS: ValidationParams;
183+
184+
/// Sensible validation parameters for this context. Unless you have a good reason
185+
/// to choose otherwise, these are the validation parameters you want.
186+
///
187+
/// They are also the validation parameters used throughout this library when no
188+
/// explicit choice of parameters is made.
189+
const SANE: ValidationParams;
190+
179191
/// Depending on ScriptContext, fragments can be malleable. For Example,
180192
/// under Legacy context, PkH is malleable because it is possible to
181193
/// estimate the cost of satisfaction because of compressed keys
@@ -359,6 +371,20 @@ pub enum Legacy {}
359371

360372
impl ScriptContext for Legacy {
361373
type Key = bitcoin::PublicKey;
374+
375+
const CONSENSUS: ValidationParams = ValidationParams {
376+
allow_compressed_keys: true,
377+
allow_dup_if: false,
378+
allow_uncompressed_keys: true,
379+
allow_multi_a: false,
380+
allow_or_i: false,
381+
allow_x_only_keys: false,
382+
max_opcode_count: MAX_OPS_PER_SCRIPT,
383+
max_script_size: MAX_SCRIPT_ELEMENT_SIZE,
384+
..ValidationParams::CONSENSUS
385+
};
386+
const SANE: ValidationParams = Self::CONSENSUS.intersect(&ValidationParams::SANE);
387+
362388
fn check_terminal_non_malleable<Pk: MiniscriptKey>(
363389
frag: &Terminal<Pk, Self>,
364390
) -> Result<(), ScriptContextError> {
@@ -467,6 +493,22 @@ pub enum Segwitv0 {}
467493

468494
impl ScriptContext for Segwitv0 {
469495
type Key = bitcoin::PublicKey;
496+
497+
const CONSENSUS: ValidationParams = ValidationParams {
498+
allow_compressed_keys: true,
499+
allow_uncompressed_keys: false,
500+
allow_multi_a: false,
501+
allow_x_only_keys: false,
502+
max_opcode_count: MAX_OPS_PER_SCRIPT,
503+
max_exec_stack_size: MAX_STACK_SIZE,
504+
..ValidationParams::CONSENSUS
505+
};
506+
const SANE: ValidationParams = ValidationParams {
507+
max_script_size: MAX_STANDARD_P2WSH_SCRIPT_SIZE,
508+
max_witness_items: MAX_STANDARD_P2WSH_STACK_ITEMS,
509+
..Self::CONSENSUS.intersect(&ValidationParams::SANE)
510+
};
511+
470512
fn check_terminal_non_malleable<Pk: MiniscriptKey>(
471513
_frag: &Terminal<Pk, Self>,
472514
) -> Result<(), ScriptContextError> {
@@ -580,6 +622,20 @@ pub enum Tap {}
580622

581623
impl ScriptContext for Tap {
582624
type Key = bitcoin::secp256k1::XOnlyPublicKey;
625+
626+
const CONSENSUS: ValidationParams = ValidationParams {
627+
allow_compressed_keys: false,
628+
allow_uncompressed_keys: false,
629+
allow_multi: false,
630+
allow_x_only_keys: true,
631+
..ValidationParams::CONSENSUS
632+
};
633+
const SANE: ValidationParams = ValidationParams {
634+
max_script_size: MAX_STANDARD_P2WSH_SCRIPT_SIZE,
635+
max_witness_items: MAX_STANDARD_P2WSH_STACK_ITEMS,
636+
..Self::CONSENSUS.intersect(&ValidationParams::SANE)
637+
};
638+
583639
fn check_terminal_non_malleable<Pk: MiniscriptKey>(
584640
_frag: &Terminal<Pk, Self>,
585641
) -> Result<(), ScriptContextError> {
@@ -691,6 +747,20 @@ pub enum BareCtx {}
691747

692748
impl ScriptContext for BareCtx {
693749
type Key = bitcoin::PublicKey;
750+
751+
const CONSENSUS: ValidationParams = ValidationParams {
752+
allow_compressed_keys: true,
753+
allow_dup_if: false,
754+
allow_uncompressed_keys: true,
755+
allow_multi_a: false,
756+
allow_or_i: false,
757+
allow_x_only_keys: false,
758+
max_opcode_count: MAX_OPS_PER_SCRIPT,
759+
max_script_size: MAX_SCRIPT_SIZE,
760+
..ValidationParams::CONSENSUS
761+
};
762+
const SANE: ValidationParams = Self::CONSENSUS.intersect(&ValidationParams::SANE);
763+
694764
fn check_terminal_non_malleable<Pk: MiniscriptKey>(
695765
_frag: &Terminal<Pk, Self>,
696766
) -> Result<(), ScriptContextError> {
@@ -801,6 +871,10 @@ pub enum NoChecks {}
801871
impl ScriptContext for NoChecks {
802872
// todo: When adding support for interpreter, we need a enum with all supported keys here
803873
type Key = bitcoin::PublicKey;
874+
875+
const CONSENSUS: ValidationParams = ValidationParams::MAX;
876+
const SANE: ValidationParams = ValidationParams::MAX;
877+
804878
fn check_terminal_non_malleable<Pk: MiniscriptKey>(
805879
_frag: &Terminal<Pk, Self>,
806880
) -> Result<(), ScriptContextError> {

0 commit comments

Comments
 (0)