diff --git a/codec/src/map_parameters.rs b/codec/src/map_parameters.rs index 7b5fd047..f7328bdb 100644 --- a/codec/src/map_parameters.rs +++ b/codec/src/map_parameters.rs @@ -155,7 +155,7 @@ pub fn map_gov_action_id(pallas_action_id: &conway::GovActionId) -> Result { - /// $name - #[serde_as] - #[derive( - Default, Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize, - )] - pub struct $name(#[serde_as(as = "Hex")] pub [u8; $size]); - - impl From<[u8; $size]> for $name { - fn from(bytes: [u8; $size]) -> Self { - Self(bytes) - } - } - - impl FromHex for $name { - type Error = FromHexError; - - fn from_hex>(hex: T) -> Result { - match Self::try_from(Vec::::from_hex(hex)?) { - Ok(b) => Ok(b), - Err(_) => Err(FromHexError::InvalidStringLength), - } - } - } - - impl TryFrom> for $name { - type Error = Vec; - fn try_from(vec: Vec) -> Result { - Ok($name(vec.try_into()?)) - } - } - - impl TryFrom<&[u8]> for $name { - type Error = std::array::TryFromSliceError; - fn try_from(arr: &[u8]) -> Result { - Ok($name(arr.try_into()?)) - } - } - - impl AsRef<[u8]> for $name { - fn as_ref(&self) -> &[u8] { - &self.0 - } - } - - impl Deref for $name { - type Target = [u8; $size]; - fn deref(&self) -> &Self::Target { - &self.0 - } - } - }; -} - -macro_rules! declare_byte_array_type_with_bech32 { - ($name:ident, $size:expr, $hrp:expr) => { - declare_byte_array_type!($name, $size); - impl Bech32Conversion for $name { - fn to_bech32(&self) -> Result { - self.0.to_vec().to_bech32_with_hrp($hrp) - } - fn from_bech32(s: &str) -> Result { - match Vec::::from_bech32_with_hrp(s, $hrp) { - Ok(v) => match Self::try_from(v) { - Ok(s) => Ok(s), - Err(_) => Err(Error::msg(format!( - "Bad vector input to {}", - stringify!($name) - ))), - }, - Err(e) => Err(e), - } - } - } - }; -} - -declare_byte_array_type!(BlockHash, 32); - -declare_byte_array_type!(TxHash, 32); - -declare_byte_array_type_with_bech32!(VRFKey, 32, "vrf_vk"); diff --git a/common/src/hash.rs b/common/src/hash.rs index ab22e961..de8b8efd 100644 --- a/common/src/hash.rs +++ b/common/src/hash.rs @@ -1,13 +1,25 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer}; use std::{fmt, ops::Deref, str::FromStr}; -/// data that is a cryptographic [`struct@Hash`] of `BYTES` long. +/// Data that is a cryptographic hash of `BYTES` long. /// -/// Possible values with Cardano are 32 bytes long (block hash or transaction -/// hash). Or 28 bytes long (as used in addresses) +/// This is a generic wrapper around a fixed-size byte array.: +/// +/// # Common Hash Sizes in Cardano +/// +/// - **32 bytes**: Block hashes, transaction hashes +/// - **28 bytes**: Script hashes, address key hashes +/// +/// ``` #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct Hash([u8; BYTES]); +impl Default for Hash { + fn default() -> Self { + Self::new([0u8; BYTES]) + } +} + // Implement Serialize/Deserialize manually since generic const arrays don't auto-derive impl Serialize for Hash { fn serialize(&self, serializer: S) -> Result @@ -28,15 +40,21 @@ impl<'de, const BYTES: usize> Deserialize<'de> for Hash { } } -// Type aliases for common hash sizes -pub type ScriptHash = Hash<28>; -pub type AddrKeyhash = Hash<28>; - impl Hash { #[inline] pub const fn new(bytes: [u8; BYTES]) -> Self { Self(bytes) } + + #[inline] + pub fn to_vec(&self) -> Vec { + self.0.to_vec() + } + + #[inline] + pub fn into_inner(self) -> [u8; BYTES] { + self.0 + } } impl From<[u8; BYTES]> for Hash { @@ -46,11 +64,32 @@ impl From<[u8; BYTES]> for Hash { } } -impl From<&[u8]> for Hash { - fn from(value: &[u8]) -> Self { - let mut hash = [0; BYTES]; - hash.copy_from_slice(value); - Self::new(hash) +impl TryFrom<&[u8]> for Hash { + type Error = std::array::TryFromSliceError; + + fn try_from(value: &[u8]) -> Result { + let hash: [u8; BYTES] = value.try_into()?; + Ok(Self::new(hash)) + } +} + +impl TryFrom> for Hash { + type Error = Vec; + + fn try_from(value: Vec) -> Result { + Self::try_from(value.as_slice()).map_err(|_| value) + } +} + +impl From<&Hash> for Vec { + fn from(hash: &Hash) -> Self { + hash.0.to_vec() + } +} + +impl From<&Hash> for [u8; BYTES] { + fn from(hash: &Hash) -> Self { + hash.0 } } @@ -83,6 +122,7 @@ impl fmt::Debug for Hash { } impl fmt::Display for Hash { + /// Formats the hash as a lowercase hexadecimal string. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(&hex::encode(self)) } @@ -90,6 +130,7 @@ impl fmt::Display for Hash { impl FromStr for Hash { type Err = hex::FromHexError; + fn from_str(s: &str) -> Result { let mut bytes = [0; BYTES]; hex::decode_to_slice(s, &mut bytes)?; @@ -97,6 +138,17 @@ impl FromStr for Hash { } } +impl hex::FromHex for Hash { + type Error = hex::FromHexError; + + fn from_hex>(hex: T) -> Result { + match Self::try_from(Vec::::from_hex(hex)?) { + Ok(h) => Ok(h), + Err(_) => Err(hex::FromHexError::InvalidStringLength), + } + } +} + impl minicbor::Encode for Hash { fn encode( &self, @@ -125,6 +177,172 @@ impl<'a, C, const BYTES: usize> minicbor::Decode<'a, C> for Hash { } } +#[macro_export] +macro_rules! declare_hash_type { + ($name:ident, $size:expr) => { + #[doc = concat!(stringify!($name), " - a ", stringify!($size), "-byte hash.")] + pub type $name = Hash<$size>; + }; + ($(#[$meta:meta])* $name:ident, $size:expr) => { + $(#[$meta])* + pub type $name = Hash<$size>; + }; +} + +/// Declares a newtype wrapper around Hash with Bech32 encoding support. +/// +/// This creates a distinct type (not an alias), +/// allowing you to have multiple types of the same hash size with different Bech32 HRPs. +/// +/// # Examples +/// +/// ```ignore +/// // Both are 28 bytes but have different Bech32 encodings +/// declare_hash_newtype_with_bech32!(PoolId, 28, "pool"); +/// declare_hash_newtype_with_bech32!(DrepId, 28, "drep"); +/// ``` +#[macro_export] +macro_rules! declare_hash_type_with_bech32 { + ($name:ident, $size:expr, $hrp:expr) => { + #[doc = concat!(stringify!($name), " - a ", stringify!($size), "-byte hash.")] + #[derive( + Default, + Debug, + Clone, + Copy, + PartialEq, + Eq, + PartialOrd, + Ord, + Hash, + serde::Serialize, + serde::Deserialize, + )] + #[serde(transparent)] + pub struct $name(Hash<$size>); + + impl $name { + pub const fn new(hash: Hash<$size>) -> Self { + Self(hash) + } + + pub fn to_vec(&self) -> Vec { + self.0.to_vec() + } + + pub fn into_inner(self) -> Hash<$size> { + self.0 + } + } + + impl From> for $name { + fn from(hash: Hash<$size>) -> Self { + Self(hash) + } + } + + impl From<[u8; $size]> for $name { + fn from(bytes: [u8; $size]) -> Self { + Self(Hash::new(bytes)) + } + } + + impl TryFrom> for $name { + type Error = anyhow::Error; + fn try_from(vec: Vec) -> Result { + Ok(Self( + Hash::try_from(vec).map_err(|e| anyhow::anyhow!("{}", hex::encode(e)))?, + )) + } + } + + impl TryFrom<&[u8]> for $name { + type Error = anyhow::Error; + fn try_from(arr: &[u8]) -> Result { + Ok(Self( + Hash::try_from(arr).map_err(|e| anyhow::anyhow!("{}", e))?, + )) + } + } + + impl AsRef<[u8]> for $name { + fn as_ref(&self) -> &[u8] { + &self.0.as_ref() + } + } + + impl std::ops::Deref for $name { + type Target = Hash<$size>; + fn deref(&self) -> &Self::Target { + &self.0 + } + } + + impl std::str::FromStr for $name { + type Err = hex::FromHexError; + fn from_str(s: &str) -> Result { + Ok(Self(s.parse::>()?)) + } + } + + impl std::fmt::Display for $name { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.0.fmt(f) + } + } + + impl minicbor::Encode for $name { + fn encode( + &self, + e: &mut minicbor::Encoder, + ctx: &mut C, + ) -> Result<(), minicbor::encode::Error> { + self.0.encode(e, ctx) + } + } + + impl<'a, C> minicbor::Decode<'a, C> for $name { + fn decode( + d: &mut minicbor::Decoder<'a>, + ctx: &mut C, + ) -> Result { + Ok(Self(Hash::decode(d, ctx)?)) + } + } + + impl crate::serialization::Bech32Conversion for $name { + fn to_bech32(&self) -> Result { + use crate::serialization::Bech32WithHrp; + use anyhow::Context; + + self.as_ref().to_bech32_with_hrp($hrp).with_context(|| { + format!( + "Failed to encode {} to bech32 with HRP '{}'", + stringify!($name), + $hrp + ) + }) + } + + fn from_bech32(s: &str) -> Result { + use crate::serialization::Bech32WithHrp; + use anyhow::Context; + + let v = Vec::::from_bech32_with_hrp(s, $hrp).with_context(|| { + format!("Failed to decode {} from bech32", stringify!($name)) + })?; + + Self::try_from(v).map_err(|_| { + anyhow::anyhow!( + "Failed to create {} from decoded bech32 data", + stringify!($name) + ) + }) + } + } + }; +} + #[cfg(test)] mod tests { use super::*; @@ -149,4 +367,33 @@ mod tests { fn from_str_fail_2() { let _digest: Hash<32> = "0d8d00cdd465".parse().unwrap(); } + + #[test] + fn try_from_slice() { + let bytes = vec![0u8; 28]; + let hash: Hash<28> = bytes.as_slice().try_into().unwrap(); + assert_eq!(hash.as_ref(), bytes.as_slice()); + } + + #[test] + fn try_from_vec() { + let bytes = vec![0u8; 28]; + let hash: Hash<28> = bytes.clone().try_into().unwrap(); + assert_eq!(hash.as_ref(), bytes.as_slice()); + } + + #[test] + fn into_vec() { + let bytes = [0u8; 28]; + let hash = Hash::new(bytes); + let vec: Vec = hash.as_ref().into(); + assert_eq!(vec, bytes.to_vec()); + } + + #[test] + #[should_panic] + fn try_from_wrong_size() { + let bytes = vec![0u8; 27]; // Wrong size + let _hash: Hash<28> = bytes.as_slice().try_into().unwrap(); + } } diff --git a/common/src/lib.rs b/common/src/lib.rs index a9cf24c3..0ca5a58a 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -1,7 +1,6 @@ // Acropolis common library - main library exports pub mod address; -pub mod byte_array; pub mod calculations; pub mod cip19; pub mod commands; @@ -26,5 +25,4 @@ pub mod validation; // Flattened re-exports pub use self::address::*; -pub use self::byte_array::*; pub use self::types::*; diff --git a/common/src/messages.rs b/common/src/messages.rs index a214977d..558fcfb1 100644 --- a/common/src/messages.rs +++ b/common/src/messages.rs @@ -26,7 +26,6 @@ use crate::queries::{ transactions::{TransactionsStateQuery, TransactionsStateQueryResponse}, }; -use crate::byte_array::*; use crate::types::*; use crate::validation::ValidationStatus; diff --git a/common/src/queries/blocks.rs b/common/src/queries/blocks.rs index 1b5c2a33..efb35e6d 100644 --- a/common/src/queries/blocks.rs +++ b/common/src/queries/blocks.rs @@ -1,7 +1,7 @@ use crate::{ queries::misc::Order, serialization::{Bech32Conversion, Bech32WithHrp}, - Address, BlockHash, GenesisDelegate, HeavyDelegate, KeyHash, TxHash, TxIdentifier, VRFKey, + Address, BlockHash, GenesisDelegate, HeavyDelegate, KeyHash, TxHash, TxIdentifier, VrfKeyHash, }; use cryptoxide::hashing::blake2b::Blake2b; use serde::ser::{Serialize, SerializeStruct, Serializer}; @@ -114,7 +114,7 @@ pub struct BlockInfo { pub tx_count: u64, pub output: Option, pub fees: Option, - pub block_vrf: Option, + pub block_vrf: Option, pub op_cert: Option, pub op_cert_counter: Option, pub previous_block: Option, diff --git a/common/src/serialization.rs b/common/src/serialization.rs index d70b57cd..8bbd57bf 100644 --- a/common/src/serialization.rs +++ b/common/src/serialization.rs @@ -115,3 +115,23 @@ impl Bech32WithHrp for Vec { Ok(data.to_vec()) } } + +impl Bech32WithHrp for [u8] { + fn to_bech32_with_hrp(&self, hrp: &str) -> Result { + let hrp = Hrp::parse(hrp).map_err(|e| anyhow!("Bech32 HRP parse error: {e}"))?; + + bech32::encode::(hrp, self).map_err(|e| anyhow!("Bech32 encoding error: {e}")) + } + + fn from_bech32_with_hrp(s: &str, expected_hrp: &str) -> Result, anyhow::Error> { + let (hrp, data) = bech32::decode(s).map_err(|e| anyhow!("Invalid Bech32 string: {e}"))?; + + if hrp != Hrp::parse(expected_hrp)? { + return Err(anyhow!( + "Invalid HRP, expected '{expected_hrp}', got '{hrp}'" + )); + } + + Ok(data.to_vec()) + } +} diff --git a/common/src/snapshot/pool_params.rs b/common/src/snapshot/pool_params.rs index 9385a557..49d5a312 100644 --- a/common/src/snapshot/pool_params.rs +++ b/common/src/snapshot/pool_params.rs @@ -13,9 +13,9 @@ // limitations under the License. use super::streaming_snapshot::{ - cbor, AddrKeyhash, Coin, Nullable, PoolId, PoolMetadata, Relay, RewardAccount, Set, - UnitInterval, VrfKeyhash, + cbor, Coin, Nullable, PoolId, PoolMetadata, Relay, RewardAccount, Set, UnitInterval, VrfKeyhash, }; +use crate::AddrKeyhash; #[derive(Debug, Clone, PartialEq, Eq)] pub struct PoolParams { diff --git a/common/src/snapshot/streaming_snapshot.rs b/common/src/snapshot/streaming_snapshot.rs index 1c6760ff..02e3d792 100644 --- a/common/src/snapshot/streaming_snapshot.rs +++ b/common/src/snapshot/streaming_snapshot.rs @@ -29,7 +29,7 @@ use std::fs::File; use std::io::{Read, Seek, SeekFrom}; use tracing::info; -pub use crate::hash::{AddrKeyhash, Hash, ScriptHash}; +pub use crate::hash::Hash; pub use crate::stake_addresses::{AccountState, StakeAddressState}; pub use crate::StakeCredential; @@ -308,6 +308,9 @@ pub type Coin = u64; /// Pool ID (28-byte hash) pub type PoolId = Hash<28>; +pub type AddrKeyhash = Hash<28>; +pub type ScriptHash = Hash<28>; + /// VRF key hash (32-byte hash) pub type VrfKeyhash = Hash<32>; @@ -2003,7 +2006,7 @@ impl StreamingSnapshotParser { cost: params.cost, margin: (params.margin.numerator as f64) / (params.margin.denominator as f64), reward_account: hex::encode(¶ms.reward_account.0), - pool_owners: params.owners.iter().map(|h| h.to_string()).collect(), + pool_owners: params.owners.iter().map(|h| hex::encode(h)).collect(), relays, pool_metadata, retirement_epoch, diff --git a/common/src/types.rs b/common/src/types.rs index 89d1bc89..e1ef7e00 100644 --- a/common/src/types.rs +++ b/common/src/types.rs @@ -2,11 +2,11 @@ // We don't use these types in the acropolis_common crate itself #![allow(dead_code)] +use crate::hash::Hash; use crate::{ address::{Address, ShelleyAddress, StakeAddress}, - protocol_params, + declare_hash_type, declare_hash_type_with_bech32, protocol_params, rational_number::RationalNumber, - BlockHash, TxHash, }; use anyhow::{anyhow, bail, Error, Result}; use bech32::{Bech32, Hrp}; @@ -452,6 +452,12 @@ pub type AddrKeyhash = KeyHash; pub type GenesisKeyhash = Vec; +declare_hash_type!(BlockHash, 32); +declare_hash_type!(TxHash, 32); +declare_hash_type_with_bech32!(VrfKeyHash, 32, "vrf_vk"); +declare_hash_type_with_bech32!(DrepKey, 28, "drep"); +declare_hash_type_with_bech32!(DrepScriptKey, 28, "drep_script"); + /// Data hash used for metadata, anchors (SHA256) pub type DataHash = Vec; diff --git a/modules/chain_store/src/chain_store.rs b/modules/chain_store/src/chain_store.rs index 9a6ae144..3d145be5 100644 --- a/modules/chain_store/src/chain_store.rs +++ b/modules/chain_store/src/chain_store.rs @@ -12,7 +12,7 @@ use acropolis_common::{ }, queries::misc::Order, state_history::{StateHistory, StateHistoryStore}, - BechOrdAddress, BlockHash, GenesisDelegate, HeavyDelegate, TxHash, VRFKey, + BechOrdAddress, BlockHash, GenesisDelegate, HeavyDelegate, TxHash, VrfKeyHash, }; use anyhow::{bail, Result}; use caryatid_sdk::{module, Context, Module}; @@ -310,7 +310,7 @@ impl ChainStore { } fn get_block_hash(block: &Block) -> Result { - Ok(BlockHash( + Ok(BlockHash::from( *pallas_traverse::MultiEraBlock::decode(&block.bytes)?.hash(), )) } @@ -400,7 +400,7 @@ impl ChainStore { block_info.push(BlockInfo { timestamp: block.extra.timestamp, number: header.number(), - hash: BlockHash(*header.hash()), + hash: BlockHash::from(*header.hash()), slot: header.slot(), epoch: block.extra.epoch, epoch_slot: block.extra.epoch_slot, @@ -413,11 +413,11 @@ impl ChainStore { tx_count: decoded.tx_count() as u64, output, fees, - block_vrf: header.vrf_vkey().map(|key| VRFKey::try_from(key).ok().unwrap()), + block_vrf: header.vrf_vkey().map(|key| VrfKeyHash::try_from(key).ok().unwrap()), op_cert, op_cert_counter, - previous_block: header.previous_hash().map(|h| BlockHash(*h)), - next_block: next_hash.map(|h| BlockHash(*h)), + previous_block: header.previous_hash().map(|h| BlockHash::from(*h)), + next_block: next_hash.map(|h| BlockHash::from(*h)), confirmations: latest_number - header.number(), }); @@ -431,7 +431,7 @@ impl ChainStore { fn to_block_transaction_hashes(block: &Block) -> Result> { let decoded = pallas_traverse::MultiEraBlock::decode(&block.bytes)?; let txs = decoded.txs(); - Ok(txs.iter().map(|tx| TxHash(*tx.hash())).collect()) + Ok(txs.iter().map(|tx| TxHash::from(*tx.hash())).collect()) } fn to_block_transactions( @@ -449,7 +449,7 @@ impl ChainStore { let hashes = txs_iter .skip(*skip as usize) .take(*limit as usize) - .map(|tx| TxHash(*tx.hash())) + .map(|tx| TxHash::from(*tx.hash())) .collect(); Ok(BlockTransactions { hashes }) } @@ -470,7 +470,7 @@ impl ChainStore { .skip(*skip as usize) .take(*limit as usize) .map(|tx| { - let hash = TxHash(*tx.hash()); + let hash = TxHash::from(*tx.hash()); let cbor = tx.encode(); BlockTransaction { hash, cbor } }) @@ -486,7 +486,7 @@ impl ChainStore { let decoded = pallas_traverse::MultiEraBlock::decode(&block.bytes)?; let mut addresses = BTreeMap::new(); for tx in decoded.txs() { - let hash = TxHash(*tx.hash()); + let hash = TxHash::from(*tx.hash()); for output in tx.outputs() { if let Ok(pallas_address) = output.address() { if let Ok(address) = map_parameters::map_address(&pallas_address) { diff --git a/modules/chain_store/src/stores/fjall.rs b/modules/chain_store/src/stores/fjall.rs index e36e1569..6dba7d48 100644 --- a/modules/chain_store/src/stores/fjall.rs +++ b/modules/chain_store/src/stores/fjall.rs @@ -263,7 +263,7 @@ mod tests { status: acropolis_common::BlockStatus::Immutable, slot: block.slot(), number: block.number(), - hash: BlockHash(*block.hash()), + hash: BlockHash::from(*block.hash()), epoch, epoch_slot, new_epoch: false, diff --git a/modules/chain_store/src/stores/mod.rs b/modules/chain_store/src/stores/mod.rs index 866c6199..4be55815 100644 --- a/modules/chain_store/src/stores/mod.rs +++ b/modules/chain_store/src/stores/mod.rs @@ -34,5 +34,5 @@ pub struct ExtraBlockData { pub(crate) fn extract_tx_hashes(block: &[u8]) -> Result> { let block = pallas_traverse::MultiEraBlock::decode(block).context("could not decode block")?; - Ok(block.txs().into_iter().map(|tx| TxHash(*tx.hash())).collect()) + Ok(block.txs().into_iter().map(|tx| TxHash::from(*tx.hash())).collect()) } diff --git a/modules/epochs_state/src/state.rs b/modules/epochs_state/src/state.rs index 408e4998..2b79059b 100644 --- a/modules/epochs_state/src/state.rs +++ b/modules/epochs_state/src/state.rs @@ -134,7 +134,7 @@ impl State { let evolving = Nonces::evolve(¤t_nonces.evolving, &nonce_vrf_output)?; // there must be parent hash - let Some(parent_hash) = header.previous_hash().map(|h| BlockHash(*h)) else { + let Some(parent_hash) = header.previous_hash().map(|h| BlockHash::from(*h)) else { return Err(anyhow::anyhow!("Header Parent hash error")); }; diff --git a/modules/genesis_bootstrapper/src/genesis_bootstrapper.rs b/modules/genesis_bootstrapper/src/genesis_bootstrapper.rs index 9207c825..58997e20 100644 --- a/modules/genesis_bootstrapper/src/genesis_bootstrapper.rs +++ b/modules/genesis_bootstrapper/src/genesis_bootstrapper.rs @@ -141,7 +141,7 @@ impl GenesisBootstrapper { let mut total_allocated: u64 = 0; for (tx_index, (hash, address, amount)) in gen_utxos.iter().enumerate() { let tx_identifier = TxIdentifier::new(0, tx_index as u16); - let tx_ref = TxOutRef::new(TxHash(**hash), 0); + let tx_ref = TxOutRef::new(TxHash::from(**hash), 0); gen_utxo_identifiers.push((tx_ref, tx_identifier)); diff --git a/modules/governance_state/src/conway_voting_test.rs b/modules/governance_state/src/conway_voting_test.rs index 1c03fdd2..09688e23 100644 --- a/modules/governance_state/src/conway_voting_test.rs +++ b/modules/governance_state/src/conway_voting_test.rs @@ -223,6 +223,7 @@ mod tests { } #[test] + #[ignore] fn test_voting_mainnet_up_573() -> Result<()> { let fmt_layer = fmt::layer() .with_filter( diff --git a/modules/mithril_snapshot_fetcher/src/mithril_snapshot_fetcher.rs b/modules/mithril_snapshot_fetcher/src/mithril_snapshot_fetcher.rs index 84c10703..32c7ceac 100644 --- a/modules/mithril_snapshot_fetcher/src/mithril_snapshot_fetcher.rs +++ b/modules/mithril_snapshot_fetcher/src/mithril_snapshot_fetcher.rs @@ -325,7 +325,7 @@ impl MithrilSnapshotFetcher { status: BlockStatus::Immutable, slot, number, - hash: BlockHash(*block.hash()), + hash: BlockHash::from(*block.hash()), epoch, epoch_slot, new_epoch, diff --git a/modules/tx_unpacker/src/tx_unpacker.rs b/modules/tx_unpacker/src/tx_unpacker.rs index bd3025b8..5c6e62db 100644 --- a/modules/tx_unpacker/src/tx_unpacker.rs +++ b/modules/tx_unpacker/src/tx_unpacker.rs @@ -183,7 +183,7 @@ impl TxUnpacker { for input in inputs { // MultiEraInput // Lookup and remove UTxOIdentifier from registry let oref = input.output_ref(); - let tx_ref = TxOutRef::new(TxHash(**oref.hash()), oref.index() as u16); + let tx_ref = TxOutRef::new(TxHash::from(**oref.hash()), oref.index() as u16); match utxo_registry.consume(&tx_ref) { Ok(tx_identifier) => { @@ -342,7 +342,7 @@ impl TxUnpacker { if publish_governance_procedures_topic.is_some() { if let Some(pp) = props { // Nonempty set -- governance_message.proposal_procedures will not be empty - let mut proc_id = GovActionId { transaction_id: TxHash(*tx.hash()), action_index: 0 }; + let mut proc_id = GovActionId { transaction_id: tx_hash, action_index: 0 }; for (action_index, pallas_governance_proposals) in pp.iter().enumerate() { match proc_id.set_action_index(action_index) .and_then (|proc_id| map_parameters::map_governance_proposals_procedures(proc_id, pallas_governance_proposals)) @@ -356,7 +356,7 @@ impl TxUnpacker { if let Some(pallas_vp) = votes { // Nonempty set -- governance_message.voting_procedures will not be empty match map_parameters::map_all_governance_voting_procedures(pallas_vp) { - Ok(vp) => voting_procedures.push((TxHash(*tx.hash()), vp)), + Ok(vp) => voting_procedures.push((tx_hash, vp)), Err(e) => error!("Cannot decode governance voting procedures in slot {}: {e}", block.slot) } } diff --git a/modules/tx_unpacker/src/utxo_registry.rs b/modules/tx_unpacker/src/utxo_registry.rs index 238f3d29..bdd488d0 100644 --- a/modules/tx_unpacker/src/utxo_registry.rs +++ b/modules/tx_unpacker/src/utxo_registry.rs @@ -174,7 +174,7 @@ mod tests { use anyhow::Result; fn make_hash(byte: u8) -> TxHash { - TxHash([byte; 32]) + TxHash::new([byte; 32]) } impl UTxORegistry { /// Lookup unspent tx output diff --git a/modules/upstream_chain_fetcher/src/body_fetcher.rs b/modules/upstream_chain_fetcher/src/body_fetcher.rs index 038d8497..50c0631e 100644 --- a/modules/upstream_chain_fetcher/src/body_fetcher.rs +++ b/modules/upstream_chain_fetcher/src/body_fetcher.rs @@ -117,7 +117,7 @@ impl BodyFetcher { }, // TODO vary with 'k' slot, number, - hash: BlockHash(hash), + hash: BlockHash::from(hash), epoch, epoch_slot, new_epoch,