From ea219e8732455c4f73abadc5cf2ff2c1aaedb575 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Tue, 15 Dec 2020 22:17:09 +0100 Subject: [PATCH] Fixing serde to use Bech32 encoding for ContractId and SchemaId types --- CHANGELOG.md | 4 +++ Cargo.lock | 3 +- Cargo.toml | 5 +++- src/rgb/bech32.rs | 62 +++++++++++++++++++++++++++++++++++++-- src/rgb/contract/data.rs | 8 ++--- src/rgb/contract/nodes.rs | 20 ++++++++++--- src/rgb/contract/value.rs | 8 ++--- src/rgb/schema/schema.rs | 5 ++-- 8 files changed, 95 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ea18080..f7462051 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ Change Log ========== +v0.2.1 +------ +- Fixing serde to use Bech32 encoding for ContractId and SchemaId types + v0.2.0 ------ No changes since RC2 diff --git a/Cargo.lock b/Cargo.lock index 35e938e8..5ed1ebfd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -726,7 +726,7 @@ checksum = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a" [[package]] name = "lnpbp" -version = "0.2.0" +version = "0.2.1" dependencies = [ "amplify", "amplify_derive", @@ -749,6 +749,7 @@ dependencies = [ "num-traits 0.2.14", "openssl", "serde 1.0.117", + "serde_json", "serde_with", "serde_with_macros", "socket2", diff --git a/Cargo.toml b/Cargo.toml index 151f47e9..0b4827f1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "lnpbp" -version = "0.2.0" +version = "0.2.1" license = "MIT" authors = ["Dr. Maxim Orlovsky "] description = "LNP/BP Core Library implementing LNPBP specifications & standards" @@ -89,6 +89,9 @@ num-derive = "~0.3.0" async-trait = { version = "~0.1.30", optional = true } torut = { version = "~0.1.6", features = ["v2", "v3"] } +[dev-dependencies] +serde_json = "~1.0.60" + [target.'cfg(target_os="android")'.dependencies] cc = { version = "=1.0.41" } # TODO: Find a soliton to a problem with breaking change in one of tokio diff --git a/src/rgb/bech32.rs b/src/rgb/bech32.rs index 5b544cf6..fc37da76 100644 --- a/src/rgb/bech32.rs +++ b/src/rgb/bech32.rs @@ -31,78 +31,130 @@ use crate::strict_encoding::{ /// Bech32 representation of generic RGB data, that can be generated from /// some string basing on Bech32 HRP value. #[derive(Clone, Debug, From)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(crate = "serde_crate", untagged) +)] pub enum Bech32 { /// Pedersen commitment /// /// HRP: `pedersen` #[from] + #[serde( + serialize_with = "to_bech32_str", + deserialize_with = "from_bech32_str" + )] PedersenCommitment(secp256k1zkp::pedersen::Commitment), /// Bulletproofs /// /// HRP: `bulletproof` #[from] + #[serde( + serialize_with = "to_bech32_str", + deserialize_with = "from_bech32_str" + )] Bulletproof(secp256k1zkp::pedersen::RangeProof), /// Curve25519 public key /// /// HRP: `curve25519pk` #[from] + #[serde( + serialize_with = "to_bech32_str", + deserialize_with = "from_bech32_str" + )] Curve25519Pk(ed25519_dalek::PublicKey), /// Ed25519 signature /// /// HRP: `ed25519sign` #[from] + #[serde( + serialize_with = "to_bech32_str", + deserialize_with = "from_bech32_str" + )] Ed25519Sign(ed25519_dalek::Signature), /// Blinded UTXO for assigning RGB state to. /// /// HRP: `utxob` #[from] - // TODO: (new) Remove it once invoice implementation will be completed + #[serde( + serialize_with = "to_bech32_str", + deserialize_with = "from_bech32_str" + )] BlindedUtxo(seal::Confidential), /// RGB Schema ID (hash of the schema data). /// /// HRP: `sch` #[from] + #[serde( + serialize_with = "to_bech32_str", + deserialize_with = "from_bech32_str" + )] SchemaId(SchemaId), /// RGB Schema raw data (hash of the genesis). /// /// HRP: `schema` #[from] + #[serde( + serialize_with = "to_bech32_str", + deserialize_with = "from_bech32_str" + )] Schema(Schema), /// RGB Contract ID (hash of the genesis). /// /// HRP: `rgb` #[from] + #[serde( + serialize_with = "to_bech32_str", + deserialize_with = "from_bech32_str" + )] ContractId(ContractId), /// RGB Contract genesis raw data /// /// HRP: `genesis` #[from] + #[serde( + serialize_with = "to_bech32_str", + deserialize_with = "from_bech32_str" + )] Genesis(Genesis), /// Raw data of state transition under some RGB contract /// /// HRP: `transition` #[from] + #[serde( + serialize_with = "to_bech32_str", + deserialize_with = "from_bech32_str" + )] Transition(Transition), /// Raw data of state extension under some RGB contract /// /// HRP: `statex` #[from] + #[serde( + serialize_with = "to_bech32_str", + deserialize_with = "from_bech32_str" + )] Extension(Extension), /// Anchor data for some dterministic bitcoin commitment /// /// HRP: `anchor` #[from] + #[serde( + serialize_with = "to_bech32_str", + deserialize_with = "from_bech32_str" + )] Anchor(Anchor), /// Disclosure data revealing some specific confidential information about @@ -110,6 +162,10 @@ pub enum Bech32 { /// /// HRP: `disclosure` #[from] + #[serde( + serialize_with = "to_bech32_str", + deserialize_with = "from_bech32_str" + )] Disclosure(Disclosure), /// Binary data for unknown Bech32 HRPs @@ -626,7 +682,7 @@ impl Display for Disclosure { /// Serializes type to a Bech32 string. #[cfg(feature = "serde")] -pub fn to_bech32(buffer: &T, serializer: S) -> Result +pub fn to_bech32_str(buffer: &T, serializer: S) -> Result where T: ToBech32, S: Serializer, @@ -636,7 +692,7 @@ where /// Deserializes a Bech32 to a `Vec`. #[cfg(feature = "serde")] -pub fn from_bech32<'de, T, D>(deserializer: D) -> Result +pub fn from_bech32_str<'de, T, D>(deserializer: D) -> Result where T: FromBech32, D: Deserializer<'de>, diff --git a/src/rgb/contract/data.rs b/src/rgb/contract/data.rs index 5aca5fb5..9c14e8fa 100644 --- a/src/rgb/contract/data.rs +++ b/src/rgb/contract/data.rs @@ -90,8 +90,8 @@ pub enum Revealed { #[cfg_attr( feature = "serde", serde( - serialize_with = "crate::rgb::bech32::to_bech32", - deserialize_with = "crate::rgb::bech32::from_bech32" + serialize_with = "crate::rgb::bech32::to_bech32_str", + deserialize_with = "crate::rgb::bech32::from_bech32_str" ) )] Curve25519Pubkey(ed25519_dalek::PublicKey), @@ -100,8 +100,8 @@ pub enum Revealed { #[cfg_attr( feature = "serde", serde( - serialize_with = "crate::rgb::bech32::to_bech32", - deserialize_with = "crate::rgb::bech32::from_bech32" + serialize_with = "crate::rgb::bech32::to_bech32_str", + deserialize_with = "crate::rgb::bech32::from_bech32_str" ) )] Ed25519Signature(ed25519_dalek::Signature), diff --git a/src/rgb/contract/nodes.rs b/src/rgb/contract/nodes.rs index d25dc9bd..04f2d878 100644 --- a/src/rgb/contract/nodes.rs +++ b/src/rgb/contract/nodes.rs @@ -30,7 +30,7 @@ use crate::rgb::schema::{ TransitionType, }; use crate::rgb::{ - schema, seal, Metadata, SchemaId, SimplicityScript, ToBech32, + schema, seal, Bech32, Metadata, SchemaId, SimplicityScript, ToBech32, }; /// Holds definition of valencies for contract nodes, which is a set of @@ -56,7 +56,6 @@ impl sha256t::Tag for NodeIdTag { /// Unique node (genesis, extensions & state transition) identifier equivalent /// to the commitment hash -#[cfg_attr(feature = "serde", serde_as(as = "DisplayFromStr"))] #[cfg_attr( feature = "serde", derive(Serialize, Deserialize), @@ -85,11 +84,10 @@ impl CommitEncodeWithStrategy for NodeId { } /// Unique contract identifier equivalent to the contract genesis commitment -#[cfg_attr(feature = "serde", serde_as(as = "DisplayFromStr"))] #[cfg_attr( feature = "serde", derive(Serialize, Deserialize), - serde(crate = "serde_crate") + serde(crate = "serde_crate", try_from = "Bech32", into = "Bech32") )] #[derive( Wrapper, @@ -1040,6 +1038,20 @@ mod test { ); } + #[test] + fn test_id_serde() { + let genesis: Genesis = Genesis::strict_decode(&GENESIS[..]).unwrap(); + let contract_id = genesis.contract_id(); + assert_eq!( + contract_id.to_string(), + "rgb1z586eqcsa5z5zvqep9y3rhqsykqpuycrhhvkc2aey6hdu25yyrgqv0a28q" + ); + assert_eq!( + serde_json::to_string(&contract_id).unwrap(), + "\"rgb1z586eqcsa5z5zvqep9y3rhqsykqpuycrhhvkc2aey6hdu25yyrgqv0a28q\"" + ); + } + #[test] fn test_genesis_impl() { let genesis: Genesis = Genesis::strict_decode(&GENESIS[..]).unwrap(); diff --git a/src/rgb/contract/value.rs b/src/rgb/contract/value.rs index 5fd99a49..e07f6ed5 100644 --- a/src/rgb/contract/value.rs +++ b/src/rgb/contract/value.rs @@ -121,16 +121,16 @@ pub struct Confidential { #[cfg_attr( feature = "serde", serde( - serialize_with = "crate::rgb::bech32::to_bech32", - deserialize_with = "crate::rgb::bech32::from_bech32" + serialize_with = "crate::rgb::bech32::to_bech32_str", + deserialize_with = "crate::rgb::bech32::from_bech32_str" ) )] pub commitment: pedersen::Commitment, #[cfg_attr( feature = "serde", serde( - serialize_with = "crate::rgb::bech32::to_bech32", - deserialize_with = "crate::rgb::bech32::from_bech32" + serialize_with = "crate::rgb::bech32::to_bech32_str", + deserialize_with = "crate::rgb::bech32::from_bech32_str" ) )] pub bulletproof: pedersen::RangeProof, diff --git a/src/rgb/schema/schema.rs b/src/rgb/schema/schema.rs index 88bf83b5..1bc50ac7 100644 --- a/src/rgb/schema/schema.rs +++ b/src/rgb/schema/schema.rs @@ -26,7 +26,7 @@ use crate::client_side_validation::{ }; use crate::commit_verify::CommitVerify; use crate::features; -use crate::rgb::ToBech32; +use crate::rgb::{Bech32, ToBech32}; // Here we can use usize since encoding/decoding makes sure that it's u16 pub type FieldType = usize; @@ -51,11 +51,10 @@ impl sha256t::Tag for SchemaIdTag { } /// Commitment-based schema identifier used for committing to the schema type -#[cfg_attr(feature = "serde", serde_as(as = "DisplayFromStr"))] #[cfg_attr( feature = "serde", derive(Serialize, Deserialize), - serde(crate = "serde_crate") + serde(crate = "serde_crate", try_from = "Bech32", into = "Bech32") )] #[derive( Wrapper,