fix merging bugs
This commit is contained in:
parent
97eb311cb0
commit
bad02d65a1
@ -278,7 +278,7 @@ impl Client {
|
|||||||
Ok(locked_block)
|
Ok(locked_block)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn calculate_enacted_retracted(&self, import_results: Vec<ImportRoute>) -> (Vec<H256>, Vec<H256>) {
|
fn calculate_enacted_retracted(&self, import_results: &[ImportRoute]) -> (Vec<H256>, Vec<H256>) {
|
||||||
fn map_to_vec(map: Vec<(H256, bool)>) -> Vec<H256> {
|
fn map_to_vec(map: Vec<(H256, bool)>) -> Vec<H256> {
|
||||||
map.into_iter().map(|(k, _v)| k).collect()
|
map.into_iter().map(|(k, _v)| k).collect()
|
||||||
}
|
}
|
||||||
@ -288,12 +288,12 @@ impl Client {
|
|||||||
// could be retracted in import `k+1`. This is why to understand if after all inserts
|
// could be retracted in import `k+1`. This is why to understand if after all inserts
|
||||||
// the block is enacted or retracted we iterate over all routes and at the end final state
|
// the block is enacted or retracted we iterate over all routes and at the end final state
|
||||||
// will be in the hashmap
|
// will be in the hashmap
|
||||||
let map = import_results.into_iter().fold(HashMap::new(), |mut map, route| {
|
let map = import_results.iter().fold(HashMap::new(), |mut map, route| {
|
||||||
for hash in route.enacted {
|
for hash in &route.enacted {
|
||||||
map.insert(hash, true);
|
map.insert(hash.clone(), true);
|
||||||
}
|
}
|
||||||
for hash in route.retracted {
|
for hash in &route.retracted {
|
||||||
map.insert(hash, false);
|
map.insert(hash.clone(), false);
|
||||||
}
|
}
|
||||||
map
|
map
|
||||||
});
|
});
|
||||||
@ -330,36 +330,10 @@ impl Client {
|
|||||||
invalid_blocks.insert(header.hash());
|
invalid_blocks.insert(header.hash());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
let closed_block = closed_block.unwrap();
|
||||||
imported_blocks.push(header.hash());
|
imported_blocks.push(header.hash());
|
||||||
|
|
||||||
// Are we committing an era?
|
let route = self.commit_block(closed_block, &header.hash(), &block.bytes);
|
||||||
let ancient = if header.number() >= HISTORY {
|
|
||||||
let n = header.number() - HISTORY;
|
|
||||||
Some((n, self.chain.block_hash(n).unwrap()))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
// Commit results
|
|
||||||
let closed_block = closed_block.unwrap();
|
|
||||||
let receipts = closed_block.block().receipts().clone();
|
|
||||||
let traces = From::from(closed_block.block().traces().clone().unwrap_or_else(Vec::new));
|
|
||||||
|
|
||||||
closed_block.drain()
|
|
||||||
.commit(header.number(), &header.hash(), ancient)
|
|
||||||
.expect("State DB commit failed.");
|
|
||||||
|
|
||||||
// And update the chain after commit to prevent race conditions
|
|
||||||
// (when something is in chain but you are not able to fetch details)
|
|
||||||
let route = self.chain.insert_block(&block.bytes, receipts);
|
|
||||||
self.tracedb.import(TraceImportRequest {
|
|
||||||
traces: traces,
|
|
||||||
block_hash: header.hash(),
|
|
||||||
block_number: header.number(),
|
|
||||||
enacted: route.enacted.clone(),
|
|
||||||
retracted: route.retracted.len()
|
|
||||||
});
|
|
||||||
|
|
||||||
import_results.push(route);
|
import_results.push(route);
|
||||||
|
|
||||||
self.report.write().unwrap().accrue_block(&block);
|
self.report.write().unwrap().accrue_block(&block);
|
||||||
@ -380,7 +354,7 @@ impl Client {
|
|||||||
|
|
||||||
{
|
{
|
||||||
if !imported_blocks.is_empty() && self.block_queue.queue_info().is_empty() {
|
if !imported_blocks.is_empty() && self.block_queue.queue_info().is_empty() {
|
||||||
let (enacted, retracted) = self.calculate_enacted_retracted(import_results);
|
let (enacted, retracted) = self.calculate_enacted_retracted(&import_results);
|
||||||
|
|
||||||
if self.queue_info().is_empty() {
|
if self.queue_info().is_empty() {
|
||||||
self.miner.chain_new_blocks(self, &imported_blocks, &invalid_blocks, &enacted, &retracted);
|
self.miner.chain_new_blocks(self, &imported_blocks, &invalid_blocks, &enacted, &retracted);
|
||||||
@ -391,19 +365,50 @@ impl Client {
|
|||||||
invalid: invalid_blocks,
|
invalid: invalid_blocks,
|
||||||
enacted: enacted,
|
enacted: enacted,
|
||||||
retracted: retracted,
|
retracted: retracted,
|
||||||
|
sealed: Vec::new(),
|
||||||
})).unwrap_or_else(|e| warn!("Error sending IO notification: {:?}", e));
|
})).unwrap_or_else(|e| warn!("Error sending IO notification: {:?}", e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
if self.chain_info().best_block_hash != original_best {
|
||||||
if self.chain_info().best_block_hash != original_best {
|
self.miner.update_sealing(self);
|
||||||
self.miner.update_sealing(self);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
imported
|
imported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn commit_block<B>(&self, block: B, hash: &H256, block_data: &Bytes) -> ImportRoute where B: IsBlock + Drain {
|
||||||
|
let number = block.header().number();
|
||||||
|
// Are we committing an era?
|
||||||
|
let ancient = if number >= HISTORY {
|
||||||
|
let n = number - HISTORY;
|
||||||
|
Some((n, self.chain.block_hash(n).unwrap()))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
// Commit results
|
||||||
|
let receipts = block.receipts().clone();
|
||||||
|
let traces = From::from(block.traces().clone().unwrap_or_else(Vec::new));
|
||||||
|
|
||||||
|
// CHECK! I *think* this is fine, even if the state_root is equal to another
|
||||||
|
// already-imported block of the same number.
|
||||||
|
// TODO: Prove it with a test.
|
||||||
|
block.drain().commit(number, hash, ancient).expect("State DB commit failed.");
|
||||||
|
|
||||||
|
// And update the chain after commit to prevent race conditions
|
||||||
|
// (when something is in chain but you are not able to fetch details)
|
||||||
|
let route = self.chain.insert_block(block_data, receipts);
|
||||||
|
self.tracedb.import(TraceImportRequest {
|
||||||
|
traces: traces,
|
||||||
|
block_hash: hash.clone(),
|
||||||
|
block_number: number,
|
||||||
|
enacted: route.enacted.clone(),
|
||||||
|
retracted: route.retracted.len()
|
||||||
|
});
|
||||||
|
route
|
||||||
|
}
|
||||||
|
|
||||||
/// Import transactions from the IO queue
|
/// Import transactions from the IO queue
|
||||||
pub fn import_queued_transactions(&self, transactions: &[Bytes]) -> usize {
|
pub fn import_queued_transactions(&self, transactions: &[Bytes]) -> usize {
|
||||||
let _timer = PerfTimer::new("import_queued_transactions");
|
let _timer = PerfTimer::new("import_queued_transactions");
|
||||||
@ -867,6 +872,39 @@ impl MiningBlockChainClient for Client {
|
|||||||
fn vm_factory(&self) -> &EvmFactory {
|
fn vm_factory(&self) -> &EvmFactory {
|
||||||
&self.vm_factory
|
&self.vm_factory
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn import_sealed_block(&self, block: SealedBlock) -> ImportResult {
|
||||||
|
let _import_lock = self.import_lock.lock();
|
||||||
|
let _timer = PerfTimer::new("import_sealed_block");
|
||||||
|
|
||||||
|
let original_best = self.chain_info().best_block_hash;
|
||||||
|
|
||||||
|
let h = block.header().hash();
|
||||||
|
let number = block.header().number();
|
||||||
|
|
||||||
|
let block_data = block.rlp_bytes();
|
||||||
|
let route = self.commit_block(block, &h, &block_data);
|
||||||
|
trace!(target: "client", "Imported sealed block #{} ({})", number, h);
|
||||||
|
|
||||||
|
{
|
||||||
|
let (enacted, retracted) = self.calculate_enacted_retracted(&[route]);
|
||||||
|
self.miner.chain_new_blocks(self, &[h.clone()], &[], &enacted, &retracted);
|
||||||
|
|
||||||
|
self.io_channel.send(NetworkIoMessage::User(SyncMessage::NewChainBlocks {
|
||||||
|
imported: vec![h.clone()],
|
||||||
|
invalid: vec![],
|
||||||
|
enacted: enacted,
|
||||||
|
retracted: retracted,
|
||||||
|
sealed: vec![h.clone()],
|
||||||
|
})).unwrap_or_else(|e| warn!("Error sending IO notification: {:?}", e));
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.chain_info().best_block_hash != original_best {
|
||||||
|
self.miner.update_sealing(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(h)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MayPanic for Client {
|
impl MayPanic for Client {
|
||||||
|
Loading…
Reference in New Issue
Block a user