Skip to content

Commit

Permalink
rusk: refactored deploy execution as method
Browse files Browse the repository at this point in the history
  • Loading branch information
miloszm committed Jul 19, 2024
1 parent 486f281 commit bbb8670
Showing 1 changed file with 54 additions and 41 deletions.
95 changes: 54 additions & 41 deletions rusk/src/lib/chain/rusk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use dusk_consensus::operations::{
CallParams, VerificationOutput, VoterWithCredits,
};
use execution_core::bytecode::Bytecode;
use execution_core::transfer::ContractDeploy;
use execution_core::{
stake::StakeData, transfer::Transaction as PhoenixTransaction, BlsScalar,
StakePublicKey,
Expand Down Expand Up @@ -505,6 +506,51 @@ fn bytecode_charge(
* gas_per_deploy_byte.unwrap_or(DEFAULT_GAS_PER_DEPLOY_BYTE)
}

// Contract deployment will fail and charge full gas limit in the
// following cases:
// 1) Transaction gas limit is smaller than deploy charge plus gas used for
// spending funds.
// 2) Transaction's bytecode's bytes are not consistent with bytecode's hash.
// 3) Deployment fails for deploy-specific reasons like e.g.:
// - contract already deployed
// - corrupted bytecode
// - sufficient gas to spend funds yet insufficient for deployment
// Note that deployment transaction will never be re-executed for reasons
// related to deployment, as it is either discarded or it requires full
// gas limit to be charged. It might be re-executed only if some other
// transaction failed to fit the block.
fn contract_deploy(
session: &mut Session,
deploy: &ContractDeploy,
gas_limit: u64,
gas_per_deploy_byte: Option<u64>,
receipt: &mut CallReceipt<Result<Vec<u8>, ContractError>>,
) {
let deploy_charge = bytecode_charge(&deploy.bytecode, &gas_per_deploy_byte);
let min_gas_limit = receipt.gas_spent + deploy_charge;
let hash = blake3::hash(deploy.bytecode.bytes.as_slice());
if gas_limit < min_gas_limit {
receipt.data = Err(OutOfGas);
} else if hash != deploy.bytecode.hash {
receipt.data = Err(Panic("failed bytecode hash check".into()))
} else {
let result = session.deploy_raw(
None,
deploy.bytecode.bytes.as_slice(),
deploy.constructor_args.clone(),
deploy.owner.clone(),
gas_limit - receipt.gas_spent,
);
match result {
Ok(_) => receipt.gas_spent += deploy_charge,
Err(err) => {
info!("Tx caused deployment error {err:?}");
receipt.data = Err(Panic("failed deployment".into()))
}
}
}
}

/// Executes a transaction, returning the receipt of the call and the gas spent.
/// The following steps are performed:
///
Expand Down Expand Up @@ -543,49 +589,16 @@ fn execute(
tx.payload().fee.gas_limit,
)?;

// Deploy if this is a deployment transaction.
// Deployment transaction will fail and charge full gas limit in the
// following cases:
// 1) Transaction gas limit is smaller than deploy charge plus gas used for
// spending funds.
// 2) Transaction's bytecode's bytes are not consistent with bytecode's
// hash.
// 3) Deployment fails for deploy-specific reasons like e.g.:
// - contract already deployed
// - corrupted bytecode
// - sufficient gas to spend funds yet insufficient for deployment
// Note that deployment transaction will never be re-executed for reasons
// related to deployment, as it is either discarded or it requires full
// gas limit to be charged. It might be re-executed only if some other
// transaction failed to fit the block.
// Deploy if this is a deployment transaction and spend part is successful.
if let Some(deploy) = tx.payload().contract_deploy() {
if receipt.data.is_ok() {
let deploy_charge =
bytecode_charge(&deploy.bytecode, &gas_per_deploy_byte);
let min_gas_limit = receipt.gas_spent + deploy_charge;
let hash = blake3::hash(deploy.bytecode.bytes.as_slice());
if tx.payload().fee.gas_limit < min_gas_limit {
receipt.data = Err(OutOfGas);
} else if hash != deploy.bytecode.hash {
receipt.data = Err(Panic("failed bytecode hash check".into()))
} else {
let result = session.deploy_raw(
None,
deploy.bytecode.bytes.as_slice(),
deploy.constructor_args.clone(),
deploy.owner.clone(),
tx.payload().fee.gas_limit - receipt.gas_spent,
);
match result {
Ok(_) => {
receipt.gas_spent += deploy_charge;
}
Err(err) => {
info!("Tx caused deployment error {err:?}");
receipt.data = Err(Panic("failed deployment".into()))
}
}
}
contract_deploy(
session,
deploy,
tx.payload().fee.gas_limit,
gas_per_deploy_byte,
&mut receipt,
);
}
};

Expand Down

0 comments on commit bbb8670

Please sign in to comment.