client.rs 36.7 KiB
Newer Older
Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
					.and_then(|number| self.tracedb.read().trace(number, tx_address.index, trace_address))
	fn transaction_traces(&self, transaction: TransactionID) -> Option<Vec<LocalizedTrace>> {
		self.transaction_address(transaction)
			.and_then(|tx_address| {
				self.block_number(BlockID::Hash(tx_address.block_hash))
Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
					.and_then(|number| self.tracedb.read().transaction_traces(number, tx_address.index))
	fn block_traces(&self, block: BlockID) -> Option<Vec<LocalizedTrace>> {
		self.block_number(block)
Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
			.and_then(|number| self.tracedb.read().block_traces(number))
	fn last_hashes(&self) -> LastHashes {
Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
		(*self.build_last_hashes(self.chain.read().best_block_hash())).clone()
Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
	fn queue_transactions(&self, transactions: Vec<Bytes>) {
		if self.queue_transactions.load(AtomicOrdering::Relaxed) > MAX_TX_QUEUE_SIZE {
			debug!("Ignoring {} transactions: queue is full", transactions.len());
		} else {
			let len = transactions.len();
			match self.io_channel.send(ClientIoMessage::NewTransactions(transactions)) {
Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
				Ok(_) => {
					self.queue_transactions.fetch_add(len, AtomicOrdering::SeqCst);
				}
				Err(e) => {
					debug!("Ignoring {} transactions: error queueing: {}", len, e);
				}
			}
		}
	}

Gav Wood's avatar
Gav Wood committed
	fn pending_transactions(&self) -> Vec<SignedTransaction> {
		self.miner.pending_transactions()
impl MiningBlockChainClient for Client {
Gav Wood's avatar
Gav Wood committed
	fn prepare_open_block(&self, author: Address, gas_range_target: (U256, U256), extra_data: Bytes) -> OpenBlock {
		let engine = &*self.engine;
Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
		let chain = self.chain.read();
		let h = chain.best_block_hash();
Nikolay Volf's avatar
Nikolay Volf committed

Marek Kotewicz's avatar
Marek Kotewicz committed
		let mut open_block = OpenBlock::new(
Nikolay Volf's avatar
Nikolay Volf committed
			engine,
Nikolay Volf's avatar
Nikolay Volf committed
			false,	// TODO: this will need to be parameterised once we want to do immediate mining insertion.
Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
			self.state_db.read().boxed_clone(),
			&chain.block_header(&h).expect("h is best block hash: so its header must exist: qed"),
Nikolay Volf's avatar
Nikolay Volf committed
			self.build_last_hashes(h.clone()),
			author,
Gav Wood's avatar
Gav Wood committed
			gas_range_target,
Nikolay Volf's avatar
Nikolay Volf committed
			extra_data,
Gav Wood's avatar
Gav Wood committed
		).expect("OpenBlock::new only fails if parent state root invalid; state root of best block's header is never invalid; qed");
Nikolay Volf's avatar
Nikolay Volf committed

		// Add uncles
Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
		chain
Nikolay Volf's avatar
Nikolay Volf committed
			.find_uncle_headers(&h, engine.maximum_uncle_age())
			.unwrap()
			.into_iter()
			.take(engine.maximum_uncle_count())
			.foreach(|h| {
Marek Kotewicz's avatar
Marek Kotewicz committed
				open_block.push_uncle(h).unwrap();
Nikolay Volf's avatar
Nikolay Volf committed
			});

Marek Kotewicz's avatar
Marek Kotewicz committed
		open_block
Nikolay Volf's avatar
Nikolay Volf committed
	}
NikVolf's avatar
NikVolf committed

	fn vm_factory(&self) -> &EvmFactory {
NikVolf's avatar
NikVolf committed
	}

	fn import_sealed_block(&self, block: SealedBlock) -> ImportResult {
		let _import_lock = self.import_lock.lock();
		let _timer = PerfTimer::new("import_sealed_block");
		let start = precise_time_ns();

		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.notify(|notify| {
			notify.new_blocks(
				vec![h.clone()],
				vec![],
				enacted.clone(),
				retracted.clone(),
				vec![h.clone()],
				precise_time_ns() - start,
			);
		});
Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
		self.db.read().flush().expect("DB flush failed.");
Tomusdrw's avatar
Tomusdrw committed
impl MayPanic for Client {
	fn on_panic<F>(&self, closure: F) where F: OnPanicListener {