Skip to content

Commit 3a2cde8

Browse files
authored
Merge pull request #5354 from zajko/endpoint_call_in_journal
Execution journal entries on entry point calls
2 parents b5be2c1 + f90e14f commit 3a2cde8

File tree

27 files changed

+1149
-76
lines changed

27 files changed

+1149
-76
lines changed

Cargo.lock

Lines changed: 26 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

execution_engine/CHANGELOG.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ All notable changes to this project will be documented in this file. The format
1818

1919
### Added
2020

21-
- A VM1 contract version install (both new and upgrade) will now produce a native message to system-owned topics:
21+
- A contract version install (both new and upgrade) will now produce a native message to system-owned topics:
2222
- in case `addressable_entity` is turned off:
2323
- `contract_key` topic will receive string-formatted `Key::Hash` containing the address of the new `StoredValue::Contract` value
2424
- `package_key` topic will receive string-formatted `Key::Hash` containing the address of the new `StoredValue::ContractPackage` value
@@ -29,6 +29,23 @@ All notable changes to this project will be documented in this file. The format
2929
- `package_key` topic will receive string-formatted `Key::SmartContract` containing the address of the new `SmartContract::Package` value
3030
- `bytecode_key` topic will receive string-formatted `Key::ByteCode` containing the address of the new `StoredValue::ByteCode` value
3131
- `contract_version` topic will receive a string containing the major contract and minor installed contract version (for example "2.1")
32+
- Calling wasm adds additional execution journal entries. For each session execution there will be a corresponding pair of TransformKindV2::EntryPointCalled and TransformKindV2::Ret written:
33+
- For session bytes:
34+
- the key under which both transforms will be stored is the Key::Account that initiated the transaction.
35+
- The `Option<HashAddr>` of `EntryPointCalled` will be `None`
36+
- The `String` of `EntryPointCalled` will be `"call"` (the default function name we expect of session wasm)
37+
- The `Ret` will either be `RetValue::Unit` or `RetValue::CLValue` depending on wether or not the code called `casper_return`.
38+
- If a session call calls a stored contracts entrypoint:
39+
- the key under which both transforms will be stored is the Key::Account that initiated the transaction.
40+
- The `Option<HashAddr>` of `EntryPointCalled` will be `Some(<called_contract_hash>)`
41+
- The `String` of `EntryPointCalled` will be the name of the called entrypoint
42+
- The `Ret` will either be `RetValue::Unit` or `RetValue::CLValue` depending on wether or not the code called `casper_return`.
43+
- If a stored contract calls another stored contract:
44+
- the key under which both transforms will be stored is the key of the contract which is executing the call.
45+
- The `Option<HashAddr>` of `EntryPointCalled` will be `Some(<called_contract_hash>)`
46+
- The `String` of `EntryPointCalled` will be the name of the called entrypoint
47+
- The `Ret` will either be `RetValue::Unit` or `RetValue::CLValue` depending on wether or not the code called `casper_return`.
48+
- the above also applies to `payment` bytecode if supplied
3249

3350
## 8.0.0
3451

execution_engine/src/runtime/mod.rs

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -718,13 +718,13 @@ where
718718
self.host_buffer = bytesrepr::deserialize_from_slice(buf).ok();
719719

720720
// Emit Ret transform to the execution journal
721-
if let Some(cl_value) = &self.host_buffer {
722-
let key = self.context.get_context_key();
723-
self.context
724-
.state()
725-
.borrow_mut()
726-
.ret(key, RetValue::CLValue(cl_value.clone()));
727-
}
721+
let ret_val = if let Some(cl_value) = &self.host_buffer {
722+
RetValue::CLValue(cl_value.clone())
723+
} else {
724+
RetValue::Unit
725+
};
726+
let key = self.context.get_context_key();
727+
self.context.state().borrow_mut().ret(key, ret_val);
728728

729729
let urefs = match &self.host_buffer {
730730
Some(buf) => utils::extract_urefs(buf),
@@ -1455,6 +1455,11 @@ where
14551455
let protocol_version = self.context.protocol_version();
14561456
let engine_config = self.context.engine_config();
14571457
let wasm_config = engine_config.wasm_config();
1458+
self.context.state().borrow_mut().entry_point_called(
1459+
self.context.get_context_key(),
1460+
None,
1461+
DEFAULT_ENTRY_POINT_NAME.to_string(),
1462+
);
14581463
#[cfg(feature = "test-support")]
14591464
let max_stack_height = wasm_config.v1().max_stack_height();
14601465
let module = preprocess(*wasm_config, module_bytes)?;
@@ -1483,6 +1488,10 @@ where
14831488
// returned the unit type `()` as per Rust functions which don't specify a
14841489
// return value.
14851490
Ok(_) => {
1491+
self.context
1492+
.state()
1493+
.borrow_mut()
1494+
.ret(self.context.get_context_key(), RetValue::Unit);
14861495
return Ok(self.take_host_buffer().unwrap_or(CLValue::from_t(())?));
14871496
}
14881497
};
@@ -1892,6 +1901,12 @@ where
18921901
}
18931902
};
18941903

1904+
self.context.state().borrow_mut().entry_point_called(
1905+
self.context.get_context_key(),
1906+
Some(entity_addr.value()),
1907+
entry_point_name.to_string(),
1908+
);
1909+
18951910
if let EntityKind::Account(_) = footprint.entity_kind() {
18961911
return Err(ExecError::InvalidContext);
18971912
}
@@ -1916,6 +1931,11 @@ where
19161931
}
19171932
};
19181933

1934+
// if session the caller's context
1935+
// else the called contract's context
1936+
let context_entity_key =
1937+
self.get_context_key_for_contract_call(entity_addr, entry_point)?;
1938+
19191939
let entry_point_type = entry_point.entry_point_type();
19201940

19211941
if self.context.engine_config().enable_entity && entry_point_type.is_invalid_context() {
@@ -1971,11 +1991,6 @@ where
19711991
return Err(ExecError::DisabledEntity(entity_hash));
19721992
}
19731993

1974-
// if session the caller's context
1975-
// else the called contract's context
1976-
let context_entity_key =
1977-
self.get_context_key_for_contract_call(entity_addr, entry_point)?;
1978-
19791994
let context_entity_hash = context_entity_key
19801995
.into_entity_hash_addr()
19811996
.ok_or(ExecError::UnexpectedKeyVariant(context_entity_key))?;
@@ -2199,7 +2214,6 @@ where
21992214
.set_emit_message_cost(runtime.context.emit_message_cost());
22002215
let transfers = self.context.transfers_mut();
22012216
runtime.context.transfers().clone_into(transfers);
2202-
22032217
match result {
22042218
Ok(_) => {
22052219
// If `Ok` and the `host_buffer` is `None`, the contract's execution succeeded but
@@ -2215,6 +2229,8 @@ where
22152229
}
22162230
self.context
22172231
.set_remaining_spending_limit(runtime.context.remaining_spending_limit());
2232+
let key = self.context.get_context_key();
2233+
self.context.state().borrow_mut().ret(key, RetValue::Unit);
22182234
Ok(runtime.take_host_buffer().unwrap_or(CLValue::from_t(())?))
22192235
}
22202236
Err(error) => {

execution_engine_testing/test_support/src/execute_request_builder.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,24 @@ impl ExecuteRequestBuilder {
223223
)
224224
}
225225

226+
/// Returns an [`ExecuteRequest`] derived from a deploy with sessiond and payment bytecode.
227+
pub fn standard_and_payment(
228+
account_hash: AccountHash,
229+
session_file: &str,
230+
session_args: RuntimeArgs,
231+
payment_file: &str,
232+
payment_args: RuntimeArgs,
233+
) -> Self {
234+
Self::standard_and_payment_with_protocol_version(
235+
account_hash,
236+
session_file,
237+
session_args,
238+
payment_file,
239+
payment_args,
240+
DEFAULT_PROTOCOL_VERSION,
241+
)
242+
}
243+
226244
/// Returns an [`ExecuteRequest`] derived from a deploy with standard dependencies.
227245
pub fn standard_with_protocol_version(
228246
account_hash: AccountHash,
@@ -241,6 +259,24 @@ impl ExecuteRequestBuilder {
241259
Self::from_deploy_item_for_protocol_version(&deploy_item, protocol_version)
242260
}
243261

262+
/// Returns an [`ExecuteRequest`] derived from a deploy with standard dependencies.
263+
pub fn standard_and_payment_with_protocol_version(
264+
account_hash: AccountHash,
265+
session_file: &str,
266+
session_args: RuntimeArgs,
267+
payment_file: &str,
268+
payment_args: RuntimeArgs,
269+
protocol_version: ProtocolVersion,
270+
) -> Self {
271+
let deploy_item = DeployItemBuilder::new()
272+
.with_address(account_hash)
273+
.with_session_code(session_file, session_args)
274+
.with_payment_code(payment_file, payment_args)
275+
.with_authorization_keys(&[account_hash])
276+
.build();
277+
Self::from_deploy_item_for_protocol_version(&deploy_item, protocol_version)
278+
}
279+
244280
/// Returns an [`ExecuteRequest`] derived from a deploy with session module bytes.
245281
pub fn module_bytes(
246282
account_hash: AccountHash,

0 commit comments

Comments
 (0)