From dcda8a211aac733f3b7073d3be75b6b5d797dfaa Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Tue, 24 Oct 2023 22:37:39 +0200 Subject: [PATCH 1/7] contract: support for multiple layer 1 --- src/contract/assignments.rs | 28 +++++++++----- src/contract/contract.rs | 38 ++++++++++++++----- src/contract/mod.rs | 5 ++- src/contract/seal.rs | 76 ++++++++++++++++++++++++++++++++++++- src/validation/status.rs | 5 +++ src/validation/validator.rs | 54 +++++++++++++++++++++----- 6 files changed, 175 insertions(+), 31 deletions(-) diff --git a/src/contract/assignments.rs b/src/contract/assignments.rs index a397306f..8160b3f5 100644 --- a/src/contract/assignments.rs +++ b/src/contract/assignments.rs @@ -35,7 +35,7 @@ use super::ExposedState; use crate::contract::seal::GenesisSeal; use crate::{ AssignmentType, ExposedSeal, GraphSeal, RevealedAttach, RevealedData, RevealedValue, - SecretSeal, StateType, VoidState, LIB_NAME_RGB, + SealDefinition, SecretSeal, StateType, VoidState, LIB_NAME_RGB, }; #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Display, Error)] @@ -76,12 +76,15 @@ pub enum Assign { state: State::Confidential, }, #[strict_type(tag = 0x03)] - Revealed { seal: Seal, state: State }, + Revealed { + seal: SealDefinition, + state: State, + }, #[strict_type(tag = 0x02)] ConfidentialSeal { seal: SecretSeal, state: State }, #[strict_type(tag = 0x01)] ConfidentialState { - seal: Seal, + seal: SealDefinition, state: State::Confidential, }, } @@ -118,9 +121,11 @@ impl Hash for Assign { } impl Assign { - pub fn revealed(seal: Seal, state: State) -> Self { Assign::Revealed { seal, state } } + pub fn revealed(seal: SealDefinition, state: State) -> Self { + Assign::Revealed { seal, state } + } - pub fn with_seal_replaced(assignment: &Self, seal: Seal) -> Self { + pub fn with_seal_replaced(assignment: &Self, seal: SealDefinition) -> Self { match assignment { Assign::Confidential { seal: _, state } | Assign::ConfidentialState { seal: _, state } => Assign::ConfidentialState { @@ -145,7 +150,7 @@ impl Assign { } } - pub fn revealed_seal(&self) -> Option { + pub fn revealed_seal(&self) -> Option> { match self { Assign::Revealed { seal, .. } | Assign::ConfidentialState { seal, .. } => Some(*seal), Assign::Confidential { .. } | Assign::ConfidentialSeal { .. } => None, @@ -175,21 +180,21 @@ impl Assign { } } - pub fn as_revealed(&self) -> Option<(&Seal, &State)> { + pub fn as_revealed(&self) -> Option<(&SealDefinition, &State)> { match self { Assign::Revealed { seal, state } => Some((seal, state)), _ => None, } } - pub fn to_revealed(&self) -> Option<(Seal, State)> { + pub fn to_revealed(&self) -> Option<(SealDefinition, State)> { match self { Assign::Revealed { seal, state } => Some((*seal, state.clone())), _ => None, } } - pub fn into_revealed(self) -> Option<(Seal, State)> { + pub fn into_revealed(self) -> Option<(SealDefinition, State)> { match self { Assign::Revealed { seal, state } => Some((seal, state)), _ => None, @@ -438,7 +443,10 @@ impl TypedAssigns { /// If seal definition does not exist, returns [`UnknownDataError`]. If the /// seal is confidential, returns `Ok(None)`; otherwise returns revealed /// seal data packed as `Ok(Some(`[`Seal`]`))` - pub fn revealed_seal_at(&self, index: u16) -> Result, UnknownDataError> { + pub fn revealed_seal_at( + &self, + index: u16, + ) -> Result>, UnknownDataError> { Ok(match self { TypedAssigns::Declarative(vec) => vec .get(index as usize) diff --git a/src/contract/contract.rs b/src/contract/contract.rs index 45b8fc86..c003844b 100644 --- a/src/contract/contract.rs +++ b/src/contract/contract.rs @@ -31,7 +31,6 @@ use std::str::FromStr; use amplify::confinement::{LargeOrdMap, LargeOrdSet, SmallVec, TinyOrdMap}; use amplify::hex; -use bp::seals::txout::TxoSeal; use bp::{Outpoint, Txid}; use strict_encoding::{StrictDecode, StrictDumb, StrictEncode}; @@ -39,10 +38,31 @@ use crate::contract::contract::WitnessOrd::OffChain; use crate::{ Assign, AssignmentType, Assignments, AssignmentsRef, ContractId, ExposedSeal, ExposedState, Extension, Genesis, GlobalStateType, OpId, Operation, RevealedAttach, RevealedData, - RevealedValue, SchemaId, SealWitness, SubSchema, Transition, TypedAssigns, VoidState, - LIB_NAME_RGB, + RevealedValue, SchemaId, SealDefinition, SealWitness, SubSchema, Transition, TypedAssigns, + VoidState, LIB_NAME_RGB, }; +#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Display)] +#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] +#[strict_type(lib = LIB_NAME_RGB, tags = custom)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(crate = "serde_crate", rename_all = "camelCase") +)] +#[display(inner)] +#[non_exhaustive] +pub enum Output { + #[strict_type(tag = 0x00)] + Bitcoin(Outpoint), + #[strict_type(tag = 0x01)] + Liquid(Outpoint), + #[strict_type(tag = 0x10)] + Abraxas, + #[strict_type(tag = 0x11, dumb)] + Prime, +} + #[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Display)] #[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] #[strict_type(lib = LIB_NAME_RGB)] @@ -144,8 +164,8 @@ impl Ord for OutputAssignment { } impl OutputAssignment { - pub fn with_witness( - seal: Seal, + pub fn with_witness( + seal: SealDefinition, witness_txid: Txid, state: State, opid: OpId, @@ -160,8 +180,8 @@ impl OutputAssignment { } } - pub fn with_genesis( - seal: Seal, + pub fn with_genesis( + seal: SealDefinition, state: State, opid: OpId, ty: AssignmentType, @@ -177,8 +197,8 @@ impl OutputAssignment { } } - pub fn with_extension( - seal: Seal, + pub fn with_extension( + seal: SealDefinition, state: State, opid: OpId, ty: AssignmentType, diff --git a/src/contract/mod.rs b/src/contract/mod.rs index 5ec6aaf9..506c4a42 100644 --- a/src/contract/mod.rs +++ b/src/contract/mod.rs @@ -52,5 +52,8 @@ pub use operations::{ ContractId, Extension, Genesis, Input, Inputs, OpId, OpRef, Operation, Redeemed, Transition, Valencies, }; -pub use seal::{ExposedSeal, GenesisSeal, GraphSeal, SealWitness, SecretSeal, TxoSeal}; +pub use seal::{ + AbraxasSeal, ExposedSeal, GenesisSeal, GraphSeal, SealDefinition, SealPreimage, SealWitness, + SecretSeal, TxoSeal, +}; pub use state::{ConfidentialState, ExposedState, StateCommitment, StateData, StateType}; diff --git a/src/contract/seal.rs b/src/contract/seal.rs index 61f2fab6..8ab62ab9 100644 --- a/src/contract/seal.rs +++ b/src/contract/seal.rs @@ -23,12 +23,13 @@ use core::fmt::Debug; use std::hash::Hash; +use amplify::Bytes32; pub use bp::seals::txout::blind::{ ChainBlindSeal as GraphSeal, ParseError, SecretSeal, SingleBlindSeal as GenesisSeal, }; pub use bp::seals::txout::TxoSeal; -use bp::Txid; -use commit_verify::{CommitEncode, Conceal}; +use bp::{Outpoint, Txid}; +use commit_verify::{strategies, CommitEncode, Conceal}; use strict_encoding::{StrictDecode, StrictDumb, StrictEncode}; use crate::LIB_NAME_RGB; @@ -52,6 +53,77 @@ impl ExposedSeal for GraphSeal {} impl ExposedSeal for GenesisSeal {} +#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug)] +#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] +#[strict_type(lib = LIB_NAME_RGB)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(crate = "serde_crate", transparent) +)] +pub struct SealPreimage(Bytes32); + +#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug)] +#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] +#[strict_type(lib = LIB_NAME_RGB)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(crate = "serde_crate", rename_all = "camelCase") +)] +pub struct AbraxasSeal { + pub block_height: u32, + pub seal_index: u16, + pub blinding: u128, +} + +#[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, Debug)] +#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] +#[strict_type(lib = LIB_NAME_RGB, tags = custom, dumb = Self::Bitcoin(strict_dumb!()))] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(crate = "serde_crate", rename_all = "camelCase") +)] +#[non_exhaustive] +pub enum SealDefinition { + #[strict_type(tag = 0x00)] + Bitcoin(U), + #[strict_type(tag = 0x01)] + Liquid(U), + #[strict_type(tag = 0x10)] + Abraxas(AbraxasSeal), + #[strict_type(tag = 0x11)] + Prime(SealPreimage), +} + +impl Conceal for SealDefinition { + type Concealed = SecretSeal; + + fn conceal(&self) -> Self::Concealed { todo!() } +} + +impl commit_verify::CommitStrategy for SealDefinition { + type Strategy = strategies::ConcealStrict; +} + +impl SealDefinition { + pub fn transmutate(self) -> SealDefinition { + match self { + SealDefinition::Bitcoin(seal) => SealDefinition::Bitcoin(seal.transmutate()), + SealDefinition::Liquid(seal) => SealDefinition::Liquid(seal.transmutate()), + SealDefinition::Abraxas(seal) => SealDefinition::Abraxas(seal), + SealDefinition::Prime(seal) => SealDefinition::Prime(seal), + } + } +} + +impl SealDefinition { + pub fn outpoint(self) -> Option { todo!() } + + pub fn outpoint_or(self, txid: Txid) -> Outpoint { todo!() } +} + #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Display)] #[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] #[strict_type(lib = LIB_NAME_RGB, tags = custom, dumb = SealWitness::Genesis)] diff --git a/src/validation/status.rs b/src/validation/status.rs index 5d38dc94..a771b7fe 100644 --- a/src/validation/status.rs +++ b/src/validation/status.rs @@ -371,6 +371,11 @@ pub enum Failure { /// operation {0} is invalid: {1} ScriptFailure(OpId, String), + /// Abraxas is not yet supported as Layer 1. + UnsupportedAbraxas, + /// Prime is not yet supported as Layer 1. + UnsupportedPrime, + /// Custom error by external services on top of RGB Core. #[display(inner)] Custom(String), diff --git a/src/validation/validator.rs b/src/validation/validator.rs index 4246ad3e..e09bda7a 100644 --- a/src/validation/validator.rs +++ b/src/validation/validator.rs @@ -34,8 +34,8 @@ use crate::contract::Opout; use crate::validation::AnchoredBundle; use crate::vm::AluRuntime; use crate::{ - BundleId, ContractId, OpId, OpRef, Operation, Schema, SchemaId, SchemaRoot, Script, SubSchema, - Transition, TransitionBundle, TypedAssigns, + BundleId, ContractId, GraphSeal, OpId, OpRef, Operation, Schema, SchemaId, SchemaRoot, Script, + SealDefinition, SubSchema, Transition, TransitionBundle, TypedAssigns, }; #[derive(Clone, Debug, Display, Error, From)] @@ -419,17 +419,53 @@ impl<'consignment, 'resolver, C: ConsignmentApi, R: ResolveTx> continue; }; - let seal = match (seal.txid, self.anchor_index.get(&op)) { - (TxPtr::WitnessTx, Some(anchor)) => { + match (seal, self.anchor_index.get(&op)) { + ( + SealDefinition::Bitcoin( + seal @ GraphSeal { + txid: TxPtr::WitnessTx, + .. + }, + ) | + SealDefinition::Liquid( + seal @ GraphSeal { + txid: TxPtr::WitnessTx, + .. + }, + ), + Some(anchor), + ) => { let prev_witness_txid = anchor.txid; - seal.resolve(prev_witness_txid) + Some(seal.resolve(prev_witness_txid)) } - (TxPtr::WitnessTx, None) => { + (SealDefinition::Bitcoin(_) | SealDefinition::Liquid(_), None) => { panic!("anchor for the operation {op} was not indexed by the validator"); } - (TxPtr::Txid(txid), _) => seal.resolve(txid), - }; - seals.push(seal) + ( + SealDefinition::Bitcoin( + seal @ GraphSeal { + txid: TxPtr::Txid(txid), + .. + }, + ) | + SealDefinition::Liquid( + seal @ GraphSeal { + txid: TxPtr::Txid(txid), + .. + }, + ), + _, + ) => Some(seal.resolve(txid)), + (SealDefinition::Abraxas(_), _) => { + self.status.add_failure(Failure::UnsupportedAbraxas); + None + } + (SealDefinition::Prime(_), _) => { + self.status.add_failure(Failure::UnsupportedPrime); + None + } + } + .map(|seal| seals.push(seal)); } let message = mpc::Message::from(bundle_id); From 10ecdc595f5e0345ef925d1413a678d3749d808a Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Tue, 24 Oct 2023 22:55:07 +0200 Subject: [PATCH 2/7] contract: make Genesis commit to alternative layers 1 --- src/contract/mod.rs | 40 ++++++++++++++++++++++++++++++++++++++ src/contract/operations.rs | 5 +++-- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/contract/mod.rs b/src/contract/mod.rs index 506c4a42..4a9e3789 100644 --- a/src/contract/mod.rs +++ b/src/contract/mod.rs @@ -32,12 +32,16 @@ mod bundle; #[allow(clippy::module_inception)] mod contract; +use std::io::Write; + +use amplify::confinement::TinyOrdSet; pub use assignments::{ Assign, AssignAttach, AssignData, AssignFungible, AssignRights, Assignments, AssignmentsRef, TypedAssigns, }; pub use attachment::{AttachId, ConcealedAttach, RevealedAttach}; pub use bundle::{BundleId, BundleItem, TransitionBundle}; +use commit_verify::CommitEncode; pub use contract::{ AttachOutput, ContractHistory, ContractState, DataOutput, FungibleOutput, GlobalOrd, Opout, OpoutParseError, OutputAssignment, RightsOutput, WitnessAnchor, WitnessHeight, WitnessOrd, @@ -57,3 +61,39 @@ pub use seal::{ SecretSeal, TxoSeal, }; pub use state::{ConfidentialState, ExposedState, StateCommitment, StateData, StateType}; + +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Display)] +#[display(lowercase)] +#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] +#[strict_type(lib = super::LIB_NAME_RGB, tags = repr, into_u8, try_from_u8)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(crate = "serde_crate", rename_all = "camelCase") +)] +#[repr(u8)] +pub enum AltLayer1 { + #[strict_type(dumb)] + Liquid = 1, + Abraxas = 0x10, + Prime = 0x11, +} + +#[derive(Wrapper, Clone, PartialEq, Eq, Hash, Debug, From)] +#[wrapper(Deref)] +#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] +#[strict_type(lib = super::LIB_NAME_RGB)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(crate = "serde_crate", transparent) +)] +pub struct AltLayer1Set(TinyOrdSet); + +impl CommitEncode for AltLayer1Set { + fn commit_encode(&self, e: &mut impl Write) { + for c in self.iter() { + e.write_all(&[*c as u8]).ok(); + } + } +} diff --git a/src/contract/operations.rs b/src/contract/operations.rs index 861465a8..7e3ddf93 100644 --- a/src/contract/operations.rs +++ b/src/contract/operations.rs @@ -36,8 +36,8 @@ use strict_encoding::{StrictDeserialize, StrictEncode, StrictSerialize}; use crate::schema::{self, ExtensionType, OpFullType, OpType, SchemaId, TransitionType}; use crate::{ - AssignmentType, Assignments, AssignmentsRef, Ffv, GenesisSeal, GlobalState, GraphSeal, Opout, - ReservedByte, TypedAssigns, LIB_NAME_RGB, + AltLayer1Set, AssignmentType, Assignments, AssignmentsRef, Ffv, GenesisSeal, GlobalState, + GraphSeal, Opout, ReservedByte, TypedAssigns, LIB_NAME_RGB, }; #[derive(Wrapper, WrapperMut, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Default, From)] @@ -279,6 +279,7 @@ pub struct Genesis { pub ffv: Ffv, pub schema_id: SchemaId, pub chain: Chain, + pub alt_layer1: AltLayer1Set, pub metadata: SmallBlob, pub globals: GlobalState, pub assignments: Assignments, From 6a49a946f811e68088508ee91ff402b1c222cb51 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Wed, 25 Oct 2023 21:29:19 +0200 Subject: [PATCH 3/7] contract: comment out Prime and Abraxas seals planned for the future --- src/contract/mod.rs | 3 +-- src/contract/seal.rs | 23 +++++++---------------- src/validation/status.rs | 5 ----- src/validation/validator.rs | 18 +++++------------- 4 files changed, 13 insertions(+), 36 deletions(-) diff --git a/src/contract/mod.rs b/src/contract/mod.rs index 4a9e3789..eb230ee3 100644 --- a/src/contract/mod.rs +++ b/src/contract/mod.rs @@ -57,8 +57,7 @@ pub use operations::{ Valencies, }; pub use seal::{ - AbraxasSeal, ExposedSeal, GenesisSeal, GraphSeal, SealDefinition, SealPreimage, SealWitness, - SecretSeal, TxoSeal, + ExposedSeal, GenesisSeal, GraphSeal, SealDefinition, SealWitness, SecretSeal, TxoSeal, }; pub use state::{ConfidentialState, ExposedState, StateCommitment, StateData, StateType}; diff --git a/src/contract/seal.rs b/src/contract/seal.rs index 8ab62ab9..b686d875 100644 --- a/src/contract/seal.rs +++ b/src/contract/seal.rs @@ -23,7 +23,6 @@ use core::fmt::Debug; use std::hash::Hash; -use amplify::Bytes32; pub use bp::seals::txout::blind::{ ChainBlindSeal as GraphSeal, ParseError, SecretSeal, SingleBlindSeal as GenesisSeal, }; @@ -53,6 +52,7 @@ impl ExposedSeal for GraphSeal {} impl ExposedSeal for GenesisSeal {} +/* #[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug)] #[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] #[strict_type(lib = LIB_NAME_RGB)] @@ -62,20 +62,7 @@ impl ExposedSeal for GenesisSeal {} serde(crate = "serde_crate", transparent) )] pub struct SealPreimage(Bytes32); - -#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug)] -#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB)] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", rename_all = "camelCase") -)] -pub struct AbraxasSeal { - pub block_height: u32, - pub seal_index: u16, - pub blinding: u128, -} + */ #[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, Debug)] #[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] @@ -91,10 +78,12 @@ pub enum SealDefinition { Bitcoin(U), #[strict_type(tag = 0x01)] Liquid(U), + /* #[strict_type(tag = 0x10)] - Abraxas(AbraxasSeal), + Abraxas(SealPreimage), #[strict_type(tag = 0x11)] Prime(SealPreimage), + */ } impl Conceal for SealDefinition { @@ -112,8 +101,10 @@ impl SealDefinition { match self { SealDefinition::Bitcoin(seal) => SealDefinition::Bitcoin(seal.transmutate()), SealDefinition::Liquid(seal) => SealDefinition::Liquid(seal.transmutate()), + /* SealDefinition::Abraxas(seal) => SealDefinition::Abraxas(seal), SealDefinition::Prime(seal) => SealDefinition::Prime(seal), + */ } } } diff --git a/src/validation/status.rs b/src/validation/status.rs index a771b7fe..5d38dc94 100644 --- a/src/validation/status.rs +++ b/src/validation/status.rs @@ -371,11 +371,6 @@ pub enum Failure { /// operation {0} is invalid: {1} ScriptFailure(OpId, String), - /// Abraxas is not yet supported as Layer 1. - UnsupportedAbraxas, - /// Prime is not yet supported as Layer 1. - UnsupportedPrime, - /// Custom error by external services on top of RGB Core. #[display(inner)] Custom(String), diff --git a/src/validation/validator.rs b/src/validation/validator.rs index e09bda7a..59fce04a 100644 --- a/src/validation/validator.rs +++ b/src/validation/validator.rs @@ -419,7 +419,7 @@ impl<'consignment, 'resolver, C: ConsignmentApi, R: ResolveTx> continue; }; - match (seal, self.anchor_index.get(&op)) { + let seal = match (seal, self.anchor_index.get(&op)) { ( SealDefinition::Bitcoin( seal @ GraphSeal { @@ -436,7 +436,7 @@ impl<'consignment, 'resolver, C: ConsignmentApi, R: ResolveTx> Some(anchor), ) => { let prev_witness_txid = anchor.txid; - Some(seal.resolve(prev_witness_txid)) + seal.resolve(prev_witness_txid) } (SealDefinition::Bitcoin(_) | SealDefinition::Liquid(_), None) => { panic!("anchor for the operation {op} was not indexed by the validator"); @@ -455,17 +455,9 @@ impl<'consignment, 'resolver, C: ConsignmentApi, R: ResolveTx> }, ), _, - ) => Some(seal.resolve(txid)), - (SealDefinition::Abraxas(_), _) => { - self.status.add_failure(Failure::UnsupportedAbraxas); - None - } - (SealDefinition::Prime(_), _) => { - self.status.add_failure(Failure::UnsupportedPrime); - None - } - } - .map(|seal| seals.push(seal)); + ) => seal.resolve(txid), + }; + seals.push(seal); } let message = mpc::Message::from(bundle_id); From 95d62943888d5302fd6f311553c9547ac0e38977 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Wed, 25 Oct 2023 21:30:31 +0200 Subject: [PATCH 4/7] contract: complete SealDefinition API --- src/contract/seal.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/contract/seal.rs b/src/contract/seal.rs index b686d875..13685348 100644 --- a/src/contract/seal.rs +++ b/src/contract/seal.rs @@ -110,9 +110,19 @@ impl SealDefinition { } impl SealDefinition { - pub fn outpoint(self) -> Option { todo!() } + #[inline] + pub fn outpoint(self) -> Option { + match self { + SealDefinition::Bitcoin(seal) | SealDefinition::Liquid(seal) => seal.outpoint(), + } + } - pub fn outpoint_or(self, txid: Txid) -> Outpoint { todo!() } + #[inline] + pub fn outpoint_or(self, txid: Txid) -> Outpoint { + match self { + SealDefinition::Bitcoin(seal) | SealDefinition::Liquid(seal) => seal.outpoint_or(txid), + } + } } #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Display)] From 8eeae44caee46ba0e5b079e92f914481d647fcfc Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Wed, 25 Oct 2023 21:31:11 +0200 Subject: [PATCH 5/7] stl: update libraries --- src/stl.rs | 2 +- stl/RGB@0.1.0.sta | 382 +++++++++++++++++++++++----------------------- stl/RGB@0.1.0.stl | Bin 11270 -> 11270 bytes stl/RGB@0.1.0.sty | 64 ++++---- 4 files changed, 230 insertions(+), 218 deletions(-) diff --git a/src/stl.rs b/src/stl.rs index d4380454..9648dd7a 100644 --- a/src/stl.rs +++ b/src/stl.rs @@ -31,7 +31,7 @@ use crate::{Extension, Genesis, SubSchema, TransitionBundle, LIB_NAME_RGB}; /// Strict types id for the library providing data types for RGB consensus. pub const LIB_ID_RGB: &str = - "urn:ubideco:stl:4fGZWR5mH5zZzRZ1r7CSRe776zm3hLBUngfXc4s3vm3V#saturn-flash-emerald"; + "urn:ubideco:stl:28ZcP9sj9SC5CC52qLWM9YxxRRhXAJjwRqD98nZLmx2y#radar-inca-valid"; fn _rgb_core_stl() -> Result { LibBuilder::new(libname!(LIB_NAME_RGB), tiny_bset! { diff --git a/stl/RGB@0.1.0.sta b/stl/RGB@0.1.0.sta index 90031120..6f34bb81 100644 --- a/stl/RGB@0.1.0.sta +++ b/stl/RGB@0.1.0.sta @@ -1,5 +1,5 @@ -----BEGIN STRICT TYPE LIB----- -Id: urn:ubideco:stl:4fGZWR5mH5zZzRZ1r7CSRe776zm3hLBUngfXc4s3vm3V +Id: urn:ubideco:stl:28ZcP9sj9SC5CC52qLWM9YxxRRhXAJjwRqD98nZLmx2y Name: RGB Dependencies: urn:ubideco:stl:2YsxMW6xygK2FxFSbbBLqmzaUSytmLHHNF9DRio5zNr2, @@ -35,182 +35,182 @@ xE+ACkZpZWxkU2VtSWRrBKMUnqaVABZnn+8CtKsk9ea3imTI2dC9ZfzXo1hOjQVT ZW1JZHnhi2InWK4TAbvqB8SGn6w9UNmQEi8JpEn9P7P6he9rB1R5U2VtSWR9djJJ 9Q+7qVWrJHLyb2mPxeAJGoLpFBTbolDWJ2TH6AVJZGVudIHTLCTXw+gy2cNi/cj0 j5CdP4covDJOTeRMoeGJmxkGBlNpemluZ6gU7Ciw7VXt7q5ReaTn5Z9As/lVFhBu -m8Euchq/flYcCUZpZWxkTmFtZTYACUFsdVNjcmlwdAYCBGxpYnMACgK5swegWqdW -SYZDQm66Fgs/j4xo+ehP/c0thUAKee0PYKcwVQIt+VzI8ImjRaI/lt5RKcATtw7x -J9ghkEGV+1MKAAgAAEAAAAAAAAAAAP//AAAAAAAAAAAAAAAAAAD/AAAAAAAAAAtl -bnRyeVBvaW50cwAKAAcAAEADAAK5swegWqdWSYZDQm66Fgs/j4xo+ehP/c0thUAK -ee0PYG3voSbhvHXh/0hL+4XBNNEMMtyMHkDgaUsc1qfr3NxhAAAAAAAAAAD//wAA -AAAAACJBc3NpZ25SZXZlYWxlZEF0dGFjaEJsaW5kU2VhbFR4UHRyBAQADGNvbmZp +m8Euchq/flYcCUZpZWxkTmFtZToACUFsdExheWVyMQMDBmxpcXVpZAEHYWJyYXhh +cxAFcHJpbWURDEFsdExheWVyMVNldAUBAAkBsCg2ZxB6frvN7t0BXHE1tteKvzew +M19b8Hk9EMcio8sAAAAAAAAAAP8AAAAAAAAACUFsdVNjcmlwdAYCBGxpYnMACgK5 +swegWqdWSYZDQm66Fgs/j4xo+ehP/c0thUAKee0PYKcwVQIt+VzI8ImjRaI/lt5R +KcATtw7xJ9ghkEGV+1MKAAgAAEAAAAAAAAAAAP//AAAAAAAAAAAAAAAAAAD/AAAA +AAAAAAtlbnRyeVBvaW50cwAKAAcAAEADAAK5swegWqdWSYZDQm66Fgs/j4xo+ehP +/c0thUAKee0PYG3voSbhvHXh/0hL+4XBNNEMMtyMHkDgaUsc1qfr3NxhAAAAAAAA +AAD//wAAAAAAACJBc3NpZ25SZXZlYWxlZEF0dGFjaEJsaW5kU2VhbFR4UHRyBAQA +DGNvbmZpZGVudGlhbAAGAgRzZWFsAhcGTmmJvADTfkAEwHWpcNUkDofH0TR+LBtu +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 -lLO9Bk4Fc3RhdGUBaFM0IAzcU8ZNduK2LqpmL9o62ZG/BqspDrzQ9noDSswDCHJl -dmVhbGVkAAYCBHNlYWwCFwZOaYm8ANN+QATAdalw1SQOh8fRNH4sG25uxi7AoTd+ -tfgzfJGqb7i9lbu7y/XhxSWJRdIRdtoe1NyMxTElZQVzdGF0ZQFoUzQgDNxTxk12 -4rYuqmYv2jrZkb8GqykOvND2egNKzCFBc3NpZ25SZXZlYWxlZEF0dGFjaEJsaW5k -U2VhbFR4aWQEBAAMY29uZmlkZW50aWFsAAYCBHNlYWwCFwZOaYm8ANN+QATAdalw -1SQOh8fRNH4sG25uxi7AoTdoGeu81bMYq5ezmKVLNmXd2qcGb+jpJOcDYKmUs70G -TgVzdGF0ZQH8NEXdX88NC/+sFaR6ugUi4FuLKxswZVKHg497LeuOPQERY29uZmlk -ZW50aWFsU3RhdGUABgIEc2VhbAIXBk5pibwA035ABMB1qXDVJA6Hx9E0fiwbbm7G -LsChNwxQbJJJnFjzLy7sLFS41xZrvJgU7D6ZAkU9cS66YQnhBXN0YXRlAfw0Rd1f -zw0L/6wVpHq6BSLgW4srGzBlUoeDj3st6449AhBjb25maWRlbnRpYWxTZWFsAAYC -BHNlYWwCFwZOaYm8ANN+QATAdalw1SQOh8fRNH4sG25uxi7AoTdoGeu81bMYq5ez -mKVLNmXd2qcGb+jpJOcDYKmUs70GTgVzdGF0ZQFoUzQgDNxTxk124rYuqmYv2jrZ -kb8GqykOvND2egNKzAMIcmV2ZWFsZWQABgIEc2VhbAIXBk5pibwA035ABMB1qXDV -JA6Hx9E0fiwbbm7GLsChNwxQbJJJnFjzLy7sLFS41xZrvJgU7D6ZAkU9cS66YQnh -BXN0YXRlAWhTNCAM3FPGTXbiti6qZi/aOtmRvwarKQ680PZ6A0rMIEFzc2lnblJl -dmVhbGVkRGF0YUJsaW5kU2VhbFR4UHRyBAQADGNvbmZpZGVudGlhbAAGAgRzZWFs -AhcGTmmJvADTfkAEwHWpcNUkDofH0TR+LBtubsYuwKE3aBnrvNWzGKuXs5ilSzZl -3dqnBm/o6STnA2CplLO9Bk4Fc3RhdGUBcA1lELKCgW8ftz3lEmOTA1cIpVJhrQLg -1L5axc+n6gkBEWNvbmZpZGVudGlhbFN0YXRlAAYCBHNlYWwCFwZOaYm8ANN+QATA -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 -h5wfrW84fB7SeInA4P203tQ6MpMc7CzLrLvSrC0DCHJldmVhbGVkAAYCBHNlYWwC -FwZOaYm8ANN+QATAdalw1SQOh8fRNH4sG25uxi7AoTcMUGySSZxY8y8u7CxUuNcW -a7yYFOw+mQJFPXEuumEJ4QVzdGF0ZQHsz3qHnB+tbzh8HtJ4icDg/bTe1Doykxzs -LMusu9KsLR1Bc3NpZ25Wb2lkU3RhdGVCbGluZFNlYWxUeFB0cgQEAAxjb25maWRl -bnRpYWwABgIEc2VhbAIXBk5pibwA035ABMB1qXDVJA6Hx9E0fiwbbm7GLsChN2gZ -67zVsxirl7OYpUs2Zd3apwZv6Okk5wNgqZSzvQZOBXN0YXRlAS6ypf4XwDBEMJjg -XJsbWmzWHu12DWHey4Am02TzFuG7ARFjb25maWRlbnRpYWxTdGF0ZQAGAgRzZWFs -AhcGTmmJvADTfkAEwHWpcNUkDofH0TR+LBtubsYuwKE3frX4M3yRqm+4vZW7u8v1 -4cUliUXSEXbaHtTcjMUxJWUFc3RhdGUBLrKl/hfAMEQwmOBcmxtabNYe7XYNYd7L -gCbTZPMW4bsCEGNvbmZpZGVudGlhbFNlYWwABgIEc2VhbAIXBk5pibwA035ABMB1 -qXDVJA6Hx9E0fiwbbm7GLsChN2gZ67zVsxirl7OYpUs2Zd3apwZv6Okk5wNgqZSz -vQZOBXN0YXRlAS6ypf4XwDBEMJjgXJsbWmzWHu12DWHey4Am02TzFuG7AwhyZXZl -YWxlZAAGAgRzZWFsAhcGTmmJvADTfkAEwHWpcNUkDofH0TR+LBtubsYuwKE3frX4 -M3yRqm+4vZW7u8v14cUliUXSEXbaHtTcjMUxJWUFc3RhdGUBLrKl/hfAMEQwmOBc -mxtabNYe7XYNYd7LgCbTZPMW4bscQXNzaWduVm9pZFN0YXRlQmxpbmRTZWFsVHhp -ZAQEAAxjb25maWRlbnRpYWwABgIEc2VhbAIXBk5pibwA035ABMB1qXDVJA6Hx9E0 -fiwbbm7GLsChN2gZ67zVsxirl7OYpUs2Zd3apwZv6Okk5wNgqZSzvQZOBXN0YXRl -AS6ypf4XwDBEMJjgXJsbWmzWHu12DWHey4Am02TzFuG7ARFjb25maWRlbnRpYWxT -dGF0ZQAGAgRzZWFsAhcGTmmJvADTfkAEwHWpcNUkDofH0TR+LBtubsYuwKE3DFBs -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 +02TzFuG7GUFzc2lnbm1lbnRzQmxpbmRTZWFsVHhQdHIFAQAKAAACAXnrMHagYzXd +WTfXzI9eqDaCZaT2GUeP1YaqS4r25dPRAAAAAAAAAAD/AAAAAAAAABhBc3NpZ25t +ZW50c0JsaW5kU2VhbFR4aWQFAQAKAAACAczZPF7dYDyIiXmdJlXUp5vepvBgmQqY +bkZ4Bg1jFaPyAAAAAAAAAAD/AAAAAAAAAAhBdHRhY2hJZAUBAAcAAEAgAA5CbGlu +ZGluZ0ZhY3RvcgUBAAcAAEAgAApCdW5kbGVJdGVtBgIGaW5wdXRzAAkAAAIAAAAA +AAAAAP8AAAAAAAAACnRyYW5zaXRpb24ABAIABG5vbmUAAAABBHNvbWUABQEBcmr+ +7Ay8HZrJPtMwfmqqRth7cpvC6emZW8QSfgsMlRMPQ29uY2VhbGVkQXR0YWNoBQEA +BwAAQCAADUNvbmNlYWxlZERhdGEFAQAHAABAIAARQ29uY2VhbGVkRnVuZ2libGUG +Agpjb21taXRtZW50AUi9Gm4X+4Y7Fnx+JV41Z9uCQ+8qXrrrosUKzQmunlEaCnJh +bmdlUHJvb2YBqFhr+JFl2sIjEG29hcSGyTfmsGbrDGZB/xYvaKh3pZgKQ29udHJh +Y3RJZAUBAAcAAEAgAAlFeHRlbnNpb24GCANmZnYB2ptRE1gWVnaQh/uZ5VaUcjaA +1zkMBqHMJJgsBWT3zNUKY29udHJhY3RJZAGfCCxJOsgCorrF3dwLInwgr5TUaMRI +zxpaIeC9wvU6Mg1leHRlbnNpb25UeXBlAAACCG1ldGFkYXRhAAgAAEAAAAAAAAAA +AP//AAAAAAAAB2dsb2JhbHMB62+KkPa4xXkjBFZKvDL2fHjgUIU6pgieDE4dPteQ +V5ULYXNzaWdubWVudHMBaCKy8llRSOK9MgrA0zzDFssnIn4NrpMyh3YCculEwwsI +cmVkZWVtZWQBgQT0DBB8gi3nW4y4nz1Kuk5kbRnE3TlUnv8Fg3EDYaIJdmFsZW5j +aWVzAbDghaeHNvIG8cyvMVh4BgOJie/iUTwW/GRSklMPxAd/D0V4dGVuc2lvblNj +aGVtYQYFCG1ldGFkYXRhAkM0A5TYGzDiUiiQJh7zb/n4qDlRkfULaV4jKh6zt0HI +awSjFJ6mlQAWZ5/vArSrJPXmt4pkyNnQvWX816NYTo0HZ2xvYmFscwAKAAACATbB +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 +CgAAAgF1xyHghj/cKDOlQUwt7I8iMU72MmAxLacE5lzt2MRnTAAAAAAAAAAA/wAA +AAAAAAAKdHlwZVN5c3RlbQJDNAOU2Bsw4lIokCYe82/5+Kg5UZH1C2leIyoes7dB +yC5HWz5zyeAibY4sJ7oUs6olvm0o90d+LP2MTSheGOxWBnNjcmlwdAHGGGN7Z00M +tLypwENdfzJig5h4c3QnQ9E35UT7uhLQTAZTY3JpcHQEAQAFYWx1Vm0ABQEBovrq +nnBcnJHM291G7Y9w5Y71FIM+yD5cZLVqW8NTrbAcU2VhbERlZmluaXRpb25CbGlu +ZFNlYWxUeFB0cgQCAAdiaXRjb2luAAUBAhcGTmmJvADTfkAEwHWpcNUkDofH0TR+ +LBtubsYuwKE3frX4M3yRqm+4vZW7u8v14cUliUXSEXbaHtTcjMUxJWUBBmxpcXVp +ZAAFAQIXBk5pibwA035ABMB1qXDVJA6Hx9E0fiwbbm7GLsChN361+DN8kapvuL2V +u7vL9eHFJYlF0hF22h7U3IzFMSVlG1NlYWxEZWZpbml0aW9uQmxpbmRTZWFsVHhp +ZAQCAAdiaXRjb2luAAUBAhcGTmmJvADTfkAEwHWpcNUkDofH0TR+LBtubsYuwKE3 +DFBskkmcWPMvLuwsVLjXFmu8mBTsPpkCRT1xLrphCeEBBmxpcXVpZAAFAQIXBk5p +ibwA035ABMB1qXDVJA6Hx9E0fiwbbm7GLsChNwxQbJJJnFjzLy7sLFS41xZrvJgU +7D6ZAkU9cS66YQnhC1N0YXRlU2NoZW1hBAQAC2RlY2xhcmF0aXZlAAAAAQhmdW5n aWJsZQAFAQH59KwIZq5Bd2bU/QwRfQSx2VT9DmdeEjtiBOtxT+nlRgIKc3RydWN0 dXJlZAAFAQJDNAOU2Bsw4lIokCYe82/5+Kg5UZH1C2leIyoes7dByGsEoxSeppUA Fmef7wK0qyT15reKZMjZ0L1l/NejWE6NAwphdHRhY2htZW50AAUBAUIwYYWIyNSr @@ -219,10 +219,10 @@ VnaQh/uZ5VaUcjaA1zkMBqHMJJgsBWT3zNUKY29udHJhY3RJZAGfCCxJOsgCorrF 3dwLInwgr5TUaMRIzxpaIeC9wvU6Mg50cmFuc2l0aW9uVHlwZQAAAghtZXRhZGF0 YQAIAABAAAAAAAAAAAD//wAAAAAAAAdnbG9iYWxzAetvipD2uMV5IwRWSrwy9nx4 4FCFOqYIngxOHT7XkFeVBmlucHV0cwFaX9oXbyoy58+YADITLy6YdgaX++L/qrjV -Q09cyFPGbAthc3NpZ25tZW50cwE/Reol2saGr9AUx2YZ9zL3QSuZXgvMdGBzCSLK -deOSBAl2YWxlbmNpZXMBsOCFp4c28gbxzK8xWHgGA4mJ7+JRPBb8ZFKSUw/EB38Q +Q09cyFPGbAthc3NpZ25tZW50cwHCuvewCwgWKAedUG/QjybA6AOiuHPowUo6v7SP +Jbj9QQl2YWxlbmNpZXMBsOCFp4c28gbxzK8xWHgGA4mJ7+JRPBb8ZFKSUw/EB38Q VHJhbnNpdGlvbkJ1bmRsZQUBAAoBlcjmeh51Yl/UllVCapHrfkKQoW9amPG+UPe2 -iiQS98UB3l/v3jImeb7jUkacvc+2UWLNKpu3zWjVy5Mv5sTZNAsAAAAAAAAAAP8A +iiQS98UBZ5eezUsO3SmECPXJzF5TkmFk1s8xolN6Luc4CVzbCKAAAAAAAAAAAP8A AAAAAAAAEFRyYW5zaXRpb25TY2hlbWEGBQhtZXRhZGF0YQJDNAOU2Bsw4lIokCYe 82/5+Kg5UZH1C2leIyoes7dByGsEoxSeppUAFmef7wK0qyT15reKZMjZ0L1l/Nej WE6NB2dsb2JhbHMACgAAAgE2wTSh+qCBE6fdMIA8XrDywv3aFLDVo9aTw26eDzKq @@ -230,18 +230,18 @@ eQAAAAAAAAAA/wAAAAAAAAAGaW5wdXRzAAoAAAIBNsE0ofqggROn3TCAPF6w8sL9 2hSw1aPWk8Nung8yqnkAAAAAAAAAAP8AAAAAAAAAC2Fzc2lnbm1lbnRzAAoAAAIB NsE0ofqggROn3TCAPF6w8sL92hSw1aPWk8Nung8yqnkAAAAAAAAAAP8AAAAAAAAA CXZhbGVuY2llcwAJAAACAAAAAAAAAAD/AAAAAAAAABpUeXBlZEFzc2lnbnNCbGlu -ZFNlYWxUeFB0cgQEAAtkZWNsYXJhdGl2ZQAFAQAIAeMluZBzZMjpN1mESmsO9R0R -Y0xmH2DYS4Ec9psiGjuxAAAAAAAAAAD//wAAAAAAAAEIZnVuZ2libGUABQEACAEf -wh66yj7ZN5TUhhhq5Gn011yFW2g1oxv59xQF/VFqfwAAAAAAAAAA//8AAAAAAAAC -CnN0cnVjdHVyZWQABQEACAGSnFNfDqb7NiUhfApFZwIY72w0MSI+nWF8hfT61rwC -YQAAAAAAAAAA//8AAAAAAAD/CmF0dGFjaG1lbnQABQEACAH3FoB0Rp1JmjNsES5Q -NzijpphEezO/swFzwHyA7HyP6QAAAAAAAAAA//8AAAAAAAAZVHlwZWRBc3NpZ25z -QmxpbmRTZWFsVHhpZAQEAAtkZWNsYXJhdGl2ZQAFAQAIAQS+rLcZ3JhQNeU3uFwk -Btr94WWcT+rBTYnQ5pLVEz8qAAAAAAAAAAD//wAAAAAAAAEIZnVuZ2libGUABQEA -CAFWEq0NV26A6aFBnU+qEVMtVfccc90n2IGRowMo644WjQAAAAAAAAAA//8AAAAA -AAACCnN0cnVjdHVyZWQABQEACAFdcYPAaGpfMY1SdN8Y2mf4PBWZPXCJc7/LbMqU -F2hragAAAAAAAAAA//8AAAAAAAD/CmF0dGFjaG1lbnQABQEACAHPHcEMPUMsvNRR -vkuT+oh2KyXC9fHOJJMBYTMB/y/LqQAAAAAAAAAA//8AAAAAAAAJVmFsZW5jaWVz +ZFNlYWxUeFB0cgQEAAtkZWNsYXJhdGl2ZQAFAQAIASlmLu7+YHlscLtafG2Pcozo +6kvLU/N6TMuVk2gImp7uAAAAAAAAAAD//wAAAAAAAAEIZnVuZ2libGUABQEACAFL +SRG2x4jTs6qG/MVTVjz9mirxuAfG5sef6XtWmQ8QsQAAAAAAAAAA//8AAAAAAAAC +CnN0cnVjdHVyZWQABQEACAFZolHNjebLiSRE7c91W7GqpdwcP9rBNM1sJTbV9hOK +wgAAAAAAAAAA//8AAAAAAAD/CmF0dGFjaG1lbnQABQEACAH7zBd2FTkXpjSm4b7g +Ht0r3GK/r4la5XU5cv8qQZfYgAAAAAAAAAAA//8AAAAAAAAZVHlwZWRBc3NpZ25z +QmxpbmRTZWFsVHhpZAQEAAtkZWNsYXJhdGl2ZQAFAQAIAZjmCNUpvD8wzk9MqgCs +LOdH/s86QuxysgqCwL4CEwKJAAAAAAAAAAD//wAAAAAAAAEIZnVuZ2libGUABQEA +CAF/bNH54DeCyZUq/Co3RTZAa4Zaz3o4XneDyeDI1eOA/QAAAAAAAAAA//8AAAAA +AAACCnN0cnVjdHVyZWQABQEACAE+3J1wNEPkBuDqB11Dgy/Nr1/LVPO0gJ1pu+1/ +YKRBowAAAAAAAAAA//8AAAAAAAD/CmF0dGFjaG1lbnQABQEACAEP+aNjbGPkkqop +cG754NrtT7ZHuV77qjvpdbNGEwz2fAAAAAAAAAAA//8AAAAAAAAJVmFsZW5jaWVz BQEACQAAAgAAAAAAAAAA/wAAAAAAAAAJVm9pZFN0YXRlBQEAAAA= -----END STRICT TYPE LIB----- diff --git a/stl/RGB@0.1.0.stl b/stl/RGB@0.1.0.stl index 831a1ba5ffb0b43bbe2e2bb3d6e10e3d78189381..a35823237c5440be81a6d07f32001786a246aa14 100644 GIT binary patch delta 1544 zcmZpRXp7jO%vx{7!0DJ%;*(gJT4cz~%$Ac`Selu_$ex%~lvt5iEWlb&l$o0<$OBgs zoLa)l$iT_CLBlLvpsH^7*>`stV+u{TUGLg&zQH&?`a`9yz;UI;rx~E&Ka>XAQW~6G zlvz;1#>A47nN-Zc#k6xX`(_)~HbzB8AHFo9u*AqVZN?Q#f-d!oENI=8S0KH@!S+lN z|D&?CFD5VKP@nA0IfV$73S8=w)j0MlGAd~(&2cWXJ+awo)-A`M zvBsx|e^N!5Nl>K%*JC1VJ_xiqo0}LnI`BLq!hLY_2)fUKM}2Y|AJESP!;z6+ee!C4 zV%*pu0Q56Ko8jgWRJlOt0TJ#yD7>2}RqB(Ui0mN3ePHtly6vE_`Xq5Bh050kWebu` z??#$mKhqz#!mKHE$u~*&{;O@Pyt}?Vy?k-9lenS6nVU9ocN1(nIxFX@gj6Nb%$IUZU zc(b`g5u-we(xy+5fgX?c8gU)CY;#!bw7OCq@4CrG?PW|wFI^6EZ$2rxn{o0d3AM?q zqzkn<6Jhz3@yb`0Z8JTWcKQn*stP>3@5CL^T`vD3ub&S*)o=V#U{2a(X_*khruWOl za%#&2rzYmOq^4!&WtL>-=Q-tM=B0pyLMj4EiddK!*po6#lJhh37+4u6HwZg&GeV09 zC|^q&r~b?oH0=o-ij%k$P)vXbZGNM=gHhqouJ0STIm9&B=LY0o=vO=Nf_c%7;ui2=I<=6k2~0pJv%=CWp&t0eu0gX<+YR)A{Pao?R|E-Q^n=&`O@f(tCrr8 zvA=cDOE9We)Y*``5|V4)WYOIY>?bq!JRPs zCW)v|UMDmKncF421Ljg>S)gVRH%(MYLDckZ&Osf&yMMXr)h5K&wO4WfidXAp@0-RP zZN>iU>-5PhL=6>|WLEG0Q?IiBgs9ICokVjrR~4cDJNiqW+r%(^@@b7(I{Bw)i$Yrb z`9&>%!=IgfTRhF7#C^BG->(7o_OqUsZ}+J#pPIwEd9GLyqr(3B8Onhze_JMT`c|cy9n#wz^wYo z@>)s?lja1+^DX;rrm9%O<(keU@jl1IP|0p?VomFpU)T09B~DHRD*7(gP~tY%bCz+A zpk9Ev#o}c%T&j)tZ)Pk$P}A_HrvK&S#ai|XEc@1Mm%KA0!1Ss4ju;iTTYn#>&hdYB z(6{r#vq@Kl?X|#e3KLq(8=lwja-ri~|5bv)x}o1?itno5Xq>p1S>tt|STER3v4zbC zGP2?gdxJ{uOWaETVIw-zwxF|k|LL4lQ^Yf}v%qdTFME*3)>&uImB4-8lYe!TX{#Rk W`th8~WX42e#{c@KS57{r?EnCtF ^ ..0xff [Byte]}, entryPoints {[Byte ^ 3] -> AluVM.LibSite {- urn:ubideco:semid:8Q9NNyK2PCcjZ7U7rDGUJBhk8q37hAnWLgSizGLmr56g#mission-papa-mercy -}} --- urn:ubideco:semid:GePq4FUFMsg9ST5F9xGw8onGmodG7DvSRn19BCEmtoUo#mimosa-user-russian +-- urn:ubideco:semid:8Ffm9AttRojBCspPTxazNdaPB3BcFD2cr9c2sES1T7ox#desert-bambino-size data AssignRevealedAttachBlindSealTxPtr :: confidential (seal BPCore.SecretSeal {- urn:ubideco:semid:81NKrdc9pBoBjsKaGBVN9wXLG4tKjkK4f8DLj7TNMZxh#santana-domingo-needle -}, state ConcealedAttach) - | confidentialState (seal BPCore.BlindSealTxPtr {- urn:ubideco:semid:9XdJg1BFMpMXPfaiw4Te79W2qYgArsEye6XPJUtj31L8#metro-chris-olympic -}, state ConcealedAttach) + | confidentialState (seal SealDefinitionBlindSealTxPtr, state ConcealedAttach) | confidentialSeal (seal BPCore.SecretSeal {- urn:ubideco:semid:81NKrdc9pBoBjsKaGBVN9wXLG4tKjkK4f8DLj7TNMZxh#santana-domingo-needle -}, state RevealedAttach) - | revealed (seal BPCore.BlindSealTxPtr {- urn:ubideco:semid:9XdJg1BFMpMXPfaiw4Te79W2qYgArsEye6XPJUtj31L8#metro-chris-olympic -}, state RevealedAttach) --- urn:ubideco:semid:3ULvFW9mbxbFR6iWgHL8dkiTSB8PgGbZDSDoG96r6LwD#maxwell-human-fabric + | revealed (seal SealDefinitionBlindSealTxPtr, state RevealedAttach) +-- urn:ubideco:semid:2szVpBWGxAdBxooiGk7qqt9CXuti6BS4wrLhhVk8tb58#explain-canvas-retro data AssignRevealedAttachBlindSealTxid :: confidential (seal BPCore.SecretSeal {- urn:ubideco:semid:81NKrdc9pBoBjsKaGBVN9wXLG4tKjkK4f8DLj7TNMZxh#santana-domingo-needle -}, state ConcealedAttach) - | confidentialState (seal BPCore.BlindSealTxid {- urn:ubideco:semid:q529pAPHhD1aFgueAHy8QtfjUayszR85WgEg7s2a3KE#raymond-reply-phrase -}, state ConcealedAttach) + | confidentialState (seal SealDefinitionBlindSealTxid, state ConcealedAttach) | confidentialSeal (seal BPCore.SecretSeal {- urn:ubideco:semid:81NKrdc9pBoBjsKaGBVN9wXLG4tKjkK4f8DLj7TNMZxh#santana-domingo-needle -}, state RevealedAttach) - | revealed (seal BPCore.BlindSealTxid {- urn:ubideco:semid:q529pAPHhD1aFgueAHy8QtfjUayszR85WgEg7s2a3KE#raymond-reply-phrase -}, state RevealedAttach) --- urn:ubideco:semid:Ex6YVSVtGApLgmof48MpZUXgsaB4ZBXBP2QNFv1BBWYZ#viva-yellow-minimum + | revealed (seal SealDefinitionBlindSealTxid, state RevealedAttach) +-- urn:ubideco:semid:65fYnZD1gAD3YrrcpJ9p3J3tRkLSyBMrCp4kf8EZCcWa#garden-arctic-market data AssignRevealedDataBlindSealTxPtr :: confidential (seal BPCore.SecretSeal {- urn:ubideco:semid:81NKrdc9pBoBjsKaGBVN9wXLG4tKjkK4f8DLj7TNMZxh#santana-domingo-needle -}, state ConcealedData) - | confidentialState (seal BPCore.BlindSealTxPtr {- urn:ubideco:semid:9XdJg1BFMpMXPfaiw4Te79W2qYgArsEye6XPJUtj31L8#metro-chris-olympic -}, state ConcealedData) + | confidentialState (seal SealDefinitionBlindSealTxPtr, state ConcealedData) | confidentialSeal (seal BPCore.SecretSeal {- urn:ubideco:semid:81NKrdc9pBoBjsKaGBVN9wXLG4tKjkK4f8DLj7TNMZxh#santana-domingo-needle -}, state RevealedData) - | revealed (seal BPCore.BlindSealTxPtr {- urn:ubideco:semid:9XdJg1BFMpMXPfaiw4Te79W2qYgArsEye6XPJUtj31L8#metro-chris-olympic -}, state RevealedData) --- urn:ubideco:semid:EDmShAA3BjqRs1me5iSUzEaF6PQhKsvbVEtdxfUyuAhS#flex-mister-bali + | revealed (seal SealDefinitionBlindSealTxPtr, state RevealedData) +-- urn:ubideco:semid:HyACqLjbgLgSFgP6JsBLVFm84YP4A3xc3qeYsfAHgfRY#model-proxy-store data AssignRevealedDataBlindSealTxid :: confidential (seal BPCore.SecretSeal {- urn:ubideco:semid:81NKrdc9pBoBjsKaGBVN9wXLG4tKjkK4f8DLj7TNMZxh#santana-domingo-needle -}, state ConcealedData) - | confidentialState (seal BPCore.BlindSealTxid {- urn:ubideco:semid:q529pAPHhD1aFgueAHy8QtfjUayszR85WgEg7s2a3KE#raymond-reply-phrase -}, state ConcealedData) + | confidentialState (seal SealDefinitionBlindSealTxid, state ConcealedData) | confidentialSeal (seal BPCore.SecretSeal {- urn:ubideco:semid:81NKrdc9pBoBjsKaGBVN9wXLG4tKjkK4f8DLj7TNMZxh#santana-domingo-needle -}, state RevealedData) - | revealed (seal BPCore.BlindSealTxid {- urn:ubideco:semid:q529pAPHhD1aFgueAHy8QtfjUayszR85WgEg7s2a3KE#raymond-reply-phrase -}, state RevealedData) --- urn:ubideco:semid:GX9uqARAfKeL4Kf2VggRjVmEX9NLmzMnZR1Xme83eET3#chris-lava-austria + | revealed (seal SealDefinitionBlindSealTxid, state RevealedData) +-- urn:ubideco:semid:FCsgg6AyiV6SbkwH4RiyJSc3CBDL8ZkDGKbv65f1odyz#gopher-nebula-spell data AssignRevealedValueBlindSealTxPtr :: confidential (seal BPCore.SecretSeal {- urn:ubideco:semid:81NKrdc9pBoBjsKaGBVN9wXLG4tKjkK4f8DLj7TNMZxh#santana-domingo-needle -}, state ConcealedFungible) - | confidentialState (seal BPCore.BlindSealTxPtr {- urn:ubideco:semid:9XdJg1BFMpMXPfaiw4Te79W2qYgArsEye6XPJUtj31L8#metro-chris-olympic -}, state ConcealedFungible) + | confidentialState (seal SealDefinitionBlindSealTxPtr, state ConcealedFungible) | confidentialSeal (seal BPCore.SecretSeal {- urn:ubideco:semid:81NKrdc9pBoBjsKaGBVN9wXLG4tKjkK4f8DLj7TNMZxh#santana-domingo-needle -}, state RevealedFungible) - | revealed (seal BPCore.BlindSealTxPtr {- urn:ubideco:semid:9XdJg1BFMpMXPfaiw4Te79W2qYgArsEye6XPJUtj31L8#metro-chris-olympic -}, state RevealedFungible) --- urn:ubideco:semid:DfNFuteuzP1PFwu2p7KZx4jUVHwc6AvVaDZ4xaH3y1Ja#edward-bundle-king + | revealed (seal SealDefinitionBlindSealTxPtr, state RevealedFungible) +-- urn:ubideco:semid:GTdZHC47e3PTSEp8JqsUxSUeVhgYiHnnxopDy5D79UC8#lion-detail-monica data AssignRevealedValueBlindSealTxid :: confidential (seal BPCore.SecretSeal {- urn:ubideco:semid:81NKrdc9pBoBjsKaGBVN9wXLG4tKjkK4f8DLj7TNMZxh#santana-domingo-needle -}, state ConcealedFungible) - | confidentialState (seal BPCore.BlindSealTxid {- urn:ubideco:semid:q529pAPHhD1aFgueAHy8QtfjUayszR85WgEg7s2a3KE#raymond-reply-phrase -}, state ConcealedFungible) + | confidentialState (seal SealDefinitionBlindSealTxid, state ConcealedFungible) | confidentialSeal (seal BPCore.SecretSeal {- urn:ubideco:semid:81NKrdc9pBoBjsKaGBVN9wXLG4tKjkK4f8DLj7TNMZxh#santana-domingo-needle -}, state RevealedFungible) - | revealed (seal BPCore.BlindSealTxid {- urn:ubideco:semid:q529pAPHhD1aFgueAHy8QtfjUayszR85WgEg7s2a3KE#raymond-reply-phrase -}, state RevealedFungible) --- urn:ubideco:semid:Fduqv2hV4s58vgXp93gqYZe7Zjaf8aMeAVpj1udWLMPA#flipper-segment-tuna + | revealed (seal SealDefinitionBlindSealTxid, state RevealedFungible) +-- urn:ubideco:semid:56jRA2TP2J2utFSd4H6WBfLYmuZY1HvGNfohTwkeBBNA#guitar-subject-equal data AssignVoidStateBlindSealTxPtr :: confidential (seal BPCore.SecretSeal {- urn:ubideco:semid:81NKrdc9pBoBjsKaGBVN9wXLG4tKjkK4f8DLj7TNMZxh#santana-domingo-needle -}, state VoidState) - | confidentialState (seal BPCore.BlindSealTxPtr {- urn:ubideco:semid:9XdJg1BFMpMXPfaiw4Te79W2qYgArsEye6XPJUtj31L8#metro-chris-olympic -}, state VoidState) + | confidentialState (seal SealDefinitionBlindSealTxPtr, state VoidState) | confidentialSeal (seal BPCore.SecretSeal {- urn:ubideco:semid:81NKrdc9pBoBjsKaGBVN9wXLG4tKjkK4f8DLj7TNMZxh#santana-domingo-needle -}, state VoidState) - | revealed (seal BPCore.BlindSealTxPtr {- urn:ubideco:semid:9XdJg1BFMpMXPfaiw4Te79W2qYgArsEye6XPJUtj31L8#metro-chris-olympic -}, state VoidState) --- urn:ubideco:semid:762bnEXornAaqA2c9hNAbJbbxabbSTYoxh7fepdpFT3k#voice-dynamic-pupil + | revealed (seal SealDefinitionBlindSealTxPtr, state VoidState) +-- urn:ubideco:semid:GNNgLKgLre8oGtmZVhPSJHqShaxYA18qAXzFKeLHU6SA#chamber-focus-charter data AssignVoidStateBlindSealTxid :: confidential (seal BPCore.SecretSeal {- urn:ubideco:semid:81NKrdc9pBoBjsKaGBVN9wXLG4tKjkK4f8DLj7TNMZxh#santana-domingo-needle -}, state VoidState) - | confidentialState (seal BPCore.BlindSealTxid {- urn:ubideco:semid:q529pAPHhD1aFgueAHy8QtfjUayszR85WgEg7s2a3KE#raymond-reply-phrase -}, state VoidState) + | confidentialState (seal SealDefinitionBlindSealTxid, state VoidState) | confidentialSeal (seal BPCore.SecretSeal {- urn:ubideco:semid:81NKrdc9pBoBjsKaGBVN9wXLG4tKjkK4f8DLj7TNMZxh#santana-domingo-needle -}, state VoidState) - | revealed (seal BPCore.BlindSealTxid {- urn:ubideco:semid:q529pAPHhD1aFgueAHy8QtfjUayszR85WgEg7s2a3KE#raymond-reply-phrase -}, state VoidState) + | revealed (seal SealDefinitionBlindSealTxid, state VoidState) -- urn:ubideco:semid:6jnUE9dFA7Lyc5tFCcqvbAka64k1ASEJu3VXHQdcFN2V#balsa-melon-rocket data AssignmentsBlindSealTxPtr :: {U16 -> ^ ..0xff TypedAssignsBlindSealTxPtr} -- urn:ubideco:semid:HhrRhDUZ8UGq9Wv69jGDNLRF4J3uQUKtbwv9fsn4uSUp#orca-immune-logo @@ -134,10 +139,11 @@ data FungibleState :: bits64:8 U64 -- urn:ubideco:semid:HpiuYTT7BuhCmoNs2GrwNrHNUx3i3yf6GjDiFphLKeQV#profit-bazooka-present data FungibleType :: unsigned64Bit:8 --- urn:ubideco:semid:4scakYFRFuZ6bB1QGKBvfV8ZxgSztvLD52ufW9DXBNpL#mayor-wedding-balance +-- urn:ubideco:semid:5gwA5ScPHt1SRRPvzvhACqiv48XFa3hhgqtTJF9b1cjY#direct-action-benny data Genesis :: ffv Ffv , schemaId SchemaId , chain Bitcoin.Chain {- urn:ubideco:semid:6aRP3odHaTGySvSWHjreC8HsbX5ss9LxkQqwcjaoxhpv#aspirin-brown-alpine -} + , altLayer1 AltLayer1Set , metadata [Byte] , globals GlobalState , assignments AssignmentsBlindSealTxid @@ -212,6 +218,12 @@ data SchemaSchema :: ffv Ffv , script Script -- urn:ubideco:semid:HyVVQCc7o1wnC3oo1VTHzcpMuVsvzFBTnSFe6xVSiDAV#process-media-second data Script :: aluVm AluScript +-- urn:ubideco:semid:67tiipcLpwkwMZTZj2rUbqZPTYWVFeCFs3U6rqc3UEdu#delphi-october-gregory +data SealDefinitionBlindSealTxPtr :: bitcoin BPCore.BlindSealTxPtr {- urn:ubideco:semid:9XdJg1BFMpMXPfaiw4Te79W2qYgArsEye6XPJUtj31L8#metro-chris-olympic -} + | liquid BPCore.BlindSealTxPtr {- urn:ubideco:semid:9XdJg1BFMpMXPfaiw4Te79W2qYgArsEye6XPJUtj31L8#metro-chris-olympic -} +-- urn:ubideco:semid:3JLMjcf79wu2VCRFwZqBZyGaZWLDexaUHzRn1XYLL5jA#ricardo-memphis-bagel +data SealDefinitionBlindSealTxid :: bitcoin BPCore.BlindSealTxid {- urn:ubideco:semid:q529pAPHhD1aFgueAHy8QtfjUayszR85WgEg7s2a3KE#raymond-reply-phrase -} + | liquid BPCore.BlindSealTxid {- urn:ubideco:semid:q529pAPHhD1aFgueAHy8QtfjUayszR85WgEg7s2a3KE#raymond-reply-phrase -} -- urn:ubideco:semid:tECDKfnyyGZgwoorc1VynUBq9unv34u9WvRBUTduoRK#report-agatha-level data StateSchema :: declarative () | fungible FungibleType From b6d754d594a41a148a9214eaeb67dde600e7c091 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Mon, 30 Oct 2023 09:00:34 +0100 Subject: [PATCH 6/7] validation: validate anchors depending on layer1 chain --- src/contract/mod.rs | 5 +- src/contract/seal.rs | 9 +- src/lib.rs | 4 +- src/stl.rs | 8 +- src/validation/anchor.rs | 97 +++++++ src/validation/consignment.rs | 19 +- src/validation/mod.rs | 4 +- src/validation/status.rs | 6 +- src/validation/validator.rs | 56 ++-- stl/RGB@0.1.0.sta | 484 ++++++++++++++++++---------------- stl/RGB@0.1.0.stl | Bin 11270 -> 12154 bytes stl/RGB@0.1.0.sty | 27 +- 12 files changed, 437 insertions(+), 282 deletions(-) create mode 100644 src/validation/anchor.rs diff --git a/src/contract/mod.rs b/src/contract/mod.rs index eb230ee3..a09e70c0 100644 --- a/src/contract/mod.rs +++ b/src/contract/mod.rs @@ -71,11 +71,12 @@ pub use state::{ConfidentialState, ExposedState, StateCommitment, StateData, Sta serde(crate = "serde_crate", rename_all = "camelCase") )] #[repr(u8)] +#[non_exhaustive] pub enum AltLayer1 { #[strict_type(dumb)] Liquid = 1, - Abraxas = 0x10, - Prime = 0x11, + // Abraxas = 0x10, + // Prime = 0x11, } #[derive(Wrapper, Clone, PartialEq, Eq, Hash, Debug, From)] diff --git a/src/contract/seal.rs b/src/contract/seal.rs index 13685348..afcf7ec1 100644 --- a/src/contract/seal.rs +++ b/src/contract/seal.rs @@ -31,7 +31,7 @@ use bp::{Outpoint, Txid}; use commit_verify::{strategies, CommitEncode, Conceal}; use strict_encoding::{StrictDecode, StrictDumb, StrictEncode}; -use crate::LIB_NAME_RGB; +use crate::{Layer1, LIB_NAME_RGB}; pub trait ExposedSeal: Debug @@ -110,6 +110,13 @@ impl SealDefinition { } impl SealDefinition { + pub fn layer1(self) -> Layer1 { + match self { + SealDefinition::Bitcoin(_) => Layer1::Bitcoin, + SealDefinition::Liquid(_) => Layer1::Liquid, + } + } + #[inline] pub fn outpoint(self) -> Option { match self { diff --git a/src/lib.rs b/src/lib.rs index 22691685..cb9c9541 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -52,10 +52,10 @@ pub mod vm; pub mod stl; pub mod prelude { - pub use bp::dbc::{Anchor, AnchorId}; + pub use bp::dbc::AnchorId; pub use contract::*; pub use schema::*; - pub use validation::AnchoredBundle; + pub use validation::{Anchor, AnchoredBundle, Layer1}; use super::*; pub use super::{schema, vm}; diff --git a/src/stl.rs b/src/stl.rs index 9648dd7a..18889367 100644 --- a/src/stl.rs +++ b/src/stl.rs @@ -23,27 +23,29 @@ pub use aluvm::stl::aluvm_stl; pub use bp::bc::stl::bp_tx_stl; pub use bp::stl::bp_core_stl; +use commit_verify::stl::commit_verify_stl; use strict_types::stl::{std_stl, strict_types_stl}; use strict_types::typelib::LibBuilder; use strict_types::{CompileError, TypeLib}; -use crate::{Extension, Genesis, SubSchema, TransitionBundle, LIB_NAME_RGB}; +use crate::{AnchoredBundle, Extension, Genesis, SubSchema, LIB_NAME_RGB}; /// Strict types id for the library providing data types for RGB consensus. pub const LIB_ID_RGB: &str = - "urn:ubideco:stl:28ZcP9sj9SC5CC52qLWM9YxxRRhXAJjwRqD98nZLmx2y#radar-inca-valid"; + "urn:ubideco:stl:DmN8aZj1dPvAvx5JYfz22azHs5RRbECxmxWoo5LK7E5f#house-herman-poem"; fn _rgb_core_stl() -> Result { LibBuilder::new(libname!(LIB_NAME_RGB), tiny_bset! { std_stl().to_dependency(), strict_types_stl().to_dependency(), + commit_verify_stl().to_dependency(), bp_tx_stl().to_dependency(), bp_core_stl().to_dependency(), aluvm_stl().to_dependency() }) .transpile::() .transpile::() - .transpile::() + .transpile::() .transpile::() .compile() } diff --git a/src/validation/anchor.rs b/src/validation/anchor.rs new file mode 100644 index 00000000..8be96a2d --- /dev/null +++ b/src/validation/anchor.rs @@ -0,0 +1,97 @@ +// RGB Core Library: consensus layer for RGB smart contracts. +// +// SPDX-License-Identifier: Apache-2.0 +// +// Written in 2019-2023 by +// Dr Maxim Orlovsky +// +// Copyright (C) 2019-2023 LNP/BP Standards Association. All rights reserved. +// Copyright (C) 2019-2023 Dr Maxim Orlovsky. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use bp::dbc; +use commit_verify::mpc; +use commit_verify::mpc::{Message, ProtocolId}; + +use crate::{TransitionBundle, LIB_NAME_RGB}; + +#[derive(Clone, Eq, PartialEq, Debug)] +#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] +#[strict_type(lib = LIB_NAME_RGB)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(crate = "serde_crate", rename_all = "camelCase") +)] +pub struct AnchoredBundle { + pub anchor: Anchor, + pub bundle: TransitionBundle, +} + +#[derive(Clone, Eq, PartialEq, Debug)] +#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] +#[strict_type(lib = LIB_NAME_RGB, tags = custom, dumb = Self::Bitcoin(strict_dumb!()))] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(crate = "serde_crate", rename_all = "camelCase") +)] +#[non_exhaustive] +pub enum Anchor { + #[strict_type(tag = 0x00)] + Bitcoin(dbc::Anchor), + + #[strict_type(tag = 0x01)] + Liquid(dbc::Anchor), +} + +impl Anchor { + pub fn layer1(&self) -> Layer1 { + match self { + Anchor::Bitcoin(_) => Layer1::Bitcoin, + Anchor::Liquid(_) => Layer1::Liquid, + } + } + + /// Verifies that the anchor commits to the given message under the given + /// protocol. + pub fn convolve( + &self, + protocol_id: impl Into, + message: Message, + ) -> Result { + match self { + Anchor::Bitcoin(anchor) | Anchor::Liquid(anchor) => { + anchor.mpc_proof.convolve(protocol_id.into(), message) + } + } + } +} + +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Display)] +#[display(lowercase)] +#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] +#[strict_type(lib = LIB_NAME_RGB, tags = repr, into_u8, try_from_u8)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(crate = "serde_crate", rename_all = "camelCase") +)] +#[repr(u8)] +#[non_exhaustive] +pub enum Layer1 { + #[strict_type(dumb)] + Bitcoin = 0, + Liquid = 1, +} diff --git a/src/validation/consignment.rs b/src/validation/consignment.rs index 96d231d3..9939089e 100644 --- a/src/validation/consignment.rs +++ b/src/validation/consignment.rs @@ -26,26 +26,11 @@ use std::collections::BTreeSet; -use commit_verify::mpc; - use crate::{ - Anchor, BundleId, Extension, Genesis, OpId, OpRef, SecretSeal, SubSchema, Transition, - TransitionBundle, LIB_NAME_RGB, + AnchoredBundle, BundleId, Extension, Genesis, OpId, OpRef, SecretSeal, SubSchema, Transition, + TransitionBundle, }; -#[derive(Clone, Eq, PartialEq, Debug)] -#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB)] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", rename_all = "camelCase") -)] -pub struct AnchoredBundle { - pub anchor: Anchor, - pub bundle: TransitionBundle, -} - /// Trait defining common data access API for all storage-related RGB structures /// /// # Verification diff --git a/src/validation/mod.rs b/src/validation/mod.rs index 7f4408ba..7d78c133 100644 --- a/src/validation/mod.rs +++ b/src/validation/mod.rs @@ -26,9 +26,11 @@ mod model; mod state; mod validator; mod consignment; +mod anchor; mod status; -pub use consignment::{AnchoredBundle, ConsignmentApi}; +pub use anchor::{Anchor, AnchoredBundle, Layer1}; +pub use consignment::ConsignmentApi; pub(crate) use model::OpInfo; pub use script::VirtualMachine; pub use status::{Failure, Info, Status, Validity, Warning}; diff --git a/src/validation/status.rs b/src/validation/status.rs index 5d38dc94..e743a241 100644 --- a/src/validation/status.rs +++ b/src/validation/status.rs @@ -31,7 +31,7 @@ use strict_types::SemId; use crate::contract::Opout; use crate::schema::{self, SchemaId}; use crate::{ - AssignmentType, BundleId, OccurrencesMismatch, OpFullType, OpId, SecretSeal, StateType, + AssignmentType, BundleId, Layer1, OccurrencesMismatch, OpFullType, OpId, SecretSeal, StateType, }; #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Display)] @@ -298,7 +298,7 @@ pub enum Failure { /// transition {0} is not anchored. NotAnchored(OpId), /// anchor for transition {0} doesn't commit to the actual transition data. - NotInAnchor(OpId, Txid), + NotInAnchor(OpId), /// transition {opid} references state type {state_type} absent in the /// outputs of previous state transition {prev_id}. NoPrevState { @@ -316,6 +316,8 @@ pub enum Failure { MpcInvalid(OpId, Txid), /// witness transaction {0} is not known to the transaction resolver. SealNoWitnessTx(Txid), + /// witness layer 1 {anchor} doesn't match seal definition {seal}. + SealWitnessLayer1Mismatch { seal: Layer1, anchor: Layer1 }, /// transition {0} doesn't close seal with the witness transaction {1}. /// Details: {2} SealInvalid(OpId, Txid, seals::txout::VerifyError), diff --git a/src/validation/validator.rs b/src/validation/validator.rs index 59fce04a..d033e828 100644 --- a/src/validation/validator.rs +++ b/src/validation/validator.rs @@ -22,20 +22,18 @@ use std::collections::{BTreeMap, BTreeSet, VecDeque}; -use bp::dbc::Anchor; use bp::seals::txout::{TxPtr, Witness}; -use bp::{Tx, Txid}; +use bp::{dbc, Tx, Txid}; use commit_verify::mpc; use single_use_seals::SealWitness; use super::status::{Failure, Warning}; use super::{ConsignmentApi, Status, Validity, VirtualMachine}; -use crate::contract::Opout; -use crate::validation::AnchoredBundle; use crate::vm::AluRuntime; use crate::{ - BundleId, ContractId, GraphSeal, OpId, OpRef, Operation, Schema, SchemaId, SchemaRoot, Script, - SealDefinition, SubSchema, Transition, TransitionBundle, TypedAssigns, + Anchor, AnchoredBundle, BundleId, ContractId, GraphSeal, Layer1, OpId, OpRef, Operation, Opout, + Schema, SchemaId, SchemaRoot, Script, SealDefinition, SubSchema, Transition, TransitionBundle, + TypedAssigns, }; #[derive(Clone, Debug, Display, Error, From)] @@ -48,7 +46,7 @@ pub enum TxResolverError { } pub trait ResolveTx { - fn resolve_tx(&self, txid: Txid) -> Result; + fn resolve_tx(&self, layer1: Layer1, txid: Txid) -> Result; } pub struct Validator<'consignment, 'resolver, C: ConsignmentApi, R: ResolveTx> { @@ -59,7 +57,7 @@ pub struct Validator<'consignment, 'resolver, C: ConsignmentApi, R: ResolveTx> { schema_id: SchemaId, genesis_id: OpId, contract_id: ContractId, - anchor_index: BTreeMap>, + anchor_index: BTreeMap, end_transitions: Vec<(&'consignment Transition, BundleId)>, validation_index: BTreeSet, anchor_validation_index: BTreeSet, @@ -82,7 +80,7 @@ impl<'consignment, 'resolver, C: ConsignmentApi, R: ResolveTx> let schema_id = consignment.genesis().schema_id; // Create indexes - let mut anchor_index = BTreeMap::>::new(); + let mut anchor_index = BTreeMap::::new(); for AnchoredBundle { ref anchor, ref bundle, @@ -217,6 +215,10 @@ impl<'consignment, 'resolver, C: ConsignmentApi, R: ResolveTx> // with a dedicated type for (operation, _) in &self.end_transitions { if let Some(anchor) = self.anchor_index.get(&operation.id()) { + let anchor = match anchor { + Anchor::Bitcoin(anchor) | Anchor::Liquid(anchor) => anchor, + }; + if let Some(pos) = self .status .failures @@ -286,10 +288,9 @@ impl<'consignment, 'resolver, C: ConsignmentApi, R: ResolveTx> // [VALIDATION]: Check that transition is committed into the anchor. // This must be done with deterministic bitcoin - // commitments & LNPBP-4. + // commitments & LNPBP-4. if anchor.convolve(self.contract_id, bundle_id.into()).is_err() { - self.status - .add_failure(Failure::NotInAnchor(opid, anchor.txid)); + self.status.add_failure(Failure::NotInAnchor(opid)); } self.validate_transition(transition, bundle_id, anchor); @@ -346,13 +347,17 @@ impl<'consignment, 'resolver, C: ConsignmentApi, R: ResolveTx> &mut self, transition: &'consignment Transition, bundle_id: BundleId, - anchor: &'consignment Anchor, + anchor: &'consignment Anchor, ) { + let (layer1, anchor) = match anchor { + Anchor::Bitcoin(a) | Anchor::Liquid(a) => (anchor.layer1(), a), + }; + let txid = anchor.txid; // Check that the anchor is committed into a transaction spending all of the // transition inputs. - match self.resolver.resolve_tx(txid) { + match self.resolver.resolve_tx(layer1, txid) { Err(_) => { // We wre unable to retrieve corresponding transaction, so can't check. // Reporting this incident and continuing further. Why this happens? No @@ -379,7 +384,7 @@ impl<'consignment, 'resolver, C: ConsignmentApi, R: ResolveTx> transition: &'consignment Transition, witness: Witness, bundle_id: BundleId, - anchor: &'consignment Anchor, + anchor: &'consignment dbc::Anchor, ) { let opid = transition.id(); let txid = witness.txid; @@ -426,14 +431,17 @@ impl<'consignment, 'resolver, C: ConsignmentApi, R: ResolveTx> txid: TxPtr::WitnessTx, .. }, - ) | + ), + Some(Anchor::Bitcoin(anchor)), + ) | + ( SealDefinition::Liquid( seal @ GraphSeal { txid: TxPtr::WitnessTx, .. }, ), - Some(anchor), + Some(Anchor::Liquid(anchor)), ) => { let prev_witness_txid = anchor.txid; seal.resolve(prev_witness_txid) @@ -447,15 +455,25 @@ impl<'consignment, 'resolver, C: ConsignmentApi, R: ResolveTx> txid: TxPtr::Txid(txid), .. }, - ) | + ), + Some(Anchor::Bitcoin(_)), + ) | + ( SealDefinition::Liquid( seal @ GraphSeal { txid: TxPtr::Txid(txid), .. }, ), - _, + Some(Anchor::Liquid(_)), ) => seal.resolve(txid), + (SealDefinition::Bitcoin(_) | SealDefinition::Liquid(_), Some(anchor)) => { + self.status.add_failure(Failure::SealWitnessLayer1Mismatch { + seal: seal.layer1(), + anchor: anchor.layer1(), + }); + continue; + } }; seals.push(seal); } diff --git a/stl/RGB@0.1.0.sta b/stl/RGB@0.1.0.sta index 6f34bb81..380038fe 100644 --- a/stl/RGB@0.1.0.sta +++ b/stl/RGB@0.1.0.sta @@ -1,248 +1,268 @@ -----BEGIN STRICT TYPE LIB----- -Id: urn:ubideco:stl:28ZcP9sj9SC5CC52qLWM9YxxRRhXAJjwRqD98nZLmx2y +Id: urn:ubideco:stl:DmN8aZj1dPvAvx5JYfz22azHs5RRbECxmxWoo5LK7E5f Name: RGB Dependencies: + urn:ubideco:stl:ZtHaBzu9ojbDahaGKEXe5v9DfSDxLERbLkEB23R6Q6V, urn:ubideco:stl:2YsxMW6xygK2FxFSbbBLqmzaUSytmLHHNF9DRio5zNr2, urn:ubideco:stl:5XLKQ1sNryZm9bdFKU2kBY3MPYdZXhchVdQKBbHA3gby, urn:ubideco:stl:6GgF7biXPVNcus2FfQj2pQuRzau11rXApMQLfCZhojgi, urn:ubideco:stl:9KALDYR8Nyjq4FdMW6kYoL7vdkWnqPqNuFnmE9qHpNjZ, urn:ubideco:stl:DVtm25LRKU4TjbyZmVxPhvCmctZ6vKkPKqfpU2QsDNUo -A1JHQgUXBk5pibwA035ABMB1qXDVJA6Hx9E0fiwbbm7GLsChNwZCUENvcmVDNAOU -2Bsw4lIokCYe82/5+Kg5UZH1C2leIyoes7dByAtTdHJpY3RUeXBlc05OhPRwFsnl -0mJ8v8P0NrLdbNTRubBEW/9e74J2cndXB0JpdGNvaW57hIA8nvriESWnfCw5vHDS -/ej5Q64N/Zz05oLtx2bKcANTdGS5swegWqdWSYZDQm66Fgs/j4xo+ehP/c0thUAK -ee0PYAVBbHVWTQUFQWx1Vk0CAG3voSbhvHXh/0hL+4XBNNEMMtyMHkDgaUsc1qfr -3NxhB0xpYlNpdGWnMFUCLflcyPCJo0WiP5beUSnAE7cO8SfYIZBBlftTCgVMaWJJ -ZAZCUENvcmUFAAxQbJJJnFjzLy7sLFS41xZrvJgU7D6ZAkU9cS66YQnhDUJsaW5k -U2VhbFR4aWRoGeu81bMYq5ezmKVLNmXd2qcGb+jpJOcDYKmUs70GTgpTZWNyZXRT -ZWFsfrX4M3yRqm+4vZW7u8v14cUliUXSEXbaHtTcjMUxJWUOQmxpbmRTZWFsVHhQ -dHKx5Tg5FAo4vvBvGs++HGClb+Hh9H14CCh5v9H60xAh3QVUeFB0ctJSMHx9cZA1 -9zB+6Cgl7BuBK6GH3Z2YSYtKjRb6btVDC0Nsb3NlTWV0aG9kB0JpdGNvaW4DACHj -PkPFqlzyKSdTozjBZ+07Y5xN2c69qY80aRe6yUN1BFZvdXRS2isFLayiTrJNkcIh -faCRfc9eTfyHZJ8nodoZFEUJkwVDaGFpbqOCQvPL19HQoRLajeFgL1bU+G8OxMR2 -xcBoWUxLBGVWBFR4aWQDU3RkAQByjqaKl950IPYqWWmwS4cmBL9F1t84lZx+Juen -JJDkrQ5BbHBoYU51bUxvZGFzaAtTdHJpY3RUeXBlcw4AJGPav3xK8eqRIO+/gMLH -iaFXktTx+6MsWJgjsQ9pIfoJUHJpbWl0aXZlKNW5WFDcLVWM0Cgl05Fu3W7c8hc9 -ykB5gdchtv8EB1sHVmFyaWFudC5HWz5zyeAibY4sJ7oUs6olvm0o90d+LP2MTShe -GOxWClR5cGVTeXN0ZW0xn1SGkTd0Y/zuX2R7hvvMeznjjLEkkTadT8MjzkVTlBBW -YXJpYW50SW5mb1NlbUlkPf7O9epejJlIc9v8I3FIjZc0RH4GjkUBmIyK4nlrCeES -VW5pb25WYXJpYW50c1NlbUlkUrbOCeSLVr1+2gjSU/4ipCdadp5fXqtpJ408YqoO -zeMMRW51bVZhcmlhbnRzZIzUD7BrhqmPZ6HASc0GpcX2indA8B7xBeR+WBKH/U8S -VW5uYW1lZEZpZWxkc1NlbUlkZjs3H8FYcj98sA45lBoVGkW2FHCHUV3lK+tUKfxt -YcEQTmFtZWRGaWVsZHNTZW1JZGdWkBgTHbcpmp/Yg0iXm2gsqcEeRaKpbeNhC7Tg -xE+ACkZpZWxkU2VtSWRrBKMUnqaVABZnn+8CtKsk9ea3imTI2dC9ZfzXo1hOjQVT -ZW1JZHnhi2InWK4TAbvqB8SGn6w9UNmQEi8JpEn9P7P6he9rB1R5U2VtSWR9djJJ -9Q+7qVWrJHLyb2mPxeAJGoLpFBTbolDWJ2TH6AVJZGVudIHTLCTXw+gy2cNi/cj0 -j5CdP4covDJOTeRMoeGJmxkGBlNpemluZ6gU7Ciw7VXt7q5ReaTn5Z9As/lVFhBu -m8Euchq/flYcCUZpZWxkTmFtZToACUFsdExheWVyMQMDBmxpcXVpZAEHYWJyYXhh -cxAFcHJpbWURDEFsdExheWVyMVNldAUBAAkBsCg2ZxB6frvN7t0BXHE1tteKvzew -M19b8Hk9EMcio8sAAAAAAAAAAP8AAAAAAAAACUFsdVNjcmlwdAYCBGxpYnMACgK5 -swegWqdWSYZDQm66Fgs/j4xo+ehP/c0thUAKee0PYKcwVQIt+VzI8ImjRaI/lt5R -KcATtw7xJ9ghkEGV+1MKAAgAAEAAAAAAAAAAAP//AAAAAAAAAAAAAAAAAAD/AAAA -AAAAAAtlbnRyeVBvaW50cwAKAAcAAEADAAK5swegWqdWSYZDQm66Fgs/j4xo+ehP -/c0thUAKee0PYG3voSbhvHXh/0hL+4XBNNEMMtyMHkDgaUsc1qfr3NxhAAAAAAAA -AAD//wAAAAAAACJBc3NpZ25SZXZlYWxlZEF0dGFjaEJsaW5kU2VhbFR4UHRyBAQA -DGNvbmZpZGVudGlhbAAGAgRzZWFsAhcGTmmJvADTfkAEwHWpcNUkDofH0TR+LBtu -bsYuwKE3aBnrvNWzGKuXs5ilSzZl3dqnBm/o6STnA2CplLO9Bk4Fc3RhdGUB/DRF -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 -qmYv2jrZkb8GqykOvND2egNKzAMIcmV2ZWFsZWQABgIEc2VhbAEiKCKcQ3Y9yLNC -muECa3LjUNl3L2zjLowpigVfZ1fyJQVzdGF0ZQFoUzQgDNxTxk124rYuqmYv2jrZ -kb8GqykOvND2egNKzCBBc3NpZ25SZXZlYWxlZERhdGFCbGluZFNlYWxUeFB0cgQE -AAxjb25maWRlbnRpYWwABgIEc2VhbAIXBk5pibwA035ABMB1qXDVJA6Hx9E0fiwb -bm7GLsChN2gZ67zVsxirl7OYpUs2Zd3apwZv6Okk5wNgqZSzvQZOBXN0YXRlAXAN -ZRCygoFvH7c95RJjkwNXCKVSYa0C4NS+WsXPp+oJARFjb25maWRlbnRpYWxTdGF0 -ZQAGAgRzZWFsAUwOZhJWYVmGKwGopFLSjxSghbpucBuoQD3MYg/idq3oBXN0YXRl -AXANZRCygoFvH7c95RJjkwNXCKVSYa0C4NS+WsXPp+oJAhBjb25maWRlbnRpYWxT -ZWFsAAYCBHNlYWwCFwZOaYm8ANN+QATAdalw1SQOh8fRNH4sG25uxi7AoTdoGeu8 -1bMYq5ezmKVLNmXd2qcGb+jpJOcDYKmUs70GTgVzdGF0ZQEg8lBWIo9mzvyR+upn -vF/G8GlcPUd5c1k/rNE3ynJIZQMIcmV2ZWFsZWQABgIEc2VhbAFMDmYSVmFZhisB -qKRS0o8UoIW6bnAbqEA9zGIP4nat6AVzdGF0ZQEg8lBWIo9mzvyR+upnvF/G8Glc -PUd5c1k/rNE3ynJIZR9Bc3NpZ25SZXZlYWxlZERhdGFCbGluZFNlYWxUeGlkBAQA -DGNvbmZpZGVudGlhbAAGAgRzZWFsAhcGTmmJvADTfkAEwHWpcNUkDofH0TR+LBtu -bsYuwKE3aBnrvNWzGKuXs5ilSzZl3dqnBm/o6STnA2CplLO9Bk4Fc3RhdGUBcA1l -ELKCgW8ftz3lEmOTA1cIpVJhrQLg1L5axc+n6gkBEWNvbmZpZGVudGlhbFN0YXRl +aFM0IAzcU8ZNduK2LqpmL9o62ZG/BqspDrzQ9noDSswhQXNzaWduUmV2ZWFsZWRB +dHRhY2hCbGluZFNlYWxUeGlkBAQADGNvbmZpZGVudGlhbAAGAgRzZWFsAhcGTmmJ +vADTfkAEwHWpcNUkDofH0TR+LBtubsYuwKE3aBnrvNWzGKuXs5ilSzZl3dqnBm/o +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 -ZWFsAAYCBHNlYWwCFwZOaYm8ANN+QATAdalw1SQOh8fRNH4sG25uxi7AoTdoGeu8 -1bMYq5ezmKVLNmXd2qcGb+jpJOcDYKmUs70GTgVzdGF0ZQHsz3qHnB+tbzh8HtJ4 -icDg/bTe1DoykxzsLMusu9KsLQMIcmV2ZWFsZWQABgIEc2VhbAFMDmYSVmFZhisB -qKRS0o8UoIW6bnAbqEA9zGIP4nat6AVzdGF0ZQHsz3qHnB+tbzh8HtJ4icDg/bTe -1DoykxzsLMusu9KsLSBBc3NpZ25SZXZlYWxlZFZhbHVlQmxpbmRTZWFsVHhpZAQE -AAxjb25maWRlbnRpYWwABgIEc2VhbAIXBk5pibwA035ABMB1qXDVJA6Hx9E0fiwb -bm7GLsChN2gZ67zVsxirl7OYpUs2Zd3apwZv6Okk5wNgqZSzvQZOBXN0YXRlAcJR -rWXpdQ2smhJZzMCFJFzV97FvUthyNkYs8XWMn05dARFjb25maWRlbnRpYWxTdGF0 -ZQAGAgRzZWFsASIoIpxDdj3Is0Ka4QJrcuNQ2XcvbOMujCmKBV9nV/IlBXN0YXRl -AcJRrWXpdQ2smhJZzMCFJFzV97FvUthyNkYs8XWMn05dAhBjb25maWRlbnRpYWxT -ZWFsAAYCBHNlYWwCFwZOaYm8ANN+QATAdalw1SQOh8fRNH4sG25uxi7AoTdoGeu8 -1bMYq5ezmKVLNmXd2qcGb+jpJOcDYKmUs70GTgVzdGF0ZQHsz3qHnB+tbzh8HtJ4 -icDg/bTe1DoykxzsLMusu9KsLQMIcmV2ZWFsZWQABgIEc2VhbAEiKCKcQ3Y9yLNC -muECa3LjUNl3L2zjLowpigVfZ1fyJQVzdGF0ZQHsz3qHnB+tbzh8HtJ4icDg/bTe -1DoykxzsLMusu9KsLR1Bc3NpZ25Wb2lkU3RhdGVCbGluZFNlYWxUeFB0cgQEAAxj -b25maWRlbnRpYWwABgIEc2VhbAIXBk5pibwA035ABMB1qXDVJA6Hx9E0fiwbbm7G -LsChN2gZ67zVsxirl7OYpUs2Zd3apwZv6Okk5wNgqZSzvQZOBXN0YXRlAS6ypf4X -wDBEMJjgXJsbWmzWHu12DWHey4Am02TzFuG7ARFjb25maWRlbnRpYWxTdGF0ZQAG +IPJQViKPZs78kfrqZ7xfxvBpXD1HeXNZP6zRN8pySGUhQXNzaWduUmV2ZWFsZWRW +YWx1ZUJsaW5kU2VhbFR4UHRyBAQADGNvbmZpZGVudGlhbAAGAgRzZWFsAhcGTmmJ +vADTfkAEwHWpcNUkDofH0TR+LBtubsYuwKE3aBnrvNWzGKuXs5ilSzZl3dqnBm/o +6STnA2CplLO9Bk4Fc3RhdGUBwlGtZel1DayaElnMwIUkXNX3sW9S2HI2RizxdYyf +Tl0BEWNvbmZpZGVudGlhbFN0YXRlAAYCBHNlYWwBTA5mElZhWYYrAaikUtKPFKCF +um5wG6hAPcxiD+J2regFc3RhdGUBwlGtZel1DayaElnMwIUkXNX3sW9S2HI2Rizx +dYyfTl0CEGNvbmZpZGVudGlhbFNlYWwABgIEc2VhbAIXBk5pibwA035ABMB1qXDV +JA6Hx9E0fiwbbm7GLsChN2gZ67zVsxirl7OYpUs2Zd3apwZv6Okk5wNgqZSzvQZO +BXN0YXRlAezPeoecH61vOHwe0niJwOD9tN7UOjKTHOwsy6y70qwtAwhyZXZlYWxl +ZAAGAgRzZWFsAUwOZhJWYVmGKwGopFLSjxSghbpucBuoQD3MYg/idq3oBXN0YXRl +AezPeoecH61vOHwe0niJwOD9tN7UOjKTHOwsy6y70qwtIEFzc2lnblJldmVhbGVk +VmFsdWVCbGluZFNlYWxUeGlkBAQADGNvbmZpZGVudGlhbAAGAgRzZWFsAhcGTmmJ +vADTfkAEwHWpcNUkDofH0TR+LBtubsYuwKE3aBnrvNWzGKuXs5ilSzZl3dqnBm/o +6STnA2CplLO9Bk4Fc3RhdGUBwlGtZel1DayaElnMwIUkXNX3sW9S2HI2RizxdYyf +Tl0BEWNvbmZpZGVudGlhbFN0YXRlAAYCBHNlYWwBIiginEN2PcizQprhAmty41DZ +dy9s4y6MKYoFX2dX8iUFc3RhdGUBwlGtZel1DayaElnMwIUkXNX3sW9S2HI2Rizx +dYyfTl0CEGNvbmZpZGVudGlhbFNlYWwABgIEc2VhbAIXBk5pibwA035ABMB1qXDV +JA6Hx9E0fiwbbm7GLsChN2gZ67zVsxirl7OYpUs2Zd3apwZv6Okk5wNgqZSzvQZO +BXN0YXRlAezPeoecH61vOHwe0niJwOD9tN7UOjKTHOwsy6y70qwtAwhyZXZlYWxl +ZAAGAgRzZWFsASIoIpxDdj3Is0Ka4QJrcuNQ2XcvbOMujCmKBV9nV/IlBXN0YXRl +AezPeoecH61vOHwe0niJwOD9tN7UOjKTHOwsy6y70qwtHUFzc2lnblZvaWRTdGF0 +ZUJsaW5kU2VhbFR4UHRyBAQADGNvbmZpZGVudGlhbAAGAgRzZWFsAhcGTmmJvADT +fkAEwHWpcNUkDofH0TR+LBtubsYuwKE3aBnrvNWzGKuXs5ilSzZl3dqnBm/o6STn +A2CplLO9Bk4Fc3RhdGUBLrKl/hfAMEQwmOBcmxtabNYe7XYNYd7LgCbTZPMW4bsB +EWNvbmZpZGVudGlhbFN0YXRlAAYCBHNlYWwBTA5mElZhWYYrAaikUtKPFKCFum5w +G6hAPcxiD+J2regFc3RhdGUBLrKl/hfAMEQwmOBcmxtabNYe7XYNYd7LgCbTZPMW +4bsCEGNvbmZpZGVudGlhbFNlYWwABgIEc2VhbAIXBk5pibwA035ABMB1qXDVJA6H +x9E0fiwbbm7GLsChN2gZ67zVsxirl7OYpUs2Zd3apwZv6Okk5wNgqZSzvQZOBXN0 +YXRlAS6ypf4XwDBEMJjgXJsbWmzWHu12DWHey4Am02TzFuG7AwhyZXZlYWxlZAAG AgRzZWFsAUwOZhJWYVmGKwGopFLSjxSghbpucBuoQD3MYg/idq3oBXN0YXRlAS6y -pf4XwDBEMJjgXJsbWmzWHu12DWHey4Am02TzFuG7AhBjb25maWRlbnRpYWxTZWFs -AAYCBHNlYWwCFwZOaYm8ANN+QATAdalw1SQOh8fRNH4sG25uxi7AoTdoGeu81bMY -q5ezmKVLNmXd2qcGb+jpJOcDYKmUs70GTgVzdGF0ZQEusqX+F8AwRDCY4FybG1ps -1h7tdg1h3suAJtNk8xbhuwMIcmV2ZWFsZWQABgIEc2VhbAFMDmYSVmFZhisBqKRS -0o8UoIW6bnAbqEA9zGIP4nat6AVzdGF0ZQEusqX+F8AwRDCY4FybG1ps1h7tdg1h -3suAJtNk8xbhuxxBc3NpZ25Wb2lkU3RhdGVCbGluZFNlYWxUeGlkBAQADGNvbmZp -ZGVudGlhbAAGAgRzZWFsAhcGTmmJvADTfkAEwHWpcNUkDofH0TR+LBtubsYuwKE3 -aBnrvNWzGKuXs5ilSzZl3dqnBm/o6STnA2CplLO9Bk4Fc3RhdGUBLrKl/hfAMEQw -mOBcmxtabNYe7XYNYd7LgCbTZPMW4bsBEWNvbmZpZGVudGlhbFN0YXRlAAYCBHNl +pf4XwDBEMJjgXJsbWmzWHu12DWHey4Am02TzFuG7HEFzc2lnblZvaWRTdGF0ZUJs +aW5kU2VhbFR4aWQEBAAMY29uZmlkZW50aWFsAAYCBHNlYWwCFwZOaYm8ANN+QATA +dalw1SQOh8fRNH4sG25uxi7AoTdoGeu81bMYq5ezmKVLNmXd2qcGb+jpJOcDYKmU +s70GTgVzdGF0ZQEusqX+F8AwRDCY4FybG1ps1h7tdg1h3suAJtNk8xbhuwERY29u +ZmlkZW50aWFsU3RhdGUABgIEc2VhbAEiKCKcQ3Y9yLNCmuECa3LjUNl3L2zjLowp +igVfZ1fyJQVzdGF0ZQEusqX+F8AwRDCY4FybG1ps1h7tdg1h3suAJtNk8xbhuwIQ +Y29uZmlkZW50aWFsU2VhbAAGAgRzZWFsAhcGTmmJvADTfkAEwHWpcNUkDofH0TR+ +LBtubsYuwKE3aBnrvNWzGKuXs5ilSzZl3dqnBm/o6STnA2CplLO9Bk4Fc3RhdGUB +LrKl/hfAMEQwmOBcmxtabNYe7XYNYd7LgCbTZPMW4bsDCHJldmVhbGVkAAYCBHNl YWwBIiginEN2PcizQprhAmty41DZdy9s4y6MKYoFX2dX8iUFc3RhdGUBLrKl/hfA -MEQwmOBcmxtabNYe7XYNYd7LgCbTZPMW4bsCEGNvbmZpZGVudGlhbFNlYWwABgIE -c2VhbAIXBk5pibwA035ABMB1qXDVJA6Hx9E0fiwbbm7GLsChN2gZ67zVsxirl7OY -pUs2Zd3apwZv6Okk5wNgqZSzvQZOBXN0YXRlAS6ypf4XwDBEMJjgXJsbWmzWHu12 -DWHey4Am02TzFuG7AwhyZXZlYWxlZAAGAgRzZWFsASIoIpxDdj3Is0Ka4QJrcuNQ -2XcvbOMujCmKBV9nV/IlBXN0YXRlAS6ypf4XwDBEMJjgXJsbWmzWHu12DWHey4Am -02TzFuG7GUFzc2lnbm1lbnRzQmxpbmRTZWFsVHhQdHIFAQAKAAACAXnrMHagYzXd -WTfXzI9eqDaCZaT2GUeP1YaqS4r25dPRAAAAAAAAAAD/AAAAAAAAABhBc3NpZ25t -ZW50c0JsaW5kU2VhbFR4aWQFAQAKAAACAczZPF7dYDyIiXmdJlXUp5vepvBgmQqY -bkZ4Bg1jFaPyAAAAAAAAAAD/AAAAAAAAAAhBdHRhY2hJZAUBAAcAAEAgAA5CbGlu -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 -nnBcnJHM291G7Y9w5Y71FIM+yD5cZLVqW8NTrbAcU2VhbERlZmluaXRpb25CbGlu -ZFNlYWxUeFB0cgQCAAdiaXRjb2luAAUBAhcGTmmJvADTfkAEwHWpcNUkDofH0TR+ -LBtubsYuwKE3frX4M3yRqm+4vZW7u8v14cUliUXSEXbaHtTcjMUxJWUBBmxpcXVp -ZAAFAQIXBk5pibwA035ABMB1qXDVJA6Hx9E0fiwbbm7GLsChN361+DN8kapvuL2V -u7vL9eHFJYlF0hF22h7U3IzFMSVlG1NlYWxEZWZpbml0aW9uQmxpbmRTZWFsVHhp -ZAQCAAdiaXRjb2luAAUBAhcGTmmJvADTfkAEwHWpcNUkDofH0TR+LBtubsYuwKE3 -DFBskkmcWPMvLuwsVLjXFmu8mBTsPpkCRT1xLrphCeEBBmxpcXVpZAAFAQIXBk5p -ibwA035ABMB1qXDVJA6Hx9E0fiwbbm7GLsChNwxQbJJJnFjzLy7sLFS41xZrvJgU -7D6ZAkU9cS66YQnhC1N0YXRlU2NoZW1hBAQAC2RlY2xhcmF0aXZlAAAAAQhmdW5n -aWJsZQAFAQH59KwIZq5Bd2bU/QwRfQSx2VT9DmdeEjtiBOtxT+nlRgIKc3RydWN0 -dXJlZAAFAQJDNAOU2Bsw4lIokCYe82/5+Kg5UZH1C2leIyoes7dByGsEoxSeppUA -Fmef7wK0qyT15reKZMjZ0L1l/NejWE6NAwphdHRhY2htZW50AAUBAUIwYYWIyNSr -FCZAx/3JFyzN0P8Q/w2TgABEfIia3cx5ClRyYW5zaXRpb24GCANmZnYB2ptRE1gW -VnaQh/uZ5VaUcjaA1zkMBqHMJJgsBWT3zNUKY29udHJhY3RJZAGfCCxJOsgCorrF -3dwLInwgr5TUaMRIzxpaIeC9wvU6Mg50cmFuc2l0aW9uVHlwZQAAAghtZXRhZGF0 -YQAIAABAAAAAAAAAAAD//wAAAAAAAAdnbG9iYWxzAetvipD2uMV5IwRWSrwy9nx4 -4FCFOqYIngxOHT7XkFeVBmlucHV0cwFaX9oXbyoy58+YADITLy6YdgaX++L/qrjV -Q09cyFPGbAthc3NpZ25tZW50cwHCuvewCwgWKAedUG/QjybA6AOiuHPowUo6v7SP -Jbj9QQl2YWxlbmNpZXMBsOCFp4c28gbxzK8xWHgGA4mJ7+JRPBb8ZFKSUw/EB38Q -VHJhbnNpdGlvbkJ1bmRsZQUBAAoBlcjmeh51Yl/UllVCapHrfkKQoW9amPG+UPe2 -iiQS98UBZ5eezUsO3SmECPXJzF5TkmFk1s8xolN6Luc4CVzbCKAAAAAAAAAAAP8A -AAAAAAAAEFRyYW5zaXRpb25TY2hlbWEGBQhtZXRhZGF0YQJDNAOU2Bsw4lIokCYe -82/5+Kg5UZH1C2leIyoes7dByGsEoxSeppUAFmef7wK0qyT15reKZMjZ0L1l/Nej -WE6NB2dsb2JhbHMACgAAAgE2wTSh+qCBE6fdMIA8XrDywv3aFLDVo9aTw26eDzKq -eQAAAAAAAAAA/wAAAAAAAAAGaW5wdXRzAAoAAAIBNsE0ofqggROn3TCAPF6w8sL9 -2hSw1aPWk8Nung8yqnkAAAAAAAAAAP8AAAAAAAAAC2Fzc2lnbm1lbnRzAAoAAAIB -NsE0ofqggROn3TCAPF6w8sL92hSw1aPWk8Nung8yqnkAAAAAAAAAAP8AAAAAAAAA -CXZhbGVuY2llcwAJAAACAAAAAAAAAAD/AAAAAAAAABpUeXBlZEFzc2lnbnNCbGlu -ZFNlYWxUeFB0cgQEAAtkZWNsYXJhdGl2ZQAFAQAIASlmLu7+YHlscLtafG2Pcozo -6kvLU/N6TMuVk2gImp7uAAAAAAAAAAD//wAAAAAAAAEIZnVuZ2libGUABQEACAFL -SRG2x4jTs6qG/MVTVjz9mirxuAfG5sef6XtWmQ8QsQAAAAAAAAAA//8AAAAAAAAC -CnN0cnVjdHVyZWQABQEACAFZolHNjebLiSRE7c91W7GqpdwcP9rBNM1sJTbV9hOK -wgAAAAAAAAAA//8AAAAAAAD/CmF0dGFjaG1lbnQABQEACAH7zBd2FTkXpjSm4b7g -Ht0r3GK/r4la5XU5cv8qQZfYgAAAAAAAAAAA//8AAAAAAAAZVHlwZWRBc3NpZ25z -QmxpbmRTZWFsVHhpZAQEAAtkZWNsYXJhdGl2ZQAFAQAIAZjmCNUpvD8wzk9MqgCs -LOdH/s86QuxysgqCwL4CEwKJAAAAAAAAAAD//wAAAAAAAAEIZnVuZ2libGUABQEA -CAF/bNH54DeCyZUq/Co3RTZAa4Zaz3o4XneDyeDI1eOA/QAAAAAAAAAA//8AAAAA -AAACCnN0cnVjdHVyZWQABQEACAE+3J1wNEPkBuDqB11Dgy/Nr1/LVPO0gJ1pu+1/ -YKRBowAAAAAAAAAA//8AAAAAAAD/CmF0dGFjaG1lbnQABQEACAEP+aNjbGPkkqop -cG754NrtT7ZHuV77qjvpdbNGEwz2fAAAAAAAAAAA//8AAAAAAAAJVmFsZW5jaWVz -BQEACQAAAgAAAAAAAAAA/wAAAAAAAAAJVm9pZFN0YXRlBQEAAAA= +MEQwmOBcmxtabNYe7XYNYd7LgCbTZPMW4bsZQXNzaWdubWVudHNCbGluZFNlYWxU +eFB0cgUBAAoAAAIBeeswdqBjNd1ZN9fMj16oNoJlpPYZR4/VhqpLivbl09EAAAAA +AAAAAP8AAAAAAAAAGEFzc2lnbm1lbnRzQmxpbmRTZWFsVHhpZAUBAAoAAAIBzNk8 +Xt1gPIiJeZ0mVdSnm96m8GCZCphuRngGDWMVo/IAAAAAAAAAAP8AAAAAAAAACEF0 +dGFjaElkBQEABwAAQCAADkJsaW5kaW5nRmFjdG9yBQEABwAAQCAACkJ1bmRsZUl0 +ZW0GAgZpbnB1dHMACQAAAgAAAAAAAAAA/wAAAAAAAAAKdHJhbnNpdGlvbgAEAgAE +bm9uZQAAAAEEc29tZQAFAQFyav7sDLwdmsk+0zB+aqpG2Htym8Lp6ZlbxBJ+CwyV +Ew9Db25jZWFsZWRBdHRhY2gFAQAHAABAIAANQ29uY2VhbGVkRGF0YQUBAAcAAEAg +ABFDb25jZWFsZWRGdW5naWJsZQYCCmNvbW1pdG1lbnQBSL0abhf7hjsWfH4lXjVn +24JD7ypeuuuixQrNCa6eURoKcmFuZ2VQcm9vZgGoWGv4kWXawiMQbb2FxIbJN+aw +ZusMZkH/Fi9oqHelmApDb250cmFjdElkBQEABwAAQCAACUV4dGVuc2lvbgYIA2Zm +dgHam1ETWBZWdpCH+5nlVpRyNoDXOQwGocwkmCwFZPfM1Qpjb250cmFjdElkAZ8I +LEk6yAKiusXd3AsifCCvlNRoxEjPGloh4L3C9ToyDWV4dGVuc2lvblR5cGUAAAII +bWV0YWRhdGEACAAAQAAAAAAAAAAA//8AAAAAAAAHZ2xvYmFscwHrb4qQ9rjFeSME +Vkq8MvZ8eOBQhTqmCJ4MTh0+15BXlQthc3NpZ25tZW50cwFoIrLyWVFI4r0yCsDT +PMMWyycifg2ukzKHdgJy6UTDCwhyZWRlZW1lZAGBBPQMEHyCLedbjLifPUq6TmRt +GcTdOVSe/wWDcQNhogl2YWxlbmNpZXMBsOCFp4c28gbxzK8xWHgGA4mJ7+JRPBb8 +ZFKSUw/EB38PRXh0ZW5zaW9uU2NoZW1hBgUIbWV0YWRhdGECQzQDlNgbMOJSKJAm +HvNv+fioOVGR9QtpXiMqHrO3QchrBKMUnqaVABZnn+8CtKsk9ea3imTI2dC9ZfzX +o1hOjQdnbG9iYWxzAAoAAAIBNsE0ofqggROn3TCAPF6w8sL92hSw1aPWk8Nung8y +qnkAAAAAAAAAAP8AAAAAAAAAB3JlZGVlbXMACQAAAgAAAAAAAAAA/wAAAAAAAAAL +YXNzaWdubWVudHMACgAAAgE2wTSh+qCBE6fdMIA8XrDywv3aFLDVo9aTw26eDzKq +eQAAAAAAAAAA/wAAAAAAAAAJdmFsZW5jaWVzAAkAAAIAAAAAAAAAAP8AAAAAAAAA +A0ZmdgUBAAACDUZ1bmdpYmxlU3RhdGUEAQgGYml0czY0AAUBAAAIDEZ1bmdpYmxl +VHlwZQMBDXVuc2lnbmVkNjRCaXQIB0dlbmVzaXMGCANmZnYB2ptRE1gWVnaQh/uZ +5VaUcjaA1zkMBqHMJJgsBWT3zNUIc2NoZW1hSWQBlFLT2wOrq6hRn6f2PtAU69RN +fTE//P4A+l0kelQEkBAFY2hhaW4CTk6E9HAWyeXSYny/w/Q2st1s1NG5sERb/17v +gnZyd1dS2isFLayiTrJNkcIhfaCRfc9eTfyHZJ8nodoZFEUJkwlhbHRMYXllcjEB +JFdS2GWA8JzKaiM3VBJEIGB8oyx/7szxFBAAbwoJKowIbWV0YWRhdGEACAAAQAAA +AAAAAAAA//8AAAAAAAAHZ2xvYmFscwHrb4qQ9rjFeSMEVkq8MvZ8eOBQhTqmCJ4M +Th0+15BXlQthc3NpZ25tZW50cwFoIrLyWVFI4r0yCsDTPMMWyycifg2ukzKHdgJy +6UTDCwl2YWxlbmNpZXMBsOCFp4c28gbxzK8xWHgGA4mJ7+JRPBb8ZFKSUw/EB38N +R2VuZXNpc1NjaGVtYQYECG1ldGFkYXRhAkM0A5TYGzDiUiiQJh7zb/n4qDlRkfUL +aV4jKh6zt0HIawSjFJ6mlQAWZ5/vArSrJPXmt4pkyNnQvWX816NYTo0HZ2xvYmFs +cwAKAAACATbBNKH6oIETp90wgDxesPLC/doUsNWj1pPDbp4PMqp5AAAAAAAAAAD/ +AAAAAAAAAAthc3NpZ25tZW50cwAKAAACATbBNKH6oIETp90wgDxesPLC/doUsNWj +1pPDbp4PMqp5AAAAAAAAAAD/AAAAAAAAAAl2YWxlbmNpZXMACQAAAgAAAAAAAAAA +/wAAAAAAAAALR2xvYmFsU3RhdGUFAQAKAAACAUY0faUe7WgMXvtvL6bEb+nZw1Lv +iY4pspRGpo3GoF6mAAAAAAAAAAD/AAAAAAAAABFHbG9iYWxTdGF0ZVNjaGVtYQYC +BXNlbUlkAkM0A5TYGzDiUiiQJh7zb/n4qDlRkfULaV4jKh6zt0HIawSjFJ6mlQAW +Z5/vArSrJPXmt4pkyNnQvWX816NYTo0IbWF4SXRlbXMAAAIMR2xvYmFsVmFsdWVz +BQEACAEg8lBWIo9mzvyR+upnvF/G8GlcPUd5c1k/rNE3ynJIZQEAAAAAAAAA//8A +AAAAAAAFSW5wdXQGAgdwcmV2T3V0Aaawjv38G127IlBS82lZaY3dqABG9VrKo3Ll +fpvcRUfUCHJlc2VydmVkAUUqpV991gFKi6FtxGYytg/xtWzcOlMuz71rk9VnGZ6J +BklucHV0cwUBAAkBPlqnYG3tnbwDFKczl8RkDMGa/1GAht1OemrQCXATVCsAAAAA +AAAAAP8AAAAAAAAACU1lZGlhVHlwZQMBA2Fuef8JTm9pc2VEdW1iBQEABwAAQAAC +C09jY3VycmVuY2VzBgIDbWluAAACA21heAAAAgRPcElkBQEABwAAQCAABU9wb3V0 +BgMCb3ABlcjmeh51Yl/UllVCapHrfkKQoW9amPG+UPe2iiQS98UCdHkAAAICbm8A +AAISUGVkZXJzZW5Db21taXRtZW50BQEABwAAQCEAClJhbmdlUHJvb2YEAf8LcGxh +Y2Vob2xkZXIABQEBHnYX8Sd92z674WoPchG3be1V329DDVURXwN4J6VCVycIUmVk +ZWVtZWQFAQAKAAACAZXI5noedWJf1JZVQmqR635CkKFvWpjxvlD3tookEvfFAAAA +AAAAAAD/AAAAAAAAAAxSZXNlcnZlZEJ5dGUFAQAAAQ5SZXZlYWxlZEF0dGFjaAYD +AmlkAYRxDZMsTvTDtwhLaYuwh3ApfjlkJH9Fkdjag23Rfbo4CW1lZGlhVHlwZQFC +MGGFiMjUqxQmQMf9yRcszdD/EP8Nk4AARHyImt3MeQRzYWx0AAAIDFJldmVhbGVk +RGF0YQUBAAgAAEAAAAAAAAAAAP//AAAAAAAAEFJldmVhbGVkRnVuZ2libGUGAgV2 +YWx1ZQGmjDCRR0vKOsJijMeVRI0s3arFFJ8FM5Wr9jxVYQcXJghibGluZGluZwGF +uPgru/Skpg2zvz9FuA+UbniDw61SbZP0b6MBqG5H2gZTY2hlbWEGCgNmZnYB2ptR +E1gWVnaQh/uZ5VaUcjaA1zkMBqHMJJgsBWT3zNUIc3Vic2V0T2YABAIABG5vbmUA +AAABBHNvbWUABQEAAAALZ2xvYmFsVHlwZXMACgAAAgHHmKbYYzZ4RB7aUW4sPou/ +DqiwSoDBtx256XLmP3HmJAAAAAAAAAAA/wAAAAAAAAAKb3duZWRUeXBlcwAKAAAC +ATjKFOCFIsfjOYJGlLLDmVh1U6boygwO4eiVibqJdxvzAAAAAAAAAAD/AAAAAAAA +AAx2YWxlbmN5VHlwZXMACQAAAgAAAAAAAAAA/wAAAAAAAAAHZ2VuZXNpcwGblA3v +M5Cfnw7uyaHDdhBCGf5ktkikEsA6dK8AQpzo5ApleHRlbnNpb25zAAoAAAIBI56L +tdkMulBTMyQDIZb7pCPy8/N71QYVk+ATWJYxyvsAAAAAAAAAAP8AAAAAAAAAC3Ry +YW5zaXRpb25zAAoAAAIBdcch4IY/3CgzpUFMLeyPIjFO9jJgMS2nBOZc7djEZ0wA +AAAAAAAAAP8AAAAAAAAACnR5cGVTeXN0ZW0CQzQDlNgbMOJSKJAmHvNv+fioOVGR +9QtpXiMqHrO3QcguR1s+c8ngIm2OLCe6FLOqJb5tKPdHfiz9jE0oXhjsVgZzY3Jp +cHQBxhhje2dNDLS8qcBDXX8yYoOYeHN0J0PRN+VE+7oS0EwIU2NoZW1hSWQFAQAH +AABAIAAMU2NoZW1hU2NoZW1hBgoDZmZ2AdqbURNYFlZ2kIf7meVWlHI2gNc5DAah +zCSYLAVk98zVCHN1YnNldE9mAAQCAARub25lAAAAAQRzb21lAAUBAbDOQpObjGEC +CCWpCejvOUXEDEPK2k88y6zc2VhwYTmFC2dsb2JhbFR5cGVzAAoAAAIBx5im2GM2 +eEQe2lFuLD6Lvw6osEqAwbcduely5j9x5iQAAAAAAAAAAP8AAAAAAAAACm93bmVk +VHlwZXMACgAAAgE4yhTghSLH4zmCRpSyw5lYdVOm6MoMDuHolYm6iXcb8wAAAAAA +AAAA/wAAAAAAAAAMdmFsZW5jeVR5cGVzAAkAAAIAAAAAAAAAAP8AAAAAAAAAB2dl +bmVzaXMBm5QN7zOQn58O7smhw3YQQhn+ZLZIpBLAOnSvAEKc6OQKZXh0ZW5zaW9u +cwAKAAACASOei7XZDLpQUzMkAyGW+6Qj8vPze9UGFZPgE1iWMcr7AAAAAAAAAAD/ +AAAAAAAAAAt0cmFuc2l0aW9ucwAKAAACAXXHIeCGP9woM6VBTC3sjyIxTvYyYDEt +pwTmXO3YxGdMAAAAAAAAAAD/AAAAAAAAAAp0eXBlU3lzdGVtAkM0A5TYGzDiUiiQ +Jh7zb/n4qDlRkfULaV4jKh6zt0HILkdbPnPJ4CJtjiwnuhSzqiW+bSj3R34s/YxN +KF4Y7FYGc2NyaXB0AcYYY3tnTQy0vKnAQ11/MmKDmHhzdCdD0TflRPu6EtBMBlNj +cmlwdAQBAAVhbHVWbQAFAQGi+uqecFyckczb3Ubtj3DljvUUgz7IPlxktWpbw1Ot +sBxTZWFsRGVmaW5pdGlvbkJsaW5kU2VhbFR4UHRyBAIAB2JpdGNvaW4ABQECFwZO +aYm8ANN+QATAdalw1SQOh8fRNH4sG25uxi7AoTd+tfgzfJGqb7i9lbu7y/XhxSWJ +RdIRdtoe1NyMxTElZQEGbGlxdWlkAAUBAhcGTmmJvADTfkAEwHWpcNUkDofH0TR+ +LBtubsYuwKE3frX4M3yRqm+4vZW7u8v14cUliUXSEXbaHtTcjMUxJWUbU2VhbERl +ZmluaXRpb25CbGluZFNlYWxUeGlkBAIAB2JpdGNvaW4ABQECFwZOaYm8ANN+QATA +dalw1SQOh8fRNH4sG25uxi7AoTcMUGySSZxY8y8u7CxUuNcWa7yYFOw+mQJFPXEu +umEJ4QEGbGlxdWlkAAUBAhcGTmmJvADTfkAEwHWpcNUkDofH0TR+LBtubsYuwKE3 +DFBskkmcWPMvLuwsVLjXFmu8mBTsPpkCRT1xLrphCeELU3RhdGVTY2hlbWEEBAAL +ZGVjbGFyYXRpdmUAAAABCGZ1bmdpYmxlAAUBAfn0rAhmrkF3ZtT9DBF9BLHZVP0O +Z14SO2IE63FP6eVGAgpzdHJ1Y3R1cmVkAAUBAkM0A5TYGzDiUiiQJh7zb/n4qDlR +kfULaV4jKh6zt0HIawSjFJ6mlQAWZ5/vArSrJPXmt4pkyNnQvWX816NYTo0DCmF0 +dGFjaG1lbnQABQEBQjBhhYjI1KsUJkDH/ckXLM3Q/xD/DZOAAER8iJrdzHkKVHJh +bnNpdGlvbgYIA2ZmdgHam1ETWBZWdpCH+5nlVpRyNoDXOQwGocwkmCwFZPfM1Qpj +b250cmFjdElkAZ8ILEk6yAKiusXd3AsifCCvlNRoxEjPGloh4L3C9ToyDnRyYW5z +aXRpb25UeXBlAAACCG1ldGFkYXRhAAgAAEAAAAAAAAAAAP//AAAAAAAAB2dsb2Jh +bHMB62+KkPa4xXkjBFZKvDL2fHjgUIU6pgieDE4dPteQV5UGaW5wdXRzAVpf2hdv +KjLnz5gAMhMvLph2Bpf74v+quNVDT1zIU8ZsC2Fzc2lnbm1lbnRzAcK697ALCBYo +B51Qb9CPJsDoA6K4c+jBSjq/tI8luP1BCXZhbGVuY2llcwGw4IWnhzbyBvHMrzFY +eAYDiYnv4lE8FvxkUpJTD8QHfxBUcmFuc2l0aW9uQnVuZGxlBQEACgGVyOZ6HnVi +X9SWVUJqket+QpChb1qY8b5Q97aKJBL3xQFnl57NSw7dKYQI9cnMXlOSYWTWzzGi +U3ou5zgJXNsIoAAAAAAAAAAA/wAAAAAAAAAQVHJhbnNpdGlvblNjaGVtYQYFCG1l +dGFkYXRhAkM0A5TYGzDiUiiQJh7zb/n4qDlRkfULaV4jKh6zt0HIawSjFJ6mlQAW +Z5/vArSrJPXmt4pkyNnQvWX816NYTo0HZ2xvYmFscwAKAAACATbBNKH6oIETp90w +gDxesPLC/doUsNWj1pPDbp4PMqp5AAAAAAAAAAD/AAAAAAAAAAZpbnB1dHMACgAA +AgE2wTSh+qCBE6fdMIA8XrDywv3aFLDVo9aTw26eDzKqeQAAAAAAAAAA/wAAAAAA +AAALYXNzaWdubWVudHMACgAAAgE2wTSh+qCBE6fdMIA8XrDywv3aFLDVo9aTw26e +DzKqeQAAAAAAAAAA/wAAAAAAAAAJdmFsZW5jaWVzAAkAAAIAAAAAAAAAAP8AAAAA +AAAAGlR5cGVkQXNzaWduc0JsaW5kU2VhbFR4UHRyBAQAC2RlY2xhcmF0aXZlAAUB +AAgBKWYu7v5geWxwu1p8bY9yjOjqS8tT83pMy5WTaAianu4AAAAAAAAAAP//AAAA +AAAAAQhmdW5naWJsZQAFAQAIAUtJEbbHiNOzqob8xVNWPP2aKvG4B8bmx5/pe1aZ +DxCxAAAAAAAAAAD//wAAAAAAAAIKc3RydWN0dXJlZAAFAQAIAVmiUc2N5suJJETt +z3Vbsaql3Bw/2sE0zWwlNtX2E4rCAAAAAAAAAAD//wAAAAAAAP8KYXR0YWNobWVu +dAAFAQAIAfvMF3YVORemNKbhvuAe3SvcYr+viVrldTly/ypBl9iAAAAAAAAAAAD/ +/wAAAAAAABlUeXBlZEFzc2lnbnNCbGluZFNlYWxUeGlkBAQAC2RlY2xhcmF0aXZl +AAUBAAgBmOYI1Sm8PzDOT0yqAKws50f+zzpC7HKyCoLAvgITAokAAAAAAAAAAP// +AAAAAAAAAQhmdW5naWJsZQAFAQAIAX9s0fngN4LJlSr8KjdFNkBrhlrPejhed4PJ +4MjV44D9AAAAAAAAAAD//wAAAAAAAAIKc3RydWN0dXJlZAAFAQAIAT7cnXA0Q+QG +4OoHXUODL82vX8tU87SAnWm77X9gpEGjAAAAAAAAAAD//wAAAAAAAP8KYXR0YWNo +bWVudAAFAQAIAQ/5o2NsY+SSqilwbvng2u1Ptke5XvuqO+l1s0YTDPZ8AAAAAAAA +AAD//wAAAAAAAAlWYWxlbmNpZXMFAQAJAAACAAAAAAAAAAD/AAAAAAAAAAlWb2lk +U3RhdGUFAQAAAA== -----END STRICT TYPE LIB----- diff --git a/stl/RGB@0.1.0.stl b/stl/RGB@0.1.0.stl index a35823237c5440be81a6d07f32001786a246aa14..2e793558103b06504e2e469feed4a1b7338a966c 100644 GIT binary patch delta 1043 zcmZpR_!Vcw9OUlA#*s5w(>^TY&CUCB9ZET_FEmybb8!q~>egGsx&P_?UMC*s{M_8k zlCadG%(TkM2ZR+SsxD<@n|M0bgqwk}hCPD*gR-?9$Sk9`F7-u3cHo z-PX$Yz0!aisve})!ahl_F!<65#fdhj%Vp==rra<4q!Aja`@_w7ikNRME6`c|Aa@02 zre~Bm6(!~+XH0$|tT4HP(MoNV*O81zbyK!oW7e8BcURc&*wn@t&Z+>G0@b%2o0+HV zX9c@v@+QV0>xUQf!dKY&dCYRip5UYVex)IU4#&R3i3*p=s5Xle#b4 zxPz06G7CzaDoav}4R^15(b8FdbOXC#k>S}%-wd{C>YnYazq9M!(OpMg*53qq9~8_U ziNzU{6QvXkS)DTyGxOrt+{}Gy?{`$>=EmOihFe^#U+b!I|25ZLe4uJctmS-PE}zuI zG>A2mBbij|w;6M;l-R#*5^vs#h$SlR%5G7a_C?O@`~S;cw<>P*JIM}G4@?U8e=yiI z{&W8mqP+3au}A#8_gAIuJ@dJ?MEIn9>MaJF4ld8UlGLKS#GHU^l=Q>Ip#Sc?oXe$! znmfBhEZn^<3#V#p$Sh)$HJ<@?8p;mR+caY59AJifV(X(^M34FjiRPKi%qWonTjGb3A0W?^Y&3L_6(EI74< zm63sy@kDl0HFs3)v571yMNgH~`!Ae7Dixlwz}tS6p@Xzdo$};r*7xjekocP%sH(3( zD6S_jP}Qj?q=*k@n-dxF(&vDpHe#ND}Ie^_pSV1K`=tgS8hdHORl+8ngToe*&7VFf%JM&RQfFYlY MQ>$n58mTBj07MS0cK`qY delta 213 zcmewr*A~Ib9OUlAI{71q!o;AZjI0xX#4@omOm@&zn7opaZxXM<Kms`|P{Bj4_3#+pc%*H{W0!AN`@yR^YhO z;?tAgu)k+intYI3e)B(0CJ}`zUs<-z^jzBMFL ^ ..0xff [Byte]}, entryPoints {[Byte ^ 3] -> AluVM.LibSite {- urn:ubideco:semid:8Q9NNyK2PCcjZ7U7rDGUJBhk8q37hAnWLgSizGLmr56g#mission-papa-mercy -}} +-- urn:ubideco:semid:8vcfUdinF6vyygbB4pZh1HLAvgWSWN27szLBnkV8jR5w#field-mama-summer +data Anchor :: bitcoin BPCore.AnchorMerkleProof {- urn:ubideco:semid:GCVxKmrRiHJHrv43cBf21L7gFdkQUX4iEo4DSuywJyv1#demand-symbol-korea -} + | liquid BPCore.AnchorMerkleProof {- urn:ubideco:semid:GCVxKmrRiHJHrv43cBf21L7gFdkQUX4iEo4DSuywJyv1#demand-symbol-korea -} +-- urn:ubideco:semid:3wnGtf3mZhoFh3zXkSppQCDFesMZzj8dxmXCcEf7EgPP#picture-service-index +data AnchoredBundle :: anchor Anchor, bundle TransitionBundle -- urn:ubideco:semid:8Ffm9AttRojBCspPTxazNdaPB3BcFD2cr9c2sES1T7ox#desert-bambino-size data AssignRevealedAttachBlindSealTxPtr :: confidential (seal BPCore.SecretSeal {- urn:ubideco:semid:81NKrdc9pBoBjsKaGBVN9wXLG4tKjkK4f8DLj7TNMZxh#santana-domingo-needle -}, state ConcealedAttach) | confidentialState (seal SealDefinitionBlindSealTxPtr, state ConcealedAttach) From c0be2d9d2ced10b9c5e20493f9eac27f2bd3c4bd Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Mon, 30 Oct 2023 09:10:44 +0100 Subject: [PATCH 7/7] validation: check that seals and anchors use layer1 allowed in genesis --- src/contract/mod.rs | 10 +++++++ src/validation/status.rs | 7 ++++- src/validation/validator.rs | 60 ++++++++++++++++++++----------------- 3 files changed, 49 insertions(+), 28 deletions(-) diff --git a/src/contract/mod.rs b/src/contract/mod.rs index a09e70c0..687b2279 100644 --- a/src/contract/mod.rs +++ b/src/contract/mod.rs @@ -61,6 +61,8 @@ pub use seal::{ }; pub use state::{ConfidentialState, ExposedState, StateCommitment, StateData, StateType}; +use crate::Layer1; + #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Display)] #[display(lowercase)] #[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] @@ -79,6 +81,14 @@ pub enum AltLayer1 { // Prime = 0x11, } +impl AltLayer1 { + pub fn layer1(&self) -> Layer1 { + match self { + AltLayer1::Liquid => Layer1::Liquid, + } + } +} + #[derive(Wrapper, Clone, PartialEq, Eq, Hash, Debug, From)] #[wrapper(Deref)] #[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] diff --git a/src/validation/status.rs b/src/validation/status.rs index e743a241..d63a2b2f 100644 --- a/src/validation/status.rs +++ b/src/validation/status.rs @@ -25,13 +25,15 @@ use core::ops::AddAssign; use std::fmt::{self, Display, Formatter}; use bp::dbc::anchor; +use bp::seals::txout::blind::ChainBlindSeal; use bp::{seals, Txid}; use strict_types::SemId; use crate::contract::Opout; use crate::schema::{self, SchemaId}; use crate::{ - AssignmentType, BundleId, Layer1, OccurrencesMismatch, OpFullType, OpId, SecretSeal, StateType, + AssignmentType, BundleId, Layer1, OccurrencesMismatch, OpFullType, OpId, SealDefinition, + SecretSeal, StateType, }; #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Display)] @@ -318,6 +320,9 @@ pub enum Failure { SealNoWitnessTx(Txid), /// witness layer 1 {anchor} doesn't match seal definition {seal}. SealWitnessLayer1Mismatch { seal: Layer1, anchor: Layer1 }, + /// seal {1:?} is defined on {0} which is not in the set of layers allowed + /// by the contract genesis. + SealInvalidLayer1(Layer1, SealDefinition), /// transition {0} doesn't close seal with the witness transaction {1}. /// Details: {2} SealInvalid(OpId, Txid, seals::txout::VerifyError), diff --git a/src/validation/validator.rs b/src/validation/validator.rs index d033e828..440114a3 100644 --- a/src/validation/validator.rs +++ b/src/validation/validator.rs @@ -31,9 +31,9 @@ use super::status::{Failure, Warning}; use super::{ConsignmentApi, Status, Validity, VirtualMachine}; use crate::vm::AluRuntime; use crate::{ - Anchor, AnchoredBundle, BundleId, ContractId, GraphSeal, Layer1, OpId, OpRef, Operation, Opout, - Schema, SchemaId, SchemaRoot, Script, SealDefinition, SubSchema, Transition, TransitionBundle, - TypedAssigns, + AltLayer1, Anchor, AnchoredBundle, BundleId, ContractId, GraphSeal, Layer1, OpId, OpRef, + Operation, Opout, Schema, SchemaId, SchemaRoot, Script, SealDefinition, SubSchema, Transition, + TransitionBundle, TypedAssigns, }; #[derive(Clone, Debug, Display, Error, From)] @@ -57,6 +57,7 @@ pub struct Validator<'consignment, 'resolver, C: ConsignmentApi, R: ResolveTx> { schema_id: SchemaId, genesis_id: OpId, contract_id: ContractId, + layers1: BTreeSet, anchor_index: BTreeMap, end_transitions: Vec<(&'consignment Transition, BundleId)>, validation_index: BTreeSet, @@ -75,9 +76,10 @@ impl<'consignment, 'resolver, C: ConsignmentApi, R: ResolveTx> let mut status = Status::default(); // Frequently used computation-heavy data - let genesis_id = consignment.genesis().id(); - let contract_id = consignment.genesis().contract_id(); - let schema_id = consignment.genesis().schema_id; + let genesis = consignment.genesis(); + let genesis_id = genesis.id(); + let contract_id = genesis.contract_id(); + let schema_id = genesis.schema_id; // Create indexes let mut anchor_index = BTreeMap::::new(); @@ -132,6 +134,9 @@ impl<'consignment, 'resolver, C: ConsignmentApi, R: ResolveTx> // Index used to avoid repeated validations of the same anchor+transition pairs let anchor_validation_index = BTreeSet::::new(); + let mut layers1 = bset! { Layer1::Bitcoin }; + layers1.extend(genesis.alt_layer1.iter().map(AltLayer1::layer1)); + let vm = match &consignment.schema().script { Script::AluVM(lib) => { Box::new(AluRuntime::new(lib)) as Box @@ -144,6 +149,7 @@ impl<'consignment, 'resolver, C: ConsignmentApi, R: ResolveTx> schema_id, genesis_id, contract_id, + layers1, anchor_index, end_transitions, validation_index, @@ -424,56 +430,56 @@ impl<'consignment, 'resolver, C: ConsignmentApi, R: ResolveTx> continue; }; - let seal = match (seal, self.anchor_index.get(&op)) { + let Some(anchor) = self.anchor_index.get(&op) else { + panic!("anchor for the operation {op} was not indexed by the validator"); + }; + if seal.layer1() != anchor.layer1() { + self.status.add_failure(Failure::SealWitnessLayer1Mismatch { + seal: seal.layer1(), + anchor: anchor.layer1(), + }); + continue; + } + if !self.layers1.contains(&seal.layer1()) { + self.status + .add_failure(Failure::SealInvalidLayer1(seal.layer1(), seal)); + continue; + } + + let seal = match (seal, anchor) { ( SealDefinition::Bitcoin( seal @ GraphSeal { txid: TxPtr::WitnessTx, .. }, - ), - Some(Anchor::Bitcoin(anchor)), - ) | - ( + ) | SealDefinition::Liquid( seal @ GraphSeal { txid: TxPtr::WitnessTx, .. }, ), - Some(Anchor::Liquid(anchor)), + Anchor::Bitcoin(anchor) | Anchor::Liquid(anchor), ) => { let prev_witness_txid = anchor.txid; seal.resolve(prev_witness_txid) } - (SealDefinition::Bitcoin(_) | SealDefinition::Liquid(_), None) => { - panic!("anchor for the operation {op} was not indexed by the validator"); - } ( SealDefinition::Bitcoin( seal @ GraphSeal { txid: TxPtr::Txid(txid), .. }, - ), - Some(Anchor::Bitcoin(_)), - ) | - ( + ) | SealDefinition::Liquid( seal @ GraphSeal { txid: TxPtr::Txid(txid), .. }, ), - Some(Anchor::Liquid(_)), + Anchor::Bitcoin(_) | Anchor::Liquid(_), ) => seal.resolve(txid), - (SealDefinition::Bitcoin(_) | SealDefinition::Liquid(_), Some(anchor)) => { - self.status.add_failure(Failure::SealWitnessLayer1Mismatch { - seal: seal.layer1(), - anchor: anchor.layer1(), - }); - continue; - } }; seals.push(seal); }