Fabcoin Core  0.16.2
P2P Digital Currency
capability.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 */
22 #include <boost/test/unit_test.hpp>
23 #include <chrono>
24 #include <thread>
25 #include <libp2p/Common.h>
26 #include <libp2p/Host.h>
27 #include <libp2p/Session.h>
28 #include <libp2p/Capability.h>
29 #include <libp2p/HostCapability.h>
31 
32 using namespace std;
33 using namespace dev;
34 using namespace dev::test;
35 using namespace dev::p2p;
36 
38 {
41 };
42 
44 {
45 public:
46  TestCapability(std::shared_ptr<SessionFace> _s, HostCapabilityFace* _h, unsigned _idOffset, CapDesc const&, uint16_t _capID): Capability(_s, _h, _idOffset, _capID), m_cntReceivedMessages(0), m_testSum(0) {}
47  virtual ~TestCapability() {}
48  int countReceivedMessages() { return m_cntReceivedMessages; }
49  int testSum() { return m_testSum; }
50  static std::string name() { return "test"; }
51  static u256 version() { return 2; }
52  static unsigned messageCount() { return UserPacket + 1; }
53  void sendTestMessage(int _i) { RLPStream s; sealAndSend(prep(s, UserPacket, 1) << _i); }
54 
55 protected:
56  virtual bool interpret(unsigned _id, RLP const& _r) override;
57 
59  int m_testSum;
60 };
61 
62 bool TestCapability::interpret(unsigned _id, RLP const& _r)
63 {
64  //cnote << "Capability::interpret(): custom message received";
65  ++m_cntReceivedMessages;
66  m_testSum += _r[0].toInt();
67  BOOST_ASSERT(_id == UserPacket);
68  return (_id == UserPacket);
69 }
70 
71 class TestHostCapability: public HostCapability<TestCapability>, public Worker
72 {
73 public:
74  TestHostCapability(): Worker("test") {}
75  virtual ~TestHostCapability() {}
76 
77  void sendTestMessage(NodeID const& _id, int _x)
78  {
79  for (auto i: peerSessions())
80  if (_id == i.second->id)
81  capabilityFromSession<TestCapability>(*i.first)->sendTestMessage(_x);
82  }
83 
84  std::pair<int, int> retrieveTestData(NodeID const& _id)
85  {
86  int cnt = 0;
87  int checksum = 0;
88  for (auto i: peerSessions())
89  if (_id == i.second->id)
90  {
91  cnt += capabilityFromSession<TestCapability>(*i.first)->countReceivedMessages();
92  checksum += capabilityFromSession<TestCapability>(*i.first)->testSum();
93  }
94 
95  return std::pair<int, int>(cnt, checksum);
96  }
97 };
98 
100 
102 {
103  if (test::Options::get().nonetwork)
104  return;
105 
106  VerbosityHolder verbosityHolder(10);
107  cnote << "Testing Capability...";
108 
109  int const step = 10;
110  const char* const localhost = "127.0.0.1";
111  NetworkPreferences prefs1(localhost, 0, false);
112  NetworkPreferences prefs2(localhost, 0, false);
113  Host host1("Test", prefs1);
114  Host host2("Test", prefs2);
115  auto thc1 = host1.registerCapability(make_shared<TestHostCapability>());
116  auto thc2 = host2.registerCapability(make_shared<TestHostCapability>());
117  host1.start();
118  host2.start();
119  auto port1 = host1.listenPort();
120  auto port2 = host2.listenPort();
121  BOOST_REQUIRE(port1);
122  BOOST_REQUIRE(port2);
123  BOOST_REQUIRE_NE(port1, port2);
124 
125  for (unsigned i = 0; i < 3000; i += step)
126  {
127  this_thread::sleep_for(chrono::milliseconds(step));
128 
129  if (host1.isStarted() && host2.isStarted())
130  break;
131  }
132 
133  BOOST_REQUIRE(host1.isStarted() && host2.isStarted());
134  host1.requirePeer(host2.id(), NodeIPEndpoint(bi::address::from_string(localhost), port2, port2));
135 
136  // Wait for up to 12 seconds, to give the hosts time to connect to each other.
137  for (unsigned i = 0; i < 12000; i += step)
138  {
139  this_thread::sleep_for(chrono::milliseconds(step));
140 
141  if ((host1.peerCount() > 0) && (host2.peerCount() > 0))
142  break;
143  }
144 
145  BOOST_REQUIRE(host1.peerCount() > 0 && host2.peerCount() > 0);
146 
147  int const target = 64;
148  int checksum = 0;
149  for (int i = 0; i < target; checksum += i++)
150  thc2->sendTestMessage(host1.id(), i);
151 
152  this_thread::sleep_for(chrono::seconds(target / 64 + 1));
153  std::pair<int, int> testData = thc1->retrieveTestData(host2.id());
154  BOOST_REQUIRE_EQUAL(target, testData.first);
155  BOOST_REQUIRE_EQUAL(checksum, testData.second);
156 }
157 
159 
160 
void sendTestMessage(NodeID const &_id, int _x)
Definition: capability.cpp:77
virtual ~TestHostCapability()
Definition: capability.cpp:75
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
Definition: Arith256.cpp:15
bool isStarted() const
Definition: Host.h:218
static unsigned messageCount()
Definition: capability.cpp:52
std::pair< std::string, u256 > CapDesc
Definition: Common.h:142
The Host class Capabilities should be registered prior to startNetwork, since m_capabilities is not t...
Definition: Host.h:129
unsigned short listenPort() const
Get the port we&#39;re listening on currently.
Definition: Host.h:198
std::hash for asio::adress
Definition: Common.h:323
IPv4,UDP/TCP endpoints.
Definition: Common.h:175
virtual ~TestCapability()
Definition: capability.cpp:47
size_t peerCount() const
Get number of peers connected.
Definition: Host.cpp:639
BOOST_AUTO_TEST_CASE(capability)
Definition: capability.cpp:101
NodeID id() const
Get our current node ID.
Definition: Host.h:233
void requirePeer(NodeID const &_node, NodeIPEndpoint const &_endpoint)
Create Peer and attempt keeping peer connected.
Definition: Host.cpp:517
boost::multiprecision::number< boost::multiprecision::cpp_int_backend< 256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void >> u256
Definition: Common.h:125
Temporary changes system&#39;s verbosity for specific function.
Definition: Log.h:80
void start()
Start network. .
Definition: Host.cpp:124
int countReceivedMessages()
Definition: capability.cpp:48
std::shared_ptr< T > registerCapability(std::shared_ptr< T > const &_t)
Register a peer-capability; all new peer connections will have this capability.
Definition: Host.h:160
TestCapability(std::shared_ptr< SessionFace > _s, HostCapabilityFace *_h, unsigned _idOffset, CapDesc const &, uint16_t _capID)
Definition: capability.cpp:46
#define cnote
Definition: Log.h:303
#define BOOST_FIXTURE_TEST_SUITE(a, b)
Definition: object.cpp:14
#define BOOST_AUTO_TEST_SUITE_END()
Definition: object.cpp:16
static std::string name()
Definition: capability.cpp:50
static u256 version()
Definition: capability.cpp:51
_T toInt(int _flags=Strict) const
Converts to int of type given; if isString(), decodes as big-endian bytestream.
Definition: RLP.h:275
Class for writing to an RLP bytestream.
Definition: RLP.h:383
std::pair< int, int > retrieveTestData(NodeID const &_id)
Definition: capability.cpp:84
Class for interpreting Recursive Linear-Prefix Data.
Definition: RLP.h:64
void sendTestMessage(int _i)
Definition: capability.cpp:53
static bool test_allowLocal
Setting true causes isAllowed to return true for all addresses. (Used by test fixtures) ...
Definition: Common.h:185
int m_cntReceivedMessages
Definition: capability.cpp:58
Helper functions to work with json::spirit and test files.
virtual bool interpret(unsigned _id, RLP const &_r) override
Definition: capability.cpp:62