blockchain cleanup
This commit is contained in:
parent
f9457cc584
commit
49fa99ae05
@ -216,8 +216,8 @@ impl BlockChain {
|
|||||||
self._tree_route((from_details, from), (to_details, to))
|
self._tree_route((from_details, from), (to_details, to))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Same as `tree_route` function, but returns a root between blocks that may not
|
/// Same as `tree_route` function, but returns a route
|
||||||
/// be in database yet
|
/// between blocks that might not yet be in database.
|
||||||
fn _tree_route(&self, from: (BlockDetails, H256), to: (BlockDetails, H256)) -> TreeRoute {
|
fn _tree_route(&self, from: (BlockDetails, H256), to: (BlockDetails, H256)) -> TreeRoute {
|
||||||
let mut from_branch = vec![];
|
let mut from_branch = vec![];
|
||||||
let mut to_branch = vec![];
|
let mut to_branch = vec![];
|
||||||
@ -272,11 +272,37 @@ impl BlockChain {
|
|||||||
// create views onto rlp
|
// create views onto rlp
|
||||||
let block = BlockView::new(bytes);
|
let block = BlockView::new(bytes);
|
||||||
let header = block.header_view();
|
let header = block.header_view();
|
||||||
|
let hash = block.sha3();
|
||||||
|
|
||||||
if self.is_known(&header.sha3()) {
|
if self.is_known(&hash) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// store block in db
|
||||||
|
self.blocks_db.put(&hash, &bytes).unwrap();
|
||||||
|
let (batch, new_best) = self.block_to_extras_insert_batch(bytes);
|
||||||
|
|
||||||
|
// update best block
|
||||||
|
let mut best_block = self.best_block.borrow_mut();
|
||||||
|
if let Some(b) = new_best {
|
||||||
|
*best_block = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
// update caches
|
||||||
|
let mut write = self.block_details.borrow_mut();
|
||||||
|
write.remove(&header.parent_hash());
|
||||||
|
|
||||||
|
// update extras database
|
||||||
|
self.extras_db.write(batch).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Transforms block into WriteBatch that may be written into database
|
||||||
|
/// Additionally, if it's new best block it returns new best block object.
|
||||||
|
fn block_to_extras_insert_batch(&self, bytes: &[u8]) -> (WriteBatch, Option<BestBlock>) {
|
||||||
|
// create views onto rlp
|
||||||
|
let block = BlockView::new(bytes);
|
||||||
|
let header = block.header_view();
|
||||||
|
|
||||||
// prepare variables
|
// prepare variables
|
||||||
let hash = block.sha3();
|
let hash = block.sha3();
|
||||||
let mut parent_details = self.block_details(&header.parent_hash()).expect("Invalid parent hash.");
|
let mut parent_details = self.block_details(&header.parent_hash()).expect("Invalid parent hash.");
|
||||||
@ -292,65 +318,54 @@ impl BlockChain {
|
|||||||
children: vec![]
|
children: vec![]
|
||||||
};
|
};
|
||||||
|
|
||||||
// store block in db
|
|
||||||
self.blocks_db.put(&hash, &bytes).unwrap();
|
|
||||||
|
|
||||||
let batch = WriteBatch::new();
|
|
||||||
// prepare update for extra details
|
// prepare update for extra details
|
||||||
{
|
let batch = WriteBatch::new();
|
||||||
// insert new block details
|
|
||||||
batch.put_extras(&hash, &details);
|
|
||||||
|
|
||||||
// update parent details
|
// insert new block details
|
||||||
parent_details.children.push(hash.clone());
|
batch.put_extras(&hash, &details);
|
||||||
batch.put_extras(&parent_hash, &parent_details);
|
|
||||||
|
// update parent details
|
||||||
|
parent_details.children.push(hash.clone());
|
||||||
|
batch.put_extras(&parent_hash, &parent_details);
|
||||||
|
|
||||||
|
// if it's not new best block, just return
|
||||||
|
if !is_new_best {
|
||||||
|
return (batch, None);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if its new best block we need to make sure that all ancestors
|
// if its new best block we need to make sure that all ancestors
|
||||||
// are moved to "canon chain"
|
// are moved to "canon chain"
|
||||||
if is_new_best {
|
// find the route between old best block and the new one
|
||||||
// find the route between old best block and the new one
|
let best_hash = self.best_block_hash();
|
||||||
let best_hash = self.best_block_hash();
|
let best_details = self.block_details(&best_hash).expect("best block hash is invalid!");
|
||||||
let best_details = self.block_details(&best_hash).expect("best block hash is invalid!");
|
let route = self._tree_route((best_details, best_hash), (details, hash.clone()));
|
||||||
let route = self._tree_route((best_details, best_hash), (details, hash.clone()));
|
|
||||||
|
|
||||||
match route.blocks.len() {
|
match route.blocks.len() {
|
||||||
// its our parent
|
// its our parent
|
||||||
1 => batch.put_extras(&header.number(), &hash),
|
1 => batch.put_extras(&header.number(), &hash),
|
||||||
// it is a fork
|
// it is a fork
|
||||||
i if i > 1 => {
|
i if i > 1 => {
|
||||||
let ancestor_number = self.block_number(&route.ancestor).unwrap();
|
let ancestor_number = self.block_number(&route.ancestor).unwrap();
|
||||||
let start_number = ancestor_number + U256::from(1u8);
|
let start_number = ancestor_number + U256::from(1u8);
|
||||||
for (index, hash) in route.blocks.iter().skip(route.index).enumerate() {
|
for (index, hash) in route.blocks.iter().skip(route.index).enumerate() {
|
||||||
batch.put_extras(&(start_number + U256::from(index as u64)), hash);
|
batch.put_extras(&(start_number + U256::from(index as u64)), hash);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// route.len() could be 0 only if inserted block is best block,
|
// route.len() could be 0 only if inserted block is best block,
|
||||||
// and this is not possible at this stage
|
// and this is not possible at this stage
|
||||||
_ => { unreachable!(); }
|
_ => { unreachable!(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
// this is new extras db
|
// this is new extras db
|
||||||
batch.put(b"best", &hash).unwrap();
|
batch.put(b"best", &hash).unwrap();
|
||||||
}
|
|
||||||
|
|
||||||
// apply update
|
let best_block = BestBlock {
|
||||||
{
|
hash: hash,
|
||||||
// update local caches
|
number: header.number(),
|
||||||
let mut best_block = self.best_block.borrow_mut();
|
total_difficulty: total_difficulty
|
||||||
if is_new_best {
|
};
|
||||||
best_block.hash = hash;
|
|
||||||
best_block.number = header.number();
|
|
||||||
best_block.total_difficulty = total_difficulty;
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove outdated cached parent details
|
(batch, Some(best_block))
|
||||||
let mut write = self.block_details.borrow_mut();
|
|
||||||
write.remove(&parent_hash);
|
|
||||||
|
|
||||||
// update extras database
|
|
||||||
self.extras_db.write(batch).unwrap();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the given block is known
|
/// Returns true if the given block is known
|
||||||
|
Loading…
Reference in New Issue
Block a user