-
Notifications
You must be signed in to change notification settings - Fork 659
remove stake program builtin #7203
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
base: master
Are you sure you want to change the base?
Conversation
a6cde57
to
f502627
Compare
playing whackamole with what i am supposed to change now that the stake program is migrated...
plus various test changes already committed... still todo:
more todo:
the most perplexing thing to fix in this pr was that no note we had test failures in |
a63431e
to
88184af
Compare
aff7033
to
05aaaa5
Compare
16e51ec
to
d09ad5a
Compare
9504c99
to
246f038
Compare
#[test] | ||
fn test_builtin_program_migration() { |
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.
it is kind of a shame to delete this whole test but i dont see how to realistically keep is since we no longer have any migrating programs. maybe make a mental note of the fact that we removed it, so we can add it back when we have a new migration
( | ||
solana_sdk_ids::stake::ID, | ||
None, | ||
include_bytes!("programs/core_bpf_stake-1.0.0.so"), | ||
), |
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.
btw im very pleased to report that all the pain of this pr was in dealing with non-ProgramTest
setups that are suddenly missing the stake program. zero issues with any of the ProgramTest
consumers that now have a different stake program
let new_stake_authority = solana_pubkey::new_rand(); | ||
let stake_authority = Keypair::new(); | ||
let validator = Keypair::new(); | ||
let voter = Keypair::new(); |
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 test has a complicated diff but the tldr is it created a stake account and wanted to see pubsub updates when it was reauthorized, i just reauthorize the vote account instead for the same effect
/// Test that lamports can be sent to stake accounts regardless of rewards period. | ||
#[test] | ||
fn test_program_execution_restricted_for_stake_account_in_reward_period() { | ||
use solana_transaction_error::TransactionError::InstructionError; | ||
|
||
fn test_rewards_period_system_transfer() { |
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.
the logic stripped out here is replaced by solana-program/stake#78, which tests all stake program instructions (except deactivate deliquent rip) instead of just withdraw
// insert a stake account delegated to it, since we do not have a stake program | ||
let stake_pubkey = Pubkey::new_unique(); | ||
let stake_account = stake_state::create_account_with_activation_epoch( | ||
&stake_pubkey, | ||
&vote_keypair.pubkey(), | ||
&bank.get_account(&vote_keypair.pubkey()).unwrap(), | ||
&Rent::default(), | ||
stake_balance, | ||
bank.epoch(), | ||
); | ||
|
||
bank.store_account(&stake_pubkey, &stake_account); | ||
|
||
// the stakes cache is updated by any successful transaction that touches a stake account | ||
let transaction = | ||
system_transaction::transfer(&mint_keypair, &stake_pubkey, 1, bank.last_blockhash()); | ||
|
||
bank.process_transaction(&transaction).unwrap(); |
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.
highlighting this in case it is contentious. this is the only runtime test that uses a stake program interaction for something "real." but i believe my change is just as good in accomplishing the intent of the test
assert_eq!(bank.epoch(), 0); | ||
assert_eq!( | ||
bank.hash().to_string(), | ||
"AyXhbqmPsC46x7MHAuW89pQcNZVrUZnAND6ABWJ24svx", | ||
"EzyLJJki4ALhQAq5wbmiNctDhytQckGJRXnk9APKXv7r", | ||
); | ||
} |
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 joked i feel like claude code just replacing the failing static value with the actual one, but per joe this is correct. the bank hash is different because we no longer have the builtin stake program account. but there is no consensus divergence because this is already the case on live clusters
let core_programs = core_bpf_programs(&genesis_config.rent, |_| true); | ||
let stake_idx = core_programs | ||
.iter() | ||
.position(|(key, _)| *key == stake::program::id()) | ||
.unwrap(); | ||
let program = core_programs[stake_idx].1.clone(); | ||
let (programdata_address, programdata) = core_programs[stake_idx + 1].clone(); | ||
|
||
genesis_config.add_account(stake::program::id(), program); | ||
genesis_config.add_account(programdata_address, programdata); |
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 is the same as what i originally did in LocalCluster
(but changed it to load all core programs). but unlike there, just throwing the program in here is totally unobjectionable, because its just testing a stake cli
fwiw these are the only two places i needed the core program binary blobs outside ProgramTest
, so i didnt consider it important to break out the core bpf programs into a new package. in fact i think its better they live there: circular dependencies create a barrier to dragging these magic elves (lol) all over the code base where they dont belong
for core_program_account in &core_bpf_programs(&Rent::default(), |_| true) { | ||
config | ||
.additional_accounts | ||
.push(core_program_account.clone()); | ||
} | ||
|
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.
im mildly concerned this is a hack, i dont know what mechanism a real cluster genesis uses to make sure it gets the core bpf programs, and if it is viable for LocalCluster
to use it as well. i guess my view is "if we have some kind of test coverage of the multinode setup or similar, that ensures fresh clusters actually work, what we do in LocalCluster
doesnt really matter. if LocalCluster
is the only test surface we have over setting up clusters, probably we should use the formal mechanism that real clusters use to get core bpf programs"
also i assume that because it goes through the same kind of GenesisConfig
setup as bank tests, LocalCluster
is implicitly FeatureSet::all_enabled()
, but i didnt find where this actually happens
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #7203 +/- ##
=========================================
Coverage ? 83.3%
=========================================
Files ? 801
Lines ? 362669
Branches ? 0
=========================================
Hits ? 302155
Misses ? 60514
Partials ? 0 🚀 New features to boost your workflow:
|
added you both as reviewers, you dont have to both review everything i was thinking @buffalojoec could sign off that i got the changes to all the hardcoded builtins/core programs/builtin costs/etc stuff right, and @joncinque could look at the stake-related test changes i decided to do the stake program removal in phases, for ease of review. this pr removes it from the builtins list, adds it to program-test, and fixes all the breakage that results from that. the next pr would delete as much of the stake program code as possible i wanted to do that as its own thing since we cant just delete it all; there is a bunch of stuff in the directory used in tests, used for genesis, used for rewards calculation etc. we may also want to reexport things from the stake program interface crate to reduce downstream breakage, make new packages for things, etc. so since there will be some debate and probably a few iterations, better to do that standalone i annotated the parts of the pr that may be particularly interesting, most of the diff is whole-file deletions edit: i have to rebase again to catch the fix in master for a security issue dependency update, but this already passed ci |
333f122
to
2e4de28
Compare
position: 0, | ||
}), | ||
)]; | ||
pub const MIGRATING_BUILTINS_COSTS: &[(Pubkey, BuiltinCost)] = &[]; |
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 is now empty, could technically remove in a follow-up PR.
However, I wonder if we should clean it up or leave it for future migrations. There are only a few programs left:
(vote::id(), BuiltinCost::NotMigrating),
(system_program::id(), BuiltinCost::NotMigrating),
(compute_budget::id(), BuiltinCost::NotMigrating),
(bpf_loader_upgradeable::id(), BuiltinCost::NotMigrating),
(bpf_loader_deprecated::id(), BuiltinCost::NotMigrating),
(bpf_loader::id(), BuiltinCost::NotMigrating),
(loader_v4::id(), BuiltinCost::NotMigrating),
(secp256k1_program::id(), BuiltinCost::NotMigrating),
(ed25519_program::id(), BuiltinCost::NotMigrating),
Do we have plans or anticipate migrating any of these?
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.
yea, i asked jon before about whether to leave the migration scaffolding in place for the future or if we were done. we want to migrate loaderv4 and the zk-elgamal program (which i dont see on this list, not sure its status), but they need some syscalls first, so i left migration logic for future use
originally we had planned on migrating vote and system. but my understanding is alpenglow will not need an actual vote program. and we nixed system because its simple enough for fd to keep their own version and creating a "privileged" syscall for a bpf system to allocate accounts was not worth it
Problem
the bpf stake program is now active on all clusters and can be removed from builtins
Summary of Changes
remove it from
BUILTINS
, add the bpf stake program 1.0.0 binary blob toCORE_BPF_PROGRAMS
, and fix various tests and test setups to deal with this:programs/stake-tests/
. these were tests forMoveStake
andMoveLamports
which have long since been duplicated in the bpf stake repothis pr is already quite difficult to review. if everyone is happy with this idea, id like to merge this as a standalone pr without removing the stake program code, and do that in a followup pr. removing the stake program code is nontrivial because it contains a bunch of utility functions which are used in tests, during genesis, and possibly elsewhere. it also contains some of the rewards-related code still running in agave. and we may want to reexport various things to not break downstream too badly
these changes will have to be debated (particularly breaking the interface, whether we move things into new packages, etc) and itd be better to look at them in isolation