-
Notifications
You must be signed in to change notification settings - Fork 4.6k
Refactor: process_instruction() #20448
Refactor: process_instruction() #20448
Conversation
b051b76
to
a851842
Compare
a851842
to
fe09137
Compare
fe09137
to
4e29b54
Compare
17fe3c1
to
05cce99
Compare
05cce99
to
cf86549
Compare
Codecov Report
@@ Coverage Diff @@
## master #20448 +/- ##
=========================================
- Coverage 82.3% 82.1% -0.3%
=========================================
Files 497 492 -5
Lines 136959 137083 +124
=========================================
- Hits 112854 112673 -181
- Misses 24105 24410 +305 |
programs/bpf_loader/src/lib.rs
Outdated
@@ -283,22 +310,22 @@ fn process_loader_upgradeable_instruction( | |||
|
|||
match limited_deserialize(instruction_data)? { | |||
UpgradeableLoaderInstruction::InitializeBuffer => { | |||
let buffer = keyed_account_at_index(keyed_accounts, 0)?; | |||
let buffer = keyed_account_at_index(keyed_accounts, 1)?; |
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 see the assert above but maybe its clearer to just pass the skip variable through?
@@ -1042,6 +1074,38 @@ mod tests { | |||
} | |||
} | |||
|
|||
type KeyedAccountTuple<'a> = (bool, bool, &'a Pubkey, &'a RefCell<AccountSharedData>); |
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.
Any reason this isn't a structure to help with readability?
keyed_accounts[0].account.borrow_mut().set_data(vec![0; 6]); | ||
let mut invoke_context = MockInvokeContext::new(keyed_accounts); | ||
keyed_accounts[0] = (true, false, &program_key, &program_account); | ||
keyed_accounts[0].3.borrow_mut().set_data(vec![0; 6]); |
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.
tuple indexing, yuck
KeyedAccount::new_readonly(&clock_id, false, &clock_account), | ||
KeyedAccount::new_readonly( | ||
&upgrade_authority_address, | ||
let keyed_accounts: Vec<KeyedAccountTuple> = vec![ |
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.
Why are these now tuples and not KeyedAccount
s?
|
||
let me = &keyed_account_at_index(keyed_accounts, 0)?; | ||
|
||
let me = &keyed_account_at_index(keyed_accounts, 1)?; |
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.
These magic numbers are confusing and there is not info here to indicate what they are based on. Also, is _skip_program_accounts
== 1 here, if so, why not base on that?
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.
You are right that we should document what keyed_account_at_index()
is based / operating on.
Because now, it is always the beginning of the program chain, followed by the instruction accounts.
I also thought about parametrizing keyed_account_at_index()
with skip_program_accounts
.
However, that would introduce yet another method like keyed_account_at_base_and_index(keyed_accounts, skip_program_accounts, index)
, or keyed_account_at_index(keyed_accounts, skip_program_accounts + index)
which is getting very long and will be short-lived as it is replaced by the ABIv2 account access pattern.
About the ugly I made all the tests to have the wrapper Now, why switch some of the test to |
cf86549
to
d683925
Compare
91e41da
to
61ccc47
Compare
61ccc47
to
1495ecd
Compare
return process_instruction(program_id, instruction_data, invoke_context); | ||
return process_instruction( | ||
program_id, | ||
1, |
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.
Name these or at leat provide a comment describing why they are the value that they are
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.
Look good, just one remaining nit about documenting a couple of magic numbers
dd1982a
to
579579a
Compare
instruction_data: &[u8], | ||
invoke_context: &mut dyn InvokeContext, | ||
) -> Result<(), InstructionError> { | ||
debug_assert_eq!(first_instruction_account, 1); |
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.
@Lichtso it's possible to hit this debug assert with the tx I described here: https://github.com/solana-labs/solana/pull/21238/files?diff=split&w=0#r752263887
* Adds first_instruction_account parameter to process_instruction(). * Removes InvokeContext::remove_first_keyed_account() from all BPF loaders. * Removes InvokeContext::remove_first_keyed_account() from all builtin programs. * Removes InvokeContext::remove_first_keyed_account() from all mock ups. * Deprecates InvokeContext::remove_first_keyed_account(). * Documents index base of keyed_account_at_index(). * Adds dynamic offset to call sites of "keyed_account_at_index()".
This reverts commit 8b7da50.
Problem
The runtime currently uses
InvokeContext::remove_first_keyed_account()
to pop off the front of the programKeyedAccount
s of each invoke stack frame. That necessitates the invoke stack frame to be writable and we want to avoid that in ABIv2 (#19191). Because, if the invoke stack frames are immutable, they can be shared as read-only between runtime, loaders and programs alike with less internal validation checks.Summary of Changes
InvokeContext::remove_first_keyed_account()
by introducing anum_program_accounts
parameter (which is acting as a cursor) toprocess_instruction()
.Fixes #