Skip to content

Instantly share code, notes, and snippets.

@sanket1729
Created October 29, 2020 00:41
Show Gist options
  • Save sanket1729/d6c9e3611903295900fe3a6ca1f5bb48 to your computer and use it in GitHub Desktop.
Save sanket1729/d6c9e3611903295900fe3a6ca1f5bb48 to your computer and use it in GitHub Desktop.
pub trait ScriptContext:
fmt::Debug + Clone + Ord + PartialOrd + Eq + PartialEq + private::Sealed
{
/// Depending on ScriptContext, fragments can be malleable. For Example,
/// under Legacy context, PkH is malleable because it is possible to
/// estimate the cost of satisfaction because of compressed keys
/// This is currently only used in compiler code for removing malleable
/// compilations.
/// This does NOT recursively check if the children of the fragment are
/// valid or not. Since the compilation proceeds in a leaf to root fashion,
/// a recursive check is unnecessary.
fn check_frag_non_malleable<Pk: MiniscriptKey, Ctx: ScriptContext>(
_frag: &Terminal<Pk, Ctx>,
) -> Result<(), ScriptContextError>;
/// Depending on script Context, some of the Terminals might not
/// be valid under the current consensus rules.
/// Or some of the script resource limits may have been exceeded.
/// These miniscripts would never be accepted by the Bitcoin network and hence
/// it is safe to discard them
/// For example, in Segwit Context with MiniscriptKey as bitcoin::PublicKey
/// uncompressed public keys are non-standard and thus invalid.
/// In LegacyP2SH context, scripts above 520 bytes are invalid.
/// Post Tapscript upgrade, this would have to consider other nodes.
/// This does *NOT* recursively check the miniscript fragments.
fn check_non_satisfaction_consensus_rules<Pk: MiniscriptKey, Ctx: ScriptContext>(
_frag: &Terminal<Pk, Ctx>,
) -> Result<(), ScriptContextError>;
/// Depending on script Context, some of the script resource limits
/// may have been exceeded under the current bitcoin core policy rules
/// These miniscripts would never be accepted by the Bitcoin network and hence
/// it is safe to discard them. (unless explicity disabled by non-standard flag)
/// For example, in Segwit Context with MiniscriptKey as bitcoin::PublicKey
/// scripts over 3600 bytes are invalid.
/// In Bare context, only c:pk(key) (P2PK),
/// c:pk_h(key) (P2PKH), and thresh_m(k,...) up to n=3 are allowed
/// Post Tapscript upgrade, this would have to consider other nodes.
/// This does *NOT* recursively check the miniscript fragments.
fn check_non_satisfaction_policy_rules<Pk: MiniscriptKey, Ctx: ScriptContext>(
_frag: &Terminal<Pk, Ctx>,
) -> Result<(), ScriptContextError>;
/// Consensus rules at the Miniscript satisfaction time.
/// It is possible that some paths of miniscript may exceed resource limits
/// and our current satisfier and lifting analysis would not work correctly.
/// For example, satisfaction path(Legacy/Segwitv0) may require more than 201 opcodes.
fn check_satisfaction_consensus_rules<Pk: MiniscriptKey, Ctx: ScriptContext>(
_frag: &Terminal<Pk, Ctx>,
) -> Result<(), ScriptContextError>;
/// Policy rules at the Miniscript satisfaction time.
/// It is possible that some paths of miniscript may exceed resource limits
/// and our current satisfier and lifting analysis would not work correctly.
/// For example, satisfaction path in Legacy context scriptSig more
/// than 1650 bytes
fn check_satisfaction_policy_rules<Pk: MiniscriptKey, Ctx: ScriptContext>(
_frag: &Terminal<Pk, Ctx>,
) -> Result<(), ScriptContextError>;
/// Check the consensus + policy(if not disabled) rules that are not based
/// satisfaction
fn check_non_satisfaction_rules<Pk: MiniscriptKey, Ctx: ScriptContext>(
_frag: &Terminal<Pk, Ctx>,
) -> Result<(), ScriptContextError> {
check_non_satisfaction_consensus_rules(_frag)?;
#[cfg(not(feature = "non-standard"))]
check_non_satisfaction_policy_rules(_frag)?;
}
/// Check the consensus + policy(if not disabled) rules including the
/// ones for satisfaction
fn check_satisfaction_rules<Pk: MiniscriptKey, Ctx: ScriptContext>(
_frag: &Terminal<Pk, Ctx>,
) -> Result<(), ScriptContextError> {
check_non_satisfaction_consensus_rules(_frag)?;
#[cfg(not(feature = "non-standard"))]
check_non_satisfaction_consensus_rules(_frag)?;
check_satisfaction_policy_rules(_frag)?;
#[cfg(not(feature = "non-standard"))]
check_satisfaction_policy_rules(_frag)?;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment