From 15f6a574bb8356c69620aefd9dc9c914ad9910bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zoe=20Faltib=C3=A0?= Date: Wed, 7 Jun 2023 15:33:40 +0200 Subject: [PATCH 1/5] change rgb20 issuedSupply to one_or_many --- std/src/interface/rgb20.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/std/src/interface/rgb20.rs b/std/src/interface/rgb20.rs index dac29b91..19a96d34 100644 --- a/std/src/interface/rgb20.rs +++ b/std/src/interface/rgb20.rs @@ -122,7 +122,7 @@ pub fn rgb20() -> Iface { fname!("spec") => GlobalIface::required(types.get("RGBContract.DivisibleAssetSpec")), fname!("terms") => GlobalIface::required(types.get("RGBContract.RicardianContract")), fname!("created") => GlobalIface::required(types.get("RGBContract.Timestamp")), - fname!("issuedSupply") => GlobalIface::none_or_many(types.get("RGB20.Amount")), + fname!("issuedSupply") => GlobalIface::one_or_many(types.get("RGB20.Amount")), fname!("burnedSupply") => GlobalIface::none_or_many(types.get("RGB20.Amount")), fname!("replacedSupply") => GlobalIface::none_or_many(types.get("RGB20.Amount")), }, From 1b1a9d2629e13a8f7b53a7c3bee9b3c734b0752f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zoe=20Faltib=C3=A0?= Date: Thu, 8 Jun 2023 11:21:30 +0200 Subject: [PATCH 2/5] export MediaRegName --- std/src/stl/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/std/src/stl/mod.rs b/std/src/stl/mod.rs index 5c79ea5c..31fe653a 100644 --- a/std/src/stl/mod.rs +++ b/std/src/stl/mod.rs @@ -27,7 +27,7 @@ mod chain; pub use chain::ProofOfReserves; pub(self) use error::Error; -pub use mime::MediaType; +pub use mime::{MediaType, MediaRegName}; pub use specs::{ AssetNaming, Details, DivisibleAssetSpec, Name, Precision, RicardianContract, Ticker, Timestamp, }; From 4f0a23626623b2720b36008a2e18cdb3c562cd3d Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Wed, 14 Jun 2023 15:58:20 +0200 Subject: [PATCH 3/5] iface: fix RGB20 tests --- std/tests/data/rgb20.rgba | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/std/tests/data/rgb20.rgba b/std/tests/data/rgb20.rgba index c65ade33..d3f7d92e 100644 --- a/std/tests/data/rgb20.rgba +++ b/std/tests/data/rgb20.rgba @@ -1,11 +1,11 @@ -----BEGIN RGB INTERFACE----- -Id: 7Rrqv5iVnTv3DquiK7FJmdVBy1nNYBuSbkXpXRunwZzy +Id: BR2fhPEKPtsjoEz2PDpBV4o24HCjvD1Dk4nHnaRx94fQ Name: RGB20 AAVSR0IyMAYMYnVybmVkU3VwcGx5AYiMWGVjOvE7lbfNGo2K8trB3BQLl3JR2dTa 88dRHI6EAAEHY3JlYXRlZAFZbno6DqNlnhAw8YtNZaO5E+5YUAf8914Lts3BacHA OwEADGlzc3VlZFN1cHBseQGIjFhlYzrxO5W3zRqNivLawdwUC5dyUdnU2vPHURyO -hAABDnJlcGxhY2VkU3VwcGx5AYiMWGVjOvE7lbfNGo2K8trB3BQLl3JR2dTa88dR +hAEBDnJlcGxhY2VkU3VwcGx5AYiMWGVjOvE7lbfNGo2K8trB3BQLl3JR2dTa88dR HI6EAAEEc3BlYwGZYk235CaSmVSTLt/I0melUpcCKTzVq8BWTm8iWzP68QEABXRl cm1zARjLlG8Sk88YDp143MZbxZtHL//+rfv1jbGYzIMo9ksBAQAFCmFzc2V0T3du ZXICAAABCWJ1cm5FcG9jaAEBAAAJYnVyblJpZ2h0AQEAARJpbmZsYXRpb25BbGxv From bedcb530be95322a614bcde59daf26bbf310519d Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Wed, 14 Jun 2023 16:08:03 +0200 Subject: [PATCH 4/5] chore: fix clippy warnings --- src/pay.rs | 3 ++- src/psbt/lnpbp4.rs | 2 +- src/psbt/rgb.rs | 4 +++- src/psbt/tapret.rs | 2 +- std/src/containers/bindle.rs | 2 +- std/src/containers/consignment.rs | 9 +++------ std/src/interface/builder.rs | 2 +- std/src/interface/iface.rs | 1 + std/src/interface/iimpl.rs | 1 + std/src/persistence/inventory.rs | 5 ++++- std/src/persistence/stock.rs | 1 + std/src/stl/mime.rs | 2 +- std/src/stl/mod.rs | 3 ++- std/src/stl/specs.rs | 3 +-- std/src/stl/stl.rs | 5 +++++ 15 files changed, 28 insertions(+), 17 deletions(-) diff --git a/src/pay.rs b/src/pay.rs index 63c03497..b681ebff 100644 --- a/src/pay.rs +++ b/src/pay.rs @@ -87,6 +87,7 @@ pub trait InventoryWallet: Inventory { /// /// 1. If PSBT output has BIP32 derivation information it belongs to our /// wallet - except when it matches address from the invoice. + #[allow(clippy::result_large_err, clippy::type_complexity)] fn pay( &mut self, invoice: RgbInvoice, @@ -142,7 +143,7 @@ pub trait InventoryWallet: Inventory { // NB: Here we assume that if output has derivation information it belongs to our wallet. .bip32_derivation .first_key_value() - .and_then(|(_, src)| src.1.into_iter().rev().skip(1).next()) + .and_then(|(_, src)| src.1.into_iter().rev().nth(1)) .copied() .map(u32::from) .and_then(|index| u8::try_from(index).ok()) diff --git a/src/psbt/lnpbp4.rs b/src/psbt/lnpbp4.rs index afa47027..0435c315 100644 --- a/src/psbt/lnpbp4.rs +++ b/src/psbt/lnpbp4.rs @@ -236,6 +236,6 @@ impl OutputLnpbp4 for Output { let key = ProprietaryKey::lnpbp4_min_tree_depth(); let val = vec![min_depth]; let prev = self.lnpbp4_min_tree_depth(); - self.proprietary.insert(key, val).and_then(|_| prev) + self.proprietary.insert(key, val).and(prev) } } diff --git a/src/psbt/rgb.rs b/src/psbt/rgb.rs index f736f049..318a6bf5 100644 --- a/src/psbt/rgb.rs +++ b/src/psbt/rgb.rs @@ -100,6 +100,7 @@ pub enum RgbPsbtError { InvalidTransition(SerializeError), } +#[allow(clippy::result_large_err)] pub trait RgbExt { fn rgb_contract_ids(&self) -> BTreeSet; @@ -165,7 +166,7 @@ impl RgbExt for Psbt { prop_key.subtype == PSBT_IN_RGB_CONSUMED_BY }) .map(|prop_key| &prop_key.key) - .filter_map(|key| ContractId::from_slice(key)) + .filter_map(ContractId::from_slice) }) .collect() } @@ -255,6 +256,7 @@ pub trait RgbInExt { /// /// If the input already contains [`PSBT_IN_RGB_NODE_ID`] key with the given /// `contract_id` but referencing different [`OpId`]. + #[allow(clippy::result_large_err)] fn set_rgb_consumer( &mut self, contract_id: ContractId, diff --git a/src/psbt/tapret.rs b/src/psbt/tapret.rs index 415a9bad..17917185 100644 --- a/src/psbt/tapret.rs +++ b/src/psbt/tapret.rs @@ -240,7 +240,7 @@ impl OutputTapret for Output { /// current crate. fn tapret_proof(&self) -> Option { let data = self.proprietary.get(&ProprietaryKey::tapret_proof())?; - let vec = Confined::try_from_iter(data.into_iter().copied()).ok()?; + let vec = Confined::try_from_iter(data.iter().copied()).ok()?; TapretPathProof::from_strict_serialized::(vec).ok() } } diff --git a/std/src/containers/bindle.rs b/std/src/containers/bindle.rs index 21acd186..363454fe 100644 --- a/std/src/containers/bindle.rs +++ b/std/src/containers/bindle.rs @@ -208,7 +208,7 @@ impl FromStr for Bindle { return Err(BindleParseError::WrongStructure); } let mut header_id = None; - while let Some(line) = lines.next() { + for line in lines.by_ref() { if line.is_empty() { break; } diff --git a/std/src/containers/consignment.rs b/std/src/containers/consignment.rs index b8493d15..463513fc 100644 --- a/std/src/containers/consignment.rs +++ b/std/src/containers/consignment.rs @@ -148,12 +148,9 @@ impl Consignment { pub fn contract_id(&self) -> ContractId { self.genesis.contract_id() } pub fn anchored_bundle(&self, bundle_id: BundleId) -> Option<&AnchoredBundle> { - for anchored_bundle in &self.bundles { - if anchored_bundle.bundle.bundle_id() == bundle_id { - return Some(anchored_bundle); - } - } - None + self.bundles + .iter() + .find(|anchored_bundle| anchored_bundle.bundle.bundle_id() == bundle_id) } pub fn validation_status(&self) -> Option<&validation::Status> { diff --git a/std/src/interface/builder.rs b/std/src/interface/builder.rs index 08f2baea..a880f814 100644 --- a/std/src/interface/builder.rs +++ b/std/src/interface/builder.rs @@ -443,7 +443,7 @@ impl OperationBuilder { let state = RevealedValue::new(value, &mut thread_rng()); match self.fungible.get_mut(&type_id) { Some(assignments) => { - assignments.insert(seal.into(), state.into())?; + assignments.insert(seal.into(), state)?; } None => { self.fungible diff --git a/std/src/interface/iface.rs b/std/src/interface/iface.rs index b5fe4fed..b324048c 100644 --- a/std/src/interface/iface.rs +++ b/std/src/interface/iface.rs @@ -62,6 +62,7 @@ impl ToBaid58<32> for IfaceId { impl FromBaid58<32> for IfaceId {} impl IfaceId { + #[allow(clippy::wrong_self_convention)] fn to_baid58_string(&self) -> String { format!("{}", self.to_baid58()) } } diff --git a/std/src/interface/iimpl.rs b/std/src/interface/iimpl.rs index e1f734b7..baea9e84 100644 --- a/std/src/interface/iimpl.rs +++ b/std/src/interface/iimpl.rs @@ -64,6 +64,7 @@ impl ToBaid58<32> for ImplId { impl FromBaid58<32> for ImplId {} impl ImplId { + #[allow(clippy::wrong_self_convention)] fn to_baid58_string(&self) -> String { format!("{}", self.to_baid58()) } } diff --git a/std/src/persistence/inventory.rs b/std/src/persistence/inventory.rs index 176c8acd..24281693 100644 --- a/std/src/persistence/inventory.rs +++ b/std/src/persistence/inventory.rs @@ -244,6 +244,7 @@ pub enum InventoryInconsistency { Stash(StashInconsistency), } +#[allow(clippy::result_large_err)] pub trait Inventory: Deref { type Stash: Stash; /// Error type which must indicate problems on data retrieval. @@ -406,6 +407,7 @@ pub trait Inventory: Deref { fn store_seal_secret(&mut self, seal: GraphSeal) -> Result<(), InventoryError>; fn seal_secrets(&mut self) -> Result, InventoryError>; + #[allow(clippy::type_complexity)] fn export_contract( &mut self, contract_id: ContractId, @@ -420,6 +422,7 @@ pub trait Inventory: Deref { // TODO: Add known sigs to the bindle } + #[allow(clippy::type_complexity)] fn transfer( &mut self, contract_id: ContractId, @@ -507,7 +510,7 @@ pub trait Inventory: Deref { .entry(id) .or_insert(self.anchored_bundle(id)?.clone()) .bundle - .reveal_transition(&transition)?; + .reveal_transition(transition)?; } let genesis = self.genesis(contract_id)?; diff --git a/std/src/persistence/stock.rs b/std/src/persistence/stock.rs index b33e51b2..13d55216 100644 --- a/std/src/persistence/stock.rs +++ b/std/src/persistence/stock.rs @@ -109,6 +109,7 @@ impl DerefMut for Stock { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.hoard } } +#[allow(clippy::result_large_err)] impl Stock { fn consume_consignment( &mut self, diff --git a/std/src/stl/mime.rs b/std/src/stl/mime.rs index af810e29..c1539143 100644 --- a/std/src/stl/mime.rs +++ b/std/src/stl/mime.rs @@ -54,7 +54,7 @@ impl MediaType { /// /// Panics is the provided string is an invalid type specifier. pub fn with(s: &'static str) -> Self { - let (ty, subty) = s.split_once("/").expect("invalid static media type string"); + let (ty, subty) = s.split_once('/').expect("invalid static media type string"); MediaType { ty: MediaRegName::from(ty), subtype: if subty == "*" { diff --git a/std/src/stl/mod.rs b/std/src/stl/mod.rs index 31fe653a..08022731 100644 --- a/std/src/stl/mod.rs +++ b/std/src/stl/mod.rs @@ -20,6 +20,7 @@ // limitations under the License. mod specs; +#[allow(clippy::module_inception)] mod stl; mod error; mod mime; @@ -27,7 +28,7 @@ mod chain; pub use chain::ProofOfReserves; pub(self) use error::Error; -pub use mime::{MediaType, MediaRegName}; +pub use mime::{MediaRegName, MediaType}; pub use specs::{ AssetNaming, Details, DivisibleAssetSpec, Name, Precision, RicardianContract, Ticker, Timestamp, }; diff --git a/std/src/stl/specs.rs b/std/src/stl/specs.rs index 0df162d2..2729f867 100644 --- a/std/src/stl/specs.rs +++ b/std/src/stl/specs.rs @@ -330,8 +330,7 @@ impl AssetNaming { ticker: Ticker::from_str(&ticker).expect("invalid asset ticker"), name: Name::from_str(&name).expect("invalid asset name"), details: details - .as_ref() - .map(String::as_str) + .as_deref() .map(Details::from_str) .transpose() .expect("invalid asset details"), diff --git a/std/src/stl/stl.rs b/std/src/stl/stl.rs index d426c763..01ec3903 100644 --- a/std/src/stl/stl.rs +++ b/std/src/stl/stl.rs @@ -56,6 +56,10 @@ pub fn rgb_contract_stl() -> TypeLib { #[derive(Debug)] pub struct StandardTypes(SymbolicSys); +impl Default for StandardTypes { + fn default() -> Self { StandardTypes::new() } +} + impl StandardTypes { pub fn new() -> Self { Self::try_with([std_stl(), bitcoin_stl(), rgb_contract_stl()]) @@ -67,6 +71,7 @@ impl StandardTypes { .expect("error in standard RGBContract type system") } + #[allow(clippy::result_large_err)] fn try_with(libs: impl IntoIterator) -> Result { let mut builder = SystemBuilder::new(); for lib in libs.into_iter() { From 882ad6ba5053bbb8453f4279c3a53781fb9bbc91 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Wed, 14 Jun 2023 20:24:19 +0200 Subject: [PATCH 5/5] iface: add convenience methods to Rgb20 wrapper for retrieving supply info --- Cargo.lock | 2 +- Cargo.toml | 2 +- std/src/interface/rgb20.rs | 52 +++++++++++++++++++++++++++++++++++++- 3 files changed, 53 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c67af8ab..5fa70a5d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -962,7 +962,7 @@ dependencies = [ [[package]] name = "strict_types" version = "1.2.0" -source = "git+https://github.com/strict-types/strict-types?branch=develop#e882e5200903fb60df5401632088c611b24b917e" +source = "git+https://github.com/strict-types/strict-types#86975f2549d484d2b9a504df6054eea04eaf5c54" dependencies = [ "amplify", "baid58", diff --git a/Cargo.toml b/Cargo.toml index e02f8682..3b760e7c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -78,7 +78,7 @@ wasm-bindgen-test = "0.3" features = [ "all" ] [patch.crates-io] -strict_types = { git = "https://github.com/strict-types/strict-types", branch = "develop" } +strict_types = { git = "https://github.com/strict-types/strict-types" } commit_verify = { git = "https://github.com/LNP-BP/client_side_validation" } bp-core = { git = "https://github.com/BP-WG/bp-core" } aluvm = { git = "https://github.com/AluVM/rust-aluvm" } diff --git a/std/src/interface/rgb20.rs b/std/src/interface/rgb20.rs index 19a96d34..48bde77e 100644 --- a/std/src/interface/rgb20.rs +++ b/std/src/interface/rgb20.rs @@ -19,10 +19,12 @@ // See the License for the specific language governing permissions and // limitations under the License. +use std::iter::Sum; + use amplify::confinement::SmallOrdSet; use bp::bc::stl::bitcoin_stl; use strict_encoding::{StrictDeserialize, StrictSerialize}; -use strict_types::{CompileError, LibBuilder, TypeLib}; +use strict_types::{CompileError, LibBuilder, StrictVal, TypeLib}; use super::{ AssignIface, GenesisIface, GlobalIface, Iface, OwnedIface, Req, TransitionIface, VerNo, @@ -48,6 +50,25 @@ pub const LIB_ID_RGB20: &str = "ethnic_raja_gloria_9tSQiAn1aGijb2F892JxTqcHDgmri )] pub struct Amount(u64); +impl StrictSerialize for Amount {} +impl StrictDeserialize for Amount {} + +impl Amount { + pub fn zero() -> Self { Amount(0) } + + pub fn one() -> Self { Amount(1) } + + pub fn from_strict_val_unchecked(value: &StrictVal) -> Self { + value.unwrap_uint::().into() + } +} + +impl Sum for Amount { + fn sum>(iter: I) -> Self { + iter.fold(Amount::zero(), |acc, i| acc + i) + } +} + #[derive(Clone, Eq, PartialEq, Hash, Debug, Default)] #[derive(StrictType, StrictEncode, StrictDecode)] #[strict_type(lib = LIB_NAME_RGB20)] @@ -296,6 +317,35 @@ impl Rgb20 { .expect("RGB20 interface requires global `spec`")[0]; DivisibleAssetSpec::from_strict_val_unchecked(strict_val) } + + pub fn total_issued_supply(&self) -> Amount { + self.0 + .global("issuedSupply") + .expect("RGB20 interface requires global `issuedSupply`") + .iter() + .map(Amount::from_strict_val_unchecked) + .sum() + } + + pub fn total_burned_supply(&self) -> Amount { + self.0 + .global("burnedSupply") + .unwrap_or_default() + .iter() + .map(Amount::from_strict_val_unchecked) + .sum() + } + + pub fn total_replaced_supply(&self) -> Amount { + self.0 + .global("replacedSupply") + .unwrap_or_default() + .iter() + .map(Amount::from_strict_val_unchecked) + .sum() + } + + pub fn total_supply(&self) -> Amount { self.total_issued_supply() - self.total_burned_supply() } } #[cfg(test)]