-
Notifications
You must be signed in to change notification settings - Fork 4.5k
Fix bad rent in Bank::deposit as if since epoch 0 #10468
Changes from all commits
097c864
2df4e88
54ce39e
ce709a9
fd15af6
e4ebe2e
7d37919
42fd2c2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -139,8 +139,9 @@ impl Accounts { | |
let (account, rent) = | ||
AccountsDB::load(storage, ancestors, accounts_index, key) | ||
.map(|(mut account, _)| { | ||
if message.is_writable(i) && !account.executable { | ||
let rent_due = rent_collector.update(&key, &mut account); | ||
if message.is_writable(i) { | ||
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. I removed |
||
let rent_due = rent_collector | ||
.collect_from_existing_account(&key, &mut account); | ||
(account, rent_due) | ||
} else { | ||
(account, 0) | ||
|
@@ -736,8 +737,7 @@ impl Accounts { | |
); | ||
if message.is_writable(i) { | ||
if account.rent_epoch == 0 { | ||
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. Well, these inconsistent predicates are concerning me. Ideally, I want to put everything into |
||
account.rent_epoch = rent_collector.epoch; | ||
acc.2 += rent_collector.update(&key, account); | ||
acc.2 += rent_collector.collect_from_created_account(&key, account); | ||
} | ||
accounts.push((key, &*account)); | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1155,18 +1155,13 @@ impl Bank { | |
.unwrap() | ||
.genesis_hash(&genesis_config.hash(), &self.fee_calculator); | ||
|
||
self.hashes_per_tick = genesis_config.poh_config.hashes_per_tick; | ||
self.ticks_per_slot = genesis_config.ticks_per_slot; | ||
self.ns_per_slot = genesis_config.poh_config.target_tick_duration.as_nanos() | ||
* genesis_config.ticks_per_slot as u128; | ||
self.hashes_per_tick = genesis_config.hashes_per_tick(); | ||
self.ticks_per_slot = genesis_config.ticks_per_slot(); | ||
self.ns_per_slot = genesis_config.ns_per_slot(); | ||
self.genesis_creation_time = genesis_config.creation_time; | ||
self.unused = genesis_config.unused; | ||
self.max_tick_height = (self.slot + 1) * self.ticks_per_slot; | ||
self.slots_per_year = years_as_slots( | ||
1.0, | ||
&genesis_config.poh_config.target_tick_duration, | ||
self.ticks_per_slot, | ||
); | ||
self.slots_per_year = genesis_config.slots_per_year(); | ||
|
||
self.epoch_schedule = genesis_config.epoch_schedule; | ||
|
||
|
@@ -2064,7 +2059,9 @@ impl Bank { | |
// parallelize? | ||
let mut rent = 0; | ||
for (pubkey, mut account) in accounts { | ||
rent += self.rent_collector.update(&pubkey, &mut account); | ||
rent += self | ||
.rent_collector | ||
.collect_from_existing_account(&pubkey, &mut account); | ||
// Store all of them unconditionally to purge old AppendVec, | ||
// even if collected rent is 0 (= not updated). | ||
self.store_account(&pubkey, &account); | ||
|
@@ -2501,10 +2498,25 @@ impl Bank { | |
|
||
pub fn deposit(&self, pubkey: &Pubkey, lamports: u64) { | ||
let mut account = self.get_account(pubkey).unwrap_or_default(); | ||
self.collected_rent.fetch_add( | ||
self.rent_collector.update(pubkey, &mut account), | ||
Ordering::Relaxed, | ||
); | ||
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. Well, there were two bugs..:
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. This is fixed by not doing rent collection at all as the new behavior. |
||
|
||
let should_be_in_new_behavior = match self.operating_mode() { | ||
OperatingMode::Development => true, | ||
OperatingMode::Preview => self.epoch() >= Epoch::max_value(), | ||
OperatingMode::Stable => self.epoch() >= Epoch::max_value(), | ||
}; | ||
|
||
// don't collect rents if we're in the new behavior; | ||
// in genral, it's not worthwhile to account for rents outside the runtime (transactions) | ||
// there are too many and subtly nuanced modification codepaths | ||
if !should_be_in_new_behavior { | ||
// previously we're too much collecting rents as if it existed since epoch 0... | ||
self.collected_rent.fetch_add( | ||
self.rent_collector | ||
.collect_from_existing_account(pubkey, &mut account), | ||
Ordering::Relaxed, | ||
); | ||
} | ||
|
||
account.lamports += lamports; | ||
self.store_account(pubkey, &account); | ||
} | ||
|
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 sounds good to me. It'd be great to get a comment from @rwalker-com to be sure we aren't missing anything. 🙏
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.
lgtm, and this is consistent with what I intended, but the call flow to load and store accounts is pretty tortured, and has many paths. were the bank to document which APIs were for runtime access of accounts, it would go a long way to making these easier to reason about.
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.
@rwalker-com(UPDATED) Yeah, I think so too... I'll address the documetation work along with #10426Anyway, thanks for confirming this pr!
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.
Err, wrong user @rwalker-apple...