Skip to content

Commit

Permalink
execution-core: bytecode as hash and bytes
Browse files Browse the repository at this point in the history
execution-core: added must_use
  • Loading branch information
miloszm committed Jul 9, 2024
1 parent 44ee87d commit 2b43cf9
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 11 deletions.
59 changes: 59 additions & 0 deletions execution-core/src/bytecode.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) DUSK NETWORK. All rights reserved.

//! Wrapper for a long data that we want to keep the integrity of.
extern crate alloc;
use alloc::vec::Vec;
use bytecheck::CheckBytes;
use dusk_bytes::Error as BytesError;
use dusk_bytes::Error::InvalidData;
use rkyv::{Archive, Deserialize, Serialize};

#[derive(Debug, Clone, PartialEq, Eq, Archive, Serialize, Deserialize)]
#[archive_attr(derive(CheckBytes))]
/// Holds bytes of bytecode and its hash.
pub struct Bytecode {
/// Hash of the bytecode bytes.
pub hash: [u8; 32],
/// Bytecode bytes.
pub bytes: Vec<u8>,
}

impl Bytecode {
/// Provides contribution bytes for an external hash.
#[must_use]
pub fn to_hash_input_bytes(&self) -> Vec<u8> {
self.hash.to_vec()
}

/// Serializes this object into a variable length buffer
#[must_use]
pub fn to_var_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new();
bytes.extend(self.hash);
bytes
}

/// Deserialize from a bytes buffer.
///
/// # Errors
/// Errors when the bytes are not available.
pub fn from_buf(buf: &[u8]) -> Result<(Self, usize), BytesError> {
if buf.len() < 32 {
return Err(InvalidData);
}
let mut hash = [0u8; 32];
hash.copy_from_slice(&buf[..32]);
Ok((
Self {
hash,
bytes: Vec::new(),
},
32,
))
}
}
1 change: 1 addition & 0 deletions execution-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
/// Block height type alias
pub type BlockHeight = u64;

pub mod bytecode;
pub mod stake;
pub mod transfer;

Expand Down
10 changes: 4 additions & 6 deletions execution-core/src/transfer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ use crate::{
};

mod transaction;
use crate::bytecode::Bytecode;
pub use transaction::{Payload, Transaction};

/// Unique ID to identify a contract.
Expand Down Expand Up @@ -110,7 +111,7 @@ pub struct ContractDeploy {
/// The optional ID of the contract to be deployed.
pub contract_id: Option<ContractId>,
/// Bytecode of the contract to be deployed.
pub bytecode: Vec<u8>,
pub bytecode: Bytecode,
/// Owner of the contract to be deployed.
pub owner: Vec<u8>,
/// Constructor arguments of the deployed contract.
Expand Down Expand Up @@ -146,8 +147,7 @@ impl ContractDeploy {
None => bytes.push(0),
}

bytes.extend((self.bytecode.len() as u64).to_bytes());
bytes.extend(&self.bytecode);
bytes.extend(&self.bytecode.to_var_bytes());

bytes.extend((self.owner.len() as u64).to_bytes());
bytes.extend(&self.owner);
Expand Down Expand Up @@ -183,9 +183,7 @@ impl ContractDeploy {
};
let mut buf = &buf[offset..];

let bytecode_len = usize::try_from(u64::from_reader(&mut buf)?)
.map_err(|_| BytesError::InvalidData)?;
let bytecode = buf[..bytecode_len].into();
let (bytecode, bytecode_len) = Bytecode::from_buf(buf)?;
buf = &buf[bytecode_len..];

let owner_len = usize::try_from(u64::from_reader(&mut buf)?)
Expand Down
8 changes: 5 additions & 3 deletions execution-core/src/transfer/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ impl Payload {
if let Some(contract_id) = &deploy.contract_id {
bytes.extend(contract_id);
}
bytes.extend(&deploy.bytecode);
bytes.extend(&deploy.bytecode.to_hash_input_bytes());
bytes.extend(&deploy.owner);
if let Some(constructor_args) = &deploy.constructor_args {
bytes.extend(constructor_args);
Expand All @@ -161,8 +161,10 @@ impl Payload {
#[derive(Debug, Clone, Archive, Serialize, Deserialize)]
#[archive_attr(derive(CheckBytes))]
pub struct Transaction {
payload: Payload,
proof: Vec<u8>,
/// Payload
pub payload: Payload,
/// Proof
pub proof: Vec<u8>,
}

impl PartialEq for Transaction {
Expand Down
25 changes: 23 additions & 2 deletions execution-core/tests/serialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use dusk_bls12_381::BlsScalar;
use dusk_bytes::{Error, Serializable};
use dusk_jubjub::JubJubScalar;
use execution_core::bytecode::Bytecode;
use execution_core::transfer::{
CallOrDeploy, ContractCall, ContractDeploy, Fee, Payload, Transaction,
};
Expand Down Expand Up @@ -95,13 +96,27 @@ fn transaction_serialization_call() -> Result<(), Error> {
Ok(())
}

fn strip_off_bytecode(tx: &Transaction) -> Transaction {
let mut tx_clone = tx.clone();
match &mut tx_clone.payload.call_or_deploy {
Some(CallOrDeploy::Deploy(deploy)) => {
deploy.bytecode.bytes.clear();
}
_ => (),
}
tx_clone
}

#[test]
fn transaction_serialization_deploy() -> Result<(), Error> {
let (tx_skeleton, fee, _) = build_skeleton_fee_deposit();

// build the contract-deploy
let contract = [42; 32];
let bytecode = vec![1, 2, 3, 4, 5];
let bytecode = Bytecode {
hash: [1u8; 32],
bytes: vec![1, 2, 3, 4, 5],
};
let owner = [1; 32];
let constructor_args = vec![5];
let deploy = ContractDeploy {
Expand All @@ -121,8 +136,14 @@ fn transaction_serialization_deploy() -> Result<(), Error> {
// set a random proof
let proof = [42; 42].to_vec();

let transaction = Transaction::new(payload, proof);
// bytecode not stripped off
let transaction = Transaction::new(payload.clone(), proof.clone());
let transaction_bytes = transaction.to_var_bytes();
let deserialized = Transaction::from_slice(&transaction_bytes)?;
assert_eq!(transaction, deserialized);

// bytecode stripped off
let transaction = strip_off_bytecode(&Transaction::new(payload, proof));
let transaction_bytes = transaction.to_var_bytes();
let deserialized = Transaction::from_slice(&transaction_bytes)?;
assert_eq!(transaction, deserialized);
Expand Down

0 comments on commit 2b43cf9

Please sign in to comment.