Ethereum  PoC-8
The C++ Implementation of Ethereum
BlockChainSync.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 <mutex>
8 #include <unordered_map>
9 
10 #include <libdevcore/Guards.h>
11 #include <libethcore/Common.h>
12 #include <libethcore/BlockHeader.h>
13 #include <libp2p/Common.h>
14 #include "CommonNet.h"
15 
16 namespace dev
17 {
18 
19 class RLPStream;
20 
21 namespace eth
22 {
23 class EthereumCapability;
24 class BlockQueue;
25 class EthereumPeer;
26 
31 class BlockChainSync final: public HasInvariants
32 {
33 public:
34  explicit BlockChainSync(EthereumCapability& _host);
36  void abortSync();
37 
39  bool isSyncing() const;
40 
42  void restartSync();
43 
46  void completeSync();
47 
49  void onPeerStatus(EthereumPeer const& _peer);
50 
52  void onPeerBlockHeaders(NodeID const& _peerID, RLP const& _r);
53 
55  void onPeerBlockBodies(NodeID const& _peerID, RLP const& _r);
56 
58  void onPeerNewBlock(NodeID const& _peerID, RLP const& _r);
59 
60  void onPeerNewHashes(NodeID const& _peerID, std::vector<std::pair<h256, u256>> const& _hashes);
61 
63  void onPeerAborting();
64 
66  void onBlockImported(BlockHeader const& _info);
67 
69  SyncStatus status() const;
70 
71  static char const* stateName(SyncState _s) { return s_stateNames[static_cast<int>(_s)]; }
72 
73 private:
75  void continueSync();
76 
78  void pauseSync();
79 
80  EthereumCapability& host() { return m_host; }
81  EthereumCapability const& host() const { return m_host; }
82 
83  void resetSync();
84  void syncPeer(NodeID const& _peerID, bool _force);
85  void requestBlocks(NodeID const& _peerID);
86  void clearPeerDownload(NodeID const& _peerID);
87  void clearPeerDownload();
88  void collectBlocks();
89  bool requestDaoForkBlockHeader(NodeID const& _peerID);
90  bool verifyDaoChallengeResponse(RLP const& _r);
91  void logImported(unsigned _success, unsigned _future, unsigned _got, unsigned _unknown);
92 
93 private:
94  struct Header
95  {
96  bytes data;
97  h256 hash;
98  h256 parent;
99  };
100 
102  struct HeaderId
103  {
104  h256 transactionsRoot;
105  h256 uncles;
106 
107  bool operator==(HeaderId const& _other) const
108  {
109  return transactionsRoot == _other.transactionsRoot && uncles == _other.uncles;
110  }
111  };
112 
113  struct HeaderIdHash
114  {
115  std::size_t operator()(const HeaderId& _k) const
116  {
117  size_t seed = 0;
118  h256::hash hasher;
119  boost::hash_combine(seed, hasher(_k.transactionsRoot));
120  boost::hash_combine(seed, hasher(_k.uncles));
121  return seed;
122  }
123  };
124 
125  EthereumCapability& m_host;
126  Handler<> m_bqRoomAvailable;
127  mutable RecursiveMutex x_sync;
129  std::set<NodeID> m_daoChallengedPeers;
130  std::atomic<SyncState> m_state{SyncState::Idle};
131  h256Hash m_knownNewHashes;
132  unsigned m_chainStartBlock = 0;
133  unsigned m_startingBlock = 0;
134  unsigned m_highestBlock = 0;
135  std::unordered_set<unsigned> m_downloadingHeaders;
136  std::unordered_set<unsigned> m_downloadingBodies;
137  std::map<unsigned, std::vector<Header>> m_headers;
138  std::map<unsigned, std::vector<bytes>> m_bodies;
139  std::map<NodeID, std::vector<unsigned>> m_headerSyncPeers;
142  std::map<NodeID, std::vector<unsigned>> m_bodySyncPeers;
143  std::unordered_map<HeaderId, unsigned, HeaderIdHash> m_headerIdToNumber;
144  bool m_haveCommonHeader = false;
145  unsigned m_lastImportedBlock = 0;
146  h256 m_lastImportedBlockHash;
147  u256 m_syncingTotalDifficulty;
148 
149  Logger m_logger{createLogger(VerbosityDebug, "sync")};
150  Logger m_loggerInfo{createLogger(VerbosityInfo, "sync")};
151  Logger m_loggerDetail{createLogger(VerbosityTrace, "sync")};
152 
153 private:
154  static char const* const s_stateNames[static_cast<int>(SyncState::Size)];
155  bool invariants() const override;
156  void logNewBlock(h256 const& _h);
157 };
158 
159 std::ostream& operator<<(std::ostream& _out, SyncStatus const& _sync);
160 
161 }
162 }
dev::eth::BlockChainSync::onPeerBlockBodies
void onPeerBlockBodies(NodeID const &_peerID, RLP const &_r)
Called by peer once it has new block bodies.
Definition: BlockChainSync.cpp:574
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::BlockChainSync::isSyncing
bool isSyncing() const
Definition: BlockChainSync.cpp:863
dev::eth::SyncStatus
Definition: CommonNet.h:96
dev::eth::BlockChainSync::onPeerBlockHeaders
void onPeerBlockHeaders(NodeID const &_peerID, RLP const &_r)
Called by peer once it has new block headers during sync.
Definition: BlockChainSync.cpp:430
dev::eth::BlockChainSync::onPeerNewBlock
void onPeerNewBlock(NodeID const &_peerID, RLP const &_r)
Called by peer once it has new block bodies.
Definition: BlockChainSync.cpp:728
dev::eth::BlockChainSync::abortSync
void abortSync()
Abort all sync activity.
Definition: BlockChainSync.cpp:174
dev::h256
FixedHash< 32 > h256
Definition: FixedHash.h:356
dev::eth::BlockChainSync::onBlockImported
void onBlockImported(BlockHeader const &_info)
Called when a blockchain has imported a new block onto the DB.
Definition: BlockChainSync.cpp:161
BlockHeader.h
dev::VerbosityInfo
@ VerbosityInfo
Definition: Log.h:70
dev::eth::BlockChainSync::onPeerAborting
void onPeerAborting()
Called by peer when it is disconnecting.
Definition: BlockChainSync.cpp:917
Common.h
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::BlockChainSync::BlockChainSync
BlockChainSync(EthereumCapability &_host)
Definition: BlockChainSync.cpp:140
dev::eth::BlockChainSync::onPeerNewHashes
void onPeerNewHashes(NodeID const &_peerID, std::vector< std::pair< h256, u256 >> const &_hashes)
Definition: BlockChainSync.cpp:868
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
dev::eth::BlockChainSync::status
SyncStatus status() const
Definition: BlockChainSync.cpp:814
dev::eth::SyncState
SyncState
Definition: CommonNet.h:85
dev::eth::BlockChainSync::completeSync
void completeSync()
Definition: BlockChainSync.cpp:851
dev::VerbosityDebug
@ VerbosityDebug
Definition: Log.h:71
dev::HasInvariants
Inheritable for classes that have invariants.
Definition: Common.h:211
dev::eth::BlockChainSync::onPeerStatus
void onPeerStatus(EthereumPeer const &_peer)
Called by peer to report status.
Definition: BlockChainSync.cpp:181
dev::RecursiveMutex
std::recursive_mutex RecursiveMutex
Definition: Guards.h:38
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::operator<<
std::ostream & operator<<(std::ostream &_out, BlockHeader const &_bi)
Definition: BlockHeader.h:217
dev
Definition: Address.cpp:21
dev::eth::BlockChainSync::restartSync
void restartSync()
Restart sync.
Definition: BlockChainSync.cpp:839
dev::eth::BlockChainSync::stateName
static char const * stateName(SyncState _s)
Definition: BlockChainSync.h:71
CommonNet.h
Guards.h
dev::eth::SyncState::Idle
@ Idle
Initial chain sync complete. Waiting for new packets.
dev::eth::BlockChainSync::~BlockChainSync
~BlockChainSync()
Definition: BlockChainSync.cpp:155
dev::RLP
Definition: RLP.h:48
dev::VerbosityTrace
@ VerbosityTrace
Definition: Log.h:72
dev::eth::BlockChainSync
Base BlockChain synchronization strategy class. Syncs to peers and keeps up to date....
Definition: BlockChainSync.h:32