Fix queue flush and add working tests.
This commit is contained in:
parent
a43ca9ae34
commit
41508cbd50
@ -188,6 +188,7 @@ impl<'x, 'y> OpenBlock<'x, 'y> {
|
||||
// info!("env_info says gas_used={}", env_info.gas_used);
|
||||
match self.block.state.apply(&env_info, self.engine, &t) {
|
||||
Ok(receipt) => {
|
||||
flushln!("Transaction executed {:?}", receipt);
|
||||
self.block.archive_set.insert(h.unwrap_or_else(||t.hash()));
|
||||
self.block.archive.push(Entry { transaction: t, receipt: receipt });
|
||||
Ok(&self.block.archive.last().unwrap().receipt)
|
||||
|
@ -19,11 +19,16 @@ pub struct BlockQueueInfo {
|
||||
pub unverified_queue_size: usize,
|
||||
/// Number of verified queued blocks pending import
|
||||
pub verified_queue_size: usize,
|
||||
/// Number of blocks being verified
|
||||
pub verifying_queue_size: usize,
|
||||
}
|
||||
|
||||
impl BlockQueueInfo {
|
||||
/// The total size of the queues.
|
||||
pub fn total_queue_size(&self) -> usize { self.unverified_queue_size + self.verified_queue_size }
|
||||
pub fn total_queue_size(&self) -> usize { self.unverified_queue_size + self.verified_queue_size + self.verifying_queue_size }
|
||||
|
||||
/// The size of the unverified and verifying queues.
|
||||
pub fn incomplete_queue_size(&self) -> usize { self.unverified_queue_size + self.verifying_queue_size }
|
||||
}
|
||||
|
||||
/// A queue of blocks. Sits between network or other I/O and the BlockChain.
|
||||
@ -115,7 +120,6 @@ impl BlockQueue {
|
||||
empty.notify_all();
|
||||
}
|
||||
|
||||
|
||||
while lock.unverified.is_empty() && !deleting.load(AtomicOrdering::Relaxed) {
|
||||
lock = wait.wait(lock).unwrap();
|
||||
}
|
||||
@ -154,7 +158,6 @@ impl BlockQueue {
|
||||
},
|
||||
Err(err) => {
|
||||
let mut v = verification.lock().unwrap();
|
||||
flushln!("Stage 2 block verification failed for {}\nError: {:?}", block_hash, err);
|
||||
warn!(target: "client", "Stage 2 block verification failed for {}\nError: {:?}", block_hash, err);
|
||||
v.bad.insert(block_hash.clone());
|
||||
v.verifying.retain(|e| e.hash != block_hash);
|
||||
@ -187,9 +190,10 @@ impl BlockQueue {
|
||||
|
||||
/// Wait for queue to be empty
|
||||
pub fn flush(&mut self) {
|
||||
let mutex: Mutex<()> = Mutex::new(());
|
||||
let lock = mutex.lock().unwrap();
|
||||
let _ = self.empty.wait(lock).unwrap();
|
||||
let mut verification = self.verification.lock().unwrap();
|
||||
while !verification.unverified.is_empty() && !verification.verifying.is_empty() {
|
||||
verification = self.empty.wait(verification).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
/// Add a block to the queue.
|
||||
@ -265,6 +269,7 @@ impl BlockQueue {
|
||||
full: false,
|
||||
verified_queue_size: verification.verified.len(),
|
||||
unverified_queue_size: verification.unverified.len(),
|
||||
verifying_queue_size: verification.verifying.len(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -181,7 +181,6 @@ impl Client {
|
||||
|
||||
/// Flush the block import queue.
|
||||
pub fn flush_queue(&self) {
|
||||
flushln!("Flushing queue {:?}", self.block_queue.read().unwrap().queue_info());
|
||||
self.block_queue.write().unwrap().flush();
|
||||
}
|
||||
|
||||
@ -189,9 +188,8 @@ impl Client {
|
||||
pub fn import_verified_blocks(&self, _io: &IoChannel<NetSyncMessage>) {
|
||||
let mut bad = HashSet::new();
|
||||
let _import_lock = self.import_lock.lock();
|
||||
|
||||
for block in self.block_queue.write().unwrap().drain(128) {
|
||||
flushln!("Importing block...");
|
||||
let blocks = self.block_queue.write().unwrap().drain(128);
|
||||
for block in blocks {
|
||||
if bad.contains(&block.header.parent_hash) {
|
||||
self.block_queue.write().unwrap().mark_as_bad(&block.header.hash());
|
||||
bad.insert(block.header.hash());
|
||||
@ -238,6 +236,7 @@ impl Client {
|
||||
}
|
||||
};
|
||||
if let Err(e) = verify_block_final(&header, result.block().header()) {
|
||||
flushln!("Stage 4 block verification failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e);
|
||||
warn!(target: "client", "Stage 4 block verification failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e);
|
||||
self.block_queue.write().unwrap().mark_as_bad(&header.hash());
|
||||
return;
|
||||
|
13
src/spec.rs
13
src/spec.rs
@ -80,7 +80,7 @@ pub struct Spec {
|
||||
/// TODO [arkpar] Please document me
|
||||
pub extra_data: Bytes,
|
||||
/// TODO [Gav Wood] Please document me
|
||||
pub genesis_state: PodState,
|
||||
genesis_state: PodState,
|
||||
/// TODO [Gav Wood] Please document me
|
||||
pub seal_fields: usize,
|
||||
/// TODO [Gav Wood] Please document me
|
||||
@ -182,6 +182,17 @@ impl Spec {
|
||||
self.seal_rlp = seal_rlp;
|
||||
self.state_root_memo = RwLock::new(genesis.find("stateRoot").and_then(|_| Some(H256::from_json(&genesis["stateRoot"]))));
|
||||
}
|
||||
|
||||
/// Alter the value of the genesis state.
|
||||
pub fn set_genesis_state(&mut self, s: PodState) {
|
||||
self.genesis_state = s;
|
||||
*self.state_root_memo.write().unwrap() = None;
|
||||
}
|
||||
|
||||
/// Returns `false` if the memoized state root is invalid. `true` otherwise.
|
||||
pub fn is_state_root_valid(&self) -> bool {
|
||||
self.state_root_memo.read().unwrap().clone().map_or(true, |sr| sr == self.genesis_state.root())
|
||||
}
|
||||
}
|
||||
|
||||
impl FromJson for Spec {
|
||||
|
@ -146,15 +146,15 @@ impl State {
|
||||
/// This will change the state accordingly.
|
||||
pub fn apply(&mut self, env_info: &EnvInfo, engine: &Engine, t: &Transaction) -> ApplyResult {
|
||||
|
||||
let old = self.to_pod();
|
||||
// let old = self.to_pod();
|
||||
|
||||
let e = try!(Executive::new(self, env_info, engine).transact(t));
|
||||
//println!("Executed: {:?}", e);
|
||||
|
||||
trace!("Applied transaction. Diff:\n{}\n", StateDiff::diff_pod(&old, &self.to_pod()));
|
||||
// trace!("Applied transaction. Diff:\n{}\n", StateDiff::diff_pod(&old, &self.to_pod()));
|
||||
self.commit();
|
||||
let receipt = Receipt::new(self.root().clone(), e.cumulative_gas_used, e.logs);
|
||||
trace!("Transaction receipt: {:?}", receipt);
|
||||
// trace!("Transaction receipt: {:?}", receipt);
|
||||
Ok(receipt)
|
||||
}
|
||||
|
||||
|
@ -158,6 +158,7 @@ impl BlockChainClient for TestBlockChainClient {
|
||||
full: false,
|
||||
verified_queue_size: 0,
|
||||
unverified_queue_size: 0,
|
||||
verifying_queue_size: 0,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,8 +22,9 @@ fn do_json_test(json_data: &[u8]) -> Vec<String> {
|
||||
|
||||
let blocks: Vec<Bytes> = test["blocks"].as_array().unwrap().iter().map(|e| xjson!(&e["rlp"])).collect();
|
||||
let mut spec = ethereum::new_frontier_like_test();
|
||||
spec.set_genesis_state(PodState::from_json(test.find("pre").unwrap()));
|
||||
spec.overwrite_genesis(test.find("genesisBlockHeader").unwrap());
|
||||
spec.genesis_state = PodState::from_json(test.find("pre").unwrap());
|
||||
assert!(spec.is_state_root_valid());
|
||||
|
||||
let mut dir = env::temp_dir();
|
||||
dir.push(H32::random().hex());
|
||||
@ -32,9 +33,12 @@ fn do_json_test(json_data: &[u8]) -> Vec<String> {
|
||||
blocks.into_iter().foreach(|b| {
|
||||
client.import_block(b).unwrap();
|
||||
});
|
||||
flushln!("Imported all");
|
||||
client.flush_queue();
|
||||
flushln!("Flushed");
|
||||
client.import_verified_blocks(&IoChannel::disconnected());
|
||||
flushln!("Best hash: {}", client.chain_info().best_block_hash);
|
||||
flushln!("Checking...");
|
||||
fail_unless(client.chain_info().best_block_hash == H256::from_json(&test["lastblockhash"]));
|
||||
}
|
||||
fs::remove_dir_all(&dir).unwrap();
|
||||
}
|
||||
@ -46,4 +50,5 @@ fn do_json_test(json_data: &[u8]) -> Vec<String> {
|
||||
failed
|
||||
}
|
||||
|
||||
declare_test!{BlockchainTests_bcStateTest, "BlockchainTests/bcStateTest"}
|
||||
//declare_test!{BlockchainTests_bcStateTest, "BlockchainTests/bcStateTest"}
|
||||
declare_test!{BlockchainTests_bcForkBlockTest, "BlockchainTests/bcForkBlockTest"}
|
||||
|
Loading…
Reference in New Issue
Block a user