-
Notifications
You must be signed in to change notification settings - Fork 123
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
Conversation
Docker tags |
Benchmark for 38d40a6Click to view benchmark
|
68e6e7a
to
76585e4
Compare
There was a problem hiding this 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) |
There was a problem hiding this comment.
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.
|
||
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); |
There was a problem hiding this comment.
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
.
use radix_engine_interface::blueprints::transaction_processor::{ | ||
TRANSACTION_PROCESSOR_BLUEPRINT, TRANSACTION_PROCESSOR_RUN_IDENT, | ||
}; | ||
use radix_rust::prelude::*; |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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> { |
There was a problem hiding this comment.
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() { |
There was a problem hiding this comment.
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)
YieldToChild
andYieldToParent
support (though arguments are not yet supported)This is the first part of Subintent execution implementation. Some TODOs for future PRs:
VerifyParent
andAssertWorktopIsEmpty
lock_fee
in subintents