diff --git a/Cargo.toml b/Cargo.toml index c0c709386..a3509edd1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -55,7 +55,7 @@ derive_more = { version = "0.99", features = [ ] } num-derive = "0.4.2" thiserror = { version = "2.0.1", default-features = false } -bounded-vec = { git = "https://github.com/SethDusek/bounded-vec", branch = "no_std" } # TODO: merge no_std support in bounded-vec +bounded-vec = { git = "https://github.com/SethDusek/bounded-vec", rev = "0eb104e114c1387f33e88bc48b33951900767249" } # TODO: merge no_std support in bounded-vec upstream bitvec = { version = "1.0.1", default-features = false, features = ["alloc"] } blake2 = { version = "0.10.6", default-features = false } sha2 = { version = "0.10", default-features = false } @@ -93,7 +93,7 @@ core2 = { version = "0.4.0", default-features = false, features = ["alloc"] } proptest = { version = "1.5.0", default-features = false, features = [ "alloc", "std", -] } # TODO: consider enabling std +] } proptest-derive = "0.3" pretty_assertions = "1.3" wasm-bindgen-test = "0.3.37" diff --git a/bindings/ergo-lib-c-core/Cargo.toml b/bindings/ergo-lib-c-core/Cargo.toml index 44d31d155..c54962560 100644 --- a/bindings/ergo-lib-c-core/Cargo.toml +++ b/bindings/ergo-lib-c-core/Cargo.toml @@ -22,7 +22,7 @@ futures-util = "0.3" url = { workspace = true } bounded-integer = { workspace = true } serde_with = { workspace = true } -bounded-vec = { workspace = true, features=["serde"] } +bounded-vec = { workspace = true, features = ["serde"] } [features] default = ["mnemonic_gen", "ergo-lib/compiler"] diff --git a/bindings/ergo-lib-c-core/src/transaction.rs b/bindings/ergo-lib-c-core/src/transaction.rs index ebebca3cc..31102de1b 100644 --- a/bindings/ergo-lib-c-core/src/transaction.rs +++ b/bindings/ergo-lib-c-core/src/transaction.rs @@ -79,7 +79,7 @@ pub unsafe fn hints_bag_get( } /// TransactionHintsBag -pub struct TransactionHintsBag(pub(crate) ergo_lib::wallet::multi_sig::TransactionHintsBag); +pub struct TransactionHintsBag(pub(crate) ergo_lib::wallet::TransactionHintsBag); pub type TransactionHintsBagPtr = *mut TransactionHintsBag; pub type ConstTransactionHintsBagPtr = *const TransactionHintsBag; @@ -90,7 +90,7 @@ pub unsafe fn transaction_hints_bag_empty( let transaction_hints_bag_out = mut_ptr_as_mut(transaction_hints_bag_out, "transaction_hints_bag_out")?; *transaction_hints_bag_out = Box::into_raw(Box::new(TransactionHintsBag( - ergo_lib::wallet::multi_sig::TransactionHintsBag::empty(), + ergo_lib::wallet::TransactionHintsBag::empty(), ))); Ok(()) } diff --git a/bindings/ergo-lib-wasm/src/transaction.rs b/bindings/ergo-lib-wasm/src/transaction.rs index 62f44ae72..cdca918f1 100644 --- a/bindings/ergo-lib-wasm/src/transaction.rs +++ b/bindings/ergo-lib-wasm/src/transaction.rs @@ -76,13 +76,13 @@ impl From TransactionHintsBag { - TransactionHintsBag(ergo_lib::wallet::multi_sig::TransactionHintsBag::empty()) + TransactionHintsBag(ergo_lib::wallet::TransactionHintsBag::empty()) } /// Adding hints for input @@ -106,8 +106,8 @@ impl TransactionHintsBag { } } -impl From for TransactionHintsBag { - fn from(t: ergo_lib::wallet::multi_sig::TransactionHintsBag) -> Self { +impl From for TransactionHintsBag { + fn from(t: ergo_lib::wallet::TransactionHintsBag) -> Self { TransactionHintsBag(t) } } diff --git a/ergo-lib/Cargo.toml b/ergo-lib/Cargo.toml index be79c81a9..c0a554e0f 100644 --- a/ergo-lib/Cargo.toml +++ b/ergo-lib/Cargo.toml @@ -17,9 +17,9 @@ sigma-util = { workspace = true } ergo-chain-types = { workspace = true } ergotree-ir = { workspace = true } ergotree-interpreter = { workspace = true } -ergo-nipopow = { workspace = true } +ergo-nipopow = { workspace = true, optional = true } ergoscript-compiler = { workspace = true, optional = true } -ergo-merkle-tree = { workspace = true } +ergo-merkle-tree = { workspace = true, optional = true } ergo-rest = { workspace = true, optional = true } indexmap = { workspace = true } base16 = { workspace = true } @@ -28,39 +28,44 @@ serde_json = { workspace = true, optional = true } thiserror = { workspace = true } derive_more = { workspace = true } bounded-vec = { workspace = true } -num-bigint = { workspace = true, features = ["serde"] } proptest-derive = { workspace = true, optional = true } k256 = { workspace = true } sha2 = { workspace = true } hmac = { version = "0.12" } pbkdf2 = "0.11" -rand = { workspace = true } +rand = { workspace = true, optional = true } bitvec = { workspace = true, optional = true } -unicode-normalization = "0.1.19" +unicode-normalization = { version = "0.1.19", default-features = false } lazy_static = { workspace = true } proptest = { workspace = true, optional = true } serde_with = { workspace = true, optional = true } -itertools = { workspace = true } +hashbrown = { workspace = true } [features] -default = ["json"] +default = ["std", "json", "nipopow", "merkle"] +std = ["rand", "ergotree-ir/std", "ergotree-interpreter/std"] json = [ "serde", "serde_json", "serde_with", "bounded-vec/serde", "ergotree-ir/json", + "ergotree-interpreter/json", + "ergo-merkle-tree?/json", ] compiler = ["ergoscript-compiler"] arbitrary = [ + "std", "proptest", "proptest-derive", "ergotree-ir/arbitrary", "ergo-chain-types/arbitrary", "ergotree-interpreter/arbitrary", ] -mnemonic_gen = ["bitvec"] +merkle = ["ergo-merkle-tree"] +nipopow = ["ergo-nipopow"] +mnemonic_gen = ["bitvec", "rand"] rest = ["ergo-rest"] [dev-dependencies] diff --git a/ergo-lib/src/chain/contract.rs b/ergo-lib/src/chain/contract.rs index 53c1df5aa..4a56f8a39 100644 --- a/ergo-lib/src/chain/contract.rs +++ b/ergo-lib/src/chain/contract.rs @@ -37,16 +37,13 @@ impl Contract { } } -#[cfg(test)] +#[cfg(all(test, feature = "compiler"))] #[allow(clippy::unwrap_used)] mod tests { use super::*; - #[cfg(feature = "compiler")] #[test] fn compile() { - let contract = - Contract::compile("HEIGHT", ergoscript_compiler::script_env::ScriptEnv::new()).unwrap(); - dbg!(&contract); + Contract::compile("HEIGHT", ergoscript_compiler::script_env::ScriptEnv::new()).unwrap(); } } diff --git a/ergo-lib/src/chain/ergo_box/box_builder.rs b/ergo-lib/src/chain/ergo_box/box_builder.rs index 326f113e7..8958be9f0 100644 --- a/ergo-lib/src/chain/ergo_box/box_builder.rs +++ b/ergo-lib/src/chain/ergo_box/box_builder.rs @@ -1,7 +1,10 @@ //! ErgoBoxCandidate builder -use std::collections::HashMap; -use std::convert::{TryFrom, TryInto}; +use alloc::string::String; +use alloc::string::ToString; +use alloc::vec::Vec; +use core::convert::{TryFrom, TryInto}; +use hashbrown::HashMap; use ergotree_ir::chain::address::AddressEncoderError; use ergotree_ir::chain::ergo_box::box_value::BoxValue; diff --git a/ergo-lib/src/chain/json.rs b/ergo-lib/src/chain/json.rs index 177f927ff..7bf8364d4 100644 --- a/ergo-lib/src/chain/json.rs +++ b/ergo-lib/src/chain/json.rs @@ -1,5 +1,7 @@ //! JSON serialization +use alloc::string::String; +use alloc::vec::Vec; use serde::{Deserialize, Serialize}; use ergotree_interpreter::sigma_protocol::prover::ProofBytes; diff --git a/ergo-lib/src/chain/json/hint.rs b/ergo-lib/src/chain/json/hint.rs index 4c3c34b76..b4f97f80e 100644 --- a/ergo-lib/src/chain/json/hint.rs +++ b/ergo-lib/src/chain/json/hint.rs @@ -1,9 +1,10 @@ -use std::collections::HashMap; +use alloc::vec::Vec; +use hashbrown::HashMap; use ergotree_interpreter::sigma_protocol::prover::hint::{Hint, HintsBag}; use serde::{Deserialize, Serialize}; -use crate::wallet::multi_sig::TransactionHintsBag; +use crate::wallet::TransactionHintsBag; #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] pub struct TransactionHintsBagJson { @@ -51,7 +52,7 @@ impl From for TransactionHintsBag { #[cfg(test)] mod tests { - use crate::wallet::multi_sig::TransactionHintsBag; + use crate::wallet::TransactionHintsBag; use proptest::prelude::*; proptest! { diff --git a/ergo-lib/src/chain/json/parameters.rs b/ergo-lib/src/chain/json/parameters.rs index 26f4d561d..bb4769504 100644 --- a/ergo-lib/src/chain/json/parameters.rs +++ b/ergo-lib/src/chain/json/parameters.rs @@ -1,6 +1,6 @@ use crate::chain::parameters::{Parameter, Parameters}; +use hashbrown::HashMap; use serde::{Deserialize, Serialize}; -use std::collections::HashMap; #[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)] pub struct ParametersJson { diff --git a/ergo-lib/src/chain/json/transaction.rs b/ergo-lib/src/chain/json/transaction.rs index 0b411df57..5fda4d38b 100644 --- a/ergo-lib/src/chain/json/transaction.rs +++ b/ergo-lib/src/chain/json/transaction.rs @@ -1,4 +1,6 @@ -use std::convert::TryFrom; +use alloc::string::String; +use alloc::vec::Vec; +use core::convert::TryFrom; use thiserror::Error; use crate::chain::transaction::unsigned::UnsignedTransaction; diff --git a/ergo-lib/src/chain/parameters.rs b/ergo-lib/src/chain/parameters.rs index 67ecce489..e7888f340 100644 --- a/ergo-lib/src/chain/parameters.rs +++ b/ergo-lib/src/chain/parameters.rs @@ -1,5 +1,5 @@ //! Blockchain parameters. This module defines adjustable blockchain parameters that can be voted on by miners -use std::collections::HashMap; +use hashbrown::HashMap; #[repr(i8)] #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)] @@ -103,7 +103,7 @@ impl Parameters { } } -impl std::default::Default for Parameters { +impl Default for Parameters { /// Default blockchain parameters // Taken from https://github.com/ergoplatform/ergo/blob/master/ergo-core/src/main/scala/org/ergoplatform/settings/Parameters.scala#L291 fn default() -> Self { diff --git a/ergo-lib/src/chain/transaction.rs b/ergo-lib/src/chain/transaction.rs index c9d9ec24f..928a00f03 100644 --- a/ergo-lib/src/chain/transaction.rs +++ b/ergo-lib/src/chain/transaction.rs @@ -7,6 +7,9 @@ pub mod reduced; pub(crate) mod storage_rent; pub mod unsigned; +use alloc::string::String; +use alloc::string::ToString; +use alloc::vec::Vec; use bounded_vec::BoundedVec; use ergo_chain_types::blake2b256_hash; use ergotree_interpreter::eval::env::Env; @@ -25,6 +28,7 @@ use ergotree_ir::chain::ergo_box::ErgoBox; use ergotree_ir::chain::ergo_box::ErgoBoxCandidate; use ergotree_ir::chain::token::TokenId; pub use ergotree_ir::chain::tx_id::TxId; +use ergotree_ir::chain::IndexSet; use ergotree_ir::ergo_tree::ErgoTreeError; use thiserror::Error; @@ -46,11 +50,9 @@ use self::ergo_transaction::TxValidationError; use self::storage_rent::try_spend_storage_rent; use self::unsigned::UnsignedTransaction; -use indexmap::IndexSet; - -use std::convert::TryFrom; -use std::convert::TryInto; -use std::iter::FromIterator; +use core::convert::TryFrom; +use core::convert::TryInto; +use core::iter::FromIterator; use super::ergo_state_context::ErgoStateContext; @@ -303,7 +305,8 @@ impl SigmaSerializable for Transaction { "too many tokens in transaction".to_string(), )); } - let mut token_ids = IndexSet::with_capacity(tokens_count as usize); + let mut token_ids = + IndexSet::with_capacity_and_hasher(tokens_count as usize, Default::default()); for _ in 0..tokens_count { token_ids.insert(TokenId::sigma_parse(r)?); } diff --git a/ergo-lib/src/chain/transaction/ergo_transaction.rs b/ergo-lib/src/chain/transaction/ergo_transaction.rs index 5ef83f9b8..cd3a14acb 100644 --- a/ergo-lib/src/chain/transaction/ergo_transaction.rs +++ b/ergo-lib/src/chain/transaction/ergo_transaction.rs @@ -8,7 +8,6 @@ use ergotree_ir::{ }, serialization::SigmaSerializationError, }; -use itertools::Itertools; use thiserror::Error; use crate::wallet::tx_context::TransactionContextError; @@ -104,7 +103,7 @@ pub trait ErgoTransaction { // Check if there are no double-spends in input (one BoxId being spent more than once) let len = inputs.len(); - let unique_count = inputs.unique().count(); + let unique_count = inputs.collect::>().len(); if unique_count != len { return Err(TxValidationError::DoubleSpend(unique_count, len)); } diff --git a/ergo-lib/src/chain/transaction/input/prover_result/json.rs b/ergo-lib/src/chain/transaction/input/prover_result/json.rs index 56a3e8ccf..6b0e0e74f 100644 --- a/ergo-lib/src/chain/transaction/input/prover_result/json.rs +++ b/ergo-lib/src/chain/transaction/input/prover_result/json.rs @@ -1,5 +1,7 @@ -use std::str::FromStr; +use core::str::FromStr; +use alloc::string::String; +use alloc::vec::Vec; use ergotree_ir::chain::context_extension::ContextExtension; use serde::ser::SerializeStruct; use serde::Serialize; diff --git a/ergo-lib/src/chain/transaction/unsigned.rs b/ergo-lib/src/chain/transaction/unsigned.rs index 507287b57..e0b3e78c8 100644 --- a/ergo-lib/src/chain/transaction/unsigned.rs +++ b/ergo-lib/src/chain/transaction/unsigned.rs @@ -6,16 +6,17 @@ use super::DataInput; use super::Transaction; use super::TxIoVec; use super::{distinct_token_ids, TransactionError}; +use alloc::vec::Vec; use bounded_vec::BoundedVec; use ergo_chain_types::blake2b256_hash; +use core::convert::TryInto; use ergotree_ir::chain::ergo_box::ErgoBox; use ergotree_ir::chain::ergo_box::ErgoBoxCandidate; use ergotree_ir::chain::token::TokenId; use ergotree_ir::chain::tx_id::TxId; +use ergotree_ir::chain::IndexSet; use ergotree_ir::serialization::SigmaSerializationError; -use indexmap::IndexSet; -use std::convert::TryInto; /// Unsigned (inputs without proofs) transaction #[cfg_attr(feature = "json", derive(serde::Serialize, serde::Deserialize))] diff --git a/ergo-lib/src/lib.rs b/ergo-lib/src/lib.rs index a629bc845..390e7b770 100644 --- a/ergo-lib/src/lib.rs +++ b/ergo-lib/src/lib.rs @@ -1,5 +1,6 @@ //! ErgoTree IR +#![cfg_attr(not(feature = "std"), no_std)] // Coding conventions #![forbid(unsafe_code)] #![deny(non_upper_case_globals)] @@ -20,6 +21,11 @@ #![deny(clippy::unreachable)] #![deny(clippy::panic)] +#[cfg(all(not(feature = "std"), any(feature = "nipopow", feature = "merkle")))] +compile_error!("ergo-nipopow and ergo-merkle-tree are not supported without std"); + +#[macro_use] +extern crate alloc; pub mod chain; pub mod constants; mod utils; @@ -30,8 +36,10 @@ pub mod wallet; /// Ergo blockchain types pub extern crate ergo_chain_types; /// Ergo Merkle Tree and Merkle verification tools +#[cfg(feature = "merkle")] pub extern crate ergo_merkle_tree; /// Ergo NiPoPoW implementation +#[cfg(feature = "nipopow")] pub extern crate ergo_nipopow; /// Re-exported types from dependencies #[cfg(feature = "rest")] diff --git a/ergo-lib/src/wallet.rs b/ergo-lib/src/wallet.rs index abe2ac038..2f6720bc5 100644 --- a/ergo-lib/src/wallet.rs +++ b/ergo-lib/src/wallet.rs @@ -8,16 +8,21 @@ pub mod miner_fee; pub mod mnemonic; #[cfg(feature = "mnemonic_gen")] pub mod mnemonic_generator; +#[cfg(feature = "std")] pub mod multi_sig; pub mod secret_key; pub mod signing; pub mod tx_builder; pub mod tx_context; +use crate::ergotree_interpreter::sigma_protocol::prover::hint::{Hint, HintsBag}; +use alloc::boxed::Box; +use alloc::vec::Vec; use ergotree_interpreter::sigma_protocol::private_input::PrivateInput; use ergotree_interpreter::sigma_protocol::prover::Prover; use ergotree_interpreter::sigma_protocol::prover::ProverError; use ergotree_interpreter::sigma_protocol::prover::TestProver; +use hashbrown::HashMap; use secret_key::SecretKey; use signing::{sign_transaction, TxSigningError}; use thiserror::Error; @@ -27,15 +32,16 @@ use crate::chain::transaction::reduced::ReducedTransaction; use crate::chain::transaction::unsigned::UnsignedTransaction; use crate::chain::transaction::Input; use crate::chain::transaction::Transaction; +#[cfg(feature = "std")] use crate::ergotree_ir::sigma_protocol::sigma_boolean::SigmaBoolean; use crate::wallet::mnemonic::Mnemonic; -use crate::wallet::multi_sig::{ - generate_commitments, generate_commitments_for, TransactionHintsBag, -}; +#[cfg(feature = "std")] +use crate::wallet::multi_sig::{generate_commitments, generate_commitments_for}; use self::ext_secret_key::ExtSecretKey; use self::ext_secret_key::ExtSecretKeyError; use self::signing::make_context; +#[cfg(feature = "std")] use self::signing::sign_message; use self::signing::sign_reduced_transaction; use self::signing::sign_tx_input; @@ -112,6 +118,7 @@ impl Wallet { } /// Generate commitments for Transaction by wallet secrets + #[cfg(feature = "std")] pub fn generate_commitments( &self, tx_context: TransactionContext, @@ -127,6 +134,7 @@ impl Wallet { } /// Generate Commitments for reduced Transaction + #[cfg(feature = "std")] pub fn generate_commitments_for_reduced_transaction( &self, reduced_tx: ReducedTransaction, @@ -147,6 +155,7 @@ impl Wallet { } /// Signs a message + #[cfg(feature = "std")] pub fn sign_message( &self, sigma_tree: SigmaBoolean, @@ -178,3 +187,106 @@ impl Wallet { )?) } } + +#[cfg(feature = "arbitrary")] +use proptest::prelude::Strategy; +/// TransactionHintsBag +#[cfg_attr(feature = "json", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr( + feature = "json", + serde( + try_from = "crate::chain::json::hint::TransactionHintsBagJson", + into = "crate::chain::json::hint::TransactionHintsBagJson" + ) +)] +#[cfg_attr(feature = "arbitrary", derive(proptest_derive::Arbitrary))] +#[derive(PartialEq, Debug, Clone)] +pub struct TransactionHintsBag { + #[cfg_attr( + feature = "arbitrary", + proptest( + strategy = "proptest::collection::hash_map(proptest::prelude::any::(), proptest::prelude::any::(), 0..5).prop_map(HashMap::from_iter)" + ) + )] + pub(crate) secret_hints: HashMap, + #[cfg_attr( + feature = "arbitrary", + proptest( + strategy = "proptest::collection::hash_map(proptest::prelude::any::(), proptest::prelude::any::(), 0..5).prop_map(HashMap::from_iter)" + ) + )] + pub(crate) public_hints: HashMap, +} + +impl TransactionHintsBag { + /// Empty TransactionHintsBag + pub fn empty() -> Self { + TransactionHintsBag { + secret_hints: HashMap::new(), + public_hints: HashMap::new(), + } + } + + /// Replacing Hints for an input index + pub fn replace_hints_for_input(&mut self, index: usize, hints_bag: HintsBag) { + let public: Vec = hints_bag + .hints + .clone() + .into_iter() + .filter(|hint| matches!(hint, Hint::CommitmentHint(_))) + .collect(); + let secret: Vec = hints_bag + .hints + .into_iter() + .filter(|hint| matches!(hint, Hint::SecretProven(_))) + .collect(); + + self.secret_hints.insert(index, HintsBag { hints: secret }); + self.public_hints.insert(index, HintsBag { hints: public }); + } + + /// Adding hints for a input index + pub fn add_hints_for_input(&mut self, index: usize, hints_bag: HintsBag) { + let mut public: Vec = hints_bag + .hints + .clone() + .into_iter() + .filter(|hint| matches!(hint, Hint::CommitmentHint(_))) + .collect(); + let mut secret: Vec = hints_bag + .hints + .into_iter() + .filter(|hint| matches!(hint, Hint::SecretProven(_))) + .collect(); + let secret_bag = HintsBag::empty(); + let public_bag = HintsBag::empty(); + let old_secret: &Vec = &self.secret_hints.get(&index).unwrap_or(&secret_bag).hints; + for hint in old_secret { + secret.push(hint.clone()); + } + + let old_public: &Vec = &self.public_hints.get(&index).unwrap_or(&public_bag).hints; + for hint in old_public { + public.push(hint.clone()); + } + self.secret_hints.insert(index, HintsBag { hints: secret }); + self.public_hints.insert(index, HintsBag { hints: public }); + } + + /// Outputting HintsBag corresponding for an index + pub fn all_hints_for_input(&self, index: usize) -> HintsBag { + let mut hints: Vec = Vec::new(); + let secret_bag = HintsBag::empty(); + let public_bag = HintsBag::empty(); + let secrets: &Vec = &self.secret_hints.get(&index).unwrap_or(&secret_bag).hints; + for hint in secrets { + hints.push(hint.clone()); + } + let public: &Vec = &self.public_hints.get(&index).unwrap_or(&public_bag).hints; + for hint in public { + hints.push(hint.clone()); + } + let hints_bag: HintsBag = HintsBag { hints }; + hints_bag + } +} diff --git a/ergo-lib/src/wallet/box_selector.rs b/ergo-lib/src/wallet/box_selector.rs index 917f84948..22222ca68 100644 --- a/ergo-lib/src/wallet/box_selector.rs +++ b/ergo-lib/src/wallet/box_selector.rs @@ -2,8 +2,9 @@ mod simple; -use std::collections::HashMap; +use hashbrown::HashMap; +use alloc::vec::Vec; use bounded_vec::BoundedVec; use ergotree_ir::chain::ergo_box::box_value::BoxValue; use ergotree_ir::chain::ergo_box::BoxId; diff --git a/ergo-lib/src/wallet/box_selector/simple.rs b/ergo-lib/src/wallet/box_selector/simple.rs index da6d2c812..987aec383 100644 --- a/ergo-lib/src/wallet/box_selector/simple.rs +++ b/ergo-lib/src/wallet/box_selector/simple.rs @@ -1,9 +1,11 @@ //! Naive box selector, collects inputs until target balance is reached -use std::cmp::min; -use std::collections::HashMap; -use std::convert::TryInto; +use core::cmp::min; +use core::convert::TryInto; +use hashbrown::HashMap; +use alloc::string::String; +use alloc::vec::Vec; use ergotree_ir::chain::ergo_box::box_value::BoxValue; use ergotree_ir::chain::ergo_box::BoxTokens; use ergotree_ir::chain::ergo_box::ErgoBox; @@ -290,7 +292,7 @@ fn make_change_boxes( #[allow(clippy::unwrap_used, clippy::panic)] mod tests { - use std::convert::TryFrom; + use core::convert::TryFrom; use ergotree_ir::chain::{ address::{AddressEncoder, NetworkPrefix}, diff --git a/ergo-lib/src/wallet/derivation_path.rs b/ergo-lib/src/wallet/derivation_path.rs index 8b46a1fa3..8b9340621 100644 --- a/ergo-lib/src/wallet/derivation_path.rs +++ b/ergo-lib/src/wallet/derivation_path.rs @@ -2,8 +2,14 @@ //! BIP-44 //! and EIP-3 +use alloc::{ + boxed::Box, + collections::VecDeque, + string::{String, ToString}, + vec::Vec, +}; +use core::{fmt, num::ParseIntError, str::FromStr}; use derive_more::From; -use std::{collections::VecDeque, fmt, num::ParseIntError, str::FromStr}; use thiserror::Error; /// Index for hardened derivation diff --git a/ergo-lib/src/wallet/ext_pub_key.rs b/ergo-lib/src/wallet/ext_pub_key.rs index d6ab42efb..cec8b3710 100644 --- a/ergo-lib/src/wallet/ext_pub_key.rs +++ b/ergo-lib/src/wallet/ext_pub_key.rs @@ -1,6 +1,7 @@ //! Extended public key operations according to BIP-32 -use std::convert::TryInto; +use core::convert::TryInto; +use alloc::string::String; use ergo_chain_types::EcPoint; use ergotree_interpreter::sigma_protocol::private_input::DlogProverInput; use ergotree_ir::chain::address::Address; diff --git a/ergo-lib/src/wallet/ext_secret_key.rs b/ergo-lib/src/wallet/ext_secret_key.rs index 0d17d7e87..16bfaaa8e 100644 --- a/ergo-lib/src/wallet/ext_secret_key.rs +++ b/ergo-lib/src/wallet/ext_secret_key.rs @@ -1,5 +1,5 @@ //! Extended private key operations according to BIP-32 -use std::convert::TryInto; +use core::convert::TryInto; use super::{ derivation_path::{ChildIndex, ChildIndexError, DerivationPath}, @@ -8,6 +8,7 @@ use super::{ secret_key::SecretKey, }; use crate::ArrLength; +use alloc::{string::String, vec::Vec}; use ergotree_interpreter::sigma_protocol::{private_input::DlogProverInput, wscalar::Wscalar}; use ergotree_ir::{ serialization::{SigmaParsingError, SigmaSerializable, SigmaSerializationError}, diff --git a/ergo-lib/src/wallet/miner_fee.rs b/ergo-lib/src/wallet/miner_fee.rs index cbbaf0e2f..9e2d5b1dd 100644 --- a/ergo-lib/src/wallet/miner_fee.rs +++ b/ergo-lib/src/wallet/miner_fee.rs @@ -1,5 +1,6 @@ //! Miner fee included in transaction +use alloc::string::String; use ergotree_ir::chain::address::Address; use ergotree_ir::chain::address::AddressEncoder; use ergotree_ir::chain::address::NetworkPrefix; diff --git a/ergo-lib/src/wallet/mnemonic.rs b/ergo-lib/src/wallet/mnemonic.rs index 90c8d1714..a223c9c38 100644 --- a/ergo-lib/src/wallet/mnemonic.rs +++ b/ergo-lib/src/wallet/mnemonic.rs @@ -1,5 +1,6 @@ //! Mnemonic operations according to BIP32/BIP39 +use alloc::string::String; use hmac::Hmac; use pbkdf2::pbkdf2; use sha2::Sha512; diff --git a/ergo-lib/src/wallet/mnemonic_generator.rs b/ergo-lib/src/wallet/mnemonic_generator.rs index c88d725ab..e824fc8e6 100644 --- a/ergo-lib/src/wallet/mnemonic_generator.rs +++ b/ergo-lib/src/wallet/mnemonic_generator.rs @@ -1,5 +1,6 @@ //! Mnemonic generation +use alloc::{string::String, vec::Vec}; use bitvec::prelude::*; use rand::RngCore; use sha2::{Digest, Sha256}; diff --git a/ergo-lib/src/wallet/multi_sig.rs b/ergo-lib/src/wallet/multi_sig.rs index 92513aea1..06d4950ed 100644 --- a/ergo-lib/src/wallet/multi_sig.rs +++ b/ergo-lib/src/wallet/multi_sig.rs @@ -1,4 +1,4 @@ -//! multi sig prove crate::chain::ergo_state_context::ErgoStateContext; +//! multi sig prover use crate::chain::ergo_state_context::ErgoStateContext; use crate::chain::transaction::unsigned::UnsignedTransaction; use crate::chain::transaction::Transaction; @@ -19,114 +19,14 @@ use crate::ergotree_ir::sigma_protocol::sigma_boolean::SigmaConjecture; use crate::ergotree_ir::sigma_protocol::sigma_boolean::SigmaConjectureItems; use crate::ergotree_ir::sigma_protocol::sigma_boolean::SigmaProofOfKnowledgeTree; use crate::wallet::signing::{make_context, TransactionContext, TxSigningError}; +use alloc::vec::Vec; use ergotree_interpreter::sigma_protocol::sig_serializer::parse_sig_compute_challenges; use ergotree_interpreter::sigma_protocol::unchecked_tree::UncheckedTree; use ergotree_interpreter::sigma_protocol::verifier::compute_commitments; -use std::collections::HashMap; use super::signing::update_context; use super::tx_context::TransactionContextError; - -/// TransactionHintsBag -#[cfg_attr(feature = "json", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr( - feature = "json", - serde( - try_from = "crate::chain::json::hint::TransactionHintsBagJson", - into = "crate::chain::json::hint::TransactionHintsBagJson" - ) -)] -#[cfg_attr(feature = "arbitrary", derive(proptest_derive::Arbitrary))] -#[derive(PartialEq, Debug, Clone)] -pub struct TransactionHintsBag { - #[cfg_attr( - feature = "arbitrary", - proptest( - strategy = "proptest::collection::hash_map(proptest::prelude::any::(), proptest::prelude::any::(), 0..5)" - ) - )] - pub(crate) secret_hints: HashMap, - #[cfg_attr( - feature = "arbitrary", - proptest( - strategy = "proptest::collection::hash_map(proptest::prelude::any::(), proptest::prelude::any::(), 0..5)" - ) - )] - pub(crate) public_hints: HashMap, -} - -impl TransactionHintsBag { - /// Empty TransactionHintsBag - pub fn empty() -> Self { - TransactionHintsBag { - secret_hints: HashMap::new(), - public_hints: HashMap::new(), - } - } - - /// Replacing Hints for an input index - pub fn replace_hints_for_input(&mut self, index: usize, hints_bag: HintsBag) { - let public: Vec = hints_bag - .hints - .clone() - .into_iter() - .filter(|hint| matches!(hint, Hint::CommitmentHint(_))) - .collect(); - let secret: Vec = hints_bag - .hints - .into_iter() - .filter(|hint| matches!(hint, Hint::SecretProven(_))) - .collect(); - - self.secret_hints.insert(index, HintsBag { hints: secret }); - self.public_hints.insert(index, HintsBag { hints: public }); - } - - /// Adding hints for a input index - pub fn add_hints_for_input(&mut self, index: usize, hints_bag: HintsBag) { - let mut public: Vec = hints_bag - .hints - .clone() - .into_iter() - .filter(|hint| matches!(hint, Hint::CommitmentHint(_))) - .collect(); - let mut secret: Vec = hints_bag - .hints - .into_iter() - .filter(|hint| matches!(hint, Hint::SecretProven(_))) - .collect(); - let secret_bag = HintsBag::empty(); - let public_bag = HintsBag::empty(); - let old_secret: &Vec = &self.secret_hints.get(&index).unwrap_or(&secret_bag).hints; - for hint in old_secret { - secret.push(hint.clone()); - } - - let old_public: &Vec = &self.public_hints.get(&index).unwrap_or(&public_bag).hints; - for hint in old_public { - public.push(hint.clone()); - } - self.secret_hints.insert(index, HintsBag { hints: secret }); - self.public_hints.insert(index, HintsBag { hints: public }); - } - - /// Outputting HintsBag corresponding for an index - pub fn all_hints_for_input(&self, index: usize) -> HintsBag { - let mut hints: Vec = Vec::new(); - let secret_bag = HintsBag::empty(); - let public_bag = HintsBag::empty(); - let secrets: &Vec = &self.secret_hints.get(&index).unwrap_or(&secret_bag).hints; - for hint in secrets { - hints.push(hint.clone()); - } - let public: &Vec = &self.public_hints.get(&index).unwrap_or(&public_bag).hints; - for hint in public { - hints.push(hint.clone()); - } - let hints_bag: HintsBag = HintsBag { hints }; - hints_bag - } -} +use super::TransactionHintsBag; /// A method which is extracting partial proofs of secret knowledge for particular secrets with their /// respective public images given. Useful for distributed signature applications. @@ -392,6 +292,7 @@ mod tests { use crate::ergotree_ir::mir::sigma_and::SigmaAnd; use crate::ergotree_ir::serialization::SigmaSerializable; use crate::ergotree_ir::sigma_protocol::sigma_boolean::cand::Cand; + use core::convert::{TryFrom, TryInto}; use ergo_chain_types::Base16DecodedBytes; use ergotree_interpreter::sigma_protocol::private_input::DhTupleProverInput; use ergotree_interpreter::sigma_protocol::wscalar::Wscalar; @@ -403,7 +304,6 @@ mod tests { use ergotree_ir::sigma_protocol::sigma_boolean::SigmaProp; use ergotree_ir::types::stype::SType; use sigma_test_util::force_any_val; - use std::convert::{TryFrom, TryInto}; #[test] fn extract_hint() { diff --git a/ergo-lib/src/wallet/secret_key.rs b/ergo-lib/src/wallet/secret_key.rs index 030760cf4..bc4d2d18e 100644 --- a/ergo-lib/src/wallet/secret_key.rs +++ b/ergo-lib/src/wallet/secret_key.rs @@ -1,5 +1,6 @@ //! Secret types +use alloc::vec::Vec; use derive_more::From; use ergo_chain_types::EcPoint; use ergotree_interpreter::sigma_protocol::private_input::DhTupleProverInput; @@ -29,11 +30,13 @@ pub enum SecretKey { impl SecretKey { /// Generates random DlogProverInput + #[cfg(feature = "std")] pub fn random_dlog() -> SecretKey { SecretKey::DlogSecretKey(DlogProverInput::random()) } /// Generates random DhTupleProverInput + #[cfg(feature = "std")] pub fn random_dht() -> SecretKey { SecretKey::DhtSecretKey(DhTupleProverInput::random()) } @@ -136,7 +139,7 @@ impl From for PrivateInput { #[allow(clippy::unwrap_used)] mod tests { use super::*; - use std::convert::TryInto; + use core::convert::TryInto; #[test] fn dlog_roundtrip() { diff --git a/ergo-lib/src/wallet/signing.rs b/ergo-lib/src/wallet/signing.rs index 28283f41c..27b06552e 100644 --- a/ergo-lib/src/wallet/signing.rs +++ b/ergo-lib/src/wallet/signing.rs @@ -7,13 +7,14 @@ use crate::chain::{ ergo_state_context::ErgoStateContext, transaction::{unsigned::UnsignedTransaction, Transaction}, }; +use alloc::vec::Vec; use ergotree_interpreter::sigma_protocol::prover::hint::HintsBag; use ergotree_interpreter::sigma_protocol::sig_serializer::SigParsingError; use ergotree_ir::serialization::SigmaSerializationError; use ergotree_ir::sigma_protocol::sigma_boolean::SigmaBoolean; use crate::chain::transaction::storage_rent::check_storage_rent_conditions; -use crate::wallet::multi_sig::TransactionHintsBag; +use crate::wallet::TransactionHintsBag; use ergotree_interpreter::sigma_protocol::prover::ProofBytes; use ergotree_interpreter::sigma_protocol::prover::Prover; use ergotree_interpreter::sigma_protocol::prover::ProverError; @@ -289,11 +290,11 @@ mod tests { }; use crate::wallet::secret_key::SecretKey; use crate::wallet::Wallet; + use core::convert::TryFrom; + use core::convert::TryInto; use ergotree_ir::chain::ergo_box::ErgoBoxCandidate; use ergotree_ir::ergo_tree::ErgoTree; use ergotree_ir::mir::expr::Expr; - use std::convert::TryFrom; - use std::convert::TryInto; use std::rc::Rc; fn verify_tx_proofs( diff --git a/ergo-lib/src/wallet/tx_builder.rs b/ergo-lib/src/wallet/tx_builder.rs index 160ca279a..651d5831f 100644 --- a/ergo-lib/src/wallet/tx_builder.rs +++ b/ergo-lib/src/wallet/tx_builder.rs @@ -1,13 +1,16 @@ //! Builder for an UnsignedTransaction +use alloc::string::String; +use alloc::string::ToString; +use alloc::vec::Vec; +use core::convert::TryInto; use ergotree_ir::chain::context::TxIoVec; use ergotree_ir::chain::context_extension::ContextExtension; use ergotree_ir::chain::token::TokenAmount; use ergotree_ir::chain::token::TokenAmountError; use ergotree_ir::ergo_tree::ErgoTree; -use std::collections::HashMap; -use std::collections::HashSet; -use std::convert::TryInto; +use hashbrown::HashMap; +use hashbrown::HashSet; use bounded_vec::BoundedVecOutOfBounds; use ergotree_interpreter::sigma_protocol; @@ -379,7 +382,7 @@ fn check_unused_token_burn_permit( #[allow(clippy::unwrap_used, clippy::panic)] mod tests { - use std::convert::TryInto; + use core::convert::TryInto; use ergotree_ir::chain::ergo_box::arbitrary::ArbBoxParameters; use ergotree_ir::chain::ergo_box::box_value::checked_sum; diff --git a/ergo-lib/src/wallet/tx_context.rs b/ergo-lib/src/wallet/tx_context.rs index 88b583c30..80216b7f9 100644 --- a/ergo-lib/src/wallet/tx_context.rs +++ b/ergo-lib/src/wallet/tx_context.rs @@ -1,7 +1,8 @@ //! Transaction context -use std::collections::hash_map::Entry; -use std::collections::HashMap; +use alloc::vec::Vec; +use hashbrown::hash_map::Entry; +use hashbrown::HashMap; use crate::chain::ergo_state_context::ErgoStateContext; use crate::chain::transaction::ergo_transaction::{ErgoTransaction, TxValidationError}; @@ -288,6 +289,7 @@ pub enum TransactionContextError { mod test { use std::collections::HashMap; + use alloc::vec::Vec; use ergotree_interpreter::sigma_protocol::prover::ProofBytes; use ergotree_ir::chain::context::TxIoVec; use ergotree_ir::chain::context_extension::ContextExtension; @@ -387,10 +389,10 @@ mod test { let parameters = Parameters::default(); let sufficient_amount = ErgoBox::MAX_BOX_SIZE as u64 * parameters.min_value_per_byte() as u64; - let max_outputs = std::cmp::min(i16::MAX as u16, (input_sum / sufficient_amount) as u16); - let outputs = std::cmp::min( + let max_outputs = core::cmp::min(i16::MAX as u16, (input_sum / sufficient_amount) as u16); + let outputs = core::cmp::min( max_outputs, - std::cmp::max(boxes.len() + 1, rng.gen_range(0..boxes.len() * 2)) as u16, + core::cmp::max(boxes.len() + 1, rng.gen_range(0..boxes.len() * 2)) as u16, ); assert!(outputs > 0); assert!(sufficient_amount * (outputs as u64) <= input_sum); @@ -667,7 +669,6 @@ mod test { .map(|b| b.creation_height) .max() .unwrap(); - dbg!(height); let mut state_context: ErgoStateContext = force_any_val(); state_context.pre_header.height = height; state_context.pre_header.version = version; diff --git a/ergo-merkle-tree/Cargo.toml b/ergo-merkle-tree/Cargo.toml index 9482cdce0..b1529d1ec 100644 --- a/ergo-merkle-tree/Cargo.toml +++ b/ergo-merkle-tree/Cargo.toml @@ -10,19 +10,19 @@ description = "Merkle tree proofs" [dependencies] blake2 = { workspace = true } -base16 = { workspace = true, optional = true } +base16 = { workspace = true, features = ["std"], optional = true } serde = { workspace = true, optional = true } serde_repr = { version = "0.1.7", optional = true } serde_json = { workspace = true, optional = true } -# currently thiserror is only needed for json conversion, so it's feature-gated behind json. +# currently thiserror is only needed for json conversion, so it's feature-gated behind json. # This may change in the future -thiserror = { workspace = true, optional = true } +thiserror = { workspace = true, optional = true } itertools = { workspace = true } -proptest-derive = {workspace = true, optional = true } +proptest-derive = { workspace = true, optional = true } sigma-ser = { workspace = true } ergo-chain-types = { workspace = true } sigma-util = { workspace = true } -proptest = { workspace = true , optional = true } +proptest = { workspace = true, optional = true } [features] default = ["json"] diff --git a/ergo-nipopow/Cargo.toml b/ergo-nipopow/Cargo.toml index 2c21911d4..b1cd55b92 100644 --- a/ergo-nipopow/Cargo.toml +++ b/ergo-nipopow/Cargo.toml @@ -6,9 +6,7 @@ authors = ["Denys Zadorozhnyi "] repository.workspace = true edition.workspace = true description = "Ergo blockchain types" -exclude = [ - "proptest-regressions/*" -] +exclude = ["proptest-regressions/*"] [lib] crate-type = ["cdylib", "rlib"] @@ -29,10 +27,15 @@ ergo-chain-types = { workspace = true } ergo-merkle-tree = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } -proptest = { workspace = true , optional = true } +proptest = { workspace = true, optional = true } [dev-dependencies] [features] -default = [] -arbitrary = ["proptest", "proptest-derive", "ergo-chain-types/arbitrary", "ergotree-ir/arbitrary"] +default = ["sigma-ser/std", "ergo-merkle-tree/json", "serde/std"] +arbitrary = [ + "proptest", + "proptest-derive", + "ergo-chain-types/arbitrary", + "ergotree-ir/arbitrary", +] diff --git a/ergo-p2p/src/message/handshake.rs b/ergo-p2p/src/message/handshake.rs index 290813b47..bc3052b82 100644 --- a/ergo-p2p/src/message/handshake.rs +++ b/ergo-p2p/src/message/handshake.rs @@ -8,6 +8,7 @@ use crate::PeerSpec; /// No further communication is possible until both peers have exchanged their handshakes. /// peerSpec - general (declared) information about peer /// time - handshake time +#[allow(unused)] pub struct Handshake { /// Peer specification pub peer_spec: PeerSpec,