Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Two more Packable derive #1730

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 25 additions & 52 deletions sdk/src/types/block/core/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -111,60 +115,29 @@ impl BlockHeader {

impl WorkScore for BlockHeader {}

impl Packable for BlockHeader {
type UnpackError = Error;
type UnpackVisitor = ProtocolParameters;

fn pack<P: Packer>(&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<const VERIFY: bool>(
protocol_version: &u8,
params: &ProtocolParameters,
) -> Result<(), Error> {
if VERIFY && *protocol_version != params.version() {
Alex6323 marked this conversation as resolved.
Show resolved Hide resolved
return Err(Error::ProtocolVersionMismatch {
expected: params.version(),
actual: *protocol_version,
});
}

fn unpack<U: Unpacker, const VERIFY: bool>(
unpacker: &mut U,
protocol_params: &Self::UnpackVisitor,
) -> Result<Self, UnpackError<Self::UnpackError, U::Error>> {
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<const VERIFY: bool>(network_id: &u64, params: &ProtocolParameters) -> Result<(), Error> {
if VERIFY && *network_id != params.network_id() {
Alex6323 marked this conversation as resolved.
Show resolved Hide resolved
return Err(Error::NetworkIdMismatch {
expected: params.network_id(),
actual: *network_id,
});
}

Ok(())
}

/// Represent the object that nodes gossip around the network.
Expand Down
46 changes: 12 additions & 34 deletions sdk/src/types/block/payload/signed_transaction/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand All @@ -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,
Expand All @@ -32,9 +34,11 @@ impl SignedTransactionPayload {

/// Creates a new [`SignedTransactionPayload`].
pub fn new(transaction: Transaction, unlocks: Unlocks) -> Result<Self, Error> {
verify_transaction_unlocks(&transaction, &unlocks)?;
let payload = Self { transaction, unlocks };

Ok(Self { transaction, unlocks })
verify_signed_transaction_payload::<true>(&payload)?;

Ok(payload)
}

/// Returns the transaction of a [`SignedTransactionPayload`].
Expand All @@ -57,37 +61,11 @@ impl WorkScore for SignedTransactionPayload {
}
}

impl Packable for SignedTransactionPayload {
type UnpackError = Error;
type UnpackVisitor = ProtocolParameters;

fn pack<P: Packer>(&self, packer: &mut P) -> Result<(), P::Error> {
self.transaction.pack(packer)?;
self.unlocks.pack(packer)?;

Ok(())
}

fn unpack<U: Unpacker, const VERIFY: bool>(
unpacker: &mut U,
visitor: &Self::UnpackVisitor,
) -> Result<Self, UnpackError<Self::UnpackError, U::Error>> {
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<const VERIFY: bool>(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(),
});
}

Expand Down
Loading