Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Subintent Execution Implementation Part 1 #1913

Merged
merged 17 commits into from
Sep 13, 2024

Conversation

talekhinezh
Copy link
Member

@talekhinezh talekhinezh commented Sep 10, 2024

  • Add YieldToChild and YieldToParent support (though arguments are not yet supported)
  • Add Transaction Processor context switching support
  • Add multiple stacks to Kernel

This is the first part of Subintent execution implementation. Some TODOs for future PRs:

  • Implement other V2 Instructions: VerifyParent and AssertWorktopIsEmpty
  • Disallow ability to call lock_fee in subintents
  • Pass resources between subintents when yield is called
  • Verification of nullifier rules

Copy link

Phylum Report Link

@talekhinezh talekhinezh marked this pull request as ready for review September 10, 2024 23:24
Copy link

github-actions bot commented Sep 10, 2024

Docker tags
docker.io/radixdlt/private-scrypto-builder:38d40a62ed

Copy link

github-actions bot commented Sep 11, 2024

Benchmark for 38d40a6

Click to view benchmark
Test Base PR %
costing::bench_prepare_wasm 63.2±0.10ms 63.3±0.53ms +0.16%
costing::decode_encoded_i8_array_to_manifest_raw_value 19.3±0.00ms 19.6±0.01ms +1.55%
costing::decode_encoded_i8_array_to_manifest_value 41.4±0.16ms 42.6±0.15ms +2.90%
costing::decode_encoded_tuple_array_to_manifest_raw_value 63.0±0.12ms 63.5±0.14ms +0.79%
costing::decode_encoded_tuple_array_to_manifest_value 99.2±0.32ms 99.2±0.35ms 0.00%
costing::decode_encoded_u8_array_to_manifest_raw_value 32.4±0.12µs 25.5±0.05µs -21.30%
costing::decode_encoded_u8_array_to_manifest_value 41.6±0.08ms 42.6±0.09ms +2.40%
costing::decode_rpd_to_manifest_raw_value 12.3±0.02µs 12.5±0.03µs +1.63%
costing::decode_rpd_to_manifest_value 10.9±0.03µs 10.7±0.02µs -1.83%
costing::deserialize_wasm 1256.5±6.38µs 1241.0±3.14µs -1.23%
costing::execute_transaction_creating_big_vec_substates 708.8±12.58ms 705.4±13.09ms -0.48%
costing::execute_transaction_reading_big_vec_substates 603.3±1.95ms 587.0±2.60ms -2.70%
costing::instantiate_flash_loan 932.9±563.30µs 1022.9±1229.44µs +9.65%
costing::instantiate_radiswap 932.7±538.16µs 964.5±561.97µs +3.41%
costing::spin_loop 20.6±0.05ms 21.1±0.05ms +2.43%
costing::validate_sbor_payload 27.5±0.03µs 31.9±0.07µs +16.00%
costing::validate_sbor_payload_bytes 215.3±0.86ns 241.3±0.38ns +12.08%
costing::validate_secp256k1 76.9±0.03µs 76.7±0.05µs -0.26%
costing::validate_wasm 33.5±0.04ms 33.7±0.04ms +0.60%
decimal::add/0 8.4±0.00ns 8.4±0.00ns 0.00%
decimal::add/rust-native 9.9±0.00ns 9.9±0.01ns 0.00%
decimal::add/wasmi 224.0±0.68ns 222.7±0.28ns -0.58%
decimal::add/wasmi-call-native 2.2±0.00µs 2.1±0.00µs -4.55%
decimal::div/0 186.3±0.13ns 184.8±0.11ns -0.81%
decimal::from_string/0 154.4±0.24ns 154.9±0.20ns +0.32%
decimal::mul/0 149.8±0.14ns 149.2±0.14ns -0.40%
decimal::mul/rust-native 148.0±0.09ns 147.5±0.11ns -0.34%
decimal::mul/wasmi 11.8±0.04µs 11.8±0.05µs 0.00%
decimal::mul/wasmi-call-native 2.3±0.01µs 2.3±0.01µs 0.00%
decimal::pow/0 689.0±0.35ns 703.1±2.29ns +2.05%
decimal::pow/rust-native 669.5±0.76ns 666.9±0.63ns -0.39%
decimal::pow/wasmi 57.4±0.21µs 57.5±0.23µs +0.17%
decimal::pow/wasmi-call-native 2.5±0.00µs 2.5±0.01µs 0.00%
decimal::root/0 8.0±0.01µs 8.1±0.01µs +1.25%
decimal::sub/0 8.2±0.01ns 8.2±0.01ns 0.00%
decimal::to_string/0 450.1±1.43ns 437.1±0.59ns -2.89%
precise_decimal::add/0 9.1±0.01ns 8.8±0.00ns -3.30%
precise_decimal::add/rust-native 10.8±0.02ns 10.7±0.04ns -0.93%
precise_decimal::add/wasmi 271.5±1.21ns 273.0±0.60ns +0.55%
precise_decimal::add/wasmi-call-native 2.8±0.00µs 2.8±0.00µs 0.00%
precise_decimal::div/0 318.0±0.24ns 317.2±0.44ns -0.25%
precise_decimal::from_string/0 202.1±0.13ns 201.9±0.27ns -0.10%
precise_decimal::mul/0 368.7±1.08ns 366.1±1.77ns -0.71%
precise_decimal::mul/rust-native 342.4±0.38ns 318.7±0.54ns -6.92%
precise_decimal::mul/wasmi 33.5±0.05µs 34.3±0.16µs +2.39%
precise_decimal::mul/wasmi-call-native 3.2±0.00µs 3.2±0.01µs 0.00%
precise_decimal::pow/0 1934.8±3.51ns 1926.5±1.58ns -0.43%
precise_decimal::pow/rust-native 1566.4±3.42ns 1543.2±2.10ns -1.48%
precise_decimal::pow/wasmi 163.6±0.95µs 165.8±0.79µs +1.34%
precise_decimal::pow/wasmi-call-native 5.8±0.04µs 5.8±0.00µs 0.00%
precise_decimal::root/0 57.0±0.03µs 57.1±0.02µs +0.18%
precise_decimal::sub/0 9.2±0.02ns 9.0±0.08ns -2.17%
precise_decimal::to_string/0 704.8±3.20ns 705.5±1.89ns +0.10%
schema::validate_payload 365.4±0.86µs 365.4±0.62µs 0.00%
transaction::radiswap 5.1±0.02ms 5.1±0.03ms 0.00%
transaction::transfer 1794.2±17.44µs 1844.9±4.16µs +2.83%
transaction_processing::prepare 2.5±0.00ms 2.6±0.00ms +4.00%
transaction_processing::prepare_and_decompile 6.9±0.01ms 6.8±0.01ms -1.45%
transaction_processing::prepare_and_decompile_and_recompile 30.2±1.46ms 26.7±2.00ms -11.59%
transaction_validation::validate_manifest 42.7±0.04µs 42.7±0.19µs 0.00%
transaction_validation::verify_bls_2KB 1061.8±15.07µs 1002.7±7.48µs -5.57%
transaction_validation::verify_bls_32B 1013.2±25.10µs 1063.4±13.32µs +4.95%
transaction_validation::verify_ecdsa 74.6±0.07µs 74.6±0.08µs 0.00%
transaction_validation::verify_ed25519 56.5±0.47µs 57.4±0.66µs +1.59%

@talekhinezh talekhinezh changed the base branch from feature/transaction-processing-v2 to develop September 13, 2024 03:41
@talekhinezh talekhinezh force-pushed the feature/subintent-impl-1 branch from 68e6e7a to 76585e4 Compare September 13, 2024 04:22
@talekhinezh talekhinezh merged commit f2d674b into develop Sep 13, 2024
31 checks passed
Copy link
Contributor

@dhedey dhedey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice. Because of the importance of this, I've done a very close review.
Quite a few of the comments are just about naming, but a few are questions about correctness / tightness.

txn_threads.execute(api)?;
let output = txn_threads
.threads
.get_mut(0)
Copy link
Contributor

@dhedey dhedey Sep 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps we should change the receipt to have outputs as an IndexMap<IntentHash, Outputs>? Or perhaps even better, separate the root intent and subintent outputs? Have added a test case for this, can do this later.

radix-engine/src/kernel/kernel.rs Show resolved Hide resolved

pub fn push(&mut self, frame: CallFrame<M::CallFrameData, M::LockData>) {
let stack = self.stacks.get_mut(self.stack_pointer).unwrap();
let parent = mem::replace(&mut stack.current_frame, frame);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MINOR: From a code neatness perspective, might be nice if this delegated to stack.push, ditto with stack.pop.

radix-engine/src/kernel/kernel.rs Show resolved Hide resolved
radix-engine/src/kernel/kernel.rs Show resolved Hide resolved
use radix_engine_interface::blueprints::transaction_processor::{
TRANSACTION_PROCESSOR_BLUEPRINT, TRANSACTION_PROCESSOR_RUN_IDENT,
};
use radix_rust::prelude::*;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Import wise, lots of this can be replaced with radix_engine::internal_prelude::* to avoid lots of import churn if we move things.

api.kernel_switch_stack(thread_id)?;

let mut system_service = SystemService::new(api);
let virtual_resources = intent
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We agreed to not use the name virtual for these going forward. Perhaps initial_proof_resources, initial_non_fungible_proofs?

virtual_non_fungibles,
)?;

api.kernel_set_call_frame_data(Actor::Function(FunctionActor {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm this feels weird to me - is this right that we're replacing the root call frame with this?

In principle, this isn't a problem, but I think we need to discuss what the abstraction is around Actor::Root and how it interacts with other parts of the codebase (cf comments on #1919 )

Ok(())
}

pub fn cleanup<Y: SystemBasedKernelApi>(self, api: &mut Y) -> Result<(), RuntimeError> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'd rather run cleanup greedily when each subintent terminates. I think it gives a more intuitive / timely orphaned node error, if a user is thinking of the intents like stack frames.

cur_thread = parent_stack.pop().unwrap();
}
ResumeResult::Done => {
if let Some(parent) = parent_stack.pop() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'd like us to be a little stricter here - e.g. set the processor to ProcesserState::Consumed, and ensure that when we yield to child, we check that we're in ProcesserState::Active(processor)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants