From 365f385434b9e343fa24c075f2a0b414d99122d1 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Thu, 9 Jun 2022 23:05:35 +0200 Subject: [PATCH 01/15] Add support for u128 and i128 in contract data --- src/contract/data.rs | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/contract/data.rs b/src/contract/data.rs index 1ffc1c61..677d4a86 100644 --- a/src/contract/data.rs +++ b/src/contract/data.rs @@ -56,16 +56,14 @@ pub enum Revealed { U16(u16), U32(u32), U64(u64), - // TODO #15: Add support later once bitcoin library will start supporting - // consensus-encoding of the native rust `u128` type - // U128(u128), + U128(u128), + // TODO #15: Add support for u256 I8(i8), I16(i16), I32(i32), I64(i64), - // TODO #15: Add support later once bitcoin library will start supporting - // consensus-encoding of the native rust `i128` type - // I128(i128), + I128(i128), + // TODO #15: Add support for i256 F32(f32), F64(f64), Bytes(Vec), @@ -274,12 +272,12 @@ pub(super) mod _strict_encoding { U16 = 0b_0000_0001_u8, U32 = 0b_0000_0010_u8, U64 = 0b_0000_0011_u8, - // U128 = 0b_0000_0100_u8, + U128 = 0b_0000_0100_u8, I8 = 0b_0000_1000_u8, I16 = 0b_0000_1001_u8, I32 = 0b_0000_1010_u8, I64 = 0b_0000_1011_u8, - // I128 = 0b_0000_1100_u8, + I128 = 0b_0000_1100_u8, F32 = 0b_0001_0010_u8, F64 = 0b_0001_0011_u8, @@ -326,8 +324,9 @@ pub(super) mod _strict_encoding { Revealed::U64(val) => { strict_encode_list!(e; EncodingTag::U64, val) } - // Value::U128(val) => strict_encode_list!(e; EncodingTag::U128, - // val), + Revealed::U128(val) => { + strict_encode_list!(e; EncodingTag::U128, val) + } Revealed::I8(val) => { strict_encode_list!(e; EncodingTag::I8, val) } @@ -340,8 +339,9 @@ pub(super) mod _strict_encoding { Revealed::I64(val) => { strict_encode_list!(e; EncodingTag::I64, val) } - // Value::I128(val) => strict_encode_list!(e; EncodingTag::I128, - // val), + Revealed::I128(val) => { + strict_encode_list!(e; EncodingTag::I128, val) + } Revealed::F32(val) => { strict_encode_list!(e; EncodingTag::F32, val) } @@ -399,14 +399,16 @@ pub(super) mod _strict_encoding { EncodingTag::U16 => Revealed::U16(u16::strict_decode(&mut d)?), EncodingTag::U32 => Revealed::U32(u32::strict_decode(&mut d)?), EncodingTag::U64 => Revealed::U64(u64::strict_decode(&mut d)?), - // EncodingTag::U128 => Value::U128(u128::strict_decode(&mut - // d)?), + EncodingTag::U128 => { + Revealed::U128(u128::strict_decode(&mut d)?) + } EncodingTag::I8 => Revealed::I8(i8::strict_decode(&mut d)?), EncodingTag::I16 => Revealed::I16(i16::strict_decode(&mut d)?), EncodingTag::I32 => Revealed::I32(i32::strict_decode(&mut d)?), EncodingTag::I64 => Revealed::I64(i64::strict_decode(&mut d)?), - // EncodingTag::I128 => Value::I128(i128::strict_decode(&mut - // d)?), + EncodingTag::I128 => { + Revealed::I128(i128::strict_decode(&mut d)?) + } EncodingTag::F32 => Revealed::F32(f32::strict_decode(&mut d)?), EncodingTag::F64 => Revealed::F64(f64::strict_decode(&mut d)?), EncodingTag::Bytes => Revealed::Bytes(Vec::strict_decode(&mut d)?), @@ -451,10 +453,12 @@ pub(super) mod _strict_encoding { EncodingTag::U16 => 0b_0000_0001_u8, EncodingTag::U32 => 0b_0000_0010_u8, EncodingTag::U64 => 0b_0000_0011_u8, + EncodingTag::U128 => 0b_0000_0100_u8, EncodingTag::I8 => 0b_0000_1000_u8, EncodingTag::I16 => 0b_0000_1001_u8, EncodingTag::I32 => 0b_0000_1010_u8, EncodingTag::I64 => 0b_0000_1011_u8, + EncodingTag::I128 => 0b_0000_1100_u8, EncodingTag::F32 => 0b_0001_0010_u8, EncodingTag::F64 => 0b_0001_0011_u8, From 4b591d0bb965bcc7cad4f4b3e4038a06f1b02c3a Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Thu, 9 Jun 2022 23:05:47 +0200 Subject: [PATCH 02/15] Remove non-primitive data types from contract --- src/contract/data.rs | 271 +------------------------------------------ 1 file changed, 6 insertions(+), 265 deletions(-) diff --git a/src/contract/data.rs b/src/contract/data.rs index 677d4a86..10b6b365 100644 --- a/src/contract/data.rs +++ b/src/contract/data.rs @@ -16,10 +16,8 @@ use core::cmp::Ordering; use core::fmt::Debug; use std::io; -use amplify::AsAny; -use bitcoin::hashes::{hash160, sha256, sha256d, sha512, Hash}; -use bitcoin::util::psbt::PartiallySignedTransaction; -use bitcoin::{secp256k1, OutPoint, Transaction}; +use bitcoin::hashes::{hash160, Hash}; + use commit_verify::{commit_encode, CommitConceal, CommitEncode}; use strict_encoding::strict_serialize; @@ -68,38 +66,6 @@ pub enum Revealed { F64(f64), Bytes(Vec), String(String), - - /// Single-path RIPEMD-160 is not secure and should not be used; see - /// - Sha256(sha256::Hash), - Sha512(sha512::Hash), - Bitcoin160(hash160::Hash), - Bitcoin256(sha256d::Hash), - - Secp256k1Pubkey(secp256k1::PublicKey), - #[cfg_attr( - feature = "serde", - serde( - serialize_with = "crate::bech32::to_bech32_str", - deserialize_with = "crate::bech32::from_bech32_str" - ) - )] - Curve25519Pubkey(ed25519_dalek::PublicKey), - - Secp256k1ECDSASignature(secp256k1::ecdsa::Signature), - #[cfg_attr( - feature = "serde", - serde( - serialize_with = "crate::bech32::to_bech32_str", - deserialize_with = "crate::bech32::from_bech32_str" - ) - )] - Ed25519Signature(ed25519_dalek::Signature), - // TODO #15: Add support for Schnorr's signatures once they will be - // implemented in rust-secp256k1 - TxOutPoint(OutPoint), - Tx(Transaction), - Psbt(PartiallySignedTransaction), } impl RevealedState for Revealed {} @@ -283,21 +249,6 @@ pub(super) mod _strict_encoding { Bytes = 0b_0010_0000_u8, String = 0b_0010_0001_u8, - - Sha256 = 0b_0100_0000_u8, - Sha512 = 0b_0100_0001_u8, - Bitcoin160 = 0b_0100_1000_u8, - Bitcoin256 = 0b_0100_1001_u8, - - Secp256k1Pubkey = 0b_1000_0001_u8, - Secp256k1Signature = 0b_1000_0010_u8, - - Curve25519Pubkey = 0b_1000_1001_u8, - Ed25519Signature = 0b_1000_1010_u8, - - TxOutPoint = 0b_0101_0001_u8, - Tx = 0b_0101_0010_u8, - Psbt = 0b_0101_0011_u8, } impl_enum_strict_encoding!(EncodingTag); @@ -354,39 +305,6 @@ pub(super) mod _strict_encoding { Revealed::String(val) => { strict_encode_list!(e; EncodingTag::String, val) } - Revealed::Sha256(val) => { - strict_encode_list!(e; EncodingTag::Sha256, val) - } - Revealed::Sha512(val) => { - strict_encode_list!(e; EncodingTag::Sha512, val) - } - Revealed::Bitcoin160(val) => { - strict_encode_list!(e; EncodingTag::Bitcoin160, val) - } - Revealed::Bitcoin256(val) => { - strict_encode_list!(e; EncodingTag::Bitcoin256, val) - } - Revealed::Secp256k1Pubkey(val) => { - strict_encode_list!(e; EncodingTag::Secp256k1Pubkey, val) - } - Revealed::Secp256k1ECDSASignature(val) => { - strict_encode_list!(e; EncodingTag::Secp256k1Signature, val) - } - Revealed::Curve25519Pubkey(val) => { - strict_encode_list!(e; EncodingTag::Curve25519Pubkey, val) - } - Revealed::Ed25519Signature(val) => { - strict_encode_list!(e; EncodingTag::Ed25519Signature, val) - } - Revealed::TxOutPoint(val) => { - strict_encode_list!(e; EncodingTag::TxOutPoint, val) - } - Revealed::Tx(val) => { - strict_encode_list!(e; EncodingTag::Tx, val) - } - Revealed::Psbt(val) => { - strict_encode_list!(e; EncodingTag::Psbt, val) - } }) } } @@ -411,32 +329,11 @@ pub(super) mod _strict_encoding { } EncodingTag::F32 => Revealed::F32(f32::strict_decode(&mut d)?), EncodingTag::F64 => Revealed::F64(f64::strict_decode(&mut d)?), - EncodingTag::Bytes => Revealed::Bytes(Vec::strict_decode(&mut d)?), - EncodingTag::String => Revealed::String(String::strict_decode(&mut d)?), - EncodingTag::Bitcoin160 => { - Revealed::Bitcoin160(hash160::Hash::strict_decode(&mut d)?) - } - EncodingTag::Bitcoin256 => { - Revealed::Bitcoin256(sha256d::Hash::strict_decode(&mut d)?) - } - EncodingTag::Sha256 => Revealed::Sha256(sha256::Hash::strict_decode(&mut d)?), - EncodingTag::Sha512 => Revealed::Sha512(sha512::Hash::strict_decode(&mut d)?), - EncodingTag::Secp256k1Pubkey => { - Revealed::Secp256k1Pubkey(secp256k1::PublicKey::strict_decode(&mut d)?) + EncodingTag::Bytes => { + Revealed::Bytes(Vec::strict_decode(&mut d)?) } - EncodingTag::Secp256k1Signature => Revealed::Secp256k1ECDSASignature( - secp256k1::ecdsa::Signature::strict_decode(&mut d)?, - ), - EncodingTag::Curve25519Pubkey => { - Revealed::Curve25519Pubkey(ed25519_dalek::PublicKey::strict_decode(&mut d)?) - } - EncodingTag::Ed25519Signature => { - Revealed::Ed25519Signature(ed25519_dalek::Signature::strict_decode(&mut d)?) - } - EncodingTag::TxOutPoint => Revealed::TxOutPoint(OutPoint::strict_decode(&mut d)?), - EncodingTag::Tx => Revealed::Tx(Transaction::strict_decode(&mut d)?), - EncodingTag::Psbt => { - Revealed::Psbt(PartiallySignedTransaction::strict_decode(&mut d)?) + EncodingTag::String => { + Revealed::String(String::strict_decode(&mut d)?) } }) } @@ -464,21 +361,6 @@ pub(super) mod _strict_encoding { EncodingTag::Bytes => 0b_0010_0000_u8, EncodingTag::String => 0b_0010_0001_u8, - - EncodingTag::Sha256 => 0b_0100_0000_u8, - EncodingTag::Sha512 => 0b_0100_0001_u8, - EncodingTag::Bitcoin160 => 0b_0100_1000_u8, - EncodingTag::Bitcoin256 => 0b_0100_1001_u8, - - EncodingTag::Secp256k1Pubkey => 0b_1000_0001_u8, - EncodingTag::Secp256k1Signature => 0b_1000_0010_u8, - - EncodingTag::Curve25519Pubkey => 0b_1000_1001_u8, - EncodingTag::Ed25519Signature => 0b_1000_1010_u8, - - EncodingTag::TxOutPoint => 0b_0101_0001_u8, - EncodingTag::Tx => 0b_0101_0010_u8, - EncodingTag::Psbt => 0b_0101_0011_u8 ) .unwrap(); } @@ -512,99 +394,6 @@ mod test { 0x21, 0x11, 0x0, 0x45, 0x54, 0x48, 0x20, 0x49, 0x53, 0x20, 0x41, 0x20, 0x53, 0x45, 0x43, 0x55, 0x52, 0x49, 0x54, 0x59, ]; - static BITCOIN160: [u8; 21] = [ - 0x48, 0xf, 0x33, 0xe5, 0xdf, 0x8, 0x7c, 0x5c, 0xef, 0x5f, 0xae, 0xbe, 0x76, 0x76, 0xd9, - 0xe7, 0xa6, 0xb8, 0x2b, 0x4a, 0x99, - ]; - static BITCOIN256: [u8; 33] = [ - 0x49, 0x39, 0x3a, 0x97, 0x1e, 0x46, 0x1d, 0x1c, 0x52, 0xd4, 0xb7, 0xb9, 0xb6, 0x5c, 0x65, - 0x1a, 0x21, 0x69, 0xf6, 0x82, 0x75, 0x9b, 0x5e, 0xc5, 0xa2, 0x0, 0xde, 0x78, 0x7e, 0x40, - 0x79, 0x55, 0x7b, - ]; - static SHA256: [u8; 33] = [ - 0x40, 0x99, 0x95, 0x91, 0x96, 0xd2, 0x51, 0x41, 0x94, 0x68, 0x59, 0xbb, 0x21, 0x3e, 0xcc, - 0x7f, 0x5f, 0xca, 0x55, 0xb8, 0x82, 0x46, 0x7e, 0xb1, 0xd3, 0x9b, 0xf5, 0x88, 0xdf, 0xa8, - 0x33, 0x2f, 0xa0, - ]; - static SHA512: [u8; 65] = [ - 0x41, 0x67, 0xf7, 0x21, 0x22, 0x5e, 0xfb, 0xd2, 0x5, 0xfc, 0xe, 0x96, 0x70, 0x0, 0x43, 0xc, - 0x4, 0xa0, 0xe, 0xef, 0x86, 0xa2, 0x9e, 0xdd, 0x40, 0xfa, 0xf4, 0x4e, 0x1b, 0xe2, 0x27, - 0x75, 0xea, 0xcf, 0x8e, 0x74, 0xfe, 0x87, 0x2f, 0xc0, 0x3d, 0xd4, 0x51, 0x2f, 0x45, 0x15, - 0xc6, 0xac, 0xa9, 0x7b, 0xb8, 0xf2, 0xf1, 0xf3, 0x84, 0x90, 0xd9, 0x78, 0x6b, 0x4, 0x3e, - 0x36, 0xed, 0xff, 0x35, - ]; - static PK_BYTES_02: [u8; 34] = [ - 0x81, 0x2, 0x9b, 0x63, 0x47, 0x39, 0x85, 0x5, 0xf5, 0xec, 0x93, 0x82, 0x6d, 0xc6, 0x1c, - 0x19, 0xf4, 0x7c, 0x66, 0xc0, 0x28, 0x3e, 0xe9, 0xbe, 0x98, 0xe, 0x29, 0xce, 0x32, 0x5a, - 0xf, 0x46, 0x79, 0xef, - ]; - static SIG_BYTES: [u8; 65] = [ - 0x82, 0xdf, 0x2b, 0x7, 0x1, 0x5f, 0x2e, 0x1, 0x67, 0x74, 0x18, 0x7e, 0xad, 0x4a, 0x4f, - 0x71, 0x9a, 0x14, 0xe3, 0xe1, 0xad, 0xa1, 0x78, 0xd6, 0x6c, 0xce, 0xcf, 0xa4, 0x5b, 0x63, - 0x30, 0x70, 0xc2, 0x43, 0xa2, 0xd7, 0x6e, 0xe0, 0x5d, 0x63, 0x49, 0xfe, 0x98, 0x69, 0x6c, - 0x1c, 0x4d, 0x9a, 0x67, 0x11, 0x24, 0xde, 0x40, 0xc5, 0x31, 0x71, 0xa4, 0xb2, 0x82, 0xb7, - 0x69, 0xb7, 0xc6, 0x96, 0xcd, - ]; - static TXOUTPOINT_BYTES: [u8; 37] = [ - 0x51, 0x53, 0xc6, 0x31, 0x13, 0xed, 0x18, 0x68, 0xfc, 0xa, 0xdf, 0x8e, 0xcd, 0xfd, 0x1f, - 0x4d, 0xd6, 0xe5, 0xe3, 0x85, 0x83, 0xa4, 0x9d, 0xb, 0x14, 0xe7, 0xf8, 0x87, 0xa4, 0xd1, - 0x61, 0x78, 0x21, 0x4, 0x0, 0x0, 0x0, - ]; - static TX_BYTES: [u8; 194] = [ - 0x52, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x59, 0x58, 0x95, 0xea, 0x20, 0x17, 0x9d, - 0xe8, 0x70, 0x52, 0xb4, 0x04, 0x6d, 0xfe, 0x6f, 0xd5, 0x15, 0x86, 0x05, 0x05, 0xd6, 0x51, - 0x1a, 0x90, 0x04, 0xcf, 0x12, 0xa1, 0xf9, 0x3c, 0xac, 0x7c, 0x01, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0x01, 0xde, 0xb8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xa9, - 0x14, 0x0f, 0x34, 0x44, 0xe2, 0x71, 0x62, 0x0c, 0x73, 0x68, 0x08, 0xaa, 0x7b, 0x33, 0xe3, - 0x70, 0xbd, 0x87, 0xcb, 0x5a, 0x07, 0x87, 0x02, 0x48, 0x30, 0x45, 0x02, 0x21, 0x00, 0xfb, - 0x60, 0xda, 0xd8, 0xdf, 0x4a, 0xf2, 0x84, 0x1a, 0xdc, 0x03, 0x46, 0x63, 0x8c, 0x16, 0xd0, - 0xb8, 0x03, 0x5f, 0x5e, 0x3f, 0x37, 0x53, 0xb8, 0x8d, 0xb1, 0x22, 0xe7, 0x0c, 0x79, 0xf9, - 0x37, 0x02, 0x20, 0x75, 0x6e, 0x66, 0x33, 0xb1, 0x7f, 0xd2, 0x71, 0x0e, 0x62, 0x63, 0x47, - 0xd2, 0x8d, 0x60, 0xb0, 0xa2, 0xd6, 0xcb, 0xb4, 0x1d, 0xe5, 0x17, 0x40, 0x64, 0x4b, 0x9f, - 0xb3, 0xba, 0x77, 0x51, 0x04, 0x01, 0x21, 0x02, 0x8f, 0xa9, 0x37, 0xca, 0x8c, 0xba, 0x21, - 0x97, 0xa3, 0x7c, 0x00, 0x71, 0x76, 0xed, 0x89, 0x41, 0x05, 0x5d, 0x3b, 0xcb, 0x86, 0x27, - 0xd0, 0x85, 0xe9, 0x45, 0x53, 0xe6, 0x2f, 0x05, 0x7d, 0xcc, 0x00, 0x00, 0x00, 0x00, - ]; - static PSBT_BYTES: [u8; 556] = [ - 0x53, 0x70, 0x73, 0x62, 0x74, 0xff, 0x01, 0x00, 0x75, 0x02, 0x00, 0x00, 0x00, 0x01, 0x26, - 0x81, 0x71, 0x37, 0x1e, 0xdf, 0xf2, 0x85, 0xe9, 0x37, 0xad, 0xee, 0xa4, 0xb3, 0x7b, 0x78, - 0x00, 0x0c, 0x05, 0x66, 0xcb, 0xb3, 0xad, 0x64, 0x64, 0x17, 0x13, 0xca, 0x42, 0x17, 0x1b, - 0xf6, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x02, 0xd3, 0xdf, 0xf5, 0x05, - 0x00, 0x00, 0x00, 0x00, 0x19, 0x76, 0xa9, 0x14, 0xd0, 0xc5, 0x99, 0x03, 0xc5, 0xba, 0xc2, - 0x86, 0x87, 0x60, 0xe9, 0x0f, 0xd5, 0x21, 0xa4, 0x66, 0x5a, 0xa7, 0x65, 0x20, 0x88, 0xac, - 0x00, 0xe1, 0xf5, 0x05, 0x00, 0x00, 0x00, 0x00, 0x17, 0xa9, 0x14, 0x35, 0x45, 0xe6, 0xe3, - 0x3b, 0x83, 0x2c, 0x47, 0x05, 0x0f, 0x24, 0xd3, 0xee, 0xb9, 0x3c, 0x9c, 0x03, 0x94, 0x8b, - 0xc7, 0x87, 0xb3, 0x2e, 0x13, 0x00, 0x00, 0x01, 0x00, 0xfd, 0xa5, 0x01, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x02, 0x89, 0xa3, 0xc7, 0x1e, 0xab, 0x4d, 0x20, 0xe0, 0x37, 0x1b, 0xbb, - 0xa4, 0xcc, 0x69, 0x8f, 0xa2, 0x95, 0xc9, 0x46, 0x3a, 0xfa, 0x2e, 0x39, 0x7f, 0x85, 0x33, - 0xcc, 0xb6, 0x2f, 0x95, 0x67, 0xe5, 0x01, 0x00, 0x00, 0x00, 0x17, 0x16, 0x00, 0x14, 0xbe, - 0x18, 0xd1, 0x52, 0xa9, 0xb0, 0x12, 0x03, 0x9d, 0xaf, 0x3d, 0xa7, 0xde, 0x4f, 0x53, 0x34, - 0x9e, 0xec, 0xb9, 0x85, 0xff, 0xff, 0xff, 0xff, 0x86, 0xf8, 0xaa, 0x43, 0xa7, 0x1d, 0xff, - 0x14, 0x48, 0x89, 0x3a, 0x53, 0x0a, 0x72, 0x37, 0xef, 0x6b, 0x46, 0x08, 0xbb, 0xb2, 0xdd, - 0x2d, 0x01, 0x71, 0xe6, 0x3a, 0xec, 0x6a, 0x48, 0x90, 0xb4, 0x01, 0x00, 0x00, 0x00, 0x17, - 0x16, 0x00, 0x14, 0xfe, 0x3e, 0x9e, 0xf1, 0xa7, 0x45, 0xe9, 0x74, 0xd9, 0x02, 0xc4, 0x35, - 0x59, 0x43, 0xab, 0xcb, 0x34, 0xbd, 0x53, 0x53, 0xff, 0xff, 0xff, 0xff, 0x02, 0x00, 0xc2, - 0xeb, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x19, 0x76, 0xa9, 0x14, 0x85, 0xcf, 0xf1, 0x09, 0x7f, - 0xd9, 0xe0, 0x08, 0xbb, 0x34, 0xaf, 0x70, 0x9c, 0x62, 0x19, 0x7b, 0x38, 0x97, 0x8a, 0x48, - 0x88, 0xac, 0x72, 0xfe, 0xf8, 0x4e, 0x2c, 0x00, 0x00, 0x00, 0x17, 0xa9, 0x14, 0x33, 0x97, - 0x25, 0xba, 0x21, 0xef, 0xd6, 0x2a, 0xc7, 0x53, 0xa9, 0xbc, 0xd0, 0x67, 0xd6, 0xc7, 0xa6, - 0xa3, 0x9d, 0x05, 0x87, 0x02, 0x47, 0x30, 0x44, 0x02, 0x20, 0x27, 0x12, 0xbe, 0x22, 0xe0, - 0x27, 0x0f, 0x39, 0x4f, 0x56, 0x83, 0x11, 0xdc, 0x7c, 0xa9, 0xa6, 0x89, 0x70, 0xb8, 0x02, - 0x5f, 0xdd, 0x3b, 0x24, 0x02, 0x29, 0xf0, 0x7f, 0x8a, 0x5f, 0x3a, 0x24, 0x02, 0x20, 0x01, - 0x8b, 0x38, 0xd7, 0xdc, 0xd3, 0x14, 0xe7, 0x34, 0xc9, 0x27, 0x6b, 0xd6, 0xfb, 0x40, 0xf6, - 0x73, 0x32, 0x5b, 0xc4, 0xba, 0xa1, 0x44, 0xc8, 0x00, 0xd2, 0xf2, 0xf0, 0x2d, 0xb2, 0x76, - 0x5c, 0x01, 0x21, 0x03, 0xd2, 0xe1, 0x56, 0x74, 0x94, 0x1b, 0xad, 0x4a, 0x99, 0x63, 0x72, - 0xcb, 0x87, 0xe1, 0x85, 0x6d, 0x36, 0x52, 0x60, 0x6d, 0x98, 0x56, 0x2f, 0xe3, 0x9c, 0x5e, - 0x9e, 0x7e, 0x41, 0x3f, 0x21, 0x05, 0x02, 0x48, 0x30, 0x45, 0x02, 0x21, 0x00, 0xd1, 0x2b, - 0x85, 0x2d, 0x85, 0xdc, 0xd9, 0x61, 0xd2, 0xf5, 0xf4, 0xab, 0x66, 0x06, 0x54, 0xdf, 0x6e, - 0xed, 0xcc, 0x79, 0x4c, 0x0c, 0x33, 0xce, 0x5c, 0xc3, 0x09, 0xff, 0xb5, 0xfc, 0xe5, 0x8d, - 0x02, 0x20, 0x67, 0x33, 0x8a, 0x8e, 0x0e, 0x17, 0x25, 0xc1, 0x97, 0xfb, 0x1a, 0x88, 0xaf, - 0x59, 0xf5, 0x1e, 0x44, 0xe4, 0x25, 0x5b, 0x20, 0x16, 0x7c, 0x86, 0x84, 0x03, 0x1c, 0x05, - 0xd1, 0xf2, 0x59, 0x2a, 0x01, 0x21, 0x02, 0x23, 0xb7, 0x2b, 0xee, 0xf0, 0x96, 0x5d, 0x10, - 0xbe, 0x07, 0x78, 0xef, 0xec, 0xd6, 0x1f, 0xca, 0xc6, 0xf7, 0x9a, 0x4e, 0xa1, 0x69, 0x39, - 0x33, 0x80, 0x73, 0x44, 0x64, 0xf8, 0x4f, 0x2a, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, - ]; static U8_CONCEALED: [u8; 20] = [ 0x99, 0x3c, 0xfd, 0x1, 0x69, 0xe, 0xa0, 0xa8, 0xb2, 0x83, 0x1e, 0xf0, 0x25, 0x36, 0xce, @@ -654,30 +443,6 @@ mod test { 0xf8, 0x3b, 0x1b, 0xcd, 0xd8, 0x82, 0x55, 0xe1, 0xf9, 0x37, 0x52, 0xeb, 0x20, 0x90, 0xfe, 0xa9, 0x14, 0x4f, 0x8a, 0xe1, ]; - static BITCOIN160_CONCEALED: [u8; 20] = [ - 0x27, 0x57, 0x9d, 0x2f, 0x5f, 0x71, 0x99, 0x6b, 0x18, 0x92, 0xc6, 0xc1, 0x7, 0xaa, 0x93, - 0xf2, 0x3d, 0x3d, 0xdd, 0xac, - ]; - static BITCOIN256_CONCEALED: [u8; 20] = [ - 0xe2, 0xa3, 0x94, 0x7e, 0x77, 0xfd, 0x76, 0x1f, 0xf6, 0xb6, 0x64, 0xa, 0xab, 0xc6, 0x59, - 0xdd, 0x24, 0x4d, 0x15, 0x98, - ]; - static SHA256_CONCEALED: [u8; 20] = [ - 0x57, 0x7f, 0xdd, 0xbc, 0x8c, 0xaa, 0x57, 0x8f, 0x57, 0xde, 0x9, 0x74, 0xe1, 0x31, 0x61, - 0xeb, 0xd0, 0x1f, 0x4e, 0x80, - ]; - static SHA512_CONCEALED: [u8; 20] = [ - 0xf7, 0x97, 0x94, 0xad, 0x58, 0xc7, 0x6, 0x4a, 0xfa, 0x3a, 0x6b, 0xb4, 0x3f, 0x29, 0xf7, - 0x67, 0x3a, 0xca, 0x12, 0x17, - ]; - static PK_BYTES_02_CONCEALED: [u8; 20] = [ - 0x76, 0xf0, 0x2c, 0x49, 0x2f, 0x3f, 0xf2, 0xee, 0x2b, 0x0, 0x4a, 0x92, 0xf8, 0xd9, 0x8f, - 0x26, 0x11, 0xd8, 0x96, 0xf3, - ]; - static SIG_BYTES_CONCEALED: [u8; 20] = [ - 0xe2, 0x17, 0xd8, 0xea, 0xc5, 0x15, 0x42, 0xf2, 0xcd, 0x5e, 0xe7, 0x70, 0xda, 0x99, 0x8, - 0x92, 0x84, 0x7a, 0x29, 0xf6, - ]; // Normal encode/decode testing #[test] @@ -695,15 +460,6 @@ mod test { (F_64, Revealed), (BYTES, Revealed), (STRING, Revealed), - (BITCOIN160, Revealed), - (BITCOIN256, Revealed), - (SHA256, Revealed), - (SHA512, Revealed), - (PK_BYTES_02, Revealed), - (SIG_BYTES, Revealed), - (TXOUTPOINT_BYTES, Revealed), - (TX_BYTES, Revealed), - (PSBT_BYTES, Revealed) ); } @@ -724,15 +480,6 @@ mod test { (F_64, Revealed, err), (BYTES, Revealed, err), (STRING, Revealed, err), - (BITCOIN160, Revealed, err), - (BITCOIN256, Revealed, err), - (SHA256, Revealed, err), - (SHA512, Revealed, err), - (PK_BYTES_02, Revealed, err), - (SIG_BYTES, Revealed, err), - (TXOUTPOINT_BYTES, Revealed, err), - (TX_BYTES, Revealed, err), - (PSBT_BYTES, Revealed, err) ); } @@ -762,12 +509,6 @@ mod test { (F_64, F64_CONCEALED, Revealed), (BYTES, BYTES_CONCEALED, Revealed), (STRING, STRING_CONCEALED, Revealed), - (BITCOIN160, BITCOIN160_CONCEALED, Revealed), - (BITCOIN256, BITCOIN256_CONCEALED, Revealed), - (SHA256, SHA256_CONCEALED, Revealed), - (SHA512, SHA512_CONCEALED, Revealed), - (PK_BYTES_02, PK_BYTES_02_CONCEALED, Revealed), - (SIG_BYTES, SIG_BYTES_CONCEALED, Revealed) ); } } From 595dce1216c0317ce31115180190f0968fff6da1 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Thu, 9 Jun 2022 23:07:06 +0200 Subject: [PATCH 03/15] Add 128 bit support to schema --- src/schema/state.rs | 66 ++++++++++++++++++++++++++++++++------------- src/schema/types.rs | 11 +++----- 2 files changed, 52 insertions(+), 25 deletions(-) diff --git a/src/schema/state.rs b/src/schema/state.rs index 23d944e4..51a1d7ac 100644 --- a/src/schema/state.rs +++ b/src/schema/state.rs @@ -386,6 +386,22 @@ mod _strict_encoding { get_bounds(min..=max, core::u64::MIN..=core::u64::MAX, true)?; write_min_max!(min, max, e, len); } + Bits::Bit128 => { + let min = u128::try_from(*min) + .map_err(|_| Error::ValueOutOfRange( + "Minimum value for Unsigned data type are outside of bit dimension", + (core::u128::MIN as u128)..(core::u128::MAX as u128), *min as u128))?; + let max = u128::try_from(*max) + .map_err(|_| Error::ValueOutOfRange( + "Maximum value for Unsigned data type are outside of bit dimension", + (core::u128::MIN as u128)..(core::u128::MAX as u128), *max as u128))?; + let (min, max) = get_bounds( + min..=max, + core::u128::MIN..=core::u128::MAX, + true, + )?; + write_min_max!(min, max, e, len); + } } len } @@ -446,6 +462,22 @@ mod _strict_encoding { get_bounds(min..=max, core::i64::MIN..=core::i64::MAX, true)?; write_min_max!(min, max, e, len); } + Bits::Bit128 => { + let min = i128::try_from(*min) + .map_err(|_| Error::ValueOutOfRange( + "Minimum value for Unsigned data type are outside of bit dimension", + (core::i128::MIN as u128)..(core::i128::MAX as u128), *min as u128))?; + let max = i128::try_from(*max) + .map_err(|_| Error::ValueOutOfRange( + "Maximum value for Unsigned data type are outside of bit dimension", + (core::i128::MIN as u128)..(core::i128::MAX as u128), *max as u128))?; + let (min, max) = get_bounds( + min..=max, + core::i128::MIN..=core::i128::MAX, + true, + )?; + write_min_max!(min, max, e, len); + } } len } @@ -547,15 +579,14 @@ mod _strict_encoding { u64::from_le_bytes(min) as u128, u64::from_le_bytes(max) as u128, ) - } /* - Bits::Bit128 => { - let mut min = [0u8; 16]; - let mut max = [0u8; 16]; - d.read_exact(&mut min)?; - d.read_exact(&mut max)?; - (u128::from_le_bytes(min), u128::from_le_bytes(max)) - } - */ + } + Bits::Bit128 => { + let mut min = [0u8; 16]; + let mut max = [0u8; 16]; + d.read_exact(&mut min)?; + d.read_exact(&mut max)?; + (u128::from_le_bytes(min), u128::from_le_bytes(max)) + } }; DataFormat::Unsigned(bits, min, max) } @@ -601,15 +632,14 @@ mod _strict_encoding { i64::from_le_bytes(min) as i128, i64::from_le_bytes(max) as i128, ) - } /* - Bits::Bit128 => { - let mut min = [0u8; 16]; - let mut max = [0u8; 16]; - d.read_exact(&mut min)?; - d.read_exact(&mut max)?; - (i128::from_le_bytes(min), i128::from_le_bytes(max)) - } - */ + } + Bits::Bit128 => { + let mut min = [0u8; 16]; + let mut max = [0u8; 16]; + d.read_exact(&mut min)?; + d.read_exact(&mut max)?; + (i128::from_le_bytes(min), i128::from_le_bytes(max)) + } }; DataFormat::Integer(bits, min, max) } diff --git a/src/schema/types.rs b/src/schema/types.rs index 48b1388b..f8fa4d47 100644 --- a/src/schema/types.rs +++ b/src/schema/types.rs @@ -84,13 +84,10 @@ pub enum Bits { Bit16 = 2, Bit32 = 4, Bit64 = 8, - /* TODO #14: Add support later once bitcoin library will start - * supporting consensus-encoding of the native rust `u128` - * type Bit128 = 16, - *Bit256 = 32, */ + Bit128 = 16, + // Bit256 = 32, } -// TODO #46: Add support later once bitcoin library will start supporting -// consensus-encoding of the native rust `u128` type +// TODO #46: Add support for 256-bit types impl Bits { pub fn max_value(&self) -> u128 { @@ -99,7 +96,7 @@ impl Bits { Bits::Bit16 => core::u16::MAX as u128, Bits::Bit32 => core::u32::MAX as u128, Bits::Bit64 => core::u64::MAX as u128, - //Bits::Bit128 => core::u128::MAX as u128, + Bits::Bit128 => core::u128::MAX as u128, } } From 8296d314d3554c87fb781821bc9507e76d724a5f Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Thu, 9 Jun 2022 23:07:45 +0200 Subject: [PATCH 04/15] Remove non-primitive data types from schema --- src/schema/mod.rs | 6 +- src/schema/schema.rs | 8 +- src/schema/state.rs | 108 ++++++-------------- src/schema/types.rs | 227 ------------------------------------------- 4 files changed, 36 insertions(+), 313 deletions(-) diff --git a/src/schema/mod.rs b/src/schema/mod.rs index 92877f7f..dbdf0def 100644 --- a/src/schema/mod.rs +++ b/src/schema/mod.rs @@ -28,10 +28,10 @@ pub use script::{ Action, AssignmentAbi, AssignmentAction, ExecutableCode, ExtensionAbi, ExtensionAction, GenericAction, GenesisAbi, GenesisAction, NodeAction, TransitionAbi, TransitionAction, VmType, }; -pub use state::{DataFormat, DiscreteFiniteFieldFormat, StateFormat, StateSchema, StateType}; -pub use types::{ - elliptic_curve, Bits, DigestAlgorithm, EllipticCurve, Occurrences, OccurrencesError, +pub use state::{ + DataFormat, DiscreteFiniteFieldFormat, StateFormat, StateSchema, StateType, }; +pub use types::{Bits, Occurrences, OccurrencesError}; mod verify { use crate::validation; diff --git a/src/schema/schema.rs b/src/schema/schema.rs index 4de0afef..48cb5237 100644 --- a/src/schema/schema.rs +++ b/src/schema/schema.rs @@ -821,14 +821,14 @@ pub(crate) mod test { rgb_features: FlagVec::default(), root_id: Default::default(), field_types: bmap! { - FIELD_TICKER => DataFormat::String(16), - FIELD_NAME => DataFormat::String(256), - FIELD_DESCRIPTION => DataFormat::String(1024), + FIELD_TICKER => DataFormat::UniString(16), + FIELD_NAME => DataFormat::UniString(256), + FIELD_DESCRIPTION => DataFormat::UniString(1024), FIELD_TOTAL_SUPPLY => DataFormat::Unsigned(Bits::Bit64, 0, core::u64::MAX as u128), FIELD_PRECISION => DataFormat::Unsigned(Bits::Bit64, 0, 18u128), FIELD_ISSUED_SUPPLY => DataFormat::Unsigned(Bits::Bit64, 0, core::u64::MAX as u128), FIELD_DUST_LIMIT => DataFormat::Unsigned(Bits::Bit64, 0, core::u64::MAX as u128), - FIELD_PRUNE_PROOF => DataFormat::Bytes(core::u16::MAX), + FIELD_PRUNE_PROOF => DataFormat::ByteString(core::u16::MAX), FIELD_TIMESTAMP => DataFormat::Unsigned(Bits::Bit64, 0, core::u64::MAX as u128), FIELD_PROOF_OF_BURN => DataFormat::TxOutPoint }, diff --git a/src/schema/state.rs b/src/schema/state.rs index 51a1d7ac..a1abf9ab 100644 --- a/src/schema/state.rs +++ b/src/schema/state.rs @@ -16,7 +16,7 @@ use std::io; use num_derive::{FromPrimitive, ToPrimitive}; -use super::{elliptic_curve, script, Bits, DigestAlgorithm, EllipticCurve}; +use super::{script, Bits}; #[derive(Clone, PartialEq, Debug, Display, StrictEncode, StrictDecode)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(crate = "serde_crate"))] @@ -88,16 +88,9 @@ pub enum DataFormat { Integer(Bits, i128, i128), Float(Bits, f64, f64), Enum(BTreeSet), - String(u16), - Bytes(u16), - Digest(DigestAlgorithm), - PublicKey(EllipticCurve, elliptic_curve::PointSerialization), - Signature(elliptic_curve::SignatureAlgorithm), - // TODO #33: Add externally stored data container id - // Container(BlobId, MIME, u64 /* AES encryption key / salt */), - TxOutPoint, - Tx, - Psbt, + UniString(u16), + ByteString(u16), + FixedBytes(u16), } // Convenience methods @@ -196,16 +189,9 @@ mod _strict_encoding { Integer = 1, Float = 2, Enum = 3, - String = 4, - Bytes = 5, - // Cryptographic types - Digest = 0x10, - PublicKey = 0x11, - Signature = 0x12, - // Composed types - TxOutPoint = 0x20, - Tx = 0x21, - Psbt = 0x22, + UniString = 4, + ByteString = 5, + FixedBytes = 6, } impl_enum_strict_encoding!(EncodingTag); @@ -511,24 +497,15 @@ mod _strict_encoding { DataFormat::Enum(values) => { strict_encode_list!(e; EncodingTag::Enum, values) } - DataFormat::String(size) => { - strict_encode_list!(e; EncodingTag::String, size) + DataFormat::UniString(size) => { + strict_encode_list!(e; EncodingTag::UniString, size) } - DataFormat::Bytes(size) => { - strict_encode_list!(e; EncodingTag::Bytes, size) + DataFormat::ByteString(size) => { + strict_encode_list!(e; EncodingTag::ByteString, size) } - DataFormat::Digest(algo) => { - strict_encode_list!(e; EncodingTag::Digest, algo) + DataFormat::FixedBytes(size) => { + strict_encode_list!(e; EncodingTag::FixedBytes, size) } - DataFormat::PublicKey(curve, ser) => { - strict_encode_list!(e; EncodingTag::PublicKey, curve, ser) - } - DataFormat::Signature(algo) => { - strict_encode_list!(e; EncodingTag::Signature, algo) - } - DataFormat::TxOutPoint => EncodingTag::TxOutPoint.strict_encode(&mut e)?, - DataFormat::Tx => EncodingTag::Tx.strict_encode(&mut e)?, - DataFormat::Psbt => EncodingTag::Psbt.strict_encode(&mut e)?, }) } } @@ -669,20 +646,18 @@ mod _strict_encoding { }; DataFormat::Float(bits, min, max) } - EncodingTag::Enum => DataFormat::Enum(BTreeSet::::strict_decode(&mut d)?), - EncodingTag::String => DataFormat::String(u16::strict_decode(&mut d)?), - EncodingTag::Bytes => DataFormat::Bytes(u16::strict_decode(&mut d)?), - EncodingTag::Digest => DataFormat::Digest(DigestAlgorithm::strict_decode(&mut d)?), - EncodingTag::PublicKey => DataFormat::PublicKey( - EllipticCurve::strict_decode(&mut d)?, - elliptic_curve::PointSerialization::strict_decode(&mut d)?, - ), - EncodingTag::Signature => DataFormat::Signature( - elliptic_curve::SignatureAlgorithm::strict_decode(&mut d)?, - ), - EncodingTag::TxOutPoint => DataFormat::TxOutPoint, - EncodingTag::Tx => DataFormat::Tx, - EncodingTag::Psbt => DataFormat::Psbt, + EncodingTag::Enum => { + DataFormat::Enum(BTreeSet::::strict_decode(&mut d)?) + } + EncodingTag::UniString => { + DataFormat::UniString(u16::strict_decode(&mut d)?) + } + EncodingTag::ByteString => { + DataFormat::ByteString(u16::strict_decode(&mut d)?) + } + EncodingTag::FixedBytes => { + DataFormat::FixedBytes(u16::strict_decode(&mut d)?) + } }) } } @@ -800,7 +775,7 @@ mod _validation { }); } - (Self::String(len), data::Revealed::String(val)) => { + (Self::UniString(len), data::Revealed::String(val)) => { if val.len() > *len as usize { status.add_failure(validation::Failure::SchemaWrongDataLength { field_or_state_type: item_id, @@ -809,7 +784,7 @@ mod _validation { }); } } - (Self::Bytes(len), data::Revealed::Bytes(val)) => { + (Self::ByteString(len), data::Revealed::Bytes(val)) => { if val.len() > *len as usize { status.add_failure(validation::Failure::SchemaWrongDataLength { field_or_state_type: item_id, @@ -819,31 +794,6 @@ mod _validation { } } - (Self::Digest(DigestAlgorithm::Sha256), data::Revealed::Sha256(_)) => {} - (Self::Digest(DigestAlgorithm::Sha512), data::Revealed::Sha512(_)) => {} - (Self::Digest(DigestAlgorithm::Bitcoin160), data::Revealed::Bitcoin160(_)) => {} - (Self::Digest(DigestAlgorithm::Bitcoin256), data::Revealed::Bitcoin256(_)) => {} - - ( - Self::PublicKey(EllipticCurve::Secp256k1, _), - data::Revealed::Secp256k1Pubkey(_), - ) => {} - ( - Self::PublicKey(EllipticCurve::Curve25519, _), - data::Revealed::Curve25519Pubkey(_), - ) => {} - ( - Self::Signature(elliptic_curve::SignatureAlgorithm::Ecdsa), - data::Revealed::Secp256k1ECDSASignature(_), - ) => {} - ( - Self::Signature(elliptic_curve::SignatureAlgorithm::Ed25519), - data::Revealed::Ed25519Signature(_), - ) => {} - (Self::TxOutPoint, data::Revealed::TxOutPoint(_)) => {} - (Self::Tx, data::Revealed::Tx(_)) => {} - (Self::Psbt, data::Revealed::Psbt(_)) => {} - _ => { status.add_failure(validation::Failure::SchemaMismatchedDataType(item_id)); } @@ -1323,7 +1273,7 @@ mod test { // Test failure cases for String format let string_data = Revealed::String("Hello".to_string()); - let string_format = DataFormat::String(2u16); + let string_format = DataFormat::UniString(2u16); assert_eq!( string_format.validate(3, &string_data).failures[0], Failure::SchemaWrongDataLength { @@ -1336,7 +1286,7 @@ mod test { // Test failure cases for Bytes format let bytes = vec![1u8, 2u8, 3u8]; let bytes_data = Revealed::Bytes(bytes); - let bytes_format = DataFormat::Bytes(2u16); + let bytes_format = DataFormat::ByteString(2u16); assert_eq!( bytes_format.validate(3, &bytes_data).failures[0], Failure::SchemaWrongDataLength { diff --git a/src/schema/types.rs b/src/schema/types.rs index f8fa4d47..1f071eb6 100644 --- a/src/schema/types.rs +++ b/src/schema/types.rs @@ -188,120 +188,10 @@ pub struct OccurrencesError { pub found: u16, } -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Display, ToPrimitive, FromPrimitive)] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", rename_all = "lowercase") -)] -#[display(Debug)] -#[repr(u8)] -#[non_exhaustive] -pub enum DigestAlgorithm { - // Single-path RIPEMD-160 is not secure and should not be used; see - // - //Ripemd160 = 0b_0000_1000_u8, - Sha256 = 0b_0001_0001_u8, - Sha512 = 0b_0001_0010_u8, - Bitcoin160 = 0b_0100_1000_u8, - Bitcoin256 = 0b_0101_0001_u8, - /* Each tagged hash is a type on it's own, so the following umbrella - * type was removed; a plain sha256 type must be used instead - *Tagged256 = 0b_1100_0000_u8, */ -} - -pub mod elliptic_curve { - use num_derive::{FromPrimitive, ToPrimitive}; - - #[derive( - Clone, - Copy, - PartialEq, - Eq, - PartialOrd, - Ord, - Debug, - Display, - ToPrimitive, - FromPrimitive - )] - #[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", rename_all = "lowercase") - )] - #[display(Debug)] - #[repr(u8)] - #[non_exhaustive] - pub enum EllipticCurve { - Secp256k1 = 0x00, - Curve25519 = 0x10, - } - - #[derive( - Clone, - Copy, - PartialEq, - Eq, - PartialOrd, - Ord, - Debug, - Display, - ToPrimitive, - FromPrimitive - )] - #[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", rename_all = "lowercase") - )] - #[display(Debug)] - #[repr(u8)] - #[non_exhaustive] - pub enum SignatureAlgorithm { - Ecdsa = 0, - Schnorr, - Ed25519, - } - - #[derive( - Clone, - Copy, - PartialEq, - Eq, - PartialOrd, - Ord, - Debug, - Display, - ToPrimitive, - FromPrimitive - )] - #[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", rename_all = "lowercase") - )] - #[display(Debug)] - #[repr(u8)] - #[non_exhaustive] - pub enum PointSerialization { - Uncompressed = 0, - Compressed, - Bip340, - } -} -pub use elliptic_curve::EllipticCurve; - mod _strict_encoding { use strict_encoding::{Error, StrictDecode, StrictEncode}; - use super::*; - - impl_enum_strict_encoding!(DigestAlgorithm); impl_enum_strict_encoding!(Bits); - impl_enum_strict_encoding!(EllipticCurve); - impl_enum_strict_encoding!(elliptic_curve::SignatureAlgorithm); - impl_enum_strict_encoding!(elliptic_curve::PointSerialization); impl StrictEncode for Occurrences { fn strict_encode(&self, mut e: E) -> Result { @@ -472,35 +362,6 @@ mod test { assert_eq!(wc2, Occurrences::OnceOrUpTo(255)); } - #[test] - fn test_digest_algorithm() { - let sha256_byte: [u8; 1] = [0x11]; - let sha512_byte: [u8; 1] = [0x12]; - let bitcoin160_byte: [u8; 1] = [0x48]; - let bitcoin256_byte: [u8; 1] = [0x51]; - - test_encode!( - (sha256_byte, DigestAlgorithm), - (sha512_byte, DigestAlgorithm), - (bitcoin160_byte, DigestAlgorithm), - (bitcoin256_byte, DigestAlgorithm) - ); - - let sha256 = DigestAlgorithm::strict_decode(&[0x11][..]).unwrap(); - let sha512 = DigestAlgorithm::strict_decode(&[0x12][..]).unwrap(); - let bitcoin160 = DigestAlgorithm::strict_decode(&[0x48][..]).unwrap(); - let bitcoin256 = DigestAlgorithm::strict_decode(&[0x51][..]).unwrap(); - - assert_eq!(sha256, DigestAlgorithm::Sha256); - assert_eq!(sha512, DigestAlgorithm::Sha512); - assert_eq!(bitcoin160, DigestAlgorithm::Bitcoin160); - assert_eq!(bitcoin256, DigestAlgorithm::Bitcoin256); - } - - #[test] - #[should_panic(expected = "EnumValueNotKnown")] - fn test_digest_panic() { DigestAlgorithm::strict_decode(&[0x17][..]).unwrap(); } - #[test] fn test_bits() { let bit8 = Bits::strict_decode(&[0x01][..]).unwrap(); @@ -532,94 +393,6 @@ mod test { #[should_panic(expected = "EnumValueNotKnown")] fn test_bits_panic() { Bits::strict_decode(&[0x12][..]).unwrap(); } - #[test] - fn test_elliptic_curve() { - let secp: [u8; 1] = [0x00]; - let c25519: [u8; 1] = [0x10]; - - test_encode!( - (secp, elliptic_curve::EllipticCurve), - (c25519, elliptic_curve::EllipticCurve) - ); - - assert_eq!( - elliptic_curve::EllipticCurve::strict_decode(&[0x00][..]).unwrap(), - elliptic_curve::EllipticCurve::Secp256k1 - ); - - assert_eq!( - elliptic_curve::EllipticCurve::strict_decode(&[0x10][..]).unwrap(), - elliptic_curve::EllipticCurve::Curve25519 - ); - } - - #[test] - #[should_panic(expected = "EnumValueNotKnown")] - fn test_elliptic_curve_panic() { - elliptic_curve::EllipticCurve::strict_decode(&[0x09][..]).unwrap(); - } - - #[test] - fn test_signature_algo() { - let ecdsa_byte: [u8; 1] = [0x00]; - let schnorr_byte: [u8; 1] = [0x01]; - let ed25519_byte: [u8; 1] = [0x02]; - - test_encode!( - (ecdsa_byte, elliptic_curve::SignatureAlgorithm), - (schnorr_byte, elliptic_curve::SignatureAlgorithm), - (ed25519_byte, elliptic_curve::SignatureAlgorithm) - ); - - let ecdsa = elliptic_curve::SignatureAlgorithm::strict_decode(&[0x00][..]).unwrap(); - let schnorr = elliptic_curve::SignatureAlgorithm::strict_decode(&[0x01][..]).unwrap(); - let ed25519 = elliptic_curve::SignatureAlgorithm::strict_decode(&[0x02][..]).unwrap(); - - assert_eq!(ecdsa, elliptic_curve::SignatureAlgorithm::Ecdsa); - assert_eq!(schnorr, elliptic_curve::SignatureAlgorithm::Schnorr); - assert_eq!(ed25519, elliptic_curve::SignatureAlgorithm::Ed25519); - } - - #[test] - #[should_panic(expected = "EnumValueNotKnown")] - fn test_signature_algo_panic() { - elliptic_curve::SignatureAlgorithm::strict_decode(&[0x03][..]).unwrap(); - } - - #[test] - fn test_point_ser() { - let uncompressed_byte: [u8; 1] = [0x00]; - let compressed_byte: [u8; 1] = [0x01]; - let schnorr_bip_byte: [u8; 1] = [0x02]; - - test_encode!( - (uncompressed_byte, elliptic_curve::PointSerialization), - (compressed_byte, elliptic_curve::PointSerialization), - (schnorr_bip_byte, elliptic_curve::PointSerialization) - ); - - assert_eq!( - elliptic_curve::PointSerialization::strict_decode(&[0x00][..]).unwrap(), - elliptic_curve::PointSerialization::Uncompressed - ); - - assert_eq!( - elliptic_curve::PointSerialization::strict_decode(&[0x01][..]).unwrap(), - elliptic_curve::PointSerialization::Compressed - ); - - assert_eq!( - elliptic_curve::PointSerialization::strict_decode(&[0x02][..]).unwrap(), - elliptic_curve::PointSerialization::Bip340 - ); - } - - #[test] - #[should_panic(expected = "EnumValueNotKnown")] - fn test_point_ser_panic() { - elliptic_curve::PointSerialization::strict_decode(&[0x03][..]).unwrap(); - } - #[test] fn test_unsigned() { let u8_unsigned = core::u8::MAX; From e89a42483069e066893bad9eef5c7300cb9dc7c4 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Thu, 9 Jun 2022 23:08:14 +0200 Subject: [PATCH 05/15] Draft new primitive schema type system for rich data --- src/schema/primitives.rs | 54 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 src/schema/primitives.rs diff --git a/src/schema/primitives.rs b/src/schema/primitives.rs new file mode 100644 index 00000000..7d10c9ff --- /dev/null +++ b/src/schema/primitives.rs @@ -0,0 +1,54 @@ + +pub enum PrimitiveType { + U8 { min: u8, max: u8 }, + U16 { min: u16, max: u16 }, + U32 { min: u32, max: u32 }, + U64 { min: u64, max: u64 }, + U128 { min: u128, max: u128 }, + U256 { min: u256, max: u256 }, + U512 { min: u512, max: u512 }, + U1024 { min: u1024, max: u1024 }, + + I8 { min: i8, max: i8 }, + I16 { min: i16, max: i16 }, + I32 { min: i32, max: i32 }, + I64 { min: i64, max: i64 }, + I128 { min: i128, max: i128 }, + I256 { min: i256, max: i256 }, + I512 { min: i512, max: i512 }, + I1024 { min: i1024, max: i1024 }, + + F16b, + F16, + F32, + F64, + F80, + F128, + F256, + F512, +} + +pub enum DataType { + Primitive(PrimitiveType), + Union(BTreeSet), + Enum(BTreeSet), + Fixed { + count: u16, + ty: PrimitiveType, + }, + Array { + min: u16, + max: u16, + ty: PrimitiveType, + }, + Ascii { + min_chars: u16, + max_chars: u16, + }, + Unicode { + min_chars: u16, + max_chars: u16, + }, +} + +const RSA: DataType = DataType::Fixed { count: 4096, ty: PrimitiveType::U8 { min: 0, max: u8::MAX } }; From c26254461dd8957b4e7a48fcbe605cdfacf2890a Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Thu, 9 Jun 2022 23:12:50 +0200 Subject: [PATCH 06/15] Remove curve26619 depencency Not required anymore after simplification of schema and contract data types --- Cargo.lock | 1 - Cargo.toml | 3 -- src/bech32.rs | 130 +++++++++++++++++++++++--------------------------- 3 files changed, 60 insertions(+), 74 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 07649f16..35753eeb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1145,7 +1145,6 @@ dependencies = [ "commit_verify", "deflate 0.8.6", "descriptor-wallet", - "ed25519-dalek", "electrum-client", "grin_secp256k1zkp", "inflate", diff --git a/Cargo.toml b/Cargo.toml index e0c82ff7..bae3a23b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -56,9 +56,6 @@ bitcoin_hashes = "~0.10.0" # we need macro from here miniscript = { version = "~7.0.0", features = ["compiler"] } electrum-client = { version = "0.10.0", optional = true } bech32 = "~0.9.0" -# Used only as a part of RGB for encoding Ed25519 key data (for instance as -# a part of Tor address) -ed25519-dalek = "~1.0.1" # Core rust projects # ------------------ # This strange naming is a workaround for cargo inability to define required diff --git a/src/bech32.rs b/src/bech32.rs index 7bdef4a0..91bcc5fe 100644 --- a/src/bech32.rs +++ b/src/bech32.rs @@ -57,26 +57,6 @@ pub enum Bech32 { )] Bulletproof(secp256k1zkp::pedersen::RangeProof), - /// Curve25519 public key - /// - /// HRP: `curve25519pk` - #[from] - #[cfg_attr( - feature = "serde", - serde(serialize_with = "to_bech32_str", deserialize_with = "from_bech32_str") - )] - Curve25519Pk(ed25519_dalek::PublicKey), - - /// Ed25519 signature - /// - /// HRP: `ed25519sign` - #[from] - #[cfg_attr( - feature = "serde", - serde(serialize_with = "to_bech32_str", deserialize_with = "from_bech32_str") - )] - Ed25519Sign(ed25519_dalek::Signature), - /// Blinded UTXO for assigning RGB state to. /// /// HRP: `utxob` @@ -167,10 +147,6 @@ impl Bech32 { pub const HRP_PEDERSEN: &'static str = "pedersen"; /// HRP for a Bech32-encoded blinded bulletproof range proof data pub const HRP_BULLETPROOF: &'static str = "bulletproof"; - /// HRP for a Bech32-encoded blinded bulletproof range proof data - pub const HRP_CURVE25519OPK: &'static str = "curve25519pk"; - /// HRP for a Bech32-encoded blinded bulletproof range proof data - pub const HRP_ED25519OSIGN: &'static str = "ed25519sign"; /// HRP for a Bech32-encoded blinded UTXO data pub const HRP_OUTPOINT: &'static str = "utxob"; @@ -318,28 +294,6 @@ impl TryFrom for secp256k1zkp::pedersen::RangeProof { } } -impl TryFrom for ed25519_dalek::PublicKey { - type Error = Error; - - fn try_from(bech32: Bech32) -> Result { - match bech32 { - Bech32::Curve25519Pk(obj) => Ok(obj), - _ => Err(Error::WrongType), - } - } -} - -impl TryFrom for ed25519_dalek::Signature { - type Error = Error; - - fn try_from(bech32: Bech32) -> Result { - match bech32 { - Bech32::Ed25519Sign(obj) => Ok(obj), - _ => Err(Error::WrongType), - } - } -} - impl TryFrom for seal::Confidential { type Error = Error; @@ -438,18 +392,36 @@ impl FromStr for Bech32 { // TODO: Update to Bech32m and check variant Ok(match hrp { - x if x == Self::HRP_PEDERSEN => Self::PedersenCommitment(strict_deserialize(&data)?), - x if x == Self::HRP_BULLETPROOF => Self::Bulletproof(strict_deserialize(&data)?), - x if x == Self::HRP_CURVE25519OPK => Self::Curve25519Pk(strict_deserialize(&data)?), - x if x == Self::HRP_ED25519OSIGN => Self::Ed25519Sign(strict_deserialize(&data)?), - x if x == Self::HRP_OUTPOINT => Self::BlindedUtxo(strict_deserialize(&data)?), - x if x == Self::HRP_SCHEMA_ID => Self::SchemaId(strict_deserialize(&data)?), - x if x == Self::HRP_CONTRACT_ID => Self::ContractId(strict_deserialize(&data)?), - x if x == Self::HRP_SCHEMA => Self::Schema(Bech32::raw_decode(&data)?), - x if x == Self::HRP_GENESIS => Self::Genesis(Bech32::raw_decode(&data)?), - x if x == Self::HRP_EXTENSION => Self::Extension(Bech32::raw_decode(&data)?), - x if x == Self::HRP_TRANSITION => Self::Transition(Bech32::raw_decode(&data)?), - x if x == Self::HRP_DISCLOSURE => Self::Disclosure(Bech32::raw_decode(&data)?), + x if x == Self::HRP_PEDERSEN => { + Self::PedersenCommitment(strict_deserialize(&data)?) + } + x if x == Self::HRP_BULLETPROOF => { + Self::Bulletproof(strict_deserialize(&data)?) + } + x if x == Self::HRP_OUTPOINT => { + Self::BlindedUtxo(strict_deserialize(&data)?) + } + x if x == Self::HRP_SCHEMA_ID => { + Self::SchemaId(strict_deserialize(&data)?) + } + x if x == Self::HRP_CONTRACT_ID => { + Self::ContractId(strict_deserialize(&data)?) + } + x if x == Self::HRP_SCHEMA => { + Self::Schema(Bech32::raw_decode(&data)?) + } + x if x == Self::HRP_GENESIS => { + Self::Genesis(Bech32::raw_decode(&data)?) + } + x if x == Self::HRP_EXTENSION => { + Self::Extension(Bech32::raw_decode(&data)?) + } + x if x == Self::HRP_TRANSITION => { + Self::Transition(Bech32::raw_decode(&data)?) + } + x if x == Self::HRP_DISCLOSURE => { + Self::Disclosure(Bech32::raw_decode(&data)?) + } other => Self::Other(other, data), }) } @@ -458,18 +430,36 @@ impl FromStr for Bech32 { impl Display for Bech32 { fn fmt(&self, f: &mut Formatter<'_>) -> ::core::fmt::Result { let (hrp, data) = match self { - Self::PedersenCommitment(obj) => (Self::HRP_PEDERSEN, strict_serialize(obj)?), - Self::Bulletproof(obj) => (Self::HRP_BULLETPROOF, strict_serialize(obj)?), - Self::Curve25519Pk(obj) => (Self::HRP_CURVE25519OPK, strict_serialize(obj)?), - Self::Ed25519Sign(obj) => (Self::HRP_ED25519OSIGN, strict_serialize(obj)?), - Self::BlindedUtxo(obj) => (Self::HRP_OUTPOINT, strict_serialize(obj)?), - Self::SchemaId(obj) => (Self::HRP_SCHEMA_ID, strict_serialize(obj)?), - Self::ContractId(obj) => (Self::HRP_CONTRACT_ID, strict_serialize(obj)?), - Self::Schema(obj) => (Self::HRP_SCHEMA, Bech32::deflate_encode(obj)?), - Self::Genesis(obj) => (Self::HRP_GENESIS, Bech32::deflate_encode(obj)?), - Self::Extension(obj) => (Self::HRP_EXTENSION, Bech32::deflate_encode(obj)?), - Self::Transition(obj) => (Self::HRP_TRANSITION, Bech32::deflate_encode(obj)?), - Self::Disclosure(obj) => (Self::HRP_DISCLOSURE, Bech32::deflate_encode(obj)?), + Self::PedersenCommitment(obj) => { + (Self::HRP_PEDERSEN, strict_serialize(obj)?) + } + Self::Bulletproof(obj) => { + (Self::HRP_BULLETPROOF, strict_serialize(obj)?) + } + Self::BlindedUtxo(obj) => { + (Self::HRP_OUTPOINT, strict_serialize(obj)?) + } + Self::SchemaId(obj) => { + (Self::HRP_SCHEMA_ID, strict_serialize(obj)?) + } + Self::ContractId(obj) => { + (Self::HRP_CONTRACT_ID, strict_serialize(obj)?) + } + Self::Schema(obj) => { + (Self::HRP_SCHEMA, Bech32::deflate_encode(obj)?) + } + Self::Genesis(obj) => { + (Self::HRP_GENESIS, Bech32::deflate_encode(obj)?) + } + Self::Extension(obj) => { + (Self::HRP_EXTENSION, Bech32::deflate_encode(obj)?) + } + Self::Transition(obj) => { + (Self::HRP_TRANSITION, Bech32::deflate_encode(obj)?) + } + Self::Disclosure(obj) => { + (Self::HRP_DISCLOSURE, Bech32::deflate_encode(obj)?) + } Self::Other(hrp, obj) => (hrp.as_ref(), obj.clone()), }; // TODO: Update to Bech32m From ac9ba98e6e744e423e8453b40adc131c2a2a3161 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Thu, 9 Jun 2022 23:31:03 +0200 Subject: [PATCH 07/15] Reformat crate --- src/bech32.rs | 80 +++++++++++--------------------------------- src/contract/data.rs | 18 +++------- src/schema/mod.rs | 4 +-- src/schema/state.rs | 30 +++++------------ src/schema/types.rs | 5 ++- 5 files changed, 38 insertions(+), 99 deletions(-) diff --git a/src/bech32.rs b/src/bech32.rs index 91bcc5fe..46606c6e 100644 --- a/src/bech32.rs +++ b/src/bech32.rs @@ -392,36 +392,16 @@ impl FromStr for Bech32 { // TODO: Update to Bech32m and check variant Ok(match hrp { - x if x == Self::HRP_PEDERSEN => { - Self::PedersenCommitment(strict_deserialize(&data)?) - } - x if x == Self::HRP_BULLETPROOF => { - Self::Bulletproof(strict_deserialize(&data)?) - } - x if x == Self::HRP_OUTPOINT => { - Self::BlindedUtxo(strict_deserialize(&data)?) - } - x if x == Self::HRP_SCHEMA_ID => { - Self::SchemaId(strict_deserialize(&data)?) - } - x if x == Self::HRP_CONTRACT_ID => { - Self::ContractId(strict_deserialize(&data)?) - } - x if x == Self::HRP_SCHEMA => { - Self::Schema(Bech32::raw_decode(&data)?) - } - x if x == Self::HRP_GENESIS => { - Self::Genesis(Bech32::raw_decode(&data)?) - } - x if x == Self::HRP_EXTENSION => { - Self::Extension(Bech32::raw_decode(&data)?) - } - x if x == Self::HRP_TRANSITION => { - Self::Transition(Bech32::raw_decode(&data)?) - } - x if x == Self::HRP_DISCLOSURE => { - Self::Disclosure(Bech32::raw_decode(&data)?) - } + x if x == Self::HRP_PEDERSEN => Self::PedersenCommitment(strict_deserialize(&data)?), + x if x == Self::HRP_BULLETPROOF => Self::Bulletproof(strict_deserialize(&data)?), + x if x == Self::HRP_OUTPOINT => Self::BlindedUtxo(strict_deserialize(&data)?), + x if x == Self::HRP_SCHEMA_ID => Self::SchemaId(strict_deserialize(&data)?), + x if x == Self::HRP_CONTRACT_ID => Self::ContractId(strict_deserialize(&data)?), + x if x == Self::HRP_SCHEMA => Self::Schema(Bech32::raw_decode(&data)?), + x if x == Self::HRP_GENESIS => Self::Genesis(Bech32::raw_decode(&data)?), + x if x == Self::HRP_EXTENSION => Self::Extension(Bech32::raw_decode(&data)?), + x if x == Self::HRP_TRANSITION => Self::Transition(Bech32::raw_decode(&data)?), + x if x == Self::HRP_DISCLOSURE => Self::Disclosure(Bech32::raw_decode(&data)?), other => Self::Other(other, data), }) } @@ -430,36 +410,16 @@ impl FromStr for Bech32 { impl Display for Bech32 { fn fmt(&self, f: &mut Formatter<'_>) -> ::core::fmt::Result { let (hrp, data) = match self { - Self::PedersenCommitment(obj) => { - (Self::HRP_PEDERSEN, strict_serialize(obj)?) - } - Self::Bulletproof(obj) => { - (Self::HRP_BULLETPROOF, strict_serialize(obj)?) - } - Self::BlindedUtxo(obj) => { - (Self::HRP_OUTPOINT, strict_serialize(obj)?) - } - Self::SchemaId(obj) => { - (Self::HRP_SCHEMA_ID, strict_serialize(obj)?) - } - Self::ContractId(obj) => { - (Self::HRP_CONTRACT_ID, strict_serialize(obj)?) - } - Self::Schema(obj) => { - (Self::HRP_SCHEMA, Bech32::deflate_encode(obj)?) - } - Self::Genesis(obj) => { - (Self::HRP_GENESIS, Bech32::deflate_encode(obj)?) - } - Self::Extension(obj) => { - (Self::HRP_EXTENSION, Bech32::deflate_encode(obj)?) - } - Self::Transition(obj) => { - (Self::HRP_TRANSITION, Bech32::deflate_encode(obj)?) - } - Self::Disclosure(obj) => { - (Self::HRP_DISCLOSURE, Bech32::deflate_encode(obj)?) - } + Self::PedersenCommitment(obj) => (Self::HRP_PEDERSEN, strict_serialize(obj)?), + Self::Bulletproof(obj) => (Self::HRP_BULLETPROOF, strict_serialize(obj)?), + Self::BlindedUtxo(obj) => (Self::HRP_OUTPOINT, strict_serialize(obj)?), + Self::SchemaId(obj) => (Self::HRP_SCHEMA_ID, strict_serialize(obj)?), + Self::ContractId(obj) => (Self::HRP_CONTRACT_ID, strict_serialize(obj)?), + Self::Schema(obj) => (Self::HRP_SCHEMA, Bech32::deflate_encode(obj)?), + Self::Genesis(obj) => (Self::HRP_GENESIS, Bech32::deflate_encode(obj)?), + Self::Extension(obj) => (Self::HRP_EXTENSION, Bech32::deflate_encode(obj)?), + Self::Transition(obj) => (Self::HRP_TRANSITION, Bech32::deflate_encode(obj)?), + Self::Disclosure(obj) => (Self::HRP_DISCLOSURE, Bech32::deflate_encode(obj)?), Self::Other(hrp, obj) => (hrp.as_ref(), obj.clone()), }; // TODO: Update to Bech32m diff --git a/src/contract/data.rs b/src/contract/data.rs index 10b6b365..8d225e15 100644 --- a/src/contract/data.rs +++ b/src/contract/data.rs @@ -16,8 +16,8 @@ use core::cmp::Ordering; use core::fmt::Debug; use std::io; +use amplify::AsAny; use bitcoin::hashes::{hash160, Hash}; - use commit_verify::{commit_encode, CommitConceal, CommitEncode}; use strict_encoding::strict_serialize; @@ -317,24 +317,16 @@ pub(super) mod _strict_encoding { EncodingTag::U16 => Revealed::U16(u16::strict_decode(&mut d)?), EncodingTag::U32 => Revealed::U32(u32::strict_decode(&mut d)?), EncodingTag::U64 => Revealed::U64(u64::strict_decode(&mut d)?), - EncodingTag::U128 => { - Revealed::U128(u128::strict_decode(&mut d)?) - } + EncodingTag::U128 => Revealed::U128(u128::strict_decode(&mut d)?), EncodingTag::I8 => Revealed::I8(i8::strict_decode(&mut d)?), EncodingTag::I16 => Revealed::I16(i16::strict_decode(&mut d)?), EncodingTag::I32 => Revealed::I32(i32::strict_decode(&mut d)?), EncodingTag::I64 => Revealed::I64(i64::strict_decode(&mut d)?), - EncodingTag::I128 => { - Revealed::I128(i128::strict_decode(&mut d)?) - } + EncodingTag::I128 => Revealed::I128(i128::strict_decode(&mut d)?), EncodingTag::F32 => Revealed::F32(f32::strict_decode(&mut d)?), EncodingTag::F64 => Revealed::F64(f64::strict_decode(&mut d)?), - EncodingTag::Bytes => { - Revealed::Bytes(Vec::strict_decode(&mut d)?) - } - EncodingTag::String => { - Revealed::String(String::strict_decode(&mut d)?) - } + EncodingTag::Bytes => Revealed::Bytes(Vec::strict_decode(&mut d)?), + EncodingTag::String => Revealed::String(String::strict_decode(&mut d)?), }) } } diff --git a/src/schema/mod.rs b/src/schema/mod.rs index dbdf0def..a2a42875 100644 --- a/src/schema/mod.rs +++ b/src/schema/mod.rs @@ -28,9 +28,7 @@ pub use script::{ Action, AssignmentAbi, AssignmentAction, ExecutableCode, ExtensionAbi, ExtensionAction, GenericAction, GenesisAbi, GenesisAction, NodeAction, TransitionAbi, TransitionAction, VmType, }; -pub use state::{ - DataFormat, DiscreteFiniteFieldFormat, StateFormat, StateSchema, StateType, -}; +pub use state::{DataFormat, DiscreteFiniteFieldFormat, StateFormat, StateSchema, StateType}; pub use types::{Bits, Occurrences, OccurrencesError}; mod verify { diff --git a/src/schema/state.rs b/src/schema/state.rs index a1abf9ab..d4a71aaf 100644 --- a/src/schema/state.rs +++ b/src/schema/state.rs @@ -381,11 +381,8 @@ mod _strict_encoding { .map_err(|_| Error::ValueOutOfRange( "Maximum value for Unsigned data type are outside of bit dimension", (core::u128::MIN as u128)..(core::u128::MAX as u128), *max as u128))?; - let (min, max) = get_bounds( - min..=max, - core::u128::MIN..=core::u128::MAX, - true, - )?; + let (min, max) = + get_bounds(min..=max, core::u128::MIN..=core::u128::MAX, true)?; write_min_max!(min, max, e, len); } } @@ -457,11 +454,8 @@ mod _strict_encoding { .map_err(|_| Error::ValueOutOfRange( "Maximum value for Unsigned data type are outside of bit dimension", (core::i128::MIN as u128)..(core::i128::MAX as u128), *max as u128))?; - let (min, max) = get_bounds( - min..=max, - core::i128::MIN..=core::i128::MAX, - true, - )?; + let (min, max) = + get_bounds(min..=max, core::i128::MIN..=core::i128::MAX, true)?; write_min_max!(min, max, e, len); } } @@ -646,18 +640,10 @@ mod _strict_encoding { }; DataFormat::Float(bits, min, max) } - EncodingTag::Enum => { - DataFormat::Enum(BTreeSet::::strict_decode(&mut d)?) - } - EncodingTag::UniString => { - DataFormat::UniString(u16::strict_decode(&mut d)?) - } - EncodingTag::ByteString => { - DataFormat::ByteString(u16::strict_decode(&mut d)?) - } - EncodingTag::FixedBytes => { - DataFormat::FixedBytes(u16::strict_decode(&mut d)?) - } + EncodingTag::Enum => DataFormat::Enum(BTreeSet::::strict_decode(&mut d)?), + EncodingTag::UniString => DataFormat::UniString(u16::strict_decode(&mut d)?), + EncodingTag::ByteString => DataFormat::ByteString(u16::strict_decode(&mut d)?), + EncodingTag::FixedBytes => DataFormat::FixedBytes(u16::strict_decode(&mut d)?), }) } } diff --git a/src/schema/types.rs b/src/schema/types.rs index 1f071eb6..77224770 100644 --- a/src/schema/types.rs +++ b/src/schema/types.rs @@ -11,7 +11,6 @@ // along with this software. // If not, see . -use std::io; use std::ops::RangeInclusive; use num_traits::ToPrimitive; @@ -189,8 +188,12 @@ pub struct OccurrencesError { } mod _strict_encoding { + use std::io; + use strict_encoding::{Error, StrictDecode, StrictEncode}; + use super::*; + impl_enum_strict_encoding!(Bits); impl StrictEncode for Occurrences { From 39152e1c2da44f4e709bfcf9993333e88944eb08 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Thu, 9 Jun 2022 23:37:14 +0200 Subject: [PATCH 08/15] Upgrade Bits strict encoding --- src/schema/state.rs | 6 +++--- src/schema/types.rs | 20 +++++++------------- 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/src/schema/state.rs b/src/schema/state.rs index d4a71aaf..79892e24 100644 --- a/src/schema/state.rs +++ b/src/schema/state.rs @@ -145,8 +145,8 @@ mod _strict_encoding { use core::fmt::Debug; use core::ops::{Add, Bound, RangeBounds, RangeInclusive, Sub}; - use num_derive::{FromPrimitive, ToPrimitive}; - use num_traits::{Bounded, ToPrimitive}; + use num_derive::FromPrimitive; + use num_traits::Bounded; use strict_encoding::{Error, StrictDecode, StrictEncode}; use super::*; @@ -482,7 +482,7 @@ mod _strict_encoding { "The provided number of bits for the floating number \ is not supported by the platform", 32..64, - unsupported_bits.to_u64().unwrap() as u128, + (*unsupported_bits as u8) as u128, ))?, } len diff --git a/src/schema/types.rs b/src/schema/types.rs index 77224770..d1b8189b 100644 --- a/src/schema/types.rs +++ b/src/schema/types.rs @@ -13,8 +13,6 @@ use std::ops::RangeInclusive; -use num_traits::ToPrimitive; - pub trait UnsignedInteger: Clone + Copy + PartialEq + Eq + PartialOrd + Ord + Into + std::fmt::Debug { @@ -69,13 +67,14 @@ impl Number for f64 {} /// NB: For now, we support only up to 128-bit integers and 64-bit floats; /// nevertheless RGB schema standard allows up to 256-byte numeric types. /// Support for larger types can be added later. -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Display, ToPrimitive, FromPrimitive)] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)] +#[derive(StrictEncode, StrictDecode)] +#[strict_encoding(by_value, repr = u8)] #[cfg_attr( feature = "serde", derive(Serialize, Deserialize), serde(crate = "serde_crate", rename_all = "lowercase") )] -#[display(Debug)] #[repr(u8)] #[non_exhaustive] pub enum Bits { @@ -89,8 +88,8 @@ pub enum Bits { // TODO #46: Add support for 256-bit types impl Bits { - pub fn max_value(&self) -> u128 { - match *self { + pub fn max_value(self) -> u128 { + match self { Bits::Bit8 => core::u8::MAX as u128, Bits::Bit16 => core::u16::MAX as u128, Bits::Bit32 => core::u32::MAX as u128, @@ -99,12 +98,9 @@ impl Bits { } } - pub fn byte_len(&self) -> usize { - self.to_u8() - .expect("Bit type MUST always occupy < 256 bytes") as usize - } + pub fn byte_len(self) -> usize { (self as u8) as usize } - pub fn bit_len(&self) -> usize { self.byte_len() * 8 } + pub fn bit_len(self) -> usize { self.byte_len() * 8 } } #[derive(Clone, PartialEq, Eq, Hash, Debug, Display)] @@ -194,8 +190,6 @@ mod _strict_encoding { use super::*; - impl_enum_strict_encoding!(Bits); - impl StrictEncode for Occurrences { fn strict_encode(&self, mut e: E) -> Result { let (min, max) = match self { From b4e36a878d24babe0b569143f247082e972e0a8c Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Thu, 9 Jun 2022 23:38:32 +0200 Subject: [PATCH 09/15] Upgrade state type strict encoding --- src/schema/state.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/schema/state.rs b/src/schema/state.rs index 79892e24..d95a60ca 100644 --- a/src/schema/state.rs +++ b/src/schema/state.rs @@ -26,7 +26,9 @@ pub struct StateSchema { pub abi: script::AssignmentAbi, } -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Display, ToPrimitive, FromPrimitive)] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)] +#[derive(StrictEncode, StrictDecode)] +#[strict_encoding(by_value, repr = u8)] #[cfg_attr( feature = "serde", derive(Serialize, Deserialize), @@ -34,7 +36,6 @@ pub struct StateSchema { )] #[non_exhaustive] #[repr(u8)] -#[display(Debug)] pub enum StateType { Declarative = 0, DiscreteFiniteField = 1, @@ -151,8 +152,6 @@ mod _strict_encoding { use super::*; - impl_enum_strict_encoding!(StateType); - impl StrictEncode for StateFormat { fn strict_encode(&self, mut e: E) -> Result { Ok(match self { From 10b231503f806c78535b6a16732bf524df652b1f Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Fri, 10 Jun 2022 00:01:33 +0200 Subject: [PATCH 10/15] Update strict encoding in schema::state mod --- src/schema/state.rs | 525 +------------------------------------------- 1 file changed, 9 insertions(+), 516 deletions(-) diff --git a/src/schema/state.rs b/src/schema/state.rs index d95a60ca..30f33a04 100644 --- a/src/schema/state.rs +++ b/src/schema/state.rs @@ -12,9 +12,6 @@ // If not, see . use std::collections::BTreeSet; -use std::io; - -use num_derive::{FromPrimitive, ToPrimitive}; use super::{script, Bits}; @@ -42,27 +39,29 @@ pub enum StateType { CustomData = 2, } -#[derive(Clone, PartialEq, Debug, Display)] +#[derive(Clone, PartialEq, Debug)] +#[derive(StrictEncode, StrictDecode)] +#[strict_encoding(by_order)] #[cfg_attr( feature = "serde", derive(Serialize, Deserialize), serde(crate = "serde_crate", rename_all = "snake_case") )] #[non_exhaustive] -#[display(Debug)] pub enum StateFormat { Declarative, DiscreteFiniteField(DiscreteFiniteFieldFormat), CustomData(DataFormat), } -#[derive(Clone, PartialEq, Debug, Display, ToPrimitive, FromPrimitive)] +#[derive(Clone, PartialEq, Debug)] +#[derive(StrictEncode, StrictDecode)] +#[strict_encoding(by_value, repr = u8)] #[cfg_attr( feature = "serde", derive(Serialize, Deserialize), serde(crate = "serde_crate", rename_all = "lowercase") )] -#[display(Debug)] #[non_exhaustive] #[repr(u8)] /// Today we support only a single format of confidential data, because of the @@ -76,13 +75,14 @@ pub enum DiscreteFiniteFieldFormat { Unsigned64bit, } -#[derive(Clone, PartialEq, Debug, Display)] +#[derive(Clone, PartialEq, Debug)] +#[derive(StrictEncode, StrictDecode)] +#[strict_encoding(by_order)] #[cfg_attr( feature = "serde", derive(Serialize, Deserialize), serde(crate = "serde_crate", rename_all = "lowercase") )] -#[display(Debug)] #[non_exhaustive] pub enum DataFormat { Unsigned(Bits, u128, u128), @@ -141,513 +141,6 @@ impl DataFormat { pub fn f64() -> Self { Self::Float(Bits::Bit64, 0.0, core::f64::MAX) } } -mod _strict_encoding { - use core::convert::TryFrom; - use core::fmt::Debug; - use core::ops::{Add, Bound, RangeBounds, RangeInclusive, Sub}; - - use num_derive::FromPrimitive; - use num_traits::Bounded; - use strict_encoding::{Error, StrictDecode, StrictEncode}; - - use super::*; - - impl StrictEncode for StateFormat { - fn strict_encode(&self, mut e: E) -> Result { - Ok(match self { - StateFormat::Declarative => StateType::Declarative.strict_encode(e)?, - StateFormat::DiscreteFiniteField(data) => { - strict_encode_list!(e; StateType::DiscreteFiniteField, data) - } - StateFormat::CustomData(data) => { - strict_encode_list!(e; StateType::CustomData, data) - } - }) - } - } - - impl StrictDecode for StateFormat { - fn strict_decode(mut d: D) -> Result { - let format = StateType::strict_decode(&mut d)?; - Ok(match format { - StateType::Declarative => StateFormat::Declarative, - StateType::DiscreteFiniteField => { - StateFormat::DiscreteFiniteField(DiscreteFiniteFieldFormat::strict_decode(d)?) - } - StateType::CustomData => StateFormat::CustomData(DataFormat::strict_decode(d)?), - }) - } - } - - #[derive(Debug, Display, FromPrimitive, ToPrimitive)] - #[display(Debug)] - #[repr(u8)] - enum EncodingTag { - // Primitive types - Unsigned = 0, - Integer = 1, - Float = 2, - Enum = 3, - UniString = 4, - ByteString = 5, - FixedBytes = 6, - } - impl_enum_strict_encoding!(EncodingTag); - - impl StrictEncode for DiscreteFiniteFieldFormat { - fn strict_encode(&self, e: E) -> Result { - match self { - // Today we support only a single format of confidential data, - // but tomorrow there might be more - DiscreteFiniteFieldFormat::Unsigned64bit => { - DataFormat::Unsigned(Bits::Bit64, 0, core::u64::MAX as u128).strict_encode(e) - } - } - } - } - - impl StrictDecode for DiscreteFiniteFieldFormat { - fn strict_decode(mut d: D) -> Result { - let format = EncodingTag::strict_decode(&mut d)?; - match format { - EncodingTag::Unsigned => { - let bits = Bits::strict_decode(&mut d)?; - let (min, max) = match bits { - Bits::Bit64 => { - let mut min = [0u8; 8]; - let mut max = [0u8; 8]; - d.read_exact(&mut min)?; - d.read_exact(&mut max)?; - ( - u64::from_le_bytes(min) as u128, - u64::from_le_bytes(max) as u128, - ) - } - _ => Err(Error::UnsupportedDataStructure( - "confidential amounts can be only of u64 type; \ - unsigned integers with different bit coin are not \ - yet supported", - ))?, - }; - if min != 0 || max != core::u64::MAX as u128 { - Err(Error::UnsupportedDataStructure( - "confidential amounts can be only of u64 type; \ - allowed values should cover full u64 value range", - ))? - } - Ok(DiscreteFiniteFieldFormat::Unsigned64bit) - } - _ => Err(Error::UnsupportedDataStructure( - "confidential amounts can be only of u64 type; \ - other types of the data is not yet supported", - )), - } - } - } - - impl StrictEncode for DataFormat { - fn strict_encode(&self, mut e: E) -> Result { - fn get_bounds( - provided: impl RangeBounds, - allowed: RangeInclusive, - exclusive: bool, - ) -> Result<(T, T), Error> - where - T: Copy - + Bounded - + PartialOrd - + Debug - + Add - + Sub - + TryFrom - + Default, - { - let min = match provided.start_bound() { - Bound::Excluded(bound) | Bound::Included(bound) if !allowed.contains(bound) => { - Err(Error::DataIntegrityError(format!( - "Lower bound {:?} of the allowed range for \ - DataFormat is outside of the possible values \ - of used number type", - bound, - )))? - } - Bound::Included(bound) => *bound, - Bound::Excluded(_) if !exclusive => Err(Error::DataIntegrityError( - "Excluded upper bound for the allowed range in \ - DataFormat does not make sense for float type" - .to_string(), - ))?, - Bound::Excluded(bound) => *bound + T::try_from(1).unwrap_or_default(), - Bound::Unbounded => *allowed.start(), - }; - let max = match provided.end_bound() { - Bound::Excluded(bound) | Bound::Included(bound) if !allowed.contains(bound) => { - Err(Error::DataIntegrityError(format!( - "Upper bound {:?} of the allowed range for \ - DataFormat is outside of the possible values \ - of used number type", - bound, - )))? - } - Bound::Included(bound) => *bound, - Bound::Excluded(_) if !exclusive => Err(Error::DataIntegrityError( - "Excluded upper bound for the allowed range in \ - DataFormat does not make sense for float type" - .to_string(), - ))?, - Bound::Excluded(bound) => *bound - T::try_from(1).unwrap_or_default(), - Bound::Unbounded => *allowed.end(), - }; - Ok((min, max)) - } - - macro_rules! write_min_max { - ($min:ident, $max:ident, $e:ident, $len:ident) => { - let (min, max) = ( - $min.to_le_bytes().to_vec(), - $max.to_le_bytes().to_vec(), - ); - $e.write_all(&min)?; - $e.write_all(&max)?; - $len += ::core::mem::size_of_val(&$min) - + ::core::mem::size_of_val(&$max); - }; - } - - Ok(match self { - DataFormat::Unsigned(bits, min, max) => { - let mut len = (EncodingTag::Unsigned).strict_encode(&mut e)?; - len += bits.strict_encode(&mut e)?; - match bits { - Bits::Bit8 => { - let min = u8::try_from(*min) - .map_err(|_| Error::ValueOutOfRange( - "Minimum value for Unsigned data type are outside of bit dimension", - (core::u8::MIN as u128)..(core::u8::MAX as u128), *min as u128))?; - let max = u8::try_from(*max) - .map_err(|_| Error::ValueOutOfRange( - "Maximum value for Unsigned data type are outside of bit dimension", - (core::u8::MIN as u128)..(core::u8::MAX as u128), *max as u128))?; - let (min, max) = - get_bounds(min..=max, core::u8::MIN..=core::u8::MAX, true)?; - write_min_max!(min, max, e, len); - } - Bits::Bit16 => { - let min = u16::try_from(*min) - .map_err(|_| Error::ValueOutOfRange( - "Minimum value for Unsigned data type are outside of bit dimension", - (core::u16::MIN as u128)..(core::u16::MAX as u128), *min as u128))?; - let max = u16::try_from(*max) - .map_err(|_| Error::ValueOutOfRange( - "Maximum value for Unsigned data type are outside of bit dimension", - (core::u16::MIN as u128)..(core::u16::MAX as u128), *max as u128))?; - let (min, max) = - get_bounds(min..=max, core::u16::MIN..=core::u16::MAX, true)?; - write_min_max!(min, max, e, len); - } - Bits::Bit32 => { - let min = u32::try_from(*min) - .map_err(|_| Error::ValueOutOfRange( - "Minimum value for Unsigned data type are outside of bit dimension", - (core::u32::MIN as u128)..(core::u32::MAX as u128), *min as u128))?; - let max = u32::try_from(*max) - .map_err(|_| Error::ValueOutOfRange( - "Maximum value for Unsigned data type are outside of bit dimension", - (core::u32::MIN as u128)..(core::u32::MAX as u128), *max as u128))?; - let (min, max) = - get_bounds(min..=max, core::u32::MIN..=core::u32::MAX, true)?; - write_min_max!(min, max, e, len); - } - Bits::Bit64 => { - let min = u64::try_from(*min) - .map_err(|_| Error::ValueOutOfRange( - "Minimum value for Unsigned data type are outside of bit dimension", - (core::u64::MIN as u128)..(core::u64::MAX as u128), *min as u128))?; - let max = u64::try_from(*max) - .map_err(|_| Error::ValueOutOfRange( - "Maximum value for Unsigned data type are outside of bit dimension", - (core::u64::MIN as u128)..(core::u64::MAX as u128), *max as u128))?; - let (min, max) = - get_bounds(min..=max, core::u64::MIN..=core::u64::MAX, true)?; - write_min_max!(min, max, e, len); - } - Bits::Bit128 => { - let min = u128::try_from(*min) - .map_err(|_| Error::ValueOutOfRange( - "Minimum value for Unsigned data type are outside of bit dimension", - (core::u128::MIN as u128)..(core::u128::MAX as u128), *min as u128))?; - let max = u128::try_from(*max) - .map_err(|_| Error::ValueOutOfRange( - "Maximum value for Unsigned data type are outside of bit dimension", - (core::u128::MIN as u128)..(core::u128::MAX as u128), *max as u128))?; - let (min, max) = - get_bounds(min..=max, core::u128::MIN..=core::u128::MAX, true)?; - write_min_max!(min, max, e, len); - } - } - len - } - - DataFormat::Integer(bits, min, max) => { - let mut len = (EncodingTag::Integer).strict_encode(&mut e)?; - len += bits.strict_encode(&mut e)?; - match bits { - Bits::Bit8 => { - let min = i8::try_from(*min) - .map_err(|_| Error::ValueOutOfRange( - "Minimum value for Integer data type are outside of bit dimension", - (core::i8::MIN as u128)..(core::i8::MAX as u128), *min as u128))?; - let max = i8::try_from(*max) - .map_err(|_| Error::ValueOutOfRange( - "Maximum value for Integer data type are outside of bit dimension", - (core::i8::MIN as u128)..(core::i8::MAX as u128), *max as u128))?; - let (min, max) = - get_bounds(min..=max, core::i8::MIN..=core::i8::MAX, true)?; - write_min_max!(min, max, e, len); - } - Bits::Bit16 => { - let min = i16::try_from(*min) - .map_err(|_| Error::ValueOutOfRange( - "Minimum value for Integer data type are outside of bit dimension", - (core::i16::MIN as u128)..(core::i16::MAX as u128), *min as u128))?; - let max = i16::try_from(*max) - .map_err(|_| Error::ValueOutOfRange( - "Maximum value for Integer data type are outside of bit dimension", - (core::i16::MIN as u128)..(core::i16::MAX as u128), *max as u128))?; - let (min, max) = - get_bounds(min..=max, core::i16::MIN..=core::i16::MAX, true)?; - write_min_max!(min, max, e, len); - } - Bits::Bit32 => { - let min = i32::try_from(*min) - .map_err(|_| Error::ValueOutOfRange( - "Minimum value for Integer data type are outside of bit dimension", - (core::i32::MIN as u128)..(core::i32::MAX as u128), *min as u128))?; - let max = i32::try_from(*max) - .map_err(|_| Error::ValueOutOfRange( - "Maximum value for Integer data type are outside of bit dimension", - (core::i32::MIN as u128)..(core::i32::MAX as u128), *max as u128))?; - let (min, max) = - get_bounds(min..=max, core::i32::MIN..=core::i32::MAX, true)?; - write_min_max!(min, max, e, len); - } - Bits::Bit64 => { - let min = i64::try_from(*min) - .map_err(|_| Error::ValueOutOfRange( - "Minimum value for Integer data type are outside of bit dimension", - (core::i64::MIN as u128)..(core::i64::MAX as u128), *min as u128))?; - let max = i64::try_from(*max) - .map_err(|_| Error::ValueOutOfRange( - "Maximum value for Integer data type are outside of bit dimension", - (core::i64::MIN as u128)..(core::i64::MAX as u128), *max as u128))?; - let (min, max) = - get_bounds(min..=max, core::i64::MIN..=core::i64::MAX, true)?; - write_min_max!(min, max, e, len); - } - Bits::Bit128 => { - let min = i128::try_from(*min) - .map_err(|_| Error::ValueOutOfRange( - "Minimum value for Unsigned data type are outside of bit dimension", - (core::i128::MIN as u128)..(core::i128::MAX as u128), *min as u128))?; - let max = i128::try_from(*max) - .map_err(|_| Error::ValueOutOfRange( - "Maximum value for Unsigned data type are outside of bit dimension", - (core::i128::MIN as u128)..(core::i128::MAX as u128), *max as u128))?; - let (min, max) = - get_bounds(min..=max, core::i128::MIN..=core::i128::MAX, true)?; - write_min_max!(min, max, e, len); - } - } - len - } - - DataFormat::Float(bits, min, max) => { - let mut len = (EncodingTag::Float).strict_encode(&mut e)?; - len += bits.strict_encode(&mut e)?; - match bits { - Bits::Bit32 => { - let min = *min as f32; - let max = *max as f32; - let (min, max) = - get_bounds(min..=max, core::f32::MIN..=core::f32::MAX, true)?; - write_min_max!(min, max, e, len); - } - Bits::Bit64 => { - let (min, max) = - get_bounds(min..=max, core::f64::MIN..=core::f64::MAX, true)?; - write_min_max!(min, max, e, len); - } - unsupported_bits => Err(Error::ValueOutOfRange( - "The provided number of bits for the floating number \ - is not supported by the platform", - 32..64, - (*unsupported_bits as u8) as u128, - ))?, - } - len - } - - DataFormat::Enum(values) => { - strict_encode_list!(e; EncodingTag::Enum, values) - } - DataFormat::UniString(size) => { - strict_encode_list!(e; EncodingTag::UniString, size) - } - DataFormat::ByteString(size) => { - strict_encode_list!(e; EncodingTag::ByteString, size) - } - DataFormat::FixedBytes(size) => { - strict_encode_list!(e; EncodingTag::FixedBytes, size) - } - }) - } - } - - impl StrictDecode for DataFormat { - fn strict_decode(mut d: D) -> Result { - let format = EncodingTag::strict_decode(&mut d)?; - Ok(match format { - EncodingTag::Unsigned => { - let bits = Bits::strict_decode(&mut d)?; - let (min, max) = match bits { - Bits::Bit8 => { - let mut min = [0u8; 1]; - let mut max = [0u8; 1]; - d.read_exact(&mut min)?; - d.read_exact(&mut max)?; - ( - u8::from_le_bytes(min) as u128, - u8::from_le_bytes(max) as u128, - ) - } - Bits::Bit16 => { - let mut min = [0u8; 2]; - let mut max = [0u8; 2]; - d.read_exact(&mut min)?; - d.read_exact(&mut max)?; - ( - u16::from_le_bytes(min) as u128, - u16::from_le_bytes(max) as u128, - ) - } - Bits::Bit32 => { - let mut min = [0u8; 4]; - let mut max = [0u8; 4]; - d.read_exact(&mut min)?; - d.read_exact(&mut max)?; - ( - u32::from_le_bytes(min) as u128, - u32::from_le_bytes(max) as u128, - ) - } - Bits::Bit64 => { - let mut min = [0u8; 8]; - let mut max = [0u8; 8]; - d.read_exact(&mut min)?; - d.read_exact(&mut max)?; - ( - u64::from_le_bytes(min) as u128, - u64::from_le_bytes(max) as u128, - ) - } - Bits::Bit128 => { - let mut min = [0u8; 16]; - let mut max = [0u8; 16]; - d.read_exact(&mut min)?; - d.read_exact(&mut max)?; - (u128::from_le_bytes(min), u128::from_le_bytes(max)) - } - }; - DataFormat::Unsigned(bits, min, max) - } - EncodingTag::Integer => { - let bits = Bits::strict_decode(&mut d)?; - let (min, max) = match bits { - Bits::Bit8 => { - let mut min = [0u8; 1]; - let mut max = [0u8; 1]; - d.read_exact(&mut min)?; - d.read_exact(&mut max)?; - ( - i8::from_le_bytes(min) as i128, - i8::from_le_bytes(max) as i128, - ) - } - Bits::Bit16 => { - let mut min = [0u8; 2]; - let mut max = [0u8; 2]; - d.read_exact(&mut min)?; - d.read_exact(&mut max)?; - ( - i16::from_le_bytes(min) as i128, - i16::from_le_bytes(max) as i128, - ) - } - Bits::Bit32 => { - let mut min = [0u8; 4]; - let mut max = [0u8; 4]; - d.read_exact(&mut min)?; - d.read_exact(&mut max)?; - ( - i32::from_le_bytes(min) as i128, - i32::from_le_bytes(max) as i128, - ) - } - Bits::Bit64 => { - let mut min = [0u8; 8]; - let mut max = [0u8; 8]; - d.read_exact(&mut min)?; - d.read_exact(&mut max)?; - ( - i64::from_le_bytes(min) as i128, - i64::from_le_bytes(max) as i128, - ) - } - Bits::Bit128 => { - let mut min = [0u8; 16]; - let mut max = [0u8; 16]; - d.read_exact(&mut min)?; - d.read_exact(&mut max)?; - (i128::from_le_bytes(min), i128::from_le_bytes(max)) - } - }; - DataFormat::Integer(bits, min, max) - } - EncodingTag::Float => { - let bits = Bits::strict_decode(&mut d)?; - let (min, max) = match bits { - Bits::Bit32 => { - let mut min = [0u8; 4]; - let mut max = [0u8; 4]; - d.read_exact(&mut min)?; - d.read_exact(&mut max)?; - ( - f32::from_le_bytes(min) as f64, - f32::from_le_bytes(max) as f64, - ) - } - Bits::Bit64 => { - let mut min = [0u8; 8]; - let mut max = [0u8; 8]; - d.read_exact(&mut min)?; - d.read_exact(&mut max)?; - (f64::from_le_bytes(min), f64::from_le_bytes(max)) - } - _ => Err(Error::DataIntegrityError( - "Unsupported float field bit size".to_string(), - ))?, - }; - DataFormat::Float(bits, min, max) - } - EncodingTag::Enum => DataFormat::Enum(BTreeSet::::strict_decode(&mut d)?), - EncodingTag::UniString => DataFormat::UniString(u16::strict_decode(&mut d)?), - EncodingTag::ByteString => DataFormat::ByteString(u16::strict_decode(&mut d)?), - EncodingTag::FixedBytes => DataFormat::FixedBytes(u16::strict_decode(&mut d)?), - }) - } - } -} - mod _validation { use core::any::Any; From bf7cc0f3045b1453d867bd640bf079b0f9512a55 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Fri, 10 Jun 2022 00:04:19 +0200 Subject: [PATCH 11/15] Fix test compilation --- src/contract/assignments.rs | 6 +++--- src/contract/data.rs | 8 ++++---- src/schema/schema.rs | 3 +-- src/schema/state.rs | 35 ++++------------------------------- 4 files changed, 12 insertions(+), 40 deletions(-) diff --git a/src/contract/assignments.rs b/src/contract/assignments.rs index 61f80767..d22b7a35 100644 --- a/src/contract/assignments.rs +++ b/src/contract/assignments.rs @@ -1713,8 +1713,8 @@ mod test { let data_set = hash_type.filter_revealed_state_data(); // Create state data from precomputed values - let data_1 = data::Revealed::Sha256(sha256::Hash::from_hex(STATE_DATA[2]).unwrap()); - let data_2 = data::Revealed::Sha256(sha256::Hash::from_hex(STATE_DATA[0]).unwrap()); + let data_1 = data::Revealed::Bytes(sha256::Hash::from_hex(STATE_DATA[2]).unwrap().to_vec()); + let data_2 = data::Revealed::Bytes(sha256::Hash::from_hex(STATE_DATA[0]).unwrap().to_vec()); // Check extracted data matches with precomputed values assert_eq!(data_set[0].to_owned(), data_1); @@ -2130,7 +2130,7 @@ mod test { let state_data_vec: Vec = STATE_DATA .iter() - .map(|data| data::Revealed::Sha256(sha256::Hash::from_hex(data).unwrap())) + .map(|data| data::Revealed::Bytes(sha256::Hash::from_hex(data).unwrap().to_vec())) .collect(); let assignment_1 = Assignment::::Revealed { diff --git a/src/contract/data.rs b/src/contract/data.rs index 8d225e15..df28f2c7 100644 --- a/src/contract/data.rs +++ b/src/contract/data.rs @@ -352,7 +352,7 @@ pub(super) mod _strict_encoding { EncodingTag::F64 => 0b_0001_0011_u8, EncodingTag::Bytes => 0b_0010_0000_u8, - EncodingTag::String => 0b_0010_0001_u8, + EncodingTag::String => 0b_0010_0001_u8 ) .unwrap(); } @@ -451,7 +451,7 @@ mod test { (F_32, Revealed), (F_64, Revealed), (BYTES, Revealed), - (STRING, Revealed), + (STRING, Revealed) ); } @@ -471,7 +471,7 @@ mod test { (F_32, Revealed, err), (F_64, Revealed, err), (BYTES, Revealed, err), - (STRING, Revealed, err), + (STRING, Revealed, err) ); } @@ -500,7 +500,7 @@ mod test { (F_64, F64_CONCEALED, Revealed), (F_64, F64_CONCEALED, Revealed), (BYTES, BYTES_CONCEALED, Revealed), - (STRING, STRING_CONCEALED, Revealed), + (STRING, STRING_CONCEALED, Revealed) ); } } diff --git a/src/schema/schema.rs b/src/schema/schema.rs index 48cb5237..cd1712d1 100644 --- a/src/schema/schema.rs +++ b/src/schema/schema.rs @@ -829,8 +829,7 @@ pub(crate) mod test { FIELD_ISSUED_SUPPLY => DataFormat::Unsigned(Bits::Bit64, 0, core::u64::MAX as u128), FIELD_DUST_LIMIT => DataFormat::Unsigned(Bits::Bit64, 0, core::u64::MAX as u128), FIELD_PRUNE_PROOF => DataFormat::ByteString(core::u16::MAX), - FIELD_TIMESTAMP => DataFormat::Unsigned(Bits::Bit64, 0, core::u64::MAX as u128), - FIELD_PROOF_OF_BURN => DataFormat::TxOutPoint + FIELD_TIMESTAMP => DataFormat::Unsigned(Bits::Bit64, 0, core::u64::MAX as u128) }, owned_right_types: bmap! { ASSIGNMENT_ISSUE => StateSchema { diff --git a/src/schema/state.rs b/src/schema/state.rs index 30f33a04..19ce0d3b 100644 --- a/src/schema/state.rs +++ b/src/schema/state.rs @@ -480,8 +480,8 @@ mod test { // Create a Map of Format type and encoded data let mut map: BTreeMap<&str, Vec> = BTreeMap::new(); - // Declarative and Pedersan formats - map.insert("Declerative", vec![0]); + // Declarative and Pedersen formats + map.insert("Declarative", vec![0]); map.insert("DiscreteFinite format", vec![ 1, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, ]); @@ -512,33 +512,6 @@ mod test { // Bytes map.insert("Bytes(27)", vec![2, 5, 27, 0]); - // Digest Algo - map.insert("Digest(Sha256)", vec![2, 16, 17]); - map.insert("Digest(Sha512)", vec![2, 16, 18]); - map.insert("Digest(Bitcoin160)", vec![2, 16, 72]); - map.insert("Digest(Bitcoin256)", vec![2, 16, 81]); - - // Txoutpoint - map.insert("TxOutPoint", vec![2, 32]); - - // Public Keys - map.insert("PublickKey(Secp, Compressed)", vec![2, 17, 0, 1]); - map.insert("PublickKey(Secp, Unompressed)", vec![2, 17, 0, 0]); - map.insert("PublickKey(Secp, SchnorrBip)", vec![2, 17, 0, 2]); - map.insert("PublickKey(Curve25519, Compressed)", vec![2, 17, 16, 1]); - map.insert("PublickKey(Curve25519, Unompressed)", vec![2, 17, 16, 0]); - map.insert("PublickKey(Curve25519, SchnorrBip)", vec![2, 17, 16, 2]); - - // Signatures - map.insert("Signature(Ecdsa)", vec![2, 18, 0]); - map.insert("Signature(Schnorr)", vec![2, 18, 1]); - map.insert("Signature(Ed25519)", vec![2, 18, 2]); - - // TX TxOutpoint and Psbt - map.insert("TxOutpoint", vec![2, 32]); - map.insert("Tx", vec![2, 33]); - map.insert("Psbt", vec![2, 34]); - // Test for correct encoding of each cases let _test: Vec<()> = map .iter() @@ -820,7 +793,7 @@ mod test { // Create CustomData Assignmnets let state_data_vec: Vec = TXID_VEC .iter() - .map(|data| data::Revealed::Sha256(sha256::Hash::from_hex(data).unwrap())) + .map(|data| data::Revealed::Bytes(sha256::Hash::from_hex(data).unwrap().to_vec())) .collect(); let assignment_hash_rev = Assignment::::Revealed { @@ -840,7 +813,7 @@ mod test { .unwrap(); let dec_format = StateFormat::Declarative; let ped_format = StateFormat::DiscreteFiniteField(DiscreteFiniteFieldFormat::Unsigned64bit); - let hash_format = StateFormat::CustomData(DataFormat::Digest(DigestAlgorithm::Sha256)); + let hash_format = StateFormat::CustomData(DataFormat::ByteString(32)); // Assert different failure combinations assert_eq!( From dcbb09e8d6b2b29a3105b6eeede9b253f812f69d Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Fri, 10 Jun 2022 00:12:24 +0200 Subject: [PATCH 12/15] Remove num_derive dependencies --- Cargo.lock | 13 ---- Cargo.toml | 5 -- src/contract/assignments.rs | 130 +++---------------------------- src/contract/data.rs | 151 +++--------------------------------- src/contract/value.rs | 31 +------- src/lib.rs | 39 ---------- src/schema/state.rs | 4 +- 7 files changed, 21 insertions(+), 352 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 35753eeb..703cce46 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -805,17 +805,6 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" -[[package]] -name = "num-derive" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "num-integer" version = "0.1.45" @@ -1151,8 +1140,6 @@ dependencies = [ "lazy_static", "lnpbp", "miniscript", - "num-derive", - "num-traits", "serde", "serde_json", "serde_with", diff --git a/Cargo.toml b/Cargo.toml index bae3a23b..794d4ef8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -78,11 +78,6 @@ chrono = "~0.4.19" # updates w/o checking them manually. Should Elements Project secpk256k-zkp # accept bulletproofs code, we will switch to it grin_secp256k1zkp = { version = "=0.7.11" } -# 2. We use these to simplify enum strict encoding, but once the required -# functionality will become part of either amplify_derive or lnpbp_derive -# crates they should be removed -num-traits = "~0.2.11" -num-derive = "~0.3.0" # Optional features used only by a binary clap = { version = "3.1", optional = true, features = ["derive"] } serde_yaml = { version = "0.8", optional = true } diff --git a/src/contract/assignments.rs b/src/contract/assignments.rs index d22b7a35..cf6cc200 100644 --- a/src/contract/assignments.rs +++ b/src/contract/assignments.rs @@ -25,7 +25,7 @@ use super::{ data, seal, value, ConcealSeals, ConcealState, EndpointValueMap, NoDataError, SealEndpoint, SealValueMap, SECP256K1_ZKP, }; -use crate::{schema, ConfidentialDataError, StateRetrievalError}; +use crate::{ConfidentialDataError, StateRetrievalError}; lazy_static! { pub(super) static ref EMPTY_ASSIGNMENT_VEC: AssignmentVec = AssignmentVec::default(); @@ -46,6 +46,7 @@ pub enum StateType { } #[derive(Clone, PartialEq, Eq, Debug, Display)] +#[derive(StrictEncode, StrictDecode)] #[display(Debug)] #[cfg_attr( feature = "serde", @@ -636,8 +637,8 @@ impl State for HashStrategy { /// State data are assigned to a seal definition, which means that they are /// owned by a person controlling spending of the seal UTXO, unless the seal /// is closed, indicating that a transfer of ownership had taken place -#[derive(Clone, Debug, Display)] -#[display(Debug)] +#[derive(Clone, Debug)] +#[derive(StrictEncode, StrictDecode)] #[cfg_attr( feature = "serde", derive(Serialize, Deserialize), @@ -976,120 +977,6 @@ where type Commitment = MerkleNode; } -mod _strict_encoding { - use std::io; - - use data::_strict_encoding::EncodingTag; - use strict_encoding::Error; - - use super::*; - - impl StrictEncode for AssignmentVec { - fn strict_encode(&self, mut e: E) -> Result { - Ok(match self { - AssignmentVec::Declarative(tree) => { - strict_encode_list!(e; schema::StateType::Declarative, tree) - } - AssignmentVec::DiscreteFiniteField(tree) => { - strict_encode_list!(e; schema::StateType::DiscreteFiniteField, EncodingTag::U64, tree) - } - AssignmentVec::CustomData(tree) => { - strict_encode_list!(e; schema::StateType::CustomData, tree) - } - }) - } - } - - impl StrictDecode for AssignmentVec { - fn strict_decode(mut d: D) -> Result { - let format = schema::StateType::strict_decode(&mut d)?; - Ok(match format { - schema::StateType::Declarative => { - AssignmentVec::Declarative(StrictDecode::strict_decode(d)?) - } - schema::StateType::DiscreteFiniteField => match EncodingTag::strict_decode(&mut d)? - { - EncodingTag::U64 => { - AssignmentVec::DiscreteFiniteField(StrictDecode::strict_decode(&mut d)?) - } - _ => Err(Error::UnsupportedDataStructure( - "We support only homomorphic commitments to U64 data", - ))?, - }, - schema::StateType::CustomData => { - AssignmentVec::CustomData(StrictDecode::strict_decode(d)?) - } - }) - } - } - - impl StrictEncode for Assignment - where - StateType: State, - StateType::Confidential: PartialEq + Eq, - StateType::Confidential: From<::ConcealedCommitment>, - { - fn strict_encode(&self, mut e: E) -> Result { - Ok(match self { - Assignment::Confidential { - seal_definition, - assigned_state, - } => { - strict_encode_list!(e; 0u8, seal_definition, assigned_state) - } - Assignment::Revealed { - seal_definition, - assigned_state, - } => { - strict_encode_list!(e; 1u8, seal_definition, assigned_state) - } - Assignment::ConfidentialSeal { - seal_definition, - assigned_state, - } => { - strict_encode_list!(e; 2u8, seal_definition, assigned_state) - } - Assignment::ConfidentialAmount { - seal_definition, - assigned_state, - } => { - strict_encode_list!(e; 3u8, seal_definition, assigned_state) - } - }) - } - } - - impl StrictDecode for Assignment - where - StateType: State, - StateType::Confidential: PartialEq + Eq, - StateType::Confidential: From<::ConcealedCommitment>, - { - fn strict_decode(mut d: D) -> Result { - let format = u8::strict_decode(&mut d)?; - Ok(match format { - 0u8 => Assignment::Confidential { - seal_definition: seal::Confidential::strict_decode(&mut d)?, - assigned_state: StateType::Confidential::strict_decode(&mut d)?, - }, - 1u8 => Assignment::Revealed { - seal_definition: seal::Revealed::strict_decode(&mut d)?, - assigned_state: StateType::Revealed::strict_decode(&mut d)?, - }, - 2u8 => Assignment::ConfidentialSeal { - seal_definition: seal::Confidential::strict_decode(&mut d)?, - assigned_state: StateType::Revealed::strict_decode(&mut d)?, - }, - 3u8 => Assignment::ConfidentialAmount { - seal_definition: seal::Revealed::strict_decode(&mut d)?, - assigned_state: StateType::Confidential::strict_decode(&mut d)?, - }, - invalid => Err(Error::EnumValueNotKnown("Assignment", invalid as usize))?, - }) - } - } -} - #[cfg(test)] mod test { use std::collections::BTreeMap; @@ -1107,6 +994,7 @@ mod test { use super::super::{NodeId, OwnedRights, ParentOwnedRights}; use super::*; use crate::contract::seal::Revealed; + use crate::schema; // Hard coded test vectors of Assignment Variants // Each Variant contains 4 types of Assignments @@ -2059,22 +1947,22 @@ mod test { let assignment_1 = Assignment::::Revealed { seal_definition: Revealed::from(OutPoint::new(txid_vec[0], 1)), - assigned_state: data::Void, + assigned_state: data::Void(), }; let assignment_2 = Assignment::::ConfidentialAmount { seal_definition: Revealed::from(OutPoint::new(txid_vec[1], 2)), - assigned_state: data::Void, + assigned_state: data::Void(), }; let assignment_3 = Assignment::::ConfidentialSeal { seal_definition: Revealed::from(OutPoint::new(txid_vec[2], 3)).commit_conceal(), - assigned_state: data::Void, + assigned_state: data::Void(), }; let assignment_4 = Assignment::::Confidential { seal_definition: Revealed::from(OutPoint::new(txid_vec[3], 4)).commit_conceal(), - assigned_state: data::Void, + assigned_state: data::Void(), }; let mut set = Vec::new(); diff --git a/src/contract/data.rs b/src/contract/data.rs index df28f2c7..43fea6c2 100644 --- a/src/contract/data.rs +++ b/src/contract/data.rs @@ -25,8 +25,9 @@ use super::{ConfidentialState, RevealedState}; /// Struct using for storing Void (i.e. absent) state #[derive(Clone, Debug, PartialOrd, Ord, PartialEq, Eq, AsAny)] +#[derive(StrictEncode, StrictDecode)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(crate = "serde_crate"))] -pub struct Void; +pub struct Void(); impl ConfidentialState for Void {} @@ -41,13 +42,14 @@ impl CommitEncode for Void { fn commit_encode(&self, _e: E) -> usize { 0 } } -#[derive(Clone, Debug, Display, AsAny)] +#[derive(Clone, Debug, AsAny)] +#[derive(StrictEncode, StrictDecode)] +#[strict_encoding(by_order)] #[cfg_attr( feature = "serde", derive(Serialize, Deserialize), serde(crate = "serde_crate", rename_all = "lowercase") )] -#[display(Debug)] #[non_exhaustive] pub enum Revealed { U8(u8), @@ -135,6 +137,10 @@ hash_newtype!( doc = "Confidential representation of data" ); +impl strict_encoding::Strategy for Confidential { + type Strategy = strict_encoding::strategies::HashFixedBytes; +} + impl ConfidentialState for Confidential {} impl AsAny for Confidential { @@ -220,145 +226,6 @@ impl Revealed { } } -pub(super) mod _strict_encoding { - use std::io; - - use strict_encoding::{strategies, Error, Strategy, StrictDecode, StrictEncode}; - - use super::*; - - impl Strategy for Confidential { - type Strategy = strategies::HashFixedBytes; - } - - #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, FromPrimitive, ToPrimitive, Debug)] - #[repr(u8)] - pub enum EncodingTag { - U8 = 0b_0000_0000_u8, - U16 = 0b_0000_0001_u8, - U32 = 0b_0000_0010_u8, - U64 = 0b_0000_0011_u8, - U128 = 0b_0000_0100_u8, - I8 = 0b_0000_1000_u8, - I16 = 0b_0000_1001_u8, - I32 = 0b_0000_1010_u8, - I64 = 0b_0000_1011_u8, - I128 = 0b_0000_1100_u8, - F32 = 0b_0001_0010_u8, - F64 = 0b_0001_0011_u8, - - Bytes = 0b_0010_0000_u8, - String = 0b_0010_0001_u8, - } - impl_enum_strict_encoding!(EncodingTag); - - impl StrictEncode for Void { - fn strict_encode(&self, _: E) -> Result { Ok(0) } - } - - impl StrictDecode for Void { - fn strict_decode(_: D) -> Result { Ok(Void) } - } - - impl StrictEncode for Revealed { - fn strict_encode(&self, mut e: E) -> Result { - Ok(match self { - Revealed::U8(val) => { - strict_encode_list!(e; EncodingTag::U8, val) - } - Revealed::U16(val) => { - strict_encode_list!(e; EncodingTag::U16, val) - } - Revealed::U32(val) => { - strict_encode_list!(e; EncodingTag::U32, val) - } - Revealed::U64(val) => { - strict_encode_list!(e; EncodingTag::U64, val) - } - Revealed::U128(val) => { - strict_encode_list!(e; EncodingTag::U128, val) - } - Revealed::I8(val) => { - strict_encode_list!(e; EncodingTag::I8, val) - } - Revealed::I16(val) => { - strict_encode_list!(e; EncodingTag::I16, val) - } - Revealed::I32(val) => { - strict_encode_list!(e; EncodingTag::I32, val) - } - Revealed::I64(val) => { - strict_encode_list!(e; EncodingTag::I64, val) - } - Revealed::I128(val) => { - strict_encode_list!(e; EncodingTag::I128, val) - } - Revealed::F32(val) => { - strict_encode_list!(e; EncodingTag::F32, val) - } - Revealed::F64(val) => { - strict_encode_list!(e; EncodingTag::F64, val) - } - Revealed::Bytes(val) => { - strict_encode_list!(e; EncodingTag::Bytes, val) - } - Revealed::String(val) => { - strict_encode_list!(e; EncodingTag::String, val) - } - }) - } - } - - impl StrictDecode for Revealed { - fn strict_decode(mut d: D) -> Result { - let format = EncodingTag::strict_decode(&mut d)?; - Ok(match format { - EncodingTag::U8 => Revealed::U8(u8::strict_decode(&mut d)?), - EncodingTag::U16 => Revealed::U16(u16::strict_decode(&mut d)?), - EncodingTag::U32 => Revealed::U32(u32::strict_decode(&mut d)?), - EncodingTag::U64 => Revealed::U64(u64::strict_decode(&mut d)?), - EncodingTag::U128 => Revealed::U128(u128::strict_decode(&mut d)?), - EncodingTag::I8 => Revealed::I8(i8::strict_decode(&mut d)?), - EncodingTag::I16 => Revealed::I16(i16::strict_decode(&mut d)?), - EncodingTag::I32 => Revealed::I32(i32::strict_decode(&mut d)?), - EncodingTag::I64 => Revealed::I64(i64::strict_decode(&mut d)?), - EncodingTag::I128 => Revealed::I128(i128::strict_decode(&mut d)?), - EncodingTag::F32 => Revealed::F32(f32::strict_decode(&mut d)?), - EncodingTag::F64 => Revealed::F64(f64::strict_decode(&mut d)?), - EncodingTag::Bytes => Revealed::Bytes(Vec::strict_decode(&mut d)?), - EncodingTag::String => Revealed::String(String::strict_decode(&mut d)?), - }) - } - } - - #[cfg(test)] - mod test { - use super::EncodingTag; - - #[test] - fn test_enum_encodingtag_exhaustive() { - test_encoding_enum_u8_exhaustive!(EncodingTag; - EncodingTag::U8 => 0b_0000_0000_u8, - EncodingTag::U16 => 0b_0000_0001_u8, - EncodingTag::U32 => 0b_0000_0010_u8, - EncodingTag::U64 => 0b_0000_0011_u8, - EncodingTag::U128 => 0b_0000_0100_u8, - EncodingTag::I8 => 0b_0000_1000_u8, - EncodingTag::I16 => 0b_0000_1001_u8, - EncodingTag::I32 => 0b_0000_1010_u8, - EncodingTag::I64 => 0b_0000_1011_u8, - EncodingTag::I128 => 0b_0000_1100_u8, - EncodingTag::F32 => 0b_0001_0010_u8, - EncodingTag::F64 => 0b_0001_0011_u8, - - EncodingTag::Bytes => 0b_0010_0000_u8, - EncodingTag::String => 0b_0010_0001_u8 - ) - .unwrap(); - } - } -} - #[cfg(test)] mod test { use strict_encoding::StrictDecode; diff --git a/src/contract/value.rs b/src/contract/value.rs index f6e6b245..91dcac8b 100644 --- a/src/contract/value.rs +++ b/src/contract/value.rs @@ -87,6 +87,7 @@ impl FromHex for BlindingFactor { } #[derive(Clone, Copy, PartialEq, Eq, Debug, Display, AsAny)] +#[derive(StrictEncode, StrictDecode)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(crate = "serde_crate"))] #[display("{value}#{blinding}")] pub struct Revealed { @@ -307,36 +308,6 @@ impl Confidential { } } -mod _strict_encoding { - use std::io; - - use strict_encoding::{Error, StrictDecode, StrictEncode}; - - use super::*; - use crate::data::_strict_encoding::EncodingTag; - - impl StrictEncode for Revealed { - fn strict_encode(&self, mut e: E) -> Result { - Ok(strict_encode_list!(e; EncodingTag::U64, self.value, self.blinding)) - } - } - - impl StrictDecode for Revealed { - fn strict_decode(mut d: D) -> Result { - let format = EncodingTag::strict_decode(&mut d)?; - Ok(match format { - EncodingTag::U64 => Self { - value: AtomicValue::strict_decode(&mut d)?, - blinding: BlindingFactor::strict_decode(&mut d)?, - }, - _ => Err(Error::UnsupportedDataStructure( - "We support only homomorphic commitments to U64 data", - ))?, - }) - } - } -} - #[cfg(test)] mod test { use strict_encoding::{strict_deserialize, StrictDecode, StrictEncode}; diff --git a/src/lib.rs b/src/lib.rs index cc572a31..0f42291c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -32,8 +32,6 @@ extern crate strict_encoding; #[macro_use] extern crate lazy_static; #[macro_use] -extern crate num_derive; -#[macro_use] extern crate bitcoin_hashes; #[cfg(feature = "serde")] @@ -44,43 +42,6 @@ extern crate serde_crate as serde; pub use secp256k1zkp; -macro_rules! impl_enum_strict_encoding { - ($type:ty) => { - impl ::strict_encoding::StrictEncode for $type { - #[inline] - fn strict_encode( - &self, - e: E, - ) -> Result { - use ::num_traits::ToPrimitive; - - match self.to_u8() { - Some(result) => result.strict_encode(e), - None => Err(::strict_encoding::Error::EnumValueOverflow(stringify!( - $type - ))), - } - } - } - - impl ::strict_encoding::StrictDecode for $type { - #[inline] - fn strict_decode(d: D) -> Result { - use ::num_traits::FromPrimitive; - - let value = u8::strict_decode(d)?; - match Self::from_u8(value) { - Some(result) => Ok(result), - None => Err(::strict_encoding::Error::EnumValueNotKnown( - stringify!($type), - value.into(), - )), - } - } - } - }; -} - // TODO: Move to strict_encoding_test #[cfg(test)] #[macro_export] diff --git a/src/schema/state.rs b/src/schema/state.rs index 19ce0d3b..73247794 100644 --- a/src/schema/state.rs +++ b/src/schema/state.rs @@ -769,13 +769,13 @@ mod test { // Create Declarative Assignments let assignment_dec_rev = Assignment::::Revealed { seal_definition: crate::contract::seal::Revealed::from(OutPoint::new(txid_vec[0], 1)), - assigned_state: data::Void, + assigned_state: data::Void(), }; let assignment_dec_conf = Assignment::::Confidential { seal_definition: crate::contract::seal::Revealed::from(OutPoint::new(txid_vec[1], 2)) .commit_conceal(), - assigned_state: data::Void, + assigned_state: data::Void(), }; // Create Pedersan Assignments From 8c55082adee4fe613d827f0c03f7c19bdfc6bda2 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Fri, 10 Jun 2022 00:14:50 +0200 Subject: [PATCH 13/15] Remove display(Debug) dummy derives --- src/contract/assignments.rs | 3 +-- src/contract/value.rs | 3 +-- src/schema/mod.rs | 3 +-- src/schema/nodes.rs | 9 +++------ src/schema/state.rs | 3 +-- src/schema/types.rs | 3 +-- 6 files changed, 8 insertions(+), 16 deletions(-) diff --git a/src/contract/assignments.rs b/src/contract/assignments.rs index cf6cc200..dd60c95b 100644 --- a/src/contract/assignments.rs +++ b/src/contract/assignments.rs @@ -45,9 +45,8 @@ pub enum StateType { Data, } -#[derive(Clone, PartialEq, Eq, Debug, Display)] +#[derive(Clone, PartialEq, Eq, Debug)] #[derive(StrictEncode, StrictDecode)] -#[display(Debug)] #[cfg_attr( feature = "serde", derive(Serialize, Deserialize), diff --git a/src/contract/value.rs b/src/contract/value.rs index 91dcac8b..5a4d388f 100644 --- a/src/contract/value.rs +++ b/src/contract/value.rs @@ -182,9 +182,8 @@ impl Ord for Revealed { } } -#[derive(Clone, Debug, Display, AsAny, StrictEncode, StrictDecode)] +#[derive(Clone, Debug, AsAny, StrictEncode, StrictDecode)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(crate = "serde_crate"))] -#[display(Debug)] pub struct Confidential { #[cfg_attr( feature = "serde", diff --git a/src/schema/mod.rs b/src/schema/mod.rs index a2a42875..061c2a54 100644 --- a/src/schema/mod.rs +++ b/src/schema/mod.rs @@ -46,8 +46,7 @@ pub use verify::SchemaVerify; /// Format for the stored history proofs, like proof of burn. It is a part of /// LNPBP standards -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Display)] -#[display(Debug)] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] #[non_exhaustive] #[repr(u8)] pub enum HistoryProofFormat { diff --git a/src/schema/nodes.rs b/src/schema/nodes.rs index cd8b4abb..bc6f23da 100644 --- a/src/schema/nodes.rs +++ b/src/schema/nodes.rs @@ -84,9 +84,8 @@ pub trait NodeSchema { fn abi(&self) -> &BTreeMap; } -#[derive(Clone, PartialEq, Debug, Display, Default, AsAny)] +#[derive(Clone, PartialEq, Debug, Default, AsAny)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(crate = "serde_crate"))] -#[display(Debug)] pub struct GenesisSchema { pub metadata: MetadataStructure, pub owned_rights: OwnedRightsStructure, @@ -94,9 +93,8 @@ pub struct GenesisSchema { pub abi: GenesisAbi, } -#[derive(Clone, PartialEq, Debug, Display, Default, AsAny)] +#[derive(Clone, PartialEq, Debug, Default, AsAny)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(crate = "serde_crate"))] -#[display(Debug)] pub struct ExtensionSchema { pub metadata: MetadataStructure, pub extends: PublicRightsStructure, @@ -105,9 +103,8 @@ pub struct ExtensionSchema { pub abi: ExtensionAbi, } -#[derive(Clone, PartialEq, Debug, Display, Default, AsAny)] +#[derive(Clone, PartialEq, Debug, Default, AsAny)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(crate = "serde_crate"))] -#[display(Debug)] pub struct TransitionSchema { pub metadata: MetadataStructure, pub closes: OwnedRightsStructure, diff --git a/src/schema/state.rs b/src/schema/state.rs index 73247794..bee677e4 100644 --- a/src/schema/state.rs +++ b/src/schema/state.rs @@ -15,9 +15,8 @@ use std::collections::BTreeSet; use super::{script, Bits}; -#[derive(Clone, PartialEq, Debug, Display, StrictEncode, StrictDecode)] +#[derive(Clone, PartialEq, Debug, StrictEncode, StrictDecode)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(crate = "serde_crate"))] -#[display(Debug)] pub struct StateSchema { pub format: StateFormat, pub abi: script::AssignmentAbi, diff --git a/src/schema/types.rs b/src/schema/types.rs index d1b8189b..b69ea9bd 100644 --- a/src/schema/types.rs +++ b/src/schema/types.rs @@ -103,13 +103,12 @@ impl Bits { pub fn bit_len(self) -> usize { self.byte_len() * 8 } } -#[derive(Clone, PartialEq, Eq, Hash, Debug, Display)] +#[derive(Clone, PartialEq, Eq, Hash, Debug)] #[cfg_attr( feature = "serde", derive(Serialize, Deserialize), serde(crate = "serde_crate", rename_all = "camelCase") )] -#[display(Debug)] #[repr(u8)] #[non_exhaustive] pub enum Occurrences { From aee34ed57c333a8712df5abb1337ff1778800740 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Fri, 10 Jun 2022 00:20:22 +0200 Subject: [PATCH 14/15] Complete support for u128/i128 data types --- src/schema/state.rs | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/schema/state.rs b/src/schema/state.rs index bee677e4..92a387b9 100644 --- a/src/schema/state.rs +++ b/src/schema/state.rs @@ -107,12 +107,9 @@ impl DataFormat { #[inline] pub fn u64() -> Self { Self::Unsigned(Bits::Bit64, 0, core::u64::MAX as u128) } - // TODO #14: Add support later once bitcoin library will start supporting - // consensus-encoding of the native rust `u128` type - //#[inline] - //pub fn u128() -> Self { - // Self::Unsigned(Bits::Bit128, 0, core::u128::MAX) - // } + #[inline] + pub fn u128() -> Self { Self::Unsigned(Bits::Bit128, 0, core::u128::MAX) } + // TODO #14: Add support for `u256` type #[inline] pub fn i8() -> Self { Self::Integer(Bits::Bit8, 0, core::i8::MAX as i128) } @@ -126,12 +123,9 @@ impl DataFormat { #[inline] pub fn i64() -> Self { Self::Integer(Bits::Bit64, 0, core::i64::MAX as i128) } - // TODO #14: Add support later once bitcoin library will start supporting - // consensus-encoding of the native rust `u128` type - //#[inline] - //pub fn i128() -> Self { - // Self::Integer(Bits::Bit128, 0, core::i128::MAX) - //} + #[inline] + pub fn i128() -> Self { Self::Integer(Bits::Bit128, 0, core::i128::MAX) } + // TODO #14: Add support for `i256` type #[inline] pub fn f32() -> Self { Self::Float(Bits::Bit32, 0.0, core::f32::MAX as f64) } @@ -198,6 +192,10 @@ mod _validation { (Self::Unsigned(Bits::Bit64, min, max), data::Revealed::U64(val)) => { range_check(item_id, true, *val, *min, *max, &mut status) } + (Self::Unsigned(Bits::Bit128, min, max), data::Revealed::U128(val)) => { + range_check(item_id, true, *val, *min, *max, &mut status) + } + // TODO #14: Add support for `u256` type (Self::Unsigned(bits, _, _), _) => { status.add_failure(validation::Failure::SchemaMismatchedBits { field_or_state_type: item_id, @@ -217,6 +215,10 @@ mod _validation { (Self::Integer(Bits::Bit64, min, max), data::Revealed::I64(val)) => { range_check(item_id, true, *val, *min, *max, &mut status) } + (Self::Integer(Bits::Bit128, min, max), data::Revealed::I128(val)) => { + range_check(item_id, true, *val, *min, *max, &mut status) + } + // TODO #14: Add support for `i256` type (Self::Integer(bits, _, _), _) => { status.add_failure(validation::Failure::SchemaMismatchedBits { field_or_state_type: item_id, From 5145b4c6750969e1c6d07a5d68693f4ccc418740 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Fri, 10 Jun 2022 00:24:04 +0200 Subject: [PATCH 15/15] Support fixed bytes state type in schema validation --- src/schema/state.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/schema/state.rs b/src/schema/state.rs index 92a387b9..150a3517 100644 --- a/src/schema/state.rs +++ b/src/schema/state.rs @@ -272,6 +272,15 @@ mod _validation { }); } } + (Self::FixedBytes(len), data::Revealed::Bytes(val)) => { + if val.len() != *len as usize { + status.add_failure(validation::Failure::SchemaWrongDataLength { + field_or_state_type: item_id, + max_expected: *len, + found: val.len(), + }); + } + } _ => { status.add_failure(validation::Failure::SchemaMismatchedDataType(item_id));