From 893b448d51b274b8567d4fb29ae503f3653e89c0 Mon Sep 17 00:00:00 2001 From: Rigidity Date: Mon, 29 Apr 2024 14:18:54 -0400 Subject: [PATCH 1/2] Add OwnedBytes and SizedBytes to clvm-traits --- crates/clvm-traits/src/from_clvm.rs | 19 +++++ crates/clvm-traits/src/to_clvm.rs | 22 ++++++ crates/clvm-traits/src/wrappers.rs | 114 ++++++++++++++++++++++++++++ 3 files changed, 155 insertions(+) diff --git a/crates/clvm-traits/src/from_clvm.rs b/crates/clvm-traits/src/from_clvm.rs index abbc3110b..132a252d0 100644 --- a/crates/clvm-traits/src/from_clvm.rs +++ b/crates/clvm-traits/src/from_clvm.rs @@ -200,6 +200,8 @@ impl FromClvm for chia_bls::Signature { mod tests { use clvmr::{serde::node_from_bytes, Allocator, NodePtr}; + use crate::{OwnedAtom, SizedAtom}; + use super::*; fn decode(a: &mut Allocator, hex: &str) -> Result @@ -286,6 +288,23 @@ mod tests { assert_eq!(decode(a, "80"), Ok("".to_string())); } + #[test] + fn test_owned_atom() { + let a = &mut Allocator::new(); + assert_eq!(decode(a, "80"), Ok(OwnedAtom::new(Vec::new()))); + assert_eq!( + decode(a, "8568656c6c6f"), + Ok(OwnedAtom::new(b"hello".to_vec())) + ); + } + + #[test] + fn test_sized_atom() { + let a = &mut Allocator::new(); + assert_eq!(decode(a, "80"), Ok(SizedAtom::new([]))); + assert_eq!(decode(a, "8568656c6c6f"), Ok(SizedAtom::new(*b"hello"))); + } + #[cfg(feature = "chia-bls")] #[test] fn test_public_key() { diff --git a/crates/clvm-traits/src/to_clvm.rs b/crates/clvm-traits/src/to_clvm.rs index bff469d07..29e66a9f1 100644 --- a/crates/clvm-traits/src/to_clvm.rs +++ b/crates/clvm-traits/src/to_clvm.rs @@ -148,6 +148,8 @@ mod tests { use clvmr::{serde::node_to_bytes, Allocator, NodePtr}; use hex::ToHex; + use crate::{OwnedAtom, SizedAtom}; + use super::*; fn encode(a: &mut Allocator, value: T) -> Result @@ -267,6 +269,26 @@ mod tests { assert_eq!(encode(a, "".to_string()), Ok("80".to_owned())); } + #[test] + fn test_owned_atom() { + let a = &mut Allocator::new(); + assert_eq!(encode(a, OwnedAtom::new(Vec::new())), Ok("80".to_owned())); + assert_eq!( + encode(a, OwnedAtom::new(b"hello".to_vec())), + Ok("8568656c6c6f".to_owned()) + ); + } + + #[test] + fn test_sized_atom() { + let a = &mut Allocator::new(); + assert_eq!(encode(a, SizedAtom::new([])), Ok("80".to_owned())); + assert_eq!( + encode(a, SizedAtom::new(*b"hello")), + Ok("8568656c6c6f".to_owned()) + ); + } + #[cfg(feature = "chia-bls")] #[test] fn test_public_key() { diff --git a/crates/clvm-traits/src/wrappers.rs b/crates/clvm-traits/src/wrappers.rs index d91cb0ff7..26c600298 100644 --- a/crates/clvm-traits/src/wrappers.rs +++ b/crates/clvm-traits/src/wrappers.rs @@ -1,3 +1,5 @@ +use std::ops::Deref; + use crate::{ClvmDecoder, ClvmEncoder, FromClvm, FromClvmError, ToClvm, ToClvmError}; /// A wrapper for an intermediate CLVM value. This is required to @@ -17,3 +19,115 @@ impl ToClvm for Raw { Ok(encoder.clone_node(&self.0)) } } + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct OwnedAtom(Vec); + +impl OwnedAtom { + pub fn new(data: Vec) -> Self { + Self(data) + } + + pub fn into_inner(self) -> Vec { + self.0 + } +} + +impl AsRef<[u8]> for OwnedAtom { + fn as_ref(&self) -> &[u8] { + &self.0 + } +} + +impl From> for OwnedAtom { + fn from(data: Vec) -> Self { + Self(data) + } +} + +impl From for Vec { + fn from(atom: OwnedAtom) -> Self { + atom.0 + } +} + +impl Deref for OwnedAtom { + type Target = [u8]; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl ToClvm for OwnedAtom { + fn to_clvm(&self, encoder: &mut impl ClvmEncoder) -> Result { + encoder.encode_atom(self) + } +} + +impl FromClvm for OwnedAtom { + fn from_clvm(decoder: &impl ClvmDecoder, node: N) -> Result { + decoder + .decode_atom(&node) + .map(|atom| Self::new(atom.as_ref().to_vec())) + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct SizedAtom([u8; LEN]); + +impl SizedAtom { + pub fn new(data: [u8; LEN]) -> Self { + Self(data) + } + + pub fn as_bytes(self) -> [u8; LEN] { + self.0 + } +} + +impl AsRef<[u8]> for SizedAtom { + fn as_ref(&self) -> &[u8] { + &self.0 + } +} + +impl Deref for SizedAtom { + type Target = [u8]; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl From<[u8; LEN]> for SizedAtom { + fn from(data: [u8; LEN]) -> Self { + Self(data) + } +} + +impl From> for [u8; LEN] { + fn from(atom: SizedAtom) -> Self { + atom.0 + } +} + +impl ToClvm for SizedAtom { + fn to_clvm(&self, encoder: &mut impl ClvmEncoder) -> Result { + encoder.encode_atom(self) + } +} + +impl FromClvm for SizedAtom { + fn from_clvm(decoder: &impl ClvmDecoder, node: N) -> Result { + let atom = decoder.decode_atom(&node)?; + let bytes = atom.as_ref(); + + Ok(Self::new(bytes.try_into().map_err(|_| { + FromClvmError::WrongAtomLength { + expected: LEN, + found: bytes.len(), + } + })?)) + } +} From 1fbee4b01a4f4badf9830367ea10065db63481ff Mon Sep 17 00:00:00 2001 From: Rigidity Date: Tue, 30 Apr 2024 10:21:01 -0400 Subject: [PATCH 2/2] Move to clvm-utils --- crates/clvm-traits/src/from_clvm.rs | 19 ----- crates/clvm-traits/src/to_clvm.rs | 22 ------ crates/clvm-traits/src/wrappers.rs | 114 ---------------------------- crates/clvm-utils/src/lib.rs | 4 + crates/clvm-utils/src/owned_atom.rs | 92 ++++++++++++++++++++++ crates/clvm-utils/src/sized_atom.rs | 98 ++++++++++++++++++++++++ 6 files changed, 194 insertions(+), 155 deletions(-) create mode 100644 crates/clvm-utils/src/owned_atom.rs create mode 100644 crates/clvm-utils/src/sized_atom.rs diff --git a/crates/clvm-traits/src/from_clvm.rs b/crates/clvm-traits/src/from_clvm.rs index 132a252d0..abbc3110b 100644 --- a/crates/clvm-traits/src/from_clvm.rs +++ b/crates/clvm-traits/src/from_clvm.rs @@ -200,8 +200,6 @@ impl FromClvm for chia_bls::Signature { mod tests { use clvmr::{serde::node_from_bytes, Allocator, NodePtr}; - use crate::{OwnedAtom, SizedAtom}; - use super::*; fn decode(a: &mut Allocator, hex: &str) -> Result @@ -288,23 +286,6 @@ mod tests { assert_eq!(decode(a, "80"), Ok("".to_string())); } - #[test] - fn test_owned_atom() { - let a = &mut Allocator::new(); - assert_eq!(decode(a, "80"), Ok(OwnedAtom::new(Vec::new()))); - assert_eq!( - decode(a, "8568656c6c6f"), - Ok(OwnedAtom::new(b"hello".to_vec())) - ); - } - - #[test] - fn test_sized_atom() { - let a = &mut Allocator::new(); - assert_eq!(decode(a, "80"), Ok(SizedAtom::new([]))); - assert_eq!(decode(a, "8568656c6c6f"), Ok(SizedAtom::new(*b"hello"))); - } - #[cfg(feature = "chia-bls")] #[test] fn test_public_key() { diff --git a/crates/clvm-traits/src/to_clvm.rs b/crates/clvm-traits/src/to_clvm.rs index 29e66a9f1..bff469d07 100644 --- a/crates/clvm-traits/src/to_clvm.rs +++ b/crates/clvm-traits/src/to_clvm.rs @@ -148,8 +148,6 @@ mod tests { use clvmr::{serde::node_to_bytes, Allocator, NodePtr}; use hex::ToHex; - use crate::{OwnedAtom, SizedAtom}; - use super::*; fn encode(a: &mut Allocator, value: T) -> Result @@ -269,26 +267,6 @@ mod tests { assert_eq!(encode(a, "".to_string()), Ok("80".to_owned())); } - #[test] - fn test_owned_atom() { - let a = &mut Allocator::new(); - assert_eq!(encode(a, OwnedAtom::new(Vec::new())), Ok("80".to_owned())); - assert_eq!( - encode(a, OwnedAtom::new(b"hello".to_vec())), - Ok("8568656c6c6f".to_owned()) - ); - } - - #[test] - fn test_sized_atom() { - let a = &mut Allocator::new(); - assert_eq!(encode(a, SizedAtom::new([])), Ok("80".to_owned())); - assert_eq!( - encode(a, SizedAtom::new(*b"hello")), - Ok("8568656c6c6f".to_owned()) - ); - } - #[cfg(feature = "chia-bls")] #[test] fn test_public_key() { diff --git a/crates/clvm-traits/src/wrappers.rs b/crates/clvm-traits/src/wrappers.rs index 26c600298..d91cb0ff7 100644 --- a/crates/clvm-traits/src/wrappers.rs +++ b/crates/clvm-traits/src/wrappers.rs @@ -1,5 +1,3 @@ -use std::ops::Deref; - use crate::{ClvmDecoder, ClvmEncoder, FromClvm, FromClvmError, ToClvm, ToClvmError}; /// A wrapper for an intermediate CLVM value. This is required to @@ -19,115 +17,3 @@ impl ToClvm for Raw { Ok(encoder.clone_node(&self.0)) } } - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct OwnedAtom(Vec); - -impl OwnedAtom { - pub fn new(data: Vec) -> Self { - Self(data) - } - - pub fn into_inner(self) -> Vec { - self.0 - } -} - -impl AsRef<[u8]> for OwnedAtom { - fn as_ref(&self) -> &[u8] { - &self.0 - } -} - -impl From> for OwnedAtom { - fn from(data: Vec) -> Self { - Self(data) - } -} - -impl From for Vec { - fn from(atom: OwnedAtom) -> Self { - atom.0 - } -} - -impl Deref for OwnedAtom { - type Target = [u8]; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl ToClvm for OwnedAtom { - fn to_clvm(&self, encoder: &mut impl ClvmEncoder) -> Result { - encoder.encode_atom(self) - } -} - -impl FromClvm for OwnedAtom { - fn from_clvm(decoder: &impl ClvmDecoder, node: N) -> Result { - decoder - .decode_atom(&node) - .map(|atom| Self::new(atom.as_ref().to_vec())) - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct SizedAtom([u8; LEN]); - -impl SizedAtom { - pub fn new(data: [u8; LEN]) -> Self { - Self(data) - } - - pub fn as_bytes(self) -> [u8; LEN] { - self.0 - } -} - -impl AsRef<[u8]> for SizedAtom { - fn as_ref(&self) -> &[u8] { - &self.0 - } -} - -impl Deref for SizedAtom { - type Target = [u8]; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl From<[u8; LEN]> for SizedAtom { - fn from(data: [u8; LEN]) -> Self { - Self(data) - } -} - -impl From> for [u8; LEN] { - fn from(atom: SizedAtom) -> Self { - atom.0 - } -} - -impl ToClvm for SizedAtom { - fn to_clvm(&self, encoder: &mut impl ClvmEncoder) -> Result { - encoder.encode_atom(self) - } -} - -impl FromClvm for SizedAtom { - fn from_clvm(decoder: &impl ClvmDecoder, node: N) -> Result { - let atom = decoder.decode_atom(&node)?; - let bytes = atom.as_ref(); - - Ok(Self::new(bytes.try_into().map_err(|_| { - FromClvmError::WrongAtomLength { - expected: LEN, - found: bytes.len(), - } - })?)) - } -} diff --git a/crates/clvm-utils/src/lib.rs b/crates/clvm-utils/src/lib.rs index 5d642a3e1..ebeca6c7c 100644 --- a/crates/clvm-utils/src/lib.rs +++ b/crates/clvm-utils/src/lib.rs @@ -26,8 +26,12 @@ mod curried_program; mod curry_tree_hash; +mod owned_atom; +mod sized_atom; mod tree_hash; pub use curried_program::*; pub use curry_tree_hash::*; +pub use owned_atom::*; +pub use sized_atom::*; pub use tree_hash::*; diff --git a/crates/clvm-utils/src/owned_atom.rs b/crates/clvm-utils/src/owned_atom.rs new file mode 100644 index 000000000..624770fbe --- /dev/null +++ b/crates/clvm-utils/src/owned_atom.rs @@ -0,0 +1,92 @@ +use std::ops::Deref; + +use clvm_traits::{ClvmDecoder, ClvmEncoder, FromClvm, FromClvmError, ToClvm, ToClvmError}; + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct OwnedAtom(Vec); + +impl OwnedAtom { + pub fn new(data: Vec) -> Self { + Self(data) + } + + pub fn into_inner(self) -> Vec { + self.0 + } +} + +impl AsRef<[u8]> for OwnedAtom { + fn as_ref(&self) -> &[u8] { + &self.0 + } +} + +impl From> for OwnedAtom { + fn from(data: Vec) -> Self { + Self(data) + } +} + +impl From for Vec { + fn from(atom: OwnedAtom) -> Self { + atom.0 + } +} + +impl Deref for OwnedAtom { + type Target = [u8]; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl ToClvm for OwnedAtom { + fn to_clvm(&self, encoder: &mut impl ClvmEncoder) -> Result { + encoder.encode_atom(self) + } +} + +impl FromClvm for OwnedAtom { + fn from_clvm(decoder: &impl ClvmDecoder, node: N) -> Result { + decoder + .decode_atom(&node) + .map(|atom| Self::new(atom.as_ref().to_vec())) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + use clvmr::{ + serde::{node_from_bytes, node_to_bytes}, + Allocator, + }; + + #[test] + fn test_to_clvm() { + let a = &mut Allocator::new(); + + let ptr = OwnedAtom::new(Vec::new()).to_clvm(a).unwrap(); + let bytes = node_to_bytes(a, ptr).unwrap(); + assert_eq!(hex::encode(bytes), "80".to_owned()); + + let ptr = OwnedAtom::new(b"hello".to_vec()).to_clvm(a).unwrap(); + let bytes = node_to_bytes(a, ptr).unwrap(); + assert_eq!(hex::encode(bytes), "8568656c6c6f".to_owned()); + } + + #[test] + fn test_from_clvm() { + let a = &mut Allocator::new(); + + let ptr = node_from_bytes(a, &hex::decode("80").unwrap()).unwrap(); + let value = OwnedAtom::from_clvm(a, ptr).unwrap(); + assert_eq!(value, OwnedAtom::new(Vec::new())); + + let ptr = node_from_bytes(a, &hex::decode("8568656c6c6f").unwrap()).unwrap(); + let value = OwnedAtom::from_clvm(a, ptr).unwrap(); + assert_eq!(value, OwnedAtom::new(b"hello".to_vec())); + } +} diff --git a/crates/clvm-utils/src/sized_atom.rs b/crates/clvm-utils/src/sized_atom.rs new file mode 100644 index 000000000..5cc29c56a --- /dev/null +++ b/crates/clvm-utils/src/sized_atom.rs @@ -0,0 +1,98 @@ +use std::ops::Deref; + +use clvm_traits::{ClvmDecoder, ClvmEncoder, FromClvm, FromClvmError, ToClvm, ToClvmError}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct SizedAtom([u8; LEN]); + +impl SizedAtom { + pub fn new(data: [u8; LEN]) -> Self { + Self(data) + } + + pub fn as_bytes(self) -> [u8; LEN] { + self.0 + } +} + +impl AsRef<[u8]> for SizedAtom { + fn as_ref(&self) -> &[u8] { + &self.0 + } +} + +impl Deref for SizedAtom { + type Target = [u8]; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl From<[u8; LEN]> for SizedAtom { + fn from(data: [u8; LEN]) -> Self { + Self(data) + } +} + +impl From> for [u8; LEN] { + fn from(atom: SizedAtom) -> Self { + atom.0 + } +} + +impl ToClvm for SizedAtom { + fn to_clvm(&self, encoder: &mut impl ClvmEncoder) -> Result { + encoder.encode_atom(self) + } +} + +impl FromClvm for SizedAtom { + fn from_clvm(decoder: &impl ClvmDecoder, node: N) -> Result { + let atom = decoder.decode_atom(&node)?; + let bytes = atom.as_ref(); + + Ok(Self::new(bytes.try_into().map_err(|_| { + FromClvmError::WrongAtomLength { + expected: LEN, + found: bytes.len(), + } + })?)) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + use clvmr::{ + serde::{node_from_bytes, node_to_bytes}, + Allocator, + }; + + #[test] + fn test_to_clvm() { + let a = &mut Allocator::new(); + + let ptr = SizedAtom::new([]).to_clvm(a).unwrap(); + let bytes = node_to_bytes(a, ptr).unwrap(); + assert_eq!(hex::encode(bytes), "80".to_owned()); + + let ptr = SizedAtom::new(*b"hello").to_clvm(a).unwrap(); + let bytes = node_to_bytes(a, ptr).unwrap(); + assert_eq!(hex::encode(bytes), "8568656c6c6f".to_owned()); + } + + #[test] + fn test_from_clvm() { + let a = &mut Allocator::new(); + + let ptr = node_from_bytes(a, &hex::decode("80").unwrap()).unwrap(); + let value = SizedAtom::from_clvm(a, ptr).unwrap(); + assert_eq!(value, SizedAtom::new([])); + + let ptr = node_from_bytes(a, &hex::decode("8568656c6c6f").unwrap()).unwrap(); + let value = SizedAtom::from_clvm(a, ptr).unwrap(); + assert_eq!(value, SizedAtom::new(*b"hello")); + } +}