Skip to content

Commit

Permalink
Merge branch 'feat-2.0' into remove-0-9-0-chainspec
Browse files Browse the repository at this point in the history
  • Loading branch information
EdHastingsCasperAssociation authored Dec 20, 2024
2 parents d5a9744 + 10feaad commit e32e798
Show file tree
Hide file tree
Showing 76 changed files with 2,309 additions and 2,929 deletions.
1,198 changes: 174 additions & 1,024 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ lint-smart-contracts:

.PHONY: audit-rs
audit-rs:
$(CARGO) audit --ignore RUSTSEC-2024-0344 --ignore RUSTSEC-2024-0367 --ignore RUSTSEC-2024-0371 --ignore RUSTSEC-2024-0421
$(CARGO) audit

.PHONY: audit-as
audit-as:
Expand Down
72 changes: 67 additions & 5 deletions binary_port/src/error_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,9 +268,9 @@ pub enum ErrorCode {
/// Entry point cannot be 'call'
#[error("entry point cannot be 'call'")]
InvalidTransactionEntryPointCannotBeCall = 83,
/// Invalid transaction kind
#[error("invalid transaction kind")]
InvalidTransactionInvalidTransactionKind = 84,
/// Invalid transaction lane
#[error("invalid transaction lane")]
InvalidTransactionInvalidTransactionLane = 84,
/// Gas price tolerance too low
#[error("gas price tolerance too low")]
GasPriceToleranceTooLow = 85,
Expand Down Expand Up @@ -307,6 +307,36 @@ pub enum ErrorCode {
/// Malformed binary request
#[error("malformed binary request")]
MalformedBinaryRequest = 96,
/// No matching lane for transaction
#[error("couldn't associate a transaction lane with the transaction")]
InvalidTransactionNoWasmLaneMatches = 97,
/// Entry point must be 'call'
#[error("entry point must be 'call'")]
InvalidTransactionEntryPointMustBeCall = 98,
/// One of the payloads field cannot be deserialized
#[error("One of the payloads field cannot be deserialized")]
InvalidTransactionCannotDeserializeField = 99,
/// Can't calculate hash of the payload fields
#[error("Can't calculate hash of the payload fields")]
InvalidTransactionCannotCalculateFieldsHash = 100,
/// Unexpected fields in payload
#[error("Unexpected fields in payload")]
InvalidTransactionUnexpectedFields = 101,
/// Expected bytes arguments
#[error("expected bytes arguments")]
InvalidTransactionExpectedBytesArguments = 102,
/// Missing seed field in transaction
#[error("Missing seed field in transaction")]
InvalidTransactionMissingSeed = 103,
/// Pricing mode not supported
#[error("Pricing mode not supported")]
PricingModeNotSupported = 104,
/// Gas limit not supported
#[error("Gas limit not supported")]
InvalidDeployGasLimitNotSupported = 105,
/// Invalid runtime for Transaction::Deploy
#[error("Invalid runtime for Transaction::Deploy")]
InvalidDeployInvalidRuntime = 106,
}

impl TryFrom<u16> for ErrorCode {
Expand Down Expand Up @@ -398,7 +428,7 @@ impl TryFrom<u16> for ErrorCode {
81 => Ok(ErrorCode::DeployMissingTransferTarget),
82 => Ok(ErrorCode::DeployMissingModuleBytes),
83 => Ok(ErrorCode::InvalidTransactionEntryPointCannotBeCall),
84 => Ok(ErrorCode::InvalidTransactionInvalidTransactionKind),
84 => Ok(ErrorCode::InvalidTransactionInvalidTransactionLane),
85 => Ok(ErrorCode::GasPriceToleranceTooLow),
86 => Ok(ErrorCode::ReceivedV1Transaction),
87 => Ok(ErrorCode::PurseNotFound),
Expand All @@ -411,6 +441,16 @@ impl TryFrom<u16> for ErrorCode {
94 => Ok(ErrorCode::MalformedProtocolVersion),
95 => Ok(ErrorCode::MalformedBinaryRequestHeader),
96 => Ok(ErrorCode::MalformedBinaryRequest),
97 => Ok(ErrorCode::InvalidTransactionNoWasmLaneMatches),
98 => Ok(ErrorCode::InvalidTransactionEntryPointMustBeCall),
99 => Ok(ErrorCode::InvalidTransactionCannotDeserializeField),
100 => Ok(ErrorCode::InvalidTransactionCannotCalculateFieldsHash),
101 => Ok(ErrorCode::InvalidTransactionUnexpectedFields),
102 => Ok(ErrorCode::InvalidTransactionExpectedBytesArguments),
103 => Ok(ErrorCode::InvalidTransactionMissingSeed),
104 => Ok(ErrorCode::PricingModeNotSupported),
105 => Ok(ErrorCode::InvalidDeployGasLimitNotSupported),
106 => Ok(ErrorCode::InvalidDeployInvalidRuntime),
_ => Err(UnknownErrorCode),
}
}
Expand Down Expand Up @@ -482,6 +522,8 @@ impl From<InvalidDeploy> for ErrorCode {
ErrorCode::InvalidDeployUnableToCalculateGasCost
}
InvalidDeploy::GasPriceToleranceTooLow { .. } => ErrorCode::GasPriceToleranceTooLow,
InvalidDeploy::GasLimitNotSupported => ErrorCode::InvalidDeployGasLimitNotSupported,
InvalidDeploy::InvalidRuntime => ErrorCode::InvalidDeployInvalidRuntime,
_ => ErrorCode::InvalidDeployUnspecified,
}
}
Expand Down Expand Up @@ -544,7 +586,7 @@ impl From<InvalidTransactionV1> for ErrorCode {
ErrorCode::InvalidTransactionEntryPointCannotBeCall
}
InvalidTransactionV1::InvalidTransactionLane(_) => {
ErrorCode::InvalidTransactionInvalidTransactionKind
ErrorCode::InvalidTransactionInvalidTransactionLane
}
InvalidTransactionV1::GasPriceToleranceTooLow { .. } => {
ErrorCode::GasPriceToleranceTooLow
Expand All @@ -553,6 +595,26 @@ impl From<InvalidTransactionV1> for ErrorCode {
InvalidTransactionV1::InvalidTransactionRuntime { .. } => {
ErrorCode::InvalidTransactionRuntime
}
InvalidTransactionV1::NoWasmLaneMatchesTransaction() => {
ErrorCode::InvalidTransactionNoWasmLaneMatches
}
InvalidTransactionV1::EntryPointMustBeCall { .. } => {
ErrorCode::InvalidTransactionEntryPointMustBeCall
}
InvalidTransactionV1::CouldNotDeserializeField { .. } => {
ErrorCode::InvalidTransactionCannotDeserializeField
}
InvalidTransactionV1::CannotCalculateFieldsHash => {
ErrorCode::InvalidTransactionCannotCalculateFieldsHash
}
InvalidTransactionV1::UnexpectedTransactionFieldEntries => {
ErrorCode::InvalidTransactionUnexpectedFields
}
InvalidTransactionV1::ExpectedBytesArguments => {
ErrorCode::InvalidTransactionExpectedBytesArguments
}
InvalidTransactionV1::MissingSeed => ErrorCode::InvalidTransactionMissingSeed,
InvalidTransactionV1::PricingModeNotSupported => ErrorCode::PricingModeNotSupported,
_other => ErrorCode::InvalidTransactionUnspecified,
}
}
Expand Down
2 changes: 1 addition & 1 deletion execution_engine/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ wat = "1.220.0"
[dev-dependencies]
assert_matches = "1.3.0"
casper-types = { path = "../types", features = ["datasize", "json-schema", "testing", "std"] }
criterion = "0.3.5"
criterion = "0.5.1"
proptest = "1.0.0"
tempfile = "3.4.0"
walrus = "0.20.2"
Expand Down
33 changes: 23 additions & 10 deletions execution_engine/src/bin/run_wasm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,17 @@ struct RunWasmInfo {

fn run_wasm(
module_bytes: Vec<u8>,
cli_args: &Args,
chainspec: &ChainspecConfig,
func_name: &str,
args: &[String],
) -> (
Result<Option<RuntimeValue>, casper_wasmi::Error>,
RunWasmInfo,
) {
println!("Invoke export {:?} with args {:?}", func_name, args);
println!(
"Invoke export {:?} with args {:?}",
func_name, cli_args.args
);

let instance = prepare_instance(&module_bytes, chainspec);

Expand All @@ -51,9 +54,13 @@ fn run_wasm(
};

let args = {
assert_eq!(args.len(), params.len(), "Not enough arguments supplied");
assert_eq!(
cli_args.args.len(),
params.len(),
"Not enough arguments supplied"
);
let mut vec = Vec::new();
for (input_arg, func_arg) in args.iter().zip(params.into_iter()) {
for (input_arg, func_arg) in cli_args.args.iter().zip(params.into_iter()) {
let value = match func_arg {
casper_wasmi::ValueType::I32 => {
casper_wasmi::RuntimeValue::I32(input_arg.parse().unwrap())
Expand All @@ -71,7 +78,11 @@ fn run_wasm(

let start = Instant::now();

let mut externals = MinimalWasmiExternals::new(0, chainspec.transaction_config.block_gas_limit);
let gas_limit = cli_args
.gas_limit
.unwrap_or(chainspec.transaction_config.block_gas_limit);

let mut externals = MinimalWasmiExternals::new(0, gas_limit);
let result: Result<Option<RuntimeValue>, casper_wasmi::Error> =
instance
.clone()
Expand All @@ -87,11 +98,13 @@ fn run_wasm(
use clap::Parser;
use serde::Deserialize;

#[derive(Parser, Debug)]
#[derive(Parser, Clone, Debug)]
#[command(author, version, about, long_about = None)]
struct Args {
#[arg(value_name = "MODULE")]
wasm_file: PathBuf,
#[arg(long = "gas_limit")]
gas_limit: Option<u64>,
#[arg(long = "invoke", value_name = "FUNCTION")]
invoke: Option<String>,
/// Arguments given to the Wasm module or the invoked function.
Expand Down Expand Up @@ -130,16 +143,16 @@ struct ChainspecConfig {
fn main() {
let args = Args::parse();

let chainspec_file = args.chainspec_file.expect("chainspec file");
let chainspec_file = args.clone().chainspec_file.expect("chainspec file");
println!("Using chainspec file {:?}", chainspec_file.display());
let chainspec_data = fs::read_to_string(chainspec_file.as_path()).expect("valid file");
let chainspec_config: ChainspecConfig =
toml::from_str(&chainspec_data).expect("valid chainspec");

let wasm_bytes = load_wasm_file(args.wasm_file);
let wasm_bytes = load_wasm_file(&args.wasm_file);

if let Some(func_name) = args.invoke {
let (result, info) = run_wasm(wasm_bytes, &chainspec_config, &func_name, &args.args);
if let Some(ref func_name) = args.invoke {
let (result, info) = run_wasm(wasm_bytes, &args, &chainspec_config, func_name);

println!("result: {:?}", result);
println!("elapsed: {:?}", info.elapsed);
Expand Down
59 changes: 52 additions & 7 deletions execution_engine/src/runtime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use std::{

use casper_wasm::elements::Module;
use casper_wasmi::{MemoryRef, Trap, TrapCode};
use tracing::{debug, error};
use tracing::{debug, error, warn};

#[cfg(feature = "test-support")]
use casper_wasmi::RuntimeValue;
Expand Down Expand Up @@ -372,6 +372,15 @@ where
) -> Result<(), Trap> {
let name = self.string_from_mem(name_ptr, name_size)?;
let key = self.key_from_mem(key_ptr, key_size)?;

if let Some(payment_purse) = self.context.maybe_payment_purse() {
if Key::URef(payment_purse).normalize() == key.normalize() {
warn!("attempt to put_key payment purse");
return Err(Into::into(ExecError::Revert(ApiError::HandlePayment(
handle_payment::Error::AttemptToPersistPaymentPurse as u8,
))));
}
}
self.context.put_key(name, key).map_err(Into::into)
}

Expand Down Expand Up @@ -920,13 +929,17 @@ where
let handle_payment_costs = system_config.handle_payment_costs();

let result = match entry_point_name {
handle_payment::METHOD_GET_PAYMENT_PURSE => (|| {
handle_payment::METHOD_GET_PAYMENT_PURSE => {
runtime.charge_system_contract_call(handle_payment_costs.get_payment_purse)?;

let rights_controlled_purse =
runtime.get_payment_purse().map_err(Self::reverter)?;
CLValue::from_t(rights_controlled_purse).map_err(Self::reverter)
})(),
match self.context.maybe_payment_purse() {
Some(payment_purse) => CLValue::from_t(payment_purse).map_err(Self::reverter),
None => {
let payment_purse = runtime.get_payment_purse().map_err(Self::reverter)?;
self.context.set_payment_purse(payment_purse);
CLValue::from_t(payment_purse).map_err(Self::reverter)
}
}
}
handle_payment::METHOD_SET_REFUND_PURSE => (|| {
runtime.charge_system_contract_call(handle_payment_costs.set_refund_purse)?;

Expand Down Expand Up @@ -2017,6 +2030,22 @@ where
return Ok(Err(err));
}
let args: RuntimeArgs = bytesrepr::deserialize_from_slice(args_bytes)?;

if let Some(payment_purse) = self.context.maybe_payment_purse() {
for named_arg in args.named_args() {
if utils::extract_urefs(named_arg.cl_value())?
.into_iter()
.any(|uref| uref.remove_access_rights() == payment_purse.remove_access_rights())
{
warn!("attempt to call_contract with payment purse");

return Err(Into::into(ExecError::Revert(ApiError::HandlePayment(
handle_payment::Error::AttemptToPersistPaymentPurse as u8,
))));
}
}
}

let result = self.call_contract(contract_hash, entry_point_name, args)?;
self.manage_call_contract_host_buffer(result_size_ptr, result)
}
Expand All @@ -2034,6 +2063,22 @@ where
return Ok(Err(err));
}
let args: RuntimeArgs = bytesrepr::deserialize_from_slice(args_bytes)?;

if let Some(payment_purse) = self.context.maybe_payment_purse() {
for named_arg in args.named_args() {
if utils::extract_urefs(named_arg.cl_value())?
.into_iter()
.any(|uref| uref.remove_access_rights() == payment_purse.remove_access_rights())
{
warn!("attempt to call_versioned_contract with payment purse");

return Err(Into::into(ExecError::Revert(ApiError::HandlePayment(
handle_payment::Error::AttemptToPersistPaymentPurse as u8,
))));
}
}
}

let result = self.call_versioned_contract(
contract_package_hash,
contract_version,
Expand Down
2 changes: 1 addition & 1 deletion execution_engine/src/runtime/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ pub(super) fn attenuate_uref_in_args(

/// Extracts a copy of every uref able to be deserialized from `cl_value`.
pub(super) fn extract_urefs(cl_value: &CLValue) -> Result<Vec<URef>, ExecError> {
let mut vec: Vec<URef> = Vec::new();
let mut vec: Vec<URef> = Default::default();
rewrite_urefs(cl_value.clone(), |uref| {
vec.push(*uref);
})?;
Expand Down
18 changes: 16 additions & 2 deletions execution_engine/src/runtime_context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ pub struct RuntimeContext<'a, R> {
account_hash: AccountHash,
emit_message_cost: U512,
allow_install_upgrade: AllowInstallUpgrade,
payment_purse: Option<URef>,
}

impl<'a, R> RuntimeContext<'a, R>
Expand Down Expand Up @@ -149,6 +150,7 @@ where
remaining_spending_limit,
emit_message_cost,
allow_install_upgrade,
payment_purse: None,
}
}

Expand Down Expand Up @@ -180,6 +182,7 @@ where
let remaining_spending_limit = self.remaining_spending_limit();

let transfers = self.transfers.clone();
let payment_purse = self.payment_purse;

RuntimeContext {
tracking_copy,
Expand All @@ -203,6 +206,7 @@ where
remaining_spending_limit,
emit_message_cost: self.emit_message_cost,
allow_install_upgrade: self.allow_install_upgrade,
payment_purse,
}
}

Expand Down Expand Up @@ -231,6 +235,16 @@ where
self.named_keys.contains(name)
}

/// Returns the payment purse, if set.
pub fn maybe_payment_purse(&self) -> Option<URef> {
self.payment_purse
}

/// Sets the payment purse to the imputed uref.
pub fn set_payment_purse(&mut self, uref: URef) {
self.payment_purse = Some(uref);
}

/// Returns an instance of the engine config.
pub fn engine_config(&self) -> &EngineConfig {
&self.engine_config
Expand Down Expand Up @@ -742,7 +756,7 @@ where
| StoredValue::Contract(_)
| StoredValue::AddressableEntity(_)
| StoredValue::SmartContract(_)
| StoredValue::LegacyTransfer(_)
| StoredValue::Transfer(_)
| StoredValue::DeployInfo(_)
| StoredValue::EraInfo(_)
| StoredValue::Bid(_)
Expand All @@ -753,7 +767,7 @@ where
| StoredValue::ContractWasm(_)
| StoredValue::MessageTopic(_)
| StoredValue::Message(_)
| StoredValue::Prepaid(_)
| StoredValue::Prepayment(_)
| StoredValue::EntryPoint(_)
| StoredValue::RawBytes(_) => Ok(()),
}
Expand Down
Loading

0 comments on commit e32e798

Please sign in to comment.