Skip to content

Commit 74c1a46

Browse files
Merge pull request #5349 from darthsiroftardis/error-codes-vm2
[VM2] Move variants from `ExecuteError` to `CallError`
2 parents d39e797 + dd4ed75 commit 74c1a46

File tree

15 files changed

+186
-62
lines changed

15 files changed

+186
-62
lines changed

binary_port/src/sandboxed_execution.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ pub enum SandboxedExecutionError {
2020
CodeNotFound,
2121
/// An internal host error occurred.
2222
InternalHostError,
23+
/// No active contract in a package.
24+
NoActiveContract,
25+
/// Entity not found
26+
EntityNotFound,
27+
/// Tried to upgrade a contract in a locked package.
28+
LockedPackage,
2329
/// Api error occurred.
2430
Api(String),
2531
/// Input invalid
@@ -35,6 +41,9 @@ impl core::fmt::Display for SandboxedExecutionError {
3541
SandboxedExecutionError::NotCallable => write!(f, "contract not callable"),
3642
SandboxedExecutionError::CodeNotFound => write!(f, "contract code not found"),
3743
SandboxedExecutionError::InternalHostError => write!(f, "internal host error"),
44+
SandboxedExecutionError::NoActiveContract => write!(f, "no active contract"),
45+
SandboxedExecutionError::EntityNotFound => write!(f, "entity not found"),
46+
SandboxedExecutionError::LockedPackage => write!(f, "locked package"),
3847
SandboxedExecutionError::Api(api_error) => write!(f, "{}", api_error),
3948
SandboxedExecutionError::InputInvalid => write!(f, "input invalid"),
4049
}

executor/wasm/src/lib.rs

Lines changed: 68 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -625,7 +625,14 @@ impl ExecutorV2 {
625625
"Couldn't find an active version for smart contract under path {:?}",
626626
[&vm1_key, &smart_contract_key]
627627
);
628-
return Err(ExecuteError::NoActiveContract(smart_contract_key));
628+
return Ok(ExecuteResult {
629+
host_error: Some(CallError::NoActiveContract),
630+
output: None,
631+
gas_usage: GasUsage::new(gas_limit, gas_limit),
632+
effects: tracking_copy.effects(),
633+
cache: tracking_copy.cache(),
634+
messages: tracking_copy.messages(),
635+
});
629636
};
630637
let entity_addr = EntityAddr::SmartContract(contract_hash.value());
631638
let latest_version_key = Key::AddressableEntity(entity_addr);
@@ -648,7 +655,14 @@ impl ExecutorV2 {
648655
"Couldn't find an active version for smart contract under path {:?}",
649656
[&vm1_key, &smart_contract_key]
650657
);
651-
return Err(ExecuteError::NoActiveContract(smart_contract_key));
658+
return Ok(ExecuteResult {
659+
host_error: Some(CallError::NoActiveContract),
660+
output: None,
661+
gas_usage: GasUsage::new(gas_limit, gas_limit),
662+
effects: tracking_copy.effects(),
663+
cache: tracking_copy.cache(),
664+
messages: tracking_copy.messages(),
665+
});
652666
};
653667
let latest_version_key = Key::Hash(contract_hash.value());
654668
tracking_copy
@@ -702,15 +716,27 @@ impl ExecutorV2 {
702716
// Note: Bytecode stored in the GlobalStateReader has a "kind" option -
703717
// currently we know we have a v2 bytecode as the stored contract is of "V2"
704718
// variant.
705-
let wasm_bytes = tracking_copy
706-
.read(&wasm_key)
707-
.map_err(|read_err| {
719+
let stored_value =
720+
match tracking_copy.read(&wasm_key).map_err(|read_err| {
708721
error!(
709722
"Error when fetching wasm_bytes {wasm_key}. Details {read_err}"
710723
);
711724
ExecuteError::Fatal(FatalHostError::TrackingCopy)
712-
})?
713-
.ok_or(ExecuteError::EntityNotFound(wasm_key))?
725+
})? {
726+
None => {
727+
return Ok(ExecuteResult {
728+
host_error: Some(CallError::CodeNotFound),
729+
output: None,
730+
gas_usage: GasUsage::new(gas_limit, gas_limit),
731+
effects: tracking_copy.effects(),
732+
cache: tracking_copy.cache(),
733+
messages: tracking_copy.messages(),
734+
});
735+
}
736+
Some(stored_value) => stored_value,
737+
};
738+
739+
let wasm_bytes = stored_value
714740
.into_byte_code()
715741
.ok_or({
716742
error!("Couldn't wasm stored value into ByteCode");
@@ -726,7 +752,14 @@ impl ExecutorV2 {
726752
match tracking_copy.runtime_footprint_by_entity_addr(entity_addr) {
727753
Ok(footprint) => footprint,
728754
Err(_) => {
729-
return Err(ExecuteError::EntityNotFound(caller_key));
755+
return Ok(ExecuteResult {
756+
host_error: Some(CallError::EntityNotFound),
757+
output: None,
758+
gas_usage: GasUsage::new(gas_limit, gas_limit),
759+
effects: tracking_copy.effects(),
760+
cache: tracking_copy.cache(),
761+
messages: tracking_copy.messages(),
762+
});
730763
}
731764
};
732765
match system::transfer(
@@ -799,7 +832,14 @@ impl ExecutorV2 {
799832
{
800833
Ok(footprint) => footprint,
801834
Err(_) => {
802-
return Err(ExecuteError::EntityNotFound(caller_key));
835+
return Ok(ExecuteResult {
836+
host_error: Some(CallError::CodeNotFound),
837+
output: None,
838+
gas_usage,
839+
effects: tracking_copy.effects(),
840+
cache: tracking_copy.cache(),
841+
messages: tracking_copy.messages(),
842+
});
803843
}
804844
};
805845

@@ -898,7 +938,14 @@ impl ExecutorV2 {
898938
?execution_kind,
899939
"No contract code found",
900940
);
901-
return Err(ExecuteError::CodeNotFound(*contract_package_addr));
941+
return Ok(ExecuteResult {
942+
host_error: Some(CallError::CodeNotFound),
943+
output: None,
944+
gas_usage: GasUsage::new(gas_limit, gas_limit),
945+
effects: tracking_copy.effects(),
946+
cache: tracking_copy.cache(),
947+
messages: tracking_copy.messages(),
948+
});
902949
}
903950
}
904951
} else {
@@ -1425,6 +1472,10 @@ impl Executor for ExecutorV2 {
14251472
CallError::CalleeTrapped(_) => SandboxedExecutionError::CalleeTrapped,
14261473
CallError::CalleeGasDepleted => SandboxedExecutionError::CalleeGasDepleted,
14271474
CallError::NotCallable => SandboxedExecutionError::NotCallable,
1475+
CallError::NoActiveContract => SandboxedExecutionError::NoActiveContract,
1476+
CallError::CodeNotFound => SandboxedExecutionError::CodeNotFound,
1477+
CallError::EntityNotFound => SandboxedExecutionError::EntityNotFound,
1478+
CallError::LockedPackage => SandboxedExecutionError::LockedPackage,
14281479
CallError::Api(api_error) => SandboxedExecutionError::Api(api_error),
14291480
CallError::InputInvalid => SandboxedExecutionError::InputInvalid,
14301481
}),
@@ -1443,7 +1494,7 @@ fn get_purse_for_entity<R: GlobalStateReader>(
14431494
let stored_value = tracking_copy
14441495
.read(&caller_key)
14451496
.map_err(|_error| ExecuteError::Fatal(FatalHostError::TrackingCopy))?
1446-
.ok_or(ExecuteError::EntityNotFound(caller_key))?;
1497+
.ok_or(ExecuteError::MainPurseNotFound(caller_key))?;
14471498
match stored_value {
14481499
StoredValue::CLValue(addressable_entity_key) => {
14491500
let key = addressable_entity_key.into_t::<Key>().map_err(|cl_error| {
@@ -1452,7 +1503,7 @@ fn get_purse_for_entity<R: GlobalStateReader>(
14521503
})?;
14531504
let hash = match key.into_entity_hash() {
14541505
Some(hash) => hash,
1455-
None => return Err(ExecuteError::EntityNotFound(key)),
1506+
None => return Err(ExecuteError::MainPurseNotFound(key)),
14561507
};
14571508
let stored_value = tracking_copy
14581509
.read(&key)
@@ -1483,7 +1534,7 @@ fn get_purse_for_entity<R: GlobalStateReader>(
14831534
contract_hash
14841535
} else {
14851536
debug!("Couldn't find an active version for smart contract {caller_key}");
1486-
return Err(ExecuteError::NoActiveContract(caller_key));
1537+
return Err(ExecuteError::MainPurseNotFound(caller_key));
14871538
};
14881539

14891540
let entity_addr = EntityAddr::SmartContract(contract_hash.value());
@@ -1495,7 +1546,7 @@ fn get_purse_for_entity<R: GlobalStateReader>(
14951546
ExecuteError::Fatal(FatalHostError::TrackingCopy)
14961547
})?;
14971548
let addressable_entity = stored_value
1498-
.ok_or(ExecuteError::EntityNotFound(latest_version_key))?
1549+
.ok_or(ExecuteError::MainPurseNotFound(latest_version_key))?
14991550
.into_addressable_entity()
15001551
.ok_or(ExecuteError::Fatal(FatalHostError::TypeConversion))?;
15011552

@@ -1504,13 +1555,13 @@ fn get_purse_for_entity<R: GlobalStateReader>(
15041555
StoredValue::ContractPackage(contract_package) => {
15051556
let contract_hash = match contract_package.enabled_versions().last_key_value() {
15061557
Some((_, contract_hash)) => Key::Hash(contract_hash.value()),
1507-
None => return Err(ExecuteError::NoActiveContract(caller_key)),
1558+
None => return Err(ExecuteError::MainPurseNotFound(caller_key)),
15081559
};
15091560

15101561
let named_keys = tracking_copy
15111562
.read(&contract_hash)
15121563
.map_err(|_error| ExecuteError::Fatal(FatalHostError::TrackingCopy))?
1513-
.ok_or(ExecuteError::EntityNotFound(contract_hash))?
1564+
.ok_or(ExecuteError::MainPurseNotFound(contract_hash))?
15141565
.into_contract()
15151566
.map(|contract| contract.take_named_keys())
15161567
.ok_or(ExecuteError::InvalidKeyForPurse(contract_hash))?;
@@ -1523,7 +1574,7 @@ fn get_purse_for_entity<R: GlobalStateReader>(
15231574

15241575
let hash_addr = contract_hash
15251576
.into_entity_hash_addr()
1526-
.ok_or(ExecuteError::EntityNotFound(contract_hash))?;
1577+
.ok_or(ExecuteError::MainPurseNotFound(contract_hash))?;
15271578

15281579
Ok((EntityAddr::SmartContract(hash_addr), uref))
15291580
}

executor/wasm/tests/integration.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1420,11 +1420,10 @@ fn non_existing_smart_contract_does_not_panic() {
14201420

14211421
let result = executor
14221422
.execute_with_provider(state_root_hash, &global_state, execute_request)
1423-
.expect_err("Failure");
1423+
.expect("should return execute with call error")
1424+
.host_error;
14241425

1425-
assert!(matches!(
1426-
result,
1427-
ExecuteWithProviderError::Execute(execute_error) if matches!(execute_error, ExecuteError::CodeNotFound(address) if address == non_existing_address)));
1426+
assert!(matches!(result, Some(CallError::CodeNotFound)))
14281427
}
14291428

14301429
#[test]

executor/wasm_common/src/error.rs

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,6 @@ pub enum HostResult {
3333
Internal = 9,
3434
/// Error related to CLValues
3535
CLValue = 10,
36-
/// No active version found in the package.
37-
NoActiveContract = 11,
38-
/// No byte code was found for execution.
39-
CodeNotFound = 12,
40-
/// Entity not found.
41-
EntityNotFound = 13,
42-
/// Package associated with the package was locked.
43-
LockedPackage = 14,
4436
/// An error code not covered by the other variants.
4537
Other(u32),
4638
}
@@ -56,10 +48,6 @@ pub const HOST_ERROR_MESSAGE_TOPIC_FULL: u32 = 7;
5648
pub const HOST_ERROR_MAX_MESSAGES_PER_BLOCK_EXCEEDED: u32 = 8;
5749
pub const HOST_ERROR_INTERNAL: u32 = 9;
5850
pub const HOST_ERROR_CL_VALUE: u32 = 10;
59-
pub const HOST_NO_ACTIVE_CONTRACT: u32 = 11;
60-
pub const HOST_CODE_NOT_FOUND: u32 = 12;
61-
pub const HOST_ENTITY_NOT_FOUND: u32 = 13;
62-
pub const HOST_LOCKED_PACKAGE: u32 = 14;
6351

6452
impl From<u32> for HostResult {
6553
fn from(value: u32) -> Self {
@@ -75,10 +63,6 @@ impl From<u32> for HostResult {
7563
HOST_ERROR_MAX_MESSAGES_PER_BLOCK_EXCEEDED => Self::MaxMessagesPerBlockExceeded,
7664
HOST_ERROR_INTERNAL => Self::Internal,
7765
HOST_ERROR_CL_VALUE => Self::CLValue,
78-
HOST_NO_ACTIVE_CONTRACT => Self::NoActiveContract,
79-
HOST_CODE_NOT_FOUND => Self::CodeNotFound,
80-
HOST_ENTITY_NOT_FOUND => Self::EntityNotFound,
81-
HOST_LOCKED_PACKAGE => Self::LockedPackage,
8266
other => Self::Other(other),
8367
}
8468
}
@@ -130,6 +114,10 @@ pub const CALLEE_INPUT_INVALID: u32 = 3;
130114
pub const CALLEE_GAS_DEPLETED: u32 = 4;
131115
pub const CALLEE_NOT_CALLABLE: u32 = 5;
132116
pub const CALLEE_API_ERROR: u32 = 6;
117+
pub const CALLEE_NO_ACTIVE_CONTRACT: u32 = 7;
118+
pub const CALLEE_CODE_NOT_FOUND: u32 = 8;
119+
pub const CALLEE_ENTITY_NOT_FOUND: u32 = 9;
120+
pub const CALLEE_LOCKED_PACKAGE: u32 = 10;
133121
/// Represents the result of a host function call.
134122
///
135123
/// 0 is used as a success.
@@ -150,6 +138,18 @@ pub enum CallError {
150138
/// Called contract is not callable.
151139
#[error("not callable")]
152140
NotCallable,
141+
/// No active version found in the package.
142+
#[error("no active contract")]
143+
NoActiveContract,
144+
/// No byte code was found for execution.
145+
#[error("code not found")]
146+
CodeNotFound,
147+
/// Entity not found.
148+
#[error("entity not found")]
149+
EntityNotFound,
150+
/// Package associated with the package was locked.
151+
#[error("locked package")]
152+
LockedPackage,
153153
/// System is callee and signaled vm instance kill.
154154
#[error("kill the vm instance of the caller")]
155155
Api(String),
@@ -165,6 +165,10 @@ impl CallError {
165165
Self::CalleeTrapped(_) => CALLEE_TRAPPED,
166166
Self::CalleeGasDepleted => CALLEE_GAS_DEPLETED,
167167
Self::NotCallable => CALLEE_NOT_CALLABLE,
168+
Self::NoActiveContract => CALLEE_NO_ACTIVE_CONTRACT,
169+
Self::CodeNotFound => CALLEE_CODE_NOT_FOUND,
170+
Self::EntityNotFound => CALLEE_ENTITY_NOT_FOUND,
171+
Self::LockedPackage => CALLEE_LOCKED_PACKAGE,
168172
Self::Api(_) => CALLEE_API_ERROR,
169173
}
170174
}

executor/wasm_host/src/host/control.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ use bytes::Bytes;
44
use casper_executor_wasm_common::{
55
chain_utils::{compute_next_contract_hash_version, compute_wasm_bytecode_hash},
66
error::{
7-
CALLEE_INPUT_INVALID, CALLEE_NOT_CALLABLE, CALLEE_SUCCEEDED, HOST_ERROR_INVALID_DATA,
8-
HOST_ERROR_INVALID_INPUT, HOST_LOCKED_PACKAGE, HOST_NO_ACTIVE_CONTRACT,
7+
CALLEE_INPUT_INVALID, CALLEE_LOCKED_PACKAGE, CALLEE_NOT_CALLABLE,
8+
CALLEE_NO_ACTIVE_CONTRACT, CALLEE_SUCCEEDED, HOST_ERROR_INVALID_DATA,
9+
HOST_ERROR_INVALID_INPUT,
910
},
1011
};
1112
use casper_executor_wasm_interface::{
@@ -291,7 +292,7 @@ pub(crate) fn host_upgrade<S: GlobalStateReader + 'static>(
291292
};
292293

293294
if package.is_locked() {
294-
return Ok(HOST_LOCKED_PACKAGE);
295+
return Ok(CALLEE_LOCKED_PACKAGE);
295296
}
296297

297298
match package.current_contract_hash() {
@@ -345,7 +346,7 @@ pub(crate) fn host_upgrade<S: GlobalStateReader + 'static>(
345346
contract_version_key.contract_version(),
346347
)
347348
}
348-
None => return Ok(HOST_NO_ACTIVE_CONTRACT),
349+
None => return Ok(CALLEE_NO_ACTIVE_CONTRACT),
349350
}
350351
}
351352
Ok(Some(other_entity)) => {

executor/wasm_host/src/system.rs

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -264,22 +264,47 @@ pub fn native_exec<A, T: ToBytes, R: GlobalStateReader + 'static>(
264264
match tracking_copy.get_package(contract_hash_addr) {
265265
Ok(package) => match package.enabled_versions().latest() {
266266
Some(entity_addr) => (Key::Hash(entity_addr.value()), *entity_addr),
267-
None => return Err(ExecuteError::NoActiveContract(caller_key)),
267+
None => {
268+
return Ok(ExecuteResult {
269+
host_error: Some(CallError::NoActiveContract),
270+
output: None,
271+
gas_usage,
272+
effects: tracking_copy.effects(),
273+
cache: tracking_copy.cache(),
274+
messages: tracking_copy.messages(),
275+
})
276+
}
268277
},
269278
Err(tce) => return Err(ExecuteError::Api(tce.to_string())),
270279
}
271280
} else if let Key::Package(package_addr) = caller_key {
272281
match tracking_copy.get_package(package_addr.value()) {
273282
Ok(package) => match package.enabled_versions().latest() {
274283
Some(entity_addr) => (Key::Hash(entity_addr.value()), *entity_addr),
275-
None => return Err(ExecuteError::NoActiveContract(caller_key)),
284+
None => {
285+
return Ok(ExecuteResult {
286+
host_error: Some(CallError::NoActiveContract),
287+
output: None,
288+
gas_usage,
289+
effects: tracking_copy.effects(),
290+
cache: tracking_copy.cache(),
291+
messages: tracking_copy.messages(),
292+
})
293+
}
276294
},
277295
Err(tce) => return Err(ExecuteError::Api(tce.to_string())),
278296
}
279297
} else if let Key::AddressableEntity(entity_addr) = caller_key {
280298
(caller_key, entity_addr)
281299
} else {
282-
return Err(ExecuteError::EntityNotFound(caller_key));
300+
return Ok(ExecuteResult {
301+
host_error: Some(CallError::EntityNotFound),
302+
output: None,
303+
gas_usage,
304+
effects: tracking_copy.effects(),
305+
cache: tracking_copy.cache(),
306+
messages: tracking_copy.messages(),
307+
});
283308
};
284309

285310
let runtime_footprint = match tracking_copy.runtime_footprint_by_entity_addr(entity_addr) {
@@ -290,7 +315,14 @@ pub fn native_exec<A, T: ToBytes, R: GlobalStateReader + 'static>(
290315
?entity_addr,
291316
"native_exec failed attempt to runtime_footprint_by_entity_addr"
292317
);
293-
return Err(ExecuteError::EntityNotFound(caller_key));
318+
return Ok(ExecuteResult {
319+
host_error: Some(CallError::EntityNotFound),
320+
output: None,
321+
gas_usage,
322+
effects: tracking_copy.effects(),
323+
cache: tracking_copy.cache(),
324+
messages: tracking_copy.messages(),
325+
});
294326
}
295327
};
296328

0 commit comments

Comments
 (0)