From 272faaff97b00b9f184e50b325dba0615ac1fae6 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Tue, 19 Sep 2023 16:29:23 +0200 Subject: [PATCH] primitives: fix Txid and BlockHash types serde serialization --- primitives/src/block.rs | 18 ++++++---- primitives/src/lib.rs | 2 -- primitives/src/macros.rs | 74 ---------------------------------------- primitives/src/tx.rs | 23 +++++++++---- 4 files changed, 28 insertions(+), 89 deletions(-) delete mode 100644 primitives/src/macros.rs diff --git a/primitives/src/block.rs b/primitives/src/block.rs index b79e5da5..a8375cf0 100644 --- a/primitives/src/block.rs +++ b/primitives/src/block.rs @@ -19,12 +19,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -use amplify::{Bytes32, Wrapper}; +use amplify::hex::{self, FromHex}; +use amplify::{Bytes32, Bytes32StrRev, Wrapper}; use crate::LIB_NAME_BITCOIN; -#[derive(Wrapper, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Display, From)] -#[display(LowerHex)] +#[derive(Wrapper, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, From)] #[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] #[strict_type(lib = LIB_NAME_BITCOIN)] #[cfg_attr( @@ -32,13 +32,19 @@ use crate::LIB_NAME_BITCOIN; derive(Serialize, Deserialize), serde(crate = "serde_crate", transparent) )] -#[wrapper(BorrowSlice, Index, RangeOps)] +#[wrapper(BorrowSlice, Index, RangeOps, Debug, LowerHex, UpperHex, Display, FromStr)] pub struct BlockHash( #[from] #[from([u8; 32])] - Bytes32, + Bytes32StrRev, ); -impl_sha256d_hashtype!(BlockHash, "BlockHash"); + +impl FromHex for BlockHash { + fn from_byte_iter(iter: I) -> Result + where I: Iterator> + ExactSizeIterator + DoubleEndedIterator { + Bytes32StrRev::from_byte_iter(iter).map(Self) + } +} #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] #[cfg_attr( diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index e816e27b..f3c0facb 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -44,8 +44,6 @@ extern crate serde_crate as serde; /// Re-export of `secp256k1` crate. pub extern crate secp256k1; -#[macro_use] -mod macros; mod block; pub mod opcodes; mod script; diff --git a/primitives/src/macros.rs b/primitives/src/macros.rs deleted file mode 100644 index 93f8ec79..00000000 --- a/primitives/src/macros.rs +++ /dev/null @@ -1,74 +0,0 @@ -// Bitcoin protocol primitives library. -// -// SPDX-License-Identifier: Apache-2.0 -// -// Written in 2019-2023 by -// Dr Maxim Orlovsky -// -// Copyright (C) 2019-2023 LNP/BP Standards Association. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/// Satoshi made all SHA245d-based hashes to be displayed as hex strings in a -/// big endian order. Thus we need this manual implementation. -macro_rules! impl_sha256d_hashtype { - ($ty:ident, $name:literal) => { - mod _sha256_hash_impl { - use core::fmt::{self, Debug, Formatter, LowerHex, UpperHex}; - use core::str::FromStr; - - use amplify::hex::{self, FromHex, ToHex}; - use amplify::{Bytes32, RawArray, Wrapper}; - - use super::$ty; - - impl From<$ty> for [u8; 32] { - fn from(value: $ty) -> Self { value.0.into_inner() } - } - - impl Debug for $ty { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - f.debug_tuple($name).field(&self.to_hex()).finish() - } - } - - impl LowerHex for $ty { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - let mut slice = self.to_raw_array(); - slice.reverse(); - f.write_str(&slice.to_hex()) - } - } - - impl UpperHex for $ty { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - f.write_str(&self.to_hex().to_uppercase()) - } - } - - impl FromStr for $ty { - type Err = hex::Error; - fn from_str(s: &str) -> Result { Self::from_hex(s) } - } - - impl FromHex for $ty { - fn from_byte_iter(iter: I) -> Result - where I: Iterator> - + ExactSizeIterator - + DoubleEndedIterator { - Bytes32::from_byte_iter(iter.rev()).map(Self::from) - } - } - } - }; -} diff --git a/primitives/src/tx.rs b/primitives/src/tx.rs index cbe1812a..5d509cca 100644 --- a/primitives/src/tx.rs +++ b/primitives/src/tx.rs @@ -24,13 +24,13 @@ use std::iter::Sum; use std::num::ParseIntError; use std::str::FromStr; -use amplify::{hex, Bytes32, Wrapper}; +use amplify::hex::FromHex; +use amplify::{hex, Bytes32StrRev, Wrapper}; use super::{VarIntArray, LIB_NAME_BITCOIN}; use crate::{NonStandardValue, ScriptPubkey, SigScript}; -#[derive(Wrapper, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Display, From)] -#[display(LowerHex)] +#[derive(Wrapper, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, From)] #[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] #[strict_type(lib = LIB_NAME_BITCOIN)] #[derive(CommitEncode)] @@ -40,19 +40,25 @@ use crate::{NonStandardValue, ScriptPubkey, SigScript}; derive(Serialize, Deserialize), serde(crate = "serde_crate", transparent) )] -#[wrapper(BorrowSlice, Index, RangeOps)] +#[wrapper(BorrowSlice, Index, RangeOps, Debug, LowerHex, UpperHex, Display, FromStr)] // all-zeros used in coinbase pub struct Txid( #[from] #[from([u8; 32])] - Bytes32, + Bytes32StrRev, ); -impl_sha256d_hashtype!(Txid, "Txid"); impl Txid { pub fn coinbase() -> Self { Self(zero!()) } } +impl FromHex for Txid { + fn from_byte_iter(iter: I) -> Result + where I: Iterator> + ExactSizeIterator + DoubleEndedIterator { + Bytes32StrRev::from_byte_iter(iter).map(Self) + } +} + #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Display, From)] #[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] #[strict_type(lib = LIB_NAME_BITCOIN)] @@ -367,11 +373,14 @@ mod test { #[test] fn txid_byteorder() { - let hex = "c9a86c99127f1b2d1ff495c238f13069ac881ec9527905016122d11d85b19b61"; + let hex = "ed9f6388c0360c1861d331a0388d5a54815dd720cc67fa783c348217a0e943ca"; let from_str = Txid::from_str(hex).unwrap(); let from_hex = Txid::from_hex(hex).unwrap(); assert_eq!(from_str, from_hex); assert_eq!(from_str.to_string(), from_str.to_hex()); + assert_eq!(from_str.to_string(), hex); + assert_eq!(format!("{from_str:x}"), hex); + assert_eq!(from_str[0], 0xca); } #[test]