diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml index 9fd96f0e..20773195 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov.yml @@ -14,33 +14,38 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - name: Install latest nightly + - name: Set up toolchain uses: actions-rs/toolchain@v1 with: - toolchain: nightly + profile: minimal + toolchain: stable override: true - - name: Build & test + components: rustfmt, llvm-tools-preview + - name: Build uses: actions-rs/cargo@v1 with: - command: test - args: --workspace --all-features --no-fail-fast + command: build + args: --release env: - CARGO_INCREMENTAL: '0' - RUSTFLAGS: '-Zprofile -Ccodegen-units=1 -Cinline-threshold=0 -Clink-dead-code -Coverflow-checks=off' - RUSTDOCFLAGS: '-Zprofile -Ccodegen-units=1 -Cinline-threshold=0 -Clink-dead-code -Coverflow-checks=off' - - id: coverage - name: Generate coverage - uses: actions-rs/grcov@0.2-proto + CARGO_INCREMENTAL: "0" + RUSTFLAGS: "-Cinstrument-coverage" + RUSTDOCFLAGS: "-Cinstrument-coverage" + - name: Test + uses: actions-rs/cargo@v1 with: - args: > - -t lcov - --llvm - --ignore-not-existing - --ignore "/*" - -o ./target/lcov.info - ./target/debug/ + command: test + args: --all-features --no-fail-fast + env: + CARGO_INCREMENTAL: "0" + RUSTFLAGS: "-Cinstrument-coverage" + RUSTDOCFLAGS: "-Cinstrument-coverage" + - name: Install grcov + run: if [[ ! -e ~/.cargo/bin/grcov ]]; then cargo install grcov; fi + - name: Generate coverage + run: grcov . --binary-path target/debug/deps/ -s . -t lcov --branch --ignore-not-existing --ignore '../**' --ignore '/*' -o coverage.lcov - name: Upload coverage to Codecov - uses: codecov/codecov-action@v1 + uses: codecov/codecov-action@v3 with: - file: ${{ steps.coverage.outputs.report }} - directory: ./coverage/reports/ + files: ./coverage.lcov + flags: rust + fail_ci_if_error: true diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index b8979f05..3f51bde0 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -39,7 +39,7 @@ jobs: name: Clippy with: command: clippy - args: --workspace --all-features --all-targets + args: --workspace --all-features --all-targets -- -D warnings doc: runs-on: ubuntu-latest steps: diff --git a/Cargo.lock b/Cargo.lock index d05a525a..2872d42c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -647,7 +647,8 @@ dependencies = [ [[package]] name = "rgb-core" version = "0.10.8" -source = "git+https://github.com/RGB-WG/rgb-core?branch=v0.10#f9dc0afb736c7520c57e229438c3e9453aab9c9a" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74ace164ee5d1a2ba5224aee07cf365a69ca028b7bd1b3dc4906a4d1b889c246" dependencies = [ "aluvm", "amplify", @@ -666,7 +667,7 @@ dependencies = [ [[package]] name = "rgb-std" -version = "0.10.8" +version = "0.10.9" dependencies = [ "amplify", "baid58", @@ -686,7 +687,7 @@ dependencies = [ [[package]] name = "rgb-wallet" -version = "0.10.8" +version = "0.10.9" dependencies = [ "amplify", "baid58", @@ -773,18 +774,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.188" +version = "1.0.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.188" +version = "1.0.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index af000d00..a3dbeae6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,7 @@ rgb-core = { version = "0.10.8", features = ["stl"] } [package] name = "rgb-wallet" -version = "0.10.8" +version = "0.10.9" description = "RGB wallet library for smart contracts on Bitcoin & Lightning network" keywords = ["bitcoin", "lightning", "rgb", "smart-contracts", "lnp-bp"] categories = ["cryptography::cryptocurrencies"] @@ -76,6 +76,3 @@ wasm-bindgen-test = "0.3" [package.metadata.docs.rs] features = [ "all" ] - -[patch.crates-io] -rgb-core = { git = "https://github.com/RGB-WG/rgb-core", branch = "v0.10" } diff --git a/src/invoice/builder.rs b/src/invoice/builder.rs index 3898bd19..fd801143 100644 --- a/src/invoice/builder.rs +++ b/src/invoice/builder.rs @@ -31,6 +31,7 @@ use super::{Beneficiary, RgbInvoice, RgbTransport, TransportParseError}; #[derive(Clone, Eq, PartialEq, Debug)] pub struct RgbInvoiceBuilder(RgbInvoice); +#[allow(clippy::result_large_err)] impl RgbInvoiceBuilder { pub fn new(beneficiary: impl Into) -> Self { Self(RgbInvoice { @@ -106,6 +107,11 @@ impl RgbInvoiceBuilder { Ok(self.set_amount_raw(amount)) } + /// # Safety + /// + /// The function may cause the loss of the information about the precise + /// amout of the asset, since f64 type doesn't provide full precision + /// required for that. pub unsafe fn set_amount_approx(self, amount: f64, precision: Precision) -> Result { if amount <= 0.0 { return Err(self); diff --git a/src/invoice/mod.rs b/src/invoice/mod.rs index e98c10e4..df0a947f 100644 --- a/src/invoice/mod.rs +++ b/src/invoice/mod.rs @@ -19,6 +19,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#[allow(clippy::module_inception)] mod invoice; mod parse; mod builder; diff --git a/src/pay.rs b/src/pay.rs index 74df140e..765bd3fa 100644 --- a/src/pay.rs +++ b/src/pay.rs @@ -24,7 +24,7 @@ use std::collections::{BTreeMap, HashMap}; use std::error::Error; use std::iter; -use amplify::RawArray; +use amplify::ByteArray; use bitcoin::hashes::Hash; use bitcoin::psbt::Psbt; use bp::seals::txout::CloseMethod; @@ -291,7 +291,7 @@ pub trait InventoryWallet: Inventory { } let beneficiary = match beneficiary { BuilderSeal::Revealed(seal) => BuilderSeal::Revealed( - seal.resolve(Txid::from_raw_array(witness_txid.to_byte_array())), + seal.resolve(Txid::from_byte_array(witness_txid.to_byte_array())), ), BuilderSeal::Concealed(seal) => BuilderSeal::Concealed(seal), }; diff --git a/src/psbt/dbc.rs b/src/psbt/dbc.rs index a4bbf4d6..3038dc31 100644 --- a/src/psbt/dbc.rs +++ b/src/psbt/dbc.rs @@ -20,7 +20,7 @@ // limitations under the License. use amplify::num::u5; -use amplify::RawArray; +use amplify::ByteArray; use bitcoin::hashes::Hash; use bitcoin::psbt::Psbt; use bitcoin::secp256k1::SECP256K1; @@ -152,7 +152,7 @@ impl PsbtDbc for Psbt { Proof::TapretFirst(tapret_proof) } else if method == CloseMethod::OpretFirst { output.set_opret_commitment(commitment)?; - txout.script_pubkey = ScriptBuf::new_op_return(&commitment.to_raw_array()); + txout.script_pubkey = ScriptBuf::new_op_return(&commitment.to_byte_array()); Proof::OpretFirst } else { return Err(DbcPsbtError::MethodUnsupported(method)); diff --git a/src/psbt/lnpbp4.rs b/src/psbt/lnpbp4.rs index 0435c315..661355a9 100644 --- a/src/psbt/lnpbp4.rs +++ b/src/psbt/lnpbp4.rs @@ -21,8 +21,8 @@ use std::collections::BTreeMap; -use amplify::confinement; -use amplify::confinement::Confined; +use amplify::confinement::{self, Confined}; +use amplify::FromSliceError; use bitcoin::psbt::raw::ProprietaryKey; use bitcoin::psbt::Output; use commit_verify::mpc::{self, Message, ProtocolId}; @@ -84,6 +84,10 @@ pub enum Lnpbp4PsbtError { #[from(bitcoin::hashes::Error)] InvalidKeyValue, + /// the length of the commitment data doesn't match 32 byte hash. + #[from(FromSliceError)] + InvalidHashValue, + /// message map produced from PSBT inputs exceeds maximum size bounds. #[from] MessageMapTooLarge(confinement::Error), @@ -120,10 +124,7 @@ impl OutputLnpbp4 for Output { key.prefix == PSBT_LNPBP4_PREFIX && key.subtype == PSBT_OUT_LNPBP4_MESSAGE }) .map(|(key, val)| { - Ok(( - ProtocolId::from_slice(&key.key).ok_or(Lnpbp4PsbtError::InvalidKeyValue)?, - Message::from_slice(val).ok_or(Lnpbp4PsbtError::InvalidKeyValue)?, - )) + Ok((ProtocolId::copy_from_slice(&key.key)?, Message::copy_from_slice(val)?)) }) .collect::, Lnpbp4PsbtError>>()?; Confined::try_from(map).map_err(Lnpbp4PsbtError::from) @@ -139,7 +140,7 @@ impl OutputLnpbp4 for Output { fn lnpbp4_message(&self, protocol_id: ProtocolId) -> Option { let key = ProprietaryKey::lnpbp4_message(protocol_id); let data = self.proprietary.get(&key)?; - Message::from_slice(data) + Message::copy_from_slice(data).ok() } /// Returns a valid LNPBP-4 entropy value, if present. diff --git a/src/psbt/opret.rs b/src/psbt/opret.rs index 2902d97c..8c9474f3 100644 --- a/src/psbt/opret.rs +++ b/src/psbt/opret.rs @@ -163,7 +163,7 @@ impl OutputOpret for Output { return Err(OpretKeyError::NonOpReturnOutput); }*/ let data = self.proprietary.get(&ProprietaryKey::opret_commitment())?; - mpc::Commitment::from_slice(data) + mpc::Commitment::copy_from_slice(data).ok() } /// Assigns value of the opreturn commitment to this PSBT output, by diff --git a/src/psbt/tapret.rs b/src/psbt/tapret.rs index 17917185..be49f19c 100644 --- a/src/psbt/tapret.rs +++ b/src/psbt/tapret.rs @@ -179,7 +179,7 @@ impl OutputTapret for Output { /// only in situations when the commitment is absent. fn tapret_commitment(&self) -> Option { let data = self.proprietary.get(&ProprietaryKey::tapret_commitment())?; - mpc::Commitment::from_slice(data) + mpc::Commitment::copy_from_slice(data).ok() } /// Assigns value of the tapreturn commitment to this PSBT output, by diff --git a/std/Cargo.toml b/std/Cargo.toml index 125a2ef1..fc37b6c7 100644 --- a/std/Cargo.toml +++ b/std/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rgb-std" -version = "0.10.8" +version = "0.10.9" description = "RGB standard library for working with smart contracts on Bitcoin & Lightning" keywords = ["bitcoin", "lightning", "rgb", "smart-contracts", "lnp-bp"] categories = ["cryptography::cryptocurrencies"] @@ -28,7 +28,7 @@ bp-core = { workspace = true } rgb-core = { workspace = true } baid58 = { workspace = true } base85 = "=2.0.0" -chrono = "0.4.31" +chrono = "0.4.26" serde_crate = { package = "serde", version = "1", features = ["derive"] } [features] diff --git a/std/src/containers/transfer.rs b/std/src/containers/transfer.rs index cb0b9f28..7f1283e7 100644 --- a/std/src/containers/transfer.rs +++ b/std/src/containers/transfer.rs @@ -23,7 +23,7 @@ use std::io; use std::str::FromStr; use amplify::confinement::SmallOrdSet; -use amplify::{Bytes32, RawArray}; +use amplify::{ByteArray, Bytes32}; use baid58::{Baid58ParseError, Chunking, FromBaid58, ToBaid58, CHUNKING_32}; use commit_verify::{CommitEncode, CommitmentId, Conceal}; use strict_encoding::{StrictEncode, StrictWriter}; @@ -51,7 +51,7 @@ pub struct TransferId( impl ToBaid58<32> for TransferId { const HRI: &'static str = "consign"; const CHUNKING: Option = CHUNKING_32; - fn to_baid58_payload(&self) -> [u8; 32] { self.to_raw_array() } + fn to_baid58_payload(&self) -> [u8; 32] { self.to_byte_array() } fn to_baid58_string(&self) -> String { self.to_string() } } impl FromBaid58<32> for TransferId {} @@ -59,6 +59,7 @@ impl FromStr for TransferId { type Err = Baid58ParseError; fn from_str(s: &str) -> Result { Self::from_baid58_chunked_str(s, ':', '#') } } +#[allow(clippy::wrong_self_convention)] // We need the method that takes self by ref in order to have simplier APIs in iterators impl TransferId { pub fn to_baid58_string(&self) -> String { format!("{::<#.2}", self.to_baid58()) } pub fn to_mnemonic(&self) -> String { self.to_baid58().mnemonic() } diff --git a/std/src/interface/iface.rs b/std/src/interface/iface.rs index 3552b6e3..64573c5f 100644 --- a/std/src/interface/iface.rs +++ b/std/src/interface/iface.rs @@ -24,7 +24,7 @@ use std::fmt::{self, Display, Formatter}; use std::str::FromStr; use amplify::confinement::{TinyOrdMap, TinyOrdSet}; -use amplify::{Bytes32, RawArray}; +use amplify::{ByteArray, Bytes32}; use baid58::{Baid58ParseError, Chunking, FromBaid58, ToBaid58, CHUNKING_32}; use commit_verify::{CommitStrategy, CommitmentId}; use rgb::Occurrences; @@ -58,7 +58,7 @@ pub struct IfaceId( impl ToBaid58<32> for IfaceId { const HRI: &'static str = "if"; const CHUNKING: Option = CHUNKING_32; - fn to_baid58_payload(&self) -> [u8; 32] { self.to_raw_array() } + fn to_baid58_payload(&self) -> [u8; 32] { self.to_byte_array() } fn to_baid58_string(&self) -> String { self.to_string() } } impl FromBaid58<32> for IfaceId {} diff --git a/std/src/interface/iimpl.rs b/std/src/interface/iimpl.rs index b8c5101a..3d2fb4fd 100644 --- a/std/src/interface/iimpl.rs +++ b/std/src/interface/iimpl.rs @@ -23,7 +23,7 @@ use std::fmt::{self, Display, Formatter}; use std::str::FromStr; use amplify::confinement::{TinyOrdMap, TinyOrdSet}; -use amplify::{Bytes32, RawArray}; +use amplify::{ByteArray, Bytes32}; use baid58::{Baid58ParseError, Chunking, FromBaid58, ToBaid58, CHUNKING_32}; use commit_verify::{CommitStrategy, CommitmentId}; use rgb::{ @@ -60,7 +60,7 @@ pub struct ImplId( impl ToBaid58<32> for ImplId { const HRI: &'static str = "im"; const CHUNKING: Option = CHUNKING_32; - fn to_baid58_payload(&self) -> [u8; 32] { self.to_raw_array() } + fn to_baid58_payload(&self) -> [u8; 32] { self.to_byte_array() } fn to_baid58_string(&self) -> String { self.to_string() } } impl FromBaid58<32> for ImplId {} diff --git a/std/src/interface/rgb20.rs b/std/src/interface/rgb20.rs index 0456c7a9..ecf5809c 100644 --- a/std/src/interface/rgb20.rs +++ b/std/src/interface/rgb20.rs @@ -20,7 +20,7 @@ // limitations under the License. use amplify::confinement::LargeVec; -use bp::bc::stl::bitcoin_stl; +use bp::bc::stl::bp_tx_stl; use strict_types::{CompileError, LibBuilder, TypeLib}; use super::{ @@ -59,7 +59,7 @@ pub enum Error { fn _rgb20_stl() -> Result { LibBuilder::new(libname!(LIB_NAME_RGB20), tiny_bset! { - bitcoin_stl().to_dependency(), + bp_tx_stl().to_dependency(), rgb_contract_stl().to_dependency() }) .transpile::() diff --git a/std/src/interface/rgb21.rs b/std/src/interface/rgb21.rs index 8d06805a..9fba8a69 100644 --- a/std/src/interface/rgb21.rs +++ b/std/src/interface/rgb21.rs @@ -27,7 +27,7 @@ use std::str::FromStr; use amplify::ascii::AsciiString; use amplify::confinement::{Confined, NonEmptyVec, SmallBlob}; -use bp::bc::stl::bitcoin_stl; +use bp::bc::stl::bp_tx_stl; use strict_encoding::stl::AsciiPrintable; use strict_encoding::{ InvalidIdent, StrictDeserialize, StrictDumb, StrictEncode, StrictSerialize, TypedWrite, @@ -262,7 +262,7 @@ pub enum Error { fn _rgb21_stl() -> Result { LibBuilder::new(libname!(LIB_NAME_RGB21), tiny_bset! { std_stl().to_dependency(), - bitcoin_stl().to_dependency(), + bp_tx_stl().to_dependency(), rgb_contract_stl().to_dependency() }) .transpile::() diff --git a/std/src/interface/rgb25.rs b/std/src/interface/rgb25.rs index 4c46301a..c428cb23 100644 --- a/std/src/interface/rgb25.rs +++ b/std/src/interface/rgb25.rs @@ -23,7 +23,7 @@ use std::fmt::Debug; -use bp::bc::stl::bitcoin_stl; +use bp::bc::stl::bp_tx_stl; use strict_encoding::{StrictDumb, StrictEncode}; use strict_types::stl::std_stl; use strict_types::{CompileError, LibBuilder, TypeLib}; @@ -61,7 +61,7 @@ pub enum Error { fn _rgb25_stl() -> Result { LibBuilder::new(libname!(LIB_NAME_RGB25), tiny_bset! { std_stl().to_dependency(), - bitcoin_stl().to_dependency(), + bp_tx_stl().to_dependency(), rgb_contract_stl().to_dependency(), }) .transpile::() diff --git a/std/src/persistence/stock.rs b/std/src/persistence/stock.rs index fbcbaa95..e81a116e 100644 --- a/std/src/persistence/stock.rs +++ b/std/src/persistence/stock.rs @@ -24,7 +24,7 @@ use std::convert::Infallible; use std::ops::{Deref, DerefMut}; use amplify::confinement::{MediumOrdMap, MediumOrdSet, TinyOrdMap}; -use amplify::RawArray; +use amplify::ByteArray; use bp::dbc::Anchor; use bp::Txid; use commit_verify::mpc::MerkleBlock; @@ -498,7 +498,7 @@ impl Inventory for Stock { let anchor_id = anchor.anchor_id(); for (_, bundle_id) in anchor.mpc_proof.to_known_message_map() { self.anchor_bundle_index - .insert(bundle_id.to_raw_array().into(), anchor_id)?; + .insert(bundle_id.to_byte_array().into(), anchor_id)?; } self.hoard.consume_anchor(anchor)?; Ok(()) diff --git a/std/src/reserved.rs b/std/src/reserved.rs index d3953831..a18a7cf0 100644 --- a/std/src/reserved.rs +++ b/std/src/reserved.rs @@ -52,10 +52,10 @@ impl StrictDecode for ReservedBytes { fn strict_decode(reader: &mut impl TypedRead) -> Result { let me = reader.read_newtype::()?; if me.0 != [VAL; LEN] { - return Err(DecodeError::DataIntegrityError(format!( + Err(DecodeError::DataIntegrityError(format!( "reserved bytes required to have value [{VAL}; {LEN}] while {} was found", me.0.to_hex() - ))); + ))) } else { Ok(me) } @@ -103,7 +103,7 @@ mod _serde { } } - let _: () = deserializer.deserialize_unit(UntaggedUnitVisitor::default())?; + deserializer.deserialize_unit(UntaggedUnitVisitor)?; Ok(default!()) } } diff --git a/std/src/stl/mod.rs b/std/src/stl/mod.rs index 2eae1165..f5940828 100644 --- a/std/src/stl/mod.rs +++ b/std/src/stl/mod.rs @@ -27,7 +27,7 @@ mod mime; mod chain; pub use chain::ProofOfReserves; -pub(self) use error::Error; +use error::Error; pub use mime::{MediaRegName, MediaType}; pub use specs::{ Amount, AssetNaming, Attachment, BurnMeta, CoinAmount, ContractData, Details, diff --git a/std/src/stl/specs.rs b/std/src/stl/specs.rs index 0ec351a8..c5095d68 100644 --- a/std/src/stl/specs.rs +++ b/std/src/stl/specs.rs @@ -519,7 +519,7 @@ impl Timestamp { pub fn to_utc(self) -> Option> { NaiveDateTime::from_timestamp_opt(self.0, 0) - .map(|naive| DateTime::::from_utc(naive, Utc)) + .map(|naive| DateTime::::from_naive_utc_and_offset(naive, Utc)) } pub fn to_local(self) -> Option> { self.to_utc().map(DateTime::::from) } @@ -595,6 +595,7 @@ mod test { #[test] fn coin_amount() { + #![allow(clippy::inconsistent_digit_grouping)] let amount = CoinAmount::with(10_000_436_081_95, Precision::default()); assert_eq!(amount.int, 10_000); assert_eq!(amount.fract, 436_081_95); diff --git a/std/src/stl/stl.rs b/std/src/stl/stl.rs index 04462b87..825d3d4b 100644 --- a/std/src/stl/stl.rs +++ b/std/src/stl/stl.rs @@ -19,7 +19,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use bp::bc::stl::bitcoin_stl; +use bp::bc::stl::bp_tx_stl; use bp::stl::bp_core_stl; use commit_verify::stl::commit_verify_stl; pub use rgb::stl::{aluvm_stl, rgb_core_stl, LIB_ID_RGB}; @@ -49,7 +49,7 @@ fn _rgb_std_stl() -> Result { std_stl().to_dependency(), strict_types_stl().to_dependency(), commit_verify_stl().to_dependency(), - bitcoin_stl().to_dependency(), + bp_tx_stl().to_dependency(), bp_core_stl().to_dependency(), aluvm_stl().to_dependency(), rgb_core_stl().to_dependency() @@ -62,7 +62,7 @@ fn _rgb_std_stl() -> Result { fn _rgb_contract_stl() -> Result { LibBuilder::new(libname!(LIB_NAME_RGB_CONTRACT), tiny_bset! { std_stl().to_dependency(), - bitcoin_stl().to_dependency() + bp_tx_stl().to_dependency() }) .transpile::() .transpile::() @@ -94,12 +94,12 @@ impl Default for StandardTypes { impl StandardTypes { pub fn new() -> Self { - Self::try_with([std_stl(), bitcoin_stl(), rgb_contract_stl()]) + Self::try_with([std_stl(), bp_tx_stl(), rgb_contract_stl()]) .expect("error in standard RGBContract type system") } pub fn with(lib: TypeLib) -> Self { - Self::try_with([std_stl(), bitcoin_stl(), rgb_contract_stl(), lib]) + Self::try_with([std_stl(), bp_tx_stl(), rgb_contract_stl(), lib]) .expect("error in standard RGBContract type system") }