From b65cf9ec35a4748862dd02b59ca72fb6b7370692 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Mon, 18 Dec 2023 19:37:20 +0100 Subject: [PATCH] containers: make Batch deterministic --- src/containers/mod.rs | 2 +- src/containers/partials.rs | 36 +++++++++++++++++++++++++++--------- src/persistence/inventory.rs | 8 ++++---- 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/containers/mod.rs b/src/containers/mod.rs index 829946a2..43dc5250 100644 --- a/src/containers/mod.rs +++ b/src/containers/mod.rs @@ -42,6 +42,6 @@ pub use bindle::{Bindle, BindleContent, BindleParseError, LoadError, UniversalBi pub use certs::{Cert, ContentId, ContentSigs, Identity}; pub use consignment::{Consignment, Contract, Transfer}; pub use disclosure::Disclosure; -pub use partials::{Batch, BatchItem, CloseMethodSet, Fascia}; +pub use partials::{Batch, CloseMethodSet, Fascia, TransitionInfo}; pub use seal::{BuilderSeal, TerminalSeal, VoutSeal}; pub use util::{ContainerVer, Terminal, XchainOutpoint}; diff --git a/src/containers/partials.rs b/src/containers/partials.rs index 3591d89e..9e518031 100644 --- a/src/containers/partials.rs +++ b/src/containers/partials.rs @@ -19,7 +19,9 @@ // See the License for the specific language governing permissions and // limitations under the License. +use std::cmp::Ordering; use std::collections::BTreeMap; +use std::hash::{Hash, Hasher}; use std::ops::{BitOr, BitOrAssign}; use std::vec; @@ -100,7 +102,7 @@ impl CloseMethodSet { pub fn has_opret_first(self) -> bool { matches!(self, Self::OpretFirst | Self::Both) } } -#[derive(Clone, PartialEq, Eq, Hash, Debug)] +#[derive(Clone, Eq, Debug)] #[derive(StrictType, StrictEncode, StrictDecode)] #[strict_type(lib = LIB_NAME_RGB_STD)] #[cfg_attr( @@ -108,18 +110,34 @@ impl CloseMethodSet { derive(Serialize, Deserialize), serde(crate = "serde_crate", rename_all = "camelCase") )] -pub struct BatchItem { +pub struct TransitionInfo { pub id: OpId, pub inputs: Confined, 1, U24>, pub transition: Transition, pub methods: CloseMethodSet, } -impl StrictDumb for BatchItem { +impl StrictDumb for TransitionInfo { fn strict_dumb() -> Self { Self::new(strict_dumb!(), [strict_dumb!()]).unwrap() } } -impl BatchItem { +impl PartialEq for TransitionInfo { + fn eq(&self, other: &Self) -> bool { self.id.eq(&other.id) } +} + +impl Ord for TransitionInfo { + fn cmp(&self, other: &Self) -> Ordering { self.id.cmp(&other.id) } +} + +impl PartialOrd for TransitionInfo { + fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } +} + +impl Hash for TransitionInfo { + fn hash(&self, state: &mut H) { state.write(self.id.as_slice()) } +} + +impl TransitionInfo { pub fn new( transition: Transition, seals: impl AsRef<[OutputSeal]>, @@ -139,7 +157,7 @@ impl BatchItem { }) }) .expect("confinement guarantees at least one item"); - Ok(BatchItem { + Ok(TransitionInfo { id: transition.id(), inputs, transition, @@ -160,16 +178,16 @@ impl BatchItem { serde(crate = "serde_crate", rename_all = "camelCase") )] pub struct Batch { - pub main: BatchItem, - pub blanks: Confined, 0, { U24 - 1 }>, + pub main: TransitionInfo, + pub blanks: Confined, 0, { U24 - 1 }>, } impl StrictSerialize for Batch {} impl StrictDeserialize for Batch {} impl IntoIterator for Batch { - type Item = BatchItem; - type IntoIter = vec::IntoIter; + type Item = TransitionInfo; + type IntoIter = vec::IntoIter; fn into_iter(self) -> Self::IntoIter { let mut vec = self.blanks.into_inner(); diff --git a/src/persistence/inventory.rs b/src/persistence/inventory.rs index cf05f94c..0810a1d5 100644 --- a/src/persistence/inventory.rs +++ b/src/persistence/inventory.rs @@ -40,8 +40,8 @@ use strict_encoding::TypeName; use crate::accessors::{BundleExt, MergeRevealError, RevealError}; use crate::containers::{ - Batch, BatchItem, Bindle, BuilderSeal, Cert, Consignment, ContentId, Contract, Fascia, - Terminal, Transfer, + Batch, Bindle, BuilderSeal, Cert, Consignment, ContentId, Contract, Fascia, Terminal, Transfer, + TransitionInfo, }; use crate::interface::{ BuilderError, ContractIface, Iface, IfaceId, IfaceImpl, IfacePair, IfaceWrapper, @@ -834,11 +834,11 @@ pub trait Inventory: Deref { } let transition = blank_builder.complete_transition(contract_id)?; - blanks.push(BatchItem::new(transition, outputs)?)?; + blanks.push(TransitionInfo::new(transition, outputs)?)?; } Ok(Batch { - main: BatchItem::new(main_transition, main_inputs)?, + main: TransitionInfo::new(main_transition, main_inputs)?, blanks, }) }