diff --git a/rusk/src/lib/chain/rusk.rs b/rusk/src/lib/chain/rusk.rs index fbb797e809..dd4f801057 100644 --- a/rusk/src/lib/chain/rusk.rs +++ b/rusk/src/lib/chain/rusk.rs @@ -18,6 +18,7 @@ use dusk_bytes::{DeserializableSlice, Serializable}; use dusk_consensus::operations::{ CallParams, VerificationOutput, VoterWithCredits, }; +use execution_core::transfer::CallOrDeploy; use execution_core::{ stake::StakeData, transfer::Transaction as PhoenixTransaction, BlsScalar, StakePublicKey, @@ -480,6 +481,17 @@ fn accept( )) } +fn strip_off_bytecode(tx: &PhoenixTransaction) -> Option { + let _ = tx.payload().contract_deploy()?; + let mut tx_clone = tx.clone(); + if let Some(CallOrDeploy::Deploy(deploy)) = + &mut tx_clone.payload.call_or_deploy + { + deploy.bytecode.bytes.clear(); + } + Some(tx_clone) +} + /// Executes a transaction, returning the receipt of the call and the gas spent. /// The following steps are performed: /// @@ -495,12 +507,13 @@ fn execute( session: &mut Session, tx: &PhoenixTransaction, ) -> Result, ContractError>>, PiecrustError> { + let tx_stripped = strip_off_bytecode(tx); // Spend the inputs and execute the call. If this errors the transaction is // unspendable. let mut receipt = session.call::<_, Result, ContractError>>( TRANSFER_CONTRACT, "spend_and_execute", - tx, + tx_stripped.as_ref().unwrap_or(tx), tx.payload().fee.gas_limit, )?; @@ -512,7 +525,7 @@ fn execute( if let Some(deploy) = tx.payload().contract_deploy() { session.deploy_raw( deploy.contract_id.map(|id| id.into()), - deploy.bytecode.as_slice(), + deploy.bytecode.bytes.as_slice(), deploy.constructor_args.clone(), deploy.owner.clone(), tx.payload().fee.gas_limit, diff --git a/rusk/tests/services/contract_deployment.rs b/rusk/tests/services/contract_deployment.rs index 01e1ed9f74..bc1dae9a54 100644 --- a/rusk/tests/services/contract_deployment.rs +++ b/rusk/tests/services/contract_deployment.rs @@ -8,10 +8,12 @@ use std::collections::HashMap; use std::path::{Path, PathBuf}; use std::sync::{Arc, RwLock}; +use execution_core::bytecode::Bytecode; use execution_core::transfer::{CallOrDeploy, ContractDeploy}; use rand::prelude::*; use rand::rngs::StdRng; use rusk::{Result, Rusk}; +use rusk_abi::hash::Hasher; use rusk_abi::Error::ContractDoesNotExist; use rusk_abi::{ContractData, ContractId}; use rusk_recovery_tools::state; @@ -97,6 +99,12 @@ fn initial_state>(dir: P, deploy_bob: bool) -> Result { Ok(rusk) } +fn bytecode_hash(bytes: impl AsRef<[u8]>) -> [u8; 32] { + let mut hasher = Hasher::new(); + hasher.update(bytes.as_ref()); + hasher.finalize().to_bytes() +} + fn make_and_execute_transaction_deploy( rusk: &Rusk, wallet: &wallet::Wallet, @@ -125,7 +133,10 @@ fn make_and_execute_transaction_deploy( &mut rng, CallOrDeploy::Deploy(ContractDeploy { contract_id: Some(contract_id.to_bytes()), - bytecode: bytecode.as_ref().to_vec(), + bytecode: Bytecode { + hash: bytecode_hash(bytecode.as_ref()), + bytes: bytecode.as_ref().to_vec(), + }, owner: BOB_OWNER.to_vec(), constructor_args, }),