From 9ff603d2956c2ca8a2bf3f4f60896b16805319c5 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Sat, 6 Jan 2024 13:17:22 +0100 Subject: [PATCH 1/7] contract: optimize assignment traits --- src/contract/contract.rs | 41 +++++++++++++++++++++++++--------------- src/contract/mod.rs | 3 +-- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/src/contract/contract.rs b/src/contract/contract.rs index 6eeba235..a957b66b 100644 --- a/src/contract/contract.rs +++ b/src/contract/contract.rs @@ -92,7 +92,13 @@ impl FromStr for Opout { } } -#[derive(Clone, Eq, Debug)] +/// Trait used by contract state. Unlike [`ExposedState`] it doesn't allow +/// concealment of the state, i.e. may contain incomplete data without blinding +/// factors, asset tags etc. +pub trait KnownState: Debug + StrictDumb + StrictEncode + StrictDecode + Ord + Clone {} +impl KnownState for S {} + +#[derive(Copy, Clone, Eq, Debug)] #[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] #[strict_type(lib = LIB_NAME_RGB)] #[cfg_attr( @@ -100,14 +106,14 @@ impl FromStr for Opout { derive(Serialize, Deserialize), serde(crate = "serde_crate", rename_all = "camelCase") )] -pub struct OutputAssignment { +pub struct OutputAssignment { pub opout: Opout, pub seal: XOutputSeal, pub state: State, pub witness: Option, } -impl PartialEq for OutputAssignment { +impl PartialEq for OutputAssignment { fn eq(&self, other: &Self) -> bool { if self.opout == other.opout && (self.seal != other.seal || @@ -127,11 +133,11 @@ impl PartialEq for OutputAssignment { } } -impl PartialOrd for OutputAssignment { +impl PartialOrd for OutputAssignment { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } -impl Ord for OutputAssignment { +impl Ord for OutputAssignment { fn cmp(&self, other: &Self) -> Ordering { if self == other { return Ordering::Equal; @@ -140,7 +146,7 @@ impl Ord for OutputAssignment { } } -impl OutputAssignment { +impl OutputAssignment { /// # Panics /// /// If the processing is done on invalid stash data, the seal is @@ -185,6 +191,16 @@ impl OutputAssignment { witness: None, } } + + pub fn transmute(self) -> OutputAssignment + where S: From { + OutputAssignment { + opout: self.opout, + seal: self.seal, + state: self.state.into(), + witness: self.witness, + } + } } #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] @@ -234,11 +250,6 @@ impl GlobalOrd { } } -pub type RightsOutput = OutputAssignment; -pub type FungibleOutput = OutputAssignment; -pub type DataOutput = OutputAssignment; -pub type AttachOutput = OutputAssignment; - /// Contract history accumulates raw data from the contract history, extracted /// from a series of consignments over the time. It does consensus ordering of /// the state data, but it doesn't interpret or validates the state against the @@ -262,10 +273,10 @@ pub struct ContractHistory { contract_id: ContractId, #[getter(skip)] global: TinyOrdMap>, - rights: LargeOrdSet, - fungibles: LargeOrdSet, - data: LargeOrdSet, - attach: LargeOrdSet, + rights: LargeOrdSet>, + fungibles: LargeOrdSet>, + data: LargeOrdSet>, + attach: LargeOrdSet>, } impl ContractHistory { diff --git a/src/contract/mod.rs b/src/contract/mod.rs index dd37a503..19ae0204 100644 --- a/src/contract/mod.rs +++ b/src/contract/mod.rs @@ -42,8 +42,7 @@ pub use assignments::{ pub use attachment::{AttachId, ConcealedAttach, RevealedAttach}; pub use bundle::{BundleId, TransitionBundle, Vin}; pub use contract::{ - AttachOutput, ContractHistory, ContractState, DataOutput, FungibleOutput, GlobalOrd, Opout, - OpoutParseError, OutputAssignment, RightsOutput, + ContractHistory, ContractState, GlobalOrd, KnownState, Opout, OpoutParseError, OutputAssignment, }; pub use data::{ConcealedData, RevealedData, VoidState}; pub use fungible::{ From f1454499c2a9eda8e85ae473b954d7f8c227b930 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Sat, 6 Jan 2024 13:23:05 +0100 Subject: [PATCH 2/7] contract: add AssignmentWitness type --- src/contract/contract.rs | 34 +++++++++++++++++++++++++++++++--- src/contract/mod.rs | 3 ++- src/stl.rs | 2 +- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/contract/contract.rs b/src/contract/contract.rs index a957b66b..41e509df 100644 --- a/src/contract/contract.rs +++ b/src/contract/contract.rs @@ -98,6 +98,34 @@ impl FromStr for Opout { pub trait KnownState: Debug + StrictDumb + StrictEncode + StrictDecode + Ord + Clone {} impl KnownState for S {} +#[derive(Copy, Clone, Eq, PartialEq, Debug, Display, From)] +#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] +#[strict_type(lib = LIB_NAME_RGB, tags = custom)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(crate = "serde_crate", rename_all = "camelCase") +)] +pub enum AssignmentWitness { + #[display("~")] + #[strict_type(tag = 0, dumb)] + Absent, + + #[from] + #[display(inner)] + #[strict_type(tag = 1)] + Present(WitnessId), +} + +impl From> for AssignmentWitness { + fn from(value: Option) -> Self { + match value { + None => AssignmentWitness::Absent, + Some(id) => AssignmentWitness::Present(id), + } + } +} + #[derive(Copy, Clone, Eq, Debug)] #[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] #[strict_type(lib = LIB_NAME_RGB)] @@ -110,7 +138,7 @@ pub struct OutputAssignment { pub opout: Opout, pub seal: XOutputSeal, pub state: State, - pub witness: Option, + pub witness: AssignmentWitness, } impl PartialEq for OutputAssignment { @@ -166,7 +194,7 @@ impl OutputAssignment { match anchor's chain", ), state, - witness: Some(witness_id), + witness: witness_id.into(), } } @@ -188,7 +216,7 @@ impl OutputAssignment { information since it comes from genesis or extension", ), state, - witness: None, + witness: AssignmentWitness::Absent, } } diff --git a/src/contract/mod.rs b/src/contract/mod.rs index 19ae0204..6e461992 100644 --- a/src/contract/mod.rs +++ b/src/contract/mod.rs @@ -42,7 +42,8 @@ pub use assignments::{ pub use attachment::{AttachId, ConcealedAttach, RevealedAttach}; pub use bundle::{BundleId, TransitionBundle, Vin}; pub use contract::{ - ContractHistory, ContractState, GlobalOrd, KnownState, Opout, OpoutParseError, OutputAssignment, + AssignmentWitness, ContractHistory, ContractState, GlobalOrd, KnownState, Opout, + OpoutParseError, OutputAssignment, }; pub use data::{ConcealedData, RevealedData, VoidState}; pub use fungible::{ diff --git a/src/stl.rs b/src/stl.rs index 81ca5f38..38a1b5b8 100644 --- a/src/stl.rs +++ b/src/stl.rs @@ -32,7 +32,7 @@ use crate::{AnchoredBundle, ContractState, Extension, Genesis, SubSchema, LIB_NA /// Strict types id for the library providing data types for RGB consensus. pub const LIB_ID_RGB: &str = - "urn:ubideco:stl:2PcZtrPrfQCu27qw8b4Wz4cEqUn2PpgSkDHwF4qVyyrq#russian-child-member"; + "urn:ubideco:stl:3VRk6Jd3VaDKff4gYasqFSCvq5xzLygbRunhhGJbF7Bh#boston-pony-goblin"; fn _rgb_core_stl() -> Result { LibBuilder::new(libname!(LIB_NAME_RGB), tiny_bset! { From 58503d9edf7c4ec2c56ab540d5993bb39e48e20a Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Sat, 6 Jan 2024 15:09:26 +0100 Subject: [PATCH 3/7] contract: blind data state with u128 number --- src/contract/contract.rs | 11 ++++--- src/contract/data.rs | 63 +++++++++++++++++++++++++++++----------- src/contract/mod.rs | 2 +- src/stl.rs | 2 +- src/validation/logic.rs | 2 +- src/validation/state.rs | 2 +- src/vm/op_contract.rs | 10 +++---- 7 files changed, 62 insertions(+), 30 deletions(-) diff --git a/src/contract/contract.rs b/src/contract/contract.rs index 41e509df..8433378f 100644 --- a/src/contract/contract.rs +++ b/src/contract/contract.rs @@ -34,10 +34,10 @@ use amplify::hex; use strict_encoding::{StrictDecode, StrictDumb, StrictEncode}; use crate::{ - Assign, AssignmentType, Assignments, AssignmentsRef, ContractId, ExposedSeal, ExposedState, - Extension, Genesis, GlobalStateType, OpId, Operation, RevealedAttach, RevealedData, - RevealedValue, SchemaId, SubSchema, Transition, TypedAssigns, VoidState, WitnessAnchor, - WitnessId, XChain, XOutputSeal, LIB_NAME_RGB, + Assign, AssignmentType, Assignments, AssignmentsRef, ContractId, DataState, ExposedSeal, + ExposedState, Extension, Genesis, GlobalStateType, OpId, Operation, RevealedAttach, + RevealedData, RevealedValue, SchemaId, SubSchema, Transition, TypedAssigns, VoidState, + WitnessAnchor, WitnessId, XChain, XOutputSeal, LIB_NAME_RGB, }; #[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Display)] @@ -98,6 +98,9 @@ impl FromStr for Opout { pub trait KnownState: Debug + StrictDumb + StrictEncode + StrictDecode + Ord + Clone {} impl KnownState for S {} +impl KnownState for () {} +impl KnownState for DataState {} + #[derive(Copy, Clone, Eq, PartialEq, Debug, Display, From)] #[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] #[strict_type(lib = LIB_NAME_RGB, tags = custom)] diff --git a/src/contract/data.rs b/src/contract/data.rs index 6bd85a01..47a62e13 100644 --- a/src/contract/data.rs +++ b/src/contract/data.rs @@ -20,12 +20,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -use core::fmt::{self, Debug, Display, Formatter}; +use core::fmt::{self, Debug, Formatter}; +use std::cmp::Ordering; +use std::io::Write; -use amplify::confinement::SmallVec; +use amplify::confinement::SmallBlob; use amplify::hex::ToHex; use amplify::{Bytes32, Wrapper}; -use commit_verify::{CommitVerify, Conceal, StrictEncodedProtocol}; +use commit_verify::{CommitEncode, CommitVerify, Conceal, StrictEncodedProtocol}; use strict_encoding::{StrictSerialize, StrictType}; use super::{ConfidentialState, ExposedState}; @@ -57,13 +59,25 @@ impl Conceal for VoidState { fn conceal(&self) -> Self::Concealed { *self } } -#[derive(Wrapper, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, From)] -#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] +#[derive(Wrapper, Clone, Debug, PartialOrd, Ord, PartialEq, Eq, Hash, From, Display, Default)] +#[display(LowerHex)] +#[wrapper(Deref, AsSlice, BorrowSlice, Hex)] +#[derive(StrictType, StrictEncode, StrictDecode)] #[strict_type(lib = LIB_NAME_RGB)] #[derive(CommitEncode)] -#[commit_encode(conceal)] +#[commit_encode(strategy = strict)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(crate = "serde_crate"))] -pub struct RevealedData(SmallVec); +pub struct DataState(SmallBlob); +impl StrictSerialize for DataState {} + +#[derive(Clone, Eq, PartialEq, Hash)] +#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] +#[strict_type(lib = LIB_NAME_RGB)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(crate = "serde_crate"))] +pub struct RevealedData { + pub value: DataState, + pub salt: u128, +} impl ExposedState for RevealedData { type Confidential = ConcealedData; @@ -73,24 +87,39 @@ impl ExposedState for RevealedData { impl Conceal for RevealedData { type Concealed = ConcealedData; + fn conceal(&self) -> Self::Concealed { ConcealedData::commit(self) } } -impl StrictSerialize for RevealedData {} +impl CommitEncode for RevealedData { + fn commit_encode(&self, e: &mut impl Write) { + e.write_all(&self.value).ok(); + e.write_all(&self.salt.to_le_bytes()).ok(); + } +} -impl Debug for RevealedData { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - let val = match String::from_utf8(self.0.to_inner()) { - Ok(s) => s, - Err(_) => self.0.to_hex(), - }; +impl PartialOrd for RevealedData { + fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } +} - f.debug_tuple("RevealedData").field(&val).finish() +impl Ord for RevealedData { + fn cmp(&self, other: &Self) -> Ordering { + match self.value.cmp(&other.value) { + Ordering::Equal => self.salt.cmp(&other.salt), + other => other, + } } } -impl Display for RevealedData { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_str(&self.as_ref().to_hex()) } +impl Debug for RevealedData { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + let val = String::from_utf8(self.value.to_vec()).unwrap_or_else(|_| self.value.to_hex()); + + f.debug_struct("RevealedData") + .field("value", &val) + .field("salt", &self.salt) + .finish() + } } /// Confidential version of an structured state data. diff --git a/src/contract/mod.rs b/src/contract/mod.rs index 6e461992..2022159f 100644 --- a/src/contract/mod.rs +++ b/src/contract/mod.rs @@ -45,7 +45,7 @@ pub use contract::{ AssignmentWitness, ContractHistory, ContractState, GlobalOrd, KnownState, Opout, OpoutParseError, OutputAssignment, }; -pub use data::{ConcealedData, RevealedData, VoidState}; +pub use data::{ConcealedData, DataState, RevealedData, VoidState}; pub use fungible::{ AssetTag, BlindingFactor, BlindingParseError, ConcealedValue, FungibleState, InvalidFieldElement, NoiseDumb, PedersenCommitment, RangeProof, RangeProofError, RevealedValue, diff --git a/src/stl.rs b/src/stl.rs index 38a1b5b8..4d173aa6 100644 --- a/src/stl.rs +++ b/src/stl.rs @@ -32,7 +32,7 @@ use crate::{AnchoredBundle, ContractState, Extension, Genesis, SubSchema, LIB_NA /// Strict types id for the library providing data types for RGB consensus. pub const LIB_ID_RGB: &str = - "urn:ubideco:stl:3VRk6Jd3VaDKff4gYasqFSCvq5xzLygbRunhhGJbF7Bh#boston-pony-goblin"; + "urn:ubideco:stl:141hHBYBr2mzKyskZbRuwazYC9ki5x9ZrrzQHLbgBzx#oscar-rufus-tractor"; fn _rgb_core_stl() -> Result { LibBuilder::new(libname!(LIB_NAME_RGB), tiny_bset! { diff --git a/src/validation/logic.rs b/src/validation/logic.rs index b0e1007c..1c0e25db 100644 --- a/src/validation/logic.rs +++ b/src/validation/logic.rs @@ -260,7 +260,7 @@ impl Schema { for data in set { if self .type_system - .strict_deserialize_type(*sem_id, data.as_ref()) + .strict_deserialize_type(*sem_id, data.value.as_ref()) .is_err() { status.add_failure(validation::Failure::SchemaInvalidGlobalValue( diff --git a/src/validation/state.rs b/src/validation/state.rs index df5d8473..08131395 100644 --- a/src/validation/state.rs +++ b/src/validation/state.rs @@ -98,7 +98,7 @@ impl StateSchema { (StateSchema::Fungible(_), StateData::Fungible(_)) => {} (StateSchema::Structured(sem_id), StateData::Structured(data)) => { if type_system - .strict_deserialize_type(*sem_id, data.as_ref()) + .strict_deserialize_type(*sem_id, data.value.as_ref()) .is_err() { status.add_failure(validation::Failure::SchemaInvalidOwnedValue( diff --git a/src/vm/op_contract.rs b/src/vm/op_contract.rs index 660bcb9f..b8676913 100644 --- a/src/vm/op_contract.rs +++ b/src/vm/op_contract.rs @@ -260,7 +260,7 @@ impl InstructionSet for ContractOp { else { fail!() }; - let state = state.map(|s| s.to_inner()); + let state = state.map(|s| s.value.as_inner()); regs.set_s(*reg, state); } ContractOp::LdS(state_type, index, reg) => { @@ -271,7 +271,7 @@ impl InstructionSet for ContractOp { else { fail!() }; - let state = state.map(|s| s.to_inner()); + let state = state.map(|s| s.value.into_inner()); regs.set_s(*reg, state); } ContractOp::LdF(state_type, index, reg) => { @@ -292,7 +292,7 @@ impl InstructionSet for ContractOp { else { fail!() }; - regs.set_s(*reg, Some(state.as_inner())); + regs.set_s(*reg, Some(state.value.as_inner())); } ContractOp::LdC(_state_type, _index, _reg) => { // TODO: implement global contract state @@ -321,11 +321,11 @@ impl InstructionSet for ContractOp { if sum.len() != 1 { fail!() } - if sum[0].as_inner().len() != 8 { + if sum[0].value.as_inner().len() != 8 { fail!() } let mut bytes = [0u8; 8]; - bytes.copy_from_slice(sum[0].as_inner()); + bytes.copy_from_slice(sum[0].value.as_inner()); let sum = u64::from_le_bytes(bytes); let Some(tag) = context.asset_tags.get(owned_state) else { From 6747267ddea1b1a5cada850ac1e0ec54deea674d Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Sat, 6 Jan 2024 15:50:57 +0100 Subject: [PATCH 4/7] contract: refactor data and attach constructors to match fungible state --- src/contract/attachment.rs | 27 +++++++++++++++++++++------ src/contract/data.rs | 21 +++++++++++++++++++++ src/contract/fungible.rs | 16 ++++++---------- 3 files changed, 48 insertions(+), 16 deletions(-) diff --git a/src/contract/attachment.rs b/src/contract/attachment.rs index 1545f1e1..248a3244 100644 --- a/src/contract/attachment.rs +++ b/src/contract/attachment.rs @@ -24,7 +24,7 @@ use std::str::FromStr; use amplify::{ByteArray, Bytes32}; use baid58::{Baid58ParseError, Chunking, FromBaid58, ToBaid58, CHUNKING_32}; -use bp::secp256k1::rand::{thread_rng, RngCore}; +use bp::secp256k1::rand::{random, Rng, RngCore}; use commit_verify::{CommitVerify, Conceal, StrictEncodedProtocol}; use strict_encoding::StrictEncode; @@ -83,13 +83,28 @@ pub struct RevealedAttach { } impl RevealedAttach { - /// Creates new revealed attachment for the attachment id and MIME type. - /// Uses `thread_rng` to initialize [`RevealedAttach::salt`]. - pub fn new(id: AttachId, media_type: MediaType) -> Self { + /// Constructs new state using the provided value using random blinding + /// factor. + pub fn new_random_salt(id: AttachId, media_type: impl Into) -> Self { + Self::with_salt(id, media_type, random()) + } + + /// Constructs new state using the provided value and random generator for + /// creating blinding factor. + pub fn with_rng( + id: AttachId, + media_type: impl Into, + rng: &mut R, + ) -> Self { + Self::with_salt(id, media_type, rng.next_u64()) + } + + /// Convenience constructor. + pub fn with_salt(id: AttachId, media_type: impl Into, salt: u64) -> Self { Self { id, - media_type, - salt: thread_rng().next_u64(), + media_type: media_type.into(), + salt, } } } diff --git a/src/contract/data.rs b/src/contract/data.rs index 47a62e13..e9d4bffc 100644 --- a/src/contract/data.rs +++ b/src/contract/data.rs @@ -27,6 +27,7 @@ use std::io::Write; use amplify::confinement::SmallBlob; use amplify::hex::ToHex; use amplify::{Bytes32, Wrapper}; +use bp::secp256k1::rand::{random, Rng, RngCore}; use commit_verify::{CommitEncode, CommitVerify, Conceal, StrictEncodedProtocol}; use strict_encoding::{StrictSerialize, StrictType}; @@ -79,6 +80,26 @@ pub struct RevealedData { pub salt: u128, } +impl RevealedData { + /// Constructs new state using the provided value using random blinding + /// factor. + pub fn new_random_salt(value: impl Into) -> Self { Self::with_salt(value, random()) } + + /// Constructs new state using the provided value and random generator for + /// creating blinding factor. + pub fn with_rng(value: impl Into, rng: &mut R) -> Self { + Self::with_salt(value, rng.gen()) + } + + /// Convenience constructor. + pub fn with_salt(value: impl Into, salt: u128) -> Self { + Self { + value: value.into(), + salt, + } + } +} + impl ExposedState for RevealedData { type Confidential = ConcealedData; fn state_type(&self) -> StateType { StateType::Structured } diff --git a/src/contract/fungible.rs b/src/contract/fungible.rs index f6cfe9b4..83847f2c 100644 --- a/src/contract/fungible.rs +++ b/src/contract/fungible.rs @@ -290,7 +290,7 @@ impl RevealedValue { /// Constructs new state using the provided value and random generator for /// creating blinding factor. - pub fn with_random_blinding( + pub fn with_rng( value: impl Into, rng: &mut R, tag: AssetTag, @@ -531,7 +531,7 @@ mod test { fn commitments_determinism() { let tag = AssetTag::from_byte_array([1u8; 32]); - let value = RevealedValue::with_random_blinding(15, &mut thread_rng(), tag); + let value = RevealedValue::with_rng(15, &mut thread_rng(), tag); let generators = (0..10) .map(|_| { @@ -548,15 +548,11 @@ mod test { let mut r = thread_rng(); let tag = AssetTag::from_byte_array([1u8; 32]); - let a = PedersenCommitment::commit(&RevealedValue::with_random_blinding(15, &mut r, tag)) - .into_inner(); - let b = PedersenCommitment::commit(&RevealedValue::with_random_blinding(7, &mut r, tag)) - .into_inner(); + let a = PedersenCommitment::commit(&RevealedValue::with_rng(15, &mut r, tag)).into_inner(); + let b = PedersenCommitment::commit(&RevealedValue::with_rng(7, &mut r, tag)).into_inner(); - let c = PedersenCommitment::commit(&RevealedValue::with_random_blinding(13, &mut r, tag)) - .into_inner(); - let d = PedersenCommitment::commit(&RevealedValue::with_random_blinding(9, &mut r, tag)) - .into_inner(); + let c = PedersenCommitment::commit(&RevealedValue::with_rng(13, &mut r, tag)).into_inner(); + let d = PedersenCommitment::commit(&RevealedValue::with_rng(9, &mut r, tag)).into_inner(); assert!(!secp256k1_zkp::verify_commitments_sum_to_equal(SECP256K1, &[a, b], &[c, d])) } From 6b93ada6d5668458b0c4dccdde132f56f5e662cc Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Sat, 6 Jan 2024 16:07:05 +0100 Subject: [PATCH 5/7] contract: add From for DataState --- src/contract/data.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/contract/data.rs b/src/contract/data.rs index e9d4bffc..a4eed1d5 100644 --- a/src/contract/data.rs +++ b/src/contract/data.rs @@ -71,6 +71,10 @@ impl Conceal for VoidState { pub struct DataState(SmallBlob); impl StrictSerialize for DataState {} +impl From for DataState { + fn from(data: RevealedData) -> Self { data.value } +} + #[derive(Clone, Eq, PartialEq, Hash)] #[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] #[strict_type(lib = LIB_NAME_RGB)] From b1232f5f77ff253bbe79bdcee04a2cf0d4ef0c05 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Sat, 6 Jan 2024 16:25:46 +0100 Subject: [PATCH 6/7] contract: relax Ord requirement for KnownState trait --- src/contract/contract.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/contract/contract.rs b/src/contract/contract.rs index 8433378f..b4a8fd8f 100644 --- a/src/contract/contract.rs +++ b/src/contract/contract.rs @@ -95,7 +95,7 @@ impl FromStr for Opout { /// Trait used by contract state. Unlike [`ExposedState`] it doesn't allow /// concealment of the state, i.e. may contain incomplete data without blinding /// factors, asset tags etc. -pub trait KnownState: Debug + StrictDumb + StrictEncode + StrictDecode + Ord + Clone {} +pub trait KnownState: Debug + StrictDumb + StrictEncode + StrictDecode + Eq + Clone {} impl KnownState for S {} impl KnownState for () {} From 2b59903039770df4766c9681bc74691382308ef5 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Sun, 7 Jan 2024 13:26:45 +0100 Subject: [PATCH 7/7] contract: impl Hash and Ord for AssignmentWitness --- src/contract/contract.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/contract/contract.rs b/src/contract/contract.rs index b4a8fd8f..ec33aea2 100644 --- a/src/contract/contract.rs +++ b/src/contract/contract.rs @@ -101,7 +101,7 @@ impl KnownState for S {} impl KnownState for () {} impl KnownState for DataState {} -#[derive(Copy, Clone, Eq, PartialEq, Debug, Display, From)] +#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Display, From)] #[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] #[strict_type(lib = LIB_NAME_RGB, tags = custom)] #[cfg_attr(