From 486f01790c271cf09ac3dbffba0e40e526e81324 Mon Sep 17 00:00:00 2001 From: Trent Nelson Date: Thu, 31 Oct 2019 16:19:49 -0600 Subject: [PATCH] Avoid allocs on update --- runtime/src/bank.rs | 19 +++++++++---------- sdk/src/sysvar/recent_blockhashes.rs | 20 ++++++++++++++------ 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index ab7793319a..318017e2bb 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -543,10 +543,13 @@ impl Bank { .read() .unwrap() .get_recent_blockhashes(sysvar::recent_blockhashes::MAX_ENTRIES); - self.store_account( - &sysvar::recent_blockhashes::id(), - &sysvar::recent_blockhashes::create_account(1, recent_blockhashes), - ); + let id = sysvar::recent_blockhashes::id(); + let mut account = self + .get_account(&id) + .or_else(|| Some(sysvar::recent_blockhashes::create_account(1))) + .unwrap(); + sysvar::recent_blockhashes::update_account(&mut account, recent_blockhashes).unwrap(); + self.store_account(&id, &account); } // If the point values are not `normal`, bring them back into range and @@ -3360,17 +3363,13 @@ mod tests { fn test_recent_blockhashes_sysvar() { let (genesis_block, _mint_keypair) = create_genesis_block(500); let mut bank = Arc::new(Bank::new(&genesis_block)); - let bhq_account = bank - .get_account(&sysvar::recent_blockhashes::id()) - .unwrap(); + let bhq_account = bank.get_account(&sysvar::recent_blockhashes::id()).unwrap(); let recent_blockhashes = sysvar::recent_blockhashes::RecentBlockhashes::from_account(&bhq_account).unwrap(); assert_eq!(recent_blockhashes.len(), 1); goto_end_of_slot(Arc::get_mut(&mut bank).unwrap()); let bank = Arc::new(new_from_parent(&bank)); - let bhq_account = bank - .get_account(&sysvar::recent_blockhashes::id()) - .unwrap(); + let bhq_account = bank.get_account(&sysvar::recent_blockhashes::id()).unwrap(); let recent_blockhashes = sysvar::recent_blockhashes::RecentBlockhashes::from_account(&bhq_account).unwrap(); assert_eq!(recent_blockhashes.len(), 2); diff --git a/sdk/src/sysvar/recent_blockhashes.rs b/sdk/src/sysvar/recent_blockhashes.rs index 1a8742592d..e3902b2956 100644 --- a/sdk/src/sysvar/recent_blockhashes.rs +++ b/sdk/src/sysvar/recent_blockhashes.rs @@ -46,10 +46,18 @@ impl Deref for RecentBlockhashes { } } -pub fn create_account(lamports: u64, recent_blockhashes: Vec) -> Account { - let mut account = Account::new(lamports, RecentBlockhashes::size_of(), &sysvar::id()); +pub fn create_account(lamports: u64) -> Account { + Account::new(lamports, RecentBlockhashes::size_of(), &sysvar::id()) +} + +pub fn update_account(account: &mut Account, recent_blockhashes: Vec) -> Option<()> { let recent_blockhashes = RecentBlockhashes(recent_blockhashes); - recent_blockhashes.to_account(&mut account).unwrap(); + recent_blockhashes.to_account(account) +} + +pub fn create_account_with_data(lamports: u64, recent_blockhashes: Vec) -> Account { + let mut account = create_account(lamports); + update_account(&mut account, recent_blockhashes).unwrap(); account } @@ -60,14 +68,14 @@ mod tests { #[test] fn test_create_account_empty() { - let account = create_account(42, vec![]); + let account = create_account_with_data(42, vec![]); let recent_blockhashes = RecentBlockhashes::from_account(&account).unwrap(); assert_eq!(recent_blockhashes, RecentBlockhashes::default()); } #[test] fn test_create_account_full() { - let account = create_account(42, vec![Hash::default(); MAX_ENTRIES]); + let account = create_account_with_data(42, vec![Hash::default(); MAX_ENTRIES]); let recent_blockhashes = RecentBlockhashes::from_account(&account).unwrap(); assert_eq!(recent_blockhashes.len(), MAX_ENTRIES); } @@ -75,7 +83,7 @@ mod tests { #[test] #[should_panic] fn test_create_account_too_big() { - let account = create_account(42, vec![Hash::default(); MAX_ENTRIES + 1]); + let account = create_account_with_data(42, vec![Hash::default(); MAX_ENTRIES + 1]); RecentBlockhashes::from_account(&account).unwrap(); } }