Fabcoin Core  0.16.2
P2P Digital Currency
BlockChainSync.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 */
22 #pragma once
23 
24 #include <mutex>
25 #include <unordered_map>
26 
27 #include <libdevcore/Guards.h>
28 #include <libethcore/Common.h>
29 #include <libethcore/BlockHeader.h>
30 #include <libp2p/Common.h>
31 #include "CommonNet.h"
32 
33 namespace dev
34 {
35 
36 class RLPStream;
37 
38 namespace eth
39 {
40 
41 class EthereumHost;
42 class BlockQueue;
43 class EthereumPeer;
44 
50 {
51 public:
54  void abortSync();
55 
57  bool isSyncing() const;
58 
60  void restartSync();
61 
64  void completeSync();
65 
67  void onPeerStatus(std::shared_ptr<EthereumPeer> _peer);
68 
70  void onPeerBlockHeaders(std::shared_ptr<EthereumPeer> _peer, RLP const& _r);
71 
73  void onPeerBlockBodies(std::shared_ptr<EthereumPeer> _peer, RLP const& _r);
74 
76  void onPeerNewBlock(std::shared_ptr<EthereumPeer> _peer, RLP const& _r);
77 
78  void onPeerNewHashes(std::shared_ptr<EthereumPeer> _peer, std::vector<std::pair<h256, u256>> const& _hashes);
79 
81  void onPeerAborting();
82 
84  void onBlockImported(BlockHeader const& _info);
85 
87  SyncStatus status() const;
88 
89  static char const* stateName(SyncState _s) { return s_stateNames[static_cast<int>(_s)]; }
90 
91 private:
93  void continueSync();
94 
96  void pauseSync();
97 
98  EthereumHost& host() { return m_host; }
99  EthereumHost const& host() const { return m_host; }
100 
101  void resetSync();
102  void syncPeer(std::shared_ptr<EthereumPeer> _peer, bool _force);
103  void requestBlocks(std::shared_ptr<EthereumPeer> _peer);
104  void clearPeerDownload(std::shared_ptr<EthereumPeer> _peer);
105  void clearPeerDownload();
106  void collectBlocks();
107 
108 private:
109  struct Header
110  {
114  };
115 
117  struct HeaderId
118  {
121 
122  bool operator==(HeaderId const& _other) const
123  {
124  return transactionsRoot == _other.transactionsRoot && uncles == _other.uncles;
125  }
126  };
127 
129  {
130  std::size_t operator()(const HeaderId& _k) const
131  {
132  size_t seed = 0;
133  h256::hash hasher;
134  boost::hash_combine(seed, hasher(_k.transactionsRoot));
135  boost::hash_combine(seed, hasher(_k.uncles));
136  return seed;
137  }
138  };
139 
145  unsigned m_startingBlock = 0;
146  unsigned m_highestBlock = 0;
147  std::unordered_set<unsigned> m_downloadingHeaders;
148  std::unordered_set<unsigned> m_downloadingBodies;
149  std::map<unsigned, std::vector<Header>> m_headers;
150  std::map<unsigned, std::vector<bytes>> m_bodies;
151  std::map<std::weak_ptr<EthereumPeer>, std::vector<unsigned>, std::owner_less<std::weak_ptr<EthereumPeer>>> m_headerSyncPeers;
152  std::map<std::weak_ptr<EthereumPeer>, std::vector<unsigned>, std::owner_less<std::weak_ptr<EthereumPeer>>> m_bodySyncPeers;
153  std::unordered_map<HeaderId, unsigned, HeaderIdHash> m_headerIdToNumber;
154  bool m_haveCommonHeader = false;
155  unsigned m_lastImportedBlock = 0;
158 
159 private:
160  static char const* const s_stateNames[static_cast<int>(SyncState::Size)];
161  bool invariants() const override;
162  void logNewBlock(h256 const& _h);
163 };
164 
165 std::ostream& operator<<(std::ostream& _out, SyncStatus const& _sync);
166 
167 }
168 }
Inheritable for classes that have invariants.
Definition: Common.h:229
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
Definition: Arith256.cpp:15
void restartSync()
Restart sync.
h256Hash m_knownNewHashes
New hashes we know about use for logging only.
void onPeerNewHashes(std::shared_ptr< EthereumPeer > _peer, std::vector< std::pair< h256, u256 >> const &_hashes)
void onPeerBlockHeaders(std::shared_ptr< EthereumPeer > _peer, RLP const &_r)
Called by peer once it has new block headers during sync.
bool invariants() const override
Reimplement to specify the invariants.
bool m_haveCommonHeader
True if common block for our and remote chain has been found.
unsigned m_startingBlock
Last block number for the start of sync.
Handler m_bqRoomAvailable
Triggered once block queue has space for more blocks.
void completeSync()
Called after all blocks have been downloaded Public only for test mode.
Encapsulation of a block header.
Definition: BlockHeader.h:95
void abortSync()
Abort all sync activity.
std::ostream & operator<<(std::ostream &_out, BlockHeader const &_bi)
Definition: BlockHeader.h:194
EthereumHost const & host() const
h256 m_lastImportedBlockHash
Last imported block hash.
unsigned m_lastImportedBlock
Last imported block number.
std::unordered_set< unsigned > m_downloadingHeaders
Set of block body numbers being downloaded.
The EthereumHost class.
Definition: EthereumHost.h:61
u256 m_syncingTotalDifficulty
Highest peer difficulty.
SyncState m_state
Current sync state.
std::map< std::weak_ptr< EthereumPeer >, std::vector< unsigned >, std::owner_less< std::weak_ptr< EthereumPeer > > > m_headerSyncPeers
Peers to m_downloadingSubchain number map.
SyncStatus status() const
std::size_t operator()(const HeaderId &_k) const
std::map< unsigned, std::vector< Header > > m_headers
Downloaded headers.
Initial chain sync complete. Waiting for new packets.
std::recursive_mutex RecursiveMutex
Definition: Guards.h:38
void continueSync()
Resume downloading after witing state.
Used to identify header by transactions and uncles hashes.
static char const *const s_stateNames[static_cast< int >(SyncState::Size)]
unsigned m_highestBlock
Highest block number seen.
std::shared_ptr< typename Signal< Args... >::HandlerAux > Handler
Definition: Common.h:181
void pauseSync()
Enter waiting state.
bool operator==(HeaderId const &_other) const
std::unordered_set< unsigned > m_downloadingBodies
Set of block header numbers being downloaded.
BlockChainSync(EthereumHost &_host)
Must be kept last.
std::vector< byte > bytes
Definition: Common.h:75
boost::multiprecision::number< boost::multiprecision::cpp_int_backend< 256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void >> u256
Definition: Common.h:125
static char const * stateName(SyncState _s)
void onPeerAborting()
Called by peer when it is disconnecting.
Base BlockChain synchronization strategy class.
void onPeerBlockBodies(std::shared_ptr< EthereumPeer > _peer, RLP const &_r)
Called by peer once it has new block bodies.
void syncPeer(std::shared_ptr< EthereumPeer > _peer, bool _force)
std::map< std::weak_ptr< EthereumPeer >, std::vector< unsigned >, std::owner_less< std::weak_ptr< EthereumPeer > > > m_bodySyncPeers
Peers to m_downloadingSubchain number map.
void onPeerStatus(std::shared_ptr< EthereumPeer > _peer)
Called by peer to report status.
std::unordered_set< h256 > h256Hash
Definition: FixedHash.h:349
EthereumHost & host()
std::map< unsigned, std::vector< bytes > > m_bodies
Downloaded block bodies.
void logNewBlock(h256 const &_h)
void onBlockImported(BlockHeader const &_info)
Called when a blockchain has imported a new block onto the DB.
Class for interpreting Recursive Linear-Prefix Data.
Definition: RLP.h:64
void onPeerNewBlock(std::shared_ptr< EthereumPeer > _peer, RLP const &_r)
Called by peer once it has new block bodies.
void requestBlocks(std::shared_ptr< EthereumPeer > _peer)
std::unordered_map< HeaderId, unsigned, HeaderIdHash > m_headerIdToNumber