From 25a26f9643f6d65e60683587d2747317bfbbb8b2 Mon Sep 17 00:00:00 2001 From: Thibault Martinez Date: Sun, 3 Dec 2023 14:41:03 +0100 Subject: [PATCH 1/2] Derive Packable for SignedTransactionPayload --- .../block/payload/signed_transaction/mod.rs | 46 +++++-------------- 1 file changed, 12 insertions(+), 34 deletions(-) diff --git a/sdk/src/types/block/payload/signed_transaction/mod.rs b/sdk/src/types/block/payload/signed_transaction/mod.rs index 41a983c453..39af5185a6 100644 --- a/sdk/src/types/block/payload/signed_transaction/mod.rs +++ b/sdk/src/types/block/payload/signed_transaction/mod.rs @@ -6,7 +6,7 @@ mod transaction; mod transaction_id; -use packable::{error::UnpackError, packer::Packer, unpacker::Unpacker, Packable, PackableExt}; +use packable::{Packable, PackableExt}; pub(crate) use self::transaction::{ContextInputCount, InputCount, OutputCount}; pub use self::{ @@ -20,7 +20,9 @@ use crate::types::block::{ }; /// A signed transaction to move funds. -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Packable)] +#[packable(unpack_error = Error)] +#[packable(verify_with = verify_signed_transaction_payload)] pub struct SignedTransactionPayload { transaction: Transaction, unlocks: Unlocks, @@ -32,9 +34,11 @@ impl SignedTransactionPayload { /// Creates a new [`SignedTransactionPayload`]. pub fn new(transaction: Transaction, unlocks: Unlocks) -> Result { - verify_transaction_unlocks(&transaction, &unlocks)?; + let payload = Self { transaction, unlocks }; - Ok(Self { transaction, unlocks }) + verify_signed_transaction_payload::(&payload)?; + + Ok(payload) } /// Returns the transaction of a [`SignedTransactionPayload`]. @@ -57,37 +61,11 @@ impl WorkScore for SignedTransactionPayload { } } -impl Packable for SignedTransactionPayload { - type UnpackError = Error; - type UnpackVisitor = ProtocolParameters; - - fn pack(&self, packer: &mut P) -> Result<(), P::Error> { - self.transaction.pack(packer)?; - self.unlocks.pack(packer)?; - - Ok(()) - } - - fn unpack( - unpacker: &mut U, - visitor: &Self::UnpackVisitor, - ) -> Result> { - let transaction = Transaction::unpack::<_, VERIFY>(unpacker, visitor)?; - let unlocks = Unlocks::unpack::<_, VERIFY>(unpacker, &())?; - - if VERIFY { - verify_transaction_unlocks(&transaction, &unlocks).map_err(UnpackError::Packable)?; - } - - Ok(Self { transaction, unlocks }) - } -} - -fn verify_transaction_unlocks(transaction: &Transaction, unlocks: &Unlocks) -> Result<(), Error> { - if transaction.inputs().len() != unlocks.len() { +fn verify_signed_transaction_payload(payload: &SignedTransactionPayload) -> Result<(), Error> { + if payload.transaction.inputs().len() != payload.unlocks.len() { return Err(Error::InputUnlockCountMismatch { - input_count: transaction.inputs().len(), - unlock_count: unlocks.len(), + input_count: payload.transaction.inputs().len(), + unlock_count: payload.unlocks.len(), }); } From e9ef34a9db8f12f67528f21d9caf637985b17c1a Mon Sep 17 00:00:00 2001 From: Thibault Martinez Date: Sun, 3 Dec 2023 14:48:05 +0100 Subject: [PATCH 2/2] Derive Packable for BlockHeader --- sdk/src/types/block/core/block.rs | 77 ++++++++++--------------------- 1 file changed, 25 insertions(+), 52 deletions(-) diff --git a/sdk/src/types/block/core/block.rs b/sdk/src/types/block/core/block.rs index 2a4f7c53f9..9a2f4e51ef 100644 --- a/sdk/src/types/block/core/block.rs +++ b/sdk/src/types/block/core/block.rs @@ -7,7 +7,7 @@ use core::mem::size_of; use crypto::hashes::{blake2b::Blake2b256, Digest}; use getset::{CopyGetters, Getters}; use packable::{ - error::{UnexpectedEOF, UnpackError, UnpackErrorExt}, + error::{UnexpectedEOF, UnpackError}, packer::{Packer, SlicePacker}, unpacker::{CounterUnpacker, SliceUnpacker, Unpacker}, Packable, PackableExt, @@ -61,12 +61,16 @@ impl UnsignedBlock { } } -#[derive(Clone, Debug, Eq, PartialEq, CopyGetters)] +#[derive(Clone, Debug, Eq, PartialEq, CopyGetters, Packable)] +#[packable(unpack_error = Error)] +#[packable(unpack_visitor = ProtocolParameters)] #[getset(get_copy = "pub")] pub struct BlockHeader { /// Protocol version of the network to which this block belongs. + #[packable(verify_with = verify_protocol_version)] protocol_version: u8, /// The identifier of the network to which this block belongs. + #[packable(verify_with = verify_network_id)] network_id: u64, /// The time at which the block was issued. It is a Unix timestamp in nanoseconds. issuing_time: u64, @@ -111,60 +115,29 @@ impl BlockHeader { impl WorkScore for BlockHeader {} -impl Packable for BlockHeader { - type UnpackError = Error; - type UnpackVisitor = ProtocolParameters; - - fn pack(&self, packer: &mut P) -> Result<(), P::Error> { - self.protocol_version.pack(packer)?; - self.network_id.pack(packer)?; - self.issuing_time.pack(packer)?; - self.slot_commitment_id.pack(packer)?; - self.latest_finalized_slot.pack(packer)?; - self.issuer_id.pack(packer)?; - - Ok(()) +fn verify_protocol_version( + protocol_version: &u8, + params: &ProtocolParameters, +) -> Result<(), Error> { + if VERIFY && *protocol_version != params.version() { + return Err(Error::ProtocolVersionMismatch { + expected: params.version(), + actual: *protocol_version, + }); } - fn unpack( - unpacker: &mut U, - protocol_params: &Self::UnpackVisitor, - ) -> Result> { - let protocol_version = u8::unpack::<_, VERIFY>(unpacker, &()).coerce()?; - - if VERIFY && protocol_version != protocol_params.version() { - return Err(UnpackError::Packable(Error::ProtocolVersionMismatch { - expected: protocol_params.version(), - actual: protocol_version, - })); - } - - let network_id = u64::unpack::<_, VERIFY>(unpacker, &()).coerce()?; - - if VERIFY && network_id != protocol_params.network_id() { - return Err(UnpackError::Packable(Error::NetworkIdMismatch { - expected: protocol_params.network_id(), - actual: network_id, - })); - } - - let issuing_time = u64::unpack::<_, VERIFY>(unpacker, &()).coerce()?; - - let slot_commitment_id = SlotCommitmentId::unpack::<_, VERIFY>(unpacker, &()).coerce()?; - - let latest_finalized_slot = SlotIndex::unpack::<_, VERIFY>(unpacker, &()).coerce()?; - - let issuer_id = AccountId::unpack::<_, VERIFY>(unpacker, &()).coerce()?; + Ok(()) +} - Ok(Self { - protocol_version, - network_id, - issuing_time, - slot_commitment_id, - latest_finalized_slot, - issuer_id, - }) +fn verify_network_id(network_id: &u64, params: &ProtocolParameters) -> Result<(), Error> { + if VERIFY && *network_id != params.network_id() { + return Err(Error::NetworkIdMismatch { + expected: params.network_id(), + actual: *network_id, + }); } + + Ok(()) } /// Represent the object that nodes gossip around the network.