diff --git a/Cargo.lock b/Cargo.lock index f9903e44..425902cc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -25,9 +25,9 @@ dependencies = [ [[package]] name = "amplify" -version = "4.7.0" +version = "4.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7147b742325842988dd6c793d55f58df3ae36bccf7d9b6e07db10ab035be343d" +checksum = "b2090b9b79b61d4047a307a46de043d0ee5ec406d99a7d652341b96d48ed5567" dependencies = [ "amplify_apfloat", "amplify_derive", @@ -178,12 +178,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "340e09e8399c7bd8912f495af6aa58bea0c9214773417ffaa8f6460f93aaee56" -[[package]] -name = "bitcoin-private" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73290177011694f38ec25e165d0387ab7ea749a4b81cd4c80dae5988229f7a57" - [[package]] name = "bitcoin_hashes" version = "0.14.0" @@ -230,14 +224,14 @@ dependencies = [ [[package]] name = "bp-consensus" -version = "0.11.0-beta.9" +version = "0.11.1-alpha.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54db63118d55e32ea78f8775e98871d442a33e3bdef6419c7964d71b308316c0" +checksum = "40f227ce25d185bc5fc9109ca83dfa8bd0e745f219e320f3da658aaf4fd7e0c5" dependencies = [ "amplify", "chrono", "commit_verify", - "secp256k1 0.30.0", + "secp256k1", "serde", "strict_encoding", "strict_types", @@ -245,9 +239,9 @@ dependencies = [ [[package]] name = "bp-core" -version = "0.11.0-beta.9" +version = "0.11.1-alpha.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e51a329150531b12243adf51d978490c796a6a20ec76c506b41c8e1226022bc" +checksum = "40c6b213ada98fe5e78a978e67a7044d16d2571edb3f85fcdb4246324ec9514a" dependencies = [ "amplify", "bp-consensus", @@ -264,24 +258,24 @@ dependencies = [ [[package]] name = "bp-dbc" -version = "0.11.0-beta.9" +version = "0.11.1-alpha.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9286fb448160672148262317f4647ebdcdd4699ed2bd34401f9799d0920cc376" +checksum = "d33d4cc345a595236441fc2b8726ca7eb693947914b278849d1e2c1923dcb314" dependencies = [ "amplify", "base85", "bp-consensus", "commit_verify", - "secp256k1 0.30.0", + "secp256k1", "serde", "strict_encoding", ] [[package]] name = "bp-invoice" -version = "0.11.0-beta.9.1" +version = "0.11.1-alpha.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "929663905dd8447a01a14fe35b31e62a4763c77f0757899cb9442b6d906fe701" +checksum = "fd6955d67eec75b22532edb859f1f4d7d4ba4af1db304abc511530f4e1a827b7" dependencies = [ "amplify", "bech32", @@ -291,9 +285,9 @@ dependencies = [ [[package]] name = "bp-seals" -version = "0.11.0-beta.9" +version = "0.11.1-alpha.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9873cfe420f4ce5cc539c394c75df0669cdbe2c23eed1930dffe024cb0f13a57" +checksum = "6a7a009fbf7e71be7ab5f43e032c69927f58cd7f59a6a822af64f84d3e8d41c5" dependencies = [ "amplify", "baid64", @@ -350,9 +344,9 @@ dependencies = [ [[package]] name = "commit_encoding_derive" -version = "0.11.0-beta.8" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea07c5ad73a637276dc4f8a957f8285764018d45bdefef35eb9137f32d0e3c81" +checksum = "dc09678c15e9280cc6eaf29bf437a2cf18fadedd8bf78c369b8ac15fa217dbe5" dependencies = [ "amplify", "amplify_syn", @@ -363,9 +357,9 @@ dependencies = [ [[package]] name = "commit_verify" -version = "0.11.0-beta.9" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bf08c4941e147937551f6a3d370552d67f98cf72c9eb18948142596beadd31e" +checksum = "0fcf5f557e112c684f2458f20c66bab865c01cab56d6a318f64243cba9b163a7" dependencies = [ "amplify", "commit_encoding_derive", @@ -694,9 +688,9 @@ dependencies = [ [[package]] name = "rgb-core" -version = "0.11.0-beta.9" +version = "0.11.1-alpha.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cf48c4e395882c5228cd788a78e04674c94f7c177d82afdd87def8619f5dff8" +checksum = "3ae7debf4fc13bbf2d217f71d29a0233fddf5fc5b148ded64175df36c3635029" dependencies = [ "aluvm", "amplify", @@ -706,7 +700,7 @@ dependencies = [ "commit_verify", "getrandom", "mime", - "secp256k1-zkp", + "secp256k1", "serde", "single_use_seals", "strict_encoding", @@ -798,17 +792,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" -[[package]] -name = "secp256k1" -version = "0.29.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9465315bc9d4566e1724f0fffcbcc446268cb522e60f9a27bcded6b19c108113" -dependencies = [ - "rand", - "secp256k1-sys", - "serde", -] - [[package]] name = "secp256k1" version = "0.30.0" @@ -830,29 +813,6 @@ dependencies = [ "cc", ] -[[package]] -name = "secp256k1-zkp" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52a44aed3002b5ae975f8624c5df3a949cfbf00479e18778b6058fcd213b76e3" -dependencies = [ - "bitcoin-private", - "rand", - "secp256k1 0.29.1", - "secp256k1-zkp-sys", - "serde", -] - -[[package]] -name = "secp256k1-zkp-sys" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57f08b2d0b143a22e07f798ae4f0ab20d5590d7c68e0d090f2088a48a21d1654" -dependencies = [ - "cc", - "secp256k1-sys", -] - [[package]] name = "serde" version = "1.0.214" @@ -936,9 +896,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "single_use_seals" -version = "0.11.0-beta.9" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec071f3b3153217f1cb2bca5ba7ac87eeafc446cb35a5c0643dec33495a37244" +checksum = "b01aad2d785dc858c4f652d1e18d0c815cd10aa8f15ac7accd2b12b894d7c367" dependencies = [ "amplify_derive", ] diff --git a/Cargo.toml b/Cargo.toml index 9fbd21e3..be0fd589 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,9 +29,9 @@ baid64 = "0.2.2" strict_encoding = "2.7.0" strict_types = "2.7.2" commit_verify = { version = "0.11.0-beta.9", features = ["stl"] } -bp-core = { version = "0.11.0-beta.9", features = ["stl"] } -bp-invoice = { version = "0.11.0-beta.9.1" } -rgb-core = { version = "0.11.0-beta.9", features = ["stl"] } +bp-core = { version = "0.11.1-alpha.1", features = ["stl"] } +bp-invoice = { version = "0.11.1-alpha.1" } +rgb-core = { version = "0.11.1-alpha.1", features = ["stl"] } indexmap = "2.4.0" serde_crate = { package = "serde", version = "1", features = ["derive"] } diff --git a/asset/armored_contract.default b/asset/armored_contract.default index 4944ab6e..0b3fb68e 100644 --- a/asset/armored_contract.default +++ b/asset/armored_contract.default @@ -1,13 +1,13 @@ -----BEGIN RGB CONSIGNMENT----- -Id: rgb:csg:mK5KaBwW-ht!iR1o-5qi3fe7-gIHhBiL-t80Tud5-Wi2Jo4A#bikini-binary-table +Id: rgb:csg:wxvP60ui-p$xdsn$-Zym51Qu-MW4pBOw-QTDxCI3-wMN2QlE#bread-kansas-yankee Version: 2 Type: contract -Contract: rgb:5M7hTCP5-or5y2Bp-xPPIYez-WEsey5D-e2GhCpV-HlsK7jI +Contract: rgb:dzueA1gq-gVtNGbP-YNB0DCs-tz9SpYl-xEctaAA-yO6UFaI Schema: rgb:sch:CyqM42yAdM1moWyNZPQedAYt73BM$k9z$dKLUXY1voA#cello-global-deluxe -Check-SHA256: 181748dae0c83cbb44f6ccfdaddf6faca0bc4122a9f35fef47bab9aea023e4a1 +Check-SHA256: def11f7fb29f94cbf0618caeaad77e65ec1b986e7e6799155c0623a5a9c34120 -0ssI2000000000000000000000000000000000000000000000000000000D0CRI`I$>^aZh38Qb#nj! -0000000000000000000000d59ZDjxe00000000dDb8~4rVQz13d2MfXa{vGU00000000000000000000 -0000000000000 +0ssI2000000000000000000000000000000000000000000000000000000D0CRI`I$>^aZh38Qb#np$ +00000000000000000004PGN0j00000000004FGd^aZh38Qb#nj! -0000000000000000000000d59ZDjxe00000000dDb8~4rVQz13d2MfXa{vGU00000000000000000000 -0000000000000 +0s#O3000000000000000000000000000000000000000000000000000000D0CRI`I$>^aZh38Qb#np$ +00000000000000000004PGN0j00000000004FGd Layer1 { - match self { - ChainNet::BitcoinMainnet - | ChainNet::BitcoinTestnet - | ChainNet::BitcoinSignet - | ChainNet::BitcoinRegtest => Layer1::Bitcoin, - ChainNet::LiquidMainnet | ChainNet::LiquidTestnet => Layer1::Liquid, - } - } - - pub fn is_prod(&self) -> bool { - match self { - ChainNet::BitcoinMainnet | ChainNet::LiquidMainnet => true, - - ChainNet::BitcoinTestnet - | ChainNet::BitcoinSignet - | ChainNet::BitcoinRegtest - | ChainNet::LiquidTestnet => false, - } - } - - pub fn address_network(&self) -> AddressNetwork { - match self { - ChainNet::BitcoinMainnet => AddressNetwork::Mainnet, - ChainNet::BitcoinTestnet | ChainNet::BitcoinSignet => AddressNetwork::Testnet, - ChainNet::BitcoinRegtest => AddressNetwork::Regtest, - ChainNet::LiquidMainnet => AddressNetwork::Mainnet, - ChainNet::LiquidTestnet => AddressNetwork::Testnet, - } - } -} - #[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug)] #[non_exhaustive] pub enum XChainNet { BitcoinMainnet(T), - BitcoinTestnet(T), + BitcoinTestnet3(T), + BitcoinTestnet4(T), BitcoinSignet(T), BitcoinRegtest(T), LiquidMainnet(T), @@ -143,7 +94,8 @@ impl XChainNet { pub fn with(cn: ChainNet, data: T) -> Self { match cn { ChainNet::BitcoinMainnet => XChainNet::BitcoinMainnet(data), - ChainNet::BitcoinTestnet => XChainNet::BitcoinTestnet(data), + ChainNet::BitcoinTestnet3 => XChainNet::BitcoinTestnet3(data), + ChainNet::BitcoinTestnet4 => XChainNet::BitcoinTestnet4(data), ChainNet::BitcoinSignet => XChainNet::BitcoinSignet(data), ChainNet::BitcoinRegtest => XChainNet::BitcoinRegtest(data), ChainNet::LiquidMainnet => XChainNet::LiquidMainnet(data), @@ -154,8 +106,8 @@ impl XChainNet { pub fn bitcoin(network: Network, data: T) -> Self { match network { Network::Mainnet => Self::BitcoinMainnet(data), - Network::Testnet3 => Self::BitcoinTestnet(data), - Network::Testnet4 => Self::BitcoinTestnet(data), + Network::Testnet3 => Self::BitcoinTestnet3(data), + Network::Testnet4 => Self::BitcoinTestnet4(data), Network::Signet => Self::BitcoinSignet(data), Network::Regtest => Self::BitcoinRegtest(data), } @@ -164,7 +116,8 @@ impl XChainNet { pub fn chain_network(&self) -> ChainNet { match self { XChainNet::BitcoinMainnet(_) => ChainNet::BitcoinMainnet, - XChainNet::BitcoinTestnet(_) => ChainNet::BitcoinTestnet, + XChainNet::BitcoinTestnet3(_) => ChainNet::BitcoinTestnet3, + XChainNet::BitcoinTestnet4(_) => ChainNet::BitcoinTestnet4, XChainNet::BitcoinSignet(_) => ChainNet::BitcoinSignet, XChainNet::BitcoinRegtest(_) => ChainNet::BitcoinRegtest, XChainNet::LiquidMainnet(_) => ChainNet::LiquidMainnet, @@ -175,7 +128,8 @@ impl XChainNet { pub fn into_inner(self) -> T { match self { XChainNet::BitcoinMainnet(inner) - | XChainNet::BitcoinTestnet(inner) + | XChainNet::BitcoinTestnet3(inner) + | XChainNet::BitcoinTestnet4(inner) | XChainNet::BitcoinSignet(inner) | XChainNet::BitcoinRegtest(inner) | XChainNet::LiquidMainnet(inner) @@ -184,15 +138,23 @@ impl XChainNet { } pub fn layer1(&self) -> Layer1 { self.chain_network().layer1() } - pub fn address_network(&self) -> AddressNetwork { self.chain_network().address_network() } - pub fn is_prod(&self) -> bool { self.chain_network().is_prod() } + + pub fn address_network(&self) -> AddressNetwork { + match self.chain_network() { + ChainNet::BitcoinMainnet => AddressNetwork::Mainnet, + ChainNet::BitcoinTestnet3 | ChainNet::BitcoinTestnet4 | ChainNet::BitcoinSignet => { + AddressNetwork::Testnet + } + ChainNet::BitcoinRegtest => AddressNetwork::Regtest, + ChainNet::LiquidMainnet => AddressNetwork::Mainnet, + ChainNet::LiquidTestnet => AddressNetwork::Testnet, + } + } } #[derive(Copy, Clone, Eq, PartialEq, Debug, Display, Error)] #[display(doc_comments)] pub enum Pay2VoutError { - /// invalid close method byte {0:#04x}. - InvalidMethod(u8), /// unexpected address type byte {0:#04x}. InvalidAddressType(u8), /// invalid taproot output key; specifically {0}. @@ -200,9 +162,16 @@ pub enum Pay2VoutError { } #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, From)] -pub struct Pay2Vout { - pub method: CloseMethod, - pub address: AddressPayload, +pub struct Pay2Vout(AddressPayload); + +impl Pay2Vout { + pub fn new(address_payload: AddressPayload) -> Self { Pay2Vout(address_payload) } +} + +impl Deref for Pay2Vout { + type Target = AddressPayload; + + fn deref(&self) -> &'_ Self::Target { &self.0 } } impl Pay2Vout { @@ -213,24 +182,22 @@ impl Pay2Vout { pub(crate) const P2TR: u8 = 5; } -impl TryFrom<[u8; 34]> for Pay2Vout { +impl TryFrom<[u8; 33]> for Pay2Vout { type Error = Pay2VoutError; - fn try_from(data: [u8; 34]) -> Result { - let method = - CloseMethod::try_from(data[0]).map_err(|e| Pay2VoutError::InvalidMethod(e.1))?; - let address = match data[1] { - Self::P2PKH => AddressPayload::Pkh(PubkeyHash::from_slice_unsafe(&data[2..22])), - Self::P2SH => AddressPayload::Sh(ScriptHash::from_slice_unsafe(&data[2..22])), - Self::P2WPKH => AddressPayload::Wpkh(WPubkeyHash::from_slice_unsafe(&data[2..22])), - Self::P2WSH => AddressPayload::Wsh(WScriptHash::from_slice_unsafe(&data[2..])), + fn try_from(data: [u8; 33]) -> Result { + let address = match data[0] { + Self::P2PKH => AddressPayload::Pkh(PubkeyHash::from_slice_unsafe(&data[1..21])), + Self::P2SH => AddressPayload::Sh(ScriptHash::from_slice_unsafe(&data[1..21])), + Self::P2WPKH => AddressPayload::Wpkh(WPubkeyHash::from_slice_unsafe(&data[1..21])), + Self::P2WSH => AddressPayload::Wsh(WScriptHash::from_slice_unsafe(&data[1..])), Self::P2TR => AddressPayload::Tr( - OutputPk::from_byte_array(Bytes32::from_slice_unsafe(&data[2..34]).to_byte_array()) + OutputPk::from_byte_array(Bytes32::from_slice_unsafe(&data[1..33]).to_byte_array()) .map_err(Pay2VoutError::InvalidTapkey)?, ), wrong => return Err(Pay2VoutError::InvalidAddressType(wrong)), }; - Ok(Self { method, address }) + Ok(Pay2Vout(address)) } } @@ -261,5 +228,4 @@ impl RgbInvoice { pub fn chain_network(&self) -> ChainNet { self.beneficiary.chain_network() } pub fn address_network(&self) -> AddressNetwork { self.beneficiary.address_network() } pub fn layer1(&self) -> Layer1 { self.beneficiary.layer1() } - pub fn is_prod(&self) -> bool { self.beneficiary.is_prod() } } diff --git a/invoice/src/lib.rs b/invoice/src/lib.rs index a798caeb..7c8132bf 100644 --- a/invoice/src/lib.rs +++ b/invoice/src/lib.rs @@ -43,8 +43,7 @@ pub use data::{Allocation, NonFungible, OwnedFraction, TokenIndex}; pub use parse::{InvoiceParseError, TransportParseError}; pub use crate::invoice::{ - Beneficiary, ChainNet, InvoiceState, Pay2Vout, Pay2VoutError, RgbInvoice, RgbTransport, - XChainNet, + Beneficiary, InvoiceState, Pay2Vout, Pay2VoutError, RgbInvoice, RgbTransport, XChainNet, }; pub const LIB_NAME_RGB_CONTRACT: &str = "RGBContract"; diff --git a/invoice/src/parse.rs b/invoice/src/parse.rs index 08e4a37e..c9cb19c0 100644 --- a/invoice/src/parse.rs +++ b/invoice/src/parse.rs @@ -30,12 +30,10 @@ use fluent_uri::Uri; use indexmap::IndexMap; use invoice::{AddressPayload, UnknownNetwork}; use percent_encoding::{utf8_percent_encode, AsciiSet, CONTROLS}; -use rgb::{ContractId, SecretSeal}; +use rgb::{ChainNet, ContractId, SecretSeal}; use strict_encoding::{InvalidRString, TypeName}; -use crate::invoice::{ - Beneficiary, ChainNet, InvoiceState, Pay2Vout, RgbInvoice, RgbTransport, XChainNet, -}; +use crate::invoice::{Beneficiary, InvoiceState, Pay2Vout, RgbInvoice, RgbTransport, XChainNet}; const OMITTED: &str = "~"; const EXPIRY: &str = "expiry"; @@ -211,7 +209,7 @@ impl FromStr for RgbTransport { impl Display for XChainNet { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - write!(f, "{}:", self.chain_network())?; + write!(f, "{}:", self.chain_network().prefix())?; match self.into_inner() { Beneficiary::BlindedSeal(seal) => Display::fmt(&seal, f), Beneficiary::WitnessVout(payload) => payload.fmt_baid64(f), @@ -219,35 +217,18 @@ impl Display for XChainNet { } } -impl FromStr for ChainNet { - type Err = InvoiceParseError; - - fn from_str(s: &str) -> Result { - match s.to_lowercase() { - x if ChainNet::BitcoinMainnet.to_string() == x => Ok(ChainNet::BitcoinMainnet), - x if ChainNet::BitcoinTestnet.to_string() == x => Ok(ChainNet::BitcoinTestnet), - x if ChainNet::BitcoinSignet.to_string() == x => Ok(ChainNet::BitcoinSignet), - x if ChainNet::BitcoinRegtest.to_string() == x => Ok(ChainNet::BitcoinRegtest), - x if ChainNet::LiquidMainnet.to_string() == x => Ok(ChainNet::BitcoinMainnet), - x if ChainNet::LiquidTestnet.to_string() == x => Ok(ChainNet::LiquidTestnet), - _ => Err(InvoiceParseError::Beneficiary(s.to_owned())), - } - } -} - -impl DisplayBaid64<34> for Pay2Vout { +impl DisplayBaid64<33> for Pay2Vout { const HRI: &'static str = "wvout"; const CHUNKING: bool = true; const PREFIX: bool = true; const EMBED_CHECKSUM: bool = true; const MNEMONIC: bool = false; - fn to_baid64_payload(&self) -> [u8; 34] { - let mut payload = [0u8; 34]; + fn to_baid64_payload(&self) -> [u8; 33] { + let mut payload = [0u8; 33]; // tmp stack array to store the tr payload to resolve lifetime issue let schnorr_pk: [u8; 32]; - payload[0] = self.method as u8; - let (addr_type, spk) = match &self.address { + let (addr_type, spk) = match &**self { AddressPayload::Pkh(pkh) => (Self::P2PKH, pkh.as_ref()), AddressPayload::Sh(sh) => (Self::P2SH, sh.as_ref()), AddressPayload::Wpkh(wpkh) => (Self::P2WPKH, wpkh.as_ref()), @@ -257,8 +238,8 @@ impl DisplayBaid64<34> for Pay2Vout { (Self::P2TR, &schnorr_pk[..]) } }; - payload[1] = addr_type; - Cursor::new(&mut payload[2..]) + payload[0] = addr_type; + Cursor::new(&mut payload[1..]) .write_all(spk) .expect("address payload always less than 32 bytes"); payload @@ -268,7 +249,7 @@ impl DisplayBaid64<34> for Pay2Vout { impl Display for Pay2Vout { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { self.fmt_baid64(f) } } -impl FromBaid64Str<34> for Pay2Vout {} +impl FromBaid64Str<33> for Pay2Vout {} impl FromStr for Pay2Vout { type Err = Baid64ParseError; fn from_str(s: &str) -> Result { Self::from_baid64_str(s) } @@ -281,7 +262,8 @@ impl FromStr for XChainNet { let Some((cn, beneficiary)) = s.split_once(':') else { return Err(InvoiceParseError::Beneficiary(s.to_owned())); }; - let cn = ChainNet::from_str(cn)?; + let cn = + ChainNet::from_str(cn).map_err(|_| InvoiceParseError::Beneficiary(s.to_owned()))?; if let Ok(seal) = SecretSeal::from_str(beneficiary) { return Ok(XChainNet::with(cn, Beneficiary::BlindedSeal(seal))); } @@ -743,41 +725,26 @@ mod test { #[test] fn pay2vout_parse() { - let p = Pay2Vout { - method: bp::dbc::Method::OpretFirst, - address: AddressPayload::Pkh([0xff; 20].into()), - }; + let p = Pay2Vout::new(AddressPayload::Pkh([0xff; 20].into())); assert_eq!(Pay2Vout::from_str(&p.to_string()).unwrap(), p); - let p = Pay2Vout { - method: bp::dbc::Method::OpretFirst, - address: AddressPayload::Sh([0xff; 20].into()), - }; + let p = Pay2Vout::new(AddressPayload::Sh([0xff; 20].into())); assert_eq!(Pay2Vout::from_str(&p.to_string()).unwrap(), p); - let p = Pay2Vout { - method: bp::dbc::Method::OpretFirst, - address: AddressPayload::Wpkh([0xff; 20].into()), - }; + let p = Pay2Vout::new(AddressPayload::Wpkh([0xff; 20].into())); assert_eq!(Pay2Vout::from_str(&p.to_string()).unwrap(), p); - let p = Pay2Vout { - method: bp::dbc::Method::OpretFirst, - address: AddressPayload::Wsh([0xff; 32].into()), - }; + let p = Pay2Vout::new(AddressPayload::Wsh([0xff; 32].into())); assert_eq!(Pay2Vout::from_str(&p.to_string()).unwrap(), p); - let p = Pay2Vout { - method: bp::dbc::Method::OpretFirst, - address: AddressPayload::Tr( - bp::OutputPk::from_byte_array([ - 0x85, 0xa6, 0x42, 0x59, 0x8b, 0xfe, 0x2e, 0x42, 0xa3, 0x78, 0xcb, 0xb5, 0x3b, - 0xf1, 0x4a, 0xbe, 0x77, 0xf8, 0x1a, 0xef, 0xed, 0xf7, 0x3b, 0x66, 0x7b, 0x42, - 0x85, 0xaf, 0x7c, 0xf1, 0xc8, 0xa3, - ]) - .unwrap(), - ), - }; + let p = Pay2Vout::new(AddressPayload::Tr( + bp::OutputPk::from_byte_array([ + 0x85, 0xa6, 0x42, 0x59, 0x8b, 0xfe, 0x2e, 0x42, 0xa3, 0x78, 0xcb, 0xb5, 0x3b, 0xf1, + 0x4a, 0xbe, 0x77, 0xf8, 0x1a, 0xef, 0xed, 0xf7, 0x3b, 0x66, 0x7b, 0x42, 0x85, 0xaf, + 0x7c, 0xf1, 0xc8, 0xa3, + ]) + .unwrap(), + )); assert_eq!(Pay2Vout::from_str(&p.to_string()).unwrap(), p); } } diff --git a/src/containers/anchors.rs b/src/containers/anchors.rs index 2c7c1671..f2e9a458 100644 --- a/src/containers/anchors.rs +++ b/src/containers/anchors.rs @@ -20,7 +20,6 @@ // limitations under the License. use std::cmp::Ordering; -use std::vec; use amplify::ByteArray; use bp::dbc::opret::OpretProof; @@ -29,13 +28,9 @@ use bp::dbc::{anchor, Anchor}; use bp::{dbc, Tx, Txid}; use commit_verify::mpc; use rgb::validation::{DbcProof, EAnchor}; -use rgb::{ - BundleId, DiscloseHash, OpId, Operation, Transition, TransitionBundle, XChain, XGraphSeal, - XWitnessId, -}; +use rgb::{BundleId, DiscloseHash, GraphSeal, OpId, Operation, Transition, TransitionBundle}; use strict_encoding::StrictDumb; -use crate::containers::Dichotomy; use crate::{MergeReveal, MergeRevealError, TypedAssignsExt, LIB_NAME_RGB_STD}; #[derive(Clone, Eq, PartialEq, Debug, Display, Error)] @@ -46,9 +41,9 @@ pub struct UnrelatedTransition(OpId, Transition); #[display(doc_comments)] pub enum AnchoredBundleMismatch { /// witness bundle for witness id {0} already has both opret and tapret information. - AlreadyDouble(XWitnessId), + AlreadyDouble(Txid), /// the combined anchored bundles for witness id {0} are of the same type. - SameBundleType(XWitnessId), + SameBundleType(Txid), } #[derive(Clone, Eq, PartialEq, Debug)] @@ -60,47 +55,32 @@ pub enum AnchoredBundleMismatch { serde(crate = "serde_crate", rename_all = "camelCase") )] pub struct SealWitness { - pub public: XPubWitness, - pub anchors: AnchorSet, + pub public: PubWitness, + pub anchor: AnchorSet, } impl SealWitness { - pub fn new(witness: XPubWitness, anchors: AnchorSet) -> Self { + pub fn new(witness: PubWitness, anchor: AnchorSet) -> Self { SealWitness { public: witness, - anchors, + anchor, } } - pub fn witness_id(&self) -> XWitnessId { self.public.to_witness_id() } + pub fn witness_id(&self) -> Txid { self.public.to_witness_id() } } -pub type XPubWitness = XChain; - pub trait ToWitnessId { - fn to_witness_id(&self) -> XWitnessId; + fn to_witness_id(&self) -> Txid; } -impl ToWitnessId for XPubWitness { - fn to_witness_id(&self) -> XWitnessId { self.map_ref(|w| w.txid()) } +impl ToWitnessId for PubWitness { + fn to_witness_id(&self) -> Txid { self.txid() } } -impl MergeReveal for XPubWitness { +impl MergeReveal for PubWitness { fn merge_reveal(self, other: Self) -> Result { - match (self, other) { - (XChain::Bitcoin(one), XChain::Bitcoin(two)) => { - one.merge_reveal(two).map(XChain::Bitcoin) - } - (XChain::Liquid(one), XChain::Liquid(two)) => one.merge_reveal(two).map(XChain::Liquid), - (XChain::Bitcoin(bitcoin), XChain::Liquid(liquid)) - | (XChain::Liquid(liquid), XChain::Bitcoin(bitcoin)) => { - Err(MergeRevealError::ChainMismatch { - bitcoin: bitcoin.txid(), - liquid: liquid.txid(), - }) - } - _ => unreachable!(), - } + self.merge_reveal(other) } } @@ -178,8 +158,8 @@ impl PubWitness { #[derive(CommitEncode)] #[commit_encode(strategy = strict, id = DiscloseHash)] pub struct WitnessBundle { - pub pub_witness: XPubWitness, - pub anchored_bundles: AnchoredBundles, + pub pub_witness: PubWitness, + pub anchored_bundle: AnchoredBundle, } impl PartialEq for WitnessBundle { @@ -196,53 +176,21 @@ impl PartialOrd for WitnessBundle { impl WitnessBundle { #[inline] - pub fn with(pub_witness: XPubWitness, anchored_bundle: ClientBundle) -> Self { + pub fn with(pub_witness: PubWitness, anchored_bundle: ClientBundle) -> Self { Self { pub_witness, - anchored_bundles: AnchoredBundles::from(anchored_bundle), - } - } - - pub fn into_double(mut self, other: ClientBundle) -> Result { - match (self.anchored_bundles, other.dbc_proof) { - (AnchoredBundles::Double { .. }, _) => { - return Err(AnchoredBundleMismatch::AlreadyDouble( - self.pub_witness.to_witness_id(), - )); - } - (AnchoredBundles::Opret(opret), DbcProof::Tapret(tapret)) => { - self.anchored_bundles = AnchoredBundles::Double { - tapret: ClientBundle::new(other.mpc_proof, tapret, other.bundle), - opret, - } - } - (AnchoredBundles::Tapret(tapret), DbcProof::Opret(opret)) => { - self.anchored_bundles = AnchoredBundles::Double { - opret: ClientBundle::new(other.mpc_proof, opret, other.bundle), - tapret, - } - } - _ => { - return Err(AnchoredBundleMismatch::SameBundleType( - self.pub_witness.to_witness_id(), - )); - } + anchored_bundle: AnchoredBundle::from(anchored_bundle), } - Ok(self) } - pub fn witness_id(&self) -> XWitnessId { self.pub_witness.to_witness_id() } + pub fn witness_id(&self) -> Txid { self.pub_witness.to_witness_id() } - pub fn reveal_seal(&mut self, bundle_id: BundleId, seal: XGraphSeal) -> bool { - let bundle = match &mut self.anchored_bundles { - AnchoredBundles::Tapret(tapret) | AnchoredBundles::Double { tapret, .. } - if tapret.bundle.bundle_id() == bundle_id => - { + pub fn reveal_seal(&mut self, bundle_id: BundleId, seal: GraphSeal) -> bool { + let bundle = match &mut self.anchored_bundle { + AnchoredBundle::Tapret(tapret) if tapret.bundle.bundle_id() == bundle_id => { Some(&mut tapret.bundle) } - AnchoredBundles::Opret(opret) | AnchoredBundles::Double { opret, .. } - if opret.bundle.bundle_id() == bundle_id => - { + AnchoredBundle::Opret(opret) if opret.bundle.bundle_id() == bundle_id => { Some(&mut opret.bundle) } _ => None, @@ -259,15 +207,13 @@ impl WitnessBundle { true } - pub fn anchored_bundles(&self) -> impl Iterator { - self.anchored_bundles.iter() - } + pub fn anchored_bundle(&self) -> &AnchoredBundle { &self.anchored_bundle } + + pub fn bundle(&self) -> &TransitionBundle { self.anchored_bundle.bundle() } #[inline] pub fn known_transitions(&self) -> impl Iterator { - self.anchored_bundles - .bundles() - .flat_map(|bundle| bundle.known_transitions.values()) + self.anchored_bundle.bundle().known_transitions.values() } } @@ -293,7 +239,6 @@ impl ClientBundle { /// /// Panics if DBC proof and bundle have different closing methods pub fn new(mpc_proof: mpc::MerkleProof, dbc_proof: D, bundle: TransitionBundle) -> Self { - assert_eq!(dbc_proof.method(), bundle.close_method); Self { mpc_proof, dbc_proof, @@ -331,23 +276,18 @@ impl ClientBundle { derive(Serialize, Deserialize), serde(crate = "serde_crate", rename_all = "camelCase") )] -pub enum AnchoredBundles { +pub enum AnchoredBundle { #[strict_type(tag = 0x01)] Tapret(ClientBundle), #[strict_type(tag = 0x02)] Opret(ClientBundle), - #[strict_type(tag = 0x03)] - Double { - tapret: ClientBundle, - opret: ClientBundle, - }, } -impl StrictDumb for AnchoredBundles { +impl StrictDumb for AnchoredBundle { fn strict_dumb() -> Self { Self::Opret(strict_dumb!()) } } -impl From for AnchoredBundles { +impl From for AnchoredBundle { fn from(ab: ClientBundle) -> Self { match ab.dbc_proof { DbcProof::Opret(proof) => { @@ -360,72 +300,30 @@ impl From for AnchoredBundles { } } -impl AnchoredBundles { - pub fn bundles(&self) -> impl Iterator { +impl AnchoredBundle { + pub fn bundle(&self) -> &TransitionBundle { match self { - AnchoredBundles::Tapret(tapret) => Dichotomy::single(&tapret.bundle), - AnchoredBundles::Opret(opret) => Dichotomy::single(&opret.bundle), - AnchoredBundles::Double { tapret, opret } => { - Dichotomy::double(&tapret.bundle, &opret.bundle) - } + AnchoredBundle::Tapret(tapret) => &tapret.bundle, + AnchoredBundle::Opret(opret) => &opret.bundle, } - .into_iter() } - pub fn into_bundles(self) -> impl Iterator { + pub fn into_bundle(self) -> TransitionBundle { match self { - AnchoredBundles::Tapret(tapret) => Dichotomy::single(tapret.bundle), - AnchoredBundles::Opret(opret) => Dichotomy::single(opret.bundle), - AnchoredBundles::Double { tapret, opret } => { - Dichotomy::double(tapret.bundle, opret.bundle) - } + AnchoredBundle::Tapret(tapret) => tapret.bundle, + AnchoredBundle::Opret(opret) => opret.bundle, } - .into_iter() } - pub fn iter(&self) -> impl Iterator { + pub fn eanchor(&self) -> EAnchor { match self { - AnchoredBundles::Tapret(tapret) => { - let anchor = - EAnchor::new(tapret.mpc_proof.clone(), tapret.dbc_proof.clone().into()); - Dichotomy::single((anchor, &tapret.bundle)) + AnchoredBundle::Tapret(tapret) => { + EAnchor::new(tapret.mpc_proof.clone(), tapret.dbc_proof.clone().into()) } - AnchoredBundles::Opret(opret) => { - let anchor = EAnchor::new(opret.mpc_proof.clone(), opret.dbc_proof.into()); - Dichotomy::single((anchor, &opret.bundle)) - } - AnchoredBundles::Double { tapret, opret } => { - let tapret_anchor = - EAnchor::new(tapret.mpc_proof.clone(), tapret.dbc_proof.clone().into()); - let opret_anchor = EAnchor::new(opret.mpc_proof.clone(), opret.dbc_proof.into()); - Dichotomy::double((tapret_anchor, &tapret.bundle), (opret_anchor, &opret.bundle)) + AnchoredBundle::Opret(opret) => { + EAnchor::new(opret.mpc_proof.clone(), opret.dbc_proof.into()) } } - .into_iter() - } -} - -impl IntoIterator for AnchoredBundles { - type Item = (EAnchor, TransitionBundle); - type IntoIter = vec::IntoIter<(EAnchor, TransitionBundle)>; - - fn into_iter(self) -> Self::IntoIter { - match self { - AnchoredBundles::Tapret(tapret) => { - let anchor = EAnchor::new(tapret.mpc_proof, tapret.dbc_proof.into()); - Dichotomy::single((anchor, tapret.bundle)) - } - AnchoredBundles::Opret(opret) => { - let anchor = EAnchor::new(opret.mpc_proof, opret.dbc_proof.into()); - Dichotomy::single((anchor, opret.bundle)) - } - AnchoredBundles::Double { tapret, opret } => { - let tapret_anchor = EAnchor::new(tapret.mpc_proof, tapret.dbc_proof.into()); - let opret_anchor = EAnchor::new(opret.mpc_proof, opret.dbc_proof.into()); - Dichotomy::double((tapret_anchor, tapret.bundle), (opret_anchor, opret.bundle)) - } - } - .into_iter() } } @@ -442,11 +340,6 @@ pub enum AnchorSet { Tapret(Anchor), #[strict_type(tag = 0x02)] Opret(Anchor), - #[strict_type(tag = 0x03)] - Double { - tapret: Anchor, - opret: Anchor, - }, } impl StrictDumb for AnchorSet { @@ -458,48 +351,16 @@ impl AnchorSet { let map = match self { AnchorSet::Tapret(tapret) => tapret.mpc_proof.to_known_message_map().release(), AnchorSet::Opret(opret) => opret.mpc_proof.to_known_message_map().release(), - AnchorSet::Double { tapret, opret } => { - let mut map = tapret.mpc_proof.to_known_message_map().release(); - map.extend(opret.mpc_proof.to_known_message_map().release()); - map - } }; map.into_values() .map(|msg| BundleId::from_byte_array(msg.to_byte_array())) } - pub fn has_tapret(&self) -> bool { matches!(self, Self::Tapret(_) | Self::Double { .. }) } - - pub fn has_opret(&self) -> bool { matches!(self, Self::Opret(_) | Self::Double { .. }) } - pub fn merge_reveal(self, other: Self) -> Result { match (self, other) { (Self::Tapret(anchor), Self::Tapret(a)) => Ok(Self::Tapret(anchor.merge_reveal(a)?)), (Self::Opret(anchor), Self::Opret(a)) => Ok(Self::Opret(anchor.merge_reveal(a)?)), - (Self::Tapret(tapret), Self::Opret(opret)) - | (Self::Opret(opret), Self::Tapret(tapret)) => Ok(Self::Double { tapret, opret }), - - (Self::Double { tapret, opret }, Self::Tapret(t)) - | (Self::Tapret(t), Self::Double { tapret, opret }) => Ok(Self::Double { - tapret: tapret.merge_reveal(t)?, - opret, - }), - - (Self::Double { tapret, opret }, Self::Opret(o)) - | (Self::Opret(o), Self::Double { tapret, opret }) => Ok(Self::Double { - tapret, - opret: opret.merge_reveal(o)?, - }), - ( - Self::Double { tapret, opret }, - Self::Double { - tapret: t, - opret: o, - }, - ) => Ok(Self::Double { - tapret: tapret.merge_reveal(t)?, - opret: opret.merge_reveal(o)?, - }), + _ => Err(anchor::MergeError::DbcMismatch), } } } diff --git a/src/containers/consignment.rs b/src/containers/consignment.rs index d1e85fcd..f8a7b629 100644 --- a/src/containers/consignment.rs +++ b/src/containers/consignment.rs @@ -35,8 +35,8 @@ use baid64::{Baid64ParseError, DisplayBaid64, FromBaid64Str}; use commit_verify::{CommitEncode, CommitEngine, CommitId, CommitmentId, DigestExt, Sha256}; use rgb::validation::{ResolveWitness, Validator, Validity, Warning, CONSIGNMENT_MAX_LIBS}; use rgb::{ - impl_serde_baid64, validation, AttachId, BundleId, ContractId, Extension, Genesis, GraphSeal, - Operation, Schema, SchemaId, XChain, + impl_serde_baid64, validation, AttachId, BundleId, ChainNet, ContractId, Extension, Genesis, + GraphSeal, Operation, Schema, SchemaId, }; use rgbcore::validation::ConsignmentApi; use strict_encoding::{StrictDeserialize, StrictDumb, StrictSerialize}; @@ -185,7 +185,7 @@ pub struct Consignment { pub transfer: bool, /// Set of secret seals which are history terminals. - pub terminals: SmallOrdMap>, + pub terminals: SmallOrdMap, /// Genesis data. pub genesis: Genesis, @@ -288,7 +288,7 @@ impl Consignment { pub fn reveal_terminal_seals( mut self, - f: impl Fn(XChain) -> Result>, E>, + f: impl Fn(SecretSeal) -> Result, E>, ) -> Result { // We need to clone since ordered set does not allow us to mutate members. let mut bundles = LargeOrdSet::with_capacity(self.bundles.len()); @@ -327,13 +327,13 @@ impl Consignment { resolver: &impl ResolveWitness, // TODO: Add sig validator //_: &impl SigValidator, - testnet: bool, + chain_net: ChainNet, ) -> Result, (validation::Status, Consignment)> { let index = IndexedConsignment::new(&self); let mut status = Validator::, _, _>::validate( &index, &resolver, - testnet, + chain_net, (&self.schema, self.contract_id()), ); diff --git a/src/containers/file.rs b/src/containers/file.rs index 4cd722c0..925379ac 100644 --- a/src/containers/file.rs +++ b/src/containers/file.rs @@ -271,9 +271,7 @@ mod test { flags: Default::default(), timestamp: Default::default(), issuer: Default::default(), - testnet: Default::default(), - alt_layers1: Default::default(), - asset_tags: Default::default(), + chain_net: Default::default(), metadata: Default::default(), globals: Default::default(), assignments: Default::default(), @@ -369,9 +367,7 @@ mod test { flags: Default::default(), timestamp: Default::default(), issuer: Default::default(), - testnet: Default::default(), - alt_layers1: Default::default(), - asset_tags: Default::default(), + chain_net: Default::default(), metadata: Default::default(), globals: Default::default(), assignments: Default::default(), diff --git a/src/containers/indexed.rs b/src/containers/indexed.rs index f4b0f8cf..bc41181b 100644 --- a/src/containers/indexed.rs +++ b/src/containers/indexed.rs @@ -24,11 +24,11 @@ use std::ops::Deref; use rgb::validation::{ConsignmentApi, EAnchor, OpRef, Scripts}; use rgb::{ - BundleId, Extension, Genesis, OpId, Operation, Schema, Transition, TransitionBundle, XWitnessId, + BundleId, Extension, Genesis, OpId, Operation, Schema, Transition, TransitionBundle, Txid, }; use strict_types::TypeSystem; -use super::{Consignment, XPubWitness}; +use super::{Consignment, PubWitness}; use crate::containers::anchors::ToWitnessId; // TODO: Transform consignment into this type instead of composing over it @@ -36,12 +36,12 @@ use crate::containers::anchors::ToWitnessId; pub struct IndexedConsignment<'c, const TRANSFER: bool> { consignment: &'c Consignment, scripts: Scripts, - anchor_idx: BTreeMap, + anchor_idx: BTreeMap, bundle_idx: BTreeMap, - op_witness_idx: BTreeMap, + op_witness_idx: BTreeMap, op_bundle_idx: BTreeMap, extension_idx: BTreeMap, - witness_idx: BTreeMap, + witness_idx: BTreeMap, } impl Deref for IndexedConsignment<'_, TRANSFER> { @@ -62,14 +62,15 @@ impl<'c, const TRANSFER: bool> IndexedConsignment<'c, TRANSFER> { witness_idx .insert(witness_bundle.pub_witness.to_witness_id(), &witness_bundle.pub_witness); let witness_id = witness_bundle.pub_witness.to_witness_id(); - for (anchor, bundle) in witness_bundle.anchored_bundles() { - let bundle_id = bundle.bundle_id(); - bundle_idx.insert(bundle_id, bundle); - anchor_idx.insert(bundle_id, (witness_id, anchor)); - for opid in bundle.known_transitions.keys() { - op_witness_idx.insert(*opid, witness_id); - op_bundle_idx.insert(*opid, bundle_id); - } + let anchored_bundle = witness_bundle.anchored_bundle(); + let anchor = anchored_bundle.eanchor(); + let bundle = anchored_bundle.bundle(); + let bundle_id = bundle.bundle_id(); + bundle_idx.insert(bundle_id, bundle); + anchor_idx.insert(bundle_id, (witness_id, anchor)); + for opid in bundle.known_transitions.keys() { + op_witness_idx.insert(*opid, witness_id); + op_bundle_idx.insert(*opid, bundle_id); } } for extension in &consignment.extensions { @@ -102,12 +103,12 @@ impl<'c, const TRANSFER: bool> IndexedConsignment<'c, TRANSFER> { .and_then(|bundle| bundle.known_transitions.get(&opid)) } - pub fn pub_witness(&self, id: XWitnessId) -> Option<&XPubWitness> { + pub fn pub_witness(&self, id: Txid) -> Option<&PubWitness> { self.witness_idx.get(&id).copied() } } -impl<'c, const TRANSFER: bool> ConsignmentApi for IndexedConsignment<'c, TRANSFER> { +impl ConsignmentApi for IndexedConsignment<'_, TRANSFER> { fn schema(&self) -> &Schema { &self.schema } fn types(&self) -> &TypeSystem { &self.types } @@ -137,11 +138,9 @@ impl<'c, const TRANSFER: bool> ConsignmentApi for IndexedConsignment<'c, TRANSFE self.bundle_idx.get(&bundle_id).copied() } - fn anchor(&self, bundle_id: BundleId) -> Option<(XWitnessId, &EAnchor)> { + fn anchor(&self, bundle_id: BundleId) -> Option<(Txid, &EAnchor)> { self.anchor_idx.get(&bundle_id).map(|(id, set)| (*id, set)) } - fn op_witness_id(&self, opid: OpId) -> Option { - self.op_witness_idx.get(&opid).copied() - } + fn op_witness_id(&self, opid: OpId) -> Option { self.op_witness_idx.get(&opid).copied() } } diff --git a/src/containers/mod.rs b/src/containers/mod.rs index 76ed6377..edb19938 100644 --- a/src/containers/mod.rs +++ b/src/containers/mod.rs @@ -39,8 +39,8 @@ mod kit; mod suppl; pub use anchors::{ - AnchorSet, AnchoredBundleMismatch, AnchoredBundles, ClientBundle, PubWitness, SealWitness, - ToWitnessId, UnrelatedTransition, WitnessBundle, XPubWitness, + AnchorSet, AnchoredBundle, AnchoredBundleMismatch, ClientBundle, PubWitness, SealWitness, + ToWitnessId, UnrelatedTransition, WitnessBundle, }; pub use consignment::{ Consignment, ConsignmentExt, ConsignmentId, ConsignmentParseError, Contract, Transfer, @@ -50,10 +50,7 @@ pub use disclosure::Disclosure; pub use file::{FileContent, LoadError, UniversalFile}; pub use indexed::IndexedConsignment; pub use kit::{Kit, KitId, ValidKit}; -pub use partials::{ - Batch, BundleDichotomy, CloseMethodSet, Dichotomy, Fascia, TransitionDichotomy, TransitionInfo, - TransitionInfoError, -}; +pub use partials::{Batch, Fascia, TransitionInfo, TransitionInfoError}; pub use seal::{BuilderSeal, VoutSeal}; pub use suppl::{ AnnotationName, Annotations, ContentRef, SupplId, SupplItem, SupplMap, SupplSub, Supplement, diff --git a/src/containers/partials.rs b/src/containers/partials.rs index 8bdf33d2..eb1b7261 100644 --- a/src/containers/partials.rs +++ b/src/containers/partials.rs @@ -22,104 +22,17 @@ use std::cmp::Ordering; use std::collections::BTreeSet; use std::hash::{Hash, Hasher}; -use std::ops::{BitOr, BitOrAssign}; -use std::{iter, vec}; use amplify::confinement::{Confined, NonEmptyOrdMap, U24}; -use bp::seals::txout::CloseMethod; -use rgb::{ - ContractId, OpId, Operation, Transition, TransitionBundle, TxoSeal, XOutpoint, XOutputSeal, - XWitnessId, -}; +use bp::Outpoint; +use rgb::{ContractId, OpId, Operation, OutputSeal, Transition, TransitionBundle, Txid}; use strict_encoding::{ - DecodeError, ReadStruct, StrictDecode, StrictDeserialize, StrictDumb, StrictEncode, - StrictProduct, StrictSerialize, StrictStruct, StrictType, TypedRead, TypedWrite, WriteStruct, + StrictDecode, StrictDeserialize, StrictDumb, StrictEncode, StrictSerialize, StrictType, }; -use crate::containers::{AnchorSet, XPubWitness}; +use crate::containers::{AnchorSet, PubWitness}; use crate::LIB_NAME_RGB_STD; -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] -#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB_STD, 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 CloseMethodSet { - #[strict_type(dumb)] - TapretFirst = 0x01, - OpretFirst = 0x02, - Both = 0x03, -} - -impl BitOr> for CloseMethodSet { - type Output = Self; - fn bitor(mut self, rhs: Option) -> Self::Output { - if let Some(m) = rhs { - self |= m - }; - self - } -} - -impl BitOrAssign> for CloseMethodSet { - fn bitor_assign(&mut self, rhs: Option) { - if let Some(m) = rhs { - *self |= m - }; - } -} - -impl BitOr for Option { - type Output = CloseMethodSet; - fn bitor(self, mut rhs: CloseMethodSet) -> Self::Output { - if let Some(m) = self { - rhs |= m - }; - rhs - } -} - -impl BitOrAssign for Option { - fn bitor_assign(&mut self, rhs: CloseMethodSet) { *self = Some(rhs | *self) } -} - -impl> BitOr for CloseMethodSet { - type Output = Self; - fn bitor(self, rhs: T) -> Self::Output { - if self == rhs.into() { - self - } else { - Self::Both - } - } -} - -impl> BitOrAssign for CloseMethodSet { - fn bitor_assign(&mut self, rhs: T) { *self = self.bitor(rhs.into()); } -} - -impl From for CloseMethodSet { - fn from(seal: XOutputSeal) -> Self { seal.method().into() } -} - -impl From for CloseMethodSet { - fn from(method: CloseMethod) -> Self { - match method { - CloseMethod::OpretFirst => CloseMethodSet::OpretFirst, - CloseMethod::TapretFirst => CloseMethodSet::TapretFirst, - } - } -} - -impl CloseMethodSet { - pub fn has_tapret_first(self) -> bool { matches!(self, Self::TapretFirst | Self::Both) } - pub fn has_opret_first(self) -> bool { matches!(self, Self::OpretFirst | Self::Both) } -} - #[derive(Clone, Eq, Debug)] #[derive(StrictType, StrictEncode, StrictDecode)] #[strict_type(lib = LIB_NAME_RGB_STD)] @@ -130,9 +43,8 @@ impl CloseMethodSet { )] pub struct TransitionInfo { pub id: OpId, - pub inputs: Confined, 1, U24>, + pub inputs: Confined, 1, U24>, pub transition: Transition, - pub method: CloseMethod, } impl StrictDumb for TransitionInfo { @@ -161,24 +73,19 @@ impl TransitionInfo { /// If the number of provided seals is zero. pub fn new( transition: Transition, - seals: impl AsRef<[XOutputSeal]>, + seals: impl AsRef<[OutputSeal]>, ) -> Result { let id = transition.id(); let seals = seals.as_ref(); assert!(!seals.is_empty(), "empty seals provided to transition info constructor"); let inputs = Confined::, 1, U24>::try_from_iter( - seals.iter().copied().map(XOutpoint::from), + seals.iter().copied().map(Outpoint::from), ) .map_err(|_| TransitionInfoError::TooMany(id))?; - let method = seals.first().expect("one item guaranteed").method(); - if seals.iter().any(|s| s.method() != method) { - return Err(TransitionInfoError::CloseMethodDivergence(id)); - } Ok(TransitionInfo { id, inputs, transition, - method, }) } } @@ -189,10 +96,6 @@ pub enum TransitionInfoError { /// the operation produces too many state transitions which can't fit the /// container requirements. TooMany(OpId), - - /// transition {0} contains inputs with different seal closing methods, - /// which is not allowed. - CloseMethodDivergence(OpId), } /// A batch of state transitions under different contracts which are associated @@ -207,8 +110,8 @@ pub enum TransitionInfoError { serde(crate = "serde_crate", rename_all = "camelCase") )] pub struct Batch { - pub main: TransitionDichotomy, - pub blanks: Confined, 0, { U24 - 1 }>, + pub main: TransitionInfo, + pub blanks: Confined, 0, { U24 - 1 }>, } impl StrictSerialize for Batch {} @@ -216,145 +119,21 @@ impl StrictDeserialize for Batch {} impl IntoIterator for Batch { type Item = TransitionInfo; - type IntoIter = iter::FlatMap< - vec::IntoIter>, - vec::IntoIter, - fn(Dichotomy) -> as IntoIterator>::IntoIter, - >; + type IntoIter = std::vec::IntoIter; fn into_iter(self) -> Self::IntoIter { let mut vec = self.blanks.release(); vec.push(self.main); - vec.into_iter().flat_map(TransitionDichotomy::into_iter) + vec.into_iter() } } impl Batch { - pub fn close_method_set(&self) -> CloseMethodSet { - let mut methods = CloseMethodSet::from(self.main.first.method); - if let Some(info) = &self.main.second { - methods |= info.method; - } - self.blanks.iter().for_each(|i| methods |= i.first.method); - self.blanks - .iter() - .filter_map(|i| i.second.as_ref()) - .for_each(|i| methods |= i.method); - methods - } - pub fn set_priority(&mut self, priority: u64) { - self.main.first.transition.nonce = priority; - if let Some(info) = &mut self.main.second { - info.transition.nonce = priority; - } + self.main.transition.nonce = priority; for info in &mut self.blanks { - info.first.transition.nonce = priority; - if let Some(info) = &mut info.second { - info.transition.nonce = priority; - } - } - } -} - -pub type BundleDichotomy = Dichotomy; -pub type TransitionDichotomy = Dichotomy; - -// TODO: Move to amplify -#[derive(Clone, PartialEq, Eq, Hash, Debug)] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", rename_all = "camelCase") -)] -pub struct Dichotomy { - pub first: T, - pub second: Option, -} - -impl StrictType for Dichotomy { - const STRICT_LIB_NAME: &'static str = LIB_NAME_RGB_STD; -} -impl StrictProduct for Dichotomy {} -impl StrictStruct for Dichotomy { - const ALL_FIELDS: &'static [&'static str] = &["first", "second"]; -} -impl StrictEncode for Dichotomy { - fn strict_encode(&self, writer: W) -> std::io::Result { - writer.write_struct::(|w| { - Ok(w.write_field(fname!("first"), &self.first)? - .write_field(fname!("second"), &self.second)? - .complete()) - }) - } -} -impl StrictDecode for Dichotomy { - fn strict_decode(reader: &mut impl TypedRead) -> Result { - reader.read_struct(|r| { - Ok(Self { - first: r.read_field(fname!("first"))?, - second: r.read_field(fname!("second"))?, - }) - }) - } -} -impl StrictDumb for Dichotomy { - fn strict_dumb() -> Self { - Self { - first: T::strict_dumb(), - second: None, - } - } -} - -impl FromIterator for Dichotomy { - fn from_iter>(iter: I) -> Self { - let mut iter = iter.into_iter(); - let first = iter.next().expect("iterator must have at least one item"); - let second = iter.next(); - assert!(iter.next().is_none(), "iterator must have at most two items"); - Self { first, second } - } -} - -impl IntoIterator for Dichotomy { - type Item = T; - type IntoIter = vec::IntoIter; - - fn into_iter(self) -> Self::IntoIter { - let mut vec = Vec::with_capacity(2); - vec.push(self.first); - if let Some(s) = self.second { - vec.push(s) - } - vec.into_iter() - } -} - -impl Dichotomy { - pub fn single(first: T) -> Self { - Self { - first, - second: None, - } - } - - pub fn double(first: T, second: T) -> Self { - Self { - first, - second: Some(second), - } - } - - pub fn with(first: T, second: Option) -> Self { Self { first, second } } - - pub fn iter(&self) -> vec::IntoIter<&T> { - let mut vec = Vec::with_capacity(2); - vec.push(&self.first); - if let Some(ref s) = self.second { - vec.push(s) + info.transition.nonce = priority; } - vec.into_iter() } } @@ -370,9 +149,9 @@ impl Dichotomy { serde(crate = "serde_crate", rename_all = "camelCase") )] pub struct Fascia { - pub witness: XPubWitness, + pub witness: PubWitness, pub anchor: AnchorSet, - pub bundles: NonEmptyOrdMap, + pub bundles: NonEmptyOrdMap, } impl StrictDumb for Fascia { @@ -388,11 +167,9 @@ impl StrictSerialize for Fascia {} impl StrictDeserialize for Fascia {} impl Fascia { - pub fn witness_id(&self) -> XWitnessId { self.witness.map_ref(|w| w.txid()) } + pub fn witness_id(&self) -> Txid { self.witness.txid() } pub fn into_bundles(self) -> impl IntoIterator { - self.bundles - .into_iter() - .flat_map(|(id, d)| d.into_iter().map(move |b| (id, b))) + self.bundles.into_iter() } } diff --git a/src/containers/seal.rs b/src/containers/seal.rs index 49dc3079..ea4e2bdf 100644 --- a/src/containers/seal.rs +++ b/src/containers/seal.rs @@ -24,7 +24,7 @@ use bp::seals::txout::{BlindSeal, CloseMethod, SealTxid}; use bp::secp256k1::rand::{thread_rng, RngCore}; use bp::Vout; -use rgb::{GraphSeal, Layer1, SecretSeal, TxoSeal, XChain}; +use rgb::{GraphSeal, SecretSeal, TxoSeal}; use crate::LIB_NAME_RGB_STD; @@ -102,28 +102,17 @@ impl VoutSeal { } impl From for GraphSeal { - fn from(seal: VoutSeal) -> Self { - Self::with_blinded_vout(seal.method, seal.vout, seal.blinding) - } + fn from(seal: VoutSeal) -> Self { Self::with_blinded_vout(seal.vout, seal.blinding) } } /// Seal used by operation builder which can be either revealed or concealed. #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, From)] pub enum BuilderSeal { - Revealed(XChain), + Revealed(Seal), #[from] - Concealed(XChain), -} - -impl From>> for BuilderSeal> { - fn from(seal: XChain>) -> Self { BuilderSeal::Revealed(seal) } + Concealed(SecretSeal), } -impl BuilderSeal { - pub fn layer1(&self) -> Layer1 { - match self { - BuilderSeal::Revealed(x) => x.layer1(), - BuilderSeal::Concealed(x) => x.layer1(), - } - } +impl From> for BuilderSeal> { + fn from(seal: BlindSeal) -> Self { BuilderSeal::Revealed(seal) } } diff --git a/src/contract/assignments.rs b/src/contract/assignments.rs index d4967520..b0577334 100644 --- a/src/contract/assignments.rs +++ b/src/contract/assignments.rs @@ -20,18 +20,17 @@ // limitations under the License. use std::cmp::Ordering; -use std::collections::HashMap; +use std::collections::{BTreeSet, HashMap}; use std::fmt::Debug; use std::hash::Hash; use amplify::confinement::SmallVec; -use commit_verify::Conceal; use invoice::Amount; use rgb::vm::WitnessOrd; use rgb::{ Assign, AssignAttach, AssignData, AssignFungible, AssignRights, AssignmentType, AttachState, - DataState, ExposedSeal, ExposedState, OpId, Opout, RevealedAttach, RevealedData, RevealedValue, - TypedAssigns, VoidState, XChain, XOutputSeal, XWitnessId, + BundleId, DataState, ExposedSeal, ExposedState, OpId, Opout, OutputSeal, RevealedAttach, + RevealedData, RevealedValue, Txid, TypedAssigns, VoidState, }; use strict_encoding::{StrictDecode, StrictDumb, StrictEncode}; @@ -78,7 +77,7 @@ impl KnownState for RevealedAttach { serde(crate = "serde_crate", rename_all = "camelCase") )] pub struct WitnessInfo { - pub id: XWitnessId, + pub id: Txid, pub ord: WitnessOrd, } @@ -93,9 +92,10 @@ pub struct WitnessInfo { )] pub struct OutputAssignment { pub opout: Opout, - pub seal: XOutputSeal, + pub seal: OutputSeal, pub state: State, - pub witness: Option, + pub witness: Option, + pub bundle_id: Option, } impl PartialEq for OutputAssignment { @@ -135,20 +135,19 @@ impl OutputAssignment { /// If the processing is done on invalid stash data, the seal is /// witness-based and the anchor chain doesn't match the seal chain. pub fn with_witness( - seal: XChain, - witness_id: XWitnessId, + seal: Seal, + witness_id: Txid, state: State, + bundle_id: Option, opid: OpId, ty: AssignmentType, no: u16, ) -> Self { OutputAssignment { opout: Opout::new(opid, ty, no), - seal: seal.try_to_output_seal(witness_id).expect( - "processing contract from unverified/invalid stash: witness seal chain doesn't \ - match anchor's chain", - ), + seal: seal.to_output_seal_or_default(witness_id), state, + bundle_id, witness: witness_id.into(), } } @@ -158,8 +157,9 @@ impl OutputAssignment { /// If the processing is done on invalid stash data, the seal is /// witness-based and the anchor chain doesn't match the seal chain. pub fn with_no_witness( - seal: XChain, + seal: Seal, state: State, + bundle_id: Option, opid: OpId, ty: AssignmentType, no: u16, @@ -171,6 +171,7 @@ impl OutputAssignment { information since it comes from genesis or extension", ), state, + bundle_id, witness: None, } } @@ -181,11 +182,12 @@ impl OutputAssignment { opout: self.opout, seal: self.seal, state: self.state.into(), + bundle_id: self.bundle_id, witness: self.witness, } } - pub fn check_witness(&self, filter: &HashMap) -> bool { + pub fn check_witness(&self, filter: &HashMap) -> bool { match self.witness { None => true, Some(witness_id) => { @@ -193,19 +195,26 @@ impl OutputAssignment { } } } + + pub fn check_bundle(&self, invalid_bundles: &BTreeSet) -> bool { + match self.bundle_id { + Some(bundle_id) => !invalid_bundles.contains(&bundle_id), + None => true, + } + } } pub trait TypedAssignsExt { - fn reveal_seal(&mut self, seal: XChain); + fn reveal_seal(&mut self, seal: Seal); - fn filter_revealed_seals(&self) -> Vec>; + fn filter_revealed_seals(&self) -> Vec; } impl TypedAssignsExt for TypedAssigns { - fn reveal_seal(&mut self, seal: XChain) { + fn reveal_seal(&mut self, seal: Seal) { fn reveal( vec: &mut SmallVec>, - revealed: XChain, + revealed: Seal, ) { for assign in vec.iter_mut() { match assign { @@ -218,13 +227,6 @@ impl TypedAssignsExt for TypedAssigns { lock: *lock, } } - Assign::Confidential { seal, state, lock } if *seal == revealed.conceal() => { - *assign = Assign::ConfidentialState { - seal: revealed, - state: *state, - lock: *lock, - } - } _ => {} } } @@ -238,7 +240,7 @@ impl TypedAssignsExt for TypedAssigns { } } - fn filter_revealed_seals(&self) -> Vec> { + fn filter_revealed_seals(&self) -> Vec { match self { TypedAssigns::Declarative(s) => { s.iter().filter_map(AssignRights::revealed_seal).collect() diff --git a/src/contract/merge_reveal.rs b/src/contract/merge_reveal.rs index b662f5a5..ecf0d3ca 100644 --- a/src/contract/merge_reveal.rs +++ b/src/contract/merge_reveal.rs @@ -99,50 +99,7 @@ impl MergeReveal for Assign Ok(state) } - // ConfidentialAmount + ConfidentialSeal = Revealed - ( - Assign::ConfidentialSeal { - state, lock: lock1, .. - }, - Assign::ConfidentialState { - seal, lock: lock2, .. - }, - ) => { - debug_assert_eq!(lock1, lock2); - Ok(Assign::Revealed { - seal, - state, - lock: lock1, - }) - } - - // ConfidentialSeal + ConfidentialAmount = Revealed - ( - Assign::ConfidentialState { - seal, lock: lock1, .. - }, - Assign::ConfidentialSeal { - state, lock: lock2, .. - }, - ) => { - debug_assert_eq!(lock1, lock2); - Ok(Assign::Revealed { - seal, - state, - lock: lock1, - }) - } - - // if self and other is of same variant return self - (state @ Assign::ConfidentialState { .. }, Assign::ConfidentialState { .. }) => { - Ok(state) - } (state @ Assign::ConfidentialSeal { .. }, Assign::ConfidentialSeal { .. }) => Ok(state), - - // Anything + Confidential = Anything - (state, Assign::Confidential { .. }) | (Assign::Confidential { .. }, state) => { - Ok(state) - } } } } diff --git a/src/contract/mod.rs b/src/contract/mod.rs index 624830ed..3e22d409 100644 --- a/src/contract/mod.rs +++ b/src/contract/mod.rs @@ -25,7 +25,7 @@ mod merge_reveal; pub use assignments::{KnownState, OutputAssignment, TypedAssignsExt, WitnessInfo}; pub use merge_reveal::{MergeReveal, MergeRevealError}; use rgb::vm::OrdOpRef; -use rgb::{ExtensionType, OpId, TransitionType, XWitnessId}; +use rgb::{ExtensionType, OpId, TransitionType, Txid}; use crate::LIB_NAME_RGB_STD; @@ -40,8 +40,8 @@ use crate::LIB_NAME_RGB_STD; pub enum OpWitness { #[strict_type(dumb)] Genesis, - Transition(XWitnessId, TransitionType), - Extension(XWitnessId, ExtensionType), + Transition(Txid, TransitionType), + Extension(Txid, ExtensionType), } impl From> for OpWitness { @@ -60,7 +60,7 @@ impl From> for OpWitness { impl OpWitness { #[inline] - pub fn witness_id(&self) -> Option { + pub fn witness_id(&self) -> Option { match self { OpWitness::Genesis => None, OpWitness::Transition(witness_id, _) | OpWitness::Extension(witness_id, _) => { @@ -87,5 +87,5 @@ pub struct GlobalOut { impl GlobalOut { #[inline] - pub fn witness_id(&self) -> Option { self.op_witness.witness_id() } + pub fn witness_id(&self) -> Option { self.op_witness.witness_id() } } diff --git a/src/info.rs b/src/info.rs index 261d890d..2c826714 100644 --- a/src/info.rs +++ b/src/info.rs @@ -20,12 +20,12 @@ // limitations under the License. use std::collections::HashMap; -use std::fmt::{self, Debug, Display, Formatter, Write}; +use std::fmt::{self, Debug, Display, Formatter}; use std::str::FromStr; use amplify::confinement::TinyOrdSet; use chrono::{DateTime, TimeZone, Utc}; -use rgb::{AltLayer1Set, ContractId, Genesis, Identity, Operation, SchemaId}; +use rgb::{ChainNet, ContractId, Genesis, Identity, Operation, SchemaId}; use strict_encoding::stl::{AlphaCapsLodash, AlphaNumLodash}; use strict_encoding::{FieldName, RString, StrictDeserialize, StrictSerialize, TypeName}; @@ -281,8 +281,7 @@ pub struct ContractInfo { pub schema_id: SchemaId, pub issuer: Identity, pub issued_at: DateTime, - pub testnet: bool, - pub alt_layers1: AltLayer1Set, + pub chain_net: ChainNet, } impl ContractInfo { @@ -295,8 +294,7 @@ impl ContractInfo { .timestamp_opt(genesis.timestamp, 0) .single() .unwrap_or_else(Utc::now), - testnet: genesis.testnet, - alt_layers1: genesis.alt_layers1.clone(), + chain_net: genesis.chain_net, } } } @@ -304,14 +302,7 @@ impl ContractInfo { impl Display for ContractInfo { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { write!(f, "{}", self.id)?; - write!( - f, - "\tbitcoin{: <12}", - self.alt_layers1.iter().fold(s!(""), |mut acc, layer| { - write!(acc, ", {layer}").ok(); - acc - }) - )?; + write!(f, "\t{}", self.chain_net)?; write!(f, "\t{}", self.issued_at.format("%Y-%m-%d"))?; writeln!(f, "\t{: <80}", self.schema_id.to_string())?; writeln!(f, " Developer: {}", self.issuer) diff --git a/src/interface/builder.rs b/src/interface/builder.rs index eb8a01c4..93c51f9f 100644 --- a/src/interface/builder.rs +++ b/src/interface/builder.rs @@ -29,11 +29,10 @@ use chrono::Utc; use invoice::{Allocation, Amount}; use rgb::validation::Scripts; use rgb::{ - validation, AltLayer1, AltLayer1Set, AssetTag, AssetTags, Assign, AssignmentType, Assignments, - AttachState, BlindingFactor, ContractId, DataState, ExposedSeal, FungibleType, Genesis, - GenesisSeal, GlobalState, GraphSeal, Identity, Input, Layer1, MetadataError, Opout, - OwnedStateSchema, RevealedAttach, RevealedData, RevealedValue, Schema, Transition, - TransitionType, TypedAssigns, XChain, XOutpoint, + validation, Assign, AssignmentType, Assignments, AttachState, ChainNet, ContractId, DataState, + ExposedSeal, FungibleType, Genesis, GenesisSeal, GlobalState, GraphSeal, Identity, Input, + Layer1, MetadataError, Opout, OwnedStateSchema, RevealedAttach, RevealedData, RevealedValue, + Schema, Transition, TransitionType, TypedAssigns, }; use rgbcore::{GlobalStateSchema, GlobalStateType, MetaType, Metadata, ValencyType}; use strict_encoding::{FieldName, SerializeError, StrictSerialize}; @@ -43,14 +42,10 @@ use crate::containers::{BuilderSeal, ContainerVer, Contract, ValidConsignment}; use crate::interface::resolver::DumbResolver; use crate::interface::{Iface, IfaceImpl, TransitionIface}; use crate::persistence::PersistedState; -use crate::Outpoint; #[derive(Clone, Eq, PartialEq, Debug, Display, Error, From)] #[display(doc_comments)] pub enum BuilderError { - /// contract already has too many layers1. - TooManyLayers1, - /// metadata `{0}` are not known to the schema MetadataNotFound(FieldName), @@ -73,18 +68,6 @@ pub enum BuilderError { /// state `{0}` provided to the builder has invalid type. InvalidStateType(AssignmentType), - /// asset tag for state `{0}` must be added before any fungible state of - /// the same type. - AssetTagMissed(AssignmentType), - - /// asset tag for state `{0}` was already automatically created. Please call - /// `add_asset_tag` before adding any fungible state to the builder. - AssetTagAutomatic(AssignmentType), - - /// state data for state type `{0}` are invalid: asset tag doesn't match the - /// tag defined by the contract. - AssetTagInvalid(AssignmentType), - /// interface doesn't specifies default operation name, thus an explicit /// operation type must be provided with `set_operation_type` method. NoOperationSubtype, @@ -112,38 +95,12 @@ pub enum BuilderError { ContractInconsistency(validation::Status), } -mod private { - pub trait Sealed {} -} - -pub trait TxOutpoint: Copy + Eq + private::Sealed { - fn is_liquid(&self) -> bool; - fn is_bitcoin(&self) -> bool; - fn map_to_xchain(self, f: impl FnOnce(Outpoint) -> U) -> XChain; -} - -impl private::Sealed for Outpoint {} -impl private::Sealed for XOutpoint {} -impl TxOutpoint for Outpoint { - fn is_liquid(&self) -> bool { false } - fn is_bitcoin(&self) -> bool { true } - fn map_to_xchain(self, f: impl FnOnce(Outpoint) -> U) -> XChain { - XChain::Bitcoin(f(self)) - } -} -impl TxOutpoint for XOutpoint { - fn is_liquid(&self) -> bool { XChain::is_liquid(self) } - fn is_bitcoin(&self) -> bool { XChain::is_bitcoin(self) } - fn map_to_xchain(self, f: impl FnOnce(Outpoint) -> U) -> XChain { self.map(f) } -} - #[derive(Clone, Debug)] pub struct ContractBuilder { builder: OperationBuilder, - testnet: bool, - alt_layers1: AltLayer1Set, scripts: Scripts, issuer: Identity, + chain_net: ChainNet, } impl ContractBuilder { @@ -154,16 +111,17 @@ impl ContractBuilder { iimpl: IfaceImpl, types: TypeSystem, scripts: Scripts, + chain_net: ChainNet, ) -> Self { Self { builder: OperationBuilder::with(iface, schema, iimpl, types), - testnet: true, - alt_layers1: none!(), scripts, issuer, + chain_net, } } + #[allow(clippy::too_many_arguments)] pub fn deterministic( issuer: Identity, iface: Iface, @@ -171,58 +129,18 @@ impl ContractBuilder { iimpl: IfaceImpl, types: TypeSystem, scripts: Scripts, + chain_net: ChainNet, ) -> Self { Self { builder: OperationBuilder::deterministic(iface, schema, iimpl, types), - testnet: true, - alt_layers1: none!(), scripts, issuer, + chain_net, } } pub fn type_system(&self) -> &TypeSystem { self.builder.type_system() } - pub fn set_mainnet(mut self) -> Self { - self.testnet = false; - self - } - - pub fn has_layer1(&self, layer1: Layer1) -> bool { - match layer1 { - Layer1::Bitcoin => true, - Layer1::Liquid => self.alt_layers1.contains(&AltLayer1::Liquid), - } - } - pub fn check_layer1(&self, layer1: Layer1) -> Result<(), BuilderError> { - if !self.has_layer1(layer1) { - return Err(BuilderError::InvalidLayer1(layer1)); - } - Ok(()) - } - - pub fn add_layer1(mut self, layer1: AltLayer1) -> Result { - self.alt_layers1 - .push(layer1) - .map_err(|_| BuilderError::TooManyLayers1)?; - Ok(self) - } - - #[inline] - pub fn asset_tag(&self, name: impl Into) -> Result { - self.builder.asset_tag(name) - } - - #[inline] - pub fn add_asset_tag( - mut self, - name: impl Into, - asset_tag: AssetTag, - ) -> Result { - self.builder = self.builder.add_asset_tag(name, asset_tag)?; - Ok(self) - } - #[inline] pub fn global_type(&self, name: &FieldName) -> Option { self.builder.global_type(name) @@ -268,7 +186,6 @@ impl ContractBuilder { state: PersistedState, ) -> Result { let seal = seal.into(); - self.check_layer1(seal.layer1())?; self.builder = self.builder.add_owned_state_det(name, seal, state)?; Ok(self) } @@ -279,7 +196,6 @@ impl ContractBuilder { seal: impl Into>, ) -> Result { let seal = seal.into(); - self.check_layer1(seal.layer1())?; self.builder = self.builder.add_rights(name, seal)?; Ok(self) } @@ -292,28 +208,10 @@ impl ContractBuilder { ) -> Result { let name = name.into(); let seal = seal.into(); - self.check_layer1(seal.layer1())?; - self.builder.init_asset_tag(name.clone())?; self.builder = self.builder.add_fungible_state(name, seal, value)?; Ok(self) } - pub fn add_fungible_state_det( - mut self, - name: impl Into, - seal: impl Into>, - value: impl Into, - blinding: BlindingFactor, - ) -> Result { - let name = name.into(); - let seal = seal.into(); - self.check_layer1(seal.layer1())?; - let tag = self.builder.init_asset_tag(name.clone())?; - let state = RevealedValue::with_blinding(value.into(), blinding, tag); - self.builder = self.builder.add_fungible_state_det(name, seal, state)?; - Ok(self) - } - pub fn add_data( mut self, name: impl Into, @@ -321,7 +219,6 @@ impl ContractBuilder { value: impl StrictSerialize, ) -> Result { let seal = seal.into(); - self.check_layer1(seal.layer1())?; self.builder = self.builder.add_data(name, seal, value)?; Ok(self) } @@ -333,7 +230,6 @@ impl ContractBuilder { data: RevealedData, ) -> Result { let seal = seal.into(); - self.check_layer1(seal.layer1())?; self.builder = self.builder.add_data_det(name, seal, data)?; Ok(self) } @@ -345,7 +241,6 @@ impl ContractBuilder { attachment: AttachState, ) -> Result { let seal = seal.into(); - self.check_layer1(seal.layer1())?; self.builder = self.builder.add_attachment(name, seal, attachment)?; Ok(self) } @@ -357,7 +252,6 @@ impl ContractBuilder { attachment: RevealedAttach, ) -> Result { let seal = seal.into(); - self.check_layer1(seal.layer1())?; self.builder = self.builder.add_attachment_det(name, seal, attachment)?; Ok(self) } @@ -382,17 +276,14 @@ impl ContractBuilder { } fn issue_contract_raw(self, timestamp: i64) -> Result, BuilderError> { - let (schema, iface, iimpl, global, assignments, types, asset_tags) = - self.builder.complete(None); + let (schema, iface, iimpl, global, assignments, types) = self.builder.complete(); let genesis = Genesis { ffv: none!(), schema_id: schema.schema_id(), flags: none!(), timestamp, - testnet: self.testnet, - alt_layers1: self.alt_layers1, - asset_tags, + chain_net: self.chain_net, metadata: empty!(), globals: global, assignments, @@ -423,7 +314,7 @@ impl ContractBuilder { }; let valid_contract = contract - .validate(&DumbResolver, self.testnet) + .validate(&DumbResolver, self.chain_net) .map_err(|(status, _)| status)?; Ok(valid_contract) @@ -563,31 +454,6 @@ impl TransitionBuilder { self } - #[inline] - pub fn asset_tag(&self, name: impl Into) -> Result { - self.builder.asset_tag(name) - } - - #[inline] - pub fn add_asset_tag( - mut self, - name: impl Into, - asset_tag: AssetTag, - ) -> Result { - self.builder = self.builder.add_asset_tag(name, asset_tag)?; - Ok(self) - } - - #[inline] - pub fn add_asset_tag_raw( - mut self, - type_id: AssignmentType, - asset_tag: AssetTag, - ) -> Result { - self.builder = self.builder.add_asset_tag_raw(type_id, asset_tag)?; - Ok(self) - } - #[inline] pub fn add_metadata( mut self, @@ -658,10 +524,6 @@ impl TransitionBuilder { seal: impl Into>, state: PersistedState, ) -> Result { - if matches!(state, PersistedState::Amount(_, _, tag) if self.builder.asset_tag_raw(type_id)? != tag) - { - return Err(BuilderError::AssetTagInvalid(type_id)); - } self.builder = self.builder.add_owned_state_raw(type_id, seal, state)?; Ok(self) } @@ -684,16 +546,6 @@ impl TransitionBuilder { self.add_fungible_state(assignment_name, seal.into(), value) } - pub fn add_fungible_default_state_det( - self, - seal: impl Into>, - value: u64, - blinding: BlindingFactor, - ) -> Result { - let assignment_name = self.default_assignment()?.clone(); - self.add_fungible_state_det(assignment_name, seal.into(), value, blinding) - } - pub fn add_fungible_state( mut self, name: impl Into, @@ -704,34 +556,13 @@ impl TransitionBuilder { Ok(self) } - pub fn add_fungible_state_det( - mut self, - name: impl Into, - seal: impl Into>, - value: impl Into, - blinding: BlindingFactor, - ) -> Result { - let name = name.into(); - let type_id = self - .builder - .assignments_type(&name) - .ok_or(BuilderError::AssignmentNotFound(name.clone()))?; - let tag = self.builder.asset_tag_raw(type_id)?; - let state = RevealedValue::with_blinding(value.into(), blinding, tag); - - self.builder = self.builder.add_fungible_state_det(name, seal, state)?; - Ok(self) - } - pub fn add_fungible_state_raw( mut self, type_id: AssignmentType, seal: impl Into>, value: impl Into, - blinding: BlindingFactor, ) -> Result { - let tag = self.builder.asset_tag_raw(type_id)?; - let state = RevealedValue::with_blinding(value.into(), blinding, tag); + let state = RevealedValue::new(value.into()); self.builder = self.builder.add_fungible_state_raw(type_id, seal, state)?; Ok(self) } @@ -800,7 +631,7 @@ impl TransitionBuilder { pub fn has_inputs(&self) -> bool { !self.inputs.is_empty() } pub fn complete_transition(self) -> Result { - let (_, _, _, global, assignments, _, _) = self.builder.complete(Some(&self.inputs)); + let (_, _, _, global, assignments, _) = self.builder.complete(); let transition = Transition { ffv: none!(), @@ -828,7 +659,6 @@ pub struct OperationBuilder { schema: Schema, iface: Iface, iimpl: IfaceImpl, - asset_tags: AssetTags, deterministic: bool, global: GlobalState, @@ -849,7 +679,6 @@ impl OperationBuilder { schema, iface, iimpl, - asset_tags: none!(), deterministic: false, global: none!(), @@ -868,7 +697,6 @@ impl OperationBuilder { schema, iface, iimpl, - asset_tags: none!(), deterministic: true, global: none!(), @@ -938,68 +766,6 @@ impl OperationBuilder { .expect("schema should match interface: must be checked by the constructor") } - pub fn asset_tag(&self, name: impl Into) -> Result { - let name = name.into(); - let type_id = self - .assignments_type(&name) - .ok_or(BuilderError::AssignmentNotFound(name.clone()))?; - self.asset_tag_raw(type_id) - } - - #[inline] - fn asset_tag_raw(&self, type_id: AssignmentType) -> Result { - self.asset_tags - .get(&type_id) - .ok_or(BuilderError::AssetTagMissed(type_id)) - .copied() - } - - #[inline] - pub fn add_asset_tag( - self, - name: impl Into, - asset_tag: AssetTag, - ) -> Result { - let name = name.into(); - let type_id = self - .assignments_type(&name) - .ok_or(BuilderError::AssignmentNotFound(name))?; - - self.add_asset_tag_raw(type_id, asset_tag) - } - - #[inline] - pub fn add_asset_tag_raw( - mut self, - type_id: AssignmentType, - asset_tag: AssetTag, - ) -> Result { - if self.fungible.contains_key(&type_id) { - return Err(BuilderError::AssetTagAutomatic(type_id)); - } - - self.asset_tags.insert(type_id, asset_tag)?; - Ok(self) - } - - pub fn init_asset_tag(&mut self, name: impl Into) -> Result { - let name = name.into(); - let type_id = self - .assignments_type(&name) - .ok_or(BuilderError::AssignmentNotFound(name))?; - - if let Some(tag) = self.asset_tags.get(&type_id) { - Ok(*tag) - } else { - let asset_tag = AssetTag::new_random( - format!("{}/{}", self.schema.schema_id(), self.iface.iface_id()), - type_id, - ); - self.asset_tags.insert(type_id, asset_tag)?; - Ok(asset_tag) - } - } - pub fn add_metadata( mut self, name: impl Into, @@ -1064,16 +830,8 @@ impl OperationBuilder { ) -> Result { match state { PersistedState::Void => self.add_rights_raw(type_id, seal), - PersistedState::Amount(value, blinding, tag) => { - if self.asset_tag_raw(type_id)? != tag { - return Err(BuilderError::AssetTagInvalid(type_id)); - } - - self.add_fungible_state_raw( - type_id, - seal, - RevealedValue::with_blinding(value, blinding, tag), - ) + PersistedState::Amount(value) => { + self.add_fungible_state_raw(type_id, seal, RevealedValue::new(value)) } PersistedState::Data(data, salt) => { self.add_data_raw(type_id, seal, RevealedData::with_salt(data, salt)) @@ -1129,39 +887,13 @@ impl OperationBuilder { seal: impl Into>, value: impl Into, ) -> Result { - debug_assert!( - !self.deterministic, - "for adding state to deterministic contracts you have to use add_*_det methods" - ); - let name = name.into(); let type_id = self .assignments_type(&name) .ok_or(BuilderError::AssignmentNotFound(name))?; - let tag = self.asset_tag_raw(type_id)?; - let state = RevealedValue::new_random_blinding(value.into(), tag); - self.add_fungible_state_raw(type_id, seal, state) - } - - fn add_fungible_state_det( - self, - name: impl Into, - seal: impl Into>, - state: RevealedValue, - ) -> Result { - debug_assert!( - self.deterministic, - "to add owned state in deterministic way the builder has to be created using \ - deterministic constructor" - ); - - let name = name.into(); - - let type_id = self - .assignments_type(&name) - .ok_or(BuilderError::AssignmentNotFound(name))?; + let state = RevealedValue::new(value.into()); self.add_fungible_state_raw(type_id, seal, state) } @@ -1324,53 +1056,23 @@ impl OperationBuilder { Ok(self) } - fn complete( - self, - inputs: Option<&TinyOrdMap>, - ) -> (Schema, Iface, IfaceImpl, GlobalState, Assignments, TypeSystem, AssetTags) { + fn complete(self) -> (Schema, Iface, IfaceImpl, GlobalState, Assignments, TypeSystem) { let owned_state = self.fungible.into_iter().map(|(id, vec)| { - let mut blindings = Vec::with_capacity(vec.len()); - let mut vec = vec + let vec = vec .into_iter() - .map(|(seal, value)| { - blindings.push(value.blinding); - match seal { - BuilderSeal::Revealed(seal) => Assign::Revealed { - seal, - state: value, - lock: none!(), - }, - BuilderSeal::Concealed(seal) => Assign::ConfidentialSeal { - seal, - state: value, - lock: none!(), - }, - } + .map(|(seal, value)| match seal { + BuilderSeal::Revealed(seal) => Assign::Revealed { + seal, + state: value, + lock: none!(), + }, + BuilderSeal::Concealed(seal) => Assign::ConfidentialSeal { + seal, + state: value, + lock: none!(), + }, }) .collect::>(); - if let Some(assignment) = vec.last_mut() { - blindings.pop(); - let state = assignment - .as_revealed_state_mut() - .expect("builder always operates revealed state"); - let mut inputs = inputs - .map(|i| { - i.iter() - .filter(|(out, _)| out.prev_out.ty == id) - .map(|(_, ts)| match ts { - PersistedState::Amount(_, blinding, _) => *blinding, - _ => panic!("previous state has invalid type"), - }) - .collect::>() - }) - .unwrap_or_default(); - if inputs.is_empty() { - inputs = vec![BlindingFactor::EMPTY]; - } - state.blinding = BlindingFactor::zero_balanced(inputs, blindings).expect( - "malformed set of blinding factors; probably random generator is broken", - ); - } let state = Confined::try_from_iter(vec).expect("at least one element"); let state = TypedAssigns::Fungible(state); (id, state) @@ -1443,6 +1145,6 @@ impl OperationBuilder { .extend(Assignments::from_inner(owned_attachments).into_inner()) .expect("too many assignments"); - (self.schema, self.iface, self.iimpl, self.global, assignments, self.types, self.asset_tags) + (self.schema, self.iface, self.iimpl, self.global, assignments, self.types) } } diff --git a/src/interface/contract.rs b/src/interface/contract.rs index 2709a054..49042304 100644 --- a/src/interface/contract.rs +++ b/src/interface/contract.rs @@ -22,10 +22,11 @@ use std::borrow::Borrow; use std::collections::{BTreeSet, HashMap, HashSet}; +use bp::Outpoint; use invoice::{Allocation, Amount}; use rgb::{ - AssignmentType, AttachState, ContractId, DataState, OpId, RevealedAttach, RevealedData, - RevealedValue, Schema, VoidState, XOutpoint, XOutputSeal, XWitnessId, + AssignmentType, AttachState, ContractId, DataState, OpId, OutputSeal, RevealedAttach, + RevealedData, RevealedValue, Schema, Txid, VoidState, }; use strict_encoding::{FieldName, StrictDecode, StrictDumb, StrictEncode}; use strict_types::{StrictVal, TypeSystem}; @@ -119,7 +120,7 @@ pub struct ContractOp { pub ty: AssignmentType, pub opids: BTreeSet, pub state: AllocatedState, - pub to: BTreeSet, + pub to: BTreeSet, pub witness: Option, } @@ -368,7 +369,7 @@ impl ContractIface { pub fn outpoint_allocations( &self, - outpoint: XOutpoint, + outpoint: Outpoint, ) -> impl Iterator + '_ { self.allocations(outpoint) } @@ -517,7 +518,7 @@ impl ContractIface { self.operations(|state| state.attach_all(), filter_outpoints, filter_witnesses) } - pub fn witness_info(&self, witness_id: XWitnessId) -> Option { + pub fn witness_info(&self, witness_id: Txid) -> Option { let ord = self.state.witness_ord(witness_id)?; Some(WitnessInfo { id: witness_id, diff --git a/src/interface/filter.rs b/src/interface/filter.rs index b76ccd65..55cd28ca 100644 --- a/src/interface/filter.rs +++ b/src/interface/filter.rs @@ -22,110 +22,90 @@ use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; use std::ops::Deref; -use rgb::{XOutpoint, XWitnessId}; +use bp::{Outpoint, Txid}; pub trait AssignmentsFilter { - fn should_include( - &self, - outpoint: impl Into, - witness_id: Option, - ) -> bool; + fn should_include(&self, outpoint: impl Into, witness_id: Option) -> bool; } pub struct FilterIncludeAll; pub struct FilterExclude(pub T); impl AssignmentsFilter for FilterIncludeAll { - fn should_include(&self, _: impl Into, _: Option) -> bool { true } + fn should_include(&self, _: impl Into, _: Option) -> bool { true } } impl AssignmentsFilter for FilterExclude { - fn should_include( - &self, - outpoint: impl Into, - witness_id: Option, - ) -> bool { + fn should_include(&self, outpoint: impl Into, witness_id: Option) -> bool { !self.0.should_include(outpoint.into(), witness_id) } } impl AssignmentsFilter for &T { - fn should_include( - &self, - outpoint: impl Into, - witness_id: Option, - ) -> bool { + fn should_include(&self, outpoint: impl Into, witness_id: Option) -> bool { (*self).should_include(outpoint, witness_id) } } impl AssignmentsFilter for &mut T { - fn should_include( - &self, - outpoint: impl Into, - witness_id: Option, - ) -> bool { + fn should_include(&self, outpoint: impl Into, witness_id: Option) -> bool { self.deref().should_include(outpoint, witness_id) } } impl AssignmentsFilter for Option { - fn should_include( - &self, - outpoint: impl Into, - witness_id: Option, - ) -> bool { + fn should_include(&self, outpoint: impl Into, witness_id: Option) -> bool { self.as_ref() .map(|filter| filter.should_include(outpoint, witness_id)) .unwrap_or(true) } } -impl AssignmentsFilter for XOutpoint { - fn should_include(&self, outpoint: impl Into, _: Option) -> bool { +impl AssignmentsFilter for Outpoint { + fn should_include(&self, outpoint: impl Into, _: Option) -> bool { *self == outpoint.into() } } -impl AssignmentsFilter for [XOutpoint; LEN] { - fn should_include(&self, outpoint: impl Into, _: Option) -> bool { +impl AssignmentsFilter for [Outpoint; LEN] { + fn should_include(&self, outpoint: impl Into, _: Option) -> bool { self.contains(&outpoint.into()) } } -impl AssignmentsFilter for &[XOutpoint] { - fn should_include(&self, outpoint: impl Into, _: Option) -> bool { +impl AssignmentsFilter for &[Outpoint] { + fn should_include(&self, outpoint: impl Into, _: Option) -> bool { self.contains(&outpoint.into()) } } -impl AssignmentsFilter for Vec { - fn should_include(&self, outpoint: impl Into, _: Option) -> bool { +impl AssignmentsFilter for Vec { + fn should_include(&self, outpoint: impl Into, _: Option) -> bool { self.contains(&outpoint.into()) } } -impl AssignmentsFilter for HashSet { - fn should_include(&self, outpoint: impl Into, _: Option) -> bool { +impl AssignmentsFilter for HashSet { + fn should_include(&self, outpoint: impl Into, _: Option) -> bool { self.contains(&outpoint.into()) } } -impl AssignmentsFilter for BTreeSet { - fn should_include(&self, outpoint: impl Into, _: Option) -> bool { +impl AssignmentsFilter for BTreeSet { + fn should_include(&self, outpoint: impl Into, _: Option) -> bool { self.contains(&outpoint.into()) } } -impl AssignmentsFilter for HashMap { - fn should_include(&self, outpoint: impl Into, _: Option) -> bool { +impl AssignmentsFilter for HashMap { + fn should_include(&self, outpoint: impl Into, _: Option) -> bool { let outpoint = outpoint.into(); self.keys().any(|o| *o == outpoint) } } -impl AssignmentsFilter for BTreeMap { - fn should_include(&self, outpoint: impl Into, _: Option) -> bool { +impl AssignmentsFilter for BTreeMap { + fn should_include(&self, outpoint: impl Into, _: Option) -> bool { let outpoint = outpoint.into(); self.keys().any(|o| *o == outpoint) } diff --git a/src/interface/iface.rs b/src/interface/iface.rs index d4a904fc..e765f691 100644 --- a/src/interface/iface.rs +++ b/src/interface/iface.rs @@ -30,7 +30,7 @@ use amplify::{ByteArray, Bytes32}; use baid64::{Baid64ParseError, DisplayBaid64, FromBaid64Str}; use chrono::{DateTime, TimeZone, Utc}; use commit_verify::{CommitId, CommitmentId, DigestExt, Sha256}; -use rgb::{ContractId, Identity, Occurrences, SchemaId, XWitnessId}; +use rgb::{ContractId, Identity, Occurrences, SchemaId, Txid}; use strict_encoding::{ FieldName, StrictDecode, StrictDeserialize, StrictDumb, StrictEncode, StrictSerialize, StrictType, TypeName, VariantName, @@ -367,7 +367,7 @@ pub trait IfaceWrapper { fn schema_id(&self) -> SchemaId; /// Returns information about a witness, if it is known to the contract state. - fn witness_info(&self, witness_id: XWitnessId) -> Option; + fn witness_info(&self, witness_id: Txid) -> Option; } /// Interface definition. diff --git a/src/interface/mod.rs b/src/interface/mod.rs index 496ce87e..301783d5 100644 --- a/src/interface/mod.rs +++ b/src/interface/mod.rs @@ -32,7 +32,7 @@ pub(crate) mod resolver; mod contractum; mod inheritance; -pub use builder::{BuilderError, ContractBuilder, TransitionBuilder, TxOutpoint}; +pub use builder::{BuilderError, ContractBuilder, TransitionBuilder}; pub use contract::{ AllocatedState, AttachAllocation, ContractError, ContractIface, ContractOp, DataAllocation, FungibleAllocation, OpDirection, OwnedAllocation, RightsAllocation, diff --git a/src/interface/resolver.rs b/src/interface/resolver.rs index 7f563820..d396ec80 100644 --- a/src/interface/resolver.rs +++ b/src/interface/resolver.rs @@ -19,20 +19,22 @@ // See the License for the specific language governing permissions and // limitations under the License. +use bp::{Tx, Txid}; use rgb::validation::{ResolveWitness, WitnessResolverError}; -use rgb::vm::{WitnessOrd, XWitnessTx}; +use rgb::vm::WitnessOrd; +use rgb::ChainNet; use strict_encoding::StrictDumb; -use crate::XWitnessId; - pub(crate) struct DumbResolver; impl ResolveWitness for DumbResolver { - fn resolve_pub_witness(&self, _: XWitnessId) -> Result { - Ok(XWitnessTx::strict_dumb()) + fn resolve_pub_witness(&self, _: Txid) -> Result { + Ok(Tx::strict_dumb()) } - fn resolve_pub_witness_ord(&self, _: XWitnessId) -> Result { + fn resolve_pub_witness_ord(&self, _: Txid) -> Result { Ok(WitnessOrd::strict_dumb()) } + + fn check_chain_net(&self, _: ChainNet) -> Result<(), WitnessResolverError> { Ok(()) } } diff --git a/src/persistence/index.rs b/src/persistence/index.rs index 7291eba0..ce2c0ebb 100644 --- a/src/persistence/index.rs +++ b/src/persistence/index.rs @@ -23,12 +23,12 @@ use std::collections::BTreeSet; use std::error::Error; use std::fmt::Debug; -use amplify::confinement; +use amplify::confinement::{self, TinyOrdSet}; +use bp::{Outpoint, Txid}; use nonasync::persistence::{CloneNoPersistence, Persisting}; use rgb::{ Assign, AssignmentType, BundleId, ContractId, ExposedState, Extension, Genesis, GenesisSeal, - GraphSeal, OpId, Operation, Opout, TransitionBundle, TypedAssigns, XChain, XOutpoint, - XWitnessId, + GraphSeal, OpId, Operation, Opout, TransitionBundle, TypedAssigns, }; use crate::containers::{ConsignmentExt, ToWitnessId, WitnessBundle}; @@ -99,7 +99,7 @@ pub enum IndexInconsistency { BundleAbsent(OpId), /// outpoint {0} is not part of the contract {1}. - OutpointUnknown(XOutpoint, ContractId), + OutpointUnknown(Outpoint, ContractId), /// index already contains information about bundle {bundle_id} which /// specifies contract {present} instead of contract {expected}. @@ -171,13 +171,12 @@ impl Index

{ } for WitnessBundle { pub_witness, - anchored_bundles, + anchored_bundle, } in consignment.bundled_witnesses() { let witness_id = pub_witness.to_witness_id(); - for bundle in anchored_bundles.bundles() { - self.index_bundle(contract_id, bundle, witness_id)?; - } + let bundle = anchored_bundle.bundle(); + self.index_bundle(contract_id, bundle, witness_id)?; } Ok(()) @@ -241,7 +240,7 @@ impl Index

{ &mut self, contract_id: ContractId, bundle: &TransitionBundle, - witness_id: XWitnessId, + witness_id: Txid, ) -> Result<(), IndexError

> { let bundle_id = bundle.bundle_id(); @@ -250,6 +249,10 @@ impl Index

{ for (opid, transition) in &bundle.known_transitions { self.provider.register_operation(*opid, bundle_id)?; + for input in &transition.inputs { + self.provider + .register_spending(input.prev_out.op, bundle_id)?; + } for (type_id, assign) in transition.assignments.iter() { match assign { TypedAssigns::Declarative(vec) => { @@ -297,7 +300,7 @@ impl Index

{ pub(super) fn contracts_assigning( &self, - outputs: BTreeSet, + outputs: BTreeSet, ) -> Result + '_, IndexError

> { self.provider .contracts_assigning(outputs) @@ -314,14 +317,14 @@ impl Index

{ pub(super) fn opouts_by_outputs( &self, contract_id: ContractId, - outputs: impl IntoIterator>, + outputs: impl IntoIterator>, ) -> Result, IndexError

> { Ok(self.provider.opouts_by_outputs(contract_id, outputs)?) } pub(super) fn opouts_by_terminals( &self, - terminals: impl IntoIterator>, + terminals: impl IntoIterator, ) -> Result, IndexError

> { self.provider .opouts_by_terminals(terminals) @@ -332,10 +335,17 @@ impl Index

{ Ok(self.provider.bundle_id_for_op(opid)?) } + pub(super) fn bundle_ids_children_of_op( + &self, + opid: OpId, + ) -> Result, IndexError

> { + Ok(self.provider.bundle_ids_children_of_op(opid)?) + } + pub(super) fn bundle_info( &self, bundle_id: BundleId, - ) -> Result<(impl Iterator + '_, ContractId), IndexError

> { + ) -> Result<(impl Iterator + '_, ContractId), IndexError

> { Ok(self.provider.bundle_info(bundle_id)?) } } @@ -368,7 +378,7 @@ pub trait IndexReadProvider { fn contracts_assigning( &self, - outputs: BTreeSet, + outputs: BTreeSet, ) -> Result + '_, Self::Error>; fn public_opouts( @@ -379,20 +389,25 @@ pub trait IndexReadProvider { fn opouts_by_outputs( &self, contract_id: ContractId, - outputs: impl IntoIterator>, + outputs: impl IntoIterator>, ) -> Result, IndexReadError>; fn opouts_by_terminals( &self, - terminals: impl IntoIterator>, + terminals: impl IntoIterator, ) -> Result, Self::Error>; fn bundle_id_for_op(&self, opid: OpId) -> Result>; + fn bundle_ids_children_of_op( + &self, + opid: OpId, + ) -> Result, IndexReadError>; + fn bundle_info( &self, bundle_id: BundleId, - ) -> Result<(impl Iterator, ContractId), IndexReadError>; + ) -> Result<(impl Iterator, ContractId), IndexReadError>; } pub trait IndexWriteProvider: StoreTransaction { @@ -403,7 +418,7 @@ pub trait IndexWriteProvider: StoreTransaction { fn register_bundle( &mut self, bundle_id: BundleId, - witness_id: XWitnessId, + witness_id: Txid, contract_id: ContractId, ) -> Result>; @@ -413,6 +428,12 @@ pub trait IndexWriteProvider: StoreTransaction { bundle_id: BundleId, ) -> Result>; + fn register_spending( + &mut self, + opid: OpId, + bundle_id: BundleId, + ) -> Result>; + fn index_genesis_assignments( &mut self, contract_id: ContractId, @@ -427,6 +448,6 @@ pub trait IndexWriteProvider: StoreTransaction { vec: &[Assign], opid: OpId, type_id: AssignmentType, - witness_id: XWitnessId, + witness_id: Txid, ) -> Result<(), IndexWriteError>; } diff --git a/src/persistence/memory.rs b/src/persistence/memory.rs index 4126daa2..df2d2222 100644 --- a/src/persistence/memory.rs +++ b/src/persistence/memory.rs @@ -24,7 +24,6 @@ use std::cmp::Ordering; use std::collections::{BTreeMap, BTreeSet, HashMap}; use std::convert::Infallible; use std::fmt::{Debug, Formatter}; -use std::num::NonZeroU32; use std::{iter, mem}; use aluvm::library::{Lib, LibId}; @@ -34,9 +33,9 @@ use amplify::confinement::{ }; use amplify::num::u24; use bp::dbc::tapret::TapretCommitment; +use bp::{Outpoint, Txid}; use commit_verify::{CommitId, Conceal}; use nonasync::persistence::{CloneNoPersistence, Persistence, PersistenceError, Persisting}; -use rgb::validation::ResolveWitness; use rgb::vm::{ ContractStateAccess, ContractStateEvolve, GlobalContractState, GlobalOrd, GlobalStateIter, OrdOpRef, UnknownGlobalStateType, WitnessOrd, @@ -44,9 +43,9 @@ use rgb::vm::{ use rgb::{ Assign, AssignmentType, Assignments, AssignmentsRef, AttachId, AttachState, BundleId, ContractId, DataState, ExposedSeal, ExposedState, Extension, FungibleState, Genesis, - GenesisSeal, GlobalStateType, GraphSeal, Identity, OpId, Operation, Opout, RevealedAttach, - RevealedData, RevealedValue, Schema, SchemaId, SecretSeal, Transition, TransitionBundle, - TypedAssigns, VoidState, XChain, XOutpoint, XOutputSeal, XWitnessId, + GenesisSeal, GlobalStateType, GraphSeal, Identity, OpId, Operation, Opout, OutputSeal, + RevealedAttach, RevealedData, RevealedValue, Schema, SchemaId, SecretSeal, Transition, + TransitionBundle, TypedAssigns, VoidState, }; use strict_encoding::{StrictDeserialize, StrictSerialize}; use strict_types::TypeSystem; @@ -56,7 +55,6 @@ use super::{ IndexReadError, IndexReadProvider, IndexWriteError, IndexWriteProvider, SchemaIfaces, StashInconsistency, StashProvider, StashProviderError, StashReadProvider, StashWriteProvider, StateInconsistency, StateProvider, StateReadProvider, StateWriteProvider, StoreTransaction, - UpdateRes, }; use crate::containers::{ AnchorSet, ContentId, ContentRef, ContentSigs, SealWitness, SigBlob, Supplement, TrustLevel, @@ -95,9 +93,9 @@ pub struct MemStash { suppl: TinyOrdMap>, bundles: LargeOrdMap, extensions: LargeOrdMap, - witnesses: LargeOrdMap, + witnesses: LargeOrdMap, attachments: SmallOrdMap, - secret_seals: MediumOrdSet>, + secret_seals: MediumOrdSet, type_system: TypeSystem, identities: SmallOrdMap, libs: SmallOrdMap, @@ -287,7 +285,7 @@ impl StashReadProvider for MemStash { .ok_or(StashInconsistency::ContractAbsent(contract_id).into()) } - fn witness_ids(&self) -> Result, Self::Error> { + fn witness_ids(&self) -> Result, Self::Error> { Ok(self.witnesses.keys().copied()) } @@ -314,25 +312,18 @@ impl StashReadProvider for MemStash { .ok_or(StashInconsistency::OperationAbsent(op_id).into()) } - fn witness( - &self, - witness_id: XWitnessId, - ) -> Result<&SealWitness, StashProviderError> { + fn witness(&self, witness_id: Txid) -> Result<&SealWitness, StashProviderError> { self.witnesses .get(&witness_id) .ok_or(StashInconsistency::WitnessAbsent(witness_id).into()) } - fn taprets(&self) -> Result, Self::Error> { + fn taprets(&self) -> Result, Self::Error> { Ok(self .witnesses .iter() - .filter_map(|(witness_id, witness)| match &witness.anchors { - AnchorSet::Tapret(anchor) - | AnchorSet::Double { - tapret: anchor, - opret: _, - } => Some((*witness_id, TapretCommitment { + .filter_map(|(witness_id, witness)| match &witness.anchor { + AnchorSet::Tapret(anchor) => Some((*witness_id, TapretCommitment { mpc: anchor.mpc_proof.commit_id(), nonce: anchor.dbc_proof.path_proof.nonce(), })), @@ -340,10 +331,7 @@ impl StashReadProvider for MemStash { })) } - fn seal_secret( - &self, - secret: XChain, - ) -> Result>, Self::Error> { + fn seal_secret(&self, secret: SecretSeal) -> Result, Self::Error> { Ok(self .secret_seals .iter() @@ -351,7 +339,7 @@ impl StashReadProvider for MemStash { .copied()) } - fn secret_seals(&self) -> Result>, Self::Error> { + fn secret_seals(&self) -> Result, Self::Error> { Ok(self.secret_seals.iter().copied()) } } @@ -473,7 +461,7 @@ impl StashWriteProvider for MemStash { Ok(()) } - fn add_secret_seal(&mut self, seal: XChain) -> Result { + fn add_secret_seal(&mut self, seal: GraphSeal) -> Result { let present = self.secret_seals.contains(&seal); self.secret_seals.push(seal)?; Ok(!present) @@ -493,7 +481,8 @@ pub struct MemState { #[strict_type(skip)] persistence: Option>, - witnesses: LargeOrdMap, + witnesses: LargeOrdMap, + invalid_bundles: LargeOrdSet, contracts: TinyOrdMap, } @@ -505,6 +494,7 @@ impl MemState { Self { persistence: none!(), witnesses: empty!(), + invalid_bundles: empty!(), contracts: empty!(), } } @@ -515,6 +505,7 @@ impl CloneNoPersistence for MemState { Self { persistence: None, witnesses: self.witnesses.clone(), + invalid_bundles: empty!(), contracts: self.contracts.clone(), } } @@ -573,16 +564,24 @@ impl StateReadProvider for MemState { }) .map(|(id, ord)| (*id, *ord)) .collect(); - Ok(MemContract { filter, unfiltered }) + Ok(MemContract { + filter, + invalid_bundles: self.invalid_bundles.clone().release(), + unfiltered, + }) } - fn is_valid_witness(&self, witness_id: XWitnessId) -> Result { + fn is_valid_witness(&self, witness_id: Txid) -> Result { let ord = self .witnesses .get(&witness_id) .ok_or(StateInconsistency::AbsentWitness(witness_id))?; Ok(ord.is_valid()) } + + fn witnesses(&self) -> LargeOrdMap { self.witnesses.clone() } + + fn invalid_bundles(&self) -> LargeOrdSet { self.invalid_bundles.clone() } } impl StateWriteProvider for MemState { @@ -610,7 +609,7 @@ impl StateWriteProvider for MemState { }; let mut writer = MemContractWriter { writer: Box::new( - |witness_id: XWitnessId, ord: WitnessOrd| -> Result<(), confinement::Error> { + |witness_id: Txid, ord: WitnessOrd| -> Result<(), confinement::Error> { // NB: We do not check the existence of the witness since we have a newer // version anyway and even if it is known we have to replace it self.witnesses.insert(witness_id, ord)?; @@ -635,7 +634,7 @@ impl StateWriteProvider for MemState { // We can't move this constructor to a dedicated method due to the rust borrower // checker writer: Box::new( - |witness_id: XWitnessId, ord: WitnessOrd| -> Result<(), confinement::Error> { + |witness_id: Txid, ord: WitnessOrd| -> Result<(), confinement::Error> { // NB: We do not check the existence of the witness since we have a newer // version anyway and even if it is known we have to replace // it @@ -647,35 +646,22 @@ impl StateWriteProvider for MemState { })) } - fn update_witnesses( + fn upsert_witness( &mut self, - resolver: impl ResolveWitness, - after_height: u32, - ) -> Result { - let after_height = NonZeroU32::new(after_height).unwrap_or(NonZeroU32::MIN); - let mut succeeded = 0; - let mut failed = map![]; - self.begin_transaction()?; - let mut witnesses = LargeOrdMap::new(); - mem::swap(&mut self.witnesses, &mut witnesses); - let mut witnesses = witnesses.release(); - for (id, ord) in &mut witnesses { - if matches!(ord, WitnessOrd::Mined(pos) if pos.height() < after_height) { - continue; - } - match resolver.resolve_pub_witness_ord(*id) { - Ok(new) => *ord = new, - Err(err) => { - failed.insert(*id, err.to_string()); - } - } - succeeded += 1; + witness_id: Txid, + witness_ord: WitnessOrd, + ) -> Result<(), Self::Error> { + self.witnesses.insert(witness_id, witness_ord)?; + Ok(()) + } + + fn update_bundle(&mut self, bundle_id: BundleId, valid: bool) -> Result<(), Self::Error> { + if valid { + self.invalid_bundles.remove(&bundle_id)?; + } else { + self.invalid_bundles.push(bundle_id)?; } - let mut witnesses = - LargeOrdMap::try_from(witnesses).inspect_err(|_| self.rollback_transaction())?; - mem::swap(&mut self.witnesses, &mut witnesses); - self.commit_transaction()?; - Ok(UpdateRes { succeeded, failed }) + Ok(()) } } @@ -767,62 +753,32 @@ impl MemContractState { } } - // We skip removing of invalidated state for the cases of re-orgs or unmined - // witness transactions committing to the new state. - // TODO: Expose an API to prune historic state by witness txid - /* - // Remove invalidated state - for input in &op.inputs() { - if let Some(o) = self.rights.iter().find(|r| r.opout == input.prev_out) { - let o = o.clone(); // need this b/c of borrow checker - self.rights - .remove(&o) - .expect("collection allows zero elements"); - } - if let Some(o) = self.fungibles.iter().find(|r| r.opout == input.prev_out) { - let o = o.clone(); - self.fungibles - .remove(&o) - .expect("collection allows zero elements"); - } - if let Some(o) = self.data.iter().find(|r| r.opout == input.prev_out) { - let o = o.clone(); - self.data - .remove(&o) - .expect("collection allows zero elements"); - } - if let Some(o) = self.attach.iter().find(|r| r.opout == input.prev_out) { - let o = o.clone(); - self.attach - .remove(&o) - .expect("collection allows zero elements"); - } - } - */ - + let bundle_id = op.bundle_id(); let witness_id = op.witness_id(); match op.assignments() { AssignmentsRef::Genesis(assignments) => { - self.add_assignments(witness_id, opid, assignments) + self.add_assignments(bundle_id, witness_id, opid, assignments) } AssignmentsRef::Graph(assignments) => { - self.add_assignments(witness_id, opid, assignments) + self.add_assignments(bundle_id, witness_id, opid, assignments) } } } fn add_assignments( &mut self, - witness_id: Option, + bundle_id: Option, + witness_id: Option, opid: OpId, assignments: &Assignments, ) { fn process( contract_state: &mut LargeOrdSet>, assignments: &[Assign], + bundle_id: Option, opid: OpId, ty: AssignmentType, - witness_id: Option, + witness_id: Option, ) { for (no, seal, state) in assignments .iter() @@ -830,10 +786,12 @@ impl MemContractState { .filter_map(|(n, a)| a.to_revealed().map(|(seal, state)| (n, seal, state))) { let assigned_state = match witness_id { - Some(witness_id) => { - OutputAssignment::with_witness(seal, witness_id, state, opid, ty, no as u16) - } - None => OutputAssignment::with_no_witness(seal, state, opid, ty, no as u16), + Some(witness_id) => OutputAssignment::with_witness( + seal, witness_id, state, bundle_id, opid, ty, no as u16, + ), + None => OutputAssignment::with_no_witness( + seal, state, bundle_id, opid, ty, no as u16, + ), }; contract_state .push(assigned_state) @@ -844,16 +802,16 @@ impl MemContractState { for (ty, assignments) in assignments.iter() { match assignments { TypedAssigns::Declarative(assignments) => { - process(&mut self.rights, assignments, opid, *ty, witness_id) + process(&mut self.rights, assignments, bundle_id, opid, *ty, witness_id) } TypedAssigns::Fungible(assignments) => { - process(&mut self.fungibles, assignments, opid, *ty, witness_id) + process(&mut self.fungibles, assignments, bundle_id, opid, *ty, witness_id) } TypedAssigns::Structured(assignments) => { - process(&mut self.data, assignments, opid, *ty, witness_id) + process(&mut self.data, assignments, bundle_id, opid, *ty, witness_id) } TypedAssigns::Attachment(assignments) => { - process(&mut self.attach, assignments, opid, *ty, witness_id) + process(&mut self.attach, assignments, bundle_id, opid, *ty, witness_id) } } } @@ -861,7 +819,8 @@ impl MemContractState { } pub struct MemContract = MemContractState> { - filter: HashMap, + filter: HashMap, + invalid_bundles: BTreeSet, unfiltered: M, } @@ -964,7 +923,7 @@ impl> ContractStateAccess for MemContract { Ok(GlobalContractState::new(iter)) } - fn rights(&self, outpoint: XOutpoint, ty: AssignmentType) -> u32 { + fn rights(&self, outpoint: Outpoint, ty: AssignmentType) -> u32 { self.unfiltered .borrow() .rights @@ -973,12 +932,13 @@ impl> ContractStateAccess for MemContract { assignment.seal.to_outpoint() == outpoint && assignment.opout.ty == ty }) .filter(|assignment| assignment.check_witness(&self.filter)) + .filter(|assignment| assignment.check_bundle(&self.invalid_bundles)) .count() as u32 } fn fungible( &self, - outpoint: XOutpoint, + outpoint: Outpoint, ty: AssignmentType, ) -> impl DoubleEndedIterator { self.unfiltered @@ -989,12 +949,13 @@ impl> ContractStateAccess for MemContract { assignment.seal.to_outpoint() == outpoint && assignment.opout.ty == ty }) .filter(|assignment| assignment.check_witness(&self.filter)) + .filter(|assignment| assignment.check_bundle(&self.invalid_bundles)) .map(|assignment| assignment.state.value) } fn data( &self, - outpoint: XOutpoint, + outpoint: Outpoint, ty: AssignmentType, ) -> impl DoubleEndedIterator> { self.unfiltered @@ -1005,12 +966,13 @@ impl> ContractStateAccess for MemContract { assignment.seal.to_outpoint() == outpoint && assignment.opout.ty == ty }) .filter(|assignment| assignment.check_witness(&self.filter)) + .filter(|assignment| assignment.check_bundle(&self.invalid_bundles)) .map(|assignment| &assignment.state.value) } fn attach( &self, - outpoint: XOutpoint, + outpoint: Outpoint, ty: AssignmentType, ) -> impl DoubleEndedIterator> { self.unfiltered @@ -1021,6 +983,7 @@ impl> ContractStateAccess for MemContract { assignment.seal.to_outpoint() == outpoint && assignment.opout.ty == ty }) .filter(|assignment| assignment.check_witness(&self.filter)) + .filter(|assignment| assignment.check_bundle(&self.invalid_bundles)) .map(|assignment| &assignment.state.file) } } @@ -1031,6 +994,7 @@ impl ContractStateEvolve for MemContract { fn init(context: Self::Context<'_>) -> Self { Self { filter: empty!(), + invalid_bundles: empty!(), unfiltered: MemContractState::new(context.0, context.1), } } @@ -1039,7 +1003,7 @@ impl ContractStateEvolve for MemContract { fn writer(me: &mut MemContract) -> MemContractWriter { MemContractWriter { writer: Box::new( - |witness_id: XWitnessId, ord: WitnessOrd| -> Result<(), confinement::Error> { + |witness_id: Txid, ord: WitnessOrd| -> Result<(), confinement::Error> { // NB: We do not check the existence of the witness since we have a // newer version anyway and even if it is // known we have to replace it @@ -1055,9 +1019,9 @@ impl ContractStateEvolve for MemContract { let mut writer = writer(self); writer.add_genesis(genesis) } - OrdOpRef::Transition(transition, witness_id, ord) => { + OrdOpRef::Transition(transition, witness_id, ord, bundle_id) => { let mut writer = writer(self); - writer.add_transition(transition, witness_id, ord) + writer.add_transition(transition, witness_id, ord, bundle_id) } OrdOpRef::Extension(extension, witness_id, ord) => { let mut writer = writer(self); @@ -1083,7 +1047,7 @@ impl> ContractStateRead for MemContract { fn schema_id(&self) -> SchemaId { self.unfiltered.borrow().schema_id } #[inline] - fn witness_ord(&self, witness_id: XWitnessId) -> Option { + fn witness_ord(&self, witness_id: Txid) -> Option { self.filter.get(&witness_id).copied() } @@ -1094,6 +1058,7 @@ impl> ContractStateRead for MemContract { .rights .iter() .filter(|assignment| assignment.check_witness(&self.filter)) + .filter(|assignment| assignment.check_bundle(&self.invalid_bundles)) } #[inline] @@ -1103,6 +1068,7 @@ impl> ContractStateRead for MemContract { .fungibles .iter() .filter(|assignment| assignment.check_witness(&self.filter)) + .filter(|assignment| assignment.check_bundle(&self.invalid_bundles)) } #[inline] @@ -1112,6 +1078,7 @@ impl> ContractStateRead for MemContract { .data .iter() .filter(|assignment| assignment.check_witness(&self.filter)) + .filter(|assignment| assignment.check_bundle(&self.invalid_bundles)) } #[inline] @@ -1121,11 +1088,12 @@ impl> ContractStateRead for MemContract { .attach .iter() .filter(|assignment| assignment.check_witness(&self.filter)) + .filter(|assignment| assignment.check_bundle(&self.invalid_bundles)) } } pub struct MemContractWriter<'mem> { - writer: Box Result<(), confinement::Error> + 'mem>, + writer: Box Result<(), confinement::Error> + 'mem>, contract: &'mem mut MemContractState, } @@ -1148,12 +1116,13 @@ impl ContractStateWrite for MemContractWriter<'_> { fn add_transition( &mut self, transition: &Transition, - witness_id: XWitnessId, + witness_id: Txid, ord: WitnessOrd, + bundle_id: BundleId, ) -> Result<(), Self::Error> { (self.writer)(witness_id, ord)?; self.contract - .add_operation(OrdOpRef::Transition(transition, witness_id, ord)); + .add_operation(OrdOpRef::Transition(transition, witness_id, ord, bundle_id)); Ok(()) } @@ -1164,7 +1133,7 @@ impl ContractStateWrite for MemContractWriter<'_> { fn add_extension( &mut self, extension: &Extension, - witness_id: XWitnessId, + witness_id: Txid, ord: WitnessOrd, ) -> Result<(), Self::Error> { (self.writer)(witness_id, ord)?; @@ -1196,7 +1165,7 @@ impl From for IndexWriteError { )] pub struct ContractIndex { public_opouts: MediumOrdSet, - outpoint_opouts: MediumOrdMap>, + outpoint_opouts: MediumOrdMap>, } #[derive(Getters, Debug)] @@ -1208,11 +1177,12 @@ pub struct MemIndex { #[strict_type(skip)] persistence: Option>, + op_bundle_children_index: MediumOrdMap>, op_bundle_index: MediumOrdMap, bundle_contract_index: MediumOrdMap, - bundle_witness_index: MediumOrdMap>, + bundle_witness_index: MediumOrdMap>, contract_index: TinyOrdMap, - terminal_index: MediumOrdMap, TinyOrdSet>, + terminal_index: MediumOrdMap>, } impl StrictSerialize for MemIndex {} @@ -1222,6 +1192,7 @@ impl MemIndex { pub fn in_memory() -> Self { Self { persistence: None, + op_bundle_children_index: empty!(), op_bundle_index: empty!(), bundle_contract_index: empty!(), bundle_witness_index: empty!(), @@ -1235,6 +1206,7 @@ impl CloneNoPersistence for MemIndex { fn clone_no_persistence(&self) -> Self { Self { persistence: None, + op_bundle_children_index: self.op_bundle_children_index.clone(), op_bundle_index: self.op_bundle_index.clone(), bundle_contract_index: self.bundle_contract_index.clone(), bundle_witness_index: self.bundle_witness_index.clone(), @@ -1273,7 +1245,7 @@ impl IndexReadProvider for MemIndex { fn contracts_assigning( &self, - outpoints: BTreeSet, + outpoints: BTreeSet, ) -> Result + '_, Self::Error> { Ok(self .contract_index @@ -1307,7 +1279,7 @@ impl IndexReadProvider for MemIndex { fn opouts_by_outputs( &self, contract_id: ContractId, - outpoints: impl IntoIterator>, + outpoints: impl IntoIterator>, ) -> Result, IndexReadError> { let index = self .contract_index @@ -1328,7 +1300,7 @@ impl IndexReadProvider for MemIndex { fn opouts_by_terminals( &self, - terminals: impl IntoIterator>, + terminals: impl IntoIterator, ) -> Result, Self::Error> { let terminals = terminals.into_iter().collect::>(); Ok(self @@ -1347,10 +1319,20 @@ impl IndexReadProvider for MemIndex { .ok_or(IndexInconsistency::BundleAbsent(opid).into()) } + fn bundle_ids_children_of_op( + &self, + opid: OpId, + ) -> Result, IndexReadError> { + self.op_bundle_children_index + .get(&opid) + .ok_or(IndexInconsistency::BundleAbsent(opid).into()) + .cloned() + } + fn bundle_info( &self, bundle_id: BundleId, - ) -> Result<(impl Iterator, ContractId), IndexReadError> { + ) -> Result<(impl Iterator, ContractId), IndexReadError> { let witness_id = self .bundle_witness_index .get(&bundle_id) @@ -1378,7 +1360,7 @@ impl IndexWriteProvider for MemIndex { fn register_bundle( &mut self, bundle_id: BundleId, - witness_id: XWitnessId, + witness_id: Txid, contract_id: ContractId, ) -> Result> { if let Some(alt) = self @@ -1425,6 +1407,25 @@ impl IndexWriteProvider for MemIndex { Ok(!present) } + fn register_spending( + &mut self, + opid: OpId, + bundle_id: BundleId, + ) -> Result> { + let mut present = false; + match self.op_bundle_children_index.get_mut(&opid) { + Some(opids) => { + present = true; + opids.push(bundle_id)?; + } + None => { + self.op_bundle_children_index + .insert(opid, tiny_bset!(bundle_id))?; + } + } + Ok(present) + } + fn index_genesis_assignments( &mut self, contract_id: ContractId, @@ -1439,7 +1440,7 @@ impl IndexWriteProvider for MemIndex { for (no, assign) in vec.iter().enumerate() { let opout = Opout::new(opid, type_id, no as u16); - if let Assign::ConfidentialState { seal, .. } | Assign::Revealed { seal, .. } = assign { + if let Assign::Revealed { seal, .. } = assign { let output = seal .to_output_seal() .expect("genesis seals always have outpoint"); @@ -1464,7 +1465,7 @@ impl IndexWriteProvider for MemIndex { vec: &[Assign], opid: OpId, type_id: AssignmentType, - witness_id: XWitnessId, + witness_id: Txid, ) -> Result<(), IndexWriteError> { let index = self .contract_index @@ -1473,14 +1474,8 @@ impl IndexWriteProvider for MemIndex { for (no, assign) in vec.iter().enumerate() { let opout = Opout::new(opid, type_id, no as u16); - if let Assign::ConfidentialState { seal, .. } | Assign::Revealed { seal, .. } = assign { - let output = seal.try_to_output_seal(witness_id).unwrap_or_else(|_| { - panic!( - "chain mismatch between assignment vout seal ({}) and witness transaction \ - ({})", - seal, witness_id - ) - }); + if let Assign::Revealed { seal, .. } = assign { + let output = seal.to_output_seal_or_default(witness_id); match index.outpoint_opouts.get_mut(&output) { Some(opouts) => { opouts.push(opout)?; @@ -1506,9 +1501,7 @@ impl MemIndex { ) -> Result<(), IndexWriteError> { for (no, assign) in vec.iter().enumerate() { let opout = Opout::new(opid, type_id, no as u16); - if let Assign::Confidential { seal, .. } | Assign::ConfidentialSeal { seal, .. } = - assign - { + if let Assign::ConfidentialSeal { seal, .. } = assign { self.add_terminal(*seal, opout)?; } } @@ -1517,7 +1510,7 @@ impl MemIndex { fn add_terminal( &mut self, - seal: XChain, + seal: SecretSeal, opout: Opout, ) -> Result<(), IndexWriteError> { match self diff --git a/src/persistence/stash.rs b/src/persistence/stash.rs index c42764e9..0221d488 100644 --- a/src/persistence/stash.rs +++ b/src/persistence/stash.rs @@ -35,8 +35,8 @@ use commit_verify::mpc::MerkleBlock; use nonasync::persistence::{CloneNoPersistence, Persisting}; use rgb::validation::{DbcProof, Scripts}; use rgb::{ - AttachId, BundleId, ContractId, Extension, Genesis, GraphSeal, Identity, OpId, Operation, - Schema, SchemaId, TransitionBundle, XChain, XWitnessId, + AttachId, BundleId, ChainNet, ContractId, Extension, Genesis, GraphSeal, Identity, OpId, + Operation, Schema, SchemaId, TransitionBundle, Txid, }; use strict_encoding::{FieldName, TypeName}; use strict_types::typesys::UnknownType; @@ -119,10 +119,10 @@ pub enum StashInconsistency { OperationAbsent(OpId), /// information about witness {0} is absent. - WitnessAbsent(XWitnessId), + WitnessAbsent(Txid), /// witness {0} for the bundle {1} misses contract {2} information in {3} anchor. - WitnessMissesContract(XWitnessId, BundleId, ContractId, CloseMethod), + WitnessMissesContract(Txid, BundleId, ContractId, CloseMethod), /// bundle {0} is absent. BundleAbsent(BundleId), @@ -261,7 +261,7 @@ impl Stash

{ pub(super) fn bundle(&self, bundle_id: BundleId) -> Result<&TransitionBundle, StashError

> { Ok(self.provider.bundle(bundle_id)?) } - pub(super) fn witness(&self, witness_id: XWitnessId) -> Result<&SealWitness, StashError

> { + pub(super) fn witness(&self, witness_id: Txid) -> Result<&SealWitness, StashError

> { Ok(self.provider.witness(witness_id)?) } @@ -322,6 +322,7 @@ impl Stash

{ issuer: Identity, schema_id: SchemaId, iface: impl Into, + chain_net: ChainNet, ) -> Result> { let schema_ifaces = self.schema(schema_id)?; let iface = self.iface(iface)?; @@ -339,6 +340,7 @@ impl Stash

{ iimpl.clone(), types, scripts, + chain_net, ); Ok(builder) } @@ -355,11 +357,10 @@ impl Stash

{ let iimpl = schema_ifaces .get(iface.iface_id()) .ok_or(StashDataError::NoIfaceImpl(schema.schema_id(), iface.iface_id()))?; - let genesis = self.provider.genesis(contract_id)?; let (types, _) = self.extract(&schema_ifaces.schema, [iface])?; - let mut builder = if let Some(transition_name) = transition_name { + let builder = if let Some(transition_name) = transition_name { TransitionBuilder::named_transition( contract_id, iface.clone(), @@ -379,12 +380,6 @@ impl Stash

{ } .expect("internal inconsistency"); - for (assignment_type, asset_tag) in genesis.asset_tags.iter() { - builder = builder - .add_asset_tag_raw(*assignment_type, *asset_tag) - .expect("tags are in bset and must not repeat"); - } - Ok(builder) } @@ -399,11 +394,10 @@ impl Stash

{ if schema_ifaces.iimpls.is_empty() { return Err(StashDataError::NoIfaceImpl(schema.schema_id(), iface.iface_id()).into()); } - let genesis = self.provider.genesis(contract_id)?; let (types, _) = self.extract(&schema_ifaces.schema, [iface])?; - let mut builder = if let Some(iimpl) = schema_ifaces.get(iface.iface_id()) { + let builder = if let Some(iimpl) = schema_ifaces.get(iface.iface_id()) { TransitionBuilder::blank_transition( contract_id, iface.clone(), @@ -424,11 +418,6 @@ impl Stash

{ types, ) }; - for (assignment_type, asset_tag) in genesis.asset_tags.iter() { - builder = builder - .add_asset_tag_raw(*assignment_type, *asset_tag) - .expect("tags are in bset and must not repeat"); - } Ok(builder) } @@ -552,92 +541,37 @@ impl Stash

{ ) -> Result<(), StashError

> { let WitnessBundle { pub_witness, - anchored_bundles, + anchored_bundle, } = witness_bundle; // TODO: Save pub witness transaction SPVs - let mut anchors = Vec::with_capacity(2); - for (anchor, bundle) in anchored_bundles.into_iter() { - let bundle_id = bundle.bundle_id(); - self.consume_bundle(bundle)?; - - let proto = mpc::ProtocolId::from_byte_array(contract_id.to_byte_array()); - let msg = mpc::Message::from_byte_array(bundle_id.to_byte_array()); - let merkle_block = MerkleBlock::with(&anchor.mpc_proof, proto, msg)?; - anchors.push(Anchor::new(merkle_block, anchor.dbc_proof)); - } - - let anchors = match (anchors.pop().unwrap(), anchors.pop()) { - ( - Anchor { - dbc_proof: DbcProof::Opret(opret), - mpc_proof, - .. - }, - None, - ) => AnchorSet::Opret(Anchor::new(mpc_proof, opret)), - ( - Anchor { - dbc_proof: DbcProof::Tapret(tapret), - mpc_proof, - .. - }, - None, - ) => AnchorSet::Tapret(Anchor::new(mpc_proof, tapret)), - ( - Anchor { - dbc_proof: DbcProof::Tapret(tapret), - mpc_proof: mpc_proof_tapret, - .. - }, - Some(Anchor { - dbc_proof: DbcProof::Opret(opret), - mpc_proof: mpc_proof_opret, - .. - }), - ) - | ( - Anchor { - dbc_proof: DbcProof::Opret(opret), - mpc_proof: mpc_proof_opret, - .. - }, - Some(Anchor { - dbc_proof: DbcProof::Tapret(tapret), - mpc_proof: mpc_proof_tapret, - .. - }), - ) => AnchorSet::Double { - tapret: Anchor::new(mpc_proof_tapret, tapret), - opret: Anchor::new(mpc_proof_opret, opret), - }, - ( - Anchor { - dbc_proof: DbcProof::Opret(_), - .. - }, - Some(Anchor { - dbc_proof: DbcProof::Opret(_), - .. - }), - ) - | ( - Anchor { - dbc_proof: DbcProof::Tapret(_), - .. - }, - Some(Anchor { - dbc_proof: DbcProof::Tapret(_), - .. - }), - ) => unreachable!( - "these combinations must be prevented at the `AnchoredBundles` structure level" - ), + let eanchor = anchored_bundle.eanchor(); + let bundle = anchored_bundle.into_bundle(); + + let bundle_id = bundle.bundle_id(); + self.consume_bundle(bundle)?; + + let proto = mpc::ProtocolId::from_byte_array(contract_id.to_byte_array()); + let msg = mpc::Message::from_byte_array(bundle_id.to_byte_array()); + let merkle_block = MerkleBlock::with(&eanchor.mpc_proof, proto, msg)?; + let anchor = Anchor::new(merkle_block, eanchor.dbc_proof); + + let anchor = match anchor { + Anchor { + dbc_proof: DbcProof::Opret(opret), + mpc_proof, + .. + } => AnchorSet::Opret(Anchor::new(mpc_proof, opret)), + Anchor { + dbc_proof: DbcProof::Tapret(opret), + mpc_proof, + .. + } => AnchorSet::Tapret(Anchor::new(mpc_proof, opret)), }; let witness = SealWitness { public: pub_witness.clone(), - anchors, + anchor, }; self.consume_witness(witness)?; @@ -648,7 +582,7 @@ impl Stash

{ let witness = match self.provider.witness(witness.witness_id()).cloned() { Ok(mut w) => { w.public = w.public.clone().merge_reveal(witness.public)?; - w.anchors = w.anchors.clone().merge_reveal(witness.anchors)?; + w.anchor = w.anchor.clone().merge_reveal(witness.anchor)?; w } Err(_) => witness, @@ -672,10 +606,7 @@ impl Stash

{ .map_err(StashError::WriteProvider) } - pub(crate) fn store_secret_seal( - &mut self, - seal: XChain, - ) -> Result> { + pub(crate) fn store_secret_seal(&mut self, seal: GraphSeal) -> Result> { self.begin_transaction()?; let seal = self .provider @@ -748,19 +679,16 @@ pub trait StashReadProvider { ) -> Result, Self::Error>; fn sigs_for(&self, content_id: &ContentId) -> Result, Self::Error>; - fn witness_ids(&self) -> Result, Self::Error>; + fn witness_ids(&self) -> Result, Self::Error>; fn bundle_ids(&self) -> Result, Self::Error>; fn bundle(&self, bundle_id: BundleId) -> Result<&TransitionBundle, ProviderError>; fn extension_ids(&self) -> Result, Self::Error>; fn extension(&self, op_id: OpId) -> Result<&Extension, ProviderError>; - fn witness(&self, witness_id: XWitnessId) -> Result<&SealWitness, ProviderError>; + fn witness(&self, witness_id: Txid) -> Result<&SealWitness, ProviderError>; - fn taprets(&self) -> Result, Self::Error>; - fn seal_secret( - &self, - secret: XChain, - ) -> Result>, Self::Error>; - fn secret_seals(&self) -> Result>, Self::Error>; + fn taprets(&self) -> Result, Self::Error>; + fn seal_secret(&self, secret: SecretSeal) -> Result, Self::Error>; + fn secret_seals(&self) -> Result, Self::Error>; } pub trait StashWriteProvider: StoreTransaction { @@ -787,5 +715,5 @@ pub trait StashWriteProvider: StoreTransaction { fn import_sigs(&mut self, content_id: ContentId, sigs: I) -> Result<(), Self::Error> where I: IntoIterator; - fn add_secret_seal(&mut self, seal: XChain) -> Result; + fn add_secret_seal(&mut self, seal: GraphSeal) -> Result; } diff --git a/src/persistence/state.rs b/src/persistence/state.rs index 4e8c21d8..c41132ae 100644 --- a/src/persistence/state.rs +++ b/src/persistence/state.rs @@ -25,19 +25,19 @@ use std::error::Error; use std::fmt::Debug; use std::iter; +use amplify::confinement::{LargeOrdMap, LargeOrdSet}; use invoice::Amount; use nonasync::persistence::{CloneNoPersistence, Persisting}; use rgb::validation::{ResolveWitness, WitnessResolverError}; use rgb::vm::{ContractStateAccess, WitnessOrd}; use rgb::{ - AssetTag, AttachState, BlindingFactor, ContractId, DataState, Extension, Genesis, Operation, - RevealedAttach, RevealedData, RevealedValue, Schema, SchemaId, Transition, TransitionBundle, - VoidState, XWitnessId, + AttachState, BundleId, ContractId, DataState, Extension, Genesis, Operation, RevealedAttach, + RevealedData, RevealedValue, Schema, SchemaId, Transition, TransitionBundle, Txid, VoidState, }; use crate::containers::{ConsignmentExt, ToWitnessId}; use crate::contract::OutputAssignment; -use crate::persistence::{StoreTransaction, UpdateRes}; +use crate::persistence::StoreTransaction; #[derive(Debug, Display, Error, From)] #[display(inner)] @@ -50,7 +50,7 @@ pub enum StateError { /// witness {0} can't be resolved: {1} #[display(doc_comments)] - Resolver(XWitnessId, WitnessResolverError), + Resolver(Txid, WitnessResolverError), /// valid (non-archived) witness is absent in the list of witnesses for a /// state transition bundle. @@ -71,30 +71,19 @@ pub enum StateInconsistency { /// contract state {0} is not known. UnknownContract(ContractId), /// a witness {0} is absent from the state data. - AbsentWitness(XWitnessId), + AbsentWitness(Txid), } #[derive(Clone, Eq, PartialEq, Debug, Hash)] pub enum PersistedState { Void, - Amount(Amount, BlindingFactor, AssetTag), + Amount(Amount), // TODO: Use RevealedData Data(DataState, u128), // TODO: Use RevealedAttach Attachment(AttachState, u64), } -impl PersistedState { - pub(crate) fn update_blinding(&mut self, blinding: BlindingFactor) { - match self { - PersistedState::Void => {} - PersistedState::Amount(_, b, _) => *b = blinding, - PersistedState::Data(_, _) => {} - PersistedState::Attachment(_, _) => {} - } - } -} - #[derive(Debug)] pub struct State { provider: P, @@ -139,8 +128,8 @@ impl State

{ pub fn select_valid_witness( &self, - witness_ids: impl IntoIterator>, - ) -> Result> { + witness_ids: impl IntoIterator>, + ) -> Result> { for witness_id in witness_ids { let witness_id = *witness_id.borrow(); if self @@ -158,7 +147,7 @@ impl State

{ &mut self, contract_id: ContractId, bundle: &TransitionBundle, - witness_id: XWitnessId, + witness_id: Txid, resolver: R, ) -> Result<(), StateError

> { let mut updater = self @@ -166,12 +155,13 @@ impl State

{ .update_contract(contract_id) .map_err(StateError::WriteProvider)? .ok_or(StateInconsistency::UnknownContract(contract_id))?; + let bundle_id = bundle.bundle_id(); for transition in bundle.known_transitions.values() { let ord = resolver .resolve_pub_witness_ord(witness_id) .map_err(|e| StateError::Resolver(witness_id, e))?; updater - .add_transition(transition, witness_id, ord) + .add_transition(transition, witness_id, ord, bundle_id) .map_err(StateError::WriteProvider)?; } Ok(()) @@ -193,14 +183,16 @@ impl State

{ .collect::>(); let mut ordered_extensions = BTreeMap::new(); for witness_bundle in consignment.bundled_witnesses() { - for transition in witness_bundle.known_transitions() { + let bundle = witness_bundle.bundle(); + let bundle_id = bundle.bundle_id(); + for (_, transition) in &bundle.known_transitions { let witness_id = witness_bundle.pub_witness.to_witness_id(); let witness_ord = resolver .resolve_pub_witness_ord(witness_id) .map_err(|e| StateError::Resolver(witness_id, e))?; state - .add_transition(transition, witness_id, witness_ord) + .add_transition(transition, witness_id, witness_ord, bundle_id) .map_err(StateError::WriteProvider)?; for (id, used) in &mut extension_idx { if *used { @@ -235,13 +227,19 @@ impl State

{ Ok(()) } - pub fn update_witnesses( + pub fn upsert_witness( &mut self, - resolver: impl ResolveWitness, - after_height: u32, - ) -> Result> { + witness_id: Txid, + witness_ord: WitnessOrd, + ) -> Result<(), StateError

> { self.provider - .update_witnesses(resolver, after_height) + .upsert_witness(witness_id, witness_ord) + .map_err(StateError::WriteProvider) + } + + pub fn update_bundle(&mut self, bundle_id: BundleId, valid: bool) -> Result<(), StateError

> { + self.provider + .update_bundle(bundle_id, valid) .map_err(StateError::WriteProvider) } } @@ -279,7 +277,11 @@ pub trait StateReadProvider { contract_id: ContractId, ) -> Result, Self::Error>; - fn is_valid_witness(&self, witness_id: XWitnessId) -> Result; + fn is_valid_witness(&self, witness_id: Txid) -> Result; + + fn witnesses(&self) -> LargeOrdMap; + + fn invalid_bundles(&self) -> LargeOrdSet; } pub trait StateWriteProvider: StoreTransaction { @@ -298,17 +300,19 @@ pub trait StateWriteProvider: StoreTransaction { contract_id: ContractId, ) -> Result>, Self::Error>; - fn update_witnesses( + fn upsert_witness( &mut self, - resolver: impl ResolveWitness, - after_height: u32, - ) -> Result; + witness_id: Txid, + witness_ord: WitnessOrd, + ) -> Result<(), Self::Error>; + + fn update_bundle(&mut self, bundle_id: BundleId, valid: bool) -> Result<(), Self::Error>; } pub trait ContractStateRead: ContractStateAccess { fn contract_id(&self) -> ContractId; fn schema_id(&self) -> SchemaId; - fn witness_ord(&self, witness_id: XWitnessId) -> Option; + fn witness_ord(&self, witness_id: Txid) -> Option; fn rights_all(&self) -> impl Iterator>; fn fungible_all(&self) -> impl Iterator>; fn data_all(&self) -> impl Iterator>; @@ -323,14 +327,15 @@ pub trait ContractStateWrite { fn add_transition( &mut self, transition: &Transition, - witness_id: XWitnessId, + witness_id: Txid, witness_ord: WitnessOrd, + bundle_id: BundleId, ) -> Result<(), Self::Error>; fn add_extension( &mut self, extension: &Extension, - witness_id: XWitnessId, + witness_id: Txid, witness_ord: WitnessOrd, ) -> Result<(), Self::Error>; } diff --git a/src/persistence/stock.rs b/src/persistence/stock.rs index b43427ee..103bd160 100644 --- a/src/persistence/stock.rs +++ b/src/persistence/stock.rs @@ -24,20 +24,20 @@ use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; use std::convert::Infallible; use std::error::Error; use std::fmt::Debug; +use std::num::NonZeroU32; -use amplify::confinement::{Confined, U24}; +use amplify::confinement::{Confined, LargeOrdSet, U24}; use amplify::Wrapper; -use bp::dbc::Method; use bp::seals::txout::CloseMethod; -use bp::Vout; +use bp::{Outpoint, Txid, Vout}; use chrono::Utc; use invoice::{Amount, Beneficiary, InvoiceState, NonFungible, RgbInvoice}; use nonasync::persistence::{CloneNoPersistence, PersistenceError, PersistenceProvider}; use rgb::validation::{DbcProof, ResolveWitness, WitnessResolverError}; +use rgb::vm::WitnessOrd; use rgb::{ - validation, AssignmentType, BlindingFactor, BundleId, ContractId, DataState, GraphSeal, - Identity, OpId, Operation, Opout, SchemaId, SecretSeal, Transition, TxoSeal, XChain, XOutpoint, - XOutputSeal, XWitnessId, + validation, AssignmentType, BundleId, ChainNet, ContractId, DataState, GraphSeal, Identity, + OpId, Operation, Opout, OutputSeal, SchemaId, SecretSeal, Transition, }; use strict_encoding::FieldName; @@ -51,9 +51,8 @@ use super::{ use crate::containers::{ AnchorSet, AnchoredBundleMismatch, Batch, BuilderSeal, ClientBundle, Consignment, ContainerVer, ContentId, ContentRef, Contract, Fascia, Kit, SealWitness, SupplItem, SupplSub, Transfer, - TransitionDichotomy, TransitionInfo, TransitionInfoError, UnrelatedTransition, - ValidConsignment, ValidContract, ValidKit, ValidTransfer, VelocityHint, WitnessBundle, - SUPPL_ANNOT_VELOCITY, + TransitionInfo, TransitionInfoError, UnrelatedTransition, ValidConsignment, ValidContract, + ValidKit, ValidTransfer, VelocityHint, WitnessBundle, SUPPL_ANNOT_VELOCITY, }; use crate::info::{ContractInfo, IfaceInfo, SchemaInfo}; use crate::interface::{ @@ -62,7 +61,7 @@ use crate::interface::{ }; use crate::MergeRevealError; -pub type ContractAssignments = HashMap>; +pub type ContractAssignments = HashMap>; #[derive(Debug, Display, Error, From)] #[display(inner)] @@ -113,7 +112,7 @@ pub enum StockError< AbsentValidWitness, /// witness {0} can't be resolved: {1} - WitnessUnresolved(XWitnessId, WitnessResolverError), + WitnessUnresolved(Txid, WitnessResolverError), } impl From> @@ -225,6 +224,9 @@ pub enum ComposeError { /// expired invoice. InvoiceExpired, + /// Invoice requesting chain-network pair {0} but contract commits to a different one ({1}) + InvoiceBeneficiaryWrongChainNet(ChainNet, ChainNet), + /// the invoice contains no contract information. NoContract, @@ -526,7 +528,7 @@ impl Stock { /// output seals. pub fn contracts_assigning( &self, - outputs: impl IntoIterator>, + outputs: impl IntoIterator>, ) -> Result + '_, StockError> { let outputs = outputs .into_iter() @@ -610,32 +612,27 @@ impl Stock { pub fn contract_assignments_for( &self, contract_id: ContractId, - outpoints: impl IntoIterator>, + outpoints: impl IntoIterator>, ) -> Result> { - let outputs: BTreeSet = outpoints.into_iter().map(|o| o.into()).collect(); + let outputs: BTreeSet = outpoints.into_iter().map(|o| o.into()).collect(); let state = self.contract_state(contract_id)?; let mut res = - HashMap::>::with_capacity(outputs.len()); + HashMap::>::with_capacity(outputs.len()); for item in state.fungible_all() { let outpoint = item.seal.into(); - if outputs.contains::(&outpoint) { - res.entry(item.seal).or_default().insert( - item.opout, - PersistedState::Amount( - item.state.value.into(), - item.state.blinding, - item.state.tag, - ), - ); + if outputs.contains::(&outpoint) { + res.entry(item.seal) + .or_default() + .insert(item.opout, PersistedState::Amount(item.state.value.into())); } } for item in state.data_all() { let outpoint = item.seal.into(); - if outputs.contains::(&outpoint) { + if outputs.contains::(&outpoint) { res.entry(item.seal).or_default().insert( item.opout, PersistedState::Data(item.state.value.clone(), item.state.salt), @@ -645,7 +642,7 @@ impl Stock { for item in state.rights_all() { let outpoint = item.seal.into(); - if outputs.contains::(&outpoint) { + if outputs.contains::(&outpoint) { res.entry(item.seal) .or_default() .insert(item.opout, PersistedState::Void); @@ -654,7 +651,7 @@ impl Stock { for item in state.attach_all() { let outpoint = item.seal.into(); - if outputs.contains::(&outpoint) { + if outputs.contains::(&outpoint) { res.entry(item.seal).or_default().insert( item.opout, PersistedState::Attachment(item.state.clone().into(), item.state.salt), @@ -670,10 +667,11 @@ impl Stock { issuer: impl Into, schema_id: SchemaId, iface: impl Into, + chain_net: ChainNet, ) -> Result> { Ok(self .stash - .contract_builder(issuer.into(), schema_id, iface)?) + .contract_builder(issuer.into(), schema_id, iface, chain_net)?) } pub fn transition_builder( @@ -720,25 +718,27 @@ impl Stock { &self, contract_id: ContractId, ) -> Result> { - let consignment = self.consign::(contract_id, [], None)?; + let consignment = self.consign::(contract_id, [], None, None)?; Ok(consignment) } pub fn transfer( &self, contract_id: ContractId, - outputs: impl AsRef<[XOutputSeal]>, - secret_seal: Option>, + outputs: impl AsRef<[OutputSeal]>, + secret_seal: Option, + witness_id: Option, ) -> Result> { - let consignment = self.consign(contract_id, outputs, secret_seal)?; + let consignment = self.consign(contract_id, outputs, secret_seal, witness_id)?; Ok(consignment) } fn consign( &self, contract_id: ContractId, - outputs: impl AsRef<[XOutputSeal]>, - secret_seal: Option>, + outputs: impl AsRef<[OutputSeal]>, + secret_seal: Option, + witness_id: Option, ) -> Result, StockError> { let outputs = outputs.as_ref(); @@ -770,16 +770,25 @@ impl Stock { // 1.3. Collect all state transitions assigning state to the provided outpoints let mut anchored_bundles = BTreeMap::::new(); let mut transitions = BTreeMap::::new(); - let mut terminals = BTreeMap::>::new(); + let mut terminals = BTreeMap::::new(); for opout in opouts { if opout.op == contract_id { continue; // we skip genesis since it will be present anywhere } let transition = self.transition(opout.op)?; - transitions.insert(opout.op, transition.clone()); let bundle_id = self.index.bundle_id_for_op(transition.id())?; + + // skip bundles not associated to the terminals witness + if let Some(witness_id) = witness_id { + let (mut witness_ids, _) = self.index.bundle_info(bundle_id)?; + if !witness_ids.any(|w| w == witness_id) { + continue; + } + } + + transitions.insert(opout.op, transition.clone()); // 2. Collect secret seals from terminal transitions to add to the consignment terminals for typed_assignments in transition.assignments.values() { for index in 0..typed_assignments.len_u16() { @@ -856,15 +865,12 @@ impl Stock { } let ifaces = Confined::from_checked(ifaces); - let mut bundles = BTreeMap::::new(); + let mut bundles = BTreeMap::::new(); for anchored_bundle in anchored_bundles.into_values() { let witness_ids = self.index.bundle_info(anchored_bundle.bundle_id())?.0; let witness_id = self.state.select_valid_witness(witness_ids)?; let pub_witness = self.stash.witness(witness_id)?.public.clone(); - let wb = match bundles.remove(&witness_id) { - Some(bundle) => bundle.into_double(anchored_bundle)?, - None => WitnessBundle::with(pub_witness, anchored_bundle), - }; + let wb = WitnessBundle::with(pub_witness, anchored_bundle); let res = bundles.insert(witness_id, wb); debug_assert!(res.is_none()); } @@ -908,19 +914,16 @@ impl Stock { pub fn compose( &self, invoice: &RgbInvoice, - prev_outputs: impl IntoIterator>, - method: CloseMethod, + prev_outputs: impl IntoIterator>, beneficiary_vout: Option>, allocator: impl Fn(ContractId, AssignmentType, VelocityHint) -> Option, ) -> Result> { self.compose_deterministic( invoice, prev_outputs, - method, beneficiary_vout, u64::MAX, allocator, - |_, _| BlindingFactor::random(), |_, _| rand::random(), ) } @@ -932,19 +935,16 @@ impl Stock { pub fn compose_deterministic( &self, invoice: &RgbInvoice, - prev_outputs: impl IntoIterator>, - method: CloseMethod, + prev_outputs: impl IntoIterator>, beneficiary_vout: Option>, priority: u64, allocator: impl Fn(ContractId, AssignmentType, VelocityHint) -> Option, - pedersen_blinder: impl Fn(ContractId, AssignmentType) -> BlindingFactor, seal_blinder: impl Fn(ContractId, AssignmentType) -> u64, ) -> Result> { - let layer1 = invoice.layer1(); let prev_outputs = prev_outputs .into_iter() .map(|o| o.into()) - .collect::>(); + .collect::>(); #[allow(clippy::type_complexity)] let output_for_assignment = @@ -968,9 +968,8 @@ impl Stock { .unwrap_or_default(); let vout = allocator(id, assignment_type, velocity) .ok_or(ComposeError::NoBlankOrChange(velocity, assignment_type))?; - let seal = - GraphSeal::with_blinded_vout(method, vout, seal_blinder(id, assignment_type)); - Ok(BuilderSeal::Revealed(XChain::with(layer1, seal))) + let seal = GraphSeal::with_blinded_vout(vout, seal_blinder(id, assignment_type)); + Ok(BuilderSeal::Revealed(seal)) }; // 1. Prepare the data @@ -993,25 +992,26 @@ impl Stock { .assignments_type(&assignment_name) .ok_or(BuilderError::InvalidStateField(assignment_name.clone()))?; - // If there are inputs which are using different seal closing method from our - // wallet (and thus main state transition) we need to put them aside and - // allocate a different state transition spending them as a change. - let mut alt_builder = - self.transition_builder(contract_id, iface.clone(), invoice.operation.clone())?; - let mut alt_inputs = Vec::::new(); + let contract_genesis = self.stash.genesis(contract_id)?; + let contract_chain_net = contract_genesis.chain_net; + let invoice_chain_net = invoice.chain_network(); + if contract_chain_net != invoice_chain_net { + return Err(ComposeError::InvoiceBeneficiaryWrongChainNet( + invoice_chain_net, + contract_chain_net, + ) + .into()); + } - let layer1 = invoice.beneficiary.chain_network().layer1(); let beneficiary = match (invoice.beneficiary.into_inner(), beneficiary_vout) { - (Beneficiary::BlindedSeal(seal), None) => { - BuilderSeal::Concealed(XChain::with(layer1, seal)) - } + (Beneficiary::BlindedSeal(seal), None) => BuilderSeal::Concealed(seal), (Beneficiary::BlindedSeal(_), Some(_)) => { return Err(ComposeError::BeneficiaryVout.into()); } - (Beneficiary::WitnessVout(payload), Some(vout)) => { + (Beneficiary::WitnessVout(_), Some(vout)) => { let blinding = seal_blinder(contract_id, assignment_id); - let seal = GraphSeal::with_blinded_vout(payload.method, vout, blinding); - BuilderSeal::Revealed(XChain::with(layer1, seal)) + let seal = GraphSeal::with_blinded_vout(vout, blinding); + BuilderSeal::Revealed(seal) } (Beneficiary::WitnessVout(_), None) => { return Err(ComposeError::NoBeneficiaryOutput.into()); @@ -1019,49 +1019,22 @@ impl Stock { }; // 2. Prepare transition - let mut main_inputs = Vec::::new(); + let mut main_inputs = Vec::::new(); let mut sum_inputs = Amount::ZERO; - let mut sum_alt = Amount::ZERO; let mut data_inputs = vec![]; - let mut data_main = true; - let lookup_state = - if let InvoiceState::Data(NonFungible::RGB21(allocation)) = &invoice.owned_state { - Some(DataState::from(*allocation)) - } else { - None - }; for (output, list) in self.contract_assignments_for(contract_id, prev_outputs.iter().copied())? { - if output.method() == method { - main_inputs.push(output) - } else { - alt_inputs.push(output) - }; - for (opout, mut state) in list { - if output.method() == method { - main_builder = main_builder.add_input(opout, state.clone())?; - } else { - alt_builder = alt_builder.add_input(opout, state.clone())?; - } + main_inputs.push(output); + for (opout, state) in list { + main_builder = main_builder.add_input(opout, state.clone())?; if opout.ty != assignment_id { let seal = output_for_assignment(contract_id, opout.ty)?; - state.update_blinding(pedersen_blinder(contract_id, assignment_id)); - if output.method() == method { - main_builder = main_builder.add_owned_state_raw(opout.ty, seal, state)?; - } else { - alt_builder = alt_builder.add_owned_state_raw(opout.ty, seal, state)?; - } - } else if let PersistedState::Amount(value, _, _) = state { + main_builder = main_builder.add_owned_state_raw(opout.ty, seal, state)?; + } else if let PersistedState::Amount(value) = state { sum_inputs += value; - if output.method() != method { - sum_alt += value; - } } else if let PersistedState::Data(value, _) = state { - if lookup_state.as_ref() == Some(&value) && output.method() != method { - data_main = false; - } data_inputs.push(value); } } @@ -1074,46 +1047,18 @@ impl Stock { return Err(ComposeError::InsufficientState.into()); } - let sum_main = sum_inputs - sum_alt; - let (paid_main, paid_alt) = - if sum_main < amt { (sum_main, amt - sum_main) } else { (amt, Amount::ZERO) }; - let blinding_beneficiary = pedersen_blinder(contract_id, assignment_id); - - if paid_main > Amount::ZERO { - main_builder = main_builder.add_fungible_state_raw( - assignment_id, - beneficiary, - paid_main, - blinding_beneficiary, - )?; + if amt > Amount::ZERO { + main_builder = + main_builder.add_fungible_state_raw(assignment_id, beneficiary, amt)?; } - if paid_alt > Amount::ZERO { - alt_builder = alt_builder.add_fungible_state_raw( - assignment_id, - beneficiary, - paid_alt, - blinding_beneficiary, - )?; - } - - let blinding_change = pedersen_blinder(contract_id, assignment_id); - let change_seal = output_for_assignment(contract_id, assignment_id)?; // Pay change - if sum_main > paid_main { + if sum_inputs > amt { + let change_seal = output_for_assignment(contract_id, assignment_id)?; main_builder = main_builder.add_fungible_state_raw( assignment_id, change_seal, - sum_main - paid_main, - blinding_change, - )?; - } - if sum_alt > paid_alt { - alt_builder = alt_builder.add_fungible_state_raw( - assignment_id, - change_seal, - sum_alt - paid_alt, - blinding_change, + sum_inputs - amt, )?; } } @@ -1125,21 +1070,8 @@ impl Stock { } let seal = seal_blinder(contract_id, assignment_id); - if data_main { - main_builder = main_builder.add_data_raw( - assignment_id, - beneficiary, - allocation, - seal, - )?; - } else { - alt_builder = alt_builder.add_data_raw( - assignment_id, - beneficiary, - allocation, - seal, - )?; - } + main_builder = + main_builder.add_data_raw(assignment_id, beneficiary, allocation, seal)?; } }, _ => { @@ -1152,96 +1084,50 @@ impl Stock { // 3. Prepare other transitions // Enumerate state - let mut spent_state = - HashMap::>>::new(); + let mut blank_state = + HashMap::>>::new(); for id in self.contracts_assigning(prev_outputs.iter().copied())? { // Skip current contract if id == contract_id { continue; } let state = self.contract_assignments_for(id, prev_outputs.iter().copied())?; - let entry = spent_state.entry(id).or_default(); + let entry = blank_state.entry(id).or_default(); for (seal, assigns) in state { entry.entry(seal).or_default().extend(assigns); } } // Construct blank transitions - let mut blanks = Confined::, 0, { U24 - 1 }>::with_capacity(spent_state.len()); - for (id, list) in spent_state { - let mut blank_builder_tapret = self.blank_builder(id, iface.clone())?; - let mut blank_builder_opret = self.blank_builder(id, iface.clone())?; - let mut outputs_tapret = Vec::with_capacity(list.len()); - let mut outputs_opret = Vec::with_capacity(list.len()); + let mut blanks = Confined::, 0, { U24 - 1 }>::with_capacity(blank_state.len()); + for (id, list) in blank_state { + let mut blank_builder = self.blank_builder(id, iface.clone())?; + let mut outputs = Vec::with_capacity(list.len()); for (output, assigns) in list { - match output.method() { - Method::TapretFirst => outputs_tapret.push(output), - Method::OpretFirst => outputs_opret.push(output), - } + outputs.push(output); for (opout, state) in assigns { let seal = output_for_assignment(id, opout.ty)?; - match output.method() { - Method::TapretFirst => { - blank_builder_tapret = blank_builder_tapret - .add_input(opout, state.clone())? - .add_owned_state_raw(opout.ty, seal, state)? - } - Method::OpretFirst => { - blank_builder_opret = blank_builder_opret - .add_input(opout, state.clone())? - .add_owned_state_raw(opout.ty, seal, state)? - } - } + blank_builder = blank_builder + .add_input(opout, state.clone())? + .add_owned_state_raw(opout.ty, seal, state)? } } - - let mut dicho = vec![]; - for (blank_builder, outputs) in - [(blank_builder_tapret, outputs_tapret), (blank_builder_opret, outputs_opret)] - { - if !blank_builder.has_inputs() { - continue; - } - let transition = blank_builder.complete_transition()?; - let info = TransitionInfo::new(transition, outputs).map_err(|e| { - debug_assert!(!matches!(e, TransitionInfoError::CloseMethodDivergence(_))); - ComposeError::TooManyInputs - })?; - dicho.push(info); + if !blank_builder.has_inputs() { + continue; } - blanks - .push(TransitionDichotomy::from_iter(dicho)) - .map_err(|_| ComposeError::TooManyBlanks)?; + let transition = blank_builder.complete_transition()?; + let info = TransitionInfo::new(transition, outputs) + .map_err(|_| ComposeError::TooManyInputs)?; + blanks.push(info).map_err(|_| ComposeError::TooManyBlanks)?; } - let (first_builder, first_inputs, second_builder, second_inputs) = - match (main_builder.has_inputs(), alt_builder.has_inputs()) { - (true, true) => (main_builder, main_inputs, Some(alt_builder), alt_inputs), - (true, false) => (main_builder, main_inputs, None, alt_inputs), - (false, true) => (alt_builder, alt_inputs, None, main_inputs), - (false, false) => return Err(ComposeError::InsufficientState.into()), - }; - let first = TransitionInfo::new(first_builder.complete_transition()?, first_inputs) - .map_err(|e| { - debug_assert!(!matches!(e, TransitionInfoError::CloseMethodDivergence(_))); - ComposeError::TooManyInputs - })?; - let second = if let Some(second_builder) = second_builder { - Some( - TransitionInfo::new(second_builder.complete_transition()?, second_inputs).map_err( - |e| { - debug_assert!(!matches!(e, TransitionInfoError::CloseMethodDivergence(_))); - ComposeError::TooManyInputs - }, - )?, - ) - } else { - None - }; - let mut batch = Batch { - main: TransitionDichotomy::with(first, second), - blanks, - }; + if !main_builder.has_inputs() { + return Err(ComposeError::InsufficientState.into()); + } + + let main = TransitionInfo::new(main_builder.complete_transition()?, main_inputs) + .map_err(|_| ComposeError::TooManyInputs)?; + let mut batch = Batch { main, blanks }; batch.set_priority(priority); Ok(batch) } @@ -1369,19 +1255,14 @@ impl Stock { let bundle = self.stash.bundle(bundle_id)?.clone(); let witness_id = self.state.select_valid_witness(witness_ids)?; let witness = self.stash.witness(witness_id)?; - let (merkle_block, dbc) = match (bundle.close_method, &witness.anchors) { - ( + let (merkle_block, dbc, close_method) = match &witness.anchor { + AnchorSet::Tapret(tapret) => ( + &tapret.mpc_proof, + DbcProof::Tapret(tapret.dbc_proof.clone()), CloseMethod::TapretFirst, - AnchorSet::Tapret(tapret) | AnchorSet::Double { tapret, .. }, - ) => (&tapret.mpc_proof, DbcProof::Tapret(tapret.dbc_proof.clone())), - ( - CloseMethod::OpretFirst, - AnchorSet::Opret(opret) | AnchorSet::Double { opret, .. }, - ) => (&opret.mpc_proof, DbcProof::Opret(opret.dbc_proof)), - _ => { - return Err( - StashInconsistency::BundleMissedInAnchors(bundle_id, contract_id).into() - ); + ), + AnchorSet::Opret(opret) => { + (&opret.mpc_proof, DbcProof::Opret(opret.dbc_proof), CloseMethod::OpretFirst) } }; let Ok(mpc_proof) = merkle_block.to_merkle_proof(contract_id.into()) else { @@ -1389,7 +1270,7 @@ impl Stock { witness_id, bundle_id, contract_id, - CloseMethod::OpretFirst, + close_method, ) .into()); }; @@ -1399,26 +1280,218 @@ impl Stock { Ok(ClientBundle::new(mpc_proof, dbc, bundle)) } - pub fn store_secret_seal( + pub fn store_secret_seal(&mut self, seal: GraphSeal) -> Result> { + Ok(self.stash.store_secret_seal(seal)?) + } + + fn set_bundles_as_invalid(&mut self, bundle_id: &BundleId) -> Result<(), StockError> { + // add bundle to set of invalid bundles + self.state.update_bundle(*bundle_id, false)?; + let bundle = self.stash.bundle(*bundle_id)?.clone(); + // recursively set all bundle descendants as invalid + for opid in bundle.known_transitions.keys() { + let children_bundle_ids = match self.index.bundle_ids_children_of_op(*opid) { + Ok(bundle_ids) => bundle_ids, + Err(IndexError::Inconsistency(IndexInconsistency::BundleAbsent(_))) => { + // this transition has no children yet + return Ok(()); + } + Err(e) => return Err(e.into()), + }; + + for child_bundle_id in children_bundle_ids { + self.set_bundles_as_invalid(&child_bundle_id)?; + } + } + Ok(()) + } + + fn maybe_update_bundles_as_valid( &mut self, - seal: XChain, + bundle_id: &BundleId, + invalid_bundles: &mut LargeOrdSet, + maybe_became_valid_bundle_ids: &mut BTreeSet, ) -> Result> { - Ok(self.stash.store_secret_seal(seal)?) + let bundle = self.stash.bundle(*bundle_id)?.clone(); + let mut valid = true; + // recursively visit bundle ancestors + for transition in bundle.known_transitions.values() { + for input in &transition.inputs { + let input_opid = input.prev_out.op; + let input_bundle_id = match self.index.bundle_id_for_op(input_opid) { + Ok(id) => Some(id), + Err(IndexError::Inconsistency(IndexInconsistency::BundleAbsent(_))) => { + // reached genesis + None + } + Err(e) => return Err(e.into()), + }; + + if let Some(input_bundle_id) = input_bundle_id { + // process parent first if its status is also uncertain + if maybe_became_valid_bundle_ids.contains(&input_bundle_id) { + valid = self.maybe_update_bundles_as_valid( + &input_bundle_id, + invalid_bundles, + maybe_became_valid_bundle_ids, + )?; + // a single invalid parent is enough to consider the bundle as invalid + } else if invalid_bundles.contains(&input_bundle_id) { + valid = false; + break; + } + } + } + } + + // remove bundle since at this point we are sure about its status + maybe_became_valid_bundle_ids.remove(bundle_id); + + if valid { + // remove bundle from set of invalid bundles + self.state.update_bundle(*bundle_id, true)?; + invalid_bundles.remove(bundle_id).unwrap(); + // recursively visit bundle descendants to check if they became valid as well + for (opid, _transition) in bundle.known_transitions { + let children_bundle_ids = match self.index.bundle_ids_children_of_op(opid) { + Ok(bundle_ids) => bundle_ids, + Err(IndexError::Inconsistency(IndexInconsistency::BundleAbsent(_))) => { + // this transition has no children yet + tiny_bset![] + } + Err(e) => return Err(e.into()), + }; + for child_bundle_id in children_bundle_ids { + self.maybe_update_bundles_as_valid( + &child_bundle_id, + invalid_bundles, + maybe_became_valid_bundle_ids, + )?; + } + } + } + + Ok(valid) + } + + fn update_witness_ord( + &mut self, + resolver: impl ResolveWitness, + id: &Txid, + ord: &mut WitnessOrd, + became_invalid_witnesses: &mut BTreeMap>, + became_valid_witnesses: &mut BTreeMap>, + ) -> Result<(), StockError> { + let new = resolver + .resolve_pub_witness_ord(*id) + .map_err(|e| StockError::WitnessUnresolved(*id, e))?; + let changed = *ord != new; + if changed { + let bundle_valid = match (*ord, new) { + (WitnessOrd::Archived, _) => Some(true), + (_, WitnessOrd::Archived) => Some(false), + _ => None, + }; + // save witnesses that became valid or invalid + if let Some(valid) = bundle_valid { + let seal_witness = self.stash.witness(*id)?; + let anchor_set = seal_witness.anchor.clone(); + let bundle_ids: BTreeSet<_> = anchor_set.known_bundle_ids().collect(); + if valid { + became_valid_witnesses.insert(*id, bundle_ids); + } else { + became_invalid_witnesses.insert(*id, bundle_ids); + } + } + // save the changed witness ord + self.state.upsert_witness(*id, new)?; + *ord = new + } + Ok(()) } pub fn update_witnesses( &mut self, resolver: impl ResolveWitness, after_height: u32, + force_witnesses: Vec, ) -> Result> { - Ok(self.state.update_witnesses(resolver, after_height)?) + let after_height = NonZeroU32::new(after_height).unwrap_or(NonZeroU32::MIN); + let mut succeeded = 0; + let mut failed = map![]; + self.state.begin_transaction()?; + let witnesses = self.as_state_provider().witnesses(); + let mut witnesses = witnesses.release(); + let mut became_invalid_witnesses = bmap!(); + let mut became_valid_witnesses = bmap!(); + // 1. update witness ord of all witnesses + for (id, ord) in &mut witnesses { + if matches!(ord, WitnessOrd::Ignored) && !force_witnesses.contains(id) { + continue; + } + if matches!(ord, WitnessOrd::Mined(pos) if pos.height() < after_height) { + continue; + } + match self.update_witness_ord( + &resolver, + id, + ord, + &mut became_invalid_witnesses, + &mut became_valid_witnesses, + ) { + Ok(()) => { + succeeded += 1; + } + Err(err) => { + failed.insert(*id, err.to_string()); + } + } + } + + // 2. set invalidity of bundles + for bundle_ids in became_invalid_witnesses.values() { + for bundle_id in bundle_ids { + let bundle_witness_ids: BTreeSet = + self.index.bundle_info(*bundle_id)?.0.collect(); + // set bundle as invalid only if there are no valid witnesses associated to it + if bundle_witness_ids + .iter() + .all(|id| !witnesses.get(id).unwrap().is_valid()) + { + // set this bundle and all its descendants as invalid + self.set_bundles_as_invalid(bundle_id)?; + } + } + } + + // 3. set validity of bundles + let mut maybe_became_valid_bundle_ids = bset!(); + // get all bundles that became invalid and ones that were already invalid + let mut invalid_bundles_pre = self.as_state_provider().invalid_bundles(); + for bundle_ids in became_valid_witnesses.values() { + // store bundles that may become valid (to be sure its ancestors are checked) + maybe_became_valid_bundle_ids.extend(bundle_ids); + } + for bundle_ids in became_valid_witnesses.values() { + for bundle_id in bundle_ids { + // check if this bundle and its descendants are now valid + self.maybe_update_bundles_as_valid( + bundle_id, + &mut invalid_bundles_pre, + &mut maybe_became_valid_bundle_ids, + )?; + } + } + + self.state.commit_transaction()?; + Ok(UpdateRes { succeeded, failed }) } } #[derive(Clone, Eq, PartialEq, Debug)] pub struct UpdateRes { pub succeeded: usize, - pub failed: HashMap, + pub failed: HashMap, } #[cfg(test)] @@ -1435,17 +1508,14 @@ mod test { #[test] fn test_consign() { let mut stock = Stock::in_memory(); - let seal = XChain::with( - rgbcore::Layer1::Bitcoin, - GraphSeal::new_random_vout(bp::dbc::Method::OpretFirst, Vout::from_u32(0)), - ); + let seal = GraphSeal::new_random_vout(Vout::from_u32(0)); let secret_seal = seal.conceal(); stock.store_secret_seal(seal).unwrap(); let contract_id = ContractId::from_baid64_str("rgb:qFuT6DN8-9AuO95M-7R8R8Mc-AZvs7zG-obum1Va-BRnweKk") .unwrap(); - if let Ok(transfer) = stock.consign::(contract_id, [], Some(secret_seal)) { + if let Ok(transfer) = stock.consign::(contract_id, [], Some(secret_seal), None) { println!("{:?}", transfer.supplements) } } diff --git a/src/stl/stl.rs b/src/stl/stl.rs index c0243564..62554f30 100644 --- a/src/stl/stl.rs +++ b/src/stl/stl.rs @@ -41,7 +41,7 @@ use crate::LIB_NAME_RGB_STD; /// Strict types id for the library providing standard data types which may be /// used in RGB smart contracts. pub const LIB_ID_RGB_STORAGE: &str = - "stl:mG$H7b6I-$T8qp18-07PSNeA-rbEBNS5-$J5X4y0-1vPxRWg#channel-vortex-bandit"; + "stl:AOyFCu23-oOZoMMm-ErRT1U!-rpjrpSt-IAXu8FP-s1NpBXQ#spark-sandra-alice"; /// Strict types id for the library providing standard data types which may be /// used in RGB smart contracts. @@ -50,7 +50,7 @@ pub const LIB_ID_RGB_CONTRACT: &str = /// Strict types id for the library representing of RGB StdLib data types. pub const LIB_ID_RGB_STD: &str = - "stl:JhUC5JgH-Kwps4cO-ZNUklUj-UP6boFp-OY!18Kx-xOSJaVQ#hair-magnum-helena"; + "stl:68OpONV0-a6jRyu4-WwnfWw$-NmcHSI0-kpc!Ppp-YBckCAo#lazarus-list-uniform"; fn _rgb_std_stl() -> Result { LibBuilder::new(libname!(LIB_NAME_RGB_STD), tiny_bset! { diff --git a/stl/RGBStd@0.11.0.sta b/stl/RGBStd@0.11.0.sta index 5c9d924c..fc0bba19 100644 --- a/stl/RGBStd@0.11.0.sta +++ b/stl/RGBStd@0.11.0.sta @@ -1,311 +1,302 @@ -----BEGIN STRICT TYPE LIB----- -Id: stl:JhUC5JgH-Kwps4cO-ZNUklUj-UP6boFp-OY!18Kx-xOSJaVQ#hair-magnum-helena +Id: stl:YgyNu!Qt-mt5DMxt-GXH55TN-bmrTwZH-o11V0B$-$jxMrfE#juliet-vega-richard Name: RGBStd Dependencies: - RGBCommit#harvest-person-orion, + BPCore#symbol-tropic-grand, StrictTypes#century-comrade-chess, - BPCore#austin-story-retro, AluVM#congo-archive-folio, CommitVerify#miller-pancake-elastic, + RGBCommit#raymond-open-organic, Std#ralph-blue-lucky, Bitcoin#signal-color-cipher -Check-SHA256: 6a9228bc3dd61ed396d19a0d3e71c3a3dfc999d232e57ec13c1488bb0b6eeb91 +Check-SHA256: 48b79da50a92f08ef630d9ed1bb0ae4224154a3bef9f84a4187df086330af8cb -22w{tQ*>kpAXg`>_lQgbaV_>=c$Ts04O39g2dD_h*R5>c*5<{j2~tNwLvL+uX>>*EqhH(h&*4NaBbD49mT$3z|G4nQgoFBhHh%l@K06L}1!AJ%| -P(yEWWnyqOe<9`Lptgpr6F_xjAC6(~TLj#*ewiHU&X!byiJ!10COKearHwcS=7M7YzYaI8*bv -hMOc?)(rkC#nUDXLvL+uX>?X)a%pCH$}AplgPGkh3_fq3Q7_j=2#kPT_9!;lWR>~GYywm#15kpA#kgq^`I&ZzC?)!&R01Y?(H9FO$CR6P1%k7c67A-20~CnZ*pZt>Z4!V_T!KNI`QJ|h6;Zj +^jB$MPK+?7Lu3>C`4HI)Q*?4^V{}w`aAk91a5aA+<>R2XhQO_4{AcS-HH^7AVzASV8M4NYxyCjHL2Pwa +O?m?z-)Viz@~C%8KNS}Z0aQ3s^SOqbBwN-D{wl@OCJaMwZEb0ER%LQ&W_h20XiL(ap`B(@2KpYTJ%x(D +C3d{wiWYg@TKk|G2{Q>&M?ynyZEb0E$}AplgPGkh3_fq3Q7_j=2#kPT_9!;lWR>~GYywm#15DT%6aZ| SrJerP1pIOD57`7Ol|-ogQ6Pjg~y>s-v>!^VNPLfWv4Jz0xkJm$nc4yMWR2J-cc#Q6SofWC)gp7L6!Sc 3I$AQVo7AP4Jk3r!|EoW{Zi$060oMN(jLzPuNboiNpoRSWoOdj7+WWC1?EKi+6QrwlvP$n -l8x-M691f9z+~t)>6ivgX<}1lX9hx0LvM0r3IG9o2VDR_OBR)w8yCZ2EylR&t_^>1Sz?kFbz0>alMxYA +l8x-M691f9z+~t)>6ivgX<}1lX9hx0LvM0r2>=0n2VDR_OBR)w8yCZ2EylR&t_^>1Sz?kFbz0>alMxYA VQ_L~bWU$%Wl&*qbZ%vG54IneKN{_;j(f`H9IfkFzO$PGD6U0+e -W+%HuC5$^~^vuG3{`}-8x6fV={eh1!etXz_4^&}ra%FT-VRUFva&K>DF1HXRxo%|^+Itiop&gxXSvq){ -{YhrGf57_P)SQy*22EvjXm4aVKVmL%Q_{#Gkvz+H9iKg9-*)mSRaq_gMnjYqO>G4cRAF#(Wpq+$XJ~Xn -a$#;`XhtWfE>N`F8f<{_M@^MEhcVy#omh=bI-rl&{j_4Y)eb^zX>MdwWnpYocu;h5M^4XN(CAD)cag{3QuryWpq$-Z*OL38SA{&vly$FvzVnzHf7z~rv`86=_Ka^V5yX|y#`JS -Q)OdvWpq?<6X>Jq%0U2$DDaiKPL`@Y=jhu|Vo)3+Q0$Mw; -ks-!CQm`I}1yf~lPHzeskk?c43YBIb6Fc=IN+pl}OUT^`C!`zX1ig-;MydoD@qdC-Hdlhx3aZBNPbr@aHF*SPB$t~%I3sYlqX>fEx -d30rSF}tqlgo$^>um>@6G0l?pFt#Zz&53{9y57aQ#OZ(83shlnPH$voNMUnmHQF5&IUsJk-Q1+ZJ%=&s -@|&mHbl*M5f*>4D7PYw?2uyEdYgB1%WjJ*Nu}gdoMr}u)7e{?0bR>WH17z$yORD!eAooFZYY9_nXH#Qx -X>fF3tl4elKTgFI*|CjhfZ7VH>n$b={WmS6z+ej~gaaD&)?_rinzL -Q&_n0fy*YdyZ9}hJM#rpcu#e7m-W{MLar(^k|jH+P94s~ljFZW({ZtfbA~le%!q<(1XE#jbDdR_th)Kl -;F~x`_=5>?(>Td5ZgsqT;~+(zt2h~^9tT%xbZ%vHbEASn^UK%K(4i9Ajp1M~R@C@!4#dQE#lUD;OiKi1 -Rs>XdX=JE;#(89COl4taR%LR& -{2u&fr5XKXQffLAhd}4?5G@P7|2n}&PV@Ibc63|}Q)6;zaCA_0Vryl2#Bytok0{Z4!I#J#jt!xkVnm$g -&}3cy$LV-HwTJPe2SRytWm9x=#d{%|zxO$Aaz=oyMOH6-?4fLKKPKJW|NMSz1LoXB0#tbDYCz3gCHcML -g#T%!5i+MiDe1kloHngE|MP04pL=vWpZ|9WI}m#WpgzCf)+{N -c)mXTm=OBn8@DNvJ^I(u7Ttc@lJ^C)`OzK@Qe|^xa&~28LV0v$b2tf7M?ynyZEb0EL;wS50?er0_e!9% -6%WL6o5Q7yVM7GXa@w44CHDB`4cre!cywiMb7^mGQ)6glZD9j@leIk>g)RqK0VQ|Mwn6X+txo3vSYd;; -z)HQ~0$d0}b#7#AWl3ZSwto`e>uZ$?1z+)WysMU3t2e*FfKh32^DD>YKF13Ts`WEp!#kMM{I9mVQf}mY;|RG6eT>4P{pQ?3(@m6s4{*=wy-PiS_k>W -l|t&*Fr0fZ2~A~mVOC*mb!8QqXJpH@t3U@-^C5At>@@qQFQ2KNd+8eYXv4en`-lihZg6#UO<`~tNY&HC -T(P)^FVARS*Zg3m2dUS*m(weL9PhQe$_)h#M`dnhb7^x^V`ybEPw9I -@e~jMZwd)2j0{0+bWCA+WpXi7WppJ)biTp4ZzpWVEhda;c-OlKZN9QQ?CZI;=cI(fPVx{>cWz~5Q*>c; -Wm98lWo=<8B@PC`naz9~L0@lerBKV`$$1fC6#s{=m+2p6@mtIZL349ubW~wyb1t%_{ujV7L@=1(T$>wO -Y}Ov_b`4?P%YY`+Wb+o`y9rirX=GD$VRU6Oo>ox?`Aroor<$W|05z3@o%yggc;Wi(O`t`n9TUcD*&5hFi^PVx{q1b@^7zTcrn*%qZTXbx0zVQzD2bZKvHRC#b^Ho-KZ`k;Xmr`<4s -JYKN!!u{G5u+^j1lf!PF4>GEG3r}NXb#iiLZewM0IVbbqN^4g)WDG0#SSGl-+Q@e<+6H_!d>A}?>eT16ofolpo#8 -?XuHZHx7d=!p7E)2#$3bL349yXKrm}Zgg`(Y-w&}Q)OXnRCrKyaz^du!w4MxxaL=+DqP^k2!wz9AHH68 -xp8!<%Jqp^&I?vyY-Mg^c~p6DWk|gmZWsH8I~II?C0;dW+k!*yDqgzlqQwf$39g<|8WK=tWMy)5Wo|=n -ZEb0EZDnqBN@#iqkT|?l*=bx{^0c**fmF&H)l(b`S3$sb4!MK-5kqfoV`X7%Wn@NmZf9v?Y-Ljs%|ogz -QLxC5#{z1Bs(ImjcZKu%4y_xMoB3q3{238PY;R&=Y*Tb$bY)XxXk~3-Q>XLl0V(0al ->0fVsbCfs)I{K8&2}O8xWo~n6Z*Ei2ZB|09R9osd9G^&mV=@u*B|k@iff^?C=mvC@noA);b8~5DZc=4- -WnpY(WI=RvVPj}QY-w&}Q)OXnRCsA*T5oByCBEN9T=>W0>u%$${;`BKEO$VG0b8(5pxNmH8B}?2Wn@8f -b7^O8b3$xsZe&wsVQf@*X=GZDa|tC)BU>oS@xONigke(HCtahRyiRHf-TMdwWnpYocxhy0bsj>g6`?#s5rWnKhSeO?L~x^!;Y#eFP|P}0Z%Ez^MR;^&ZgXjGZd7@2Wo<;p^e<`! -Iztr?rsl#d#OQkEER^^L)C{HEhxT=ipb%1Jc4c8~Wn@NmZf9v?Y-Ml_We~E0fo~tTJ>?Q(lLJ=>rBY$7 -0^roXTE)+&>In@)Z*F5{VQgh&L}7Gcb>vO>-_DBy8`Vb0jGrW9$=2qSMXvL3HlVN`i= -Wp=e2Xp5rzopjE#5h98`u~h0v`BV8NkLOrpFzp4z*br25VQzD2bZKvHQ)6glZDD(|HElq4!)_b{H>!() -nCt8iM0hjp5N|z=I>OKHojw{=d2nT9L349yXKr&sY-w&}Q)OXnRCrKya)BP_mkyA>T}tj_kdvFcMGT4` -fC%jFncQ)?C=$=&Q6NEcb7^O8Qe}2!VQgh&L}7GcLTqVnWK(5fY*ctqbaH|W4XEgn0epQ -k*PX+nL>xOm%pK>soN7+Lug@XZbEEnZe&wsVQf@*X=H?P4U;TR^uxCZOKFR+hj1x=IbKf -Z0H=mhJ>?uV^xB4~9n`Dx!RtcK)nwJGn -aBp>VlfaZ*5|&qoaMx&cZSO)Ho!_*yjLvyQo1^f$X+6j;96@t)X=iR$Z)s#xbYXO5LTqVnWK(5fY*ct@ -WRz0V+XJhss8OG%_CC-Q>(otsF+cqN0Qy}ddQ=3E5C~IaXk~3-No1AC=6W7=VqesjRYGc!>wZFzp>JB4 -@xD;^wu&SY_r(NHa7kpJ2rNlD$O59e#ogQsB77jPl+h5j^*S;NLvL<$a$#e1No1ysFp)<~ -$~wYgjK`HkjV#@&#T1_fGnK3MJXK)_7bXoxb#7;AVr*qobYXO5siJyUlgOLOB};96cGdSG6&iv=7PD~j -ruGj4o;;a=21#ykb#!y8wrKJIUBJXnP(l%Y$cDDuY1Bm#?@QxYCjWldxIc>!SVL%GX>L$;VpnN&Ze??G -uZ@?{0aPfN4Did>Ze%hHN@6KPlLd+s#TneAz-EYx5L9wuZgXjLX>V>qb#7#AWwz*mh8!q$B6|*YuiTY; -OURW8#d%1{rxIXtTaY^?oCrx|Wo~q7ba}{Yf_n>Eea4XlBy!~v3=AX`3Ri2tjjmWpq?wXVr~g2n?Horiuqf0^m>2O`jNR -ziT$b7#=ya6uYYC;sr@=aCLOm?vf5kh_h+&YE#h%O8d1V_{UOl9{V;uR#^q%R5PSyeIwjVvMyte)HLS3WfgRB~Z%b7^#GZ*JDSGqJ&TQwZPkn|ZOr{h9VN -EFkRYIec?G`g2UV1s5Vgb8~5DZc=4-WnpY(WI=RvVPj}QY-w&}Q)OXnRCrKya@w0w6Id2jc94hrndMfL -ayEe1ISdA&%p{mB1!VWk)dNOmcG|`19mwqd!6t9MpF6k$l8zT&IM0)BxIjDir5zArRUtuhb7^O8Qe}2! -VQgh&R$**)WkPIeZe&wsVQf@*P;_$Jidq_i6cBYN^7xEELu$lFU37Sf$J;ty5yrmOX|)6pSVL%GX>LWpmymk!z-`g4hv-$6z_Y -xoLZ_neUP>BpbEf7FA*KKfDV^Y;R&=Y*Tb$bY;{@O*mP8`7qV21dnrCyk{{a-lF$FG0V5TNAc?Tc{K=4 -WprU=VRT{n^sESGu0eNZ)cp(*eFU-DRQ(QTUJ^TE1nY56>E%WYMs;pyX<}?;RC#b^{4_<~U(XE-|Ev|H -db$N7;9H9;8!%;3hl7uME$faw4?}NmV`X7%Wn@8gbYWv?|7c^tcv66A`G>fI&S@S1XLTY^Y?LL}v9ZWWu2|;XdXkkNP -aC1n$BNr;@ghiU?gEXK9KMDE{F?;HZBRuDVqlk6qmbeZmb;*F> -vukd;=m`ygb@x#_>`RmOO$0)3Z)|vJcxJL|x?WKK>7x;m>=zTw_)ojDN{iR+YxT1qeJQTRI%yh?{hxxA$ -L2PhnVMAeXb4+h!VRLBFJq*Jt8?Abrta^#~Iw-!oZ%zqO(A&rh^vGm~tg_w^L2PhnVN-2kY-~(#WMOk? -3sZD*X=8L$d2nTO4*&^LN2X=Q9=Q)O*QWK$LhgcQkwbf~^M){{|8P%hsRk~m~ep32F151Y4W -WC&DwaAi(mZDnMP)DN(0hN+Kdp}ZAoN($wDX8VgT7DmW3qm%zcviBmGB|7z0dgBIJ4& -sCG^VR$+2!VQzGR(<~&{!{{>E!(#o&^pB98KZhv1GEPn8Orhb4n;8ZMQ)zl>ZfBCy0{K32d-H~a`3x8b -375ImR&CF_#3#*gz1^xtuG$bzVQpn(MrmbiWOGwxZAoO8A%m*X98W>f2s0TH8C&EH;|vtDTYgh)4~t7} -WW`YoMQ(L%R$+2!VQzGDn938Qb#DiI%LhXtBc@pg0t!L7$2{bU&sPXOO(dS=5LRJwX<=@3Np5CuQ)O*Q -Wc?UbbJ9Xwr}~3wv^yxa@v}v^+kiGSR2X#8M$tG2GZIy9X>V>;VRC6_vj93RHP;Wm9=`bY*QQ01rWKV`y)3Wn@BiZe(m_a|8nc26SO?a%FS?1pxsz -U(P2B2NqiWU>yu4AB#Dm;I?Y3kL%RWN&q1Y-Ioj0tR$paB^jI0XARGCkqD_TK!-h3?(0nIicXTch2QnD}62L@rHg-X9aI? -a%FS@hd|-Wi=lHam_X!<3uvO83$-e(J0!3HH}n+hlR66r4nb~iZ**aFX>V>$VQpmv0RRO80?I5NZ-bfL -FbqC#o>4E?M+l67UG^w8*<_XZ#%uyqCnto_jB5_YJg;9E|1`d*r&;qSS3+uh`0YNLave-Im;eX@$}Apl -gPGkh3_fq3Q7_j=2#kPT_9!;lWR>~GYywm#cxiZMvTM3tQ2*(p5s~Z{6V3QiK&W#-F~+s6raGiL00000 -00000{r~^~000003qfvfZ**aFX>V?G1pxpG0WnM89|TAhYfrNblQVQ`LpZXKteHopy#|_NJkG`K5da7P -06+i$00000009600000000000000000093000000000X?b8~5DZb@cgV`T;e3U7CAWn@!yVRU5y-Vzs+ --~y(u)KQ?3g=q&>T!Ej;9TxQjc0+10Fg2)p25@y^Y-wWx$}AplgPGkh3_fq3Q7_j=2#kPT_9!;lWR>~G -Yywm#VTK~nd#>CWCF@89&dx0-7pM3Z=O*v*GCA9 -fL-<|HrZsA`NnJlR3~AEBGG%U@MZ$v=XJ?|;InIPy66cFfOYp#JM2r7_Du+Fb!>ELaBO7)$}AplgPGkh -3_fq3Q7_j=2#kPT_9!;lWR>~GYywm#VTK~nd#>0|;$!V^DH$Z)O5|10COKearHwcS=7M7YzYaI8*bvhMOc?)(rkC#nUE*(LK3V -&vL%&i(~ao9rExlGMgPx_&tqtqVlwo1}@PEWMX4ba&K>D0#*~&*VKn|nRBmPlPrrd^EP>$AHP6|FsuXs -I;G3ONJmc3T+rxDK6vW;JU&?LxLM72H?wDC1Zo}=N}D)4mj+^WZe(m_0w7l>toMja192_(UwD?W=?zm* -&IhOn$k(lG-qz;DsjrQf(E(H_nGEpD*KTAo3`$}tLz4xH6U7D0(t`--)Viz@~C%8KNS}Z0aQ3s^SOqbBwN-D{wl@OCWX;GxmM3|zUzx)^-Ue} -@Gdf&9Z>i^jdP;%w2}rc(FkN>V^DH$Z)O5k6V}(%hjW>8uUwNXi!t*yd7K}=K!`A`1OPgv%fUzwwjY>3 -8tto&d&=ez4Ev5gyU5%_yeyFzybaG*Cb7p070?I5NZ-bfLFbqC#o>4E?M+l67UG^w8 -*<_XZ#%uyqCt-#n(R;4&W&+>mb;*F>vukd;=m`ygb@x#_>`RmOO$l^ma&2jDVQg~%3IZTkC#?5~OapN( -_Fs6GvFQy{P|gRa2*}s1Y~I%9#i;{(leIk>g)RqK0VQ|Mwn6X+txo3vSYd;;z)HQ~0$c(hS0}9Zh)e@< -E%sk{ma*v#Q&7$as0hf{t!&=b=EbSoidq_i6cBYN^7xEELu$lFU37Sf$J;ty5yrmOX|)6Z0000000030 -{{R3000007XJu|>b7^w|AXg`>_lQgbaV_>=c$Ts04O39g2dD_h*R5>c*5<{j?6T%|znQ^KeoD%bg94CL -Cf*q;P?fLY7qq^#2NiM*3T1e7Wo~n6Z*Fq{2?8KjC#?5~OapN(_Fs6GvFQy{P|gRa2*}s1Y~I%9#i>)L -^XdU9;lkvmMR*4bh)jz;q`~Q5Z+&x=I0QQSl+6GD0000000960|Nj60000MKb#7#AWpe-t0nT^OmoUfe -VvhY+ARw!>`>M$upk~C-sV(3xjy;4dI{*Lx000000RR90{{R3000whoXk~3-0w7l>toMja192_(UwD?W -=?zm*&IhOn$k(lG-qz;DsX2RKhRF9oualB}P71SaJfwx=uHX^JIK`}#x3$o4Af`kVHyQ&~TYCSRqgWgjZ$<5FZnjcuT6B5B6)POqpHCTrHl4#QtZa;zni700000 -00000{{R30000003v+dFaBO95Wo~qH00{wOJ=2M>OG#EL&$!Mwbx&PZd -lOljoA7|k;k>s6qoa5|8f~f~{V{&P5baMa+0%CAAe<9`Lptgpr6F_xjAC6(~TLj#*ewiHWCD< -wgM1*ibOB -_lQgbaV_>=c$Ts04O39g2dD_h*R5>c*5<{jgmDd%EKc;pw+KsVi?D}qDSkO*B!5Mb*xG|_(S5o&00;m8 -KmY&$000000RR900000000000000000RR6000000019(yXKrD1b#i5M015%()D=(>(T2L(qY0=?Nz4Ev5gyU5%_yeyFzybaG*C -b7p070?I5NZ-bfLFbqC#o>4E?M+l67UG^w8*<_XZ#%uyqCt-#n(R;4&W&+>mb;*F>vukd;=m`ygb@x#_ ->`RmOO$l^ma&2jDVQg~%3IZTkC#?5~OapN(_Fs6GvFQy{P|gRa2*}s1Y~I%9#i;{(leIk>g)RqK0VQ|M -wn6X+txo3vSYd;;z)HQ~0$c(hS0}9Zh)e@b7^w|AXg`>_lQgbaV_>=c$Ts04O39g -2dD_h*R5>c*5<{j?6T%|znQ^KeoD%bg94CLCf*q;P?fLY7qq^#2NiM*3T1e7Wo~n6Z*Fq{2?8KjC#?5~ -OapN(_Fs6GvFQy{P|gRa2*}s1Y~I%9#i>)L^XdU9;lkvmMR*4bh)jz;q`~Q5Z+&x=I0QQSl+6GD00000 -00960|Nj60000MKb#7#AWpe-t0nT^OmoUfeVvhY+ARw!>`>M$upk~C-sV(3xjy;4dI{*Lx000000RR90 -{{R3000whoXk~3-0w7l>toMja192_(UwD?W=?zm*&IhOn$k(lG-qz;DsX2RKhRF9oualB}P71SaJfwx= -uHX^JIK`}#x3$o4Af`kVHyQ&~TYCSRqgWgjZ$<5FZnj -cuT6B5B6)POqpHCTrHl4#QtZa;zni70000000000{{R30000003v+dFaBO95Wo~qH00{wOJ=2M>OG#EL -&$!Mwbx&PZdlOljoA7|k;k>s6qoa5|8f~f~{V{&P5baMa+0%CAAe<9`L -ptgpr6F_xjAC6(~TLj#*ewiHWCD_lQgbaV_>=c$Ts04O39g2dD_h*R5>c*5<{jgmDd%EKc;p -w+KsVi?D}qDSkO*B!5Mb*xG|_(S5o&00;m8KmY&$000000RR900000000000000000RR6000000019(y -XKrD1b#i5M015%()D=(>(T2L(qY0=?N_lQgbaV_>=c$Ts04O39g2dD_h*R5>c*5<{jp9m~TI>-W|y2ahx -3nF|Vuawki#7NH?S|Q-Q!u2{b0tIPiVPjm(ZiUQ7;QU9z@vLsQUy3b9HcVYybrT0cSFYzzA^b -6`Drj_fC5M7<0km5x1u)VS{2*yf9yYl?p>|ZggdCbW&wz1OxyEb7N>_ZD9Zf0RkXbC#?5~OapN(_Fs6G -vFQy{P|gRa2*}s1Y~I%9#i^81)7t~9tEf?*r}jS36zkMYeK9}${s8)2BzjZ?kPra}XJu|>b7^w`1pxve -S0}9Zh)e@2rNlD$O59e#ogQsB77jPl+h5j^*S;F -1!-nsV`TsZ0RcP8z<~n@;VY|KA!vt$qMEp^75#kD_Tqj3WXX=Y(#Wl3#tYybrT0anNlc)Z3! -7CPHT_+Dq|&?jn_(4)LjFAF^$MA+G=`wK&FZggdCbW>?(a|Hna3IZTkC#?5~OapN(_Fs6GvFQy{P|gRa -2*}s1Y~I%9#i_RFfQB3>bs~EXcCXx(drQcb3B`Fx$)^%va$Ar)C7b~v#}{qTDnK1gUZ=~4IPtBJuMnKC -WEcQ$kD_ZvQg;gh000000000A000000000EMR;^&ZgXjGZb@cgV`T;j2yJg~GYywm# -VTK~nd#>C`}q*r8?;yf@?frQ$owe+rTo-{AMw{vgzX#P!9p!}0yp?_0000000000{{R30000002WM<= -Vqt7^015&{>Z4!V_T!KNI`QJ|h6;Zj^jB$MPK+?7Lu3>C`4HI~v{(W1V6JV*{3!yZ{M3XW@z+p_lQgbaV_>=c$Ts04O39g2dD_h*R5>c*5<{jHo-KZ`k;Xmr`<4sJYKN!!u{G5u+^j1 -lf!PF4>GEG0000000000{{R30000003t@9}X=iS2Wo~qH015&{>Z4!V_T!KNI`QJ|h6;Zj^jB$MPK+?7 -Lu3>C`4HI~v{(W1V6JV*{3!yZ{M3XW@z+p_lQgbaV_>=c$Ts04O39g2dD_h -*R5>c*5<{jHo-KZ`k;Xmr`<4sJYKN!!u{G5u+^j1lf!PF4>GEG0000000000{{R30000002XbX(Wo2!1 -00{y`>Z4!V_T!KNI`QJ|h6;Zj^jB$MPK+?7Lu3>C`4HI~v{(W1V6JV*{3!yZ{M3XW@z+pa{vhfMe3tp+xFv-0Xp&G?S=|}9rRaeU`~uMrbA>C`}q*r +W+%HuC5$^~^vuG3{`}-8x6fV={eh1!etXz_4^&}ra%FT-VRUFva&K>DECY>5OGottJZHLg1Ujv+c;>sahi4MJ>bZe&wsVQf@*X=FG*VlHu0(#Ro^Jj-_-pFL#XcJe4ySuOZRLzEUxZ3PijVQ_L~ +bW&+&XmmnyVQyn+M^4XN(CAD)cag{3QuryWpq$-Z*OL38SA{&vly$F +vzVnzHf7z~rv`86=_Ka^V5yX|y#`JSQ)OdvWpq%$n#j0HLDJN5-IKgM_J7b(p+0MPGk2Gl)y2(Rz1Xgc#bS10xxe^o?x}!PNUwajG +r*TW+dUY6G&@nZ7)X6RBh6__;a%pgMLV0v$b1}QF=!A)P#jpo4axu-4_As_7EzOC4+`8Vyy2R;!*$Y%* +a87SzWk_LjXf@g$6*(YoyWQNR!##&F>hhbX+H~JN$bujoP8PMf90*KrV{24tZDlxh1hGqe4n}Q9o)<@b +By=Qy_yc6@Jxi+hIw1E!bZZGyX=hVoa%pgMU#!_}aHwX>fFqJ7jQqgpV60Q!3=n#-@oxpi@}5@PW%Fv%B~$o;&jeRCrHybeHwl212eXGm<4cs7@Wu#FOK{ +KGSirhjWHCPRxjcYXnnabaS0mldQV=&ET6jM)-pXanm@-FK%_beB&TRo~t++rXB}ZX>@L7b91ADLi5Yl +(a@n1+Ku60FILp}Zw|!7cE!MGSxid=WmW`Kcxhy)e8zcXXXRJdMCHk1I^Yb;mDw5%F9Y9nz;zN&zQ>*g +RCrcpa;b%ccT=8d`>?<6$C@F;S3|*6`1-v+nBdcqJ?FPKcnV2wbY*gGVQf%qwlfK-7{9iX4Q|L-q$GzU +Mp|h#f#zWg5iW~CYZWKwE66NffE< +bz*B}dBk#SkB=zPdcl{-9gYp5n_@(q=Fnta{>SNfJhg}MqX$BHbY)X?a>aWgn!oosZgNI|twmNZeC(lY +Za*g7-2eQ3Yy;-pL;_TJ=xRXCTqXIv;)MTcr4cfxK`S9uy$)6q!N22#m0-mN2v2o%aBpdDbo`>HD!!5a +&4Q@0n2=*4!cKOosx|T?(Q^f3pcpQQSqE58Zfto_YYangZEb0ER%LQ&W_bnxIG#g>Clv)aMjKgwAH@`b +u1x<7g|G$};xvA~n-$_S3Qc8lYiwmmVRLAO(LK3V&vL%&i(~ao9rExlGMgPx_&tqtqVlwo1}@PHO=WUx +Y-Lb#Z*OLk_h5K%L=laq&yA1JoJ^{7>oKLkF4~iax8KK|47hp@Qe|^xa&~28LV0v$b1}=fEj#9D^K)f# +Cf|Xn@L3mU0Z2&n-dr?jcD1Ll0RawDWpib6c4cHjd30rSGVkgW4+YqPF=12xaaxrgbrDxyH3;v2Uql0Ev@(iYu*+LHGLwE58<4pL=vWpZ|9WI}m# +Wpg+QQb$5VZ*6U9bUOe8XadZr-SV>qb#7#AWeK)_65s1c;WeUUgB8EM+V1n+TF3m?Yd1DC`X&GvUv9(-1>WQHGZVX3kZ(?C=R$**)WpfPE&0f8wJi%%!Y}u>; +$65#kwiiC+oZF-Hf6=ZQ>wOwjd2nT9L349yXKr&sY-w&}Q)OXnRCrKyaug*zj!?y>j|-pde{GkuQzBXTAin>Id +F&9PAZ4eqJ|JRcX$Hf^zb8~5DZf#|5baO&%X>MdwWnpYocu;h5B%)2d$+)#qWOeU-&^BHT8-%*B3Y<=; +rA~cRW%6F~9YJ$*X=iR$Z)s#xbYXO5LTqVnWK(5fY*ctqbaEv{biTp4ZzpWVEhda;c-OlKZN9QQ?CZI; +=cI(fPVx{>cWz~5Q*>c;Wm98lWo=<5iOjwi&ipUJkjC-eqrzX2Ju@O|t6`=nY8`b4SeCJ1RUi64PH$rAZV^45~b+QcEHNeWbQVQzD2bZKvHEz*5Sr(qVbRr(sgSTLXWu*DC! +3`08H_Vqrgg&j6`AVG6;X=iRyWp-s@Y-MCtVQh6}LTqVnWK(5fY*ct@WG=F${ujV7L@=1(T$>wOY}Ov_ +b`4?P%YY`+Wb+o`y9rirX=GD$VRU6Oo>ox?`Aroor<$W|05z3@o%yggc; +Wi(O`t`n9TUcD*&5hFi^PVx{q1b@^7zTcrn*%qZTXbx0zVQzD2bZKvHRC#b^H9CeC{6$3z7L3&+{EW{G +yYZJ%0knKxE<9tS|D?sh5K?7!WnpY(WJYyvXK7+=Wj4Vyq57bK6Q|uUfIMEX^1}Vv6tLB!)|10-o)0pr +c?(ZtV|8+JWo~0-b2)ophRF9oualB}P71SaJfwx=uHX^JIK`}V>+d2nTJ%+!W_LE6rjH$cQ=8Ln)Sgi5RNhKKPi@=@5j +iV>*V`yb^xB4~9n`Dx!RtcK)nwJGnaBp>Vlv2~%1FNg3QJ<&wKF}2F)J=Uc +Km7gx`duV?R0NO^2vcKdWo=+kk4W| +0D0)1tC589WlkJ4(T@u?8)d_7GlQG%sFl!L349yXKqqu +c4c8~Wn@HQbYVhlX>MdwWnpYocxhy%7cwO5*n2s$3@K6WR=W11q{+)$o%x+F6XK_jJ2Mg?L349yXKqqu +c4c8~Wn@-iY;|QqY-w&}Q)OXnRCrKya;A(hkw;6)I>KU%$CX5lEZwTb6rTk%m8vvBgJ_74J{Jehz7Np5g;baSm9Ka?O}aEvKu^y*67(3wRv +ID`L1eu0Pjrm!gUE7k}@Xklq?PGxkhy!1S2^HuJ7Oiw7YF=1>so3EIu+3*)t78850@mnbwRC#b^WI=Ot +X=iS8LTqVnWK(5fY*ct@WVYylh8!q$B6|*YuiTY;OURW8#d%1{rxIXtTaY^?oCrx|Wo~q7ba~BGr9yo^ +9b7e4c;WkPIeZe&wsVQf@*X=Kv0L;LZ8 +3j1o=jC2tuhEYb*>|BZ=<&>MYmew2xdV>c?Wo~72X>-+$UkD7Ff~JZGMgrhZ&rP2gYrktY!x$bpv=qCl +=HdlOZg6#U)$WoGNrWpmymk!z-`g4hv-$6z_YxoLZ_neUP>BpbEf7FA*KKfDV^Y;R&=Y*Tb$bYE%WYMs;pyX<}?;RC#b^{4_<~U(XE-|Ev|Hdb$N7;9H9;8!%;3hl7uME$faw +4?}NmV`X7%Wn@8gbYWv?|7c^tcv66A`G>fII^CwqAYJB+ZKALhJOg5MaL2PhnVMAeXb4b1;7b@t4MVjY>G@u4Q3HlB( +d+LiLJm-R=h;`?dxDG*cV`*tna%paKVPb4$VTK~nd#>@6JWikDr@YkEA +s#9)9JJvRH-Qc7Q2s%Kf+=VCyOABEU3kOtrQ)O*QWJFFoaz*WZZ5##rf6bm&7qffY6*N`B##bI~HzDmr +7z##dWo%?qWo=1hQx*t>6v={gsJ=SZlTl1iF5eQ8IAl(q%E@>So406W2vm7+WlmvjWn_%h53p;7sgGx& +z)8&prN#D&cR=tS@df05SQ3Z*PZCvbZeeX@WJYOaY-Dp&Wo=1hYXqYdo~D%m7H6OD0<^0n_2##VWXRdj +y=DB@qgYOj1yf~hNo0M=LMPN>0NEy%g(UCHeUkYj{YR7-159lqXIqm$}teZO^;JC(UrZ-Ks{e+7M1* +ZDnLeX=Q9=b5mt)No1EHgR0RSPeIWLGZ_*YTjUMn3>33lep74@i%V@}#Ze4JZgp)|VRC6;+#Z*Ep$a%o|1baPW>ZAoPPfv$so3kRF1PV2}fOp_vjQ6FdFHId|K_%|4nb~iZ**aFX>V>$ +VQpmv0RRO80?I5NZ-bfLFbqC#o>4E?M+l67UG^w8*<_XZ#%uyqCnto_jB5_YJg;9E|1`d*r&;qSS3+uh +`0YNLave-Im;eX@$}AplgPGkh3_fq3Q7_j=2#kPT_9!;lWR>~GYywm#cxiZMvTM3tQ2*(p5s~Z{6V3Qi +K&W#-F~+s6raGiL0000000000{r~^~000003qfvfZ**aFX>V?G1pxpG0WnM89|TAhYfrNblQVQ`LpZXK +teHopy#|_NJkG`K5da7P06+i$00000009600000000000000000093000000000X?b8~5DZb@cgV`T;e +3U7CAWn@!yVRU5y-Vzs+-~y(u)KQ?3g=q&>T!Ej;9TxQjc0+10Fg2)p25@y^Y-wWx$}AplgPGkh3_fq3 +Q7_j=2#kPT_9!;lWR>~GYywm#VTK~nd#>CWCF@8 +9&dx0-7pM3Z=O*v*GCA9fL-<|HrZsA`NnJlR3~AEBGG%U@MZ$v=XJ?|;InIPy66cFfOYp#JM2r7_Du+F +b!>ELaBO7)$}AplgPGkh3_fq3Q7_j=2#kPT_9!;lWR>~GYywm#VTK~nd#>0|;$!V^DH$Z)O5|10COKearHwcS=7M7YzYaI8*bv +hMOc?)(rkC#nUE*(LK3V&vL%&i(~ao9rExlGMgPx_&tqtqVlwo1}@PEWMX4ba&K>D0wHj#q4l6D4ZcK) +2hLYH81C&KXiWu&flb+s{C0G-{6|jDT+rxDK6vW;JU&?LxLM72H?wDC1Zo}=N}D)4mj+^WZe(m_0-u0r +OVXX8on}%7`W~n~g^Ir=cD&(=7J1!T`=A*KGX;3#jF_Psll$K3m0qvW>0&oDqqo0*?q^FKQ(!8W@fSmE +X=QG7LUnFrY-LnoaB^jIP;zf?W(ETYZE#~ya&K>D0(t`--)Viz@~C%8KNS}Z0aQ3s^SOqbBwN-D{wl@O +CWX;GxmM3|zUzx)^-Ue}@Gdf&9Z>i^jdP;%w2}rc(FkN>V^DH$Z)O4^aI2y9pehZ%M2QE^S2-B&?H_1O +1&4u6*^T^mbhP{rwjY>38tto&d&=e}S +s6B;>za@6O;ffY{-CFyg83{85c;k$ip&FC>-szQIuhHpZH#DQSzklv$OC3{SDwpvPLvL<#X=iS2Wo~q4 +VQh0{1`P*xWpZz4Ev5gyU5%_yeyFzybaG*Cb7p070?I5NZ-bfL +FbqC#o>4E?M+l67UG^w8*<_XZ#%uyqCt-#n(R;4&W&+>mb;*F>vukd;=m`ygb@x#_>`RmOO$l^ma&2jD +VQg~%3Id;iXiL(ap`B(@2KpYTJ%x(DC3d{wiWYg@TKk|G2{QwGleIk>g)RqK0VQ|Mwn6X+txo3vSYd;; +z)HQ~0$c(iaI2y9pehZ%M2QE^S2-B&?H_1O1&4u6*^T^mbhP|v8SA{&vly$FvzVnzHf7z~rv`86=_Ka^ +V5yX|y#`JI0000000030{{R3000007XJu|>b7^w|pMYpf(w(85W>N +(zHYS@qr5aYT1l*5hjLFM$znCiXr8co3@tL90z)X3T1e7Wo~n6Z*Fq{2?C#hXiL(ap`B(@2KpYTJ%x(D +C3d{wiWYg@TKk|G2{R^%%)S@S{4c_g#_`^x!e5a+Ga_oMVWuc-d(EoHF)siB0000000960|Nj60000MK +b#7#AWpe-t0VKb!>z@X6l5yio1?-YV)2V!clxMdOjzu+IFQjzqg#Z8m000000RR90{{R3000whoXk~3- +0-u0rOVXX8on}%7`W~n~g^Ir=cD&(=7J1!T`=A*KGdX);hRF9oualB}P71SaJfwx=uHX^JIK`}#x3$o4Af`kVHyQ&~TYCSRqgWgjZ$<5FZnjcuT6B5B6)POqpHC +TrHl4#QtZa;zni70000000000{{R30000003v+dFaBO95Wo~qH00{wOJ=2M>OG#EL&$!Mwbx&PZdlOljoA7|k;k>s6qoa5|8f~f~{V{&P5baMa+0%CAAe<9`Lptgpr6F_ +xjAC6(~TLj#*ewiHWCDNgmDd%EKc;pw+KsVi?D}qDSkO* +B!5Mb*xG|_(S5o&00;m8KmY&$000000RR900000000000000000RR6000000019(yXKrD1b#i5M015%( +)D=(>(T2L(qY0=?Nz4 +Ev5gyU5%_yeyFzybaG*Cb7p070?I5NZ-bfLFbqC#o>4E?M+l67UG^w8*<_XZ#%uyqCt-#n(R;4&W&+>m +b;*F>vukd;=m`ygb@x#_>`RmOO$l^ma&2jDVQg~%3Id;iXiL(ap`B(@2KpYTJ%x(DC3d{wiWYg@TKk|G +2{QwGleIk>g)RqK0VQ|Mwn6X+txo3vSYd;;z)HQ~0$c(iaI2y9pehZ%M2QE^S2-B&?H_1O1&4u6*^T^m +bhP|v8SA{&vly$FvzVnzHf7z~rv`86=_Ka^V5yX|y#`JI0000000030{{R3000007XJu|>b7^w|pMYpf +(w(85W>N(zHYS@qr5aYT1l*5hjLFM$znCiXr8co3@tL90z)X3T1e7 +Wo~n6Z*Fq{2?C#hXiL(ap`B(@2KpYTJ%x(DC3d{wiWYg@TKk|G2{R^%%)S@S{4c_g#_`^x!e5a+Ga_oM +VWuc-d(EoHF)siB0000000960|Nj60000MKb#7#AWpe-t0VKb!>z@X6l5yio1?-YV)2V!clxMdOjzu+I +FQjzqg#Z8m000000RR90{{R3000whoXk~3-0-u0rOVXX8on}%7`W~n~g^Ir=cD&(=7J1!T`=A*KGdX); +hRF9oualB}P71SaJfwx=uHX^JIK`}#x3$o4Af`kVHyQ +&~TYCSRqgWgjZ$<5FZnjcuT6B5B6)POqpHCTrHl4#QtZa;zni70000000000{{R30000003v+dFaBO95 +Wo~qH00{wOJ=2M>OG#EL&$!Mwbx&PZdlOljoA7|k;k>s6qoa5|8f~f~{ +V{&P5baMa+0%CAAe<9`Lptgpr6F_xjAC6(~TLj#*ewiHWCDNgmDd%EKc;pw+KsVi?D}qDSkO*B!5Mb*xG|_(S5o&00;m8KmY&$000000RR900000000000 +000000RR6000000019(yXKrD1b#i5M015%()D=(>(T2L(qY0=?N}Ss6B;>za@6O;ffY{-CFyg83{9#Qq$W5tE;F{ +pQrXd&=l*`O?@#x{Qdy?T_k!`1dtE`2WMq&WpinB00jX8pMYpf(w(85W>Np9m~TI>-W|y2ahx3nF|Vuawki#7NH?S|Q-Q!u2{b0tIPiVPjm(ZiUQ7;QU9z@vLsQUy3 +b9HcVYybrT0cSFYzzA^b6`Drj_fC5M7<0km5x1u)VS{2*yf9yYl?p>|ZggdCbW&wz1OxyEb7N>_ZD9Zf +0Ro?ZXiL(ap`B(@2KpYTJ%x(DC3d{wiWYg@TKk|G2{V*Z)7t~9tEf?*r}jS36zkMYeK9}${s8)2BzjZ? +kPra}XJu|>b7^w`1pxw|fM`q7ouQp(QU>}Ss6B;>za@6O;ffY{-CFyg83{9=2rNlD$O59e#ogQsB77jP +l+h5j^*S;F1!-nsV`TsZ0RcP8z<~n@;VY|KA!vt$qMEp^75#kD_Tqj3WXX=Y(# +Wl3#tYybrT0anNlc)Z3!7CPHT_+Dq|&?jn_(4)LjFAF^$MA+G=`wK&FZggdCbW>?(a|Hna3Id;iXiL(a +p`B(@2KpYTJ%x(DC3d{wiWYg@TKk|G2{X3nfQB3>bs~EXcCXx(drQcb3B`Fx$)^%va$Ar)C7b~v#}{qT +DnK1gUZ=~4IPtBJuMnKCWEcQ$kD_ZvQg;gh000000000A000000000EMR;^&ZgXjGZb@cgV`T;j2yJg< +X=Z6~GYywm#VTK~nd#>C`}q*r8?;yf@?frQ$owe+rTo-{AMw{vgzX#P!9p!}0yp?_00000 +00000{{R30000002WM<=Vqt7^015&{>Z4!V_T!KNI`QJ|h6;Zj^jB$MPK+?7Lu3>C`4HI~v{(W1V6JV* +{3!yZ{M3XW@z+pNHo-KZ`k;Xm +r`<4sJYKN!!u{G5u+^j1lf!PF4>GEG0000000000{{R30000003t@9}X=iS2Wo~qH015&{>Z4!V_T!KN +I`QJ|h6;Zj^jB$MPK+?7Lu3>C`4HI~v{(W1V6JV*{3!yZ{M3XW@z+pNHo-KZ`k;Xmr`<4sJYKN!!u{G5u+^j1lf!PF4>GEG0000000000 +{{R30000002XbX(Wo2!100{y`>Z4!V_T!KNI`QJ|h6;Zj^jB$MPK+?7Lu3>C`4HI~v{(W1V6JV*{3!yZ +{M3XW@z+pa{vhfMe3tp+xFv-0Xp&G?S=|} +9rRaeU`~uMrbA>C`}q*r8?;yf@?frQ$owe+rTo-{AMw{vgzX#P!9p!}0yp?_0000000000{{R3000000 +24!+`Z*p@02?9mxqhH(h&Z4!V_T!KNI`QJ|h6;Zj^jB$MPK+?7Lu3>C`4HI~v{(W1V6JV*{3!yZ{M3XW@z+p}Ss6B;>za@6O;ffY{-CFyg +83{8s!8D=zpn(&o-7tVWUa<1Q{n`|;)uYyv!)~4rGOBq10000000030000000000BVRLh7XKrm}Zgg`1 +3IavyqhH(h}Ss6B;>za@6O;ffY{-CFyg83{8s!8D=zpn(&o-7tVWUa<1Q{n`|;)uYyv!)~4r +GOBq100000000300000000009c42H~ZewX>a{vhfMe3tp+xFv-0Xp&G?S=|}9rRaeU`~uMrbA>C`}q*r 8?;yf@?frQ$owe+rTo-{AMw{vgzX#P!9p!}0yp?_0000000000{{R300000024!+`Z*p@02?9mxqhH(h &Z4!V_T!KN -I`QJ|h6;Zj^jB$MPK+?7Lu3>C`4HI~v{(W1V6JV*{3!yZ{M3XW@z+pa{vhfMe3tp+xFv-0Xp&G?S=|}9rRaeU`~uMrbA>C`}q*r8?;yf@?frQ$owe+rTo-{ -AMw{vgzX#P!9p!}0yp?_0000000000{{R300000024!+`Z*p@02?9mxqhH(hNn`*70ssVVZ*FA(00035b8l^B00jX8Me3tp+xFv-0Xp&G?S=|}9rRaeU`~uMrbA>C -`}q*rYXqYdo~D%m7H6OD0<^0n_2##VWXRdjy=DB@qgYOj2y$g{b!l>CWCF@89&dx0-7pM3Z=O*v*GCA9 -fL-<|HrZsA`NnJlR3~AEBGG%U@MZ$v=XJ?|;InIPy66cFfOYp#JM2r7_Du+Fb!>ELaBO7)$}AplgPGkh -3_fq3Q7_j=2#kPT_9!;lWR>~GYywm#VTK~nd#>Z4!V_T!KNI`QJ|h6;Zj -^jB$MPK+?7Lu3>C`4HJt76^nC$%1sKzB<;EQA|)S-x88IWKN#S$#@T&w`gPtX>Mp`a%psP00;p)%D{mG -2;nQMTOnwNgyXhzrB~SH04;UKo5i(1Vxw^Y00000000300000000009bZKp6b97;CZ~y>E2yJC_VPs)+ -VE_sOMe3tp+xFv-0Xp&G?S=|}9rRaeU`~uMrbA>C`}q*r8?;yf@?frQ$owe+rTo-{AMw{vgzX#P!9p!} -0yp?_0!8YhU)%QMkO4aJ;_ZeCe;xE!X<$x_Fs4If6Z`oP*=q!&6rQG)02XJT?*g=|B=zREie$*y(7k2+ -*P~cYjQ{`u000000RI300000001IbqZ(?C=Q*>c;WdI5SMe3tp+xFv-0Xp&G?S=|}9rRaeU`~uMrbA>C -`}q*r8?;yf@?frQ$owe+rTo-{AMw{vgzX#P!9p!}0yp?_0m=yGke?j1l!xqXd>q7+-P0pRHy9#PwIC -`}q*r8?;yf@?frQ$owe+rTo-{AMw{vgzX#P!9p!}0yp?_0ZXaKh^f@$D{A?t{IfX>#}PNp!L%7{0GY9x -pq!KXGXMYp000000RI3000000010+sY-Mg^X=QT&3IavyqhH(hb7^w{b?qhoJW!8=sKG~^&Ni^C7tcO}co=3CQC(GPVoWSC3v_Z} -ZgXjLX>V?G015&{>Z4!V_T!KNI`QJ|h6;Zj^jB$MPK+?7Lu3>C`4HI~v{(W1V6JV*{3!yZ{M3XW@z+p< -?Hl01LM?X!H~4Y^Hx3&bJ$HXE2K+s|vHZ6#&ske5?JSDZAfr}PGrQJ;0000000000{{R30000003T1e7 -Wo~n6Z*Fq{3IavyqhH(hD`aAk5~bZKvH00aU61a5C`WdHyG0R(ezZDjxj0RlzpqhH(hC`}q*r35LOoBKkGaY9#cS7Qj{WgyAGcS>>g~&^g7bS0}9Zh)e@p#+${pKVqYC33O>~Wpi|4ZEyepNC<6ZbYWy+bYTDq0lk5UVp0y6#Opn49V(cQc;WdI2QadI6-(bd|-i#!&GYaF>qoh8ar -da{vheR)?jU+FZ2DLr`QR#xHIKjC^A48Li8o -%k$8HEod=_0000000000{{R30000003v_Z}ZgXjLX>V?G00{v&KD$)QXhhr5^*YH=BF-=c -yOsxg-v9sr000000RI300000000w1pa&K~T00{xZXXT7NJOW`Spw3o_*cmz+=1%_1gm*5-D79nn{HtC7 -00000000300000000009WMy_`Y;SO7asnV%C#?5~OapN(_Fs6GvFQy{P|gRa2*}s1Y~I%9#i_RFfQB3> -bs~EXcCXx(drQcb3B`Fx$)^%va$Ar)C7cFHZE$Q!WCZ~L2LJ#-AOHhPX>#x3$o4Af`kVHyQ&~TYC -SRqgV00000000300000000008b7N>_ZDDj_00{yhS0}9Zh)e@ite$I%(jAWg00000000300000000006X=!b6Y;yn!0fbj(2M`|< -m3T|4oDcSEr%ah$$XqR+hQ$77qvA$o%>V!Z000000RI300000001I<Z4!V_T!KNI`QJ|h6;Zj -^jB$MPK+?7Lu3>C`4HLtfv$so3kRF1PV2}fOp_vjQ6FdFHId|lr&gK9B00000 -0096000000000VeX=iR>bairNa{vkf;?xyT5z&Ua+M@}mOiDpYxh>^^GknUxTJ!XL#OUcE0frb5ENEw7 -&f?o%+)B!ZpG}K!%4G?I4vp$|ttu*CMF0Q*000000RI300000000>QQWNBt;WpV=p2w`G#baG*1bN~o% -c4cyMX=G&q1!ie(VQl{xPGN0jWJYOaY-B-mb7^O8ZDnqBRC#b^1_J_VWC9>pC#?5~OapN(_Fs6GvFQy{ -P|gRa2*}s1Y~I%9#i@t>;$>KfZ0H=mhJ>?uVC`}q*r8?;yf@?frQ$owe+rTo-{AMw{vgzX#P!9p!}0yp?_2y$g}WpZ|9WCD5v -9p7nv%krpqNFdAXg`>_lQgbaV_>=c$Ts04O39g2dD_h*R5>c*5<{jWOW`w -sTH9-LlJ`2|Ay5Z(?oEikl{+~pis;@Q*TJ#1a4t%WdcR&qhH(hNn`*70ssVVZ*FA(00035b8l^B00jX8Me3tp+xFv-0Xp&G +?S=|}9rRaeU`~uMrbA>C`}q*rYXqYdo~D%m7H6OD0<^0n_2##VWXRdjy=DB@qgYOj2y$g{b!l>CWCF@8 +9&dx0-7pM3Z=O*v*GCA9fL-<|HrZsA`NnJlR3~AEBGG%U@MZ$v=XJ?|;InIPy66cFfOYp#JM2r7_Du+F +b!>ELaBO7)$}AplgPGkh3_fq3Q7_j=2#kPT_9!;lWR>~GYywm#VTK~nd#>Z4!V_T!KNI`QJ|h6;Zj^jB$MPK+?7Lu3>C`4HJt76^nC$%1sKzB<;EQA|)S-x88IWKN#S$#@T&w`gPt +X>Mp`a%psP00;p)%D{mG2;nQMTOnwNgyXhzrB~SH04;UKo5i(1Vxw^Y00000000300000000009bZKp6 +b97;CZ~y>E2yJC_VPs)+VE_sOMe3tp+xFv-0Xp&G?S=|}9rRaeU`~uMrbA>C`}q*r8?;yf@?frQ$owe+ +rTo-{AMw{vgzX#P!9p!}0yp?_0!8YhU)%QMkO4aJ;_ZeCe;xE!X<$x_Fs4If6Z`oP*=q!&6rQG)02XJT +?*g=|B=zREie$*y(7k2+*P~cYjQ{`u000000RI300000001IbqZ(?C=Q*>c;WdI5SMe3tp+xFv-0Xp&G +?S=|}9rRaeU`~uMrbA>C`}q*r8?;yf@?frQ$owe+rTo-{AMw{vgzX#P!9p!}0yp?_0m=yGke?j1l!xqX +d>q7+-P0pRHy9#PwIC`}q*r8?;yf@?frQ$owe+rTo-{AMw{vgzX#P!9p!}0yp?_0ZXaKh^f@$D{A?t +{IfX>#}PNp!L%7{0GY9xpq!KXGXMYp000000RI3000000010+sY-Mg^X=QT&3IavyqhH(hb7^w{b?qhoJW!8=sKG~^&Ni^C7tcO} +co=3CQC(GPVoWSC3v_Z}ZgXjLX>V?G015&{>Z4!V_T!KNI`QJ|h6;Zj^jB$MPK+?7Lu3>C`4HI~v{(W1 +V6JV*{3!yZ{M3XW@z+pD`aAk5~bZKvH00aU61a5C`WdHyG0R(ezZDjxj0RlzpqhH(hC`}q*r35LOoBKkGaY9#cS7Qj{WgyAGcS>>g~&^g7}Ss6B;>za@6O +;ffY{-CFyg83{AC=zxYCD0L!x4tB5Hm3vFbl?lapNXe%XU~*fKJ0+Y4NoHYVWl3ZO0RRU806-uB2}x#Q +V`WKgaBKz)2X}Ss6B;>za@6O;ffY{-CFyg83{9#Qq$W5tE;F{pQrXd&=l*`O?@#x{Qdy?T_k!`1dtF1X=Y(# +Wl3ZKJIcU;0|?p#+${pKVqYC33O>~Wpi|4ZEyepNC<6ZbYWy+bYTDq0lk5U +Vp0y6#Opn49V(cQc;WdI2QadI6- +(bd|-i#!&GYaF>qoh8arda{vheR)?jU+FZ2D +Lr`QR#xHIKjC^A48Li8o%k$8HEod=_0000000000{{R30000003v_Z}ZgXjLX>V?G00{v&KD$)QXhhr5^*YH=BF-=cyOsxg-v9sr000000RI300000000w1pa&K~T00{xZXXT7NJOW`Spw3o_*cmz+ +=1%_1gm*5-D79nn{HtC700000000300000000009WMy_`Y;SO7asr=#XiL(ap`B(@2KpYTJ%x(DC3d{w +iWYg@TKk|G2{X3nfQB3>bs~EXcCXx(drQcb3B`Fx$)^%va$Ar)C7cFHZE$Q!WCZ~L2LJ#-AOHhPX>#x3$o4Af`kVHyQ&~TYCSRqgV00000000300000000008b7N>_ZDDj_00{!0fM`q7ouQp(QU>}Ss6B;> +za@6O;ffY{-CFyg83{8vdtiph_du_cl6_7Jvu!-2h2yT^5yv>ite$I%(jAWg00000000300000000006 +X=!b6Y;yn!0fbj(2M`|V!Z000000RI300000001I<Z4!V_T!KNI`QJ|h6;Zj^jB$MPK+?7Lu3>C`4HLtfv$so3kRF1PV2}fOp_vjQ6FdFHId|lr&gK9B000000096000000000VeX=iR>bairNa{vkf;?xyT5z&Ua+M@}mOiDpYxh>^^GknUx +TJ!XL#OUcE0frb5ENEw7&f?o%+)B!ZpG}K!%4G?I4vp$|ttu*CMF0Q*000000RI300000000>QQWNBt; +WpV=p2w`G#baG*1bN~o%c4cyMX=G&q1!ie(VQl{xPGN0jWJYOaY-B-mb7^O8ZDnqBRC#b^1_J_VWCEXn +XiL(ap`B(@2KpYTJ%x(DC3d{wiWYg@TKk|G2{VWO;$>KfZ0H=mhJ>?uVC`}q*r8?;yf@?frQ$owe+rTo-{AMw{vgzX#P!9p!} +0yp?_2y$g}WpZ|9WCD5v9p7nv%krpqNFdpMYpf(w(85W>NWOW`wsTH9-LlJ`2|Ay5Z(?oEikl{+~pis;@Q*TJ#1a4t%WdcR&qhH(he1kloHngE|MP08BSqs +Wn@NaWo%?eY;R&=Y*Tb$bY)a|aAgJq0%>FdpMYpf(w(85W>N)$WoG +Nre1kloHngE|MP08BSqsWn@NaWo%?eY;R&=Y*Tb$ -bY)a|aAgJq0%>FdAXg`>_lQgbaV_>=c$Ts04O39g2dD_h*R5>c*5<{j)$WoGNre1kloHngE|MP05>8=lWn@NaWo%?kWprUwd2nS00|IGe0w7l>toMja192_( -UwD?W=?zm*&IhOn$k(lG-qz;DsdeN{_}|Wp0vpvv$c&#PW69R$ltr%da5t5w^x+8!q6BVXZDj&Q>Z4!V -_T!KNI`QJ|h6;Zj^jB$MPK+?7Lu3>C`4HI~v{(W1V6JV*{3!yZ{M3XW@z+pFdAXg`>_lQgbaV_>=c$Ts04O39g2dD_h*R5>c -*5<{jG*S<)6P6lYy(#<=BR_>s@(?%#f7ArN-=Rj?7Ns(11a4t%WdcR&qhH(he1kloHngE|MP06;5GoWn@NaWo%?t -VQgh?V|i40aAgJq0%>FdAXg`>_lQgbaV_>=c$Ts04O39g2dD_h*R5>c*5<{jM(yUq2ps*m=2xUDT;RqC -gn#@WzFu~@adfH5^@&-|1a4t%WdcR&qhH(he1kloHngE|MP04o+chWn@-ia%o|1bagle0|IGe00035ZeeX@0!8Yh -U)%QMkO4aJ;_ZeCe;xE!X<$x_Fs4If6Z`oP*$IZhiz50p(P||0m=?fQ^Mv6fMp@;h#Lzj#&aRFSj|g&Q -b7gXNWn=<+10COKearHwcS=7M7YzYaI8*bvhMOc?)(rkC#nUG5>JtwI*nu%&Q~z;Vl^%5wS6(#;{6ajG -64wDPk{-(nPj_x*WJzXWV`T&e00Uuec>n+a0S0nuXJ~YD0000224QV)b#8P30009AVQzUuVRT^t000CD -VQzUrbaY{3XaE2J1q5VabYTDm0RlzpqhH(hioJ -pYH;+t0eX2w~A!Q+0eaZ{MVycPK^psbz)a(bZ%vHa|8ka1ax?5WB>&L0`+VYVk7oBr%DNv+($;q`HHK! -gIHa)*%m(-e#9sm3ZsHT^UK%K(4i9Ajp1M~R@C@!4#dQE#lUD;OiKi1RsjNZcmM?f0`+VYVk7oBr%DNv -+($;q`HHK!gIHa)*%m(-e#9sm3dMUNn!oosZgNI|twmNZeC(lYZa*g7-2eQ3Yy;-pL1po(RWoBV@Y;*ts009Pc -d2nS;ZvX`W0006J2y}UHWlmvjWdH>M0!8YhU)%QMkO4aJ;_ZeCe;xE!X<$x_Fs4If6Z`oP*;5t>gcQkw -bf~^M){{|8P%hsRk~m~ep32F151Y4WWD*HxX=Q9=PGN0j00jX8Me3tp+xFv-0Xp&G?S=|}9rRaeU`~uM -rbA>C`}q*r8?;yf@?frQ$owe+rTo-{AMw{vgzX#P!9p!}0yp?_6AN}>a%o|1bWUMyWdH>M0!8YhU)%QM -kO4aJ;_ZeCe;xE!X<$x_Fs4If6Z`oP*$IZhiz50p(P||0m=?fQ^Mv6fMp@;h#Lzj#&aRFSj|fwBaByr* -VQ>Wj015$yz}|oy`cC#6Uw2{wE+Sw~);*uMH+9Bf@aCY-RuiZDn*}0S0GmZ(?C=0tIh(Ze?Tx -2XWo~161PWnub7^O8ZDnqB1qWwkZe??6a|Q}@a$#@6CZU+fvcywiMb7^mG2nl6)V`Xr3X>V=` -3R87(aBO95Wo~o^1PNnrZggdCbV+0Z2AHk4+Bm{3x%H=p>4!*u&n~Wpi|4 -ZEyepNC#tbWnpx0asnV%C#?5~OapN(_Fs6GvFQy{P|gRa2*}s1Y~I%9#i_RFfQB3>bs~EXcCXx(drQcb -3B`Fx$)^%va$Ar)C7cUkZfdKHyBH|__hx_vscRWAu^w2r{b^x;wDWyGXd29 -kG60)seH8)H{-R`;$q)jqasX>@6CZb@cgV`T;j -2yJg~GYywm#VTK~nd#>C`}q*r8?;yf@?frQ$owe+rTo-{AMw{vgzX#P!9p!}0yp?_ -0000000000{{R30000002WM<=Vqt7^015&{>Z4!V_T!KNI`QJ|h6;Zj^jB$MPK+?7Lu3>C`4HI~v{(W1 -V6JV*{3!yZ{M3XW@z+p_lQgbaV_>=c$Ts04O39g2dD_h*R5>c*5<{jHo-KZ -`k;Xmr`<4sJYKN!!u{G5u+^j1lf!PF4>GEG0000000000{{R300000025D|^b#!w83IavyqhH(ha{vhfMe3tp+xFv-0Xp&G -?S=|}9rRaeU`~uMrbA>C`}q*r8?;yf@?frQ$owe+rTo-{AMw{vgzX#P!9p!}0yp?_0000000000{{R30 -0000024!+`Z*p@02?9mxqhH(huJC38-{*D7fZ(%hZo23R4S;p`Q9JBQllDyoR%LQdZvz4Xb}#?}b}<1BS7~%^Wpi^vb#7#AWd;HY -aCKr=X>@L7b8`Y9S0}9Zh)e@zVQyn+Z*pa1LUnFrY-Mu+hzwODL;*@eYE_8FVm19wjO(ZbIvDI)B0PALl`~a8 +xrUo0The1kloHngE|MP05>8=lWn@NaWo%?kWprUwd2nS0 +0|IGe0-u0rOVXX8on}%7`W~n~g^Ir=cD&(=7J1!T`=A*KGj-%m_}|Wp0vpvv$c&#PW69R$ltr%da5t5w +^x+8!q6BVXZDj&Q>Z4!V_T!KNI`QJ|h6;Zj^jB$MPK+?7Lu3>C`4HI~v{(W1V6JV*{3!yZ{M3XW@z+p< +?Hl01LM?X!H~4Z0a%FR6a&~280(t`--)Viz@~C%8KNS}Z0aQ3s^SOqbBwN-D{wl@OChzJK4+YqPF=12x +aaxrgbrDxyH3FdpMYpf(w(85W>NG*S<)6P6lYy(#<=BR_>s@(?%#f7ArN-=Rj?7Ns(11a4t%WdcR&qhH(h +e1kloHng +E|MP06;5GoWn@NaWo%?tVQgh?V|i40aAgJq0%>FdpMYpf(w(85W>N +M(yUq2ps*m=2xUDT;RqCgn#@WzFu~@adfH5^@&-|1a4t%WdcR&qhH(he1kloHngE|MP04o+chWn@-ia%o|1bagle +0|IGe00035ZeeX@0!8YhU)%QMkO4aJ;_ZeCe;xE!X<$x_Fs4If6Z`oP*$IZhiz50p(P||0m=?fQ^Mv6f +Mp@;h#Lzj#&aRFSj|g&Qb7gXNWn=<+10COKearHwcS=7M7YzYaI8*bvhMOc?)(rkC#nUG5>JtwI*nu%& +Q~z;Vl^%5wS6(#;{6ajG64wDPk{-(nPj_x*WJzXWV`T&e00Uuec>n+a0S0nuXJ~YD0000224QV)b#8P3 +0009AVQzUuVRT^t000CDVQzUrbaY{3XaE2J1q5VabYTDm0RlzpqhH(hioJpYH;+t0eX2w~A!Q+0eaZ{MVycPK^psbz)a(bZ%vHa|8ka1ax?5WB>&L0`+VY +Vk7oBr%DNv+($;q`HHK!gIHa)*%m(-e#9sm3ZsHT^UK%K(4i9Ajp1M~R@C@!4#dQE#lUD;OiKi1RsjNZ +cmM?f0`+VYVk7oBr%DNv+($;q`HHK!gIHa)*%m(-e#9sm3dMUNn!oosZgNI|twmNZeC(lYZa*g7-2eQ3 +Yy;-pL +1po(RWoBV@Y;*ts009Pcd2nS;ZvX`W0006J2y}UHWlmvjWdH>M0!8YhU)%QMkO4aJ;_ZeCe;xE!X<$x_ +Fs4If6Z`oP*;5t>gcQkwbf~^M){{|8P%hsRk~m~ep32F151Y4WWD*HxX=Q9=PGN0j00jX8Me3tp+xFv- +0Xp&G?S=|}9rRaeU`~uMrbA>C`}q*r8?;yf@?frQ$owe+rTo-{AMw{vgzX#P!9p!}0yp?_6AN}>a%o|1 +bWUMyWdH>M0!8YhU)%QMkO4aJ;_ZeCe;xE!X<$x_Fs4If6Z`oP*$IZhiz50p(P||0m=?fQ^Mv6fMp@;h +#Lzj#&aRFSj|fwBaByr*VQ>Wj015$yz}|oy`cC#6Uw2{wE+Sw~);*uMH+9Bf@aCY-RuiZDn*} +0S0GmZ(?C=0tIh(Ze?Tx2XWo~161PWnub7^O8ZDnqB1qWwkZe??6a|Q}@a$#@6CZU+fvcywiM +b7^mG2nl6)V`Xr3X>V=`3R87(aBO95Wo~o^1PNnrZggdCbV+0Z2AHk4+Bm{3x%H=p>4!*u&n~Wpi|4ZEyepNC#tbWnpx0asr=#XiL(ap`B(@2KpYTJ%x(DC3d{wiWYg@TKk|G2{X3n +fQB3>bs~EXcCXx(drQcb3B`Fx$)^%va$Ar)C7cUkZfdKHyBH|__hx_vscRW +Au^w2r{b^x;wDWyGXd29kG60)seH8)H{-R`;$q)jqasX>@6CZb@cgV`T;j2yJg~GYywm#VTK~nd#>C`}q*r8?;yf@?frQ$owe+rTo-{ +AMw{vgzX#P!9p!}0yp?_0000000000{{R30000002WM<=Vqt7^015&{>Z4!V_T!KNI`QJ|h6;Zj^jB$M +PK+?7Lu3>C`4HI~v{(W1V6JV*{3!yZ{M3XW@z+pNHo-KZ`k;Xmr`<4sJYKN!!u{G5u+^j1lf!PF4>GEG0000000000{{R300000025D|^ +b#!w83IavyqhH(h}Ss6B;>za@6O;ffY{-CFyg83{8s!8D=zpn(&o-7tVWUa<1Q{n`|;)uYyv +!)~4rGOBq10000000030000000000BVRLh7XKrm}Zgg`13IavyqhH(h}Ss6B;>za@6O;ffY{ +-CFyg83{8s!8D=zpn(&o-7tVWUa<1Q{n`|;)uYyv!)~4rGOBq100000000300000000009c42H~ZewX> +a{vhfMe3tp+xFv-0Xp&G?S=|}9rRaeU`~uMrbA>C`}q*r8?;yf@?frQ$owe+rTo-{AMw{vgzX#P!9p!} +0yp?_0000000000{{R300000024!+`Z*p@02?9mxqhH(huJC38-{*D7fZ(%hZo23R4S;p`Q9JBQllDyoR%LQdZvz4Xb}#?}b}<1B +S7~%^Wpi^vb#7#AWd;HYaCKr=X>@L7b8`U(J4=$RltJLk?Nfj|sXiSdmgaJi@wPyW+dHeUQG($PVQyn+ +Z*pa1LUnFrY-Ir*q&^ereJSbv4~AUlRja@2Ckv4h-B^wIs2Ae~UL>y -----END STRICT TYPE LIB----- diff --git a/stl/RGBStd@0.11.0.stl b/stl/RGBStd@0.11.0.stl index aa9bc8cd..489d56ef 100644 Binary files a/stl/RGBStd@0.11.0.stl and b/stl/RGBStd@0.11.0.stl differ diff --git a/stl/RGBStd@0.11.0.sty b/stl/RGBStd@0.11.0.sty index 25c3be31..c499865d 100644 --- a/stl/RGBStd@0.11.0.sty +++ b/stl/RGBStd@0.11.0.sty @@ -1,5 +1,5 @@ {- - Id: stl:JhUC5JgH-Kwps4cO-ZNUklUj-UP6boFp-OY!18Kx-xOSJaVQ#hair-magnum-helena + Id: stl:YgyNu!Qt-mt5DMxt-GXH55TN-bmrTwZH-o11V0B$-$jxMrfE#juliet-vega-richard Name: RGBStd Version: 0.11.0 Description: RGB standard library @@ -11,120 +11,110 @@ @context typelib RGBStd -import RGBCommit#harvest-person-orion +import BPCore#symbol-tropic-grand + use TapretNodePartner#roger-member-educate + use TapretProof#marco-border-sample + use TapretPathProof#kiwi-mirror-paris + use BlindSealTxid#halt-crash-valid + use TapretRightBranch#miracle-patriot-touch + use OpretProof#good-village-flex + use SecretSeal#dollar-iris-wizard + use BlindSealTxPtr#content-paradox-dominic + use TxPtr#italian-july-eddie + +import StrictTypes#century-comrade-chess + use VariantName#theory-austin-before + use FieldName#present-flute-herman + use Primitive#deliver-arrow-boxer + use TySemId#popcorn-super-young + use FieldSemId#spiral-road-marco + use TypeName#edgar-carol-mystery + use UnnamedFieldsSemId#freedom-degree-gregory + use SemId#logic-absorb-hilton + use Variant#humor-regard-promise + use Sizing#courage-alien-salon + use NamedFieldsSemId#solar-salad-smoke + use EnumVariants#dispute-natasha-vega + use VariantInfoSemId#museum-edward-mirror + use UnionVariantsSemId#santana-address-pepper + use TypeSystem#adrian-boris-sponsor + +import AluVM#congo-archive-folio + use Lib#gate-biology-optimal + use LibSite#ultra-grace-message + use IsaName#taboo-olympic-cloud + use LibId#germany-culture-olivia + use IsaSeg#size-shake-olga + use LibSeg#lemon-philips-horse + +import CommitVerify#miller-pancake-elastic + use MerkleHash#horse-popcorn-bundle + use MerkleProof#price-aloha-grid + use ReservedBytes1#origin-roger-relax + use ReservedBytes2#florida-libra-circus + use ReservedBytes4#young-goblin-academy + use ReservedBytes8#rudolf-tape-adrian + +import RGBCommit#raymond-open-organic use ExtensionSchema#active-eddie-empty use BundleId#carmen-farmer-diesel + use TransitionBundle#value-benny-happy use AttachState#lady-japan-fiesta use GlobalValues#pilot-boris-alice + use TypedAssignsBlindSealTxPtr#sultan-doctor-loyal use MetaValue#split-package-recycle use InputMap#octavia-north-gram use GenesisSchema#iron-forbid-hamlet - use AltLayer1Set#flute-flex-bottle + use AssignmentsBlindSealTxPtr#fabric-suzuki-exhibit + use AssignVoidStateBlindSealTxPtr#horse-vision-slogan use OwnedStateSchema#python-snake-capsule - use AssetTags#anita-nice-deliver + use Extension#album-forest-heaven + use Transition#pedro-accent-mother + use AssignRevealedValueBlindSealTxid#precise-banjo-ultra use VoidState#email-snow-safari use DataState#short-noise-postal use TransitionType#picture-reflex-brigade + use RevealedFungible#java-canvas-shelter use Occurrences#source-olga-mirage - use AssignVoidStateBlindSealTxPtr#profit-granite-fuji use Schema#vocal-hammer-logic use MediaType#isabel-heaven-north - use AssignmentsBlindSealTxPtr#village-result-bahama use ValencyType#aloha-dublin-brush - use PedersenCommitment#pupil-scale-jerome - use ConcealedFungible#story-shrink-aloha use GlobalStateSchema#silk-college-august - use Extension#ambient-greek-jackson - use AssignRevealedAttachBlindSealTxid#local-memo-modern - use TypedAssignsBlindSealTxid#garlic-project-zigzag - use AssignRevealedDataBlindSealTxid#fantasy-monica-jump - use AssignmentsBlindSealTxid#electra-bishop-helena + use AssignmentsBlindSealTxid#veteran-victor-correct use ExtensionType#apropos-scoop-viva - use RevealedFungible#origin-iris-insect + use AssignRevealedAttachBlindSealTxid#capsule-ozone-puzzle use ConcealedData#ivan-tripod-young use MetaType#quebec-mission-quota use TransitionSchema#jumbo-matrix-normal - use TypedAssignsBlindSealTxPtr#airline-video-travel - use AssignRevealedDataBlindSealTxPtr#ritual-license-arcade - use XChainBlindSealTxid#dynamic-life-brown + use AssignRevealedDataBlindSealTxPtr#herbert-metal-guitar use AttachId#factor-hair-everest - use BlindingFactor#animal-plume-minus use AssignmentType#secret-penguin-limit - use XChainBlindSealTxPtr#senator-limbo-raymond use Opout#yoga-samba-karma - use AssignVoidStateBlindSealTxid#senior-beyond-cement use SchemaId#ramirez-patron-simon use OpId#picnic-single-gloria use ContractId#uniform-welcome-papa + use ConcealedFungible#crater-vienna-vacuum + use AssignRevealedDataBlindSealTxid#compare-saddle-scorpio + use AssignRevealedValueBlindSealTxPtr#shirt-kitchen-blitz use FungibleState#guide-poker-coconut use Inputs#herman-liberal-galaxy - use XChainPubWitness#carrot-import-nova - use TransitionBundle#mambo-anita-plate + use ChainNet#ringo-fashion-enrico + use TypedAssignsBlindSealTxid#richard-double-voltage use Identity#smart-pioneer-nominal - use AltLayer1#edison-survive-nitro - use AssetTag#slang-amber-club + use AssignRevealedAttachBlindSealTxPtr#yankee-lunch-element + use AssignVoidStateBlindSealTxid#emerald-dream-armada + use Genesis#tropic-joseph-permit use Input#actor-minus-multi use GlobalStateType#yoga-quick-jasmine - use Transition#tactic-arcade-manager - use AssignRevealedAttachBlindSealTxPtr#wave-comet-arnold use Ffv#pigment-career-hippie - use AssignRevealedValueBlindSealTxPtr#cuba-needle-salami - use XChainSecretSeal#alex-griffin-left use Valencies#light-letter-comet use GlobalState#stadium-barcode-bazaar use Redeemed#mile-lady-perfect use RevealedAttach#slalom-phantom-voyage - use Genesis#round-sound-nectar use Metadata#member-nobody-imitate use FungibleType#matrix-optimal-sinatra use ConcealedAttach#meter-arizona-albino use RevealedData#olivia-copper-stamp - use AssignRevealedValueBlindSealTxid#photo-jump-silicon - -import StrictTypes#century-comrade-chess - use VariantName#theory-austin-before - use FieldName#present-flute-herman - use Primitive#deliver-arrow-boxer - use TySemId#popcorn-super-young - use FieldSemId#spiral-road-marco - use TypeName#edgar-carol-mystery - use UnnamedFieldsSemId#freedom-degree-gregory - use SemId#logic-absorb-hilton - use Variant#humor-regard-promise - use Sizing#courage-alien-salon - use NamedFieldsSemId#solar-salad-smoke - use EnumVariants#dispute-natasha-vega - use VariantInfoSemId#museum-edward-mirror - use UnionVariantsSemId#santana-address-pepper - use TypeSystem#adrian-boris-sponsor - -import BPCore#austin-story-retro - use TapretNodePartner#roger-member-educate - use TapretProof#marco-border-sample - use TapretPathProof#kiwi-mirror-paris - use Method#bali-boris-plasma - use TapretRightBranch#miracle-patriot-touch - use BlindSealTxPtr#fortune-iron-salmon - use OpretProof#good-village-flex - use SecretSeal#dollar-iris-wizard - use BlindSealTxid#media-judge-anita - use TxPtr#italian-july-eddie - -import AluVM#congo-archive-folio - use Lib#gate-biology-optimal - use LibSite#ultra-grace-message - use IsaName#taboo-olympic-cloud - use LibId#germany-culture-olivia - use IsaSeg#size-shake-olga - use LibSeg#lemon-philips-horse - -import CommitVerify#miller-pancake-elastic - use MerkleHash#horse-popcorn-bundle - use MerkleProof#price-aloha-grid - use ReservedBytes1#origin-roger-relax - use ReservedBytes2#florida-libra-circus - use ReservedBytes4#young-goblin-academy - use ReservedBytes8#rudolf-tape-adrian import Std#ralph-blue-lucky use AlphaCaps#picnic-soprano-aurora @@ -159,10 +149,9 @@ import Bitcoin#signal-color-cipher use XOnlyPk#clever-swim-carpet -@mnemonic(mayday-rider-diploma) -data AnchoredBundles : tapret#1 ClientBundleTapretProof +@mnemonic(vanilla-static-scoop) +data AnchoredBundle : tapret#1 ClientBundleTapretProof | opret ClientBundleOpretProof - | double (tapret ClientBundleTapretProof, opret ClientBundleOpretProof) @mnemonic(domino-waiter-orlando) data AnnotationName : Std.AlphaCaps, [Std.AlphaNumDash ^ ..0xfe] @@ -176,20 +165,20 @@ data AssignIface : ownedState OwnedIface , required Std.Bool , multiple Std.Bool -@mnemonic(scoop-deluxe-action) +@mnemonic(single-today-lucky) data ClientBundleOpretProof : mpcProof CommitVerify.MerkleProof , dbcProof BPCore.OpretProof , bundle RGBCommit.TransitionBundle -@mnemonic(fame-iris-habitat) +@mnemonic(ivan-zodiac-figure) data ClientBundleTapretProof : mpcProof CommitVerify.MerkleProof , dbcProof BPCore.TapretProof , bundle RGBCommit.TransitionBundle -@mnemonic(tango-hotel-jamaica) +@mnemonic(minimum-torpedo-dispute) data Consignmentfalse : version ContainerVer , transfer Std.Bool - , terminals {RGBCommit.BundleId -> RGBCommit.XChainSecretSeal} + , terminals {RGBCommit.BundleId -> BPCore.SecretSeal} , genesis RGBCommit.Genesis , extensions {RGBCommit.Extension ^ ..0xffffffff} , bundles {WitnessBundle ^ ..0xffffffff} @@ -201,10 +190,10 @@ data Consignmentfalse : version ContainerVer , attachments {RGBCommit.AttachId -> [Byte ^ ..0xffffff]} , signatures {ContentId -> ^ ..0xff ContentSigs} -@mnemonic(postage-canary-oxygen) +@mnemonic(domain-annual-apollo) data Consignmenttrue : version ContainerVer , transfer Std.Bool - , terminals {RGBCommit.BundleId -> RGBCommit.XChainSecretSeal} + , terminals {RGBCommit.BundleId -> BPCore.SecretSeal} , genesis RGBCommit.Genesis , extensions {RGBCommit.Extension ^ ..0xffffffff} , bundles {WitnessBundle ^ ..0xffffffff} @@ -217,7 +206,7 @@ data Consignmenttrue : version ContainerVer , signatures {ContentId -> ^ ..0xff ContentSigs} @mnemonic(giant-bravo-jacket) -data ContainerVer : v2#2 +data ContainerVer : v2#2 | (|) @mnemonic(dispute-senator-parody) @@ -403,7 +392,7 @@ data ValencyIface : required Std.Bool data VerNo : v0 | v1 -@mnemonic(storm-left-reflex) -data WitnessBundle : pubWitness RGBCommit.XChainPubWitness, anchoredBundles AnchoredBundles +@mnemonic(message-danube-casino) +data WitnessBundle : pubWitness PubWitness, anchoredBundle AnchoredBundle diff --git a/stl/RGBStorage@0.11.0.sta b/stl/RGBStorage@0.11.0.sta index 3a12b1b6..c21bc6ef 100644 --- a/stl/RGBStorage@0.11.0.sta +++ b/stl/RGBStorage@0.11.0.sta @@ -1,223 +1,219 @@ -----BEGIN STRICT TYPE LIB----- -Id: stl:mG$H7b6I-$T8qp18-07PSNeA-rbEBNS5-$J5X4y0-1vPxRWg#channel-vortex-bandit +Id: stl:c5eyy1RT-t6KrAvm-keIbJHD-CLn9soO-8texpLg-EECfSPw#prize-status-pattern Name: RGBStorage Dependencies: - RGBCommit#harvest-person-orion, - RGBStd#hair-magnum-helena, + RGBLogic#permit-helena-lorenzo, + BPCore#symbol-tropic-grand, StrictTypes#century-comrade-chess, - BPCore#austin-story-retro, + RGBStd#juliet-vega-richard, AluVM#congo-archive-folio, CommitVerify#miller-pancake-elastic, - RGBLogic#import-boxer-seminar, + RGBCommit#raymond-open-organic, Std#ralph-blue-lucky, Bitcoin#signal-color-cipher -Check-SHA256: 1b751fa1bbeea231625cc17129d356fefecb85e0974f343cadf022d6c227ad17 +Check-SHA256: f2f4e349586ba5b8d7139f30b8c0bc13d0b7325b3d4dfdd5986aa015f33ddb5d -3Q|WxQ*>`~VP|CtAXg`>_lQgbaV_>=c$Ts04O39g2dD_h*R5>c*5<{j2~tNwLvL+uX>=wP0_2znD++Ak -!AD4^=04ZLvBczwX;cPMM?zC{WJT(uU)%QMkO4aJ;_ZeCe;xE!X<$x_Fs4If6Z`oP*$Y#2 -a%p39RC#b^b5;}9*VKn|nRBmPlPrrd^EP>$AHP6|FsuXsI;G3ONCrYsLvM0rVsJHoA?4$swuZp1Wc+9A -Of`(TIbyKWjTy4WkGaM+1wm|eR!w>X9p7nv%krpqN@X!nKLI&Lh`~VP|Ct9rx4~O&OrvnOxfr^6gzk#5iY}j-z(!KALU=NBN052vSEvOmAmtVq4l6D4ZcK) +2hLYH81C&KXiWu&flb+s{C0G-{02f$LvM0rMe3tp+xFv-0Xp&G?S=|}9rRaeU`~uMrbA>C`}q*r3sZD* +X=8L$d2nTOVhoMD*5<7|86J&wS3rOMJWQ?e22w{tQ*>lva5aA+<>R2XhQO_4{AcS- +HH^7AVzASV8M4NYxyCjHL2PwaO?m?z-)Viz@~C%8KNS}Z0aQ3s^SOqbBwN-D{wl@OCJaMwZEb0ER%LQ& +W_h20XiL(ap`B(@2KpYTJ%x(DC3d{wiWYg@TKk|G2{Q>&M?ynyZEb0E$}AplgPGkh3_fq3Q7_j=2#kPT _9!;lWR>~GYywm#15DT%6aZ|SrJerP1pIOD57`7Ol|-ogQ6Pjg~y>s-v>!^VNPLfWv4Jz0xkJm$nc4y MWR2J-cc#Q6SofWC)gp7L6!Sc3I$AQVo7AP4Jk3r!|EoW{Zi$060oMN(jLzPuNboiNpoRS -WoOdj7+WWC1?EKi+6QrwlvP$nl8x-M691f9z+~t)>6ivgX<}1lX9hx0LvM0r4FCar2VDR_OBR)w8yCZ2 -EylR&t_^>1Sz?kFbz0>alMxYAVQ_L~bWU$%Wl&*qbZ%vG1JyK;>qK>mX$cszrKCL=@F5H{a;)B(Tlt4r -og*WC5Jh-!Y-wX@bW>$vY*ct@WDm9jq6_bZBp6I6q=8aZ}RBA(1@GcO9QSWZ!o3C{DWI)5Jeow&v$k6@5bjw%EMbM&T%L^glVtzy>c`nt -RvSTXV`y)3O=WUxY-K`hZ)0muaB^jIP;zf?W@s7fyw$T9tCzEwrAszt-P)%HZ|LbH=L2A=l(W4CP6|_H -V{&D5Q)OXnu*Pw&hI`xNV4B0;>oUbhHyi-Y#=22)QEgSwgbZe&wsVQf@*X=JhGI5`vwIKJ?2 -8qdBQV5M*2;q-lY2q<~K(fZR6A>9R3cu;h52SRCdV{d706aWDkZG|bw_S!^E6;6$ujJ=)@jfnzUJFt-< -#ywK79)|@}WpPe#3K@{sQ}POxW*-wf^&?6pkN!)@-3ce88{`DNj-p1Y1XOrQZXx47L&d6G@+l`%qd385 -?K@+fP1(-9sgE>i7rMzqbp%##b#x`G^|=xh7rLW4)L(lQb*FJl;d*r#UC=Q#deq4+>4pnaV{&P5bV7M_ -WpgpRuIPk`cg3&=F>*1@lJ+pRDJ{*3f84s>#k$1lf7uIEVQ@}wWMxQUb7(c%9ThnsZoA#wq{BUjG3xT0 -r`mMiJ;;I}98MOsxf}>gZ)0mzX>DaVbp)|Xd=5r!N1hi)eI#@wfA|Ar>^)1W_c|c=L3C>gQ)y>YV{&P5 -bYHC5ZRI~s#T41Gjc0(`3ajfaCJX&HEu+ACq+L0mO$tn9VP;cfa%pgMkUL~>d4!J}CQ~Zp&c>#RM4(ex -xbT6?CbPTvEuK5`1yp!Xb##~Y*9JnaDl?KLJE%?_&cu`BzdqA(v4?YpHBQWkf@=g*VRUnyRgqGWM}19*F@#XVmjaq%az$04KD-Vbij2IPrk>V1yp!eWpb&7gm+V(X#23g?#G%T#8*SXRQUS6 -KbYXtkv-?PH+Tw3ZggdGZeeUtYqm29sTjYuk_~RiSfnI}BSut4!A4H=_ds@ZTntlVa%pgMP<3K!WqHJMYmbj8(R#s`$Q_Oip_^hvoaWGE -UH-@Ecs#X-@uLSqd30q{baKUeA)3GUIc{=BfUQMVFMRBwY;Hd$-Q55DeryBg+(ZIYc<5?C&0HnY62ZUYgq2{$1_)1ebZ~EJZgl*jrz*aY{>_4@v6zr!BEn8~s;V{eB++vPW1tu=h*<|% -Pi|~^P-_fBZ*6U9bXH|@X=Zr|05Fw)<{e=)S-S-YQ3WPbltNdpi4*91)SI!>2Tf&jb75y?IG#g>Clv)aMjKgwAH@`bu1x<7g|G$} -;xvA~n-$_S3Qc8lYiwmmVRL9)&E@`k{z!7(TI@Y9B6!g4sB24Po?(Fc@vtHNfU4XJO=WUxY-K`hZ)0nd -_h5K%L=laq&yA1JoJ^{7>oKLkF4~iax8KK|47hp@Qe|^xa&~28LV0v$b1}=fEj#9D^K)f#Cf|Xn@L3mU -0Z2&n-dr?jcD1Ll0RawDWpib6c4cHjd30rSGT61bmh)A>-9G+(AKhLw+s!eDmlO2>&}_PPHjCBJR|r&c -Wo1rpWM%K_6AuO0fiYoI|8ZKC9(55{UNs2(LOhfb*8wh)9?K3=Wpib6c4cHjd30rSH2#7XN#A(BKKz&v -`r;e6DUv<<*U}c>;b184%wsNMHUptBVZ#B!U% -rHo-i1kG~VoNp!e_~i}U4@G!%Wo~n6Z*Eg#Xk~3-1ACLTJsO2B2U!6ncg?mz@CdC==Kxq?gSEg)z2E{| -2tsvkWNc+gWC^x^65s1c;WeUUgB8EM+V1n+T -F3m?Yd1DC`X&GvUv9(-1>WQHGZVX3kZ(?C=R$**)WpflIJdRMsrjHBJ^EIe4enz&iEACnc`NWk%>en!w -doT%2WprUyVQh6}6`5yb%eAXO2UPPRaj@((`=>9Tsh)f38uw_!yYu^q2uW^mb#zT(a2QC{)5Kh{xQ8## -XkXX-V5JAC*Swe0D}EgBwY$m<1r0}KZe??6b5mnzWo=<3S5nwzfbg8kY9lvP5=0XL2PtPVR>b8F;iu9B}H_;!MSfIY{o4njA(e*y9jN*vODbSxwYq{gu+hp5Knh*Wn@!yVRU6vV`yb< -VJRgJ2Em!ld>cVuZ*8Se%j3y;5n>eohpw0DA7$}d%n3nrb7gc?VP|tLvZekPz%WEGnBZKS8(M7E9_@Aw -VcyGtCevi|7U8=IR&Qx!Q*>c;Wip;tQ3m-<6)UHjqig^*m4co5us7ukl*0UQzs7w8g$YDqbYW9;VRU6Q -QV*^ZmKt8YDf|&5KZQ>65I6*X)C9iYp+?yjr7~y^RB~Z%b7^#GZ*Ek1aAh{ZG@<&SffJ|QFn~N>u=2wF -+7z(Wqt=tdZk`V^s(A}fV`Fu4a%FB~WpgMdwWnpYocu;h5IeTD+$oD|6lahT-3bSoIq=nQXM0|*v-OPCjO=V)bO0J^ce(PcW1p-OKH=(^)qT -gDk?v){Y2{bs0f(b7^O8ZDnqBb3$xsZe&wsVQf@*P;_!e?dHP>9R0ZFSEMRj;Km4qfBYZ5UUs>0bg9bq -iCNAIR$**qZew{=d2nS&y&7&8`-VFfe10WfHD}v`L+>hHy6d9F3e5?wo>3YSP-SFga&u*FLvL+uX>@I6 -Zgfg$dIyj=yj0m~TwLF91B-Lz;+I~gZmLfZ*F5{VQgh&Ms;pyX<}?;QxVNWsw`2k$dAVY -YJsYG;e2<6^ZE|08NgypNP%NA5%VQKM}UDECiLhAbd;J)AwhFi#4d2nT9L349yXKr&s -Y-w&}Q)OXnRCsA*T90!HB~2q+D9Z7_cLRiBQrIV5qn*4?Y6;!|pLWveA3<|-X=iRyWp-s@Y-MCbVRT_a -Y-w&}Q)OXnRCsA*Vd@w5&2+699UCMSB2$w)@^&J+aUCZtmJ634`nl9<7(sJ$X=iS2Wo~qHLTqVnWK(5f -Y*ct@WMp+7La7y@JVOzJ)&GXo9MeQ_qmbcB?4VH0I#X{*-VH@~bY*UHX>V>+d2nTIM8@PY!h`6Z9%SYt5l1;p48RB~Z%b7^#GZ*Eg#Xk~3-dBoUB2y8Zom7+;NN8Xgkb3WeV -)QDb*=NiflQ)(Iz225djWpXilvNdf$cEfHQ12?LRftc&;5JY%0?GSH0jXJ{5?wvjwRC#b^WI=OtX=iS8 -LTqVnWK(5fY*ctqbaH_n=a&wUzgWZ$SVL%GX>LMnX>MdwWnpYo -cxhyWaSf9!PV~dK2uo>;u!nFdemP_$e?^hl+JkM;eY!XZL3DIsV`xcag}C@DyY!@{4YR*LMYs=?Zg_*k -tx|21^lzg9sBTBv4nk~cZe(e0XGURTbZ>Hp{^Dg=h-~N_zJ`Red1EINWrM}GXaQb}6c#qIM2EQ!L349y -XKrm}Zgf<6aAk>WSS8KIkY89@$6%;X7qJ(R#b4x^L3+^xAn+qc8}SNQLug@XZd7<_WRJVT=tr7P^xB4~9 -n`Dx!RtcK)nwJGnaBp>VlfaZ*5|&qoaMx&cZSO)Ho!_*yjLvyQo1^f$X+6j;96@t)X=iR$Z)s#xbYXO5 -LTqVnWK(5fY*ct@WRz0V+XJhss8OG%_CC-Q>(otsF+cqN0Qy}ddQ=3E5C~IaXk~3-No1AC=6W7=Vqesj +WoOdj7+WWC1?EKi+6QrwlvP$nl8x-M691f9z+~t)>6ivgX<}1lX9hx0LvM0r3;+Rq2VDR_OBR)w8yCZ2 +EylR&t_^>1Sz?kFbz0>alMxYAVQ_L~bWU$%Wl&*qbZ%vG54IneKN{_;j(f`H9IfkFzO$PGD6U0+eW+%HuC5$^~^vuG3{`}-8x6fV={eh1!etXz_4^&}ra%FT-VRUFva&K>D +ECY>5OGottJZHLg1Ujv+c;>sahi4MJ>bZe&wsVQf@*X=FG*VlHu0(#Ro^Jj-_-pFL#X +cJe4ySuOZRLzEUxZ3PijVQ_L~bW&+&XmmnyVQyn+M^4XN(CAD)cag{ +3QuryWpq$-Z*OK~K*OqjPr(1k(EY-6%U8=q(4?)}eJ3)E0#%9cElQglL2hGcZ*om#a%*g5LTqniYgA!y +a%FT-a&K>DWMEp}<<2L&Dqlb_e6Pm!=_rp}o{aaCWdH8!$Jtd@8$oVkXm4^&WpZn5WkPIkV{1=va%FT- +a&K>DXc_Cg)w39@m$R6qOEzWQ+NTC@=;OF|0}@Y#k~NrxRcQq+F$P2q2)nlUE64L7%3W7R +4nk~cZe&wsVQf@*P;_#!ZeT05|jA;vvYupWm6Q)O{ZZweWZ*HiKem1Z9kJM|+S+XYD&bY*ifyRPVjiFd`Y2QhLn&64&owka*miGSR>-o?7a>3`V^RAF#V +Z)9aiVRL9T+8q@+Aa1+e+@!-jhcW8%o2S}z-#y5JARJB>wYeM!OmAarRB3HxICTWEOMDJSZAYFLM|~u8 +B!Bn=Wb8dls`ok|_d#@P2~%ljQ)6;zaCBd+*=^-NPQ?`2v5jYd+6t@dEhY>7H!Y*UdZb-BpG^u(WnpGh +V{&P5bdWn_aCwA}8zxgKpy7|rEn>a@Jg9&ldILR+=b-aAzAVr?5I2ooM2UlryZe??Gqk=;7%h%D+ +p%U7S;b1RT)c9`>#Kd;Rz-U=aO9W+B1XOrwWTLLzo&{8R +R%LRjg@kugo@o29zwXDHA;ech!BqJAy+4@X(~&*rw>NkSNp5sya&BR4P;0g`38@&rwvr8Q$XKK#ha*N> +X+Ls92fzOv*E(~7PRR#MWnpGkWpcj!9{gsd8U18ZYC02#KAOx^Y=h@bX*KmV{&P5bWn9- +Yh`)Fa%+!|DA9Vsm&hHC4WXN2M4aZ(WL^Hp>3BS~hw-BaLV0v$Q*?60dm);?_c?BIMu4qFRxf<)p=@qH +Cf(fs{C;c$=G;UARCwrWK+Rkw`Mu(V|7oQWGN(Z+AyvH&RuaL#N4?X)a%pCH2>>vae&!uvG+Da^2;||fJ!&Dp +*8BS%F@mRgsZfv!yd427@;7veO2zMB=|GYU;*a%*g5NMUnmT+QYFd;Umr-dgNEFCuu*?Wk)@ +WS(Jw`th(K{eY_63r%HmYiwmgY;R+0llNeFa6}P}rq7L!(40)FbL%msz%JU8hqvFyoea2o4pL=vWpZ|9 +WI}m#WpgphxGg*8X!CPrawgw_sqk4BX8}k^^xj-FXm+)yumJ%MQe|^xa&~28LV0v$b28Yqxt8-)z}-In +eIMOkG~3NFhnExe0MKl@b~cOE&{qgla%E*sZ)9cf>JtwI*nu%&Q~z;Vl^%5wS6(#;{6ajG64wDPk{-(r +Qe|^xa&~28LV0v$b2R>f7D?ZDzCQez5c=X9w<(f6`q$DH-G17V_XV{1(H;&`Wpib6c4cHjd30rSI0;fm +LPKwDZE18o00U?O%&6V>N}#h955#ht!=;R2Lj=uo+MI7C_W0!u+z&-~bY*UHX>V>*V`yb6Kou(dlA0G^4k_f9_{X9aCT` +m+=r(a$#@6CZbEf#WNc*#wto`e>uZ$?1z+)WysMU3t2e*FfKh32^DD>YKF13Ts`WEp!#kMM{I9mVQf}mY;|RG4AaeCy`?B|MH$#iox7(epK^GJZz3uq*Cb2l>R6 +Lh9EroO>_{O=WapR$**)WfhrcWXrXyKnGOwA#t$mH2bG7pQ)aE=^FQF!@KkQhzLn;aCLM|VQ?5o)zidW +vABmX&uCxQ{9vUAsn@)h(<^=)@3p(i4FwHHWo~72X>(I!Xk~3-BTDP};0*ks55c}RUto&5M4d4gMbT{# +8YchOlMBbi89{S%X=iS2Wo~qHLTqVnWK(5fY*ctqbaEu3O})vuwNYes?|slVUJVMdwWnpYocu;h5B}H_;!MSfIY{o4njA(e*y9jN*vODbSxwYq{gu+hp +5Knh*Wn@!yVRU6vV`ybbY*UHX>V>RL|e#I +O-TAgsp%#NX)%c(fjr3)`APEDlE~V`A*D$QRB~Z%b7^#GZ*DEpeMzTb7O++N8oyXDpZBoE54a3NI^6d4 +KBMdwWnpYocxhxVvZekPz%WEGnBZKS8(M7E9_@AwVcyGt +Cevi|7U8=IR&Qx!Q*>c;Wip;tQ3m-<6)UHjqig^*m4co5us7ukl*0UQzs7w8g$YDqbYW9;VRU6QQV*^Z +mKt8YDf|&5KZQ>65I6*X)C9iYp+?yjr7~y^RB~Z%b7^#GZ*Ek1aAh?*h8FxqMGF>;)g%0j&kVcqmr((< +d|oa*W2671#lR3!Wp-s@Y-MCdb#7;AVr*qL!8D=zpn(&o-7tVWUa<1Q{n`|;)uYyv!)~4rGOBqCPh(?s +a&l#EV`XzWdtiph_du_cl6_7Jvu!-2h2yT^5yv>ite$I%(jAWmQ)6glZDB$%VTFju)Tx{+}2@b8~5DZf#|5baO&%X>MdwWnpYocxhy0bsj>g6`?#s5rWnKhSeO? +L~x^!;Y#eFP|P}0Z%Ez^MR;^&ZgXjGZd7@2Wp2#WhI~QV&X+ep#A6w*Y?6dZtMP`1@htLD*t(0EsUbmg +b7^O8Qe}2!VQgh&L3DIsV`xHbX>MdwWnpYocxhyC4P_9rf`M-zw>{+&W0M0{2&GbCtpecGzFNi4r|Jm} +LvL@6CZc}4uWo==3#Mns)Y&M6LqDeqU-jv95KHlThh+c{3 +8p;h*Y8ns*OksItaxs6+hz+(e+q|0DOh?)N_UyZEhuA*+>b)o!7;u!nFdemP_$e?^hl+JkM;eY!XZL3DIsV`xcahyLPaScq)s +9KMExvw34D6J>+NwrBxfixd_%u|$Wt4ncEsX=iS2Wo~p-d2nTu5WIk~G+K)5%bR49 +t5yk`^qQ9iPjGK_bd*xl+XJhss8OG%_CC-Q>(otsF+cqN0Qy}ddQ=3E5C~IaXk~3-No1AC=6W7=Vqesj RYGc!>wZFzp>JB4@xD;^wu&SY_r(NHa7kpJ2rNlD$O59e#ogQsB77jPl+h5j^*S;NLvL<$ -a$#e1No1ysFp)<~$~wYgjK`HkjV#@&#T1_fGnK3MJXK)_7bXoxb#7;AVr*qobYXO5siJyUlgOLOB};96 -cGdSG6&iv=7PD~jruGj4o;;a=21#ykb#!yDjhE2@R4ADY@XOb3WHJm&VktwD1&R~J8Qi15W{8UrRB~Z% -b7^#GZ*D?$Ze(m_w&;L{94K`ndk%K5+?9Jv$dw7jc}U5p5@2#$kUJ%u2uWmRZggpMdB|&mdkb29#*qXh -a^)f?kI>J>8dqqbOFybHKpQ-MBMCulbWCA+WpXjekD95&21^?K{bw7Oyejxis%MV9vZ(?C=Q*>c;WmI`^W!4yF%LYxT^jDrckDVwO1AtjoG6an*A`7gZ+wE6AH40R6VQzD2bZKvH -*1R*Z!FE#!-}0MzvBUkD_A@LX?C3dsb3FQUOt}RYB0+O=X=iRyWp-s@Y-MCYbaY{3XhLjhZe&wsVQf@* -P;_$In^6;37FKqUhx?i3R+Mr!fY&(;2BFL(m@EZk_srD;MrL-}#pxZ$?Eb+fZ@!;9xB`-n7hgEflW({{ -JNKm>5Mos!L349yXKqquc4c8~Wn@-iY;|QqY-w&}Q)OXnRCrKya@&ep8iEuMbtv-qj6g$b#7A9pc!|f` -I$jaRzSe2A1Q1w5Xklq?Q)OdvWpqv&8b0-V>p(oz$%022vTKaWo2z;WalM|{+CCYqok=CI6O*0D2Q5~XK8~xVetWFewK9hZ4Odpc4c8~ -Wn@8gbYWv??6T%|znQ^KeoD%bg94CLCf*q;P?fLY7qq^#2NiM*2S;UYWpinB^?FS>S$_F2)vN@Mb6UJ- -F(lri_dqerx4lR4>iBsz2u)>lVPs)+Vfpl|2xhK9cV^W63=w?=$`$i`X@y)HBPPGtNLug@XZcue%S7~%^Wpi`yAASLvLGVedrqOkAVG6;X=iRyWp-s@ -Y-MCtVQh6}LTqVnWK(5fY*ct@WC&76LQHRGX=4HaT-**L6)$-r+lRyXoI{GIo*U3CNI7Emc=xo*$N+#6 -3Rh`#Ze??GP;YZ`yF$nqQ(ZC7jQ{zx3L?h_$J($?&iPIm+b{NqZ<^r>S7~%^Wpi^+a%2WlM?zC{WGVm# -J4=$RltJLk?Nfj|sXiSdmgaJi@wPyW+dHeUQG($LP<3KgX>@L7b8`lmt+(1Z!Y#S=r-tc=NPf>PeW=$` -IKP*ssSB}HE2RoUZ*FvDZgf&*W+BHHZO|$}9Zg=R%ZE7et&pz}oUddU0B(<>YerIc3kOqaXF_amVlhkK -9|TAhYfrNblQVQ`LpZXKteHopy#|_NJkG`K5e`9aZf|s9bZKvHPGN0jHx3&bJ$HXE2K+s|vHZ6#&ske5 -?JSDZAfr}PGrQJ;4^(ntZgXjLX>V>xW?^GxI6k{n`X+XC81LasyqR+($`>jwnD57lV5q8m)(2RS7*1hr -Wn@NaWo%?ra$#@6CZd7@2WjJdtcwu66snXR_9Zdb&#xLPSG6d3U8q**F>Pta$W)4MobY*UHX>V>x -W?^GxIma44eh@g%x4xWoee18jkej%UZIDDtP|$FhF<2o`1xaRMV`V$az<~n@;VY|KA!vt$qM -Ep^75#kD_Tqj3jGW?^GxNn}22@%59@e*l9;LQD7pr}6`4EeCo&xZzHANbCVxZ$AuHVQgh?V|httVPj=J -w@A-6`Vp=cnK>{7wQSPJQFX$PK`>V6xnyyv_mEW!L2hnubYXO9Z*Fr-smO?_)Z;5^`KSD|ISj`UH_gGc -8EgQVv6`Tqlln6YL349yXKqPmVPj=XbV6p4OMBubAg=+DGK(xA?XXJF{2H^dT~zWT)b=0OBT1J2MDVb#QQO -Q*~lsKY4$``7oZ);noRy3n6DO2)Q4;H@bN5MlNj7(#BUDPjz%~b#y^6%<dWpinBNoHYVWq36o>AP`=z3=Ru;NRp0 -56I1tGJoS+I(F^t&c0kHT?s*MV`y)3Q)P67S7rwg9}|^$ORAg?_G_n1nO(?SEuMzN{%51&MrF+jNoHYV -Wl3#tY=#&RENEw7&f?o%+)B!ZpG}K!%4G?I4vp$|ttu*CMGHf3ZggdCbW>?(bB4g)fE@Zx_8VV!VgW89 -U{2OOpSL%4#$e>_yXHjFISEsBaByr%bY*Rn9PeeuXILaAA3^JIKdZ3ic!M@6PJV67bl-3#Cg!RLO>bmr -W@%+|nIb5$QI^$V6PNW$vdMt6d#0>Rmk*`=dQ)K)k7d+w7*1hrWn@NaWo%?Yb8~5DZf#|5bX0k8Wuo9& -)X}ib9i^%gOs*8bY}uR&S59aNAMwsm_ykY{pbAuSb#rt~Wp-t3y@7~gQVy8J>pg27DwvPuRhrP3QWOC! -bDKQy2TX#&5>8=lWn@NaWo%?kWprUwd2nUJXXT7NJOW`Spw3o_*cmz+=1%_1gm*5-D79nn{HtCLPGN0j -WL9BvX<=@3bvVaOk0BBjil877-n>SP^xWIoCC77|*ORF1g-x>(>`)0$a93$`Ze??G$6skVRwOM6wz9dS -Yg6i3-rmX0uFE(Y8AEY@srN=83sYrbY*%S?Ze??G$_VC=pB%K5hwN>99K@5|(<4SV7$Q=&CebuM;tt7# -3rB2kVqt7aW?^Gx(swU)=eHZcWUx8U##PM;a30K-=Jl8VtAf?Zi=Hx63{zuhWo=T!Ej;9TxQjc0+10Fg2)p -3Qu=#Wn@WaVPj?D)D=(>(T2L(qY0=?Nc;Wdl=mWC;K#gwc#^4#qsMUl{*1zNe>I^CwqAYJB+ZKALhJOg5Ma -L2PhnVMAeXb4b1;7b@t4MVjY>G@u4Q3HlB(d+LiLJm-R=h;`?dxDG*cV`*tna%paKVPb4$VTK~nd#>-Vi}-aA;vuZDDL|OmAdib7%`wbaH89bX0k8WpfVz35LOoBKkGa -Y9#cS7Qj{WgyAGcS>>g~&^g7Kv@4tY;$BCg=lGO40qbyjMBe4%@A^HhWa%pX8bZK^FG5w(M*PErP -Q*K8));4q9;G_%)IzXn}g(wG03t}BM5{Lay5>;+)VQpn(MrmbiWOGwxZAoNn1fvw5rj-B|XP@r^w5ufb=C_Ju$l1`n -W&GEpSWb-vQ)O*QWPQm(C)8p9*(R2SB=5|9lKCV3N0b-?Ol>0MdKRd5P6t+Da%o|1bb-?>B-g{}GTFmo -{mAr>kexq=D7-RGP2^0W;fb3W1_o1UdTDNFlG6hDK5~2WhJ*PG7zYWLxz$!}&%4AY&2YWlsz$Eb5Kduj -Wn@NaWo%?~Q)O*QWS1d>s?i)zLD2{^84?*=6Qgx+ -2Ybs0Lm?xkSqB0NLAl2~i-ZdPG(X<=@3b5mt)No4(ju7iFH2b-u)>&PZdlOljoA7|k;k>s6qoa5|8f~g8r -d2nS@d2@7SZ3X}hLvL<$a$#e1Np56icm@ItaCKsAX=6`tZ*_EY00{yhS0}9Zh)e@5%bR49t5yk`^qQ9d0000000030|Nj600000EZ*_EV -Z)t9HPjGK_baMa-0w7l>toMja192_(UwD?W=?zm*&IhOn$k(lG-qz;DsnKT_y+ac4_6daU{%%bk3j+fu -`A*2Y1(Gbp$uTFEssITBAXg`>_lQgbaV_>=c$Ts04O39g2dD_h*R5>c*5<{jlMuXsu{2tXFT+?;?hj39 -&>gq>HOrf1lB-q;n)I5N0000000000|Ns90000000000000000|Ns90000005KU!mLvL<$a$#e1Q*>c; -Wd;Wbb7N>_ZDC1d0w7l>toMja192_(UwD?W=?zm*&IhOn$k(lG-qz;DsgzRF+XJhss8OG%_CC-Q>(ots -F+cqN0Qy}ddQ=3E5DH^&Zgg^CV{}Pm0w7l>toMja192_(UwD?W=?zm*&IhOn$k(lG-qz;DshAD4^=04ZLvBczwX;k#6 -*Wiap5|FEe8kw!8dbCNj+WG;-FCN910OIk;E?fWr0000000960|Nj60000SQb#7;AVr*q|00{yn6$0d# -2P+C};lr6VNhMM>59zuEq~<=?!m-5UiD^{RS{k*RP>KQ|D6@UrgHD8Pn~kr<(gaR)wpptCRljin00000 -00030|Ns9000004WMOn+00{yn6$0d#2P+C};lr6VNhMM>59zuEq~<=?!m-5UiD^_|KY4$``7oZ);noRy -3n6DO2)Q4;H@bN5MlNj7(#BT+0000000030|Ns9000006VRUq1V`u;g0wxs#KG(vr#N>%-RB36-k*iEz1m@>LhD1|b9AmK%IADG&k)euf*x}6a-2eap000000RR90{{R3001i!M -ZAWZxVqt7kbYXO51_A|ZZf|#P015&o6$0d#2P+C};lr6VNhMM>59zuEq~<=?!m-5UiD^{hV;!^nQC@YX -pR0TOwJqTsbD!F2W4d9F8pxqnXBGnjAXg`>_lQgbaV_>=c$Ts04O39g2dD_h*R5>c*5<{jGM-jZ2Kh}D -E2o;HYydTtf}Q!WH{}bI!u)W*#(e~Z0000000000|NsC0000001#D?;X>toMja192_(UwD?W=?zm*&IhOn$k(lG-qz;Dsg=m)dLDIRU(}XWLTZugenOC; -Z(5k~zEJnJiX;;E#R4E#C#?5~OapN(_Fs6GvFQy{P|gRa2*}s1Y~I%9#i;{(leIk>g)RqK0VQ|Mwn6X+ -txo3vSYd;;z)HQ~0$cz90000000960{{R30000wWb#7#AWkYXnbaG*1bV+VxWq1Gz0w7l>toMja192_( -UwD?W=?zm*&IhOn$k(lG-qz;DsRMhHwLKbzE(ciwC3nrXLGTEzPUiqvVS}~6O1_lQgbaV_>=c$Ts04O39g2dD_h*R5>c*5<{j1ACLT -JsO2B2U!6ncg?mz@CdC==Kxq?gSEg)z2E{|00{yhS0}9Zh)e@_lQgbaV_>=c$Ts04O39g2dD_h*R5>c*5<{jp9m~TI>-W|y2ahx3nF|V -uawki#7NH?S|Q-Q!u2{b0W8#V&bbGUt!Bq`S1yuTOW~jDcd`iI3^X_>4e9 -YQ#rfba;u!+d5tm#=h2RwFCeO0w7l>toMja192_(UwD?W=?zm*&IhOn$k(lG-qz;Dsgn@AfUz`Mi!Z}i -Qtl5;XwV(E`Zdd&WRj~^37YhpmjD0&000000RI300000000000000000RR900000000>QGZBuk%b7%$) -2y_lQgbaV_>=c$Ts04O39g2dD_h*R5>c*5<{jlv2~%1FNg3QJ<&wKF}2F)J=Uc -Km7gx`duV?R0NO^0wxs#KG(vr#N>%-RMK}Zb?3Jmz+|vF&&E~F32+|F -mge=B|Eq%4$%~#cQ~&?~000000RI300000000wDhVPj=;015&o6$0d#2P+C};lr6VNhMM>59zuEq~<=? -!m-5UiD^_j%D{mG2;nQMTOnwNgyXhzrB~SH04;UKo5i(1Vxw^aCKUqYmH4o{!1*GOa -*TS*H2rNlD$O59e#ogQsB77jPl+h5j -^*S;FAXg`>_lQgbaV_>=c$Ts04O39g2dD_h*R5>c*5<{j?6T%|znQ^KeoD%bg94CLCf*q;P?fLY7qq^# -2NiM*0000000000{{R30000001#@+9aBKhy0wxs#KG(vr#N>%-R0f!> -x7s+uExGllhUte$e$Op^sMk_Bzn7+|3$axzr2q*6CKUqYmH4o{!1*GOa*TS*H_lQgbaV_>=c$Ts04O39g2dD_h*R5>c*5<{juZ@?{0aPfN4Did>Ze%hHN@6KP -lLd+s#TneAz-EYx0000000000|NsC0000003T1e7Wo~n6Z*Fq{3IZTkC#?5~OapN(_Fs6GvFQy{P|gRa -2*}s1Y~I%9#i^CZ=6W7=VqesjRYGc!>wZFzp>JB4@xD;^wu&SY_r(GrS0}9Zh)e@_lQgbaV_>=c$Ts04O39g2dD_h*R5>c*5<{jiECIT&Bl;lSX#$ms8AQN7m&qYKG(vr#N>%-RL5UwIaVYs3AVDiqia*@S>E2s&92Kh -8W}@zf2sFIAOHXW000000RR90{{R3001IJsbYWv?ZDnqBa{vkgAXg`>_lQgbaV_>=c$Ts04O39g2dD_h -*R5>c*5<{jgmDd%EKc;pw+KsVi?D}qDSkO*B!5Mb*xG|_(S5o&00;m8KmY&$000000RR900000000000 -000000RR600000001I_lQgbaV_>=c$Ts04O39g2dD_h*R5>c*5<{jkGsO? -N19ILP2yc~f4%w>xYW^+v~7{W03rq(;firJ0000000000|Ns90000003UqmJWm9=`bY*PC`}q*r{eiB7ehUYis7~w1CQOqefKeZ3;Wd%uopqe!>_vj93Tb3zZggpM -X=QT&3IZTkC#?5~OapN(_Fs6GvFQy{P|gRa2*}s1Y~I%9#i_RFfQB3>bs~EXcCXx(drQcb3B`Fx$)^%v -a$Ar)C7c2#6$0d#2P+C};lr6VNhMM>59zuEq~<=?!m-5UiD^`#;91nsu+1H%suE1D6u@lRoC;S?XbB(j -&QSOSPz0a=0000000030{{R3000004Y-wV1015(Pa5aA+<>R2XhQO_4{AcS-HH^7AVzASV8M4NYxyCl9 -FjWFA`CQ2GiK9iLKbGE6DZmrA4)G`0A&^0p`%?-6VsJHoA?4$swuZp1Wc+9AOf`(TIbyKWjTy4WkGaM+ -5(KBV0uX$PL@)I=)&*`^S@`8Scoz5#{lyP)a751L0000000000|Nj60000001aoO;a{vkgCKUqYmH4o{!1*GOa*TS*H^^GknUxTJ!XL#OUcE0wxs#KG(vr#N>%-RE8K3ENEw7&f?o%+)B!ZpG}K!%4G?I4vp$|ttu*CMF0Q*00000 -0RR600000000>QGZBuk%bY%tt33q99Ze??GWpe-u0w7l>toMja192_(UwD?W=?zm*&IhOn$k(lG-qz;D -sflY?CC$c=UszhlV5m?Ru@{iVU*wrVdeH+Q@FPbX@dBEuZK_k`JKyPG=Rp7@Nbf+-FrJ*HF>i&!wTZgU -Bh_-dLdY0XT`|v$|M|2EBF6^D+OST}`A!+zFZPFTn&AKd0000000960|Nj60000SNZ*FvQVPkZ2015&i -S0}9Zh)e@2rNlD$O59e#ogQsB77jPl+h5j^*S;E -cA8SzdwhWF9dgX`>ZnjA*51^hO#z=?KV_fm3KoU?0000000000{{R3000000 +a$#e1No1d<IUvP{mXY}ey+|ZdtG&qC*MSg*Y`lhfb^DEW}Lug@XZcb%%t-SO+Y4cU? +c}!0zvoT?8H=D1RsoC%sRTdL_u<=_d8B}?2Wn@8fb7^O8b3$xsZe&wsVQf@*X=JwOfQB3>bs~EXcCXx( +drQcb3B`Fx$)^%va$Ar)C7cLJWMyu2X>@tbRHZ_FJ{?>&Rph7jPVW%b(L2*g%&@>wmxoIA`(ME#L349y +XKqquc4c8~Wn@8gbYWv?LTqVnWK(5fY*ctqbaK)dll1LbcY^ob(uSpY74YD(LO1vdEoQwrK}u5 +b8~5DZdPw;WK(oubY((pX>MdwWnpYocxhzPv_t#xfeQO-*^G1%CWcW)(d=A`A?1{twwBf$2YQ1CM`dnh +b7^zcjb8{1n}Vi_2Sx(mPtQ%C7;C?4Hp3VmIkXhJs^;PaNp5g;bk**X4oQf!Y4K`P(FaQVwIle)QgI&p +Ha%8Z1>xis%MV9vZ(?C=Q*>c;WmI`^W!jrj6Id2jc94hrndMfLayEe1ISdA&%p{mB1!VWk)dNOmcHM<$ +0B>Pr5ftu@@z<*O39}j`u&O7io3b$Is?RA$O$kloIF_owDud_0-=Ov5& +mq(eSq^TM>JW4?*h+3X!X@fjr@d0IimUQ-Q4pL=yWnpY(WI=RvVPk0ZdQCW4e)%xftOSp9TD)g5B;KO; +Krzd=y+`rt_<1!5O=WapWMOn+`Sh#^X0AbZX4L%*5q$))*;M@wXI>IJVg&1PPwC}G3`TWsXK7+=WmI`^ +W&AWn-CxfQ3;(PYq*(Q&@ei9r{ +b#!obbU|}-X=iS2Wo~p*Wp-s@Y-MCbVRT^nW^eLnZQ)OXn +S7~%^Wpi^O#}{qTDnK1gUZ=~4IPtBJuMnKCWEcQ$kD_ZvQg;gnQ)y>HY;R&QOWz*^NEK^Ovka3nbZSF5 +vXHEqN2R?6nqxf9#qALeL2hnubYXO9Z*ERuZDltO8yY=#e=i37J-o5}w=U0FTPy7>iqjyYR#Y>))`AaI +a$#@6CZb@cgV`Vr#yHxrnc61o;;Y_@lb0o?aDlVAs$BAI5s(jW5SdbV_VQpn(MrmbiWK?otZgXjL +X>V>+d2nSoYc6p#+${pKVqYC2T5jO +V`WKXK5OyylhJ#}PNp!L%7{0GY9xpq!KXGYdg; +b7^O8NoHYVWlVHJW|2#K;wB)k0g*C`Fwq1F!!?eFe@CD1{Hz9}!v$7la!zknhozd@T(rwWP-G*~32(7)!VKwhueASIYDuGM{9p;;;bXCQUmt2vc=%aBNd`Vq-niiLgsaRw~c9 +&Ny{YCK_TCaeS`x+X~XLW@}|UwF*;paBys8ZDnqBXEKMt2yp8annvOGPI~_sbHU;fx2Gv#gJM&>FkgU` +2UB%$aBN9rX~bo}HX&M*bLmIr&^7fxYqWn@NaWo%?ccywiMb7^mGRC#b^ +adI6-(bd|-i#!&GYaF>qoh8ard&4S7rwg9}|^$ORAg?_G_n1nO(?SEuMzN +{%51&MrF+jNoHYVWl3#tY=vTZV5b3xH$$#qHiSUt?>koiWBSx8z6l#U<`??EtsYNxbZ~WaL349yXKrm} +Zgf&*c4c8~Wn@8gbYWv?h8PemXlG!~;@e)_O3H?xO^a~KWeI~0jp}x-Dk@(^3qx;ibY*UIQ)y>&hQQu{ +9Qsc78(()~0WKn7PS!o2w>NdhVC3z)=0wst2~%}&aBN9*Wo?uk?`6hkSR^JNLF;fotFYyGgElEner?Qj +-*6=+=BfxyZ)9m^X=QSmA}Fy@mepYsm-R}r$$+zarmRet52gKjQ(+a4Wz=vOPGN0jWJYOaY-B-mb7^O8 +ZDnqBRC#b^oD+mh$ngc_{o0BQHv&+Zz~Nu-9tWThDIq|CJf~Jy2}f*iVqt7gb#$WOS=7<6%^jtx5=^cX +z--x^3Rg~O2_Ny!Q1}E;1fU93a&>cbOl5XuY`uYqVp0y6#Opn49V(cQiM=UF)OS@-HCak`i5#Wy{om=fffyPjz%~b#y^c;Wy%QVke?j1 +l!xqXd>q7+-P0pRHy9#PwI{4d;Y3eK&S@S1XLTY^Y +?LL}v9ZWWu2|;XdXkkNPaC1n$BNr;@ghiU?gEXK9KMDE{F?;HZBRuDVqlk6qmbeZmb;*F>vukd;=m`ygb@x#_>`RmOO$0)3Z)|2*aM+Gq(Fu_0Ocz)^+@GUUoV7w&pu=F9 +->y0X3z7m=HF#-wX0mI#UQqw(qY;tp7Zc6+Qb4G4KrzO(t)@DpIt)Q@6J +WikDr@YkEAs#9)9JJvRH-Qc7Q2s%Kf+=VCyOABEU3kOtrQ)O*QWJFFoaz*WZZ5##rf6bm&7qffY6*N`B +##bI~HzDmr7z##dWo%?qWo=1hQx*t>6v={gsJ=SZlTl1iF5eQ8IAl(q%E@>So406W2vm7+WlmvjWn_%h +53p;7sgGx&z)8&prN#D&cR=tS@df05SQ3Z*PZCvbZeeX@WJYOaY-Dp&Wo=1hYXqYdo~D%m7H6OD0<^0n +_2##VWXRdjy=DB@qgYOj1yf~hNo0M=LMPN>0NEy%g(UCHeUkYj{YR7-159lqXIqm$}teZO^;JC(UrZ +-Ks{e+7M1*ZDnLeX=Q9=b5mt)No1EHgR0RSPeIWLGZ_*YTjUMn3>33lep74@i%V@}#Ze4JZgp)|VRC6< +Zgg{)$`hk?ZwGtJ2SXtvrdbC93PHKYJmiYcR|q~$B%b6DR$+2!VQzFuZf0*&Wo=1h{TNkq(n4IP`h#h- +J1DmCvqiYufHpK#7;+#Z*Ep$a%o|1baPW>ZAoPPfv$so3kRF1PV2}fOp_vjQ6FdFHId|< +b)4huMS`gcRC#b^Q+acAWo-rk4MT5kbaG*1bV+VxWq1Yx3~+T~Y-wXpaBp>Va{vhfpMYpf(w(85W>NlMuXsu{2tXFT+?;?hj39&>gq>HOrf1lB-q;n)I5N0000000000|Ns90 +000004sUgIaBpdDbWd<^b#!w83IZW;tD*IvDh<9wi3iSCIT-HkA81Vlhk;Gmjr?|WwEUnvf%o<(T&E;B +3PONkMAxSUN>@h$CD;?(VA_yLjW_@a0-u0rOVXX8on}%7`W~n~g^Ir=cD&(=7J1!T`=A*KGm{X!fUz`M +i!Z}iQtl5;XwV(E`Zdd&WRj~^37YhpmjD0&000000RR900000000000000000RR900000001!=OZ9{Kv +baG*1bW?O;bY%ty2yN)$WoGNrYW-WRvK!KKk>= +iM=UF)OS@-HCak`i5#Wy{om=fffZ0000000030|Ns9000009W_507X<}?; +a{vhfVhoMD*5<7|86J&wS3rOMJWQ?e_G69TXIL>{4d;Y3eK*5<7|86J&wS3rOMJWQ?e3#PMu +b0zS$R1PI#k8M9VrRnYo;h`Hf2cFp`kG*~p0000000000|NsC00000024Qq`VPj|j2?Amajl1M6n%+Y* +8%A7yc}&*ktvneXjdfQ*fBrm7t?`9od0?jjhc`p6U^aw6=I=XJ|6}^pD!vIDJLVVqzpVfO0000000960 +|Nj60000h6Wo<`nZ(?C=Q*>c;Wd;HTYi@6MZU71bVhoMD*5<7|86J&wS3rOMJWQ?e +oD+mh$ngc_{o0BQHv&+Zz~Nu-9tWThDIq|CJf~Jy0-u0rOVXX8on}%7`W~n~g^Ir=cD&(=7J1!T`=A*K +Gcul5Q3m-<6)UHjqig^*m4co5us7ukl*0UQzs7w8g#Z8m000000RR90{{R3000nGmZE17>00Rh3Wo=1r +WMy~;1{H5`LUnFrY-K}eX>4S2Wo}7sWMy~&3Id;iXiL(ap`B(@2KpYTJ%x(DC3d{wiWYg@TKk|G2{V<* +=6W7=VqesjRYGc!>wZFzp>JB4@xD;^wu&SY_r(AS0-u0rOVXX8on}%7`W~n~g^Ir=cD&(=7J1!T`=A*K +GXr~*wLKbzE(ciwC3nrXLGTEzPUiqvVS}~6O1wZFzp>JB4@xD;^wu&SY_r(IAfM`q7ouQp(QU>}Ss6B;>za@6O;ffY{-CFyg83{83dy}<28ig(gSpg+? +&9*`C2(3=%09avzwZKZf-~wC#0000000030|Nj600000JVs&n0Y-K}lZgg^CV{}PwWMy~&3Id;iXiL(a +p`B(@2KpYTJ%x(DC3d{wiWYg@TKk|G2{QwGleIk>g)RqK0VQ|Mwn6X+txo3vSYd;;z)HQ~0$c*0fM`q7 +ouQp(QU>}Ss6B;>za@6O;ffY{-CFyg83{9=2rNlD$O59e#ogQsB77jPl+h5j^*S;D00000 +00030|Nj600000IVs&n0Y-LwzbZ%vHb4hMwWq1Gz0-u0rOVXX8on}%7`W~n~g^Ir=cD&(=7J1!T`=A*K +GXr~*wLKbzE(ciwC3nrXLGTEzPUiqvVS}~6O1#Kd;Rz-U=aO9W+B0000000000{{R30000000000000000|Ns90 +000004P$R^baG*1bV+VxWq1Gz0-u0rOVXX8on}%7`W~n~g^Ir=cD&(=7J1!T`=A*KGoJ`7Njk^^qPoT1 ++zTRnAg`3vXv9d*8d@RXy~6c6G6A?jl5_^Jmae8PaFd-@1fSOS=_sEK*2tZxtUl`Mr%M0;0000000930 +00000000eiWpZt4ZeeUmZe(S6015&jaI2y9pehZ%M2QE^S2-B&?H_1O1&4u6*^T^mbhP|v8SA{&vly$F +vzVnzHf7z~rv`86=_Ka^V5yX|y#`JI2?C#hXiL(ap`B(@2KpYTJ%x(DC3d{wiWYg@TKk|G2{V%rynwMZ +T8l5kSW@l}O=!>^xB4~9n`Dx!RtcK)nwJ0o000000093000000000000000000960{{R30000P0Wo=V* +VRL8(4G42%Xk~3-bYTDr0-u0rOVXX8on}%7`W~n~g^Ir=cD&(=7J1!T`=A*KGn7)(+XJhss8OG%_CC-Q +>(otsF+cqN0Qy}ddQ=3E5CUQhjl1M6n%+Y*8%A7yc}&*ktvneXjdfQ*fBrm7t?|-#FLmd)8^C0+InTyb +%?WTG%$DZ$m;bAR)ya#VGE@Kn000000093000000000JQW?^Gxa{vkgVhoMD*5<7| +86J&wS3rOMJWQ?eJIcU;0|?p#+${pKVqYC0%8n}yW}mJ-a|7RMqGY*OxEVD +JQ*I1byq-t{ya>r@j1sDK7J55&$qsubbafuzL1-^j%|=cN>I>nnK4))Pyhe`000000RI300000000(Df +Ze??2a{vkgpMYpf(w(85W>Np9m~TI>-W|y2ahx3nF|Vuawki#7NH? +S|Q-Q!u2{b0-u0rOVXX8on}%7`W~n~g^Ir=cD&(=7J1!T`=A*KGt#s}`|*Ja`)b*YbP*k000000RI300000000nb(aByq@3Ibvbjl1M6n%+Y*8%A7yc}&*ktvneXjdfQ*fBrm7 +t?>q!t+(1Z!Y#S=r-tc=NPf>PeW=$`IKP*ssSB}HE2RJl0%8n}yW}mJ-a|7RMqGY*OxEVDJQ*I1byq-t +{ya>r@nb#HiLgsaRw~c9&Ny{YCK_TCaeS`x+X~XLW@}|UwEzGB000000RI300000000000000000RI30 +0000000&}qZe(m_a{vkgpMYpf(w(85W>N1ACLTJsO2B2U!6ncg?mz +@CdC==Kxq?gSEg)z2E{|0-u0rOVXX8on}%7`W~n~g^Ir=cD&(=7J1!T`=A*KGX;3#jF_Psll$K3m0qvW +>0&oDqqo0*?q^FKQ(!8W@c;k-000000RR90{{R30019PzbY*UHX>V?G015)1fM`q7ouQp(QU>}Ss6B;> +za@6O;ffY{-CFyg83{9$$mV(;bz)!CmQ_M(k?Vd!kfCo{nDM?)_qK{868FUdpMYpf(w(85W>NCW*|x7tZ`I!jQ)C-lM`_kv%gaYO7(UC~SMps>d-e0000000000|NsC000000 +33q99Ze??GWpe-u0`+VYVk7oBr%DNv+($;q`HHK!gIHa)*%m(-e#9sm3ZsHT^UK%K(4i9Ajp1M~R@C@! +4#dQE#lUD;OiKi1Rsv!Sjl1M6n%+Y*8%A7yc}&*ktvneXjdfQ*fBrm7t??2o-$0@yp2V-B2Sg`iDCMTP +tNw5A9E}qwvrD7&DWm`Z0000000960|Nj60000YNbaY{3Xl-R~baMa-0-u0rOVXX8on}%7`W~n~g^Ir= +cD&(=7J1!T`=A*KGlX#slPpg3!?y@aX^XIja4CK{WF&t@k=WXUZP9(YH~bW>$vY;yn!0wHj#q4l6D4ZcK)2hLYH81C&KXiWu&flb+s{C0G- +{HLh$xdReUg_1Rxg;i+}Ss6B;>za@6O;ffY{-CFyg83{AC=zxYCD0L!x4tB5Hm3vFbl?lap +NXe%XU~*fKJ0+X~VhoMD*5<7|86J&wS3rOMJWQ?eqTpH7(Xh=OrK%E4t`xv**_;Yj +PG|`q@y<~A1W*K^0000000000|Nj60000001Z-(ya{vkgVsJHoA?4$swuZp1Wc+9AOf`(TIbyKWjTy4W +kGaM+r!Z9lE%{u?@QI^EqCb}2Q7OO^w+`_q*ddTXmHSf)0%CAAe<9`Lptgpr6F_xjAC6(~TLj +#*ewiHWCDr@#54KP!Z9Fy4s@&s7y*hO1UlNfirx{z*_V4e8lMKAp&9y +jl1M6n%+Y*8%A7yc}&*ktvneXjdfQ*fBrm7t?`B!5G-hCV9w&(UffE`hM!G~aLQ!~gAR@AcC9KZUqt`_ +000000096000000000P0Wo=V*VRU5%0||F&bZ%vHb7gY?3Ig?P6JjIwIj2eqliWu}$@z+_xPw?-wb>Rw +7=FYk8VaL=Li5Yl(a@n1+Ku60FILp}Zw|!7cE!MGSxid=WmWLp3P=6Evz0000000030|Ns900000EX>N95Y-wad +b#7#AWpe-t0-u0rOVXX8on}%7`W~n~g^Ir=cD&(=7J1!T`=A*KGXr~*wLKbzE(ciwC3nrXLGTEzPUiqv +VS}~6O13Id;iXiL(ap`B(@2KpYTJ%x(DC3d{wiWYg@ +TKk|G2{WGvEJ-@Z0;0Ob-P{Wzd?2rs)M&&=&l*}G;Jw22Ix+zQeSE-D&as6bavW-TpDK3Q$S;EaU-vt4 +bL ^ ..0xffffff {RGBCommit.Opout ^ ..0xffffff}} +@mnemonic(tribal-apollo-plasma) +data ContractIndex : publicOpouts {RGBCommit.Opout ^ ..0xffffff}, outpointOpouts {BPCore.ExplicitSealTxid -> ^ ..0xffffff {RGBCommit.Opout ^ ..0xffffff}} -@mnemonic(shake-square-wizard) +@mnemonic(henry-agatha-parole) data MemContractState : schemaId RGBCommit.SchemaId , contractId RGBCommit.ContractId , global {RGBCommit.GlobalStateType -> ^ ..0xff MemGlobalState} @@ -229,32 +217,35 @@ data MemContractState : schemaId RGBCommit.SchemaId , data {RGBStd.OutputAssignmentRevealedData ^ ..0xffffffff} , attach {RGBStd.OutputAssignmentRevealedAttach ^ ..0xffffffff} -@mnemonic(gilbert-torpedo-digital) +@mnemonic(august-depend-banana) data MemGlobalState : known {RGBStd.GlobalOut -> ^ ..0xffffffff RGBCommit.DataState}, limit U24 -@mnemonic(savage-joshua-clone) -data MemIndex : opBundleIndex {RGBCommit.OpId -> ^ ..0xffffff RGBCommit.BundleId} +@mnemonic(lithium-lunar-cartoon) +data MemIndex : opBundleChildrenIndex {RGBCommit.OpId -> ^ ..0xffffff {RGBCommit.BundleId ^ ..0xff}} + , opBundleIndex {RGBCommit.OpId -> ^ ..0xffffff RGBCommit.BundleId} , bundleContractIndex {RGBCommit.BundleId -> ^ ..0xffffff RGBCommit.ContractId} - , bundleWitnessIndex {RGBCommit.BundleId -> ^ ..0xffffff {RGBCommit.XChainTxid ^ ..0xff}} + , bundleWitnessIndex {RGBCommit.BundleId -> ^ ..0xffffff {Bitcoin.Txid ^ ..0xff}} , contractIndex {RGBCommit.ContractId -> ^ ..0xff ContractIndex} - , terminalIndex {RGBCommit.XChainSecretSeal -> ^ ..0xffffff {RGBCommit.Opout ^ ..0xff}} + , terminalIndex {BPCore.SecretSeal -> ^ ..0xffffff {RGBCommit.Opout ^ ..0xff}} -@mnemonic(level-open-morph) +@mnemonic(horse-reunion-tonight) data MemStash : schemata {RGBCommit.SchemaId -> ^ ..0xff RGBStd.SchemaIfaces} , ifaces {RGBStd.IfaceId -> ^ ..0xff RGBStd.Iface} , geneses {RGBCommit.ContractId -> ^ ..0xff RGBCommit.Genesis} , suppl {RGBStd.ContentRef -> ^ ..0xff {RGBStd.Supplement ^ ..0xff}} , bundles {RGBCommit.BundleId -> ^ ..0xffffffff RGBCommit.TransitionBundle} , extensions {RGBCommit.OpId -> ^ ..0xffffffff RGBCommit.Extension} - , witnesses {RGBCommit.XChainTxid -> ^ ..0xffffffff RGBStd.SealWitness} + , witnesses {Bitcoin.Txid -> ^ ..0xffffffff RGBStd.SealWitness} , attachments {RGBCommit.AttachId -> [Byte ^ ..0xffffff]} - , secretSeals {RGBCommit.XChainBlindSealTxPtr ^ ..0xffffff} + , secretSeals {BPCore.BlindSealTxPtr ^ ..0xffffff} , typeSystem StrictTypes.TypeSystem , identities {RGBCommit.Identity -> RGBStd.TrustLevel} , libs {AluVM.LibId -> AluVM.Lib} , sigs {RGBStd.ContentId -> RGBStd.ContentSigs} -@mnemonic(paradox-polka-juliet) -data MemState : witnesses {RGBCommit.XChainTxid -> ^ ..0xffffffff RGBLogic.WitnessOrd}, contracts {RGBCommit.ContractId -> ^ ..0xff MemContractState} +@mnemonic(bazooka-dallas-martin) +data MemState : witnesses {Bitcoin.Txid -> ^ ..0xffffffff RGBLogic.WitnessOrd} + , invalidBundles {RGBCommit.BundleId ^ ..0xffffffff} + , contracts {RGBCommit.ContractId -> ^ ..0xff MemContractState} diff --git a/stl/Transfer.vesper b/stl/Transfer.vesper index ca6ac774..e5031dd9 100644 --- a/stl/Transfer.vesper +++ b/stl/Transfer.vesper @@ -18,9 +18,9 @@ ConsignmentId commitment hasher=SHA256 tagged=urn:lnp-bp:rgb:consignment#2024-03 DiscloseHash element DiscloseHash set len=0..MAX32 DiscloseHash element - XChainSecretSeal map len=0..MAX16 + SecretSeal map len=0..MAX16 BundleId mapKey - XChainSecretSeal mapValue + SecretSeal mapValue AttachId set len=0..MAX16 AttachId element SupplId set len=0..MAX8 @@ -36,21 +36,14 @@ Consignmenttrue rec version enum ContainerVer v2=2 transfer enum Bool false=0 true=1 terminals map len=0..MAX16 - value union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 + value bytes len=32 aka=SecretSeal genesis rec Genesis ffv is U16 aka=Ffv schemaId bytes len=32 aka=SchemaId flags bytes len=1 aka=ReservedBytes1 timestamp is I64 issuer ascii aka=Identity first=AsciiPrintable rest=AsciiPrintable len=1..4096 - testnet enum Bool false=0 true=1 - altLayers1 set len=0..MAX8 aka=AltLayer1Set - AltLayer1 enum liquid=1 - assetTags map len=0..MAX8 aka=AssetTags - key is U16 aka=AssignmentType - value bytes len=32 aka=AssetTag + chainNet enum ChainNet bitcoinMainnet=0 bitcoinTestnet3=1 bitcoinTestnet4=2 bitcoinSignet=3 bitcoinRegtest=4 liquidMainnet=5 liquidTestnet=6 metadata map len=0..MAX8 aka=Metadata key is U16 aka=MetaType value bytes len=0..MAX16 aka=MetaValue @@ -64,141 +57,85 @@ Consignmenttrue rec declarative list len=0..MAX16 wrapped tag=0 AssignVoidStateBlindSealTxid union confidential rec tag=0 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 + seal bytes len=32 aka=SecretSeal state is Unit aka=VoidState lock bytes len=2 aka=ReservedBytes2 confidentialState rec tag=1 - seal union XChainBlindSealTxid - bitcoin rec BlindSealTxid wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxid wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 + seal rec BlindSealTxid + txid bytes len=32 aka=Txid + vout is U32 aka=Vout + blinding is U64 state is Unit aka=VoidState lock bytes len=2 aka=ReservedBytes2 confidentialSeal rec tag=2 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 + seal bytes len=32 aka=SecretSeal state is Unit aka=VoidState lock bytes len=2 aka=ReservedBytes2 revealed rec tag=3 - seal union XChainBlindSealTxid - bitcoin rec BlindSealTxid wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxid wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 + seal rec BlindSealTxid + txid bytes len=32 aka=Txid + vout is U32 aka=Vout + blinding is U64 state is Unit aka=VoidState lock bytes len=2 aka=ReservedBytes2 fungible list len=0..MAX16 wrapped tag=1 AssignRevealedValueBlindSealTxid union confidential rec tag=0 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 + seal bytes len=32 aka=SecretSeal state rec ConcealedFungible - commitment bytes len=33 aka=PedersenCommitment - rangeProof bytes len=33 aka=PedersenCommitment + value union FungibleState + bits64 is U64 wrapped tag=0 + concealedDummy is Unit lock bytes len=2 aka=ReservedBytes2 confidentialState rec tag=1 - seal union XChainBlindSealTxid - bitcoin rec BlindSealTxid wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxid wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 + seal rec BlindSealTxid + txid bytes len=32 aka=Txid + vout is U32 aka=Vout + blinding is U64 state rec ConcealedFungible - commitment bytes len=33 aka=PedersenCommitment - rangeProof bytes len=33 aka=PedersenCommitment + value union FungibleState + bits64 is U64 wrapped tag=0 + concealedDummy is Unit lock bytes len=2 aka=ReservedBytes2 confidentialSeal rec tag=2 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 + seal bytes len=32 aka=SecretSeal state rec RevealedFungible value union FungibleState bits64 is U64 wrapped tag=0 - blinding bytes len=32 aka=BlindingFactor - tag bytes len=32 aka=AssetTag lock bytes len=2 aka=ReservedBytes2 revealed rec tag=3 - seal union XChainBlindSealTxid - bitcoin rec BlindSealTxid wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxid wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 + seal rec BlindSealTxid + txid bytes len=32 aka=Txid + vout is U32 aka=Vout + blinding is U64 state rec RevealedFungible value union FungibleState bits64 is U64 wrapped tag=0 - blinding bytes len=32 aka=BlindingFactor - tag bytes len=32 aka=AssetTag lock bytes len=2 aka=ReservedBytes2 structured list len=0..MAX16 wrapped tag=2 AssignRevealedDataBlindSealTxid union confidential rec tag=0 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 + seal bytes len=32 aka=SecretSeal state bytes len=32 aka=ConcealedData lock bytes len=2 aka=ReservedBytes2 confidentialState rec tag=1 - seal union XChainBlindSealTxid - bitcoin rec BlindSealTxid wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxid wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 + seal rec BlindSealTxid + txid bytes len=32 aka=Txid + vout is U32 aka=Vout + blinding is U64 state bytes len=32 aka=ConcealedData lock bytes len=2 aka=ReservedBytes2 confidentialSeal rec tag=2 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 + seal bytes len=32 aka=SecretSeal state rec RevealedData value bytes len=0..MAX16 aka=DataState salt is U128 lock bytes len=2 aka=ReservedBytes2 revealed rec tag=3 - seal union XChainBlindSealTxid - bitcoin rec BlindSealTxid wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxid wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 + seal rec BlindSealTxid + txid bytes len=32 aka=Txid + vout is U32 aka=Vout + blinding is U64 state rec RevealedData value bytes len=0..MAX16 aka=DataState salt is U128 @@ -206,29 +143,18 @@ Consignmenttrue rec attachment list len=0..MAX16 wrapped tag=3 AssignRevealedAttachBlindSealTxid union confidential rec tag=0 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 + seal bytes len=32 aka=SecretSeal state bytes len=32 aka=ConcealedAttach lock bytes len=2 aka=ReservedBytes2 confidentialState rec tag=1 - seal union XChainBlindSealTxid - bitcoin rec BlindSealTxid wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxid wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 + seal rec BlindSealTxid + txid bytes len=32 aka=Txid + vout is U32 aka=Vout + blinding is U64 state bytes len=32 aka=ConcealedAttach lock bytes len=2 aka=ReservedBytes2 confidentialSeal rec tag=2 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 + seal bytes len=32 aka=SecretSeal state rec RevealedAttach file rec AttachState id bytes len=32 aka=AttachId @@ -236,17 +162,10 @@ Consignmenttrue rec salt is U64 lock bytes len=2 aka=ReservedBytes2 revealed rec tag=3 - seal union XChainBlindSealTxid - bitcoin rec BlindSealTxid wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxid wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 + seal rec BlindSealTxid + txid bytes len=32 aka=Txid + vout is U32 aka=Vout + blinding is U64 state rec RevealedAttach file rec AttachState id bytes len=32 aka=AttachId @@ -275,141 +194,85 @@ Consignmenttrue rec declarative list len=0..MAX16 wrapped tag=0 AssignVoidStateBlindSealTxid union confidential rec tag=0 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 + seal bytes len=32 aka=SecretSeal state is Unit aka=VoidState lock bytes len=2 aka=ReservedBytes2 confidentialState rec tag=1 - seal union XChainBlindSealTxid - bitcoin rec BlindSealTxid wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxid wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 + seal rec BlindSealTxid + txid bytes len=32 aka=Txid + vout is U32 aka=Vout + blinding is U64 state is Unit aka=VoidState lock bytes len=2 aka=ReservedBytes2 confidentialSeal rec tag=2 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 + seal bytes len=32 aka=SecretSeal state is Unit aka=VoidState lock bytes len=2 aka=ReservedBytes2 revealed rec tag=3 - seal union XChainBlindSealTxid - bitcoin rec BlindSealTxid wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxid wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 + seal rec BlindSealTxid + txid bytes len=32 aka=Txid + vout is U32 aka=Vout + blinding is U64 state is Unit aka=VoidState lock bytes len=2 aka=ReservedBytes2 fungible list len=0..MAX16 wrapped tag=1 AssignRevealedValueBlindSealTxid union confidential rec tag=0 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 + seal bytes len=32 aka=SecretSeal state rec ConcealedFungible - commitment bytes len=33 aka=PedersenCommitment - rangeProof bytes len=33 aka=PedersenCommitment + value union FungibleState + bits64 is U64 wrapped tag=0 + concealedDummy is Unit lock bytes len=2 aka=ReservedBytes2 confidentialState rec tag=1 - seal union XChainBlindSealTxid - bitcoin rec BlindSealTxid wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxid wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 + seal rec BlindSealTxid + txid bytes len=32 aka=Txid + vout is U32 aka=Vout + blinding is U64 state rec ConcealedFungible - commitment bytes len=33 aka=PedersenCommitment - rangeProof bytes len=33 aka=PedersenCommitment + value union FungibleState + bits64 is U64 wrapped tag=0 + concealedDummy is Unit lock bytes len=2 aka=ReservedBytes2 confidentialSeal rec tag=2 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 + seal bytes len=32 aka=SecretSeal state rec RevealedFungible value union FungibleState bits64 is U64 wrapped tag=0 - blinding bytes len=32 aka=BlindingFactor - tag bytes len=32 aka=AssetTag lock bytes len=2 aka=ReservedBytes2 revealed rec tag=3 - seal union XChainBlindSealTxid - bitcoin rec BlindSealTxid wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxid wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 + seal rec BlindSealTxid + txid bytes len=32 aka=Txid + vout is U32 aka=Vout + blinding is U64 state rec RevealedFungible value union FungibleState bits64 is U64 wrapped tag=0 - blinding bytes len=32 aka=BlindingFactor - tag bytes len=32 aka=AssetTag lock bytes len=2 aka=ReservedBytes2 structured list len=0..MAX16 wrapped tag=2 AssignRevealedDataBlindSealTxid union confidential rec tag=0 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 + seal bytes len=32 aka=SecretSeal state bytes len=32 aka=ConcealedData lock bytes len=2 aka=ReservedBytes2 confidentialState rec tag=1 - seal union XChainBlindSealTxid - bitcoin rec BlindSealTxid wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxid wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 + seal rec BlindSealTxid + txid bytes len=32 aka=Txid + vout is U32 aka=Vout + blinding is U64 state bytes len=32 aka=ConcealedData lock bytes len=2 aka=ReservedBytes2 confidentialSeal rec tag=2 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 + seal bytes len=32 aka=SecretSeal state rec RevealedData value bytes len=0..MAX16 aka=DataState salt is U128 lock bytes len=2 aka=ReservedBytes2 revealed rec tag=3 - seal union XChainBlindSealTxid - bitcoin rec BlindSealTxid wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxid wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 + seal rec BlindSealTxid + txid bytes len=32 aka=Txid + vout is U32 aka=Vout + blinding is U64 state rec RevealedData value bytes len=0..MAX16 aka=DataState salt is U128 @@ -417,29 +280,18 @@ Consignmenttrue rec attachment list len=0..MAX16 wrapped tag=3 AssignRevealedAttachBlindSealTxid union confidential rec tag=0 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 + seal bytes len=32 aka=SecretSeal state bytes len=32 aka=ConcealedAttach lock bytes len=2 aka=ReservedBytes2 confidentialState rec tag=1 - seal union XChainBlindSealTxid - bitcoin rec BlindSealTxid wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxid wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 + seal rec BlindSealTxid + txid bytes len=32 aka=Txid + vout is U32 aka=Vout + blinding is U64 state bytes len=32 aka=ConcealedAttach lock bytes len=2 aka=ReservedBytes2 confidentialSeal rec tag=2 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 + seal bytes len=32 aka=SecretSeal state rec RevealedAttach file rec AttachState id bytes len=32 aka=AttachId @@ -447,17 +299,10 @@ Consignmenttrue rec salt is U64 lock bytes len=2 aka=ReservedBytes2 revealed rec tag=3 - seal union XChainBlindSealTxid - bitcoin rec BlindSealTxid wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxid wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 + seal rec BlindSealTxid + txid bytes len=32 aka=Txid + vout is U32 aka=Vout + blinding is U64 state rec RevealedAttach file rec AttachState id bytes len=32 aka=AttachId @@ -473,7 +318,25 @@ Consignmenttrue rec witness bytes len=2 aka=ReservedBytes2 bundles set len=0..MAX32 WitnessBundle rec - anchoredBundles union AnchoredBundles + pubWitness union PubWitness + txid bytes len=32 wrapped aka=Txid tag=0 + tx rec Tx wrapped tag=1 + version is I32 aka=TxVer + inputs list len=0..MAX32 + TxIn rec + prevOutput rec Outpoint + txid bytes len=32 aka=Txid + vout is U32 aka=Vout + sigScript bytes len=0..MAX32 aka=SigScript aka=ScriptBytes + sequence is U32 aka=SeqNo + witness list len=0..MAX32 aka=Witness + element bytes len=0..MAX32 aka=ByteStr + outputs list len=0..MAX32 + TxOut rec + value is U64 aka=Sats + scriptPubkey bytes len=0..MAX32 aka=ScriptPubkey aka=ScriptBytes + lockTime is U32 aka=LockTime + anchoredBundle union AnchoredBundle tapret rec ClientBundleTapretProof wrapped tag=0 mpcProof rec MerkleProof pos is U32 @@ -486,7 +349,6 @@ Consignmenttrue rec rightBranch rec TapretRightBranch wrapped tag=2 nonce is U8 bundle rec TransitionBundle - closeMethod enum Method opretFirst=0 tapretFirst=1 inputMap map len=1..MAX16 aka=InputMap key is U32 aka=Vout value bytes len=32 aka=OpId @@ -517,165 +379,97 @@ Consignmenttrue rec declarative list len=0..MAX16 wrapped tag=0 AssignVoidStateBlindSealTxPtr union confidential rec tag=0 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 + seal bytes len=32 aka=SecretSeal state is Unit aka=VoidState lock bytes len=2 aka=ReservedBytes2 confidentialState rec tag=1 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 + seal rec BlindSealTxPtr + txid union TxPtr + witnessTx is Unit tag=0 + txid bytes len=32 wrapped aka=Txid tag=1 + vout is U32 aka=Vout + blinding is U64 state is Unit aka=VoidState lock bytes len=2 aka=ReservedBytes2 confidentialSeal rec tag=2 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 + seal bytes len=32 aka=SecretSeal state is Unit aka=VoidState lock bytes len=2 aka=ReservedBytes2 revealed rec tag=3 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 + seal rec BlindSealTxPtr + txid union TxPtr + witnessTx is Unit tag=0 + txid bytes len=32 wrapped aka=Txid tag=1 + vout is U32 aka=Vout + blinding is U64 state is Unit aka=VoidState lock bytes len=2 aka=ReservedBytes2 fungible list len=0..MAX16 wrapped tag=1 AssignRevealedValueBlindSealTxPtr union confidential rec tag=0 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 + seal bytes len=32 aka=SecretSeal state rec ConcealedFungible - commitment bytes len=33 aka=PedersenCommitment - rangeProof bytes len=33 aka=PedersenCommitment + value union FungibleState + bits64 is U64 wrapped tag=0 + concealedDummy is Unit lock bytes len=2 aka=ReservedBytes2 confidentialState rec tag=1 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 + seal rec BlindSealTxPtr + txid union TxPtr + witnessTx is Unit tag=0 + txid bytes len=32 wrapped aka=Txid tag=1 + vout is U32 aka=Vout + blinding is U64 state rec ConcealedFungible - commitment bytes len=33 aka=PedersenCommitment - rangeProof bytes len=33 aka=PedersenCommitment + value union FungibleState + bits64 is U64 wrapped tag=0 + concealedDummy is Unit lock bytes len=2 aka=ReservedBytes2 confidentialSeal rec tag=2 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 + seal bytes len=32 aka=SecretSeal state rec RevealedFungible value union FungibleState bits64 is U64 wrapped tag=0 - blinding bytes len=32 aka=BlindingFactor - tag bytes len=32 aka=AssetTag lock bytes len=2 aka=ReservedBytes2 revealed rec tag=3 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 + seal rec BlindSealTxPtr + txid union TxPtr + witnessTx is Unit tag=0 + txid bytes len=32 wrapped aka=Txid tag=1 + vout is U32 aka=Vout + blinding is U64 state rec RevealedFungible value union FungibleState bits64 is U64 wrapped tag=0 - blinding bytes len=32 aka=BlindingFactor - tag bytes len=32 aka=AssetTag lock bytes len=2 aka=ReservedBytes2 structured list len=0..MAX16 wrapped tag=2 AssignRevealedDataBlindSealTxPtr union confidential rec tag=0 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 + seal bytes len=32 aka=SecretSeal state bytes len=32 aka=ConcealedData lock bytes len=2 aka=ReservedBytes2 confidentialState rec tag=1 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 + seal rec BlindSealTxPtr + txid union TxPtr + witnessTx is Unit tag=0 + txid bytes len=32 wrapped aka=Txid tag=1 + vout is U32 aka=Vout + blinding is U64 state bytes len=32 aka=ConcealedData lock bytes len=2 aka=ReservedBytes2 confidentialSeal rec tag=2 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 + seal bytes len=32 aka=SecretSeal state rec RevealedData value bytes len=0..MAX16 aka=DataState salt is U128 lock bytes len=2 aka=ReservedBytes2 revealed rec tag=3 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 + seal rec BlindSealTxPtr + txid union TxPtr + witnessTx is Unit tag=0 + txid bytes len=32 wrapped aka=Txid tag=1 + vout is U32 aka=Vout + blinding is U64 state rec RevealedData value bytes len=0..MAX16 aka=DataState salt is U128 @@ -683,33 +477,20 @@ Consignmenttrue rec attachment list len=0..MAX16 wrapped tag=3 AssignRevealedAttachBlindSealTxPtr union confidential rec tag=0 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 + seal bytes len=32 aka=SecretSeal state bytes len=32 aka=ConcealedAttach lock bytes len=2 aka=ReservedBytes2 confidentialState rec tag=1 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 + seal rec BlindSealTxPtr + txid union TxPtr + witnessTx is Unit tag=0 + txid bytes len=32 wrapped aka=Txid tag=1 + vout is U32 aka=Vout + blinding is U64 state bytes len=32 aka=ConcealedAttach lock bytes len=2 aka=ReservedBytes2 confidentialSeal rec tag=2 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 + seal bytes len=32 aka=SecretSeal state rec RevealedAttach file rec AttachState id bytes len=32 aka=AttachId @@ -717,21 +498,12 @@ Consignmenttrue rec salt is U64 lock bytes len=2 aka=ReservedBytes2 revealed rec tag=3 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 + seal rec BlindSealTxPtr + txid union TxPtr + witnessTx is Unit tag=0 + txid bytes len=32 wrapped aka=Txid tag=1 + vout is U32 aka=Vout + blinding is U64 state rec RevealedAttach file rec AttachState id bytes len=32 aka=AttachId @@ -750,7 +522,6 @@ Consignmenttrue rec element bytes len=32 aka=MerkleHash dbcProof is Unit aka=OpretProof bundle rec TransitionBundle - closeMethod enum Method opretFirst=0 tapretFirst=1 inputMap map len=1..MAX16 aka=InputMap key is U32 aka=Vout value bytes len=32 aka=OpId @@ -781,165 +552,97 @@ Consignmenttrue rec declarative list len=0..MAX16 wrapped tag=0 AssignVoidStateBlindSealTxPtr union confidential rec tag=0 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 + seal bytes len=32 aka=SecretSeal state is Unit aka=VoidState lock bytes len=2 aka=ReservedBytes2 confidentialState rec tag=1 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 + seal rec BlindSealTxPtr + txid union TxPtr + witnessTx is Unit tag=0 + txid bytes len=32 wrapped aka=Txid tag=1 + vout is U32 aka=Vout + blinding is U64 state is Unit aka=VoidState lock bytes len=2 aka=ReservedBytes2 confidentialSeal rec tag=2 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 + seal bytes len=32 aka=SecretSeal state is Unit aka=VoidState lock bytes len=2 aka=ReservedBytes2 revealed rec tag=3 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 + seal rec BlindSealTxPtr + txid union TxPtr + witnessTx is Unit tag=0 + txid bytes len=32 wrapped aka=Txid tag=1 + vout is U32 aka=Vout + blinding is U64 state is Unit aka=VoidState lock bytes len=2 aka=ReservedBytes2 fungible list len=0..MAX16 wrapped tag=1 AssignRevealedValueBlindSealTxPtr union confidential rec tag=0 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 + seal bytes len=32 aka=SecretSeal state rec ConcealedFungible - commitment bytes len=33 aka=PedersenCommitment - rangeProof bytes len=33 aka=PedersenCommitment + value union FungibleState + bits64 is U64 wrapped tag=0 + concealedDummy is Unit lock bytes len=2 aka=ReservedBytes2 confidentialState rec tag=1 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 + seal rec BlindSealTxPtr + txid union TxPtr + witnessTx is Unit tag=0 + txid bytes len=32 wrapped aka=Txid tag=1 + vout is U32 aka=Vout + blinding is U64 state rec ConcealedFungible - commitment bytes len=33 aka=PedersenCommitment - rangeProof bytes len=33 aka=PedersenCommitment + value union FungibleState + bits64 is U64 wrapped tag=0 + concealedDummy is Unit lock bytes len=2 aka=ReservedBytes2 confidentialSeal rec tag=2 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 + seal bytes len=32 aka=SecretSeal state rec RevealedFungible value union FungibleState bits64 is U64 wrapped tag=0 - blinding bytes len=32 aka=BlindingFactor - tag bytes len=32 aka=AssetTag lock bytes len=2 aka=ReservedBytes2 revealed rec tag=3 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 + seal rec BlindSealTxPtr + txid union TxPtr + witnessTx is Unit tag=0 + txid bytes len=32 wrapped aka=Txid tag=1 + vout is U32 aka=Vout + blinding is U64 state rec RevealedFungible value union FungibleState bits64 is U64 wrapped tag=0 - blinding bytes len=32 aka=BlindingFactor - tag bytes len=32 aka=AssetTag lock bytes len=2 aka=ReservedBytes2 structured list len=0..MAX16 wrapped tag=2 AssignRevealedDataBlindSealTxPtr union confidential rec tag=0 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 + seal bytes len=32 aka=SecretSeal state bytes len=32 aka=ConcealedData lock bytes len=2 aka=ReservedBytes2 confidentialState rec tag=1 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 + seal rec BlindSealTxPtr + txid union TxPtr + witnessTx is Unit tag=0 + txid bytes len=32 wrapped aka=Txid tag=1 + vout is U32 aka=Vout + blinding is U64 state bytes len=32 aka=ConcealedData lock bytes len=2 aka=ReservedBytes2 confidentialSeal rec tag=2 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 + seal bytes len=32 aka=SecretSeal state rec RevealedData value bytes len=0..MAX16 aka=DataState salt is U128 lock bytes len=2 aka=ReservedBytes2 revealed rec tag=3 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 + seal rec BlindSealTxPtr + txid union TxPtr + witnessTx is Unit tag=0 + txid bytes len=32 wrapped aka=Txid tag=1 + vout is U32 aka=Vout + blinding is U64 state rec RevealedData value bytes len=0..MAX16 aka=DataState salt is U128 @@ -947,33 +650,20 @@ Consignmenttrue rec attachment list len=0..MAX16 wrapped tag=3 AssignRevealedAttachBlindSealTxPtr union confidential rec tag=0 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 + seal bytes len=32 aka=SecretSeal state bytes len=32 aka=ConcealedAttach lock bytes len=2 aka=ReservedBytes2 confidentialState rec tag=1 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 + seal rec BlindSealTxPtr + txid union TxPtr + witnessTx is Unit tag=0 + txid bytes len=32 wrapped aka=Txid tag=1 + vout is U32 aka=Vout + blinding is U64 state bytes len=32 aka=ConcealedAttach lock bytes len=2 aka=ReservedBytes2 confidentialSeal rec tag=2 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 + seal bytes len=32 aka=SecretSeal state rec RevealedAttach file rec AttachState id bytes len=32 aka=AttachId @@ -981,21 +671,12 @@ Consignmenttrue rec salt is U64 lock bytes len=2 aka=ReservedBytes2 revealed rec tag=3 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 + seal rec BlindSealTxPtr + txid union TxPtr + witnessTx is Unit tag=0 + txid bytes len=32 wrapped aka=Txid tag=1 + vout is U32 aka=Vout + blinding is U64 state rec RevealedAttach file rec AttachState id bytes len=32 aka=AttachId @@ -1006,539 +687,6 @@ Consignmenttrue rec element is U16 aka=ValencyType validator bytes len=1 aka=ReservedBytes1 witness bytes len=2 aka=ReservedBytes2 - double rec tag=2 - tapret rec ClientBundleTapretProof - mpcProof rec MerkleProof - pos is U32 - cofactor is U16 - path list len=0..32 - element bytes len=32 aka=MerkleHash - dbcProof rec TapretProof - pathProof rec TapretPathProof - some union TapretNodePartner option wrapped tag=1 - rightBranch rec TapretRightBranch wrapped tag=2 - nonce is U8 - bundle rec TransitionBundle - closeMethod enum Method opretFirst=0 tapretFirst=1 - inputMap map len=1..MAX16 aka=InputMap - key is U32 aka=Vout - value bytes len=32 aka=OpId - knownTransitions map len=1..MAX16 - key bytes len=32 aka=OpId - value rec Transition - ffv is U16 aka=Ffv - contractId bytes len=32 aka=ContractId - nonce is U64 - transitionType is U16 aka=TransitionType - metadata map len=0..MAX8 aka=Metadata - key is U16 aka=MetaType - value bytes len=0..MAX16 aka=MetaValue - globals map len=0..MAX8 aka=GlobalState - key is U16 aka=GlobalStateType - value list len=1..MAX16 aka=GlobalValues - element bytes len=0..MAX16 aka=DataState - inputs set len=0..MAX16 aka=Inputs - Input rec - prevOut rec Opout - op bytes len=32 aka=OpId - ty is U16 aka=AssignmentType - no is U16 - reserved bytes len=2 aka=ReservedBytes2 - assignments map len=0..MAX8 aka=AssignmentsBlindSealTxPtr - key is U16 aka=AssignmentType - value union TypedAssignsBlindSealTxPtr - declarative list len=0..MAX16 wrapped tag=0 - AssignVoidStateBlindSealTxPtr union - confidential rec tag=0 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 - state is Unit aka=VoidState - lock bytes len=2 aka=ReservedBytes2 - confidentialState rec tag=1 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - state is Unit aka=VoidState - lock bytes len=2 aka=ReservedBytes2 - confidentialSeal rec tag=2 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 - state is Unit aka=VoidState - lock bytes len=2 aka=ReservedBytes2 - revealed rec tag=3 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - state is Unit aka=VoidState - lock bytes len=2 aka=ReservedBytes2 - fungible list len=0..MAX16 wrapped tag=1 - AssignRevealedValueBlindSealTxPtr union - confidential rec tag=0 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 - state rec ConcealedFungible - commitment bytes len=33 aka=PedersenCommitment - rangeProof bytes len=33 aka=PedersenCommitment - lock bytes len=2 aka=ReservedBytes2 - confidentialState rec tag=1 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - state rec ConcealedFungible - commitment bytes len=33 aka=PedersenCommitment - rangeProof bytes len=33 aka=PedersenCommitment - lock bytes len=2 aka=ReservedBytes2 - confidentialSeal rec tag=2 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 - state rec RevealedFungible - value union FungibleState - bits64 is U64 wrapped tag=0 - blinding bytes len=32 aka=BlindingFactor - tag bytes len=32 aka=AssetTag - lock bytes len=2 aka=ReservedBytes2 - revealed rec tag=3 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - state rec RevealedFungible - value union FungibleState - bits64 is U64 wrapped tag=0 - blinding bytes len=32 aka=BlindingFactor - tag bytes len=32 aka=AssetTag - lock bytes len=2 aka=ReservedBytes2 - structured list len=0..MAX16 wrapped tag=2 - AssignRevealedDataBlindSealTxPtr union - confidential rec tag=0 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 - state bytes len=32 aka=ConcealedData - lock bytes len=2 aka=ReservedBytes2 - confidentialState rec tag=1 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - state bytes len=32 aka=ConcealedData - lock bytes len=2 aka=ReservedBytes2 - confidentialSeal rec tag=2 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 - state rec RevealedData - value bytes len=0..MAX16 aka=DataState - salt is U128 - lock bytes len=2 aka=ReservedBytes2 - revealed rec tag=3 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - state rec RevealedData - value bytes len=0..MAX16 aka=DataState - salt is U128 - lock bytes len=2 aka=ReservedBytes2 - attachment list len=0..MAX16 wrapped tag=3 - AssignRevealedAttachBlindSealTxPtr union - confidential rec tag=0 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 - state bytes len=32 aka=ConcealedAttach - lock bytes len=2 aka=ReservedBytes2 - confidentialState rec tag=1 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - state bytes len=32 aka=ConcealedAttach - lock bytes len=2 aka=ReservedBytes2 - confidentialSeal rec tag=2 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 - state rec RevealedAttach - file rec AttachState - id bytes len=32 aka=AttachId - mediaType enum MediaType any=255 - salt is U64 - lock bytes len=2 aka=ReservedBytes2 - revealed rec tag=3 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - state rec RevealedAttach - file rec AttachState - id bytes len=32 aka=AttachId - mediaType enum MediaType any=255 - salt is U64 - lock bytes len=2 aka=ReservedBytes2 - valencies set len=0..MAX8 aka=Valencies - element is U16 aka=ValencyType - validator bytes len=1 aka=ReservedBytes1 - witness bytes len=2 aka=ReservedBytes2 - opret rec ClientBundleOpretProof - mpcProof rec MerkleProof - pos is U32 - cofactor is U16 - path list len=0..32 - element bytes len=32 aka=MerkleHash - dbcProof is Unit aka=OpretProof - bundle rec TransitionBundle - closeMethod enum Method opretFirst=0 tapretFirst=1 - inputMap map len=1..MAX16 aka=InputMap - key is U32 aka=Vout - value bytes len=32 aka=OpId - knownTransitions map len=1..MAX16 - key bytes len=32 aka=OpId - value rec Transition - ffv is U16 aka=Ffv - contractId bytes len=32 aka=ContractId - nonce is U64 - transitionType is U16 aka=TransitionType - metadata map len=0..MAX8 aka=Metadata - key is U16 aka=MetaType - value bytes len=0..MAX16 aka=MetaValue - globals map len=0..MAX8 aka=GlobalState - key is U16 aka=GlobalStateType - value list len=1..MAX16 aka=GlobalValues - element bytes len=0..MAX16 aka=DataState - inputs set len=0..MAX16 aka=Inputs - Input rec - prevOut rec Opout - op bytes len=32 aka=OpId - ty is U16 aka=AssignmentType - no is U16 - reserved bytes len=2 aka=ReservedBytes2 - assignments map len=0..MAX8 aka=AssignmentsBlindSealTxPtr - key is U16 aka=AssignmentType - value union TypedAssignsBlindSealTxPtr - declarative list len=0..MAX16 wrapped tag=0 - AssignVoidStateBlindSealTxPtr union - confidential rec tag=0 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 - state is Unit aka=VoidState - lock bytes len=2 aka=ReservedBytes2 - confidentialState rec tag=1 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - state is Unit aka=VoidState - lock bytes len=2 aka=ReservedBytes2 - confidentialSeal rec tag=2 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 - state is Unit aka=VoidState - lock bytes len=2 aka=ReservedBytes2 - revealed rec tag=3 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - state is Unit aka=VoidState - lock bytes len=2 aka=ReservedBytes2 - fungible list len=0..MAX16 wrapped tag=1 - AssignRevealedValueBlindSealTxPtr union - confidential rec tag=0 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 - state rec ConcealedFungible - commitment bytes len=33 aka=PedersenCommitment - rangeProof bytes len=33 aka=PedersenCommitment - lock bytes len=2 aka=ReservedBytes2 - confidentialState rec tag=1 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - state rec ConcealedFungible - commitment bytes len=33 aka=PedersenCommitment - rangeProof bytes len=33 aka=PedersenCommitment - lock bytes len=2 aka=ReservedBytes2 - confidentialSeal rec tag=2 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 - state rec RevealedFungible - value union FungibleState - bits64 is U64 wrapped tag=0 - blinding bytes len=32 aka=BlindingFactor - tag bytes len=32 aka=AssetTag - lock bytes len=2 aka=ReservedBytes2 - revealed rec tag=3 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - state rec RevealedFungible - value union FungibleState - bits64 is U64 wrapped tag=0 - blinding bytes len=32 aka=BlindingFactor - tag bytes len=32 aka=AssetTag - lock bytes len=2 aka=ReservedBytes2 - structured list len=0..MAX16 wrapped tag=2 - AssignRevealedDataBlindSealTxPtr union - confidential rec tag=0 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 - state bytes len=32 aka=ConcealedData - lock bytes len=2 aka=ReservedBytes2 - confidentialState rec tag=1 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - state bytes len=32 aka=ConcealedData - lock bytes len=2 aka=ReservedBytes2 - confidentialSeal rec tag=2 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 - state rec RevealedData - value bytes len=0..MAX16 aka=DataState - salt is U128 - lock bytes len=2 aka=ReservedBytes2 - revealed rec tag=3 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - state rec RevealedData - value bytes len=0..MAX16 aka=DataState - salt is U128 - lock bytes len=2 aka=ReservedBytes2 - attachment list len=0..MAX16 wrapped tag=3 - AssignRevealedAttachBlindSealTxPtr union - confidential rec tag=0 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 - state bytes len=32 aka=ConcealedAttach - lock bytes len=2 aka=ReservedBytes2 - confidentialState rec tag=1 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - state bytes len=32 aka=ConcealedAttach - lock bytes len=2 aka=ReservedBytes2 - confidentialSeal rec tag=2 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 - state rec RevealedAttach - file rec AttachState - id bytes len=32 aka=AttachId - mediaType enum MediaType any=255 - salt is U64 - lock bytes len=2 aka=ReservedBytes2 - revealed rec tag=3 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - state rec RevealedAttach - file rec AttachState - id bytes len=32 aka=AttachId - mediaType enum MediaType any=255 - salt is U64 - lock bytes len=2 aka=ReservedBytes2 - valencies set len=0..MAX8 aka=Valencies - element is U16 aka=ValencyType - validator bytes len=1 aka=ReservedBytes1 - witness bytes len=2 aka=ReservedBytes2 schema rec Schema ffv is U16 aka=Ffv flags bytes len=1 aka=ReservedBytes1