Skip to content
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
6 changes: 4 additions & 2 deletions executor/wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -318,8 +318,6 @@ impl ExecutorV2 {
execution_stack,
} = execute_request;

let (entity_addr, source_purse) = get_purse_for_entity(&mut tracking_copy, caller_key)?;

let (wasm_bytes, export_name) = {
if let ExecutionKind::SessionBytes(wasm_bytes) = &execution_kind {
(wasm_bytes.clone(), DEFAULT_WASM_ENTRY_POINT)
Expand Down Expand Up @@ -472,6 +470,8 @@ impl ExecutorV2 {
.take_bytes();

if transferred_value != 0 {
let (entity_addr, source_purse) =
get_purse_for_entity(&mut tracking_copy, caller_key)?;
// TODO: consult w/ Michal re: charge timing
let gas_usage = GasUsage::new_from_limit(gas_limit);

Expand Down Expand Up @@ -551,6 +551,8 @@ impl ExecutorV2 {
})? {
Some(StoredValue::ByteCode(bytecode)) => {
if transferred_value != 0 {
let (entity_addr, source_purse) =
get_purse_for_entity(&mut tracking_copy, caller_key)?;
// TODO: consult w/ Michal re: charge timing
let gas_usage = GasUsage::new_from_limit(gas_limit);

Expand Down
74 changes: 73 additions & 1 deletion executor/wasm/tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1722,7 +1722,9 @@ fn escrow() {
}

#[test]
fn should_not_fail_without_account() {
fn should_fail_without_account() {
// When transferred value is provided we fetch the underlying account, if global state doesn't
// hold it the execution should fail
let chainspec_config = ChainspecConfig::from_chainspec_path(&*CHAINSPEC_SYMLINK)
.expect("must get chainspec config");
let executor = make_executor(&chainspec_config);
Expand All @@ -1749,6 +1751,7 @@ fn should_not_fail_without_account() {
.with_state_hash(Digest::from_raw([0; 32]))
.with_block_height(1)
.with_parent_block_hash(BlockHash::new(Digest::from_raw([0; 32])))
.with_transferred_value(1555)
.build()
.expect("should build");

Expand Down Expand Up @@ -2414,6 +2417,75 @@ fn calling_session_should_produce_entry_point_called_and_ret() {
assert_eq!(ep_calls_and_rets, vec![call, session_return]);
}

#[test]
fn calling_session_should_not_perform_an_install() {
let chainspec_config = ChainspecConfig::from_chainspec_path(&*CHAINSPEC_SYMLINK)
.expect("must get chainspec config");

let mut executor = make_executor(&chainspec_config);
let (global_state, mut state_root_hash, _tempdir) = make_global_state_with_genesis();
let address_generator = make_address_generator();

let vm2_returner = read_wasm("vm2_returner.wasm");

let install_request = base_install_request_builder(&chainspec_config)
.with_wasm_bytes(vm2_returner.wasm)
.with_bundle_data(vm2_returner.meta.expect("should have bundle"))
.with_shared_address_generator(Arc::clone(&address_generator))
.with_transferred_value(0)
.with_entry_point("new".to_string())
.build()
.expect("should build");

let create_result = run_create_contract(
&mut executor,
&global_state,
state_root_hash,
install_request,
);
state_root_hash = global_state
.commit_effects(state_root_hash, create_result.effects().clone())
.expect("Should commit");
let vm2_returner_caller = read_wasm("vm2_returner_caller.wasm");
let input: Bytes = create_result
.smart_contract_addr()
.to_bytes()
.unwrap()
.into();
let execute_request = base_execute_builder(&chainspec_config)
.with_state_hash(state_root_hash)
.with_initiator(*DEFAULT_ACCOUNT_HASH)
.with_caller_key(Key::Account(*DEFAULT_ACCOUNT_HASH))
.with_gas_limit(DEFAULT_GAS_LIMIT)
.with_transaction_hash(TRANSACTION_HASH)
.with_execution_kind(ExecutionKind::SessionBytes(vm2_returner_caller.wasm))
.with_transferred_value(0)
.with_shared_address_generator(Arc::clone(&address_generator))
.with_block_height(1)
.with_parent_block_hash(BlockHash::new(Digest::from_raw([0; 32])))
.with_runtime_native_config(make_runtime_config(&chainspec_config))
.with_input(input)
.build()
.expect("should build");
let result = expect_successful_execution(
&mut executor,
&global_state,
state_root_hash,
execute_request,
);

let transforms = result.effects().transforms();
assert!(!transforms.iter().any(|transform: &TransformV2| {
matches!(
transform.kind(),
TransformKindV2::Write(StoredValue::ContractPackage(_))
) || matches!(
transform.kind(),
TransformKindV2::Write(StoredValue::SmartContract(_))
)
}));
}

fn get_contract_package_and_wasms(
state_hash: Digest,
global_state: &LmdbGlobalState,
Expand Down
38 changes: 24 additions & 14 deletions node/src/components/contract_runtime/operations/wasm_v2_request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,8 @@ pub(crate) enum InvalidRequest {
ExpectedTransferredValue,
#[error("Expected V2 runtime")]
ExpectedV2Runtime,
#[error("Invalida input")]
InvalidaInput,
}

impl WasmV2Request {
Expand Down Expand Up @@ -272,20 +274,28 @@ impl WasmV2Request {
seed,
bundle_data,
},
is_install_upgrade: _, // TODO: Handle this
} => match entry_point {
TransactionEntryPoint::Call => Target::Session {
module_bytes: module_bytes.clone().take_inner().into(),
},
TransactionEntryPoint::Custom(entry_point) => Target::Install {
module_bytes: module_bytes.clone().take_inner().into(),
entry_point: entry_point.to_string(),
transferred_value,
seed,
bundle_data: bundle_data.map(|bytes| bytes.take_inner().into()),
},
_ => todo!(),
},
is_install_upgrade,
} => {
if is_install_upgrade {
let entry_point_name = match entry_point {
TransactionEntryPoint::Custom(entry_point) => entry_point,
// For vm2 session install/upgrade we expect a constructor name
// to be specified verbatim in the TransactionEntryPoint::Custom variant
_ => return Err(InvalidRequest::InvalidaInput),
};
Target::Install {
module_bytes: module_bytes.clone().take_inner().into(),
entry_point: entry_point_name,
transferred_value,
seed,
bundle_data: bundle_data.map(|bytes| bytes.take_inner().into()),
}
} else {
Target::Session {
module_bytes: module_bytes.clone().take_inner().into(),
}
}
}
};

info!(%transaction_hash, "executing v1 contract");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ pub mod exports {
#[casper(export)]
pub fn call(address: Address) {
let _ = casper::print(&format!("trying to call address {:?}", address));

casper::casper_call(&address, 0, "do_return", &[])
.1
.unwrap();
Expand Down
3 changes: 2 additions & 1 deletion smart_contracts/vm2/sdk/src/casper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,8 @@ pub(crate) fn call_result_from_code(result_code: u32) -> Result<(), CallError> {
if result_code == HOST_ERROR_SUCCESS {
Ok(())
} else {
Err(CallError::try_from(result_code).expect("Unexpected error code"))
Err(CallError::try_from(result_code)
.unwrap_or_else(|_| panic!("Unexpected error code: {}", result_code)))
}
}

Expand Down
5 changes: 5 additions & 0 deletions smart_contracts/vm2/sdk/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ impl TryFrom<u32> for CallError {
type Error = ();

fn try_from(value: u32) -> Result<Self, Self::Error> {
#[allow(unreachable_patterns)]
match value {
CALLEE_ROLLED_BACK => Ok(Self::CalleeRolledBack),
CALLEE_TRAPPED => Ok(Self::CalleeTrapped),
Expand All @@ -235,6 +236,10 @@ impl TryFrom<u32> for CallError {
CALLEE_ENTITY_NOT_FOUND => Ok(Self::EntityNotFound),
CALLEE_LOCKED_PACKAGE => Ok(Self::LockedPackage),
CALLEE_REVERT_ERROR => Ok(Self::CalleeReverted),
CALLEE_NO_ACTIVE_CONTRACT => Ok(Self::NoActiveContract),
CALLEE_CODE_NOT_FOUND => Ok(Self::CodeNotFound),
CALLEE_ENTITY_NOT_FOUND => Ok(Self::EntityNotFound),
CALLEE_LOCKED_PACKAGE => Ok(Self::LockedPackage),
_ => Err(()),
}
}
Expand Down