Ethereum  PoC-8
The C++ Implementation of Ethereum
EthereumCapability.h
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 */
17 
18 #pragma once
19 
20 #include "CommonNet.h"
21 #include "EthereumPeer.h"
22 #include <libdevcore/Guards.h>
23 #include <libdevcore/OverlayDB.h>
24 #include <libethcore/BlockHeader.h>
25 #include <libethcore/Common.h>
27 #include <libp2p/Capability.h>
28 #include <libp2p/CapabilityHost.h>
29 #include <libp2p/Common.h>
30 #include <memory>
31 #include <mutex>
32 #include <random>
33 #include <thread>
34 #include <unordered_map>
35 #include <unordered_set>
36 #include <utility>
37 #include <vector>
38 
39 namespace dev
40 {
41 
42 class RLPStream;
43 
44 namespace eth
45 {
46 
47 class TransactionQueue;
48 class BlockQueue;
49 class BlockChainSync;
50 
52 {
53 public:
54  virtual ~EthereumPeerObserverFace() = default;
55 
56  virtual void onPeerStatus(EthereumPeer const& _peer) = 0;
57 
58  virtual void onPeerTransactions(NodeID const& _peerID, RLP const& _r) = 0;
59 
60  virtual void onPeerBlockHeaders(NodeID const& _peerID, RLP const& _headers) = 0;
61 
62  virtual void onPeerBlockBodies(NodeID const& _peerID, RLP const& _r) = 0;
63 
64  virtual void onPeerNewHashes(
65  NodeID const& _peerID, std::vector<std::pair<h256, u256>> const& _hashes) = 0;
66 
67  virtual void onPeerNewBlock(NodeID const& _peerID, RLP const& _r) = 0;
68 
69  virtual void onPeerNodeData(NodeID const& _peerID, RLP const& _r) = 0;
70 
71  virtual void onPeerReceipts(NodeID const& _peerID, RLP const& _r) = 0;
72 
73  virtual void onPeerAborting() = 0;
74 };
75 
77 {
78 public:
79  virtual ~EthereumHostDataFace() = default;
80 
81  virtual std::pair<bytes, unsigned> blockHeaders(
82  RLP const& _blockId, unsigned _maxHeaders, u256 _skip, bool _reverse) const = 0;
83 
84  virtual std::pair<bytes, unsigned> blockBodies(RLP const& _blockHashes) const = 0;
85 
86  virtual strings nodeData(RLP const& _dataHashes) const = 0;
87 
88  virtual std::pair<bytes, unsigned> receipts(RLP const& _blockHashes) const = 0;
89 };
90 
91 
97 class EthereumCapability : public p2p::CapabilityFace
98 {
99 public:
101  EthereumCapability(std::shared_ptr<p2p::CapabilityHostFace> _host, BlockChain const& _ch,
102  OverlayDB const& _db, TransactionQueue& _tq, BlockQueue& _bq, u256 _networkId);
103 
104  std::string name() const override { return "eth"; }
105  u256 version() const override { return c_protocolVersion; }
106  unsigned messageCount() const override { return PacketCount; }
107 
108  void onStarting() override;
109  void onStopping() override;
110 
111  unsigned protocolVersion() const { return c_protocolVersion; }
112  u256 networkId() const { return m_networkId; }
113  void setNetworkId(u256 _n) { m_networkId = _n; }
114 
115  void reset();
117  void completeSync();
118 
119  bool isSyncing() const;
120 
121  void noteNewTransactions() { m_newTransactions = true; }
122  void noteNewBlocks() { m_newBlocks = true; }
123  void onBlockImported(BlockHeader const& _info) { m_sync->onBlockImported(_info); }
124 
125  BlockChain const& chain() const { return m_chain; }
126  OverlayDB const& db() const { return m_db; }
127  BlockQueue& bq() { return m_bq; }
128  BlockQueue const& bq() const { return m_bq; }
129  SyncStatus status() const;
130 
131  static char const* stateName(SyncState _s) { return s_stateNames[static_cast<int>(_s)]; }
132 
133  static unsigned const c_oldProtocolVersion;
134 
135  void onConnect(NodeID const& _nodeID, u256 const& _peerCapabilityVersion) override;
136  void onDisconnect(NodeID const& _nodeID) override;
137  bool interpretCapabilityPacket(NodeID const& _peerID, unsigned _id, RLP const& _r) override;
138 
139  p2p::CapabilityHostFace& capabilityHost() { return *m_host; }
140 
141  EthereumPeer const& peer(NodeID const& _peerID) const;
142  EthereumPeer& peer(NodeID const& _peerID);
143  void disablePeer(NodeID const& _peerID, std::string const& _problem);
144 
145 private:
146  static char const* const s_stateNames[static_cast<int>(SyncState::Size)];
147 
148  std::vector<NodeID> selectPeers(
149  std::function<bool(EthereumPeer const&)> const& _predicate) const;
150 
151  std::pair<std::vector<NodeID>, std::vector<NodeID>> randomPartitionPeers(
152  std::vector<NodeID> const& _peers, std::size_t _number) const;
153 
154  void doBackgroundWork();
155 
156  void maintainTransactions();
157  void maintainBlocks(h256 const& _currentBlock);
158  void onTransactionImported(ImportResult _ir, h256 const& _h, h512 const& _nodeId);
159 
161  bool ensureInitialised();
162 
163  void setIdle(NodeID const& _peerID);
164  void setAsking(NodeID const& _peerID, Asking _a);
165 
167  bool isCriticalSyncing(NodeID const& _peerID) const;
168 
170  bool needsSyncing(NodeID const& _peerID) const;
171 
172  std::shared_ptr<p2p::CapabilityHostFace> m_host;
173 
174  BlockChain const& m_chain;
175  OverlayDB const& m_db;
176  TransactionQueue& m_tq;
177  BlockQueue& m_bq;
178 
179  u256 m_networkId;
180 
181  h256 m_latestBlockSent;
182  h256Hash m_transactionsSent;
183 
184  std::atomic<bool> m_newTransactions = {false};
185  std::atomic<bool> m_newBlocks = {false};
186 
187  std::shared_ptr<BlockChainSync> m_sync;
188  std::atomic<time_t> m_lastTick = { 0 };
189 
190  std::unique_ptr<EthereumHostDataFace> m_hostData;
191  std::unique_ptr<EthereumPeerObserverFace> m_peerObserver;
192 
193  std::unordered_map<NodeID, EthereumPeer> m_peers;
194 
195  std::atomic<bool> m_backgroundWorkEnabled = {false};
196 
197  mutable std::mt19937_64 m_urng; // Mersenne Twister psuedo-random number generator
198 
199  Logger m_logger{createLogger(VerbosityDebug, "ethcap")};
201  Logger m_loggerImpolite{createLogger(VerbosityDebug, "impolite")};
202 };
203 
204 }
205 }
Definition: Address.cpp:20
static unsigned const c_oldProtocolVersion
virtual void onPeerBlockBodies(NodeID const &_peerID, RLP const &_r)=0
virtual strings nodeData(RLP const &_dataHashes) const =0
const unsigned c_protocolVersion
Current protocol version.
Definition: Common.cpp:40
EthereumCapability(std::shared_ptr< p2p::CapabilityHostFace > _host, BlockChain const &_ch, OverlayDB const &_db, TransactionQueue &_tq, BlockQueue &_bq, u256 _networkId)
Start server, but don&#39;t listen.
A queue of Transactions, each stored as RLP. Maintains a transaction queue sorted by nonce diff and g...
virtual ~EthereumPeerObserverFace()=default
void onDisconnect(NodeID const &_nodeID) override
virtual void onPeerStatus(EthereumPeer const &_peer)=0
Implements the blockchain database. All data this gives is disk-backed. .
Definition: BlockChain.h:104
Encapsulation of a block header. Class to contain all of a block header&#39;s data. It is able to parse a...
Definition: BlockHeader.h:96
void onBlockImported(BlockHeader const &_info)
void completeSync()
Don&#39;t sync further - used only in test mode.
bool interpretCapabilityPacket(NodeID const &_peerID, unsigned _id, RLP const &_r) override
The EthereumCapability class.
std::vector< std::string > strings
Definition: Common.h:143
virtual void onPeerNodeData(NodeID const &_peerID, RLP const &_r)=0
EthereumPeer const & peer(NodeID const &_peerID) const
virtual std::pair< bytes, unsigned > blockBodies(RLP const &_blockHashes) const =0
void disablePeer(NodeID const &_peerID, std::string const &_problem)
OverlayDB const & db() const
virtual void onPeerBlockHeaders(NodeID const &_peerID, RLP const &_headers)=0
ImportResult
Definition: Common.h:115
virtual void onPeerReceipts(NodeID const &_peerID, RLP const &_r)=0
p2p::NodeID NodeID
Definition: CommonNet.h:105
Must be kept last.
Logger createLogger(int _severity, std::string const &_channel)
Definition: Log.h:125
void onConnect(NodeID const &_nodeID, u256 const &_peerCapabilityVersion) override
BlockQueue const & bq() const
A queue of blocks. Sits between network or other I/O and the BlockChain. Sorts them ready for blockch...
Definition: BlockQueue.h:223
u256 version() const override
virtual void onPeerNewHashes(NodeID const &_peerID, std::vector< std::pair< h256, u256 >> const &_hashes)=0
virtual void onPeerNewBlock(NodeID const &_peerID, RLP const &_r)=0
virtual void onPeerTransactions(NodeID const &_peerID, RLP const &_r)=0
virtual std::pair< bytes, unsigned > blockHeaders(RLP const &_blockId, unsigned _maxHeaders, u256 _skip, bool _reverse) const =0
boost::multiprecision::number< boost::multiprecision::cpp_int_backend< 256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void > > u256
Definition: Common.h:121
virtual ~EthereumHostDataFace()=default
std::string name() const override
virtual std::pair< bytes, unsigned > receipts(RLP const &_blockHashes) const =0
unsigned messageCount() const override
std::unordered_set< h256 > h256Hash
Definition: FixedHash.h:363
Definition: RLP.h:47
static char const * stateName(SyncState _s)
boost::log::sources::severity_channel_logger<> Logger
Definition: Log.h:124
p2p::CapabilityHostFace & capabilityHost()
BlockChain const & chain() const