From c7d6502b430503d44dde98659c81742e6b9b2bdb Mon Sep 17 00:00:00 2001 From: subtly Date: Tue, 16 Dec 2014 22:01:39 +0100 Subject: [PATCH 01/30] udp != tcp. history-commit. --- kademlia.cpp | 33 +++++++++++++++++++++++++++++++++ network.cpp => net.cpp | 0 2 files changed, 33 insertions(+) create mode 100644 kademlia.cpp rename network.cpp => net.cpp (100%) diff --git a/kademlia.cpp b/kademlia.cpp new file mode 100644 index 000000000..21c28cb87 --- /dev/null +++ b/kademlia.cpp @@ -0,0 +1,33 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file kademlia.cpp + * @author Alex Leverington + * @date 2014 + * Basic networking tests + */ + +#include +#include +using namespace std; +using namespace dev; +using namespace dev::p2p; + +BOOST_AUTO_TEST_CASE(host_listen_udp4) +{ + +} + diff --git a/network.cpp b/net.cpp similarity index 100% rename from network.cpp rename to net.cpp From d22e4b3b21b05aa3590f84847259ba17895a91b2 Mon Sep 17 00:00:00 2001 From: subtly Date: Thu, 18 Dec 2014 08:35:12 +0100 Subject: [PATCH 02/30] initial interface for udp. test sending/receiving udp. --- kademlia.cpp | 12 -------- net.cpp | 86 ++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 60 insertions(+), 38 deletions(-) diff --git a/kademlia.cpp b/kademlia.cpp index 21c28cb87..a9d7701cf 100644 --- a/kademlia.cpp +++ b/kademlia.cpp @@ -17,17 +17,5 @@ /** @file kademlia.cpp * @author Alex Leverington * @date 2014 - * Basic networking tests */ -#include -#include -using namespace std; -using namespace dev; -using namespace dev::p2p; - -BOOST_AUTO_TEST_CASE(host_listen_udp4) -{ - -} - diff --git a/net.cpp b/net.cpp index acdd649d9..e52654411 100644 --- a/net.cpp +++ b/net.cpp @@ -14,42 +14,76 @@ You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ -/** @file network.cpp - * @author Marko Simovic +/** @file net.cpp + * @author Alex Leverington * @date 2014 - * Basic networking tests */ #include -#include -#include -#include -#include -#include "TestHelper.h" +#include +#include using namespace std; using namespace dev; -using namespace dev::eth; +using namespace dev::p2p; +namespace ba = boost::asio; +namespace bi = ba::ip; -// Disabled since tests shouldn't block (not the worst offender, but timeout should be reduced anyway). -/* -BOOST_AUTO_TEST_CASE(listen_port_busy) +class TestA: UDPSocketEvents, public Worker { - short port = 20000; +public: + TestA(): Worker("test",0), m_io(), m_socket(new UDPSocket(m_io, *this, 30300)) {} + ~TestA() { m_io.stop(); stopWorking(); } + + void start() { startWorking(); } + void doWork() { m_io.run(); } + + void onDisconnected(UDPSocketFace*) {}; + void onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytesConstRef _packet) { if(_packet.toString() == "AAAA") success = true; }; - //make use of the port ahead of our client - ba::io_service ioService; - bi::tcp::endpoint endPoint(bi::tcp::v4(), port); - bi::tcp::acceptor acceptor(ioService, endPoint); - acceptor.listen(10); + ba::io_service m_io; + shared_ptr> m_socket; + + bool success = false; +}; - //prepare client and try to listen on same, used, port - Client c1("TestClient1", KeyPair::create().address(), - (boost::filesystem::temp_directory_path() / boost::filesystem::unique_path()).string()); +//struct TestBProtocol: UDPSocketEvents +//{ +// void onDisconnected(UDPSocketFace*) {}; +// void onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytesConstRef _packet) { cout << "received TestBProtocol" << endl; }; +//}; +// +//class TestB: TestBProtocol +//{ +//public: +// TestB(): m_io(), m_socket(m_io, *this, 30300) {} +////private: +// ba::io_service m_io; +// UDPSocket m_socket; +//}; +// +//class TestC +//{ +//public: +// TestC(): m_io(), m_socket(m_io, m_rpc, 30300) {} +////private: +// ba::io_service m_io; +// TestBProtocol m_rpc; +// UDPSocket m_socket; +//}; - c1.startNetwork(port); +BOOST_AUTO_TEST_SUITE(p2p) - BOOST_REQUIRE(c1.haveNetwork()); - BOOST_REQUIRE(c1.peerServer()->listenPort() != 0); - BOOST_REQUIRE(c1.peerServer()->listenPort() != port); +BOOST_AUTO_TEST_CASE(test) +{ + UDPDatagram d; + d.to = boost::asio::ip::udp::endpoint(boost::asio::ip::address::from_string("127.0.0.1"), 30300); + d.data = bytes({65,65,65,65}); + + TestA a; a.start(); a.m_socket->connect(); + a.m_socket->send(d); + sleep(1); + BOOST_REQUIRE_EQUAL(true, a.success); } -*/ + +BOOST_AUTO_TEST_SUITE_END() + From b3b4411c4c31d74fe0d7f5f2f85461036cac0f6e Mon Sep 17 00:00:00 2001 From: subtly Date: Thu, 18 Dec 2014 17:21:06 +0100 Subject: [PATCH 03/30] spacing --- net.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net.cpp b/net.cpp index e52654411..0b3208302 100644 --- a/net.cpp +++ b/net.cpp @@ -38,7 +38,7 @@ public: void doWork() { m_io.run(); } void onDisconnected(UDPSocketFace*) {}; - void onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytesConstRef _packet) { if(_packet.toString() == "AAAA") success = true; }; + void onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytesConstRef _packet) { if (_packet.toString() == "AAAA") success = true; } ba::io_service m_io; shared_ptr> m_socket; @@ -73,7 +73,7 @@ public: BOOST_AUTO_TEST_SUITE(p2p) -BOOST_AUTO_TEST_CASE(test) +BOOST_AUTO_TEST_CASE(test_txrx_one) { UDPDatagram d; d.to = boost::asio::ip::udp::endpoint(boost::asio::ip::address::from_string("127.0.0.1"), 30300); From ed9a5e572a8254f1595154e302f51dd242673272 Mon Sep 17 00:00:00 2001 From: subtly Date: Thu, 18 Dec 2014 20:25:36 +0100 Subject: [PATCH 04/30] stash --- net.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/net.cpp b/net.cpp index 0b3208302..1e8d20c54 100644 --- a/net.cpp +++ b/net.cpp @@ -28,6 +28,21 @@ using namespace dev::p2p; namespace ba = boost::asio; namespace bi = ba::ip; +class Kademlia: UDPSocketEvents +{ +public: + Kademlia(): Worker("test",0), m_io(), m_socket(new UDPSocket(m_io, *this, 30300)) {} + ~Kademlia() { m_io.stop(); stopWorking(); } + + void onDisconnected(UDPSocketFace*) {}; + void onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytesConstRef _packet) { if (_packet.toString() == "AAAA") success = true; } + + ba::io_service m_io; + shared_ptr> m_socket; + + bool success = false; +}; + class TestA: UDPSocketEvents, public Worker { public: From 4588bfba6655698396cf067d251a849ad4dfd7c1 Mon Sep 17 00:00:00 2001 From: subtly Date: Fri, 19 Dec 2014 22:14:11 +0100 Subject: [PATCH 05/30] initialize atomics so udp messages are delivered on linux #656 --- net.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net.cpp b/net.cpp index 1e8d20c54..34b20ccc7 100644 --- a/net.cpp +++ b/net.cpp @@ -94,7 +94,7 @@ BOOST_AUTO_TEST_CASE(test_txrx_one) d.to = boost::asio::ip::udp::endpoint(boost::asio::ip::address::from_string("127.0.0.1"), 30300); d.data = bytes({65,65,65,65}); - TestA a; a.start(); a.m_socket->connect(); + TestA a; a.m_socket->connect(); a.start(); a.m_socket->send(d); sleep(1); BOOST_REQUIRE_EQUAL(true, a.success); From 16ba69ae780179d327bf05e164a3e176127ee462 Mon Sep 17 00:00:00 2001 From: subtly Date: Fri, 19 Dec 2014 22:40:44 +0100 Subject: [PATCH 06/30] fix the fix --- net.cpp | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/net.cpp b/net.cpp index 34b20ccc7..6e9efff16 100644 --- a/net.cpp +++ b/net.cpp @@ -20,6 +20,7 @@ */ #include +#include #include #include using namespace std; @@ -28,21 +29,6 @@ using namespace dev::p2p; namespace ba = boost::asio; namespace bi = ba::ip; -class Kademlia: UDPSocketEvents -{ -public: - Kademlia(): Worker("test",0), m_io(), m_socket(new UDPSocket(m_io, *this, 30300)) {} - ~Kademlia() { m_io.stop(); stopWorking(); } - - void onDisconnected(UDPSocketFace*) {}; - void onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytesConstRef _packet) { if (_packet.toString() == "AAAA") success = true; } - - ba::io_service m_io; - shared_ptr> m_socket; - - bool success = false; -}; - class TestA: UDPSocketEvents, public Worker { public: From 400d19b140acda22ffad294db5f8958190f728e4 Mon Sep 17 00:00:00 2001 From: subtly Date: Mon, 22 Dec 2014 01:51:19 +0100 Subject: [PATCH 07/30] move some things for udp. added a class for kademlia. --- net.cpp | 567 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 530 insertions(+), 37 deletions(-) diff --git a/net.cpp b/net.cpp index 6e9efff16..0a22a7e63 100644 --- a/net.cpp +++ b/net.cpp @@ -20,8 +20,8 @@ */ #include -#include #include +#include #include using namespace std; using namespace dev; @@ -29,58 +29,551 @@ using namespace dev::p2p; namespace ba = boost::asio; namespace bi = ba::ip; -class TestA: UDPSocketEvents, public Worker +/** + * Ping packet: Check if node is alive. + * PingNode is cached and regenerated after expiration - t, where t is timeout. + * + * signature: Signature of message. + * ipAddress: Our IP address. + * port: Our port. + * expiration: Triggers regeneration of packet. May also provide control over synchronization. + * + * Ping is used to implement evict. When a new node is seen for + * a given bucket which is full, the least-responsive node is pinged. + * If the pinged node doesn't respond then it is removed and the new + * node is inserted. + */ +struct PingNode: RLPDatagram +{ + bytes ipAddress; + uint16_t port; + uint64_t expiration; + + Signature signature; + +// void streamRLP(RLPStream& _s) const { _s.appendList(3); _s << ipAddress << port << expiration; } +}; + +struct Pong: RLPDatagram +{ + // todo: weak-signed pong + Address from; + uint64_t replyTo; /// expiration from PingNode + + void streamRLP(RLPStream& _s) const { _s.appendList(2); _s << from << replyTo; } +}; + +/** + * FindNeighbors Packet: Request k-nodes, closest to the target. + * FindNeighbors is cached and regenerated after expiration - t, where t is timeout. + * + * signature: Signature of message. + * target: Address of NodeId. The responding node will send back nodes closest to the target. + * expiration: Triggers regeneration of packet. May also provide control over synchronization. + * + */ +struct FindNeighbors: RLPDatagram +{ + h160 target; + uint64_t expiration; + + Signature signature; + + void streamRLP(RLPStream& _s) const { _s.appendList(2); _s << target << expiration; } +}; + +/** + * Node Packet: Multiple node packets are sent in response to FindNeighbors. + */ +struct Neighbors: RLPDatagram +{ + struct Node + { + bytes ipAddress; + uint16_t port; + NodeId node; +// void streamRLP(RLPStream& _s) const { _s.appendList(3); _s << ipAddress << port << node; } + }; + + std::set nodes; + h256 nonce; + + Signature signature; + +// void streamRLP(RLPStream& _s) const { _s.appendList(2); _s.appendList(nodes.size()); for (auto& n: nodes) n.streamRLP(_s); _s << nonce; } +}; + +/** + * NodeTable using S/Kademlia system for node discovery and preference. + * untouched buckets are refreshed if they have not been touched within an hour + * + * Thread-safety is ensured by modifying NodeEntry details via + * shared_ptr replacement instead of mutating values. + * + * @todo don't try to evict node if node isRequired. (support for makeRequired) + * @todo optimize (use tree for state (or set w/custom compare for cache)) + * @todo constructor support for m_node, m_secret + * @todo use s_bitsPerStep for find and refresh/ping + * @todo exclude bucket from refresh if we have node as peer + * @todo restore nodes + */ +class NodeTable: UDPSocketEvents, public std::enable_shared_from_this +{ + using nodeSocket = UDPSocket; + using timePoint = std::chrono::steady_clock::time_point; + + static unsigned const s_bucketSize = 16; // Denoted by k in [Kademlia]. Number of nodes stored in each bucket. +// const unsigned s_bitsPerStep = 5; // @todo Denoted by b in [Kademlia]. Bits by which address space will be divided for find responses. + static unsigned const s_alpha = 3; // Denoted by \alpha in [Kademlia]. Number of concurrent FindNeighbors requests. + const unsigned s_findTimout = 300; // How long to wait between find queries. +// const unsigned s_siblings = 5; // @todo Denoted by s in [S/Kademlia]. User-defined by sub-protocols. + const unsigned s_bucketRefresh = 3600; // Refresh interval prevents bucket from becoming stale. [Kademlia] + const unsigned s_bits = sizeof(Address); // Denoted by n. + const unsigned s_buckets = 8 * s_bits - 1; + const unsigned s_evictionCheckInterval = 75; // Interval by which eviction timeouts are checked. + const unsigned s_pingTimeout = 500; + static size_t const s_tableSize = Address::size * 8 - 1; // Address::size + +public: + static unsigned dist(Address const& _a, Address const& _b) { u160 d = _a ^ _b; unsigned ret; for (ret = 0; d >>= 1; ++ret) {}; return ret; } + +protected: + struct NodeDefaultEndpoint + { + NodeDefaultEndpoint(bi::udp::endpoint _udp): udp(_udp) {} + bi::udp::endpoint udp; + }; + + struct NodeEntry + { + NodeEntry(Address _id, Public _pubk, bi::udp::endpoint _udp): id(_id), pubk(_pubk), endpoint(NodeDefaultEndpoint(_udp)), distance(0) {} + NodeEntry(NodeEntry _src, Address _id, Public _pubk, bi::udp::endpoint _udp): id(_id), pubk(_pubk), endpoint(NodeDefaultEndpoint(_udp)), distance(dist(_src.id,_id)) {} + NodeEntry(NodeEntry _src, Address _id, Public _pubk, NodeDefaultEndpoint _gw): id(_id), pubk(_pubk), endpoint(_gw), distance(dist(_src.id,_id)) {} + Address id; + Public pubk; + NodeDefaultEndpoint endpoint; ///< How we've previously connected to this node. (must match node's reported endpoint) + const unsigned distance; + timePoint activePing; + }; + + struct NodeBucket + { + unsigned distance; + timePoint modified; + std::list> nodes; + }; + + using EvictionTimeout = std::pair,Address>; + +public: + NodeTable(ba::io_service& _io): + m_node(NodeEntry(Address(), Public(), bi::udp::endpoint())), + m_socket(new nodeSocket(_io, *this, 30300)), + m_socketPtr(m_socket.get()), + m_io(_io), + m_bucketRefreshTimer(m_io), + m_evictionCheckTimer(m_io) + { + for (unsigned i = 0; i < s_buckets; i++) + m_state[i].distance = i, m_state[i].modified = chrono::steady_clock::now() - chrono::seconds(1); + doRefreshBuckets(boost::system::error_code()); + } + + ~NodeTable() { + m_evictionCheckTimer.cancel(); + m_bucketRefreshTimer.cancel(); + m_socketPtr->disconnect(); + } + + void join() { doFindNode(m_node.id); } + + std::list
nodes() const + { + std::list
nodes; + Guard l(x_nodes); + for (auto& i: m_nodes) + nodes.push_back(i.second->id); + return std::move(nodes); + } + + NodeEntry operator[](Address _id) + { + Guard l(x_nodes); + return *m_nodes[_id]; + } + +protected: + void requestNeighbors(NodeEntry const& _node, Address _target) const + { + FindNeighbors p; + p.target = _target; + + p.to = _node.endpoint.udp; + p.seal(m_secret); + m_socketPtr->send(p); + } + + /// Dispatches udp requests in order to populate node table to be as close as possible to _node. + void doFindNode(Address _node, unsigned _round = 0, std::shared_ptr>> _tried = std::shared_ptr>>()) + { + if (!m_socketPtr->isOpen() || _round == 7) + return; + + auto nearest = findNearest(_node); + std::list> tried; + for (unsigned i = 0; i < nearest.size() && tried.size() < s_alpha; i++) + if (!_tried->count(nearest[i])) + { + tried.push_back(nearest[i]); + requestNeighbors(*nearest[i], _node); + } + else + continue; + + while (auto n = tried.front()) + { + _tried->insert(n); + tried.pop_front(); + } + + auto self(shared_from_this()); + m_evictionCheckTimer.expires_from_now(boost::posix_time::milliseconds(s_findTimout)); + m_evictionCheckTimer.async_wait([this, self, _node, _round, _tried](boost::system::error_code const& _ec) + { + if (_ec) + return; + doFindNode(_node, _round + 1, _tried); + }); + } + + std::vector> findNearest(Address _target) + { + // send s_alpha FindNeighbors packets to nodes we know, closest to target + unsigned head = dist(m_node.id, _target); + unsigned tail = (head - 1) % (s_tableSize - 1); + + // todo: optimize with tree + std::map>> found; + unsigned count = 0; + + // if d is 0, then we roll look forward, if last, we reverse, else, spread from d + if (head != 0 && tail != s_tableSize) + while (head != tail && count < s_bucketSize) + { + Guard l(x_state); + for (auto& n: m_state[head].nodes) + if (auto p = n.lock()) + { + if (count < s_bucketSize) + found[dist(_target, p->id)].push_back(p); + else + break; + } + + if (count < s_bucketSize && head) + for (auto& n: m_state[tail].nodes) + if (auto p = n.lock()) + { + if (count < s_bucketSize) + found[dist(_target, p->id)].push_back(p); + else + break; + } + head++; + tail = (tail - 1) % (s_tableSize - 1); + } + else if (head == 0) + while (head < s_bucketSize && count < s_bucketSize) + { + Guard l(x_state); + for (auto& n: m_state[head].nodes) + if (auto p = n.lock()) + { + if (count < s_bucketSize) + found[dist(_target, p->id)].push_back(p); + else + break; + } + head--; + } + else if (tail == s_tableSize - 1) + while (tail > 0 && count < s_bucketSize) + { + Guard l(x_state); + for (auto& n: m_state[tail].nodes) + if (auto p = n.lock()) + { + if (count < s_bucketSize) + found[dist(_target, p->id)].push_back(p); + else + break; + } + tail--; + } + + std::vector> ret; + for (auto& nodes: found) + for (auto& n: nodes.second) + ret.push_back(n); + return std::move(ret); + } + + void ping(bi::address _address, unsigned _port) const + { + PingNode p; + string ip = m_node.endpoint.udp.address().to_string(); + p.ipAddress = asBytes(ip); + p.port = m_node.endpoint.udp.port(); +// p.expiration; + p.seal(m_secret); + m_socketPtr->send(p); + } + + void ping(NodeEntry* _n) const + { + if (_n && _n->endpoint.udp.address().is_v4()) + ping(_n->endpoint.udp.address(), _n->endpoint.udp.port()); + } + + void evict(std::shared_ptr _leastSeen, std::shared_ptr _new) + { + if (!m_socketPtr->isOpen()) + return; + + Guard l(x_evictions); + m_evictions.push_back(EvictionTimeout(make_pair(_leastSeen->id,chrono::steady_clock::now()), _new->id)); + if (m_evictions.size() == 1) + doCheckEvictions(boost::system::error_code()); + + m_evictions.push_back(EvictionTimeout(make_pair(_leastSeen->id,chrono::steady_clock::now()), _new->id)); + ping(_leastSeen.get()); + } + + void noteNode(Public _pubk, bi::udp::endpoint _endpoint) + { + Address id = right160(sha3(_pubk)); + std::shared_ptr node; + { + Guard l(x_nodes); + auto n = m_nodes.find(id); + if (n == m_nodes.end()) + { + m_nodes[id] = std::shared_ptr(new NodeEntry(m_node, id, _pubk, _endpoint)); + node = m_nodes[id]; + } + else + node = n->second; + } + + noteNode(node); + } + + void noteNode(std::shared_ptr _n) + { + std::shared_ptr contested; + { + NodeBucket s = bucket(_n.get()); + Guard l(x_state); + s.nodes.remove_if([&_n](std::weak_ptr n) + { + auto p = n.lock(); + if (!p || p == _n) + return true; + return false; + }); + + if (s.nodes.size() >= s_bucketSize) + { + contested = s.nodes.front().lock(); + if (!contested) + { + s.nodes.pop_front(); + s.nodes.push_back(_n); + } + } + else + s.nodes.push_back(_n); + } + + if (contested) + evict(contested, _n); + } + + void dropNode(std::shared_ptr _n) + { + NodeBucket s = bucket(_n.get()); + { + Guard l(x_state); + s.nodes.remove_if([&_n](std::weak_ptr n) { return n.lock() == _n; }); + } + Guard l(x_nodes); + m_nodes.erase(_n->id); + } + + NodeBucket const& bucket(NodeEntry* _n) const + { + return m_state[_n->distance]; + } + + void onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytesConstRef _packet) + { + RLP rlp(_packet); + + + // whenever a pong is received, first check if it's in m_evictions, if so, remove it + Guard l(x_evictions); + } + + void onDisconnected(UDPSocketFace*) + { + + } + + void doCheckEvictions(boost::system::error_code const& _ec) + { + if (_ec || !m_socketPtr->isOpen()) + return; + + m_evictionCheckTimer.expires_from_now(boost::posix_time::milliseconds(s_evictionCheckInterval)); + auto self(shared_from_this()); + m_evictionCheckTimer.async_wait([this, self](boost::system::error_code const& _ec) + { + if (_ec) + return; + + bool evictionsRemain = false; + std::list> drop; + { + Guard l(x_evictions); + for (auto& e: m_evictions) + if (chrono::steady_clock::now() - e.first.second > chrono::milliseconds(s_pingTimeout)) + { + Guard l(x_nodes); + drop.push_back(m_nodes[e.second]); + } + evictionsRemain = m_evictions.size() - drop.size() > 0; + } + + for (auto& n: drop) + dropNode(n); + + if (evictionsRemain) + doCheckEvictions(boost::system::error_code()); + }); + } + + void doRefreshBuckets(boost::system::error_code const& _ec) + { + cout << "refreshing buckets" << endl; + if (_ec) + return; + + // first check if there are any pending evictions + + + bool connected = m_socketPtr->isOpen(); + bool refreshed = false; + if (connected) + { + Guard l(x_state); + for (auto& d: m_state) + if (chrono::steady_clock::now() - d.modified > chrono::seconds(s_bucketRefresh)) + while (!d.nodes.empty()) + { + auto n = d.nodes.front(); + if (auto p = n.lock()) + { + refreshed = true; + ping(p.get()); + break; + } + d.nodes.pop_front(); + } + } + + unsigned nextRefresh = connected ? (refreshed ? 200 : s_bucketRefresh*1000) : 10000; + auto runcb = [this](boost::system::error_code const& error) -> void { doRefreshBuckets(error); }; + m_bucketRefreshTimer.expires_from_now(boost::posix_time::milliseconds(nextRefresh)); + m_bucketRefreshTimer.async_wait(runcb); + } + +private: + NodeEntry m_node; ///< This node. + Secret m_secret; ///< This nodes secret key. + + mutable Mutex x_nodes; ///< Mutable for thread-safe copy in nodes() const. + std::map> m_nodes; ///< Address -> Node table (most common lookup path) + + Mutex x_state; + std::array m_state; ///< State table; logbinned nodes. + + Mutex x_evictions; + std::deque m_evictions; ///< Eviction timeouts. + + shared_ptr m_socket; ///< Shared pointer for our UDPSocket; ASIO requires shared_ptr. + nodeSocket* m_socketPtr; ///< Set to m_socket.get(). + ba::io_service& m_io; ///< Used by bucket refresh timer. + boost::asio::deadline_timer m_bucketRefreshTimer; ///< Timer which schedules and enacts bucket refresh. + boost::asio::deadline_timer m_evictionCheckTimer; ///< Timer for handling node evictions. +}; + +/** + * Only used for testing. Not useful beyond tests. + */ +class TestHost: public Worker { public: - TestA(): Worker("test",0), m_io(), m_socket(new UDPSocket(m_io, *this, 30300)) {} - ~TestA() { m_io.stop(); stopWorking(); } + TestHost(): Worker("test",0), m_io() {}; + ~TestHost() { m_io.stop(); stopWorking(); } + void start() { startWorking(); } + void doWork() { m_io.run(); } +protected: + ba::io_service m_io; +}; + +/** + * Only used for testing. Not useful beyond tests. + */ +class TestNodeHost: public TestHost +{ +public: + TestNodeHost(): m_nodes(m_io) {}; + ~TestNodeHost() { m_io.stop(); stopWorking(); } + void start() { startWorking(); } + void doWork() { m_io.run(); } + + NodeTable m_nodes; +}; + +class TestUDPSocket: UDPSocketEvents, public TestHost +{ +public: + TestUDPSocket(): m_socket(new UDPSocket(m_io, *this, 30300)) {} + ~TestUDPSocket() { m_io.stop(); stopWorking(); } void start() { startWorking(); } void doWork() { m_io.run(); } void onDisconnected(UDPSocketFace*) {}; - void onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytesConstRef _packet) { if (_packet.toString() == "AAAA") success = true; } + void onReceived(UDPSocketFace*, bi::udp::endpoint const&, bytesConstRef _packet) { if (_packet.toString() == "AAAA") success = true; } - ba::io_service m_io; - shared_ptr> m_socket; + shared_ptr> m_socket; bool success = false; }; -//struct TestBProtocol: UDPSocketEvents -//{ -// void onDisconnected(UDPSocketFace*) {}; -// void onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytesConstRef _packet) { cout << "received TestBProtocol" << endl; }; -//}; -// -//class TestB: TestBProtocol -//{ -//public: -// TestB(): m_io(), m_socket(m_io, *this, 30300) {} -////private: -// ba::io_service m_io; -// UDPSocket m_socket; -//}; -// -//class TestC -//{ -//public: -// TestC(): m_io(), m_socket(m_io, m_rpc, 30300) {} -////private: -// ba::io_service m_io; -// TestBProtocol m_rpc; -// UDPSocket m_socket; -//}; - BOOST_AUTO_TEST_SUITE(p2p) +BOOST_AUTO_TEST_CASE(kademlia) +{ + TestNodeHost nodeHost; + +} + BOOST_AUTO_TEST_CASE(test_txrx_one) { - UDPDatagram d; - d.to = boost::asio::ip::udp::endpoint(boost::asio::ip::address::from_string("127.0.0.1"), 30300); - d.data = bytes({65,65,65,65}); - - TestA a; a.m_socket->connect(); a.start(); + UDPDatagram d(bi::udp::endpoint(boost::asio::ip::address::from_string("127.0.0.1"), 30300), bytes({65,65,65,65})); + TestUDPSocket a; a.m_socket->connect(); a.start(); a.m_socket->send(d); sleep(1); BOOST_REQUIRE_EQUAL(true, a.success); From 88f7ff617d3878001ab7732a913e3ab21639b1db Mon Sep 17 00:00:00 2001 From: subtly Date: Mon, 22 Dec 2014 03:56:07 +0100 Subject: [PATCH 08/30] repot. --- net.cpp | 489 +------------------------------------------------------- 1 file changed, 1 insertion(+), 488 deletions(-) diff --git a/net.cpp b/net.cpp index 0a22a7e63..3d2e08eb6 100644 --- a/net.cpp +++ b/net.cpp @@ -23,500 +23,13 @@ #include #include #include +#include using namespace std; using namespace dev; using namespace dev::p2p; namespace ba = boost::asio; namespace bi = ba::ip; -/** - * Ping packet: Check if node is alive. - * PingNode is cached and regenerated after expiration - t, where t is timeout. - * - * signature: Signature of message. - * ipAddress: Our IP address. - * port: Our port. - * expiration: Triggers regeneration of packet. May also provide control over synchronization. - * - * Ping is used to implement evict. When a new node is seen for - * a given bucket which is full, the least-responsive node is pinged. - * If the pinged node doesn't respond then it is removed and the new - * node is inserted. - */ -struct PingNode: RLPDatagram -{ - bytes ipAddress; - uint16_t port; - uint64_t expiration; - - Signature signature; - -// void streamRLP(RLPStream& _s) const { _s.appendList(3); _s << ipAddress << port << expiration; } -}; - -struct Pong: RLPDatagram -{ - // todo: weak-signed pong - Address from; - uint64_t replyTo; /// expiration from PingNode - - void streamRLP(RLPStream& _s) const { _s.appendList(2); _s << from << replyTo; } -}; - -/** - * FindNeighbors Packet: Request k-nodes, closest to the target. - * FindNeighbors is cached and regenerated after expiration - t, where t is timeout. - * - * signature: Signature of message. - * target: Address of NodeId. The responding node will send back nodes closest to the target. - * expiration: Triggers regeneration of packet. May also provide control over synchronization. - * - */ -struct FindNeighbors: RLPDatagram -{ - h160 target; - uint64_t expiration; - - Signature signature; - - void streamRLP(RLPStream& _s) const { _s.appendList(2); _s << target << expiration; } -}; - -/** - * Node Packet: Multiple node packets are sent in response to FindNeighbors. - */ -struct Neighbors: RLPDatagram -{ - struct Node - { - bytes ipAddress; - uint16_t port; - NodeId node; -// void streamRLP(RLPStream& _s) const { _s.appendList(3); _s << ipAddress << port << node; } - }; - - std::set nodes; - h256 nonce; - - Signature signature; - -// void streamRLP(RLPStream& _s) const { _s.appendList(2); _s.appendList(nodes.size()); for (auto& n: nodes) n.streamRLP(_s); _s << nonce; } -}; - -/** - * NodeTable using S/Kademlia system for node discovery and preference. - * untouched buckets are refreshed if they have not been touched within an hour - * - * Thread-safety is ensured by modifying NodeEntry details via - * shared_ptr replacement instead of mutating values. - * - * @todo don't try to evict node if node isRequired. (support for makeRequired) - * @todo optimize (use tree for state (or set w/custom compare for cache)) - * @todo constructor support for m_node, m_secret - * @todo use s_bitsPerStep for find and refresh/ping - * @todo exclude bucket from refresh if we have node as peer - * @todo restore nodes - */ -class NodeTable: UDPSocketEvents, public std::enable_shared_from_this -{ - using nodeSocket = UDPSocket; - using timePoint = std::chrono::steady_clock::time_point; - - static unsigned const s_bucketSize = 16; // Denoted by k in [Kademlia]. Number of nodes stored in each bucket. -// const unsigned s_bitsPerStep = 5; // @todo Denoted by b in [Kademlia]. Bits by which address space will be divided for find responses. - static unsigned const s_alpha = 3; // Denoted by \alpha in [Kademlia]. Number of concurrent FindNeighbors requests. - const unsigned s_findTimout = 300; // How long to wait between find queries. -// const unsigned s_siblings = 5; // @todo Denoted by s in [S/Kademlia]. User-defined by sub-protocols. - const unsigned s_bucketRefresh = 3600; // Refresh interval prevents bucket from becoming stale. [Kademlia] - const unsigned s_bits = sizeof(Address); // Denoted by n. - const unsigned s_buckets = 8 * s_bits - 1; - const unsigned s_evictionCheckInterval = 75; // Interval by which eviction timeouts are checked. - const unsigned s_pingTimeout = 500; - static size_t const s_tableSize = Address::size * 8 - 1; // Address::size - -public: - static unsigned dist(Address const& _a, Address const& _b) { u160 d = _a ^ _b; unsigned ret; for (ret = 0; d >>= 1; ++ret) {}; return ret; } - -protected: - struct NodeDefaultEndpoint - { - NodeDefaultEndpoint(bi::udp::endpoint _udp): udp(_udp) {} - bi::udp::endpoint udp; - }; - - struct NodeEntry - { - NodeEntry(Address _id, Public _pubk, bi::udp::endpoint _udp): id(_id), pubk(_pubk), endpoint(NodeDefaultEndpoint(_udp)), distance(0) {} - NodeEntry(NodeEntry _src, Address _id, Public _pubk, bi::udp::endpoint _udp): id(_id), pubk(_pubk), endpoint(NodeDefaultEndpoint(_udp)), distance(dist(_src.id,_id)) {} - NodeEntry(NodeEntry _src, Address _id, Public _pubk, NodeDefaultEndpoint _gw): id(_id), pubk(_pubk), endpoint(_gw), distance(dist(_src.id,_id)) {} - Address id; - Public pubk; - NodeDefaultEndpoint endpoint; ///< How we've previously connected to this node. (must match node's reported endpoint) - const unsigned distance; - timePoint activePing; - }; - - struct NodeBucket - { - unsigned distance; - timePoint modified; - std::list> nodes; - }; - - using EvictionTimeout = std::pair,Address>; - -public: - NodeTable(ba::io_service& _io): - m_node(NodeEntry(Address(), Public(), bi::udp::endpoint())), - m_socket(new nodeSocket(_io, *this, 30300)), - m_socketPtr(m_socket.get()), - m_io(_io), - m_bucketRefreshTimer(m_io), - m_evictionCheckTimer(m_io) - { - for (unsigned i = 0; i < s_buckets; i++) - m_state[i].distance = i, m_state[i].modified = chrono::steady_clock::now() - chrono::seconds(1); - doRefreshBuckets(boost::system::error_code()); - } - - ~NodeTable() { - m_evictionCheckTimer.cancel(); - m_bucketRefreshTimer.cancel(); - m_socketPtr->disconnect(); - } - - void join() { doFindNode(m_node.id); } - - std::list
nodes() const - { - std::list
nodes; - Guard l(x_nodes); - for (auto& i: m_nodes) - nodes.push_back(i.second->id); - return std::move(nodes); - } - - NodeEntry operator[](Address _id) - { - Guard l(x_nodes); - return *m_nodes[_id]; - } - -protected: - void requestNeighbors(NodeEntry const& _node, Address _target) const - { - FindNeighbors p; - p.target = _target; - - p.to = _node.endpoint.udp; - p.seal(m_secret); - m_socketPtr->send(p); - } - - /// Dispatches udp requests in order to populate node table to be as close as possible to _node. - void doFindNode(Address _node, unsigned _round = 0, std::shared_ptr>> _tried = std::shared_ptr>>()) - { - if (!m_socketPtr->isOpen() || _round == 7) - return; - - auto nearest = findNearest(_node); - std::list> tried; - for (unsigned i = 0; i < nearest.size() && tried.size() < s_alpha; i++) - if (!_tried->count(nearest[i])) - { - tried.push_back(nearest[i]); - requestNeighbors(*nearest[i], _node); - } - else - continue; - - while (auto n = tried.front()) - { - _tried->insert(n); - tried.pop_front(); - } - - auto self(shared_from_this()); - m_evictionCheckTimer.expires_from_now(boost::posix_time::milliseconds(s_findTimout)); - m_evictionCheckTimer.async_wait([this, self, _node, _round, _tried](boost::system::error_code const& _ec) - { - if (_ec) - return; - doFindNode(_node, _round + 1, _tried); - }); - } - - std::vector> findNearest(Address _target) - { - // send s_alpha FindNeighbors packets to nodes we know, closest to target - unsigned head = dist(m_node.id, _target); - unsigned tail = (head - 1) % (s_tableSize - 1); - - // todo: optimize with tree - std::map>> found; - unsigned count = 0; - - // if d is 0, then we roll look forward, if last, we reverse, else, spread from d - if (head != 0 && tail != s_tableSize) - while (head != tail && count < s_bucketSize) - { - Guard l(x_state); - for (auto& n: m_state[head].nodes) - if (auto p = n.lock()) - { - if (count < s_bucketSize) - found[dist(_target, p->id)].push_back(p); - else - break; - } - - if (count < s_bucketSize && head) - for (auto& n: m_state[tail].nodes) - if (auto p = n.lock()) - { - if (count < s_bucketSize) - found[dist(_target, p->id)].push_back(p); - else - break; - } - head++; - tail = (tail - 1) % (s_tableSize - 1); - } - else if (head == 0) - while (head < s_bucketSize && count < s_bucketSize) - { - Guard l(x_state); - for (auto& n: m_state[head].nodes) - if (auto p = n.lock()) - { - if (count < s_bucketSize) - found[dist(_target, p->id)].push_back(p); - else - break; - } - head--; - } - else if (tail == s_tableSize - 1) - while (tail > 0 && count < s_bucketSize) - { - Guard l(x_state); - for (auto& n: m_state[tail].nodes) - if (auto p = n.lock()) - { - if (count < s_bucketSize) - found[dist(_target, p->id)].push_back(p); - else - break; - } - tail--; - } - - std::vector> ret; - for (auto& nodes: found) - for (auto& n: nodes.second) - ret.push_back(n); - return std::move(ret); - } - - void ping(bi::address _address, unsigned _port) const - { - PingNode p; - string ip = m_node.endpoint.udp.address().to_string(); - p.ipAddress = asBytes(ip); - p.port = m_node.endpoint.udp.port(); -// p.expiration; - p.seal(m_secret); - m_socketPtr->send(p); - } - - void ping(NodeEntry* _n) const - { - if (_n && _n->endpoint.udp.address().is_v4()) - ping(_n->endpoint.udp.address(), _n->endpoint.udp.port()); - } - - void evict(std::shared_ptr _leastSeen, std::shared_ptr _new) - { - if (!m_socketPtr->isOpen()) - return; - - Guard l(x_evictions); - m_evictions.push_back(EvictionTimeout(make_pair(_leastSeen->id,chrono::steady_clock::now()), _new->id)); - if (m_evictions.size() == 1) - doCheckEvictions(boost::system::error_code()); - - m_evictions.push_back(EvictionTimeout(make_pair(_leastSeen->id,chrono::steady_clock::now()), _new->id)); - ping(_leastSeen.get()); - } - - void noteNode(Public _pubk, bi::udp::endpoint _endpoint) - { - Address id = right160(sha3(_pubk)); - std::shared_ptr node; - { - Guard l(x_nodes); - auto n = m_nodes.find(id); - if (n == m_nodes.end()) - { - m_nodes[id] = std::shared_ptr(new NodeEntry(m_node, id, _pubk, _endpoint)); - node = m_nodes[id]; - } - else - node = n->second; - } - - noteNode(node); - } - - void noteNode(std::shared_ptr _n) - { - std::shared_ptr contested; - { - NodeBucket s = bucket(_n.get()); - Guard l(x_state); - s.nodes.remove_if([&_n](std::weak_ptr n) - { - auto p = n.lock(); - if (!p || p == _n) - return true; - return false; - }); - - if (s.nodes.size() >= s_bucketSize) - { - contested = s.nodes.front().lock(); - if (!contested) - { - s.nodes.pop_front(); - s.nodes.push_back(_n); - } - } - else - s.nodes.push_back(_n); - } - - if (contested) - evict(contested, _n); - } - - void dropNode(std::shared_ptr _n) - { - NodeBucket s = bucket(_n.get()); - { - Guard l(x_state); - s.nodes.remove_if([&_n](std::weak_ptr n) { return n.lock() == _n; }); - } - Guard l(x_nodes); - m_nodes.erase(_n->id); - } - - NodeBucket const& bucket(NodeEntry* _n) const - { - return m_state[_n->distance]; - } - - void onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytesConstRef _packet) - { - RLP rlp(_packet); - - - // whenever a pong is received, first check if it's in m_evictions, if so, remove it - Guard l(x_evictions); - } - - void onDisconnected(UDPSocketFace*) - { - - } - - void doCheckEvictions(boost::system::error_code const& _ec) - { - if (_ec || !m_socketPtr->isOpen()) - return; - - m_evictionCheckTimer.expires_from_now(boost::posix_time::milliseconds(s_evictionCheckInterval)); - auto self(shared_from_this()); - m_evictionCheckTimer.async_wait([this, self](boost::system::error_code const& _ec) - { - if (_ec) - return; - - bool evictionsRemain = false; - std::list> drop; - { - Guard l(x_evictions); - for (auto& e: m_evictions) - if (chrono::steady_clock::now() - e.first.second > chrono::milliseconds(s_pingTimeout)) - { - Guard l(x_nodes); - drop.push_back(m_nodes[e.second]); - } - evictionsRemain = m_evictions.size() - drop.size() > 0; - } - - for (auto& n: drop) - dropNode(n); - - if (evictionsRemain) - doCheckEvictions(boost::system::error_code()); - }); - } - - void doRefreshBuckets(boost::system::error_code const& _ec) - { - cout << "refreshing buckets" << endl; - if (_ec) - return; - - // first check if there are any pending evictions - - - bool connected = m_socketPtr->isOpen(); - bool refreshed = false; - if (connected) - { - Guard l(x_state); - for (auto& d: m_state) - if (chrono::steady_clock::now() - d.modified > chrono::seconds(s_bucketRefresh)) - while (!d.nodes.empty()) - { - auto n = d.nodes.front(); - if (auto p = n.lock()) - { - refreshed = true; - ping(p.get()); - break; - } - d.nodes.pop_front(); - } - } - - unsigned nextRefresh = connected ? (refreshed ? 200 : s_bucketRefresh*1000) : 10000; - auto runcb = [this](boost::system::error_code const& error) -> void { doRefreshBuckets(error); }; - m_bucketRefreshTimer.expires_from_now(boost::posix_time::milliseconds(nextRefresh)); - m_bucketRefreshTimer.async_wait(runcb); - } - -private: - NodeEntry m_node; ///< This node. - Secret m_secret; ///< This nodes secret key. - - mutable Mutex x_nodes; ///< Mutable for thread-safe copy in nodes() const. - std::map> m_nodes; ///< Address -> Node table (most common lookup path) - - Mutex x_state; - std::array m_state; ///< State table; logbinned nodes. - - Mutex x_evictions; - std::deque m_evictions; ///< Eviction timeouts. - - shared_ptr m_socket; ///< Shared pointer for our UDPSocket; ASIO requires shared_ptr. - nodeSocket* m_socketPtr; ///< Set to m_socket.get(). - ba::io_service& m_io; ///< Used by bucket refresh timer. - boost::asio::deadline_timer m_bucketRefreshTimer; ///< Timer which schedules and enacts bucket refresh. - boost::asio::deadline_timer m_evictionCheckTimer; ///< Timer for handling node evictions. -}; - /** * Only used for testing. Not useful beyond tests. */ From 1e0d4c95ce3d788b0be8cb5b8b32ede72683e7ae Mon Sep 17 00:00:00 2001 From: subtly Date: Tue, 23 Dec 2014 08:56:56 +0100 Subject: [PATCH 09/30] refactor constants to be determined during compile. added RLPXDatagram. constructors and updates to datagram constructors. docs and logging. WIP tests and host/harness for NodeTable. --- net.cpp | 71 +++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 54 insertions(+), 17 deletions(-) diff --git a/net.cpp b/net.cpp index 3d2e08eb6..886e17a47 100644 --- a/net.cpp +++ b/net.cpp @@ -30,6 +30,8 @@ using namespace dev::p2p; namespace ba = boost::asio; namespace bi = ba::ip; +BOOST_AUTO_TEST_SUITE(p2p) + /** * Only used for testing. Not useful beyond tests. */ @@ -37,7 +39,7 @@ class TestHost: public Worker { public: TestHost(): Worker("test",0), m_io() {}; - ~TestHost() { m_io.stop(); stopWorking(); } + virtual ~TestHost() { m_io.stop(); stopWorking(); } void start() { startWorking(); } void doWork() { m_io.run(); } @@ -45,28 +47,62 @@ protected: ba::io_service m_io; }; +struct TestNodeTable: public NodeTable +{ + void generateTestNodes(int _count = 10) + { + asserts(_count < 1000); + static uint16_t s_basePort = 30500; + + m_testNodes.clear(); + for (auto i = 0; i < _count; i++) + m_testNodes.push_back(make_pair(KeyPair::create(),s_basePort++)); + } + std::vector> m_testNodes; // keypair and port + + /// Constructor + using NodeTable::NodeTable; + + void setup() + { + /// Phase 1 test: populate with pings + /// Phase 2 test: pre-populate *expected* ping-responses, send pings + + bi::address ourIp = bi::address::from_string("127.0.0.1"); + uint16_t ourPort = 30300; + bi::udp::endpoint ourEndpoint(ourIp, ourPort); + + generateTestNodes(); + for (auto& n: m_testNodes) + ping(bi::udp::endpoint(ourIp, n.second)); + + // wait 1ms between each send + // send PingNode for each s_bootstrapNodes + // wait until nodecount is s_testNodes.count() + + } + + void reset() + { + Guard l(x_state); + for (auto& n: m_state) n.nodes.clear(); + } +}; + /** * Only used for testing. Not useful beyond tests. */ -class TestNodeHost: public TestHost +struct TestNodeTableHost: public TestHost { -public: - TestNodeHost(): m_nodes(m_io) {}; - ~TestNodeHost() { m_io.stop(); stopWorking(); } - void start() { startWorking(); } - void doWork() { m_io.run(); } - - NodeTable m_nodes; + TestNodeTableHost(): nodeTable(new TestNodeTable(m_io)) {}; + shared_ptr nodeTable; }; class TestUDPSocket: UDPSocketEvents, public TestHost { public: TestUDPSocket(): m_socket(new UDPSocket(m_io, *this, 30300)) {} - ~TestUDPSocket() { m_io.stop(); stopWorking(); } - void start() { startWorking(); } - void doWork() { m_io.run(); } - + void onDisconnected(UDPSocketFace*) {}; void onReceived(UDPSocketFace*, bi::udp::endpoint const&, bytesConstRef _packet) { if (_packet.toString() == "AAAA") success = true; } @@ -75,12 +111,13 @@ public: bool success = false; }; -BOOST_AUTO_TEST_SUITE(p2p) - BOOST_AUTO_TEST_CASE(kademlia) { - TestNodeHost nodeHost; - +// TestNodeTableHost node; +// node.start(); +// node.nodeTable->join(); // ideally, joining with empty node table logs warning we can check for +// node.nodeTable->setup(); +// sleep(1); } BOOST_AUTO_TEST_CASE(test_txrx_one) From cb6517e99e568b01bd46eba5b1c403cea6ea3428 Mon Sep 17 00:00:00 2001 From: subtly Date: Tue, 23 Dec 2014 09:25:36 +0100 Subject: [PATCH 10/30] send/receive messages (not yet interepreted) --- net.cpp | 52 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/net.cpp b/net.cpp index 886e17a47..d3aaae53d 100644 --- a/net.cpp +++ b/net.cpp @@ -49,21 +49,10 @@ protected: struct TestNodeTable: public NodeTable { - void generateTestNodes(int _count = 10) - { - asserts(_count < 1000); - static uint16_t s_basePort = 30500; - - m_testNodes.clear(); - for (auto i = 0; i < _count; i++) - m_testNodes.push_back(make_pair(KeyPair::create(),s_basePort++)); - } - std::vector> m_testNodes; // keypair and port - /// Constructor using NodeTable::NodeTable; - void setup() + void setup(std::vector> const& _testNodes) { /// Phase 1 test: populate with pings /// Phase 2 test: pre-populate *expected* ping-responses, send pings @@ -72,8 +61,7 @@ struct TestNodeTable: public NodeTable uint16_t ourPort = 30300; bi::udp::endpoint ourEndpoint(ourIp, ourPort); - generateTestNodes(); - for (auto& n: m_testNodes) + for (auto& n: _testNodes) ping(bi::udp::endpoint(ourIp, n.second)); // wait 1ms between each send @@ -94,8 +82,32 @@ struct TestNodeTable: public NodeTable */ struct TestNodeTableHost: public TestHost { - TestNodeTableHost(): nodeTable(new TestNodeTable(m_io)) {}; + TestNodeTableHost(): m_alias(KeyPair::create()), nodeTable(new TestNodeTable(m_io, m_alias)) {}; + + void generateTestNodes(int _count = 10) + { + asserts(_count < 1000); + static uint16_t s_basePort = 30500; + + m_testNodes.clear(); + for (auto i = 0; i < _count; i++) + { + KeyPair k = KeyPair::create(); + m_testNodes.push_back(make_pair(k,s_basePort+i)); + testNodes.push_back(make_shared(m_io,k,s_basePort+i)); + } + } + std::vector> m_testNodes; // keypair and port + + void setup() + { + generateTestNodes(); + nodeTable->setup(m_testNodes); + } + + KeyPair m_alias; shared_ptr nodeTable; + std::vector> testNodes; }; class TestUDPSocket: UDPSocketEvents, public TestHost @@ -113,11 +125,11 @@ public: BOOST_AUTO_TEST_CASE(kademlia) { -// TestNodeTableHost node; -// node.start(); -// node.nodeTable->join(); // ideally, joining with empty node table logs warning we can check for -// node.nodeTable->setup(); -// sleep(1); + TestNodeTableHost node; + node.start(); + node.nodeTable->join(); // ideally, joining with empty node table logs warning we can check for + node.setup(); + sleep(1); } BOOST_AUTO_TEST_CASE(test_txrx_one) From 25a905b740892831f07c3d54f465ddaaf83441a6 Mon Sep 17 00:00:00 2001 From: subtly Date: Tue, 23 Dec 2014 13:44:52 +0100 Subject: [PATCH 11/30] basic implementation of packets --- net.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/net.cpp b/net.cpp index d3aaae53d..8277c1f70 100644 --- a/net.cpp +++ b/net.cpp @@ -54,7 +54,6 @@ struct TestNodeTable: public NodeTable void setup(std::vector> const& _testNodes) { - /// Phase 1 test: populate with pings /// Phase 2 test: pre-populate *expected* ping-responses, send pings bi::address ourIp = bi::address::from_string("127.0.0.1"); @@ -63,11 +62,6 @@ struct TestNodeTable: public NodeTable for (auto& n: _testNodes) ping(bi::udp::endpoint(ourIp, n.second)); - - // wait 1ms between each send - // send PingNode for each s_bootstrapNodes - // wait until nodecount is s_testNodes.count() - } void reset() From aad7141f0af696ec386f58e41fa9ecc862f116d7 Mon Sep 17 00:00:00 2001 From: subtly Date: Wed, 24 Dec 2014 10:22:27 +0100 Subject: [PATCH 12/30] message signing and verification. shutdown io/thread before dealloc in nodetable/testnodetables. --- net.cpp | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/net.cpp b/net.cpp index 8277c1f70..274f729c6 100644 --- a/net.cpp +++ b/net.cpp @@ -42,6 +42,7 @@ public: virtual ~TestHost() { m_io.stop(); stopWorking(); } void start() { startWorking(); } void doWork() { m_io.run(); } + void doneWorking() { m_io.reset(); m_io.poll(); m_io.reset(); } protected: ba::io_service m_io; @@ -52,18 +53,20 @@ struct TestNodeTable: public NodeTable /// Constructor using NodeTable::NodeTable; - void setup(std::vector> const& _testNodes) + void pingAll(std::vector> const& _testNodes) { - /// Phase 2 test: pre-populate *expected* ping-responses, send pings - bi::address ourIp = bi::address::from_string("127.0.0.1"); - uint16_t ourPort = 30300; - bi::udp::endpoint ourEndpoint(ourIp, ourPort); - for (auto& n: _testNodes) ping(bi::udp::endpoint(ourIp, n.second)); } + void populate(std::vector> const& _testNodes) + { + bi::address ourIp = bi::address::from_string("127.0.0.1"); + for (auto& n: _testNodes) + noteNode(n.first.pub(), bi::udp::endpoint(ourIp, n.second)); + } + void reset() { Guard l(x_state); @@ -77,8 +80,9 @@ struct TestNodeTable: public NodeTable struct TestNodeTableHost: public TestHost { TestNodeTableHost(): m_alias(KeyPair::create()), nodeTable(new TestNodeTable(m_io, m_alias)) {}; + ~TestNodeTableHost() { m_io.stop(); stopWorking(); } - void generateTestNodes(int _count = 10) + void generateTestNodes(int _count = 30) { asserts(_count < 1000); static uint16_t s_basePort = 30500; @@ -96,7 +100,16 @@ struct TestNodeTableHost: public TestHost void setup() { generateTestNodes(); - nodeTable->setup(m_testNodes); + } + + void pingAll() + { + nodeTable->pingAll(m_testNodes); + } + + void populate() + { + nodeTable->populate(m_testNodes); } KeyPair m_alias; @@ -123,7 +136,10 @@ BOOST_AUTO_TEST_CASE(kademlia) node.start(); node.nodeTable->join(); // ideally, joining with empty node table logs warning we can check for node.setup(); - sleep(1); + node.pingAll(); + this_thread::sleep_for(chrono::milliseconds(500)); + + cout << "NodeTable:\n" << *node.nodeTable.get() << endl; } BOOST_AUTO_TEST_CASE(test_txrx_one) From 7553954cf200f6ee7ee6ff6769020759dcb7b671 Mon Sep 17 00:00:00 2001 From: subtly Date: Wed, 24 Dec 2014 14:48:47 +0100 Subject: [PATCH 13/30] memory --- net.cpp | 43 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/net.cpp b/net.cpp index 274f729c6..d5113b8b4 100644 --- a/net.cpp +++ b/net.cpp @@ -57,14 +57,23 @@ struct TestNodeTable: public NodeTable { bi::address ourIp = bi::address::from_string("127.0.0.1"); for (auto& n: _testNodes) + { ping(bi::udp::endpoint(ourIp, n.second)); + this_thread::sleep_for(chrono::milliseconds(5)); + } } - void populate(std::vector> const& _testNodes) + void populate(std::vector> const& _testNodes, size_t _count = 0) { + if (!_count) + _count = _testNodes.size(); + bi::address ourIp = bi::address::from_string("127.0.0.1"); for (auto& n: _testNodes) - noteNode(n.first.pub(), bi::udp::endpoint(ourIp, n.second)); + if (_count--) + noteNode(n.first.pub(), bi::udp::endpoint(ourIp, n.second)); + else + break; } void reset() @@ -82,7 +91,7 @@ struct TestNodeTableHost: public TestHost TestNodeTableHost(): m_alias(KeyPair::create()), nodeTable(new TestNodeTable(m_io, m_alias)) {}; ~TestNodeTableHost() { m_io.stop(); stopWorking(); } - void generateTestNodes(int _count = 30) + void generateTestNodes(int _count = 16) { asserts(_count < 1000); static uint16_t s_basePort = 30500; @@ -105,11 +114,13 @@ struct TestNodeTableHost: public TestHost void pingAll() { nodeTable->pingAll(m_testNodes); +// for (auto& n: testNodes) +// n->pingAll(m_testNodes); } - void populate() + void populate(size_t _count = 0) { - nodeTable->populate(m_testNodes); + nodeTable->populate(m_testNodes, _count); } KeyPair m_alias; @@ -130,6 +141,13 @@ public: bool success = false; }; +BOOST_AUTO_TEST_CASE(test_findnode_neighbors) +{ + // Executing findNode should result in a list which is serialized + // into Neighbors packet. Neighbors packet should then be deserialized + // into the same list of nearest nodes. +} + BOOST_AUTO_TEST_CASE(kademlia) { TestNodeTableHost node; @@ -137,12 +155,23 @@ BOOST_AUTO_TEST_CASE(kademlia) node.nodeTable->join(); // ideally, joining with empty node table logs warning we can check for node.setup(); node.pingAll(); + clog << "NodeTable:\n" << *node.nodeTable.get() << endl; + this_thread::sleep_for(chrono::milliseconds(10000)); + + node.nodeTable->reset(); + clog << "NodeTable:\n" << *node.nodeTable.get() << endl; + + node.populate(2); + clog << "NodeTable:\n" << *node.nodeTable.get() << endl; this_thread::sleep_for(chrono::milliseconds(500)); - cout << "NodeTable:\n" << *node.nodeTable.get() << endl; +// node.nodeTable->join(); +// this_thread::sleep_for(chrono::milliseconds(2000)); +// +// clog << "NodeTable:\n" << *node.nodeTable.get() << endl; } -BOOST_AUTO_TEST_CASE(test_txrx_one) +BOOST_AUTO_TEST_CASE(test_udp_once) { UDPDatagram d(bi::udp::endpoint(boost::asio::ip::address::from_string("127.0.0.1"), 30300), bytes({65,65,65,65})); TestUDPSocket a; a.m_socket->connect(); a.start(); From b66334952443955b157e6693d871c7aa242ae07a Mon Sep 17 00:00:00 2001 From: subtly Date: Fri, 26 Dec 2014 00:56:50 +0100 Subject: [PATCH 14/30] test encoding/decoding neighbors. add MAC. --- net.cpp | 103 ++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 63 insertions(+), 40 deletions(-) diff --git a/net.cpp b/net.cpp index d5113b8b4..4c45475f3 100644 --- a/net.cpp +++ b/net.cpp @@ -53,7 +53,23 @@ struct TestNodeTable: public NodeTable /// Constructor using NodeTable::NodeTable; - void pingAll(std::vector> const& _testNodes) + static std::vector> createTestNodes(int _count = 16) + { + std::vector> ret; + asserts(_count < 1000); + static uint16_t s_basePort = 30500; + + ret.clear(); + for (auto i = 0; i < _count; i++) + { + KeyPair k = KeyPair::create(); + ret.push_back(make_pair(k,s_basePort+i)); + } + + return std::move(ret); + } + + void pingTestNodes(std::vector> const& _testNodes) { bi::address ourIp = bi::address::from_string("127.0.0.1"); for (auto& n: _testNodes) @@ -63,7 +79,7 @@ struct TestNodeTable: public NodeTable } } - void populate(std::vector> const& _testNodes, size_t _count = 0) + void populateTestNodes(std::vector> const& _testNodes, size_t _count = 0) { if (!_count) _count = _testNodes.size(); @@ -88,44 +104,19 @@ struct TestNodeTable: public NodeTable */ struct TestNodeTableHost: public TestHost { - TestNodeTableHost(): m_alias(KeyPair::create()), nodeTable(new TestNodeTable(m_io, m_alias)) {}; + TestNodeTableHost(): m_alias(KeyPair::create()), nodeTable(new TestNodeTable(m_io, m_alias)), testNodes(TestNodeTable::createTestNodes()) {}; ~TestNodeTableHost() { m_io.stop(); stopWorking(); } - - void generateTestNodes(int _count = 16) - { - asserts(_count < 1000); - static uint16_t s_basePort = 30500; - - m_testNodes.clear(); - for (auto i = 0; i < _count; i++) - { - KeyPair k = KeyPair::create(); - m_testNodes.push_back(make_pair(k,s_basePort+i)); - testNodes.push_back(make_shared(m_io,k,s_basePort+i)); - } - } - std::vector> m_testNodes; // keypair and port - void setup() - { - generateTestNodes(); - } + void setup() { for (auto n: testNodes) nodeTables.push_back(make_shared(m_io,n.first,n.second)); } - void pingAll() - { - nodeTable->pingAll(m_testNodes); -// for (auto& n: testNodes) -// n->pingAll(m_testNodes); - } + void pingAll() { for (auto& t: nodeTables) t->pingTestNodes(testNodes); } - void populate(size_t _count = 0) - { - nodeTable->populate(m_testNodes, _count); - } + void populate(size_t _count = 0) { nodeTable->populateTestNodes(testNodes, _count); } KeyPair m_alias; shared_ptr nodeTable; - std::vector> testNodes; + std::vector> testNodes; // keypair and port + std::vector> nodeTables; }; class TestUDPSocket: UDPSocketEvents, public TestHost @@ -141,6 +132,36 @@ public: bool success = false; }; +BOOST_AUTO_TEST_CASE(test_neighbors_packet) +{ + KeyPair k = KeyPair::create(); + std::vector> testNodes(TestNodeTable::createTestNodes()); + bi::udp::endpoint to(boost::asio::ip::address::from_string("127.0.0.1"), 30000); + + Neighbors out(to); + for (auto n: testNodes) + { + Neighbors::Node node; + node.ipAddress = boost::asio::ip::address::from_string("127.0.0.1").to_string(); + node.port = n.second; + node.node = n.first.pub(); + out.nodes.push_back(node); + } + out.sign(k.sec()); + + bytesConstRef packet(out.data.data(), out.data.size()); + bytesConstRef rlpBytes(packet.cropped(97, packet.size() - 97)); + Neighbors in = Neighbors::fromBytesConstRef(to, rlpBytes); + int count = 0; + for (auto n: in.nodes) + { + BOOST_REQUIRE_EQUAL(testNodes[count].second, n.port); + BOOST_REQUIRE_EQUAL(testNodes[count].first.pub(), n.node); + BOOST_REQUIRE_EQUAL(sha3(testNodes[count].first.pub()), sha3(n.node)); + count++; + } +} + BOOST_AUTO_TEST_CASE(test_findnode_neighbors) { // Executing findNode should result in a list which is serialized @@ -154,21 +175,23 @@ BOOST_AUTO_TEST_CASE(kademlia) node.start(); node.nodeTable->join(); // ideally, joining with empty node table logs warning we can check for node.setup(); - node.pingAll(); + node.populate(); + clog << "NodeTable:\n" << *node.nodeTable.get() << endl; + + node.pingAll(); + this_thread::sleep_for(chrono::milliseconds(4000)); clog << "NodeTable:\n" << *node.nodeTable.get() << endl; - this_thread::sleep_for(chrono::milliseconds(10000)); node.nodeTable->reset(); clog << "NodeTable:\n" << *node.nodeTable.get() << endl; node.populate(2); - clog << "NodeTable:\n" << *node.nodeTable.get() << endl; this_thread::sleep_for(chrono::milliseconds(500)); + clog << "NodeTable:\n" << *node.nodeTable.get() << endl; -// node.nodeTable->join(); -// this_thread::sleep_for(chrono::milliseconds(2000)); -// -// clog << "NodeTable:\n" << *node.nodeTable.get() << endl; + node.nodeTable->join(); + this_thread::sleep_for(chrono::milliseconds(2000)); + clog << "NodeTable:\n" << *node.nodeTable.get() << endl; } BOOST_AUTO_TEST_CASE(test_udp_once) From 60f2344b2bbb9efec42469cebf62570dc5068284 Mon Sep 17 00:00:00 2001 From: subtly Date: Fri, 26 Dec 2014 05:38:27 +0100 Subject: [PATCH 15/30] inline << operator, mute logging --- net.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/net.cpp b/net.cpp index 4c45475f3..d9b5d1579 100644 --- a/net.cpp +++ b/net.cpp @@ -53,14 +53,14 @@ struct TestNodeTable: public NodeTable /// Constructor using NodeTable::NodeTable; - static std::vector> createTestNodes(int _count = 16) + static std::vector> createTestNodes(unsigned _count) { std::vector> ret; asserts(_count < 1000); static uint16_t s_basePort = 30500; ret.clear(); - for (auto i = 0; i < _count; i++) + for (unsigned i = 0; i < _count; i++) { KeyPair k = KeyPair::create(); ret.push_back(make_pair(k,s_basePort+i)); @@ -75,7 +75,7 @@ struct TestNodeTable: public NodeTable for (auto& n: _testNodes) { ping(bi::udp::endpoint(ourIp, n.second)); - this_thread::sleep_for(chrono::milliseconds(5)); + this_thread::sleep_for(chrono::milliseconds(2)); } } @@ -104,7 +104,7 @@ struct TestNodeTable: public NodeTable */ struct TestNodeTableHost: public TestHost { - TestNodeTableHost(): m_alias(KeyPair::create()), nodeTable(new TestNodeTable(m_io, m_alias)), testNodes(TestNodeTable::createTestNodes()) {}; + TestNodeTableHost(unsigned _count = 8): m_alias(KeyPair::create()), nodeTable(new TestNodeTable(m_io, m_alias)), testNodes(TestNodeTable::createTestNodes(_count)) {}; ~TestNodeTableHost() { m_io.stop(); stopWorking(); } void setup() { for (auto n: testNodes) nodeTables.push_back(make_shared(m_io,n.first,n.second)); } @@ -135,7 +135,7 @@ public: BOOST_AUTO_TEST_CASE(test_neighbors_packet) { KeyPair k = KeyPair::create(); - std::vector> testNodes(TestNodeTable::createTestNodes()); + std::vector> testNodes(TestNodeTable::createTestNodes(16)); bi::udp::endpoint to(boost::asio::ip::address::from_string("127.0.0.1"), 30000); Neighbors out(to); @@ -171,7 +171,7 @@ BOOST_AUTO_TEST_CASE(test_findnode_neighbors) BOOST_AUTO_TEST_CASE(kademlia) { - TestNodeTableHost node; + TestNodeTableHost node(12); node.start(); node.nodeTable->join(); // ideally, joining with empty node table logs warning we can check for node.setup(); @@ -179,7 +179,7 @@ BOOST_AUTO_TEST_CASE(kademlia) clog << "NodeTable:\n" << *node.nodeTable.get() << endl; node.pingAll(); - this_thread::sleep_for(chrono::milliseconds(4000)); + this_thread::sleep_for(chrono::milliseconds(1000)); clog << "NodeTable:\n" << *node.nodeTable.get() << endl; node.nodeTable->reset(); From 94c1a961d9e7bfc951e10a8a81fc1513c23b9f65 Mon Sep 17 00:00:00 2001 From: subtly Date: Sun, 28 Dec 2014 14:24:21 +0100 Subject: [PATCH 16/30] manually populate nodes for test rather than leveraging ping --- net.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/net.cpp b/net.cpp index d9b5d1579..8a2e2af78 100644 --- a/net.cpp +++ b/net.cpp @@ -111,6 +111,8 @@ struct TestNodeTableHost: public TestHost void pingAll() { for (auto& t: nodeTables) t->pingTestNodes(testNodes); } + void populateAll(size_t _count = 0) { for (auto& t: nodeTables) t->populateTestNodes(testNodes, _count); } + void populate(size_t _count = 0) { nodeTable->populateTestNodes(testNodes, _count); } KeyPair m_alias; @@ -171,22 +173,21 @@ BOOST_AUTO_TEST_CASE(test_findnode_neighbors) BOOST_AUTO_TEST_CASE(kademlia) { - TestNodeTableHost node(12); + // Not yet a 'real' test. + TestNodeTableHost node(8); node.start(); node.nodeTable->join(); // ideally, joining with empty node table logs warning we can check for node.setup(); node.populate(); clog << "NodeTable:\n" << *node.nodeTable.get() << endl; - node.pingAll(); - this_thread::sleep_for(chrono::milliseconds(1000)); + node.populateAll(); clog << "NodeTable:\n" << *node.nodeTable.get() << endl; node.nodeTable->reset(); clog << "NodeTable:\n" << *node.nodeTable.get() << endl; - node.populate(2); - this_thread::sleep_for(chrono::milliseconds(500)); + node.populate(1); clog << "NodeTable:\n" << *node.nodeTable.get() << endl; node.nodeTable->join(); From 96ebead6aa318f496fe5030f0d84236d0c39d3e0 Mon Sep 17 00:00:00 2001 From: subtly Date: Sun, 4 Jan 2015 21:01:56 +0100 Subject: [PATCH 17/30] coding standards, h512 node id, mute warnings for clang builds. attempt inherited constructor fix for windows. --- boostTest.cpp | 4 ++++ net.cpp | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/boostTest.cpp b/boostTest.cpp index 7d89f853c..cef3cc0a7 100644 --- a/boostTest.cpp +++ b/boostTest.cpp @@ -21,4 +21,8 @@ */ #define BOOST_TEST_MODULE EthereumTests +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" #include +#pragma warning(pop) +#pragma GCC diagnostic pop diff --git a/net.cpp b/net.cpp index 8a2e2af78..0a008d6eb 100644 --- a/net.cpp +++ b/net.cpp @@ -171,6 +171,12 @@ BOOST_AUTO_TEST_CASE(test_findnode_neighbors) // into the same list of nearest nodes. } +BOOST_AUTO_TEST_CASE(test_windows_template) +{ + bi::udp::endpoint ep; + PingNode p(ep); +} + BOOST_AUTO_TEST_CASE(kademlia) { // Not yet a 'real' test. From 682c68842ca9ac64fb4908c7de6587bc3c95a130 Mon Sep 17 00:00:00 2001 From: subtly Date: Mon, 5 Jan 2015 22:01:23 +0100 Subject: [PATCH 18/30] code review --- net.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/net.cpp b/net.cpp index 0a008d6eb..6952c282a 100644 --- a/net.cpp +++ b/net.cpp @@ -134,16 +134,16 @@ public: bool success = false; }; -BOOST_AUTO_TEST_CASE(test_neighbors_packet) +BOOST_AUTO_TEST_CASE(test_neighbours_packet) { KeyPair k = KeyPair::create(); std::vector> testNodes(TestNodeTable::createTestNodes(16)); bi::udp::endpoint to(boost::asio::ip::address::from_string("127.0.0.1"), 30000); - Neighbors out(to); + Neighbours out(to); for (auto n: testNodes) { - Neighbors::Node node; + Neighbours::Node node; node.ipAddress = boost::asio::ip::address::from_string("127.0.0.1").to_string(); node.port = n.second; node.node = n.first.pub(); @@ -153,7 +153,7 @@ BOOST_AUTO_TEST_CASE(test_neighbors_packet) bytesConstRef packet(out.data.data(), out.data.size()); bytesConstRef rlpBytes(packet.cropped(97, packet.size() - 97)); - Neighbors in = Neighbors::fromBytesConstRef(to, rlpBytes); + Neighbours in = Neighbours::fromBytesConstRef(to, rlpBytes); int count = 0; for (auto n: in.nodes) { @@ -164,10 +164,10 @@ BOOST_AUTO_TEST_CASE(test_neighbors_packet) } } -BOOST_AUTO_TEST_CASE(test_findnode_neighbors) +BOOST_AUTO_TEST_CASE(test_findnode_neighbours) { // Executing findNode should result in a list which is serialized - // into Neighbors packet. Neighbors packet should then be deserialized + // into Neighbours packet. Neighbours packet should then be deserialized // into the same list of nearest nodes. } From 08837a1d32e21c5c7a86288820667ea905bb9ac4 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Tue, 6 Jan 2015 11:30:52 +0100 Subject: [PATCH 19/30] Blockhash correction and some tests --- vmBlockInfoTestFiller.json | 90 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 87 insertions(+), 3 deletions(-) diff --git a/vmBlockInfoTestFiller.json b/vmBlockInfoTestFiller.json index 1ebedc12b..15c270173 100644 --- a/vmBlockInfoTestFiller.json +++ b/vmBlockInfoTestFiller.json @@ -1,8 +1,8 @@ { - "prevhash": { + "blockhashNotExistingBlock": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", + "currentNumber" : "1", "currentGasLimit" : "1000000", "currentDifficulty" : "256", "currentTimestamp" : 1, @@ -12,7 +12,91 @@ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", "nonce" : 0, - "code" : "{ [[ 0 ]] (PREVHASH) }", + "code" : "{ [[ 0 ]] (BLOCKHASH 2) }", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, + + "blockhashMyBlock": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "1", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ [[ 0 ]] (BLOCKHASH 1) }", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, + + "blockhash258Block": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "258", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ [[ 0 ]] (BLOCKHASH 1) }", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, + + "blockhash257Block": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "257", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ [[ 0 ]] (BLOCKHASH 0) }", "storage": {} } }, From f7a6a06ef55060b57b1ad67a6bcfb5e4a27f4d0e Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Tue, 6 Jan 2015 14:42:37 +0100 Subject: [PATCH 20/30] added more jumpdest tests --- vmIOandFlowOperationsTestFiller.json | 711 ++++++++++++++++++++++++++- 1 file changed, 705 insertions(+), 6 deletions(-) diff --git a/vmIOandFlowOperationsTestFiller.json b/vmIOandFlowOperationsTestFiller.json index dce594e1e..073c8ac80 100644 --- a/vmIOandFlowOperationsTestFiller.json +++ b/vmIOandFlowOperationsTestFiller.json @@ -475,7 +475,7 @@ } }, - "jump0_foreverOutOfGas": { + "jumpAfterStop": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -488,7 +488,7 @@ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", "nonce" : 0, - "code" : "0x600056", + "code" : "0x6006560060015b6002600355", "storage": {} } }, @@ -503,7 +503,175 @@ } }, - "jump0": { + "jumpiAfterStop": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "0x60016008570060015b6002600355", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, + + "jumpInsidePushWithoutJumpDest": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "0x60055661eeff", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, + + "jumpInsidePushWithJumpDest": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "0x600456655b6001600155", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, + + "jumpifInsidePushWithoutJumpDest": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "0x600160075761eeff", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, + + "jumpifInsidePushWithJumpDest": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "0x6001600657655b6001600155", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, + + "jump0_foreverOutOfGas": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "0x5b600056", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, + + "jump0_outOfBoundary": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -558,7 +726,35 @@ } }, - "jump0_jumpdest1": { + "jump0_withoutJumpdest": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "0x60236007566001600255", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, + + "jump0_AfterJumpdest": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -614,7 +810,7 @@ } }, - "jump0_jumpdest3": { + "jump0_AfterJumpdest3": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -754,7 +950,7 @@ } }, - "jumpi2": { + "jumpiOutsideBoundary": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -782,6 +978,509 @@ } }, + "DynamicJumpAfterStop": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "0x6008600101560060015b6002600355", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, + + "DynamicJumpiAfterStop": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "0x60016008600301570060015b6002600355", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, + + "DynamicJumpInsidePushWithoutJumpDest": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "0x60056003015661eeff", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, + + "DynamicJumpInsidePushWithJumpDest": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "0x600460030156655b6001600155", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, + + "DynamicJumpifInsidePushWithoutJumpDest": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "0x600160076003015761eeff", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, + + "DynamicJumpifInsidePushWithJumpDest": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "0x6001600660030157655b6001600155", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, + + "DynamicJump0_foreverOutOfGas": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "0x5b600060000156", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, + + "DyanmicJump0_outOfBoundary": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "0x60236007600301566001600255", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, + "DynamicJump0_jumpdest0": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "0x602360076003015660015b600255", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, + + "DynamicJump0_withoutJumpdest": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "0x60236007600301566001600255", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, + + "DynamicJump0_AfterJumpdest": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "0x602360086003015660015b600255", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, + + "DynamicJump0_jumpdest2": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "0x6023600a6008506003015660015b600255", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, + + "DynamicJump0_AfterJumpdest3": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "0x6023600b6008506003015660015b600255", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, + + "DynamicJump1": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "0x620fffff620fffff0160030156", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, + + "DynamicJumpi0": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "0x602360016009600301576001600255", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, + + "DynamicJumpi1_jumpdest": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "0x60236001600a6003015760015b600255", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, + + "DynamicJumpi1": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "0x602360006009600301576001600255", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, + + "DynamicJumpiOutsideBoundary": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "0x60017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0600301576002600355", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, + "pc0": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", From d6bbdd04641c462a5eb02fba7560af52f55e1926 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Tue, 6 Jan 2015 16:25:21 +0100 Subject: [PATCH 21/30] add zero memory expansion tests --- stSystemOperationsTestFiller.json | 117 ++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) diff --git a/stSystemOperationsTestFiller.json b/stSystemOperationsTestFiller.json index b79066368..47d18b7b1 100644 --- a/stSystemOperationsTestFiller.json +++ b/stSystemOperationsTestFiller.json @@ -33,6 +33,40 @@ } }, + "createNameRegistratorZeroMemExpansion": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ (MSTORE 0 0x601080600c6000396000f30060003554156009570060203560003555) [[ 0 ]] (CREATE 23 0 0) }", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "10000", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + "createNameRegistratorValueTooHigh": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", @@ -177,6 +211,48 @@ } }, + "CallToNameRegistratorZeorSizeMemExpansion": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 1000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 0 0 0) }", + "storage": {} + }, + "945304eb96065b2a98b57a48a06ae28d285a71b5" : { + "balance" : "23", + "code" : "0x60003554156009570060203560003555", + "nonce" : "0", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "", + "storage": {} + } + + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "10000", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + "CallToReturn1": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", @@ -1132,6 +1208,47 @@ } }, + "callcodeToNameRegistratorZeroMemExpanion": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALLCODE 1000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 0 0 0) }", + "storage": {} + }, + "945304eb96065b2a98b57a48a06ae28d285a71b5" : { + "balance" : "23", + "code" : "0x60003554156009570060203560003555", + "nonce" : "0", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "1000000", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + "TestNameRegistrator": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", From 9df47617b9b3469838a3706ca20e0ab40e4888ac Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Tue, 6 Jan 2015 16:32:01 +0100 Subject: [PATCH 22/30] add zero memory expansion tests for vm --- vmEnvironmentalInfoTestFiller.json | 94 +++++++++++++++++++++++++++++- 1 file changed, 92 insertions(+), 2 deletions(-) diff --git a/vmEnvironmentalInfoTestFiller.json b/vmEnvironmentalInfoTestFiller.json index abeed9945..91b09cd33 100644 --- a/vmEnvironmentalInfoTestFiller.json +++ b/vmEnvironmentalInfoTestFiller.json @@ -478,6 +478,34 @@ } }, + "calldatacopyZeroMemExpansion": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ (CALLDATACOPY 0 0 0 ) [[ 0 ]] @0}", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "0x1234567890abcdef01234567890abcdef", + "gasPrice" : "1000000000", + "gas" : "100000000000" + } + }, + "calldatacopy_DataIndexTooHigh": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", @@ -674,7 +702,7 @@ } }, - "codecopy1": { + "codecopy0": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -687,7 +715,35 @@ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", "nonce" : 0, - "code" : "{ (CODECOPY 0 0 (CODESIZE) ) [[ 0 ]] @0 }", + "code" : "{ (CODECOPY 0 0 5 ) [[ 0 ]] @0 }", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "0x1234567890abcdef01234567890abcdef", + "gasPrice" : "1000000000", + "gas" : "100000000000" + } + }, + + "codecopyZeroMemExpansion": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ (CODECOPY 0 0 0 ) [[ 0 ]] @0 }", "storage": {} } }, @@ -825,6 +881,40 @@ } }, + "extcodecopyZeroMemExpansion": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ (EXTCODECOPY (CALLER) 0 0 0 ) ) [[ 0 ]] @0 }", + "storage": {} + }, + "cd1722f3947def4cf144679da39c4c32bdc35681" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ [[ 0 ]] 5 }", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "0x1234567890abcdef01234567890abcdef", + "gasPrice" : "123456789", + "gas" : "100000000000" + } + }, + "extcodecopy0": { "env" : { From 2cf2af356bbb22d15ceee5df1a9d27af0a4036cc Mon Sep 17 00:00:00 2001 From: subtly Date: Tue, 6 Jan 2015 16:51:10 +0100 Subject: [PATCH 23/30] define constructors for windows --- net.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net.cpp b/net.cpp index 6952c282a..946995130 100644 --- a/net.cpp +++ b/net.cpp @@ -51,7 +51,7 @@ protected: struct TestNodeTable: public NodeTable { /// Constructor - using NodeTable::NodeTable; + TestNodeTable(ba::io_service& _io, KeyPair _alias, uint16_t _port = 30300): NodeTable(_io, _alias, _port) {} static std::vector> createTestNodes(unsigned _count) { From ecf3c0bb324b328b562408a5605aa33c6bfca9f4 Mon Sep 17 00:00:00 2001 From: subtly Date: Tue, 6 Jan 2015 17:01:17 +0100 Subject: [PATCH 24/30] stl sleep_for, for windows --- net.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net.cpp b/net.cpp index 946995130..67c50dae8 100644 --- a/net.cpp +++ b/net.cpp @@ -206,7 +206,7 @@ BOOST_AUTO_TEST_CASE(test_udp_once) UDPDatagram d(bi::udp::endpoint(boost::asio::ip::address::from_string("127.0.0.1"), 30300), bytes({65,65,65,65})); TestUDPSocket a; a.m_socket->connect(); a.start(); a.m_socket->send(d); - sleep(1); + this_thread::sleep_for(chrono::seconds(1)); BOOST_REQUIRE_EQUAL(true, a.success); } From a8d472f5ab83cc7e11cf838e335b8b26f658927b Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Tue, 6 Jan 2015 20:57:33 +0100 Subject: [PATCH 25/30] Blockhash tests --- stBlockHashTestFiller.json | 103 +++++++++++++++++++++++++++++++++++++ state.cpp | 15 +++++- 2 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 stBlockHashTestFiller.json diff --git a/stBlockHashTestFiller.json b/stBlockHashTestFiller.json new file mode 100644 index 000000000..ccbff5d21 --- /dev/null +++ b/stBlockHashTestFiller.json @@ -0,0 +1,103 @@ +{ + "blockhash0" : { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "5", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ [[ 0 ]] (BLOCKHASH 0) [[ 1 ]] (BLOCKHASH 5) [[ 2 ]] (BLOCKHASH 4) }", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "100000", + "nonce" : 0, + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "8500", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "blockhashOutOfRange" : { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "257", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ [[ 0 ]] (BLOCKHASH 0) [[ 1 ]] (BLOCKHASH 257) [[ 2 ]] (BLOCKHASH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) }", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "100000", + "nonce" : 0, + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "8500", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "blockhashInRange" : { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "257", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ [[ 0 ]] (BLOCKHASH 1) [[ 1 ]] (BLOCKHASH 2) [[ 2 ]] (BLOCKHASH 256) }", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "100000", + "nonce" : 0, + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "8500", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + } +} diff --git a/state.cpp b/state.cpp index 133468226..db8350e42 100644 --- a/state.cpp +++ b/state.cpp @@ -39,6 +39,14 @@ using namespace dev::eth; namespace dev { namespace test { +LastHashes lastHashes(u256 _currentBlockNumber) +{ + LastHashes ret; + for (u256 i = 1; i <= 256 && i <= _currentBlockNumber; ++i) + ret.push_back(sha3(toString(_currentBlockNumber - i))); + return ret; +} + void doStateTests(json_spirit::mValue& v, bool _fillin) @@ -62,7 +70,7 @@ void doStateTests(json_spirit::mValue& v, bool _fillin) try { - theState.execute(LastHashes(), tx, &output); + theState.execute(lastHashes(importer.m_environment.currentBlock.number), tx, &output); } catch (Exception const& _e) { @@ -157,6 +165,11 @@ BOOST_AUTO_TEST_CASE(stRefundTest) dev::test::executeTests("stRefundTest", "/StateTests", dev::test::doStateTests); } +BOOST_AUTO_TEST_CASE(stBlockHashTest) +{ + dev::test::executeTests("stBlockHashTest", "/StateTests", dev::test::doStateTests); +} + BOOST_AUTO_TEST_CASE(stCreateTest) { for (int i = 1; i < boost::unit_test::framework::master_test_suite().argc; ++i) From 8f61058567329d90bd99dacb1089464a53274d9d Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Wed, 7 Jan 2015 11:14:45 +0100 Subject: [PATCH 26/30] check address input greater then 2**160 --- stSystemOperationsTestFiller.json | 300 +++++++++++++++++++++++++++-- vmEnvironmentalInfoTestFiller.json | 210 ++++++++++++++++++++ 2 files changed, 494 insertions(+), 16 deletions(-) diff --git a/stSystemOperationsTestFiller.json b/stSystemOperationsTestFiller.json index 47d18b7b1..70ce448fc 100644 --- a/stSystemOperationsTestFiller.json +++ b/stSystemOperationsTestFiller.json @@ -12,7 +12,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", "nonce" : 0, - "code" : "{ (MSTORE 0 0x601080600c6000396000f30060003554156009570060203560003555) [[ 0 ]] (CREATE 23 4 28) }", + "code" : "{ (MSTORE 0 0x601080600c6000396000f3006000355415600957005b60203560003555) [[ 0 ]] (CREATE 23 3 29) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -46,7 +46,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", "nonce" : 0, - "code" : "{ (MSTORE 0 0x601080600c6000396000f30060003554156009570060203560003555) [[ 0 ]] (CREATE 23 0 0) }", + "code" : "{ (MSTORE 0 0x601080600c6000396000f3006000355415600957005b60203560003555) [[ 0 ]] (CREATE 23 0 0) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -80,7 +80,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", "nonce" : 0, - "code" : "{ (MSTORE 0 0x601080600c6000396000f30060003554156009570060203560003555) [[ 0 ]] (CREATE 1000 4 28) }", + "code" : "{ (MSTORE 0 0x601080600c6000396000f3006000355415600957005b60203560003555) [[ 0 ]] (CREATE 1000 3 29) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -114,7 +114,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", "nonce" : 0, - "code" : "{ (MSTORE 0 0x601080600c6000396000f30060003554156009570060203560003555) [[ 0 ]] (CREATE 23 0xfffffffffff 28) }", + "code" : "{ (MSTORE 0 0x601080600c6000396000f3006000355415600957005b60203560003555) [[ 0 ]] (CREATE 23 0xfffffffffff 29) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -148,7 +148,41 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", "nonce" : 0, - "code" : "{ (MSTORE 0 0x601080600c6000396000f30060003554156009570060203560003555) [[ 0 ]] (CREATE 23 4 0xfffffffffff) }", + "code" : "{ (MSTORE 0 0x601080600c6000396000f3006000355415600957005b60203560003555) [[ 0 ]] (CREATE 23 3 0xfffffffffff) }", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "10000", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "balanceInputAddressTooBig": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ [[ 0 ]] (BALANCE 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0baa ) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -187,7 +221,91 @@ }, "945304eb96065b2a98b57a48a06ae28d285a71b5" : { "balance" : "23", - "code" : "0x60003554156009570060203560003555", + "code" : "0x6000355415600957005b60203560003555", + "nonce" : "0", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "", + "storage": {} + } + + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "10000", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CallToNameRegistratorAddressTooBigLeft": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 1000 0xaa945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 64 64 0) }", + "storage": {} + }, + "945304eb96065b2a98b57a48a06ae28d285a71b5" : { + "balance" : "23", + "code" : "0x6000355415600957005b60203560003555", + "nonce" : "0", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "", + "storage": {} + } + + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "10000", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CallToNameRegistratorAddressTooBigRight": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 1000 0x945304eb96065b2a98b57a48a06ae28d285a71b5aa 23 0 64 64 0) }", + "storage": {} + }, + "945304eb96065b2a98b57a48a06ae28d285a71b5" : { + "balance" : "23", + "code" : "0x6000355415600957005b60203560003555", "nonce" : "0", "storage" : { } @@ -229,7 +347,7 @@ }, "945304eb96065b2a98b57a48a06ae28d285a71b5" : { "balance" : "23", - "code" : "0x60003554156009570060203560003555", + "code" : "0x6000355415600957005b60203560003555", "nonce" : "0", "storage" : { } @@ -440,7 +558,7 @@ }, "945304eb96065b2a98b57a48a06ae28d285a71b5" : { "balance" : "23", - "code" : "0x60003554156009570060203560003555", + "code" : "0x6000355415600957005b60203560003555", "nonce" : "0", "storage" : { } @@ -482,7 +600,7 @@ }, "945304eb96065b2a98b57a48a06ae28d285a71b5" : { "balance" : "23", - "code" : "0x60003554156009570060203560003555", + "code" : "0x6000355415600957005b60203560003555", "nonce" : "0", "storage" : { } @@ -523,7 +641,7 @@ }, "945304eb96065b2a98b57a48a06ae28d285a71b5" : { "balance" : "23", - "code" : "0x60003554156009570060203560003555", + "code" : "0x6000355415600957005b60203560003555", "nonce" : "0", "storage" : { } @@ -564,7 +682,7 @@ }, "945304eb96065b2a98b57a48a06ae28d285a71b5" : { "balance" : "23", - "code" : "0x60003554156009570060203560003555", + "code" : "0x6000355415600957005b60203560003555", "nonce" : "0", "storage" : { } @@ -606,7 +724,7 @@ }, "945304eb96065b2a98b57a48a06ae28d285a71b5" : { "balance" : "23", - "code" : "0x60003554156009570060203560003555", + "code" : "0x6000355415600957005b60203560003555", "nonce" : "0", "storage" : { } @@ -647,7 +765,7 @@ }, "945304eb96065b2a98b57a48a06ae28d285a71b5" : { "balance" : "23", - "code" : "0x60003554156009570060203560003555", + "code" : "0x6000355415600957005b60203560003555", "nonce" : "0", "storage" : { } @@ -926,6 +1044,74 @@ } }, + "suicideCallerAddresTooBigLeft": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ [[0]] (CALLER) (SUICIDE 0xaaa94f5374fce5edbc8e2a8697c15331677e6ebf0b)}", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "1000000", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "suicideCallerAddresTooBigRight": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ [[0]] (CALLER) (SUICIDE 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0baa)}", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "1000000", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + "suicideOrigin": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", @@ -1185,7 +1371,7 @@ }, "945304eb96065b2a98b57a48a06ae28d285a71b5" : { "balance" : "23", - "code" : "0x60003554156009570060203560003555", + "code" : "0x6000355415600957005b60203560003555", "nonce" : "0", "storage" : { } @@ -1208,6 +1394,88 @@ } }, + "callcodeToNameRegistratorAddresTooBigLeft": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALLCODE 1000 0xaa945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 64 64 0) }", + "storage": {} + }, + "945304eb96065b2a98b57a48a06ae28d285a71b5" : { + "balance" : "23", + "code" : "0x6000355415600957005b60203560003555", + "nonce" : "0", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "1000000", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "callcodeToNameRegistratorAddresTooBigRight": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALLCODE 1000 0x945304eb96065b2a98b57a48a06ae28d285a71b5aa 23 0 64 64 0) }", + "storage": {} + }, + "945304eb96065b2a98b57a48a06ae28d285a71b5" : { + "balance" : "23", + "code" : "0x6000355415600957005b60203560003555", + "nonce" : "0", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "1000000", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + "callcodeToNameRegistratorZeroMemExpanion": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", @@ -1226,7 +1494,7 @@ }, "945304eb96065b2a98b57a48a06ae28d285a71b5" : { "balance" : "23", - "code" : "0x60003554156009570060203560003555", + "code" : "0x6000355415600957005b60203560003555", "nonce" : "0", "storage" : { } @@ -1262,7 +1530,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", "nonce" : 0, - "code" : "0x60003554156009570060203560003555", + "code" : "0x6000355415600957005b60203560003555", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { diff --git a/vmEnvironmentalInfoTestFiller.json b/vmEnvironmentalInfoTestFiller.json index 91b09cd33..43f4706cb 100644 --- a/vmEnvironmentalInfoTestFiller.json +++ b/vmEnvironmentalInfoTestFiller.json @@ -83,6 +83,91 @@ } }, + "balanceAddressInputTooBig": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ [[ 0 ]] (BALANCE 0xcd1722f3947def4cf144679da39c4c32bdc35681aa )}", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "1000000000", + "gas" : "100000000000" + } + }, + + "balanceAddressInputTooBigRightMyAddress": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ [[ 0 ]] (BALANCE 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6aa )}", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "1000000000", + "gas" : "100000000000" + } + }, + + "balanceAddressInputTooBigLeftMyAddress": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ [[ 0 ]] (BALANCE 0xaa0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 )}", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "1000000000", + "gas" : "100000000000" + } + }, + + "balance1": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", @@ -786,6 +871,63 @@ } }, + "ExtCodeSizeAddressInputTooBigRightMyAddress": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ [[ 0 ]] (EXTCODESIZE 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6aa )}", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "1000000000", + "gas" : "100000000000" + } + }, + + "ExtCodeSizeAddressInputTooBigLeftMyAddress": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ [[ 0 ]] (EXTCODESIZE 0xaa0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 )}", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "1000000000", + "gas" : "100000000000" + } + }, + + "extcodesize0": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", @@ -948,6 +1090,74 @@ "gasPrice" : "123456789", "gas" : "100000000000" } + }, + + "extcodecopy0AddressTooBigLeft": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ (EXTCODECOPY 0xaacd1722f3947def4cf144679da39c4c32bdc35681 0 0 (EXTCODESIZE (CALLER) ) ) [[ 0 ]] @0 }", + "storage": {} + }, + "cd1722f3947def4cf144679da39c4c32bdc35681" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ [[ 0 ]] 5 }", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "0x1234567890abcdef01234567890abcdef", + "gasPrice" : "123456789", + "gas" : "100000000000" + } + }, + + "extcodecopy0AddressTooBigRight": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ (EXTCODECOPY 0xcd1722f3947def4cf144679da39c4c32bdc35681aa 0 0 (EXTCODESIZE (CALLER) ) ) [[ 0 ]] @0 }", + "storage": {} + }, + "cd1722f3947def4cf144679da39c4c32bdc35681" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ [[ 0 ]] 5 }", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "0x1234567890abcdef01234567890abcdef", + "gasPrice" : "123456789", + "gas" : "100000000000" + } } } From 8c0a3dc16e4304880fc01ee746ca2bc54ef7d750 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Wed, 7 Jan 2015 12:14:33 +0100 Subject: [PATCH 27/30] memory test: high offset, zero size -> zero gas cost --- stSystemOperationsTestFiller.json | 69 +++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/stSystemOperationsTestFiller.json b/stSystemOperationsTestFiller.json index 70ce448fc..757c8a235 100644 --- a/stSystemOperationsTestFiller.json +++ b/stSystemOperationsTestFiller.json @@ -33,6 +33,75 @@ } }, + "createNameRegistratorZeroMem": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ (MSTORE 0 0x601080600c6000396000f3006000355415600957005b60203560003555) [[ 0 ]] (CREATE 23 3 0) }", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "10000", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "createNameRegistratorZeroMem2": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ (MSTORE 0 0x601080600c6000396000f3006000355415600957005b60203560003555) [[ 0 ]] (CREATE 23 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0) }", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "10000", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "createNameRegistratorZeroMemExpansion": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", From fc60f0f5867c02430137f30f3ffba5758dd64ecb Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Wed, 7 Jan 2015 12:36:15 +0100 Subject: [PATCH 28/30] jump onto jump, dynamic and static jump with same destination --- vmIOandFlowOperationsTestFiller.json | 56 ++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/vmIOandFlowOperationsTestFiller.json b/vmIOandFlowOperationsTestFiller.json index 073c8ac80..efbd0d683 100644 --- a/vmIOandFlowOperationsTestFiller.json +++ b/vmIOandFlowOperationsTestFiller.json @@ -671,6 +671,62 @@ } }, + "jumpOntoJump": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "0x565b600056", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, + + "jumpDynamicJumpSameDest": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "0x6002600401565b600360005260206000f3600656", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, + "jump0_outOfBoundary": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", From a6b0376e25b39e18f528b7d77ee3c45f54661ef1 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Wed, 7 Jan 2015 15:37:00 +0100 Subject: [PATCH 29/30] add tests for OOG at max call depth --- stSystemOperationsTestFiller.json | 110 ++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) diff --git a/stSystemOperationsTestFiller.json b/stSystemOperationsTestFiller.json index 757c8a235..12f10fde5 100644 --- a/stSystemOperationsTestFiller.json +++ b/stSystemOperationsTestFiller.json @@ -33,6 +33,40 @@ } }, + "createNameRegistratorOOG_MemExpansionInsufficientBalance": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "10000", + "nonce" : 0, + "code" : "{ (MSTORE 0 0x601080600c6000396000f3006000355415600957005b60203560003555) [[ 0 ]] (CREATE 11000 3 0xffffffffffffffffffffff) }", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "10000", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + "createNameRegistratorZeroMem": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", @@ -314,6 +348,48 @@ } }, + "CallToNameRegistratorMemOOGAndInsufficientBalance": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 0xffffffffff 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 0xffffffffffff 64 0) }", + "storage": {} + }, + "945304eb96065b2a98b57a48a06ae28d285a71b5" : { + "balance" : "23", + "code" : "0x6000355415600957005b60203560003555", + "nonce" : "0", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "", + "storage": {} + } + + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "10000", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + "CallToNameRegistratorAddressTooBigLeft": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", @@ -977,6 +1053,40 @@ } }, + "CallRecursiveBomb0_OOG_atMaxCallDepth": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : 0, + "code" : "{ [[ 0 ]] (+ (SLOAD 0) 1) [[ 2 ]] (MUL (DIV @@0 0x0402) 0xfffffffffffffffffff) [[ 1 ]] (CALL (- (GAS) 1024) (ADDRESS) 0 0 (MUL (DIV @@0 0x0402) 0xfffffffffffffffffff) 0 0) } ", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "1000000000", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + "CallRecursiveBomb1": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", From 646f99d34ae42d1fe17590c850e7f1cf999ea8b8 Mon Sep 17 00:00:00 2001 From: Christian Date: Wed, 7 Jan 2015 15:41:11 +0100 Subject: [PATCH 30/30] Some changes to the optimizer. --- SolidityOptimizer.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/SolidityOptimizer.cpp b/SolidityOptimizer.cpp index ef5c6f9b5..7e06c2e30 100644 --- a/SolidityOptimizer.cpp +++ b/SolidityOptimizer.cpp @@ -48,7 +48,7 @@ public: m_optimize = true; bytes optimizedBytecode = compileAndRun(_sourceCode, _value, _contractName); int sizeDiff = nonOptimizedBytecode.size() - optimizedBytecode.size(); - BOOST_CHECK_MESSAGE(sizeDiff == int(_expectedSizeDecrease), "Bytecode did only shrink by " + BOOST_CHECK_MESSAGE(sizeDiff == int(_expectedSizeDecrease), "Bytecode shrank by " + boost::lexical_cast(sizeDiff) + " bytes, expected: " + boost::lexical_cast(_expectedSizeDecrease)); m_optimizedContract = m_contractAddress; @@ -91,10 +91,10 @@ BOOST_AUTO_TEST_CASE(large_integers) contract test { function f() returns (uint a, uint b) { a = 0x234234872642837426347000000; - b = 0x110000000000000000000000002; + b = 0x10000000000000000000000002; } })"; - compileBothVersions(28, sourceCode); + compileBothVersions(33, sourceCode); compareVersions(0); } @@ -102,8 +102,8 @@ BOOST_AUTO_TEST_CASE(invariants) { char const* sourceCode = R"( contract test { - function f(uint a) returns (uint b) { - return (((a + (1 - 1)) ^ 0) | 0) & (uint(0) - 1); + function f(int a) returns (int b) { + return int(0) | (int(1) * (int(0) ^ (0 + a))); } })"; compileBothVersions(28, sourceCode); @@ -127,8 +127,8 @@ BOOST_AUTO_TEST_CASE(unused_expressions) BOOST_AUTO_TEST_CASE(constant_folding_both_sides) { // if constants involving the same associative and commutative operator are applied from both - // sides, the operator should be applied only once, because the expression compiler - // (even in non-optimized mode) pushes literals as late as possible + // sides, the operator should be applied only once, because the expression compiler pushes + // literals as late as possible char const* sourceCode = R"( contract test { function f(uint x) returns (uint y) {