EthereumHost.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. /*
  2. This file is part of cpp-ethereum.
  3. cpp-ethereum is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 3 of the License, or
  6. (at your option) any later version.
  7. cpp-ethereum is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. /** @file EthereumHost.h
  15. * @author Gav Wood <i@gavwood.com>
  16. * @date 2014
  17. */
  18. #pragma once
  19. #include <mutex>
  20. #include <unordered_map>
  21. #include <vector>
  22. #include <unordered_set>
  23. #include <memory>
  24. #include <utility>
  25. #include <thread>
  26. #include <libdevcore/Guards.h>
  27. #include <libdevcore/Worker.h>
  28. #include <libethcore/Common.h>
  29. #include <libp2p/Common.h>
  30. #include <libdevcore/OverlayDB.h>
  31. #include "CommonNet.h"
  32. #include "EthereumPeer.h"
  33. namespace dev
  34. {
  35. class RLPStream;
  36. namespace eth
  37. {
  38. class TransactionQueue;
  39. class BlockQueue;
  40. class BlockChainSync;
  41. struct EthereumHostTrace: public LogChannel { static const char* name(); static const int verbosity = 6; };
  42. /**
  43. * @brief The EthereumHost class
  44. * @warning None of this is thread-safe. You have been warned.
  45. * @doWork Syncs to peers and sends new blocks and transactions.
  46. */
  47. class EthereumHost: public p2p::HostCapability<EthereumPeer>, Worker
  48. {
  49. public:
  50. /// Start server, but don't listen.
  51. EthereumHost(BlockChain const& _ch, OverlayDB const& _db, TransactionQueue& _tq, BlockQueue& _bq, u256 _networkId);
  52. /// Will block on network process events.
  53. virtual ~EthereumHost();
  54. unsigned protocolVersion() const { return c_protocolVersion; }
  55. u256 networkId() const { return m_networkId; }
  56. void setNetworkId(u256 _n) { m_networkId = _n; }
  57. void reset();
  58. bool isSyncing() const;
  59. bool isBanned(p2p::NodeID const& _id) const { return !!m_banned.count(_id); }
  60. void noteNewTransactions() { m_newTransactions = true; }
  61. void noteNewBlocks() { m_newBlocks = true; }
  62. BlockChain const& chain() const { return m_chain; }
  63. OverlayDB const& db() const { return m_db; }
  64. BlockQueue& bq() { return m_bq; }
  65. BlockQueue const& bq() const { return m_bq; }
  66. SyncStatus status() const;
  67. h256 latestBlockSent() { return m_latestBlockSent; }
  68. static char const* stateName(SyncState _s) { return s_stateNames[static_cast<int>(_s)]; }
  69. static unsigned const c_oldProtocolVersion;
  70. void foreachPeer(std::function<bool(std::shared_ptr<EthereumPeer>)> const& _f) const;
  71. void onPeerStatus(std::shared_ptr<EthereumPeer> _peer);
  72. void onPeerBlockHeaders(std::shared_ptr<EthereumPeer> _peer, RLP const& _headers);
  73. void onPeerBlockBodies(std::shared_ptr<EthereumPeer> _peer, RLP const& _r);
  74. void onPeerNewHashes(std::shared_ptr<EthereumPeer> _peer, std::vector<std::pair<h256, u256>> const& _hashes);
  75. void onPeerNewBlock(std::shared_ptr<EthereumPeer> _peer, RLP const& _r);
  76. void onPeerTransactions(std::shared_ptr<EthereumPeer> _peer, RLP const& _r);
  77. void onPeerAborting();
  78. private:
  79. static char const* const s_stateNames[static_cast<int>(SyncState::Size)];
  80. std::tuple<std::vector<std::shared_ptr<EthereumPeer>>, std::vector<std::shared_ptr<EthereumPeer>>, std::vector<std::shared_ptr<p2p::Session>>> randomSelection(unsigned _percent = 25, std::function<bool(EthereumPeer*)> const& _allow = [](EthereumPeer const*){ return true; });
  81. /// Sync with the BlockChain. It might contain one of our mined blocks, we might have new candidates from the network.
  82. virtual void doWork() override;
  83. void maintainTransactions();
  84. void maintainBlocks(h256 const& _currentBlock);
  85. void onTransactionImported(ImportResult _ir, h256 const& _h, h512 const& _nodeId);
  86. /// Check to see if the network peer-state initialisation has happened.
  87. bool isInitialised() const { return (bool)m_latestBlockSent; }
  88. /// Initialises the network peer-state, doing the stuff that needs to be once-only. @returns true if it really was first.
  89. bool ensureInitialised();
  90. virtual void onStarting() override { startWorking(); }
  91. virtual void onStopping() override { stopWorking(); }
  92. BlockChain const& m_chain;
  93. OverlayDB const& m_db; ///< References to DB, needed for some of the Ethereum Protocol responses.
  94. TransactionQueue& m_tq; ///< Maintains a list of incoming transactions not yet in a block on the blockchain.
  95. BlockQueue& m_bq; ///< Maintains a list of incoming blocks not yet on the blockchain (to be imported).
  96. u256 m_networkId;
  97. h256 m_latestBlockSent;
  98. h256Hash m_transactionsSent;
  99. std::unordered_set<p2p::NodeID> m_banned;
  100. bool m_newTransactions = false;
  101. bool m_newBlocks = false;
  102. mutable RecursiveMutex x_sync;
  103. mutable Mutex x_transactions;
  104. std::unique_ptr<BlockChainSync> m_sync;
  105. std::atomic<time_t> m_lastTick = { 0 };
  106. };
  107. }
  108. }