From 4d48054cee56c20eeae220ec797e2a013c77477c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Tue, 18 Oct 2016 16:43:42 +0200 Subject: [PATCH] Fixing importing traces for non-canon blockS (#2683) --- ethcore/src/trace/db.rs | 70 +++++++++++++++++++++++++++++++++++------ 1 file changed, 60 insertions(+), 10 deletions(-) diff --git a/ethcore/src/trace/db.rs b/ethcore/src/trace/db.rs index 2cf14828a..c5b004f79 100644 --- a/ethcore/src/trace/db.rs +++ b/ethcore/src/trace/db.rs @@ -275,16 +275,6 @@ impl TraceDatabase for TraceDB where T: DatabaseExtras { .map(Into::into) .collect(); - // insert new block traces into the cache and the database - { - let mut traces = self.traces.write(); - // it's important to use overwrite here, - // cause this value might be queried by hash later - batch.write_with_cache(db::COL_TRACE, &mut *traces, request.block_hash, request.traces, CacheUpdatePolicy::Overwrite); - // note_used must be called after locking traces to avoid cache/traces deadlock on garbage collection - self.note_used(CacheID::Trace(request.block_hash.clone())); - } - let chain = BloomGroupChain::new(self.bloom_config, self); let trace_blooms = chain.replace(&replaced_range, enacted_blooms); let blooms_to_insert = trace_blooms.into_iter() @@ -299,6 +289,16 @@ impl TraceDatabase for TraceDB where T: DatabaseExtras { self.note_used(CacheID::Bloom(key)); } } + + // insert new block traces into the cache and the database + { + let mut traces = self.traces.write(); + // it's important to use overwrite here, + // cause this value might be queried by hash later + batch.write_with_cache(db::COL_TRACE, &mut *traces, request.block_hash, request.traces, CacheUpdatePolicy::Overwrite); + // note_used must be called after locking traces to avoid cache/traces deadlock on garbage collection + self.note_used(CacheID::Trace(request.block_hash.clone())); + } } fn trace(&self, block_number: BlockNumber, tx_position: usize, trace_position: Vec) -> Option { @@ -504,6 +504,28 @@ mod tests { } } + fn create_noncanon_import_request(block_number: BlockNumber, block_hash: H256) -> ImportRequest { + ImportRequest { + traces: FlatBlockTraces::from(vec![FlatTransactionTraces::from(vec![FlatTrace { + trace_address: Default::default(), + subtraces: 0, + action: Action::Call(Call { + from: 1.into(), + to: 2.into(), + value: 3.into(), + gas: 4.into(), + input: vec![], + call_type: CallType::Call, + }), + result: Res::FailedCall(TraceError::OutOfGas), + }])]), + block_hash: block_hash.clone(), + block_number: block_number, + enacted: vec![], + retracted: 0, + } + } + fn create_simple_localized_trace(block_number: BlockNumber, block_hash: H256, tx_hash: H256) -> LocalizedTrace { LocalizedTrace { action: Action::Call(Call { @@ -524,6 +546,34 @@ mod tests { } } + #[test] + fn test_import_non_canon_traces() { + let temp = RandomTempPath::new(); + let db = Arc::new(Database::open(&DatabaseConfig::with_columns(::db::NUM_COLUMNS), temp.as_str()).unwrap()); + let mut config = Config::default(); + config.enabled = true; + let block_0 = H256::from(0xa1); + let block_1 = H256::from(0xa2); + let tx_0 = H256::from(0xff); + let tx_1 = H256::from(0xaf); + + let mut extras = Extras::default(); + extras.block_hashes.insert(0, block_0.clone()); + extras.block_hashes.insert(1, block_1.clone()); + extras.transaction_hashes.insert(0, vec![tx_0.clone()]); + extras.transaction_hashes.insert(1, vec![tx_1.clone()]); + + let tracedb = TraceDB::new(config, db.clone(), Arc::new(extras)); + + // import block 0 + let request = create_noncanon_import_request(0, block_0.clone()); + let mut batch = DBTransaction::new(&db); + tracedb.import(&mut batch, request); + db.write(batch).unwrap(); + + assert!(tracedb.traces(&block_0).is_some(), "Traces should be available even if block is non-canon."); + } + #[test] fn test_import() {