Ethereum  PoC-8
The C++ Implementation of Ethereum
WarpCapability.cpp
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 #include "WarpCapability.h"
6 #include "BlockChain.h"
7 #include "SnapshotStorage.h"
8 
9 #include <boost/fiber/all.hpp>
10 #include <chrono>
11 
12 namespace dev
13 {
14 namespace eth
15 {
16 
17 std::chrono::milliseconds constexpr WarpCapability::c_backgroundWorkInterval;
18 
19 namespace
20 {
21 static size_t const c_freePeerBufferSize = 32;
22 
23 bool validateManifest(RLP const& _manifestRlp)
24 {
25  if (!_manifestRlp.isList() || _manifestRlp.itemCount() != 1)
26  return false;
27 
28  RLP const manifest = _manifestRlp[0];
29 
30  u256 const version = manifest[0].toInt<u256>();
31  return version == 2;
32 }
33 
34 h256 snapshotBlockHash(RLP const& _manifestRlp)
35 {
36  RLP const manifest = _manifestRlp[0];
37  return manifest[5].toHash<h256>();
38 }
39 
40 class WarpPeerObserver : public WarpPeerObserverFace
41 {
42 public:
43  WarpPeerObserver(WarpCapability& _host, BlockChain const& _blockChain,
44  boost::filesystem::path const& _snapshotPath)
45  : m_host(_host),
46  m_hostProtocolVersion(_host.version()),
47  m_hostNetworkId(_host.networkId()),
48  m_hostGenesisHash(_blockChain.genesisHash()),
49  m_daoForkBlock(_blockChain.sealEngine()->chainParams().daoHardforkBlock),
50  m_freePeers(c_freePeerBufferSize),
51  m_snapshotDir(_snapshotPath)
52  {}
53  ~WarpPeerObserver()
54  {
55  if (m_downloadFiber)
56  m_downloadFiber->join();
57  }
58 
59  void onPeerStatus(NodeID const& _peerID) override
60  {
61  boost::fibers::fiber checkPeerFiber(&WarpPeerObserver::validatePeer, this, _peerID);
62  checkPeerFiber.detach();
63 
64  // start the downloading fiber in the thread handling network messages
65  if (!m_downloadFiber)
66  m_downloadFiber.reset(
67  new boost::fibers::fiber(&WarpPeerObserver::downloadChunks, this));
68 
69  boost::this_fiber::yield();
70  }
71 
72  void onPeerManifest(NodeID const& _peerID, RLP const& _r) override
73  {
74  m_manifests[_peerID].set_value(_r.data().toBytes());
75  boost::this_fiber::yield();
76  }
77 
78  void onPeerBlockHeaders(NodeID const& _peerID, RLP const& _r) override
79  {
80  m_daoForkHeaders[_peerID].set_value(_r.data().toBytes());
81  boost::this_fiber::yield();
82  }
83 
84  void onPeerData(NodeID const& _peerID, RLP const& _r) override
85  {
86  if (!_r.isList() || _r.itemCount() != 1)
87  return;
88 
89  RLP const data = _r[0];
90 
91  h256 const hash = sha3(data.toBytesConstRef());
92 
93  auto it = m_requestedChunks.find(_peerID);
94  if (it == m_requestedChunks.end())
95  return;
96 
97  h256 const askedHash = it->second;
98  m_requestedChunks.erase(it);
99 
100  if (hash == askedHash)
101  {
102  // TODO handle writeFile failure
103  writeFile((boost::filesystem::path(m_snapshotDir) / toHex(hash)).string(),
104  data.toBytesConstRef());
105 
106  LOG(m_logger) << "Saved chunk " << hash << " Chunks left: " << m_neededChunks.size()
107  << " Requested chunks: " << m_requestedChunks.size();
108  if (m_neededChunks.empty() && m_requestedChunks.empty())
109  LOG(m_logger) << "Snapshot download complete!";
110  }
111  else
112  m_neededChunks.push_back(askedHash);
113 
114  m_freePeers.push(_peerID);
115  boost::this_fiber::yield();
116  }
117 
118  void onPeerDisconnect(NodeID const& _peerID, Asking _asking) override
119  {
120  if (_asking == Asking::WarpManifest)
121  {
122  auto it = m_manifests.find(_peerID);
123  if (it != m_manifests.end())
124  it->second.set_exception(std::make_exception_ptr(FailedToDownloadManifest()));
125  }
126  else if (_asking == Asking::BlockHeaders)
127  {
128  auto it = m_daoForkHeaders.find(_peerID);
129  if (it != m_daoForkHeaders.end())
130  it->second.set_exception(
131  std::make_exception_ptr(FailedToDownloadDaoForkBlockHeader()));
132  }
133  else if (_asking == Asking::WarpData)
134  {
135  auto it = m_requestedChunks.find(_peerID);
136  if (it != m_requestedChunks.end())
137  {
138  m_neededChunks.push_back(it->second);
139  m_requestedChunks.erase(it);
140  }
141  }
142  boost::this_fiber::yield();
143  }
144 
145 private:
146  void validatePeer(NodeID _peerID)
147  {
148  if (!m_host.validateStatus(
149  _peerID, m_hostGenesisHash, {m_hostProtocolVersion}, m_hostNetworkId))
150  return;
151 
152  m_host.requestManifest(_peerID);
153 
154  bytes const manifestBytes = waitForManifestResponse(_peerID);
155  if (manifestBytes.empty())
156  return;
157 
158  RLP manifestRlp(manifestBytes);
159  if (!validateManifest(manifestRlp))
160  {
161  // TODO try disconnecting instead of disabling; disabled peer still occupies the peer slot
162  m_host.disablePeer(_peerID, "Invalid snapshot manifest.");
163  return;
164  }
165 
166  u256 const snapshotHash = snapshotBlockHash(manifestRlp);
167  if (m_syncingSnapshotHash)
168  {
169  if (snapshotHash == m_syncingSnapshotHash)
170  m_freePeers.push(_peerID);
171  else
172  m_host.disablePeer(_peerID, "Another snapshot.");
173  }
174  else
175  {
176  if (m_daoForkBlock)
177  {
178  m_host.requestBlockHeaders(_peerID, m_daoForkBlock, 1, 0, false);
179 
180  bytes const headerBytes = waitForDaoForkBlockResponse(_peerID);
181  if (headerBytes.empty())
182  return;
183 
184  RLP headerRlp(headerBytes);
185  if (!verifyDaoChallengeResponse(headerRlp))
186  {
187  m_host.disablePeer(_peerID, "Peer from another fork.");
188  return;
189  }
190  }
191 
192  m_syncingSnapshotHash = snapshotHash;
193  m_manifest.set_value(manifestBytes);
194  m_freePeers.push(_peerID);
195  }
196  }
197 
198  bytes waitForManifestResponse(NodeID const& _peerID)
199  {
200  try
201  {
202  bytes const result = m_manifests[_peerID].get_future().get();
203  m_manifests.erase(_peerID);
204  return result;
205  }
206  catch (Exception const&)
207  {
208  m_manifests.erase(_peerID);
209  }
210  return bytes{};
211  }
212 
213  bytes waitForDaoForkBlockResponse(NodeID const& _peerID)
214  {
215  try
216  {
217  bytes const result = m_daoForkHeaders[_peerID].get_future().get();
218  m_daoForkHeaders.erase(_peerID);
219  return result;
220  }
221  catch (Exception const&)
222  {
223  m_daoForkHeaders.erase(_peerID);
224  }
225  return bytes{};
226  }
227 
228  bool verifyDaoChallengeResponse(RLP const& _r)
229  {
230  if (_r.itemCount() != 1)
231  return false;
232 
233  BlockHeader info(_r[0].data(), HeaderData);
234  return info.number() == m_daoForkBlock &&
235  info.extraData() == fromHex("0x64616f2d686172642d666f726b");
236  }
237 
238  void downloadChunks()
239  {
240  bytes const manifestBytes = m_manifest.get_future().get();
241 
242  RLP manifestRlp(manifestBytes);
243  RLP manifest(manifestRlp[0]);
244 
245  u256 const version = manifest[0].toInt<u256>();
246  h256s const stateHashes = manifest[1].toVector<h256>();
247  h256s const blockHashes = manifest[2].toVector<h256>();
248  h256 const stateRoot = manifest[3].toHash<h256>();
249  u256 const blockNumber = manifest[4].toInt<u256>();
250  h256 const blockHash = manifest[5].toHash<h256>();
251 
252  LOG(m_logger) << "MANIFEST: "
253  << "version " << version << " state root " << stateRoot << " block number "
254  << blockNumber << " block hash " << blockHash;
255 
256  // TODO handle writeFile failure
257  writeFile((boost::filesystem::path(m_snapshotDir) / "MANIFEST").string(), manifest.data());
258 
259  m_neededChunks.assign(stateHashes.begin(), stateHashes.end());
260  m_neededChunks.insert(m_neededChunks.end(), blockHashes.begin(), blockHashes.end());
261 
262  while (!m_neededChunks.empty())
263  {
264  h256 const chunkHash(m_neededChunks.front());
265 
266  NodeID peerID;
267  do
268  {
269  peerID = m_freePeers.value_pop();
270  } while (!m_host.requestData(peerID, chunkHash));
271 
272  LOG(m_logger) << "Requested chunk " << chunkHash;
273 
274  m_requestedChunks[peerID] = chunkHash;
275  m_neededChunks.pop_front();
276  }
277  }
278 
279  WarpCapability& m_host;
280  unsigned const m_hostProtocolVersion;
281  u256 const m_hostNetworkId;
282  h256 const m_hostGenesisHash;
283  unsigned const m_daoForkBlock;
284  boost::fibers::promise<bytes> m_manifest;
285  h256 m_syncingSnapshotHash;
286  std::deque<h256> m_neededChunks;
287  boost::fibers::buffered_channel<NodeID> m_freePeers;
288  boost::filesystem::path const m_snapshotDir;
289  std::map<NodeID, boost::fibers::promise<bytes>> m_manifests;
290  std::map<NodeID, boost::fibers::promise<bytes>> m_daoForkHeaders;
291  std::map<NodeID, h256> m_requestedChunks;
292 
293  std::unique_ptr<boost::fibers::fiber> m_downloadFiber;
294 
295  Logger m_logger{createLogger(VerbosityInfo, "snap")};
296 };
297 
298 } // namespace
299 
300 
301 WarpCapability::WarpCapability(std::shared_ptr<p2p::CapabilityHostFace> _host,
302  BlockChain const& _blockChain, u256 const& _networkId,
303  boost::filesystem::path const& _snapshotDownloadPath,
304  std::shared_ptr<SnapshotStorageFace> _snapshotStorage)
305  : m_host(std::move(_host)),
306  m_blockChain(_blockChain),
307  m_networkId(_networkId),
308  m_snapshot(_snapshotStorage),
309  // observer needed only in case we download snapshot
310  m_peerObserver(
311  _snapshotDownloadPath.empty() ? nullptr : createPeerObserver(_snapshotDownloadPath))
312 {
313 }
314 
315 std::chrono::milliseconds WarpCapability::backgroundWorkInterval() const
316 {
317  return c_backgroundWorkInterval;
318 }
319 
320 std::shared_ptr<WarpPeerObserverFace> WarpCapability::createPeerObserver(
321  boost::filesystem::path const& _snapshotDownloadPath)
322 {
323  return std::make_shared<WarpPeerObserver>(*this, m_blockChain, _snapshotDownloadPath);
324 }
325 
326 void WarpCapability::onConnect(NodeID const& _peerID, u256 const& /* _peerCapabilityVersion */)
327 {
328  m_peers.emplace(_peerID, WarpPeerStatus{});
329 
330  u256 snapshotBlockNumber;
331  h256 snapshotBlockHash;
332  if (m_snapshot)
333  {
334  bytes const snapshotManifest(m_snapshot->readManifest());
335  RLP manifest(snapshotManifest);
336  if (manifest.itemCount() != 6)
337  BOOST_THROW_EXCEPTION(InvalidSnapshotManifest());
338  snapshotBlockNumber = manifest[4].toInt<u256>(RLP::VeryStrict);
339  snapshotBlockHash = manifest[5].toHash<h256>(RLP::VeryStrict);
340  }
341 
342  requestStatus(_peerID, c_WarpProtocolVersion, m_networkId,
343  m_blockChain.details().totalDifficulty, m_blockChain.currentHash(),
344  m_blockChain.genesisHash(), snapshotBlockHash, snapshotBlockNumber);
345 }
346 
347 bool WarpCapability::interpretCapabilityPacket(NodeID const& _peerID, unsigned _id, RLP const& _r)
348 {
349  auto& peerStatus = m_peers[_peerID];
350  peerStatus.m_lastAsk = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
351 
352  try
353  {
354  switch (_id)
355  {
356  case WarpStatusPacket:
357  {
358  if (_r.itemCount() < 7)
359  BOOST_THROW_EXCEPTION(InvalidWarpStatusPacket());
360 
361  // Packet layout:
362  // [ version:P, state_hashes : [hash_1:B_32, hash_2 : B_32, ...], block_hashes :
363  // [hash_1:B_32, hash_2 : B_32, ...],
364  // state_root : B_32, block_number : P, block_hash : B_32 ]
365  peerStatus.m_protocolVersion = _r[0].toInt<unsigned>();
366  peerStatus.m_networkId = _r[1].toInt<u256>();
367  peerStatus.m_totalDifficulty = _r[2].toInt<u256>();
368  peerStatus.m_latestHash = _r[3].toHash<h256>();
369  peerStatus.m_genesisHash = _r[4].toHash<h256>();
370  peerStatus.m_snapshotHash = _r[5].toHash<h256>();
371  peerStatus.m_snapshotNumber = _r[6].toInt<u256>();
372 
373  cnetlog << "Status: "
374  << " protocol version " << peerStatus.m_protocolVersion << " networkId "
375  << peerStatus.m_networkId << " genesis hash " << peerStatus.m_genesisHash
376  << " total difficulty " << peerStatus.m_totalDifficulty << " latest hash "
377  << peerStatus.m_latestHash << " snapshot hash " << peerStatus.m_snapshotHash
378  << " snapshot number " << peerStatus.m_snapshotNumber;
379  setIdle(_peerID);
380  m_peerObserver->onPeerStatus(_peerID);
381  break;
382  }
383  case GetSnapshotManifest:
384  {
385  if (!m_snapshot)
386  return false;
387 
388  RLPStream s;
389  m_host->prep(_peerID, name(), s, SnapshotManifest, 1)
390  .appendRaw(m_snapshot->readManifest());
391  m_host->sealAndSend(_peerID, s);
392  break;
393  }
394  case GetSnapshotData:
395  {
396  if (!m_snapshot)
397  return false;
398 
399  const h256 chunkHash = _r[0].toHash<h256>(RLP::VeryStrict);
400 
401  RLPStream s;
402  m_host->prep(_peerID, name(), s, SnapshotData, 1)
403  .append(m_snapshot->readCompressedChunk(chunkHash));
404  m_host->sealAndSend(_peerID, s);
405  break;
406  }
408  {
409  // TODO We are being asked DAO fork block sometimes, need to be able to answer this
410  RLPStream s;
411  m_host->prep(_peerID, name(), s, BlockHeadersPacket);
412  m_host->sealAndSend(_peerID, s);
413  break;
414  }
415  case BlockHeadersPacket:
416  {
417  setIdle(_peerID);
418  m_peerObserver->onPeerBlockHeaders(_peerID, _r);
419  break;
420  }
421  case SnapshotManifest:
422  {
423  setIdle(_peerID);
424  m_peerObserver->onPeerManifest(_peerID, _r);
425  break;
426  }
427  case SnapshotData:
428  {
429  setIdle(_peerID);
430  m_peerObserver->onPeerData(_peerID, _r);
431  break;
432  }
433  default:
434  return false;
435  }
436  }
437  catch (Exception const&)
438  {
439  cnetlog << "Warp Peer causing an Exception: "
440  << boost::current_exception_diagnostic_information() << " " << _r;
441  }
442  catch (std::exception const& _e)
443  {
444  cnetlog << "Warp Peer causing an exception: " << _e.what() << " " << _r;
445  }
446 
447  return true;
448 }
449 
451 {
452  m_peerObserver->onPeerDisconnect(_peerID, m_peers[_peerID].m_asking);
453  m_peers.erase(_peerID);
454 }
455 
457 {
458  for (auto const& peer : m_peers)
459  {
460  time_t now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
461  auto const& status = peer.second;
462  if (now - status.m_lastAsk > 10 && status.m_asking != Asking::Nothing)
463  {
464  // timeout
465  m_host->disconnect(peer.first, p2p::PingTimeout);
466  }
467  }
468 }
469 
470 void WarpCapability::requestStatus(NodeID const& _peerID, unsigned _hostProtocolVersion,
471  u256 const& _hostNetworkId, u256 const& _chainTotalDifficulty, h256 const& _chainCurrentHash,
472  h256 const& _chainGenesisHash, h256 const& _snapshotBlockHash, u256 const& _snapshotBlockNumber)
473 {
474  RLPStream s;
475  m_host->prep(_peerID, name(), s, WarpStatusPacket, 7)
476  << _hostProtocolVersion << _hostNetworkId << _chainTotalDifficulty << _chainCurrentHash
477  << _chainGenesisHash << _snapshotBlockHash << _snapshotBlockNumber;
478  m_host->sealAndSend(_peerID, s);
479 }
480 
481 
483  NodeID const& _peerID, unsigned _startNumber, unsigned _count, unsigned _skip, bool _reverse)
484 {
485  auto itPeerStatus = m_peers.find(_peerID);
486  if (itPeerStatus == m_peers.end())
487  return;
488 
489  assert(itPeerStatus->second.m_asking == Asking::Nothing);
490  setAsking(_peerID, Asking::BlockHeaders);
491  RLPStream s;
492  m_host->prep(_peerID, name(), s, GetBlockHeadersPacket, 4)
493  << _startNumber << _count << _skip << (_reverse ? 1 : 0);
494  m_host->sealAndSend(_peerID, s);
495 }
496 
498 {
499  auto itPeerStatus = m_peers.find(_peerID);
500  if (itPeerStatus == m_peers.end())
501  return;
502 
503  assert(itPeerStatus->second.m_asking == Asking::Nothing);
504  setAsking(_peerID, Asking::WarpManifest);
505  RLPStream s;
506  m_host->prep(_peerID, name(), s, GetSnapshotManifest);
507  m_host->sealAndSend(_peerID, s);
508 }
509 
510 bool WarpCapability::requestData(NodeID const& _peerID, h256 const& _chunkHash)
511 {
512  auto itPeerStatus = m_peers.find(_peerID);
513  if (itPeerStatus == m_peers.end())
514  return false;
515 
516  assert(itPeerStatus->second.m_asking == Asking::Nothing);
517  setAsking(_peerID, Asking::WarpData);
518  RLPStream s;
519 
520  m_host->prep(_peerID, name(), s, GetSnapshotData, 1) << _chunkHash;
521  m_host->sealAndSend(_peerID, s);
522  return true;
523 }
524 
525 void WarpCapability::setAsking(NodeID const& _peerID, Asking _a)
526 {
527  auto itPeerStatus = m_peers.find(_peerID);
528  if (itPeerStatus == m_peers.end())
529  return;
530 
531  auto& peerStatus = itPeerStatus->second;
532 
533  peerStatus.m_asking = _a;
534  peerStatus.m_lastAsk = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
535 }
536 
538 bool WarpCapability::validateStatus(NodeID const& _peerID, h256 const& _genesisHash,
539  std::vector<unsigned> const& _protocolVersions, u256 const& _networkId)
540 {
541  auto itPeerStatus = m_peers.find(_peerID);
542  if (itPeerStatus == m_peers.end())
543  return false; // Expired
544 
545  auto const& peerStatus = itPeerStatus->second;
546 
547  if (peerStatus.m_genesisHash != _genesisHash)
548  {
549  disablePeer(_peerID, "Invalid genesis hash");
550  return false;
551  }
552  if (find(_protocolVersions.begin(), _protocolVersions.end(), peerStatus.m_protocolVersion) ==
553  _protocolVersions.end())
554  {
555  disablePeer(_peerID, "Invalid protocol version.");
556  return false;
557  }
558  if (peerStatus.m_networkId != _networkId)
559  {
560  disablePeer(_peerID, "Invalid network identifier.");
561  return false;
562  }
563  if (peerStatus.m_asking != Asking::State && peerStatus.m_asking != Asking::Nothing)
564  {
565  disablePeer(_peerID, "Peer banned for unexpected status message.");
566  return false;
567  }
568 
569  return true;
570 }
571 
572 void WarpCapability::disablePeer(NodeID const& _peerID, std::string const& _problem)
573 {
574  m_host->disableCapability(_peerID, name(), _problem);
575 }
576 
577 } // namespace eth
578 } // namespace dev
dev::eth::Asking::WarpManifest
@ WarpManifest
dev::eth::BlockChain::currentHash
h256 currentHash() const
Get a given block (RLP format). Thread-safe.
Definition: BlockChain.h:228
dev::RLP::VeryStrict
@ VeryStrict
Definition: RLP.h:58
dev::eth::WarpCapability::requestData
bool requestData(NodeID const &_peerID, h256 const &_chunkHash)
Definition: WarpCapability.cpp:510
dev::eth::HeaderData
@ HeaderData
Definition: BlockHeader.h:69
SnapshotStorage.h
dev::sha3
bool sha3(bytesConstRef _input, bytesRef o_output) noexcept
Definition: SHA3.cpp:28
dev::eth::BlockChain::genesisHash
h256 genesisHash() const
Get the hash of the genesis block. Thread-safe.
Definition: BlockChain.h:231
dev::eth::WarpCapability::requestManifest
void requestManifest(NodeID const &_peerID)
Definition: WarpCapability.cpp:497
dev::h256
FixedHash< 32 > h256
Definition: FixedHash.h:356
dev::eth::WarpCapability::interpretCapabilityPacket
bool interpretCapabilityPacket(NodeID const &_peerID, unsigned _id, RLP const &) override
Definition: WarpCapability.cpp:347
dev::eth::WarpCapability::requestStatus
void requestStatus(NodeID const &_peerID, unsigned _hostProtocolVersion, u256 const &_hostNetworkId, u256 const &_chainTotalDifficulty, h256 const &_chainCurrentHash, h256 const &_chainGenesisHash, h256 const &_snapshotBlockHash, u256 const &_snapshotBlockNumber)
Definition: WarpCapability.cpp:470
dev::eth::WarpCapability::WarpCapability
WarpCapability(std::shared_ptr< p2p::CapabilityHostFace > _host, BlockChain const &_blockChain, u256 const &_networkId, boost::filesystem::path const &_snapshotDownloadPath, std::shared_ptr< SnapshotStorageFace > _snapshotStorage)
Definition: WarpCapability.cpp:301
dev::FixedHash< 32 >
dev::VerbosityInfo
@ VerbosityInfo
Definition: Log.h:70
dev::eth::GetBlockHeadersPacket
@ GetBlockHeadersPacket
Definition: CommonNet.h:58
dev::eth::GetSnapshotManifest
@ GetSnapshotManifest
Definition: WarpCapability.h:22
dev::eth::WarpCapability::onConnect
void onConnect(NodeID const &_peerID, u256 const &_peerCapabilityVersion) override
Definition: WarpCapability.cpp:326
dev::Exception
Base class for all exceptions.
Definition: Exceptions.h:39
LOG
#define LOG
Definition: Log.h:63
dev::eth::WarpCapability::doBackgroundWork
void doBackgroundWork() override
Definition: WarpCapability.cpp:456
dev::eth::WarpCapability::backgroundWorkInterval
std::chrono::milliseconds backgroundWorkInterval() const override
Definition: WarpCapability.cpp:315
dev::eth::BlockChain::details
BlockDetails details(h256 const &_hash) const
Get the familial details concerning a block (or the most recent mined if none given)....
Definition: BlockChain.h:157
dev::eth::WarpStatusPacket
@ WarpStatusPacket
Definition: WarpCapability.h:21
dev::h256s
std::vector< h256 > h256s
Definition: FixedHash.h:361
dev::Logger
boost::log::sources::severity_channel_logger<> Logger
Definition: Log.h:124
dev::eth::Asking::State
@ State
dev::eth::BlockDetails::totalDifficulty
u256 totalDifficulty
Definition: BlockDetails.h:52
dev::eth::WarpCapability::name
std::string name() const override
Definition: WarpCapability.h:76
dev::eth::Asking
Asking
Definition: CommonNet.h:73
dev::bytes
std::vector< byte > bytes
Definition: Common.h:72
dev::createLogger
Logger createLogger(int _severity, std::string const &_channel)
Definition: Log.h:125
dev::eth::NodeID
p2p::NodeID NodeID
Definition: CommonNet.h:105
WarpCapability.h
dev::eth::c_WarpProtocolVersion
unsigned const c_WarpProtocolVersion
Definition: WarpCapability.h:17
dev::eth::BlockChain
Implements the blockchain database. All data this gives is disk-backed. @threadsafe.
Definition: BlockChain.h:105
dev::eth::WarpCapability::requestBlockHeaders
void requestBlockHeaders(NodeID const &_peerID, unsigned _startNumber, unsigned _count, unsigned _skip, bool _reverse)
Definition: WarpCapability.cpp:482
BlockChain.h
dev::eth::WarpCapability::onDisconnect
void onDisconnect(NodeID const &_peerID) override
Definition: WarpCapability.cpp:450
dev::RLPStream
Class for writing to an RLP bytestream.
Definition: RLP.h:370
dev::eth::WarpPeerStatus
Definition: WarpCapability.h:31
dev::eth::GetSnapshotData
@ GetSnapshotData
Definition: WarpCapability.h:24
dev::eth::WarpCapability::validateStatus
bool validateStatus(NodeID const &_peerID, h256 const &_genesisHash, std::vector< unsigned > const &_protocolVersions, u256 const &_networkId)
Validates whether peer is able to communicate with the host, disables peer if not.
Definition: WarpCapability.cpp:538
dev::RLP::itemCount
size_t itemCount() const
Definition: RLP.h:101
std
Definition: FixedHash.h:393
dev::eth::BlockHeadersPacket
@ BlockHeadersPacket
Definition: CommonNet.h:59
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::RLP::toInt
_T toInt(int _flags=Strict) const
Converts to int of type given; if isData(), decodes as big-endian bytestream.
Definition: RLP.h:257
dev::RLP::toHash
_N toHash(int _flags=Strict) const
Definition: RLP.h:288
dev
Definition: Address.cpp:21
dev::eth::SnapshotData
@ SnapshotData
Definition: WarpCapability.h:25
dev::eth::Asking::BlockHeaders
@ BlockHeaders
dev::writeFile
void writeFile(boost::filesystem::path const &_file, bytesConstRef _data, bool _writeDeleteRename)
Definition: CommonIO.cpp:125
dev::toHex
std::string toHex(Iterator _it, Iterator _end, std::string const &_prefix)
Definition: CommonData.h:46
dev::eth::SnapshotManifest
@ SnapshotManifest
Definition: WarpCapability.h:23
dev::eth::WarpCapability::disablePeer
void disablePeer(NodeID const &_peerID, std::string const &_problem)
Definition: WarpCapability.cpp:572
dev::RLP
Definition: RLP.h:48
dev::eth::Asking::Nothing
@ Nothing
dev::fromHex
bytes fromHex(std::string const &_s, WhenError _throw=WhenError::DontThrow)
Definition: CommonData.cpp:81
dev::eth::Asking::WarpData
@ WarpData