From ac066f38465a936c4dd9a8ac1ba030cd91865772 Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Thu, 28 May 2020 16:36:52 +0900 Subject: [PATCH] Fetch consistent state in mempool functions We found that mempool mis-calculates sequence in the TPS test. After fixing the mempool to read consistent state, mempool calculates sequence well. --- core/src/client/test_client.rs | 6 ++++++ core/src/miner/mem_pool.rs | 10 ++++++---- core/src/miner/miner.rs | 20 ++++++++++++-------- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/core/src/client/test_client.rs b/core/src/client/test_client.rs index 8b61a8f443..a33eddedd4 100644 --- a/core/src/client/test_client.rs +++ b/core/src/client/test_client.rs @@ -392,6 +392,9 @@ impl AccountData for TestBlockChainClient { fn seq(&self, address: &Address, id: BlockId) -> Option { match id { BlockId::Latest => Some(self.seqs.read().get(address).cloned().unwrap_or(0)), + BlockId::Hash(hash) if hash == *self.last_hash.read() => { + Some(self.seqs.read().get(address).cloned().unwrap_or(0)) + } _ => None, } } @@ -401,6 +404,9 @@ impl AccountData for TestBlockChainClient { StateOrBlock::Block(BlockId::Latest) | StateOrBlock::State(_) => { Some(self.balances.read().get(address).cloned().unwrap_or(0)) } + StateOrBlock::Block(BlockId::Hash(hash)) if hash == *self.last_hash.read() => { + Some(self.balances.read().get(address).cloned().unwrap_or(0)) + } _ => None, } } diff --git a/core/src/miner/mem_pool.rs b/core/src/miner/mem_pool.rs index 8729639c0e..880171ab11 100644 --- a/core/src/miner/mem_pool.rs +++ b/core/src/miner/mem_pool.rs @@ -33,7 +33,7 @@ use super::mem_pool_types::{ use super::TransactionImportResult; use crate::client::{AccountData, BlockChainTrait}; use crate::transaction::{PendingSignedTransactions, SignedTransaction}; -use crate::Error as CoreError; +use crate::{BlockId, Error as CoreError}; const DEFAULT_POOLING_PERIOD: BlockNumber = 128; @@ -429,12 +429,14 @@ impl MemPool { // Recover MemPool state from db stored data pub fn recover_from_db(&mut self, client: &C) { + let recover_block_hash = client.chain_info().best_block_hash; + let recover_block_id = BlockId::Hash(recover_block_hash); let fetch_account = |p: &Public| -> AccountDetails { let address = public_to_address(p); - let a = client.latest_regular_key_owner(&address).unwrap_or(address); + let a = client.regular_key_owner(&address, recover_block_id.into()).unwrap_or(address); AccountDetails { - seq: client.latest_seq(&a), - balance: client.latest_balance(&a), + seq: client.seq(&a, recover_block_id).expect("Read from best block"), + balance: client.balance(&a, recover_block_id.into()).expect("Read from best block"), } }; let by_hash = backup::recover_to_data(self.db.as_ref()); diff --git a/core/src/miner/miner.rs b/core/src/miner/miner.rs index ccf5b791f9..270deb29f0 100644 --- a/core/src/miner/miner.rs +++ b/core/src/miner/miner.rs @@ -460,10 +460,10 @@ impl Miner { let fetch_account = |p: &Public| -> AccountDetails { let address = public_to_address(p); - let a = client.latest_regular_key_owner(&address).unwrap_or(address); + let a = client.regular_key_owner(&address, BlockId::Hash(best_header.hash()).into()).unwrap_or(address); AccountDetails { - seq: client.latest_seq(&a), - balance: client.latest_balance(&a), + seq: client.seq(&a, BlockId::Hash(best_header.hash())).expect("Read from best block"), + balance: client.balance(&a, BlockId::Hash(best_header.hash()).into()).expect("Read from best block"), } }; @@ -718,10 +718,12 @@ impl Miner { }; let block = open_block.close(&parent_header, &parent_common_params, term_common_params.as_ref())?; + let best_block_hash = chain.chain_info().best_block_hash; + let block_id = BlockId::Hash(best_block_hash); let fetch_seq = |p: &Public| { let address = public_to_address(p); - let a = chain.latest_regular_key_owner(&address).unwrap_or(address); - chain.latest_seq(&a) + let a = chain.regular_key_owner(&address, block_id.into()).unwrap_or(address); + chain.seq(&a, block_id).expect("Read from best block") }; { @@ -903,13 +905,15 @@ impl MinerService for Miner { // ...and at the end remove the old ones { + let current_block_hash = chain.chain_info().best_block_hash; + let block_id = BlockId::Hash(current_block_hash); let fetch_account = |p: &Public| { let address = public_to_address(p); - let a = chain.latest_regular_key_owner(&address).unwrap_or(address); + let a = chain.regular_key_owner(&address, block_id.into()).unwrap_or(address); AccountDetails { - seq: chain.latest_seq(&a), - balance: chain.latest_balance(&a), + seq: chain.seq(&a, block_id).expect("Read from best block"), + balance: chain.balance(&a, block_id.into()).expect("Read from best block"), } }; let current_block_number = chain.chain_info().best_block_number;