From d96c70677425f72e0ffceb055e0eea5d2b709f7b Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Fri, 17 Nov 2023 19:12:57 +0100 Subject: [PATCH 1/7] chore: update rgb std. Use InvoiceState instead of TypedState --- Cargo.lock | 9 +++------ Cargo.toml | 5 +++++ cli/src/command.rs | 6 +++--- invoice/src/builder.rs | 7 +++---- invoice/src/invoice.rs | 7 +++---- invoice/src/parse.rs | 7 +++---- 6 files changed, 20 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 089c64e..03fdcff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -29,8 +29,7 @@ dependencies = [ [[package]] name = "aluvm" version = "0.11.0-alpha.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14a99358b65b74973749140c2bd657e960d54ba3925c5a56afdbf544317f12f6" +source = "git+https://github.com/AluVM/rust-aluvm?branch=v0.11#7c43abba6b734d31e5bdf8ac786e2e3702541f94" dependencies = [ "amplify", "baid58", @@ -1474,8 +1473,7 @@ dependencies = [ [[package]] name = "rgb-core" version = "0.11.0-beta.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e548bc2d50dac8821ceb7fc2b8e8655cb0a41bb9d76f9b1c069d1e4e09f782c" +source = "git+https://github.com/RGB-WG/rgb-core?branch=v0.11#065137e0d25328d46b2c7d2320cac5c7b6ad3bed" dependencies = [ "aluvm", "amplify", @@ -1538,8 +1536,7 @@ dependencies = [ [[package]] name = "rgb-std" version = "0.11.0-beta.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34ce5c05887c4a445ad747ff38f8eb97aa65a0fcd6d803053715d5c5770087f1" +source = "git+https://github.com/RGB-WG/rgb-std?branch=v0.11#4c478af9301a48c20cc16ab96445c5757ead4a32" dependencies = [ "amplify", "baid58", diff --git a/Cargo.toml b/Cargo.toml index 20fcb19..1be151d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -80,3 +80,8 @@ serde = ["serde_crate", "serde_yaml", "bp-std/serde", "bp-wallet/serde",] [package.metadata.docs.rs] features = [ "all" ] + +[patch.crates-io] +aluvm = { git = "https://github.com/AluVM/rust-aluvm", branch = "v0.11" } +rgb-core = { git = "https://github.com/RGB-WG/rgb-core", branch = "v0.11" } +rgb-std = { git = "https://github.com/RGB-WG/rgb-std", branch = "v0.11" } diff --git a/cli/src/command.rs b/cli/src/command.rs index 428db73..47b84c9 100644 --- a/cli/src/command.rs +++ b/cli/src/command.rs @@ -27,10 +27,10 @@ use amplify::confinement::U16; use bp_util::{Config, Exec}; use bpstd::Txid; use rgb_rt::{DescriptorRgb, RuntimeError}; -use rgbinvoice::{RgbInvoice, RgbTransport}; +use rgbinvoice::{InvoiceState, RgbInvoice, RgbTransport}; use rgbstd::containers::{Bindle, Transfer, UniversalBindle}; use rgbstd::contract::{ContractId, GenesisSeal, GraphSeal, StateType}; -use rgbstd::interface::{ContractBuilder, FilterExclude, SchemaIfaces, TypedState}; +use rgbstd::interface::{ContractBuilder, FilterExclude, SchemaIfaces}; use rgbstd::persistence::{Inventory, Stash}; use rgbstd::schema::SchemaId; use rgbstd::SealDefinition; @@ -507,7 +507,7 @@ impl Exec for RgbArgs { operation: None, assignment: None, beneficiary: seal.to_concealed_seal().into(), - owned_state: TypedState::Amount(*value), + owned_state: InvoiceState::Amount(*value), network: None, expiry: None, unknown_query: none!(), diff --git a/invoice/src/builder.rs b/invoice/src/builder.rs index b882d54..6ecb38a 100644 --- a/invoice/src/builder.rs +++ b/invoice/src/builder.rs @@ -22,11 +22,10 @@ use std::str::FromStr; use bpstd::Network; -use rgbstd::interface::TypedState; use rgbstd::stl::Precision; use rgbstd::ContractId; -use super::{Beneficiary, RgbInvoice, RgbTransport, TransportParseError}; +use super::{Beneficiary, InvoiceState, RgbInvoice, RgbTransport, TransportParseError}; #[derive(Clone, Eq, PartialEq, Debug)] pub struct RgbInvoiceBuilder(RgbInvoice); @@ -41,7 +40,7 @@ impl RgbInvoiceBuilder { operation: None, assignment: None, beneficiary: beneficiary.into(), - owned_state: TypedState::Void, + owned_state: InvoiceState::Void, network: None, expiry: None, unknown_query: none!(), @@ -81,7 +80,7 @@ impl RgbInvoiceBuilder { } pub fn set_amount_raw(mut self, amount: u64) -> Self { - self.0.owned_state = TypedState::Amount(amount); + self.0.owned_state = InvoiceState::Amount(amount); self } diff --git a/invoice/src/invoice.rs b/invoice/src/invoice.rs index 4cc5286..d7c5dc8 100644 --- a/invoice/src/invoice.rs +++ b/invoice/src/invoice.rs @@ -21,7 +21,6 @@ use bpstd::{Address, Network}; use indexmap::IndexMap; -use rgbstd::interface::TypedState; use rgbstd::{AttachId, ContractId, SecretSeal}; use strict_encoding::{FieldName, TypeName}; @@ -38,8 +37,8 @@ pub enum RgbTransport { pub enum InvoiceState { #[display("")] Void, - #[display("{0}.{1}")] - Fungible(u64, u64), + #[display("{0}")] + Amount(u64), #[display("...")] // TODO Data(Vec /* StrictVal */), #[display(inner)] @@ -63,7 +62,7 @@ pub struct RgbInvoice { pub operation: Option, pub assignment: Option, pub beneficiary: Beneficiary, - pub owned_state: TypedState, + pub owned_state: InvoiceState, pub network: Option, /// UTC unix timestamp pub expiry: Option, diff --git a/invoice/src/parse.rs b/invoice/src/parse.rs index 09afe8a..72c70cb 100644 --- a/invoice/src/parse.rs +++ b/invoice/src/parse.rs @@ -28,11 +28,10 @@ use fluent_uri::enc::EStr; use fluent_uri::Uri; use indexmap::IndexMap; use percent_encoding::{utf8_percent_encode, AsciiSet, CONTROLS}; -use rgbstd::interface::TypedState; use rgbstd::{ContractId, SecretSeal}; use strict_encoding::{InvalidIdent, TypeName}; -use super::{Beneficiary, RgbInvoice, RgbTransport}; +use super::{Beneficiary, InvoiceState, RgbInvoice, RgbTransport}; const OMITTED: char = '~'; const EXPIRY: &str = "expiry"; @@ -294,8 +293,8 @@ impl FromStr for RgbInvoice { let mut assignment = path[next_path_index].split('+'); // TODO: support other state types let (beneficiary_str, value) = match (assignment.next(), assignment.next()) { - (Some(a), Some(b)) => (b, TypedState::Amount(a.parse::()?)), - (Some(b), None) => (b, TypedState::Void), + (Some(a), Some(b)) => (b, InvoiceState::Amount(a.parse::()?)), + (Some(b), None) => (b, InvoiceState::Void), _ => return Err(InvoiceParseError::Invalid), }; From 6383719b7b5435c24bf7350cef017033b5a6d9fe Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Sat, 18 Nov 2023 13:56:12 +0100 Subject: [PATCH 2/7] cli: support asset tags --- Cargo.lock | 2 +- cli/src/command.rs | 29 +++++++++++++++++++++++++++-- examples/rgb20-demo.yaml | 1 + 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 03fdcff..7e6cfd0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1536,7 +1536,7 @@ dependencies = [ [[package]] name = "rgb-std" version = "0.11.0-beta.1" -source = "git+https://github.com/RGB-WG/rgb-std?branch=v0.11#4c478af9301a48c20cc16ab96445c5757ead4a32" +source = "git+https://github.com/RGB-WG/rgb-std?branch=v0.11#8ce111c9c66550d630d31e34be8e4fb2239318d7" dependencies = [ "amplify", "baid58", diff --git a/cli/src/command.rs b/cli/src/command.rs index 47b84c9..cd017fc 100644 --- a/cli/src/command.rs +++ b/cli/src/command.rs @@ -19,6 +19,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +use std::collections::HashSet; use std::fs; use std::path::PathBuf; use std::str::FromStr; @@ -30,10 +31,10 @@ use rgb_rt::{DescriptorRgb, RuntimeError}; use rgbinvoice::{InvoiceState, RgbInvoice, RgbTransport}; use rgbstd::containers::{Bindle, Transfer, UniversalBindle}; use rgbstd::contract::{ContractId, GenesisSeal, GraphSeal, StateType}; -use rgbstd::interface::{ContractBuilder, FilterExclude, SchemaIfaces}; +use rgbstd::interface::{AssetTagExt, ContractBuilder, FilterExclude, SchemaIfaces}; use rgbstd::persistence::{Inventory, Stash}; use rgbstd::schema::SchemaId; -use rgbstd::SealDefinition; +use rgbstd::{AssetTag, AssignmentType, SealDefinition}; use seals::txout::{CloseMethod, ExplicitSeal, TxPtr}; use strict_types::encoding::{FieldName, TypeName}; use strict_types::StrictVal; @@ -375,6 +376,11 @@ impl Exec for RgbArgs { let code = code .as_mapping() .expect("invalid YAML root-level structure"); + + let contract_domain = code + .get("domain") + .map(|val| val.as_str().expect("domain name must be a string")); + if let Some(globals) = code.get("globals") { for (name, val) in globals .as_mapping() @@ -419,6 +425,7 @@ impl Exec for RgbArgs { } } + let mut asset_tags: HashSet = empty!(); if let Some(assignments) = code.get("assignments") { for (name, val) in assignments .as_mapping() @@ -462,6 +469,24 @@ impl Exec for RgbArgs { match state_schema.state_type() { StateType::Void => todo!(), StateType::Fungible => { + let assignment_type = + iface_impl.assignments_type(&field_name).expect( + "unknown assignment name, which is absent from the \ + interface implementation", + ); + if !asset_tags.contains(&assignment_type) { + let asset_tag = AssetTag::new_random( + contract_domain.expect( + "when issuing contracts using fungible state it is \ + required to provide a contract domain", + ), + assignment_type, + ); + asset_tags.insert(assignment_type); + builder = builder + .add_asset_tag(field_name.clone(), asset_tag) + .expect("unable to register asset tag"); + } let amount = assign .get("amount") .expect("owned state must be a fungible amount") diff --git a/examples/rgb20-demo.yaml b/examples/rgb20-demo.yaml index dddc475..d0b58f8 100644 --- a/examples/rgb20-demo.yaml +++ b/examples/rgb20-demo.yaml @@ -1,4 +1,5 @@ interface: RGB20 +domain: examples.lnp-bp.org/rgb-wallet/RGB20 globals: spec: From 69d7387d9957a00f0a6ef9b1fd3a9266d01c3e14 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Sat, 18 Nov 2023 14:04:44 +0100 Subject: [PATCH 3/7] cli: improve error reporting --- Cargo.lock | 24 ++++++++++++------------ cli/src/command.rs | 8 +++++++- src/runtime.rs | 8 ++++---- 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7e6cfd0..576fe85 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -460,9 +460,9 @@ checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "cc" -version = "1.0.84" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f8e7c90afad890484a21653d08b6e209ae34770fb5ee298f9c699fcc1e5c856" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" dependencies = [ "libc", ] @@ -743,9 +743,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c18ee0ed65a5f1f81cac6b1d213b69c35fa47d4252ad41f1486dbd8226fe36e" +checksum = "f258a7194e7f7c2a7837a8913aeab7fd8c383457034fa20ce4dd3dcb813e8eb8" dependencies = [ "libc", "windows-sys", @@ -876,9 +876,9 @@ checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" [[package]] name = "h2" -version = "0.3.21" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" +checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178" dependencies = [ "bytes", "fnv", @@ -886,7 +886,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 1.9.3", + "indexmap 2.1.0", "slab", "tokio", "tokio-util", @@ -1473,7 +1473,7 @@ dependencies = [ [[package]] name = "rgb-core" version = "0.11.0-beta.1" -source = "git+https://github.com/RGB-WG/rgb-core?branch=v0.11#065137e0d25328d46b2c7d2320cac5c7b6ad3bed" +source = "git+https://github.com/RGB-WG/rgb-core?branch=v0.11#f009e51734f8f258d75a51aac4cdc68e13732c9d" dependencies = [ "aluvm", "amplify", @@ -1610,9 +1610,9 @@ checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustix" -version = "0.38.23" +version = "0.38.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb93593068e9babdad10e4fce47dc9b3ac25315a72a59766ffd9e9a71996a04" +checksum = "9ad981d6c340a49cdc40a1028d9c6084ec7e9fa33fcb839cab656a267071e234" dependencies = [ "bitflags 2.4.1", "errno", @@ -1623,9 +1623,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.8" +version = "0.21.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "446e14c5cda4f3f30fe71863c34ec70f5ac79d6087097ad0bb433e1be5edf04c" +checksum = "629648aced5775d558af50b2b4c7b02983a04b312126d45eeead26e7caa498b9" dependencies = [ "log", "ring", diff --git a/cli/src/command.rs b/cli/src/command.rs index cd017fc..667b1cd 100644 --- a/cli/src/command.rs +++ b/cli/src/command.rs @@ -507,7 +507,13 @@ impl Exec for RgbArgs { let mut resolver = PanickingResolver; let validated_contract = contract .validate(&mut resolver, self.general.network.is_testnet()) - .map_err(|_| RuntimeError::IncompleteContract)?; + .map_err(|consignment| { + RuntimeError::IncompleteContract( + consignment + .into_validation_status() + .expect("just validated"), + ) + })?; runtime .import_contract(validated_contract, &mut resolver) .expect("failure importing issued contract"); diff --git a/src/runtime.rs b/src/runtime.rs index 996cb27..d8eade1 100644 --- a/src/runtime.rs +++ b/src/runtime.rs @@ -70,11 +70,11 @@ pub enum RuntimeError { #[from] InvalidConsignment(validation::Status), - /// the contract source doesn't provide all state information required by - /// the schema. This means that some of the global fields or assignments are - /// missed. + /// the contract source doesn't fit requirements imposed by the used schema. + /// + /// {0} #[display(doc_comments)] - IncompleteContract, + IncompleteContract(validation::Status), #[from] #[from(bpwallet::LoadError)] From 39e5bab542cb10854459c758fe37eec0ebebc0c4 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Sat, 18 Nov 2023 14:24:29 +0100 Subject: [PATCH 4/7] chore: fix clippy lints --- cli/src/args.rs | 4 ++-- cli/src/command.rs | 4 ++-- src/descriptor.rs | 7 ++----- src/runtime.rs | 4 +++- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/cli/src/args.rs b/cli/src/args.rs index c1b0ed2..59c89d8 100644 --- a/cli/src/args.rs +++ b/cli/src/args.rs @@ -19,6 +19,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#![allow(clippy::needless_update)] // Caused by the From derivation macro + use bp_util::DescriptorOpts; use bpstd::XpubDerivable; use rgb_rt::{DescriptorRgb, Runtime, RuntimeError, TapretKey}; @@ -53,8 +55,6 @@ impl DescriptorOpts for DescrRgbOpts { #[command(author, version, about)] pub struct RgbArgs { #[clap(flatten)] - #[from] - #[wrap] pub inner: bp_util::Args, } diff --git a/cli/src/command.rs b/cli/src/command.rs index 667b1cd..f464da6 100644 --- a/cli/src/command.rs +++ b/cli/src/command.rs @@ -294,7 +294,7 @@ impl Exec for RgbArgs { .map_err(|err| err.to_string())?; if let Some(file) = file { // TODO: handle armored flag - bindle.save(&file)?; + bindle.save(file)?; eprintln!("Contract {contract} exported to '{}'", file.display()); } else { println!("{bindle}"); @@ -595,7 +595,7 @@ impl Exec for RgbArgs { Command::Dump { root_dir } => { let runtime = self.rgb_runtime()?; - fs::remove_dir_all(&root_dir).ok(); + fs::remove_dir_all(root_dir).ok(); fs::create_dir_all(format!("{root_dir}/stash/schemata"))?; fs::create_dir_all(format!("{root_dir}/stash/ifaces"))?; fs::create_dir_all(format!("{root_dir}/stash/geneses"))?; diff --git a/src/descriptor.rs b/src/descriptor.rs index 2c5430f..3622a41 100644 --- a/src/descriptor.rs +++ b/src/descriptor.rs @@ -120,7 +120,7 @@ impl From> for TapretKey { } } -#[derive(Clone, Eq, PartialEq, Hash, Debug, From)] +#[derive(Clone, Eq, PartialEq, Hash, Debug, Default, From)] #[derive(Serialize, Deserialize)] #[serde( crate = "serde_crate", @@ -131,16 +131,13 @@ impl From> for TapretKey { ) )] pub enum DescriptorRgb { + #[default] None, #[from] TapretKey(TapretKey), } -impl Default for DescriptorRgb { - fn default() -> Self { DescriptorRgb::None } -} - impl Derive for DescriptorRgb { fn keychains(&self) -> Range { match self { diff --git a/src/runtime.rs b/src/runtime.rs index d8eade1..662e915 100644 --- a/src/runtime.rs +++ b/src/runtime.rs @@ -19,6 +19,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#![allow(clippy::result_large_err)] + use std::convert::Infallible; use std::ops::{Deref, DerefMut}; use std::path::PathBuf; @@ -235,7 +237,7 @@ impl, K> Runtime { pub fn descriptor(&self) -> &D { self.wallet.deref() } - pub fn unload(self) -> () {} + pub fn unload(self) {} pub fn address_network(&self) -> AddressNetwork { self.network.into() } From e933c87a36b4d95d29e326437d82d9035e562394 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Sat, 18 Nov 2023 14:26:51 +0100 Subject: [PATCH 5/7] ci: fix build features --- .github/workflows/build.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ae88e9f..89ca89c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -44,8 +44,9 @@ jobs: fail-fast: false matrix: feature: - - cli - - electrum + - esplora + - log + - serde steps: - uses: actions/checkout@v3 - name: Install rust stable From a5c8d33f9c59ae529053d5018d92373351ea090f Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Sat, 18 Nov 2023 14:30:13 +0100 Subject: [PATCH 6/7] chore: fix warnings --- cli/src/command.rs | 2 ++ src/descriptor.rs | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/cli/src/command.rs b/cli/src/command.rs index f464da6..ac6eeb8 100644 --- a/cli/src/command.rs +++ b/cli/src/command.rs @@ -546,6 +546,7 @@ impl Exec for RgbArgs { runtime.store_seal_secret(SealDefinition::Bitcoin(seal))?; println!("{invoice}"); } + #[allow(unused_variables)] Command::Transfer { method, psbt_file, @@ -707,6 +708,7 @@ impl Exec for RgbArgs { runtime.accept_transfer(transfer, &mut resolver, *force)?; eprintln!("Transfer accepted into the stash"); } + #[allow(unused_variables)] Command::SetHost { method, psbt_file } => { todo!(); /* diff --git a/src/descriptor.rs b/src/descriptor.rs index 3622a41..1c3d434 100644 --- a/src/descriptor.rs +++ b/src/descriptor.rs @@ -168,9 +168,9 @@ where Self: Derive fn xpubs(&self) -> Self::XpubIter<'_> { todo!() } - fn compr_keyset(&self, terminal: Terminal) -> IndexMap { todo!() } + fn compr_keyset(&self, _terminal: Terminal) -> IndexMap { todo!() } - fn xonly_keyset(&self, terminal: Terminal) -> IndexMap { todo!() } + fn xonly_keyset(&self, _terminal: Terminal) -> IndexMap { todo!() } } impl From for DescriptorRgb { From bfcb57f555cc85553c7989a384590c2788b8bf21 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Sat, 18 Nov 2023 14:34:03 +0100 Subject: [PATCH 7/7] chore: re-do manual Default impl for DescriptorRgb to fix MSRV --- src/descriptor.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/descriptor.rs b/src/descriptor.rs index 1c3d434..5238dcc 100644 --- a/src/descriptor.rs +++ b/src/descriptor.rs @@ -120,7 +120,7 @@ impl From> for TapretKey { } } -#[derive(Clone, Eq, PartialEq, Hash, Debug, Default, From)] +#[derive(Clone, Eq, PartialEq, Hash, Debug, From)] #[derive(Serialize, Deserialize)] #[serde( crate = "serde_crate", @@ -131,13 +131,16 @@ impl From> for TapretKey { ) )] pub enum DescriptorRgb { - #[default] None, #[from] TapretKey(TapretKey), } +impl Default for DescriptorRgb { + fn default() -> Self { Self::None } +} + impl Derive for DescriptorRgb { fn keychains(&self) -> Range { match self {