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