From f8109a860017dcf733e7010e4ec5cd38ca2603a9 Mon Sep 17 00:00:00 2001 From: Kamal Ahmad Date: Thu, 7 Nov 2024 16:27:23 +0500 Subject: [PATCH 01/16] Update thiserror to v2 --- Cargo.toml | 2 +- ergo-lib/src/chain/transaction/ergo_transaction.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ee934a1f8..ef4c839b3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,7 +38,7 @@ ergo-rest = { version = "^0.13.0", path = "./ergo-rest" } ergo-lib = { version = "^0.28.0", path = "./ergo-lib" } k256 = { version = "0.13.1", features = ["arithmetic", "ecdsa"] } elliptic-curve = { version = "0.12", features = ["ff"] } -thiserror = "1" +thiserror = "2" bounded-vec = { version = "^0.7.0" } bitvec = { version = "1.0.1" } derive_more = { version = "0.99", features = [ diff --git a/ergo-lib/src/chain/transaction/ergo_transaction.rs b/ergo-lib/src/chain/transaction/ergo_transaction.rs index 3da6db931..5ef83f9b8 100644 --- a/ergo-lib/src/chain/transaction/ergo_transaction.rs +++ b/ergo-lib/src/chain/transaction/ergo_transaction.rs @@ -59,10 +59,10 @@ pub enum TxValidationError { /// Negative heights are not allowed after block v1. /// When using sigma-rust where heights are always unsigned, this error may be because creation height was set to be >= 2147483648 NegativeHeight, - #[error("Output box size {0} > maximum {}", ErgoBox::MAX_BOX_SIZE)] + #[error("Output box size {0} > maximum {max_size}", max_size = ErgoBox::MAX_BOX_SIZE)] /// Box size is > [ErgoBox::MAX_BOX_SIZE] BoxSizeExceeded(usize), - #[error("Output box size {0} > maximum {}", ErgoBox::MAX_SCRIPT_SIZE)] + #[error("Output box size {0} > maximum {max_size}", max_size = ErgoBox::MAX_SCRIPT_SIZE)] /// Script size is > [ErgoBox::MAX_SCRIPT_SIZE] ScriptSizeExceeded(usize), #[error("TX context error: {0}")] From 482a88285b6df107f83279a6dd985adc9e781efd Mon Sep 17 00:00:00 2001 From: Kamal Ahmad Date: Thu, 7 Nov 2024 16:45:31 +0500 Subject: [PATCH 02/16] sigma_ser: add no_std support --- Cargo.toml | 11 +++++++---- sigma-ser/Cargo.toml | 5 +++++ sigma-ser/src/lib.rs | 4 ++++ sigma-ser/src/scorex_serialize.rs | 13 +++++++++---- sigma-ser/src/vlq_encode.rs | 23 +++++++++++++++-------- sigma-ser/src/zig_zag_encode.rs | 1 + 6 files changed, 41 insertions(+), 16 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ef4c839b3..f6ea0da3e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,7 +38,7 @@ ergo-rest = { version = "^0.13.0", path = "./ergo-rest" } ergo-lib = { version = "^0.28.0", path = "./ergo-lib" } k256 = { version = "0.13.1", features = ["arithmetic", "ecdsa"] } elliptic-curve = { version = "0.12", features = ["ff"] } -thiserror = "2" +thiserror = { version = "2", default-features = false } bounded-vec = { version = "^0.7.0" } bitvec = { version = "1.0.1" } derive_more = { version = "0.99", features = [ @@ -81,14 +81,17 @@ url = "~2.2" getrandom = { version = "0.2.7" } itertools = "0.10.3" miette = { version = "5", features = ["fancy"] } - +hashbrown = { version = "0.14.3", features = ["serde"] } # dev-dependencies -proptest = { version = "=1.0", default-features = false, features = ["std"] } +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" expect-test = "1.4.1" - +core2 = { version = "0.4.0", default-features = false, features = ["alloc"] } [profile.release] # Tell `rustc` to optimize for small code size. opt-level = "z" diff --git a/sigma-ser/Cargo.toml b/sigma-ser/Cargo.toml index d2dad76ee..9a6ab5658 100644 --- a/sigma-ser/Cargo.toml +++ b/sigma-ser/Cargo.toml @@ -10,10 +10,15 @@ description = "Ergo binary serialization primitives" [lib] crate-type = ["cdylib", "rlib"] +[features] +default = ["std"] +std = ["core2/std"] + [dependencies] thiserror = { workspace = true } bitvec = { workspace = true } bounded-vec = { workspace = true } +core2 = { workspace = true } [dev-dependencies] proptest = { workspace = true } diff --git a/sigma-ser/src/lib.rs b/sigma-ser/src/lib.rs index 20792b1d3..05e7cd084 100644 --- a/sigma-ser/src/lib.rs +++ b/sigma-ser/src/lib.rs @@ -1,5 +1,7 @@ //! Sigma serialization +#![no_std] +// #![cfg_attr(not(feature = "std"), no_std)] // Coding conventions #![forbid(unsafe_code)] #![deny(non_upper_case_globals)] @@ -17,6 +19,8 @@ #![deny(clippy::panic)] #![deny(clippy::wildcard_enum_match_arm)] +extern crate alloc; + /// ScoreX Serialization mod scorex_serialize; pub use scorex_serialize::{ diff --git a/sigma-ser/src/scorex_serialize.rs b/sigma-ser/src/scorex_serialize.rs index fc43fc2b0..e3ba083a3 100644 --- a/sigma-ser/src/scorex_serialize.rs +++ b/sigma-ser/src/scorex_serialize.rs @@ -1,5 +1,10 @@ -use std::io; -use std::{convert::TryInto, io::Cursor}; +use alloc::boxed::Box; +use alloc::string::ToString; +use alloc::vec::Vec; +use alloc::{string::String, vec}; +use core::convert::TryInto; +use core2::io; +use core2::io::Cursor; use crate::vlq_encode; use crate::vlq_encode::*; @@ -20,7 +25,7 @@ pub enum ScorexSerializationError { NotSupported(&'static str), /// Integer type conversion failed #[error("Bounds check error: {0}")] - TryFrom(#[from] std::num::TryFromIntError), + TryFrom(#[from] core::num::TryFromIntError), /// Misc error #[error("error: {0}")] Misc(&'static str), @@ -79,7 +84,7 @@ pub enum ScorexParsingError { BoundedVecOutOfBounds(#[from] BoundedVecOutOfBounds), /// Failed to convert integer type #[error("Bounds check error: {0}")] - TryFrom(#[from] std::num::TryFromIntError), + TryFrom(#[from] core::num::TryFromIntError), } impl From for ScorexParsingError { diff --git a/sigma-ser/src/vlq_encode.rs b/sigma-ser/src/vlq_encode.rs index c8f22dff2..05692404f 100644 --- a/sigma-ser/src/vlq_encode.rs +++ b/sigma-ser/src/vlq_encode.rs @@ -1,6 +1,11 @@ use super::zig_zag_encode; -use std::convert::TryFrom; -use std::io; +use alloc::{ + string::{String, ToString}, + vec, + vec::Vec, +}; +use core::convert::TryFrom; +use core2::io; use bitvec::order::Lsb0; use bitvec::prelude::BitVec; @@ -16,7 +21,7 @@ pub enum VlqEncodingError { Io(String), /// value bounds check error #[error("Bounds check error: {1} for input: {0}")] - TryFrom(String, std::num::TryFromIntError), + TryFrom(String, core::num::TryFromIntError), /// Fail to decode a value from bytes #[error("VLQ decoding failed")] VlqDecodingFailed, @@ -166,7 +171,7 @@ pub trait ReadSigmaVlqExt: io::Read + io::Seek { } /// Read u8 without decoding - fn get_u8(&mut self) -> std::result::Result { + fn get_u8(&mut self) -> Result { let mut slice = [0u8; 1]; self.read_exact(&mut slice)?; Ok(slice[0]) @@ -265,10 +270,12 @@ mod tests { // See corresponding test suite in // https://github.com/ScorexFoundation/scorex-util/blob/9adb6c68b8a1c00ec17730e6da11c2976a892ad8/src/test/scala/scorex/util/serialization/VLQReaderWriterSpecification.scala#L11 use super::*; + use alloc::format; + use alloc::vec; + use core2::io::Cursor; + use core2::io::Read; + use core2::io::Write; use proptest::collection; - use std::io::Cursor; - use std::io::Read; - use std::io::Write; extern crate derive_more; use derive_more::From; @@ -944,7 +951,7 @@ mod tests { w.put_short_string(&s).unwrap(); let inner = w.into_inner(); prop_assert_eq!(inner[0] as usize, s.len()); - prop_assert_eq!(std::str::from_utf8(&inner[1..]), Ok(&*s)); + prop_assert_eq!(core::str::from_utf8(&inner[1..]), Ok(&*s)); } #[test] diff --git a/sigma-ser/src/zig_zag_encode.rs b/sigma-ser/src/zig_zag_encode.rs index fd025f7f2..86942fc43 100644 --- a/sigma-ser/src/zig_zag_encode.rs +++ b/sigma-ser/src/zig_zag_encode.rs @@ -42,6 +42,7 @@ pub fn decode_u64(v: u64) -> i64 { #[allow(clippy::panic)] mod tests { use super::*; + use alloc::format; #[allow(overflowing_literals)] #[test] From d0d72c88e4128da6b143538cf2c82674736dfad9 Mon Sep 17 00:00:00 2001 From: Kamal Ahmad Date: Sat, 9 Nov 2024 06:49:10 +0500 Subject: [PATCH 03/16] no_std sigma-util --- Cargo.toml | 7 ++++--- sigma-util/src/hash.rs | 2 ++ sigma-util/src/lib.rs | 4 +++- sigma-util/src/vec_ext.rs | 4 +++- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f6ea0da3e..4285b46c8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,4 +1,5 @@ [workspace] +resolver = "2" members = [ "sigma-test-util", "sigma-ser", @@ -52,9 +53,9 @@ derive_more = { version = "0.99", features = [ "from_str", "display", ] } -blake2 = "0.10" -sha2 = "0.10" num-derive = "0.4.2" +blake2 = { version = "0.10.6", default-features = false } +sha2 = { version = "0.10", default-features = false } num-traits = "0.2.14" num-integer = "0.1.44" num-bigint = "0.4.0" @@ -62,7 +63,7 @@ lazy_static = "1.4" bs58 = "0.4.0" base16 = "0.2.1" base64 = "0.13.0" -indexmap = { version = "1.3.2", features = ["serde"] } +indexmap = { version = "2.6.0", default-features = false } #TODO: enable std conditionally serde = { version = "1.0", features = ["derive"] } serde_json = { version = "1.0", features = [ "arbitrary_precision", diff --git a/sigma-util/src/hash.rs b/sigma-util/src/hash.rs index 418d74c23..8a65fec45 100644 --- a/sigma-util/src/hash.rs +++ b/sigma-util/src/hash.rs @@ -1,5 +1,7 @@ //! Hash functions +use alloc::boxed::Box; + /// Blake2b256 hash (256 bit) pub fn blake2b256_hash(bytes: &[u8]) -> Box<[u8; 32]> { use blake2::digest::typenum::U32; diff --git a/sigma-util/src/lib.rs b/sigma-util/src/lib.rs index 8c65bee1a..c8100f069 100644 --- a/sigma-util/src/lib.rs +++ b/sigma-util/src/lib.rs @@ -1,5 +1,5 @@ //! Ergo primitives - +#![no_std] // Coding conventions #![forbid(unsafe_code)] #![deny(non_upper_case_globals)] @@ -13,6 +13,8 @@ #![allow(clippy::unit_arg)] #![deny(rustdoc::broken_intra_doc_links)] +extern crate alloc; + pub mod hash; mod vec_ext; diff --git a/sigma-util/src/vec_ext.rs b/sigma-util/src/vec_ext.rs index 07cd53225..a222521e1 100644 --- a/sigma-util/src/vec_ext.rs +++ b/sigma-util/src/vec_ext.rs @@ -1,6 +1,8 @@ //! Vec extensions -use std::sync::Arc; +use alloc::sync::Arc; + +use alloc::vec::Vec; /// Vec to Vec conversion pub trait FromVecI8 { From 0cd366c12b86438e2a323c7cc187ae1813ef12e1 Mon Sep 17 00:00:00 2001 From: Kamal Ahmad Date: Sat, 9 Nov 2024 17:33:37 +0500 Subject: [PATCH 04/16] Bump Rust MSRV to 1.81 --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 9242d8e7a..ea3769f29 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -1.76 +1.81 From 13a6e4360059ae95e94503af46659ab88da65b43 Mon Sep 17 00:00:00 2001 From: Kamal Ahmad Date: Sun, 10 Nov 2024 11:34:38 +0500 Subject: [PATCH 05/16] sigma_ser no_std fixes --- Cargo.toml | 6 +++--- sigma-ser/src/lib.rs | 3 +-- sigma-ser/src/scorex_serialize.rs | 11 +++++++++++ sigma-ser/src/vlq_encode.rs | 6 +++++- 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4285b46c8..8dda0a766 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,9 +39,6 @@ ergo-rest = { version = "^0.13.0", path = "./ergo-rest" } ergo-lib = { version = "^0.28.0", path = "./ergo-lib" } k256 = { version = "0.13.1", features = ["arithmetic", "ecdsa"] } elliptic-curve = { version = "0.12", features = ["ff"] } -thiserror = { version = "2", default-features = false } -bounded-vec = { version = "^0.7.0" } -bitvec = { version = "1.0.1" } derive_more = { version = "0.99", features = [ "add", "add_assign", @@ -54,6 +51,9 @@ derive_more = { version = "0.99", features = [ "display", ] } 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 +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 } num-traits = "0.2.14" diff --git a/sigma-ser/src/lib.rs b/sigma-ser/src/lib.rs index 05e7cd084..763bed141 100644 --- a/sigma-ser/src/lib.rs +++ b/sigma-ser/src/lib.rs @@ -1,7 +1,6 @@ //! Sigma serialization -#![no_std] -// #![cfg_attr(not(feature = "std"), no_std)] +#![cfg_attr(not(feature = "std"), no_std)] // Coding conventions #![forbid(unsafe_code)] #![deny(non_upper_case_globals)] diff --git a/sigma-ser/src/scorex_serialize.rs b/sigma-ser/src/scorex_serialize.rs index e3ba083a3..f1c76ddbf 100644 --- a/sigma-ser/src/scorex_serialize.rs +++ b/sigma-ser/src/scorex_serialize.rs @@ -37,12 +37,23 @@ impl From for ScorexSerializationError { } } +#[cfg(feature = "std")] impl From for io::Error { fn from(e: ScorexSerializationError) -> Self { io::Error::new(io::ErrorKind::InvalidInput, e.to_string()) } } +#[cfg(not(feature = "std"))] +impl From for io::Error { + fn from(_e: ScorexSerializationError) -> Self { + io::Error::new( + io::ErrorKind::InvalidInput, + "Error messages are only supported on std target", + ) + } +} + /// Ways parsing might fail #[derive(Error, Eq, PartialEq, Debug, Clone)] pub enum ScorexParsingError { diff --git a/sigma-ser/src/vlq_encode.rs b/sigma-ser/src/vlq_encode.rs index 05692404f..48f23b208 100644 --- a/sigma-ser/src/vlq_encode.rs +++ b/sigma-ser/src/vlq_encode.rs @@ -131,8 +131,12 @@ pub trait WriteSigmaVlqExt: io::Write { /// Put a short string (< 256 bytes) into the writer. Writes length (as u8) and string bytes to the writer fn put_short_string(&mut self, s: &str) -> io::Result<()> { if s.len() > 255 { + #[cfg(feature = "std")] + let err_kind = io::ErrorKind::Unsupported; + #[cfg(not(feature = "std"))] + let err_kind = io::ErrorKind::Uncategorized; return Err(io::Error::new( - io::ErrorKind::Unsupported, + err_kind, "Serializing strings with more than 255 bytes is not allowed", )); } From 987dfed4124678f54e53afcaefcbb031afceda8f Mon Sep 17 00:00:00 2001 From: Kamal Ahmad Date: Sun, 10 Nov 2024 14:39:05 +0500 Subject: [PATCH 06/16] no_std support for ergo-chain-types --- Cargo.toml | 15 ++++--- ergo-chain-types/Cargo.toml | 22 ++++------ ergo-chain-types/src/base16_bytes.rs | 7 ++- ergo-chain-types/src/block_id.rs | 1 + ergo-chain-types/src/digest32.rs | 47 +++++++++++++++++---- ergo-chain-types/src/ec_point.rs | 13 +++--- ergo-chain-types/src/extensioncandidate.rs | 2 + ergo-chain-types/src/header.rs | 33 ++++++--------- ergo-chain-types/src/lib.rs | 7 +++ ergo-chain-types/src/peer_connection_dir.rs | 5 +-- ergo-chain-types/src/preheader.rs | 2 + ergo-chain-types/src/votes.rs | 5 ++- sigma-ser/Cargo.toml | 3 -- sigma-test-util/Cargo.toml | 4 +- 14 files changed, 98 insertions(+), 68 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8dda0a766..cec2b9875 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,7 @@ edition = "2021" [workspace.dependencies] sigma-util = { version = "^0.18.0", path = "./sigma-util" } -sigma-ser = { version = "^0.19.0", path = "./sigma-ser" } +sigma-ser = { version = "^0.19.0", path = "./sigma-ser", default-features = false } ergotree-ir = { version = "^0.28.0", path = "./ergotree-ir" } ergo-chain-types = { version = "^0.15.0", path = "./ergo-chain-types" } sigma-test-util = { version = "^0.3.0", path = "./sigma-test-util" } @@ -37,7 +37,10 @@ ergo-nipopow = { version = "^0.15", path = "./ergo-nipopow" } ergo-merkle-tree = { version = "^0.15.0", path = "./ergo-merkle-tree" } ergo-rest = { version = "^0.13.0", path = "./ergo-rest" } ergo-lib = { version = "^0.28.0", path = "./ergo-lib" } -k256 = { version = "0.13.1", features = ["arithmetic", "ecdsa"] } +k256 = { version = "0.13.1", default-features = false, features = [ + "arithmetic", + "ecdsa", +] } # TODO: look into precomputed_tables feature for std, could be useful for speeding up signature verification elliptic-curve = { version = "0.12", features = ["ff"] } derive_more = { version = "0.99", features = [ "add", @@ -56,13 +59,13 @@ bounded-vec = { git = "https://github.com/SethDusek/bounded-vec", branch = "no_s 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 } -num-traits = "0.2.14" +num-traits = { version = "0.2.14", default-features = false } num-integer = "0.1.44" -num-bigint = "0.4.0" +num-bigint = { version = "0.4.0", default-features = false } lazy_static = "1.4" bs58 = "0.4.0" -base16 = "0.2.1" -base64 = "0.13.0" +base16 = { version = "0.2.1", default-features = false, features = ["alloc"] } +base64 = { version = "0.13.0", default-features = false, features = ["alloc"] } indexmap = { version = "2.6.0", default-features = false } #TODO: enable std conditionally serde = { version = "1.0", features = ["derive"] } serde_json = { version = "1.0", features = [ diff --git a/ergo-chain-types/Cargo.toml b/ergo-chain-types/Cargo.toml index f413c252b..1b5085612 100644 --- a/ergo-chain-types/Cargo.toml +++ b/ergo-chain-types/Cargo.toml @@ -6,12 +6,7 @@ authors = ["Denys Zadorozhnyi "] repository.workspace = true edition.workspace = true description = "Ergo blockchain types" -exclude = [ - "proptest-regressions/*" -] - -[lib] -crate-type = ["cdylib", "rlib"] +exclude = ["proptest-regressions/*"] [dependencies] thiserror = { workspace = true } @@ -22,19 +17,20 @@ base16 = { workspace = true } base64 = { workspace = true } serde = { workspace = true, optional = true } serde_json = { workspace = true, optional = true } -url = { workspace = true } +url = { workspace = true, optional = true } k256 = { workspace = true } elliptic-curve = { workspace = true } num-bigint = { workspace = true } -byteorder = { workspace = true } serde_with = { workspace = true, optional = true } -proptest = { workspace = true , optional = true } -proptest-derive = {workspace = true, optional = true } +proptest = { workspace = true, optional = true } +proptest-derive = { workspace = true, optional = true } num-traits = { workspace = true } +core2 = { workspace = true } [features] -default = ["json"] -arbitrary = ["proptest", "proptest-derive"] -json = ["serde", "serde_json", "serde_with"] +default = ["std", "json"] +arbitrary = ["proptest", "proptest-derive", "std"] +json = ["serde", "serde_json", "serde_with", "std"] +std = ["dep:url", "base16/std", "base64/std"] [dev-dependencies] diff --git a/ergo-chain-types/src/base16_bytes.rs b/ergo-chain-types/src/base16_bytes.rs index cf0532150..5e55942eb 100644 --- a/ergo-chain-types/src/base16_bytes.rs +++ b/ergo-chain-types/src/base16_bytes.rs @@ -1,9 +1,12 @@ //! Transitioning type for Base16 encoded bytes in JSON serialization +use alloc::string::String; +use alloc::string::ToString; +use alloc::vec::Vec; +use core::convert::TryFrom; +use core::convert::TryInto; #[cfg(feature = "json")] use serde::{Deserialize, Serialize}; -use std::convert::TryFrom; -use std::convert::TryInto; extern crate derive_more; use derive_more::{From, Into}; diff --git a/ergo-chain-types/src/block_id.rs b/ergo-chain-types/src/block_id.rs index 5e600c508..ad44f2f4b 100644 --- a/ergo-chain-types/src/block_id.rs +++ b/ergo-chain-types/src/block_id.rs @@ -1,5 +1,6 @@ //! Main "remote" type for [BlockId]() +use alloc::{string::String, vec::Vec}; use derive_more::Display; use crate::DigestNError; diff --git a/ergo-chain-types/src/digest32.rs b/ergo-chain-types/src/digest32.rs index 54783856d..39eaa93eb 100644 --- a/ergo-chain-types/src/digest32.rs +++ b/ergo-chain-types/src/digest32.rs @@ -1,14 +1,17 @@ //! Digest types for various sizes +use alloc::boxed::Box; +use alloc::string::String; +use alloc::vec::Vec; +use core::convert::TryFrom; +use core::convert::TryInto; +use core::fmt::Formatter; use sigma_ser::vlq_encode::ReadSigmaVlqExt; use sigma_ser::vlq_encode::WriteSigmaVlqExt; use sigma_ser::ScorexParsingError; use sigma_ser::ScorexSerializable; use sigma_ser::ScorexSerializeResult; use sigma_util::AsVecI8; -use std::convert::TryFrom; -use std::convert::TryInto; -use std::fmt::Formatter; use thiserror::Error; /// N-bytes array in a box. `Digest32` is most type synonym. @@ -47,14 +50,14 @@ impl Digest { } } -impl std::fmt::Debug for Digest { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Debug for Digest { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { base16::encode_lower(&(self.0)).fmt(f) } } -impl std::fmt::Display for Digest { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Display for Digest { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { base16::encode_lower(&(self.0)).fmt(f) } } @@ -149,14 +152,40 @@ impl AsRef<[u8]> for Digest32 { #[derive(Error, Debug)] pub enum DigestNError { /// error decoding from Base16 + #[cfg(feature = "std")] #[error("error decoding from Base16: {0}")] Base16DecodingError(#[from] base16::DecodeError), + /// error decoding from Base16 + #[cfg(not(feature = "std"))] + #[error("error decoding from Base16")] + Base16DecodingError, /// Invalid byte array size #[error("Invalid byte array size ({0})")] - InvalidSize(#[from] std::array::TryFromSliceError), + InvalidSize(#[from] core::array::TryFromSliceError), /// error decoding from Base64 + #[cfg(feature = "std")] #[error("error decoding from Base64: {0}")] Base64DecodingError(#[from] base64::DecodeError), + + /// error decoding from Base64 + #[cfg(not(feature = "std"))] + #[error("error decoding from Base64")] + Base64DecodingError, +} + +/// both base16 and base64 don't implement core::error::Error for their error types yet, so we can't use them in thiserror in no_std contexts +#[cfg(not(feature = "std"))] +impl From for DigestNError { + fn from(_: base16::DecodeError) -> Self { + Self::Base16DecodingError + } +} + +#[cfg(not(feature = "std"))] +impl From for DigestNError { + fn from(_: base64::DecodeError) -> Self { + Self::Base64DecodingError + } } /// Arbitrary @@ -165,9 +194,9 @@ pub enum DigestNError { pub(crate) mod arbitrary { use super::Digest; + use core::convert::TryInto; use proptest::prelude::{Arbitrary, BoxedStrategy}; use proptest::{collection::vec, prelude::*}; - use std::convert::TryInto; impl Arbitrary for Digest { type Parameters = (); diff --git a/ergo-chain-types/src/ec_point.rs b/ergo-chain-types/src/ec_point.rs index df90938a5..34f3caf67 100644 --- a/ergo-chain-types/src/ec_point.rs +++ b/ergo-chain-types/src/ec_point.rs @@ -1,13 +1,14 @@ //! Elliptic curve point. +use alloc::string::String; +use core::convert::TryFrom; +use core::ops::{Add, Mul, Neg}; use derive_more::{From, Into}; use k256::elliptic_curve::group::prime::PrimeCurveAffine; use k256::elliptic_curve::sec1::ToEncodedPoint; use k256::{ProjectivePoint, PublicKey, Scalar}; use sigma_ser::vlq_encode::{ReadSigmaVlqExt, WriteSigmaVlqExt}; use sigma_ser::{ScorexParsingError, ScorexSerializable, ScorexSerializeResult}; -use std::convert::TryFrom; -use std::ops::{Add, Mul, Neg}; /// Elliptic curve point #[derive(PartialEq, Clone, Default, From, Into)] @@ -19,8 +20,8 @@ use std::ops::{Add, Mul, Neg}; pub struct EcPoint(ProjectivePoint); #[allow(clippy::unwrap_used)] -impl std::fmt::Debug for EcPoint { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { +impl core::fmt::Debug for EcPoint { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { f.write_str("EC:")?; f.write_str(&base16::encode_lower( &self.scorex_serialize_bytes().unwrap(), @@ -29,8 +30,8 @@ impl std::fmt::Debug for EcPoint { } #[allow(clippy::unwrap_used)] -impl std::fmt::Display for EcPoint { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { +impl core::fmt::Display for EcPoint { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { f.write_str(&base16::encode_lower( &self.scorex_serialize_bytes().unwrap(), )) diff --git a/ergo-chain-types/src/extensioncandidate.rs b/ergo-chain-types/src/extensioncandidate.rs index 853328c74..1218dda37 100644 --- a/ergo-chain-types/src/extensioncandidate.rs +++ b/ergo-chain-types/src/extensioncandidate.rs @@ -1,3 +1,5 @@ +use alloc::vec::Vec; + /// Extension section of Ergo block. Contains key-value storage. #[derive(Clone, Debug, Default)] pub struct ExtensionCandidate { diff --git a/ergo-chain-types/src/header.rs b/ergo-chain-types/src/header.rs index 98cea4097..32befab68 100644 --- a/ergo-chain-types/src/header.rs +++ b/ergo-chain-types/src/header.rs @@ -1,12 +1,14 @@ //! Block header use crate::{ADDigest, BlockId, Digest32, EcPoint}; +use alloc::boxed::Box; +use alloc::vec::Vec; +use core2::io::Write; use num_bigint::BigInt; use sigma_ser::vlq_encode::{ReadSigmaVlqExt, WriteSigmaVlqExt}; use sigma_ser::{ ScorexParsingError, ScorexSerializable, ScorexSerializationError, ScorexSerializeResult, }; use sigma_util::hash::blake2b256_hash; -use std::io::Write; use crate::votes::Votes; @@ -56,7 +58,6 @@ pub struct Header { impl Header { /// Used in nipowpow pub fn serialize_without_pow(&self) -> Result, ScorexSerializationError> { - use byteorder::{BigEndian, WriteBytesExt}; let mut data = Vec::new(); let mut w = &mut data; w.put_u8(self.version)?; @@ -69,12 +70,8 @@ impl Header { // n_bits needs to be serialized in big-endian format. Note that it actually fits in a // `u32`. - let mut n_bits_writer = vec![]; - #[allow(clippy::unwrap_used)] - n_bits_writer - .write_u32::(self.n_bits as u32) - .unwrap(); - w.write_all(&n_bits_writer)?; + let n_bits_be = (self.n_bits as u32).to_be_bytes(); + w.write_all(&n_bits_be)?; w.put_u32(self.height)?; w.write_all(&self.votes.0)?; @@ -108,14 +105,7 @@ impl ScorexSerializable for Header { let extension_root = Digest32::scorex_parse(r)?; let mut n_bits_buf = [0u8, 0, 0, 0]; r.read_exact(&mut n_bits_buf)?; - let n_bits = { - use byteorder::{BigEndian, ReadBytesExt}; - let mut reader = std::io::Cursor::new(n_bits_buf); - #[allow(clippy::unwrap_used)] - { - reader.read_u32::().unwrap() as u64 - } - }; + let n_bits = u32::from_be_bytes(n_bits_buf) as u64; let height = r.get_u32()?; let mut votes_bytes = [0u8, 0, 0]; r.read_exact(&mut votes_bytes)?; @@ -126,8 +116,9 @@ impl ScorexSerializable for Header { if version > 1 { let new_field_size = r.get_u8()?; if new_field_size > 0 { - let mut field_bytes: Vec = - std::iter::repeat(0).take(new_field_size as usize).collect(); + let mut field_bytes: Vec = core::iter::repeat(0) + .take(new_field_size as usize) + .collect(); r.read_exact(&mut field_bytes)?; } } @@ -136,10 +127,10 @@ impl ScorexSerializable for Header { let autolykos_solution = if version == 1 { let miner_pk = EcPoint::scorex_parse(r)?.into(); let pow_onetime_pk = Some(EcPoint::scorex_parse(r)?.into()); - let mut nonce: Vec = std::iter::repeat(0).take(8).collect(); + let mut nonce: Vec = core::iter::repeat(0).take(8).collect(); r.read_exact(&mut nonce)?; let d_bytes_len = r.get_u8()?; - let mut d_bytes: Vec = std::iter::repeat(0).take(d_bytes_len as usize).collect(); + let mut d_bytes: Vec = core::iter::repeat(0).take(d_bytes_len as usize).collect(); r.read_exact(&mut d_bytes)?; let pow_distance = Some(BigInt::from_signed_bytes_be(&d_bytes)); AutolykosSolution { @@ -153,7 +144,7 @@ impl ScorexSerializable for Header { let pow_onetime_pk = None; let pow_distance = None; let miner_pk = EcPoint::scorex_parse(r)?.into(); - let mut nonce: Vec = std::iter::repeat(0).take(8).collect(); + let mut nonce: Vec = core::iter::repeat(0).take(8).collect(); r.read_exact(&mut nonce)?; AutolykosSolution { miner_pk, diff --git a/ergo-chain-types/src/lib.rs b/ergo-chain-types/src/lib.rs index 79c7f5aea..f6fe60f5b 100644 --- a/ergo-chain-types/src/lib.rs +++ b/ergo-chain-types/src/lib.rs @@ -1,5 +1,6 @@ //! Ergo blockchain types +#![cfg_attr(not(feature = "std"), no_std)] // Coding conventions #![forbid(unsafe_code)] #![deny(non_upper_case_globals)] @@ -18,13 +19,18 @@ #![deny(clippy::unreachable)] #![deny(clippy::panic)] +#[macro_use] +extern crate alloc; + mod base16_bytes; mod block_id; mod digest32; pub mod ec_point; mod extensioncandidate; mod header; +#[cfg(feature = "json")] mod json; +#[cfg(feature = "std")] mod peer_addr; mod peer_connection_dir; mod preheader; @@ -41,6 +47,7 @@ pub use digest32::DigestNError; pub use ec_point::EcPoint; pub use extensioncandidate::ExtensionCandidate; pub use header::{AutolykosSolution, Header}; +#[cfg(feature = "std")] pub use peer_addr::PeerAddr; pub use peer_connection_dir::ConnectionDirection; pub use preheader::PreHeader; diff --git a/ergo-chain-types/src/peer_connection_dir.rs b/ergo-chain-types/src/peer_connection_dir.rs index 5ec2b23fe..89449de56 100644 --- a/ergo-chain-types/src/peer_connection_dir.rs +++ b/ergo-chain-types/src/peer_connection_dir.rs @@ -1,7 +1,6 @@ -use serde::{Deserialize, Serialize}; - /// Direction of the connection to a peer -#[derive(PartialEq, Eq, Debug, Copy, Clone, Hash, Deserialize, Serialize)] +#[derive(PartialEq, Eq, Debug, Copy, Clone, Hash)] +#[cfg_attr(feature = "json", derive(serde::Serialize, serde::Deserialize))] pub enum ConnectionDirection { /// A peer is connecting to us Incoming, diff --git a/ergo-chain-types/src/preheader.rs b/ergo-chain-types/src/preheader.rs index 2923c3599..25d68c412 100644 --- a/ergo-chain-types/src/preheader.rs +++ b/ergo-chain-types/src/preheader.rs @@ -1,4 +1,6 @@ //! Block header with fields that can be predicted by miner +use alloc::boxed::Box; + use crate::{BlockId, EcPoint, Header, Votes}; /// Block header with the current `spendingTransaction`, that can be predicted diff --git a/ergo-chain-types/src/votes.rs b/ergo-chain-types/src/votes.rs index 4a51c8dba..5824fb645 100644 --- a/ergo-chain-types/src/votes.rs +++ b/ergo-chain-types/src/votes.rs @@ -1,8 +1,9 @@ //! Main "remote" type for [Vote]() use crate::{Base16DecodedBytes, Base16EncodedBytes}; +use alloc::vec::Vec; use thiserror::Error; -use std::convert::{TryFrom, TryInto}; +use core::convert::{TryFrom, TryInto}; /// Votes for changing system parameters #[cfg_attr(feature = "json", derive(serde::Serialize, serde::Deserialize))] @@ -36,7 +37,7 @@ impl TryFrom> for Votes { pub enum VotesError { /// Invalid byte array size #[error("Votes: Invalid byte array size ({0})")] - InvalidSize(#[from] std::array::TryFromSliceError), + InvalidSize(#[from] core::array::TryFromSliceError), } impl TryFrom for Votes { diff --git a/sigma-ser/Cargo.toml b/sigma-ser/Cargo.toml index 9a6ab5658..e33893620 100644 --- a/sigma-ser/Cargo.toml +++ b/sigma-ser/Cargo.toml @@ -7,9 +7,6 @@ repository.workspace = true edition.workspace = true description = "Ergo binary serialization primitives" -[lib] -crate-type = ["cdylib", "rlib"] - [features] default = ["std"] std = ["core2/std"] diff --git a/sigma-test-util/Cargo.toml b/sigma-test-util/Cargo.toml index 03c5e36dc..20a250753 100644 --- a/sigma-test-util/Cargo.toml +++ b/sigma-test-util/Cargo.toml @@ -11,7 +11,5 @@ description = "Test utilities for Ergo" crate-type = ["cdylib", "rlib"] [dependencies] -proptest = {version = "1.0.0"} -proptest-derive = {version = "0.3.0"} - +proptest = { workspace = true } [dev-dependencies] From 83adea179526d06fb05874639d514537e26b010f Mon Sep 17 00:00:00 2001 From: Kamal Ahmad Date: Sun, 10 Nov 2024 16:59:11 +0500 Subject: [PATCH 07/16] ergotree_ir no_std --- Cargo.toml | 8 ++-- ergo-chain-types/src/peer_addr.rs | 6 +-- ergotree-interpreter/Cargo.toml | 2 +- ergotree-ir/Cargo.toml | 27 ++++++++---- ergotree-ir/src/base16_str.rs | 1 + ergotree-ir/src/bigint256.rs | 5 ++- ergotree-ir/src/chain.rs | 5 +++ ergotree-ir/src/chain/address.rs | 12 +++++- ergotree-ir/src/chain/context_extension.rs | 21 +++++---- ergotree-ir/src/chain/ergo_box.rs | 11 +++-- ergotree-ir/src/chain/ergo_box/box_id.rs | 9 ++-- ergotree-ir/src/chain/ergo_box/box_value.rs | 11 +++-- ergotree-ir/src/chain/ergo_box/register.rs | 38 ++++++++++++++-- ergotree-ir/src/chain/ergo_box/register/id.rs | 5 ++- .../src/chain/ergo_box/register/value.rs | 4 ++ ergotree-ir/src/chain/json.rs | 11 ++--- ergotree-ir/src/chain/json/box_value.rs | 4 +- ergotree-ir/src/chain/json/ergo_box.rs | 11 +++-- .../src/chain/json/ergo_box/box_value.rs | 2 +- ergotree-ir/src/chain/json/ergo_tree.rs | 1 + ergotree-ir/src/chain/json/sigma_protocol.rs | 5 ++- ergotree-ir/src/chain/json/token.rs | 4 +- ergotree-ir/src/chain/token.rs | 7 ++- ergotree-ir/src/chain/tx_id.rs | 1 + ergotree-ir/src/ergo_tree.rs | 34 ++++++++++----- ergotree-ir/src/ergo_tree/tree_header.rs | 3 +- ergotree-ir/src/lib.rs | 4 ++ ergotree-ir/src/mir/and.rs | 3 ++ ergotree-ir/src/mir/apply.rs | 4 ++ ergotree-ir/src/mir/atleast.rs | 3 ++ ergotree-ir/src/mir/avl_tree_data.rs | 2 + ergotree-ir/src/mir/bin_op.rs | 13 +++--- ergotree-ir/src/mir/bit_inversion.rs | 2 + ergotree-ir/src/mir/block.rs | 3 ++ ergotree-ir/src/mir/bool_to_sigma.rs | 2 + ergotree-ir/src/mir/byte_array_to_bigint.rs | 4 +- ergotree-ir/src/mir/byte_array_to_long.rs | 4 +- ergotree-ir/src/mir/calc_blake2b256.rs | 4 +- ergotree-ir/src/mir/calc_sha256.rs | 4 +- ergotree-ir/src/mir/coll_append.rs | 3 ++ ergotree-ir/src/mir/coll_by_index.rs | 4 +- ergotree-ir/src/mir/coll_exists.rs | 5 ++- ergotree-ir/src/mir/coll_filter.rs | 5 ++- ergotree-ir/src/mir/coll_fold.rs | 4 ++ ergotree-ir/src/mir/coll_forall.rs | 5 ++- ergotree-ir/src/mir/coll_map.rs | 4 ++ ergotree-ir/src/mir/coll_size.rs | 3 ++ ergotree-ir/src/mir/coll_slice.rs | 3 ++ ergotree-ir/src/mir/collection.rs | 7 ++- ergotree-ir/src/mir/constant.rs | 43 +++++++++++-------- ergotree-ir/src/mir/create_avl_tree.rs | 7 ++- ergotree-ir/src/mir/create_prove_dh_tuple.rs | 2 + ergotree-ir/src/mir/create_provedlog.rs | 2 + ergotree-ir/src/mir/decode_point.rs | 4 +- ergotree-ir/src/mir/deserialize_register.rs | 4 ++ ergotree-ir/src/mir/downcast.rs | 3 ++ ergotree-ir/src/mir/exponentiate.rs | 3 ++ ergotree-ir/src/mir/expr.rs | 35 +++++++++------ ergotree-ir/src/mir/extract_amount.rs | 4 ++ ergotree-ir/src/mir/extract_bytes.rs | 2 + .../src/mir/extract_bytes_with_no_ref.rs | 2 + ergotree-ir/src/mir/extract_creation_info.rs | 2 + ergotree-ir/src/mir/extract_id.rs | 4 ++ ergotree-ir/src/mir/extract_reg_as.rs | 4 +- ergotree-ir/src/mir/extract_script_bytes.rs | 2 + ergotree-ir/src/mir/func_value.rs | 7 ++- ergotree-ir/src/mir/get_var.rs | 1 + ergotree-ir/src/mir/global_vars.rs | 6 +-- ergotree-ir/src/mir/if_op.rs | 2 + ergotree-ir/src/mir/logical_not.rs | 2 + ergotree-ir/src/mir/long_to_byte_array.rs | 3 ++ ergotree-ir/src/mir/method_call.rs | 9 +++- ergotree-ir/src/mir/multiply_group.rs | 3 ++ ergotree-ir/src/mir/negation.rs | 4 ++ ergotree-ir/src/mir/option_get.rs | 4 +- ergotree-ir/src/mir/option_get_or_else.rs | 4 +- ergotree-ir/src/mir/option_is_defined.rs | 3 ++ ergotree-ir/src/mir/or.rs | 2 + ergotree-ir/src/mir/property_call.rs | 4 ++ ergotree-ir/src/mir/select_field.rs | 7 ++- ergotree-ir/src/mir/sigma_and.rs | 5 ++- ergotree-ir/src/mir/sigma_or.rs | 5 ++- ergotree-ir/src/mir/sigma_prop_bytes.rs | 2 + ergotree-ir/src/mir/subst_const.rs | 3 ++ ergotree-ir/src/mir/tree_lookup.rs | 4 +- ergotree-ir/src/mir/tuple.rs | 4 +- ergotree-ir/src/mir/upcast.rs | 3 ++ ergotree-ir/src/mir/val_def.rs | 3 +- ergotree-ir/src/mir/val_use.rs | 3 ++ ergotree-ir/src/mir/value.rs | 32 ++++++++------ ergotree-ir/src/mir/xor.rs | 4 +- ergotree-ir/src/mir/xor_of.rs | 3 ++ ergotree-ir/src/pretty_printer.rs | 7 +-- ergotree-ir/src/pretty_printer/print.rs | 7 ++- ergotree-ir/src/reference.rs | 10 +++-- ergotree-ir/src/serialization/bin_op.rs | 3 ++ ergotree-ir/src/serialization/constant.rs | 6 +-- .../src/serialization/constant_placeholder.rs | 4 +- .../src/serialization/constant_store.rs | 3 ++ ergotree-ir/src/serialization/data.rs | 9 +++- ergotree-ir/src/serialization/expr.rs | 5 ++- ergotree-ir/src/serialization/method_call.rs | 8 +++- .../src/serialization/property_call.rs | 2 + ergotree-ir/src/serialization/serializable.rs | 10 +++-- .../src/serialization/sigma_byte_reader.rs | 28 +++++++++--- .../src/serialization/sigma_byte_writer.rs | 6 +-- ergotree-ir/src/serialization/sigmaboolean.rs | 1 + ergotree-ir/src/serialization/types.rs | 5 ++- .../src/serialization/val_def_type_store.rs | 2 +- .../src/sigma_protocol/sigma_boolean.rs | 24 ++++++----- .../src/sigma_protocol/sigma_boolean/cand.rs | 12 ++++-- .../src/sigma_protocol/sigma_boolean/cor.rs | 12 ++++-- .../sigma_boolean/cthreshold.rs | 9 ++-- ergotree-ir/src/source_span.rs | 3 ++ ergotree-ir/src/traversable.rs | 27 ++++++------ ergotree-ir/src/type_check.rs | 3 ++ ergotree-ir/src/types/savltree.rs | 4 +- ergotree-ir/src/types/sbox.rs | 7 ++- ergotree-ir/src/types/scoll.rs | 4 +- ergotree-ir/src/types/scontext.rs | 2 + ergotree-ir/src/types/sfunc.rs | 10 +++-- ergotree-ir/src/types/sglobal.rs | 2 + ergotree-ir/src/types/sgroup_elem.rs | 4 +- ergotree-ir/src/types/sheader.rs | 2 + ergotree-ir/src/types/smethod.rs | 11 +++-- ergotree-ir/src/types/soption.rs | 2 + ergotree-ir/src/types/spreheader.rs | 2 + ergotree-ir/src/types/stuple.rs | 16 ++++--- ergotree-ir/src/types/stype.rs | 14 +++--- ergotree-ir/src/types/stype_companion.rs | 6 ++- ergotree-ir/src/types/stype_param.rs | 15 ++++--- ergotree-ir/src/types/type_unify.rs | 9 +++- sigma-util/Cargo.toml | 3 -- 133 files changed, 657 insertions(+), 260 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index cec2b9875..ebd1ba10f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,7 @@ edition = "2021" sigma-util = { version = "^0.18.0", path = "./sigma-util" } sigma-ser = { version = "^0.19.0", path = "./sigma-ser", default-features = false } ergotree-ir = { version = "^0.28.0", path = "./ergotree-ir" } -ergo-chain-types = { version = "^0.15.0", path = "./ergo-chain-types" } +ergo-chain-types = { version = "^0.15.0", path = "./ergo-chain-types", default-features = false } sigma-test-util = { version = "^0.3.0", path = "./sigma-test-util" } ergoscript-compiler = { version = "^0.24.0", path = "./ergoscript-compiler" } ergotree-interpreter = { version = "^0.28.0", path = "./ergotree-interpreter" } @@ -60,10 +60,10 @@ 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 } num-traits = { version = "0.2.14", default-features = false } -num-integer = "0.1.44" +num-integer = { version = "0.1.44", default-features = false } num-bigint = { version = "0.4.0", default-features = false } -lazy_static = "1.4" -bs58 = "0.4.0" +lazy_static = { version = "1.4", features = ["spin_no_std"] } # TODO: add no_std feature, so spin_no_std is only enabled if std is not available +bs58 = { version = "0.4.0", default-features = false, features = ["alloc"] } base16 = { version = "0.2.1", default-features = false, features = ["alloc"] } base64 = { version = "0.13.0", default-features = false, features = ["alloc"] } indexmap = { version = "2.6.0", default-features = false } #TODO: enable std conditionally diff --git a/ergo-chain-types/src/peer_addr.rs b/ergo-chain-types/src/peer_addr.rs index 430a7e518..934602496 100644 --- a/ergo-chain-types/src/peer_addr.rs +++ b/ergo-chain-types/src/peer_addr.rs @@ -7,14 +7,12 @@ use std::{ use derive_more::FromStr; use derive_more::{Display, From, Into}; -use serde::{Deserialize, Serialize}; use sigma_ser::{ScorexSerializable, ScorexSerializationError}; use url::Url; /// Peer address -#[derive( - PartialEq, Eq, Debug, Copy, Clone, From, Into, Hash, Display, FromStr, Deserialize, Serialize, -)] +#[derive(PartialEq, Eq, Debug, Copy, Clone, From, Into, Hash, Display, FromStr)] +#[cfg_attr(feature = "json", derive(serde::Serialize, serde::Deserialize))] pub struct PeerAddr(pub SocketAddr); impl PeerAddr { diff --git a/ergotree-interpreter/Cargo.toml b/ergotree-interpreter/Cargo.toml index cb280daff..0a19a4365 100644 --- a/ergotree-interpreter/Cargo.toml +++ b/ergotree-interpreter/Cargo.toml @@ -37,7 +37,7 @@ proptest = { workspace = true, optional = true } ergo_avltree_rust = "0.1.0" gf2_192 = { version = "^0.28.0", path = "../gf2_192" } miette = { workspace = true } -hashbrown = "0.14.3" +hashbrown = { workspace = true } [features] default = ["json"] diff --git a/ergotree-ir/Cargo.toml b/ergotree-ir/Cargo.toml index ef185305d..d15747d1d 100644 --- a/ergotree-ir/Cargo.toml +++ b/ergotree-ir/Cargo.toml @@ -9,7 +9,7 @@ description = "ErgoTree IR, serialization" exclude = ["proptest-regressions/*"] [lib] -crate-type = ["cdylib", "rlib"] +crate-type = ["rlib"] [dependencies] sigma-ser = { workspace = true } @@ -35,14 +35,25 @@ serde_json = { workspace = true, optional = true } serde_with = { workspace = true, optional = true } bnum = { version = "0.12.0", features = ["numtraits"] } impl-trait-for-tuples = "0.2.0" -strum = "0.21" -strum_macros = "0.21" -miette = { workspace = true } - +strum = { version = "0.26.2", default-features = false, features = ["derive"] } +strum_macros = { version = "0.26.4", default-features = false } +miette = { workspace = true, optional = true } +hashbrown = { workspace = true } +core2 = { workspace = true } +foldhash = { version = "0.1.3", default-features = false } [features] -default = ["json"] -arbitrary = ["proptest", "proptest-derive", "ergo-chain-types/arbitrary"] -json = ["serde", "serde_json", "serde_with", "bounded-vec/serde"] +default = ["json", "std"] +arbitrary = ["std", "proptest", "proptest-derive", "ergo-chain-types/arbitrary"] +json = [ + "serde", + "serde_json", + "serde_with", + "bounded-vec/serde", + "std", + "ergo-chain-types/json", + "indexmap/serde", +] +std = ["core2/std", "dep:miette", "ergo-chain-types/std", "sigma-ser/std"] [dev-dependencies] sigma-test-util = { workspace = true } diff --git a/ergotree-ir/src/base16_str.rs b/ergotree-ir/src/base16_str.rs index 6be0cf155..d342febe4 100644 --- a/ergotree-ir/src/base16_str.rs +++ b/ergotree-ir/src/base16_str.rs @@ -1,6 +1,7 @@ //! Trait for base16-encoded serialized bytes use crate::serialization::SigmaSerializationError; +use alloc::string::String; /// Encodes serialized bytes as Base16 pub trait Base16Str { diff --git a/ergotree-ir/src/bigint256.rs b/ergotree-ir/src/bigint256.rs index cd1848068..8e316d94c 100644 --- a/ergotree-ir/src/bigint256.rs +++ b/ergotree-ir/src/bigint256.rs @@ -1,6 +1,9 @@ //! 256-bit signed integer type -use std::ops::{Div, Mul, Neg, Rem}; +use alloc::string::String; +use alloc::vec::Vec; +use core::convert::TryFrom; +use core::ops::{Div, Mul, Neg, Rem}; use bnum::cast::As; use bnum::types::I256; diff --git a/ergotree-ir/src/chain.rs b/ergotree-ir/src/chain.rs index 11a2895c5..6d1e63f2e 100644 --- a/ergotree-ir/src/chain.rs +++ b/ergotree-ir/src/chain.rs @@ -8,3 +8,8 @@ pub mod ergo_box; pub mod json; pub mod token; pub mod tx_id; + +/// Index Map +pub type IndexMap = indexmap::IndexMap; +/// Index Set +pub type IndexSet = indexmap::IndexSet; diff --git a/ergotree-ir/src/chain/address.rs b/ergotree-ir/src/chain/address.rs index 8a1d981b3..53fe2689a 100644 --- a/ergotree-ir/src/chain/address.rs +++ b/ergotree-ir/src/chain/address.rs @@ -24,12 +24,18 @@ use crate::sigma_protocol::sigma_boolean::SigmaProofOfKnowledgeTree; use crate::sigma_protocol::sigma_boolean::SigmaProp; use crate::source_span::Spanned; use crate::types::stype::SType; + +use alloc::boxed::Box; +use alloc::string::{String, ToString}; +use alloc::sync::Arc; +use alloc::vec; +use alloc::vec::Vec; + use ergo_chain_types::EcPoint; +use core::convert::{TryFrom, TryInto}; use sigma_util::hash::blake2b256_hash; use sigma_util::AsVecU8; -use std::convert::{TryFrom, TryInto}; -use std::sync::Arc; use thiserror::Error; /** @@ -585,8 +591,10 @@ pub(crate) mod arbitrary { mod tests { use super::*; + use proptest::prelude::*; + #[cfg(feature = "std")] proptest! { #[test] diff --git a/ergotree-ir/src/chain/context_extension.rs b/ergotree-ir/src/chain/context_extension.rs index 8197ee048..422ee38b5 100644 --- a/ergotree-ir/src/chain/context_extension.rs +++ b/ergotree-ir/src/chain/context_extension.rs @@ -5,11 +5,15 @@ use crate::serialization::sigma_byte_writer::SigmaByteWrite; use crate::serialization::SigmaParsingError; use crate::serialization::SigmaSerializable; use crate::serialization::SigmaSerializeResult; -use indexmap::IndexMap; -use std::convert::TryFrom; -use std::fmt; +use alloc::string::String; +use alloc::vec::Vec; +use core::convert::TryFrom; +use core::fmt; +use core::hash::Hasher; use thiserror::Error; +use super::IndexMap; + /// User-defined variables to be put into context #[derive(Debug, PartialEq, Eq, Clone)] pub struct ContextExtension { @@ -21,7 +25,7 @@ impl ContextExtension { /// Returns an empty ContextExtension pub fn empty() -> Self { Self { - values: IndexMap::new(), + values: IndexMap::with_hasher(Default::default()), } } } @@ -45,7 +49,8 @@ impl SigmaSerializable for ContextExtension { fn sigma_parse(r: &mut R) -> Result { let values_count = r.get_u8()?; - let mut values: IndexMap = IndexMap::with_capacity(values_count as usize); + let mut values: IndexMap = + IndexMap::with_capacity_and_hasher(values_count as usize, Default::default()); for _ in 0..values_count { let idx = r.get_u8()?; values.insert(idx, Constant::sigma_parse(r)?); @@ -60,11 +65,11 @@ impl SigmaSerializable for ContextExtension { pub struct ConstantParsingError(pub String); // for JSON encoding in ergo-lib -impl TryFrom> for ContextExtension { +impl TryFrom> for ContextExtension { type Error = ConstantParsingError; - fn try_from(values_str: IndexMap) -> Result { + fn try_from(values_str: indexmap::IndexMap) -> Result { let values = values_str.iter().try_fold( - IndexMap::with_capacity(values_str.len()), + IndexMap::with_capacity_and_hasher(values_str.len(), Default::default()), |mut acc, pair| { let idx: u8 = pair.0.parse().map_err(|_| { ConstantParsingError(format!("cannot parse index from {0:?}", pair.0)) diff --git a/ergotree-ir/src/chain/ergo_box.rs b/ergotree-ir/src/chain/ergo_box.rs index 2e7b5e843..f3e5c4a99 100644 --- a/ergotree-ir/src/chain/ergo_box.rs +++ b/ergotree-ir/src/chain/ergo_box.rs @@ -13,17 +13,19 @@ use crate::serialization::SigmaSerializable; use crate::serialization::SigmaSerializationError; use crate::serialization::SigmaSerializeResult; +use alloc::string::ToString; +use alloc::vec::Vec; pub use box_id::*; use ergo_chain_types::Digest32; pub use register::*; +use super::IndexSet; use bounded_vec::BoundedVec; -use indexmap::IndexSet; +use core::convert::TryFrom; use sigma_util::hash::blake2b256_hash; use sigma_util::AsVecI8; -use std::convert::TryFrom; -use std::convert::TryInto; +use core::convert::TryInto; use self::box_value::BoxValue; @@ -403,7 +405,7 @@ pub mod arbitrary { pub creation_height: BoxedStrategy, pub registers: BoxedStrategy, } - impl std::default::Default for ArbBoxParameters { + impl core::default::Default for ArbBoxParameters { fn default() -> Self { Self { value_range: ArbBoxValueRange::default(), @@ -482,6 +484,7 @@ mod tests { use super::*; use crate::chain::token::arbitrary::ArbTokenIdParam; use crate::serialization::sigma_serialize_roundtrip; + use proptest::collection::SizeRange; use proptest::prelude::*; use sigma_test_util::force_any_val; diff --git a/ergotree-ir/src/chain/ergo_box/box_id.rs b/ergotree-ir/src/chain/ergo_box/box_id.rs index 193a45799..d91bb4e3c 100644 --- a/ergotree-ir/src/chain/ergo_box/box_id.rs +++ b/ergotree-ir/src/chain/ergo_box/box_id.rs @@ -1,7 +1,9 @@ //! Box id type -use std::convert::TryFrom; +use core::convert::TryFrom; use crate::serialization::SigmaSerializeResult; +use alloc::string::String; +use alloc::vec::Vec; use sigma_ser::ScorexSerializable; use crate::serialization::{ @@ -56,8 +58,8 @@ impl From for Vec { } } -impl std::fmt::Display for BoxId { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Display for BoxId { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!(f, "{}", self.0) } } @@ -78,6 +80,7 @@ impl SigmaSerializable for BoxId { mod tests { use super::*; use crate::serialization::sigma_serialize_roundtrip; + use proptest::prelude::*; proptest! { diff --git a/ergotree-ir/src/chain/ergo_box/box_value.rs b/ergotree-ir/src/chain/ergo_box/box_value.rs index ff44e2013..58a1b4a3e 100644 --- a/ergotree-ir/src/chain/ergo_box/box_value.rs +++ b/ergotree-ir/src/chain/ergo_box/box_value.rs @@ -7,8 +7,9 @@ use crate::serialization::SigmaSerializeResult; use crate::serialization::{ sigma_byte_reader::SigmaByteRead, SigmaParsingError, SigmaSerializable, }; + +use core::convert::TryFrom; use derive_more::FromStr; -use std::convert::TryFrom; use thiserror::Error; #[cfg(not(feature = "json"))] @@ -114,7 +115,7 @@ impl BoxValue { } impl PartialOrd for BoxValue { - fn partial_cmp(&self, other: &Self) -> Option { + fn partial_cmp(&self, other: &Self) -> Option { self.0.partial_cmp(other.as_u64()) } } @@ -211,9 +212,9 @@ pub fn checked_sum>(mut iter: I) -> Result, + pub fn new>( + regs: I, ) -> Result { NonMandatoryRegisters::try_from( regs.into_iter() @@ -217,6 +222,31 @@ impl TryFrom> for NonMandatoryReg } } +#[cfg(feature = "std")] +impl TryFrom> + for NonMandatoryRegisters +{ + type Error = NonMandatoryRegistersError; + fn try_from( + reg_map: std::collections::HashMap, + ) -> Result { + let regs_num = reg_map.len(); + if regs_num > NonMandatoryRegisters::MAX_SIZE { + Err(NonMandatoryRegistersError::InvalidSize(regs_num)) + } else { + let mut res: Vec = vec![]; + NonMandatoryRegisterId::REG_IDS + .iter() + .take(regs_num) + .try_for_each(|reg_id| match reg_map.get(reg_id) { + Some(v) => Ok(res.push(v.clone())), + None => Err(NonMandatoryRegistersError::NonDenselyPacked(*reg_id as u8)), + })?; + Ok(NonMandatoryRegisters(res)) + } + } +} + #[cfg(feature = "json")] impl TryFrom> for NonMandatoryRegisters diff --git a/ergotree-ir/src/chain/ergo_box/register/id.rs b/ergotree-ir/src/chain/ergo_box/register/id.rs index 85bf1cca3..9d641fcbc 100644 --- a/ergotree-ir/src/chain/ergo_box/register/id.rs +++ b/ergotree-ir/src/chain/ergo_box/register/id.rs @@ -1,5 +1,6 @@ -use std::fmt::Display; +use core::fmt::Display; +use alloc::{format, string::String}; use derive_more::From; use thiserror::Error; @@ -66,7 +67,7 @@ impl From for u8 { } impl Display for RegisterId { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self { RegisterId::MandatoryRegisterId(id) => write!(f, "{}", id), RegisterId::NonMandatoryRegisterId(id) => write!(f, "{}", id), diff --git a/ergotree-ir/src/chain/ergo_box/register/value.rs b/ergotree-ir/src/chain/ergo_box/register/value.rs index f55ee2149..23625a48b 100644 --- a/ergotree-ir/src/chain/ergo_box/register/value.rs +++ b/ergotree-ir/src/chain/ergo_box/register/value.rs @@ -1,3 +1,7 @@ + +use alloc::string::String; +use alloc::string::ToString; +use alloc::vec::Vec; use derive_more::From; use thiserror::Error; diff --git a/ergotree-ir/src/chain/json.rs b/ergotree-ir/src/chain/json.rs index cf550d91a..82a0f9928 100644 --- a/ergotree-ir/src/chain/json.rs +++ b/ergotree-ir/src/chain/json.rs @@ -1,8 +1,9 @@ //! JSON serialization -use std::fmt; -use std::marker::PhantomData; -use std::str::FromStr; +use core::fmt; +use core::marker::PhantomData; +use core::str::FromStr; + use serde::de; use serde::de::MapAccess; @@ -32,7 +33,7 @@ pub fn t_as_string_or_struct<'de, T, D, E>(deserializer: D) -> Result + FromStr, D: Deserializer<'de>, - E: std::fmt::Display, + E: core::fmt::Display, { // This is a Visitor that forwards string types to T's `FromStr` impl and // forwards map types to T's `Deserialize` impl. The `PhantomData` is to @@ -44,7 +45,7 @@ where impl<'de, T, FromStrErr> Visitor<'de> for StringOrStruct where T: Deserialize<'de> + FromStr, - FromStrErr: std::fmt::Display, + FromStrErr: core::fmt::Display, { type Value = T; diff --git a/ergotree-ir/src/chain/json/box_value.rs b/ergotree-ir/src/chain/json/box_value.rs index 985058dcf..681daff20 100644 --- a/ergotree-ir/src/chain/json/box_value.rs +++ b/ergotree-ir/src/chain/json/box_value.rs @@ -1,6 +1,8 @@ //! Code to implement `BoxValue` JSON encoding -use std::convert::TryFrom; +use core::convert::TryFrom; + +use alloc::string::String; use crate::chain::ergo_box::box_value::BoxValue; diff --git a/ergotree-ir/src/chain/json/ergo_box.rs b/ergotree-ir/src/chain/json/ergo_box.rs index e55d337c1..83b4c5d4d 100644 --- a/ergotree-ir/src/chain/json/ergo_box.rs +++ b/ergotree-ir/src/chain/json/ergo_box.rs @@ -10,10 +10,12 @@ use crate::chain::tx_id::TxId; use crate::ergo_tree::ErgoTree; use crate::serialization::SigmaParsingError; use crate::serialization::SigmaSerializationError; +use alloc::string::ToString; +use alloc::vec::Vec; +use core::convert::TryFrom; +use core::convert::TryInto; +use core::str::FromStr; use ergo_chain_types::Base16DecodedBytes; -use std::convert::TryFrom; -use std::convert::TryInto; -use std::str::FromStr; extern crate derive_more; use derive_more::From; @@ -241,8 +243,9 @@ impl FromStr for RichConstant { #[allow(clippy::panic)] #[allow(clippy::unwrap_used)] #[cfg(test)] +#[cfg(feature = "arbitrary")] mod tests { - use std::convert::TryInto; + use core::convert::TryInto; use crate::chain::ergo_box::ErgoBox; use crate::chain::ergo_box::NonMandatoryRegisterId; diff --git a/ergotree-ir/src/chain/json/ergo_box/box_value.rs b/ergotree-ir/src/chain/json/ergo_box/box_value.rs index 82130aef3..b8f88c4b4 100644 --- a/ergotree-ir/src/chain/json/ergo_box/box_value.rs +++ b/ergotree-ir/src/chain/json/ergo_box/box_value.rs @@ -2,7 +2,7 @@ #[cfg(test)] mod tests { use crate::chain::ergo_box::box_value::BoxValue; - use std::convert::TryInto; + use core::convert::TryInto; #[test] fn parse_value_as_str() { diff --git a/ergotree-ir/src/chain/json/ergo_tree.rs b/ergotree-ir/src/chain/json/ergo_tree.rs index c4347f9fe..dd2c786d2 100644 --- a/ergotree-ir/src/chain/json/ergo_tree.rs +++ b/ergotree-ir/src/chain/json/ergo_tree.rs @@ -2,6 +2,7 @@ use crate::ergo_tree::ErgoTree; use crate::serialization::SigmaSerializable; +use alloc::string::{String, ToString}; use serde::{Deserialize, Deserializer, Serializer}; use super::serialize_bytes; diff --git a/ergotree-ir/src/chain/json/sigma_protocol.rs b/ergotree-ir/src/chain/json/sigma_protocol.rs index 9e28d2644..434950db4 100644 --- a/ergotree-ir/src/chain/json/sigma_protocol.rs +++ b/ergotree-ir/src/chain/json/sigma_protocol.rs @@ -1,6 +1,7 @@ -use std::convert::TryFrom; -use std::convert::TryInto; +use core::convert::TryFrom; +use core::convert::TryInto; +use alloc::vec::Vec; use bounded_vec::BoundedVecOutOfBounds; use ergo_chain_types::EcPoint; use serde::Deserialize; diff --git a/ergotree-ir/src/chain/json/token.rs b/ergotree-ir/src/chain/json/token.rs index 1b5cd5cf2..03024d27e 100644 --- a/ergotree-ir/src/chain/json/token.rs +++ b/ergotree-ir/src/chain/json/token.rs @@ -1,6 +1,8 @@ //! Code to implement `TokenAmount` JSON encoding -use std::convert::TryFrom; +use core::convert::TryFrom; + +use alloc::string::String; use crate::chain::token::TokenAmount; diff --git a/ergotree-ir/src/chain/token.rs b/ergotree-ir/src/chain/token.rs index e15c8853f..181adc3ea 100644 --- a/ergotree-ir/src/chain/token.rs +++ b/ergotree-ir/src/chain/token.rs @@ -5,9 +5,11 @@ use crate::serialization::{ sigma_byte_reader::SigmaByteRead, sigma_byte_writer::SigmaByteWrite, SigmaParsingError, SigmaSerializable, }; -use std::convert::TryFrom; +use core::convert::TryFrom; use super::ergo_box::BoxId; +use alloc::string::String; +use alloc::vec::Vec; use derive_more::From; use derive_more::Into; use ergo_chain_types::{Digest32, DigestNError}; @@ -198,7 +200,7 @@ pub mod arbitrary { use super::TokenAmount; use super::TokenId; - use std::convert::TryFrom; + use core::convert::TryFrom; /// How to generate a token id #[derive(Default)] @@ -281,6 +283,7 @@ mod tests { use crate::chain::token::TokenId; use crate::serialization::sigma_serialize_roundtrip; + use proptest::prelude::*; proptest! { diff --git a/ergotree-ir/src/chain/tx_id.rs b/ergotree-ir/src/chain/tx_id.rs index 339e7c4d1..1a015ae10 100644 --- a/ergotree-ir/src/chain/tx_id.rs +++ b/ergotree-ir/src/chain/tx_id.rs @@ -1,4 +1,5 @@ //! Transaction id type +use alloc::string::String; use derive_more::Display; use derive_more::From; diff --git a/ergotree-ir/src/ergo_tree.rs b/ergotree-ir/src/ergo_tree.rs index 7c7942a3e..7316d33ac 100644 --- a/ergotree-ir/src/ergo_tree.rs +++ b/ergotree-ir/src/ergo_tree.rs @@ -11,13 +11,19 @@ use crate::serialization::{ }; use crate::sigma_protocol::sigma_boolean::ProveDlog; use crate::types::stype::SType; -use io::Cursor; + +use alloc::string::String; +use alloc::string::ToString; +use alloc::vec; +use alloc::vec::Vec; use sigma_ser::vlq_encode::WriteSigmaVlqExt; use crate::serialization::constant_store::ConstantStore; +use core::convert::TryFrom; +use core2::io; use derive_more::From; -use std::convert::TryFrom; -use std::io; +use io::Cursor; +#[cfg(feature = "std")] use std::sync::OnceLock; use thiserror::Error; @@ -30,6 +36,7 @@ pub struct ParsedErgoTree { header: ErgoTreeHeader, constants: Vec, root: Expr, + #[cfg(feature = "std")] has_deserialize: OnceLock, } @@ -40,7 +47,7 @@ impl ParsedErgoTree { let mut new_constants = self.constants.clone(); if let Some(old_constant) = self.constants.get(index) { if constant.tpe == old_constant.tpe { - let _ = std::mem::replace(&mut new_constants[index], constant); + let _ = core::mem::replace(&mut new_constants[index], constant); Ok(Self { constants: new_constants, ..self @@ -157,6 +164,7 @@ impl ErgoTree { let was_deserialize = r.was_deserialize(); r.set_deserialize(false); let root = Expr::sigma_parse(r)?; + #[allow(unused)] let has_deserialize = r.was_deserialize(); r.set_deserialize(was_deserialize); if root.tpe() != SType::SSigmaProp { @@ -166,6 +174,7 @@ impl ErgoTree { header, constants, root, + #[cfg(feature = "std")] has_deserialize: has_deserialize.into(), }) } @@ -208,6 +217,7 @@ impl ErgoTree { header, constants, root: parsed_expr, + #[cfg(feature = "std")] has_deserialize: OnceLock::new(), }) } else { @@ -215,6 +225,7 @@ impl ErgoTree { header, constants: Vec::new(), root: expr.clone(), + #[cfg(feature = "std")] has_deserialize: OnceLock::new(), }) }) @@ -240,12 +251,14 @@ impl ErgoTree { pub fn has_deserialize(&self) -> bool { match self { ErgoTree::Unparsed { .. } => false, + #[cfg(feature = "std")] ErgoTree::Parsed(ParsedErgoTree { - header: _, - constants: _, root, has_deserialize, + .. }) => *has_deserialize.get_or_init(|| root.has_deserialize()), + #[cfg(not(feature = "std"))] + ErgoTree::Parsed(ParsedErgoTree { root, .. }) => root.has_deserialize(), } } @@ -366,11 +379,11 @@ impl SigmaSerializable for ErgoTree { } fn sigma_parse(r: &mut R) -> Result { - let start_pos = r.stream_position()?; + let start_pos = r.position()?; let header = ErgoTreeHeader::sigma_parse(r)?; if header.has_size() { let tree_size_bytes = r.get_u32()?; - let body_pos = r.stream_position()?; + let body_pos = r.position()?; let mut buf = vec![0u8; tree_size_bytes as usize]; r.read_exact(buf.as_mut_slice())?; let mut inner_r = @@ -400,6 +413,7 @@ impl SigmaSerializable for ErgoTree { header, constants, root, + #[cfg(feature = "std")] has_deserialize: OnceLock::new(), })) } @@ -425,8 +439,8 @@ impl TryFrom for ProveDlog { } } -impl From for ErgoTreeError { - fn from(e: std::io::Error) -> Self { +impl From for ErgoTreeError { + fn from(e: core2::io::Error) -> Self { ErgoTreeError::IoError(e.to_string()) } } diff --git a/ergotree-ir/src/ergo_tree/tree_header.rs b/ergotree-ir/src/ergo_tree/tree_header.rs index e7d5108c2..12e96b83e 100644 --- a/ergotree-ir/src/ergo_tree/tree_header.rs +++ b/ergotree-ir/src/ergo_tree/tree_header.rs @@ -1,5 +1,6 @@ //! ErgoTree header +use alloc::string::{String, ToString}; use derive_more::From; use thiserror::Error; @@ -32,7 +33,7 @@ pub struct ErgoTreeHeader { impl ErgoTreeHeader { /// Serialization - pub fn sigma_serialize(&self, w: &mut W) -> Result<(), std::io::Error> { + pub fn sigma_serialize(&self, w: &mut W) -> Result<(), core2::io::Error> { w.put_u8(self.serialized()) } /// Deserialization diff --git a/ergotree-ir/src/lib.rs b/ergotree-ir/src/lib.rs index 37e697db6..ee4d6e7eb 100644 --- a/ergotree-ir/src/lib.rs +++ b/ergotree-ir/src/lib.rs @@ -1,5 +1,6 @@ //! ErgoTree, MIR (Middle-level Internal Representation) +#![cfg_attr(not(feature = "std"), no_std)] // Coding conventions #![forbid(unsafe_code)] #![deny(non_upper_case_globals)] @@ -19,6 +20,9 @@ #![deny(clippy::unreachable)] #![deny(clippy::panic)] +#[macro_use] +extern crate alloc; + mod has_opcode; pub mod base16_str; diff --git a/ergotree-ir/src/mir/and.rs b/ergotree-ir/src/mir/and.rs index 10d41b65a..e7d53dcd1 100644 --- a/ergotree-ir/src/mir/and.rs +++ b/ergotree-ir/src/mir/and.rs @@ -1,5 +1,7 @@ //! AND logical conjunction +use alloc::boxed::Box; + use crate::serialization::op_code::OpCode; use crate::serialization::sigma_byte_reader::SigmaByteRead; use crate::serialization::sigma_byte_writer::SigmaByteWrite; @@ -74,6 +76,7 @@ mod tests { use super::*; use crate::mir::expr::Expr; use crate::serialization::sigma_serialize_roundtrip; + use proptest::prelude::*; proptest! { diff --git a/ergotree-ir/src/mir/apply.rs b/ergotree-ir/src/mir/apply.rs index 8660b45f4..71f27d575 100644 --- a/ergotree-ir/src/mir/apply.rs +++ b/ergotree-ir/src/mir/apply.rs @@ -1,5 +1,9 @@ //! Application of function +use alloc::boxed::Box; + +use alloc::vec::Vec; + use crate::serialization::op_code::OpCode; use crate::serialization::sigma_byte_reader::SigmaByteRead; use crate::serialization::sigma_byte_writer::SigmaByteWrite; diff --git a/ergotree-ir/src/mir/atleast.rs b/ergotree-ir/src/mir/atleast.rs index cf42750dd..3d09f98c0 100644 --- a/ergotree-ir/src/mir/atleast.rs +++ b/ergotree-ir/src/mir/atleast.rs @@ -1,4 +1,7 @@ //! THRESHOLD composition for sigma expressions +use alloc::boxed::Box; + + use crate::serialization::op_code::OpCode; use crate::serialization::sigma_byte_reader::SigmaByteRead; use crate::serialization::sigma_byte_writer::SigmaByteWrite; diff --git a/ergotree-ir/src/mir/avl_tree_data.rs b/ergotree-ir/src/mir/avl_tree_data.rs index a0b12f024..f02a68a27 100644 --- a/ergotree-ir/src/mir/avl_tree_data.rs +++ b/ergotree-ir/src/mir/avl_tree_data.rs @@ -1,3 +1,4 @@ +use alloc::boxed::Box; use ergo_chain_types::ADDigest; use sigma_ser::ScorexSerializable; @@ -140,6 +141,7 @@ mod tests { use super::*; use crate::mir::expr::Expr; use crate::serialization::sigma_serialize_roundtrip; + use proptest::prelude::*; proptest! { diff --git a/ergotree-ir/src/mir/bin_op.rs b/ergotree-ir/src/mir/bin_op.rs index 70cc7307c..15d464e81 100644 --- a/ergotree-ir/src/mir/bin_op.rs +++ b/ergotree-ir/src/mir/bin_op.rs @@ -1,6 +1,7 @@ //! Operators in ErgoTree -use std::fmt::Display; +use alloc::boxed::Box; +use core::fmt::Display; use super::expr::Expr; use crate::has_opcode::HasOpCode; @@ -48,7 +49,7 @@ impl From for OpCode { } impl Display for ArithOp { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self { ArithOp::Plus => write!(f, "+"), ArithOp::Minus => write!(f, "-"), @@ -93,7 +94,7 @@ impl From for OpCode { } impl Display for RelationOp { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self { RelationOp::Eq => write!(f, "=="), RelationOp::NEq => write!(f, "!="), @@ -128,7 +129,7 @@ impl From for OpCode { } impl Display for LogicalOp { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self { LogicalOp::And => write!(f, "&&"), LogicalOp::Or => write!(f, "||"), @@ -160,7 +161,7 @@ impl From for OpCode { } impl Display for BitOp { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self { BitOp::BitOr => write!(f, "|"), BitOp::BitAnd => write!(f, "&"), @@ -195,7 +196,7 @@ impl From for OpCode { } impl Display for BinOpKind { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self { BinOpKind::Arith(op) => write!(f, "{}", op), BinOpKind::Relation(op) => write!(f, "{}", op), diff --git a/ergotree-ir/src/mir/bit_inversion.rs b/ergotree-ir/src/mir/bit_inversion.rs index 2cedd892d..6adc6ddd8 100644 --- a/ergotree-ir/src/mir/bit_inversion.rs +++ b/ergotree-ir/src/mir/bit_inversion.rs @@ -1,3 +1,5 @@ +use alloc::boxed::Box; + use super::expr::Expr; use super::expr::InvalidArgumentError; use super::unary_op::OneArgOp; diff --git a/ergotree-ir/src/mir/block.rs b/ergotree-ir/src/mir/block.rs index 6ecae13d2..d75d854a9 100644 --- a/ergotree-ir/src/mir/block.rs +++ b/ergotree-ir/src/mir/block.rs @@ -1,5 +1,8 @@ //! Block of statements ending with an expression +use alloc::boxed::Box; +use alloc::vec::Vec; + use super::expr::Expr; use crate::has_opcode::HasStaticOpCode; use crate::serialization::op_code::OpCode; diff --git a/ergotree-ir/src/mir/bool_to_sigma.rs b/ergotree-ir/src/mir/bool_to_sigma.rs index 9a020632d..286026cd1 100644 --- a/ergotree-ir/src/mir/bool_to_sigma.rs +++ b/ergotree-ir/src/mir/bool_to_sigma.rs @@ -1,4 +1,6 @@ //! Embedding of Boolean values to SigmaProp +use alloc::boxed::Box; + use crate::has_opcode::HasStaticOpCode; use crate::mir::unary_op::OneArgOp; use crate::mir::unary_op::OneArgOpTryBuild; diff --git a/ergotree-ir/src/mir/byte_array_to_bigint.rs b/ergotree-ir/src/mir/byte_array_to_bigint.rs index bfcd774ad..c45aa5359 100644 --- a/ergotree-ir/src/mir/byte_array_to_bigint.rs +++ b/ergotree-ir/src/mir/byte_array_to_bigint.rs @@ -1,5 +1,6 @@ //! Convert byte array to SBigInt -use std::sync::Arc; +use alloc::boxed::Box; +use alloc::sync::Arc; use crate::serialization::op_code::OpCode; use crate::types::stype::SType; @@ -77,6 +78,7 @@ mod arbitrary { mod tests { use super::*; use crate::serialization::sigma_serialize_roundtrip; + use proptest::prelude::*; proptest! { diff --git a/ergotree-ir/src/mir/byte_array_to_long.rs b/ergotree-ir/src/mir/byte_array_to_long.rs index 87029e66b..43018d2f9 100644 --- a/ergotree-ir/src/mir/byte_array_to_long.rs +++ b/ergotree-ir/src/mir/byte_array_to_long.rs @@ -1,5 +1,6 @@ //! Convert byte array to SLong -use std::sync::Arc; +use alloc::boxed::Box; +use alloc::sync::Arc; use crate::serialization::op_code::OpCode; use crate::types::stype::SType; @@ -77,6 +78,7 @@ mod arbitrary { mod tests { use super::*; use crate::serialization::sigma_serialize_roundtrip; + use proptest::prelude::*; proptest! { diff --git a/ergotree-ir/src/mir/calc_blake2b256.rs b/ergotree-ir/src/mir/calc_blake2b256.rs index afb84f892..923dbbdfe 100644 --- a/ergotree-ir/src/mir/calc_blake2b256.rs +++ b/ergotree-ir/src/mir/calc_blake2b256.rs @@ -1,4 +1,5 @@ -use std::sync::Arc; +use alloc::boxed::Box; +use alloc::sync::Arc; use crate::has_opcode::HasStaticOpCode; use crate::serialization::op_code::OpCode; @@ -76,6 +77,7 @@ mod arbitrary { mod tests { use super::*; use crate::serialization::sigma_serialize_roundtrip; + use proptest::prelude::*; proptest! { diff --git a/ergotree-ir/src/mir/calc_sha256.rs b/ergotree-ir/src/mir/calc_sha256.rs index d36897286..e415d0b32 100644 --- a/ergotree-ir/src/mir/calc_sha256.rs +++ b/ergotree-ir/src/mir/calc_sha256.rs @@ -1,4 +1,5 @@ -use std::sync::Arc; +use alloc::boxed::Box; +use alloc::sync::Arc; use crate::has_opcode::HasStaticOpCode; use crate::serialization::op_code::OpCode; @@ -76,6 +77,7 @@ mod arbitrary { mod tests { use super::*; use crate::serialization::sigma_serialize_roundtrip; + use proptest::prelude::*; proptest! { diff --git a/ergotree-ir/src/mir/coll_append.rs b/ergotree-ir/src/mir/coll_append.rs index 8fc9bd8d7..3cff3d992 100644 --- a/ergotree-ir/src/mir/coll_append.rs +++ b/ergotree-ir/src/mir/coll_append.rs @@ -1,3 +1,6 @@ +use alloc::boxed::Box; + + use crate::serialization::op_code::OpCode; use crate::serialization::sigma_byte_reader::SigmaByteRead; use crate::serialization::sigma_byte_writer::SigmaByteWrite; diff --git a/ergotree-ir/src/mir/coll_by_index.rs b/ergotree-ir/src/mir/coll_by_index.rs index 8cedfc7ba..cb3c5bf35 100644 --- a/ergotree-ir/src/mir/coll_by_index.rs +++ b/ergotree-ir/src/mir/coll_by_index.rs @@ -1,4 +1,6 @@ -use std::sync::Arc; +use alloc::boxed::Box; + +use alloc::sync::Arc; use crate::serialization::op_code::OpCode; use crate::serialization::sigma_byte_reader::SigmaByteRead; diff --git a/ergotree-ir/src/mir/coll_exists.rs b/ergotree-ir/src/mir/coll_exists.rs index b605181bf..97e7bfb83 100644 --- a/ergotree-ir/src/mir/coll_exists.rs +++ b/ergotree-ir/src/mir/coll_exists.rs @@ -1,4 +1,6 @@ -use std::sync::Arc; +use alloc::boxed::Box; + +use alloc::sync::Arc; use super::expr::Expr; use super::expr::InvalidArgumentError; @@ -84,6 +86,7 @@ mod arbitrary { use super::*; use crate::mir::expr::arbitrary::ArbExprParams; use crate::types::sfunc::SFunc; + use alloc::vec; use proptest::prelude::*; impl Arbitrary for Exists { diff --git a/ergotree-ir/src/mir/coll_filter.rs b/ergotree-ir/src/mir/coll_filter.rs index b245da250..9dd22c079 100644 --- a/ergotree-ir/src/mir/coll_filter.rs +++ b/ergotree-ir/src/mir/coll_filter.rs @@ -1,4 +1,6 @@ -use std::sync::Arc; +use alloc::boxed::Box; + +use alloc::sync::Arc; use super::expr::Expr; use super::expr::InvalidArgumentError; @@ -84,6 +86,7 @@ mod arbitrary { use super::*; use crate::mir::expr::arbitrary::ArbExprParams; use crate::types::sfunc::SFunc; + use alloc::vec; use proptest::prelude::*; impl Arbitrary for Filter { diff --git a/ergotree-ir/src/mir/coll_fold.rs b/ergotree-ir/src/mir/coll_fold.rs index bd9f96f3c..51c7320ce 100644 --- a/ergotree-ir/src/mir/coll_fold.rs +++ b/ergotree-ir/src/mir/coll_fold.rs @@ -1,3 +1,7 @@ +use alloc::boxed::Box; + +use alloc::vec; + use crate::serialization::op_code::OpCode; use crate::serialization::sigma_byte_reader::SigmaByteRead; use crate::serialization::sigma_byte_writer::SigmaByteWrite; diff --git a/ergotree-ir/src/mir/coll_forall.rs b/ergotree-ir/src/mir/coll_forall.rs index 75f375525..f24a56d0a 100644 --- a/ergotree-ir/src/mir/coll_forall.rs +++ b/ergotree-ir/src/mir/coll_forall.rs @@ -1,4 +1,6 @@ -use std::sync::Arc; +use alloc::boxed::Box; + +use alloc::sync::Arc; use super::expr::Expr; use super::expr::InvalidArgumentError; @@ -84,6 +86,7 @@ mod arbitrary { use super::*; use crate::mir::expr::arbitrary::ArbExprParams; use crate::types::sfunc::SFunc; + use alloc::vec; use proptest::prelude::*; impl Arbitrary for ForAll { diff --git a/ergotree-ir/src/mir/coll_map.rs b/ergotree-ir/src/mir/coll_map.rs index 42f3d85f7..7eab91eb7 100644 --- a/ergotree-ir/src/mir/coll_map.rs +++ b/ergotree-ir/src/mir/coll_map.rs @@ -1,3 +1,6 @@ +use alloc::boxed::Box; + + use crate::serialization::op_code::OpCode; use crate::serialization::sigma_byte_reader::SigmaByteRead; use crate::serialization::sigma_byte_writer::SigmaByteWrite; @@ -84,6 +87,7 @@ impl_traversable_expr!(Map, boxed input, boxed mapper); mod arbitrary { use super::*; use crate::mir::expr::arbitrary::ArbExprParams; + use alloc::vec; use proptest::prelude::*; impl Arbitrary for Map { diff --git a/ergotree-ir/src/mir/coll_size.rs b/ergotree-ir/src/mir/coll_size.rs index f837ee403..ba1f3ad06 100644 --- a/ergotree-ir/src/mir/coll_size.rs +++ b/ergotree-ir/src/mir/coll_size.rs @@ -1,3 +1,6 @@ +use alloc::boxed::Box; + + use crate::serialization::op_code::OpCode; use crate::types::stype::SType; diff --git a/ergotree-ir/src/mir/coll_slice.rs b/ergotree-ir/src/mir/coll_slice.rs index 3d2bc06e0..57eb6a974 100644 --- a/ergotree-ir/src/mir/coll_slice.rs +++ b/ergotree-ir/src/mir/coll_slice.rs @@ -1,3 +1,6 @@ +use alloc::boxed::Box; + + use crate::serialization::op_code::OpCode; use crate::serialization::sigma_byte_reader::SigmaByteRead; use crate::serialization::sigma_byte_writer::SigmaByteWrite; diff --git a/ergotree-ir/src/mir/collection.rs b/ergotree-ir/src/mir/collection.rs index 4b653f4f5..19792dadd 100644 --- a/ergotree-ir/src/mir/collection.rs +++ b/ergotree-ir/src/mir/collection.rs @@ -1,3 +1,6 @@ +use alloc::boxed::Box; +use alloc::vec::Vec; + use crate::has_opcode::HasOpCode; use crate::serialization::op_code::OpCode; use crate::serialization::sigma_byte_reader::SigmaByteRead; @@ -83,13 +86,13 @@ impl Traversable for Collection { fn children(&self) -> Box + '_> { match self { Self::Exprs { elem_tpe: _, items } => Box::new(items.iter()), - Self::BoolConstants(_) => Box::new(std::iter::empty()), + Self::BoolConstants(_) => Box::new(core::iter::empty()), } } fn children_mut(&mut self) -> Box + '_> { match self { Self::Exprs { elem_tpe: _, items } => Box::new(items.iter_mut()), - Self::BoolConstants(_) => Box::new(std::iter::empty()), + Self::BoolConstants(_) => Box::new(core::iter::empty()), } } } diff --git a/ergotree-ir/src/mir/constant.rs b/ergotree-ir/src/mir/constant.rs index ae61153e9..c828acfe5 100644 --- a/ergotree-ir/src/mir/constant.rs +++ b/ergotree-ir/src/mir/constant.rs @@ -17,6 +17,15 @@ use crate::types::stuple::STuple; use crate::types::stuple::TupleItems; use crate::types::stype::LiftIntoSType; use crate::types::stype::SType; +use alloc::boxed::Box; + +use alloc::string::String; +use alloc::string::ToString; +use alloc::sync::Arc; +use alloc::vec::Vec; +use core::convert::TryFrom; +use core::convert::TryInto; +use core::fmt::Formatter; use ergo_chain_types::ADDigest; use ergo_chain_types::Base16DecodedBytes; use ergo_chain_types::Digest32; @@ -24,10 +33,6 @@ use ergo_chain_types::EcPoint; use impl_trait_for_tuples::impl_for_tuples; use sigma_util::AsVecI8; use sigma_util::AsVecU8; -use std::convert::TryFrom; -use std::convert::TryInto; -use std::fmt::Formatter; -use std::sync::Arc; mod constant_placeholder; @@ -83,20 +88,20 @@ pub enum Literal { Tup(TupleItems), } -impl std::fmt::Debug for Constant { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Debug for Constant { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { format!("{:?}: {:?}", self.v, self.tpe).fmt(f) } } -impl std::fmt::Display for Constant { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Display for Constant { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { self.v.fmt(f) } } -impl std::fmt::Debug for Literal { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Debug for Literal { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { match self { Literal::Coll(CollKind::NativeColl(NativeColl::CollByte(i8_bytes))) => { base16::encode_lower(&i8_bytes.as_vec_u8()).fmt(f) @@ -119,8 +124,8 @@ impl std::fmt::Debug for Literal { } } -impl std::fmt::Display for Literal { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Display for Literal { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { match self { Literal::Coll(CollKind::NativeColl(NativeColl::CollByte(i8_bytes))) => { write!(f, "Coll[Byte](")?; @@ -755,13 +760,13 @@ impl + StoreWrapped> TryExtractFrom for Vec< } => v.iter().cloned().map(T::try_extract_from).collect(), _ => Err(TryExtractFromError(format!( "expected {:?}, found {:?}", - std::any::type_name::(), + core::any::type_name::(), coll ))), }, _ => Err(TryExtractFromError(format!( "expected {:?}, found {:?}", - std::any::type_name::(), + core::any::type_name::(), c ))), } @@ -775,13 +780,13 @@ impl TryExtractFrom for Vec { CollKind::NativeColl(NativeColl::CollByte(bs)) => Ok(bs.iter().copied().collect()), // TODO: optimize _ => Err(TryExtractFromError(format!( "expected {:?}, found {:?}", - std::any::type_name::(), + core::any::type_name::(), v ))), }, _ => Err(TryExtractFromError(format!( "expected {:?}, found {:?}", - std::any::type_name::(), + core::any::type_name::(), v ))), } @@ -823,7 +828,7 @@ impl TryExtractFrom for BigInt256 { Literal::BigInt(bi) => Ok(bi), _ => Err(TryExtractFromError(format!( "expected {:?}, found {:?}", - std::any::type_name::(), + core::any::type_name::(), v ))), } @@ -836,7 +841,7 @@ impl TryExtractFrom for AvlTreeData { Literal::AvlTree(a) => Ok(*a), _ => Err(TryExtractFromError(format!( "expected {:?}, found {:?}", - std::any::type_name::(), + core::any::type_name::(), v ))), } @@ -926,7 +931,7 @@ impl TryFrom for Constant { #[allow(clippy::todo)] /// Arbitrary impl pub(crate) mod arbitrary { - use std::convert::TryFrom; + use core::convert::TryFrom; use super::*; use crate::mir::value::CollKind; diff --git a/ergotree-ir/src/mir/create_avl_tree.rs b/ergotree-ir/src/mir/create_avl_tree.rs index 0ef8feb8d..e0d7db78f 100644 --- a/ergotree-ir/src/mir/create_avl_tree.rs +++ b/ergotree-ir/src/mir/create_avl_tree.rs @@ -1,5 +1,8 @@ //! Create an AVL tree +use alloc::boxed::Box; + + use super::expr::Expr; use crate::has_opcode::HasStaticOpCode; use crate::mir::expr::InvalidArgumentError; @@ -32,7 +35,7 @@ impl CreateAvlTree { value_length: Option>, ) -> Result { flags.check_post_eval_tpe(&SType::SByte)?; - digest.check_post_eval_tpe(&SType::SColl(std::sync::Arc::new(SType::SByte)))?; + digest.check_post_eval_tpe(&SType::SColl(alloc::sync::Arc::new(SType::SByte)))?; key_length.check_post_eval_tpe(&SType::SInt)?; if !value_length .clone() @@ -86,7 +89,7 @@ impl_traversable_expr!(CreateAvlTree, boxed flags, boxed digest, boxed key_lengt #[cfg(feature = "arbitrary")] /// Arbitrary impl mod arbitrary { - use std::sync::Arc; + use alloc::sync::Arc; use crate::mir::expr::arbitrary::ArbExprParams; diff --git a/ergotree-ir/src/mir/create_prove_dh_tuple.rs b/ergotree-ir/src/mir/create_prove_dh_tuple.rs index 3da6f8563..27c8f2152 100644 --- a/ergotree-ir/src/mir/create_prove_dh_tuple.rs +++ b/ergotree-ir/src/mir/create_prove_dh_tuple.rs @@ -1,3 +1,5 @@ +use alloc::boxed::Box; + use crate::serialization::op_code::OpCode; use crate::serialization::sigma_byte_reader::SigmaByteRead; use crate::serialization::sigma_byte_writer::SigmaByteWrite; diff --git a/ergotree-ir/src/mir/create_provedlog.rs b/ergotree-ir/src/mir/create_provedlog.rs index f7828ca94..de4ea5d8a 100644 --- a/ergotree-ir/src/mir/create_provedlog.rs +++ b/ergotree-ir/src/mir/create_provedlog.rs @@ -1,3 +1,5 @@ +use alloc::boxed::Box; + use crate::serialization::op_code::OpCode; use crate::types::stype::SType; diff --git a/ergotree-ir/src/mir/decode_point.rs b/ergotree-ir/src/mir/decode_point.rs index 8db2d17ff..0a360289e 100644 --- a/ergotree-ir/src/mir/decode_point.rs +++ b/ergotree-ir/src/mir/decode_point.rs @@ -1,6 +1,7 @@ //! Decode byte array to EC point -use std::sync::Arc; +use alloc::boxed::Box; +use alloc::sync::Arc; use crate::serialization::op_code::OpCode; use crate::types::stype::SType; @@ -77,6 +78,7 @@ mod tests { use super::*; use crate::mir::expr::Expr; use crate::serialization::sigma_serialize_roundtrip; + use proptest::prelude::*; proptest! { diff --git a/ergotree-ir/src/mir/deserialize_register.rs b/ergotree-ir/src/mir/deserialize_register.rs index 33ab5645f..397bdc9bb 100644 --- a/ergotree-ir/src/mir/deserialize_register.rs +++ b/ergotree-ir/src/mir/deserialize_register.rs @@ -1,5 +1,8 @@ //! Extract register of SELF box as `Coll[Byte]`, deserialize it into Value and inline into executing script. +use alloc::boxed::Box; +use alloc::string::ToString; + use super::expr::Expr; use super::expr::InvalidArgumentError; use crate::chain::ergo_box::RegisterId; @@ -71,6 +74,7 @@ mod arbitrary { use super::*; + use alloc::boxed::Box; use proptest::option; use proptest::prelude::*; diff --git a/ergotree-ir/src/mir/downcast.rs b/ergotree-ir/src/mir/downcast.rs index 0b9a34e1c..d8a036965 100644 --- a/ergotree-ir/src/mir/downcast.rs +++ b/ergotree-ir/src/mir/downcast.rs @@ -1,5 +1,8 @@ //! Numerical downcast +use alloc::boxed::Box; + + use super::expr::Expr; use super::expr::InvalidArgumentError; use crate::serialization::op_code::OpCode; diff --git a/ergotree-ir/src/mir/exponentiate.rs b/ergotree-ir/src/mir/exponentiate.rs index a93cebc81..fed5ad27c 100644 --- a/ergotree-ir/src/mir/exponentiate.rs +++ b/ergotree-ir/src/mir/exponentiate.rs @@ -1,3 +1,6 @@ +use alloc::boxed::Box; + + use crate::serialization::op_code::OpCode; use crate::serialization::sigma_byte_reader::SigmaByteRead; use crate::serialization::sigma_byte_writer::SigmaByteWrite; diff --git a/ergotree-ir/src/mir/expr.rs b/ergotree-ir/src/mir/expr.rs index 9f48d128e..7e7054b0a 100644 --- a/ergotree-ir/src/mir/expr.rs +++ b/ergotree-ir/src/mir/expr.rs @@ -1,7 +1,11 @@ //! IR expression -use std::convert::Infallible; -use std::convert::TryFrom; +use alloc::boxed::Box; +use alloc::string::String; +use alloc::vec::Vec; +use core::convert::Infallible; +use core::convert::TryFrom; +use core::convert::TryInto; use crate::chain::context::Context; use crate::chain::ergo_box::RegisterId; @@ -324,8 +328,10 @@ impl Expr { if &expr_tpe == expected_tpe { Ok(()) } else { - use std::backtrace::Backtrace; - let backtrace = Backtrace::capture(); + #[cfg(feature = "std")] + let backtrace = std::backtrace::Backtrace::capture(); + #[cfg(not(feature = "std"))] + let backtrace = "Backtraces not supported without std"; Err(InvalidExprEvalTypeError(format!( "expected: {0:?}, got: {1:?}\nBacktrace:\n{backtrace}", expected_tpe, expr_tpe @@ -485,7 +491,7 @@ impl Traversable for Expr { fn children<'a>(&'a self) -> Box + '_> { match self { - Expr::Const(_) => Box::new(std::iter::empty()), + Expr::Const(_) => Box::new(core::iter::empty()), Expr::SubstConstants(op) => op.children(), Expr::ByteArrayToLong(op) => op.children(), Expr::ByteArrayToBigInt(op) => op.children(), @@ -498,8 +504,8 @@ impl Traversable for Expr { Expr::MethodCall(op) => op.children(), Expr::PropertyCall(op) => op.children(), Expr::BinOp(op) => op.children(), - Expr::Global => Box::new(std::iter::empty()), - Expr::Context => Box::new(std::iter::empty()), + Expr::Global => Box::new(core::iter::empty()), + Expr::Context => Box::new(core::iter::empty()), Expr::OptionGet(v) => v.children(), Expr::Apply(op) => op.children(), Expr::FuncValue(op) => op.children(), @@ -507,7 +513,7 @@ impl Traversable for Expr { Expr::BlockValue(op) => op.children(), Expr::SelectField(op) => op.children(), Expr::ExtractAmount(op) => op.children(), - Expr::ConstPlaceholder(_) => Box::new(std::iter::empty()), + Expr::ConstPlaceholder(_) => Box::new(core::iter::empty()), Expr::Collection(op) => op.children(), Expr::ValDef(op) => op.children(), Expr::And(op) => op.children(), @@ -555,7 +561,7 @@ impl Traversable for Expr { } fn children_mut<'a>(&'a mut self) -> Box + '_> { match self { - Expr::Const(_) => Box::new(std::iter::empty()), + Expr::Const(_) => Box::new(core::iter::empty()), Expr::SubstConstants(op) => op.children_mut(), Expr::ByteArrayToLong(op) => op.children_mut(), Expr::ByteArrayToBigInt(op) => op.children_mut(), @@ -568,8 +574,8 @@ impl Traversable for Expr { Expr::MethodCall(op) => op.children_mut(), Expr::PropertyCall(op) => op.children_mut(), Expr::BinOp(op) => op.children_mut(), - Expr::Global => Box::new(std::iter::empty()), - Expr::Context => Box::new(std::iter::empty()), + Expr::Global => Box::new(core::iter::empty()), + Expr::Context => Box::new(core::iter::empty()), Expr::OptionGet(v) => v.children_mut(), Expr::Apply(op) => op.children_mut(), Expr::FuncValue(op) => op.children_mut(), @@ -577,7 +583,7 @@ impl Traversable for Expr { Expr::BlockValue(op) => op.children_mut(), Expr::SelectField(op) => op.children_mut(), Expr::ExtractAmount(op) => op.children_mut(), - Expr::ConstPlaceholder(_) => Box::new(std::iter::empty()), + Expr::ConstPlaceholder(_) => Box::new(core::iter::empty()), Expr::Collection(op) => op.children_mut(), Expr::ValDef(op) => op.children_mut(), Expr::And(op) => op.children_mut(), @@ -680,7 +686,7 @@ impl> TryExtractFrom for T { let res: Result = v.clone().try_into().map_err(|_| { TryExtractFromError(format!( "Cannot extract {0:?} from {1:?}", - std::any::type_name::(), + core::any::type_name::(), v )) }); @@ -698,9 +704,10 @@ pub(crate) mod arbitrary { use crate::mir::func_value::FuncArg; use crate::sigma_protocol::sigma_boolean::ProveDlog; use crate::types::sfunc::SFunc; + use alloc::sync::Arc; + use alloc::vec; use proptest::collection::*; use proptest::prelude::*; - use std::sync::Arc; /// Parameters for arbitrary Expr generation #[derive(PartialEq, Eq, Debug, Clone)] diff --git a/ergotree-ir/src/mir/extract_amount.rs b/ergotree-ir/src/mir/extract_amount.rs index 206d77fb4..e189f1936 100644 --- a/ergotree-ir/src/mir/extract_amount.rs +++ b/ergotree-ir/src/mir/extract_amount.rs @@ -1,3 +1,5 @@ +use alloc::boxed::Box; + use crate::serialization::op_code::OpCode; use crate::types::stype::SType; @@ -46,6 +48,8 @@ impl OneArgOpTryBuild for ExtractAmount { #[cfg(test)] #[cfg(feature = "arbitrary")] mod tests { + use alloc::boxed::Box; + use crate::mir::global_vars::GlobalVars; use crate::serialization::sigma_serialize_roundtrip; diff --git a/ergotree-ir/src/mir/extract_bytes.rs b/ergotree-ir/src/mir/extract_bytes.rs index c866be5e9..b7bdb009c 100644 --- a/ergotree-ir/src/mir/extract_bytes.rs +++ b/ergotree-ir/src/mir/extract_bytes.rs @@ -1,3 +1,5 @@ +use alloc::boxed::Box; + use crate::serialization::op_code::OpCode; use crate::types::stype::SType; diff --git a/ergotree-ir/src/mir/extract_bytes_with_no_ref.rs b/ergotree-ir/src/mir/extract_bytes_with_no_ref.rs index 2771e12b4..6afa79184 100644 --- a/ergotree-ir/src/mir/extract_bytes_with_no_ref.rs +++ b/ergotree-ir/src/mir/extract_bytes_with_no_ref.rs @@ -1,3 +1,5 @@ +use alloc::boxed::Box; + use crate::serialization::op_code::OpCode; use crate::types::stype::SType; diff --git a/ergotree-ir/src/mir/extract_creation_info.rs b/ergotree-ir/src/mir/extract_creation_info.rs index eb34b74e3..f1ed83157 100644 --- a/ergotree-ir/src/mir/extract_creation_info.rs +++ b/ergotree-ir/src/mir/extract_creation_info.rs @@ -1,3 +1,5 @@ +use alloc::boxed::Box; + use crate::serialization::op_code::OpCode; use crate::types::stuple::STuple; use crate::types::stype::SType; diff --git a/ergotree-ir/src/mir/extract_id.rs b/ergotree-ir/src/mir/extract_id.rs index e33a3ce72..bca53f090 100644 --- a/ergotree-ir/src/mir/extract_id.rs +++ b/ergotree-ir/src/mir/extract_id.rs @@ -1,3 +1,5 @@ +use alloc::boxed::Box; + use crate::serialization::op_code::OpCode; use crate::types::stype::SType; @@ -46,6 +48,8 @@ impl OneArgOpTryBuild for ExtractId { #[cfg(test)] #[cfg(feature = "arbitrary")] mod tests { + use alloc::boxed::Box; + use crate::mir::global_vars::GlobalVars; use crate::serialization::sigma_serialize_roundtrip; diff --git a/ergotree-ir/src/mir/extract_reg_as.rs b/ergotree-ir/src/mir/extract_reg_as.rs index a1ce698f8..fe4e1b800 100644 --- a/ergotree-ir/src/mir/extract_reg_as.rs +++ b/ergotree-ir/src/mir/extract_reg_as.rs @@ -1,4 +1,6 @@ -use std::sync::Arc; +use alloc::boxed::Box; + +use alloc::sync::Arc; use crate::serialization::op_code::OpCode; use crate::serialization::sigma_byte_reader::SigmaByteRead; diff --git a/ergotree-ir/src/mir/extract_script_bytes.rs b/ergotree-ir/src/mir/extract_script_bytes.rs index 5f14803b6..cfa8be5ab 100644 --- a/ergotree-ir/src/mir/extract_script_bytes.rs +++ b/ergotree-ir/src/mir/extract_script_bytes.rs @@ -1,3 +1,5 @@ +use alloc::boxed::Box; + use crate::serialization::op_code::OpCode; use crate::types::stype::SType; diff --git a/ergotree-ir/src/mir/func_value.rs b/ergotree-ir/src/mir/func_value.rs index 6d4fa5ca8..7a8192c67 100644 --- a/ergotree-ir/src/mir/func_value.rs +++ b/ergotree-ir/src/mir/func_value.rs @@ -1,4 +1,7 @@ -use std::fmt; +use alloc::boxed::Box; +use alloc::vec; +use alloc::vec::Vec; +use core::fmt; use crate::has_opcode::HasStaticOpCode; use crate::serialization::op_code::OpCode; @@ -40,7 +43,7 @@ impl SigmaSerializable for FuncArg { } } -impl std::fmt::Display for FuncArg { +impl core::fmt::Display for FuncArg { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "v{}: {}", self.idx, self.tpe) } diff --git a/ergotree-ir/src/mir/get_var.rs b/ergotree-ir/src/mir/get_var.rs index cd480b2c1..f49f3e903 100644 --- a/ergotree-ir/src/mir/get_var.rs +++ b/ergotree-ir/src/mir/get_var.rs @@ -70,6 +70,7 @@ mod tests { use super::*; use crate::mir::expr::Expr; use crate::serialization::sigma_serialize_roundtrip; + use proptest::prelude::*; proptest! { diff --git a/ergotree-ir/src/mir/global_vars.rs b/ergotree-ir/src/mir/global_vars.rs index 09165e735..8335a3f20 100644 --- a/ergotree-ir/src/mir/global_vars.rs +++ b/ergotree-ir/src/mir/global_vars.rs @@ -1,7 +1,7 @@ //! Global variables -use std::fmt::Display; -use std::sync::Arc; +use alloc::sync::Arc; +use core::fmt::Display; use crate::has_opcode::HasOpCode; use crate::serialization::op_code::OpCode; @@ -56,7 +56,7 @@ impl HasOpCode for GlobalVars { } impl Display for GlobalVars { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self { GlobalVars::SelfBox => write!(f, "SELF"), GlobalVars::Inputs => write!(f, "INPUTS"), diff --git a/ergotree-ir/src/mir/if_op.rs b/ergotree-ir/src/mir/if_op.rs index 1298f3e30..ce842494f 100644 --- a/ergotree-ir/src/mir/if_op.rs +++ b/ergotree-ir/src/mir/if_op.rs @@ -1,3 +1,5 @@ +use alloc::boxed::Box; + use super::expr::Expr; use crate::has_opcode::HasStaticOpCode; use crate::serialization::op_code::OpCode; diff --git a/ergotree-ir/src/mir/logical_not.rs b/ergotree-ir/src/mir/logical_not.rs index cdb0cc664..85fa9311d 100644 --- a/ergotree-ir/src/mir/logical_not.rs +++ b/ergotree-ir/src/mir/logical_not.rs @@ -1,3 +1,5 @@ +use alloc::boxed::Box; + use super::expr::Expr; use super::expr::InvalidArgumentError; use super::unary_op::OneArgOp; diff --git a/ergotree-ir/src/mir/long_to_byte_array.rs b/ergotree-ir/src/mir/long_to_byte_array.rs index bd01a0b4b..609a7b491 100644 --- a/ergotree-ir/src/mir/long_to_byte_array.rs +++ b/ergotree-ir/src/mir/long_to_byte_array.rs @@ -1,4 +1,6 @@ //! Convert SLong to byte array +use alloc::boxed::Box; + use crate::serialization::op_code::OpCode; use crate::types::stype::SType; @@ -78,6 +80,7 @@ mod arbitrary { mod tests { use super::*; use crate::serialization::sigma_serialize_roundtrip; + use proptest::prelude::*; proptest! { diff --git a/ergotree-ir/src/mir/method_call.rs b/ergotree-ir/src/mir/method_call.rs index 6d6e8ccac..e21d6f6c0 100644 --- a/ergotree-ir/src/mir/method_call.rs +++ b/ergotree-ir/src/mir/method_call.rs @@ -1,4 +1,9 @@ -use std::collections::HashMap; +use hashbrown::HashMap; + +use alloc::boxed::Box; + +use alloc::vec; +use alloc::vec::Vec; use crate::serialization::op_code::OpCode; use crate::traversable::impl_traversable_expr; @@ -52,7 +57,7 @@ impl MethodCall { .method_raw .explicit_type_args .iter() - .find(|tpe| !explicit_type_args.contains_key(tpe)) + .find(|&tpe| !explicit_type_args.contains_key(tpe)) { return Err(InvalidArgumentError(format!( "MethodCall: explicit_type_args does not include substitution for STypeVar {missing_tpe:?}", diff --git a/ergotree-ir/src/mir/multiply_group.rs b/ergotree-ir/src/mir/multiply_group.rs index 97e4c4ec7..bc8e2891d 100644 --- a/ergotree-ir/src/mir/multiply_group.rs +++ b/ergotree-ir/src/mir/multiply_group.rs @@ -1,3 +1,6 @@ +use alloc::boxed::Box; + + use crate::serialization::op_code::OpCode; use crate::serialization::sigma_byte_reader::SigmaByteRead; use crate::serialization::sigma_byte_writer::SigmaByteWrite; diff --git a/ergotree-ir/src/mir/negation.rs b/ergotree-ir/src/mir/negation.rs index 16b3d42eb..1be5986d3 100644 --- a/ergotree-ir/src/mir/negation.rs +++ b/ergotree-ir/src/mir/negation.rs @@ -1,3 +1,6 @@ +use alloc::boxed::Box; + + use super::expr::Expr; use super::expr::InvalidArgumentError; use super::unary_op::OneArgOp; @@ -91,6 +94,7 @@ mod tests { use super::*; use crate::mir::expr::Expr; use crate::serialization::sigma_serialize_roundtrip; + use proptest::prelude::*; proptest! { diff --git a/ergotree-ir/src/mir/option_get.rs b/ergotree-ir/src/mir/option_get.rs index 571c50aa2..8920f344d 100644 --- a/ergotree-ir/src/mir/option_get.rs +++ b/ergotree-ir/src/mir/option_get.rs @@ -1,4 +1,6 @@ -use std::sync::Arc; +use alloc::boxed::Box; + +use alloc::sync::Arc; use super::expr::Expr; use super::expr::InvalidArgumentError; diff --git a/ergotree-ir/src/mir/option_get_or_else.rs b/ergotree-ir/src/mir/option_get_or_else.rs index 299752f82..24d322115 100644 --- a/ergotree-ir/src/mir/option_get_or_else.rs +++ b/ergotree-ir/src/mir/option_get_or_else.rs @@ -9,7 +9,9 @@ use crate::serialization::SigmaSerializable; use crate::serialization::SigmaSerializeResult; use crate::traversable::impl_traversable_expr; use crate::types::stype::SType; -use std::sync::Arc; +use alloc::boxed::Box; + +use alloc::sync::Arc; /// Returns the Option's value or error if no value #[derive(PartialEq, Eq, Debug, Clone)] diff --git a/ergotree-ir/src/mir/option_is_defined.rs b/ergotree-ir/src/mir/option_is_defined.rs index 6adb2a28a..3bd9e1271 100644 --- a/ergotree-ir/src/mir/option_is_defined.rs +++ b/ergotree-ir/src/mir/option_is_defined.rs @@ -1,3 +1,6 @@ +use alloc::boxed::Box; + + use super::expr::Expr; use super::expr::InvalidArgumentError; use super::unary_op::OneArgOp; diff --git a/ergotree-ir/src/mir/or.rs b/ergotree-ir/src/mir/or.rs index 52526961e..947728e83 100644 --- a/ergotree-ir/src/mir/or.rs +++ b/ergotree-ir/src/mir/or.rs @@ -1,3 +1,5 @@ +use alloc::boxed::Box; + use super::expr::Expr; use super::unary_op::OneArgOp; use crate::has_opcode::HasStaticOpCode; diff --git a/ergotree-ir/src/mir/property_call.rs b/ergotree-ir/src/mir/property_call.rs index 0f0f078ff..d08d49898 100644 --- a/ergotree-ir/src/mir/property_call.rs +++ b/ergotree-ir/src/mir/property_call.rs @@ -1,3 +1,7 @@ +use alloc::boxed::Box; + +use alloc::vec; + use crate::serialization::op_code::OpCode; use crate::traversable::impl_traversable_expr; use crate::types::smethod::SMethod; diff --git a/ergotree-ir/src/mir/select_field.rs b/ergotree-ir/src/mir/select_field.rs index d033b40c0..4a0aed165 100644 --- a/ergotree-ir/src/mir/select_field.rs +++ b/ergotree-ir/src/mir/select_field.rs @@ -1,4 +1,7 @@ -use std::convert::TryFrom; +use core::convert::TryFrom; + +use alloc::boxed::Box; + use crate::serialization::op_code::OpCode; use crate::serialization::sigma_byte_reader::SigmaByteRead; @@ -126,7 +129,7 @@ impl_traversable_expr!(SelectField, boxed input); #[cfg(feature = "arbitrary")] #[allow(clippy::unwrap_used)] mod tests { - use std::convert::TryInto; + use core::convert::TryInto; use crate::serialization::sigma_serialize_roundtrip; diff --git a/ergotree-ir/src/mir/sigma_and.rs b/ergotree-ir/src/mir/sigma_and.rs index 6659aa762..2b33fd975 100644 --- a/ergotree-ir/src/mir/sigma_and.rs +++ b/ergotree-ir/src/mir/sigma_and.rs @@ -1,6 +1,9 @@ //! AND conjunction for sigma propositions -use std::convert::TryInto; +use core::convert::TryInto; + + +use alloc::vec::Vec; use crate::serialization::op_code::OpCode; use crate::serialization::sigma_byte_reader::SigmaByteRead; diff --git a/ergotree-ir/src/mir/sigma_or.rs b/ergotree-ir/src/mir/sigma_or.rs index af24d4b97..68070649d 100644 --- a/ergotree-ir/src/mir/sigma_or.rs +++ b/ergotree-ir/src/mir/sigma_or.rs @@ -1,6 +1,9 @@ //! OR conjunction for sigma propositions -use std::convert::TryInto; +use core::convert::TryInto; + + +use alloc::vec::Vec; use crate::serialization::op_code::OpCode; use crate::serialization::sigma_byte_reader::SigmaByteRead; diff --git a/ergotree-ir/src/mir/sigma_prop_bytes.rs b/ergotree-ir/src/mir/sigma_prop_bytes.rs index 9db3ae51a..5d7e26d81 100644 --- a/ergotree-ir/src/mir/sigma_prop_bytes.rs +++ b/ergotree-ir/src/mir/sigma_prop_bytes.rs @@ -1,3 +1,5 @@ +use alloc::boxed::Box; + use crate::serialization::op_code::OpCode; use crate::types::stype::SType; diff --git a/ergotree-ir/src/mir/subst_const.rs b/ergotree-ir/src/mir/subst_const.rs index afb8a23f8..60da0fd3d 100644 --- a/ergotree-ir/src/mir/subst_const.rs +++ b/ergotree-ir/src/mir/subst_const.rs @@ -1,4 +1,7 @@ //! Substitution of constants in serialized sigma expression +use alloc::boxed::Box; + + use super::expr::Expr; use crate::has_opcode::HasStaticOpCode; use crate::mir::expr::InvalidArgumentError; diff --git a/ergotree-ir/src/mir/tree_lookup.rs b/ergotree-ir/src/mir/tree_lookup.rs index 918131f27..bb23e1936 100644 --- a/ergotree-ir/src/mir/tree_lookup.rs +++ b/ergotree-ir/src/mir/tree_lookup.rs @@ -1,4 +1,6 @@ //! Lookup in AVL tree +use alloc::boxed::Box; + use crate::serialization::op_code::OpCode; use crate::traversable::impl_traversable_expr; use crate::types::stype::SType; @@ -66,7 +68,7 @@ impl_traversable_expr!(TreeLookup, boxed tree, boxed key, boxed proof); /// Arbitrary impl mod arbitrary { use crate::mir::expr::arbitrary::ArbExprParams; - use std::sync::Arc; + use alloc::sync::Arc; use super::*; use proptest::prelude::*; diff --git a/ergotree-ir/src/mir/tuple.rs b/ergotree-ir/src/mir/tuple.rs index 90b8cfcd1..262b220d8 100644 --- a/ergotree-ir/src/mir/tuple.rs +++ b/ergotree-ir/src/mir/tuple.rs @@ -1,4 +1,6 @@ -use std::convert::TryInto; +use core::convert::TryInto; + +use alloc::vec::Vec; use crate::serialization::op_code::OpCode; use crate::serialization::sigma_byte_reader::SigmaByteRead; diff --git a/ergotree-ir/src/mir/upcast.rs b/ergotree-ir/src/mir/upcast.rs index 79bd82bcf..0181446e6 100644 --- a/ergotree-ir/src/mir/upcast.rs +++ b/ergotree-ir/src/mir/upcast.rs @@ -1,5 +1,8 @@ //! Numerical upcast +use alloc::boxed::Box; + + use super::expr::Expr; use super::expr::InvalidArgumentError; use crate::serialization::op_code::OpCode; diff --git a/ergotree-ir/src/mir/val_def.rs b/ergotree-ir/src/mir/val_def.rs index d241b024a..d7541acab 100644 --- a/ergotree-ir/src/mir/val_def.rs +++ b/ergotree-ir/src/mir/val_def.rs @@ -10,6 +10,7 @@ use crate::types::stype::SType; use super::expr::Expr; extern crate derive_more; +use alloc::boxed::Box; use derive_more::Display; use derive_more::From; @@ -23,7 +24,7 @@ use proptest_derive::Arbitrary; pub struct ValId(pub u32); impl ValId { - pub(crate) fn sigma_serialize(&self, w: &mut W) -> std::io::Result<()> { + pub(crate) fn sigma_serialize(&self, w: &mut W) -> core2::io::Result<()> { w.put_u32(self.0) } diff --git a/ergotree-ir/src/mir/val_use.rs b/ergotree-ir/src/mir/val_use.rs index 684d7e03a..bf7f8449d 100644 --- a/ergotree-ir/src/mir/val_use.rs +++ b/ergotree-ir/src/mir/val_use.rs @@ -55,6 +55,9 @@ mod tests { use super::*; + use alloc::boxed::Box; + + use alloc::vec; use proptest::prelude::*; proptest! { diff --git a/ergotree-ir/src/mir/value.rs b/ergotree-ir/src/mir/value.rs index 9f01c9b69..9991bb703 100644 --- a/ergotree-ir/src/mir/value.rs +++ b/ergotree-ir/src/mir/value.rs @@ -1,8 +1,12 @@ //! Ergo data type -use std::convert::TryInto; -use std::fmt::Formatter; -use std::sync::Arc; +use alloc::boxed::Box; + +use alloc::string::ToString; +use alloc::sync::Arc; +use alloc::vec::Vec; +use core::convert::TryInto; +use core::fmt::Formatter; use impl_trait_for_tuples::impl_for_tuples; use sigma_util::AsVecI8; @@ -329,8 +333,8 @@ impl From for Value<'static> { } } -impl std::fmt::Display for Value<'_> { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Display for Value<'_> { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { match self { Value::Coll(CollKind::NativeColl(NativeColl::CollByte(i8_bytes))) => { write!(f, "Coll[Byte](")?; @@ -558,13 +562,13 @@ impl<'ctx, T: TryExtractFrom> + StoreWrapped> TryExtractFrom v.iter().cloned().map(T::try_extract_from).collect(), _ => Err(TryExtractFromError(format!( "expected {:?}, found {:?}", - std::any::type_name::(), + core::any::type_name::(), coll ))), }, _ => Err(TryExtractFromError(format!( "expected {:?}, found {:?}", - std::any::type_name::(), + core::any::type_name::(), c ))), } @@ -587,17 +591,17 @@ impl<'ctx, T: TryExtractFrom> + StoreWrapped, const N: usize> .map(T::try_extract_from) .collect::, _>>()?; let len = v.len(); - v.try_into().map_err(|_| TryExtractFromError(format!("can't convert vec of {:?} with length of {:?} to array with length of {:?}", std::any::type_name::(), len, N))) + v.try_into().map_err(|_| TryExtractFromError(format!("can't convert vec of {:?} with length of {:?} to array with length of {:?}", core::any::type_name::(), len, N))) } _ => Err(TryExtractFromError(format!( "expected {:?}, found {:?}", - std::any::type_name::(), + core::any::type_name::(), coll ))), }, _ => Err(TryExtractFromError(format!( "expected {:?}, found {:?}", - std::any::type_name::(), + core::any::type_name::(), c ))), } @@ -611,13 +615,13 @@ impl TryExtractFrom> for Vec { CollKind::NativeColl(NativeColl::CollByte(bs)) => Ok(bs.iter().copied().collect()), _ => Err(TryExtractFromError(format!( "expected {:?}, found {:?}", - std::any::type_name::(), + core::any::type_name::(), v ))), }, _ => Err(TryExtractFromError(format!( "expected {:?}, found {:?}", - std::any::type_name::(), + core::any::type_name::(), v ))), } @@ -643,7 +647,7 @@ impl TryExtractFrom> for BigInt256 { Value::BigInt(bi) => Ok(bi), _ => Err(TryExtractFromError(format!( "expected {:?}, found {:?}", - std::any::type_name::(), + core::any::type_name::(), v ))), } @@ -656,7 +660,7 @@ impl TryExtractFrom> for AvlTreeData { Value::AvlTree(a) => Ok(*a), _ => Err(TryExtractFromError(format!( "expected {:?}, found {:?}", - std::any::type_name::(), + core::any::type_name::(), v ))), } diff --git a/ergotree-ir/src/mir/xor.rs b/ergotree-ir/src/mir/xor.rs index 8258d7919..6560f64aa 100644 --- a/ergotree-ir/src/mir/xor.rs +++ b/ergotree-ir/src/mir/xor.rs @@ -9,7 +9,9 @@ use crate::serialization::SigmaSerializable; use crate::serialization::SigmaSerializeResult; use crate::traversable::impl_traversable_expr; use crate::types::stype::SType; -use std::sync::Arc; +use alloc::boxed::Box; + +use alloc::sync::Arc; /// Byte-wise XOR op on byte arrays #[derive(PartialEq, Eq, Debug, Clone)] diff --git a/ergotree-ir/src/mir/xor_of.rs b/ergotree-ir/src/mir/xor_of.rs index 6665552e5..3b75dc579 100644 --- a/ergotree-ir/src/mir/xor_of.rs +++ b/ergotree-ir/src/mir/xor_of.rs @@ -1,5 +1,7 @@ //! XOR for collection of booleans +use alloc::boxed::Box; + use crate::serialization::op_code::OpCode; use crate::serialization::sigma_byte_reader::SigmaByteRead; use crate::serialization::sigma_byte_writer::SigmaByteWrite; @@ -74,6 +76,7 @@ mod tests { use super::*; use crate::mir::expr::Expr; use crate::serialization::sigma_serialize_roundtrip; + use proptest::prelude::*; proptest! { diff --git a/ergotree-ir/src/pretty_printer.rs b/ergotree-ir/src/pretty_printer.rs index 345ce1b01..6bfbd0c5a 100644 --- a/ergotree-ir/src/pretty_printer.rs +++ b/ergotree-ir/src/pretty_printer.rs @@ -1,8 +1,9 @@ //! Pretty printer for ErgoTree IR -use std::fmt::Write; +use core::fmt::Write; mod print; +use alloc::string::String; pub use print::Print; // TODO: extract to a separate module @@ -17,7 +18,7 @@ pub trait Printer: Write { /// Get current indent fn get_indent(&self) -> usize; /// Print the current indent - fn print_indent(&mut self) -> std::fmt::Result { + fn print_indent(&mut self) -> core::fmt::Result { write!(self, "{:indent$}", "", indent = self.get_indent()) } } @@ -30,7 +31,7 @@ pub struct PosTrackingWriter { } impl Write for PosTrackingWriter { - fn write_str(&mut self, s: &str) -> std::fmt::Result { + fn write_str(&mut self, s: &str) -> core::fmt::Result { let len = s.len(); self.current_pos += len; write!(self.print_buf, "{}", s) diff --git a/ergotree-ir/src/pretty_printer/print.rs b/ergotree-ir/src/pretty_printer/print.rs index 1b30ffe39..3aeba4e57 100644 --- a/ergotree-ir/src/pretty_printer/print.rs +++ b/ergotree-ir/src/pretty_printer/print.rs @@ -1,3 +1,8 @@ +use alloc::borrow::ToOwned; +use alloc::boxed::Box; + +use alloc::string::String; +use alloc::vec::Vec; use thiserror::Error; use crate::mir::and::And; @@ -77,7 +82,7 @@ use super::Printer; #[derive(PartialEq, Eq, Debug, Clone, Error)] pub enum PrintError { #[error("fmt error: {0:?}")] - FmtError(#[from] std::fmt::Error), + FmtError(#[from] core::fmt::Error), } impl Expr { diff --git a/ergotree-ir/src/reference.rs b/ergotree-ir/src/reference.rs index 9dfd0ad68..824e112a6 100644 --- a/ergotree-ir/src/reference.rs +++ b/ergotree-ir/src/reference.rs @@ -1,5 +1,7 @@ //! Reference type used extensively throughout interpreter. a Ref<'ctx, T> can either borrow from Context or be `Arc` -use std::{ops::Deref, sync::Arc}; +use core::ops::Deref; + +use alloc::sync::Arc; #[derive(Clone, Debug, Eq)] /// A wrapper type that provides immutable access to T. Ref can either be [`Ref::Borrowed`], holding a reference to some data in Context, or [`Ref::Arc`] @@ -10,9 +12,9 @@ pub enum Ref<'ctx, T> { Arc(Arc), } -impl std::cmp::PartialEq for Ref<'_, T> +impl core::cmp::PartialEq for Ref<'_, T> where - T: std::cmp::PartialEq, + T: core::cmp::PartialEq, { fn eq(&self, other: &Self) -> bool { self.deref() == other.deref() @@ -50,7 +52,7 @@ impl<'ctx, T> From for Ref<'ctx, T> { } } -impl<'ctx, T> std::ops::Deref for Ref<'ctx, T> { +impl<'ctx, T> core::ops::Deref for Ref<'ctx, T> { type Target = T; fn deref(&self) -> &T { match self { diff --git a/ergotree-ir/src/serialization/bin_op.rs b/ergotree-ir/src/serialization/bin_op.rs index 6f0b040a6..4bbb8f734 100644 --- a/ergotree-ir/src/serialization/bin_op.rs +++ b/ergotree-ir/src/serialization/bin_op.rs @@ -1,3 +1,5 @@ +use alloc::boxed::Box; + use crate::mir::bin_op::BinOp; use crate::mir::bin_op::BinOpKind; use crate::mir::constant::Constant; @@ -72,6 +74,7 @@ mod proptests { use super::*; use crate::mir::expr::arbitrary::ArbExprParams; use crate::serialization::sigma_serialize_roundtrip; + use proptest::prelude::*; proptest! { diff --git a/ergotree-ir/src/serialization/constant.rs b/ergotree-ir/src/serialization/constant.rs index 04eee7572..ae2d9ee01 100644 --- a/ergotree-ir/src/serialization/constant.rs +++ b/ergotree-ir/src/serialization/constant.rs @@ -39,8 +39,9 @@ mod tests { use super::*; use crate::mir::constant::arbitrary::ArbConstantParams; use crate::serialization::sigma_serialize_roundtrip; + + use alloc::sync::Arc; use proptest::prelude::*; - use std::sync::Arc; proptest! { @@ -63,9 +64,6 @@ mod tests { let constant_bytes_str = "0c63028092f401104904000e200137c91882b759ad46a20e39aa4d035ce32525dc76d021ee643e71d09446400f04020e20f6ff8b7210015545d4b3ac5fc60c908092d035a1a16155c029e8d511627c7a2c0e20efc4f603dea6041286a89f5bd516ac96ea5b25da4f08d76c6927e01d61b22adf040204000402040004000402040c044c04010404040404020e20f5918eb4b0283c669bdd8a195640766c19e40a693a6697b775b08e09052523d40e20767caa80b98e496ad8a9f689c4410ae453327f0f95e95084c0ae206350793b7704000402040004020412040005809bee0204000400040004000402040404000402041205d00f040304000402040204420580897a0e20012aec95af24812a01775de090411ba70a648fe859013f896ca2a1a95882ce5f040204040400041004100402041005000402040004100400040004000400040004100410040204100402040205000404040404020402040404040100d80dd601db6501fed602b27201730000d6037301d604b27201730200d605dc640be4c6720204640283020e73037304e4e3000ed606e4c6a70410d607b27206730500d608b2a5730600d609e4c672080410d60ab27209730700d60be3044005d60ce4720bd60d8c720c01d196830301938cb2db63087202730800017203938cb2db6308720473090001b4e4b27205730a00730b730c95ed947207720a937207730dd80cd60eb27201730e00d60fdb6308a7d610e4c6a70511d611720bd612720cd613b47210730fb17210d6148c721202d615b2a5731000d616dc640be4c6720e04640283020e73117312e4e3010ed617b2db63087215731300d6188cb2720f73140002d6197cb4e4b272167315007316731796830401938cb2db6308720e7318000172039683080193c27208c2a792c1720899c1a7731993b2db63087208731a00b2720f731b0093b27209731c00b27206731d0093e4c672080511721093e4c672080664e4c6a7066493720a9591b27210731e009d9cb2e4c672040511731f007cb4e4b27205732000732173227323720d7324edafdb0c0e7213d9011a049593721a720d93b27213721a00721490b27213721a00721491b17213720d91db6903db6503feb272107325009683040193cbc27215b4e4b272167326007327732892c172157329938c721701732a928c72170295927218721972187219d802d60ee4c6a70511d60fe4c6720805119594720e720fd809d610b2a4732b00d611e4c6b2a4732c00050ed612adb4db0c0e7211732d9db17211732ed90112047cb472119c7212732f9c9a721273307331d613b072127332d90113599a8c7213018c721302d614e4c6a70664d615e4c67210050ed616dc640a7214027215e4e3010ed617e67216d618e4e3020e96830801927cb4e4dc640ae4c672040464028cb2db6308721073330001e4e3030e73347335721393c27208c2a792c17208c1a793b2db63087208733600b2db6308a7733700937209720693b2720f733800b2720e733900957217d802d619e47216d61aadb4db0c0e7219733a9db17219733bd9011a047cb472199c721a733c9c9a721a733d733e9683020193b2720f733f009a99b2720e734000b0721a7341d9011b599a8c721b018c721b02721393b4720f7342b1720faddc0c1db4720e7343b1720e01addc0c1d721a017212d9011b59998c721b028c721b01d9011b599a8c721b018c721b029683020193b2720f7344009ab2720e734500721393b4720f7346b1720faddc0c1db4720e7347b1720e017212d90119599a8c7219018c72190293db6401e4c672080664db6401957217e4dc640d72140283013c0e0e8602721572117218e4dc640c72140283013c0e0e86027215721172187348efc13b02010b4858ce0425ed4748d0d3a59f2dbf874166a2caaf734655ac5e3f88a68cdd01012aec95af24812a01775de090411ba70a648fe859013f896ca2a1a95882ce5f904e0310020001110400000000644ec61f485b98eb87153f7c57db4f5ecd75556fddbc403b41acf8441fde8e1609000720003b6fd893695e655e17804641c3ed2074731ff34281dafb0e5b50688d0627717300c0843d10230400040204000402040604040500050004000e200137c91882b759ad46a20e39aa4d035ce32525dc76d021ee643e71d09446400f04000e20010b4858ce0425ed4748d0d3a59f2dbf874166a2caaf734655ac5e3f88a68cdd0400040204080400040204040502040604080400040004020402040004020e20c7c537e6c635930ecb4ace95a54926b3ab77698d9f4922f0b1c58ea87156483b0400040204420404040205000502d80ed601db6501fed602b27201730000d603b27201730100d604e4c672030410d605e4c6a70411d606b27205730200d607b27205730300d608b27205730400d609b27205730500d60a9172097306d60be4c6a7050c63d60cb1720bd60db1a5d60ed9010e0c63b0dc0c0f720e01d9011063db630872107307d90110414d0e9a8c7210018c8c72100202d196830701938cb2db6308720273080001730996830301938cb2db63087203730a0001730b937eb27204730c00057206937eb27204730d0005720792db6903db6503fe720895720ad804d60fe4c6a7050c63d610b2a5b1720f00d611e4c672100411d612b27205730e009683090192c17210c1a793db63087210db6308a793b27211730f00720693b27211731000720793b27211731100997209731293b272117313009a7208721293b27211731400721293e4c67210050c63720f93c27210c2a7efaea5d9010f63aedb6308720fd901114d0e938c7211018cb2db6308a773150001afdc0c1d720b01b4a5731699720c7317d9010f3c636393c48c720f01c48c720f0293720d9a9a720c95720a731873199593cbc2b2a599720d731a00b4e4b2dc640be4c6720204640283010e731be4e3000e731c00731d731e731f732093da720e01a49ada720e01a595720a73217322efc13b0100b44a84993674c57c4fc23c6c1bb221470463e4e711b2260ffd8ed01f1aab420102110500020000000c6301c0843d0008cd02e4cb952261186ec0fd2dc4c2baa8dbfd9c8f6012c5efa9f702f9450a58fe221eefc13b01012aec95af24812a01775de090411ba70a648fe859013f896ca2a1a95882ce5fc0843d00c9ffc2d2fd948bd3217a245eab2c9d829abd0cd3b41a8069006ff2bb38b06e2d00cb93d676f11faa9b7204a875fdb34d55619fc0e933ae956af8c7d8ce4c9e20ca00"; let constant_bytes = base16::decode(constant_bytes_str).unwrap(); let c_res = Constant::sigma_parse_bytes(&constant_bytes); - if let Err(e) = &c_res { - println!("Failed to parse constant: {}", e); - } assert!(c_res.is_ok()); assert_eq!(c_res.unwrap().tpe, SType::SColl(Arc::new(SType::SBox))); } diff --git a/ergotree-ir/src/serialization/constant_placeholder.rs b/ergotree-ir/src/serialization/constant_placeholder.rs index 4ad229747..b8dbf57c2 100644 --- a/ergotree-ir/src/serialization/constant_placeholder.rs +++ b/ergotree-ir/src/serialization/constant_placeholder.rs @@ -36,8 +36,10 @@ mod tests { constant_store::ConstantStore, sigma_byte_reader::SigmaByteReader, sigma_byte_writer::SigmaByteWriter, }; + + use alloc::vec::Vec; + use core2::io::Cursor; use proptest::prelude::*; - use std::io::Cursor; proptest! { diff --git a/ergotree-ir/src/serialization/constant_store.rs b/ergotree-ir/src/serialization/constant_store.rs index 78f374da3..d33f69485 100644 --- a/ergotree-ir/src/serialization/constant_store.rs +++ b/ergotree-ir/src/serialization/constant_store.rs @@ -1,5 +1,8 @@ //! Constant store for Sigma byte reader +use alloc::vec; +use alloc::vec::Vec; + use crate::mir::constant::{Constant, ConstantPlaceholder}; /// Storage for constants used in ErgoTree constant segregation diff --git a/ergotree-ir/src/serialization/data.rs b/ergotree-ir/src/serialization/data.rs index 49a1ef5e1..cf2a56e43 100644 --- a/ergotree-ir/src/serialization/data.rs +++ b/ergotree-ir/src/serialization/data.rs @@ -1,3 +1,8 @@ +use alloc::boxed::Box; + +use alloc::string::ToString; +use alloc::vec; +use alloc::vec::Vec; use sigma_util::AsVecU8; use crate::bigint256::BigInt256; @@ -19,8 +24,8 @@ use crate::types::stype::SType; use ergo_chain_types::EcPoint; use super::sigma_byte_writer::SigmaByteWrite; -use std::convert::TryInto; -use std::sync::Arc; +use alloc::sync::Arc; +use core::convert::TryInto; /// Used to serialize and parse `Literal` and `Value`. pub struct DataSerializer {} diff --git a/ergotree-ir/src/serialization/expr.rs b/ergotree-ir/src/serialization/expr.rs index 4abb5eef8..f41a2043d 100644 --- a/ergotree-ir/src/serialization/expr.rs +++ b/ergotree-ir/src/serialization/expr.rs @@ -1,3 +1,5 @@ + + use super::bin_op::bin_op_sigma_parse; use super::bin_op::bin_op_sigma_serialize; use super::{op_code::OpCode, sigma_byte_writer::SigmaByteWrite}; @@ -503,7 +505,6 @@ mod tests { let p2s_addr_str = "HfdbQC2Zwr5vfAUxdmjmX6b3TxQbq5w764pwsz9LLKyZVhv7SpifLB22PieCgvzSaFLomv8HNr9dxxQSSYaQg6ZyFL37nPfuVib3hVL8h42jajp754NXGqv1s4eKcbPsKkBMeTmYVSSGrpnZHzjqvcT4oN8rqKGUtLVXHs4QKyBwwNQKS5KNC8DLkdvHUQRNv5r8pCJ6ehTi31h1rfLVTsaMhAeDcYCs1uS7YMXk3msfH36krAskv8TgApoFJ1DarszwiacTuE1o4N6o4PJJifAgJ1WH4XuGRieYE1k3fo631benRDQw9nQ49p4oqAda5aXTNmabAsfCgAR8jbmUzzi3UCyYJgRUtXp7ijaGfr6o3hXd5VHDZe4gM6Vw4Ly3s881WZX2WWNedrXNqKKMVXKk55jbgn3ZmFpZiLtvPHSBCG7ULyARrTz2rAUC16StdYBqPuhHpRKEx3QYeFTYJGcMbsMGompAkCxG37X7ZVs7m7xCpPuP3AqxWtWdxkTzw5FCHALsu6ZD334n8mFgn9kiif4tbShpBo1AJu6dP22XvPU3S93q5LuNaXx6d7u5VFrpQKSN6WnhkU4LUfh3t8YU1ZBATrQDGRkaji59pqoNDuwVSfn7g1UhcMWdMnwzrCNNq1jsX2KrkX7o81aS7LEmz6xAySdyvubGh51oXNd2cmgbJ9at2Tp3hNi9FwWG5iEk882AZ7gby6QktknAwyaw9CL5qdodeh4t659H42SoqK2ATtfrZgjU5b5pYAzNp9EjFHCKkYxTo7t5G1vHHZUXjTbkzc22ggJdH3BvZYEcdQtUCLbEFJSCiMp2RjxEmyh"; let encoder = AddressEncoder::new(NetworkPrefix::Mainnet); let addr = encoder.parse_address_from_str(p2s_addr_str).unwrap(); - let script = addr.script().unwrap().proposition().unwrap(); - dbg!(&script); + addr.script().unwrap().proposition().unwrap(); } } diff --git a/ergotree-ir/src/serialization/method_call.rs b/ergotree-ir/src/serialization/method_call.rs index b1fc31282..10d8f5519 100644 --- a/ergotree-ir/src/serialization/method_call.rs +++ b/ergotree-ir/src/serialization/method_call.rs @@ -1,4 +1,6 @@ -use std::collections::HashMap; +use hashbrown::HashMap; + +use alloc::vec::Vec; use crate::mir::expr::Expr; use crate::mir::method_call::MethodCall; @@ -40,7 +42,7 @@ impl SigmaSerializable for MethodCall { .explicit_type_args .iter() .cloned() - .zip(std::iter::from_fn(|| Some(SType::sigma_parse(r)))) + .zip(core::iter::from_fn(|| Some(SType::sigma_parse(r)))) .map(|(tpe, res)| -> Result<(STypeVar, SType), SigmaParsingError> { Ok((tpe, res?)) }) .collect::, _>>()?; Ok(MethodCall::with_type_args( @@ -56,6 +58,8 @@ impl SigmaSerializable for MethodCall { #[cfg(feature = "arbitrary")] #[allow(clippy::unwrap_used)] mod tests { + use alloc::vec; + use crate::mir::expr::Expr; use crate::mir::method_call::MethodCall; use crate::serialization::sigma_serialize_roundtrip; diff --git a/ergotree-ir/src/serialization/property_call.rs b/ergotree-ir/src/serialization/property_call.rs index 1a33d86c3..9f1f3429d 100644 --- a/ergotree-ir/src/serialization/property_call.rs +++ b/ergotree-ir/src/serialization/property_call.rs @@ -1,3 +1,5 @@ +use alloc::vec::Vec; + use crate::mir::expr::Expr; use crate::mir::property_call::PropertyCall; use crate::types::smethod::MethodId; diff --git a/ergotree-ir/src/serialization/serializable.rs b/ergotree-ir/src/serialization/serializable.rs index e51dec4ac..4b50d9566 100644 --- a/ergotree-ir/src/serialization/serializable.rs +++ b/ergotree-ir/src/serialization/serializable.rs @@ -11,12 +11,16 @@ use super::{ sigma_byte_writer::{SigmaByteWrite, SigmaByteWriter}, }; use crate::types::smethod::MethodId; +use alloc::boxed::Box; + +use alloc::string::{String, ToString}; +use alloc::vec::Vec; use bounded_vec::BoundedVec; use bounded_vec::BoundedVecOutOfBounds; +use core::convert::TryInto; +use core2::io; use io::Cursor; use sigma_ser::{vlq_encode, ScorexParsingError, ScorexSerializationError}; -use std::convert::TryInto; -use std::io; use thiserror::Error; /// Ways serialization might fail @@ -132,7 +136,7 @@ pub type SigmaSerializeResult = Result<(), SigmaSerializationError>; pub trait SigmaSerializable: Sized { /// Write `self` to the given `writer`. /// This function has a `sigma_` prefix to alert the reader that the - /// serialization in use is consensus-critical serialization + /// serialization in use is consensus-critical serialization // fn sigma_serialize(&self, w: &mut W) -> SigmaSerializeResult; fn sigma_serialize(&self, w: &mut W) -> SigmaSerializeResult; diff --git a/ergotree-ir/src/serialization/sigma_byte_reader.rs b/ergotree-ir/src/serialization/sigma_byte_reader.rs index cfa63d03b..1e224ce68 100644 --- a/ergotree-ir/src/serialization/sigma_byte_reader.rs +++ b/ergotree-ir/src/serialization/sigma_byte_reader.rs @@ -1,10 +1,10 @@ //! Sigma byte stream writer use super::constant_store::ConstantStore; use super::val_def_type_store::ValDefTypeStore; +use core2::io::Cursor; +use core2::io::Read; +use core2::io::Seek; use sigma_ser::vlq_encode::ReadSigmaVlqExt; -use std::io::Cursor; -use std::io::Read; -use std::io::Seek; /// Implementation of SigmaByteRead pub struct SigmaByteReader { @@ -73,24 +73,38 @@ pub trait SigmaByteRead: ReadSigmaVlqExt { /// Set that deserialization node was read fn set_deserialize(&mut self, has_deserialize: bool); + + /// Get position of reader in buffer. This is functionally equivalent to [`std::io::Seek::stream_position`] but redefined here so it can be used in no_std contexts + fn position(&mut self) -> core2::io::Result { + #[cfg(feature = "std")] + { + ::stream_position(self) + } + #[cfg(not(feature = "std"))] + { + self.seek(core2::io::SeekFrom::Current(0)) + } + } } impl Read for SigmaByteReader { - fn read(&mut self, buf: &mut [u8]) -> std::io::Result { + fn read(&mut self, buf: &mut [u8]) -> core2::io::Result { self.inner.read(buf) } } impl Seek for SigmaByteReader { - fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result { + fn seek(&mut self, pos: core2::io::SeekFrom) -> core2::io::Result { self.inner.seek(pos) } - fn rewind(&mut self) -> std::io::Result<()> { + #[cfg(feature = "std")] + fn rewind(&mut self) -> core2::io::Result<()> { self.inner.rewind() } - fn stream_position(&mut self) -> std::io::Result { + #[cfg(feature = "std")] + fn stream_position(&mut self) -> core2::io::Result { self.inner.stream_position() } } diff --git a/ergotree-ir/src/serialization/sigma_byte_writer.rs b/ergotree-ir/src/serialization/sigma_byte_writer.rs index fb591322d..36feba4ce 100644 --- a/ergotree-ir/src/serialization/sigma_byte_writer.rs +++ b/ergotree-ir/src/serialization/sigma_byte_writer.rs @@ -1,7 +1,7 @@ //! Sigma byte stream writer use super::constant_store::ConstantStore; +use core2::io::Write; use sigma_ser::vlq_encode::WriteSigmaVlqExt; -use std::io::Write; /// Implementation for SigmaByteWrite pub struct SigmaByteWriter<'a, W> { @@ -27,11 +27,11 @@ pub trait SigmaByteWrite: WriteSigmaVlqExt { } impl<'a, W: Write> Write for SigmaByteWriter<'a, W> { - fn write(&mut self, buf: &[u8]) -> std::io::Result { + fn write(&mut self, buf: &[u8]) -> core2::io::Result { self.inner.write(buf) } - fn flush(&mut self) -> std::io::Result<()> { + fn flush(&mut self) -> core2::io::Result<()> { self.inner.flush() } } diff --git a/ergotree-ir/src/serialization/sigmaboolean.rs b/ergotree-ir/src/serialization/sigmaboolean.rs index f8f8702d5..cf20ba6a2 100644 --- a/ergotree-ir/src/serialization/sigmaboolean.rs +++ b/ergotree-ir/src/serialization/sigmaboolean.rs @@ -7,6 +7,7 @@ use crate::serialization::{ use crate::sigma_protocol::sigma_boolean::{ ProveDhTuple, ProveDlog, SigmaBoolean, SigmaConjecture, SigmaProofOfKnowledgeTree, }; + use ergo_chain_types::EcPoint; use crate::sigma_protocol::sigma_boolean::cand::Cand; diff --git a/ergotree-ir/src/serialization/types.rs b/ergotree-ir/src/serialization/types.rs index 32a008191..267604577 100644 --- a/ergotree-ir/src/serialization/types.rs +++ b/ergotree-ir/src/serialization/types.rs @@ -8,9 +8,11 @@ use crate::serialization::{ use crate::types::stuple; use crate::types::stype::SType; use crate::types::stype_param; +use alloc::string::ToString; +use alloc::vec::Vec; +use core::convert::TryInto; use num_derive::FromPrimitive; use num_traits::FromPrimitive; -use std::convert::TryInto; #[allow(non_camel_case_types)] #[allow(clippy::upper_case_acronyms)] // to differentiate from similarly named SType enum variants @@ -561,6 +563,7 @@ impl SigmaSerializable for SType { mod tests { use super::*; use crate::serialization::sigma_serialize_roundtrip; + use proptest::prelude::*; proptest! { diff --git a/ergotree-ir/src/serialization/val_def_type_store.rs b/ergotree-ir/src/serialization/val_def_type_store.rs index 02e2706d9..ec6bc33f6 100644 --- a/ergotree-ir/src/serialization/val_def_type_store.rs +++ b/ergotree-ir/src/serialization/val_def_type_store.rs @@ -1,4 +1,4 @@ -use std::collections::HashMap; +use hashbrown::HashMap; use crate::mir::val_def::ValId; use crate::types::stype::SType; diff --git a/ergotree-ir/src/sigma_protocol/sigma_boolean.rs b/ergotree-ir/src/sigma_protocol/sigma_boolean.rs index 2f67f3fd4..4e545e245 100644 --- a/ergotree-ir/src/sigma_protocol/sigma_boolean.rs +++ b/ergotree-ir/src/sigma_protocol/sigma_boolean.rs @@ -10,9 +10,12 @@ use crate::mir::constant::Constant; use crate::mir::expr::Expr; use crate::serialization::op_code::OpCode; use crate::serialization::SigmaSerializable; +use alloc::boxed::Box; +use alloc::vec::Vec; +use core::convert::TryFrom; +use core::convert::TryInto; +use core::fmt::Formatter; use ergo_chain_types::EcPoint; -use std::convert::TryFrom; -use std::fmt::Formatter; extern crate derive_more; use bounded_vec::BoundedVec; @@ -53,8 +56,8 @@ impl From for ProveDlog { } } -impl std::fmt::Display for ProveDlog { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Display for ProveDlog { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { write!(f, "proveDlog({})", self.h) } } @@ -92,8 +95,8 @@ impl ProveDhTuple { } } -impl std::fmt::Display for ProveDhTuple { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Display for ProveDhTuple { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { write!( f, "ProveDhTuple(g: {}, h: {}, u: {}, v: {})", @@ -141,8 +144,8 @@ impl HasOpCode for SigmaConjecture { } } -impl std::fmt::Display for SigmaConjecture { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Display for SigmaConjecture { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { match self { SigmaConjecture::Cand(c) => write!(f, "{}", c), SigmaConjecture::Cor(c) => write!(f, "{}", c), @@ -272,8 +275,8 @@ impl From for SigmaBoolean { } } -impl std::fmt::Display for SigmaBoolean { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Display for SigmaBoolean { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { match self { SigmaBoolean::TrivialProp(b) => write!(f, "sigmaProp({})", b), SigmaBoolean::ProofOfKnowledge(kt) => write!(f, "{}", kt), @@ -421,6 +424,7 @@ mod arbitrary { mod tests { use super::*; use crate::serialization::sigma_serialize_roundtrip; + use proptest::prelude::*; proptest! { diff --git a/ergotree-ir/src/sigma_protocol/sigma_boolean/cand.rs b/ergotree-ir/src/sigma_protocol/sigma_boolean/cand.rs index 957f46354..22f71249d 100644 --- a/ergotree-ir/src/sigma_protocol/sigma_boolean/cand.rs +++ b/ergotree-ir/src/sigma_protocol/sigma_boolean/cand.rs @@ -1,5 +1,7 @@ //! AND conjunction for sigma proposition -use std::convert::TryInto; +use core::convert::TryInto; + +use alloc::vec::Vec; use super::SigmaBoolean; use super::SigmaConjectureItems; @@ -48,8 +50,8 @@ impl Cand { } } -impl std::fmt::Display for Cand { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Display for Cand { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.write_str("(")?; for (i, item) in self.items.iter().enumerate() { if i > 0 { @@ -107,9 +109,11 @@ mod tests { use super::*; use crate::serialization::sigma_serialize_roundtrip; use crate::sigma_protocol::sigma_boolean::ProveDlog; + + use alloc::vec; + use core::convert::TryInto; use proptest::prelude::*; use sigma_test_util::force_any_val; - use std::convert::TryInto; #[test] fn trivial_true() { diff --git a/ergotree-ir/src/sigma_protocol/sigma_boolean/cor.rs b/ergotree-ir/src/sigma_protocol/sigma_boolean/cor.rs index acf0c3f9e..ef206e7b1 100644 --- a/ergotree-ir/src/sigma_protocol/sigma_boolean/cor.rs +++ b/ergotree-ir/src/sigma_protocol/sigma_boolean/cor.rs @@ -1,5 +1,7 @@ //! OR conjunction for sigma proposition -use std::convert::TryInto; +use core::convert::TryInto; + +use alloc::vec::Vec; use super::SigmaBoolean; use super::SigmaConjectureItems; @@ -49,8 +51,8 @@ impl Cor { } } -impl std::fmt::Display for Cor { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Display for Cor { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.write_str("(")?; for (i, item) in self.items.iter().enumerate() { if i > 0 { @@ -109,9 +111,11 @@ mod tests { use super::*; use crate::serialization::sigma_serialize_roundtrip; use crate::sigma_protocol::sigma_boolean::ProveDlog; + + use alloc::vec; + use core::convert::TryInto; use proptest::prelude::*; use sigma_test_util::force_any_val; - use std::convert::TryInto; #[test] fn trivial_true() { diff --git a/ergotree-ir/src/sigma_protocol/sigma_boolean/cthreshold.rs b/ergotree-ir/src/sigma_protocol/sigma_boolean/cthreshold.rs index 125661d68..868cb79cb 100644 --- a/ergotree-ir/src/sigma_protocol/sigma_boolean/cthreshold.rs +++ b/ergotree-ir/src/sigma_protocol/sigma_boolean/cthreshold.rs @@ -1,6 +1,9 @@ //! THRESHOLD conjunction for sigma proposition -use std::convert::TryInto; +use core::convert::TryInto; + +use alloc::string::ToString; +use alloc::vec::Vec; use super::cand::Cand; use super::cor::Cor; @@ -81,8 +84,8 @@ impl Cthreshold { } } -impl std::fmt::Display for Cthreshold { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Display for Cthreshold { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.write_str("atLeast(")?; f.write_str(self.k.to_string().as_str())?; f.write_str(", (")?; diff --git a/ergotree-ir/src/source_span.rs b/ergotree-ir/src/source_span.rs index b744d8101..fd2a11161 100644 --- a/ergotree-ir/src/source_span.rs +++ b/ergotree-ir/src/source_span.rs @@ -1,5 +1,7 @@ //! Source position for an IR node in the source code +use alloc::boxed::Box; + use crate::mir::and::And; use crate::mir::bin_op::BinOp; use crate::mir::block::BlockValue; @@ -58,6 +60,7 @@ impl From<(usize, usize)> for SourceSpan { } } +#[cfg(feature = "std")] impl From for miette::SourceSpan { fn from(value: SourceSpan) -> Self { miette::SourceSpan::new(value.offset.into(), value.length.into()) diff --git a/ergotree-ir/src/traversable.rs b/ergotree-ir/src/traversable.rs index 88d7006b0..87d69e0f3 100644 --- a/ergotree-ir/src/traversable.rs +++ b/ergotree-ir/src/traversable.rs @@ -1,6 +1,7 @@ //! Traversable trait use crate::mir::{expr::Expr, unary_op::OneArgOp}; +use alloc::boxed::Box; /// Trait for types that have child nodes. /// In ergotree-ir this is used for traversing trees of [`Expr`] and doing rewriting operations such as replacing [ConstantPlaceholder](crate::mir::constant::ConstantPlaceholder)s with [`Constant`](crate::mir::constant::Constant)s @@ -17,10 +18,10 @@ impl Traversable for T { type Item = Expr; fn children<'a>(&'a self) -> Box + 'a> { - Box::new(std::iter::once(self.input())) + Box::new(core::iter::once(self.input())) } fn children_mut<'a>(&'a mut self) -> Box + 'a> { - Box::new(std::iter::once(self.input_mut())) + Box::new(core::iter::once(self.input_mut())) } } @@ -32,7 +33,7 @@ macro_rules! iter_from { $self.$x.iter().chain(crate::traversable::iter_from!($self, $($y)*)) }; ($self:ident, boxed $x:tt, $($y:tt)*) => { - std::iter::once(&*$self.$x).chain(crate::traversable::iter_from!($self, $($y)*)) + core::iter::once(&*$self.$x).chain(crate::traversable::iter_from!($self, $($y)*)) }; ($self:ident, opt $x:tt) => { $self.$x.as_deref().into_iter() @@ -41,10 +42,10 @@ macro_rules! iter_from { $self.$x.iter() }; ($self:ident, boxed $x:tt) => { - std::iter::once(&*$self.$x) + core::iter::once(&*$self.$x) }; ($self:ident) => { - std::iter::empty() + core::iter::empty() } } @@ -56,7 +57,7 @@ macro_rules! iter_from_mut { $self.$x.iter_mut().chain(crate::traversable::iter_from_mut!($self, $($y)*)) }; ($self:ident, boxed $x:tt, $($y:tt)*) => { - std::iter::once(&mut *$self.$x).chain(crate::traversable::iter_from_mut!($self, $($y)*)) + core::iter::once(&mut *$self.$x).chain(crate::traversable::iter_from_mut!($self, $($y)*)) }; ($self:ident, opt $x:tt) => { $self.$x.as_deref_mut().into_iter() @@ -65,10 +66,10 @@ macro_rules! iter_from_mut { $self.$x.iter_mut() }; ($self:ident, boxed $x:tt) => { - std::iter::once(&mut *$self.$x) + core::iter::once(&mut *$self.$x) }; ($self:ident) => { - std::iter::empty() + core::iter::empty() } } @@ -77,11 +78,11 @@ macro_rules! impl_traversable_expr { ($op:ident $(, $($args:tt)+ )? ) => { impl crate::traversable::Traversable for $op { type Item = Expr; - fn children(&self) -> Box + '_> { - Box::new(crate::traversable::iter_from!(self $(, $($args)*)?)) + fn children(&self) -> alloc::boxed::Box + '_> { + alloc::boxed::Box::new(crate::traversable::iter_from!(self $(, $($args)*)?)) } - fn children_mut(&mut self) -> Box + '_> { - Box::new(crate::traversable::iter_from_mut!(self $(, $($args)*)?)) + fn children_mut(&mut self) -> alloc::boxed::Box + '_> { + alloc::boxed::Box::new(crate::traversable::iter_from_mut!(self $(, $($args)*)?)) } } }; @@ -93,6 +94,8 @@ pub(crate) use iter_from_mut; #[cfg(test)] mod test { + use alloc::{boxed::Box, vec::Vec}; + use crate::mir::{constant::Constant, expr::Expr}; use super::Traversable; diff --git a/ergotree-ir/src/type_check.rs b/ergotree-ir/src/type_check.rs index 447db8593..34260c62e 100644 --- a/ergotree-ir/src/type_check.rs +++ b/ergotree-ir/src/type_check.rs @@ -1,5 +1,8 @@ //! Type checking + +use alloc::string::String; + use crate::mir::expr::Expr; use crate::source_span::Spanned; diff --git a/ergotree-ir/src/types/savltree.rs b/ergotree-ir/src/types/savltree.rs index 216779748..bd5cb911a 100644 --- a/ergotree-ir/src/types/savltree.rs +++ b/ergotree-ir/src/types/savltree.rs @@ -1,4 +1,6 @@ -use std::sync::Arc; +use alloc::sync::Arc; +use alloc::vec; +use alloc::vec::Vec; use crate::serialization::types::TypeCode; diff --git a/ergotree-ir/src/types/sbox.rs b/ergotree-ir/src/types/sbox.rs index b898604b0..c99b0514d 100644 --- a/ergotree-ir/src/types/sbox.rs +++ b/ergotree-ir/src/types/sbox.rs @@ -1,5 +1,8 @@ use crate::serialization::types::TypeCode; -use std::sync::Arc; +use alloc::boxed::Box; +use alloc::sync::Arc; +use alloc::vec; +use alloc::vec::Vec; use super::sfunc::SFunc; use super::smethod::MethodId; @@ -103,7 +106,7 @@ mod tests { #[test] fn test_getreg_serialization_roundtrip() { - let type_args = std::iter::once((STypeVar::t(), SType::SInt)).collect(); + let type_args = core::iter::once((STypeVar::t(), SType::SInt)).collect(); let mc = MethodCall::with_type_args( GlobalVars::SelfBox.into(), GET_REG_METHOD.clone().with_concrete_types(&type_args), diff --git a/ergotree-ir/src/types/scoll.rs b/ergotree-ir/src/types/scoll.rs index 11400aea6..d0fad2023 100644 --- a/ergotree-ir/src/types/scoll.rs +++ b/ergotree-ir/src/types/scoll.rs @@ -1,7 +1,9 @@ use crate::serialization::types::TypeCode; use crate::types::stuple::STuple; use crate::types::stype_companion::STypeCompanion; -use std::sync::Arc; +use alloc::sync::Arc; +use alloc::vec; +use alloc::vec::Vec; use super::sfunc::SFunc; use super::smethod::MethodId; diff --git a/ergotree-ir/src/types/scontext.rs b/ergotree-ir/src/types/scontext.rs index b6d6638ed..f46f661ff 100644 --- a/ergotree-ir/src/types/scontext.rs +++ b/ergotree-ir/src/types/scontext.rs @@ -8,6 +8,8 @@ use super::smethod::SMethod; use super::smethod::SMethodDesc; use super::stype::SType; use super::stype::SType::{SAvlTree, SBox, SByte, SColl, SHeader, SInt, SPreHeader}; +use alloc::vec; +use alloc::vec::Vec; use lazy_static::lazy_static; /// SContext type code diff --git a/ergotree-ir/src/types/sfunc.rs b/ergotree-ir/src/types/sfunc.rs index b00e0e5e4..6570f74b2 100644 --- a/ergotree-ir/src/types/sfunc.rs +++ b/ergotree-ir/src/types/sfunc.rs @@ -1,4 +1,8 @@ -use std::collections::HashMap; +use hashbrown::HashMap; + +use alloc::boxed::Box; +use alloc::vec; +use alloc::vec::Vec; use super::stype::SType; use super::stype_param::STypeParam; @@ -15,8 +19,8 @@ pub struct SFunc { pub tpe_params: Vec, } -impl std::fmt::Display for SFunc { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Display for SFunc { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!(f, "(")?; for (i, item) in self.t_dom.iter().enumerate() { if i > 0 { diff --git a/ergotree-ir/src/types/sglobal.rs b/ergotree-ir/src/types/sglobal.rs index 9e90c2e75..53442425d 100644 --- a/ergotree-ir/src/types/sglobal.rs +++ b/ergotree-ir/src/types/sglobal.rs @@ -6,6 +6,8 @@ use super::smethod::SMethodDesc; use super::stype::SType; use crate::types::smethod::SMethod; use crate::types::stype_companion::STypeCompanion; +use alloc::vec; +use alloc::vec::Vec; use lazy_static::lazy_static; /// SGlobal type code diff --git a/ergotree-ir/src/types/sgroup_elem.rs b/ergotree-ir/src/types/sgroup_elem.rs index f389f49ee..1623c1630 100644 --- a/ergotree-ir/src/types/sgroup_elem.rs +++ b/ergotree-ir/src/types/sgroup_elem.rs @@ -1,6 +1,8 @@ use crate::serialization::types::TypeCode; use crate::types::stype_companion::STypeCompanion; -use std::sync::Arc; +use alloc::sync::Arc; +use alloc::vec; +use alloc::vec::Vec; use super::sfunc::SFunc; use super::smethod::MethodId; diff --git a/ergotree-ir/src/types/sheader.rs b/ergotree-ir/src/types/sheader.rs index adf083a2b..22784ad3b 100644 --- a/ergotree-ir/src/types/sheader.rs +++ b/ergotree-ir/src/types/sheader.rs @@ -1,5 +1,7 @@ #![allow(missing_docs)] +use alloc::vec; +use alloc::vec::Vec; use lazy_static::lazy_static; use crate::serialization::types::TypeCode; diff --git a/ergotree-ir/src/types/smethod.rs b/ergotree-ir/src/types/smethod.rs index f369904a3..d0e59545b 100644 --- a/ergotree-ir/src/types/smethod.rs +++ b/ergotree-ir/src/types/smethod.rs @@ -1,9 +1,12 @@ +use alloc::vec; +use alloc::vec::Vec; + use crate::serialization::sigma_byte_reader::SigmaByteRead; use crate::serialization::sigma_byte_writer::SigmaByteWrite; use crate::serialization::types::TypeCode; use crate::serialization::SigmaParsingError; -use std::collections::HashMap; -use std::convert::TryFrom; +use core::convert::TryFrom; +use hashbrown::HashMap; use super::sfunc::SFunc; use super::stype::SType; @@ -18,11 +21,11 @@ use crate::serialization::SigmaParsingError::UnknownMethodId; pub struct MethodId(pub u8); impl MethodId { - pub(crate) fn sigma_serialize(&self, w: &mut W) -> std::io::Result<()> { + pub(crate) fn sigma_serialize(&self, w: &mut W) -> core2::io::Result<()> { w.put_u8(self.0) } - pub(crate) fn sigma_parse(r: &mut R) -> std::io::Result { + pub(crate) fn sigma_parse(r: &mut R) -> core2::io::Result { Ok(Self(r.get_u8()?)) } } diff --git a/ergotree-ir/src/types/soption.rs b/ergotree-ir/src/types/soption.rs index 2a3dccb08..ec50c4f15 100644 --- a/ergotree-ir/src/types/soption.rs +++ b/ergotree-ir/src/types/soption.rs @@ -7,6 +7,8 @@ use super::stype::SType; use super::stype_companion::STypeCompanion; use super::stype_param::STypeVar; use crate::types::smethod::MethodId; +use alloc::vec; +use alloc::vec::Vec; use lazy_static::lazy_static; /// SOption type code diff --git a/ergotree-ir/src/types/spreheader.rs b/ergotree-ir/src/types/spreheader.rs index 23ebed87e..5eebac8af 100644 --- a/ergotree-ir/src/types/spreheader.rs +++ b/ergotree-ir/src/types/spreheader.rs @@ -6,6 +6,8 @@ use super::smethod::{MethodId, SMethod, SMethodDesc}; use super::stype::SType; use super::stype_companion::STypeCompanion; use crate::types::stype::SType::{SByte, SColl}; +use alloc::vec; +use alloc::vec::Vec; use lazy_static::lazy_static; /// SPreHeader type code diff --git a/ergotree-ir/src/types/stuple.rs b/ergotree-ir/src/types/stuple.rs index 71596f3d7..00c555a9b 100644 --- a/ergotree-ir/src/types/stuple.rs +++ b/ergotree-ir/src/types/stuple.rs @@ -1,7 +1,9 @@ -use std::collections::HashMap; -use std::convert::TryFrom; -use std::convert::TryInto; +use core::convert::TryFrom; +use core::convert::TryInto; +use hashbrown::HashMap; +use alloc::vec; +use alloc::vec::Vec; use bounded_vec::BoundedVec; use bounded_vec::BoundedVecOutOfBounds; @@ -28,14 +30,14 @@ pub struct STuple { pub items: TupleItems, } -impl std::fmt::Debug for STuple { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Debug for STuple { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { self.items.clone().to_vec().fmt(f) } } -impl std::fmt::Display for STuple { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Display for STuple { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!(f, "(")?; for (i, item) in self.items.iter().enumerate() { if i > 0 { diff --git a/ergotree-ir/src/types/stype.rs b/ergotree-ir/src/types/stype.rs index 41efd553d..f73ffc0d2 100644 --- a/ergotree-ir/src/types/stype.rs +++ b/ergotree-ir/src/types/stype.rs @@ -1,9 +1,10 @@ //! SType hierarchy -use std::collections::HashMap; -use std::convert::TryInto; -use std::fmt::Debug; -use std::sync::Arc; +use alloc::sync::Arc; +use alloc::vec::Vec; +use core::convert::TryInto; +use core::fmt::Debug; +use hashbrown::HashMap; use impl_trait_for_tuples::impl_for_tuples; @@ -128,8 +129,8 @@ impl From for SType { } } -impl std::fmt::Display for SType { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Display for SType { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self { SType::STypeVar(t) => write!(f, "{}", t.as_string()), SType::SAny => write!(f, "Any"), @@ -277,6 +278,7 @@ impl LiftIntoSType for Tuple { #[allow(clippy::unwrap_used)] pub(crate) mod tests { use super::*; + use alloc::vec; use proptest::prelude::*; pub(crate) fn primitive_type() -> BoxedStrategy { diff --git a/ergotree-ir/src/types/stype_companion.rs b/ergotree-ir/src/types/stype_companion.rs index 07f500817..82901e57f 100644 --- a/ergotree-ir/src/types/stype_companion.rs +++ b/ergotree-ir/src/types/stype_companion.rs @@ -1,5 +1,5 @@ -use std::convert::TryFrom; -use std::fmt::Debug; +use core::convert::TryFrom; +use core::fmt::Debug; use crate::serialization::types::TypeCode; use crate::serialization::SigmaParsingError; @@ -16,6 +16,8 @@ use super::smethod::SMethod; use super::smethod::SMethodDesc; use super::soption; use super::spreheader; + +use alloc::vec::Vec; use strum::IntoEnumIterator; use strum_macros::EnumIter; diff --git a/ergotree-ir/src/types/stype_param.rs b/ergotree-ir/src/types/stype_param.rs index 39e7c2f59..4fddb16d6 100644 --- a/ergotree-ir/src/types/stype_param.rs +++ b/ergotree-ir/src/types/stype_param.rs @@ -1,7 +1,12 @@ -use std::convert::TryInto; -use std::fmt::Formatter; -use std::hash::Hash; +use core::convert::TryInto; +use core::fmt::Formatter; +use core::hash::Hash; + +use alloc::string::String; +use alloc::string::ToString; +use alloc::vec; +use alloc::vec::Vec; use bounded_vec::BoundedVec; use crate::mir::expr::InvalidArgumentError; @@ -20,8 +25,8 @@ pub struct STypeVar { name_bytes: BoundedVec, } -impl std::fmt::Debug for STypeVar { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Debug for STypeVar { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { self.as_string().fmt(f) } } diff --git a/ergotree-ir/src/types/type_unify.rs b/ergotree-ir/src/types/type_unify.rs index e1ce3f950..bb47e1a01 100644 --- a/ergotree-ir/src/types/type_unify.rs +++ b/ergotree-ir/src/types/type_unify.rs @@ -1,7 +1,10 @@ -use std::collections::HashMap; +use hashbrown::HashMap; use super::stype::SType; use super::stype_param::STypeVar; + +use alloc::string::String; +use alloc::vec::Vec; use SType::*; #[allow(clippy::unnecessary_wraps)] @@ -79,7 +82,9 @@ pub fn unify_one(t1: &SType, t2: &SType) -> Result, Typ #[cfg(test)] #[allow(clippy::panic)] mod tests { - use std::sync::Arc; + + use alloc::sync::Arc; + use alloc::vec; use super::super::stype::tests::primitive_type; use super::*; diff --git a/sigma-util/Cargo.toml b/sigma-util/Cargo.toml index 1b03ae0da..17eab0a2d 100644 --- a/sigma-util/Cargo.toml +++ b/sigma-util/Cargo.toml @@ -7,9 +7,6 @@ repository.workspace = true edition.workspace = true description = "Ergo primitives" -[lib] -crate-type = ["cdylib", "rlib"] - [dependencies] blake2 = { workspace = true } sha2 = { workspace = true } From 458c4962b42f739fbd36223243b823606149a8d9 Mon Sep 17 00:00:00 2001 From: Kamal Ahmad Date: Sat, 23 Nov 2024 20:55:22 +0500 Subject: [PATCH 08/16] no_std gf2_192 --- gf2_192/Cargo.toml | 6 ++++-- gf2_192/src/gf2_192.rs | 14 ++++++++------ gf2_192/src/gf2_192poly.rs | 7 ++++--- gf2_192/src/lib.rs | 3 +++ 4 files changed, 19 insertions(+), 11 deletions(-) diff --git a/gf2_192/Cargo.toml b/gf2_192/Cargo.toml index f2299ba16..17bd7ebcf 100644 --- a/gf2_192/Cargo.toml +++ b/gf2_192/Cargo.toml @@ -9,10 +9,12 @@ edition.workspace = true [dependencies] derive_more = { workspace = true } -rand = { workspace = true } thiserror = { workspace = true } proptest-derive = { workspace = true, optional = true } -proptest = { workspace = true , optional = true } +proptest = { workspace = true, optional = true } + +[dev-dependencies] +rand = { workspace = true } [features] arbitrary = ["proptest", "proptest-derive"] diff --git a/gf2_192/src/gf2_192.rs b/gf2_192/src/gf2_192.rs index b77dcec85..74e97912e 100644 --- a/gf2_192/src/gf2_192.rs +++ b/gf2_192/src/gf2_192.rs @@ -281,7 +281,7 @@ impl Default for Gf2_192 { } } -impl std::ops::Add for Gf2_192 { +impl core::ops::Add for Gf2_192 { type Output = Self; fn add(self, rhs: Self) -> Self { let mut word = [0, 0, 0]; @@ -292,7 +292,7 @@ impl std::ops::Add for Gf2_192 { } } -impl std::ops::Mul for Gf2_192 { +impl core::ops::Mul for Gf2_192 { type Output = Self; fn mul(self, rhs: Self) -> Self { @@ -665,6 +665,8 @@ static POW_TABLE_2: [[i64; 192]; 7] = [ #[allow(clippy::unwrap_used)] mod tests { use super::*; + use alloc::vec; + use alloc::vec::Vec; use rand::{thread_rng, Rng}; #[derive(PartialEq, Eq, Clone)] @@ -675,7 +677,7 @@ mod tests { impl GF2Slow { fn equals(e: &GF2Slow, that: &[i64]) -> bool { let mut i = 0; - while i < std::cmp::min(e.x.len(), that.len()) { + while i < core::cmp::min(e.x.len(), that.len()) { if e.x[i] != that[i] { return false; } @@ -700,7 +702,7 @@ mod tests { #[allow(clippy::needless_range_loop)] fn mul_bits(a: &[i64], b: &[i64]) -> GF2Slow { - let mut c: Vec<_> = std::iter::repeat(0).take(a.len() + b.len()).collect(); + let mut c: Vec<_> = core::iter::repeat(0).take(a.len() + b.len()).collect(); for i in 0..a.len() { for i1 in 0..64 { @@ -739,7 +741,7 @@ mod tests { impl Modulus { fn new(sparse_modulus: &[i32]) -> Modulus { let degree = sparse_modulus[0]; - let mut offset: Vec<_> = std::iter::repeat(0).take(sparse_modulus.len()).collect(); + let mut offset: Vec<_> = core::iter::repeat(0).take(sparse_modulus.len()).collect(); for i in 1..sparse_modulus.len() { offset[i] = degree - sparse_modulus[i]; } @@ -752,7 +754,7 @@ mod tests { static PENTANOMIAL: [i32; 5] = [192, 7, 2, 1, 0]; fn generate_test_values() -> Vec { - let mut test_values: Vec<[i64; 3]> = std::iter::repeat([0, 0, 0]).take(250).collect(); + let mut test_values: Vec<[i64; 3]> = core::iter::repeat([0, 0, 0]).take(250).collect(); let mut rng = thread_rng(); // Test single 1s in every bit position but last diff --git a/gf2_192/src/gf2_192poly.rs b/gf2_192/src/gf2_192poly.rs index f6b0938dd..19bdedd37 100644 --- a/gf2_192/src/gf2_192poly.rs +++ b/gf2_192/src/gf2_192poly.rs @@ -24,6 +24,7 @@ //! //! For more information, please refer to +use alloc::vec::Vec; use thiserror::Error; use crate::{gf2_192::Gf2_192, Gf2_192Error}; @@ -129,7 +130,7 @@ impl Gf2_192Poly { /// NOT including the degree-zero coefficient. Each coefficient takes 24 bytes for a total of /// `self.degree * 24` bytes pub fn to_bytes(&self) -> Vec { - let mut res: Vec<_> = std::iter::repeat(0).take(self.degree * 24).collect(); + let mut res: Vec<_> = core::iter::repeat(0).take(self.degree * 24).collect(); for i in 1..=self.degree { #[allow(clippy::unwrap_used)] self.coefficients[i] @@ -168,7 +169,7 @@ impl Gf2_192Poly { /// Constructs a constant polynomial (degree 0) which takes value of `constant_term`. /// `max_degree` specifies the maximum degree of the polynomial (to allocate space). fn make_constant(max_degree: usize, constant_term: i32) -> Gf2_192Poly { - let mut coefficients: Vec<_> = std::iter::repeat_with(Gf2_192::new) + let mut coefficients: Vec<_> = core::iter::repeat_with(Gf2_192::new) .take(max_degree + 1) .collect(); coefficients[0] = Gf2_192::from(constant_term); @@ -225,7 +226,7 @@ mod tests { let mut rng = thread_rng(); for len in 1..100 { - let mut points: Vec<_> = std::iter::repeat(0).take(len).collect(); + let mut points: Vec<_> = core::iter::repeat(0).take(len).collect(); // Generate a byte that's not an element of `points` nor 0 let mut j = 0; while j < points.len() { diff --git a/gf2_192/src/lib.rs b/gf2_192/src/lib.rs index 8c759bd79..8a8862325 100644 --- a/gf2_192/src/lib.rs +++ b/gf2_192/src/lib.rs @@ -1,6 +1,7 @@ //! Implementation of finite field arithmetic and polynomial interpolation/evaluation in Galois //! field GF(2^192). +#![no_std] // Coding conventions #![forbid(unsafe_code)] #![deny(non_upper_case_globals)] @@ -19,6 +20,8 @@ #![deny(clippy::unimplemented)] #![deny(clippy::panic)] +extern crate alloc; + use derive_more::From; use gf2_192poly::Gf2_192PolyError; use thiserror::Error; From 1d0ca3cd38cf23068c2dacb772291cda2e1d8eca Mon Sep 17 00:00:00 2001 From: Kamal Ahmad Date: Sun, 24 Nov 2024 01:38:08 +0500 Subject: [PATCH 09/16] ergotree-ir: Disable proptests when arbitrary is not available This fixes tests without --features arbitrary and also gives us some test coverage on no_std --- ergo-chain-types/src/ec_point.rs | 1 + ergotree-ir/src/bigint256.rs | 1 + ergotree-ir/src/chain/address.rs | 2 +- ergotree-ir/src/chain/ergo_box.rs | 1 + ergotree-ir/src/chain/ergo_box/box_id.rs | 1 + ergotree-ir/src/chain/ergo_box/box_value.rs | 2 ++ ergotree-ir/src/chain/ergo_box/register.rs | 3 +++ ergotree-ir/src/chain/token.rs | 1 + ergotree-ir/src/mir/and.rs | 1 + ergotree-ir/src/mir/apply.rs | 1 + ergotree-ir/src/mir/atleast.rs | 2 +- ergotree-ir/src/mir/avl_tree_data.rs | 1 + ergotree-ir/src/mir/bin_op.rs | 21 ++++++++++++------- ergotree-ir/src/mir/bit_inversion.rs | 1 + ergotree-ir/src/mir/block.rs | 1 + ergotree-ir/src/mir/constant.rs | 1 + ergotree-ir/src/mir/decode_point.rs | 1 + ergotree-ir/src/mir/func_value.rs | 4 ++-- ergotree-ir/src/mir/get_var.rs | 1 + ergotree-ir/src/mir/logical_not.rs | 1 + ergotree-ir/src/mir/negation.rs | 2 +- ergotree-ir/src/mir/or.rs | 1 + ergotree-ir/src/mir/sigma_and.rs | 2 +- ergotree-ir/src/mir/sigma_or.rs | 2 +- ergotree-ir/src/mir/val_def.rs | 2 +- ergotree-ir/src/mir/xor_of.rs | 1 + ergotree-ir/src/pretty_printer.rs | 1 + ergotree-ir/src/reference.rs | 1 + ergotree-ir/src/serialization/bin_op.rs | 1 + ergotree-ir/src/sigma_protocol/dlog_group.rs | 1 + .../src/sigma_protocol/sigma_boolean.rs | 1 + .../src/sigma_protocol/sigma_boolean/cand.rs | 1 + .../src/sigma_protocol/sigma_boolean/cor.rs | 1 + ergotree-ir/src/types/type_unify.rs | 3 +++ 34 files changed, 52 insertions(+), 16 deletions(-) diff --git a/ergo-chain-types/src/ec_point.rs b/ergo-chain-types/src/ec_point.rs index 34f3caf67..ecc141474 100644 --- a/ergo-chain-types/src/ec_point.rs +++ b/ergo-chain-types/src/ec_point.rs @@ -167,6 +167,7 @@ mod arbitrary { #[allow(clippy::unwrap_used)] #[cfg(test)] +#[cfg(feature = "arbitrary")] #[allow(clippy::panic)] mod tests { use super::*; diff --git a/ergotree-ir/src/bigint256.rs b/ergotree-ir/src/bigint256.rs index 8e316d94c..425cfd52f 100644 --- a/ergotree-ir/src/bigint256.rs +++ b/ergotree-ir/src/bigint256.rs @@ -288,6 +288,7 @@ mod arbitrary { mod tests { use super::*; use num_traits::Num; + #[cfg(feature = "arbitrary")] use proptest::{prelude::*, proptest}; #[cfg(feature = "arbitrary")] diff --git a/ergotree-ir/src/chain/address.rs b/ergotree-ir/src/chain/address.rs index 53fe2689a..a39da6e32 100644 --- a/ergotree-ir/src/chain/address.rs +++ b/ergotree-ir/src/chain/address.rs @@ -588,13 +588,13 @@ pub(crate) mod arbitrary { #[cfg(test)] #[allow(clippy::unwrap_used)] #[allow(clippy::panic)] +#[cfg(feature = "arbitrary")] mod tests { use super::*; use proptest::prelude::*; - #[cfg(feature = "std")] proptest! { #[test] diff --git a/ergotree-ir/src/chain/ergo_box.rs b/ergotree-ir/src/chain/ergo_box.rs index f3e5c4a99..49a68d3e8 100644 --- a/ergotree-ir/src/chain/ergo_box.rs +++ b/ergotree-ir/src/chain/ergo_box.rs @@ -480,6 +480,7 @@ pub mod arbitrary { #[allow(clippy::panic)] #[allow(clippy::unwrap_used)] #[cfg(test)] +#[cfg(feature = "arbitrary")] mod tests { use super::*; use crate::chain::token::arbitrary::ArbTokenIdParam; diff --git a/ergotree-ir/src/chain/ergo_box/box_id.rs b/ergotree-ir/src/chain/ergo_box/box_id.rs index d91bb4e3c..9d771cdec 100644 --- a/ergotree-ir/src/chain/ergo_box/box_id.rs +++ b/ergotree-ir/src/chain/ergo_box/box_id.rs @@ -77,6 +77,7 @@ impl SigmaSerializable for BoxId { #[allow(clippy::unwrap_used)] #[allow(clippy::panic)] #[cfg(test)] +#[cfg(feature = "arbitrary")] mod tests { use super::*; use crate::serialization::sigma_serialize_roundtrip; diff --git a/ergotree-ir/src/chain/ergo_box/box_value.rs b/ergotree-ir/src/chain/ergo_box/box_value.rs index 58a1b4a3e..94c94eff6 100644 --- a/ergotree-ir/src/chain/ergo_box/box_value.rs +++ b/ergotree-ir/src/chain/ergo_box/box_value.rs @@ -246,6 +246,7 @@ pub mod tests { use super::*; use alloc::vec; use alloc::vec::Vec; + #[cfg(feature = "arbitrary")] use proptest::{collection::vec, prelude::*}; extern crate derive_more; @@ -324,6 +325,7 @@ pub mod tests { assert!(checked_sum(input.into_iter()).is_err()); } + #[cfg(feature = "arbitrary")] proptest! { #[test] diff --git a/ergotree-ir/src/chain/ergo_box/register.rs b/ergotree-ir/src/chain/ergo_box/register.rs index 603a1bc9b..13ecabee6 100644 --- a/ergotree-ir/src/chain/ergo_box/register.rs +++ b/ergotree-ir/src/chain/ergo_box/register.rs @@ -312,9 +312,12 @@ pub(crate) mod arbitrary { #[cfg(test)] mod tests { use super::*; + #[cfg(feature = "arbitrary")] use crate::serialization::sigma_serialize_roundtrip; + #[cfg(feature = "arbitrary")] use proptest::prelude::*; + #[cfg(feature = "arbitrary")] proptest! { #[test] diff --git a/ergotree-ir/src/chain/token.rs b/ergotree-ir/src/chain/token.rs index 181adc3ea..a42984ec2 100644 --- a/ergotree-ir/src/chain/token.rs +++ b/ergotree-ir/src/chain/token.rs @@ -279,6 +279,7 @@ pub mod arbitrary { #[allow(clippy::panic)] #[cfg(test)] +#[cfg(feature = "arbitrary")] mod tests { use crate::chain::token::TokenId; diff --git a/ergotree-ir/src/mir/and.rs b/ergotree-ir/src/mir/and.rs index e7d53dcd1..9da374cb8 100644 --- a/ergotree-ir/src/mir/and.rs +++ b/ergotree-ir/src/mir/and.rs @@ -71,6 +71,7 @@ mod arbitrary { } #[cfg(test)] +#[cfg(feature = "arbitrary")] #[allow(clippy::panic)] mod tests { use super::*; diff --git a/ergotree-ir/src/mir/apply.rs b/ergotree-ir/src/mir/apply.rs index 71f27d575..42c637169 100644 --- a/ergotree-ir/src/mir/apply.rs +++ b/ergotree-ir/src/mir/apply.rs @@ -115,6 +115,7 @@ pub mod arbitrary { } #[cfg(test)] +#[cfg(feature = "arbitrary")] #[allow(clippy::panic)] #[allow(clippy::unwrap_used)] mod tests { diff --git a/ergotree-ir/src/mir/atleast.rs b/ergotree-ir/src/mir/atleast.rs index 3d09f98c0..e6a561827 100644 --- a/ergotree-ir/src/mir/atleast.rs +++ b/ergotree-ir/src/mir/atleast.rs @@ -1,7 +1,6 @@ //! THRESHOLD composition for sigma expressions use alloc::boxed::Box; - use crate::serialization::op_code::OpCode; use crate::serialization::sigma_byte_reader::SigmaByteRead; use crate::serialization::sigma_byte_writer::SigmaByteWrite; @@ -103,6 +102,7 @@ mod arbitrary { } #[cfg(test)] +#[cfg(feature = "arbitrary")] #[allow(clippy::panic)] mod tests { use super::*; diff --git a/ergotree-ir/src/mir/avl_tree_data.rs b/ergotree-ir/src/mir/avl_tree_data.rs index f02a68a27..c03c4d664 100644 --- a/ergotree-ir/src/mir/avl_tree_data.rs +++ b/ergotree-ir/src/mir/avl_tree_data.rs @@ -135,6 +135,7 @@ mod arbitrary { } #[cfg(test)] +#[cfg(feature = "arbitrary")] #[allow(clippy::unwrap_used)] #[allow(clippy::panic)] mod tests { diff --git a/ergotree-ir/src/mir/bin_op.rs b/ergotree-ir/src/mir/bin_op.rs index 15d464e81..55feffcf8 100644 --- a/ergotree-ir/src/mir/bin_op.rs +++ b/ergotree-ir/src/mir/bin_op.rs @@ -335,18 +335,23 @@ mod tests { use crate::mir::constant::Constant; use crate::mir::constant::Literal::Boolean; use crate::mir::expr::Expr; - use crate::serialization::sigma_serialize_roundtrip; use crate::serialization::SigmaSerializable; - use proptest::prelude::*; - proptest! { + #[cfg(feature = "arbitrary")] + mod proptests { + use super::BinOp; + use super::Expr; + use crate::serialization::sigma_serialize_roundtrip; + use proptest::prelude::*; + + proptest! { + #[test] + fn ser_roundtrip(v in any::()) { + let expr: Expr = v.into(); + prop_assert_eq![sigma_serialize_roundtrip(&expr), expr]; + } - #[test] - fn ser_roundtrip(v in any::()) { - let expr: Expr = v.into(); - prop_assert_eq![sigma_serialize_roundtrip(&expr), expr]; } - } // Test that binop with boolean literals serialized correctly diff --git a/ergotree-ir/src/mir/bit_inversion.rs b/ergotree-ir/src/mir/bit_inversion.rs index 6adc6ddd8..d4ae665f5 100644 --- a/ergotree-ir/src/mir/bit_inversion.rs +++ b/ergotree-ir/src/mir/bit_inversion.rs @@ -92,6 +92,7 @@ mod arbitrary { } #[cfg(test)] +#[cfg(feature = "arbitrary")] #[allow(clippy::panic)] mod tests { use super::*; diff --git a/ergotree-ir/src/mir/block.rs b/ergotree-ir/src/mir/block.rs index d75d854a9..c87d75acd 100644 --- a/ergotree-ir/src/mir/block.rs +++ b/ergotree-ir/src/mir/block.rs @@ -82,6 +82,7 @@ mod arbitrary { } #[cfg(test)] +#[cfg(feature = "arbitrary")] #[allow(clippy::panic)] pub mod tests { use crate::mir::block::BlockValue; diff --git a/ergotree-ir/src/mir/constant.rs b/ergotree-ir/src/mir/constant.rs index c828acfe5..f07107bbd 100644 --- a/ergotree-ir/src/mir/constant.rs +++ b/ergotree-ir/src/mir/constant.rs @@ -1097,6 +1097,7 @@ pub(crate) mod arbitrary { #[allow(clippy::unwrap_used)] #[cfg(test)] +#[cfg(feature = "arbitrary")] #[allow(clippy::panic)] pub mod tests { use super::*; diff --git a/ergotree-ir/src/mir/decode_point.rs b/ergotree-ir/src/mir/decode_point.rs index 0a360289e..15fd10e58 100644 --- a/ergotree-ir/src/mir/decode_point.rs +++ b/ergotree-ir/src/mir/decode_point.rs @@ -73,6 +73,7 @@ mod arbitrary { } #[cfg(test)] +#[cfg(feature = "arbitrary")] #[allow(clippy::panic)] mod tests { use super::*; diff --git a/ergotree-ir/src/mir/func_value.rs b/ergotree-ir/src/mir/func_value.rs index 7a8192c67..0380d0f42 100644 --- a/ergotree-ir/src/mir/func_value.rs +++ b/ergotree-ir/src/mir/func_value.rs @@ -17,12 +17,12 @@ use crate::types::stype::SType; use super::expr::Expr; use super::val_def::ValId; -#[cfg(test)] +#[cfg(feature = "arbitrary")] use proptest_derive::Arbitrary; /// Argument parameter for the user-defined function [`FuncValue`] #[derive(PartialEq, Eq, Debug, Clone)] -#[cfg_attr(test, derive(Arbitrary))] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct FuncArg { /// Value id (defined with [`super::val_def::ValDef`]) pub idx: ValId, diff --git a/ergotree-ir/src/mir/get_var.rs b/ergotree-ir/src/mir/get_var.rs index f49f3e903..6b1c0e949 100644 --- a/ergotree-ir/src/mir/get_var.rs +++ b/ergotree-ir/src/mir/get_var.rs @@ -65,6 +65,7 @@ mod arbitrary { } #[cfg(test)] +#[cfg(feature = "arbitrary")] #[allow(clippy::panic)] mod tests { use super::*; diff --git a/ergotree-ir/src/mir/logical_not.rs b/ergotree-ir/src/mir/logical_not.rs index 85fa9311d..da77e303c 100644 --- a/ergotree-ir/src/mir/logical_not.rs +++ b/ergotree-ir/src/mir/logical_not.rs @@ -70,6 +70,7 @@ mod arbitrary { } #[cfg(test)] +#[cfg(feature = "arbitrary")] #[allow(clippy::panic)] mod tests { use super::*; diff --git a/ergotree-ir/src/mir/negation.rs b/ergotree-ir/src/mir/negation.rs index 1be5986d3..683288add 100644 --- a/ergotree-ir/src/mir/negation.rs +++ b/ergotree-ir/src/mir/negation.rs @@ -1,6 +1,5 @@ use alloc::boxed::Box; - use super::expr::Expr; use super::expr::InvalidArgumentError; use super::unary_op::OneArgOp; @@ -90,6 +89,7 @@ mod arbitrary { #[cfg(test)] #[allow(clippy::panic)] +#[cfg(feature = "arbitrary")] mod tests { use super::*; use crate::mir::expr::Expr; diff --git a/ergotree-ir/src/mir/or.rs b/ergotree-ir/src/mir/or.rs index 947728e83..d3654c277 100644 --- a/ergotree-ir/src/mir/or.rs +++ b/ergotree-ir/src/mir/or.rs @@ -79,6 +79,7 @@ mod arbitrary { #[cfg(test)] #[allow(clippy::panic)] +#[cfg(feature = "arbitrary")] mod tests { use super::*; use crate::mir::expr::Expr; diff --git a/ergotree-ir/src/mir/sigma_and.rs b/ergotree-ir/src/mir/sigma_and.rs index 2b33fd975..cf66e09cc 100644 --- a/ergotree-ir/src/mir/sigma_and.rs +++ b/ergotree-ir/src/mir/sigma_and.rs @@ -2,7 +2,6 @@ use core::convert::TryInto; - use alloc::vec::Vec; use crate::serialization::op_code::OpCode; @@ -100,6 +99,7 @@ mod arbitrary { } #[cfg(test)] +#[cfg(feature = "arbitrary")] #[allow(clippy::panic)] mod tests { use super::*; diff --git a/ergotree-ir/src/mir/sigma_or.rs b/ergotree-ir/src/mir/sigma_or.rs index 68070649d..cc49176be 100644 --- a/ergotree-ir/src/mir/sigma_or.rs +++ b/ergotree-ir/src/mir/sigma_or.rs @@ -2,7 +2,6 @@ use core::convert::TryInto; - use alloc::vec::Vec; use crate::serialization::op_code::OpCode; @@ -100,6 +99,7 @@ mod arbitrary { } #[cfg(test)] +#[cfg(feature = "arbitrary")] #[allow(clippy::panic)] mod tests { use super::*; diff --git a/ergotree-ir/src/mir/val_def.rs b/ergotree-ir/src/mir/val_def.rs index d7541acab..38e56da96 100644 --- a/ergotree-ir/src/mir/val_def.rs +++ b/ergotree-ir/src/mir/val_def.rs @@ -39,7 +39,7 @@ impl ValId { * This representation is more compact in serialized form. * @param id unique identifier of the variable in the current scope. */ #[derive(PartialEq, Eq, Debug, Clone)] -#[cfg_attr(test, derive(Arbitrary))] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct ValDef { /// Variable id pub id: ValId, diff --git a/ergotree-ir/src/mir/xor_of.rs b/ergotree-ir/src/mir/xor_of.rs index 3b75dc579..16e26be5a 100644 --- a/ergotree-ir/src/mir/xor_of.rs +++ b/ergotree-ir/src/mir/xor_of.rs @@ -72,6 +72,7 @@ mod arbitrary { #[cfg(test)] #[allow(clippy::panic)] +#[cfg(feature = "arbitrary")] mod tests { use super::*; use crate::mir::expr::Expr; diff --git a/ergotree-ir/src/pretty_printer.rs b/ergotree-ir/src/pretty_printer.rs index 6bfbd0c5a..e6adddb58 100644 --- a/ergotree-ir/src/pretty_printer.rs +++ b/ergotree-ir/src/pretty_printer.rs @@ -91,6 +91,7 @@ mod tests { use expect_test::expect; + use alloc::boxed::Box; use crate::chain::address::AddressEncoder; use crate::chain::address::NetworkPrefix; use crate::ergo_tree::ErgoTree; diff --git a/ergotree-ir/src/reference.rs b/ergotree-ir/src/reference.rs index 824e112a6..08de65ab4 100644 --- a/ergotree-ir/src/reference.rs +++ b/ergotree-ir/src/reference.rs @@ -63,6 +63,7 @@ impl<'ctx, T> core::ops::Deref for Ref<'ctx, T> { } #[cfg(test)] +#[cfg(feature = "arbitrary")] mod test { use crate::reference::Ref; use proptest::prelude::*; diff --git a/ergotree-ir/src/serialization/bin_op.rs b/ergotree-ir/src/serialization/bin_op.rs index 4bbb8f734..e27e8f024 100644 --- a/ergotree-ir/src/serialization/bin_op.rs +++ b/ergotree-ir/src/serialization/bin_op.rs @@ -88,6 +88,7 @@ mod proptests { } #[cfg(test)] +#[cfg(feature = "arbitrary")] mod tests { use sigma_test_util::force_any_val_with; diff --git a/ergotree-ir/src/sigma_protocol/dlog_group.rs b/ergotree-ir/src/sigma_protocol/dlog_group.rs index f8a3ff7c1..c339fb417 100644 --- a/ergotree-ir/src/sigma_protocol/dlog_group.rs +++ b/ergotree-ir/src/sigma_protocol/dlog_group.rs @@ -104,6 +104,7 @@ pub fn order_bigint() -> BigInt { #[allow(clippy::unwrap_used)] #[cfg(test)] +#[cfg(feature = "arbitrary")] #[allow(clippy::panic)] mod tests { use super::*; diff --git a/ergotree-ir/src/sigma_protocol/sigma_boolean.rs b/ergotree-ir/src/sigma_protocol/sigma_boolean.rs index 4e545e245..218f6b0ec 100644 --- a/ergotree-ir/src/sigma_protocol/sigma_boolean.rs +++ b/ergotree-ir/src/sigma_protocol/sigma_boolean.rs @@ -420,6 +420,7 @@ mod arbitrary { #[allow(clippy::panic)] #[cfg(test)] +#[cfg(feature = "arbitrary")] #[allow(clippy::panic)] mod tests { use super::*; diff --git a/ergotree-ir/src/sigma_protocol/sigma_boolean/cand.rs b/ergotree-ir/src/sigma_protocol/sigma_boolean/cand.rs index 22f71249d..db561fb73 100644 --- a/ergotree-ir/src/sigma_protocol/sigma_boolean/cand.rs +++ b/ergotree-ir/src/sigma_protocol/sigma_boolean/cand.rs @@ -105,6 +105,7 @@ mod arbitrary { #[allow(clippy::panic)] #[allow(clippy::unwrap_used)] #[cfg(test)] +#[cfg(feature = "arbitrary")] mod tests { use super::*; use crate::serialization::sigma_serialize_roundtrip; diff --git a/ergotree-ir/src/sigma_protocol/sigma_boolean/cor.rs b/ergotree-ir/src/sigma_protocol/sigma_boolean/cor.rs index ef206e7b1..9bb0eec91 100644 --- a/ergotree-ir/src/sigma_protocol/sigma_boolean/cor.rs +++ b/ergotree-ir/src/sigma_protocol/sigma_boolean/cor.rs @@ -107,6 +107,7 @@ mod arbitrary { #[allow(clippy::unwrap_used)] #[allow(clippy::panic)] #[cfg(test)] +#[cfg(feature = "arbitrary")] mod tests { use super::*; use crate::serialization::sigma_serialize_roundtrip; diff --git a/ergotree-ir/src/types/type_unify.rs b/ergotree-ir/src/types/type_unify.rs index bb47e1a01..f08d44fb9 100644 --- a/ergotree-ir/src/types/type_unify.rs +++ b/ergotree-ir/src/types/type_unify.rs @@ -86,12 +86,15 @@ mod tests { use alloc::sync::Arc; use alloc::vec; + #[cfg(feature = "arbitrary")] use super::super::stype::tests::primitive_type; use super::*; use crate::types::sfunc::SFunc; use crate::types::stuple::STuple; + #[cfg(feature = "arbitrary")] use proptest::prelude::*; + #[cfg(feature = "arbitrary")] proptest! { #[test] From fbfa14e0855d936b9ec2422b98e40bab020ab428 Mon Sep 17 00:00:00 2001 From: Kamal Ahmad Date: Sun, 24 Nov 2024 09:16:09 +0500 Subject: [PATCH 10/16] no_std ergotree-interpreter --- Cargo.toml | 8 +- ergotree-interpreter/Cargo.toml | 25 +++-- ergotree-interpreter/src/contracts.rs | 2 +- ergotree-interpreter/src/eval.rs | 6 +- ergotree-interpreter/src/eval/and.rs | 1 + ergotree-interpreter/src/eval/apply.rs | 9 +- ergotree-interpreter/src/eval/atleast.rs | 6 +- ergotree-interpreter/src/eval/bin_op.rs | 43 +++----- .../src/eval/byte_array_to_bigint.rs | 2 + .../src/eval/byte_array_to_long.rs | 3 + .../src/eval/calc_blake2b256.rs | 2 + ergotree-interpreter/src/eval/calc_sha256.rs | 1 + ergotree-interpreter/src/eval/coll_append.rs | 3 +- ergotree-interpreter/src/eval/coll_exists.rs | 3 + ergotree-interpreter/src/eval/coll_filter.rs | 5 +- ergotree-interpreter/src/eval/coll_fold.rs | 4 +- ergotree-interpreter/src/eval/coll_forall.rs | 3 + ergotree-interpreter/src/eval/coll_map.rs | 5 +- ergotree-interpreter/src/eval/collection.rs | 3 +- ergotree-interpreter/src/eval/costs.rs | 2 + .../src/eval/create_avl_tree.rs | 6 +- ergotree-interpreter/src/eval/decode_point.rs | 1 + ergotree-interpreter/src/eval/downcast.rs | 3 +- ergotree-interpreter/src/eval/env.rs | 7 +- ergotree-interpreter/src/eval/error.rs | 41 ++++--- ergotree-interpreter/src/eval/exponentiate.rs | 1 + ergotree-interpreter/src/eval/expr.rs | 1 + .../src/eval/extract_amount.rs | 1 + .../src/eval/extract_bytes.rs | 1 + .../src/eval/extract_bytes_with_no_ref.rs | 1 + .../src/eval/extract_creation_info.rs | 1 + ergotree-interpreter/src/eval/extract_id.rs | 2 + .../src/eval/extract_reg_as.rs | 4 +- .../src/eval/extract_script_bytes.rs | 1 + ergotree-interpreter/src/eval/global_vars.rs | 2 + ergotree-interpreter/src/eval/if_op.rs | 1 + .../src/eval/long_to_byte_array.rs | 2 + ergotree-interpreter/src/eval/method_call.rs | 1 + .../src/eval/multiply_group.rs | 1 + ergotree-interpreter/src/eval/negation.rs | 4 +- ergotree-interpreter/src/eval/option_get.rs | 1 + .../src/eval/option_is_defined.rs | 1 + ergotree-interpreter/src/eval/or.rs | 1 + .../src/eval/property_call.rs | 1 + ergotree-interpreter/src/eval/savltree.rs | 11 +- ergotree-interpreter/src/eval/sbox.rs | 4 +- ergotree-interpreter/src/eval/scoll.rs | 11 +- ergotree-interpreter/src/eval/scontext.rs | 4 +- ergotree-interpreter/src/eval/sglobal.rs | 2 +- ergotree-interpreter/src/eval/sgroup_elem.rs | 2 + ergotree-interpreter/src/eval/sheader.rs | 7 +- ergotree-interpreter/src/eval/sigma_and.rs | 4 +- ergotree-interpreter/src/eval/sigma_or.rs | 4 +- ergotree-interpreter/src/eval/soption.rs | 4 + ergotree-interpreter/src/eval/spreheader.rs | 4 +- ergotree-interpreter/src/eval/subst_const.rs | 5 +- ergotree-interpreter/src/eval/tree_lookup.rs | 4 +- ergotree-interpreter/src/eval/xor.rs | 21 ++-- ergotree-interpreter/src/eval/xor_of.rs | 1 + ergotree-interpreter/src/json/hint.rs | 2 +- ergotree-interpreter/src/lib.rs | 4 + ergotree-interpreter/src/sigma_protocol.rs | 9 +- .../src/sigma_protocol/challenge.rs | 16 +-- .../src/sigma_protocol/dht_protocol.rs | 18 +++- .../src/sigma_protocol/dlog_protocol.rs | 30 ++++-- .../src/sigma_protocol/fiat_shamir.rs | 34 +++--- .../src/sigma_protocol/gf2_192.rs | 3 +- .../src/sigma_protocol/private_input.rs | 31 +++--- .../src/sigma_protocol/proof_tree.rs | 2 +- .../src/sigma_protocol/prover.rs | 101 ++++++++++++++---- .../src/sigma_protocol/prover/hint.rs | 1 + .../sigma_protocol/prover/prover_result.rs | 5 +- .../src/sigma_protocol/sig_serializer.rs | 8 +- .../src/sigma_protocol/unchecked_tree.rs | 3 +- .../src/sigma_protocol/unproven_tree.rs | 13 ++- .../src/sigma_protocol/verifier.rs | 2 +- .../src/sigma_protocol/wscalar.rs | 10 +- .../tests/signing_spec_tests.rs | 2 +- 78 files changed, 404 insertions(+), 200 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ebd1ba10f..00d5b88b1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,7 +28,7 @@ edition = "2021" [workspace.dependencies] sigma-util = { version = "^0.18.0", path = "./sigma-util" } sigma-ser = { version = "^0.19.0", path = "./sigma-ser", default-features = false } -ergotree-ir = { version = "^0.28.0", path = "./ergotree-ir" } +ergotree-ir = { version = "^0.28.0", path = "./ergotree-ir", default-features = false } ergo-chain-types = { version = "^0.15.0", path = "./ergo-chain-types", default-features = false } sigma-test-util = { version = "^0.3.0", path = "./sigma-test-util" } ergoscript-compiler = { version = "^0.24.0", path = "./ergoscript-compiler" } @@ -62,7 +62,7 @@ sha2 = { version = "0.10", default-features = false } num-traits = { version = "0.2.14", default-features = false } num-integer = { version = "0.1.44", default-features = false } num-bigint = { version = "0.4.0", default-features = false } -lazy_static = { version = "1.4", features = ["spin_no_std"] } # TODO: add no_std feature, so spin_no_std is only enabled if std is not available +lazy_static = { version = "1.4", features = ["spin_no_std"] } bs58 = { version = "0.4.0", default-features = false, features = ["alloc"] } base16 = { version = "0.2.1", default-features = false, features = ["alloc"] } base64 = { version = "0.13.0", default-features = false, features = ["alloc"] } @@ -74,7 +74,7 @@ serde_json = { version = "1.0", features = [ ] } serde_with = { version = "1.9.1", features = ["json"] } rand = "0.8.5" -bytes = "1.1" +bytes = { version = "1.1", default-features = false } byteorder = "1" futures = "0.3" tokio = { version = "1.15.0", features = ["full"] } @@ -86,6 +86,7 @@ getrandom = { version = "0.2.7" } itertools = "0.10.3" miette = { version = "5", features = ["fancy"] } hashbrown = { version = "0.14.3", features = ["serde"] } +core2 = { version = "0.4.0", default-features = false, features = ["alloc"] } # dev-dependencies proptest = { version = "1.5.0", default-features = false, features = [ "alloc", @@ -95,7 +96,6 @@ proptest-derive = "0.3" pretty_assertions = "1.3" wasm-bindgen-test = "0.3.37" expect-test = "1.4.1" -core2 = { version = "0.4.0", default-features = false, features = ["alloc"] } [profile.release] # Tell `rustc` to optimize for small code size. opt-level = "z" diff --git a/ergotree-interpreter/Cargo.toml b/ergotree-interpreter/Cargo.toml index 0a19a4365..273e8ba7d 100644 --- a/ergotree-interpreter/Cargo.toml +++ b/ergotree-interpreter/Cargo.toml @@ -9,7 +9,7 @@ description = "ErgoTree interpreter" exclude = ["proptest-regressions/*"] [lib] -crate-type = ["cdylib", "rlib"] +crate-type = ["rlib"] [dependencies] sigma-util = { workspace = true } @@ -20,7 +20,7 @@ indexmap = { workspace = true } k256 = { workspace = true } elliptic-curve = { workspace = true } blake2 = { workspace = true } -rand = { workspace = true } +rand = { workspace = true, optional = true } lazy_static = { workspace = true } thiserror = { workspace = true } derive_more = { workspace = true } @@ -29,20 +29,29 @@ base16 = { workspace = true } proptest-derive = { workspace = true, optional = true } bytes = { workspace = true } num-bigint = { workspace = true } -bounded-vec = { workspace = true, features = ["serde"] } +bounded-vec = { workspace = true } serde = { workspace = true, optional = true } serde_json = { workspace = true, optional = true } serde_with = { workspace = true, optional = true } proptest = { workspace = true, optional = true } -ergo_avltree_rust = "0.1.0" +ergo_avltree_rust = { git = "https://github.com/SethDusek/scorex_crypto_avltree", branch = "no_std" } # TODO: wait for upstream gf2_192 = { version = "^0.28.0", path = "../gf2_192" } -miette = { workspace = true } +miette = { workspace = true, optional = true } hashbrown = { workspace = true } - +core2 = { workspace = true } [features] -default = ["json"] -json = ["serde", "serde_json", "serde_with", "bounded-vec/serde"] +json = [ + "serde", + "serde_json", + "serde_with", + "bounded-vec/serde", + "ergotree-ir/json", + "ergo-chain-types/json", +] +default = ["json", "std"] +std = ["rand", "miette"] arbitrary = [ + "std", "proptest", "proptest-derive", "ergotree-ir/arbitrary", diff --git a/ergotree-interpreter/src/contracts.rs b/ergotree-interpreter/src/contracts.rs index b3e47cc07..c73b14b55 100644 --- a/ergotree-interpreter/src/contracts.rs +++ b/ergotree-interpreter/src/contracts.rs @@ -1,7 +1,7 @@ #[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { - use std::convert::TryInto; + use core::convert::TryInto; use crate::eval::tests::eval_out_wo_ctx; use ergotree_ir::chain::address::AddressEncoder; diff --git a/ergotree-interpreter/src/eval.rs b/ergotree-interpreter/src/eval.rs index d043ebdee..cc2236896 100644 --- a/ergotree-interpreter/src/eval.rs +++ b/ergotree-interpreter/src/eval.rs @@ -1,8 +1,10 @@ //! Interpreter +use alloc::string::{String, ToString}; +use alloc::vec::Vec; +use core::fmt::Display; use ergotree_ir::ergo_tree::ErgoTree; use ergotree_ir::mir::constant::TryExtractInto; use ergotree_ir::sigma_protocol::sigma_boolean::SigmaProp; -use std::fmt::Display; use ergotree_ir::mir::expr::Expr; use ergotree_ir::mir::value::Value; @@ -103,7 +105,7 @@ pub struct ReductionDiagnosticInfo { } impl Display for ReductionDiagnosticInfo { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { if let Some(expr_str) = &self.pretty_printed_expr { writeln!(f, "Pretty printed expr:\n{}", expr_str)?; } diff --git a/ergotree-interpreter/src/eval/and.rs b/ergotree-interpreter/src/eval/and.rs index 3cb82bd85..94e821a7e 100644 --- a/ergotree-interpreter/src/eval/and.rs +++ b/ergotree-interpreter/src/eval/and.rs @@ -1,3 +1,4 @@ +use alloc::vec::Vec; use ergotree_ir::mir::and::And; use ergotree_ir::mir::constant::TryExtractInto; use ergotree_ir::mir::value::Value; diff --git a/ergotree-interpreter/src/eval/apply.rs b/ergotree-interpreter/src/eval/apply.rs index 34020f43a..b38d233a6 100644 --- a/ergotree-interpreter/src/eval/apply.rs +++ b/ergotree-interpreter/src/eval/apply.rs @@ -1,3 +1,4 @@ +use alloc::vec::Vec; use ergotree_ir::mir::apply::Apply; use ergotree_ir::mir::val_def::ValId; use ergotree_ir::mir::value::Value; @@ -56,7 +57,7 @@ impl Evaluable for Apply { #[cfg(test)] #[allow(clippy::unwrap_used)] mod tests { - use ergotree_ir::chain::context::Context; + use alloc::boxed::Box; use ergotree_ir::mir::bin_op::BinOp; use ergotree_ir::mir::bin_op::RelationOp; use ergotree_ir::mir::block::BlockValue; @@ -66,9 +67,8 @@ mod tests { use ergotree_ir::mir::val_def::ValDef; use ergotree_ir::mir::val_use::ValUse; use ergotree_ir::types::stype::SType; - use sigma_test_util::force_any_val; - use crate::eval::tests::eval_out; + use crate::eval::tests::eval_out_wo_ctx; use super::*; @@ -119,7 +119,6 @@ mod tests { ) .unwrap() .into(); - let ctx = force_any_val::(); - assert!(eval_out::(&apply, &ctx)); + assert!(eval_out_wo_ctx::(&apply)); } } diff --git a/ergotree-interpreter/src/eval/atleast.rs b/ergotree-interpreter/src/eval/atleast.rs index 625f20ae4..b56212667 100644 --- a/ergotree-interpreter/src/eval/atleast.rs +++ b/ergotree-interpreter/src/eval/atleast.rs @@ -1,5 +1,7 @@ -use std::convert::TryInto; +use core::convert::TryInto; +use alloc::boxed::Box; +use alloc::vec::Vec; use ergotree_ir::mir::atleast::Atleast; use ergotree_ir::mir::constant::TryExtractFromError; use ergotree_ir::mir::constant::TryExtractInto; @@ -59,7 +61,7 @@ impl Evaluable for Atleast { #[allow(clippy::panic)] #[cfg(test)] mod tests { - use std::sync::Arc; + use alloc::sync::Arc; use crate::eval::tests::try_eval_out_wo_ctx; use ergotree_ir::mir::constant::Constant; diff --git a/ergotree-interpreter/src/eval/bin_op.rs b/ergotree-interpreter/src/eval/bin_op.rs index e77ab254b..3043d7015 100644 --- a/ergotree-interpreter/src/eval/bin_op.rs +++ b/ergotree-interpreter/src/eval/bin_op.rs @@ -20,7 +20,7 @@ use crate::eval::Context; use crate::eval::EvalError; use crate::eval::Evaluable; -fn arithmetic_err( +fn arithmetic_err( op: &str, lv_raw: T, rv_raw: T, @@ -34,7 +34,7 @@ fn arithmetic_err( fn eval_plus<'ctx, T>(lv_raw: T, rv: Value<'ctx>) -> Result, EvalError> where - T: Num + CheckedAdd + TryExtractFrom> + Into> + std::fmt::Display, + T: Num + CheckedAdd + TryExtractFrom> + Into> + core::fmt::Display, { let rv_raw = rv.try_extract_into::()?; lv_raw @@ -45,7 +45,7 @@ where fn eval_minus<'ctx, T>(lv_raw: T, rv: Value<'ctx>) -> Result, EvalError> where - T: Num + CheckedSub + TryExtractFrom> + Into> + std::fmt::Display, + T: Num + CheckedSub + TryExtractFrom> + Into> + core::fmt::Display, { let rv_raw = rv.try_extract_into::()?; lv_raw @@ -56,7 +56,7 @@ where fn eval_mul<'ctx, T>(lv_raw: T, rv: Value<'ctx>) -> Result, EvalError> where - T: Num + CheckedMul + TryExtractFrom> + Into> + std::fmt::Display, + T: Num + CheckedMul + TryExtractFrom> + Into> + core::fmt::Display, { let rv_raw = rv.try_extract_into::()?; lv_raw @@ -67,7 +67,7 @@ where fn eval_div<'ctx, T>(lv_raw: T, rv: Value<'ctx>) -> Result, EvalError> where - T: Num + CheckedDiv + TryExtractFrom> + Into> + std::fmt::Display, + T: Num + CheckedDiv + TryExtractFrom> + Into> + core::fmt::Display, { let rv_raw = rv.try_extract_into::()?; lv_raw @@ -78,7 +78,7 @@ where fn eval_mod<'ctx, T>(lv_raw: T, rv: Value<'ctx>) -> Result, EvalError> where - T: Num + CheckedRem + TryExtractFrom> + Into> + std::fmt::Display, + T: Num + CheckedRem + TryExtractFrom> + Into> + core::fmt::Display, { let rv_raw = rv.try_extract_into::()?; lv_raw @@ -89,7 +89,7 @@ where fn eval_bit_op<'ctx, T, F>(lv_raw: T, rv: Value<'ctx>, op: F) -> Result, EvalError> where - T: Num + TryExtractFrom> + Into> + std::fmt::Display, + T: Num + TryExtractFrom> + Into> + core::fmt::Display, F: FnOnce(T, T) -> T, { let rv_raw = rv.try_extract_into::()?; @@ -326,14 +326,13 @@ impl Evaluable for BinOp { #[allow(clippy::unwrap_used)] mod tests { use super::*; - use crate::eval::tests::eval_out; - use crate::eval::tests::try_eval_out; - use ergotree_ir::chain::context::Context; + use crate::eval::tests::eval_out_wo_ctx; + use crate::eval::tests::try_eval_out_wo_ctx; + use alloc::boxed::Box; use ergotree_ir::mir::constant::Constant; use ergotree_ir::mir::expr::Expr; use num_traits::Bounded; use proptest::prelude::*; - use sigma_test_util::force_any_val; fn check_eq_neq(left: Constant, right: Constant) -> bool { let eq_op: Expr = BinOp { @@ -342,15 +341,13 @@ mod tests { right: Box::new(right.clone().into()), } .into(); - let ctx = force_any_val::(); let neq_op: Expr = BinOp { kind: BinOpKind::Relation(RelationOp::NEq), left: Box::new(left.into()), right: Box::new(right.into()), } .into(); - let ctx1 = force_any_val::(); - eval_out::(&eq_op, &ctx) && !eval_out::(&neq_op, &ctx1) + eval_out_wo_ctx::(&eq_op) && !eval_out_wo_ctx::(&neq_op) } #[test] @@ -418,8 +415,7 @@ mod tests { ), } .into(); - let ctx = force_any_val::(); - assert!(eval_out::(&e, &ctx)); + assert!(eval_out_wo_ctx::(&e)); } #[test] @@ -438,8 +434,7 @@ mod tests { ), } .into(); - let ctx = force_any_val::(); - assert!(!eval_out::(&e, &ctx)); + assert!(!eval_out_wo_ctx::(&e)); } fn eval_arith_op> + Into + 'static>( @@ -453,8 +448,7 @@ mod tests { right: Box::new(right.into().into()), } .into(); - let ctx = force_any_val::(); - try_eval_out::(&expr, &ctx) + try_eval_out_wo_ctx::(&expr) } fn eval_bit_op> + Into + 'static>( @@ -468,8 +462,7 @@ mod tests { right: Box::new(right.into().into()), } .into(); - let ctx = force_any_val::(); - try_eval_out::(&expr, &ctx) + try_eval_out_wo_ctx::(&expr) } fn eval_relation_op>(op: RelationOp, left: T, right: T) -> bool { @@ -479,8 +472,7 @@ mod tests { right: Box::new(right.into().into()), } .into(); - let ctx = force_any_val::(); - eval_out::(&expr, &ctx) + eval_out_wo_ctx::(&expr) } fn eval_logical_op>(op: LogicalOp, left: T, right: T) -> bool { @@ -490,8 +482,7 @@ mod tests { right: Box::new(right.into().into()), } .into(); - let ctx = force_any_val::(); - eval_out::(&expr, &ctx) + eval_out_wo_ctx::(&expr) } #[test] diff --git a/ergotree-interpreter/src/eval/byte_array_to_bigint.rs b/ergotree-interpreter/src/eval/byte_array_to_bigint.rs index 2be8f4110..2826af23f 100644 --- a/ergotree-interpreter/src/eval/byte_array_to_bigint.rs +++ b/ergotree-interpreter/src/eval/byte_array_to_bigint.rs @@ -1,4 +1,5 @@ #![allow(clippy::unwrap_used)] +use alloc::vec::Vec; use ergotree_ir::bigint256::BigInt256; use ergotree_ir::mir::byte_array_to_bigint::ByteArrayToBigInt; use ergotree_ir::mir::constant::TryExtractInto; @@ -38,6 +39,7 @@ mod tests { use super::*; use crate::eval::tests::try_eval_out_wo_ctx; + use alloc::boxed::Box; use num_bigint::{BigInt, Sign, ToBigInt}; use num_traits::{Bounded, Num, Pow}; diff --git a/ergotree-interpreter/src/eval/byte_array_to_long.rs b/ergotree-interpreter/src/eval/byte_array_to_long.rs index 98d3af2a5..84a3da488 100644 --- a/ergotree-interpreter/src/eval/byte_array_to_long.rs +++ b/ergotree-interpreter/src/eval/byte_array_to_long.rs @@ -1,3 +1,4 @@ +use alloc::vec::Vec; use ergotree_ir::mir::byte_array_to_long::ByteArrayToLong; use ergotree_ir::mir::value::Value; @@ -36,6 +37,8 @@ impl Evaluable for ByteArrayToLong { #[allow(clippy::unwrap_used)] mod tests { + use alloc::boxed::Box; + use super::*; use crate::eval::tests::try_eval_out_wo_ctx; diff --git a/ergotree-interpreter/src/eval/calc_blake2b256.rs b/ergotree-interpreter/src/eval/calc_blake2b256.rs index f8ce4a194..278c7af3e 100644 --- a/ergotree-interpreter/src/eval/calc_blake2b256.rs +++ b/ergotree-interpreter/src/eval/calc_blake2b256.rs @@ -1,3 +1,4 @@ +use alloc::vec::Vec; use ergotree_ir::mir::calc_blake2b256::CalcBlake2b256; use ergotree_ir::mir::value::CollKind; use ergotree_ir::mir::value::NativeColl; @@ -32,6 +33,7 @@ impl Evaluable for CalcBlake2b256 { } #[cfg(test)] +#[cfg(feature = "arbitrary")] #[allow(clippy::panic)] mod tests { use super::*; diff --git a/ergotree-interpreter/src/eval/calc_sha256.rs b/ergotree-interpreter/src/eval/calc_sha256.rs index e348aaacb..e68dd7cc7 100644 --- a/ergotree-interpreter/src/eval/calc_sha256.rs +++ b/ergotree-interpreter/src/eval/calc_sha256.rs @@ -1,3 +1,4 @@ +use alloc::vec::Vec; use ergotree_ir::mir::calc_sha256::CalcSha256; use ergotree_ir::mir::value::CollKind; use ergotree_ir::mir::value::NativeColl; diff --git a/ergotree-interpreter/src/eval/coll_append.rs b/ergotree-interpreter/src/eval/coll_append.rs index ffdb1f387..cd72aad3a 100644 --- a/ergotree-interpreter/src/eval/coll_append.rs +++ b/ergotree-interpreter/src/eval/coll_append.rs @@ -1,5 +1,6 @@ -use std::sync::Arc; +use alloc::sync::Arc; +use alloc::vec::Vec; use ergotree_ir::mir::coll_append::Append; // use ergotree_ir::mir::constant::TryExtractInto; use ergotree_ir::mir::value::CollKind; diff --git a/ergotree-interpreter/src/eval/coll_exists.rs b/ergotree-interpreter/src/eval/coll_exists.rs index 7a1eb1d16..1e8e37ead 100644 --- a/ergotree-interpreter/src/eval/coll_exists.rs +++ b/ergotree-interpreter/src/eval/coll_exists.rs @@ -1,3 +1,5 @@ +use alloc::string::ToString; +use alloc::vec::Vec; use ergotree_ir::mir::coll_exists::Exists; use ergotree_ir::mir::constant::TryExtractInto; use ergotree_ir::mir::value::Value; @@ -73,6 +75,7 @@ mod tests { use super::*; + use alloc::boxed::Box; use ergotree_ir::mir::bin_op::BinOp; use ergotree_ir::mir::bin_op::RelationOp; use ergotree_ir::mir::expr::Expr; diff --git a/ergotree-interpreter/src/eval/coll_filter.rs b/ergotree-interpreter/src/eval/coll_filter.rs index 7209d4b4f..98605275d 100644 --- a/ergotree-interpreter/src/eval/coll_filter.rs +++ b/ergotree-interpreter/src/eval/coll_filter.rs @@ -1,5 +1,7 @@ -use std::sync::Arc; +use alloc::string::ToString; +use alloc::sync::Arc; +use alloc::vec::Vec; use ergotree_ir::mir::coll_filter::Filter; use ergotree_ir::mir::constant::TryExtractInto; use ergotree_ir::mir::value::CollKind; @@ -84,6 +86,7 @@ impl Evaluable for Filter { #[allow(clippy::unwrap_used)] #[allow(clippy::panic)] #[cfg(test)] +#[cfg(feature = "arbitrary")] mod tests { use crate::eval::tests::eval_out; diff --git a/ergotree-interpreter/src/eval/coll_fold.rs b/ergotree-interpreter/src/eval/coll_fold.rs index 69128b789..878d6ecc9 100644 --- a/ergotree-interpreter/src/eval/coll_fold.rs +++ b/ergotree-interpreter/src/eval/coll_fold.rs @@ -1,3 +1,4 @@ +use alloc::string::ToString; use ergotree_ir::mir::coll_fold::Fold; use ergotree_ir::mir::value::CollKind; use ergotree_ir::mir::value::NativeColl; @@ -66,8 +67,9 @@ impl Evaluable for Fold { #[allow(clippy::panic)] #[allow(clippy::unwrap_used)] #[cfg(test)] +#[cfg(feature = "arbitrary")] mod tests { - use std::convert::TryInto; + use core::convert::TryInto; use crate::eval::tests::eval_out; use ergotree_ir::chain::context::Context; diff --git a/ergotree-interpreter/src/eval/coll_forall.rs b/ergotree-interpreter/src/eval/coll_forall.rs index ccdc22076..90aaa2132 100644 --- a/ergotree-interpreter/src/eval/coll_forall.rs +++ b/ergotree-interpreter/src/eval/coll_forall.rs @@ -1,3 +1,5 @@ +use alloc::string::ToString; +use alloc::vec::Vec; use ergotree_ir::mir::coll_forall::ForAll; use ergotree_ir::mir::constant::TryExtractInto; use ergotree_ir::mir::value::Value; @@ -73,6 +75,7 @@ mod tests { use super::*; + use alloc::boxed::Box; use ergotree_ir::mir::bin_op::BinOp; use ergotree_ir::mir::bin_op::RelationOp; use ergotree_ir::mir::expr::Expr; diff --git a/ergotree-interpreter/src/eval/coll_map.rs b/ergotree-interpreter/src/eval/coll_map.rs index 62d576fe8..08254ee51 100644 --- a/ergotree-interpreter/src/eval/coll_map.rs +++ b/ergotree-interpreter/src/eval/coll_map.rs @@ -1,5 +1,7 @@ -use std::sync::Arc; +use alloc::string::ToString; +use alloc::sync::Arc; +use alloc::vec::Vec; use ergotree_ir::mir::coll_map::Map; use ergotree_ir::mir::value::CollKind; use ergotree_ir::mir::value::Value; @@ -82,6 +84,7 @@ impl Evaluable for Map { #[allow(clippy::panic)] #[allow(clippy::unwrap_used)] #[cfg(test)] +#[cfg(feature = "arbitrary")] mod tests { use crate::eval::tests::eval_out; diff --git a/ergotree-interpreter/src/eval/collection.rs b/ergotree-interpreter/src/eval/collection.rs index c7061c7b9..297f5ac4f 100644 --- a/ergotree-interpreter/src/eval/collection.rs +++ b/ergotree-interpreter/src/eval/collection.rs @@ -1,4 +1,4 @@ -use std::sync::Arc; +use alloc::sync::Arc; use ergotree_ir::mir::collection::Collection; use ergotree_ir::mir::constant::TryExtractFromError; @@ -46,6 +46,7 @@ impl Evaluable for Collection { #[allow(clippy::unwrap_used)] #[allow(clippy::panic)] #[cfg(test)] +#[cfg(feature = "arbitrary")] mod tests { use super::*; use crate::eval::tests::eval_out_wo_ctx; diff --git a/ergotree-interpreter/src/eval/costs.rs b/ergotree-interpreter/src/eval/costs.rs index 07e496199..eb9296eb6 100644 --- a/ergotree-interpreter/src/eval/costs.rs +++ b/ergotree-interpreter/src/eval/costs.rs @@ -6,6 +6,8 @@ use derive_more::{From, Into}; #[derive(PartialEq, Eq, Debug, Clone, From, Into)] pub struct Cost(u32); +// Costing types will be reintroduced later +#[allow(dead_code)] #[derive(Debug)] pub struct Costs { pub eq_const_size: Cost, diff --git a/ergotree-interpreter/src/eval/create_avl_tree.rs b/ergotree-interpreter/src/eval/create_avl_tree.rs index 02bd94f68..385ebc717 100644 --- a/ergotree-interpreter/src/eval/create_avl_tree.rs +++ b/ergotree-interpreter/src/eval/create_avl_tree.rs @@ -2,13 +2,15 @@ use super::Evaluable; use crate::eval::env::Env; use crate::eval::Context; use crate::eval::EvalError; +use alloc::boxed::Box; +use alloc::vec::Vec; +use core::convert::TryFrom; use ergo_chain_types::ADDigest; use ergotree_ir::mir::avl_tree_data::{AvlTreeData, AvlTreeFlags}; use ergotree_ir::mir::constant::TryExtractInto; use ergotree_ir::mir::create_avl_tree::CreateAvlTree; use ergotree_ir::mir::value::Value; use sigma_util::AsVecU8; -use std::convert::TryFrom; impl Evaluable for CreateAvlTree { fn eval<'ctx>( @@ -38,7 +40,7 @@ impl Evaluable for CreateAvlTree { } } -fn map_eval_err(e: T) -> EvalError { +fn map_eval_err(e: T) -> EvalError { EvalError::AvlTree(format!("{:?}", e)) } diff --git a/ergotree-interpreter/src/eval/decode_point.rs b/ergotree-interpreter/src/eval/decode_point.rs index 627b9d625..12b72b2b4 100644 --- a/ergotree-interpreter/src/eval/decode_point.rs +++ b/ergotree-interpreter/src/eval/decode_point.rs @@ -1,3 +1,4 @@ +use alloc::vec::Vec; use ergotree_ir::mir::decode_point::DecodePoint; use ergotree_ir::mir::value::Value; diff --git a/ergotree-interpreter/src/eval/downcast.rs b/ergotree-interpreter/src/eval/downcast.rs index ed34051ca..aeef9962d 100644 --- a/ergotree-interpreter/src/eval/downcast.rs +++ b/ergotree-interpreter/src/eval/downcast.rs @@ -1,3 +1,4 @@ +use alloc::string::ToString; use ergotree_ir::bigint256::BigInt256; use ergotree_ir::ergo_tree::ErgoTreeVersion; use ergotree_ir::mir::downcast::Downcast; @@ -9,7 +10,7 @@ use crate::eval::env::Env; use crate::eval::Context; use crate::eval::EvalError; use crate::eval::Evaluable; -use std::convert::TryFrom; +use core::convert::TryFrom; fn downcast_to_bigint<'a>(in_v: Value<'a>, ctx: &Context<'_>) -> Result, EvalError> { match in_v { diff --git a/ergotree-interpreter/src/eval/env.rs b/ergotree-interpreter/src/eval/env.rs index 43b7cdc4e..7fda226cc 100644 --- a/ergotree-interpreter/src/eval/env.rs +++ b/ergotree-interpreter/src/eval/env.rs @@ -1,6 +1,7 @@ -use std::collections::HashMap; -use std::fmt::Display; +use core::fmt::Display; +use hashbrown::HashMap; +use alloc::vec::Vec; use ergotree_ir::mir::val_def::ValId; use ergotree_ir::mir::value::Value; @@ -57,7 +58,7 @@ impl<'ctx> Env<'ctx> { } impl Display for Env<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { let mut keys: Vec<&ValId> = self.store.keys().collect(); keys.sort(); for k in keys { diff --git a/ergotree-interpreter/src/eval/error.rs b/ergotree-interpreter/src/eval/error.rs index 8e17cdbe9..28dfea55d 100644 --- a/ergotree-interpreter/src/eval/error.rs +++ b/ergotree-interpreter/src/eval/error.rs @@ -1,8 +1,8 @@ +use alloc::boxed::Box; +use alloc::string::String; +use core::fmt::Debug; +use core::fmt::Display; use ergotree_ir::mir::expr::SubstDeserializeError; -use miette::miette; -use miette::LabeledSpan; -use std::fmt::Debug; -use std::fmt::Display; use bounded_vec::BoundedVecOutOfBounds; use derive_more::TryInto; @@ -112,8 +112,9 @@ pub struct SpannedWithSourceEvalError { source: String, } +#[cfg(feature = "std")] impl Display for SpannedWithSourceEvalError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { let _ = miette::set_hook(Box::new(|_| { Box::new( miette::MietteHandlerOpts::new() @@ -126,8 +127,8 @@ impl Display for SpannedWithSourceEvalError { ) })); let err_msg = self.error.to_string(); - let report = miette!( - labels = vec![LabeledSpan::at(self.source_span, err_msg,)], + let report = miette::miette!( + labels = vec![miette::LabeledSpan::at(self.source_span, err_msg,)], // help = "Help msg", "Evaluation error" ) @@ -136,8 +137,16 @@ impl Display for SpannedWithSourceEvalError { } } +#[cfg(not(feature = "std"))] +impl Display for SpannedWithSourceEvalError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "{self}") + } +} + +#[cfg(feature = "std")] impl Debug for SpannedWithSourceEvalError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { let _ = miette::set_hook(Box::new(|_| { Box::new( miette::MietteHandlerOpts::new() @@ -150,8 +159,8 @@ impl Debug for SpannedWithSourceEvalError { ) })); let err_msg = self.error.to_string(); - let report = miette!( - labels = vec![LabeledSpan::at(self.source_span, err_msg,)], + let report = miette::miette!( + labels = vec![miette::LabeledSpan::at(self.source_span, err_msg,)], // help = "Help msg", "Evaluation error" ) @@ -161,6 +170,14 @@ impl Debug for SpannedWithSourceEvalError { } } +#[cfg(not(feature = "std"))] +impl Debug for SpannedWithSourceEvalError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "{self}")?; + write!(f, "Env:\n{}", self.env) + } +} + impl EvalError { /// Wrap eval error with source span pub fn wrap(self, source_span: SourceSpan, env: Env) -> Self { @@ -203,6 +220,8 @@ impl ExtResultEvalError for Result { #[allow(clippy::unwrap_used, unused_imports, dead_code)] #[cfg(test)] mod tests { + use alloc::boxed::Box; + use alloc::string::ToString; use ergotree_ir::mir::coll_by_index::ByIndex; use ergotree_ir::mir::global_vars::GlobalVars; use ergotree_ir::source_span::SourceSpan; @@ -227,7 +246,6 @@ mod tests { fn check(expr: Expr, expected_tree: expect_test::Expect) { let mut w = PosTrackingWriter::new(); let spanned_expr = expr.print(&mut w).unwrap(); - dbg!(&spanned_expr); let ctx = force_any_val::(); let err_raw: SpannedEvalError = try_eval_out::(&spanned_expr, &ctx) .err() @@ -246,7 +264,6 @@ mod tests { fn check_error_span(expr: Expr, expected_span: SourceSpan) { let mut w = PosTrackingWriter::new(); let spanned_expr = expr.print(&mut w).unwrap(); - dbg!(&spanned_expr); let ctx = force_any_val::(); let err_raw: SpannedEvalError = try_eval_out::(&spanned_expr, &ctx) .err() diff --git a/ergotree-interpreter/src/eval/exponentiate.rs b/ergotree-interpreter/src/eval/exponentiate.rs index 39350de7c..c1ab600bd 100644 --- a/ergotree-interpreter/src/eval/exponentiate.rs +++ b/ergotree-interpreter/src/eval/exponentiate.rs @@ -37,6 +37,7 @@ impl Evaluable for Exponentiate { #[allow(clippy::unwrap_used)] #[allow(clippy::panic)] #[cfg(test)] +#[cfg(feature = "arbitrary")] mod tests { use super::*; use crate::eval::tests::eval_out; diff --git a/ergotree-interpreter/src/eval/expr.rs b/ergotree-interpreter/src/eval/expr.rs index b2a3d8a88..5ceed31ad 100644 --- a/ergotree-interpreter/src/eval/expr.rs +++ b/ergotree-interpreter/src/eval/expr.rs @@ -1,5 +1,6 @@ //! Evaluation of ErgoTree expressions +use alloc::string::ToString; use ergotree_ir::mir::expr::Expr; use ergotree_ir::mir::value::Value; use ergotree_ir::source_span::Spanned; diff --git a/ergotree-interpreter/src/eval/extract_amount.rs b/ergotree-interpreter/src/eval/extract_amount.rs index a6a287bce..73661a649 100644 --- a/ergotree-interpreter/src/eval/extract_amount.rs +++ b/ergotree-interpreter/src/eval/extract_amount.rs @@ -25,6 +25,7 @@ impl Evaluable for ExtractAmount { #[allow(clippy::unwrap_used)] #[cfg(test)] +#[cfg(feature = "arbitrary")] mod tests { use super::*; use crate::eval::tests::eval_out; diff --git a/ergotree-interpreter/src/eval/extract_bytes.rs b/ergotree-interpreter/src/eval/extract_bytes.rs index 17a37137e..07ab663ea 100644 --- a/ergotree-interpreter/src/eval/extract_bytes.rs +++ b/ergotree-interpreter/src/eval/extract_bytes.rs @@ -26,6 +26,7 @@ impl Evaluable for ExtractBytes { #[allow(clippy::unwrap_used)] #[cfg(test)] +#[cfg(feature = "arbitrary")] mod tests { use super::*; use crate::eval::tests::eval_out; diff --git a/ergotree-interpreter/src/eval/extract_bytes_with_no_ref.rs b/ergotree-interpreter/src/eval/extract_bytes_with_no_ref.rs index a84874f06..fb24cded0 100644 --- a/ergotree-interpreter/src/eval/extract_bytes_with_no_ref.rs +++ b/ergotree-interpreter/src/eval/extract_bytes_with_no_ref.rs @@ -25,6 +25,7 @@ impl Evaluable for ExtractBytesWithNoRef { #[allow(clippy::unwrap_used)] #[cfg(test)] +#[cfg(feature = "arbitrary")] mod tests { use super::*; use crate::eval::tests::eval_out; diff --git a/ergotree-interpreter/src/eval/extract_creation_info.rs b/ergotree-interpreter/src/eval/extract_creation_info.rs index 84badbe5b..d5ec545b9 100644 --- a/ergotree-interpreter/src/eval/extract_creation_info.rs +++ b/ergotree-interpreter/src/eval/extract_creation_info.rs @@ -25,6 +25,7 @@ impl Evaluable for ExtractCreationInfo { #[allow(clippy::unwrap_used)] #[cfg(test)] +#[cfg(feature = "arbitrary")] mod tests { use crate::eval::tests::eval_out; use crate::eval::Context; diff --git a/ergotree-interpreter/src/eval/extract_id.rs b/ergotree-interpreter/src/eval/extract_id.rs index 5baaf5d01..55b819c7b 100644 --- a/ergotree-interpreter/src/eval/extract_id.rs +++ b/ergotree-interpreter/src/eval/extract_id.rs @@ -1,3 +1,4 @@ +use alloc::vec::Vec; use ergotree_ir::mir::extract_id::ExtractId; use ergotree_ir::mir::value::Value; @@ -28,6 +29,7 @@ impl Evaluable for ExtractId { #[allow(clippy::unwrap_used)] #[cfg(test)] +#[cfg(feature = "arbitrary")] mod tests { use super::*; use crate::eval::tests::eval_out; diff --git a/ergotree-interpreter/src/eval/extract_reg_as.rs b/ergotree-interpreter/src/eval/extract_reg_as.rs index 05d93502f..7c991b8a7 100644 --- a/ergotree-interpreter/src/eval/extract_reg_as.rs +++ b/ergotree-interpreter/src/eval/extract_reg_as.rs @@ -1,5 +1,6 @@ -use std::convert::TryInto; +use core::convert::TryInto; +use alloc::boxed::Box; use ergotree_ir::chain::ergo_box::ErgoBox; use ergotree_ir::mir::constant::TryExtractInto; use ergotree_ir::mir::extract_reg_as::ExtractRegisterAs; @@ -47,6 +48,7 @@ impl Evaluable for ExtractRegisterAs { #[allow(clippy::unwrap_used)] #[cfg(test)] +#[cfg(feature = "arbitrary")] mod tests { use super::*; use crate::eval::tests::{eval_out, try_eval_out}; diff --git a/ergotree-interpreter/src/eval/extract_script_bytes.rs b/ergotree-interpreter/src/eval/extract_script_bytes.rs index 3557ddee0..64cf8ea07 100644 --- a/ergotree-interpreter/src/eval/extract_script_bytes.rs +++ b/ergotree-interpreter/src/eval/extract_script_bytes.rs @@ -25,6 +25,7 @@ impl Evaluable for ExtractScriptBytes { #[allow(clippy::unwrap_used)] #[cfg(test)] +#[cfg(feature = "arbitrary")] mod tests { use super::*; use crate::eval::tests::eval_out; diff --git a/ergotree-interpreter/src/eval/global_vars.rs b/ergotree-interpreter/src/eval/global_vars.rs index c94e12f80..9709fdbd4 100644 --- a/ergotree-interpreter/src/eval/global_vars.rs +++ b/ergotree-interpreter/src/eval/global_vars.rs @@ -1,4 +1,5 @@ use crate::eval::Env; +use alloc::vec::Vec; use ergotree_ir::mir::global_vars::GlobalVars; use ergotree_ir::mir::value::Value; use ergotree_ir::reference::Ref; @@ -33,6 +34,7 @@ impl Evaluable for GlobalVars { #[allow(clippy::unwrap_used)] #[cfg(test)] +#[cfg(feature = "arbitrary")] mod tests { use crate::eval::tests::eval_out; diff --git a/ergotree-interpreter/src/eval/if_op.rs b/ergotree-interpreter/src/eval/if_op.rs index d4704d1dc..5af5c1455 100644 --- a/ergotree-interpreter/src/eval/if_op.rs +++ b/ergotree-interpreter/src/eval/if_op.rs @@ -26,6 +26,7 @@ impl Evaluable for If { mod tests { use super::*; use crate::eval::tests::eval_out_wo_ctx; + use alloc::boxed::Box; use ergotree_ir::mir::bin_op::ArithOp; use ergotree_ir::mir::bin_op::BinOp; use ergotree_ir::mir::expr::Expr; diff --git a/ergotree-interpreter/src/eval/long_to_byte_array.rs b/ergotree-interpreter/src/eval/long_to_byte_array.rs index 4bc654335..c904f86ac 100644 --- a/ergotree-interpreter/src/eval/long_to_byte_array.rs +++ b/ergotree-interpreter/src/eval/long_to_byte_array.rs @@ -26,6 +26,8 @@ impl Evaluable for LongToByteArray { #[cfg(test)] mod tests { + use alloc::{boxed::Box, vec::Vec}; + use super::*; use crate::eval::tests::eval_out_wo_ctx; diff --git a/ergotree-interpreter/src/eval/method_call.rs b/ergotree-interpreter/src/eval/method_call.rs index 4902b527a..2b42c33b9 100644 --- a/ergotree-interpreter/src/eval/method_call.rs +++ b/ergotree-interpreter/src/eval/method_call.rs @@ -1,3 +1,4 @@ +use alloc::vec::Vec; use ergotree_ir::mir::method_call::MethodCall; use ergotree_ir::mir::value::Value; diff --git a/ergotree-interpreter/src/eval/multiply_group.rs b/ergotree-interpreter/src/eval/multiply_group.rs index f79d54bb6..aabab7bbe 100644 --- a/ergotree-interpreter/src/eval/multiply_group.rs +++ b/ergotree-interpreter/src/eval/multiply_group.rs @@ -30,6 +30,7 @@ impl Evaluable for MultiplyGroup { #[allow(clippy::unwrap_used)] #[allow(clippy::panic)] #[cfg(test)] +#[cfg(feature = "arbitrary")] mod tests { use super::*; use crate::eval::tests::eval_out; diff --git a/ergotree-interpreter/src/eval/negation.rs b/ergotree-interpreter/src/eval/negation.rs index ed2f47c43..d5ed12fb2 100644 --- a/ergotree-interpreter/src/eval/negation.rs +++ b/ergotree-interpreter/src/eval/negation.rs @@ -15,10 +15,10 @@ impl Evaluable for Negation { ) -> Result, EvalError> { let input_v = self.input.eval(env, ctx)?; - fn overflow_err(v: &T) -> EvalError { + fn overflow_err(v: &T) -> EvalError { EvalError::ArithmeticException(format!("Overflow on Negation of value {}", *v)) } - fn neg<'ctx, T: CheckedNeg + Into> + std::fmt::Display>( + fn neg<'ctx, T: CheckedNeg + Into> + core::fmt::Display>( v: &T, ) -> Result, EvalError> { v.checked_neg() diff --git a/ergotree-interpreter/src/eval/option_get.rs b/ergotree-interpreter/src/eval/option_get.rs index 3b872dd22..c9f702918 100644 --- a/ergotree-interpreter/src/eval/option_get.rs +++ b/ergotree-interpreter/src/eval/option_get.rs @@ -1,3 +1,4 @@ +use alloc::string::ToString; use ergotree_ir::mir::option_get::OptionGet; use ergotree_ir::mir::value::Value; diff --git a/ergotree-interpreter/src/eval/option_is_defined.rs b/ergotree-interpreter/src/eval/option_is_defined.rs index dfe237f2c..5b5b7896f 100644 --- a/ergotree-interpreter/src/eval/option_is_defined.rs +++ b/ergotree-interpreter/src/eval/option_is_defined.rs @@ -25,6 +25,7 @@ impl Evaluable for OptionIsDefined { #[allow(clippy::unwrap_used)] #[cfg(test)] +#[cfg(feature = "arbitrary")] mod tests { use super::OptionIsDefined; use crate::eval::tests::eval_out; diff --git a/ergotree-interpreter/src/eval/or.rs b/ergotree-interpreter/src/eval/or.rs index 349cb54a0..68be6c62f 100644 --- a/ergotree-interpreter/src/eval/or.rs +++ b/ergotree-interpreter/src/eval/or.rs @@ -1,3 +1,4 @@ +use alloc::vec::Vec; use ergotree_ir::mir::constant::TryExtractInto; use ergotree_ir::mir::or::Or; use ergotree_ir::mir::value::Value; diff --git a/ergotree-interpreter/src/eval/property_call.rs b/ergotree-interpreter/src/eval/property_call.rs index 4b52f5052..b38d01723 100644 --- a/ergotree-interpreter/src/eval/property_call.rs +++ b/ergotree-interpreter/src/eval/property_call.rs @@ -20,6 +20,7 @@ impl Evaluable for PropertyCall { #[allow(clippy::unwrap_used)] #[cfg(test)] +#[cfg(feature = "arbitrary")] mod tests { use super::*; use crate::eval::tests::eval_out; diff --git a/ergotree-interpreter/src/eval/savltree.rs b/ergotree-interpreter/src/eval/savltree.rs index 769c2ca32..9c6065137 100644 --- a/ergotree-interpreter/src/eval/savltree.rs +++ b/ergotree-interpreter/src/eval/savltree.rs @@ -1,5 +1,8 @@ -use std::convert::TryFrom; -use std::sync::Arc; +use alloc::boxed::Box; +use alloc::string::ToString; +use alloc::sync::Arc; +use alloc::vec::Vec; +use core::convert::TryFrom; use bytes::Bytes; use ergo_avltree_rust::authenticated_tree_ops::AuthenticatedTreeOps; @@ -429,7 +432,7 @@ pub(crate) static UPDATE_EVAL_FN: EvalFn = } }; -fn map_eval_err(e: T) -> EvalError { +fn map_eval_err(e: T) -> EvalError { EvalError::AvlTree(format!("{:?}", e)) } @@ -437,7 +440,7 @@ fn map_eval_err(e: T) -> EvalError { #[cfg(test)] #[cfg(feature = "arbitrary")] mod tests { - use std::sync::Arc; + use alloc::sync::Arc; use ergo_avltree_rust::batch_avl_prover::BatchAVLProver; use ergotree_ir::{ diff --git a/ergotree-interpreter/src/eval/sbox.rs b/ergotree-interpreter/src/eval/sbox.rs index d53511c4c..5a142607b 100644 --- a/ergotree-interpreter/src/eval/sbox.rs +++ b/ergotree-interpreter/src/eval/sbox.rs @@ -1,7 +1,7 @@ -use std::convert::TryInto; - use crate::eval::EvalError; +use alloc::boxed::Box; +use alloc::string::ToString; use ergotree_ir::chain::ergo_box::ErgoBox; use ergotree_ir::ergo_tree::ErgoTreeVersion; use ergotree_ir::mir::constant::TryExtractInto; diff --git a/ergotree-interpreter/src/eval/scoll.rs b/ergotree-interpreter/src/eval/scoll.rs index d22e9784d..17c796d87 100644 --- a/ergotree-interpreter/src/eval/scoll.rs +++ b/ergotree-interpreter/src/eval/scoll.rs @@ -1,6 +1,8 @@ use crate::eval::EvalError; use crate::eval::Evaluable; +use alloc::string::ToString; +use alloc::vec::Vec; use ergotree_ir::mir::constant::TryExtractInto; use ergotree_ir::mir::expr::Expr; use ergotree_ir::mir::value::CollKind; @@ -12,8 +14,8 @@ use ergotree_ir::types::stype::SType::SInt; use super::env::Env; use super::Context; use super::EvalFn; -use std::convert::TryFrom; -use std::sync::Arc; +use alloc::sync::Arc; +use core::convert::TryFrom; pub(crate) static INDEX_OF_EVAL_FN: EvalFn = |_mc, _env, _ctx, obj, args| { Ok(Value::Int({ @@ -169,7 +171,7 @@ pub(crate) static INDICES_EVAL_FN: EvalFn = |_mc, _env, _ctx, obj, _args| { }?; let indices_i32 = (0..input_len) .map(|i| Ok(Value::Int(i32::try_from(i)?))) - .collect::, std::num::TryFromIntError>>(); + .collect::, core::num::TryFromIntError>>(); match indices_i32 { Ok(vec_val) => match CollKind::from_collection(SInt, vec_val) { Ok(coll) => Ok(Value::Coll(coll)), @@ -336,8 +338,9 @@ pub(crate) static UPDATE_MANY_EVAL_FN: EvalFn = #[cfg(test)] #[cfg(feature = "arbitrary")] mod tests { - use std::sync::Arc; + use alloc::sync::Arc; + use alloc::vec::Vec; use ergotree_ir::mir::constant::Constant; use ergotree_ir::mir::constant::Literal; use ergotree_ir::mir::expr::Expr; diff --git a/ergotree-interpreter/src/eval/scontext.rs b/ergotree-interpreter/src/eval/scontext.rs index 5949d3f91..106d1c599 100644 --- a/ergotree-interpreter/src/eval/scontext.rs +++ b/ergotree-interpreter/src/eval/scontext.rs @@ -1,4 +1,6 @@ -use std::sync::Arc; +use alloc::boxed::Box; +use alloc::string::ToString; +use alloc::sync::Arc; use ergotree_ir::mir::avl_tree_data::AvlTreeData; use ergotree_ir::mir::avl_tree_data::AvlTreeFlags; diff --git a/ergotree-interpreter/src/eval/sglobal.rs b/ergotree-interpreter/src/eval/sglobal.rs index e01508659..8bba35054 100644 --- a/ergotree-interpreter/src/eval/sglobal.rs +++ b/ergotree-interpreter/src/eval/sglobal.rs @@ -1,4 +1,4 @@ -use std::sync::Arc; +use alloc::{string::ToString, sync::Arc}; use crate::eval::EvalError; diff --git a/ergotree-interpreter/src/eval/sgroup_elem.rs b/ergotree-interpreter/src/eval/sgroup_elem.rs index e3181fb96..b8f633192 100644 --- a/ergotree-interpreter/src/eval/sgroup_elem.rs +++ b/ergotree-interpreter/src/eval/sgroup_elem.rs @@ -1,5 +1,6 @@ use crate::eval::EvalError; +use alloc::vec::Vec; use ergo_chain_types::EcPoint; use ergotree_ir::mir::value::Value; use ergotree_ir::reference::Ref; @@ -34,6 +35,7 @@ pub(crate) static NEGATE_EVAL_FN: EvalFn = |_mc, _env, _ctx, obj, _args| { #[cfg(test)] #[cfg(feature = "arbitrary")] mod tests { + use alloc::vec::Vec; use ergotree_ir::mir::expr::Expr; use ergotree_ir::mir::method_call::MethodCall; use ergotree_ir::types::sgroup_elem; diff --git a/ergotree-interpreter/src/eval/sheader.rs b/ergotree-interpreter/src/eval/sheader.rs index 7a537b5f4..7253c6bf3 100644 --- a/ergotree-interpreter/src/eval/sheader.rs +++ b/ergotree-interpreter/src/eval/sheader.rs @@ -1,7 +1,9 @@ //! Evaluating predefined `Header` (or SHeader) type properties -use std::{convert::TryInto, sync::Arc}; +use alloc::sync::Arc; +use core::convert::TryInto; +use alloc::vec::Vec; use ergo_chain_types::Header; use ergotree_ir::{bigint256::BigInt256, mir::constant::TryExtractInto}; @@ -92,8 +94,9 @@ pub(crate) static VOTES_EVAL_FN: EvalFn = |_mc, _env, _ctx, obj, _args| { #[cfg(feature = "arbitrary")] #[allow(clippy::expect_used, clippy::panic, clippy::unwrap_used)] mod tests { - use std::convert::{TryFrom, TryInto}; + use core::convert::{TryFrom, TryInto}; + use alloc::{boxed::Box, vec::Vec}; use ergo_chain_types::{BlockId, Digest, Digest32, EcPoint, Votes}; use ergotree_ir::{ bigint256::BigInt256, diff --git a/ergotree-interpreter/src/eval/sigma_and.rs b/ergotree-interpreter/src/eval/sigma_and.rs index 9908e6f54..a272bfbf2 100644 --- a/ergotree-interpreter/src/eval/sigma_and.rs +++ b/ergotree-interpreter/src/eval/sigma_and.rs @@ -1,3 +1,4 @@ +use alloc::boxed::Box; use ergotree_ir::mir::constant::TryExtractInto; use ergotree_ir::mir::sigma_and::SigmaAnd; use ergotree_ir::mir::value::Value; @@ -28,10 +29,11 @@ impl Evaluable for SigmaAnd { #[allow(clippy::unwrap_used)] #[allow(clippy::panic)] #[cfg(test)] +#[cfg(feature = "arbitrary")] mod tests { + use core::convert::TryInto; use ergotree_ir::sigma_protocol::sigma_boolean::SigmaBoolean; use ergotree_ir::sigma_protocol::sigma_boolean::SigmaConjecture; - use std::convert::TryInto; use crate::eval::tests::eval_out; use ergotree_ir::chain::context::Context; diff --git a/ergotree-interpreter/src/eval/sigma_or.rs b/ergotree-interpreter/src/eval/sigma_or.rs index dc15eb152..9e0454c17 100644 --- a/ergotree-interpreter/src/eval/sigma_or.rs +++ b/ergotree-interpreter/src/eval/sigma_or.rs @@ -1,3 +1,4 @@ +use alloc::boxed::Box; use ergotree_ir::mir::constant::TryExtractInto; use ergotree_ir::mir::sigma_or::SigmaOr; use ergotree_ir::mir::value::Value; @@ -28,10 +29,11 @@ impl Evaluable for SigmaOr { #[allow(clippy::unwrap_used)] #[allow(clippy::panic)] #[cfg(test)] +#[cfg(feature = "arbitrary")] mod tests { + use core::convert::TryInto; use ergotree_ir::sigma_protocol::sigma_boolean::SigmaBoolean; use ergotree_ir::sigma_protocol::sigma_boolean::SigmaConjecture; - use std::convert::TryInto; use crate::eval::tests::eval_out; use ergotree_ir::chain::context::Context; diff --git a/ergotree-interpreter/src/eval/soption.rs b/ergotree-interpreter/src/eval/soption.rs index 7ac133c12..5352e8a70 100644 --- a/ergotree-interpreter/src/eval/soption.rs +++ b/ergotree-interpreter/src/eval/soption.rs @@ -1,6 +1,9 @@ use crate::eval::EvalError; use crate::eval::Evaluable; +use alloc::boxed::Box; +use alloc::string::ToString; +use alloc::vec::Vec; use ergotree_ir::mir::value::Value; use ergotree_ir::types::smethod::SMethod; @@ -116,6 +119,7 @@ pub fn filter_eval<'ctx>( #[cfg(test)] #[cfg(feature = "arbitrary")] mod tests { + use alloc::boxed::Box; use ergotree_ir::mir::bin_op::RelationOp; use ergotree_ir::mir::bin_op::{ArithOp, BinOp}; use ergotree_ir::mir::constant::Constant; diff --git a/ergotree-interpreter/src/eval/spreheader.rs b/ergotree-interpreter/src/eval/spreheader.rs index 4066ff3eb..4ffe4d1a9 100644 --- a/ergotree-interpreter/src/eval/spreheader.rs +++ b/ergotree-interpreter/src/eval/spreheader.rs @@ -1,4 +1,4 @@ -use std::sync::Arc; +use alloc::{sync::Arc, vec::Vec}; use ergo_chain_types::PreHeader; use ergotree_ir::mir::constant::TryExtractInto; @@ -44,7 +44,7 @@ pub(crate) static VOTES_EVAL_FN: EvalFn = |_mc, _env, _ctx, obj, _args| { #[cfg(feature = "arbitrary")] #[allow(clippy::expect_used)] mod tests { - use std::convert::{TryFrom, TryInto}; + use core::convert::{TryFrom, TryInto}; use ergo_chain_types::{BlockId, EcPoint, Votes}; use ergotree_ir::{ diff --git a/ergotree-interpreter/src/eval/subst_const.rs b/ergotree-interpreter/src/eval/subst_const.rs index 725063c1d..f575706b9 100644 --- a/ergotree-interpreter/src/eval/subst_const.rs +++ b/ergotree-interpreter/src/eval/subst_const.rs @@ -2,6 +2,8 @@ use crate::eval::env::Env; use crate::eval::Context; use crate::eval::EvalError; use crate::eval::Evaluable; +use alloc::vec::Vec; +use core::convert::TryFrom; use ergotree_ir::ergo_tree::ErgoTree; use ergotree_ir::mir::constant::Constant; use ergotree_ir::mir::constant::TryExtractInto; @@ -12,7 +14,6 @@ use ergotree_ir::mir::value::Value; use ergotree_ir::serialization::SigmaSerializable; use sigma_util::AsVecI8; use sigma_util::AsVecU8; -use std::convert::TryFrom; impl Evaluable for SubstConstants { fn eval<'ctx>( @@ -83,7 +84,7 @@ impl Evaluable for SubstConstants { } } -fn to_misc_err(e: T) -> EvalError { +fn to_misc_err(e: T) -> EvalError { EvalError::Misc(format!("{:?}", e)) } diff --git a/ergotree-interpreter/src/eval/tree_lookup.rs b/ergotree-interpreter/src/eval/tree_lookup.rs index b633ff863..4a7900ae2 100644 --- a/ergotree-interpreter/src/eval/tree_lookup.rs +++ b/ergotree-interpreter/src/eval/tree_lookup.rs @@ -1,3 +1,5 @@ +use alloc::boxed::Box; +use alloc::vec::Vec; use bytes::Bytes; use ergotree_ir::mir::tree_lookup::TreeLookup; use ergotree_ir::mir::value::Value; @@ -60,7 +62,7 @@ impl Evaluable for TreeLookup { } } -fn map_eval_err(e: T) -> EvalError { +fn map_eval_err(e: T) -> EvalError { EvalError::AvlTree(format!("{:?}", e)) } diff --git a/ergotree-interpreter/src/eval/xor.rs b/ergotree-interpreter/src/eval/xor.rs index ea322a3ab..a94c0f7b9 100644 --- a/ergotree-interpreter/src/eval/xor.rs +++ b/ergotree-interpreter/src/eval/xor.rs @@ -1,4 +1,4 @@ -use std::sync::Arc; +use alloc::sync::Arc; use ergotree_ir::mir::value::CollKind; use ergotree_ir::mir::value::NativeColl; @@ -44,7 +44,9 @@ impl Evaluable for Xor { #[cfg(test)] mod tests { use super::*; - use crate::eval::tests::eval_out; + use crate::eval::tests::{eval_out, eval_out_wo_ctx}; + use alloc::boxed::Box; + use alloc::vec::Vec; use ergotree_ir::chain::context::Context; use ergotree_ir::mir::expr::Expr; use proptest::prelude::*; @@ -62,8 +64,7 @@ mod tests { } .into(); - let ctx = force_any_val::(); - assert_eq!(eval_out::>(&expr, &ctx), expected_xor); + assert_eq!(eval_out_wo_ctx::>(&expr), expected_xor); } #[test] @@ -94,8 +95,7 @@ mod tests { } .into(); - let ctx = force_any_val::(); - assert_eq!(eval_out::>(&expr, &ctx), expected_xor); + assert_eq!(eval_out_wo_ctx::>(&expr), expected_xor); } #[test] @@ -110,8 +110,7 @@ mod tests { } .into(); - let ctx = force_any_val::(); - assert_eq!(eval_out::>(&expr, &ctx), expected_xor); + assert_eq!(eval_out_wo_ctx::>(&expr), expected_xor); } #[test] @@ -126,8 +125,7 @@ mod tests { } .into(); - let ctx = force_any_val::(); - assert_eq!(eval_out::>(&expr, &ctx), expected_xor); + assert_eq!(eval_out_wo_ctx::>(&expr), expected_xor); } proptest! { @@ -143,8 +141,7 @@ mod tests { } .into(); - let ctx = force_any_val::(); - assert_eq!(&eval_out::>(&expr, &ctx)[..], &expected_xor[..]); + assert_eq!(&eval_out_wo_ctx::>(&expr)[..], &expected_xor[..]); } } } diff --git a/ergotree-interpreter/src/eval/xor_of.rs b/ergotree-interpreter/src/eval/xor_of.rs index 52ad3d2c1..e55c0586a 100644 --- a/ergotree-interpreter/src/eval/xor_of.rs +++ b/ergotree-interpreter/src/eval/xor_of.rs @@ -1,3 +1,4 @@ +use alloc::vec::Vec; use ergotree_ir::mir::constant::TryExtractInto; use ergotree_ir::mir::value::Value; diff --git a/ergotree-interpreter/src/json/hint.rs b/ergotree-interpreter/src/json/hint.rs index 5c3f1ddb8..4c5e91738 100644 --- a/ergotree-interpreter/src/json/hint.rs +++ b/ergotree-interpreter/src/json/hint.rs @@ -1,4 +1,4 @@ -use std::convert::TryFrom; +use core::convert::TryFrom; use std::num::ParseIntError; use std::str::FromStr; diff --git a/ergotree-interpreter/src/lib.rs b/ergotree-interpreter/src/lib.rs index 05932db52..e808bf87d 100644 --- a/ergotree-interpreter/src/lib.rs +++ b/ergotree-interpreter/src/lib.rs @@ -1,5 +1,6 @@ //! ErgoTree interpreter +#![cfg_attr(not(feature = "std"), no_std)] // Coding conventions #![forbid(unsafe_code)] #![allow(clippy::needless_lifetimes)] @@ -20,6 +21,9 @@ #![deny(clippy::unreachable)] #![deny(clippy::panic)] +#[macro_use] +extern crate alloc; + mod contracts; pub mod eval; diff --git a/ergotree-interpreter/src/sigma_protocol.rs b/ergotree-interpreter/src/sigma_protocol.rs index 6f4b4a03a..fb10dc8cf 100644 --- a/ergotree-interpreter/src/sigma_protocol.rs +++ b/ergotree-interpreter/src/sigma_protocol.rs @@ -7,6 +7,7 @@ pub mod prover; pub mod verifier; pub(crate) mod challenge; +#[cfg(feature = "std")] mod crypto_utils; pub mod dht_protocol; pub mod dlog_protocol; @@ -18,9 +19,11 @@ pub mod unchecked_tree; pub mod unproven_tree; pub mod wscalar; -use std::array::TryFromSliceError; -use std::convert::TryFrom; -use std::convert::TryInto; +use alloc::boxed::Box; +use alloc::vec::Vec; +use core::array::TryFromSliceError; +use core::convert::TryFrom; +use core::convert::TryInto; use ergotree_ir::sigma_protocol::sigma_boolean::SigmaBoolean; diff --git a/ergotree-interpreter/src/sigma_protocol/challenge.rs b/ergotree-interpreter/src/sigma_protocol/challenge.rs index 11ab1ad5b..9bb150395 100644 --- a/ergotree-interpreter/src/sigma_protocol/challenge.rs +++ b/ergotree-interpreter/src/sigma_protocol/challenge.rs @@ -1,24 +1,26 @@ use super::{fiat_shamir::FiatShamirHash, SOUNDNESS_BYTES}; +use alloc::boxed::Box; +use alloc::vec::Vec; +use core::convert::TryFrom; use ergotree_ir::serialization::sigma_byte_reader::SigmaByteRead; use ergotree_ir::serialization::sigma_byte_writer::SigmaByteWrite; #[cfg(feature = "arbitrary")] use proptest_derive::Arbitrary; -use std::convert::TryFrom; /// Challenge in Sigma protocol #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(PartialEq, Eq, Clone)] -#[cfg(feature = "json")] -#[derive(serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "json", derive(serde::Serialize, serde::Deserialize))] pub struct Challenge(pub(crate) FiatShamirHash); -impl std::fmt::Debug for Challenge { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Debug for Challenge { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { "Challenge:***".fmt(f) } } impl Challenge { + #[cfg(feature = "std")] pub fn secure_random() -> Self { Self(FiatShamirHash::secure_random()) } @@ -35,12 +37,12 @@ impl Challenge { FiatShamirHash::try_from(res.as_slice()).unwrap().into() } - pub fn sigma_serialize(&self, w: &mut W) -> Result<(), std::io::Error> { + pub fn sigma_serialize(&self, w: &mut W) -> Result<(), core2::io::Error> { w.write_all(self.0 .0.as_ref())?; Ok(()) } - pub fn sigma_parse(r: &mut R) -> Result { + pub fn sigma_parse(r: &mut R) -> Result { let mut chal_bytes: [u8; super::SOUNDNESS_BYTES] = [0; super::SOUNDNESS_BYTES]; r.read_exact(&mut chal_bytes)?; Ok(Challenge::from(FiatShamirHash(Box::new(chal_bytes)))) diff --git a/ergotree-interpreter/src/sigma_protocol/dht_protocol.rs b/ergotree-interpreter/src/sigma_protocol/dht_protocol.rs index 637550bc7..fefcf236b 100644 --- a/ergotree-interpreter/src/sigma_protocol/dht_protocol.rs +++ b/ergotree-interpreter/src/sigma_protocol/dht_protocol.rs @@ -2,6 +2,8 @@ use super::wscalar::Wscalar; use super::ProverMessage; +use alloc::boxed::Box; +use alloc::vec::Vec; use ergo_chain_types::EcPoint; use ergotree_ir::serialization::SigmaSerializable; @@ -47,13 +49,11 @@ pub struct SecondDhTupleProverMessage { /// Interactive prover pub mod interactive_prover { - use std::ops::Mul; + use core::ops::Mul; use super::*; - use crate::sigma_protocol::crypto_utils; use crate::sigma_protocol::private_input::DhTupleProverInput; use crate::sigma_protocol::Challenge; - use ergotree_ir::sigma_protocol::dlog_group; use ergotree_ir::sigma_protocol::sigma_boolean::ProveDhTuple; use k256::Scalar; @@ -61,13 +61,17 @@ pub mod interactive_prover { /// For every leaf marked “simulated”, use the simulator of the sigma protocol for that leaf /// to compute the commitment "a" and the response "z", given the challenge "e" that /// is already stored in the leaf + #[cfg(feature = "std")] pub(crate) fn simulate( public_input: &ProveDhTuple, challenge: &Challenge, ) -> (FirstDhTupleProverMessage, SecondDhTupleProverMessage) { use ergo_chain_types::ec_point::exponentiate; + use ergotree_ir::sigma_protocol::dlog_group; //SAMPLE a random z <- Zq - let z = dlog_group::random_scalar_in_group_range(crypto_utils::secure_rng()); + let z = dlog_group::random_scalar_in_group_range( + crate::sigma_protocol::crypto_utils::secure_rng(), + ); // COMPUTE a = g^z*u^(-e) and b = h^z*v^{-e} (where -e here means -e mod q) let e: Scalar = challenge.clone().into(); @@ -89,9 +93,13 @@ pub mod interactive_prover { /// that leaf to compute the necessary randomness "r" and the commitment "a" /// /// In this case (DH tuple) "a" is also a tuple + #[cfg(feature = "std")] pub fn first_message(public_input: &ProveDhTuple) -> (Wscalar, FirstDhTupleProverMessage) { use ergo_chain_types::ec_point::exponentiate; - let r = dlog_group::random_scalar_in_group_range(crypto_utils::secure_rng()); + use ergotree_ir::sigma_protocol::dlog_group; + let r = dlog_group::random_scalar_in_group_range( + crate::sigma_protocol::crypto_utils::secure_rng(), + ); let a = exponentiate(&public_input.g, &r); let b = exponentiate(&public_input.h, &r); (r.into(), FirstDhTupleProverMessage::new(a, b)) diff --git a/ergotree-interpreter/src/sigma_protocol/dlog_protocol.rs b/ergotree-interpreter/src/sigma_protocol/dlog_protocol.rs index e26064cf6..0391fa024 100644 --- a/ergotree-interpreter/src/sigma_protocol/dlog_protocol.rs +++ b/ergotree-interpreter/src/sigma_protocol/dlog_protocol.rs @@ -2,6 +2,8 @@ use super::wscalar::Wscalar; use super::ProverMessage; +use alloc::boxed::Box; +use alloc::vec::Vec; use ergo_chain_types::EcPoint; use ergotree_ir::serialization::SigmaSerializable; @@ -38,17 +40,15 @@ pub struct SecondDlogProverMessage { /// Interactive prover pub mod interactive_prover { - use std::ops::Mul; + use core::ops::Mul; - use super::{FirstDlogProverMessage, SecondDlogProverMessage}; - use crate::sigma_protocol::crypto_utils; + use super::SecondDlogProverMessage; use crate::sigma_protocol::wscalar::Wscalar; use crate::sigma_protocol::{private_input::DlogProverInput, Challenge}; use ergo_chain_types::{ ec_point::{exponentiate, generator, inverse}, EcPoint, }; - use ergotree_ir::sigma_protocol::dlog_group; use ergotree_ir::sigma_protocol::sigma_boolean::ProveDlog; use k256::Scalar; @@ -56,12 +56,16 @@ pub mod interactive_prover { /// For every leaf marked “simulated”, use the simulator of the sigma protocol for that leaf /// to compute the commitment "a" and the response "z", given the challenge "e" that /// is already stored in the leaf + #[cfg(feature = "std")] pub(crate) fn simulate( public_input: &ProveDlog, challenge: &Challenge, - ) -> (FirstDlogProverMessage, SecondDlogProverMessage) { + ) -> (super::FirstDlogProverMessage, SecondDlogProverMessage) { + use ergotree_ir::sigma_protocol::dlog_group; //SAMPLE a random z <- Zq - let z = dlog_group::random_scalar_in_group_range(crypto_utils::secure_rng()); + let z = dlog_group::random_scalar_in_group_range( + crate::sigma_protocol::crypto_utils::secure_rng(), + ); //COMPUTE a = g^z*h^(-e) (where -e here means -e mod q) let e: Scalar = challenge.clone().into(); @@ -70,7 +74,7 @@ pub mod interactive_prover { let g_to_z = exponentiate(&generator(), &z); let a = g_to_z * &h_to_e; ( - FirstDlogProverMessage { a: a.into() }, + super::FirstDlogProverMessage { a: a.into() }, SecondDlogProverMessage { z: z.into() }, ) } @@ -78,11 +82,15 @@ pub mod interactive_prover { /// Step 6 from /// For every leaf marked “real”, use the first prover step of the sigma protocol for /// that leaf to compute the necessary randomness "r" and the commitment "a" - pub fn first_message() -> (Wscalar, FirstDlogProverMessage) { - let r = dlog_group::random_scalar_in_group_range(crypto_utils::secure_rng()); + #[cfg(feature = "std")] + pub fn first_message() -> (Wscalar, super::FirstDlogProverMessage) { + use ergotree_ir::sigma_protocol::dlog_group; + let r = dlog_group::random_scalar_in_group_range( + crate::sigma_protocol::crypto_utils::secure_rng(), + ); let g = generator(); let a = exponentiate(&g, &r); - (r.into(), FirstDlogProverMessage { a: a.into() }) + (r.into(), super::FirstDlogProverMessage { a: a.into() }) } /// Step 9 part 2 from @@ -105,7 +113,7 @@ pub mod interactive_prover { /// The function computes initial prover's commitment to randomness /// ("a" message of the sigma-protocol) based on the verifier's challenge ("e") /// and prover's response ("z") - /// + /// /// g^z = a*h^e => a = g^z/h^e pub fn compute_commitment( proposition: &ProveDlog, diff --git a/ergotree-interpreter/src/sigma_protocol/fiat_shamir.rs b/ergotree-interpreter/src/sigma_protocol/fiat_shamir.rs index a64e422f4..288b8e06b 100644 --- a/ergotree-interpreter/src/sigma_protocol/fiat_shamir.rs +++ b/ergotree-interpreter/src/sigma_protocol/fiat_shamir.rs @@ -1,10 +1,16 @@ //! Fiat-Shamir transformation -use super::crypto_utils::secure_random_bytes; use super::proof_tree::ProofTreeKind; use crate::sigma_protocol::unchecked_tree::{UncheckedConjecture, UncheckedTree}; use crate::sigma_protocol::unproven_tree::{UnprovenConjecture, UnprovenTree}; use crate::sigma_protocol::ProverMessage; +use alloc::boxed::Box; +use alloc::string::String; +use alloc::string::ToString; +use alloc::vec::Vec; +use core::array::TryFromSliceError; +use core::convert::{TryFrom, TryInto}; +use core::fmt::Formatter; use ergo_chain_types::{Base16DecodedBytes, Base16EncodedBytes}; use ergotree_ir::ergo_tree::{ErgoTree, ErgoTreeHeader}; use ergotree_ir::mir::expr::Expr; @@ -13,9 +19,6 @@ use ergotree_ir::serialization::sigma_byte_writer::SigmaByteWriter; use ergotree_ir::serialization::SigmaSerializable; use ergotree_ir::sigma_protocol::sigma_boolean::{SigmaBoolean, SigmaProp}; use sigma_util::hash::blake2b256_hash; -use std::array::TryFromSliceError; -use std::convert::{TryFrom, TryInto}; -use std::fmt::Formatter; use thiserror::Error; #[cfg(feature = "arbitrary")] @@ -38,9 +41,10 @@ use super::SOUNDNESS_BYTES; pub struct FiatShamirHash(pub Box<[u8; SOUNDNESS_BYTES]>); impl FiatShamirHash { + #[cfg(feature = "std")] pub fn secure_random() -> Self { #[allow(clippy::unwrap_used)] // since we set the correct size - secure_random_bytes(SOUNDNESS_BYTES) + super::crypto_utils::secure_random_bytes(SOUNDNESS_BYTES) .as_slice() .try_into() .unwrap() @@ -85,8 +89,8 @@ impl TryFrom<&[u8]> for FiatShamirHash { } } -impl std::fmt::Debug for FiatShamirHash { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Debug for FiatShamirHash { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { f.write_str("FSH:")?; f.write_str(&base16::encode_lower(&(*self.0))) } @@ -95,10 +99,10 @@ impl std::fmt::Debug for FiatShamirHash { /// Invalid byte array size #[derive(Error, Debug)] #[error("Invalid byte array size ({0})")] -pub struct FiatShamirHashError(std::array::TryFromSliceError); +pub struct FiatShamirHashError(core::array::TryFromSliceError); -impl From for FiatShamirHashError { - fn from(err: std::array::TryFromSliceError) -> Self { +impl From for FiatShamirHashError { + fn from(err: core::array::TryFromSliceError) -> Self { FiatShamirHashError(err) } } @@ -122,8 +126,14 @@ pub(crate) fn fiat_shamir_tree_to_bytes( pub enum FiatShamirTreeSerializationError { #[error("empty commitment in leaf with proposition {0:?} ")] EmptyCommitmentInLeaf(SigmaBoolean), - #[error("io errro {0:?} ")] - IoError(#[from] std::io::Error), + #[error("io errror {0:?} ")] + IoError(String), +} + +impl From for FiatShamirTreeSerializationError { + fn from(error: core2::io::Error) -> FiatShamirTreeSerializationError { + FiatShamirTreeSerializationError::IoError(error.to_string()) + } } fn fiat_shamir_write_bytes( diff --git a/ergotree-interpreter/src/sigma_protocol/gf2_192.rs b/ergotree-interpreter/src/sigma_protocol/gf2_192.rs index 3be2ba24a..3ca01f18a 100644 --- a/ergotree-interpreter/src/sigma_protocol/gf2_192.rs +++ b/ergotree-interpreter/src/sigma_protocol/gf2_192.rs @@ -1,6 +1,7 @@ -use std::convert::TryFrom; +use core::convert::TryFrom; use super::{challenge::Challenge, fiat_shamir::FiatShamirHash, SOUNDNESS_BYTES}; +use alloc::{boxed::Box, vec::Vec}; use gf2_192::{ gf2_192::Gf2_192, gf2_192poly::{CoefficientsByteRepr, Gf2_192Poly}, diff --git a/ergotree-interpreter/src/sigma_protocol/private_input.rs b/ergotree-interpreter/src/sigma_protocol/private_input.rs index 09ba86d8e..4b8ebed3d 100644 --- a/ergotree-interpreter/src/sigma_protocol/private_input.rs +++ b/ergotree-interpreter/src/sigma_protocol/private_input.rs @@ -1,10 +1,10 @@ //! Private input types for the prover's secrets -use std::convert::TryInto; -use std::fmt::Formatter; +use core::convert::TryInto; +use core::fmt::Formatter; +use alloc::vec::Vec; use ergo_chain_types::EcPoint; use ergotree_ir::serialization::SigmaSerializable; -use ergotree_ir::sigma_protocol::dlog_group; use ergotree_ir::sigma_protocol::sigma_boolean::ProveDhTuple; use ergotree_ir::sigma_protocol::sigma_boolean::ProveDlog; @@ -16,7 +16,6 @@ use k256::elliptic_curve::PrimeField; use num_bigint::BigUint; use num_traits::ToPrimitive; -use super::crypto_utils; use super::wscalar::Wscalar; /// Secret key of discrete logarithm signature protocol @@ -28,8 +27,8 @@ pub struct DlogProverInput { pub w: Wscalar, } -impl std::fmt::Debug for DlogProverInput { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Debug for DlogProverInput { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { // to avoid leaking it in error messages, logs, etc. "DLOGPI:***".fmt(f) } @@ -40,9 +39,13 @@ impl DlogProverInput { pub const SIZE_BYTES: usize = 32; /// generates random secret in the range [0, n), where n is DLog group order. + #[cfg(feature = "std")] pub fn random() -> DlogProverInput { DlogProverInput { - w: dlog_group::random_scalar_in_group_range(crypto_utils::secure_rng()).into(), + w: ergotree_ir::sigma_protocol::dlog_group::random_scalar_in_group_range( + super::crypto_utils::secure_rng(), + ) + .into(), } } @@ -56,8 +59,8 @@ impl DlogProverInput { /// Attempts to parse the given Base16-encoded byte array as an SEC-1-encoded scalar(secret key). /// Returns None if the byte array does not contain a big-endian integer in the range [0, modulus). - pub fn from_base16_str(str: String) -> Option { - base16::decode(&str) + pub fn from_base16_str(str: &str) -> Option { + base16::decode(str) .ok() .and_then(|bytes| bytes.as_slice().try_into().ok().map(Self::from_bytes)) .flatten() @@ -116,8 +119,8 @@ pub struct DhTupleProverInput { pub common_input: ProveDhTuple, } -impl std::fmt::Debug for DhTupleProverInput { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Debug for DhTupleProverInput { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { // to avoid leaking it in error messages, logs, etc. "DHTPI:***".fmt(f) } @@ -129,14 +132,16 @@ impl DhTupleProverInput { /// Create random secret and Diffie-Hellman tuple #[allow(clippy::many_single_char_names)] + #[cfg(feature = "std")] pub fn random() -> DhTupleProverInput { use ergo_chain_types::ec_point::{exponentiate, generator}; + use ergotree_ir::sigma_protocol::dlog_group; let g = generator(); let h = exponentiate( &generator(), - &dlog_group::random_scalar_in_group_range(crypto_utils::secure_rng()), + &dlog_group::random_scalar_in_group_range(super::crypto_utils::secure_rng()), ); - let w = dlog_group::random_scalar_in_group_range(crypto_utils::secure_rng()); + let w = dlog_group::random_scalar_in_group_range(super::crypto_utils::secure_rng()); let u = exponentiate(&g, &w); let v = exponentiate(&h, &w); let common_input = ProveDhTuple::new(g, h, u, v); diff --git a/ergotree-interpreter/src/sigma_protocol/proof_tree.rs b/ergotree-interpreter/src/sigma_protocol/proof_tree.rs index cef7af695..887ba375a 100644 --- a/ergotree-interpreter/src/sigma_protocol/proof_tree.rs +++ b/ergotree-interpreter/src/sigma_protocol/proof_tree.rs @@ -2,7 +2,7 @@ extern crate derive_more; -use std::fmt::Debug; +use core::fmt::Debug; use derive_more::From; use derive_more::TryInto; diff --git a/ergotree-interpreter/src/sigma_protocol/prover.rs b/ergotree-interpreter/src/sigma_protocol/prover.rs index b00a2de87..7a3193131 100644 --- a/ergotree-interpreter/src/sigma_protocol/prover.rs +++ b/ergotree-interpreter/src/sigma_protocol/prover.rs @@ -6,10 +6,9 @@ pub mod hint; use crate::eval::reduce_to_crypto; use crate::eval::ReductionDiagnosticInfo; -use crate::sigma_protocol::crypto_utils::secure_random_bytes; +use crate::sigma_protocol::dht_protocol; use crate::sigma_protocol::fiat_shamir::fiat_shamir_hash_fn; use crate::sigma_protocol::fiat_shamir::fiat_shamir_tree_to_bytes; -use crate::sigma_protocol::gf2_192::gf2_192poly_from_byte_array; use crate::sigma_protocol::proof_tree::ProofTree; use crate::sigma_protocol::unchecked_tree::{UncheckedDhTuple, UncheckedLeaf}; use crate::sigma_protocol::unproven_tree::CandUnproven; @@ -18,14 +17,13 @@ use crate::sigma_protocol::unproven_tree::NodePosition; use crate::sigma_protocol::unproven_tree::UnprovenDhTuple; use crate::sigma_protocol::Challenge; use crate::sigma_protocol::UnprovenLeaf; -use crate::sigma_protocol::SOUNDNESS_BYTES; -use crate::sigma_protocol::{crypto_utils, dht_protocol}; +use alloc::vec::Vec; +use core::convert::TryInto; use ergotree_ir::sigma_protocol::sigma_boolean::SigmaBoolean; use ergotree_ir::sigma_protocol::sigma_boolean::SigmaConjectureItems; use gf2_192::gf2_192poly::Gf2_192Poly; use gf2_192::gf2_192poly::Gf2_192PolyError; use gf2_192::Gf2_192Error; -use std::convert::TryInto; use ergotree_ir::ergo_tree::ErgoTree; use ergotree_ir::ergo_tree::ErgoTreeError; @@ -54,9 +52,6 @@ use super::FirstProverMessage::FirstDlogProverMessage; use crate::eval::EvalError; use ergotree_ir::chain::context::Context; -use crate::sigma_protocol::dht_protocol::SecondDhTupleProverMessage; -use crate::sigma_protocol::dlog_protocol::SecondDlogProverMessage; -use ergotree_ir::sigma_protocol::dlog_group; use thiserror::Error; /// Prover errors @@ -95,6 +90,9 @@ pub enum ProverError { /// Error while tree serialization for Fiat-Shamir hash #[error("Fiat-Shamir tree serialization error: {0}")] FiatShamirTreeSerializationError(FiatShamirTreeSerializationError), + /// Unsupported operation + #[error("RNG is not available in no_std environments, can't generate signature without Hint")] + Unsupported, } impl From for ProverError { @@ -458,21 +456,32 @@ fn step4_real_conj( //real OR Threshold case UnprovenConjecture::CorUnproven(_) | UnprovenConjecture::CthresholdUnproven(_) => { let new_children = cast_to_unp(uc.children())? - .mapped(|c| { + .try_mapped(|c| -> Result<_, ProverError> { if c.is_real() { - c + Ok(c) } else { // take challenge from previously done proof stored in the hints bag, // or generate random challenge for simulated child - let new_challenge: Challenge = hints_bag + let new_challenge: Challenge = if let Some(new_challenge) = hints_bag .proofs() .into_iter() .find(|p| p.position() == c.position()) .map(|p| p.challenge().clone()) - .unwrap_or_else(Challenge::secure_random); - c.with_challenge(new_challenge) + { + new_challenge + } else { + #[cfg(feature = "std")] + { + Challenge::secure_random() + } + #[cfg(not(feature = "std"))] + { + return Err(ProverError::Unsupported); + } + }; + Ok(c.with_challenge(new_challenge)) } - }) + })? .mapped(|c| c.into()); Ok(Some( uc.with_children(new_children).into(), // CorUnproven { @@ -507,6 +516,7 @@ fn step4_simulated_and_conj(cand: CandUnproven) -> Result, Pro } } +#[cfg(feature = "std")] fn step4_simulated_or_conj(cor: CorUnproven) -> Result, ProverError> { // If the node is OR, then each of its children except one gets a fresh uniformly random // challenge in {0,1}^t. The remaining child gets a challenge computed as an XOR of the challenges of all @@ -551,10 +561,16 @@ fn step4_simulated_or_conj(cor: CorUnproven) -> Result, Prover )) } } +#[cfg(not(feature = "std"))] +fn step4_simulated_or_conj(_cor: CorUnproven) -> Result, ProverError> { + Err(ProverError::Unsupported) +} +#[cfg(feature = "std")] fn step4_simulated_threshold_conj( ct: CthresholdUnproven, ) -> Result, ProverError> { + use crate::sigma_protocol::gf2_192::gf2_192poly_from_byte_array; // The faster algorithm is as follows. Pick n-k fresh uniformly random values // q_1, ..., q_{n-k} from {0,1}^t and let q_0=e_0. // Viewing 1, 2, ..., n and q_0, ..., q_{n-k} as elements of GF(2^t), @@ -566,7 +582,7 @@ fn step4_simulated_threshold_conj( let n = ct.children.len(); let q = gf2_192poly_from_byte_array( challenge, - secure_random_bytes(SOUNDNESS_BYTES * (n - ct.k as usize)), + super::crypto_utils::secure_random_bytes(super::SOUNDNESS_BYTES * (n - ct.k as usize)), )?; let new_children = unproven_children .enumerated() @@ -588,6 +604,13 @@ fn step4_simulated_threshold_conj( } } +#[cfg(not(feature = "std"))] +fn step4_simulated_threshold_conj( + _ct: CthresholdUnproven, +) -> Result, ProverError> { + Err(ProverError::Unsupported) +} + fn step5_schnorr( us: UnprovenSchnorr, hints_bag: &HintsBag, @@ -615,6 +638,7 @@ fn step5_schnorr( .into(); pt } + #[cfg(feature = "std")] None => { if us.simulated { // Step 5 (simulated leaf -- complete the simulation) @@ -646,6 +670,8 @@ fn step5_schnorr( )) }? } + #[cfg(not(feature = "std"))] + None => return Err(ProverError::Unsupported), }; Ok(Some(res)) } @@ -678,6 +704,7 @@ fn step5_diffie_hellman_tuple( .unwrap_or_else(|| { if dhu.simulated { // Step 5 (simulated leaf -- complete the simulation) + #[cfg(feature = "std")] if let Some(dhu_challenge) = dhu.challenge_opt.clone() { let (fm, sm) = dht_protocol::interactive_prover::simulate( &dhu.proposition, @@ -693,7 +720,12 @@ fn step5_diffie_hellman_tuple( } else { Err(ProverError::SimulatedLeafWithoutChallenge) } + #[cfg(not(feature = "std"))] + return Err(ProverError::Unsupported); + } else { + #[cfg(feature = "std")] + { // Step 6 -- compute the commitment let (r, fm) = dht_protocol::interactive_prover::first_message(&dhu.proposition); @@ -703,6 +735,11 @@ fn step5_diffie_hellman_tuple( ..dhu.clone() } .into()) + } + #[cfg(not(feature = "std"))] + { + Err(ProverError::Unsupported) + } } }); Ok(Some(res?)) @@ -919,9 +956,19 @@ fn step9_real_schnorr( } } None => { - let bs = - dlog_group::random_scalar_in_group_range(crypto_utils::secure_rng()).into(); - SecondDlogProverMessage { z: bs } + #[cfg(feature = "std")] + { + let bs = + ergotree_ir::sigma_protocol::dlog_group::random_scalar_in_group_range( + crate::sigma_protocol::crypto_utils::secure_rng(), + ) + .into(); + dlog_protocol::SecondDlogProverMessage { z: bs } + } + #[cfg(not(feature = "std"))] + { + return Err(ProverError::Unsupported); + } } }, }; @@ -996,9 +1043,19 @@ fn step9_real_dh_tuple( } } None => { - let z = - dlog_group::random_scalar_in_group_range(crypto_utils::secure_rng()).into(); - SecondDhTupleProverMessage { z } + #[cfg(feature = "std")] + { + let z = + ergotree_ir::sigma_protocol::dlog_group::random_scalar_in_group_range( + super::crypto_utils::secure_rng(), + ) + .into(); + dht_protocol::SecondDhTupleProverMessage { z } + } + #[cfg(not(feature = "std"))] + { + return Err(ProverError::Unsupported); + } } }, }; @@ -1205,6 +1262,7 @@ mod tests { use super::*; use crate::sigma_protocol::private_input::DhTupleProverInput; use crate::sigma_protocol::private_input::DlogProverInput; + use core::convert::TryFrom; use ergotree_ir::mir::atleast::Atleast; use ergotree_ir::mir::collection::Collection; use ergotree_ir::mir::constant::Constant; @@ -1215,7 +1273,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; #[test] fn test_prove_true_prop() { diff --git a/ergotree-interpreter/src/sigma_protocol/prover/hint.rs b/ergotree-interpreter/src/sigma_protocol/prover/hint.rs index 5e59d9847..eadd08940 100644 --- a/ergotree-interpreter/src/sigma_protocol/prover/hint.rs +++ b/ergotree-interpreter/src/sigma_protocol/prover/hint.rs @@ -1,5 +1,6 @@ //! Hints for a prover which helps the prover to prove a statement. +use alloc::vec::Vec; use derive_more::From; use ergotree_ir::sigma_protocol::sigma_boolean::SigmaBoolean; diff --git a/ergotree-interpreter/src/sigma_protocol/prover/prover_result.rs b/ergotree-interpreter/src/sigma_protocol/prover/prover_result.rs index be47c51ea..186222472 100644 --- a/ergotree-interpreter/src/sigma_protocol/prover/prover_result.rs +++ b/ergotree-interpreter/src/sigma_protocol/prover/prover_result.rs @@ -1,4 +1,7 @@ //! ProverResult +use alloc::string::String; +use alloc::string::ToString; +use alloc::vec::Vec; use ergotree_ir::chain::context_extension::ContextExtension; use ergotree_ir::serialization::sigma_byte_reader::SigmaByteRead; use ergotree_ir::serialization::sigma_byte_writer::SigmaByteWrite; @@ -6,7 +9,7 @@ use ergotree_ir::serialization::SigmaParsingError; use ergotree_ir::serialization::SigmaSerializable; use ergotree_ir::serialization::SigmaSerializeResult; -use std::convert::TryFrom; +use core::convert::TryFrom; /// Serialized proof generated by ['Prover'] #[derive(PartialEq, Eq, Hash, Debug, Clone)] diff --git a/ergotree-interpreter/src/sigma_protocol/sig_serializer.rs b/ergotree-interpreter/src/sigma_protocol/sig_serializer.rs index 0fada38dc..c6e296425 100644 --- a/ergotree-interpreter/src/sigma_protocol/sig_serializer.rs +++ b/ergotree-interpreter/src/sigma_protocol/sig_serializer.rs @@ -1,6 +1,6 @@ //! Serialization of proof tree signatures -use std::convert::TryInto; +use core::convert::TryInto; use super::gf2_192::gf2_192poly_from_byte_array; use super::prover::ProofBytes; @@ -16,6 +16,8 @@ use crate::sigma_protocol::Challenge; use crate::sigma_protocol::GroupSizedBytes; use crate::sigma_protocol::UncheckedSchnorr; +use alloc::boxed::Box; +use alloc::vec::Vec; use ergotree_ir::serialization::sigma_byte_reader; use ergotree_ir::serialization::sigma_byte_reader::SigmaByteRead; use ergotree_ir::serialization::sigma_byte_writer::SigmaByteWrite; @@ -47,7 +49,7 @@ fn sig_write_bytes( node: &UncheckedTree, w: &mut W, write_challenges: bool, -) -> Result<(), std::io::Error> { +) -> Result<(), core2::io::Error> { if write_challenges { node.challenge().sigma_serialize(w)?; } @@ -287,7 +289,7 @@ pub enum SigParsingError { #[cfg(test)] #[allow(clippy::unwrap_used)] mod test { - use std::io::Cursor; + use core2::io::Cursor; use ergotree_ir::serialization::{ constant_store::ConstantStore, sigma_byte_reader::SigmaByteReader, diff --git a/ergotree-interpreter/src/sigma_protocol/unchecked_tree.rs b/ergotree-interpreter/src/sigma_protocol/unchecked_tree.rs index 08b70749e..48d7841ff 100644 --- a/ergotree-interpreter/src/sigma_protocol/unchecked_tree.rs +++ b/ergotree-interpreter/src/sigma_protocol/unchecked_tree.rs @@ -1,5 +1,6 @@ //! Unchecked proof tree types +use alloc::vec::Vec; use ergo_chain_types::Base16EncodedBytes; use ergotree_ir::sigma_protocol::sigma_boolean::ProveDhTuple; use ergotree_ir::sigma_protocol::sigma_boolean::ProveDlog; @@ -332,7 +333,7 @@ impl ProofTreeConjecture for UncheckedConjecture { #[cfg(feature = "arbitrary")] #[allow(clippy::unwrap_used)] mod arbitrary { - use std::convert::TryInto; + use core::convert::TryInto; use crate::sigma_protocol::gf2_192::gf2_192poly_from_byte_array; diff --git a/ergotree-interpreter/src/sigma_protocol/unproven_tree.rs b/ergotree-interpreter/src/sigma_protocol/unproven_tree.rs index d07b61f05..b6de29614 100644 --- a/ergotree-interpreter/src/sigma_protocol/unproven_tree.rs +++ b/ergotree-interpreter/src/sigma_protocol/unproven_tree.rs @@ -10,6 +10,7 @@ use super::wscalar::Wscalar; use super::{dlog_protocol::FirstDlogProverMessage, Challenge, FirstProverMessage}; use crate::sigma_protocol::proof_tree::ProofTreeLeaf; use crate::sigma_protocol::SOUNDNESS_BYTES; +use alloc::vec::Vec; use ergotree_ir::sigma_protocol::sigma_boolean::cand::Cand; use ergotree_ir::sigma_protocol::sigma_boolean::cor::Cor; use ergotree_ir::sigma_protocol::sigma_boolean::cthreshold::Cthreshold; @@ -395,11 +396,13 @@ impl UnprovenDhTuple { /// Please note that "0" prefix is for a crypto tree. There are several kinds of trees during evaluation. /// Initial mixed tree (ergoTree) would have another prefix. #[derive(PartialEq, Eq, Debug, Clone)] -#[cfg(feature = "json")] -#[derive(serde::Serialize, serde::Deserialize)] -#[serde( - try_from = "crate::json::hint::NodePositionJson", - into = "crate::json::hint::NodePositionJson" +#[cfg_attr( + feature = "json", + derive(serde::Serialize, serde::Deserialize), + serde( + try_from = "crate::json::hint::NodePositionJson", + into = "crate::json::hint::NodePositionJson" + ) )] #[cfg_attr(feature = "arbitrary", derive(proptest_derive::Arbitrary))] pub struct NodePosition { diff --git a/ergotree-interpreter/src/sigma_protocol/verifier.rs b/ergotree-interpreter/src/sigma_protocol/verifier.rs index a08569369..64202fcc6 100644 --- a/ergotree-interpreter/src/sigma_protocol/verifier.rs +++ b/ergotree-interpreter/src/sigma_protocol/verifier.rs @@ -172,7 +172,7 @@ impl Verifier for TestVerifier {} #[cfg(test)] #[cfg(feature = "arbitrary")] mod tests { - use std::convert::TryFrom; + use core::convert::TryFrom; use crate::sigma_protocol::private_input::{DhTupleProverInput, DlogProverInput, PrivateInput}; use crate::sigma_protocol::prover::hint::HintsBag; diff --git a/ergotree-interpreter/src/sigma_protocol/wscalar.rs b/ergotree-interpreter/src/sigma_protocol/wscalar.rs index 9aee5bbd5..28634fb1c 100644 --- a/ergotree-interpreter/src/sigma_protocol/wscalar.rs +++ b/ergotree-interpreter/src/sigma_protocol/wscalar.rs @@ -1,9 +1,9 @@ //! Wrapper for Scalar //! mainly for Arbitrary impl and JSON encoding -use std::array::TryFromSliceError; -use std::convert::TryFrom; -use std::fmt::Formatter; +use core::array::TryFromSliceError; +use core::convert::TryFrom; +use core::fmt::Formatter; use derive_more::From; use derive_more::Into; @@ -72,8 +72,8 @@ impl TryFrom for Wscalar { } } -impl std::fmt::Debug for Wscalar { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Debug for Wscalar { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { f.write_str("Wscalar:")?; f.write_str(&base16::encode_lower(&(*self.0.to_bytes()))) } diff --git a/ergotree-interpreter/tests/signing_spec_tests.rs b/ergotree-interpreter/tests/signing_spec_tests.rs index 04b69bceb..394f55511 100644 --- a/ergotree-interpreter/tests/signing_spec_tests.rs +++ b/ergotree-interpreter/tests/signing_spec_tests.rs @@ -13,7 +13,7 @@ use ergotree_ir::sigma_protocol::sigma_boolean::{ProveDhTuple, SigmaProp}; use ergotree_ir::types::stype::SType; use num_bigint::BigUint; use sigma_test_util::force_any_val; -use std::convert::TryInto; +use core::convert::TryInto; #[test] fn sig_test_vector_provedlog() { From 4a2db23042375134a6af95eec73bba8930df7091 Mon Sep 17 00:00:00 2001 From: Kamal Ahmad Date: Sun, 24 Nov 2024 11:01:09 +0500 Subject: [PATCH 11/16] Move ContextExtension serde impl to ergotree-ir --- ergo-lib/Cargo.toml | 28 ++-- ergo-lib/src/chain/json.rs | 1 - ergo-lib/src/chain/json/context_extension.rs | 151 ------------------ ergo-lib/src/chain/json/transaction.rs | 84 ++++++++++ ergo-lib/src/chain/transaction/input.rs | 13 +- .../chain/transaction/input/prover_result.rs | 6 +- .../transaction/input/prover_result/json.rs | 6 +- ergotree-ir/src/chain/context_extension.rs | 50 +++++- ergotree-ir/src/chain/json.rs | 1 - 9 files changed, 154 insertions(+), 186 deletions(-) delete mode 100644 ergo-lib/src/chain/json/context_extension.rs diff --git a/ergo-lib/Cargo.toml b/ergo-lib/Cargo.toml index 21efdbaaa..be79c81a9 100644 --- a/ergo-lib/Cargo.toml +++ b/ergo-lib/Cargo.toml @@ -6,9 +6,7 @@ authors = ["Denys Zadorozhnyi "] repository.workspace = true edition.workspace = true description = "ErgoTree interpreter and wallet-like features for Ergo" -exclude = [ - "proptest-regressions/*" -] +exclude = ["proptest-regressions/*"] [lib] crate-type = ["cdylib", "rlib"] @@ -20,9 +18,9 @@ ergo-chain-types = { workspace = true } ergotree-ir = { workspace = true } ergotree-interpreter = { workspace = true } ergo-nipopow = { workspace = true } -ergoscript-compiler = { workspace = true, optional = true} +ergoscript-compiler = { workspace = true, optional = true } ergo-merkle-tree = { workspace = true } -ergo-rest = { workspace = true, optional = true} +ergo-rest = { workspace = true, optional = true } indexmap = { workspace = true } base16 = { workspace = true } serde = { workspace = true, optional = true } @@ -31,7 +29,7 @@ thiserror = { workspace = true } derive_more = { workspace = true } bounded-vec = { workspace = true } num-bigint = { workspace = true, features = ["serde"] } -proptest-derive = {workspace = true, optional = true } +proptest-derive = { workspace = true, optional = true } k256 = { workspace = true } sha2 = { workspace = true } hmac = { version = "0.12" } @@ -40,16 +38,28 @@ rand = { workspace = true } bitvec = { workspace = true, optional = true } unicode-normalization = "0.1.19" lazy_static = { workspace = true } -proptest = { workspace = true , optional = true } +proptest = { workspace = true, optional = true } serde_with = { workspace = true, optional = true } itertools = { workspace = true } [features] default = ["json"] -json = ["serde", "serde_json", "serde_with", "bounded-vec/serde"] +json = [ + "serde", + "serde_json", + "serde_with", + "bounded-vec/serde", + "ergotree-ir/json", +] compiler = ["ergoscript-compiler"] -arbitrary = ["proptest", "proptest-derive", "ergotree-ir/arbitrary", "ergo-chain-types/arbitrary", "ergotree-interpreter/arbitrary"] +arbitrary = [ + "proptest", + "proptest-derive", + "ergotree-ir/arbitrary", + "ergo-chain-types/arbitrary", + "ergotree-interpreter/arbitrary", +] mnemonic_gen = ["bitvec"] rest = ["ergo-rest"] diff --git a/ergo-lib/src/chain/json.rs b/ergo-lib/src/chain/json.rs index 211832f14..177f927ff 100644 --- a/ergo-lib/src/chain/json.rs +++ b/ergo-lib/src/chain/json.rs @@ -4,7 +4,6 @@ use serde::{Deserialize, Serialize}; use ergotree_interpreter::sigma_protocol::prover::ProofBytes; -pub(crate) mod context_extension; pub(crate) mod hint; pub(crate) mod parameters; pub(crate) mod transaction; diff --git a/ergo-lib/src/chain/json/context_extension.rs b/ergo-lib/src/chain/json/context_extension.rs deleted file mode 100644 index fe2c85af5..000000000 --- a/ergo-lib/src/chain/json/context_extension.rs +++ /dev/null @@ -1,151 +0,0 @@ -use ergotree_ir::chain::context_extension::ContextExtension; -use ergotree_ir::{mir::constant::Constant, serialization::SigmaSerializable}; -use indexmap::IndexMap; -use serde::{ser::SerializeMap, Deserialize, Serialize}; - -#[cfg_attr( - feature = "json", - derive(Deserialize), - serde(try_from = "indexmap::IndexMap"), - serde(remote = "ContextExtension") -)] -#[derive(Debug, PartialEq, Eq, Clone)] -pub(crate) struct ContextExtensionSerde { - values: IndexMap, -} - -#[cfg(feature = "json")] -impl Serialize for ContextExtensionSerde { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - use serde::ser::Error; - let mut map = serializer.serialize_map(Some(self.values.len()))?; - for (k, v) in &self.values { - map.serialize_entry( - &format!("{}", k), - &base16::encode_lower(&v.sigma_serialize_bytes().map_err(Error::custom)?), - )?; - } - map.end() - } -} - -impl From for ContextExtensionSerde { - fn from(ce: ContextExtension) -> Self { - ContextExtensionSerde { values: ce.values } - } -} - -#[cfg(test)] -#[allow(clippy::unwrap_used)] -mod tests { - use ergo_chain_types::Digest32; - - use crate::chain::transaction::Transaction; - - use super::*; - - #[test] - fn parse_empty_context_extension() { - let mut de = serde_json::Deserializer::from_str("{}"); - let c: ContextExtension = ContextExtensionSerde::deserialize(&mut de).unwrap(); - assert_eq!(c, ContextExtension::empty()); - } - - #[test] - fn parse_context_extension() { - let json = r#" - {"1" :"05b0b5cad8e6dbaef44a", "3":"048ce5d4e505"} - "#; - let mut de = serde_json::Deserializer::from_str(json); - let c: ContextExtension = ContextExtensionSerde::deserialize(&mut de).unwrap(); - assert_eq!(c.values.len(), 2); - assert!(c.values.get(&1u8).is_some()); - assert!(c.values.get(&3u8).is_some()); - } - - #[test] - fn item_order_preservation_685() { - let tx_json = r#" -{ - "id" : "c8520befd345ff40fcf244b44ffe8cea29c8b116b174cfaf4f2a521604d531a4", - "inputs" : [ - { - "boxId" : "59f2856068c56264d290520043044ace138a3a80d414748d0e4dcd0806188546", - "spendingProof" : { - "proofBytes" : "", - "extension" : { - "0" : "04c60f", - "5" : "0514", - "10" : "0eee03101808cd0279aed8dea2b2a25316d5d49d13bf51c0b2c1dc696974bb4b0c07b5894e998e56040005e0e0a447040404060402040004000e201d5afc59838920bb5ef2a8f9d63825a55b1d48e269d7cecee335d637c3ff5f3f0e20003bd19d0187117f130b62e1bcab0939929ff5c7709f843c5c4dd158949285d005e201058c85a2010514040404c60f06010104d00f05e0e0a44704c60f0e691005040004000e36100204a00b08cd0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ea02d192a39a8cc7a701730073011001020402d19683030193a38cc7b2a57300000193c2b2a57301007473027303830108cdeeac93b1a57304050005000580ade2040100d803d6017300d602b2a4730100d6037302eb027201d195ed93b1a4730393b1db630872027304d804d604db63087202d605b2a5730500d606b2db63087205730600d6077e8c72060206edededededed938cb2720473070001730893c27205d07201938c72060173099272077e730a06927ec172050699997ec1a7069d9c72077e730b067e730c067e720306909c9c7e8cb27204730d0002067e7203067e730e069c9a7207730f9a9c7ec17202067e7310067e9c73117e7312050690b0ada5d90108639593c272087313c1720873147315d90108599a8c7208018c72080273167317", - "1" : "0e20003bd19d0187117f130b62e1bcab0939929ff5c7709f843c5c4dd158949285d0", - "6" : "0580ade204", - "9" : "0580b48913", - "2" : "05e201", - "7" : "0e201d5afc59838920bb5ef2a8f9d63825a55b1d48e269d7cecee335d637c3ff5f3f", - "3" : "05e0e0a447", - "8" : "0580ade204", - "4" : "058c85a201" - } - } - } - ], - "dataInputs" : [ - ], - "outputs" : [ - { - "boxId" : "0586c90d0cf6a82dab48c6a79500364ddbd6f81705f5032b03aa287de43dc638", - "value" : 94750000, - "ergoTree" : "101808cd0279aed8dea2b2a25316d5d49d13bf51c0b2c1dc696974bb4b0c07b5894e998e56040005e0e0a447040404060402040004000e201d5afc59838920bb5ef2a8f9d63825a55b1d48e269d7cecee335d637c3ff5f3f0e20003bd19d0187117f130b62e1bcab0939929ff5c7709f843c5c4dd158949285d005e201058c85a2010514040404c60f06010104d00f05e0e0a44704c60f0e691005040004000e36100204a00b08cd0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ea02d192a39a8cc7a701730073011001020402d19683030193a38cc7b2a57300000193c2b2a57301007473027303830108cdeeac93b1a57304050005000580ade2040100d803d6017300d602b2a4730100d6037302eb027201d195ed93b1a4730393b1db630872027304d804d604db63087202d605b2a5730500d606b2db63087205730600d6077e8c72060206edededededed938cb2720473070001730893c27205d07201938c72060173099272077e730a06927ec172050699997ec1a7069d9c72077e730b067e730c067e720306909c9c7e8cb27204730d0002067e7203067e730e069c9a7207730f9a9c7ec17202067e7310067e9c73117e7312050690b0ada5d90108639593c272087313c1720873147315d90108599a8c7208018c72080273167317", - "assets" : [ - ], - "creationHeight" : 693475, - "additionalRegisters" : { - - }, - "transactionId" : "c8520befd345ff40fcf244b44ffe8cea29c8b116b174cfaf4f2a521604d531a4", - "index" : 0 - }, - { - "boxId" : "4b99c2ef8496a491d176ecaf789d9e1d9aad0c2bf3e70b32e8bad73f48c722b9", - "value" : 250000, - "ergoTree" : "100e04000500059a0505d00f04020404040608cd03c6543ac8e8059748b1c6209ee419dd49a19ffaf5712a2f34a9412016a3a1d96708cd035b736bebf0c5393f78329f6894af84d1864c7496cc65ddc250ef60cdd75df52008cd021b63e19ab452c84cdc6687242e8494957b1f11e3750c8c184a8425f8a8171d9b05060580ade2040580a8d6b907040ad806d601b2a5730000d602b0a47301d9010241639a8c720201c18c720202d6039d9c730272027303d604b2a5730400d605b2a5730500d606b2a5730600d1968306019683020193c17201720393c27201d073079683020193c17204720393c27204d073089683020193c17205720393c27205d073099683020192c17206999972029c730a7203730b93c2a7c27206927202730c93b1a5730d", - "assets" : [ - ], - "creationHeight" : 693475, - "additionalRegisters" : { - - }, - "transactionId" : "c8520befd345ff40fcf244b44ffe8cea29c8b116b174cfaf4f2a521604d531a4", - "index" : 1 - }, - { - "boxId" : "00ddbeb981c0b08536f72ea41e07a25adbf7bf104ee59b865619a21676e64715", - "value" : 5000000, - "ergoTree" : "1005040004000e36100204a00b08cd0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ea02d192a39a8cc7a701730073011001020402d19683030193a38cc7b2a57300000193c2b2a57301007473027303830108cdeeac93b1a57304", - "assets" : [ - ], - "creationHeight" : 693475, - "additionalRegisters" : { - - }, - "transactionId" : "c8520befd345ff40fcf244b44ffe8cea29c8b116b174cfaf4f2a521604d531a4", - "index" : 2 - } - ], - "size" : 1562 - } - "#; - let tx: Transaction = serde_json::from_str(tx_json).unwrap(); - assert_eq!( - tx.id(), - Digest32::try_from( - "c8520befd345ff40fcf244b44ffe8cea29c8b116b174cfaf4f2a521604d531a4".to_string() - ) - .unwrap() - .into() - ); - } -} diff --git a/ergo-lib/src/chain/json/transaction.rs b/ergo-lib/src/chain/json/transaction.rs index 27a1d3fa3..0b411df57 100644 --- a/ergo-lib/src/chain/json/transaction.rs +++ b/ergo-lib/src/chain/json/transaction.rs @@ -110,6 +110,7 @@ impl TryFrom for Transaction { mod tests { use crate::chain::transaction::unsigned::UnsignedTransaction; use crate::chain::transaction::Transaction; + use ergo_chain_types::Digest32; use proptest::prelude::*; proptest! { @@ -133,4 +134,87 @@ mod tests { } } + + #[test] + fn item_order_preservation_685() { + let tx_json = r#" +{ + "id" : "c8520befd345ff40fcf244b44ffe8cea29c8b116b174cfaf4f2a521604d531a4", + "inputs" : [ + { + "boxId" : "59f2856068c56264d290520043044ace138a3a80d414748d0e4dcd0806188546", + "spendingProof" : { + "proofBytes" : "", + "extension" : { + "0" : "04c60f", + "5" : "0514", + "10" : "0eee03101808cd0279aed8dea2b2a25316d5d49d13bf51c0b2c1dc696974bb4b0c07b5894e998e56040005e0e0a447040404060402040004000e201d5afc59838920bb5ef2a8f9d63825a55b1d48e269d7cecee335d637c3ff5f3f0e20003bd19d0187117f130b62e1bcab0939929ff5c7709f843c5c4dd158949285d005e201058c85a2010514040404c60f06010104d00f05e0e0a44704c60f0e691005040004000e36100204a00b08cd0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ea02d192a39a8cc7a701730073011001020402d19683030193a38cc7b2a57300000193c2b2a57301007473027303830108cdeeac93b1a57304050005000580ade2040100d803d6017300d602b2a4730100d6037302eb027201d195ed93b1a4730393b1db630872027304d804d604db63087202d605b2a5730500d606b2db63087205730600d6077e8c72060206edededededed938cb2720473070001730893c27205d07201938c72060173099272077e730a06927ec172050699997ec1a7069d9c72077e730b067e730c067e720306909c9c7e8cb27204730d0002067e7203067e730e069c9a7207730f9a9c7ec17202067e7310067e9c73117e7312050690b0ada5d90108639593c272087313c1720873147315d90108599a8c7208018c72080273167317", + "1" : "0e20003bd19d0187117f130b62e1bcab0939929ff5c7709f843c5c4dd158949285d0", + "6" : "0580ade204", + "9" : "0580b48913", + "2" : "05e201", + "7" : "0e201d5afc59838920bb5ef2a8f9d63825a55b1d48e269d7cecee335d637c3ff5f3f", + "3" : "05e0e0a447", + "8" : "0580ade204", + "4" : "058c85a201" + } + } + } + ], + "dataInputs" : [ + ], + "outputs" : [ + { + "boxId" : "0586c90d0cf6a82dab48c6a79500364ddbd6f81705f5032b03aa287de43dc638", + "value" : 94750000, + "ergoTree" : "101808cd0279aed8dea2b2a25316d5d49d13bf51c0b2c1dc696974bb4b0c07b5894e998e56040005e0e0a447040404060402040004000e201d5afc59838920bb5ef2a8f9d63825a55b1d48e269d7cecee335d637c3ff5f3f0e20003bd19d0187117f130b62e1bcab0939929ff5c7709f843c5c4dd158949285d005e201058c85a2010514040404c60f06010104d00f05e0e0a44704c60f0e691005040004000e36100204a00b08cd0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ea02d192a39a8cc7a701730073011001020402d19683030193a38cc7b2a57300000193c2b2a57301007473027303830108cdeeac93b1a57304050005000580ade2040100d803d6017300d602b2a4730100d6037302eb027201d195ed93b1a4730393b1db630872027304d804d604db63087202d605b2a5730500d606b2db63087205730600d6077e8c72060206edededededed938cb2720473070001730893c27205d07201938c72060173099272077e730a06927ec172050699997ec1a7069d9c72077e730b067e730c067e720306909c9c7e8cb27204730d0002067e7203067e730e069c9a7207730f9a9c7ec17202067e7310067e9c73117e7312050690b0ada5d90108639593c272087313c1720873147315d90108599a8c7208018c72080273167317", + "assets" : [ + ], + "creationHeight" : 693475, + "additionalRegisters" : { + + }, + "transactionId" : "c8520befd345ff40fcf244b44ffe8cea29c8b116b174cfaf4f2a521604d531a4", + "index" : 0 + }, + { + "boxId" : "4b99c2ef8496a491d176ecaf789d9e1d9aad0c2bf3e70b32e8bad73f48c722b9", + "value" : 250000, + "ergoTree" : "100e04000500059a0505d00f04020404040608cd03c6543ac8e8059748b1c6209ee419dd49a19ffaf5712a2f34a9412016a3a1d96708cd035b736bebf0c5393f78329f6894af84d1864c7496cc65ddc250ef60cdd75df52008cd021b63e19ab452c84cdc6687242e8494957b1f11e3750c8c184a8425f8a8171d9b05060580ade2040580a8d6b907040ad806d601b2a5730000d602b0a47301d9010241639a8c720201c18c720202d6039d9c730272027303d604b2a5730400d605b2a5730500d606b2a5730600d1968306019683020193c17201720393c27201d073079683020193c17204720393c27204d073089683020193c17205720393c27205d073099683020192c17206999972029c730a7203730b93c2a7c27206927202730c93b1a5730d", + "assets" : [ + ], + "creationHeight" : 693475, + "additionalRegisters" : { + + }, + "transactionId" : "c8520befd345ff40fcf244b44ffe8cea29c8b116b174cfaf4f2a521604d531a4", + "index" : 1 + }, + { + "boxId" : "00ddbeb981c0b08536f72ea41e07a25adbf7bf104ee59b865619a21676e64715", + "value" : 5000000, + "ergoTree" : "1005040004000e36100204a00b08cd0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ea02d192a39a8cc7a701730073011001020402d19683030193a38cc7b2a57300000193c2b2a57301007473027303830108cdeeac93b1a57304", + "assets" : [ + ], + "creationHeight" : 693475, + "additionalRegisters" : { + + }, + "transactionId" : "c8520befd345ff40fcf244b44ffe8cea29c8b116b174cfaf4f2a521604d531a4", + "index" : 2 + } + ], + "size" : 1562 + } + "#; + let tx: Transaction = serde_json::from_str(tx_json).unwrap(); + assert_eq!( + tx.id(), + Digest32::try_from( + "c8520befd345ff40fcf244b44ffe8cea29c8b116b174cfaf4f2a521604d531a4".to_string() + ) + .unwrap() + .into() + ); + } } diff --git a/ergo-lib/src/chain/transaction/input.rs b/ergo-lib/src/chain/transaction/input.rs index 21f194cc9..65c163088 100644 --- a/ergo-lib/src/chain/transaction/input.rs +++ b/ergo-lib/src/chain/transaction/input.rs @@ -11,8 +11,6 @@ use ergotree_ir::serialization::SigmaParsingError; use ergotree_ir::serialization::SigmaSerializable; use ergotree_ir::serialization::SigmaSerializeResult; -#[cfg(feature = "json")] -use crate::chain::json::context_extension::ContextExtensionSerde; use crate::wallet::box_selector::ErgoBoxId; #[cfg(feature = "json")] use serde::ser::SerializeStruct; @@ -30,11 +28,7 @@ pub struct UnsignedInput { #[cfg_attr(feature = "json", serde(rename = "boxId"))] pub box_id: BoxId, /// user-defined variables to be put into context - #[cfg_attr( - feature = "json", - serde(rename = "extension",), - serde(with = "crate::chain::json::context_extension::ContextExtensionSerde") - )] + #[cfg_attr(feature = "json", serde(rename = "extension",))] pub extension: ContextExtension, } @@ -46,10 +40,7 @@ impl Serialize for UnsignedInput { { let mut s = serializer.serialize_struct("UnsignedInput", 2)?; s.serialize_field("boxId", &self.box_id)?; - s.serialize_field( - "extension", - &ContextExtensionSerde::from(self.extension.clone()), - )?; + s.serialize_field("extension", &self.extension)?; s.end() } } diff --git a/ergo-lib/src/chain/transaction/input/prover_result.rs b/ergo-lib/src/chain/transaction/input/prover_result.rs index 6aa0be88d..a917b5d96 100644 --- a/ergo-lib/src/chain/transaction/input/prover_result.rs +++ b/ergo-lib/src/chain/transaction/input/prover_result.rs @@ -23,11 +23,7 @@ pub struct ProverResult { )] pub proof: ProofBytes, /// user-defined variables to be put into context - #[cfg_attr( - feature = "json", - serde(rename = "extension"), - serde(with = "crate::chain::json::context_extension::ContextExtensionSerde") - )] + #[cfg_attr(feature = "json", serde(rename = "extension"))] pub extension: ContextExtension, } 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 b9aae483a..56a3e8ccf 100644 --- a/ergo-lib/src/chain/transaction/input/prover_result/json.rs +++ b/ergo-lib/src/chain/transaction/input/prover_result/json.rs @@ -1,6 +1,5 @@ use std::str::FromStr; -use crate::chain::json::context_extension::ContextExtensionSerde; use ergotree_ir::chain::context_extension::ContextExtension; use serde::ser::SerializeStruct; use serde::Serialize; @@ -14,10 +13,7 @@ impl Serialize for ProverResult { { let mut s = serializer.serialize_struct("ProverResult", 2)?; s.serialize_field("proofBytes", &String::from(self.proof.clone()))?; - s.serialize_field( - "extension", - &ContextExtensionSerde::from(self.extension.clone()), - )?; + s.serialize_field("extension", &self.extension)?; s.end() } } diff --git a/ergotree-ir/src/chain/context_extension.rs b/ergotree-ir/src/chain/context_extension.rs index 422ee38b5..a4a90bebe 100644 --- a/ergotree-ir/src/chain/context_extension.rs +++ b/ergotree-ir/src/chain/context_extension.rs @@ -9,13 +9,18 @@ use alloc::string::String; use alloc::vec::Vec; use core::convert::TryFrom; use core::fmt; -use core::hash::Hasher; +use core::hash::BuildHasher; use thiserror::Error; use super::IndexMap; /// User-defined variables to be put into context #[derive(Debug, PartialEq, Eq, Clone)] +#[cfg_attr( + feature = "json", + derive(serde::Deserialize), + serde(try_from = "indexmap::IndexMap") +)] pub struct ContextExtension { /// key-value pairs of variable id and it's value pub values: IndexMap, @@ -65,7 +70,7 @@ impl SigmaSerializable for ContextExtension { pub struct ConstantParsingError(pub String); // for JSON encoding in ergo-lib -impl TryFrom> for ContextExtension { +impl TryFrom> for ContextExtension { type Error = ConstantParsingError; fn try_from(values_str: indexmap::IndexMap) -> Result { let values = values_str.iter().try_fold( @@ -96,6 +101,25 @@ impl TryFrom> for ContextExtens } } +#[cfg(feature = "json")] +impl serde::Serialize for ContextExtension { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + use serde::ser::Error; + use serde::ser::SerializeMap; + let mut map = serializer.serialize_map(Some(self.values.len()))?; + for (k, v) in &self.values { + map.serialize_entry( + &format!("{}", k), + &base16::encode_lower(&v.sigma_serialize_bytes().map_err(Error::custom)?), + )?; + } + map.end() + } +} + #[cfg(feature = "arbitrary")] mod arbitrary { use super::*; @@ -122,7 +146,7 @@ mod arbitrary { #[cfg(test)] #[cfg(feature = "arbitrary")] -#[allow(clippy::panic)] +#[allow(clippy::panic, clippy::unwrap_used)] mod tests { use super::*; use crate::serialization::sigma_serialize_roundtrip; @@ -135,4 +159,24 @@ mod tests { prop_assert_eq![sigma_serialize_roundtrip(&v), v]; } } + #[cfg(feature = "json")] + mod json { + use super::*; + #[test] + fn parse_empty_context_extension() { + let c: ContextExtension = serde_json::from_str("{}").unwrap(); + assert_eq!(c, ContextExtension::empty()); + } + + #[test] + fn parse_context_extension() { + let json = r#" + {"1" :"05b0b5cad8e6dbaef44a", "3":"048ce5d4e505"} + "#; + let c: ContextExtension = serde_json::from_str(json).unwrap(); + assert_eq!(c.values.len(), 2); + assert!(c.values.get(&1u8).is_some()); + assert!(c.values.get(&3u8).is_some()); + } + } } diff --git a/ergotree-ir/src/chain/json.rs b/ergotree-ir/src/chain/json.rs index 82a0f9928..dd877d0d9 100644 --- a/ergotree-ir/src/chain/json.rs +++ b/ergotree-ir/src/chain/json.rs @@ -4,7 +4,6 @@ use core::fmt; use core::marker::PhantomData; use core::str::FromStr; - use serde::de; use serde::de::MapAccess; use serde::de::Visitor; From 51c632d05058e1f3ccde339502456f190b01c792 Mon Sep 17 00:00:00 2001 From: Kamal Ahmad Date: Mon, 25 Nov 2024 12:55:32 +0500 Subject: [PATCH 12/16] ergotree-ir, ergotree-interpreter: Fix serde support for no_std --- Cargo.toml | 18 ++++++++++-------- ergo-chain-types/Cargo.toml | 4 ++-- .../src/json/autolykos_solution.rs | 5 ++++- ergo-chain-types/src/json/votes.rs | 3 ++- ergotree-interpreter/Cargo.toml | 2 +- ergotree-interpreter/src/json/hint.rs | 7 +++++-- ergotree-ir/Cargo.toml | 1 - ergotree-ir/src/chain/context_extension.rs | 2 +- 8 files changed, 25 insertions(+), 17 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 00d5b88b1..c0c709386 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,9 +32,9 @@ ergotree-ir = { version = "^0.28.0", path = "./ergotree-ir", default-features = ergo-chain-types = { version = "^0.15.0", path = "./ergo-chain-types", default-features = false } sigma-test-util = { version = "^0.3.0", path = "./sigma-test-util" } ergoscript-compiler = { version = "^0.24.0", path = "./ergoscript-compiler" } -ergotree-interpreter = { version = "^0.28.0", path = "./ergotree-interpreter" } +ergotree-interpreter = { version = "^0.28.0", path = "./ergotree-interpreter", default-features = false } ergo-nipopow = { version = "^0.15", path = "./ergo-nipopow" } -ergo-merkle-tree = { version = "^0.15.0", path = "./ergo-merkle-tree" } +ergo-merkle-tree = { version = "^0.15.0", path = "./ergo-merkle-tree", default-features = false } ergo-rest = { version = "^0.13.0", path = "./ergo-rest" } ergo-lib = { version = "^0.28.0", path = "./ergo-lib" } k256 = { version = "0.13.1", default-features = false, features = [ @@ -66,13 +66,15 @@ lazy_static = { version = "1.4", features = ["spin_no_std"] } bs58 = { version = "0.4.0", default-features = false, features = ["alloc"] } base16 = { version = "0.2.1", default-features = false, features = ["alloc"] } base64 = { version = "0.13.0", default-features = false, features = ["alloc"] } -indexmap = { version = "2.6.0", default-features = false } #TODO: enable std conditionally -serde = { version = "1.0", features = ["derive"] } -serde_json = { version = "1.0", features = [ +indexmap = { version = "2.6.0", default-features = false } +serde = { version = "1.0", default-features = false, features = ["derive"] } +serde_json = { version = "1.0", default-features = false, features = [ "arbitrary_precision", - "preserve_order", ] } -serde_with = { version = "1.9.1", features = ["json"] } +serde_with = { version = "3.11.0", default-features = false, features = [ + "json", + "macros", +] } rand = "0.8.5" bytes = { version = "1.1", default-features = false } byteorder = "1" @@ -83,7 +85,7 @@ tokio-util = { version = "0.6.9", features = ["codec"] } bounded-integer = { version = "^0.5", features = ["types"] } url = "~2.2" getrandom = { version = "0.2.7" } -itertools = "0.10.3" +itertools = { version = "0.10.3", default-features = false } miette = { version = "5", features = ["fancy"] } hashbrown = { version = "0.14.3", features = ["serde"] } core2 = { version = "0.4.0", default-features = false, features = ["alloc"] } diff --git a/ergo-chain-types/Cargo.toml b/ergo-chain-types/Cargo.toml index 1b5085612..e00b6f556 100644 --- a/ergo-chain-types/Cargo.toml +++ b/ergo-chain-types/Cargo.toml @@ -30,7 +30,7 @@ core2 = { workspace = true } [features] default = ["std", "json"] arbitrary = ["proptest", "proptest-derive", "std"] -json = ["serde", "serde_json", "serde_with", "std"] -std = ["dep:url", "base16/std", "base64/std"] +json = ["serde", "serde_json", "serde_with"] +std = ["dep:url", "base16/std", "base64/std", "serde/std"] [dev-dependencies] diff --git a/ergo-chain-types/src/json/autolykos_solution.rs b/ergo-chain-types/src/json/autolykos_solution.rs index 4f6ed3308..d39241d3a 100644 --- a/ergo-chain-types/src/json/autolykos_solution.rs +++ b/ergo-chain-types/src/json/autolykos_solution.rs @@ -1,6 +1,9 @@ //! Code to implement `AutolykosSolution` JSON encoding -use std::str::FromStr; +use alloc::string::String; +use alloc::string::ToString; +use alloc::vec::Vec; +use core::str::FromStr; use num_bigint::BigInt; use num_traits::FromPrimitive; diff --git a/ergo-chain-types/src/json/votes.rs b/ergo-chain-types/src/json/votes.rs index 996cc4018..4cfa856e6 100644 --- a/ergo-chain-types/src/json/votes.rs +++ b/ergo-chain-types/src/json/votes.rs @@ -1,6 +1,7 @@ //! Code to implement `Votes` JSON encoding -use std::convert::{TryFrom, TryInto}; +use alloc::vec::Vec; +use core::convert::{TryFrom, TryInto}; use crate::votes::{Votes, VotesError}; use crate::Base16DecodedBytes; diff --git a/ergotree-interpreter/Cargo.toml b/ergotree-interpreter/Cargo.toml index 273e8ba7d..7d0bf6226 100644 --- a/ergotree-interpreter/Cargo.toml +++ b/ergotree-interpreter/Cargo.toml @@ -49,7 +49,7 @@ json = [ "ergo-chain-types/json", ] default = ["json", "std"] -std = ["rand", "miette"] +std = ["rand", "miette", "ergotree-ir/std"] arbitrary = [ "std", "proptest", diff --git a/ergotree-interpreter/src/json/hint.rs b/ergotree-interpreter/src/json/hint.rs index 4c5e91738..513130802 100644 --- a/ergotree-interpreter/src/json/hint.rs +++ b/ergotree-interpreter/src/json/hint.rs @@ -1,6 +1,9 @@ +use alloc::string::String; +use alloc::string::ToString; +use alloc::vec::Vec; use core::convert::TryFrom; -use std::num::ParseIntError; -use std::str::FromStr; +use core::num::ParseIntError; +use core::str::FromStr; use ergo_chain_types::Base16DecodedBytes; use ergotree_ir::sigma_protocol::sigma_boolean::SigmaBoolean; diff --git a/ergotree-ir/Cargo.toml b/ergotree-ir/Cargo.toml index d15747d1d..241e9ff94 100644 --- a/ergotree-ir/Cargo.toml +++ b/ergotree-ir/Cargo.toml @@ -49,7 +49,6 @@ json = [ "serde_json", "serde_with", "bounded-vec/serde", - "std", "ergo-chain-types/json", "indexmap/serde", ] diff --git a/ergotree-ir/src/chain/context_extension.rs b/ergotree-ir/src/chain/context_extension.rs index a4a90bebe..2881fa829 100644 --- a/ergotree-ir/src/chain/context_extension.rs +++ b/ergotree-ir/src/chain/context_extension.rs @@ -19,7 +19,7 @@ use super::IndexMap; #[cfg_attr( feature = "json", derive(serde::Deserialize), - serde(try_from = "indexmap::IndexMap") + serde(try_from = "IndexMap") )] pub struct ContextExtension { /// key-value pairs of variable id and it's value From fa0d0bbc6194d9abd938c40d863b8992c4e5b557 Mon Sep 17 00:00:00 2001 From: Kamal Ahmad Date: Tue, 26 Nov 2024 04:11:13 +0500 Subject: [PATCH 13/16] no_std ergo-lib, make ergo-merkle-tree and ergo-nipopow optional --- Cargo.toml | 4 +- bindings/ergo-lib-c-core/Cargo.toml | 2 +- bindings/ergo-lib-c-core/src/transaction.rs | 4 +- bindings/ergo-lib-wasm/src/transaction.rs | 8 +- ergo-lib/Cargo.toml | 29 +++- ergo-lib/src/chain/contract.rs | 7 +- ergo-lib/src/chain/ergo_box/box_builder.rs | 7 +- ergo-lib/src/chain/json.rs | 2 + ergo-lib/src/chain/json/hint.rs | 7 +- ergo-lib/src/chain/json/parameters.rs | 2 +- ergo-lib/src/chain/json/transaction.rs | 4 +- ergo-lib/src/chain/parameters.rs | 4 +- ergo-lib/src/chain/transaction.rs | 15 +- .../src/chain/transaction/ergo_transaction.rs | 3 +- .../transaction/input/prover_result/json.rs | 4 +- ergo-lib/src/chain/transaction/unsigned.rs | 5 +- ergo-lib/src/lib.rs | 9 ++ ergo-lib/src/wallet.rs | 137 ++++++++++++++++-- ergo-lib/src/wallet/box_selector.rs | 3 +- ergo-lib/src/wallet/box_selector/simple.rs | 10 +- ergo-lib/src/wallet/derivation_path.rs | 8 +- ergo-lib/src/wallet/ext_pub_key.rs | 3 +- ergo-lib/src/wallet/ext_secret_key.rs | 3 +- ergo-lib/src/wallet/miner_fee.rs | 1 + ergo-lib/src/wallet/mnemonic.rs | 1 + ergo-lib/src/wallet/mnemonic_generator.rs | 1 + ergo-lib/src/wallet/multi_sig.rs | 108 +------------- ergo-lib/src/wallet/secret_key.rs | 5 +- ergo-lib/src/wallet/signing.rs | 7 +- ergo-lib/src/wallet/tx_builder.rs | 11 +- ergo-lib/src/wallet/tx_context.rs | 13 +- ergo-merkle-tree/Cargo.toml | 10 +- ergo-nipopow/Cargo.toml | 15 +- ergo-p2p/src/message/handshake.rs | 1 + .../tests/signing_spec_tests.rs | 2 +- .../src/chain/ergo_box/register/value.rs | 1 - ergotree-ir/src/mir/coll_append.rs | 1 - ergotree-ir/src/mir/coll_map.rs | 1 - ergotree-ir/src/mir/coll_size.rs | 1 - ergotree-ir/src/mir/coll_slice.rs | 1 - ergotree-ir/src/mir/create_avl_tree.rs | 1 - ergotree-ir/src/mir/downcast.rs | 1 - ergotree-ir/src/mir/exponentiate.rs | 1 - ergotree-ir/src/mir/multiply_group.rs | 1 - ergotree-ir/src/mir/option_is_defined.rs | 1 - ergotree-ir/src/mir/select_field.rs | 1 - ergotree-ir/src/mir/subst_const.rs | 1 - ergotree-ir/src/mir/upcast.rs | 1 - ergotree-ir/src/pretty_printer.rs | 2 +- ergotree-ir/src/serialization/expr.rs | 2 - ergotree-ir/src/type_check.rs | 1 - ergotree-ir/src/types/stype_param.rs | 1 - 52 files changed, 267 insertions(+), 207 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c0c709386..bcac9a7be 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", branch = "no_std" } # 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..d21362e81 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] @@ -73,3 +78,11 @@ pretty_assertions = { workspace = true } bs58 = { workspace = true } byteorder = { workspace = true } expect-test = { workspace = true } + + +# docs.rs-specific configuration +[package.metadata.docs.rs] +# document all features +all-features = true +# enable docsrs flag, which lets us enable doc_auto_cfg to mark feature-gated functionality in documentation +rustdoc-args = ["--cfg", "docsrs"] 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..e1d987d19 100644 --- a/ergo-lib/src/lib.rs +++ b/ergo-lib/src/lib.rs @@ -1,5 +1,7 @@ //! ErgoTree IR +#![cfg_attr(not(feature = "std"), no_std)] +#![cfg_attr(docsrs, feature(doc_auto_cfg))] // Coding conventions #![forbid(unsafe_code)] #![deny(non_upper_case_globals)] @@ -20,6 +22,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 +37,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..0334957e7 100644 --- a/ergo-lib/src/wallet.rs +++ b/ergo-lib/src/wallet.rs @@ -8,38 +8,48 @@ 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; +#[cfg(feature = "std")] use crate::chain::ergo_state_context::ErgoStateContext; +#[cfg(feature = "std")] use crate::chain::transaction::reduced::ReducedTransaction; +#[cfg(feature = "std")] use crate::chain::transaction::unsigned::UnsignedTransaction; +#[cfg(feature = "std")] use crate::chain::transaction::Input; +#[cfg(feature = "std")] 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; -use self::signing::sign_message; -use self::signing::sign_reduced_transaction; -use self::signing::sign_tx_input; -use self::signing::TransactionContext; +use self::signing::TxSigningError; +#[cfg(feature = "std")] +use self::signing::{ + make_context, sign_message, sign_reduced_transaction, sign_transaction, sign_tx_input, + TransactionContext, +}; /// Wallet pub struct Wallet { @@ -91,6 +101,7 @@ impl Wallet { } /// Signs a transaction + #[cfg(feature = "std")] pub fn sign_transaction( &self, tx_context: TransactionContext, @@ -102,6 +113,7 @@ impl Wallet { } /// Signs a reduced transaction (generating proofs for inputs) + #[cfg(feature = "std")] pub fn sign_reduced_transaction( &self, reduced_tx: ReducedTransaction, @@ -112,6 +124,7 @@ impl Wallet { } /// Generate commitments for Transaction by wallet secrets + #[cfg(feature = "std")] pub fn generate_commitments( &self, tx_context: TransactionContext, @@ -127,6 +140,7 @@ impl Wallet { } /// Generate Commitments for reduced Transaction + #[cfg(feature = "std")] pub fn generate_commitments_for_reduced_transaction( &self, reduced_tx: ReducedTransaction, @@ -147,6 +161,7 @@ impl Wallet { } /// Signs a message + #[cfg(feature = "std")] pub fn sign_message( &self, sigma_tree: SigmaBoolean, @@ -156,6 +171,7 @@ impl Wallet { } /// Signs a transaction input + #[cfg(feature = "std")] pub fn sign_tx_input( &self, input_idx: usize, @@ -178,3 +194,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, diff --git a/ergotree-interpreter/tests/signing_spec_tests.rs b/ergotree-interpreter/tests/signing_spec_tests.rs index 394f55511..85fbedaf3 100644 --- a/ergotree-interpreter/tests/signing_spec_tests.rs +++ b/ergotree-interpreter/tests/signing_spec_tests.rs @@ -1,3 +1,4 @@ +use core::convert::TryInto; use ergotree_interpreter::sigma_protocol::private_input::DlogProverInput; use ergotree_interpreter::sigma_protocol::verifier::{TestVerifier, Verifier}; use ergotree_ir::chain::context::Context; @@ -13,7 +14,6 @@ use ergotree_ir::sigma_protocol::sigma_boolean::{ProveDhTuple, SigmaProp}; use ergotree_ir::types::stype::SType; use num_bigint::BigUint; use sigma_test_util::force_any_val; -use core::convert::TryInto; #[test] fn sig_test_vector_provedlog() { diff --git a/ergotree-ir/src/chain/ergo_box/register/value.rs b/ergotree-ir/src/chain/ergo_box/register/value.rs index 23625a48b..7dbf4a445 100644 --- a/ergotree-ir/src/chain/ergo_box/register/value.rs +++ b/ergotree-ir/src/chain/ergo_box/register/value.rs @@ -1,4 +1,3 @@ - use alloc::string::String; use alloc::string::ToString; use alloc::vec::Vec; diff --git a/ergotree-ir/src/mir/coll_append.rs b/ergotree-ir/src/mir/coll_append.rs index 3cff3d992..054e6b0dd 100644 --- a/ergotree-ir/src/mir/coll_append.rs +++ b/ergotree-ir/src/mir/coll_append.rs @@ -1,6 +1,5 @@ use alloc::boxed::Box; - use crate::serialization::op_code::OpCode; use crate::serialization::sigma_byte_reader::SigmaByteRead; use crate::serialization::sigma_byte_writer::SigmaByteWrite; diff --git a/ergotree-ir/src/mir/coll_map.rs b/ergotree-ir/src/mir/coll_map.rs index 7eab91eb7..a52038e62 100644 --- a/ergotree-ir/src/mir/coll_map.rs +++ b/ergotree-ir/src/mir/coll_map.rs @@ -1,6 +1,5 @@ use alloc::boxed::Box; - use crate::serialization::op_code::OpCode; use crate::serialization::sigma_byte_reader::SigmaByteRead; use crate::serialization::sigma_byte_writer::SigmaByteWrite; diff --git a/ergotree-ir/src/mir/coll_size.rs b/ergotree-ir/src/mir/coll_size.rs index ba1f3ad06..9808d8d67 100644 --- a/ergotree-ir/src/mir/coll_size.rs +++ b/ergotree-ir/src/mir/coll_size.rs @@ -1,6 +1,5 @@ use alloc::boxed::Box; - use crate::serialization::op_code::OpCode; use crate::types::stype::SType; diff --git a/ergotree-ir/src/mir/coll_slice.rs b/ergotree-ir/src/mir/coll_slice.rs index 57eb6a974..bc53d4b34 100644 --- a/ergotree-ir/src/mir/coll_slice.rs +++ b/ergotree-ir/src/mir/coll_slice.rs @@ -1,6 +1,5 @@ use alloc::boxed::Box; - use crate::serialization::op_code::OpCode; use crate::serialization::sigma_byte_reader::SigmaByteRead; use crate::serialization::sigma_byte_writer::SigmaByteWrite; diff --git a/ergotree-ir/src/mir/create_avl_tree.rs b/ergotree-ir/src/mir/create_avl_tree.rs index e0d7db78f..3959b3468 100644 --- a/ergotree-ir/src/mir/create_avl_tree.rs +++ b/ergotree-ir/src/mir/create_avl_tree.rs @@ -2,7 +2,6 @@ use alloc::boxed::Box; - use super::expr::Expr; use crate::has_opcode::HasStaticOpCode; use crate::mir::expr::InvalidArgumentError; diff --git a/ergotree-ir/src/mir/downcast.rs b/ergotree-ir/src/mir/downcast.rs index d8a036965..35f7160c2 100644 --- a/ergotree-ir/src/mir/downcast.rs +++ b/ergotree-ir/src/mir/downcast.rs @@ -2,7 +2,6 @@ use alloc::boxed::Box; - use super::expr::Expr; use super::expr::InvalidArgumentError; use crate::serialization::op_code::OpCode; diff --git a/ergotree-ir/src/mir/exponentiate.rs b/ergotree-ir/src/mir/exponentiate.rs index fed5ad27c..28ab7be92 100644 --- a/ergotree-ir/src/mir/exponentiate.rs +++ b/ergotree-ir/src/mir/exponentiate.rs @@ -1,6 +1,5 @@ use alloc::boxed::Box; - use crate::serialization::op_code::OpCode; use crate::serialization::sigma_byte_reader::SigmaByteRead; use crate::serialization::sigma_byte_writer::SigmaByteWrite; diff --git a/ergotree-ir/src/mir/multiply_group.rs b/ergotree-ir/src/mir/multiply_group.rs index bc8e2891d..725303a79 100644 --- a/ergotree-ir/src/mir/multiply_group.rs +++ b/ergotree-ir/src/mir/multiply_group.rs @@ -1,6 +1,5 @@ use alloc::boxed::Box; - use crate::serialization::op_code::OpCode; use crate::serialization::sigma_byte_reader::SigmaByteRead; use crate::serialization::sigma_byte_writer::SigmaByteWrite; diff --git a/ergotree-ir/src/mir/option_is_defined.rs b/ergotree-ir/src/mir/option_is_defined.rs index 3bd9e1271..c52fd4ec6 100644 --- a/ergotree-ir/src/mir/option_is_defined.rs +++ b/ergotree-ir/src/mir/option_is_defined.rs @@ -1,6 +1,5 @@ use alloc::boxed::Box; - use super::expr::Expr; use super::expr::InvalidArgumentError; use super::unary_op::OneArgOp; diff --git a/ergotree-ir/src/mir/select_field.rs b/ergotree-ir/src/mir/select_field.rs index 4a0aed165..4b4e78262 100644 --- a/ergotree-ir/src/mir/select_field.rs +++ b/ergotree-ir/src/mir/select_field.rs @@ -2,7 +2,6 @@ use core::convert::TryFrom; use alloc::boxed::Box; - use crate::serialization::op_code::OpCode; use crate::serialization::sigma_byte_reader::SigmaByteRead; use crate::serialization::sigma_byte_writer::SigmaByteWrite; diff --git a/ergotree-ir/src/mir/subst_const.rs b/ergotree-ir/src/mir/subst_const.rs index 60da0fd3d..46537a689 100644 --- a/ergotree-ir/src/mir/subst_const.rs +++ b/ergotree-ir/src/mir/subst_const.rs @@ -1,7 +1,6 @@ //! Substitution of constants in serialized sigma expression use alloc::boxed::Box; - use super::expr::Expr; use crate::has_opcode::HasStaticOpCode; use crate::mir::expr::InvalidArgumentError; diff --git a/ergotree-ir/src/mir/upcast.rs b/ergotree-ir/src/mir/upcast.rs index 0181446e6..09919de80 100644 --- a/ergotree-ir/src/mir/upcast.rs +++ b/ergotree-ir/src/mir/upcast.rs @@ -2,7 +2,6 @@ use alloc::boxed::Box; - use super::expr::Expr; use super::expr::InvalidArgumentError; use crate::serialization::op_code::OpCode; diff --git a/ergotree-ir/src/pretty_printer.rs b/ergotree-ir/src/pretty_printer.rs index e6adddb58..eee5beb1d 100644 --- a/ergotree-ir/src/pretty_printer.rs +++ b/ergotree-ir/src/pretty_printer.rs @@ -91,7 +91,6 @@ mod tests { use expect_test::expect; - use alloc::boxed::Box; use crate::chain::address::AddressEncoder; use crate::chain::address::NetworkPrefix; use crate::ergo_tree::ErgoTree; @@ -103,6 +102,7 @@ mod tests { use crate::mir::val_use::ValUse; use crate::serialization::SigmaSerializable; use crate::types::stype::SType; + use alloc::boxed::Box; use super::*; diff --git a/ergotree-ir/src/serialization/expr.rs b/ergotree-ir/src/serialization/expr.rs index f41a2043d..3d3f578e1 100644 --- a/ergotree-ir/src/serialization/expr.rs +++ b/ergotree-ir/src/serialization/expr.rs @@ -1,5 +1,3 @@ - - use super::bin_op::bin_op_sigma_parse; use super::bin_op::bin_op_sigma_serialize; use super::{op_code::OpCode, sigma_byte_writer::SigmaByteWrite}; diff --git a/ergotree-ir/src/type_check.rs b/ergotree-ir/src/type_check.rs index 34260c62e..25fb63f5e 100644 --- a/ergotree-ir/src/type_check.rs +++ b/ergotree-ir/src/type_check.rs @@ -1,6 +1,5 @@ //! Type checking - use alloc::string::String; use crate::mir::expr::Expr; diff --git a/ergotree-ir/src/types/stype_param.rs b/ergotree-ir/src/types/stype_param.rs index 4fddb16d6..ae760caf1 100644 --- a/ergotree-ir/src/types/stype_param.rs +++ b/ergotree-ir/src/types/stype_param.rs @@ -2,7 +2,6 @@ use core::convert::TryInto; use core::fmt::Formatter; use core::hash::Hash; - use alloc::string::String; use alloc::string::ToString; use alloc::vec; From f56f57ddba0d08a34e8cb32d42481ff591947bf0 Mon Sep 17 00:00:00 2001 From: Kamal Ahmad Date: Wed, 27 Nov 2024 11:29:51 +0500 Subject: [PATCH 14/16] Clippy --- bindings/ergo-lib-c-core/Cargo.toml | 3 +- .../src/rest/api/node/abortable.rs | 7 +- ergo-rest/src/wasm_timer/timer/heap.rs | 53 ------------ ergotree-interpreter/src/eval.rs | 2 - ergotree-ir/src/chain/address.rs | 85 ++++++++++--------- ergotree-ir/src/serialization/types.rs | 2 + sigma-ser/src/lib.rs | 1 - 7 files changed, 49 insertions(+), 104 deletions(-) diff --git a/bindings/ergo-lib-c-core/Cargo.toml b/bindings/ergo-lib-c-core/Cargo.toml index c54962560..30394b1f2 100644 --- a/bindings/ergo-lib-c-core/Cargo.toml +++ b/bindings/ergo-lib-c-core/Cargo.toml @@ -25,6 +25,7 @@ serde_with = { workspace = true } bounded-vec = { workspace = true, features = ["serde"] } [features] -default = ["mnemonic_gen", "ergo-lib/compiler"] +default = ["mnemonic_gen", "ergo-lib/compiler", "json"] +json = [] rest = ["tokio", "ergo-lib/rest"] mnemonic_gen = ["ergo-lib/mnemonic_gen"] diff --git a/bindings/ergo-lib-c-core/src/rest/api/node/abortable.rs b/bindings/ergo-lib-c-core/src/rest/api/node/abortable.rs index fc165e4ed..5383486a1 100644 --- a/bindings/ergo-lib-c-core/src/rest/api/node/abortable.rs +++ b/bindings/ergo-lib-c-core/src/rest/api/node/abortable.rs @@ -5,12 +5,9 @@ use crate::rest::api::runtime::RestApiRuntime; use crate::Error; /// Wraps a task with future::Abortable, spawns it on the provided runtime and returns task's abort handle -pub(crate) fn spawn_abortable( - runtime: &RestApiRuntime, - task: T, -) -> Result +pub(crate) fn spawn_abortable(runtime: &RestApiRuntime, task: T) -> Result where - T: futures_util::Future + Send, + T: futures_util::Future + Send + 'static, { let (abort_handle, abort_registration) = AbortHandle::new_pair(); let future = Abortable::new(task, abort_registration); diff --git a/ergo-rest/src/wasm_timer/timer/heap.rs b/ergo-rest/src/wasm_timer/timer/heap.rs index 36ee7ae82..9c2f44cb7 100644 --- a/ergo-rest/src/wasm_timer/timer/heap.rs +++ b/ergo-rest/src/wasm_timer/timer/heap.rs @@ -46,7 +46,6 @@ impl Heap { /// heap, but only if the element was previously not removed from the heap. #[allow(clippy::panic)] pub fn push(&mut self, t: T) -> Slot { - self.assert_consistent(); let len = self.items.len(); let slot = SlabSlot::Full { value: len }; let slot_idx = if self.next_index == self.index.len() { @@ -61,17 +60,14 @@ impl Heap { }; self.items.push((t, slot_idx)); self.percolate_up(len); - self.assert_consistent(); Slot { idx: slot_idx } } pub fn peek(&self) -> Option<&T> { - self.assert_consistent(); self.items.get(0).map(|i| &i.0) } pub fn pop(&mut self) -> Option { - self.assert_consistent(); if self.items.len() == 0 { return None; } @@ -83,7 +79,6 @@ impl Heap { #[allow(clippy::panic)] pub fn remove(&mut self, slot: Slot) -> T { - self.assert_consistent(); let empty = SlabSlot::Empty { next: self.next_index, }; @@ -102,7 +97,6 @@ impl Heap { self.percolate_down(idx); } } - self.assert_consistent(); return item; } @@ -164,53 +158,6 @@ impl Heap { } return idx; } - - #[allow(clippy::panic)] - fn assert_consistent(&self) { - if !cfg!(assert_timer_heap_consistent) { - return; - } - - assert_eq!( - self.items.len(), - self.index - .iter() - .filter(|slot| { - match **slot { - SlabSlot::Full { .. } => true, - SlabSlot::Empty { .. } => false, - } - }) - .count() - ); - - for (i, &(_, j)) in self.items.iter().enumerate() { - let index = match self.index[j] { - SlabSlot::Full { value } => value, - SlabSlot::Empty { .. } => { - panic!() - } - }; - if index != i { - panic!( - "self.index[j] != i : i={} j={} self.index[j]={}", - i, j, index - ); - } - } - - for (i, &(ref item, _)) in self.items.iter().enumerate() { - if i > 0 { - assert!(*item >= self.items[(i - 1) / 2].0, "bad at index: {}", i); - } - if let Some(left) = self.items.get(2 * i + 1) { - assert!(*item <= left.0, "bad left at index: {}", i); - } - if let Some(right) = self.items.get(2 * i + 2) { - assert!(*item <= right.0, "bad right at index: {}", i); - } - } - } } #[allow(clippy::panic)] diff --git a/ergotree-interpreter/src/eval.rs b/ergotree-interpreter/src/eval.rs index cc2236896..92991843f 100644 --- a/ergotree-interpreter/src/eval.rs +++ b/ergotree-interpreter/src/eval.rs @@ -365,8 +365,6 @@ fn smethod_eval_fn(method: &SMethod) -> Result { #[allow(clippy::todo)] pub(crate) mod tests { - #![allow(dead_code)] - use super::env::Env; use super::*; use ergotree_ir::mir::bin_op::BinOp; diff --git a/ergotree-ir/src/chain/address.rs b/ergotree-ir/src/chain/address.rs index a39da6e32..0c2c33fdf 100644 --- a/ergotree-ir/src/chain/address.rs +++ b/ergotree-ir/src/chain/address.rs @@ -39,48 +39,49 @@ use sigma_util::AsVecU8; use thiserror::Error; /** - * An address is a short string corresponding to some script used to protect a box. Unlike (string-encoded) binary - * representation of a script, an address has some useful characteristics: - * - * - Integrity of an address could be checked., as it is incorporating a checksum. - * - A prefix of address is showing network and an address type. - * - An address is using an encoding (namely, Base58) which is avoiding similarly l0Oking characters, friendly to - * double-clicking and line-breaking in emails. - * - * - * - * An address is encoding network type, address type, checksum, and enough information to watch for a particular scripts. - * - * Possible network types are: - * Mainnet - 0x00 - * Testnet - 0x10 - * - * For an address type, we form content bytes as follows: - * - * P2PK - serialized (compressed) public key - * P2SH - first 192 bits of the Blake2b256 hash of serialized script bytes - * P2S - serialized script - * - * Address examples for testnet: - * - * 3 - P2PK (3WvsT2Gm4EpsM9Pg18PdY6XyhNNMqXDsvJTbbf6ihLvAmSb7u5RN) - * ? - P2SH (rbcrmKEYduUvADj9Ts3dSVSG27h54pgrq5fPuwB) - * ? - P2S (Ms7smJwLGbUAjuWQ) - * - * for mainnet: - * - * 9 - P2PK (9fRAWhdxEsTcdb8PhGNrZfwqa65zfkuYHAMmkQLcic1gdLSV5vA) - * ? - P2SH (8UApt8czfFVuTgQmMwtsRBZ4nfWquNiSwCWUjMg) - * ? - P2S (4MQyML64GnzMxZgm, BxKBaHkvrTvLZrDcZjcsxsF7aSsrN73ijeFZXtbj4CXZHHcvBtqSxQ) - * - * - * Prefix byte = network type + address type - * - * checksum = blake2b256(prefix byte ++ content bytes) - * - * address = prefix byte ++ content bytes ++ checksum - * - */ +* An address is a short string corresponding to some script used to protect a box. Unlike (string-encoded) binary +* representation of a script, an address has some useful characteristics: +* +* - Integrity of an address could be checked., as it is incorporating a checksum. +* - A prefix of address is showing network and an address type. +* - An address is using an encoding (namely, Base58) which is avoiding similarly l0Oking characters, friendly to + +* double-clicking and line-breaking in emails. +* +* +* +* An address is encoding network type, address type, checksum, and enough information to watch for a particular scripts. +* +* Possible network types are: +* Mainnet - 0x00 +* Testnet - 0x10 +* +* For an address type, we form content bytes as follows: +* +* P2PK - serialized (compressed) public key +* P2SH - first 192 bits of the Blake2b256 hash of serialized script bytes +* P2S - serialized script +* +* Address examples for testnet: +* +* 3 - P2PK (3WvsT2Gm4EpsM9Pg18PdY6XyhNNMqXDsvJTbbf6ihLvAmSb7u5RN) +* ? - P2SH (rbcrmKEYduUvADj9Ts3dSVSG27h54pgrq5fPuwB) +* ? - P2S (Ms7smJwLGbUAjuWQ) +* +* for mainnet: +* +* 9 - P2PK (9fRAWhdxEsTcdb8PhGNrZfwqa65zfkuYHAMmkQLcic1gdLSV5vA) +* ? - P2SH (8UApt8czfFVuTgQmMwtsRBZ4nfWquNiSwCWUjMg) +* ? - P2S (4MQyML64GnzMxZgm, BxKBaHkvrTvLZrDcZjcsxsF7aSsrN73ijeFZXtbj4CXZHHcvBtqSxQ) +* +* +* Prefix byte = network type + address type +* +* checksum = blake2b256(prefix byte ++ content bytes) +* +* address = prefix byte ++ content bytes ++ checksum +* +*/ #[derive(PartialEq, Eq, Debug, Clone)] pub enum Address { /// serialized (compressed) public key diff --git a/ergotree-ir/src/serialization/types.rs b/ergotree-ir/src/serialization/types.rs index 267604577..850a2ff5f 100644 --- a/ergotree-ir/src/serialization/types.rs +++ b/ergotree-ir/src/serialization/types.rs @@ -334,10 +334,12 @@ impl SType { /// - emitting typeCode of each node (see special case for collections below) /// - then recursively serializing subtrees from left to right on each level /// - for each collection of primitive type there is special type code to emit single byte instead of two bytes +/// /// Types code intervals /// - (1 .. MaxPrimTypeCode) // primitive types /// - (CollectionTypeCode .. CollectionTypeCode + MaxPrimTypeCode) // collections of primitive types /// - (MaxCollectionTypeCode ..) // Other types +/// /// Collection of non-primitive type is serialized as (CollectionTypeCode, serialize(elementType)) impl SigmaSerializable for SType { fn sigma_serialize(&self, w: &mut W) -> SigmaSerializeResult { diff --git a/sigma-ser/src/lib.rs b/sigma-ser/src/lib.rs index 763bed141..b648bd265 100644 --- a/sigma-ser/src/lib.rs +++ b/sigma-ser/src/lib.rs @@ -10,7 +10,6 @@ #![deny(dead_code)] #![deny(unused_imports)] #![deny(missing_docs)] -#![forbid(unsafe_code)] #![deny(clippy::unwrap_used)] #![deny(clippy::expect_used)] #![deny(clippy::todo)] From e1551d1d953c520ac1d2c65fb4d10fb0c404e359 Mon Sep 17 00:00:00 2001 From: Kamal Ahmad Date: Wed, 27 Nov 2024 11:32:00 +0500 Subject: [PATCH 15/16] ci: use cargo-rustc to build ergo-lib as rlib --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0414ff330..918ba2d32 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,8 +27,8 @@ jobs: - name: Build ergo-lib uses: actions-rs/cargo@v1 with: - command: build - args: --no-default-features --manifest-path ergo-lib/Cargo.toml + command: rustc + args: --no-default-features --manifest-path ergo-lib/Cargo.toml --crate-type rlib test: name: Tests on ${{ matrix.os }} From f27bd19424140fb4302af49b5748da1889388c1d Mon Sep 17 00:00:00 2001 From: Kamal Ahmad Date: Tue, 3 Dec 2024 13:17:44 +0500 Subject: [PATCH 16/16] Use new bounded-vec and ergo_avltree releases --- Cargo.toml | 2 +- ergotree-interpreter/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index bcac9a7be..b65092686 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 upstream +bounded-vec = { version = "0.8.0", default-features = false } 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 } diff --git a/ergotree-interpreter/Cargo.toml b/ergotree-interpreter/Cargo.toml index 7d0bf6226..1d1067ed3 100644 --- a/ergotree-interpreter/Cargo.toml +++ b/ergotree-interpreter/Cargo.toml @@ -34,7 +34,7 @@ serde = { workspace = true, optional = true } serde_json = { workspace = true, optional = true } serde_with = { workspace = true, optional = true } proptest = { workspace = true, optional = true } -ergo_avltree_rust = { git = "https://github.com/SethDusek/scorex_crypto_avltree", branch = "no_std" } # TODO: wait for upstream +ergo_avltree_rust = { version = "0.1.1" } gf2_192 = { version = "^0.28.0", path = "../gf2_192" } miette = { workspace = true, optional = true } hashbrown = { workspace = true }