Skip to content

Commit e70ca41

Browse files
committed
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.
1 parent 31dbd9f commit e70ca41

File tree

4 files changed

+36
-13
lines changed

4 files changed

+36
-13
lines changed

core/src/client/test_client.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,9 @@ impl AccountData for TestBlockChainClient {
384384
fn seq(&self, address: &Address, id: BlockId) -> Option<u64> {
385385
match id {
386386
BlockId::Latest => Some(self.seqs.read().get(address).cloned().unwrap_or(0)),
387+
BlockId::Hash(hash) if hash == *self.last_hash.read() => {
388+
Some(self.seqs.read().get(address).cloned().unwrap_or(0))
389+
}
387390
_ => None,
388391
}
389392
}
@@ -393,6 +396,9 @@ impl AccountData for TestBlockChainClient {
393396
StateOrBlock::Block(BlockId::Latest) | StateOrBlock::State(_) => {
394397
Some(self.balances.read().get(address).cloned().unwrap_or(0))
395398
}
399+
StateOrBlock::Block(BlockId::Hash(hash)) if hash == *self.last_hash.read() => {
400+
Some(self.balances.read().get(address).cloned().unwrap_or(0))
401+
}
396402
_ => None,
397403
}
398404
}

core/src/miner/mem_pool.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use super::TransactionImportResult;
2323
use crate::client::{AccountData, BlockChainTrait};
2424
use crate::miner::fetch_account_creator;
2525
use crate::transaction::{PendingSignedTransactions, SignedTransaction};
26-
use crate::Error as CoreError;
26+
use crate::{BlockId, Error as CoreError};
2727
use ckey::{public_to_address, Public};
2828
use ctypes::errors::{HistoryError, RuntimeError, SyntaxError};
2929
use ctypes::{BlockNumber, TxHash};
@@ -430,7 +430,12 @@ impl MemPool {
430430

431431
// Recover MemPool state from db stored data
432432
pub fn recover_from_db<C: AccountData + BlockChainTrait>(&mut self, client: &C) {
433-
let fetch_account = fetch_account_creator(client);
433+
let recover_block_id = {
434+
let recover_block_hash = client.chain_info().best_block_hash;
435+
BlockId::Hash(recover_block_hash)
436+
};
437+
let fetch_account = fetch_account_creator(client, recover_block_id);
438+
434439
let by_hash = backup::recover_to_data(self.db.as_ref());
435440

436441
let recover_block_number = client.chain_info().best_block_number;
@@ -1524,7 +1529,7 @@ pub mod test {
15241529
let db = Arc::new(kvdb_memorydb::create(crate::db::NUM_COLUMNS.unwrap_or(0)));
15251530
let mut mem_pool = MemPool::with_limits(8192, usize::max_value(), 3, db.clone(), Default::default());
15261531

1527-
let fetch_account = fetch_account_creator(&test_client);
1532+
let fetch_account = fetch_account_creator(&test_client, BlockId::Latest);
15281533
let no_timelock = TxTimelock {
15291534
block: None,
15301535
timestamp: None,
@@ -1647,7 +1652,7 @@ pub mod test {
16471652
txs: Vec<SignedTransaction>,
16481653
origin: TxOrigin,
16491654
) -> Vec<Result<TransactionImportResult, Error>> {
1650-
let fetch_account = fetch_account_creator(test_client);
1655+
let fetch_account = fetch_account_creator(test_client, BlockId::Latest);
16511656
let no_timelock = TxTimelock {
16521657
block: None,
16531658
timestamp: None,
@@ -1782,7 +1787,7 @@ pub mod test {
17821787
let db = Arc::new(kvdb_memorydb::create(crate::db::NUM_COLUMNS.unwrap_or(0)));
17831788
let mut mem_pool = MemPool::with_limits(8192, usize::max_value(), 3, db, Default::default());
17841789

1785-
let fetch_account = fetch_account_creator(&test_client);
1790+
let fetch_account = fetch_account_creator(&test_client, BlockId::Latest);
17861791
let keypair = Random.generate().unwrap();
17871792
let address = public_to_address(keypair.public());
17881793
println!("! {}", address);

core/src/miner/miner.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,8 @@ impl Miner {
461461
})
462462
.collect();
463463

464-
let fetch_account = fetch_account_creator(client);
464+
let block_id = BlockId::Hash(best_header.hash());
465+
let fetch_account = fetch_account_creator(client, block_id);
465466

466467
let insertion_results = mem_pool.add(to_insert, current_block_number, current_timestamp, &fetch_account);
467468

@@ -709,10 +710,14 @@ impl Miner {
709710
let term_common_params = chain.term_common_params(parent_hash.into());
710711
let block = open_block.close(&parent_header, term_common_params.as_ref())?;
711712

713+
let block_id = {
714+
let best_block_hash = chain.chain_info().best_block_hash;
715+
BlockId::Hash(best_block_hash)
716+
};
712717
let fetch_seq = |p: &Public| {
713718
let address = public_to_address(p);
714-
let a = chain.latest_regular_key_owner(&address).unwrap_or(address);
715-
chain.latest_seq(&a)
719+
let a = chain.regular_key_owner(&address, block_id.into()).unwrap_or(address);
720+
chain.seq(&a, block_id).expect("Read from best block")
716721
};
717722

718723
{
@@ -886,7 +891,11 @@ impl MinerService for Miner {
886891

887892
// ...and at the end remove the old ones
888893
{
889-
let fetch_account = fetch_account_creator(chain);
894+
let block_id = {
895+
let current_block_hash = chain.chain_info().best_block_hash;
896+
BlockId::Hash(current_block_hash)
897+
};
898+
let fetch_account = fetch_account_creator(chain, block_id);
890899
let current_block_number = chain.chain_info().best_block_number;
891900
let current_timestamp = chain.chain_info().best_block_timestamp;
892901
let mut mem_pool = self.mem_pool.write();

core/src/miner/mod.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -197,13 +197,16 @@ pub enum TransactionImportResult {
197197
#[cfg(all(feature = "nightly", test))]
198198
mod mem_pool_benches;
199199

200-
fn fetch_account_creator<'c>(client: &'c dyn AccountData) -> impl Fn(&Public) -> AccountDetails + 'c {
200+
fn fetch_account_creator<'c>(
201+
client: &'c dyn AccountData,
202+
block_id: BlockId,
203+
) -> impl Fn(&Public) -> AccountDetails + 'c {
201204
move |public: &Public| {
202205
let address = public_to_address(public);
203-
let a = client.latest_regular_key_owner(&address).unwrap_or(address);
206+
let a = client.regular_key_owner(&address, block_id.into()).unwrap_or(address);
204207
AccountDetails {
205-
seq: client.latest_seq(&a),
206-
balance: client.latest_balance(&a),
208+
seq: client.seq(&a, block_id).expect("We are querying sequence using trusted block id"),
209+
balance: client.balance(&a, block_id.into()).expect("We are querying balance using trusted block id"),
207210
}
208211
}
209212
}

0 commit comments

Comments
 (0)