Fabcoin Core  0.16.2
P2P Digital Currency
Client.cpp
Go to the documentation of this file.
1 /*
2  This file is part of cpp-ethereum.
3 
4  cpp-ethereum is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  cpp-ethereum is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
16 */
22 #include "Client.h"
23 #include <chrono>
24 #include <memory>
25 #include <thread>
26 #include <boost/filesystem.hpp>
27 #include <libdevcore/Log.h>
28 #include <libp2p/Host.h>
29 #include "Defaults.h"
30 #include "Executive.h"
31 #include "EthereumHost.h"
32 #include "Block.h"
33 #include "TransactionQueue.h"
34 using namespace std;
35 using namespace dev;
36 using namespace dev::eth;
37 using namespace p2p;
38 
39 static_assert(BOOST_VERSION == 106300, "Wrong boost headers version");
40 
41 std::ostream& dev::eth::operator<<(std::ostream& _out, ActivityReport const& _r)
42 {
43  _out << "Since " << toString(_r.since) << " (" << std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now() - _r.since).count();
44  _out << "): " << _r.ticks << "ticks";
45  return _out;
46 }
47 
48 #if defined(_WIN32)
49 const char* ClientNote::name() { return EthTeal "^" EthBlue " i"; }
50 const char* ClientChat::name() { return EthTeal "^" EthWhite " o"; }
51 const char* ClientTrace::name() { return EthTeal "^" EthGray " O"; }
52 const char* ClientDetail::name() { return EthTeal "^" EthCoal " 0"; }
53 #else
54 const char* ClientNote::name() { return EthTeal "⧫" EthBlue " ℹ"; }
55 const char* ClientChat::name() { return EthTeal "⧫" EthWhite " ◌"; }
56 const char* ClientTrace::name() { return EthTeal "⧫" EthGray " ◎"; }
57 const char* ClientDetail::name() { return EthTeal "⧫" EthCoal " ●"; }
58 #endif
59 
60 Client::Client(
61  ChainParams const& _params,
62  int _networkID,
63  p2p::Host* _host,
64  std::shared_ptr<GasPricer> _gpForAdoption,
65  std::string const& _dbPath,
66  WithExisting _forceAction,
67  TransactionQueue::Limits const& _l
68 ):
69  ClientBase(_l),
70  Worker("eth", 0),
71  m_bc(_params, _dbPath, _forceAction, [](unsigned d, unsigned t){ std::cerr << "REVISING BLOCKCHAIN: Processed " << d << " of " << t << "...\r"; }),
72  m_gp(_gpForAdoption ? _gpForAdoption : make_shared<TrivialGasPricer>()),
76 {
77  init(_host, _dbPath, _forceAction, _networkID);
78 }
79 
81 {
82  stopWorking();
83 }
84 
85 void Client::init(p2p::Host* _extNet, std::string const& _dbPath, WithExisting _forceAction, u256 _networkId)
86 {
88 
89  // Cannot be opened until after blockchain is open, since BlockChain may upgrade the database.
90  // TODO: consider returning the upgrade mechanism here. will delaying the opening of the blockchain database
91  // until after the construction.
92  m_stateDB = State::openDB(_dbPath, bc().genesisHash(), _forceAction);
93  // LAZY. TODO: move genesis state construction/commiting to stateDB openning and have this just take the root from the genesis block.
96 
97  m_bq.setChain(bc());
98 
99  m_lastGetWork = std::chrono::system_clock::now() - chrono::seconds(30);
100  m_tqReady = m_tq.onReady([=](){ this->onTransactionQueueReady(); }); // TODO: should read m_tq->onReady(thisThread, syncTransactionQueue);
101  m_tqReplaced = m_tq.onReplaced([=](h256 const&){ m_needStateReset = true; });
102  m_bqReady = m_bq.onReady([=](){ this->onBlockQueueReady(); }); // TODO: should read m_bq->onReady(thisThread, syncBlockQueue);
103  m_bq.setOnBad([=](Exception& ex){ this->onBadBlock(ex); });
104  bc().setOnBad([=](Exception& ex){ this->onBadBlock(ex); });
105  bc().setOnBlockImport([=](BlockHeader const& _info){
106  if (auto h = m_host.lock())
107  h->onBlockImported(_info);
108  });
109 
110  if (_forceAction == WithExisting::Rescue)
111  bc().rescue(m_stateDB);
112 
113  m_gp->update(bc());
114 
115  auto host = _extNet->registerCapability(make_shared<EthereumHost>(bc(), m_stateDB, m_tq, m_bq, _networkId));
116  m_host = host;
117 
118  _extNet->addCapability(host, EthereumHost::staticName(), EthereumHost::c_oldProtocolVersion); //TODO: remove this once v61+ protocol is common
119 
120 
121  if (_dbPath.size())
122  Defaults::setDBPath(_dbPath);
123  doWork(false);
124  startWorking();
125 }
126 
127 ImportResult Client::queueBlock(bytes const& _block, bool _isSafe)
128 {
129  if (m_bq.status().verified + m_bq.status().verifying + m_bq.status().unverified > 10000)
130  this_thread::sleep_for(std::chrono::milliseconds(500));
131  return m_bq.import(&_block, _isSafe);
132 }
133 
134 tuple<ImportRoute, bool, unsigned> Client::syncQueue(unsigned _max)
135 {
136  stopWorking();
137  return bc().sync(m_bq, m_stateDB, _max);
138 }
139 
141 {
142  // BAD BLOCK!!!
143  bytes const* block = boost::get_error_info<errinfo_block>(_ex);
144  if (!block)
145  {
146  cwarn << "ODD: onBadBlock called but exception (" << _ex.what() << ") has no block in it.";
147  cwarn << boost::diagnostic_information(_ex);
148  return;
149  }
150 
151  badBlock(*block, _ex.what());
152 }
153 
155 {
156  while (true)
157  {
158  function<void()> f;
160  if (!m_functionQueue.empty())
161  {
162  f = m_functionQueue.front();
163  m_functionQueue.pop();
164  }
165  if (f)
166  f();
167  else
168  break;
169  }
170 }
171 
173 {
174  if (auto h = m_host.lock())
175  return h->networkId();
176  return 0;
177 }
178 
179 void Client::setNetworkId(u256 const& _n)
180 {
181  if (auto h = m_host.lock())
182  h->setNetworkId(_n);
183 }
184 
185 bool Client::isSyncing() const
186 {
187  if (auto h = m_host.lock())
188  return h->isSyncing();
189  return false;
190 }
191 
193 {
194  if (auto h = m_host.lock())
195  {
196  SyncState state = h->status().state;
197  return (state != SyncState::Idle && state != SyncState::NewBlocks) || h->bq().items().first > 10;
198  }
199  return false;
200 }
201 
203 {
204  // Synchronise the state according to the head of the block chain.
205  // TODO: currently it contains keys for *all* blocks. Make it remove old ones.
206  clog(ClientTrace) << "startedWorking()";
207 
209  m_preSeal.sync(bc());
211  {
216  }
217 }
218 
220 {
221  // Synchronise the state according to the head of the block chain.
222  // TODO: currently it contains keys for *all* blocks. Make it remove old ones.
224  m_preSeal.sync(bc());
226  {
231  }
232 }
233 
235 {
236  reopenChain(bc().chainParams(), _we);
237 }
238 
240 {
241  bool wasSealing = wouldSeal();
242  if (wasSealing)
243  stopSealing();
244  stopWorking();
245 
246  m_tq.clear();
247  m_bq.clear();
249 
250  {
252  WriteGuard l2(x_preSeal);
253  WriteGuard l3(x_working);
254 
255  auto author = m_preSeal.author(); // backup and restore author.
256  m_preSeal = Block(chainParams().accountStartNonce);
257  m_postSeal = Block(chainParams().accountStartNonce);
258  m_working = Block(chainParams().accountStartNonce);
259 
260  m_stateDB = OverlayDB();
261  bc().reopen(_p, _we);
262  m_stateDB = State::openDB(Defaults::dbPath(), bc().genesisHash(), _we);
263 
267  m_working = Block(chainParams().accountStartNonce);
268  }
269 
270  if (auto h = m_host.lock())
271  h->reset();
272 
273  startedWorking();
274  doWork();
275 
276  startWorking();
277  if (wasSealing)
278  startSealing();
279 }
280 
281 void Client::executeInMainThread(function<void ()> const& _function)
282 {
284  m_functionQueue.push(_function);
285  m_signalled.notify_all();
286 }
287 
289 {
291  {
292  if (!m_postSeal.pending().size())
293  return;
294  m_tq.clear();
297  }
298 
299  startSealing();
300  h256Hash changeds;
301  noteChanged(changeds);
302 }
303 
304 template <class S, class T>
305 static S& filtersStreamOut(S& _out, T const& _fs)
306 {
307  _out << "{";
308  unsigned i = 0;
309  for (h256 const& f: _fs)
310  {
311  _out << (i++ ? ", " : "");
312  if (f == PendingChangedFilter)
313  _out << LogTag::Special << "pending";
314  else if (f == ChainChangedFilter)
315  _out << LogTag::Special << "chain";
316  else
317  _out << f;
318  }
319  _out << "}";
320  return _out;
321 }
322 
323 void Client::appendFromNewPending(TransactionReceipt const& _receipt, h256Hash& io_changed, h256 _sha3)
324 {
326  io_changed.insert(PendingChangedFilter);
327  m_specialFilters.at(PendingChangedFilter).push_back(_sha3);
328  for (pair<h256 const, InstalledFilter>& i: m_filters)
329  {
330  // acceptable number.
331  auto m = i.second.filter.matches(_receipt);
332  if (m.size())
333  {
334  // filter catches them
335  for (LogEntry const& l: m)
336  i.second.changes.push_back(LocalisedLogEntry(l));
337  io_changed.insert(i.first);
338  }
339  }
340 }
341 
342 void Client::appendFromBlock(h256 const& _block, BlockPolarity _polarity, h256Hash& io_changed)
343 {
344  // TODO: more precise check on whether the txs match.
345  auto receipts = bc().receipts(_block).receipts;
346 
348  io_changed.insert(ChainChangedFilter);
349  m_specialFilters.at(ChainChangedFilter).push_back(_block);
350  for (pair<h256 const, InstalledFilter>& i: m_filters)
351  {
352  // acceptable number & looks like block may contain a matching log entry.
353  for (size_t j = 0; j < receipts.size(); j++)
354  {
355  auto tr = receipts[j];
356  auto m = i.second.filter.matches(tr);
357  if (m.size())
358  {
359  auto transactionHash = transaction(_block, j).sha3();
360  // filter catches them
361  for (LogEntry const& l: m)
362  i.second.changes.push_back(LocalisedLogEntry(l, _block, (BlockNumber)bc().number(_block), transactionHash, j, 0, _polarity));
363  io_changed.insert(i.first);
364  }
365  }
366  }
367 }
368 
369 ExecutionResult Client::call(Address _dest, bytes const& _data, u256 _gas, u256 _value, u256 _gasPrice, Address const& _from)
370 {
371  ExecutionResult ret;
372  try
373  {
374  Block temp(chainParams().accountStartNonce);
375  clog(ClientDetail) << "Nonce at " << _dest << " pre:" << m_preSeal.transactionsFrom(_dest) << " post:" << m_postSeal.transactionsFrom(_dest);
377  temp = m_postSeal;
378  temp.mutableState().addBalance(_from, _value + _gasPrice * _gas);
379  Executive e(temp);
380  e.setResultRecipient(ret);
381  if (!e.call(_dest, _from, _value, _gasPrice, &_data, _gas))
382  e.go();
383  e.finalize();
384  }
385  catch (...)
386  {
387  cwarn << "Client::call failed: " << boost::current_exception_diagnostic_information();
388  }
389  return ret;
390 }
391 
392 unsigned static const c_syncMin = 1;
393 unsigned static const c_syncMax = 1000;
394 double static const c_targetDuration = 1;
395 
397 {
398 // cdebug << "syncBlockQueue()";
399 
400  ImportRoute ir;
401  unsigned count;
402  Timer t;
403  tie(ir, m_syncBlockQueue, count) = bc().sync(m_bq, m_stateDB, m_syncAmount);
404  double elapsed = t.elapsed();
405 
406  if (count)
407  {
408  clog(ClientNote) << count << "blocks imported in" << unsigned(elapsed * 1000) << "ms (" << (count / elapsed) << "blocks/s) in #" << bc().number();
409  }
410 
411  if (elapsed > c_targetDuration * 1.1 && count > c_syncMin)
412  m_syncAmount = max(c_syncMin, count * 9 / 10);
413  else if (count == m_syncAmount && elapsed < c_targetDuration * 0.9 && m_syncAmount < c_syncMax)
414  m_syncAmount = min(c_syncMax, m_syncAmount * 11 / 10 + 1);
415  if (ir.liveBlocks.empty())
416  return;
417  onChainChanged(ir);
418 }
419 
421 {
422  Timer timer;
423 
424  h256Hash changeds;
425  TransactionReceipts newPendingReceipts;
426 
428  {
429  if (m_working.isSealed())
430  {
431  ctrace << "Skipping txq sync for a sealed block.";
432  return;
433  }
434 
435  tie(newPendingReceipts, m_syncTransactionQueue) = m_working.sync(bc(), m_tq, *m_gp);
436  }
437 
438  if (newPendingReceipts.empty())
439  {
440  auto s = m_tq.status();
441  ctrace << "No transactions to process. " << m_working.pending().size() << " pending, " << s.current << " queued, " << s.future << " future, " << s.unverified << " unverified";
442  return;
443  }
444 
448 
450  for (size_t i = 0; i < newPendingReceipts.size(); i++)
451  appendFromNewPending(newPendingReceipts[i], changeds, m_postSeal.pending()[i].sha3());
452 
453  // Tell farm about new transaction (i.e. restart mining).
455 
456  // Tell watches about the new transactions.
457  noteChanged(changeds);
458 
459  // Tell network about the new transactions.
460  if (auto h = m_host.lock())
461  h->noteNewTransactions();
462 
463  ctrace << "Processed " << newPendingReceipts.size() << " transactions in" << (timer.elapsed() * 1000) << "(" << (bool)m_syncTransactionQueue << ")";
464 }
465 
466 void Client::onDeadBlocks(h256s const& _blocks, h256Hash& io_changed)
467 {
468  // insert transactions that we are declaring the dead part of the chain
469  for (auto const& h: _blocks)
470  {
471  clog(ClientTrace) << "Dead block:" << h;
472  for (auto const& t: bc().transactions(h))
473  {
474  clog(ClientTrace) << "Resubmitting dead-block transaction " << Transaction(t, CheckTransaction::None);
475  ctrace << "Resubmitting dead-block transaction " << Transaction(t, CheckTransaction::None);
477  }
478  }
479 
480  for (auto const& h: _blocks)
481  appendFromBlock(h, BlockPolarity::Dead, io_changed);
482 }
483 
484 void Client::onNewBlocks(h256s const& _blocks, h256Hash& io_changed)
485 {
486  // remove transactions from m_tq nicely rather than relying on out of date nonce later on.
487  for (auto const& h: _blocks)
488  clog(ClientTrace) << "Live block:" << h;
489 
490  if (auto h = m_host.lock())
491  h->noteNewBlocks();
492 
493  for (auto const& h: _blocks)
494  appendFromBlock(h, BlockPolarity::Live, io_changed);
495 }
496 
498 {
499  // RESTART MINING
500 
501 // ctrace << "resyncStateFromChain()";
502 
503  if (!isMajorSyncing())
504  {
505  bool preChanged = false;
506  Block newPreMine(chainParams().accountStartNonce);
508  newPreMine = m_preSeal;
509 
510  // TODO: use m_postSeal to avoid re-evaluating our own blocks.
511  preChanged = newPreMine.sync(bc());
512 
513  if (preChanged || m_postSeal.author() != m_preSeal.author())
514  {
516  m_preSeal = newPreMine;
518  m_working = newPreMine;
520  if (!m_postSeal.isSealed() || m_postSeal.info().hash() != newPreMine.info().parentHash())
521  for (auto const& t: m_postSeal.pending())
522  {
523  clog(ClientTrace) << "Resubmitting post-seal transaction " << t;
524 // ctrace << "Resubmitting post-seal transaction " << t;
525  auto ir = m_tq.import(t, IfDropped::Retry);
526  if (ir != ImportResult::Success)
528  }
531 
533  }
534 
535  // Quick hack for now - the TQ at this point already has the prior pending transactions in it;
536  // we should resync with it manually until we are stricter about what constitutes "knowing".
538  }
539 }
540 
542 {
543  Block newPreMine(chainParams().accountStartNonce);
545  newPreMine = m_preSeal;
546 
548  m_working = newPreMine;
551 
554 }
555 
557 {
558 // ctrace << "onChainChanged()";
559  h256Hash changeds;
560  onDeadBlocks(_ir.deadBlocks, changeds);
561  for (auto const& t: _ir.goodTranactions)
562  {
563  clog(ClientTrace) << "Safely dropping transaction " << t.sha3();
564  m_tq.dropGood(t);
565  }
566  onNewBlocks(_ir.liveBlocks, changeds);
568  noteChanged(changeds);
569 }
570 
572 {
573  return chrono::system_clock::now() - m_lastGetWork < chrono::seconds(30);
574 }
575 
577 {
578  clog(ClientTrace) << "Post state changed.";
579  m_signalled.notify_all();
580  m_remoteWorking = false;
581 }
582 
584 {
585  if (m_wouldSeal == true)
586  return;
587  clog(ClientNote) << "Mining Beneficiary: " << author();
588  if (author())
589  {
590  m_wouldSeal = true;
591  m_signalled.notify_all();
592  }
593  else
594  clog(ClientNote) << "You need to set an author in order to seal!";
595 }
596 
598 {
599  if ((wouldSeal() || remoteActive()) && !isMajorSyncing())
600  {
601  if (sealEngine()->shouldSeal(this))
602  {
603  m_wouldButShouldnot = false;
604 
605  clog(ClientTrace) << "Rejigging seal engine...";
607  {
608  if (m_working.isSealed())
609  {
610  clog(ClientNote) << "Tried to seal sealed block...";
611  return;
612  }
614  }
616  {
620  }
621 
622  if (wouldSeal())
623  {
624  sealEngine()->onSealGenerated([=](bytes const& header){
625  if (!this->submitSealed(header))
626  clog(ClientNote) << "Submitting block failed...";
627  });
628  ctrace << "Generating seal on" << m_sealingInfo.hash(WithoutSeal) << "#" << m_sealingInfo.number();
630  }
631  }
632  else
633  m_wouldButShouldnot = true;
634  }
635  if (!m_wouldSeal)
637 }
638 
639 void Client::noteChanged(h256Hash const& _filters)
640 {
642  if (_filters.size())
643  filtersStreamOut(cwatch << "noteChanged:", _filters);
644  // accrue all changes left in each filter into the watches.
645  for (auto& w: m_watches)
646  if (_filters.count(w.second.id))
647  {
648  if (m_filters.count(w.second.id))
649  {
650  cwatch << "!!!" << w.first << w.second.id.abridged();
651  w.second.changes += m_filters.at(w.second.id).changes;
652  }
653  else if (m_specialFilters.count(w.second.id))
654  for (h256 const& hash: m_specialFilters.at(w.second.id))
655  {
656  cwatch << "!!!" << w.first << LogTag::Special << (w.second.id == PendingChangedFilter ? "pending" : w.second.id == ChainChangedFilter ? "chain" : "???");
657  w.second.changes.push_back(LocalisedLogEntry(SpecialLogEntry, hash));
658  }
659  }
660  // clear the filters now.
661  for (auto& i: m_filters)
662  i.second.changes.clear();
663  for (auto& i: m_specialFilters)
664  i.second.clear();
665 }
666 
667 void Client::doWork(bool _doWait)
668 {
669  bool t = true;
670  if (m_syncBlockQueue.compare_exchange_strong(t, false))
671  syncBlockQueue();
672 
673  if (m_needStateReset)
674  {
675  resetState();
676  m_needStateReset = false;
677  }
678 
679  t = true;
680  bool isSealed = false;
682  isSealed = m_working.isSealed();
683  if (!isSealed && !isSyncing() && !m_remoteWorking && m_syncTransactionQueue.compare_exchange_strong(t, false))
685 
686  tick();
687 
688  rejigSealing();
689 
691 
693  isSealed = m_working.isSealed();
694  // If the block is sealed, we have to wait for it to tickle through the block queue
695  // (which only signals as wanting to be synced if it is ready).
696  if (!m_syncBlockQueue && !m_syncTransactionQueue && (_doWait || isSealed))
697  {
698  std::unique_lock<std::mutex> l(x_signalled);
699  m_signalled.wait_for(l, chrono::seconds(1));
700  }
701 }
702 
704 {
705  if (chrono::system_clock::now() - m_lastTick > chrono::seconds(1))
706  {
707  m_report.ticks++;
709  m_bq.tick();
710  m_lastTick = chrono::system_clock::now();
711  if (m_report.ticks == 15)
713  }
714 }
715 
717 {
718  if (chrono::system_clock::now() - m_lastGarbageCollection > chrono::seconds(5))
719  {
720  // watches garbage collection
721  vector<unsigned> toUninstall;
723  for (auto key: keysOf(m_watches))
724  if (m_watches[key].lastPoll != chrono::system_clock::time_point::max() && chrono::system_clock::now() - m_watches[key].lastPoll > chrono::seconds(20))
725  {
726  toUninstall.push_back(key);
727  clog(ClientTrace) << "GC: Uninstall" << key << "(" << chrono::duration_cast<chrono::seconds>(chrono::system_clock::now() - m_watches[key].lastPoll).count() << "s old)";
728  }
729  for (auto i: toUninstall)
730  uninstallWatch(i);
731 
732  // blockchain GC
733  bc().garbageCollect();
734 
735  m_lastGarbageCollection = chrono::system_clock::now();
736  }
737 }
738 
740 {
741  startWorking();
742 }
743 
744 Block Client::block(h256 const& _block) const
745 {
746  try
747  {
748  Block ret(bc(), m_stateDB);
749  ret.populateFromChain(bc(), _block);
750  return ret;
751  }
752  catch (Exception& ex)
753  {
754  ex << errinfo_block(bc().block(_block));
755  onBadBlock(ex);
756  return Block(bc());
757  }
758 }
759 
760 Block Client::block(h256 const& _blockHash, PopulationStatistics* o_stats) const
761 {
762  try
763  {
764  Block ret(bc(), m_stateDB);
765  PopulationStatistics s = ret.populateFromChain(bc(), _blockHash);
766  if (o_stats)
767  swap(s, *o_stats);
768  return ret;
769  }
770  catch (Exception& ex)
771  {
772  ex << errinfo_block(bc().block(_blockHash));
773  onBadBlock(ex);
774  return Block(bc());
775  }
776 }
777 
778 State Client::state(unsigned _txi, h256 const& _blockHash) const
779 {
780  try
781  {
782  return block(_blockHash).fromPending(_txi);
783  }
784  catch (Exception& ex)
785  {
786  ex << errinfo_block(bc().block(_blockHash));
787  onBadBlock(ex);
788  return State(chainParams().accountStartNonce);
789  }
790 }
791 
792 eth::State Client::state(unsigned _txi) const
793 {
795  return m_postSeal.fromPending(_txi);
796  assert(false);
797  return State(chainParams().accountStartNonce);
798 }
799 
801 {
802  doWork();
803 }
804 
806 {
807  auto h = m_host.lock();
808  if (!h)
809  return SyncStatus();
810  SyncStatus status = h->status();
811  status.majorSyncing = isMajorSyncing();
812  return status;
813 }
814 
815 bool Client::submitSealed(bytes const& _header)
816 {
817  bytes newBlock;
818  {
820  {
821  UpgradeGuard l2(l);
822  if (!m_working.sealBlock(_header))
823  return false;
824  }
827  newBlock = m_working.blockData();
828  }
829 
830  // OPTIMISE: very inefficient to not utilise the existing OverlayDB in m_postSeal that contains all trie changes.
831  return m_bq.import(&newBlock, true) == ImportResult::Success;
832 }
833 
834 void Client::rewind(unsigned _n)
835 {
836  executeInMainThread([=]() {
837  bc().rewind(_n);
839  });
840 
841  for (unsigned i = 0; i < 10; ++i)
842  {
843  u256 n;
845  n = m_working.info().number();
846  if (n == _n + 1)
847  break;
848  this_thread::sleep_for(std::chrono::milliseconds(50));
849  }
850  auto h = m_host.lock();
851  if (h)
852  h->reset();
853 }
bytes const & blockData() const
Get the complete current block, including valid nonce.
Definition: Block.h:276
virtual bool uninstallWatch(unsigned _watchId) override
Definition: ClientBase.cpp:325
void stopSealing() override
Stop sealing.
Definition: Client.h:161
void resetState()
Clear working state of transactions.
Definition: Client.cpp:541
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
Definition: Arith256.cpp:15
boost::error_info< struct tag_block, bytes > errinfo_block
Definition: State.h:53
bool call(Address _receiveAddress, Address _txSender, u256 _txValue, u256 _gasPrice, bytesConstRef _txData, u256 _gas)
Set up the executive for evaluating a bare CALL (message call) operation.
Definition: Executive.cpp:261
BlockHeader m_sealingInfo
The header we&#39;re attempting to seal on (derived from m_postSeal).
Definition: Client.h:305
Block m_working
The state of the client which we&#39;re sealing (i.e. it&#39;ll have all the rewards added), while we&#39;re actually working on it.
Definition: Client.h:304
void syncTransactionQueue()
Signal handler for when the block queue needs processing.
Definition: Client.cpp:420
#define ctrace
Definition: Log.h:305
std::vector< T > keysOf(std::map< T, U > const &_m)
Definition: CommonData.h:341
std::pair< TransactionReceipts, bool > sync(BlockChain const &_bc, TransactionQueue &_tq, GasPricer const &_gp, unsigned _msTimeout=100)
Sync our transactions, killing those from the queue that we have and assimilating those that we don&#39;t...
Definition: Block.cpp:301
u256 const & number() const
Definition: BlockHeader.h:162
bool isSealed() const
Definition: Block.h:272
void rewind(unsigned _n)
Rewind to a prior head.
Definition: Client.cpp:834
std::chrono::system_clock::time_point m_lastGarbageCollection
When did we last both doing GC on the watches?
Definition: Client.h:320
State fromPending(unsigned _i) const
Get the State immediately after the given number of pending transactions have been applied...
Definition: Block.cpp:832
void onPostStateChanged()
Called when the post state has changed (i.e.
Definition: Client.cpp:576
void swap(dev::eth::Watch &_a, dev::eth::Watch &_b)
Definition: Interface.h:284
dev::eth::Block block(h256 const &_blockHash, PopulationStatistics *o_stats) const
Get the block.
Definition: Client.cpp:760
dev::eth::State state(unsigned _txi, h256 const &_block) const
Get the state of the given block part way through execution, immediately before transaction index _tx...
Definition: Client.cpp:778
void setOnBad(T const &_t)
Definition: BlockQueue.h:274
h256 hash(IncludeSeal _i=WithSeal) const
Definition: BlockHeader.cpp:64
void onTransactionQueueReady()
Magically called when m_tq needs syncing. Be nice and don&#39;t block.
Definition: Client.h:272
void doneWorking() override
Called when Worker is exiting.
Definition: Client.cpp:219
Block m_postSeal
The state of the client which we&#39;re sealing (i.e. it&#39;ll have all the rewards added).
Definition: Client.h:302
Encapsulation of a block header.
Definition: BlockHeader.h:95
Handler m_tqReady
Definition: Client.h:313
#define T(i, x)
static OverlayDB openDB(std::string const &_path, h256 const &_genesisHash, WithExisting _we=WithExisting::Trust)
Open a DB - useful for passing into the constructor & keeping for other states that are necessary...
Definition: State.cpp:74
Handler onReady(T const &_t)
Register a handler that will be called once there is a new transaction imported.
std::ostream & operator<<(std::ostream &_out, BlockHeader const &_bi)
Definition: BlockHeader.h:194
#define h(i)
Definition: sha.cpp:736
BlockReceipts receipts(h256 const &_hash) const
Get the transactions&#39; receipts of a block (or the most recent mined if none given).
Definition: BlockChain.h:165
size_t count
Definition: ExecStats.cpp:37
The Host class Capabilities should be registered prior to startNetwork, since m_capabilities is not t...
Definition: Host.h:129
const char * what() const noexceptoverride
Definition: Exceptions.h:42
ImportResult import(bytesConstRef _block, bool _isOurs=false)
Import a block into the queue.
Definition: BlockQueue.cpp:175
virtual void generateSeal(BlockHeader const &_bi)=0
TransactionReceipts receipts
Definition: BlockDetails.h:85
virtual bool submitSealed(bytes const &_s)
Submit.
Definition: Client.cpp:815
void reopenChain(ChainParams const &_p, WithExisting _we=WithExisting::Trust)
Reloads the blockchain. Just for debug use.
Definition: Client.cpp:239
void init(p2p::Host *_extNet, std::string const &_dbPath, WithExisting _forceAction, u256 _networkId)
Perform critical setup functions.
Definition: Client.cpp:85
bool isSyncing() const override
Are we updating the chain (syncing or importing a new block)?
Definition: Client.cpp:185
SharedMutex x_preSeal
Lock on m_preSeal.
Definition: Client.h:299
boost::upgrade_to_unique_lock< boost::shared_mutex > UpgradeGuard
Definition: Guards.h:46
Block genesisBlock(OverlayDB const &_db) const
Get a pre-made genesis State object.
virtual ~Client()
Destructor.
Definition: Client.cpp:80
void commitToSeal(BlockChain const &_bc, bytes const &_extraData={})
Prepares the current state for mining.
Definition: Block.cpp:695
std::hash for asio::adress
Definition: Common.h:323
assert(len-trim+(2 *lenIndices)<=WIDTH)
u256 transactionsFrom(Address const &_address) const
Get the number of transactions a particular address has sent (used for the transaction nonce)...
Definition: Block.h:132
void startedWorking() override
Called when Worker is starting.
Definition: Client.cpp:202
ChainParams const & chainParams() const
Get information on this chain.
Definition: Client.h:91
std::chrono::system_clock::time_point m_lastTick
When did we last tick()?
Definition: Client.h:322
std::string toString(string32 const &_s)
Make normal string from fixed-length string.
Definition: CommonData.cpp:141
bool m_wouldButShouldnot
True if the last time we called rejigSealing wouldSeal() was true but sealer&#39;s shouldSeal() was false...
Definition: Client.h:318
boost::upgrade_lock< boost::shared_mutex > UpgradableGuard
Definition: Guards.h:45
void noteChanged(h256Hash const &_filters)
Record that the set of filters _filters have changed.
Definition: Client.cpp:639
ExecStats::duration min
Definition: ExecStats.cpp:35
Description of the result of executing a transaction.
Definition: Transaction.h:69
Model of an Ethereum state, essentially a facade for the trie.
Definition: State.h:161
bool go(OnOpFunc const &_onOp=OnOpFunc())
Executes (or continues execution of) the VM.
Definition: Executive.cpp:386
void tick()
Notes that time has moved on and some blocks that used to be "in the future" may no be valid...
Definition: BlockQueue.cpp:350
void clear()
Clear everything.
Definition: BlockQueue.cpp:74
unsigned BlockNumber
Definition: Common.h:72
void setOnBlockImport(std::function< void(BlockHeader const &)> _t)
Change the function that is called when a new block is imported.
Definition: BlockChain.h:296
virtual Transactions transactions(h256 _blockHash) const override
Definition: ClientBase.cpp:437
BlockQueue m_bq
Maintains a list of incoming blocks not yet on the blockchain (to be imported).
Definition: Client.h:295
Initial chain sync complete. Waiting for new packets.
h256 const & parentHash() const
Definition: BlockHeader.h:154
Import transaction even if it was dropped before.
Handler m_bqReady
Definition: Client.h:315
void doWork() override
Called continuously following sleep for m_idleWaitMs.
Definition: Client.h:241
ImportResult
Definition: Common.h:97
WithExisting
Definition: Common.h:310
void rejigSealing()
Called when wouldSeal(), pendingTransactions() have changed.
Definition: Client.cpp:597
#define DEV_GUARDED(MUTEX)
Simple block guard.
Definition: Guards.h:144
Mutex x_signalled
Definition: Client.h:333
virtual Address author() const override
Get the block author.
Definition: Client.h:144
bool isMajorSyncing() const override
Are we syncing the chain?
Definition: Client.cpp:192
Active model of a block within the block chain.
Definition: Block.h:73
std::shared_ptr< GasPricer > m_gp
The gas pricer.
Definition: Client.h:296
void onBlockQueueReady()
Magically called when m_bq needs syncing. Be nice and don&#39;t block.
Definition: Client.h:275
std::vector< TransactionReceipt > TransactionReceipts
void appendFromNewPending(TransactionReceipt const &_receipt, h256Hash &io_changed, h256 _sha3)
Collate the changed filters for the bloom filter of the given pending transaction.
Definition: Client.cpp:323
bool wouldSeal() const override
Are we sealing now?
Definition: Client.h:163
unsigned m_syncAmount
Number of blocks to sync in each go.
Definition: Client.h:325
double elapsed() const
Definition: Common.h:280
void stopWorking()
Stop worker thread; causes call to stopWorking().
Definition: Worker.cpp:85
void badBlock(bytesConstRef _block, string const &_err)
Definition: Common.cpp:147
Base class for all exceptions.
Definition: Exceptions.h:39
SyncStatus syncStatus() const override
Get some information on the block syncing.
Definition: Client.cpp:805
std::tuple< ImportRoute, bool, unsigned > syncQueue(unsigned _max=1)
Freeze worker thread and sync some of the block queue.
Definition: Client.cpp:134
static unsigned const c_oldProtocolVersion
Definition: EthereumHost.h:93
std::lock_guard< std::mutex > Guard
Definition: Guards.h:41
PopulationStatistics populateFromChain(BlockChain const &_bc, h256 const &_hash, ImportRequirements::value _ir=ImportRequirements::None)
Construct state object from arbitrary point in blockchain.
Definition: Block.cpp:150
virtual void flushTransactions() override
Blocks until all pending transactions have been processed.
Definition: Client.cpp:800
BlockChain & bc() override
InterfaceStub methods.
Definition: Client.h:211
void onDeadBlocks(h256s const &_blocks, h256Hash &io_changed)
Called on chain changes.
Definition: Client.cpp:466
unsigned number(h256 const &_hash) const
Get a number for the given hash (or the most recent mined if none given). Thread-safe.
Definition: BlockChain.h:225
BlockPolarity
Definition: ExtVMFace.h:81
std::chrono::system_clock::time_point since
Definition: Client.h:67
void clearPending()
Clears pending transactions. Just for debug use.
Definition: Client.cpp:288
const char * name
Definition: rest.cpp:36
#define DEV_WRITE_GUARDED(MUTEX)
Definition: Guards.h:148
ExecStats::duration max
Definition: ExecStats.cpp:36
ActivityReport m_report
Definition: Client.h:327
void rewind(unsigned _newHead)
Alter the head of the chain to some prior block along it.
void finalize()
Finalise a transaction previously set up with initialize().
Definition: Executive.cpp:466
u256 networkId() const override
Gets the network id.
Definition: Client.cpp:172
#define EthWhite
Definition: Terminal.h:119
BlockGetAndPut< word32, BigEndian > Block
Definition: cast.cpp:34
virtual void onSealGenerated(std::function< void(bytes const &s)> const &_f)=0
void resyncStateFromChain()
Called after processing blocks by onChainChanged(_ir)
Definition: Client.cpp:497
std::atomic< bool > m_syncBlockQueue
Definition: Client.h:335
#define DEV_READ_GUARDED(MUTEX)
Definition: Guards.h:146
std::vector< byte > bytes
Definition: Common.h:75
void clear()
Clear the queue.
ExecutionResult call(Address _dest, bytes const &_data=bytes(), u256 _gas=125000, u256 _value=0, u256 _gasPrice=1 *ether, Address const &_from=Address())
Makes the given call. Nothing is recorded into the state. This cheats by creating a null address and ...
Definition: Client.cpp:369
#define EthGray
Definition: Terminal.h:118
h256 sha3(IncludeSignature _sig=WithSignature) const
#define cwarn
Definition: Log.h:304
void garbageCollect(bool _force=false)
Deallocate unused data.
Message-call/contract-creation executor; useful for executing transactions.
Definition: Executive.h:106
bool sealBlock(bytes const &_header)
Pass in a properly sealed header matching this block.
Definition: Block.h:268
std::atomic< bool > m_needStateReset
Need reset working state to premin on next sync.
Definition: Client.h:308
boost::multiprecision::number< boost::multiprecision::cpp_int_backend< 256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void >> u256
Definition: Common.h:125
static std::string const & dbPath()
Definition: Defaults.h:41
static void setDBPath(std::string const &_dbPath)
Definition: Defaults.h:40
ImportResult import(bytes const &_tx, IfDropped _ik=IfDropped::Ignore)
Verify and add transaction to the queue synchronously.
bytes m_extraData
Definition: Client.h:337
void startWorking()
Starts worker thread; causes startedWorking() to be called.
Definition: Worker.cpp:30
Transactions const & pending() const
Get the list of pending transactions.
Definition: Block.h:188
Encodes a transaction, ready to be exported to or freshly imported from RLP.
Definition: Transaction.h:84
boost::unique_lock< boost::shared_mutex > WriteGuard
Definition: Guards.h:47
void reopen(WithExisting _we=WithExisting::Trust, ProgressCallback const &_pc=ProgressCallback())
Reopen everything.
Definition: BlockChain.h:114
virtual void onNewBlocks(h256s const &_blocks, h256Hash &io_changed)
Called on chain changes.
Definition: Client.cpp:484
void addCapability(std::shared_ptr< T > const &_p, std::string const &_name, u256 const &_version)
Definition: Host.h:161
BlockQueueStatus status() const
Get some infomration on the current status.
Definition: BlockQueue.cpp:378
Address author() const
Get the author address for any transactions we do and rewards we get.
Definition: Block.h:114
Handler onReady(T const &_t)
Definition: BlockQueue.h:271
#define cwatch
Definition: ClientBase.h:68
std::queue< std::function< void()> > m_functionQueue
Functions waiting to be executed in the main thread.
Definition: Client.h:330
#define f(x)
Definition: gost.cpp:57
void setAuthor(Address const &_id)
Set the author address for any transactions we do and rewards we get.
Definition: Block.h:118
void dropGood(Transaction const &_t)
Drop a trasnaction from the list if exists and move following future trasnactions to current (if any)...
std::shared_ptr< T > registerCapability(std::shared_ptr< T > const &_t)
Register a peer-capability; all new peer connections will have this capability.
Definition: Host.h:160
std::chrono::system_clock::time_point m_lastGetWork
Is there an active and valid remote worker?
Definition: Client.h:309
State & mutableState()
Get a mutable State object which is backing this block.
Definition: Block.h:180
void callQueuedFunctions()
Executes the pending functions in m_functionQueue.
Definition: Client.cpp:154
std::unordered_map< h256, h256s > m_specialFilters
The dictionary of special filters and their additional data.
Definition: ClientBase.h:193
void setChain(BlockChain const &_bc)
Definition: BlockQueue.h:231
void executeInMainThread(std::function< void()> const &_function)
Queues a function to be executed in the main thread (that owns the blockchain, etc).
Definition: Client.cpp:281
#define EthCoal
Definition: Terminal.h:117
bool remoteActive() const
Is there an active and valid remote worker?
Definition: Client.cpp:571
void setOnBad(std::function< void(Exception &)> _t)
Change the function that is called with a bad block.
Definition: BlockChain.h:293
SharedMutex x_functionQueue
Definition: Client.h:329
Block m_preSeal
The present state of the client.
Definition: Client.h:300
virtual void addBalance(Address const &_id, u256 const &_amount)
Add some amount to balance.
Definition: State.cpp:286
TransactionQueue m_tq
}
Definition: ClientBase.h:188
#define EthTeal
Definition: Terminal.h:130
std::weak_ptr< EthereumHost > m_host
Our Ethereum Host. Don&#39;t do anything if we can&#39;t lock.
Definition: Client.h:311
void checkWatchGarbage()
Does garbage collection on watches.
Definition: Client.cpp:716
void syncBlockQueue()
Signal handler for when the block queue needs processing.
Definition: Client.cpp:396
#define clog(X)
Definition: Log.h:295
#define e(i)
Definition: sha.cpp:733
Definition: ExtVMFace.h:112
std::unordered_set< h256 > h256Hash
Definition: FixedHash.h:349
SealEngineFace * sealEngine() const override
Get the seal engine.
Definition: Client.h:176
virtual unsigned number() const override
Definition: ClientBase.cpp:481
#define d(i)
Definition: sha.cpp:732
#define S(a)
Definition: mars.cpp:50
void appendFromBlock(h256 const &_blockHash, BlockPolarity _polarity, h256Hash &io_changed)
Collate the changed filters for the hash of the given block.
Definition: Client.cpp:342
bool m_wouldSeal
True if we /should/ be sealing.
Definition: Client.h:317
#define EthBlue
Definition: Terminal.h:127
ActivityReport activityReport()
Get a report of activity.
Definition: Client.h:191
std::atomic< bool > m_syncTransactionQueue
Definition: Client.h:334
Mutex x_filtersWatches
Our lock.
Definition: ClientBase.h:191
void startSealing() override
Start sealing.
Definition: Client.cpp:583
std::tuple< ImportRoute, bool, unsigned > sync(BlockQueue &_bq, OverlayDB const &_stateDB, unsigned _max)
Sync the chain with any incoming blocks.
Definition: BlockChain.cpp:408
SharedMutex x_working
Lock on m_working.
Definition: Client.h:303
OverlayDB m_stateDB
Acts as the central point for the state database, so multiple States can share it.
Definition: Client.h:298
std::vector< Transaction > goodTranactions
Definition: Common.h:94
std::vector< h256 > h256s
Definition: FixedHash.h:345
virtual Transaction transaction(h256 _transactionHash) const override
Definition: ClientBase.cpp:386
void rescue(OverlayDB const &_db)
Rescue the database.
void onBadBlock(Exception &_ex) const
Called when we have attempted to import a bad block.
Definition: Client.cpp:140
SharedMutex x_postSeal
Lock on m_postSeal.
Definition: Client.h:301
std::condition_variable m_signalled
Definition: Client.h:332
void onChainChanged(ImportRoute const &_ir)
Magically called when the chain has changed.
Definition: Client.cpp:556
Downloading blocks learned from NewHashes packet.
std::map< unsigned, ClientWatch > m_watches
Each and every watch - these reference a filter.
Definition: ClientBase.h:195
#define DEV_TIMED_FUNCTION_ABOVE(MS)
Definition: Common.h:300
Handler< h256 const & > onReplaced(T const &_t)
Register a handler that will be called once asynchronous verification is comeplte an transaction has ...
void setNetworkId(u256 const &_n) override
Sets the network id.
Definition: Client.cpp:179
Handler< h256 const & > m_tqReplaced
Definition: Client.h:314
BlockHeader const & info() const
Get the header information on the present block.
Definition: Block.h:279
std::unordered_map< h256, InstalledFilter > m_filters
The dictionary of filters that are active.
Definition: ClientBase.h:192
void tick()
Ticks various system-level objects.
Definition: Client.cpp:703
virtual void cancelGeneration()
Definition: SealEngine.h:73
void setResultRecipient(ExecutionResult &_res)
Collect execution results in the result storage provided.
Definition: Executive.h:184
bool m_remoteWorking
Has the remote worker recently been reset?
Definition: Client.h:307
ImportResult queueBlock(bytes const &_block, bool _isSafe=false)
Queues a block for import.
Definition: Client.cpp:127
Definition: ExtVMFace.h:88
virtual void prepareForTransaction() override
Definition: Client.cpp:739