-
Notifications
You must be signed in to change notification settings - Fork 4.6k
system-program: Remove zero lamport check on transfers #17726
Conversation
|
||
if invoke_context.is_feature_active(&feature_set::system_transfer_zero_check::id()) | ||
&& lamports == 0 | ||
{ | ||
return Ok(()); | ||
} | ||
|
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.
this looks unnecessary. The lamports check below will be bypassed when lamports == 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.
Yeah it looks a bit silly, but it avoids unnecessary calls to try_account_ref_mut()
later on. If there's no possible issues with doing those, I'm happy to get rid of this
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.
yeah no possible issues with that, let's get rid of it
@@ -1103,7 +1125,7 @@ mod tests { | |||
0, | |||
&MockInvokeContext::new(vec![]), | |||
) | |||
.is_ok(),); | |||
.is_err(),); |
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.
Can we assert_eq!(transfer(), Err(InstructionError::MissingRequiredSignature));
here instead? Reordering of errors will break consensus and we should be able to catch it.
@jstarry @t-nelson Could I ask for another quick check? The stake split instruction uses the Line 399 in be957f2
split with auto-authorized stakes in 1.6, I'll remove that backport and only backport to 1.7. Let me know what you think.
|
@@ -179,6 +179,7 @@ fn transfer_verified( | |||
ic_msg!(invoke_context, "Transfer: `from` must not carry data"); | |||
return Err(InstructionError::InvalidArgument); | |||
} | |||
|
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.
nit: avoid change here
&id(), | ||
), | ||
system_instruction::allocate(split_stake_pubkey, std::mem::size_of::<StakeState>() as u64), | ||
system_instruction::assign(split_stake_pubkey, &id()), |
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.
This will break the Ledger app's parser. Splits will need to be blind signed until it's updated
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.
Looks like it used to be allocate + assign, then something changed https://github.com/LedgerHQ/app-solana/blob/1c72216edf4e5358f719b164a8d1b6100988b34d/libsol/transaction_printers.c#L29
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.
Ah right. Good ole lazy past-Trent saves the day 😉
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.
That's a rarity. I don't think past me has ever helped me that much
Pull request has been modified.
@@ -288,7 +288,6 @@ pub fn split_with_seed( | |||
std::mem::size_of::<StakeState>() as u64, | |||
&id(), | |||
), | |||
system_instruction::assign_with_seed(split_stake_pubkey, base, seed, &id()), |
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.
Landmines everywhere!
solana/runtime/src/system_instruction_processor.rs
Lines 391 to 404 in 7bb5f24
SystemInstruction::AllocateWithSeed { | |
base, | |
seed, | |
space, | |
owner, | |
} => { | |
let keyed_account = keyed_account_at_index(keyed_accounts, 0)?; | |
let mut account = keyed_account.try_account_ref_mut()?; | |
let address = Address::create( | |
keyed_account.unsigned_key(), | |
Some((&base, &seed, &owner)), | |
invoke_context, | |
)?; | |
allocate_and_assign( |
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.
Seriously. You should see my most recent commit 😅
@t-nelson @jstarry sorry, just one more check please on bdd6da6 -- with these changes, it's also possible to split a stake into an account that already has lamports, which is currently supported by the stake program. For some reason, there's an existing test to make sure that this isn't possible, even though this behavior is reasonable. As such, I've updated the test from a failure to a success. |
It's usually a mistake to split into an account which already has lamports. However, this is a recoverable mistake because a split account can have its extra lamports withdrawn and it can also be merged and closed completely if needed. I think that the "existing account" check should be a client side check in the cli rather than in the transaction. This looks good to me |
Agreed. This is no worse than doing a system transfer into a delegated stake account. Which is annoying, but no funds are at risk past a bit of dust for fees |
Codecov Report
@@ Coverage Diff @@
## master #17726 +/- ##
=========================================
- Coverage 82.7% 82.7% -0.1%
=========================================
Files 431 431
Lines 120590 120610 +20
=========================================
+ Hits 99839 99841 +2
- Misses 20751 20769 +18 |
* system-program: Move lamports == 0 check on transfers * Address feedback * Update stake split to explicitly allocate + assign * Update stake tests referring to split instruction * Revert whitespace * Update split instruction index in test * Remove unnecessary `assign_with_seed` from `split_with_seed` * Fix stake instruction parser * Update test to allow splitting into account with lamports (cherry picked from commit 8f5e773) # Conflicts: # runtime/src/system_instruction_processor.rs # sdk/src/feature_set.rs
* system-program: Move lamports == 0 check on transfers * Address feedback * Update stake split to explicitly allocate + assign * Update stake tests referring to split instruction * Revert whitespace * Update split instruction index in test * Remove unnecessary `assign_with_seed` from `split_with_seed` * Fix stake instruction parser * Update test to allow splitting into account with lamports (cherry picked from commit 8f5e773)
* system-program: Move lamports == 0 check on transfers * Address feedback * Update stake split to explicitly allocate + assign * Update stake tests referring to split instruction * Revert whitespace * Update split instruction index in test * Remove unnecessary `assign_with_seed` from `split_with_seed` * Fix stake instruction parser * Update test to allow splitting into account with lamports (cherry picked from commit 8f5e773) Co-authored-by: Jon Cinque <jon.cinque@gmail.com>
…) (#17763) * system-program: Remove zero lamport check on transfers (#17726) * system-program: Move lamports == 0 check on transfers * Address feedback * Update stake split to explicitly allocate + assign * Update stake tests referring to split instruction * Revert whitespace * Update split instruction index in test * Remove unnecessary `assign_with_seed` from `split_with_seed` * Fix stake instruction parser * Update test to allow splitting into account with lamports (cherry picked from commit 8f5e773) # Conflicts: # runtime/src/system_instruction_processor.rs # sdk/src/feature_set.rs * Resolve merge conflicts Co-authored-by: Jon Cinque <jon.cinque@gmail.com>
Problem
It's possible to bypass signature checks if transferring 0 lamports, causing potential unclear / misleading behavior.
Summary of Changes
Perform all checks on transfers, even for 0 lamports.
Fixes #