From 236ec8e8c4e671055e0bf85356bf8807fc2fa04c Mon Sep 17 00:00:00 2001 From: arvidn Date: Sun, 3 Dec 2023 14:27:48 +0100 Subject: [PATCH] drop clvm-trait's dependency on clvmr, and remove the ToNodePtr and FromNodePtr traits as well as FromClvm and ToClvm for Allocator and NodePtr (those are moved into clvmr) --- Cargo.lock | 46 ++++++-- Cargo.toml | 2 +- chia-bls/Cargo.toml | 6 +- chia-protocol/Cargo.toml | 2 +- chia-tools/Cargo.toml | 2 +- chia-wallet/Cargo.toml | 4 +- chia-wallet/fuzz/Cargo.toml | 2 +- clvm-traits/Cargo.toml | 4 +- clvm-traits/docs/derive_macros.md | 14 +-- clvm-traits/src/clvm_decoder.rs | 25 ----- clvm-traits/src/clvm_encoder.rs | 18 ---- clvm-traits/src/from_clvm.rs | 98 +++++------------ clvm-traits/src/lib.rs | 172 +++++++++++++++++++++++++----- clvm-traits/src/to_clvm.rs | 125 ++++++++-------------- clvm-utils/Cargo.toml | 2 +- clvm-utils/fuzz/Cargo.toml | 2 +- fuzz/Cargo.toml | 2 +- wheel/Cargo.toml | 2 +- 18 files changed, 274 insertions(+), 254 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8d80cb777..4e0c233c6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -288,8 +288,8 @@ dependencies = [ "chia-protocol", "chia-traits", "chia-wallet", - "clvm-derive", - "clvm-traits", + "clvm-derive 0.2.14", + "clvm-traits 0.2.14", "clvm-utils", "clvmr", "hex", @@ -310,7 +310,7 @@ dependencies = [ "blst", "chia-traits", "chia_py_streamable_macro", - "clvm-traits", + "clvm-traits 0.2.14", "clvmr", "criterion", "hex", @@ -352,7 +352,7 @@ dependencies = [ "chia", "chia-protocol", "chia-traits", - "clvm-traits", + "clvm-traits 0.2.14", "clvm-utils", "clvmr", "hex-literal", @@ -368,7 +368,7 @@ dependencies = [ "chia-traits", "chia_py_streamable_macro", "chia_streamable_macro", - "clvm-traits", + "clvm-traits 0.2.14", "clvm-utils", "clvmr", "hex", @@ -411,7 +411,7 @@ dependencies = [ "chia-traits", "chia-wallet", "clap", - "clvm-traits", + "clvm-traits 0.2.14", "clvm-utils", "clvmr", "hex", @@ -440,7 +440,7 @@ dependencies = [ "arbitrary", "chia-bls", "chia-protocol", - "clvm-traits", + "clvm-traits 0.2.14", "clvm-utils", "clvmr", "hex", @@ -454,7 +454,7 @@ name = "chia-wallet-fuzz" version = "0.0.0" dependencies = [ "chia-wallet", - "clvm-traits", + "clvm-traits 0.2.14", "clvmr", "libfuzzer-sys", "pyo3", @@ -568,13 +568,37 @@ dependencies = [ "syn 2.0.28", ] +[[package]] +name = "clvm-derive" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9110e638f8a4d34922e0436282c7fe1a8149020aef3aacf699377dcd3f1553da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + [[package]] name = "clvm-traits" version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d64ffd2241dead56ca31fb0261b4d0f802ba0b98a1c1e6f4514bc06c6095a9a9" dependencies = [ - "clvm-derive", + "clvm-derive 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "clvmr", + "num-bigint", + "pyo3", + "thiserror", +] + +[[package]] +name = "clvm-traits" +version = "0.2.15" +dependencies = [ + "clvm-derive 0.2.14", "hex", + "hex-literal", "num-bigint", "pyo3", "thiserror", @@ -584,7 +608,7 @@ dependencies = [ name = "clvm-utils" version = "0.2.14" dependencies = [ - "clvm-traits", + "clvm-traits 0.2.14", "clvmr", "hex", ] @@ -595,7 +619,7 @@ version = "0.0.0" dependencies = [ "chia", "chia-fuzz", - "clvm-traits", + "clvm-traits 0.2.14", "clvm-utils", "clvmr", "libfuzzer-sys", diff --git a/Cargo.toml b/Cargo.toml index 36385ea1f..626607736 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,7 +42,7 @@ hex = "0.4.3" pyo3 = { version = ">=0.19.0", optional = true } clvm-utils = { version = "=0.2.14", path = "clvm-utils" } chia-traits = { version = "=0.2.14", path = "chia-traits" } -clvm-traits = { version = "=0.2.14", path = "clvm-traits" } +clvm-traits = { version = "=0.2.14" } clvm-derive = { version = "=0.2.14", path = "clvm-derive" } chia-protocol = { version = "=0.2.14", path = "chia-protocol" } chia-wallet = { version = "=0.2.14", path = "chia-wallet" } diff --git a/chia-bls/Cargo.toml b/chia-bls/Cargo.toml index 30e8a2e18..09740e9a6 100644 --- a/chia-bls/Cargo.toml +++ b/chia-bls/Cargo.toml @@ -9,18 +9,17 @@ homepage = "https://github.com/Chia-Network/chia_rs/chia-bls/" repository = "https://github.com/Chia-Network/chia_rs/chia-bls/" [features] -py-bindings = ["dep:pyo3", "chia_py_streamable_macro", "chia-traits/py-bindings"] +py-bindings = ["dep:pyo3", "chia_py_streamable_macro", "chia-traits/py-bindings", "clvm-traits/py-bindings"] [dependencies] chia-traits = { version = "=0.2.14", path = "../chia-traits" } -clvm-traits = { version = "=0.2.14", path = "../clvm-traits", features = ["derive"] } +clvm-traits = { version = "=0.2.14", features = ["derive"] } chia_py_streamable_macro = { version = "=0.2.14", path = "../chia_py_streamable_macro", optional = true } tiny-bip39 = "1.0.0" anyhow = "1.0.71" sha2 = "0.10.8" hkdf = "0.12.0" blst = { version = "0.3.11", features = ["portable"] } -clvmr = "=0.3.0" hex = "0.4.3" thiserror = "1.0.44" pyo3 = { version = "0.19.0", features = ["multiple-pymethods"], optional = true } @@ -30,6 +29,7 @@ arbitrary = { version = "1.3.0" } rand = "0.8.5" criterion = "0.5.1" rstest = "0.17.0" +clvmr = "=0.3.0" [lib] crate-type = ["rlib"] diff --git a/chia-protocol/Cargo.toml b/chia-protocol/Cargo.toml index 428b05605..d1205c6a4 100644 --- a/chia-protocol/Cargo.toml +++ b/chia-protocol/Cargo.toml @@ -19,7 +19,7 @@ chia_streamable_macro = { version = "=0.2.14", path = "../chia_streamable_macro" chia_py_streamable_macro = { version = "=0.2.14", path = "../chia_py_streamable_macro", optional = true } clvmr = "=0.3.0" chia-traits = { version = "=0.2.14", path = "../chia-traits" } -clvm-traits = { version = "=0.2.14", path = "../clvm-traits", features = ["derive"] } +clvm-traits = { version = "=0.2.14", features = ["derive"] } clvm-utils = { version = "=0.2.14", path = "../clvm-utils" } chia-bls = { version = "=0.2.14", path = "../chia-bls" } arbitrary = { version = "1.3.0", features = ["derive"] } diff --git a/chia-tools/Cargo.toml b/chia-tools/Cargo.toml index 9240cf5f3..f84d7f16a 100644 --- a/chia-tools/Cargo.toml +++ b/chia-tools/Cargo.toml @@ -12,7 +12,7 @@ repository = "https://github.com/Chia-Network/chia_rs/chia-tools" chia-protocol = { version = "0.2.14", path = "../chia-protocol" } chia-traits = { path = "../chia-traits" } clvm-utils = { path = "../clvm-utils" } -clvm-traits = { path = "../clvm-traits" } +clvm-traits = { version = "=0.2.14" } chia-wallet = { version = "=0.2.14", path = "../chia-wallet" } clvmr = { version = "=0.3.0", features = ["counters"] } chia = { version = "0.2.14", path = ".." } diff --git a/chia-wallet/Cargo.toml b/chia-wallet/Cargo.toml index fcf0f3c7e..e079ae5ea 100644 --- a/chia-wallet/Cargo.toml +++ b/chia-wallet/Cargo.toml @@ -14,7 +14,7 @@ sha2 = "0.10.8" num-bigint = "0.4.3" hex-literal = "0.4.1" clvm-utils = { version = "0.2.14", path = "../clvm-utils" } -clvm-traits = { version = "0.2.14", path = "../clvm-traits" } +clvm-traits = { version = "0.2.14" } chia-bls = { version = "0.2.14", path = "../chia-bls" } chia-protocol = { version = "0.2.14", path = "../chia-protocol" } arbitrary = "=1.3.0" @@ -23,4 +23,4 @@ arbitrary = "=1.3.0" hex = "0.4.3" [lib] -crate-type = ["rlib"] \ No newline at end of file +crate-type = ["rlib"] diff --git a/chia-wallet/fuzz/Cargo.toml b/chia-wallet/fuzz/Cargo.toml index db7a4395d..c25554f49 100644 --- a/chia-wallet/fuzz/Cargo.toml +++ b/chia-wallet/fuzz/Cargo.toml @@ -13,7 +13,7 @@ libfuzzer-sys = "0.4" clvmr = "0.3.0" pyo3 = { version = ">=0.19.0", features = ["auto-initialize"]} chia-wallet = { path = ".." } -clvm-traits = { path = "../../clvm-traits" } +clvm-traits = { version = "0.2.14" } [[bin]] name = "roundtrip" diff --git a/clvm-traits/Cargo.toml b/clvm-traits/Cargo.toml index f3effe08f..45c0f6927 100644 --- a/clvm-traits/Cargo.toml +++ b/clvm-traits/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clvm-traits" -version = "0.2.14" +version = "0.2.15" edition = "2021" license = "Apache-2.0" description = "Traits for encoding and decoding CLVM objects." @@ -18,9 +18,9 @@ py-bindings = ["dep:pyo3"] [dependencies] pyo3 = { version = ">=0.19.0", optional = true } clvm-derive = { version = "0.2.14", path = "../clvm-derive", optional = true } -clvmr = "0.3.0" num-bigint = "0.4.3" thiserror = "1.0.44" [dev-dependencies] hex = "0.4.3" +hex-literal = "=0.4.1" diff --git a/clvm-traits/docs/derive_macros.md b/clvm-traits/docs/derive_macros.md index 96f184366..12682087d 100644 --- a/clvm-traits/docs/derive_macros.md +++ b/clvm-traits/docs/derive_macros.md @@ -24,7 +24,7 @@ For example: - `(A, B, C)` is encoded as `(A . (B . C))`, since every cons-pair must contain two values. - `(A, B, C, D)` is encoded as `(A . (B . (C . D)))` for the same reason as above. -```rust +```rust compile_fail use clvmr::Allocator; use clvm_traits::{ToClvm, FromClvm}; @@ -59,7 +59,7 @@ For example: Note that the following code is for example purposes only and is not indicative of how to create a secure program. Using a password like shown in this example is an insecure method of locking coins, but it's effective for learning. -```rust +```rust compile_fail use clvmr::Allocator; use clvm_traits::{ToClvm, FromClvm}; @@ -91,7 +91,7 @@ You can read more about currying on the [Chia blockchain documentation](https:// Note that the following code is for example purposes only and is not indicative of how to create a secure program. Using a password like shown in this example is an insecure method of locking coins, but it's effective for learning. -```rust +```rust compile_fail use clvmr::Allocator; use clvm_traits::{ToClvm, FromClvm}; @@ -121,7 +121,7 @@ For convenience, this is the behavior when deriving `ToClvm` and `FromClvm` for In this example, since the `tuple` representation is used and the only values are the discriminants, the variants will be encoded as an atom. Discriminants default to the `isize` type and the first value is `0`. Subsequent values are incremented by `1` by default. -```rust +```rust compile_fail use clvmr::Allocator; use clvm_traits::{ToClvm, FromClvm}; @@ -145,7 +145,7 @@ It's possible to override both the type of the discriminator, and the value. The `#[repr(...)]` attribute is used by the Rust compiler to allow overriding the discriminator type. As such, this attribute is also used to change the underlying type used to serialize and deserialize discriminator values. -```rust +```rust compile_fail use clvmr::Allocator; use clvm_traits::{ToClvm, FromClvm}; @@ -169,7 +169,7 @@ assert_eq!(Status::from_clvm(a, ptr).unwrap(), status); Of course, you can also include fields on enum variants, and they will be serialized after the discriminator accordingly. It's also possible to override the representation of an individual variant, as if it were a standalone struct. -```rust +```rust compile_fail use clvmr::Allocator; use clvm_traits::{ToClvm, FromClvm}; @@ -199,7 +199,7 @@ This is what `#[clvm(untagged)]` allows you to do. However, due to current limit Note that if there is any ambiguity, the first variant which matches a value will be the resulting value. For example, if both `A` and `B` are in that order and are the same type, if you serialize a value of `B`, it will be deserialized as `A`. -```rust +```rust compile_fail use clvmr::Allocator; use clvm_traits::{ToClvm, FromClvm}; diff --git a/clvm-traits/src/clvm_decoder.rs b/clvm-traits/src/clvm_decoder.rs index 75c63d037..57bd512c8 100644 --- a/clvm-traits/src/clvm_decoder.rs +++ b/clvm-traits/src/clvm_decoder.rs @@ -1,8 +1,3 @@ -use clvmr::{ - allocator::{NodePtr, SExp}, - Allocator, -}; - use crate::FromClvmError; pub trait ClvmDecoder { @@ -18,23 +13,3 @@ pub trait ClvmDecoder { node.clone() } } - -impl ClvmDecoder for Allocator { - type Node = NodePtr; - - fn decode_atom(&self, node: &Self::Node) -> Result<&[u8], FromClvmError> { - if let SExp::Atom = self.sexp(*node) { - Ok(self.atom(*node)) - } else { - Err(FromClvmError::ExpectedAtom) - } - } - - fn decode_pair(&self, node: &Self::Node) -> Result<(Self::Node, Self::Node), FromClvmError> { - if let SExp::Pair(first, rest) = self.sexp(*node) { - Ok((first, rest)) - } else { - Err(FromClvmError::ExpectedPair) - } - } -} diff --git a/clvm-traits/src/clvm_encoder.rs b/clvm-traits/src/clvm_encoder.rs index f65812cb8..dc3ebce9b 100644 --- a/clvm-traits/src/clvm_encoder.rs +++ b/clvm-traits/src/clvm_encoder.rs @@ -1,5 +1,3 @@ -use clvmr::{allocator::NodePtr, Allocator}; - use crate::ToClvmError; pub trait ClvmEncoder { @@ -19,19 +17,3 @@ pub trait ClvmEncoder { node.clone() } } - -impl ClvmEncoder for Allocator { - type Node = NodePtr; - - fn encode_atom(&mut self, bytes: &[u8]) -> Result { - self.new_atom(bytes).or(Err(ToClvmError::OutOfMemory)) - } - - fn encode_pair( - &mut self, - first: Self::Node, - rest: Self::Node, - ) -> Result { - self.new_pair(first, rest).or(Err(ToClvmError::OutOfMemory)) - } -} diff --git a/clvm-traits/src/from_clvm.rs b/clvm-traits/src/from_clvm.rs index 800d2d931..d3042a535 100644 --- a/clvm-traits/src/from_clvm.rs +++ b/clvm-traits/src/from_clvm.rs @@ -1,4 +1,3 @@ -use clvmr::{allocator::NodePtr, Allocator}; use num_bigint::{BigInt, Sign}; use crate::{ClvmDecoder, FromClvmError}; @@ -7,33 +6,6 @@ pub trait FromClvm: Sized { fn from_clvm(decoder: &impl ClvmDecoder, node: N) -> Result; } -pub trait FromNodePtr { - fn from_node_ptr(a: &Allocator, node: NodePtr) -> Result - where - Self: Sized; -} - -impl FromNodePtr for T -where - T: FromClvm, -{ - fn from_node_ptr(a: &Allocator, node: NodePtr) -> Result - where - Self: Sized, - { - T::from_clvm(a, node) - } -} - -impl FromClvm for NodePtr { - fn from_clvm( - _decoder: &impl ClvmDecoder, - node: NodePtr, - ) -> Result { - Ok(node) - } -} - macro_rules! clvm_primitive { ($primitive:ty) => { impl FromClvm for $primitive { @@ -186,85 +158,73 @@ impl FromClvm for String { #[cfg(test)] mod tests { - use clvmr::{allocator::NodePtr, serde::node_from_bytes, Allocator}; + use crate::tests::{str_to_node, TestAllocator, TestNode}; + use super::FromClvm; use super::*; - fn decode(a: &mut Allocator, hex: &str) -> Result + fn decode(hex: &str) -> Result where - T: FromClvm, + T: FromClvm, { - let bytes = hex::decode(hex).unwrap(); - let actual = node_from_bytes(a, &bytes).unwrap(); - T::from_clvm(a, actual) - } - - #[test] - fn test_nodeptr() { - let a = &mut Allocator::new(); - let ptr = a.one(); - assert_eq!(NodePtr::from_clvm(a, ptr).unwrap(), ptr); + let mut a = TestAllocator::new(); + let (rest, actual) = str_to_node(&mut a, hex); + assert_eq!(rest, ""); + T::from_clvm(&a, actual) } #[test] fn test_primitives() { - let a = &mut Allocator::new(); - assert_eq!(decode(a, "80"), Ok(0u8)); - assert_eq!(decode(a, "80"), Ok(0i8)); - assert_eq!(decode(a, "05"), Ok(5u8)); - assert_eq!(decode(a, "05"), Ok(5u32)); - assert_eq!(decode(a, "05"), Ok(5i32)); - assert_eq!(decode(a, "81e5"), Ok(-27i32)); - assert_eq!(decode(a, "80"), Ok(-0)); - assert_eq!(decode(a, "8180"), Ok(-128i8)); + assert_eq!(decode("NIL"), Ok(0u8)); + assert_eq!(decode("NIL"), Ok(0i8)); + assert_eq!(decode("05"), Ok(5u8)); + assert_eq!(decode("05"), Ok(5u32)); + assert_eq!(decode("05"), Ok(5i32)); + assert_eq!(decode("e5"), Ok(-27i32)); + assert_eq!(decode("NIL"), Ok(-0)); + assert_eq!(decode("80"), Ok(-128i8)); } #[test] fn test_pair() { - let a = &mut Allocator::new(); - assert_eq!(decode(a, "ff0502"), Ok((5, 2))); - assert_eq!(decode(a, "ff81b8ff8301600980"), Ok((-72, (90121, ())))); + assert_eq!(decode("( 05 02"), Ok((5, 2))); + assert_eq!(decode("( b8 ( 016009 NIL"), Ok((-72, (90121, ())))); assert_eq!( - decode(a, "ffff80ff80ff80ffff80ff80ff80808080"), + decode("( ( NIL ( NIL ( NIL ( ( NIL ( NIL ( NIL NIL NIL NIL"), Ok((((), ((), ((), (((), ((), ((), ()))), ())))), ())) ); } #[test] fn test_nil() { - let a = &mut Allocator::new(); - assert_eq!(decode(a, "80"), Ok(())); + assert_eq!(decode("NIL"), Ok(())); } #[test] fn test_array() { - let a = &mut Allocator::new(); - assert_eq!(decode(a, "ff01ff02ff03ff0480"), Ok([1, 2, 3, 4])); - assert_eq!(decode(a, "80"), Ok([] as [i32; 0])); + assert_eq!(decode("( 01 ( 02 ( 03 ( 04 NIL"), Ok([1, 2, 3, 4])); + assert_eq!(decode("NIL"), Ok([] as [i32; 0])); } #[test] fn test_vec() { - let a = &mut Allocator::new(); - assert_eq!(decode(a, "ff01ff02ff03ff0480"), Ok(vec![1, 2, 3, 4])); - assert_eq!(decode(a, "80"), Ok(Vec::::new())); + assert_eq!(decode("( 01 ( 02 ( 03 ( 04 NIL"), Ok(vec![1, 2, 3, 4])); + assert_eq!(decode("NIL"), Ok(Vec::::new())); } #[test] fn test_option() { - let a = &mut Allocator::new(); - assert_eq!(decode(a, "8568656c6c6f"), Ok(Some("hello".to_string()))); - assert_eq!(decode(a, "80"), Ok(None::)); + assert_eq!(decode("68656c6c6f"), Ok(Some("hello".to_string()))); + assert_eq!(decode("NIL"), Ok(None::)); // Empty strings get decoded as None instead, since both values are represented by nil bytes. // This could be considered either intended behavior or not, depending on the way it's used. - assert_ne!(decode(a, "80"), Ok(Some("".to_string()))); + assert_ne!(decode("NIL"), Ok(Some("".to_string()))); } #[test] fn test_string() { - let a = &mut Allocator::new(); - assert_eq!(decode(a, "8568656c6c6f"), Ok("hello".to_string())); - assert_eq!(decode(a, "80"), Ok("".to_string())); + assert_eq!(decode("68656c6c6f"), Ok("hello".to_string())); + assert_eq!(decode("NIL"), Ok("".to_string())); } } diff --git a/clvm-traits/src/lib.rs b/clvm-traits/src/lib.rs index 6b6b93f6d..c3ee1240b 100644 --- a/clvm-traits/src/lib.rs +++ b/clvm-traits/src/lib.rs @@ -27,37 +27,157 @@ pub use to_clvm::*; pub use wrappers::*; #[cfg(test)] -#[cfg(feature = "derive")] -mod tests { +pub mod tests { extern crate self as clvm_traits; - use std::fmt; + use super::*; + + #[derive(Clone)] + pub enum TestNode { + Atom(usize), + Pair(Box, Box), + } + + pub struct TestAllocator { + atoms: Vec>, + } + + impl TestAllocator { + pub fn new() -> Self { + TestAllocator { atoms: vec![] } + } + + fn new_atom(&mut self, buf: &[u8]) -> TestNode { + let idx = self.atoms.len(); + self.atoms.push(buf.to_vec()); + TestNode::Atom(idx) + } - use clvmr::{allocator::NodePtr, serde::node_to_bytes, Allocator}; + fn atom(&self, idx: usize) -> &[u8] { + self.atoms[idx].as_slice() + } + } + + pub fn node_eq(a: &TestAllocator, left: &TestNode, right: &TestNode) -> bool { + match (left, right) { + (TestNode::Atom(l), TestNode::Atom(r)) => a.atom(*l) == a.atom(*r), + (TestNode::Pair(l1, r1), TestNode::Pair(l2, r2)) => { + node_eq(a, l1, l2) && node_eq(a, r1, r2) + } + (_, _) => false, + } + } + + pub fn node_to_str(a: &TestAllocator, input: &TestNode) -> String { + match input { + TestNode::Atom(v) => { + let atom = a.atom(*v); + if atom.len() == 0 { + "NIL".to_owned() + } else { + format!("{}", &hex::encode(&atom)) + } + } + TestNode::Pair(l, r) => format!("( {} {}", node_to_str(a, l), node_to_str(a, r)), + } + } + + pub fn str_to_node<'a>(a: &mut TestAllocator, input: &'a str) -> (&'a str, TestNode) { + let (first, rest) = if let Some((f, r)) = input.split_once(' ') { + (f, r) + } else { + (input, "") + }; + + println!("\"{first}\" | \"{rest}\""); + if first == "(" { + let (rest, left) = str_to_node(a, rest); + let (rest, right) = str_to_node(a, rest); + (rest, TestNode::Pair(Box::new(left), Box::new(right))) + } else { + if first == "NIL" { + (rest, a.new_atom(&[])) + } else { + ( + rest, + a.new_atom(hex::decode(first).expect("invalid hex").as_slice()), + ) + } + } + } + + impl ClvmDecoder for TestAllocator { + type Node = TestNode; + + fn decode_atom(&self, node: &Self::Node) -> Result<&[u8], FromClvmError> { + match &node { + TestNode::Atom(v) => Ok(self.atom(*v)), + _ => Err(FromClvmError::ExpectedAtom), + } + } + + fn decode_pair( + &self, + node: &Self::Node, + ) -> Result<(Self::Node, Self::Node), FromClvmError> { + match &node { + TestNode::Pair(l, r) => Ok((*l.clone(), *r.clone())), + _ => Err(FromClvmError::ExpectedPair), + } + } + + fn clone_node(&self, node: &Self::Node) -> Self::Node { + node.clone() + } + } + + impl ClvmEncoder for TestAllocator { + type Node = TestNode; + + fn encode_atom(&mut self, bytes: &[u8]) -> Result { + Ok(self.new_atom(bytes)) + } + + fn encode_pair( + &mut self, + first: Self::Node, + rest: Self::Node, + ) -> Result { + Ok(TestNode::Pair(Box::new(first), Box::new(rest))) + } + } +} + +#[cfg(test)] +#[cfg(feature = "derive")] +mod derive_tests { + extern crate self as clvm_traits; use super::*; + use crate::tests::*; + use std::fmt::Debug; fn check(value: T, expected: &str) where - T: fmt::Debug + PartialEq + ToClvm + FromClvm, + T: Debug + PartialEq + ToClvm + FromClvm, { - let a = &mut Allocator::new(); + let a = &mut TestAllocator::new(); let ptr = value.to_clvm(a).unwrap(); - let round_trip = T::from_clvm(a, ptr).unwrap(); - assert_eq!(value, round_trip); - let bytes = node_to_bytes(a, ptr).unwrap(); - let actual = hex::encode(bytes); + let actual = node_to_str(a, &ptr); assert_eq!(expected, actual); + + let round_trip = T::from_clvm(a, ptr).unwrap(); + assert_eq!(value, round_trip); } fn coerce_into(value: A) -> B where - A: ToClvm, - B: FromClvm, + A: ToClvm, + B: FromClvm, { - let a = &mut Allocator::new(); + let a = &mut TestAllocator::new(); let ptr = value.to_clvm(a).unwrap(); B::from_clvm(a, ptr).unwrap() } @@ -71,7 +191,7 @@ mod tests { b: i32, } - check(TupleStruct { a: 52, b: -32 }, "ff3481e0"); + check(TupleStruct { a: 52, b: -32 }, "( 34 e0"); } #[test] @@ -83,7 +203,7 @@ mod tests { b: i32, } - check(ListStruct { a: 52, b: -32 }, "ff34ff81e080"); + check(ListStruct { a: 52, b: -32 }, "( 34 ( e0 NIL"); } #[test] @@ -97,7 +217,7 @@ mod tests { check( CurryStruct { a: 52, b: -32 }, - "ff04ffff0134ffff04ffff0181e0ff018080", + "( 04 ( ( 01 34 ( ( 04 ( ( 01 e0 ( 01 NIL NIL", ); } @@ -107,7 +227,7 @@ mod tests { #[clvm(tuple)] struct UnnamedStruct(String, String); - check(UnnamedStruct("A".to_string(), "B".to_string()), "ff4142"); + check(UnnamedStruct("A".to_string(), "B".to_string()), "( 41 42"); } #[test] @@ -116,7 +236,7 @@ mod tests { #[clvm(tuple)] struct NewTypeStruct(String); - check(NewTypeStruct("XYZ".to_string()), "8358595a"); + check(NewTypeStruct("XYZ".to_string()), "58595a"); } #[test] @@ -129,9 +249,9 @@ mod tests { C, } - check(Enum::A(32), "ff8020"); - check(Enum::B { x: -72 }, "ff0181b8"); - check(Enum::C, "ff0280"); + check(Enum::A(32), "( NIL 20"); + check(Enum::B { x: -72 }, "( 01 b8"); + check(Enum::C, "( 02 NIL"); } #[test] @@ -145,9 +265,9 @@ mod tests { C = 11, } - check(Enum::A(32), "ff2a20"); - check(Enum::B { x: -72 }, "ff2281b8"); - check(Enum::C, "ff0b80"); + check(Enum::A(32), "( 2a 20"); + check(Enum::B { x: -72 }, "( 22 b8"); + check(Enum::C, "( 0b NIL"); } #[test] @@ -170,12 +290,12 @@ mod tests { } check(Enum::A(32), "20"); - check(Enum::B { x: -72, y: 94 }, "ff81b8ff5e80"); + check(Enum::B { x: -72, y: 94 }, "( b8 ( 5e NIL"); check( Enum::C { curried_value: "Hello".to_string(), }, - "ff04ffff018548656c6c6fff0180", + "( 04 ( ( 01 48656c6c6f ( 01 NIL", ); } diff --git a/clvm-traits/src/to_clvm.rs b/clvm-traits/src/to_clvm.rs index e5dac9a20..6f51bc240 100644 --- a/clvm-traits/src/to_clvm.rs +++ b/clvm-traits/src/to_clvm.rs @@ -1,4 +1,3 @@ -use clvmr::{allocator::NodePtr, Allocator}; use num_bigint::BigInt; use crate::{ClvmEncoder, ToClvmError}; @@ -7,28 +6,6 @@ pub trait ToClvm { fn to_clvm(&self, encoder: &mut impl ClvmEncoder) -> Result; } -pub trait ToNodePtr { - fn to_node_ptr(&self, a: &mut Allocator) -> Result; -} - -impl ToNodePtr for T -where - T: ToClvm, -{ - fn to_node_ptr(&self, a: &mut Allocator) -> Result { - self.to_clvm(a) - } -} - -impl ToClvm for NodePtr { - fn to_clvm( - &self, - _encoder: &mut impl ClvmEncoder, - ) -> Result { - Ok(*self) - } -} - pub fn simplify_int_bytes(mut slice: &[u8]) -> &[u8] { while (!slice.is_empty()) && (slice[0] == 0) { if slice.len() > 1 && (slice[1] & 0x80 == 0x80) { @@ -148,118 +125,100 @@ impl ToClvm for String { #[cfg(test)] mod tests { - use clvmr::{serde::node_to_bytes, Allocator}; - use hex::ToHex; + use crate::tests::{node_to_str, TestAllocator, TestNode}; use super::*; - fn encode(a: &mut Allocator, value: T) -> Result + fn encode(value: T) -> Result where - T: ToClvm, + T: ToClvm, { - let actual = value.to_clvm(a).unwrap(); - let actual_bytes = node_to_bytes(a, actual).unwrap(); - Ok(actual_bytes.encode_hex()) - } - - #[test] - fn test_nodeptr() { - let a = &mut Allocator::new(); - let ptr = a.one(); - assert_eq!(ptr.to_clvm(a).unwrap(), ptr); + let mut a = TestAllocator::new(); + let node = value.to_clvm(&mut a).unwrap(); + Ok(node_to_str(&a, &node)) } #[test] fn test_primitives() { - let a = &mut Allocator::new(); - assert_eq!(encode(a, 0u8), Ok("80".to_owned())); - assert_eq!(encode(a, 0i8), Ok("80".to_owned())); - assert_eq!(encode(a, 5u8), Ok("05".to_owned())); - assert_eq!(encode(a, 5u32), Ok("05".to_owned())); - assert_eq!(encode(a, 5i32), Ok("05".to_owned())); - assert_eq!(encode(a, -27i32), Ok("81e5".to_owned())); - assert_eq!(encode(a, -0), Ok("80".to_owned())); - assert_eq!(encode(a, -128i8), Ok("8180".to_owned())); + assert_eq!(encode(0u8), Ok("NIL".to_owned())); + assert_eq!(encode(0i8), Ok("NIL".to_owned())); + assert_eq!(encode(5u8), Ok("05".to_owned())); + assert_eq!(encode(5u32), Ok("05".to_owned())); + assert_eq!(encode(5i32), Ok("05".to_owned())); + assert_eq!(encode(-27i32), Ok("e5".to_owned())); + assert_eq!(encode(-0), Ok("NIL".to_owned())); + assert_eq!(encode(-128i8), Ok("80".to_owned())); } #[test] fn test_reference() { - let a = &mut Allocator::new(); - assert_eq!(encode(a, [1, 2, 3]), encode(a, [1, 2, 3])); - assert_eq!(encode(a, Some(42)), encode(a, Some(42))); - assert_eq!(encode(a, Some(&42)), encode(a, Some(42))); - assert_eq!(encode(a, Some(&42)), encode(a, Some(42))); + assert_eq!(encode([1, 2, 3]), encode([1, 2, 3])); + assert_eq!(encode(Some(42)), encode(Some(42))); + assert_eq!(encode(Some(&42)), encode(Some(42))); + assert_eq!(encode(Some(&42)), encode(Some(42))); } #[test] fn test_pair() { - let a = &mut Allocator::new(); - assert_eq!(encode(a, (5, 2)), Ok("ff0502".to_owned())); + assert_eq!(encode((5, 2)), Ok("( 05 02".to_owned())); assert_eq!( - encode(a, (-72, (90121, ()))), - Ok("ff81b8ff8301600980".to_owned()) + encode((-72, (90121, ()))), + Ok("( b8 ( 016009 NIL".to_owned()) ); assert_eq!( - encode(a, (((), ((), ((), (((), ((), ((), ()))), ())))), ())), - Ok("ffff80ff80ff80ffff80ff80ff80808080".to_owned()) + encode((((), ((), ((), (((), ((), ((), ()))), ())))), ())), + Ok("( ( NIL ( NIL ( NIL ( ( NIL ( NIL ( NIL NIL NIL NIL".to_owned()) ); } #[test] fn test_nil() { - let a = &mut Allocator::new(); - assert_eq!(encode(a, ()), Ok("80".to_owned())); + assert_eq!(encode(()), Ok("NIL".to_owned())); } #[test] fn test_slice() { - let a = &mut Allocator::new(); assert_eq!( - encode(a, [1, 2, 3, 4].as_slice()), - Ok("ff01ff02ff03ff0480".to_owned()) + encode([1, 2, 3, 4].as_slice()), + Ok("( 01 ( 02 ( 03 ( 04 NIL".to_owned()) ); - assert_eq!(encode(a, [0; 0].as_slice()), Ok("80".to_owned())); + assert_eq!(encode([0; 0].as_slice()), Ok("NIL".to_owned())); } #[test] fn test_array() { - let a = &mut Allocator::new(); - assert_eq!(encode(a, [1, 2, 3, 4]), Ok("ff01ff02ff03ff0480".to_owned())); - assert_eq!(encode(a, [0; 0]), Ok("80".to_owned())); + assert_eq!( + encode([1, 2, 3, 4]), + Ok("( 01 ( 02 ( 03 ( 04 NIL".to_owned()) + ); + assert_eq!(encode([0; 0]), Ok("NIL".to_owned())); } #[test] fn test_vec() { - let a = &mut Allocator::new(); assert_eq!( - encode(a, vec![1, 2, 3, 4]), - Ok("ff01ff02ff03ff0480".to_owned()) + encode(vec![1, 2, 3, 4]), + Ok("( 01 ( 02 ( 03 ( 04 NIL".to_owned()) ); - assert_eq!(encode(a, vec![0; 0]), Ok("80".to_owned())); + assert_eq!(encode(vec![0; 0]), Ok("NIL".to_owned())); } #[test] fn test_option() { - let a = &mut Allocator::new(); - assert_eq!(encode(a, Some("hello")), Ok("8568656c6c6f".to_owned())); - assert_eq!(encode(a, None::<&str>), Ok("80".to_owned())); - assert_eq!(encode(a, Some("")), Ok("80".to_owned())); + assert_eq!(encode(Some("hello")), Ok("68656c6c6f".to_owned())); + assert_eq!(encode(None::<&str>), Ok("NIL".to_owned())); + assert_eq!(encode(Some("")), Ok("NIL".to_owned())); } #[test] fn test_str() { - let a = &mut Allocator::new(); - assert_eq!(encode(a, "hello"), Ok("8568656c6c6f".to_owned())); - assert_eq!(encode(a, ""), Ok("80".to_owned())); + assert_eq!(encode("hello"), Ok("68656c6c6f".to_owned())); + assert_eq!(encode(""), Ok("NIL".to_owned())); } #[test] fn test_string() { - let a = &mut Allocator::new(); - assert_eq!( - encode(a, "hello".to_string()), - Ok("8568656c6c6f".to_owned()) - ); - assert_eq!(encode(a, "".to_string()), Ok("80".to_owned())); + assert_eq!(encode("hello".to_string()), Ok("68656c6c6f".to_owned())); + assert_eq!(encode("".to_string()), Ok("NIL".to_owned())); } } diff --git a/clvm-utils/Cargo.toml b/clvm-utils/Cargo.toml index 10cdbed2d..d4fd47899 100644 --- a/clvm-utils/Cargo.toml +++ b/clvm-utils/Cargo.toml @@ -10,7 +10,7 @@ repository = "https://github.com/Chia-Network/chia_rs/clvm-utils" [dependencies] clvmr = "0.3.0" -clvm-traits = { version = "0.2.14", path = "../clvm-traits" } +clvm-traits = { version = "0.2.14" } [dev-dependencies] hex = "0.4.3" diff --git a/clvm-utils/fuzz/Cargo.toml b/clvm-utils/fuzz/Cargo.toml index e0e318a5e..0bc057923 100644 --- a/clvm-utils/fuzz/Cargo.toml +++ b/clvm-utils/fuzz/Cargo.toml @@ -13,7 +13,7 @@ libfuzzer-sys = "0.4" clvmr = "=0.3.0" chia-fuzz = { path = "../../fuzz" } clvm-utils = { path = ".." } -clvm-traits = { path = "../../clvm-traits" } +clvm-traits = { version = "=0.2.14" } chia = { path = "../.." } [[bin]] diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index c1690af2f..b3d9ae470 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -12,7 +12,7 @@ cargo-fuzz = true libfuzzer-sys = "0.4" clvmr = "=0.3.0" clvm-utils = { path = "../clvm-utils" } -clvm-traits = { path = "../clvm-traits" } +clvm-traits = { version = "=0.2.14" } chia-protocol = { path = "../chia-protocol" } chia-traits = { path = "../chia-traits" } chia = { path = ".." } diff --git a/wheel/Cargo.toml b/wheel/Cargo.toml index 1c46325a0..b7865608a 100644 --- a/wheel/Cargo.toml +++ b/wheel/Cargo.toml @@ -23,6 +23,6 @@ chia = { version = "=0.2.14", path = "..", features = ["py-bindings"] } chia-bls = { version = "=0.2.14", path = "../chia-bls", features = ["py-bindings"] } chia-protocol = { version = "=0.2.14", path = "../chia-protocol", features = ["py-bindings"] } chia-traits = { version = "=0.2.14", path = "../chia-traits", features = ["py-bindings"] } -clvm-traits = { version = "=0.2.14", path = "../clvm-traits", features = ["derive", "py-bindings"] } +clvm-traits = { version = "=0.2.14", features = ["derive", "py-bindings"] } chia_py_streamable_macro = { version = "=0.2.14", path = "../chia_py_streamable_macro" } chia_streamable_macro = { version = "=0.2.14", path = "../chia_streamable_macro" }