Ethereum  PoC-8
The C++ Implementation of Ethereum
EthereumPeer.cpp
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 #include "EthereumPeer.h"
19 #include <libethcore/Common.h>
20 #include <libp2p/CapabilityHost.h>
21 
22 
23 using namespace std;
24 using namespace dev;
25 using namespace dev::eth;
26 
27 static std::string const c_ethCapability = "eth";
28 
29 namespace
30 {
31 string toString(Asking _a)
32 {
33  switch (_a)
34  {
35  case Asking::BlockHeaders:
36  return "BlockHeaders";
37  case Asking::BlockBodies:
38  return "BlockBodies";
39  case Asking::NodeData:
40  return "NodeData";
41  case Asking::Receipts:
42  return "Receipts";
43  case Asking::Nothing:
44  return "Nothing";
45  case Asking::State:
46  return "State";
47  case Asking::WarpManifest:
48  return "WarpManifest";
49  case Asking::WarpData:
50  return "WarpData";
51  }
52  return "?";
53 }
54 } // namespace
55 
56 void EthereumPeer::setStatus(unsigned _protocolVersion, u256 const& _networkId,
57  u256 const& _totalDifficulty, h256 const& _latestHash, h256 const& _genesisHash)
58 {
59  m_protocolVersion = _protocolVersion;
60  m_networkId = _networkId;
61  m_totalDifficulty = _totalDifficulty;
62  m_latestHash = _latestHash;
63  m_genesisHash = _genesisHash;
64 }
65 
66 
67 std::string EthereumPeer::validate(
68  h256 const& _hostGenesisHash, unsigned _hostProtocolVersion, u256 const& _hostNetworkId) const
69 {
70  std::string error;
71  if (m_genesisHash != _hostGenesisHash)
72  error = "Invalid genesis hash.";
73  else if (m_protocolVersion != _hostProtocolVersion)
74  error = "Invalid protocol version.";
75  else if (m_networkId != _hostNetworkId)
76  error = "Invalid network identifier.";
77  else if (m_asking != Asking::State && m_asking != Asking::Nothing)
78  error = "Peer banned for unexpected status message.";
79 
80  return error;
81 }
82 
83 void EthereumPeer::requestStatus(
84  u256 _hostNetworkId, u256 _chainTotalDifficulty, h256 _chainCurrentHash, h256 _chainGenesisHash)
85 {
86  assert(m_asking == Asking::Nothing);
87  setAsking(Asking::State);
88  m_requireTransactions = true;
89  RLPStream s;
90  m_host->prep(m_id, c_ethCapability, s, StatusPacket, 5)
91  << c_protocolVersion << _hostNetworkId << _chainTotalDifficulty << _chainCurrentHash
92  << _chainGenesisHash;
93  m_host->sealAndSend(m_id, s);
94 }
95 
96 void EthereumPeer::requestBlockHeaders(
97  unsigned _startNumber, unsigned _count, unsigned _skip, bool _reverse)
98 {
99  if (m_asking != Asking::Nothing)
100  {
101  LOG(m_logger) << "Asking headers while requesting " << ::toString(m_asking);
102  }
103  setAsking(Asking::BlockHeaders);
104  RLPStream s;
105  m_host->prep(m_id, c_ethCapability, s, GetBlockHeadersPacket, 4)
106  << _startNumber << _count << _skip << (_reverse ? 1 : 0);
107  LOG(m_logger) << "Requesting " << _count << " block headers starting from " << _startNumber
108  << (_reverse ? " in reverse" : "");
109  m_lastAskedHeaders = _count;
110  m_host->sealAndSend(m_id, s);
111 }
112 
113 void EthereumPeer::requestBlockHeaders(
114  h256 const& _startHash, unsigned _count, unsigned _skip, bool _reverse)
115 {
116  if (m_asking != Asking::Nothing)
117  {
118  LOG(m_logger) << "Asking headers while requesting " << ::toString(m_asking);
119  }
120  setAsking(Asking::BlockHeaders);
121  RLPStream s;
122  m_host->prep(m_id, c_ethCapability, s, GetBlockHeadersPacket, 4)
123  << _startHash << _count << _skip << (_reverse ? 1 : 0);
124  LOG(m_logger) << "Requesting " << _count << " block headers starting from " << _startHash
125  << (_reverse ? " in reverse" : "");
126  m_lastAskedHeaders = _count;
127  m_host->sealAndSend(m_id, s);
128 }
129 
130 
131 void EthereumPeer::requestBlockBodies(h256s const& _blocks)
132 {
133  requestByHashes(_blocks, Asking::BlockBodies, GetBlockBodiesPacket);
134 }
135 
136 void EthereumPeer::requestNodeData(h256s const& _hashes)
137 {
138  requestByHashes(_hashes, Asking::NodeData, GetNodeDataPacket);
139 }
140 
141 void EthereumPeer::requestReceipts(h256s const& _blocks)
142 {
143  requestByHashes(_blocks, Asking::Receipts, GetReceiptsPacket);
144 }
145 
146 void EthereumPeer::requestByHashes(
147  h256s const& _hashes, Asking _asking, SubprotocolPacketType _packetType)
148 {
149  if (m_asking != Asking::Nothing)
150  {
151  LOG(m_logger) << "Asking " << ::toString(_asking) << " while requesting "
152  << ::toString(m_asking);
153  }
154  setAsking(_asking);
155  if (_hashes.size())
156  {
157  RLPStream s;
158  m_host->prep(m_id, c_ethCapability, s, _packetType, _hashes.size());
159  for (auto const& i : _hashes)
160  s << i;
161  m_host->sealAndSend(m_id, s);
162  }
163  else
164  setAsking(Asking::Nothing);
165 }
dev::eth::c_protocolVersion
const unsigned c_protocolVersion
Current protocol version.
Definition: Common.cpp:40
dev::eth
Definition: BasicAuthority.h:32
dev::toString
std::string toString(std::chrono::time_point< T > const &_e, std::string const &_format="%F %T")
Definition: CommonIO.h:86
dev::FixedHash< 32 >
dev::eth::GetBlockHeadersPacket
@ GetBlockHeadersPacket
Definition: CommonNet.h:58
dev::eth::StatusPacket
@ StatusPacket
Definition: CommonNet.h:55
LOG
#define LOG
Definition: Log.h:63
EthereumPeer.h
Common.h
dev::eth::SubprotocolPacketType
SubprotocolPacketType
Definition: CommonNet.h:54
dev::h256s
std::vector< h256 > h256s
Definition: FixedHash.h:361
dev::eth::Asking
Asking
Definition: CommonNet.h:73
dev::eth::GetBlockBodiesPacket
@ GetBlockBodiesPacket
Definition: CommonNet.h:60
dev::RLPStream
Class for writing to an RLP bytestream.
Definition: RLP.h:370
dev::eth::GetNodeDataPacket
@ GetNodeDataPacket
Definition: CommonNet.h:64
std
Definition: FixedHash.h:393
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
Definition: Address.cpp:21
dev::eth::GetReceiptsPacket
@ GetReceiptsPacket
Definition: CommonNet.h:66