This repository was archived by the owner on Jan 22, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
v1.0: Maintain sysvar balances for consistent market cap. #9937
Merged
mvines
merged 4 commits into
solana-labs:v1.0
from
ryoqun:sysvar-balance-for-capitalization-v1.0
May 8, 2020
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -72,6 +72,8 @@ pub const MAX_SNAPSHOT_DATA_FILE_SIZE: u64 = 32 * 1024 * 1024 * 1024; // 32 GiB | |
|
|
||
| pub const MAX_LEADER_SCHEDULE_STAKES: Epoch = 5; | ||
|
|
||
| const SYSVAR_BALANCE_ACTIVATION_EPOCH: Epoch = 25; | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's land this first than
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just now,
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Confirmed we now fixed the capitalization security hole. $ solana-ledger-tool --version
solana-ledger-tool 1.0.23 [channel=on-ryoqun-fork commit=e26840cb09465352067aa037b2eee7591091529b]
$ solana-ledger-tool --ledger 7Np4/ capitalization
[2020-05-13T14:58:52.451659928Z INFO solana_ledger::blockstore] Maximum open file descriptors: 65000
[2020-05-13T14:58:52.451757437Z INFO solana_ledger::blockstore] Opening database at "/home/ryoqun/work/solana/solana/7Np4/rocksdb"
[2020-05-13T14:58:52.496282617Z INFO solana_ledger::blockstore] "/home/ryoqun/work/solana/solana/7Np4/rocksdb" open took 44ms
[2020-05-13T14:58:52.496396355Z INFO solana_ledger::bank_forks_utils] Initializing snapshot path: "/home/ryoqun/work/solana/solana/7Np4/snapshot"
[2020-05-13T14:58:52.510939661Z INFO solana_ledger::bank_forks_utils] Loading snapshot package: "/home/ryoqun/work/solana/solana/7Np4/snapshot-10800485-D7hNsgoVP78JhCcYaLnNxmcjdmFGsVV972LPHws2F8sW.tar.bz2"
[2020-05-13T15:00:44.248861917Z INFO solana_ledger::snapshot_utils] snapshot untar took 111.7s
[2020-05-13T15:00:44.249240456Z INFO solana_ledger::snapshot_utils] snapshot version: 1.1.0
[2020-05-13T15:00:44.249389877Z INFO solana_ledger::snapshot_utils] Loading bank from "/home/ryoqun/work/solana/solana/7Np4/snapshot/.tmp7V6HdT/snapshots/10800485/10800485"
[2020-05-13T15:00:44.349281802Z INFO solana_ledger::snapshot_utils] Rebuilding accounts...
[2020-05-13T15:03:59.756305474Z INFO solana_ledger::snapshot_utils] Rebuilding status cache...
[2020-05-13T15:04:00.177954788Z INFO solana_ledger::snapshot_utils] Loaded bank for slot: 10800485
[2020-05-13T15:04:00.179688287Z INFO solana_runtime::accounts_db] total_stores: 2500, newest_slot: 10800485, oldest_slot: 0, max_slot: 0 (num=5), min_slot: 4352296 (num=1)
[2020-05-13T15:04:00.179824349Z INFO solana_metrics::metrics] metrics disabled: SOLANA_METRICS_CONFIG: environment variable not found
[2020-05-13T15:04:00.180175764Z INFO solana_metrics::metrics] datapoint: accounts_db-stores total_count=2500i
[2020-05-13T15:04:01.017741218Z INFO solana_runtime::accounts_db] scan took 309us merge took 55us accumulate took 157us
[2020-05-13T15:04:01.017911287Z INFO solana_runtime::bank] bank frozen: 10800485 hash: HHQZF2VqbKfhWrWqySVPHZfkqQAB1sHA7LHG35Fv9duN accounts_delta: DrbroEkyrFtMTwyp1xEWfXnpAdYurwXMiSqBvz2gZab signature_count: 2 last_blockhash: DdmF1iG8ERFS4YGKUowDxmemqSFAd8VUS8uTYEoguLw8 capitalization: 499996966416753973
[2020-05-13T15:04:01.018237665Z INFO solana_runtime::bank] accounts hash slot: 10800485 stats: BankHashStats { num_removed_accounts: 10, num_added_accounts: 0, num_lamports_stored: 1340866471525, total_data_len: 165103, num_executable_accounts: 0 }
[2020-05-13T15:04:01.018317962Z INFO solana_ledger::snapshot_utils] bank rebuild from snapshot took 196.8s
[2020-05-13T15:04:01.027419913Z INFO solana_ledger::blockstore_processor] processing ledger from root slot 10800485...
[2020-05-13T15:04:02.474804690Z INFO solana_ledger::blockstore_processor] ledger processed in 1445ms. 90 MB allocated. 1 fork at 10800485, with 1 frozen bank
Capitalization: 499996966.416753973 SOL |
||
|
|
||
| type BankStatusCache = StatusCache<Result<()>>; | ||
| pub type BankSlotDelta = SlotDelta<Result<()>>; | ||
| type TransactionAccountRefCells = Vec<Rc<RefCell<Account>>>; | ||
|
|
@@ -556,16 +558,25 @@ impl Bank { | |
| self.store_account(pubkey, &new_account); | ||
| } | ||
|
|
||
| fn inherit_sysvar_account_balance(&self, old_account: &Option<Account>) -> u64 { | ||
| // Corrent sysvar account balance maintenance activates at this epoch on the mainnet-beta | ||
| if self.epoch() >= SYSVAR_BALANCE_ACTIVATION_EPOCH { | ||
| old_account.as_ref().map(|a| a.lamports).unwrap_or(1) | ||
| } else { | ||
| 1 | ||
| } | ||
| } | ||
|
|
||
| fn update_clock(&self) { | ||
| self.update_sysvar_account(&sysvar::clock::id(), |_| { | ||
| self.update_sysvar_account(&sysvar::clock::id(), |account| { | ||
| sysvar::clock::Clock { | ||
| slot: self.slot, | ||
| segment: get_segment_from_slot(self.slot, self.slots_per_segment), | ||
| epoch: self.epoch_schedule.get_epoch(self.slot), | ||
| leader_schedule_epoch: self.epoch_schedule.get_leader_schedule_epoch(self.slot), | ||
| unix_timestamp: self.unix_timestamp(), | ||
| } | ||
| .create_account(1) | ||
| .create_account(self.inherit_sysvar_account_balance(account)) | ||
| }); | ||
| } | ||
|
|
||
|
|
@@ -576,7 +587,7 @@ impl Bank { | |
| .map(|account| SlotHistory::from_account(&account).unwrap()) | ||
| .unwrap_or_default(); | ||
| slot_history.add(self.slot()); | ||
| slot_history.create_account(1) | ||
| slot_history.create_account(self.inherit_sysvar_account_balance(account)) | ||
| }); | ||
| } | ||
|
|
||
|
|
@@ -587,7 +598,7 @@ impl Bank { | |
| .map(|account| SlotHashes::from_account(&account).unwrap()) | ||
| .unwrap_or_default(); | ||
| slot_hashes.add(self.parent_slot, self.parent_hash); | ||
| slot_hashes.create_account(1) | ||
| slot_hashes.create_account(self.inherit_sysvar_account_balance(account)) | ||
| }); | ||
| } | ||
|
|
||
|
|
@@ -622,20 +633,29 @@ impl Bank { | |
| } | ||
|
|
||
| fn update_fees(&self) { | ||
| self.update_sysvar_account(&sysvar::fees::id(), |_| { | ||
| sysvar::fees::create_account(1, &self.fee_calculator) | ||
| self.update_sysvar_account(&sysvar::fees::id(), |account| { | ||
| sysvar::fees::create_account( | ||
| self.inherit_sysvar_account_balance(account), | ||
| &self.fee_calculator, | ||
| ) | ||
| }); | ||
| } | ||
|
|
||
| fn update_rent(&self) { | ||
| self.update_sysvar_account(&sysvar::rent::id(), |_| { | ||
| sysvar::rent::create_account(1, &self.rent_collector.rent) | ||
| self.update_sysvar_account(&sysvar::rent::id(), |account| { | ||
| sysvar::rent::create_account( | ||
| self.inherit_sysvar_account_balance(account), | ||
| &self.rent_collector.rent, | ||
| ) | ||
| }); | ||
| } | ||
|
|
||
| fn update_epoch_schedule(&self) { | ||
| self.update_sysvar_account(&sysvar::epoch_schedule::id(), |_| { | ||
| sysvar::epoch_schedule::create_account(1, &self.epoch_schedule) | ||
| self.update_sysvar_account(&sysvar::epoch_schedule::id(), |account| { | ||
| sysvar::epoch_schedule::create_account( | ||
| self.inherit_sysvar_account_balance(account), | ||
| &self.epoch_schedule, | ||
| ) | ||
| }); | ||
| } | ||
|
|
||
|
|
@@ -644,8 +664,11 @@ impl Bank { | |
| return; | ||
| } | ||
| // if I'm the first Bank in an epoch, ensure stake_history is updated | ||
| self.update_sysvar_account(&sysvar::stake_history::id(), |_| { | ||
| sysvar::stake_history::create_account(1, self.stakes.read().unwrap().history()) | ||
| self.update_sysvar_account(&sysvar::stake_history::id(), |account| { | ||
| sysvar::stake_history::create_account( | ||
| self.inherit_sysvar_account_balance(account), | ||
| self.stakes.read().unwrap().history(), | ||
| ) | ||
| }); | ||
| } | ||
|
|
||
|
|
@@ -680,8 +703,12 @@ impl Bank { | |
| validator_rewards / validator_points as f64, | ||
| storage_rewards / storage_points as f64, | ||
| ); | ||
| self.update_sysvar_account(&sysvar::rewards::id(), |_| { | ||
| sysvar::rewards::create_account(1, validator_point_value, storage_point_value) | ||
| self.update_sysvar_account(&sysvar::rewards::id(), |account| { | ||
| sysvar::rewards::create_account( | ||
| self.inherit_sysvar_account_balance(account), | ||
| validator_point_value, | ||
| storage_point_value, | ||
| ) | ||
| }); | ||
|
|
||
| let validator_rewards = self.pay_validator_rewards(validator_point_value); | ||
|
|
@@ -747,10 +774,13 @@ impl Bank { | |
| } | ||
|
|
||
| pub fn update_recent_blockhashes(&self) { | ||
| self.update_sysvar_account(&sysvar::recent_blockhashes::id(), |_| { | ||
| self.update_sysvar_account(&sysvar::recent_blockhashes::id(), |account| { | ||
| let blockhash_queue = self.blockhash_queue.read().unwrap(); | ||
| let recent_blockhash_iter = blockhash_queue.get_recent_blockhashes(); | ||
| sysvar::recent_blockhashes::create_account_with_data(1, recent_blockhash_iter) | ||
| sysvar::recent_blockhashes::create_account_with_data( | ||
| self.inherit_sysvar_account_balance(account), | ||
| recent_blockhash_iter, | ||
| ) | ||
| }); | ||
| } | ||
|
|
||
|
|
@@ -1896,12 +1926,13 @@ impl Bank { | |
| } | ||
|
|
||
| info!( | ||
| "bank frozen: {} hash: {} accounts_delta: {} signature_count: {} last_blockhash: {}", | ||
| "bank frozen: {} hash: {} accounts_delta: {} signature_count: {} last_blockhash: {} capitalization: {}", | ||
| self.slot(), | ||
| hash, | ||
| accounts_delta_hash.hash, | ||
| self.signature_count(), | ||
| self.last_blockhash(), | ||
| self.capitalization(), | ||
| ); | ||
|
|
||
| info!( | ||
|
|
@@ -3484,6 +3515,45 @@ mod tests { | |
| assert_eq!(bank.get_balance(&pubkey), 500); | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_transfer_to_sysvar() { | ||
| solana_logger::setup(); | ||
| let (genesis_config, mint_keypair) = create_genesis_config(10_000_000); | ||
| let bank = Arc::new(Bank::new(&genesis_config)); | ||
|
|
||
| let normal_pubkey = Pubkey::new_rand(); | ||
| let sysvar_pubkey = sysvar::clock::id(); | ||
| assert_eq!(bank.get_balance(&normal_pubkey), 0); | ||
| assert_eq!(bank.get_balance(&sysvar_pubkey), 1); | ||
|
|
||
| bank.transfer(500, &mint_keypair, &normal_pubkey).unwrap(); | ||
| bank.transfer(500, &mint_keypair, &sysvar_pubkey).unwrap(); | ||
| assert_eq!(bank.get_balance(&normal_pubkey), 500); | ||
| assert_eq!(bank.get_balance(&sysvar_pubkey), 501); | ||
|
|
||
| let bank = Arc::new(new_from_parent(&bank)); | ||
| assert_eq!(bank.get_balance(&normal_pubkey), 500); | ||
| assert_eq!(bank.get_balance(&sysvar_pubkey), 1); | ||
|
|
||
| let bank = Arc::new(Bank::new_from_parent( | ||
| &bank, | ||
| &Pubkey::default(), | ||
| genesis_config | ||
| .epoch_schedule | ||
| .get_first_slot_in_epoch(SYSVAR_BALANCE_ACTIVATION_EPOCH), | ||
| )); | ||
|
|
||
| let normal_pubkey = Pubkey::new_rand(); | ||
| bank.transfer(6000, &mint_keypair, &normal_pubkey).unwrap(); | ||
| bank.transfer(6000, &mint_keypair, &sysvar_pubkey).unwrap(); | ||
| assert_eq!(bank.get_balance(&normal_pubkey), 3561); | ||
| assert_eq!(bank.get_balance(&sysvar_pubkey), 6001); | ||
|
|
||
| let bank = Arc::new(new_from_parent(&bank)); | ||
| assert_eq!(bank.get_balance(&normal_pubkey), 3561); | ||
| assert_eq!(bank.get_balance(&sysvar_pubkey), 6001); | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_bank_deposit() { | ||
| let (genesis_config, _mint_keypair) = create_genesis_config(100); | ||
|
|
||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
My bad... follow-up to #9920, yeah piggybacking on this pr..
11_000_000 is too close to tds tigger timing (*). I think this violates the purpose of
OperatingMode::Preview... ;)let's again move later to some round number of weekday. Or I'm caring too much?
$ cal May 2020 Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 $ pry [5] pry(main)> Time.now + ((11_000_000 - 9834692) / 2.5) # mainnet beta => 2020-05-14 05:40:42 +0900 [7] pry(main)> Time.now + ((14_000_000 - 12953124) / 2.5) # tds => 2020-05-13 16:31:21 +0900 [6] pry(main)> Time.now + ((12_000_000 - 9834692) / 2.5) # another weekend around the world... => 2020-05-18 20:47:29 +0900 [8] pry(main)> Time.now + ((12_500_000 - 9834692) / 2.5) # projected trigger time => 2020-05-21 04:21:46 +0900