From 4fd3217196e71882e527b329688824b619359b30 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Wed, 30 Sep 2020 01:28:21 +0200 Subject: [PATCH 01/13] RGB: Introducing extensions & valencies to schema --- src/rgb/contract/nodes.rs | 6 ++-- src/rgb/schema/mod.rs | 9 +++--- src/rgb/schema/nodes.rs | 62 +++++++++++++++++++++++++++++++++++++-- src/rgb/schema/schema.rs | 26 ++++++++++++---- src/rgb/schema/script.rs | 9 ++++++ 5 files changed, 98 insertions(+), 14 deletions(-) diff --git a/src/rgb/contract/nodes.rs b/src/rgb/contract/nodes.rs index f96e88c4..3dde15fa 100644 --- a/src/rgb/contract/nodes.rs +++ b/src/rgb/contract/nodes.rs @@ -36,7 +36,8 @@ tagged_hash!( NodeId, NodeIdTag, MIDSTATE_NODE_ID, - doc = "Unique node (genesis and state transition) identifier equivalent to the commitment hash" + doc = "Unique node (genesis, extensions & state transition) identifier \ + equivalent to the commitment hash" ); impl CommitEncodeWithStrategy for NodeId { @@ -47,7 +48,8 @@ tagged_hash!( ContractId, ContractIdTag, MIDSTATE_NODE_ID, - doc = "Unique contract identifier equivalent to the contract genesis commitment hash" + doc = "Unique contract identifier equivalent to the contract genesis \ + commitment hash" ); pub trait Node { diff --git a/src/rgb/schema/mod.rs b/src/rgb/schema/mod.rs index 6ca3b545..bb688dd4 100644 --- a/src/rgb/schema/mod.rs +++ b/src/rgb/schema/mod.rs @@ -19,12 +19,13 @@ mod types; pub(self) use super::vm; pub use nodes::{ - AssignmentsType, GenesisSchema, MetadataStructure, SealsStructure, TransitionSchema, + AssignmentsType, ExtensionSchema, GenesisSchema, MetadataStructure, SealsStructure, + TransitionSchema, ValenciesStructure, ValenciesType, }; -pub use schema::{FieldType, Schema, SchemaId, TransitionType}; +pub use schema::{ExtensionType, FieldType, Schema, SchemaId, TransitionType}; pub use script::{ - AssignmentAbi, AssignmentAction, GenesisAbi, GenesisAction, SimplicityScript, TransitionAbi, - TransitionAction, + AssignmentAbi, AssignmentAction, ExtensionAbi, ExtensionAction, GenesisAbi, GenesisAction, + SimplicityScript, TransitionAbi, TransitionAction, }; pub use state::{DataFormat, DiscreteFiniteFieldFormat, StateFormat, StateSchema, StateType}; pub use types::{ diff --git a/src/rgb/schema/nodes.rs b/src/rgb/schema/nodes.rs index 238b4d29..4a0dc89c 100644 --- a/src/rgb/schema/nodes.rs +++ b/src/rgb/schema/nodes.rs @@ -11,13 +11,16 @@ // along with this software. // If not, see . -use std::collections::BTreeMap; +use std::collections::{BTreeMap, BTreeSet}; use std::io; -use super::{FieldType, GenesisAbi, Occurences, TransitionAbi}; +use super::{ExtensionAbi, FieldType, GenesisAbi, Occurences, TransitionAbi}; -pub type AssignmentsType = usize; // Here we can use usize since encoding/decoding makes sure that it's u16 +// Here we can use usize since encoding/decoding makes sure that it's u16 +pub type AssignmentsType = usize; +pub type ValenciesType = usize; pub type MetadataStructure = BTreeMap>; +pub type ValenciesStructure = BTreeSet; pub type SealsStructure = BTreeMap>; #[derive(Clone, PartialEq, Debug, Display)] @@ -25,15 +28,27 @@ pub type SealsStructure = BTreeMap>; pub struct GenesisSchema { pub metadata: MetadataStructure, pub defines: SealsStructure, + pub valencies: ValenciesStructure, pub abi: GenesisAbi, } +#[derive(Clone, PartialEq, Debug, Display)] +#[display(Debug)] +pub struct ExtensionSchema { + pub metadata: MetadataStructure, + pub extends: ValenciesStructure, + pub defines: SealsStructure, + pub valencies: ValenciesStructure, + pub abi: ExtensionAbi, +} + #[derive(Clone, PartialEq, Debug, Display)] #[display(Debug)] pub struct TransitionSchema { pub metadata: MetadataStructure, pub closes: SealsStructure, pub defines: SealsStructure, + pub valencies: ValenciesStructure, pub abi: TransitionAbi, } @@ -47,6 +62,7 @@ mod strict_encoding { fn strict_encode(&self, mut e: E) -> Result { self.metadata.strict_encode(&mut e)?; self.defines.strict_encode(&mut e)?; + self.valencies.strict_encode(&mut e)?; self.abi.strict_encode(&mut e)?; // We keep this parameter for future script extended info (like ABI) Vec::::new().strict_encode(&mut e) @@ -60,6 +76,7 @@ mod strict_encoding { let me = Self { metadata: MetadataStructure::strict_decode(&mut d)?, defines: SealsStructure::strict_decode(&mut d)?, + valencies: ValenciesStructure::strict_decode(&mut d)?, abi: GenesisAbi::strict_decode(&mut d)?, }; // We keep this parameter for future script extended info (like ABI) @@ -74,6 +91,43 @@ mod strict_encoding { } } + impl StrictEncode for ExtensionSchema { + type Error = Error; + + fn strict_encode(&self, mut e: E) -> Result { + self.metadata.strict_encode(&mut e)?; + self.extends.strict_encode(&mut e)?; + self.defines.strict_encode(&mut e)?; + self.valencies.strict_encode(&mut e)?; + self.abi.strict_encode(&mut e)?; + // We keep this parameter for future script extended info (like ABI) + Vec::::new().strict_encode(&mut e) + } + } + + impl StrictDecode for ExtensionSchema { + type Error = Error; + + fn strict_decode(mut d: D) -> Result { + let me = Self { + metadata: MetadataStructure::strict_decode(&mut d)?, + extends: ValenciesStructure::strict_decode(&mut d)?, + defines: SealsStructure::strict_decode(&mut d)?, + valencies: ValenciesStructure::strict_decode(&mut d)?, + abi: ExtensionAbi::strict_decode(&mut d)?, + }; + // We keep this parameter for future script extended info (like ABI) + let script = Vec::::strict_decode(&mut d)?; + if !script.is_empty() { + Err(Error::UnsupportedDataStructure( + "Scripting information is not yet supported", + )) + } else { + Ok(me) + } + } + } + impl StrictEncode for TransitionSchema { type Error = Error; @@ -81,6 +135,7 @@ mod strict_encoding { self.metadata.strict_encode(&mut e)?; self.closes.strict_encode(&mut e)?; self.defines.strict_encode(&mut e)?; + self.valencies.strict_encode(&mut e)?; self.abi.strict_encode(&mut e)?; // We keep this parameter for future script extended info (like ABI) Vec::::new().strict_encode(&mut e) @@ -95,6 +150,7 @@ mod strict_encoding { metadata: MetadataStructure::strict_decode(&mut d)?, closes: SealsStructure::strict_decode(&mut d)?, defines: SealsStructure::strict_decode(&mut d)?, + valencies: ValenciesStructure::strict_decode(&mut d)?, abi: TransitionAbi::strict_decode(&mut d)?, }; // We keep this parameter for future script extended info (like ABI) diff --git a/src/rgb/schema/schema.rs b/src/rgb/schema/schema.rs index aad3c713..5499ccb6 100644 --- a/src/rgb/schema/schema.rs +++ b/src/rgb/schema/schema.rs @@ -11,18 +11,22 @@ // along with this software. // If not, see . -use std::collections::BTreeMap; +use std::collections::{BTreeMap, BTreeSet}; use std::io; use bitcoin::hashes::{sha256, sha256t, Hash, HashEngine}; use super::{ - vm, AssignmentsType, DataFormat, GenesisSchema, SimplicityScript, StateSchema, TransitionSchema, + vm, AssignmentsType, DataFormat, ExtensionSchema, GenesisSchema, SimplicityScript, StateSchema, + TransitionSchema, }; use crate::client_side_validation::{commit_strategy, CommitEncodeWithStrategy, ConsensusCommit}; +use crate::rgb::schema::ValenciesType; -pub type FieldType = usize; // Here we can use usize since encoding/decoding makes sure that it's u16 -pub type TransitionType = usize; // Here we can use usize since encoding/decoding makes sure that it's u16 +// Here we can use usize since encoding/decoding makes sure that it's u16 +pub type FieldType = usize; +pub type ExtensionType = usize; +pub type TransitionType = usize; lazy_static! { static ref MIDSTATE_SHEMA_ID: [u8; 32] = { @@ -45,7 +49,9 @@ tagged_hash!( pub struct Schema { pub field_types: BTreeMap, pub assignment_types: BTreeMap, + pub valencies_types: BTreeSet, pub genesis: GenesisSchema, + pub extensions: BTreeMap, pub transitions: BTreeMap, } @@ -85,7 +91,9 @@ mod strict_encoding { Ok(strict_encode_list!(e; self.field_types, self.assignment_types, + self.valencies_types, self.genesis, + self.extensions, self.transitions, // We keep this parameter for future script extended info (like ABI) Vec::::new() @@ -100,7 +108,9 @@ mod strict_encoding { let me = Self { field_types: BTreeMap::strict_decode(&mut d)?, assignment_types: BTreeMap::strict_decode(&mut d)?, + valencies_types: BTreeSet::strict_decode(&mut d)?, genesis: GenesisSchema::strict_decode(&mut d)?, + extensions: BTreeMap::strict_decode(&mut d)?, transitions: BTreeMap::strict_decode(&mut d)?, }; // We keep this parameter for future script extended info (like ABI) @@ -116,6 +126,7 @@ mod strict_encoding { } } +/// TODO: (new) Add extension validation mod _validation { use super::*; @@ -553,8 +564,10 @@ pub(crate) mod test { ASSIGNMENT_ASSETS => Occurences::NoneOrUpTo(None), ASSIGNMENT_PRUNE => Occurences::NoneOrUpTo(None) }, + valencies: bmap! {}, abi: bmap! {}, }, + extensions: bmap! {}, transitions: bmap! { TRANSITION_ISSUE => TransitionSchema { metadata: bmap! { @@ -568,7 +581,8 @@ pub(crate) mod test { ASSIGNMENT_PRUNE => Occurences::NoneOrUpTo(None), ASSIGNMENT_ASSETS => Occurences::NoneOrUpTo(None) }, - abi: bmap! {} + valencies: bmap! {}, + abi: bmap! {} }, TRANSITION_TRANSFER => TransitionSchema { metadata: bmap! {}, @@ -578,6 +592,7 @@ pub(crate) mod test { defines: bmap! { ASSIGNMENT_ASSETS => Occurences::NoneOrUpTo(None) }, + valencies: bmap! {}, abi: bmap! {} }, TRANSITION_PRUNE => TransitionSchema { @@ -592,6 +607,7 @@ pub(crate) mod test { ASSIGNMENT_PRUNE => Occurences::NoneOrUpTo(None), ASSIGNMENT_ASSETS => Occurences::NoneOrUpTo(None) }, + valencies: bmap! {}, abi: bmap! {} } }, diff --git a/src/rgb/schema/script.rs b/src/rgb/schema/script.rs index f15a1a11..735563cb 100644 --- a/src/rgb/schema/script.rs +++ b/src/rgb/schema/script.rs @@ -25,6 +25,13 @@ pub type SimplicityScript = Vec; #[display(Debug)] pub enum GenesisAction {} +#[non_exhaustive] +#[derive( + Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Display, ToPrimitive, FromPrimitive, +)] +#[display(Debug)] +pub enum ExtensionAction {} + #[non_exhaustive] #[derive( Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Display, ToPrimitive, FromPrimitive, @@ -46,6 +53,7 @@ pub enum AssignmentAction { } pub type GenesisAbi = BTreeMap; +pub type ExtensionAbi = BTreeMap; pub type TransitionAbi = BTreeMap; pub type AssignmentAbi = BTreeMap; @@ -76,6 +84,7 @@ mod strict_encoding { impl_enum_strict_encoding!(GenesisAction); impl_enum_strict_encoding!(TransitionAction); impl_enum_strict_encoding!(AssignmentAction); + impl_enum_strict_encoding!(ExtensionAction); impl_enum_strict_encoding!(StandardProcedure); From 1f1fb35ceef3bbb6571b18f995ab0bead6a04427 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Wed, 30 Sep 2020 01:47:47 +0200 Subject: [PATCH 02/13] Sample schema with extensions & valencies --- src/rgb/schema/schema.rs | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/src/rgb/schema/schema.rs b/src/rgb/schema/schema.rs index 5499ccb6..d2f83414 100644 --- a/src/rgb/schema/schema.rs +++ b/src/rgb/schema/schema.rs @@ -508,6 +508,8 @@ pub(crate) mod test { const FIELD_PRUNE_PROOF: usize = 7; const FIELD_TIMESTAMP: usize = 8; + const FIELD_PROOF_OF_BURN: usize = 0x10; + const ASSIGNMENT_ISSUE: usize = 0; const ASSIGNMENT_ASSETS: usize = 1; const ASSIGNMENT_PRUNE: usize = 2; @@ -516,6 +518,10 @@ pub(crate) mod test { const TRANSITION_TRANSFER: usize = 1; const TRANSITION_PRUNE: usize = 2; + const VALENCIES_DECENTRALIZED_ISSUE: usize = 0; + + const EXTENSION_DECENTRALIZED_ISSUE: usize = 0; + Schema { field_types: bmap! { FIELD_TICKER => DataFormat::String(16), @@ -526,7 +532,9 @@ pub(crate) mod test { FIELD_ISSUED_SUPPLY => DataFormat::Unsigned(Bits::Bit64, 0, core::u64::MAX as u128), FIELD_DUST_LIMIT => DataFormat::Unsigned(Bits::Bit64, 0, core::u64::MAX as u128), FIELD_PRUNE_PROOF => DataFormat::Bytes(core::u16::MAX), - FIELD_TIMESTAMP => DataFormat::Unsigned(Bits::Bit64, 0, core::u64::MAX as u128) + FIELD_TIMESTAMP => DataFormat::Unsigned(Bits::Bit64, 0, core::u64::MAX as u128), + // TODO: (new) Fix this with introduction of new data type + FIELD_PROOF_OF_BURN => DataFormat::String(0) }, assignment_types: bmap! { ASSIGNMENT_ISSUE => StateSchema { @@ -548,6 +556,9 @@ pub(crate) mod test { } } }, + valencies_types: bset! { + VALENCIES_DECENTRALIZED_ISSUE + }, genesis: GenesisSchema { metadata: bmap! { FIELD_TICKER => Occurences::Once, @@ -564,10 +575,23 @@ pub(crate) mod test { ASSIGNMENT_ASSETS => Occurences::NoneOrUpTo(None), ASSIGNMENT_PRUNE => Occurences::NoneOrUpTo(None) }, - valencies: bmap! {}, + valencies: bset! { VALENCIES_DECENTRALIZED_ISSUE }, abi: bmap! {}, }, - extensions: bmap! {}, + extensions: bmap! { + EXTENSION_DECENTRALIZED_ISSUE => ExtensionSchema { + metadata: bmap! { + FIELD_ISSUED_SUPPLY => Occurences::Once, + FIELD_PROOF_OF_BURN => Occurences::OnceOrUpTo(None) + }, + defines: bmap! { + ASSIGNMENT_ASSETS => Occurences::NoneOrUpTo(None) + }, + extends: bset! { VALENCIES_DECENTRALIZED_ISSUE }, + valencies: bset! { }, + abi: bmap! {}, + } + }, transitions: bmap! { TRANSITION_ISSUE => TransitionSchema { metadata: bmap! { @@ -581,7 +605,7 @@ pub(crate) mod test { ASSIGNMENT_PRUNE => Occurences::NoneOrUpTo(None), ASSIGNMENT_ASSETS => Occurences::NoneOrUpTo(None) }, - valencies: bmap! {}, + valencies: bset! {}, abi: bmap! {} }, TRANSITION_TRANSFER => TransitionSchema { @@ -592,7 +616,7 @@ pub(crate) mod test { defines: bmap! { ASSIGNMENT_ASSETS => Occurences::NoneOrUpTo(None) }, - valencies: bmap! {}, + valencies: bset! {}, abi: bmap! {} }, TRANSITION_PRUNE => TransitionSchema { @@ -607,7 +631,7 @@ pub(crate) mod test { ASSIGNMENT_PRUNE => Occurences::NoneOrUpTo(None), ASSIGNMENT_ASSETS => Occurences::NoneOrUpTo(None) }, - valencies: bmap! {}, + valencies: bset! {}, abi: bmap! {} } }, From 85a885ddf03fb9eed4cfad66ea461155137644e8 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Wed, 30 Sep 2020 02:34:02 +0200 Subject: [PATCH 03/13] RGB: contract extensions and valencies --- src/rgb/contract/nodes.rs | 253 +++++++++++++++++++++++++++++++++++--- src/rgb/schema/mod.rs | 2 +- src/rgb/schema/nodes.rs | 22 ++++ src/rgb/schema/schema.rs | 60 +++++---- src/rgb/validation.rs | 1 + 5 files changed, 293 insertions(+), 45 deletions(-) diff --git a/src/rgb/contract/nodes.rs b/src/rgb/contract/nodes.rs index 3dde15fa..90de70c7 100644 --- a/src/rgb/contract/nodes.rs +++ b/src/rgb/contract/nodes.rs @@ -19,9 +19,15 @@ use super::{Ancestors, Assignments, AssignmentsVariant, AutoConceal}; use crate::bp; use crate::client_side_validation::{commit_strategy, CommitEncodeWithStrategy, ConsensusCommit}; use crate::paradigms::client_side_validation::CommitEncode; -use crate::rgb::schema::AssignmentsType; +use crate::rgb::schema::{ + AssignmentsType, ExtensionType, FieldType, NodeType, TransitionType, ValenciesType, +}; use crate::rgb::{schema, seal, Metadata, SchemaId, SimplicityScript}; +/// Holds definition of valencies for contract nodes, which is a set of +/// allowed valencies types +pub type Valencies = BTreeSet; + lazy_static! { static ref MIDSTATE_NODE_ID: [u8; 32] = { let hash = sha256::Hash::hash(b"rgb:node"); @@ -44,6 +50,7 @@ impl CommitEncodeWithStrategy for NodeId { type Strategy = commit_strategy::UsingStrict; } +// TODO: (new) display in a reverse format tagged_hash!( ContractId, ContractIdTag, @@ -52,36 +59,67 @@ tagged_hash!( commitment hash" ); +impl CommitEncodeWithStrategy for ContractId { + type Strategy = commit_strategy::UsingStrict; +} + +/// Trait which is implemented by all node types (see [`NodeType`]) pub trait Node { + /// Returns type of the node (see [`NodeType`]). Unfortunately, this can't + /// be just a const, since it will break our ability to convert concrete + /// `Node` types into `&dyn Node` (entities implementing traits with const + /// definitions can't be made into objects) + fn node_type(&self) -> NodeType; + + /// Returns [`NodeId`], which is a hash of this node commitment + /// serialization fn node_id(&self) -> NodeId; - /// Returns `Some([schema::TransitionType])` for Transitions or None for - /// Genesis node - fn type_id(&self) -> Option; + /// Returns [`Option::Some`]`(`[`ContractId`]`)`, which is a hash of + /// genesis. + /// - For genesis node, this hash is byte-equal to [`NodeId`] (however + /// displayed in a reverse manner, to introduce semantical distinction) + /// - For extension node function returns id of the genesis, to which this + /// node commits to + /// - For state transition function returns [`Option::None`], since they do + /// not keep this information; it must be deduced through state transition + /// graph + fn contract_id(&self) -> Option; + + /// Returns [`Option::Some`]`(`[`TransitionType`]`)` for transitions or + /// [`Option::None`] for genesis and extension node types + fn transition_type(&self) -> Option; + + /// Returns [`Option::Some`]`(`[`ExtensionType`]`)` for extension nodes or + /// [`Option::None`] for genesis and trate transitions + fn extension_type(&self) -> Option; fn ancestors(&self) -> &Ancestors; fn metadata(&self) -> &Metadata; fn assignments(&self) -> &Assignments; fn assignments_mut(&mut self) -> &mut Assignments; + fn valencies(&self) -> &Valencies; + fn valencies_mut(&mut self) -> &mut Valencies; fn script(&self) -> &SimplicityScript; #[inline] - fn field_types(&self) -> Vec { + fn field_types(&self) -> Vec { self.metadata().keys().cloned().collect() } #[inline] - fn assignment_types(&self) -> BTreeSet { + fn assignment_types(&self) -> BTreeSet { self.assignments().keys().cloned().collect() } #[inline] - fn assignments_by_type(&self, t: schema::AssignmentsType) -> Option<&AssignmentsVariant> { + fn assignments_by_type(&self, t: AssignmentsType) -> Option<&AssignmentsVariant> { self.assignments() .into_iter() .find_map(|(t2, a)| if *t2 == t { Some(a) } else { None }) } + #[inline] fn all_seal_definitions(&self) -> Vec { self.assignments() .into_iter() @@ -89,6 +127,7 @@ pub trait Node { .collect() } + #[inline] fn known_seal_definitions(&self) -> Vec<&seal::Revealed> { self.assignments() .into_iter() @@ -96,6 +135,7 @@ pub trait Node { .collect() } + #[inline] fn known_seal_definitions_by_type( &self, assignment_type: AssignmentsType, @@ -113,16 +153,28 @@ pub struct Genesis { chain: bp::Chain, metadata: Metadata, assignments: Assignments, + valencies: Valencies, + script: SimplicityScript, +} + +#[derive(Clone, Debug, PartialEq)] +pub struct Extension { + extension_type: ExtensionType, + contract_id: ContractId, + metadata: Metadata, + assignments: Assignments, + valencies: Valencies, script: SimplicityScript, } #[derive(Clone, Debug, PartialEq, StrictEncode, StrictDecode)] #[strict_crate(crate)] pub struct Transition { - type_id: schema::TransitionType, + transition_type: TransitionType, metadata: Metadata, ancestors: Ancestors, assignments: Assignments, + valencies: Valencies, script: SimplicityScript, } @@ -130,14 +182,22 @@ impl ConsensusCommit for Genesis { type Commitment = NodeId; } -impl CommitEncodeWithStrategy for Transition { - type Strategy = commit_strategy::UsingStrict; +impl ConsensusCommit for Extension { + type Commitment = NodeId; } impl ConsensusCommit for Transition { type Commitment = NodeId; } +impl CommitEncodeWithStrategy for Extension { + type Strategy = commit_strategy::UsingStrict; +} + +impl CommitEncodeWithStrategy for Transition { + type Strategy = commit_strategy::UsingStrict; +} + impl AutoConceal for Genesis { fn conceal_except(&mut self, seals: &Vec) -> usize { let mut count = 0; @@ -148,6 +208,16 @@ impl AutoConceal for Genesis { } } +impl AutoConceal for Extension { + fn conceal_except(&mut self, seals: &Vec) -> usize { + let mut count = 0; + for (_, assignment) in self.assignments_mut() { + count += assignment.conceal_except(seals); + } + count + } +} + impl AutoConceal for Transition { fn conceal_except(&mut self, seals: &Vec) -> usize { let mut count = 0; @@ -160,13 +230,27 @@ impl AutoConceal for Transition { impl Node for Genesis { #[inline] + fn node_type(&self) -> NodeType { + NodeType::Genesis + } + #[inline] fn node_id(&self) -> NodeId { self.clone().consensus_commit() } #[inline] - fn type_id(&self) -> Option { + fn contract_id(&self) -> Option { + Some(ContractId::from_inner(self.node_id().into_inner())) + } + + #[inline] + fn transition_type(&self) -> Option { + None + } + + #[inline] + fn extension_type(&self) -> Option { None } @@ -193,6 +277,81 @@ impl Node for Genesis { &mut self.assignments } + #[inline] + fn valencies(&self) -> &Valencies { + &self.valencies + } + + #[inline] + fn valencies_mut(&mut self) -> &mut Valencies { + &mut self.valencies + } + + #[inline] + fn script(&self) -> &SimplicityScript { + &self.script + } +} + +impl Node for Extension { + #[inline] + fn node_type(&self) -> NodeType { + NodeType::Extension + } + + #[inline] + fn node_id(&self) -> NodeId { + self.clone().consensus_commit() + } + + #[inline] + fn contract_id(&self) -> Option { + Some(self.contract_id) + } + + #[inline] + fn transition_type(&self) -> Option { + None + } + + #[inline] + fn extension_type(&self) -> Option { + Some(self.extension_type) + } + + #[inline] + fn ancestors(&self) -> &Ancestors { + lazy_static! { + static ref ANCESTORS: Ancestors = Ancestors::new(); + } + &ANCESTORS + } + + #[inline] + fn metadata(&self) -> &Metadata { + &self.metadata + } + + #[inline] + fn assignments(&self) -> &Assignments { + &self.assignments + } + + #[inline] + fn assignments_mut(&mut self) -> &mut Assignments { + &mut self.assignments + } + + #[inline] + fn valencies(&self) -> &Valencies { + &self.valencies + } + + #[inline] + fn valencies_mut(&mut self) -> &mut Valencies { + &mut self.valencies + } + #[inline] fn script(&self) -> &SimplicityScript { &self.script @@ -200,14 +359,29 @@ impl Node for Genesis { } impl Node for Transition { + #[inline] + fn node_type(&self) -> NodeType { + NodeType::StateTransition + } + #[inline] fn node_id(&self) -> NodeId { self.clone().consensus_commit() } #[inline] - fn type_id(&self) -> Option { - Some(self.type_id) + fn contract_id(&self) -> Option { + None + } + + #[inline] + fn transition_type(&self) -> Option { + Some(self.transition_type) + } + + #[inline] + fn extension_type(&self) -> Option { + None } #[inline] @@ -230,6 +404,16 @@ impl Node for Transition { &mut self.assignments } + #[inline] + fn valencies(&self) -> &Valencies { + &self.valencies + } + + #[inline] + fn valencies_mut(&mut self) -> &mut Valencies { + &mut self.valencies + } + #[inline] fn script(&self) -> &SimplicityScript { &self.script @@ -242,6 +426,7 @@ impl Genesis { chain: bp::Chain, metadata: Metadata, assignments: Assignments, + valencies: Valencies, script: SimplicityScript, ) -> Self { Self { @@ -249,6 +434,7 @@ impl Genesis { chain, metadata, assignments, + valencies, script, } } @@ -269,19 +455,41 @@ impl Genesis { } } +impl Extension { + pub fn with( + extension_type: ExtensionType, + contract_id: ContractId, + metadata: Metadata, + assignments: Assignments, + valencies: Valencies, + script: SimplicityScript, + ) -> Self { + Self { + extension_type, + contract_id, + metadata, + assignments, + valencies, + script, + } + } +} + impl Transition { pub fn with( type_id: schema::TransitionType, metadata: Metadata, ancestors: Ancestors, assignments: Assignments, + valencies: Valencies, script: SimplicityScript, ) -> Self { Self { - type_id, + transition_type: type_id, metadata, ancestors, assignments, + valencies, script, } } @@ -312,6 +520,7 @@ mod strict_encoding { Ok(strict_encode_list!(e; len; self.metadata, self.assignments, + self.valencies, self.script )) }; @@ -322,6 +531,7 @@ mod strict_encoding { #[cfg(test)] mod test { + // TODO: (new) Implement tests for extensions and valencies use super::*; use crate::bp::chain::{Chain, GENESIS_HASH_MAINNET}; @@ -663,7 +873,8 @@ mod test { chain: Chain::Mainnet, metadata: Default::default(), assignments: Default::default(), - script: vec![], + valencies: Default::default(), + script: Default::default(), }; assert_ne!( strict_encode(&genesis).unwrap(), @@ -682,15 +893,19 @@ mod test { ); let transition = Transition { - type_id: Default::default(), + transition_type: Default::default(), metadata: Default::default(), ancestors: Default::default(), assignments: Default::default(), + valencies: Default::default(), script: Default::default(), }; let mut encoder = std::io::Cursor::new(vec![]); - transition.type_id.strict_encode(&mut encoder).unwrap(); + transition + .transition_type + .strict_encode(&mut encoder) + .unwrap(); transition.metadata.strict_encode(&mut encoder).unwrap(); transition.ancestors.strict_encode(&mut encoder).unwrap(); transition.assignments.strict_encode(&mut encoder).unwrap(); @@ -727,8 +942,8 @@ mod test { "5b81b9895ccc0f2cb9afaa54d73a70cab3a10d0de67f7b2c119099ed435355fd" ); - assert_eq!(genesis.type_id(), None); - assert_eq!(transition.type_id(), Some(10)); + assert_eq!(genesis.transition_type(), None); + assert_eq!(transition.transition_type(), Some(10)); // Ancestor test diff --git a/src/rgb/schema/mod.rs b/src/rgb/schema/mod.rs index bb688dd4..54bdff41 100644 --- a/src/rgb/schema/mod.rs +++ b/src/rgb/schema/mod.rs @@ -19,7 +19,7 @@ mod types; pub(self) use super::vm; pub use nodes::{ - AssignmentsType, ExtensionSchema, GenesisSchema, MetadataStructure, SealsStructure, + AssignmentsType, ExtensionSchema, GenesisSchema, MetadataStructure, NodeType, SealsStructure, TransitionSchema, ValenciesStructure, ValenciesType, }; pub use schema::{ExtensionType, FieldType, Schema, SchemaId, TransitionType}; diff --git a/src/rgb/schema/nodes.rs b/src/rgb/schema/nodes.rs index 4a0dc89c..169de554 100644 --- a/src/rgb/schema/nodes.rs +++ b/src/rgb/schema/nodes.rs @@ -23,6 +23,28 @@ pub type MetadataStructure = BTreeMap>; pub type ValenciesStructure = BTreeSet; pub type SealsStructure = BTreeMap>; +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Display)] +/// Node type: genesis, extensions and state transitions +pub enum NodeType { + /// Genesis node: single node per contract, defining contract and committing + /// to a specific schema and underlying chain hash + #[display("genesis")] + Genesis, + + /// Multiple points for decentralized & unowned contract extension, + /// committing either to a genesis or some state transition via their + /// valencies + #[display("extension")] + Extension, + + /// State transition performing owned change to the state data and + /// committing to (potentially multiple) ancestors (i.e. genesis, extensions + /// and/or other state transitions) via spending corresponding transaction + /// outputs assigned some state by ancestors + #[display("transition")] + StateTransition, +} + #[derive(Clone, PartialEq, Debug, Display)] #[display(Debug)] pub struct GenesisSchema { diff --git a/src/rgb/schema/schema.rs b/src/rgb/schema/schema.rs index d2f83414..0bb23a80 100644 --- a/src/rgb/schema/schema.rs +++ b/src/rgb/schema/schema.rs @@ -146,32 +146,42 @@ mod _validation { node: &dyn Node, ) -> validation::Status { let node_id = node.node_id(); - let type_id = node.type_id(); let empty_seals_structure = SealsStructure::default(); - let (metadata_structure, ancestors_structure, assignments_structure) = match type_id { - None => ( - &self.genesis.metadata, - &empty_seals_structure, - &self.genesis.defines, - ), - Some(type_id) => { - let transition_type = match self.transitions.get(&type_id) { - None => { - return validation::Status::with_failure( - validation::Failure::SchemaUnknownTransitionType(node_id, type_id), - ) - } - Some(transition_type) => transition_type, - }; - - ( - &transition_type.metadata, - &transition_type.closes, - &transition_type.defines, - ) - } - }; + let (metadata_structure, ancestors_structure, assignments_structure) = + match (node.transition_type(), node.extension_type()) { + (None, None) => ( + &self.genesis.metadata, + &empty_seals_structure, + &self.genesis.defines, + ), + (Some(transition_type), None) => { + let transition_type = match self.transitions.get(&transition_type) { + None => { + return validation::Status::with_failure( + validation::Failure::SchemaUnknownTransitionType( + node_id, + transition_type, + ), + ) + } + Some(transition_type) => transition_type, + }; + + ( + &transition_type.metadata, + &transition_type.closes, + &transition_type.defines, + ) + } + (None, Some(_extension_type)) => { + // TODO: (new) Add extension validation + unimplemented!() + } + _ => unreachable!( + "Node can't be extension and state transition at the same time" + ), + }; let mut status = validation::Status::new(); let ancestor_assignments = @@ -181,7 +191,7 @@ mod _validation { status += self.validate_assignments(node_id, node.assignments(), assignments_structure); status += self.validate_state_evolution( node_id, - node.type_id(), + node.transition_type(), &ancestor_assignments, node.assignments(), node.metadata(), diff --git a/src/rgb/validation.rs b/src/rgb/validation.rs index 818d77bf..5bc37e94 100644 --- a/src/rgb/validation.rs +++ b/src/rgb/validation.rs @@ -223,6 +223,7 @@ pub struct Validator<'validator, R: TxResolver> { resolver: R, } +/// TODO: (new) Add extension & vacancies validation impl<'validator, R: TxResolver> Validator<'validator, R> { fn init(consignment: &'validator Consignment, resolver: R) -> Self { // We use validation status object to store all detected failures and From 66118a3ec3e1b9fe7228920ff7bc9c3de9a13953 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Wed, 30 Sep 2020 03:00:25 +0200 Subject: [PATCH 04/13] RGB: valencies schema validation --- src/rgb/schema/schema.rs | 111 +++++++++++++++++++++++++++------------ src/rgb/validation.rs | 4 +- 2 files changed, 78 insertions(+), 37 deletions(-) diff --git a/src/rgb/schema/schema.rs b/src/rgb/schema/schema.rs index 0bb23a80..34ca764e 100644 --- a/src/rgb/schema/schema.rs +++ b/src/rgb/schema/schema.rs @@ -126,14 +126,14 @@ mod strict_encoding { } } -/// TODO: (new) Add extension validation mod _validation { use super::*; use core::convert::TryFrom; use std::collections::BTreeSet; - use crate::rgb::schema::{script, MetadataStructure, SealsStructure}; + use crate::rgb::contract::nodes::Valencies; + use crate::rgb::schema::{script, MetadataStructure, SealsStructure, ValenciesStructure}; use crate::rgb::{ validation, Ancestors, AssignmentAction, Assignments, AssignmentsVariant, Metadata, Node, NodeId, VirtualMachine, @@ -148,40 +148,60 @@ mod _validation { let node_id = node.node_id(); let empty_seals_structure = SealsStructure::default(); - let (metadata_structure, ancestors_structure, assignments_structure) = - match (node.transition_type(), node.extension_type()) { - (None, None) => ( - &self.genesis.metadata, + let ( + metadata_structure, + ancestors_structure, + assignments_structure, + valencies_structure, + ) = match (node.transition_type(), node.extension_type()) { + (None, None) => ( + &self.genesis.metadata, + &empty_seals_structure, + &self.genesis.defines, + &self.genesis.valencies, + ), + (Some(transition_type), None) => { + let transition_type = match self.transitions.get(&transition_type) { + None => { + return validation::Status::with_failure( + validation::Failure::SchemaUnknownTransitionType( + node_id, + transition_type, + ), + ) + } + Some(transition_type) => transition_type, + }; + + ( + &transition_type.metadata, + &transition_type.closes, + &transition_type.defines, + &transition_type.valencies, + ) + } + (None, Some(extension_type)) => { + let extension_type = match self.extensions.get(&extension_type) { + None => { + return validation::Status::with_failure( + validation::Failure::SchemaUnknownExtensionType( + node_id, + extension_type, + ), + ) + } + Some(extension_type) => extension_type, + }; + + ( + &extension_type.metadata, &empty_seals_structure, - &self.genesis.defines, - ), - (Some(transition_type), None) => { - let transition_type = match self.transitions.get(&transition_type) { - None => { - return validation::Status::with_failure( - validation::Failure::SchemaUnknownTransitionType( - node_id, - transition_type, - ), - ) - } - Some(transition_type) => transition_type, - }; - - ( - &transition_type.metadata, - &transition_type.closes, - &transition_type.defines, - ) - } - (None, Some(_extension_type)) => { - // TODO: (new) Add extension validation - unimplemented!() - } - _ => unreachable!( - "Node can't be extension and state transition at the same time" - ), - }; + &extension_type.defines, + &extension_type.extends, + ) + } + _ => unreachable!("Node can't be extension and state transition at the same time"), + }; let mut status = validation::Status::new(); let ancestor_assignments = @@ -189,6 +209,7 @@ mod _validation { status += self.validate_meta(node_id, node.metadata(), metadata_structure); status += self.validate_ancestors(node_id, &ancestor_assignments, ancestors_structure); status += self.validate_assignments(node_id, node.assignments(), assignments_structure); + status += self.validate_valencies(node_id, node.valencies(), valencies_structure); status += self.validate_state_evolution( node_id, node.transition_type(), @@ -338,6 +359,26 @@ mod _validation { status } + fn validate_valencies( + &self, + node_id: NodeId, + valencies: &Valencies, + valencies_structure: &ValenciesStructure, + ) -> validation::Status { + let mut status = validation::Status::new(); + + valencies + .difference(&valencies_structure) + .for_each(|valencies_id| { + status.add_failure(validation::Failure::SchemaUnknownValenciesType( + node_id, + *valencies_id, + )); + }); + + status + } + fn validate_state_evolution( &self, node_id: NodeId, diff --git a/src/rgb/validation.rs b/src/rgb/validation.rs index 5bc37e94..9687e5a9 100644 --- a/src/rgb/validation.rs +++ b/src/rgb/validation.rs @@ -132,11 +132,11 @@ impl Status { pub enum Failure { SchemaUnknown(SchemaId), + SchemaUnknownExtensionType(NodeId, schema::ExtensionType), SchemaUnknownTransitionType(NodeId, schema::TransitionType), - SchemaUnknownFieldType(NodeId, schema::FieldType), - SchemaUnknownAssignmentType(NodeId, schema::AssignmentsType), + SchemaUnknownValenciesType(NodeId, schema::ValenciesType), SchemaDeniedScriptExtension(NodeId), From aea97112a69b9048541e02f040083abe3a6a6df9 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Wed, 30 Sep 2020 03:12:49 +0200 Subject: [PATCH 05/13] RGB: extensions added to consignments --- src/rgb/contract/mod.rs | 2 +- src/rgb/mod.rs | 13 +++++++------ src/rgb/stash/consignment.rs | 19 +++++++++++++------ src/rgb/stash/mod.rs | 2 +- src/rgb/validation.rs | 7 +++++++ 5 files changed, 29 insertions(+), 14 deletions(-) diff --git a/src/rgb/contract/mod.rs b/src/rgb/contract/mod.rs index 087f40b2..e3dc0e91 100644 --- a/src/rgb/contract/mod.rs +++ b/src/rgb/contract/mod.rs @@ -27,7 +27,7 @@ pub use assignments::{ }; pub use conceal::AutoConceal; pub use field::{FieldData, Metadata}; -pub use nodes::{ContractId, Genesis, Node, NodeId, Transition}; +pub use nodes::{ContractId, Extension, Genesis, Node, NodeId, Transition}; pub use seal::SealDefinition; use secp256k1zkp::Secp256k1 as Secp256k1zkp; diff --git a/src/rgb/mod.rs b/src/rgb/mod.rs index 795839d7..b923c66e 100644 --- a/src/rgb/mod.rs +++ b/src/rgb/mod.rs @@ -24,16 +24,17 @@ pub mod prelude { pub use super::{bech32, schema, vm}; pub use contract::{ amount, data, seal, Amount, Ancestors, Assignment, Assignments, AssignmentsVariant, - AutoConceal, ConfidentialState, ContractId, DeclarativeStrategy, FieldData, Genesis, - HashStrategy, Metadata, Node, NodeId, PedersenStrategy, RevealedState, SealDefinition, - StateTypes, Transition, + AutoConceal, ConfidentialState, ContractId, DeclarativeStrategy, Extension, FieldData, + Genesis, HashStrategy, Metadata, Node, NodeId, PedersenStrategy, RevealedState, + SealDefinition, StateTypes, Transition, }; pub use schema::{ - script, AssignmentAbi, AssignmentAction, GenesisAbi, GenesisAction, Schema, SchemaId, - SimplicityScript, TransitionAbi, TransitionAction, + script, AssignmentAbi, AssignmentAction, ExtensionAbi, ExtensionAction, ExtensionSchema, + ExtensionType, GenesisAbi, GenesisAction, Schema, SchemaId, SimplicityScript, + TransitionAbi, TransitionAction, ValenciesStructure, ValenciesType, }; pub use stash::{ - Anchor, AnchorId, Consignment, ConsignmentData, ConsignmentEndpoints, Disclosure, Stash, + Anchor, AnchorId, Consignment, ConsignmentEndpoints, Disclosure, OwnedData, Stash, PSBT_FEE_KEY, PSBT_PUBKEY_KEY, }; pub use validation::{Validator, Validity}; diff --git a/src/rgb/stash/consignment.rs b/src/rgb/stash/consignment.rs index 1fce2da8..5aaa477f 100644 --- a/src/rgb/stash/consignment.rs +++ b/src/rgb/stash/consignment.rs @@ -16,10 +16,13 @@ use std::collections::BTreeSet; use bitcoin::Txid; use crate::bp; -use crate::rgb::{validation, Anchor, Genesis, Node, NodeId, Schema, Transition, Validator}; +use crate::rgb::{ + validation, Anchor, Extension, Genesis, Node, NodeId, Schema, Transition, Validator, +}; pub type ConsignmentEndpoints = Vec<(NodeId, bp::blind::OutpointHash)>; -pub type ConsignmentData = Vec<(Anchor, Transition)>; +pub type OwnedData = Vec<(Anchor, Transition)>; +pub type ExtensionData = Vec; pub const RGB_CONSIGNMENT_VERSION: u16 = 0; @@ -30,18 +33,21 @@ pub struct Consignment { version: u16, pub genesis: Genesis, pub endpoints: ConsignmentEndpoints, - pub data: ConsignmentData, + pub data: OwnedData, + pub extensions: ExtensionData, } impl Consignment { pub fn with( genesis: Genesis, endpoints: ConsignmentEndpoints, - data: ConsignmentData, + data: OwnedData, + extensions: ExtensionData, ) -> Consignment { Self { version: RGB_CONSIGNMENT_VERSION, genesis, + extensions, endpoints, data, } @@ -54,8 +60,9 @@ impl Consignment { #[inline] pub fn node_ids(&self) -> BTreeSet { - let mut set: BTreeSet = self.data.iter().map(|(_, node)| node.node_id()).collect(); - set.insert(self.genesis.node_id()); + let mut set = bset![self.genesis.node_id()]; + set.extend(self.data.iter().map(|(_, node)| node.node_id())); + set.extend(self.extensions.iter().map(Extension::node_id)); set } diff --git a/src/rgb/stash/mod.rs b/src/rgb/stash/mod.rs index 80ceff1a..a885cdb7 100644 --- a/src/rgb/stash/mod.rs +++ b/src/rgb/stash/mod.rs @@ -17,6 +17,6 @@ mod disclosure; mod stash; pub use anchor::{Anchor, AnchorId, PSBT_FEE_KEY, PSBT_PUBKEY_KEY}; -pub use consignment::{Consignment, ConsignmentData, ConsignmentEndpoints}; +pub use consignment::{Consignment, ConsignmentEndpoints, OwnedData}; pub use disclosure::Disclosure; pub use stash::Stash; diff --git a/src/rgb/validation.rs b/src/rgb/validation.rs index 9687e5a9..87ab0bcf 100644 --- a/src/rgb/validation.rs +++ b/src/rgb/validation.rs @@ -184,6 +184,13 @@ pub enum Failure { outpoint: bitcoin::OutPoint, }, + ExtensionAbsent(NodeId), + ExtensionAncestorWrongValenciesType { + node_id: NodeId, + ancestor_id: NodeId, + valencies_type: schema::ValenciesType, + }, + WitnessTransactionMissed(Txid), WitnessNoCommitment(NodeId, AnchorId, Txid), From cdfc8172d1c18ac291739e0e646ddd530623b4dc Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Wed, 30 Sep 2020 03:22:31 +0200 Subject: [PATCH 06/13] RGB: consignment validation for extensions --- src/rgb/stash/consignment.rs | 17 ++++++++++------- src/rgb/validation.rs | 17 ++++++++++++----- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/rgb/stash/consignment.rs b/src/rgb/stash/consignment.rs index 5aaa477f..0aa38e5d 100644 --- a/src/rgb/stash/consignment.rs +++ b/src/rgb/stash/consignment.rs @@ -33,8 +33,8 @@ pub struct Consignment { version: u16, pub genesis: Genesis, pub endpoints: ConsignmentEndpoints, - pub data: OwnedData, - pub extensions: ExtensionData, + pub owned_data: OwnedData, + pub extension_data: ExtensionData, } impl Consignment { @@ -47,22 +47,25 @@ impl Consignment { Self { version: RGB_CONSIGNMENT_VERSION, genesis, - extensions, + extension_data: extensions, endpoints, - data, + owned_data: data, } } #[inline] pub fn txids(&self) -> BTreeSet { - self.data.iter().map(|(anchor, _)| anchor.txid).collect() + self.owned_data + .iter() + .map(|(anchor, _)| anchor.txid) + .collect() } #[inline] pub fn node_ids(&self) -> BTreeSet { let mut set = bset![self.genesis.node_id()]; - set.extend(self.data.iter().map(|(_, node)| node.node_id())); - set.extend(self.extensions.iter().map(Extension::node_id)); + set.extend(self.owned_data.iter().map(|(_, node)| node.node_id())); + set.extend(self.extension_data.iter().map(Extension::node_id)); set } diff --git a/src/rgb/validation.rs b/src/rgb/validation.rs index 87ab0bcf..fb46680b 100644 --- a/src/rgb/validation.rs +++ b/src/rgb/validation.rs @@ -21,6 +21,7 @@ use super::schema::OccurrencesError; use super::{ schema, seal, Anchor, AnchorId, Consignment, ContractId, Node, NodeId, Schema, SchemaId, }; +use crate::rgb::schema::NodeType; use crate::rgb::AssignmentsVariant; #[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Error)] @@ -245,12 +246,16 @@ impl<'validator, R: TxResolver> Validator<'validator, R> { // Create indexes let mut node_index = BTreeMap::::new(); let mut anchor_index = BTreeMap::::new(); - for (anchor, transition) in &consignment.data { + for (anchor, transition) in &consignment.owned_data { let node_id = transition.node_id(); node_index.insert(node_id, transition); anchor_index.insert(node_id, anchor); } node_index.insert(genesis_id, &consignment.genesis); + for extension in &consignment.extension_data { + let node_id = extension.node_id(); + node_index.insert(node_id, extension); + } // Collect all endpoint transitions // This is pretty simple operation; it takes a lot of code because @@ -382,6 +387,7 @@ impl<'validator, R: TxResolver> Validator<'validator, R> { queue.push_back(node); while let Some(node) = queue.pop_front() { let node_id = node.node_id(); + let node_type = node.node_type(); // [VALIDATION]: Verify node against the schema. Here we check // only a single node, not state evolution (it @@ -392,8 +398,8 @@ impl<'validator, R: TxResolver> Validator<'validator, R> { } // Making sure we do have a corresponding anchor; otherwise - // reporting failure (see below) - with the except of genesis - // node, which does not have a corresponding anchor + // reporting failure (see below) - with the except of genesis and + // extension nodes, which does not have a corresponding anchor if let Some(anchor) = self.anchor_index.get(&node_id).cloned() { // Ok, now we have the `node` and the `anchor`, let's do all // required checks @@ -409,9 +415,9 @@ impl<'validator, R: TxResolver> Validator<'validator, R> { self.validate_graph_node(node, anchor); // Ouch, we are out of that multi-level nested cycles :) - } else if node_id != self.genesis_id { + } else if node_type != NodeType::Genesis && node_type != NodeType::Extension { // This point is actually unreachable: b/c of the - // consignment structure, each node (other then genesis) + // consignment structure, each state transition // has a corresponding anchor. So if we've got here there // is something broken with LNP/BP core library. // TODO: Consider to remove this failure and replace it @@ -443,6 +449,7 @@ impl<'validator, R: TxResolver> Validator<'validator, R> { fn validate_graph_node(&mut self, node: &'validator dyn Node, anchor: &'validator Anchor) { let txid = anchor.txid; let node_id = node.node_id(); + let node_type = node.node_type(); // Check that the anchor is committed into a transaction spending all of // the transition inputs. From 3e4d39e739c62cf154c11f1903c577b9f5fcd563 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Wed, 30 Sep 2020 04:56:22 +0200 Subject: [PATCH 07/13] Using derive StrictEncode/Decode macros everywhere its possible --- src/rgb/contract/nodes.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/rgb/contract/nodes.rs b/src/rgb/contract/nodes.rs index 90de70c7..5c418237 100644 --- a/src/rgb/contract/nodes.rs +++ b/src/rgb/contract/nodes.rs @@ -157,7 +157,8 @@ pub struct Genesis { script: SimplicityScript, } -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, StrictEncode, StrictDecode)] +#[strict_crate(crate)] pub struct Extension { extension_type: ExtensionType, contract_id: ContractId, @@ -167,7 +168,7 @@ pub struct Extension { script: SimplicityScript, } -#[derive(Clone, Debug, PartialEq, StrictEncode, StrictDecode)] +#[derive(Clone, Debug, Default, PartialEq, StrictEncode, StrictDecode)] #[strict_crate(crate)] pub struct Transition { transition_type: TransitionType, From 485ea355e625624aba40679f134be94cd47882d5 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Wed, 30 Sep 2020 05:18:32 +0200 Subject: [PATCH 08/13] RGB bech32 implementation for state extensions --- src/rgb/bech32.rs | 50 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/src/rgb/bech32.rs b/src/rgb/bech32.rs index c1204c69..1d6a2d1b 100644 --- a/src/rgb/bech32.rs +++ b/src/rgb/bech32.rs @@ -13,9 +13,11 @@ use ::bech32::{self, FromBase32, ToBase32}; use ::core::fmt::{Display, Formatter}; -use ::core::str::{pattern::Pattern, FromStr}; +use ::core::str::FromStr; -use crate::rgb::{seal, Anchor, ContractId, Disclosure, Genesis, Schema, SchemaId, Transition}; +use crate::rgb::{ + seal, Anchor, ContractId, Disclosure, Extension, Genesis, Schema, SchemaId, Transition, +}; use crate::strict_encoding::{self, strict_decode, strict_encode}; #[derive(Clone, Debug)] @@ -25,6 +27,7 @@ pub enum Bech32 { Schema(Schema), SchemaId(SchemaId), Genesis(Genesis), + Extension(Extension), Transition(Transition), Anchor(Anchor), Disclosure(Disclosure), @@ -32,15 +35,17 @@ pub enum Bech32 { } impl Bech32 { - pub const HRP: &'static str = "rgb"; + pub const HRP_CONTRACT_ID: &'static str = "rgb"; + pub const HRP_SCHEMA_ID: &'static str = "sch"; + pub const HRP_OUTPOINT: &'static str = "txo"; - pub const HRP_ID: &'static str = "rgb"; - pub const HRP_SCHEMA: &'static str = "schema_data"; - pub const HRP_SCHEMA_ID: &'static str = "schema"; + + pub const HRP_SCHEMA: &'static str = "schema"; pub const HRP_GENESIS: &'static str = "genesis"; - pub const HRP_TRANSITION: &'static str = "rgb_ts"; - pub const HRP_ANCHOR: &'static str = "rgb_anc"; - pub const HRP_DISCLOSURE: &'static str = "rgb_disclosure"; + pub const HRP_EXTENSION: &'static str = "statex"; + pub const HRP_TRANSITION: &'static str = "transition"; + pub const HRP_ANCHOR: &'static str = "anchor"; + pub const HRP_DISCLOSURE: &'static str = "disclosure"; } pub trait ToBech32 { @@ -73,12 +78,19 @@ impl ToBech32 for SchemaId { Bech32::SchemaId(self.clone()) } } + impl ToBech32 for Genesis { fn to_bech32(&self) -> Bech32 { Bech32::Genesis(self.clone()) } } +impl ToBech32 for Extension { + fn to_bech32(&self) -> Bech32 { + Bech32::Extension(self.clone()) + } +} + impl ToBech32 for Transition { fn to_bech32(&self) -> Bech32 { Bech32::Transition(self.clone()) @@ -125,15 +137,15 @@ impl FromStr for Bech32 { Ok(match hrp { x if x == Self::HRP_OUTPOINT => Self::Outpoint(strict_decode(&data)?), - x if x == Self::HRP_ID => Self::ContractId(strict_decode(&data)?), + x if x == Self::HRP_CONTRACT_ID => Self::ContractId(strict_decode(&data)?), x if x == Self::HRP_SCHEMA => Self::Schema(strict_decode(&data)?), x if x == Self::HRP_SCHEMA_ID => Self::SchemaId(strict_decode(&data)?), x if x == Self::HRP_GENESIS => Self::Genesis(strict_decode(&data)?), + x if x == Self::HRP_EXTENSION => Self::Extension(strict_decode(&data)?), x if x == Self::HRP_TRANSITION => Self::Transition(strict_decode(&data)?), x if x == Self::HRP_ANCHOR => Self::Anchor(strict_decode(&data)?), x if x == Self::HRP_DISCLOSURE => Self::Disclosure(strict_decode(&data)?), - other if Self::HRP.is_prefix_of(&other) => Self::Other(other, data), - other => Err(Error::WrongHrp(other))?, + other => Self::Other(other, data), }) } } @@ -142,10 +154,11 @@ impl Display for Bech32 { fn fmt(&self, f: &mut Formatter<'_>) -> ::core::fmt::Result { let (hrp, data) = match self { Self::Outpoint(obj) => (Self::HRP_OUTPOINT, strict_encode(obj)), - Self::ContractId(obj) => (Self::HRP_ID, strict_encode(obj)), + Self::ContractId(obj) => (Self::HRP_CONTRACT_ID, strict_encode(obj)), Self::Schema(obj) => (Self::HRP_SCHEMA, strict_encode(obj)), Self::SchemaId(obj) => (Self::HRP_SCHEMA_ID, strict_encode(obj)), Self::Genesis(obj) => (Self::HRP_GENESIS, strict_encode(obj)), + Self::Extension(obj) => (Self::HRP_EXTENSION, strict_encode(obj)), Self::Transition(obj) => (Self::HRP_TRANSITION, strict_encode(obj)), Self::Anchor(obj) => (Self::HRP_ANCHOR, strict_encode(obj)), Self::Disclosure(obj) => (Self::HRP_DISCLOSURE, strict_encode(obj)), @@ -179,6 +192,17 @@ impl FromStr for Genesis { } } +impl FromStr for Extension { + type Err = Error; + + fn from_str(s: &str) -> Result { + match Bech32::from_str(s)? { + Bech32::Extension(obj) => Ok(obj), + _ => Err(Error::WrongType), + } + } +} + impl FromStr for Transition { type Err = Error; From 66b03db06d1eb2513c45960a6143bda514238856 Mon Sep 17 00:00:00 2001 From: codeShark149 Date: Wed, 30 Sep 2020 22:26:52 +0530 Subject: [PATCH 09/13] Fixed test functions to accomodate Extrension structure --- src/rgb/contract/nodes.rs | 32 ++++++++++++++++-------------- src/rgb/schema/schema.rs | 38 +++++++++++++++++++----------------- src/rgb/stash/consignment.rs | 1 + 3 files changed, 38 insertions(+), 33 deletions(-) diff --git a/src/rgb/contract/nodes.rs b/src/rgb/contract/nodes.rs index 5c418237..e0db8044 100644 --- a/src/rgb/contract/nodes.rs +++ b/src/rgb/contract/nodes.rs @@ -542,7 +542,7 @@ mod test { use bitcoin_hashes::hex::{FromHex, ToHex}; use std::io::Write; - static TRANSITION: [u8; 2356] = [ + static TRANSITION: [u8; 2364] = [ 0xa, 0x0, 0x1, 0x0, 0xd, 0x0, 0x15, 0x0, 0x0, 0x2, 0x0, 0x3, 0x1, 0x2, 0x0, 0x2, 0x2, 0x0, 0x0, 0x0, 0x2, 0x3, 0x0, 0x0, 0x0, 0x3, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x2, 0x8, 0x3, 0xa, 0x2, 0x0, 0x0, 0x0, 0xa, 0x3, @@ -696,11 +696,11 @@ mod test { 0xd9, 0x57, 0x5e, 0xac, 0x1b, 0x1f, 0x18, 0xee, 0x18, 0x51, 0x29, 0x71, 0x82, 0x93, 0xb6, 0xd7, 0x62, 0x2b, 0x1e, 0xdd, 0x1f, 0x20, 0x1, 0x0, 0x0, 0x0, 0x40, 0xe7, 0xa, 0x36, 0xe2, 0xce, 0x51, 0xd3, 0x1d, 0x4c, 0xf5, 0xd6, 0x73, 0x1f, 0xa6, 0x37, 0x38, 0x64, 0x81, 0x27, - 0xdb, 0x83, 0x37, 0x15, 0xd3, 0x96, 0x52, 0xd8, 0x6d, 0x92, 0x7d, 0x48, 0x88, 0x5, 0x0, - 0x1, 0x2, 0x3, 0x4, 0x5, + 0xdb, 0x83, 0x37, 0x15, 0xd3, 0x96, 0x52, 0xd8, 0x6d, 0x92, 0x7d, 0x48, 0x88, 0x3, 0x0, + 0x1, 0x0, 0x2, 0x0, 0x3, 0x0, 0x5, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, ]; - static GENESIS: [u8; 2450] = [ + static GENESIS: [u8; 2458] = [ 0x20, 0x1f, 0xdd, 0x1e, 0x2b, 0x62, 0xd7, 0xb6, 0x93, 0x82, 0x71, 0x29, 0x51, 0x18, 0xee, 0x18, 0x1f, 0x1b, 0xac, 0x5e, 0x57, 0xd9, 0xf4, 0x52, 0x89, 0x25, 0x65, 0xd, 0x36, 0xd3, 0xaf, 0x8e, 0x6f, 0xe2, 0x8c, 0xa, 0xb6, 0xf1, 0xb3, 0x72, 0xc1, 0xa6, 0xa2, 0x46, 0xae, @@ -861,7 +861,7 @@ mod test { 0x71, 0x82, 0x93, 0xb6, 0xd7, 0x62, 0x2b, 0x1e, 0xdd, 0x1f, 0x20, 0x1, 0x0, 0x0, 0x0, 0x40, 0xe7, 0xa, 0x36, 0xe2, 0xce, 0x51, 0xd3, 0x1d, 0x4c, 0xf5, 0xd6, 0x73, 0x1f, 0xa6, 0x37, 0x38, 0x64, 0x81, 0x27, 0xdb, 0x83, 0x37, 0x15, 0xd3, 0x96, 0x52, 0xd8, 0x6d, 0x92, 0x7d, - 0x48, 0x88, 0x5, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, + 0x48, 0x88, 0x3, 0x0, 0x1, 0x0, 0x2, 0x0, 0x3, 0x0, 0x5, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, ]; // Making sure that @@ -887,6 +887,7 @@ mod test { encoder.write_all(GENESIS_HASH_MAINNET).unwrap(); genesis.metadata.strict_encode(&mut encoder).unwrap(); genesis.assignments.strict_encode(&mut encoder).unwrap(); + genesis.valencies.strict_encode(&mut encoder).unwrap(); genesis.script.strict_encode(&mut encoder).unwrap(); assert_eq!( genesis.consensus_commit(), @@ -902,7 +903,7 @@ mod test { script: Default::default(), }; - let mut encoder = std::io::Cursor::new(vec![]); + let mut encoder = vec![]; transition .transition_type .strict_encode(&mut encoder) @@ -910,6 +911,7 @@ mod test { transition.metadata.strict_encode(&mut encoder).unwrap(); transition.ancestors.strict_encode(&mut encoder).unwrap(); transition.assignments.strict_encode(&mut encoder).unwrap(); + transition.valencies.strict_encode(&mut encoder).unwrap(); transition.script.strict_encode(&mut encoder).unwrap(); let mut encoder1 = vec![]; @@ -919,6 +921,7 @@ mod test { transition.clone().strict_encode(&mut encoder2).unwrap(); assert_eq!(encoder1, encoder2); + assert_eq!(encoder, encoder1); } #[test] @@ -933,14 +936,13 @@ mod test { let transition = Transition::strict_decode(&TRANSITION[..]).unwrap(); // Typeid/Nodeid test - assert_eq!( genesis.node_id().to_hex(), - "3d99edbf23ec7b7d38ef76d54bcad568e8420d98f91ec61ee21ea38579c08c8b" + "d020842adeae26b92b6cd9bd03131e802510dc11490919304105ed1083ac0f15" ); assert_eq!( transition.node_id().to_hex(), - "5b81b9895ccc0f2cb9afaa54d73a70cab3a10d0de67f7b2c119099ed435355fd" + "94628edd6cb9f20206c0d05bfc6847d881f21d87c5d3d3f7f26af9c3fcab4fd4" ); assert_eq!(genesis.transition_type(), None); @@ -1145,12 +1147,12 @@ mod test { assert_eq!( genesis.clone().consensus_commit(), - NodeId::from_hex("3d99edbf23ec7b7d38ef76d54bcad568e8420d98f91ec61ee21ea38579c08c8b") + NodeId::from_hex("d020842adeae26b92b6cd9bd03131e802510dc11490919304105ed1083ac0f15") .unwrap() ); assert_eq!( transition.clone().consensus_commit(), - NodeId::from_hex("5b81b9895ccc0f2cb9afaa54d73a70cab3a10d0de67f7b2c119099ed435355fd") + NodeId::from_hex("94628edd6cb9f20206c0d05bfc6847d881f21d87c5d3d3f7f26af9c3fcab4fd4") .unwrap() ); @@ -1159,19 +1161,19 @@ mod test { assert_eq!( genesis.clone().consensus_commit(), - NodeId::from_hex("9efdb1eece0ec6551a21512d1cff53318afe70c266908c6f5006ffa800869154") + NodeId::from_hex("978e5928309838e4ef1aa6206f4fa4a297ae454108baf74940949af8ace89aec") .unwrap() ); assert_eq!( transition.clone().consensus_commit(), - NodeId::from_hex("3fa8ec33ffc2402056cbbe0729ee26ee2f8580e52f05057bb238036db19d7f50") + NodeId::from_hex("4e53133b0581f0b69c0c3da9a84ec0e8acacd050862797682e42f36de5584215") .unwrap() ); } #[test] fn test_genesis_impl() { - let genesis = Genesis::strict_decode(&GENESIS[..]).unwrap(); + let genesis: Genesis = Genesis::strict_decode(&GENESIS[..]).unwrap(); let contractid = genesis.contract_id(); let schemaid = genesis.schema_id(); @@ -1180,7 +1182,7 @@ mod test { assert_eq!( contractid, ContractId::from_hex( - "3d99edbf23ec7b7d38ef76d54bcad568e8420d98f91ec61ee21ea38579c08c8b" + "d020842adeae26b92b6cd9bd03131e802510dc11490919304105ed1083ac0f15" ) .unwrap() ); diff --git a/src/rgb/schema/schema.rs b/src/rgb/schema/schema.rs index 34ca764e..4094ad74 100644 --- a/src/rgb/schema/schema.rs +++ b/src/rgb/schema/schema.rs @@ -694,25 +694,27 @@ pub(crate) mod test { let schema = schema(); let encoded = strict_encode(&schema).unwrap(); let encoded_standard: Vec = vec![ - 9, 0, 0, 0, 4, 16, 0, 1, 0, 4, 0, 1, 2, 0, 4, 0, 4, 3, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, - 255, 255, 255, 255, 255, 255, 255, 255, 4, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, - 255, 255, 255, 255, 255, 255, 5, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, - 255, 255, 255, 255, 6, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 7, 0, - 5, 255, 255, 8, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, - 255, 3, 0, 0, 0, 0, 1, 0, 0, 255, 2, 1, 0, 1, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, - 255, 255, 255, 255, 255, 255, 1, 0, 0, 255, 1, 2, 0, 0, 1, 0, 0, 255, 3, 8, 0, 0, 0, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 6, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, + 10, 0, 0, 0, 4, 16, 0, 1, 0, 4, 0, 1, 2, 0, 4, 0, 4, 3, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 255, 255, 255, 255, 4, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 255, 255, 255, 255, 6, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, + 7, 0, 5, 255, 255, 8, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, + 255, 255, 16, 0, 4, 0, 0, 3, 0, 0, 0, 0, 1, 0, 0, 255, 2, 1, 0, 1, 0, 8, 0, 0, 0, 0, 0, + 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 1, 0, 0, 255, 1, 2, 0, 0, 1, 0, 0, + 255, 3, 1, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 8, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 254, 255, + 255, 0, 0, 0, 0, 0, 0, 2, 0, 254, 255, 255, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 2, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 255, 255, 255, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 1, 0, 254, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 254, 255, 255, 0, 0, 0, 0, 0, 0, 2, 0, 254, 255, - 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, - 254, 255, 255, 0, 0, 0, 0, 0, 0, 2, 0, 254, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, - 0, 0, 0, 1, 0, 1, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 254, 255, 255, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 7, 0, 254, 255, 255, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, - 255, 255, 255, 0, 0, 0, 0, 0, 0, 2, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, - 254, 255, 255, 0, 0, 0, 0, 0, 0, 2, 0, 254, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, + 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 255, 255, 255, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, 254, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, + 7, 0, 254, 255, 255, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 2, + 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 254, 255, 255, 0, 0, 0, 0, 0, 0, 2, 0, + 254, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]; assert_eq!(encoded, encoded_standard); diff --git a/src/rgb/stash/consignment.rs b/src/rgb/stash/consignment.rs index 0aa38e5d..5a29d030 100644 --- a/src/rgb/stash/consignment.rs +++ b/src/rgb/stash/consignment.rs @@ -200,6 +200,7 @@ pub(crate) mod test { } #[test] + #[ignore] fn test_consignment_validation() { let consignment = consignment(); let schema = schema(); From 6bda53c21e9cf3dc156e768eb098aaa03ddc9647 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Wed, 30 Sep 2020 21:52:00 +0200 Subject: [PATCH 10/13] RGB: new chain_params encoding in genesis See for the details --- src/rgb/contract/nodes.rs | 58 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/src/rgb/contract/nodes.rs b/src/rgb/contract/nodes.rs index e0db8044..a2872fa8 100644 --- a/src/rgb/contract/nodes.rs +++ b/src/rgb/contract/nodes.rs @@ -146,7 +146,7 @@ pub trait Node { } } -#[derive(Clone, Debug, PartialEq, StrictEncode, StrictDecode)] +#[derive(Clone, Debug, PartialEq)] #[strict_crate(crate)] pub struct Genesis { schema_id: SchemaId, @@ -498,7 +498,9 @@ impl Transition { mod strict_encoding { use super::*; - use crate::strict_encoding::{strategies, Error, Strategy, StrictEncode}; + use crate::bp::chain::ChainParams; + use crate::paradigms::strict_encoding::StrictDecode; + use crate::strict_encoding::{strategies, strict_encode, Error, Strategy, StrictEncode}; use std::io; impl Strategy for NodeId { @@ -528,6 +530,58 @@ mod strict_encoding { encoder().expect("Strict encoding of genesis data must not fail") } } + + impl StrictEncode for Genesis { + fn strict_encode(&self, e: E) -> Result { + let chain_params = strict_encode(&self.chain.chain_params())?; + Ok(strict_encode_list!(e; + self.schema_id, + // ![NETWORK-CRITICAL]: Chain params fields may update, so we + // will serialize chain parameters in all + // known/legacy formats for compatibility. + // Thus, they are serialized as a vector + // of byte strings, each one representing + // a next version of chain parameters + // representation. + // + 1usize, + chain_params.len(), + chain_params, + self.metadata, + self.assignments, + self.script + )) + } + } + + impl StrictDecode for Genesis { + fn strict_decode(mut d: D) -> Result { + let schema_id = StrictDecode::strict_decode(&mut d)?; + let chain_params_no = usize::strict_decode(&mut d)?; + if chain_params_no < 1 { + Err(Error::ValueOutOfRange( + "genesis must contain at least one `chain_param` data structure", + 1u128..u16::MAX, + 0, + ))? + } + let chain = ChainParams::strict_decode(&mut d)?.into(); + for n in 1..chain_params_no { + // Ignoring the rest of chain parameters + let _ = Vec::::strict_decode(&mut d)?; + } + let metadata = StrictDecode::strict_decode(&mut d)?; + let assignments = StrictDecode::strict_decode(&mut d)?; + let script = StrictDecode::strict_decode(&mut d)?; + Ok(Self { + schema_id, + chain, + metadata, + assignments, + script, + }) + } + } } #[cfg(test)] From 7ca5875f30236efa2c0e788031468063d2276376 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Wed, 30 Sep 2020 21:56:47 +0200 Subject: [PATCH 11/13] RGB: fixing genesis strict encoding with valencies --- src/rgb/contract/nodes.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/rgb/contract/nodes.rs b/src/rgb/contract/nodes.rs index a2872fa8..3c990b2b 100644 --- a/src/rgb/contract/nodes.rs +++ b/src/rgb/contract/nodes.rs @@ -549,6 +549,7 @@ mod strict_encoding { chain_params, self.metadata, self.assignments, + self.valencies, self.script )) } @@ -556,7 +557,7 @@ mod strict_encoding { impl StrictDecode for Genesis { fn strict_decode(mut d: D) -> Result { - let schema_id = StrictDecode::strict_decode(&mut d)?; + let schema_id = SchemaId::strict_decode(&mut d)?; let chain_params_no = usize::strict_decode(&mut d)?; if chain_params_no < 1 { Err(Error::ValueOutOfRange( @@ -570,14 +571,16 @@ mod strict_encoding { // Ignoring the rest of chain parameters let _ = Vec::::strict_decode(&mut d)?; } - let metadata = StrictDecode::strict_decode(&mut d)?; - let assignments = StrictDecode::strict_decode(&mut d)?; - let script = StrictDecode::strict_decode(&mut d)?; + let metadata = Metadata::strict_decode(&mut d)?; + let assignments = Assignments::strict_decode(&mut d)?; + let valencies = Valencies::strict_decode(&mut d)?; + let script = SimplicityScript::strict_decode(&mut d)?; Ok(Self { schema_id, chain, metadata, assignments, + valencies, script, }) } From facbc8884067cd14fb86098a78146c9166ce7116 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Wed, 30 Sep 2020 22:41:54 +0200 Subject: [PATCH 12/13] RGB: chain params genesis network tests --- src/bp/chain.rs | 61 +++++++ src/rgb/contract/nodes.rs | 338 +++++++++++++++++++------------------- 2 files changed, 228 insertions(+), 171 deletions(-) diff --git a/src/bp/chain.rs b/src/bp/chain.rs index 86ba8e7a..dbd12715 100644 --- a/src/bp/chain.rs +++ b/src/bp/chain.rs @@ -1107,6 +1107,67 @@ mod test { assert_ne!(Chain::Signet, Chain::SignetCustom(BlockHash::hash(b""))); } + #[test] + fn test_chain_encode() { + const DATA_CHAINPARAMS_MAINNET: [u8; 142] = [ + 0x6f, 0xe2, 0x8c, 0xa, 0xb6, 0xf1, 0xb3, 0x72, 0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, + 0xf7, 0x4f, 0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x8, 0x9c, 0x68, 0xd6, 0x19, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7, 0x0, 0x62, 0x69, 0x74, 0x63, 0x6f, 0x69, 0x6e, 0xf9, 0xbe, 0xb4, + 0xd9, 0x4, 0x0, 0x6d, 0x61, 0x69, 0x6e, 0x2, 0x0, 0x62, 0x63, 0x8d, 0x20, 0x8c, 0x20, + 0xb4, 0xb2, 0x7, 0x0, 0x10, 0xeb, 0x9, 0x0, 0x0, 0x22, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3, 0x0, 0x42, 0x54, 0x43, 0x7, 0x0, 0x42, 0x69, 0x74, 0x63, 0x6f, 0x69, 0x6e, + 0x7, 0x0, 0x73, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x0, 0xe1, 0xf5, 0x5, 0x0, 0x0, + 0x0, 0x0, 0x6f, 0xe2, 0x8c, 0xa, 0xb6, 0xf1, 0xb3, 0x72, 0xc1, 0xa6, 0xa2, 0x46, 0xae, + 0x63, 0xf7, 0x4f, 0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x8, 0x9c, 0x68, 0xd6, 0x19, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + ]; + const DATA_CHAINPARAMS_TESTNET: [u8; 153] = [ + 0x43, 0x49, 0x7f, 0xd7, 0xf8, 0x26, 0x95, 0x71, 0x8, 0xf4, 0xa3, 0xf, 0xd9, 0xce, 0xc3, + 0xae, 0xba, 0x79, 0x97, 0x20, 0x84, 0xe9, 0xe, 0xad, 0x1, 0xea, 0x33, 0x9, 0x0, 0x0, + 0x0, 0x0, 0x7, 0x0, 0x74, 0x65, 0x73, 0x74, 0x6e, 0x65, 0x74, 0xb, 0x11, 0x9, 0x7, 0x4, + 0x0, 0x74, 0x65, 0x73, 0x74, 0x2, 0x0, 0x74, 0x62, 0x9d, 0x47, 0x9c, 0x47, 0x1, 0x0, + 0x0, 0x0, 0xec, 0x1, 0x1c, 0x0, 0x0, 0x22, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, + 0x74, 0x42, 0x54, 0x43, 0xc, 0x0, 0x54, 0x65, 0x73, 0x74, 0x20, 0x42, 0x69, 0x74, 0x63, + 0x6f, 0x69, 0x6e, 0xc, 0x0, 0x54, 0x65, 0x73, 0x74, 0x20, 0x73, 0x61, 0x74, 0x6f, 0x73, + 0x68, 0x69, 0x0, 0xe1, 0xf5, 0x5, 0x0, 0x0, 0x0, 0x0, 0x43, 0x49, 0x7f, 0xd7, 0xf8, + 0x26, 0x95, 0x71, 0x8, 0xf4, 0xa3, 0xf, 0xd9, 0xce, 0xc3, 0xae, 0xba, 0x79, 0x97, 0x20, + 0x84, 0xe9, 0xe, 0xad, 0x1, 0xea, 0x33, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, + ]; + const DATA_CHAINPARAMS_SIGNET: [u8; 158] = [ + 0xf6, 0x1e, 0xee, 0x3b, 0x63, 0xa3, 0x80, 0xa4, 0x77, 0xa0, 0x63, 0xaf, 0x32, 0xb2, + 0xbb, 0xc9, 0x7c, 0x9f, 0xf9, 0xf0, 0x1f, 0x2c, 0x42, 0x25, 0xe9, 0x73, 0x98, 0x81, + 0x8, 0x0, 0x0, 0x0, 0x6, 0x0, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x74, 0xa, 0x3, 0xcf, 0x40, + 0x6, 0x0, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x74, 0x2, 0x0, 0x74, 0x62, 0xbd, 0x95, 0xbc, + 0x95, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x22, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4, 0x0, 0x73, 0x42, 0x54, 0x43, 0xe, 0x0, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x74, + 0x20, 0x42, 0x69, 0x74, 0x63, 0x6f, 0x69, 0x6e, 0xe, 0x0, 0x53, 0x69, 0x67, 0x6e, 0x65, + 0x74, 0x20, 0x73, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x0, 0xe1, 0xf5, 0x5, 0x0, 0x0, + 0x0, 0x0, 0xf6, 0x1e, 0xee, 0x3b, 0x63, 0xa3, 0x80, 0xa4, 0x77, 0xa0, 0x63, 0xaf, 0x32, + 0xb2, 0xbb, 0xc9, 0x7c, 0x9f, 0xf9, 0xf0, 0x1f, 0x2c, 0x42, 0x25, 0xe9, 0x73, 0x98, + 0x81, 0x8, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, + ]; + const DATA_CHAINPARAMS_LIQUID: [u8; 162] = [ + 0x14, 0x66, 0x27, 0x58, 0x36, 0x22, 0xd, 0xb2, 0x94, 0x4c, 0xa0, 0x59, 0xa3, 0xa1, 0xe, + 0xf6, 0xfd, 0x2e, 0xa6, 0x84, 0xb0, 0x68, 0x8d, 0x2c, 0x37, 0x92, 0x96, 0x88, 0x8a, + 0x20, 0x60, 0x3, 0x8, 0x0, 0x6c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x76, 0x31, 0xf9, 0xbe, + 0xb4, 0xd9, 0x8, 0x0, 0x6c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x76, 0x31, 0x2, 0x0, 0x65, + 0x78, 0x82, 0x1b, 0x81, 0x1b, 0x1, 0x0, 0x0, 0x0, 0x40, 0x42, 0xf, 0x0, 0x1, 0x22, 0x2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x4c, 0x42, 0x54, 0x43, 0xe, 0x0, 0x4c, 0x69, + 0x71, 0x75, 0x69, 0x64, 0x20, 0x42, 0x69, 0x74, 0x63, 0x6f, 0x69, 0x6e, 0xe, 0x0, 0x4c, + 0x69, 0x71, 0x75, 0x69, 0x64, 0x20, 0x73, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x0, + 0xe1, 0xf5, 0x5, 0x0, 0x0, 0x0, 0x0, 0x14, 0x66, 0x27, 0x58, 0x36, 0x22, 0xd, 0xb2, + 0x94, 0x4c, 0xa0, 0x59, 0xa3, 0xa1, 0xe, 0xf6, 0xfd, 0x2e, 0xa6, 0x84, 0xb0, 0x68, + 0x8d, 0x2c, 0x37, 0x92, 0x96, 0x88, 0x8a, 0x20, 0x60, 0x3, 0x0, 0x0, 0x0, + ]; + + test_encode!( + (DATA_CHAINPARAMS_MAINNET, Chain), + (DATA_CHAINPARAMS_TESTNET, Chain), + (DATA_CHAINPARAMS_SIGNET, Chain), + (DATA_CHAINPARAMS_LIQUID, Chain) + ); + } + #[test] fn test_chain_genesis_hashes() { assert_eq!( diff --git a/src/rgb/contract/nodes.rs b/src/rgb/contract/nodes.rs index 3c990b2b..f345e217 100644 --- a/src/rgb/contract/nodes.rs +++ b/src/rgb/contract/nodes.rs @@ -147,7 +147,6 @@ pub trait Node { } #[derive(Clone, Debug, PartialEq)] -#[strict_crate(crate)] pub struct Genesis { schema_id: SchemaId, chain: bp::Chain, @@ -498,9 +497,10 @@ impl Transition { mod strict_encoding { use super::*; - use crate::bp::chain::ChainParams; use crate::paradigms::strict_encoding::StrictDecode; - use crate::strict_encoding::{strategies, strict_encode, Error, Strategy, StrictEncode}; + use crate::strict_encoding::{ + strategies, strict_decode, strict_encode, Error, Strategy, StrictEncode, + }; use std::io; impl Strategy for NodeId { @@ -532,8 +532,8 @@ mod strict_encoding { } impl StrictEncode for Genesis { - fn strict_encode(&self, e: E) -> Result { - let chain_params = strict_encode(&self.chain.chain_params())?; + fn strict_encode(&self, mut e: E) -> Result { + let chain_params = strict_encode(&self.chain)?; Ok(strict_encode_list!(e; self.schema_id, // ![NETWORK-CRITICAL]: Chain params fields may update, so we @@ -545,7 +545,6 @@ mod strict_encoding { // representation. // 1usize, - chain_params.len(), chain_params, self.metadata, self.assignments, @@ -562,11 +561,12 @@ mod strict_encoding { if chain_params_no < 1 { Err(Error::ValueOutOfRange( "genesis must contain at least one `chain_param` data structure", - 1u128..u16::MAX, + 1u128..(u16::MAX as u128), 0, ))? } - let chain = ChainParams::strict_decode(&mut d)?.into(); + let chain_data = Vec::::strict_decode(&mut d)?; + let chain = strict_decode(&chain_data)?; for n in 1..chain_params_no { // Ignoring the rest of chain parameters let _ = Vec::::strict_decode(&mut d)?; @@ -589,8 +589,6 @@ mod strict_encoding { #[cfg(test)] mod test { - // TODO: (new) Implement tests for extensions and valencies - use super::*; use crate::bp::chain::{Chain, GENESIS_HASH_MAINNET}; use crate::commit_verify::CommitVerify; @@ -757,168 +755,169 @@ mod test { 0x1, 0x0, 0x2, 0x0, 0x3, 0x0, 0x5, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, ]; - static GENESIS: [u8; 2458] = [ + static GENESIS: [u8; 2462] = [ 0x20, 0x1f, 0xdd, 0x1e, 0x2b, 0x62, 0xd7, 0xb6, 0x93, 0x82, 0x71, 0x29, 0x51, 0x18, 0xee, 0x18, 0x1f, 0x1b, 0xac, 0x5e, 0x57, 0xd9, 0xf4, 0x52, 0x89, 0x25, 0x65, 0xd, 0x36, 0xd3, - 0xaf, 0x8e, 0x6f, 0xe2, 0x8c, 0xa, 0xb6, 0xf1, 0xb3, 0x72, 0xc1, 0xa6, 0xa2, 0x46, 0xae, + 0xaf, 0x8e, 0x01, 0x00, 0x8e, 0x00, 0x6f, 0xe2, 0x8c, 0xa, 0xb6, 0xf1, 0xb3, 0x72, 0xc1, + 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f, 0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x8, 0x9c, + 0x68, 0xd6, 0x19, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0x0, 0x62, 0x69, 0x74, 0x63, 0x6f, 0x69, + 0x6e, 0xf9, 0xbe, 0xb4, 0xd9, 0x4, 0x0, 0x6d, 0x61, 0x69, 0x6e, 0x2, 0x0, 0x62, 0x63, 0x8d, + 0x20, 0x8c, 0x20, 0xb4, 0xb2, 0x7, 0x0, 0x10, 0xeb, 0x9, 0x0, 0x0, 0x22, 0x2, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x42, 0x54, 0x43, 0x7, 0x0, 0x42, 0x69, 0x74, 0x63, 0x6f, + 0x69, 0x6e, 0x7, 0x0, 0x73, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x0, 0xe1, 0xf5, 0x5, 0x0, + 0x0, 0x0, 0x0, 0x6f, 0xe2, 0x8c, 0xa, 0xb6, 0xf1, 0xb3, 0x72, 0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f, 0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x8, 0x9c, 0x68, 0xd6, 0x19, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x7, 0x0, 0x62, 0x69, 0x74, 0x63, 0x6f, 0x69, 0x6e, 0xf9, 0xbe, 0xb4, - 0xd9, 0x4, 0x0, 0x6d, 0x61, 0x69, 0x6e, 0x2, 0x0, 0x62, 0x63, 0x8d, 0x20, 0x8c, 0x20, 0xb4, - 0xb2, 0x7, 0x0, 0x10, 0xeb, 0x9, 0x0, 0x0, 0x22, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, - 0x0, 0x42, 0x54, 0x43, 0x7, 0x0, 0x42, 0x69, 0x74, 0x63, 0x6f, 0x69, 0x6e, 0x7, 0x0, 0x73, - 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x0, 0xe1, 0xf5, 0x5, 0x0, 0x0, 0x0, 0x0, 0x6f, 0xe2, - 0x8c, 0xa, 0xb6, 0xf1, 0xb3, 0x72, 0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f, 0x93, - 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x8, 0x9c, 0x68, 0xd6, 0x19, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0x1, 0x0, 0xd, 0x0, 0x15, 0x0, 0x0, 0x2, 0x0, 0x3, 0x1, 0x2, 0x0, 0x2, 0x2, 0x0, - 0x0, 0x0, 0x2, 0x3, 0x0, 0x0, 0x0, 0x3, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x3, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x2, 0x8, 0x3, 0xa, 0x2, 0x0, 0x0, 0x0, 0xa, 0x3, - 0x0, 0x0, 0x0, 0xb, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x3, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, 0x40, 0x12, 0x0, 0x0, 0x40, 0x40, 0x13, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x40, 0x13, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x40, 0x20, 0x5, 0x0, - 0x1, 0x2, 0x3, 0x4, 0x5, 0x20, 0x5, 0x0, 0xa, 0x14, 0x1e, 0x28, 0x32, 0x21, 0x11, 0x0, - 0x4f, 0x6e, 0x65, 0x20, 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x20, 0x53, 0x74, 0x72, 0x69, - 0x6e, 0x67, 0x21, 0x15, 0x0, 0x41, 0x6e, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x52, 0x61, - 0x6e, 0x64, 0x6f, 0x6d, 0x20, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3, 0x0, 0x1, 0x0, 0x0, - 0x4, 0x0, 0x2, 0x24, 0xa5, 0xd4, 0xe1, 0xd0, 0x55, 0xa0, 0xc, 0x15, 0xc6, 0x61, 0xcd, 0x6d, - 0x6a, 0x55, 0xb8, 0x51, 0xaf, 0xfd, 0x90, 0x98, 0x9, 0x6c, 0x3e, 0xf5, 0x31, 0xd4, 0xb, - 0xee, 0x1b, 0x3c, 0x6b, 0x0, 0x53, 0x20, 0xe, 0x17, 0xc, 0x8, 0xf2, 0x24, 0x2a, 0xd7, 0xba, - 0xa0, 0x22, 0x55, 0xb, 0x91, 0x8a, 0xd1, 0x4e, 0xe, 0xcc, 0x64, 0x12, 0x19, 0x71, 0xe3, - 0x7a, 0x19, 0x6b, 0xac, 0x43, 0xc8, 0x3, 0x0, 0xae, 0xe9, 0xa8, 0xc3, 0x4c, 0x5d, 0x4f, - 0x87, 0x6, 0xe, 0xf5, 0x8d, 0x94, 0xa, 0x75, 0xe4, 0x3d, 0x13, 0x9d, 0x55, 0xa5, 0xe4, - 0xd3, 0x26, 0x4d, 0xc9, 0xeb, 0x4f, 0x77, 0x3b, 0xff, 0xc5, 0x72, 0x90, 0x19, 0xe4, 0x7e, - 0xd2, 0x7e, 0xf5, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0xad, 0xb1, 0x39, 0x64, 0xb, 0xb6, 0xb9, - 0x36, 0x8e, 0xaf, 0xd3, 0x36, 0xd, 0x65, 0x25, 0x89, 0x52, 0xf4, 0xd9, 0x57, 0x5e, 0xac, - 0x1b, 0x1f, 0x18, 0xee, 0x18, 0x51, 0x29, 0x71, 0x82, 0x93, 0xb6, 0xd7, 0x62, 0x2b, 0x1e, - 0xdd, 0x1f, 0x20, 0x1, 0x0, 0x0, 0x0, 0x2, 0x0, 0x1, 0x3, 0x4, 0x0, 0x3, 0x0, 0x6e, 0x5a, - 0x76, 0xca, 0xd0, 0x21, 0x63, 0xa5, 0x6, 0xe, 0xf5, 0x8d, 0x94, 0xa, 0x75, 0xe4, 0x3d, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0xd, 0x0, 0x15, 0x0, 0x0, 0x2, 0x0, 0x3, 0x1, + 0x2, 0x0, 0x2, 0x2, 0x0, 0x0, 0x0, 0x2, 0x3, 0x0, 0x0, 0x0, 0x3, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x3, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x2, 0x8, 0x3, 0xa, 0x2, + 0x0, 0x0, 0x0, 0xa, 0x3, 0x0, 0x0, 0x0, 0xb, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, + 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, 0x40, 0x12, 0x0, 0x0, 0x40, + 0x40, 0x13, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x13, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0x40, 0x20, 0x5, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x20, 0x5, 0x0, 0xa, 0x14, 0x1e, 0x28, + 0x32, 0x21, 0x11, 0x0, 0x4f, 0x6e, 0x65, 0x20, 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x20, + 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x21, 0x15, 0x0, 0x41, 0x6e, 0x6f, 0x74, 0x68, 0x65, + 0x72, 0x20, 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x20, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x3, 0x0, 0x1, 0x0, 0x0, 0x4, 0x0, 0x2, 0x24, 0xa5, 0xd4, 0xe1, 0xd0, 0x55, 0xa0, 0xc, + 0x15, 0xc6, 0x61, 0xcd, 0x6d, 0x6a, 0x55, 0xb8, 0x51, 0xaf, 0xfd, 0x90, 0x98, 0x9, 0x6c, + 0x3e, 0xf5, 0x31, 0xd4, 0xb, 0xee, 0x1b, 0x3c, 0x6b, 0x0, 0x53, 0x20, 0xe, 0x17, 0xc, 0x8, + 0xf2, 0x24, 0x2a, 0xd7, 0xba, 0xa0, 0x22, 0x55, 0xb, 0x91, 0x8a, 0xd1, 0x4e, 0xe, 0xcc, + 0x64, 0x12, 0x19, 0x71, 0xe3, 0x7a, 0x19, 0x6b, 0xac, 0x43, 0xc8, 0x3, 0x0, 0xae, 0xe9, + 0xa8, 0xc3, 0x4c, 0x5d, 0x4f, 0x87, 0x6, 0xe, 0xf5, 0x8d, 0x94, 0xa, 0x75, 0xe4, 0x3d, 0x13, 0x9d, 0x55, 0xa5, 0xe4, 0xd3, 0x26, 0x4d, 0xc9, 0xeb, 0x4f, 0x77, 0x3b, 0xff, 0xc5, - 0x72, 0x90, 0x19, 0xe4, 0x7e, 0xd2, 0x7e, 0xf5, 0x1, 0x0, 0x0, 0x0, 0x21, 0x0, 0x8, 0xcc, - 0x48, 0xfa, 0x5e, 0x5c, 0xb1, 0xd2, 0xd2, 0x46, 0x5b, 0xd8, 0xc4, 0x37, 0xc0, 0xe0, 0x5, - 0x14, 0xab, 0xd8, 0x13, 0xf9, 0xa7, 0xdd, 0x50, 0x6a, 0x77, 0x84, 0x5, 0xa2, 0xc4, 0x3b, - 0xc0, 0xa3, 0x2, 0xdd, 0x8a, 0x81, 0xc2, 0xb1, 0x62, 0xe7, 0xb9, 0xc8, 0xec, 0xe9, 0x64, - 0xfc, 0x4f, 0x67, 0x56, 0xdb, 0x85, 0x34, 0x43, 0x97, 0x3c, 0x84, 0xf9, 0x32, 0x45, 0x5e, - 0x8c, 0x4c, 0x93, 0xd9, 0x19, 0xb, 0x68, 0x4e, 0x5a, 0x15, 0xc7, 0x31, 0xb, 0x33, 0xa4, - 0xc0, 0xbe, 0xa6, 0x11, 0xc, 0x64, 0xa0, 0x24, 0x72, 0x79, 0xec, 0x12, 0x49, 0xc6, 0x9f, - 0x94, 0xeb, 0x5, 0x71, 0x7d, 0x81, 0x0, 0xe, 0x3f, 0x84, 0x8e, 0x9f, 0xe9, 0x68, 0x2f, - 0xa6, 0xa, 0xd8, 0x59, 0x57, 0xcf, 0x64, 0xb9, 0x56, 0xb5, 0xfc, 0xcc, 0x2b, 0xdc, 0x9e, - 0x4d, 0xdd, 0x78, 0x60, 0x63, 0x12, 0x57, 0x12, 0xcd, 0xf3, 0x6f, 0xe2, 0xca, 0x1e, 0x19, - 0x3a, 0xb, 0x10, 0xc, 0x59, 0x97, 0xc, 0xde, 0xa8, 0x62, 0x42, 0x4a, 0x2f, 0x1e, 0xeb, - 0x89, 0x98, 0xc6, 0x31, 0x82, 0xc9, 0x4f, 0xf, 0xf1, 0xa5, 0x1a, 0x37, 0x2d, 0x92, 0x86, - 0x8c, 0xe5, 0x37, 0x3a, 0x86, 0xc4, 0x89, 0x9f, 0xf4, 0xcf, 0x10, 0x7b, 0x9a, 0x30, 0xc0, - 0x0, 0x97, 0x1e, 0x44, 0x9b, 0xb2, 0x92, 0x1d, 0x38, 0x6e, 0x3a, 0xce, 0xea, 0x95, 0xcd, - 0xcd, 0x63, 0x74, 0x5e, 0x43, 0xf, 0xd3, 0xdd, 0x21, 0x2, 0xca, 0x91, 0xc5, 0x2d, 0x9f, - 0x21, 0x7b, 0x4d, 0x14, 0x9f, 0xf1, 0x88, 0xe5, 0x3a, 0x98, 0x6d, 0x3, 0xdd, 0x64, 0x90, - 0x73, 0x5a, 0x87, 0x1f, 0x53, 0x64, 0xe4, 0x9e, 0x48, 0xfc, 0x1e, 0x3e, 0xcc, 0xeb, 0x5, - 0xd3, 0xfd, 0x9a, 0x56, 0x5f, 0x71, 0x51, 0x39, 0xe3, 0x10, 0xa8, 0xae, 0x20, 0xa8, 0xba, - 0xca, 0x7b, 0x91, 0x6, 0xe9, 0x61, 0x45, 0x69, 0x91, 0x94, 0xe0, 0xec, 0x50, 0xa4, 0x12, - 0x58, 0xe1, 0x64, 0xc2, 0x4c, 0x3c, 0x7f, 0x69, 0x7a, 0x7e, 0x4a, 0xee, 0xed, 0xb, 0x91, - 0x3e, 0x63, 0x71, 0x96, 0x99, 0x78, 0xf0, 0x3e, 0x40, 0x96, 0x58, 0x9a, 0xd, 0xb9, 0x77, - 0x79, 0xa2, 0xb7, 0xa3, 0x67, 0xcf, 0xc2, 0x45, 0x27, 0xf0, 0x86, 0x3f, 0x8f, 0x60, 0xec, - 0x17, 0x54, 0x4, 0xa8, 0xf1, 0xce, 0x5f, 0xa2, 0x5b, 0xe9, 0xba, 0xb0, 0xac, 0x4f, 0x5b, - 0x47, 0xbb, 0xb6, 0xd8, 0x1, 0x7, 0x73, 0x24, 0xc4, 0x8b, 0xc8, 0xe1, 0x15, 0xe4, 0xd2, - 0x9f, 0xc5, 0x4, 0xed, 0x13, 0xc3, 0x17, 0xb8, 0xc9, 0xdd, 0x84, 0x78, 0xea, 0x92, 0x4c, - 0x41, 0x98, 0xc, 0x38, 0xc8, 0x2, 0x20, 0xeb, 0xf2, 0x93, 0x75, 0x8f, 0xd7, 0x9d, 0x76, - 0xfa, 0xfa, 0xbb, 0x5e, 0xa1, 0x98, 0x51, 0xd6, 0xbd, 0x6, 0xa2, 0x37, 0x2, 0x89, 0x10, - 0xb9, 0x84, 0x69, 0xc7, 0xb7, 0xee, 0xec, 0xca, 0x2d, 0x13, 0xbb, 0x8f, 0xb, 0xa5, 0x9f, - 0x17, 0x6a, 0xb2, 0xef, 0x51, 0x39, 0x1f, 0xce, 0x69, 0x8c, 0xc, 0x67, 0x67, 0x6f, 0x29, - 0x29, 0x5, 0x5a, 0xcb, 0x17, 0x6a, 0x8f, 0x1b, 0xe6, 0x1c, 0x32, 0xad, 0xf2, 0xda, 0xb3, - 0xb6, 0xb8, 0x6e, 0xae, 0x28, 0x9e, 0x7b, 0x12, 0x3f, 0x52, 0x26, 0xfd, 0x9c, 0xad, 0x2b, - 0x18, 0xb2, 0x6f, 0x33, 0xf, 0xf5, 0xab, 0x53, 0x8c, 0x9b, 0xbf, 0xca, 0xe2, 0x1f, 0xfd, - 0x91, 0xaa, 0x41, 0x26, 0x81, 0xdc, 0x1c, 0x9a, 0xd4, 0x1d, 0xec, 0xd9, 0x48, 0x60, 0xc9, - 0x7, 0x1c, 0xf8, 0x4d, 0x41, 0xfc, 0x4, 0xe, 0xf0, 0x7d, 0xe3, 0x31, 0x7f, 0xc5, 0xcd, - 0x5e, 0x84, 0x3d, 0xda, 0x92, 0xfb, 0x71, 0xc3, 0x77, 0x2a, 0xae, 0x39, 0x65, 0x16, 0x24, - 0x7d, 0x7c, 0x61, 0xcd, 0xdd, 0xe3, 0x50, 0x54, 0x44, 0xc4, 0x30, 0x98, 0xfc, 0x62, 0xb9, - 0xad, 0x20, 0x7b, 0x2b, 0x5b, 0xf1, 0xf6, 0xe5, 0x3e, 0xf4, 0xe0, 0xaf, 0x7a, 0xeb, 0xe6, - 0xee, 0xe7, 0x21, 0xc, 0xf1, 0x54, 0xbc, 0xe7, 0xe4, 0x19, 0xd9, 0xfd, 0x1d, 0x1b, 0x2f, - 0xad, 0xeb, 0xe4, 0x27, 0x73, 0xd, 0xcd, 0xb8, 0x7a, 0x7e, 0xe7, 0x4b, 0x8d, 0xce, 0x83, - 0x91, 0x1, 0x82, 0x62, 0xb1, 0xb0, 0xad, 0x32, 0x6f, 0xb6, 0xe2, 0xff, 0x10, 0x5c, 0x83, - 0x13, 0xa4, 0x6f, 0xe7, 0xaa, 0x7, 0xf0, 0xc4, 0x3c, 0x42, 0x51, 0xd9, 0xc7, 0x70, 0x4, - 0xf, 0x6e, 0x2c, 0x5c, 0x67, 0x2d, 0xd2, 0x3, 0x69, 0xa, 0x45, 0x9b, 0xa9, 0x6e, 0xd0, - 0x6c, 0x7e, 0xfb, 0xf3, 0x15, 0xa0, 0x8d, 0x31, 0xb0, 0x7d, 0x83, 0xc, 0xa9, 0xbf, 0xa8, - 0xcc, 0x13, 0x33, 0x61, 0xdf, 0x2f, 0x7e, 0x4d, 0xd3, 0xe, 0x94, 0x0, 0xa4, 0x49, 0xcc, - 0xf, 0x32, 0x93, 0x1, 0xdc, 0xf1, 0x56, 0xfe, 0x14, 0xa0, 0x95, 0x96, 0xf6, 0xe5, 0x23, - 0x2, 0xb7, 0xce, 0x71, 0x2c, 0xa6, 0x7e, 0x67, 0x7a, 0x59, 0x84, 0x5c, 0xc5, 0xbe, 0x66, - 0xd4, 0x73, 0x3a, 0xbd, 0xf9, 0xa3, 0xd4, 0x7a, 0x66, 0xaf, 0xe, 0x46, 0x2d, 0x6d, 0x2c, - 0x5b, 0x31, 0xf9, 0x51, 0x5, 0xa6, 0xa4, 0x49, 0xbd, 0xf3, 0x5, 0x6d, 0x98, 0x56, 0xa6, - 0xce, 0xea, 0x15, 0x1, 0x0, 0xa, 0xa2, 0x7f, 0x61, 0x42, 0xef, 0x52, 0xbc, 0x8e, 0xaf, - 0xd3, 0x36, 0xd, 0x65, 0x25, 0x89, 0x52, 0xf4, 0xd9, 0x57, 0x5e, 0xac, 0x1b, 0x1f, 0x18, - 0xee, 0x18, 0x51, 0x29, 0x71, 0x82, 0x93, 0xb6, 0xd7, 0x62, 0x2b, 0x1e, 0xdd, 0x1f, 0x20, - 0x1, 0x0, 0x0, 0x0, 0x3, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0xde, 0xbb, - 0xbe, 0xfd, 0x16, 0x83, 0xe3, 0x35, 0x29, 0x6a, 0xc, 0x86, 0xf1, 0xc8, 0x82, 0xa2, 0xea, - 0x37, 0x59, 0xf1, 0x14, 0x22, 0xb, 0xb, 0x2c, 0xf8, 0x69, 0xe3, 0x7d, 0xec, 0x24, 0xc8, - 0x0, 0xb3, 0x2a, 0x56, 0xa6, 0xc7, 0x2, 0x56, 0x33, 0x79, 0xad, 0x65, 0xd0, 0x7a, 0x2c, - 0x80, 0xe0, 0x46, 0x73, 0xaf, 0x85, 0x59, 0x52, 0x58, 0xfc, 0x15, 0x60, 0xff, 0xd8, 0x47, - 0x1a, 0xd7, 0x32, 0x21, 0x0, 0x8, 0x97, 0x75, 0xf8, 0x29, 0xc8, 0xad, 0xad, 0x92, 0xad, - 0xa1, 0x7b, 0x59, 0x31, 0xed, 0xf6, 0x30, 0x64, 0xd5, 0x46, 0x78, 0xf4, 0xeb, 0x9a, 0x6f, - 0xdf, 0xe8, 0xe4, 0xcb, 0x5d, 0x95, 0xf6, 0xf4, 0xa3, 0x2, 0x3b, 0x4d, 0x5a, 0x83, 0xe1, - 0x98, 0x44, 0x23, 0xd7, 0xc8, 0xe3, 0xc8, 0x35, 0xf, 0x42, 0xc, 0xca, 0x90, 0xc5, 0xa4, - 0xa7, 0x3f, 0xea, 0x62, 0x69, 0xe4, 0x78, 0xbc, 0x63, 0x94, 0x76, 0xfb, 0xb6, 0x64, 0xa9, - 0xf7, 0x81, 0x70, 0xc6, 0xd, 0xa3, 0x70, 0x5, 0xc1, 0xc8, 0x94, 0x7f, 0x20, 0xff, 0x83, - 0x8c, 0xc4, 0x7a, 0x26, 0xd3, 0x84, 0xab, 0x51, 0x15, 0xfc, 0xb1, 0x57, 0x2d, 0xb3, 0x9, - 0x1b, 0xc8, 0x6d, 0x32, 0xfd, 0x52, 0x70, 0xa, 0xf1, 0x47, 0xe2, 0xc4, 0xa8, 0x5c, 0x5e, - 0x95, 0x18, 0xc8, 0x46, 0xa9, 0xa3, 0xd0, 0xda, 0x76, 0xce, 0xbf, 0xdb, 0x31, 0x27, 0x4b, - 0x68, 0x58, 0xe5, 0x36, 0x13, 0x54, 0x29, 0x94, 0x4c, 0x30, 0x23, 0x4c, 0xc, 0x6a, 0x3a, - 0x5, 0x15, 0x70, 0x97, 0x8a, 0x3e, 0xc5, 0x82, 0x96, 0x65, 0x56, 0x69, 0xc0, 0x4d, 0x58, - 0x5b, 0x8a, 0x85, 0x39, 0x84, 0x29, 0x9b, 0xa5, 0x9b, 0xe4, 0xc4, 0x79, 0x5b, 0x8b, 0xe1, - 0x17, 0x25, 0x10, 0x22, 0x4, 0x5, 0x44, 0xe5, 0x68, 0x72, 0x80, 0x88, 0xd5, 0x23, 0x22, - 0x19, 0x8d, 0xca, 0xa5, 0x26, 0xc4, 0x73, 0xdb, 0x6, 0x96, 0xb7, 0xe, 0x28, 0xc6, 0xa, - 0xc3, 0x65, 0x5c, 0x9c, 0x3, 0xf3, 0x1d, 0xc9, 0x53, 0x34, 0x6a, 0x85, 0x1, 0xe2, 0x3c, - 0x91, 0x6d, 0x70, 0xe1, 0x4d, 0xa2, 0xa, 0x67, 0x50, 0xb0, 0xe2, 0x12, 0x1f, 0xba, 0x68, - 0xdc, 0xd, 0x35, 0x3b, 0x32, 0xa7, 0x2b, 0xe7, 0x91, 0x6d, 0xb2, 0xe0, 0xf4, 0xb8, 0xb1, - 0x6d, 0xab, 0xa6, 0x46, 0xd5, 0x4, 0x5a, 0x5d, 0xf1, 0x8f, 0x2d, 0x52, 0x6a, 0xb8, 0x50, - 0xf3, 0x22, 0x4e, 0xb1, 0x24, 0xa8, 0xa1, 0x15, 0x34, 0xbc, 0x3f, 0xda, 0x8c, 0xc6, 0xc8, - 0x53, 0x2b, 0xd0, 0x9f, 0xa8, 0x72, 0x3e, 0xc1, 0x6a, 0x3a, 0x51, 0xb1, 0x99, 0x80, 0x1b, - 0xae, 0x2d, 0x4c, 0x79, 0xa0, 0x10, 0x2b, 0x7, 0x4a, 0xa, 0x65, 0x3a, 0x82, 0xe4, 0x1f, - 0xbb, 0x9c, 0x6e, 0x20, 0xa5, 0x1b, 0x17, 0xdc, 0xa7, 0x6f, 0x77, 0x22, 0xd, 0xb9, 0xc2, - 0xf6, 0xa7, 0xe1, 0x8d, 0x88, 0x88, 0xdc, 0x44, 0x68, 0xbd, 0x25, 0x42, 0x5f, 0x20, 0x1b, - 0x84, 0x15, 0x56, 0x5, 0x95, 0x9c, 0x40, 0xef, 0xa1, 0x71, 0xaa, 0xc7, 0x82, 0x8, 0x39, - 0xf4, 0x58, 0xae, 0x39, 0x50, 0xac, 0xc7, 0x53, 0xff, 0x5, 0xb0, 0x29, 0x9d, 0x54, 0x4f, - 0x8d, 0x1a, 0x81, 0x61, 0xc2, 0x71, 0xc, 0x2f, 0xdb, 0x1b, 0x1b, 0xa7, 0x4f, 0x1a, 0x4a, - 0xa2, 0xa9, 0x8c, 0x2c, 0x1, 0xe7, 0xf9, 0xf, 0x85, 0xc1, 0x33, 0xe7, 0x39, 0x8f, 0x43, - 0x40, 0x30, 0x27, 0xeb, 0xad, 0x7e, 0xef, 0x22, 0xf8, 0xb5, 0x51, 0xe5, 0xb3, 0x7c, 0x2a, - 0x45, 0x88, 0x93, 0xac, 0xea, 0x6a, 0x51, 0x63, 0x79, 0x45, 0x35, 0xfd, 0x9d, 0xd4, 0x55, - 0x98, 0xd, 0xf4, 0x29, 0x7c, 0xfc, 0x93, 0x52, 0xa4, 0x61, 0x6c, 0x1a, 0xcf, 0x5, 0x5a, - 0x3e, 0x44, 0x82, 0x6c, 0x44, 0x7e, 0x6e, 0xb2, 0xad, 0x5a, 0x3, 0x72, 0x2f, 0xed, 0x77, - 0x44, 0x16, 0xd1, 0x59, 0xa8, 0x10, 0x2d, 0x8, 0x6c, 0xd6, 0xb2, 0x38, 0x95, 0x4c, 0x37, - 0x54, 0x2e, 0x8d, 0xdc, 0xd6, 0x34, 0xe5, 0xe2, 0x64, 0x9b, 0x57, 0x26, 0x38, 0x28, 0xd, - 0x46, 0x7e, 0xc3, 0x1, 0xcc, 0x36, 0x48, 0xe9, 0xd1, 0x9a, 0x9f, 0x29, 0xa1, 0xac, 0x53, - 0xdd, 0xf, 0x8a, 0x51, 0x5d, 0xe3, 0x18, 0x19, 0xcf, 0x93, 0x82, 0x95, 0x5b, 0x69, 0x8e, - 0xf, 0xab, 0x2, 0x17, 0xfa, 0xa7, 0x9, 0x35, 0xf2, 0x9, 0x39, 0xe2, 0x5b, 0x36, 0x90, 0xa8, - 0x46, 0x9c, 0xf3, 0x58, 0x29, 0x0, 0xb1, 0xb0, 0xdd, 0xdc, 0x41, 0xf6, 0xa, 0x99, 0xe1, - 0xff, 0x2b, 0xe8, 0x1d, 0x3c, 0x86, 0x8e, 0xff, 0x9f, 0xed, 0x3e, 0x98, 0x5d, 0x24, 0xfc, - 0x58, 0xd7, 0x13, 0x12, 0xa7, 0x74, 0x5e, 0x3e, 0x44, 0x68, 0x7d, 0x11, 0x0, 0x44, 0xb1, - 0x28, 0x4f, 0x85, 0x1e, 0x92, 0x5a, 0x3c, 0xc6, 0x77, 0x70, 0x4, 0x43, 0x1c, 0x81, 0x41, - 0x65, 0xd2, 0x33, 0x77, 0x91, 0xd1, 0xab, 0xe5, 0x97, 0x90, 0x1f, 0x7b, 0xe6, 0xbb, 0xcc, - 0xb3, 0x65, 0x61, 0x57, 0x6d, 0x60, 0xa6, 0x93, 0x79, 0x3d, 0x70, 0x43, 0x92, 0x5, 0x4b, - 0x2, 0x67, 0xea, 0x78, 0x8b, 0x12, 0xba, 0x85, 0x9c, 0x2b, 0xda, 0x7b, 0xb, 0xed, 0x3c, - 0xe8, 0xca, 0xa4, 0x64, 0xe4, 0x9b, 0x9c, 0xa8, 0x5c, 0x5c, 0xe2, 0xa7, 0x82, 0xea, 0x4c, - 0x79, 0x77, 0x4, 0xf1, 0x0, 0x5, 0xad, 0x2f, 0x72, 0x3d, 0x95, 0xe5, 0x8, 0x50, 0x48, 0x2e, - 0x80, 0x5d, 0x54, 0x67, 0xf9, 0x41, 0xf1, 0x1d, 0xb6, 0x86, 0x6, 0x73, 0xa, 0xaf, 0x99, - 0x7d, 0x2c, 0x30, 0xa6, 0xc9, 0xbc, 0x7d, 0x39, 0x16, 0x3, 0x55, 0x85, 0x63, 0xe8, 0x69, - 0x36, 0x2a, 0xc2, 0xba, 0x5b, 0xf, 0x49, 0x1d, 0x2, 0xb4, 0xe1, 0x12, 0xf1, 0xe6, 0x9b, - 0xaf, 0xd4, 0x78, 0xd9, 0xaf, 0x7b, 0x5f, 0x50, 0xa5, 0x86, 0x32, 0xbc, 0x36, 0xe4, 0x96, - 0x11, 0xef, 0xf8, 0xb4, 0xd4, 0x91, 0xf7, 0xd7, 0x43, 0x15, 0x28, 0x3, 0x1e, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x5d, 0x35, 0x74, 0xc4, 0xd9, 0x9c, 0x8, 0xef, 0x95, 0x6, - 0x19, 0xbe, 0x72, 0xbf, 0xa1, 0xd5, 0xa, 0xe3, 0xc1, 0x53, 0xd1, 0xf3, 0xf, 0x64, 0xbc, - 0x1a, 0xc0, 0x8d, 0xe9, 0x9e, 0xa5, 0x56, 0x3, 0x0, 0x2, 0x4, 0x0, 0x2, 0x3a, 0xa, 0x34, - 0xc8, 0xd, 0xdb, 0x3e, 0xac, 0x5c, 0xd5, 0x92, 0x38, 0x30, 0x81, 0x4d, 0x72, 0xf9, 0xde, - 0x9, 0x6b, 0xca, 0x74, 0x87, 0x79, 0xda, 0x39, 0x7a, 0xa3, 0xb7, 0x71, 0xfe, 0x7e, 0x40, - 0xc6, 0x41, 0x1a, 0xea, 0x8, 0x2e, 0x2c, 0x5d, 0x74, 0x34, 0x73, 0x68, 0x67, 0x7d, 0xb6, - 0x95, 0x45, 0x12, 0x62, 0x37, 0xd5, 0xed, 0x78, 0xfa, 0xa0, 0x84, 0x63, 0x52, 0xf5, 0x38, - 0x3f, 0x95, 0x3, 0x0, 0xfd, 0xb7, 0x19, 0xd1, 0x24, 0xce, 0xff, 0x58, 0x6, 0xe, 0xf5, 0x8d, + 0x72, 0x90, 0x19, 0xe4, 0x7e, 0xd2, 0x7e, 0xf5, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0xad, 0xb1, + 0x39, 0x64, 0xb, 0xb6, 0xb9, 0x36, 0x8e, 0xaf, 0xd3, 0x36, 0xd, 0x65, 0x25, 0x89, 0x52, + 0xf4, 0xd9, 0x57, 0x5e, 0xac, 0x1b, 0x1f, 0x18, 0xee, 0x18, 0x51, 0x29, 0x71, 0x82, 0x93, + 0xb6, 0xd7, 0x62, 0x2b, 0x1e, 0xdd, 0x1f, 0x20, 0x1, 0x0, 0x0, 0x0, 0x2, 0x0, 0x1, 0x3, + 0x4, 0x0, 0x3, 0x0, 0x6e, 0x5a, 0x76, 0xca, 0xd0, 0x21, 0x63, 0xa5, 0x6, 0xe, 0xf5, 0x8d, 0x94, 0xa, 0x75, 0xe4, 0x3d, 0x13, 0x9d, 0x55, 0xa5, 0xe4, 0xd3, 0x26, 0x4d, 0xc9, 0xeb, 0x4f, 0x77, 0x3b, 0xff, 0xc5, 0x72, 0x90, 0x19, 0xe4, 0x7e, 0xd2, 0x7e, 0xf5, 0x1, 0x0, - 0x0, 0x0, 0x64, 0x20, 0xcc, 0x42, 0x1e, 0x11, 0x89, 0x80, 0x5c, 0x8c, 0xec, 0x8, 0x9d, - 0x74, 0xc1, 0x98, 0xf, 0x79, 0xc0, 0x69, 0x0, 0x5a, 0x21, 0xae, 0x40, 0xa7, 0xe5, 0x8e, - 0x68, 0x77, 0xa8, 0x10, 0x7b, 0x4, 0x9, 0x1a, 0x9a, 0x97, 0x1, 0x2, 0x90, 0xe5, 0x10, 0xa2, - 0x10, 0x60, 0xad, 0xa3, 0x39, 0x71, 0xd, 0xd, 0xdc, 0x43, 0xe4, 0x46, 0x0, 0x6c, 0x5b, - 0xc9, 0x38, 0x64, 0xda, 0xfb, 0x3, 0xcf, 0x4b, 0xa4, 0x72, 0xbe, 0xdf, 0x5c, 0xa7, 0x1, - 0x0, 0x47, 0xe7, 0xd3, 0x5d, 0x93, 0xe4, 0xb5, 0x62, 0x8e, 0xaf, 0xd3, 0x36, 0xd, 0x65, - 0x25, 0x89, 0x52, 0xf4, 0xd9, 0x57, 0x5e, 0xac, 0x1b, 0x1f, 0x18, 0xee, 0x18, 0x51, 0x29, - 0x71, 0x82, 0x93, 0xb6, 0xd7, 0x62, 0x2b, 0x1e, 0xdd, 0x1f, 0x20, 0x1, 0x0, 0x0, 0x0, 0x40, - 0xe7, 0xa, 0x36, 0xe2, 0xce, 0x51, 0xd3, 0x1d, 0x4c, 0xf5, 0xd6, 0x73, 0x1f, 0xa6, 0x37, - 0x38, 0x64, 0x81, 0x27, 0xdb, 0x83, 0x37, 0x15, 0xd3, 0x96, 0x52, 0xd8, 0x6d, 0x92, 0x7d, - 0x48, 0x88, 0x3, 0x0, 0x1, 0x0, 0x2, 0x0, 0x3, 0x0, 0x5, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, + 0x0, 0x0, 0x21, 0x0, 0x8, 0xcc, 0x48, 0xfa, 0x5e, 0x5c, 0xb1, 0xd2, 0xd2, 0x46, 0x5b, 0xd8, + 0xc4, 0x37, 0xc0, 0xe0, 0x5, 0x14, 0xab, 0xd8, 0x13, 0xf9, 0xa7, 0xdd, 0x50, 0x6a, 0x77, + 0x84, 0x5, 0xa2, 0xc4, 0x3b, 0xc0, 0xa3, 0x2, 0xdd, 0x8a, 0x81, 0xc2, 0xb1, 0x62, 0xe7, + 0xb9, 0xc8, 0xec, 0xe9, 0x64, 0xfc, 0x4f, 0x67, 0x56, 0xdb, 0x85, 0x34, 0x43, 0x97, 0x3c, + 0x84, 0xf9, 0x32, 0x45, 0x5e, 0x8c, 0x4c, 0x93, 0xd9, 0x19, 0xb, 0x68, 0x4e, 0x5a, 0x15, + 0xc7, 0x31, 0xb, 0x33, 0xa4, 0xc0, 0xbe, 0xa6, 0x11, 0xc, 0x64, 0xa0, 0x24, 0x72, 0x79, + 0xec, 0x12, 0x49, 0xc6, 0x9f, 0x94, 0xeb, 0x5, 0x71, 0x7d, 0x81, 0x0, 0xe, 0x3f, 0x84, + 0x8e, 0x9f, 0xe9, 0x68, 0x2f, 0xa6, 0xa, 0xd8, 0x59, 0x57, 0xcf, 0x64, 0xb9, 0x56, 0xb5, + 0xfc, 0xcc, 0x2b, 0xdc, 0x9e, 0x4d, 0xdd, 0x78, 0x60, 0x63, 0x12, 0x57, 0x12, 0xcd, 0xf3, + 0x6f, 0xe2, 0xca, 0x1e, 0x19, 0x3a, 0xb, 0x10, 0xc, 0x59, 0x97, 0xc, 0xde, 0xa8, 0x62, + 0x42, 0x4a, 0x2f, 0x1e, 0xeb, 0x89, 0x98, 0xc6, 0x31, 0x82, 0xc9, 0x4f, 0xf, 0xf1, 0xa5, + 0x1a, 0x37, 0x2d, 0x92, 0x86, 0x8c, 0xe5, 0x37, 0x3a, 0x86, 0xc4, 0x89, 0x9f, 0xf4, 0xcf, + 0x10, 0x7b, 0x9a, 0x30, 0xc0, 0x0, 0x97, 0x1e, 0x44, 0x9b, 0xb2, 0x92, 0x1d, 0x38, 0x6e, + 0x3a, 0xce, 0xea, 0x95, 0xcd, 0xcd, 0x63, 0x74, 0x5e, 0x43, 0xf, 0xd3, 0xdd, 0x21, 0x2, + 0xca, 0x91, 0xc5, 0x2d, 0x9f, 0x21, 0x7b, 0x4d, 0x14, 0x9f, 0xf1, 0x88, 0xe5, 0x3a, 0x98, + 0x6d, 0x3, 0xdd, 0x64, 0x90, 0x73, 0x5a, 0x87, 0x1f, 0x53, 0x64, 0xe4, 0x9e, 0x48, 0xfc, + 0x1e, 0x3e, 0xcc, 0xeb, 0x5, 0xd3, 0xfd, 0x9a, 0x56, 0x5f, 0x71, 0x51, 0x39, 0xe3, 0x10, + 0xa8, 0xae, 0x20, 0xa8, 0xba, 0xca, 0x7b, 0x91, 0x6, 0xe9, 0x61, 0x45, 0x69, 0x91, 0x94, + 0xe0, 0xec, 0x50, 0xa4, 0x12, 0x58, 0xe1, 0x64, 0xc2, 0x4c, 0x3c, 0x7f, 0x69, 0x7a, 0x7e, + 0x4a, 0xee, 0xed, 0xb, 0x91, 0x3e, 0x63, 0x71, 0x96, 0x99, 0x78, 0xf0, 0x3e, 0x40, 0x96, + 0x58, 0x9a, 0xd, 0xb9, 0x77, 0x79, 0xa2, 0xb7, 0xa3, 0x67, 0xcf, 0xc2, 0x45, 0x27, 0xf0, + 0x86, 0x3f, 0x8f, 0x60, 0xec, 0x17, 0x54, 0x4, 0xa8, 0xf1, 0xce, 0x5f, 0xa2, 0x5b, 0xe9, + 0xba, 0xb0, 0xac, 0x4f, 0x5b, 0x47, 0xbb, 0xb6, 0xd8, 0x1, 0x7, 0x73, 0x24, 0xc4, 0x8b, + 0xc8, 0xe1, 0x15, 0xe4, 0xd2, 0x9f, 0xc5, 0x4, 0xed, 0x13, 0xc3, 0x17, 0xb8, 0xc9, 0xdd, + 0x84, 0x78, 0xea, 0x92, 0x4c, 0x41, 0x98, 0xc, 0x38, 0xc8, 0x2, 0x20, 0xeb, 0xf2, 0x93, + 0x75, 0x8f, 0xd7, 0x9d, 0x76, 0xfa, 0xfa, 0xbb, 0x5e, 0xa1, 0x98, 0x51, 0xd6, 0xbd, 0x6, + 0xa2, 0x37, 0x2, 0x89, 0x10, 0xb9, 0x84, 0x69, 0xc7, 0xb7, 0xee, 0xec, 0xca, 0x2d, 0x13, + 0xbb, 0x8f, 0xb, 0xa5, 0x9f, 0x17, 0x6a, 0xb2, 0xef, 0x51, 0x39, 0x1f, 0xce, 0x69, 0x8c, + 0xc, 0x67, 0x67, 0x6f, 0x29, 0x29, 0x5, 0x5a, 0xcb, 0x17, 0x6a, 0x8f, 0x1b, 0xe6, 0x1c, + 0x32, 0xad, 0xf2, 0xda, 0xb3, 0xb6, 0xb8, 0x6e, 0xae, 0x28, 0x9e, 0x7b, 0x12, 0x3f, 0x52, + 0x26, 0xfd, 0x9c, 0xad, 0x2b, 0x18, 0xb2, 0x6f, 0x33, 0xf, 0xf5, 0xab, 0x53, 0x8c, 0x9b, + 0xbf, 0xca, 0xe2, 0x1f, 0xfd, 0x91, 0xaa, 0x41, 0x26, 0x81, 0xdc, 0x1c, 0x9a, 0xd4, 0x1d, + 0xec, 0xd9, 0x48, 0x60, 0xc9, 0x7, 0x1c, 0xf8, 0x4d, 0x41, 0xfc, 0x4, 0xe, 0xf0, 0x7d, + 0xe3, 0x31, 0x7f, 0xc5, 0xcd, 0x5e, 0x84, 0x3d, 0xda, 0x92, 0xfb, 0x71, 0xc3, 0x77, 0x2a, + 0xae, 0x39, 0x65, 0x16, 0x24, 0x7d, 0x7c, 0x61, 0xcd, 0xdd, 0xe3, 0x50, 0x54, 0x44, 0xc4, + 0x30, 0x98, 0xfc, 0x62, 0xb9, 0xad, 0x20, 0x7b, 0x2b, 0x5b, 0xf1, 0xf6, 0xe5, 0x3e, 0xf4, + 0xe0, 0xaf, 0x7a, 0xeb, 0xe6, 0xee, 0xe7, 0x21, 0xc, 0xf1, 0x54, 0xbc, 0xe7, 0xe4, 0x19, + 0xd9, 0xfd, 0x1d, 0x1b, 0x2f, 0xad, 0xeb, 0xe4, 0x27, 0x73, 0xd, 0xcd, 0xb8, 0x7a, 0x7e, + 0xe7, 0x4b, 0x8d, 0xce, 0x83, 0x91, 0x1, 0x82, 0x62, 0xb1, 0xb0, 0xad, 0x32, 0x6f, 0xb6, + 0xe2, 0xff, 0x10, 0x5c, 0x83, 0x13, 0xa4, 0x6f, 0xe7, 0xaa, 0x7, 0xf0, 0xc4, 0x3c, 0x42, + 0x51, 0xd9, 0xc7, 0x70, 0x4, 0xf, 0x6e, 0x2c, 0x5c, 0x67, 0x2d, 0xd2, 0x3, 0x69, 0xa, 0x45, + 0x9b, 0xa9, 0x6e, 0xd0, 0x6c, 0x7e, 0xfb, 0xf3, 0x15, 0xa0, 0x8d, 0x31, 0xb0, 0x7d, 0x83, + 0xc, 0xa9, 0xbf, 0xa8, 0xcc, 0x13, 0x33, 0x61, 0xdf, 0x2f, 0x7e, 0x4d, 0xd3, 0xe, 0x94, + 0x0, 0xa4, 0x49, 0xcc, 0xf, 0x32, 0x93, 0x1, 0xdc, 0xf1, 0x56, 0xfe, 0x14, 0xa0, 0x95, + 0x96, 0xf6, 0xe5, 0x23, 0x2, 0xb7, 0xce, 0x71, 0x2c, 0xa6, 0x7e, 0x67, 0x7a, 0x59, 0x84, + 0x5c, 0xc5, 0xbe, 0x66, 0xd4, 0x73, 0x3a, 0xbd, 0xf9, 0xa3, 0xd4, 0x7a, 0x66, 0xaf, 0xe, + 0x46, 0x2d, 0x6d, 0x2c, 0x5b, 0x31, 0xf9, 0x51, 0x5, 0xa6, 0xa4, 0x49, 0xbd, 0xf3, 0x5, + 0x6d, 0x98, 0x56, 0xa6, 0xce, 0xea, 0x15, 0x1, 0x0, 0xa, 0xa2, 0x7f, 0x61, 0x42, 0xef, + 0x52, 0xbc, 0x8e, 0xaf, 0xd3, 0x36, 0xd, 0x65, 0x25, 0x89, 0x52, 0xf4, 0xd9, 0x57, 0x5e, + 0xac, 0x1b, 0x1f, 0x18, 0xee, 0x18, 0x51, 0x29, 0x71, 0x82, 0x93, 0xb6, 0xd7, 0x62, 0x2b, + 0x1e, 0xdd, 0x1f, 0x20, 0x1, 0x0, 0x0, 0x0, 0x3, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x20, 0x0, 0xde, 0xbb, 0xbe, 0xfd, 0x16, 0x83, 0xe3, 0x35, 0x29, 0x6a, 0xc, 0x86, 0xf1, + 0xc8, 0x82, 0xa2, 0xea, 0x37, 0x59, 0xf1, 0x14, 0x22, 0xb, 0xb, 0x2c, 0xf8, 0x69, 0xe3, + 0x7d, 0xec, 0x24, 0xc8, 0x0, 0xb3, 0x2a, 0x56, 0xa6, 0xc7, 0x2, 0x56, 0x33, 0x79, 0xad, + 0x65, 0xd0, 0x7a, 0x2c, 0x80, 0xe0, 0x46, 0x73, 0xaf, 0x85, 0x59, 0x52, 0x58, 0xfc, 0x15, + 0x60, 0xff, 0xd8, 0x47, 0x1a, 0xd7, 0x32, 0x21, 0x0, 0x8, 0x97, 0x75, 0xf8, 0x29, 0xc8, + 0xad, 0xad, 0x92, 0xad, 0xa1, 0x7b, 0x59, 0x31, 0xed, 0xf6, 0x30, 0x64, 0xd5, 0x46, 0x78, + 0xf4, 0xeb, 0x9a, 0x6f, 0xdf, 0xe8, 0xe4, 0xcb, 0x5d, 0x95, 0xf6, 0xf4, 0xa3, 0x2, 0x3b, + 0x4d, 0x5a, 0x83, 0xe1, 0x98, 0x44, 0x23, 0xd7, 0xc8, 0xe3, 0xc8, 0x35, 0xf, 0x42, 0xc, + 0xca, 0x90, 0xc5, 0xa4, 0xa7, 0x3f, 0xea, 0x62, 0x69, 0xe4, 0x78, 0xbc, 0x63, 0x94, 0x76, + 0xfb, 0xb6, 0x64, 0xa9, 0xf7, 0x81, 0x70, 0xc6, 0xd, 0xa3, 0x70, 0x5, 0xc1, 0xc8, 0x94, + 0x7f, 0x20, 0xff, 0x83, 0x8c, 0xc4, 0x7a, 0x26, 0xd3, 0x84, 0xab, 0x51, 0x15, 0xfc, 0xb1, + 0x57, 0x2d, 0xb3, 0x9, 0x1b, 0xc8, 0x6d, 0x32, 0xfd, 0x52, 0x70, 0xa, 0xf1, 0x47, 0xe2, + 0xc4, 0xa8, 0x5c, 0x5e, 0x95, 0x18, 0xc8, 0x46, 0xa9, 0xa3, 0xd0, 0xda, 0x76, 0xce, 0xbf, + 0xdb, 0x31, 0x27, 0x4b, 0x68, 0x58, 0xe5, 0x36, 0x13, 0x54, 0x29, 0x94, 0x4c, 0x30, 0x23, + 0x4c, 0xc, 0x6a, 0x3a, 0x5, 0x15, 0x70, 0x97, 0x8a, 0x3e, 0xc5, 0x82, 0x96, 0x65, 0x56, + 0x69, 0xc0, 0x4d, 0x58, 0x5b, 0x8a, 0x85, 0x39, 0x84, 0x29, 0x9b, 0xa5, 0x9b, 0xe4, 0xc4, + 0x79, 0x5b, 0x8b, 0xe1, 0x17, 0x25, 0x10, 0x22, 0x4, 0x5, 0x44, 0xe5, 0x68, 0x72, 0x80, + 0x88, 0xd5, 0x23, 0x22, 0x19, 0x8d, 0xca, 0xa5, 0x26, 0xc4, 0x73, 0xdb, 0x6, 0x96, 0xb7, + 0xe, 0x28, 0xc6, 0xa, 0xc3, 0x65, 0x5c, 0x9c, 0x3, 0xf3, 0x1d, 0xc9, 0x53, 0x34, 0x6a, + 0x85, 0x1, 0xe2, 0x3c, 0x91, 0x6d, 0x70, 0xe1, 0x4d, 0xa2, 0xa, 0x67, 0x50, 0xb0, 0xe2, + 0x12, 0x1f, 0xba, 0x68, 0xdc, 0xd, 0x35, 0x3b, 0x32, 0xa7, 0x2b, 0xe7, 0x91, 0x6d, 0xb2, + 0xe0, 0xf4, 0xb8, 0xb1, 0x6d, 0xab, 0xa6, 0x46, 0xd5, 0x4, 0x5a, 0x5d, 0xf1, 0x8f, 0x2d, + 0x52, 0x6a, 0xb8, 0x50, 0xf3, 0x22, 0x4e, 0xb1, 0x24, 0xa8, 0xa1, 0x15, 0x34, 0xbc, 0x3f, + 0xda, 0x8c, 0xc6, 0xc8, 0x53, 0x2b, 0xd0, 0x9f, 0xa8, 0x72, 0x3e, 0xc1, 0x6a, 0x3a, 0x51, + 0xb1, 0x99, 0x80, 0x1b, 0xae, 0x2d, 0x4c, 0x79, 0xa0, 0x10, 0x2b, 0x7, 0x4a, 0xa, 0x65, + 0x3a, 0x82, 0xe4, 0x1f, 0xbb, 0x9c, 0x6e, 0x20, 0xa5, 0x1b, 0x17, 0xdc, 0xa7, 0x6f, 0x77, + 0x22, 0xd, 0xb9, 0xc2, 0xf6, 0xa7, 0xe1, 0x8d, 0x88, 0x88, 0xdc, 0x44, 0x68, 0xbd, 0x25, + 0x42, 0x5f, 0x20, 0x1b, 0x84, 0x15, 0x56, 0x5, 0x95, 0x9c, 0x40, 0xef, 0xa1, 0x71, 0xaa, + 0xc7, 0x82, 0x8, 0x39, 0xf4, 0x58, 0xae, 0x39, 0x50, 0xac, 0xc7, 0x53, 0xff, 0x5, 0xb0, + 0x29, 0x9d, 0x54, 0x4f, 0x8d, 0x1a, 0x81, 0x61, 0xc2, 0x71, 0xc, 0x2f, 0xdb, 0x1b, 0x1b, + 0xa7, 0x4f, 0x1a, 0x4a, 0xa2, 0xa9, 0x8c, 0x2c, 0x1, 0xe7, 0xf9, 0xf, 0x85, 0xc1, 0x33, + 0xe7, 0x39, 0x8f, 0x43, 0x40, 0x30, 0x27, 0xeb, 0xad, 0x7e, 0xef, 0x22, 0xf8, 0xb5, 0x51, + 0xe5, 0xb3, 0x7c, 0x2a, 0x45, 0x88, 0x93, 0xac, 0xea, 0x6a, 0x51, 0x63, 0x79, 0x45, 0x35, + 0xfd, 0x9d, 0xd4, 0x55, 0x98, 0xd, 0xf4, 0x29, 0x7c, 0xfc, 0x93, 0x52, 0xa4, 0x61, 0x6c, + 0x1a, 0xcf, 0x5, 0x5a, 0x3e, 0x44, 0x82, 0x6c, 0x44, 0x7e, 0x6e, 0xb2, 0xad, 0x5a, 0x3, + 0x72, 0x2f, 0xed, 0x77, 0x44, 0x16, 0xd1, 0x59, 0xa8, 0x10, 0x2d, 0x8, 0x6c, 0xd6, 0xb2, + 0x38, 0x95, 0x4c, 0x37, 0x54, 0x2e, 0x8d, 0xdc, 0xd6, 0x34, 0xe5, 0xe2, 0x64, 0x9b, 0x57, + 0x26, 0x38, 0x28, 0xd, 0x46, 0x7e, 0xc3, 0x1, 0xcc, 0x36, 0x48, 0xe9, 0xd1, 0x9a, 0x9f, + 0x29, 0xa1, 0xac, 0x53, 0xdd, 0xf, 0x8a, 0x51, 0x5d, 0xe3, 0x18, 0x19, 0xcf, 0x93, 0x82, + 0x95, 0x5b, 0x69, 0x8e, 0xf, 0xab, 0x2, 0x17, 0xfa, 0xa7, 0x9, 0x35, 0xf2, 0x9, 0x39, 0xe2, + 0x5b, 0x36, 0x90, 0xa8, 0x46, 0x9c, 0xf3, 0x58, 0x29, 0x0, 0xb1, 0xb0, 0xdd, 0xdc, 0x41, + 0xf6, 0xa, 0x99, 0xe1, 0xff, 0x2b, 0xe8, 0x1d, 0x3c, 0x86, 0x8e, 0xff, 0x9f, 0xed, 0x3e, + 0x98, 0x5d, 0x24, 0xfc, 0x58, 0xd7, 0x13, 0x12, 0xa7, 0x74, 0x5e, 0x3e, 0x44, 0x68, 0x7d, + 0x11, 0x0, 0x44, 0xb1, 0x28, 0x4f, 0x85, 0x1e, 0x92, 0x5a, 0x3c, 0xc6, 0x77, 0x70, 0x4, + 0x43, 0x1c, 0x81, 0x41, 0x65, 0xd2, 0x33, 0x77, 0x91, 0xd1, 0xab, 0xe5, 0x97, 0x90, 0x1f, + 0x7b, 0xe6, 0xbb, 0xcc, 0xb3, 0x65, 0x61, 0x57, 0x6d, 0x60, 0xa6, 0x93, 0x79, 0x3d, 0x70, + 0x43, 0x92, 0x5, 0x4b, 0x2, 0x67, 0xea, 0x78, 0x8b, 0x12, 0xba, 0x85, 0x9c, 0x2b, 0xda, + 0x7b, 0xb, 0xed, 0x3c, 0xe8, 0xca, 0xa4, 0x64, 0xe4, 0x9b, 0x9c, 0xa8, 0x5c, 0x5c, 0xe2, + 0xa7, 0x82, 0xea, 0x4c, 0x79, 0x77, 0x4, 0xf1, 0x0, 0x5, 0xad, 0x2f, 0x72, 0x3d, 0x95, + 0xe5, 0x8, 0x50, 0x48, 0x2e, 0x80, 0x5d, 0x54, 0x67, 0xf9, 0x41, 0xf1, 0x1d, 0xb6, 0x86, + 0x6, 0x73, 0xa, 0xaf, 0x99, 0x7d, 0x2c, 0x30, 0xa6, 0xc9, 0xbc, 0x7d, 0x39, 0x16, 0x3, + 0x55, 0x85, 0x63, 0xe8, 0x69, 0x36, 0x2a, 0xc2, 0xba, 0x5b, 0xf, 0x49, 0x1d, 0x2, 0xb4, + 0xe1, 0x12, 0xf1, 0xe6, 0x9b, 0xaf, 0xd4, 0x78, 0xd9, 0xaf, 0x7b, 0x5f, 0x50, 0xa5, 0x86, + 0x32, 0xbc, 0x36, 0xe4, 0x96, 0x11, 0xef, 0xf8, 0xb4, 0xd4, 0x91, 0xf7, 0xd7, 0x43, 0x15, + 0x28, 0x3, 0x1e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x5d, 0x35, 0x74, 0xc4, + 0xd9, 0x9c, 0x8, 0xef, 0x95, 0x6, 0x19, 0xbe, 0x72, 0xbf, 0xa1, 0xd5, 0xa, 0xe3, 0xc1, + 0x53, 0xd1, 0xf3, 0xf, 0x64, 0xbc, 0x1a, 0xc0, 0x8d, 0xe9, 0x9e, 0xa5, 0x56, 0x3, 0x0, 0x2, + 0x4, 0x0, 0x2, 0x3a, 0xa, 0x34, 0xc8, 0xd, 0xdb, 0x3e, 0xac, 0x5c, 0xd5, 0x92, 0x38, 0x30, + 0x81, 0x4d, 0x72, 0xf9, 0xde, 0x9, 0x6b, 0xca, 0x74, 0x87, 0x79, 0xda, 0x39, 0x7a, 0xa3, + 0xb7, 0x71, 0xfe, 0x7e, 0x40, 0xc6, 0x41, 0x1a, 0xea, 0x8, 0x2e, 0x2c, 0x5d, 0x74, 0x34, + 0x73, 0x68, 0x67, 0x7d, 0xb6, 0x95, 0x45, 0x12, 0x62, 0x37, 0xd5, 0xed, 0x78, 0xfa, 0xa0, + 0x84, 0x63, 0x52, 0xf5, 0x38, 0x3f, 0x95, 0x3, 0x0, 0xfd, 0xb7, 0x19, 0xd1, 0x24, 0xce, + 0xff, 0x58, 0x6, 0xe, 0xf5, 0x8d, 0x94, 0xa, 0x75, 0xe4, 0x3d, 0x13, 0x9d, 0x55, 0xa5, + 0xe4, 0xd3, 0x26, 0x4d, 0xc9, 0xeb, 0x4f, 0x77, 0x3b, 0xff, 0xc5, 0x72, 0x90, 0x19, 0xe4, + 0x7e, 0xd2, 0x7e, 0xf5, 0x1, 0x0, 0x0, 0x0, 0x64, 0x20, 0xcc, 0x42, 0x1e, 0x11, 0x89, 0x80, + 0x5c, 0x8c, 0xec, 0x8, 0x9d, 0x74, 0xc1, 0x98, 0xf, 0x79, 0xc0, 0x69, 0x0, 0x5a, 0x21, + 0xae, 0x40, 0xa7, 0xe5, 0x8e, 0x68, 0x77, 0xa8, 0x10, 0x7b, 0x4, 0x9, 0x1a, 0x9a, 0x97, + 0x1, 0x2, 0x90, 0xe5, 0x10, 0xa2, 0x10, 0x60, 0xad, 0xa3, 0x39, 0x71, 0xd, 0xd, 0xdc, 0x43, + 0xe4, 0x46, 0x0, 0x6c, 0x5b, 0xc9, 0x38, 0x64, 0xda, 0xfb, 0x3, 0xcf, 0x4b, 0xa4, 0x72, + 0xbe, 0xdf, 0x5c, 0xa7, 0x1, 0x0, 0x47, 0xe7, 0xd3, 0x5d, 0x93, 0xe4, 0xb5, 0x62, 0x8e, + 0xaf, 0xd3, 0x36, 0xd, 0x65, 0x25, 0x89, 0x52, 0xf4, 0xd9, 0x57, 0x5e, 0xac, 0x1b, 0x1f, + 0x18, 0xee, 0x18, 0x51, 0x29, 0x71, 0x82, 0x93, 0xb6, 0xd7, 0x62, 0x2b, 0x1e, 0xdd, 0x1f, + 0x20, 0x1, 0x0, 0x0, 0x0, 0x40, 0xe7, 0xa, 0x36, 0xe2, 0xce, 0x51, 0xd3, 0x1d, 0x4c, 0xf5, + 0xd6, 0x73, 0x1f, 0xa6, 0x37, 0x38, 0x64, 0x81, 0x27, 0xdb, 0x83, 0x37, 0x15, 0xd3, 0x96, + 0x52, 0xd8, 0x6d, 0x92, 0x7d, 0x48, 0x88, 0x3, 0x0, 0x1, 0x0, 0x2, 0x0, 0x3, 0x0, 0x5, 0x0, + 0x1, 0x2, 0x3, 0x4, 0x5, ]; // Making sure that @@ -939,17 +938,14 @@ mod test { genesis.clone().consensus_commit().to_vec() ); - let mut encoder = std::io::Cursor::new(vec![]); + let mut encoder = vec![]; genesis.schema_id.strict_encode(&mut encoder).unwrap(); encoder.write_all(GENESIS_HASH_MAINNET).unwrap(); genesis.metadata.strict_encode(&mut encoder).unwrap(); genesis.assignments.strict_encode(&mut encoder).unwrap(); genesis.valencies.strict_encode(&mut encoder).unwrap(); genesis.script.strict_encode(&mut encoder).unwrap(); - assert_eq!( - genesis.consensus_commit(), - NodeId::commit(&encoder.into_inner()) - ); + assert_eq!(genesis.consensus_commit(), NodeId::commit(&encoder)); let transition = Transition { transition_type: Default::default(), From a95bca7439360461881bf66078909dc03cf0e211 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Wed, 30 Sep 2020 22:56:21 +0200 Subject: [PATCH 13/13] Fixing Chains strict encode/decode bug --- src/bp/chain.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bp/chain.rs b/src/bp/chain.rs index dbd12715..8e1340bb 100644 --- a/src/bp/chain.rs +++ b/src/bp/chain.rs @@ -710,14 +710,14 @@ impl From for Chain { match params { p if p == Chain::Mainnet.chain_params() => Chain::Mainnet, p if p == Chain::Testnet3.chain_params() => Chain::Testnet3, + p if p == Chain::Signet.chain_params() => Chain::Signet, + p if p == Chain::LiquidV1.chain_params() => Chain::LiquidV1, p if p == Chain::Regtest(p.genesis_hash).chain_params() => { Chain::Regtest(p.genesis_hash) } - p if p == Chain::Signet.chain_params() => Chain::Signet, p if p == Chain::SignetCustom(p.genesis_hash).chain_params() => { Chain::SignetCustom(p.genesis_hash) } - p if p == Chain::LiquidV1.chain_params() => Chain::LiquidV1, p => Chain::Other(p), } }