From 5436f90f04d1ec6a81f1fe90f57a8385e9e8635d Mon Sep 17 00:00:00 2001 From: subtly Date: Mon, 5 Jan 2015 00:49:16 +0100 Subject: [PATCH 001/213] Pass 1 integrating node table. TBD: whether to store/relay cap info. --- libp2p/Host.cpp | 202 +++++++++++++++++++++++-------------------- libp2p/Host.h | 66 +++++++++----- libp2p/NodeTable.cpp | 19 ++-- libp2p/NodeTable.h | 92 +++++++++++--------- libp2p/Session.cpp | 2 +- libp2p/Session.h | 6 +- libp2p/UDP.h | 2 - 7 files changed, 214 insertions(+), 175 deletions(-) diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index 4a99ac90f..73fabe7f2 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -44,7 +44,8 @@ Host::Host(std::string const& _clientVersion, NetworkPreferences const& _n, bool m_ifAddresses(Network::getInterfaceAddresses()), m_ioService(2), m_tcp4Acceptor(m_ioService), - m_key(KeyPair::create()) + m_key(KeyPair::create()), + m_nodeTable(new NodeTable(m_ioService, m_key)) { for (auto address: m_ifAddresses) if (address.is_v4()) @@ -143,11 +144,12 @@ void Host::doneWorking() unsigned Host::protocolVersion() const { - return 2; + return 3; } void Host::registerPeer(std::shared_ptr _s, CapDescs const& _caps) { +#warning integration: todo rework so this is an exception if (!_s->m_node || !_s->m_node->id) { cwarn << "Attempting to register a peer without node information!"; @@ -180,7 +182,8 @@ void Host::seal(bytes& _b) _b[7] = len & 0xff; } -shared_ptr Host::noteNode(NodeId _id, bi::tcp::endpoint _a, Origin _o, bool _ready, NodeId _oldId) +#warning integration: todo remove origin, ready, oldid. port to NodeTable. see Session.cpp#244,363 +shared_ptr Host::noteNode(NodeId _id, bi::tcp::endpoint _a, Origin _o, bool _ready, NodeId _oldId) { RecursiveGuard l(x_peers); if (_a.port() < 30300 || _a.port() > 30305) @@ -192,11 +195,11 @@ shared_ptr Host::noteNode(NodeId _id, bi::tcp::endpoint _a, Origin _o, boo _a = bi::tcp::endpoint(_a.address(), 0); } -// cnote << "Node:" << _id.abridged() << _a << (_ready ? "ready" : "used") << _oldId.abridged() << (m_nodes.count(_id) ? "[have]" : "[NEW]"); +// cnote << "NodeInfo:" << _id.abridged() << _a << (_ready ? "ready" : "used") << _oldId.abridged() << (m_nodes.count(_id) ? "[have]" : "[NEW]"); // First check for another node with the same connection credentials, and put it in oldId if found. if (!_oldId) - for (pair> const& n: m_nodes) + for (pair> const& n: m_nodes) if (n.second->address == _a && n.second->id != _id) { _oldId = n.second->id; @@ -217,7 +220,7 @@ shared_ptr Host::noteNode(NodeId _id, bi::tcp::endpoint _a, Origin _o, boo i = m_nodesList.size(); m_nodesList.push_back(_id); } - m_nodes[_id] = make_shared(); + m_nodes[_id] = make_shared(); m_nodes[_id]->id = _id; m_nodes[_id]->index = i; m_nodes[_id]->idOrigin = _o; @@ -246,6 +249,7 @@ shared_ptr Host::noteNode(NodeId _id, bi::tcp::endpoint _a, Origin _o, boo return m_nodes[_id]; } +#warning integration: TBD caps in NodeTable/NodeEntry Nodes Host::potentialPeers(RangeMask const& _known) { RecursiveGuard l(x_peers); @@ -376,6 +380,7 @@ string Host::pocHost() return "poc-" + strs[1] + ".ethdev.com"; } +#warning integration: todo remove all connect() w/ addNode makeRequired (this requires pubkey) void Host::connect(std::string const& _addr, unsigned short _port) noexcept { if (!m_run) @@ -428,13 +433,13 @@ void Host::connect(bi::tcp::endpoint const& _ep) }); } -void Host::connect(std::shared_ptr const& _n) +void Host::connect(std::shared_ptr const& _n) { if (!m_run) return; // prevent concurrently connecting to a node; todo: better abstraction - Node *nptr = _n.get(); + NodeInfo *nptr = _n.get(); { Guard l(x_pendingNodeConns); if (m_pendingNodeConns.count(nptr)) @@ -488,7 +493,7 @@ bool Host::havePeer(NodeId _id) const return !!m_peers.count(_id); } -unsigned Node::fallbackSeconds() const +unsigned NodeInfo::fallbackSeconds() const { switch (lastDisconnect) { @@ -510,85 +515,83 @@ unsigned Node::fallbackSeconds() const } } -bool Node::shouldReconnect() const -{ - return chrono::system_clock::now() > lastAttempted + chrono::seconds(fallbackSeconds()); -} - -void Host::growPeers() -{ - RecursiveGuard l(x_peers); - int morePeers = (int)m_idealPeerCount - m_peers.size(); - if (morePeers > 0) - { - auto toTry = m_ready; - if (!m_netPrefs.localNetworking) - toTry -= m_private; - set ns; - for (auto i: toTry) - if (m_nodes[m_nodesList[i]]->shouldReconnect()) - ns.insert(*m_nodes[m_nodesList[i]]); - - if (ns.size()) - for (Node const& i: ns) - { - connect(m_nodes[i.id]); - if (!--morePeers) - return; - } - else - for (auto const& i: m_peers) - if (auto p = i.second.lock()) - p->ensureNodesRequested(); - } -} - -void Host::prunePeers() -{ - RecursiveGuard l(x_peers); - // We'll keep at most twice as many as is ideal, halfing what counts as "too young to kill" until we get there. - set dc; - for (unsigned old = 15000; m_peers.size() - dc.size() > m_idealPeerCount * 2 && old > 100; old /= 2) - if (m_peers.size() - dc.size() > m_idealPeerCount) - { - // look for worst peer to kick off - // first work out how many are old enough to kick off. - shared_ptr worst; - unsigned agedPeers = 0; - for (auto i: m_peers) - if (!dc.count(i.first)) - if (auto p = i.second.lock()) - if (/*(m_mode != NodeMode::Host || p->m_caps != 0x01) &&*/ chrono::steady_clock::now() > p->m_connect + chrono::milliseconds(old)) // don't throw off new peers; peer-servers should never kick off other peer-servers. - { - ++agedPeers; - if ((!worst || p->rating() < worst->rating() || (p->rating() == worst->rating() && p->m_connect > worst->m_connect))) // kill older ones - worst = p; - } - if (!worst || agedPeers <= m_idealPeerCount) - break; - dc.insert(worst->id()); - worst->disconnect(TooManyPeers); - } - - // Remove dead peers from list. - for (auto i = m_peers.begin(); i != m_peers.end();) - if (i->second.lock().get()) - ++i; - else - i = m_peers.erase(i); -} - -PeerInfos Host::peers(bool _updatePing) const +#warning integration: ---- grow/prunePeers +#warning integration: todo grow/prune into 'maintainPeers' & evaluate reputation instead of availability. schedule via deadline timer. +//void Host::growPeers() +//{ +// RecursiveGuard l(x_peers); +// int morePeers = (int)m_idealPeerCount - m_peers.size(); +// if (morePeers > 0) +// { +// auto toTry = m_ready; +// if (!m_netPrefs.localNetworking) +// toTry -= m_private; +// set ns; +// for (auto i: toTry) +// if (m_nodes[m_nodesList[i]]->shouldReconnect()) +// ns.insert(*m_nodes[m_nodesList[i]]); +// +// if (ns.size()) +// for (NodeInfo const& i: ns) +// { +// connect(m_nodes[i.id]); +// if (!--morePeers) +// return; +// } +// else +// for (auto const& i: m_peers) +// if (auto p = i.second.lock()) +// p->ensureNodesRequested(); +// } +//} +// +//void Host::prunePeers() +//{ +// RecursiveGuard l(x_peers); +// // We'll keep at most twice as many as is ideal, halfing what counts as "too young to kill" until we get there. +// set dc; +// for (unsigned old = 15000; m_peers.size() - dc.size() > m_idealPeerCount * 2 && old > 100; old /= 2) +// if (m_peers.size() - dc.size() > m_idealPeerCount) +// { +// // look for worst peer to kick off +// // first work out how many are old enough to kick off. +// shared_ptr worst; +// unsigned agedPeers = 0; +// for (auto i: m_peers) +// if (!dc.count(i.first)) +// if (auto p = i.second.lock()) +// if (/*(m_mode != NodeMode::Host || p->m_caps != 0x01) &&*/ chrono::steady_clock::now() > p->m_connect + chrono::milliseconds(old)) // don't throw off new peers; peer-servers should never kick off other peer-servers. +// { +// ++agedPeers; +// if ((!worst || p->rating() < worst->rating() || (p->rating() == worst->rating() && p->m_connect > worst->m_connect))) // kill older ones +// worst = p; +// } +// if (!worst || agedPeers <= m_idealPeerCount) +// break; +// dc.insert(worst->id()); +// worst->disconnect(TooManyPeers); +// } +// +// // Remove dead peers from list. +// for (auto i = m_peers.begin(); i != m_peers.end();) +// if (i->second.lock().get()) +// ++i; +// else +// i = m_peers.erase(i); +//} + +PeerInfos Host::peers() const { if (!m_run) return PeerInfos(); +#warning integration: ---- pingAll. It is called every 30secs via deadline timer. RecursiveGuard l(x_peers); - if (_updatePing) - { - const_cast(this)->pingAll(); - this_thread::sleep_for(chrono::milliseconds(200)); - } +// if (_updatePing) +// { +// const_cast(this)->pingAll(); +// this_thread::sleep_for(chrono::milliseconds(200)); +// } std::vector ret; for (auto& i: m_peers) if (auto j = i.second.lock()) @@ -610,13 +613,14 @@ void Host::run(boost::system::error_code const&) return; } - m_lastTick += c_timerInterval; - if (m_lastTick >= c_timerInterval * 10) - { - growPeers(); - prunePeers(); - m_lastTick = 0; - } +#warning integration: ---- +// m_lastTick += c_timerInterval; +// if (m_lastTick >= c_timerInterval * 10) +// { +// growPeers(); +// prunePeers(); +// m_lastTick = 0; +// } if (m_hadNewNodes) { @@ -670,12 +674,19 @@ void Host::startedWorking() if (m_listenPort > 0) runAcceptor(); + +#warning integration: ++++ + if (!m_tcpPublic.address().is_unspecified()) + m_nodeTable.reset(new NodeTable(m_ioService, m_key, m_listenPort, m_tcpPublic)); + else + m_nodeTable.reset(new NodeTable(m_ioService, m_key, m_listenPort > 0 ? m_listenPort : 30303)); } - // if m_public address is valid then add us to node list - // todo: abstract empty() and emplace logic - if (!m_tcpPublic.address().is_unspecified() && (m_nodes.empty() || m_nodes[m_nodesList[0]]->id != id())) - noteNode(id(), m_tcpPublic, Origin::Perfect, false); +#warning integration: ---- +// // if m_public address is valid then add us to node list +// // todo: abstract empty() and emplace logic +// if (!m_tcpPublic.address().is_unspecified() && (m_nodes.empty() || m_nodes[m_nodesList[0]]->id != id())) +// noteNode(id(), m_tcpPublic, Origin::Perfect, false); clog(NetNote) << "Id:" << id().abridged(); @@ -697,6 +708,7 @@ void Host::pingAll() m_lastPing = chrono::steady_clock::now(); } +#warning integration: todo save/restoreNodes bytes Host::saveNodes() const { RLPStream nodes; @@ -705,7 +717,7 @@ bytes Host::saveNodes() const RecursiveGuard l(x_peers); for (auto const& i: m_nodes) { - Node const& n = *(i.second); + NodeInfo const& n = *(i.second); // TODO: PoC-7: Figure out why it ever shares these ports.//n.address.port() >= 30300 && n.address.port() <= 30305 && if (!n.dead && chrono::system_clock::now() - n.lastConnected < chrono::seconds(3600 * 48) && n.address.port() > 0 && n.address.port() < /*49152*/32768 && n.id != id() && !isPrivateAddress(n.address.address())) { diff --git a/libp2p/Host.h b/libp2p/Host.h index 8ed25f2ae..9600c723b 100644 --- a/libp2p/Host.h +++ b/libp2p/Host.h @@ -34,6 +34,7 @@ #include #include #include +#include "NodeTable.h" #include "HostCapability.h" #include "Network.h" #include "Common.h" @@ -59,29 +60,47 @@ enum class Origin Perfect, }; -struct Node +struct NodeInfo { NodeId id; ///< Their id/public key. unsigned index; ///< Index into m_nodesList + + // p2p: move to NodeEndpoint bi::tcp::endpoint address; ///< As reported from the node itself. - int score = 0; ///< All time cumulative. - int rating = 0; ///< Trending. - bool dead = false; ///< If true, we believe this node is permanently dead - forget all about it. + + // p2p: This information is relevant to the network-stack, ex: firewall, rather than node itself std::chrono::system_clock::time_point lastConnected; std::chrono::system_clock::time_point lastAttempted; unsigned failedAttempts = 0; DisconnectReason lastDisconnect = NoDisconnect; ///< Reason for disconnect that happened last. + // p2p: just remove node + // p2p: revisit logic in see Session.cpp#210 + bool dead = false; ///< If true, we believe this node is permanently dead - forget all about it. + + // p2p: move to protocol-specific map + int score = 0; ///< All time cumulative. + int rating = 0; ///< Trending. + + // p2p: remove Origin idOrigin = Origin::Unknown; ///< How did we get to know this node's id? + // p2p: move to NodeEndpoint int secondsSinceLastConnected() const { return lastConnected == std::chrono::system_clock::time_point() ? -1 : (int)std::chrono::duration_cast(std::chrono::system_clock::now() - lastConnected).count(); } + // p2p: move to NodeEndpoint int secondsSinceLastAttempted() const { return lastAttempted == std::chrono::system_clock::time_point() ? -1 : (int)std::chrono::duration_cast(std::chrono::system_clock::now() - lastAttempted).count(); } + // p2p: move to NodeEndpoint unsigned fallbackSeconds() const; - bool shouldReconnect() const; + // p2p: move to NodeEndpoint + bool shouldReconnect() const { return std::chrono::system_clock::now() > lastAttempted + std::chrono::seconds(fallbackSeconds()); } + // p2p: This has two meanings now. It's possible UDP works but TPC is down (unable to punch hole). + // p2p: Rename to isConnect() and move to endpoint. revisit Session.cpp#245, MainWin.cpp#877 bool isOffline() const { return lastAttempted > lastConnected; } - bool operator<(Node const& _n) const + + // p2p: Remove (in favor of lru eviction and sub-protocol ratings). + bool operator<(NodeInfo const& _n) const { if (isOffline() != _n.isOffline()) return isOffline(); @@ -101,7 +120,7 @@ struct Node } }; -using Nodes = std::vector; +using Nodes = std::vector; /** * @brief The Host class @@ -111,7 +130,7 @@ class Host: public Worker { friend class Session; friend class HostCapabilityFace; - friend struct Node; + friend struct NodeInfo; public: /// Start server, listening for connections on the given port. @@ -134,16 +153,19 @@ public: static std::string pocHost(); void connect(std::string const& _addr, unsigned short _port = 30303) noexcept; void connect(bi::tcp::endpoint const& _ep); - void connect(std::shared_ptr const& _n); + void connect(std::shared_ptr const& _n); /// @returns true iff we have a peer of the given id. bool havePeer(NodeId _id) const; /// Set ideal number of peers. void setIdealPeerCount(unsigned _n) { m_idealPeerCount = _n; } + + /// p2p: template? + void setIdealPeerCount(HostCapabilityFace* _cap, unsigned _n) { m_capIdealPeerCount[_cap->capDesc()] = _n; } /// Get peer information. - PeerInfos peers(bool _updatePing = false) const; + PeerInfos peers() const; /// Get number of peers connected; equivalent to, but faster than, peers().size(). size_t peerCount() const { RecursiveGuard l(x_peers); return m_peers.size(); } @@ -178,7 +200,7 @@ public: void registerPeer(std::shared_ptr _s, CapDescs const& _caps); - std::shared_ptr node(NodeId _id) const { if (m_nodes.count(_id)) return m_nodes.at(_id); return std::shared_ptr(); } + std::shared_ptr node(NodeId _id) const { if (m_nodes.count(_id)) return m_nodes.at(_id); return std::shared_ptr(); } private: /// Populate m_peerAddresses with available public addresses. @@ -189,9 +211,6 @@ private: void seal(bytes& _b); - void growPeers(); - void prunePeers(); - /// Called by Worker. Not thread-safe; to be called only by worker. virtual void startedWorking(); /// Called by startedWorking. Not thread-safe; to be called only be Worker. @@ -203,34 +222,35 @@ private: /// Shutdown network. Not thread-safe; to be called only by worker. virtual void doneWorking(); - std::shared_ptr noteNode(NodeId _id, bi::tcp::endpoint _a, Origin _o, bool _ready, NodeId _oldId = NodeId()); + std::shared_ptr noteNode(NodeId _id, bi::tcp::endpoint _a, Origin _o, bool _ready, NodeId _oldId = NodeId()); Nodes potentialPeers(RangeMask const& _known); bool m_run = false; ///< Whether network is running. - std::mutex x_runTimer; ///< Start/stop mutex. + std::mutex x_runTimer; ///< Start/stop mutex. std::string m_clientVersion; ///< Our version string. NetworkPreferences m_netPrefs; ///< Network settings. /// Interface addresses (private, public) - std::vector m_ifAddresses; ///< Interface addresses. + std::vector m_ifAddresses; ///< Interface addresses. int m_listenPort = -1; ///< What port are we listening on. -1 means binding failed or acceptor hasn't been initialized. - ba::io_service m_ioService; ///< IOService for network stuff. - bi::tcp::acceptor m_tcp4Acceptor; ///< Listening acceptor. + ba::io_service m_ioService; ///< IOService for network stuff. + bi::tcp::acceptor m_tcp4Acceptor; ///< Listening acceptor. std::unique_ptr m_socket; ///< Listening socket. std::unique_ptr m_timer; ///< Timer which, when network is running, calls scheduler() every c_timerInterval ms. static const unsigned c_timerInterval = 100; ///< Interval which m_timer is run when network is connected. - unsigned m_lastTick = 0; ///< Used by run() for scheduling; must not be mutated outside of run(). - std::set m_pendingNodeConns; /// Used only by connect(Node&) to limit concurrently connecting to same node. See connect(shared_ptrconst&). + std::set m_pendingNodeConns; /// Used only by connect(NodeInfo&) to limit concurrently connecting to same node. See connect(shared_ptrconst&). Mutex x_pendingNodeConns; bi::tcp::endpoint m_tcpPublic; ///< Our public listening endpoint. - KeyPair m_key; ///< Our unique ID. + KeyPair m_key; ///< Our unique ID. + std::shared_ptr m_nodeTable; ///< Node table (uses kademlia-like discovery). + std::map m_capIdealPeerCount; ///< Ideal peer count for capability. bool m_hadNewNodes = false; @@ -242,7 +262,7 @@ private: /// Nodes to which we may connect (or to which we have connected). /// TODO: does this need a lock? - std::map > m_nodes; + std::map > m_nodes; /// A list of node IDs. This contains every index from m_nodes; the order is guaranteed to remain the same. std::vector m_nodesList; diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index 20f9f5fdf..54c8c9f35 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -24,12 +24,15 @@ using namespace std; using namespace dev; using namespace dev::p2p; -NodeTable::NodeTable(ba::io_service& _io, KeyPair _alias, uint16_t _listenPort): +NodeEntry::NodeEntry(Node _src, Public _pubk, NodeDefaultEndpoint _gw): Node(_pubk, _gw), distance(NodeTable::dist(_src.id,_pubk)) {} +NodeEntry::NodeEntry(Node _src, Public _pubk, bi::udp::endpoint _udp): Node(_pubk, NodeDefaultEndpoint(_udp)), distance(NodeTable::dist(_src.id,_pubk)) {} + +NodeTable::NodeTable(ba::io_service& _io, KeyPair _alias, uint16_t _udp, bi::tcp::endpoint _ep): m_node(Node(_alias.pub(), bi::udp::endpoint())), m_secret(_alias.sec()), - m_socket(new NodeSocket(_io, *this, _listenPort)), - m_socketPtr(m_socket.get()), m_io(_io), + m_socket(new NodeSocket(m_io, *this, _udp)), + m_socketPtr(m_socket.get()), m_bucketRefreshTimer(m_io), m_evictionCheckTimer(m_io) { @@ -64,7 +67,7 @@ std::list NodeTable::nodes() const return std::move(nodes); } -list NodeTable::state() const +list NodeTable::state() const { list ret; Guard l(x_state); @@ -74,7 +77,7 @@ list NodeTable::state() const return move(ret); } -NodeTable::NodeEntry NodeTable::operator[](NodeId _id) +NodeEntry NodeTable::operator[](NodeId _id) { Guard l(x_nodes); return *m_nodes[_id]; @@ -135,7 +138,7 @@ void NodeTable::doFindNode(NodeId _node, unsigned _round, std::shared_ptr> NodeTable::findNearest(NodeId _target) +std::vector> NodeTable::findNearest(NodeId _target) { // send s_alpha FindNode packets to nodes we know, closest to target static unsigned lastBin = s_bins - 1; @@ -259,7 +262,7 @@ void NodeTable::noteNode(Public const& _pubk, bi::udp::endpoint const& _endpoint } } - // todo: why is this necessary? + // todo: sometimes node is nullptr here if (!!node) noteNode(node); } @@ -365,7 +368,7 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes // clog(NodeTableMessageSummary) << "Received FindNode from " << _from.address().to_string() << ":" << _from.port(); FindNode in = FindNode::fromBytesConstRef(_from, rlpBytes); - std::vector> nearest = findNearest(in.target); + std::vector> nearest = findNearest(in.target); static unsigned const nlimit = (m_socketPtr->maxDatagramSize - 11) / 86; for (unsigned offset = 0; offset < nearest.size(); offset += nlimit) { diff --git a/libp2p/NodeTable.h b/libp2p/NodeTable.h index 5466a3ae3..e3503b0b9 100644 --- a/libp2p/NodeTable.h +++ b/libp2p/NodeTable.h @@ -31,6 +31,41 @@ namespace dev namespace p2p { +struct NodeDefaultEndpoint +{ + NodeDefaultEndpoint(bi::udp::endpoint _udp): udp(_udp) {} + NodeDefaultEndpoint(bi::tcp::endpoint _tcp): tcp(_tcp) {} + NodeDefaultEndpoint(bi::udp::endpoint _udp, bi::tcp::endpoint _tcp): udp(_udp), tcp(_tcp) {} + + bi::udp::endpoint udp; + bi::tcp::endpoint tcp; +}; + +struct Node +{ + Node(Public _pubk, NodeDefaultEndpoint _udp): id(_pubk), endpoint(_udp) {} + Node(Public _pubk, bi::udp::endpoint _udp): Node(_pubk, NodeDefaultEndpoint(_udp)) {} + + virtual NodeId const& address() const { return id; } + virtual Public const& publicKey() const { return id; } + + NodeId id; + NodeDefaultEndpoint endpoint; +}; + + +/** + * NodeEntry + * @brief Entry in Node Table + */ +struct NodeEntry: public Node +{ + NodeEntry(Node _src, Public _pubk, NodeDefaultEndpoint _gw); //: Node(_pubk, _gw), distance(dist(_src.id,_pubk)) {} + NodeEntry(Node _src, Public _pubk, bi::udp::endpoint _udp); //: Node(_pubk, NodeDefaultEndpoint(_udp)), distance(dist(_src.id,_pubk)) {} + + const unsigned distance; ///< Node's distance from _src (see constructor). +}; + /** * NodeTable using S/Kademlia system for node discovery and preference. * untouched buckets are refreshed if they have not been touched within an hour @@ -50,7 +85,7 @@ namespace p2p * @todo expiration and sha3(id) 'to' for messages which are replies (prevents replay) * @todo std::shared_ptr m_cachedPingPacket; * @todo std::shared_ptr m_cachedFindSelfPacket; - * @todo store root node in table? + * @todo store self (root) in table? (potential bug. alt is to add to list when self is closest to target) * * [Networking] * @todo TCP endpoints @@ -70,46 +105,9 @@ class NodeTable: UDPSocketEvents, public std::enable_shared_from_this using NodeSocket = UDPSocket; using TimePoint = std::chrono::steady_clock::time_point; using EvictionTimeout = std::pair,NodeId>; ///< First NodeId may be evicted and replaced with second NodeId. - - struct NodeDefaultEndpoint - { - NodeDefaultEndpoint(bi::udp::endpoint _udp): udp(_udp) {} - bi::udp::endpoint udp; - }; - - struct Node - { - Node(Public _pubk, NodeDefaultEndpoint _udp): id(_pubk), endpoint(_udp) {} - Node(Public _pubk, bi::udp::endpoint _udp): Node(_pubk, NodeDefaultEndpoint(_udp)) {} - - virtual NodeId const& address() const { return id; } - virtual Public const& publicKey() const { return id; } - - NodeId id; - NodeDefaultEndpoint endpoint; - }; - - /** - * NodeEntry - * @todo Type of id will become template parameter. - */ - struct NodeEntry: public Node - { - NodeEntry(Node _src, Public _pubk, NodeDefaultEndpoint _gw): Node(_pubk, _gw), distance(dist(_src.id,_pubk)) {} - NodeEntry(Node _src, Public _pubk, bi::udp::endpoint _udp): Node(_pubk, NodeDefaultEndpoint(_udp)), distance(dist(_src.id,_pubk)) {} - - const unsigned distance; ///< Node's distance from _src (see constructor). - }; - - struct NodeBucket - { - unsigned distance; - TimePoint modified; - std::list> nodes; - }; public: - NodeTable(ba::io_service& _io, KeyPair _alias, uint16_t _port = 30300); + NodeTable(ba::io_service& _io, KeyPair _alias, uint16_t _udpPort = 30303, bi::tcp::endpoint _ep = bi::tcp::endpoint()); ~NodeTable(); /// Constants for Kademlia, mostly derived from address space. @@ -121,7 +119,7 @@ public: /// Chosen constants - static unsigned const s_bucketSize = 16; ///< Denoted by k in [Kademlia]. Number of nodes stored in each bucket. + static unsigned const s_bucketSize = 16; ///< Denoted by k in [Kademlia]. Number of nodes stored in each bucket. static unsigned const s_alpha = 3; ///< Denoted by \alpha in [Kademlia]. Number of concurrent FindNode requests. /// Intervals @@ -142,6 +140,13 @@ public: protected: + struct NodeBucket + { + unsigned distance; + TimePoint modified; + std::list> nodes; + }; + /// Repeatedly sends s_alpha concurrent requests to nodes nearest to target, for nodes nearest to target, up to s_maxSteps rounds. void doFindNode(NodeId _node, unsigned _round = 0, std::shared_ptr>> _tried = std::shared_ptr>>()); @@ -193,10 +198,11 @@ protected: Mutex x_evictions; std::deque m_evictions; ///< Eviction timeouts. - + + ba::io_service& m_io; ///< Used by bucket refresh timer. std::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. }; @@ -317,7 +323,7 @@ struct Neighbors: RLPXDatagram }; using RLPXDatagram::RLPXDatagram; - Neighbors(bi::udp::endpoint _to, std::vector> const& _nearest, unsigned _offset = 0, unsigned _limit = 0): RLPXDatagram(_to) + Neighbors(bi::udp::endpoint _to, std::vector> const& _nearest, unsigned _offset = 0, unsigned _limit = 0): RLPXDatagram(_to) { auto limit = _limit ? std::min(_nearest.size(), (size_t)(_offset + _limit)) : _nearest.size(); for (auto i = _offset; i < limit; i++) diff --git a/libp2p/Session.cpp b/libp2p/Session.cpp index 3a0dcf1cf..9a0dd2d2e 100644 --- a/libp2p/Session.cpp +++ b/libp2p/Session.cpp @@ -47,7 +47,7 @@ Session::Session(Host* _s, bi::tcp::socket _socket, bi::tcp::endpoint const& _ma m_info = PeerInfo({NodeId(), "?", m_manualEndpoint.address().to_string(), 0, std::chrono::steady_clock::duration(0), CapDescSet(), 0, map()}); } -Session::Session(Host* _s, bi::tcp::socket _socket, std::shared_ptr const& _n, bool _force): +Session::Session(Host* _s, bi::tcp::socket _socket, std::shared_ptr const& _n, bool _force): m_server(_s), m_socket(std::move(_socket)), m_node(_n), diff --git a/libp2p/Session.h b/libp2p/Session.h index cabef2cbf..869eca96e 100644 --- a/libp2p/Session.h +++ b/libp2p/Session.h @@ -39,7 +39,7 @@ namespace dev namespace p2p { -struct Node; +struct NodeInfo; /** * @brief The Session class @@ -51,7 +51,7 @@ class Session: public std::enable_shared_from_this friend class HostCapabilityFace; public: - Session(Host* _server, bi::tcp::socket _socket, std::shared_ptr const& _n, bool _force = false); + Session(Host* _server, bi::tcp::socket _socket, std::shared_ptr const& _n, bool _force = false); Session(Host* _server, bi::tcp::socket _socket, bi::tcp::endpoint const& _manual); virtual ~Session(); @@ -113,7 +113,7 @@ private: PeerInfo m_info; ///< Dynamic information about this peer. unsigned m_protocolVersion = 0; ///< The protocol version of the peer. - std::shared_ptr m_node; ///< The Node object. Might be null if we constructed using a bare address/port. + std::shared_ptr m_node; ///< The NodeInfo object. Might be null if we constructed using a bare address/port. bi::tcp::endpoint m_manualEndpoint; ///< The endpoint as specified by the constructor. bool m_force = false; ///< If true, ignore IDs being different. This could open you up to MitM attacks. bool m_dropped = false; ///< If true, we've already divested ourselves of this peer. We're just waiting for the reads & writes to fail before the shared_ptr goes OOS and the destructor kicks in. diff --git a/libp2p/UDP.h b/libp2p/UDP.h index ac4afb0b1..8e732d3ff 100644 --- a/libp2p/UDP.h +++ b/libp2p/UDP.h @@ -57,8 +57,6 @@ protected: /** * @brief RLPX Datagram which can be signed. - * @todo compact templates - * @todo make data private/functional (see UDPDatagram) */ struct RLPXDatagramFace: public UDPDatagram { From da9668c0f5c6fa5c6f9013c903e7abf2ad760a8c Mon Sep 17 00:00:00 2001 From: subtly Date: Wed, 7 Jan 2015 02:26:14 +0100 Subject: [PATCH 002/213] Pass 2 integrating node table. Pruning and merging old node lifecycle logic with new. Begin moving node identification and authentication into Host so session can be directly-constructed with NodeInfo and is not created until after authentication. Require session to be passed a valid node. --- libp2p/Host.cpp | 191 +++++++++++++++------------------------ libp2p/Host.h | 27 ++---- libp2p/NodeTable.cpp | 34 ++++--- libp2p/NodeTable.h | 5 +- libp2p/Session.cpp | 58 ++++-------- libp2p/Session.h | 6 +- libwebthree/WebThree.cpp | 2 +- test/peer.cpp | 2 +- test/whisperTopic.cpp | 2 +- 9 files changed, 122 insertions(+), 205 deletions(-) diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index bdb72985c..ffc63cf8e 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -149,12 +149,8 @@ unsigned Host::protocolVersion() const void Host::registerPeer(std::shared_ptr _s, CapDescs const& _caps) { -#warning integration: todo rework so this is an exception - if (!_s->m_node || !_s->m_node->id) - { - cwarn << "Attempting to register a peer without node information!"; - return; - } + assert(!!_s->m_node); + assert(!!_s->m_node->id); { RecursiveGuard l(x_peers); @@ -182,8 +178,8 @@ void Host::seal(bytes& _b) _b[7] = len & 0xff; } -#warning integration: todo remove origin, ready, oldid. port to NodeTable. see Session.cpp#244,363 -shared_ptr Host::noteNode(NodeId _id, bi::tcp::endpoint _a, Origin _o, bool _ready, NodeId _oldId) +// TODO P2P: remove oldid. port to NodeTable. (see noteNode calls, Session.cpp#218,337) +shared_ptr Host::noteNode(NodeId _id, bi::tcp::endpoint _a, NodeId _oldId) { RecursiveGuard l(x_peers); if (_a.port() < 30300 || _a.port() > 30305) @@ -195,8 +191,6 @@ shared_ptr Host::noteNode(NodeId _id, bi::tcp::endpoint _a, Origin _o, _a = bi::tcp::endpoint(_a.address(), 0); } -// cnote << "NodeInfo:" << _id.abridged() << _a << (_ready ? "ready" : "used") << _oldId.abridged() << (m_nodes.count(_id) ? "[have]" : "[NEW]"); - // First check for another node with the same connection credentials, and put it in oldId if found. if (!_oldId) for (pair> const& n: m_nodes) @@ -223,33 +217,21 @@ shared_ptr Host::noteNode(NodeId _id, bi::tcp::endpoint _a, Origin _o, m_nodes[_id] = make_shared(); m_nodes[_id]->id = _id; m_nodes[_id]->index = i; - m_nodes[_id]->idOrigin = _o; } else - { i = m_nodes[_id]->index; - m_nodes[_id]->idOrigin = max(m_nodes[_id]->idOrigin, _o); - } m_nodes[_id]->address = _a; - m_ready.extendAll(i); m_private.extendAll(i); - if (_ready) - m_ready += i; - else - m_ready -= i; if (!_a.port() || (isPrivateAddress(_a.address()) && !m_netPrefs.localNetworking)) m_private += i; else m_private -= i; -// cnote << m_nodes[_id]->index << ":" << m_ready; - - m_hadNewNodes = true; - return m_nodes[_id]; } -#warning integration: TBD caps in NodeTable/NodeEntry +// TODO P2P: should be based on target +// TODO P2P: store caps in NodeTable/NodeEntry Nodes Host::potentialPeers(RangeMask const& _known) { RecursiveGuard l(x_peers); @@ -340,13 +322,7 @@ void Host::runAcceptor() { try { - try { - clog(NetConnect) << "Accepted connection from " << m_socket->remote_endpoint(); - } catch (...){} - bi::address remoteAddress = m_socket->remote_endpoint().address(); - // Port defaults to 0 - we let the hello tell us which port the peer listens to - auto p = std::make_shared(this, std::move(*m_socket.release()), bi::tcp::endpoint(remoteAddress, 0)); - p->start(); + doHandshake(m_socket.release()); success = true; } catch (Exception const& _e) @@ -373,6 +349,16 @@ void Host::runAcceptor() } } +void Host::doHandshake(bi::tcp::socket* _socket, NodeId _egressNodeId) +{ + try { + clog(NetConnect) << "Accepting connection for " << _socket->remote_endpoint(); + } catch (...){} + + auto p = std::make_shared(this, std::move(*_socket), m_nodes[_egressNodeId]); + p->start(); +} + string Host::pocHost() { vector strs; @@ -380,56 +366,51 @@ string Host::pocHost() return "poc-" + strs[1] + ".ethdev.com"; } -#warning integration: todo remove all connect() w/ addNode makeRequired (this requires pubkey) -void Host::connect(std::string const& _addr, unsigned short _port) noexcept +// TODO P2P: support for TCP+UDP when manually connecting +// TODO P2P: remove in favor of addNode(NodeId, string, uint16_t, bool _required = false) +void Host::connect(NodeId const& _node, std::string const& _addr, unsigned short _port) noexcept { if (!m_run) return; + + assert(_node); - for (auto first: {true, false}) + auto n = m_nodes[_node]; + + // TODO: refactor into async_resolve + m_ioService.post([=]() { - try + for (auto first: {true, false}) { - if (first) + try { - bi::tcp::resolver r(m_ioService); - connect(r.resolve({_addr, toString(_port)})->endpoint()); + bi::tcp::endpoint ep; + if (first) + { + bi::tcp::resolver r(m_ioService); + ep = r.resolve({_addr, toString(_port)})->endpoint(); + } + else + ep = bi::tcp::endpoint(bi::address::from_string(_addr), _port); + + if (!n) + m_nodes[_node] = make_shared(); + m_nodes[_node]->id = _node; + m_nodes[_node]->address = ep; + connect(m_nodes[_node]); + break; + } + catch (Exception const& _e) + { + // Couldn't connect + clog(NetConnect) << "Bad host " << _addr << "\n" << diagnostic_information(_e); + } + catch (exception const& e) + { + // Couldn't connect + clog(NetConnect) << "Bad host " << _addr << " (" << e.what() << ")"; } - else - connect(bi::tcp::endpoint(bi::address::from_string(_addr), _port)); - break; - } - catch (Exception const& _e) - { - // Couldn't connect - clog(NetConnect) << "Bad host " << _addr << "\n" << diagnostic_information(_e); - } - catch (exception const& e) - { - // Couldn't connect - clog(NetConnect) << "Bad host " << _addr << " (" << e.what() << ")"; - } - } -} - -void Host::connect(bi::tcp::endpoint const& _ep) -{ - if (!m_run) - return; - - clog(NetConnect) << "Attempting single-shot connection to " << _ep; - bi::tcp::socket* s = new bi::tcp::socket(m_ioService); - s->async_connect(_ep, [=](boost::system::error_code const& ec) - { - if (ec) - clog(NetConnect) << "Connection refused to " << _ep << " (" << ec.message() << ")"; - else - { - auto p = make_shared(this, std::move(*s), _ep); - clog(NetConnect) << "Connected to " << _ep; - p->start(); } - delete s; }); } @@ -438,7 +419,7 @@ void Host::connect(std::shared_ptr const& _n) if (!m_run) return; - // prevent concurrently connecting to a node; todo: better abstraction + // prevent concurrently connecting to a node NodeInfo *nptr = _n.get(); { Guard l(x_pendingNodeConns); @@ -450,7 +431,6 @@ void Host::connect(std::shared_ptr const& _n) clog(NetConnect) << "Attempting connection to node" << _n->id.abridged() << "@" << _n->address << "from" << id().abridged(); _n->lastAttempted = std::chrono::system_clock::now(); _n->failedAttempts++; - m_ready -= _n->index; bi::tcp::socket* s = new bi::tcp::socket(m_ioService); auto n = node(_n->id); @@ -462,13 +442,12 @@ void Host::connect(std::shared_ptr const& _n) clog(NetConnect) << "Connection refused to node" << _n->id.abridged() << "@" << _n->address << "(" << ec.message() << ")"; _n->lastDisconnect = TCPError; _n->lastAttempted = std::chrono::system_clock::now(); - m_ready += _n->index; } else { clog(NetConnect) << "Connected to" << _n->id.abridged() << "@" << _n->address; _n->lastConnected = std::chrono::system_clock::now(); - auto p = make_shared(this, std::move(*s), n, true); // true because we don't care about ids matched for now. Once we have permenant IDs this will matter a lot more and we can institute a safer mechanism. + auto p = make_shared(this, std::move(*s), n); p->start(); } delete s; @@ -476,7 +455,7 @@ void Host::connect(std::shared_ptr const& _n) m_pendingNodeConns.erase(nptr); }); else - clog(NetWarn) << "Trying to connect to node not in node table."; + clog(NetWarn) << "Aborted connect. Node not in node table."; } bool Host::havePeer(NodeId _id) const @@ -515,8 +494,8 @@ unsigned NodeInfo::fallbackSeconds() const } } -#warning integration: ---- grow/prunePeers -#warning integration: todo grow/prune into 'maintainPeers' & evaluate reputation instead of availability. schedule via deadline timer. +// TODO P2P: rebuild noetable when localNetworking is enabled/disabled +// TODO P2P: migrate grow/prunePeers into 'maintainPeers' & evaluate reputation instead of availability. schedule via deadline timer. //void Host::growPeers() //{ // RecursiveGuard l(x_peers); @@ -585,14 +564,8 @@ PeerInfos Host::peers() const if (!m_run) return PeerInfos(); -#warning integration: ---- pingAll. It is called every 30secs via deadline timer. - RecursiveGuard l(x_peers); -// if (_updatePing) -// { -// const_cast(this)->pingAll(); -// this_thread::sleep_for(chrono::milliseconds(200)); -// } std::vector ret; + RecursiveGuard l(x_peers); for (auto& i: m_peers) if (auto j = i.second.lock()) if (j->m_socket.is_open()) @@ -604,6 +577,9 @@ void Host::run(boost::system::error_code const&) { if (!m_run) { + // reset NodeTable + m_nodeTable.reset(); + // stopping io service allows running manual network operations for shutdown // and also stops blocking worker thread, allowing worker thread to exit m_ioService.stop(); @@ -612,24 +588,10 @@ void Host::run(boost::system::error_code const&) m_timer.reset(); return; } - -#warning integration: ---- -// m_lastTick += c_timerInterval; -// if (m_lastTick >= c_timerInterval * 10) -// { -// growPeers(); -// prunePeers(); -// m_lastTick = 0; -// } - if (m_hadNewNodes) - { - for (auto p: m_peers) - if (auto pp = p.second.lock()) - pp->serviceNodesRequest(); - - m_hadNewNodes = false; - } + for (auto p: m_peers) + if (auto pp = p.second.lock()) + pp->serviceNodesRequest(); if (chrono::steady_clock::now() - m_lastPing > chrono::seconds(30)) // ping every 30s. { @@ -675,20 +637,13 @@ void Host::startedWorking() if (m_listenPort > 0) runAcceptor(); -#warning integration: ++++ if (!m_tcpPublic.address().is_unspecified()) m_nodeTable.reset(new NodeTable(m_ioService, m_key, m_listenPort, m_tcpPublic)); else m_nodeTable.reset(new NodeTable(m_ioService, m_key, m_listenPort > 0 ? m_listenPort : 30303)); } - -#warning integration: ---- -// // if m_public address is valid then add us to node list -// // todo: abstract empty() and emplace logic -// if (!m_tcpPublic.address().is_unspecified() && (m_nodes.empty() || m_nodes[m_nodesList[0]]->id != id())) -// noteNode(id(), m_tcpPublic, Origin::Perfect, false); - - clog(NetNote) << "Id:" << id().abridged(); + + clog(NetNote) << "p2p.started id:" << id().abridged(); run(boost::system::error_code()); } @@ -708,7 +663,7 @@ void Host::pingAll() m_lastPing = chrono::steady_clock::now(); } -#warning integration: todo save/restoreNodes +// TODO P2P: integration: todo save/restoreNodes bytes Host::saveNodes() const { RLPStream nodes; @@ -726,7 +681,7 @@ bytes Host::saveNodes() const nodes << n.address.address().to_v4().to_bytes(); else nodes << n.address.address().to_v6().to_bytes(); - nodes << n.address.port() << n.id << (int)n.idOrigin + nodes << n.address.port() << n.id /* << (int)n.idOrigin */ << 0 << chrono::duration_cast(n.lastConnected.time_since_epoch()).count() << chrono::duration_cast(n.lastAttempted.time_since_epoch()).count() << n.failedAttempts << (unsigned)n.lastDisconnect << n.score << n.rating; @@ -751,7 +706,7 @@ void Host::restoreNodes(bytesConstRef _b) { auto oldId = id(); m_key = KeyPair(r[1].toHash()); - noteNode(id(), m_tcpPublic, Origin::Perfect, false, oldId); + noteNode(id(), m_tcpPublic, oldId); for (auto i: r[2]) { @@ -763,8 +718,8 @@ void Host::restoreNodes(bytesConstRef _b) auto id = (NodeId)i[2]; if (!m_nodes.count(id)) { - auto o = (Origin)i[3].toInt(); - auto n = noteNode(id, ep, o, true); +// auto o = (Origin)i[3].toInt(); + auto n = noteNode(id, ep); n->lastConnected = chrono::system_clock::time_point(chrono::seconds(i[4].toInt())); n->lastAttempted = chrono::system_clock::time_point(chrono::seconds(i[5].toInt())); n->failedAttempts = i[6].toInt(); @@ -787,7 +742,7 @@ void Host::restoreNodes(bytesConstRef _b) ep = bi::tcp::endpoint(bi::address_v4(i[0].toArray()), i[1].toInt()); else ep = bi::tcp::endpoint(bi::address_v6(i[0].toArray()), i[1].toInt()); - auto n = noteNode(id, ep, Origin::Self, true); + auto n = noteNode(id, ep); } } } diff --git a/libp2p/Host.h b/libp2p/Host.h index 9600c723b..817a844cd 100644 --- a/libp2p/Host.h +++ b/libp2p/Host.h @@ -51,15 +51,6 @@ namespace p2p class Host; -enum class Origin -{ - Unknown, - Self, - SelfThird, - PerfectThird, - Perfect, -}; - struct NodeInfo { NodeId id; ///< Their id/public key. @@ -81,9 +72,6 @@ struct NodeInfo // p2p: move to protocol-specific map int score = 0; ///< All time cumulative. int rating = 0; ///< Trending. - - // p2p: remove - Origin idOrigin = Origin::Unknown; ///< How did we get to know this node's id? // p2p: move to NodeEndpoint int secondsSinceLastConnected() const { return lastConnected == std::chrono::system_clock::time_point() ? -1 : (int)std::chrono::duration_cast(std::chrono::system_clock::now() - lastConnected).count(); } @@ -125,6 +113,7 @@ using Nodes = std::vector; /** * @brief The Host class * Capabilities should be registered prior to startNetwork, since m_capabilities is not thread-safe. + * @todo determinePublic: ipv6, udp */ class Host: public Worker { @@ -151,8 +140,8 @@ public: /// Connect to a peer explicitly. static std::string pocHost(); - void connect(std::string const& _addr, unsigned short _port = 30303) noexcept; - void connect(bi::tcp::endpoint const& _ep); + void connect(NodeId const& _node, std::string const& _addr, unsigned short _port = 30303) noexcept; + void connect(NodeId const& _node, bi::tcp::endpoint const& _ep); void connect(std::shared_ptr const& _n); /// @returns true iff we have a peer of the given id. @@ -209,6 +198,9 @@ private: /// Called only from startedWorking(). void runAcceptor(); + /// Handler for verifying handshake siganture before creating session. _egressNodeId is passed for outbound connections. + void doHandshake(bi::tcp::socket* _socket, NodeId _egressNodeId = NodeId()); + void seal(bytes& _b); /// Called by Worker. Not thread-safe; to be called only by worker. @@ -222,7 +214,7 @@ private: /// Shutdown network. Not thread-safe; to be called only by worker. virtual void doneWorking(); - std::shared_ptr noteNode(NodeId _id, bi::tcp::endpoint _a, Origin _o, bool _ready, NodeId _oldId = NodeId()); + std::shared_ptr noteNode(NodeId _id, bi::tcp::endpoint _a, NodeId _oldId = NodeId()); Nodes potentialPeers(RangeMask const& _known); bool m_run = false; ///< Whether network is running. @@ -252,8 +244,6 @@ private: std::shared_ptr m_nodeTable; ///< Node table (uses kademlia-like discovery). std::map m_capIdealPeerCount; ///< Ideal peer count for capability. - bool m_hadNewNodes = false; - mutable RecursiveMutex x_peers; /// The nodes to which we are currently connected. @@ -261,13 +251,12 @@ private: mutable std::map> m_peers; /// Nodes to which we may connect (or to which we have connected). - /// TODO: does this need a lock? + /// TODO: mutex; replace with nodeTable std::map > m_nodes; /// A list of node IDs. This contains every index from m_nodes; the order is guaranteed to remain the same. std::vector m_nodesList; - RangeMask m_ready; ///< Indices into m_nodesList over to which nodes we are not currently connected, connecting or otherwise ignoring. RangeMask m_private; ///< Indices into m_nodesList over to which nodes are private. unsigned m_idealPeerCount = 5; ///< Ideal number of peers to be connected to. diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index abf762fff..699f0d0c9 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -239,29 +239,27 @@ void NodeTable::evict(shared_ptr _leastSeen, shared_ptr _n ping(_leastSeen.get()); } +shared_ptr NodeTable::addNode(Public const& _pubk, bi::udp::endpoint const& _udp, bi::tcp::endpoint const& _tcp) +{ + shared_ptr ret; + Guard l(x_nodes); + if (auto n = m_nodes[_pubk]) + ret = n; + else + { + ret.reset(new NodeEntry(m_node, _pubk, _udp)); + m_nodes[_pubk] = ret; + } + return move(ret); +} + void NodeTable::noteNode(Public const& _pubk, bi::udp::endpoint const& _endpoint) { - // Don't add ourself if (_pubk == m_node.address()) return; - shared_ptr node; - { - Guard l(x_nodes); - auto n = m_nodes.find(_pubk); - if (n == m_nodes.end()) - { - node.reset(new NodeEntry(m_node, _pubk, _endpoint)); - m_nodes[_pubk] = node; -// clog(NodeTableMessageSummary) << "Adding node to cache: " << _pubk; - } - else - { - node = n->second; -// clog(NodeTableMessageSummary) << "Found node in cache: " << _pubk; - } - } - + shared_ptr node(addNode(_pubk, _endpoint)); + // todo: sometimes node is nullptr here if (!!node) noteNode(node); diff --git a/libp2p/NodeTable.h b/libp2p/NodeTable.h index d99119f02..d209018a2 100644 --- a/libp2p/NodeTable.h +++ b/libp2p/NodeTable.h @@ -131,6 +131,9 @@ public: static unsigned dist(NodeId const& _a, NodeId const& _b) { u512 d = _a ^ _b; unsigned ret; for (ret = 0; d >>= 1; ++ret) {}; return ret; } + /// Add node details and attempt adding to node table if node responds to ping. NodeEntry will immediately be returned and may be used for required connectivity. + std::shared_ptr addNode(Public const& _pubk, bi::udp::endpoint const& _udp, bi::tcp::endpoint const& _tcp = bi::tcp::endpoint()); + void join(); NodeEntry root() const { return NodeEntry(m_node, m_node.publicKey(), m_node.endpoint.udp); } @@ -192,7 +195,7 @@ protected: Secret m_secret; ///< This nodes secret key. mutable Mutex x_nodes; ///< Mutable for thread-safe copy in nodes() const. - std::map> m_nodes; ///< NodeId -> Node table (most common lookup path) + std::map> m_nodes; ///< NodeId -> Node table mutable Mutex x_state; std::array m_state; ///< State table of binned nodes. diff --git a/libp2p/Session.cpp b/libp2p/Session.cpp index d53a89f09..c31335357 100644 --- a/libp2p/Session.cpp +++ b/libp2p/Session.cpp @@ -36,23 +36,11 @@ using namespace dev::p2p; #endif #define clogS(X) dev::LogOutputStream(false) << "| " << std::setw(2) << m_socket.native_handle() << "] " -Session::Session(Host* _s, bi::tcp::socket _socket, bi::tcp::endpoint const& _manual): - m_server(_s), - m_socket(std::move(_socket)), - m_node(nullptr), - m_manualEndpoint(_manual) // NOTE: the port on this shouldn't be used if it's zero. -{ - m_lastReceived = m_connect = std::chrono::steady_clock::now(); - - m_info = PeerInfo({NodeId(), "?", m_manualEndpoint.address().to_string(), 0, std::chrono::steady_clock::duration(0), CapDescSet(), 0, map()}); -} - -Session::Session(Host* _s, bi::tcp::socket _socket, std::shared_ptr const& _n, bool _force): +Session::Session(Host* _s, bi::tcp::socket _socket, std::shared_ptr const& _n): m_server(_s), m_socket(std::move(_socket)), m_node(_n), - m_manualEndpoint(_n->address), - m_force(_force) + m_manualEndpoint(_n->address) { m_lastReceived = m_connect = std::chrono::steady_clock::now(); m_info = PeerInfo({m_node->id, "?", _n->address.address().to_string(), _n->address.port(), std::chrono::steady_clock::duration(0), CapDescSet(), 0, map()}); @@ -60,13 +48,9 @@ Session::Session(Host* _s, bi::tcp::socket _socket, std::shared_ptr co Session::~Session() { - if (m_node) - { - if (id() && !isPermanentProblem(m_node->lastDisconnect) && !m_node->dead) - m_server->m_ready += m_node->index; - else - m_node->lastConnected = m_node->lastAttempted - chrono::seconds(1); - } + // TODO P2P: revisit (refactored from previous logic) + if (m_node && !(id() && !isPermanentProblem(m_node->lastDisconnect) && !m_node->dead)) + m_node->lastConnected = m_node->lastAttempted - chrono::seconds(1); // Read-chain finished for one reason or another. for (auto& i: m_capabilities) @@ -103,6 +87,7 @@ int Session::rating() const return m_node->rating; } +// TODO P2P: integration: session->? should be unavailable when socket isn't open bi::tcp::endpoint Session::endpoint() const { if (m_socket.is_open() && m_node) @@ -132,6 +117,7 @@ template vector randomSelection(vector const& _t, unsigned _n) return ret; } +// TODO P2P: integration: replace w/asio post -> serviceNodesRequest() void Session::ensureNodesRequested() { if (isOpen() && !m_weRequestedNodes) @@ -207,25 +193,8 @@ bool Session::interpret(RLP const& _r) return true; } - if (m_node && m_node->id != id) - { - if (m_force || m_node->idOrigin <= Origin::SelfThird) - // SECURITY: We're forcing through the new ID, despite having been told - clogS(NetWarn) << "Connected to node, but their ID has changed since last time. This could indicate a MitM attack. Allowing anyway..."; - else - { - clogS(NetWarn) << "Connected to node, but their ID has changed since last time. This could indicate a MitM attack. Disconnecting."; - disconnect(UnexpectedIdentity); - return true; - } - - if (m_server->havePeer(id)) - { - m_node->dead = true; - disconnect(DuplicatePeer); - return true; - } - } + assert(!!m_node); + assert(!!m_node->id); if (m_server->havePeer(id)) { @@ -241,9 +210,14 @@ bool Session::interpret(RLP const& _r) return true; } - m_node = m_server->noteNode(id, bi::tcp::endpoint(m_socket.remote_endpoint().address(), listenPort), Origin::Self, false, !m_node || m_node->id == id ? NodeId() : m_node->id); + // TODO P2P: first pass, implement signatures. if signature fails, drop connection. if egress, flag node's endpoint as stale. + // TODO P2P: remove oldid + // TODO P2P: with encrypted transport the handshake will fail and we won't get here + m_node = m_server->noteNode(id, bi::tcp::endpoint(m_socket.remote_endpoint().address(), listenPort), m_node->id); if (m_node->isOffline()) m_node->lastConnected = chrono::system_clock::now(); + + // TODO P2P: introduce map of nodes we've given to this node (if GetPeers/Peers stays in TCP) m_knownNodes.extendAll(m_node->index); m_knownNodes.unionWith(m_node->index); @@ -360,7 +334,7 @@ bool Session::interpret(RLP const& _r) // OK passed all our checks. Assume it's good. addRating(1000); - m_server->noteNode(id, ep, m_node->idOrigin == Origin::Perfect ? Origin::PerfectThird : Origin::SelfThird, true); + m_server->noteNode(id, ep); clogS(NetTriviaDetail) << "New peer: " << ep << "(" << id .abridged()<< ")"; CONTINUE:; } diff --git a/libp2p/Session.h b/libp2p/Session.h index 869eca96e..19dc60a28 100644 --- a/libp2p/Session.h +++ b/libp2p/Session.h @@ -51,8 +51,7 @@ class Session: public std::enable_shared_from_this friend class HostCapabilityFace; public: - Session(Host* _server, bi::tcp::socket _socket, std::shared_ptr const& _n, bool _force = false); - Session(Host* _server, bi::tcp::socket _socket, bi::tcp::endpoint const& _manual); + Session(Host* _server, bi::tcp::socket _socket, std::shared_ptr const& _n); virtual ~Session(); void start(); @@ -113,9 +112,8 @@ private: PeerInfo m_info; ///< Dynamic information about this peer. unsigned m_protocolVersion = 0; ///< The protocol version of the peer. - std::shared_ptr m_node; ///< The NodeInfo object. Might be null if we constructed using a bare address/port. + std::shared_ptr m_node; ///< The NodeInfo object. bi::tcp::endpoint m_manualEndpoint; ///< The endpoint as specified by the constructor. - bool m_force = false; ///< If true, ignore IDs being different. This could open you up to MitM attacks. bool m_dropped = false; ///< If true, we've already divested ourselves of this peer. We're just waiting for the reads & writes to fail before the shared_ptr goes OOS and the destructor kicks in. bool m_theyRequestedNodes = false; ///< Has the peer requested nodes from us without receiveing an answer from us? diff --git a/libwebthree/WebThree.cpp b/libwebthree/WebThree.cpp index c9f9d56e3..fd51b5947 100644 --- a/libwebthree/WebThree.cpp +++ b/libwebthree/WebThree.cpp @@ -102,5 +102,5 @@ void WebThreeDirect::restoreNodes(bytesConstRef _saved) void WebThreeDirect::connect(std::string const& _seedHost, unsigned short _port) { - m_net.connect(_seedHost, _port); + m_net.connect(NodeId(), _seedHost, _port); } diff --git a/test/peer.cpp b/test/peer.cpp index a99ce7201..70d03e9bf 100644 --- a/test/peer.cpp +++ b/test/peer.cpp @@ -49,7 +49,7 @@ int peerTest(int argc, char** argv) Host ph("Test", NetworkPreferences(listenPort)); if (!remoteHost.empty()) - ph.connect(remoteHost, remotePort); + ph.connect(NodeId(), remoteHost, remotePort); for (int i = 0; ; ++i) { diff --git a/test/whisperTopic.cpp b/test/whisperTopic.cpp index 79adf3d6a..8ecabde9b 100644 --- a/test/whisperTopic.cpp +++ b/test/whisperTopic.cpp @@ -72,7 +72,7 @@ BOOST_AUTO_TEST_CASE(topic) this_thread::sleep_for(chrono::milliseconds(500)); ph.start(); this_thread::sleep_for(chrono::milliseconds(500)); - ph.connect("127.0.0.1", 50303); + ph.connect(NodeId(), "127.0.0.1", 50303); KeyPair us = KeyPair::create(); for (int i = 0; i < 10; ++i) From fa11fc01490b7b32f397531b859ee47c36b927d4 Mon Sep 17 00:00:00 2001 From: subtly Date: Thu, 8 Jan 2015 18:36:58 +0100 Subject: [PATCH 003/213] Persist host identifier to disk. Replace noteNode with addNode. Add udp node port to connect. Add addNode to node table which pings node, potentially adding node to table if node respons. Rename NodeEndpoint to NodeIPEndpoint. --- libp2p/Host.cpp | 184 ++++++++++++++++++++++++------------------- libp2p/Host.h | 34 +++++--- libp2p/NodeTable.cpp | 19 +++-- libp2p/NodeTable.h | 40 ++++++---- libp2p/Session.cpp | 28 ++++--- 5 files changed, 182 insertions(+), 123 deletions(-) diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index ffc63cf8e..392d02dc4 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include "Session.h" #include "Common.h" #include "Capability.h" @@ -44,14 +45,14 @@ Host::Host(std::string const& _clientVersion, NetworkPreferences const& _n, bool m_ifAddresses(Network::getInterfaceAddresses()), m_ioService(2), m_tcp4Acceptor(m_ioService), - m_key(KeyPair::create()), + m_key(move(getHostIdentifier())), m_nodeTable(new NodeTable(m_ioService, m_key)) { for (auto address: m_ifAddresses) if (address.is_v4()) clog(NetNote) << "IP Address: " << address << " = " << (isPrivateAddress(address) ? "[LOCAL]" : "[PEER]"); - clog(NetNote) << "Id:" << id().abridged(); + clog(NetNote) << "Id:" << id(); if (_start) start(); } @@ -178,69 +179,78 @@ void Host::seal(bytes& _b) _b[7] = len & 0xff; } -// TODO P2P: remove oldid. port to NodeTable. (see noteNode calls, Session.cpp#218,337) -shared_ptr Host::noteNode(NodeId _id, bi::tcp::endpoint _a, NodeId _oldId) -{ - RecursiveGuard l(x_peers); - if (_a.port() < 30300 || _a.port() > 30305) - cwarn << "Weird port being recorded: " << _a.port(); - - if (_a.port() >= /*49152*/32768) - { - cwarn << "Private port being recorded - setting to 0"; - _a = bi::tcp::endpoint(_a.address(), 0); - } +// TODO: P2P port to NodeTable. (see noteNode calls, Session.cpp) +//shared_ptr Host::noteNode(NodeId _id, bi::tcp::endpoint _a) +//{ +// RecursiveGuard l(x_peers); +// if (_a.port() < 30300 || _a.port() > 30305) +// cwarn << "Weird port being recorded: " << _a.port(); +// +// if (_a.port() >= /*49152*/32768) +// { +// cwarn << "Private port being recorded - setting to 0"; +// _a = bi::tcp::endpoint(_a.address(), 0); +// } +// +// unsigned i; +// if (!m_nodes.count(_id)) +// { +// i = m_nodesList.size(); +// m_nodesList.push_back(_id); +// m_nodes[_id] = make_shared(); +// m_nodes[_id]->id = _id; +// m_nodes[_id]->index = i; +// } +// else +// i = m_nodes[_id]->index; +// m_nodes[_id]->address = _a; +// m_private.extendAll(i); +// if (!_a.port() || (isPrivateAddress(_a.address()) && !m_netPrefs.localNetworking)) +// m_private += i; +// else +// m_private -= i; +// +// return m_nodes[_id]; +//} - // First check for another node with the same connection credentials, and put it in oldId if found. - if (!_oldId) - for (pair> const& n: m_nodes) - if (n.second->address == _a && n.second->id != _id) - { - _oldId = n.second->id; - break; - } +// TODO: P2P base on target +// TODO: P2P store caps in NodeTable/NodeEntry +//Nodes Host::potentialPeers(RangeMask const& _known) +//{ +// RecursiveGuard l(x_peers); +// Nodes ret; +// +// // todo: if localnetworking is enabled it should only share peers if remote +// // is within the same network as our interfaces. +// // this requires flagging nodes when we receive them as to if they're on private network +// auto ns = (m_netPrefs.localNetworking ? _known : (m_private + _known)).inverted(); +// for (auto i: ns) +// ret.push_back(*m_nodes[m_nodesList[i]]); +// return ret; +//} - unsigned i; - if (!m_nodes.count(_id)) +KeyPair Host::getHostIdentifier() +{ + static string s_file(getDataDir() + "/host"); + static mutex s_x; + lock_guard l(s_x); + + h256 secret; + bytes b = contents(s_file); + if (b.size() == 32) + memcpy(secret.data(), b.data(), 32); + else { - if (m_nodes.count(_oldId)) - { - i = m_nodes[_oldId]->index; - m_nodes.erase(_oldId); - m_nodesList[i] = _id; - } - else - { - i = m_nodesList.size(); - m_nodesList.push_back(_id); - } - m_nodes[_id] = make_shared(); - m_nodes[_id]->id = _id; - m_nodes[_id]->index = i; + // todo: replace w/user entropy; abstract to devcrypto + std::mt19937_64 s_eng(time(0) + chrono::high_resolution_clock::now().time_since_epoch().count()); + std::uniform_int_distribution d(0, 255); + for (unsigned i = 0; i < 32; ++i) + secret[i] = (byte)d(s_eng); } - else - i = m_nodes[_id]->index; - m_nodes[_id]->address = _a; - m_private.extendAll(i); - if (!_a.port() || (isPrivateAddress(_a.address()) && !m_netPrefs.localNetworking)) - m_private += i; - else - m_private -= i; - - return m_nodes[_id]; -} - -// TODO P2P: should be based on target -// TODO P2P: store caps in NodeTable/NodeEntry -Nodes Host::potentialPeers(RangeMask const& _known) -{ - RecursiveGuard l(x_peers); - Nodes ret; - - auto ns = (m_netPrefs.localNetworking ? _known : (m_private + _known)).inverted(); - for (auto i: ns) - ret.push_back(*m_nodes[m_nodesList[i]]); - return ret; + + if (!secret) + BOOST_THROW_EXCEPTION(crypto::InvalidState()); + return move(KeyPair(move(secret))); } void Host::determinePublic(string const& _publicAddress, bool _upnp) @@ -366,9 +376,25 @@ string Host::pocHost() return "poc-" + strs[1] + ".ethdev.com"; } -// TODO P2P: support for TCP+UDP when manually connecting -// TODO P2P: remove in favor of addNode(NodeId, string, uint16_t, bool _required = false) -void Host::connect(NodeId const& _node, std::string const& _addr, unsigned short _port) noexcept +void Host::addNode(NodeId const& _node, std::string const& _addr, unsigned short _tcpPeerPort, unsigned short _udpNodePort) +{ + boost::system::error_code ec; + bi::address addr = bi::address::from_string(_addr, ec); + if (ec) + { + bi::tcp::resolver r(m_ioService); + r.async_resolve({_addr, toString(_tcpPeerPort)}, [=](boost::system::error_code const& _ec, bi::tcp::resolver::iterator _epIt) { + if (_ec) + return; + bi::tcp::endpoint tcp = *_epIt; + addNode(Node(_node, NodeIPEndpoint(bi::udp::endpoint(tcp.address(), _udpNodePort), tcp))); + }); + } + else + addNode(Node(_node, NodeIPEndpoint(bi::udp::endpoint(addr, _udpNodePort), bi::tcp::endpoint(addr, _tcpPeerPort)))); +} + +void Host::connect(NodeId const& _node, std::string const& _addr, unsigned short _peerPort, unsigned short _nodePort) noexcept { if (!m_run) return; @@ -388,10 +414,10 @@ void Host::connect(NodeId const& _node, std::string const& _addr, unsigned short if (first) { bi::tcp::resolver r(m_ioService); - ep = r.resolve({_addr, toString(_port)})->endpoint(); + ep = r.resolve({_addr, toString(_peerPort)})->endpoint(); } else - ep = bi::tcp::endpoint(bi::address::from_string(_addr), _port); + ep = bi::tcp::endpoint(bi::address::from_string(_addr), _peerPort); if (!n) m_nodes[_node] = make_shared(); @@ -494,8 +520,8 @@ unsigned NodeInfo::fallbackSeconds() const } } -// TODO P2P: rebuild noetable when localNetworking is enabled/disabled -// TODO P2P: migrate grow/prunePeers into 'maintainPeers' & evaluate reputation instead of availability. schedule via deadline timer. +// TODO: P2P rebuild noetable when localNetworking is enabled/disabled +// TODO: P2P migrate grow/prunePeers into 'maintainPeers' & evaluate reputation instead of availability. schedule via deadline timer. //void Host::growPeers() //{ // RecursiveGuard l(x_peers); @@ -663,7 +689,6 @@ void Host::pingAll() m_lastPing = chrono::steady_clock::now(); } -// TODO P2P: integration: todo save/restoreNodes bytes Host::saveNodes() const { RLPStream nodes; @@ -704,9 +729,8 @@ void Host::restoreNodes(bytesConstRef _b) { case 0: { - auto oldId = id(); m_key = KeyPair(r[1].toHash()); - noteNode(id(), m_tcpPublic, oldId); +// noteNode(id(), m_tcpPublic); for (auto i: r[2]) { @@ -718,14 +742,14 @@ void Host::restoreNodes(bytesConstRef _b) auto id = (NodeId)i[2]; if (!m_nodes.count(id)) { -// auto o = (Origin)i[3].toInt(); - auto n = noteNode(id, ep); - n->lastConnected = chrono::system_clock::time_point(chrono::seconds(i[4].toInt())); - n->lastAttempted = chrono::system_clock::time_point(chrono::seconds(i[5].toInt())); - n->failedAttempts = i[6].toInt(); - n->lastDisconnect = (DisconnectReason)i[7].toInt(); - n->score = (int)i[8].toInt(); - n->rating = (int)i[9].toInt(); +//// auto o = (Origin)i[3].toInt(); +// auto n = noteNode(id, ep); +// n->lastConnected = chrono::system_clock::time_point(chrono::seconds(i[4].toInt())); +// n->lastAttempted = chrono::system_clock::time_point(chrono::seconds(i[5].toInt())); +// n->failedAttempts = i[6].toInt(); +// n->lastDisconnect = (DisconnectReason)i[7].toInt(); +// n->score = (int)i[8].toInt(); +// n->rating = (int)i[9].toInt(); } } } @@ -742,7 +766,7 @@ void Host::restoreNodes(bytesConstRef _b) ep = bi::tcp::endpoint(bi::address_v4(i[0].toArray()), i[1].toInt()); else ep = bi::tcp::endpoint(bi::address_v6(i[0].toArray()), i[1].toInt()); - auto n = noteNode(id, ep); +// auto n = noteNode(id, ep); } } } diff --git a/libp2p/Host.h b/libp2p/Host.h index 817a844cd..edfa79df3 100644 --- a/libp2p/Host.h +++ b/libp2p/Host.h @@ -56,7 +56,7 @@ struct NodeInfo NodeId id; ///< Their id/public key. unsigned index; ///< Index into m_nodesList - // p2p: move to NodeEndpoint + // p2p: move to NodeIPEndpoint bi::tcp::endpoint address; ///< As reported from the node itself. // p2p: This information is relevant to the network-stack, ex: firewall, rather than node itself @@ -73,14 +73,14 @@ struct NodeInfo int score = 0; ///< All time cumulative. int rating = 0; ///< Trending. - // p2p: move to NodeEndpoint + // p2p: move to NodeIPEndpoint int secondsSinceLastConnected() const { return lastConnected == std::chrono::system_clock::time_point() ? -1 : (int)std::chrono::duration_cast(std::chrono::system_clock::now() - lastConnected).count(); } - // p2p: move to NodeEndpoint + // p2p: move to NodeIPEndpoint int secondsSinceLastAttempted() const { return lastAttempted == std::chrono::system_clock::time_point() ? -1 : (int)std::chrono::duration_cast(std::chrono::system_clock::now() - lastAttempted).count(); } - // p2p: move to NodeEndpoint + // p2p: move to NodeIPEndpoint unsigned fallbackSeconds() const; - // p2p: move to NodeEndpoint + // p2p: move to NodeIPEndpoint bool shouldReconnect() const { return std::chrono::system_clock::now() > lastAttempted + std::chrono::seconds(fallbackSeconds()); } // p2p: This has two meanings now. It's possible UDP works but TPC is down (unable to punch hole). @@ -114,6 +114,7 @@ using Nodes = std::vector; * @brief The Host class * Capabilities should be registered prior to startNetwork, since m_capabilities is not thread-safe. * @todo determinePublic: ipv6, udp + * @todo handle conflict if addNode/requireNode called and Node already exists w/conflicting tcp or udp port */ class Host: public Worker { @@ -128,6 +129,9 @@ public: /// Will block on network process events. virtual ~Host(); + /// Default host for current version of client. + static std::string pocHost(); + /// Basic peer network protocol version. unsigned protocolVersion() const; @@ -137,10 +141,12 @@ public: bool haveCapability(CapDesc const& _name) const { return m_capabilities.count(_name) != 0; } CapDescs caps() const { CapDescs ret; for (auto const& i: m_capabilities) ret.push_back(i.first); return ret; } template std::shared_ptr cap() const { try { return std::static_pointer_cast(m_capabilities.at(std::make_pair(T::staticName(), T::staticVersion()))); } catch (...) { return nullptr; } } + + /// Manually add node. + void addNode(NodeId const& _node, std::string const& _addr, unsigned short _tcpPort = 30303, unsigned short _udpPort = 30303); /// Connect to a peer explicitly. - static std::string pocHost(); - void connect(NodeId const& _node, std::string const& _addr, unsigned short _port = 30303) noexcept; + void connect(NodeId const& _node, std::string const& _addr, unsigned short _tcpPort = 30303, unsigned short _udpPort = 30303) noexcept; void connect(NodeId const& _node, bi::tcp::endpoint const& _ep); void connect(std::shared_ptr const& _n); @@ -192,6 +198,8 @@ public: std::shared_ptr node(NodeId _id) const { if (m_nodes.count(_id)) return m_nodes.at(_id); return std::shared_ptr(); } private: + KeyPair getHostIdentifier(); + /// Populate m_peerAddresses with available public addresses. void determinePublic(std::string const& _publicAddress, bool _upnp); @@ -213,9 +221,11 @@ private: /// Shutdown network. Not thread-safe; to be called only by worker. virtual void doneWorking(); + + /// Add node + void addNode(Node const& _nodeInfo) { m_nodeTable->addNode(_nodeInfo); } - std::shared_ptr noteNode(NodeId _id, bi::tcp::endpoint _a, NodeId _oldId = NodeId()); - Nodes potentialPeers(RangeMask const& _known); +// Nodes potentialPeers(RangeMask const& _known); bool m_run = false; ///< Whether network is running. std::mutex x_runTimer; ///< Start/stop mutex. @@ -254,10 +264,10 @@ private: /// TODO: mutex; replace with nodeTable std::map > m_nodes; - /// A list of node IDs. This contains every index from m_nodes; the order is guaranteed to remain the same. - std::vector m_nodesList; +// /// A list of node IDs. This contains every index from m_nodes; the order is guaranteed to remain the same. +// std::vector m_nodesList; - RangeMask m_private; ///< Indices into m_nodesList over to which nodes are private. +// RangeMask m_private; ///< Indices into m_nodesList over to which nodes are private. unsigned m_idealPeerCount = 5; ///< Ideal number of peers to be connected to. diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index 699f0d0c9..53acc9dbe 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -24,8 +24,8 @@ using namespace std; using namespace dev; using namespace dev::p2p; -NodeEntry::NodeEntry(Node _src, Public _pubk, NodeDefaultEndpoint _gw): Node(_pubk, _gw), distance(NodeTable::dist(_src.id,_pubk)) {} -NodeEntry::NodeEntry(Node _src, Public _pubk, bi::udp::endpoint _udp): Node(_pubk, NodeDefaultEndpoint(_udp)), distance(NodeTable::dist(_src.id,_pubk)) {} +NodeEntry::NodeEntry(Node _src, Public _pubk, NodeIPEndpoint _gw): Node(_pubk, _gw), distance(NodeTable::dist(_src.id,_pubk)) {} +NodeEntry::NodeEntry(Node _src, Public _pubk, bi::udp::endpoint _udp): Node(_pubk, NodeIPEndpoint(_udp)), distance(NodeTable::dist(_src.id,_pubk)) {} NodeTable::NodeTable(ba::io_service& _io, KeyPair _alias, uint16_t _udp, bi::tcp::endpoint _ep): m_node(Node(_alias.pub(), bi::udp::endpoint())), @@ -240,15 +240,24 @@ void NodeTable::evict(shared_ptr _leastSeen, shared_ptr _n } shared_ptr NodeTable::addNode(Public const& _pubk, bi::udp::endpoint const& _udp, bi::tcp::endpoint const& _tcp) +{ + auto node = Node(_pubk, NodeIPEndpoint(_udp, _tcp)); + return move(addNode(node)); +} + +shared_ptr NodeTable::addNode(Node const& _node) { shared_ptr ret; Guard l(x_nodes); - if (auto n = m_nodes[_pubk]) + if (auto n = m_nodes[_node.id]) ret = n; else { - ret.reset(new NodeEntry(m_node, _pubk, _udp)); - m_nodes[_pubk] = ret; + ret.reset(new NodeEntry(m_node, _node.id, NodeIPEndpoint(_node.endpoint.udp, _node.endpoint.tcp))); + m_nodes[_node.id] = ret; + PingNode p(_node.endpoint.udp, m_node.endpoint.udp.address().to_string(), m_node.endpoint.udp.port()); + p.sign(m_secret); + m_socketPtr->send(p); } return move(ret); } diff --git a/libp2p/NodeTable.h b/libp2p/NodeTable.h index d209018a2..89bd68be1 100644 --- a/libp2p/NodeTable.h +++ b/libp2p/NodeTable.h @@ -31,37 +31,45 @@ namespace dev namespace p2p { -struct NodeDefaultEndpoint +/** + * @brief IPv4,UDP/TCP endpoints. + */ +struct NodeIPEndpoint { - NodeDefaultEndpoint(bi::udp::endpoint _udp): udp(_udp) {} - NodeDefaultEndpoint(bi::tcp::endpoint _tcp): tcp(_tcp) {} - NodeDefaultEndpoint(bi::udp::endpoint _udp, bi::tcp::endpoint _tcp): udp(_udp), tcp(_tcp) {} - + NodeIPEndpoint(bi::udp::endpoint _udp): udp(_udp) {} + NodeIPEndpoint(bi::tcp::endpoint _tcp): tcp(_tcp) {} + NodeIPEndpoint(bi::udp::endpoint _udp, bi::tcp::endpoint _tcp): udp(_udp), tcp(_tcp) {} + bi::udp::endpoint udp; bi::tcp::endpoint tcp; }; struct Node { - Node(Public _pubk, NodeDefaultEndpoint _udp): id(_pubk), endpoint(_udp) {} - Node(Public _pubk, bi::udp::endpoint _udp): Node(_pubk, NodeDefaultEndpoint(_udp)) {} + Node(Public _pubk, NodeIPEndpoint _ip, bool _required = false): id(_pubk), endpoint(_ip), required(_required) {} + Node(Public _pubk, bi::udp::endpoint _udp, bool _required = false): Node(_pubk, NodeIPEndpoint(_udp), _required) {} virtual NodeId const& address() const { return id; } virtual Public const& publicKey() const { return id; } NodeId id; - NodeDefaultEndpoint endpoint; + + /// Endpoints by which we expect to reach node. + NodeIPEndpoint endpoint; + + /// If true, node will not be removed from Node list. + bool required = false; }; - + /** * NodeEntry * @brief Entry in Node Table */ struct NodeEntry: public Node { - NodeEntry(Node _src, Public _pubk, NodeDefaultEndpoint _gw); //: Node(_pubk, _gw), distance(dist(_src.id,_pubk)) {} - NodeEntry(Node _src, Public _pubk, bi::udp::endpoint _udp); //: Node(_pubk, NodeDefaultEndpoint(_udp)), distance(dist(_src.id,_pubk)) {} + NodeEntry(Node _src, Public _pubk, NodeIPEndpoint _gw); //: Node(_pubk, _gw), distance(dist(_src.id,_pubk)) {} + NodeEntry(Node _src, Public _pubk, bi::udp::endpoint _udp); //: Node(_pubk, NodeIPEndpoint(_udp)), distance(dist(_src.id,_pubk)) {} const unsigned distance; ///< Node's distance from _src (see constructor). }; @@ -131,9 +139,12 @@ public: static unsigned dist(NodeId const& _a, NodeId const& _b) { u512 d = _a ^ _b; unsigned ret; for (ret = 0; d >>= 1; ++ret) {}; return ret; } - /// Add node details and attempt adding to node table if node responds to ping. NodeEntry will immediately be returned and may be used for required connectivity. + /// Add node. Node will be pinged if it's not already known. std::shared_ptr addNode(Public const& _pubk, bi::udp::endpoint const& _udp, bi::tcp::endpoint const& _tcp = bi::tcp::endpoint()); + /// Add node. Node will be pinged if it's not already known. + std::shared_ptr addNode(Node const& _node); + void join(); NodeEntry root() const { return NodeEntry(m_node, m_node.publicKey(), m_node.endpoint.udp); } @@ -142,7 +153,6 @@ public: NodeEntry operator[](NodeId _id); - protected: struct NodeBucket { @@ -195,10 +205,10 @@ protected: Secret m_secret; ///< This nodes secret key. mutable Mutex x_nodes; ///< Mutable for thread-safe copy in nodes() const. - std::map> m_nodes; ///< NodeId -> Node table + std::map> m_nodes; ///< Nodes mutable Mutex x_state; - std::array m_state; ///< State table of binned nodes. + std::array m_state; ///< State of p2p node network. Mutex x_evictions; std::deque m_evictions; ///< Eviction timeouts. diff --git a/libp2p/Session.cpp b/libp2p/Session.cpp index c31335357..c6797b69c 100644 --- a/libp2p/Session.cpp +++ b/libp2p/Session.cpp @@ -48,7 +48,7 @@ Session::Session(Host* _s, bi::tcp::socket _socket, std::shared_ptr co Session::~Session() { - // TODO P2P: revisit (refactored from previous logic) + // TODO: P2P revisit (refactored from previous logic) if (m_node && !(id() && !isPermanentProblem(m_node->lastDisconnect) && !m_node->dead)) m_node->lastConnected = m_node->lastAttempted - chrono::seconds(1); @@ -87,7 +87,7 @@ int Session::rating() const return m_node->rating; } -// TODO P2P: integration: session->? should be unavailable when socket isn't open +// TODO: P2P integration: session->? should be unavailable when socket isn't open bi::tcp::endpoint Session::endpoint() const { if (m_socket.is_open() && m_node) @@ -117,7 +117,7 @@ template vector randomSelection(vector const& _t, unsigned _n) return ret; } -// TODO P2P: integration: replace w/asio post -> serviceNodesRequest() +// TODO: P2P integration: replace w/asio post -> serviceNodesRequest() void Session::ensureNodesRequested() { if (isOpen() && !m_weRequestedNodes) @@ -133,7 +133,9 @@ void Session::serviceNodesRequest() if (!m_theyRequestedNodes) return; - auto peers = m_server->potentialPeers(m_knownNodes); +// TODO: P2P +// auto peers = m_server->potentialPeers(m_knownNodes); + Nodes peers; if (peers.empty()) { addNote("peers", "requested"); @@ -210,14 +212,16 @@ bool Session::interpret(RLP const& _r) return true; } - // TODO P2P: first pass, implement signatures. if signature fails, drop connection. if egress, flag node's endpoint as stale. - // TODO P2P: remove oldid - // TODO P2P: with encrypted transport the handshake will fail and we won't get here - m_node = m_server->noteNode(id, bi::tcp::endpoint(m_socket.remote_endpoint().address(), listenPort), m_node->id); + // TODO: P2P first pass, implement signatures. if signature fails, drop connection. if egress, flag node's endpoint as stale. + // Discussion: Most this to Host so we consolidate authentication logic and eschew peer deduplication logic. + // TODO: P2P Move all node-lifecycle information into Host. Determine best way to handle peer-lifecycle properties vs node lifecycle. + // TODO: P2P remove oldid + // TODO: P2P with encrypted transport the handshake will fail and we won't get here +// m_node = m_server->noteNode(m_node->id, bi::tcp::endpoint(m_socket.remote_endpoint().address(), listenPort)); if (m_node->isOffline()) m_node->lastConnected = chrono::system_clock::now(); - - // TODO P2P: introduce map of nodes we've given to this node (if GetPeers/Peers stays in TCP) +// +// // TODO: P2P introduce map of nodes we've given to this node (if GetPeers/Peers stays in TCP) m_knownNodes.extendAll(m_node->index); m_knownNodes.unionWith(m_node->index); @@ -334,7 +338,9 @@ bool Session::interpret(RLP const& _r) // OK passed all our checks. Assume it's good. addRating(1000); - m_server->noteNode(id, ep); + + // TODO: P2P change to addNode() +// m_server->noteNode(id, ep); clogS(NetTriviaDetail) << "New peer: " << ep << "(" << id .abridged()<< ")"; CONTINUE:; } From 22efa458330bb9297d82c388d3bb6456e1cb23d5 Mon Sep 17 00:00:00 2001 From: subtly Date: Thu, 8 Jan 2015 22:20:11 +0100 Subject: [PATCH 004/213] remove private ports from upnp port range --- libp2p/UPnP.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libp2p/UPnP.cpp b/libp2p/UPnP.cpp index 42868d67a..36795c540 100644 --- a/libp2p/UPnP.cpp +++ b/libp2p/UPnP.cpp @@ -132,7 +132,7 @@ int UPnP::addRedirect(char const* _addr, int _port) srand(time(NULL)); for (unsigned i = 0; i < 10; ++i) { - _port = rand() % (65535 - 1024) + 1024; + _port = rand() % (32768 - 1024) + 1024; sprintf(ext_port_str, "%d", _port); if (!UPNP_AddPortMapping(m_urls->controlURL, m_data->first.servicetype, ext_port_str, port_str, _addr, "ethereum", "TCP", NULL, NULL)) return _port; From 40e07b312a973992317bf7fc19857bad0596a482 Mon Sep 17 00:00:00 2001 From: subtly Date: Thu, 8 Jan 2015 22:26:21 +0100 Subject: [PATCH 005/213] Consolidate use of pingAll into keepAlivePeers. Add bool operators for Node and NodeIPEndpoint population. NodeTable returns Node instead of NodeEntry (subject to change). Begin transition from NodeInfo to NodeTable Node. --- libp2p/Host.cpp | 26 +++++++++++++------------- libp2p/Host.h | 4 ++-- libp2p/NodeTable.cpp | 5 +++-- libp2p/NodeTable.h | 8 +++++++- test/peer.cpp | 2 +- 5 files changed, 26 insertions(+), 19 deletions(-) diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index 392d02dc4..5f756f2a5 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -401,7 +401,7 @@ void Host::connect(NodeId const& _node, std::string const& _addr, unsigned short assert(_node); - auto n = m_nodes[_node]; + auto n = (*m_nodeTable)[_node]; // TODO: refactor into async_resolve m_ioService.post([=]() @@ -619,14 +619,8 @@ void Host::run(boost::system::error_code const&) if (auto pp = p.second.lock()) pp->serviceNodesRequest(); - if (chrono::steady_clock::now() - m_lastPing > chrono::seconds(30)) // ping every 30s. - { - for (auto p: m_peers) - if (auto pp = p.second.lock()) - if (chrono::steady_clock::now() - pp->m_lastReceived > chrono::seconds(60)) - pp->disconnect(PingTimeout); - pingAll(); - } + if (chrono::steady_clock::now() - m_lastPing >= chrono::seconds(30)) // ping every 30s. + keepAlivePeers(); auto runcb = [this](boost::system::error_code const& error) -> void { run(error); }; m_timer->expires_from_now(boost::posix_time::milliseconds(c_timerInterval)); @@ -680,12 +674,18 @@ void Host::doWork() m_ioService.run(); } -void Host::pingAll() +void Host::keepAlivePeers() { RecursiveGuard l(x_peers); - for (auto& i: m_peers) - if (auto j = i.second.lock()) - j->ping(); + for (auto p: m_peers) + if (auto pp = p.second.lock()) + { + if (chrono::steady_clock::now() - pp->m_lastReceived >= chrono::seconds(60)) + pp->disconnect(PingTimeout); + else + pp->ping(); + } + m_lastPing = chrono::steady_clock::now(); } diff --git a/libp2p/Host.h b/libp2p/Host.h index edfa79df3..5892b5b0d 100644 --- a/libp2p/Host.h +++ b/libp2p/Host.h @@ -165,8 +165,8 @@ public: /// Get number of peers connected; equivalent to, but faster than, peers().size(). size_t peerCount() const { RecursiveGuard l(x_peers); return m_peers.size(); } - /// Ping the peers, to update the latency information. - void pingAll(); + /// Ping the peers to update the latency information and disconnect peers which have timed out. + void keepAlivePeers(); /// Get the port we're listening on currently. unsigned short listenPort() const { return m_tcpPublic.port(); } diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index 53acc9dbe..1b74abbda 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -77,10 +77,11 @@ list NodeTable::state() const return move(ret); } -NodeEntry NodeTable::operator[](NodeId _id) +Node NodeTable::operator[](NodeId _id) { Guard l(x_nodes); - return *m_nodes[_id]; + auto n = m_nodes[_id]; + return !!n ? *n : Node(); } void NodeTable::requestNeighbours(NodeEntry const& _node, NodeId _target) const diff --git a/libp2p/NodeTable.h b/libp2p/NodeTable.h index 89bd68be1..79ce6a9e3 100644 --- a/libp2p/NodeTable.h +++ b/libp2p/NodeTable.h @@ -36,16 +36,20 @@ namespace p2p */ struct NodeIPEndpoint { + NodeIPEndpoint(): udp(bi::udp::endpoint()), tcp(bi::tcp::endpoint()) {} NodeIPEndpoint(bi::udp::endpoint _udp): udp(_udp) {} NodeIPEndpoint(bi::tcp::endpoint _tcp): tcp(_tcp) {} NodeIPEndpoint(bi::udp::endpoint _udp, bi::tcp::endpoint _tcp): udp(_udp), tcp(_tcp) {} bi::udp::endpoint udp; bi::tcp::endpoint tcp; + + operator bool() const { return udp.address().is_unspecified() && tcp.address().is_unspecified(); } }; struct Node { + Node(): endpoint(NodeIPEndpoint()) {}; Node(Public _pubk, NodeIPEndpoint _ip, bool _required = false): id(_pubk), endpoint(_ip), required(_required) {} Node(Public _pubk, bi::udp::endpoint _udp, bool _required = false): Node(_pubk, NodeIPEndpoint(_udp), _required) {} @@ -59,6 +63,8 @@ struct Node /// If true, node will not be removed from Node list. bool required = false; + + operator bool() const { return (bool)id; } }; @@ -151,7 +157,7 @@ public: std::list nodes() const; std::list state() const; - NodeEntry operator[](NodeId _id); + Node operator[](NodeId _id); protected: struct NodeBucket diff --git a/test/peer.cpp b/test/peer.cpp index 70d03e9bf..d13ea97f3 100644 --- a/test/peer.cpp +++ b/test/peer.cpp @@ -55,7 +55,7 @@ int peerTest(int argc, char** argv) { this_thread::sleep_for(chrono::milliseconds(100)); if (!(i % 10)) - ph.pingAll(); + ph.keepAlivePeers(); } return 0; From 94c09508fd9d7495e91f57c333a56220a9060961 Mon Sep 17 00:00:00 2001 From: subtly Date: Sat, 10 Jan 2015 19:45:20 +0100 Subject: [PATCH 006/213] Merging in new data structure for nodes from node-table. End result will be consolidation into NodeId, Node (id and endpoints), NodeEntry (as in table), and Peer (connected node as in host). Rename PeerInfo to PeerSessionInfo. Rename NodeInfo to PeerInfo. PeerSessionInfo which is information about the Peer connection and will be split/merged into Node and PeerInfo. Add node-table callbacks for Host to perform connect node if there are not enough nodes. --- alethzero/MainWin.cpp | 2 +- libp2p/Common.h | 4 +- libp2p/Host.cpp | 342 ++++++++++++++++---------------------- libp2p/Host.h | 88 +++++----- libp2p/HostCapability.cpp | 4 +- libp2p/NodeTable.cpp | 55 +++--- libp2p/NodeTable.h | 44 ++++- libp2p/Session.cpp | 138 +++++++-------- libp2p/Session.h | 10 +- libwebthree/WebThree.cpp | 4 +- libwebthree/WebThree.h | 4 +- neth/main.cpp | 2 +- test/peer.cpp | 16 +- test/whisperTopic.cpp | 2 +- 14 files changed, 354 insertions(+), 361 deletions(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index b73a2cd0d..40663db8d 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -906,7 +906,7 @@ void Main::refreshNetwork() if (web3()->haveNetwork()) { map clients; - for (PeerInfo const& i: ps) + for (PeerSessionInfo const& i: ps) ui->peers->addItem(QString("[%8 %7] %3 ms - %1:%2 - %4 %5 %6") .arg(QString::fromStdString(i.host)) .arg(i.port) diff --git a/libp2p/Common.h b/libp2p/Common.h index d46c5eed1..059e1a64e 100644 --- a/libp2p/Common.h +++ b/libp2p/Common.h @@ -116,7 +116,7 @@ typedef std::pair CapDesc; typedef std::set CapDescSet; typedef std::vector CapDescs; -struct PeerInfo +struct PeerSessionInfo { NodeId id; std::string clientVersion; @@ -128,7 +128,7 @@ struct PeerInfo std::map notes; }; -using PeerInfos = std::vector; +using PeerSessionInfos = std::vector; } } diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index 5f756f2a5..243738918 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -38,6 +38,13 @@ using namespace std; using namespace dev; using namespace dev::p2p; +HostNodeTableHandler::HostNodeTableHandler(Host& _host): m_host(_host) {} + +void HostNodeTableHandler::processEvent(NodeId _n, NodeTableEventType _e) +{ + m_host.onNodeTableEvent(_n, _e); +} + Host::Host(std::string const& _clientVersion, NetworkPreferences const& _n, bool _start): Worker("p2p", 0), m_clientVersion(_clientVersion), @@ -116,8 +123,8 @@ void Host::doneWorking() for (unsigned n = 0;; n = 0) { { - RecursiveGuard l(x_peers); - for (auto i: m_peers) + RecursiveGuard l(x_sessions); + for (auto i: m_sessions) if (auto p = i.second.lock()) if (p->isOpen()) { @@ -139,8 +146,8 @@ void Host::doneWorking() m_ioService.reset(); // finally, clear out peers (in case they're lingering) - RecursiveGuard l(x_peers); - m_peers.clear(); + RecursiveGuard l(x_sessions); + m_sessions.clear(); } unsigned Host::protocolVersion() const @@ -150,12 +157,12 @@ unsigned Host::protocolVersion() const void Host::registerPeer(std::shared_ptr _s, CapDescs const& _caps) { - assert(!!_s->m_node); - assert(!!_s->m_node->id); + assert(!!_s->m_peer); + assert(!!_s->m_peer->id); { - RecursiveGuard l(x_peers); - m_peers[_s->m_node->id] = _s; + RecursiveGuard l(x_sessions); + m_sessions[_s->m_peer->id] = _s; } unsigned o = (unsigned)UserPacket; for (auto const& i: _caps) @@ -166,6 +173,34 @@ void Host::registerPeer(std::shared_ptr _s, CapDescs const& _caps) } } +void Host::onNodeTableEvent(NodeId _n, NodeTableEventType _e) +{ + if (_e == NodeEntryAdded) + { + auto n = (*m_nodeTable)[_n]; + if (n) + { + RecursiveGuard l(x_sessions); + auto p = m_peers[_n]; + if (!p) + { + m_peers[_n] = make_shared(); + p = m_peers[_n]; + p->id = _n; + } + p->address = n.endpoint.tcp; + + if (peerCount() < m_idealPeerCount) + connect(p); + } + } + else if (_e == NodeEntryRemoved) + { + RecursiveGuard l(x_sessions); + m_peers.erase(_n); + } +} + void Host::seal(bytes& _b) { _b[0] = 0x22; @@ -179,80 +214,6 @@ void Host::seal(bytes& _b) _b[7] = len & 0xff; } -// TODO: P2P port to NodeTable. (see noteNode calls, Session.cpp) -//shared_ptr Host::noteNode(NodeId _id, bi::tcp::endpoint _a) -//{ -// RecursiveGuard l(x_peers); -// if (_a.port() < 30300 || _a.port() > 30305) -// cwarn << "Weird port being recorded: " << _a.port(); -// -// if (_a.port() >= /*49152*/32768) -// { -// cwarn << "Private port being recorded - setting to 0"; -// _a = bi::tcp::endpoint(_a.address(), 0); -// } -// -// unsigned i; -// if (!m_nodes.count(_id)) -// { -// i = m_nodesList.size(); -// m_nodesList.push_back(_id); -// m_nodes[_id] = make_shared(); -// m_nodes[_id]->id = _id; -// m_nodes[_id]->index = i; -// } -// else -// i = m_nodes[_id]->index; -// m_nodes[_id]->address = _a; -// m_private.extendAll(i); -// if (!_a.port() || (isPrivateAddress(_a.address()) && !m_netPrefs.localNetworking)) -// m_private += i; -// else -// m_private -= i; -// -// return m_nodes[_id]; -//} - -// TODO: P2P base on target -// TODO: P2P store caps in NodeTable/NodeEntry -//Nodes Host::potentialPeers(RangeMask const& _known) -//{ -// RecursiveGuard l(x_peers); -// Nodes ret; -// -// // todo: if localnetworking is enabled it should only share peers if remote -// // is within the same network as our interfaces. -// // this requires flagging nodes when we receive them as to if they're on private network -// auto ns = (m_netPrefs.localNetworking ? _known : (m_private + _known)).inverted(); -// for (auto i: ns) -// ret.push_back(*m_nodes[m_nodesList[i]]); -// return ret; -//} - -KeyPair Host::getHostIdentifier() -{ - static string s_file(getDataDir() + "/host"); - static mutex s_x; - lock_guard l(s_x); - - h256 secret; - bytes b = contents(s_file); - if (b.size() == 32) - memcpy(secret.data(), b.data(), 32); - else - { - // todo: replace w/user entropy; abstract to devcrypto - std::mt19937_64 s_eng(time(0) + chrono::high_resolution_clock::now().time_since_epoch().count()); - std::uniform_int_distribution d(0, 255); - for (unsigned i = 0; i < 32; ++i) - secret[i] = (byte)d(s_eng); - } - - if (!secret) - BOOST_THROW_EXCEPTION(crypto::InvalidState()); - return move(KeyPair(move(secret))); -} - void Host::determinePublic(string const& _publicAddress, bool _upnp) { m_peerAddresses.clear(); @@ -324,15 +285,16 @@ void Host::runAcceptor() { clog(NetConnect) << "Listening on local port " << m_listenPort << " (public: " << m_tcpPublic << ")"; m_accepting = true; - m_socket.reset(new bi::tcp::socket(m_ioService)); - m_tcp4Acceptor.async_accept(*m_socket, [=](boost::system::error_code ec) + + bi::tcp::socket* s = new bi::tcp::socket(m_ioService); + m_tcp4Acceptor.async_accept(*s, [=](boost::system::error_code ec) { bool success = false; if (!ec) { try { - doHandshake(m_socket.release()); + doHandshake(s); success = true; } catch (Exception const& _e) @@ -345,27 +307,29 @@ void Host::runAcceptor() } } - if (!success && m_socket->is_open()) + if (!success && s->is_open()) { boost::system::error_code ec; - m_socket->shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec); - m_socket->close(); + s->shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec); + s->close(); } m_accepting = false; + delete s; + if (ec.value() < 1) runAcceptor(); }); } } -void Host::doHandshake(bi::tcp::socket* _socket, NodeId _egressNodeId) +void Host::doHandshake(bi::tcp::socket* _socket, NodeId _nodeId) { try { clog(NetConnect) << "Accepting connection for " << _socket->remote_endpoint(); } catch (...){} - auto p = std::make_shared(this, std::move(*_socket), m_nodes[_egressNodeId]); + auto p = std::make_shared(this, std::move(*_socket), m_peers[_nodeId]); p->start(); } @@ -378,6 +342,15 @@ string Host::pocHost() void Host::addNode(NodeId const& _node, std::string const& _addr, unsigned short _tcpPeerPort, unsigned short _udpNodePort) { + if (_tcpPeerPort < 30300 || _tcpPeerPort > 30305) + cwarn << "Weird port being recorded: " << _tcpPeerPort; + + if (_tcpPeerPort >= /*49152*/32768) + { + cwarn << "Private port being recorded - setting to 0"; + _tcpPeerPort = 0; + } + boost::system::error_code ec; bi::address addr = bi::address::from_string(_addr, ec); if (ec) @@ -394,59 +367,25 @@ void Host::addNode(NodeId const& _node, std::string const& _addr, unsigned short addNode(Node(_node, NodeIPEndpoint(bi::udp::endpoint(addr, _udpNodePort), bi::tcp::endpoint(addr, _tcpPeerPort)))); } -void Host::connect(NodeId const& _node, std::string const& _addr, unsigned short _peerPort, unsigned short _nodePort) noexcept +void Host::connect(std::shared_ptr const& _n) { if (!m_run) return; - assert(_node); - - auto n = (*m_nodeTable)[_node]; + if (havePeerSession(_n->id)) + { + clog(NetWarn) << "Aborted connect. Node already connected."; + return; + } - // TODO: refactor into async_resolve - m_ioService.post([=]() + if (!m_nodeTable->haveNode(_n->id)) { - for (auto first: {true, false}) - { - try - { - bi::tcp::endpoint ep; - if (first) - { - bi::tcp::resolver r(m_ioService); - ep = r.resolve({_addr, toString(_peerPort)})->endpoint(); - } - else - ep = bi::tcp::endpoint(bi::address::from_string(_addr), _peerPort); - - if (!n) - m_nodes[_node] = make_shared(); - m_nodes[_node]->id = _node; - m_nodes[_node]->address = ep; - connect(m_nodes[_node]); - break; - } - catch (Exception const& _e) - { - // Couldn't connect - clog(NetConnect) << "Bad host " << _addr << "\n" << diagnostic_information(_e); - } - catch (exception const& e) - { - // Couldn't connect - clog(NetConnect) << "Bad host " << _addr << " (" << e.what() << ")"; - } - } - }); -} - -void Host::connect(std::shared_ptr const& _n) -{ - if (!m_run) + clog(NetWarn) << "Aborted connect. Node not in node table."; return; + } // prevent concurrently connecting to a node - NodeInfo *nptr = _n.get(); + PeerInfo *nptr = _n.get(); { Guard l(x_pendingNodeConns); if (m_pendingNodeConns.count(nptr)) @@ -457,48 +396,32 @@ void Host::connect(std::shared_ptr const& _n) clog(NetConnect) << "Attempting connection to node" << _n->id.abridged() << "@" << _n->address << "from" << id().abridged(); _n->lastAttempted = std::chrono::system_clock::now(); _n->failedAttempts++; + bi::tcp::socket* s = new bi::tcp::socket(m_ioService); - - auto n = node(_n->id); - if (n) - s->async_connect(_n->address, [=](boost::system::error_code const& ec) + s->async_connect(_n->address, [=](boost::system::error_code const& ec) + { + if (ec) { - if (ec) - { - clog(NetConnect) << "Connection refused to node" << _n->id.abridged() << "@" << _n->address << "(" << ec.message() << ")"; - _n->lastDisconnect = TCPError; - _n->lastAttempted = std::chrono::system_clock::now(); - } - else - { - clog(NetConnect) << "Connected to" << _n->id.abridged() << "@" << _n->address; - _n->lastConnected = std::chrono::system_clock::now(); - auto p = make_shared(this, std::move(*s), n); - p->start(); - } - delete s; - Guard l(x_pendingNodeConns); - m_pendingNodeConns.erase(nptr); - }); - else - clog(NetWarn) << "Aborted connect. Node not in node table."; -} - -bool Host::havePeer(NodeId _id) const -{ - RecursiveGuard l(x_peers); - - // Remove dead peers from list. - for (auto i = m_peers.begin(); i != m_peers.end();) - if (i->second.lock().get()) - ++i; + clog(NetConnect) << "Connection refused to node" << _n->id.abridged() << "@" << _n->address << "(" << ec.message() << ")"; + _n->lastDisconnect = TCPError; + _n->lastAttempted = std::chrono::system_clock::now(); + } else - i = m_peers.erase(i); - - return !!m_peers.count(_id); + { + clog(NetConnect) << "Connected to" << _n->id.abridged() << "@" << _n->address; + + _n->lastConnected = std::chrono::system_clock::now(); + auto p = make_shared(this, std::move(*s), _n); + p->start(); + + } + delete s; + Guard l(x_pendingNodeConns); + m_pendingNodeConns.erase(nptr); + }); } -unsigned NodeInfo::fallbackSeconds() const +unsigned PeerInfo::fallbackSeconds() const { switch (lastDisconnect) { @@ -524,27 +447,27 @@ unsigned NodeInfo::fallbackSeconds() const // TODO: P2P migrate grow/prunePeers into 'maintainPeers' & evaluate reputation instead of availability. schedule via deadline timer. //void Host::growPeers() //{ -// RecursiveGuard l(x_peers); -// int morePeers = (int)m_idealPeerCount - m_peers.size(); +// RecursiveGuard l(x_sessions); +// int morePeers = (int)m_idealPeerCount - m_sessions.size(); // if (morePeers > 0) // { // auto toTry = m_ready; // if (!m_netPrefs.localNetworking) // toTry -= m_private; -// set ns; +// set ns; // for (auto i: toTry) // if (m_nodes[m_nodesList[i]]->shouldReconnect()) // ns.insert(*m_nodes[m_nodesList[i]]); // // if (ns.size()) -// for (NodeInfo const& i: ns) +// for (PeerInfo const& i: ns) // { // connect(m_nodes[i.id]); // if (!--morePeers) // return; // } // else -// for (auto const& i: m_peers) +// for (auto const& i: m_sessions) // if (auto p = i.second.lock()) // p->ensureNodesRequested(); // } @@ -552,17 +475,17 @@ unsigned NodeInfo::fallbackSeconds() const // //void Host::prunePeers() //{ -// RecursiveGuard l(x_peers); +// RecursiveGuard l(x_sessions); // // We'll keep at most twice as many as is ideal, halfing what counts as "too young to kill" until we get there. // set dc; -// for (unsigned old = 15000; m_peers.size() - dc.size() > m_idealPeerCount * 2 && old > 100; old /= 2) -// if (m_peers.size() - dc.size() > m_idealPeerCount) +// for (unsigned old = 15000; m_sessions.size() - dc.size() > m_idealPeerCount * 2 && old > 100; old /= 2) +// if (m_sessions.size() - dc.size() > m_idealPeerCount) // { // // look for worst peer to kick off // // first work out how many are old enough to kick off. // shared_ptr worst; // unsigned agedPeers = 0; -// for (auto i: m_peers) +// for (auto i: m_sessions) // if (!dc.count(i.first)) // if (auto p = i.second.lock()) // if (/*(m_mode != NodeMode::Host || p->m_caps != 0x01) &&*/ chrono::steady_clock::now() > p->m_connect + chrono::milliseconds(old)) // don't throw off new peers; peer-servers should never kick off other peer-servers. @@ -578,21 +501,21 @@ unsigned NodeInfo::fallbackSeconds() const // } // // // Remove dead peers from list. -// for (auto i = m_peers.begin(); i != m_peers.end();) +// for (auto i = m_sessions.begin(); i != m_sessions.end();) // if (i->second.lock().get()) // ++i; // else -// i = m_peers.erase(i); +// i = m_sessions.erase(i); //} -PeerInfos Host::peers() const +PeerSessionInfos Host::peers() const { if (!m_run) - return PeerInfos(); + return PeerSessionInfos(); - std::vector ret; - RecursiveGuard l(x_peers); - for (auto& i: m_peers) + std::vector ret; + RecursiveGuard l(x_sessions); + for (auto& i: m_sessions) if (auto j = i.second.lock()) if (j->m_socket.is_open()) ret.push_back(j->m_info); @@ -615,7 +538,7 @@ void Host::run(boost::system::error_code const&) return; } - for (auto p: m_peers) + for (auto p: m_sessions) if (auto pp = p.second.lock()) pp->serviceNodesRequest(); @@ -658,7 +581,8 @@ void Host::startedWorking() runAcceptor(); if (!m_tcpPublic.address().is_unspecified()) - m_nodeTable.reset(new NodeTable(m_ioService, m_key, m_listenPort, m_tcpPublic)); + // TODO: add m_tcpPublic endpoint; sort out endpoint stuff for nodetable + m_nodeTable.reset(new NodeTable(m_ioService, m_key, m_listenPort)); else m_nodeTable.reset(new NodeTable(m_ioService, m_key, m_listenPort > 0 ? m_listenPort : 30303)); } @@ -676,8 +600,8 @@ void Host::doWork() void Host::keepAlivePeers() { - RecursiveGuard l(x_peers); - for (auto p: m_peers) + RecursiveGuard l(x_sessions); + for (auto p: m_sessions) if (auto pp = p.second.lock()) { if (chrono::steady_clock::now() - pp->m_lastReceived >= chrono::seconds(60)) @@ -694,10 +618,10 @@ bytes Host::saveNodes() const RLPStream nodes; int count = 0; { - RecursiveGuard l(x_peers); - for (auto const& i: m_nodes) + RecursiveGuard l(x_sessions); + for (auto const& i: m_peers) { - NodeInfo const& n = *(i.second); + PeerInfo const& n = *(i.second); // TODO: PoC-7: Figure out why it ever shares these ports.//n.address.port() >= 30300 && n.address.port() <= 30305 && if (!n.dead && chrono::system_clock::now() - n.lastConnected < chrono::seconds(3600 * 48) && n.address.port() > 0 && n.address.port() < /*49152*/32768 && n.id != id() && !isPrivateAddress(n.address.address())) { @@ -722,7 +646,7 @@ bytes Host::saveNodes() const void Host::restoreNodes(bytesConstRef _b) { - RecursiveGuard l(x_peers); + RecursiveGuard l(x_sessions); RLP r(_b); if (r.itemCount() > 0 && r[0].isInt()) switch (r[0].toInt()) @@ -740,7 +664,7 @@ void Host::restoreNodes(bytesConstRef _b) else ep = bi::tcp::endpoint(bi::address_v6(i[0].toArray()), i[1].toInt()); auto id = (NodeId)i[2]; - if (!m_nodes.count(id)) + if (!m_peers.count(id)) { //// auto o = (Origin)i[3].toInt(); // auto n = noteNode(id, ep); @@ -759,7 +683,7 @@ void Host::restoreNodes(bytesConstRef _b) for (auto i: r) { auto id = (NodeId)i[2]; - if (!m_nodes.count(id)) + if (!m_peers.count(id)) { bi::tcp::endpoint ep; if (i[0].itemCount() == 4) @@ -770,3 +694,27 @@ void Host::restoreNodes(bytesConstRef _b) } } } + +KeyPair Host::getHostIdentifier() +{ + static string s_file(getDataDir() + "/host"); + static mutex s_x; + lock_guard l(s_x); + + h256 secret; + bytes b = contents(s_file); + if (b.size() == 32) + memcpy(secret.data(), b.data(), 32); + else + { + // todo: replace w/user entropy; abstract to devcrypto + std::mt19937_64 s_eng(time(0) + chrono::high_resolution_clock::now().time_since_epoch().count()); + std::uniform_int_distribution d(0, 255); + for (unsigned i = 0; i < 32; ++i) + secret[i] = (byte)d(s_eng); + } + + if (!secret) + BOOST_THROW_EXCEPTION(crypto::InvalidState()); + return move(KeyPair(move(secret))); +} diff --git a/libp2p/Host.h b/libp2p/Host.h index 5892b5b0d..097b07433 100644 --- a/libp2p/Host.h +++ b/libp2p/Host.h @@ -51,7 +51,7 @@ namespace p2p class Host; -struct NodeInfo +struct PeerInfo { NodeId id; ///< Their id/public key. unsigned index; ///< Index into m_nodesList @@ -88,7 +88,7 @@ struct NodeInfo bool isOffline() const { return lastAttempted > lastConnected; } // p2p: Remove (in favor of lru eviction and sub-protocol ratings). - bool operator<(NodeInfo const& _n) const + bool operator<(PeerInfo const& _n) const { if (isOffline() != _n.isOffline()) return isOffline(); @@ -108,19 +108,30 @@ struct NodeInfo } }; -using Nodes = std::vector; +using Nodes = std::vector; + +class Host; +class HostNodeTableHandler: public NodeTableEventHandler +{ + HostNodeTableHandler(Host& _host); + virtual void processEvent(NodeId _n, NodeTableEventType _e); + Host& m_host; +}; + /** * @brief The Host class * Capabilities should be registered prior to startNetwork, since m_capabilities is not thread-safe. + * @todo gracefully disconnect peer if peer already connected * @todo determinePublic: ipv6, udp * @todo handle conflict if addNode/requireNode called and Node already exists w/conflicting tcp or udp port */ class Host: public Worker { + friend class HostNodeTableHandler; friend class Session; friend class HostCapabilityFace; - friend struct NodeInfo; + friend struct PeerInfo; public: /// Start server, listening for connections on the given port. @@ -142,31 +153,19 @@ public: CapDescs caps() const { CapDescs ret; for (auto const& i: m_capabilities) ret.push_back(i.first); return ret; } template std::shared_ptr cap() const { try { return std::static_pointer_cast(m_capabilities.at(std::make_pair(T::staticName(), T::staticVersion()))); } catch (...) { return nullptr; } } - /// Manually add node. - void addNode(NodeId const& _node, std::string const& _addr, unsigned short _tcpPort = 30303, unsigned short _udpPort = 30303); - - /// Connect to a peer explicitly. - void connect(NodeId const& _node, std::string const& _addr, unsigned short _tcpPort = 30303, unsigned short _udpPort = 30303) noexcept; - void connect(NodeId const& _node, bi::tcp::endpoint const& _ep); - void connect(std::shared_ptr const& _n); - - /// @returns true iff we have a peer of the given id. - bool havePeer(NodeId _id) const; - + bool havePeerSession(NodeId _id) { RecursiveGuard l(x_sessions); if (m_sessions.count(_id)) return !!m_sessions[_id].lock(); else return false; } + + /// Add node. + void addNode(NodeId const& _node, std::string const& _addr, unsigned short _tcpPort, unsigned short _udpPort); + /// Set ideal number of peers. void setIdealPeerCount(unsigned _n) { m_idealPeerCount = _n; } - - /// p2p: template? - void setIdealPeerCount(HostCapabilityFace* _cap, unsigned _n) { m_capIdealPeerCount[_cap->capDesc()] = _n; } /// Get peer information. - PeerInfos peers() const; + PeerSessionInfos peers() const; /// Get number of peers connected; equivalent to, but faster than, peers().size(). - size_t peerCount() const { RecursiveGuard l(x_peers); return m_peers.size(); } - - /// Ping the peers to update the latency information and disconnect peers which have timed out. - void keepAlivePeers(); + size_t peerCount() const { RecursiveGuard l(x_sessions); return m_peers.size(); } /// Get the port we're listening on currently. unsigned short listenPort() const { return m_tcpPublic.port(); } @@ -177,7 +176,8 @@ public: /// Deserialise the data and populate the set of known peers. void restoreNodes(bytesConstRef _b); - Nodes nodes() const { RecursiveGuard l(x_peers); Nodes ret; for (auto const& i: m_nodes) ret.push_back(*i.second); return ret; } + // TODO: P2P this should be combined with peers into a HostStat object of some kind; coalesce data, as it's only used for status information. + Nodes nodes() const { RecursiveGuard l(x_sessions); Nodes ret; for (auto const& i: m_peers) ret.push_back(*i.second); return ret; } void setNetworkPreferences(NetworkPreferences const& _p) { auto had = isStarted(); if (had) stop(); m_netPrefs = _p; if (had) start(); } @@ -195,14 +195,20 @@ public: void registerPeer(std::shared_ptr _s, CapDescs const& _caps); - std::shared_ptr node(NodeId _id) const { if (m_nodes.count(_id)) return m_nodes.at(_id); return std::shared_ptr(); } +// std::shared_ptr node(NodeId _id) const { if (m_nodes.count(_id)) return m_nodes.at(_id); return std::shared_ptr(); } + +protected: + void onNodeTableEvent(NodeId _n, NodeTableEventType _e); private: - KeyPair getHostIdentifier(); - /// Populate m_peerAddresses with available public addresses. void determinePublic(std::string const& _publicAddress, bool _upnp); + void connect(std::shared_ptr const& _n); + + /// Ping the peers to update the latency information and disconnect peers which have timed out. + void keepAlivePeers(); + /// Called only from startedWorking(). void runAcceptor(); @@ -223,9 +229,10 @@ private: virtual void doneWorking(); /// Add node - void addNode(Node const& _nodeInfo) { m_nodeTable->addNode(_nodeInfo); } + void addNode(Node const& _node) { m_nodeTable->addNode(_node); } -// Nodes potentialPeers(RangeMask const& _known); + /// Get or create host identifier (KeyPair). + KeyPair getHostIdentifier(); bool m_run = false; ///< Whether network is running. std::mutex x_runTimer; ///< Start/stop mutex. @@ -241,33 +248,24 @@ private: ba::io_service m_ioService; ///< IOService for network stuff. bi::tcp::acceptor m_tcp4Acceptor; ///< Listening acceptor. - std::unique_ptr m_socket; ///< Listening socket. std::unique_ptr m_timer; ///< Timer which, when network is running, calls scheduler() every c_timerInterval ms. static const unsigned c_timerInterval = 100; ///< Interval which m_timer is run when network is connected. - std::set m_pendingNodeConns; /// Used only by connect(NodeInfo&) to limit concurrently connecting to same node. See connect(shared_ptrconst&). + std::set m_pendingNodeConns; /// Used only by connect(PeerInfo&) to limit concurrently connecting to same node. See connect(shared_ptrconst&). Mutex x_pendingNodeConns; bi::tcp::endpoint m_tcpPublic; ///< Our public listening endpoint. KeyPair m_key; ///< Our unique ID. std::shared_ptr m_nodeTable; ///< Node table (uses kademlia-like discovery). - std::map m_capIdealPeerCount; ///< Ideal peer count for capability. - - mutable RecursiveMutex x_peers; + std::map> m_peers; + + mutable RecursiveMutex x_sessions; + /// The nodes to which we are currently connected. /// Mutable because we flush zombie entries (null-weakptrs) as regular maintenance from a const method. - mutable std::map> m_peers; - - /// Nodes to which we may connect (or to which we have connected). - /// TODO: mutex; replace with nodeTable - std::map > m_nodes; - -// /// A list of node IDs. This contains every index from m_nodes; the order is guaranteed to remain the same. -// std::vector m_nodesList; - -// RangeMask m_private; ///< Indices into m_nodesList over to which nodes are private. + mutable std::map> m_sessions; unsigned m_idealPeerCount = 5; ///< Ideal number of peers to be connected to. @@ -280,6 +278,6 @@ private: bool m_accepting = false; }; - + } } diff --git a/libp2p/HostCapability.cpp b/libp2p/HostCapability.cpp index 0728bef2c..8ff74d3b6 100644 --- a/libp2p/HostCapability.cpp +++ b/libp2p/HostCapability.cpp @@ -34,9 +34,9 @@ void HostCapabilityFace::seal(bytes& _b) std::vector > HostCapabilityFace::peers() const { - RecursiveGuard l(m_host->x_peers); + RecursiveGuard l(m_host->x_sessions); std::vector > ret; - for (auto const& i: m_host->m_peers) + for (auto const& i: m_host->m_sessions) if (std::shared_ptr p = i.second.lock()) if (p->m_capabilities.count(capDesc())) ret.push_back(p); diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index 1b74abbda..b384c42d2 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -27,7 +27,7 @@ using namespace dev::p2p; NodeEntry::NodeEntry(Node _src, Public _pubk, NodeIPEndpoint _gw): Node(_pubk, _gw), distance(NodeTable::dist(_src.id,_pubk)) {} NodeEntry::NodeEntry(Node _src, Public _pubk, bi::udp::endpoint _udp): Node(_pubk, NodeIPEndpoint(_udp)), distance(NodeTable::dist(_src.id,_pubk)) {} -NodeTable::NodeTable(ba::io_service& _io, KeyPair _alias, uint16_t _udp, bi::tcp::endpoint _ep): +NodeTable::NodeTable(ba::io_service& _io, KeyPair _alias, uint16_t _udp): m_node(Node(_alias.pub(), bi::udp::endpoint())), m_secret(_alias.sec()), m_io(_io), @@ -53,11 +53,32 @@ NodeTable::~NodeTable() m_socketPtr->disconnect(); } +shared_ptr NodeTable::addNode(Public const& _pubk, bi::udp::endpoint const& _udp, bi::tcp::endpoint const& _tcp) +{ + auto node = Node(_pubk, NodeIPEndpoint(_udp, _tcp)); + return move(addNode(node)); +} + +shared_ptr NodeTable::addNode(Node const& _node) +{ + Guard l(x_nodes); + shared_ptr ret = m_nodes[_node.id]; + if (!ret) + { + ret.reset(new NodeEntry(m_node, _node.id, NodeIPEndpoint(_node.endpoint.udp, _node.endpoint.tcp))); + m_nodes[_node.id] = ret; + PingNode p(_node.endpoint.udp, m_node.endpoint.udp.address().to_string(), m_node.endpoint.udp.port()); + p.sign(m_secret); + m_socketPtr->send(p); + } + return move(ret); +} + void NodeTable::join() { doFindNode(m_node.id); } - + list NodeTable::nodes() const { list nodes; @@ -84,6 +105,13 @@ Node NodeTable::operator[](NodeId _id) return !!n ? *n : Node(); } +shared_ptr NodeTable::getNodeEntry(NodeId _id) +{ + Guard l(x_nodes); + auto n = m_nodes[_id]; + return !!n ? move(n) : move(shared_ptr()); +} + void NodeTable::requestNeighbours(NodeEntry const& _node, NodeId _target) const { FindNode p(_node.endpoint.udp, _target); @@ -240,29 +268,6 @@ void NodeTable::evict(shared_ptr _leastSeen, shared_ptr _n ping(_leastSeen.get()); } -shared_ptr NodeTable::addNode(Public const& _pubk, bi::udp::endpoint const& _udp, bi::tcp::endpoint const& _tcp) -{ - auto node = Node(_pubk, NodeIPEndpoint(_udp, _tcp)); - return move(addNode(node)); -} - -shared_ptr NodeTable::addNode(Node const& _node) -{ - shared_ptr ret; - Guard l(x_nodes); - if (auto n = m_nodes[_node.id]) - ret = n; - else - { - ret.reset(new NodeEntry(m_node, _node.id, NodeIPEndpoint(_node.endpoint.udp, _node.endpoint.tcp))); - m_nodes[_node.id] = ret; - PingNode p(_node.endpoint.udp, m_node.endpoint.udp.address().to_string(), m_node.endpoint.udp.port()); - p.sign(m_secret); - m_socketPtr->send(p); - } - return move(ret); -} - void NodeTable::noteNode(Public const& _pubk, bi::udp::endpoint const& _endpoint) { if (_pubk == m_node.address()) diff --git a/libp2p/NodeTable.h b/libp2p/NodeTable.h index 79ce6a9e3..7f75bf27e 100644 --- a/libp2p/NodeTable.h +++ b/libp2p/NodeTable.h @@ -22,6 +22,7 @@ #pragma once #include +#include #include #include #include @@ -74,14 +75,37 @@ struct Node */ struct NodeEntry: public Node { - NodeEntry(Node _src, Public _pubk, NodeIPEndpoint _gw); //: Node(_pubk, _gw), distance(dist(_src.id,_pubk)) {} - NodeEntry(Node _src, Public _pubk, bi::udp::endpoint _udp); //: Node(_pubk, NodeIPEndpoint(_udp)), distance(dist(_src.id,_pubk)) {} + NodeEntry(Node _src, Public _pubk, NodeIPEndpoint _gw); + NodeEntry(Node _src, Public _pubk, bi::udp::endpoint _udp); - const unsigned distance; ///< Node's distance from _src (see constructor). + const unsigned distance; ///< Node's distance (xor of _src as integer). +}; + +enum NodeTableEventType { + NodeEntryAdded, + NodeEntryRemoved +}; +class NodeTable; +class NodeTableEventHandler +{ + friend class NodeTable; +public: + virtual void processEvent(NodeId _n, NodeTableEventType _e) =0; + +protected: + /// Called by NodeTable on behalf of an implementation (Host) to process new events without blocking nodetable. + void processEvents() { std::list> events; { Guard l(x_events); if (!m_nodeEvents.size()) return; m_nodeEvents.unique(); for (auto const& n: m_nodeEvents) events.push_back(std::make_pair(n,m_events[n])); m_nodeEvents.empty(); m_events.empty(); } for (auto const& e: events) processEvent(e.first, e.second); } + + /// Called by NodeTable to append event. + virtual void appendEvent(NodeId _n, NodeTableEventType _e) { Guard l(x_events); m_nodeEvents.push_back(_n); m_events[_n] = _e; } + + Mutex x_events; + std::list m_nodeEvents; + std::map m_events; }; /** - * NodeTable using S/Kademlia system for node discovery and preference. + * NodeTable using modified kademlia 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 @@ -122,7 +146,7 @@ class NodeTable: UDPSocketEvents, public std::enable_shared_from_this using EvictionTimeout = std::pair,NodeId>; ///< First NodeId may be evicted and replaced with second NodeId. public: - NodeTable(ba::io_service& _io, KeyPair _alias, uint16_t _udpPort = 30303, bi::tcp::endpoint _ep = bi::tcp::endpoint()); + NodeTable(ba::io_service& _io, KeyPair _alias, uint16_t _udpPort = 30303); ~NodeTable(); /// Constants for Kademlia, mostly derived from address space. @@ -145,6 +169,12 @@ public: static unsigned dist(NodeId const& _a, NodeId const& _b) { u512 d = _a ^ _b; unsigned ret; for (ret = 0; d >>= 1; ++ret) {}; return ret; } + /// Set event handler for NodeEntryAdded and NodeEntryRemoved events. + void setEventHandler(NodeTableEventHandler* _handler) { m_nodeEvents.reset(_handler); } + + /// Called by implementation which provided handler to process NodeEntryAdded/NodeEntryRemoved events. Events are coalesced by type whereby old events are ignored. + void processEvents() { if (m_nodeEvents) m_nodeEvents->processEvents(); } + /// Add node. Node will be pinged if it's not already known. std::shared_ptr addNode(Public const& _pubk, bi::udp::endpoint const& _udp, bi::tcp::endpoint const& _tcp = bi::tcp::endpoint()); @@ -157,7 +187,9 @@ public: std::list nodes() const; std::list state() const; + bool haveNode(NodeId _id) { Guard l(x_nodes); return !!m_nodes[_id]; } Node operator[](NodeId _id); + std::shared_ptr getNodeEntry(NodeId _id); protected: struct NodeBucket @@ -207,6 +239,8 @@ protected: /// Sends FindNeighbor packet. See doFindNode. void requestNeighbours(NodeEntry const& _node, NodeId _target) const; + std::unique_ptr m_nodeEvents; ///< Event handler for node events. + Node m_node; ///< This node. Secret m_secret; ///< This nodes secret key. diff --git a/libp2p/Session.cpp b/libp2p/Session.cpp index c6797b69c..0ef06ab50 100644 --- a/libp2p/Session.cpp +++ b/libp2p/Session.cpp @@ -36,21 +36,21 @@ using namespace dev::p2p; #endif #define clogS(X) dev::LogOutputStream(false) << "| " << std::setw(2) << m_socket.native_handle() << "] " -Session::Session(Host* _s, bi::tcp::socket _socket, std::shared_ptr const& _n): +Session::Session(Host* _s, bi::tcp::socket _socket, std::shared_ptr const& _n): m_server(_s), m_socket(std::move(_socket)), - m_node(_n), + m_info({m_peer->id, "?", _n->address.address().to_string(), _n->address.port(), std::chrono::steady_clock::duration(0), CapDescSet(), 0, map()}), + m_peer(_n), m_manualEndpoint(_n->address) { m_lastReceived = m_connect = std::chrono::steady_clock::now(); - m_info = PeerInfo({m_node->id, "?", _n->address.address().to_string(), _n->address.port(), std::chrono::steady_clock::duration(0), CapDescSet(), 0, map()}); } Session::~Session() { // TODO: P2P revisit (refactored from previous logic) - if (m_node && !(id() && !isPermanentProblem(m_node->lastDisconnect) && !m_node->dead)) - m_node->lastConnected = m_node->lastAttempted - chrono::seconds(1); + if (m_peer && !(id() && !isPermanentProblem(m_peer->lastDisconnect) && !m_peer->dead)) + m_peer->lastConnected = m_peer->lastAttempted - chrono::seconds(1); // Read-chain finished for one reason or another. for (auto& i: m_capabilities) @@ -70,35 +70,35 @@ Session::~Session() NodeId Session::id() const { - return m_node ? m_node->id : NodeId(); + return m_peer ? m_peer->id : NodeId(); } void Session::addRating(unsigned _r) { - if (m_node) + if (m_peer) { - m_node->rating += _r; - m_node->score += _r; + m_peer->rating += _r; + m_peer->score += _r; } } int Session::rating() const { - return m_node->rating; + return m_peer->rating; } // TODO: P2P integration: session->? should be unavailable when socket isn't open bi::tcp::endpoint Session::endpoint() const { - if (m_socket.is_open() && m_node) + if (m_socket.is_open() && m_peer) try { - return bi::tcp::endpoint(m_socket.remote_endpoint().address(), m_node->address.port()); + return bi::tcp::endpoint(m_socket.remote_endpoint().address(), m_peer->address.port()); } catch (...) {} - if (m_node) - return m_node->address; + if (m_peer) + return m_peer->address; return m_manualEndpoint; } @@ -195,10 +195,11 @@ bool Session::interpret(RLP const& _r) return true; } - assert(!!m_node); - assert(!!m_node->id); + assert(!!m_peer); + assert(!!m_peer->id); - if (m_server->havePeer(id)) + // TODO: P2P ensure disabled logic is covered + if (false /* m_server->havePeer(id) */) { // Already connected. clogS(NetWarn) << "Already connected to a peer with id" << id.abridged(); @@ -217,20 +218,28 @@ bool Session::interpret(RLP const& _r) // TODO: P2P Move all node-lifecycle information into Host. Determine best way to handle peer-lifecycle properties vs node lifecycle. // TODO: P2P remove oldid // TODO: P2P with encrypted transport the handshake will fail and we won't get here -// m_node = m_server->noteNode(m_node->id, bi::tcp::endpoint(m_socket.remote_endpoint().address(), listenPort)); - if (m_node->isOffline()) - m_node->lastConnected = chrono::system_clock::now(); +// m_peer = m_server->noteNode(m_peer->id, bi::tcp::endpoint(m_socket.remote_endpoint().address(), listenPort)); + if (m_peer->isOffline()) + m_peer->lastConnected = chrono::system_clock::now(); // // // TODO: P2P introduce map of nodes we've given to this node (if GetPeers/Peers stays in TCP) - m_knownNodes.extendAll(m_node->index); - m_knownNodes.unionWith(m_node->index); + m_knownNodes.extendAll(m_peer->index); + m_knownNodes.unionWith(m_peer->index); if (m_protocolVersion != m_server->protocolVersion()) { disconnect(IncompatibleProtocol); return true; } - m_info = PeerInfo({id, clientVersion, m_socket.remote_endpoint().address().to_string(), listenPort, std::chrono::steady_clock::duration(), _r[3].toSet(), (unsigned)m_socket.native_handle(), map() }); + + // TODO: P2P migrate auth to Host and Handshake to constructor + m_info.clientVersion = clientVersion; + m_info.host = m_socket.remote_endpoint().address().to_string(); + m_info.port = listenPort; + m_info.lastPing = std::chrono::steady_clock::duration(); + m_info.caps = _r[3].toSet(); + m_info.socket = (unsigned)m_socket.native_handle(); + m_info.notes = map(); m_server->registerPeer(shared_from_this(), caps); break; @@ -285,64 +294,63 @@ bool Session::interpret(RLP const& _r) } auto ep = bi::tcp::endpoint(peerAddress, _r[i][1].toInt()); NodeId id = _r[i][2].toHash(); - clogS(NetAllDetail) << "Checking: " << ep << "(" << id.abridged() << ")" << isPrivateAddress(peerAddress) << this->id().abridged() << isPrivateAddress(endpoint().address()) << m_server->m_nodes.count(id) << (m_server->m_nodes.count(id) ? isPrivateAddress(m_server->m_nodes.at(id)->address.address()) : -1); + + clogS(NetAllDetail) << "Checking: " << ep << "(" << id.abridged() << ")"; +// clogS(NetAllDetail) << "Checking: " << ep << "(" << id.abridged() << ")" << isPrivateAddress(peerAddress) << this->id().abridged() << isPrivateAddress(endpoint().address()) << m_server->m_peers.count(id) << (m_server->m_peers.count(id) ? isPrivateAddress(m_server->m_peers.at(id)->address.address()) : -1); - if (isPrivateAddress(peerAddress) && !m_server->m_netPrefs.localNetworking) + // ignore if dist(us,item) - dist(us,them) > 1 + + // TODO: isPrivate + if (!m_server->m_netPrefs.localNetworking && isPrivateAddress(peerAddress)) goto CONTINUE; // Private address. Ignore. if (!id) - goto CONTINUE; // Null identity. Ignore. + goto LAMEPEER; // Null identity. Ignore. if (m_server->id() == id) - goto CONTINUE; // Just our info - we already have that. + goto LAMEPEER; // Just our info - we already have that. if (id == this->id()) - goto CONTINUE; // Just their info - we already have that. + goto LAMEPEER; // Just their info - we already have that. + // we don't worry about m_peers.count(id) now because node table will handle this and + // by default we will not blindly connect to nodes received via tcp; instead they will + // be pinged, as-is standard, by the node table and added if appropriate. unless flagged + // as required, nodes aren't connected to unless they respond via discovery; no matter if + // a node is relayed via udp or tcp. // check that it's not us or one we already know: - if (m_server->m_nodes.count(id)) - { - /* MEH. Far from an ideal solution. Leave alone for now. - // Already got this node. - // See if it's any better that ours or not... - // This could be the public address of a known node. - // SECURITY: remove this in beta - it's only for lazy connections and presents an easy attack vector. - if (m_server->m_nodes.count(id) && isPrivateAddress(m_server->m_nodes.at(id)->address.address()) && ep.port() != 0) - // Update address if the node if we now have a public IP for it. - m_server->m_nodes[id]->address = ep; - */ - goto CONTINUE; - } +// if (m_server->m_peers.count(id)) +// { +// /* MEH. Far from an ideal solution. Leave alone for now. +// // Already got this node. +// // See if it's any better that ours or not... +// // This could be the public address of a known node. +// // SECURITY: remove this in beta - it's only for lazy connections and presents an easy attack vector. +// if (m_server->m_peers.count(id) && isPrivateAddress(m_server->m_peers.at(id)->address.address()) && ep.port() != 0) +// // Update address if the node if we now have a public IP for it. +// m_server->m_peers[id]->address = ep; +// */ +// goto CONTINUE; +// } if (!ep.port()) - goto CONTINUE; // Zero port? Don't think so. + goto LAMEPEER; // Zero port? Don't think so. if (ep.port() >= /*49152*/32768) - goto CONTINUE; // Private port according to IANA. + goto LAMEPEER; // Private port according to IANA. - // TODO: PoC-7: - // Technically fine, but ignore for now to avoid peers passing on incoming ports until we can be sure that doesn't happen any more. -// if (ep.port() < 30300 || ep.port() > 30305) -// goto CONTINUE; // Wierd port. - - // Avoid our random other addresses that they might end up giving us. - for (auto i: m_server->m_peerAddresses) - if (ep.address() == i && ep.port() == m_server->listenPort()) - goto CONTINUE; - - // Check that we don't already know about this addr:port combination. If we are, assume the original is best. - // SECURITY: Not a valid assumption in general. Should compare ID origins and pick the best or note uncertainty and weight each equally. - for (auto const& i: m_server->m_nodes) - if (i.second->address == ep) - goto CONTINUE; // Same address but a different node. + // node table handles another node giving us a node which represents one of our other local network interfaces + // node table handles another node giving us a node we already know about // OK passed all our checks. Assume it's good. addRating(1000); // TODO: P2P change to addNode() -// m_server->noteNode(id, ep); + m_server->addNode(Node(id, NodeIPEndpoint(bi::udp::endpoint(ep.address(), 30303), ep))); + clogS(NetTriviaDetail) << "New peer: " << ep << "(" << id .abridged()<< ")"; CONTINUE:; + LAMEPEER:; } break; default: @@ -469,15 +477,15 @@ void Session::drop(DisconnectReason _reason) } catch (...) {} - if (m_node) + if (m_peer) { - if (_reason != m_node->lastDisconnect || _reason == NoDisconnect || _reason == ClientQuit || _reason == DisconnectRequested) - m_node->failedAttempts = 0; - m_node->lastDisconnect = _reason; + if (_reason != m_peer->lastDisconnect || _reason == NoDisconnect || _reason == ClientQuit || _reason == DisconnectRequested) + m_peer->failedAttempts = 0; + m_peer->lastDisconnect = _reason; if (_reason == BadProtocol) { - m_node->rating /= 2; - m_node->score /= 2; + m_peer->rating /= 2; + m_peer->score /= 2; } } m_dropped = true; diff --git a/libp2p/Session.h b/libp2p/Session.h index 19dc60a28..9c0472a81 100644 --- a/libp2p/Session.h +++ b/libp2p/Session.h @@ -39,7 +39,7 @@ namespace dev namespace p2p { -struct NodeInfo; +struct PeerInfo; /** * @brief The Session class @@ -51,7 +51,7 @@ class Session: public std::enable_shared_from_this friend class HostCapabilityFace; public: - Session(Host* _server, bi::tcp::socket _socket, std::shared_ptr const& _n); + Session(Host* _server, bi::tcp::socket _socket, std::shared_ptr const& _n); virtual ~Session(); void start(); @@ -80,7 +80,7 @@ public: void addNote(std::string const& _k, std::string const& _v) { m_info.notes[_k] = _v; } - PeerInfo const& info() const { return m_info; } + PeerSessionInfo const& info() const { return m_info; } void ensureNodesRequested(); void serviceNodesRequest(); @@ -109,10 +109,10 @@ private: std::array m_data; ///< Buffer for ingress packet data. bytes m_incoming; ///< Read buffer for ingress bytes. - PeerInfo m_info; ///< Dynamic information about this peer. + PeerSessionInfo m_info; ///< Dynamic information about this peer. unsigned m_protocolVersion = 0; ///< The protocol version of the peer. - std::shared_ptr m_node; ///< The NodeInfo object. + std::shared_ptr m_peer; ///< The PeerInfo object. bi::tcp::endpoint m_manualEndpoint; ///< The endpoint as specified by the constructor. bool m_dropped = false; ///< If true, we've already divested ourselves of this peer. We're just waiting for the reads & writes to fail before the shared_ptr goes OOS and the destructor kicks in. diff --git a/libwebthree/WebThree.cpp b/libwebthree/WebThree.cpp index fd51b5947..40e878858 100644 --- a/libwebthree/WebThree.cpp +++ b/libwebthree/WebThree.cpp @@ -75,7 +75,7 @@ void WebThreeDirect::setNetworkPreferences(p2p::NetworkPreferences const& _n) startNetwork(); } -std::vector WebThreeDirect::peers() +std::vector WebThreeDirect::peers() { return m_net.peers(); } @@ -102,5 +102,5 @@ void WebThreeDirect::restoreNodes(bytesConstRef _saved) void WebThreeDirect::connect(std::string const& _seedHost, unsigned short _port) { - m_net.connect(NodeId(), _seedHost, _port); + m_net.addNode(NodeId(), _seedHost, _port, _port); } diff --git a/libwebthree/WebThree.h b/libwebthree/WebThree.h index ec7bf2406..3a9fbbb30 100644 --- a/libwebthree/WebThree.h +++ b/libwebthree/WebThree.h @@ -84,7 +84,7 @@ public: // Network stuff: /// Get information on the current peer set. - std::vector peers(); + std::vector peers(); /// Same as peers().size(), but more efficient. size_t peerCount() const; @@ -195,7 +195,7 @@ public: // Peer network stuff - forward through RPCSlave, probably with P2PNetworkSlave/Master classes like Whisper & Ethereum. /// Get information on the current peer set. - std::vector peers(); + std::vector peers(); /// Same as peers().size(), but more efficient. size_t peerCount() const; diff --git a/neth/main.cpp b/neth/main.cpp index 8552177ce..2bcbb5e04 100644 --- a/neth/main.cpp +++ b/neth/main.cpp @@ -913,7 +913,7 @@ int main(int argc, char** argv) // Peers y = 1; - for (PeerInfo const& i: web3.peers()) + for (PeerSessionInfo const& i: web3.peers()) { auto s = boost::format("%1% ms - %2%:%3% - %4%") % toString(chrono::duration_cast(i.lastPing).count()) % diff --git a/test/peer.cpp b/test/peer.cpp index d13ea97f3..5c11d4cfb 100644 --- a/test/peer.cpp +++ b/test/peer.cpp @@ -49,14 +49,14 @@ int peerTest(int argc, char** argv) Host ph("Test", NetworkPreferences(listenPort)); if (!remoteHost.empty()) - ph.connect(NodeId(), remoteHost, remotePort); - - for (int i = 0; ; ++i) - { - this_thread::sleep_for(chrono::milliseconds(100)); - if (!(i % 10)) - ph.keepAlivePeers(); - } + ph.addNode(NodeId(), remoteHost, remotePort, remotePort); + +// for (int i = 0; ; ++i) +// { +// this_thread::sleep_for(chrono::milliseconds(100)); +// if (!(i % 10)) +// ph.keepAlivePeers(); +// } return 0; } diff --git a/test/whisperTopic.cpp b/test/whisperTopic.cpp index 8ecabde9b..ea46b162c 100644 --- a/test/whisperTopic.cpp +++ b/test/whisperTopic.cpp @@ -72,7 +72,7 @@ BOOST_AUTO_TEST_CASE(topic) this_thread::sleep_for(chrono::milliseconds(500)); ph.start(); this_thread::sleep_for(chrono::milliseconds(500)); - ph.connect(NodeId(), "127.0.0.1", 50303); + ph.addNode(NodeId(), "127.0.0.1", 50303, 50303); KeyPair us = KeyPair::create(); for (int i = 0; i < 10; ++i) From 77316d19dc35a88b4b7390ed5ef418fb51640745 Mon Sep 17 00:00:00 2001 From: subtly Date: Sat, 10 Jan 2015 20:12:47 +0100 Subject: [PATCH 007/213] Don't setup nodetable until network is started. --- libp2p/Host.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index 243738918..dd38ff5bd 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -52,8 +52,8 @@ Host::Host(std::string const& _clientVersion, NetworkPreferences const& _n, bool m_ifAddresses(Network::getInterfaceAddresses()), m_ioService(2), m_tcp4Acceptor(m_ioService), - m_key(move(getHostIdentifier())), - m_nodeTable(new NodeTable(m_ioService, m_key)) + m_key(move(getHostIdentifier())) +// m_nodeTable(new NodeTable(m_ioService, m_key)) { for (auto address: m_ifAddresses) if (address.is_v4()) @@ -443,7 +443,7 @@ unsigned PeerInfo::fallbackSeconds() const } } -// TODO: P2P rebuild noetable when localNetworking is enabled/disabled +// TODO: P2P rebuild nodetable when localNetworking is enabled/disabled // TODO: P2P migrate grow/prunePeers into 'maintainPeers' & evaluate reputation instead of availability. schedule via deadline timer. //void Host::growPeers() //{ From 75f231419aad339028c92024ea55bd741b0e63e7 Mon Sep 17 00:00:00 2001 From: subtly Date: Mon, 12 Jan 2015 04:58:52 +0100 Subject: [PATCH 008/213] Connectivity and nodetable callbacks. Disable stale code. --- alethzero/MainWin.cpp | 4 ++-- libp2p/Host.cpp | 20 +++++++++++++++++++- libp2p/Host.h | 6 +++--- libp2p/NodeTable.cpp | 14 ++++++++++++-- libp2p/NodeTable.h | 20 ++++++++++++++++++-- libp2p/Session.cpp | 44 ++++++++++++++++++++++--------------------- libp2p/Session.h | 7 ++----- test/peer.cpp | 23 ++++++++++++++++++++++ 8 files changed, 102 insertions(+), 36 deletions(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index f2437c6d2..f4750326d 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -930,7 +930,7 @@ void Main::refreshNetwork() .arg(QString::fromStdString(i.id.abridged()))); auto ns = web3()->nodes(); - for (p2p::Node const& i: ns) + for (p2p::PeerInfo const& i: ns) if (!i.dead) ui->nodes->insertItem(clients.count(i.id) ? 0 : ui->nodes->count(), QString("[%1 %3] %2 - ( =%5s | /%4s%6 ) - *%7 $%8") .arg(QString::fromStdString(i.id.abridged())) @@ -940,7 +940,7 @@ void Main::refreshNetwork() .arg(i.secondsSinceLastConnected()) .arg(i.isOffline() ? " | " + QString::fromStdString(reasonOf(i.lastDisconnect)) + " | " + QString::number(i.failedAttempts) + "x" : "") .arg(i.rating) - .arg((int)i.idOrigin) + .arg(0 /* (int)i.idOrigin */) ); } } diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index dd38ff5bd..61f30b548 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -177,6 +177,8 @@ void Host::onNodeTableEvent(NodeId _n, NodeTableEventType _e) { if (_e == NodeEntryAdded) { + clog(NetNote) << "p2p.host.nodeTable.events.nodeEntryAdded " << _n; + auto n = (*m_nodeTable)[_n]; if (n) { @@ -196,6 +198,8 @@ void Host::onNodeTableEvent(NodeId _n, NodeTableEventType _e) } else if (_e == NodeEntryRemoved) { + clog(NetNote) << "p2p.host.nodeTable.events.nodeEntryRemoved " << _n; + RecursiveGuard l(x_sessions); m_peers.erase(_n); } @@ -294,7 +298,17 @@ void Host::runAcceptor() { try { - doHandshake(s); +// RecursiveGuard l(x_sessions); +// auto p = m_peers[_n]; +// if (!p) +// { +// m_peers[_n] = make_shared(); +// p = m_peers[_n]; +// p->id = _n; +// } +// p->address = n.endpoint.tcp; + + doHandshake(s, NodeId()); success = true; } catch (Exception const& _e) @@ -329,6 +343,7 @@ void Host::doHandshake(bi::tcp::socket* _socket, NodeId _nodeId) clog(NetConnect) << "Accepting connection for " << _socket->remote_endpoint(); } catch (...){} + // auto p = std::make_shared(this, std::move(*_socket), m_peers[_nodeId]); p->start(); } @@ -538,6 +553,8 @@ void Host::run(boost::system::error_code const&) return; } + m_nodeTable->processEvents(); + for (auto p: m_sessions) if (auto pp = p.second.lock()) pp->serviceNodesRequest(); @@ -585,6 +602,7 @@ void Host::startedWorking() m_nodeTable.reset(new NodeTable(m_ioService, m_key, m_listenPort)); else m_nodeTable.reset(new NodeTable(m_ioService, m_key, m_listenPort > 0 ? m_listenPort : 30303)); + m_nodeTable->setEventHandler(new HostNodeTableHandler(*this)); } clog(NetNote) << "p2p.started id:" << id().abridged(); diff --git a/libp2p/Host.h b/libp2p/Host.h index 097b07433..3d386fe8c 100644 --- a/libp2p/Host.h +++ b/libp2p/Host.h @@ -110,10 +110,10 @@ struct PeerInfo using Nodes = std::vector; - -class Host; + class HostNodeTableHandler: public NodeTableEventHandler { + friend class Host; HostNodeTableHandler(Host& _host); virtual void processEvent(NodeId _n, NodeTableEventType _e); Host& m_host; @@ -213,7 +213,7 @@ private: void runAcceptor(); /// Handler for verifying handshake siganture before creating session. _egressNodeId is passed for outbound connections. - void doHandshake(bi::tcp::socket* _socket, NodeId _egressNodeId = NodeId()); + void doHandshake(bi::tcp::socket* _socket, NodeId _nodeId); void seal(bytes& _b); diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index b384c42d2..635f91bfb 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -65,6 +65,10 @@ shared_ptr NodeTable::addNode(Node const& _node) shared_ptr ret = m_nodes[_node.id]; if (!ret) { + clog(NodeTableNote) << "p2p.nodes.add " << _node.id.abridged(); + if (m_nodeEvents) + m_nodeEvents->appendEvent(_node.id, NodeEntryAdded); + ret.reset(new NodeEntry(m_node, _node.id, NodeIPEndpoint(_node.endpoint.udp, _node.endpoint.tcp))); m_nodes[_node.id] = ret; PingNode p(_node.endpoint.udp, m_node.endpoint.udp.address().to_string(), m_node.endpoint.udp.port()); @@ -317,8 +321,14 @@ void NodeTable::dropNode(shared_ptr _n) Guard l(x_state); s.nodes.remove_if([&_n](weak_ptr n) { return n.lock() == _n; }); } - Guard l(x_nodes); - m_nodes.erase(_n->id); + { + Guard l(x_nodes); + m_nodes.erase(_n->id); + } + + clog(NodeTableNote) << "p2p.nodes.drop " << _n->id.abridged(); + if (m_nodeEvents) + m_nodeEvents->appendEvent(_n->id, NodeEntryRemoved); } NodeTable::NodeBucket& NodeTable::bucket(NodeEntry const* _n) diff --git a/libp2p/NodeTable.h b/libp2p/NodeTable.h index 7f75bf27e..75042dffc 100644 --- a/libp2p/NodeTable.h +++ b/libp2p/NodeTable.h @@ -94,7 +94,20 @@ public: protected: /// Called by NodeTable on behalf of an implementation (Host) to process new events without blocking nodetable. - void processEvents() { std::list> events; { Guard l(x_events); if (!m_nodeEvents.size()) return; m_nodeEvents.unique(); for (auto const& n: m_nodeEvents) events.push_back(std::make_pair(n,m_events[n])); m_nodeEvents.empty(); m_events.empty(); } for (auto const& e: events) processEvent(e.first, e.second); } + void processEvents() { + std::list> events; + { + Guard l(x_events); + if (!m_nodeEvents.size()) + return; + m_nodeEvents.unique(); + for (auto const& n: m_nodeEvents) events.push_back(std::make_pair(n,m_events[n])); + m_nodeEvents.empty(); + m_events.empty(); + } + for (auto const& e: events) + processEvent(e.first, e.second); + } /// Called by NodeTable to append event. virtual void appendEvent(NodeId _n, NodeTableEventType _e) { Guard l(x_events); m_nodeEvents.push_back(_n); m_events[_n] = _e; } @@ -173,7 +186,10 @@ public: void setEventHandler(NodeTableEventHandler* _handler) { m_nodeEvents.reset(_handler); } /// Called by implementation which provided handler to process NodeEntryAdded/NodeEntryRemoved events. Events are coalesced by type whereby old events are ignored. - void processEvents() { if (m_nodeEvents) m_nodeEvents->processEvents(); } + void processEvents() { + if (m_nodeEvents) + m_nodeEvents->processEvents(); + } /// Add node. Node will be pinged if it's not already known. std::shared_ptr addNode(Public const& _pubk, bi::udp::endpoint const& _udp, bi::tcp::endpoint const& _tcp = bi::tcp::endpoint()); diff --git a/libp2p/Session.cpp b/libp2p/Session.cpp index 0ef06ab50..80c538b24 100644 --- a/libp2p/Session.cpp +++ b/libp2p/Session.cpp @@ -39,9 +39,8 @@ using namespace dev::p2p; Session::Session(Host* _s, bi::tcp::socket _socket, std::shared_ptr const& _n): m_server(_s), m_socket(std::move(_socket)), - m_info({m_peer->id, "?", _n->address.address().to_string(), _n->address.port(), std::chrono::steady_clock::duration(0), CapDescSet(), 0, map()}), m_peer(_n), - m_manualEndpoint(_n->address) + m_info({NodeId(), "?", m_socket.remote_endpoint().address().to_string(), 0, std::chrono::steady_clock::duration(0), CapDescSet(), 0, map()}) { m_lastReceived = m_connect = std::chrono::steady_clock::now(); } @@ -87,21 +86,21 @@ int Session::rating() const return m_peer->rating; } -// TODO: P2P integration: session->? should be unavailable when socket isn't open -bi::tcp::endpoint Session::endpoint() const -{ - if (m_socket.is_open() && m_peer) - try - { - return bi::tcp::endpoint(m_socket.remote_endpoint().address(), m_peer->address.port()); - } - catch (...) {} - - if (m_peer) - return m_peer->address; - - return m_manualEndpoint; -} +//// TODO: P2P integration: session->? should be unavailable when socket isn't open +//bi::tcp::endpoint Session::endpoint() const +//{ +// if (m_socket.is_open() && m_peer) +// try +// { +// return bi::tcp::endpoint(m_socket.remote_endpoint().address(), m_peer->address.port()); +// } +// catch (...) {} +// +// if (m_peer) +// return m_peer->address; +// +// return m_manualEndpoint; +//} template vector randomSelection(vector const& _t, unsigned _n) { @@ -190,14 +189,11 @@ bool Session::interpret(RLP const& _r) if (m_server->id() == id) { // Already connected. - clogS(NetWarn) << "Connected to ourself under a false pretext. We were told this peer was id" << m_info.id.abridged(); + clogS(NetWarn) << "Connected to ourself under a false pretext. We were told this peer was id" << id.abridged(); disconnect(LocalIdentity); return true; } - assert(!!m_peer); - assert(!!m_peer->id); - // TODO: P2P ensure disabled logic is covered if (false /* m_server->havePeer(id) */) { @@ -218,7 +214,13 @@ bool Session::interpret(RLP const& _r) // TODO: P2P Move all node-lifecycle information into Host. Determine best way to handle peer-lifecycle properties vs node lifecycle. // TODO: P2P remove oldid // TODO: P2P with encrypted transport the handshake will fail and we won't get here + + // if peer is missing this is incoming connection and we need to tell host about new potential peer + + // m_peer = m_server->noteNode(m_peer->id, bi::tcp::endpoint(m_socket.remote_endpoint().address(), listenPort)); + assert(!!m_peer); + assert(!!m_peer->id); if (m_peer->isOffline()) m_peer->lastConnected = chrono::system_clock::now(); // diff --git a/libp2p/Session.h b/libp2p/Session.h index 9c0472a81..55330c93c 100644 --- a/libp2p/Session.h +++ b/libp2p/Session.h @@ -64,8 +64,6 @@ public: NodeId id() const; unsigned socketId() const { return m_socket.native_handle(); } - bi::tcp::endpoint endpoint() const; ///< for other peers to connect to. - template std::shared_ptr cap() const { try { return std::static_pointer_cast(m_capabilities.at(std::make_pair(PeerCap::name(), PeerCap::version()))); } catch (...) { return nullptr; } } @@ -109,13 +107,12 @@ private: std::array m_data; ///< Buffer for ingress packet data. bytes m_incoming; ///< Read buffer for ingress bytes. - PeerSessionInfo m_info; ///< Dynamic information about this peer. - unsigned m_protocolVersion = 0; ///< The protocol version of the peer. std::shared_ptr m_peer; ///< The PeerInfo object. - bi::tcp::endpoint m_manualEndpoint; ///< The endpoint as specified by the constructor. bool m_dropped = false; ///< If true, we've already divested ourselves of this peer. We're just waiting for the reads & writes to fail before the shared_ptr goes OOS and the destructor kicks in. + PeerSessionInfo m_info; ///< Dynamic information about this peer. + bool m_theyRequestedNodes = false; ///< Has the peer requested nodes from us without receiveing an answer from us? bool m_weRequestedNodes = false; ///< Have we requested nodes from the peer and not received an answer yet? diff --git a/test/peer.cpp b/test/peer.cpp index 5c11d4cfb..c3a617ce6 100644 --- a/test/peer.cpp +++ b/test/peer.cpp @@ -20,6 +20,7 @@ * Peer Network test functions. */ +#include #include #include #include @@ -27,6 +28,28 @@ using namespace std; using namespace dev; using namespace dev::p2p; +BOOST_AUTO_TEST_SUITE(p2p) + +BOOST_AUTO_TEST_CASE(host) +{ + NetworkPreferences host1prefs(30301, "127.0.0.1", true, true); + NetworkPreferences host2prefs(30302, "127.0.0.1", true, true); + + Host host1("Test", host1prefs); + NodeId node1 = host1.id(); + host1.start(); + + Host host2("Test", host2prefs); + auto node2 = host2.id(); + host2.start(); + + host1.addNode(node2, "127.0.0.1", host2prefs.listenPort, host2prefs.listenPort); + + this_thread::sleep_for(chrono::seconds(2)); +} + +BOOST_AUTO_TEST_SUITE_END() + int peerTest(int argc, char** argv) { short listenPort = 30303; From 7ac5c12978ae5b892cac234b6da77140b1ca1d08 Mon Sep 17 00:00:00 2001 From: subtly Date: Wed, 14 Jan 2015 12:32:12 -0500 Subject: [PATCH 009/213] peerinfo created closer to authentication (when it's known). fixes missing m_peer on connect. --- libp2p/Host.cpp | 36 ++++++++++++++++++---------------- libp2p/Host.h | 7 +++---- libp2p/Session.cpp | 49 ++++++++++++++++++---------------------------- 3 files changed, 41 insertions(+), 51 deletions(-) diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index 61f30b548..d7546bb11 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -157,13 +157,15 @@ unsigned Host::protocolVersion() const void Host::registerPeer(std::shared_ptr _s, CapDescs const& _caps) { - assert(!!_s->m_peer); - assert(!!_s->m_peer->id); + asserts(!!_s->m_peer->id); { RecursiveGuard l(x_sessions); + if (!m_peers.count(_s->m_peer->id)) + m_peers[_s->m_peer->id] = _s->m_peer; m_sessions[_s->m_peer->id] = _s; } + unsigned o = (unsigned)UserPacket; for (auto const& i: _caps) if (haveCapability(i)) @@ -298,16 +300,7 @@ void Host::runAcceptor() { try { -// RecursiveGuard l(x_sessions); -// auto p = m_peers[_n]; -// if (!p) -// { -// m_peers[_n] = make_shared(); -// p = m_peers[_n]; -// p->id = _n; -// } -// p->address = n.endpoint.tcp; - + // incoming connection so we don't yet know nodeid doHandshake(s, NodeId()); success = true; } @@ -343,9 +336,18 @@ void Host::doHandshake(bi::tcp::socket* _socket, NodeId _nodeId) clog(NetConnect) << "Accepting connection for " << _socket->remote_endpoint(); } catch (...){} - // - auto p = std::make_shared(this, std::move(*_socket), m_peers[_nodeId]); - p->start(); + shared_ptr p; + if (_nodeId) + p = m_peers[_nodeId]; + + if (!p) + { + p = make_shared(); + p->address.address(_socket->remote_endpoint().address()); + } + + auto ps = std::make_shared(this, std::move(*_socket), p); + ps->start(); } string Host::pocHost() @@ -426,8 +428,8 @@ void Host::connect(std::shared_ptr const& _n) clog(NetConnect) << "Connected to" << _n->id.abridged() << "@" << _n->address; _n->lastConnected = std::chrono::system_clock::now(); - auto p = make_shared(this, std::move(*s), _n); - p->start(); + auto ps = make_shared(this, std::move(*s), _n); + ps->start(); } delete s; diff --git a/libp2p/Host.h b/libp2p/Host.h index 3d386fe8c..0e86710ec 100644 --- a/libp2p/Host.h +++ b/libp2p/Host.h @@ -212,8 +212,8 @@ private: /// Called only from startedWorking(). void runAcceptor(); - /// Handler for verifying handshake siganture before creating session. _egressNodeId is passed for outbound connections. - void doHandshake(bi::tcp::socket* _socket, NodeId _nodeId); + /// Handler for verifying handshake siganture before creating session. _nodeId is passed for outbound connections. + void doHandshake(bi::tcp::socket* _socket, NodeId _nodeId = NodeId()); void seal(bytes& _b); @@ -261,11 +261,10 @@ private: std::map> m_peers; - mutable RecursiveMutex x_sessions; - /// The nodes to which we are currently connected. /// Mutable because we flush zombie entries (null-weakptrs) as regular maintenance from a const method. mutable std::map> m_sessions; + mutable RecursiveMutex x_sessions; unsigned m_idealPeerCount = 5; ///< Ideal number of peers to be connected to. diff --git a/libp2p/Session.cpp b/libp2p/Session.cpp index 80c538b24..bafaed7e3 100644 --- a/libp2p/Session.cpp +++ b/libp2p/Session.cpp @@ -86,22 +86,6 @@ int Session::rating() const return m_peer->rating; } -//// TODO: P2P integration: session->? should be unavailable when socket isn't open -//bi::tcp::endpoint Session::endpoint() const -//{ -// if (m_socket.is_open() && m_peer) -// try -// { -// return bi::tcp::endpoint(m_socket.remote_endpoint().address(), m_peer->address.port()); -// } -// catch (...) {} -// -// if (m_peer) -// return m_peer->address; -// -// return m_manualEndpoint; -//} - template vector randomSelection(vector const& _t, unsigned _n) { if (_t.size() <= _n) @@ -172,6 +156,11 @@ bool Session::interpret(RLP const& _r) { case HelloPacket: { + // TODO: P2P first pass, implement signatures. if signature fails, drop connection. if egress, flag node's endpoint as stale. + // Move auth to Host so we consolidate authentication logic and eschew peer deduplication logic. + // Move all node-lifecycle information into Host. + // Finalize peer-lifecycle properties vs node lifecycle. + m_protocolVersion = _r[1].toInt(); auto clientVersion = _r[2].toString(); auto caps = _r[3].toVector(); @@ -194,7 +183,7 @@ bool Session::interpret(RLP const& _r) return true; } - // TODO: P2P ensure disabled logic is covered + // TODO: P2P ensure disabled logic is considered if (false /* m_server->havePeer(id) */) { // Already connected. @@ -203,27 +192,28 @@ bool Session::interpret(RLP const& _r) return true; } + // if peer and connection have id, check for UnexpectedIdentity if (!id) { disconnect(NullIdentity); return true; } - - // TODO: P2P first pass, implement signatures. if signature fails, drop connection. if egress, flag node's endpoint as stale. - // Discussion: Most this to Host so we consolidate authentication logic and eschew peer deduplication logic. - // TODO: P2P Move all node-lifecycle information into Host. Determine best way to handle peer-lifecycle properties vs node lifecycle. - // TODO: P2P remove oldid - // TODO: P2P with encrypted transport the handshake will fail and we won't get here - - // if peer is missing this is incoming connection and we need to tell host about new potential peer - + else if (!m_peer->id) + { + m_peer->id = id; + m_peer->address.port(listenPort); + } + else if (m_peer->id != id) + { + disconnect(UnexpectedIdentity); + return true; + } -// m_peer = m_server->noteNode(m_peer->id, bi::tcp::endpoint(m_socket.remote_endpoint().address(), listenPort)); assert(!!m_peer); assert(!!m_peer->id); if (m_peer->isOffline()) m_peer->lastConnected = chrono::system_clock::now(); -// + // // TODO: P2P introduce map of nodes we've given to this node (if GetPeers/Peers stays in TCP) m_knownNodes.extendAll(m_peer->index); m_knownNodes.unionWith(m_peer->index); @@ -234,7 +224,6 @@ bool Session::interpret(RLP const& _r) return true; } - // TODO: P2P migrate auth to Host and Handshake to constructor m_info.clientVersion = clientVersion; m_info.host = m_socket.remote_endpoint().address().to_string(); m_info.port = listenPort; @@ -347,7 +336,7 @@ bool Session::interpret(RLP const& _r) // OK passed all our checks. Assume it's good. addRating(1000); - // TODO: P2P change to addNode() + // TODO: P2P test m_server->addNode(Node(id, NodeIPEndpoint(bi::udp::endpoint(ep.address(), 30303), ep))); clogS(NetTriviaDetail) << "New peer: " << ep << "(" << id .abridged()<< ")"; From b8da68e77405e25ec83ce14961a9fccd0ec0e3b0 Mon Sep 17 00:00:00 2001 From: subtly Date: Wed, 14 Jan 2015 12:41:42 -0500 Subject: [PATCH 010/213] empty events via clear --- libp2p/NodeTable.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libp2p/NodeTable.h b/libp2p/NodeTable.h index 75042dffc..a68d42426 100644 --- a/libp2p/NodeTable.h +++ b/libp2p/NodeTable.h @@ -102,8 +102,8 @@ protected: return; m_nodeEvents.unique(); for (auto const& n: m_nodeEvents) events.push_back(std::make_pair(n,m_events[n])); - m_nodeEvents.empty(); - m_events.empty(); + m_nodeEvents.clear(); + m_events.clear(); } for (auto const& e: events) processEvent(e.first, e.second); From d13f69da5985e353ce63ad544b5966a67ea6c434 Mon Sep 17 00:00:00 2001 From: subtly Date: Thu, 15 Jan 2015 17:17:20 -0500 Subject: [PATCH 011/213] fix merge conflict --- libp2p/Host.h | 1 + libwebthree/WebThree.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/libp2p/Host.h b/libp2p/Host.h index 0e86710ec..d04470efd 100644 --- a/libp2p/Host.h +++ b/libp2p/Host.h @@ -125,6 +125,7 @@ class HostNodeTableHandler: public NodeTableEventHandler * @todo gracefully disconnect peer if peer already connected * @todo determinePublic: ipv6, udp * @todo handle conflict if addNode/requireNode called and Node already exists w/conflicting tcp or udp port + * @todo writing host identifier */ class Host: public Worker { diff --git a/libwebthree/WebThree.h b/libwebthree/WebThree.h index c5655b581..f2130d3f4 100644 --- a/libwebthree/WebThree.h +++ b/libwebthree/WebThree.h @@ -54,7 +54,7 @@ class WebThreeNetworkFace { public: /// Get information on the current peer set. - virtual std::vector peers() = 0; + virtual std::vector peers() = 0; /// Same as peers().size(), but more efficient. virtual size_t peerCount() const = 0; From f0a06fa1153db6f5b53c86a513f7604daa78af19 Mon Sep 17 00:00:00 2001 From: subtly Date: Fri, 16 Jan 2015 21:37:21 -0500 Subject: [PATCH 012/213] evictions logic --- libp2p/NodeTable.cpp | 14 +++++++++++++- libp2p/NodeTable.h | 13 +++++-------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index 635f91bfb..1e6d54682 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -374,7 +374,19 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes // clog(NodeTableMessageSummary) << "Received Pong from " << _from.address().to_string() << ":" << _from.port(); Pong in = Pong::fromBytesConstRef(_from, rlpBytes); - // whenever a pong is received, first check if it's in m_evictions + // whenever a pong is received, check if it's in m_evictions + Guard le(x_evictions); + for (auto it = m_evictions.begin(); it != m_evictions.end(); it++) + if (it->first.first == nodeid && it->first.second > std::chrono::steady_clock::now()) + { + if (auto n = getNodeEntry(it->second)) + dropNode(n); + + if (auto n = (*this)[it->first.first]) + addNode(n); + + m_evictions.erase(it); + } break; } diff --git a/libp2p/NodeTable.h b/libp2p/NodeTable.h index a68d42426..66f445827 100644 --- a/libp2p/NodeTable.h +++ b/libp2p/NodeTable.h @@ -125,19 +125,19 @@ protected: * shared_ptr replacement instead of mutating values. * * [Integration] - * @todo deadline-timer which maintains tcp/peer connections * @todo restore nodes: affects refreshbuckets * @todo TCP endpoints * @todo makeRequired: don't try to evict node if node isRequired. * @todo makeRequired: exclude bucket from refresh if we have node as peer. * * [Optimization] + * @todo serialize evictions per-bucket + * @todo store evictions in map, unit-test eviction logic + * @todo store root node in table * @todo encapsulate doFindNode into NetworkAlgorithm (task) * @todo Pong to include ip:port where ping was received * @todo expiration and sha3(id) 'to' for messages which are replies (prevents replay) - * @todo std::shared_ptr m_cachedPingPacket; - * @todo std::shared_ptr m_cachedFindSelfPacket; - * @todo store root node in table? + * @todo cache Ping and FindSelf * * [Networking] * @todo TCP endpoints @@ -145,11 +145,8 @@ protected: * @todo firewall * * [Protocol] - * @todo post-eviction pong * @todo optimize knowledge at opposite edges; eg, s_bitsPerStep lookups. (Can be done via pointers to NodeBucket) - * @todo ^ s_bitsPerStep = 5; // Denoted by b in [Kademlia]. Bits by which address space is divided. - * @todo optimize (use tree for state and/or custom compare for cache) - * @todo reputation (aka universal siblings lists) + * @todo ^ s_bitsPerStep = 8; // Denoted by b in [Kademlia]. Bits by which address space is divided. */ class NodeTable: UDPSocketEvents, public std::enable_shared_from_this { From f63e53f7351692c9c03fc45d635b0d8c729995a7 Mon Sep 17 00:00:00 2001 From: subtly Date: Sat, 17 Jan 2015 00:51:27 -0500 Subject: [PATCH 013/213] cleanup, sanity checks, and last pass of noting todos. --- libp2p/Host.cpp | 2 +- libp2p/Host.h | 8 ++---- libp2p/NodeTable.cpp | 10 ++++++- libp2p/Session.cpp | 63 ++++++++++++-------------------------------- libp2p/Session.h | 1 - 5 files changed, 29 insertions(+), 55 deletions(-) diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index f566af6e1..d4ef54795 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -644,7 +644,7 @@ bytes Host::saveNodes() const { PeerInfo const& n = *(i.second); // TODO: PoC-7: Figure out why it ever shares these ports.//n.address.port() >= 30300 && n.address.port() <= 30305 && - if (!n.dead && chrono::system_clock::now() - n.lastConnected < chrono::seconds(3600 * 48) && n.address.port() > 0 && n.address.port() < /*49152*/32768 && n.id != id() && !isPrivateAddress(n.address.address())) + if (chrono::system_clock::now() - n.lastConnected < chrono::seconds(3600 * 48) && n.address.port() > 0 && n.address.port() < /*49152*/32768 && n.id != id() && !isPrivateAddress(n.address.address())) { nodes.appendList(10); if (n.address.address().is_v4()) diff --git a/libp2p/Host.h b/libp2p/Host.h index d04470efd..f979ceebc 100644 --- a/libp2p/Host.h +++ b/libp2p/Host.h @@ -54,7 +54,6 @@ class Host; struct PeerInfo { NodeId id; ///< Their id/public key. - unsigned index; ///< Index into m_nodesList // p2p: move to NodeIPEndpoint bi::tcp::endpoint address; ///< As reported from the node itself. @@ -65,10 +64,6 @@ struct PeerInfo unsigned failedAttempts = 0; DisconnectReason lastDisconnect = NoDisconnect; ///< Reason for disconnect that happened last. - // p2p: just remove node - // p2p: revisit logic in see Session.cpp#210 - bool dead = false; ///< If true, we believe this node is permanently dead - forget all about it. - // p2p: move to protocol-specific map int score = 0; ///< All time cumulative. int rating = 0; ///< Trending. @@ -125,7 +120,8 @@ class HostNodeTableHandler: public NodeTableEventHandler * @todo gracefully disconnect peer if peer already connected * @todo determinePublic: ipv6, udp * @todo handle conflict if addNode/requireNode called and Node already exists w/conflicting tcp or udp port - * @todo writing host identifier + * @todo write host identifier to disk along w/nodes + * @todo move Session::addRating into Host and implement via sender-tagged events */ class Host: public Worker { diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index 1e6d54682..90916450d 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -63,7 +63,15 @@ shared_ptr NodeTable::addNode(Node const& _node) { Guard l(x_nodes); shared_ptr ret = m_nodes[_node.id]; - if (!ret) + if (ret) + { + // TODO: p2p robust percolation of node-endpoint changes +// // SECURITY: remove this in beta - it's only for lazy connections and presents an easy attack vector. +// if (m_server->m_peers.count(id) && isPrivateAddress(m_server->m_peers.at(id)->address.address()) && ep.port() != 0) +// // Update address if the node if we now have a public IP for it. +// m_server->m_peers[id]->address = ep; + } + else { clog(NodeTableNote) << "p2p.nodes.add " << _node.id.abridged(); if (m_nodeEvents) diff --git a/libp2p/Session.cpp b/libp2p/Session.cpp index bafaed7e3..d57a16fa2 100644 --- a/libp2p/Session.cpp +++ b/libp2p/Session.cpp @@ -47,9 +47,7 @@ Session::Session(Host* _s, bi::tcp::socket _socket, std::shared_ptr co Session::~Session() { - // TODO: P2P revisit (refactored from previous logic) - if (m_peer && !(id() && !isPermanentProblem(m_peer->lastDisconnect) && !m_peer->dead)) - m_peer->lastConnected = m_peer->lastAttempted - chrono::seconds(1); + m_peer->lastConnected = m_peer->lastAttempted - chrono::seconds(1); // Read-chain finished for one reason or another. for (auto& i: m_capabilities) @@ -136,8 +134,6 @@ void Session::serviceNodesRequest() s.appendList(3) << bytesConstRef(i.address.address().to_v4().to_bytes().data(), 4) << i.address.port() << i.id; else// if (i.second.address().is_v6()) - assumed s.appendList(3) << bytesConstRef(i.address.address().to_v6().to_bytes().data(), 16) << i.address.port() << i.id; - m_knownNodes.extendAll(i.index); - m_knownNodes.unionWith(i.index); } sealAndSend(s); m_theyRequestedNodes = false; @@ -183,15 +179,6 @@ bool Session::interpret(RLP const& _r) return true; } - // TODO: P2P ensure disabled logic is considered - if (false /* m_server->havePeer(id) */) - { - // Already connected. - clogS(NetWarn) << "Already connected to a peer with id" << id.abridged(); - disconnect(DuplicatePeer); - return true; - } - // if peer and connection have id, check for UnexpectedIdentity if (!id) { @@ -208,16 +195,18 @@ bool Session::interpret(RLP const& _r) disconnect(UnexpectedIdentity); return true; } + + if (m_server->havePeerSession(id)) + { + // Already connected. + clogS(NetWarn) << "Already connected to a peer with id" << id.abridged(); + disconnect(DuplicatePeer); + return true; + } - assert(!!m_peer); - assert(!!m_peer->id); if (m_peer->isOffline()) m_peer->lastConnected = chrono::system_clock::now(); -// // TODO: P2P introduce map of nodes we've given to this node (if GetPeers/Peers stays in TCP) - m_knownNodes.extendAll(m_peer->index); - m_knownNodes.unionWith(m_peer->index); - if (m_protocolVersion != m_server->protocolVersion()) { disconnect(IncompatibleProtocol); @@ -262,12 +251,20 @@ bool Session::interpret(RLP const& _r) break; case GetPeersPacket: { + // Disabled for interop testing. + // GetPeers/PeersPacket will be modified to only exchange new nodes which it's peers are interested in. + break; + clogS(NetTriviaSummary) << "GetPeers"; m_theyRequestedNodes = true; serviceNodesRequest(); break; } case PeersPacket: + // Disabled for interop testing. + // GetPeers/PeersPacket will be modified to only exchange new nodes which it's peers are interested in. + break; + clogS(NetTriviaSummary) << "Peers (" << dec << (_r.itemCount() - 1) << " entries)"; m_weRequestedNodes = false; for (unsigned i = 1; i < _r.itemCount(); ++i) @@ -304,41 +301,15 @@ bool Session::interpret(RLP const& _r) if (id == this->id()) goto LAMEPEER; // Just their info - we already have that. - // we don't worry about m_peers.count(id) now because node table will handle this and - // by default we will not blindly connect to nodes received via tcp; instead they will - // be pinged, as-is standard, by the node table and added if appropriate. unless flagged - // as required, nodes aren't connected to unless they respond via discovery; no matter if - // a node is relayed via udp or tcp. - // check that it's not us or one we already know: -// if (m_server->m_peers.count(id)) -// { -// /* MEH. Far from an ideal solution. Leave alone for now. -// // Already got this node. -// // See if it's any better that ours or not... -// // This could be the public address of a known node. -// // SECURITY: remove this in beta - it's only for lazy connections and presents an easy attack vector. -// if (m_server->m_peers.count(id) && isPrivateAddress(m_server->m_peers.at(id)->address.address()) && ep.port() != 0) -// // Update address if the node if we now have a public IP for it. -// m_server->m_peers[id]->address = ep; -// */ -// goto CONTINUE; -// } - if (!ep.port()) goto LAMEPEER; // Zero port? Don't think so. if (ep.port() >= /*49152*/32768) goto LAMEPEER; // Private port according to IANA. - // node table handles another node giving us a node which represents one of our other local network interfaces - // node table handles another node giving us a node we already know about - // OK passed all our checks. Assume it's good. addRating(1000); - - // TODO: P2P test m_server->addNode(Node(id, NodeIPEndpoint(bi::udp::endpoint(ep.address(), 30303), ep))); - clogS(NetTriviaDetail) << "New peer: " << ep << "(" << id .abridged()<< ")"; CONTINUE:; LAMEPEER:; diff --git a/libp2p/Session.h b/libp2p/Session.h index 55330c93c..68f9e5fa6 100644 --- a/libp2p/Session.h +++ b/libp2p/Session.h @@ -121,7 +121,6 @@ private: std::chrono::steady_clock::time_point m_lastReceived; ///< Time point of last message. std::map> m_capabilities; ///< The peer's capability set. - RangeMask m_knownNodes; ///< Nodes we already know about as indices into Host's nodesList. These shouldn't be resent to peer. }; } From 94ca6ca088d1c416df81c1b7bebb4d9eb752a01f Mon Sep 17 00:00:00 2001 From: subtly Date: Sat, 17 Jan 2015 00:56:36 -0500 Subject: [PATCH 014/213] cleanup --- libp2p/Host.cpp | 64 +------------------------------------------------ test/peer.cpp | 1 - 2 files changed, 1 insertion(+), 64 deletions(-) diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index d4ef54795..a63b47b76 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -462,69 +462,7 @@ unsigned PeerInfo::fallbackSeconds() const } // TODO: P2P rebuild nodetable when localNetworking is enabled/disabled -// TODO: P2P migrate grow/prunePeers into 'maintainPeers' & evaluate reputation instead of availability. schedule via deadline timer. -//void Host::growPeers() -//{ -// RecursiveGuard l(x_peers); -// int morePeers = (int)m_idealPeerCount - m_peers.size(); -// if (morePeers > 0) -// { -// auto toTry = m_ready; -// if (!m_netPrefs.localNetworking) -// toTry -= m_private; -// set ns; -// for (auto i: toTry) -// if (m_nodes[m_nodesList[i]]->shouldReconnect()) -// ns.insert(*m_nodes[m_nodesList[i]]); -// -// if (ns.size()) -// for (Node const& i: ns) -// { -// connect(m_nodes[i.id]); -// if (!--morePeers) -// return; -// } -// else -// for (auto const& i: m_peers) -// if (auto p = i.second.lock()) -// p->ensureNodesRequested(); -// } -//} -// -//void Host::prunePeers() -//{ -// RecursiveGuard l(x_peers); -// // We'll keep at most twice as many as is ideal, halfing what counts as "too young to kill" until we get there. -// set dc; -// for (unsigned old = 15000; m_peers.size() - dc.size() > m_idealPeerCount * 2 && old > 100; old /= 2) -// if (m_peers.size() - dc.size() > m_idealPeerCount) -// { -// // look for worst peer to kick off -// // first work out how many are old enough to kick off. -// shared_ptr worst; -// unsigned agedPeers = 0; -// for (auto i: m_peers) -// if (!dc.count(i.first)) -// if (auto p = i.second.lock()) -// if (chrono::steady_clock::now() > p->m_connect + chrono::milliseconds(old)) // don't throw off new peers; peer-servers should never kick off other peer-servers. -// { -// ++agedPeers; -// if ((!worst || p->rating() < worst->rating() || (p->rating() == worst->rating() && p->m_connect > worst->m_connect))) // kill older ones -// worst = p; -// } -// if (!worst || agedPeers <= m_idealPeerCount) -// break; -// dc.insert(worst->id()); -// worst->disconnect(TooManyPeers); -// } -// -// // Remove dead peers from list. -// for (auto i = m_peers.begin(); i != m_peers.end();) -// if (i->second.lock().get()) -// ++i; -// else -// i = m_peers.erase(i); -//} +// TODO: P2P implement 'maintainPeers' & evaluate reputation instead of availability. schedule via deadline timer. PeerSessionInfos Host::peers() const { diff --git a/test/peer.cpp b/test/peer.cpp index c3a617ce6..43ddc792a 100644 --- a/test/peer.cpp +++ b/test/peer.cpp @@ -36,7 +36,6 @@ BOOST_AUTO_TEST_CASE(host) NetworkPreferences host2prefs(30302, "127.0.0.1", true, true); Host host1("Test", host1prefs); - NodeId node1 = host1.id(); host1.start(); Host host2("Test", host2prefs); From c01b6da4345731cf8a6af8ce9480abc11923a28e Mon Sep 17 00:00:00 2001 From: subtly Date: Sat, 17 Jan 2015 01:10:50 -0500 Subject: [PATCH 015/213] cleanup --- libp2p/Host.cpp | 5 +++-- libp2p/Host.h | 5 ++--- libp2p/NodeTable.cpp | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index a63b47b76..b330386fb 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -374,7 +374,8 @@ void Host::addNode(NodeId const& _node, std::string const& _addr, unsigned short if (ec) { bi::tcp::resolver r(m_ioService); - r.async_resolve({_addr, toString(_tcpPeerPort)}, [=](boost::system::error_code const& _ec, bi::tcp::resolver::iterator _epIt) { + r.async_resolve({_addr, toString(_tcpPeerPort)}, [=](boost::system::error_code const& _ec, bi::tcp::resolver::iterator _epIt) + { if (_ec) return; bi::tcp::endpoint tcp = *_epIt; @@ -503,7 +504,7 @@ void Host::run(boost::system::error_code const&) if (chrono::steady_clock::now() - m_lastPing >= chrono::seconds(30)) // ping every 30s. keepAlivePeers(); - auto runcb = [this](boost::system::error_code const& error) -> void { run(error); }; + auto runcb = [this](boost::system::error_code const& error) { run(error); }; m_timer->expires_from_now(boost::posix_time::milliseconds(c_timerInterval)); m_timer->async_wait(runcb); } diff --git a/libp2p/Host.h b/libp2p/Host.h index f979ceebc..3b1825cca 100644 --- a/libp2p/Host.h +++ b/libp2p/Host.h @@ -78,11 +78,10 @@ struct PeerInfo // p2p: move to NodeIPEndpoint bool shouldReconnect() const { return std::chrono::system_clock::now() > lastAttempted + std::chrono::seconds(fallbackSeconds()); } - // p2p: This has two meanings now. It's possible UDP works but TPC is down (unable to punch hole). - // p2p: Rename to isConnect() and move to endpoint. revisit Session.cpp#245, MainWin.cpp#877 + // p2p: This has two meanings now. It's possible UDP works but TPC is down or vice-versa. bool isOffline() const { return lastAttempted > lastConnected; } - // p2p: Remove (in favor of lru eviction and sub-protocol ratings). + // p2p: Remove (in favor of lr-seen eviction and ratings). bool operator<(PeerInfo const& _n) const { if (isOffline() != _n.isOffline()) diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index 90916450d..75e642f2e 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -506,7 +506,7 @@ void NodeTable::doRefreshBuckets(boost::system::error_code const& _ec) } unsigned nextRefresh = connected ? (refreshed ? 200 : c_bucketRefresh.count()*1000) : 10000; - auto runcb = [this](boost::system::error_code const& error) -> void { doRefreshBuckets(error); }; + auto runcb = [this](boost::system::error_code const& error) { doRefreshBuckets(error); }; m_bucketRefreshTimer.expires_from_now(boost::posix_time::milliseconds(nextRefresh)); m_bucketRefreshTimer.async_wait(runcb); } From 8845967a1d536031ab9d771e42de59e183db58a3 Mon Sep 17 00:00:00 2001 From: subtly Date: Sat, 17 Jan 2015 01:30:52 -0500 Subject: [PATCH 016/213] coding standards --- libp2p/Host.cpp | 3 --- libp2p/NodeTable.cpp | 6 ++++++ libp2p/NodeTable.h | 8 +++----- test/peer.cpp | 2 +- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index b330386fb..8829b728e 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -53,7 +53,6 @@ Host::Host(std::string const& _clientVersion, NetworkPreferences const& _n, bool m_ioService(2), m_tcp4Acceptor(m_ioService), m_key(move(getHostIdentifier())) -// m_nodeTable(new NodeTable(m_ioService, m_key)) { for (auto address: m_ifAddresses) if (address.is_v4()) @@ -157,8 +156,6 @@ unsigned Host::protocolVersion() const void Host::registerPeer(std::shared_ptr _s, CapDescs const& _caps) { - asserts(!!_s->m_peer->id); - { RecursiveGuard l(x_sessions); if (!m_peers.count(_s->m_peer->id)) diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index 75e642f2e..242c1b325 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -53,6 +53,12 @@ NodeTable::~NodeTable() m_socketPtr->disconnect(); } +void NodeTable::processEvents() +{ + if (m_nodeEvents) + m_nodeEvents->processEvents(); +} + shared_ptr NodeTable::addNode(Public const& _pubk, bi::udp::endpoint const& _udp, bi::tcp::endpoint const& _tcp) { auto node = Node(_pubk, NodeIPEndpoint(_udp, _tcp)); diff --git a/libp2p/NodeTable.h b/libp2p/NodeTable.h index 66f445827..b68a9e346 100644 --- a/libp2p/NodeTable.h +++ b/libp2p/NodeTable.h @@ -94,7 +94,8 @@ public: protected: /// Called by NodeTable on behalf of an implementation (Host) to process new events without blocking nodetable. - void processEvents() { + void processEvents() + { std::list> events; { Guard l(x_events); @@ -183,10 +184,7 @@ public: void setEventHandler(NodeTableEventHandler* _handler) { m_nodeEvents.reset(_handler); } /// Called by implementation which provided handler to process NodeEntryAdded/NodeEntryRemoved events. Events are coalesced by type whereby old events are ignored. - void processEvents() { - if (m_nodeEvents) - m_nodeEvents->processEvents(); - } + void processEvents(); /// Add node. Node will be pinged if it's not already known. std::shared_ptr addNode(Public const& _pubk, bi::udp::endpoint const& _udp, bi::tcp::endpoint const& _tcp = bi::tcp::endpoint()); diff --git a/test/peer.cpp b/test/peer.cpp index 43ddc792a..51e777a56 100644 --- a/test/peer.cpp +++ b/test/peer.cpp @@ -44,7 +44,7 @@ BOOST_AUTO_TEST_CASE(host) host1.addNode(node2, "127.0.0.1", host2prefs.listenPort, host2prefs.listenPort); - this_thread::sleep_for(chrono::seconds(2)); + this_thread::sleep_for(chrono::seconds(1)); } BOOST_AUTO_TEST_SUITE_END() From 97f6145b939e43fa32ab4cd4dc521ff5a976ac79 Mon Sep 17 00:00:00 2001 From: subtly Date: Sat, 17 Jan 2015 02:45:59 -0500 Subject: [PATCH 017/213] compile fix --- alethzero/MainWin.cpp | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 0a6622e7c..87704eb04 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -943,17 +943,16 @@ void Main::refreshNetwork() auto ns = web3()->nodes(); for (p2p::PeerInfo const& i: ns) - if (!i.dead) - ui->nodes->insertItem(clients.count(i.id) ? 0 : ui->nodes->count(), QString("[%1 %3] %2 - ( =%5s | /%4s%6 ) - *%7 $%8") - .arg(QString::fromStdString(i.id.abridged())) - .arg(QString::fromStdString(toString(i.address))) - .arg(i.id == web3()->id() ? "self" : clients.count(i.id) ? clients[i.id] : i.secondsSinceLastAttempted() == -1 ? "session-fail" : i.secondsSinceLastAttempted() >= (int)i.fallbackSeconds() ? "retrying..." : "retry-" + QString::number(i.fallbackSeconds() - i.secondsSinceLastAttempted()) + "s") - .arg(i.secondsSinceLastAttempted()) - .arg(i.secondsSinceLastConnected()) - .arg(i.isOffline() ? " | " + QString::fromStdString(reasonOf(i.lastDisconnect)) + " | " + QString::number(i.failedAttempts) + "x" : "") - .arg(i.rating) - .arg(0 /* (int)i.idOrigin */) - ); + ui->nodes->insertItem(clients.count(i.id) ? 0 : ui->nodes->count(), QString("[%1 %3] %2 - ( =%5s | /%4s%6 ) - *%7 $%8") + .arg(QString::fromStdString(i.id.abridged())) + .arg(QString::fromStdString(toString(i.address))) + .arg(i.id == web3()->id() ? "self" : clients.count(i.id) ? clients[i.id] : i.secondsSinceLastAttempted() == -1 ? "session-fail" : i.secondsSinceLastAttempted() >= (int)i.fallbackSeconds() ? "retrying..." : "retry-" + QString::number(i.fallbackSeconds() - i.secondsSinceLastAttempted()) + "s") + .arg(i.secondsSinceLastAttempted()) + .arg(i.secondsSinceLastConnected()) + .arg(i.isOffline() ? " | " + QString::fromStdString(reasonOf(i.lastDisconnect)) + " | " + QString::number(i.failedAttempts) + "x" : "") + .arg(i.rating) + .arg(0 /* (int)i.idOrigin */) + ); } } From a4bafa86eb51f8dcb0163e147895470ac9d63e30 Mon Sep 17 00:00:00 2001 From: subtly Date: Sat, 17 Jan 2015 14:13:59 -0500 Subject: [PATCH 018/213] header include path --- libp2p/Host.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index 8829b728e..5eb948077 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include "Session.h" #include "Common.h" #include "Capability.h" From 6f174b50afe3f9853cb96e33ed192aa1e5f2cda3 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Wed, 21 Jan 2015 16:10:06 +0100 Subject: [PATCH 019/213] new file block.cpp --- test/block.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 test/block.cpp diff --git a/test/block.cpp b/test/block.cpp new file mode 100644 index 000000000..974acbf6d --- /dev/null +++ b/test/block.cpp @@ -0,0 +1,21 @@ +/* + 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 state.cpp + * @author Christoph Jentzsch + * @date 2014 + * block test functions. + */ From d7e3065f97c19381fff678fc15bb182819b31f49 Mon Sep 17 00:00:00 2001 From: subtly Date: Thu, 22 Jan 2015 18:32:12 -0500 Subject: [PATCH 020/213] Remove unused code paths with confidence. Rename key/identity to alias. Inherit Peer from Node and update Host/Session to use Node::endpoint instead of previous Peer::address. --- alethzero/MainWin.cpp | 2 +- libp2p/Common.h | 47 ++++++++++++++++-- libp2p/Host.cpp | 89 ++++++++++++++------------------- libp2p/Host.h | 110 +++++++++++++++++++---------------------- libp2p/NodeTable.h | 40 +-------------- libp2p/Session.cpp | 17 +++---- libp2p/Session.h | 6 +-- libwebthree/WebThree.h | 4 +- 8 files changed, 148 insertions(+), 167 deletions(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 87704eb04..6a44a2b24 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -942,7 +942,7 @@ void Main::refreshNetwork() .arg(QString::fromStdString(i.id.abridged()))); auto ns = web3()->nodes(); - for (p2p::PeerInfo const& i: ns) + for (p2p::Peer const& i: ns) ui->nodes->insertItem(clients.count(i.id) ? 0 : ui->nodes->count(), QString("[%1 %3] %2 - ( =%5s | /%4s%6 ) - *%7 $%8") .arg(QString::fromStdString(i.id.abridged())) .arg(QString::fromStdString(toString(i.address))) diff --git a/libp2p/Common.h b/libp2p/Common.h index 059e1a64e..38012ec76 100644 --- a/libp2p/Common.h +++ b/libp2p/Common.h @@ -16,9 +16,10 @@ */ /** @file Common.h * @author Gav Wood + * @author Alex Leverington * @date 2014 * - * Miscellanea required for the Host/Session classes. + * Miscellanea required for the Host/Session/NodeTable classes. */ #pragma once @@ -29,9 +30,8 @@ #include #include #include -#include +#include #include -#include namespace ba = boost::asio; namespace bi = boost::asio::ip; @@ -116,6 +116,11 @@ typedef std::pair CapDesc; typedef std::set CapDescSet; typedef std::vector CapDescs; +/* + * Used by Host to pass negotiated information about a connection to a + * new Peer Session; PeerSessionInfo is then maintained by Session and can + * be queried for point-in-time status information via Host. + */ struct PeerSessionInfo { NodeId id; @@ -130,5 +135,41 @@ struct PeerSessionInfo using PeerSessionInfos = std::vector; +/** + * @brief IPv4,UDP/TCP endpoints. + */ +struct NodeIPEndpoint +{ + NodeIPEndpoint(): udp(bi::udp::endpoint()), tcp(bi::tcp::endpoint()) {} + NodeIPEndpoint(bi::udp::endpoint _udp): udp(_udp) {} + NodeIPEndpoint(bi::tcp::endpoint _tcp): tcp(_tcp) {} + NodeIPEndpoint(bi::udp::endpoint _udp, bi::tcp::endpoint _tcp): udp(_udp), tcp(_tcp) {} + + bi::udp::endpoint udp; + bi::tcp::endpoint tcp; + + operator bool() const { return udp.address().is_unspecified() && tcp.address().is_unspecified(); } +}; + +struct Node +{ + Node(): endpoint(NodeIPEndpoint()) {}; + Node(Public _pubk, NodeIPEndpoint _ip, bool _required = false): id(_pubk), endpoint(_ip), required(_required) {} + Node(Public _pubk, bi::udp::endpoint _udp, bool _required = false): Node(_pubk, NodeIPEndpoint(_udp), _required) {} + + virtual NodeId const& address() const { return id; } + virtual Public const& publicKey() const { return id; } + + NodeId id; + + /// Endpoints by which we expect to reach node. + NodeIPEndpoint endpoint; + + /// If true, node will not be removed from Node list. + bool required = false; + + operator bool() const { return (bool)id; } +}; + } } diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index 5eb948077..38929278d 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -52,7 +52,7 @@ Host::Host(std::string const& _clientVersion, NetworkPreferences const& _n, bool m_ifAddresses(Network::getInterfaceAddresses()), m_ioService(2), m_tcp4Acceptor(m_ioService), - m_key(move(getHostIdentifier())) + m_alias(move(getHostIdentifier())) { for (auto address: m_ifAddresses) if (address.is_v4()) @@ -186,12 +186,20 @@ void Host::onNodeTableEvent(NodeId _n, NodeTableEventType _e) auto p = m_peers[_n]; if (!p) { - m_peers[_n] = make_shared(); + m_peers[_n] = make_shared(); p = m_peers[_n]; p->id = _n; } - p->address = n.endpoint.tcp; + p->endpoint.tcp = n.endpoint.tcp; + // TODO: Implement similar to doFindNode. Attempt connecting to nodes + // until ideal peer count is reached; if all nodes are tried, + // repeat. Notably, this is an integrated process such that + // when onNodeTableEvent occurs we should also update +/- + // the list of nodes to be tried. Thus: + // 1) externalize connection attempts + // 2) attempt copies potentialPeer list + // 3) replace this logic w/maintenance of potentialPeers if (peerCount() < m_idealPeerCount) connect(p); } @@ -334,14 +342,14 @@ void Host::doHandshake(bi::tcp::socket* _socket, NodeId _nodeId) clog(NetConnect) << "Accepting connection for " << _socket->remote_endpoint(); } catch (...){} - shared_ptr p; + shared_ptr p; if (_nodeId) p = m_peers[_nodeId]; if (!p) { - p = make_shared(); - p->address.address(_socket->remote_endpoint().address()); + p = make_shared(); + p->endpoint.tcp.address(_socket->remote_endpoint().address()); } auto ps = std::make_shared(this, std::move(*_socket), p); @@ -357,6 +365,8 @@ string Host::pocHost() void Host::addNode(NodeId const& _node, std::string const& _addr, unsigned short _tcpPeerPort, unsigned short _udpNodePort) { + + if (_tcpPeerPort < 30300 || _tcpPeerPort > 30305) cwarn << "Non-standard port being recorded: " << _tcpPeerPort; @@ -383,7 +393,7 @@ void Host::addNode(NodeId const& _node, std::string const& _addr, unsigned short addNode(Node(_node, NodeIPEndpoint(bi::udp::endpoint(addr, _udpNodePort), bi::tcp::endpoint(addr, _tcpPeerPort)))); } -void Host::connect(std::shared_ptr const& _n) +void Host::connect(std::shared_ptr const& _n) { if (!m_run) return; @@ -401,7 +411,7 @@ void Host::connect(std::shared_ptr const& _n) } // prevent concurrently connecting to a node - PeerInfo *nptr = _n.get(); + Peer *nptr = _n.get(); { Guard l(x_pendingNodeConns); if (m_pendingNodeConns.count(nptr)) @@ -409,22 +419,19 @@ void Host::connect(std::shared_ptr const& _n) m_pendingNodeConns.insert(nptr); } - clog(NetConnect) << "Attempting connection to node" << _n->id.abridged() << "@" << _n->address << "from" << id().abridged(); - _n->lastAttempted = std::chrono::system_clock::now(); - _n->failedAttempts++; - + clog(NetConnect) << "Attempting connection to node" << _n->id.abridged() << "@" << _n->peerEndpoint() << "from" << id().abridged(); bi::tcp::socket* s = new bi::tcp::socket(m_ioService); - s->async_connect(_n->address, [=](boost::system::error_code const& ec) + s->async_connect(_n->peerEndpoint(), [=](boost::system::error_code const& ec) { if (ec) { - clog(NetConnect) << "Connection refused to node" << _n->id.abridged() << "@" << _n->address << "(" << ec.message() << ")"; + clog(NetConnect) << "Connection refused to node" << _n->id.abridged() << "@" << _n->peerEndpoint() << "(" << ec.message() << ")"; _n->lastDisconnect = TCPError; _n->lastAttempted = std::chrono::system_clock::now(); } else { - clog(NetConnect) << "Connected to" << _n->id.abridged() << "@" << _n->address; + clog(NetConnect) << "Connected to" << _n->id.abridged() << "@" << _n->peerEndpoint(); _n->lastConnected = std::chrono::system_clock::now(); auto ps = make_shared(this, std::move(*s), _n); @@ -437,31 +444,6 @@ void Host::connect(std::shared_ptr const& _n) }); } -unsigned PeerInfo::fallbackSeconds() const -{ - switch (lastDisconnect) - { - case BadProtocol: - return 30 * (failedAttempts + 1); - case UselessPeer: - case TooManyPeers: - case ClientQuit: - return 15 * (failedAttempts + 1); - case NoDisconnect: - return 0; - default: - if (failedAttempts < 5) - return failedAttempts * 5; - else if (failedAttempts < 15) - return 25 + (failedAttempts - 5) * 10; - else - return 25 + 100 + (failedAttempts - 15) * 20; - } -} - -// TODO: P2P rebuild nodetable when localNetworking is enabled/disabled -// TODO: P2P implement 'maintainPeers' & evaluate reputation instead of availability. schedule via deadline timer. - PeerSessionInfos Host::peers() const { if (!m_run) @@ -538,12 +520,14 @@ void Host::startedWorking() if (!m_tcpPublic.address().is_unspecified()) // TODO: add m_tcpPublic endpoint; sort out endpoint stuff for nodetable - m_nodeTable.reset(new NodeTable(m_ioService, m_key, m_listenPort)); + m_nodeTable.reset(new NodeTable(m_ioService, m_alias, m_listenPort)); else - m_nodeTable.reset(new NodeTable(m_ioService, m_key, m_listenPort > 0 ? m_listenPort : 30303)); + m_nodeTable.reset(new NodeTable(m_ioService, m_alias, m_listenPort > 0 ? m_listenPort : 30303)); m_nodeTable->setEventHandler(new HostNodeTableHandler(*this)); } - + else + clog(NetNote) << "p2p.start.notice id:" << id().abridged() << "Invalid listen-port. Node Table Disabled."; + clog(NetNote) << "p2p.started id:" << id().abridged(); run(boost::system::error_code()); @@ -578,16 +562,16 @@ bytes Host::saveNodes() const RecursiveGuard l(x_sessions); for (auto const& i: m_peers) { - PeerInfo const& n = *(i.second); + Peer const& n = *(i.second); // TODO: PoC-7: Figure out why it ever shares these ports.//n.address.port() >= 30300 && n.address.port() <= 30305 && - if (chrono::system_clock::now() - n.lastConnected < chrono::seconds(3600 * 48) && n.address.port() > 0 && n.address.port() < /*49152*/32768 && n.id != id() && !isPrivateAddress(n.address.address())) + if (chrono::system_clock::now() - n.lastConnected < chrono::seconds(3600 * 48) && n.peerEndpoint().port() > 0 && n.peerEndpoint().port() < /*49152*/32768 && n.id != id() && !isPrivateAddress(n.peerEndpoint().address())) { nodes.appendList(10); - if (n.address.address().is_v4()) - nodes << n.address.address().to_v4().to_bytes(); + if (n.peerEndpoint().address().is_v4()) + nodes << n.peerEndpoint().address().to_v4().to_bytes(); else - nodes << n.address.address().to_v6().to_bytes(); - nodes << n.address.port() << n.id /* << (int)n.idOrigin */ << 0 + nodes << n.peerEndpoint().address().to_v6().to_bytes(); + nodes << n.peerEndpoint().port() << n.id /* << (int)n.idOrigin */ << 0 << chrono::duration_cast(n.lastConnected.time_since_epoch()).count() << chrono::duration_cast(n.lastAttempted.time_since_epoch()).count() << n.failedAttempts << (unsigned)n.lastDisconnect << n.score << n.rating; @@ -596,11 +580,12 @@ bytes Host::saveNodes() const } } RLPStream ret(3); - ret << 0 << m_key.secret(); + ret << 0 << m_alias.secret(); ret.appendList(count).appendRaw(nodes.out(), count); return ret.out(); } +// TODO: p2p Import-ant void Host::restoreNodes(bytesConstRef _b) { RecursiveGuard l(x_sessions); @@ -610,7 +595,7 @@ void Host::restoreNodes(bytesConstRef _b) { case 0: { - m_key = KeyPair(r[1].toHash()); + m_alias = KeyPair(r[1].toHash()); // noteNode(id(), m_tcpPublic); for (auto i: r[2]) @@ -623,7 +608,7 @@ void Host::restoreNodes(bytesConstRef _b) auto id = (NodeId)i[2]; if (!m_peers.count(id)) { -//// auto o = (Origin)i[3].toInt(); + // TODO: p2p Important :) // auto n = noteNode(id, ep); // n->lastConnected = chrono::system_clock::time_point(chrono::seconds(i[4].toInt())); // n->lastAttempted = chrono::system_clock::time_point(chrono::seconds(i[5].toInt())); diff --git a/libp2p/Host.h b/libp2p/Host.h index 3b1825cca..1719bac6a 100644 --- a/libp2p/Host.h +++ b/libp2p/Host.h @@ -51,58 +51,50 @@ namespace p2p class Host; -struct PeerInfo +/** + * @brief Representation of connectivity state and all other pertinent Peer metadata. + * A Peer represents connectivity between two nodes, which in this case, are the host + * and remote nodes. + * + * State information necessary for loading network topology is maintained by NodeTable. + * + * @todo Implement 'bool required' + * @todo reputation: Move score, rating to capability-specific map (&& remove friend class) + * @todo reputation: implement via origin-tagged events + * @todo Populate metadata upon construction; save when destroyed. + * @todo Metadata for peers needs to be handled via a storage backend. + * Specifically, peers can be utilized in a variety of + * many-to-many relationships while also needing to modify shared instances of + * those peers. Modifying these properties via a storage backend alleviates + * Host of the responsibility. (&& remove save/restoreNodes) + * @todo reimplement recording of historical session information on per-transport basis + * @todo rebuild nodetable when localNetworking is enabled/disabled + */ +class Peer: public Node { - NodeId id; ///< Their id/public key. + friend class Session; /// Allows Session to update score and rating. + friend class Host; /// For Host: saveNodes(), restoreNodes() +public: + bool isOffline() const { return !m_session.lock(); } + + bi::tcp::endpoint const& peerEndpoint() const { return endpoint.tcp; } + +protected: + + /// Used by isOffline() and (todo) for peer to emit session information. + std::weak_ptr m_session; + + int score = 0; ///< All time cumulative. + int rating = 0; ///< Trending. - // p2p: move to NodeIPEndpoint - bi::tcp::endpoint address; ///< As reported from the node itself. + /// Network Availability - // p2p: This information is relevant to the network-stack, ex: firewall, rather than node itself std::chrono::system_clock::time_point lastConnected; std::chrono::system_clock::time_point lastAttempted; unsigned failedAttempts = 0; DisconnectReason lastDisconnect = NoDisconnect; ///< Reason for disconnect that happened last. - - // p2p: move to protocol-specific map - int score = 0; ///< All time cumulative. - int rating = 0; ///< Trending. - - // p2p: move to NodeIPEndpoint - int secondsSinceLastConnected() const { return lastConnected == std::chrono::system_clock::time_point() ? -1 : (int)std::chrono::duration_cast(std::chrono::system_clock::now() - lastConnected).count(); } - // p2p: move to NodeIPEndpoint - int secondsSinceLastAttempted() const { return lastAttempted == std::chrono::system_clock::time_point() ? -1 : (int)std::chrono::duration_cast(std::chrono::system_clock::now() - lastAttempted).count(); } - - // p2p: move to NodeIPEndpoint - unsigned fallbackSeconds() const; - // p2p: move to NodeIPEndpoint - bool shouldReconnect() const { return std::chrono::system_clock::now() > lastAttempted + std::chrono::seconds(fallbackSeconds()); } - - // p2p: This has two meanings now. It's possible UDP works but TPC is down or vice-versa. - bool isOffline() const { return lastAttempted > lastConnected; } - - // p2p: Remove (in favor of lr-seen eviction and ratings). - bool operator<(PeerInfo const& _n) const - { - if (isOffline() != _n.isOffline()) - return isOffline(); - else if (isOffline()) - if (lastAttempted == _n.lastAttempted) - return failedAttempts < _n.failedAttempts; - else - return lastAttempted < _n.lastAttempted; - else - if (score == _n.score) - if (rating == _n.rating) - return failedAttempts < _n.failedAttempts; - else - return rating < _n.rating; - else - return score < _n.score; - } }; - -using Nodes = std::vector; +using Peers = std::vector; class HostNodeTableHandler: public NodeTableEventHandler @@ -116,18 +108,18 @@ class HostNodeTableHandler: public NodeTableEventHandler /** * @brief The Host class * Capabilities should be registered prior to startNetwork, since m_capabilities is not thread-safe. - * @todo gracefully disconnect peer if peer already connected + * + * @todo onNodeTableEvent: move peer-connection logic into ensurePeers + * @todo handshake: gracefully disconnect peer if peer already connected * @todo determinePublic: ipv6, udp * @todo handle conflict if addNode/requireNode called and Node already exists w/conflicting tcp or udp port - * @todo write host identifier to disk along w/nodes - * @todo move Session::addRating into Host and implement via sender-tagged events + * @todo write host identifier to disk w/nodes */ class Host: public Worker { friend class HostNodeTableHandler; friend class Session; friend class HostCapabilityFace; - friend struct PeerInfo; public: /// Start server, listening for connections on the given port. @@ -163,6 +155,9 @@ public: /// Get number of peers connected; equivalent to, but faster than, peers().size(). size_t peerCount() const { RecursiveGuard l(x_sessions); return m_peers.size(); } + /// Get the address we're listening on currently. + std::string listenAddress() const { return m_tcpPublic.address().to_string(); } + /// Get the port we're listening on currently. unsigned short listenPort() const { return m_tcpPublic.port(); } @@ -173,7 +168,7 @@ public: void restoreNodes(bytesConstRef _b); // TODO: P2P this should be combined with peers into a HostStat object of some kind; coalesce data, as it's only used for status information. - Nodes nodes() const { RecursiveGuard l(x_sessions); Nodes ret; for (auto const& i: m_peers) ret.push_back(*i.second); return ret; } + Peers nodes() const { RecursiveGuard l(x_sessions); Peers ret; for (auto const& i: m_peers) ret.push_back(*i.second); return ret; } void setNetworkPreferences(NetworkPreferences const& _p) { auto had = isStarted(); if (had) stop(); m_netPrefs = _p; if (had) start(); } @@ -187,12 +182,10 @@ public: /// @returns if network is running. bool isStarted() const { return m_run; } - NodeId id() const { return m_key.pub(); } + NodeId id() const { return m_alias.pub(); } void registerPeer(std::shared_ptr _s, CapDescs const& _caps); -// std::shared_ptr node(NodeId _id) const { if (m_nodes.count(_id)) return m_nodes.at(_id); return std::shared_ptr(); } - protected: void onNodeTableEvent(NodeId _n, NodeTableEventType _e); @@ -200,7 +193,7 @@ private: /// Populate m_peerAddresses with available public addresses. void determinePublic(std::string const& _publicAddress, bool _upnp); - void connect(std::shared_ptr const& _n); + void connect(std::shared_ptr const& _n); /// Ping the peers to update the latency information and disconnect peers which have timed out. void keepAlivePeers(); @@ -225,7 +218,7 @@ private: virtual void doneWorking(); /// Add node - void addNode(Node const& _node) { m_nodeTable->addNode(_node); } + void addNode(Node const& _node) { if (m_nodeTable) m_nodeTable->addNode(_node); } /// Get or create host identifier (KeyPair). KeyPair getHostIdentifier(); @@ -248,16 +241,17 @@ private: std::unique_ptr m_timer; ///< Timer which, when network is running, calls scheduler() every c_timerInterval ms. static const unsigned c_timerInterval = 100; ///< Interval which m_timer is run when network is connected. - std::set m_pendingNodeConns; /// Used only by connect(PeerInfo&) to limit concurrently connecting to same node. See connect(shared_ptrconst&). + std::set m_pendingNodeConns; /// Used only by connect(Peer&) to limit concurrently connecting to same node. See connect(shared_ptrconst&). Mutex x_pendingNodeConns; bi::tcp::endpoint m_tcpPublic; ///< Our public listening endpoint. - KeyPair m_key; ///< Our unique ID. + KeyPair m_alias; ///< Alias for network communication. Network address is k*G. k is key material. TODO: Replace KeyPair. std::shared_ptr m_nodeTable; ///< Node table (uses kademlia-like discovery). - std::map> m_peers; + /// Shared storage of Peer objects. Peers are created or destroyed on demand by the Host. Active sessions maintain a shared_ptr to a Peer; + std::map> m_peers; - /// The nodes to which we are currently connected. + /// The nodes to which we are currently connected. Used by host to service peer requests and keepAlivePeers and for shutdown. (see run()) /// Mutable because we flush zombie entries (null-weakptrs) as regular maintenance from a const method. mutable std::map> m_sessions; mutable RecursiveMutex x_sessions; diff --git a/libp2p/NodeTable.h b/libp2p/NodeTable.h index b68a9e346..dee10c7ae 100644 --- a/libp2p/NodeTable.h +++ b/libp2p/NodeTable.h @@ -24,51 +24,14 @@ #include #include #include -#include #include +#include "Common.h" namespace dev { namespace p2p { -/** - * @brief IPv4,UDP/TCP endpoints. - */ -struct NodeIPEndpoint -{ - NodeIPEndpoint(): udp(bi::udp::endpoint()), tcp(bi::tcp::endpoint()) {} - NodeIPEndpoint(bi::udp::endpoint _udp): udp(_udp) {} - NodeIPEndpoint(bi::tcp::endpoint _tcp): tcp(_tcp) {} - NodeIPEndpoint(bi::udp::endpoint _udp, bi::tcp::endpoint _tcp): udp(_udp), tcp(_tcp) {} - - bi::udp::endpoint udp; - bi::tcp::endpoint tcp; - - operator bool() const { return udp.address().is_unspecified() && tcp.address().is_unspecified(); } -}; - -struct Node -{ - Node(): endpoint(NodeIPEndpoint()) {}; - Node(Public _pubk, NodeIPEndpoint _ip, bool _required = false): id(_pubk), endpoint(_ip), required(_required) {} - Node(Public _pubk, bi::udp::endpoint _udp, bool _required = false): Node(_pubk, NodeIPEndpoint(_udp), _required) {} - - virtual NodeId const& address() const { return id; } - virtual Public const& publicKey() const { return id; } - - NodeId id; - - /// Endpoints by which we expect to reach node. - NodeIPEndpoint endpoint; - - /// If true, node will not be removed from Node list. - bool required = false; - - operator bool() const { return (bool)id; } -}; - - /** * NodeEntry * @brief Entry in Node Table @@ -151,7 +114,6 @@ protected: */ class NodeTable: UDPSocketEvents, public std::enable_shared_from_this { - friend struct Neighbours; using NodeSocket = UDPSocket; using TimePoint = std::chrono::steady_clock::time_point; using EvictionTimeout = std::pair,NodeId>; ///< First NodeId may be evicted and replaced with second NodeId. diff --git a/libp2p/Session.cpp b/libp2p/Session.cpp index d57a16fa2..9f68f3ef0 100644 --- a/libp2p/Session.cpp +++ b/libp2p/Session.cpp @@ -36,7 +36,7 @@ using namespace dev::p2p; #endif #define clogS(X) dev::LogOutputStream(false) << "| " << std::setw(2) << m_socket.native_handle() << "] " -Session::Session(Host* _s, bi::tcp::socket _socket, std::shared_ptr const& _n): +Session::Session(Host* _s, bi::tcp::socket _socket, std::shared_ptr const& _n): m_server(_s), m_socket(std::move(_socket)), m_peer(_n), @@ -114,9 +114,9 @@ void Session::serviceNodesRequest() if (!m_theyRequestedNodes) return; -// TODO: P2P +// TODO: P2P reimplement, as per TCP "close nodes" gossip specifications (WiP) // auto peers = m_server->potentialPeers(m_knownNodes); - Nodes peers; + Peers peers; if (peers.empty()) { addNote("peers", "requested"); @@ -129,11 +129,11 @@ void Session::serviceNodesRequest() auto rs = randomSelection(peers, 10); for (auto const& i: rs) { - clogS(NetTriviaDetail) << "Sending peer " << i.id.abridged() << i.address; - if (i.address.address().is_v4()) - s.appendList(3) << bytesConstRef(i.address.address().to_v4().to_bytes().data(), 4) << i.address.port() << i.id; + clogS(NetTriviaDetail) << "Sending peer " << i.id.abridged() << i.peerEndpoint(); + if (i.peerEndpoint().address().is_v4()) + s.appendList(3) << bytesConstRef(i.peerEndpoint().address().to_v4().to_bytes().data(), 4) << i.peerEndpoint().port() << i.id; else// if (i.second.address().is_v6()) - assumed - s.appendList(3) << bytesConstRef(i.address.address().to_v6().to_bytes().data(), 16) << i.address.port() << i.id; + s.appendList(3) << bytesConstRef(i.peerEndpoint().address().to_v6().to_bytes().data(), 16) << i.peerEndpoint().port() << i.id; } sealAndSend(s); m_theyRequestedNodes = false; @@ -188,7 +188,7 @@ bool Session::interpret(RLP const& _r) else if (!m_peer->id) { m_peer->id = id; - m_peer->address.port(listenPort); + m_peer->endpoint.tcp.port(listenPort); } else if (m_peer->id != id) { @@ -386,7 +386,6 @@ void Session::send(bytes&& _msg) if (!checkPacket(bytesConstRef(&_msg))) clogS(NetWarn) << "INVALID PACKET CONSTRUCTED!"; -// cerr << (void*)this << " writeImpl" << endl; if (!m_socket.is_open()) return; diff --git a/libp2p/Session.h b/libp2p/Session.h index 68f9e5fa6..87620a604 100644 --- a/libp2p/Session.h +++ b/libp2p/Session.h @@ -39,7 +39,7 @@ namespace dev namespace p2p { -struct PeerInfo; +class Peer; /** * @brief The Session class @@ -51,7 +51,7 @@ class Session: public std::enable_shared_from_this friend class HostCapabilityFace; public: - Session(Host* _server, bi::tcp::socket _socket, std::shared_ptr const& _n); + Session(Host* _server, bi::tcp::socket _socket, std::shared_ptr const& _n); virtual ~Session(); void start(); @@ -108,7 +108,7 @@ private: bytes m_incoming; ///< Read buffer for ingress bytes. unsigned m_protocolVersion = 0; ///< The protocol version of the peer. - std::shared_ptr m_peer; ///< The PeerInfo object. + std::shared_ptr m_peer; ///< The Peer object. bool m_dropped = false; ///< If true, we've already divested ourselves of this peer. We're just waiting for the reads & writes to fail before the shared_ptr goes OOS and the destructor kicks in. PeerSessionInfo m_info; ///< Dynamic information about this peer. diff --git a/libwebthree/WebThree.h b/libwebthree/WebThree.h index f2130d3f4..3b97a0763 100644 --- a/libwebthree/WebThree.h +++ b/libwebthree/WebThree.h @@ -78,7 +78,7 @@ public: virtual p2p::NodeId id() const = 0; /// Gets the nodes. - virtual p2p::Nodes nodes() const = 0; + virtual p2p::Peers nodes() const = 0; /// Start the network subsystem. virtual void startNetwork() = 0; @@ -148,7 +148,7 @@ public: p2p::NodeId id() const override { return m_net.id(); } /// Gets the nodes. - p2p::Nodes nodes() const override { return m_net.nodes(); } + p2p::Peers nodes() const override { return m_net.nodes(); } /// Start the network subsystem. void startNetwork() override { m_net.start(); } From 26f8d3b62dcee0ca958420ececce9aa913bd85d8 Mon Sep 17 00:00:00 2001 From: subtly Date: Thu, 22 Jan 2015 19:50:33 -0500 Subject: [PATCH 021/213] update whisper test. move ports out of private ranges and specify ip address. --- test/whisperTopic.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/test/whisperTopic.cpp b/test/whisperTopic.cpp index ea46b162c..9f0f34630 100644 --- a/test/whisperTopic.cpp +++ b/test/whisperTopic.cpp @@ -36,15 +36,16 @@ BOOST_AUTO_TEST_CASE(topic) auto oldLogVerbosity = g_logVerbosity; g_logVerbosity = 0; + Host ph1("Test", NetworkPreferences(30303, "127.0.0.1", true, true)); + bool started = false; unsigned result = 0; std::thread listener([&]() { setThreadName("other"); - Host ph("Test", NetworkPreferences(50303, "", false, true)); - auto wh = ph.registerCapability(new WhisperHost()); - ph.start(); + auto wh = ph1.registerCapability(new WhisperHost()); + ph1.start(); started = true; @@ -67,12 +68,12 @@ BOOST_AUTO_TEST_CASE(topic) while (!started) this_thread::sleep_for(chrono::milliseconds(50)); - Host ph("Test", NetworkPreferences(50300, "", false, true)); + Host ph("Test", NetworkPreferences(30300, "127.0.0.1", true, true)); auto wh = ph.registerCapability(new WhisperHost()); this_thread::sleep_for(chrono::milliseconds(500)); ph.start(); this_thread::sleep_for(chrono::milliseconds(500)); - ph.addNode(NodeId(), "127.0.0.1", 50303, 50303); + ph.addNode(ph1.id(), "127.0.0.1", 30303, 30303); KeyPair us = KeyPair::create(); for (int i = 0; i < 10; ++i) From a73f1fa7c55923cf13550efe8809e0ac26efaa8f Mon Sep 17 00:00:00 2001 From: subtly Date: Fri, 23 Jan 2015 04:23:55 -0500 Subject: [PATCH 022/213] add packet-type. prep for node-discovery interop. --- alethzero/MainWin.cpp | 13 +++++-------- libp2p/Host.h | 11 +++++------ libp2p/NodeTable.cpp | 25 +++++++++++++++---------- libp2p/NodeTable.h | 22 +++++++++++----------- libp2p/UDP.cpp | 14 +++++++++++--- libp2p/UDP.h | 3 ++- 6 files changed, 49 insertions(+), 39 deletions(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 7a28948f4..d96c55917 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -938,13 +938,13 @@ void Main::refreshNetwork() if (web3()->haveNetwork()) { - map clients; + map sessions; for (PeerSessionInfo const& i: ps) ui->peers->addItem(QString("[%8 %7] %3 ms - %1:%2 - %4 %5 %6") .arg(QString::fromStdString(i.host)) .arg(i.port) .arg(chrono::duration_cast(i.lastPing).count()) - .arg(clients[i.id] = QString::fromStdString(i.clientVersion)) + .arg(sessions[i.id] = QString::fromStdString(i.clientVersion)) .arg(QString::fromStdString(toString(i.caps))) .arg(QString::fromStdString(toString(i.notes))) .arg(i.socket) @@ -952,15 +952,12 @@ void Main::refreshNetwork() auto ns = web3()->nodes(); for (p2p::Peer const& i: ns) - ui->nodes->insertItem(clients.count(i.id) ? 0 : ui->nodes->count(), QString("[%1 %3] %2 - ( =%5s | /%4s%6 ) - *%7 $%8") + ui->nodes->insertItem(sessions.count(i.id) ? 0 : ui->nodes->count(), QString("[%1 %3] %2 - ( =%5s | /%4s%6 ) - *%7 $%8") .arg(QString::fromStdString(i.id.abridged())) - .arg(QString::fromStdString(toString(i.address))) - .arg(i.id == web3()->id() ? "self" : clients.count(i.id) ? clients[i.id] : i.secondsSinceLastAttempted() == -1 ? "session-fail" : i.secondsSinceLastAttempted() >= (int)i.fallbackSeconds() ? "retrying..." : "retry-" + QString::number(i.fallbackSeconds() - i.secondsSinceLastAttempted()) + "s") - .arg(i.secondsSinceLastAttempted()) - .arg(i.secondsSinceLastConnected()) + .arg(QString::fromStdString(i.peerEndpoint().address().to_string())) + .arg(i.id == web3()->id() ? "self" : sessions.count(i.id) ? sessions[i.id] : "disconnected") .arg(i.isOffline() ? " | " + QString::fromStdString(reasonOf(i.lastDisconnect)) + " | " + QString::number(i.failedAttempts) + "x" : "") .arg(i.rating) - .arg(0 /* (int)i.idOrigin */) ); } } diff --git a/libp2p/Host.h b/libp2p/Host.h index 1719bac6a..bffc6c39f 100644 --- a/libp2p/Host.h +++ b/libp2p/Host.h @@ -69,6 +69,7 @@ class Host; * Host of the responsibility. (&& remove save/restoreNodes) * @todo reimplement recording of historical session information on per-transport basis * @todo rebuild nodetable when localNetworking is enabled/disabled + * @todo move attributes into protected */ class Peer: public Node { @@ -79,11 +80,6 @@ public: bi::tcp::endpoint const& peerEndpoint() const { return endpoint.tcp; } -protected: - - /// Used by isOffline() and (todo) for peer to emit session information. - std::weak_ptr m_session; - int score = 0; ///< All time cumulative. int rating = 0; ///< Trending. @@ -93,6 +89,10 @@ protected: std::chrono::system_clock::time_point lastAttempted; unsigned failedAttempts = 0; DisconnectReason lastDisconnect = NoDisconnect; ///< Reason for disconnect that happened last. + +protected: + /// Used by isOffline() and (todo) for peer to emit session information. + std::weak_ptr m_session; }; using Peers = std::vector; @@ -260,7 +260,6 @@ private: std::set m_peerAddresses; ///< Public addresses that peers (can) know us by. - // Our capabilities. std::map> m_capabilities; ///< Each of the capabilities we support. std::chrono::steady_clock::time_point m_lastPing; ///< Time we sent the last ping to all peers. diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index 242c1b325..40688f4a5 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -352,24 +352,24 @@ NodeTable::NodeBucket& NodeTable::bucket(NodeEntry const* _n) void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytesConstRef _packet) { - // h256 + Signature + RLP (smallest possible packet is empty neighbours packet which is 3 bytes) - if (_packet.size() < h256::size + Signature::size + 3) + // h256 + Signature + type + RLP (smallest possible packet is empty neighbours packet which is 3 bytes) + if (_packet.size() < h256::size + Signature::size + 1 + 3) { clog(NodeTableMessageSummary) << "Invalid Message size from " << _from.address().to_string() << ":" << _from.port(); return; } - bytesConstRef signedBytes(_packet.cropped(h256::size, _packet.size() - h256::size)); - h256 hashSigned(sha3(signedBytes)); + bytesConstRef hashedBytes(_packet.cropped(h256::size, _packet.size() - h256::size)); + h256 hashSigned(sha3(hashedBytes)); if (!_packet.cropped(0, h256::size).contentsEqual(hashSigned.asBytes())) { clog(NodeTableMessageSummary) << "Invalid Message hash from " << _from.address().to_string() << ":" << _from.port(); return; } + + bytesConstRef rlpBytes(hashedBytes.cropped(Signature::size, hashedBytes.size() - Signature::size)); - bytesConstRef rlpBytes(signedBytes.cropped(Signature::size, signedBytes.size() - Signature::size)); - RLP rlp(rlpBytes); - unsigned itemCount = rlp.itemCount(); + // todo: verify sig via known-nodeid and MDC, or, do ping/pong auth if node/endpoint is unknown/untrusted bytesConstRef sigBytes(_packet.cropped(h256::size, Signature::size)); Public nodeid(dev::recover(*(Signature const*)sigBytes.data(), sha3(rlpBytes))); @@ -378,8 +378,13 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes clog(NodeTableMessageSummary) << "Invalid Message signature from " << _from.address().to_string() << ":" << _from.port(); return; } - noteNode(nodeid, _from); + if (rlpBytes[0] && rlpBytes[0] < 4) + noteNode(nodeid, _from); + + // todo: switch packet-type + RLP rlp(rlpBytes.cropped(1, rlpBytes.size() - 1)); + unsigned itemCount = rlp.itemCount(); try { switch (itemCount) { @@ -435,14 +440,14 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes PingNode in = PingNode::fromBytesConstRef(_from, rlpBytes); Pong p(_from); - p.replyTo = sha3(rlpBytes); + p.echo = sha3(rlpBytes); p.sign(m_secret); m_socketPtr->send(p); break; } default: - clog(NodeTableMessageSummary) << "Invalid Message received from " << _from.address().to_string() << ":" << _from.port(); + clog(NodeTableMessageSummary) << "Invalid Message, " << std::hex << rlpBytes[0] << ", received from " << _from.address().to_string() << ":" << _from.port(); return; } } diff --git a/libp2p/NodeTable.h b/libp2p/NodeTable.h index dee10c7ae..acf735f74 100644 --- a/libp2p/NodeTable.h +++ b/libp2p/NodeTable.h @@ -122,7 +122,7 @@ public: NodeTable(ba::io_service& _io, KeyPair _alias, uint16_t _udpPort = 30303); ~NodeTable(); - /// Constants for Kademlia, mostly derived from address space. + /// Constants for Kademlia, derived from address space. static unsigned const s_addressByteSize = sizeof(NodeId); ///< Size of address type in bytes. static unsigned const s_bits = 8 * s_addressByteSize; ///< Denoted by n in [Kademlia]. @@ -269,6 +269,9 @@ struct PingNode: RLPXDatagram PingNode(bi::udp::endpoint _ep): RLPXDatagram(_ep) {} PingNode(bi::udp::endpoint _ep, std::string _src, uint16_t _srcPort, std::chrono::seconds _expiration = std::chrono::seconds(60)): RLPXDatagram(_ep), ipAddress(_src), port(_srcPort), expiration(futureFromEpoch(_expiration)) {} + uint8_t packetType() { return 1; } + + unsigned version = 1; std::string ipAddress; unsigned port; unsigned expiration; @@ -283,20 +286,17 @@ struct PingNode: RLPXDatagram * RLP Encoded Items: 1 * Minimum Encoded Size: 33 bytes * Maximum Encoded Size: 33 bytes - * - * @todo expiration - * @todo value of replyTo - * @todo create from PingNode (reqs RLPXDatagram verify flag) */ struct Pong: RLPXDatagram { Pong(bi::udp::endpoint _ep): RLPXDatagram(_ep) {} - h256 replyTo; // hash of rlp of PingNode + uint8_t packetType() { return 2; } + h256 echo; ///< MCD of PingNode unsigned expiration; - void streamRLP(RLPStream& _s) const { _s.appendList(1); _s << replyTo; } - void interpretRLP(bytesConstRef _bytes) { RLP r(_bytes); replyTo = (h256)r[0]; } + void streamRLP(RLPStream& _s) const { _s.appendList(1); _s << echo; } + void interpretRLP(bytesConstRef _bytes) { RLP r(_bytes); echo = (h256)r[0]; } }; /** @@ -317,6 +317,7 @@ struct FindNode: RLPXDatagram FindNode(bi::udp::endpoint _ep): RLPXDatagram(_ep) {} FindNode(bi::udp::endpoint _ep, NodeId _target, std::chrono::seconds _expiration = std::chrono::seconds(30)): RLPXDatagram(_ep), target(_target), expiration(futureFromEpoch(_expiration)) {} + uint8_t packetType() { return 3; } h512 target; unsigned expiration; @@ -329,8 +330,6 @@ struct FindNode: RLPXDatagram * * RLP Encoded Items: 2 (first item is list) * Minimum Encoded Size: 10 bytes - * - * @todo nonce: Should be replaced with expiration. */ struct Neighbours: RLPXDatagram { @@ -346,7 +345,7 @@ struct Neighbours: RLPXDatagram }; Neighbours(bi::udp::endpoint _ep): RLPXDatagram(_ep) {} - Neighbours(bi::udp::endpoint _to, std::vector> const& _nearest, unsigned _offset = 0, unsigned _limit = 0): RLPXDatagram(_to) + Neighbours(bi::udp::endpoint _to, std::vector> const& _nearest, unsigned _offset = 0, unsigned _limit = 0): RLPXDatagram(_to), expiration(futureFromEpoch(std::chrono::seconds(30))) { auto limit = _limit ? std::min(_nearest.size(), (size_t)(_offset + _limit)) : _nearest.size(); for (auto i = _offset; i < limit; i++) @@ -359,6 +358,7 @@ struct Neighbours: RLPXDatagram } } + uint8_t packetType() { return 4; } std::list nodes; unsigned expiration = 1; diff --git a/libp2p/UDP.cpp b/libp2p/UDP.cpp index b1f87e409..23a3531ac 100644 --- a/libp2p/UDP.cpp +++ b/libp2p/UDP.cpp @@ -25,9 +25,13 @@ using namespace dev::p2p; h256 RLPXDatagramFace::sign(Secret const& _k) { - RLPStream rlpstream; - streamRLP(rlpstream); - bytes rlpBytes(rlpstream.out()); + assert(packetType()); + + RLPStream rlpxstream; +// rlpxstream.appendRaw(toPublic(_k).asBytes()); // for mdc-based signature + rlpxstream.appendRaw(bytes(1, packetType())); + streamRLP(rlpxstream); + bytes rlpBytes(rlpxstream.out()); bytesConstRef rlp(&rlpBytes); h256 hash(dev::sha3(rlp)); @@ -35,12 +39,16 @@ h256 RLPXDatagramFace::sign(Secret const& _k) data.resize(h256::size + Signature::size + rlp.size()); bytesConstRef packetHash(&data[0], h256::size); + bytesConstRef signedPayload(&data[h256::size], Signature::size + rlp.size()); bytesConstRef payloadSig(&data[h256::size], Signature::size); bytesConstRef payload(&data[h256::size + Signature::size], rlp.size()); sig.ref().copyTo(payloadSig); +// rlp.cropped(Public::size, rlp.size() - Public::size).copyTo(payload); rlp.copyTo(payload); + +// hash.ref().copyTo(packetHash); // for mdc-based signature dev::sha3(signedPayload).ref().copyTo(packetHash); return std::move(hash); diff --git a/libp2p/UDP.h b/libp2p/UDP.h index d048e697c..9451e43f0 100644 --- a/libp2p/UDP.h +++ b/libp2p/UDP.h @@ -63,7 +63,8 @@ struct RLPXDatagramFace: public UDPDatagram static uint64_t futureFromEpoch(std::chrono::milliseconds _ms) { return std::chrono::duration_cast((std::chrono::system_clock::now() + _ms).time_since_epoch()).count(); } static uint64_t futureFromEpoch(std::chrono::seconds _sec) { return std::chrono::duration_cast((std::chrono::system_clock::now() + _sec).time_since_epoch()).count(); } static Public authenticate(bytesConstRef _sig, bytesConstRef _rlp); - + + virtual uint8_t packetType() =0; RLPXDatagramFace(bi::udp::endpoint const& _ep): UDPDatagram(_ep) {} virtual h256 sign(Secret const& _from); From 98a2d193c2d1abbee760e8856a7dda2ea61ab928 Mon Sep 17 00:00:00 2001 From: subtly Date: Sun, 25 Jan 2015 14:08:34 -0800 Subject: [PATCH 023/213] updates and fixes for code review --- libp2p/Common.h | 2 +- libp2p/Host.cpp | 62 +++++++++++++++++++++++++++---------------- libp2p/Host.h | 22 ++++++++++----- libp2p/NodeTable.cpp | 28 ++++++++++--------- libp2p/NodeTable.h | 26 +++++++++--------- libp2p/Session.cpp | 4 +-- libp2p/UDP.cpp | 31 ++++++++++------------ test/peer.cpp | 16 +++++------ test/whisperTopic.cpp | 28 +++++++++---------- 9 files changed, 120 insertions(+), 99 deletions(-) diff --git a/libp2p/Common.h b/libp2p/Common.h index 38012ec76..784b2f513 100644 --- a/libp2p/Common.h +++ b/libp2p/Common.h @@ -148,7 +148,7 @@ struct NodeIPEndpoint bi::udp::endpoint udp; bi::tcp::endpoint tcp; - operator bool() const { return udp.address().is_unspecified() && tcp.address().is_unspecified(); } + operator bool() const { return !udp.address().is_unspecified() || !tcp.address().is_unspecified(); } }; struct Node diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index 38929278d..8c73a79f2 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -40,7 +40,7 @@ using namespace dev::p2p; HostNodeTableHandler::HostNodeTableHandler(Host& _host): m_host(_host) {} -void HostNodeTableHandler::processEvent(NodeId _n, NodeTableEventType _e) +void HostNodeTableHandler::processEvent(NodeId const& _n, NodeTableEventType const& _e) { m_host.onNodeTableEvent(_n, _e); } @@ -158,6 +158,8 @@ void Host::registerPeer(std::shared_ptr _s, CapDescs const& _caps) { { RecursiveGuard l(x_sessions); + // TODO: temporary loose-coupling; if m_peers already has peer, + // it is same as _s->m_peer. (fixing next PR) if (!m_peers.count(_s->m_peer->id)) m_peers[_s->m_peer->id] = _s->m_peer; m_sessions[_s->m_peer->id] = _s; @@ -172,7 +174,7 @@ void Host::registerPeer(std::shared_ptr _s, CapDescs const& _caps) } } -void Host::onNodeTableEvent(NodeId _n, NodeTableEventType _e) +void Host::onNodeTableEvent(NodeId const& _n, NodeTableEventType const& _e) { if (_e == NodeEntryAdded) @@ -320,6 +322,7 @@ void Host::runAcceptor() } } + // asio doesn't close socket on error if (!success && s->is_open()) { boost::system::error_code ec; @@ -393,25 +396,25 @@ void Host::addNode(NodeId const& _node, std::string const& _addr, unsigned short addNode(Node(_node, NodeIPEndpoint(bi::udp::endpoint(addr, _udpNodePort), bi::tcp::endpoint(addr, _tcpPeerPort)))); } -void Host::connect(std::shared_ptr const& _n) +void Host::connect(std::shared_ptr const& _p) { if (!m_run) return; - if (havePeerSession(_n->id)) + if (havePeerSession(_p->id)) { clog(NetWarn) << "Aborted connect. Node already connected."; return; } - if (!m_nodeTable->haveNode(_n->id)) + if (!m_nodeTable->haveNode(_p->id)) { clog(NetWarn) << "Aborted connect. Node not in node table."; return; } // prevent concurrently connecting to a node - Peer *nptr = _n.get(); + Peer *nptr = _p.get(); { Guard l(x_pendingNodeConns); if (m_pendingNodeConns.count(nptr)) @@ -419,22 +422,22 @@ void Host::connect(std::shared_ptr const& _n) m_pendingNodeConns.insert(nptr); } - clog(NetConnect) << "Attempting connection to node" << _n->id.abridged() << "@" << _n->peerEndpoint() << "from" << id().abridged(); + clog(NetConnect) << "Attempting connection to node" << _p->id.abridged() << "@" << _p->peerEndpoint() << "from" << id().abridged(); bi::tcp::socket* s = new bi::tcp::socket(m_ioService); - s->async_connect(_n->peerEndpoint(), [=](boost::system::error_code const& ec) + s->async_connect(_p->peerEndpoint(), [=](boost::system::error_code const& ec) { if (ec) { - clog(NetConnect) << "Connection refused to node" << _n->id.abridged() << "@" << _n->peerEndpoint() << "(" << ec.message() << ")"; - _n->lastDisconnect = TCPError; - _n->lastAttempted = std::chrono::system_clock::now(); + clog(NetConnect) << "Connection refused to node" << _p->id.abridged() << "@" << _p->peerEndpoint() << "(" << ec.message() << ")"; + _p->lastDisconnect = TCPError; + _p->lastAttempted = std::chrono::system_clock::now(); } else { - clog(NetConnect) << "Connected to" << _n->id.abridged() << "@" << _n->peerEndpoint(); + clog(NetConnect) << "Connected to" << _p->id.abridged() << "@" << _p->peerEndpoint(); - _n->lastConnected = std::chrono::system_clock::now(); - auto ps = make_shared(this, std::move(*s), _n); + _p->lastConnected = std::chrono::system_clock::now(); + auto ps = make_shared(this, std::move(*s), _p); ps->start(); } @@ -480,8 +483,8 @@ void Host::run(boost::system::error_code const&) if (auto pp = p.second.lock()) pp->serviceNodesRequest(); - if (chrono::steady_clock::now() - m_lastPing >= chrono::seconds(30)) // ping every 30s. - keepAlivePeers(); + disconnectLatePeers(); + keepAlivePeers(); auto runcb = [this](boost::system::error_code const& error) { run(error); }; m_timer->expires_from_now(boost::posix_time::milliseconds(c_timerInterval)); @@ -541,19 +544,29 @@ void Host::doWork() void Host::keepAlivePeers() { + if (chrono::steady_clock::now() < m_lastPing + c_keepAliveInterval) + return; + RecursiveGuard l(x_sessions); for (auto p: m_sessions) if (auto pp = p.second.lock()) - { - if (chrono::steady_clock::now() - pp->m_lastReceived >= chrono::seconds(60)) - pp->disconnect(PingTimeout); - else pp->ping(); - } m_lastPing = chrono::steady_clock::now(); } +void Host::disconnectLatePeers() +{ + if (chrono::steady_clock::now() < m_lastPing + c_keepAliveTimeOut) + return; + + RecursiveGuard l(x_sessions); + for (auto p: m_sessions) + if (auto pp = p.second.lock()) + if (pp->m_lastReceived < m_lastPing + c_keepAliveTimeOut) + pp->disconnect(PingTimeout); +} + bytes Host::saveNodes() const { RLPStream nodes; @@ -563,7 +576,9 @@ bytes Host::saveNodes() const for (auto const& i: m_peers) { Peer const& n = *(i.second); - // TODO: PoC-7: Figure out why it ever shares these ports.//n.address.port() >= 30300 && n.address.port() <= 30305 && + // TODO: alpha: Figure out why it ever shares these ports.//n.address.port() >= 30300 && n.address.port() <= 30305 && + // TODO: alpha: if/how to save private addresses + // Only save peers which have connected within 2 days, with properly-advertised port and public IP address if (chrono::system_clock::now() - n.lastConnected < chrono::seconds(3600 * 48) && n.peerEndpoint().port() > 0 && n.peerEndpoint().port() < /*49152*/32768 && n.id != id() && !isPrivateAddress(n.peerEndpoint().address())) { nodes.appendList(10); @@ -571,7 +586,8 @@ bytes Host::saveNodes() const nodes << n.peerEndpoint().address().to_v4().to_bytes(); else nodes << n.peerEndpoint().address().to_v6().to_bytes(); - nodes << n.peerEndpoint().port() << n.id /* << (int)n.idOrigin */ << 0 + // TODO: alpha: replace 0 with trust-state of node + nodes << n.peerEndpoint().port() << n.id << 0 << chrono::duration_cast(n.lastConnected.time_since_epoch()).count() << chrono::duration_cast(n.lastAttempted.time_since_epoch()).count() << n.failedAttempts << (unsigned)n.lastDisconnect << n.score << n.rating; diff --git a/libp2p/Host.h b/libp2p/Host.h index bffc6c39f..bb3e214c4 100644 --- a/libp2p/Host.h +++ b/libp2p/Host.h @@ -101,7 +101,7 @@ class HostNodeTableHandler: public NodeTableEventHandler { friend class Host; HostNodeTableHandler(Host& _host); - virtual void processEvent(NodeId _n, NodeTableEventType _e); + virtual void processEvent(NodeId const& _n, NodeTableEventType const& _e); Host& m_host; }; @@ -111,9 +111,11 @@ class HostNodeTableHandler: public NodeTableEventHandler * * @todo onNodeTableEvent: move peer-connection logic into ensurePeers * @todo handshake: gracefully disconnect peer if peer already connected + * @todo abstract socket -> IPConnection * @todo determinePublic: ipv6, udp * @todo handle conflict if addNode/requireNode called and Node already exists w/conflicting tcp or udp port * @todo write host identifier to disk w/nodes + * @todo per-session keepalive/ping instead of broadcast; set ping-timeout via median-latency */ class Host: public Worker { @@ -128,6 +130,12 @@ public: /// Will block on network process events. virtual ~Host(); + /// Interval at which Host::run will call keepAlivePeers to ping peers. + std::chrono::seconds const c_keepAliveInterval = std::chrono::seconds(30); + + /// Disconnect timeout after failure to respond to keepAlivePeers ping. + std::chrono::seconds const c_keepAliveTimeOut = std::chrono::seconds(1); + /// Default host for current version of client. static std::string pocHost(); @@ -141,9 +149,8 @@ public: CapDescs caps() const { CapDescs ret; for (auto const& i: m_capabilities) ret.push_back(i.first); return ret; } template std::shared_ptr cap() const { try { return std::static_pointer_cast(m_capabilities.at(std::make_pair(T::staticName(), T::staticVersion()))); } catch (...) { return nullptr; } } - bool havePeerSession(NodeId _id) { RecursiveGuard l(x_sessions); if (m_sessions.count(_id)) return !!m_sessions[_id].lock(); else return false; } + bool havePeerSession(NodeId _id) { RecursiveGuard l(x_sessions); return m_sessions.count(_id) ? !!m_sessions[_id].lock() : false; } - /// Add node. void addNode(NodeId const& _node, std::string const& _addr, unsigned short _tcpPort, unsigned short _udpPort); /// Set ideal number of peers. @@ -187,21 +194,24 @@ public: void registerPeer(std::shared_ptr _s, CapDescs const& _caps); protected: - void onNodeTableEvent(NodeId _n, NodeTableEventType _e); + void onNodeTableEvent(NodeId const& _n, NodeTableEventType const& _e); private: /// Populate m_peerAddresses with available public addresses. void determinePublic(std::string const& _publicAddress, bool _upnp); - void connect(std::shared_ptr const& _n); + void connect(std::shared_ptr const& _p); /// Ping the peers to update the latency information and disconnect peers which have timed out. void keepAlivePeers(); + /// Disconnect peers which didn't respond to keepAlivePeers ping prior to c_keepAliveTimeOut. + void disconnectLatePeers(); + /// Called only from startedWorking(). void runAcceptor(); - /// Handler for verifying handshake siganture before creating session. _nodeId is passed for outbound connections. + /// Handler for verifying handshake siganture before creating session. _nodeId is passed for outbound connections. If successful, socket is moved to Session via std::move. void doHandshake(bi::tcp::socket* _socket, NodeId _nodeId = NodeId()); void seal(bytes& _b); diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index 40688f4a5..ae32cc81d 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -55,8 +55,8 @@ NodeTable::~NodeTable() void NodeTable::processEvents() { - if (m_nodeEvents) - m_nodeEvents->processEvents(); + if (m_nodeEventHandler) + m_nodeEventHandler->processEvents(); } shared_ptr NodeTable::addNode(Public const& _pubk, bi::udp::endpoint const& _udp, bi::tcp::endpoint const& _tcp) @@ -80,8 +80,8 @@ shared_ptr NodeTable::addNode(Node const& _node) else { clog(NodeTableNote) << "p2p.nodes.add " << _node.id.abridged(); - if (m_nodeEvents) - m_nodeEvents->appendEvent(_node.id, NodeEntryAdded); + if (m_nodeEventHandler) + m_nodeEventHandler->appendEvent(_node.id, NodeEntryAdded); ret.reset(new NodeEntry(m_node, _node.id, NodeIPEndpoint(_node.endpoint.udp, _node.endpoint.tcp))); m_nodes[_node.id] = ret; @@ -341,8 +341,8 @@ void NodeTable::dropNode(shared_ptr _n) } clog(NodeTableNote) << "p2p.nodes.drop " << _n->id.abridged(); - if (m_nodeEvents) - m_nodeEvents->appendEvent(_n->id, NodeEntryRemoved); + if (m_nodeEventHandler) + m_nodeEventHandler->appendEvent(_n->id, NodeEntryRemoved); } NodeTable::NodeBucket& NodeTable::bucket(NodeEntry const* _n) @@ -367,23 +367,25 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes return; } - bytesConstRef rlpBytes(hashedBytes.cropped(Signature::size, hashedBytes.size() - Signature::size)); + bytesConstRef signedBytes(hashedBytes.cropped(Signature::size, hashedBytes.size() - Signature::size)); // todo: verify sig via known-nodeid and MDC, or, do ping/pong auth if node/endpoint is unknown/untrusted bytesConstRef sigBytes(_packet.cropped(h256::size, Signature::size)); - Public nodeid(dev::recover(*(Signature const*)sigBytes.data(), sha3(rlpBytes))); + Public nodeid(dev::recover(*(Signature const*)sigBytes.data(), sha3(signedBytes))); if (!nodeid) { clog(NodeTableMessageSummary) << "Invalid Message signature from " << _from.address().to_string() << ":" << _from.port(); return; } - if (rlpBytes[0] && rlpBytes[0] < 4) + unsigned packetType = signedBytes[0]; + if (packetType && packetType < 4) noteNode(nodeid, _from); // todo: switch packet-type - RLP rlp(rlpBytes.cropped(1, rlpBytes.size() - 1)); + bytesConstRef rlpBytes(_packet.cropped(h256::size + Signature::size + 1)); + RLP rlp(rlpBytes); unsigned itemCount = rlp.itemCount(); try { switch (itemCount) @@ -404,7 +406,7 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes if (auto n = (*this)[it->first.first]) addNode(n); - m_evictions.erase(it); + it = m_evictions.erase(it); } break; @@ -447,7 +449,7 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes } default: - clog(NodeTableMessageSummary) << "Invalid Message, " << std::hex << rlpBytes[0] << ", received from " << _from.address().to_string() << ":" << _from.port(); + clog(NodeTableWarn) << "Invalid Message, " << hex << packetType << ", received from " << _from.address().to_string() << ":" << dec << _from.port(); return; } } @@ -456,7 +458,7 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes clog(NodeTableWarn) << "Exception processing message from " << _from.address().to_string() << ":" << _from.port(); } } - + void NodeTable::doCheckEvictions(boost::system::error_code const& _ec) { if (_ec || !m_socketPtr->isOpen()) diff --git a/libp2p/NodeTable.h b/libp2p/NodeTable.h index acf735f74..79adba62b 100644 --- a/libp2p/NodeTable.h +++ b/libp2p/NodeTable.h @@ -41,7 +41,7 @@ struct NodeEntry: public Node NodeEntry(Node _src, Public _pubk, NodeIPEndpoint _gw); NodeEntry(Node _src, Public _pubk, bi::udp::endpoint _udp); - const unsigned distance; ///< Node's distance (xor of _src as integer). + unsigned const distance; ///< Node's distance (xor of _src as integer). }; enum NodeTableEventType { @@ -53,20 +53,20 @@ class NodeTableEventHandler { friend class NodeTable; public: - virtual void processEvent(NodeId _n, NodeTableEventType _e) =0; + virtual void processEvent(NodeId const& _n, NodeTableEventType const& _e) =0; protected: /// Called by NodeTable on behalf of an implementation (Host) to process new events without blocking nodetable. void processEvents() { - std::list> events; + std::list> events; { Guard l(x_events); - if (!m_nodeEvents.size()) + if (!m_nodeEventHandler.size()) return; - m_nodeEvents.unique(); - for (auto const& n: m_nodeEvents) events.push_back(std::make_pair(n,m_events[n])); - m_nodeEvents.clear(); + m_nodeEventHandler.unique(); + for (auto const& n: m_nodeEventHandler) events.push_back(std::make_pair(n,m_events[n])); + m_nodeEventHandler.clear(); m_events.clear(); } for (auto const& e: events) @@ -74,11 +74,11 @@ protected: } /// Called by NodeTable to append event. - virtual void appendEvent(NodeId _n, NodeTableEventType _e) { Guard l(x_events); m_nodeEvents.push_back(_n); m_events[_n] = _e; } + virtual void appendEvent(NodeId _n, NodeTableEventType _e) { Guard l(x_events); m_nodeEventHandler.push_back(_n); m_events[_n] = _e; } Mutex x_events; - std::list m_nodeEvents; - std::map m_events; + std::list m_nodeEventHandler; + std::map m_events; }; /** @@ -143,7 +143,7 @@ public: static unsigned dist(NodeId const& _a, NodeId const& _b) { u512 d = _a ^ _b; unsigned ret; for (ret = 0; d >>= 1; ++ret) {}; return ret; } /// Set event handler for NodeEntryAdded and NodeEntryRemoved events. - void setEventHandler(NodeTableEventHandler* _handler) { m_nodeEvents.reset(_handler); } + void setEventHandler(NodeTableEventHandler* _handler) { m_nodeEventHandler.reset(_handler); } /// Called by implementation which provided handler to process NodeEntryAdded/NodeEntryRemoved events. Events are coalesced by type whereby old events are ignored. void processEvents(); @@ -160,7 +160,7 @@ public: std::list nodes() const; std::list state() const; - bool haveNode(NodeId _id) { Guard l(x_nodes); return !!m_nodes[_id]; } + bool haveNode(NodeId _id) { Guard l(x_nodes); return m_nodes.count(_id); } Node operator[](NodeId _id); std::shared_ptr getNodeEntry(NodeId _id); @@ -212,7 +212,7 @@ protected: /// Sends FindNeighbor packet. See doFindNode. void requestNeighbours(NodeEntry const& _node, NodeId _target) const; - std::unique_ptr m_nodeEvents; ///< Event handler for node events. + std::unique_ptr m_nodeEventHandler; ///< Event handler for node events. Node m_node; ///< This node. Secret m_secret; ///< This nodes secret key. diff --git a/libp2p/Session.cpp b/libp2p/Session.cpp index 9f68f3ef0..d23bf2d89 100644 --- a/libp2p/Session.cpp +++ b/libp2p/Session.cpp @@ -286,7 +286,7 @@ bool Session::interpret(RLP const& _r) clogS(NetAllDetail) << "Checking: " << ep << "(" << id.abridged() << ")"; // clogS(NetAllDetail) << "Checking: " << ep << "(" << id.abridged() << ")" << isPrivateAddress(peerAddress) << this->id().abridged() << isPrivateAddress(endpoint().address()) << m_server->m_peers.count(id) << (m_server->m_peers.count(id) ? isPrivateAddress(m_server->m_peers.at(id)->address.address()) : -1); - // ignore if dist(us,item) - dist(us,them) > 1 + // todo: draft spec: ignore if dist(us,item) - dist(us,them) > 1 // TODO: isPrivate if (!m_server->m_netPrefs.localNetworking && isPrivateAddress(peerAddress)) @@ -309,7 +309,7 @@ bool Session::interpret(RLP const& _r) // OK passed all our checks. Assume it's good. addRating(1000); - m_server->addNode(Node(id, NodeIPEndpoint(bi::udp::endpoint(ep.address(), 30303), ep))); + m_server->addNode(Node(id, NodeIPEndpoint(bi::udp::endpoint(ep.address(), ep.port()), ep))); clogS(NetTriviaDetail) << "New peer: " << ep << "(" << id .abridged()<< ")"; CONTINUE:; LAMEPEER:; diff --git a/libp2p/UDP.cpp b/libp2p/UDP.cpp index 23a3531ac..e27b6e57a 100644 --- a/libp2p/UDP.cpp +++ b/libp2p/UDP.cpp @@ -29,29 +29,26 @@ h256 RLPXDatagramFace::sign(Secret const& _k) RLPStream rlpxstream; // rlpxstream.appendRaw(toPublic(_k).asBytes()); // for mdc-based signature - rlpxstream.appendRaw(bytes(1, packetType())); + rlpxstream.appendRaw(bytes(1, packetType())); // prefix by 1 byte for type streamRLP(rlpxstream); - bytes rlpBytes(rlpxstream.out()); + bytes rlpxBytes(rlpxstream.out()); - bytesConstRef rlp(&rlpBytes); - h256 hash(dev::sha3(rlp)); - Signature sig = dev::sign(_k, hash); + bytesConstRef rlpx(&rlpxBytes); + h256 sighash(dev::sha3(rlpx)); // H(type||data) + Signature sig = dev::sign(_k, sighash); // S(H(type||data)) - data.resize(h256::size + Signature::size + rlp.size()); - bytesConstRef packetHash(&data[0], h256::size); - - bytesConstRef signedPayload(&data[h256::size], Signature::size + rlp.size()); - bytesConstRef payloadSig(&data[h256::size], Signature::size); - bytesConstRef payload(&data[h256::size + Signature::size], rlp.size()); + data.resize(h256::size + Signature::size + rlpx.size()); + bytesConstRef rlpxHash(&data[0], h256::size); + bytesConstRef rlpxSig(&data[h256::size], Signature::size); + bytesConstRef rlpxPayload(&data[h256::size + Signature::size], rlpx.size()); - sig.ref().copyTo(payloadSig); -// rlp.cropped(Public::size, rlp.size() - Public::size).copyTo(payload); - rlp.copyTo(payload); + sig.ref().copyTo(rlpxSig); + rlpx.copyTo(rlpxPayload); -// hash.ref().copyTo(packetHash); // for mdc-based signature - dev::sha3(signedPayload).ref().copyTo(packetHash); + bytesConstRef signedRLPx(&data[h256::size], data.size() - h256::size); + dev::sha3(signedRLPx).ref().copyTo(rlpxHash); - return std::move(hash); + return std::move(sighash); }; Public RLPXDatagramFace::authenticate(bytesConstRef _sig, bytesConstRef _rlp) diff --git a/test/peer.cpp b/test/peer.cpp index 51e777a56..5c3e677f6 100644 --- a/test/peer.cpp +++ b/test/peer.cpp @@ -51,10 +51,11 @@ BOOST_AUTO_TEST_SUITE_END() int peerTest(int argc, char** argv) { + Public remoteAlias; short listenPort = 30303; string remoteHost; short remotePort = 30303; - + for (int i = 1; i < argc; ++i) { string arg = argv[i]; @@ -64,21 +65,18 @@ int peerTest(int argc, char** argv) remoteHost = argv[++i]; else if (arg == "-p" && i + 1 < argc) remotePort = (short)atoi(argv[++i]); + else if (arg == "-ra" && i + 1 < argc) + remoteAlias = Public(dev::fromHex(argv[++i])); else remoteHost = argv[i]; } Host ph("Test", NetworkPreferences(listenPort)); - if (!remoteHost.empty()) - ph.addNode(NodeId(), remoteHost, remotePort, remotePort); + if (!remoteHost.empty() && !remoteAlias) + ph.addNode(remoteAlias, remoteHost, remotePort, remotePort); -// for (int i = 0; ; ++i) -// { -// this_thread::sleep_for(chrono::milliseconds(100)); -// if (!(i % 10)) -// ph.keepAlivePeers(); -// } + this_thread::sleep_for(chrono::milliseconds(200)); return 0; } diff --git a/test/whisperTopic.cpp b/test/whisperTopic.cpp index 9f0f34630..02fccbc9f 100644 --- a/test/whisperTopic.cpp +++ b/test/whisperTopic.cpp @@ -34,29 +34,27 @@ BOOST_AUTO_TEST_CASE(topic) { cnote << "Testing Whisper..."; auto oldLogVerbosity = g_logVerbosity; - g_logVerbosity = 0; + g_logVerbosity = 5; - Host ph1("Test", NetworkPreferences(30303, "127.0.0.1", true, true)); + Host phOther("Test", NetworkPreferences(30303, "127.0.0.1", true, true)); + auto whOther = phOther.registerCapability(new WhisperHost()); + phOther.start(); bool started = false; unsigned result = 0; std::thread listener([&]() { setThreadName("other"); - - auto wh = ph1.registerCapability(new WhisperHost()); - ph1.start(); - started = true; /// Only interested in odd packets - auto w = wh->installWatch(BuildTopicMask("odd")); + auto w = whOther->installWatch(BuildTopicMask("odd")); for (int i = 0, last = 0; i < 200 && last < 81; ++i) { - for (auto i: wh->checkWatch(w)) + for (auto i: whOther->checkWatch(w)) { - Message msg = wh->envelope(i).open(); + Message msg = whOther->envelope(i).open(); last = RLP(msg.payload()).toInt(); cnote << "New message from:" << msg.from().abridged() << RLP(msg.payload()).toInt(); result += last; @@ -65,16 +63,16 @@ BOOST_AUTO_TEST_CASE(topic) } }); - while (!started) - this_thread::sleep_for(chrono::milliseconds(50)); - Host ph("Test", NetworkPreferences(30300, "127.0.0.1", true, true)); auto wh = ph.registerCapability(new WhisperHost()); - this_thread::sleep_for(chrono::milliseconds(500)); ph.start(); - this_thread::sleep_for(chrono::milliseconds(500)); - ph.addNode(ph1.id(), "127.0.0.1", 30303, 30303); + ph.addNode(phOther.id(), "127.0.0.1", 30303, 30303); + this_thread::sleep_for(chrono::milliseconds(300)); + while (!started) + this_thread::sleep_for(chrono::milliseconds(25)); + + KeyPair us = KeyPair::create(); for (int i = 0; i < 10; ++i) { From 6381706c665ffae061c847c7a309b18167e32ad4 Mon Sep 17 00:00:00 2001 From: subtly Date: Sun, 25 Jan 2015 19:54:15 -0800 Subject: [PATCH 024/213] fix ping-timeouts --- libp2p/Host.cpp | 12 +++++++----- libp2p/Host.h | 2 +- libp2p/Session.cpp | 3 ++- test/peer.cpp | 2 +- test/whisperTopic.cpp | 22 +++++++++++++--------- 5 files changed, 24 insertions(+), 17 deletions(-) diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index 8c73a79f2..11320e463 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -52,7 +52,8 @@ Host::Host(std::string const& _clientVersion, NetworkPreferences const& _n, bool m_ifAddresses(Network::getInterfaceAddresses()), m_ioService(2), m_tcp4Acceptor(m_ioService), - m_alias(move(getHostIdentifier())) + m_alias(move(getHostIdentifier())), + m_lastPing(chrono::time_point::min()) { for (auto address: m_ifAddresses) if (address.is_v4()) @@ -483,8 +484,8 @@ void Host::run(boost::system::error_code const&) if (auto pp = p.second.lock()) pp->serviceNodesRequest(); - disconnectLatePeers(); keepAlivePeers(); + disconnectLatePeers(); auto runcb = [this](boost::system::error_code const& error) { run(error); }; m_timer->expires_from_now(boost::posix_time::milliseconds(c_timerInterval)); @@ -544,7 +545,7 @@ void Host::doWork() void Host::keepAlivePeers() { - if (chrono::steady_clock::now() < m_lastPing + c_keepAliveInterval) + if (chrono::steady_clock::now() - c_keepAliveInterval < m_lastPing) return; RecursiveGuard l(x_sessions); @@ -557,13 +558,14 @@ void Host::keepAlivePeers() void Host::disconnectLatePeers() { - if (chrono::steady_clock::now() < m_lastPing + c_keepAliveTimeOut) + auto now = chrono::steady_clock::now(); + if (now - c_keepAliveTimeOut < m_lastPing) return; RecursiveGuard l(x_sessions); for (auto p: m_sessions) if (auto pp = p.second.lock()) - if (pp->m_lastReceived < m_lastPing + c_keepAliveTimeOut) + if (now - c_keepAliveTimeOut > m_lastPing && pp->m_lastReceived < m_lastPing) pp->disconnect(PingTimeout); } diff --git a/libp2p/Host.h b/libp2p/Host.h index bb3e214c4..d770b81b1 100644 --- a/libp2p/Host.h +++ b/libp2p/Host.h @@ -134,7 +134,7 @@ public: std::chrono::seconds const c_keepAliveInterval = std::chrono::seconds(30); /// Disconnect timeout after failure to respond to keepAlivePeers ping. - std::chrono::seconds const c_keepAliveTimeOut = std::chrono::seconds(1); + std::chrono::milliseconds const c_keepAliveTimeOut = std::chrono::milliseconds(1000); /// Default host for current version of client. static std::string pocHost(); diff --git a/libp2p/Session.cpp b/libp2p/Session.cpp index d23bf2d89..7e618fb3b 100644 --- a/libp2p/Session.cpp +++ b/libp2p/Session.cpp @@ -40,7 +40,8 @@ Session::Session(Host* _s, bi::tcp::socket _socket, std::shared_ptr const& m_server(_s), m_socket(std::move(_socket)), m_peer(_n), - m_info({NodeId(), "?", m_socket.remote_endpoint().address().to_string(), 0, std::chrono::steady_clock::duration(0), CapDescSet(), 0, map()}) + m_info({NodeId(), "?", m_socket.remote_endpoint().address().to_string(), 0, std::chrono::steady_clock::duration(0), CapDescSet(), 0, map()}), + m_ping(chrono::time_point::max()) { m_lastReceived = m_connect = std::chrono::steady_clock::now(); } diff --git a/test/peer.cpp b/test/peer.cpp index 5c3e677f6..7c128276e 100644 --- a/test/peer.cpp +++ b/test/peer.cpp @@ -44,7 +44,7 @@ BOOST_AUTO_TEST_CASE(host) host1.addNode(node2, "127.0.0.1", host2prefs.listenPort, host2prefs.listenPort); - this_thread::sleep_for(chrono::seconds(1)); + this_thread::sleep_for(chrono::seconds(3)); } BOOST_AUTO_TEST_SUITE_END() diff --git a/test/whisperTopic.cpp b/test/whisperTopic.cpp index 02fccbc9f..eccdf16c0 100644 --- a/test/whisperTopic.cpp +++ b/test/whisperTopic.cpp @@ -34,12 +34,21 @@ BOOST_AUTO_TEST_CASE(topic) { cnote << "Testing Whisper..."; auto oldLogVerbosity = g_logVerbosity; - g_logVerbosity = 5; + g_logVerbosity = 0; - Host phOther("Test", NetworkPreferences(30303, "127.0.0.1", true, true)); + Host phOther("Test", NetworkPreferences(30303, "127.0.0.1", false, true)); auto whOther = phOther.registerCapability(new WhisperHost()); phOther.start(); + Host ph("Test", NetworkPreferences(30300, "127.0.0.1", false, true)); + auto wh = ph.registerCapability(new WhisperHost()); + ph.start(); + + this_thread::sleep_for(chrono::milliseconds(100)); + ph.addNode(phOther.id(), "127.0.0.1", 30303, 30303); + + this_thread::sleep_for(chrono::milliseconds(500)); + bool started = false; unsigned result = 0; std::thread listener([&]() @@ -61,16 +70,11 @@ BOOST_AUTO_TEST_CASE(topic) } this_thread::sleep_for(chrono::milliseconds(50)); } + }); - Host ph("Test", NetworkPreferences(30300, "127.0.0.1", true, true)); - auto wh = ph.registerCapability(new WhisperHost()); - ph.start(); - ph.addNode(phOther.id(), "127.0.0.1", 30303, 30303); - - this_thread::sleep_for(chrono::milliseconds(300)); while (!started) - this_thread::sleep_for(chrono::milliseconds(25)); + this_thread::sleep_for(chrono::milliseconds(1)); KeyPair us = KeyPair::create(); From 2e7ea3564c10e498fdf8bbb3054c722b8f7845ac Mon Sep 17 00:00:00 2001 From: subtly Date: Sun, 25 Jan 2015 21:43:53 -0800 Subject: [PATCH 025/213] add test-require to p2p/host --- libp2p/Host.cpp | 2 +- test/peer.cpp | 5 ++++- test/whisperTopic.cpp | 1 - 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index 11320e463..5bf0b937d 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -626,7 +626,7 @@ void Host::restoreNodes(bytesConstRef _b) auto id = (NodeId)i[2]; if (!m_peers.count(id)) { - // TODO: p2p Important :) + // TODO: p2p import/export :) // auto n = noteNode(id, ep); // n->lastConnected = chrono::system_clock::time_point(chrono::seconds(i[4].toInt())); // n->lastAttempted = chrono::system_clock::time_point(chrono::seconds(i[5].toInt())); diff --git a/test/peer.cpp b/test/peer.cpp index 7c128276e..a4b07e0b3 100644 --- a/test/peer.cpp +++ b/test/peer.cpp @@ -44,7 +44,10 @@ BOOST_AUTO_TEST_CASE(host) host1.addNode(node2, "127.0.0.1", host2prefs.listenPort, host2prefs.listenPort); - this_thread::sleep_for(chrono::seconds(3)); + this_thread::sleep_for(chrono::seconds(1)); + + BOOST_REQUIRE_EQUAL(host1.peerCount(), 1); + BOOST_REQUIRE_EQUAL(host2.peerCount(), host1.peerCount()); } BOOST_AUTO_TEST_SUITE_END() diff --git a/test/whisperTopic.cpp b/test/whisperTopic.cpp index eccdf16c0..5bd8f0f88 100644 --- a/test/whisperTopic.cpp +++ b/test/whisperTopic.cpp @@ -75,7 +75,6 @@ BOOST_AUTO_TEST_CASE(topic) while (!started) this_thread::sleep_for(chrono::milliseconds(1)); - KeyPair us = KeyPair::create(); for (int i = 0; i < 10; ++i) From 5566f335e8671830bad3a572ab9d80aabb7bc08c Mon Sep 17 00:00:00 2001 From: subtly Date: Mon, 26 Jan 2015 10:02:08 -0800 Subject: [PATCH 026/213] Comments for socket in acceptor. Remove start arg from Host constructor; it is not used and conflicts with restoreNodes being used to set node credentials. --- libp2p/Host.cpp | 26 +++++++++++++++++++++----- libp2p/Host.h | 2 +- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index 5bf0b937d..f2f2b6a89 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -45,7 +45,7 @@ void HostNodeTableHandler::processEvent(NodeId const& _n, NodeTableEventType con m_host.onNodeTableEvent(_n, _e); } -Host::Host(std::string const& _clientVersion, NetworkPreferences const& _n, bool _start): +Host::Host(std::string const& _clientVersion, NetworkPreferences const& _n): Worker("p2p", 0), m_clientVersion(_clientVersion), m_netPrefs(_n), @@ -60,8 +60,6 @@ Host::Host(std::string const& _clientVersion, NetworkPreferences const& _n, bool clog(NetNote) << "IP Address: " << address << " = " << (isPrivateAddress(address) ? "[LOCAL]" : "[PEER]"); clog(NetNote) << "Id:" << id(); - if (_start) - start(); } Host::~Host() @@ -300,16 +298,34 @@ void Host::runAcceptor() { clog(NetConnect) << "Listening on local port " << m_listenPort << " (public: " << m_tcpPublic << ")"; m_accepting = true; + + // socket is created outside of acceptor-callback + // An allocated socket is necessary as asio can use the socket + // until the callback succeeds or fails. + // + // Until callback succeeds or fails, we can't dealloc it. + // + // Callback is guaranteed to be called via asio or when + // m_tcp4Acceptor->stop() is called by Host. + // + // All exceptions are caught so they don't halt asio and so the + // socket is deleted. + // + // It's possible for an accepted connection to return an error in which + // case the socket may be open and must be closed to prevent asio from + // processing socket events after socket is deallocated. - bi::tcp::socket* s = new bi::tcp::socket(m_ioService); + bi::tcp::socket *s = new bi::tcp::socket(m_ioService); m_tcp4Acceptor.async_accept(*s, [=](boost::system::error_code ec) { + // if no error code, doHandshake takes ownership bool success = false; if (!ec) { try { - // incoming connection so we don't yet know nodeid + // doHandshake takes ownersihp of *s via std::move + // incoming connection; we don't yet know nodeid doHandshake(s, NodeId()); success = true; } diff --git a/libp2p/Host.h b/libp2p/Host.h index d770b81b1..a4493f9bf 100644 --- a/libp2p/Host.h +++ b/libp2p/Host.h @@ -125,7 +125,7 @@ class Host: public Worker public: /// Start server, listening for connections on the given port. - Host(std::string const& _clientVersion, NetworkPreferences const& _n = NetworkPreferences(), bool _start = false); + Host(std::string const& _clientVersion, NetworkPreferences const& _n = NetworkPreferences()); /// Will block on network process events. virtual ~Host(); From 2f3ab3a92d286727ce30847f5646048ed23819ef Mon Sep 17 00:00:00 2001 From: subtly Date: Thu, 29 Jan 2015 10:53:30 -0800 Subject: [PATCH 027/213] add expiration to pong --- libp2p/NodeTable.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libp2p/NodeTable.h b/libp2p/NodeTable.h index 79adba62b..7f9e3877f 100644 --- a/libp2p/NodeTable.h +++ b/libp2p/NodeTable.h @@ -88,6 +88,9 @@ protected: * Thread-safety is ensured by modifying NodeEntry details via * shared_ptr replacement instead of mutating values. * + * NodeTable accepts a port for UDP and will listen to the port on all available + * interfaces. + * * [Integration] * @todo restore nodes: affects refreshbuckets * @todo TCP endpoints @@ -289,7 +292,7 @@ struct PingNode: RLPXDatagram */ struct Pong: RLPXDatagram { - Pong(bi::udp::endpoint _ep): RLPXDatagram(_ep) {} + Pong(bi::udp::endpoint _ep): RLPXDatagram(_ep), expiration(futureFromEpoch(std::chrono::seconds(60))) {} uint8_t packetType() { return 2; } h256 echo; ///< MCD of PingNode From 3d2e72ce774a70bc2b8913d14ad6c0a42db8a577 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Fri, 30 Jan 2015 00:50:28 +0100 Subject: [PATCH 028/213] libp2p: distinguish discovery packets by packet type --- libp2p/NodeTable.cpp | 52 +++++++++++++++++++++----------------------- libp2p/NodeTable.h | 10 +++++---- libp2p/UDP.h | 1 + 3 files changed, 32 insertions(+), 31 deletions(-) diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index ae32cc81d..dffa0933b 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -383,14 +383,12 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes if (packetType && packetType < 4) noteNode(nodeid, _from); - // todo: switch packet-type bytesConstRef rlpBytes(_packet.cropped(h256::size + Signature::size + 1)); RLP rlp(rlpBytes); - unsigned itemCount = rlp.itemCount(); try { - switch (itemCount) + switch (packetType) { - case 1: + case Pong::type: { // clog(NodeTableMessageSummary) << "Received Pong from " << _from.address().to_string() << ":" << _from.port(); Pong in = Pong::fromBytesConstRef(_from, rlpBytes); @@ -408,35 +406,35 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes it = m_evictions.erase(it); } - break; } - case 2: - if (rlp[0].isList()) - { - Neighbours in = Neighbours::fromBytesConstRef(_from, rlpBytes); -// clog(NodeTableMessageSummary) << "Received " << in.nodes.size() << " Neighbours from " << _from.address().to_string() << ":" << _from.port(); - for (auto n: in.nodes) - noteNode(n.node, bi::udp::endpoint(bi::address::from_string(n.ipAddress), n.port)); - } - else + case Neighbours::type: + { + Neighbours in = Neighbours::fromBytesConstRef(_from, rlpBytes); +// clog(NodeTableMessageSummary) << "Received " << in.nodes.size() << " Neighbours from " << _from.address().to_string() << ":" << _from.port(); + for (auto n: in.nodes) + noteNode(n.node, bi::udp::endpoint(bi::address::from_string(n.ipAddress), n.port)); + break; + } + + case FindNode::type: + { +// clog(NodeTableMessageSummary) << "Received FindNode from " << _from.address().to_string() << ":" << _from.port(); + FindNode in = FindNode::fromBytesConstRef(_from, rlpBytes); + + vector> nearest = findNearest(in.target); + static unsigned const nlimit = (m_socketPtr->maxDatagramSize - 11) / 86; + for (unsigned offset = 0; offset < nearest.size(); offset += nlimit) { -// clog(NodeTableMessageSummary) << "Received FindNode from " << _from.address().to_string() << ":" << _from.port(); - FindNode in = FindNode::fromBytesConstRef(_from, rlpBytes); - - vector> nearest = findNearest(in.target); - static unsigned const nlimit = (m_socketPtr->maxDatagramSize - 11) / 86; - for (unsigned offset = 0; offset < nearest.size(); offset += nlimit) - { - Neighbours out(_from, nearest, offset, nlimit); - out.sign(m_secret); - m_socketPtr->send(out); - } + Neighbours out(_from, nearest, offset, nlimit); + out.sign(m_secret); + m_socketPtr->send(out); } break; - - case 3: + } + + case PingNode::type: { // clog(NodeTableMessageSummary) << "Received PingNode from " << _from.address().to_string() << ":" << _from.port(); PingNode in = PingNode::fromBytesConstRef(_from, rlpBytes); diff --git a/libp2p/NodeTable.h b/libp2p/NodeTable.h index 7f9e3877f..61241a333 100644 --- a/libp2p/NodeTable.h +++ b/libp2p/NodeTable.h @@ -272,7 +272,7 @@ struct PingNode: RLPXDatagram PingNode(bi::udp::endpoint _ep): RLPXDatagram(_ep) {} PingNode(bi::udp::endpoint _ep, std::string _src, uint16_t _srcPort, std::chrono::seconds _expiration = std::chrono::seconds(60)): RLPXDatagram(_ep), ipAddress(_src), port(_srcPort), expiration(futureFromEpoch(_expiration)) {} - uint8_t packetType() { return 1; } + static const uint8_t type = 1; unsigned version = 1; std::string ipAddress; @@ -294,7 +294,8 @@ struct Pong: RLPXDatagram { Pong(bi::udp::endpoint _ep): RLPXDatagram(_ep), expiration(futureFromEpoch(std::chrono::seconds(60))) {} - uint8_t packetType() { return 2; } + static const uint8_t type = 2; + h256 echo; ///< MCD of PingNode unsigned expiration; @@ -319,8 +320,9 @@ struct FindNode: RLPXDatagram { FindNode(bi::udp::endpoint _ep): RLPXDatagram(_ep) {} FindNode(bi::udp::endpoint _ep, NodeId _target, std::chrono::seconds _expiration = std::chrono::seconds(30)): RLPXDatagram(_ep), target(_target), expiration(futureFromEpoch(_expiration)) {} + + static const uint8_t type = 3; - uint8_t packetType() { return 3; } h512 target; unsigned expiration; @@ -361,7 +363,7 @@ struct Neighbours: RLPXDatagram } } - uint8_t packetType() { return 4; } + static const uint8_t type = 4; std::list nodes; unsigned expiration = 1; diff --git a/libp2p/UDP.h b/libp2p/UDP.h index 9451e43f0..cc0dca330 100644 --- a/libp2p/UDP.h +++ b/libp2p/UDP.h @@ -77,6 +77,7 @@ struct RLPXDatagram: public RLPXDatagramFace { RLPXDatagram(bi::udp::endpoint const& _ep): RLPXDatagramFace(_ep) {} static T fromBytesConstRef(bi::udp::endpoint const& _ep, bytesConstRef _bytes) { T t(_ep); t.interpretRLP(_bytes); return std::move(t); } + uint8_t packetType() { return T::type; } }; /** From a1911f34952c81c37101680e8a95d720b4ca2398 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 29 Jan 2015 22:29:03 +0100 Subject: [PATCH 029/213] libp2p: add expiration to serialized Pong packets --- libp2p/NodeTable.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libp2p/NodeTable.h b/libp2p/NodeTable.h index 61241a333..8127c3597 100644 --- a/libp2p/NodeTable.h +++ b/libp2p/NodeTable.h @@ -286,7 +286,7 @@ struct PingNode: RLPXDatagram /** * Pong packet: response to ping * - * RLP Encoded Items: 1 + * RLP Encoded Items: 2 * Minimum Encoded Size: 33 bytes * Maximum Encoded Size: 33 bytes */ @@ -299,8 +299,8 @@ struct Pong: RLPXDatagram h256 echo; ///< MCD of PingNode unsigned expiration; - void streamRLP(RLPStream& _s) const { _s.appendList(1); _s << echo; } - void interpretRLP(bytesConstRef _bytes) { RLP r(_bytes); echo = (h256)r[0]; } + void streamRLP(RLPStream& _s) const { _s.appendList(2); _s << echo << expiration; } + void interpretRLP(bytesConstRef _bytes) { RLP r(_bytes); echo = (h256)r[0]; expiration = r[1].toInt(); } }; /** From 683a5da114c191c2b46b9355bbe001ba12acf2e7 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Fri, 30 Jan 2015 00:51:30 +0100 Subject: [PATCH 030/213] libp2p: use actual unix timestamps for discover packets --- libp2p/UDP.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libp2p/UDP.h b/libp2p/UDP.h index cc0dca330..bf9a6a372 100644 --- a/libp2p/UDP.h +++ b/libp2p/UDP.h @@ -60,8 +60,8 @@ protected: */ struct RLPXDatagramFace: public UDPDatagram { - static uint64_t futureFromEpoch(std::chrono::milliseconds _ms) { return std::chrono::duration_cast((std::chrono::system_clock::now() + _ms).time_since_epoch()).count(); } - static uint64_t futureFromEpoch(std::chrono::seconds _sec) { return std::chrono::duration_cast((std::chrono::system_clock::now() + _sec).time_since_epoch()).count(); } + static uint64_t futureFromEpoch(std::chrono::milliseconds _ms) { return std::chrono::duration_cast((std::chrono::system_clock::now() + _ms).time_since_epoch()).count(); } + static uint64_t futureFromEpoch(std::chrono::seconds _sec) { return std::chrono::duration_cast((std::chrono::system_clock::now() + _sec).time_since_epoch()).count(); } static Public authenticate(bytesConstRef _sig, bytesConstRef _rlp); virtual uint8_t packetType() =0; From 92f9ec8c42fece1c133ec89d2a33e0683df76da8 Mon Sep 17 00:00:00 2001 From: subtly Date: Fri, 30 Jan 2015 17:53:27 -0800 Subject: [PATCH 031/213] import/export peers and nodes --- alethzero/MainWin.cpp | 13 +-- alethzero/MainWin.h | 2 +- eth/main.cpp | 10 +- libp2p/Common.h | 5 +- libp2p/Host.cpp | 198 +++++++++++++++++++++------------------ libp2p/Host.h | 53 ++++++++--- libp2p/NodeTable.h | 3 +- libp2p/Session.cpp | 4 +- libp2p/Session.h | 2 +- libwebthree/WebThree.cpp | 13 +-- libwebthree/WebThree.h | 13 +-- neth/main.cpp | 9 +- test/net.cpp | 11 ++- test/peer.cpp | 37 ++++++++ third/MainWin.cpp | 19 ++-- third/MainWin.h | 2 +- 16 files changed, 235 insertions(+), 159 deletions(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 33089244d..55c32fb8e 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -660,10 +660,10 @@ void Main::writeSettings() s.setValue("verbosity", ui->verbosity->value()); s.setValue("jitvm", ui->jitvm->isChecked()); - bytes d = m_webThree->saveNodes(); + bytes d = m_webThree->saveNetwork(); if (d.size()) - m_peers = QByteArray((char*)d.data(), (int)d.size()); - s.setValue("peers", m_peers); + m_networkConfig = QByteArray((char*)d.data(), (int)d.size()); + s.setValue("peers", m_networkConfig); s.setValue("nameReg", ui->nameReg->text()); s.setValue("geometry", saveGeometry()); @@ -712,7 +712,7 @@ void Main::readSettings(bool _skipGeometry) } } - m_peers = s.value("peers").toByteArray(); + m_networkConfig = s.value("peers").toByteArray(); ui->upnp->setChecked(s.value("upnp", true).toBool()); ui->forceAddress->setText(s.value("forceAddress", "").toString()); ui->usePast->setChecked(s.value("usePast", true).toBool()); @@ -1859,8 +1859,9 @@ void Main::on_net_triggered() web3()->setIdealPeerCount(ui->idealPeers->value()); web3()->setNetworkPreferences(netPrefs()); ethereum()->setNetworkId(m_privateChain.size() ? sha3(m_privateChain.toStdString()) : 0); - if (m_peers.size()/* && ui->usePast->isChecked()*/) - web3()->restoreNodes(bytesConstRef((byte*)m_peers.data(), m_peers.size())); + // TODO: p2p + if (m_networkConfig.size()/* && ui->usePast->isChecked()*/) + web3()->restoreNetwork(bytesConstRef((byte*)m_networkConfig.data(), m_networkConfig.size())); web3()->startNetwork(); ui->downloadView->setDownloadMan(ethereum()->downloadMan()); } diff --git a/alethzero/MainWin.h b/alethzero/MainWin.h index b5639fc68..4e21d493f 100644 --- a/alethzero/MainWin.h +++ b/alethzero/MainWin.h @@ -251,7 +251,7 @@ private: unsigned m_currenciesFilter = (unsigned)-1; unsigned m_balancesFilter = (unsigned)-1; - QByteArray m_peers; + QByteArray m_networkConfig; QStringList m_servers; QList m_myKeys; QList m_myIdentities; diff --git a/eth/main.cpp b/eth/main.cpp index 515197ddc..f3a6a3941 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -332,13 +332,14 @@ int main(int argc, char** argv) VMFactory::setKind(jit ? VMKind::JIT : VMKind::Interpreter); NetworkPreferences netPrefs(listenPort, publicIP, upnp, useLocal); + auto nodesState = contents((dbPath.size() ? dbPath : getDataDir()) + "/network.rlp"); dev::WebThreeDirect web3( "Ethereum(++)/" + clientName + "v" + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM) + (jit ? "/JIT" : ""), dbPath, false, mode == NodeMode::Full ? set{"eth", "shh"} : set(), - netPrefs - ); + netPrefs, + &nodesState); web3.setIdealPeerCount(peers); eth::Client* c = mode == NodeMode::Full ? web3.ethereum() : nullptr; @@ -348,9 +349,6 @@ int main(int argc, char** argv) c->setAddress(coinbase); } - auto nodesState = contents((dbPath.size() ? dbPath : getDataDir()) + "/nodeState.rlp"); - web3.restoreNodes(&nodesState); - cout << "Address: " << endl << toHex(us.address().asArray()) << endl; web3.startNetwork(); @@ -824,7 +822,7 @@ int main(int argc, char** argv) while (!g_exit) this_thread::sleep_for(chrono::milliseconds(1000)); - writeFile((dbPath.size() ? dbPath : getDataDir()) + "/nodeState.rlp", web3.saveNodes()); + writeFile((dbPath.size() ? dbPath : getDataDir()) + "/network.rlp", web3.saveNetwork()); return 0; } diff --git a/libp2p/Common.h b/libp2p/Common.h index 784b2f513..19cf447ce 100644 --- a/libp2p/Common.h +++ b/libp2p/Common.h @@ -32,6 +32,7 @@ #include #include #include +#include namespace ba = boost::asio; namespace bi = boost::asio::ip; @@ -54,6 +55,8 @@ class Capability; class Host; class Session; +struct NetworkStartRequired: virtual dev::Exception {}; + struct NetWarn: public LogChannel { static const char* name() { return "!N!"; } static const int verbosity = 0; }; struct NetNote: public LogChannel { static const char* name() { return "*N*"; } static const int verbosity = 1; }; struct NetMessageSummary: public LogChannel { static const char* name() { return "-N-"; } static const int verbosity = 2; }; @@ -168,7 +171,7 @@ struct Node /// If true, node will not be removed from Node list. bool required = false; - operator bool() const { return (bool)id; } + virtual operator bool() const { return (bool)id; } }; } diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index f2f2b6a89..a526db259 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -45,14 +45,15 @@ void HostNodeTableHandler::processEvent(NodeId const& _n, NodeTableEventType con m_host.onNodeTableEvent(_n, _e); } -Host::Host(std::string const& _clientVersion, NetworkPreferences const& _n): +Host::Host(std::string const& _clientVersion, NetworkPreferences const& _n, bytesConstRef _restoreNetwork): Worker("p2p", 0), + m_restoreNetwork(_restoreNetwork.toBytes()), m_clientVersion(_clientVersion), m_netPrefs(_n), m_ifAddresses(Network::getInterfaceAddresses()), m_ioService(2), m_tcp4Acceptor(m_ioService), - m_alias(move(getHostIdentifier())), + m_alias(getNetworkAlias(_restoreNetwork)), m_lastPing(chrono::time_point::min()) { for (auto address: m_ifAddresses) @@ -124,7 +125,7 @@ void Host::doneWorking() RecursiveGuard l(x_sessions); for (auto i: m_sessions) if (auto p = i.second.lock()) - if (p->isOpen()) + if (p->isConnected()) { p->disconnect(ClientQuit); n++; @@ -156,6 +157,7 @@ unsigned Host::protocolVersion() const void Host::registerPeer(std::shared_ptr _s, CapDescs const& _caps) { { + clog(NetNote) << "p2p.host.peer.register" << _s->m_peer->id.abridged(); RecursiveGuard l(x_sessions); // TODO: temporary loose-coupling; if m_peers already has peer, // it is same as _s->m_peer. (fixing next PR) @@ -385,8 +387,6 @@ string Host::pocHost() void Host::addNode(NodeId const& _node, std::string const& _addr, unsigned short _tcpPeerPort, unsigned short _udpNodePort) { - - if (_tcpPeerPort < 30300 || _tcpPeerPort > 30305) cwarn << "Non-standard port being recorded: " << _tcpPeerPort; @@ -406,11 +406,11 @@ void Host::addNode(NodeId const& _node, std::string const& _addr, unsigned short if (_ec) return; bi::tcp::endpoint tcp = *_epIt; - addNode(Node(_node, NodeIPEndpoint(bi::udp::endpoint(tcp.address(), _udpNodePort), tcp))); + if (m_nodeTable) m_nodeTable->addNode(Node(_node, NodeIPEndpoint(bi::udp::endpoint(tcp.address(), _udpNodePort), tcp))); }); } else - addNode(Node(_node, NodeIPEndpoint(bi::udp::endpoint(addr, _udpNodePort), bi::tcp::endpoint(addr, _tcpPeerPort)))); + if (m_nodeTable) m_nodeTable->addNode(Node(_node, NodeIPEndpoint(bi::udp::endpoint(addr, _udpNodePort), bi::tcp::endpoint(addr, _tcpPeerPort)))); } void Host::connect(std::shared_ptr const& _p) @@ -473,11 +473,22 @@ PeerSessionInfos Host::peers() const RecursiveGuard l(x_sessions); for (auto& i: m_sessions) if (auto j = i.second.lock()) - if (j->m_socket.is_open()) + if (j->isConnected()) ret.push_back(j->m_info); return ret; } +size_t Host::peerCount() const +{ + unsigned retCount = 0; + RecursiveGuard l(x_sessions); + for (auto& i: m_sessions) + if (std::shared_ptr j = i.second.lock()) + if (j->isConnected()) + retCount++; + return retCount; +} + void Host::run(boost::system::error_code const&) { if (!m_run) @@ -537,16 +548,14 @@ void Host::startedWorking() if (m_listenPort > 0) runAcceptor(); - - if (!m_tcpPublic.address().is_unspecified()) - // TODO: add m_tcpPublic endpoint; sort out endpoint stuff for nodetable - m_nodeTable.reset(new NodeTable(m_ioService, m_alias, m_listenPort)); - else - m_nodeTable.reset(new NodeTable(m_ioService, m_alias, m_listenPort > 0 ? m_listenPort : 30303)); - m_nodeTable->setEventHandler(new HostNodeTableHandler(*this)); } else - clog(NetNote) << "p2p.start.notice id:" << id().abridged() << "Invalid listen-port. Node Table Disabled."; + clog(NetNote) << "p2p.start.notice id:" << id().abridged() << "Listen port is invalid or unavailable. Node Table using default port (30303)."; + + // TODO: add m_tcpPublic endpoint; sort out endpoint stuff for nodetable + m_nodeTable.reset(new NodeTable(m_ioService, m_alias, m_listenPort > 0 ? m_listenPort : 30303)); + m_nodeTable->setEventHandler(new HostNodeTableHandler(*this)); + restoreNetwork(&m_restoreNetwork); clog(NetNote) << "p2p.started id:" << id().abridged(); @@ -585,112 +594,117 @@ void Host::disconnectLatePeers() pp->disconnect(PingTimeout); } -bytes Host::saveNodes() const +bytes Host::saveNetwork() const { - RLPStream nodes; + std::list peers; + { + RecursiveGuard l(x_sessions); + for (auto p: m_peers) + if (p.second) + peers.push_back(*p.second); + } + peers.sort(); + + RLPStream network; int count = 0; { RecursiveGuard l(x_sessions); - for (auto const& i: m_peers) + for (auto const& p: peers) { - Peer const& n = *(i.second); - // TODO: alpha: Figure out why it ever shares these ports.//n.address.port() >= 30300 && n.address.port() <= 30305 && + // TODO: alpha: Figure out why it ever shares these ports.//p.address.port() >= 30300 && p.address.port() <= 30305 && // TODO: alpha: if/how to save private addresses // Only save peers which have connected within 2 days, with properly-advertised port and public IP address - if (chrono::system_clock::now() - n.lastConnected < chrono::seconds(3600 * 48) && n.peerEndpoint().port() > 0 && n.peerEndpoint().port() < /*49152*/32768 && n.id != id() && !isPrivateAddress(n.peerEndpoint().address())) + if (chrono::system_clock::now() - p.lastConnected < chrono::seconds(3600 * 48) && p.peerEndpoint().port() > 0 && p.peerEndpoint().port() < /*49152*/32768 && p.id != id() && !isPrivateAddress(p.peerEndpoint().address())) { - nodes.appendList(10); - if (n.peerEndpoint().address().is_v4()) - nodes << n.peerEndpoint().address().to_v4().to_bytes(); + network.appendList(10); + if (p.peerEndpoint().address().is_v4()) + network << p.peerEndpoint().address().to_v4().to_bytes(); else - nodes << n.peerEndpoint().address().to_v6().to_bytes(); + network << p.peerEndpoint().address().to_v6().to_bytes(); // TODO: alpha: replace 0 with trust-state of node - nodes << n.peerEndpoint().port() << n.id << 0 - << chrono::duration_cast(n.lastConnected.time_since_epoch()).count() - << chrono::duration_cast(n.lastAttempted.time_since_epoch()).count() - << n.failedAttempts << (unsigned)n.lastDisconnect << n.score << n.rating; + network << p.peerEndpoint().port() << p.id << 0 + << chrono::duration_cast(p.lastConnected.time_since_epoch()).count() + << chrono::duration_cast(p.lastAttempted.time_since_epoch()).count() + << p.failedAttempts << (unsigned)p.lastDisconnect << p.score << p.rating; count++; } } } + + auto state = m_nodeTable->state(); + state.sort(); + for (auto const& s: state) + { + network.appendList(3); + if (s.endpoint.tcp.address().is_v4()) + network << s.endpoint.tcp.address().to_v4().to_bytes(); + else + network << s.endpoint.tcp.address().to_v6().to_bytes(); + network << s.endpoint.tcp.port() << s.id; + count++; + } + RLPStream ret(3); - ret << 0 << m_alias.secret(); - ret.appendList(count).appendRaw(nodes.out(), count); + ret << 1 << m_alias.secret(); + ret.appendList(count).appendRaw(network.out(), count); return ret.out(); } -// TODO: p2p Import-ant -void Host::restoreNodes(bytesConstRef _b) +void Host::restoreNetwork(bytesConstRef _b) { + // nodes can only be added if network is added + if (!isStarted()) + BOOST_THROW_EXCEPTION(NetworkStartRequired()); + RecursiveGuard l(x_sessions); RLP r(_b); - if (r.itemCount() > 0 && r[0].isInt()) - switch (r[0].toInt()) - { - case 0: - { - m_alias = KeyPair(r[1].toHash()); -// noteNode(id(), m_tcpPublic); + if (r.itemCount() > 0 && r[0].isInt() && r[0].toInt() == 1) + { + // r[0] = version + // r[1] = key + // r[2] = nodes - for (auto i: r[2]) + for (auto i: r[2]) + { + bi::tcp::endpoint tcp; + bi::udp::endpoint udp; + if (i[0].itemCount() == 4) { - bi::tcp::endpoint ep; - if (i[0].itemCount() == 4) - ep = bi::tcp::endpoint(bi::address_v4(i[0].toArray()), i[1].toInt()); - else - ep = bi::tcp::endpoint(bi::address_v6(i[0].toArray()), i[1].toInt()); - auto id = (NodeId)i[2]; - if (!m_peers.count(id)) - { - // TODO: p2p import/export :) -// auto n = noteNode(id, ep); -// n->lastConnected = chrono::system_clock::time_point(chrono::seconds(i[4].toInt())); -// n->lastAttempted = chrono::system_clock::time_point(chrono::seconds(i[5].toInt())); -// n->failedAttempts = i[6].toInt(); -// n->lastDisconnect = (DisconnectReason)i[7].toInt(); -// n->score = (int)i[8].toInt(); -// n->rating = (int)i[9].toInt(); - } + tcp = bi::tcp::endpoint(bi::address_v4(i[0].toArray()), i[1].toInt()); + udp = bi::udp::endpoint(bi::address_v4(i[0].toArray()), i[1].toInt()); + } + else + { + tcp = bi::tcp::endpoint(bi::address_v6(i[0].toArray()), i[1].toInt()); + udp = bi::udp::endpoint(bi::address_v6(i[0].toArray()), i[1].toInt()); } - } - default:; - } - else - for (auto i: r) - { auto id = (NodeId)i[2]; - if (!m_peers.count(id)) + if (i.itemCount() == 3) + m_nodeTable->addNode(id, udp, tcp); + else if (i.itemCount() == 10) { - bi::tcp::endpoint ep; - if (i[0].itemCount() == 4) - ep = bi::tcp::endpoint(bi::address_v4(i[0].toArray()), i[1].toInt()); - else - ep = bi::tcp::endpoint(bi::address_v6(i[0].toArray()), i[1].toInt()); -// auto n = noteNode(id, ep); + shared_ptr p = make_shared(); + p->id = id; + p->lastConnected = chrono::system_clock::time_point(chrono::seconds(i[4].toInt())); + p->lastAttempted = chrono::system_clock::time_point(chrono::seconds(i[5].toInt())); + p->failedAttempts = i[6].toInt(); + p->lastDisconnect = (DisconnectReason)i[7].toInt(); + p->score = (int)i[8].toInt(); + p->rating = (int)i[9].toInt(); + p->endpoint.tcp = tcp; + p->endpoint.udp = udp; + m_peers[p->id] = p; + m_nodeTable->addNode(*p.get()); } } + } } -KeyPair Host::getHostIdentifier() +KeyPair Host::getNetworkAlias(bytesConstRef _b) { - static string s_file(getDataDir() + "/host"); - static mutex s_x; - lock_guard l(s_x); - - h256 secret; - bytes b = contents(s_file); - if (b.size() == 32) - memcpy(secret.data(), b.data(), 32); + RLP r(_b); + if (r.itemCount() == 3 && r[0].isInt() && r[0].toInt() == 1) + return move(KeyPair(move(Secret(r[1].toBytes())))); else - { - // todo: replace w/user entropy; abstract to devcrypto - std::mt19937_64 s_eng(time(0) + chrono::high_resolution_clock::now().time_since_epoch().count()); - std::uniform_int_distribution d(0, 255); - for (unsigned i = 0; i < 32; ++i) - secret[i] = (byte)d(s_eng); - } - - if (!secret) - BOOST_THROW_EXCEPTION(crypto::InvalidState()); - return move(KeyPair(move(secret))); + return move(KeyPair::create()); } diff --git a/libp2p/Host.h b/libp2p/Host.h index a4493f9bf..cd45f3268 100644 --- a/libp2p/Host.h +++ b/libp2p/Host.h @@ -66,7 +66,7 @@ class Host; * Specifically, peers can be utilized in a variety of * many-to-many relationships while also needing to modify shared instances of * those peers. Modifying these properties via a storage backend alleviates - * Host of the responsibility. (&& remove save/restoreNodes) + * Host of the responsibility. (&& remove save/restoreNetwork) * @todo reimplement recording of historical session information on per-transport basis * @todo rebuild nodetable when localNetworking is enabled/disabled * @todo move attributes into protected @@ -74,7 +74,7 @@ class Host; class Peer: public Node { friend class Session; /// Allows Session to update score and rating. - friend class Host; /// For Host: saveNodes(), restoreNodes() + friend class Host; /// For Host: saveNetwork(), restoreNetwork() public: bool isOffline() const { return !m_session.lock(); } @@ -90,6 +90,28 @@ public: unsigned failedAttempts = 0; DisconnectReason lastDisconnect = NoDisconnect; ///< Reason for disconnect that happened last. + virtual bool operator<(Peer const& _p) const + { + if (isOffline() != _p.isOffline()) + return isOffline(); + else if (isOffline()) + if (lastAttempted == _p.lastAttempted) + return failedAttempts < _p.failedAttempts; + else + return lastAttempted < _p.lastAttempted; + else + if (score == _p.score) + if (rating == _p.rating) + if (failedAttempts == _p.failedAttempts) + return id < _p.id; + else + return failedAttempts < _p.failedAttempts; + else + return rating < _p.rating; + else + return score < _p.score; + } + protected: /// Used by isOffline() and (todo) for peer to emit session information. std::weak_ptr m_session; @@ -109,6 +131,7 @@ class HostNodeTableHandler: public NodeTableEventHandler * @brief The Host class * Capabilities should be registered prior to startNetwork, since m_capabilities is not thread-safe. * + * @todo exceptions when nodeTable not set (prior to start) * @todo onNodeTableEvent: move peer-connection logic into ensurePeers * @todo handshake: gracefully disconnect peer if peer already connected * @todo abstract socket -> IPConnection @@ -116,6 +139,7 @@ class HostNodeTableHandler: public NodeTableEventHandler * @todo handle conflict if addNode/requireNode called and Node already exists w/conflicting tcp or udp port * @todo write host identifier to disk w/nodes * @todo per-session keepalive/ping instead of broadcast; set ping-timeout via median-latency + * @todo configuration-management (NetworkPrefs+Keys+Topology) */ class Host: public Worker { @@ -125,7 +149,7 @@ class Host: public Worker public: /// Start server, listening for connections on the given port. - Host(std::string const& _clientVersion, NetworkPreferences const& _n = NetworkPreferences()); + Host(std::string const& _clientVersion, NetworkPreferences const& _n = NetworkPreferences(), bytesConstRef _restoreNetwork = bytesConstRef()); /// Will block on network process events. virtual ~Host(); @@ -158,10 +182,10 @@ public: /// Get peer information. PeerSessionInfos peers() const; - - /// Get number of peers connected; equivalent to, but faster than, peers().size(). - size_t peerCount() const { RecursiveGuard l(x_sessions); return m_peers.size(); } - + + /// Get number of peers connected. + size_t peerCount() const; + /// Get the address we're listening on currently. std::string listenAddress() const { return m_tcpPublic.address().to_string(); } @@ -169,10 +193,7 @@ public: unsigned short listenPort() const { return m_tcpPublic.port(); } /// Serialise the set of known peers. - bytes saveNodes() const; - - /// Deserialise the data and populate the set of known peers. - void restoreNodes(bytesConstRef _b); + bytes saveNetwork() const; // TODO: P2P this should be combined with peers into a HostStat object of some kind; coalesce data, as it's only used for status information. Peers nodes() const { RecursiveGuard l(x_sessions); Peers ret; for (auto const& i: m_peers) ret.push_back(*i.second); return ret; } @@ -196,6 +217,9 @@ public: protected: void onNodeTableEvent(NodeId const& _n, NodeTableEventType const& _e); + /// Deserialise the data and populate the set of known peers. + void restoreNetwork(bytesConstRef _b); + private: /// Populate m_peerAddresses with available public addresses. void determinePublic(std::string const& _publicAddress, bool _upnp); @@ -226,13 +250,12 @@ private: /// Shutdown network. Not thread-safe; to be called only by worker. virtual void doneWorking(); - - /// Add node - void addNode(Node const& _node) { if (m_nodeTable) m_nodeTable->addNode(_node); } /// Get or create host identifier (KeyPair). - KeyPair getHostIdentifier(); + static KeyPair getNetworkAlias(bytesConstRef _b); + bytes m_restoreNetwork; ///< Set by constructor and used to set Host key and restore network peers & nodes. + bool m_run = false; ///< Whether network is running. std::mutex x_runTimer; ///< Start/stop mutex. diff --git a/libp2p/NodeTable.h b/libp2p/NodeTable.h index 7f9e3877f..b0fafa6cf 100644 --- a/libp2p/NodeTable.h +++ b/libp2p/NodeTable.h @@ -161,6 +161,7 @@ public: NodeEntry root() const { return NodeEntry(m_node, m_node.publicKey(), m_node.endpoint.udp); } std::list nodes() const; + unsigned size() const { return m_nodes.size(); } std::list state() const; bool haveNode(NodeId _id) { Guard l(x_nodes); return m_nodes.count(_id); } @@ -347,7 +348,7 @@ struct Neighbours: RLPXDatagram void interpretRLP(RLP const& _r) { ipAddress = _r[0].toString(); port = _r[1].toInt(); node = h512(_r[2].toBytes()); } }; - Neighbours(bi::udp::endpoint _ep): RLPXDatagram(_ep) {} + Neighbours(bi::udp::endpoint _ep): RLPXDatagram(_ep), expiration(futureFromEpoch(std::chrono::seconds(30))) {} Neighbours(bi::udp::endpoint _to, std::vector> const& _nearest, unsigned _offset = 0, unsigned _limit = 0): RLPXDatagram(_to), expiration(futureFromEpoch(std::chrono::seconds(30))) { auto limit = _limit ? std::min(_nearest.size(), (size_t)(_offset + _limit)) : _nearest.size(); diff --git a/libp2p/Session.cpp b/libp2p/Session.cpp index 7e618fb3b..1e93f5b1d 100644 --- a/libp2p/Session.cpp +++ b/libp2p/Session.cpp @@ -102,7 +102,7 @@ template vector randomSelection(vector const& _t, unsigned _n) // TODO: P2P integration: replace w/asio post -> serviceNodesRequest() void Session::ensureNodesRequested() { - if (isOpen() && !m_weRequestedNodes) + if (isConnected() && !m_weRequestedNodes) { m_weRequestedNodes = true; RLPStream s; @@ -310,7 +310,7 @@ bool Session::interpret(RLP const& _r) // OK passed all our checks. Assume it's good. addRating(1000); - m_server->addNode(Node(id, NodeIPEndpoint(bi::udp::endpoint(ep.address(), ep.port()), ep))); + m_server->addNode(id, ep.address().to_string(), ep.port(), ep.port()); clogS(NetTriviaDetail) << "New peer: " << ep << "(" << id .abridged()<< ")"; CONTINUE:; LAMEPEER:; diff --git a/libp2p/Session.h b/libp2p/Session.h index 87620a604..4d55e7d9d 100644 --- a/libp2p/Session.h +++ b/libp2p/Session.h @@ -59,7 +59,7 @@ public: void ping(); - bool isOpen() const { return m_socket.is_open(); } + bool isConnected() const { return m_socket.is_open(); } NodeId id() const; unsigned socketId() const { return m_socket.native_handle(); } diff --git a/libwebthree/WebThree.cpp b/libwebthree/WebThree.cpp index 40e878858..7daec9693 100644 --- a/libwebthree/WebThree.cpp +++ b/libwebthree/WebThree.cpp @@ -35,9 +35,9 @@ using namespace dev::p2p; using namespace dev::eth; using namespace dev::shh; -WebThreeDirect::WebThreeDirect(std::string const& _clientVersion, std::string const& _dbPath, bool _forceClean, std::set const& _interfaces, NetworkPreferences const& _n): +WebThreeDirect::WebThreeDirect(std::string const& _clientVersion, std::string const& _dbPath, bool _forceClean, std::set const& _interfaces, NetworkPreferences const& _n, bytesConstRef _network): m_clientVersion(_clientVersion), - m_net(_clientVersion, _n) + m_net(_clientVersion, _n, _network) { if (_dbPath.size()) Defaults::setDBPath(_dbPath); @@ -90,14 +90,9 @@ void WebThreeDirect::setIdealPeerCount(size_t _n) return m_net.setIdealPeerCount(_n); } -bytes WebThreeDirect::saveNodes() +bytes WebThreeDirect::saveNetwork() { - return m_net.saveNodes(); -} - -void WebThreeDirect::restoreNodes(bytesConstRef _saved) -{ - return m_net.restoreNodes(_saved); + return m_net.saveNetwork(); } void WebThreeDirect::connect(std::string const& _seedHost, unsigned short _port) diff --git a/libwebthree/WebThree.h b/libwebthree/WebThree.h index 3b97a0763..f99eed5cf 100644 --- a/libwebthree/WebThree.h +++ b/libwebthree/WebThree.h @@ -63,10 +63,7 @@ public: virtual void connect(std::string const& _seedHost, unsigned short _port) = 0; /// Save peers - virtual dev::bytes saveNodes() = 0; - - /// Restore peers - virtual void restoreNodes(bytesConstRef _saved) = 0; + virtual dev::bytes saveNetwork() = 0; /// Sets the ideal number of peers. virtual void setIdealPeerCount(size_t _n) = 0; @@ -106,7 +103,7 @@ class WebThreeDirect : public WebThreeNetworkFace public: /// Constructor for private instance. If there is already another process on the machine using @a _dbPath, then this will throw an exception. /// ethereum() may be safely static_cast()ed to a eth::Client*. - WebThreeDirect(std::string const& _clientVersion, std::string const& _dbPath, bool _forceClean = false, std::set const& _interfaces = {"eth", "shh"}, p2p::NetworkPreferences const& _n = p2p::NetworkPreferences()); + WebThreeDirect(std::string const& _clientVersion, std::string const& _dbPath, bool _forceClean = false, std::set const& _interfaces = {"eth", "shh"}, p2p::NetworkPreferences const& _n = p2p::NetworkPreferences(), bytesConstRef _network = bytesConstRef()); /// Destructor. ~WebThreeDirect(); @@ -133,10 +130,10 @@ public: void connect(std::string const& _seedHost, unsigned short _port = 30303) override; /// Save peers - dev::bytes saveNodes() override; + dev::bytes saveNetwork() override; - /// Restore peers - void restoreNodes(bytesConstRef _saved) override; +// /// Restore peers +// void restoreNetwork(bytesConstRef _saved) override; /// Sets the ideal number of peers. void setIdealPeerCount(size_t _n) override; diff --git a/neth/main.cpp b/neth/main.cpp index e49e47c16..cb84e87c7 100644 --- a/neth/main.cpp +++ b/neth/main.cpp @@ -415,13 +415,14 @@ int main(int argc, char** argv) cout << credits(); NetworkPreferences netPrefs(listenPort, publicIP, upnp, useLocal); + auto nodesState = contents((dbPath.size() ? dbPath : getDataDir()) + "/network.rlp"); dev::WebThreeDirect web3( "NEthereum(++)/" + clientName + "v" + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM), dbPath, false, mode == NodeMode::Full ? set{"eth", "shh"} : set(), - netPrefs - ); + netPrefs, + &nodesState); web3.setIdealPeerCount(peers); eth::Client* c = mode == NodeMode::Full ? web3.ethereum() : nullptr; @@ -431,9 +432,7 @@ int main(int argc, char** argv) c->setAddress(coinbase); } - auto nodesState = contents((dbPath.size() ? dbPath : getDataDir()) + "/nodeState.rlp"); - web3.restoreNodes(&nodesState); - + cout << "Address: " << endl << toHex(us.address().asArray()) << endl; web3.startNetwork(); if (bootstrap) diff --git a/test/net.cpp b/test/net.cpp index 67c50dae8..7f30ed03b 100644 --- a/test/net.cpp +++ b/test/net.cpp @@ -30,7 +30,7 @@ using namespace dev::p2p; namespace ba = boost::asio; namespace bi = ba::ip; -BOOST_AUTO_TEST_SUITE(p2p) +BOOST_AUTO_TEST_SUITE(net) /** * Only used for testing. Not useful beyond tests. @@ -190,6 +190,9 @@ BOOST_AUTO_TEST_CASE(kademlia) node.populateAll(); clog << "NodeTable:\n" << *node.nodeTable.get() << endl; + auto nodes = node.nodeTable->nodes(); + nodes.sort(); + node.nodeTable->reset(); clog << "NodeTable:\n" << *node.nodeTable.get() << endl; @@ -199,6 +202,12 @@ BOOST_AUTO_TEST_CASE(kademlia) node.nodeTable->join(); this_thread::sleep_for(chrono::milliseconds(2000)); clog << "NodeTable:\n" << *node.nodeTable.get() << endl; + + BOOST_REQUIRE_EQUAL(node.nodeTable->size(), 8); + + auto netNodes = node.nodeTable->nodes(); + netNodes.sort(); + } BOOST_AUTO_TEST_CASE(test_udp_once) diff --git a/test/peer.cpp b/test/peer.cpp index a4b07e0b3..7f3c19e1e 100644 --- a/test/peer.cpp +++ b/test/peer.cpp @@ -50,6 +50,43 @@ BOOST_AUTO_TEST_CASE(host) BOOST_REQUIRE_EQUAL(host2.peerCount(), host1.peerCount()); } +BOOST_AUTO_TEST_CASE(save_nodes) +{ + std::list hosts; + for (auto i:{0,1,2,3,4,5}) + { + Host* h = new Host("Test", NetworkPreferences(30300 + i, "127.0.0.1", true, true)); + // starting host is required so listenport is available + h->start(); + while (!h->isStarted()) + this_thread::sleep_for(chrono::milliseconds(2)); + hosts.push_back(h); + } + + Host& host = *hosts.front(); + for (auto const& h: hosts) + host.addNode(h->id(), "127.0.0.1", h->listenPort(), h->listenPort()); + + Host& host2 = *hosts.back(); + for (auto const& h: hosts) + host2.addNode(h->id(), "127.0.0.1", h->listenPort(), h->listenPort()); + + this_thread::sleep_for(chrono::milliseconds(1000)); + bytes firstHostNetwork(host.saveNetwork()); + bytes secondHostNetwork(host.saveNetwork()); + + BOOST_REQUIRE_EQUAL(sha3(firstHostNetwork), sha3(secondHostNetwork)); + + BOOST_CHECK_EQUAL(host.peerCount(), 5); + BOOST_CHECK_EQUAL(host2.peerCount(), 5); + + RLP r(firstHostNetwork); + BOOST_REQUIRE(r.itemCount() == 3); + BOOST_REQUIRE(r[0].toInt() == 1); + BOOST_REQUIRE_EQUAL(r[1].toBytes().size(), 32); // secret + BOOST_REQUIRE_EQUAL(r[2].itemCount(), 5); +} + BOOST_AUTO_TEST_SUITE_END() int peerTest(int argc, char** argv) diff --git a/third/MainWin.cpp b/third/MainWin.cpp index 35650f94b..71d89039d 100644 --- a/third/MainWin.cpp +++ b/third/MainWin.cpp @@ -114,7 +114,8 @@ Main::Main(QWidget *parent) : connect(ui->ourAccounts->model(), SIGNAL(rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)), SLOT(ourAccountsRowsMoved())); - m_web3.reset(new WebThreeDirect("Third", getDataDir() + "/Third", false, {"eth", "shh"})); + bytesConstRef networkConfig((byte*)m_networkConfig.data(), m_networkConfig.size()) + m_web3.reset(new WebThreeDirect("Third", getDataDir() + "/Third", false, {"eth", "shh"}, NetworkPreferences(), networkConfig)); m_web3->connect(Host::pocHost()); m_server = unique_ptr(new WebThreeStubServer(m_qwebConnector, *web3(), keysAsVector(m_myKeys))); @@ -377,10 +378,10 @@ void Main::writeSettings() s.setValue("address", b); s.setValue("url", ui->urlEdit->text()); - bytes d = m_web3->saveNodes(); + bytes d = m_web3->saveNetwork(); if (d.size()) - m_nodes = QByteArray((char*)d.data(), (int)d.size()); - s.setValue("peers", m_nodes); + m_networkConfig = QByteArray((char*)d.data(), (int)d.size()); + s.setValue("peers", m_networkConfig); s.setValue("geometry", saveGeometry()); s.setValue("windowState", saveState()); @@ -409,7 +410,7 @@ void Main::readSettings(bool _skipGeometry) } } ethereum()->setAddress(m_myKeys.back().address()); - m_nodes = s.value("peers").toByteArray(); + m_networkConfig = s.value("peers").toByteArray(); ui->urlEdit->setText(s.value("url", "about:blank").toString()); //http://gavwood.com/gavcoin.html on_urlEdit_returnPressed(); } @@ -581,11 +582,9 @@ void Main::ensureNetwork() web3()->startNetwork(); web3()->connect(defPeer); } - else - if (!m_web3->peerCount()) - m_web3->connect(defPeer); - if (m_nodes.size()) - m_web3->restoreNodes(bytesConstRef((byte*)m_nodes.data(), m_nodes.size())); +// else +// if (!m_web3->peerCount()) +// m_web3->connect(defPeer); } void Main::on_connect_triggered() diff --git a/third/MainWin.h b/third/MainWin.h index 0bd75d5de..924fc057e 100644 --- a/third/MainWin.h +++ b/third/MainWin.h @@ -131,7 +131,7 @@ private: unsigned m_currenciesFilter = (unsigned)-1; unsigned m_balancesFilter = (unsigned)-1; - QByteArray m_nodes; + QByteArray m_networkConfig; QStringList m_servers; QNetworkAccessManager m_webCtrl; From 0d7a4a929df97ac2b051565c117c8c94e85a81c7 Mon Sep 17 00:00:00 2001 From: winsvega Date: Sat, 31 Jan 2015 20:36:14 +0300 Subject: [PATCH 032/213] transaction address length test fix --- test/transaction.cpp | 4 +++- test/ttTransactionTestFiller.json | 34 ++----------------------------- 2 files changed, 5 insertions(+), 33 deletions(-) diff --git a/test/transaction.cpp b/test/transaction.cpp index e1e275302..8c2e99cf9 100644 --- a/test/transaction.cpp +++ b/test/transaction.cpp @@ -21,7 +21,6 @@ */ #include "TestHelper.h" - using namespace std; using namespace json_spirit; using namespace dev; @@ -152,6 +151,9 @@ void doTransactionTests(json_spirit::mValue& _v, bool _fillin) if (!txFromFields.signature().isValid()) BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("transaction from RLP signature is invalid") ); + //cause Address is length20 array, when trying to create address from sting of another length, field "to" would be diffrent from RLP encoded Address + BOOST_CHECK_MESSAGE(Address(tObj["to"].get_str()) == txFromFields.receiveAddress(), "seems that transaction 'to' address has wrong format"); + o["sender"] = toString(txFromFields.sender()); } catch(...) diff --git a/test/ttTransactionTestFiller.json b/test/ttTransactionTestFiller.json index 3c39b9da5..6967f4284 100644 --- a/test/ttTransactionTestFiller.json +++ b/test/ttTransactionTestFiller.json @@ -242,44 +242,14 @@ } }, - "AddressMore20" : { + "WrongAddress" : { "transaction" : { "data" : "", "gasLimit" : "", "gasPrice" : "", "nonce" : "", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d871f", - "value" : "", - "v" : "27", - "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", - "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" - } - }, - - "AddressLess20" : { - "transaction" : - { - "data" : "", - "gasLimit" : "", - "gasPrice" : "", - "nonce" : "", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d", - "value" : "", - "v" : "27", - "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", - "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" - } - }, - - "AddressMore20WithFirstZeros" : { - "transaction" : - { - "data" : "", - "gasLimit" : "", - "gasPrice" : "", - "nonce" : "", - "to" : "0x00000000000000000000000095e7baea6a6c7c4c2dfeb977efac326af552d", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d8v", "value" : "", "v" : "27", "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", From a51e889f4ac10fe5b7820d44b5a84fceee74f804 Mon Sep 17 00:00:00 2001 From: winsvega Date: Sat, 31 Jan 2015 21:00:35 +0300 Subject: [PATCH 033/213] state test conditions to filler files --- test/TestHelper.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/TestHelper.cpp b/test/TestHelper.cpp index 5a579702a..8cb4e11c0 100644 --- a/test/TestHelper.cpp +++ b/test/TestHelper.cpp @@ -108,6 +108,12 @@ void ImportTest::importState(json_spirit::mObject& _o, State& _state) BOOST_REQUIRE(o.count("storage") > 0); BOOST_REQUIRE(o.count("code") > 0); + bigint biValue256 = bigint("115792089237316195423570985008687907853269984665640564039457584007913129639936"); + if (bigint(o["balance"].get_str()) >= biValue256) + BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("State 'balance' is equal or grater than 2**256") ); + if (bigint(o["nonce"].get_str()) >= biValue256) + BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("State 'nonce' is equal or grater than 2**256") ); + Address address = Address(i.first); bytes code = importCode(o); @@ -140,6 +146,16 @@ void ImportTest::importTransaction(json_spirit::mObject& _o) BOOST_REQUIRE(_o.count("secretKey") > 0); BOOST_REQUIRE(_o.count("data") > 0); + bigint biValue256 = bigint("115792089237316195423570985008687907853269984665640564039457584007913129639936"); + if (bigint(_o["nonce"].get_str()) >= biValue256) + BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("Transaction 'nonce' is equal or grater than 2**256") ); + if (bigint(_o["gasPrice"].get_str()) >= biValue256) + BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("Transaction 'gasPrice' is equal or grater than 2**256") ); + if (bigint(_o["gasLimit"].get_str()) >= biValue256) + BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("Transaction 'gasLimit' is equal or grater than 2**256") ); + if (bigint(_o["value"].get_str()) >= biValue256) + BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("Transaction 'value' is equal or grater than 2**256") ); + m_transaction = _o["to"].get_str().empty() ? Transaction(toInt(_o["value"]), toInt(_o["gasPrice"]), toInt(_o["gasLimit"]), importData(_o), toInt(_o["nonce"]), Secret(_o["secretKey"].get_str())) : Transaction(toInt(_o["value"]), toInt(_o["gasPrice"]), toInt(_o["gasLimit"]), Address(_o["to"].get_str()), importData(_o), toInt(_o["nonce"]), Secret(_o["secretKey"].get_str())); From 6bbcaae5e29c8b81cc3e85e5d695e342016d37f6 Mon Sep 17 00:00:00 2001 From: subtly Date: Mon, 2 Feb 2015 09:46:41 -0800 Subject: [PATCH 034/213] alethzero, third: load network config --- alethzero/MainWin.cpp | 9 +++++---- third/MainWin.cpp | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 6a8cf07fe..f20782a42 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -159,8 +159,9 @@ Main::Main(QWidget *parent) : statusBar()->addPermanentWidget(ui->blockCount); connect(ui->ourAccounts->model(), SIGNAL(rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)), SLOT(ourAccountsRowsMoved())); - - m_webThree.reset(new WebThreeDirect(string("AlethZero/v") + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM), getDataDir() + "/AlethZero", false, {"eth", "shh"})); + + bytesConstRef network((byte*)m_networkConfig.data(), m_networkConfig.size()); + m_webThree.reset(new WebThreeDirect(string("AlethZero/v") + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM), getDataDir() + "/AlethZero", false, {"eth", "shh"}, p2p::NetworkPreferences(), network)); m_qwebConnector.reset(new QWebThreeConnector()); m_server.reset(new OurWebThreeStubServer(*m_qwebConnector, *web3(), keysAsVector(m_myKeys), this)); @@ -1860,8 +1861,8 @@ void Main::on_net_triggered() web3()->setNetworkPreferences(netPrefs()); ethereum()->setNetworkId(m_privateChain.size() ? sha3(m_privateChain.toStdString()) : 0); // TODO: p2p - if (m_networkConfig.size()/* && ui->usePast->isChecked()*/) - web3()->restoreNetwork(bytesConstRef((byte*)m_networkConfig.data(), m_networkConfig.size())); +// if (m_networkConfig.size()/* && ui->usePast->isChecked()*/) +// web3()->restoreNetwork(bytesConstRef((byte*)m_networkConfig.data(), m_networkConfig.size())); web3()->startNetwork(); ui->downloadView->setDownloadMan(ethereum()->downloadMan()); } diff --git a/third/MainWin.cpp b/third/MainWin.cpp index b50722eff..e52cecc7e 100644 --- a/third/MainWin.cpp +++ b/third/MainWin.cpp @@ -114,7 +114,7 @@ Main::Main(QWidget *parent) : connect(ui->ourAccounts->model(), SIGNAL(rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)), SLOT(ourAccountsRowsMoved())); - bytesConstRef networkConfig((byte*)m_networkConfig.data(), m_networkConfig.size()) + bytesConstRef networkConfig((byte*)m_networkConfig.data(), m_networkConfig.size()); m_web3.reset(new WebThreeDirect("Third", getDataDir() + "/Third", false, {"eth", "shh"}, NetworkPreferences(), networkConfig)); m_web3->connect(Host::pocHost()); From 0ac7d86c87c28582a7a1c98c4cc1cf666540fdf9 Mon Sep 17 00:00:00 2001 From: subtly Date: Mon, 2 Feb 2015 09:47:16 -0800 Subject: [PATCH 035/213] update whisper test for node-network --- test/whisperTopic.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/test/whisperTopic.cpp b/test/whisperTopic.cpp index 6c08ae1ab..99032d99b 100644 --- a/test/whisperTopic.cpp +++ b/test/whisperTopic.cpp @@ -101,6 +101,7 @@ BOOST_AUTO_TEST_CASE(forwarding) bool done = false; bool startedListener = false; + Public phid; std::thread listener([&]() { setThreadName("listener"); @@ -110,6 +111,7 @@ BOOST_AUTO_TEST_CASE(forwarding) ph.setIdealPeerCount(0); auto wh = ph.registerCapability(new WhisperHost()); ph.start(); + phid = ph.id(); startedListener = true; @@ -130,6 +132,7 @@ BOOST_AUTO_TEST_CASE(forwarding) }); bool startedForwarder = false; + Public fwderid; std::thread forwarder([&]() { setThreadName("forwarder"); @@ -143,9 +146,10 @@ BOOST_AUTO_TEST_CASE(forwarding) auto wh = ph.registerCapability(new WhisperHost()); this_thread::sleep_for(chrono::milliseconds(500)); ph.start(); + fwderid = ph.id(); this_thread::sleep_for(chrono::milliseconds(500)); - ph.connect("127.0.0.1", 50303); + ph.addNode(phid, "127.0.0.1", 50303, 50303); startedForwarder = true; @@ -172,7 +176,7 @@ BOOST_AUTO_TEST_CASE(forwarding) this_thread::sleep_for(chrono::milliseconds(500)); ph.start(); this_thread::sleep_for(chrono::milliseconds(500)); - ph.connect("127.0.0.1", 50305); + ph.addNode(fwderid, "127.0.0.1", 50305, 50305); KeyPair us = KeyPair::create(); wh->post(us.sec(), RLPStream().append(1).out(), BuildTopic("test")); @@ -195,6 +199,7 @@ BOOST_AUTO_TEST_CASE(asyncforwarding) unsigned result = 0; bool done = false; + Public listenerid; bool startedForwarder = false; std::thread forwarder([&]() { @@ -206,9 +211,9 @@ BOOST_AUTO_TEST_CASE(asyncforwarding) auto wh = ph.registerCapability(new WhisperHost()); this_thread::sleep_for(chrono::milliseconds(500)); ph.start(); - + this_thread::sleep_for(chrono::milliseconds(500)); - ph.connect("127.0.0.1", 50303); +// ph.addNode("127.0.0.1", 50303, 50303); startedForwarder = true; @@ -236,7 +241,7 @@ BOOST_AUTO_TEST_CASE(asyncforwarding) this_thread::sleep_for(chrono::milliseconds(500)); ph.start(); this_thread::sleep_for(chrono::milliseconds(500)); - ph.connect("127.0.0.1", 50305); +// ph.addNode("127.0.0.1", 50305, 50305); KeyPair us = KeyPair::create(); wh->post(us.sec(), RLPStream().append(1).out(), BuildTopic("test")); @@ -250,7 +255,7 @@ BOOST_AUTO_TEST_CASE(asyncforwarding) this_thread::sleep_for(chrono::milliseconds(500)); ph.start(); this_thread::sleep_for(chrono::milliseconds(500)); - ph.connect("127.0.0.1", 50305); +// ph.addNode("127.0.0.1", 50305, 50305); /// Only interested in odd packets auto w = wh->installWatch(BuildTopicMask("test")); From 27e2f98278280a7c613252d3de557c4cf4096357 Mon Sep 17 00:00:00 2001 From: subtly Date: Wed, 4 Feb 2015 17:50:03 -0800 Subject: [PATCH 036/213] fix whispertopic test --- test/whisperTopic.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/test/whisperTopic.cpp b/test/whisperTopic.cpp index 9c88d1b24..1dcc6b9d6 100644 --- a/test/whisperTopic.cpp +++ b/test/whisperTopic.cpp @@ -40,15 +40,6 @@ BOOST_AUTO_TEST_CASE(topic) auto whOther = phOther.registerCapability(new WhisperHost()); phOther.start(); - Host ph("Test", NetworkPreferences(30300, "127.0.0.1", false, true)); - auto wh = ph.registerCapability(new WhisperHost()); - ph.start(); - - this_thread::sleep_for(chrono::milliseconds(100)); - ph.addNode(phOther.id(), "127.0.0.1", 30303, 30303); - - this_thread::sleep_for(chrono::milliseconds(500)); - bool started = false; unsigned result = 0; std::thread listener([&]() @@ -66,7 +57,7 @@ BOOST_AUTO_TEST_CASE(topic) { for (auto i: whOther->checkWatch(w)) { - Message msg = wh->envelope(i).open(wh->fullTopic(w)); + Message msg = whOther->envelope(i).open(whOther->fullTopic(w)); last = RLP(msg.payload()).toInt(); if (received.count(last)) continue; @@ -78,6 +69,15 @@ BOOST_AUTO_TEST_CASE(topic) } }); + + Host ph("Test", NetworkPreferences(30300, "127.0.0.1", false, true)); + auto wh = ph.registerCapability(new WhisperHost()); + ph.start(); + + this_thread::sleep_for(chrono::milliseconds(100)); + ph.addNode(phOther.id(), "127.0.0.1", 30303, 30303); + + this_thread::sleep_for(chrono::milliseconds(500)); while (!started) this_thread::sleep_for(chrono::milliseconds(2)); From ac8ddfdcd80eef27eb6bb0bd71caa285d2ee3105 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Thu, 5 Feb 2015 16:34:46 +0100 Subject: [PATCH 037/213] first definition of block tests - header only --- libethcore/BlockInfo.cpp | 2 +- test/blValidBlockTestFiller.json | 20 ++++ test/block.cpp | 185 ++++++++++++++++++++++++++++++- 3 files changed, 204 insertions(+), 3 deletions(-) create mode 100644 test/blValidBlockTestFiller.json diff --git a/libethcore/BlockInfo.cpp b/libethcore/BlockInfo.cpp index 62017796e..8465424a8 100644 --- a/libethcore/BlockInfo.cpp +++ b/libethcore/BlockInfo.cpp @@ -134,7 +134,7 @@ void BlockInfo::populate(bytesConstRef _block, bool _checkNonce) RLP header = root[0]; if (!header.isList()) - BOOST_THROW_EXCEPTION(InvalidBlockFormat(0,header.data())); + BOOST_THROW_EXCEPTION(InvalidBlockFormat(0,header.data()) << errinfo_comment("block header needs to be a list")); populateFromHeader(header, _checkNonce); if (!root[1].isList()) diff --git a/test/blValidBlockTestFiller.json b/test/blValidBlockTestFiller.json new file mode 100644 index 000000000..ab0369fa4 --- /dev/null +++ b/test/blValidBlockTestFiller.json @@ -0,0 +1,20 @@ +{ + "validBlock" : { + "block" : { + "parentHash": "0xefb4db878627027c81b3bb1c7dd3a18dae3914a49cdd24a3e40ab3bbfbb240c5", + "uncleHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "coinbase": "0x8888f1f195afa192cfee860698584c030f4c9db1", + "stateRoot": "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "transactionsTrie": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "receiptTrie": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "bloom": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "difficulty": "023101", + "number": "62", + "gasLimit": "0x0dddb6", + "gasUsed": "100", + "timestamp": "0x54c98c81", + "extraData": "42", + "nonce": "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d" + } + } +} diff --git a/test/block.cpp b/test/block.cpp index 974acbf6d..674c7c40d 100644 --- a/test/block.cpp +++ b/test/block.cpp @@ -14,8 +14,189 @@ You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ -/** @file state.cpp +/** @file block.cpp * @author Christoph Jentzsch - * @date 2014 + * @date 2015 * block test functions. */ + +#include "TestHelper.h" + +using namespace std; +using namespace json_spirit; +using namespace dev; +using namespace dev::eth; + +namespace dev { namespace test { + +bytes createBlockRLPFromFields(mObject& _tObj) +{ + BOOST_REQUIRE(_tObj.count("parentHash") > 0); + BOOST_REQUIRE(_tObj.count("uncleHash") > 0); + BOOST_REQUIRE(_tObj.count("coinbase") > 0); + BOOST_REQUIRE(_tObj.count("stateRoot") > 0); + BOOST_REQUIRE(_tObj.count("transactionsTrie")> 0); + BOOST_REQUIRE(_tObj.count("receiptTrie") > 0); + BOOST_REQUIRE(_tObj.count("bloom") > 0); + BOOST_REQUIRE(_tObj.count("difficulty") > 0); + BOOST_REQUIRE(_tObj.count("number") > 0); + BOOST_REQUIRE(_tObj.count("gasLimit")> 0); + BOOST_REQUIRE(_tObj.count("gasUsed") > 0); + BOOST_REQUIRE(_tObj.count("timestamp") > 0); + BOOST_REQUIRE(_tObj.count("extraData") > 0); + BOOST_REQUIRE(_tObj.count("nonce") > 0); + + // construct RLP of the given block + cout << "done with require\n"; + RLPStream rlpStream; + rlpStream.appendList(14); + cout << "increate aha1\n"; + rlpStream << h256(_tObj["parentHash"].get_str()) << h256(_tObj["uncleHash"].get_str()) << Address(_tObj["coinbase"].get_str()); + rlpStream << h256(_tObj["stateRoot"].get_str()) << h256(_tObj["transactionsTrie"].get_str()) << Address(_tObj["receiptTrie"].get_str()); + rlpStream << LogBloom(_tObj["bloom"].get_str()) << u256(_tObj["difficulty"].get_str()) << u256(_tObj["number"].get_str()); + rlpStream << u256(_tObj["gasLimit"].get_str()) << u256(_tObj["gasUsed"].get_str()) << u256(_tObj["timestamp"].get_str()); + rlpStream << importByteArray(_tObj["extraData"].get_str()) << h256(_tObj["nonce"].get_str()); + + return rlpStream.out(); +} + +void doBlockTests(json_spirit::mValue& _v, bool _fillin) +{ + for (auto& i: _v.get_obj()) + { + cerr << i.first << endl; + mObject& o = i.second.get_obj(); + + if (_fillin == false) + { + BOOST_REQUIRE(o.count("rlp") > 0); + const bytes rlpReaded = importByteArray(o["rlp"].get_str()); + RLP myRLP(rlpReaded); + BlockInfo blockFromRlp; + + try + { + blockFromRlp.populateFromHeader(myRLP, false); + //blockFromRlp.verifyInternals(rlpReaded); + } + catch(Exception const& _e) + { + cnote << "block construction did throw an exception: " << diagnostic_information(_e); + BOOST_ERROR("Failed block construction Test with Exception: " << _e.what()); + BOOST_CHECK_MESSAGE(o.count("block") == 0, "A block object should not be defined because the block RLP is invalid!"); + return; + } + + BOOST_REQUIRE(o.count("block") > 0); + + mObject tObj = o["block"].get_obj(); + BlockInfo blockFromFields; + const bytes rlpreade2 = createBlockRLPFromFields(tObj); + RLP mysecondRLP(rlpreade2); + blockFromFields.populateFromHeader(mysecondRLP, false); + + //Check the fields restored from RLP to original fields + BOOST_CHECK_MESSAGE(blockFromFields.hash == blockFromRlp.hash, "hash in given RLP not matching the block hash!"); + BOOST_CHECK_MESSAGE(blockFromFields.parentHash == blockFromRlp.parentHash, "parentHash in given RLP not matching the block parentHash!"); + BOOST_CHECK_MESSAGE(blockFromFields.sha3Uncles == blockFromRlp.sha3Uncles, "sha3Uncles in given RLP not matching the block sha3Uncles!"); + BOOST_CHECK_MESSAGE(blockFromFields.coinbaseAddress == blockFromRlp.coinbaseAddress,"coinbaseAddress in given RLP not matching the block coinbaseAddress!"); + BOOST_CHECK_MESSAGE(blockFromFields.stateRoot == blockFromRlp.stateRoot, "stateRoot in given RLP not matching the block stateRoot!"); + BOOST_CHECK_MESSAGE(blockFromFields.transactionsRoot == blockFromRlp.transactionsRoot, "transactionsRoot in given RLP not matching the block transactionsRoot!"); + BOOST_CHECK_MESSAGE(blockFromFields.logBloom == blockFromRlp.logBloom, "logBloom in given RLP not matching the block logBloom!"); + BOOST_CHECK_MESSAGE(blockFromFields.difficulty == blockFromRlp.difficulty, "difficulty in given RLP not matching the block difficulty!"); + BOOST_CHECK_MESSAGE(blockFromFields.number == blockFromRlp.number, "number in given RLP not matching the block number!"); + BOOST_CHECK_MESSAGE(blockFromFields.gasLimit == blockFromRlp.gasLimit,"gasLimit in given RLP not matching the block gasLimit!"); + BOOST_CHECK_MESSAGE(blockFromFields.gasUsed == blockFromRlp.gasUsed, "gasUsed in given RLP not matching the block gasUsed!"); + BOOST_CHECK_MESSAGE(blockFromFields.timestamp == blockFromRlp.timestamp, "timestamp in given RLP not matching the block timestamp!"); + BOOST_CHECK_MESSAGE(blockFromFields.extraData == blockFromRlp.extraData, "extraData in given RLP not matching the block extraData!"); + BOOST_CHECK_MESSAGE(blockFromFields.nonce == blockFromRlp.nonce, "nonce in given RLP not matching the block nonce!"); + + BOOST_CHECK_MESSAGE(blockFromFields == blockFromRlp, "However, blockFromFields != blockFromRlp!"); + + } + else + { + BOOST_REQUIRE(o.count("block") > 0); + + // construct Rlp of the given block + bytes blockRLP = createBlockRLPFromFields(o["block"].get_obj()); + RLP myRLP(blockRLP); + o["rlp"] = toHex(blockRLP); + + try + { + BlockInfo blockFromFields; + blockFromFields.populateFromHeader(myRLP, false); + (void)blockFromFields; + //blockFromFields.verifyInternals(blockRLP); + } + catch (Exception const& _e) + { + cnote << "block construction did throw an exception: " << diagnostic_information(_e); + BOOST_ERROR("Failed block construction Test with Exception: " << _e.what()); + o.erase(o.find("block")); + } + catch (std::exception const& _e) + { + cnote << "block construction did throw an exception: " << _e.what(); + BOOST_ERROR("Failed block construction Test with Exception: " << _e.what()); + o.erase(o.find("block")); + } + catch(...) + { + o.erase(o.find("block")); + } + } + } +} + +} }// Namespace Close + + +BOOST_AUTO_TEST_SUITE(BlockTests) + +BOOST_AUTO_TEST_CASE(blValidBlocksTest) +{ + dev::test::executeTests("blValidBlockTest", "/BlockTests", dev::test::doBlockTests); +} + +BOOST_AUTO_TEST_CASE(ttCreateTest) +{ + for (int i = 1; i < boost::unit_test::framework::master_test_suite().argc; ++i) + { + string arg = boost::unit_test::framework::master_test_suite().argv[i]; + if (arg == "--createtest") + { + if (boost::unit_test::framework::master_test_suite().argc <= i + 2) + { + cnote << "usage: ./testeth --createtest \n"; + return; + } + try + { + cnote << "Populating tests..."; + json_spirit::mValue v; + string s = asString(dev::contents(boost::unit_test::framework::master_test_suite().argv[i + 1])); + BOOST_REQUIRE_MESSAGE(s.length() > 0, "Content of " + (string)boost::unit_test::framework::master_test_suite().argv[i + 1] + " is empty."); + json_spirit::read_string(s, v); + dev::test::doBlockTests(v, true); + writeFile(boost::unit_test::framework::master_test_suite().argv[i + 2], asBytes(json_spirit::write_string(v, true))); + } + catch (Exception const& _e) + { + BOOST_ERROR("Failed block test with Exception: " << diagnostic_information(_e)); + } + catch (std::exception const& _e) + { + BOOST_ERROR("Failed block test with Exception: " << _e.what()); + } + } + } +} + +BOOST_AUTO_TEST_CASE(userDefinedFileTT) +{ + dev::test::userDefinedTest("--bltest", dev::test::doBlockTests); +} + +BOOST_AUTO_TEST_SUITE_END() From 00293a05b642e5091357f7f1b8fa44051859a396 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Fri, 6 Feb 2015 15:00:06 +0100 Subject: [PATCH 038/213] include transaction list --- test/block.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/test/block.cpp b/test/block.cpp index 674c7c40d..40984e8da 100644 --- a/test/block.cpp +++ b/test/block.cpp @@ -144,8 +144,30 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) } catch(...) { + cnote << "block construction did throw an unknow exception\n"; o.erase(o.find("block")); } + + BOOST_REQUIRE(o.count("transactions") > 0); + + for (auto const& txObj: o["transactions"].get_array()) + { + mObject tx = txObj.get_obj(); + BOOST_REQUIRE(tx.count("nonce") > 0); + BOOST_REQUIRE(tx.count("gasPrice") > 0); + BOOST_REQUIRE(tx.count("gasLimit") > 0); + BOOST_REQUIRE(tx.count("to") > 0); + BOOST_REQUIRE(tx.count("value") > 0); + BOOST_REQUIRE(tx.count("v") > 0); + BOOST_REQUIRE(tx.count("r") > 0); + BOOST_REQUIRE(tx.count("s") > 0); + BOOST_REQUIRE(tx.count("data") > 0); + + Transaction txFromFields = createTransactionFromFields(tx); + + + + } } } } From 2adee26fc012cbc5fee9ddc1c895626d51239590 Mon Sep 17 00:00:00 2001 From: winsvega Date: Fri, 6 Feb 2015 18:28:48 +0300 Subject: [PATCH 039/213] nonce value from 0 to "0" in fillers --- test/TestHelper.cpp | 13 +- test/randomTestFiller.json | 2 +- test/stBlockHashTestFiller.json | 12 +- test/stInitCodeTestFiller.json | 14 +- test/stLogTestsFiller.json | 270 ++++----- test/stPreCompiledContractsFiller.json | 96 +-- test/stRecursiveCreateFiller.json | 4 +- test/stRefundTestFiller.json | 32 +- test/stSpecialTestFiller.json | 6 +- test/stSystemOperationsTestFiller.json | 228 +++---- test/stTransactionTestFiller.json | 296 ++++++++++ test/vmArithmeticTestFiller.json | 624 ++++++++++---------- test/vmBitwiseLogicOperationTestFiller.json | 240 ++++---- test/vmBlockInfoTestFiller.json | 44 +- test/vmEnvironmentalInfoTestFiller.json | 172 +++--- test/vmIOandFlowOperationsTestFiller.json | 424 ++++++------- test/vmLogTestFiller.json | 184 +++--- test/vmPushDupSwapTestFiller.json | 276 ++++----- test/vmSha3TestFiller.json | 28 +- test/vmSystemOperationsTestFiller.json | 136 ++--- test/vmtestsFiller.json | 16 +- 21 files changed, 1707 insertions(+), 1410 deletions(-) diff --git a/test/TestHelper.cpp b/test/TestHelper.cpp index 8cb4e11c0..fc05de85a 100644 --- a/test/TestHelper.cpp +++ b/test/TestHelper.cpp @@ -110,9 +110,9 @@ void ImportTest::importState(json_spirit::mObject& _o, State& _state) bigint biValue256 = bigint("115792089237316195423570985008687907853269984665640564039457584007913129639936"); if (bigint(o["balance"].get_str()) >= biValue256) - BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("State 'balance' is equal or grater than 2**256") ); + BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("State 'balance' is equal or greater than 2**256") ); if (bigint(o["nonce"].get_str()) >= biValue256) - BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("State 'nonce' is equal or grater than 2**256") ); + BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("State 'nonce' is equal or greater than 2**256") ); Address address = Address(i.first); @@ -148,13 +148,14 @@ void ImportTest::importTransaction(json_spirit::mObject& _o) bigint biValue256 = bigint("115792089237316195423570985008687907853269984665640564039457584007913129639936"); if (bigint(_o["nonce"].get_str()) >= biValue256) - BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("Transaction 'nonce' is equal or grater than 2**256") ); + BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("Transaction 'nonce' is equal or greater than 2**256") ); if (bigint(_o["gasPrice"].get_str()) >= biValue256) - BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("Transaction 'gasPrice' is equal or grater than 2**256") ); + BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("Transaction 'gasPrice' is equal or greater than 2**256") ); if (bigint(_o["gasLimit"].get_str()) >= biValue256) - BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("Transaction 'gasLimit' is equal or grater than 2**256") ); + BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("Transaction 'gasLimit' is equal or greater than 2**256") ); if (bigint(_o["value"].get_str()) >= biValue256) - BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("Transaction 'value' is equal or grater than 2**256") ); + BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("Transaction 'value' is equal or greater than 2**256") ); + m_transaction = _o["to"].get_str().empty() ? Transaction(toInt(_o["value"]), toInt(_o["gasPrice"]), toInt(_o["gasLimit"]), importData(_o), toInt(_o["nonce"]), Secret(_o["secretKey"].get_str())) : diff --git a/test/randomTestFiller.json b/test/randomTestFiller.json index 065a21b34..0712cc40f 100644 --- a/test/randomTestFiller.json +++ b/test/randomTestFiller.json @@ -11,7 +11,7 @@ "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "random", "storage": {} } diff --git a/test/stBlockHashTestFiller.json b/test/stBlockHashTestFiller.json index ccbff5d21..af2234976 100644 --- a/test/stBlockHashTestFiller.json +++ b/test/stBlockHashTestFiller.json @@ -11,13 +11,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (BLOCKHASH 0) [[ 1 ]] (BLOCKHASH 5) [[ 2 ]] (BLOCKHASH 4) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "100000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -45,13 +45,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (BLOCKHASH 0) [[ 1 ]] (BLOCKHASH 257) [[ 2 ]] (BLOCKHASH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "100000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -79,13 +79,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (BLOCKHASH 1) [[ 1 ]] (BLOCKHASH 2) [[ 2 ]] (BLOCKHASH 256) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "100000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } diff --git a/test/stInitCodeTestFiller.json b/test/stInitCodeTestFiller.json index ac6bbee16..0996bd6a2 100644 --- a/test/stInitCodeTestFiller.json +++ b/test/stInitCodeTestFiller.json @@ -229,7 +229,7 @@ { "095e7baea6a6c7c4c2dfeb977efac326af552d87": { "balance": "0", - "nonce": 0, + "nonce": "0", "code": "{(CREATE 0 0 32)}", "storage": {} }, @@ -267,7 +267,7 @@ { "095e7baea6a6c7c4c2dfeb977efac326af552d87": { "balance": "0", - "nonce": 0, + "nonce": "0", "code": "{[[ 2 ]](ADDRESS)(CODECOPY 0 0 32)(CREATE 0 0 32)}", "storage": {} }, @@ -305,7 +305,7 @@ { "095e7baea6a6c7c4c2dfeb977efac326af552d87": { "balance": "1", - "nonce": 0, + "nonce": "0", "//": "{[[0]] 12 (CREATE 0 64 32)}", "code": "{(MSTORE 0 0x600c600055602060406000f0)(CREATE 0 20 12)}", "storage": {} @@ -344,7 +344,7 @@ { "095e7baea6a6c7c4c2dfeb977efac326af552d87": { "balance": "1000", - "nonce": 0, + "nonce": "0", "//": "(CREATE 0 64 32)", "//": "{[[0]] 12 (MSTORE 32 0x602060406000f0)(RETURN 57 7)}", "code": "{(MSTORE 0 0x600c60005566602060406000f060205260076039f3)[[0]](CREATE 1 11 21)(CALL 500 (SLOAD 0) 1 0 0 0 0)}", @@ -384,7 +384,7 @@ { "095e7baea6a6c7c4c2dfeb977efac326af552d87": { "balance": "0", - "nonce": 0, + "nonce": "0", "//": "(CREATE 0 64 32)", "//": "{[[0]] 12 (MSTORE 32 0x602060406000f0)(RETURN 57 7)}", "code": "{(MSTORE 0 0x600c60005566602060406000f060205260076039f3)[[0]](CREATE 1 11 21)(CALL 0 (SLOAD 0) 0 0 0 0 0)}", @@ -424,7 +424,7 @@ { "095e7baea6a6c7c4c2dfeb977efac326af552d87": { "balance": "1000", - "nonce": 0, + "nonce": "0", "//": "(CREATE 0 64 32)", "//": "{[[0]] 12 (MSTORE 32 0x602060406000f0)(RETURN 57 7)}", "code": "{(MSTORE 0 0x600c60005566602060406000f060205260076039f3)[[0]](CREATE 1 11 21)(CALL 0 (SLOAD 0) 1 0 0 0 0)}", @@ -464,7 +464,7 @@ { "095e7baea6a6c7c4c2dfeb977efac326af552d87": { "balance": "1000", - "nonce": 0, + "nonce": "0", "//": "(CREATE 0 64 32)", "//": "{[[0]] 12 (MSTORE 32 0x602060406000f0)(RETURN 57 7)}", "code": "{(MSTORE 0 0x600c60005566602060406000f060205260076039f3)[[0]](CREATE 1001 11 21)}", diff --git a/test/stLogTestsFiller.json b/test/stLogTestsFiller.json index 34758ff83..0f31c4c63 100644 --- a/test/stLogTestsFiller.json +++ b/test/stLogTestsFiller.json @@ -11,19 +11,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (LOG0 0 0) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -52,19 +52,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG0 0 32) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -93,19 +93,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG0 0 1) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -135,19 +135,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG0 31 1) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -176,19 +176,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 1) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -217,19 +217,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG0 1 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -258,19 +258,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG0 1 0) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -299,19 +299,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (LOG1 0 0 0) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -340,19 +340,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG1 0 32 0) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -381,19 +381,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG1 0 1 0) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -423,19 +423,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG1 31 1 0) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -464,19 +464,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG1 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 1 0) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -505,19 +505,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG1 1 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -546,19 +546,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG1 1 0 0) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -587,19 +587,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG1 0 32 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -628,19 +628,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE8 0 0xff) (LOG1 0 32 (CALLER)) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -669,19 +669,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (LOG2 0 0 0 0) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -710,19 +710,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG2 0 32 0 0) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -751,19 +751,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG2 0 1 0 0) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -793,19 +793,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG2 31 1 0 0) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -834,19 +834,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG2 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 1 0 0) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -875,19 +875,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG2 1 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0 0) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -916,19 +916,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG2 1 0 0 0) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -957,19 +957,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG2 0 32 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -998,19 +998,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE8 0 0xff) (LOG2 0 32 0 (CALLER) ) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1039,19 +1039,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (LOG3 0 0 0 0 0) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1080,19 +1080,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG3 0 32 0 0 0) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1121,19 +1121,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG3 0 1 0 0 0) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1163,19 +1163,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG3 31 1 0 0 0) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1204,19 +1204,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG3 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 1 0 0 0) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1245,19 +1245,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG3 1 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0 0 0) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1286,19 +1286,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG3 1 0 0 0 0) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1327,19 +1327,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG3 0 32 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1368,19 +1368,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE8 0 0xff) (LOG3 0 32 0 0 (CALLER) ) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1409,19 +1409,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE8 0 0xff) (LOG3 0 32 (PC) (PC) (PC) ) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1450,19 +1450,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (LOG4 0 0 0 0 0 0) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1491,19 +1491,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG4 0 32 0 0 0 0) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1532,19 +1532,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG4 0 1 0 0 0 0) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1574,19 +1574,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG4 31 1 0 0 0 0) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1615,19 +1615,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG4 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 1 0 0 0 0) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1656,19 +1656,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG4 1 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0 0 0 0) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1697,19 +1697,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG4 1 0 0 0 0 0) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1738,19 +1738,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG4 0 32 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1779,19 +1779,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE8 0 0xff) (LOG3 0 32 0 0 0 (CALLER) ) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1820,19 +1820,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 23 0 0 0 0) }", "storage": {} }, "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE8 0 0xff) (LOG3 0 32 (PC) (PC) (PC) (PC) ) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } diff --git a/test/stPreCompiledContractsFiller.json b/test/stPreCompiledContractsFiller.json index 62a3a1623..7c7fd8e4b 100644 --- a/test/stPreCompiledContractsFiller.json +++ b/test/stPreCompiledContractsFiller.json @@ -11,13 +11,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", - "nonce" : 0, + "nonce" : "0", "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 1000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -45,13 +45,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", - "nonce" : 0, + "nonce" : "0", "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 1000 1 0 0 128 64 32) [[ 0 ]] (MOD (MLOAD 64) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -80,13 +80,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", - "nonce" : 0, + "nonce" : "0", "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 1000 1 0 0 128 128 32) [[ 0 ]] (MLOAD 128) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -114,13 +114,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", - "nonce" : 0, + "nonce" : "0", "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 500 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -148,13 +148,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", - "nonce" : 0, + "nonce" : "0", "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 499 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -182,13 +182,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", - "nonce" : 0, + "nonce" : "0", "code": "{ [[ 2 ]] (CALL 1000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -216,13 +216,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", - "nonce" : 0, + "nonce" : "0", "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 1) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 1000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -250,13 +250,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", - "nonce" : 0, + "nonce" : "0", "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 33 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 65 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 1000 1 0 0 97 97 32) [[ 0 ]] (MOD (MLOAD 97) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -284,13 +284,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", - "nonce" : 0, + "nonce" : "0", "code": "{ (MSTORE 0 0x2f380a2dea7e778d81affc2443403b8fe4644db442ae4862ff5bb3732829cdb9) (MSTORE 32 27) (MSTORE 64 0x6b65ccb0558806e9b097f27a396d08f964e37b8b7af6ceeb516ff86739fbea0a) (MSTORE 96 0x37cbc8d883e129a4b1ef9d5f1df53c4f21a3ef147cf2a50a4ede0eb06ce092d4) [[ 2 ]] (CALL 1000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -318,13 +318,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x600160005260206000602060006000600260fff1600051600055", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -352,13 +352,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 2 ]] (CALL 500 2 0 0 0 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -386,13 +386,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 2 ]] (CALL 500 2 0x13 0 0 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -420,13 +420,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 5 0xf34578907f) [[ 2 ]] (CALL 500 2 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -454,13 +454,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xf34578907f) [[ 2 ]] (CALL 500 2 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -488,13 +488,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 100 2 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -522,13 +522,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 99 2 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -556,13 +556,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 500 2 0 0 1000000 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -590,13 +590,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x600160005260206000602060006000600360fff1600051600055", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -624,13 +624,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 2 ]] (CALL 500 3 0 0 0 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -658,13 +658,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 5 0xf34578907f) [[ 2 ]] (CALL 500 3 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -692,13 +692,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xf34578907f) [[ 2 ]] (CALL 500 3 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -726,13 +726,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 100 3 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -760,13 +760,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 99 3 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -794,13 +794,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 500 3 0 0 1000000 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } diff --git a/test/stRecursiveCreateFiller.json b/test/stRecursiveCreateFiller.json index 0d18fb7a5..25a909d9c 100644 --- a/test/stRecursiveCreateFiller.json +++ b/test/stRecursiveCreateFiller.json @@ -11,13 +11,13 @@ "pre": { "095e7baea6a6c7c4c2dfeb977efac326af552d87": { "balance": "20000000", - "nonce": 0, + "nonce" : "0", "code": "{(CODECOPY 0 0 32)(CREATE 0 0 32)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b": { "balance": "1000000000000000000", - "nonce": 0, + "nonce" : "0", "code": "", "storage": {} } diff --git a/test/stRefundTestFiller.json b/test/stRefundTestFiller.json index 6b2b2fc15..627d0167d 100644 --- a/test/stRefundTestFiller.json +++ b/test/stRefundTestFiller.json @@ -11,7 +11,7 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 1 ]] 0 }", "storage" : { "0x01" : "0x01" @@ -19,7 +19,7 @@ }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -47,7 +47,7 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 1 ]] 23 }", "storage" : { "0x01" : "0x01" @@ -55,7 +55,7 @@ }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -83,7 +83,7 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 1 ]] 0 }", "storage" : { "0x01" : "0x01" @@ -91,7 +91,7 @@ }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "500", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -119,7 +119,7 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 1 ]] 0 }", "storage" : { "0x01" : "0x01" @@ -127,7 +127,7 @@ }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "502", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -155,7 +155,7 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 1 ]] 0 [[ 2 ]] 0 [[ 3 ]] 0 [[ 4 ]] 0 [[ 5 ]] 0 }", "storage" : { "0x01" : "0x01", @@ -167,7 +167,7 @@ }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "10000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -195,7 +195,7 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 10 ]] 1 [[ 11 ]] 1 [[ 1 ]] 0 [[ 2 ]] 0 [[ 3 ]] 0 [[ 4 ]] 0 [[ 5 ]] 0 }", "storage" : { "0x01" : "0x01", @@ -207,7 +207,7 @@ }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "10000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -235,7 +235,7 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ @@1 @@2 [[ 10 ]] (EXP 2 0xff) [[ 11 ]] (BALANCE (ADDRESS)) [[ 1 ]] 0 [[ 2 ]] 0 [[ 3 ]] 0 [[ 4 ]] 0 [[ 5 ]] 0 [[ 6 ]] 0 }", "storage" : { "0x01" : "0x01", @@ -248,7 +248,7 @@ }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "10000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -276,7 +276,7 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ @@1 @@2 [[ 10 ]] (EXP 2 0xffff) [[ 11 ]] (BALANCE (ADDRESS)) [[ 1 ]] 0 [[ 2 ]] 0 [[ 3 ]] 0 [[ 4 ]] 0 [[ 5 ]] 0 [[ 6 ]] 0 }", "storage" : { "0x01" : "0x01", @@ -289,7 +289,7 @@ }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "10000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } diff --git a/test/stSpecialTestFiller.json b/test/stSpecialTestFiller.json index 3691df80f..d01072b46 100644 --- a/test/stSpecialTestFiller.json +++ b/test/stSpecialTestFiller.json @@ -11,19 +11,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0x601080600c6000396000f20060003554156009570060203560003555) (CALL 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec 0xaaaaaaaaace5edbc8e2a8697c15331677e6ebf0b 23 0 0 0 0) }", "storage": {} }, "aaaaaaaaace5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x600160015532600255", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } diff --git a/test/stSystemOperationsTestFiller.json b/test/stSystemOperationsTestFiller.json index 253ba0a8a..dcdb6d8f0 100644 --- a/test/stSystemOperationsTestFiller.json +++ b/test/stSystemOperationsTestFiller.json @@ -11,13 +11,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0x601080600c6000396000f3006000355415600957005b60203560003555) [[ 0 ]] (CREATE 23 3 29) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -45,13 +45,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "10000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0x601080600c6000396000f3006000355415600957005b60203560003555) [[ 0 ]] (CREATE 11000 3 0xffffffffffffffffffffff) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -79,13 +79,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0x601080600c6000396000f3006000355415600957005b60203560003555) [[ 0 ]] (CREATE 23 3 0) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -113,13 +113,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0x601080600c6000396000f3006000355415600957005b60203560003555) [[ 0 ]] (CREATE 23 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -148,13 +148,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0x601080600c6000396000f3006000355415600957005b60203560003555) [[ 0 ]] (CREATE 23 0 0) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -182,13 +182,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0x601080600c6000396000f3006000355415600957005b60203560003555) [[ 0 ]] (CREATE 1000 3 29) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -216,13 +216,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0x601080600c6000396000f3006000355415600957005b60203560003555) [[ 0 ]] (CREATE 23 0xfffffffffff 29) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -250,13 +250,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0x601080600c6000396000f3006000355415600957005b60203560003555) [[ 0 ]] (CREATE 23 3 0xfffffffffff) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -284,13 +284,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (BALANCE 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0baa ) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -318,7 +318,7 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 1000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 64 64 0) }", "storage": {} }, @@ -331,7 +331,7 @@ }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -360,7 +360,7 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 0xffffffffff 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 0xffffffffffff 64 0) }", "storage": {} }, @@ -373,7 +373,7 @@ }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -402,7 +402,7 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 1000 0xaa945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 64 64 0) }", "storage": {} }, @@ -415,7 +415,7 @@ }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -444,7 +444,7 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 1000 0x945304eb96065b2a98b57a48a06ae28d285a71b5aa 23 0 64 64 0) }", "storage": {} }, @@ -457,7 +457,7 @@ }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -486,7 +486,7 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 1000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 0 0 0) }", "storage": {} }, @@ -499,7 +499,7 @@ }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -528,7 +528,7 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALL 1000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 0 31 1) [[ 1 ]] @0 }", "storage": {} }, @@ -541,7 +541,7 @@ }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -569,7 +569,7 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6001601f60006000601773945304eb96065b2a98b57a48a06ae28d285a71b56103e8f1600055600051565b6023602355", "storage": {} }, @@ -582,7 +582,7 @@ }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -610,7 +610,7 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6001601f60006000601773945304eb96065b2a98b57a48a06ae28d285a71b56103e8f160005560005156605b6023602355", "storage": {} }, @@ -623,7 +623,7 @@ }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -651,7 +651,7 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) (POST 1000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 64 ) }", "storage": {} }, @@ -664,7 +664,7 @@ }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -693,7 +693,7 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALLSTATELESS 500 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 64 0 2 ) }", "storage": {} }, @@ -706,7 +706,7 @@ }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -735,7 +735,7 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALLCODE 500 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 64 0 2 ) }", "storage": {} }, @@ -748,7 +748,7 @@ }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -778,7 +778,7 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xeeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 100 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 64 64 0) }", "storage": {} }, @@ -791,7 +791,7 @@ }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -820,7 +820,7 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xeeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 500 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 987654321 64 64 0) }", "storage": {} }, @@ -833,7 +833,7 @@ }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -861,7 +861,7 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xeeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 500 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 9865432 64 0) }", "storage": {} }, @@ -874,7 +874,7 @@ }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -902,7 +902,7 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xeeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 500 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 64 987654 1) }", "storage": {} }, @@ -915,7 +915,7 @@ }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -944,7 +944,7 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xeeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 500 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 64 987654 0) }", "storage": {} }, @@ -957,7 +957,7 @@ }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -985,7 +985,7 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xeeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 500 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 987654 0 64 0) }", "storage": {} }, @@ -998,7 +998,7 @@ }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1026,19 +1026,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (CALL 100000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 0 0 0) }", "storage": {} }, "945304eb96065b2a98b57a48a06ae28d285a71b5" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (+ (SLOAD 0) 1) [[ 1 ]] (CALL (- (GAS) 224) (ADDRESS) 0 0 0 0 0) } ", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1066,19 +1066,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (CALL 100000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 0 0 0) }", "storage": {} }, "945304eb96065b2a98b57a48a06ae28d285a71b5" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG0 0 32) [[ 0 ]] (+ (SLOAD 0) 1) [[ 1 ]] (CALL (- (GAS) 224) (ADDRESS) 0 0 0 0 0) } ", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1106,19 +1106,19 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (CALL 100000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 0 0 0) }", "storage": {} }, "945304eb96065b2a98b57a48a06ae28d285a71b5" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 (GAS)) (LOG0 0 32) [[ 0 ]] (+ (SLOAD 0) 1) [[ 1 ]] (CALL (- (GAS) 224) (ADDRESS) 0 0 0 0 0) } ", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1146,13 +1146,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", - "nonce" : 0, + "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, + "nonce" : "0", "code" : "", "storage": {} } @@ -1180,13 +1180,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (+ (SLOAD 0) 1) [[ 1 ]] (CALL (- (GAS) 224) (ADDRESS) 0 0 0 0 0) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1214,13 +1214,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (+ (SLOAD 0) 1) [[ 1 ]] (CALL (- (GAS) 224) (ADDRESS) 0 0 0 0 0) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1248,13 +1248,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (+ (SLOAD 0) 1) [[ 1 ]] (CALL (- (GAS) 224) (ADDRESS) 0 0 0 0 0) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1282,13 +1282,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[0]] (CALLER) (SUICIDE (CALLER))}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1316,13 +1316,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[0]] (CALLER) (SUICIDE 0xaaa94f5374fce5edbc8e2a8697c15331677e6ebf0b)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1350,13 +1350,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[0]] (CALLER) (SUICIDE 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0baa)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1384,13 +1384,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[0]] (ORIGIN) (SUICIDE (ORIGIN))}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1418,13 +1418,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[0]] (ADDRESS) (SUICIDE (ADDRESS))}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1452,13 +1452,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (SUICIDE 0xaa1722f3947def4cf144679da39c4c32bdc35681 )}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1486,13 +1486,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (SUICIDE (ADDRESS) )}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1527,7 +1527,7 @@ }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1562,7 +1562,7 @@ }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1597,7 +1597,7 @@ }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1625,7 +1625,7 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALLCODE 1000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 64 64 0) }", "storage": {} }, @@ -1638,7 +1638,7 @@ }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1666,7 +1666,7 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALLCODE 1000 0xaa945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 64 64 0) }", "storage": {} }, @@ -1679,7 +1679,7 @@ }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1707,7 +1707,7 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALLCODE 1000 0x945304eb96065b2a98b57a48a06ae28d285a71b5aa 23 0 64 64 0) }", "storage": {} }, @@ -1720,7 +1720,7 @@ }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1748,7 +1748,7 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALLCODE 1000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 0 0 0) }", "storage": {} }, @@ -1761,7 +1761,7 @@ }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1789,13 +1789,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6000355415600957005b60203560003555", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1823,7 +1823,7 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ (PC) ]] (CALL 1000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 24 0 0 0 0) }", "storage": {} }, @@ -1836,7 +1836,7 @@ }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1864,7 +1864,7 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ (PC) ]] (CALL (- (GAS) 1000) 0x945304eb96065b2a98b57a48a06ae28d285a71b5 24 0 0 0 0) }", "storage": {} }, @@ -1877,7 +1877,7 @@ }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1905,7 +1905,7 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (ADD (SLOAD 0) 1) (CALL (- (GAS) 1000) 0x945304eb96065b2a98b57a48a06ae28d285a71b5 1 0 0 0 0) }", "storage": {} }, @@ -1918,7 +1918,7 @@ }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1946,7 +1946,7 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1025000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (ADD (SLOAD 0) 1) (CALL (- (GAS) 1000) 0x945304eb96065b2a98b57a48a06ae28d285a71b5 1 0 0 0 0) }", "storage": {} }, @@ -1959,7 +1959,7 @@ }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -1987,7 +1987,7 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ (PC) ]] (CALL 1000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 24 0 0 0 0) (SUICIDE 0x945304eb96065b2a98b57a48a06ae28d285a71b5) }", "storage": {} }, @@ -2000,7 +2000,7 @@ }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -2028,7 +2028,7 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ (PC) ]] (CALL 1000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 24 0 0 0 0) }", "storage": {} }, @@ -2041,7 +2041,7 @@ }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -2069,13 +2069,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[0]] (CALLVALUE) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } @@ -2103,13 +2103,13 @@ "pre": { "095e7baea6a6c7c4c2dfeb977efac326af552d87": { "balance": "1000000000000000000", - "nonce": 0, + "nonce": "0", "code": "{ [[0]] (balance (address)) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b": { "balance": "1000000000000000000", - "nonce": 0, + "nonce": "0", "code": "", "storage": {} } @@ -2137,13 +2137,13 @@ "pre": { "095e7baea6a6c7c4c2dfeb977efac326af552d87": { "balance": "1000000000000000000", - "nonce": 0, + "nonce": "0", "code": "{ [[0]] (balance (caller)) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b": { "balance": "1000000000000000000", - "nonce": 0, + "nonce": "0", "code": "", "storage": {} } diff --git a/test/stTransactionTestFiller.json b/test/stTransactionTestFiller.json index cd42af795..878aed0d1 100644 --- a/test/stTransactionTestFiller.json +++ b/test/stTransactionTestFiller.json @@ -507,4 +507,300 @@ } }, + "TransactionMakeAccountBalanceOverflow" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "100000", + "code" : "", + "nonce" : "0", + "storage" : { + } + }, + + "b94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "115792089237316195423570985008687907853269984665640564039457584007913129639935", + "code" : "", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "", + "gasLimit" : "1000", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "value" : "100" + } + }, + + "TransactionMakeAccountNonceOverflow" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "1", + "currentGasLimit" : "1000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "100000", + "code" : "", + "nonce" : "115792089237316195423570985008687907853269984665640564039457584007913129639935", + "nonce" : "10000000", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "", + "gasLimit" : "1000", + "gasPrice" : "1", + "nonce" : "115792089237316195423570985008687907853269984665640564039457584007913129639935", + "nonce" : "10000000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "value" : "100" + } + }, + + "UserTransactionZeroCost" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "3000", + "code" : "", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "", + "gasLimit" : "5100", + "gasPrice" : "0", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "value" : "900" + } + }, + + "UserTransactionGasLimitIsTooLowWhenZeroCost" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "3000", + "code" : "", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "", + "gasLimit" : "12", + "gasPrice" : "0", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "value" : "900" + } + }, + + "UserTransactionZeroCostWithData" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "3000", + "code" : "", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "0x3240349548983454", + "gasLimit" : "500", + "gasPrice" : "0", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "value" : "900" + } + }, + + "HighGasLimit" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "(2**256)-1", + "currentGasLimit" : "115792089237316195423570985008687907853269984665640564039457584007913129639935", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "115792089237316195423570985008687907853269984665640564039457584007913129639935", + "code" : "", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "0x3240349548983454", + "gasLimit" : "2**200", + "gasLimit" : "1606938044258990275541962092341162602522202993782792835301376", + "gasPrice" : "2**56-1", + "gasPrice" : "72057594037927935", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "value" : "900" + } + }, + + "OverflowGasRequire" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "(2**256)-1", + "currentGasLimit" : "115792089237316195423570985008687907853269984665640564039457584007913129639935", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "115792089237316195423570985008687907853269984665640564039457584007913129639935", + "code" : "", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "0x3240349548983454", + "gasLimit" : "2**200", + "gasLimit" : "1606938044258990275541962092341162602522202993782792835301376", + "gasPrice" : "(2**56)*10", + "gasPrice" : "720575940379279360", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "value" : "900" + } + }, + + "RefundOverflow" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "(2**256)-1", + "currentGasLimit" : "115792089237316195423570985008687907853269984665640564039457584007913129639935", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "400", + "code" : "", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "", + "gasLimit" : "(2**256+400)/20", + "gasLimit" : "5789604461865809771178549250434395392663499233282028201972879200395656482016", + "gasPrice" : "20", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "value" : "" + } + }, + + "TransactionToAddressh160minusOne" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "100000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "100000", + "code" : "", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "", + "gasLimit" : "1000", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "0xffffffffffffffffffffffffffffffffffffffff", + "value" : "100" + } + } } diff --git a/test/vmArithmeticTestFiller.json b/test/vmArithmeticTestFiller.json index 9e8b3f61c..329e2e507 100644 --- a/test/vmArithmeticTestFiller.json +++ b/test/vmArithmeticTestFiller.json @@ -5,13 +5,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x00", "storage": {} } @@ -33,13 +33,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (+ 115792089237316195423570985008687907853269984665640564039457584007913129639935 115792089237316195423570985008687907853269984665640564039457584007913129639935) }", "storage": {} } @@ -61,13 +61,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (+ 115792089237316195423570985008687907853269984665640564039457584007913129639935 4) }", "storage": {} } @@ -89,13 +89,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (+ 115792089237316195423570985008687907853269984665640564039457584007913129639936 1) }", "storage": {} } @@ -117,13 +117,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (+ 0 0) }", "storage": {} } @@ -145,13 +145,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (+ 1 115792089237316195423570985008687907853269984665640564039457584007913129639935) }", "storage": {} } @@ -174,13 +174,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (* 2 3) }", "storage": {} } @@ -203,13 +203,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (* 115792089237316195423570985008687907853269984665640564039457584007913129639935 115792089237316195423570985008687907853269984665640564039457584007913129639935) }", "storage": {} } @@ -231,13 +231,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (* 0 23) }", "storage": {} } @@ -259,13 +259,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (* 23 1) }", "storage": {} } @@ -287,13 +287,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (* 0x8000000000000000000000000000000000000000000000000000000000000000 115792089237316195423570985008687907853269984665640564039457584007913129639935) }", "storage": {} } @@ -315,13 +315,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (* 0x8000000000000000000000000000000000000000000000000000000000000000 0x8000000000000000000000000000000000000000000000000000000000000000) }", "storage": {} } @@ -343,13 +343,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (* 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) }", "storage": {} } @@ -372,13 +372,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (- 23 1) }", "storage": {} } @@ -400,13 +400,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (- 2 3) }", "storage": {} } @@ -428,13 +428,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (- 0 23) }", "storage": {} } @@ -456,13 +456,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (- 0 115792089237316195423570985008687907853269984665640564039457584007913129639935) }", "storage": {} } @@ -484,13 +484,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (- 115792089237316195423570985008687907853269984665640564039457584007913129639935 0) }", "storage": {} } @@ -512,13 +512,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (/ 2 0) }", "storage": {} } @@ -540,13 +540,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (/ 5 2) }", "storage": {} } @@ -568,13 +568,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (/ 23 24) }", "storage": {} } @@ -596,13 +596,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (/ 0 24) }", "storage": {} } @@ -624,13 +624,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (/ 1 1) }", "storage": {} } @@ -652,13 +652,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (SDIV (- 0 3) (- 0 0)) }", "storage": {} } @@ -680,13 +680,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (SDIV (- 0 115792089237316195423570985008687907853269984665640564039457584007913129639935) 0) }", "storage": {} } @@ -708,13 +708,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (SDIV (- 0 115792089237316195423570985008687907853269984665640564039457584007913129639935) 115792089237316195423570985008687907853269984665640564039457584007913129639935) }", "storage": {} } @@ -736,13 +736,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (SDIV 115792089237316195423570985008687907853269984665640564039457584007913129639935 (- 0 115792089237316195423570985008687907853269984665640564039457584007913129639935) ) }", "storage": {} } @@ -764,13 +764,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (SDIV (- 0 2) (- 0 4) ) }", "storage": {} } @@ -792,13 +792,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (SDIV 4 (- 0 2) ) }", "storage": {} } @@ -820,13 +820,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (SDIV 5 (- 0 4) ) }", "storage": {} } @@ -848,13 +848,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (SDIV (- 0 57896044618658097711785492504343953926634992332820282019728792003956564819967) (- 0 1) ) }", "storage": {} } @@ -876,13 +876,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (% 2 3 ) }", "storage": {} } @@ -904,13 +904,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (% 115792089237316195423570985008687907853269984665640564039457584007913129639935 2 ) }", "storage": {} } @@ -932,13 +932,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (% 0 115792089237316195423570985008687907853269984665640564039457584007913129639935 ) }", "storage": {} } @@ -960,13 +960,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (% 3 0) }", "storage": {} } @@ -988,13 +988,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (% (- 0 2) 3) }", "storage": {} } @@ -1016,13 +1016,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (SMOD (- 0 5) (- 0 3))}", "storage": {} } @@ -1044,13 +1044,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (SMOD 5 (- 0 3))}", "storage": {} } @@ -1072,13 +1072,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (SMOD (- 0 5) 3)}", "storage": {} } @@ -1100,13 +1100,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (SMOD (- 0 2) 115792089237316195423570985008687907853269984665640564039457584007913129639935)}", "storage": {} } @@ -1128,13 +1128,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (SMOD (- 0 2) 0)}", "storage": {} } @@ -1156,13 +1156,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (ADDMOD 1 2 2) } ", "storage": {} } @@ -1184,13 +1184,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (ADDMOD (- 0 1) (- 0 2) 2) } ", "storage": {} } @@ -1212,13 +1212,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (ADDMOD (- 0 6) 1 3) } ", "storage": {} } @@ -1240,13 +1240,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EQ (SMOD (- 0 5) 3) (ADDMOD (- 0 6) 1 3) ) } ", "storage": {} } @@ -1268,13 +1268,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{[[ 0 ]] (EQ (MOD (- 0 5) 3) (ADDMOD (- 0 6) 1 3) ) }", "storage": {} } @@ -1296,13 +1296,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (ADDMOD 4 1 (- 0 3) )} ", "storage": {} } @@ -1324,13 +1324,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EQ (ADDMOD 4 1 (- 0 3) ) 2 ) } ", "storage": {} } @@ -1352,13 +1352,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (ADDMOD 4 1 0) } ", "storage": {} } @@ -1380,13 +1380,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (ADDMOD 0 1 0) } ", "storage": {} } @@ -1408,13 +1408,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (ADDMOD 1 0 0) } ", "storage": {} } @@ -1437,13 +1437,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (MULMOD 1 2 2) } ", "storage": {} } @@ -1465,13 +1465,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (MULMOD (- 0 1) (- 0 2) 3) } ", "storage": {} } @@ -1493,13 +1493,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (MULMOD (- 0 5) 1 3) } ", "storage": {} } @@ -1521,13 +1521,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EQ (SMOD (- 0 5) 3) (MULMOD (- 0 5) 1 3) ) } ", "storage": {} } @@ -1549,13 +1549,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{[[ 0 ]] (EQ (MOD (- 0 5) 3) (MULMOD (- 0 5) 1 3) ) }", "storage": {} } @@ -1577,13 +1577,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (MULMOD 5 1 (- 0 3) )} ", "storage": {} } @@ -1605,13 +1605,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EQ (MULMOD 5 1 (- 0 3) ) 2 )} ", "storage": {} } @@ -1633,13 +1633,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (MULMOD 5 1 0) } ", "storage": {} } @@ -1661,13 +1661,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (MULMOD 0 1 0) } ", "storage": {} } @@ -1689,13 +1689,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (MULMOD 1 0 0) } ", "storage": {} } @@ -1718,13 +1718,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 2 2)}", "storage": {} } @@ -1746,13 +1746,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 115792089237316195423570985008687907853269984665640564039457584007913129639935 115792089237316195423570985008687907853269984665640564039457584007913129639934 )}", "storage": {} } @@ -1774,13 +1774,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 2147483647 2147483647)}", "storage": {} } @@ -1802,13 +1802,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 0 2147483647)}", "storage": {} } @@ -1830,13 +1830,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 2147483647 0)}", "storage": {} } @@ -1858,13 +1858,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 257 1)}", "storage": {} } @@ -1886,13 +1886,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 1 257)}", "storage": {} } @@ -1914,13 +1914,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 2 257)}", "storage": {} } @@ -1942,13 +1942,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 2 2) [[ 1 ]] (EXP 2 1) [[ 2 ]] (EXP 2 3) }", "storage": {} } @@ -1970,13 +1970,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 2 4) [[ 1 ]] (EXP 2 3) [[ 2 ]] (EXP 2 5) }", "storage": {} } @@ -1998,13 +1998,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 2 8) [[ 1 ]] (EXP 2 7) [[ 2 ]] (EXP 2 9) }", "storage": {} } @@ -2026,13 +2026,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 2 16) [[ 1 ]] (EXP 2 15) [[ 2 ]] (EXP 2 17) }", "storage": {} } @@ -2054,13 +2054,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 2 32) [[ 1 ]] (EXP 2 31) [[ 2 ]] (EXP 2 33) }", "storage": {} } @@ -2082,13 +2082,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 2 64) [[ 1 ]] (EXP 2 63) [[ 2 ]] (EXP 2 65) }", "storage": {} } @@ -2110,13 +2110,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 2 128) [[ 1 ]] (EXP 2 127) [[ 2 ]] (EXP 2 129) }", "storage": {} } @@ -2138,13 +2138,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 2 256) [[ 1 ]] (EXP 2 255) [[ 2 ]] (EXP 2 257) }", "storage": {} } @@ -2166,13 +2166,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 1) [[ 1 ]] (EXP 255 1) [[ 2 ]] (EXP 257 1) }", "storage": {} } @@ -2194,13 +2194,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 2) [[ 1 ]] (EXP 255 2) [[ 2 ]] (EXP 257 2) }", "storage": {} } @@ -2222,13 +2222,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 3) [[ 1 ]] (EXP 255 3) [[ 2 ]] (EXP 257 3) }", "storage": {} } @@ -2250,13 +2250,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 4) [[ 1 ]] (EXP 255 4) [[ 2 ]] (EXP 257 4) }", "storage": {} } @@ -2278,13 +2278,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 5) [[ 1 ]] (EXP 255 5) [[ 2 ]] (EXP 257 5) }", "storage": {} } @@ -2306,13 +2306,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 6) [[ 1 ]] (EXP 255 6) [[ 2 ]] (EXP 257 6) }", "storage": {} } @@ -2334,13 +2334,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 7) [[ 1 ]] (EXP 255 7) [[ 2 ]] (EXP 257 7) }", "storage": {} } @@ -2362,13 +2362,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 8) [[ 1 ]] (EXP 255 8) [[ 2 ]] (EXP 257 8) }", "storage": {} } @@ -2390,13 +2390,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 9) [[ 1 ]] (EXP 255 9) [[ 2 ]] (EXP 257 9) }", "storage": {} } @@ -2418,13 +2418,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 10) [[ 1 ]] (EXP 255 10) [[ 2 ]] (EXP 257 10) }", "storage": {} } @@ -2446,13 +2446,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 11) [[ 1 ]] (EXP 255 11) [[ 2 ]] (EXP 257 11) }", "storage": {} } @@ -2474,13 +2474,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 12) [[ 1 ]] (EXP 255 12) [[ 2 ]] (EXP 257 12) }", "storage": {} } @@ -2502,13 +2502,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 13) [[ 1 ]] (EXP 255 13) [[ 2 ]] (EXP 257 13) }", "storage": {} } @@ -2530,13 +2530,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 14) [[ 1 ]] (EXP 255 14) [[ 2 ]] (EXP 257 14) }", "storage": {} } @@ -2558,13 +2558,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 15) [[ 1 ]] (EXP 255 15) [[ 2 ]] (EXP 257 15) }", "storage": {} } @@ -2586,13 +2586,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 16) [[ 1 ]] (EXP 255 16) [[ 2 ]] (EXP 257 16) }", "storage": {} } @@ -2614,13 +2614,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 17) [[ 1 ]] (EXP 255 17) [[ 2 ]] (EXP 257 17) }", "storage": {} } @@ -2642,13 +2642,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 18) [[ 1 ]] (EXP 255 18) [[ 2 ]] (EXP 257 18) }", "storage": {} } @@ -2670,13 +2670,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 19) [[ 1 ]] (EXP 255 19) [[ 2 ]] (EXP 257 19) }", "storage": {} } @@ -2698,13 +2698,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 20) [[ 1 ]] (EXP 255 20) [[ 2 ]] (EXP 257 20) }", "storage": {} } @@ -2726,13 +2726,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 21) [[ 1 ]] (EXP 255 21) [[ 2 ]] (EXP 257 21) }", "storage": {} } @@ -2754,13 +2754,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 22) [[ 1 ]] (EXP 255 22) [[ 2 ]] (EXP 257 22) }", "storage": {} } @@ -2782,13 +2782,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 23) [[ 1 ]] (EXP 255 23) [[ 2 ]] (EXP 257 23) }", "storage": {} } @@ -2810,13 +2810,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 24) [[ 1 ]] (EXP 255 24) [[ 2 ]] (EXP 257 24) }", "storage": {} } @@ -2838,13 +2838,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 25) [[ 1 ]] (EXP 255 25) [[ 2 ]] (EXP 257 25) }", "storage": {} } @@ -2866,13 +2866,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 26) [[ 1 ]] (EXP 255 26) [[ 2 ]] (EXP 257 26) }", "storage": {} } @@ -2894,13 +2894,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 27) [[ 1 ]] (EXP 255 27) [[ 2 ]] (EXP 257 27) }", "storage": {} } @@ -2922,13 +2922,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 28) [[ 1 ]] (EXP 255 28) [[ 2 ]] (EXP 257 28) }", "storage": {} } @@ -2950,13 +2950,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 29) [[ 1 ]] (EXP 255 29) [[ 2 ]] (EXP 257 29) }", "storage": {} } @@ -2978,13 +2978,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 30) [[ 1 ]] (EXP 255 30) [[ 2 ]] (EXP 257 30) }", "storage": {} } @@ -3006,13 +3006,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 31) [[ 1 ]] (EXP 255 31) [[ 2 ]] (EXP 257 31) }", "storage": {} } @@ -3034,13 +3034,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 32) [[ 1 ]] (EXP 255 32) [[ 2 ]] (EXP 257 32) }", "storage": {} } @@ -3062,13 +3062,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 33) [[ 1 ]] (EXP 255 33) [[ 2 ]] (EXP 257 33) }", "storage": {} } @@ -3090,13 +3090,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 (EXP 256 0)) [[ 1 ]] (EXP 256 (EXP 255 0)) [[ 2 ]] (EXP 256 (EXP 257 0)) [[ 3 ]] (EXP 255 (EXP 256 0)) [[ 4 ]] (EXP 255 (EXP 255 0)) [[ 5 ]] (EXP 255 (EXP 257 0)) [[ 6 ]] (EXP 257 (EXP 256 0)) [[ 7 ]] (EXP 257 (EXP 255 0)) [[ 8 ]] (EXP 257 (EXP 257 0)) }", "storage": {} } @@ -3118,13 +3118,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 (EXP 256 1)) [[ 1 ]] (EXP 256 (EXP 255 1)) [[ 2 ]] (EXP 256 (EXP 257 1)) [[ 3 ]] (EXP 255 (EXP 256 1)) [[ 4 ]] (EXP 255 (EXP 255 1)) [[ 5 ]] (EXP 255 (EXP 257 1)) [[ 6 ]] (EXP 257 (EXP 256 1)) [[ 7 ]] (EXP 257 (EXP 255 1)) [[ 8 ]] (EXP 257 (EXP 257 1)) }", "storage": {} } @@ -3146,13 +3146,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 (EXP 256 2)) [[ 1 ]] (EXP 256 (EXP 255 2)) [[ 2 ]] (EXP 256 (EXP 257 2)) [[ 3 ]] (EXP 255 (EXP 256 2)) [[ 4 ]] (EXP 255 (EXP 255 2)) [[ 5 ]] (EXP 255 (EXP 257 2)) [[ 6 ]] (EXP 257 (EXP 256 2)) [[ 7 ]] (EXP 257 (EXP 255 2)) [[ 8 ]] (EXP 257 (EXP 257 2)) }", "storage": {} } @@ -3174,13 +3174,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 (EXP 256 3)) [[ 1 ]] (EXP 256 (EXP 255 3)) [[ 2 ]] (EXP 256 (EXP 257 3)) [[ 3 ]] (EXP 255 (EXP 256 3)) [[ 4 ]] (EXP 255 (EXP 255 3)) [[ 5 ]] (EXP 255 (EXP 257 3)) [[ 6 ]] (EXP 257 (EXP 256 3)) [[ 7 ]] (EXP 257 (EXP 255 3)) [[ 8 ]] (EXP 257 (EXP 257 3)) }", "storage": {} } @@ -3202,13 +3202,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 (EXP 256 4)) [[ 1 ]] (EXP 256 (EXP 255 4)) [[ 2 ]] (EXP 256 (EXP 257 4)) [[ 3 ]] (EXP 255 (EXP 256 4)) [[ 4 ]] (EXP 255 (EXP 255 4)) [[ 5 ]] (EXP 255 (EXP 257 4)) [[ 6 ]] (EXP 257 (EXP 256 4)) [[ 7 ]] (EXP 257 (EXP 255 4)) [[ 8 ]] (EXP 257 (EXP 257 4)) }", "storage": {} } @@ -3230,13 +3230,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 (EXP 256 5)) [[ 1 ]] (EXP 256 (EXP 255 5)) [[ 2 ]] (EXP 256 (EXP 257 5)) [[ 3 ]] (EXP 255 (EXP 256 5)) [[ 4 ]] (EXP 255 (EXP 255 5)) [[ 5 ]] (EXP 255 (EXP 257 5)) [[ 6 ]] (EXP 257 (EXP 256 5)) [[ 7 ]] (EXP 257 (EXP 255 5)) [[ 8 ]] (EXP 257 (EXP 257 5)) }", "storage": {} } @@ -3258,13 +3258,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 (EXP 256 6)) [[ 1 ]] (EXP 256 (EXP 255 6)) [[ 2 ]] (EXP 256 (EXP 257 6)) [[ 3 ]] (EXP 255 (EXP 256 6)) [[ 4 ]] (EXP 255 (EXP 255 6)) [[ 5 ]] (EXP 255 (EXP 257 6)) [[ 6 ]] (EXP 257 (EXP 256 6)) [[ 7 ]] (EXP 257 (EXP 255 6)) [[ 8 ]] (EXP 257 (EXP 257 6)) }", "storage": {} } @@ -3286,13 +3286,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 (EXP 256 7)) [[ 1 ]] (EXP 256 (EXP 255 7)) [[ 2 ]] (EXP 256 (EXP 257 7)) [[ 3 ]] (EXP 255 (EXP 256 7)) [[ 4 ]] (EXP 255 (EXP 255 7)) [[ 5 ]] (EXP 255 (EXP 257 7)) [[ 6 ]] (EXP 257 (EXP 256 7)) [[ 7 ]] (EXP 257 (EXP 255 7)) [[ 8 ]] (EXP 257 (EXP 257 7)) }", "storage": {} } @@ -3314,13 +3314,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 (EXP 256 8)) [[ 1 ]] (EXP 256 (EXP 255 8)) [[ 2 ]] (EXP 256 (EXP 257 8)) [[ 3 ]] (EXP 255 (EXP 256 8)) [[ 4 ]] (EXP 255 (EXP 255 8)) [[ 5 ]] (EXP 255 (EXP 257 8)) [[ 6 ]] (EXP 257 (EXP 256 8)) [[ 7 ]] (EXP 257 (EXP 255 8)) [[ 8 ]] (EXP 257 (EXP 257 8)) }", "storage": {} } @@ -3342,13 +3342,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 (EXP 256 9)) [[ 1 ]] (EXP 256 (EXP 255 9)) [[ 2 ]] (EXP 256 (EXP 257 9)) [[ 3 ]] (EXP 255 (EXP 256 9)) [[ 4 ]] (EXP 255 (EXP 255 9)) [[ 5 ]] (EXP 255 (EXP 257 9)) [[ 6 ]] (EXP 257 (EXP 256 9)) [[ 7 ]] (EXP 257 (EXP 255 9)) [[ 8 ]] (EXP 257 (EXP 257 9)) }", "storage": {} } @@ -3370,13 +3370,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 (EXP 256 10)) [[ 1 ]] (EXP 256 (EXP 255 10)) [[ 2 ]] (EXP 256 (EXP 257 10)) [[ 3 ]] (EXP 255 (EXP 256 10)) [[ 4 ]] (EXP 255 (EXP 255 10)) [[ 5 ]] (EXP 255 (EXP 257 10)) [[ 6 ]] (EXP 257 (EXP 256 10)) [[ 7 ]] (EXP 257 (EXP 255 10)) [[ 8 ]] (EXP 257 (EXP 257 10)) }", "storage": {} } @@ -3398,13 +3398,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 (EXP 256 11)) [[ 1 ]] (EXP 256 (EXP 255 11)) [[ 2 ]] (EXP 256 (EXP 257 11)) [[ 3 ]] (EXP 255 (EXP 256 11)) [[ 4 ]] (EXP 255 (EXP 255 11)) [[ 5 ]] (EXP 255 (EXP 257 11)) [[ 6 ]] (EXP 257 (EXP 256 11)) [[ 7 ]] (EXP 257 (EXP 255 11)) [[ 8 ]] (EXP 257 (EXP 257 11)) }", "storage": {} } @@ -3426,13 +3426,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 (EXP 256 12)) [[ 1 ]] (EXP 256 (EXP 255 12)) [[ 2 ]] (EXP 256 (EXP 257 12)) [[ 3 ]] (EXP 255 (EXP 256 12)) [[ 4 ]] (EXP 255 (EXP 255 12)) [[ 5 ]] (EXP 255 (EXP 257 12)) [[ 6 ]] (EXP 257 (EXP 256 12)) [[ 7 ]] (EXP 257 (EXP 255 12)) [[ 8 ]] (EXP 257 (EXP 257 12)) }", "storage": {} } @@ -3454,13 +3454,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 (EXP 256 13)) [[ 1 ]] (EXP 256 (EXP 255 13)) [[ 2 ]] (EXP 256 (EXP 257 13)) [[ 3 ]] (EXP 255 (EXP 256 13)) [[ 4 ]] (EXP 255 (EXP 255 13)) [[ 5 ]] (EXP 255 (EXP 257 13)) [[ 6 ]] (EXP 257 (EXP 256 13)) [[ 7 ]] (EXP 257 (EXP 255 13)) [[ 8 ]] (EXP 257 (EXP 257 13)) }", "storage": {} } @@ -3482,13 +3482,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 (EXP 256 14)) [[ 1 ]] (EXP 256 (EXP 255 14)) [[ 2 ]] (EXP 256 (EXP 257 14)) [[ 3 ]] (EXP 255 (EXP 256 14)) [[ 4 ]] (EXP 255 (EXP 255 14)) [[ 5 ]] (EXP 255 (EXP 257 14)) [[ 6 ]] (EXP 257 (EXP 256 14)) [[ 7 ]] (EXP 257 (EXP 255 14)) [[ 8 ]] (EXP 257 (EXP 257 14)) }", "storage": {} } @@ -3510,13 +3510,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 (EXP 256 15)) [[ 1 ]] (EXP 256 (EXP 255 15)) [[ 2 ]] (EXP 256 (EXP 257 15)) [[ 3 ]] (EXP 255 (EXP 256 15)) [[ 4 ]] (EXP 255 (EXP 255 15)) [[ 5 ]] (EXP 255 (EXP 257 15)) [[ 6 ]] (EXP 257 (EXP 256 15)) [[ 7 ]] (EXP 257 (EXP 255 15)) [[ 8 ]] (EXP 257 (EXP 257 15)) }", "storage": {} } @@ -3538,13 +3538,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 (EXP 256 16)) [[ 1 ]] (EXP 256 (EXP 255 16)) [[ 2 ]] (EXP 256 (EXP 257 16)) [[ 3 ]] (EXP 255 (EXP 256 16)) [[ 4 ]] (EXP 255 (EXP 255 16)) [[ 5 ]] (EXP 255 (EXP 257 16)) [[ 6 ]] (EXP 257 (EXP 256 16)) [[ 7 ]] (EXP 257 (EXP 255 16)) [[ 8 ]] (EXP 257 (EXP 257 16)) }", "storage": {} } @@ -3566,13 +3566,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 (EXP 256 17)) [[ 1 ]] (EXP 256 (EXP 255 17)) [[ 2 ]] (EXP 256 (EXP 257 17)) [[ 3 ]] (EXP 255 (EXP 256 17)) [[ 4 ]] (EXP 255 (EXP 255 17)) [[ 5 ]] (EXP 255 (EXP 257 17)) [[ 6 ]] (EXP 257 (EXP 256 17)) [[ 7 ]] (EXP 257 (EXP 255 17)) [[ 8 ]] (EXP 257 (EXP 257 17)) }", "storage": {} } @@ -3594,13 +3594,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 (EXP 256 18)) [[ 1 ]] (EXP 256 (EXP 255 18)) [[ 2 ]] (EXP 256 (EXP 257 18)) [[ 3 ]] (EXP 255 (EXP 256 18)) [[ 4 ]] (EXP 255 (EXP 255 18)) [[ 5 ]] (EXP 255 (EXP 257 18)) [[ 6 ]] (EXP 257 (EXP 256 18)) [[ 7 ]] (EXP 257 (EXP 255 18)) [[ 8 ]] (EXP 257 (EXP 257 18)) }", "storage": {} } @@ -3622,13 +3622,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 (EXP 256 19)) [[ 1 ]] (EXP 256 (EXP 255 19)) [[ 2 ]] (EXP 256 (EXP 257 19)) [[ 3 ]] (EXP 255 (EXP 256 19)) [[ 4 ]] (EXP 255 (EXP 255 19)) [[ 5 ]] (EXP 255 (EXP 257 19)) [[ 6 ]] (EXP 257 (EXP 256 19)) [[ 7 ]] (EXP 257 (EXP 255 19)) [[ 8 ]] (EXP 257 (EXP 257 19)) }", "storage": {} } @@ -3650,13 +3650,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 (EXP 256 20)) [[ 1 ]] (EXP 256 (EXP 255 20)) [[ 2 ]] (EXP 256 (EXP 257 20)) [[ 3 ]] (EXP 255 (EXP 256 20)) [[ 4 ]] (EXP 255 (EXP 255 20)) [[ 5 ]] (EXP 255 (EXP 257 20)) [[ 6 ]] (EXP 257 (EXP 256 20)) [[ 7 ]] (EXP 257 (EXP 255 20)) [[ 8 ]] (EXP 257 (EXP 257 20)) }", "storage": {} } @@ -3678,13 +3678,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 (EXP 256 21)) [[ 1 ]] (EXP 256 (EXP 255 21)) [[ 2 ]] (EXP 256 (EXP 257 21)) [[ 3 ]] (EXP 255 (EXP 256 21)) [[ 4 ]] (EXP 255 (EXP 255 21)) [[ 5 ]] (EXP 255 (EXP 257 21)) [[ 6 ]] (EXP 257 (EXP 256 21)) [[ 7 ]] (EXP 257 (EXP 255 21)) [[ 8 ]] (EXP 257 (EXP 257 21)) }", "storage": {} } @@ -3706,13 +3706,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 (EXP 256 22)) [[ 1 ]] (EXP 256 (EXP 255 22)) [[ 2 ]] (EXP 256 (EXP 257 22)) [[ 3 ]] (EXP 255 (EXP 256 22)) [[ 4 ]] (EXP 255 (EXP 255 22)) [[ 5 ]] (EXP 255 (EXP 257 22)) [[ 6 ]] (EXP 257 (EXP 256 22)) [[ 7 ]] (EXP 257 (EXP 255 22)) [[ 8 ]] (EXP 257 (EXP 257 22)) }", "storage": {} } @@ -3734,13 +3734,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 (EXP 256 23)) [[ 1 ]] (EXP 256 (EXP 255 23)) [[ 2 ]] (EXP 256 (EXP 257 23)) [[ 3 ]] (EXP 255 (EXP 256 23)) [[ 4 ]] (EXP 255 (EXP 255 23)) [[ 5 ]] (EXP 255 (EXP 257 23)) [[ 6 ]] (EXP 257 (EXP 256 23)) [[ 7 ]] (EXP 257 (EXP 255 23)) [[ 8 ]] (EXP 257 (EXP 257 23)) }", "storage": {} } @@ -3762,13 +3762,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 (EXP 256 24)) [[ 1 ]] (EXP 256 (EXP 255 24)) [[ 2 ]] (EXP 256 (EXP 257 24)) [[ 3 ]] (EXP 255 (EXP 256 24)) [[ 4 ]] (EXP 255 (EXP 255 24)) [[ 5 ]] (EXP 255 (EXP 257 24)) [[ 6 ]] (EXP 257 (EXP 256 24)) [[ 7 ]] (EXP 257 (EXP 255 24)) [[ 8 ]] (EXP 257 (EXP 257 24)) }", "storage": {} } @@ -3790,13 +3790,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 (EXP 256 25)) [[ 1 ]] (EXP 256 (EXP 255 25)) [[ 2 ]] (EXP 256 (EXP 257 25)) [[ 3 ]] (EXP 255 (EXP 256 25)) [[ 4 ]] (EXP 255 (EXP 255 25)) [[ 5 ]] (EXP 255 (EXP 257 25)) [[ 6 ]] (EXP 257 (EXP 256 25)) [[ 7 ]] (EXP 257 (EXP 255 25)) [[ 8 ]] (EXP 257 (EXP 257 25)) }", "storage": {} } @@ -3818,13 +3818,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 (EXP 256 26)) [[ 1 ]] (EXP 256 (EXP 255 26)) [[ 2 ]] (EXP 256 (EXP 257 26)) [[ 3 ]] (EXP 255 (EXP 256 26)) [[ 4 ]] (EXP 255 (EXP 255 26)) [[ 5 ]] (EXP 255 (EXP 257 26)) [[ 6 ]] (EXP 257 (EXP 256 26)) [[ 7 ]] (EXP 257 (EXP 255 26)) [[ 8 ]] (EXP 257 (EXP 257 26)) }", "storage": {} } @@ -3846,13 +3846,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 (EXP 256 27)) [[ 1 ]] (EXP 256 (EXP 255 27)) [[ 2 ]] (EXP 256 (EXP 257 27)) [[ 3 ]] (EXP 255 (EXP 256 27)) [[ 4 ]] (EXP 255 (EXP 255 27)) [[ 5 ]] (EXP 255 (EXP 257 27)) [[ 6 ]] (EXP 257 (EXP 256 27)) [[ 7 ]] (EXP 257 (EXP 255 27)) [[ 8 ]] (EXP 257 (EXP 257 27)) }", "storage": {} } @@ -3874,13 +3874,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 (EXP 256 28)) [[ 1 ]] (EXP 256 (EXP 255 28)) [[ 2 ]] (EXP 256 (EXP 257 28)) [[ 3 ]] (EXP 255 (EXP 256 28)) [[ 4 ]] (EXP 255 (EXP 255 28)) [[ 5 ]] (EXP 255 (EXP 257 28)) [[ 6 ]] (EXP 257 (EXP 256 28)) [[ 7 ]] (EXP 257 (EXP 255 28)) [[ 8 ]] (EXP 257 (EXP 257 28)) }", "storage": {} } @@ -3902,13 +3902,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 (EXP 256 29)) [[ 1 ]] (EXP 256 (EXP 255 29)) [[ 2 ]] (EXP 256 (EXP 257 29)) [[ 3 ]] (EXP 255 (EXP 256 29)) [[ 4 ]] (EXP 255 (EXP 255 29)) [[ 5 ]] (EXP 255 (EXP 257 29)) [[ 6 ]] (EXP 257 (EXP 256 29)) [[ 7 ]] (EXP 257 (EXP 255 29)) [[ 8 ]] (EXP 257 (EXP 257 29)) }", "storage": {} } @@ -3930,13 +3930,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 (EXP 256 30)) [[ 1 ]] (EXP 256 (EXP 255 30)) [[ 2 ]] (EXP 256 (EXP 257 30)) [[ 3 ]] (EXP 255 (EXP 256 30)) [[ 4 ]] (EXP 255 (EXP 255 30)) [[ 5 ]] (EXP 255 (EXP 257 30)) [[ 6 ]] (EXP 257 (EXP 256 30)) [[ 7 ]] (EXP 257 (EXP 255 30)) [[ 8 ]] (EXP 257 (EXP 257 30)) }", "storage": {} } @@ -3958,13 +3958,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 (EXP 256 31)) [[ 1 ]] (EXP 256 (EXP 255 31)) [[ 2 ]] (EXP 256 (EXP 257 31)) [[ 3 ]] (EXP 255 (EXP 256 31)) [[ 4 ]] (EXP 255 (EXP 255 31)) [[ 5 ]] (EXP 255 (EXP 257 31)) [[ 6 ]] (EXP 257 (EXP 256 31)) [[ 7 ]] (EXP 257 (EXP 255 31)) [[ 8 ]] (EXP 257 (EXP 257 31)) }", "storage": {} } @@ -3986,13 +3986,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 (EXP 256 32)) [[ 1 ]] (EXP 256 (EXP 255 32)) [[ 2 ]] (EXP 256 (EXP 257 32)) [[ 3 ]] (EXP 255 (EXP 256 32)) [[ 4 ]] (EXP 255 (EXP 255 32)) [[ 5 ]] (EXP 255 (EXP 257 32)) [[ 6 ]] (EXP 257 (EXP 256 32)) [[ 7 ]] (EXP 257 (EXP 255 32)) [[ 8 ]] (EXP 257 (EXP 257 32)) }", "storage": {} } @@ -4014,13 +4014,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXP 256 (EXP 256 33)) [[ 1 ]] (EXP 256 (EXP 255 33)) [[ 2 ]] (EXP 256 (EXP 257 33)) [[ 3 ]] (EXP 255 (EXP 256 33)) [[ 4 ]] (EXP 255 (EXP 255 33)) [[ 5 ]] (EXP 255 (EXP 257 33)) [[ 6 ]] (EXP 257 (EXP 256 33)) [[ 7 ]] (EXP 257 (EXP 255 33)) [[ 8 ]] (EXP 257 (EXP 257 33)) }", "storage": {} } @@ -4042,13 +4042,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x62122ff460000b600055", "storage": {} } @@ -4070,13 +4070,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x62122f6a60000b600055", "storage": {} } @@ -4098,13 +4098,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6212faf460010b600055", "storage": {} } @@ -4126,13 +4126,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x62126af460010b600055", "storage": {} } @@ -4154,13 +4154,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x62126af460500b600055", "storage": {} } @@ -4182,13 +4182,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (SIGNEXTEND 0 0) } ", "storage": {} } @@ -4210,13 +4210,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (SIGNEXTEND 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0) } ", "storage": {} } @@ -4238,13 +4238,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (SIGNEXTEND 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) } ", "storage": {} } @@ -4266,13 +4266,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (SIGNEXTEND 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) } ", "storage": {} } @@ -4294,13 +4294,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (SIGNEXTEND 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) } ", "storage": {} } @@ -4322,13 +4322,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x66f000000000000161ffff0b600055", "storage": {} } @@ -4350,13 +4350,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x60ff68f000000000000000010b600055", "storage": {} } diff --git a/test/vmBitwiseLogicOperationTestFiller.json b/test/vmBitwiseLogicOperationTestFiller.json index d0956e261..8954dca1e 100644 --- a/test/vmBitwiseLogicOperationTestFiller.json +++ b/test/vmBitwiseLogicOperationTestFiller.json @@ -5,13 +5,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (LT (- 0 2) 0 )}", "storage": {} } @@ -33,13 +33,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (LT 0 (- 0 2) )}", "storage": {} } @@ -61,13 +61,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (LT 115792089237316195423570985008687907853269984665640564039457584007913129639935 0 )}", "storage": {} } @@ -90,13 +90,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (LT 0 115792089237316195423570985008687907853269984665640564039457584007913129639935 )}", "storage": {} } @@ -118,13 +118,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] ( GT (- 0 2) 0 )}", "storage": {} } @@ -146,13 +146,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (GT 0 (- 0 2) )}", "storage": {} } @@ -174,13 +174,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (GT 115792089237316195423570985008687907853269984665640564039457584007913129639935 0 )}", "storage": {} } @@ -203,13 +203,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (GT 0 115792089237316195423570985008687907853269984665640564039457584007913129639935 )}", "storage": {} } @@ -231,13 +231,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (SLT (- 0 2) 0 )}", "storage": {} } @@ -259,13 +259,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (SLT 0 (- 0 2) )}", "storage": {} } @@ -287,13 +287,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (SLT 115792089237316195423570985008687907853269984665640564039457584007913129639935 0 )}", "storage": {} } @@ -316,13 +316,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (SLT 0 115792089237316195423570985008687907853269984665640564039457584007913129639935 )}", "storage": {} } @@ -344,13 +344,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (SLT (- 0 5) (- 0 3) )}", "storage": {} } @@ -372,13 +372,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (SGT (- 0 2) 0 )}", "storage": {} } @@ -400,13 +400,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (SGT 0 (- 0 2) )}", "storage": {} } @@ -428,13 +428,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (SGT 115792089237316195423570985008687907853269984665640564039457584007913129639935 0 )}", "storage": {} } @@ -457,13 +457,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (SGT 0 115792089237316195423570985008687907853269984665640564039457584007913129639935 )}", "storage": {} } @@ -485,13 +485,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (SGT (- 0 5) (- 0 3) )}", "storage": {} } @@ -513,13 +513,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EQ (- 0 5) (- 0 3) )}", "storage": {} } @@ -541,13 +541,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EQ 0 0)}", "storage": {} } @@ -569,13 +569,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EQ 115792089237316195423570985008687907853269984665640564039457584007913129639935 115792089237316195423570985008687907853269984665640564039457584007913129639935 )}", "storage": {} } @@ -597,13 +597,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (ISZERO 115792089237316195423570985008687907853269984665640564039457584007913129639935 )}", "storage": {} } @@ -625,13 +625,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (ISZERO 0 )}", "storage": {} } @@ -652,13 +652,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (ISZERO (- 0 2) )}", "storage": {} } @@ -680,13 +680,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (AND 2 2) }", "storage": {} } @@ -708,13 +708,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (AND 2 1) }", "storage": {} } @@ -736,13 +736,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (AND 3 1) }", "storage": {} } @@ -763,13 +763,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (AND 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef) } ", "storage": {} } @@ -790,13 +790,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (AND 0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) } ", "storage": {} } @@ -818,13 +818,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (AND 0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeefeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) } ", "storage": {} } @@ -846,13 +846,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (OR 2 2) } ", "storage": {} } @@ -874,13 +874,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (OR 2 1) } ", "storage": {} } @@ -902,13 +902,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (OR 3 1) } ", "storage": {} } @@ -929,13 +929,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (OR 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef) } ", "storage": {} } @@ -956,13 +956,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (OR 0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) } ", "storage": {} } @@ -984,13 +984,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (OR 0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeefeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) } ", "storage": {} } @@ -1012,13 +1012,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (XOR 2 2) } ", "storage": {} } @@ -1040,13 +1040,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (XOR 2 1) } ", "storage": {} } @@ -1068,13 +1068,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (XOR 3 1) } ", "storage": {} } @@ -1095,13 +1095,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (XOR 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef) } ", "storage": {} } @@ -1122,13 +1122,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (XOR 0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) } ", "storage": {} } @@ -1150,13 +1150,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (XOR 0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeefeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) } ", "storage": {} } @@ -1178,13 +1178,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (NOT 0 )}", "storage": {} } @@ -1206,13 +1206,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (NOT 2 )}", "storage": {} } @@ -1234,13 +1234,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (NOT 115792089237316195423570985008687907853269984665640564039457584007913129639935 )}", "storage": {} } @@ -1262,13 +1262,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (NOT (- 0 2) )}", "storage": {} } @@ -1290,13 +1290,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (NOT (- 0 115792089237316195423570985008687907853269984665640564039457584007913129639935) )}", "storage": {} } @@ -1318,13 +1318,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (NOT (- 0 0) )}", "storage": {} } @@ -1346,13 +1346,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (BYTE (- 31 0) 0x8040201008040201 ) } ", "storage": {} } @@ -1373,13 +1373,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (BYTE (- 31 1) 0x8040201008040201 ) } ", "storage": {} } @@ -1400,13 +1400,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (BYTE (- 31 2) 0x8040201008040201 ) } ", "storage": {} } @@ -1428,13 +1428,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (BYTE (- 31 3) 0x8040201008040201 ) } ", "storage": {} } @@ -1456,13 +1456,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (BYTE (- 31 4) 0x8040201008040201 ) } ", "storage": {} } @@ -1484,13 +1484,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (BYTE (- 31 5) 0x8040201008040201 ) } ", "storage": {} } @@ -1513,13 +1513,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (BYTE (- 31 6) 0x8040201008040201 ) } ", "storage": {} } @@ -1541,13 +1541,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (BYTE (- 31 7) 0x8040201008040201 ) } ", "storage": {} } @@ -1570,13 +1570,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (BYTE (- 31 31) 0x8040201008040201 ) } ", "storage": {} } @@ -1598,13 +1598,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (BYTE (SDIV 31 32) 0x8040201008040201 ) } ", "storage": {} } @@ -1626,13 +1626,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (BYTE 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0x8040201008040201 ) } ", "storage": {} } @@ -1654,13 +1654,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (BYTE 0 0x8040201008040201) } ", "storage": {} } diff --git a/test/vmBlockInfoTestFiller.json b/test/vmBlockInfoTestFiller.json index 898629477..04cbec51c 100644 --- a/test/vmBlockInfoTestFiller.json +++ b/test/vmBlockInfoTestFiller.json @@ -5,13 +5,13 @@ "currentNumber" : "1", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (BLOCKHASH 2) }", "storage": {} } @@ -33,13 +33,13 @@ "currentNumber" : "1", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (BLOCKHASH 1) }", "storage": {} } @@ -61,13 +61,13 @@ "currentNumber" : "258", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (BLOCKHASH 1) }", "storage": {} } @@ -89,13 +89,13 @@ "currentNumber" : "257", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (BLOCKHASH 0) }", "storage": {} } @@ -117,13 +117,13 @@ "currentNumber" : "257", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (BLOCKHASH 1) [[ 1 ]] (BLOCKHASH 2) [[ 2 ]] (BLOCKHASH 256) }", "storage": {} } @@ -145,13 +145,13 @@ "currentNumber" : "257", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (BLOCKHASH 0) [[ 1 ]] (BLOCKHASH 257) [[ 2 ]] (BLOCKHASH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) }", "storage": {} } @@ -173,13 +173,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (COINBASE) }", "storage": {} } @@ -201,13 +201,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (TIMESTAMP) }", "storage": {} } @@ -229,13 +229,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (NUMBER) }", "storage": {} } @@ -257,13 +257,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (DIFFICULTY) }", "storage": {} } @@ -285,13 +285,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (GASLIMIT) }", "storage": {} } diff --git a/test/vmEnvironmentalInfoTestFiller.json b/test/vmEnvironmentalInfoTestFiller.json index 43f4706cb..bca2c387a 100644 --- a/test/vmEnvironmentalInfoTestFiller.json +++ b/test/vmEnvironmentalInfoTestFiller.json @@ -5,13 +5,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (ADDRESS)}", "storage": {} } @@ -33,13 +33,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "cd1722f3947def4cf144679da39c4c32bdc35681" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (ADDRESS)}", "storage": {} } @@ -61,13 +61,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (BALANCE 0xcd1722f3947def4cf144679da39c4c32bdc35681 )}", "storage": {} } @@ -89,13 +89,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (BALANCE 0xcd1722f3947def4cf144679da39c4c32bdc35681aa )}", "storage": {} } @@ -117,13 +117,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (BALANCE 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6aa )}", "storage": {} } @@ -145,13 +145,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (BALANCE 0xaa0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 )}", "storage": {} } @@ -174,13 +174,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (BALANCE 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 )}", "storage": {} } @@ -202,13 +202,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EQ (BALANCE 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6) (BALANCE (ADDRESS)))}", "storage": {} } @@ -231,13 +231,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EQ (BALANCE 0xcd1722f3947def4cf144679da39c4c32bdc35681) (BALANCE (CALLER)))}", "storage": {} } @@ -259,13 +259,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (ORIGIN)}", "storage": {} } @@ -287,13 +287,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALLER)}", "storage": {} } @@ -316,13 +316,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALLVALUE)}", "storage": {} } @@ -345,13 +345,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALLDATALOAD 0)}", "storage": {} } @@ -373,13 +373,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALLDATALOAD 1)}", "storage": {} } @@ -401,13 +401,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALLDATALOAD 5)}", "storage": {} } @@ -429,13 +429,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALLDATALOAD 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa)}", "storage": {} } @@ -457,13 +457,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALLDATASIZE)}", "storage": {} } @@ -485,13 +485,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALLDATASIZE)}", "storage": {} } @@ -513,13 +513,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CALLDATASIZE)}", "storage": {} } @@ -541,13 +541,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (CALLDATACOPY 0 1 2 ) [[ 0 ]] @0}", "storage": {} } @@ -569,13 +569,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (CALLDATACOPY 0 0 0 ) [[ 0 ]] @0}", "storage": {} } @@ -597,13 +597,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (CALLDATACOPY 0 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa 0xff ) [[ 0 ]] @0}", "storage": {} } @@ -625,13 +625,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (CALLDATACOPY 0 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa 9 ) [[ 0 ]] @0}", "storage": {} } @@ -653,13 +653,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (CALLDATACOPY 0 1 1 ) [[ 0 ]] @0}", "storage": {} } @@ -681,13 +681,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (CALLDATACOPY 0 1 0 ) [[ 0 ]] @0}", "storage": {} } @@ -709,13 +709,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CODESIZE)}", "storage": {} } @@ -737,13 +737,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (CODECOPY 0 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa 8 ) [[ 0 ]] @0}", "storage": {} } @@ -765,13 +765,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (CODECOPY 0 0 5 ) [[ 0 ]] @0 }", "storage": {} } @@ -793,13 +793,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (CODECOPY 0 0 5 ) [[ 0 ]] @0 }", "storage": {} } @@ -821,13 +821,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (CODECOPY 0 0 0 ) [[ 0 ]] @0 }", "storage": {} } @@ -849,13 +849,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (GASPRICE) }", "storage": {} } @@ -877,13 +877,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXTCODESIZE 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6aa )}", "storage": {} } @@ -905,13 +905,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXTCODESIZE 0xaa0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 )}", "storage": {} } @@ -934,19 +934,19 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EQ (EXTCODESIZE (CALLER)) (CODESIZE) ) }", "storage": {} }, "cd1722f3947def4cf144679da39c4c32bdc35681" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EQ (EXTCODESIZE (CALLER)) (CODESIZE) ) }", "storage": {} } @@ -967,19 +967,19 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (CODESIZE) }", "storage": {} }, "cd1722f3947def4cf144679da39c4c32bdc35681" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (EXTCODESIZE (CALLER) ) }", "storage": {} } @@ -1001,13 +1001,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (EXTCODECOPY (ADDRESS) 0 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa 8 ) [[ 0 ]] @0}", "storage": {} } @@ -1029,19 +1029,19 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (EXTCODECOPY (CALLER) 0 0 0 ) ) [[ 0 ]] @0 }", "storage": {} }, "cd1722f3947def4cf144679da39c4c32bdc35681" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] 5 }", "storage": {} } @@ -1064,19 +1064,19 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (EXTCODECOPY (CALLER) 0 0 (EXTCODESIZE (CALLER) ) ) [[ 0 ]] @0 }", "storage": {} }, "cd1722f3947def4cf144679da39c4c32bdc35681" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] 5 }", "storage": {} } @@ -1098,19 +1098,19 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (EXTCODECOPY 0xaacd1722f3947def4cf144679da39c4c32bdc35681 0 0 (EXTCODESIZE (CALLER) ) ) [[ 0 ]] @0 }", "storage": {} }, "cd1722f3947def4cf144679da39c4c32bdc35681" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] 5 }", "storage": {} } @@ -1132,19 +1132,19 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (EXTCODECOPY 0xcd1722f3947def4cf144679da39c4c32bdc35681aa 0 0 (EXTCODESIZE (CALLER) ) ) [[ 0 ]] @0 }", "storage": {} }, "cd1722f3947def4cf144679da39c4c32bdc35681" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] 5 }", "storage": {} } diff --git a/test/vmIOandFlowOperationsTestFiller.json b/test/vmIOandFlowOperationsTestFiller.json index a6c221716..e794fb2c9 100644 --- a/test/vmIOandFlowOperationsTestFiller.json +++ b/test/vmIOandFlowOperationsTestFiller.json @@ -5,13 +5,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6002600360045055", "storage": {} } @@ -33,13 +33,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x5060026003600455", "storage": {} } @@ -61,13 +61,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x600260035155", "storage": {} } @@ -89,13 +89,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x600260035255", "storage": {} } @@ -117,13 +117,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{(MSTORE 0 23) [[ 1 ]] (MLOAD 0) } ", "storage": {} } @@ -145,13 +145,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{[[ 0 ]] (MLOAD 0) } ", "storage": {} } @@ -173,13 +173,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{(MSTORE 1 23) [[ 1 ]] (MLOAD 0) } ", "storage": {} } @@ -201,13 +201,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 1 ]] (MLOAD 7489573) } ", "storage": {} } @@ -229,13 +229,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 1 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 1 ]] (MLOAD 1) } ", "storage": {} } @@ -257,13 +257,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 1 (+ 2 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ) [[ 1 ]] (MLOAD 1) } ", "storage": {} } @@ -285,13 +285,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 1 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff23 ) [[ 1 ]] (MLOAD 1) } ", "storage": {} } @@ -313,13 +313,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE8 1 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff23 ) [[ 1 ]] (MLOAD 1) } ", "storage": {} } @@ -341,13 +341,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE8 1 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ) [[ 1 ]] (MLOAD 1) } ", "storage": {} } @@ -369,13 +369,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE8 1 0xff) (MSTORE8 2 0xee) [[ 1 ]] (MLOAD 0) } ", "storage": {} } @@ -397,13 +397,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (SSTORE 0 0xff) (SSTORE 10 0xee) [[ 20 ]] (SLOAD 0) } ", "storage": {} } @@ -425,13 +425,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (SSTORE 0 0xff) (SSTORE 10 0xee) [[ 20 ]] (SLOAD 100) } ", "storage": {} } @@ -453,13 +453,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (SSTORE 0 0xff) (SSTORE 1 0xee) (SSTORE 2 0xdd) [[ 10 ]] (SLOAD 1) [[ 20 ]] (SLOAD 2) } ", "storage": {} } @@ -481,13 +481,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6009565b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b", "storage": {} } @@ -509,13 +509,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6006560060015b6002600355", "storage": {} } @@ -537,13 +537,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x60016008570060015b6002600355", "storage": {} } @@ -565,13 +565,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x60055661eeff", "storage": {} } @@ -593,13 +593,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x600456655b6001600155", "storage": {} } @@ -621,13 +621,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x600160075761eeff", "storage": {} } @@ -649,13 +649,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6001600657655b6001600155", "storage": {} } @@ -677,13 +677,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x5b600056", "storage": {} } @@ -705,13 +705,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x565b600056", "storage": {} } @@ -733,13 +733,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6002600401565b600360005260206000f3600656", "storage": {} } @@ -761,13 +761,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x60236007566001600255", "storage": {} } @@ -788,13 +788,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x602360075660015b600255", "storage": {} } @@ -816,13 +816,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x60236007566001600255", "storage": {} } @@ -844,13 +844,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x602360085660015b600255", "storage": {} } @@ -872,13 +872,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6023600a6008505660015b600255", "storage": {} } @@ -900,13 +900,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6023600b6008505660015b600255", "storage": {} } @@ -928,13 +928,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x620fffff620fffff0156", "storage": {} } @@ -956,13 +956,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x602360016009576001600255", "storage": {} } @@ -984,13 +984,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x60236001600a5760015b600255", "storage": {} } @@ -1012,13 +1012,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x602360006009576001600255", "storage": {} } @@ -1040,13 +1040,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x60017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff576002600355", "storage": {} } @@ -1068,13 +1068,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6008600101560060015b6002600355", "storage": {} } @@ -1096,13 +1096,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x60016008600301570060015b6002600355", "storage": {} } @@ -1124,13 +1124,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x60056003015661eeff", "storage": {} } @@ -1152,13 +1152,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x600460030156655b6001600155", "storage": {} } @@ -1180,13 +1180,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x600160076003015761eeff", "storage": {} } @@ -1208,13 +1208,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6001600660030157655b6001600155", "storage": {} } @@ -1236,13 +1236,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x5b586000555960115758600052596000575b58600055", "storage": {} } @@ -1264,13 +1264,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x5b600060000156", "storage": {} } @@ -1292,13 +1292,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x60236007600301566001600255", "storage": {} } @@ -1319,13 +1319,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x602360076003015660015b600255", "storage": {} } @@ -1347,13 +1347,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x60236007600301566001600255", "storage": {} } @@ -1375,13 +1375,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x602360086003015660015b600255", "storage": {} } @@ -1403,13 +1403,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6023600a6008506003015660015b600255", "storage": {} } @@ -1431,13 +1431,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6023600b6008506003015660015b600255", "storage": {} } @@ -1459,13 +1459,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x620fffff620fffff0160030156", "storage": {} } @@ -1487,13 +1487,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x602360016009600301576001600255", "storage": {} } @@ -1515,13 +1515,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x60236001600a6003015760015b600255", "storage": {} } @@ -1543,13 +1543,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x602360006009600301576001600255", "storage": {} } @@ -1571,13 +1571,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x60017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0600301576002600355", "storage": {} } @@ -1599,13 +1599,13 @@ "currentNumber" : "2", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x600160084301570060015b6002600355", "storage": {} } @@ -1627,13 +1627,13 @@ "currentNumber" : "2", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x600543015661eeff", "storage": {} } @@ -1655,13 +1655,13 @@ "currentNumber" : "2", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6004430156655b6001600155", "storage": {} } @@ -1683,13 +1683,13 @@ "currentNumber" : "2", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6001600743015761eeff", "storage": {} } @@ -1711,13 +1711,13 @@ "currentNumber" : "2", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x60016006430157655b6001600155", "storage": {} } @@ -1739,13 +1739,13 @@ "currentNumber" : "2", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x5b600060000156", "storage": {} } @@ -1767,13 +1767,13 @@ "currentNumber" : "2", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x602360074301566001600255", "storage": {} } @@ -1794,13 +1794,13 @@ "currentNumber" : "2", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6023600743015660015b600255", "storage": {} } @@ -1822,13 +1822,13 @@ "currentNumber" : "2", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x602360074301566001600255", "storage": {} } @@ -1850,13 +1850,13 @@ "currentNumber" : "2", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6023600843015660015b600255", "storage": {} } @@ -1878,13 +1878,13 @@ "currentNumber" : "2", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6023600a60085043015660015b600255", "storage": {} } @@ -1906,13 +1906,13 @@ "currentNumber" : "2", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6023600b60085043015660015b600255", "storage": {} } @@ -1934,13 +1934,13 @@ "currentNumber" : "2", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x620fffff620fffff01430156", "storage": {} } @@ -1962,13 +1962,13 @@ "currentNumber" : "2", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6023600160094301576001600255", "storage": {} } @@ -1990,13 +1990,13 @@ "currentNumber" : "2", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x60236001600a43015760015b600255", "storage": {} } @@ -2018,13 +2018,13 @@ "currentNumber" : "2", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6023600060094301576001600255", "storage": {} } @@ -2046,13 +2046,13 @@ "currentNumber" : "2", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x60017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04301576002600355", "storage": {} } @@ -2075,13 +2075,13 @@ "currentNumber" : "1", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "//" : "PUSH1 3 JUMP", "code" : "0x6009436006575b566001", "storage": {} @@ -2104,13 +2104,13 @@ "currentNumber" : "1", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x600a436006575b5660015b6001600155", "storage": {} } @@ -2132,13 +2132,13 @@ "currentNumber" : "4", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x435660615b4343025660615b60615b5b5b6001600155", "storage": {} } @@ -2160,13 +2160,13 @@ "currentNumber" : "4", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x435660615b4343025660615b60615b605b6001600155", "storage": {} } @@ -2188,13 +2188,13 @@ "currentNumber" : "4", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x435631615b60615b60615b606001600155", "storage": {} } @@ -2216,13 +2216,13 @@ "currentNumber" : "7", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x435631615b60615b60615b606001600155", "storage": {} } @@ -2244,13 +2244,13 @@ "currentNumber" : "7", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x435631615b60615b60615b606001600155", "storage": {} } @@ -2272,13 +2272,13 @@ "currentNumber" : "2", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6001600860005401570060015b6002600355", "storage" : { "0x00" : "0x04" @@ -2302,13 +2302,13 @@ "currentNumber" : "2", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6005600054015661eeff", "storage" : { "0x00" : "0x04" @@ -2332,13 +2332,13 @@ "currentNumber" : "2", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x60046000540156655b6001600155", "storage" : { "0x00" : "0x04" @@ -2362,13 +2362,13 @@ "currentNumber" : "2", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x60016007600054015761eeff", "storage" : { "0x00" : "0x04" @@ -2392,13 +2392,13 @@ "currentNumber" : "2", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x600160066000540157655b6001600155", "storage" : { "0x00" : "0x04" @@ -2422,13 +2422,13 @@ "currentNumber" : "2", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x5b600060000156", "storage" : { "0x00" : "0x04" @@ -2452,13 +2452,13 @@ "currentNumber" : "2", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6023600760005401566001600255", "storage" : { "0x00" : "0x04" @@ -2482,13 +2482,13 @@ "currentNumber" : "2", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x60236007600054015660015b600255", "storage" : { "0x00" : "0x04" @@ -2512,13 +2512,13 @@ "currentNumber" : "2", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6023600760005401566001600255", "storage" : { "0x00" : "0x04" @@ -2543,13 +2543,13 @@ "currentNumber" : "2", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x60236008600054015660015b600255", "storage" : { "0x00" : "0x04" @@ -2573,13 +2573,13 @@ "currentNumber" : "2", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6023600a600850600054015660015b600255", "storage" : { "0x00" : "0x04" @@ -2604,13 +2604,13 @@ "currentNumber" : "2", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6023600b600850600054015660015b600255", "storage" : { "0x00" : "0x04" @@ -2634,13 +2634,13 @@ "currentNumber" : "2", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x620fffff620fffff016000540156", "storage" : { "0x00" : "0x04" @@ -2665,13 +2665,13 @@ "currentNumber" : "2", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x60236001600960005401576001600255", "storage" : { "0x00" : "0x04" @@ -2695,13 +2695,13 @@ "currentNumber" : "2", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x60236001600a600054015760015b600255", "storage" : { "0x00" : "0x04" @@ -2726,13 +2726,13 @@ "currentNumber" : "2", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x60236000600960005401576001600255", "storage" : { "0x00" : "0x04" @@ -2756,13 +2756,13 @@ "currentNumber" : "2", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x60017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff060005401576002600355", "storage" : { "0x00" : "0x04" @@ -2787,13 +2787,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (PC)}", "storage": {} } @@ -2815,13 +2815,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{(SSTORE 0 0xff) [[ 0 ]] (PC)}", "storage": {} } @@ -2843,13 +2843,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{(MSTORE 0 0xff) [[ 0 ]] (MSIZE)}", "storage": {} } @@ -2871,13 +2871,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{(MSTORE 0 0xffffffffff) [[ 0 ]] (MSIZE)}", "storage": {} } @@ -2899,13 +2899,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{(MSTORE 0 0xffffffffff) (MSTORE 32 0xeeee) [[ 0 ]] (MSIZE)}", "storage": {} } @@ -2927,13 +2927,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{(MSTORE 0 0xffffffffff) (MSTORE 90 0xeeee) [[ 0 ]] (MSIZE)}", "storage": {} } @@ -2955,13 +2955,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{(MSTORE 0 0xffffffffff) (MSTORE 90 0xeeee) [[ 0 ]] (GAS)}", "storage": {} } @@ -2983,13 +2983,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{[[ 0 ]] (GAS)}", "storage": {} } diff --git a/test/vmLogTestFiller.json b/test/vmLogTestFiller.json index 4f3d26f52..5b63957c5 100644 --- a/test/vmLogTestFiller.json +++ b/test/vmLogTestFiller.json @@ -5,13 +5,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (LOG0 0 0) }", "storage": {} } @@ -33,13 +33,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG0 0 32) }", "storage": {} } @@ -61,13 +61,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG0 0 32) (LOG0 2 16) }", "storage": {} } @@ -89,13 +89,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG0 0 1) }", "storage": {} } @@ -118,13 +118,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG0 31 1) }", "storage": {} } @@ -146,13 +146,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 1) }", "storage": {} } @@ -174,13 +174,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG0 1 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) }", "storage": {} } @@ -202,13 +202,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG0 1 0) }", "storage": {} } @@ -230,13 +230,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (LOG1 0 0 0) }", "storage": {} } @@ -258,13 +258,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG1 0 32 0) }", "storage": {} } @@ -286,13 +286,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG1 0 1 0) }", "storage": {} } @@ -315,13 +315,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG1 31 1 0) }", "storage": {} } @@ -343,13 +343,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG1 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 1 0) }", "storage": {} } @@ -371,13 +371,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG1 1 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0) }", "storage": {} } @@ -399,13 +399,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG1 1 0 0) }", "storage": {} } @@ -427,13 +427,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG1 0 32 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) }", "storage": {} } @@ -455,13 +455,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE8 0 0xff) (LOG1 0 32 (CALLER)) }", "storage": {} } @@ -483,13 +483,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (LOG2 0 0 0 0) }", "storage": {} } @@ -511,13 +511,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG2 0 32 0 0) }", "storage": {} } @@ -539,13 +539,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG2 0 1 0 0) }", "storage": {} } @@ -568,13 +568,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG2 31 1 0 0) }", "storage": {} } @@ -596,13 +596,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG2 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 1 0 0) }", "storage": {} } @@ -624,13 +624,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG2 1 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0 0) }", "storage": {} } @@ -652,13 +652,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG2 1 0 0 0) }", "storage": {} } @@ -680,13 +680,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG2 0 32 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) }", "storage": {} } @@ -708,13 +708,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE8 0 0xff) (LOG2 0 32 0 (CALLER) ) }", "storage": {} } @@ -736,13 +736,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (LOG3 0 0 0 0 0) }", "storage": {} } @@ -764,13 +764,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG3 0 32 0 0 0) }", "storage": {} } @@ -792,13 +792,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG3 0 1 0 0 0) }", "storage": {} } @@ -821,13 +821,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG3 31 1 0 0 0) }", "storage": {} } @@ -849,13 +849,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG3 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 1 0 0 0) }", "storage": {} } @@ -877,13 +877,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG3 1 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0 0 0) }", "storage": {} } @@ -905,13 +905,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG3 1 0 0 0 0) }", "storage": {} } @@ -933,13 +933,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG3 0 32 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) }", "storage": {} } @@ -961,13 +961,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE8 0 0xff) (LOG3 0 32 0 0 (CALLER) ) }", "storage": {} } @@ -989,13 +989,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE8 0 0xff) (LOG3 0 32 (PC) (PC) (PC) ) }", "storage": {} } @@ -1017,13 +1017,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (LOG4 0 0 0 0 0 0) }", "storage": {} } @@ -1045,13 +1045,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG4 0 32 0 0 0 0) }", "storage": {} } @@ -1073,13 +1073,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG4 0 1 0 0 0 0) }", "storage": {} } @@ -1102,13 +1102,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG4 31 1 0 0 0 0) }", "storage": {} } @@ -1130,13 +1130,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG4 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 1 0 0 0 0) }", "storage": {} } @@ -1158,13 +1158,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG4 1 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0 0 0 0) }", "storage": {} } @@ -1186,13 +1186,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG4 1 0 0 0 0 0) }", "storage": {} } @@ -1214,13 +1214,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG4 0 32 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) }", "storage": {} } @@ -1242,13 +1242,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE8 0 0xff) (LOG3 0 32 0 0 0 (CALLER) ) }", "storage": {} } @@ -1270,13 +1270,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE8 0 0xff) (LOG3 0 32 (PC) (PC) (PC) (PC) ) }", "storage": {} } diff --git a/test/vmPushDupSwapTestFiller.json b/test/vmPushDupSwapTestFiller.json index 69d0254b7..a9b69f79e 100644 --- a/test/vmPushDupSwapTestFiller.json +++ b/test/vmPushDupSwapTestFiller.json @@ -5,13 +5,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x60ff600355", "storage": {} } @@ -33,13 +33,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x60", "storage": {} } @@ -61,13 +61,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x61eeff600355", "storage": {} } @@ -89,13 +89,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x62ddeeff600355", "storage": {} } @@ -117,13 +117,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x63ccddeeff600355", "storage": {} } @@ -145,13 +145,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x64bbccddeeff600355", "storage": {} } @@ -173,13 +173,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x65aabbccddeeff600355", "storage": {} } @@ -201,13 +201,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6699aabbccddeeff600355", "storage": {} } @@ -229,13 +229,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x678899aabbccddeeff600355", "storage": {} } @@ -257,13 +257,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x68778899aabbccddeeff600355", "storage": {} } @@ -285,13 +285,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6966778899aabbccddeeff600355", "storage": {} } @@ -313,13 +313,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6a5566778899aabbccddeeff600355", "storage": {} } @@ -341,13 +341,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6b445566778899aabbccddeeff600355", "storage": {} } @@ -369,13 +369,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6c33445566778899aabbccddeeff600355", "storage": {} } @@ -397,13 +397,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6d2233445566778899aabbccddeeff600355", "storage": {} } @@ -425,13 +425,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6e112233445566778899aabbccddeeff600355", "storage": {} } @@ -453,13 +453,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6f10112233445566778899aabbccddeeff600355", "storage": {} } @@ -481,13 +481,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x70ff00112233445566778899aabbccddeeff600355", "storage": {} } @@ -509,13 +509,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x71eeff00112233445566778899aabbccddeeff600355", "storage": {} } @@ -537,13 +537,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x72ddeeff00112233445566778899aabbccddeeff600355", "storage": {} } @@ -565,13 +565,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x73ccddeeff00112233445566778899aabbccddeeff600355", "storage": {} } @@ -593,13 +593,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x74bbccddeeff00112233445566778899aabbccddeeff600355", "storage": {} } @@ -621,13 +621,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x75aabbccddeeff00112233445566778899aabbccddeeff600355", "storage": {} } @@ -649,13 +649,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x7699aabbccddeeff00112233445566778899aabbccddeeff600355", "storage": {} } @@ -677,13 +677,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x778899aabbccddeeff00112233445566778899aabbccddeeff600355", "storage": {} } @@ -705,13 +705,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x78778899aabbccddeeff00112233445566778899aabbccddeeff600355", "storage": {} } @@ -733,13 +733,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x7966778899aabbccddeeff00112233445566778899aabbccddeeff600355", "storage": {} } @@ -762,13 +762,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x7a5566778899aabbccddeeff00112233445566778899aabbccddeeff600355", "storage": {} } @@ -790,13 +790,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x7b445566778899aabbccddeeff00112233445566778899aabbccddeeff600355", "storage": {} } @@ -818,13 +818,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x7c33445566778899aabbccddeeff00112233445566778899aabbccddeeff600355", "storage": {} } @@ -846,13 +846,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x7d2233445566778899aabbccddeeff00112233445566778899aabbccddeeff600355", "storage": {} } @@ -874,13 +874,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x7e112233445566778899aabbccddeeff00112233445566778899aabbccddeeff600355", "storage": {} } @@ -902,13 +902,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x7f10112233445566778899aabbccddeeff00112233445566778899aabbccddeeff600355", "storage": {} } @@ -930,13 +930,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x7fff10112233445566778899aabbccddeeff00112233445566778899aabbccddeeff600355", "storage": {} } @@ -959,13 +959,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x7fff10112233445566778899aabbccddeeff00112233445566778899aabbccdd", "storage": {} } @@ -987,13 +987,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x7f10112233445566778899aabbccddeeff00112233445566778899aabbccddeeff80600355", "storage": {} } @@ -1015,13 +1015,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x7f10112233445566778899aabbccddeeff00112233445566778899aabbccddeeff81600355", "storage": {} } @@ -1043,13 +1043,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6002600181600355", "storage": {} } @@ -1071,13 +1071,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x60036002600182600355", "storage": {} } @@ -1099,13 +1099,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x600460036002600183600355", "storage": {} } @@ -1127,13 +1127,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6005600460036002600184600355", "storage": {} } @@ -1155,13 +1155,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x60066005600460036002600185600355", "storage": {} } @@ -1183,13 +1183,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x600760066005600460036002600186600355", "storage": {} } @@ -1211,13 +1211,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6008600760066005600460036002600187600355", "storage": {} } @@ -1239,13 +1239,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x60096008600760066005600460036002600188600355", "storage": {} } @@ -1267,13 +1267,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x600a60096008600760066005600460036002600189600355", "storage": {} } @@ -1295,13 +1295,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x600b600a6009600860076006600560046003600260018a600355", "storage": {} } @@ -1323,13 +1323,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x600c600b600a6009600860076006600560046003600260018b600355", "storage": {} } @@ -1351,13 +1351,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x600d600c600b600a6009600860076006600560046003600260018c600355", "storage": {} } @@ -1379,13 +1379,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x600e600d600c600b600a6009600860076006600560046003600260018d600355", "storage": {} } @@ -1407,13 +1407,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x600f600e600d600c600b600a6009600860076006600560046003600260018e600355", "storage": {} } @@ -1435,13 +1435,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6010600f600e600d600c600b600a6009600860076006600560046003600260018f600355", "storage": {} } @@ -1463,13 +1463,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x7f10112233445566778899aabbccddeeff00112233445566778899aabbccddeeff60039055", "storage": {} } @@ -1491,13 +1491,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x7f10112233445566778899aabbccddeeff00112233445566778899aabbccddeeff60039155", "storage": {} } @@ -1519,13 +1519,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6002600160039155", "storage": {} } @@ -1547,13 +1547,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x60036002600160039255", "storage": {} } @@ -1575,13 +1575,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x600460036002600160039355", "storage": {} } @@ -1603,13 +1603,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6005600460036002600160039455", "storage": {} } @@ -1631,13 +1631,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x60066005600460036002600160039555", "storage": {} } @@ -1659,13 +1659,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x600760066005600460036002600160039655", "storage": {} } @@ -1687,13 +1687,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6008600760066005600460036002600160039755", "storage": {} } @@ -1715,13 +1715,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x60096008600760066005600460036002600160039855", "storage": {} } @@ -1743,13 +1743,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x600a60096008600760066005600460036002600160039955", "storage": {} } @@ -1771,13 +1771,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x600b600a60096008600760066005600460036002600160039a55", "storage": {} } @@ -1799,13 +1799,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x600c600b600a60096008600760066005600460036002600160039b55", "storage": {} } @@ -1827,13 +1827,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x600d600c600b600a60096008600760066005600460036002600160039c55", "storage": {} } @@ -1855,13 +1855,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x600e600d600c600b600a60096008600760066005600460036002600160039d55", "storage": {} } @@ -1883,13 +1883,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x600f600e600d600c600b600a60096008600760066005600460036002600160039e55", "storage": {} } @@ -1911,13 +1911,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6010600f600e600d600c600b600a60096008600760066005600460036002600160039f55", "storage": {} } diff --git a/test/vmSha3TestFiller.json b/test/vmSha3TestFiller.json index 7ed729520..dd38f7d0b 100644 --- a/test/vmSha3TestFiller.json +++ b/test/vmSha3TestFiller.json @@ -5,13 +5,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (SHA3 0 0)}", "storage": {} } @@ -33,13 +33,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (SHA3 4 5)}", "storage": {} } @@ -61,13 +61,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (SHA3 10 10)}", "storage": {} } @@ -89,13 +89,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (SHA3 1000 0xfffff)}", "storage": {} } @@ -117,13 +117,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (SHA3 0xfffffffff 100)}", "storage": {} } @@ -145,13 +145,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (SHA3 10000 0xfffffffff )}", "storage": {} } @@ -173,13 +173,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (SHA3 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)}", "storage": {} } diff --git a/test/vmSystemOperationsTestFiller.json b/test/vmSystemOperationsTestFiller.json index 0e160bd53..709af7079 100644 --- a/test/vmSystemOperationsTestFiller.json +++ b/test/vmSystemOperationsTestFiller.json @@ -5,13 +5,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0x601080600c6000396000f3006000355415600957005b60203560003555) [[ 0 ]] (CREATE 23 3 29) }", "storage": {} } @@ -33,13 +33,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "100", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0x601080600c6000396000f3006000355415600957005b60203560003555) [[ 0 ]] (CREATE 230 3 29) }", "storage": {} } @@ -61,13 +61,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "100", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0x601080600c6000396000f3006000355415600957005b60203560003555) [[ 0 ]] (CREATE 23 0xfffffffffff 29) }", "storage": {} } @@ -89,13 +89,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "100", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0x601080600c6000396000f3006000355415600957005b60203560003555) [[ 0 ]] (CREATE 23 3 0xffffffff) }", "storage": {} } @@ -117,13 +117,13 @@ "currentNumber" : "0", "currentGasLimit" : "10000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 1000000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 64 64 0) }", "storage": {} }, @@ -183,13 +183,13 @@ "currentNumber" : "0", "currentGasLimit" : "10000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 1000000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 64 0 2) }", "storage": {} }, @@ -219,13 +219,13 @@ "currentNumber" : "0", "currentGasLimit" : "10000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) (POST 1000000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 64 ) }", "storage": {} }, @@ -255,13 +255,13 @@ "currentNumber" : "0", "currentGasLimit" : "10000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALLSTATELESS 500 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 64 0 2 ) }", "storage": {} }, @@ -291,13 +291,13 @@ "currentNumber" : "0", "currentGasLimit" : "10000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALLCODE 500 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 64 0 2 ) }", "storage": {} }, @@ -328,13 +328,13 @@ "currentNumber" : "0", "currentGasLimit" : "10000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xeeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 100 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 64 64 0) }", "storage": {} }, @@ -364,13 +364,13 @@ "currentNumber" : "0", "currentGasLimit" : "10000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xeeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 500 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 987654321 64 64 0) }", "storage": {} }, @@ -400,13 +400,13 @@ "currentNumber" : "0", "currentGasLimit" : "10000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xeeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 500 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 9865432 64 0) }", "storage": {} }, @@ -436,13 +436,13 @@ "currentNumber" : "0", "currentGasLimit" : "10000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xeeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 500 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 64 987654 1) }", "storage": {} }, @@ -473,13 +473,13 @@ "currentNumber" : "0", "currentGasLimit" : "10000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xeeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 500 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 64 987654 0) }", "storage": {} }, @@ -509,13 +509,13 @@ "currentNumber" : "0", "currentGasLimit" : "10000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xeeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 500 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 987654 0 64 0) }", "storage": {} }, @@ -545,19 +545,19 @@ "currentNumber" : "0", "currentGasLimit" : "10000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "20000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (CALL 100000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 0 0 0) }", "storage": {} }, "945304eb96065b2a98b57a48a06ae28d285a71b5" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (+ (SLOAD 0) 1) [[ 1 ]] (CALL (- (GAS) 224) (ADDRESS) 0 0 0 0 0) } ", "storage": {} } @@ -579,13 +579,13 @@ "currentNumber" : "0", "currentGasLimit" : "10000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "20000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (+ (SLOAD 0) 1) [[ 1 ]] (CALL (- (GAS) 224) (ADDRESS) 0 0 0 0 0) }", "storage": {} } @@ -607,13 +607,13 @@ "currentNumber" : "0", "currentGasLimit" : "10000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "20000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (+ (SLOAD 0) 1) [[ 1 ]] (CALL (- (GAS) 224) (ADDRESS) 0 0 0 0 0) }", "storage": {} } @@ -635,13 +635,13 @@ "currentNumber" : "0", "currentGasLimit" : "10000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "20000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (+ (SLOAD 0) 1) [[ 1 ]] (CALL (- (GAS) 224) (ADDRESS) 0 0 0 0 0) }", "storage": {} } @@ -663,13 +663,13 @@ "currentNumber" : "0", "currentGasLimit" : "10000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (SUICIDE (CALLER))}", "storage": {} }, @@ -699,13 +699,13 @@ "currentNumber" : "0", "currentGasLimit" : "10000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (SUICIDE 0xaa1722f3947def4cf144679da39c4c32bdc35681 )}", "storage": {} }, @@ -735,13 +735,13 @@ "currentNumber" : "0", "currentGasLimit" : "10000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (SUICIDE (ADDRESS) )}", "storage": {} }, @@ -771,7 +771,7 @@ "currentNumber" : "0", "currentGasLimit" : "10000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { @@ -801,7 +801,7 @@ "currentNumber" : "0", "currentGasLimit" : "10000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { @@ -831,7 +831,7 @@ "currentNumber" : "0", "currentGasLimit" : "10000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { @@ -861,13 +861,13 @@ "currentNumber" : "0", "currentGasLimit" : "10000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) (POST 1000000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 64 ) }", "storage": {} }, @@ -897,13 +897,13 @@ "currentNumber" : "0", "currentGasLimit" : "10000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALLSTATELESS 1000000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 64 64 0) }", "storage": {} }, @@ -933,13 +933,13 @@ "currentNumber" : "0", "currentGasLimit" : "10000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALLCODE 1000000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 64 64 0) }", "storage": {} }, @@ -969,13 +969,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x6000355415600957005b60203560003555", "storage": {} } @@ -997,13 +997,13 @@ "currentNumber" : "0", "currentGasLimit" : "10000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ (PC) ]] (CALL 1000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 24 0 0 0 0) }", "storage": {} }, @@ -1033,13 +1033,13 @@ "currentNumber" : "0", "currentGasLimit" : "10000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ (PC) ]] (CALL (- (GAS) 1000) 0x945304eb96065b2a98b57a48a06ae28d285a71b5 24 0 0 0 0) }", "storage": {} }, @@ -1069,13 +1069,13 @@ "currentNumber" : "0", "currentGasLimit" : "10000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (ADD (SLOAD 0) 1) (CALL (- (GAS) 1000) 0x945304eb96065b2a98b57a48a06ae28d285a71b5 1 0 0 0 0) }", "storage": {} }, @@ -1105,13 +1105,13 @@ "currentNumber" : "0", "currentGasLimit" : "10000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1025000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ 0 ]] (ADD (SLOAD 0) 1) (CALL (- (GAS) 1000) 0x945304eb96065b2a98b57a48a06ae28d285a71b5 1 0 0 0 0) }", "storage": {} }, @@ -1141,13 +1141,13 @@ "currentNumber" : "0", "currentGasLimit" : "10000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ (PC) ]] (CALL 1000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 24 0 0 0 0) (SUICIDE 0x945304eb96065b2a98b57a48a06ae28d285a71b5) }", "storage": {} }, @@ -1177,13 +1177,13 @@ "currentNumber" : "0", "currentGasLimit" : "10000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ [[ (PC) ]] (CALL 1000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 24 0 0 0 0) }", "storage": {} }, diff --git a/test/vmtestsFiller.json b/test/vmtestsFiller.json index 6dce8bff7..75bf1da8f 100644 --- a/test/vmtestsFiller.json +++ b/test/vmtestsFiller.json @@ -5,13 +5,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "(suicide (caller))", "storage": {} } @@ -33,13 +33,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "{ (call (- (gas) 200) (caller) (+ 2 2 (* 4 4 4) (/ 2 2) (% 3 2) (- 8 2 2)) 0 0 0 0) }", "storage": {} } @@ -61,13 +61,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "(seq (when (and 1 1) (call (- (gas) 200) (caller) 2 0 0 0 0)) (when (and 1 0) (call (- (gas) 200) (caller) 3 0 0 0 0)) (when (and 0 1) (call (- (gas) 200) (caller) 4 0 0 0 0)) (when (and 0 0) (call (- (gas) 200) (caller) 5 0 0 0 0)) (when (or 1 1) (call (- (gas) 200) (caller) 12 0 0 0 0)) (when (or 1 0) (call (- (gas) 200) (caller) 13 0 0 0 0)) (when (or 0 1) (call (- (gas) 200) (caller) 14 0 0 0 0)) (when (or 0 0) (call (- (gas) 200) (caller) 15 0 0 0 0)) )", "storage": {} } @@ -89,13 +89,13 @@ "currentNumber" : "0", "currentGasLimit" : "1000000", "currentDifficulty" : "256", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "(call (- (gas) 200) (caller) 500000000000000000 0 0 0 0)", "storage": {} } From e9538b23c8d9bccb0905755d4150e59b58e8d90c Mon Sep 17 00:00:00 2001 From: subtly Date: Fri, 6 Feb 2015 11:54:00 -0800 Subject: [PATCH 040/213] updates for code-review --- libp2p/Common.h | 1 + libp2p/Host.cpp | 44 +++++------ libp2p/Host.h | 47 ++++++----- libp2p/NodeTable.cpp | 153 ++++++++++++++++++------------------ libp2p/NodeTable.h | 164 +++++++++++++++++++++++---------------- libp2p/Session.cpp | 20 ++--- libp2p/UDP.h | 6 +- libwebthree/WebThree.cpp | 2 +- libwebthree/WebThree.h | 2 +- test/net.cpp | 8 +- test/whisperTopic.cpp | 22 +++--- 11 files changed, 251 insertions(+), 218 deletions(-) diff --git a/libp2p/Common.h b/libp2p/Common.h index 19cf447ce..219ec804b 100644 --- a/libp2p/Common.h +++ b/libp2p/Common.h @@ -169,6 +169,7 @@ struct Node NodeIPEndpoint endpoint; /// If true, node will not be removed from Node list. + // TODO: p2p implement bool required = false; virtual operator bool() const { return (bool)id; } diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index fc86cf06b..25a095ae6 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -53,7 +53,7 @@ Host::Host(std::string const& _clientVersion, NetworkPreferences const& _n, byte m_ifAddresses(Network::getInterfaceAddresses()), m_ioService(2), m_tcp4Acceptor(m_ioService), - m_alias(getNetworkAlias(_restoreNetwork)), + m_alias(networkAlias(_restoreNetwork)), m_lastPing(chrono::time_point::min()) { for (auto address: m_ifAddresses) @@ -182,7 +182,7 @@ void Host::onNodeTableEvent(NodeId const& _n, NodeTableEventType const& _e) { clog(NetNote) << "p2p.host.nodeTable.events.nodeEntryAdded " << _n; - auto n = (*m_nodeTable)[_n]; + auto n = m_nodeTable->node(_n); if (n) { RecursiveGuard l(x_sessions); @@ -195,7 +195,7 @@ void Host::onNodeTableEvent(NodeId const& _n, NodeTableEventType const& _e) } p->endpoint.tcp = n.endpoint.tcp; - // TODO: Implement similar to doFindNode. Attempt connecting to nodes + // TODO: Implement similar to discover. Attempt connecting to nodes // until ideal peer count is reached; if all nodes are tried, // repeat. Notably, this is an integrated process such that // when onNodeTableEvent occurs we should also update +/- @@ -442,9 +442,9 @@ void Host::connect(std::shared_ptr const& _p) Peer *nptr = _p.get(); { Guard l(x_pendingNodeConns); - if (m_pendingNodeConns.count(nptr)) + if (m_pendingPeerConns.count(nptr)) return; - m_pendingNodeConns.insert(nptr); + m_pendingPeerConns.insert(nptr); } clog(NetConnect) << "Attempting connection to node" << _p->id.abridged() << "@" << _p->peerEndpoint() << "from" << id().abridged(); @@ -454,25 +454,25 @@ void Host::connect(std::shared_ptr const& _p) if (ec) { clog(NetConnect) << "Connection refused to node" << _p->id.abridged() << "@" << _p->peerEndpoint() << "(" << ec.message() << ")"; - _p->lastDisconnect = TCPError; - _p->lastAttempted = std::chrono::system_clock::now(); + _p->m_lastDisconnect = TCPError; + _p->m_lastAttempted = std::chrono::system_clock::now(); } else { clog(NetConnect) << "Connected to" << _p->id.abridged() << "@" << _p->peerEndpoint(); - _p->lastConnected = std::chrono::system_clock::now(); + _p->m_lastConnected = std::chrono::system_clock::now(); auto ps = make_shared(this, std::move(*s), _p); ps->start(); } delete s; Guard l(x_pendingNodeConns); - m_pendingNodeConns.erase(nptr); + m_pendingPeerConns.erase(nptr); }); } -PeerSessionInfos Host::peers() const +PeerSessionInfos Host::peerSessionInfo() const { if (!m_run) return PeerSessionInfos(); @@ -622,7 +622,7 @@ bytes Host::saveNetwork() const // TODO: alpha: Figure out why it ever shares these ports.//p.address.port() >= 30300 && p.address.port() <= 30305 && // TODO: alpha: if/how to save private addresses // Only save peers which have connected within 2 days, with properly-advertised port and public IP address - if (chrono::system_clock::now() - p.lastConnected < chrono::seconds(3600 * 48) && p.peerEndpoint().port() > 0 && p.peerEndpoint().port() < /*49152*/32768 && p.id != id() && !isPrivateAddress(p.peerEndpoint().address())) + if (chrono::system_clock::now() - p.m_lastConnected < chrono::seconds(3600 * 48) && p.peerEndpoint().port() > 0 && p.peerEndpoint().port() < /*49152*/32768 && p.id != id() && !isPrivateAddress(p.peerEndpoint().address())) { network.appendList(10); if (p.peerEndpoint().address().is_v4()) @@ -631,15 +631,15 @@ bytes Host::saveNetwork() const network << p.peerEndpoint().address().to_v6().to_bytes(); // TODO: alpha: replace 0 with trust-state of node network << p.peerEndpoint().port() << p.id << 0 - << chrono::duration_cast(p.lastConnected.time_since_epoch()).count() - << chrono::duration_cast(p.lastAttempted.time_since_epoch()).count() - << p.failedAttempts << (unsigned)p.lastDisconnect << p.score << p.rating; + << chrono::duration_cast(p.m_lastConnected.time_since_epoch()).count() + << chrono::duration_cast(p.m_lastAttempted.time_since_epoch()).count() + << p.m_failedAttempts << (unsigned)p.m_lastDisconnect << p.m_score << p.m_rating; count++; } } } - auto state = m_nodeTable->state(); + auto state = m_nodeTable->snapshot(); state.sort(); for (auto const& s: state) { @@ -693,12 +693,12 @@ void Host::restoreNetwork(bytesConstRef _b) { shared_ptr p = make_shared(); p->id = id; - p->lastConnected = chrono::system_clock::time_point(chrono::seconds(i[4].toInt())); - p->lastAttempted = chrono::system_clock::time_point(chrono::seconds(i[5].toInt())); - p->failedAttempts = i[6].toInt(); - p->lastDisconnect = (DisconnectReason)i[7].toInt(); - p->score = (int)i[8].toInt(); - p->rating = (int)i[9].toInt(); + p->m_lastConnected = chrono::system_clock::time_point(chrono::seconds(i[4].toInt())); + p->m_lastAttempted = chrono::system_clock::time_point(chrono::seconds(i[5].toInt())); + p->m_failedAttempts = i[6].toInt(); + p->m_lastDisconnect = (DisconnectReason)i[7].toInt(); + p->m_score = (int)i[8].toInt(); + p->m_rating = (int)i[9].toInt(); p->endpoint.tcp = tcp; p->endpoint.udp = udp; m_peers[p->id] = p; @@ -708,7 +708,7 @@ void Host::restoreNetwork(bytesConstRef _b) } } -KeyPair Host::getNetworkAlias(bytesConstRef _b) +KeyPair Host::networkAlias(bytesConstRef _b) { RLP r(_b); if (r.itemCount() == 3 && r[0].isInt() && r[0].toInt() == 1) diff --git a/libp2p/Host.h b/libp2p/Host.h index cd45f3268..b24f1343c 100644 --- a/libp2p/Host.h +++ b/libp2p/Host.h @@ -79,37 +79,37 @@ public: bool isOffline() const { return !m_session.lock(); } bi::tcp::endpoint const& peerEndpoint() const { return endpoint.tcp; } - - int score = 0; ///< All time cumulative. - int rating = 0; ///< Trending. + + int m_score = 0; ///< All time cumulative. + int m_rating = 0; ///< Trending. /// Network Availability - std::chrono::system_clock::time_point lastConnected; - std::chrono::system_clock::time_point lastAttempted; - unsigned failedAttempts = 0; - DisconnectReason lastDisconnect = NoDisconnect; ///< Reason for disconnect that happened last. + std::chrono::system_clock::time_point m_lastConnected; + std::chrono::system_clock::time_point m_lastAttempted; + unsigned m_failedAttempts = 0; + DisconnectReason m_lastDisconnect = NoDisconnect; ///< Reason for disconnect that happened last. virtual bool operator<(Peer const& _p) const { if (isOffline() != _p.isOffline()) return isOffline(); else if (isOffline()) - if (lastAttempted == _p.lastAttempted) - return failedAttempts < _p.failedAttempts; + if (m_lastAttempted == _p.m_lastAttempted) + return m_failedAttempts < _p.m_failedAttempts; else - return lastAttempted < _p.lastAttempted; + return m_lastAttempted < _p.m_lastAttempted; else - if (score == _p.score) - if (rating == _p.rating) - if (failedAttempts == _p.failedAttempts) + if (m_score == _p.m_score) + if (m_rating == _p.m_rating) + if (m_failedAttempts == _p.m_failedAttempts) return id < _p.id; else - return failedAttempts < _p.failedAttempts; + return m_failedAttempts < _p.m_failedAttempts; else - return rating < _p.rating; + return m_rating < _p.m_rating; else - return score < _p.score; + return m_score < _p.m_score; } protected: @@ -121,9 +121,14 @@ using Peers = std::vector; class HostNodeTableHandler: public NodeTableEventHandler { - friend class Host; +public: HostNodeTableHandler(Host& _host); + + Host const& host() const { return m_host; } + +private: virtual void processEvent(NodeId const& _n, NodeTableEventType const& _e); + Host& m_host; }; @@ -181,7 +186,7 @@ public: void setIdealPeerCount(unsigned _n) { m_idealPeerCount = _n; } /// Get peer information. - PeerSessionInfos peers() const; + PeerSessionInfos peerSessionInfo() const; /// Get number of peers connected. size_t peerCount() const; @@ -196,7 +201,7 @@ public: bytes saveNetwork() const; // TODO: P2P this should be combined with peers into a HostStat object of some kind; coalesce data, as it's only used for status information. - Peers nodes() const { RecursiveGuard l(x_sessions); Peers ret; for (auto const& i: m_peers) ret.push_back(*i.second); return ret; } + Peers getPeers() const { RecursiveGuard l(x_sessions); Peers ret; for (auto const& i: m_peers) ret.push_back(*i.second); return ret; } void setNetworkPreferences(NetworkPreferences const& _p) { auto had = isStarted(); if (had) stop(); m_netPrefs = _p; if (had) start(); } @@ -252,7 +257,7 @@ private: virtual void doneWorking(); /// Get or create host identifier (KeyPair). - static KeyPair getNetworkAlias(bytesConstRef _b); + static KeyPair networkAlias(bytesConstRef _b); bytes m_restoreNetwork; ///< Set by constructor and used to set Host key and restore network peers & nodes. @@ -274,7 +279,7 @@ private: std::unique_ptr m_timer; ///< Timer which, when network is running, calls scheduler() every c_timerInterval ms. static const unsigned c_timerInterval = 100; ///< Interval which m_timer is run when network is connected. - std::set m_pendingNodeConns; /// Used only by connect(Peer&) to limit concurrently connecting to same node. See connect(shared_ptrconst&). + std::set m_pendingPeerConns; /// Used only by connect(Peer&) to limit concurrently connecting to same node. See connect(shared_ptrconst&). Mutex x_pendingNodeConns; bi::tcp::endpoint m_tcpPublic; ///< Our public listening endpoint. diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index dffa0933b..186ece5e2 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -24,15 +24,15 @@ using namespace std; using namespace dev; using namespace dev::p2p; -NodeEntry::NodeEntry(Node _src, Public _pubk, NodeIPEndpoint _gw): Node(_pubk, _gw), distance(NodeTable::dist(_src.id,_pubk)) {} -NodeEntry::NodeEntry(Node _src, Public _pubk, bi::udp::endpoint _udp): Node(_pubk, NodeIPEndpoint(_udp)), distance(NodeTable::dist(_src.id,_pubk)) {} +NodeEntry::NodeEntry(Node _src, Public _pubk, NodeIPEndpoint _gw): Node(_pubk, _gw), distance(NodeTable::distance(_src.id,_pubk)) {} +NodeEntry::NodeEntry(Node _src, Public _pubk, bi::udp::endpoint _udp): Node(_pubk, NodeIPEndpoint(_udp)), distance(NodeTable::distance(_src.id,_pubk)) {} NodeTable::NodeTable(ba::io_service& _io, KeyPair _alias, uint16_t _udp): m_node(Node(_alias.pub(), bi::udp::endpoint())), m_secret(_alias.sec()), m_io(_io), m_socket(new NodeSocket(m_io, *this, _udp)), - m_socketPtr(m_socket.get()), + m_socketPointer(m_socket.get()), m_bucketRefreshTimer(m_io), m_evictionCheckTimer(m_io) { @@ -42,15 +42,18 @@ NodeTable::NodeTable(ba::io_service& _io, KeyPair _alias, uint16_t _udp): m_state[i].modified = chrono::steady_clock::now() - chrono::seconds(1); } - m_socketPtr->connect(); + m_socketPointer->connect(); doRefreshBuckets(boost::system::error_code()); } NodeTable::~NodeTable() { + // Cancel scheduled tasks to ensure. m_evictionCheckTimer.cancel(); m_bucketRefreshTimer.cancel(); - m_socketPtr->disconnect(); + + // Disconnect socket so that deallocation is safe. + m_socketPointer->disconnect(); } void NodeTable::processEvents() @@ -87,14 +90,14 @@ shared_ptr NodeTable::addNode(Node const& _node) m_nodes[_node.id] = ret; PingNode p(_node.endpoint.udp, m_node.endpoint.udp.address().to_string(), m_node.endpoint.udp.port()); p.sign(m_secret); - m_socketPtr->send(p); + m_socketPointer->send(p); } return move(ret); } -void NodeTable::join() +void NodeTable::discover() { - doFindNode(m_node.id); + discover(m_node.id); } list NodeTable::nodes() const @@ -106,7 +109,7 @@ list NodeTable::nodes() const return move(nodes); } -list NodeTable::state() const +list NodeTable::snapshot() const { list ret; Guard l(x_state); @@ -116,42 +119,35 @@ list NodeTable::state() const return move(ret); } -Node NodeTable::operator[](NodeId _id) +Node NodeTable::node(NodeId _id) { Guard l(x_nodes); auto n = m_nodes[_id]; return !!n ? *n : Node(); } -shared_ptr NodeTable::getNodeEntry(NodeId _id) +shared_ptr NodeTable::nodeEntry(NodeId _id) { Guard l(x_nodes); auto n = m_nodes[_id]; return !!n ? move(n) : move(shared_ptr()); } -void NodeTable::requestNeighbours(NodeEntry const& _node, NodeId _target) const +void NodeTable::discover(NodeId _node, unsigned _round, shared_ptr>> _tried) { - FindNode p(_node.endpoint.udp, _target); - p.sign(m_secret); - m_socketPtr->send(p); -} - -void NodeTable::doFindNode(NodeId _node, unsigned _round, shared_ptr>> _tried) -{ - if (!m_socketPtr->isOpen() || _round == s_maxSteps) + if (!m_socketPointer->isOpen() || _round == s_maxSteps) return; if (_round == s_maxSteps) { - clog(NodeTableNote) << "Terminating doFindNode after " << _round << " rounds."; + clog(NodeTableNote) << "Terminating discover after " << _round << " rounds."; return; } else if(!_round && !_tried) // initialized _tried on first round _tried.reset(new set>()); - auto nearest = findNearest(_node); + auto nearest = nearestNodeEntries(_node); list> tried; for (unsigned i = 0; i < nearest.size() && tried.size() < s_alpha; i++) if (!_tried->count(nearest[i])) @@ -160,12 +156,12 @@ void NodeTable::doFindNode(NodeId _node, unsigned _round, shared_ptrendpoint.udp, _node); p.sign(m_secret); - m_socketPtr->send(p); + m_socketPointer->send(p); } if (tried.empty()) { - clog(NodeTableNote) << "Terminating doFindNode after " << _round << " rounds."; + clog(NodeTableNote) << "Terminating discover after " << _round << " rounds."; return; } @@ -181,15 +177,15 @@ void NodeTable::doFindNode(NodeId _node, unsigned _round, shared_ptr> NodeTable::findNearest(NodeId _target) +vector> NodeTable::nearestNodeEntries(NodeId _target) { // send s_alpha FindNode packets to nodes we know, closest to target static unsigned lastBin = s_bins - 1; - unsigned head = dist(m_node.id, _target); + unsigned head = distance(m_node.id, _target); unsigned tail = head == 0 ? lastBin : (head - 1) % s_bins; map>> found; @@ -204,7 +200,7 @@ vector> NodeTable::findNearest(NodeId _target) if (auto p = n.lock()) { if (count < s_bucketSize) - found[dist(_target, p->id)].push_back(p); + found[distance(_target, p->id)].push_back(p); else break; } @@ -214,7 +210,7 @@ vector> NodeTable::findNearest(NodeId _target) if (auto p = n.lock()) { if (count < s_bucketSize) - found[dist(_target, p->id)].push_back(p); + found[distance(_target, p->id)].push_back(p); else break; } @@ -231,7 +227,7 @@ vector> NodeTable::findNearest(NodeId _target) if (auto p = n.lock()) { if (count < s_bucketSize) - found[dist(_target, p->id)].push_back(p); + found[distance(_target, p->id)].push_back(p); else break; } @@ -245,7 +241,7 @@ vector> NodeTable::findNearest(NodeId _target) if (auto p = n.lock()) { if (count < s_bucketSize) - found[dist(_target, p->id)].push_back(p); + found[distance(_target, p->id)].push_back(p); else break; } @@ -263,7 +259,7 @@ void NodeTable::ping(bi::udp::endpoint _to) const { PingNode p(_to, m_node.endpoint.udp.address().to_string(), m_node.endpoint.udp.port()); p.sign(m_secret); - m_socketPtr->send(p); + m_socketPointer->send(p); } void NodeTable::ping(NodeEntry* _n) const @@ -274,65 +270,64 @@ void NodeTable::ping(NodeEntry* _n) const void NodeTable::evict(shared_ptr _leastSeen, shared_ptr _new) { - if (!m_socketPtr->isOpen()) + if (!m_socketPointer->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)); + { + 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 NodeTable::noteNode(Public const& _pubk, bi::udp::endpoint const& _endpoint) +void NodeTable::noteActiveNode(Public const& _pubk, bi::udp::endpoint const& _endpoint) { if (_pubk == m_node.address()) return; shared_ptr node(addNode(_pubk, _endpoint)); - // todo: sometimes node is nullptr here + // TODO p2p: old bug (maybe gone now) sometimes node is nullptr here if (!!node) - noteNode(node); -} - -void NodeTable::noteNode(shared_ptr _n) -{ - shared_ptr contested; { - NodeBucket& s = bucket(_n.get()); - Guard l(x_state); - s.nodes.remove_if([&_n](weak_ptr n) - { - if (n.lock() == _n) - return true; - return false; - }); - - if (s.nodes.size() >= s_bucketSize) + shared_ptr contested; { - contested = s.nodes.front().lock(); - if (!contested) + Guard l(x_state); + NodeBucket& s = bucket_UNSAFE(node.get()); + s.nodes.remove_if([&node](weak_ptr n) + { + if (n.lock() == node) + return true; + return false; + }); + + if (s.nodes.size() >= s_bucketSize) { - s.nodes.pop_front(); - s.nodes.push_back(_n); + contested = s.nodes.front().lock(); + if (!contested) + { + s.nodes.pop_front(); + s.nodes.push_back(node); + } } + else + s.nodes.push_back(node); } - else - s.nodes.push_back(_n); + + if (contested) + evict(contested, node); } - - if (contested) - evict(contested, _n); } void NodeTable::dropNode(shared_ptr _n) { - NodeBucket &s = bucket(_n.get()); { Guard l(x_state); + NodeBucket& s = bucket_UNSAFE(_n.get()); s.nodes.remove_if([&_n](weak_ptr n) { return n.lock() == _n; }); } { @@ -345,7 +340,7 @@ void NodeTable::dropNode(shared_ptr _n) m_nodeEventHandler->appendEvent(_n->id, NodeEntryRemoved); } -NodeTable::NodeBucket& NodeTable::bucket(NodeEntry const* _n) +NodeTable::NodeBucket& NodeTable::bucket_UNSAFE(NodeEntry const* _n) { return m_state[_n->distance - 1]; } @@ -381,7 +376,7 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes unsigned packetType = signedBytes[0]; if (packetType && packetType < 4) - noteNode(nodeid, _from); + noteActiveNode(nodeid, _from); bytesConstRef rlpBytes(_packet.cropped(h256::size + Signature::size + 1)); RLP rlp(rlpBytes); @@ -398,10 +393,10 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes for (auto it = m_evictions.begin(); it != m_evictions.end(); it++) if (it->first.first == nodeid && it->first.second > std::chrono::steady_clock::now()) { - if (auto n = getNodeEntry(it->second)) + if (auto n = nodeEntry(it->second)) dropNode(n); - if (auto n = (*this)[it->first.first]) + if (auto n = node(it->first.first)) addNode(n); it = m_evictions.erase(it); @@ -414,7 +409,7 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes Neighbours in = Neighbours::fromBytesConstRef(_from, rlpBytes); // clog(NodeTableMessageSummary) << "Received " << in.nodes.size() << " Neighbours from " << _from.address().to_string() << ":" << _from.port(); for (auto n: in.nodes) - noteNode(n.node, bi::udp::endpoint(bi::address::from_string(n.ipAddress), n.port)); + noteActiveNode(n.node, bi::udp::endpoint(bi::address::from_string(n.ipAddress), n.port)); break; } @@ -423,13 +418,13 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes // clog(NodeTableMessageSummary) << "Received FindNode from " << _from.address().to_string() << ":" << _from.port(); FindNode in = FindNode::fromBytesConstRef(_from, rlpBytes); - vector> nearest = findNearest(in.target); - static unsigned const nlimit = (m_socketPtr->maxDatagramSize - 11) / 86; + vector> nearest = nearestNodeEntries(in.target); + static unsigned const nlimit = (m_socketPointer->maxDatagramSize - 11) / 86; for (unsigned offset = 0; offset < nearest.size(); offset += nlimit) { Neighbours out(_from, nearest, offset, nlimit); out.sign(m_secret); - m_socketPtr->send(out); + m_socketPointer->send(out); } break; } @@ -442,7 +437,7 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes Pong p(_from); p.echo = sha3(rlpBytes); p.sign(m_secret); - m_socketPtr->send(p); + m_socketPointer->send(p); break; } @@ -459,7 +454,7 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes void NodeTable::doCheckEvictions(boost::system::error_code const& _ec) { - if (_ec || !m_socketPtr->isOpen()) + if (_ec || !m_socketPointer->isOpen()) return; auto self(shared_from_this()); @@ -472,8 +467,8 @@ void NodeTable::doCheckEvictions(boost::system::error_code const& _ec) bool evictionsRemain = false; list> drop; { - Guard le(x_evictions); Guard ln(x_nodes); + Guard le(x_evictions); for (auto& e: m_evictions) if (chrono::steady_clock::now() - e.first.second > c_reqTimeout) if (auto n = m_nodes[e.second]) @@ -496,7 +491,7 @@ void NodeTable::doRefreshBuckets(boost::system::error_code const& _ec) return; clog(NodeTableNote) << "refreshing buckets"; - bool connected = m_socketPtr->isOpen(); + bool connected = m_socketPointer->isOpen(); bool refreshed = false; if (connected) { diff --git a/libp2p/NodeTable.h b/libp2p/NodeTable.h index e2ba06f4b..72f7800f5 100644 --- a/libp2p/NodeTable.h +++ b/libp2p/NodeTable.h @@ -53,7 +53,7 @@ class NodeTableEventHandler { friend class NodeTable; public: - virtual void processEvent(NodeId const& _n, NodeTableEventType const& _e) =0; + virtual void processEvent(NodeId const& _n, NodeTableEventType const& _e) = 0; protected: /// Called by NodeTable on behalf of an implementation (Host) to process new events without blocking nodetable. @@ -65,7 +65,8 @@ protected: if (!m_nodeEventHandler.size()) return; m_nodeEventHandler.unique(); - for (auto const& n: m_nodeEventHandler) events.push_back(std::make_pair(n,m_events[n])); + for (auto const& n: m_nodeEventHandler) + events.push_back(std::make_pair(n,m_events[n])); m_nodeEventHandler.clear(); m_events.clear(); } @@ -80,10 +81,17 @@ protected: std::list m_nodeEventHandler; std::map m_events; }; + +class NodeTable; +inline std::ostream& operator<<(std::ostream& _out, NodeTable const& _nodeTable); /** * NodeTable using modified kademlia for node discovery and preference. - * untouched buckets are refreshed if they have not been touched within an hour + * Node table requires an IO service, creates a socket for incoming + * UDP messages and implements a kademlia-like protocol. Node requests and + * responses are used to build a node table which can be queried to + * obtain a list of potential nodes to connect to, and, passes events to + * Host whenever a node is added or removed to/from the table. * * Thread-safety is ensured by modifying NodeEntry details via * shared_ptr replacement instead of mutating values. @@ -101,7 +109,7 @@ protected: * @todo serialize evictions per-bucket * @todo store evictions in map, unit-test eviction logic * @todo store root node in table - * @todo encapsulate doFindNode into NetworkAlgorithm (task) + * @todo encapsulate discover into NetworkAlgorithm (task) * @todo Pong to include ip:port where ping was received * @todo expiration and sha3(id) 'to' for messages which are replies (prevents replay) * @todo cache Ping and FindSelf @@ -117,33 +125,17 @@ protected: */ class NodeTable: UDPSocketEvents, public std::enable_shared_from_this { + friend std::ostream& operator<<(std::ostream& _out, NodeTable const& _nodeTable); using NodeSocket = UDPSocket; using TimePoint = std::chrono::steady_clock::time_point; - using EvictionTimeout = std::pair,NodeId>; ///< First NodeId may be evicted and replaced with second NodeId. + using EvictionTimeout = std::pair, NodeId>; ///< First NodeId may be evicted and replaced with second NodeId. public: NodeTable(ba::io_service& _io, KeyPair _alias, uint16_t _udpPort = 30303); ~NodeTable(); - /// Constants for Kademlia, derived from address space. - - static unsigned const s_addressByteSize = sizeof(NodeId); ///< Size of address type in bytes. - static unsigned const s_bits = 8 * s_addressByteSize; ///< Denoted by n in [Kademlia]. - static unsigned const s_bins = s_bits - 1; ///< Size of m_state (excludes root, which is us). - static unsigned const s_maxSteps = boost::static_log2::value; ///< Max iterations of discovery. (doFindNode) - - /// Chosen constants - - static unsigned const s_bucketSize = 16; ///< Denoted by k in [Kademlia]. Number of nodes stored in each bucket. - static unsigned const s_alpha = 3; ///< Denoted by \alpha in [Kademlia]. Number of concurrent FindNode requests. - - /// Intervals - - boost::posix_time::milliseconds const c_evictionCheckInterval = boost::posix_time::milliseconds(75); ///< Interval at which eviction timeouts are checked. - std::chrono::milliseconds const c_reqTimeout = std::chrono::milliseconds(300); ///< How long to wait for requests (evict, find iterations). - std::chrono::seconds const c_bucketRefresh = std::chrono::seconds(3600); ///< Refresh interval prevents bucket from becoming stale. [Kademlia] - - static unsigned dist(NodeId const& _a, NodeId const& _b) { u512 d = _a ^ _b; unsigned ret; for (ret = 0; d >>= 1; ++ret) {}; return ret; } + /// Returns distance based on xor metric two node ids. Used by NodeEntry and NodeTable. + static unsigned distance(NodeId const& _a, NodeId const& _b) { u512 d = _a ^ _b; unsigned ret; for (ret = 0; d >>= 1; ++ret) {}; return ret; } /// Set event handler for NodeEntryAdded and NodeEntryRemoved events. void setEventHandler(NodeTableEventHandler* _handler) { m_nodeEventHandler.reset(_handler); } @@ -157,18 +149,49 @@ public: /// Add node. Node will be pinged if it's not already known. std::shared_ptr addNode(Node const& _node); - void join(); + /// To be called when node table is empty. Runs node discovery with m_node.id as the target in order to populate node-table. + void discover(); - NodeEntry root() const { return NodeEntry(m_node, m_node.publicKey(), m_node.endpoint.udp); } + /// Returns list of node ids active in node table. std::list nodes() const; - unsigned size() const { return m_nodes.size(); } - std::list state() const; + /// Returns node count. + unsigned count() const { return m_nodes.size(); } + + /// Returns snapshot of table. + std::list snapshot() const; + + /// Returns true if node id is in node table. bool haveNode(NodeId _id) { Guard l(x_nodes); return m_nodes.count(_id); } - Node operator[](NodeId _id); - std::shared_ptr getNodeEntry(NodeId _id); + /// Returns the Node to the corresponding node id or the empty Node if that id is not found. + Node node(NodeId _id); + +#ifndef BOOST_AUTO_TEST_SUITE +private: +#else protected: +#endif + + /// Constants for Kademlia, derived from address space. + + static unsigned const s_addressByteSize = sizeof(NodeId); ///< Size of address type in bytes. + static unsigned const s_bits = 8 * s_addressByteSize; ///< Denoted by n in [Kademlia]. + static unsigned const s_bins = s_bits - 1; ///< Size of m_state (excludes root, which is us). + static unsigned const s_maxSteps = boost::static_log2::value; ///< Max iterations of discovery. (discover) + + /// Chosen constants + + static unsigned const s_bucketSize = 16; ///< Denoted by k in [Kademlia]. Number of nodes stored in each bucket. + static unsigned const s_alpha = 3; ///< Denoted by \alpha in [Kademlia]. Number of concurrent FindNode requests. + + /// Intervals + + /* todo: replace boost::posix_time; change constants to upper camelcase */ + boost::posix_time::milliseconds const c_evictionCheckInterval = boost::posix_time::milliseconds(75); ///< Interval at which eviction timeouts are checked. + std::chrono::milliseconds const c_reqTimeout = std::chrono::milliseconds(300); ///< How long to wait for requests (evict, find iterations). + std::chrono::seconds const c_bucketRefresh = std::chrono::seconds(3600); ///< Refresh interval prevents bucket from becoming stale. [Kademlia] + struct NodeBucket { unsigned distance; @@ -176,81 +199,95 @@ protected: std::list> nodes; }; - /// Repeatedly sends s_alpha concurrent requests to nodes nearest to target, for nodes nearest to target, up to s_maxSteps rounds. - void doFindNode(NodeId _node, unsigned _round = 0, std::shared_ptr>> _tried = std::shared_ptr>>()); - - /// Returns nodes nearest to target. - std::vector> findNearest(NodeId _target); - + /// Used to ping endpoint. void ping(bi::udp::endpoint _to) const; + /// Used ping known node. Used by node table when refreshing buckets and as part of eviction process (see evict). void ping(NodeEntry* _n) const; - void evict(std::shared_ptr _leastSeen, std::shared_ptr _new); + /// Returns center node entry which describes this node and used with dist() to calculate xor metric for node table nodes. + NodeEntry center() const { return NodeEntry(m_node, m_node.publicKey(), m_node.endpoint.udp); } + + /// Used by asynchronous operations to return NodeEntry which is active and managed by node table. + std::shared_ptr nodeEntry(NodeId _id); - void noteNode(Public const& _pubk, bi::udp::endpoint const& _endpoint); + /// Used to discovery nodes on network which are close to the given target. + /// Sends s_alpha concurrent requests to nodes nearest to target, for nodes nearest to target, up to s_maxSteps rounds. + void discover(NodeId _target, unsigned _round = 0, std::shared_ptr>> _tried = std::shared_ptr>>()); + + /// Returns nodes from node table which are closest to target. + std::vector> nearestNodeEntries(NodeId _target); - void noteNode(std::shared_ptr _n); + /// Asynchronously drops _leastSeen node if it doesn't reply and adds _new node, otherwise _new node is thrown away. + void evict(std::shared_ptr _leastSeen, std::shared_ptr _new); + /// Called whenever activity is received from an unknown node in order to maintain node table. + void noteActiveNode(Public const& _pubk, bi::udp::endpoint const& _endpoint); + + /// Used to drop node when timeout occurs or when evict() result is to keep previous node. void dropNode(std::shared_ptr _n); - NodeBucket& bucket(NodeEntry const* _n); + /// Returns references to bucket which corresponds to distance of node id. + /// @warning Only use the return reference locked x_state mutex. + // TODO p2p: Remove this method after removing offset-by-one functionality. + NodeBucket& bucket_UNSAFE(NodeEntry const* _n); /// General Network Events + /// Called by m_socket when packet is received. void onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytesConstRef _packet); - void onDisconnected(UDPSocketFace*) {}; + /// Called by m_socket when socket is disconnected. + void onDisconnected(UDPSocketFace*) {} /// Tasks + /// Called by evict() to ensure eviction check is scheduled to run and terminates when no evictions remain. Asynchronous. void doCheckEvictions(boost::system::error_code const& _ec); - - void doRefreshBuckets(boost::system::error_code const& _ec); -#ifndef BOOST_AUTO_TEST_SUITE -private: -#else -protected: -#endif - /// Sends FindNeighbor packet. See doFindNode. - void requestNeighbours(NodeEntry const& _node, NodeId _target) const; + /// Purges and pings nodes for any buckets which haven't been touched for c_bucketRefresh seconds. + void doRefreshBuckets(boost::system::error_code const& _ec); - std::unique_ptr m_nodeEventHandler; ///< Event handler for node events. + std::unique_ptr m_nodeEventHandler; ///< Event handler for node events. Node m_node; ///< This node. Secret m_secret; ///< This nodes secret key. - mutable Mutex x_nodes; ///< Mutable for thread-safe copy in nodes() const. + mutable Mutex x_nodes; ///< LOCK x_state first if both locks are required. Mutable for thread-safe copy in nodes() const. std::map> m_nodes; ///< Nodes - mutable Mutex x_state; + mutable Mutex x_state; ///< LOCK x_state first if both x_nodes and x_state locks are required. std::array m_state; ///< State of p2p node network. - Mutex x_evictions; + Mutex x_evictions; ///< LOCK x_nodes first if both x_nodes and x_evictions locks are required. std::deque m_evictions; ///< Eviction timeouts. ba::io_service& m_io; ///< Used by bucket refresh timer. std::shared_ptr m_socket; ///< Shared pointer for our UDPSocket; ASIO requires shared_ptr. - NodeSocket* m_socketPtr; ///< Set to m_socket.get(). + NodeSocket* m_socketPointer; ///< Set to m_socket.get(). Socket is created in constructor and disconnected in destructor to ensure access to pointer is safe. boost::asio::deadline_timer m_bucketRefreshTimer; ///< Timer which schedules and enacts bucket refresh. boost::asio::deadline_timer m_evictionCheckTimer; ///< Timer for handling node evictions. }; - + inline std::ostream& operator<<(std::ostream& _out, NodeTable const& _nodeTable) { - _out << _nodeTable.root().address() << "\t" << "0\t" << _nodeTable.root().endpoint.udp.address() << ":" << _nodeTable.root().endpoint.udp.port() << std::endl; - auto s = _nodeTable.state(); + _out << _nodeTable.center().address() << "\t" << "0\t" << _nodeTable.center().endpoint.udp.address() << ":" << _nodeTable.center().endpoint.udp.port() << std::endl; + auto s = _nodeTable.snapshot(); for (auto n: s) _out << n.address() << "\t" << n.distance << "\t" << n.endpoint.udp.address() << ":" << n.endpoint.udp.port() << std::endl; return _out; } /** - * Ping packet: Check if node is alive. + * Ping packet: Sent to check if node is alive. * PingNode is cached and regenerated after expiration - t, where t is timeout. * + * 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. + * * RLP Encoded Items: 3 * Minimum Encoded Size: 18 bytes * Maximum Encoded Size: bytes // todo after u128 addresses @@ -260,11 +297,6 @@ inline std::ostream& operator<<(std::ostream& _out, NodeTable const& _nodeTable) * 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. - * * @todo uint128_t for ip address (<->integer ipv4/6, asio-address, asio-endpoint) * */ @@ -285,7 +317,7 @@ struct PingNode: RLPXDatagram }; /** - * Pong packet: response to ping + * Pong packet: Sent in response to ping * * RLP Encoded Items: 2 * Minimum Encoded Size: 33 bytes @@ -365,7 +397,7 @@ struct Neighbours: RLPXDatagram } static const uint8_t type = 4; - std::list nodes; + std::vector nodes; unsigned expiration = 1; void streamRLP(RLPStream& _s) const { _s.appendList(2); _s.appendList(nodes.size()); for (auto& n: nodes) n.streamRLP(_s); _s << expiration; } diff --git a/libp2p/Session.cpp b/libp2p/Session.cpp index 4a6621d09..1d1d69b7d 100644 --- a/libp2p/Session.cpp +++ b/libp2p/Session.cpp @@ -48,7 +48,7 @@ Session::Session(Host* _s, bi::tcp::socket _socket, std::shared_ptr const& Session::~Session() { - m_peer->lastConnected = m_peer->lastAttempted - chrono::seconds(1); + m_peer->m_lastConnected = m_peer->m_lastAttempted - chrono::seconds(1); // Read-chain finished for one reason or another. for (auto& i: m_capabilities) @@ -75,14 +75,14 @@ void Session::addRating(unsigned _r) { if (m_peer) { - m_peer->rating += _r; - m_peer->score += _r; + m_peer->m_rating += _r; + m_peer->m_score += _r; } } int Session::rating() const { - return m_peer->rating; + return m_peer->m_rating; } template vector randomSelection(vector const& _t, unsigned _n) @@ -206,7 +206,7 @@ bool Session::interpret(RLP const& _r) } if (m_peer->isOffline()) - m_peer->lastConnected = chrono::system_clock::now(); + m_peer->m_lastConnected = chrono::system_clock::now(); if (m_protocolVersion != m_server->protocolVersion()) { @@ -446,13 +446,13 @@ void Session::drop(DisconnectReason _reason) if (m_peer) { - if (_reason != m_peer->lastDisconnect || _reason == NoDisconnect || _reason == ClientQuit || _reason == DisconnectRequested) - m_peer->failedAttempts = 0; - m_peer->lastDisconnect = _reason; + if (_reason != m_peer->m_lastDisconnect || _reason == NoDisconnect || _reason == ClientQuit || _reason == DisconnectRequested) + m_peer->m_failedAttempts = 0; + m_peer->m_lastDisconnect = _reason; if (_reason == BadProtocol) { - m_peer->rating /= 2; - m_peer->score /= 2; + m_peer->m_rating /= 2; + m_peer->m_score /= 2; } } m_dropped = true; diff --git a/libp2p/UDP.h b/libp2p/UDP.h index bf9a6a372..5c3b9362f 100644 --- a/libp2p/UDP.h +++ b/libp2p/UDP.h @@ -64,12 +64,12 @@ struct RLPXDatagramFace: public UDPDatagram static uint64_t futureFromEpoch(std::chrono::seconds _sec) { return std::chrono::duration_cast((std::chrono::system_clock::now() + _sec).time_since_epoch()).count(); } static Public authenticate(bytesConstRef _sig, bytesConstRef _rlp); - virtual uint8_t packetType() =0; + virtual uint8_t packetType() = 0; RLPXDatagramFace(bi::udp::endpoint const& _ep): UDPDatagram(_ep) {} virtual h256 sign(Secret const& _from); - virtual void streamRLP(RLPStream&) const =0; - virtual void interpretRLP(bytesConstRef _bytes) =0; + virtual void streamRLP(RLPStream&) const = 0; + virtual void interpretRLP(bytesConstRef _bytes) = 0; }; template diff --git a/libwebthree/WebThree.cpp b/libwebthree/WebThree.cpp index 7daec9693..3075108d1 100644 --- a/libwebthree/WebThree.cpp +++ b/libwebthree/WebThree.cpp @@ -77,7 +77,7 @@ void WebThreeDirect::setNetworkPreferences(p2p::NetworkPreferences const& _n) std::vector WebThreeDirect::peers() { - return m_net.peers(); + return m_net.peerSessionInfo(); } size_t WebThreeDirect::peerCount() const diff --git a/libwebthree/WebThree.h b/libwebthree/WebThree.h index f99eed5cf..1bce0820c 100644 --- a/libwebthree/WebThree.h +++ b/libwebthree/WebThree.h @@ -145,7 +145,7 @@ public: p2p::NodeId id() const override { return m_net.id(); } /// Gets the nodes. - p2p::Peers nodes() const override { return m_net.nodes(); } + p2p::Peers nodes() const override { return m_net.getPeers(); } /// Start the network subsystem. void startNetwork() override { m_net.start(); } diff --git a/test/net.cpp b/test/net.cpp index 7f30ed03b..5a7e56d23 100644 --- a/test/net.cpp +++ b/test/net.cpp @@ -87,7 +87,7 @@ struct TestNodeTable: public NodeTable bi::address ourIp = bi::address::from_string("127.0.0.1"); for (auto& n: _testNodes) if (_count--) - noteNode(n.first.pub(), bi::udp::endpoint(ourIp, n.second)); + noteActiveNode(n.first.pub(), bi::udp::endpoint(ourIp, n.second)); else break; } @@ -182,7 +182,7 @@ BOOST_AUTO_TEST_CASE(kademlia) // 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.nodeTable->discover(); // ideally, joining with empty node table logs warning we can check for node.setup(); node.populate(); clog << "NodeTable:\n" << *node.nodeTable.get() << endl; @@ -199,11 +199,11 @@ BOOST_AUTO_TEST_CASE(kademlia) node.populate(1); clog << "NodeTable:\n" << *node.nodeTable.get() << endl; - node.nodeTable->join(); + node.nodeTable->discover(); this_thread::sleep_for(chrono::milliseconds(2000)); clog << "NodeTable:\n" << *node.nodeTable.get() << endl; - BOOST_REQUIRE_EQUAL(node.nodeTable->size(), 8); + BOOST_REQUIRE_EQUAL(node.nodeTable->count(), 8); auto netNodes = node.nodeTable->nodes(); netNodes.sort(); diff --git a/test/whisperTopic.cpp b/test/whisperTopic.cpp index 1dcc6b9d6..e59a3f289 100644 --- a/test/whisperTopic.cpp +++ b/test/whisperTopic.cpp @@ -111,7 +111,7 @@ BOOST_AUTO_TEST_CASE(forwarding) setThreadName("listener"); // Host must be configured not to share peers. - Host ph("Listner", NetworkPreferences(50303, "", false, true)); + Host ph("Listner", NetworkPreferences(30303, "", false, true)); ph.setIdealPeerCount(0); auto wh = ph.registerCapability(new WhisperHost()); ph.start(); @@ -145,7 +145,7 @@ BOOST_AUTO_TEST_CASE(forwarding) this_thread::sleep_for(chrono::milliseconds(50)); // Host must be configured not to share peers. - Host ph("Forwarder", NetworkPreferences(50305, "", false, true)); + Host ph("Forwarder", NetworkPreferences(30305, "", false, true)); ph.setIdealPeerCount(0); auto wh = ph.registerCapability(new WhisperHost()); this_thread::sleep_for(chrono::milliseconds(500)); @@ -153,7 +153,7 @@ BOOST_AUTO_TEST_CASE(forwarding) fwderid = ph.id(); this_thread::sleep_for(chrono::milliseconds(500)); - ph.addNode(phid, "127.0.0.1", 50303, 50303); + ph.addNode(phid, "127.0.0.1", 30303, 30303); startedForwarder = true; @@ -174,13 +174,13 @@ BOOST_AUTO_TEST_CASE(forwarding) while (!startedForwarder) this_thread::sleep_for(chrono::milliseconds(50)); - Host ph("Sender", NetworkPreferences(50300, "", false, true)); + Host ph("Sender", NetworkPreferences(30300, "", false, true)); ph.setIdealPeerCount(0); shared_ptr wh = ph.registerCapability(new WhisperHost()); this_thread::sleep_for(chrono::milliseconds(500)); ph.start(); this_thread::sleep_for(chrono::milliseconds(500)); - ph.addNode(fwderid, "127.0.0.1", 50305, 50305); + ph.addNode(fwderid, "127.0.0.1", 30305, 30305); KeyPair us = KeyPair::create(); wh->post(us.sec(), RLPStream().append(1).out(), BuildTopic("test")); @@ -210,14 +210,14 @@ BOOST_AUTO_TEST_CASE(asyncforwarding) setThreadName("forwarder"); // Host must be configured not to share peers. - Host ph("Forwarder", NetworkPreferences(50305, "", false, true)); + Host ph("Forwarder", NetworkPreferences(30305, "", false, true)); ph.setIdealPeerCount(0); auto wh = ph.registerCapability(new WhisperHost()); this_thread::sleep_for(chrono::milliseconds(500)); ph.start(); this_thread::sleep_for(chrono::milliseconds(500)); -// ph.addNode("127.0.0.1", 50303, 50303); +// ph.addNode("127.0.0.1", 30303, 30303); startedForwarder = true; @@ -239,13 +239,13 @@ BOOST_AUTO_TEST_CASE(asyncforwarding) this_thread::sleep_for(chrono::milliseconds(50)); { - Host ph("Sender", NetworkPreferences(50300, "", false, true)); + Host ph("Sender", NetworkPreferences(30300, "", false, true)); ph.setIdealPeerCount(0); shared_ptr wh = ph.registerCapability(new WhisperHost()); this_thread::sleep_for(chrono::milliseconds(500)); ph.start(); this_thread::sleep_for(chrono::milliseconds(500)); -// ph.addNode("127.0.0.1", 50305, 50305); +// ph.addNode("127.0.0.1", 30305, 30305); KeyPair us = KeyPair::create(); wh->post(us.sec(), RLPStream().append(1).out(), BuildTopic("test")); @@ -253,13 +253,13 @@ BOOST_AUTO_TEST_CASE(asyncforwarding) } { - Host ph("Listener", NetworkPreferences(50300, "", false, true)); + Host ph("Listener", NetworkPreferences(30300, "", false, true)); ph.setIdealPeerCount(0); shared_ptr wh = ph.registerCapability(new WhisperHost()); this_thread::sleep_for(chrono::milliseconds(500)); ph.start(); this_thread::sleep_for(chrono::milliseconds(500)); -// ph.addNode("127.0.0.1", 50305, 50305); +// ph.addNode("127.0.0.1", 30305, 30305); /// Only interested in odd packets auto w = wh->installWatch(BuildTopicMask("test")); From 8c2daa4195c0a9acc4f10396b457628edbc60640 Mon Sep 17 00:00:00 2001 From: subtly Date: Fri, 6 Feb 2015 13:55:01 -0800 Subject: [PATCH 041/213] update whisper topic and forwarding tests for node-discovery --- test/whisperTopic.cpp | 87 +++++++++++++++++++++++-------------------- 1 file changed, 47 insertions(+), 40 deletions(-) diff --git a/test/whisperTopic.cpp b/test/whisperTopic.cpp index e59a3f289..d2f2d9d89 100644 --- a/test/whisperTopic.cpp +++ b/test/whisperTopic.cpp @@ -36,9 +36,12 @@ BOOST_AUTO_TEST_CASE(topic) auto oldLogVerbosity = g_logVerbosity; g_logVerbosity = 0; - Host phOther("Test", NetworkPreferences(30303, "127.0.0.1", false, true)); - auto whOther = phOther.registerCapability(new WhisperHost()); - phOther.start(); + Host host1("Test", NetworkPreferences(30303, "127.0.0.1", false, true)); + auto whost1 = host1.registerCapability(new WhisperHost()); + host1.start(); + + while (!host1.isStarted()) + this_thread::sleep_for(chrono::milliseconds(2)); bool started = false; unsigned result = 0; @@ -48,16 +51,16 @@ BOOST_AUTO_TEST_CASE(topic) started = true; /// Only interested in odd packets - auto w = whOther->installWatch(BuildTopicMask("odd")); + auto w = whost1->installWatch(BuildTopicMask("odd")); started = true; set received; for (int iterout = 0, last = 0; iterout < 200 && last < 81; ++iterout) { - for (auto i: whOther->checkWatch(w)) + for (auto i: whost1->checkWatch(w)) { - Message msg = whOther->envelope(i).open(whOther->fullTopic(w)); + Message msg = whost1->envelope(i).open(whost1->fullTopic(w)); last = RLP(msg.payload()).toInt(); if (received.count(last)) continue; @@ -70,12 +73,15 @@ BOOST_AUTO_TEST_CASE(topic) }); - Host ph("Test", NetworkPreferences(30300, "127.0.0.1", false, true)); - auto wh = ph.registerCapability(new WhisperHost()); - ph.start(); + Host host2("Test", NetworkPreferences(30300, "127.0.0.1", false, true)); + auto whost2 = host2.registerCapability(new WhisperHost()); + host2.start(); + + while (!host2.isStarted()) + this_thread::sleep_for(chrono::milliseconds(2)); this_thread::sleep_for(chrono::milliseconds(100)); - ph.addNode(phOther.id(), "127.0.0.1", 30303, 30303); + host2.addNode(host1.id(), "127.0.0.1", 30303, 30303); this_thread::sleep_for(chrono::milliseconds(500)); @@ -85,7 +91,7 @@ BOOST_AUTO_TEST_CASE(topic) KeyPair us = KeyPair::create(); for (int i = 0; i < 10; ++i) { - wh->post(us.sec(), RLPStream().append(i * i).out(), BuildTopic(i)(i % 2 ? "odd" : "even")); + whost2->post(us.sec(), RLPStream().append(i * i).out(), BuildTopic(i)(i % 2 ? "odd" : "even")); this_thread::sleep_for(chrono::milliseconds(250)); } @@ -100,33 +106,33 @@ BOOST_AUTO_TEST_CASE(forwarding) cnote << "Testing Whisper forwarding..."; auto oldLogVerbosity = g_logVerbosity; g_logVerbosity = 0; - + + // Host must be configured not to share peers. + Host host1("Listner", NetworkPreferences(30303, "", false, true)); + host1.setIdealPeerCount(0); + auto whost1 = host1.registerCapability(new WhisperHost()); + host1.start(); + while (!host1.isStarted()) + this_thread::sleep_for(chrono::milliseconds(2)); + unsigned result = 0; bool done = false; bool startedListener = false; - Public phid; std::thread listener([&]() { setThreadName("listener"); - // Host must be configured not to share peers. - Host ph("Listner", NetworkPreferences(30303, "", false, true)); - ph.setIdealPeerCount(0); - auto wh = ph.registerCapability(new WhisperHost()); - ph.start(); - phid = ph.id(); - startedListener = true; /// Only interested in odd packets - auto w = wh->installWatch(BuildTopicMask("test")); + auto w = whost1->installWatch(BuildTopicMask("test")); for (int i = 0; i < 200 && !result; ++i) { - for (auto i: wh->checkWatch(w)) + for (auto i: whost1->checkWatch(w)) { - Message msg = wh->envelope(i).open(wh->fullTopic(w)); + Message msg = whost1->envelope(i).open(whost1->fullTopic(w)); unsigned last = RLP(msg.payload()).toInt(); cnote << "New message from:" << msg.from().abridged() << RLP(msg.payload()).toInt(); result = last; @@ -135,8 +141,17 @@ BOOST_AUTO_TEST_CASE(forwarding) } }); - bool startedForwarder = false; + + // Host must be configured not to share peers. + Host host2("Forwarder", NetworkPreferences(30305, "", false, true)); + host2.setIdealPeerCount(1); + auto whost2 = host2.registerCapability(new WhisperHost()); + host2.start(); + while (!host2.isStarted()) + this_thread::sleep_for(chrono::milliseconds(2)); + Public fwderid; + bool startedForwarder = false; std::thread forwarder([&]() { setThreadName("forwarder"); @@ -144,27 +159,19 @@ BOOST_AUTO_TEST_CASE(forwarding) while (!startedListener) this_thread::sleep_for(chrono::milliseconds(50)); - // Host must be configured not to share peers. - Host ph("Forwarder", NetworkPreferences(30305, "", false, true)); - ph.setIdealPeerCount(0); - auto wh = ph.registerCapability(new WhisperHost()); this_thread::sleep_for(chrono::milliseconds(500)); - ph.start(); - fwderid = ph.id(); - - this_thread::sleep_for(chrono::milliseconds(500)); - ph.addNode(phid, "127.0.0.1", 30303, 30303); + host2.addNode(host1.id(), "127.0.0.1", 30303, 30303); startedForwarder = true; /// Only interested in odd packets - auto w = wh->installWatch(BuildTopicMask("test")); + auto w = whost2->installWatch(BuildTopicMask("test")); while (!done) { - for (auto i: wh->checkWatch(w)) + for (auto i: whost2->checkWatch(w)) { - Message msg = wh->envelope(i).open(wh->fullTopic(w)); + Message msg = whost2->envelope(i).open(whost2->fullTopic(w)); cnote << "New message from:" << msg.from().abridged() << RLP(msg.payload()).toInt(); } this_thread::sleep_for(chrono::milliseconds(50)); @@ -175,12 +182,12 @@ BOOST_AUTO_TEST_CASE(forwarding) this_thread::sleep_for(chrono::milliseconds(50)); Host ph("Sender", NetworkPreferences(30300, "", false, true)); - ph.setIdealPeerCount(0); + ph.setIdealPeerCount(1); shared_ptr wh = ph.registerCapability(new WhisperHost()); - this_thread::sleep_for(chrono::milliseconds(500)); ph.start(); - this_thread::sleep_for(chrono::milliseconds(500)); - ph.addNode(fwderid, "127.0.0.1", 30305, 30305); + ph.addNode(host2.id(), "127.0.0.1", 30305, 30305); + while (!ph.isStarted()) + this_thread::sleep_for(chrono::milliseconds(10)); KeyPair us = KeyPair::create(); wh->post(us.sec(), RLPStream().append(1).out(), BuildTopic("test")); From 6f4265a615cd0a1e38385dea6bd4403a1976d4ad Mon Sep 17 00:00:00 2001 From: winsvega Date: Sat, 7 Feb 2015 01:13:02 +0300 Subject: [PATCH 042/213] TransactionTest Incorrect receiver address ength --- test/transaction.cpp | 106 ++++++++++++------------------ test/ttTransactionTestFiller.json | 49 +++++++++++++- 2 files changed, 87 insertions(+), 68 deletions(-) diff --git a/test/transaction.cpp b/test/transaction.cpp index 8c2e99cf9..ddd7c3dc4 100644 --- a/test/transaction.cpp +++ b/test/transaction.cpp @@ -28,31 +28,48 @@ using namespace dev::eth; namespace dev { namespace test { -Transaction createTransactionFromFields(mObject& _tObj) +RLPStream createRLPStreamFromTransactionFields(mObject& _tObj) { - BOOST_REQUIRE(_tObj.count("data") > 0); - BOOST_REQUIRE(_tObj.count("value") > 0); - BOOST_REQUIRE(_tObj.count("gasPrice") > 0); - BOOST_REQUIRE(_tObj.count("gasLimit") > 0); - BOOST_REQUIRE(_tObj.count("nonce")> 0); - BOOST_REQUIRE(_tObj.count("to") > 0); - - BOOST_REQUIRE(_tObj.count("v") > 0); - BOOST_REQUIRE(_tObj.count("r") > 0); - BOOST_REQUIRE(_tObj.count("s") > 0); - //Construct Rlp of the given transaction RLPStream rlpStream; - rlpStream.appendList(9); - rlpStream << bigint(_tObj["nonce"].get_str()) << bigint(_tObj["gasPrice"].get_str()) << bigint(_tObj["gasLimit"].get_str()); - if (_tObj["to"].get_str().empty()) - rlpStream << ""; - else - rlpStream << Address(_tObj["to"].get_str()); - rlpStream << bigint(_tObj["value"].get_str()) << importData(_tObj); - rlpStream << bigint(_tObj["v"].get_str()) << bigint(_tObj["r"].get_str()) << bigint(_tObj["s"].get_str()); - - return Transaction(rlpStream.out(), CheckSignature::Sender); + rlpStream.appendList(_tObj.size()); + + if (_tObj.count("nonce") > 0) + rlpStream << bigint(_tObj["nonce"].get_str()); + + if (_tObj.count("gasPrice") > 0) + rlpStream << bigint(_tObj["gasPrice"].get_str()); + + if (_tObj.count("gasLimit") > 0) + rlpStream << bigint(_tObj["gasLimit"].get_str()); + + if (_tObj.count("to") > 0) + { + if (_tObj["to"].get_str().empty()) + rlpStream << ""; + else + rlpStream << importByteArray(_tObj["to"].get_str()); + } + + if (_tObj.count("value") > 0) + rlpStream << bigint(_tObj["value"].get_str()); + + if (_tObj.count("data") > 0) + rlpStream << importData(_tObj); + + if (_tObj.count("v") > 0) + rlpStream << bigint(_tObj["v"].get_str()); + + if (_tObj.count("r") > 0) + rlpStream << bigint(_tObj["r"].get_str()); + + if (_tObj.count("s") > 0) + rlpStream << bigint(_tObj["s"].get_str()); + + if (_tObj.count("extrafield") > 0) + rlpStream << bigint(_tObj["extrafield"].get_str()); + + return rlpStream; } void doTransactionTests(json_spirit::mValue& _v, bool _fillin) @@ -83,7 +100,7 @@ void doTransactionTests(json_spirit::mValue& _v, bool _fillin) BOOST_REQUIRE(o.count("transaction") > 0); mObject tObj = o["transaction"].get_obj(); - Transaction txFromFields = createTransactionFromFields(tObj); + Transaction txFromFields(createRLPStreamFromTransactionFields(tObj).out(),CheckSignature::Sender); //Check the fields restored from RLP to original fields BOOST_CHECK_MESSAGE(txFromFields.data() == txFromRlp.data(), "Data in given RLP not matching the Transaction data!"); @@ -105,44 +122,7 @@ void doTransactionTests(json_spirit::mValue& _v, bool _fillin) mObject tObj = o["transaction"].get_obj(); //Construct Rlp of the given transaction - RLPStream rlpStream; - rlpStream.appendList(tObj.size()); - - if (tObj.count("nonce") > 0) - rlpStream << bigint(tObj["nonce"].get_str()); - - if (tObj.count("gasPrice") > 0) - rlpStream << bigint(tObj["gasPrice"].get_str()); - - if (tObj.count("gasLimit") > 0) - rlpStream << bigint(tObj["gasLimit"].get_str()); - - if (tObj.count("to") > 0) - { - if (tObj["to"].get_str().empty()) - rlpStream << ""; - else - rlpStream << Address(tObj["to"].get_str()); - } - - if (tObj.count("value") > 0) - rlpStream << bigint(tObj["value"].get_str()); - - if (tObj.count("data") > 0) - rlpStream << importData(tObj); - - if (tObj.count("v") > 0) - rlpStream << bigint(tObj["v"].get_str()); - - if (tObj.count("r") > 0) - rlpStream << bigint(tObj["r"].get_str()); - - if (tObj.count("s") > 0) - rlpStream << bigint(tObj["s"].get_str()); - - if (tObj.count("extrafield") > 0) - rlpStream << bigint(tObj["extrafield"].get_str()); - + RLPStream rlpStream = createRLPStreamFromTransactionFields(tObj); o["rlp"] = "0x" + toHex(rlpStream.out()); try @@ -151,9 +131,6 @@ void doTransactionTests(json_spirit::mValue& _v, bool _fillin) if (!txFromFields.signature().isValid()) BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("transaction from RLP signature is invalid") ); - //cause Address is length20 array, when trying to create address from sting of another length, field "to" would be diffrent from RLP encoded Address - BOOST_CHECK_MESSAGE(Address(tObj["to"].get_str()) == txFromFields.receiveAddress(), "seems that transaction 'to' address has wrong format"); - o["sender"] = toString(txFromFields.sender()); } catch(...) @@ -163,7 +140,6 @@ void doTransactionTests(json_spirit::mValue& _v, bool _fillin) } }//for }//doTransactionTests - } }// Namespace Close diff --git a/test/ttTransactionTestFiller.json b/test/ttTransactionTestFiller.json index 6967f4284..26f32271e 100644 --- a/test/ttTransactionTestFiller.json +++ b/test/ttTransactionTestFiller.json @@ -10,8 +10,7 @@ "value" : "10", "v" : "28", "r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", - "s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" - + "s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" } }, @@ -255,6 +254,50 @@ "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" } - } + }, + + "AddressMoreThan20" : { + "transaction" : + { + "data" : "", + "gasLimit" : "2000", + "gasPrice" : "1", + "nonce" : "0", + "to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b1c", + "value" : "10", + "v" : "28", + "r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", + "s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" + } + }, + + "AddressLessThan20" : { + "transaction" : + { + "data" : "", + "gasLimit" : "2000", + "gasPrice" : "1", + "nonce" : "0", + "to" : "b9331677e6ebf", + "value" : "10", + "v" : "28", + "r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", + "s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" + } + }, + "AddressLessThan20Prefixed0" : { + "transaction" : + { + "data" : "", + "gasLimit" : "2000", + "gasPrice" : "1", + "nonce" : "0", + "to" : "0x000000000000000000000000000b9331677e6ebf", + "value" : "10", + "v" : "28", + "r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", + "s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" + } + } } From 7d03f7be2e1c6e7cadeaa7e8768766441d1940e3 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Fri, 6 Feb 2015 23:43:49 +0100 Subject: [PATCH 043/213] create block from transaction with genesis block as parent --- libethereum/State.h | 2 +- test/TestHelper.cpp | 27 +++++ test/TestHelper.h | 1 + test/blFirstTestFiller.json | 15 +++ test/block.cpp | 197 +++++++++++++++++++++++------------- test/transaction.cpp | 30 +----- 6 files changed, 170 insertions(+), 102 deletions(-) create mode 100644 test/blFirstTestFiller.json diff --git a/libethereum/State.h b/libethereum/State.h index 65a333fb4..5a296c0dd 100644 --- a/libethereum/State.h +++ b/libethereum/State.h @@ -128,7 +128,7 @@ public: * commitToMine(_blockChain); // will call uncommitToMine if a repeat. * // unlock * MineInfo info; - * for (info.complete = false; !info.complete; info = mine()) {} + * for (info.completed = false; !info.completed; info = mine()) {} * } * // lock * completeMine(); diff --git a/test/TestHelper.cpp b/test/TestHelper.cpp index 5a579702a..3289305cd 100644 --- a/test/TestHelper.cpp +++ b/test/TestHelper.cpp @@ -487,6 +487,33 @@ void executeTests(const string& _name, const string& _testPathAppendix, std::fun } } +bytes createTransactionFromFields(json_spirit::mObject& _tObj) +{ + BOOST_REQUIRE(_tObj.count("data") > 0); + BOOST_REQUIRE(_tObj.count("value") > 0); + BOOST_REQUIRE(_tObj.count("gasPrice") > 0); + BOOST_REQUIRE(_tObj.count("gasLimit") > 0); + BOOST_REQUIRE(_tObj.count("nonce")> 0); + BOOST_REQUIRE(_tObj.count("to") > 0); + + BOOST_REQUIRE(_tObj.count("v") > 0); + BOOST_REQUIRE(_tObj.count("r") > 0); + BOOST_REQUIRE(_tObj.count("s") > 0); + + //Construct Rlp of the given transaction + RLPStream rlpStream; + rlpStream.appendList(9); + rlpStream << bigint(_tObj["nonce"].get_str()) << bigint(_tObj["gasPrice"].get_str()) << bigint(_tObj["gasLimit"].get_str()); + if (_tObj["to"].get_str().empty()) + rlpStream << ""; + else + rlpStream << Address(_tObj["to"].get_str()); + rlpStream << bigint(_tObj["value"].get_str()) << importData(_tObj); + rlpStream << bigint(_tObj["v"].get_str()) << bigint(_tObj["r"].get_str()) << bigint(_tObj["s"].get_str()); + + return rlpStream.out(); +} + void processCommandLineOptions() { diff --git a/test/TestHelper.h b/test/TestHelper.h index ae6ea20cc..344f61a3f 100644 --- a/test/TestHelper.h +++ b/test/TestHelper.h @@ -79,6 +79,7 @@ void checkCallCreates(eth::Transactions _resultCallCreates, eth::Transactions _e void executeTests(const std::string& _name, const std::string& _testPathAppendix, std::function doTests); std::string getTestPath(); void userDefinedTest(std::string testTypeFlag, std::function doTests); +bytes createTransactionFromFields(json_spirit::mObject& _tObj); void processCommandLineOptions(); eth::LastHashes lastHashes(u256 _currentBlockNumber); diff --git a/test/blFirstTestFiller.json b/test/blFirstTestFiller.json new file mode 100644 index 000000000..0084fda13 --- /dev/null +++ b/test/blFirstTestFiller.json @@ -0,0 +1,15 @@ +{ + "firstBlockTest" : { + "transactions": [{ + "nonce": "0", + "gasPrice": "0x09184e72a000", + "gasLimit": "0x0f3e6f", + "to": "", + "value": "", + "data": "0x60056013565b6101918061001d6000396000f35b3360008190555056006001600060e060020a6000350480630a874df61461003a57806341c0e1b514610058578063a02b161e14610066578063dbbdf0831461007757005b610045600435610149565b80600160a060020a031660005260206000f35b610060610161565b60006000f35b6100716004356100d4565b60006000f35b61008560043560243561008b565b60006000f35b600054600160a060020a031632600160a060020a031614156100ac576100b1565b6100d0565b8060018360005260205260406000208190555081600060005260206000a15b5050565b600054600160a060020a031633600160a060020a031614158015610118575033600160a060020a0316600182600052602052604060002054600160a060020a031614155b61012157610126565b610146565b600060018260005260205260406000208190555080600060005260206000a15b50565b60006001826000526020526040600020549050919050565b600054600160a060020a031633600160a060020a0316146101815761018f565b600054600160a060020a0316ff5b56", + "v": "0x1b", + "r": "0xd4287e915ebac7a8af390560fa53c8f0b7f13802ba0393d7afa5823c2560ca89", + "s": "0xae75db31a34f7e386ad459646de98ec3a1c88cc91b11620b4ffd86871f579942" + }] + } +} diff --git a/test/block.cpp b/test/block.cpp index 40984e8da..518b61238 100644 --- a/test/block.cpp +++ b/test/block.cpp @@ -20,6 +20,7 @@ * block test functions. */ +#include #include "TestHelper.h" using namespace std; @@ -116,40 +117,42 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) } else { - BOOST_REQUIRE(o.count("block") > 0); - - // construct Rlp of the given block - bytes blockRLP = createBlockRLPFromFields(o["block"].get_obj()); - RLP myRLP(blockRLP); - o["rlp"] = toHex(blockRLP); - - try - { - BlockInfo blockFromFields; - blockFromFields.populateFromHeader(myRLP, false); - (void)blockFromFields; - //blockFromFields.verifyInternals(blockRLP); - } - catch (Exception const& _e) - { - cnote << "block construction did throw an exception: " << diagnostic_information(_e); - BOOST_ERROR("Failed block construction Test with Exception: " << _e.what()); - o.erase(o.find("block")); - } - catch (std::exception const& _e) - { - cnote << "block construction did throw an exception: " << _e.what(); - BOOST_ERROR("Failed block construction Test with Exception: " << _e.what()); - o.erase(o.find("block")); - } - catch(...) - { - cnote << "block construction did throw an unknow exception\n"; - o.erase(o.find("block")); - } +// BOOST_REQUIRE(o.count("block") > 0); + +// // construct Rlp of the given block +// bytes blockRLP = createBlockRLPFromFields(o["block"].get_obj()); +// RLP myRLP(blockRLP); +// o["rlp"] = toHex(blockRLP); + +// try +// { +// BlockInfo blockFromFields; +// blockFromFields.populateFromHeader(myRLP, false); +// (void)blockFromFields; +// //blockFromFields.verifyInternals(blockRLP); +// } +// catch (Exception const& _e) +// { +// cnote << "block construction did throw an exception: " << diagnostic_information(_e); +// BOOST_ERROR("Failed block construction Test with Exception: " << _e.what()); +// o.erase(o.find("block")); +// } +// catch (std::exception const& _e) +// { +// cnote << "block construction did throw an exception: " << _e.what(); +// BOOST_ERROR("Failed block construction Test with Exception: " << _e.what()); +// o.erase(o.find("block")); +// } +// catch(...) +// { +// cnote << "block construction did throw an unknow exception\n"; +// o.erase(o.find("block")); +// } BOOST_REQUIRE(o.count("transactions") > 0); + TransactionQueue txs; + for (auto const& txObj: o["transactions"].get_array()) { mObject tx = txObj.get_obj(); @@ -162,12 +165,60 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) BOOST_REQUIRE(tx.count("r") > 0); BOOST_REQUIRE(tx.count("s") > 0); BOOST_REQUIRE(tx.count("data") > 0); + cout << "attempt to import transaction\n"; + txs.attemptImport(createTransactionFromFields(tx)); + } + cout << "done importing txs\n"; - Transaction txFromFields = createTransactionFromFields(tx); + //BOOST_REQUIRE(o.count("env") > 0); + //BOOST_REQUIRE(o.count("pre") > 0); + +// ImportTest importer; +// importer.importEnv(o["env"].get_obj()); +// importer.importState(o["pre"].get_obj(), m_statePre); + +// State theState = importer.m_statePre; +// bytes output; + + cout << "construct bc\n"; + CanonBlockChain bc(true); + cout << "construct state\n"; + State theState; + + try + { + cout << "sync bc and txs in state\n"; + theState.sync(bc,txs); + // lock + cout << "commit to mine\n"; + theState.commitToMine(bc); // will call uncommitToMine if a repeat. + // unlock + MineInfo info; + cout << "mine...\n"; + for (info.completed = false; !info.completed; info = theState.mine()) {} + cout << "done mining, completeMine\n"; + // lock + theState.completeMine(); + // unlock + + cout << "new block: " << theState.blockData() << endl << theState.info() << endl; + } + catch (Exception const& _e) + { + cnote << "state sync did throw an exception: " << diagnostic_information(_e); + } + catch (std::exception const& _e) + { + cnote << "state sync did throw an exception: " << _e.what(); + } + + // write block and rlp to json + + //TODO if block rlp is invalid, delete transactions, and block + - } } } } @@ -177,48 +228,48 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) BOOST_AUTO_TEST_SUITE(BlockTests) -BOOST_AUTO_TEST_CASE(blValidBlocksTest) -{ - dev::test::executeTests("blValidBlockTest", "/BlockTests", dev::test::doBlockTests); -} - -BOOST_AUTO_TEST_CASE(ttCreateTest) +BOOST_AUTO_TEST_CASE(blFirstTest) { - for (int i = 1; i < boost::unit_test::framework::master_test_suite().argc; ++i) - { - string arg = boost::unit_test::framework::master_test_suite().argv[i]; - if (arg == "--createtest") - { - if (boost::unit_test::framework::master_test_suite().argc <= i + 2) - { - cnote << "usage: ./testeth --createtest \n"; - return; - } - try - { - cnote << "Populating tests..."; - json_spirit::mValue v; - string s = asString(dev::contents(boost::unit_test::framework::master_test_suite().argv[i + 1])); - BOOST_REQUIRE_MESSAGE(s.length() > 0, "Content of " + (string)boost::unit_test::framework::master_test_suite().argv[i + 1] + " is empty."); - json_spirit::read_string(s, v); - dev::test::doBlockTests(v, true); - writeFile(boost::unit_test::framework::master_test_suite().argv[i + 2], asBytes(json_spirit::write_string(v, true))); - } - catch (Exception const& _e) - { - BOOST_ERROR("Failed block test with Exception: " << diagnostic_information(_e)); - } - catch (std::exception const& _e) - { - BOOST_ERROR("Failed block test with Exception: " << _e.what()); - } - } - } + dev::test::executeTests("blFirstTest", "/BlockTests", dev::test::doBlockTests); } -BOOST_AUTO_TEST_CASE(userDefinedFileTT) -{ - dev::test::userDefinedTest("--bltest", dev::test::doBlockTests); -} +//BOOST_AUTO_TEST_CASE(ttCreateTest) +//{ +// for (int i = 1; i < boost::unit_test::framework::master_test_suite().argc; ++i) +// { +// string arg = boost::unit_test::framework::master_test_suite().argv[i]; +// if (arg == "--createtest") +// { +// if (boost::unit_test::framework::master_test_suite().argc <= i + 2) +// { +// cnote << "usage: ./testeth --createtest \n"; +// return; +// } +// try +// { +// cnote << "Populating tests..."; +// json_spirit::mValue v; +// string s = asString(dev::contents(boost::unit_test::framework::master_test_suite().argv[i + 1])); +// BOOST_REQUIRE_MESSAGE(s.length() > 0, "Content of " + (string)boost::unit_test::framework::master_test_suite().argv[i + 1] + " is empty."); +// json_spirit::read_string(s, v); +// dev::test::doBlockTests(v, true); +// writeFile(boost::unit_test::framework::master_test_suite().argv[i + 2], asBytes(json_spirit::write_string(v, true))); +// } +// catch (Exception const& _e) +// { +// BOOST_ERROR("Failed block test with Exception: " << diagnostic_information(_e)); +// } +// catch (std::exception const& _e) +// { +// BOOST_ERROR("Failed block test with Exception: " << _e.what()); +// } +// } +// } +//} + +//BOOST_AUTO_TEST_CASE(userDefinedFileTT) +//{ +// dev::test::userDefinedTest("--bltest", dev::test::doBlockTests); +//} BOOST_AUTO_TEST_SUITE_END() diff --git a/test/transaction.cpp b/test/transaction.cpp index e1e275302..00de5fb23 100644 --- a/test/transaction.cpp +++ b/test/transaction.cpp @@ -29,33 +29,6 @@ using namespace dev::eth; namespace dev { namespace test { -Transaction createTransactionFromFields(mObject& _tObj) -{ - BOOST_REQUIRE(_tObj.count("data") > 0); - BOOST_REQUIRE(_tObj.count("value") > 0); - BOOST_REQUIRE(_tObj.count("gasPrice") > 0); - BOOST_REQUIRE(_tObj.count("gasLimit") > 0); - BOOST_REQUIRE(_tObj.count("nonce")> 0); - BOOST_REQUIRE(_tObj.count("to") > 0); - - BOOST_REQUIRE(_tObj.count("v") > 0); - BOOST_REQUIRE(_tObj.count("r") > 0); - BOOST_REQUIRE(_tObj.count("s") > 0); - - //Construct Rlp of the given transaction - RLPStream rlpStream; - rlpStream.appendList(9); - rlpStream << bigint(_tObj["nonce"].get_str()) << bigint(_tObj["gasPrice"].get_str()) << bigint(_tObj["gasLimit"].get_str()); - if (_tObj["to"].get_str().empty()) - rlpStream << ""; - else - rlpStream << Address(_tObj["to"].get_str()); - rlpStream << bigint(_tObj["value"].get_str()) << importData(_tObj); - rlpStream << bigint(_tObj["v"].get_str()) << bigint(_tObj["r"].get_str()) << bigint(_tObj["s"].get_str()); - - return Transaction(rlpStream.out(), CheckSignature::Sender); -} - void doTransactionTests(json_spirit::mValue& _v, bool _fillin) { for (auto& i: _v.get_obj()) @@ -84,7 +57,8 @@ void doTransactionTests(json_spirit::mValue& _v, bool _fillin) BOOST_REQUIRE(o.count("transaction") > 0); mObject tObj = o["transaction"].get_obj(); - Transaction txFromFields = createTransactionFromFields(tObj); + bytes txRLP = createTransactionFromFields(tObj); + Transaction txFromFields(txRLP, CheckSignature::Sender); //Check the fields restored from RLP to original fields BOOST_CHECK_MESSAGE(txFromFields.data() == txFromRlp.data(), "Data in given RLP not matching the Transaction data!"); From fc15ac8071ccce6724b1ec33ff1bf2907f72dcfd Mon Sep 17 00:00:00 2001 From: subtly Date: Fri, 6 Feb 2015 14:58:23 -0800 Subject: [PATCH 044/213] update remaining whisper tests --- test/whisperTopic.cpp | 48 +++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/test/whisperTopic.cpp b/test/whisperTopic.cpp index d2f2d9d89..ab0cdc115 100644 --- a/test/whisperTopic.cpp +++ b/test/whisperTopic.cpp @@ -209,19 +209,19 @@ BOOST_AUTO_TEST_CASE(asyncforwarding) unsigned result = 0; bool done = false; + + // Host must be configured not to share peers. + Host host1("Forwarder", NetworkPreferences(30305, "", false, true)); + host1.setIdealPeerCount(1); + auto whost1 = host1.registerCapability(new WhisperHost()); + host1.start(); + while (!host1.isStarted()) + this_thread::sleep_for(chrono::milliseconds(2)); - Public listenerid; bool startedForwarder = false; std::thread forwarder([&]() { setThreadName("forwarder"); - - // Host must be configured not to share peers. - Host ph("Forwarder", NetworkPreferences(30305, "", false, true)); - ph.setIdealPeerCount(0); - auto wh = ph.registerCapability(new WhisperHost()); - this_thread::sleep_for(chrono::milliseconds(500)); - ph.start(); this_thread::sleep_for(chrono::milliseconds(500)); // ph.addNode("127.0.0.1", 30303, 30303); @@ -229,13 +229,13 @@ BOOST_AUTO_TEST_CASE(asyncforwarding) startedForwarder = true; /// Only interested in odd packets - auto w = wh->installWatch(BuildTopicMask("test")); + auto w = whost1->installWatch(BuildTopicMask("test")); while (!done) { - for (auto i: wh->checkWatch(w)) + for (auto i: whost1->checkWatch(w)) { - Message msg = wh->envelope(i).open(wh->fullTopic(w)); + Message msg = whost1->envelope(i).open(whost1->fullTopic(w)); cnote << "New message from:" << msg.from().abridged() << RLP(msg.payload()).toInt(); } this_thread::sleep_for(chrono::milliseconds(50)); @@ -245,28 +245,28 @@ BOOST_AUTO_TEST_CASE(asyncforwarding) while (!startedForwarder) this_thread::sleep_for(chrono::milliseconds(50)); + Host host2("Sender", NetworkPreferences(30300, "", false, true)); + host2.setIdealPeerCount(1); + shared_ptr whost2 = host2.registerCapability(new WhisperHost()); + host2.start(); + while (!host2.isStarted()) + this_thread::sleep_for(chrono::milliseconds(2)); + host2.addNode(host1.id(), "127.0.0.1", 30305, 30305); + { - Host ph("Sender", NetworkPreferences(30300, "", false, true)); - ph.setIdealPeerCount(0); - shared_ptr wh = ph.registerCapability(new WhisperHost()); - this_thread::sleep_for(chrono::milliseconds(500)); - ph.start(); - this_thread::sleep_for(chrono::milliseconds(500)); -// ph.addNode("127.0.0.1", 30305, 30305); - KeyPair us = KeyPair::create(); - wh->post(us.sec(), RLPStream().append(1).out(), BuildTopic("test")); + whost2->post(us.sec(), RLPStream().append(1).out(), BuildTopic("test")); this_thread::sleep_for(chrono::milliseconds(250)); } { Host ph("Listener", NetworkPreferences(30300, "", false, true)); - ph.setIdealPeerCount(0); + ph.setIdealPeerCount(1); shared_ptr wh = ph.registerCapability(new WhisperHost()); - this_thread::sleep_for(chrono::milliseconds(500)); ph.start(); - this_thread::sleep_for(chrono::milliseconds(500)); -// ph.addNode("127.0.0.1", 30305, 30305); + while (!ph.isStarted()) + this_thread::sleep_for(chrono::milliseconds(2)); + ph.addNode(host1.id(), "127.0.0.1", 30305, 30305); /// Only interested in odd packets auto w = wh->installWatch(BuildTopicMask("test")); From eae64afe21c97cf4e76e7d52875e8538f1e675a2 Mon Sep 17 00:00:00 2001 From: subtly Date: Fri, 6 Feb 2015 16:49:35 -0800 Subject: [PATCH 045/213] update packet test --- test/net.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/net.cpp b/test/net.cpp index 5a7e56d23..5039c5436 100644 --- a/test/net.cpp +++ b/test/net.cpp @@ -152,7 +152,7 @@ BOOST_AUTO_TEST_CASE(test_neighbours_packet) out.sign(k.sec()); bytesConstRef packet(out.data.data(), out.data.size()); - bytesConstRef rlpBytes(packet.cropped(97, packet.size() - 97)); + bytesConstRef rlpBytes(packet.cropped(h256::size + Signature::size + 1)); Neighbours in = Neighbours::fromBytesConstRef(to, rlpBytes); int count = 0; for (auto n: in.nodes) From d6ebb4454b60d8e8bfdb4bb0f3fac703606335b7 Mon Sep 17 00:00:00 2001 From: winsvega Date: Sat, 7 Feb 2015 14:23:17 +0300 Subject: [PATCH 046/213] Style Changes New exception for values larger than 2**256 Auto format .json files --- libdevcore/Exceptions.h | 1 + test/TestHelper.cpp | 13 +- test/stInitCodeTestFiller.json | 154 +++++++++++------------ test/stTransactionTestFiller.json | 154 +++++++++++------------ test/transaction.cpp | 2 +- test/ttTransactionTestFiller.json | 198 +++++++++++++++--------------- 6 files changed, 261 insertions(+), 261 deletions(-) diff --git a/libdevcore/Exceptions.h b/libdevcore/Exceptions.h index e13d41476..961fc6f4c 100644 --- a/libdevcore/Exceptions.h +++ b/libdevcore/Exceptions.h @@ -33,6 +33,7 @@ namespace dev // base class for all exceptions struct Exception: virtual std::exception, virtual boost::exception { mutable std::string m_message; }; +struct ValueTooLarge: virtual Exception {}; struct BadHexCharacter: virtual Exception {}; struct RLPException: virtual Exception {}; struct BadCast: virtual RLPException {}; diff --git a/test/TestHelper.cpp b/test/TestHelper.cpp index fc05de85a..fbb302f15 100644 --- a/test/TestHelper.cpp +++ b/test/TestHelper.cpp @@ -110,9 +110,9 @@ void ImportTest::importState(json_spirit::mObject& _o, State& _state) bigint biValue256 = bigint("115792089237316195423570985008687907853269984665640564039457584007913129639936"); if (bigint(o["balance"].get_str()) >= biValue256) - BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("State 'balance' is equal or greater than 2**256") ); + BOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("State 'balance' is equal or greater than 2**256") ); if (bigint(o["nonce"].get_str()) >= biValue256) - BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("State 'nonce' is equal or greater than 2**256") ); + BOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("State 'nonce' is equal or greater than 2**256") ); Address address = Address(i.first); @@ -148,14 +148,13 @@ void ImportTest::importTransaction(json_spirit::mObject& _o) bigint biValue256 = bigint("115792089237316195423570985008687907853269984665640564039457584007913129639936"); if (bigint(_o["nonce"].get_str()) >= biValue256) - BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("Transaction 'nonce' is equal or greater than 2**256") ); + BOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("Transaction 'nonce' is equal or greater than 2**256") ); if (bigint(_o["gasPrice"].get_str()) >= biValue256) - BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("Transaction 'gasPrice' is equal or greater than 2**256") ); + BOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("Transaction 'gasPrice' is equal or greater than 2**256") ); if (bigint(_o["gasLimit"].get_str()) >= biValue256) - BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("Transaction 'gasLimit' is equal or greater than 2**256") ); + BOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("Transaction 'gasLimit' is equal or greater than 2**256") ); if (bigint(_o["value"].get_str()) >= biValue256) - BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("Transaction 'value' is equal or greater than 2**256") ); - + BOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("Transaction 'value' is equal or greater than 2**256") ); m_transaction = _o["to"].get_str().empty() ? Transaction(toInt(_o["value"]), toInt(_o["gasPrice"]), toInt(_o["gasLimit"]), importData(_o), toInt(_o["nonce"]), Secret(_o["secretKey"].get_str())) : diff --git a/test/stInitCodeTestFiller.json b/test/stInitCodeTestFiller.json index 0996bd6a2..134d75198 100644 --- a/test/stInitCodeTestFiller.json +++ b/test/stInitCodeTestFiller.json @@ -19,7 +19,7 @@ } }, "transaction" : - { + { "data" : "0x600a80600c6000396000f200600160008035811a8100", "gasLimit" : "599", "gasPrice" : "1", @@ -51,7 +51,7 @@ } }, "transaction" : - { + { "data" : "0x600a80600c6000396000f200600160008035811a8100", "gasLimit" : "599", "gasPrice" : "1", @@ -62,7 +62,7 @@ } }, - "OutOfGasContractCreation" : { + "OutOfGasContractCreation" : { "env" : { "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", "currentDifficulty" : "45678256", @@ -82,7 +82,7 @@ } }, "transaction" : - { + { "data" : "0x600a80600c6000396000f200600160008035811a8100", "gasLimit" : "590", "gasPrice" : "3", @@ -92,7 +92,7 @@ "value" : "1" } }, - "StackUnderFlowContractCreation" : { + "StackUnderFlowContractCreation" : { "env" : { "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", "currentDifficulty" : "45678256", @@ -112,7 +112,7 @@ } }, "transaction" : - { + { "data" : "0x6000f1", "gasLimit" : "1000", "gasPrice" : "1", @@ -123,7 +123,7 @@ } }, - "TransactionSuicideInitCode" : { + "TransactionSuicideInitCode" : { "env" : { "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", "currentDifficulty" : "45678256", @@ -143,7 +143,7 @@ } }, "transaction" : - { + { "data" : "0x600a80600c6000396000fff2ffff600160008035811a81", "gasLimit" : "1000", "gasPrice" : "1", @@ -154,7 +154,7 @@ } }, - "TransactionStopInitCode" : { + "TransactionStopInitCode" : { "env" : { "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", "currentDifficulty" : "45678256", @@ -174,7 +174,7 @@ } }, "transaction" : - { + { "data" : "0x600a80600c600039600000f20000600160008035811a81", "gasLimit" : "1000", "gasPrice" : "1", @@ -185,7 +185,7 @@ } }, - "TransactionCreateSuicideContract" : { + "TransactionCreateSuicideContract" : { "env" : { "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", "currentDifficulty" : "45678256", @@ -205,7 +205,7 @@ } }, "transaction" : - { + { "data" : "0x600a80600c6000396000f200ff600160008035811a81", "gasLimit" : "1000", "gasPrice" : "1", @@ -216,7 +216,7 @@ } }, - "CallTheContractToCreateEmptyContract" : { + "CallTheContractToCreateEmptyContract" : { "env" : { "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", "currentDifficulty" : "45678256", @@ -227,12 +227,12 @@ }, "pre" : { - "095e7baea6a6c7c4c2dfeb977efac326af552d87": { - "balance": "0", - "nonce": "0", - "code": "{(CREATE 0 0 32)}", - "storage": {} - }, + "095e7baea6a6c7c4c2dfeb977efac326af552d87": { + "balance": "0", + "nonce": "0", + "code": "{(CREATE 0 0 32)}", + "storage": {} + }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "100000", @@ -243,7 +243,7 @@ } }, "transaction" : - { + { "data" : "0x00", "gasLimit" : "10000", "gasPrice" : "1", @@ -254,7 +254,7 @@ } }, - "CallRecursiveContract" : { + "CallRecursiveContract" : { "env" : { "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", "currentDifficulty" : "45678256", @@ -265,12 +265,12 @@ }, "pre" : { - "095e7baea6a6c7c4c2dfeb977efac326af552d87": { - "balance": "0", - "nonce": "0", - "code": "{[[ 2 ]](ADDRESS)(CODECOPY 0 0 32)(CREATE 0 0 32)}", - "storage": {} - }, + "095e7baea6a6c7c4c2dfeb977efac326af552d87": { + "balance": "0", + "nonce": "0", + "code": "{[[ 2 ]](ADDRESS)(CODECOPY 0 0 32)(CREATE 0 0 32)}", + "storage": {} + }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "100000", @@ -281,7 +281,7 @@ } }, "transaction" : - { + { "data" : "0x00", "gasLimit" : "10000", "gasPrice" : "1", @@ -292,7 +292,7 @@ } }, - "CallContractToCreateContractWhichWouldCreateContractInInitCode" : { + "CallContractToCreateContractWhichWouldCreateContractInInitCode" : { "env" : { "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", "currentDifficulty" : "45678256", @@ -303,13 +303,13 @@ }, "pre" : { - "095e7baea6a6c7c4c2dfeb977efac326af552d87": { - "balance": "1", - "nonce": "0", - "//": "{[[0]] 12 (CREATE 0 64 32)}", - "code": "{(MSTORE 0 0x600c600055602060406000f0)(CREATE 0 20 12)}", - "storage": {} - }, + "095e7baea6a6c7c4c2dfeb977efac326af552d87": { + "balance": "1", + "nonce": "0", + "//": "{[[0]] 12 (CREATE 0 64 32)}", + "code": "{(MSTORE 0 0x600c600055602060406000f0)(CREATE 0 20 12)}", + "storage": {} + }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "100000000", @@ -320,7 +320,7 @@ } }, "transaction" : - { + { "data" : "0x00", "gasLimit" : "20000000", "gasPrice" : "1", @@ -331,7 +331,7 @@ } }, - "CallContractToCreateContractWhichWouldCreateContractIfCalled" : { + "CallContractToCreateContractWhichWouldCreateContractIfCalled" : { "env" : { "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", "currentDifficulty" : "45678256", @@ -342,14 +342,14 @@ }, "pre" : { - "095e7baea6a6c7c4c2dfeb977efac326af552d87": { - "balance": "1000", - "nonce": "0", - "//": "(CREATE 0 64 32)", - "//": "{[[0]] 12 (MSTORE 32 0x602060406000f0)(RETURN 57 7)}", - "code": "{(MSTORE 0 0x600c60005566602060406000f060205260076039f3)[[0]](CREATE 1 11 21)(CALL 500 (SLOAD 0) 1 0 0 0 0)}", - "storage": {} - }, + "095e7baea6a6c7c4c2dfeb977efac326af552d87": { + "balance": "1000", + "nonce": "0", + "//": "(CREATE 0 64 32)", + "//": "{[[0]] 12 (MSTORE 32 0x602060406000f0)(RETURN 57 7)}", + "code": "{(MSTORE 0 0x600c60005566602060406000f060205260076039f3)[[0]](CREATE 1 11 21)(CALL 500 (SLOAD 0) 1 0 0 0 0)}", + "storage": {} + }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "100000000", @@ -360,7 +360,7 @@ } }, "transaction" : - { + { "data" : "0x00", "gasLimit" : "20000000", "gasPrice" : "1", @@ -371,7 +371,7 @@ } }, - "CallContractToCreateContractOOG" : { + "CallContractToCreateContractOOG" : { "env" : { "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", "currentDifficulty" : "45678256", @@ -382,14 +382,14 @@ }, "pre" : { - "095e7baea6a6c7c4c2dfeb977efac326af552d87": { - "balance": "0", - "nonce": "0", - "//": "(CREATE 0 64 32)", - "//": "{[[0]] 12 (MSTORE 32 0x602060406000f0)(RETURN 57 7)}", - "code": "{(MSTORE 0 0x600c60005566602060406000f060205260076039f3)[[0]](CREATE 1 11 21)(CALL 0 (SLOAD 0) 0 0 0 0 0)}", - "storage": {} - }, + "095e7baea6a6c7c4c2dfeb977efac326af552d87": { + "balance": "0", + "nonce": "0", + "//": "(CREATE 0 64 32)", + "//": "{[[0]] 12 (MSTORE 32 0x602060406000f0)(RETURN 57 7)}", + "code": "{(MSTORE 0 0x600c60005566602060406000f060205260076039f3)[[0]](CREATE 1 11 21)(CALL 0 (SLOAD 0) 0 0 0 0 0)}", + "storage": {} + }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "100000000", @@ -400,7 +400,7 @@ } }, "transaction" : - { + { "data" : "0x00", "gasLimit" : "20000000", "gasPrice" : "1", @@ -411,7 +411,7 @@ } }, - "CallContractToCreateContractAndCallItOOG" : { + "CallContractToCreateContractAndCallItOOG" : { "env" : { "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", "currentDifficulty" : "45678256", @@ -422,14 +422,14 @@ }, "pre" : { - "095e7baea6a6c7c4c2dfeb977efac326af552d87": { - "balance": "1000", - "nonce": "0", - "//": "(CREATE 0 64 32)", - "//": "{[[0]] 12 (MSTORE 32 0x602060406000f0)(RETURN 57 7)}", - "code": "{(MSTORE 0 0x600c60005566602060406000f060205260076039f3)[[0]](CREATE 1 11 21)(CALL 0 (SLOAD 0) 1 0 0 0 0)}", - "storage": {} - }, + "095e7baea6a6c7c4c2dfeb977efac326af552d87": { + "balance": "1000", + "nonce": "0", + "//": "(CREATE 0 64 32)", + "//": "{[[0]] 12 (MSTORE 32 0x602060406000f0)(RETURN 57 7)}", + "code": "{(MSTORE 0 0x600c60005566602060406000f060205260076039f3)[[0]](CREATE 1 11 21)(CALL 0 (SLOAD 0) 1 0 0 0 0)}", + "storage": {} + }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "100000000", @@ -440,7 +440,7 @@ } }, "transaction" : - { + { "data" : "0x00", "gasLimit" : "20000000", "gasPrice" : "1", @@ -451,7 +451,7 @@ } }, - "CallContractToCreateContractNoCash" : { + "CallContractToCreateContractNoCash" : { "env" : { "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", "currentDifficulty" : "45678256", @@ -462,14 +462,14 @@ }, "pre" : { - "095e7baea6a6c7c4c2dfeb977efac326af552d87": { - "balance": "1000", - "nonce": "0", - "//": "(CREATE 0 64 32)", - "//": "{[[0]] 12 (MSTORE 32 0x602060406000f0)(RETURN 57 7)}", - "code": "{(MSTORE 0 0x600c60005566602060406000f060205260076039f3)[[0]](CREATE 1001 11 21)}", - "storage": {} - }, + "095e7baea6a6c7c4c2dfeb977efac326af552d87": { + "balance": "1000", + "nonce": "0", + "//": "(CREATE 0 64 32)", + "//": "{[[0]] 12 (MSTORE 32 0x602060406000f0)(RETURN 57 7)}", + "code": "{(MSTORE 0 0x600c60005566602060406000f060205260076039f3)[[0]](CREATE 1001 11 21)}", + "storage": {} + }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "100000000", @@ -480,7 +480,7 @@ } }, "transaction" : - { + { "data" : "0x00", "gasLimit" : "20000000", "gasPrice" : "1", diff --git a/test/stTransactionTestFiller.json b/test/stTransactionTestFiller.json index 878aed0d1..cf132b0da 100644 --- a/test/stTransactionTestFiller.json +++ b/test/stTransactionTestFiller.json @@ -19,7 +19,7 @@ } }, "transaction" : - { + { "data" : "", "gasLimit" : "", "gasPrice" : "", @@ -50,7 +50,7 @@ } }, "transaction" : - { + { "data" : "", "gasLimit" : "500", "gasPrice" : "1", @@ -82,7 +82,7 @@ } }, "transaction" : - { + { "data" : "", "gasLimit" : "5000", "gasPrice" : "1", @@ -114,7 +114,7 @@ } }, "transaction" : - { + { "data" : "", "gasLimit" : "5000", "gasPrice" : "1", @@ -146,7 +146,7 @@ } }, "transaction" : - { + { "data" : "", "gasLimit" : "600", "gasPrice" : "1", @@ -178,7 +178,7 @@ } }, "transaction" : - { + { "data" : "", "gasLimit" : "600", "gasPrice" : "1", @@ -213,22 +213,22 @@ "code" : "{(SSTORE 0 0)(SSTORE 1 0)(SSTORE 2 0)(SSTORE 3 0)(SSTORE 4 0)(SSTORE 5 0)(SSTORE 6 0)(SSTORE 7 0)(SSTORE 8 0)(SSTORE 9 0)}", "nonce" : "0", "storage" : { - "0x" : "0x0c", + "0x" : "0x0c", "0x01" : "0x0c", - "0x02" : "0x0c", - "0x03" : "0x0c", - "0x04" : "0x0c", - "0x05" : "0x0c", - "0x06" : "0x0c", - "0x07" : "0x0c", - "0x08" : "0x0c", - "0x09" : "0x0c" - } + "0x02" : "0x0c", + "0x03" : "0x0c", + "0x04" : "0x0c", + "0x05" : "0x0c", + "0x06" : "0x0c", + "0x07" : "0x0c", + "0x08" : "0x0c", + "0x09" : "0x0c" + } } }, "transaction" : - { + { "data" : "", "gasLimit" : "600", "gasPrice" : "1", @@ -263,22 +263,22 @@ "code" : "{(SSTORE 0 0)(SSTORE 1 0)(SSTORE 2 0)(SSTORE 3 0)(SSTORE 4 0)(SSTORE 5 0)(SSTORE 6 0)(SSTORE 7 0)(SSTORE 8 0)(SSTORE 9 12)}", "nonce" : "0", "storage" : { - "0x" : "0x0c", + "0x" : "0x0c", "0x01" : "0x0c", - "0x02" : "0x0c", - "0x03" : "0x0c", - "0x04" : "0x0c", - "0x05" : "0x0c", - "0x06" : "0x0c", - "0x07" : "0x0c", - "0x08" : "0x0c", - "0x09" : "0x0c" - } + "0x02" : "0x0c", + "0x03" : "0x0c", + "0x04" : "0x0c", + "0x05" : "0x0c", + "0x06" : "0x0c", + "0x07" : "0x0c", + "0x08" : "0x0c", + "0x09" : "0x0c" + } } }, "transaction" : - { + { "data" : "", "gasLimit" : "600", "gasPrice" : "1", @@ -308,9 +308,9 @@ } }, - "c94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "c94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "10", - "//" : "gas = 19 going OOG, gas = 20 fine", + "//" : "gas = 19 going OOG, gas = 20 fine", "code" : "{ (CALL 19 0 1 0 0 0 0) }", "nonce" : "0", "storage" : { @@ -322,23 +322,23 @@ "code" : "{(SSTORE 0 0)(SSTORE 1 0)(SSTORE 2 0)(SSTORE 3 0)(SSTORE 4 0)(SSTORE 5 0)(SSTORE 6 0)(SSTORE 7 0)(SSTORE 8 0)(SSTORE 9 0)}", "nonce" : "0", "storage" : { - "0x" : "0x0c", + "0x" : "0x0c", "0x01" : "0x0c", - "0x02" : "0x0c", - "0x03" : "0x0c", - "0x04" : "0x0c", - "0x05" : "0x0c", - "0x06" : "0x0c", - "0x07" : "0x0c", - "0x08" : "0x0c", - "0x09" : "0x0c" - } + "0x02" : "0x0c", + "0x03" : "0x0c", + "0x04" : "0x0c", + "0x05" : "0x0c", + "0x06" : "0x0c", + "0x07" : "0x0c", + "0x08" : "0x0c", + "0x09" : "0x0c" + } } }, "transaction" : - { + { "data" : "", "gasLimit" : "700", "gasPrice" : "1", @@ -368,7 +368,7 @@ } }, - "c94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "c94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "10", "//" : "gas = 19 going OOG, gas = 20 fine", "code" : "{(SSTORE 0 0)(SSTORE 1 0)(SSTORE 2 0)(SSTORE 3 0) (CALL 19 0 1 0 0 0 0) }", @@ -379,7 +379,7 @@ "0x02" : "0x0c", "0x03" : "0x0c", "0x04" : "0x0c" - } + } }, "0000000000000000000000000000000000000000" : { @@ -387,23 +387,23 @@ "code" : "{(SSTORE 0 0)(SSTORE 1 0)(SSTORE 2 0)(SSTORE 3 0)(SSTORE 4 0)(SSTORE 5 0)(SSTORE 6 0)(SSTORE 7 0)(SSTORE 8 0)(SSTORE 9 0)}", "nonce" : "0", "storage" : { - "0x" : "0x0c", + "0x" : "0x0c", "0x01" : "0x0c", - "0x02" : "0x0c", - "0x03" : "0x0c", - "0x04" : "0x0c", - "0x05" : "0x0c", - "0x06" : "0x0c", - "0x07" : "0x0c", - "0x08" : "0x0c", - "0x09" : "0x0c" - } + "0x02" : "0x0c", + "0x03" : "0x0c", + "0x04" : "0x0c", + "0x05" : "0x0c", + "0x06" : "0x0c", + "0x07" : "0x0c", + "0x08" : "0x0c", + "0x09" : "0x0c" + } } }, "transaction" : - { + { "data" : "", "gasLimit" : "700", "gasPrice" : "1", @@ -414,7 +414,7 @@ } }, - "TransactionNonceCheck" : { + "TransactionNonceCheck" : { "env" : { "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", "currentDifficulty" : "45678256", @@ -434,7 +434,7 @@ } }, "transaction" : - { + { "data" : "", "gasLimit" : "1000", "gasPrice" : "1", @@ -465,7 +465,7 @@ } }, "transaction" : - { + { "data" : "", "gasLimit" : "1000", "gasPrice" : "1", @@ -496,7 +496,7 @@ } }, "transaction" : - { + { "data" : "0x00000000000000000000112233445566778f32", "gasLimit" : "1000", "gasPrice" : "1", @@ -526,7 +526,7 @@ } }, - "b94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "b94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "115792089237316195423570985008687907853269984665640564039457584007913129639935", "code" : "", "nonce" : "0", @@ -535,7 +535,7 @@ } }, "transaction" : - { + { "data" : "", "gasLimit" : "1000", "gasPrice" : "1", @@ -561,13 +561,13 @@ "balance" : "100000", "code" : "", "nonce" : "115792089237316195423570985008687907853269984665640564039457584007913129639935", - "nonce" : "10000000", + "nonce" : "10000000", "storage" : { } } }, "transaction" : - { + { "data" : "", "gasLimit" : "1000", "gasPrice" : "1", @@ -579,7 +579,7 @@ } }, - "UserTransactionZeroCost" : { + "UserTransactionZeroCost" : { "env" : { "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", "currentDifficulty" : "45678256", @@ -599,7 +599,7 @@ } }, "transaction" : - { + { "data" : "", "gasLimit" : "5100", "gasPrice" : "0", @@ -630,7 +630,7 @@ } }, "transaction" : - { + { "data" : "", "gasLimit" : "12", "gasPrice" : "0", @@ -661,7 +661,7 @@ } }, "transaction" : - { + { "data" : "0x3240349548983454", "gasLimit" : "500", "gasPrice" : "0", @@ -676,7 +676,7 @@ "env" : { "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", "currentDifficulty" : "45678256", - "currentGasLimit" : "(2**256)-1", + "currentGasLimit" : "(2**256)-1", "currentGasLimit" : "115792089237316195423570985008687907853269984665640564039457584007913129639935", "currentNumber" : "0", "currentTimestamp" : 1, @@ -693,9 +693,9 @@ } }, "transaction" : - { + { "data" : "0x3240349548983454", - "gasLimit" : "2**200", + "gasLimit" : "2**200", "gasLimit" : "1606938044258990275541962092341162602522202993782792835301376", "gasPrice" : "2**56-1", "gasPrice" : "72057594037927935", @@ -710,7 +710,7 @@ "env" : { "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", "currentDifficulty" : "45678256", - "currentGasLimit" : "(2**256)-1", + "currentGasLimit" : "(2**256)-1", "currentGasLimit" : "115792089237316195423570985008687907853269984665640564039457584007913129639935", "currentNumber" : "0", "currentTimestamp" : 1, @@ -727,9 +727,9 @@ } }, "transaction" : - { + { "data" : "0x3240349548983454", - "gasLimit" : "2**200", + "gasLimit" : "2**200", "gasLimit" : "1606938044258990275541962092341162602522202993782792835301376", "gasPrice" : "(2**56)*10", "gasPrice" : "720575940379279360", @@ -744,7 +744,7 @@ "env" : { "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", "currentDifficulty" : "45678256", - "currentGasLimit" : "(2**256)-1", + "currentGasLimit" : "(2**256)-1", "currentGasLimit" : "115792089237316195423570985008687907853269984665640564039457584007913129639935", "currentNumber" : "0", "currentTimestamp" : 1, @@ -761,9 +761,9 @@ } }, "transaction" : - { + { "data" : "", - "gasLimit" : "(2**256+400)/20", + "gasLimit" : "(2**256+400)/20", "gasLimit" : "5789604461865809771178549250434395392663499233282028201972879200395656482016", "gasPrice" : "20", "nonce" : "0", @@ -793,13 +793,13 @@ } }, "transaction" : - { + { "data" : "", "gasLimit" : "1000", "gasPrice" : "1", "nonce" : "0", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "0xffffffffffffffffffffffffffffffffffffffff", + "to" : "0xffffffffffffffffffffffffffffffffffffffff", "value" : "100" } } diff --git a/test/transaction.cpp b/test/transaction.cpp index ddd7c3dc4..b51494d84 100644 --- a/test/transaction.cpp +++ b/test/transaction.cpp @@ -100,7 +100,7 @@ void doTransactionTests(json_spirit::mValue& _v, bool _fillin) BOOST_REQUIRE(o.count("transaction") > 0); mObject tObj = o["transaction"].get_obj(); - Transaction txFromFields(createRLPStreamFromTransactionFields(tObj).out(),CheckSignature::Sender); + Transaction txFromFields(createRLPStreamFromTransactionFields(tObj).out(), CheckSignature::Sender); //Check the fields restored from RLP to original fields BOOST_CHECK_MESSAGE(txFromFields.data() == txFromRlp.data(), "Data in given RLP not matching the Transaction data!"); diff --git a/test/ttTransactionTestFiller.json b/test/ttTransactionTestFiller.json index 26f32271e..49831261a 100644 --- a/test/ttTransactionTestFiller.json +++ b/test/ttTransactionTestFiller.json @@ -1,303 +1,303 @@ { "RightVRSTest" : { "transaction" : - { + { "data" : "0x5544", "gasLimit" : "2000", "gasPrice" : "1", "nonce" : "3", "to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", "value" : "10", - "v" : "28", - "r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", - "s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" + "v" : "28", + "r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", + "s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" } }, "WrongVRSTestVl27" : { "transaction" : - { + { "data" : "", "gasLimit" : "2000", "gasPrice" : "1", "nonce" : "0", "to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", "value" : "10", - "v" : "26", - "r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", - "s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" + "v" : "26", + "r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", + "s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" } }, "WrongVRSTestVge31" : { "transaction" : - { + { "data" : "", "gasLimit" : "2000", "gasPrice" : "1", "nonce" : "0", "to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", "value" : "10", - "v" : "31", - "r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", - "s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" + "v" : "31", + "r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", + "s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" } }, - "SenderTest" : { - "//" : "sender a94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "SenderTest" : { + "//" : "sender a94f5374fce5edbc8e2a8697c15331677e6ebf0b", "transaction" : - { + { "data" : "", "gasLimit" : "850", "gasPrice" : "1", "nonce" : "0", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "10", - "v" : "27", - "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", - "s" : "secretkey 45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" + "v" : "27", + "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", + "s" : "secretkey 45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" } }, - "TransactionWithTooManyRLPElements" : { + "TransactionWithTooManyRLPElements" : { "transaction" : - { + { "data" : "", "gasLimit" : "850", "gasPrice" : "1", "nonce" : "0", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "10", - "v" : "27", - "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", - "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", - "extrafield" : "128472387293" + "v" : "27", + "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", + "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "extrafield" : "128472387293" } }, - "TransactionWithTooFewRLPElements" : { + "TransactionWithTooFewRLPElements" : { "transaction" : - { + { "data" : "", "gasPrice" : "1", "nonce" : "0", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "v" : "27", - "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", - "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" + "v" : "27", + "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", + "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" } }, - "TransactionWithHihghValue" : { + "TransactionWithHihghValue" : { "transaction" : - { + { "data" : "", "gasLimit" : "850", "gasPrice" : "1", "nonce" : "0", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "115792089237316195423570985008687907853269984665640564039457584007913129639935", - "v" : "27", - "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", - "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" + "v" : "27", + "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", + "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" } }, - "TransactionWithHihghValueOverflow" : { + "TransactionWithHihghValueOverflow" : { "transaction" : - { + { "data" : "", "gasLimit" : "850", "gasPrice" : "1", "nonce" : "0", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "115792089237316195423570985008687907853269984665640564039457584007913129639936", - "v" : "27", - "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", - "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" + "v" : "27", + "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", + "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" } }, "TransactionWithSvalueOverflow" : { "transaction" : - { + { "data" : "", "gasLimit" : "850", "gasPrice" : "1", "nonce" : "0", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "11", - "v" : "27", - "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", - "s" : "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f" + "v" : "27", + "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", + "s" : "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f" } }, - "TransactionWithRvalueOverflow" : { + "TransactionWithRvalueOverflow" : { "transaction" : - { + { "data" : "", "gasLimit" : "850", "gasPrice" : "1", "nonce" : "0", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "11", - "v" : "27", - "r" : "0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", - "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" + "v" : "27", + "r" : "0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", + "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" } }, - "TransactionWithNonceOverflow" : { + "TransactionWithNonceOverflow" : { "transaction" : - { + { "data" : "", "gasLimit" : "850", "gasPrice" : "1", "nonce" : "115792089237316195423570985008687907853269984665640564039457584007913129639936", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "11", - "v" : "27", - "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", - "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" + "v" : "27", + "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", + "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" } }, -"TransactionWithGasPriceOverflow" : { + "TransactionWithGasPriceOverflow" : { "transaction" : - { + { "data" : "", "gasLimit" : "850", "gasPrice" : "115792089237316195423570985008687907853269984665640564039457584007913129639936", "nonce" : "0", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "11", - "v" : "27", - "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", - "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" + "v" : "27", + "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", + "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" } }, - "TransactionWithGasLimitOverflow" : { + "TransactionWithGasLimitOverflow" : { "transaction" : - { + { "data" : "", "gasLimit" : "115792089237316195423570985008687907853269984665640564039457584007913129639936", "gasPrice" : "123", "nonce" : "0", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "11", - "v" : "27", - "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", - "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" + "v" : "27", + "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", + "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" } }, "RLPElementsWithZeros" : { "transaction" : - { + { "data" : "0x0000011222333", "gasLimit" : "1000", "gasPrice" : "00123", "nonce" : "0054", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "00000011", - "v" : "27", - "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", - "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" + "v" : "27", + "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", + "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" } }, - "RLPWrongHexElements" : { + "RLPWrongHexElements" : { "transaction" : - { + { "data" : "0x0000000012", "gasLimit" : "1000", "gasPrice" : "123", "nonce" : "54", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "11", - "v" : "27", - "r" : "0x0048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", - "s" : "0x00efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" + "v" : "27", + "r" : "0x0048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", + "s" : "0x00efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" } }, - "EmptyTransaction" : { + "EmptyTransaction" : { "transaction" : - { - "data" : "", + { + "data" : "", "gasLimit" : "", "gasPrice" : "", "nonce" : "", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "", - "v" : "27", - "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", - "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" + "v" : "27", + "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", + "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" } }, "WrongAddress" : { "transaction" : - { - "data" : "", + { + "data" : "", "gasLimit" : "", "gasPrice" : "", "nonce" : "", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d8v", "value" : "", - "v" : "27", - "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", - "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" + "v" : "27", + "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", + "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" } }, - "AddressMoreThan20" : { + "AddressMoreThan20" : { "transaction" : - { + { "data" : "", "gasLimit" : "2000", "gasPrice" : "1", "nonce" : "0", "to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b1c", "value" : "10", - "v" : "28", - "r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", - "s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" + "v" : "28", + "r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", + "s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" } }, - "AddressLessThan20" : { + "AddressLessThan20" : { "transaction" : - { + { "data" : "", "gasLimit" : "2000", "gasPrice" : "1", "nonce" : "0", "to" : "b9331677e6ebf", "value" : "10", - "v" : "28", - "r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", - "s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" + "v" : "28", + "r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", + "s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" } }, - "AddressLessThan20Prefixed0" : { + "AddressLessThan20Prefixed0" : { "transaction" : - { + { "data" : "", "gasLimit" : "2000", "gasPrice" : "1", "nonce" : "0", "to" : "0x000000000000000000000000000b9331677e6ebf", "value" : "10", - "v" : "28", - "r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", - "s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" + "v" : "28", + "r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", + "s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" } } } From 70eafae18736d4c59728b897f54d60de3e525761 Mon Sep 17 00:00:00 2001 From: debris Date: Sun, 8 Feb 2015 21:41:42 +0100 Subject: [PATCH 047/213] fixed arrays << error in msvc --- libdevcore/CommonIO.h | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/libdevcore/CommonIO.h b/libdevcore/CommonIO.h index d2a67921b..23092b702 100644 --- a/libdevcore/CommonIO.h +++ b/libdevcore/CommonIO.h @@ -57,7 +57,7 @@ template struct StreamOut { static S& bypass(S& _out, T const template struct StreamOut { static S& bypass(S& _out, uint8_t const& _t) { _out << (int)_t; return _out; } }; template inline std::ostream& operator<<(std::ostream& _out, std::vector const& _e); -template inline std::ostream& operator<<(std::ostream& _out, std::array const& _e); +template inline std::ostream& operator<<(std::ostream& _out, std::array const& _e); template inline std::ostream& operator<<(std::ostream& _out, std::pair const& _e); template inline std::ostream& operator<<(std::ostream& _out, std::list const& _e); template inline std::ostream& operator<<(std::ostream& _out, std::tuple const& _e); @@ -84,7 +84,7 @@ inline S& streamout(S& _out, std::vector const& _e) template inline std::ostream& operator<<(std::ostream& _out, std::vector const& _e) { streamout(_out, _e); return _out; } -template +template inline S& streamout(S& _out, std::array const& _e) { _out << "["; @@ -98,23 +98,7 @@ inline S& streamout(S& _out, std::array const& _e) _out << "]"; return _out; } -template inline std::ostream& operator<<(std::ostream& _out, std::array const& _e) { streamout(_out, _e); return _out; } - -template -inline S& streamout(S& _out, std::array const& _e) -{ - _out << "["; - if (!_e.empty()) - { - StreamOut::bypass(_out, _e.front()); - auto i = _e.begin(); - for (++i; i != _e.end(); ++i) - StreamOut::bypass(_out << ",", *i); - } - _out << "]"; - return _out; -} -template inline std::ostream& operator<<(std::ostream& _out, std::array const& _e) { streamout(_out, _e); return _out; } +template inline std::ostream& operator<<(std::ostream& _out, std::array const& _e) { streamout(_out, _e); return _out; } template inline S& streamout(S& _out, std::list const& _e) From 92bfd9181208f9e9c66f0b9d3f8b3e0e0107fd70 Mon Sep 17 00:00:00 2001 From: debris Date: Sun, 8 Feb 2015 21:56:15 +0100 Subject: [PATCH 048/213] cmake mess --- alethzero/CMakeLists.txt | 9 ++++++--- eth/CMakeLists.txt | 1 + libweb3jsonrpc/CMakeLists.txt | 5 ++++- lllc/CMakeLists.txt | 2 ++ mix/CMakeLists.txt | 2 ++ solc/CMakeLists.txt | 2 ++ test/CMakeLists.txt | 6 ++++++ third/CMakeLists.txt | 2 ++ 8 files changed, 25 insertions(+), 4 deletions(-) diff --git a/alethzero/CMakeLists.txt b/alethzero/CMakeLists.txt index b58446935..2cd6f43a4 100644 --- a/alethzero/CMakeLists.txt +++ b/alethzero/CMakeLists.txt @@ -32,6 +32,8 @@ eth_add_executable(${EXECUTABLE} add_dependencies(${EXECUTABLE} BuildInfo.h) +target_link_libraries(${EXECUTABLE} ${Boost_CHRONO_LIBRARIES}) +target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARIES}) target_link_libraries(${EXECUTABLE} Qt5::Core) target_link_libraries(${EXECUTABLE} webthree) target_link_libraries(${EXECUTABLE} qwebthree) @@ -40,9 +42,6 @@ target_link_libraries(${EXECUTABLE} evm) target_link_libraries(${EXECUTABLE} ethcore) target_link_libraries(${EXECUTABLE} devcrypto) target_link_libraries(${EXECUTABLE} secp256k1) -if (NOT ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")) -target_link_libraries(${EXECUTABLE} serpent) -endif() target_link_libraries(${EXECUTABLE} lll) target_link_libraries(${EXECUTABLE} solidity) target_link_libraries(${EXECUTABLE} evmcore) @@ -51,6 +50,10 @@ target_link_libraries(${EXECUTABLE} web3jsonrpc) target_link_libraries(${EXECUTABLE} jsqrc) target_link_libraries(${EXECUTABLE} natspec) +if (NOT ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")) + target_link_libraries(${EXECUTABLE} serpent) +endif() + # eth_install_executable is defined in cmake/EthExecutableHelper.cmake eth_install_executable(${EXECUTABLE}) diff --git a/eth/CMakeLists.txt b/eth/CMakeLists.txt index c98f3cbec..bdd966bfc 100644 --- a/eth/CMakeLists.txt +++ b/eth/CMakeLists.txt @@ -17,6 +17,7 @@ add_dependencies(${EXECUTABLE} BuildInfo.h) target_link_libraries(${EXECUTABLE} ${Boost_REGEX_LIBRARIES}) target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARIES}) +target_link_libraries(${EXECUTABLE} ${Boost_CHRONO_LIBRARIES}) if (READLINE_FOUND) target_link_libraries(${EXECUTABLE} ${READLINE_LIBRARIES}) diff --git a/libweb3jsonrpc/CMakeLists.txt b/libweb3jsonrpc/CMakeLists.txt index f371024e6..e4e71e885 100644 --- a/libweb3jsonrpc/CMakeLists.txt +++ b/libweb3jsonrpc/CMakeLists.txt @@ -30,7 +30,10 @@ target_link_libraries(${EXECUTABLE} ${JSON_RPC_CPP_SERVER_LIBRARIES}) target_link_libraries(${EXECUTABLE} webthree) target_link_libraries(${EXECUTABLE} secp256k1) target_link_libraries(${EXECUTABLE} solidity) -target_link_libraries(${EXECUTABLE} serpent) + +if (NOT ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")) + target_link_libraries(${EXECUTABLE} serpent) +endif() install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) diff --git a/lllc/CMakeLists.txt b/lllc/CMakeLists.txt index 2e76aa6ff..f41584e04 100644 --- a/lllc/CMakeLists.txt +++ b/lllc/CMakeLists.txt @@ -13,6 +13,8 @@ add_executable(${EXECUTABLE} ${SRC_LIST} ${HEADERS}) add_dependencies(${EXECUTABLE} BuildInfo.h) +target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARIES}) +target_link_libraries(${EXECUTABLE} ${Boost_CHRONO_LIBRARIES}) target_link_libraries(${EXECUTABLE} lll) target_link_libraries(${EXECUTABLE} evmcore) target_link_libraries(${EXECUTABLE} devcore) diff --git a/mix/CMakeLists.txt b/mix/CMakeLists.txt index db9452061..235c41b92 100644 --- a/mix/CMakeLists.txt +++ b/mix/CMakeLists.txt @@ -34,6 +34,8 @@ eth_add_executable(${EXECUTABLE} UI_RESOURCES ${UI_RESOURCES} ) +target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARIES}) +target_link_libraries(${EXECUTABLE} ${Boost_CHRONO_LIBRARIES}) target_link_libraries(${EXECUTABLE} Qt5::Core) target_link_libraries(${EXECUTABLE} Qt5::Gui) target_link_libraries(${EXECUTABLE} Qt5::Widgets) diff --git a/solc/CMakeLists.txt b/solc/CMakeLists.txt index 8c0ece27e..96129c499 100644 --- a/solc/CMakeLists.txt +++ b/solc/CMakeLists.txt @@ -13,6 +13,8 @@ add_executable(${EXECUTABLE} ${SRC_LIST} ${HEADERS}) target_link_libraries(${EXECUTABLE} ${Boost_FILESYSTEM_LIBRARIES}) target_link_libraries(${EXECUTABLE} ${Boost_PROGRAM_OPTIONS_LIBRARIES}) +target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARIES}) +target_link_libraries(${EXECUTABLE} ${Boost_CHRONO_LIBRARIES}) target_link_libraries(${EXECUTABLE} solidity) install( TARGETS ${EXECUTABLE} DESTINATION bin ) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 36876eea6..4d240a0ee 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -16,6 +16,8 @@ add_executable(createRandomTest createRandomTest.cpp vm.cpp TestHelper.cpp) add_executable(checkRandomTest checkRandomTest.cpp vm.cpp TestHelper.cpp) target_link_libraries(testeth ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES}) +target_link_libraries(testeth ${Boost_DATE_TIME_LIBRARIES}) +target_link_libraries(testeth ${Boost_CHRONO_LIBRARIES}) target_link_libraries(testeth ${CURL_LIBRARIES}) target_link_libraries(testeth ethereum) target_link_libraries(testeth ethcore) @@ -30,9 +32,13 @@ if (JSONRPC) endif() target_link_libraries(createRandomTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES}) +target_link_libraries(createRandomTest ${Boost_DATE_TIME_LIBRARIES}) +target_link_libraries(createRandomTest ${Boost_CHRONO_LIBRARIES}) target_link_libraries(createRandomTest ethereum) target_link_libraries(createRandomTest ethcore) target_link_libraries(checkRandomTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES}) +target_link_libraries(checkRandomTest ${Boost_DATE_TIME_LIBRARIES}) +target_link_libraries(checkRandomTest ${Boost_CHRONO_LIBRARIES}) target_link_libraries(checkRandomTest ethereum) target_link_libraries(checkRandomTest ethcore) diff --git a/third/CMakeLists.txt b/third/CMakeLists.txt index 71f1e70f2..db72cdebd 100644 --- a/third/CMakeLists.txt +++ b/third/CMakeLists.txt @@ -31,6 +31,8 @@ eth_add_executable(${EXECUTABLE} add_dependencies(${EXECUTABLE} BuildInfo.h) +target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARIES}) +target_link_libraries(${EXECUTABLE} ${Boost_CHRONO_LIBRARIES}) target_link_libraries(${EXECUTABLE} Qt5::Core) target_link_libraries(${EXECUTABLE} webthree) target_link_libraries(${EXECUTABLE} qwebthree) From eb2a4e375a8b8612342f6d03011a14d3ec3e5db6 Mon Sep 17 00:00:00 2001 From: subtly Date: Mon, 9 Feb 2015 00:35:25 -0500 Subject: [PATCH 049/213] update for cr. update whisper test. --- libp2p/Host.h | 73 ++------------------------------------ libp2p/Peer.cpp | 57 ++++++++++++++++++++++++++++++ libp2p/Peer.h | 82 +++++++++++++++++++++++++++++++++++++++++++ test/whisperTopic.cpp | 19 +++++----- 4 files changed, 152 insertions(+), 79 deletions(-) create mode 100644 libp2p/Peer.cpp create mode 100644 libp2p/Peer.h diff --git a/libp2p/Host.h b/libp2p/Host.h index b24f1343c..baf8f0585 100644 --- a/libp2p/Host.h +++ b/libp2p/Host.h @@ -37,6 +37,7 @@ #include "NodeTable.h" #include "HostCapability.h" #include "Network.h" +#include "Peer.h" #include "Common.h" namespace ba = boost::asio; namespace bi = ba::ip; @@ -44,81 +45,11 @@ namespace bi = ba::ip; namespace dev { -class RLPStream; - namespace p2p { class Host; -/** - * @brief Representation of connectivity state and all other pertinent Peer metadata. - * A Peer represents connectivity between two nodes, which in this case, are the host - * and remote nodes. - * - * State information necessary for loading network topology is maintained by NodeTable. - * - * @todo Implement 'bool required' - * @todo reputation: Move score, rating to capability-specific map (&& remove friend class) - * @todo reputation: implement via origin-tagged events - * @todo Populate metadata upon construction; save when destroyed. - * @todo Metadata for peers needs to be handled via a storage backend. - * Specifically, peers can be utilized in a variety of - * many-to-many relationships while also needing to modify shared instances of - * those peers. Modifying these properties via a storage backend alleviates - * Host of the responsibility. (&& remove save/restoreNetwork) - * @todo reimplement recording of historical session information on per-transport basis - * @todo rebuild nodetable when localNetworking is enabled/disabled - * @todo move attributes into protected - */ -class Peer: public Node -{ - friend class Session; /// Allows Session to update score and rating. - friend class Host; /// For Host: saveNetwork(), restoreNetwork() -public: - bool isOffline() const { return !m_session.lock(); } - - bi::tcp::endpoint const& peerEndpoint() const { return endpoint.tcp; } - - int m_score = 0; ///< All time cumulative. - int m_rating = 0; ///< Trending. - - /// Network Availability - - std::chrono::system_clock::time_point m_lastConnected; - std::chrono::system_clock::time_point m_lastAttempted; - unsigned m_failedAttempts = 0; - DisconnectReason m_lastDisconnect = NoDisconnect; ///< Reason for disconnect that happened last. - - virtual bool operator<(Peer const& _p) const - { - if (isOffline() != _p.isOffline()) - return isOffline(); - else if (isOffline()) - if (m_lastAttempted == _p.m_lastAttempted) - return m_failedAttempts < _p.m_failedAttempts; - else - return m_lastAttempted < _p.m_lastAttempted; - else - if (m_score == _p.m_score) - if (m_rating == _p.m_rating) - if (m_failedAttempts == _p.m_failedAttempts) - return id < _p.id; - else - return m_failedAttempts < _p.m_failedAttempts; - else - return m_rating < _p.m_rating; - else - return m_score < _p.m_score; - } - -protected: - /// Used by isOffline() and (todo) for peer to emit session information. - std::weak_ptr m_session; -}; -using Peers = std::vector; - - class HostNodeTableHandler: public NodeTableEventHandler { public: @@ -131,7 +62,7 @@ private: Host& m_host; }; - + /** * @brief The Host class * Capabilities should be registered prior to startNetwork, since m_capabilities is not thread-safe. diff --git a/libp2p/Peer.cpp b/libp2p/Peer.cpp new file mode 100644 index 000000000..1811da930 --- /dev/null +++ b/libp2p/Peer.cpp @@ -0,0 +1,57 @@ +/* + 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 Peer.cpp + * @author Alex Leverington + * @author Gav Wood + * @date 2014 + */ + +#include "Peer.h" +using namespace std; +using namespace dev; +using namespace dev::p2p; + +namespace dev +{ + +namespace p2p +{ + +bool Peer::operator<(Peer const& _p) const +{ + if (isOffline() != _p.isOffline()) + return isOffline(); + else if (isOffline()) + if (m_lastAttempted == _p.m_lastAttempted) + return m_failedAttempts < _p.m_failedAttempts; + else + return m_lastAttempted < _p.m_lastAttempted; + else + if (m_score == _p.m_score) + if (m_rating == _p.m_rating) + if (m_failedAttempts == _p.m_failedAttempts) + return id < _p.id; + else + return m_failedAttempts < _p.m_failedAttempts; + else + return m_rating < _p.m_rating; + else + return m_score < _p.m_score; +} + +} +} diff --git a/libp2p/Peer.h b/libp2p/Peer.h new file mode 100644 index 000000000..f3db9d7e1 --- /dev/null +++ b/libp2p/Peer.h @@ -0,0 +1,82 @@ +/* + 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 Peer.h + * @author Alex Leverington + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include "Common.h" + +namespace dev +{ + +namespace p2p +{ + +/** + * @brief Representation of connectivity state and all other pertinent Peer metadata. + * A Peer represents connectivity between two nodes, which in this case, are the host + * and remote nodes. + * + * State information necessary for loading network topology is maintained by NodeTable. + * + * @todo Implement 'bool required' + * @todo reputation: Move score, rating to capability-specific map (&& remove friend class) + * @todo reputation: implement via origin-tagged events + * @todo Populate metadata upon construction; save when destroyed. + * @todo Metadata for peers needs to be handled via a storage backend. + * Specifically, peers can be utilized in a variety of + * many-to-many relationships while also needing to modify shared instances of + * those peers. Modifying these properties via a storage backend alleviates + * Host of the responsibility. (&& remove save/restoreNetwork) + * @todo reimplement recording of historical session information on per-transport basis + * @todo rebuild nodetable when localNetworking is enabled/disabled + * @todo move attributes into protected + */ +class Peer: public Node +{ + friend class Session; /// Allows Session to update score and rating. + friend class Host; /// For Host: saveNetwork(), restoreNetwork() + +public: + bool isOffline() const { return !m_session.lock(); } + + bi::tcp::endpoint const& peerEndpoint() const { return endpoint.tcp; } + + virtual bool operator<(Peer const& _p) const; + +protected: + int m_score = 0; ///< All time cumulative. + int m_rating = 0; ///< Trending. + + /// Network Availability + + std::chrono::system_clock::time_point m_lastConnected; + std::chrono::system_clock::time_point m_lastAttempted; + unsigned m_failedAttempts = 0; + DisconnectReason m_lastDisconnect = NoDisconnect; ///< Reason for disconnect that happened last. + + /// Used by isOffline() and (todo) for peer to emit session information. + std::weak_ptr m_session; +}; +using Peers = std::vector; + +} +} diff --git a/test/whisperTopic.cpp b/test/whisperTopic.cpp index ab0cdc115..be93174ec 100644 --- a/test/whisperTopic.cpp +++ b/test/whisperTopic.cpp @@ -243,17 +243,20 @@ BOOST_AUTO_TEST_CASE(asyncforwarding) }); while (!startedForwarder) - this_thread::sleep_for(chrono::milliseconds(50)); - - Host host2("Sender", NetworkPreferences(30300, "", false, true)); - host2.setIdealPeerCount(1); - shared_ptr whost2 = host2.registerCapability(new WhisperHost()); - host2.start(); - while (!host2.isStarted()) this_thread::sleep_for(chrono::milliseconds(2)); - host2.addNode(host1.id(), "127.0.0.1", 30305, 30305); { + Host host2("Sender", NetworkPreferences(30300, "", false, true)); + host2.setIdealPeerCount(1); + shared_ptr whost2 = host2.registerCapability(new WhisperHost()); + host2.start(); + while (!host2.isStarted()) + this_thread::sleep_for(chrono::milliseconds(2)); + host2.addNode(host1.id(), "127.0.0.1", 30305, 30305); + + while (!host2.peerCount()) + this_thread::sleep_for(chrono::milliseconds(5)); + KeyPair us = KeyPair::create(); whost2->post(us.sec(), RLPStream().append(1).out(), BuildTopic("test")); this_thread::sleep_for(chrono::milliseconds(250)); From ff2682710887489b5a5b2a508ff67cfcd8d77080 Mon Sep 17 00:00:00 2001 From: subtly Date: Mon, 9 Feb 2015 02:00:21 -0500 Subject: [PATCH 050/213] update alethzero mainwin --- alethzero/MainWin.cpp | 4 ++-- libp2p/Peer.h | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index e9824ffce..465ae6877 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -965,8 +965,8 @@ void Main::refreshNetwork() .arg(QString::fromStdString(i.id.abridged())) .arg(QString::fromStdString(i.peerEndpoint().address().to_string())) .arg(i.id == web3()->id() ? "self" : sessions.count(i.id) ? sessions[i.id] : "disconnected") - .arg(i.isOffline() ? " | " + QString::fromStdString(reasonOf(i.lastDisconnect)) + " | " + QString::number(i.failedAttempts) + "x" : "") - .arg(i.rating) + .arg(i.isOffline() ? " | " + QString::fromStdString(reasonOf(i.lastDisconnect())) + " | " + QString::number(i.failedAttempts()) + "x" : "") + .arg(i.rating()) ); } } diff --git a/libp2p/Peer.h b/libp2p/Peer.h index f3db9d7e1..415573c0c 100644 --- a/libp2p/Peer.h +++ b/libp2p/Peer.h @@ -62,6 +62,15 @@ public: virtual bool operator<(Peer const& _p) const; + /// This peers rating. + int rating() const { return m_rating; } + + /// Number of times connection has been attempted to peer. + int failedAttempts() const { return m_failedAttempts; } + + /// Reason peer was previously disconnected. + DisconnectReason lastDisconnect() const { return m_lastDisconnect; } + protected: int m_score = 0; ///< All time cumulative. int m_rating = 0; ///< Trending. From e63b1521f43216f1478519493d35cee8b627cc7a Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Mon, 9 Feb 2015 08:17:30 +0100 Subject: [PATCH 051/213] write block header and uncle list --- test/block.cpp | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/test/block.cpp b/test/block.cpp index 518b61238..adf8a3ad9 100644 --- a/test/block.cpp +++ b/test/block.cpp @@ -214,11 +214,33 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) cnote << "state sync did throw an exception: " << _e.what(); } - // write block and rlp to json - - //TODO if block rlp is invalid, delete transactions, and block - - + o["rlp"] = "0x" + toHex(theState.blockData()); + + // write block header + + mObject oBlockHeader; + BlockInfo current_BlockHeader = theState.info(); + oBlockHeader["parentHash"] = toString(current_BlockHeader.parentHash); + oBlockHeader["uncleHash"] = toString(current_BlockHeader.sha3Uncles); + oBlockHeader["coinbase"] = toString(current_BlockHeader.coinbaseAddress); + oBlockHeader["stateRoot"] = toString(current_BlockHeader.stateRoot); + oBlockHeader["transactionsTrie"] = toString(current_BlockHeader.transactionsRoot); + oBlockHeader["receiptTrie"] = toString(current_BlockHeader.receiptsRoot); + oBlockHeader["bloom"] = toString(current_BlockHeader.logBloom); + oBlockHeader["difficulty"] = toString(current_BlockHeader.difficulty); + oBlockHeader["number"] = toString(current_BlockHeader.number); + oBlockHeader["gasLimit"] = toString(current_BlockHeader.gasLimit); + oBlockHeader["gasUsed"] = toString(current_BlockHeader.gasUsed); + oBlockHeader["timestamp"] = toString(current_BlockHeader.timestamp); + oBlockHeader["extraData"] = toHex(current_BlockHeader.extraData); + oBlockHeader["nonce"] = toString(current_BlockHeader.nonce); + + o["blockHeader"] = oBlockHeader; + + // write uncle list + + mArray aUncleList; // as of now, our parent is always the genesis block, so we can not have uncles. That might change. + o["uncleHeaders"] = aUncleList; } } } From a53a963b647181e5a8fc07c7f385e815afc35b95 Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 9 Feb 2015 18:17:15 +0100 Subject: [PATCH 052/213] Integration with system default font size. --- mix/AppContext.cpp | 2 ++ mix/ClientModel.cpp | 1 - mix/qml/BasicContent.qml | 35 -------------------- mix/qml/CodeEditor.qml | 3 +- mix/qml/CodeEditorStyle.qml | 14 ++++++++ mix/qml/Debugger.qml | 19 ++++++----- mix/qml/DebuggerPaneStyle.qml | 15 +++++++++ mix/qml/FilesSection.qml | 26 +++++++-------- mix/qml/ItemDelegateDataDump.qml | 5 +-- mix/qml/{Style.qml => ProjectFilesStyle.qml} | 15 +++++---- mix/qml/ProjectList.qml | 16 ++++----- mix/qml/StateDialog.qml | 3 +- mix/qml/StateList.qml | 3 +- mix/qml/StateStyle.qml | 14 ++++++++ mix/qml/StatusPane.qml | 5 +-- mix/qml/StatusPaneStyle.qml | 15 +++++++++ mix/qml/qmldir | 5 ++- mix/res.qrc | 7 ++-- 18 files changed, 121 insertions(+), 82 deletions(-) delete mode 100644 mix/qml/BasicContent.qml create mode 100644 mix/qml/CodeEditorStyle.qml create mode 100644 mix/qml/DebuggerPaneStyle.qml rename mix/qml/{Style.qml => ProjectFilesStyle.qml} (72%) create mode 100644 mix/qml/StateStyle.qml create mode 100644 mix/qml/StatusPaneStyle.qml diff --git a/mix/AppContext.cpp b/mix/AppContext.cpp index a806a39f4..7fe22106f 100644 --- a/mix/AppContext.cpp +++ b/mix/AppContext.cpp @@ -81,6 +81,8 @@ void AppContext::load() BOOST_THROW_EXCEPTION(exception); } m_applicationEngine->rootContext()->setContextProperty("projectModel", projectModel); + QFont f; + m_applicationEngine->rootContext()->setContextProperty("systemPointSize", f.pointSize()); qmlRegisterType("CodeEditorExtensionManager", 1, 0, "CodeEditorExtensionManager"); qmlRegisterType("HttpServer", 1, 0, "HttpServer"); m_applicationEngine->load(QUrl("qrc:/qml/main.qml")); diff --git a/mix/ClientModel.cpp b/mix/ClientModel.cpp index 602940078..0838668bb 100644 --- a/mix/ClientModel.cpp +++ b/mix/ClientModel.cpp @@ -89,7 +89,6 @@ ClientModel::ClientModel(AppContext* _context): m_web3Server.reset(new Web3Server(*m_rpcConnector.get(), std::vector { m_client->userAccount() }, m_client.get())); connect(m_web3Server.get(), &Web3Server::newTransaction, this, &ClientModel::onNewTransaction, Qt::DirectConnection); - _context->appEngine()->rootContext()->setContextProperty("clientModel", this); } diff --git a/mix/qml/BasicContent.qml b/mix/qml/BasicContent.qml deleted file mode 100644 index ff31dc86f..000000000 --- a/mix/qml/BasicContent.qml +++ /dev/null @@ -1,35 +0,0 @@ -import QtQuick 2.2 -import QtQuick.Controls 1.1 - -Rectangle { - anchors.fill: parent - width: parent.width - height: parent.height - color: "lightgray" - Text { - font.pointSize: 9 - anchors.left: parent.left - anchors.top: parent.top - anchors.topMargin: 3 - anchors.leftMargin: 3 - height: 9 - font.family: "Monospace" - objectName: "status" - id: status - } - TextArea { - readOnly: true - anchors.left: parent.left - anchors.leftMargin: 10 - anchors.top: status.bottom - anchors.topMargin: 3 - font.pointSize: 9 - font.family: "Monospace" - height: parent.height * 0.8 - width: parent.width - 20 - wrapMode: Text.Wrap - backgroundVisible: false - objectName: "content" - id: content - } -} diff --git a/mix/qml/CodeEditor.qml b/mix/qml/CodeEditor.qml index 0c554b379..9d3df69e5 100644 --- a/mix/qml/CodeEditor.qml +++ b/mix/qml/CodeEditor.qml @@ -3,6 +3,7 @@ import QtQuick.Window 2.0 import QtQuick.Layouts 1.0 import QtQuick.Controls 1.0 import QtQuick.Controls.Styles 1.1 +import "." Item { signal editorTextChanged @@ -65,7 +66,7 @@ Item { height: parent.height font.family: "Monospace" - font.pointSize: 12 + font.pointSize: CodeEditorStyle.general.basicFontSize width: parent.width tabChangesFocus: false diff --git a/mix/qml/CodeEditorStyle.qml b/mix/qml/CodeEditorStyle.qml new file mode 100644 index 000000000..c9740957c --- /dev/null +++ b/mix/qml/CodeEditorStyle.qml @@ -0,0 +1,14 @@ +pragma Singleton +import QtQuick 2.0 + +QtObject { + + function absoluteSize(rel) + { + return systemPointSize + rel; + } + + property QtObject general: QtObject { + property int basicFontSize: absoluteSize(1) + } +} diff --git a/mix/qml/Debugger.qml b/mix/qml/Debugger.qml index e9c718f70..94ab88cf4 100644 --- a/mix/qml/Debugger.qml +++ b/mix/qml/Debugger.qml @@ -6,6 +6,7 @@ import QtQuick.Layouts 1.1 import Qt.labs.settings 1.0 import "js/Debugger.js" as Debugger import "js/ErrorLocationFormater.js" as ErrorLocationFormater +import "." Rectangle { id: debugPanel @@ -346,7 +347,7 @@ Rectangle { color: "#b2b3ae" text: styleData.value.split(' ')[0] font.family: "monospace" - font.pointSize: 9 + font.pointSize: DebuggerPaneProjectFilesStyle.general.basicFontSize wrapMode: Text.NoWrap id: id } @@ -356,7 +357,7 @@ Rectangle { color: styleData.selected ? "white" : "black" font.family: "monospace" text: styleData.value.replace(styleData.value.split(' ')[0], '') - font.pointSize: 9 + font.pointSize: DebuggerPaneProjectFilesStyle.general.basicFontSize } } } @@ -425,11 +426,11 @@ Rectangle { Layout.minimumHeight: parent.height Text { anchors.centerIn: parent - anchors.leftMargin: 5 + anchors.leftMargin: 5() font.family: "monospace" color: "#4a4a4a" text: styleData.row; - font.pointSize: 9 + font.pointSize: DebuggerPaneProjectFilesStyle.general.basicFontSize } } @@ -447,7 +448,7 @@ Rectangle { anchors.verticalCenter: parent.verticalCenter color: "#4a4a4a" text: styleData.value - font.pointSize: 9 + font.pointSize: DebuggerPaneProjectFilesStyle.general.basicFontSize } } } @@ -514,7 +515,7 @@ Rectangle { anchors.leftMargin: 5 color: "#4a4a4a" text: styleData.row; - font.pointSize: 9 + font.pointSize: DebuggerPaneProjectFilesStyle.general.basicFontSize width: parent.width - 5 elide: Text.ElideRight } @@ -535,7 +536,7 @@ Rectangle { color: "#4a4a4a" text: styleData.value; elide: Text.ElideRight - font.pointSize: 9 + font.pointSize: DebuggerPaneProjectFilesStyle.general.basicFontSize } } } @@ -585,7 +586,7 @@ Rectangle { anchors.leftMargin: 5 color: "#4a4a4a" text: styleData.value.split('\t')[0]; - font.pointSize: 9 + font.pointSize: DebuggerPaneProjectFilesStyle.general.basicFontSize width: parent.width - 5 elide: Text.ElideRight } @@ -606,7 +607,7 @@ Rectangle { color: "#4a4a4a" text: styleData.value.split('\t')[1]; elide: Text.ElideRight - font.pointSize: 9 + font.pointSize: DebuggerPaneProjectFilesStyle.general.basicFontSize } } } diff --git a/mix/qml/DebuggerPaneStyle.qml b/mix/qml/DebuggerPaneStyle.qml new file mode 100644 index 000000000..1078df2f9 --- /dev/null +++ b/mix/qml/DebuggerPaneStyle.qml @@ -0,0 +1,15 @@ +pragma Singleton +import QtQuick 2.0 + +QtObject { + + function absoluteSize(rel) + { + return systemPointSize + rel; + } + + property QtObject general: QtObject { + property int basicFontSize: absoluteSize(-2) + property int dataDumpFontSize: absoluteSize(-3) + } +} diff --git a/mix/qml/FilesSection.qml b/mix/qml/FilesSection.qml index 32202f839..76e235e7d 100644 --- a/mix/qml/FilesSection.qml +++ b/mix/qml/FilesSection.qml @@ -20,17 +20,17 @@ ColumnLayout { function hiddenHeightTopLevel() { - return section.state === "hidden" ? Style.documentsList.height : Style.documentsList.fileNameHeight * model.count + Style.documentsList.height; + return section.state === "hidden" ? ProjectFilesStyle.documentsList.height : ProjectFilesStyle.documentsList.fileNameHeight * model.count + ProjectFilesStyle.documentsList.height; } function hiddenHeightRepeater() { - return section.state === "hidden" ? 0 : Style.documentsList.fileNameHeight * wrapperItem.model.count; + return section.state === "hidden" ? 0 : ProjectFilesStyle.documentsList.fileNameHeight * wrapperItem.model.count; } function hiddenHeightElement() { - return section.state === "hidden" ? 0 : Style.documentsList.fileNameHeight; + return section.state === "hidden" ? 0 : ProjectFilesStyle.documentsList.fileNameHeight; } function getDocumentIndex(documentId) @@ -65,7 +65,7 @@ ColumnLayout { anchors.top: parent.top id: rowCol width: parent.width - height: Style.documentsList.height + height: ProjectFilesStyle.documentsList.height Image { source: "qrc:/qml/img/opentriangleindicator_filesproject.png" @@ -83,15 +83,15 @@ ColumnLayout { id: section text: sectionName anchors.left: parent.left - anchors.leftMargin: Style.general.leftMargin - color: Style.documentsList.sectionColor + anchors.leftMargin: ProjectFilesStyle.general.leftMargin + color: ProjectFilesStyle.documentsList.sectionColor font.family: boldFont.name - font.pointSize: Style.documentsList.sectionFontSize + font.pointSize: ProjectFilesStyle.documentsList.sectionFontSize states: [ State { name: "hidden" PropertyChanges { target: filesList; visible: false; } - PropertyChanges { target: rowCol; Layout.minimumHeight: Style.documentsList.height; Layout.maximumHeight: Style.documentsList.height; height: Style.documentsList.height; } + PropertyChanges { target: rowCol; Layout.minimumHeight: ProjectFilesStyle.documentsList.height; Layout.maximumHeight: ProjectFilesStyle.documentsList.height; height: ProjectFilesStyle.documentsList.height; } PropertyChanges { target: imgArrow; source: "qrc:/qml/img/closedtriangleindicator_filesproject.png" } } ] @@ -132,21 +132,21 @@ ColumnLayout { Layout.preferredHeight: wrapperItem.hiddenHeightElement() Layout.maximumHeight: wrapperItem.hiddenHeightElement() height: wrapperItem.hiddenHeightElement() - color: isSelected ? Style.documentsList.highlightColor : Style.documentsList.background + color: isSelected ? ProjectFilesStyle.documentsList.highlightColor : ProjectFilesStyle.documentsList.background property bool isSelected property bool renameMode Text { id: nameText height: parent.height visible: !renameMode - color: rootItem.isSelected ? Style.documentsList.selectedColor : Style.documentsList.color + color: rootItem.isSelected ? ProjectFilesStyle.documentsList.selectedColor : ProjectFilesStyle.documentsList.color text: name; font.family: fileNameFont.name - font.pointSize: Style.documentsList.fontSize + font.pointSize: ProjectFilesStyle.documentsList.fontSize anchors.verticalCenter: parent.verticalCenter verticalAlignment: Text.AlignVCenter anchors.left: parent.left - anchors.leftMargin: Style.general.leftMargin + 2 + anchors.leftMargin: ProjectFilesStyle.general.leftMargin + 2 width: parent.width Connections { @@ -171,7 +171,7 @@ ColumnLayout { visible: renameMode anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left - anchors.leftMargin: Style.general.leftMargin + anchors.leftMargin: ProjectFilesStyle.general.leftMargin MouseArea { id: textMouseArea anchors.fill: parent diff --git a/mix/qml/ItemDelegateDataDump.qml b/mix/qml/ItemDelegateDataDump.qml index a57a61b03..9aa6d00db 100644 --- a/mix/qml/ItemDelegateDataDump.qml +++ b/mix/qml/ItemDelegateDataDump.qml @@ -2,6 +2,7 @@ import QtQuick 2.2 import QtQuick.Controls 1.1 import QtQuick.Layouts 1.0 import QtQuick.Controls.Styles 1.1 +import "." Rectangle { anchors.fill: parent @@ -27,7 +28,7 @@ Rectangle { font.bold: true color: "#4a4a4a" text: modelData[0] - font.pointSize: 8; + font.pointSize: DebuggerPaneStyle.general.dataDumpFontSize; } } @@ -46,7 +47,7 @@ Rectangle { anchors.leftMargin: 4 color: "#4a4a4a" text: modelData[1] - font.pointSize: 8 + font.pointSize: DebuggerPaneStyle.general.dataDumpFontSize } } } diff --git a/mix/qml/Style.qml b/mix/qml/ProjectFilesStyle.qml similarity index 72% rename from mix/qml/Style.qml rename to mix/qml/ProjectFilesStyle.qml index 348d8c4d1..cb8225e0d 100644 --- a/mix/qml/Style.qml +++ b/mix/qml/ProjectFilesStyle.qml @@ -1,10 +1,13 @@ pragma Singleton import QtQuick 2.0 -/* - * Project Files - */ QtObject { + + function absoluteSize(rel) + { + return systemPointSize + rel; + } + property QtObject general: QtObject { property int leftMargin: 45 } @@ -13,7 +16,7 @@ QtObject { property string color: "#808080" property string background: "#f0f0f0" property int height: 55 - property int pointSize: 18 + property int fontSize: absoluteSize(7);// 18 } property QtObject documentsList: QtObject { @@ -24,7 +27,7 @@ QtObject { property string highlightColor: "#4a90e2" property int height: 25 property int fileNameHeight: 30 - property int fontSize: 13 - property int sectionFontSize: 13 + property int fontSize: absoluteSize(2)// 13 + property int sectionFontSize: absoluteSize(2)// 13 } } diff --git a/mix/qml/ProjectList.qml b/mix/qml/ProjectList.qml index 138e86fe9..347e72bcb 100644 --- a/mix/qml/ProjectList.qml +++ b/mix/qml/ProjectList.qml @@ -20,8 +20,8 @@ Item { Rectangle { - color: Style.title.background - height: Style.title.height + color: ProjectFilesStyle.title.background + height: ProjectFilesStyle.title.height Layout.fillWidth: true Image { id: projectIcon @@ -35,14 +35,14 @@ Item { Text { id: projectTitle - color: Style.title.color + color: ProjectFilesStyle.title.color text: projectModel.projectTitle anchors.verticalCenter: parent.verticalCenter visible: !projectModel.isEmpty; anchors.left: parent.left - anchors.leftMargin: Style.general.leftMargin + anchors.leftMargin: ProjectFilesStyle.general.leftMargin font.family: srcSansProLight.name - font.pointSize: Style.title.pointSize + font.pointSize: ProjectFilesStyle.title.fontSize font.weight: Font.Light } @@ -52,7 +52,7 @@ Item { anchors.right: parent.right anchors.rightMargin: 15 font.family: srcSansProLight.name - font.pointSize: Style.title.pointSize + font.pointSize: ProjectFilesStyle.title.fontSize anchors.verticalCenter: parent.verticalCenter font.weight: Font.Light } @@ -62,7 +62,7 @@ Item { { Layout.fillWidth: true height: 10 - color: Style.documentsList.background + color: ProjectFilesStyle.documentsList.background } @@ -71,7 +71,7 @@ Item { { Layout.fillWidth: true Layout.fillHeight: true - color: Style.documentsList.background + color: ProjectFilesStyle.documentsList.background ColumnLayout { diff --git a/mix/qml/StateDialog.qml b/mix/qml/StateDialog.qml index fa48c640e..4384b81a6 100644 --- a/mix/qml/StateDialog.qml +++ b/mix/qml/StateDialog.qml @@ -5,6 +5,7 @@ import QtQuick.Window 2.0 import org.ethereum.qml.QEther 1.0 import "js/QEtherHelper.js" as QEtherHelper import "js/TransactionHelper.js" as TransactionHelper +import "." Window { id: modalStateDialog @@ -158,7 +159,7 @@ Window { Layout.fillWidth: true Layout.fillHeight: true text: functionId - font.pointSize: 12 + font.pointSize: StateStyle.general.basicFontSize //12 verticalAlignment: Text.AlignBottom } ToolButton { diff --git a/mix/qml/StateList.qml b/mix/qml/StateList.qml index 059b35bc2..f6f778cd9 100644 --- a/mix/qml/StateList.qml +++ b/mix/qml/StateList.qml @@ -4,6 +4,7 @@ import QtQuick.Controls 1.1 import QtQuick.Dialogs 1.1 import QtQuick.Layouts 1.1 import QtQuick.Window 2.0 +import "." Window { id: stateListContainer @@ -45,7 +46,7 @@ Window { Layout.fillWidth: true Layout.fillHeight: true text: styleData.value - font.pointSize: 12 + font.pointSize: StateStyle.general.basicFontSize verticalAlignment: Text.AlignBottom } ToolButton { diff --git a/mix/qml/StateStyle.qml b/mix/qml/StateStyle.qml new file mode 100644 index 000000000..c9740957c --- /dev/null +++ b/mix/qml/StateStyle.qml @@ -0,0 +1,14 @@ +pragma Singleton +import QtQuick 2.0 + +QtObject { + + function absoluteSize(rel) + { + return systemPointSize + rel; + } + + property QtObject general: QtObject { + property int basicFontSize: absoluteSize(1) + } +} diff --git a/mix/qml/StatusPane.qml b/mix/qml/StatusPane.qml index 57ade7a3a..956d3f2ec 100644 --- a/mix/qml/StatusPane.qml +++ b/mix/qml/StatusPane.qml @@ -2,6 +2,7 @@ import QtQuick 2.2 import QtQuick.Controls 1.1 import QtQuick.Layouts 1.1 import "js/ErrorLocationFormater.js" as ErrorLocationFormater +import "." Rectangle { id: statusHeader @@ -59,7 +60,7 @@ Rectangle { spacing: 5 Text { - font.pointSize: 10 + font.pointSize: StatusPaneStyle.general.statusFontSize height: 9 font.family: "sans serif" objectName: "status" @@ -81,7 +82,7 @@ Rectangle { Text { visible: false - font.pointSize: 9 + font.pointSize: StatusPaneStyle.general.logLinkFontSize height: 9 text: qsTr("See Log.") font.family: "Monospace" diff --git a/mix/qml/StatusPaneStyle.qml b/mix/qml/StatusPaneStyle.qml new file mode 100644 index 000000000..e6a1c9910 --- /dev/null +++ b/mix/qml/StatusPaneStyle.qml @@ -0,0 +1,15 @@ +pragma Singleton +import QtQuick 2.0 + +QtObject { + + function absoluteSize(rel) + { + return systemPointSize + rel; + } + + property QtObject general: QtObject { + property int statusFontSize: absoluteSize(-1) + property int logLinkFontSize: absoluteSize(-2) + } +} diff --git a/mix/qml/qmldir b/mix/qml/qmldir index 819842274..9eb0effd0 100644 --- a/mix/qml/qmldir +++ b/mix/qml/qmldir @@ -1 +1,4 @@ -singleton Style 1.0 Style.qml +singleton ProjectFilesStyle 1.0 ProjectFilesStyle.qml +singleton DebuggerPaneStyle 1.0 DebuggerPaneStyle.qml +singleton StateStyle 1.0 StateStyle.qml +singleton StatusPaneStyle 1.0 StatusPaneStyle.qml diff --git a/mix/res.qrc b/mix/res.qrc index d17c32549..a22a2d25b 100644 --- a/mix/res.qrc +++ b/mix/res.qrc @@ -2,7 +2,6 @@ qml/main.qml qml/AlertMessageDialog.qml - qml/BasicContent.qml qml/BasicMessage.qml qml/Debugger.qml qml/MainContent.qml @@ -63,7 +62,6 @@ res/mix_256x256x32.png qml/CallStack.qml qml/QVariableDeclaration.qml - qml/Style.qml qml/qmldir qml/FilesSection.qml qml/fonts/SourceSansPro-Black.ttf @@ -84,5 +82,10 @@ qml/img/closedtriangleindicator_filesproject.png qml/img/opentriangleindicator_filesproject.png qml/img/projecticon.png + qml/ProjectFilesStyle.qml + qml/DebuggerPaneStyle.qml + qml/CodeEditorStyle.qml + qml/StatusPaneStyle.qml + qml/StateStyle.qml From d5b3f224c650676df5a916f2d51bebd5bb634725 Mon Sep 17 00:00:00 2001 From: winsvega Date: Mon, 9 Feb 2015 23:40:47 +0300 Subject: [PATCH 053/213] Bigint bigint(1) << 256 --- test/TestHelper.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/TestHelper.cpp b/test/TestHelper.cpp index fbb302f15..ed351bb73 100644 --- a/test/TestHelper.cpp +++ b/test/TestHelper.cpp @@ -108,7 +108,7 @@ void ImportTest::importState(json_spirit::mObject& _o, State& _state) BOOST_REQUIRE(o.count("storage") > 0); BOOST_REQUIRE(o.count("code") > 0); - bigint biValue256 = bigint("115792089237316195423570985008687907853269984665640564039457584007913129639936"); + bigint biValue256 = bigint(1) << 256; if (bigint(o["balance"].get_str()) >= biValue256) BOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("State 'balance' is equal or greater than 2**256") ); if (bigint(o["nonce"].get_str()) >= biValue256) @@ -146,7 +146,7 @@ void ImportTest::importTransaction(json_spirit::mObject& _o) BOOST_REQUIRE(_o.count("secretKey") > 0); BOOST_REQUIRE(_o.count("data") > 0); - bigint biValue256 = bigint("115792089237316195423570985008687907853269984665640564039457584007913129639936"); + bigint biValue256 = bigint(1) << 256; if (bigint(_o["nonce"].get_str()) >= biValue256) BOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("Transaction 'nonce' is equal or greater than 2**256") ); if (bigint(_o["gasPrice"].get_str()) >= biValue256) From 62c685ae7c7a8fedf87d12a8fd5b6cc605b65ee1 Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 9 Feb 2015 22:38:30 +0100 Subject: [PATCH 054/213] integration with system font size - bug fix --- mix/qml/Debugger.qml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/mix/qml/Debugger.qml b/mix/qml/Debugger.qml index 94ab88cf4..2bf23ccef 100644 --- a/mix/qml/Debugger.qml +++ b/mix/qml/Debugger.qml @@ -347,7 +347,7 @@ Rectangle { color: "#b2b3ae" text: styleData.value.split(' ')[0] font.family: "monospace" - font.pointSize: DebuggerPaneProjectFilesStyle.general.basicFontSize + font.pointSize: DebuggerPaneStyle.general.basicFontSize wrapMode: Text.NoWrap id: id } @@ -357,7 +357,7 @@ Rectangle { color: styleData.selected ? "white" : "black" font.family: "monospace" text: styleData.value.replace(styleData.value.split(' ')[0], '') - font.pointSize: DebuggerPaneProjectFilesStyle.general.basicFontSize + font.pointSize: DebuggerPaneStyle.general.basicFontSize } } } @@ -430,7 +430,7 @@ Rectangle { font.family: "monospace" color: "#4a4a4a" text: styleData.row; - font.pointSize: DebuggerPaneProjectFilesStyle.general.basicFontSize + font.pointSize: DebuggerPaneStyle.general.basicFontSize } } @@ -448,7 +448,7 @@ Rectangle { anchors.verticalCenter: parent.verticalCenter color: "#4a4a4a" text: styleData.value - font.pointSize: DebuggerPaneProjectFilesStyle.general.basicFontSize + font.pointSize: DebuggerPaneStyle.general.basicFontSize } } } @@ -515,7 +515,7 @@ Rectangle { anchors.leftMargin: 5 color: "#4a4a4a" text: styleData.row; - font.pointSize: DebuggerPaneProjectFilesStyle.general.basicFontSize + font.pointSize: DebuggerPaneStyle.general.basicFontSize width: parent.width - 5 elide: Text.ElideRight } @@ -536,7 +536,7 @@ Rectangle { color: "#4a4a4a" text: styleData.value; elide: Text.ElideRight - font.pointSize: DebuggerPaneProjectFilesStyle.general.basicFontSize + font.pointSize: DebuggerPaneStyle.general.basicFontSize } } } @@ -586,7 +586,7 @@ Rectangle { anchors.leftMargin: 5 color: "#4a4a4a" text: styleData.value.split('\t')[0]; - font.pointSize: DebuggerPaneProjectFilesStyle.general.basicFontSize + font.pointSize: DebuggerPaneStyle.general.basicFontSize width: parent.width - 5 elide: Text.ElideRight } @@ -607,7 +607,7 @@ Rectangle { color: "#4a4a4a" text: styleData.value.split('\t')[1]; elide: Text.ElideRight - font.pointSize: DebuggerPaneProjectFilesStyle.general.basicFontSize + font.pointSize: DebuggerPaneStyle.general.basicFontSize } } } From 6a8c6cba6134d257e2d028a879de47181b8f42db Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Tue, 10 Feb 2015 08:35:18 +0100 Subject: [PATCH 055/213] start with test defined genesis block --- libdevcore/RLP.cpp | 2 +- test/TestHelper.h | 3 +- test/blFirstTestFiller.json | 17 ++ test/blValidBlockTestFiller.json | 71 ++++-- test/block.cpp | 365 +++++++++++++++++-------------- 5 files changed, 275 insertions(+), 183 deletions(-) diff --git a/libdevcore/RLP.cpp b/libdevcore/RLP.cpp index d72b5c20b..0dd61b876 100644 --- a/libdevcore/RLP.cpp +++ b/libdevcore/RLP.cpp @@ -177,7 +177,7 @@ void RLPStream::noteAppended(unsigned _itemCount) while (m_listStack.size()) { if (m_listStack.back().first < _itemCount) - BOOST_THROW_EXCEPTION(RLPException() << errinfo_comment("itemCount too large")); + BOOST_THROW_EXCEPTION(RLPException() << errinfo_comment("itemCount too large") << RequirementError((bigint)m_listStack.back().first, (bigint)_itemCount)); m_listStack.back().first -= _itemCount; if (m_listStack.back().first) break; diff --git a/test/TestHelper.h b/test/TestHelper.h index 344f61a3f..9ac1f0d4d 100644 --- a/test/TestHelper.h +++ b/test/TestHelper.h @@ -45,7 +45,7 @@ namespace test class ImportTest { public: - ImportTest() = default; + ImportTest(json_spirit::mObject& _o) : m_TestObject(_o) {} ImportTest(json_spirit::mObject& _o, bool isFiller); // imports @@ -53,6 +53,7 @@ public: void importState(json_spirit::mObject& _o, eth::State& _state); void importTransaction(json_spirit::mObject& _o); void exportTest(bytes _output, eth::State& _statePost); + std::map getStateMap(eth::State& _state){return _state.m_cache;} eth::State m_statePre; eth::State m_statePost; diff --git a/test/blFirstTestFiller.json b/test/blFirstTestFiller.json index 0084fda13..d4e6d109f 100644 --- a/test/blFirstTestFiller.json +++ b/test/blFirstTestFiller.json @@ -1,5 +1,22 @@ { "firstBlockTest" : { + "block" : { + "parentHash": "0xefb4db878627027c81b3bb1c7dd3a18dae3914a49cdd24a3e40ab3bbfbb240c5", + "uncleHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "coinbase": "0x8888f1f195afa192cfee860698584c030f4c9db1", + "stateRoot": "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "transactionsTrie": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "receiptTrie": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "bloom": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "difficulty": "023101", + "number": "62", + "gasLimit": "0x0dddb6", + "gasUsed": "100", + "timestamp": "0x54c98c81", + "extraData": "42", + "nonce": "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d" + }, + "pre" : {}, "transactions": [{ "nonce": "0", "gasPrice": "0x09184e72a000", diff --git a/test/blValidBlockTestFiller.json b/test/blValidBlockTestFiller.json index ab0369fa4..8b951b179 100644 --- a/test/blValidBlockTestFiller.json +++ b/test/blValidBlockTestFiller.json @@ -1,20 +1,61 @@ { "validBlock" : { "block" : { - "parentHash": "0xefb4db878627027c81b3bb1c7dd3a18dae3914a49cdd24a3e40ab3bbfbb240c5", - "uncleHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "coinbase": "0x8888f1f195afa192cfee860698584c030f4c9db1", - "stateRoot": "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", - "transactionsTrie": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "receiptTrie": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "bloom": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "difficulty": "023101", - "number": "62", - "gasLimit": "0x0dddb6", - "gasUsed": "100", - "timestamp": "0x54c98c81", - "extraData": "42", - "nonce": "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d" - } + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "1024", + "extraData" : "42", + "gasLimit" : "0x0dddb6", + "gasUsed" : "100", + "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", + "number" : "0", + "parentHash" : "0xefb4db878627027c81b3bb1c7dd3a18dae3914a49cdd24a3e40ab3bbfbb240c5", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0000000000000000000000000000000000000000", + "difficulty" : "130944", + "extraData" : "", + "gasLimit" : "999023", + "gasUsed" : "4803", + "nonce" : "62778f62183098b7cc8d221fc199654e613ca47b85696f940de3bd2bb6a2a54e", + "number" : "1", + "parentHash" : "c9cb614fddd89b3bc6e2f0ed1f8e58e8a0d826612a607a6151be6f39c991a941", + "receiptTrie" : "8fd35225dd530f30dc39719f9791583309b5889ad79bff0d31e9b1eb12f55000", + "stateRoot" : "b3ef9fe736086bdf1b3cd235f68097aab5f4c6e40d57f417d39c2cc6fb67f6c7", + "timestamp" : "1423490430", + "transactionsTrie" : "2cb4068eb8ccc9124426a7ed5c445b1353c997fc419031254ff7e2768c4dcd7f", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000", + "nonce" : 0, + "code" : "", + "storage": {} + } + }, + "rlp" : "0xf9033bf9012fa0c9cb614fddd89b3bc6e2f0ed1f8e58e8a0d826612a607a6151be6f39c991a941a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a0b3ef9fe736086bdf1b3cd235f68097aab5f4c6e40d57f417d39c2cc6fb67f6c7a02cb4068eb8ccc9124426a7ed5c445b1353c997fc419031254ff7e2768c4dcd7fa08fd35225dd530f30dc39719f9791583309b5889ad79bff0d31e9b1eb12f55000b840000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008301ff8001830f3e6f8212c38454d8bd7e80a062778f62183098b7cc8d221fc199654e613ca47b85696f940de3bd2bb6a2a54ef90205f90202808609184e72a000830f3e6f8080b901ae60056013565b6101918061001d6000396000f35b3360008190555056006001600060e060020a6000350480630a874df61461003a57806341c0e1b514610058578063a02b161e14610066578063dbbdf0831461007757005b610045600435610149565b80600160a060020a031660005260206000f35b610060610161565b60006000f35b6100716004356100d4565b60006000f35b61008560043560243561008b565b60006000f35b600054600160a060020a031632600160a060020a031614156100ac576100b1565b6100d0565b8060018360005260205260406000208190555081600060005260206000a15b5050565b600054600160a060020a031633600160a060020a031614158015610118575033600160a060020a0316600182600052602052604060002054600160a060020a031614155b61012157610126565b610146565b600060018260005260205260406000208190555080600060005260206000a15b50565b60006001826000526020526040600020549050919050565b600054600160a060020a031633600160a060020a0316146101815761018f565b600054600160a060020a0316ff5b561ba0d4287e915ebac7a8af390560fa53c8f0b7f13802ba0393d7afa5823c2560ca89a0ae75db31a34f7e386ad459646de98ec3a1c88cc91b11620b4ffd86871f579942c0", + "transactions" : [ + { + "data" : "", + "gasLimit" : "850", + "gasPrice" : "1", + "nonce" : "0", + "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", + "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "v" : "27", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] } } + diff --git a/test/block.cpp b/test/block.cpp index adf8a3ad9..9b598bbca 100644 --- a/test/block.cpp +++ b/test/block.cpp @@ -32,168 +32,194 @@ namespace dev { namespace test { bytes createBlockRLPFromFields(mObject& _tObj) { - BOOST_REQUIRE(_tObj.count("parentHash") > 0); - BOOST_REQUIRE(_tObj.count("uncleHash") > 0); - BOOST_REQUIRE(_tObj.count("coinbase") > 0); - BOOST_REQUIRE(_tObj.count("stateRoot") > 0); - BOOST_REQUIRE(_tObj.count("transactionsTrie")> 0); - BOOST_REQUIRE(_tObj.count("receiptTrie") > 0); - BOOST_REQUIRE(_tObj.count("bloom") > 0); - BOOST_REQUIRE(_tObj.count("difficulty") > 0); - BOOST_REQUIRE(_tObj.count("number") > 0); - BOOST_REQUIRE(_tObj.count("gasLimit")> 0); - BOOST_REQUIRE(_tObj.count("gasUsed") > 0); - BOOST_REQUIRE(_tObj.count("timestamp") > 0); - BOOST_REQUIRE(_tObj.count("extraData") > 0); - BOOST_REQUIRE(_tObj.count("nonce") > 0); - - // construct RLP of the given block - cout << "done with require\n"; - RLPStream rlpStream; - rlpStream.appendList(14); - cout << "increate aha1\n"; - rlpStream << h256(_tObj["parentHash"].get_str()) << h256(_tObj["uncleHash"].get_str()) << Address(_tObj["coinbase"].get_str()); - rlpStream << h256(_tObj["stateRoot"].get_str()) << h256(_tObj["transactionsTrie"].get_str()) << Address(_tObj["receiptTrie"].get_str()); - rlpStream << LogBloom(_tObj["bloom"].get_str()) << u256(_tObj["difficulty"].get_str()) << u256(_tObj["number"].get_str()); - rlpStream << u256(_tObj["gasLimit"].get_str()) << u256(_tObj["gasUsed"].get_str()) << u256(_tObj["timestamp"].get_str()); - rlpStream << importByteArray(_tObj["extraData"].get_str()) << h256(_tObj["nonce"].get_str()); - - return rlpStream.out(); + BOOST_REQUIRE(_tObj.count("parentHash") > 0); + BOOST_REQUIRE(_tObj.count("uncleHash") > 0); + BOOST_REQUIRE(_tObj.count("coinbase") > 0); + BOOST_REQUIRE(_tObj.count("stateRoot") > 0); + BOOST_REQUIRE(_tObj.count("transactionsTrie")> 0); + BOOST_REQUIRE(_tObj.count("receiptTrie") > 0); + BOOST_REQUIRE(_tObj.count("bloom") > 0); + BOOST_REQUIRE(_tObj.count("difficulty") > 0); + BOOST_REQUIRE(_tObj.count("number") > 0); + BOOST_REQUIRE(_tObj.count("gasLimit")> 0); + BOOST_REQUIRE(_tObj.count("gasUsed") > 0); + BOOST_REQUIRE(_tObj.count("timestamp") > 0); + BOOST_REQUIRE(_tObj.count("extraData") > 0); + BOOST_REQUIRE(_tObj.count("nonce") > 0); + + // construct RLP of the given block + cout << "done with require\n"; + RLPStream rlpStream; + rlpStream.appendList(14); + cout << "increate aha1\n"; + rlpStream << h256(_tObj["parentHash"].get_str()) << h256(_tObj["uncleHash"].get_str()) << Address(_tObj["coinbase"].get_str()); + rlpStream << h256(_tObj["stateRoot"].get_str()) << h256(_tObj["transactionsTrie"].get_str()) << Address(_tObj["receiptTrie"].get_str()); + rlpStream << LogBloom(_tObj["bloom"].get_str()) << u256(_tObj["difficulty"].get_str()) << u256(_tObj["number"].get_str()); + rlpStream << u256(_tObj["gasLimit"].get_str()) << u256(_tObj["gasUsed"].get_str()) << u256(_tObj["timestamp"].get_str()); + rlpStream << importByteArray(_tObj["extraData"].get_str()) << h256(_tObj["nonce"].get_str()); + + return rlpStream.out(); } void doBlockTests(json_spirit::mValue& _v, bool _fillin) { - for (auto& i: _v.get_obj()) - { - cerr << i.first << endl; - mObject& o = i.second.get_obj(); - - if (_fillin == false) - { - BOOST_REQUIRE(o.count("rlp") > 0); - const bytes rlpReaded = importByteArray(o["rlp"].get_str()); - RLP myRLP(rlpReaded); - BlockInfo blockFromRlp; - - try - { - blockFromRlp.populateFromHeader(myRLP, false); - //blockFromRlp.verifyInternals(rlpReaded); - } - catch(Exception const& _e) - { - cnote << "block construction did throw an exception: " << diagnostic_information(_e); - BOOST_ERROR("Failed block construction Test with Exception: " << _e.what()); - BOOST_CHECK_MESSAGE(o.count("block") == 0, "A block object should not be defined because the block RLP is invalid!"); - return; - } - - BOOST_REQUIRE(o.count("block") > 0); - - mObject tObj = o["block"].get_obj(); - BlockInfo blockFromFields; - const bytes rlpreade2 = createBlockRLPFromFields(tObj); - RLP mysecondRLP(rlpreade2); - blockFromFields.populateFromHeader(mysecondRLP, false); - - //Check the fields restored from RLP to original fields - BOOST_CHECK_MESSAGE(blockFromFields.hash == blockFromRlp.hash, "hash in given RLP not matching the block hash!"); - BOOST_CHECK_MESSAGE(blockFromFields.parentHash == blockFromRlp.parentHash, "parentHash in given RLP not matching the block parentHash!"); - BOOST_CHECK_MESSAGE(blockFromFields.sha3Uncles == blockFromRlp.sha3Uncles, "sha3Uncles in given RLP not matching the block sha3Uncles!"); - BOOST_CHECK_MESSAGE(blockFromFields.coinbaseAddress == blockFromRlp.coinbaseAddress,"coinbaseAddress in given RLP not matching the block coinbaseAddress!"); - BOOST_CHECK_MESSAGE(blockFromFields.stateRoot == blockFromRlp.stateRoot, "stateRoot in given RLP not matching the block stateRoot!"); - BOOST_CHECK_MESSAGE(blockFromFields.transactionsRoot == blockFromRlp.transactionsRoot, "transactionsRoot in given RLP not matching the block transactionsRoot!"); - BOOST_CHECK_MESSAGE(blockFromFields.logBloom == blockFromRlp.logBloom, "logBloom in given RLP not matching the block logBloom!"); - BOOST_CHECK_MESSAGE(blockFromFields.difficulty == blockFromRlp.difficulty, "difficulty in given RLP not matching the block difficulty!"); - BOOST_CHECK_MESSAGE(blockFromFields.number == blockFromRlp.number, "number in given RLP not matching the block number!"); - BOOST_CHECK_MESSAGE(blockFromFields.gasLimit == blockFromRlp.gasLimit,"gasLimit in given RLP not matching the block gasLimit!"); - BOOST_CHECK_MESSAGE(blockFromFields.gasUsed == blockFromRlp.gasUsed, "gasUsed in given RLP not matching the block gasUsed!"); - BOOST_CHECK_MESSAGE(blockFromFields.timestamp == blockFromRlp.timestamp, "timestamp in given RLP not matching the block timestamp!"); - BOOST_CHECK_MESSAGE(blockFromFields.extraData == blockFromRlp.extraData, "extraData in given RLP not matching the block extraData!"); - BOOST_CHECK_MESSAGE(blockFromFields.nonce == blockFromRlp.nonce, "nonce in given RLP not matching the block nonce!"); - - BOOST_CHECK_MESSAGE(blockFromFields == blockFromRlp, "However, blockFromFields != blockFromRlp!"); - - } - else - { -// BOOST_REQUIRE(o.count("block") > 0); - -// // construct Rlp of the given block -// bytes blockRLP = createBlockRLPFromFields(o["block"].get_obj()); -// RLP myRLP(blockRLP); -// o["rlp"] = toHex(blockRLP); + for (auto& i: _v.get_obj()) + { + cerr << i.first << endl; + mObject& o = i.second.get_obj(); + + if (_fillin == false) + { + // TODO + + // BOOST_REQUIRE(o.count("rlp") > 0); + // const bytes rlpReaded = importByteArray(o["rlp"].get_str()); + // RLP myRLP(rlpReaded); + // BlockInfo blockFromRlp; + + // try + // { + // blockFromRlp.populateFromHeader(myRLP, false); + // //blockFromRlp.verifyInternals(rlpReaded); + // } + // catch(Exception const& _e) + // { + // cnote << "block construction did throw an exception: " << diagnostic_information(_e); + // BOOST_ERROR("Failed block construction Test with Exception: " << _e.what()); + // BOOST_CHECK_MESSAGE(o.count("block") == 0, "A block object should not be defined because the block RLP is invalid!"); + // return; + // } + + // BOOST_REQUIRE(o.count("block") > 0); + + // mObject tObj = o["block"].get_obj(); + // BlockInfo blockFromFields; + // const bytes rlpreade2 = createBlockRLPFromFields(tObj); + // RLP mysecondRLP(rlpreade2); + // blockFromFields.populateFromHeader(mysecondRLP, false); + + // //Check the fields restored from RLP to original fields + // BOOST_CHECK_MESSAGE(blockFromFields.hash == blockFromRlp.hash, "hash in given RLP not matching the block hash!"); + // BOOST_CHECK_MESSAGE(blockFromFields.parentHash == blockFromRlp.parentHash, "parentHash in given RLP not matching the block parentHash!"); + // BOOST_CHECK_MESSAGE(blockFromFields.sha3Uncles == blockFromRlp.sha3Uncles, "sha3Uncles in given RLP not matching the block sha3Uncles!"); + // BOOST_CHECK_MESSAGE(blockFromFields.coinbaseAddress == blockFromRlp.coinbaseAddress,"coinbaseAddress in given RLP not matching the block coinbaseAddress!"); + // BOOST_CHECK_MESSAGE(blockFromFields.stateRoot == blockFromRlp.stateRoot, "stateRoot in given RLP not matching the block stateRoot!"); + // BOOST_CHECK_MESSAGE(blockFromFields.transactionsRoot == blockFromRlp.transactionsRoot, "transactionsRoot in given RLP not matching the block transactionsRoot!"); + // BOOST_CHECK_MESSAGE(blockFromFields.logBloom == blockFromRlp.logBloom, "logBloom in given RLP not matching the block logBloom!"); + // BOOST_CHECK_MESSAGE(blockFromFields.difficulty == blockFromRlp.difficulty, "difficulty in given RLP not matching the block difficulty!"); + // BOOST_CHECK_MESSAGE(blockFromFields.number == blockFromRlp.number, "number in given RLP not matching the block number!"); + // BOOST_CHECK_MESSAGE(blockFromFields.gasLimit == blockFromRlp.gasLimit,"gasLimit in given RLP not matching the block gasLimit!"); + // BOOST_CHECK_MESSAGE(blockFromFields.gasUsed == blockFromRlp.gasUsed, "gasUsed in given RLP not matching the block gasUsed!"); + // BOOST_CHECK_MESSAGE(blockFromFields.timestamp == blockFromRlp.timestamp, "timestamp in given RLP not matching the block timestamp!"); + // BOOST_CHECK_MESSAGE(blockFromFields.extraData == blockFromRlp.extraData, "extraData in given RLP not matching the block extraData!"); + // BOOST_CHECK_MESSAGE(blockFromFields.nonce == blockFromRlp.nonce, "nonce in given RLP not matching the block nonce!"); + + // BOOST_CHECK_MESSAGE(blockFromFields == blockFromRlp, "However, blockFromFields != blockFromRlp!"); + + } + else + { + BOOST_REQUIRE(o.count("block") > 0); + + // construct Rlp of the given block + bytes blockRLP = createBlockRLPFromFields(o["block"].get_obj()); + RLP myRLP(blockRLP); + BlockInfo blockFromFields; + cout << "blockFromFields diff:" << blockFromFields.difficulty << endl; -// try -// { -// BlockInfo blockFromFields; -// blockFromFields.populateFromHeader(myRLP, false); -// (void)blockFromFields; -// //blockFromFields.verifyInternals(blockRLP); -// } -// catch (Exception const& _e) -// { -// cnote << "block construction did throw an exception: " << diagnostic_information(_e); -// BOOST_ERROR("Failed block construction Test with Exception: " << _e.what()); -// o.erase(o.find("block")); -// } -// catch (std::exception const& _e) -// { -// cnote << "block construction did throw an exception: " << _e.what(); -// BOOST_ERROR("Failed block construction Test with Exception: " << _e.what()); -// o.erase(o.find("block")); -// } -// catch(...) -// { -// cnote << "block construction did throw an unknow exception\n"; -// o.erase(o.find("block")); -// } + try + { + + blockFromFields.populateFromHeader(myRLP, false); + //blockFromFields.verifyInternals(blockRLP); + } + catch (Exception const& _e) + { + cnote << "block construction did throw an exception: " << diagnostic_information(_e); + BOOST_ERROR("Failed block construction Test with Exception: " << _e.what()); + o.erase(o.find("block")); + } + catch (std::exception const& _e) + { + cnote << "block construction did throw an exception: " << _e.what(); + BOOST_ERROR("Failed block construction Test with Exception: " << _e.what()); + o.erase(o.find("block")); + } + catch(...) + { + cnote << "block construction did throw an unknown exception\n"; + o.erase(o.find("block")); + } - BOOST_REQUIRE(o.count("transactions") > 0); + BOOST_REQUIRE(o.count("transactions") > 0); TransactionQueue txs; - for (auto const& txObj: o["transactions"].get_array()) - { - mObject tx = txObj.get_obj(); - BOOST_REQUIRE(tx.count("nonce") > 0); - BOOST_REQUIRE(tx.count("gasPrice") > 0); - BOOST_REQUIRE(tx.count("gasLimit") > 0); - BOOST_REQUIRE(tx.count("to") > 0); - BOOST_REQUIRE(tx.count("value") > 0); - BOOST_REQUIRE(tx.count("v") > 0); - BOOST_REQUIRE(tx.count("r") > 0); - BOOST_REQUIRE(tx.count("s") > 0); - BOOST_REQUIRE(tx.count("data") > 0); + for (auto const& txObj: o["transactions"].get_array()) + { + mObject tx = txObj.get_obj(); + BOOST_REQUIRE(tx.count("nonce") > 0); + BOOST_REQUIRE(tx.count("gasPrice") > 0); + BOOST_REQUIRE(tx.count("gasLimit") > 0); + BOOST_REQUIRE(tx.count("to") > 0); + BOOST_REQUIRE(tx.count("value") > 0); + BOOST_REQUIRE(tx.count("v") > 0); + BOOST_REQUIRE(tx.count("r") > 0); + BOOST_REQUIRE(tx.count("s") > 0); + BOOST_REQUIRE(tx.count("data") > 0); cout << "attempt to import transaction\n"; txs.attemptImport(createTransactionFromFields(tx)); - } + } cout << "done importing txs\n"; + BOOST_REQUIRE(o.count("pre") > 0); + // create state + + ImportTest importer(o["pre"].get_obj()); + State theState(Address(), OverlayDB(), BaseState::Empty); + importer.importState(o["pre"].get_obj(), theState); + + cout << "current state diff 1 : " << theState.info().difficulty << endl; + cout << "balance of a94f5374fce5edbc8e2a8697c15331677e6ebf0b: " << theState.balance(Address("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")) << endl; + theState.commit(); + cout << "balance of a94f5374fce5edbc8e2a8697c15331677e6ebf0b: " << theState.balance(Address("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")) << endl; + blockFromFields.stateRoot = theState.rootHash(); + cout << "stateRoot: " << blockFromFields.stateRoot << endl; + // find new nonce + ProofOfWork pow; + MineInfo ret; + tie(ret, blockFromFields.nonce) = pow.mine(blockFromFields.headerHash(WithoutNonce), blockFromFields.difficulty, 1000, true, false); - //BOOST_REQUIRE(o.count("env") > 0); - //BOOST_REQUIRE(o.count("pre") > 0); + // create new "genesis" block" -// ImportTest importer; -// importer.importEnv(o["env"].get_obj()); -// importer.importState(o["pre"].get_obj(), m_statePre); + RLPStream rlpStream; + blockFromFields.streamRLP(rlpStream, WithNonce); -// State theState = importer.m_statePre; -// bytes output; + RLPStream block(3); + block.appendRaw(rlpStream.out()); + block.appendRaw(RLPEmptyList); + block.appendRaw(RLPEmptyList); + //return block.out(); + cout << "my genesis hash: " << sha3(RLP(block.out())[0].data()) << endl; cout << "construct bc\n"; - CanonBlockChain bc(true); - cout << "construct state\n"; - State theState; + BlockChain bc(block.out(), std::string(), true); + cout << "pre difficulty: " << blockFromFields.difficulty << endl; try { + //cout << "sync state with pre block" << endl; + theState.sync(bc); cout << "sync bc and txs in state\n"; + cout << "balance of a94f5374fce5edbc8e2a8697c15331677e6ebf0b: " << theState.balance(Address("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")) << endl; + cout << "current state diff: " << theState.info().difficulty << endl; theState.sync(bc,txs); + cout << "current state diff: " << theState.info().difficulty << endl; // lock cout << "commit to mine\n"; theState.commitToMine(bc); // will call uncommitToMine if a repeat. + cout << "current state diff: " << theState.info().difficulty << endl; // unlock MineInfo info; cout << "mine...\n"; @@ -201,9 +227,11 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) cout << "done mining, completeMine\n"; // lock theState.completeMine(); + cout << "current state diff: " << theState.info().difficulty << endl; // unlock cout << "new block: " << theState.blockData() << endl << theState.info() << endl; + cout << "current diff: " << theState.info().difficulty << endl; } catch (Exception const& _e) { @@ -214,35 +242,35 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) cnote << "state sync did throw an exception: " << _e.what(); } - o["rlp"] = "0x" + toHex(theState.blockData()); - - // write block header - - mObject oBlockHeader; - BlockInfo current_BlockHeader = theState.info(); - oBlockHeader["parentHash"] = toString(current_BlockHeader.parentHash); - oBlockHeader["uncleHash"] = toString(current_BlockHeader.sha3Uncles); - oBlockHeader["coinbase"] = toString(current_BlockHeader.coinbaseAddress); - oBlockHeader["stateRoot"] = toString(current_BlockHeader.stateRoot); - oBlockHeader["transactionsTrie"] = toString(current_BlockHeader.transactionsRoot); - oBlockHeader["receiptTrie"] = toString(current_BlockHeader.receiptsRoot); - oBlockHeader["bloom"] = toString(current_BlockHeader.logBloom); - oBlockHeader["difficulty"] = toString(current_BlockHeader.difficulty); - oBlockHeader["number"] = toString(current_BlockHeader.number); - oBlockHeader["gasLimit"] = toString(current_BlockHeader.gasLimit); - oBlockHeader["gasUsed"] = toString(current_BlockHeader.gasUsed); - oBlockHeader["timestamp"] = toString(current_BlockHeader.timestamp); - oBlockHeader["extraData"] = toHex(current_BlockHeader.extraData); - oBlockHeader["nonce"] = toString(current_BlockHeader.nonce); - - o["blockHeader"] = oBlockHeader; - - // write uncle list - - mArray aUncleList; // as of now, our parent is always the genesis block, so we can not have uncles. That might change. - o["uncleHeaders"] = aUncleList; - } - } + o["rlp"] = "0x" + toHex(theState.blockData()); + + // write block header + + mObject oBlockHeader; + BlockInfo current_BlockHeader = theState.info(); + oBlockHeader["parentHash"] = toString(current_BlockHeader.parentHash); + oBlockHeader["uncleHash"] = toString(current_BlockHeader.sha3Uncles); + oBlockHeader["coinbase"] = toString(current_BlockHeader.coinbaseAddress); + oBlockHeader["stateRoot"] = toString(current_BlockHeader.stateRoot); + oBlockHeader["transactionsTrie"] = toString(current_BlockHeader.transactionsRoot); + oBlockHeader["receiptTrie"] = toString(current_BlockHeader.receiptsRoot); + oBlockHeader["bloom"] = toString(current_BlockHeader.logBloom); + oBlockHeader["difficulty"] = toString(current_BlockHeader.difficulty); + oBlockHeader["number"] = toString(current_BlockHeader.number); + oBlockHeader["gasLimit"] = toString(current_BlockHeader.gasLimit); + oBlockHeader["gasUsed"] = toString(current_BlockHeader.gasUsed); + oBlockHeader["timestamp"] = toString(current_BlockHeader.timestamp); + oBlockHeader["extraData"] = toHex(current_BlockHeader.extraData); + oBlockHeader["nonce"] = toString(current_BlockHeader.nonce); + + o["blockHeader"] = oBlockHeader; + + // write uncle list + + mArray aUncleList; // as of now, our parent is always the genesis block, so we can not have uncles. That will change. + o["uncleHeaders"] = aUncleList; + } + } } } }// Namespace Close @@ -250,9 +278,14 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) BOOST_AUTO_TEST_SUITE(BlockTests) -BOOST_AUTO_TEST_CASE(blFirstTest) +//BOOST_AUTO_TEST_CASE(blFirstTest) +//{ +// dev::test::executeTests("blFirstTest", "/BlockTests", dev::test::doBlockTests); +//} + +BOOST_AUTO_TEST_CASE(blValidBlockTest) { - dev::test::executeTests("blFirstTest", "/BlockTests", dev::test::doBlockTests); + dev::test::executeTests("blValidBlockTest", "/BlockTests", dev::test::doBlockTests); } //BOOST_AUTO_TEST_CASE(ttCreateTest) From df50b9a784db711f13eae2dd2a561a0e718c26cd Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Tue, 10 Feb 2015 10:49:41 +0100 Subject: [PATCH 056/213] added missing pragma once --- libnatspec/NatspecExpressionEvaluator.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libnatspec/NatspecExpressionEvaluator.h b/libnatspec/NatspecExpressionEvaluator.h index fc122084e..2ea224027 100644 --- a/libnatspec/NatspecExpressionEvaluator.h +++ b/libnatspec/NatspecExpressionEvaluator.h @@ -19,6 +19,8 @@ * @date 2015 */ +#pragma once + #include #include #include From ce3638f75dd90b90e0d889975182ca6f1238e4a4 Mon Sep 17 00:00:00 2001 From: winsvega Date: Tue, 10 Feb 2015 13:07:31 +0300 Subject: [PATCH 057/213] Test related Constant in TestHelper.h Exception in TestHelper.h --- libdevcore/Exceptions.h | 1 - test/TestHelper.cpp | 14 ++++++-------- test/TestHelper.h | 3 +++ 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/libdevcore/Exceptions.h b/libdevcore/Exceptions.h index 961fc6f4c..e13d41476 100644 --- a/libdevcore/Exceptions.h +++ b/libdevcore/Exceptions.h @@ -33,7 +33,6 @@ namespace dev // base class for all exceptions struct Exception: virtual std::exception, virtual boost::exception { mutable std::string m_message; }; -struct ValueTooLarge: virtual Exception {}; struct BadHexCharacter: virtual Exception {}; struct RLPException: virtual Exception {}; struct BadCast: virtual RLPException {}; diff --git a/test/TestHelper.cpp b/test/TestHelper.cpp index ed351bb73..8e4c493eb 100644 --- a/test/TestHelper.cpp +++ b/test/TestHelper.cpp @@ -108,10 +108,9 @@ void ImportTest::importState(json_spirit::mObject& _o, State& _state) BOOST_REQUIRE(o.count("storage") > 0); BOOST_REQUIRE(o.count("code") > 0); - bigint biValue256 = bigint(1) << 256; - if (bigint(o["balance"].get_str()) >= biValue256) + if (bigint(o["balance"].get_str()) >= c_max256plus1) BOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("State 'balance' is equal or greater than 2**256") ); - if (bigint(o["nonce"].get_str()) >= biValue256) + if (bigint(o["nonce"].get_str()) >= c_max256plus1) BOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("State 'nonce' is equal or greater than 2**256") ); Address address = Address(i.first); @@ -146,14 +145,13 @@ void ImportTest::importTransaction(json_spirit::mObject& _o) BOOST_REQUIRE(_o.count("secretKey") > 0); BOOST_REQUIRE(_o.count("data") > 0); - bigint biValue256 = bigint(1) << 256; - if (bigint(_o["nonce"].get_str()) >= biValue256) + if (bigint(_o["nonce"].get_str()) >= c_max256plus1) BOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("Transaction 'nonce' is equal or greater than 2**256") ); - if (bigint(_o["gasPrice"].get_str()) >= biValue256) + if (bigint(_o["gasPrice"].get_str()) >= c_max256plus1) BOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("Transaction 'gasPrice' is equal or greater than 2**256") ); - if (bigint(_o["gasLimit"].get_str()) >= biValue256) + if (bigint(_o["gasLimit"].get_str()) >= c_max256plus1) BOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("Transaction 'gasLimit' is equal or greater than 2**256") ); - if (bigint(_o["value"].get_str()) >= biValue256) + if (bigint(_o["value"].get_str()) >= c_max256plus1) BOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("Transaction 'value' is equal or greater than 2**256") ); m_transaction = _o["to"].get_str().empty() ? diff --git a/test/TestHelper.h b/test/TestHelper.h index ae6ea20cc..2b93bccfb 100644 --- a/test/TestHelper.h +++ b/test/TestHelper.h @@ -42,6 +42,9 @@ void connectClients(Client& c1, Client& c2); namespace test { +struct ValueTooLarge: virtual Exception {}; +bigint const c_max256plus1 = bigint(1) << 256; + class ImportTest { public: From b6cb2a87eed2f8b2e8fc1083c0ec2801ee300980 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Tue, 10 Feb 2015 12:15:44 +0100 Subject: [PATCH 058/213] fixed jsoncpp find_path --- CMakeLists.txt | 7 ++++--- alethzero/NatspecHandler.h | 2 +- cmake/FindJsoncpp.cmake | 3 ++- libsolidity/ASTJsonConverter.h | 2 +- libsolidity/InterfaceHandler.h | 2 +- test/SolidityABIJSON.cpp | 2 +- test/SolidityNatspecJSON.cpp | 2 +- 7 files changed, 11 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a3adde425..a7de17000 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -135,15 +135,15 @@ endif() add_subdirectory(libdevcore) add_subdirectory(libevmcore) add_subdirectory(liblll) + if (NOT ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")) add_subdirectory(libserpent) + add_subdirectory(sc) endif () + add_subdirectory(libsolidity) add_subdirectory(lllc) add_subdirectory(solc) -if (NOT ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")) -add_subdirectory(sc) -endif() if (JSONRPC) add_subdirectory(libweb3jsonrpc) @@ -161,6 +161,7 @@ add_subdirectory(libethereum) add_subdirectory(libwebthree) add_subdirectory(test) add_subdirectory(eth) + if("x${CMAKE_BUILD_TYPE}" STREQUAL "xDebug") add_subdirectory(exp) endif () diff --git a/alethzero/NatspecHandler.h b/alethzero/NatspecHandler.h index edd9281d7..98677dbc2 100644 --- a/alethzero/NatspecHandler.h +++ b/alethzero/NatspecHandler.h @@ -26,7 +26,7 @@ #pragma warning(disable: 4100 4267) #include #pragma warning(pop) -#include +#include #include namespace ldb = leveldb; diff --git a/cmake/FindJsoncpp.cmake b/cmake/FindJsoncpp.cmake index 36ba12a3e..c5b9c87d8 100644 --- a/cmake/FindJsoncpp.cmake +++ b/cmake/FindJsoncpp.cmake @@ -12,7 +12,8 @@ # only look in default directories find_path( JSONCPP_INCLUDE_DIR - NAMES jsoncpp/json/json.h + NAMES json/json.h + PATH_SUFFIXES jsoncpp DOC "jsoncpp include dir" ) diff --git a/libsolidity/ASTJsonConverter.h b/libsolidity/ASTJsonConverter.h index cb43c2d9e..466801e9c 100644 --- a/libsolidity/ASTJsonConverter.h +++ b/libsolidity/ASTJsonConverter.h @@ -27,7 +27,7 @@ #include #include #include -#include +#include namespace dev { diff --git a/libsolidity/InterfaceHandler.h b/libsolidity/InterfaceHandler.h index 2b62cabdf..08232e4d2 100644 --- a/libsolidity/InterfaceHandler.h +++ b/libsolidity/InterfaceHandler.h @@ -28,7 +28,7 @@ #include #include -#include +#include namespace dev { diff --git a/test/SolidityABIJSON.cpp b/test/SolidityABIJSON.cpp index d600340eb..9cb7c9445 100644 --- a/test/SolidityABIJSON.cpp +++ b/test/SolidityABIJSON.cpp @@ -22,7 +22,7 @@ #include #include -#include +#include #include namespace dev diff --git a/test/SolidityNatspecJSON.cpp b/test/SolidityNatspecJSON.cpp index 911820ddd..91d504e8c 100644 --- a/test/SolidityNatspecJSON.cpp +++ b/test/SolidityNatspecJSON.cpp @@ -21,7 +21,7 @@ */ #include -#include +#include #include #include #include From 2ad606baeb7db4c3ba11dde1495dad07498676ff Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 10 Feb 2015 12:40:00 +0100 Subject: [PATCH 059/213] bug fix #995 mix: Menu item "Open Project" doesn't do anything #995 --- mix/qml/ProjectList.qml | 5 +++++ mix/qml/ProjectModel.qml | 26 +------------------------- mix/qml/js/ProjectModel.js | 8 -------- mix/qml/main.qml | 27 +++++++++++++++++++++++++-- 4 files changed, 31 insertions(+), 35 deletions(-) diff --git a/mix/qml/ProjectList.qml b/mix/qml/ProjectList.qml index 138e86fe9..6895de125 100644 --- a/mix/qml/ProjectList.qml +++ b/mix/qml/ProjectList.qml @@ -137,7 +137,12 @@ Item { sectionModel.clear(); } + onProjectClosed: { + sectionModel.clear(); + } + onProjectLoaded: { + sectionModel.clear(); addDocToSubModel(); if (modelData === "Contracts") { diff --git a/mix/qml/ProjectModel.qml b/mix/qml/ProjectModel.qml index 42bf91d9d..10dde5b41 100644 --- a/mix/qml/ProjectModel.qml +++ b/mix/qml/ProjectModel.qml @@ -34,11 +34,9 @@ Item { //interface function saveAll() { ProjectModelCode.saveAll(); } function createProject() { ProjectModelCode.createProject(); } - function browseProject() { ProjectModelCode.browseProject(); } function closeProject() { ProjectModelCode.closeProject(); } function saveProject() { ProjectModelCode.saveProject(); } function loadProject(path) { ProjectModelCode.loadProject(path); } - function addExistingFile() { ProjectModelCode.addExistingFile(); } function newHtmlFile() { ProjectModelCode.newHtmlFile(); } function newJsFile() { ProjectModelCode.newJsFile(); } function newCssFile() { ProjectModelCode.newCssFile(); } @@ -50,6 +48,7 @@ Item { function removeDocument(documentId) { ProjectModelCode.removeDocument(documentId); } function getDocument(documentId) { return ProjectModelCode.getDocument(documentId); } function getDocumentIndex(documentId) { return ProjectModelCode.getDocumentIndex(documentId); } + function doAddExistingFiles(paths) { ProjectModelCode.doAddExistingFiles(paths); } Connections { target: appContext @@ -96,27 +95,4 @@ Item { id: projectSettings property string lastProjectPath; } - - FileDialog { - id: openProjectFileDialog - visible: false - title: qsTr("Open a Project") - selectFolder: true - onAccepted: { - var path = openProjectFileDialog.fileUrl.toString(); - path += "/"; - loadProject(path); - } - } - - FileDialog { - id: addExistingFileDialog - visible: false - title: qsTr("Add a File") - selectFolder: false - onAccepted: { - var paths = addExistingFileDialog.fileUrls; - ProjectModelCode.doAddExistingFiles(paths); - } - } } diff --git a/mix/qml/js/ProjectModel.js b/mix/qml/js/ProjectModel.js index ac44dffa9..7c7a8ae4c 100644 --- a/mix/qml/js/ProjectModel.js +++ b/mix/qml/js/ProjectModel.js @@ -28,10 +28,6 @@ function createProject() { newProjectDialog.open(); } -function browseProject() { - openProjectFileDialog.open(); -} - function closeProject() { if (!isEmpty) { if (haveUnsavedChanges) @@ -77,10 +73,6 @@ function loadProject(path) { projectLoaded() } -function addExistingFile() { - addExistingFileDialog.open(); -} - function addFile(fileName) { var p = projectPath + fileName; var extension = fileName.substring(fileName.lastIndexOf("."), fileName.length); diff --git a/mix/qml/main.qml b/mix/qml/main.qml index ea5d6dd04..79430eb59 100644 --- a/mix/qml/main.qml +++ b/mix/qml/main.qml @@ -203,7 +203,19 @@ ApplicationWindow { text: qsTr("&Open Project") shortcut: "Ctrl+O" enabled: true; - onTriggered: projectModel.browseProject(); + onTriggered: openProjectFileDialog.open() + } + + FileDialog { + id: openProjectFileDialog + visible: false + title: qsTr("Open a Project") + selectFolder: true + onAccepted: { + var path = openProjectFileDialog.fileUrl.toString(); + path += "/"; + projectModel.loadProject(path); + } } Action { @@ -243,7 +255,18 @@ ApplicationWindow { text: qsTr("Add Existing File") shortcut: "Ctrl+Alt+A" enabled: !projectModel.isEmpty - onTriggered: projectModel.addExistingFile(); + onTriggered: addExistingFileDialog.open() + } + + FileDialog { + id: addExistingFileDialog + visible: false + title: qsTr("Add a File") + selectFolder: false + onAccepted: { + var paths = addExistingFileDialog.fileUrls; + projectModel.doAddExistingFiles(paths); + } } Action { From 604aef47cbd1a67d917ba8d4d352cd38eb290dfe Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Tue, 10 Feb 2015 14:31:27 +0100 Subject: [PATCH 060/213] BuildInfo.sh replaced with custom cmake script --- BuildInfo.h.in | 7 +++++ BuildInfo.sh | 55 ----------------------------------- CMakeLists.txt | 7 ++++- cmake/EthDependencies.cmake | 8 +++++ cmake/scripts/buildinfo.cmake | 33 +++++++++++++++++++++ cmake/scripts/configure.cmake | 14 +++++++++ 6 files changed, 68 insertions(+), 56 deletions(-) create mode 100644 BuildInfo.h.in delete mode 100644 BuildInfo.sh create mode 100644 cmake/scripts/buildinfo.cmake create mode 100644 cmake/scripts/configure.cmake diff --git a/BuildInfo.h.in b/BuildInfo.h.in new file mode 100644 index 000000000..7d2bfc1c8 --- /dev/null +++ b/BuildInfo.h.in @@ -0,0 +1,7 @@ +#pragma once + +#define ETH_COMMIT_HASH @ETH_COMMIT_HASH@ +#define ETH_CLEAN_REPO @ETH_CLEAN_REPO@ +#define ETH_BUILD_TYPE @ETH_BUILD_TYPE@ +#define ETH_BUILD_PLATFORM @ETH_BUILD_PLATFORM@ + diff --git a/BuildInfo.sh b/BuildInfo.sh deleted file mode 100644 index 0370297df..000000000 --- a/BuildInfo.sh +++ /dev/null @@ -1,55 +0,0 @@ -CURRENT_SOURCE_DIR=$1 -CURRENT_BINARY_DIR=$2 -BUILD_TYPE=$3 -BUILD_PLATFORM=$4 - -echo "Current source dir: $CURRENT_SOURCE_DIR" -echo "Current binary dir: $CURRENT_BINARY_DIR" -echo "Build type: $BUILD_TYPE" -echo "Build platform: $BUILD_PLATFORM" - -if [[ -e "$CURRENT_SOURCE_DIR/BuildInfo.h" ]] -then - echo "Using existing BuildInfo.h" - cp $CURRENT_SOURCE_DIR/BuildInfo.h $CURRENT_BINARY_DIR/BuildInfo.h.tmp -else - if [[ -e "$CURRENT_SOURCE_DIR/.git" ]] - then - ETH_COMMIT_HASH=$(git --git-dir=$CURRENT_SOURCE_DIR/.git --work-tree=$CURRENT_SOURCE_DIR rev-parse HEAD) - ETH_LOCAL_CHANGES=$(git --git-dir=$CURRENT_SOURCE_DIR/.git --work-tree=$CURRENT_SOURCE_DIR diff --shortstat) - if [[ -z "$ETH_LOCAL_CHANGES" ]] - then - ETH_CLEAN_REPO=1 - else - ETH_CLEAN_REPO=0 - fi - - echo "Commit hash: ${ETH_COMMIT_HASH} (Clean: ${ETH_CLEAN_REPO} - ${ETH_LOCAL_CHANGES})" - else - echo "Unknown repo." - ETH_COMMIT_HASH=0 - ETH_CLEAN_REPO=1 - fi - - echo "// This file was automatically generated by cmake" > $CURRENT_BINARY_DIR/BuildInfo.h.tmp - echo "" >> $CURRENT_BINARY_DIR/BuildInfo.h.tmp - echo "#pragma once" >> $CURRENT_BINARY_DIR/BuildInfo.h.tmp - echo "" >> $CURRENT_BINARY_DIR/BuildInfo.h.tmp - echo "#define ETH_COMMIT_HASH $ETH_COMMIT_HASH" >> $CURRENT_BINARY_DIR/BuildInfo.h.tmp - echo "#define ETH_CLEAN_REPO $ETH_CLEAN_REPO" >> $CURRENT_BINARY_DIR/BuildInfo.h.tmp - echo "#define ETH_BUILD_TYPE $BUILD_TYPE" >> $CURRENT_BINARY_DIR/BuildInfo.h.tmp - echo "#define ETH_BUILD_PLATFORM $BUILD_PLATFORM" >> $CURRENT_BINARY_DIR/BuildInfo.h.tmp -fi - -if [[ -e "$CURRENT_BINARY_DIR/BuildInfo.h" ]] -then - DIFF=$(diff $CURRENT_BINARY_DIR/BuildInfo.h $CURRENT_BINARY_DIR/BuildInfo.h.tmp) - if [[ -z "$DIFF" ]] - then - rm $CURRENT_BINARY_DIR/BuildInfo.h.tmp - else - mv $CURRENT_BINARY_DIR/BuildInfo.h.tmp $CURRENT_BINARY_DIR/BuildInfo.h - fi -else - mv $CURRENT_BINARY_DIR/BuildInfo.h.tmp $CURRENT_BINARY_DIR/BuildInfo.h -fi diff --git a/CMakeLists.txt b/CMakeLists.txt index a3adde425..e6b49bf72 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -86,7 +86,12 @@ function(createBuildInfo) endif() # Generate header file containing useful build information - add_custom_target(BuildInfo.h ALL COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/BuildInfo.sh ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${_cmake_build_type} ${ETH_BUILD_PLATFORM}) + add_custom_target(BuildInfo.h ALL + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + COMMAND cmake -DETH_SOURCE_DIR=${CMAKE_SOURCE_DIR} -DETH_DST_DIR=${CMAKE_BINARY_DIR} + -DETH_BUILD_TYPE=${_cmake_build_type} -DETH_BUILD_PLATFORM=${ETH_BUILD_PLATFORM} + -P ${ETH_SCRIPTS_DIR}/buildinfo.cmake + ) include_directories(${CMAKE_CURRENT_BINARY_DIR}) set(CMAKE_INCLUDE_CURRENT_DIR ON) diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake index 8ff3d1460..00f99e7e3 100644 --- a/cmake/EthDependencies.cmake +++ b/cmake/EthDependencies.cmake @@ -7,6 +7,14 @@ string(TOLOWER ${CMAKE_SYSTEM_NAME} _system_name) set (ETH_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/extdep/install/${_system_name}") set (CMAKE_PREFIX_PATH ${ETH_DEPENDENCY_INSTALL_DIR}) +# setup directory for cmake generated files and include it globally +# it's not used yet, but if we have more generated files, consider moving them to ETH_GENERATED_DIR +set(ETH_GENERATED_DIR "${PROJECT_BINARY_DIR}/gen") +include_directories(${ETH_GENERATED_DIR}) + +# custom cmake scripts +set(ETH_SCRIPTS_DIR ${CMAKE_SOURCE_DIR}/cmake/scripts) + # Qt5 requires opengl # TODO use proper version of windows SDK (32 vs 64) # TODO make it possible to use older versions of windows SDK (7.0+ should also work) diff --git a/cmake/scripts/buildinfo.cmake b/cmake/scripts/buildinfo.cmake new file mode 100644 index 000000000..870cbf4e1 --- /dev/null +++ b/cmake/scripts/buildinfo.cmake @@ -0,0 +1,33 @@ +# generates BuildInfo.h +# +# this module expects +# ETH_SOURCE_DIR - main CMAKE_SOURCE_DIR +# ETH_DST_DIR - main CMAKE_BINARY_DIR +# ETH_BUILD_TYPE +# ETH_BUILD_PLATFORM +# +# example usage: +# cmake -DETH_SOURCE_DIR=. -DETH_DST_DIR=build -DETH_BUILD_TYPE=Debug -DETH_BUILD_PLATFORM=mac -P scripts/buildinfo.cmake + +execute_process( + COMMAND git --git-dir=${ETH_SOURCE_DIR}/.git --work-tree=${ETH_SOURCE_DIR} rev-parse HEAD + OUTPUT_VARIABLE ETH_COMMIT_HASH +) + +if (NOT ETH_COMMIT_HASH) + set(ETH_COMMIT_HASH 0) +endif() + +execute_process( + COMMAND git --git-dir=${ETH_SOURCE_DIR}/.git --work-tree=${ETH_SOURCE_DIR} diff --shortstat + OUTPUT_VARIABLE ETH_LOCAL_CHANGES +) + +if (ETH_LOCAL_CHANGES) + set(ETH_CLEAN_REPO 0) +else() + set(ETH_CLEAN_REPO 1) +endif() + +configure_file("${ETH_SOURCE_DIR}/BuildInfo.h.in" "${ETH_DST_DIR}/BuildInfo.h") + diff --git a/cmake/scripts/configure.cmake b/cmake/scripts/configure.cmake new file mode 100644 index 000000000..76fb7b757 --- /dev/null +++ b/cmake/scripts/configure.cmake @@ -0,0 +1,14 @@ +# adds possibility to run configure_file as buildstep +# reference: +# http://www.cmake.org/pipermail/cmake/2012-May/050227.html +# +# This module expects +# INFILE +# OUTFILE +# other custom vars +# +# example usage: +# cmake -DINFILE=blah.in -DOUTFILE=blah.out -Dvar1=value1 -Dvar2=value2 -P scripts/configure.cmake + +configure_file(${INFILE} ${OUTFILE}) + From 169438191ee1404ea09ac198446e7768a23124a5 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Tue, 10 Feb 2015 14:36:56 +0100 Subject: [PATCH 061/213] build_type && build_platform unknown by default --- cmake/scripts/buildinfo.cmake | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cmake/scripts/buildinfo.cmake b/cmake/scripts/buildinfo.cmake index 870cbf4e1..b33ca1954 100644 --- a/cmake/scripts/buildinfo.cmake +++ b/cmake/scripts/buildinfo.cmake @@ -9,6 +9,14 @@ # example usage: # cmake -DETH_SOURCE_DIR=. -DETH_DST_DIR=build -DETH_BUILD_TYPE=Debug -DETH_BUILD_PLATFORM=mac -P scripts/buildinfo.cmake +if (NOT ETH_BUILD_TYPE) + set(ETH_BUILD_TYPE "unknown") +endif() + +if (NOT ETH_BUILD_PLATFORM) + set(ETH_BUILD_PLATFORM "unknown") +endif() + execute_process( COMMAND git --git-dir=${ETH_SOURCE_DIR}/.git --work-tree=${ETH_SOURCE_DIR} rev-parse HEAD OUTPUT_VARIABLE ETH_COMMIT_HASH From 31d02099242e18e8f17c3db8481c1cfb43385217 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Tue, 10 Feb 2015 15:44:35 +0100 Subject: [PATCH 062/213] check if BuildInfo.h is outdated --- cmake/scripts/buildinfo.cmake | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/cmake/scripts/buildinfo.cmake b/cmake/scripts/buildinfo.cmake index b33ca1954..5b9f2fbf1 100644 --- a/cmake/scripts/buildinfo.cmake +++ b/cmake/scripts/buildinfo.cmake @@ -10,25 +10,25 @@ # cmake -DETH_SOURCE_DIR=. -DETH_DST_DIR=build -DETH_BUILD_TYPE=Debug -DETH_BUILD_PLATFORM=mac -P scripts/buildinfo.cmake if (NOT ETH_BUILD_TYPE) - set(ETH_BUILD_TYPE "unknown") + set(ETH_BUILD_TYPE "unknown") endif() if (NOT ETH_BUILD_PLATFORM) - set(ETH_BUILD_PLATFORM "unknown") + set(ETH_BUILD_PLATFORM "unknown") endif() execute_process( COMMAND git --git-dir=${ETH_SOURCE_DIR}/.git --work-tree=${ETH_SOURCE_DIR} rev-parse HEAD - OUTPUT_VARIABLE ETH_COMMIT_HASH + OUTPUT_VARIABLE ETH_COMMIT_HASH OUTPUT_STRIP_TRAILING_WHITESPACE ) if (NOT ETH_COMMIT_HASH) - set(ETH_COMMIT_HASH 0) + set(ETH_COMMIT_HASH 0) endif() execute_process( COMMAND git --git-dir=${ETH_SOURCE_DIR}/.git --work-tree=${ETH_SOURCE_DIR} diff --shortstat - OUTPUT_VARIABLE ETH_LOCAL_CHANGES + OUTPUT_VARIABLE ETH_LOCAL_CHANGES OUTPUT_STRIP_TRAILING_WHITESPACE ) if (ETH_LOCAL_CHANGES) @@ -37,5 +37,25 @@ else() set(ETH_CLEAN_REPO 1) endif() -configure_file("${ETH_SOURCE_DIR}/BuildInfo.h.in" "${ETH_DST_DIR}/BuildInfo.h") +set(INFILE "${ETH_SOURCE_DIR}/BuildInfo.h.in") +set(TMPFILE "${ETH_DST_DIR}/BuildInfo.h.tmp") +set(OUTFILE "${ETH_DST_DIR}/BuildInfo.h") + +# create outfile if it doesn't exist +if (NOT (EXISTS ${OUTFILE})) + execute_process(COMMAND touch ${OUTFILE}) +endif() + +configure_file("${INFILE}" "${TMPFILE}") + +execute_process( + COMMAND diff "${OUTFILE}" "${TMPFILE}" + OUTPUT_VARIABLE ETH_FILE_OUTDATED +) + +if (ETH_FILE_OUTDATED) + execute_process(COMMAND mv "${TMPFILE}" "${OUTFILE}") +else() + execute_process(COMMAND rm "${TMPFILE}") +endif() From 3128f90f7702d459d085bb061abb0947a37f2312 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Tue, 10 Feb 2015 16:23:18 +0100 Subject: [PATCH 063/213] quotes --- CMakeLists.txt | 6 +++--- cmake/scripts/buildinfo.cmake | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e6b49bf72..70598f614 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -88,9 +88,9 @@ function(createBuildInfo) # Generate header file containing useful build information add_custom_target(BuildInfo.h ALL WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - COMMAND cmake -DETH_SOURCE_DIR=${CMAKE_SOURCE_DIR} -DETH_DST_DIR=${CMAKE_BINARY_DIR} - -DETH_BUILD_TYPE=${_cmake_build_type} -DETH_BUILD_PLATFORM=${ETH_BUILD_PLATFORM} - -P ${ETH_SCRIPTS_DIR}/buildinfo.cmake + COMMAND cmake -DETH_SOURCE_DIR="${CMAKE_SOURCE_DIR}" -DETH_DST_DIR="${CMAKE_BINARY_DIR}" + -DETH_BUILD_TYPE="${_cmake_build_type}" -DETH_BUILD_PLATFORM="${ETH_BUILD_PLATFORM}" + -P "${ETH_SCRIPTS_DIR}/buildinfo.cmake" ) include_directories(${CMAKE_CURRENT_BINARY_DIR}) diff --git a/cmake/scripts/buildinfo.cmake b/cmake/scripts/buildinfo.cmake index 5b9f2fbf1..e61e3fa15 100644 --- a/cmake/scripts/buildinfo.cmake +++ b/cmake/scripts/buildinfo.cmake @@ -42,8 +42,8 @@ set(TMPFILE "${ETH_DST_DIR}/BuildInfo.h.tmp") set(OUTFILE "${ETH_DST_DIR}/BuildInfo.h") # create outfile if it doesn't exist -if (NOT (EXISTS ${OUTFILE})) - execute_process(COMMAND touch ${OUTFILE}) +if (NOT (EXISTS "${OUTFILE}")) + execute_process(COMMAND touch "${OUTFILE}") endif() configure_file("${INFILE}" "${TMPFILE}") From e85fe2348f0ca293594546b89933aafe9604bb47 Mon Sep 17 00:00:00 2001 From: Lu Guanqun Date: Sun, 8 Feb 2015 19:23:17 +0800 Subject: [PATCH 064/213] add exponent operator https://www.pivotaltracker.com/n/projects/1189488/stories/83746404 --- libsolidity/ExpressionCompiler.cpp | 3 +++ libsolidity/Scanner.cpp | 10 ++++++++-- libsolidity/Token.h | 5 +++-- libsolidity/Types.cpp | 10 ++++++++++ test/SolidityEndToEndTest.cpp | 30 ++++++++++++++++++++++++++++++ test/SolidityParser.cpp | 11 +++++++++++ 6 files changed, 65 insertions(+), 4 deletions(-) diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index 1d3f23e69..beda01322 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -650,6 +650,9 @@ void ExpressionCompiler::appendArithmeticOperatorCode(Token::Value _operator, Ty case Token::Mod: m_context << (c_isSigned ? eth::Instruction::SMOD : eth::Instruction::MOD); break; + case Token::Exp: + m_context << eth::Instruction::EXP; + break; default: BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown arithmetic operator.")); } diff --git a/libsolidity/Scanner.cpp b/libsolidity/Scanner.cpp index fc4bdb6b5..fbe3ea974 100644 --- a/libsolidity/Scanner.cpp +++ b/libsolidity/Scanner.cpp @@ -465,8 +465,14 @@ void Scanner::scanToken() token = Token::Sub; break; case '*': - // * *= - token = selectToken('=', Token::AssignMul, Token::Mul); + // * ** *= + advance(); + if (m_char == '*') + token = selectToken(Token::Exp); + else if (m_char == '=') + token = selectToken(Token::AssignMul); + else + token = Token::Mul; break; case '%': // % %= diff --git a/libsolidity/Token.h b/libsolidity/Token.h index b913f0cec..ac8c618fa 100644 --- a/libsolidity/Token.h +++ b/libsolidity/Token.h @@ -118,6 +118,7 @@ namespace solidity T(Mul, "*", 13) \ T(Div, "/", 13) \ T(Mod, "%", 13) \ + T(Exp, "**", 14) \ \ /* Compare operators sorted by precedence. */ \ /* IsCompareOp() relies on this block of enum values */ \ @@ -361,10 +362,10 @@ public: // Predicates static bool isElementaryTypeName(Value tok) { return Int <= tok && tok < TypesEnd; } static bool isAssignmentOp(Value tok) { return Assign <= tok && tok <= AssignMod; } - static bool isBinaryOp(Value op) { return Comma <= op && op <= Mod; } + static bool isBinaryOp(Value op) { return Comma <= op && op <= Exp; } static bool isCommutativeOp(Value op) { return op == BitOr || op == BitXor || op == BitAnd || op == Add || op == Mul || op == Equal || op == NotEqual; } - static bool isArithmeticOp(Value op) { return Add <= op && op <= Mod; } + static bool isArithmeticOp(Value op) { return Add <= op && op <= Exp; } static bool isCompareOp(Value op) { return Equal <= op && op <= In; } static Value AssignmentToBinaryOp(Value op) diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index 6fd9e8b4c..dcc0738d7 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -320,6 +320,16 @@ TypePointer IntegerConstantType::binaryOperatorResult(Token::Value _operator, Ty return TypePointer(); value = m_value % other.m_value; break; + case Token::Exp: + if (other.m_value < 0) + BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("exponent can't be negative")); + else + { + value = boost::multiprecision::powm(m_value, other.m_value, bigint(2) << 256); + if (value >= (bigint(1) << 256)) + BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("exp result overflowed")); + } + break; default: return TypePointer(); } diff --git a/test/SolidityEndToEndTest.cpp b/test/SolidityEndToEndTest.cpp index 31b80894e..748110145 100644 --- a/test/SolidityEndToEndTest.cpp +++ b/test/SolidityEndToEndTest.cpp @@ -56,6 +56,36 @@ BOOST_AUTO_TEST_CASE(empty_contract) BOOST_CHECK(callContractFunction("i_am_not_there()", bytes()).empty()); } +BOOST_AUTO_TEST_CASE(exp_operator) +{ + char const* sourceCode = R"( + contract test { + function f(uint a) returns(uint d) { return 2 ** a; } + })"; + compileAndRun(sourceCode); + testSolidityAgainstCppOnRange("f(uint256)", [](u256 const& a) -> u256 { return u256(1 << a.convert_to()); }, 0, 16); +} + +BOOST_AUTO_TEST_CASE(exp_operator_const) +{ + char const* sourceCode = R"( + contract test { + function f() returns(uint d) { return 2 ** 3; } + })"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("f()", bytes()) == toBigEndian(u256(8))); +} + +BOOST_AUTO_TEST_CASE(exp_operator_const_signed) +{ + char const* sourceCode = R"( + contract test { + function f() returns(int d) { return -2 ** 3; } + })"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("f()", bytes()) == toBigEndian(u256(-8))); +} + BOOST_AUTO_TEST_CASE(recursive_calls) { char const* sourceCode = "contract test {\n" diff --git a/test/SolidityParser.cpp b/test/SolidityParser.cpp index 7af99567b..84f36170f 100644 --- a/test/SolidityParser.cpp +++ b/test/SolidityParser.cpp @@ -387,6 +387,17 @@ BOOST_AUTO_TEST_CASE(complex_expression) BOOST_CHECK_NO_THROW(parseText(text)); } +BOOST_AUTO_TEST_CASE(exp_expression) +{ + char const* text = R"( + contract test { + function fun(uint256 a) { + uint256 x = 3 ** a; + } + })"; + BOOST_CHECK_NO_THROW(parseText(text)); +} + BOOST_AUTO_TEST_CASE(while_loop) { char const* text = "contract test {\n" From aabc234e457075197b70b673c4002994e417a2ed Mon Sep 17 00:00:00 2001 From: Lu Guanqun Date: Mon, 9 Feb 2015 23:15:36 +0800 Subject: [PATCH 065/213] add two more exp tests --- test/SolidityNameAndTypeResolution.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/test/SolidityNameAndTypeResolution.cpp b/test/SolidityNameAndTypeResolution.cpp index f4be31f4b..b529f0b70 100644 --- a/test/SolidityNameAndTypeResolution.cpp +++ b/test/SolidityNameAndTypeResolution.cpp @@ -974,6 +974,24 @@ BOOST_AUTO_TEST_CASE(overflow_caused_by_ether_units) BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); } +BOOST_AUTO_TEST_CASE(exp_operator_negative_exponent) +{ + char const* sourceCode = R"( + contract test { + function f() returns(uint d) { return 2 ** -3; } + })"; + BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), InternalCompilerError); +} + +BOOST_AUTO_TEST_CASE(exp_operator_const_overflowed) +{ + char const* sourceCode = R"( + contract test { + function f() returns(uint d) { return 10 ** 256; } + })"; + BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), InternalCompilerError); +} + BOOST_AUTO_TEST_SUITE_END() } From 1372154ff2955068b30b00d352726822a6fc28f6 Mon Sep 17 00:00:00 2001 From: Lu Guanqun Date: Tue, 10 Feb 2015 22:43:13 +0800 Subject: [PATCH 066/213] small fixes per chris's comments --- libsolidity/Types.cpp | 12 ++++++------ test/SolidityEndToEndTest.cpp | 2 +- test/SolidityNameAndTypeResolution.cpp | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index dcc0738d7..5f573a6da 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -26,6 +26,8 @@ #include #include +#include + using namespace std; namespace dev @@ -322,13 +324,11 @@ TypePointer IntegerConstantType::binaryOperatorResult(Token::Value _operator, Ty break; case Token::Exp: if (other.m_value < 0) - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("exponent can't be negative")); + return TypePointer(); + else if (other.m_value > std::numeric_limits::max()) + return TypePointer(); else - { - value = boost::multiprecision::powm(m_value, other.m_value, bigint(2) << 256); - if (value >= (bigint(1) << 256)) - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("exp result overflowed")); - } + value = boost::multiprecision::pow(m_value, other.m_value.convert_to()); break; default: return TypePointer(); diff --git a/test/SolidityEndToEndTest.cpp b/test/SolidityEndToEndTest.cpp index 748110145..13a666fbf 100644 --- a/test/SolidityEndToEndTest.cpp +++ b/test/SolidityEndToEndTest.cpp @@ -80,7 +80,7 @@ BOOST_AUTO_TEST_CASE(exp_operator_const_signed) { char const* sourceCode = R"( contract test { - function f() returns(int d) { return -2 ** 3; } + function f() returns(int d) { return (-2) ** 3; } })"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("f()", bytes()) == toBigEndian(u256(-8))); diff --git a/test/SolidityNameAndTypeResolution.cpp b/test/SolidityNameAndTypeResolution.cpp index b529f0b70..d013f5c5e 100644 --- a/test/SolidityNameAndTypeResolution.cpp +++ b/test/SolidityNameAndTypeResolution.cpp @@ -980,16 +980,16 @@ BOOST_AUTO_TEST_CASE(exp_operator_negative_exponent) contract test { function f() returns(uint d) { return 2 ** -3; } })"; - BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), InternalCompilerError); + BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); } -BOOST_AUTO_TEST_CASE(exp_operator_const_overflowed) +BOOST_AUTO_TEST_CASE(exp_operator_exponent_too_big) { char const* sourceCode = R"( contract test { - function f() returns(uint d) { return 10 ** 256; } + function f() returns(uint d) { return 2 ** 10000000000; } })"; - BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), InternalCompilerError); + BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); } BOOST_AUTO_TEST_SUITE_END() From f7867d39b03128cbabf4d2da823f84ee95346c82 Mon Sep 17 00:00:00 2001 From: Christian Date: Tue, 10 Feb 2015 16:17:54 +0100 Subject: [PATCH 067/213] MSVC constexpr fix. --- libethcore/CommonEth.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libethcore/CommonEth.cpp b/libethcore/CommonEth.cpp index f71969525..47344a156 100644 --- a/libethcore/CommonEth.cpp +++ b/libethcore/CommonEth.cpp @@ -35,12 +35,12 @@ namespace eth const unsigned c_protocolVersion = 53; const unsigned c_databaseVersion = 5; -template constexpr u256 exp10() +template u256 exp10() { return exp10() * u256(10); } -template <> constexpr u256 exp10<0>() +template <> u256 exp10<0>() { return u256(1); } From ea043668b46cc838af1feb5d4db44a88ef2af9f6 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 10 Feb 2015 20:53:38 +0100 Subject: [PATCH 068/213] Test stuff into cpp from header. Additional debug stuff in cmake. --- cmake/EthDependencies.cmake | 1 + test/TestHelper.cpp | 3 +++ test/TestHelper.h | 3 --- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake index 8ff3d1460..18e221583 100644 --- a/cmake/EthDependencies.cmake +++ b/cmake/EthDependencies.cmake @@ -123,6 +123,7 @@ if (NOT HEADLESS) message(" - npm location : ${ETH_NPM}") find_program(ETH_JSON_RPC_STUB jsonrpcstub) + message(" - jsonrpcstub location : ${ETH_JSON_RPC_STUB}") endif() #HEADLESS diff --git a/test/TestHelper.cpp b/test/TestHelper.cpp index 8e4c493eb..8a00a5462 100644 --- a/test/TestHelper.cpp +++ b/test/TestHelper.cpp @@ -64,6 +64,9 @@ void connectClients(Client& c1, Client& c2) namespace test { +struct ValueTooLarge: virtual Exception {}; +bigint const c_max256plus1 = bigint(1) << 256; + ImportTest::ImportTest(json_spirit::mObject& _o, bool isFiller): m_TestObject(_o) { importEnv(_o["env"].get_obj()); diff --git a/test/TestHelper.h b/test/TestHelper.h index 2b93bccfb..ae6ea20cc 100644 --- a/test/TestHelper.h +++ b/test/TestHelper.h @@ -42,9 +42,6 @@ void connectClients(Client& c1, Client& c2); namespace test { -struct ValueTooLarge: virtual Exception {}; -bigint const c_max256plus1 = bigint(1) << 256; - class ImportTest { public: From a406402a4c9409b9c19421597f81dee8cb0158b6 Mon Sep 17 00:00:00 2001 From: subtly Date: Wed, 11 Feb 2015 01:03:13 -0500 Subject: [PATCH 069/213] Fixes for uninit. shared pointers and add const&. --- libp2p/Host.cpp | 29 ++++++++++++-------- libp2p/NodeTable.cpp | 64 ++++++++++++++++++++++++++++---------------- libp2p/NodeTable.h | 8 +++--- 3 files changed, 64 insertions(+), 37 deletions(-) diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index 25a095ae6..5ffb12c8f 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -185,15 +185,24 @@ void Host::onNodeTableEvent(NodeId const& _n, NodeTableEventType const& _e) auto n = m_nodeTable->node(_n); if (n) { - RecursiveGuard l(x_sessions); - auto p = m_peers[_n]; - if (!p) + shared_ptr p; { - m_peers[_n] = make_shared(); - p = m_peers[_n]; - p->id = _n; + RecursiveGuard l(x_sessions); + if (m_peers.count(_n)) + p = m_peers[_n]; + else + { + // TODO p2p: construct peer from node + p.reset(new Peer()); + p->id = _n; + p->endpoint = NodeIPEndpoint(n.endpoint.udp, n.endpoint.tcp); + p->required = n.required; + m_peers[_n] = p; + + clog(NetNote) << "p2p.host.peers.events.peersAdded " << _n << p->endpoint.tcp.address() << p->endpoint.udp.address(); + } + p->endpoint.tcp = n.endpoint.tcp; } - p->endpoint.tcp = n.endpoint.tcp; // TODO: Implement similar to discover. Attempt connecting to nodes // until ideal peer count is reached; if all nodes are tried, @@ -369,10 +378,8 @@ void Host::doHandshake(bi::tcp::socket* _socket, NodeId _nodeId) p = m_peers[_nodeId]; if (!p) - { - p = make_shared(); - p->endpoint.tcp.address(_socket->remote_endpoint().address()); - } + p.reset(new Peer()); + p->endpoint.tcp.address(_socket->remote_endpoint().address()); auto ps = std::make_shared(this, std::move(*_socket), p); ps->start(); diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index 186ece5e2..3ccbca62d 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -70,28 +70,37 @@ shared_ptr NodeTable::addNode(Public const& _pubk, bi::udp::endpoint shared_ptr NodeTable::addNode(Node const& _node) { + // ping address if nodeid is empty + if (!_node.id) + { + PingNode p(_node.endpoint.udp, m_node.endpoint.udp.address().to_string(), m_node.endpoint.udp.port()); + p.sign(m_secret); + m_socketPointer->send(p); + shared_ptr n; + return move(n); + } + Guard l(x_nodes); - shared_ptr ret = m_nodes[_node.id]; - if (ret) + if (m_nodes.count(_node.id)) { - // TODO: p2p robust percolation of node-endpoint changes // // SECURITY: remove this in beta - it's only for lazy connections and presents an easy attack vector. // if (m_server->m_peers.count(id) && isPrivateAddress(m_server->m_peers.at(id)->address.address()) && ep.port() != 0) // // Update address if the node if we now have a public IP for it. // m_server->m_peers[id]->address = ep; + return m_nodes[_node.id]; } - else - { - clog(NodeTableNote) << "p2p.nodes.add " << _node.id.abridged(); - if (m_nodeEventHandler) - m_nodeEventHandler->appendEvent(_node.id, NodeEntryAdded); - - ret.reset(new NodeEntry(m_node, _node.id, NodeIPEndpoint(_node.endpoint.udp, _node.endpoint.tcp))); - m_nodes[_node.id] = ret; - PingNode p(_node.endpoint.udp, m_node.endpoint.udp.address().to_string(), m_node.endpoint.udp.port()); - p.sign(m_secret); - m_socketPointer->send(p); - } + + shared_ptr ret(new NodeEntry(m_node, _node.id, NodeIPEndpoint(_node.endpoint.udp, _node.endpoint.tcp))); + m_nodes[_node.id] = ret; + PingNode p(_node.endpoint.udp, m_node.endpoint.udp.address().to_string(), m_node.endpoint.udp.port()); + p.sign(m_secret); + m_socketPointer->send(p); + + // TODO p2p: rename to p2p.nodes.pending, add p2p.nodes.add event (when pong is received) + clog(NodeTableNote) << "p2p.nodes.add " << _node.id.abridged(); + if (m_nodeEventHandler) + m_nodeEventHandler->appendEvent(_node.id, NodeEntryAdded); + return move(ret); } @@ -119,18 +128,23 @@ list NodeTable::snapshot() const return move(ret); } -Node NodeTable::node(NodeId _id) +Node NodeTable::node(NodeId const& _id) { + // TODO p2p: eloquent copy operator Guard l(x_nodes); - auto n = m_nodes[_id]; - return !!n ? *n : Node(); + if (m_nodes.count(_id)) + { + auto entry = m_nodes[_id]; + Node n(_id, NodeIPEndpoint(entry->endpoint.udp, entry->endpoint.tcp), entry->required); + return move(n); + } + return move(Node()); } shared_ptr NodeTable::nodeEntry(NodeId _id) { Guard l(x_nodes); - auto n = m_nodes[_id]; - return !!n ? move(n) : move(shared_ptr()); + return m_nodes.count(_id) ? move(m_nodes[_id]) : move(shared_ptr()); } void NodeTable::discover(NodeId _node, unsigned _round, shared_ptr>> _tried) @@ -289,7 +303,9 @@ void NodeTable::noteActiveNode(Public const& _pubk, bi::udp::endpoint const& _en if (_pubk == m_node.address()) return; - shared_ptr node(addNode(_pubk, _endpoint)); + clog(NodeTableNote) << "Noting active node:" << _pubk.abridged() << _endpoint.address().to_string() << ":" << _endpoint.port(); + + shared_ptr node(addNode(_pubk, _endpoint, bi::tcp::endpoint(_endpoint.address(), _endpoint.port()))); // TODO p2p: old bug (maybe gone now) sometimes node is nullptr here if (!!node) @@ -471,8 +487,8 @@ void NodeTable::doCheckEvictions(boost::system::error_code const& _ec) Guard le(x_evictions); for (auto& e: m_evictions) if (chrono::steady_clock::now() - e.first.second > c_reqTimeout) - if (auto n = m_nodes[e.second]) - drop.push_back(n); + if (m_nodes.count(e.second)) + drop.push_back(m_nodes[e.second]); evictionsRemain = m_evictions.size() - drop.size() > 0; } @@ -498,6 +514,7 @@ void NodeTable::doRefreshBuckets(boost::system::error_code const& _ec) Guard l(x_state); for (auto& d: m_state) if (chrono::steady_clock::now() - d.modified > c_bucketRefresh) + { while (!d.nodes.empty()) { auto n = d.nodes.front(); @@ -509,6 +526,7 @@ void NodeTable::doRefreshBuckets(boost::system::error_code const& _ec) } d.nodes.pop_front(); } + } } unsigned nextRefresh = connected ? (refreshed ? 200 : c_bucketRefresh.count()*1000) : 10000; diff --git a/libp2p/NodeTable.h b/libp2p/NodeTable.h index 72f7800f5..04e8d009c 100644 --- a/libp2p/NodeTable.h +++ b/libp2p/NodeTable.h @@ -115,6 +115,7 @@ inline std::ostream& operator<<(std::ostream& _out, NodeTable const& _nodeTable) * @todo cache Ping and FindSelf * * [Networking] + * @todo node-endpoint updates * @todo TCP endpoints * @todo eth/upnp/natpmp/stun/ice/etc for public-discovery * @todo firewall @@ -144,7 +145,7 @@ public: void processEvents(); /// Add node. Node will be pinged if it's not already known. - std::shared_ptr addNode(Public const& _pubk, bi::udp::endpoint const& _udp, bi::tcp::endpoint const& _tcp = bi::tcp::endpoint()); + std::shared_ptr addNode(Public const& _pubk, bi::udp::endpoint const& _udp, bi::tcp::endpoint const& _tcp); /// Add node. Node will be pinged if it's not already known. std::shared_ptr addNode(Node const& _node); @@ -162,10 +163,10 @@ public: std::list snapshot() const; /// Returns true if node id is in node table. - bool haveNode(NodeId _id) { Guard l(x_nodes); return m_nodes.count(_id); } + bool haveNode(NodeId const& _id) { Guard l(x_nodes); return m_nodes.count(_id); } /// Returns the Node to the corresponding node id or the empty Node if that id is not found. - Node node(NodeId _id); + Node node(NodeId const& _id); #ifndef BOOST_AUTO_TEST_SUITE private: @@ -197,6 +198,7 @@ protected: unsigned distance; TimePoint modified; std::list> nodes; + void touch() { modified = std::chrono::steady_clock::now(); } }; /// Used to ping endpoint. From 49d21e9ada1fa140fb66137c7b3bc2453df7df6c Mon Sep 17 00:00:00 2001 From: subtly Date: Wed, 11 Feb 2015 01:43:36 -0500 Subject: [PATCH 070/213] add back fallback for retrying when connect peers is 0 and idealpeercount > 0 --- libp2p/Host.cpp | 10 ++++++++++ libp2p/Peer.cpp | 26 ++++++++++++++++++++++++++ libp2p/Peer.h | 10 ++++++++-- 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index 5ffb12c8f..e35f8100f 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -528,6 +528,16 @@ void Host::run(boost::system::error_code const&) keepAlivePeers(); disconnectLatePeers(); + + if (m_idealPeerCount && !peerCount()) + for (auto p: m_peers) + if (p.second->shouldReconnect()) + { + // TODO p2p: fixme + p.second->m_lastAttempted = std::chrono::system_clock::now(); + connect(p.second); + break; + } auto runcb = [this](boost::system::error_code const& error) { run(error); }; m_timer->expires_from_now(boost::posix_time::milliseconds(c_timerInterval)); diff --git a/libp2p/Peer.cpp b/libp2p/Peer.cpp index 1811da930..4be0fd799 100644 --- a/libp2p/Peer.cpp +++ b/libp2p/Peer.cpp @@ -31,6 +31,32 @@ namespace dev namespace p2p { +bool Peer::shouldReconnect() const +{ + return chrono::system_clock::now() > m_lastAttempted + chrono::seconds(fallbackSeconds()); +} + +unsigned Peer::fallbackSeconds() const +{ + switch (m_lastDisconnect) + { + case BadProtocol: + return 30 * (m_failedAttempts + 1); + case UselessPeer: + case TooManyPeers: + case ClientQuit: + return 15 * (m_failedAttempts + 1); + case NoDisconnect: + default: + if (m_failedAttempts < 5) + return m_failedAttempts ? m_failedAttempts * 5 : 5; + else if (m_failedAttempts < 15) + return 25 + (m_failedAttempts - 5) * 10; + else + return 25 + 100 + (m_failedAttempts - 15) * 20; + } +} + bool Peer::operator<(Peer const& _p) const { if (isOffline() != _p.isOffline()) diff --git a/libp2p/Peer.h b/libp2p/Peer.h index 415573c0c..704e5c2b4 100644 --- a/libp2p/Peer.h +++ b/libp2p/Peer.h @@ -62,16 +62,22 @@ public: virtual bool operator<(Peer const& _p) const; - /// This peers rating. + /// WIP: Returns current peer rating. int rating() const { return m_rating; } + /// Return true if connection attempt should be made to this peer or false if + bool shouldReconnect() const; + /// Number of times connection has been attempted to peer. int failedAttempts() const { return m_failedAttempts; } - + /// Reason peer was previously disconnected. DisconnectReason lastDisconnect() const { return m_lastDisconnect; } protected: + /// Returns number of seconds to wait until attempting connection, based on attempted connection history. + unsigned fallbackSeconds() const; + int m_score = 0; ///< All time cumulative. int m_rating = 0; ///< Trending. From e3368ad364d67b1e802e2f15191cb43f5b73b02b Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 11 Feb 2015 07:58:21 +0100 Subject: [PATCH 071/213] cmake replace with ${CMAKE_COMMAND}, fixed #1006 --- CMakeLists.txt | 2 +- libweb3jsonrpc/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 70598f614..5aa1f5fcd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -88,7 +88,7 @@ function(createBuildInfo) # Generate header file containing useful build information add_custom_target(BuildInfo.h ALL WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - COMMAND cmake -DETH_SOURCE_DIR="${CMAKE_SOURCE_DIR}" -DETH_DST_DIR="${CMAKE_BINARY_DIR}" + COMMAND ${CMAKE_COMMAND} -DETH_SOURCE_DIR="${CMAKE_SOURCE_DIR}" -DETH_DST_DIR="${CMAKE_BINARY_DIR}" -DETH_BUILD_TYPE="${_cmake_build_type}" -DETH_BUILD_PLATFORM="${ETH_BUILD_PLATFORM}" -P "${ETH_SCRIPTS_DIR}/buildinfo.cmake" ) diff --git a/libweb3jsonrpc/CMakeLists.txt b/libweb3jsonrpc/CMakeLists.txt index e18a53cd8..3e0574ced 100644 --- a/libweb3jsonrpc/CMakeLists.txt +++ b/libweb3jsonrpc/CMakeLists.txt @@ -38,7 +38,7 @@ if (ETH_JSON_RPC_STUB) POST_BUILD WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMAND ${ETH_JSON_RPC_STUB} spec.json --cpp-server=AbstractWebThreeStubServer --cpp-client=WebThreeStubClient - COMMAND cmake -E rename webthreestubclient.h ../test/webthreestubclient.h + COMMAND ${CMAKE_COMMAND} -E rename webthreestubclient.h ../test/webthreestubclient.h ) add_dependencies(${EXECUTABLE} jsonrpcstub) endif() From c60b0099c797ef950e1645dcebc0854f33c7101d Mon Sep 17 00:00:00 2001 From: subtly Date: Wed, 11 Feb 2015 02:00:39 -0500 Subject: [PATCH 072/213] update last disconnect for fallback timer after successful connect. --- libp2p/Host.cpp | 3 ++- libp2p/Session.cpp | 8 ++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index e35f8100f..e9c172ac1 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -467,8 +467,9 @@ void Host::connect(std::shared_ptr const& _p) else { clog(NetConnect) << "Connected to" << _p->id.abridged() << "@" << _p->peerEndpoint(); - + _p->m_lastDisconnect = NoDisconnect; _p->m_lastConnected = std::chrono::system_clock::now(); + _p->m_failedAttempts = 0; auto ps = make_shared(this, std::move(*s), _p); ps->start(); diff --git a/libp2p/Session.cpp b/libp2p/Session.cpp index 1d1d69b7d..83270b6cf 100644 --- a/libp2p/Session.cpp +++ b/libp2p/Session.cpp @@ -193,8 +193,12 @@ bool Session::interpret(RLP const& _r) } else if (m_peer->id != id) { - disconnect(UnexpectedIdentity); - return true; + // TODO p2p: FIXME. Host should catch this and reattempt adding node to table. + m_peer->id = id; + m_peer->m_score = 0; + m_peer->m_rating = 0; +// disconnect(UnexpectedIdentity); +// return true; } if (m_server->havePeerSession(id)) From 7e9b20394deb5346e761024903d4611e81f46b01 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Wed, 11 Feb 2015 08:37:54 +0100 Subject: [PATCH 073/213] validate block (the not fill tests path) --- test/blValidBlockTestFiller.json | 27 +-- test/block.cpp | 315 +++++++++++++++++-------------- 2 files changed, 179 insertions(+), 163 deletions(-) diff --git a/test/blValidBlockTestFiller.json b/test/blValidBlockTestFiller.json index 8b951b179..75ad8452e 100644 --- a/test/blValidBlockTestFiller.json +++ b/test/blValidBlockTestFiller.json @@ -1,37 +1,21 @@ { - "validBlock" : { - "block" : { + "lowGasLimitBoundary" : { + "genesisBlockHeader" : { "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", - "difficulty" : "1024", + "difficulty" : "10000", "extraData" : "42", - "gasLimit" : "0x0dddb6", + "gasLimit" : "100000", "gasUsed" : "100", "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", "number" : "0", - "parentHash" : "0xefb4db878627027c81b3bb1c7dd3a18dae3914a49cdd24a3e40ab3bbfbb240c5", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", "timestamp" : "0x54c98c81", "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "blockHeader" : { - "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "coinbase" : "0000000000000000000000000000000000000000", - "difficulty" : "130944", - "extraData" : "", - "gasLimit" : "999023", - "gasUsed" : "4803", - "nonce" : "62778f62183098b7cc8d221fc199654e613ca47b85696f940de3bd2bb6a2a54e", - "number" : "1", - "parentHash" : "c9cb614fddd89b3bc6e2f0ed1f8e58e8a0d826612a607a6151be6f39c991a941", - "receiptTrie" : "8fd35225dd530f30dc39719f9791583309b5889ad79bff0d31e9b1eb12f55000", - "stateRoot" : "b3ef9fe736086bdf1b3cd235f68097aab5f4c6e40d57f417d39c2cc6fb67f6c7", - "timestamp" : "1423490430", - "transactionsTrie" : "2cb4068eb8ccc9124426a7ed5c445b1353c997fc419031254ff7e2768c4dcd7f", - "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" - }, "pre" : { "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "10000000000", @@ -40,7 +24,6 @@ "storage": {} } }, - "rlp" : "0xf9033bf9012fa0c9cb614fddd89b3bc6e2f0ed1f8e58e8a0d826612a607a6151be6f39c991a941a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a0b3ef9fe736086bdf1b3cd235f68097aab5f4c6e40d57f417d39c2cc6fb67f6c7a02cb4068eb8ccc9124426a7ed5c445b1353c997fc419031254ff7e2768c4dcd7fa08fd35225dd530f30dc39719f9791583309b5889ad79bff0d31e9b1eb12f55000b840000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008301ff8001830f3e6f8212c38454d8bd7e80a062778f62183098b7cc8d221fc199654e613ca47b85696f940de3bd2bb6a2a54ef90205f90202808609184e72a000830f3e6f8080b901ae60056013565b6101918061001d6000396000f35b3360008190555056006001600060e060020a6000350480630a874df61461003a57806341c0e1b514610058578063a02b161e14610066578063dbbdf0831461007757005b610045600435610149565b80600160a060020a031660005260206000f35b610060610161565b60006000f35b6100716004356100d4565b60006000f35b61008560043560243561008b565b60006000f35b600054600160a060020a031632600160a060020a031614156100ac576100b1565b6100d0565b8060018360005260205260406000208190555081600060005260206000a15b5050565b600054600160a060020a031633600160a060020a031614158015610118575033600160a060020a0316600182600052602052604060002054600160a060020a031614155b61012157610126565b610146565b600060018260005260205260406000208190555080600060005260206000a15b50565b60006001826000526020526040600020549050919050565b600054600160a060020a031633600160a060020a0316146101815761018f565b600054600160a060020a0316ff5b561ba0d4287e915ebac7a8af390560fa53c8f0b7f13802ba0393d7afa5823c2560ca89a0ae75db31a34f7e386ad459646de98ec3a1c88cc91b11620b4ffd86871f579942c0", "transactions" : [ { "data" : "", diff --git a/test/block.cpp b/test/block.cpp index 9b598bbca..f72e7001d 100644 --- a/test/block.cpp +++ b/test/block.cpp @@ -70,86 +70,174 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) if (_fillin == false) { - // TODO - - // BOOST_REQUIRE(o.count("rlp") > 0); - // const bytes rlpReaded = importByteArray(o["rlp"].get_str()); - // RLP myRLP(rlpReaded); - // BlockInfo blockFromRlp; - - // try - // { - // blockFromRlp.populateFromHeader(myRLP, false); - // //blockFromRlp.verifyInternals(rlpReaded); - // } - // catch(Exception const& _e) - // { - // cnote << "block construction did throw an exception: " << diagnostic_information(_e); - // BOOST_ERROR("Failed block construction Test with Exception: " << _e.what()); - // BOOST_CHECK_MESSAGE(o.count("block") == 0, "A block object should not be defined because the block RLP is invalid!"); - // return; - // } - - // BOOST_REQUIRE(o.count("block") > 0); - - // mObject tObj = o["block"].get_obj(); - // BlockInfo blockFromFields; - // const bytes rlpreade2 = createBlockRLPFromFields(tObj); - // RLP mysecondRLP(rlpreade2); - // blockFromFields.populateFromHeader(mysecondRLP, false); - - // //Check the fields restored from RLP to original fields - // BOOST_CHECK_MESSAGE(blockFromFields.hash == blockFromRlp.hash, "hash in given RLP not matching the block hash!"); - // BOOST_CHECK_MESSAGE(blockFromFields.parentHash == blockFromRlp.parentHash, "parentHash in given RLP not matching the block parentHash!"); - // BOOST_CHECK_MESSAGE(blockFromFields.sha3Uncles == blockFromRlp.sha3Uncles, "sha3Uncles in given RLP not matching the block sha3Uncles!"); - // BOOST_CHECK_MESSAGE(blockFromFields.coinbaseAddress == blockFromRlp.coinbaseAddress,"coinbaseAddress in given RLP not matching the block coinbaseAddress!"); - // BOOST_CHECK_MESSAGE(blockFromFields.stateRoot == blockFromRlp.stateRoot, "stateRoot in given RLP not matching the block stateRoot!"); - // BOOST_CHECK_MESSAGE(blockFromFields.transactionsRoot == blockFromRlp.transactionsRoot, "transactionsRoot in given RLP not matching the block transactionsRoot!"); - // BOOST_CHECK_MESSAGE(blockFromFields.logBloom == blockFromRlp.logBloom, "logBloom in given RLP not matching the block logBloom!"); - // BOOST_CHECK_MESSAGE(blockFromFields.difficulty == blockFromRlp.difficulty, "difficulty in given RLP not matching the block difficulty!"); - // BOOST_CHECK_MESSAGE(blockFromFields.number == blockFromRlp.number, "number in given RLP not matching the block number!"); - // BOOST_CHECK_MESSAGE(blockFromFields.gasLimit == blockFromRlp.gasLimit,"gasLimit in given RLP not matching the block gasLimit!"); - // BOOST_CHECK_MESSAGE(blockFromFields.gasUsed == blockFromRlp.gasUsed, "gasUsed in given RLP not matching the block gasUsed!"); - // BOOST_CHECK_MESSAGE(blockFromFields.timestamp == blockFromRlp.timestamp, "timestamp in given RLP not matching the block timestamp!"); - // BOOST_CHECK_MESSAGE(blockFromFields.extraData == blockFromRlp.extraData, "extraData in given RLP not matching the block extraData!"); - // BOOST_CHECK_MESSAGE(blockFromFields.nonce == blockFromRlp.nonce, "nonce in given RLP not matching the block nonce!"); - - // BOOST_CHECK_MESSAGE(blockFromFields == blockFromRlp, "However, blockFromFields != blockFromRlp!"); + BOOST_REQUIRE(o.count("genesisBlockHeader") > 0); + + // construct RLP of the genesis block + bytes blockRLP = createBlockRLPFromFields(o["genesisBlockHeader"].get_obj()); + RLP myRLP(blockRLP); + BlockInfo blockFromFields; + + try + { + blockFromFields.populateFromHeader(myRLP, false); + } + catch (Exception const& _e) + { + cnote << "block construction did throw an exception: " << diagnostic_information(_e); + BOOST_ERROR("Failed block construction Test with Exception: " << _e.what()); + return; + } + catch (std::exception const& _e) + { + cnote << "block construction did throw an exception: " << _e.what(); + BOOST_ERROR("Failed block construction Test with Exception: " << _e.what()); + return; + } + catch(...) + { + cnote << "block construction did throw an unknown exception\n"; + return; + } + + BOOST_REQUIRE(o.count("pre") > 0); + + ImportTest importer(o["pre"].get_obj()); + State theState(Address(), OverlayDB(), BaseState::Empty); + importer.importState(o["pre"].get_obj(), theState); + + // commit changes to DB + theState.commit(); + + BOOST_CHECK_MESSAGE(blockFromFields.stateRoot == theState.rootHash(), "root hash do not match"); + cout << "root hash - no fill in : " << theState.rootHash() << endl; + cout << "root hash - no fill in - from block: " << blockFromFields.stateRoot << endl; + + // create new "genesis" block + RLPStream rlpStream; + blockFromFields.streamRLP(rlpStream, WithNonce); + + RLPStream block(3); + block.appendRaw(rlpStream.out()); + block.appendRaw(RLPEmptyList); + block.appendRaw(RLPEmptyList); + + blockFromFields.verifyInternals(&block.out()); + + // construc blockchain + BlockChain bc(block.out(), string(), true); + + try + { + theState.sync(bc); + bytes blockRLP = importByteArray(o["rlp"].get_str()); + cout << "import block rlp\n"; + bc.import(blockRLP, theState.db()); + cout << "sync with the state\n"; + theState.sync(bc); + } + // if exception is thrown, RLP is invalid and not blockHeader, Transaction list, and Uncle list should be given + catch (Exception const& _e) + { + cnote << "state sync or block import did throw an exception: " << diagnostic_information(_e); + BOOST_CHECK(o.count("blockHeader") == 0); + BOOST_CHECK(o.count("transactions") == 0); + BOOST_CHECK(o.count("uncleHeaders") == 0); + } + catch (std::exception const& _e) + { + cnote << "state sync or block import did throw an exception: " << _e.what(); + BOOST_CHECK(o.count("blockHeader") == 0); + BOOST_CHECK(o.count("transactions") == 0); + BOOST_CHECK(o.count("uncleHeaders") == 0); + } + catch(...) + { + cnote << "state sync or block import did throw an exception\n"; + BOOST_CHECK(o.count("blockHeader") == 0); + BOOST_CHECK(o.count("transactions") == 0); + BOOST_CHECK(o.count("uncleHeaders") == 0); + } + + + // if yes, check parameters in blockHeader + // check transaction list + // check uncle list + + BOOST_REQUIRE(o.count("blockHeader") > 0); + + mObject tObj = o["blockHeader"].get_obj(); + BlockInfo blockHeaderFromFields; + const bytes rlpBytesBlockHeader = createBlockRLPFromFields(tObj); + RLP blockHeaderRLP(rlpBytesBlockHeader); + blockHeaderFromFields.populateFromHeader(blockHeaderRLP, false); + + BlockInfo blockFromRlp = bc.info(); + + cout << "root hash - no fill in - from state : " << theState.rootHash() << endl; + cout << " hash - no fill in - from rlp : " << blockFromRlp.hash << endl; + cout << " hash - no fill in - from block: " << blockHeaderFromFields.hash << endl; + + //Check the fields restored from RLP to original fields + BOOST_CHECK_MESSAGE(blockHeaderFromFields.headerHash() == blockFromRlp.headerHash(), "hash in given RLP not matching the block hash!"); + BOOST_CHECK_MESSAGE(blockHeaderFromFields.parentHash == blockFromRlp.parentHash, "parentHash in given RLP not matching the block parentHash!"); + BOOST_CHECK_MESSAGE(blockHeaderFromFields.sha3Uncles == blockFromRlp.sha3Uncles, "sha3Uncles in given RLP not matching the block sha3Uncles!"); + BOOST_CHECK_MESSAGE(blockHeaderFromFields.coinbaseAddress == blockFromRlp.coinbaseAddress,"coinbaseAddress in given RLP not matching the block coinbaseAddress!"); + BOOST_CHECK_MESSAGE(blockHeaderFromFields.stateRoot == blockFromRlp.stateRoot, "stateRoot in given RLP not matching the block stateRoot!"); + BOOST_CHECK_MESSAGE(blockHeaderFromFields.transactionsRoot == blockFromRlp.transactionsRoot, "transactionsRoot in given RLP not matching the block transactionsRoot!"); + BOOST_CHECK_MESSAGE(blockHeaderFromFields.logBloom == blockFromRlp.logBloom, "logBloom in given RLP not matching the block logBloom!"); + BOOST_CHECK_MESSAGE(blockHeaderFromFields.difficulty == blockFromRlp.difficulty, "difficulty in given RLP not matching the block difficulty!"); + BOOST_CHECK_MESSAGE(blockHeaderFromFields.number == blockFromRlp.number, "number in given RLP not matching the block number!"); + BOOST_CHECK_MESSAGE(blockHeaderFromFields.gasLimit == blockFromRlp.gasLimit,"gasLimit in given RLP not matching the block gasLimit!"); + BOOST_CHECK_MESSAGE(blockHeaderFromFields.gasUsed == blockFromRlp.gasUsed, "gasUsed in given RLP not matching the block gasUsed!"); + BOOST_CHECK_MESSAGE(blockHeaderFromFields.timestamp == blockFromRlp.timestamp, "timestamp in given RLP not matching the block timestamp!"); + BOOST_CHECK_MESSAGE(blockHeaderFromFields.extraData == blockFromRlp.extraData, "extraData in given RLP not matching the block extraData!"); + BOOST_CHECK_MESSAGE(blockHeaderFromFields.nonce == blockFromRlp.nonce, "nonce in given RLP not matching the block nonce!"); + + BOOST_CHECK_MESSAGE(blockHeaderFromFields == blockFromRlp, "However, blockHeaderFromFields != blockFromRlp!"); } else { - BOOST_REQUIRE(o.count("block") > 0); + BOOST_REQUIRE(o.count("genesisBlockHeader") > 0); - // construct Rlp of the given block - bytes blockRLP = createBlockRLPFromFields(o["block"].get_obj()); + // construct RLP of the genesis block + bytes blockRLP = createBlockRLPFromFields(o["genesisBlockHeader"].get_obj()); RLP myRLP(blockRLP); BlockInfo blockFromFields; - cout << "blockFromFields diff:" << blockFromFields.difficulty << endl; try { - blockFromFields.populateFromHeader(myRLP, false); - //blockFromFields.verifyInternals(blockRLP); } catch (Exception const& _e) { cnote << "block construction did throw an exception: " << diagnostic_information(_e); BOOST_ERROR("Failed block construction Test with Exception: " << _e.what()); - o.erase(o.find("block")); + return; } catch (std::exception const& _e) { cnote << "block construction did throw an exception: " << _e.what(); BOOST_ERROR("Failed block construction Test with Exception: " << _e.what()); - o.erase(o.find("block")); + return; } catch(...) { cnote << "block construction did throw an unknown exception\n"; - o.erase(o.find("block")); - } + return; + } + + BOOST_REQUIRE(o.count("pre") > 0); + + ImportTest importer(o["pre"].get_obj()); + State theState(Address(), OverlayDB(), BaseState::Empty); + importer.importState(o["pre"].get_obj(), theState); + + // commit changes to DB + theState.commit(); + + + // fillin specific --- start BOOST_REQUIRE(o.count("transactions") > 0); @@ -167,32 +255,27 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) BOOST_REQUIRE(tx.count("r") > 0); BOOST_REQUIRE(tx.count("s") > 0); BOOST_REQUIRE(tx.count("data") > 0); - cout << "attempt to import transaction\n"; - txs.attemptImport(createTransactionFromFields(tx)); - } - cout << "done importing txs\n"; - - BOOST_REQUIRE(o.count("pre") > 0); - // create state - ImportTest importer(o["pre"].get_obj()); - State theState(Address(), OverlayDB(), BaseState::Empty); - importer.importState(o["pre"].get_obj(), theState); + if (!txs.attemptImport(createTransactionFromFields(tx))) + cnote << "failed importing transaction\n"; + } - cout << "current state diff 1 : " << theState.info().difficulty << endl; - cout << "balance of a94f5374fce5edbc8e2a8697c15331677e6ebf0b: " << theState.balance(Address("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")) << endl; - theState.commit(); - cout << "balance of a94f5374fce5edbc8e2a8697c15331677e6ebf0b: " << theState.balance(Address("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")) << endl; + // update stateRootHash blockFromFields.stateRoot = theState.rootHash(); - cout << "stateRoot: " << blockFromFields.stateRoot << endl; + cout << "root hash1: " << theState.rootHash() << endl; - // find new nonce + // find new valid nonce ProofOfWork pow; MineInfo ret; tie(ret, blockFromFields.nonce) = pow.mine(blockFromFields.headerHash(WithoutNonce), blockFromFields.difficulty, 1000, true, false); + //---stop - // create new "genesis" block" + //update genesis block in json file + o["genesisBlockHeader"].get_obj()["stateRoot"] = toString(blockFromFields.stateRoot); + o["genesisBlockHeader"].get_obj()["nonce"] = toString(blockFromFields.nonce); + + // create new "genesis" block RLPStream rlpStream; blockFromFields.streamRLP(rlpStream, WithNonce); @@ -200,46 +283,35 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) block.appendRaw(rlpStream.out()); block.appendRaw(RLPEmptyList); block.appendRaw(RLPEmptyList); - //return block.out(); - cout << "my genesis hash: " << sha3(RLP(block.out())[0].data()) << endl; - cout << "construct bc\n"; - BlockChain bc(block.out(), std::string(), true); - cout << "pre difficulty: " << blockFromFields.difficulty << endl; + blockFromFields.verifyInternals(&block.out()); + + // construct blockchain + BlockChain bc(block.out(), string(), true); + + try { - //cout << "sync state with pre block" << endl; theState.sync(bc); - cout << "sync bc and txs in state\n"; - cout << "balance of a94f5374fce5edbc8e2a8697c15331677e6ebf0b: " << theState.balance(Address("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")) << endl; - cout << "current state diff: " << theState.info().difficulty << endl; + cout << "root hash2: " << theState.rootHash() << endl; theState.sync(bc,txs); - cout << "current state diff: " << theState.info().difficulty << endl; - // lock - cout << "commit to mine\n"; - theState.commitToMine(bc); // will call uncommitToMine if a repeat. - cout << "current state diff: " << theState.info().difficulty << endl; - // unlock + cout << "root hash3: " << theState.rootHash() << endl; + theState.commitToMine(bc); + cout << "root hash4: " << theState.rootHash() << endl; MineInfo info; - cout << "mine...\n"; for (info.completed = false; !info.completed; info = theState.mine()) {} - cout << "done mining, completeMine\n"; - // lock + cout << "root hash5: " << theState.rootHash() << endl; theState.completeMine(); - cout << "current state diff: " << theState.info().difficulty << endl; - // unlock - - cout << "new block: " << theState.blockData() << endl << theState.info() << endl; - cout << "current diff: " << theState.info().difficulty << endl; + cout << "root hash6: " << theState.rootHash() << endl; } catch (Exception const& _e) { - cnote << "state sync did throw an exception: " << diagnostic_information(_e); + cnote << "state sync or mining did throw an exception: " << diagnostic_information(_e); } catch (std::exception const& _e) { - cnote << "state sync did throw an exception: " << _e.what(); + cnote << "state sync or mining did throw an exception: " << _e.what(); } o["rlp"] = "0x" + toHex(theState.blockData()); @@ -267,7 +339,7 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) // write uncle list - mArray aUncleList; // as of now, our parent is always the genesis block, so we can not have uncles. That will change. + mArray aUncleList; // as of now, our parent is always the genesis block, so we can not have uncles. o["uncleHeaders"] = aUncleList; } } @@ -278,53 +350,14 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) BOOST_AUTO_TEST_SUITE(BlockTests) -//BOOST_AUTO_TEST_CASE(blFirstTest) -//{ -// dev::test::executeTests("blFirstTest", "/BlockTests", dev::test::doBlockTests); -//} - BOOST_AUTO_TEST_CASE(blValidBlockTest) { dev::test::executeTests("blValidBlockTest", "/BlockTests", dev::test::doBlockTests); } -//BOOST_AUTO_TEST_CASE(ttCreateTest) -//{ -// for (int i = 1; i < boost::unit_test::framework::master_test_suite().argc; ++i) -// { -// string arg = boost::unit_test::framework::master_test_suite().argv[i]; -// if (arg == "--createtest") -// { -// if (boost::unit_test::framework::master_test_suite().argc <= i + 2) -// { -// cnote << "usage: ./testeth --createtest \n"; -// return; -// } -// try -// { -// cnote << "Populating tests..."; -// json_spirit::mValue v; -// string s = asString(dev::contents(boost::unit_test::framework::master_test_suite().argv[i + 1])); -// BOOST_REQUIRE_MESSAGE(s.length() > 0, "Content of " + (string)boost::unit_test::framework::master_test_suite().argv[i + 1] + " is empty."); -// json_spirit::read_string(s, v); -// dev::test::doBlockTests(v, true); -// writeFile(boost::unit_test::framework::master_test_suite().argv[i + 2], asBytes(json_spirit::write_string(v, true))); -// } -// catch (Exception const& _e) -// { -// BOOST_ERROR("Failed block test with Exception: " << diagnostic_information(_e)); -// } -// catch (std::exception const& _e) -// { -// BOOST_ERROR("Failed block test with Exception: " << _e.what()); -// } -// } -// } -//} - -//BOOST_AUTO_TEST_CASE(userDefinedFileTT) -//{ -// dev::test::userDefinedTest("--bltest", dev::test::doBlockTests); -//} +BOOST_AUTO_TEST_CASE(userDefinedFileBl) +{ + dev::test::userDefinedTest("--bltest", dev::test::doBlockTests); +} BOOST_AUTO_TEST_SUITE_END() From 572e451bab9f259843018ae9522fe4f351e46c8e Mon Sep 17 00:00:00 2001 From: subtly Date: Wed, 11 Feb 2015 03:27:04 -0500 Subject: [PATCH 074/213] Added session to hostcapabilityface::peers to ensure it isn't deallocated when shared-ptr to cap is returned. Previously hosts depended on using Session however this could result in an infinite session when hostcapface::peers is processed concurrently (mutexes can make this a likely event). This will be cleaner with better integration of Session and Peer. --- libethereum/EthereumHost.cpp | 25 ++++++++++++++----------- libp2p/HostCapability.cpp | 10 +++++----- libp2p/HostCapability.h | 3 ++- libp2p/Session.cpp | 2 ++ libwhisper/WhisperHost.cpp | 16 ++++++++++------ 5 files changed, 33 insertions(+), 23 deletions(-) diff --git a/libethereum/EthereumHost.cpp b/libethereum/EthereumHost.cpp index 94ef9d35c..7dfc51b47 100644 --- a/libethereum/EthereumHost.cpp +++ b/libethereum/EthereumHost.cpp @@ -51,8 +51,8 @@ EthereumHost::EthereumHost(BlockChain const& _ch, TransactionQueue& _tq, BlockQu EthereumHost::~EthereumHost() { - for (auto const& i: peers()) - i->cap()->abortSync(); + for (auto i: peerSessions()) + i.first->cap().get()->abortSync(); } bool EthereumHost::ensureInitialised() @@ -95,16 +95,19 @@ void EthereumHost::changeSyncer(EthereumPeer* _syncer) if (isSyncing()) { if (_syncer->m_asking == Asking::Blocks) - for (auto j: peers()) - if (j->cap().get() != _syncer && j->cap()->m_asking == Asking::Nothing) - j->cap()->transition(Asking::Blocks); + for (auto j: peerSessions()) + { + auto e = j.first->cap().get(); + if (e != _syncer && e->m_asking == Asking::Nothing) + e->transition(Asking::Blocks); + } } else { // start grabbing next hash chain if there is one. - for (auto j: peers()) + for (auto j: peerSessions()) { - j->cap()->attemptSync(); + j.first->cap()->attemptSync(); if (isSyncing()) return; } @@ -167,8 +170,8 @@ void EthereumHost::doWork() void EthereumHost::maintainTransactions() { // Send any new transactions. - for (auto const& p: peers()) - if (auto ep = p->cap()) + for (auto p: peerSessions()) + if (auto ep = p.first->cap().get()) { bytes b; unsigned n = 0; @@ -198,9 +201,9 @@ void EthereumHost::maintainBlocks(h256 _currentHash) { clog(NetMessageSummary) << "Sending a new block (current is" << _currentHash << ", was" << m_latestBlockSent << ")"; - for (auto j: peers()) + for (auto j: peerSessions()) { - auto p = j->cap(); + auto p = j.first->cap().get(); RLPStream ts; p->prep(ts, NewBlockPacket, 2).appendRaw(m_chain.block(), 1).append(m_chain.details().totalDifficulty); diff --git a/libp2p/HostCapability.cpp b/libp2p/HostCapability.cpp index 8ff74d3b6..9437cd45c 100644 --- a/libp2p/HostCapability.cpp +++ b/libp2p/HostCapability.cpp @@ -32,13 +32,13 @@ void HostCapabilityFace::seal(bytes& _b) m_host->seal(_b); } -std::vector > HostCapabilityFace::peers() const +std::vector,std::shared_ptr>> HostCapabilityFace::peerSessions() const { RecursiveGuard l(m_host->x_sessions); - std::vector > ret; + std::vector,std::shared_ptr>> ret; for (auto const& i: m_host->m_sessions) - if (std::shared_ptr p = i.second.lock()) - if (p->m_capabilities.count(capDesc())) - ret.push_back(p); + if (std::shared_ptr s = i.second.lock()) + if (s->m_capabilities.count(capDesc())) + ret.push_back(make_pair(s,s->m_peer)); return ret; } diff --git a/libp2p/HostCapability.h b/libp2p/HostCapability.h index 9666ef65a..9122ca1fa 100644 --- a/libp2p/HostCapability.h +++ b/libp2p/HostCapability.h @@ -23,6 +23,7 @@ #pragma once +#include "Peer.h" #include "Common.h" namespace dev @@ -44,7 +45,7 @@ public: Host* host() const { return m_host; } - std::vector > peers() const; + std::vector,std::shared_ptr>> peerSessions() const; protected: virtual std::string name() const = 0; diff --git a/libp2p/Session.cpp b/libp2p/Session.cpp index 83270b6cf..cb7225f0f 100644 --- a/libp2p/Session.cpp +++ b/libp2p/Session.cpp @@ -205,6 +205,8 @@ bool Session::interpret(RLP const& _r) { // Already connected. clogS(NetWarn) << "Already connected to a peer with id" << id.abridged(); + // Possible that two nodes continually connect to each other with exact same timing. + this_thread::sleep_for(chrono::milliseconds(rand() % 100)); disconnect(DuplicatePeer); return true; } diff --git a/libwhisper/WhisperHost.cpp b/libwhisper/WhisperHost.cpp index 213134db9..22a6a56fe 100644 --- a/libwhisper/WhisperHost.cpp +++ b/libwhisper/WhisperHost.cpp @@ -79,11 +79,15 @@ void WhisperHost::inject(Envelope const& _m, WhisperPeer* _p) noteChanged(h, f.first); } - for (auto& i: peers()) - if (i->cap().get() == _p) - i->addRating(1); + // TODO p2p: capability-based rating + for (auto i: peerSessions()) + { + auto w = i.first->cap().get(); + if (w == _p) + w->addRating(1); else - i->cap()->noteNewMessage(h, _m); + w->noteNewMessage(h, _m); + } } void WhisperHost::noteChanged(h256 _messageHash, h256 _filter) @@ -158,8 +162,8 @@ void WhisperHost::uninstallWatch(unsigned _i) void WhisperHost::doWork() { - for (auto& i: peers()) - i->cap()->sendMessages(); + for (auto& i: peerSessions()) + i.first->cap().get()->sendMessages(); cleanup(); } From dfcebb93e4b87dfe6a9e9680978d67da7a911d24 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 11 Feb 2015 09:19:49 +0100 Subject: [PATCH 075/213] checking for changes in jsonrpcstub, fixed #1004 --- cmake/EthUtils.cmake | 24 ++++++++++++++++++++++ cmake/scripts/buildinfo.cmake | 21 ++++--------------- cmake/scripts/jsonrpcstub.cmake | 36 +++++++++++++++++++++++++++++++++ libweb3jsonrpc/CMakeLists.txt | 7 +++++-- 4 files changed, 69 insertions(+), 19 deletions(-) create mode 100644 cmake/EthUtils.cmake create mode 100644 cmake/scripts/jsonrpcstub.cmake diff --git a/cmake/EthUtils.cmake b/cmake/EthUtils.cmake new file mode 100644 index 000000000..c6fd43ed4 --- /dev/null +++ b/cmake/EthUtils.cmake @@ -0,0 +1,24 @@ +# +# renames the file if it is different from its destination +include(CMakeParseArguments) +# +macro(replace_if_different SOURCE DST) + set(extra_macro_args ${ARGN}) + set(options CREATE) + set(one_value_args) + set(multi_value_args) + cmake_parse_arguments(REPLACE_IF_DIFFERENT "${options}" "${one_value_args}" "${multi_value_args}" "${extra_macro_args}") + + if (REPLACE_IF_DIFFERENT_CREATE AND (NOT (EXISTS "${DST}"))) + file(WRITE "${DST}" "") + endif() + + execute_process(COMMAND ${CMAKE_COMMAND} -E compare_files "${SOURCE}" "${DST}" RESULT_VARIABLE DIFFERENT) + + if (DIFFERENT) + execute_process(COMMAND ${CMAKE_COMMAND} -E rename "${SOURCE}" "${DST}") + else() + execute_process(COMMAND ${CMAKE_COMMAND} -E remove "${SOURCE}") + endif() +endmacro() + diff --git a/cmake/scripts/buildinfo.cmake b/cmake/scripts/buildinfo.cmake index e61e3fa15..a0666c9f5 100644 --- a/cmake/scripts/buildinfo.cmake +++ b/cmake/scripts/buildinfo.cmake @@ -19,7 +19,7 @@ endif() execute_process( COMMAND git --git-dir=${ETH_SOURCE_DIR}/.git --work-tree=${ETH_SOURCE_DIR} rev-parse HEAD - OUTPUT_VARIABLE ETH_COMMIT_HASH OUTPUT_STRIP_TRAILING_WHITESPACE + OUTPUT_VARIABLE ETH_COMMIT_HASH OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET ) if (NOT ETH_COMMIT_HASH) @@ -28,7 +28,7 @@ endif() execute_process( COMMAND git --git-dir=${ETH_SOURCE_DIR}/.git --work-tree=${ETH_SOURCE_DIR} diff --shortstat - OUTPUT_VARIABLE ETH_LOCAL_CHANGES OUTPUT_STRIP_TRAILING_WHITESPACE + OUTPUT_VARIABLE ETH_LOCAL_CHANGES OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET ) if (ETH_LOCAL_CHANGES) @@ -41,21 +41,8 @@ set(INFILE "${ETH_SOURCE_DIR}/BuildInfo.h.in") set(TMPFILE "${ETH_DST_DIR}/BuildInfo.h.tmp") set(OUTFILE "${ETH_DST_DIR}/BuildInfo.h") -# create outfile if it doesn't exist -if (NOT (EXISTS "${OUTFILE}")) - execute_process(COMMAND touch "${OUTFILE}") -endif() - configure_file("${INFILE}" "${TMPFILE}") -execute_process( - COMMAND diff "${OUTFILE}" "${TMPFILE}" - OUTPUT_VARIABLE ETH_FILE_OUTDATED -) - -if (ETH_FILE_OUTDATED) - execute_process(COMMAND mv "${TMPFILE}" "${OUTFILE}") -else() - execute_process(COMMAND rm "${TMPFILE}") -endif() +include("${ETH_SOURCE_DIR}/cmake/EthUtils.cmake") +replace_if_different("${TMPFILE}" "${OUTFILE}" CREATE) diff --git a/cmake/scripts/jsonrpcstub.cmake b/cmake/scripts/jsonrpcstub.cmake new file mode 100644 index 000000000..a9b2c44ab --- /dev/null +++ b/cmake/scripts/jsonrpcstub.cmake @@ -0,0 +1,36 @@ +# generates JSONRPC Stub Server && Client +# +# this script expects +# ETH_SOURCE_DIR - main CMAKE_SOURCE_DIR +# ETH_SPEC_PATH +# ETH_SERVER_DIR +# ETH_CLIENT_DIR +# ETH_SERVER_NAME +# ETH_CLIENT_NAME +# ETH_JSON_RPC_STUB +# +# example usage: +# cmake -DETH_SPEC_PATH=spec.json -DETH_SERVER_DIR=libweb3jsonrpc -DETH_CLIENT_DIR=test +# -DETH_SERVER_NAME=AbstractWebThreeStubServer -DETH_CLIENT_NAME=WebThreeStubClient -DETH_JSON_RPC_STUB=/usr/local/bin/jsonrpcstub + +# by default jsonrpcstub produces files in lowercase, we want to stick to this +string(TOLOWER ${ETH_SERVER_NAME} ETH_SERVER_NAME_LOWER) +string(TOLOWER ${ETH_CLIENT_NAME} ETH_CLIENT_NAME_LOWER) + +# setup names +set(SERVER_TMPFILE "${ETH_SERVER_DIR}/${ETH_SERVER_NAME_LOWER}.h.tmp") +set(SERVER_OUTFILE "${ETH_SERVER_DIR}/${ETH_SERVER_NAME_LOWER}.h") +set(CLIENT_TMPFILE "${ETH_CLIENT_DIR}/${ETH_CLIENT_NAME_LOWER}.h.tmp") +set(CLIENT_OUTFILE "${ETH_CLIENT_DIR}/${ETH_CLIENT_NAME_LOWER}.h") + +# create tmp files +execute_process( + COMMAND ${ETH_JSON_RPC_STUB} ${ETH_SPEC_PATH} + --cpp-server=${ETH_SERVER_NAME} --cpp-server-file=${SERVER_TMPFILE} + --cpp-client=${ETH_CLIENT_NAME} --cpp-client-file=${CLIENT_TMPFILE} +) + +include("${ETH_SOURCE_DIR}/cmake/EthUtils.cmake") +replace_if_different("${SERVER_TMPFILE}" "${SERVER_OUTFILE}") +replace_if_different("${CLIENT_TMPFILE}" "${CLIENT_OUTFILE}") + diff --git a/libweb3jsonrpc/CMakeLists.txt b/libweb3jsonrpc/CMakeLists.txt index 3e0574ced..c9b2aa39d 100644 --- a/libweb3jsonrpc/CMakeLists.txt +++ b/libweb3jsonrpc/CMakeLists.txt @@ -37,8 +37,11 @@ if (ETH_JSON_RPC_STUB) add_custom_command(TARGET jsonrpcstub POST_BUILD WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - COMMAND ${ETH_JSON_RPC_STUB} spec.json --cpp-server=AbstractWebThreeStubServer --cpp-client=WebThreeStubClient - COMMAND ${CMAKE_COMMAND} -E rename webthreestubclient.h ../test/webthreestubclient.h + COMMAND ${CMAKE_COMMAND} -DETH_SPEC_PATH="${CMAKE_CURRENT_SOURCE_DIR}/spec.json" -DETH_SOURCE_DIR="${CMAKE_SOURCE_DIR}" + -DETH_SERVER_DIR="${CMAKE_CURRENT_SOURCE_DIR}" -DETH_CLIENT_DIR="${CMAKE_SOURCE_DIR}/test" + -DETH_SERVER_NAME=AbstractWebThreeStubServer -DETH_CLIENT_NAME=WebThreeStubClient + -DETH_JSON_RPC_STUB="${ETH_JSON_RPC_STUB}" + -P "${ETH_SCRIPTS_DIR}/jsonrpcstub.cmake" ) add_dependencies(${EXECUTABLE} jsonrpcstub) endif() From a153d078bce9e8c497afc02fa89259264faea685 Mon Sep 17 00:00:00 2001 From: subtly Date: Wed, 11 Feb 2015 03:58:46 -0500 Subject: [PATCH 076/213] Prevent infinite sleep on connect. Write settings before shutdown of web3. --- alethzero/MainWin.cpp | 2 +- libp2p/Host.cpp | 6 ++++-- libp2p/NodeTable.cpp | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 05daada69..f3714e76e 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -211,11 +211,11 @@ Main::Main(QWidget *parent) : Main::~Main() { + writeSettings(); // Must do this here since otherwise m_ethereum'll be deleted (and therefore clearWatches() called by the destructor) // *after* the client is dead. m_qweb->clientDieing(); g_logPost = simpleDebugOut; - writeSettings(); } void Main::on_newIdentity_triggered() diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index e9c172ac1..7010f9b04 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -428,8 +428,9 @@ void Host::addNode(NodeId const& _node, std::string const& _addr, unsigned short void Host::connect(std::shared_ptr const& _p) { - while (isWorking() && !m_run) - this_thread::sleep_for(chrono::milliseconds(50)); + for (unsigned i = 0; i < 40; i++) + if (isWorking() && !m_run) + this_thread::sleep_for(chrono::milliseconds(50)); if (!m_run) return; @@ -442,6 +443,7 @@ void Host::connect(std::shared_ptr const& _p) if (!m_nodeTable->haveNode(_p->id)) { clog(NetWarn) << "Aborted connect. Node not in node table."; + m_nodeTable->addNode(*_p.get()); return; } diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index 3ccbca62d..e6f8a171b 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -65,7 +65,7 @@ void NodeTable::processEvents() shared_ptr NodeTable::addNode(Public const& _pubk, bi::udp::endpoint const& _udp, bi::tcp::endpoint const& _tcp) { auto node = Node(_pubk, NodeIPEndpoint(_udp, _tcp)); - return move(addNode(node)); + return addNode(node); } shared_ptr NodeTable::addNode(Node const& _node) @@ -101,7 +101,7 @@ shared_ptr NodeTable::addNode(Node const& _node) if (m_nodeEventHandler) m_nodeEventHandler->appendEvent(_node.id, NodeEntryAdded); - return move(ret); + return ret; } void NodeTable::discover() From a253a894e7a4dc1cf88662cd2fde5305390cd962 Mon Sep 17 00:00:00 2001 From: Patrick Salami Date: Wed, 11 Feb 2015 01:16:58 -0800 Subject: [PATCH 077/213] added CLI flag to set number of mining threads for eth and neth --- eth/main.cpp | 7 ++++++- libethereum/Client.cpp | 7 +++++-- libethereum/Client.h | 2 +- libwebthree/WebThree.cpp | 8 ++++---- libwebthree/WebThree.h | 2 +- neth/main.cpp | 7 ++++++- 6 files changed, 23 insertions(+), 10 deletions(-) diff --git a/eth/main.cpp b/eth/main.cpp index 7a128298a..87fde2bdd 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -119,6 +119,7 @@ void help() << " -p,--port Connect to remote port (default: 30303)." << endl << " -r,--remote Connect to remote host (default: none)." << endl << " -s,--secret Set the secret key for use with send command (default: auto)." << endl + << " -t,--miners Number of mining threads to start (Default: " << thread::hardware_concurrency() << ")" << endl << " -u,--public-ip Force public ip to given (default; auto)." << endl << " -v,--verbosity <0 - 9> Set the log verbosity from 0 to 9 (Default: 8)." << endl << " -x,--peers Attempt to connect to given number of peers (Default: 5)." << endl @@ -195,6 +196,7 @@ int main(int argc, char** argv) unsigned mining = ~(unsigned)0; NodeMode mode = NodeMode::Full; unsigned peers = 5; + int miners = -1; bool interactive = false; #if ETH_JSONRPC int jsonrpc = -1; @@ -295,6 +297,8 @@ int main(int argc, char** argv) g_logVerbosity = atoi(argv[++i]); else if ((arg == "-x" || arg == "--peers") && i + 1 < argc) peers = atoi(argv[++i]); + else if ((arg == "-t" || arg == "--miners") && i + 1 < argc) + miners = atoi(argv[++i]); else if ((arg == "-o" || arg == "--mode") && i + 1 < argc) { string m = argv[++i]; @@ -337,7 +341,8 @@ int main(int argc, char** argv) dbPath, false, mode == NodeMode::Full ? set{"eth", "shh"} : set(), - netPrefs + netPrefs, + miners ); web3.setIdealPeerCount(peers); eth::Client* c = mode == NodeMode::Full ? web3.ethereum() : nullptr; diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index a42d1df99..f36a9ba22 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -59,7 +59,7 @@ void VersionChecker::setOk() } } -Client::Client(p2p::Host* _extNet, std::string const& _dbPath, bool _forceClean, u256 _networkId): +Client::Client(p2p::Host* _extNet, std::string const& _dbPath, bool _forceClean, u256 _networkId, int miners): Worker("eth"), m_vc(_dbPath), m_bc(_dbPath, !m_vc.ok() || _forceClean), @@ -69,7 +69,10 @@ Client::Client(p2p::Host* _extNet, std::string const& _dbPath, bool _forceClean, { m_host = _extNet->registerCapability(new EthereumHost(m_bc, m_tq, m_bq, _networkId)); - setMiningThreads(); + if(miners > -1) + setMiningThreads(miners); + else + setMiningThreads(); if (_dbPath.size()) Defaults::setDBPath(_dbPath); m_vc.setOk(); diff --git a/libethereum/Client.h b/libethereum/Client.h index ce3506bde..cb4488b17 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -166,7 +166,7 @@ class Client: public MinerHost, public Interface, Worker public: /// New-style Constructor. - explicit Client(p2p::Host* _host, std::string const& _dbPath = std::string(), bool _forceClean = false, u256 _networkId = 0); + explicit Client(p2p::Host* _host, std::string const& _dbPath = std::string(), bool _forceClean = false, u256 _networkId = 0, int miners = -1); /// Destructor. virtual ~Client(); diff --git a/libwebthree/WebThree.cpp b/libwebthree/WebThree.cpp index c9f9d56e3..a3a95146e 100644 --- a/libwebthree/WebThree.cpp +++ b/libwebthree/WebThree.cpp @@ -35,15 +35,15 @@ using namespace dev::p2p; using namespace dev::eth; using namespace dev::shh; -WebThreeDirect::WebThreeDirect(std::string const& _clientVersion, std::string const& _dbPath, bool _forceClean, std::set const& _interfaces, NetworkPreferences const& _n): +WebThreeDirect::WebThreeDirect(std::string const& _clientVersion, std::string const& _dbPath, bool _forceClean, std::set const& _interfaces, NetworkPreferences const& _n, int miners): m_clientVersion(_clientVersion), m_net(_clientVersion, _n) { if (_dbPath.size()) Defaults::setDBPath(_dbPath); - - if (_interfaces.count("eth")) - m_ethereum.reset(new eth::Client(&m_net, _dbPath, _forceClean)); + if (_interfaces.count("eth")) + m_ethereum.reset(new eth::Client(&m_net, _dbPath, _forceClean, 0, miners)); + if (_interfaces.count("shh")) m_whisper = m_net.registerCapability(new WhisperHost); diff --git a/libwebthree/WebThree.h b/libwebthree/WebThree.h index 682fdc0b6..013986984 100644 --- a/libwebthree/WebThree.h +++ b/libwebthree/WebThree.h @@ -106,7 +106,7 @@ class WebThreeDirect : public WebThreeNetworkFace public: /// Constructor for private instance. If there is already another process on the machine using @a _dbPath, then this will throw an exception. /// ethereum() may be safely static_cast()ed to a eth::Client*. - WebThreeDirect(std::string const& _clientVersion, std::string const& _dbPath, bool _forceClean = false, std::set const& _interfaces = {"eth", "shh"}, p2p::NetworkPreferences const& _n = p2p::NetworkPreferences()); + WebThreeDirect(std::string const& _clientVersion, std::string const& _dbPath, bool _forceClean = false, std::set const& _interfaces = {"eth", "shh"}, p2p::NetworkPreferences const& _n = p2p::NetworkPreferences(), int miners = -1); /// Destructor. ~WebThreeDirect(); diff --git a/neth/main.cpp b/neth/main.cpp index 2c1a85241..2cc3f6239 100644 --- a/neth/main.cpp +++ b/neth/main.cpp @@ -81,6 +81,7 @@ void help() << " -p,--port Connect to remote port (default: 30303)." << endl << " -r,--remote Connect to remote host (default: none)." << endl << " -s,--secret Set the secret key for use with send command (default: auto)." << endl + << " -t,--miners Number of mining threads to start (Default: " << thread::hardware_concurrency() << ")" << endl << " -u,--public-ip Force public ip to given (default; auto)." << endl << " -v,--verbosity <0..9> Set the log verbosity from 0 to 9 (tmp forced to 1)." << endl << " -x,--peers Attempt to connect to given number of peers (default: 5)." << endl @@ -307,6 +308,7 @@ int main(int argc, char** argv) unsigned mining = ~(unsigned)0; NodeMode mode = NodeMode::Full; unsigned peers = 5; + int miners = -1; #if ETH_JSONRPC int jsonrpc = 8080; #endif @@ -401,6 +403,8 @@ int main(int argc, char** argv) g_logVerbosity = atoi(argv[++i]); else if ((arg == "-x" || arg == "--peers") && i + 1 < argc) peers = atoi(argv[++i]); + else if ((arg == "-t" || arg == "--miners") && i + 1 < argc) + miners = atoi(argv[++i]); else if (arg == "-h" || arg == "--help") help(); else if (arg == "-V" || arg == "--version") @@ -420,7 +424,8 @@ int main(int argc, char** argv) dbPath, false, mode == NodeMode::Full ? set{"eth", "shh"} : set(), - netPrefs + netPrefs, + miners ); web3.setIdealPeerCount(peers); eth::Client* c = mode == NodeMode::Full ? web3.ethereum() : nullptr; From f1acd74f71db84aaebe820191654bc31d8ab6466 Mon Sep 17 00:00:00 2001 From: Patrick Salami Date: Wed, 11 Feb 2015 01:28:58 -0800 Subject: [PATCH 078/213] fixed indentation --- eth/main.cpp | 10 +++++----- libethereum/Client.cpp | 8 ++++---- libwebthree/WebThree.cpp | 4 ++-- neth/main.cpp | 10 +++++----- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/eth/main.cpp b/eth/main.cpp index 87fde2bdd..41036d77e 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -119,7 +119,7 @@ void help() << " -p,--port Connect to remote port (default: 30303)." << endl << " -r,--remote Connect to remote host (default: none)." << endl << " -s,--secret Set the secret key for use with send command (default: auto)." << endl - << " -t,--miners Number of mining threads to start (Default: " << thread::hardware_concurrency() << ")" << endl + << " -t,--miners Number of mining threads to start (Default: " << thread::hardware_concurrency() << ")" << endl << " -u,--public-ip Force public ip to given (default; auto)." << endl << " -v,--verbosity <0 - 9> Set the log verbosity from 0 to 9 (Default: 8)." << endl << " -x,--peers Attempt to connect to given number of peers (Default: 5)." << endl @@ -196,7 +196,7 @@ int main(int argc, char** argv) unsigned mining = ~(unsigned)0; NodeMode mode = NodeMode::Full; unsigned peers = 5; - int miners = -1; + int miners = -1; bool interactive = false; #if ETH_JSONRPC int jsonrpc = -1; @@ -297,8 +297,8 @@ int main(int argc, char** argv) g_logVerbosity = atoi(argv[++i]); else if ((arg == "-x" || arg == "--peers") && i + 1 < argc) peers = atoi(argv[++i]); - else if ((arg == "-t" || arg == "--miners") && i + 1 < argc) - miners = atoi(argv[++i]); + else if ((arg == "-t" || arg == "--miners") && i + 1 < argc) + miners = atoi(argv[++i]); else if ((arg == "-o" || arg == "--mode") && i + 1 < argc) { string m = argv[++i]; @@ -342,7 +342,7 @@ int main(int argc, char** argv) false, mode == NodeMode::Full ? set{"eth", "shh"} : set(), netPrefs, - miners + miners ); web3.setIdealPeerCount(peers); eth::Client* c = mode == NodeMode::Full ? web3.ethereum() : nullptr; diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index f36a9ba22..455cce7a8 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -69,10 +69,10 @@ Client::Client(p2p::Host* _extNet, std::string const& _dbPath, bool _forceClean, { m_host = _extNet->registerCapability(new EthereumHost(m_bc, m_tq, m_bq, _networkId)); - if(miners > -1) - setMiningThreads(miners); - else - setMiningThreads(); + if(miners > -1) + setMiningThreads(miners); + else + setMiningThreads(); if (_dbPath.size()) Defaults::setDBPath(_dbPath); m_vc.setOk(); diff --git a/libwebthree/WebThree.cpp b/libwebthree/WebThree.cpp index a3a95146e..b11a2dccd 100644 --- a/libwebthree/WebThree.cpp +++ b/libwebthree/WebThree.cpp @@ -41,8 +41,8 @@ WebThreeDirect::WebThreeDirect(std::string const& _clientVersion, std::string co { if (_dbPath.size()) Defaults::setDBPath(_dbPath); - if (_interfaces.count("eth")) - m_ethereum.reset(new eth::Client(&m_net, _dbPath, _forceClean, 0, miners)); + if (_interfaces.count("eth")) + m_ethereum.reset(new eth::Client(&m_net, _dbPath, _forceClean, 0, miners)); if (_interfaces.count("shh")) diff --git a/neth/main.cpp b/neth/main.cpp index 2cc3f6239..15815dd40 100644 --- a/neth/main.cpp +++ b/neth/main.cpp @@ -81,7 +81,7 @@ void help() << " -p,--port Connect to remote port (default: 30303)." << endl << " -r,--remote Connect to remote host (default: none)." << endl << " -s,--secret Set the secret key for use with send command (default: auto)." << endl - << " -t,--miners Number of mining threads to start (Default: " << thread::hardware_concurrency() << ")" << endl + << " -t,--miners Number of mining threads to start (Default: " << thread::hardware_concurrency() << ")" << endl << " -u,--public-ip Force public ip to given (default; auto)." << endl << " -v,--verbosity <0..9> Set the log verbosity from 0 to 9 (tmp forced to 1)." << endl << " -x,--peers Attempt to connect to given number of peers (default: 5)." << endl @@ -308,7 +308,7 @@ int main(int argc, char** argv) unsigned mining = ~(unsigned)0; NodeMode mode = NodeMode::Full; unsigned peers = 5; - int miners = -1; + int miners = -1; #if ETH_JSONRPC int jsonrpc = 8080; #endif @@ -403,8 +403,8 @@ int main(int argc, char** argv) g_logVerbosity = atoi(argv[++i]); else if ((arg == "-x" || arg == "--peers") && i + 1 < argc) peers = atoi(argv[++i]); - else if ((arg == "-t" || arg == "--miners") && i + 1 < argc) - miners = atoi(argv[++i]); + else if ((arg == "-t" || arg == "--miners") && i + 1 < argc) + miners = atoi(argv[++i]); else if (arg == "-h" || arg == "--help") help(); else if (arg == "-V" || arg == "--version") @@ -425,7 +425,7 @@ int main(int argc, char** argv) false, mode == NodeMode::Full ? set{"eth", "shh"} : set(), netPrefs, - miners + miners ); web3.setIdealPeerCount(peers); eth::Client* c = mode == NodeMode::Full ? web3.ethereum() : nullptr; From f36b043f9f400840a4ebe2431fd057f5d89567f6 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Wed, 11 Feb 2015 10:38:50 +0100 Subject: [PATCH 079/213] We should search for jsonrpcstub headless or not --- cmake/EthDependencies.cmake | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake index 3f012212f..bcb0780c1 100644 --- a/cmake/EthDependencies.cmake +++ b/cmake/EthDependencies.cmake @@ -95,6 +95,10 @@ find_package (CURL) message(" - curl header: ${CURL_INCLUDE_DIRS}") message(" - curl lib : ${CURL_LIBRARIES}") +# find location of jsonrpcstub +find_program(ETH_JSON_RPC_STUB jsonrpcstub) +message(" - jsonrpcstub location : ${ETH_JSON_RPC_STUB}") + # do not compile GUI if (NOT HEADLESS) @@ -130,9 +134,6 @@ if (NOT HEADLESS) string(REGEX REPLACE "npm" "" ETH_NPM_DIRECTORY ${ETH_NPM}) message(" - npm location : ${ETH_NPM}") - find_program(ETH_JSON_RPC_STUB jsonrpcstub) - message(" - jsonrpcstub location : ${ETH_JSON_RPC_STUB}") - endif() #HEADLESS # use multithreaded boost libraries, with -mt suffix From 6e5b352dc007e31bb59f555531580994f7c2bf56 Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 11 Feb 2015 10:42:10 +0100 Subject: [PATCH 080/213] - Add SourceSansPro*.qml - Ui changes on state/transaction dialog --- mix/QEther.cpp | 4 +- mix/qml/Ether.qml | 11 ++ mix/qml/FilesSection.qml | 6 +- mix/qml/ProjectList.qml | 4 +- mix/qml/QHashTypeView.qml | 7 + mix/qml/QIntTypeView.qml | 7 + mix/qml/QStringTypeView.qml | 7 + mix/qml/SourceSansProBold.qml | 6 + mix/qml/SourceSansProLight.qml | 7 + mix/qml/SourceSansProRegular.qml | 8 + mix/qml/StateDialog.qml | 155 +++++++++++----- mix/qml/StateDialogStyle.qml | 17 ++ mix/qml/TransactionDialog.qml | 294 ++++++++++++++++++++----------- mix/qml/qmldir | 1 + mix/res.qrc | 4 + 15 files changed, 382 insertions(+), 156 deletions(-) create mode 100644 mix/qml/SourceSansProBold.qml create mode 100644 mix/qml/SourceSansProLight.qml create mode 100644 mix/qml/SourceSansProRegular.qml create mode 100644 mix/qml/StateDialogStyle.qml diff --git a/mix/QEther.cpp b/mix/QEther.cpp index 46562d440..4eef1fbdb 100644 --- a/mix/QEther.cpp +++ b/mix/QEther.cpp @@ -35,7 +35,7 @@ QBigInt* QEther::toWei() const const char* key = units.valueToKey(m_currentUnit); for (std::pair rawUnit: dev::eth::units()) { - if (rawUnit.second == QString(key).toLower().toStdString()) + if (QString::fromStdString(rawUnit.second).toLower() == QString(key).toLower()) return multiply(new QBigInt(rawUnit.first)); } return new QBigInt(dev::u256(0)); @@ -46,7 +46,7 @@ void QEther::setUnit(QString const& _unit) QMetaEnum units = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("EtherUnit")); for (int k = 0; k < units.keyCount(); k++) { - if (QString(units.key(k)).toLower() == _unit) + if (QString(units.key(k)).toLower() == _unit.toLower()) { m_currentUnit = static_cast(units.keysToValue(units.key(k))); return; diff --git a/mix/qml/Ether.qml b/mix/qml/Ether.qml index a5fd5dba2..61727b848 100644 --- a/mix/qml/Ether.qml +++ b/mix/qml/Ether.qml @@ -32,6 +32,11 @@ RowLayout { units.currentIndex = unit; } + SourceSansProRegular + { + id: regularFont + } + TextField { implicitWidth: 200 @@ -46,6 +51,7 @@ RowLayout { readOnly: !edit visible: edit id: etherValueEdit; + font.family: regularFont.name } ComboBox @@ -81,10 +87,15 @@ RowLayout { ListElement { text: "Kwei"; } ListElement { text: "wei"; } } + style: ComboBoxStyle + { + font: regularFont.name + } } Text { visible: displayFormattedValue id: formattedValue + font.family: regularFont.name } } diff --git a/mix/qml/FilesSection.qml b/mix/qml/FilesSection.qml index 32202f839..e002d6394 100644 --- a/mix/qml/FilesSection.qml +++ b/mix/qml/FilesSection.qml @@ -48,16 +48,14 @@ ColumnLayout { model.remove(i); } - FontLoader + SourceSansProRegular { id: fileNameFont - source: "qrc:/qml/fonts/SourceSansPro-Regular.ttf" } - FontLoader + SourceSansProBold { id: boldFont - source: "qrc:/qml/fonts/SourceSansPro-Bold.ttf" } RowLayout diff --git a/mix/qml/ProjectList.qml b/mix/qml/ProjectList.qml index 138e86fe9..66dc7de2a 100644 --- a/mix/qml/ProjectList.qml +++ b/mix/qml/ProjectList.qml @@ -12,10 +12,10 @@ Item { anchors.fill: parent id: filesCol spacing: 0 - FontLoader + + SourceSansProLight { id: srcSansProLight - source: "qrc:/qml/fonts/SourceSansPro-Light.ttf" } Rectangle diff --git a/mix/qml/QHashTypeView.qml b/mix/qml/QHashTypeView.qml index e36514fab..b97284a34 100644 --- a/mix/qml/QHashTypeView.qml +++ b/mix/qml/QHashTypeView.qml @@ -4,6 +4,12 @@ Item { property alias text: textinput.text id: editRoot + + SourceSansProBold + { + id: boldFont + } + Rectangle { anchors.fill: parent TextInput { @@ -11,6 +17,7 @@ Item text: text anchors.fill: parent wrapMode: Text.WrapAnywhere + font.family: boldFont.name MouseArea { id: mouseArea anchors.fill: parent diff --git a/mix/qml/QIntTypeView.qml b/mix/qml/QIntTypeView.qml index f794a3b2d..6bf7f1aa7 100644 --- a/mix/qml/QIntTypeView.qml +++ b/mix/qml/QIntTypeView.qml @@ -4,12 +4,19 @@ Item { property alias text: textinput.text id: editRoot + + SourceSansProBold + { + id: boldFont + } + Rectangle { anchors.fill: parent TextInput { id: textinput text: text anchors.fill: parent + font.family: boldFont.name MouseArea { id: mouseArea anchors.fill: parent diff --git a/mix/qml/QStringTypeView.qml b/mix/qml/QStringTypeView.qml index a78fc1d26..7f0059cc9 100644 --- a/mix/qml/QStringTypeView.qml +++ b/mix/qml/QStringTypeView.qml @@ -4,6 +4,12 @@ Item { property alias text: textinput.text id: editRoot + + SourceSansProBold + { + id: boldFont + } + Rectangle { anchors.fill: parent TextInput { @@ -11,6 +17,7 @@ Item text: text anchors.fill: parent wrapMode: Text.WrapAnywhere + font.family: boldFont.name MouseArea { id: mouseArea anchors.fill: parent diff --git a/mix/qml/SourceSansProBold.qml b/mix/qml/SourceSansProBold.qml new file mode 100644 index 000000000..39c99cc8d --- /dev/null +++ b/mix/qml/SourceSansProBold.qml @@ -0,0 +1,6 @@ +import QtQuick 2.0 + +FontLoader +{ + source: "qrc:/qml/fonts/SourceSansPro-Bold.ttf" +} diff --git a/mix/qml/SourceSansProLight.qml b/mix/qml/SourceSansProLight.qml new file mode 100644 index 000000000..f46abedd5 --- /dev/null +++ b/mix/qml/SourceSansProLight.qml @@ -0,0 +1,7 @@ +import QtQuick 2.0 + +FontLoader +{ + source: "qrc:/qml/fonts/SourceSansPro-Light.ttf" +} + diff --git a/mix/qml/SourceSansProRegular.qml b/mix/qml/SourceSansProRegular.qml new file mode 100644 index 000000000..d9ce908e0 --- /dev/null +++ b/mix/qml/SourceSansProRegular.qml @@ -0,0 +1,8 @@ +import QtQuick 2.0 + +FontLoader +{ + source: "qrc:/qml/fonts/SourceSansPro-Regular.ttf" +} + + diff --git a/mix/qml/StateDialog.qml b/mix/qml/StateDialog.qml index fa48c640e..7f659e7f4 100644 --- a/mix/qml/StateDialog.qml +++ b/mix/qml/StateDialog.qml @@ -2,9 +2,11 @@ import QtQuick 2.2 import QtQuick.Controls 1.1 import QtQuick.Layouts 1.1 import QtQuick.Window 2.0 +import QtQuick.Controls.Styles 1.3 import org.ethereum.qml.QEther 1.0 import "js/QEtherHelper.js" as QEtherHelper import "js/TransactionHelper.js" as TransactionHelper +import "." Window { id: modalStateDialog @@ -14,6 +16,7 @@ Window { height: 480 visible: false + color: StateDialogStyle.generic.backgroundColor property alias stateTitle: titleField.text property alias stateBalance: balanceField.value @@ -53,59 +56,96 @@ Window { return item; } - GridLayout { - id: dialogContent - columns: 2 + SourceSansProRegular + { + id: regularFont + } + + Rectangle + { anchors.fill: parent anchors.margins: 10 - rowSpacing: 10 - columnSpacing: 10 + color: StateDialogStyle.generic.backgroundColor + GridLayout { + id: dialogContent + columns: 2 + anchors.top: parent.top + rowSpacing: 10 + columnSpacing: 10 - Label { - text: qsTr("Title") - } - TextField { - id: titleField - focus: true - Layout.fillWidth: true - } + Label { + text: qsTr("Title") + font.family: regularFont.name + color: "#808080" + } + TextField { + id: titleField + focus: true + Layout.fillWidth: true + font.family: regularFont.name + } - Label { - text: qsTr("Balance") - } - Ether { - id: balanceField - edit: true - displayFormattedValue: true - Layout.fillWidth: true - } + Label { + text: qsTr("Balance") + font.family: regularFont.name + color: "#808080" + } + Ether { + id: balanceField + edit: true + displayFormattedValue: true + Layout.fillWidth: true + } - Label { - text: qsTr("Default") - } - CheckBox { - id: defaultCheckBox - Layout.fillWidth: true + Label { + text: qsTr("Default") + font.family: regularFont.name + color: "#808080" + } + CheckBox { + id: defaultCheckBox + Layout.fillWidth: true + } } - Label { - text: qsTr("Transactions") - } - ListView { - Layout.fillWidth: true - Layout.fillHeight: true - model: transactionsModel - delegate: transactionRenderDelegate - } + ColumnLayout + { + width: parent.width + anchors.top: dialogContent.bottom + anchors.topMargin: 5 + spacing: 5 + Label { + text: qsTr("Transactions") + font.family: regularFont.name + color: "#808080" + } - Label { + ListView { + id: trList + Layout.preferredWidth: 200 + Layout.fillHeight: true + Layout.minimumHeight: 20 * transactionsModel.count + model: transactionsModel + delegate: transactionRenderDelegate + visible: transactionsModel.count > 0 + } + ToolButton { + onClicked: transactionsModel.addTransaction() + style: ButtonStyle + { + label: Text { + font.family: regularFont.name + text: qsTr("+") + font.pointSize: 20 + color: "#808080" + } + background: Rectangle { + color: "transparent" + } + } + } } - Button { - text: qsTr("Add") - onClicked: transactionsModel.addTransaction() - } - } RowLayout { anchors.bottom: parent.bottom @@ -123,6 +163,10 @@ Window { onClicked: close(); } } +} + + + ListModel { id: transactionsModel @@ -160,18 +204,43 @@ Window { text: functionId font.pointSize: 12 verticalAlignment: Text.AlignBottom + font.family: regularFont.name } ToolButton { text: qsTr("Edit"); visible: !stdContract Layout.fillHeight: true onClicked: transactionsModel.editTransaction(index) + style: ButtonStyle + { + label: Text { + font.family: regularFont.name + text: qsTr("Edit") + font.italic: true + font.pointSize: 9 + } + background: Rectangle { + color: "transparent" + } + } } ToolButton { visible: index >= 0 ? !transactionsModel.get(index).executeConstructor : false text: qsTr("Delete"); Layout.fillHeight: true onClicked: transactionsModel.deleteTransaction(index) + style: ButtonStyle + { + label: Text { + font.family: regularFont.name + text: qsTr("Delete") + font.italic: true + font.pointSize: 9 + } + background: Rectangle { + color: "transparent" + } + } } } } diff --git a/mix/qml/StateDialogStyle.qml b/mix/qml/StateDialogStyle.qml new file mode 100644 index 000000000..39214312a --- /dev/null +++ b/mix/qml/StateDialogStyle.qml @@ -0,0 +1,17 @@ +pragma Singleton +import QtQuick 2.0 + +QtObject { + property QtObject generic: QtObject + { + property string backgroundColor: "#ededed" + } + + property QtObject stateDialog: QtObject + { + } + + property QtObject transactionDialog: QtObject + { + } +} diff --git a/mix/qml/TransactionDialog.qml b/mix/qml/TransactionDialog.qml index 3e6cf0236..90e7e03ba 100644 --- a/mix/qml/TransactionDialog.qml +++ b/mix/qml/TransactionDialog.qml @@ -2,15 +2,18 @@ import QtQuick 2.2 import QtQuick.Controls 1.1 import QtQuick.Layouts 1.1 import QtQuick.Window 2.0 +import QtQuick.Controls.Styles 1.3 import org.ethereum.qml.QEther 1.0 import "js/TransactionHelper.js" as TransactionHelper +import "." Window { id: modalTransactionDialog modality: Qt.WindowModal - width:640 - height:640 + width: 640 + height: 700 visible: false + color: StateDialogStyle.generic.backgroundColor property int transactionIndex property alias transactionParams: paramsModel; @@ -155,11 +158,17 @@ Window { return item; } + SourceSansProRegular + { + id: regularFont + } + ColumnLayout { id: dialogContent width: parent.width anchors.left: parent.left anchors.right: parent.right + anchors.top: parent.top anchors.margins: 10 spacing: 30 RowLayout @@ -170,10 +179,12 @@ Window { Label { Layout.preferredWidth: 75 text: qsTr("Function") + font.family: regularFont.name + color: "#808080" } ComboBox { id: functionComboBox - Layout.fillWidth: true + Layout.preferredWidth: 350 currentIndex: -1 textRole: "text" editable: false @@ -183,6 +194,10 @@ Window { onCurrentIndexChanged: { loadParameters(); } + style: ComboBoxStyle + { + font: regularFont.name + } } } @@ -191,18 +206,17 @@ Window { { id: rowValue Layout.fillWidth: true + height: 150 Label { Layout.preferredWidth: 75 text: qsTr("Value") + font.family: regularFont.name + color: "#808080" } - Rectangle - { - Layout.fillWidth: true - Ether { - id: valueField - edit: true - displayFormattedValue: true - } + Ether { + id: valueField + edit: true + displayFormattedValue: true } } @@ -211,18 +225,17 @@ Window { { id: rowGas Layout.fillWidth: true + height: 150 Label { Layout.preferredWidth: 75 text: qsTr("Gas") + font.family: regularFont.name + color: "#808080" } - Rectangle - { - Layout.fillWidth: true - Ether { - id: gasField - edit: true - displayFormattedValue: true - } + Ether { + id: gasField + edit: true + displayFormattedValue: true } } @@ -230,31 +243,153 @@ Window { { id: rowGasPrice Layout.fillWidth: true + height: 150 Label { Layout.preferredWidth: 75 text: qsTr("Gas Price") + font.family: regularFont.name + color: "#808080" } - Rectangle - { - Layout.fillWidth: true - Ether { - id: gasPriceField - edit: true - displayFormattedValue: true - } + Ether { + id: gasPriceField + edit: true + displayFormattedValue: true } } - RowLayout - { - Layout.fillWidth: true - Label { - text: qsTr("Parameters") - Layout.preferredWidth: 75 - } - TableView { + //ColumnLayout + //{ + //Layout.fillHeight: true; + //Layout.fillWidth: true; + //visible: paramsModel.count > 0 + + Label { + text: qsTr("Parameters") + Layout.preferredWidth: 75 + font.family: regularFont.name + color: "#808080" + visible: paramsModel.count > 0 + } + + Repeater + { + model: paramsModel + visible: paramsModel.count > 0 + Rectangle + { + color: "transparent" + Layout.fillWidth: true + height: 150 + Label { + id: typeLabel + text: type + } + + Label { + anchors.left: typeLabel.right + id: nameLabel + text: name + } + + Label { + anchors.left: nameLabel.right + id: equalLabel + text: "=" + } + + Loader + { + anchors.left: equalLabel.right + id: typeLoader + height: 50 + width: 150 + Connections { + target: typeLoader.item + onTextChanged: { + console.log("text changed 0 " + value); + value = typeLoader.item.text; + console.log("text changed 1 " + value); + } + } + + sourceComponent: + { + console.log(type); + if (type.indexOf("int") !== -1) + return intViewComp; + else if (type.indexOf("bool") !== -1) + return boolViewComp; + else if (type.indexOf("string") !== -1) + return stringViewComp; + else if (type.indexOf("hash") !== -1) + return hashViewComp; + else + return null; + } + + Component + { + id: intViewComp + QIntTypeView + { + height: 50 + width: 150 + id: intView + text: value + } + } + + Component + { + id: boolViewComp + QBoolTypeView + { + height: 50 + width: 150 + id: boolView + defaultValue: "1" + Component.onCompleted: + { + /*loaderEditor.updateValue(styleData.row, styleData.role, + (paramsModel.get(styleData.row).value === "" ? defaultValue : + paramsModel.get(styleData.row).value)); + text = (paramsModel.get(styleData.row).value === "" ? defaultValue : paramsModel.get(styleData.row).value);*/ + } + } + } + + Component + { + id: stringViewComp + QStringTypeView + { + height: 50 + width: 150 + id: stringView + text: value + } + } + + Component + { + id: hashViewComp + QHashTypeView + { + height: 50 + width: 150 + id: hashView + text: value + } + } + } + + } + } + //} + + /*TableView { model: paramsModel - Layout.preferredWidth: 120 * 2 + 240 + Layout.fillWidth: true Layout.minimumHeight: 150 Layout.preferredHeight: 400 Layout.maximumHeight: 600 @@ -276,27 +411,26 @@ Window { rowDelegate: rowDelegate itemDelegate: editableDelegate - } + }*/ } - } - RowLayout - { - anchors.bottom: parent.bottom - anchors.right: parent.right; - - Button { - text: qsTr("OK"); - onClicked: { - close(); - accepted(); + RowLayout + { + anchors.bottom: parent.bottom + anchors.right: parent.right; + + Button { + text: qsTr("OK"); + onClicked: { + close(); + accepted(); + } + } + Button { + text: qsTr("Cancel"); + onClicked: close(); } } - Button { - text: qsTr("Cancel"); - onClicked: close(); - } - } ListModel { @@ -332,6 +466,7 @@ Window { sourceComponent: { + console.log("role " + styleData.role); if (styleData.role === "value") { if (paramsModel.get(styleData.row) === undefined) @@ -349,53 +484,7 @@ Window { return editor; } - Component - { - id: intViewComp - QIntTypeView - { - id: intView - text: styleData.value - } - } - - Component - { - id: boolViewComp - QBoolTypeView - { - id: boolView - defaultValue: "1" - Component.onCompleted: - { - loaderEditor.updateValue(styleData.row, styleData.role, - (paramsModel.get(styleData.row).value === "" ? defaultValue : - paramsModel.get(styleData.row).value)); - text = (paramsModel.get(styleData.row).value === "" ? defaultValue : paramsModel.get(styleData.row).value); - } - } - } - - Component - { - id: stringViewComp - QStringTypeView - { - id: stringView - text: styleData.value - } - } - - Component - { - id: hashViewComp - QHashTypeView - { - id: hashView - text: styleData.value - } - } Component { id: editor @@ -404,12 +493,7 @@ Window { readOnly: true color: styleData.textColor text: styleData.value - MouseArea { - id: mouseArea - anchors.fill: parent - hoverEnabled: true - onClicked: textinput.forceActiveFocus() - } + font.family: regularFont.name } } } diff --git a/mix/qml/qmldir b/mix/qml/qmldir index 819842274..0fefc3b29 100644 --- a/mix/qml/qmldir +++ b/mix/qml/qmldir @@ -1 +1,2 @@ singleton Style 1.0 Style.qml +singleton StateDialogStyle 1.0 StateDialogStyle.qml diff --git a/mix/res.qrc b/mix/res.qrc index a33323870..d05c3f5b1 100644 --- a/mix/res.qrc +++ b/mix/res.qrc @@ -83,5 +83,9 @@ qml/img/closedtriangleindicator_filesproject.png qml/img/opentriangleindicator_filesproject.png qml/img/projecticon.png + qml/SourceSansProRegular.qml + qml/SourceSansProBold.qml + qml/SourceSansProLight.qml + qml/StateDialogStyle.qml From 5ca7b3209f2ef9f8b24097502c45a0f533f06c47 Mon Sep 17 00:00:00 2001 From: debris Date: Wed, 11 Feb 2015 11:41:56 +0100 Subject: [PATCH 081/213] fixed transitive dependencies for msvc --- alethzero/CMakeLists.txt | 2 -- eth/CMakeLists.txt | 2 -- libdevcore/CMakeLists.txt | 7 ++++++- lllc/CMakeLists.txt | 2 -- mix/CMakeLists.txt | 2 -- solc/CMakeLists.txt | 2 -- test/CMakeLists.txt | 6 ------ third/CMakeLists.txt | 2 -- 8 files changed, 6 insertions(+), 19 deletions(-) diff --git a/alethzero/CMakeLists.txt b/alethzero/CMakeLists.txt index 2cd6f43a4..8f355def7 100644 --- a/alethzero/CMakeLists.txt +++ b/alethzero/CMakeLists.txt @@ -32,8 +32,6 @@ eth_add_executable(${EXECUTABLE} add_dependencies(${EXECUTABLE} BuildInfo.h) -target_link_libraries(${EXECUTABLE} ${Boost_CHRONO_LIBRARIES}) -target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARIES}) target_link_libraries(${EXECUTABLE} Qt5::Core) target_link_libraries(${EXECUTABLE} webthree) target_link_libraries(${EXECUTABLE} qwebthree) diff --git a/eth/CMakeLists.txt b/eth/CMakeLists.txt index bdd966bfc..31aa8df96 100644 --- a/eth/CMakeLists.txt +++ b/eth/CMakeLists.txt @@ -16,8 +16,6 @@ add_executable(${EXECUTABLE} ${SRC_LIST} ${HEADERS}) add_dependencies(${EXECUTABLE} BuildInfo.h) target_link_libraries(${EXECUTABLE} ${Boost_REGEX_LIBRARIES}) -target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARIES}) -target_link_libraries(${EXECUTABLE} ${Boost_CHRONO_LIBRARIES}) if (READLINE_FOUND) target_link_libraries(${EXECUTABLE} ${READLINE_LIBRARIES}) diff --git a/libdevcore/CMakeLists.txt b/libdevcore/CMakeLists.txt index 51caee3d3..40aa7ce24 100644 --- a/libdevcore/CMakeLists.txt +++ b/libdevcore/CMakeLists.txt @@ -26,9 +26,14 @@ else() endif() target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARIES}) -#target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARIES}) target_link_libraries(${EXECUTABLE} ${Boost_SYSTEM_LIBRARIES}) +# transitive dependencies for windows executables +if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + target_link_libraries(${EXECUTABLE} ${Boost_CHRONO_LIBRARIES}) + target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARIES}) +endif() + if (APPLE) find_package(Threads REQUIRED) target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) diff --git a/lllc/CMakeLists.txt b/lllc/CMakeLists.txt index f41584e04..2e76aa6ff 100644 --- a/lllc/CMakeLists.txt +++ b/lllc/CMakeLists.txt @@ -13,8 +13,6 @@ add_executable(${EXECUTABLE} ${SRC_LIST} ${HEADERS}) add_dependencies(${EXECUTABLE} BuildInfo.h) -target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARIES}) -target_link_libraries(${EXECUTABLE} ${Boost_CHRONO_LIBRARIES}) target_link_libraries(${EXECUTABLE} lll) target_link_libraries(${EXECUTABLE} evmcore) target_link_libraries(${EXECUTABLE} devcore) diff --git a/mix/CMakeLists.txt b/mix/CMakeLists.txt index 235c41b92..db9452061 100644 --- a/mix/CMakeLists.txt +++ b/mix/CMakeLists.txt @@ -34,8 +34,6 @@ eth_add_executable(${EXECUTABLE} UI_RESOURCES ${UI_RESOURCES} ) -target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARIES}) -target_link_libraries(${EXECUTABLE} ${Boost_CHRONO_LIBRARIES}) target_link_libraries(${EXECUTABLE} Qt5::Core) target_link_libraries(${EXECUTABLE} Qt5::Gui) target_link_libraries(${EXECUTABLE} Qt5::Widgets) diff --git a/solc/CMakeLists.txt b/solc/CMakeLists.txt index 96129c499..8c0ece27e 100644 --- a/solc/CMakeLists.txt +++ b/solc/CMakeLists.txt @@ -13,8 +13,6 @@ add_executable(${EXECUTABLE} ${SRC_LIST} ${HEADERS}) target_link_libraries(${EXECUTABLE} ${Boost_FILESYSTEM_LIBRARIES}) target_link_libraries(${EXECUTABLE} ${Boost_PROGRAM_OPTIONS_LIBRARIES}) -target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARIES}) -target_link_libraries(${EXECUTABLE} ${Boost_CHRONO_LIBRARIES}) target_link_libraries(${EXECUTABLE} solidity) install( TARGETS ${EXECUTABLE} DESTINATION bin ) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 4d240a0ee..36876eea6 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -16,8 +16,6 @@ add_executable(createRandomTest createRandomTest.cpp vm.cpp TestHelper.cpp) add_executable(checkRandomTest checkRandomTest.cpp vm.cpp TestHelper.cpp) target_link_libraries(testeth ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES}) -target_link_libraries(testeth ${Boost_DATE_TIME_LIBRARIES}) -target_link_libraries(testeth ${Boost_CHRONO_LIBRARIES}) target_link_libraries(testeth ${CURL_LIBRARIES}) target_link_libraries(testeth ethereum) target_link_libraries(testeth ethcore) @@ -32,13 +30,9 @@ if (JSONRPC) endif() target_link_libraries(createRandomTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES}) -target_link_libraries(createRandomTest ${Boost_DATE_TIME_LIBRARIES}) -target_link_libraries(createRandomTest ${Boost_CHRONO_LIBRARIES}) target_link_libraries(createRandomTest ethereum) target_link_libraries(createRandomTest ethcore) target_link_libraries(checkRandomTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES}) -target_link_libraries(checkRandomTest ${Boost_DATE_TIME_LIBRARIES}) -target_link_libraries(checkRandomTest ${Boost_CHRONO_LIBRARIES}) target_link_libraries(checkRandomTest ethereum) target_link_libraries(checkRandomTest ethcore) diff --git a/third/CMakeLists.txt b/third/CMakeLists.txt index db72cdebd..71f1e70f2 100644 --- a/third/CMakeLists.txt +++ b/third/CMakeLists.txt @@ -31,8 +31,6 @@ eth_add_executable(${EXECUTABLE} add_dependencies(${EXECUTABLE} BuildInfo.h) -target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARIES}) -target_link_libraries(${EXECUTABLE} ${Boost_CHRONO_LIBRARIES}) target_link_libraries(${EXECUTABLE} Qt5::Core) target_link_libraries(${EXECUTABLE} webthree) target_link_libraries(${EXECUTABLE} qwebthree) From 1966e57e396e33145b86ae41ba6776eb24030806 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Wed, 11 Feb 2015 13:37:32 +0100 Subject: [PATCH 082/213] Avoid making blocks with invalid timestamps. --- libethereum/State.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libethereum/State.cpp b/libethereum/State.cpp index e44b81c83..beab32abb 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -370,7 +370,7 @@ void State::resetCurrent() m_cache.clear(); m_currentBlock = BlockInfo(); m_currentBlock.coinbaseAddress = m_ourAddress; - m_currentBlock.timestamp = time(0); + m_currentBlock.timestamp = max(m_previousBlock.timestamp + 1, (u256)time(0)); m_currentBlock.transactionsRoot = h256(); m_currentBlock.sha3Uncles = h256(); m_currentBlock.populateFromParent(m_previousBlock); From 96f1e772d02800c5540e995a2d4f9df930fb810b Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 11 Feb 2015 15:17:26 +0100 Subject: [PATCH 083/213] fixed compile errors when using old version of jsonrpcstub, fixed #1003 --- cmake/scripts/jsonrpcstub.cmake | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/cmake/scripts/jsonrpcstub.cmake b/cmake/scripts/jsonrpcstub.cmake index a9b2c44ab..39f850e53 100644 --- a/cmake/scripts/jsonrpcstub.cmake +++ b/cmake/scripts/jsonrpcstub.cmake @@ -27,10 +27,19 @@ set(CLIENT_OUTFILE "${ETH_CLIENT_DIR}/${ETH_CLIENT_NAME_LOWER}.h") execute_process( COMMAND ${ETH_JSON_RPC_STUB} ${ETH_SPEC_PATH} --cpp-server=${ETH_SERVER_NAME} --cpp-server-file=${SERVER_TMPFILE} - --cpp-client=${ETH_CLIENT_NAME} --cpp-client-file=${CLIENT_TMPFILE} + --cpp-client=${ETH_CLIENT_NAME} --cpp-client-file=${CLIENT_TMPFILE} + OUTPUT_VARIABLE ERR ERROR_QUIET ) -include("${ETH_SOURCE_DIR}/cmake/EthUtils.cmake") -replace_if_different("${SERVER_TMPFILE}" "${SERVER_OUTFILE}") -replace_if_different("${CLIENT_TMPFILE}" "${CLIENT_OUTFILE}") +# don't throw fatal error on jsonrpcstub error, someone might have old version of jsonrpcstub, +# he does not need to upgrade it if he is not working on JSON RPC +# show him warning instead +if (ERR) + message(WARNING "Your version of jsonrcpstub tool is not supported. Please upgrade it.") + message(WARNING "${ERR}") +else() + include("${ETH_SOURCE_DIR}/cmake/EthUtils.cmake") + replace_if_different("${SERVER_TMPFILE}" "${SERVER_OUTFILE}") + replace_if_different("${CLIENT_TMPFILE}" "${CLIENT_OUTFILE}") +endif() From 785cde6492e83e803c8cac21daf59c6abf203e93 Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 11 Feb 2015 15:51:59 +0100 Subject: [PATCH 084/213] StateDialog.qml / TransactionDialog.qml redesign TODO: refactor using Style.qml --- mix/qml/NewProjectDialog.qml | 4 +- mix/qml/QHashTypeView.qml | 2 + mix/qml/QIntTypeView.qml | 2 + mix/qml/QStringTypeView.qml | 2 + mix/qml/StateDialog.qml | 65 +++++++++----- mix/qml/StateListModel.qml | 1 + mix/qml/TransactionDialog.qml | 164 +++++++++++++++++----------------- 7 files changed, 132 insertions(+), 108 deletions(-) diff --git a/mix/qml/NewProjectDialog.qml b/mix/qml/NewProjectDialog.qml index 8d5afc7ac..770775df2 100644 --- a/mix/qml/NewProjectDialog.qml +++ b/mix/qml/NewProjectDialog.qml @@ -5,7 +5,7 @@ import QtQuick.Window 2.0 import QtQuick.Dialogs 1.1 Window { - + id: newProjectWin modality: Qt.WindowModal width: 640 @@ -18,6 +18,8 @@ Window { signal accepted function open() { + newProjectWin.setX((Screen.width - width) / 2); + newProjectWin.setY((Screen.height - height) / 2); visible = true; titleField.focus = true; } diff --git a/mix/qml/QHashTypeView.qml b/mix/qml/QHashTypeView.qml index b97284a34..6f3c1910e 100644 --- a/mix/qml/QHashTypeView.qml +++ b/mix/qml/QHashTypeView.qml @@ -12,6 +12,8 @@ Item Rectangle { anchors.fill: parent + radius: 4 + color: "#f7f7f7" TextInput { id: textinput text: text diff --git a/mix/qml/QIntTypeView.qml b/mix/qml/QIntTypeView.qml index 6bf7f1aa7..00a08d819 100644 --- a/mix/qml/QIntTypeView.qml +++ b/mix/qml/QIntTypeView.qml @@ -12,6 +12,8 @@ Item Rectangle { anchors.fill: parent + radius: 4 + color: "#f7f7f7" TextInput { id: textinput text: text diff --git a/mix/qml/QStringTypeView.qml b/mix/qml/QStringTypeView.qml index 7f0059cc9..7e7d2ec76 100644 --- a/mix/qml/QStringTypeView.qml +++ b/mix/qml/QStringTypeView.qml @@ -12,6 +12,8 @@ Item Rectangle { anchors.fill: parent + radius: 4 + color: "#f7f7f7" TextInput { id: textinput text: text diff --git a/mix/qml/StateDialog.qml b/mix/qml/StateDialog.qml index 532d40857..886805cca 100644 --- a/mix/qml/StateDialog.qml +++ b/mix/qml/StateDialog.qml @@ -12,9 +12,9 @@ Window { id: modalStateDialog modality: Qt.WindowModal - width: 640 + width: 450 height: 480 - + title: qsTr("State Edition") visible: false color: StateDialogStyle.generic.backgroundColor @@ -36,10 +36,16 @@ Window { transactionsModel.append(item.transactions[t]); stateTransactions.push(item.transactions[t]); } + + modalStateDialog.setX((Screen.width - width) / 2); + modalStateDialog.setY((Screen.height - height) / 2); + visible = true; isDefault = setDefault; titleField.focus = true; defaultCheckBox.enabled = !isDefault; + + } function close() { @@ -110,15 +116,43 @@ Window { ColumnLayout { - width: parent.width anchors.top: dialogContent.bottom anchors.topMargin: 5 spacing: 5 - Label { - text: qsTr("Transactions") - font.family: regularFont.name - color: "#808080" + RowLayout + { + Label { + text: qsTr("Transactions") + font.family: regularFont.name + color: "#808080" + } + + Button { + tooltip: qsTr("Create a new transaction") + onClicked: transactionsModel.addTransaction() + height: 5 + width: 5 + style: ButtonStyle + { + label: Text { + font.family: regularFont.name + text: qsTr("+") + font.pointSize: 15 + color: "#808080" + height: 5 + width: 5 + } + background: Rectangle { + radius: 4 + border.width: 1 + color: "#f7f7f7" + height: 5 + implicitHeight: 5 + } + } + } + } ListView { id: trList @@ -129,22 +163,6 @@ Window { delegate: transactionRenderDelegate visible: transactionsModel.count > 0 } - - ToolButton { - onClicked: transactionsModel.addTransaction() - style: ButtonStyle - { - label: Text { - font.family: regularFont.name - text: qsTr("+") - font.pointSize: 20 - color: "#808080" - } - background: Rectangle { - color: "transparent" - } - } - } } RowLayout { @@ -260,5 +278,4 @@ Window { } } } - } diff --git a/mix/qml/StateListModel.qml b/mix/qml/StateListModel.qml index e87a96f76..fd7959477 100644 --- a/mix/qml/StateListModel.qml +++ b/mix/qml/StateListModel.qml @@ -2,6 +2,7 @@ import QtQuick 2.2 import QtQuick.Controls.Styles 1.1 import QtQuick.Controls 1.1 import QtQuick.Dialogs 1.1 +import QtQuick.Window 2.2 import QtQuick.Layouts 1.1 import org.ethereum.qml.QEther 1.0 import "js/QEtherHelper.js" as QEtherHelper diff --git a/mix/qml/TransactionDialog.qml b/mix/qml/TransactionDialog.qml index 90e7e03ba..c2b531367 100644 --- a/mix/qml/TransactionDialog.qml +++ b/mix/qml/TransactionDialog.qml @@ -10,11 +10,11 @@ import "." Window { id: modalTransactionDialog modality: Qt.WindowModal - width: 640 - height: 700 + width: 450 + height: (paramsModel.count > 0 ? 550 : 300) visible: false color: StateDialogStyle.generic.backgroundColor - + title: qsTr("Transaction Edition") property int transactionIndex property alias transactionParams: paramsModel; property alias gas: gasField.value; @@ -66,6 +66,9 @@ Window { for (var p = 0; p < parameters.length; p++) loadParameter(parameters[p]); } + modalTransactionDialog.setX((Screen.width - width) / 2); + modalTransactionDialog.setY((Screen.height - height) / 2); + visible = true; valueField.focus = true; } @@ -108,6 +111,15 @@ Window { } } + function param(name) + { + for (var k = 0; k < paramsModel.count; k++) + { + if (paramsModel.get(k).name === name) + return paramsModel.get(k); + } + } + function close() { visible = false; @@ -163,13 +175,16 @@ Window { id: regularFont } - ColumnLayout { - id: dialogContent - width: parent.width + Rectangle { + anchors.fill: parent anchors.left: parent.left anchors.right: parent.right anchors.top: parent.top anchors.margins: 10 + color: StateDialogStyle.generic.backgroundColor + + ColumnLayout { + id: dialogContent spacing: 30 RowLayout { @@ -257,64 +272,74 @@ Window { } } - //ColumnLayout - //{ - //Layout.fillHeight: true; - //Layout.fillWidth: true; - //visible: paramsModel.count > 0 - - Label { - text: qsTr("Parameters") - Layout.preferredWidth: 75 - font.family: regularFont.name - color: "#808080" - visible: paramsModel.count > 0 - } + Label { + text: qsTr("Parameters") + Layout.preferredWidth: 75 + font.family: regularFont.name + color: "#808080" + visible: paramsModel.count > 0 + } + ScrollView + { + Layout.fillWidth: true + visible: paramsModel.count > 0 + ColumnLayout + { + id: paramRepeater + Layout.fillWidth: true + spacing: 10 Repeater { + anchors.fill: parent model: paramsModel visible: paramsModel.count > 0 - Rectangle + RowLayout { - color: "transparent" + id: row Layout.fillWidth: true height: 150 + Label { id: typeLabel text: type + font.family: regularFont.name + Layout.preferredWidth: 50 } Label { - anchors.left: typeLabel.right id: nameLabel text: name + font.family: regularFont.name + Layout.preferredWidth: 50 } Label { - anchors.left: nameLabel.right id: equalLabel text: "=" + font.family: regularFont.name + Layout.preferredWidth: 15 } Loader { - anchors.left: equalLabel.right id: typeLoader - height: 50 - width: 150 + Layout.preferredHeight: 50 + Layout.preferredWidth: 150 + function getCurrent() + { + return modalTransactionDialog.param(name); + } + Connections { target: typeLoader.item onTextChanged: { - console.log("text changed 0 " + value); - value = typeLoader.item.text; - console.log("text changed 1 " + value); + typeLoader.getCurrent().value = typeLoader.item.text; } } sourceComponent: { - console.log(type); if (type.indexOf("int") !== -1) return intViewComp; else if (type.indexOf("bool") !== -1) @@ -335,7 +360,7 @@ Window { height: 50 width: 150 id: intView - text: value + text: typeLoader.getCurrent().value } } @@ -350,10 +375,8 @@ Window { defaultValue: "1" Component.onCompleted: { - /*loaderEditor.updateValue(styleData.row, styleData.role, - (paramsModel.get(styleData.row).value === "" ? defaultValue : - paramsModel.get(styleData.row).value)); - text = (paramsModel.get(styleData.row).value === "" ? defaultValue : paramsModel.get(styleData.row).value);*/ + var current = typeLoader.getCurrent().value; + (current === "" ? text = defaultValue : text = current); } } } @@ -366,7 +389,10 @@ Window { height: 50 width: 150 id: stringView - text: value + text: + { + return typeLoader.getCurrent().value + } } } @@ -378,61 +404,34 @@ Window { height: 50 width: 150 id: hashView - text: value + text: typeLoader.getCurrent().value } } } - } } - //} - - /*TableView { - model: paramsModel - Layout.fillWidth: true - Layout.minimumHeight: 150 - Layout.preferredHeight: 400 - Layout.maximumHeight: 600 - TableViewColumn { - role: "name" - title: qsTr("Name") - width: 120 - } - TableViewColumn { - role: "type" - title: qsTr("Type") - width: 120 - } - TableViewColumn { - role: "value" - title: qsTr("Value") - width: 240 - } - - rowDelegate: rowDelegate - itemDelegate: editableDelegate - }*/ + } } + } - RowLayout - { - anchors.bottom: parent.bottom - anchors.right: parent.right; - - Button { - text: qsTr("OK"); - onClicked: { - close(); - accepted(); - } - } - Button { - text: qsTr("Cancel"); - onClicked: close(); + RowLayout + { + anchors.bottom: parent.bottom + anchors.right: parent.right; + + Button { + text: qsTr("OK"); + onClicked: { + close(); + accepted(); } } - - + Button { + text: qsTr("Cancel"); + onClicked: close(); + } + } +} ListModel { id: paramsModel } @@ -466,7 +465,6 @@ Window { sourceComponent: { - console.log("role " + styleData.role); if (styleData.role === "value") { if (paramsModel.get(styleData.row) === undefined) From de88a9ac5bf80172079f08128f859ee7b307d46e Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 11 Feb 2015 16:03:46 +0100 Subject: [PATCH 085/213] printing CMAKE_VERSION in configure step --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5aa1f5fcd..942bd4d18 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -109,6 +109,7 @@ cmake_policy(SET CMP0015 NEW) createDefaultCacheConfig() configureProject() +message(STATUS "CMAKE_VERSION: ${CMAKE_VERSION}") message("-- VMTRACE: ${VMTRACE}; PARANOIA: ${PARANOIA}; HEADLESS: ${HEADLESS}; JSONRPC: ${JSONRPC}; EVMJIT: ${EVMJIT}") From 3ab33165f4fce2e3697d745d6183c2cb47c30022 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Wed, 11 Feb 2015 16:36:00 +0100 Subject: [PATCH 086/213] check transactions --- test/TestHelper.cpp | 59 +++++++++++++-------- test/TestHelper.h | 2 +- test/blValidBlockTestFiller.json | 2 +- test/block.cpp | 91 +++++++++++++++++++++++++------- test/transaction.cpp | 44 --------------- 5 files changed, 113 insertions(+), 85 deletions(-) diff --git a/test/TestHelper.cpp b/test/TestHelper.cpp index 43e6106da..ec284d480 100644 --- a/test/TestHelper.cpp +++ b/test/TestHelper.cpp @@ -504,31 +504,48 @@ void executeTests(const string& _name, const string& _testPathAppendix, std::fun } } -bytes createTransactionFromFields(json_spirit::mObject& _tObj) +RLPStream createRLPStreamFromTransactionFields(json_spirit::mObject& _tObj) { - BOOST_REQUIRE(_tObj.count("data") > 0); - BOOST_REQUIRE(_tObj.count("value") > 0); - BOOST_REQUIRE(_tObj.count("gasPrice") > 0); - BOOST_REQUIRE(_tObj.count("gasLimit") > 0); - BOOST_REQUIRE(_tObj.count("nonce")> 0); - BOOST_REQUIRE(_tObj.count("to") > 0); - - BOOST_REQUIRE(_tObj.count("v") > 0); - BOOST_REQUIRE(_tObj.count("r") > 0); - BOOST_REQUIRE(_tObj.count("s") > 0); - //Construct Rlp of the given transaction RLPStream rlpStream; - rlpStream.appendList(9); - rlpStream << bigint(_tObj["nonce"].get_str()) << bigint(_tObj["gasPrice"].get_str()) << bigint(_tObj["gasLimit"].get_str()); - if (_tObj["to"].get_str().empty()) - rlpStream << ""; - else - rlpStream << Address(_tObj["to"].get_str()); - rlpStream << bigint(_tObj["value"].get_str()) << importData(_tObj); - rlpStream << bigint(_tObj["v"].get_str()) << bigint(_tObj["r"].get_str()) << bigint(_tObj["s"].get_str()); + rlpStream.appendList(_tObj.size()); + + if (_tObj.count("nonce") > 0) + rlpStream << bigint(_tObj["nonce"].get_str()); + + if (_tObj.count("gasPrice") > 0) + rlpStream << bigint(_tObj["gasPrice"].get_str()); + + if (_tObj.count("gasLimit") > 0) + rlpStream << bigint(_tObj["gasLimit"].get_str()); + + if (_tObj.count("to") > 0) + { + if (_tObj["to"].get_str().empty()) + rlpStream << ""; + else + rlpStream << importByteArray(_tObj["to"].get_str()); + } + + if (_tObj.count("value") > 0) + rlpStream << bigint(_tObj["value"].get_str()); + + if (_tObj.count("data") > 0) + rlpStream << importData(_tObj); + + if (_tObj.count("v") > 0) + rlpStream << bigint(_tObj["v"].get_str()); + + if (_tObj.count("r") > 0) + rlpStream << bigint(_tObj["r"].get_str()); + + if (_tObj.count("s") > 0) + rlpStream << bigint(_tObj["s"].get_str()); + + if (_tObj.count("extrafield") > 0) + rlpStream << bigint(_tObj["extrafield"].get_str()); - return rlpStream.out(); + return rlpStream; } diff --git a/test/TestHelper.h b/test/TestHelper.h index 9ac1f0d4d..f7df3a2c0 100644 --- a/test/TestHelper.h +++ b/test/TestHelper.h @@ -80,7 +80,7 @@ void checkCallCreates(eth::Transactions _resultCallCreates, eth::Transactions _e void executeTests(const std::string& _name, const std::string& _testPathAppendix, std::function doTests); std::string getTestPath(); void userDefinedTest(std::string testTypeFlag, std::function doTests); -bytes createTransactionFromFields(json_spirit::mObject& _tObj); +RLPStream createRLPStreamFromTransactionFields(json_spirit::mObject& _tObj); void processCommandLineOptions(); eth::LastHashes lastHashes(u256 _currentBlockNumber); diff --git a/test/blValidBlockTestFiller.json b/test/blValidBlockTestFiller.json index 75ad8452e..99f1d32af 100644 --- a/test/blValidBlockTestFiller.json +++ b/test/blValidBlockTestFiller.json @@ -19,7 +19,7 @@ "pre" : { "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "10000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } diff --git a/test/block.cpp b/test/block.cpp index f72e7001d..5d9192a26 100644 --- a/test/block.cpp +++ b/test/block.cpp @@ -53,10 +53,11 @@ bytes createBlockRLPFromFields(mObject& _tObj) rlpStream.appendList(14); cout << "increate aha1\n"; rlpStream << h256(_tObj["parentHash"].get_str()) << h256(_tObj["uncleHash"].get_str()) << Address(_tObj["coinbase"].get_str()); - rlpStream << h256(_tObj["stateRoot"].get_str()) << h256(_tObj["transactionsTrie"].get_str()) << Address(_tObj["receiptTrie"].get_str()); + rlpStream << h256(_tObj["stateRoot"].get_str()) << h256(_tObj["transactionsTrie"].get_str()) << h256(_tObj["receiptTrie"].get_str()); rlpStream << LogBloom(_tObj["bloom"].get_str()) << u256(_tObj["difficulty"].get_str()) << u256(_tObj["number"].get_str()); rlpStream << u256(_tObj["gasLimit"].get_str()) << u256(_tObj["gasUsed"].get_str()) << u256(_tObj["timestamp"].get_str()); rlpStream << importByteArray(_tObj["extraData"].get_str()) << h256(_tObj["nonce"].get_str()); + cout << "done createBlockRLPFromFields" << endl; return rlpStream.out(); } @@ -105,12 +106,10 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) State theState(Address(), OverlayDB(), BaseState::Empty); importer.importState(o["pre"].get_obj(), theState); - // commit changes to DB + // commit changes to DB theState.commit(); BOOST_CHECK_MESSAGE(blockFromFields.stateRoot == theState.rootHash(), "root hash do not match"); - cout << "root hash - no fill in : " << theState.rootHash() << endl; - cout << "root hash - no fill in - from block: " << blockFromFields.stateRoot << endl; // create new "genesis" block RLPStream rlpStream; @@ -123,17 +122,15 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) blockFromFields.verifyInternals(&block.out()); - // construc blockchain + // construct blockchain BlockChain bc(block.out(), string(), true); try { theState.sync(bc); - bytes blockRLP = importByteArray(o["rlp"].get_str()); - cout << "import block rlp\n"; + bytes blockRLP = importByteArray(o["rlp"].get_str()); bc.import(blockRLP, theState.db()); - cout << "sync with the state\n"; - theState.sync(bc); + theState.sync(bc); } // if exception is thrown, RLP is invalid and not blockHeader, Transaction list, and Uncle list should be given catch (Exception const& _e) @@ -173,18 +170,15 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) BlockInfo blockFromRlp = bc.info(); - cout << "root hash - no fill in - from state : " << theState.rootHash() << endl; - cout << " hash - no fill in - from rlp : " << blockFromRlp.hash << endl; - cout << " hash - no fill in - from block: " << blockHeaderFromFields.hash << endl; - //Check the fields restored from RLP to original fields - BOOST_CHECK_MESSAGE(blockHeaderFromFields.headerHash() == blockFromRlp.headerHash(), "hash in given RLP not matching the block hash!"); + BOOST_CHECK_MESSAGE(blockHeaderFromFields.headerHash(WithNonce) == blockFromRlp.headerHash(WithNonce), "hash in given RLP not matching the block hash!"); BOOST_CHECK_MESSAGE(blockHeaderFromFields.parentHash == blockFromRlp.parentHash, "parentHash in given RLP not matching the block parentHash!"); BOOST_CHECK_MESSAGE(blockHeaderFromFields.sha3Uncles == blockFromRlp.sha3Uncles, "sha3Uncles in given RLP not matching the block sha3Uncles!"); BOOST_CHECK_MESSAGE(blockHeaderFromFields.coinbaseAddress == blockFromRlp.coinbaseAddress,"coinbaseAddress in given RLP not matching the block coinbaseAddress!"); BOOST_CHECK_MESSAGE(blockHeaderFromFields.stateRoot == blockFromRlp.stateRoot, "stateRoot in given RLP not matching the block stateRoot!"); BOOST_CHECK_MESSAGE(blockHeaderFromFields.transactionsRoot == blockFromRlp.transactionsRoot, "transactionsRoot in given RLP not matching the block transactionsRoot!"); - BOOST_CHECK_MESSAGE(blockHeaderFromFields.logBloom == blockFromRlp.logBloom, "logBloom in given RLP not matching the block logBloom!"); + BOOST_CHECK_MESSAGE(blockHeaderFromFields.receiptsRoot == blockFromRlp.receiptsRoot, "receiptsRoot in given RLP not matching the block receiptsRoot!"); + BOOST_CHECK_MESSAGE(blockHeaderFromFields.logBloom == blockFromRlp.logBloom, "logBloom in given RLP not matching the block logBloom!"); BOOST_CHECK_MESSAGE(blockHeaderFromFields.difficulty == blockFromRlp.difficulty, "difficulty in given RLP not matching the block difficulty!"); BOOST_CHECK_MESSAGE(blockHeaderFromFields.number == blockFromRlp.number, "number in given RLP not matching the block number!"); BOOST_CHECK_MESSAGE(blockHeaderFromFields.gasLimit == blockFromRlp.gasLimit,"gasLimit in given RLP not matching the block gasLimit!"); @@ -195,6 +189,65 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) BOOST_CHECK_MESSAGE(blockHeaderFromFields == blockFromRlp, "However, blockHeaderFromFields != blockFromRlp!"); + //Check transaction list + + Transactions txsFromField; + + for (auto const& txObj: o["transactions"].get_array()) + { + mObject tx = txObj.get_obj(); + BOOST_REQUIRE(tx.count("nonce") > 0); + BOOST_REQUIRE(tx.count("gasPrice") > 0); + BOOST_REQUIRE(tx.count("gasLimit") > 0); + BOOST_REQUIRE(tx.count("to") > 0); + BOOST_REQUIRE(tx.count("value") > 0); + BOOST_REQUIRE(tx.count("v") > 0); + BOOST_REQUIRE(tx.count("r") > 0); + BOOST_REQUIRE(tx.count("s") > 0); + BOOST_REQUIRE(tx.count("data") > 0); + + Transaction t(createRLPStreamFromTransactionFields(tx).out(), CheckSignature::Sender); + txsFromField.push_back(t); + } + + Transactions txsFromRlp; + bytes blockRLP2 = importByteArray(o["rlp"].get_str()); + RLP root(blockRLP2); + for (auto const& tr: root[1]) + { + Transaction tx(tr.data(), CheckSignature::Sender); + txsFromRlp.push_back(tx); + } + + cout << "size of pending transactions: " << txsFromRlp.size() << endl; + + BOOST_CHECK_MESSAGE(txsFromRlp.size() == txsFromField.size(), "transaction list size does not match"); + + for (size_t i = 0; i < txsFromField.size(); ++i) + { + BOOST_CHECK_MESSAGE(txsFromField[i].data() == txsFromRlp[i].data(), "transaction data in rlp and in field do not match"); + BOOST_CHECK_MESSAGE(txsFromField[i].gas() == txsFromRlp[i].gas(), "transaction gasLimit in rlp and in field do not match"); + BOOST_CHECK_MESSAGE(txsFromField[i].gasPrice() == txsFromRlp[i].gasPrice(), "transaction gasPrice in rlp and in field do not match"); + BOOST_CHECK_MESSAGE(txsFromField[i].nonce() == txsFromRlp[i].nonce(), "transaction nonce in rlp and in field do not match"); + BOOST_CHECK_MESSAGE(txsFromField[i].signature().r == txsFromRlp[i].signature().r, "transaction r in rlp and in field do not match"); + BOOST_CHECK_MESSAGE(txsFromField[i].signature().s == txsFromRlp[i].signature().s, "transaction s in rlp and in field do not match"); + BOOST_CHECK_MESSAGE(txsFromField[i].signature().v == txsFromRlp[i].signature().v, "transaction v in rlp and in field do not match"); + BOOST_CHECK_MESSAGE(txsFromField[i].receiveAddress() == txsFromRlp[i].receiveAddress(), "transaction receiveAddress in rlp and in field do not match"); + BOOST_CHECK_MESSAGE(txsFromField[i].value() == txsFromRlp[i].value(), "transaction receiveAddress in rlp and in field do not match"); + + BOOST_CHECK_MESSAGE(txsFromField[i] == txsFromRlp[i], "however, transactions in rlp and in field do not match"); + } + + // check uncle list + + BOOST_CHECK_MESSAGE(o["uncleList"].get_array().size() == 0, "Uncle list is not empty, but the genesis block can not have uncles"); + + + + + + + } else { @@ -256,7 +309,9 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) BOOST_REQUIRE(tx.count("s") > 0); BOOST_REQUIRE(tx.count("data") > 0); - if (!txs.attemptImport(createTransactionFromFields(tx))) + //Transaction txFromFields(createRLPStreamFromTransactionFields(tx).out(), CheckSignature::Sender); + + if (!txs.attemptImport(&createRLPStreamFromTransactionFields(tx).out())) cnote << "failed importing transaction\n"; } @@ -339,8 +394,8 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) // write uncle list - mArray aUncleList; // as of now, our parent is always the genesis block, so we can not have uncles. - o["uncleHeaders"] = aUncleList; + mArray aUncleList; // as of now, our parent is always the genesis block, so we can not have uncles. + o["uncleHeaders"] = aUncleList; } } } diff --git a/test/transaction.cpp b/test/transaction.cpp index 6a1aa0d84..7ced5a6f4 100644 --- a/test/transaction.cpp +++ b/test/transaction.cpp @@ -29,50 +29,6 @@ using namespace dev::eth; namespace dev { namespace test { -RLPStream createRLPStreamFromTransactionFields(mObject& _tObj) -{ - //Construct Rlp of the given transaction - RLPStream rlpStream; - rlpStream.appendList(_tObj.size()); - - if (_tObj.count("nonce") > 0) - rlpStream << bigint(_tObj["nonce"].get_str()); - - if (_tObj.count("gasPrice") > 0) - rlpStream << bigint(_tObj["gasPrice"].get_str()); - - if (_tObj.count("gasLimit") > 0) - rlpStream << bigint(_tObj["gasLimit"].get_str()); - - if (_tObj.count("to") > 0) - { - if (_tObj["to"].get_str().empty()) - rlpStream << ""; - else - rlpStream << importByteArray(_tObj["to"].get_str()); - } - - if (_tObj.count("value") > 0) - rlpStream << bigint(_tObj["value"].get_str()); - - if (_tObj.count("data") > 0) - rlpStream << importData(_tObj); - - if (_tObj.count("v") > 0) - rlpStream << bigint(_tObj["v"].get_str()); - - if (_tObj.count("r") > 0) - rlpStream << bigint(_tObj["r"].get_str()); - - if (_tObj.count("s") > 0) - rlpStream << bigint(_tObj["s"].get_str()); - - if (_tObj.count("extrafield") > 0) - rlpStream << bigint(_tObj["extrafield"].get_str()); - - return rlpStream; -} - void doTransactionTests(json_spirit::mValue& _v, bool _fillin) { for (auto& i: _v.get_obj()) From 226c435abfe7bb7d6de85fe3ff09c829b471256e Mon Sep 17 00:00:00 2001 From: debris Date: Wed, 11 Feb 2015 16:47:56 +0100 Subject: [PATCH 087/213] fixed cmake include_directories --- alethzero/CMakeLists.txt | 1 + lllc/CMakeLists.txt | 1 + mix/CMakeLists.txt | 1 + solc/CMakeLists.txt | 1 + 4 files changed, 4 insertions(+) diff --git a/alethzero/CMakeLists.txt b/alethzero/CMakeLists.txt index b58446935..fd3addb6b 100644 --- a/alethzero/CMakeLists.txt +++ b/alethzero/CMakeLists.txt @@ -11,6 +11,7 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) aux_source_directory(. SRC_LIST) include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) +include_directories(${JSONCPP_INCLUDE_DIRS}) include_directories(..) qt5_wrap_ui(ui_Main.h Main.ui) diff --git a/lllc/CMakeLists.txt b/lllc/CMakeLists.txt index 2e76aa6ff..5aaca0ccc 100644 --- a/lllc/CMakeLists.txt +++ b/lllc/CMakeLists.txt @@ -4,6 +4,7 @@ set(CMAKE_AUTOMOC OFF) aux_source_directory(. SRC_LIST) include_directories(${Boost_INCLUDE_DIRS}) +include_directories(${JSONCPP_INCLUDE_DIRS}) include_directories(..) set(EXECUTABLE lllc) diff --git a/mix/CMakeLists.txt b/mix/CMakeLists.txt index db9452061..755f3df04 100644 --- a/mix/CMakeLists.txt +++ b/mix/CMakeLists.txt @@ -10,6 +10,7 @@ endif() set(CMAKE_INCLUDE_CURRENT_DIR ON) aux_source_directory(. SRC_LIST) +include_directories(${JSONCPP_INCLUDE_DIRS}) include_directories(..) find_package (Qt5WebEngine QUIET) diff --git a/solc/CMakeLists.txt b/solc/CMakeLists.txt index 8c0ece27e..2a7bd7b6d 100644 --- a/solc/CMakeLists.txt +++ b/solc/CMakeLists.txt @@ -4,6 +4,7 @@ set(CMAKE_AUTOMOC OFF) aux_source_directory(. SRC_LIST) include_directories(${Boost_INCLUDE_DIRS}) +include_directories(${JSONCPP_INCLUDE_DIRS}) include_directories(..) set(EXECUTABLE solc) From 26d1798c812630d1487f1605295c2bd595ec8ff1 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Wed, 11 Feb 2015 16:49:01 +0100 Subject: [PATCH 088/213] safe transaction injection add diagnostic information output compile fix compile fix --- alethzero/MainWin.cpp | 18 +++++++++++++++++- libdevcore/CommonData.cpp | 2 ++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 9a29aff40..b76c94508 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -1327,7 +1327,23 @@ void Main::ourAccountsRowsMoved() void Main::on_inject_triggered() { QString s = QInputDialog::getText(this, "Inject Transaction", "Enter transaction dump in hex"); - bytes b = fromHex(s.toStdString()); + bytes b; + try + { + b = fromHex(s.toStdString()); + } + catch(BadHexCharacter& _e) + { + cnote << "invalid hex character, transaction rejected"; + cnote << boost::diagnostic_information(_e); + return; + } + catch(...) + { + cnote << "transaction rejected"; + return; + } + ethereum()->inject(&b); } diff --git a/libdevcore/CommonData.cpp b/libdevcore/CommonData.cpp index b3abe4300..efdd48d4a 100644 --- a/libdevcore/CommonData.cpp +++ b/libdevcore/CommonData.cpp @@ -96,6 +96,7 @@ bytes dev::fromHex(std::string const& _s) #ifndef BOOST_NO_EXCEPTIONS cwarn << boost::current_exception_diagnostic_information(); #endif + throw; } for (unsigned i = s; i < _s.size(); i += 2) try @@ -107,6 +108,7 @@ bytes dev::fromHex(std::string const& _s) #ifndef BOOST_NO_EXCEPTIONS cwarn << boost::current_exception_diagnostic_information(); #endif + throw; } return ret; } From ae5d53bc78a656f6dae92eee1e821589c17302c2 Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 11 Feb 2015 17:32:49 +0100 Subject: [PATCH 089/213] fix indentation issues --- mix/qml/Ether.qml | 7 +- mix/qml/StateDialog.qml | 122 +++++---- mix/qml/TransactionDialog.qml | 452 +++++++++++++++------------------- 3 files changed, 257 insertions(+), 324 deletions(-) diff --git a/mix/qml/Ether.qml b/mix/qml/Ether.qml index 61727b848..f737b12b6 100644 --- a/mix/qml/Ether.qml +++ b/mix/qml/Ether.qml @@ -65,6 +65,7 @@ RowLayout { formattedValue.text = value.format(); } } + model: ListModel { id: unitsModel ListElement { text: "Uether"; } @@ -87,11 +88,11 @@ RowLayout { ListElement { text: "Kwei"; } ListElement { text: "wei"; } } - style: ComboBoxStyle - { - font: regularFont.name + style: ComboBoxStyle { + font: regularFont.name } } + Text { visible: displayFormattedValue diff --git a/mix/qml/StateDialog.qml b/mix/qml/StateDialog.qml index 886805cca..a8ac27ecf 100644 --- a/mix/qml/StateDialog.qml +++ b/mix/qml/StateDialog.qml @@ -44,8 +44,6 @@ Window { isDefault = setDefault; titleField.focus = true; defaultCheckBox.enabled = !isDefault; - - } function close() { @@ -67,8 +65,7 @@ Window { id: regularFont } - Rectangle - { + Rectangle { anchors.fill: parent anchors.margins: 10 color: StateDialogStyle.generic.backgroundColor @@ -114,8 +111,7 @@ Window { } } - ColumnLayout - { + ColumnLayout { anchors.top: dialogContent.bottom anchors.topMargin: 5 spacing: 5 @@ -132,27 +128,26 @@ Window { onClicked: transactionsModel.addTransaction() height: 5 width: 5 - style: ButtonStyle - { - label: Text { - font.family: regularFont.name - text: qsTr("+") - font.pointSize: 15 - color: "#808080" - height: 5 - width: 5 - } - background: Rectangle { - radius: 4 - border.width: 1 - color: "#f7f7f7" - height: 5 - implicitHeight: 5 + style: ButtonStyle { + label: Text { + font.family: regularFont.name + text: qsTr("+") + font.pointSize: 15 + color: "#808080" + height: 5 + width: 5 + } + background: Rectangle { + radius: 4 + border.width: 1 + color: "#f7f7f7" + height: 5 + implicitHeight: 5 + } } - } + } } - } ListView { id: trList @@ -165,26 +160,25 @@ Window { } } - RowLayout { - anchors.bottom: parent.bottom - anchors.right: parent.right; - Button { - text: qsTr("OK"); - onClicked: { - close(); - accepted(); + RowLayout + { + anchors.bottom: parent.bottom + anchors.right: parent.right; + + Button { + text: qsTr("OK"); + onClicked: { + close(); + accepted(); + } + } + Button { + text: qsTr("Cancel"); + onClicked: close(); } - } - Button { - text: qsTr("Cancel"); - onClicked: close(); } } -} - - - ListModel { id: transactionsModel @@ -229,17 +223,16 @@ Window { visible: !stdContract Layout.fillHeight: true onClicked: transactionsModel.editTransaction(index) - style: ButtonStyle - { - label: Text { - font.family: regularFont.name - text: qsTr("Edit") - font.italic: true - font.pointSize: 9 - } - background: Rectangle { - color: "transparent" - } + style: ButtonStyle { + label: Text { + font.family: regularFont.name + text: qsTr("Edit") + font.italic: true + font.pointSize: 9 + } + background: Rectangle { + color: "transparent" + } } } ToolButton { @@ -247,26 +240,27 @@ Window { text: qsTr("Delete"); Layout.fillHeight: true onClicked: transactionsModel.deleteTransaction(index) - style: ButtonStyle - { - label: Text { - font.family: regularFont.name - text: qsTr("Delete") - font.italic: true - font.pointSize: 9 - } - background: Rectangle { - color: "transparent" - } + style: ButtonStyle { + label: Text { + font.family: regularFont.name + text: qsTr("Delete") + font.italic: true + font.pointSize: 9 + } + background: Rectangle { + color: "transparent" + } } } } } } - TransactionDialog { + TransactionDialog + { id: transactionDialog - onAccepted: { + onAccepted: + { var item = transactionDialog.getItem(); if (transactionDialog.transactionIndex < transactionsModel.count) { diff --git a/mix/qml/TransactionDialog.qml b/mix/qml/TransactionDialog.qml index c2b531367..4b2b46cd2 100644 --- a/mix/qml/TransactionDialog.qml +++ b/mix/qml/TransactionDialog.qml @@ -183,228 +183,228 @@ Window { anchors.margins: 10 color: StateDialogStyle.generic.backgroundColor - ColumnLayout { - id: dialogContent - spacing: 30 - RowLayout - { - id: rowFunction - Layout.fillWidth: true - height: 150 - Label { - Layout.preferredWidth: 75 - text: qsTr("Function") - font.family: regularFont.name - color: "#808080" - } - ComboBox { - id: functionComboBox - Layout.preferredWidth: 350 - currentIndex: -1 - textRole: "text" - editable: false - model: ListModel { - id: functionsModel - } - onCurrentIndexChanged: { - loadParameters(); + ColumnLayout { + id: dialogContent + spacing: 30 + RowLayout + { + id: rowFunction + Layout.fillWidth: true + height: 150 + Label { + Layout.preferredWidth: 75 + text: qsTr("Function") + font.family: regularFont.name + color: "#808080" } - style: ComboBoxStyle - { - font: regularFont.name + ComboBox { + id: functionComboBox + Layout.preferredWidth: 350 + currentIndex: -1 + textRole: "text" + editable: false + model: ListModel { + id: functionsModel + } + onCurrentIndexChanged: { + loadParameters(); + } + style: ComboBoxStyle { + font: regularFont.name + } } } - } - RowLayout - { - id: rowValue - Layout.fillWidth: true - height: 150 - Label { - Layout.preferredWidth: 75 - text: qsTr("Value") - font.family: regularFont.name - color: "#808080" - } - Ether { - id: valueField - edit: true - displayFormattedValue: true + RowLayout + { + id: rowValue + Layout.fillWidth: true + height: 150 + Label { + Layout.preferredWidth: 75 + text: qsTr("Value") + font.family: regularFont.name + color: "#808080" + } + Ether { + id: valueField + edit: true + displayFormattedValue: true + } } - } - RowLayout - { - id: rowGas - Layout.fillWidth: true - height: 150 - Label { - Layout.preferredWidth: 75 - text: qsTr("Gas") - font.family: regularFont.name - color: "#808080" + RowLayout + { + id: rowGas + Layout.fillWidth: true + height: 150 + Label { + Layout.preferredWidth: 75 + text: qsTr("Gas") + font.family: regularFont.name + color: "#808080" + } + Ether { + id: gasField + edit: true + displayFormattedValue: true + } } - Ether { - id: gasField - edit: true - displayFormattedValue: true + + RowLayout + { + id: rowGasPrice + Layout.fillWidth: true + height: 150 + Label { + Layout.preferredWidth: 75 + text: qsTr("Gas Price") + font.family: regularFont.name + color: "#808080" + } + Ether { + id: gasPriceField + edit: true + displayFormattedValue: true + } } - } - RowLayout - { - id: rowGasPrice - Layout.fillWidth: true - height: 150 Label { + text: qsTr("Parameters") Layout.preferredWidth: 75 - text: qsTr("Gas Price") font.family: regularFont.name color: "#808080" + visible: paramsModel.count > 0 } - Ether { - id: gasPriceField - edit: true - displayFormattedValue: true - } - } - - Label { - text: qsTr("Parameters") - Layout.preferredWidth: 75 - font.family: regularFont.name - color: "#808080" - visible: paramsModel.count > 0 - } - ScrollView - { - Layout.fillWidth: true - visible: paramsModel.count > 0 - ColumnLayout + ScrollView { - id: paramRepeater Layout.fillWidth: true - spacing: 10 - Repeater + visible: paramsModel.count > 0 + ColumnLayout { - anchors.fill: parent - model: paramsModel - visible: paramsModel.count > 0 - RowLayout + id: paramRepeater + Layout.fillWidth: true + spacing: 10 + Repeater { - id: row - Layout.fillWidth: true - height: 150 - - Label { - id: typeLabel - text: type - font.family: regularFont.name - Layout.preferredWidth: 50 - } - - Label { - id: nameLabel - text: name - font.family: regularFont.name - Layout.preferredWidth: 50 - } - - Label { - id: equalLabel - text: "=" - font.family: regularFont.name - Layout.preferredWidth: 15 - } - - Loader + anchors.fill: parent + model: paramsModel + visible: paramsModel.count > 0 + RowLayout { - id: typeLoader - Layout.preferredHeight: 50 - Layout.preferredWidth: 150 - function getCurrent() - { - return modalTransactionDialog.param(name); + id: row + Layout.fillWidth: true + height: 150 + + Label { + id: typeLabel + text: type + font.family: regularFont.name + Layout.preferredWidth: 50 } - Connections { - target: typeLoader.item - onTextChanged: { - typeLoader.getCurrent().value = typeLoader.item.text; - } + Label { + id: nameLabel + text: name + font.family: regularFont.name + Layout.preferredWidth: 50 } - sourceComponent: - { - if (type.indexOf("int") !== -1) - return intViewComp; - else if (type.indexOf("bool") !== -1) - return boolViewComp; - else if (type.indexOf("string") !== -1) - return stringViewComp; - else if (type.indexOf("hash") !== -1) - return hashViewComp; - else - return null; + Label { + id: equalLabel + text: "=" + font.family: regularFont.name + Layout.preferredWidth: 15 } - Component + Loader { - id: intViewComp - QIntTypeView + id: typeLoader + Layout.preferredHeight: 50 + Layout.preferredWidth: 150 + function getCurrent() { - height: 50 - width: 150 - id: intView - text: typeLoader.getCurrent().value + return modalTransactionDialog.param(name); } - } - Component - { - id: boolViewComp - QBoolTypeView + Connections { + target: typeLoader.item + onTextChanged: { + typeLoader.getCurrent().value = typeLoader.item.text; + } + } + + sourceComponent: { - height: 50 - width: 150 - id: boolView - defaultValue: "1" - Component.onCompleted: + if (type.indexOf("int") !== -1) + return intViewComp; + else if (type.indexOf("bool") !== -1) + return boolViewComp; + else if (type.indexOf("string") !== -1) + return stringViewComp; + else if (type.indexOf("hash") !== -1) + return hashViewComp; + else + return null; + } + + Component + { + id: intViewComp + QIntTypeView { - var current = typeLoader.getCurrent().value; - (current === "" ? text = defaultValue : text = current); + height: 50 + width: 150 + id: intView + text: typeLoader.getCurrent().value } } - } - Component - { - id: stringViewComp - QStringTypeView + Component { - height: 50 - width: 150 - id: stringView - text: + id: boolViewComp + QBoolTypeView { - return typeLoader.getCurrent().value + height: 50 + width: 150 + id: boolView + defaultValue: "1" + Component.onCompleted: + { + var current = typeLoader.getCurrent().value; + (current === "" ? text = defaultValue : text = current); + } } } - } - Component - { - id: hashViewComp - QHashTypeView + Component { - height: 50 - width: 150 - id: hashView - text: typeLoader.getCurrent().value + id: stringViewComp + QStringTypeView + { + height: 50 + width: 150 + id: stringView + text: + { + return typeLoader.getCurrent().value + } + } + } + + Component + { + id: hashViewComp + QHashTypeView + { + height: 50 + width: 150 + id: hashView + text: typeLoader.getCurrent().value + } } } } @@ -412,89 +412,27 @@ Window { } } } - } - RowLayout - { - anchors.bottom: parent.bottom - anchors.right: parent.right; - - Button { - text: qsTr("OK"); - onClicked: { - close(); - accepted(); + RowLayout + { + anchors.bottom: parent.bottom + anchors.right: parent.right; + + Button { + text: qsTr("OK"); + onClicked: { + close(); + accepted(); + } + } + Button { + text: qsTr("Cancel"); + onClicked: close(); } - } - Button { - text: qsTr("Cancel"); - onClicked: close(); } } -} + ListModel { id: paramsModel } - - Component { - id: rowDelegate - Item { - height: 100 - } - } - - Component { - id: editableDelegate - Item { - Loader { - id: loaderEditor - anchors.fill: parent - anchors.margins: 4 - Connections { - target: loaderEditor.item - onTextChanged: { - if (styleData.role === "value" && styleData.row < paramsModel.count) - loaderEditor.updateValue(styleData.row, styleData.role, loaderEditor.item.text); - } - } - - function updateValue(row, role, value) - { - paramsModel.setProperty(styleData.row, styleData.role, value); - } - - sourceComponent: - { - if (styleData.role === "value") - { - if (paramsModel.get(styleData.row) === undefined) - return null; - if (paramsModel.get(styleData.row).type.indexOf("int") !== -1) - return intViewComp; - else if (paramsModel.get(styleData.row).type.indexOf("bool") !== -1) - return boolViewComp; - else if (paramsModel.get(styleData.row).type.indexOf("string") !== -1) - return stringViewComp; - else if (paramsModel.get(styleData.row).type.indexOf("hash") !== -1) - return hashViewComp; - } - else - return editor; - } - - - - Component { - id: editor - TextInput { - id: textinput - readOnly: true - color: styleData.textColor - text: styleData.value - font.family: regularFont.name - } - } - } - } - } } From 7fb9e980cf41d1577d352fbfeaefbbc0bcb8c486 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Wed, 11 Feb 2015 18:17:01 +0100 Subject: [PATCH 090/213] avoid code doubling --- test/block.cpp | 514 +++++++++++++++++++++---------------------------- 1 file changed, 223 insertions(+), 291 deletions(-) diff --git a/test/block.cpp b/test/block.cpp index 5d9192a26..bfc7c01d6 100644 --- a/test/block.cpp +++ b/test/block.cpp @@ -69,96 +69,183 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) cerr << i.first << endl; mObject& o = i.second.get_obj(); - if (_fillin == false) - { - BOOST_REQUIRE(o.count("genesisBlockHeader") > 0); - - // construct RLP of the genesis block - bytes blockRLP = createBlockRLPFromFields(o["genesisBlockHeader"].get_obj()); - RLP myRLP(blockRLP); - BlockInfo blockFromFields; - - try - { - blockFromFields.populateFromHeader(myRLP, false); - } - catch (Exception const& _e) - { - cnote << "block construction did throw an exception: " << diagnostic_information(_e); - BOOST_ERROR("Failed block construction Test with Exception: " << _e.what()); - return; - } - catch (std::exception const& _e) - { - cnote << "block construction did throw an exception: " << _e.what(); - BOOST_ERROR("Failed block construction Test with Exception: " << _e.what()); - return; - } - catch(...) - { - cnote << "block construction did throw an unknown exception\n"; - return; - } - - BOOST_REQUIRE(o.count("pre") > 0); - - ImportTest importer(o["pre"].get_obj()); - State theState(Address(), OverlayDB(), BaseState::Empty); - importer.importState(o["pre"].get_obj(), theState); - - // commit changes to DB - theState.commit(); - - BOOST_CHECK_MESSAGE(blockFromFields.stateRoot == theState.rootHash(), "root hash do not match"); - - // create new "genesis" block - RLPStream rlpStream; - blockFromFields.streamRLP(rlpStream, WithNonce); - - RLPStream block(3); - block.appendRaw(rlpStream.out()); - block.appendRaw(RLPEmptyList); - block.appendRaw(RLPEmptyList); - - blockFromFields.verifyInternals(&block.out()); - - // construct blockchain - BlockChain bc(block.out(), string(), true); - - try - { - theState.sync(bc); - bytes blockRLP = importByteArray(o["rlp"].get_str()); + BOOST_REQUIRE(o.count("genesisBlockHeader") > 0); + + // construct RLP of the genesis block + bytes blockRLP = createBlockRLPFromFields(o["genesisBlockHeader"].get_obj()); + RLP myRLP(blockRLP); + BlockInfo blockFromFields; + + try + { + blockFromFields.populateFromHeader(myRLP, false); + } + catch (Exception const& _e) + { + cnote << "block construction did throw an exception: " << diagnostic_information(_e); + BOOST_ERROR("Failed block construction Test with Exception: " << _e.what()); + return; + } + catch (std::exception const& _e) + { + cnote << "block construction did throw an exception: " << _e.what(); + BOOST_ERROR("Failed block construction Test with Exception: " << _e.what()); + return; + } + catch(...) + { + cnote << "block construction did throw an unknown exception\n"; + return; + } + + BOOST_REQUIRE(o.count("pre") > 0); + + ImportTest importer(o["pre"].get_obj()); + State theState(Address(), OverlayDB(), BaseState::Empty); + importer.importState(o["pre"].get_obj(), theState); + + // commit changes to DB + theState.commit(); + + if (_fillin) + blockFromFields.stateRoot = theState.rootHash(); + else + BOOST_CHECK_MESSAGE(blockFromFields.stateRoot == theState.rootHash(), "root hash do not match"); + + if (_fillin) + { + // find new valid nonce + ProofOfWork pow; + MineInfo ret; + tie(ret, blockFromFields.nonce) = pow.mine(blockFromFields.headerHash(WithoutNonce), blockFromFields.difficulty, 1000, true, false); + + //update genesis block in json file + o["genesisBlockHeader"].get_obj()["stateRoot"] = toString(blockFromFields.stateRoot); + o["genesisBlockHeader"].get_obj()["nonce"] = toString(blockFromFields.nonce); + } + + // create new "genesis" block + RLPStream rlpStream; + blockFromFields.streamRLP(rlpStream, WithNonce); + + RLPStream block(3); + block.appendRaw(rlpStream.out()); + block.appendRaw(RLPEmptyList); + block.appendRaw(RLPEmptyList); + + blockFromFields.verifyInternals(&block.out()); + + // construct blockchain + BlockChain bc(block.out(), string(), true); + + if (_fillin) + { + BOOST_REQUIRE(o.count("transactions") > 0); + + TransactionQueue txs; + + for (auto const& txObj: o["transactions"].get_array()) + { + mObject tx = txObj.get_obj(); + BOOST_REQUIRE(tx.count("nonce") > 0); + BOOST_REQUIRE(tx.count("gasPrice") > 0); + BOOST_REQUIRE(tx.count("gasLimit") > 0); + BOOST_REQUIRE(tx.count("to") > 0); + BOOST_REQUIRE(tx.count("value") > 0); + BOOST_REQUIRE(tx.count("v") > 0); + BOOST_REQUIRE(tx.count("r") > 0); + BOOST_REQUIRE(tx.count("s") > 0); + BOOST_REQUIRE(tx.count("data") > 0); + + //Transaction txFromFields(createRLPStreamFromTransactionFields(tx).out(), CheckSignature::Sender); + + if (!txs.attemptImport(&createRLPStreamFromTransactionFields(tx).out())) + cnote << "failed importing transaction\n"; + } + + try + { + theState.sync(bc); + theState.sync(bc,txs); + theState.commitToMine(bc); + MineInfo info; + for (info.completed = false; !info.completed; info = theState.mine()) {} + theState.completeMine(); + } + catch (Exception const& _e) + { + cnote << "state sync or mining did throw an exception: " << diagnostic_information(_e); + } + catch (std::exception const& _e) + { + cnote << "state sync or mining did throw an exception: " << _e.what(); + } + + o["rlp"] = "0x" + toHex(theState.blockData()); + + // write block header + + mObject oBlockHeader; + BlockInfo current_BlockHeader = theState.info(); + oBlockHeader["parentHash"] = toString(current_BlockHeader.parentHash); + oBlockHeader["uncleHash"] = toString(current_BlockHeader.sha3Uncles); + oBlockHeader["coinbase"] = toString(current_BlockHeader.coinbaseAddress); + oBlockHeader["stateRoot"] = toString(current_BlockHeader.stateRoot); + oBlockHeader["transactionsTrie"] = toString(current_BlockHeader.transactionsRoot); + oBlockHeader["receiptTrie"] = toString(current_BlockHeader.receiptsRoot); + oBlockHeader["bloom"] = toString(current_BlockHeader.logBloom); + oBlockHeader["difficulty"] = toString(current_BlockHeader.difficulty); + oBlockHeader["number"] = toString(current_BlockHeader.number); + oBlockHeader["gasLimit"] = toString(current_BlockHeader.gasLimit); + oBlockHeader["gasUsed"] = toString(current_BlockHeader.gasUsed); + oBlockHeader["timestamp"] = toString(current_BlockHeader.timestamp); + oBlockHeader["extraData"] = toHex(current_BlockHeader.extraData); + oBlockHeader["nonce"] = toString(current_BlockHeader.nonce); + + o["blockHeader"] = oBlockHeader; + + // write uncle list + + mArray aUncleList; // as of now, our parent is always the genesis block, so we can not have uncles. + o["uncleHeaders"] = aUncleList; + } + + else + { + try + { + theState.sync(bc); + bytes blockRLP = importByteArray(o["rlp"].get_str()); bc.import(blockRLP, theState.db()); - theState.sync(bc); - } + theState.sync(bc); + } // if exception is thrown, RLP is invalid and not blockHeader, Transaction list, and Uncle list should be given - catch (Exception const& _e) - { - cnote << "state sync or block import did throw an exception: " << diagnostic_information(_e); + catch (Exception const& _e) + { + cnote << "state sync or block import did throw an exception: " << diagnostic_information(_e); BOOST_CHECK(o.count("blockHeader") == 0); BOOST_CHECK(o.count("transactions") == 0); BOOST_CHECK(o.count("uncleHeaders") == 0); - } - catch (std::exception const& _e) - { - cnote << "state sync or block import did throw an exception: " << _e.what(); + } + catch (std::exception const& _e) + { + cnote << "state sync or block import did throw an exception: " << _e.what(); BOOST_CHECK(o.count("blockHeader") == 0); BOOST_CHECK(o.count("transactions") == 0); BOOST_CHECK(o.count("uncleHeaders") == 0); - } - catch(...) - { + } + catch(...) + { cnote << "state sync or block import did throw an exception\n"; - BOOST_CHECK(o.count("blockHeader") == 0); - BOOST_CHECK(o.count("transactions") == 0); - BOOST_CHECK(o.count("uncleHeaders") == 0); - } + BOOST_CHECK(o.count("blockHeader") == 0); + BOOST_CHECK(o.count("transactions") == 0); + BOOST_CHECK(o.count("uncleHeaders") == 0); + } - // if yes, check parameters in blockHeader - // check transaction list - // check uncle list + // if yes, check parameters in blockHeader + // check transaction list + // check uncle list BOOST_REQUIRE(o.count("blockHeader") > 0); @@ -171,14 +258,14 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) BlockInfo blockFromRlp = bc.info(); //Check the fields restored from RLP to original fields - BOOST_CHECK_MESSAGE(blockHeaderFromFields.headerHash(WithNonce) == blockFromRlp.headerHash(WithNonce), "hash in given RLP not matching the block hash!"); + BOOST_CHECK_MESSAGE(blockHeaderFromFields.headerHash(WithNonce) == blockFromRlp.headerHash(WithNonce), "hash in given RLP not matching the block hash!"); BOOST_CHECK_MESSAGE(blockHeaderFromFields.parentHash == blockFromRlp.parentHash, "parentHash in given RLP not matching the block parentHash!"); BOOST_CHECK_MESSAGE(blockHeaderFromFields.sha3Uncles == blockFromRlp.sha3Uncles, "sha3Uncles in given RLP not matching the block sha3Uncles!"); BOOST_CHECK_MESSAGE(blockHeaderFromFields.coinbaseAddress == blockFromRlp.coinbaseAddress,"coinbaseAddress in given RLP not matching the block coinbaseAddress!"); BOOST_CHECK_MESSAGE(blockHeaderFromFields.stateRoot == blockFromRlp.stateRoot, "stateRoot in given RLP not matching the block stateRoot!"); BOOST_CHECK_MESSAGE(blockHeaderFromFields.transactionsRoot == blockFromRlp.transactionsRoot, "transactionsRoot in given RLP not matching the block transactionsRoot!"); - BOOST_CHECK_MESSAGE(blockHeaderFromFields.receiptsRoot == blockFromRlp.receiptsRoot, "receiptsRoot in given RLP not matching the block receiptsRoot!"); - BOOST_CHECK_MESSAGE(blockHeaderFromFields.logBloom == blockFromRlp.logBloom, "logBloom in given RLP not matching the block logBloom!"); + BOOST_CHECK_MESSAGE(blockHeaderFromFields.receiptsRoot == blockFromRlp.receiptsRoot, "receiptsRoot in given RLP not matching the block receiptsRoot!"); + BOOST_CHECK_MESSAGE(blockHeaderFromFields.logBloom == blockFromRlp.logBloom, "logBloom in given RLP not matching the block logBloom!"); BOOST_CHECK_MESSAGE(blockHeaderFromFields.difficulty == blockFromRlp.difficulty, "difficulty in given RLP not matching the block difficulty!"); BOOST_CHECK_MESSAGE(blockHeaderFromFields.number == blockFromRlp.number, "number in given RLP not matching the block number!"); BOOST_CHECK_MESSAGE(blockHeaderFromFields.gasLimit == blockFromRlp.gasLimit,"gasLimit in given RLP not matching the block gasLimit!"); @@ -189,215 +276,60 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) BOOST_CHECK_MESSAGE(blockHeaderFromFields == blockFromRlp, "However, blockHeaderFromFields != blockFromRlp!"); - //Check transaction list - - Transactions txsFromField; - - for (auto const& txObj: o["transactions"].get_array()) - { - mObject tx = txObj.get_obj(); - BOOST_REQUIRE(tx.count("nonce") > 0); - BOOST_REQUIRE(tx.count("gasPrice") > 0); - BOOST_REQUIRE(tx.count("gasLimit") > 0); - BOOST_REQUIRE(tx.count("to") > 0); - BOOST_REQUIRE(tx.count("value") > 0); - BOOST_REQUIRE(tx.count("v") > 0); - BOOST_REQUIRE(tx.count("r") > 0); - BOOST_REQUIRE(tx.count("s") > 0); - BOOST_REQUIRE(tx.count("data") > 0); - - Transaction t(createRLPStreamFromTransactionFields(tx).out(), CheckSignature::Sender); - txsFromField.push_back(t); - } - - Transactions txsFromRlp; - bytes blockRLP2 = importByteArray(o["rlp"].get_str()); - RLP root(blockRLP2); - for (auto const& tr: root[1]) - { - Transaction tx(tr.data(), CheckSignature::Sender); - txsFromRlp.push_back(tx); - } - - cout << "size of pending transactions: " << txsFromRlp.size() << endl; - - BOOST_CHECK_MESSAGE(txsFromRlp.size() == txsFromField.size(), "transaction list size does not match"); - - for (size_t i = 0; i < txsFromField.size(); ++i) - { - BOOST_CHECK_MESSAGE(txsFromField[i].data() == txsFromRlp[i].data(), "transaction data in rlp and in field do not match"); - BOOST_CHECK_MESSAGE(txsFromField[i].gas() == txsFromRlp[i].gas(), "transaction gasLimit in rlp and in field do not match"); - BOOST_CHECK_MESSAGE(txsFromField[i].gasPrice() == txsFromRlp[i].gasPrice(), "transaction gasPrice in rlp and in field do not match"); - BOOST_CHECK_MESSAGE(txsFromField[i].nonce() == txsFromRlp[i].nonce(), "transaction nonce in rlp and in field do not match"); - BOOST_CHECK_MESSAGE(txsFromField[i].signature().r == txsFromRlp[i].signature().r, "transaction r in rlp and in field do not match"); - BOOST_CHECK_MESSAGE(txsFromField[i].signature().s == txsFromRlp[i].signature().s, "transaction s in rlp and in field do not match"); - BOOST_CHECK_MESSAGE(txsFromField[i].signature().v == txsFromRlp[i].signature().v, "transaction v in rlp and in field do not match"); - BOOST_CHECK_MESSAGE(txsFromField[i].receiveAddress() == txsFromRlp[i].receiveAddress(), "transaction receiveAddress in rlp and in field do not match"); - BOOST_CHECK_MESSAGE(txsFromField[i].value() == txsFromRlp[i].value(), "transaction receiveAddress in rlp and in field do not match"); - - BOOST_CHECK_MESSAGE(txsFromField[i] == txsFromRlp[i], "however, transactions in rlp and in field do not match"); - } - - // check uncle list - - BOOST_CHECK_MESSAGE(o["uncleList"].get_array().size() == 0, "Uncle list is not empty, but the genesis block can not have uncles"); - - - - - - - - } - else - { - BOOST_REQUIRE(o.count("genesisBlockHeader") > 0); - - // construct RLP of the genesis block - bytes blockRLP = createBlockRLPFromFields(o["genesisBlockHeader"].get_obj()); - RLP myRLP(blockRLP); - BlockInfo blockFromFields; - - try - { - blockFromFields.populateFromHeader(myRLP, false); - } - catch (Exception const& _e) - { - cnote << "block construction did throw an exception: " << diagnostic_information(_e); - BOOST_ERROR("Failed block construction Test with Exception: " << _e.what()); - return; - } - catch (std::exception const& _e) - { - cnote << "block construction did throw an exception: " << _e.what(); - BOOST_ERROR("Failed block construction Test with Exception: " << _e.what()); - return; - } - catch(...) - { - cnote << "block construction did throw an unknown exception\n"; - return; - } - - BOOST_REQUIRE(o.count("pre") > 0); - - ImportTest importer(o["pre"].get_obj()); - State theState(Address(), OverlayDB(), BaseState::Empty); - importer.importState(o["pre"].get_obj(), theState); - - // commit changes to DB - theState.commit(); - - - // fillin specific --- start - - BOOST_REQUIRE(o.count("transactions") > 0); - - TransactionQueue txs; - - for (auto const& txObj: o["transactions"].get_array()) - { - mObject tx = txObj.get_obj(); - BOOST_REQUIRE(tx.count("nonce") > 0); - BOOST_REQUIRE(tx.count("gasPrice") > 0); - BOOST_REQUIRE(tx.count("gasLimit") > 0); - BOOST_REQUIRE(tx.count("to") > 0); - BOOST_REQUIRE(tx.count("value") > 0); - BOOST_REQUIRE(tx.count("v") > 0); - BOOST_REQUIRE(tx.count("r") > 0); - BOOST_REQUIRE(tx.count("s") > 0); - BOOST_REQUIRE(tx.count("data") > 0); - - //Transaction txFromFields(createRLPStreamFromTransactionFields(tx).out(), CheckSignature::Sender); - - if (!txs.attemptImport(&createRLPStreamFromTransactionFields(tx).out())) - cnote << "failed importing transaction\n"; - } - - // update stateRootHash - blockFromFields.stateRoot = theState.rootHash(); - cout << "root hash1: " << theState.rootHash() << endl; - - // find new valid nonce - ProofOfWork pow; - MineInfo ret; - tie(ret, blockFromFields.nonce) = pow.mine(blockFromFields.headerHash(WithoutNonce), blockFromFields.difficulty, 1000, true, false); - //---stop - - //update genesis block in json file - o["genesisBlockHeader"].get_obj()["stateRoot"] = toString(blockFromFields.stateRoot); - o["genesisBlockHeader"].get_obj()["nonce"] = toString(blockFromFields.nonce); - - - // create new "genesis" block - RLPStream rlpStream; - blockFromFields.streamRLP(rlpStream, WithNonce); - - RLPStream block(3); - block.appendRaw(rlpStream.out()); - block.appendRaw(RLPEmptyList); - block.appendRaw(RLPEmptyList); - - blockFromFields.verifyInternals(&block.out()); - - // construct blockchain - BlockChain bc(block.out(), string(), true); - - - - try - { - theState.sync(bc); - cout << "root hash2: " << theState.rootHash() << endl; - theState.sync(bc,txs); - cout << "root hash3: " << theState.rootHash() << endl; - theState.commitToMine(bc); - cout << "root hash4: " << theState.rootHash() << endl; - MineInfo info; - for (info.completed = false; !info.completed; info = theState.mine()) {} - cout << "root hash5: " << theState.rootHash() << endl; - theState.completeMine(); - cout << "root hash6: " << theState.rootHash() << endl; - } - catch (Exception const& _e) - { - cnote << "state sync or mining did throw an exception: " << diagnostic_information(_e); - } - catch (std::exception const& _e) - { - cnote << "state sync or mining did throw an exception: " << _e.what(); - } - - o["rlp"] = "0x" + toHex(theState.blockData()); - - // write block header - - mObject oBlockHeader; - BlockInfo current_BlockHeader = theState.info(); - oBlockHeader["parentHash"] = toString(current_BlockHeader.parentHash); - oBlockHeader["uncleHash"] = toString(current_BlockHeader.sha3Uncles); - oBlockHeader["coinbase"] = toString(current_BlockHeader.coinbaseAddress); - oBlockHeader["stateRoot"] = toString(current_BlockHeader.stateRoot); - oBlockHeader["transactionsTrie"] = toString(current_BlockHeader.transactionsRoot); - oBlockHeader["receiptTrie"] = toString(current_BlockHeader.receiptsRoot); - oBlockHeader["bloom"] = toString(current_BlockHeader.logBloom); - oBlockHeader["difficulty"] = toString(current_BlockHeader.difficulty); - oBlockHeader["number"] = toString(current_BlockHeader.number); - oBlockHeader["gasLimit"] = toString(current_BlockHeader.gasLimit); - oBlockHeader["gasUsed"] = toString(current_BlockHeader.gasUsed); - oBlockHeader["timestamp"] = toString(current_BlockHeader.timestamp); - oBlockHeader["extraData"] = toHex(current_BlockHeader.extraData); - oBlockHeader["nonce"] = toString(current_BlockHeader.nonce); - - o["blockHeader"] = oBlockHeader; - - // write uncle list - - mArray aUncleList; // as of now, our parent is always the genesis block, so we can not have uncles. - o["uncleHeaders"] = aUncleList; - } - } + //Check transaction list + + Transactions txsFromField; + + for (auto const& txObj: o["transactions"].get_array()) + { + mObject tx = txObj.get_obj(); + BOOST_REQUIRE(tx.count("nonce") > 0); + BOOST_REQUIRE(tx.count("gasPrice") > 0); + BOOST_REQUIRE(tx.count("gasLimit") > 0); + BOOST_REQUIRE(tx.count("to") > 0); + BOOST_REQUIRE(tx.count("value") > 0); + BOOST_REQUIRE(tx.count("v") > 0); + BOOST_REQUIRE(tx.count("r") > 0); + BOOST_REQUIRE(tx.count("s") > 0); + BOOST_REQUIRE(tx.count("data") > 0); + + Transaction t(createRLPStreamFromTransactionFields(tx).out(), CheckSignature::Sender); + txsFromField.push_back(t); + } + + Transactions txsFromRlp; + bytes blockRLP2 = importByteArray(o["rlp"].get_str()); + RLP root(blockRLP2); + for (auto const& tr: root[1]) + { + Transaction tx(tr.data(), CheckSignature::Sender); + txsFromRlp.push_back(tx); + } + + cout << "size of pending transactions: " << txsFromRlp.size() << endl; + + BOOST_CHECK_MESSAGE(txsFromRlp.size() == txsFromField.size(), "transaction list size does not match"); + + for (size_t i = 0; i < txsFromField.size(); ++i) + { + BOOST_CHECK_MESSAGE(txsFromField[i].data() == txsFromRlp[i].data(), "transaction data in rlp and in field do not match"); + BOOST_CHECK_MESSAGE(txsFromField[i].gas() == txsFromRlp[i].gas(), "transaction gasLimit in rlp and in field do not match"); + BOOST_CHECK_MESSAGE(txsFromField[i].gasPrice() == txsFromRlp[i].gasPrice(), "transaction gasPrice in rlp and in field do not match"); + BOOST_CHECK_MESSAGE(txsFromField[i].nonce() == txsFromRlp[i].nonce(), "transaction nonce in rlp and in field do not match"); + BOOST_CHECK_MESSAGE(txsFromField[i].signature().r == txsFromRlp[i].signature().r, "transaction r in rlp and in field do not match"); + BOOST_CHECK_MESSAGE(txsFromField[i].signature().s == txsFromRlp[i].signature().s, "transaction s in rlp and in field do not match"); + BOOST_CHECK_MESSAGE(txsFromField[i].signature().v == txsFromRlp[i].signature().v, "transaction v in rlp and in field do not match"); + BOOST_CHECK_MESSAGE(txsFromField[i].receiveAddress() == txsFromRlp[i].receiveAddress(), "transaction receiveAddress in rlp and in field do not match"); + BOOST_CHECK_MESSAGE(txsFromField[i].value() == txsFromRlp[i].value(), "transaction receiveAddress in rlp and in field do not match"); + + BOOST_CHECK_MESSAGE(txsFromField[i] == txsFromRlp[i], "however, transactions in rlp and in field do not match"); + } + + // check uncle list + + BOOST_CHECK_MESSAGE((o["uncleList"].type() == json_spirit::null_type ? 0 : o["uncleList"].get_array().size()) == 0, "Uncle list is not empty, but the genesis block can not have uncles"); + } + } } } }// Namespace Close From 7a126cf22378deeea59994339616675fad2dce76 Mon Sep 17 00:00:00 2001 From: subtly Date: Wed, 11 Feb 2015 14:10:08 -0500 Subject: [PATCH 091/213] update nodebucket modification time when node is inserted or bucket is refreshed so bucket-refresh doesn't loop --- libp2p/NodeTable.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index e6f8a171b..a65ebd53c 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -323,15 +323,20 @@ void NodeTable::noteActiveNode(Public const& _pubk, bi::udp::endpoint const& _en if (s.nodes.size() >= s_bucketSize) { + // It's only contested iff nodeentry exists contested = s.nodes.front().lock(); if (!contested) { s.nodes.pop_front(); s.nodes.push_back(node); + s.touch(); } } else + { s.nodes.push_back(node); + s.touch(); + } } if (contested) @@ -515,6 +520,7 @@ void NodeTable::doRefreshBuckets(boost::system::error_code const& _ec) for (auto& d: m_state) if (chrono::steady_clock::now() - d.modified > c_bucketRefresh) { + d.touch(); while (!d.nodes.empty()) { auto n = d.nodes.front(); From a88377e5cbd4bf908a0bf13de54abe7f51bbb8a4 Mon Sep 17 00:00:00 2001 From: Christian Date: Wed, 11 Feb 2015 20:20:37 +0100 Subject: [PATCH 092/213] Some windows fixes. --- libsolidity/CompilerContext.cpp | 2 +- test/SolidityEndToEndTest.cpp | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/libsolidity/CompilerContext.cpp b/libsolidity/CompilerContext.cpp index 52910a556..01a71d7c9 100644 --- a/libsolidity/CompilerContext.cpp +++ b/libsolidity/CompilerContext.cpp @@ -76,7 +76,7 @@ bytes const& CompilerContext::getCompiledContract(const ContractDefinition& _con bool CompilerContext::isLocalVariable(Declaration const* _declaration) const { - return m_localVariables.count(_declaration); + return !!m_localVariables.count(_declaration); } eth::AssemblyItem CompilerContext::getFunctionEntryLabel(Declaration const& _declaration) diff --git a/test/SolidityEndToEndTest.cpp b/test/SolidityEndToEndTest.cpp index 13a666fbf..8a21290cb 100644 --- a/test/SolidityEndToEndTest.cpp +++ b/test/SolidityEndToEndTest.cpp @@ -963,7 +963,7 @@ BOOST_AUTO_TEST_CASE(multiple_elementary_accessors) compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("data()") == encodeArgs(8)); BOOST_CHECK(callContractFunction("name()") == encodeArgs("Celina")); - BOOST_CHECK(callContractFunction("a_hash()") == encodeArgs(dev::sha3(bytes({0x7b})))); + BOOST_CHECK(callContractFunction("a_hash()") == encodeArgs(dev::sha3(bytes{0x7b}))); BOOST_CHECK(callContractFunction("an_address()") == encodeArgs(toBigEndian(u160(0x1337)))); BOOST_CHECK(callContractFunction("super_secret_data()") == bytes()); } @@ -2202,8 +2202,8 @@ BOOST_AUTO_TEST_CASE(sha3_multiple_arguments_with_numeric_literals) BOOST_CHECK(callContractFunction("foo(uint256,uint16)", 10, 12) == encodeArgs( dev::sha3( toBigEndian(u256(10)) + - bytes({0x0, 0xc}) + - bytes({0x91})))); + bytes{0x0, 0xc} + + bytes{0x91}))); } BOOST_AUTO_TEST_CASE(sha3_multiple_arguments_with_string_literals) @@ -2226,9 +2226,9 @@ BOOST_AUTO_TEST_CASE(sha3_multiple_arguments_with_string_literals) BOOST_CHECK(callContractFunction("bar(uint256,uint16)", 10, 12) == encodeArgs( dev::sha3( toBigEndian(u256(10)) + - bytes({0x0, 0xc}) + - bytes({0x91}) + - bytes({0x66, 0x6f, 0x6f})))); + bytes{0x0, 0xc} + + bytes{0x91} + + bytes{0x66, 0x6f, 0x6f}))); } BOOST_AUTO_TEST_CASE(generic_call) From 38230cb1e4ac81d75c4587f133a28412a5e77a0a Mon Sep 17 00:00:00 2001 From: subtly Date: Wed, 11 Feb 2015 15:54:31 -0500 Subject: [PATCH 093/213] Increase connect timeout for upnp initialization and fix resolver. --- libp2p/Host.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index 7010f9b04..5892121ed 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -413,13 +413,15 @@ void Host::addNode(NodeId const& _node, std::string const& _addr, unsigned short bi::address addr = bi::address::from_string(_addr, ec); if (ec) { - bi::tcp::resolver r(m_ioService); - r.async_resolve({_addr, toString(_tcpPeerPort)}, [=](boost::system::error_code const& _ec, bi::tcp::resolver::iterator _epIt) + bi::tcp::resolver *r = new bi::tcp::resolver(m_ioService); + r->async_resolve({_addr, toString(_tcpPeerPort)}, [=](boost::system::error_code const& _ec, bi::tcp::resolver::iterator _epIt) { - if (_ec) - return; - bi::tcp::endpoint tcp = *_epIt; - if (m_nodeTable) m_nodeTable->addNode(Node(_node, NodeIPEndpoint(bi::udp::endpoint(tcp.address(), _udpNodePort), tcp))); + if (!_ec) + { + bi::tcp::endpoint tcp = *_epIt; + if (m_nodeTable) m_nodeTable->addNode(Node(_node, NodeIPEndpoint(bi::udp::endpoint(tcp.address(), _udpNodePort), tcp))); + } + delete r; }); } else @@ -428,7 +430,7 @@ void Host::addNode(NodeId const& _node, std::string const& _addr, unsigned short void Host::connect(std::shared_ptr const& _p) { - for (unsigned i = 0; i < 40; i++) + for (unsigned i = 0; i < 200; i++) if (isWorking() && !m_run) this_thread::sleep_for(chrono::milliseconds(50)); if (!m_run) From de0b52ec696e2fbc30ebe04d3b17e4256c31bf47 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Wed, 11 Feb 2015 22:05:34 +0100 Subject: [PATCH 094/213] style --- test/block.cpp | 48 ++++++++++++++++++++++-------------------------- 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/test/block.cpp b/test/block.cpp index bfc7c01d6..88f7de634 100644 --- a/test/block.cpp +++ b/test/block.cpp @@ -48,16 +48,13 @@ bytes createBlockRLPFromFields(mObject& _tObj) BOOST_REQUIRE(_tObj.count("nonce") > 0); // construct RLP of the given block - cout << "done with require\n"; RLPStream rlpStream; rlpStream.appendList(14); - cout << "increate aha1\n"; rlpStream << h256(_tObj["parentHash"].get_str()) << h256(_tObj["uncleHash"].get_str()) << Address(_tObj["coinbase"].get_str()); rlpStream << h256(_tObj["stateRoot"].get_str()) << h256(_tObj["transactionsTrie"].get_str()) << h256(_tObj["receiptTrie"].get_str()); rlpStream << LogBloom(_tObj["bloom"].get_str()) << u256(_tObj["difficulty"].get_str()) << u256(_tObj["number"].get_str()); rlpStream << u256(_tObj["gasLimit"].get_str()) << u256(_tObj["gasUsed"].get_str()) << u256(_tObj["timestamp"].get_str()); rlpStream << importByteArray(_tObj["extraData"].get_str()) << h256(_tObj["nonce"].get_str()); - cout << "done createBlockRLPFromFields" << endl; return rlpStream.out(); } @@ -72,45 +69,44 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) BOOST_REQUIRE(o.count("genesisBlockHeader") > 0); // construct RLP of the genesis block - bytes blockRLP = createBlockRLPFromFields(o["genesisBlockHeader"].get_obj()); - RLP myRLP(blockRLP); + const bytes c_blockRLP = createBlockRLPFromFields(o["genesisBlockHeader"].get_obj()); + const RLP c_bRLP(c_blockRLP); BlockInfo blockFromFields; try { - blockFromFields.populateFromHeader(myRLP, false); + blockFromFields.populateFromHeader(c_bRLP, false); } catch (Exception const& _e) { - cnote << "block construction did throw an exception: " << diagnostic_information(_e); - BOOST_ERROR("Failed block construction Test with Exception: " << _e.what()); + cnote << "block population did throw an exception: " << diagnostic_information(_e); + BOOST_ERROR("Failed block population with Exception: " << _e.what()); return; } catch (std::exception const& _e) { - cnote << "block construction did throw an exception: " << _e.what(); - BOOST_ERROR("Failed block construction Test with Exception: " << _e.what()); + BOOST_ERROR("Failed block population with Exception: " << _e.what()); return; } catch(...) { - cnote << "block construction did throw an unknown exception\n"; + cnote << "block population did throw an unknown exception\n"; return; } BOOST_REQUIRE(o.count("pre") > 0); ImportTest importer(o["pre"].get_obj()); - State theState(Address(), OverlayDB(), BaseState::Empty); - importer.importState(o["pre"].get_obj(), theState); + State state(Address(), OverlayDB(), BaseState::Empty); + importer.importState(o["pre"].get_obj(), state); // commit changes to DB - theState.commit(); + state.commit(); if (_fillin) - blockFromFields.stateRoot = theState.rootHash(); + blockFromFields.stateRoot = state.rootHash(); else - BOOST_CHECK_MESSAGE(blockFromFields.stateRoot == theState.rootHash(), "root hash do not match"); + BOOST_CHECK_MESSAGE(blockFromFields.stateRoot == state.rootHash(), "root hash does not match"); if (_fillin) { @@ -165,12 +161,12 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) try { - theState.sync(bc); - theState.sync(bc,txs); - theState.commitToMine(bc); + state.sync(bc); + state.sync(bc,txs); + state.commitToMine(bc); MineInfo info; - for (info.completed = false; !info.completed; info = theState.mine()) {} - theState.completeMine(); + for (info.completed = false; !info.completed; info = state.mine()) {} + state.completeMine(); } catch (Exception const& _e) { @@ -181,12 +177,12 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) cnote << "state sync or mining did throw an exception: " << _e.what(); } - o["rlp"] = "0x" + toHex(theState.blockData()); + o["rlp"] = "0x" + toHex(state.blockData()); // write block header mObject oBlockHeader; - BlockInfo current_BlockHeader = theState.info(); + BlockInfo current_BlockHeader = state.info(); oBlockHeader["parentHash"] = toString(current_BlockHeader.parentHash); oBlockHeader["uncleHash"] = toString(current_BlockHeader.sha3Uncles); oBlockHeader["coinbase"] = toString(current_BlockHeader.coinbaseAddress); @@ -214,10 +210,10 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) { try { - theState.sync(bc); + state.sync(bc); bytes blockRLP = importByteArray(o["rlp"].get_str()); - bc.import(blockRLP, theState.db()); - theState.sync(bc); + bc.import(blockRLP, state.db()); + state.sync(bc); } // if exception is thrown, RLP is invalid and not blockHeader, Transaction list, and Uncle list should be given catch (Exception const& _e) From d8cf73b4ad6d8d7d2cac5dbfdb59df5a8a67dc52 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Wed, 11 Feb 2015 22:28:43 +0100 Subject: [PATCH 095/213] add ability to throw to fromHex --- alethzero/MainWin.cpp | 6 +++--- libdevcore/CommonData.cpp | 8 +++++--- libdevcore/CommonData.h | 3 ++- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index b76c94508..e5dae5644 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -1330,15 +1330,15 @@ void Main::on_inject_triggered() bytes b; try { - b = fromHex(s.toStdString()); + b = fromHex(s.toStdString(), true); } - catch(BadHexCharacter& _e) + catch (BadHexCharacter& _e) { cnote << "invalid hex character, transaction rejected"; cnote << boost::diagnostic_information(_e); return; } - catch(...) + catch (...) { cnote << "transaction rejected"; return; diff --git a/libdevcore/CommonData.cpp b/libdevcore/CommonData.cpp index efdd48d4a..59372bfd0 100644 --- a/libdevcore/CommonData.cpp +++ b/libdevcore/CommonData.cpp @@ -78,7 +78,7 @@ int dev::fromHex(char _i) BOOST_THROW_EXCEPTION(BadHexCharacter() << errinfo_invalidSymbol(_i)); } -bytes dev::fromHex(std::string const& _s) +bytes dev::fromHex(std::string const& _s, bool _throw) { unsigned s = (_s[0] == '0' && _s[1] == 'x') ? 2 : 0; std::vector ret; @@ -96,7 +96,8 @@ bytes dev::fromHex(std::string const& _s) #ifndef BOOST_NO_EXCEPTIONS cwarn << boost::current_exception_diagnostic_information(); #endif - throw; + if (_throw) + throw; } for (unsigned i = s; i < _s.size(); i += 2) try @@ -108,7 +109,8 @@ bytes dev::fromHex(std::string const& _s) #ifndef BOOST_NO_EXCEPTIONS cwarn << boost::current_exception_diagnostic_information(); #endif - throw; + if (_throw) + throw; } return ret; } diff --git a/libdevcore/CommonData.h b/libdevcore/CommonData.h index 883e76dd9..b2370950a 100644 --- a/libdevcore/CommonData.h +++ b/libdevcore/CommonData.h @@ -53,7 +53,8 @@ int fromHex(char _i); /// Converts a (printable) ASCII hex string into the corresponding byte stream. /// @example fromHex("41626261") == asBytes("Abba") -bytes fromHex(std::string const& _s); +/// If _throw = false, it replaces bad hex characters with 0's, otherwise it will throw an exception. +bytes fromHex(std::string const& _s, bool _throw = false); #if 0 std::string toBase58(bytesConstRef _data); From f070de2047843f31d8bbedaa9b992a0667276c2c Mon Sep 17 00:00:00 2001 From: subtly Date: Thu, 12 Feb 2015 00:00:05 -0500 Subject: [PATCH 096/213] load network before constructing webthreedirect --- alethzero/MainWin.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index f3714e76e..1d4427789 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -162,6 +162,8 @@ Main::Main(QWidget *parent) : connect(ui->ourAccounts->model(), SIGNAL(rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)), SLOT(ourAccountsRowsMoved())); + QSettings s("ethereum", "alethzero"); + m_networkConfig = s.value("peers").toByteArray(); bytesConstRef network((byte*)m_networkConfig.data(), m_networkConfig.size()); m_webThree.reset(new WebThreeDirect(string("AlethZero/v") + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM), getDataDir() + "/AlethZero", false, {"eth", "shh"}, p2p::NetworkPreferences(), network)); @@ -715,7 +717,6 @@ void Main::readSettings(bool _skipGeometry) } } - m_networkConfig = s.value("peers").toByteArray(); ui->upnp->setChecked(s.value("upnp", true).toBool()); ui->forceAddress->setText(s.value("forceAddress", "").toString()); ui->usePast->setChecked(s.value("usePast", true).toBool()); From 3291bc1d9aabc703349263006592620f4408d646 Mon Sep 17 00:00:00 2001 From: subtly Date: Thu, 12 Feb 2015 00:17:31 -0500 Subject: [PATCH 097/213] perform node discovery when there aren't enough nodes --- libp2p/Host.cpp | 6 +++++- libp2p/NodeTable.cpp | 4 +++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index 5892121ed..f09468e0d 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -534,7 +534,8 @@ void Host::run(boost::system::error_code const&) keepAlivePeers(); disconnectLatePeers(); - if (m_idealPeerCount && !peerCount()) + auto c = peerCount(); + if (m_idealPeerCount && !c) for (auto p: m_peers) if (p.second->shouldReconnect()) { @@ -544,6 +545,9 @@ void Host::run(boost::system::error_code const&) break; } + if (c < m_idealPeerCount) + m_nodeTable->discover(); + auto runcb = [this](boost::system::error_code const& error) { run(error); }; m_timer->expires_from_now(boost::posix_time::milliseconds(c_timerInterval)); m_timer->async_wait(runcb); diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index a65ebd53c..15eca291c 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -106,7 +106,9 @@ shared_ptr NodeTable::addNode(Node const& _node) void NodeTable::discover() { - discover(m_node.id); + static chrono::steady_clock::time_point s_lastDiscover = chrono::steady_clock::now() - std::chrono::seconds(30); + if (chrono::steady_clock::now() > s_lastDiscover + std::chrono::seconds(30)) + discover(m_node.id); } list NodeTable::nodes() const From 57f6aacf9ed981811873f8012586259ddfbc3ac3 Mon Sep 17 00:00:00 2001 From: subtly Date: Thu, 12 Feb 2015 00:31:48 -0500 Subject: [PATCH 098/213] update last discovery timepoint --- libp2p/NodeTable.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index 15eca291c..adeb43c2e 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -108,7 +108,10 @@ void NodeTable::discover() { static chrono::steady_clock::time_point s_lastDiscover = chrono::steady_clock::now() - std::chrono::seconds(30); if (chrono::steady_clock::now() > s_lastDiscover + std::chrono::seconds(30)) + { + s_lastDiscover = chrono::steady_clock::now(); discover(m_node.id); + } } list NodeTable::nodes() const From 99a2acbad134e4ae9685d5cf37dab35a886f518c Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Thu, 12 Feb 2015 09:35:33 +0100 Subject: [PATCH 099/213] replace bool with enum --- libdevcore/CommonData.cpp | 6 +++--- libdevcore/CommonData.h | 8 +++++++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/libdevcore/CommonData.cpp b/libdevcore/CommonData.cpp index 59372bfd0..b2478d233 100644 --- a/libdevcore/CommonData.cpp +++ b/libdevcore/CommonData.cpp @@ -78,7 +78,7 @@ int dev::fromHex(char _i) BOOST_THROW_EXCEPTION(BadHexCharacter() << errinfo_invalidSymbol(_i)); } -bytes dev::fromHex(std::string const& _s, bool _throw) +bytes dev::fromHex(std::string const& _s, ThrowType _throw) { unsigned s = (_s[0] == '0' && _s[1] == 'x') ? 2 : 0; std::vector ret; @@ -96,7 +96,7 @@ bytes dev::fromHex(std::string const& _s, bool _throw) #ifndef BOOST_NO_EXCEPTIONS cwarn << boost::current_exception_diagnostic_information(); #endif - if (_throw) + if (_throw = ThrowType::Throw) throw; } for (unsigned i = s; i < _s.size(); i += 2) @@ -109,7 +109,7 @@ bytes dev::fromHex(std::string const& _s, bool _throw) #ifndef BOOST_NO_EXCEPTIONS cwarn << boost::current_exception_diagnostic_information(); #endif - if (_throw) + if (_throw = ThrowType::Throw) throw; } return ret; diff --git a/libdevcore/CommonData.h b/libdevcore/CommonData.h index b2370950a..c82d0b7cb 100644 --- a/libdevcore/CommonData.h +++ b/libdevcore/CommonData.h @@ -35,6 +35,12 @@ namespace dev // String conversion functions, mainly to/from hex/nibble/byte representations. +enum class ThrowType +{ + NoThrow = 0, + Throw = 1, +}; + /// Convert a series of bytes to the corresponding string of hex duplets. /// @param _w specifies the width of each of the elements. Defaults to two - enough to represent a byte. /// @example toHex("A\x69") == "4169" @@ -54,7 +60,7 @@ int fromHex(char _i); /// Converts a (printable) ASCII hex string into the corresponding byte stream. /// @example fromHex("41626261") == asBytes("Abba") /// If _throw = false, it replaces bad hex characters with 0's, otherwise it will throw an exception. -bytes fromHex(std::string const& _s, bool _throw = false); +bytes fromHex(std::string const& _s, ThrowType _throw = ThrowType::NoThrow); #if 0 std::string toBase58(bytesConstRef _data); From 2895dc6648d50cbcf2c812e486272219e4d230e1 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Thu, 12 Feb 2015 09:37:24 +0100 Subject: [PATCH 100/213] typo --- libdevcore/CommonData.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libdevcore/CommonData.cpp b/libdevcore/CommonData.cpp index b2478d233..09b525d59 100644 --- a/libdevcore/CommonData.cpp +++ b/libdevcore/CommonData.cpp @@ -96,7 +96,7 @@ bytes dev::fromHex(std::string const& _s, ThrowType _throw) #ifndef BOOST_NO_EXCEPTIONS cwarn << boost::current_exception_diagnostic_information(); #endif - if (_throw = ThrowType::Throw) + if (_throw == ThrowType::Throw) throw; } for (unsigned i = s; i < _s.size(); i += 2) @@ -109,7 +109,7 @@ bytes dev::fromHex(std::string const& _s, ThrowType _throw) #ifndef BOOST_NO_EXCEPTIONS cwarn << boost::current_exception_diagnostic_information(); #endif - if (_throw = ThrowType::Throw) + if (_throw == ThrowType::Throw) throw; } return ret; From be383da6246254a4bb7c0a6d472c25f419c0e964 Mon Sep 17 00:00:00 2001 From: Lu Guanqun Date: Thu, 12 Feb 2015 17:41:26 +0800 Subject: [PATCH 101/213] spot a simple typo when reading coding standards --- CodingStandards.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CodingStandards.txt b/CodingStandards.txt index 78885ce25..f883c9147 100644 --- a/CodingStandards.txt +++ b/CodingStandards.txt @@ -93,7 +93,7 @@ b. Only one per line. c. Associate */& with type, not variable (at ends with parser, but more readable, and safe if in conjunction with (b)). d. Favour declarations close to use; don't habitually declare at top of scope ala C. e. Always pass non-trivial parameters with a const& suffix. -f. If a func tion returns multiple values, use std::tuple (std::pair acceptable). Prefer not using */& arguments, except where efficiency requires. +f. If a function returns multiple values, use std::tuple (std::pair acceptable). Prefer not using */& arguments, except where efficiency requires. g. Never use a macro where adequate non-preprocessor C++ can be written. h. Prefer "using NewType = OldType" to "typedef OldType NewType". From bd373f4be93fecdbe314422d41f74402fefef3b1 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Thu, 12 Feb 2015 11:12:00 +0100 Subject: [PATCH 102/213] avoiding catastrophic typos in addresses --- alethzero/MainWin.cpp | 32 ++++++++++----- eth/main.cpp | 90 ++++++++++++++++++++++++++++++++++++----- libdevcore/CommonData.h | 2 +- neth/main.cpp | 73 +++++++++++++++++++++++++++++---- 4 files changed, 168 insertions(+), 29 deletions(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index e5dae5644..907eda568 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -569,7 +569,23 @@ Address Main::fromString(QString const& _n) const }*/ if (_n.size() == 40) - return Address(fromHex(_n.toStdString())); + { + try + { + return Address(fromHex(_n.toStdString(), ThrowType::Throw)); + } + catch (BadHexCharacter& _e) + { + cwarn << "invalid hex character, address rejected"; + cwarn << boost::diagnostic_information(_e); + return Address(); + } + catch (...) + { + cwarn << "address rejected"; + return Address(); + } + } else return Address(); } @@ -1327,24 +1343,20 @@ void Main::ourAccountsRowsMoved() void Main::on_inject_triggered() { QString s = QInputDialog::getText(this, "Inject Transaction", "Enter transaction dump in hex"); - bytes b; try { - b = fromHex(s.toStdString(), true); + bytes b = fromHex(s.toStdString(), ThrowType::Throw); + ethereum()->inject(&b); } catch (BadHexCharacter& _e) { - cnote << "invalid hex character, transaction rejected"; - cnote << boost::diagnostic_information(_e); - return; + cwarn << "invalid hex character, transaction rejected"; + cwarn << boost::diagnostic_information(_e); } catch (...) { - cnote << "transaction rejected"; - return; + cwarn << "transaction rejected"; } - - ethereum()->inject(&b); } void Main::on_blocks_currentItemChanged() diff --git a/eth/main.cpp b/eth/main.cpp index 7a128298a..1c72b7036 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -258,7 +258,23 @@ int main(int argc, char** argv) else if ((arg == "-c" || arg == "--client-name") && i + 1 < argc) clientName = argv[++i]; else if ((arg == "-a" || arg == "--address" || arg == "--coinbase-address") && i + 1 < argc) - coinbase = h160(fromHex(argv[++i])); + { + try + { + coinbase = h160(fromHex(argv[++i], ThrowType::Throw)); + } + catch (BadHexCharacter& _e) + { + cwarn << "invalid hex character, coinbase rejected"; + cwarn << boost::diagnostic_information(_e); + break; + } + catch (...) + { + cwarn << "coinbase rejected"; + break; + } + } else if ((arg == "-s" || arg == "--secret") && i + 1 < argc) us = KeyPair(h256(fromHex(argv[++i]))); else if ((arg == "-d" || arg == "--path" || arg == "--db-path") && i + 1 < argc) @@ -532,9 +548,21 @@ int main(int argc, char** argv) } else { - Secret secret = h256(fromHex(sechex)); - Address dest = h160(fromHex(hexAddr)); - c->transact(secret, amount, dest, data, gas, gasPrice); + try + { + Secret secret = h256(fromHex(sechex)); + Address dest = h160(fromHex(hexAddr)); + c->transact(secret, amount, dest, data, gas, gasPrice); + } + catch (BadHexCharacter& _e) + { + cwarn << "invalid hex character, transaction rejected"; + cwarn << boost::diagnostic_information(_e); + } + catch (...) + { + cwarn << "transaction rejected"; + } } } else @@ -583,8 +611,20 @@ int main(int argc, char** argv) auto blockData = bc.block(h); BlockInfo info(blockData); u256 minGas = (u256)Client::txGas(bytes(), 0); - Address dest = h160(fromHex(hexAddr)); - c->transact(us.secret(), amount, dest, bytes(), minGas); + try + { + Address dest = h160(fromHex(hexAddr, ThrowType::Throw)); + c->transact(us.secret(), amount, dest, bytes(), minGas); + } + catch (BadHexCharacter& _e) + { + cwarn << "invalid hex character, transaction rejected"; + cwarn << boost::diagnostic_information(_e); + } + catch (...) + { + cwarn << "transaction rejected"; + } } } else @@ -615,14 +655,30 @@ int main(int argc, char** argv) { cnote << "Assembled:"; stringstream ssc; - init = fromHex(sinit); + try + { + init = fromHex(sinit, ThrowType::Throw); + } + catch (BadHexCharacter& _e) + { + cwarn << "invalid hex character, code rejected"; + cwarn << boost::diagnostic_information(_e); + init = bytes(); + } + catch (...) + { + cwarn << "code rejected"; + init = bytes(); + } ssc.str(string()); ssc << disassemble(init); cnote << "Init:"; cnote << ssc.str(); } u256 minGas = (u256)Client::txGas(init, 0); - if (endowment < 0) + if (!init.size()) + cwarn << "Contract creation aborted, no init code."; + else if (endowment < 0) cwarn << "Invalid endowment"; else if (gas < minGas) cwarn << "Minimum gas amount is" << minGas; @@ -759,8 +815,22 @@ int main(int argc, char** argv) if (hexAddr.length() != 40) cwarn << "Invalid address length: " << hexAddr.length(); else - coinbase = h160(fromHex(hexAddr)); - } + { + try + { + coinbase = h160(fromHex(hexAddr, ThrowType::Throw)); + } + catch (BadHexCharacter& _e) + { + cwarn << "invalid hex character, coinbase rejected"; + cwarn << boost::diagnostic_information(_e); + } + catch (...) + { + cwarn << "coinbase rejected"; + } + } + } else cwarn << "Require parameter: setAddress HEXADDRESS"; } diff --git a/libdevcore/CommonData.h b/libdevcore/CommonData.h index c82d0b7cb..3cdf3b449 100644 --- a/libdevcore/CommonData.h +++ b/libdevcore/CommonData.h @@ -59,7 +59,7 @@ int fromHex(char _i); /// Converts a (printable) ASCII hex string into the corresponding byte stream. /// @example fromHex("41626261") == asBytes("Abba") -/// If _throw = false, it replaces bad hex characters with 0's, otherwise it will throw an exception. +/// If _throw = ThrowType::NoThrow, it replaces bad hex characters with 0's, otherwise it will throw an exception. bytes fromHex(std::string const& _s, ThrowType _throw = ThrowType::NoThrow); #if 0 diff --git a/neth/main.cpp b/neth/main.cpp index 2c1a85241..efede7bb2 100644 --- a/neth/main.cpp +++ b/neth/main.cpp @@ -366,7 +366,23 @@ int main(int argc, char** argv) else if ((arg == "-c" || arg == "--client-name") && i + 1 < argc) clientName = argv[++i]; else if ((arg == "-a" || arg == "--address" || arg == "--coinbase-address") && i + 1 < argc) - coinbase = h160(fromHex(argv[++i])); + { + try + { + coinbase = h160(fromHex(argv[++i], ThrowType::Throw)); + } + catch (BadHexCharacter& _e) + { + cwarn << "invalid hex character, coinbase rejected"; + cwarn << boost::diagnostic_information(_e); + break; + } + catch (...) + { + cwarn << "coinbase rejected"; + break; + } + } else if ((arg == "-s" || arg == "--secret") && i + 1 < argc) us = KeyPair(h256(fromHex(argv[++i]))); else if ((arg == "-d" || arg == "--path" || arg == "--db-path") && i + 1 < argc) @@ -709,9 +725,21 @@ int main(int argc, char** argv) } else { - Secret secret = h256(fromHex(sechex)); - Address dest = h160(fromHex(fields[0])); - c->transact(secret, amount, dest, data, gas, gasPrice); + try + { + Secret secret = h256(fromHex(sechex, ThrowType::Throw)); + Address dest = h160(fromHex(fields[0], ThrowType::Throw)); + c->transact(secret, amount, dest, data, gas, gasPrice); + } + catch (BadHexCharacter& _e) + { + cwarn << "invalid hex character, transaction rejected"; + cwarn << boost::diagnostic_information(_e); + } + catch (...) + { + cwarn << "transaction rejected"; + } } } } @@ -749,8 +777,20 @@ int main(int argc, char** argv) auto blockData = bc.block(h); BlockInfo info(blockData); u256 minGas = (u256)Client::txGas(bytes(), 0); - Address dest = h160(fromHex(fields[0])); - c->transact(us.secret(), amount, dest, bytes(), minGas); + try + { + Address dest = h160(fromHex(fields[0], ThrowType::Throw)); + c->transact(us.secret(), amount, dest, bytes(), minGas); + } + catch (BadHexCharacter& _e) + { + cwarn << "invalid hex character, transaction rejected"; + cwarn << boost::diagnostic_information(_e); + } + catch (...) + { + cwarn << "transaction rejected"; + } } } } @@ -803,14 +843,31 @@ int main(int argc, char** argv) { cnote << "Assembled:"; stringstream ssc; - init = fromHex(sinit); + try + { + init = fromHex(sinit, ThrowType::Throw); + } + catch (BadHexCharacter& _e) + { + cwarn << "invalid hex character, code rejected"; + cwarn << boost::diagnostic_information(_e); + init = bytes(); + } + catch (...) + { + cwarn << "code rejected"; + init = bytes(); + } + ssc.str(string()); ssc << disassemble(init); cnote << "Init:"; cnote << ssc.str(); } u256 minGas = (u256)Client::txGas(init, 0); - if (endowment < 0) + if (!init.size()) + cwarn << "Contract creation aborted, no init code."; + else if (endowment < 0) cwarn << "Invalid endowment"; else if (gas < minGas) cwarn << "Minimum gas amount is" << minGas; From 1e6f3cb1bd437e18693f0a477bc76128d86978c3 Mon Sep 17 00:00:00 2001 From: Christian Date: Mon, 9 Feb 2015 18:45:00 +0100 Subject: [PATCH 103/213] Introduced byte array type. --- libsolidity/Token.h | 6 +++--- libsolidity/Types.cpp | 11 +++++++++++ libsolidity/Types.h | 32 ++++++++++++++++++++++++++++---- 3 files changed, 42 insertions(+), 7 deletions(-) diff --git a/libsolidity/Token.h b/libsolidity/Token.h index ac8c618fa..5167c1a77 100644 --- a/libsolidity/Token.h +++ b/libsolidity/Token.h @@ -176,8 +176,7 @@ namespace solidity K(SubFinney, "finney", 0) \ K(SubEther, "ether", 0) \ /* type keywords, keep them in this order, keep int as first keyword - * the implementation in Types.cpp has to be synced to this here - * TODO more to be added */ \ + * the implementation in Types.cpp has to be synced to this here */\ K(Int, "int", 0) \ K(Int8, "int8", 0) \ K(Int16, "int16", 0) \ @@ -279,7 +278,8 @@ namespace solidity K(Hash256, "hash256", 0) \ K(Address, "address", 0) \ K(Bool, "bool", 0) \ - K(StringType, "string", 0) \ + K(Bytes, "bytes", 0) \ + K(StringType, "string", 0) \ K(String0, "string0", 0) \ K(String1, "string1", 0) \ K(String2, "string2", 0) \ diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index 5f573a6da..069493e62 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -57,6 +57,8 @@ shared_ptr Type::fromElementaryTypeName(Token::Value _typeToken) return make_shared(); else if (Token::String0 <= _typeToken && _typeToken <= Token::String32) return make_shared(int(_typeToken) - int(Token::String0)); + else if (_typeToken == Token::Bytes) + return make_shared(ByteArrayType::Location::Storage, 0, 0, true); else BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unable to convert elementary typename " + std::string(Token::toString(_typeToken)) + " to type.")); @@ -506,6 +508,15 @@ TypePointer ContractType::unaryOperatorResult(Token::Value _operator) const return _operator == Token::Delete ? make_shared() : TypePointer(); } +bool ByteArrayType::operator==(Type const& _other) const +{ + if (_other.getCategory() != getCategory()) + return false; + ByteArrayType const& other = dynamic_cast(_other); + return other.m_location == m_location && other.m_dynamicLength == m_dynamicLength + && other.m_length == m_length && other.m_offset == m_offset; +} + bool ContractType::operator==(Type const& _other) const { if (_other.getCategory() != getCategory()) diff --git a/libsolidity/Types.h b/libsolidity/Types.h index 05090c7a2..927ca2902 100644 --- a/libsolidity/Types.h +++ b/libsolidity/Types.h @@ -76,9 +76,10 @@ class Type: private boost::noncopyable, public std::enable_shared_from_this Date: Tue, 10 Feb 2015 09:00:50 +0100 Subject: [PATCH 104/213] Tests and some code for msg.data. --- libsolidity/AST.cpp | 3 ++- libsolidity/Types.cpp | 14 +++++++++++++- libsolidity/Types.h | 2 +- test/SolidityEndToEndTest.cpp | 25 +++++++++++++++++++++++++ 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp index 041b6277d..33cf8c12d 100644 --- a/libsolidity/AST.cpp +++ b/libsolidity/AST.cpp @@ -403,7 +403,8 @@ void Assignment::checkTypeRequirements() m_leftHandSide->checkTypeRequirements(); m_leftHandSide->requireLValue(); //@todo later, assignments to structs might be possible, but not to mappings - if (!m_leftHandSide->getType()->isValueType() && !m_leftHandSide->isLocalLValue()) + if (m_leftHandSide->getType()->getCategory() != Type::Category::ByteArray && + !m_leftHandSide->getType()->isValueType() && !m_leftHandSide->isLocalLValue()) BOOST_THROW_EXCEPTION(createTypeError("Assignment to non-local non-value lvalue.")); m_type = m_leftHandSide->getType(); if (m_assigmentOperator == Token::Assign) diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index 069493e62..9faa3f3c0 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -508,6 +508,16 @@ TypePointer ContractType::unaryOperatorResult(Token::Value _operator) const return _operator == Token::Delete ? make_shared() : TypePointer(); } +bool ByteArrayType::isImplicitlyConvertibleTo(const Type& _convertTo) const +{ + if (*this == _convertTo) + return true; + if (_convertTo.getCategory() != Category::ByteArray) + return false; + auto const& other = dynamic_cast(_convertTo); + return (m_dynamicLength == other.m_dynamicLength || m_length == other.m_length); +} + bool ByteArrayType::operator==(Type const& _other) const { if (_other.getCategory() != getCategory()) @@ -952,7 +962,9 @@ MagicType::MagicType(MagicType::Kind _kind): case Kind::Message: m_members = MemberList({{"sender", make_shared(0, IntegerType::Modifier::Address)}, {"gas", make_shared(256)}, - {"value", make_shared(256)}}); + {"value", make_shared(256)}, + {"data", make_shared(ByteArrayType::Location::CallData, + 0, 0, true)}}); break; case Kind::Transaction: m_members = MemberList({{"origin", make_shared(0, IntegerType::Modifier::Address)}, diff --git a/libsolidity/Types.h b/libsolidity/Types.h index 927ca2902..ddcfad9ed 100644 --- a/libsolidity/Types.h +++ b/libsolidity/Types.h @@ -287,11 +287,11 @@ public: virtual Category getCategory() const override { return Category::ByteArray; } ByteArrayType(Location _location, u256 const& _offset, u256 const& _length, bool _dynamicLength): m_location(_location), m_offset(_offset), m_length(_length), m_dynamicLength(_dynamicLength) {} + virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override; virtual bool operator==(const Type& _other) const override; virtual unsigned getSizeOnStack() const override { return 1; /* TODO */ } virtual std::string toString() const override { return "bytes"; } - private: Location m_location; u256 m_offset; diff --git a/test/SolidityEndToEndTest.cpp b/test/SolidityEndToEndTest.cpp index 8a21290cb..054b0c6a4 100644 --- a/test/SolidityEndToEndTest.cpp +++ b/test/SolidityEndToEndTest.cpp @@ -2254,6 +2254,31 @@ BOOST_AUTO_TEST_CASE(generic_call) BOOST_CHECK_EQUAL(m_state.balance(m_contractAddress), 50 - 2); } +BOOST_AUTO_TEST_CASE(storing_bytes) +{ + char const* sourceCode = R"( + contract C { + function save() { + savedData = msg.data; + } + function forward() { + this.call(savedData); + } + function clear() { + delete savedData; + } + function doubleIt(uint a) returns (uint b) { return a * 2; } + bytes savedData; + } + )"; + compileAndRun(sourceCode); + FixedHash<4> innerHash(dev::sha3("doubleIt(uint256)")); + BOOST_CHECK(callContractFunction("save()", innerHash.asBytes(), 7) == bytes()); + BOOST_CHECK(callContractFunction("forward()") == encodeArgs(14)); + BOOST_CHECK(callContractFunction("clear()") == bytes()); + BOOST_CHECK(callContractFunction("forward()") == bytes()); +} + BOOST_AUTO_TEST_SUITE_END() } From f9d853fe909ba443342598aa49c9a7daf8398716 Mon Sep 17 00:00:00 2001 From: Christian Date: Tue, 10 Feb 2015 14:57:01 +0100 Subject: [PATCH 105/213] Simple copy of bytes to storage. --- libsolidity/ExpressionCompiler.cpp | 118 ++++++++++++++++++++++++----- libsolidity/ExpressionCompiler.h | 5 +- libsolidity/Types.cpp | 18 ++++- libsolidity/Types.h | 11 ++- test/SolidityEndToEndTest.cpp | 65 +++++++++++++++- 5 files changed, 189 insertions(+), 28 deletions(-) diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index beda01322..8c9028e45 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -59,13 +59,15 @@ void ExpressionCompiler::appendStateVariableAccessor(CompilerContext& _context, bool ExpressionCompiler::visit(Assignment const& _assignment) { _assignment.getRightHandSide().accept(*this); - appendTypeConversion(*_assignment.getRightHandSide().getType(), *_assignment.getType()); + if (_assignment.getType()->isValueType()) + appendTypeConversion(*_assignment.getRightHandSide().getType(), *_assignment.getType()); _assignment.getLeftHandSide().accept(*this); solAssert(m_currentLValue.isValid(), "LValue not retrieved."); Token::Value op = _assignment.getAssignmentOperator(); if (op != Token::Assign) // compound assignment { + solAssert(_assignment.getType()->isValueType(), "Compound operators not implemented for non-value types."); if (m_currentLValue.storesReferenceOnStack()) m_context << eth::Instruction::SWAP1 << eth::Instruction::DUP2; m_currentLValue.retrieveValue(_assignment.getType(), _assignment.getLocation(), true); @@ -73,7 +75,7 @@ bool ExpressionCompiler::visit(Assignment const& _assignment) if (m_currentLValue.storesReferenceOnStack()) m_context << eth::Instruction::SWAP1; } - m_currentLValue.storeValue(_assignment); + m_currentLValue.storeValue(_assignment, *_assignment.getRightHandSide().getType()); m_currentLValue.reset(); return false; @@ -126,7 +128,7 @@ bool ExpressionCompiler::visit(UnaryOperation const& _unaryOperation) // Stack for postfix: *ref [ref] (*ref)+-1 if (m_currentLValue.storesReferenceOnStack()) m_context << eth::Instruction::SWAP1; - m_currentLValue.storeValue(_unaryOperation, !_unaryOperation.isPrefixOperation()); + m_currentLValue.storeValue(_unaryOperation, *_unaryOperation.getType(), !_unaryOperation.isPrefixOperation()); m_currentLValue.reset(); break; case Token::Add: // + @@ -472,6 +474,10 @@ void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess) m_context << eth::Instruction::GAS; else if (member == "gasprice") m_context << eth::Instruction::GASPRICE; + else if (member == "data") + { + // nothing to store on the stack + } else BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown magic member.")); break; @@ -1014,7 +1020,7 @@ void ExpressionCompiler::LValue::retrieveValueFromStorage(TypePointer const& _ty } } -void ExpressionCompiler::LValue::storeValue(Expression const& _expression, bool _move) const +void ExpressionCompiler::LValue::storeValue(Expression const& _expression, Type const& _sourceType, bool _move) const { switch (m_type) { @@ -1032,28 +1038,45 @@ void ExpressionCompiler::LValue::storeValue(Expression const& _expression, bool break; } case LValueType::Storage: - if (!_expression.getType()->isValueType()) - break; // no distinction between value and reference for non-value types // stack layout: value value ... value ref - if (!_move) // copy values + if (_expression.getType()->isValueType()) { - if (m_size + 1 > 16) - BOOST_THROW_EXCEPTION(CompilerError() << errinfo_sourceLocation(_expression.getLocation()) - << errinfo_comment("Stack too deep.")); + if (!_move) // copy values + { + if (m_size + 1 > 16) + BOOST_THROW_EXCEPTION(CompilerError() << errinfo_sourceLocation(_expression.getLocation()) + << errinfo_comment("Stack too deep.")); + for (unsigned i = 0; i < m_size; ++i) + *m_context << eth::dupInstruction(m_size + 1) << eth::Instruction::SWAP1; + } + if (m_size > 0) // store high index value first + *m_context << u256(m_size - 1) << eth::Instruction::ADD; for (unsigned i = 0; i < m_size; ++i) - *m_context << eth::dupInstruction(m_size + 1) << eth::Instruction::SWAP1; + { + if (i + 1 >= m_size) + *m_context << eth::Instruction::SSTORE; + else + // v v ... v v r+x + *m_context << eth::Instruction::SWAP1 << eth::Instruction::DUP2 + << eth::Instruction::SSTORE + << u256(1) << eth::Instruction::SWAP1 << eth::Instruction::SUB; + } } - if (m_size > 0) // store high index value first - *m_context << u256(m_size - 1) << eth::Instruction::ADD; - for (unsigned i = 0; i < m_size; ++i) + else { - if (i + 1 >= m_size) - *m_context << eth::Instruction::SSTORE; + solAssert(!_move, "Move assign for non-value types not implemented."); + solAssert(_sourceType.getCategory() == _expression.getType()->getCategory(), ""); + if (_expression.getType()->getCategory() == Type::Category::ByteArray) + copyByteArrayToStorage(dynamic_cast(*_expression.getType()), + dynamic_cast(_sourceType)); + else if (_expression.getType()->getCategory() == Type::Category::Struct) + { + //@todo + solAssert(false, "Struct copy not yet implemented."); + } else - // v v ... v v r+x - *m_context << eth::Instruction::SWAP1 << eth::Instruction::DUP2 - << eth::Instruction::SSTORE - << u256(1) << eth::Instruction::SWAP1 << eth::Instruction::SUB; + BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_sourceLocation(_expression.getLocation()) + << errinfo_comment("Invalid non-value type for assignment.")); } break; case LValueType::Memory: @@ -1145,5 +1168,60 @@ void ExpressionCompiler::LValue::fromIdentifier(Identifier const& _identifier, D << errinfo_comment("Identifier type not supported or identifier not found.")); } +void ExpressionCompiler::LValue::copyByteArrayToStorage(ByteArrayType const& _targetType, + ByteArrayType const& _sourceType) const +{ + // stack layout: [source_ref] target_ref (head) + // need to leave target_ref on the stack at the end + solAssert(m_type == LValueType::Storage, ""); + solAssert(_targetType.getLocation() == ByteArrayType::Location::Storage, ""); + switch (_sourceType.getLocation()) + { + case ByteArrayType::Location::CallData: + { + // @todo this does not take length into account. It also assumes that after "CALLDATALENGTH" we only have zeros. + // add some useful constants + *m_context << u256(32) << u256(1); + // stack here: target_ref 32 1 + // store length (in bytes) + if (_sourceType.getOffset() == 0) + *m_context << eth::Instruction::CALLDATASIZE; + else + *m_context << _sourceType.getOffset() << eth::Instruction::CALLDATASIZE << eth::Instruction::SUB; + *m_context << eth::Instruction::DUP1 << eth::Instruction::DUP5 << eth::Instruction::SSTORE; + // jump to end if length is zero + *m_context << eth::Instruction::ISZERO; + eth::AssemblyItem loopEnd = m_context->newTag(); + m_context->appendConditionalJumpTo(loopEnd); + // actual array data is stored at SHA3(storage_offset) + *m_context << eth::Instruction::DUP3; + CompilerUtils(*m_context).storeInMemory(0); + *m_context << u256(32) << u256(0) << eth::Instruction::SHA3; + + *m_context << _sourceType.getOffset(); + // stack now: target_ref 32 1 target_data_ref calldata_offset + eth::AssemblyItem loopStart = m_context->newTag(); + *m_context << loopStart + // copy from calldata and store + << eth::Instruction::DUP1 << eth::Instruction::CALLDATALOAD + << eth::Instruction::DUP3 << eth::Instruction::SSTORE + // increment target_data_ref by 1 + << eth::Instruction::SWAP1 << eth::Instruction::DUP3 << eth::Instruction::ADD + // increment calldata_offset by 32 + << eth::Instruction::SWAP1 << eth::Instruction::DUP4 << eth::Instruction::ADD + // check for loop condition + << eth::Instruction::DUP1 << eth::Instruction::CALLDATASIZE << eth::Instruction::GT; + m_context->appendConditionalJumpTo(loopStart); + *m_context << eth::Instruction::POP << eth::Instruction::POP; + *m_context << loopEnd << eth::Instruction::POP << eth::Instruction::POP; + break; + } + case ByteArrayType::Location::Storage: + break; + default: + solAssert(false, "Byte array location not implemented."); + } +} + } } diff --git a/libsolidity/ExpressionCompiler.h b/libsolidity/ExpressionCompiler.h index 3c94d74c2..bd45e067d 100644 --- a/libsolidity/ExpressionCompiler.h +++ b/libsolidity/ExpressionCompiler.h @@ -148,7 +148,8 @@ private: /// be on the top of the stack, if any) in the lvalue and removes the reference. /// Also removes the stored value from the stack if @a _move is /// true. @a _expression is the current expression, used for error reporting. - void storeValue(Expression const& _expression, bool _move = false) const; + /// @a _sourceType is the type of the expression that is assigned. + void storeValue(Expression const& _expression, Type const& _sourceType, bool _move = false) const; /// Stores zero in the lvalue. /// @a _expression is the current expression, used for error reporting. void setToZero(Expression const& _expression) const; @@ -159,6 +160,8 @@ private: private: /// Convenience function to retrieve Value from Storage. Specific version of @ref retrieveValue void retrieveValueFromStorage(TypePointer const& _type, bool _remove = false) const; + /// Copies from a byte array to a byte array in storage, both references on the stack. + void copyByteArrayToStorage(ByteArrayType const& _targetType, ByteArrayType const& _sourceType) const; CompilerContext* m_context; LValueType m_type = LValueType::None; diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index 9faa3f3c0..16674742e 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -518,6 +518,13 @@ bool ByteArrayType::isImplicitlyConvertibleTo(const Type& _convertTo) const return (m_dynamicLength == other.m_dynamicLength || m_length == other.m_length); } +TypePointer ByteArrayType::unaryOperatorResult(Token::Value _operator) const +{ + if (_operator == Token::Delete) + return make_shared(); + return TypePointer(); +} + bool ByteArrayType::operator==(Type const& _other) const { if (_other.getCategory() != getCategory()) @@ -527,6 +534,14 @@ bool ByteArrayType::operator==(Type const& _other) const && other.m_length == m_length && other.m_offset == m_offset; } +unsigned ByteArrayType::getSizeOnStack() const +{ + if (m_location == Location::CallData) + return 0; + else + return 1; +} + bool ContractType::operator==(Type const& _other) const { if (_other.getCategory() != getCategory()) @@ -963,8 +978,7 @@ MagicType::MagicType(MagicType::Kind _kind): m_members = MemberList({{"sender", make_shared(0, IntegerType::Modifier::Address)}, {"gas", make_shared(256)}, {"value", make_shared(256)}, - {"data", make_shared(ByteArrayType::Location::CallData, - 0, 0, true)}}); + {"data", make_shared(ByteArrayType::Location::CallData)}}); break; case Kind::Transaction: m_members = MemberList({{"origin", make_shared(0, IntegerType::Modifier::Address)}, diff --git a/libsolidity/Types.h b/libsolidity/Types.h index ddcfad9ed..a23790fa2 100644 --- a/libsolidity/Types.h +++ b/libsolidity/Types.h @@ -285,13 +285,20 @@ public: enum class Location { Storage, CallData, Memory }; virtual Category getCategory() const override { return Category::ByteArray; } - ByteArrayType(Location _location, u256 const& _offset, u256 const& _length, bool _dynamicLength): + explicit ByteArrayType(Location _location, u256 const& _offset = 0, u256 const& _length = 0, + bool _dynamicLength = false): m_location(_location), m_offset(_offset), m_length(_length), m_dynamicLength(_dynamicLength) {} virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override; + virtual TypePointer unaryOperatorResult(Token::Value _operator) const override; virtual bool operator==(const Type& _other) const override; - virtual unsigned getSizeOnStack() const override { return 1; /* TODO */ } + virtual unsigned getSizeOnStack() const override; virtual std::string toString() const override { return "bytes"; } + Location getLocation() const { return m_location; } + u256 const& getOffset() const { return m_offset; } + u256 const& getLength() const { return m_length; } + bool hasDynamicLength() const { return m_dynamicLength; } + private: Location m_location; u256 m_offset; diff --git a/test/SolidityEndToEndTest.cpp b/test/SolidityEndToEndTest.cpp index 054b0c6a4..ecf7ba8a5 100644 --- a/test/SolidityEndToEndTest.cpp +++ b/test/SolidityEndToEndTest.cpp @@ -2254,7 +2254,26 @@ BOOST_AUTO_TEST_CASE(generic_call) BOOST_CHECK_EQUAL(m_state.balance(m_contractAddress), 50 - 2); } -BOOST_AUTO_TEST_CASE(storing_bytes) +BOOST_AUTO_TEST_CASE(store_bytes) +{ + // this test just checks that the copy loop does not mess up the stack + char const* sourceCode = R"( + contract C { + function save() returns (uint r) { + r = 23; + savedData = msg.data; + r = 24; + } + bytes savedData; + } + )"; + compileAndRun(sourceCode); + // empty copy loop + BOOST_CHECK(callContractFunction("save()") == encodeArgs(24)); + BOOST_CHECK(callContractFunction("save()", "abcdefg") == encodeArgs(24)); +} + +BOOST_AUTO_TEST_CASE(call_forward_bytes) { char const* sourceCode = R"( contract C { @@ -2267,16 +2286,56 @@ BOOST_AUTO_TEST_CASE(storing_bytes) function clear() { delete savedData; } - function doubleIt(uint a) returns (uint b) { return a * 2; } + function doubleIt(uint a) { val += a * 2; } bytes savedData; + uint public val; } )"; compileAndRun(sourceCode); FixedHash<4> innerHash(dev::sha3("doubleIt(uint256)")); BOOST_CHECK(callContractFunction("save()", innerHash.asBytes(), 7) == bytes()); - BOOST_CHECK(callContractFunction("forward()") == encodeArgs(14)); + BOOST_CHECK(callContractFunction("val()") == bytes(0)); + BOOST_CHECK(callContractFunction("forward()") == bytes()); + BOOST_CHECK(callContractFunction("val()") == bytes(14)); BOOST_CHECK(callContractFunction("clear()") == bytes()); + BOOST_CHECK(callContractFunction("val()") == bytes(14)); BOOST_CHECK(callContractFunction("forward()") == bytes()); + BOOST_CHECK(callContractFunction("val()") == bytes(14)); +} + +BOOST_AUTO_TEST_CASE(copying_bytes_multiassign) +{ + char const* sourceCode = R"( + contract C { + function save() { + data1 = data2 = msg.data; + } + function forward(bool selector) { + if (selector) + { + this.call(data1); + delete data1; + } + else + { + this.call(data2); + delete data2; + } + } + function doubleIt(uint a) returns (uint b) { val += a * 2; } + bytes data1; + bytes data2; + uint public val; + } + )"; + compileAndRun(sourceCode); + FixedHash<4> innerHash(dev::sha3("doubleIt(uint256)")); + BOOST_CHECK(callContractFunction("save()", innerHash.asBytes(), 7) == bytes()); + BOOST_CHECK(callContractFunction("val()") == bytes(0)); + BOOST_CHECK(callContractFunction("forward(bool)", true) == bytes()); + BOOST_CHECK(callContractFunction("val()") == bytes(14)); + BOOST_CHECK(callContractFunction("forward(bool)", false) == bytes()); + BOOST_CHECK(callContractFunction("val()") == bytes(28)); } BOOST_AUTO_TEST_SUITE_END() From 9be8307f22bc01a90479dc29706147cef8624e89 Mon Sep 17 00:00:00 2001 From: Christian Date: Tue, 10 Feb 2015 17:53:43 +0100 Subject: [PATCH 106/213] Dynamic copy to memory. --- libsolidity/Compiler.cpp | 7 +- libsolidity/CompilerUtils.cpp | 41 +++++--- libsolidity/CompilerUtils.h | 12 ++- libsolidity/ExpressionCompiler.cpp | 146 +++++++++++++++++------------ libsolidity/ExpressionCompiler.h | 27 +++--- libsolidity/Types.cpp | 31 +++--- libsolidity/Types.h | 1 + test/SolidityEndToEndTest.cpp | 86 +++++++++-------- 8 files changed, 200 insertions(+), 151 deletions(-) diff --git a/libsolidity/Compiler.cpp b/libsolidity/Compiler.cpp index b36153677..dad79bb06 100644 --- a/libsolidity/Compiler.cpp +++ b/libsolidity/Compiler.cpp @@ -207,15 +207,10 @@ void Compiler::appendReturnValuePacker(TypePointers const& _typeParameters) for (TypePointer const& type: _typeParameters) { - unsigned numBytes = type->getCalldataEncodedSize(); - if (numBytes > 32) - BOOST_THROW_EXCEPTION(CompilerError() - << errinfo_comment("Type " + type->toString() + " not yet supported.")); CompilerUtils(m_context).copyToStackTop(stackDepth, *type); ExpressionCompiler::appendTypeConversion(m_context, *type, *type, true); - bool const c_leftAligned = type->getCategory() == Type::Category::String; bool const c_padToWords = true; - dataOffset += CompilerUtils(m_context).storeInMemory(dataOffset, numBytes, c_leftAligned, c_padToWords); + dataOffset += CompilerUtils(m_context).storeInMemory(dataOffset, *type, c_padToWords); stackDepth -= type->getSizeOnStack(); } // note that the stack is not cleaned up here diff --git a/libsolidity/CompilerUtils.cpp b/libsolidity/CompilerUtils.cpp index 3101c1b44..129403678 100644 --- a/libsolidity/CompilerUtils.cpp +++ b/libsolidity/CompilerUtils.cpp @@ -62,20 +62,22 @@ unsigned CompilerUtils::loadFromMemory(unsigned _offset, unsigned _bytes, bool _ } } -unsigned CompilerUtils::storeInMemory(unsigned _offset, unsigned _bytes, bool _leftAligned, - bool _padToWordBoundaries) +unsigned CompilerUtils::storeInMemory(unsigned _offset, Type const& _type, bool _padToWordBoundaries) { - if (_bytes == 0) + unsigned numBytes = prepareMemoryStore(_type, _padToWordBoundaries); + if (numBytes > 0) + m_context << u256(_offset) << eth::Instruction::MSTORE; + return numBytes; +} + +void CompilerUtils::storeInMemoryDynamic(Type const& _type, bool _padToWordBoundaries) +{ + unsigned numBytes = prepareMemoryStore(_type, _padToWordBoundaries); + if (numBytes > 0) { - m_context << eth::Instruction::POP; - return 0; + m_context << eth::Instruction::DUP2 << eth::Instruction::MSTORE; + m_context << u256(numBytes) << eth::Instruction::ADD; } - solAssert(_bytes <= 32, "Memory store of more than 32 bytes requested."); - if (_bytes != 32 && !_leftAligned && !_padToWordBoundaries) - // shift the value accordingly before storing - m_context << (u256(1) << ((32 - _bytes) * 8)) << eth::Instruction::MUL; - m_context << u256(_offset) << eth::Instruction::MSTORE; - return _padToWordBoundaries ? 32 : _bytes; } void CompilerUtils::moveToStackVariable(VariableDeclaration const& _variable) @@ -114,5 +116,22 @@ unsigned CompilerUtils::getSizeOnStack(vector> const& _va return size; } +unsigned CompilerUtils::prepareMemoryStore(Type const& _type, bool _padToWordBoundaries) +{ + unsigned _encodedSize = _type.getCalldataEncodedSize(); + unsigned numBytes = _padToWordBoundaries ? getPaddedSize(_encodedSize) : _encodedSize; + bool leftAligned = _type.getCategory() == Type::Category::String; + if (numBytes == 0) + m_context << eth::Instruction::POP; + else + { + solAssert(numBytes <= 32, "Memory store of more than 32 bytes requested."); + if (numBytes != 32 && !leftAligned && !_padToWordBoundaries) + // shift the value accordingly before storing + m_context << (u256(1) << ((32 - numBytes) * 8)) << eth::Instruction::MUL; + } + return numBytes; +} + } } diff --git a/libsolidity/CompilerUtils.h b/libsolidity/CompilerUtils.h index b5a695282..e591e9a71 100644 --- a/libsolidity/CompilerUtils.h +++ b/libsolidity/CompilerUtils.h @@ -47,13 +47,14 @@ public: bool _fromCalldata = false, bool _padToWordBoundaries = false); /// Stores data from stack in memory. /// @param _offset offset in memory - /// @param _bytes number of bytes to store - /// @param _leftAligned if true, data is left aligned on stack (otherwise right aligned) + /// @param _type type of the data on the stack /// @param _padToWordBoundaries if true, pad the data to word (32 byte) boundaries /// @returns the number of bytes written to memory (can be different from _bytes if /// _padToWordBoundaries is true) - unsigned storeInMemory(unsigned _offset, unsigned _bytes = 32, bool _leftAligned = false, - bool _padToWordBoundaries = false); + unsigned storeInMemory(unsigned _offset, Type const& _type = IntegerType(256), bool _padToWordBoundaries = false); + /// Dynamic version of @see storeInMemory, expects the memory offset below the value on the stack + /// and also updates that. + void storeInMemoryDynamic(Type const& _type, bool _padToWordBoundaries = true); /// @returns _size rounded up to the next multiple of 32 (the number of bytes occupied in the /// padded calldata) static unsigned getPaddedSize(unsigned _size) { return ((_size + 31) / 32) * 32; } @@ -72,7 +73,10 @@ public: /// Bytes we need to the start of call data. /// - The size in bytes of the function (hash) identifier. static const unsigned int dataStartOffset; + private: + unsigned prepareMemoryStore(Type const& _type, bool _padToWordBoundaries); + CompilerContext& m_context; }; diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index 8c9028e45..363d1d4b2 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -276,10 +276,10 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) //@todo copy to memory position 0, shift as soon as we use memory m_context << u256(0) << eth::Instruction::CODECOPY; - unsigned length = bytecode.size(); - length += appendArgumentsCopyToMemory(arguments, function.getParameterTypes(), length); + m_context << u256(bytecode.size()); + appendArgumentsCopyToMemory(arguments, function.getParameterTypes()); // size, offset, endowment - m_context << u256(length) << u256(0); + m_context << u256(0); if (function.valueSet()) m_context << eth::dupInstruction(3); else @@ -329,8 +329,9 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) break; case Location::SHA3: { - unsigned length = appendArgumentsCopyToMemory(arguments, TypePointers(), 0, function.padArguments()); - m_context << u256(length) << u256(0) << eth::Instruction::SHA3; + m_context << u256(0); + appendArgumentsCopyToMemory(arguments, TypePointers(), function.padArguments()); + m_context << u256(0) << eth::Instruction::SHA3; break; } case Location::Log0: @@ -345,23 +346,16 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) arguments[arg]->accept(*this); appendTypeConversion(*arguments[arg]->getType(), *function.getParameterTypes()[arg], true); } - unsigned length = appendExpressionCopyToMemory(*function.getParameterTypes().front(), - *arguments.front()); - solAssert(length == 32, "Log data should be 32 bytes long (for now)."); - m_context << u256(length) << u256(0) << eth::logInstruction(logNumber); + m_context << u256(0); + appendExpressionCopyToMemory(*function.getParameterTypes().front(), *arguments.front()); + m_context << u256(0) << eth::logInstruction(logNumber); break; } case Location::Event: { _functionCall.getExpression().accept(*this); auto const& event = dynamic_cast(function.getDeclaration()); - // Copy all non-indexed arguments to memory (data) unsigned numIndexed = 0; - unsigned memLength = 0; - for (unsigned arg = 0; arg < arguments.size(); ++arg) - if (!event.getParameters()[arg]->isIndexed()) - memLength += appendExpressionCopyToMemory(*function.getParameterTypes()[arg], - *arguments[arg], memLength); // All indexed arguments go to the stack for (unsigned arg = arguments.size(); arg > 0; --arg) if (event.getParameters()[arg - 1]->isIndexed()) @@ -374,7 +368,12 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) m_context << u256(h256::Arith(dev::sha3(function.getCanonicalSignature(event.getName())))); ++numIndexed; solAssert(numIndexed <= 4, "Too many indexed arguments."); - m_context << u256(memLength) << u256(0) << eth::logInstruction(numIndexed); + // Copy all non-indexed arguments to memory (data) + m_context << u256(0); + for (unsigned arg = 0; arg < arguments.size(); ++arg) + if (!event.getParameters()[arg]->isIndexed()) + appendExpressionCopyToMemory(*function.getParameterTypes()[arg], *arguments[arg]); + m_context << u256(0) << eth::logInstruction(numIndexed); break; } case Location::BlockHash: @@ -514,12 +513,16 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess) { _indexAccess.getBaseExpression().accept(*this); - TypePointer const& keyType = dynamic_cast(*_indexAccess.getBaseExpression().getType()).getKeyType(); - unsigned length = appendExpressionCopyToMemory(*keyType, _indexAccess.getIndexExpression()); - solAssert(length == 32, "Mapping key has to take 32 bytes in memory (for now)."); - // @todo move this once we actually use memory - length += CompilerUtils(m_context).storeInMemory(length); - m_context << u256(length) << u256(0) << eth::Instruction::SHA3; + Type const& baseType = *_indexAccess.getBaseExpression().getType(); + solAssert(baseType.getCategory() == Type::Category::Mapping, ""); + Type const& keyType = *dynamic_cast(baseType).getKeyType(); + m_context << u256(0); + appendExpressionCopyToMemory(keyType, _indexAccess.getIndexExpression()); + solAssert(baseType.getSizeOnStack() == 1, + "Unexpected: Not exactly one stack slot taken by subscriptable expression."); + m_context << eth::Instruction::SWAP1; + appendTypeMoveToMemory(IntegerType(256)); + m_context << u256(0) << eth::Instruction::SHA3; m_currentLValue = LValue(m_context, LValue::LValueType::Storage, *_indexAccess.getType()); m_currentLValue.retrieveValueIfLValueNotRequested(_indexAccess); @@ -810,26 +813,30 @@ void ExpressionCompiler::appendExternalFunctionCall(FunctionType const& _functio unsigned gasStackPos = m_context.currentToBaseStackOffset(gasValueSize); unsigned valueStackPos = m_context.currentToBaseStackOffset(1); - if (!bare) + //@todo only return the first return value for now + Type const* firstType = _functionType.getReturnParameterTypes().empty() ? nullptr : + _functionType.getReturnParameterTypes().front().get(); + unsigned retSize = firstType ? CompilerUtils::getPaddedSize(firstType->getCalldataEncodedSize()) : 0; + m_context << u256(retSize) << u256(0); + + if (bare) + m_context << u256(0); + else { // copy function identifier - m_context << eth::dupInstruction(gasValueSize + 1); - CompilerUtils(m_context).storeInMemory(0, CompilerUtils::dataStartOffset); + m_context << eth::dupInstruction(gasValueSize + 3); + CompilerUtils(m_context).storeInMemory(0, IntegerType(CompilerUtils::dataStartOffset * 8)); + m_context << u256(CompilerUtils::dataStartOffset); } - // reserve space for the function identifier - unsigned dataOffset = bare ? 0 : CompilerUtils::dataStartOffset; // For bare call, activate "4 byte pad exception": If the first argument has exactly 4 bytes, // do not pad it to 32 bytes. - dataOffset += appendArgumentsCopyToMemory(_arguments, _functionType.getParameterTypes(), dataOffset, - _functionType.padArguments(), bare); + appendArgumentsCopyToMemory(_arguments, _functionType.getParameterTypes(), + _functionType.padArguments(), bare); - //@todo only return the first return value for now - Type const* firstType = _functionType.getReturnParameterTypes().empty() ? nullptr : - _functionType.getReturnParameterTypes().front().get(); - unsigned retSize = firstType ? CompilerUtils::getPaddedSize(firstType->getCalldataEncodedSize()) : 0; - // CALL arguments: outSize, outOff, inSize, inOff, value, addr, gas (stack top) - m_context << u256(retSize) << u256(0) << u256(dataOffset) << u256(0); + // CALL arguments: outSize, outOff, inSize, (already present up to here) + // inOff, value, addr, gas (stack top) + m_context << u256(0); if (_functionType.valueSet()) m_context << eth::dupInstruction(m_context.baseToCurrentStackOffset(valueStackPos)); else @@ -858,14 +865,12 @@ void ExpressionCompiler::appendExternalFunctionCall(FunctionType const& _functio } } -unsigned ExpressionCompiler::appendArgumentsCopyToMemory(vector> const& _arguments, - TypePointers const& _types, - unsigned _memoryOffset, - bool _padToWordBoundaries, - bool _padExceptionIfFourBytes) +void ExpressionCompiler::appendArgumentsCopyToMemory(vector> const& _arguments, + TypePointers const& _types, + bool _padToWordBoundaries, + bool _padExceptionIfFourBytes) { solAssert(_types.empty() || _types.size() == _arguments.size(), ""); - unsigned length = 0; for (size_t i = 0; i < _arguments.size(); ++i) { _arguments[i]->accept(*this); @@ -875,31 +880,55 @@ unsigned ExpressionCompiler::appendArgumentsCopyToMemory(vectorgetCalldataEncodedSize() == 4) pad = false; - length += appendTypeMoveToMemory(*expectedType, _arguments[i]->getLocation(), - _memoryOffset + length, pad); + appendTypeMoveToMemory(*expectedType, pad); } - return length; } -unsigned ExpressionCompiler::appendTypeMoveToMemory(Type const& _type, Location const& _location, unsigned _memoryOffset, bool _padToWordBoundaries) +void ExpressionCompiler::appendTypeMoveToMemory(Type const& _type, bool _padToWordBoundaries) { - unsigned const c_encodedSize = _type.getCalldataEncodedSize(); - unsigned const c_numBytes = _padToWordBoundaries ? CompilerUtils::getPaddedSize(c_encodedSize) : c_encodedSize; - if (c_numBytes == 0 || c_numBytes > 32) - BOOST_THROW_EXCEPTION(CompilerError() - << errinfo_sourceLocation(_location) - << errinfo_comment("Type " + _type.toString() + " not yet supported.")); - bool const c_leftAligned = _type.getCategory() == Type::Category::String; - return CompilerUtils(m_context).storeInMemory(_memoryOffset, c_numBytes, c_leftAligned, _padToWordBoundaries); + if (_type.getCategory() == Type::Category::ByteArray) + { + auto const& type = dynamic_cast(_type); + solAssert(type.getLocation() == ByteArrayType::Location::Storage, "Non-storage byte arrays not yet implemented."); + + m_context << eth::Instruction::DUP1 << eth::Instruction::SLOAD; + // stack here: memory_offset storage_offset length_bytes + // jump to end if length is zero + m_context << eth::Instruction::DUP1 << eth::Instruction::ISZERO; + eth::AssemblyItem loopEnd = m_context.newTag(); + m_context.appendConditionalJumpTo(loopEnd); + // compute memory end offset + m_context << eth::Instruction::DUP3 << eth::Instruction::ADD << eth::Instruction::SWAP2; + // actual array data is stored at SHA3(storage_offset) + m_context << eth::Instruction::SWAP1; + CompilerUtils(m_context).storeInMemory(0); + m_context << u256(32) << u256(0) << eth::Instruction::SHA3 + << eth::Instruction::SWAP1; + + // stack here: memory_end_offset storage_data_offset memory_offset + eth::AssemblyItem loopStart = m_context.newTag(); + m_context << loopStart + // load and store + << eth::Instruction::DUP2 << eth::Instruction::SLOAD + << eth::Instruction::DUP2 << eth::Instruction::MSTORE + // increment storage_data_offset by 1 + << eth::Instruction::SWAP1 << u256(1) << eth::Instruction::ADD + // increment memory offset by 32 + << eth::Instruction::SWAP1 << u256(32) << eth::Instruction::ADD + // check for loop condition + << eth::Instruction::DUP1 << eth::Instruction::DUP4 << eth::Instruction::GT; + m_context.appendConditionalJumpTo(loopStart); + m_context << loopEnd << eth::Instruction::POP << eth::Instruction::POP; + } + else + CompilerUtils(m_context).storeInMemoryDynamic(_type, _padToWordBoundaries); } -unsigned ExpressionCompiler::appendExpressionCopyToMemory(Type const& _expectedType, - Expression const& _expression, - unsigned _memoryOffset) +void ExpressionCompiler::appendExpressionCopyToMemory(Type const& _expectedType, Expression const& _expression) { _expression.accept(*this); appendTypeConversion(*_expression.getType(), _expectedType, true); - return appendTypeMoveToMemory(_expectedType, _expression.getLocation(), _memoryOffset); + appendTypeMoveToMemory(_expectedType); } void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const& _varDecl) @@ -910,7 +939,7 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const& TypePointers const& paramTypes = accessorType.getParameterTypes(); // move arguments to memory for (TypePointer const& paramType: boost::adaptors::reverse(paramTypes)) - length += appendTypeMoveToMemory(*paramType, Location(), length); + length += CompilerUtils(m_context).storeInMemory(length, *paramType, true); // retrieve the position of the variable m_context << m_context.getStorageLocationOfVariable(_varDecl); @@ -1217,6 +1246,7 @@ void ExpressionCompiler::LValue::copyByteArrayToStorage(ByteArrayType const& _ta break; } case ByteArrayType::Location::Storage: + solAssert(false, "Not Yet implemented."); break; default: solAssert(false, "Byte array location not implemented."); diff --git a/libsolidity/ExpressionCompiler.h b/libsolidity/ExpressionCompiler.h index bd45e067d..dd26881fd 100644 --- a/libsolidity/ExpressionCompiler.h +++ b/libsolidity/ExpressionCompiler.h @@ -92,21 +92,18 @@ private: /// Appends code to call a function of the given type with the given arguments. void appendExternalFunctionCall(FunctionType const& _functionType, std::vector> const& _arguments, bool bare = false); - /// Appends code that evaluates the given arguments and moves the result to memory (with optional offset). - /// @returns the number of bytes moved to memory - unsigned appendArgumentsCopyToMemory(std::vector> const& _arguments, - TypePointers const& _types = {}, - unsigned _memoryOffset = 0, - bool _padToWordBoundaries = true, - bool _padExceptionIfFourBytes = false); - /// Appends code that moves a stack element of the given type to memory - /// @returns the number of bytes moved to memory - unsigned appendTypeMoveToMemory(Type const& _type, Location const& _location, unsigned _memoryOffset, - bool _padToWordBoundaries = true); - /// Appends code that evaluates a single expression and moves the result to memory (with optional offset). - /// @returns the number of bytes moved to memory - unsigned appendExpressionCopyToMemory(Type const& _expectedType, Expression const& _expression, - unsigned _memoryOffset = 0); + /// Appends code that evaluates the given arguments and moves the result to memory. The memory offset is + /// expected to be on the stack and is updated by this call. + void appendArgumentsCopyToMemory(std::vector> const& _arguments, + TypePointers const& _types = {}, + bool _padToWordBoundaries = true, + bool _padExceptionIfFourBytes = false); + /// Appends code that moves a stack element of the given type to memory. The memory offset is + /// expected below the stack element and is updated by this call. + void appendTypeMoveToMemory(Type const& _type, bool _padToWordBoundaries = true); + /// Appends code that evaluates a single expression and moves the result to memory. The memory offset is + /// expected to be on the stack and is updated by this call. + void appendExpressionCopyToMemory(Type const& _expectedType, Expression const& _expression); /// Appends code for a State Variable accessor function void appendStateVariableAccessor(VariableDeclaration const& _varDecl); diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index 16674742e..f43a3ffe3 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -35,7 +35,7 @@ namespace dev namespace solidity { -shared_ptr Type::fromElementaryTypeName(Token::Value _typeToken) +TypePointer Type::fromElementaryTypeName(Token::Value _typeToken) { solAssert(Token::isElementaryTypeName(_typeToken), "Elementary type name expected."); @@ -64,7 +64,12 @@ shared_ptr Type::fromElementaryTypeName(Token::Value _typeToken) std::string(Token::toString(_typeToken)) + " to type.")); } -shared_ptr Type::fromUserDefinedTypeName(UserDefinedTypeName const& _typeName) +TypePointer Type::fromElementaryTypeName(string const& _name) +{ + return fromElementaryTypeName(Token::fromIdentifierOrKeyword(_name)); +} + +TypePointer Type::fromUserDefinedTypeName(UserDefinedTypeName const& _typeName) { Declaration const* declaration = _typeName.getReferencedDeclaration(); if (StructDefinition const* structDef = dynamic_cast(declaration)) @@ -73,21 +78,21 @@ shared_ptr Type::fromUserDefinedTypeName(UserDefinedTypeName const& return make_shared(*function); else if (ContractDefinition const* contract = dynamic_cast(declaration)) return make_shared(*contract); - return shared_ptr(); + return TypePointer(); } -shared_ptr Type::fromMapping(Mapping const& _typeName) +TypePointer Type::fromMapping(Mapping const& _typeName) { - shared_ptr keyType = _typeName.getKeyType().toType(); + TypePointer keyType = _typeName.getKeyType().toType(); if (!keyType) BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Error resolving type name.")); - shared_ptr valueType = _typeName.getValueType().toType(); + TypePointer valueType = _typeName.getValueType().toType(); if (!valueType) BOOST_THROW_EXCEPTION(_typeName.getValueType().createTypeError("Invalid type name")); return make_shared(keyType, valueType); } -shared_ptr Type::forLiteral(Literal const& _literal) +TypePointer Type::forLiteral(Literal const& _literal) { switch (_literal.getToken()) { @@ -561,8 +566,8 @@ MemberList const& ContractType::getMembers() const if (!m_members) { // All address members and all interface functions - map> members(IntegerType::AddressMemberList.begin(), - IntegerType::AddressMemberList.end()); + map members(IntegerType::AddressMemberList.begin(), + IntegerType::AddressMemberList.end()); if (m_super) { for (ContractDefinition const* base: m_contract.getLinearizedBaseContracts()) @@ -617,14 +622,14 @@ bool StructType::operator==(Type const& _other) const u256 StructType::getStorageSize() const { u256 size = 0; - for (pair> const& member: getMembers()) + for (pair const& member: getMembers()) size += member.second->getStorageSize(); return max(1, size); } bool StructType::canLiveOutsideStorage() const { - for (pair> const& member: getMembers()) + for (pair const& member: getMembers()) if (!member.second->canLiveOutsideStorage()) return false; return true; @@ -640,7 +645,7 @@ MemberList const& StructType::getMembers() const // We need to lazy-initialize it because of recursive references. if (!m_members) { - map> members; + map members; for (ASTPointer const& variable: m_struct.getMembers()) members[variable->getName()] = variable->getType(); m_members.reset(new MemberList(members)); @@ -847,7 +852,7 @@ TypePointers FunctionType::parseElementaryTypeVector(strings const& _types) TypePointers pointers; pointers.reserve(_types.size()); for (string const& type: _types) - pointers.push_back(Type::fromElementaryTypeName(Token::fromIdentifierOrKeyword(type))); + pointers.push_back(Type::fromElementaryTypeName(type)); return pointers; } diff --git a/libsolidity/Types.h b/libsolidity/Types.h index a23790fa2..0270773fb 100644 --- a/libsolidity/Types.h +++ b/libsolidity/Types.h @@ -86,6 +86,7 @@ public: ///@name Factory functions /// Factory functions that convert an AST @ref TypeName to a Type. static TypePointer fromElementaryTypeName(Token::Value _typeToken); + static TypePointer fromElementaryTypeName(std::string const& _name); static TypePointer fromUserDefinedTypeName(UserDefinedTypeName const& _typeName); static TypePointer fromMapping(Mapping const& _typeName); static TypePointer fromFunction(FunctionDefinition const& _function); diff --git a/test/SolidityEndToEndTest.cpp b/test/SolidityEndToEndTest.cpp index ecf7ba8a5..235e535d0 100644 --- a/test/SolidityEndToEndTest.cpp +++ b/test/SolidityEndToEndTest.cpp @@ -668,7 +668,7 @@ BOOST_AUTO_TEST_CASE(mapping_state) testSolidityAgainstCpp("getVoteCount(address)", getVoteCount, u160(0)); testSolidityAgainstCpp("getVoteCount(address)", getVoteCount, u160(1)); testSolidityAgainstCpp("getVoteCount(address)", getVoteCount, u160(2)); - // voting without vote right shourd be rejected + // voting without vote right should be rejected testSolidityAgainstCpp("vote(address,address)", vote, u160(0), u160(2)); testSolidityAgainstCpp("getVoteCount(address)", getVoteCount, u160(0)); testSolidityAgainstCpp("getVoteCount(address)", getVoteCount, u160(1)); @@ -2276,68 +2276,66 @@ BOOST_AUTO_TEST_CASE(store_bytes) BOOST_AUTO_TEST_CASE(call_forward_bytes) { char const* sourceCode = R"( - contract C { - function save() { - savedData = msg.data; - } - function forward() { - this.call(savedData); - } - function clear() { - delete savedData; - } - function doubleIt(uint a) { val += a * 2; } + contract receiver { + uint public received; + function receive(uint x) { received += x + 1; } + function() { received = 0x80; } + } + contract sender { + function sender() { rec = new receiver(); } + function() { savedData = msg.data; } + function forward() { rec.call(savedData); } + function clear() { delete savedData; } + function val() returns (uint) { return rec.received(); } + receiver rec; bytes savedData; - uint public val; } )"; - compileAndRun(sourceCode); - FixedHash<4> innerHash(dev::sha3("doubleIt(uint256)")); - BOOST_CHECK(callContractFunction("save()", innerHash.asBytes(), 7) == bytes()); - BOOST_CHECK(callContractFunction("val()") == bytes(0)); + compileAndRun(sourceCode, 0, "sender"); + BOOST_CHECK(callContractFunction("receive(uint256)", 7) == bytes()); + BOOST_CHECK(callContractFunction("val()") == encodeArgs(0)); BOOST_CHECK(callContractFunction("forward()") == bytes()); - BOOST_CHECK(callContractFunction("val()") == bytes(14)); + BOOST_CHECK(callContractFunction("val()") == encodeArgs(8)); BOOST_CHECK(callContractFunction("clear()") == bytes()); - BOOST_CHECK(callContractFunction("val()") == bytes(14)); + BOOST_CHECK(callContractFunction("val()") == encodeArgs(8)); BOOST_CHECK(callContractFunction("forward()") == bytes()); - BOOST_CHECK(callContractFunction("val()") == bytes(14)); + BOOST_CHECK(callContractFunction("val()") == encodeArgs(0x80)); } BOOST_AUTO_TEST_CASE(copying_bytes_multiassign) { char const* sourceCode = R"( - contract C { - function save() { - data1 = data2 = msg.data; - } + contract receiver { + uint public received; + function receive(uint x) { received += x + 1; } + function() { received = 0x80; } + } + contract sender { + function sender() { rec = new receiver(); } + function() { savedData1 = savedData2 = msg.data; } function forward(bool selector) { - if (selector) - { - this.call(data1); - delete data1; - } - else - { - this.call(data2); - delete data2; - } + if (selector) { rec.call(savedData1); delete savedData1; } + else { rec.call(savedData2); delete savedData2; } } - function doubleIt(uint a) returns (uint b) { val += a * 2; } - bytes data1; - bytes data2; - uint public val; + function val() returns (uint) { return rec.received(); } + receiver rec; + bytes savedData1; + bytes savedData2; } )"; - compileAndRun(sourceCode); - FixedHash<4> innerHash(dev::sha3("doubleIt(uint256)")); - BOOST_CHECK(callContractFunction("save()", innerHash.asBytes(), 7) == bytes()); - BOOST_CHECK(callContractFunction("val()") == bytes(0)); + compileAndRun(sourceCode, 0, "sender"); + BOOST_CHECK(callContractFunction("receive(uint256)", 7) == bytes()); + BOOST_CHECK(callContractFunction("val()") == encodeArgs(0)); BOOST_CHECK(callContractFunction("forward(bool)", true) == bytes()); - BOOST_CHECK(callContractFunction("val()") == bytes(14)); + BOOST_CHECK(callContractFunction("val()") == encodeArgs(8)); BOOST_CHECK(callContractFunction("forward(bool)", false) == bytes()); - BOOST_CHECK(callContractFunction("val()") == bytes(28)); + BOOST_CHECK(callContractFunction("val()") == encodeArgs(16)); + BOOST_CHECK(callContractFunction("forward(bool)", true) == bytes()); + BOOST_CHECK(callContractFunction("val()") == encodeArgs(0x80)); } +// TODO test that "delete" also clears the values + BOOST_AUTO_TEST_SUITE_END() } From aa765180f1c7ac887941702e336d5aaa3cf5177d Mon Sep 17 00:00:00 2001 From: Christian Date: Wed, 11 Feb 2015 14:24:34 +0100 Subject: [PATCH 107/213] Copy storage to storage. --- libsolidity/CompilerUtils.cpp | 6 +++ libsolidity/CompilerUtils.h | 5 ++ libsolidity/ExpressionCompiler.cpp | 77 +++++++++++++++++++++++++++--- 3 files changed, 81 insertions(+), 7 deletions(-) diff --git a/libsolidity/CompilerUtils.cpp b/libsolidity/CompilerUtils.cpp index 129403678..c38149c14 100644 --- a/libsolidity/CompilerUtils.cpp +++ b/libsolidity/CompilerUtils.cpp @@ -116,6 +116,12 @@ unsigned CompilerUtils::getSizeOnStack(vector> const& _va return size; } +void CompilerUtils::computeHashStatic(Type const& _type, bool _padToWordBoundaries) +{ + unsigned length = storeInMemory(0, _type, _padToWordBoundaries); + m_context << u256(length) << u256(0) << eth::Instruction::SHA3; +} + unsigned CompilerUtils::prepareMemoryStore(Type const& _type, bool _padToWordBoundaries) { unsigned _encodedSize = _type.getCalldataEncodedSize(); diff --git a/libsolidity/CompilerUtils.h b/libsolidity/CompilerUtils.h index e591e9a71..493750476 100644 --- a/libsolidity/CompilerUtils.h +++ b/libsolidity/CompilerUtils.h @@ -70,6 +70,11 @@ public: static unsigned getSizeOnStack(std::vector const& _variables); static unsigned getSizeOnStack(std::vector> const& _variableTypes); + /// Appends code that computes tha SHA3 hash of the topmost stack element of type @a _type. + /// If @a _pad is set, padds the type to muliples of 32 bytes. + /// @note Only works for types of fixed size. + void computeHashStatic(Type const& _type = IntegerType(256), bool _padToWordBoundaries = false); + /// Bytes we need to the start of call data. /// - The size in bytes of the function (hash) identifier. static const unsigned int dataStartOffset; diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index 363d1d4b2..a05d71e69 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -886,6 +886,8 @@ void ExpressionCompiler::appendArgumentsCopyToMemory(vector(_type); @@ -901,9 +903,8 @@ void ExpressionCompiler::appendTypeMoveToMemory(Type const& _type, bool _padToWo m_context << eth::Instruction::DUP3 << eth::Instruction::ADD << eth::Instruction::SWAP2; // actual array data is stored at SHA3(storage_offset) m_context << eth::Instruction::SWAP1; - CompilerUtils(m_context).storeInMemory(0); - m_context << u256(32) << u256(0) << eth::Instruction::SHA3 - << eth::Instruction::SWAP1; + CompilerUtils(m_context).computeHashStatic(); + m_context << eth::Instruction::SWAP1; // stack here: memory_end_offset storage_data_offset memory_offset eth::AssemblyItem loopStart = m_context.newTag(); @@ -1204,6 +1205,9 @@ void ExpressionCompiler::LValue::copyByteArrayToStorage(ByteArrayType const& _ta // need to leave target_ref on the stack at the end solAssert(m_type == LValueType::Storage, ""); solAssert(_targetType.getLocation() == ByteArrayType::Location::Storage, ""); + + // @TODO move this to CompilerUtils! + switch (_sourceType.getLocation()) { case ByteArrayType::Location::CallData: @@ -1224,8 +1228,7 @@ void ExpressionCompiler::LValue::copyByteArrayToStorage(ByteArrayType const& _ta m_context->appendConditionalJumpTo(loopEnd); // actual array data is stored at SHA3(storage_offset) *m_context << eth::Instruction::DUP3; - CompilerUtils(*m_context).storeInMemory(0); - *m_context << u256(32) << u256(0) << eth::Instruction::SHA3; + CompilerUtils(*m_context).computeHashStatic(); *m_context << _sourceType.getOffset(); // stack now: target_ref 32 1 target_data_ref calldata_offset @@ -1246,10 +1249,70 @@ void ExpressionCompiler::LValue::copyByteArrayToStorage(ByteArrayType const& _ta break; } case ByteArrayType::Location::Storage: - solAssert(false, "Not Yet implemented."); + { + // this copies source to target and also clears target if it was larger + + // stack: source_ref target_ref + // fetch lengthes + *m_context << eth::Instruction::DUP1 << eth::Instruction::SLOAD << eth::Instruction::SWAP2 + << eth::Instruction::DUP1 << eth::Instruction::SLOAD; + // stack: target_len_bytes target_ref source_ref source_len_bytes + // store new target length + *m_context << eth::Instruction::DUP1 << eth::Instruction::DUP4 << eth::Instruction::SSTORE; + // compute hashes (data positions) + *m_context << eth::Instruction::SWAP2; + CompilerUtils(*m_context).computeHashStatic(); + *m_context << eth::Instruction::SWAP1; + CompilerUtils(*m_context).computeHashStatic(); + // stack: target_len_bytes source_len_bytes target_data_pos source_data_pos + // convert lengthes from bytes to storage slots + *m_context << u256(31) << u256(32) << eth::Instruction::DUP1 << eth::Instruction::DUP3 + << eth::Instruction::DUP8 << eth::Instruction::ADD << eth::Instruction::DIV + << eth::Instruction::SWAP2 + << eth::Instruction::DUP6 << eth::Instruction::ADD << eth::Instruction::DIV; + // stack: target_len_bytes source_len_bytes target_data_pos source_data_pos target_len source_len + // @todo we might be able to go without a third counter + *m_context << u256(0); + // stack: target_len_bytes source_len_bytes target_data_pos source_data_pos target_len source_len counter + eth::AssemblyItem copyLoopStart = m_context->newTag(); + *m_context << copyLoopStart; + // check for loop condition + *m_context << eth::Instruction::DUP1 << eth::Instruction::DUP3 + << eth::Instruction::GT << eth::Instruction::ISZERO; + eth::AssemblyItem copyLoopEnd = m_context->newTag(); + m_context->appendConditionalJumpTo(copyLoopEnd); + // copy + *m_context << eth::Instruction::DUP4 << eth::Instruction::DUP2 << eth::Instruction::ADD + << eth::Instruction::SLOAD + << eth::Instruction::DUP6 << eth::Instruction::DUP3 << eth::Instruction::ADD + << eth::Instruction::SSTORE; + // increment + *m_context << u256(1) << eth::Instruction::ADD; + m_context->appendJumpTo(copyLoopStart); + *m_context << copyLoopEnd; + // zero-out leftovers in target + eth::AssemblyItem zeroLoopStart = m_context->newTag(); + *m_context << zeroLoopStart; + // check for loop condition + *m_context << eth::Instruction::DUP1 << eth::Instruction::DUP4 + << eth::Instruction::GT << eth::Instruction::ISZERO; + eth::AssemblyItem zeroLoopEnd = m_context->newTag(); + m_context->appendConditionalJumpTo(zeroLoopEnd); + // zero out + *m_context << u256(0) + << eth::Instruction::DUP6 << eth::Instruction::DUP3 << eth::Instruction::ADD + << eth::Instruction::SSTORE; + // increment + *m_context << u256(1) << eth::Instruction::ADD; + m_context->appendJumpTo(zeroLoopStart); + // cleanup + *m_context << zeroLoopEnd; + *m_context << eth::Instruction::POP << eth::Instruction::POP << eth::Instruction::POP + << eth::Instruction::POP << eth::Instruction::POP << eth::Instruction::POP; break; + } default: - solAssert(false, "Byte array location not implemented."); + solAssert(false, "Given byte array location not implemented."); } } From 390097db535b025ce272dc72fe43782006bd3e1e Mon Sep 17 00:00:00 2001 From: Christian Date: Wed, 11 Feb 2015 14:32:46 +0100 Subject: [PATCH 108/213] Moved copy code to CompilerUtils. --- libsolidity/CompilerUtils.cpp | 213 ++++++++++++++++++++++++++++- libsolidity/CompilerUtils.h | 13 +- libsolidity/ExpressionCompiler.cpp | 186 +++---------------------- libsolidity/ExpressionCompiler.h | 2 +- test/SolidityEndToEndTest.cpp | 69 ++++++++-- test/solidityExecutionFramework.h | 2 +- 6 files changed, 298 insertions(+), 187 deletions(-) diff --git a/libsolidity/CompilerUtils.cpp b/libsolidity/CompilerUtils.cpp index c38149c14..192d66d5c 100644 --- a/libsolidity/CompilerUtils.cpp +++ b/libsolidity/CompilerUtils.cpp @@ -64,6 +64,7 @@ unsigned CompilerUtils::loadFromMemory(unsigned _offset, unsigned _bytes, bool _ unsigned CompilerUtils::storeInMemory(unsigned _offset, Type const& _type, bool _padToWordBoundaries) { + solAssert(_type.getCategory() != Type::Category::ByteArray, "Unable to statically store dynamic type."); unsigned numBytes = prepareMemoryStore(_type, _padToWordBoundaries); if (numBytes > 0) m_context << u256(_offset) << eth::Instruction::MSTORE; @@ -72,11 +73,47 @@ unsigned CompilerUtils::storeInMemory(unsigned _offset, Type const& _type, bool void CompilerUtils::storeInMemoryDynamic(Type const& _type, bool _padToWordBoundaries) { - unsigned numBytes = prepareMemoryStore(_type, _padToWordBoundaries); - if (numBytes > 0) + if (_type.getCategory() == Type::Category::ByteArray) { - m_context << eth::Instruction::DUP2 << eth::Instruction::MSTORE; - m_context << u256(numBytes) << eth::Instruction::ADD; + auto const& type = dynamic_cast(_type); + solAssert(type.getLocation() == ByteArrayType::Location::Storage, "Non-storage byte arrays not yet implemented."); + + m_context << eth::Instruction::DUP1 << eth::Instruction::SLOAD; + // stack here: memory_offset storage_offset length_bytes + // jump to end if length is zero + m_context << eth::Instruction::DUP1 << eth::Instruction::ISZERO; + eth::AssemblyItem loopEnd = m_context.newTag(); + m_context.appendConditionalJumpTo(loopEnd); + // compute memory end offset + m_context << eth::Instruction::DUP3 << eth::Instruction::ADD << eth::Instruction::SWAP2; + // actual array data is stored at SHA3(storage_offset) + m_context << eth::Instruction::SWAP1; + CompilerUtils(m_context).computeHashStatic(); + m_context << eth::Instruction::SWAP1; + + // stack here: memory_end_offset storage_data_offset memory_offset + eth::AssemblyItem loopStart = m_context.newTag(); + m_context << loopStart + // load and store + << eth::Instruction::DUP2 << eth::Instruction::SLOAD + << eth::Instruction::DUP2 << eth::Instruction::MSTORE + // increment storage_data_offset by 1 + << eth::Instruction::SWAP1 << u256(1) << eth::Instruction::ADD + // increment memory offset by 32 + << eth::Instruction::SWAP1 << u256(32) << eth::Instruction::ADD + // check for loop condition + << eth::Instruction::DUP1 << eth::Instruction::DUP4 << eth::Instruction::GT; + m_context.appendConditionalJumpTo(loopStart); + m_context << loopEnd << eth::Instruction::POP << eth::Instruction::POP; + } + else + { + unsigned numBytes = prepareMemoryStore(_type, _padToWordBoundaries); + if (numBytes > 0) + { + m_context << eth::Instruction::DUP2 << eth::Instruction::MSTORE; + m_context << u256(numBytes) << eth::Instruction::ADD; + } } } @@ -122,7 +159,153 @@ void CompilerUtils::computeHashStatic(Type const& _type, bool _padToWordBoundari m_context << u256(length) << u256(0) << eth::Instruction::SHA3; } -unsigned CompilerUtils::prepareMemoryStore(Type const& _type, bool _padToWordBoundaries) +void CompilerUtils::copyByteArrayToStorage(ByteArrayType const& _targetType, + ByteArrayType const& _sourceType) const +{ + // stack layout: [source_ref] target_ref (top) + // need to leave target_ref on the stack at the end + solAssert(_targetType.getLocation() == ByteArrayType::Location::Storage, ""); + + switch (_sourceType.getLocation()) + { + case ByteArrayType::Location::CallData: + { + // @todo this does not take length into account. It also assumes that after "CALLDATALENGTH" we only have zeros. + // fetch old length and convert to words + m_context << eth::Instruction::DUP1 << eth::Instruction::SLOAD; + m_context << u256(31) << eth::Instruction::ADD + << u256(32) << eth::Instruction::SWAP1 << eth::Instruction::DIV; + // stack here: target_ref target_length_words + // actual array data is stored at SHA3(storage_offset) + m_context << eth::Instruction::DUP2; + CompilerUtils(m_context).computeHashStatic(); + // compute target_data_end + m_context << eth::Instruction::DUP1 << eth::Instruction::SWAP2 << eth::Instruction::ADD + << eth::Instruction::SWAP1; + // stack here: target_ref target_data_end target_data_ref + // store length (in bytes) + if (_sourceType.getOffset() == 0) + m_context << eth::Instruction::CALLDATASIZE; + else + m_context << _sourceType.getOffset() << eth::Instruction::CALLDATASIZE << eth::Instruction::SUB; + m_context << eth::Instruction::DUP1 << eth::Instruction::DUP5 << eth::Instruction::SSTORE; + // jump to end if length is zero + m_context << eth::Instruction::ISZERO; + eth::AssemblyItem copyLoopEnd = m_context.newTag(); + m_context.appendConditionalJumpTo(copyLoopEnd); + + m_context << _sourceType.getOffset(); + // stack now: target_ref target_data_end target_data_ref calldata_offset + eth::AssemblyItem copyLoopStart = m_context.newTag(); + m_context << copyLoopStart + // copy from calldata and store + << eth::Instruction::DUP1 << eth::Instruction::CALLDATALOAD + << eth::Instruction::DUP3 << eth::Instruction::SSTORE + // increment target_data_ref by 1 + << eth::Instruction::SWAP1 << u256(1) << eth::Instruction::ADD + // increment calldata_offset by 32 + << eth::Instruction::SWAP1 << u256(32) << eth::Instruction::ADD + // check for loop condition + << eth::Instruction::DUP1 << eth::Instruction::CALLDATASIZE << eth::Instruction::GT; + m_context.appendConditionalJumpTo(copyLoopStart); + m_context << eth::Instruction::POP; + m_context << copyLoopEnd; + + // now clear leftover bytes of the old value + // stack now: target_ref target_data_end target_data_ref + clearStorageLoop(); + + m_context << eth::Instruction::POP; + break; + } + case ByteArrayType::Location::Storage: + { + // this copies source to target and also clears target if it was larger + + // stack: source_ref target_ref + // store target_ref + m_context << eth::Instruction::SWAP1 << eth::Instruction::DUP2; + // fetch lengthes + m_context << eth::Instruction::DUP1 << eth::Instruction::SLOAD << eth::Instruction::SWAP2 + << eth::Instruction::DUP1 << eth::Instruction::SLOAD; + // stack: target_ref target_len_bytes target_ref source_ref source_len_bytes + // store new target length + m_context << eth::Instruction::DUP1 << eth::Instruction::DUP4 << eth::Instruction::SSTORE; + // compute hashes (data positions) + m_context << eth::Instruction::SWAP2; + CompilerUtils(m_context).computeHashStatic(); + m_context << eth::Instruction::SWAP1; + CompilerUtils(m_context).computeHashStatic(); + // stack: target_ref target_len_bytes source_len_bytes target_data_pos source_data_pos + // convert lengthes from bytes to storage slots + m_context << u256(31) << u256(32) << eth::Instruction::DUP1 << eth::Instruction::DUP3 + << eth::Instruction::DUP8 << eth::Instruction::ADD << eth::Instruction::DIV + << eth::Instruction::SWAP2 + << eth::Instruction::DUP6 << eth::Instruction::ADD << eth::Instruction::DIV; + // stack: target_ref target_len_bytes source_len_bytes target_data_pos source_data_pos target_len source_len + // @todo we might be able to go without a third counter + m_context << u256(0); + // stack: target_ref target_len_bytes source_len_bytes target_data_pos source_data_pos target_len source_len counter + eth::AssemblyItem copyLoopStart = m_context.newTag(); + m_context << copyLoopStart; + // check for loop condition + m_context << eth::Instruction::DUP1 << eth::Instruction::DUP3 + << eth::Instruction::GT << eth::Instruction::ISZERO; + eth::AssemblyItem copyLoopEnd = m_context.newTag(); + m_context.appendConditionalJumpTo(copyLoopEnd); + // copy + m_context << eth::Instruction::DUP4 << eth::Instruction::DUP2 << eth::Instruction::ADD + << eth::Instruction::SLOAD + << eth::Instruction::DUP6 << eth::Instruction::DUP3 << eth::Instruction::ADD + << eth::Instruction::SSTORE; + // increment + m_context << u256(1) << eth::Instruction::ADD; + m_context.appendJumpTo(copyLoopStart); + m_context << copyLoopEnd; + + // zero-out leftovers in target + // stack: target_ref target_len_bytes source_len_bytes target_data_pos source_data_pos target_len source_len counter + // add counter to target_data_pos + m_context << eth::Instruction::DUP5 << eth::Instruction::ADD + << eth::Instruction::SWAP5 << eth::Instruction::POP; + // stack: target_ref target_len_bytes target_data_pos_updated target_data_pos source_data_pos target_len source_len + // add length to target_data_pos to get target_data_end + m_context << eth::Instruction::POP << eth::Instruction::DUP3 << eth::Instruction::ADD + << eth::Instruction::SWAP4 + << eth::Instruction::POP << eth::Instruction::POP << eth::Instruction::POP; + // stack: target_ref target_data_end target_data_pos_updated + clearStorageLoop(); + m_context << eth::Instruction::POP; + break; + } + default: + solAssert(false, "Given byte array location not implemented."); + } +} + +void CompilerUtils::clearByteArray(ByteArrayType const& _type) const +{ + solAssert(_type.getLocation() == ByteArrayType::Location::Storage, ""); + + // fetch length + m_context << eth::Instruction::DUP1 << eth::Instruction::SLOAD; + // set length to zero + m_context << u256(0) << eth::Instruction::DUP3 << eth::Instruction::SSTORE; + // convert length from bytes to storage slots + m_context << u256(31) << eth::Instruction::ADD + << u256(32) << eth::Instruction::SWAP1 << eth::Instruction::DIV; + // compute data positions + m_context << eth::Instruction::SWAP1; + CompilerUtils(m_context).computeHashStatic(); + // stack: len data_pos + m_context << eth::Instruction::SWAP1 << eth::Instruction::DUP2 << eth::Instruction::ADD + << eth::Instruction::SWAP1; + clearStorageLoop(); + // cleanup + m_context << eth::Instruction::POP; +} + +unsigned CompilerUtils::prepareMemoryStore(Type const& _type, bool _padToWordBoundaries) const { unsigned _encodedSize = _type.getCalldataEncodedSize(); unsigned numBytes = _padToWordBoundaries ? getPaddedSize(_encodedSize) : _encodedSize; @@ -139,5 +322,25 @@ unsigned CompilerUtils::prepareMemoryStore(Type const& _type, bool _padToWordBou return numBytes; } +void CompilerUtils::clearStorageLoop() const +{ + // stack: end_pos pos + eth::AssemblyItem loopStart = m_context.newTag(); + m_context << loopStart; + // check for loop condition + m_context << eth::Instruction::DUP1 << eth::Instruction::DUP3 + << eth::Instruction::GT << eth::Instruction::ISZERO; + eth::AssemblyItem zeroLoopEnd = m_context.newTag(); + m_context.appendConditionalJumpTo(zeroLoopEnd); + // zero out + m_context << u256(0) << eth::Instruction::DUP2 << eth::Instruction::SSTORE; + // increment + m_context << u256(1) << eth::Instruction::ADD; + m_context.appendJumpTo(loopStart); + // cleanup + m_context << zeroLoopEnd; + m_context << eth::Instruction::POP; +} + } } diff --git a/libsolidity/CompilerUtils.h b/libsolidity/CompilerUtils.h index 493750476..7ac3cc295 100644 --- a/libsolidity/CompilerUtils.h +++ b/libsolidity/CompilerUtils.h @@ -75,12 +75,23 @@ public: /// @note Only works for types of fixed size. void computeHashStatic(Type const& _type = IntegerType(256), bool _padToWordBoundaries = false); + /// Copies a byte array to a byte array in storage, where the target is assumed to be on the + /// to top of the stay. Leaves a reference to the target on the stack. + void copyByteArrayToStorage(ByteArrayType const& _targetType, ByteArrayType const& _sourceType) const; + /// Clears the length and data elements of the byte array referenced on the stack. + /// Removes the reference from the stack. + void clearByteArray(ByteArrayType const& _type) const; + /// Bytes we need to the start of call data. /// - The size in bytes of the function (hash) identifier. static const unsigned int dataStartOffset; private: - unsigned prepareMemoryStore(Type const& _type, bool _padToWordBoundaries); + unsigned prepareMemoryStore(Type const& _type, bool _padToWordBoundaries) const; + /// Appends a loop that clears all storage between the storage reference at the stack top + /// and the one below it (excluding). + /// Will leave the single value of the end pointer on the stack. + void clearStorageLoop() const; CompilerContext& m_context; }; diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index a05d71e69..b373bfbcb 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -105,7 +105,7 @@ bool ExpressionCompiler::visit(UnaryOperation const& _unaryOperation) break; case Token::Delete: // delete solAssert(m_currentLValue.isValid(), "LValue not retrieved."); - m_currentLValue.setToZero(_unaryOperation); + m_currentLValue.setToZero(_unaryOperation, *_unaryOperation.getSubExpression().getType()); m_currentLValue.reset(); break; case Token::Inc: // ++ (pre- or postfix) @@ -886,43 +886,7 @@ void ExpressionCompiler::appendArgumentsCopyToMemory(vector(_type); - solAssert(type.getLocation() == ByteArrayType::Location::Storage, "Non-storage byte arrays not yet implemented."); - - m_context << eth::Instruction::DUP1 << eth::Instruction::SLOAD; - // stack here: memory_offset storage_offset length_bytes - // jump to end if length is zero - m_context << eth::Instruction::DUP1 << eth::Instruction::ISZERO; - eth::AssemblyItem loopEnd = m_context.newTag(); - m_context.appendConditionalJumpTo(loopEnd); - // compute memory end offset - m_context << eth::Instruction::DUP3 << eth::Instruction::ADD << eth::Instruction::SWAP2; - // actual array data is stored at SHA3(storage_offset) - m_context << eth::Instruction::SWAP1; - CompilerUtils(m_context).computeHashStatic(); - m_context << eth::Instruction::SWAP1; - - // stack here: memory_end_offset storage_data_offset memory_offset - eth::AssemblyItem loopStart = m_context.newTag(); - m_context << loopStart - // load and store - << eth::Instruction::DUP2 << eth::Instruction::SLOAD - << eth::Instruction::DUP2 << eth::Instruction::MSTORE - // increment storage_data_offset by 1 - << eth::Instruction::SWAP1 << u256(1) << eth::Instruction::ADD - // increment memory offset by 32 - << eth::Instruction::SWAP1 << u256(32) << eth::Instruction::ADD - // check for loop condition - << eth::Instruction::DUP1 << eth::Instruction::DUP4 << eth::Instruction::GT; - m_context.appendConditionalJumpTo(loopStart); - m_context << loopEnd << eth::Instruction::POP << eth::Instruction::POP; - } - else - CompilerUtils(m_context).storeInMemoryDynamic(_type, _padToWordBoundaries); + CompilerUtils(m_context).storeInMemoryDynamic(_type, _padToWordBoundaries); } void ExpressionCompiler::appendExpressionCopyToMemory(Type const& _expectedType, Expression const& _expression) @@ -1097,8 +1061,9 @@ void ExpressionCompiler::LValue::storeValue(Expression const& _expression, Type solAssert(!_move, "Move assign for non-value types not implemented."); solAssert(_sourceType.getCategory() == _expression.getType()->getCategory(), ""); if (_expression.getType()->getCategory() == Type::Category::ByteArray) - copyByteArrayToStorage(dynamic_cast(*_expression.getType()), - dynamic_cast(_sourceType)); + CompilerUtils(*m_context).copyByteArrayToStorage( + dynamic_cast(*_expression.getType()), + dynamic_cast(_sourceType)); else if (_expression.getType()->getCategory() == Type::Category::Struct) { //@todo @@ -1122,7 +1087,7 @@ void ExpressionCompiler::LValue::storeValue(Expression const& _expression, Type } } -void ExpressionCompiler::LValue::setToZero(Expression const& _expression) const +void ExpressionCompiler::LValue::setToZero(Expression const& _expression, Type const& _type) const { switch (m_type) { @@ -1139,20 +1104,21 @@ void ExpressionCompiler::LValue::setToZero(Expression const& _expression) const break; } case LValueType::Storage: - if (m_size == 0) - *m_context << eth::Instruction::POP; - for (unsigned i = 0; i < m_size; ++i) + if (_type.getCategory() == Type::Category::ByteArray) + CompilerUtils(*m_context).clearByteArray(dynamic_cast(_type)); + else { - if (i + 1 >= m_size) - *m_context << u256(0) << eth::Instruction::SWAP1 << eth::Instruction::SSTORE; - else - *m_context << u256(0) << eth::Instruction::DUP2 << eth::Instruction::SSTORE - << u256(1) << eth::Instruction::ADD; + if (m_size == 0) + *m_context << eth::Instruction::POP; + for (unsigned i = 0; i < m_size; ++i) + if (i + 1 >= m_size) + *m_context << u256(0) << eth::Instruction::SWAP1 << eth::Instruction::SSTORE; + else + *m_context << u256(0) << eth::Instruction::DUP2 << eth::Instruction::SSTORE + << u256(1) << eth::Instruction::ADD; } break; case LValueType::Memory: - if (!_expression.getType()->isValueType()) - break; // no distinction between value and reference for non-value types BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_sourceLocation(_expression.getLocation()) << errinfo_comment("Location type not yet implemented.")); break; @@ -1161,7 +1127,6 @@ void ExpressionCompiler::LValue::setToZero(Expression const& _expression) const << errinfo_comment("Unsupported location type.")); break; } - } void ExpressionCompiler::LValue::retrieveValueIfLValueNotRequested(Expression const& _expression) @@ -1198,123 +1163,6 @@ void ExpressionCompiler::LValue::fromIdentifier(Identifier const& _identifier, D << errinfo_comment("Identifier type not supported or identifier not found.")); } -void ExpressionCompiler::LValue::copyByteArrayToStorage(ByteArrayType const& _targetType, - ByteArrayType const& _sourceType) const -{ - // stack layout: [source_ref] target_ref (head) - // need to leave target_ref on the stack at the end - solAssert(m_type == LValueType::Storage, ""); - solAssert(_targetType.getLocation() == ByteArrayType::Location::Storage, ""); - - // @TODO move this to CompilerUtils! - - switch (_sourceType.getLocation()) - { - case ByteArrayType::Location::CallData: - { - // @todo this does not take length into account. It also assumes that after "CALLDATALENGTH" we only have zeros. - // add some useful constants - *m_context << u256(32) << u256(1); - // stack here: target_ref 32 1 - // store length (in bytes) - if (_sourceType.getOffset() == 0) - *m_context << eth::Instruction::CALLDATASIZE; - else - *m_context << _sourceType.getOffset() << eth::Instruction::CALLDATASIZE << eth::Instruction::SUB; - *m_context << eth::Instruction::DUP1 << eth::Instruction::DUP5 << eth::Instruction::SSTORE; - // jump to end if length is zero - *m_context << eth::Instruction::ISZERO; - eth::AssemblyItem loopEnd = m_context->newTag(); - m_context->appendConditionalJumpTo(loopEnd); - // actual array data is stored at SHA3(storage_offset) - *m_context << eth::Instruction::DUP3; - CompilerUtils(*m_context).computeHashStatic(); - - *m_context << _sourceType.getOffset(); - // stack now: target_ref 32 1 target_data_ref calldata_offset - eth::AssemblyItem loopStart = m_context->newTag(); - *m_context << loopStart - // copy from calldata and store - << eth::Instruction::DUP1 << eth::Instruction::CALLDATALOAD - << eth::Instruction::DUP3 << eth::Instruction::SSTORE - // increment target_data_ref by 1 - << eth::Instruction::SWAP1 << eth::Instruction::DUP3 << eth::Instruction::ADD - // increment calldata_offset by 32 - << eth::Instruction::SWAP1 << eth::Instruction::DUP4 << eth::Instruction::ADD - // check for loop condition - << eth::Instruction::DUP1 << eth::Instruction::CALLDATASIZE << eth::Instruction::GT; - m_context->appendConditionalJumpTo(loopStart); - *m_context << eth::Instruction::POP << eth::Instruction::POP; - *m_context << loopEnd << eth::Instruction::POP << eth::Instruction::POP; - break; - } - case ByteArrayType::Location::Storage: - { - // this copies source to target and also clears target if it was larger - - // stack: source_ref target_ref - // fetch lengthes - *m_context << eth::Instruction::DUP1 << eth::Instruction::SLOAD << eth::Instruction::SWAP2 - << eth::Instruction::DUP1 << eth::Instruction::SLOAD; - // stack: target_len_bytes target_ref source_ref source_len_bytes - // store new target length - *m_context << eth::Instruction::DUP1 << eth::Instruction::DUP4 << eth::Instruction::SSTORE; - // compute hashes (data positions) - *m_context << eth::Instruction::SWAP2; - CompilerUtils(*m_context).computeHashStatic(); - *m_context << eth::Instruction::SWAP1; - CompilerUtils(*m_context).computeHashStatic(); - // stack: target_len_bytes source_len_bytes target_data_pos source_data_pos - // convert lengthes from bytes to storage slots - *m_context << u256(31) << u256(32) << eth::Instruction::DUP1 << eth::Instruction::DUP3 - << eth::Instruction::DUP8 << eth::Instruction::ADD << eth::Instruction::DIV - << eth::Instruction::SWAP2 - << eth::Instruction::DUP6 << eth::Instruction::ADD << eth::Instruction::DIV; - // stack: target_len_bytes source_len_bytes target_data_pos source_data_pos target_len source_len - // @todo we might be able to go without a third counter - *m_context << u256(0); - // stack: target_len_bytes source_len_bytes target_data_pos source_data_pos target_len source_len counter - eth::AssemblyItem copyLoopStart = m_context->newTag(); - *m_context << copyLoopStart; - // check for loop condition - *m_context << eth::Instruction::DUP1 << eth::Instruction::DUP3 - << eth::Instruction::GT << eth::Instruction::ISZERO; - eth::AssemblyItem copyLoopEnd = m_context->newTag(); - m_context->appendConditionalJumpTo(copyLoopEnd); - // copy - *m_context << eth::Instruction::DUP4 << eth::Instruction::DUP2 << eth::Instruction::ADD - << eth::Instruction::SLOAD - << eth::Instruction::DUP6 << eth::Instruction::DUP3 << eth::Instruction::ADD - << eth::Instruction::SSTORE; - // increment - *m_context << u256(1) << eth::Instruction::ADD; - m_context->appendJumpTo(copyLoopStart); - *m_context << copyLoopEnd; - // zero-out leftovers in target - eth::AssemblyItem zeroLoopStart = m_context->newTag(); - *m_context << zeroLoopStart; - // check for loop condition - *m_context << eth::Instruction::DUP1 << eth::Instruction::DUP4 - << eth::Instruction::GT << eth::Instruction::ISZERO; - eth::AssemblyItem zeroLoopEnd = m_context->newTag(); - m_context->appendConditionalJumpTo(zeroLoopEnd); - // zero out - *m_context << u256(0) - << eth::Instruction::DUP6 << eth::Instruction::DUP3 << eth::Instruction::ADD - << eth::Instruction::SSTORE; - // increment - *m_context << u256(1) << eth::Instruction::ADD; - m_context->appendJumpTo(zeroLoopStart); - // cleanup - *m_context << zeroLoopEnd; - *m_context << eth::Instruction::POP << eth::Instruction::POP << eth::Instruction::POP - << eth::Instruction::POP << eth::Instruction::POP << eth::Instruction::POP; - break; - } - default: - solAssert(false, "Given byte array location not implemented."); - } -} } } diff --git a/libsolidity/ExpressionCompiler.h b/libsolidity/ExpressionCompiler.h index dd26881fd..e0cc75ce8 100644 --- a/libsolidity/ExpressionCompiler.h +++ b/libsolidity/ExpressionCompiler.h @@ -149,7 +149,7 @@ private: void storeValue(Expression const& _expression, Type const& _sourceType, bool _move = false) const; /// Stores zero in the lvalue. /// @a _expression is the current expression, used for error reporting. - void setToZero(Expression const& _expression) const; + void setToZero(Expression const& _expression, Type const& _type) const; /// Convenience function to convert the stored reference to a value and reset type to NONE if /// the reference was not requested by @a _expression. void retrieveValueIfLValueNotRequested(Expression const& _expression); diff --git a/test/SolidityEndToEndTest.cpp b/test/SolidityEndToEndTest.cpp index 235e535d0..67d05d6e3 100644 --- a/test/SolidityEndToEndTest.cpp +++ b/test/SolidityEndToEndTest.cpp @@ -2284,8 +2284,8 @@ BOOST_AUTO_TEST_CASE(call_forward_bytes) contract sender { function sender() { rec = new receiver(); } function() { savedData = msg.data; } - function forward() { rec.call(savedData); } - function clear() { delete savedData; } + function forward() returns (bool) { rec.call(savedData); return true; } + function clear() returns (bool) { delete savedData; return true; } function val() returns (uint) { return rec.received(); } receiver rec; bytes savedData; @@ -2294,11 +2294,11 @@ BOOST_AUTO_TEST_CASE(call_forward_bytes) compileAndRun(sourceCode, 0, "sender"); BOOST_CHECK(callContractFunction("receive(uint256)", 7) == bytes()); BOOST_CHECK(callContractFunction("val()") == encodeArgs(0)); - BOOST_CHECK(callContractFunction("forward()") == bytes()); + BOOST_CHECK(callContractFunction("forward()") == encodeArgs(true)); BOOST_CHECK(callContractFunction("val()") == encodeArgs(8)); - BOOST_CHECK(callContractFunction("clear()") == bytes()); + BOOST_CHECK(callContractFunction("clear()") == encodeArgs(true)); BOOST_CHECK(callContractFunction("val()") == encodeArgs(8)); - BOOST_CHECK(callContractFunction("forward()") == bytes()); + BOOST_CHECK(callContractFunction("forward()") == encodeArgs(true)); BOOST_CHECK(callContractFunction("val()") == encodeArgs(0x80)); } @@ -2313,9 +2313,10 @@ BOOST_AUTO_TEST_CASE(copying_bytes_multiassign) contract sender { function sender() { rec = new receiver(); } function() { savedData1 = savedData2 = msg.data; } - function forward(bool selector) { + function forward(bool selector) returns (bool) { if (selector) { rec.call(savedData1); delete savedData1; } else { rec.call(savedData2); delete savedData2; } + return true; } function val() returns (uint) { return rec.received(); } receiver rec; @@ -2326,15 +2327,63 @@ BOOST_AUTO_TEST_CASE(copying_bytes_multiassign) compileAndRun(sourceCode, 0, "sender"); BOOST_CHECK(callContractFunction("receive(uint256)", 7) == bytes()); BOOST_CHECK(callContractFunction("val()") == encodeArgs(0)); - BOOST_CHECK(callContractFunction("forward(bool)", true) == bytes()); + BOOST_CHECK(callContractFunction("forward(bool)", true) == encodeArgs(true)); BOOST_CHECK(callContractFunction("val()") == encodeArgs(8)); - BOOST_CHECK(callContractFunction("forward(bool)", false) == bytes()); + BOOST_CHECK(callContractFunction("forward(bool)", false) == encodeArgs(true)); BOOST_CHECK(callContractFunction("val()") == encodeArgs(16)); - BOOST_CHECK(callContractFunction("forward(bool)", true) == bytes()); + BOOST_CHECK(callContractFunction("forward(bool)", true) == encodeArgs(true)); BOOST_CHECK(callContractFunction("val()") == encodeArgs(0x80)); } -// TODO test that "delete" also clears the values +BOOST_AUTO_TEST_CASE(delete_removes_bytes_data) +{ + char const* sourceCode = R"( + contract c { + function() { data = msg.data; } + function del() returns (bool) { delete data; return true; } + bytes data; + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("---", 7) == bytes()); + BOOST_CHECK(!m_state.storage(m_contractAddress).empty()); + BOOST_CHECK(callContractFunction("del()", 7) == encodeArgs(true)); + BOOST_CHECK(m_state.storage(m_contractAddress).empty()); +} + +BOOST_AUTO_TEST_CASE(copy_from_calldata_removes_bytes_data) +{ + char const* sourceCode = R"( + contract c { + function set() returns (bool) { data = msg.data; return true; } + function() { data = msg.data; } + bytes data; + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("set()", 1, 2, 3, 4, 5) == encodeArgs(true)); + BOOST_CHECK(!m_state.storage(m_contractAddress).empty()); + sendMessage(bytes(), false); + BOOST_CHECK(m_output == bytes()); + BOOST_CHECK(m_state.storage(m_contractAddress).empty()); +} + +BOOST_AUTO_TEST_CASE(copy_removes_bytes_data) +{ + char const* sourceCode = R"( + contract c { + function set() returns (bool) { data1 = msg.data; return true; } + function reset() returns (bool) { data1 = data2; return true; } + bytes data1; + bytes data2; + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("set()", 1, 2, 3, 4, 5) == encodeArgs(true)); + BOOST_CHECK(!m_state.storage(m_contractAddress).empty()); + BOOST_CHECK(callContractFunction("reset()") == encodeArgs(true)); + BOOST_CHECK(m_state.storage(m_contractAddress).empty()); +} BOOST_AUTO_TEST_SUITE_END() diff --git a/test/solidityExecutionFramework.h b/test/solidityExecutionFramework.h index 5a6935365..4ef9bfdc8 100644 --- a/test/solidityExecutionFramework.h +++ b/test/solidityExecutionFramework.h @@ -139,6 +139,7 @@ private: return encode(_cppFunction(_arguments...)); } +protected: void sendMessage(bytes const& _data, bool _isCreation, u256 const& _value = 0) { m_state.addBalance(m_sender, _value); // just in case @@ -171,7 +172,6 @@ private: m_logs = executive.logs(); } -protected: bool m_optimize = false; bool m_addStandardSources = false; Address m_sender; From 3bf06f344bdda4233d5cdb125b5c0caa8b6741ce Mon Sep 17 00:00:00 2001 From: Christian Date: Thu, 12 Feb 2015 11:40:14 +0100 Subject: [PATCH 109/213] Added some comments. --- libsolidity/CompilerUtils.h | 17 +++++++++++------ libsolidity/ExpressionCompiler.cpp | 4 ++-- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/libsolidity/CompilerUtils.h b/libsolidity/CompilerUtils.h index 7ac3cc295..fe28ceadf 100644 --- a/libsolidity/CompilerUtils.h +++ b/libsolidity/CompilerUtils.h @@ -54,6 +54,8 @@ public: unsigned storeInMemory(unsigned _offset, Type const& _type = IntegerType(256), bool _padToWordBoundaries = false); /// Dynamic version of @see storeInMemory, expects the memory offset below the value on the stack /// and also updates that. + /// Stack pre: memory_offset value... + /// Stack post: (memory_offset+length) void storeInMemoryDynamic(Type const& _type, bool _padToWordBoundaries = true); /// @returns _size rounded up to the next multiple of 32 (the number of bytes occupied in the /// padded calldata) @@ -75,11 +77,13 @@ public: /// @note Only works for types of fixed size. void computeHashStatic(Type const& _type = IntegerType(256), bool _padToWordBoundaries = false); - /// Copies a byte array to a byte array in storage, where the target is assumed to be on the - /// to top of the stay. Leaves a reference to the target on the stack. + /// Copies a byte array to a byte array in storage. + /// Stack pre: [source_reference] target_reference + /// Stack post: target_reference void copyByteArrayToStorage(ByteArrayType const& _targetType, ByteArrayType const& _sourceType) const; /// Clears the length and data elements of the byte array referenced on the stack. - /// Removes the reference from the stack. + /// Stack pre: reference + /// Stack post: void clearByteArray(ByteArrayType const& _type) const; /// Bytes we need to the start of call data. @@ -87,10 +91,11 @@ public: static const unsigned int dataStartOffset; private: + /// Prepares the given type for storing in memory by shifting it if necessary. unsigned prepareMemoryStore(Type const& _type, bool _padToWordBoundaries) const; - /// Appends a loop that clears all storage between the storage reference at the stack top - /// and the one below it (excluding). - /// Will leave the single value of the end pointer on the stack. + /// Appends a loop that clears a sequence of storage slots (excluding end). + /// Stack pre: end_ref start_ref + /// Stack post: end_ref void clearStorageLoop() const; CompilerContext& m_context; diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index b373bfbcb..63132a124 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -1032,7 +1032,7 @@ void ExpressionCompiler::LValue::storeValue(Expression const& _expression, Type break; } case LValueType::Storage: - // stack layout: value value ... value ref + // stack layout: value value ... value target_ref if (_expression.getType()->isValueType()) { if (!_move) // copy values @@ -1050,7 +1050,7 @@ void ExpressionCompiler::LValue::storeValue(Expression const& _expression, Type if (i + 1 >= m_size) *m_context << eth::Instruction::SSTORE; else - // v v ... v v r+x + // stack here: value value ... value value (target_ref+offset) *m_context << eth::Instruction::SWAP1 << eth::Instruction::DUP2 << eth::Instruction::SSTORE << u256(1) << eth::Instruction::SWAP1 << eth::Instruction::SUB; From 697124ac25f75a016a20782787b432acf1490ce8 Mon Sep 17 00:00:00 2001 From: Christian Date: Thu, 12 Feb 2015 11:54:44 +0100 Subject: [PATCH 110/213] Another try in fixing windows build. --- test/SolidityEndToEndTest.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/SolidityEndToEndTest.cpp b/test/SolidityEndToEndTest.cpp index 8a21290cb..1bfb55f66 100644 --- a/test/SolidityEndToEndTest.cpp +++ b/test/SolidityEndToEndTest.cpp @@ -963,7 +963,7 @@ BOOST_AUTO_TEST_CASE(multiple_elementary_accessors) compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("data()") == encodeArgs(8)); BOOST_CHECK(callContractFunction("name()") == encodeArgs("Celina")); - BOOST_CHECK(callContractFunction("a_hash()") == encodeArgs(dev::sha3(bytes{0x7b}))); + BOOST_CHECK(callContractFunction("a_hash()") == encodeArgs(dev::sha3(bytes(1, 0x7b)))); BOOST_CHECK(callContractFunction("an_address()") == encodeArgs(toBigEndian(u160(0x1337)))); BOOST_CHECK(callContractFunction("super_secret_data()") == bytes()); } @@ -2203,7 +2203,7 @@ BOOST_AUTO_TEST_CASE(sha3_multiple_arguments_with_numeric_literals) dev::sha3( toBigEndian(u256(10)) + bytes{0x0, 0xc} + - bytes{0x91}))); + bytes(1, 0x91)))); } BOOST_AUTO_TEST_CASE(sha3_multiple_arguments_with_string_literals) @@ -2227,7 +2227,7 @@ BOOST_AUTO_TEST_CASE(sha3_multiple_arguments_with_string_literals) dev::sha3( toBigEndian(u256(10)) + bytes{0x0, 0xc} + - bytes{0x91} + + bytes(1, 0x91) + bytes{0x66, 0x6f, 0x6f}))); } From 11283fef7e328887176e9bcc00b7206861a9dfa1 Mon Sep 17 00:00:00 2001 From: Christian Date: Thu, 12 Feb 2015 15:01:38 +0100 Subject: [PATCH 111/213] Bytes type cleanup. --- libsolidity/CompilerUtils.cpp | 9 +++------ libsolidity/Types.cpp | 12 +++--------- libsolidity/Types.h | 10 +--------- 3 files changed, 7 insertions(+), 24 deletions(-) diff --git a/libsolidity/CompilerUtils.cpp b/libsolidity/CompilerUtils.cpp index 192d66d5c..73be38176 100644 --- a/libsolidity/CompilerUtils.cpp +++ b/libsolidity/CompilerUtils.cpp @@ -184,17 +184,14 @@ void CompilerUtils::copyByteArrayToStorage(ByteArrayType const& _targetType, << eth::Instruction::SWAP1; // stack here: target_ref target_data_end target_data_ref // store length (in bytes) - if (_sourceType.getOffset() == 0) - m_context << eth::Instruction::CALLDATASIZE; - else - m_context << _sourceType.getOffset() << eth::Instruction::CALLDATASIZE << eth::Instruction::SUB; + m_context << eth::Instruction::CALLDATASIZE; m_context << eth::Instruction::DUP1 << eth::Instruction::DUP5 << eth::Instruction::SSTORE; // jump to end if length is zero m_context << eth::Instruction::ISZERO; eth::AssemblyItem copyLoopEnd = m_context.newTag(); m_context.appendConditionalJumpTo(copyLoopEnd); - - m_context << _sourceType.getOffset(); + // store start offset + m_context << u256(0); // stack now: target_ref target_data_end target_data_ref calldata_offset eth::AssemblyItem copyLoopStart = m_context.newTag(); m_context << copyLoopStart diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index f43a3ffe3..b1029ec6f 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -58,7 +58,7 @@ TypePointer Type::fromElementaryTypeName(Token::Value _typeToken) else if (Token::String0 <= _typeToken && _typeToken <= Token::String32) return make_shared(int(_typeToken) - int(Token::String0)); else if (_typeToken == Token::Bytes) - return make_shared(ByteArrayType::Location::Storage, 0, 0, true); + return make_shared(ByteArrayType::Location::Storage); else BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unable to convert elementary typename " + std::string(Token::toString(_typeToken)) + " to type.")); @@ -515,12 +515,7 @@ TypePointer ContractType::unaryOperatorResult(Token::Value _operator) const bool ByteArrayType::isImplicitlyConvertibleTo(const Type& _convertTo) const { - if (*this == _convertTo) - return true; - if (_convertTo.getCategory() != Category::ByteArray) - return false; - auto const& other = dynamic_cast(_convertTo); - return (m_dynamicLength == other.m_dynamicLength || m_length == other.m_length); + return _convertTo.getCategory() == getCategory(); } TypePointer ByteArrayType::unaryOperatorResult(Token::Value _operator) const @@ -535,8 +530,7 @@ bool ByteArrayType::operator==(Type const& _other) const if (_other.getCategory() != getCategory()) return false; ByteArrayType const& other = dynamic_cast(_other); - return other.m_location == m_location && other.m_dynamicLength == m_dynamicLength - && other.m_length == m_length && other.m_offset == m_offset; + return other.m_location == m_location; } unsigned ByteArrayType::getSizeOnStack() const diff --git a/libsolidity/Types.h b/libsolidity/Types.h index 0270773fb..627bc76f0 100644 --- a/libsolidity/Types.h +++ b/libsolidity/Types.h @@ -286,9 +286,7 @@ public: enum class Location { Storage, CallData, Memory }; virtual Category getCategory() const override { return Category::ByteArray; } - explicit ByteArrayType(Location _location, u256 const& _offset = 0, u256 const& _length = 0, - bool _dynamicLength = false): - m_location(_location), m_offset(_offset), m_length(_length), m_dynamicLength(_dynamicLength) {} + explicit ByteArrayType(Location _location): m_location(_location) {} virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override; virtual TypePointer unaryOperatorResult(Token::Value _operator) const override; virtual bool operator==(const Type& _other) const override; @@ -296,15 +294,9 @@ public: virtual std::string toString() const override { return "bytes"; } Location getLocation() const { return m_location; } - u256 const& getOffset() const { return m_offset; } - u256 const& getLength() const { return m_length; } - bool hasDynamicLength() const { return m_dynamicLength; } private: Location m_location; - u256 m_offset; - u256 m_length; - bool m_dynamicLength; }; /** From c57775bdd971401cdc12112efa31e650cbdd62a3 Mon Sep 17 00:00:00 2001 From: Christian Date: Thu, 12 Feb 2015 15:18:50 +0100 Subject: [PATCH 112/213] Test for bytes in mapping. --- test/SolidityEndToEndTest.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/test/SolidityEndToEndTest.cpp b/test/SolidityEndToEndTest.cpp index 67d05d6e3..a57eb2700 100644 --- a/test/SolidityEndToEndTest.cpp +++ b/test/SolidityEndToEndTest.cpp @@ -2385,6 +2385,30 @@ BOOST_AUTO_TEST_CASE(copy_removes_bytes_data) BOOST_CHECK(m_state.storage(m_contractAddress).empty()); } +BOOST_AUTO_TEST_CASE(bytes_inside_mappings) +{ + char const* sourceCode = R"( + contract c { + function set(uint key) returns (bool) { data[key] = msg.data; return true; } + function copy(uint from, uint to) returns (bool) { data[to] = data[from]; return true; } + mapping(uint => bytes) data; + } + )"; + compileAndRun(sourceCode); + // store a short byte array at 1 and a longer one at 2 + BOOST_CHECK(callContractFunction("set(uint256)", 1, 2) == encodeArgs(true)); + BOOST_CHECK(callContractFunction("set(uint256)", 2, 2, 3, 4, 5) == encodeArgs(true)); + BOOST_CHECK(!m_state.storage(m_contractAddress).empty()); + // copy shorter to longer + BOOST_CHECK(callContractFunction("copy(uint256,uint256)", 1, 2) == encodeArgs(true)); + BOOST_CHECK(!m_state.storage(m_contractAddress).empty()); + // copy empty to both + BOOST_CHECK(callContractFunction("copy(uint256,uint256)", 99, 1) == encodeArgs(true)); + BOOST_CHECK(!m_state.storage(m_contractAddress).empty()); + BOOST_CHECK(callContractFunction("copy(uint256,uint256)", 99, 2) == encodeArgs(true)); + BOOST_CHECK(m_state.storage(m_contractAddress).empty()); +} + BOOST_AUTO_TEST_SUITE_END() } From a0db309212f7b64f599bed3ff4a83f6102da7354 Mon Sep 17 00:00:00 2001 From: Christian Date: Thu, 12 Feb 2015 15:44:35 +0100 Subject: [PATCH 113/213] length member for byte arrays. --- libsolidity/ExpressionCompiler.cpp | 6 ++++++ libsolidity/Types.cpp | 2 ++ libsolidity/Types.h | 2 ++ test/SolidityEndToEndTest.cpp | 15 +++++++++++++++ 4 files changed, 25 insertions(+) diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index 63132a124..3dbb4012d 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -504,6 +504,12 @@ void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess) } BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Invalid member access to " + type.toString())); } + case Type::Category::ByteArray: + { + solAssert(member == "length", "Illegal bytearray member."); + m_context << eth::Instruction::SLOAD; + break; + } default: BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Member access to unknown type.")); } diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index b1029ec6f..33cc8a1ec 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -541,6 +541,8 @@ unsigned ByteArrayType::getSizeOnStack() const return 1; } +const MemberList ByteArrayType::s_byteArrayMemberList = MemberList({{"length", make_shared(256)}}); + bool ContractType::operator==(Type const& _other) const { if (_other.getCategory() != getCategory()) diff --git a/libsolidity/Types.h b/libsolidity/Types.h index 627bc76f0..5a0e2c429 100644 --- a/libsolidity/Types.h +++ b/libsolidity/Types.h @@ -292,11 +292,13 @@ public: virtual bool operator==(const Type& _other) const override; virtual unsigned getSizeOnStack() const override; virtual std::string toString() const override { return "bytes"; } + virtual MemberList const& getMembers() const override { return s_byteArrayMemberList; } Location getLocation() const { return m_location; } private: Location m_location; + static const MemberList s_byteArrayMemberList; }; /** diff --git a/test/SolidityEndToEndTest.cpp b/test/SolidityEndToEndTest.cpp index a57eb2700..71cb4a6f1 100644 --- a/test/SolidityEndToEndTest.cpp +++ b/test/SolidityEndToEndTest.cpp @@ -2409,6 +2409,21 @@ BOOST_AUTO_TEST_CASE(bytes_inside_mappings) BOOST_CHECK(m_state.storage(m_contractAddress).empty()); } +BOOST_AUTO_TEST_CASE(bytes_length_member) +{ + char const* sourceCode = R"( + contract c { + function set() returns (bool) { data = msg.data; return true; } + function getLength() returns (uint) { return data.length; } + bytes data; + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("getLength()") == encodeArgs(0)); + BOOST_CHECK(callContractFunction("set()", 1, 2) == encodeArgs(true)); + BOOST_CHECK(callContractFunction("getLength()") == encodeArgs(4+32+32)); +} + BOOST_AUTO_TEST_SUITE_END() } From 07ced4cab31092efb78dc63e7bf794e0d08048ad Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 12 Feb 2015 16:27:45 +0100 Subject: [PATCH 114/213] - Add Reusable common controls (Text, Label, ...). - Add Generic Style.qml. - TransactionDialog/StateDialog ui improvement. - Other Small changes. --- mix/ClientModel.cpp | 3 +- mix/qml/CommonSeparator.qml | 9 ++ mix/qml/DefaultLabel.qml | 16 +++ mix/qml/DefaultTextField.qml | 13 ++ mix/qml/Ether.qml | 11 +- mix/qml/MainContent.qml | 2 +- mix/qml/NewProjectDialog.qml | 2 +- mix/qml/QHashTypeView.qml | 1 + mix/qml/QIntTypeView.qml | 1 + mix/qml/QStringTypeView.qml | 1 + mix/qml/StateDialog.qml | 230 ++++++++++++++++---------------- mix/qml/StateListModel.qml | 9 +- mix/qml/Style.qml | 16 +++ mix/qml/TransactionDialog.qml | 124 +++++++++-------- mix/qml/TransactionLog.qml | 10 ++ mix/qml/WebPreview.qml | 4 +- mix/qml/img/delete_sign.png | Bin 0 -> 465 bytes mix/qml/img/edit.png | Bin 0 -> 511 bytes mix/qml/img/plus.png | Bin 0 -> 254 bytes mix/qml/js/QEtherHelper.js | 9 ++ mix/qml/js/TransactionHelper.js | 2 +- mix/qml/qmldir | 1 + mix/res.qrc | 7 + 23 files changed, 284 insertions(+), 187 deletions(-) create mode 100644 mix/qml/CommonSeparator.qml create mode 100644 mix/qml/DefaultLabel.qml create mode 100644 mix/qml/DefaultTextField.qml create mode 100644 mix/qml/Style.qml create mode 100644 mix/qml/img/delete_sign.png create mode 100644 mix/qml/img/edit.png create mode 100644 mix/qml/img/plus.png diff --git a/mix/ClientModel.cpp b/mix/ClientModel.cpp index b7be8988a..57caf573c 100644 --- a/mix/ClientModel.cpp +++ b/mix/ClientModel.cpp @@ -156,7 +156,8 @@ void ClientModel::setupState(QVariantMap _state) { QVariantMap transaction = t.toMap(); QString functionId = transaction.value("functionId").toString(); - u256 gas = (qvariant_cast(transaction.value("gas")))->toU256Wei(); + + u256 gas = boost::get(qvariant_cast(transaction.value("gas"))->internalValue()); u256 value = (qvariant_cast(transaction.value("value")))->toU256Wei(); u256 gasPrice = (qvariant_cast(transaction.value("gasPrice")))->toU256Wei(); diff --git a/mix/qml/CommonSeparator.qml b/mix/qml/CommonSeparator.qml new file mode 100644 index 000000000..4d081e05f --- /dev/null +++ b/mix/qml/CommonSeparator.qml @@ -0,0 +1,9 @@ +import QtQuick 2.0 +import "." + +Rectangle +{ + height: 3 + color: Style.generic.layout.separatorColor +} + diff --git a/mix/qml/DefaultLabel.qml b/mix/qml/DefaultLabel.qml new file mode 100644 index 000000000..da5495863 --- /dev/null +++ b/mix/qml/DefaultLabel.qml @@ -0,0 +1,16 @@ +import QtQuick 2.0 +import QtQuick.Controls 1.1 + +Label { + text: text + font.family: regularFont.name + + SourceSansProRegular + { + id: regularFont + } +} + + + + diff --git a/mix/qml/DefaultTextField.qml b/mix/qml/DefaultTextField.qml new file mode 100644 index 000000000..6705273db --- /dev/null +++ b/mix/qml/DefaultTextField.qml @@ -0,0 +1,13 @@ +import QtQuick 2.0 +import QtQuick.Controls 1.1 + +TextField { + id: titleField + focus: true + font.family: regularFont.name + + SourceSansProRegular + { + id: regularFont; + } +} diff --git a/mix/qml/Ether.qml b/mix/qml/Ether.qml index f737b12b6..be41fced9 100644 --- a/mix/qml/Ether.qml +++ b/mix/qml/Ether.qml @@ -32,12 +32,8 @@ RowLayout { units.currentIndex = unit; } - SourceSansProRegular - { - id: regularFont - } - TextField + DefaultTextField { implicitWidth: 200 onTextChanged: @@ -51,7 +47,10 @@ RowLayout { readOnly: !edit visible: edit id: etherValueEdit; - font.family: regularFont.name + } + + SourceSansProBold { + id: regularFont; } ComboBox diff --git a/mix/qml/MainContent.qml b/mix/qml/MainContent.qml index d984e2753..6c6781878 100644 --- a/mix/qml/MainContent.qml +++ b/mix/qml/MainContent.qml @@ -85,7 +85,7 @@ Rectangle { property alias webWidth: webPreview.width property alias webHeight: webPreview.height property alias showProjectView: projectList.visible - property bool runOnProjectLoad: false + property bool runOnProjectLoad: true } ColumnLayout diff --git a/mix/qml/NewProjectDialog.qml b/mix/qml/NewProjectDialog.qml index 770775df2..4fcb524b2 100644 --- a/mix/qml/NewProjectDialog.qml +++ b/mix/qml/NewProjectDialog.qml @@ -6,7 +6,7 @@ import QtQuick.Dialogs 1.1 Window { id: newProjectWin - modality: Qt.WindowModal + modality: Qt.ApplicationModal width: 640 height: 120 diff --git a/mix/qml/QHashTypeView.qml b/mix/qml/QHashTypeView.qml index 6f3c1910e..73678f953 100644 --- a/mix/qml/QHashTypeView.qml +++ b/mix/qml/QHashTypeView.qml @@ -19,6 +19,7 @@ Item text: text anchors.fill: parent wrapMode: Text.WrapAnywhere + clip: true font.family: boldFont.name MouseArea { id: mouseArea diff --git a/mix/qml/QIntTypeView.qml b/mix/qml/QIntTypeView.qml index 00a08d819..98344dd8b 100644 --- a/mix/qml/QIntTypeView.qml +++ b/mix/qml/QIntTypeView.qml @@ -19,6 +19,7 @@ Item text: text anchors.fill: parent font.family: boldFont.name + clip: true MouseArea { id: mouseArea anchors.fill: parent diff --git a/mix/qml/QStringTypeView.qml b/mix/qml/QStringTypeView.qml index 7e7d2ec76..016206e6d 100644 --- a/mix/qml/QStringTypeView.qml +++ b/mix/qml/QStringTypeView.qml @@ -17,6 +17,7 @@ Item TextInput { id: textinput text: text + clip: true anchors.fill: parent wrapMode: Text.WrapAnywhere font.family: boldFont.name diff --git a/mix/qml/StateDialog.qml b/mix/qml/StateDialog.qml index a8ac27ecf..ebcf5fd1d 100644 --- a/mix/qml/StateDialog.qml +++ b/mix/qml/StateDialog.qml @@ -10,11 +10,11 @@ import "." Window { id: modalStateDialog - modality: Qt.WindowModal + modality: Qt.ApplicationModal width: 450 height: 480 - title: qsTr("State Edition") + title: qsTr("Edit State") visible: false color: StateDialogStyle.generic.backgroundColor @@ -44,6 +44,7 @@ Window { isDefault = setDefault; titleField.focus = true; defaultCheckBox.enabled = !isDefault; + forceActiveFocus(); } function close() { @@ -60,53 +61,67 @@ Window { return item; } - SourceSansProRegular - { - id: regularFont - } - - Rectangle { + ColumnLayout { anchors.fill: parent anchors.margins: 10 - color: StateDialogStyle.generic.backgroundColor - GridLayout { + ColumnLayout { id: dialogContent - columns: 2 anchors.top: parent.top - rowSpacing: 10 - columnSpacing: 10 - Label { - text: qsTr("Title") - font.family: regularFont.name - color: "#808080" + RowLayout + { + Layout.fillWidth: true + DefaultLabel { + Layout.preferredWidth: 75 + text: qsTr("Title") + } + DefaultTextField + { + id: titleField + Layout.fillWidth: true + } } - TextField { - id: titleField - focus: true + + CommonSeparator + { Layout.fillWidth: true - font.family: regularFont.name } - Label { - text: qsTr("Balance") - font.family: regularFont.name - color: "#808080" + RowLayout + { + Layout.fillWidth: true + DefaultLabel { + Layout.preferredWidth: 75 + text: qsTr("Balance") + } + Ether { + id: balanceField + edit: true + displayFormattedValue: true + Layout.fillWidth: true + } } - Ether { - id: balanceField - edit: true - displayFormattedValue: true + + CommonSeparator + { Layout.fillWidth: true } - Label { - text: qsTr("Default") - font.family: regularFont.name - color: "#808080" + RowLayout + { + Layout.fillWidth: true + DefaultLabel { + Layout.preferredWidth: 75 + text: qsTr("Default") + } + CheckBox { + id: defaultCheckBox + Layout.fillWidth: true + } } - CheckBox { - id: defaultCheckBox + + CommonSeparator + { Layout.fillWidth: true } } @@ -114,52 +129,51 @@ Window { ColumnLayout { anchors.top: dialogContent.bottom anchors.topMargin: 5 - spacing: 5 + spacing: 0 RowLayout { - Label { - text: qsTr("Transactions") - font.family: regularFont.name - color: "#808080" + DefaultLabel { + text: qsTr("Transactions: ") } - Button { - tooltip: qsTr("Create a new transaction") - onClicked: transactionsModel.addTransaction() - height: 5 - width: 5 - style: ButtonStyle { - label: Text { - font.family: regularFont.name - text: qsTr("+") - font.pointSize: 15 - color: "#808080" - height: 5 - width: 5 - } - background: Rectangle { - radius: 4 - border.width: 1 - color: "#f7f7f7" - height: 5 - implicitHeight: 5 - } - } + Button + { + iconSource: "qrc:/qml/img/plus.png" + action: newTrAction + width: 10 + height: 10 + } + Action { + id: newTrAction + tooltip: qsTr("Create a new transaction") + onTriggered: transactionsModel.addTransaction() } } - ListView { - id: trList - Layout.preferredWidth: 200 + ScrollView + { Layout.fillHeight: true - Layout.minimumHeight: 20 * transactionsModel.count - model: transactionsModel - delegate: transactionRenderDelegate - visible: transactionsModel.count > 0 + Layout.preferredWidth: 300 + Column + { + Layout.fillHeight: true + Repeater + { + id: trRepeater + model: transactionsModel + delegate: transactionRenderDelegate + visible: transactionsModel.count > 0 + height: 20 * transactionsModel.count + } + } } - } + CommonSeparator + { + Layout.fillWidth: true + } + } RowLayout { @@ -204,53 +218,37 @@ Window { Component { id: transactionRenderDelegate - Item { - id: wrapperItem - height: 20 - width: parent.width - RowLayout { - anchors.fill: parent - Text { - Layout.fillWidth: true - Layout.fillHeight: true - text: functionId - font.pointSize: StateStyle.general.basicFontSize //12 - verticalAlignment: Text.AlignBottom - font.family: regularFont.name - } - ToolButton { - text: qsTr("Edit"); - visible: !stdContract - Layout.fillHeight: true - onClicked: transactionsModel.editTransaction(index) - style: ButtonStyle { - label: Text { - font.family: regularFont.name - text: qsTr("Edit") - font.italic: true - font.pointSize: 9 - } - background: Rectangle { - color: "transparent" - } - } + RowLayout { + DefaultLabel { + Layout.preferredWidth: 150 + text: functionId + } + + Button + { + id: deleteBtn + iconSource: "qrc:/qml/img/delete_sign.png" + action: deleteAction + width: 10 + height: 10 + Action { + id: deleteAction + tooltip: qsTr("Delete") + onTriggered: transactionsModel.deleteTransaction(index) } - ToolButton { - visible: index >= 0 ? !transactionsModel.get(index).executeConstructor : false - text: qsTr("Delete"); - Layout.fillHeight: true - onClicked: transactionsModel.deleteTransaction(index) - style: ButtonStyle { - label: Text { - font.family: regularFont.name - text: qsTr("Delete") - font.italic: true - font.pointSize: 9 - } - background: Rectangle { - color: "transparent" - } - } + } + + Button + { + iconSource: "qrc:/qml/img/edit.png" + action: editAction + visible: !stdContract + width: 10 + height: 10 + Action { + id: editAction + tooltip: qsTr("Edit") + onTriggered: transactionsModel.editTransaction(index) } } } diff --git a/mix/qml/StateListModel.qml b/mix/qml/StateListModel.qml index fd7959477..67372421c 100644 --- a/mix/qml/StateListModel.qml +++ b/mix/qml/StateListModel.qml @@ -25,7 +25,7 @@ Item { functionId: t.functionId, url: t.url, value: QEtherHelper.createEther(t.value.value, t.value.unit), - gas: QEtherHelper.createEther(t.gas.value, t.gas.unit), + gas: QEtherHelper.createBigInt(t.gas.value), //t.gas,//QEtherHelper.createEther(t.gas.value, t.gas.unit), gasPrice: QEtherHelper.createEther(t.gasPrice.value, t.gasPrice.unit), executeConstructor: t.executeConstructor, stdContract: t.stdContract, @@ -81,7 +81,7 @@ Item { functionId: t.functionId, url: t.url, value: { value: t.value.value, unit: t.value.unit }, - gas: { value: t.gas.value, unit: t.gas.unit }, + gas: { value: t.gas.value() }, gasPrice: { value: t.gasPrice.value, unit: t.gasPrice.unit }, executeConstructor: t.executeConstructor, stdContract: t.stdContract, @@ -157,7 +157,7 @@ Item { function defaultTransactionItem() { return { value: QEtherHelper.createEther("100", QEther.Wei), - gas: QEtherHelper.createEther("125000", QEther.Wei), + gas: QEtherHelper.createBigInt("125000"), gasPrice: QEtherHelper.createEther("10000000000000", QEther.Wei), executeConstructor: false, stdContract: false @@ -165,7 +165,8 @@ Item { } function createDefaultState() { - var ether = QEtherHelper.createEther("100000000000000000000000000", QEther.Wei); + //var ether = QEtherHelper.createEther("100000000000000000000000000", QEther.Wei); + var ether = QEtherHelper.createEther("1000000", QEther.Ether); var item = { title: "", balance: ether, diff --git a/mix/qml/Style.qml b/mix/qml/Style.qml new file mode 100644 index 000000000..4dd5d978c --- /dev/null +++ b/mix/qml/Style.qml @@ -0,0 +1,16 @@ +pragma Singleton +import QtQuick 2.0 + +QtObject { + + function absoluteSize(rel) + { + return systemPointSize + rel; + } + + property QtObject generic: QtObject { + property QtObject layout : QtObject { + property string separatorColor: "#f7f7f7" + } + } +} diff --git a/mix/qml/TransactionDialog.qml b/mix/qml/TransactionDialog.qml index 4b2b46cd2..cef82ecc9 100644 --- a/mix/qml/TransactionDialog.qml +++ b/mix/qml/TransactionDialog.qml @@ -9,15 +9,15 @@ import "." Window { id: modalTransactionDialog - modality: Qt.WindowModal + modality: Qt.ApplicationModal width: 450 - height: (paramsModel.count > 0 ? 550 : 300) + height: (paramsModel.count > 0 ? 500 : 300) visible: false color: StateDialogStyle.generic.backgroundColor - title: qsTr("Transaction Edition") + title: qsTr("Edit Transaction") property int transactionIndex property alias transactionParams: paramsModel; - property alias gas: gasField.value; + property alias gas: gasValueEdit.gasValue; property alias gasPrice: gasPriceField.value; property alias transactionValue: valueField.value; property alias functionId: functionComboBox.currentText; @@ -36,7 +36,7 @@ Window { rowGasPrice.visible = !useTransactionDefaultValue; transactionIndex = index; - gasField.value = item.gas; + gasValueEdit.gasValue = item.gas; gasPriceField.value = item.gasPrice; valueField.value = item.value; var functionId = item.functionId; @@ -170,32 +170,27 @@ Window { return item; } - SourceSansProRegular - { - id: regularFont - } - - Rectangle { + ColumnLayout { anchors.fill: parent - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top anchors.margins: 10 - color: StateDialogStyle.generic.backgroundColor + + SourceSansProLight + { + id: lightFont + } ColumnLayout { id: dialogContent - spacing: 30 + anchors.top: parent.top + spacing: 10 RowLayout { id: rowFunction Layout.fillWidth: true height: 150 - Label { + DefaultLabel { Layout.preferredWidth: 75 text: qsTr("Function") - font.family: regularFont.name - color: "#808080" } ComboBox { id: functionComboBox @@ -210,22 +205,24 @@ Window { loadParameters(); } style: ComboBoxStyle { - font: regularFont.name + font: lightFont.name } } } + CommonSeparator + { + Layout.fillWidth: true + } RowLayout { id: rowValue Layout.fillWidth: true height: 150 - Label { + DefaultLabel { Layout.preferredWidth: 75 text: qsTr("Value") - font.family: regularFont.name - color: "#808080" } Ether { id: valueField @@ -234,35 +231,44 @@ Window { } } + CommonSeparator + { + Layout.fillWidth: true + } RowLayout { id: rowGas Layout.fillWidth: true height: 150 - Label { + DefaultLabel { Layout.preferredWidth: 75 text: qsTr("Gas") - font.family: regularFont.name - color: "#808080" } - Ether { - id: gasField - edit: true - displayFormattedValue: true + + DefaultTextField + { + property variant gasValue + onGasValueChanged: text = gasValue.value(); + onTextChanged: gasValue.setValue(text); + implicitWidth: 200 + id: gasValueEdit; } } + CommonSeparator + { + Layout.fillWidth: true + } + RowLayout { id: rowGasPrice Layout.fillWidth: true height: 150 - Label { + DefaultLabel { Layout.preferredWidth: 75 text: qsTr("Gas Price") - font.family: regularFont.name - color: "#808080" } Ether { id: gasPriceField @@ -271,59 +277,62 @@ Window { } } - Label { - text: qsTr("Parameters") + CommonSeparator + { + Layout.fillWidth: true + } + + DefaultLabel { + id: paramLabel + text: qsTr("Parameters:") Layout.preferredWidth: 75 - font.family: regularFont.name - color: "#808080" visible: paramsModel.count > 0 } ScrollView { - Layout.fillWidth: true + anchors.top: paramLabel.bottom + anchors.topMargin: 10 + Layout.preferredWidth: 350 + Layout.fillHeight: true visible: paramsModel.count > 0 - ColumnLayout + Column { id: paramRepeater Layout.fillWidth: true - spacing: 10 + Layout.fillHeight: true + spacing: 3 Repeater { - anchors.fill: parent + height: 20 * paramsModel.count model: paramsModel visible: paramsModel.count > 0 RowLayout { id: row Layout.fillWidth: true - height: 150 - - Label { + height: 20 + DefaultLabel { id: typeLabel text: type - font.family: regularFont.name Layout.preferredWidth: 50 } - Label { + DefaultLabel { id: nameLabel text: name - font.family: regularFont.name - Layout.preferredWidth: 50 + Layout.preferredWidth: 80 } - Label { + DefaultLabel { id: equalLabel text: "=" - font.family: regularFont.name Layout.preferredWidth: 15 } Loader { id: typeLoader - Layout.preferredHeight: 50 Layout.preferredWidth: 150 function getCurrent() { @@ -356,7 +365,7 @@ Window { id: intViewComp QIntTypeView { - height: 50 + height: 20 width: 150 id: intView text: typeLoader.getCurrent().value @@ -368,7 +377,7 @@ Window { id: boolViewComp QBoolTypeView { - height: 50 + height: 20 width: 150 id: boolView defaultValue: "1" @@ -385,7 +394,7 @@ Window { id: stringViewComp QStringTypeView { - height: 50 + height: 20 width: 150 id: stringView text: @@ -400,7 +409,7 @@ Window { id: hashViewComp QHashTypeView { - height: 50 + height: 20 width: 150 id: hashView text: typeLoader.getCurrent().value @@ -411,6 +420,11 @@ Window { } } } + + CommonSeparator + { + Layout.fillWidth: true + } } RowLayout diff --git a/mix/qml/TransactionLog.qml b/mix/qml/TransactionLog.qml index b31956898..61d2e0920 100644 --- a/mix/qml/TransactionLog.qml +++ b/mix/qml/TransactionLog.qml @@ -32,6 +32,16 @@ Item { anchors.fill: parent RowLayout { + Connections + { + target: projectModel + onProjectSaved: + { + if (codeModel.hasContract && !clientModel.running) + projectModel.stateListModel.debugDefaultState(); + } + } + ComboBox { id: statesCombo model: projectModel.stateListModel diff --git a/mix/qml/WebPreview.qml b/mix/qml/WebPreview.qml index f4ddca84e..f258c2e21 100644 --- a/mix/qml/WebPreview.qml +++ b/mix/qml/WebPreview.qml @@ -72,8 +72,8 @@ Item { Connections { target: projectModel - onProjectSaved : reloadOnSave(); - onDocumentSaved: reloadOnSave(); + //onProjectSaved : reloadOnSave(); + //onDocumentSaved: reloadOnSave(); onDocumentAdded: { var document = projectModel.getDocument(documentId) if (document.isHtml) diff --git a/mix/qml/img/delete_sign.png b/mix/qml/img/delete_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..5c00a20bac86f1ef0f68bd3f1fe9ea5626f49cec GIT binary patch literal 465 zcmV;?0WSWDP)B|tu`-VVe7@ox3z8-jWL zDkTUyI9t6Qh?yfkZ62q!1+9JTBQb6S!c&8w%?L~r!VBq*X-2d_dSOC{R)`uCMnoVg zObQW&urX;w2ExKn5LrkTLqjkiQ4AHqg0y1j2qwgfks#QR8b*dtK-MsLK3&C&w^%fc z6wjqG((liUCi*}=Awj4jGQsBp9ON{~An=vAHBHDd0q{oB$zwXFpV z@`#ILKxGp|=Cp>uz%__+a@4+e2z5CLo$V1JEF!gw%|zr2CTY+!=nFUS00000NkvXX Hu0mjfYje6+ literal 0 HcmV?d00001 diff --git a/mix/qml/img/edit.png b/mix/qml/img/edit.png new file mode 100644 index 0000000000000000000000000000000000000000..0530fd192ff2354ce5975c2ee306003d6df288e7 GIT binary patch literal 511 zcmVQKoj{#HH&G|BPM~fOCr~G_-9RU(|LZ}H;~)ts@cx85E*GFF zA3V}K=yEZWw48}!F$KsPgMEj5X$JiZ*GJ?RcM{kkH|XqhBx;^eesAm8Au{@B9pQh0 zx<=~RAt$DzG0X?*CG;pE5>5}uR|e6A`9+&kMu@v6+OR=KW0)Q4R%{R#af{AvytNU+ zyra$GZN{=j`ViLSV*XHgj=W`o3`O`D`7LQ@O?yUC5E4SNxEn9z4!4?+6ohTtE^Z&A z1sQ{ozK31{YBQ1@p%Gd|5Vax25H%r15w#%25j7xH5Tzm25G5g15v3s25hWlhh};l0 zL{5k*A{Rs*kpn`3I2J;KI0iz67z?38jDb)hQX#a66bLn9D1;s{1TqOkA7nC!F36-1 zG05Z)G00vjkfOVKralF1K2q-DZ<)$Q@#_Ex6(TevvQ;lf!8V0vg$@yde4Sz;!WX)sC4ZN&r>3^^+k|JSHq|Fm=YAd&F_nueR+21zt@+1{OAx^;sQHmQ*CtvQgIh?lfb5gTCvqYh_ zo05{@D%GZ6sUhAfZd+XfLQb=~ZjDL06Q#8A@hVe2m0vg1v}Xr%snu`1Z6?A#wR##; zPsa+^NX|VX9qeaQj@Q0fU1#uU(&8wvDUZzW!E}QReRQqJF*aED`j1U^wb{D*&-Qf) rPLGK4SIRu}u12V^bLrRXDxa7Ru2C?~D8DZU^bmumtDnm{r-UW|B%opw literal 0 HcmV?d00001 diff --git a/mix/qml/js/QEtherHelper.js b/mix/qml/js/QEtherHelper.js index 9761b2f45..7563941d2 100644 --- a/mix/qml/js/QEtherHelper.js +++ b/mix/qml/js/QEtherHelper.js @@ -6,3 +6,12 @@ function createEther(_value, _unit, _parent) ether.setUnit(_unit); return ether; } + +function createBigInt(_value) +{ + var bigintComponent = Qt.createComponent("qrc:/qml/BigIntValue.qml"); + var bigint = bigintComponent.createObject(); + bigint.setValue(_value); + return bigint; +} + diff --git a/mix/qml/js/TransactionHelper.js b/mix/qml/js/TransactionHelper.js index f404685cf..87dd74beb 100644 --- a/mix/qml/js/TransactionHelper.js +++ b/mix/qml/js/TransactionHelper.js @@ -5,7 +5,7 @@ function defaultTransaction() return { value: createEther("0", QEther.Wei), functionId: "", - gas: createEther("125000", QEther.Wei), + gas: createBigInt("125000"), gasPrice: createEther("100000", QEther.Wei), executeConstructor: false, parameters: {} diff --git a/mix/qml/qmldir b/mix/qml/qmldir index a90fd7135..ca8e494fe 100644 --- a/mix/qml/qmldir +++ b/mix/qml/qmldir @@ -1,3 +1,4 @@ +singleton Style 1.0 Style.qml singleton StateDialogStyle 1.0 StateDialogStyle.qml singleton ProjectFilesStyle 1.0 ProjectFilesStyle.qml singleton DebuggerPaneStyle 1.0 DebuggerPaneStyle.qml diff --git a/mix/res.qrc b/mix/res.qrc index 5d44e1299..6d9ce3d79 100644 --- a/mix/res.qrc +++ b/mix/res.qrc @@ -90,5 +90,12 @@ qml/CodeEditorStyle.qml qml/StatusPaneStyle.qml qml/StateStyle.qml + qml/img/plus.png + qml/img/delete_sign.png + qml/img/edit.png + qml/DefaultLabel.qml + qml/DefaultTextField.qml + qml/CommonSeparator.qml + qml/Style.qml From 6810ad3d86f1568e98af9c38d89457a9b615b1b7 Mon Sep 17 00:00:00 2001 From: arkpar Date: Wed, 11 Feb 2015 18:49:48 +0100 Subject: [PATCH 115/213] deploy to network --- mix/CodeModel.cpp | 9 +++- mix/CodeModel.h | 6 +-- mix/qml/ProjectModel.qml | 7 ++- mix/qml/StatusPane.qml | 8 +++- mix/qml/js/ProjectModel.js | 93 +++++++++++++++++++++++++++++++++++++- mix/qml/main.qml | 13 +++++- 6 files changed, 127 insertions(+), 9 deletions(-) diff --git a/mix/CodeModel.cpp b/mix/CodeModel.cpp index a9cfcc336..d2e06f6b3 100644 --- a/mix/CodeModel.cpp +++ b/mix/CodeModel.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include "QContractDefinition.h" #include "QFunctionDefinition.h" #include "QVariableDeclaration.h" @@ -61,7 +62,6 @@ CompilationResult::CompilationResult(const dev::solidity::CompilerStack& _compil auto const& contractDefinition = _compiler.getContractDefinition(std::string()); m_contract.reset(new QContractDefinition(&contractDefinition)); m_bytes = _compiler.getBytecode(); - m_assemblyCode = QString::fromStdString(dev::eth::disassemble(m_bytes)); dev::solidity::InterfaceHandler interfaceHandler; m_contractInterface = QString::fromStdString(*interfaceHandler.getABIInterface(contractDefinition)); if (m_contractInterface.isEmpty()) @@ -78,11 +78,16 @@ CompilationResult::CompilationResult(CompilationResult const& _prev, QString con m_contract(_prev.m_contract), m_compilerMessage(_compilerMessage), m_bytes(_prev.m_bytes), - m_assemblyCode(_prev.m_assemblyCode), m_contractInterface(_prev.m_contractInterface), m_codeHighlighter(_prev.m_codeHighlighter) {} + +QString CompilationResult::codeHex() const +{ + return QString::fromStdString(toJS(m_bytes)); +} + CodeModel::CodeModel(QObject* _parent): QObject(_parent), m_compiling(false), diff --git a/mix/CodeModel.h b/mix/CodeModel.h index 5f2add874..0262aa094 100644 --- a/mix/CodeModel.h +++ b/mix/CodeModel.h @@ -69,6 +69,7 @@ class CompilationResult: public QObject Q_PROPERTY(QString compilerMessage READ compilerMessage CONSTANT) Q_PROPERTY(bool successful READ successful CONSTANT) Q_PROPERTY(QString contractInterface READ contractInterface CONSTANT) + Q_PROPERTY(QString codeHex READ codeHex CONSTANT) public: /// Empty compilation result constructor @@ -88,8 +89,8 @@ public: QString compilerMessage() const { return m_compilerMessage; } /// @returns contract bytecode dev::bytes const& bytes() const { return m_bytes; } - /// @returns contract bytecode in human-readable form - QString assemblyCode() const { return m_assemblyCode; } + /// @returns contract bytecode as hex string + QString codeHex() const; /// @returns contract definition in JSON format QString contractInterface() const { return m_contractInterface; } /// Get code highlighter @@ -101,7 +102,6 @@ private: std::shared_ptr m_contract; QString m_compilerMessage; ///< @todo: use some structure here dev::bytes m_bytes; - QString m_assemblyCode; QString m_contractInterface; std::shared_ptr m_codeHighlighter; diff --git a/mix/qml/ProjectModel.qml b/mix/qml/ProjectModel.qml index 10dde5b41..98ed0b02e 100644 --- a/mix/qml/ProjectModel.qml +++ b/mix/qml/ProjectModel.qml @@ -20,6 +20,9 @@ Item { signal projectSaved() signal newProject(var projectData) signal documentSaved(var documentId) + signal deploymentStarted() + signal deploymentComplete() + signal deploymentError(string error) property bool isEmpty: (projectPath === "") readonly property string projectFileName: ".mix" @@ -28,6 +31,7 @@ Item { property string projectPath: "" property string projectTitle: "" property string currentDocumentId: "" + property string deploymentAddress: "" property var listModel: projectListModel property var stateListModel: projectStateListModel.model @@ -48,7 +52,8 @@ Item { function removeDocument(documentId) { ProjectModelCode.removeDocument(documentId); } function getDocument(documentId) { return ProjectModelCode.getDocument(documentId); } function getDocumentIndex(documentId) { return ProjectModelCode.getDocumentIndex(documentId); } - function doAddExistingFiles(paths) { ProjectModelCode.doAddExistingFiles(paths); } + function addExistingFiles(paths) { ProjectModelCode.doAddExistingFiles(paths); } + function deployProject() { ProjectModelCode.deployProject(); } Connections { target: appContext diff --git a/mix/qml/StatusPane.qml b/mix/qml/StatusPane.qml index 956d3f2ec..ddadb9953 100644 --- a/mix/qml/StatusPane.qml +++ b/mix/qml/StatusPane.qml @@ -38,11 +38,17 @@ Rectangle { Connections { target:clientModel - onRunStarted: infoMessage(qsTr("Running transactions..")); + onRunStarted: infoMessage(qsTr("Running transactions...")); onRunFailed: infoMessage(qsTr("Error running transactions")); onRunComplete: infoMessage(qsTr("Run complete")); onNewBlock: infoMessage(qsTr("New block created")); } + Connections { + target:projectModel + onDeploymentStarted: infoMessage(qsTr("Running deployment...")); + onDeploymentError: infoMessage(error); + onDeploymentComplete: infoMessage(qsTr("Deployment complete")); + } color: "transparent" anchors.fill: parent diff --git a/mix/qml/js/ProjectModel.js b/mix/qml/js/ProjectModel.js index 7c7a8ae4c..dcea66b13 100644 --- a/mix/qml/js/ProjectModel.js +++ b/mix/qml/js/ProjectModel.js @@ -39,7 +39,11 @@ function closeProject() { function saveProject() { if (!isEmpty) { - var projectData = { files: [] }; + var projectData = { + files: [], + title: projectTitle, + deploymentAddress: deploymentAddress + }; for (var i = 0; i < projectListModel.count; i++) projectData.files.push(projectListModel.get(i).fileName) projectSaving(projectData); @@ -60,6 +64,7 @@ function loadProject(path) { var parts = path.split("/"); projectData.title = parts[parts.length - 2]; } + deploymentAddress = projectData.deploymentAddress ? projectData.deploymentAddress : ""; projectTitle = projectData.title; projectPath = path; if (!projectData.files) @@ -246,3 +251,89 @@ function generateFileName(name, extension) { return fileName } + +var jsonRpcRequestId = 1; +function deployProject() { + + saveAll(); //TODO: ask user + + var deploymentId = Date.now().toLocaleString("ddMMyyyHHmmsszzz"); + var jsonRpcUrl = "http://localhost:8080"; + console.log("Deploying " + deploymentId + " to " + jsonRpcUrl); + deploymentStarted(); + var code = codeModel.codeHex + var rpcRequest = JSON.stringify({ + jsonrpc: "2.0", + method: "eth_transact", + params: [ { + "code": code + } ], + id: jsonRpcRequestId++ + }); + var httpRequest = new XMLHttpRequest() + httpRequest.open("POST", jsonRpcUrl, true); + httpRequest.setRequestHeader("Content-type", "application/json"); + httpRequest.setRequestHeader("Content-length", rpcRequest.length); + httpRequest.setRequestHeader("Connection", "close"); + httpRequest.onreadystatechange = function() { + if (httpRequest.readyState === XMLHttpRequest.DONE) { + if (httpRequest.status === 200) { + var rpcResponse = JSON.parse(httpRequest.responseText); + var address = rpcResponse.result; + console.log("Created contract, address: " + address); + finalizeDeployment(deploymentId, address); + } else { + var errorText = qsTr("Deployment error: RPC server HTTP status ") + http.status; + console.log(errorText); + deploymentError(errorText); + } + } + } + httpRequest.send(rpcRequest); +} + +function finalizeDeployment(deploymentId, address) { + //create a dir for frontend files and copy them + var deploymentDir = projectPath + deploymentId + "/"; + fileIo.makeDir(deploymentDir); + for (var i = 0; i < projectListModel.count; i++) { + var doc = projectListModel.get(i); + if (doc.isContract) + continue; + if (doc.isHtml) { + //inject the script to access contract API + //TODO: use a template + var html = fileIo.readFile(doc.path); + var insertAt = html.indexOf("") + if (insertAt < 0) + insertAt = 0; + else + insertAt += 6; + html = html.substr(0, insertAt) + + "" + + "" + + "" + + html.substr(insertAt); + fileIo.writeFile(deploymentDir + doc.fileName, html); + } + else + fileIo.copyFile(doc.path, deploymentDir + doc.fileName); + } + //write deployment js + var deploymentJs = + "// Autogenerated by Mix\n" + + "var web3 = require(\"web3\");\n" + + "var contractInterface = " + codeModel.code.contractInterface + ";\n" + + "deployment = {\n" + + "\tweb3: web3,\n" + + "\tcontractAddress: \"" + address + "\",\n" + + "\tcontractInterface: contractInterface,\n" + + "};\n" + + "deplyment.contract = web3.eth.contract(deplyment.contractAddress, deployment.contractInterface);\n"; + fileIo.writeFile(deploymentDir + "deployment.js", deploymentJs); + //copy scripts + fileIo.copyFile("qrc:///js/bignumber.min.js", deploymentDir + "bignumber.min.js"); + fileIo.copyFile("qrc:///js/webthree.js", deploymentDir + "ethereum.js"); + saveProject(); + deploymentComplete(); +} diff --git a/mix/qml/main.qml b/mix/qml/main.qml index 79430eb59..38f58c852 100644 --- a/mix/qml/main.qml +++ b/mix/qml/main.qml @@ -42,6 +42,8 @@ ApplicationWindow { MenuSeparator {} MenuItem { action: editStatesAction } MenuSeparator {} + MenuItem { action: deployViaRpcAction } + MenuSeparator {} MenuItem { action: toggleRunOnLoadAction } } Menu { @@ -265,7 +267,7 @@ ApplicationWindow { selectFolder: false onAccepted: { var paths = addExistingFileDialog.fileUrls; - projectModel.doAddExistingFiles(paths); + projectModel.addExistingFiles(paths); } } @@ -301,4 +303,13 @@ ApplicationWindow { onTriggered: projectModel.openPrevDocument(); } + Action { + id: deployViaRpcAction + text: qsTr("Deploy to Network") + shortcut: "Ctrl+Shift+D" + enabled: !projectModel.isEmpty && codeModel.hasContract + onTriggered: projectModel.deployProject(); + } + + } From d2b72415e878779e2568c11003fc9c52ad96947e Mon Sep 17 00:00:00 2001 From: arkpar Date: Thu, 12 Feb 2015 16:32:29 +0100 Subject: [PATCH 116/213] web preview via http server --- mix/FileIo.cpp | 6 +++++ mix/HttpServer.cpp | 12 +++++---- mix/HttpServer.h | 4 +++ mix/qml/CodeEditorView.qml | 23 ++++++++++++----- mix/qml/ProjectModel.qml | 15 ++++++++++- mix/qml/WebPreview.qml | 47 ++++++++++++++++++++++++---------- mix/qml/html/WebContainer.html | 7 ++++- mix/qml/js/ProjectModel.js | 17 ++++++++---- 8 files changed, 99 insertions(+), 32 deletions(-) diff --git a/mix/FileIo.cpp b/mix/FileIo.cpp index 52fd57902..818d8c887 100644 --- a/mix/FileIo.cpp +++ b/mix/FileIo.cpp @@ -70,6 +70,12 @@ void FileIo::writeFile(QString const& _url, QString const& _data) void FileIo::copyFile(QString const& _sourceUrl, QString const& _destUrl) { + if (QUrl(_sourceUrl).scheme() == "qrc") + { + writeFile(_destUrl, readFile(_sourceUrl)); + return; + } + QUrl sourceUrl(_sourceUrl); QUrl destUrl(_destUrl); if (!QFile::copy(sourceUrl.path(), destUrl.path())) diff --git a/mix/HttpServer.cpp b/mix/HttpServer.cpp index cfe5c37f4..bf210444b 100644 --- a/mix/HttpServer.cpp +++ b/mix/HttpServer.cpp @@ -132,23 +132,25 @@ void HttpServer::readClient() if (socket->canReadLine()) { QString hdr = QString(socket->readLine()); - if (hdr.startsWith("POST")) + if (hdr.startsWith("POST") || hdr.startsWith("GET")) { + QUrl url(hdr.split(' ')[1]); QString l; do l = socket->readLine(); while (!(l.isEmpty() || l == "\r" || l == "\r\n")); QString content = socket->readAll(); - QUrl url; std::unique_ptr request(new HttpRequest(this, url, content)); clientConnected(request.get()); QTextStream os(socket); os.setAutoDetectUnicode(true); + QString q; ///@todo: allow setting response content-type, charset, etc - os << "HTTP/1.0 200 Ok\r\n" - "Content-Type: text/plain; charset=\"utf-8\"\r\n" - "\r\n"; + os << "HTTP/1.0 200 Ok\r\n"; + if (!request->m_responseContentType.isEmpty()) + os << "Content-Type: " << request->m_responseContentType << "; "; + os << "charset=\"utf-8\"\r\n\r\n"; os << request->m_response; } } diff --git a/mix/HttpServer.h b/mix/HttpServer.h index 00d63a073..add83238b 100644 --- a/mix/HttpServer.h +++ b/mix/HttpServer.h @@ -51,11 +51,15 @@ public: /// Set response for a request /// @param _response Response body. If no response is set, server returns status 200 with empty body Q_INVOKABLE void setResponse(QString const& _response) { m_response = _response; } + /// Set response content type + /// @param _contentType Response content type string. text/plain by default + Q_INVOKABLE void setResponseContentType(QString const& _contentType) { m_responseContentType = _contentType ; } private: QUrl m_url; QString m_content; QString m_response; + QString m_responseContentType; friend class HttpServer; }; diff --git a/mix/qml/CodeEditorView.qml b/mix/qml/CodeEditorView.qml index 36fc586b3..4d54994fe 100644 --- a/mix/qml/CodeEditorView.qml +++ b/mix/qml/CodeEditorView.qml @@ -4,18 +4,26 @@ import QtQuick.Layouts 1.0 import QtQuick.Controls 1.0 Item { - + id: codeEditorView property string currentDocumentId: "" + signal documentEdit(string documentId) function getDocumentText(documentId) { - for (i = 0; i < editorListModel.count; i++) { + for (var i = 0; i < editorListModel.count; i++) { if (editorListModel.get(i).documentId === documentId) { - return editors.itemAt(i).getText(); + return editors.itemAt(i).item.getText(); } } return ""; } + function isDocumentOpen(documentId) { + for (var i = 0; i < editorListModel.count; i++) + if (editorListModel.get(i).documentId === documentId) + return true; + return false; + } + function openDocument(document) { loadDocument(document); currentDocumentId = document.documentId; @@ -31,13 +39,16 @@ Item { function doLoadDocument(editor, document) { var data = fileIo.readFile(document.path); - if (document.isContract) - editor.onEditorTextChanged.connect(function() { + editor.onEditorTextChanged.connect(function() { + documentEdit(document.documentId); + if (document.isContract) codeModel.registerCodeChange(editor.getText()); - }); + }); editor.setText(data, document.syntaxMode); } + Component.onCompleted: projectModel.codeEditor = codeEditorView; + Connections { target: projectModel onDocumentOpened: { diff --git a/mix/qml/ProjectModel.qml b/mix/qml/ProjectModel.qml index 98ed0b02e..7e65f3174 100644 --- a/mix/qml/ProjectModel.qml +++ b/mix/qml/ProjectModel.qml @@ -34,6 +34,7 @@ Item { property string deploymentAddress: "" property var listModel: projectListModel property var stateListModel: projectStateListModel.model + property CodeEditorView codeEditor: null //interface function saveAll() { ProjectModelCode.saveAll(); } @@ -53,7 +54,7 @@ Item { function getDocument(documentId) { return ProjectModelCode.getDocument(documentId); } function getDocumentIndex(documentId) { return ProjectModelCode.getDocumentIndex(documentId); } function addExistingFiles(paths) { ProjectModelCode.doAddExistingFiles(paths); } - function deployProject() { ProjectModelCode.deployProject(); } + function deployProject() { ProjectModelCode.deployProject(false); } Connections { target: appContext @@ -88,6 +89,18 @@ Item { } } + MessageDialog { + id: deployWarningDialog + title: qsTr("Project") + text: qsTr("This project has been already deployed to the network. Do you want to re-deploy it?") + standardButtons: StandardButton.Ok | StandardButton.Cancel + icon: StandardIcon.Question + onAccepted: { + ProjectModelCode.deployProject(true); + } + } + + ListModel { id: projectListModel } diff --git a/mix/qml/WebPreview.qml b/mix/qml/WebPreview.qml index f4ddca84e..a952d6345 100644 --- a/mix/qml/WebPreview.qml +++ b/mix/qml/WebPreview.qml @@ -43,8 +43,8 @@ Item { } function changePage() { - if (pageCombo.currentIndex >=0 && pageCombo.currentIndex < pageListModel.count) { - setPreviewUrl(pageListModel.get(pageCombo.currentIndex).path); + if (pageCombo.currentIndex >= 0 && pageCombo.currentIndex < pageListModel.count) { + setPreviewUrl(httpServer.url + "/" + pageListModel.get(pageCombo.currentIndex).documentId); } else { setPreviewUrl(""); } @@ -54,7 +54,7 @@ Item { onAppLoaded: { //We need to load the container using file scheme so that web security would allow loading local files in iframe var containerPage = fileIo.readFile("qrc:///qml/html/WebContainer.html"); - webView.loadHtml(containerPage, "file:///WebContainer.html") + webView.loadHtml(containerPage, httpServer.url + "/WebContainer.html") } } @@ -112,16 +112,35 @@ Item { accept: true port: 8893 onClientConnected: { - //filter polling spam - //TODO: do it properly - //var log = _request.content.indexOf("eth_changed") < 0; - var log = true; - if (log) - console.log(_request.content); - var response = clientModel.apiCall(_request.content); - if (log) - console.log(response); - _request.setResponse(response); + var urlPath = _request.url.toString(); + if (urlPath.indexOf("/rpc/") === 0) + { + //jsonrpc request + //filter polling requests //TODO: do it properly + var log = _request.content.indexOf("eth_changed") < 0; + if (log) + console.log(_request.content); + var response = clientModel.apiCall(_request.content); + if (log) + console.log(response); + _request.setResponse(response); + } + else + { + //document request + var documentId = urlPath.substr(urlPath.lastIndexOf("/") + 1); + var content = ""; + if (projectModel.codeEditor.isDocumentOpen(documentId)) + content = projectModel.codeEditor.getDocumentText(documentId); + else + content = fileIo.readFile(projectModel.getDocument(documentId).path); + if (documentId === pageListModel.get(pageCombo.currentIndex).documentId) { + //root page, inject deployment script + content = "\n" + content; + _request.setResponseContentType("text/html"); + } + _request.setResponse(content); + } } } @@ -163,7 +182,7 @@ Item { onLoadingChanged: { if (!loading) { initialized = true; - webView.runJavaScript("init(\"" + httpServer.url + "\")"); + webView.runJavaScript("init(\"" + httpServer.url + "/rpc/\")"); if (pendingPageUrl) setPreviewUrl(pendingPageUrl); } diff --git a/mix/qml/html/WebContainer.html b/mix/qml/html/WebContainer.html index 04ba8ab73..e48668041 100644 --- a/mix/qml/html/WebContainer.html +++ b/mix/qml/html/WebContainer.html @@ -21,13 +21,18 @@ updateContract = function(address, contractFace) { window.contractAddress = address; window.contractInterface = contractFace; window.contract = window.web3.eth.contract(address, contractFace); + window.deploy = { + contractAddress: address, + contractInterface: contractFace, + contract: window.contract + }; } }; init = function(url) { web3 = require('web3'); - web3.setProvider(new web3.providers.HttpSyncProvider(url)); window.web3 = web3; + web3.setProvider(new web3.providers.HttpSyncProvider(url)); }; diff --git a/mix/qml/js/ProjectModel.js b/mix/qml/js/ProjectModel.js index dcea66b13..fb6872bd4 100644 --- a/mix/qml/js/ProjectModel.js +++ b/mix/qml/js/ProjectModel.js @@ -253,11 +253,17 @@ function generateFileName(name, extension) { var jsonRpcRequestId = 1; -function deployProject() { +function deployProject(force) { saveAll(); //TODO: ask user - var deploymentId = Date.now().toLocaleString("ddMMyyyHHmmsszzz"); + if (!force && deploymentAddress !== "") { + deployWarningDialog.visible = true; + return; + } + + var date = new Date(); + var deploymentId = date.toLocaleString(Qt.locale(), "ddMMyyHHmmsszzz"); var jsonRpcUrl = "http://localhost:8080"; console.log("Deploying " + deploymentId + " to " + jsonRpcUrl); deploymentStarted(); @@ -283,7 +289,7 @@ function deployProject() { console.log("Created contract, address: " + address); finalizeDeployment(deploymentId, address); } else { - var errorText = qsTr("Deployment error: RPC server HTTP status ") + http.status; + var errorText = qsTr("Deployment error: RPC server HTTP status ") + httpRequest.status; console.log(errorText); deploymentError(errorText); } @@ -324,16 +330,17 @@ function finalizeDeployment(deploymentId, address) { "// Autogenerated by Mix\n" + "var web3 = require(\"web3\");\n" + "var contractInterface = " + codeModel.code.contractInterface + ";\n" + - "deployment = {\n" + + "deploy = {\n" + "\tweb3: web3,\n" + "\tcontractAddress: \"" + address + "\",\n" + "\tcontractInterface: contractInterface,\n" + "};\n" + - "deplyment.contract = web3.eth.contract(deplyment.contractAddress, deployment.contractInterface);\n"; + "deploy.contract = web3.eth.contract(deploy.contractAddress, deploy.contractInterface);\n"; fileIo.writeFile(deploymentDir + "deployment.js", deploymentJs); //copy scripts fileIo.copyFile("qrc:///js/bignumber.min.js", deploymentDir + "bignumber.min.js"); fileIo.copyFile("qrc:///js/webthree.js", deploymentDir + "ethereum.js"); + deploymentAddress = address; saveProject(); deploymentComplete(); } From a5b758e77d52285b0b81a7045d3313be4d152d3a Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Thu, 12 Feb 2015 16:34:49 +0100 Subject: [PATCH 117/213] Minor style fix. --- libethereum/Client.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index 455cce7a8..4a49812df 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -69,7 +69,7 @@ Client::Client(p2p::Host* _extNet, std::string const& _dbPath, bool _forceClean, { m_host = _extNet->registerCapability(new EthereumHost(m_bc, m_tq, m_bq, _networkId)); - if(miners > -1) + if (miners > -1) setMiningThreads(miners); else setMiningThreads(); From 90d309ec933bcf4b66bac98e6284597cfd51d55c Mon Sep 17 00:00:00 2001 From: arkpar Date: Thu, 12 Feb 2015 16:37:06 +0100 Subject: [PATCH 118/213] style --- mix/CodeModel.cpp | 1 - mix/qml/ProjectModel.qml | 1 - mix/qml/main.qml | 2 -- 3 files changed, 4 deletions(-) diff --git a/mix/CodeModel.cpp b/mix/CodeModel.cpp index d2e06f6b3..aae9dac86 100644 --- a/mix/CodeModel.cpp +++ b/mix/CodeModel.cpp @@ -82,7 +82,6 @@ CompilationResult::CompilationResult(CompilationResult const& _prev, QString con m_codeHighlighter(_prev.m_codeHighlighter) {} - QString CompilationResult::codeHex() const { return QString::fromStdString(toJS(m_bytes)); diff --git a/mix/qml/ProjectModel.qml b/mix/qml/ProjectModel.qml index 7e65f3174..e74be7a9b 100644 --- a/mix/qml/ProjectModel.qml +++ b/mix/qml/ProjectModel.qml @@ -100,7 +100,6 @@ Item { } } - ListModel { id: projectListModel } diff --git a/mix/qml/main.qml b/mix/qml/main.qml index 38f58c852..71d8c24bf 100644 --- a/mix/qml/main.qml +++ b/mix/qml/main.qml @@ -310,6 +310,4 @@ ApplicationWindow { enabled: !projectModel.isEmpty && codeModel.hasContract onTriggered: projectModel.deployProject(); } - - } From 518ef9c18b3380408f2c878302d20b57d2aaaabe Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 12 Feb 2015 17:57:45 +0100 Subject: [PATCH 119/213] ui improvement --- mix/AppContext.cpp | 4 ++-- mix/qml/CommonSeparator.qml | 2 +- mix/qml/DefaultLabel.qml | 5 +++-- mix/qml/StateDialog.qml | 2 ++ mix/qml/Style.qml | 7 +++++-- mix/qml/TransactionDialog.qml | 1 + 6 files changed, 14 insertions(+), 7 deletions(-) diff --git a/mix/AppContext.cpp b/mix/AppContext.cpp index 7fe22106f..64bc59ff8 100644 --- a/mix/AppContext.cpp +++ b/mix/AppContext.cpp @@ -60,6 +60,8 @@ AppContext::~AppContext() void AppContext::load() { m_applicationEngine->rootContext()->setContextProperty("appContext", this); + QFont f; + m_applicationEngine->rootContext()->setContextProperty("systemPointSize", f.pointSize()); qmlRegisterType("org.ethereum.qml", 1, 0, "FileIo"); m_applicationEngine->rootContext()->setContextProperty("codeModel", m_codeModel.get()); m_applicationEngine->rootContext()->setContextProperty("fileIo", m_fileIo.get()); @@ -81,8 +83,6 @@ void AppContext::load() BOOST_THROW_EXCEPTION(exception); } m_applicationEngine->rootContext()->setContextProperty("projectModel", projectModel); - QFont f; - m_applicationEngine->rootContext()->setContextProperty("systemPointSize", f.pointSize()); qmlRegisterType("CodeEditorExtensionManager", 1, 0, "CodeEditorExtensionManager"); qmlRegisterType("HttpServer", 1, 0, "HttpServer"); m_applicationEngine->load(QUrl("qrc:/qml/main.qml")); diff --git a/mix/qml/CommonSeparator.qml b/mix/qml/CommonSeparator.qml index 4d081e05f..c81a81f63 100644 --- a/mix/qml/CommonSeparator.qml +++ b/mix/qml/CommonSeparator.qml @@ -3,7 +3,7 @@ import "." Rectangle { - height: 3 + height: 1 color: Style.generic.layout.separatorColor } diff --git a/mix/qml/DefaultLabel.qml b/mix/qml/DefaultLabel.qml index da5495863..a1304e673 100644 --- a/mix/qml/DefaultLabel.qml +++ b/mix/qml/DefaultLabel.qml @@ -1,11 +1,12 @@ import QtQuick 2.0 import QtQuick.Controls 1.1 +import "." Label { text: text font.family: regularFont.name - - SourceSansProRegular + font.pointSize: Style.generic.size.titlePointSize + SourceSansProLight { id: regularFont } diff --git a/mix/qml/StateDialog.qml b/mix/qml/StateDialog.qml index ebcf5fd1d..eeda2ae22 100644 --- a/mix/qml/StateDialog.qml +++ b/mix/qml/StateDialog.qml @@ -132,6 +132,7 @@ Window { spacing: 0 RowLayout { + Layout.preferredWidth: 150 DefaultLabel { text: qsTr("Transactions: ") } @@ -142,6 +143,7 @@ Window { action: newTrAction width: 10 height: 10 + anchors.right: parent.right } Action { diff --git a/mix/qml/Style.qml b/mix/qml/Style.qml index 4dd5d978c..9e4b6f268 100644 --- a/mix/qml/Style.qml +++ b/mix/qml/Style.qml @@ -9,8 +9,11 @@ QtObject { } property QtObject generic: QtObject { - property QtObject layout : QtObject { - property string separatorColor: "#f7f7f7" + property QtObject layout: QtObject { + property string separatorColor: "#808080" + } + property QtObject size: QtObject { + property string titlePointSize: absoluteSize(0) } } } diff --git a/mix/qml/TransactionDialog.qml b/mix/qml/TransactionDialog.qml index cef82ecc9..a38886354 100644 --- a/mix/qml/TransactionDialog.qml +++ b/mix/qml/TransactionDialog.qml @@ -424,6 +424,7 @@ Window { CommonSeparator { Layout.fillWidth: true + visible: paramsModel.count > 0 } } From 4f17defa103ab63b2355b0b4285c41bcad5b6b01 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Thu, 12 Feb 2015 20:13:44 +0100 Subject: [PATCH 120/213] add valid tx output --- test/blFirstTestFiller.json | 32 ------ test/blValidBlockTestFiller.json | 187 ++++++++++++++++++++++++++++++- test/block.cpp | 122 +++++++++++++------- 3 files changed, 266 insertions(+), 75 deletions(-) delete mode 100644 test/blFirstTestFiller.json diff --git a/test/blFirstTestFiller.json b/test/blFirstTestFiller.json deleted file mode 100644 index d4e6d109f..000000000 --- a/test/blFirstTestFiller.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "firstBlockTest" : { - "block" : { - "parentHash": "0xefb4db878627027c81b3bb1c7dd3a18dae3914a49cdd24a3e40ab3bbfbb240c5", - "uncleHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "coinbase": "0x8888f1f195afa192cfee860698584c030f4c9db1", - "stateRoot": "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", - "transactionsTrie": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "receiptTrie": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "bloom": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "difficulty": "023101", - "number": "62", - "gasLimit": "0x0dddb6", - "gasUsed": "100", - "timestamp": "0x54c98c81", - "extraData": "42", - "nonce": "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d" - }, - "pre" : {}, - "transactions": [{ - "nonce": "0", - "gasPrice": "0x09184e72a000", - "gasLimit": "0x0f3e6f", - "to": "", - "value": "", - "data": "0x60056013565b6101918061001d6000396000f35b3360008190555056006001600060e060020a6000350480630a874df61461003a57806341c0e1b514610058578063a02b161e14610066578063dbbdf0831461007757005b610045600435610149565b80600160a060020a031660005260206000f35b610060610161565b60006000f35b6100716004356100d4565b60006000f35b61008560043560243561008b565b60006000f35b600054600160a060020a031632600160a060020a031614156100ac576100b1565b6100d0565b8060018360005260205260406000208190555081600060005260206000a15b5050565b600054600160a060020a031633600160a060020a031614158015610118575033600160a060020a0316600182600052602052604060002054600160a060020a031614155b61012157610126565b610146565b600060018260005260205260406000208190555080600060005260206000a15b50565b60006001826000526020526040600020549050919050565b600054600160a060020a031633600160a060020a0316146101815761018f565b600054600160a060020a0316ff5b56", - "v": "0x1b", - "r": "0xd4287e915ebac7a8af390560fa53c8f0b7f13802ba0393d7afa5823c2560ca89", - "s": "0xae75db31a34f7e386ad459646de98ec3a1c88cc91b11620b4ffd86871f579942" - }] - } -} diff --git a/test/blValidBlockTestFiller.json b/test/blValidBlockTestFiller.json index 99f1d32af..da2625ea6 100644 --- a/test/blValidBlockTestFiller.json +++ b/test/blValidBlockTestFiller.json @@ -1,12 +1,54 @@ { - "lowGasLimitBoundary" : { + "diffTooLow" : { "genesisBlockHeader" : { "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", - "difficulty" : "10000", + "difficulty" : "1023", + "extraData" : "42", + "gasLimit" : "100000", + "gasUsed" : "0", + "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transactions" : [ + { + "data" : "", + "gasLimit" : "850", + "gasPrice" : "1", + "nonce" : "0", + "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", + "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "v" : "27", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + + "diff1024" : { + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "1024", "extraData" : "42", "gasLimit" : "100000", - "gasUsed" : "100", + "gasUsed" : "0", "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", "number" : "0", "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -39,6 +81,145 @@ ], "uncleHeaders" : [ ] + }, + + "gasPrice0" : { + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "10000", + "extraData" : "42", + "gasLimit" : "100000", + "gasUsed" : "0", + "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transactions" : [ + { + "data" : "", + "gasLimit" : "500", + "gasPrice" : "0", + "nonce" : "0", + "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", + "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "v" : "27", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + + "tx" : { + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "10000", + "extraData" : "42", + "gasLimit" : "100000", + "gasUsed" : "0", + "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transactions" : [ + { + "data" : "", + "gasLimit" : "500", + "gasPrice" : "0", + "nonce" : "0", + "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", + "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "v" : "27", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + + "txOrder" : { + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "10000", + "extraData" : "42", + "gasLimit" : "100000", + "gasUsed" : "0", + "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transactions" : [ + { + "data" : "", + "gasLimit" : "500", + "gasPrice" : "10", + "nonce" : "0", + "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", + "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "v" : "27", + "value" : "7000000000" + }, + + { + "data" : "", + "gasLimit" : "500", + "gasPrice" : "10", + "nonce" : "0", + "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", + "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "v" : "27", + "value" : "1000000000" + }, + + ], + "uncleHeaders" : [ + ] } } diff --git a/test/block.cpp b/test/block.cpp index 88f7de634..c701cb979 100644 --- a/test/block.cpp +++ b/test/block.cpp @@ -32,29 +32,50 @@ namespace dev { namespace test { bytes createBlockRLPFromFields(mObject& _tObj) { - BOOST_REQUIRE(_tObj.count("parentHash") > 0); - BOOST_REQUIRE(_tObj.count("uncleHash") > 0); - BOOST_REQUIRE(_tObj.count("coinbase") > 0); - BOOST_REQUIRE(_tObj.count("stateRoot") > 0); - BOOST_REQUIRE(_tObj.count("transactionsTrie")> 0); - BOOST_REQUIRE(_tObj.count("receiptTrie") > 0); - BOOST_REQUIRE(_tObj.count("bloom") > 0); - BOOST_REQUIRE(_tObj.count("difficulty") > 0); - BOOST_REQUIRE(_tObj.count("number") > 0); - BOOST_REQUIRE(_tObj.count("gasLimit")> 0); - BOOST_REQUIRE(_tObj.count("gasUsed") > 0); - BOOST_REQUIRE(_tObj.count("timestamp") > 0); - BOOST_REQUIRE(_tObj.count("extraData") > 0); - BOOST_REQUIRE(_tObj.count("nonce") > 0); - - // construct RLP of the given block RLPStream rlpStream; - rlpStream.appendList(14); - rlpStream << h256(_tObj["parentHash"].get_str()) << h256(_tObj["uncleHash"].get_str()) << Address(_tObj["coinbase"].get_str()); - rlpStream << h256(_tObj["stateRoot"].get_str()) << h256(_tObj["transactionsTrie"].get_str()) << h256(_tObj["receiptTrie"].get_str()); - rlpStream << LogBloom(_tObj["bloom"].get_str()) << u256(_tObj["difficulty"].get_str()) << u256(_tObj["number"].get_str()); - rlpStream << u256(_tObj["gasLimit"].get_str()) << u256(_tObj["gasUsed"].get_str()) << u256(_tObj["timestamp"].get_str()); - rlpStream << importByteArray(_tObj["extraData"].get_str()) << h256(_tObj["nonce"].get_str()); + rlpStream.appendList(_tObj.size()); + + if (_tObj.count("parentHash") > 0) + rlpStream << importByteArray(_tObj["parentHash"].get_str()); + + if (_tObj.count("uncleHash") > 0) + rlpStream << importByteArray(_tObj["uncleHash"].get_str()); + + if (_tObj.count("coinbase") > 0) + rlpStream << importByteArray(_tObj["coinbase"].get_str()); + + if (_tObj.count("stateRoot") > 0) + rlpStream << importByteArray(_tObj["stateRoot"].get_str()); + + if (_tObj.count("transactionsTrie") > 0) + rlpStream << importByteArray(_tObj["transactionsTrie"].get_str()); + + if (_tObj.count("receiptTrie") > 0) + rlpStream << importByteArray(_tObj["receiptTrie"].get_str()); + + if (_tObj.count("bloom") > 0) + rlpStream << importByteArray(_tObj["bloom"].get_str()); + + if (_tObj.count("difficulty") > 0) + rlpStream << bigint(_tObj["difficulty"].get_str()); + + if (_tObj.count("number") > 0) + rlpStream << bigint(_tObj["number"].get_str()); + + if (_tObj.count("gasLimit") > 0) + rlpStream << bigint(_tObj["gasLimit"].get_str()); + + if (_tObj.count("gasUsed") > 0) + rlpStream << bigint(_tObj["gasUsed"].get_str()); + + if (_tObj.count("timestamp") > 0) + rlpStream << bigint(_tObj["timestamp"].get_str()); + + if (_tObj.count("extraData") > 0) + rlpStream << importByteArray(_tObj["extraData"].get_str()); + + if (_tObj.count("nonce") > 0) + rlpStream << importByteArray(_tObj["nonce"].get_str()); return rlpStream.out(); } @@ -67,6 +88,7 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) mObject& o = i.second.get_obj(); BOOST_REQUIRE(o.count("genesisBlockHeader") > 0); + cout << "construc genesis\n"; // construct RLP of the genesis block const bytes c_blockRLP = createBlockRLPFromFields(o["genesisBlockHeader"].get_obj()); @@ -95,6 +117,7 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) } BOOST_REQUIRE(o.count("pre") > 0); + cout << "read state\n"; ImportTest importer(o["pre"].get_obj()); State state(Address(), OverlayDB(), BaseState::Empty); @@ -137,6 +160,7 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) if (_fillin) { BOOST_REQUIRE(o.count("transactions") > 0); + cout << "read transactions\n"; TransactionQueue txs; @@ -152,17 +176,18 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) BOOST_REQUIRE(tx.count("r") > 0); BOOST_REQUIRE(tx.count("s") > 0); BOOST_REQUIRE(tx.count("data") > 0); - - //Transaction txFromFields(createRLPStreamFromTransactionFields(tx).out(), CheckSignature::Sender); - + cout << "import tx\n"; if (!txs.attemptImport(&createRLPStreamFromTransactionFields(tx).out())) cnote << "failed importing transaction\n"; } try { - state.sync(bc); - state.sync(bc,txs); + cout << "sync state: " << state.sync(bc) << endl; + TransactionReceipts txReceipts = state.sync(bc,txs); + cout << "sync state done\n"; + //if (syncSuccess) + // throw Exception(); state.commitToMine(bc); MineInfo info; for (info.completed = false; !info.completed; info = state.mine()) {} @@ -171,12 +196,36 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) catch (Exception const& _e) { cnote << "state sync or mining did throw an exception: " << diagnostic_information(_e); + return; } catch (std::exception const& _e) { cnote << "state sync or mining did throw an exception: " << _e.what(); + return; + } + + // write valid txs + cout << "number of valid txs: " << txs.transactions().size(); + mArray txArray; + for (auto const& txi: txs.transactions()) + { + Transaction tx(txi.second, CheckSignature::Sender); + mObject txObject; + txObject["nonce"] = toString(tx.nonce()); + txObject["data"] = toHex(tx.data()); + txObject["gasLimit"] = toString(tx.gas()); + txObject["gasPrice"] = toString(tx.gasPrice()); + txObject["r"] = toString(tx.signature().r); + txObject["s"] = toString(tx.signature().s); + txObject["v"] = to_string(tx.signature().v + 27); + txObject["to"] = toString(tx.receiveAddress()); + txObject["value"] = toString(tx.value()); + + txArray.push_back(txObject); } + o["transactions"] = txArray; + o["rlp"] = "0x" + toHex(state.blockData()); // write block header @@ -215,7 +264,7 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) bc.import(blockRLP, state.db()); state.sync(bc); } - // if exception is thrown, RLP is invalid and not blockHeader, Transaction list, and Uncle list should be given + // if exception is thrown, RLP is invalid and no blockHeader, Transaction list, or Uncle list should be given catch (Exception const& _e) { cnote << "state sync or block import did throw an exception: " << diagnostic_information(_e); @@ -238,18 +287,13 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) BOOST_CHECK(o.count("uncleHeaders") == 0); } - - // if yes, check parameters in blockHeader - // check transaction list - // check uncle list - BOOST_REQUIRE(o.count("blockHeader") > 0); mObject tObj = o["blockHeader"].get_obj(); BlockInfo blockHeaderFromFields; - const bytes rlpBytesBlockHeader = createBlockRLPFromFields(tObj); - RLP blockHeaderRLP(rlpBytesBlockHeader); - blockHeaderFromFields.populateFromHeader(blockHeaderRLP, false); + const bytes c_rlpBytesBlockHeader = createBlockRLPFromFields(tObj); + const RLP c_blockHeaderRLP(c_rlpBytesBlockHeader); + blockHeaderFromFields.populateFromHeader(c_blockHeaderRLP, false); BlockInfo blockFromRlp = bc.info(); @@ -294,16 +338,14 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) } Transactions txsFromRlp; - bytes blockRLP2 = importByteArray(o["rlp"].get_str()); - RLP root(blockRLP2); + bytes blockRLP = importByteArray(o["rlp"].get_str()); + RLP root(blockRLP); for (auto const& tr: root[1]) { Transaction tx(tr.data(), CheckSignature::Sender); txsFromRlp.push_back(tx); } - cout << "size of pending transactions: " << txsFromRlp.size() << endl; - BOOST_CHECK_MESSAGE(txsFromRlp.size() == txsFromField.size(), "transaction list size does not match"); for (size_t i = 0; i < txsFromField.size(); ++i) From a98c86f797ea427ef96bc21c717198aff46eae6c Mon Sep 17 00:00:00 2001 From: arkpar Date: Thu, 12 Feb 2015 20:08:01 +0100 Subject: [PATCH 121/213] added web3 to deploy object --- mix/qml/Debugger.qml | 2 +- mix/qml/html/WebContainer.html | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/mix/qml/Debugger.qml b/mix/qml/Debugger.qml index 2bf23ccef..61bf5e8cc 100644 --- a/mix/qml/Debugger.qml +++ b/mix/qml/Debugger.qml @@ -426,7 +426,7 @@ Rectangle { Layout.minimumHeight: parent.height Text { anchors.centerIn: parent - anchors.leftMargin: 5() + anchors.leftMargin: 5 font.family: "monospace" color: "#4a4a4a" text: styleData.row; diff --git a/mix/qml/html/WebContainer.html b/mix/qml/html/WebContainer.html index e48668041..372860209 100644 --- a/mix/qml/html/WebContainer.html +++ b/mix/qml/html/WebContainer.html @@ -24,7 +24,8 @@ updateContract = function(address, contractFace) { window.deploy = { contractAddress: address, contractInterface: contractFace, - contract: window.contract + contract: window.contract, + web3: window.web3 }; } }; From 02f2070ddb1fa7e6ee07e1f6fe9ffb95151c785b Mon Sep 17 00:00:00 2001 From: Christian Date: Thu, 12 Feb 2015 18:38:07 +0100 Subject: [PATCH 122/213] Copying structs. --- libsolidity/AST.cpp | 6 +- libsolidity/ExpressionCompiler.cpp | 165 ++++++++++++++----------- libsolidity/ExpressionCompiler.h | 33 ++--- libsolidity/Types.cpp | 2 +- test/SolidityEndToEndTest.cpp | 60 +++++++++ test/SolidityNameAndTypeResolution.cpp | 2 +- 6 files changed, 175 insertions(+), 93 deletions(-) diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp index 33cf8c12d..3c6b6007c 100644 --- a/libsolidity/AST.cpp +++ b/libsolidity/AST.cpp @@ -402,10 +402,8 @@ void Assignment::checkTypeRequirements() { m_leftHandSide->checkTypeRequirements(); m_leftHandSide->requireLValue(); - //@todo later, assignments to structs might be possible, but not to mappings - if (m_leftHandSide->getType()->getCategory() != Type::Category::ByteArray && - !m_leftHandSide->getType()->isValueType() && !m_leftHandSide->isLocalLValue()) - BOOST_THROW_EXCEPTION(createTypeError("Assignment to non-local non-value lvalue.")); + if (m_leftHandSide->getType()->getCategory() == Type::Category::Mapping) + BOOST_THROW_EXCEPTION(createTypeError("Mappings cannot be assigned to.")); m_type = m_leftHandSide->getType(); if (m_assigmentOperator == Token::Assign) m_rightHandSide->expectType(*m_type); diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index 3dbb4012d..90f860a1e 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -70,12 +70,12 @@ bool ExpressionCompiler::visit(Assignment const& _assignment) solAssert(_assignment.getType()->isValueType(), "Compound operators not implemented for non-value types."); if (m_currentLValue.storesReferenceOnStack()) m_context << eth::Instruction::SWAP1 << eth::Instruction::DUP2; - m_currentLValue.retrieveValue(_assignment.getType(), _assignment.getLocation(), true); + m_currentLValue.retrieveValue(_assignment.getLocation(), true); appendOrdinaryBinaryOperatorCode(Token::AssignmentToBinaryOp(op), *_assignment.getType()); if (m_currentLValue.storesReferenceOnStack()) m_context << eth::Instruction::SWAP1; } - m_currentLValue.storeValue(_assignment, *_assignment.getRightHandSide().getType()); + m_currentLValue.storeValue(*_assignment.getRightHandSide().getType(), _assignment.getLocation()); m_currentLValue.reset(); return false; @@ -105,13 +105,13 @@ bool ExpressionCompiler::visit(UnaryOperation const& _unaryOperation) break; case Token::Delete: // delete solAssert(m_currentLValue.isValid(), "LValue not retrieved."); - m_currentLValue.setToZero(_unaryOperation, *_unaryOperation.getSubExpression().getType()); + m_currentLValue.setToZero(_unaryOperation.getLocation()); m_currentLValue.reset(); break; case Token::Inc: // ++ (pre- or postfix) case Token::Dec: // -- (pre- or postfix) solAssert(m_currentLValue.isValid(), "LValue not retrieved."); - m_currentLValue.retrieveValue(_unaryOperation.getType(), _unaryOperation.getLocation()); + m_currentLValue.retrieveValue(_unaryOperation.getLocation()); if (!_unaryOperation.isPrefixOperation()) { if (m_currentLValue.storesReferenceOnStack()) @@ -128,7 +128,8 @@ bool ExpressionCompiler::visit(UnaryOperation const& _unaryOperation) // Stack for postfix: *ref [ref] (*ref)+-1 if (m_currentLValue.storesReferenceOnStack()) m_context << eth::Instruction::SWAP1; - m_currentLValue.storeValue(_unaryOperation, *_unaryOperation.getType(), !_unaryOperation.isPrefixOperation()); + m_currentLValue.storeValue(*_unaryOperation.getType(), _unaryOperation.getLocation(), + !_unaryOperation.isPrefixOperation()); m_currentLValue.reset(); break; case Token::Add: // + @@ -484,7 +485,7 @@ void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess) { StructType const& type = dynamic_cast(*_memberAccess.getExpression().getType()); m_context << type.getStorageOffsetOfMember(member) << eth::Instruction::ADD; - m_currentLValue = LValue(m_context, LValue::LValueType::Storage, *_memberAccess.getType()); + m_currentLValue = LValue(m_context, LValue::LValueType::Storage, _memberAccess.getType()); m_currentLValue.retrieveValueIfLValueNotRequested(_memberAccess); break; } @@ -530,7 +531,7 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess) appendTypeMoveToMemory(IntegerType(256)); m_context << u256(0) << eth::Instruction::SHA3; - m_currentLValue = LValue(m_context, LValue::LValueType::Storage, *_indexAccess.getType()); + m_currentLValue = LValue(m_context, LValue::LValueType::Storage, _indexAccess.getType()); m_currentLValue.retrieveValueIfLValueNotRequested(_indexAccess); return false; @@ -939,8 +940,8 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const& m_context << eth::Instruction::DUP1 << structType->getStorageOffsetOfMember(names[i]) << eth::Instruction::ADD; - m_currentLValue = LValue(m_context, LValue::LValueType::Storage, *types[i]); - m_currentLValue.retrieveValue(types[i], Location(), true); + m_currentLValue = LValue(m_context, LValue::LValueType::Storage, types[i]); + m_currentLValue.retrieveValue(Location(), true); solAssert(types[i]->getSizeOnStack() == 1, "Returning struct elements with stack size != 1 not yet implemented."); m_context << eth::Instruction::SWAP1; retSizeOnStack += types[i]->getSizeOnStack(); @@ -951,27 +952,51 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const& { // simple value solAssert(accessorType.getReturnParameterTypes().size() == 1, ""); - m_currentLValue = LValue(m_context, LValue::LValueType::Storage, *returnType); - m_currentLValue.retrieveValue(returnType, Location(), true); + m_currentLValue = LValue(m_context, LValue::LValueType::Storage, returnType); + m_currentLValue.retrieveValue(Location(), true); retSizeOnStack = returnType->getSizeOnStack(); } solAssert(retSizeOnStack <= 15, "Stack too deep."); m_context << eth::dupInstruction(retSizeOnStack + 1) << eth::Instruction::JUMP; } -ExpressionCompiler::LValue::LValue(CompilerContext& _compilerContext, LValueType _type, Type const& _dataType, - unsigned _baseStackOffset): - m_context(&_compilerContext), m_type(_type), m_baseStackOffset(_baseStackOffset) +ExpressionCompiler::LValue::LValue(CompilerContext& _compilerContext, LValueType _type, + TypePointer const& _dataType, unsigned _baseStackOffset): + m_context(&_compilerContext), m_type(_type), m_dataType(_dataType), + m_baseStackOffset(_baseStackOffset) { //@todo change the type cast for arrays - solAssert(_dataType.getStorageSize() <= numeric_limits::max(), "The storage size of " +_dataType.toString() + " should fit in unsigned"); + solAssert(m_dataType->getStorageSize() <= numeric_limits::max(), + "The storage size of " + m_dataType->toString() + " should fit in unsigned"); if (m_type == LValueType::Storage) - m_size = unsigned(_dataType.getStorageSize()); + m_size = unsigned(m_dataType->getStorageSize()); else - m_size = unsigned(_dataType.getSizeOnStack()); + m_size = unsigned(m_dataType->getSizeOnStack()); } -void ExpressionCompiler::LValue::retrieveValue(TypePointer const& _type, Location const& _location, bool _remove) const +void ExpressionCompiler::LValue::fromIdentifier(Identifier const& _identifier, Declaration const& _declaration) +{ + if (m_context->isLocalVariable(&_declaration)) + { + m_type = LValueType::Stack; + m_dataType = _identifier.getType(); + m_size = m_dataType->getSizeOnStack(); + m_baseStackOffset = m_context->getBaseStackOffsetOfVariable(_declaration); + } + else if (m_context->isStateVariable(&_declaration)) + { + *m_context << m_context->getStorageLocationOfVariable(_declaration); + m_type = LValueType::Storage; + m_dataType = _identifier.getType(); + solAssert(m_dataType->getStorageSize() <= numeric_limits::max(), + "The storage size of " + m_dataType->toString() + " should fit in an unsigned"); + m_size = unsigned(m_dataType->getStorageSize()); } + else + BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_sourceLocation(_identifier.getLocation()) + << errinfo_comment("Identifier type not supported or identifier not found.")); +} + +void ExpressionCompiler::LValue::retrieveValue(Location const& _location, bool _remove) const { switch (m_type) { @@ -986,10 +1011,10 @@ void ExpressionCompiler::LValue::retrieveValue(TypePointer const& _type, Locatio break; } case LValueType::Storage: - retrieveValueFromStorage(_type, _remove); + retrieveValueFromStorage(_remove); break; case LValueType::Memory: - if (!_type->isValueType()) + if (!m_dataType->isValueType()) break; // no distinction between value and reference for non-value types BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_sourceLocation(_location) << errinfo_comment("Location type not yet implemented.")); @@ -1001,9 +1026,9 @@ void ExpressionCompiler::LValue::retrieveValue(TypePointer const& _type, Locatio } } -void ExpressionCompiler::LValue::retrieveValueFromStorage(TypePointer const& _type, bool _remove) const +void ExpressionCompiler::LValue::retrieveValueFromStorage(bool _remove) const { - if (!_type->isValueType()) + if (!m_dataType->isValueType()) return; // no distinction between value and reference for non-value types if (!_remove) *m_context << eth::Instruction::DUP1; @@ -1020,7 +1045,7 @@ void ExpressionCompiler::LValue::retrieveValueFromStorage(TypePointer const& _ty } } -void ExpressionCompiler::LValue::storeValue(Expression const& _expression, Type const& _sourceType, bool _move) const +void ExpressionCompiler::LValue::storeValue(Type const& _sourceType, Location const& _location, bool _move) const { switch (m_type) { @@ -1028,23 +1053,23 @@ void ExpressionCompiler::LValue::storeValue(Expression const& _expression, Type { unsigned stackDiff = m_context->baseToCurrentStackOffset(unsigned(m_baseStackOffset)) - m_size + 1; if (stackDiff > 16) - BOOST_THROW_EXCEPTION(CompilerError() << errinfo_sourceLocation(_expression.getLocation()) + BOOST_THROW_EXCEPTION(CompilerError() << errinfo_sourceLocation(_location) << errinfo_comment("Stack too deep.")); else if (stackDiff > 0) for (unsigned i = 0; i < m_size; ++i) *m_context << eth::swapInstruction(stackDiff) << eth::Instruction::POP; if (!_move) - retrieveValue(_expression.getType(), _expression.getLocation()); + retrieveValue(_location); break; } case LValueType::Storage: // stack layout: value value ... value target_ref - if (_expression.getType()->isValueType()) + if (m_dataType->isValueType()) { if (!_move) // copy values { if (m_size + 1 > 16) - BOOST_THROW_EXCEPTION(CompilerError() << errinfo_sourceLocation(_expression.getLocation()) + BOOST_THROW_EXCEPTION(CompilerError() << errinfo_sourceLocation(_location) << errinfo_comment("Stack too deep.")); for (unsigned i = 0; i < m_size; ++i) *m_context << eth::dupInstruction(m_size + 1) << eth::Instruction::SWAP1; @@ -1064,36 +1089,60 @@ void ExpressionCompiler::LValue::storeValue(Expression const& _expression, Type } else { - solAssert(!_move, "Move assign for non-value types not implemented."); - solAssert(_sourceType.getCategory() == _expression.getType()->getCategory(), ""); - if (_expression.getType()->getCategory() == Type::Category::ByteArray) + solAssert(_sourceType.getCategory() == m_dataType->getCategory(), ""); + if (m_dataType->getCategory() == Type::Category::ByteArray) CompilerUtils(*m_context).copyByteArrayToStorage( - dynamic_cast(*_expression.getType()), + dynamic_cast(*m_dataType), dynamic_cast(_sourceType)); - else if (_expression.getType()->getCategory() == Type::Category::Struct) + else if (m_dataType->getCategory() == Type::Category::Struct) { - //@todo - solAssert(false, "Struct copy not yet implemented."); + // stack layout: source_ref target_ref + auto const& structType = dynamic_cast(*m_dataType); + solAssert(structType == _sourceType, "Struct assignment with conversion."); + for (auto const& member: structType.getMembers()) + { + // assign each member that is not a mapping + TypePointer const& memberType = member.second; + if (memberType->getCategory() == Type::Category::Mapping) + continue; + *m_context << structType.getStorageOffsetOfMember(member.first) + << eth::Instruction::DUP3 << eth::Instruction::DUP2 + << eth::Instruction::ADD; + LValue rightHandSide(*m_context, LValueType::Storage, memberType); + rightHandSide.retrieveValue(_location, true); + // stack: source_ref target_ref offset source_value... + *m_context << eth::dupInstruction(2 + memberType->getSizeOnStack()) + << eth::dupInstruction(2 + memberType->getSizeOnStack()) + << eth::Instruction::ADD; + LValue memberLValue(*m_context, LValueType::Storage, memberType); + memberLValue.storeValue(*memberType, _location, true); + *m_context << eth::Instruction::POP; + } + if (_move) + *m_context << eth::Instruction::POP; + else + *m_context << eth::Instruction::SWAP1; + *m_context << eth::Instruction::POP; } else - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_sourceLocation(_expression.getLocation()) + BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_sourceLocation(_location) << errinfo_comment("Invalid non-value type for assignment.")); } break; case LValueType::Memory: - if (!_expression.getType()->isValueType()) + if (!m_dataType->isValueType()) break; // no distinction between value and reference for non-value types - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_sourceLocation(_expression.getLocation()) + BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_sourceLocation(_location) << errinfo_comment("Location type not yet implemented.")); break; default: - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_sourceLocation(_expression.getLocation()) + BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_sourceLocation(_location) << errinfo_comment("Unsupported location type.")); break; } } -void ExpressionCompiler::LValue::setToZero(Expression const& _expression, Type const& _type) const +void ExpressionCompiler::LValue::setToZero(Location const& _location) const { switch (m_type) { @@ -1101,7 +1150,7 @@ void ExpressionCompiler::LValue::setToZero(Expression const& _expression, Type c { unsigned stackDiff = m_context->baseToCurrentStackOffset(unsigned(m_baseStackOffset)); if (stackDiff > 16) - BOOST_THROW_EXCEPTION(CompilerError() << errinfo_sourceLocation(_expression.getLocation()) + BOOST_THROW_EXCEPTION(CompilerError() << errinfo_sourceLocation(_location) << errinfo_comment("Stack too deep.")); solAssert(stackDiff >= m_size - 1, ""); for (unsigned i = 0; i < m_size; ++i) @@ -1110,8 +1159,8 @@ void ExpressionCompiler::LValue::setToZero(Expression const& _expression, Type c break; } case LValueType::Storage: - if (_type.getCategory() == Type::Category::ByteArray) - CompilerUtils(*m_context).clearByteArray(dynamic_cast(_type)); + if (m_dataType->getCategory() == Type::Category::ByteArray) + CompilerUtils(*m_context).clearByteArray(dynamic_cast(*m_dataType)); else { if (m_size == 0) @@ -1125,11 +1174,11 @@ void ExpressionCompiler::LValue::setToZero(Expression const& _expression, Type c } break; case LValueType::Memory: - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_sourceLocation(_expression.getLocation()) + BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_sourceLocation(_location) << errinfo_comment("Location type not yet implemented.")); break; default: - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_sourceLocation(_expression.getLocation()) + BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_sourceLocation(_location) << errinfo_comment("Unsupported location type.")); break; } @@ -1139,36 +1188,10 @@ void ExpressionCompiler::LValue::retrieveValueIfLValueNotRequested(Expression co { if (!_expression.lvalueRequested()) { - retrieveValue(_expression.getType(), _expression.getLocation(), true); + retrieveValue(_expression.getLocation(), true); reset(); } } -void ExpressionCompiler::LValue::fromStateVariable(Declaration const& _varDecl, TypePointer const& _type) -{ - m_type = LValueType::Storage; - solAssert(_type->getStorageSize() <= numeric_limits::max(), "The storage size of " + _type->toString() + " should fit in an unsigned"); - *m_context << m_context->getStorageLocationOfVariable(_varDecl); - m_size = unsigned(_type->getStorageSize()); -} - -void ExpressionCompiler::LValue::fromIdentifier(Identifier const& _identifier, Declaration const& _declaration) -{ - if (m_context->isLocalVariable(&_declaration)) - { - m_type = LValueType::Stack; - m_size = _identifier.getType()->getSizeOnStack(); - m_baseStackOffset = m_context->getBaseStackOffsetOfVariable(_declaration); - } - else if (m_context->isStateVariable(&_declaration)) - { - fromStateVariable(_declaration, _identifier.getType()); - } - else - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_sourceLocation(_identifier.getLocation()) - << errinfo_comment("Identifier type not supported or identifier not found.")); -} - - } } diff --git a/libsolidity/ExpressionCompiler.h b/libsolidity/ExpressionCompiler.h index e0cc75ce8..734da50de 100644 --- a/libsolidity/ExpressionCompiler.h +++ b/libsolidity/ExpressionCompiler.h @@ -22,8 +22,10 @@ */ #include +#include #include #include +#include #include namespace dev { @@ -37,6 +39,7 @@ namespace solidity { class CompilerContext; class Type; class IntegerType; +class ByteArrayType; class StaticStringType; /** @@ -119,14 +122,13 @@ private: enum class LValueType { None, Stack, Memory, Storage }; explicit LValue(CompilerContext& _compilerContext): m_context(&_compilerContext) { reset(); } - LValue(CompilerContext& _compilerContext, LValueType _type, Type const& _dataType, unsigned _baseStackOffset = 0); + LValue(CompilerContext& _compilerContext, LValueType _type, + std::shared_ptr const& _dataType, unsigned _baseStackOffset = 0); /// Set type according to the declaration and retrieve the reference. /// @a _expression is the current expression void fromIdentifier(Identifier const& _identifier, Declaration const& _declaration); - /// Convenience function to set type for a state variable and retrieve the reference - void fromStateVariable(Declaration const& _varDecl, TypePointer const& _type); - void reset() { m_type = LValueType::None; m_baseStackOffset = 0; m_size = 0; } + void reset() { m_type = LValueType::None; m_dataType.reset(); m_baseStackOffset = 0; m_size = 0; } bool isValid() const { return m_type != LValueType::None; } bool isInOnStack() const { return m_type == LValueType::Stack; } @@ -138,30 +140,29 @@ private: /// Copies the value of the current lvalue to the top of the stack and, if @a _remove is true, /// also removes the reference from the stack (note that is does not reset the type to @a NONE). - /// @a _type is the type of the current expression and @ _location its location, used for error reporting. - /// @a _location can be a nullptr for expressions that don't have an actual ASTNode equivalent - void retrieveValue(TypePointer const& _type, Location const& _location, bool _remove = false) const; - /// Stores a value (from the stack directly beneath the reference, which is assumed to - /// be on the top of the stack, if any) in the lvalue and removes the reference. - /// Also removes the stored value from the stack if @a _move is - /// true. @a _expression is the current expression, used for error reporting. - /// @a _sourceType is the type of the expression that is assigned. - void storeValue(Expression const& _expression, Type const& _sourceType, bool _move = false) const; + /// @a _location source location of the current expression, used for error reporting. + void retrieveValue(Location const& _location, bool _remove = false) const; + /// Moves a value from the stack to the lvalue. Removes the value if @a _move is true. + /// @a _location is the source location of the expression that caused this operation. + /// Stack pre: [lvalue_ref] value + /// Stack post if !_move: value_of(lvalue_ref) + void storeValue(Type const& _sourceType, Location const& _location = Location(), bool _move = false) const; /// Stores zero in the lvalue. - /// @a _expression is the current expression, used for error reporting. - void setToZero(Expression const& _expression, Type const& _type) const; + /// @a _location is the source location of the requested operation + void setToZero(Location const& _location = Location()) const; /// Convenience function to convert the stored reference to a value and reset type to NONE if /// the reference was not requested by @a _expression. void retrieveValueIfLValueNotRequested(Expression const& _expression); private: /// Convenience function to retrieve Value from Storage. Specific version of @ref retrieveValue - void retrieveValueFromStorage(TypePointer const& _type, bool _remove = false) const; + void retrieveValueFromStorage(bool _remove = false) const; /// Copies from a byte array to a byte array in storage, both references on the stack. void copyByteArrayToStorage(ByteArrayType const& _targetType, ByteArrayType const& _sourceType) const; CompilerContext* m_context; LValueType m_type = LValueType::None; + std::shared_ptr m_dataType; /// If m_type is STACK, this is base stack offset (@see /// CompilerContext::getBaseStackOffsetOfVariable) of a local variable. unsigned m_baseStackOffset = 0; diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index 33cc8a1ec..16514b148 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -653,7 +653,7 @@ u256 StructType::getStorageOffsetOfMember(string const& _name) const { //@todo cache member offset? u256 offset; - for (ASTPointer variable: m_struct.getMembers()) + for (ASTPointer const& variable: m_struct.getMembers()) { if (variable->getName() == _name) return offset; diff --git a/test/SolidityEndToEndTest.cpp b/test/SolidityEndToEndTest.cpp index 587d4193f..abfc97b73 100644 --- a/test/SolidityEndToEndTest.cpp +++ b/test/SolidityEndToEndTest.cpp @@ -2424,6 +2424,66 @@ BOOST_AUTO_TEST_CASE(bytes_length_member) BOOST_CHECK(callContractFunction("getLength()") == encodeArgs(4+32+32)); } +BOOST_AUTO_TEST_CASE(struct_copy) +{ + char const* sourceCode = R"( + contract c { + struct Nested { uint x; uint y; } + struct Struct { uint a; mapping(uint => Struct) b; Nested nested; uint c; } + mapping(uint => Struct) public data; + function set(uint k) returns (bool) { + data[k].a = 1; + data[k].nested.x = 3; + data[k].nested.y = 4; + data[k].c = 2; + return true; + } + function copy(uint from, uint to) returns (bool) { + data[to] = data[from]; + return true; + } + function retrieve(uint k) returns (uint a, uint x, uint y, uint c) + { + a = data[k].a; + x = data[k].nested.x; + y = data[k].nested.y; + c = data[k].c; + } + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("set(uint256)", 7) == encodeArgs(true)); + BOOST_CHECK(callContractFunction("retrieve(uint256)", 7) == encodeArgs(1, 3, 4, 2)); + BOOST_CHECK(callContractFunction("copy(uint256,uint256)", 7, 8) == encodeArgs(true)); + BOOST_CHECK(callContractFunction("retrieve(uint256)", 7) == encodeArgs(1, 3, 4, 2)); + BOOST_CHECK(callContractFunction("retrieve(uint256)", 8) == encodeArgs(1, 3, 4, 2)); + BOOST_CHECK(callContractFunction("copy(uint256,uint256)", 0, 7) == encodeArgs(true)); + BOOST_CHECK(callContractFunction("retrieve(uint256)", 7) == encodeArgs(0, 0, 0, 0)); + BOOST_CHECK(callContractFunction("retrieve(uint256)", 8) == encodeArgs(1, 3, 4, 2)); + BOOST_CHECK(callContractFunction("copy(uint256,uint256)", 7, 8) == encodeArgs(true)); + BOOST_CHECK(callContractFunction("retrieve(uint256)", 8) == encodeArgs(0, 0, 0, 0)); +} + +BOOST_AUTO_TEST_CASE(struct_copy_via_local) +{ + char const* sourceCode = R"( + contract c { + struct Struct { uint a; uint b; } + Struct data1; + Struct data2; + function test() returns (bool) { + data1.a = 1; + data1.b = 2; + var x = data1; + data2 = x; + return data2.a == data1.a && data2.b == data1.b; + } + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("test()") == encodeArgs(true)); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/SolidityNameAndTypeResolution.cpp b/test/SolidityNameAndTypeResolution.cpp index d013f5c5e..3ead6f1c5 100644 --- a/test/SolidityNameAndTypeResolution.cpp +++ b/test/SolidityNameAndTypeResolution.cpp @@ -332,7 +332,7 @@ BOOST_AUTO_TEST_CASE(assignment_to_struct) " data = a;\n" " }\n" "}\n"; - BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); + BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); } BOOST_AUTO_TEST_CASE(returns_in_constructor) From f18c2aa378fd60a977649480bb3cd9fa80e77ddc Mon Sep 17 00:00:00 2001 From: winsvega Date: Thu, 12 Feb 2015 22:26:10 +0300 Subject: [PATCH 123/213] New Tests Solidity test Transaction test update --- test/stSolidityTestFiller.json | 237 ++++++++++++++++++++++++++++++ test/state.cpp | 5 + test/ttTransactionTestFiller.json | 70 ++++++--- 3 files changed, 292 insertions(+), 20 deletions(-) create mode 100644 test/stSolidityTestFiller.json diff --git a/test/stSolidityTestFiller.json b/test/stSolidityTestFiller.json new file mode 100644 index 000000000..fc0770c5e --- /dev/null +++ b/test/stSolidityTestFiller.json @@ -0,0 +1,237 @@ +{ + "SolidityTest" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1000000000000000000000", + "currentNumber" : "120", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000000000", + "code" : "", + "nonce" : "0", + "storage" : { + } + }, + + "d94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "100000", + "//" : " ", + "//" : "contract TestContract ", + "//" : "{ ", + "//" : " function testMethod() returns (int res) ", + "//" : " { ", + "//" : " return 225; ", + "//" : " } ", + "//" : " ", + "//" : " function destroy(address sendFoundsTo) ", + "//" : " { ", + "//" : " suicide(sendFoundsTo); ", + "//" : " } ", + "//" : "} ", + "//" : " ", + "//" : "contract TestSolidityContracts ", + "//" : "{ ", + "//" : "struct StructTest ", + "//" : " { ", + "//" : " address addr; ", + "//" : " int amount; ", + "//" : " string32 str; ", + "//" : " mapping (uint => address) funders; ", + "//" : " } ", + "//" : " ", + "//" : " int globalValue; ", + "//" : " StructTest globalData; ", + "//" : " function runSolidityTests() returns (hash res) ", + "//" : " { ", + "//" : " //res is a mask of failing tests given the first byte is first test ", + "//" : " res = 0x0000000000000000000000000000000000000000000000000000000000000000; ", + "//" : " ", + "//" : " createContractFromMethod(); ", + "//" : " ", + "//" : " if (!testKeywords()) ", + "//" : " res = hash(int(res) + int(0xf000000000000000000000000000000000000000000000000000000000000000)); ", + "//" : " ", + "//" : " if (!testContractInteraction()) ", + "//" : " res = hash(int(res) + int(0x0f00000000000000000000000000000000000000000000000000000000000000)); ", + "//" : " ", + "//" : " if (!testContractSuicide()) ", + "//" : " res = hash(int(res) + int(0x00f0000000000000000000000000000000000000000000000000000000000000)); ", + "//" : " ", + "//" : " if (!testBlockAndTransactionProperties()) ", + "//" : " res = hash(int(res) + int(0x000f000000000000000000000000000000000000000000000000000000000000)); ", + "//" : " ", + "//" : " globalValue = 255; ", + "//" : " globalData.addr = 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b; ", + "//" : " globalData.amount = 255; ", + "//" : " globalData.str = 'global data 32 length string'; ", + "//" : " globalData.funders[0] = 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b; ", + "//" : " if (!testStructuresAndVariabless()) ", + "//" : " res = hash(int(res) + int(0x0000f00000000000000000000000000000000000000000000000000000000000)); ", + "//" : " ", + "//" : " //Tested 27.01.2015 ", + "//" : " //should run out of gas ", + "//" : " //if (!testInfiniteLoop()) ", + "//" : " // res = hash(int(res) + int(0x000f000000000000000000000000000000000000000000000000000000000000)); ", + "//" : " // ", + "//" : " //should run out of gas ", + "//" : " //if (!testRecursiveMethods()) ", + "//" : " // res = hash(int(res) + int(0x0000000000000000000000000000000000000000000000000000000000000000)); ", + "//" : " } ", + "//" : " ", + "//" : " function testStructuresAndVariabless() returns (bool res) ", + "//" : " { ", + "//" : " res = true; ", + "//" : " if (globalValue != 255) ", + "//" : " return false; ", + "//" : " ", + "//" : " if (globalValue != globalData.amount) ", + "//" : " return false; ", + "//" : " ", + "//" : " if (globalData.addr != 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b) ", + "//" : " return false; ", + "//" : " ", + "//" : " if (globalData.str != 'global data 32 length string') ", + "//" : " return false; ", + "//" : " ", + "//" : " if (globalData.funders[0] != 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b) ", + "//" : " return false; ", + "//" : " } ", + "//" : " ", + "//" : " function testBlockAndTransactionProperties() returns (bool res) ", + "//" : " { ", + "//" : " res = true; ", + "//" : " if (block.coinbase != 0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba) ", + "//" : " return false; ", + "//" : " ", + "//" : " if (block.difficulty != 45678256) ", + "//" : " return false; ", + "//" : " ", + "//" : " //for some reason does not work 27.01.2015 ", + "//" : " //if (block.gaslimit != 1000000000000000000000) ", + "//" : " // return false; ", + "//" : " ", + "//" : " if (block.number != 120) ", + "//" : " return false; ", + "//" : " ", + "//" : " //try to call this ", + "//" : " block.blockhash(120); ", + "//" : " block.timestamp; ", + "//" : " msg.gas; ", + "//" : " ", + "//" : " if (msg.sender != 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b) ", + "//" : " return false; ", + "//" : " ", + "//" : " if (msg.value != 100) ", + "//" : " return false; ", + "//" : " ", + "//" : " if (tx.gasprice != 1) ", + "//" : " return false; ", + "//" : " ", + "//" : " if (tx.origin != 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b) ", + "//" : " return false; ", + "//" : " ", + "//" : " } ", + "//" : " ", + "//" : " function testInfiniteLoop() returns (bool res) ", + "//" : " { ", + "//" : " res = false; ", + "//" : " while(true){} ", + "//" : " return true; ", + "//" : " } ", + "//" : " ", + "//" : " function testRecursiveMethods() returns (bool res) ", + "//" : " { ", + "//" : " res = false; ", + "//" : " testRecursiveMethods2(); ", + "//" : " return true; ", + "//" : " } ", + "//" : " function testRecursiveMethods2() ", + "//" : " { ", + "//" : " testRecursiveMethods(); ", + "//" : "} ", + "//" : " ", + "//" : " ", + "//" : " function testContractSuicide() returns (bool res) ", + "//" : " { ", + "//" : " TestContract a = new TestContract(); ", + "//" : " a.destroy(block.coinbase); ", + "//" : " if (a.testMethod() == 225) //we should be able to call a contract ", + "//" : " return true; ", + "//" : " return false; ", + "//" : " } ", + "//" : " ", + "//" : " function testContractInteraction() returns (bool res) ", + "//" : " { ", + "//" : " TestContract a = new TestContract(); ", + "//" : " if (a.testMethod() == 225) ", + "//" : " return true; ", + "//" : " return false; ", + "//" : " } ", + "//" : " ", + "//" : " function testKeywords() returns (bool res) ", + "//" : " { ", + "//" : " //some simple checks for the if statemnt ", + "//" : " //if, else, while, for, break, continue, return ", + "//" : " int i = 0; ", + "//" : " res = false; ", + "//" : " ", + "//" : " if (i == 0) ", + "//" : " { ", + "//" : " if( i <= -25) ", + "//" : " { ", + "//" : " return false; ", + "//" : " } ", + "//" : " else ", + "//" : " { ", + "//" : " while(i < 10) ", + "//" : " i++; ", + "//" : " ", + "//" : " if (i == 10) ", + "//" : " { ", + "//" : " for(var j=10; j>0; j--) ", + "//" : " { ", + "//" : " i--; ", + "//" : " } ", + "//" : " } ", + "//" : " } ", + "//" : " } ", + "//" : " ", + "//" : " ", + "//" : " if (i == 0) ", + "//" : " return true; ", + "//" : " ", + "//" : " return false; ", + "//" : " } ", + "//" : " ", + "//" : " function createContractFromMethod() returns (TestContract a) ", + "//" : " { ", + "//" : " a = new TestContract(); ", + "//" : " } ", + "//" : "} ", + "code" : "0x60e060020a6000350480630c4c9a8014610078578063296df0df1461008a5780632a9afb831461009c578063380e4396146100ae5780634893d88a146100c05780637ee17e12146100ce578063981a3165146100dc578063a60eedda146100ee578063e97384dc14610100578063ed973fe91461011257005b610080610431565b8060005260206000f35b6100926103f7565b8060005260206000f35b6100a46105d1565b8060005260206000f35b6100b6610220565b8060005260206000f35b6100c8610426565b60006000f35b6100d66102df565b60006000f35b6100e4610411565b8060005260206000f35b6100f6610124565b8060005260206000f35b6101086102f5565b8060005260206000f35b61011a6101be565b8060005260206000f35b60006000605f6106be600039605f60006000f0905080600160a060020a031662f55d9d8060e060020a0260005241600160a060020a0316600452600060006024600060008660155a03f150505080600160a060020a031663b9c3d0a58060e060020a02600052602060006004600060008660155a03f150505060005160e1146101ac576101b5565b600191506101ba565b600091505b5090565b60006000605f6106be600039605f60006000f0905080600160a060020a031663b9c3d0a58060e060020a02600052602060006004600060008660155a03f150505060005160e11461020e57610217565b6001915061021c565b600091505b5090565b60006000600060009150600092508160001461023b576102bf565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe78213156102b5575b600a82121561027a578180600101925050610264565b81600a14610287576102b0565b600a90505b60008160ff1611156102af5781806001900392505080806001900391505061028c565b5b6102be565b600092506102da565b5b816000146102cc576102d5565b600192506102da565b600092505b505090565b6000605f6106be600039605f60006000f0905090565b60006001905041600160a060020a0316732adc25665018aa1fe0e6bc666dac8fc2697ff9ba14156103255761032e565b600090506103f4565b446302b8feb0141561033f57610348565b600090506103f4565b43607814156103565761035f565b600090506103f4565b33600160a060020a031673a94f5374fce5edbc8e2a8697c15331677e6ebf0b141561038957610392565b600090506103f4565b34606414156103a0576103a9565b600090506103f4565b3a600114156103b7576103c0565b600090506103f4565b32600160a060020a031673a94f5374fce5edbc8e2a8697c15331677e6ebf0b14156103ea576103f3565b600090506103f4565b5b90565b6000600090505b60011561040a576103fe565b6001905090565b60006000905061041f610426565b6001905090565b61042e610411565b50565b60006000905061043f6102df565b50610448610220565b1561045257610478565b7ff000000000000000000000000000000000000000000000000000000000000000810190505b6104806101be565b1561048a576104b0565b7f0f00000000000000000000000000000000000000000000000000000000000000810190505b6104b8610124565b156104c2576104e7565b7ef0000000000000000000000000000000000000000000000000000000000000810190505b6104ef6102f5565b156104f95761051e565b7e0f000000000000000000000000000000000000000000000000000000000000810190505b60ff60008190555073a94f5374fce5edbc8e2a8697c15331677e6ebf0b60018190555060ff6002819055507f676c6f62616c2064617461203332206c656e67746820737472696e670000000060038190555073a94f5374fce5edbc8e2a8697c15331677e6ebf0b600460006000526020526040600020819055506105a06105d1565b156105aa576105ce565b7df00000000000000000000000000000000000000000000000000000000000810190505b90565b60006001905060005460ff14156105e7576105f0565b600090506106ba565b60025460005414156106015761060a565b600090506106ba565b600154600160a060020a031673a94f5374fce5edbc8e2a8697c15331677e6ebf0b14156106365761063f565b600090506106ba565b6003547f676c6f62616c2064617461203332206c656e67746820737472696e6700000000141561066e57610677565b600090506106ba565b60046000600052602052604060002054600160a060020a031673a94f5374fce5edbc8e2a8697c15331677e6ebf0b14156106b0576106b9565b600090506106ba565b5b905600605380600c6000396000f30060e060020a600035048062f55d9d14601d578063b9c3d0a514602c57005b60266004356045565b60006000f35b6032603c565b8060005260206000f35b600060e1905090565b80600160a060020a0316ff5056", + "nonce" : "0", + "storage" : { + } + } + }, + + "transaction" : + { + "//" : "createContractFromMethod()", + "data" : "0x7ee17e12", + "//" : "runSolidityTests()", + "data" : "0x0c4c9a80", + "gasLimit" : "465224", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "d94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "value" : "100" + } + } +} diff --git a/test/state.cpp b/test/state.cpp index fb54a62ae..03f01d0fb 100644 --- a/test/state.cpp +++ b/test/state.cpp @@ -159,6 +159,11 @@ BOOST_AUTO_TEST_CASE(stBlockHashTest) dev::test::executeTests("stBlockHashTest", "/StateTests", dev::test::doStateTests); } +BOOST_AUTO_TEST_CASE(stSolidityTest) +{ + dev::test::executeTests("stSolidityTest", "/StateTests", dev::test::doStateTests); +} + BOOST_AUTO_TEST_CASE(stCreateTest) { for (int i = 1; i < boost::unit_test::framework::master_test_suite().argc; ++i) diff --git a/test/ttTransactionTestFiller.json b/test/ttTransactionTestFiller.json index 49831261a..e9ae27188 100644 --- a/test/ttTransactionTestFiller.json +++ b/test/ttTransactionTestFiller.json @@ -44,6 +44,21 @@ } }, + "WrongVRSTestIncorrectSize" : { + "transaction" : + { + "data" : "", + "gasLimit" : "2000", + "gasPrice" : "1", + "nonce" : "0", + "to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "value" : "10", + "v" : "28", + "r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a02c3", + "s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a302c3" + } + }, + "SenderTest" : { "//" : "sender a94f5374fce5edbc8e2a8697c15331677e6ebf0b", "transaction" : @@ -196,33 +211,18 @@ } }, - "RLPElementsWithZeros" : { + "AddressMoreThan20PrefixedBy0" : { "transaction" : { - "data" : "0x0000011222333", - "gasLimit" : "1000", - "gasPrice" : "00123", - "nonce" : "0054", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "value" : "00000011", - "v" : "27", - "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", - "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" - } - }, - - "RLPWrongHexElements" : { - "transaction" : - { - "data" : "0x0000000012", + "data" : "0x12", "gasLimit" : "1000", "gasPrice" : "123", "nonce" : "54", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "to" : "0x0000000000000000095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "11", "v" : "27", - "r" : "0x0048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", - "s" : "0x00efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" + "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", + "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" } }, @@ -299,5 +299,35 @@ "r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", "s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" } + }, + + "ValuesAsHex" : { + "transaction" : + { + "data" : "", + "gasLimit" : "0xadc053", + "gasPrice" : "1", + "nonce" : "0xffdc5", + "to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "value" : "0xfffdc12c", + "v" : "28", + "r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", + "s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" + } + }, + + "ValuesAsDec" : { + "transaction" : + { + "data" : "", + "gasLimit" : "11386963", + "gasPrice" : "1", + "nonce" : "1048005", + "to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "value" : "4501151495864620", + "v" : "28", + "r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", + "s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" + } } } From 48dee28af5703c4db78515df60b07446a2b0beff Mon Sep 17 00:00:00 2001 From: arkpar Date: Thu, 12 Feb 2015 20:57:25 +0100 Subject: [PATCH 124/213] 'web3' and 'contracts' for JS context instead of 'deploy' --- mix/qml/WebPreview.qml | 4 ++-- mix/qml/html/WebContainer.html | 16 +++++++--------- mix/qml/js/ProjectModel.js | 14 +++++++------- 3 files changed, 16 insertions(+), 18 deletions(-) diff --git a/mix/qml/WebPreview.qml b/mix/qml/WebPreview.qml index 08f25b3df..10d0b3c83 100644 --- a/mix/qml/WebPreview.qml +++ b/mix/qml/WebPreview.qml @@ -28,7 +28,7 @@ Item { } function updateContract() { - webView.runJavaScript("updateContract(\"" + clientModel.contractAddress + "\", " + codeModel.code.contractInterface + ")"); + webView.runJavaScript("updateContract(\"" + codeModel.code.contract.name + "\", \"" + clientModel.contractAddress + "\", " + codeModel.code.contractInterface + ")"); } function reloadOnSave() { @@ -136,7 +136,7 @@ Item { content = fileIo.readFile(projectModel.getDocument(documentId).path); if (documentId === pageListModel.get(pageCombo.currentIndex).documentId) { //root page, inject deployment script - content = "\n" + content; + content = "\n" + content; _request.setResponseContentType("text/html"); } _request.setResponse(content); diff --git a/mix/qml/html/WebContainer.html b/mix/qml/html/WebContainer.html index 372860209..09a8734d5 100644 --- a/mix/qml/html/WebContainer.html +++ b/mix/qml/html/WebContainer.html @@ -15,17 +15,15 @@ reloadPage = function() { preview.contentWindow.location.reload(); }; -updateContract = function(address, contractFace) { +updateContract = function(name, address, contractFace) { if (window.web3) { window.web3.provider.polls = []; - window.contractAddress = address; - window.contractInterface = contractFace; - window.contract = window.web3.eth.contract(address, contractFace); - window.deploy = { - contractAddress: address, - contractInterface: contractFace, - contract: window.contract, - web3: window.web3 + var contract = window.web3.eth.contract(address, contractFace); + window.contracts = {}; + window.contracts[name] = { + address: address, + interface: contractFace, + contract: contract, }; } }; diff --git a/mix/qml/js/ProjectModel.js b/mix/qml/js/ProjectModel.js index fb6872bd4..be6c07c5b 100644 --- a/mix/qml/js/ProjectModel.js +++ b/mix/qml/js/ProjectModel.js @@ -326,16 +326,16 @@ function finalizeDeployment(deploymentId, address) { fileIo.copyFile(doc.path, deploymentDir + doc.fileName); } //write deployment js + var contractAccessor = "contracts[\"" + codeModel.code.contract.name + "\"]"; var deploymentJs = "// Autogenerated by Mix\n" + - "var web3 = require(\"web3\");\n" + - "var contractInterface = " + codeModel.code.contractInterface + ";\n" + - "deploy = {\n" + - "\tweb3: web3,\n" + - "\tcontractAddress: \"" + address + "\",\n" + - "\tcontractInterface: contractInterface,\n" + + "web3 = require(\"web3\");\n" + + "contracts = {};\n" + + contractAccessor + " = {\n" + + "\tinterface: " + codeModel.code.contractInterface + ",\n" + + "\taddress: \"" + address + "\"\n" + "};\n" + - "deploy.contract = web3.eth.contract(deploy.contractAddress, deploy.contractInterface);\n"; + contractAccessor + ".contract = web3.eth.contract(" + contractAccessor + ".address, " + contractAccessor + ".interface);\n"; fileIo.writeFile(deploymentDir + "deployment.js", deploymentJs); //copy scripts fileIo.copyFile("qrc:///js/bignumber.min.js", deploymentDir + "bignumber.min.js"); From 29abb4fb551f17442955e56160ff86ea4a622892 Mon Sep 17 00:00:00 2001 From: winsvega Date: Thu, 12 Feb 2015 23:43:57 +0300 Subject: [PATCH 125/213] New Tests Transaction with RLP object and catching exceptions from importByteArray --- test/TestHelper.cpp | 2 +- test/stTransactionTestFiller.json | 152 +++++++++++++++++++++++++++++- test/transaction.cpp | 11 ++- 3 files changed, 157 insertions(+), 8 deletions(-) diff --git a/test/TestHelper.cpp b/test/TestHelper.cpp index 8a00a5462..5e7472105 100644 --- a/test/TestHelper.cpp +++ b/test/TestHelper.cpp @@ -247,7 +247,7 @@ byte toByte(json_spirit::mValue const& _v) bytes importByteArray(std::string const& _str) { - return fromHex(_str.substr(0, 2) == "0x" ? _str.substr(2) : _str); + return fromHex(_str.substr(0, 2) == "0x" ? _str.substr(2) : _str, ThrowType::Throw); } bytes importData(json_spirit::mObject& _o) diff --git a/test/stTransactionTestFiller.json b/test/stTransactionTestFiller.json index e5369f0cd..214a0ae7c 100644 --- a/test/stTransactionTestFiller.json +++ b/test/stTransactionTestFiller.json @@ -189,6 +189,53 @@ } }, + "InternalCallHittingGasLimit" : { + "env" : { + "currentCoinbase" : "a94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1100", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000", + "code" : "", + "nonce" : "0", + "storage" : { + } + }, + + "b94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000", + "code" : "{ (CALL 5000 0xc94f5374fce5edbc8e2a8697c15331677e6ebf0b 1 0 0 0 0) }", + "nonce" : "0", + "storage" : { + } + }, + + "c94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0", + "code" : "{[[1]]55}", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "", + "gasLimit" : "1100", + "gasPrice" : "1", + "nonce" : "", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "value" : "10" + } + }, + "TransactionFromCoinbaseHittingBlockGasLimit" : { "env" : { "currentCoinbase" : "a94f5374fce5edbc8e2a8697c15331677e6ebf0b", @@ -623,7 +670,7 @@ "balance" : "100000", "code" : "", "nonce" : "115792089237316195423570985008687907853269984665640564039457584007913129639935", - "nonce" : "10000000", + "nonce" : "10000", "storage" : { } } @@ -634,7 +681,7 @@ "gasLimit" : "1000", "gasPrice" : "1", "nonce" : "115792089237316195423570985008687907853269984665640564039457584007913129639935", - "nonce" : "10000000", + "nonce" : "10000", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", "value" : "100" @@ -864,5 +911,106 @@ "to" : "0xffffffffffffffffffffffffffffffffffffffff", "value" : "100" } + }, + + "CreateTransactionReverted" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1000000000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000", + "code" : "", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "0x602280600c6000396000f30060e060020a600035048063f8a8fd6d14601457005b601a6020565b60006000f35b56", + "gasLimit" : "882", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "", + "value" : "" + } + }, + + "CreateTransactionWorking" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1000000000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000", + "code" : "", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "0x602280600c6000396000f30060e060020a600035048063f8a8fd6d14601457005b601a6020565b60006000f35b56", + "gasLimit" : "883", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "", + "value" : "100" + } + }, + + "CreateMessageReverted" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1000000000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000", + "code" : "", + "nonce" : "0", + "storage" : { + } + }, + + "b94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0", + "code" : "{(MSTORE 0 0x600c600055) (CREATE 0 27 5)}", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "", + "gasLimit" : "882", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "value" : "100" + } } } diff --git a/test/transaction.cpp b/test/transaction.cpp index b51494d84..9f9429534 100644 --- a/test/transaction.cpp +++ b/test/transaction.cpp @@ -64,7 +64,7 @@ RLPStream createRLPStreamFromTransactionFields(mObject& _tObj) rlpStream << bigint(_tObj["r"].get_str()); if (_tObj.count("s") > 0) - rlpStream << bigint(_tObj["s"].get_str()); + rlpStream << bigint(_tObj["s"].get_str()); if (_tObj.count("extrafield") > 0) rlpStream << bigint(_tObj["extrafield"].get_str()); @@ -82,18 +82,18 @@ void doTransactionTests(json_spirit::mValue& _v, bool _fillin) if (_fillin == false) { BOOST_REQUIRE(o.count("rlp") > 0); - bytes rlpReaded = importByteArray(o["rlp"].get_str()); Transaction txFromRlp; - try { - txFromRlp = Transaction(rlpReaded, CheckSignature::Sender); + bytes stream = importByteArray(o["rlp"].get_str()); + RLP rlp(stream); + txFromRlp = Transaction(rlp.data(), CheckSignature::Sender); if (!txFromRlp.signature().isValid()) BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("transaction from RLP signature is invalid") ); } catch(...) { - BOOST_CHECK_MESSAGE(o.count("transaction") == 0, "A transction object should not be defined because the RLP is invalid!"); + BOOST_CHECK_MESSAGE(o.count("transaction") == 0, "A transaction object should not be defined because the RLP is invalid!"); return; } @@ -115,6 +115,7 @@ void doTransactionTests(json_spirit::mValue& _v, bool _fillin) Address addressReaded = Address(o["sender"].get_str()); BOOST_CHECK_MESSAGE(txFromFields.sender() == addressReaded || txFromRlp.sender() == addressReaded, "Signature address of sender does not match given sender address!"); + } else { From e1666c85e5ccbfaa7d2cd757fb5172b4feb8511d Mon Sep 17 00:00:00 2001 From: arkpar Date: Thu, 12 Feb 2015 21:52:30 +0100 Subject: [PATCH 126/213] Ctrl+C/Cmd+C to copy data from debug panes --- mix/qml/DebugInfoList.qml | 11 ++++++++++- mix/qml/Debugger.qml | 4 ++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/mix/qml/DebugInfoList.qml b/mix/qml/DebugInfoList.qml index c1ab11596..ae7e6fabe 100644 --- a/mix/qml/DebugInfoList.qml +++ b/mix/qml/DebugInfoList.qml @@ -8,7 +8,7 @@ ColumnLayout { property string title property variant listModel; property bool collapsible; - property bool enableSelection; + property bool enableSelection: false; property real storedHeight: 0; property Component itemDelegate signal rowActivated(int index) @@ -116,6 +116,15 @@ ColumnLayout { } } onActivated: rowActivated(row); + Keys.onPressed: { + if ((event.modifiers & Qt.ControlModifier) && event.key === Qt.Key_C && currentRow >=0 && currentRow < listModel.length) { + var str = ""; + for (var i = 0; i < listModel.length; i++) + str += listModel[i] + "\n"; + appContext.toClipboard(str); + } + } + TableViewColumn { role: "modelData" width: parent.width diff --git a/mix/qml/Debugger.qml b/mix/qml/Debugger.qml index 61bf5e8cc..df91aa1c4 100644 --- a/mix/qml/Debugger.qml +++ b/mix/qml/Debugger.qml @@ -529,7 +529,7 @@ Rectangle { Text { anchors.leftMargin: 5 width: parent.width - 5 - wrapMode: Text.Wrap + wrapMode: Text.NoWrap anchors.left: parent.left font.family: "monospace" anchors.verticalCenter: parent.verticalCenter @@ -600,7 +600,7 @@ Rectangle { Text { anchors.leftMargin: 5 width: parent.width - 5 - wrapMode: Text.Wrap + wrapMode: Text.NoWrap anchors.left: parent.left font.family: "monospace" anchors.verticalCenter: parent.verticalCenter From 1ffdd5d7ff32558437a6c1277a9b33b6daad2e88 Mon Sep 17 00:00:00 2001 From: Christian Date: Fri, 13 Feb 2015 01:29:21 +0100 Subject: [PATCH 127/213] Copying calldata directly to memory. --- libsolidity/CompilerUtils.cpp | 63 ++++++++++++++++++++--------------- test/SolidityEndToEndTest.cpp | 15 +++++++++ 2 files changed, 51 insertions(+), 27 deletions(-) diff --git a/libsolidity/CompilerUtils.cpp b/libsolidity/CompilerUtils.cpp index 73be38176..dda1736d6 100644 --- a/libsolidity/CompilerUtils.cpp +++ b/libsolidity/CompilerUtils.cpp @@ -76,35 +76,44 @@ void CompilerUtils::storeInMemoryDynamic(Type const& _type, bool _padToWordBound if (_type.getCategory() == Type::Category::ByteArray) { auto const& type = dynamic_cast(_type); - solAssert(type.getLocation() == ByteArrayType::Location::Storage, "Non-storage byte arrays not yet implemented."); - m_context << eth::Instruction::DUP1 << eth::Instruction::SLOAD; - // stack here: memory_offset storage_offset length_bytes - // jump to end if length is zero - m_context << eth::Instruction::DUP1 << eth::Instruction::ISZERO; - eth::AssemblyItem loopEnd = m_context.newTag(); - m_context.appendConditionalJumpTo(loopEnd); - // compute memory end offset - m_context << eth::Instruction::DUP3 << eth::Instruction::ADD << eth::Instruction::SWAP2; - // actual array data is stored at SHA3(storage_offset) - m_context << eth::Instruction::SWAP1; - CompilerUtils(m_context).computeHashStatic(); - m_context << eth::Instruction::SWAP1; + if (type.getLocation() == ByteArrayType::Location::CallData) + { + m_context << eth::Instruction::CALLDATASIZE << u256(0) << eth::Instruction::DUP3 + << eth::Instruction::CALLDATACOPY + << eth::Instruction::CALLDATASIZE << eth::Instruction::ADD; + } + else + { + solAssert(type.getLocation() == ByteArrayType::Location::Storage, "Memory byte arrays not yet implemented."); + m_context << eth::Instruction::DUP1 << eth::Instruction::SLOAD; + // stack here: memory_offset storage_offset length_bytes + // jump to end if length is zero + m_context << eth::Instruction::DUP1 << eth::Instruction::ISZERO; + eth::AssemblyItem loopEnd = m_context.newTag(); + m_context.appendConditionalJumpTo(loopEnd); + // compute memory end offset + m_context << eth::Instruction::DUP3 << eth::Instruction::ADD << eth::Instruction::SWAP2; + // actual array data is stored at SHA3(storage_offset) + m_context << eth::Instruction::SWAP1; + CompilerUtils(m_context).computeHashStatic(); + m_context << eth::Instruction::SWAP1; - // stack here: memory_end_offset storage_data_offset memory_offset - eth::AssemblyItem loopStart = m_context.newTag(); - m_context << loopStart - // load and store - << eth::Instruction::DUP2 << eth::Instruction::SLOAD - << eth::Instruction::DUP2 << eth::Instruction::MSTORE - // increment storage_data_offset by 1 - << eth::Instruction::SWAP1 << u256(1) << eth::Instruction::ADD - // increment memory offset by 32 - << eth::Instruction::SWAP1 << u256(32) << eth::Instruction::ADD - // check for loop condition - << eth::Instruction::DUP1 << eth::Instruction::DUP4 << eth::Instruction::GT; - m_context.appendConditionalJumpTo(loopStart); - m_context << loopEnd << eth::Instruction::POP << eth::Instruction::POP; + // stack here: memory_end_offset storage_data_offset memory_offset + eth::AssemblyItem loopStart = m_context.newTag(); + m_context << loopStart + // load and store + << eth::Instruction::DUP2 << eth::Instruction::SLOAD + << eth::Instruction::DUP2 << eth::Instruction::MSTORE + // increment storage_data_offset by 1 + << eth::Instruction::SWAP1 << u256(1) << eth::Instruction::ADD + // increment memory offset by 32 + << eth::Instruction::SWAP1 << u256(32) << eth::Instruction::ADD + // check for loop condition + << eth::Instruction::DUP1 << eth::Instruction::DUP4 << eth::Instruction::GT; + m_context.appendConditionalJumpTo(loopStart); + m_context << loopEnd << eth::Instruction::POP << eth::Instruction::POP; + } } else { diff --git a/test/SolidityEndToEndTest.cpp b/test/SolidityEndToEndTest.cpp index abfc97b73..259123db6 100644 --- a/test/SolidityEndToEndTest.cpp +++ b/test/SolidityEndToEndTest.cpp @@ -2273,6 +2273,21 @@ BOOST_AUTO_TEST_CASE(store_bytes) BOOST_CHECK(callContractFunction("save()", "abcdefg") == encodeArgs(24)); } +BOOST_AUTO_TEST_CASE(bytes_from_calldata_to_memory) +{ + char const* sourceCode = R"( + contract C { + function() returns (hash) { + return sha3("abc", msg.data); + } + } + )"; + compileAndRun(sourceCode); + bytes calldata = bytes(61, 0x22) + bytes(12, 0x12); + sendMessage(calldata, false); + BOOST_CHECK(m_output == encodeArgs(dev::sha3(bytes{'a', 'b', 'c'} + calldata))); +} + BOOST_AUTO_TEST_CASE(call_forward_bytes) { char const* sourceCode = R"( From 483ce3a2ea136f840ae6f1eac9dbf7fd0258a8e9 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Fri, 13 Feb 2015 09:00:51 +0100 Subject: [PATCH 128/213] performance test --- test/vm.cpp | 28 +++++++++++++++++++++++ test/vmPerformanceTestFiller.json | 38 +++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 test/vmPerformanceTestFiller.json diff --git a/test/vm.cpp b/test/vm.cpp index f15dc048a..af946777f 100644 --- a/test/vm.cpp +++ b/test/vm.cpp @@ -32,6 +32,8 @@ using namespace dev; using namespace dev::eth; using namespace dev::test; +using Millisecs = chrono::duration; + FakeExtVM::FakeExtVM(eth::BlockInfo const& _previousBlock, eth::BlockInfo const& _currentBlock, unsigned _depth): /// TODO: XXX: remove the default argument & fix. ExtVMFace(Address(), Address(), Address(), 0, 1, bytesConstRef(), bytes(), _previousBlock, _currentBlock, test::lastHashes(_currentBlock.number), _depth) {} @@ -513,13 +515,39 @@ BOOST_AUTO_TEST_CASE(vmSystemOperationsTest) dev::test::executeTests("vmSystemOperationsTest", "/VMTests", dev::test::doVMTests); } +BOOST_AUTO_TEST_CASE(vmPerformanceTest) +{ + for (int i = 1; i < boost::unit_test::framework::master_test_suite().argc; ++i) + { + string arg = boost::unit_test::framework::master_test_suite().argv[i]; + if (arg == "--performance") + { + chrono::steady_clock::time_point start = chrono::steady_clock::now(); + + dev::test::executeTests("vmPerformanceTest", "/VMTests", dev::test::doVMTests); + + chrono::steady_clock::time_point end = chrono::steady_clock::now(); + Millisecs duration(chrono::duration_cast(end - start)); + cnote << "test duration: " << duration.count() << " milliseconds.\n"; + } + } +} + BOOST_AUTO_TEST_CASE(vmInputLimitsTest1) { for (int i = 1; i < boost::unit_test::framework::master_test_suite().argc; ++i) { string arg = boost::unit_test::framework::master_test_suite().argv[i]; if (arg == "--inputlimits") + { + chrono::steady_clock::time_point start = chrono::steady_clock::now(); + dev::test::executeTests("vmInputLimitsTest1", "/VMTests", dev::test::doVMTests); + + chrono::steady_clock::time_point end = chrono::steady_clock::now(); + Millisecs duration(chrono::duration_cast(end - start)); + cnote << "test duration: " << duration.count() << " milliseconds.\n"; + } } } diff --git a/test/vmPerformanceTestFiller.json b/test/vmPerformanceTestFiller.json new file mode 100644 index 000000000..7979bfbdb --- /dev/null +++ b/test/vmPerformanceTestFiller.json @@ -0,0 +1,38 @@ +{ + "ackermann33": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "100000000000", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "//" : "contract PerformanceTester {", + "//" : " function ackermann(uint m, uint n) returns (uint) {", + "//" : " if (m == 0)", + "//" : " return n + 1;", + "//" : " if (n == 0)", + "//" : " return ackermann(m - 1, 1);", + "//" : " return ackermann(m - 1, ackermann(m, n - 1));", + "//" : " }", + "//" : "}", + "code" : "0x60e060020a6000350480632839e92814601457005b6020600435602435602a565b8060005260206000f35b6000826000146037576041565b8160010190506076565b81600014604c57605e565b6058600184036001602a565b90506076565b607360018403606f8560018603602a565b602a565b90505b9291505056", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "0x2839e92800000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003", + "gasPrice" : "100000000000000", + "gas" : "100000000000" + } + } +} From 0520e0f4db7fa8b49b6c294135b689b1fdce4427 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Fri, 13 Feb 2015 09:03:03 +0100 Subject: [PATCH 129/213] fixed issue with including wrong json/json.h file --- alethzero/CMakeLists.txt | 4 ++-- libsolidity/CMakeLists.txt | 4 ++-- lllc/CMakeLists.txt | 4 ++-- mix/CMakeLists.txt | 3 ++- solc/CMakeLists.txt | 4 ++-- test/CMakeLists.txt | 5 +++-- 6 files changed, 13 insertions(+), 11 deletions(-) diff --git a/alethzero/CMakeLists.txt b/alethzero/CMakeLists.txt index ed2d8fa5e..c18a76c36 100644 --- a/alethzero/CMakeLists.txt +++ b/alethzero/CMakeLists.txt @@ -10,9 +10,9 @@ endif() set(CMAKE_INCLUDE_CURRENT_DIR ON) aux_source_directory(. SRC_LIST) -include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) -include_directories(${JSONCPP_INCLUDE_DIRS}) include_directories(..) +include_directories(BEFORE ${JSONCPP_INCLUDE_DIRS}) +include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) qt5_wrap_ui(ui_Main.h Main.ui) diff --git a/libsolidity/CMakeLists.txt b/libsolidity/CMakeLists.txt index 9c0b50775..cccc5e165 100644 --- a/libsolidity/CMakeLists.txt +++ b/libsolidity/CMakeLists.txt @@ -11,9 +11,9 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") aux_source_directory(. SRC_LIST) -include_directories(${Boost_INCLUDE_DIRS}) -include_directories(${JSONCPP_INCLUDE_DIRS}) include_directories(..) +include_directories(BEFORE ${JSONCPP_INCLUDE_DIRS}) +include_directories(${Boost_INCLUDE_DIRS}) set(EXECUTABLE solidity) diff --git a/lllc/CMakeLists.txt b/lllc/CMakeLists.txt index 5aaca0ccc..2157fea74 100644 --- a/lllc/CMakeLists.txt +++ b/lllc/CMakeLists.txt @@ -3,9 +3,9 @@ set(CMAKE_AUTOMOC OFF) aux_source_directory(. SRC_LIST) -include_directories(${Boost_INCLUDE_DIRS}) -include_directories(${JSONCPP_INCLUDE_DIRS}) include_directories(..) +include_directories(BEFORE ${JSONCPP_INCLUDE_DIRS}) +include_directories(${Boost_INCLUDE_DIRS}) set(EXECUTABLE lllc) diff --git a/mix/CMakeLists.txt b/mix/CMakeLists.txt index 755f3df04..4390a4eb0 100644 --- a/mix/CMakeLists.txt +++ b/mix/CMakeLists.txt @@ -10,8 +10,9 @@ endif() set(CMAKE_INCLUDE_CURRENT_DIR ON) aux_source_directory(. SRC_LIST) -include_directories(${JSONCPP_INCLUDE_DIRS}) + include_directories(..) +include_directories(BEFORE ${JSONCPP_INCLUDE_DIRS}) find_package (Qt5WebEngine QUIET) qt5_add_resources(UI_RESOURCES res.qrc) diff --git a/solc/CMakeLists.txt b/solc/CMakeLists.txt index 2a7bd7b6d..747effad0 100644 --- a/solc/CMakeLists.txt +++ b/solc/CMakeLists.txt @@ -3,9 +3,9 @@ set(CMAKE_AUTOMOC OFF) aux_source_directory(. SRC_LIST) -include_directories(${Boost_INCLUDE_DIRS}) -include_directories(${JSONCPP_INCLUDE_DIRS}) include_directories(..) +include_directories(BEFORE ${JSONCPP_INCLUDE_DIRS}) +include_directories(${Boost_INCLUDE_DIRS}) set(EXECUTABLE solc) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index ab8afcd70..6ba07f280 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -4,11 +4,12 @@ aux_source_directory(. SRC_LIST) list(REMOVE_ITEM SRC_LIST "./createRandomTest.cpp") list(REMOVE_ITEM SRC_LIST "./checkRandomTest.cpp") +include_directories(..) +include_directories(BEFORE ${JSONCPP_INCLUDE_DIRS}) include_directories(${Boost_INCLUDE_DIRS}) include_directories(${CRYPTOPP_INCLUDE_DIRS}) -include_directories(${JSONCPP_INCLUDE_DIRS}) include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) -include_directories(..) + file(GLOB HEADERS "*.h") add_executable(testeth ${SRC_LIST} ${HEADERS}) From d892a39cb21a9fcd871977d61ceecf8e23c0e052 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Fri, 13 Feb 2015 09:07:07 +0100 Subject: [PATCH 130/213] style fix --- test/vmPerformanceTestFiller.json | 64 +++++++++++++++---------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/test/vmPerformanceTestFiller.json b/test/vmPerformanceTestFiller.json index 7979bfbdb..7cfe659d5 100644 --- a/test/vmPerformanceTestFiller.json +++ b/test/vmPerformanceTestFiller.json @@ -1,38 +1,38 @@ { "ackermann33": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "100000000000", - "currentDifficulty" : "256", - "currentTimestamp" : "1", - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "pre" : { - "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { - "balance" : "1000000000000000000", - "nonce" : "0", - "//" : "contract PerformanceTester {", - "//" : " function ackermann(uint m, uint n) returns (uint) {", - "//" : " if (m == 0)", - "//" : " return n + 1;", - "//" : " if (n == 0)", - "//" : " return ackermann(m - 1, 1);", - "//" : " return ackermann(m - 1, ackermann(m, n - 1));", - "//" : " }", - "//" : "}", - "code" : "0x60e060020a6000350480632839e92814601457005b6020600435602435602a565b8060005260206000f35b6000826000146037576041565b8160010190506076565b81600014604c57605e565b6058600184036001602a565b90506076565b607360018403606f8560018603602a565b602a565b90505b9291505056", - "storage": {} - } - }, + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "100000000000", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "//" : "contract PerformanceTester {", + "//" : " function ackermann(uint m, uint n) returns (uint) {", + "//" : " if (m == 0)", + "//" : " return n + 1;", + "//" : " if (n == 0)", + "//" : " return ackermann(m - 1, 1);", + "//" : " return ackermann(m - 1, ackermann(m, n - 1));", + "//" : " }", + "//" : "}", + "code" : "0x60e060020a6000350480632839e92814601457005b6020600435602435602a565b8060005260206000f35b6000826000146037576041565b8160010190506076565b81600014604c57605e565b6058600184036001602a565b90506076565b607360018403606f8560018603602a565b602a565b90505b9291505056", + "storage": {} + } + }, "exec" : { - "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", - "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", - "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", - "value" : "1000000000000000000", + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", "data" : "0x2839e92800000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003", - "gasPrice" : "100000000000000", + "gasPrice" : "100000000000000", "gas" : "100000000000" - } - } + } + } } From 0696ee87da8d34d09fd1286cc7d08e535b514ce3 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 13 Feb 2015 10:25:56 +0100 Subject: [PATCH 131/213] Windows compile fix. --- libp2p/Host.cpp | 2 +- libp2p/Session.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index f09468e0d..f117df37a 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -54,7 +54,7 @@ Host::Host(std::string const& _clientVersion, NetworkPreferences const& _n, byte m_ioService(2), m_tcp4Acceptor(m_ioService), m_alias(networkAlias(_restoreNetwork)), - m_lastPing(chrono::time_point::min()) + m_lastPing(chrono::steady_clock::time_point::min()) { for (auto address: m_ifAddresses) if (address.is_v4()) diff --git a/libp2p/Session.cpp b/libp2p/Session.cpp index cb7225f0f..6ff765cf6 100644 --- a/libp2p/Session.cpp +++ b/libp2p/Session.cpp @@ -40,10 +40,10 @@ Session::Session(Host* _s, bi::tcp::socket _socket, std::shared_ptr const& m_server(_s), m_socket(std::move(_socket)), m_peer(_n), - m_info({NodeId(), "?", m_socket.remote_endpoint().address().to_string(), 0, std::chrono::steady_clock::duration(0), CapDescSet(), 0, map()}), - m_ping(chrono::time_point::max()) + m_info({NodeId(), "?", m_socket.remote_endpoint().address().to_string(), 0, chrono::steady_clock::duration(0), CapDescSet(), 0, map()}), + m_ping(chrono::steady_clock::time_point::max()) { - m_lastReceived = m_connect = std::chrono::steady_clock::now(); + m_lastReceived = m_connect = chrono::steady_clock::now(); } Session::~Session() From f5022ee58f2262624b991487006e3fd56991ce07 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Fri, 13 Feb 2015 10:27:38 +0100 Subject: [PATCH 132/213] use auto for steady clock and chrono::milliseconds --- test/vm.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/test/vm.cpp b/test/vm.cpp index af946777f..faab48129 100644 --- a/test/vm.cpp +++ b/test/vm.cpp @@ -32,8 +32,6 @@ using namespace dev; using namespace dev::eth; using namespace dev::test; -using Millisecs = chrono::duration; - FakeExtVM::FakeExtVM(eth::BlockInfo const& _previousBlock, eth::BlockInfo const& _currentBlock, unsigned _depth): /// TODO: XXX: remove the default argument & fix. ExtVMFace(Address(), Address(), Address(), 0, 1, bytesConstRef(), bytes(), _previousBlock, _currentBlock, test::lastHashes(_currentBlock.number), _depth) {} @@ -522,12 +520,12 @@ BOOST_AUTO_TEST_CASE(vmPerformanceTest) string arg = boost::unit_test::framework::master_test_suite().argv[i]; if (arg == "--performance") { - chrono::steady_clock::time_point start = chrono::steady_clock::now(); + auto start = chrono::steady_clock::now(); dev::test::executeTests("vmPerformanceTest", "/VMTests", dev::test::doVMTests); - chrono::steady_clock::time_point end = chrono::steady_clock::now(); - Millisecs duration(chrono::duration_cast(end - start)); + auto end = chrono::steady_clock::now(); + chrono::milliseconds duration(chrono::duration_cast(end - start)); cnote << "test duration: " << duration.count() << " milliseconds.\n"; } } @@ -540,12 +538,12 @@ BOOST_AUTO_TEST_CASE(vmInputLimitsTest1) string arg = boost::unit_test::framework::master_test_suite().argv[i]; if (arg == "--inputlimits") { - chrono::steady_clock::time_point start = chrono::steady_clock::now(); + auto start = chrono::steady_clock::now(); dev::test::executeTests("vmInputLimitsTest1", "/VMTests", dev::test::doVMTests); - chrono::steady_clock::time_point end = chrono::steady_clock::now(); - Millisecs duration(chrono::duration_cast(end - start)); + auto end = chrono::steady_clock::now(); + chrono::milliseconds duration(chrono::duration_cast(end - start)); cnote << "test duration: " << duration.count() << " milliseconds.\n"; } } From 5d15c00aba00bacac7748b7dbf9b6c814018d131 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 13 Feb 2015 10:43:46 +0100 Subject: [PATCH 133/213] Windows warning fix. --- libp2p/NodeTable.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libp2p/NodeTable.h b/libp2p/NodeTable.h index 04e8d009c..0217c700e 100644 --- a/libp2p/NodeTable.h +++ b/libp2p/NodeTable.h @@ -163,7 +163,7 @@ public: std::list snapshot() const; /// Returns true if node id is in node table. - bool haveNode(NodeId const& _id) { Guard l(x_nodes); return m_nodes.count(_id); } + bool haveNode(NodeId const& _id) { Guard l(x_nodes); return m_nodes.count(_id) > 0; } /// Returns the Node to the corresponding node id or the empty Node if that id is not found. Node node(NodeId const& _id); @@ -418,4 +418,4 @@ struct NodeTableEgress: public LogChannel { static const char* name() { return " struct NodeTableIngress: public LogChannel { static const char* name() { return "< Date: Fri, 13 Feb 2015 10:59:47 +0100 Subject: [PATCH 134/213] fix import transaction --- test/block.cpp | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/test/block.cpp b/test/block.cpp index c701cb979..69c236606 100644 --- a/test/block.cpp +++ b/test/block.cpp @@ -157,6 +157,8 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) // construct blockchain BlockChain bc(block.out(), string(), true); + cout << "constructed bc\n"; + if (_fillin) { BOOST_REQUIRE(o.count("transactions") > 0); @@ -260,9 +262,13 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) try { state.sync(bc); + cout << "synced bc\n"; bytes blockRLP = importByteArray(o["rlp"].get_str()); + cout << "imported rlp bc\n"; bc.import(blockRLP, state.db()); + cout << "imported rlp to bc bc\n"; state.sync(bc); + cout << "synced state bc\n"; } // if exception is thrown, RLP is invalid and no blockHeader, Transaction list, or Uncle list should be given catch (Exception const& _e) @@ -316,6 +322,8 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) BOOST_CHECK_MESSAGE(blockHeaderFromFields == blockFromRlp, "However, blockHeaderFromFields != blockFromRlp!"); + cout << "checked block header bc\n"; + //Check transaction list Transactions txsFromField; @@ -323,6 +331,9 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) for (auto const& txObj: o["transactions"].get_array()) { mObject tx = txObj.get_obj(); + + cout << "read single tx\n"; + BOOST_REQUIRE(tx.count("nonce") > 0); BOOST_REQUIRE(tx.count("gasPrice") > 0); BOOST_REQUIRE(tx.count("gasLimit") > 0); @@ -333,10 +344,25 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) BOOST_REQUIRE(tx.count("s") > 0); BOOST_REQUIRE(tx.count("data") > 0); - Transaction t(createRLPStreamFromTransactionFields(tx).out(), CheckSignature::Sender); - txsFromField.push_back(t); + cout << "construct single tx\n"; + try + { + Transaction t(createRLPStreamFromTransactionFields(tx).out(), CheckSignature::Sender); + txsFromField.push_back(t); + } + catch (Exception const& _e) + { + BOOST_ERROR("Failed transaction constructor with Exception: " << diagnostic_information(_e)); + + } + catch (exception const& _e) + { + cout << _e.what() << endl; + } } + cout << "read txs bc\n"; + Transactions txsFromRlp; bytes blockRLP = importByteArray(o["rlp"].get_str()); RLP root(blockRLP); @@ -362,6 +388,7 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) BOOST_CHECK_MESSAGE(txsFromField[i] == txsFromRlp[i], "however, transactions in rlp and in field do not match"); } + cout << "checked txs bc\n"; // check uncle list From cec31a7f04ba0b95de35f5422b611aa4c41291d1 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 13 Feb 2015 11:24:14 +0100 Subject: [PATCH 135/213] auto reccommendations. --- CodingStandards.txt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/CodingStandards.txt b/CodingStandards.txt index f883c9147..8acea78ae 100644 --- a/CodingStandards.txt +++ b/CodingStandards.txt @@ -96,12 +96,18 @@ e. Always pass non-trivial parameters with a const& suffix. f. If a function returns multiple values, use std::tuple (std::pair acceptable). Prefer not using */& arguments, except where efficiency requires. g. Never use a macro where adequate non-preprocessor C++ can be written. h. Prefer "using NewType = OldType" to "typedef OldType NewType". +i. Make use of auto whenever type is clear or unimportant: +- Always avoid doubly-stating the type. +- Use to avoid vast and unimportant type declarations + (WRONG) const double d = 0; int i, j; char *s; float meanAndSigma(std::vector _v, float* _sigma); +Derived* x(dynamic_cast(base)); +for (map::iterator i = l.begin(); i != l.end(); ++l) {} (CORRECT) double const d = 0; @@ -109,7 +115,8 @@ int i; int j; char* s; std::tuple meanAndSigma(std::vector const& _v); - +auto x = dynamic_cast(base); +for (auto i = x.begin(); i != x.end(); ++i) {} 7. Structs & classes From 8f0638fdfdb2b0beba5947daaa5ca4fab554e283 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Fri, 13 Feb 2015 11:24:20 +0100 Subject: [PATCH 136/213] fix tx output --- test/block.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/block.cpp b/test/block.cpp index 69c236606..3544a3f8e 100644 --- a/test/block.cpp +++ b/test/block.cpp @@ -217,8 +217,8 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) txObject["data"] = toHex(tx.data()); txObject["gasLimit"] = toString(tx.gas()); txObject["gasPrice"] = toString(tx.gasPrice()); - txObject["r"] = toString(tx.signature().r); - txObject["s"] = toString(tx.signature().s); + txObject["r"] = "0x" + toString(tx.signature().r); + txObject["s"] = "0x" + toString(tx.signature().s); txObject["v"] = to_string(tx.signature().v + 27); txObject["to"] = toString(tx.receiveAddress()); txObject["value"] = toString(tx.value()); From 814005ddb42760e2767ab3a2f3397136d7c3340c Mon Sep 17 00:00:00 2001 From: arkpar Date: Fri, 13 Feb 2015 11:22:46 +0100 Subject: [PATCH 137/213] enable parallel compilation for windows build style --- cmake/EthCompilerSettings.cmake | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmake/EthCompilerSettings.cmake b/cmake/EthCompilerSettings.cmake index 12adc1d02..4d56c808b 100755 --- a/cmake/EthCompilerSettings.cmake +++ b/cmake/EthCompilerSettings.cmake @@ -27,13 +27,14 @@ elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + # enable parallel compilation # specify Exception Handling Model in msvc # disable unknown pragma warning (4068) # disable unsafe function warning (4996) # disable decorated name length exceeded, name was truncated (4503) # disable warning C4535: calling _set_se_translator() requires /EHa (for boost tests) # declare Windows XP requirement - add_compile_options(/EHsc /wd4068 /wd4996 /wd4503 -D_WIN32_WINNT=0x0501) + add_compile_options(/MP /EHsc /wd4068 /wd4996 /wd4503 -D_WIN32_WINNT=0x0501) # disable empty object file warning set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /ignore:4221") # warning LNK4075: ignoring '/EDITANDCONTINUE' due to '/SAFESEH' specification From 6107f678d8c86e594ce8d003525606314ee85ff5 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Fri, 13 Feb 2015 11:30:59 +0100 Subject: [PATCH 138/213] style - auto --- test/vm.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/vm.cpp b/test/vm.cpp index faab48129..66925f929 100644 --- a/test/vm.cpp +++ b/test/vm.cpp @@ -525,7 +525,7 @@ BOOST_AUTO_TEST_CASE(vmPerformanceTest) dev::test::executeTests("vmPerformanceTest", "/VMTests", dev::test::doVMTests); auto end = chrono::steady_clock::now(); - chrono::milliseconds duration(chrono::duration_cast(end - start)); + auto duration(chrono::duration_cast(end - start)); cnote << "test duration: " << duration.count() << " milliseconds.\n"; } } @@ -543,7 +543,7 @@ BOOST_AUTO_TEST_CASE(vmInputLimitsTest1) dev::test::executeTests("vmInputLimitsTest1", "/VMTests", dev::test::doVMTests); auto end = chrono::steady_clock::now(); - chrono::milliseconds duration(chrono::duration_cast(end - start)); + auto duration(chrono::duration_cast(end - start)); cnote << "test duration: " << duration.count() << " milliseconds.\n"; } } From d8377e88424e37ae804d6e6e0788cb7324b5bc20 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Fri, 13 Feb 2015 12:38:38 +0100 Subject: [PATCH 139/213] switch to secretKey in fillers --- test/TestHelper.cpp | 1 - test/blValidBlockTestFiller.json | 82 +++++++++++++++++++++++--------- test/block.cpp | 24 ++-------- 3 files changed, 64 insertions(+), 43 deletions(-) diff --git a/test/TestHelper.cpp b/test/TestHelper.cpp index ec284d480..907447aba 100644 --- a/test/TestHelper.cpp +++ b/test/TestHelper.cpp @@ -548,7 +548,6 @@ RLPStream createRLPStreamFromTransactionFields(json_spirit::mObject& _tObj) return rlpStream; } - void processCommandLineOptions() { auto argc = boost::unit_test::framework::master_test_suite().argc; diff --git a/test/blValidBlockTestFiller.json b/test/blValidBlockTestFiller.json index da2625ea6..d19c8104d 100644 --- a/test/blValidBlockTestFiller.json +++ b/test/blValidBlockTestFiller.json @@ -30,10 +30,8 @@ "gasLimit" : "850", "gasPrice" : "1", "nonce" : "0", - "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", - "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "v" : "27", "value" : "10" } ], @@ -72,10 +70,8 @@ "gasLimit" : "850", "gasPrice" : "1", "nonce" : "0", - "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", - "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "v" : "27", "value" : "10" } ], @@ -111,13 +107,11 @@ "transactions" : [ { "data" : "", - "gasLimit" : "500", + "gasLimit" : "850", "gasPrice" : "0", "nonce" : "0", - "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", - "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "v" : "27", "value" : "10" } ], @@ -154,12 +148,10 @@ { "data" : "", "gasLimit" : "500", - "gasPrice" : "0", + "gasPrice" : "10", "nonce" : "0", - "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", - "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "v" : "27", "value" : "10" } ], @@ -198,28 +190,74 @@ "gasLimit" : "500", "gasPrice" : "10", "nonce" : "0", - "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", - "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "v" : "27", "value" : "7000000000" }, + { + "data" : "", + "gasLimit" : "500", + "gasPrice" : "10", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "8000000000" + } + ], + "uncleHeaders" : [ + ] + }, + "txEqualValue" : { + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "10000", + "extraData" : "42", + "gasLimit" : "100000", + "gasUsed" : "0", + "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transactions" : [ { "data" : "", "gasLimit" : "500", "gasPrice" : "10", "nonce" : "0", - "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", - "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "v" : "27", - "value" : "1000000000" + "value" : "5000000000" }, - + { + "data" : "", + "gasLimit" : "500", + "gasPrice" : "9", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "5000000000" + } ], "uncleHeaders" : [ ] } + + + } diff --git a/test/block.cpp b/test/block.cpp index 3544a3f8e..2d44e8d71 100644 --- a/test/block.cpp +++ b/test/block.cpp @@ -169,27 +169,15 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) for (auto const& txObj: o["transactions"].get_array()) { mObject tx = txObj.get_obj(); - BOOST_REQUIRE(tx.count("nonce") > 0); - BOOST_REQUIRE(tx.count("gasPrice") > 0); - BOOST_REQUIRE(tx.count("gasLimit") > 0); - BOOST_REQUIRE(tx.count("to") > 0); - BOOST_REQUIRE(tx.count("value") > 0); - BOOST_REQUIRE(tx.count("v") > 0); - BOOST_REQUIRE(tx.count("r") > 0); - BOOST_REQUIRE(tx.count("s") > 0); - BOOST_REQUIRE(tx.count("data") > 0); - cout << "import tx\n"; - if (!txs.attemptImport(&createRLPStreamFromTransactionFields(tx).out())) + importer.importTransaction(tx); + if (!txs.attemptImport(importer.m_transaction.rlp())) cnote << "failed importing transaction\n"; } try { - cout << "sync state: " << state.sync(bc) << endl; - TransactionReceipts txReceipts = state.sync(bc,txs); - cout << "sync state done\n"; - //if (syncSuccess) - // throw Exception(); + state.sync(bc); + state.sync(bc,txs); state.commitToMine(bc); MineInfo info; for (info.completed = false; !info.completed; info = state.mine()) {} @@ -262,13 +250,9 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) try { state.sync(bc); - cout << "synced bc\n"; bytes blockRLP = importByteArray(o["rlp"].get_str()); - cout << "imported rlp bc\n"; bc.import(blockRLP, state.db()); - cout << "imported rlp to bc bc\n"; state.sync(bc); - cout << "synced state bc\n"; } // if exception is thrown, RLP is invalid and no blockHeader, Transaction list, or Uncle list should be given catch (Exception const& _e) From 5910aa823dcf402bc63acaf3083ca3b4612c1102 Mon Sep 17 00:00:00 2001 From: arkpar Date: Fri, 13 Feb 2015 14:02:11 +0100 Subject: [PATCH 140/213] reorder import statements to work around macdeployqt bug --- mix/qml/BasicMessage.qml | 2 +- mix/qml/Debugger.qml | 2 +- mix/qml/StateList.qml | 2 +- mix/qml/StateListModel.qml | 2 +- mix/qml/TransactionLog.qml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/mix/qml/BasicMessage.qml b/mix/qml/BasicMessage.qml index 8ac8bcd45..7ab04d57c 100644 --- a/mix/qml/BasicMessage.qml +++ b/mix/qml/BasicMessage.qml @@ -1,6 +1,6 @@ import QtQuick 2.2 -import QtQuick.Controls.Styles 1.1 import QtQuick.Controls 1.1 +import QtQuick.Controls.Styles 1.1 import QtQuick.Dialogs 1.1 import QtQuick.Layouts 1.1 diff --git a/mix/qml/Debugger.qml b/mix/qml/Debugger.qml index df91aa1c4..644a7f975 100644 --- a/mix/qml/Debugger.qml +++ b/mix/qml/Debugger.qml @@ -1,6 +1,6 @@ import QtQuick 2.2 -import QtQuick.Controls.Styles 1.1 import QtQuick.Controls 1.1 +import QtQuick.Controls.Styles 1.1 import QtQuick.Dialogs 1.1 import QtQuick.Layouts 1.1 import Qt.labs.settings 1.0 diff --git a/mix/qml/StateList.qml b/mix/qml/StateList.qml index f6f778cd9..2e1bb4a06 100644 --- a/mix/qml/StateList.qml +++ b/mix/qml/StateList.qml @@ -1,6 +1,6 @@ import QtQuick 2.2 -import QtQuick.Controls.Styles 1.1 import QtQuick.Controls 1.1 +import QtQuick.Controls.Styles 1.1 import QtQuick.Dialogs 1.1 import QtQuick.Layouts 1.1 import QtQuick.Window 2.0 diff --git a/mix/qml/StateListModel.qml b/mix/qml/StateListModel.qml index 67372421c..c68a433f7 100644 --- a/mix/qml/StateListModel.qml +++ b/mix/qml/StateListModel.qml @@ -1,6 +1,6 @@ import QtQuick 2.2 -import QtQuick.Controls.Styles 1.1 import QtQuick.Controls 1.1 +import QtQuick.Controls.Styles 1.1 import QtQuick.Dialogs 1.1 import QtQuick.Window 2.2 import QtQuick.Layouts 1.1 diff --git a/mix/qml/TransactionLog.qml b/mix/qml/TransactionLog.qml index 61d2e0920..75f7a4da3 100644 --- a/mix/qml/TransactionLog.qml +++ b/mix/qml/TransactionLog.qml @@ -1,6 +1,6 @@ import QtQuick 2.2 -import QtQuick.Controls.Styles 1.1 import QtQuick.Controls 1.1 +import QtQuick.Controls.Styles 1.1 import QtQuick.Dialogs 1.1 import QtQuick.Layouts 1.1 From a2e2a6e1dbf4fd706a837f1a1d582ba83de637a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Fri, 13 Feb 2015 14:56:27 +0100 Subject: [PATCH 141/213] Performance tests: more ackermann calls, fibonacci. - ackermann(3, 1) - ackermann(3, 2) - fibonacci(10) - fibonacci(16) Contract code included: PerformanceTester.sol --- test/PerformaceTester.sol | 17 ++++ test/vmPerformanceTestFiller.json | 131 +++++++++++++++++++++++++++--- 2 files changed, 137 insertions(+), 11 deletions(-) create mode 100644 test/PerformaceTester.sol diff --git a/test/PerformaceTester.sol b/test/PerformaceTester.sol new file mode 100644 index 000000000..3b1202cea --- /dev/null +++ b/test/PerformaceTester.sol @@ -0,0 +1,17 @@ +contract PerformanceTester { + function ackermann(uint m, uint n) returns (uint) { + if (m == 0) + return n + 1; + + if (n == 0) + return ackermann(m - 1, 1); + + return ackermann(m - 1, ackermann(m, n - 1)); + } + + function fibonacci(uint n) returns (uint) { + if (n == 0 || n == 1) + return n; + return fibonacci(n - 1) + fibonacci(n - 2); + } +} \ No newline at end of file diff --git a/test/vmPerformanceTestFiller.json b/test/vmPerformanceTestFiller.json index 7cfe659d5..3292916ec 100644 --- a/test/vmPerformanceTestFiller.json +++ b/test/vmPerformanceTestFiller.json @@ -1,4 +1,62 @@ { + "ackermann31": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "100000000000", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "//" : "PerformanceTester.sol", + "code" : "0x60e060020a6000350480632839e92814601e57806361047ff414603457005b602a6004356024356047565b8060005260206000f35b603d6004356099565b8060005260206000f35b600082600014605457605e565b8160010190506093565b81600014606957607b565b60756001840360016047565b90506093565b609060018403608c85600186036047565b6047565b90505b92915050565b6000816000148060a95750816001145b60b05760b7565b81905060cf565b60c1600283036099565b60cb600184036099565b0190505b91905056", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "//" : "ackermann(3, 1)", + "data" : "0x2839e92800000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, + "ackermann32": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "100000000000", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "//" : "PerformanceTester.sol", + "code" : "0x60e060020a6000350480632839e92814601e57806361047ff414603457005b602a6004356024356047565b8060005260206000f35b603d6004356099565b8060005260206000f35b600082600014605457605e565b8160010190506093565b81600014606957607b565b60756001840360016047565b90506093565b609060018403608c85600186036047565b6047565b90505b92915050565b6000816000148060a95750816001145b60b05760b7565b81905060cf565b60c1600283036099565b60cb600184036099565b0190505b91905056", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "//" : "ackermann(3, 2)", + "data" : "0x2839e92800000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002", + "gasPrice" : "100000000000000", + "gas" : "100000" + } + }, "ackermann33": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", @@ -12,16 +70,8 @@ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", "nonce" : "0", - "//" : "contract PerformanceTester {", - "//" : " function ackermann(uint m, uint n) returns (uint) {", - "//" : " if (m == 0)", - "//" : " return n + 1;", - "//" : " if (n == 0)", - "//" : " return ackermann(m - 1, 1);", - "//" : " return ackermann(m - 1, ackermann(m, n - 1));", - "//" : " }", - "//" : "}", - "code" : "0x60e060020a6000350480632839e92814601457005b6020600435602435602a565b8060005260206000f35b6000826000146037576041565b8160010190506076565b81600014604c57605e565b6058600184036001602a565b90506076565b607360018403606f8560018603602a565b602a565b90505b9291505056", + "//" : "PerformanceTester.sol", + "code" : "0x60e060020a6000350480632839e92814601e57806361047ff414603457005b602a6004356024356047565b8060005260206000f35b603d6004356099565b8060005260206000f35b600082600014605457605e565b8160010190506093565b81600014606957607b565b60756001840360016047565b90506093565b609060018403608c85600186036047565b6047565b90505b92915050565b6000816000148060a95750816001145b60b05760b7565b81905060cf565b60c1600283036099565b60cb600184036099565b0190505b91905056", "storage": {} } }, @@ -30,9 +80,68 @@ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", "value" : "1000000000000000000", + "//" : "ackermann(3, 3)", "data" : "0x2839e92800000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003", "gasPrice" : "100000000000000", - "gas" : "100000000000" + "gas" : "100000" + } + }, + "fibonacci10": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "100000000000", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "//" : "PerformanceTester.sol", + "code" : "0x60e060020a6000350480632839e92814601e57806361047ff414603457005b602a6004356024356047565b8060005260206000f35b603d6004356099565b8060005260206000f35b600082600014605457605e565b8160010190506093565b81600014606957607b565b60756001840360016047565b90506093565b609060018403608c85600186036047565b6047565b90505b92915050565b6000816000148060a95750816001145b60b05760b7565b81905060cf565b60c1600283036099565b60cb600184036099565b0190505b91905056", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "//" : "fibonacci(10)", + "data" : "0x61047ff4000000000000000000000000000000000000000000000000000000000000000a", + "gasPrice" : "100000000000000", + "gas" : "100000" + } + }, + "fibonacci16": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "100000000000", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "//" : "PerformanceTester.sol", + "code" : "0x60e060020a6000350480632839e92814601e57806361047ff414603457005b602a6004356024356047565b8060005260206000f35b603d6004356099565b8060005260206000f35b600082600014605457605e565b8160010190506093565b81600014606957607b565b60756001840360016047565b90506093565b609060018403608c85600186036047565b6047565b90505b92915050565b6000816000148060a95750816001145b60b05760b7565b81905060cf565b60c1600283036099565b60cb600184036099565b0190505b91905056", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "//" : "fibonacci(16)", + "data" : "0x61047ff40000000000000000000000000000000000000000000000000000000000000010", + "gasPrice" : "100000000000000", + "gas" : "100000000" } } } From 8457bc4efb87ec375a45d2ab5ee9fe6b6892fe9f Mon Sep 17 00:00:00 2001 From: yann300 Date: Fri, 13 Feb 2015 15:47:29 +0100 Subject: [PATCH 142/213] bug fix: storage view in debug pane broken for long values. --- libethcore/CommonJS.cpp | 11 ++++++++--- libethcore/CommonJS.h | 2 +- mix/qml/Debugger.qml | 4 +++- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/libethcore/CommonJS.cpp b/libethcore/CommonJS.cpp index 3ed4e2796..aa39c8e0c 100644 --- a/libethcore/CommonJS.cpp +++ b/libethcore/CommonJS.cpp @@ -97,7 +97,7 @@ std::string fromRaw(h256 _n, unsigned* _inc) return ""; } -std::string prettyU256(u256 _n) +std::string prettyU256(u256 _n, bool _abridged) { unsigned inc = 0; std::string raw; @@ -110,11 +110,16 @@ std::string prettyU256(u256 _n) { Address a = right160(_n); - std::string n = a.abridged(); + std::string n; + if (_abridged) + n = a.abridged(); + else + n = toHex(a.ref()); + if (n.empty()) s << "0x" << a; else - s << n << "(0x" << a.abridged() << ")"; + s << n << "(0x" << n << ")"; } else if ((raw = fromRaw((h256)_n, &inc)).size()) return "\"" + raw + "\"" + (inc ? " + " + std::to_string(inc) : ""); diff --git a/libethcore/CommonJS.h b/libethcore/CommonJS.h index ccc3b3103..2f82d8945 100644 --- a/libethcore/CommonJS.h +++ b/libethcore/CommonJS.h @@ -59,7 +59,7 @@ bytes unpadded(bytes _s); /// Remove all 0 byte on the head of @a _s. bytes unpadLeft(bytes _s); /// Convert u256 into user-readable string. Returns int/hex value of 64 bits int, hex of 160 bits FixedHash. As a fallback try to handle input as h256. -std::string prettyU256(u256 _n); +std::string prettyU256(u256 _n, bool _abridged = true); /// Convert h256 into user-readable string (by directly using std::string constructor). std::string fromRaw(h256 _n, unsigned* _inc = nullptr); /// Convert string to Address (h160), returns empty address if (_a.size != 40). diff --git a/mix/qml/Debugger.qml b/mix/qml/Debugger.qml index 644a7f975..1dd05574f 100644 --- a/mix/qml/Debugger.qml +++ b/mix/qml/Debugger.qml @@ -598,9 +598,11 @@ Rectangle { Layout.minimumWidth: parent.width / 2 Layout.maximumWidth: parent.width / 2 Text { + maximumLineCount: 1 + clip: true anchors.leftMargin: 5 width: parent.width - 5 - wrapMode: Text.NoWrap + wrapMode: Text.WrapAnywhere anchors.left: parent.left font.family: "monospace" anchors.verticalCenter: parent.verticalCenter From 57f3a322a6b818820a25e3b2498a8d2db1a8378a Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Wed, 11 Feb 2015 11:23:57 +0100 Subject: [PATCH 143/213] Changes required for upgrade to jsonrpccpp 0.4.2 --- libweb3jsonrpc/WebThreeStubServerBase.cpp | 26 ++-- libweb3jsonrpc/WebThreeStubServerBase.h | 26 ++-- libweb3jsonrpc/abstractwebthreestubserver.h | 146 +++++++++++--------- test/webthreestubclient.h | 30 ++-- 4 files changed, 120 insertions(+), 108 deletions(-) diff --git a/libweb3jsonrpc/WebThreeStubServerBase.cpp b/libweb3jsonrpc/WebThreeStubServerBase.cpp index 7ad29ed1b..49094a423 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.cpp +++ b/libweb3jsonrpc/WebThreeStubServerBase.cpp @@ -264,7 +264,7 @@ Json::Value WebThreeStubServerBase::eth_blockByHash(std::string const& _hash) return toJson(client()->blockInfo(jsToFixed<32>(_hash))); } -Json::Value WebThreeStubServerBase::eth_blockByNumber(int const& _number) +Json::Value WebThreeStubServerBase::eth_blockByNumber(int _number) { return toJson(client()->blockInfo(client()->hashFromNumber(_number))); } @@ -342,7 +342,7 @@ std::string WebThreeStubServerBase::eth_call(Json::Value const& _json) return ret; } -Json::Value WebThreeStubServerBase::eth_changed(int const& _id) +Json::Value WebThreeStubServerBase::eth_changed(int _id) { auto entries = client()->checkWatch(_id); if (entries.size()) @@ -381,7 +381,7 @@ std::string WebThreeStubServerBase::db_get(std::string const& _name, std::string return toJS(dev::asBytes(ret)); } -Json::Value WebThreeStubServerBase::eth_filterLogs(int const& _id) +Json::Value WebThreeStubServerBase::eth_filterLogs(int _id) { return toJson(client()->logs(_id)); } @@ -563,13 +563,13 @@ bool WebThreeStubServerBase::eth_setCoinbase(std::string const& _address) return true; } -bool WebThreeStubServerBase::eth_setDefaultBlock(int const& _block) +bool WebThreeStubServerBase::eth_setDefaultBlock(int _block) { client()->setDefault(_block); return true; } -bool WebThreeStubServerBase::eth_setListening(bool const& _listening) +bool WebThreeStubServerBase::eth_setListening(bool _listening) { if (_listening) network()->startNetwork(); @@ -578,7 +578,7 @@ bool WebThreeStubServerBase::eth_setListening(bool const& _listening) return true; } -bool WebThreeStubServerBase::eth_setMining(bool const& _mining) +bool WebThreeStubServerBase::eth_setMining(bool _mining) { if (_mining) client()->startMining(); @@ -587,7 +587,7 @@ bool WebThreeStubServerBase::eth_setMining(bool const& _mining) return true; } -Json::Value WebThreeStubServerBase::shh_changed(int const& _id) +Json::Value WebThreeStubServerBase::shh_changed(int _id) { Json::Value ret(Json::arrayValue); auto pub = m_shhWatches[_id]; @@ -619,7 +619,7 @@ int WebThreeStubServerBase::shh_newFilter(Json::Value const& _json) return ret; } -bool WebThreeStubServerBase::shh_uninstallFilter(int const& _id) +bool WebThreeStubServerBase::shh_uninstallFilter(int _id) { face()->uninstallWatch(_id); return true; @@ -671,27 +671,27 @@ bool WebThreeStubServerBase::authenticate(TransactionSkeleton const& _t) return true; } -Json::Value WebThreeStubServerBase::eth_transactionByHash(std::string const& _hash, int const& _i) +Json::Value WebThreeStubServerBase::eth_transactionByHash(std::string const& _hash, int _i) { return toJson(client()->transaction(jsToFixed<32>(_hash), _i)); } -Json::Value WebThreeStubServerBase::eth_transactionByNumber(int const& _number, int const& _i) +Json::Value WebThreeStubServerBase::eth_transactionByNumber(int _number, int _i) { return toJson(client()->transaction(client()->hashFromNumber(_number), _i)); } -Json::Value WebThreeStubServerBase::eth_uncleByHash(std::string const& _hash, int const& _i) +Json::Value WebThreeStubServerBase::eth_uncleByHash(std::string const& _hash, int _i) { return toJson(client()->uncle(jsToFixed<32>(_hash), _i)); } -Json::Value WebThreeStubServerBase::eth_uncleByNumber(int const& _number, int const& _i) +Json::Value WebThreeStubServerBase::eth_uncleByNumber(int _number, int _i) { return toJson(client()->uncle(client()->hashFromNumber(_number), _i)); } -bool WebThreeStubServerBase::eth_uninstallFilter(int const& _id) +bool WebThreeStubServerBase::eth_uninstallFilter(int _id) { client()->uninstallWatch(_id); return true; diff --git a/libweb3jsonrpc/WebThreeStubServerBase.h b/libweb3jsonrpc/WebThreeStubServerBase.h index 1190ce407..005ac4130 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.h +++ b/libweb3jsonrpc/WebThreeStubServerBase.h @@ -69,16 +69,16 @@ public: virtual Json::Value eth_accounts(); virtual std::string eth_balanceAt(std::string const& _address); virtual Json::Value eth_blockByHash(std::string const& _hash); - virtual Json::Value eth_blockByNumber(int const& _number); + virtual Json::Value eth_blockByNumber(int _number); virtual std::string eth_call(Json::Value const& _json); - virtual Json::Value eth_changed(int const& _id); + virtual Json::Value eth_changed(int _id); virtual std::string eth_codeAt(std::string const& _address); virtual std::string eth_coinbase(); virtual Json::Value eth_compilers(); virtual double eth_countAt(std::string const& _address); virtual int eth_defaultBlock(); virtual std::string eth_gasPrice(); - virtual Json::Value eth_filterLogs(int const& _id); + virtual Json::Value eth_filterLogs(int _id); virtual bool eth_flush(); virtual Json::Value eth_logs(Json::Value const& _json); virtual bool eth_listening(); @@ -88,20 +88,20 @@ public: virtual int eth_number(); virtual int eth_peerCount(); virtual bool eth_setCoinbase(std::string const& _address); - virtual bool eth_setDefaultBlock(int const& _block); - virtual bool eth_setListening(bool const& _listening); + virtual bool eth_setDefaultBlock(int _block); + virtual bool eth_setListening(bool _listening); virtual std::string eth_lll(std::string const& _s); virtual std::string eth_serpent(std::string const& _s); - virtual bool eth_setMining(bool const& _mining); + virtual bool eth_setMining(bool _mining); virtual std::string eth_solidity(std::string const& _code); virtual std::string eth_stateAt(std::string const& _address, std::string const& _storage); virtual Json::Value eth_storageAt(std::string const& _address); virtual std::string eth_transact(Json::Value const& _json); - virtual Json::Value eth_transactionByHash(std::string const& _hash, int const& _i); - virtual Json::Value eth_transactionByNumber(int const& _number, int const& _i); - virtual Json::Value eth_uncleByHash(std::string const& _hash, int const& _i); - virtual Json::Value eth_uncleByNumber(int const& _number, int const& _i); - virtual bool eth_uninstallFilter(int const& _id); + virtual Json::Value eth_transactionByHash(std::string const& _hash, int _i); + virtual Json::Value eth_transactionByNumber(int _number, int _i); + virtual Json::Value eth_uncleByHash(std::string const& _hash, int _i); + virtual Json::Value eth_uncleByNumber(int _number, int _i); + virtual bool eth_uninstallFilter(int _id); virtual Json::Value eth_getWork(); virtual bool eth_submitWork(std::string const& _nonce); @@ -112,13 +112,13 @@ public: virtual bool db_putString(std::string const& _name, std::string const& _key, std::string const& _value); virtual std::string shh_addToGroup(std::string const& _group, std::string const& _who); - virtual Json::Value shh_changed(int const& _id); + virtual Json::Value shh_changed(int _id); virtual bool shh_haveIdentity(std::string const& _id); virtual int shh_newFilter(Json::Value const& _json); virtual std::string shh_newGroup(std::string const& _id, std::string const& _who); virtual std::string shh_newIdentity(); virtual bool shh_post(Json::Value const& _json); - virtual bool shh_uninstallFilter(int const& _id); + virtual bool shh_uninstallFilter(int _id); void setAccounts(std::vector const& _accounts); void setIdentities(std::vector const& _ids); diff --git a/libweb3jsonrpc/abstractwebthreestubserver.h b/libweb3jsonrpc/abstractwebthreestubserver.h index dda8def08..5bade41f6 100644 --- a/libweb3jsonrpc/abstractwebthreestubserver.h +++ b/libweb3jsonrpc/abstractwebthreestubserver.h @@ -10,59 +10,59 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServer { public: - AbstractWebThreeStubServer(jsonrpc::AbstractServerConnector &conn) : jsonrpc::AbstractServer(conn) - { - this->bindAndAddMethod(new jsonrpc::Procedure("web3_sha3", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::web3_sha3I); - this->bindAndAddMethod(new jsonrpc::Procedure("eth_coinbase", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_coinbaseI); - this->bindAndAddMethod(new jsonrpc::Procedure("eth_setCoinbase", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_setCoinbaseI); - this->bindAndAddMethod(new jsonrpc::Procedure("eth_listening", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, NULL), &AbstractWebThreeStubServer::eth_listeningI); - this->bindAndAddMethod(new jsonrpc::Procedure("eth_setListening", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_BOOLEAN, NULL), &AbstractWebThreeStubServer::eth_setListeningI); - this->bindAndAddMethod(new jsonrpc::Procedure("eth_mining", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, NULL), &AbstractWebThreeStubServer::eth_miningI); - this->bindAndAddMethod(new jsonrpc::Procedure("eth_setMining", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_BOOLEAN, NULL), &AbstractWebThreeStubServer::eth_setMiningI); - this->bindAndAddMethod(new jsonrpc::Procedure("eth_gasPrice", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_gasPriceI); - this->bindAndAddMethod(new jsonrpc::Procedure("eth_accounts", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, NULL), &AbstractWebThreeStubServer::eth_accountsI); - this->bindAndAddMethod(new jsonrpc::Procedure("eth_peerCount", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::eth_peerCountI); - this->bindAndAddMethod(new jsonrpc::Procedure("eth_defaultBlock", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::eth_defaultBlockI); - this->bindAndAddMethod(new jsonrpc::Procedure("eth_setDefaultBlock", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::eth_setDefaultBlockI); - this->bindAndAddMethod(new jsonrpc::Procedure("eth_number", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::eth_numberI); - this->bindAndAddMethod(new jsonrpc::Procedure("eth_balanceAt", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_balanceAtI); - this->bindAndAddMethod(new jsonrpc::Procedure("eth_stateAt", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_stateAtI); - this->bindAndAddMethod(new jsonrpc::Procedure("eth_storageAt", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_storageAtI); - this->bindAndAddMethod(new jsonrpc::Procedure("eth_countAt", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_REAL, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_countAtI); - this->bindAndAddMethod(new jsonrpc::Procedure("eth_codeAt", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_codeAtI); - this->bindAndAddMethod(new jsonrpc::Procedure("eth_transact", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::eth_transactI); - this->bindAndAddMethod(new jsonrpc::Procedure("eth_call", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::eth_callI); - this->bindAndAddMethod(new jsonrpc::Procedure("eth_flush", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, NULL), &AbstractWebThreeStubServer::eth_flushI); - this->bindAndAddMethod(new jsonrpc::Procedure("eth_blockByHash", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_blockByHashI); - this->bindAndAddMethod(new jsonrpc::Procedure("eth_blockByNumber", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::eth_blockByNumberI); - this->bindAndAddMethod(new jsonrpc::Procedure("eth_transactionByHash", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::eth_transactionByHashI); - this->bindAndAddMethod(new jsonrpc::Procedure("eth_transactionByNumber", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_INTEGER,"param2",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::eth_transactionByNumberI); - this->bindAndAddMethod(new jsonrpc::Procedure("eth_uncleByHash", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::eth_uncleByHashI); - this->bindAndAddMethod(new jsonrpc::Procedure("eth_uncleByNumber", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_INTEGER,"param2",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::eth_uncleByNumberI); - this->bindAndAddMethod(new jsonrpc::Procedure("eth_compilers", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, NULL), &AbstractWebThreeStubServer::eth_compilersI); - this->bindAndAddMethod(new jsonrpc::Procedure("eth_lll", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_lllI); - this->bindAndAddMethod(new jsonrpc::Procedure("eth_solidity", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_solidityI); - this->bindAndAddMethod(new jsonrpc::Procedure("eth_serpent", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_serpentI); - this->bindAndAddMethod(new jsonrpc::Procedure("eth_newFilter", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_INTEGER, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::eth_newFilterI); - this->bindAndAddMethod(new jsonrpc::Procedure("eth_newFilterString", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_INTEGER, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_newFilterStringI); - this->bindAndAddMethod(new jsonrpc::Procedure("eth_uninstallFilter", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::eth_uninstallFilterI); - this->bindAndAddMethod(new jsonrpc::Procedure("eth_changed", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::eth_changedI); - this->bindAndAddMethod(new jsonrpc::Procedure("eth_filterLogs", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::eth_filterLogsI); - this->bindAndAddMethod(new jsonrpc::Procedure("eth_logs", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::eth_logsI); - this->bindAndAddMethod(new jsonrpc::Procedure("eth_getWork", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, NULL), &AbstractWebThreeStubServer::eth_getWorkI); - this->bindAndAddMethod(new jsonrpc::Procedure("eth_submitWork", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_submitWorkI); - this->bindAndAddMethod(new jsonrpc::Procedure("db_put", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING,"param3",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::db_putI); - this->bindAndAddMethod(new jsonrpc::Procedure("db_get", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::db_getI); - this->bindAndAddMethod(new jsonrpc::Procedure("db_putString", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING,"param3",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::db_putStringI); - this->bindAndAddMethod(new jsonrpc::Procedure("db_getString", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::db_getStringI); - this->bindAndAddMethod(new jsonrpc::Procedure("shh_post", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::shh_postI); - this->bindAndAddMethod(new jsonrpc::Procedure("shh_newIdentity", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::shh_newIdentityI); - this->bindAndAddMethod(new jsonrpc::Procedure("shh_haveIdentity", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::shh_haveIdentityI); - this->bindAndAddMethod(new jsonrpc::Procedure("shh_newGroup", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::shh_newGroupI); - this->bindAndAddMethod(new jsonrpc::Procedure("shh_addToGroup", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::shh_addToGroupI); - this->bindAndAddMethod(new jsonrpc::Procedure("shh_newFilter", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_INTEGER, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::shh_newFilterI); - this->bindAndAddMethod(new jsonrpc::Procedure("shh_uninstallFilter", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::shh_uninstallFilterI); - this->bindAndAddMethod(new jsonrpc::Procedure("shh_changed", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::shh_changedI); + AbstractWebThreeStubServer(jsonrpc::AbstractServerConnector &conn, jsonrpc::serverVersion_t type = jsonrpc::JSONRPC_SERVER_V2) : jsonrpc::AbstractServer(conn, type) + { + this->bindAndAddMethod(jsonrpc::Procedure("web3_sha3", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::web3_sha3I); + this->bindAndAddMethod(jsonrpc::Procedure("eth_coinbase", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_coinbaseI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_setCoinbase", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_setCoinbaseI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_listening", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, NULL), &AbstractWebThreeStubServer::eth_listeningI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_setListening", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_BOOLEAN, NULL), &AbstractWebThreeStubServer::eth_setListeningI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_mining", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, NULL), &AbstractWebThreeStubServer::eth_miningI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_setMining", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_BOOLEAN, NULL), &AbstractWebThreeStubServer::eth_setMiningI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_gasPrice", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_gasPriceI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_accounts", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, NULL), &AbstractWebThreeStubServer::eth_accountsI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_peerCount", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::eth_peerCountI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_defaultBlock", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::eth_defaultBlockI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_setDefaultBlock", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::eth_setDefaultBlockI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_number", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::eth_numberI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_balanceAt", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_balanceAtI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_stateAt", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_stateAtI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_storageAt", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_storageAtI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_countAt", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_REAL, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_countAtI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_codeAt", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_codeAtI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_transact", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::eth_transactI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_call", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::eth_callI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_flush", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, NULL), &AbstractWebThreeStubServer::eth_flushI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_blockByHash", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_blockByHashI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_blockByNumber", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::eth_blockByNumberI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_transactionByHash", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::eth_transactionByHashI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_transactionByNumber", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_INTEGER,"param2",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::eth_transactionByNumberI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_uncleByHash", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::eth_uncleByHashI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_uncleByNumber", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_INTEGER,"param2",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::eth_uncleByNumberI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_compilers", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, NULL), &AbstractWebThreeStubServer::eth_compilersI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_lll", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_lllI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_solidity", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_solidityI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_serpent", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_serpentI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_newFilter", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_INTEGER, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::eth_newFilterI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_newFilterString", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_INTEGER, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_newFilterStringI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_uninstallFilter", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::eth_uninstallFilterI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_changed", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::eth_changedI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_filterLogs", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::eth_filterLogsI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_logs", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::eth_logsI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_getWork", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, NULL), &AbstractWebThreeStubServer::eth_getWorkI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_submitWork", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_submitWorkI); + this->bindAndAddMethod(jsonrpc::Procedure("db_put", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING,"param3",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::db_putI); + this->bindAndAddMethod(jsonrpc::Procedure("db_get", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::db_getI); + this->bindAndAddMethod(jsonrpc::Procedure("db_putString", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING,"param3",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::db_putStringI); + this->bindAndAddMethod(jsonrpc::Procedure("db_getString", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::db_getStringI); + this->bindAndAddMethod(jsonrpc::Procedure("shh_post", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::shh_postI); + this->bindAndAddMethod(jsonrpc::Procedure("shh_newIdentity", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::shh_newIdentityI); + this->bindAndAddMethod(jsonrpc::Procedure("shh_haveIdentity", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::shh_haveIdentityI); + this->bindAndAddMethod(jsonrpc::Procedure("shh_newGroup", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::shh_newGroupI); + this->bindAndAddMethod(jsonrpc::Procedure("shh_addToGroup", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::shh_addToGroupI); + this->bindAndAddMethod(jsonrpc::Procedure("shh_newFilter", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_INTEGER, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::shh_newFilterI); + this->bindAndAddMethod(jsonrpc::Procedure("shh_uninstallFilter", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::shh_uninstallFilterI); + this->bindAndAddMethod(jsonrpc::Procedure("shh_changed", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::shh_changedI); } inline virtual void web3_sha3I(const Json::Value &request, Json::Value &response) @@ -71,6 +71,7 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServereth_coinbase(); } inline virtual void eth_setCoinbaseI(const Json::Value &request, Json::Value &response) @@ -79,6 +80,7 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServereth_listening(); } inline virtual void eth_setListeningI(const Json::Value &request, Json::Value &response) @@ -87,6 +89,7 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServereth_mining(); } inline virtual void eth_setMiningI(const Json::Value &request, Json::Value &response) @@ -95,18 +98,22 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServereth_gasPrice(); } inline virtual void eth_accountsI(const Json::Value &request, Json::Value &response) { + (void)request; response = this->eth_accounts(); } inline virtual void eth_peerCountI(const Json::Value &request, Json::Value &response) { + (void)request; response = this->eth_peerCount(); } inline virtual void eth_defaultBlockI(const Json::Value &request, Json::Value &response) { + (void)request; response = this->eth_defaultBlock(); } inline virtual void eth_setDefaultBlockI(const Json::Value &request, Json::Value &response) @@ -115,6 +122,7 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServereth_number(); } inline virtual void eth_balanceAtI(const Json::Value &request, Json::Value &response) @@ -147,6 +155,7 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServereth_flush(); } inline virtual void eth_blockByHashI(const Json::Value &request, Json::Value &response) @@ -175,6 +184,7 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServereth_compilers(); } inline virtual void eth_lllI(const Json::Value &request, Json::Value &response) @@ -215,6 +225,7 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServereth_getWork(); } inline virtual void eth_submitWorkI(const Json::Value &request, Json::Value &response) @@ -243,6 +254,7 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServershh_newIdentity(); } inline virtual void shh_haveIdentityI(const Json::Value &request, Json::Value &response) @@ -273,14 +285,14 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServer Date: Fri, 13 Feb 2015 14:05:09 +0100 Subject: [PATCH 144/213] extdep download json-rpc-cpp version 4.2 --- extdep/CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/extdep/CMakeLists.txt b/extdep/CMakeLists.txt index fdee34602..d3a3bde70 100644 --- a/extdep/CMakeLists.txt +++ b/extdep/CMakeLists.txt @@ -35,7 +35,10 @@ if (ETH_COMPILE) include(compile/boost.cmake) else() eth_download(jsoncpp) - eth_download(json-rpc-cpp OSX_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/scripts/json-rpc-cpp_osx.sh) + eth_download(json-rpc-cpp + VERSION 4.2 + OSX_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/scripts/json-rpc-cpp_osx.sh + ) if (APPLE) eth_download(snappy OSX_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/scripts/snappy_osx.sh) From 3ee5ecf7f2364cb67383877c1c1b944bef8dea97 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Fri, 13 Feb 2015 15:06:19 +0100 Subject: [PATCH 145/213] fixed eth_changed to be compatible with jsonrpc4.2 --- mix/Web3Server.cpp | 2 +- mix/Web3Server.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mix/Web3Server.cpp b/mix/Web3Server.cpp index edac252fe..11cb56b1d 100644 --- a/mix/Web3Server.cpp +++ b/mix/Web3Server.cpp @@ -55,7 +55,7 @@ void Web3Server::put(std::string const& _name, std::string const& _key, std::str m_db[k] = _value; } -Json::Value Web3Server::eth_changed(int const& _id) +Json::Value Web3Server::eth_changed(int _id) { return WebThreeStubServerBase::eth_changed(_id); } diff --git a/mix/Web3Server.h b/mix/Web3Server.h index b344720e7..01a187ff7 100644 --- a/mix/Web3Server.h +++ b/mix/Web3Server.h @@ -44,7 +44,7 @@ signals: void newTransaction(); protected: - virtual Json::Value eth_changed(int const& _id) override; + virtual Json::Value eth_changed(int _id) override; virtual std::string eth_transact(Json::Value const& _json) override; virtual std::string eth_call(Json::Value const& _json) override; From e212a8910f82218eaeeac51589c1a16f1037b0dd Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Fri, 13 Feb 2015 15:25:11 +0100 Subject: [PATCH 146/213] microhttpd --- extdep/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/extdep/CMakeLists.txt b/extdep/CMakeLists.txt index d3a3bde70..2760d8998 100644 --- a/extdep/CMakeLists.txt +++ b/extdep/CMakeLists.txt @@ -35,6 +35,7 @@ if (ETH_COMPILE) include(compile/boost.cmake) else() eth_download(jsoncpp) + eth_download(microhttpd) eth_download(json-rpc-cpp VERSION 4.2 OSX_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/scripts/json-rpc-cpp_osx.sh From 994c0ecbcb7d801e1df9b839bc7465821db22b31 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Fri, 13 Feb 2015 15:36:52 +0100 Subject: [PATCH 147/213] link microhttpd --- cmake/EthDependencies.cmake | 4 +++ cmake/FindMHD.cmake | 47 +++++++++++++++++++++++++++++++++++ libweb3jsonrpc/CMakeLists.txt | 5 +++- 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100755 cmake/FindMHD.cmake diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake index bcb0780c1..fb6b09bb8 100644 --- a/cmake/EthDependencies.cmake +++ b/cmake/EthDependencies.cmake @@ -59,6 +59,10 @@ if (JSONRPC) message (" - json-rpc-cpp lib : ${JSON_RPC_CPP_LIBRARIES}") add_definitions(-DETH_JSONRPC) + find_package(MHD) + message(" - microhttpd header: ${MHD_INCLUDE_DIRS}") + message(" - microhttpd lib : ${MHD_LIBRARIES}") + endif() #JSONRPC # TODO readline package does not yet check for correct version number diff --git a/cmake/FindMHD.cmake b/cmake/FindMHD.cmake new file mode 100755 index 000000000..88df554ef --- /dev/null +++ b/cmake/FindMHD.cmake @@ -0,0 +1,47 @@ +# Find microhttpd +# +# Find the microhttpd includes and library +# +# if you nee to add a custom library search path, do it via via CMAKE_PREFIX_PATH +# +# This module defines +# MHD_INCLUDE_DIRS, where to find header, etc. +# MHD_LIBRARIES, the libraries needed to use jsoncpp. +# MHD_FOUND, If false, do not try to use jsoncpp. + +find_path( + MHD_INCLUDE_DIR + NAMES microhttpd.h + DOC "microhttpd include dir" +) + +find_library( + MHD_LIBRARY + NAMES microhttpd microhttpd-10 libmicrohttpd libmicrohttpd-dll + DOC "microhttpd library" +) + +set(MHD_INCLUDE_DIRS ${MHD_INCLUDE_DIR}) +set(MHD_LIBRARIES ${MHD_LIBRARY}) + +# debug library on windows +# same naming convention as in qt (appending debug library with d) +# boost is using the same "hack" as us with "optimized" and "debug" +# official MHD project actually uses _d suffix +if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + find_library( + MHD_LIBRARY_DEBUG + NAMES microhttpd_d microhttpd-10_d libmicrohttpd_d libmicrohttpd-dll_d + DOC "mhd debug library" + ) + + set(MHD_LIBRARIES optimized ${MHD_LIBRARIES} debug ${MHD_LIBRARY_DEBUG}) + +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(mhd DEFAULT_MSG + MHD_INCLUDE_DIR MHD_LIBRARY) + +mark_as_advanced(MHD_INCLUDE_DIR MHD_LIBRARY) + diff --git a/libweb3jsonrpc/CMakeLists.txt b/libweb3jsonrpc/CMakeLists.txt index 98bbaa339..34df1633a 100644 --- a/libweb3jsonrpc/CMakeLists.txt +++ b/libweb3jsonrpc/CMakeLists.txt @@ -9,9 +9,11 @@ set(CMAKE_AUTOMOC OFF) aux_source_directory(. SRC_LIST) +include_directories(..) +include_directories(${JSONCPP_INCLUDE_DIRS}) +include_directories(${MHD_INCLUDE_DIRS}) include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) include_directories(${LEVELDB_INCLUDE_DIRS}) -include_directories(..) set(EXECUTABLE web3jsonrpc) @@ -26,6 +28,7 @@ endif() target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARIES}) target_link_libraries(${EXECUTABLE} ${JSONCPP_LIBRARIES}) target_link_libraries(${EXECUTABLE} ${JSON_RPC_CPP_SERVER_LIBRARIES}) +target_link_libraries(${EXECUTABLE} ${MHD_LIBRARIES}) target_link_libraries(${EXECUTABLE} webthree) target_link_libraries(${EXECUTABLE} secp256k1) From a576fa1389935ea667a334c8576b3978b1da65bf Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Fri, 13 Feb 2015 15:44:51 +0100 Subject: [PATCH 148/213] Typo in FindMHD.cmake --- cmake/FindMHD.cmake | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cmake/FindMHD.cmake b/cmake/FindMHD.cmake index 88df554ef..84875bc47 100755 --- a/cmake/FindMHD.cmake +++ b/cmake/FindMHD.cmake @@ -1,16 +1,16 @@ -# Find microhttpd +# Find microhttpd # # Find the microhttpd includes and library -# -# if you nee to add a custom library search path, do it via via CMAKE_PREFIX_PATH -# +# +# if you need to add a custom library search path, do it via via CMAKE_PREFIX_PATH +# # This module defines # MHD_INCLUDE_DIRS, where to find header, etc. # MHD_LIBRARIES, the libraries needed to use jsoncpp. # MHD_FOUND, If false, do not try to use jsoncpp. find_path( - MHD_INCLUDE_DIR + MHD_INCLUDE_DIR NAMES microhttpd.h DOC "microhttpd include dir" ) @@ -25,7 +25,7 @@ set(MHD_INCLUDE_DIRS ${MHD_INCLUDE_DIR}) set(MHD_LIBRARIES ${MHD_LIBRARY}) # debug library on windows -# same naming convention as in qt (appending debug library with d) +# same naming convention as in QT (appending debug library with d) # boost is using the same "hack" as us with "optimized" and "debug" # official MHD project actually uses _d suffix if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") From e15859ed27cc33558ebad83f84831ad50dd8e2d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Fri, 13 Feb 2015 16:07:16 +0100 Subject: [PATCH 149/213] Windows fixes --- evmjit/libevmjit/Arith256.cpp | 2 +- libp2p/NodeTable.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/evmjit/libevmjit/Arith256.cpp b/evmjit/libevmjit/Arith256.cpp index 2ec227dcc..15d18c814 100644 --- a/evmjit/libevmjit/Arith256.cpp +++ b/evmjit/libevmjit/Arith256.cpp @@ -416,7 +416,7 @@ namespace explicit operator uint128() { uint128 r = lo; - r |= ((uint128) mid) << 64; + r = r + ((uint128) mid) << 64; return r; } diff --git a/libp2p/NodeTable.h b/libp2p/NodeTable.h index 0217c700e..23ca33661 100644 --- a/libp2p/NodeTable.h +++ b/libp2p/NodeTable.h @@ -168,10 +168,10 @@ public: /// Returns the Node to the corresponding node id or the empty Node if that id is not found. Node node(NodeId const& _id); -#ifndef BOOST_AUTO_TEST_SUITE -private: -#else +#if defined(BOOST_AUTO_TEST_SUITE) || defined(_MSC_VER) // MSVC includes access specifier in symbol name protected: +#else +private: #endif /// Constants for Kademlia, derived from address space. From d119c6c18817a24c1e3791704ea6a7e6e4a354a6 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 13 Feb 2015 16:38:06 +0100 Subject: [PATCH 150/213] Coding standards update. --- CodingStandards.txt | 20 ++++++++++++++++++-- alethzero/MainWin.h | 3 +-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/CodingStandards.txt b/CodingStandards.txt index 8acea78ae..76e1203a4 100644 --- a/CodingStandards.txt +++ b/CodingStandards.txt @@ -1,8 +1,11 @@ 0. Formatting +GOLDEN RULE: Never *ever* use spaces for formatting. + a. Use tabs for indentation! - tab stops are every 4 characters. - One indentation level -> exactly one byte (i.e. a tab character) in the source file. +- Never use spaces to line up sequential lines: If you have run-on lines, indent as you would for a block. b. Line widths: - Don't worry about having lines of code > 80-char wide. - Lines of comments should be formatted according to ease of viewing, but simplicity is to be prefered over beauty. @@ -17,10 +20,22 @@ j. Braces, when used, always have their own lines and are at same indentation le (WRONG) if( a==b[ i ] ) { printf ("Hello\n"); } +foo->bar(someLongVariableName, + anotherLongVariableName, + anotherLongVariableName, + anotherLongVariableName, + anotherLongVariableName); (RIGHT) if (a == b[i]) - printf("Hello\n"); // NOTE spaces used instead of tab here for clarify - first byte should be '\t'. + printf("Hello\n"); // NOTE spaces used instead of tab here for clarity - first byte should be '\t'. +foo->bar( + someLongVariableName, + anotherLongVariableName, + anotherLongVariableName, + anotherLongVariableName, + anotherLongVariableName +); @@ -98,7 +113,7 @@ g. Never use a macro where adequate non-preprocessor C++ can be written. h. Prefer "using NewType = OldType" to "typedef OldType NewType". i. Make use of auto whenever type is clear or unimportant: - Always avoid doubly-stating the type. -- Use to avoid vast and unimportant type declarations +- Use to avoid vast and unimportant type declarations. (WRONG) @@ -173,6 +188,7 @@ d. In general expressions should be roughly as important/semantically meaningful a. Comments should be doxygen-compilable, using @notation rather than \notation. + 12. Include Headers a. Includes should go in order of lower level (STL -> boost -> libdevcore -> libdevcrypto -> libethcore -> libethereum) to higher level. Lower levels are basically dependencies to the higher levels. For example: diff --git a/alethzero/MainWin.h b/alethzero/MainWin.h index 4e21d493f..2625f566d 100644 --- a/alethzero/MainWin.h +++ b/alethzero/MainWin.h @@ -239,8 +239,7 @@ private: /// Attempts to infer that @c _source contains Solidity code bool sourceIsSolidity(std::string const& _source); /// @eturns all method hashes of a Solidity contract in a string - std::string const getFunctionHashes(dev::solidity::CompilerStack const &_compiler, - std::string const& _contractName = ""); + std::string const getFunctionHashes(dev::solidity::CompilerStack const &_compiler, std::string const& _contractName = ""); std::unique_ptr ui; From 2ff89547d6013a84dbfe78ae06909a7911d2930c Mon Sep 17 00:00:00 2001 From: yann300 Date: Fri, 13 Feb 2015 16:48:40 +0100 Subject: [PATCH 151/213] Change in formatting storage values. --- libethcore/CommonJS.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libethcore/CommonJS.cpp b/libethcore/CommonJS.cpp index aa39c8e0c..cc63785bc 100644 --- a/libethcore/CommonJS.cpp +++ b/libethcore/CommonJS.cpp @@ -117,9 +117,9 @@ std::string prettyU256(u256 _n, bool _abridged) n = toHex(a.ref()); if (n.empty()) - s << "0x" << a; + s << "0x0"; else - s << n << "(0x" << n << ")"; + s << "0x" << n <<; } else if ((raw = fromRaw((h256)_n, &inc)).size()) return "\"" + raw + "\"" + (inc ? " + " + std::to_string(inc) : ""); From 9b7a2b7a2da4654d8aa8abcc9459a45ae5ecf830 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 13 Feb 2015 16:51:09 +0100 Subject: [PATCH 152/213] Coding standard updates on documentation. --- CodingStandards.txt | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/CodingStandards.txt b/CodingStandards.txt index 76e1203a4..e1a1b3ba9 100644 --- a/CodingStandards.txt +++ b/CodingStandards.txt @@ -72,6 +72,8 @@ e. Split complex macro on multiple lines with '\'. 3. Capitalization; +GOLDEN RULE: Preprocessor: ALL_CAPS; C++: camelCase. + a. Use camelCase for splitting words in names, except where obviously extending STL/boost functionality in which case follow those naming conventions. b. The following entities' first alpha is upper case: - Type names. @@ -80,6 +82,7 @@ b. The following entities' first alpha is upper case: - static const variables that form an external API. c. All preprocessor symbols (macros, macro argments) in full uppercase with underscore word separation. + All other entities' first alpha is lower case. @@ -137,6 +140,7 @@ for (auto i = x.begin(); i != x.end(); ++i) {} 7. Structs & classes a. Structs to be used when all members public and no virtual functions. +- In this case, members should be named naturally and not prefixed with 'm_' b. Classes to be used in all other circumstances. @@ -146,7 +150,7 @@ b. Classes to be used in all other circumstances. a. One member per line only. b. Private, non-static, non-const fields prefixed with m_. c. Avoid public fields, except in structs. -d. Use override, final and const judiciously. +d. Use override, final and const as much as possible. e. No implementations with the class declaration, except: - template or force-inline method (though prefer implementation at bottom of header file). - one-line implementation (in which case include it in same line as declaration). @@ -169,14 +173,18 @@ c. Avoid unpronouncable names; - If you need to shorten a name favour a pronouncable slice of the original to a scatterred set of consonants. - e.g. Manager shortens to Man rather than Mgr. d. Avoid prefixes of initials (e.g. DON'T use IMyInterface, CMyImplementation) -e. A dictionary and thesaurus are your friends. +e. Find short, memorable & (at least semi-) descriptive names for commonly used classes or name-fragments. +- A dictionary and thesaurus are your friends. - Spell correctly. -- Find short, memorable & (at least semi-) descriptive names for commonly used classes or name-fragments. +- Think carefully about the class's purpose. +- Imagine it as an isolated component to try to decontextualise it when considering its name. +- Don't be trapped into naming it (purely) in terms of its implementation. + 10. Type-definitions -a. Prefer using to typedef. e.g. using ints = std::vector; rather than typedef std::vector ints; +a. Prefer 'using' to 'typedef'. e.g. using ints = std::vector; rather than typedef std::vector ints; b. Generally avoid shortening a standard form that already includes all important information: - e.g. stick to shared_ptr rather than shortening to ptr. c. Where there are exceptions to this (due to excessive use and clear meaning), note the change prominently and use it consistently. @@ -184,9 +192,16 @@ c. Where there are exceptions to this (due to excessive use and clear meaning), d. In general expressions should be roughly as important/semantically meaningful as the space they occupy. + 11. Commenting a. Comments should be doxygen-compilable, using @notation rather than \notation. +b. Document the interface, not the implementation. +- Documentation should be able to remain completely unchanged, even if the method is reimplemented. +- Comment in terms of the method properties and intended alteration to class state (or what aspects of the state it reports). +- Be careful to scrutinise documentation that extends only to intended purpose and usage. +- Reject documentation that is simply an English transaction of the implementation. + 12. Include Headers From 53e901930dfdaffc74f2e1f2d90061e7f0cac34d Mon Sep 17 00:00:00 2001 From: yann300 Date: Fri, 13 Feb 2015 16:52:10 +0100 Subject: [PATCH 153/213] small changes --- libethcore/CommonJS.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libethcore/CommonJS.cpp b/libethcore/CommonJS.cpp index cc63785bc..388738528 100644 --- a/libethcore/CommonJS.cpp +++ b/libethcore/CommonJS.cpp @@ -117,9 +117,9 @@ std::string prettyU256(u256 _n, bool _abridged) n = toHex(a.ref()); if (n.empty()) - s << "0x0"; + s << "0"; else - s << "0x" << n <<; + s << _n << "(0x" << n << ")"; } else if ((raw = fromRaw((h256)_n, &inc)).size()) return "\"" + raw + "\"" + (inc ? " + " + std::to_string(inc) : ""); From 031c1392c6811d0696fd779690413c196aa10cc2 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Fri, 13 Feb 2015 18:25:47 +0100 Subject: [PATCH 154/213] add possibility to create bad blocks in fillers --- test/blValidBlockTestFiller.json | 228 +----------------------- test/block.cpp | 231 +++++++++++++++++++------ test/stSystemOperationsTestFiller.json | 4 +- 3 files changed, 186 insertions(+), 277 deletions(-) diff --git a/test/blValidBlockTestFiller.json b/test/blValidBlockTestFiller.json index d19c8104d..db7138b5b 100644 --- a/test/blValidBlockTestFiller.json +++ b/test/blValidBlockTestFiller.json @@ -1,85 +1,8 @@ { - "diffTooLow" : { - "genesisBlockHeader" : { - "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", - "difficulty" : "1023", - "extraData" : "42", - "gasLimit" : "100000", - "gasUsed" : "0", - "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", - "number" : "0", - "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", - "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", - "timestamp" : "0x54c98c81", - "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" - }, - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "10000000000", - "nonce" : "0", - "code" : "", - "storage": {} - } - }, - "transactions" : [ - { - "data" : "", - "gasLimit" : "850", - "gasPrice" : "1", - "nonce" : "0", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "value" : "10" - } - ], - "uncleHeaders" : [ - ] - }, - - "diff1024" : { - "genesisBlockHeader" : { - "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", - "difficulty" : "1024", - "extraData" : "42", - "gasLimit" : "100000", - "gasUsed" : "0", - "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", - "number" : "0", - "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", - "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", - "timestamp" : "0x54c98c81", - "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" - }, - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "10000000000", - "nonce" : "0", - "code" : "", - "storage": {} - } - }, - "transactions" : [ - { - "data" : "", - "gasLimit" : "850", - "gasPrice" : "1", - "nonce" : "0", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "value" : "10" - } - ], - "uncleHeaders" : [ - ] - }, - - "gasPrice0" : { + "log1" : { + "blockHeader" : { + "number" : "2" + }, "genesisBlockHeader" : { "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", @@ -102,162 +25,27 @@ "nonce" : "0", "code" : "", "storage": {} - } - }, - "transactions" : [ - { - "data" : "", - "gasLimit" : "850", - "gasPrice" : "0", - "nonce" : "0", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "value" : "10" - } - ], - "uncleHeaders" : [ - ] - }, - - "tx" : { - "genesisBlockHeader" : { - "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", - "difficulty" : "10000", - "extraData" : "42", - "gasLimit" : "100000", - "gasUsed" : "0", - "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", - "number" : "0", - "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", - "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", - "timestamp" : "0x54c98c81", - "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" - }, - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "10000000000", - "nonce" : "0", - "code" : "", - "storage": {} - } - }, - "transactions" : [ - { - "data" : "", - "gasLimit" : "500", - "gasPrice" : "10", - "nonce" : "0", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "value" : "10" - } - ], - "uncleHeaders" : [ - ] - }, - - "txOrder" : { - "genesisBlockHeader" : { - "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", - "difficulty" : "10000", - "extraData" : "42", - "gasLimit" : "100000", - "gasUsed" : "0", - "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", - "number" : "0", - "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", - "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", - "timestamp" : "0x54c98c81", - "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" - }, - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "10000000000", - "nonce" : "0", - "code" : "", - "storage": {} - } - }, - "transactions" : [ - { - "data" : "", - "gasLimit" : "500", - "gasPrice" : "10", - "nonce" : "0", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "value" : "7000000000" }, - { - "data" : "", - "gasLimit" : "500", - "gasPrice" : "10", + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "100", "nonce" : "0", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "value" : "8000000000" - } - ], - "uncleHeaders" : [ - ] - }, - - "txEqualValue" : { - "genesisBlockHeader" : { - "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", - "difficulty" : "10000", - "extraData" : "42", - "gasLimit" : "100000", - "gasUsed" : "0", - "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", - "number" : "0", - "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", - "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", - "timestamp" : "0x54c98c81", - "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" - }, - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "10000000000", - "nonce" : "0", - "code" : "", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG1 0 32 0) }", "storage": {} } }, "transactions" : [ { "data" : "", - "gasLimit" : "500", + "gasLimit" : "5000", "gasPrice" : "10", "nonce" : "0", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "5000000000" - }, - { - "data" : "", - "gasLimit" : "500", - "gasPrice" : "9", - "nonce" : "0", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "value" : "5000000000" } ], "uncleHeaders" : [ ] } - - - } diff --git a/test/block.cpp b/test/block.cpp index 2d44e8d71..4d1f5accc 100644 --- a/test/block.cpp +++ b/test/block.cpp @@ -1,18 +1,18 @@ /* - This file is part of cpp-ethereum. + 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 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. + 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 . + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . */ /** @file block.cpp * @author Christoph Jentzsch @@ -32,60 +32,60 @@ namespace dev { namespace test { bytes createBlockRLPFromFields(mObject& _tObj) { - RLPStream rlpStream; - rlpStream.appendList(_tObj.size()); + RLPStream rlpStream; + rlpStream.appendList(_tObj.size()); - if (_tObj.count("parentHash") > 0) - rlpStream << importByteArray(_tObj["parentHash"].get_str()); + if (_tObj.count("parentHash") > 0) + rlpStream << importByteArray(_tObj["parentHash"].get_str()); - if (_tObj.count("uncleHash") > 0) - rlpStream << importByteArray(_tObj["uncleHash"].get_str()); + if (_tObj.count("uncleHash") > 0) + rlpStream << importByteArray(_tObj["uncleHash"].get_str()); - if (_tObj.count("coinbase") > 0) - rlpStream << importByteArray(_tObj["coinbase"].get_str()); + if (_tObj.count("coinbase") > 0) + rlpStream << importByteArray(_tObj["coinbase"].get_str()); - if (_tObj.count("stateRoot") > 0) - rlpStream << importByteArray(_tObj["stateRoot"].get_str()); + if (_tObj.count("stateRoot") > 0) + rlpStream << importByteArray(_tObj["stateRoot"].get_str()); - if (_tObj.count("transactionsTrie") > 0) - rlpStream << importByteArray(_tObj["transactionsTrie"].get_str()); + if (_tObj.count("transactionsTrie") > 0) + rlpStream << importByteArray(_tObj["transactionsTrie"].get_str()); - if (_tObj.count("receiptTrie") > 0) - rlpStream << importByteArray(_tObj["receiptTrie"].get_str()); + if (_tObj.count("receiptTrie") > 0) + rlpStream << importByteArray(_tObj["receiptTrie"].get_str()); - if (_tObj.count("bloom") > 0) - rlpStream << importByteArray(_tObj["bloom"].get_str()); + if (_tObj.count("bloom") > 0) + rlpStream << importByteArray(_tObj["bloom"].get_str()); - if (_tObj.count("difficulty") > 0) - rlpStream << bigint(_tObj["difficulty"].get_str()); + if (_tObj.count("difficulty") > 0) + rlpStream << bigint(_tObj["difficulty"].get_str()); - if (_tObj.count("number") > 0) - rlpStream << bigint(_tObj["number"].get_str()); + if (_tObj.count("number") > 0) + rlpStream << bigint(_tObj["number"].get_str()); - if (_tObj.count("gasLimit") > 0) - rlpStream << bigint(_tObj["gasLimit"].get_str()); + if (_tObj.count("gasLimit") > 0) + rlpStream << bigint(_tObj["gasLimit"].get_str()); - if (_tObj.count("gasUsed") > 0) - rlpStream << bigint(_tObj["gasUsed"].get_str()); + if (_tObj.count("gasUsed") > 0) + rlpStream << bigint(_tObj["gasUsed"].get_str()); - if (_tObj.count("timestamp") > 0) - rlpStream << bigint(_tObj["timestamp"].get_str()); + if (_tObj.count("timestamp") > 0) + rlpStream << bigint(_tObj["timestamp"].get_str()); - if (_tObj.count("extraData") > 0) - rlpStream << importByteArray(_tObj["extraData"].get_str()); + if (_tObj.count("extraData") > 0) + rlpStream << importByteArray(_tObj["extraData"].get_str()); - if (_tObj.count("nonce") > 0) - rlpStream << importByteArray(_tObj["nonce"].get_str()); + if (_tObj.count("nonce") > 0) + rlpStream << importByteArray(_tObj["nonce"].get_str()); - return rlpStream.out(); + return rlpStream.out(); } void doBlockTests(json_spirit::mValue& _v, bool _fillin) { - for (auto& i: _v.get_obj()) - { - cerr << i.first << endl; - mObject& o = i.second.get_obj(); + for (auto& i: _v.get_obj()) + { + cerr << i.first << endl; + mObject& o = i.second.get_obj(); BOOST_REQUIRE(o.count("genesisBlockHeader") > 0); cout << "construc genesis\n"; @@ -197,9 +197,12 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) // write valid txs cout << "number of valid txs: " << txs.transactions().size(); mArray txArray; + Transactions txList; for (auto const& txi: txs.transactions()) { + cout << "AHA0" << endl; Transaction tx(txi.second, CheckSignature::Sender); + txList.push_back(tx); mObject txObject; txObject["nonce"] = toString(tx.nonce()); txObject["data"] = toHex(tx.data()); @@ -210,10 +213,11 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) txObject["v"] = to_string(tx.signature().v + 27); txObject["to"] = toString(tx.receiveAddress()); txObject["value"] = toString(tx.value()); + cout << "AHA0.5" << endl; txArray.push_back(txObject); } - + cout << "AHA1" << endl; o["transactions"] = txArray; o["rlp"] = "0x" + toHex(state.blockData()); @@ -237,12 +241,125 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) oBlockHeader["extraData"] = toHex(current_BlockHeader.extraData); oBlockHeader["nonce"] = toString(current_BlockHeader.nonce); - o["blockHeader"] = oBlockHeader; - // write uncle list - mArray aUncleList; // as of now, our parent is always the genesis block, so we can not have uncles. - o["uncleHeaders"] = aUncleList; + // overwrite (wrong) data from blockheader in filler" << endl; + + if (o.count("blockHeader") > 0) + { + if (o["blockHeader"].get_obj().size() != 14) + { + + BlockInfo tmp = current_BlockHeader; + + if (o["blockHeader"].get_obj().count("parentHash") > 0) + tmp.parentHash = h256(o["blockHeader"].get_obj()["parentHash"].get_str()); + + if (o["blockHeader"].get_obj().count("sha3Uncles") > 0) + tmp.sha3Uncles = h256(o["blockHeader"].get_obj()["uncleHash"].get_str()); + + if (o["blockHeader"].get_obj().count("coinbase") > 0) + tmp.coinbaseAddress = Address(o["blockHeader"].get_obj()["coinbase"].get_str()); + + if (o["blockHeader"].get_obj().count("stateRoot") > 0) + tmp.stateRoot = h256(o["blockHeader"].get_obj()["stateRoot"].get_str()); + + if (o["blockHeader"].get_obj().count("transactionsTrie") > 0) + tmp.transactionsRoot = h256(o["blockHeader"].get_obj()["transactionsTrie"].get_str()); + + if (o["blockHeader"].get_obj().count("receiptTrie") > 0) + tmp.receiptsRoot = h256(o["blockHeader"].get_obj()["receiptTrie"].get_str()); + + if (o["blockHeader"].get_obj().count("bloom") > 0) + tmp.logBloom = LogBloom(o["blockHeader"].get_obj()["bloom"].get_str()); + + if (o["blockHeader"].get_obj().count("difficulty") > 0) + tmp.difficulty = toInt(o["blockHeader"].get_obj()["difficulty"]); + + if (o["blockHeader"].get_obj().count("number") > 0) + tmp.number = toInt(o["blockHeader"].get_obj()["number"]); + + if (o["blockHeader"].get_obj().count("gasLimit") > 0) + tmp.gasLimit = toInt(o["blockHeader"].get_obj()["gasLimit"]); + + if (o["blockHeader"].get_obj().count("gasUsed") > 0) + tmp.gasUsed = toInt(o["blockHeader"].get_obj()["gasUsed"]); + + if (o["blockHeader"].get_obj().count("timestamp") > 0) + tmp.timestamp = toInt(o["blockHeader"].get_obj()["timestamp"]); + + if (o["blockHeader"].get_obj().count("extraData") > 0) + tmp.extraData = importByteArray(o["blockHeader"].get_obj()["extraData"].get_str()); + + // find new valid nonce + + if (tmp != current_BlockHeader) + { + current_BlockHeader = tmp; + cout << "new header!\n"; + ProofOfWork pow; + MineInfo ret; + while (!ProofOfWork::verify(current_BlockHeader.headerHash(WithoutNonce), current_BlockHeader.nonce, current_BlockHeader.difficulty)) + tie(ret, current_BlockHeader.nonce) = pow.mine(current_BlockHeader.headerHash(WithoutNonce), current_BlockHeader.difficulty, 10000, true, true); + oBlockHeader["nonce"] = toString(current_BlockHeader.nonce); + } + } + else + { + // take the blockheader as is + const bytes c_blockRLP = createBlockRLPFromFields(o["genesisBlockHeader"].get_obj()); + const RLP c_bRLP(c_blockRLP); + current_BlockHeader.populateFromHeader(c_bRLP, false); + } + } + + //txs: + + RLPStream txStream; + txStream.appendList(txList.size()); + for (unsigned i = 0; i < txList.size(); ++i) + { + RLPStream txrlp; + txList[i].streamRLP(txrlp); + txStream.appendRaw(txrlp.out()); + } + + cout << "create block:" << endl; + + RLPStream rlpStream2; + current_BlockHeader.streamRLP(rlpStream2, WithNonce); + + RLPStream block2(3); + block2.appendRaw(rlpStream2.out()); + block2.appendRaw(txStream.out()); + block2.appendRaw(RLPEmptyList); + + if (sha3(RLP(state.blockData())[0].data()) != sha3(RLP(block2.out())[0].data())) + cout << "block 0 wrong" << endl; + + if (sha3(RLP(state.blockData())[1].data()) != sha3(RLP(block2.out())[1].data())) + cout << "block 1 wrong" << endl; + + if (sha3(RLP(state.blockData())[2].data()) != sha3(RLP(block2.out())[2].data())) + cout << "block 2 wrong" << endl; + + + if (sha3(state.blockData()) != sha3(block2.out())) + { + cout << "blocks do not match!" << endl; + o["rlp"] = "0x" + toHex(block2.out()); + o.erase(o.find("blockHeader")); + o.erase(o.find("uncleHeaders")); + o.erase(o.find("transactions")); + } + else + { + o["blockHeader"] = oBlockHeader; + + // write uncle list + mArray aUncleList; // as of now, our parent is always the genesis block, so we can not have uncles. + o["uncleHeaders"] = aUncleList; + } } else @@ -254,13 +371,14 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) bc.import(blockRLP, state.db()); state.sync(bc); } - // if exception is thrown, RLP is invalid and no blockHeader, Transaction list, or Uncle list should be given + // if exception is thrown, RLP is invalid and no blockHeader, Transaction list, or Uncle list should be given catch (Exception const& _e) { cnote << "state sync or block import did throw an exception: " << diagnostic_information(_e); BOOST_CHECK(o.count("blockHeader") == 0); BOOST_CHECK(o.count("transactions") == 0); BOOST_CHECK(o.count("uncleHeaders") == 0); + return; } catch (std::exception const& _e) { @@ -268,6 +386,7 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) BOOST_CHECK(o.count("blockHeader") == 0); BOOST_CHECK(o.count("transactions") == 0); BOOST_CHECK(o.count("uncleHeaders") == 0); + return; } catch(...) { @@ -275,8 +394,10 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) BOOST_CHECK(o.count("blockHeader") == 0); BOOST_CHECK(o.count("transactions") == 0); BOOST_CHECK(o.count("uncleHeaders") == 0); + return; } - + cout << "valid block header\n"; + //cout << "block number: " << BOOST_REQUIRE(o.count("blockHeader") > 0); mObject tObj = o["blockHeader"].get_obj(); @@ -388,12 +509,12 @@ BOOST_AUTO_TEST_SUITE(BlockTests) BOOST_AUTO_TEST_CASE(blValidBlockTest) { - dev::test::executeTests("blValidBlockTest", "/BlockTests", dev::test::doBlockTests); + dev::test::executeTests("blValidBlockTest", "/BlockTests", dev::test::doBlockTests); } BOOST_AUTO_TEST_CASE(userDefinedFileBl) { - dev::test::userDefinedTest("--bltest", dev::test::doBlockTests); + dev::test::userDefinedTest("--bltest", dev::test::doBlockTests); } BOOST_AUTO_TEST_SUITE_END() diff --git a/test/stSystemOperationsTestFiller.json b/test/stSystemOperationsTestFiller.json index eae393645..9f47b2fef 100644 --- a/test/stSystemOperationsTestFiller.json +++ b/test/stSystemOperationsTestFiller.json @@ -81,13 +81,13 @@ "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "0x444242424245434253f0", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", - "nonce" : 0, + "nonce" : "0", "code" : "", "storage": {} } From ece46d70ea403fc601a4865988e25a65e1c97ee2 Mon Sep 17 00:00:00 2001 From: yann300 Date: Fri, 13 Feb 2015 18:55:59 +0100 Subject: [PATCH 155/213] WebPreview ui redesign --- mix/qml/CodeEditorView.qml | 3 +- mix/qml/WebPreview.qml | 124 +++++++++++++++++++++--------- mix/qml/WebPreviewStyle.qml | 14 ++++ mix/qml/img/available_updates.png | Bin 0 -> 889 bytes mix/qml/qmldir | 1 + mix/res.qrc | 2 + 6 files changed, 108 insertions(+), 36 deletions(-) create mode 100644 mix/qml/WebPreviewStyle.qml create mode 100644 mix/qml/img/available_updates.png diff --git a/mix/qml/CodeEditorView.qml b/mix/qml/CodeEditorView.qml index 4d54994fe..9c0b804d7 100644 --- a/mix/qml/CodeEditorView.qml +++ b/mix/qml/CodeEditorView.qml @@ -19,7 +19,8 @@ Item { function isDocumentOpen(documentId) { for (var i = 0; i < editorListModel.count; i++) - if (editorListModel.get(i).documentId === documentId) + if (editorListModel.get(i).documentId === documentId && + editors.itemAt(i).item) return true; return false; } diff --git a/mix/qml/WebPreview.qml b/mix/qml/WebPreview.qml index 10d0b3c83..88b992b54 100644 --- a/mix/qml/WebPreview.qml +++ b/mix/qml/WebPreview.qml @@ -6,6 +6,7 @@ import QtQuick.Controls.Styles 1.1 import QtWebEngine 1.0 import QtWebEngine.experimental 1.0 import HttpServer 1.0 +import "." Item { id: webPreview @@ -38,7 +39,7 @@ Item { function updateDocument(documentId, action) { for (var i = 0; i < pageListModel.count; i++) - if (pageListModel.get(i).documentId === i) + if (pageListModel.get(i).documentId === documentId) action(i); } @@ -82,10 +83,22 @@ Item { onDocumentRemoved: { updateDocument(documentId, function(i) { pageListModel.remove(i) } ) } + onDocumentUpdated: { updateDocument(documentId, function(i) { pageListModel.set(i, projectModel.getDocument(documentId)) } ) } + onDocumentOpened: { + if (!document.isHtml) + return; + for (var i = 0; i < pageListModel.count; i++) { + var doc = pageListModel.get(i); + if (doc.documentId === document.documentId) { + pageCombo.currentIndex = i; + } + } + } + onProjectLoading: { for (var i = 0; i < target.listModel.count; i++) { var document = target.listModel.get(i); @@ -146,45 +159,86 @@ Item { ColumnLayout { anchors.fill: parent - - RowLayout { - anchors.top: parent.top - Layout.fillWidth: true; - Text { - text: qsTr("Page") - } - ComboBox { - id: pageCombo - model: pageListModel - textRole: "name" - currentIndex: -1 - onCurrentIndexChanged: changePage() - } - Button { - text: qsTr("Reload") - onClicked: reload() + spacing: 0 + Rectangle + { + SourceSansProLight + { + id: regularFont } - CheckBox { - id: autoReloadOnSave - checked: true - text: qsTr("Auto reload on save") + + anchors.leftMargin: 4 + color: WebPreviewStyle.general.headerBackgroundColor + Layout.preferredWidth: parent.width + Layout.preferredHeight: 32 + Row { + anchors.top: parent.top + anchors.fill: parent + anchors.leftMargin: 3 + spacing: 3 + DefaultLabel { + text: qsTr("Preview of") + anchors.verticalCenter: parent.verticalCenter + } + + ComboBox { + id: pageCombo + model: pageListModel + textRole: "name" + currentIndex: -1 + onCurrentIndexChanged: changePage() + anchors.verticalCenter: parent.verticalCenter + style: ComboBoxStyle { + font: regularFont.name + } + } + + Action { + tooltip: qsTr("Reload") + id: buttonReloadAction + onTriggered: { + reload(); + } + } + + Button { + iconSource: "qrc:/qml/img/available_updates.png" + action: buttonReloadAction + anchors.verticalCenter: parent.verticalCenter + width: 26 + height: 26 + } + CheckBox { + id: autoReloadOnSave + checked: true + anchors.verticalCenter: parent.verticalCenter + style: CheckBoxStyle { + label: DefaultLabel { + text: qsTr("Auto reload on save") + } + } + } } } - WebEngineView { - Layout.fillWidth: true + Rectangle + { + Layout.preferredWidth: parent.width Layout.fillHeight: true - id: webView - experimental.settings.localContentCanAccessRemoteUrls: true - onJavaScriptConsoleMessage: { - console.log(sourceID + ":" + lineNumber + ":" + message); - } - onLoadingChanged: { - if (!loading) { - initialized = true; - webView.runJavaScript("init(\"" + httpServer.url + "/rpc/\")"); - if (pendingPageUrl) - setPreviewUrl(pendingPageUrl); + WebEngineView { + anchors.fill: parent + id: webView + experimental.settings.localContentCanAccessRemoteUrls: true + onJavaScriptConsoleMessage: { + console.log(sourceID + ":" + lineNumber + ":" + message); + } + onLoadingChanged: { + if (!loading) { + initialized = true; + webView.runJavaScript("init(\"" + httpServer.url + "/rpc/\")"); + if (pendingPageUrl) + setPreviewUrl(pendingPageUrl); + } } } } diff --git a/mix/qml/WebPreviewStyle.qml b/mix/qml/WebPreviewStyle.qml new file mode 100644 index 000000000..551f5a446 --- /dev/null +++ b/mix/qml/WebPreviewStyle.qml @@ -0,0 +1,14 @@ +pragma Singleton +import QtQuick 2.0 + +QtObject { + + function absoluteSize(rel) + { + return systemPointSize + rel; + } + + property QtObject general: QtObject { + property string headerBackgroundColor: "#f0f0f0" + } +} diff --git a/mix/qml/img/available_updates.png b/mix/qml/img/available_updates.png new file mode 100644 index 0000000000000000000000000000000000000000..fa08c1d80754a1edf631eef463a23958c6d0f9f1 GIT binary patch literal 889 zcmV-<1BU#GP)l0v$LNgbr{jfK-4}0Z;*^0@4Adf+Q8>s34&NOa(v%pwF{AbF*`|l6Lpb z&Wtsq@t?G-Cq3=y&Zj4bAzvko>zYtbYn&VTzLj-uML&w(l&*OQKsFNmJJCO)=i$|j z=MaGWmZ)EZ$nWI!%8f!C_6=kyF+3!J0|Y=W**6e+;(Zcv5yhqi@>&911WmL16ncUF zz$O(p#aaS^=QJ&+5R|DE7sXltA)}u}SGAGXP^=aR{9cR3Q>QVOUDKORu~Hxe&PA*R zg*5Ocij@EX1V`p8ErLeBn@%w=5J3E#kV<3NRf>6lcq;KjA|jJi?W|E{vJ~?Gp(i+6 zQ~4!dkg+Z(08$|d^b@)&1ec|l6-b;=`vHEJ59<)TC+Sq_(c=(o*^eY_hkPwS(!R(p zXbA9w*nBbAMU!vxW}_v{0wm5ue?vyx16>kyC!ZN#a>8EhL&XOxkUDEX7UIAubss9{ktw@fkfj!yND&kp7v*q+7`%q}B8GC=96Noo9m;DilD_t`fA1jhcGEL3BJ6Gq; z48_=O(Xt`{;MSK}iuaeI-E#u6kYLk?4^#s%twg;r*HmN~Dll}9!fZD5eF?CYII$P6 zqf!FoO`s2pk4e>&^{^-vW!wkAx#+eP5E^(bx-g_w-B?+JB=MgKdoj*rtHD}YMPdW9 zkOcs1GRazPQ#|-lg+47!Ny!1>^r4BpOh@L;=7)LltDi=XaB6)FK#~dv1ZA9J%JZL=6bE+KRS%Hf2c&*B~n4x}np6 zuyGB=EP?lJs091DK(K%X2zGN&jGh35nNIx-SbiFQxV*A6pLf~awI^4pG>?!#wgZ$Yqml/DefaultTextField.qml qml/CommonSeparator.qml qml/Style.qml + qml/WebPreviewStyle.qml + qml/img/available_updates.png From 8bc011394b78cc970c2211075e185261f78f76e2 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Fri, 13 Feb 2015 22:10:03 +0100 Subject: [PATCH 156/213] update windows precompiled qt version 5.3 -> 5.4 --- extdep/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extdep/CMakeLists.txt b/extdep/CMakeLists.txt index fdee34602..b5038bd0c 100644 --- a/extdep/CMakeLists.txt +++ b/extdep/CMakeLists.txt @@ -42,7 +42,7 @@ else() endif() eth_download(leveldb OSX_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/scripts/leveldb_osx.sh) - eth_download(qt) + eth_download(qt VERSION 5.4) eth_download(cryptopp) eth_download(boost) eth_download(curl) From 5fe0aca0b6b1aba8ad57ab54028f7b250fd90afe Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 13 Feb 2015 23:13:03 +0100 Subject: [PATCH 157/213] Debugger separate from AlethZero mainwin. --- alethzero/CMakeLists.txt | 3 +- alethzero/Context.cpp | 26 +++ alethzero/Context.h | 41 +++++ alethzero/Debugger.cpp | 372 +++++++++++++++++++++++++++++++++++++++ alethzero/Debugger.h | 102 +++++++++++ alethzero/Debugger.ui | 238 +++++++++++++++++++++++++ alethzero/MainWin.h | 35 ++-- libdevcore/vector_ref.h | 3 +- 8 files changed, 793 insertions(+), 27 deletions(-) create mode 100644 alethzero/Context.cpp create mode 100644 alethzero/Context.h create mode 100644 alethzero/Debugger.cpp create mode 100644 alethzero/Debugger.h create mode 100644 alethzero/Debugger.ui diff --git a/alethzero/CMakeLists.txt b/alethzero/CMakeLists.txt index c18a76c36..17462bad8 100644 --- a/alethzero/CMakeLists.txt +++ b/alethzero/CMakeLists.txt @@ -15,6 +15,7 @@ include_directories(BEFORE ${JSONCPP_INCLUDE_DIRS}) include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) qt5_wrap_ui(ui_Main.h Main.ui) +qt5_wrap_ui(ui_Debugger.h Debugger.ui) file(GLOB HEADERS "*.h") @@ -27,7 +28,7 @@ endif () # eth_add_executable is defined in cmake/EthExecutableHelper.cmake eth_add_executable(${EXECUTABLE} ICON alethzero - UI_RESOURCES alethzero.icns Main.ui + UI_RESOURCES alethzero.icns Main.ui Debugger.ui WIN_RESOURCES alethzero.rc ) diff --git a/alethzero/Context.cpp b/alethzero/Context.cpp new file mode 100644 index 000000000..0505a03e0 --- /dev/null +++ b/alethzero/Context.cpp @@ -0,0 +1,26 @@ +/* + 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 Debugger.h + * @author Gav Wood + * @date 2015 + */ + +#include "Context.h" + +Context::~Context() +{ +} diff --git a/alethzero/Context.h b/alethzero/Context.h new file mode 100644 index 000000000..2a41988a3 --- /dev/null +++ b/alethzero/Context.h @@ -0,0 +1,41 @@ +/* + 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 Debugger.h + * @author Gav Wood + * @date 2015 + */ + +#pragma once + +#include +#include +#include + +namespace dev { namespace eth { class StateDiff; } } + +class Context +{ +public: + virtual ~Context(); + + virtual QString pretty(dev::Address _a) const = 0; + virtual QString prettyU256(dev::u256 _n) const = 0; + virtual QString render(dev::Address _a) const = 0; + virtual dev::Address fromString(QString const& _a) const = 0; + virtual std::string renderDiff(dev::eth::StateDiff const& _d) const = 0; +}; + diff --git a/alethzero/Debugger.cpp b/alethzero/Debugger.cpp new file mode 100644 index 000000000..690c281f9 --- /dev/null +++ b/alethzero/Debugger.cpp @@ -0,0 +1,372 @@ +/* + 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 Debugger.cpp + * @author Gav Wood + * @date 2015 + */ + +#include "Debugger.h" + +#include +#include +#include +#include +#include +#include "ui_Debugger.h" +using namespace std; +using namespace dev; +using namespace dev::eth; + +Debugger::Debugger(Context* _c, QWidget* _parent): + QDialog(_parent), + ui(new Ui::Debugger), + m_context(_c) +{ + ui->setupUi(this); +} + +Debugger::~Debugger() +{ + delete ui; +} + +void Debugger::init() +{ + if (m_session.history.size()) + { + alterDebugStateGroup(true); + ui->debugCode->setEnabled(false); + ui->debugTimeline->setMinimum(0); + ui->debugTimeline->setMaximum(m_session.history.size()); + ui->debugTimeline->setValue(0); + } +} + +void Debugger::populate(dev::eth::Executive& _executive, dev::bytesConstRef _transactionRLP) +{ + finished(); + if (m_session.populate(_executive, _transactionRLP)) + init(); + update(); +} + +bool DebugSession::populate(dev::eth::Executive& _executive, dev::bytesConstRef _transactionRLP) +{ + if (_executive.setup(_transactionRLP)) + return false; + vector levels; + bytes lastExtCode; + bytesConstRef lastData; + h256 lastHash; + h256 lastDataHash; + auto onOp = [&](uint64_t steps, Instruction inst, dev::bigint newMemSize, dev::bigint gasCost, VM* voidVM, ExtVMFace const* voidExt) + { + VM& vm = *voidVM; + ExtVM const& ext = *static_cast(voidExt); + if (ext.code != lastExtCode) + { + lastExtCode = ext.code; + lastHash = sha3(lastExtCode); + if (!codes.count(lastHash)) + codes[lastHash] = ext.code; + } + if (ext.data != lastData) + { + lastData = ext.data; + lastDataHash = sha3(lastData); + if (!codes.count(lastDataHash)) + codes[lastDataHash] = ext.data.toBytes(); + } + if (levels.size() < ext.depth) + levels.push_back(&history.back()); + else + levels.resize(ext.depth); + history.append(WorldState({steps, ext.myAddress, vm.curPC(), inst, newMemSize, vm.gas(), lastHash, lastDataHash, vm.stack(), vm.memory(), gasCost, ext.state().storage(ext.myAddress), levels})); + }; + _executive.go(onOp); + _executive.finalize(); + return true; +} + +void Debugger::finished() +{ + m_session = DebugSession(); + ui->callStack->clear(); + ui->debugCode->clear(); + ui->debugStack->clear(); + ui->debugMemory->setHtml(""); + ui->debugStorage->setHtml(""); + ui->debugStateInfo->setText(""); + alterDebugStateGroup(false); +} + +void Debugger::update() +{ + if (m_session.history.size()) + { + WorldState const& nws = m_session.history[min((int)m_session.history.size() - 1, ui->debugTimeline->value())]; + WorldState const& ws = ui->callStack->currentRow() > 0 ? *nws.levels[nws.levels.size() - ui->callStack->currentRow()] : nws; + + if (ui->debugTimeline->value() >= m_session.history.size()) + { + if (ws.gasCost > ws.gas) + ui->debugMemory->setHtml("

OUT-OF-GAS

"); + else if (ws.inst == Instruction::RETURN && ws.stack.size() >= 2) + { + unsigned from = (unsigned)ws.stack.back(); + unsigned size = (unsigned)ws.stack[ws.stack.size() - 2]; + unsigned o = 0; + bytes out(size, 0); + for (; o < size && from + o < ws.memory.size(); ++o) + out[o] = ws.memory[from + o]; + ui->debugMemory->setHtml("

RETURN

" + QString::fromStdString(dev::memDump(out, 16, true))); + } + else if (ws.inst == Instruction::STOP) + ui->debugMemory->setHtml("

STOP

"); + else if (ws.inst == Instruction::SUICIDE && ws.stack.size() >= 1) + ui->debugMemory->setHtml("

SUICIDE

0x" + QString::fromStdString(toString(right160(ws.stack.back())))); + else + ui->debugMemory->setHtml("

EXCEPTION

"); + + ostringstream ss; + ss << dec << "EXIT | GAS: " << dec << max(0, (dev::bigint)ws.gas - ws.gasCost); + ui->debugStateInfo->setText(QString::fromStdString(ss.str())); + ui->debugStorage->setHtml(""); + ui->debugCallData->setHtml(""); + m_session.currentData = h256(); + ui->callStack->clear(); + m_session.currentLevels.clear(); + ui->debugCode->clear(); + m_session.currentCode = h256(); + ui->debugStack->setHtml(""); + } + else + { + if (m_session.currentLevels != nws.levels || !ui->callStack->count()) + { + m_session.currentLevels = nws.levels; + ui->callStack->clear(); + for (unsigned i = 0; i <= nws.levels.size(); ++i) + { + WorldState const& s = i ? *nws.levels[nws.levels.size() - i] : nws; + ostringstream out; + out << s.cur.abridged(); + if (i) + out << " " << instructionInfo(s.inst).name << " @0x" << hex << s.curPC; + ui->callStack->addItem(QString::fromStdString(out.str())); + } + } + + if (ws.code != m_session.currentCode) + { + m_session.currentCode = ws.code; + bytes const& code = m_session.codes[ws.code]; + QListWidget* dc = ui->debugCode; + dc->clear(); + m_session.pcWarp.clear(); + for (unsigned i = 0; i <= code.size(); ++i) + { + byte b = i < code.size() ? code[i] : 0; + try + { + QString s = QString::fromStdString(instructionInfo((Instruction)b).name); + ostringstream out; + out << hex << setw(4) << setfill('0') << i; + m_session.pcWarp[i] = dc->count(); + if (b >= (byte)Instruction::PUSH1 && b <= (byte)Instruction::PUSH32) + { + unsigned bc = b - (byte)Instruction::PUSH1 + 1; + s = "PUSH 0x" + QString::fromStdString(toHex(bytesConstRef(&code[i + 1], bc))); + i += bc; + } + dc->addItem(QString::fromStdString(out.str()) + " " + s); + } + catch (...) + { + cerr << "Unhandled exception!" << endl << boost::current_exception_diagnostic_information(); + break; // probably hit data segment + } + } + } + + if (ws.callData != m_session.currentData) + { + m_session.currentData = ws.callData; + if (ws.callData) + { + assert(m_session.codes.count(ws.callData)); + ui->debugCallData->setHtml(QString::fromStdString(dev::memDump(m_session.codes[ws.callData], 16, true))); + } + else + ui->debugCallData->setHtml(""); + } + + QString stack; + for (auto i: ws.stack) + stack.prepend("
" + m_context->prettyU256(i) + "
"); + ui->debugStack->setHtml(stack); + ui->debugMemory->setHtml(QString::fromStdString(dev::memDump(ws.memory, 16, true))); + assert(m_session.codes.count(ws.code)); + + if (m_session.codes[ws.code].size() >= (unsigned)ws.curPC) + { + int l = m_session.pcWarp[(unsigned)ws.curPC]; + ui->debugCode->setCurrentRow(max(0, l - 5)); + ui->debugCode->setCurrentRow(min(ui->debugCode->count() - 1, l + 5)); + ui->debugCode->setCurrentRow(l); + } + else + cwarn << "PC (" << (unsigned)ws.curPC << ") is after code range (" << m_session.codes[ws.code].size() << ")"; + + ostringstream ss; + ss << dec << "STEP: " << ws.steps << " | PC: 0x" << hex << ws.curPC << " : " << instructionInfo(ws.inst).name << " | ADDMEM: " << dec << ws.newMemSize << " words | COST: " << dec << ws.gasCost << " | GAS: " << dec << ws.gas; + ui->debugStateInfo->setText(QString::fromStdString(ss.str())); + stringstream s; + for (auto const& i: ws.storage) + s << "@" << m_context->prettyU256(i.first).toStdString() << "    " << m_context->prettyU256(i.second).toStdString() << "
"; + ui->debugStorage->setHtml(QString::fromStdString(s.str())); + } + } +} + +void Debugger::on_callStack_currentItemChanged() +{ + update(); +} + +void Debugger::alterDebugStateGroup(bool _enable) const +{ + ui->stepOver->setEnabled(_enable); + ui->stepInto->setEnabled(_enable); + ui->stepOut->setEnabled(_enable); + ui->backOver->setEnabled(_enable); + ui->backInto->setEnabled(_enable); + ui->backOut->setEnabled(_enable); + ui->dump->setEnabled(_enable); + ui->dumpStorage->setEnabled(_enable); + ui->dumpPretty->setEnabled(_enable); +} + +void Debugger::on_debugTimeline_valueChanged() +{ + update(); +} + +void Debugger::on_stepOver_triggered() +{ + if (ui->debugTimeline->value() < m_session.history.size()) { + auto l = m_session.history[ui->debugTimeline->value()].levels.size(); + if ((ui->debugTimeline->value() + 1) < m_session.history.size() && m_session.history[ui->debugTimeline->value() + 1].levels.size() > l) + { + on_stepInto_triggered(); + if (m_session.history[ui->debugTimeline->value()].levels.size() > l) + on_stepOut_triggered(); + } + else + on_stepInto_triggered(); + } +} + +void Debugger::on_stepInto_triggered() +{ + ui->debugTimeline->setValue(ui->debugTimeline->value() + 1); + ui->callStack->setCurrentRow(0); +} + +void Debugger::on_stepOut_triggered() +{ + if (ui->debugTimeline->value() < m_session.history.size()) + { + auto ls = m_session.history[ui->debugTimeline->value()].levels.size(); + auto l = ui->debugTimeline->value(); + for (; l < m_session.history.size() && m_session.history[l].levels.size() >= ls; ++l) {} + ui->debugTimeline->setValue(l); + ui->callStack->setCurrentRow(0); + } +} + +void Debugger::on_backInto_triggered() +{ + ui->debugTimeline->setValue(ui->debugTimeline->value() - 1); + ui->callStack->setCurrentRow(0); +} + +void Debugger::on_backOver_triggered() +{ + auto l = m_session.history[ui->debugTimeline->value()].levels.size(); + if (ui->debugTimeline->value() > 0 && m_session.history[ui->debugTimeline->value() - 1].levels.size() > l) + { + on_backInto_triggered(); + if (m_session.history[ui->debugTimeline->value()].levels.size() > l) + on_backOut_triggered(); + } + else + on_backInto_triggered(); +} + +void Debugger::on_backOut_triggered() +{ + if (ui->debugTimeline->value() > 0 && m_session.history.size() > 0) + { + auto ls = m_session.history[min(ui->debugTimeline->value(), m_session.history.size() - 1)].levels.size(); + int l = ui->debugTimeline->value(); + for (; l > 0 && m_session.history[l].levels.size() >= ls; --l) {} + ui->debugTimeline->setValue(l); + ui->callStack->setCurrentRow(0); + } +} + +void Debugger::on_dump_triggered() +{ + QString fn = QFileDialog::getSaveFileName(this, "Select file to output EVM trace"); + ofstream f(fn.toStdString()); + if (f.is_open()) + for (WorldState const& ws: m_session.history) + f << ws.cur << " " << hex << toHex(dev::toCompactBigEndian(ws.curPC, 1)) << " " << hex << toHex(dev::toCompactBigEndian((int)(byte)ws.inst, 1)) << " " << hex << toHex(dev::toCompactBigEndian((uint64_t)ws.gas, 1)) << endl; +} + +void Debugger::on_dumpPretty_triggered() +{ + QString fn = QFileDialog::getSaveFileName(this, "Select file to output EVM trace"); + ofstream f(fn.toStdString()); + if (f.is_open()) + for (WorldState const& ws: m_session.history) + { + f << endl << " STACK" << endl; + for (auto i: ws.stack) + f << (h256)i << endl; + f << " MEMORY" << endl << dev::memDump(ws.memory); + f << " STORAGE" << endl; + for (auto const& i: ws.storage) + f << showbase << hex << i.first << ": " << i.second << endl; + f << dec << ws.levels.size() << " | " << ws.cur << " | #" << ws.steps << " | " << hex << setw(4) << setfill('0') << ws.curPC << " : " << instructionInfo(ws.inst).name << " | " << dec << ws.gas << " | -" << dec << ws.gasCost << " | " << ws.newMemSize << "x32"; + } +} + +void Debugger::on_dumpStorage_triggered() +{ + QString fn = QFileDialog::getSaveFileName(this, "Select file to output EVM trace"); + ofstream f(fn.toStdString()); + if (f.is_open()) + for (WorldState const& ws: m_session.history) + { + if (ws.inst == Instruction::STOP || ws.inst == Instruction::RETURN || ws.inst == Instruction::SUICIDE) + for (auto i: ws.storage) + f << toHex(dev::toCompactBigEndian(i.first, 1)) << " " << toHex(dev::toCompactBigEndian(i.second, 1)) << endl; + f << ws.cur << " " << hex << toHex(dev::toCompactBigEndian(ws.curPC, 1)) << " " << hex << toHex(dev::toCompactBigEndian((int)(byte)ws.inst, 1)) << " " << hex << toHex(dev::toCompactBigEndian((uint64_t)ws.gas, 1)) << endl; + } +} diff --git a/alethzero/Debugger.h b/alethzero/Debugger.h new file mode 100644 index 000000000..dc4f4cbc3 --- /dev/null +++ b/alethzero/Debugger.h @@ -0,0 +1,102 @@ +/* + 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 Debugger.h + * @author Gav Wood + * @date 2015 + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include "Context.h" + +namespace Ui { class Debugger; } + +struct WorldState +{ + uint64_t steps; + dev::Address cur; + dev::u256 curPC; + dev::eth::Instruction inst; + dev::bigint newMemSize; + dev::u256 gas; + dev::h256 code; + dev::h256 callData; + dev::u256s stack; + dev::bytes memory; + dev::bigint gasCost; + std::map storage; + std::vector levels; +}; + +struct DebugSession +{ + DebugSession() {} + + bool populate(dev::eth::Executive& _executive, dev::bytesConstRef _transactionRLP); + + dev::h256 currentCode; + dev::h256 currentData; + std::vector currentLevels; + + QMap pcWarp; + QList history; + + std::map codes; +}; + +class Debugger: public QDialog +{ + Q_OBJECT + +public: + explicit Debugger(Context* _context, QWidget* _parent = 0); + ~Debugger(); + + void populate(dev::eth::Executive& _executive, dev::bytesConstRef _transactionRLP); + +protected slots: + void on_callStack_currentItemChanged(); + void on_debugTimeline_valueChanged(); + void on_stepOver_triggered(); + void on_stepInto_triggered(); + void on_stepOut_triggered(); + void on_backOver_triggered(); + void on_backInto_triggered(); + void on_backOut_triggered(); + void on_dump_triggered(); + void on_dumpPretty_triggered(); + void on_dumpStorage_triggered(); + +private: + void init(); + void update(); + void finished(); + + void alterDebugStateGroup(bool _enable) const; + + Ui::Debugger* ui; + + DebugSession m_session; + Context* m_context; +}; diff --git a/alethzero/Debugger.ui b/alethzero/Debugger.ui new file mode 100644 index 000000000..4795e0c5c --- /dev/null +++ b/alethzero/Debugger.ui @@ -0,0 +1,238 @@ + + + Debugger + + + + 0 + 0 + 946 + 690 + + + + Dialog + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Step Over + + + + + + + Step Into + + + + + + + Step Out + + + + + + + Back Over + + + + + + + Back Into + + + + + + + Back Out + + + + + + + Dump + + + + + + + Dump Pretty + + + + + + + Dump Storage + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + Qt::Horizontal + + + + + 1 + 0 + + + + Qt::Vertical + + + + + 0 + 0 + + + + QFrame::NoFrame + + + 0 + + + + + + Ubuntu Mono + + + + QFrame::NoFrame + + + 0 + + + + + + + 1 + 0 + + + + Qt::Vertical + + + + QFrame::NoFrame + + + 0 + + + true + + + Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + QFrame::NoFrame + + + 0 + + + true + + + Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + QFrame::NoFrame + + + 0 + + + true + + + Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + QFrame::NoFrame + + + true + + + + + + + + + + 0 + 0 + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Qt::Horizontal + + + + + + + + diff --git a/alethzero/MainWin.h b/alethzero/MainWin.h index 2625f566d..be1b162e9 100644 --- a/alethzero/MainWin.h +++ b/alethzero/MainWin.h @@ -37,7 +37,8 @@ #include #include #include - +#include "Context.h" +#include "Debugger.h" #include "NatspecHandler.h" namespace Ui { @@ -52,28 +53,11 @@ class State; class QQuickView; class OurWebThreeStubServer; -struct WorldState -{ - uint64_t steps; - dev::Address cur; - dev::u256 curPC; - dev::eth::Instruction inst; - dev::bigint newMemSize; - dev::u256 gas; - dev::h256 code; - dev::h256 callData; - dev::u256s stack; - dev::bytes memory; - dev::bigint gasCost; - std::map storage; - std::vector levels; -}; - using WatchHandler = std::function; QString contentsOfQResource(std::string const& res); -class Main : public QMainWindow +class Main: public QMainWindow, public Context { Q_OBJECT @@ -179,9 +163,6 @@ signals: private: dev::p2p::NetworkPreferences netPrefs() const; - QString pretty(dev::Address _a) const; - QString prettyU256(dev::u256 _n) const; - QString lookup(QString const& _n) const; dev::Address getNameReg() const; dev::Address getCurrencies() const; @@ -190,9 +171,12 @@ private: void initDebugger(); void updateDebugger(); void debugFinished(); - QString render(dev::Address _a) const; - dev::Address fromString(QString const& _a) const; - std::string renderDiff(dev::eth::StateDiff const& _d) const; + + QString pretty(dev::Address _a) const override; + QString prettyU256(dev::u256 _n) const override; + QString render(dev::Address _a) const override; + dev::Address fromString(QString const& _a) const override; + std::string renderDiff(dev::eth::StateDiff const& _d) const override; void alterDebugStateGroup(bool _enable) const; @@ -269,6 +253,7 @@ private: QMap m_pcWarp; QList m_history; std::map m_codes; // and pcWarps + bool m_enableOptimizer = true; QNetworkAccessManager m_webCtrl; diff --git a/libdevcore/vector_ref.h b/libdevcore/vector_ref.h index 4b1df924d..f7ab4c14a 100644 --- a/libdevcore/vector_ref.h +++ b/libdevcore/vector_ref.h @@ -1,7 +1,8 @@ #pragma once -#include +#include #include +#include #include #include From 1265be7bb8d77ac7ac2b46abbb5f0036a28b3975 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Mon, 9 Feb 2015 15:24:36 +0100 Subject: [PATCH 158/213] Adding enum Token and whitespace style at Token.h --- libsolidity/Token.h | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/libsolidity/Token.h b/libsolidity/Token.h index 5167c1a77..f164e3fcc 100644 --- a/libsolidity/Token.h +++ b/libsolidity/Token.h @@ -67,27 +67,27 @@ namespace solidity #define IGNORE_TOKEN(name, string, precedence) -#define TOKEN_LIST(T, K) \ - /* End of source indicator. */ \ - T(EOS, "EOS", 0) \ - \ - /* Punctuators (ECMA-262, section 7.7, page 15). */ \ - T(LParen, "(", 0) \ - T(RParen, ")", 0) \ - T(LBrack, "[", 0) \ - T(RBrack, "]", 0) \ - T(LBrace, "{", 0) \ - T(RBrace, "}", 0) \ - T(Colon, ":", 0) \ - T(Semicolon, ";", 0) \ - T(Period, ".", 0) \ - T(Conditional, "?", 3) \ - T(Arrow, "=>", 0) \ - \ - /* Assignment operators. */ \ - /* IsAssignmentOp() relies on this block of enum values being */ \ - /* contiguous and sorted in the same order!*/ \ - T(Assign, "=", 2) \ +#define TOKEN_LIST(T, K) \ + /* End of source indicator. */ \ + T(EOS, "EOS", 0) \ + \ + /* Punctuators (ECMA-262, section 7.7, page 15). */ \ + T(LParen, "(", 0) \ + T(RParen, ")", 0) \ + T(LBrack, "[", 0) \ + T(RBrack, "]", 0) \ + T(LBrace, "{", 0) \ + T(RBrace, "}", 0) \ + T(Colon, ":", 0) \ + T(Semicolon, ";", 0) \ + T(Period, ".", 0) \ + T(Conditional, "?", 3) \ + T(Arrow, "=>", 0) \ + \ + /* Assignment operators. */ \ + /* IsAssignmentOp() relies on this block of enum values being */ \ + /* contiguous and sorted in the same order!*/ \ + T(Assign, "=", 2) \ /* The following have to be in exactly the same order as the simple binary operators*/ \ T(AssignBitOr, "|=", 2) \ T(AssignBitXor, "^=", 2) \ From 082bfb2300d90482df4c2f55605b4fe72c80f552 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Mon, 9 Feb 2015 18:08:56 +0100 Subject: [PATCH 159/213] Parsing enums for Solidity - WIP --- libsolidity/AST.cpp | 16 +++++++++++++++ libsolidity/AST.h | 38 +++++++++++++++++++++++++++++++++++ libsolidity/ASTForward.h | 2 ++ libsolidity/ASTPrinter.cpp | 22 ++++++++++++++++++++ libsolidity/ASTPrinter.h | 4 ++++ libsolidity/ASTVisitor.h | 4 ++++ libsolidity/AST_accept.h | 12 +++++++++++ libsolidity/Parser.cpp | 41 +++++++++++++++++++++++++++++++++++++- libsolidity/Parser.h | 3 +++ 9 files changed, 141 insertions(+), 1 deletion(-) diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp index 3c6b6007c..0c34cea38 100644 --- a/libsolidity/AST.cpp +++ b/libsolidity/AST.cpp @@ -255,6 +255,22 @@ void StructDefinition::checkRecursion() const } } +void EnumDefinition::checkValidityOfMembers() const +{ +#if 0 // LTODO: Make this work for the Declarations + vector> members = getMembers(); + sort(begin(members), end(members)); + for (size_t i = 0; i < members.size(); ++i) + if (members[i] == members[i + 1]) + BOOST_THROW_EXCEPTION(createTypeError("Duplicate member detected in Enum")); +#endif +} + +TypePointer EnumDefinition::getType(ContractDefinition const*) const +{ + return make_shared(make_shared(*this)); +} + TypePointer FunctionDefinition::getType(ContractDefinition const*) const { return make_shared(*this); diff --git a/libsolidity/AST.h b/libsolidity/AST.h index 4e79026e8..d3a7853a4 100644 --- a/libsolidity/AST.h +++ b/libsolidity/AST.h @@ -165,6 +165,18 @@ private: Declaration const* m_scope; }; +/** + * Declaration of an Enum Value + */ +class EnumDeclaration : public Declaration +{ + EnumDeclaration(Location const& _location, + ASTPointer const& _name): + Declaration(_location, _name) {} + + TypePointer getType(ContractDefinition const*) const; +}; + /** * Abstract class that is added to each AST node that can store local variables. */ @@ -209,6 +221,7 @@ public: ASTPointer const& _documentation, std::vector> const& _baseContracts, std::vector> const& _definedStructs, + std::vector> const& _definedEnums, std::vector> const& _stateVariables, std::vector> const& _definedFunctions, std::vector> const& _functionModifiers, @@ -216,6 +229,7 @@ public: Declaration(_location, _name), Documented(_documentation), m_baseContracts(_baseContracts), m_definedStructs(_definedStructs), + m_definedEnums(_definedEnums), m_stateVariables(_stateVariables), m_definedFunctions(_definedFunctions), m_functionModifiers(_functionModifiers), @@ -227,6 +241,7 @@ public: std::vector> const& getBaseContracts() const { return m_baseContracts; } std::vector> const& getDefinedStructs() const { return m_definedStructs; } + std::vector> const& getDefinedEnums() const { return m_definedEnums; } std::vector> const& getStateVariables() const { return m_stateVariables; } std::vector> const& getFunctionModifiers() const { return m_functionModifiers; } std::vector> const& getDefinedFunctions() const { return m_definedFunctions; } @@ -260,6 +275,7 @@ private: std::vector> m_baseContracts; std::vector> m_definedStructs; + std::vector> m_definedEnums; std::vector> m_stateVariables; std::vector> m_definedFunctions; std::vector> m_functionModifiers; @@ -315,6 +331,28 @@ private: std::vector> m_members; }; +class EnumDefinition: public Declaration +{ +public: + EnumDefinition(Location const& _location, + ASTPointer const& _name, + std::vector> const& _members): + Declaration(_location, _name), m_members(_members) {} + virtual void accept(ASTVisitor& _visitor) override; + virtual void accept(ASTConstVisitor& _visitor) const override; + + std::vector> const& getMembers() const { return m_members; } + + virtual TypePointer getType(ContractDefinition const*) const override; + + /// Checks that the members do not include any duplicate names + void checkValidityOfMembers() const; + +private: + + std::vector> m_members; +}; + /** * Parameter list, used as function parameter list and return list. * None of the parameters is allowed to contain mappings (not even recursively diff --git a/libsolidity/ASTForward.h b/libsolidity/ASTForward.h index 22015f26b..a0a6f6832 100644 --- a/libsolidity/ASTForward.h +++ b/libsolidity/ASTForward.h @@ -40,6 +40,8 @@ class Declaration; class ContractDefinition; class InheritanceSpecifier; class StructDefinition; +class EnumDefinition; +class EnumDeclaration; class ParameterList; class FunctionDefinition; class VariableDeclaration; diff --git a/libsolidity/ASTPrinter.cpp b/libsolidity/ASTPrinter.cpp index 949740e89..34cd12a98 100644 --- a/libsolidity/ASTPrinter.cpp +++ b/libsolidity/ASTPrinter.cpp @@ -71,6 +71,18 @@ bool ASTPrinter::visit(StructDefinition const& _node) return goDeeper(); } +bool ASTPrinter::visit(EnumDefinition const& _node) +{ + writeLine("EnumDefinition \"" + _node.getName() + "\""); + return goDeeper(); +} + +bool ASTPrinter::visit(EnuumDeclaration const& _node) +{ + writeLine("EnumValue \"" + _node.getName() + "\""); + return goDeeper(); +} + bool ASTPrinter::visit(ParameterList const& _node) { writeLine("ParameterList"); @@ -347,6 +359,16 @@ void ASTPrinter::endVisit(StructDefinition const&) m_indentation--; } +void ASTPrinter::endVisit(EnumDefinition const&) +{ + m_indentation--; +} + +void ASTPrinter::endVisit(EnumDeclaration const&) +{ + m_indentation--; +} + void ASTPrinter::endVisit(ParameterList const&) { m_indentation--; diff --git a/libsolidity/ASTPrinter.h b/libsolidity/ASTPrinter.h index ebc163e31..a306e90b5 100644 --- a/libsolidity/ASTPrinter.h +++ b/libsolidity/ASTPrinter.h @@ -46,6 +46,8 @@ public: bool visit(ContractDefinition const& _node) override; bool visit(InheritanceSpecifier const& _node) override; bool visit(StructDefinition const& _node) override; + bool visit(EnumDefinition const& _node) override; + bool visit(EnumDeclaration const& _node) override; bool visit(ParameterList const& _node) override; bool visit(FunctionDefinition const& _node) override; bool visit(VariableDeclaration const& _node) override; @@ -85,6 +87,8 @@ public: void endVisit(ContractDefinition const&) override; void endVisit(InheritanceSpecifier const&) override; void endVisit(StructDefinition const&) override; + void endVisit(EnumDefinition const&) override; + void endVisit(EnumDeclaration const&) override; void endVisit(ParameterList const&) override; void endVisit(FunctionDefinition const&) override; void endVisit(VariableDeclaration const&) override; diff --git a/libsolidity/ASTVisitor.h b/libsolidity/ASTVisitor.h index 294902778..b05ec6580 100644 --- a/libsolidity/ASTVisitor.h +++ b/libsolidity/ASTVisitor.h @@ -47,6 +47,7 @@ public: virtual bool visit(ContractDefinition&) { return true; } virtual bool visit(InheritanceSpecifier&) { return true; } virtual bool visit(StructDefinition&) { return true; } + virtual bool visit(EnumDefinition&) { return true; } virtual bool visit(ParameterList&) { return true; } virtual bool visit(FunctionDefinition&) { return true; } virtual bool visit(VariableDeclaration&) { return true; } @@ -88,6 +89,7 @@ public: virtual void endVisit(ContractDefinition&) { } virtual void endVisit(InheritanceSpecifier&) { } virtual void endVisit(StructDefinition&) { } + virtual void endVisit(EnumDefinition&) { } virtual void endVisit(ParameterList&) { } virtual void endVisit(FunctionDefinition&) { } virtual void endVisit(VariableDeclaration&) { } @@ -133,6 +135,7 @@ public: virtual bool visit(ContractDefinition const&) { return true; } virtual bool visit(InheritanceSpecifier const&) { return true; } virtual bool visit(StructDefinition const&) { return true; } + virtual bool visit(EnumDefinition const&) { return true; } virtual bool visit(ParameterList const&) { return true; } virtual bool visit(FunctionDefinition const&) { return true; } virtual bool visit(VariableDeclaration const&) { return true; } @@ -174,6 +177,7 @@ public: virtual void endVisit(ContractDefinition const&) { } virtual void endVisit(InheritanceSpecifier const&) { } virtual void endVisit(StructDefinition const&) { } + virtual void endVisit(EnumDefinition const&) { } virtual void endVisit(ParameterList const&) { } virtual void endVisit(FunctionDefinition const&) { } virtual void endVisit(VariableDeclaration const&) { } diff --git a/libsolidity/AST_accept.h b/libsolidity/AST_accept.h index 38108cd72..15f6b7eeb 100644 --- a/libsolidity/AST_accept.h +++ b/libsolidity/AST_accept.h @@ -112,6 +112,18 @@ void StructDefinition::accept(ASTVisitor& _visitor) _visitor.endVisit(*this); } +void EnumDefinition::accept(ASTVisitor& _visitor) +{ + _visitor.visit(*this) + _visitor.endVisit(*this); +} + +void EnumDefinition::accept(ASTConstVisitor& _visitor) const +{ + _visitor.visit(*this) + _visitor.endVisit(*this); +} + void StructDefinition::accept(ASTConstVisitor& _visitor) const { if (_visitor.visit(*this)) diff --git a/libsolidity/Parser.cpp b/libsolidity/Parser.cpp index f076df876..2f0796d6d 100644 --- a/libsolidity/Parser.cpp +++ b/libsolidity/Parser.cpp @@ -119,6 +119,7 @@ ASTPointer Parser::parseContractDefinition() ASTPointer name = expectIdentifierToken(); vector> baseContracts; vector> structs; + vector> enums; vector> stateVariables; vector> functions; vector> modifiers; @@ -140,6 +141,8 @@ ASTPointer Parser::parseContractDefinition() functions.push_back(parseFunctionDefinition(name.get())); else if (currentToken == Token::Struct) structs.push_back(parseStructDefinition()); + else if (currentToken == Token::Enum) + enums.push_back(parseEnumDefinition()); else if (currentToken == Token::Identifier || currentToken == Token::Mapping || Token::isElementaryTypeName(currentToken)) { @@ -157,7 +160,7 @@ ASTPointer Parser::parseContractDefinition() } nodeFactory.markEndPosition(); expectToken(Token::RBrace); - return nodeFactory.createNode(name, docString, baseContracts, structs, + return nodeFactory.createNode(name, docString, baseContracts, structs, enums, stateVariables, functions, modifiers, events); } @@ -263,6 +266,35 @@ ASTPointer Parser::parseStructDefinition() return nodeFactory.createNode(name, members); } +ASTPointer Parser::parseEnumDeclaration() +{ + ASTNodeFactory nodeFactory(*this); + ASTPointer name = expectIdentifierToken(); + nodeFactory.markEndPosition(); + return nodeFactory.createNode(name); +} + +ASTPointer Parser::parseEnumDefinition() +{ + ASTNodeFactory nodeFactory(*this); + expectToken(Token::Enum); + ASTPointer name = expectIdentifierToken(); + vector> members; + expectToken(Token::LBrace); + + while (m_scanner->getCurrentToken() == Token::Identifier) + { + members.push_back(parseEnumDeclaration()); + if (m_scanner->getCurrentToken() == Token::RBrace) + break; + expectToken(Token::Comma); + } + + nodeFactory.markEndPosition(); + expectToken(Token::RBrace); + return nodeFactory.createNode(name, members); +} + ASTPointer Parser::parseVariableDeclaration(VarDeclParserOptions const& _options) { ASTNodeFactory nodeFactory(*this); @@ -823,6 +855,13 @@ ASTPointer Parser::expectIdentifierToken() return getLiteralAndAdvance(); } +ASTPointer Parser::peekIdentifierToken() +{ + if (m_scanner->getCurrentToken() != Token::Identifier) + return nullptr; + return getLiteralAndAdvance(); +} + ASTPointer Parser::getLiteralAndAdvance() { ASTPointer identifier = make_shared(m_scanner->getCurrentLiteral()); diff --git a/libsolidity/Parser.h b/libsolidity/Parser.h index 5816fec40..734bdd57e 100644 --- a/libsolidity/Parser.h +++ b/libsolidity/Parser.h @@ -61,6 +61,8 @@ private: Declaration::Visibility parseVisibilitySpecifier(Token::Value _token); ASTPointer parseFunctionDefinition(ASTString const* _contractName); ASTPointer parseStructDefinition(); + ASTPointer parseEnumDefinition(); + ASTPointer parseEnumDeclaration(); ASTPointer parseVariableDeclaration(VarDeclParserOptions const& _options = VarDeclParserOptions()); ASTPointer parseModifierDefinition(); ASTPointer parseEventDefinition(); @@ -96,6 +98,7 @@ private: void expectToken(Token::Value _value); Token::Value expectAssignmentOperator(); ASTPointer expectIdentifierToken(); + ASTPointer peekIdentifierToken(); ASTPointer getLiteralAndAdvance(); ///@} From 133969bd2a2b3627dc7758851ef0fae02c176a3d Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Tue, 10 Feb 2015 13:40:21 +0100 Subject: [PATCH 160/213] Parsing an enum AST node --- libsolidity/AST.cpp | 10 +++++++++- libsolidity/AST.h | 5 ++++- libsolidity/ASTPrinter.cpp | 2 +- libsolidity/ASTVisitor.h | 4 ++++ libsolidity/AST_accept.h | 24 +++++++++++++++++++----- libsolidity/Parser.cpp | 2 +- libsolidity/Token.h | 2 +- 7 files changed, 39 insertions(+), 10 deletions(-) diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp index 0c34cea38..95014fa18 100644 --- a/libsolidity/AST.cpp +++ b/libsolidity/AST.cpp @@ -206,6 +206,12 @@ vector, FunctionTypePointer>> const& ContractDefinition::getIn return *m_interfaceFunctionList; } +TypePointer EnumDeclaration::getType(ContractDefinition const*) const +{ + // LTODO + return nullptr; +} + void InheritanceSpecifier::checkTypeRequirements() { m_baseName->checkTypeRequirements(); @@ -268,7 +274,9 @@ void EnumDefinition::checkValidityOfMembers() const TypePointer EnumDefinition::getType(ContractDefinition const*) const { - return make_shared(make_shared(*this)); + //LTODO: + return nullptr; + // return make_shared(make_shared(*this)); } TypePointer FunctionDefinition::getType(ContractDefinition const*) const diff --git a/libsolidity/AST.h b/libsolidity/AST.h index d3a7853a4..02493df25 100644 --- a/libsolidity/AST.h +++ b/libsolidity/AST.h @@ -170,10 +170,13 @@ private: */ class EnumDeclaration : public Declaration { + public: EnumDeclaration(Location const& _location, ASTPointer const& _name): Declaration(_location, _name) {} + virtual void accept(ASTVisitor& _visitor) override; + virtual void accept(ASTConstVisitor& _visitor) const override; TypePointer getType(ContractDefinition const*) const; }; @@ -717,7 +720,7 @@ public: Expression const& getCondition() const { return *m_condition; } Statement const& getTrueStatement() const { return *m_trueBody; } - /// @returns the "else" part of the if statement or nullptr if there is no "else" part. + /// @returns the "else" part of the if statement or nullptr if there is no "else" part. Statement const* getFalseStatement() const { return m_falseBody.get(); } private: diff --git a/libsolidity/ASTPrinter.cpp b/libsolidity/ASTPrinter.cpp index 34cd12a98..b655d309d 100644 --- a/libsolidity/ASTPrinter.cpp +++ b/libsolidity/ASTPrinter.cpp @@ -77,7 +77,7 @@ bool ASTPrinter::visit(EnumDefinition const& _node) return goDeeper(); } -bool ASTPrinter::visit(EnuumDeclaration const& _node) +bool ASTPrinter::visit(EnumDeclaration const& _node) { writeLine("EnumValue \"" + _node.getName() + "\""); return goDeeper(); diff --git a/libsolidity/ASTVisitor.h b/libsolidity/ASTVisitor.h index b05ec6580..108827573 100644 --- a/libsolidity/ASTVisitor.h +++ b/libsolidity/ASTVisitor.h @@ -48,6 +48,7 @@ public: virtual bool visit(InheritanceSpecifier&) { return true; } virtual bool visit(StructDefinition&) { return true; } virtual bool visit(EnumDefinition&) { return true; } + virtual bool visit(EnumDeclaration&) { return true; } virtual bool visit(ParameterList&) { return true; } virtual bool visit(FunctionDefinition&) { return true; } virtual bool visit(VariableDeclaration&) { return true; } @@ -90,6 +91,7 @@ public: virtual void endVisit(InheritanceSpecifier&) { } virtual void endVisit(StructDefinition&) { } virtual void endVisit(EnumDefinition&) { } + virtual void endVisit(EnumDeclaration&) { } virtual void endVisit(ParameterList&) { } virtual void endVisit(FunctionDefinition&) { } virtual void endVisit(VariableDeclaration&) { } @@ -136,6 +138,7 @@ public: virtual bool visit(InheritanceSpecifier const&) { return true; } virtual bool visit(StructDefinition const&) { return true; } virtual bool visit(EnumDefinition const&) { return true; } + virtual bool visit(EnumDeclaration const&) { return true; } virtual bool visit(ParameterList const&) { return true; } virtual bool visit(FunctionDefinition const&) { return true; } virtual bool visit(VariableDeclaration const&) { return true; } @@ -178,6 +181,7 @@ public: virtual void endVisit(InheritanceSpecifier const&) { } virtual void endVisit(StructDefinition const&) { } virtual void endVisit(EnumDefinition const&) { } + virtual void endVisit(EnumDeclaration const&) { } virtual void endVisit(ParameterList const&) { } virtual void endVisit(FunctionDefinition const&) { } virtual void endVisit(VariableDeclaration const&) { } diff --git a/libsolidity/AST_accept.h b/libsolidity/AST_accept.h index 15f6b7eeb..9568da5b3 100644 --- a/libsolidity/AST_accept.h +++ b/libsolidity/AST_accept.h @@ -105,22 +105,36 @@ void InheritanceSpecifier::accept(ASTConstVisitor& _visitor) const _visitor.endVisit(*this); } -void StructDefinition::accept(ASTVisitor& _visitor) +void EnumDefinition::accept(ASTVisitor& _visitor) { if (_visitor.visit(*this)) listAccept(m_members, _visitor); _visitor.endVisit(*this); } -void EnumDefinition::accept(ASTVisitor& _visitor) +void EnumDefinition::accept(ASTConstVisitor& _visitor) const { - _visitor.visit(*this) + if (_visitor.visit(*this)) + listAccept(m_members, _visitor); _visitor.endVisit(*this); } -void EnumDefinition::accept(ASTConstVisitor& _visitor) const +void EnumDeclaration::accept(ASTVisitor& _visitor) +{ + _visitor.visit(*this); + _visitor.endVisit(*this); +} + +void EnumDeclaration::accept(ASTConstVisitor& _visitor) const +{ + _visitor.visit(*this); + _visitor.endVisit(*this); +} + +void StructDefinition::accept(ASTVisitor& _visitor) { - _visitor.visit(*this) + if (_visitor.visit(*this)) + listAccept(m_members, _visitor); _visitor.endVisit(*this); } diff --git a/libsolidity/Parser.cpp b/libsolidity/Parser.cpp index 2f0796d6d..fd25d7ce1 100644 --- a/libsolidity/Parser.cpp +++ b/libsolidity/Parser.cpp @@ -279,7 +279,7 @@ ASTPointer Parser::parseEnumDefinition() ASTNodeFactory nodeFactory(*this); expectToken(Token::Enum); ASTPointer name = expectIdentifierToken(); - vector> members; + vector> members; expectToken(Token::LBrace); while (m_scanner->getCurrentToken() == Token::Identifier) diff --git a/libsolidity/Token.h b/libsolidity/Token.h index f164e3fcc..5039d5b5f 100644 --- a/libsolidity/Token.h +++ b/libsolidity/Token.h @@ -168,7 +168,7 @@ namespace solidity K(Switch, "switch", 0) \ K(Var, "var", 0) \ K(While, "while", 0) \ - \ + K(Enum, "enum", 0) \ \ /* Ether subdenominations */ \ K(SubWei, "wei", 0) \ From ec47c759ea6e0a5bad7744e6e14b491d7890dd64 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Tue, 10 Feb 2015 14:51:40 +0100 Subject: [PATCH 161/213] Adding test for Enum Parsing --- test/SolidityParser.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test/SolidityParser.cpp b/test/SolidityParser.cpp index 84f36170f..035bfd789 100644 --- a/test/SolidityParser.cpp +++ b/test/SolidityParser.cpp @@ -703,6 +703,20 @@ BOOST_AUTO_TEST_CASE(literal_constants_with_ether_subdenominations_in_expression BOOST_CHECK_NO_THROW(parseTextExplainError(text)); } +BOOST_AUTO_TEST_CASE(enum_declaration) +{ + char const* text = R"( + contract c { + enum foo { WARNING, NOTICE, ERROR, CRITICAL }; + function c () + { + a = foo.CRITICAL; + } + uint256 a; + })"; + BOOST_CHECK_NO_THROW(parseTextExplainError(text)); +} + BOOST_AUTO_TEST_SUITE_END() } From 9232b4cd8870113dfc835749a46da5fd971ace2d Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Wed, 11 Feb 2015 16:37:46 +0100 Subject: [PATCH 162/213] Introducing EnumType and some Parser tests --- libsolidity/AST.cpp | 6 ++---- libsolidity/AST.h | 2 +- libsolidity/Parser.cpp | 1 + libsolidity/Types.cpp | 31 +++++++++++++++++++++++++++++++ libsolidity/Types.h | 28 ++++++++++++++++++++++++---- test/SolidityParser.cpp | 14 ++++++++++++++ 6 files changed, 73 insertions(+), 9 deletions(-) diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp index 95014fa18..488bd4cd1 100644 --- a/libsolidity/AST.cpp +++ b/libsolidity/AST.cpp @@ -208,7 +208,7 @@ vector, FunctionTypePointer>> const& ContractDefinition::getIn TypePointer EnumDeclaration::getType(ContractDefinition const*) const { - // LTODO + // LTODO: How to get the parent EnumDefinition and return its type here? return nullptr; } @@ -274,9 +274,7 @@ void EnumDefinition::checkValidityOfMembers() const TypePointer EnumDefinition::getType(ContractDefinition const*) const { - //LTODO: - return nullptr; - // return make_shared(make_shared(*this)); + return make_shared(make_shared(*this)); } TypePointer FunctionDefinition::getType(ContractDefinition const*) const diff --git a/libsolidity/AST.h b/libsolidity/AST.h index 02493df25..65c35026c 100644 --- a/libsolidity/AST.h +++ b/libsolidity/AST.h @@ -177,7 +177,7 @@ class EnumDeclaration : public Declaration virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTConstVisitor& _visitor) const override; - TypePointer getType(ContractDefinition const*) const; + TypePointer getType(ContractDefinition const* = nullptr) const; }; /** diff --git a/libsolidity/Parser.cpp b/libsolidity/Parser.cpp index fd25d7ce1..a26713a73 100644 --- a/libsolidity/Parser.cpp +++ b/libsolidity/Parser.cpp @@ -292,6 +292,7 @@ ASTPointer Parser::parseEnumDefinition() nodeFactory.markEndPosition(); expectToken(Token::RBrace); + expectToken(Token::Semicolon); return nodeFactory.createNode(name, members); } diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index 16514b148..6b6a70c29 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -662,6 +662,37 @@ u256 StructType::getStorageOffsetOfMember(string const& _name) const BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Storage offset of non-existing member requested.")); } +TypePointer EnumType::unaryOperatorResult(Token::Value _operator) const +{ + return _operator == Token::Delete ? make_shared() : TypePointer(); +} + +bool EnumType::operator==(Type const& _other) const +{ + if (_other.getCategory() != getCategory()) + return false; + EnumType const& other = dynamic_cast(_other); + return other.m_enum == m_enum; +} + +string EnumType::toString() const +{ + return string("enum ") + m_enum.getName(); +} + +MemberList const& EnumType::getMembers() const +{ + // We need to lazy-initialize it because of recursive references. + if (!m_members) + { + map> members; + for (ASTPointer const& enumValue: m_enum.getMembers()) + members.insert(make_pair(enumValue->getName(), make_shared(m_enum))); + m_members.reset(new MemberList(members)); + } + return *m_members; +} + FunctionType::FunctionType(FunctionDefinition const& _function, bool _isInternal): m_location(_isInternal ? Location::Internal : Location::External), m_isConstant(_function.isDeclaredConst()), diff --git a/libsolidity/Types.h b/libsolidity/Types.h index 5a0e2c429..70703938d 100644 --- a/libsolidity/Types.h +++ b/libsolidity/Types.h @@ -76,10 +76,9 @@ class Type: private boost::noncopyable, public std::enable_shared_from_this m_members; }; +/** + * The type of an enum instance, there is one distinct type per enum definition. + */ +class EnumType: public Type +{ +public: + virtual Category getCategory() const override { return Category::Enum; } + explicit EnumType(EnumDefinition const& _enum): m_enum(_enum) {} + virtual TypePointer unaryOperatorResult(Token::Value _operator) const override; + virtual bool operator==(Type const& _other) const override; + virtual unsigned getSizeOnStack() const override { return 1; /*@todo*/ } + virtual std::string toString() const override; + + virtual MemberList const& getMembers() const override; + +private: + EnumDefinition const& m_enum; + /// List of member types, will be lazy-initialized because of recursive references. + mutable std::unique_ptr m_members; +}; + /** * The type of a function, identified by its (return) parameter types. * @todo the return parameters should also have names, i.e. return parameters should be a struct diff --git a/test/SolidityParser.cpp b/test/SolidityParser.cpp index 035bfd789..291ec6051 100644 --- a/test/SolidityParser.cpp +++ b/test/SolidityParser.cpp @@ -717,6 +717,20 @@ BOOST_AUTO_TEST_CASE(enum_declaration) BOOST_CHECK_NO_THROW(parseTextExplainError(text)); } +BOOST_AUTO_TEST_CASE(empty_enum_declaration) +{ + char const* text = R"( + contract c { + enum foo { }; + function c () + { + a = 5; + } + uint256 a; + })"; + BOOST_CHECK_NO_THROW(parseTextExplainError(text)); +} + BOOST_AUTO_TEST_SUITE_END() } From 31014b34575d9168b04f5d0aba9530410dc12b17 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Wed, 11 Feb 2015 17:23:13 +0100 Subject: [PATCH 163/213] Disallow trailing comma in Enum Declaration --- libsolidity/Parser.cpp | 5 ++++- test/SolidityParser.cpp | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/libsolidity/Parser.cpp b/libsolidity/Parser.cpp index a26713a73..e59e698f1 100644 --- a/libsolidity/Parser.cpp +++ b/libsolidity/Parser.cpp @@ -282,12 +282,15 @@ ASTPointer Parser::parseEnumDefinition() vector> members; expectToken(Token::LBrace); - while (m_scanner->getCurrentToken() == Token::Identifier) + while (m_scanner->getCurrentToken() != Token::RBrace) { members.push_back(parseEnumDeclaration()); if (m_scanner->getCurrentToken() == Token::RBrace) break; expectToken(Token::Comma); + if (m_scanner->getCurrentToken() != Token::Identifier) { + BOOST_THROW_EXCEPTION(createParserError("Expected Identifier after ,")); + } } nodeFactory.markEndPosition(); diff --git a/test/SolidityParser.cpp b/test/SolidityParser.cpp index 291ec6051..07ec2dcfa 100644 --- a/test/SolidityParser.cpp +++ b/test/SolidityParser.cpp @@ -731,6 +731,20 @@ BOOST_AUTO_TEST_CASE(empty_enum_declaration) BOOST_CHECK_NO_THROW(parseTextExplainError(text)); } +BOOST_AUTO_TEST_CASE(malformed_enum_declaration) +{ + char const* text = R"( + contract c { + enum foo { WARNING,}; + function c () + { + a = foo.CRITICAL; + } + uint256 a; + })"; + BOOST_CHECK_THROW(parseText(text), ParserError); +} + BOOST_AUTO_TEST_SUITE_END() } From 2dbf7391196295567b3ec55bdf99eec43fa73ba1 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Wed, 11 Feb 2015 21:40:47 +0100 Subject: [PATCH 164/213] Enums NameAndTypeResolution - WIP - Also adding an EndToEnd enum test --- libsolidity/AST_accept.h | 2 ++ libsolidity/NameAndTypeResolver.cpp | 15 +++++++++++++++ libsolidity/NameAndTypeResolver.h | 2 ++ libsolidity/Types.cpp | 2 ++ test/SolidityEndToEndTest.cpp | 20 ++++++++++++++++++++ test/SolidityNameAndTypeResolution.cpp | 15 +++++++++++++++ 6 files changed, 56 insertions(+) diff --git a/libsolidity/AST_accept.h b/libsolidity/AST_accept.h index 9568da5b3..78c2f8c58 100644 --- a/libsolidity/AST_accept.h +++ b/libsolidity/AST_accept.h @@ -63,6 +63,7 @@ void ContractDefinition::accept(ASTVisitor& _visitor) { listAccept(m_baseContracts, _visitor); listAccept(m_definedStructs, _visitor); + listAccept(m_definedEnums, _visitor); listAccept(m_stateVariables, _visitor); listAccept(m_events, _visitor); listAccept(m_functionModifiers, _visitor); @@ -77,6 +78,7 @@ void ContractDefinition::accept(ASTConstVisitor& _visitor) const { listAccept(m_baseContracts, _visitor); listAccept(m_definedStructs, _visitor); + listAccept(m_definedEnums, _visitor); listAccept(m_stateVariables, _visitor); listAccept(m_events, _visitor); listAccept(m_functionModifiers, _visitor); diff --git a/libsolidity/NameAndTypeResolver.cpp b/libsolidity/NameAndTypeResolver.cpp index 7dc42bc62..859d0097c 100644 --- a/libsolidity/NameAndTypeResolver.cpp +++ b/libsolidity/NameAndTypeResolver.cpp @@ -58,6 +58,8 @@ void NameAndTypeResolver::resolveNamesAndTypes(ContractDefinition& _contract) for (ASTPointer const& structDef: _contract.getDefinedStructs()) ReferencesResolver resolver(*structDef, *this, &_contract, nullptr); + for (ASTPointer const& enumDef: _contract.getDefinedEnums()) + ReferencesResolver resolver(*enumDef, *this, &_contract, nullptr); for (ASTPointer const& variable: _contract.getStateVariables()) ReferencesResolver resolver(*variable, *this, &_contract, nullptr); for (ASTPointer const& event: _contract.getEvents()) @@ -79,6 +81,8 @@ void NameAndTypeResolver::checkTypeRequirements(ContractDefinition& _contract) { for (ASTPointer const& structDef: _contract.getDefinedStructs()) structDef->checkValidityOfMembers(); + for (ASTPointer const& enumDef: _contract.getDefinedEnums()) + enumDef->checkValidityOfMembers(); _contract.checkTypeRequirements(); } @@ -221,6 +225,17 @@ void DeclarationRegistrationHelper::endVisit(StructDefinition&) closeCurrentScope(); } +bool DeclarationRegistrationHelper::visit(EnumDefinition& _enum) +{ + registerDeclaration(_enum, true); + return true; +} + +void DeclarationRegistrationHelper::endVisit(EnumDefinition&) +{ + closeCurrentScope(); +} + bool DeclarationRegistrationHelper::visit(FunctionDefinition& _function) { registerDeclaration(_function, true); diff --git a/libsolidity/NameAndTypeResolver.h b/libsolidity/NameAndTypeResolver.h index 4b7ce6e7d..4b1b8c0cd 100644 --- a/libsolidity/NameAndTypeResolver.h +++ b/libsolidity/NameAndTypeResolver.h @@ -98,6 +98,8 @@ private: void endVisit(ContractDefinition& _contract) override; bool visit(StructDefinition& _struct) override; void endVisit(StructDefinition& _struct) override; + bool visit(EnumDefinition& _enum) override; + void endVisit(EnumDefinition& _enum) override; bool visit(FunctionDefinition& _function) override; void endVisit(FunctionDefinition& _function) override; bool visit(ModifierDefinition& _modifier) override; diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index 6b6a70c29..418d6b17e 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -74,6 +74,8 @@ TypePointer Type::fromUserDefinedTypeName(UserDefinedTypeName const& _typeName) Declaration const* declaration = _typeName.getReferencedDeclaration(); if (StructDefinition const* structDef = dynamic_cast(declaration)) return make_shared(*structDef); + else if (EnumDefinition const* enumDef = dynamic_cast(declaration)) + return make_shared(*enumDef); else if (FunctionDefinition const* function = dynamic_cast(declaration)) return make_shared(*function); else if (ContractDefinition const* contract = dynamic_cast(declaration)) diff --git a/test/SolidityEndToEndTest.cpp b/test/SolidityEndToEndTest.cpp index 259123db6..7fa7dd251 100644 --- a/test/SolidityEndToEndTest.cpp +++ b/test/SolidityEndToEndTest.cpp @@ -2499,6 +2499,26 @@ BOOST_AUTO_TEST_CASE(struct_copy_via_local) BOOST_CHECK(callContractFunction("test()") == encodeArgs(true)); } +BOOST_AUTO_TEST_CASE(using_enums) +{ + char const* sourceCode = R"( + contract test { + enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }; + function test() + { + choices = ActionChoices.GoStraight; + } + function getChoice() returns (uint d) + { + d = choices; + } + ActionChoices choices; + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("getChoice()") == encodeArgs(2)); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/SolidityNameAndTypeResolution.cpp b/test/SolidityNameAndTypeResolution.cpp index 3ead6f1c5..490ab3be5 100644 --- a/test/SolidityNameAndTypeResolution.cpp +++ b/test/SolidityNameAndTypeResolution.cpp @@ -991,6 +991,21 @@ BOOST_AUTO_TEST_CASE(exp_operator_exponent_too_big) })"; BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); } +BOOST_AUTO_TEST_CASE(enum_member_access) +{ + char const* text = R"( + contract test { + struct foo { uint256 x;} + enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }; + function test() + { + choices = ActionChoices.GoStraight; + } + ActionChoices choices; + } + )"; + BOOST_CHECK_NO_THROW(parseTextAndResolveNamesWithChecks(text)); +} BOOST_AUTO_TEST_SUITE_END() From 5659ed1238d15b024294039414221ee683f92191 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Thu, 12 Feb 2015 15:19:04 +0100 Subject: [PATCH 165/213] Correcting and testing enum member access --- libsolidity/Types.cpp | 20 +++++++------------- libsolidity/Types.h | 3 ++- test/SolidityNameAndTypeResolution.cpp | 17 ++++++++++++++++- 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index 418d6b17e..f25431605 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -682,19 +682,6 @@ string EnumType::toString() const return string("enum ") + m_enum.getName(); } -MemberList const& EnumType::getMembers() const -{ - // We need to lazy-initialize it because of recursive references. - if (!m_members) - { - map> members; - for (ASTPointer const& enumValue: m_enum.getMembers()) - members.insert(make_pair(enumValue->getName(), make_shared(m_enum))); - m_members.reset(new MemberList(members)); - } - return *m_members; -} - FunctionType::FunctionType(FunctionDefinition const& _function, bool _isInternal): m_location(_isInternal ? Location::Internal : Location::External), m_isConstant(_function.isDeclaredConst()), @@ -957,6 +944,13 @@ MemberList const& TypeType::getMembers() const if (!f->isConstructor() && !f->getName().empty()) members[f->getName()] = make_shared(*f); } + else if (m_actualType->getCategory() == Category::Enum) + { + EnumDefinition const& enumDef = dynamic_cast(*m_actualType).getEnumDefinition(); + for (ASTPointer const& enumValue: enumDef.getMembers()) + members.insert(make_pair(enumValue->getName(), make_shared(enumDef))); + m_members.reset(new MemberList(members)); + } m_members.reset(new MemberList(members)); } return *m_members; diff --git a/libsolidity/Types.h b/libsolidity/Types.h index 70703938d..0b576bd3f 100644 --- a/libsolidity/Types.h +++ b/libsolidity/Types.h @@ -379,8 +379,9 @@ public: virtual bool operator==(Type const& _other) const override; virtual unsigned getSizeOnStack() const override { return 1; /*@todo*/ } virtual std::string toString() const override; + virtual bool isValueType() const override { return true; } - virtual MemberList const& getMembers() const override; + EnumDefinition const& getEnumDefinition() const { return m_enum; } private: EnumDefinition const& m_enum; diff --git a/test/SolidityNameAndTypeResolution.cpp b/test/SolidityNameAndTypeResolution.cpp index 490ab3be5..34f51a4ce 100644 --- a/test/SolidityNameAndTypeResolution.cpp +++ b/test/SolidityNameAndTypeResolution.cpp @@ -991,11 +991,11 @@ BOOST_AUTO_TEST_CASE(exp_operator_exponent_too_big) })"; BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); } + BOOST_AUTO_TEST_CASE(enum_member_access) { char const* text = R"( contract test { - struct foo { uint256 x;} enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }; function test() { @@ -1007,6 +1007,21 @@ BOOST_AUTO_TEST_CASE(enum_member_access) BOOST_CHECK_NO_THROW(parseTextAndResolveNamesWithChecks(text)); } +BOOST_AUTO_TEST_CASE(enum_invalid_member_access) +{ + char const* text = R"( + contract test { + enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }; + function test() + { + choices = ActionChoices.RunAroundWavingYourHands; + } + ActionChoices choices; + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); +} + BOOST_AUTO_TEST_SUITE_END() } From 07886f42bbccb2d217c29ecc335dc58e1d4a50eb Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Thu, 12 Feb 2015 17:59:52 +0100 Subject: [PATCH 166/213] Enum type conversion and member value access. - Added tests for the type conversion part. - Enum member value access still needs some work --- libsolidity/AST.cpp | 13 ++++++++++ libsolidity/AST.h | 3 +++ libsolidity/ExpressionCompiler.cpp | 12 ++++++++- libsolidity/Types.cpp | 5 ++++ libsolidity/Types.h | 2 ++ test/SolidityEndToEndTest.cpp | 2 +- test/SolidityNameAndTypeResolution.cpp | 34 ++++++++++++++++++++++++++ 7 files changed, 69 insertions(+), 2 deletions(-) diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp index 488bd4cd1..7653952f4 100644 --- a/libsolidity/AST.cpp +++ b/libsolidity/AST.cpp @@ -277,6 +277,19 @@ TypePointer EnumDefinition::getType(ContractDefinition const*) const return make_shared(make_shared(*this)); } + +unsigned int EnumDefinition::getMemberValue(ASTString const& _member) const +{ + unsigned int index = 0; + for (ASTPointer const& decl: m_members) + { + if (decl->getName() == _member) + return index; + ++index; + } + BOOST_THROW_EXCEPTION(createTypeError("Requested unknown enum value ." + _member)); +} + TypePointer FunctionDefinition::getType(ContractDefinition const*) const { return make_shared(*this); diff --git a/libsolidity/AST.h b/libsolidity/AST.h index 65c35026c..fdbbcd5b4 100644 --- a/libsolidity/AST.h +++ b/libsolidity/AST.h @@ -348,6 +348,9 @@ public: virtual TypePointer getType(ContractDefinition const*) const override; + /// @returns the value that the string has in the Enum + unsigned int getMemberValue(ASTString const& _member) const; + /// Checks that the members do not include any duplicate names void checkValidityOfMembers() const; diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index 90f860a1e..dd41b485a 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -489,6 +489,12 @@ void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess) m_currentLValue.retrieveValueIfLValueNotRequested(_memberAccess); break; } + case Type::Category::Enum: + { + EnumType const& type = dynamic_cast(*_memberAccess.getExpression().getType()); + EnumDefinition const& enumDef = type.getEnumDefinition(); + m_context << enumDef.getMemberValue(_memberAccess.getMemberName()); + } case Type::Category::TypeType: { TypeType const& type = dynamic_cast(*_memberAccess.getExpression().getType()); @@ -562,6 +568,10 @@ void ExpressionCompiler::endVisit(Identifier const& _identifier) { // no-op } + else if (dynamic_cast(declaration)) + { + // no-op + } else { BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Identifier type not expected in expression context.")); @@ -746,7 +756,7 @@ void ExpressionCompiler::appendTypeConversion(Type const& _typeOnStack, Type con } } else if (stackTypeCategory == Type::Category::Integer || stackTypeCategory == Type::Category::Contract || - stackTypeCategory == Type::Category::IntegerConstant) + stackTypeCategory == Type::Category::IntegerConstant || stackTypeCategory == Type::Category::Enum) { if (targetTypeCategory == Type::Category::String && stackTypeCategory == Type::Category::Integer) { diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index f25431605..df0b0f207 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -682,6 +682,11 @@ string EnumType::toString() const return string("enum ") + m_enum.getName(); } +bool EnumType::isExplicitlyConvertibleTo(Type const& _convertTo) const +{ + return _convertTo.getCategory() == getCategory() || _convertTo.getCategory() == Category::Integer; +} + FunctionType::FunctionType(FunctionDefinition const& _function, bool _isInternal): m_location(_isInternal ? Location::Internal : Location::External), m_isConstant(_function.isDeclaredConst()), diff --git a/libsolidity/Types.h b/libsolidity/Types.h index 0b576bd3f..15bd86b1b 100644 --- a/libsolidity/Types.h +++ b/libsolidity/Types.h @@ -381,6 +381,8 @@ public: virtual std::string toString() const override; virtual bool isValueType() const override { return true; } + virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override; + EnumDefinition const& getEnumDefinition() const { return m_enum; } private: diff --git a/test/SolidityEndToEndTest.cpp b/test/SolidityEndToEndTest.cpp index 7fa7dd251..551607df2 100644 --- a/test/SolidityEndToEndTest.cpp +++ b/test/SolidityEndToEndTest.cpp @@ -2510,7 +2510,7 @@ BOOST_AUTO_TEST_CASE(using_enums) } function getChoice() returns (uint d) { - d = choices; + d = uint256(choices); } ActionChoices choices; } diff --git a/test/SolidityNameAndTypeResolution.cpp b/test/SolidityNameAndTypeResolution.cpp index 34f51a4ce..9399280b0 100644 --- a/test/SolidityNameAndTypeResolution.cpp +++ b/test/SolidityNameAndTypeResolution.cpp @@ -1022,6 +1022,40 @@ BOOST_AUTO_TEST_CASE(enum_invalid_member_access) BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); } +BOOST_AUTO_TEST_CASE(enum_explicit_conversion_is_okay) +{ + char const* text = R"( + contract test { + enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }; + function test() + { + a = uint256(ActionChoices.GoStraight); + b = uint64(ActionChoices.Sit); + } + uint256 a; + uint64 b; + } + )"; + BOOST_CHECK_NO_THROW(parseTextAndResolveNamesWithChecks(text)); +} + +BOOST_AUTO_TEST_CASE(enum_implicit_conversion_is_not_okay) +{ + char const* text = R"( + contract test { + enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }; + function test() + { + a = ActionChoices.GoStraight; + b = ActionChoices.Sit; + } + uint256 a; + uint64 b; + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); +} + BOOST_AUTO_TEST_SUITE_END() } From 5c164fb42c67aa541d00675245b8bedda49b8e1e Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Fri, 13 Feb 2015 13:32:18 +0100 Subject: [PATCH 167/213] Enum Value member access should now work properly - Also detection of duplicate enum values and tests for them have been added --- libsolidity/AST.cpp | 14 +++++++------ libsolidity/ExpressionCompiler.cpp | 27 ++++++++++++++++++-------- test/SolidityNameAndTypeResolution.cpp | 17 ++++++++++++++++ 3 files changed, 44 insertions(+), 14 deletions(-) diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp index 7653952f4..65dc57e5e 100644 --- a/libsolidity/AST.cpp +++ b/libsolidity/AST.cpp @@ -263,13 +263,15 @@ void StructDefinition::checkRecursion() const void EnumDefinition::checkValidityOfMembers() const { -#if 0 // LTODO: Make this work for the Declarations - vector> members = getMembers(); - sort(begin(members), end(members)); - for (size_t i = 0; i < members.size(); ++i) - if (members[i] == members[i + 1]) + vector> members(getMembers()); + auto compareDecls = [](ASTPointer a, ASTPointer b) + { + return a->getName() < b->getName(); + }; + sort(begin(members), end(members), compareDecls); + for (size_t i = 0; i < members.size() - 1; ++i) + if (members[i]->getName() == members[i + 1]->getName()) BOOST_THROW_EXCEPTION(createTypeError("Duplicate member detected in Enum")); -#endif } TypePointer EnumDefinition::getType(ContractDefinition const*) const diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index dd41b485a..4e72aca54 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -494,20 +494,31 @@ void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess) EnumType const& type = dynamic_cast(*_memberAccess.getExpression().getType()); EnumDefinition const& enumDef = type.getEnumDefinition(); m_context << enumDef.getMemberValue(_memberAccess.getMemberName()); + break; } case Type::Category::TypeType: { TypeType const& type = dynamic_cast(*_memberAccess.getExpression().getType()); + ContractType const* contractType; + EnumType const* enumType; if (type.getMembers().getMemberType(member)) { - ContractDefinition const& contract = dynamic_cast(*type.getActualType()) - .getContractDefinition(); - for (ASTPointer const& function: contract.getDefinedFunctions()) - if (function->getName() == member) - { - m_context << m_context.getFunctionEntryLabel(*function).pushTag(); - return; - } + if ((contractType = dynamic_cast(type.getActualType().get()))) + { + ContractDefinition const& contract = contractType->getContractDefinition(); + for (ASTPointer const& function: contract.getDefinedFunctions()) + if (function->getName() == member) + { + m_context << m_context.getFunctionEntryLabel(*function).pushTag(); + return; + } + } + else if ((enumType = dynamic_cast(type.getActualType().get()))) + { + EnumDefinition const &enumDef = enumType->getEnumDefinition(); + m_context << enumDef.getMemberValue(_memberAccess.getMemberName()); + return; + } } BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Invalid member access to " + type.toString())); } diff --git a/test/SolidityNameAndTypeResolution.cpp b/test/SolidityNameAndTypeResolution.cpp index 9399280b0..e7482d661 100644 --- a/test/SolidityNameAndTypeResolution.cpp +++ b/test/SolidityNameAndTypeResolution.cpp @@ -1056,6 +1056,23 @@ BOOST_AUTO_TEST_CASE(enum_implicit_conversion_is_not_okay) BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); } +BOOST_AUTO_TEST_CASE(enum_duplicate_values) +{ + char const* text = R"( + contract test { + enum ActionChoices { GoLeft, GoRight, GoLeft, Sit }; + function test() + { + a = 1; + b = 2; + } + uint256 a; + uint64 b; + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); +} + BOOST_AUTO_TEST_SUITE_END() } From fc6210e00f780647b678fbdeda424440e0c91869 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Fri, 13 Feb 2015 15:59:30 +0100 Subject: [PATCH 168/213] Indentation fixes --- libsolidity/Parser.cpp | 2 +- libsolidity/Token.h | 66 +++++++++++++------------- libsolidity/Types.cpp | 2 +- test/SolidityNameAndTypeResolution.cpp | 4 +- 4 files changed, 37 insertions(+), 37 deletions(-) diff --git a/libsolidity/Parser.cpp b/libsolidity/Parser.cpp index e59e698f1..59c360a41 100644 --- a/libsolidity/Parser.cpp +++ b/libsolidity/Parser.cpp @@ -289,7 +289,7 @@ ASTPointer Parser::parseEnumDefinition() break; expectToken(Token::Comma); if (m_scanner->getCurrentToken() != Token::Identifier) { - BOOST_THROW_EXCEPTION(createParserError("Expected Identifier after ,")); + BOOST_THROW_EXCEPTION(createParserError("Expected Identifier after ','")); } } diff --git a/libsolidity/Token.h b/libsolidity/Token.h index 5039d5b5f..3e599a6ee 100644 --- a/libsolidity/Token.h +++ b/libsolidity/Token.h @@ -72,26 +72,26 @@ namespace solidity T(EOS, "EOS", 0) \ \ /* Punctuators (ECMA-262, section 7.7, page 15). */ \ - T(LParen, "(", 0) \ - T(RParen, ")", 0) \ - T(LBrack, "[", 0) \ - T(RBrack, "]", 0) \ - T(LBrace, "{", 0) \ - T(RBrace, "}", 0) \ - T(Colon, ":", 0) \ - T(Semicolon, ";", 0) \ - T(Period, ".", 0) \ - T(Conditional, "?", 3) \ - T(Arrow, "=>", 0) \ - \ + T(LParen, "(", 0) \ + T(RParen, ")", 0) \ + T(LBrack, "[", 0) \ + T(RBrack, "]", 0) \ + T(LBrace, "{", 0) \ + T(RBrace, "}", 0) \ + T(Colon, ":", 0) \ + T(Semicolon, ";", 0) \ + T(Period, ".", 0) \ + T(Conditional, "?", 3) \ + T(Arrow, "=>", 0) \ + \ /* Assignment operators. */ \ /* IsAssignmentOp() relies on this block of enum values being */ \ /* contiguous and sorted in the same order!*/ \ - T(Assign, "=", 2) \ + T(Assign, "=", 2) \ /* The following have to be in exactly the same order as the simple binary operators*/ \ - T(AssignBitOr, "|=", 2) \ - T(AssignBitXor, "^=", 2) \ - T(AssignBitAnd, "&=", 2) \ + T(AssignBitOr, "|=", 2) \ + T(AssignBitXor, "^=", 2) \ + T(AssignBitAnd, "&=", 2) \ T(AssignShl, "<<=", 2) \ T(AssignSar, ">>=", 2) \ T(AssignShr, ">>>=", 2) \ @@ -107,9 +107,9 @@ namespace solidity T(Comma, ",", 1) \ T(Or, "||", 4) \ T(And, "&&", 5) \ - T(BitOr, "|", 8) \ - T(BitXor, "^", 9) \ - T(BitAnd, "&", 10) \ + T(BitOr, "|", 8) \ + T(BitXor, "^", 9) \ + T(BitAnd, "&", 10) \ T(SHL, "<<", 11) \ T(SAR, ">>", 11) \ T(SHR, ">>>", 11) \ @@ -123,19 +123,19 @@ namespace solidity /* Compare operators sorted by precedence. */ \ /* IsCompareOp() relies on this block of enum values */ \ /* being contiguous and sorted in the same order! */ \ - T(Equal, "==", 6) \ - T(NotEqual, "!=", 6) \ - T(LessThan, "<", 7) \ - T(GreaterThan, ">", 7) \ - T(LessThanOrEqual, "<=", 7) \ - T(GreaterThanOrEqual, ">=", 7) \ + T(Equal, "==", 6) \ + T(NotEqual, "!=", 6) \ + T(LessThan, "<", 7) \ + T(GreaterThan, ">", 7) \ + T(LessThanOrEqual, "<=", 7) \ + T(GreaterThanOrEqual, ">=", 7) \ K(In, "in", 7) \ \ /* Unary operators. */ \ /* IsUnaryOp() relies on this block of enum values */ \ /* being contiguous and sorted in the same order! */ \ T(Not, "!", 0) \ - T(BitNot, "~", 0) \ + T(BitNot, "~", 0) \ T(Inc, "++", 0) \ T(Dec, "--", 0) \ K(Delete, "delete", 0) \ @@ -168,7 +168,7 @@ namespace solidity K(Switch, "switch", 0) \ K(Var, "var", 0) \ K(While, "while", 0) \ - K(Enum, "enum", 0) \ + K(Enum, "enum", 0) \ \ /* Ether subdenominations */ \ K(SubWei, "wei", 0) \ @@ -316,15 +316,15 @@ namespace solidity K(Text, "text", 0) \ K(Real, "real", 0) \ K(UReal, "ureal", 0) \ - T(TypesEnd, NULL, 0) /* used as type enum end marker */ \ + T(TypesEnd, NULL, 0) /* used as type enum end marker */ \ \ /* Literals */ \ - K(NullLiteral, "null", 0) \ - K(TrueLiteral, "true", 0) \ - K(FalseLiteral, "false", 0) \ + K(NullLiteral, "null", 0) \ + K(TrueLiteral, "true", 0) \ + K(FalseLiteral, "false", 0) \ T(Number, NULL, 0) \ - T(StringLiteral, NULL, 0) \ - T(CommentLiteral, NULL, 0) \ + T(StringLiteral, NULL, 0) \ + T(CommentLiteral, NULL, 0) \ \ /* Identifiers (not keywords or future reserved words). */ \ T(Identifier, NULL, 0) \ diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index df0b0f207..709002bac 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -953,7 +953,7 @@ MemberList const& TypeType::getMembers() const { EnumDefinition const& enumDef = dynamic_cast(*m_actualType).getEnumDefinition(); for (ASTPointer const& enumValue: enumDef.getMembers()) - members.insert(make_pair(enumValue->getName(), make_shared(enumDef))); + members.insert(make_pair(enumValue->getName(), make_shared(enumDef))); m_members.reset(new MemberList(members)); } m_members.reset(new MemberList(members)); diff --git a/test/SolidityNameAndTypeResolution.cpp b/test/SolidityNameAndTypeResolution.cpp index e7482d661..051b3dce7 100644 --- a/test/SolidityNameAndTypeResolution.cpp +++ b/test/SolidityNameAndTypeResolution.cpp @@ -1063,8 +1063,8 @@ BOOST_AUTO_TEST_CASE(enum_duplicate_values) enum ActionChoices { GoLeft, GoRight, GoLeft, Sit }; function test() { - a = 1; - b = 2; + a = 1; + b = 2; } uint256 a; uint64 b; From b4302da54292b9ea18c46de887d07bde3113777e Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Fri, 13 Feb 2015 17:22:53 +0100 Subject: [PATCH 169/213] EnumDeclaration -> EnumValue --- libsolidity/AST.cpp | 8 ++++---- libsolidity/AST.h | 10 +++++----- libsolidity/ASTForward.h | 2 +- libsolidity/ASTPrinter.cpp | 4 ++-- libsolidity/ASTPrinter.h | 4 ++-- libsolidity/ASTVisitor.h | 8 ++++---- libsolidity/AST_accept.h | 4 ++-- libsolidity/Parser.cpp | 6 +++--- libsolidity/Parser.h | 2 +- libsolidity/Types.cpp | 2 +- 10 files changed, 25 insertions(+), 25 deletions(-) diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp index 65dc57e5e..cdc1f6cb5 100644 --- a/libsolidity/AST.cpp +++ b/libsolidity/AST.cpp @@ -206,7 +206,7 @@ vector, FunctionTypePointer>> const& ContractDefinition::getIn return *m_interfaceFunctionList; } -TypePointer EnumDeclaration::getType(ContractDefinition const*) const +TypePointer EnumvValue::getType(ContractDefinition const*) const { // LTODO: How to get the parent EnumDefinition and return its type here? return nullptr; @@ -263,8 +263,8 @@ void StructDefinition::checkRecursion() const void EnumDefinition::checkValidityOfMembers() const { - vector> members(getMembers()); - auto compareDecls = [](ASTPointer a, ASTPointer b) + vector> members(getMembers()); + auto compareDecls = [](ASTPointer a, ASTPointer b) { return a->getName() < b->getName(); }; @@ -283,7 +283,7 @@ TypePointer EnumDefinition::getType(ContractDefinition const*) const unsigned int EnumDefinition::getMemberValue(ASTString const& _member) const { unsigned int index = 0; - for (ASTPointer const& decl: m_members) + for (ASTPointer const& decl: m_members) { if (decl->getName() == _member) return index; diff --git a/libsolidity/AST.h b/libsolidity/AST.h index fdbbcd5b4..11dfef590 100644 --- a/libsolidity/AST.h +++ b/libsolidity/AST.h @@ -168,10 +168,10 @@ private: /** * Declaration of an Enum Value */ -class EnumDeclaration : public Declaration +class EnumvValue : public Declaration { public: - EnumDeclaration(Location const& _location, + EnumvValue(Location const& _location, ASTPointer const& _name): Declaration(_location, _name) {} @@ -339,12 +339,12 @@ class EnumDefinition: public Declaration public: EnumDefinition(Location const& _location, ASTPointer const& _name, - std::vector> const& _members): + std::vector> const& _members): Declaration(_location, _name), m_members(_members) {} virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTConstVisitor& _visitor) const override; - std::vector> const& getMembers() const { return m_members; } + std::vector> const& getMembers() const { return m_members; } virtual TypePointer getType(ContractDefinition const*) const override; @@ -356,7 +356,7 @@ public: private: - std::vector> m_members; + std::vector> m_members; }; /** diff --git a/libsolidity/ASTForward.h b/libsolidity/ASTForward.h index a0a6f6832..3370e88a8 100644 --- a/libsolidity/ASTForward.h +++ b/libsolidity/ASTForward.h @@ -41,7 +41,7 @@ class ContractDefinition; class InheritanceSpecifier; class StructDefinition; class EnumDefinition; -class EnumDeclaration; +class EnumvValue; class ParameterList; class FunctionDefinition; class VariableDeclaration; diff --git a/libsolidity/ASTPrinter.cpp b/libsolidity/ASTPrinter.cpp index b655d309d..dd66bf0d7 100644 --- a/libsolidity/ASTPrinter.cpp +++ b/libsolidity/ASTPrinter.cpp @@ -77,7 +77,7 @@ bool ASTPrinter::visit(EnumDefinition const& _node) return goDeeper(); } -bool ASTPrinter::visit(EnumDeclaration const& _node) +bool ASTPrinter::visit(EnumvValue const& _node) { writeLine("EnumValue \"" + _node.getName() + "\""); return goDeeper(); @@ -364,7 +364,7 @@ void ASTPrinter::endVisit(EnumDefinition const&) m_indentation--; } -void ASTPrinter::endVisit(EnumDeclaration const&) +void ASTPrinter::endVisit(EnumvValue const&) { m_indentation--; } diff --git a/libsolidity/ASTPrinter.h b/libsolidity/ASTPrinter.h index a306e90b5..dda2f1c4a 100644 --- a/libsolidity/ASTPrinter.h +++ b/libsolidity/ASTPrinter.h @@ -47,7 +47,7 @@ public: bool visit(InheritanceSpecifier const& _node) override; bool visit(StructDefinition const& _node) override; bool visit(EnumDefinition const& _node) override; - bool visit(EnumDeclaration const& _node) override; + bool visit(EnumvValue const& _node) override; bool visit(ParameterList const& _node) override; bool visit(FunctionDefinition const& _node) override; bool visit(VariableDeclaration const& _node) override; @@ -88,7 +88,7 @@ public: void endVisit(InheritanceSpecifier const&) override; void endVisit(StructDefinition const&) override; void endVisit(EnumDefinition const&) override; - void endVisit(EnumDeclaration const&) override; + void endVisit(EnumvValue const&) override; void endVisit(ParameterList const&) override; void endVisit(FunctionDefinition const&) override; void endVisit(VariableDeclaration const&) override; diff --git a/libsolidity/ASTVisitor.h b/libsolidity/ASTVisitor.h index 108827573..392da7616 100644 --- a/libsolidity/ASTVisitor.h +++ b/libsolidity/ASTVisitor.h @@ -48,7 +48,7 @@ public: virtual bool visit(InheritanceSpecifier&) { return true; } virtual bool visit(StructDefinition&) { return true; } virtual bool visit(EnumDefinition&) { return true; } - virtual bool visit(EnumDeclaration&) { return true; } + virtual bool visit(EnumvValue&) { return true; } virtual bool visit(ParameterList&) { return true; } virtual bool visit(FunctionDefinition&) { return true; } virtual bool visit(VariableDeclaration&) { return true; } @@ -91,7 +91,7 @@ public: virtual void endVisit(InheritanceSpecifier&) { } virtual void endVisit(StructDefinition&) { } virtual void endVisit(EnumDefinition&) { } - virtual void endVisit(EnumDeclaration&) { } + virtual void endVisit(EnumvValue&) { } virtual void endVisit(ParameterList&) { } virtual void endVisit(FunctionDefinition&) { } virtual void endVisit(VariableDeclaration&) { } @@ -138,7 +138,7 @@ public: virtual bool visit(InheritanceSpecifier const&) { return true; } virtual bool visit(StructDefinition const&) { return true; } virtual bool visit(EnumDefinition const&) { return true; } - virtual bool visit(EnumDeclaration const&) { return true; } + virtual bool visit(EnumvValue const&) { return true; } virtual bool visit(ParameterList const&) { return true; } virtual bool visit(FunctionDefinition const&) { return true; } virtual bool visit(VariableDeclaration const&) { return true; } @@ -181,7 +181,7 @@ public: virtual void endVisit(InheritanceSpecifier const&) { } virtual void endVisit(StructDefinition const&) { } virtual void endVisit(EnumDefinition const&) { } - virtual void endVisit(EnumDeclaration const&) { } + virtual void endVisit(EnumvValue const&) { } virtual void endVisit(ParameterList const&) { } virtual void endVisit(FunctionDefinition const&) { } virtual void endVisit(VariableDeclaration const&) { } diff --git a/libsolidity/AST_accept.h b/libsolidity/AST_accept.h index 78c2f8c58..e6877d937 100644 --- a/libsolidity/AST_accept.h +++ b/libsolidity/AST_accept.h @@ -121,13 +121,13 @@ void EnumDefinition::accept(ASTConstVisitor& _visitor) const _visitor.endVisit(*this); } -void EnumDeclaration::accept(ASTVisitor& _visitor) +void EnumvValue::accept(ASTVisitor& _visitor) { _visitor.visit(*this); _visitor.endVisit(*this); } -void EnumDeclaration::accept(ASTConstVisitor& _visitor) const +void EnumvValue::accept(ASTConstVisitor& _visitor) const { _visitor.visit(*this); _visitor.endVisit(*this); diff --git a/libsolidity/Parser.cpp b/libsolidity/Parser.cpp index 59c360a41..3e077261b 100644 --- a/libsolidity/Parser.cpp +++ b/libsolidity/Parser.cpp @@ -266,12 +266,12 @@ ASTPointer Parser::parseStructDefinition() return nodeFactory.createNode(name, members); } -ASTPointer Parser::parseEnumDeclaration() +ASTPointer Parser::parseEnumDeclaration() { ASTNodeFactory nodeFactory(*this); ASTPointer name = expectIdentifierToken(); nodeFactory.markEndPosition(); - return nodeFactory.createNode(name); + return nodeFactory.createNode(name); } ASTPointer Parser::parseEnumDefinition() @@ -279,7 +279,7 @@ ASTPointer Parser::parseEnumDefinition() ASTNodeFactory nodeFactory(*this); expectToken(Token::Enum); ASTPointer name = expectIdentifierToken(); - vector> members; + vector> members; expectToken(Token::LBrace); while (m_scanner->getCurrentToken() != Token::RBrace) diff --git a/libsolidity/Parser.h b/libsolidity/Parser.h index 734bdd57e..44b14da06 100644 --- a/libsolidity/Parser.h +++ b/libsolidity/Parser.h @@ -62,7 +62,7 @@ private: ASTPointer parseFunctionDefinition(ASTString const* _contractName); ASTPointer parseStructDefinition(); ASTPointer parseEnumDefinition(); - ASTPointer parseEnumDeclaration(); + ASTPointer parseEnumDeclaration(); ASTPointer parseVariableDeclaration(VarDeclParserOptions const& _options = VarDeclParserOptions()); ASTPointer parseModifierDefinition(); ASTPointer parseEventDefinition(); diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index 709002bac..df62773a9 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -952,7 +952,7 @@ MemberList const& TypeType::getMembers() const else if (m_actualType->getCategory() == Category::Enum) { EnumDefinition const& enumDef = dynamic_cast(*m_actualType).getEnumDefinition(); - for (ASTPointer const& enumValue: enumDef.getMembers()) + for (ASTPointer const& enumValue: enumDef.getMembers()) members.insert(make_pair(enumValue->getName(), make_shared(enumDef))); m_members.reset(new MemberList(members)); } From 81ecc03e9df66603cb71d5b38b3b05ac874ff5e8 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Fri, 13 Feb 2015 17:32:34 +0100 Subject: [PATCH 170/213] implement getType() for EnumValue --- libsolidity/AST.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp index cdc1f6cb5..2baf9dae8 100644 --- a/libsolidity/AST.cpp +++ b/libsolidity/AST.cpp @@ -208,8 +208,8 @@ vector, FunctionTypePointer>> const& ContractDefinition::getIn TypePointer EnumvValue::getType(ContractDefinition const*) const { - // LTODO: How to get the parent EnumDefinition and return its type here? - return nullptr; + EnumDefinition const* parentDef = dynamic_cast(getScope()); + return make_shared(*parentDef); } void InheritanceSpecifier::checkTypeRequirements() From e5ccf5e2bed4d55508c90b405c59964c442b0191 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Fri, 13 Feb 2015 17:34:46 +0100 Subject: [PATCH 171/213] Typo in EnumValue --- libsolidity/AST.cpp | 8 ++++---- libsolidity/AST.h | 14 +++++++------- libsolidity/ASTForward.h | 2 +- libsolidity/ASTPrinter.cpp | 4 ++-- libsolidity/ASTPrinter.h | 4 ++-- libsolidity/ASTVisitor.h | 8 ++++---- libsolidity/AST_accept.h | 4 ++-- libsolidity/Parser.cpp | 6 +++--- libsolidity/Parser.h | 2 +- libsolidity/Types.cpp | 2 +- 10 files changed, 27 insertions(+), 27 deletions(-) diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp index 2baf9dae8..9d7d2169b 100644 --- a/libsolidity/AST.cpp +++ b/libsolidity/AST.cpp @@ -206,7 +206,7 @@ vector, FunctionTypePointer>> const& ContractDefinition::getIn return *m_interfaceFunctionList; } -TypePointer EnumvValue::getType(ContractDefinition const*) const +TypePointer EnumValue::getType(ContractDefinition const*) const { EnumDefinition const* parentDef = dynamic_cast(getScope()); return make_shared(*parentDef); @@ -263,8 +263,8 @@ void StructDefinition::checkRecursion() const void EnumDefinition::checkValidityOfMembers() const { - vector> members(getMembers()); - auto compareDecls = [](ASTPointer a, ASTPointer b) + vector> members(getMembers()); + auto compareDecls = [](ASTPointer a, ASTPointer b) { return a->getName() < b->getName(); }; @@ -283,7 +283,7 @@ TypePointer EnumDefinition::getType(ContractDefinition const*) const unsigned int EnumDefinition::getMemberValue(ASTString const& _member) const { unsigned int index = 0; - for (ASTPointer const& decl: m_members) + for (ASTPointer const& decl: m_members) { if (decl->getName() == _member) return index; diff --git a/libsolidity/AST.h b/libsolidity/AST.h index 11dfef590..3485631ba 100644 --- a/libsolidity/AST.h +++ b/libsolidity/AST.h @@ -168,12 +168,12 @@ private: /** * Declaration of an Enum Value */ -class EnumvValue : public Declaration +class EnumValue: public Declaration { public: - EnumvValue(Location const& _location, - ASTPointer const& _name): - Declaration(_location, _name) {} + EnumValue(Location const& _location, + ASTPointer const& _name): + Declaration(_location, _name) {} virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTConstVisitor& _visitor) const override; @@ -339,12 +339,12 @@ class EnumDefinition: public Declaration public: EnumDefinition(Location const& _location, ASTPointer const& _name, - std::vector> const& _members): + std::vector> const& _members): Declaration(_location, _name), m_members(_members) {} virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTConstVisitor& _visitor) const override; - std::vector> const& getMembers() const { return m_members; } + std::vector> const& getMembers() const { return m_members; } virtual TypePointer getType(ContractDefinition const*) const override; @@ -356,7 +356,7 @@ public: private: - std::vector> m_members; + std::vector> m_members; }; /** diff --git a/libsolidity/ASTForward.h b/libsolidity/ASTForward.h index 3370e88a8..0b6817e45 100644 --- a/libsolidity/ASTForward.h +++ b/libsolidity/ASTForward.h @@ -41,7 +41,7 @@ class ContractDefinition; class InheritanceSpecifier; class StructDefinition; class EnumDefinition; -class EnumvValue; +class EnumValue; class ParameterList; class FunctionDefinition; class VariableDeclaration; diff --git a/libsolidity/ASTPrinter.cpp b/libsolidity/ASTPrinter.cpp index dd66bf0d7..d380b0029 100644 --- a/libsolidity/ASTPrinter.cpp +++ b/libsolidity/ASTPrinter.cpp @@ -77,7 +77,7 @@ bool ASTPrinter::visit(EnumDefinition const& _node) return goDeeper(); } -bool ASTPrinter::visit(EnumvValue const& _node) +bool ASTPrinter::visit(EnumValue const& _node) { writeLine("EnumValue \"" + _node.getName() + "\""); return goDeeper(); @@ -364,7 +364,7 @@ void ASTPrinter::endVisit(EnumDefinition const&) m_indentation--; } -void ASTPrinter::endVisit(EnumvValue const&) +void ASTPrinter::endVisit(EnumValue const&) { m_indentation--; } diff --git a/libsolidity/ASTPrinter.h b/libsolidity/ASTPrinter.h index dda2f1c4a..d9072aacc 100644 --- a/libsolidity/ASTPrinter.h +++ b/libsolidity/ASTPrinter.h @@ -47,7 +47,7 @@ public: bool visit(InheritanceSpecifier const& _node) override; bool visit(StructDefinition const& _node) override; bool visit(EnumDefinition const& _node) override; - bool visit(EnumvValue const& _node) override; + bool visit(EnumValue const& _node) override; bool visit(ParameterList const& _node) override; bool visit(FunctionDefinition const& _node) override; bool visit(VariableDeclaration const& _node) override; @@ -88,7 +88,7 @@ public: void endVisit(InheritanceSpecifier const&) override; void endVisit(StructDefinition const&) override; void endVisit(EnumDefinition const&) override; - void endVisit(EnumvValue const&) override; + void endVisit(EnumValue const&) override; void endVisit(ParameterList const&) override; void endVisit(FunctionDefinition const&) override; void endVisit(VariableDeclaration const&) override; diff --git a/libsolidity/ASTVisitor.h b/libsolidity/ASTVisitor.h index 392da7616..a7fa6b1cf 100644 --- a/libsolidity/ASTVisitor.h +++ b/libsolidity/ASTVisitor.h @@ -48,7 +48,7 @@ public: virtual bool visit(InheritanceSpecifier&) { return true; } virtual bool visit(StructDefinition&) { return true; } virtual bool visit(EnumDefinition&) { return true; } - virtual bool visit(EnumvValue&) { return true; } + virtual bool visit(EnumValue&) { return true; } virtual bool visit(ParameterList&) { return true; } virtual bool visit(FunctionDefinition&) { return true; } virtual bool visit(VariableDeclaration&) { return true; } @@ -91,7 +91,7 @@ public: virtual void endVisit(InheritanceSpecifier&) { } virtual void endVisit(StructDefinition&) { } virtual void endVisit(EnumDefinition&) { } - virtual void endVisit(EnumvValue&) { } + virtual void endVisit(EnumValue&) { } virtual void endVisit(ParameterList&) { } virtual void endVisit(FunctionDefinition&) { } virtual void endVisit(VariableDeclaration&) { } @@ -138,7 +138,7 @@ public: virtual bool visit(InheritanceSpecifier const&) { return true; } virtual bool visit(StructDefinition const&) { return true; } virtual bool visit(EnumDefinition const&) { return true; } - virtual bool visit(EnumvValue const&) { return true; } + virtual bool visit(EnumValue const&) { return true; } virtual bool visit(ParameterList const&) { return true; } virtual bool visit(FunctionDefinition const&) { return true; } virtual bool visit(VariableDeclaration const&) { return true; } @@ -181,7 +181,7 @@ public: virtual void endVisit(InheritanceSpecifier const&) { } virtual void endVisit(StructDefinition const&) { } virtual void endVisit(EnumDefinition const&) { } - virtual void endVisit(EnumvValue const&) { } + virtual void endVisit(EnumValue const&) { } virtual void endVisit(ParameterList const&) { } virtual void endVisit(FunctionDefinition const&) { } virtual void endVisit(VariableDeclaration const&) { } diff --git a/libsolidity/AST_accept.h b/libsolidity/AST_accept.h index e6877d937..b71e103df 100644 --- a/libsolidity/AST_accept.h +++ b/libsolidity/AST_accept.h @@ -121,13 +121,13 @@ void EnumDefinition::accept(ASTConstVisitor& _visitor) const _visitor.endVisit(*this); } -void EnumvValue::accept(ASTVisitor& _visitor) +void EnumValue::accept(ASTVisitor& _visitor) { _visitor.visit(*this); _visitor.endVisit(*this); } -void EnumvValue::accept(ASTConstVisitor& _visitor) const +void EnumValue::accept(ASTConstVisitor& _visitor) const { _visitor.visit(*this); _visitor.endVisit(*this); diff --git a/libsolidity/Parser.cpp b/libsolidity/Parser.cpp index 3e077261b..28339a464 100644 --- a/libsolidity/Parser.cpp +++ b/libsolidity/Parser.cpp @@ -266,12 +266,12 @@ ASTPointer Parser::parseStructDefinition() return nodeFactory.createNode(name, members); } -ASTPointer Parser::parseEnumDeclaration() +ASTPointer Parser::parseEnumDeclaration() { ASTNodeFactory nodeFactory(*this); ASTPointer name = expectIdentifierToken(); nodeFactory.markEndPosition(); - return nodeFactory.createNode(name); + return nodeFactory.createNode(name); } ASTPointer Parser::parseEnumDefinition() @@ -279,7 +279,7 @@ ASTPointer Parser::parseEnumDefinition() ASTNodeFactory nodeFactory(*this); expectToken(Token::Enum); ASTPointer name = expectIdentifierToken(); - vector> members; + vector> members; expectToken(Token::LBrace); while (m_scanner->getCurrentToken() != Token::RBrace) diff --git a/libsolidity/Parser.h b/libsolidity/Parser.h index 44b14da06..172b45dd5 100644 --- a/libsolidity/Parser.h +++ b/libsolidity/Parser.h @@ -62,7 +62,7 @@ private: ASTPointer parseFunctionDefinition(ASTString const* _contractName); ASTPointer parseStructDefinition(); ASTPointer parseEnumDefinition(); - ASTPointer parseEnumDeclaration(); + ASTPointer parseEnumDeclaration(); ASTPointer parseVariableDeclaration(VarDeclParserOptions const& _options = VarDeclParserOptions()); ASTPointer parseModifierDefinition(); ASTPointer parseEventDefinition(); diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index df62773a9..06c0af320 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -952,7 +952,7 @@ MemberList const& TypeType::getMembers() const else if (m_actualType->getCategory() == Category::Enum) { EnumDefinition const& enumDef = dynamic_cast(*m_actualType).getEnumDefinition(); - for (ASTPointer const& enumValue: enumDef.getMembers()) + for (ASTPointer const& enumValue: enumDef.getMembers()) members.insert(make_pair(enumValue->getName(), make_shared(enumDef))); m_members.reset(new MemberList(members)); } From c3c1b5c63c9834115f3529637c80d109ea3b5992 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Fri, 13 Feb 2015 22:52:04 +0100 Subject: [PATCH 172/213] Addressing issues with Enums in Solidity --- libsolidity/AST.cpp | 3 ++- libsolidity/AST.h | 30 ++++++++++----------- libsolidity/ExpressionCompiler.cpp | 36 +++++++++++++------------- libsolidity/Parser.cpp | 17 +++--------- libsolidity/Parser.h | 3 +-- libsolidity/Types.h | 2 +- test/SolidityNameAndTypeResolution.cpp | 7 ----- test/SolidityParser.cpp | 16 +++--------- 8 files changed, 44 insertions(+), 70 deletions(-) diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp index 9d7d2169b..5aa672184 100644 --- a/libsolidity/AST.cpp +++ b/libsolidity/AST.cpp @@ -209,6 +209,7 @@ vector, FunctionTypePointer>> const& ContractDefinition::getIn TypePointer EnumValue::getType(ContractDefinition const*) const { EnumDefinition const* parentDef = dynamic_cast(getScope()); + solAssert(parentDef, "Enclosing Scope of EnumValue was not set"); return make_shared(*parentDef); } @@ -271,7 +272,7 @@ void EnumDefinition::checkValidityOfMembers() const sort(begin(members), end(members), compareDecls); for (size_t i = 0; i < members.size() - 1; ++i) if (members[i]->getName() == members[i + 1]->getName()) - BOOST_THROW_EXCEPTION(createTypeError("Duplicate member detected in Enum")); + BOOST_THROW_EXCEPTION(members[i]->createTypeError("Duplicate member detected in Enum")); } TypePointer EnumDefinition::getType(ContractDefinition const*) const diff --git a/libsolidity/AST.h b/libsolidity/AST.h index 3485631ba..25c18f4f7 100644 --- a/libsolidity/AST.h +++ b/libsolidity/AST.h @@ -165,21 +165,6 @@ private: Declaration const* m_scope; }; -/** - * Declaration of an Enum Value - */ -class EnumValue: public Declaration -{ - public: - EnumValue(Location const& _location, - ASTPointer const& _name): - Declaration(_location, _name) {} - - virtual void accept(ASTVisitor& _visitor) override; - virtual void accept(ASTConstVisitor& _visitor) const override; - TypePointer getType(ContractDefinition const* = nullptr) const; -}; - /** * Abstract class that is added to each AST node that can store local variables. */ @@ -359,6 +344,21 @@ private: std::vector> m_members; }; +/** + * Declaration of an Enum Value + */ +class EnumValue: public Declaration +{ + public: + EnumValue(Location const& _location, + ASTPointer const& _name): + Declaration(_location, _name) {} + + virtual void accept(ASTVisitor& _visitor) override; + virtual void accept(ASTConstVisitor& _visitor) const override; + TypePointer getType(ContractDefinition const* = nullptr) const; +}; + /** * Parameter list, used as function parameter list and return list. * None of the parameters is allowed to contain mappings (not even recursively diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index 4e72aca54..00c2dafd1 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -501,26 +501,26 @@ void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess) TypeType const& type = dynamic_cast(*_memberAccess.getExpression().getType()); ContractType const* contractType; EnumType const* enumType; - if (type.getMembers().getMemberType(member)) + if (!type.getMembers().getMemberType(member)) + BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Invalid member access to " + type.toString())); + + if ((contractType = dynamic_cast(type.getActualType().get()))) { - if ((contractType = dynamic_cast(type.getActualType().get()))) - { - ContractDefinition const& contract = contractType->getContractDefinition(); - for (ASTPointer const& function: contract.getDefinedFunctions()) - if (function->getName() == member) - { - m_context << m_context.getFunctionEntryLabel(*function).pushTag(); - return; - } - } - else if ((enumType = dynamic_cast(type.getActualType().get()))) - { - EnumDefinition const &enumDef = enumType->getEnumDefinition(); - m_context << enumDef.getMemberValue(_memberAccess.getMemberName()); - return; - } + ContractDefinition const& contract = contractType->getContractDefinition(); + for (ASTPointer const& function: contract.getDefinedFunctions()) + if (function->getName() == member) + { + m_context << m_context.getFunctionEntryLabel(*function).pushTag(); + return; + } } - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Invalid member access to " + type.toString())); + else if ((enumType = dynamic_cast(type.getActualType().get()))) + { + EnumDefinition const &enumDef = enumType->getEnumDefinition(); + m_context << enumDef.getMemberValue(_memberAccess.getMemberName()); + return; + } + } case Type::Category::ByteArray: { diff --git a/libsolidity/Parser.cpp b/libsolidity/Parser.cpp index 28339a464..4277ef54f 100644 --- a/libsolidity/Parser.cpp +++ b/libsolidity/Parser.cpp @@ -266,12 +266,11 @@ ASTPointer Parser::parseStructDefinition() return nodeFactory.createNode(name, members); } -ASTPointer Parser::parseEnumDeclaration() +ASTPointer Parser::parseEnumValue() { ASTNodeFactory nodeFactory(*this); - ASTPointer name = expectIdentifierToken(); nodeFactory.markEndPosition(); - return nodeFactory.createNode(name); + return nodeFactory.createNode(expectIdentifierToken()); } ASTPointer Parser::parseEnumDefinition() @@ -284,13 +283,12 @@ ASTPointer Parser::parseEnumDefinition() while (m_scanner->getCurrentToken() != Token::RBrace) { - members.push_back(parseEnumDeclaration()); + members.push_back(parseEnumValue()); if (m_scanner->getCurrentToken() == Token::RBrace) break; expectToken(Token::Comma); - if (m_scanner->getCurrentToken() != Token::Identifier) { + if (m_scanner->getCurrentToken() != Token::Identifier) BOOST_THROW_EXCEPTION(createParserError("Expected Identifier after ','")); - } } nodeFactory.markEndPosition(); @@ -859,13 +857,6 @@ ASTPointer Parser::expectIdentifierToken() return getLiteralAndAdvance(); } -ASTPointer Parser::peekIdentifierToken() -{ - if (m_scanner->getCurrentToken() != Token::Identifier) - return nullptr; - return getLiteralAndAdvance(); -} - ASTPointer Parser::getLiteralAndAdvance() { ASTPointer identifier = make_shared(m_scanner->getCurrentLiteral()); diff --git a/libsolidity/Parser.h b/libsolidity/Parser.h index 172b45dd5..1bb4ea977 100644 --- a/libsolidity/Parser.h +++ b/libsolidity/Parser.h @@ -62,7 +62,7 @@ private: ASTPointer parseFunctionDefinition(ASTString const* _contractName); ASTPointer parseStructDefinition(); ASTPointer parseEnumDefinition(); - ASTPointer parseEnumDeclaration(); + ASTPointer parseEnumValue(); ASTPointer parseVariableDeclaration(VarDeclParserOptions const& _options = VarDeclParserOptions()); ASTPointer parseModifierDefinition(); ASTPointer parseEventDefinition(); @@ -98,7 +98,6 @@ private: void expectToken(Token::Value _value); Token::Value expectAssignmentOperator(); ASTPointer expectIdentifierToken(); - ASTPointer peekIdentifierToken(); ASTPointer getLiteralAndAdvance(); ///@} diff --git a/libsolidity/Types.h b/libsolidity/Types.h index 15bd86b1b..d8b1b6b7a 100644 --- a/libsolidity/Types.h +++ b/libsolidity/Types.h @@ -377,7 +377,7 @@ public: explicit EnumType(EnumDefinition const& _enum): m_enum(_enum) {} virtual TypePointer unaryOperatorResult(Token::Value _operator) const override; virtual bool operator==(Type const& _other) const override; - virtual unsigned getSizeOnStack() const override { return 1; /*@todo*/ } + virtual unsigned getSizeOnStack() const override { return 1; } virtual std::string toString() const override; virtual bool isValueType() const override { return true; } diff --git a/test/SolidityNameAndTypeResolution.cpp b/test/SolidityNameAndTypeResolution.cpp index 051b3dce7..c912939fc 100644 --- a/test/SolidityNameAndTypeResolution.cpp +++ b/test/SolidityNameAndTypeResolution.cpp @@ -1061,13 +1061,6 @@ BOOST_AUTO_TEST_CASE(enum_duplicate_values) char const* text = R"( contract test { enum ActionChoices { GoLeft, GoRight, GoLeft, Sit }; - function test() - { - a = 1; - b = 2; - } - uint256 a; - uint64 b; } )"; BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); diff --git a/test/SolidityParser.cpp b/test/SolidityParser.cpp index 07ec2dcfa..702d1d6db 100644 --- a/test/SolidityParser.cpp +++ b/test/SolidityParser.cpp @@ -703,14 +703,14 @@ BOOST_AUTO_TEST_CASE(literal_constants_with_ether_subdenominations_in_expression BOOST_CHECK_NO_THROW(parseTextExplainError(text)); } -BOOST_AUTO_TEST_CASE(enum_declaration) +BOOST_AUTO_TEST_CASE(enum_valid_declaration) { char const* text = R"( contract c { - enum foo { WARNING, NOTICE, ERROR, CRITICAL }; + enum validEnum { Value1, Value2, Value3, Value4 }; function c () { - a = foo.CRITICAL; + a = foo.Value3; } uint256 a; })"; @@ -722,11 +722,6 @@ BOOST_AUTO_TEST_CASE(empty_enum_declaration) char const* text = R"( contract c { enum foo { }; - function c () - { - a = 5; - } - uint256 a; })"; BOOST_CHECK_NO_THROW(parseTextExplainError(text)); } @@ -736,11 +731,6 @@ BOOST_AUTO_TEST_CASE(malformed_enum_declaration) char const* text = R"( contract c { enum foo { WARNING,}; - function c () - { - a = foo.CRITICAL; - } - uint256 a; })"; BOOST_CHECK_THROW(parseText(text), ParserError); } From 4a70ec94443f047a875bfb2ed4e32ccf7bec9533 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Fri, 13 Feb 2015 22:56:46 +0100 Subject: [PATCH 173/213] adding Enums to grammar.txt --- libsolidity/grammar.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libsolidity/grammar.txt b/libsolidity/grammar.txt index 1785b516c..5ba0ef238 100644 --- a/libsolidity/grammar.txt +++ b/libsolidity/grammar.txt @@ -1,7 +1,7 @@ ContractDefinition = 'contract' Identifier ( 'is' InheritanceSpecifier (',' InheritanceSpecifier )* )? '{' ContractPart* '}' -ContractPart = StateVariableDeclaration | StructDefinition | ModifierDefinition | FunctionDefinition +ContractPart = StateVariableDeclaration | StructDefinition | ModifierDefinition | FunctionDefinition | EnumDefinition InheritanceSpecifier = Identifier ( '(' Expression ( ',' Expression )* ')' )? StructDefinition = 'struct' Identifier '{' @@ -11,6 +11,9 @@ ModifierDefinition = 'modifier' Identifier ParameterList? Block FunctionDefinition = 'function' Identifier ParameterList ( Identifier | 'constant' | 'public' | 'protected' | 'private' )* ( 'returns' ParameterList )? Block + +EnumValue = Identifier +EnumDefinition = 'enum' '{' EnumValue (',' EnumValue)* '}' ';' ParameterList = '(' ( VariableDeclaration (',' VariableDeclaration)* )? ')' // semantic restriction: mappings and structs (recursively) containing mappings // are not allowed in argument lists From 58c598b8cb505e576a482c500a1e9ce6755c21df Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Fri, 13 Feb 2015 23:03:32 +0100 Subject: [PATCH 174/213] Moving getMemberValue from EnumDefinition to EnumType --- libsolidity/AST.cpp | 13 ------------- libsolidity/AST.h | 3 --- libsolidity/ExpressionCompiler.cpp | 6 ++---- libsolidity/Types.cpp | 12 ++++++++++++ libsolidity/Types.h | 2 ++ 5 files changed, 16 insertions(+), 20 deletions(-) diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp index 5aa672184..683452027 100644 --- a/libsolidity/AST.cpp +++ b/libsolidity/AST.cpp @@ -280,19 +280,6 @@ TypePointer EnumDefinition::getType(ContractDefinition const*) const return make_shared(make_shared(*this)); } - -unsigned int EnumDefinition::getMemberValue(ASTString const& _member) const -{ - unsigned int index = 0; - for (ASTPointer const& decl: m_members) - { - if (decl->getName() == _member) - return index; - ++index; - } - BOOST_THROW_EXCEPTION(createTypeError("Requested unknown enum value ." + _member)); -} - TypePointer FunctionDefinition::getType(ContractDefinition const*) const { return make_shared(*this); diff --git a/libsolidity/AST.h b/libsolidity/AST.h index 25c18f4f7..4167537e5 100644 --- a/libsolidity/AST.h +++ b/libsolidity/AST.h @@ -333,9 +333,6 @@ public: virtual TypePointer getType(ContractDefinition const*) const override; - /// @returns the value that the string has in the Enum - unsigned int getMemberValue(ASTString const& _member) const; - /// Checks that the members do not include any duplicate names void checkValidityOfMembers() const; diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index 00c2dafd1..63324fe58 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -492,8 +492,7 @@ void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess) case Type::Category::Enum: { EnumType const& type = dynamic_cast(*_memberAccess.getExpression().getType()); - EnumDefinition const& enumDef = type.getEnumDefinition(); - m_context << enumDef.getMemberValue(_memberAccess.getMemberName()); + m_context << type.getMemberValue(_memberAccess.getMemberName()); break; } case Type::Category::TypeType: @@ -516,8 +515,7 @@ void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess) } else if ((enumType = dynamic_cast(type.getActualType().get()))) { - EnumDefinition const &enumDef = enumType->getEnumDefinition(); - m_context << enumDef.getMemberValue(_memberAccess.getMemberName()); + m_context << enumType->getMemberValue(_memberAccess.getMemberName()); return; } diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index 06c0af320..c4a808f89 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -687,6 +687,18 @@ bool EnumType::isExplicitlyConvertibleTo(Type const& _convertTo) const return _convertTo.getCategory() == getCategory() || _convertTo.getCategory() == Category::Integer; } +unsigned int EnumType::getMemberValue(ASTString const& _member) const +{ + unsigned int index = 0; + for (ASTPointer const& decl: m_enum.getMembers()) + { + if (decl->getName() == _member) + return index; + ++index; + } + BOOST_THROW_EXCEPTION(m_enum.createTypeError("Requested unknown enum value ." + _member)); +} + FunctionType::FunctionType(FunctionDefinition const& _function, bool _isInternal): m_location(_isInternal ? Location::Internal : Location::External), m_isConstant(_function.isDeclaredConst()), diff --git a/libsolidity/Types.h b/libsolidity/Types.h index d8b1b6b7a..3b4eee57f 100644 --- a/libsolidity/Types.h +++ b/libsolidity/Types.h @@ -384,6 +384,8 @@ public: virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override; EnumDefinition const& getEnumDefinition() const { return m_enum; } + /// @returns the value that the string has in the Enum + unsigned int getMemberValue(ASTString const& _member) const; private: EnumDefinition const& m_enum; From 64bba8e3ccd0e2b256afec928d912b7045995cdd Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Fri, 13 Feb 2015 23:14:58 +0100 Subject: [PATCH 175/213] Explicit conversion from int to Enum --- libsolidity/Types.cpp | 4 +++- test/SolidityNameAndTypeResolution.cpp | 17 +++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index c4a808f89..c29873b15 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -156,7 +156,9 @@ bool IntegerType::isExplicitlyConvertibleTo(Type const& _convertTo) const StaticStringType const& convertTo = dynamic_cast(_convertTo); return isHash() && (m_bits == convertTo.getNumBytes() * 8); } - return _convertTo.getCategory() == getCategory() || _convertTo.getCategory() == Category::Contract; + return _convertTo.getCategory() == getCategory() || + _convertTo.getCategory() == Category::Contract || + _convertTo.getCategory() == Category::Enum; } TypePointer IntegerType::unaryOperatorResult(Token::Value _operator) const diff --git a/test/SolidityNameAndTypeResolution.cpp b/test/SolidityNameAndTypeResolution.cpp index c912939fc..f3edfc313 100644 --- a/test/SolidityNameAndTypeResolution.cpp +++ b/test/SolidityNameAndTypeResolution.cpp @@ -1039,6 +1039,23 @@ BOOST_AUTO_TEST_CASE(enum_explicit_conversion_is_okay) BOOST_CHECK_NO_THROW(parseTextAndResolveNamesWithChecks(text)); } +BOOST_AUTO_TEST_CASE(int_to_enum_explicit_conversion_is_okay) +{ + char const* text = R"( + contract test { + enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }; + function test() + { + a = 2; + b = ActionChoices(a); + } + uint256 a; + ActionChoices b; + } + )"; + BOOST_CHECK_NO_THROW(parseTextAndResolveNamesWithChecks(text)); +} + BOOST_AUTO_TEST_CASE(enum_implicit_conversion_is_not_okay) { char const* text = R"( From 2370068db6ba572bf88d558f22441c101827da54 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Fri, 13 Feb 2015 23:26:03 +0100 Subject: [PATCH 176/213] Small improvement in TypeType::getMembers() --- libsolidity/Types.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index c29873b15..5d753645c 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -966,9 +966,9 @@ MemberList const& TypeType::getMembers() const else if (m_actualType->getCategory() == Category::Enum) { EnumDefinition const& enumDef = dynamic_cast(*m_actualType).getEnumDefinition(); + auto enumType = make_shared(enumDef); for (ASTPointer const& enumValue: enumDef.getMembers()) - members.insert(make_pair(enumValue->getName(), make_shared(enumDef))); - m_members.reset(new MemberList(members)); + members.insert(make_pair(enumValue->getName(), enumType)); } m_members.reset(new MemberList(members)); } From c3c52d59b2d15ca4dad1a307e3d999b7e192a1fa Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Fri, 13 Feb 2015 23:47:55 +0100 Subject: [PATCH 177/213] Removing ';' from the end of EnumDefinition --- libsolidity/Parser.cpp | 1 - libsolidity/grammar.txt | 2 +- test/SolidityEndToEndTest.cpp | 2 +- test/SolidityNameAndTypeResolution.cpp | 12 ++++++------ test/SolidityParser.cpp | 6 +++--- 5 files changed, 11 insertions(+), 12 deletions(-) diff --git a/libsolidity/Parser.cpp b/libsolidity/Parser.cpp index 4277ef54f..c96593f64 100644 --- a/libsolidity/Parser.cpp +++ b/libsolidity/Parser.cpp @@ -293,7 +293,6 @@ ASTPointer Parser::parseEnumDefinition() nodeFactory.markEndPosition(); expectToken(Token::RBrace); - expectToken(Token::Semicolon); return nodeFactory.createNode(name, members); } diff --git a/libsolidity/grammar.txt b/libsolidity/grammar.txt index 5ba0ef238..5e6e65f85 100644 --- a/libsolidity/grammar.txt +++ b/libsolidity/grammar.txt @@ -13,7 +13,7 @@ FunctionDefinition = 'function' Identifier ParameterList ( 'returns' ParameterList )? Block EnumValue = Identifier -EnumDefinition = 'enum' '{' EnumValue (',' EnumValue)* '}' ';' +EnumDefinition = 'enum' '{' EnumValue (',' EnumValue)* '}' ParameterList = '(' ( VariableDeclaration (',' VariableDeclaration)* )? ')' // semantic restriction: mappings and structs (recursively) containing mappings // are not allowed in argument lists diff --git a/test/SolidityEndToEndTest.cpp b/test/SolidityEndToEndTest.cpp index 551607df2..2ef2b8038 100644 --- a/test/SolidityEndToEndTest.cpp +++ b/test/SolidityEndToEndTest.cpp @@ -2503,7 +2503,7 @@ BOOST_AUTO_TEST_CASE(using_enums) { char const* sourceCode = R"( contract test { - enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }; + enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } function test() { choices = ActionChoices.GoStraight; diff --git a/test/SolidityNameAndTypeResolution.cpp b/test/SolidityNameAndTypeResolution.cpp index f3edfc313..ec49a42d1 100644 --- a/test/SolidityNameAndTypeResolution.cpp +++ b/test/SolidityNameAndTypeResolution.cpp @@ -996,7 +996,7 @@ BOOST_AUTO_TEST_CASE(enum_member_access) { char const* text = R"( contract test { - enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }; + enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } function test() { choices = ActionChoices.GoStraight; @@ -1011,7 +1011,7 @@ BOOST_AUTO_TEST_CASE(enum_invalid_member_access) { char const* text = R"( contract test { - enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }; + enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } function test() { choices = ActionChoices.RunAroundWavingYourHands; @@ -1026,7 +1026,7 @@ BOOST_AUTO_TEST_CASE(enum_explicit_conversion_is_okay) { char const* text = R"( contract test { - enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }; + enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } function test() { a = uint256(ActionChoices.GoStraight); @@ -1043,7 +1043,7 @@ BOOST_AUTO_TEST_CASE(int_to_enum_explicit_conversion_is_okay) { char const* text = R"( contract test { - enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }; + enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } function test() { a = 2; @@ -1060,7 +1060,7 @@ BOOST_AUTO_TEST_CASE(enum_implicit_conversion_is_not_okay) { char const* text = R"( contract test { - enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }; + enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } function test() { a = ActionChoices.GoStraight; @@ -1077,7 +1077,7 @@ BOOST_AUTO_TEST_CASE(enum_duplicate_values) { char const* text = R"( contract test { - enum ActionChoices { GoLeft, GoRight, GoLeft, Sit }; + enum ActionChoices { GoLeft, GoRight, GoLeft, Sit } } )"; BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); diff --git a/test/SolidityParser.cpp b/test/SolidityParser.cpp index 702d1d6db..af82f612a 100644 --- a/test/SolidityParser.cpp +++ b/test/SolidityParser.cpp @@ -707,7 +707,7 @@ BOOST_AUTO_TEST_CASE(enum_valid_declaration) { char const* text = R"( contract c { - enum validEnum { Value1, Value2, Value3, Value4 }; + enum validEnum { Value1, Value2, Value3, Value4 } function c () { a = foo.Value3; @@ -721,7 +721,7 @@ BOOST_AUTO_TEST_CASE(empty_enum_declaration) { char const* text = R"( contract c { - enum foo { }; + enum foo { } })"; BOOST_CHECK_NO_THROW(parseTextExplainError(text)); } @@ -730,7 +730,7 @@ BOOST_AUTO_TEST_CASE(malformed_enum_declaration) { char const* text = R"( contract c { - enum foo { WARNING,}; + enum foo { WARNING,} })"; BOOST_CHECK_THROW(parseText(text), ParserError); } From 4b0a566e708ba2f4d10d8b565d8514840822b5a3 Mon Sep 17 00:00:00 2001 From: Christian Date: Sat, 14 Feb 2015 03:06:50 +0100 Subject: [PATCH 178/213] Some changes to enums. --- libsolidity/AST.cpp | 13 ------------- libsolidity/AST.h | 4 ---- libsolidity/ExpressionCompiler.cpp | 13 ++++--------- libsolidity/NameAndTypeResolver.cpp | 8 ++++++-- libsolidity/NameAndTypeResolver.h | 1 + test/SolidityNameAndTypeResolution.cpp | 2 +- 6 files changed, 12 insertions(+), 29 deletions(-) diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp index 683452027..0dbad433f 100644 --- a/libsolidity/AST.cpp +++ b/libsolidity/AST.cpp @@ -262,19 +262,6 @@ void StructDefinition::checkRecursion() const } } -void EnumDefinition::checkValidityOfMembers() const -{ - vector> members(getMembers()); - auto compareDecls = [](ASTPointer a, ASTPointer b) - { - return a->getName() < b->getName(); - }; - sort(begin(members), end(members), compareDecls); - for (size_t i = 0; i < members.size() - 1; ++i) - if (members[i]->getName() == members[i + 1]->getName()) - BOOST_THROW_EXCEPTION(members[i]->createTypeError("Duplicate member detected in Enum")); -} - TypePointer EnumDefinition::getType(ContractDefinition const*) const { return make_shared(make_shared(*this)); diff --git a/libsolidity/AST.h b/libsolidity/AST.h index 4167537e5..51d8031a3 100644 --- a/libsolidity/AST.h +++ b/libsolidity/AST.h @@ -333,11 +333,7 @@ public: virtual TypePointer getType(ContractDefinition const*) const override; - /// Checks that the members do not include any duplicate names - void checkValidityOfMembers() const; - private: - std::vector> m_members; }; diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index 63324fe58..29ec3d577 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -498,12 +498,10 @@ void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess) case Type::Category::TypeType: { TypeType const& type = dynamic_cast(*_memberAccess.getExpression().getType()); - ContractType const* contractType; - EnumType const* enumType; if (!type.getMembers().getMemberType(member)) - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Invalid member access to " + type.toString())); + BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Invalid member access to " + type.toString())); - if ((contractType = dynamic_cast(type.getActualType().get()))) + if (auto contractType = dynamic_cast(type.getActualType().get())) { ContractDefinition const& contract = contractType->getContractDefinition(); for (ASTPointer const& function: contract.getDefinedFunctions()) @@ -513,12 +511,9 @@ void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess) return; } } - else if ((enumType = dynamic_cast(type.getActualType().get()))) - { + else if (auto enumType = dynamic_cast(type.getActualType().get())) m_context << enumType->getMemberValue(_memberAccess.getMemberName()); - return; - } - + break; } case Type::Category::ByteArray: { diff --git a/libsolidity/NameAndTypeResolver.cpp b/libsolidity/NameAndTypeResolver.cpp index 859d0097c..dbe5693a8 100644 --- a/libsolidity/NameAndTypeResolver.cpp +++ b/libsolidity/NameAndTypeResolver.cpp @@ -81,8 +81,6 @@ void NameAndTypeResolver::checkTypeRequirements(ContractDefinition& _contract) { for (ASTPointer const& structDef: _contract.getDefinedStructs()) structDef->checkValidityOfMembers(); - for (ASTPointer const& enumDef: _contract.getDefinedEnums()) - enumDef->checkValidityOfMembers(); _contract.checkTypeRequirements(); } @@ -236,6 +234,12 @@ void DeclarationRegistrationHelper::endVisit(EnumDefinition&) closeCurrentScope(); } +bool DeclarationRegistrationHelper::visit(EnumValue& _value) +{ + registerDeclaration(_value, false); + return true; +} + bool DeclarationRegistrationHelper::visit(FunctionDefinition& _function) { registerDeclaration(_function, true); diff --git a/libsolidity/NameAndTypeResolver.h b/libsolidity/NameAndTypeResolver.h index 4b1b8c0cd..d9ac98ce5 100644 --- a/libsolidity/NameAndTypeResolver.h +++ b/libsolidity/NameAndTypeResolver.h @@ -100,6 +100,7 @@ private: void endVisit(StructDefinition& _struct) override; bool visit(EnumDefinition& _enum) override; void endVisit(EnumDefinition& _enum) override; + bool visit(EnumValue& _value) override; bool visit(FunctionDefinition& _function) override; void endVisit(FunctionDefinition& _function) override; bool visit(ModifierDefinition& _modifier) override; diff --git a/test/SolidityNameAndTypeResolution.cpp b/test/SolidityNameAndTypeResolution.cpp index ec49a42d1..d6e4ed516 100644 --- a/test/SolidityNameAndTypeResolution.cpp +++ b/test/SolidityNameAndTypeResolution.cpp @@ -1080,7 +1080,7 @@ BOOST_AUTO_TEST_CASE(enum_duplicate_values) enum ActionChoices { GoLeft, GoRight, GoLeft, Sit } } )"; - BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); + BOOST_CHECK_THROW(parseTextAndResolveNames(text), DeclarationError); } BOOST_AUTO_TEST_SUITE_END() From ab9258d0a8c5651f2cbb3ad4571fff46a0018849 Mon Sep 17 00:00:00 2001 From: Christian Date: Sat, 14 Feb 2015 03:22:49 +0100 Subject: [PATCH 179/213] Forced cleanup for conversion to enum. --- libsolidity/ExpressionCompiler.cpp | 8 +++++++- test/SolidityEndToEndTest.cpp | 15 +++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index 29ec3d577..0f0e94f21 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -759,8 +759,11 @@ void ExpressionCompiler::appendTypeConversion(Type const& _typeOnStack, Type con } } } + else if (stackTypeCategory == Type::Category::Enum) + solAssert(targetTypeCategory == Type::Category::Integer || + targetTypeCategory == Type::Category::Enum, ""); else if (stackTypeCategory == Type::Category::Integer || stackTypeCategory == Type::Category::Contract || - stackTypeCategory == Type::Category::IntegerConstant || stackTypeCategory == Type::Category::Enum) + stackTypeCategory == Type::Category::IntegerConstant) { if (targetTypeCategory == Type::Category::String && stackTypeCategory == Type::Category::Integer) { @@ -772,6 +775,9 @@ void ExpressionCompiler::appendTypeConversion(Type const& _typeOnStack, Type con solAssert(typeOnStack.getNumBits() == targetStringType.getNumBytes() * 8, "The size should be the same."); m_context << (u256(1) << (256 - typeOnStack.getNumBits())) << eth::Instruction::MUL; } + else if (targetTypeCategory == Type::Category::Enum) + // just clean + appendTypeConversion(_typeOnStack, *_typeOnStack.getRealType(), true); else { solAssert(targetTypeCategory == Type::Category::Integer || targetTypeCategory == Type::Category::Contract, ""); diff --git a/test/SolidityEndToEndTest.cpp b/test/SolidityEndToEndTest.cpp index 2ef2b8038..0325c4c6a 100644 --- a/test/SolidityEndToEndTest.cpp +++ b/test/SolidityEndToEndTest.cpp @@ -2519,6 +2519,21 @@ BOOST_AUTO_TEST_CASE(using_enums) BOOST_CHECK(callContractFunction("getChoice()") == encodeArgs(2)); } +BOOST_AUTO_TEST_CASE(constructing_enums_from_ints) +{ + char const* sourceCode = R"( + contract c { + enum Truth { False, True } + function test() returns (uint) + { + return uint(Truth(uint8(0x701))); + } + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("test()") == encodeArgs(1)); +} + BOOST_AUTO_TEST_SUITE_END() } From 1df4cacc4065436bb111c1e17513222cd3fc0851 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Sat, 14 Feb 2015 19:48:19 +0100 Subject: [PATCH 180/213] removed libqwebthree --- CMakeLists.txt | 1 - alethzero/CMakeLists.txt | 4 +- alethzero/MainWin.cpp | 21 +++---- alethzero/MainWin.h | 8 ++- libjsqrc/setup.js | 4 +- libqwebthree/CMakeLists.txt | 41 -------------- libqwebthree/QWebThree.cpp | 107 ------------------------------------ libqwebthree/QWebThree.h | 89 ------------------------------ third/CMakeLists.txt | 5 +- third/MainWin.cpp | 20 ++++--- third/MainWin.h | 8 ++- 11 files changed, 41 insertions(+), 267 deletions(-) delete mode 100644 libqwebthree/CMakeLists.txt delete mode 100644 libqwebthree/QWebThree.cpp delete mode 100644 libqwebthree/QWebThree.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 682ba5a14..0cd7a80c4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -181,7 +181,6 @@ if (NOT HEADLESS) add_subdirectory(libnatspec) add_subdirectory(libjsqrc) - add_subdirectory(libqwebthree) add_subdirectory(alethzero) add_subdirectory(third) add_subdirectory(mix) diff --git a/alethzero/CMakeLists.txt b/alethzero/CMakeLists.txt index c18a76c36..b4fc1a938 100644 --- a/alethzero/CMakeLists.txt +++ b/alethzero/CMakeLists.txt @@ -34,8 +34,10 @@ eth_add_executable(${EXECUTABLE} add_dependencies(${EXECUTABLE} BuildInfo.h) target_link_libraries(${EXECUTABLE} Qt5::Core) +target_link_libraries(${EXECUTABLE} Qt5::Widgets) +target_link_libraries(${EXECUTABLE} Qt5::WebKit) +target_link_libraries(${EXECUTABLE} Qt5::WebKitWidgets) target_link_libraries(${EXECUTABLE} webthree) -target_link_libraries(${EXECUTABLE} qwebthree) target_link_libraries(${EXECUTABLE} ethereum) target_link_libraries(${EXECUTABLE} evm) target_link_libraries(${EXECUTABLE} ethcore) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 397b2330c..865cfec3e 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -50,6 +50,7 @@ #include #include #include +#include #include "MainWin.h" #include "DownloadView.h" #include "MiningView.h" @@ -167,25 +168,26 @@ Main::Main(QWidget *parent) : bytesConstRef network((byte*)m_networkConfig.data(), m_networkConfig.size()); m_webThree.reset(new WebThreeDirect(string("AlethZero/v") + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM), getDataDir() + "/AlethZero", false, {"eth", "shh"}, p2p::NetworkPreferences(), network)); - m_qwebConnector.reset(new QWebThreeConnector()); - m_server.reset(new OurWebThreeStubServer(*m_qwebConnector, *web3(), keysAsVector(m_myKeys), this)); + m_httpConnector.reset(new jsonrpc::HttpServer(8080)); + m_server.reset(new OurWebThreeStubServer(*m_httpConnector, *web3(), keysAsVector(m_myKeys), this)); connect(&*m_server, SIGNAL(onNewId(QString)), SLOT(addNewId(QString))); m_server->setIdentities(keysAsVector(owned())); m_server->StartListening(); connect(ui->webView, &QWebView::loadStarted, [this]() { - // NOTE: no need to delete as QETH_INSTALL_JS_NAMESPACE adopts it. - m_qweb = new QWebThree(this); - auto qweb = m_qweb; - m_qwebConnector->setQWeb(qweb); - QWebSettings::globalSettings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true); QWebFrame* f = ui->webView->page()->mainFrame(); f->disconnect(SIGNAL(javaScriptWindowObjectCleared())); - connect(f, &QWebFrame::javaScriptWindowObjectCleared, QETH_INSTALL_JS_NAMESPACE(f, this, qweb)); - connect(m_qweb, SIGNAL(onNewId(QString)), this, SLOT(addNewId(QString))); + connect(f, &QWebFrame::javaScriptWindowObjectCleared, [f, this]() + { + f->disconnect(); + f->addToJavaScriptWindowObject("env", this, QWebFrame::QtOwnership); + f->evaluateJavaScript(contentsOfQResource(":/js/bignumber.min.js")); + f->evaluateJavaScript(contentsOfQResource(":/js/webthree.js")); + f->evaluateJavaScript(contentsOfQResource(":/js/setup.js")); + }); }); connect(ui->webView, &QWebView::loadFinished, [=]() @@ -216,7 +218,6 @@ Main::~Main() writeSettings(); // Must do this here since otherwise m_ethereum'll be deleted (and therefore clearWatches() called by the destructor) // *after* the client is dead. - m_qweb->clientDieing(); g_logPost = simpleDebugOut; } diff --git a/alethzero/MainWin.h b/alethzero/MainWin.h index 2625f566d..94dcaabe5 100644 --- a/alethzero/MainWin.h +++ b/alethzero/MainWin.h @@ -34,7 +34,6 @@ #include #include #include -#include #include #include @@ -49,6 +48,10 @@ class Client; class State; }} +namespace jsonrpc { +class HttpServer; +} + class QQuickView; class OurWebThreeStubServer; @@ -278,9 +281,8 @@ private: QString m_logHistory; bool m_logChanged = true; - std::unique_ptr m_qwebConnector; + std::unique_ptr m_httpConnector; std::unique_ptr m_server; - QWebThree* m_qweb = nullptr; static QString fromRaw(dev::h256 _n, unsigned* _inc = nullptr); NatspecHandler m_natspecDB; diff --git a/libjsqrc/setup.js b/libjsqrc/setup.js index 2aa54ed30..fa1921877 100644 --- a/libjsqrc/setup.js +++ b/libjsqrc/setup.js @@ -20,8 +20,6 @@ * @date 2014 */ -navigator.qt = _web3; - var web3 = require('web3'); -web3.setProvider(new web3.providers.QtSyncProvider()); +web3.setProvider(new web3.providers.HttpSyncProvider()); diff --git a/libqwebthree/CMakeLists.txt b/libqwebthree/CMakeLists.txt deleted file mode 100644 index 4de131ead..000000000 --- a/libqwebthree/CMakeLists.txt +++ /dev/null @@ -1,41 +0,0 @@ -cmake_policy(SET CMP0015 NEW) -# let cmake autolink dependencies on windows -cmake_policy(SET CMP0020 NEW) -# this policy was introduced in cmake 3.0 -# remove if, once 3.0 will be used on unix -if (${CMAKE_MAJOR_VERSION} GREATER 2) - # old policy do not use MACOSX_RPATH - cmake_policy(SET CMP0042 OLD) - cmake_policy(SET CMP0043 OLD) -endif() - -set(CMAKE_INCLUDE_CURRENT_DIR ON) -aux_source_directory(. SRC_LIST) - -include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) -include_directories(..) - -set(EXECUTABLE qwebthree) - -file(GLOB HEADERS "*.h") - -if(ETH_STATIC) - add_library(${EXECUTABLE} STATIC ${RESOURCE_ADDED} ${SRC_LIST} ${HEADERS}) -else() - add_library(${EXECUTABLE} SHARED ${RESOURCE_ADDED} ${SRC_LIST} ${HEADERS}) -endif() - -target_link_libraries(${EXECUTABLE} Qt5::Core) -target_link_libraries(${EXECUTABLE} Qt5::Gui) -target_link_libraries(${EXECUTABLE} Qt5::WebKit) -target_link_libraries(${EXECUTABLE} Qt5::WebKitWidgets) -target_link_libraries(${EXECUTABLE} Qt5::Widgets) -target_link_libraries(${EXECUTABLE} Qt5::Network) -target_link_libraries(${EXECUTABLE} Qt5::Quick) -target_link_libraries(${EXECUTABLE} Qt5::Qml) -target_link_libraries(${EXECUTABLE} ${JSON_RPC_CPP_SERVER_LIBRARIES}) -target_link_libraries(${EXECUTABLE} ethereum) -target_link_libraries(${EXECUTABLE} secp256k1) - -install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) -install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) diff --git a/libqwebthree/QWebThree.cpp b/libqwebthree/QWebThree.cpp deleted file mode 100644 index 31f2f6b92..000000000 --- a/libqwebthree/QWebThree.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* - 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 QWebThree.cpp - * @authors: - * Gav Wood - * Marek Kotewicz - * @date 2014 - */ - -#include -#include "QWebThree.h" - -using namespace std; - -QWebThree::QWebThree(QObject* _p): QObject(_p) -{ - moveToThread(_p->thread()); -} - -QWebThree::~QWebThree() -{ - clientDieing(); -} - -void QWebThree::clientDieing() -{ - this->disconnect(); -} - -QString QWebThree::callMethod(QString _json) -{ - emit processData(_json, ""); // it's synchronous - return m_response; -} - -void QWebThree::onDataProcessed(QString _json, QString) -{ - QJsonObject f = QJsonDocument::fromJson(_json.toUtf8()).object(); - syncResponse(QString::fromUtf8(QJsonDocument(f).toJson())); -} - -void QWebThree::syncResponse(QString _json) -{ - m_response = _json; -} - -QWebThreeConnector::QWebThreeConnector() -{ -} - -QWebThreeConnector::~QWebThreeConnector() -{ - StopListening(); -} - -void QWebThreeConnector::setQWeb(QWebThree* _q) -{ - m_qweb = _q; - if (m_isListening) - { - StopListening(); - StartListening(); - } -} - -bool QWebThreeConnector::StartListening() -{ - m_isListening = true; - if (m_qweb) - { - connect(m_qweb, SIGNAL(processData(QString, QString)), this, SLOT(onProcessData(QString, QString))); - connect(this, SIGNAL(dataProcessed(QString, QString)), m_qweb, SLOT(onDataProcessed(QString, QString))); - } - return true; -} - -bool QWebThreeConnector::StopListening() -{ - this->disconnect(); - return true; -} - -bool QWebThreeConnector::SendResponse(std::string const& _response, void* _addInfo) -{ - emit dataProcessed(QString::fromStdString(_response), *(QString*)_addInfo); - return true; -} - -void QWebThreeConnector::onProcessData(QString const& _json, QString const& _addInfo) -{ - OnRequest(_json.toStdString(), (void*)&_addInfo); -} - diff --git a/libqwebthree/QWebThree.h b/libqwebthree/QWebThree.h deleted file mode 100644 index 72c434649..000000000 --- a/libqwebthree/QWebThree.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - 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 QWebThree.h - * @authors: - * Gav Wood - * Marek Kotewicz - * @date 2014 - */ - -#pragma once - -#include -#include -#include - -class QWebThree: public QObject -{ - Q_OBJECT - -public: - QWebThree(QObject* _p); - virtual ~QWebThree(); - void clientDieing(); - - Q_INVOKABLE QString callMethod(QString _json); - void syncResponse(QString _json); - -public slots: - void onDataProcessed(QString _json, QString _addInfo); - -signals: - void processData(QString _json, QString _addInfo); - void response(QString _json); - void onNewId(QString _id); - -private: - QString m_response; -}; - -class QWebThreeConnector: public QObject, public jsonrpc::AbstractServerConnector -{ - Q_OBJECT - -public: - QWebThreeConnector(); - virtual ~QWebThreeConnector(); - - void setQWeb(QWebThree *_q); - - virtual bool StartListening(); - virtual bool StopListening(); - virtual bool SendResponse(std::string const& _response, void* _addInfo = NULL); - -public slots: - void onProcessData(QString const& _json, QString const& _addInfo); - -signals: - void dataProcessed(QString const& _json, QString const& _addInfo); - -private: - QWebThree* m_qweb = nullptr; - bool m_isListening; -}; - -#define QETH_INSTALL_JS_NAMESPACE(_frame, _env, qweb) [_frame, _env, qweb]() \ -{ \ - _frame->disconnect(); \ - _frame->addToJavaScriptWindowObject("_web3", qweb, QWebFrame::ScriptOwnership); \ - _frame->addToJavaScriptWindowObject("env", _env, QWebFrame::QtOwnership); \ - _frame->evaluateJavaScript(contentsOfQResource(":/js/bignumber.min.js")); \ - _frame->evaluateJavaScript(contentsOfQResource(":/js/webthree.js")); \ - _frame->evaluateJavaScript(contentsOfQResource(":/js/setup.js")); \ -} - - diff --git a/third/CMakeLists.txt b/third/CMakeLists.txt index 71f1e70f2..3f4981e29 100644 --- a/third/CMakeLists.txt +++ b/third/CMakeLists.txt @@ -32,8 +32,11 @@ eth_add_executable(${EXECUTABLE} add_dependencies(${EXECUTABLE} BuildInfo.h) target_link_libraries(${EXECUTABLE} Qt5::Core) +target_link_libraries(${EXECUTABLE} Qt5::Widgets) +target_link_libraries(${EXECUTABLE} Qt5::WebKit) +target_link_libraries(${EXECUTABLE} Qt5::WebKitWidgets) +target_link_libraries(${EXECUTABLE} webthree) target_link_libraries(${EXECUTABLE} webthree) -target_link_libraries(${EXECUTABLE} qwebthree) target_link_libraries(${EXECUTABLE} ethereum) target_link_libraries(${EXECUTABLE} evm) target_link_libraries(${EXECUTABLE} ethcore) diff --git a/third/MainWin.cpp b/third/MainWin.cpp index f1b7bc826..5fb5074bc 100644 --- a/third/MainWin.cpp +++ b/third/MainWin.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include "BuildInfo.h" #include "MainWin.h" #include "ui_Main.h" @@ -118,20 +119,24 @@ Main::Main(QWidget *parent) : m_web3.reset(new WebThreeDirect("Third", getDataDir() + "/Third", false, {"eth", "shh"}, NetworkPreferences(), networkConfig)); m_web3->connect(Host::pocHost()); - m_server = unique_ptr(new WebThreeStubServer(m_qwebConnector, *web3(), keysAsVector(m_myKeys))); + m_httpConnector.reset(new jsonrpc::HttpServer(8080)); + m_server.reset(new WebThreeStubServer(*m_httpConnector, *web3(), keysAsVector(m_myKeys))); +// m_server = unique_ptr(new WebThreeStubServer(m_httpConnector, *web3(), keysAsVector(m_myKeys))); m_server->setIdentities(keysAsVector(owned())); m_server->StartListening(); connect(ui->webView, &QWebView::loadStarted, [this]() { - // NOTE: no need to delete as QETH_INSTALL_JS_NAMESPACE adopts it. - m_qweb = new QWebThree(this); - auto qweb = m_qweb; - m_qwebConnector.setQWeb(qweb); - QWebFrame* f = ui->webView->page()->mainFrame(); f->disconnect(SIGNAL(javaScriptWindowObjectCleared())); - connect(f, &QWebFrame::javaScriptWindowObjectCleared, QETH_INSTALL_JS_NAMESPACE(f, this, qweb)); + connect(f, &QWebFrame::javaScriptWindowObjectCleared, [f, this]() + { + f->disconnect(); + f->addToJavaScriptWindowObject("env", this, QWebFrame::QtOwnership); + f->evaluateJavaScript(contentsOfQResource(":/js/bignumber.min.js")); + f->evaluateJavaScript(contentsOfQResource(":/js/webthree.js")); + f->evaluateJavaScript(contentsOfQResource(":/js/setup.js")); + }); }); connect(ui->webView, &QWebView::loadFinished, [=]() @@ -163,7 +168,6 @@ Main::~Main() { // Must do this here since otherwise m_ethereum'll be deleted (and therefore clearWatches() called by the destructor) // *after* the client is dead. - m_qweb->clientDieing(); writeSettings(); } diff --git a/third/MainWin.h b/third/MainWin.h index 924fc057e..513cfe96e 100644 --- a/third/MainWin.h +++ b/third/MainWin.h @@ -30,7 +30,6 @@ #include #include #include -#include namespace Ui { class Main; @@ -47,6 +46,10 @@ class WhisperHost; } } +namespace jsonrpc { +class HttpServer; +} + class QQuickView; class WebThreeStubServer; @@ -136,7 +139,6 @@ private: QNetworkAccessManager m_webCtrl; + std::unique_ptr m_httpConnector; std::unique_ptr m_server; - QWebThreeConnector m_qwebConnector; - QWebThree* m_qweb = nullptr; }; From b9e4bbbc14c4a2cc683cfb6880d9027a83a97525 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 15 Feb 2015 00:13:31 +0100 Subject: [PATCH 181/213] Compile warning fix. --- evmjit/libevmjit/Arith256.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evmjit/libevmjit/Arith256.cpp b/evmjit/libevmjit/Arith256.cpp index 15d18c814..99ca63ea6 100644 --- a/evmjit/libevmjit/Arith256.cpp +++ b/evmjit/libevmjit/Arith256.cpp @@ -416,7 +416,7 @@ namespace explicit operator uint128() { uint128 r = lo; - r = r + ((uint128) mid) << 64; + r = (r + ((uint128) mid)) << 64; return r; } From 809df5cdc593ec7613c766d67455df276c2f1bdc Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 15 Feb 2015 01:00:09 +0100 Subject: [PATCH 182/213] Working, albeit slowly, non-NatSpec transaction confirmations. --- alethzero/MainWin.cpp | 14 ++++- alethzero/MainWin.h | 14 +++-- alethzero/OurWebThreeStubServer.cpp | 70 +++++++++++++++-------- alethzero/OurWebThreeStubServer.h | 4 +- libethcore/CommonJS.h | 1 + libsolidity/CompilerStack.cpp | 5 ++ libsolidity/CompilerStack.h | 1 + libweb3jsonrpc/WebThreeStubServerBase.cpp | 2 + 8 files changed, 80 insertions(+), 31 deletions(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 865cfec3e..ec58fd559 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -1733,7 +1733,7 @@ void Main::on_data_textChanged() // compiler.addSources(dev::solidity::StandardSources); m_data = compiler.compile(src, m_enableOptimizer); solidity = "

Solidity

"; - solidity += "
var " + QString::fromStdString(compiler.getContractNames().front()) + " = web3.eth.contractFromAbi(" + QString::fromStdString(compiler.getInterface()).replace(QRegExp("\\s"), "").toHtmlEscaped() + ");
"; + solidity += "
var " + QString::fromStdString(compiler.defaultContractName()) + " = web3.eth.contractFromAbi(" + QString::fromStdString(compiler.getInterface()).replace(QRegExp("\\s"), "").toHtmlEscaped() + ");
"; solidity += "
" + QString::fromStdString(compiler.getSolidityInterface()).toHtmlEscaped() + "
"; solidity += "
" + QString::fromStdString(getFunctionHashes(compiler)).toHtmlEscaped() + "
"; } @@ -2442,6 +2442,18 @@ string Main::lookupNatSpecUserNotice(dev::h256 const& _contractHash, dev::bytes return m_natspecDB.getUserNotice(_contractHash, _transactionData); } +int Main::authenticate(QString _title, QString _text) +{ + QMessageBox userInput(this); + userInput.setText(_title); + userInput.setInformativeText(_text); + userInput.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); + userInput.button(QMessageBox::Ok)->setText("Allow"); + userInput.button(QMessageBox::Cancel)->setText("Reject"); + userInput.setDefaultButton(QMessageBox::Cancel); + return userInput.exec(); +} + void Main::refreshWhispers() { ui->whispers->clear(); diff --git a/alethzero/MainWin.h b/alethzero/MainWin.h index 5298a28a2..fa451b63f 100644 --- a/alethzero/MainWin.h +++ b/alethzero/MainWin.h @@ -79,6 +79,12 @@ public: QVariant evalRaw(QString const& _js); + QString pretty(dev::Address _a) const override; + QString prettyU256(dev::u256 _n) const override; + QString render(dev::Address _a) const override; + dev::Address fromString(QString const& _a) const override; + std::string renderDiff(dev::eth::StateDiff const& _d) const override; + public slots: void load(QString _file); void note(QString _entry); @@ -86,6 +92,8 @@ public slots: void warn(QString _entry); QString contents(QString _file); + int authenticate(QString _title, QString _text); + void onKeysChanged(); private slots: @@ -175,12 +183,6 @@ private: void updateDebugger(); void debugFinished(); - QString pretty(dev::Address _a) const override; - QString prettyU256(dev::u256 _n) const override; - QString render(dev::Address _a) const override; - dev::Address fromString(QString const& _a) const override; - std::string renderDiff(dev::eth::StateDiff const& _d) const override; - void alterDebugStateGroup(bool _enable) const; void updateFee(); diff --git a/alethzero/OurWebThreeStubServer.cpp b/alethzero/OurWebThreeStubServer.cpp index 02d7236df..89d616756 100644 --- a/alethzero/OurWebThreeStubServer.cpp +++ b/alethzero/OurWebThreeStubServer.cpp @@ -46,48 +46,72 @@ string OurWebThreeStubServer::shh_newIdentity() bool OurWebThreeStubServer::showAuthenticationPopup(string const& _title, string const& _text) const { - QMessageBox userInput; - userInput.setText(QString::fromStdString(_title)); - userInput.setInformativeText(QString::fromStdString(_text + "\n Do you wish to allow this?")); - userInput.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); - userInput.button(QMessageBox::Ok)->setText("Allow"); - userInput.button(QMessageBox::Cancel)->setText("Reject"); - userInput.setDefaultButton(QMessageBox::Cancel); - return userInput.exec() == QMessageBox::Ok; + int button; + QMetaObject::invokeMethod(m_main, "authenticate", Qt::BlockingQueuedConnection, Q_RETURN_ARG(int, button), Q_ARG(QString, QString::fromStdString(_title)), Q_ARG(QString, QString::fromStdString(_text))); + return button == QMessageBox::Ok; } -void OurWebThreeStubServer::showBasicValueTransferNotice(u256 _value) const +bool OurWebThreeStubServer::showCreationNotice(TransactionSkeleton const& _t) const { - QMessageBox notice; - notice.setText("Basic Value Transfer Transaction"); - notice.setInformativeText(QString::fromStdString("Value is " + toString(_value))); - notice.setStandardButtons(QMessageBox::Ok); - notice.exec(); + return showAuthenticationPopup("Contract Creation Transaction", "ÐApp is attemping to create a contract; to be endowed with " + formatBalance(_t.value) + ", with additional network fees of up to " + formatBalance(_t.gas * _t.gasPrice) + ".\n\nMaximum total cost is " + formatBalance(_t.value + _t.gas * _t.gasPrice) + "."); +} + +bool OurWebThreeStubServer::showSendNotice(TransactionSkeleton const& _t) const +{ + return showAuthenticationPopup("Fund Transfer Transaction", "ÐApp is attempting to send " + formatBalance(_t.value) + " to a recipient " + m_main->pretty(_t.to).toStdString() + ", with additional network fees of up to " + formatBalance(_t.gas * _t.gasPrice) + ".\n\nMaximum total cost is " + formatBalance(_t.value + _t.gas * _t.gasPrice) + "."); +} + +bool OurWebThreeStubServer::showUnknownCallNotice(TransactionSkeleton const& _t) const +{ + return showAuthenticationPopup("DANGEROUS! Unknown Contract Transaction!", + "ÐApp is attempting to call into an unknown contract at address " + + m_main->pretty(_t.to).toStdString() + + ".\n\nCall involves sending " + + formatBalance(_t.value) + " to the recipient, with additional network fees of up to " + + formatBalance(_t.gas * _t.gasPrice) + + "However, this also does other stuff which we don't understand, and does so in your name.\n\n" + + "WARNING: This is probably going to cost you at least " + + formatBalance(_t.value + _t.gas * _t.gasPrice) + + ", however this doesn't include any side-effects, which could be of far greater importance.\n\n" + + "REJECT UNLESS YOU REALLY KNOW WHAT YOU ARE DOING!"); } bool OurWebThreeStubServer::authenticate(TransactionSkeleton const& _t) { + if (_t.creation) + { + // recipient has no code - nothing special about this transaction, show basic value transfer info + return showCreationNotice(_t); + } + h256 contractCodeHash = m_web3->ethereum()->postState().codeHash(_t.to); if (contractCodeHash == EmptySHA3) - // contract creation - return true; - - if (false) //TODO: When is is just a value transfer? { // recipient has no code - nothing special about this transaction, show basic value transfer info - showBasicValueTransferNotice(_t.value); - return true; + return showSendNotice(_t); } + // TODO: include total cost in Ether string userNotice = m_main->lookupNatSpecUserNotice(contractCodeHash, _t.data); if (userNotice.empty()) - return showAuthenticationPopup("Unverified Pending Transaction", - "An undocumented transaction is about to be executed."); + return showUnknownCallNotice(_t); NatspecExpressionEvaluator evaluator; userNotice = evaluator.evalExpression(QString::fromStdString(userNotice)).toStdString(); // otherwise it's a transaction to a contract for which we have the natspec - return showAuthenticationPopup("Pending Transaction", userNotice); + return showAuthenticationPopup("Contract Transaction", + "ÐApp attempting to conduct contract interaction with " + + m_main->pretty(_t.to).toStdString() + + ": " + userNotice + ".\n\n" + + (_t.value > 0 ? + "In addition, ÐApp is attempting to send " + + formatBalance(_t.value) + " to said recipient, with additional network fees of up to " + + formatBalance(_t.gas * _t.gasPrice) + " = " + + formatBalance(_t.value + _t.gas * _t.gasPrice) + "." + : + "Additional network fees are at most" + + formatBalance(_t.gas * _t.gasPrice) + ".") + ); } diff --git a/alethzero/OurWebThreeStubServer.h b/alethzero/OurWebThreeStubServer.h index 303b73111..fbdae7d03 100644 --- a/alethzero/OurWebThreeStubServer.h +++ b/alethzero/OurWebThreeStubServer.h @@ -42,7 +42,9 @@ signals: private: bool showAuthenticationPopup(std::string const& _title, std::string const& _text) const; - void showBasicValueTransferNotice(dev::u256 _value) const; + bool showCreationNotice(dev::eth::TransactionSkeleton const& _t) const; + bool showSendNotice(dev::eth::TransactionSkeleton const& _t) const; + bool showUnknownCallNotice(dev::eth::TransactionSkeleton const& _t) const; dev::WebThreeDirect* m_web3; Main* m_main; diff --git a/libethcore/CommonJS.h b/libethcore/CommonJS.h index 2f82d8945..abe74f0af 100644 --- a/libethcore/CommonJS.h +++ b/libethcore/CommonJS.h @@ -144,6 +144,7 @@ inline Address jsToAddress(std::string const& _s) { return jsToFixedgetName(); +} + CompilerStack::Contract const& CompilerStack::getContract(string const& _contractName) const { if (m_contracts.empty()) diff --git a/libsolidity/CompilerStack.h b/libsolidity/CompilerStack.h index 439077f36..cb4770cd3 100644 --- a/libsolidity/CompilerStack.h +++ b/libsolidity/CompilerStack.h @@ -73,6 +73,7 @@ public: void parse(std::string const& _sourceCode); /// Returns a list of the contract names in the sources. std::vector getContractNames() const; + std::string defaultContractName() const; /// Compiles the source units that were previously added and parsed. void compile(bool _optimize = false); diff --git a/libweb3jsonrpc/WebThreeStubServerBase.cpp b/libweb3jsonrpc/WebThreeStubServerBase.cpp index 49094a423..27b8268da 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.cpp +++ b/libweb3jsonrpc/WebThreeStubServerBase.cpp @@ -279,6 +279,8 @@ static TransactionSkeleton toTransaction(Json::Value const& _json) ret.from = jsToAddress(_json["from"].asString()); if (_json["to"].isString()) ret.to = jsToAddress(_json["to"].asString()); + else + ret.creation = true; if (!_json["value"].empty()) { if (_json["value"].isString()) From 0066771e3bdbc9c6594191b05228174f35dca13f Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 15 Feb 2015 01:22:26 +0100 Subject: [PATCH 183/213] Use external debugger. --- alethzero/Debugger.cpp | 30 ++++++++--------- alethzero/Debugger.h | 19 ++++++----- alethzero/Debugger.ui | 76 ++++++++++++++++++++++++++++++------------ alethzero/MainWin.cpp | 11 ++++-- 4 files changed, 87 insertions(+), 49 deletions(-) diff --git a/alethzero/Debugger.cpp b/alethzero/Debugger.cpp index 690c281f9..442868a94 100644 --- a/alethzero/Debugger.cpp +++ b/alethzero/Debugger.cpp @@ -266,28 +266,28 @@ void Debugger::on_debugTimeline_valueChanged() update(); } -void Debugger::on_stepOver_triggered() +void Debugger::on_stepOver_clicked() { if (ui->debugTimeline->value() < m_session.history.size()) { auto l = m_session.history[ui->debugTimeline->value()].levels.size(); if ((ui->debugTimeline->value() + 1) < m_session.history.size() && m_session.history[ui->debugTimeline->value() + 1].levels.size() > l) { - on_stepInto_triggered(); + on_stepInto_clicked(); if (m_session.history[ui->debugTimeline->value()].levels.size() > l) - on_stepOut_triggered(); + on_stepOut_clicked(); } else - on_stepInto_triggered(); + on_stepInto_clicked(); } } -void Debugger::on_stepInto_triggered() +void Debugger::on_stepInto_clicked() { ui->debugTimeline->setValue(ui->debugTimeline->value() + 1); ui->callStack->setCurrentRow(0); } -void Debugger::on_stepOut_triggered() +void Debugger::on_stepOut_clicked() { if (ui->debugTimeline->value() < m_session.history.size()) { @@ -299,26 +299,26 @@ void Debugger::on_stepOut_triggered() } } -void Debugger::on_backInto_triggered() +void Debugger::on_backInto_clicked() { ui->debugTimeline->setValue(ui->debugTimeline->value() - 1); ui->callStack->setCurrentRow(0); } -void Debugger::on_backOver_triggered() +void Debugger::on_backOver_clicked() { auto l = m_session.history[ui->debugTimeline->value()].levels.size(); if (ui->debugTimeline->value() > 0 && m_session.history[ui->debugTimeline->value() - 1].levels.size() > l) { - on_backInto_triggered(); + on_backInto_clicked(); if (m_session.history[ui->debugTimeline->value()].levels.size() > l) - on_backOut_triggered(); + on_backOut_clicked(); } else - on_backInto_triggered(); + on_backInto_clicked(); } -void Debugger::on_backOut_triggered() +void Debugger::on_backOut_clicked() { if (ui->debugTimeline->value() > 0 && m_session.history.size() > 0) { @@ -330,7 +330,7 @@ void Debugger::on_backOut_triggered() } } -void Debugger::on_dump_triggered() +void Debugger::on_dump_clicked() { QString fn = QFileDialog::getSaveFileName(this, "Select file to output EVM trace"); ofstream f(fn.toStdString()); @@ -339,7 +339,7 @@ void Debugger::on_dump_triggered() f << ws.cur << " " << hex << toHex(dev::toCompactBigEndian(ws.curPC, 1)) << " " << hex << toHex(dev::toCompactBigEndian((int)(byte)ws.inst, 1)) << " " << hex << toHex(dev::toCompactBigEndian((uint64_t)ws.gas, 1)) << endl; } -void Debugger::on_dumpPretty_triggered() +void Debugger::on_dumpPretty_clicked() { QString fn = QFileDialog::getSaveFileName(this, "Select file to output EVM trace"); ofstream f(fn.toStdString()); @@ -357,7 +357,7 @@ void Debugger::on_dumpPretty_triggered() } } -void Debugger::on_dumpStorage_triggered() +void Debugger::on_dumpStorage_clicked() { QString fn = QFileDialog::getSaveFileName(this, "Select file to output EVM trace"); ofstream f(fn.toStdString()); diff --git a/alethzero/Debugger.h b/alethzero/Debugger.h index dc4f4cbc3..1b08e8f92 100644 --- a/alethzero/Debugger.h +++ b/alethzero/Debugger.h @@ -78,15 +78,16 @@ public: protected slots: void on_callStack_currentItemChanged(); void on_debugTimeline_valueChanged(); - void on_stepOver_triggered(); - void on_stepInto_triggered(); - void on_stepOut_triggered(); - void on_backOver_triggered(); - void on_backInto_triggered(); - void on_backOut_triggered(); - void on_dump_triggered(); - void on_dumpPretty_triggered(); - void on_dumpStorage_triggered(); + void on_stepOver_clicked(); + void on_stepInto_clicked(); + void on_stepOut_clicked(); + void on_backOver_clicked(); + void on_backInto_clicked(); + void on_backOut_clicked(); + void on_dump_clicked(); + void on_dumpPretty_clicked(); + void on_dumpStorage_clicked(); + void on_close_clicked() { close(); } private: void init(); diff --git a/alethzero/Debugger.ui b/alethzero/Debugger.ui index 4795e0c5c..59b706fab 100644 --- a/alethzero/Debugger.ui +++ b/alethzero/Debugger.ui @@ -6,7 +6,7 @@ 0 0 - 946 + 989 690 @@ -65,27 +65,6 @@ - - - - Dump - - - - - - - Dump Pretty - - - - - - - Dump Storage - - - @@ -231,6 +210,59 @@ + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Dump + + + + + + + Dump Storage + + + + + + + Dump Pretty + + + + + + + Qt::Horizontal + + + + 577 + 20 + + + + + + + + Close + + + + + + diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index ec58fd559..6c9c4a069 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -1999,14 +1999,19 @@ void Main::on_debug_clicked() if (ethereum()->balanceAt(i.address()) >= totalReq) { Secret s = i.secret(); - m_executiveState = ethereum()->postState(); - m_currentExecution = unique_ptr(new Executive(m_executiveState, ethereum()->blockChain(), 0)); Transaction t = isCreation() ? Transaction(value(), gasPrice(), ui->gas->value(), m_data, m_executiveState.transactionsFrom(dev::toAddress(s)), s) : Transaction(value(), gasPrice(), ui->gas->value(), fromString(ui->destination->currentText()), m_data, m_executiveState.transactionsFrom(dev::toAddress(s)), s); auto r = t.rlp(); + Debugger dw(this, this); + Executive e(m_executiveState, ethereum()->blockChain(), 0); + dw.populate(e, &r); + dw.exec(); + + /*m_executiveState = ethereum()->postState(); + m_currentExecution = unique_ptr(new Executive(m_executiveState, ethereum()->blockChain(), 0)); populateDebugger(&r); - m_currentExecution.reset(); + m_currentExecution.reset();*/ return; } statusBar()->showMessage("Couldn't make transaction: no single account contains at least the required amount."); From 513fc897d82a6b9c851920699f20a3bd4a2bd49e Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 15 Feb 2015 13:05:49 +0100 Subject: [PATCH 184/213] External Debugger for debugging past transactions, too. --- alethzero/Debugger.cpp | 16 ++++++++++++---- alethzero/Debugger.h | 4 ++-- alethzero/MainWin.cpp | 22 +++++++--------------- libethereum/BlockChain.h | 4 ++++ libethereum/Executive.cpp | 6 ++++++ libethereum/Executive.h | 5 +++++ 6 files changed, 36 insertions(+), 21 deletions(-) diff --git a/alethzero/Debugger.cpp b/alethzero/Debugger.cpp index 442868a94..93d6b1f6a 100644 --- a/alethzero/Debugger.cpp +++ b/alethzero/Debugger.cpp @@ -56,18 +56,26 @@ void Debugger::init() } } -void Debugger::populate(dev::eth::Executive& _executive, dev::bytesConstRef _transactionRLP) +void Debugger::populate(dev::eth::Executive& _executive, dev::eth::Transaction const& _transaction) { finished(); - if (m_session.populate(_executive, _transactionRLP)) + if (m_session.populate(_executive, _transaction)) init(); update(); } -bool DebugSession::populate(dev::eth::Executive& _executive, dev::bytesConstRef _transactionRLP) +bool DebugSession::populate(dev::eth::Executive& _executive, dev::eth::Transaction const& _transaction) { - if (_executive.setup(_transactionRLP)) + try { + if (_executive.setup(_transaction)) + return false; + } + catch (...) + { + // Invalid transaction return false; + } + vector levels; bytes lastExtCode; bytesConstRef lastData; diff --git a/alethzero/Debugger.h b/alethzero/Debugger.h index 1b08e8f92..370ad6e30 100644 --- a/alethzero/Debugger.h +++ b/alethzero/Debugger.h @@ -53,7 +53,7 @@ struct DebugSession { DebugSession() {} - bool populate(dev::eth::Executive& _executive, dev::bytesConstRef _transactionRLP); + bool populate(dev::eth::Executive& _executive, dev::eth::Transaction const& _transaction); dev::h256 currentCode; dev::h256 currentData; @@ -73,7 +73,7 @@ public: explicit Debugger(Context* _context, QWidget* _parent = 0); ~Debugger(); - void populate(dev::eth::Executive& _executive, dev::bytesConstRef _transactionRLP); + void populate(dev::eth::Executive& _executive, dev::eth::Transaction const& _transaction); protected slots: void on_callStack_currentItemChanged(); diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 6c9c4a069..62bc5e069 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -1478,13 +1478,12 @@ void Main::on_debugCurrent_triggered() if (!item->data(Qt::UserRole + 1).isNull()) { unsigned txi = item->data(Qt::UserRole + 1).toInt(); - m_executiveState = ethereum()->state(txi + 1, h); - m_currentExecution = unique_ptr(new Executive(m_executiveState, ethereum()->blockChain(), 0)); - Transaction t = m_executiveState.pending()[txi]; - m_executiveState = m_executiveState.fromPending(txi); - auto r = t.rlp(); - populateDebugger(&r); - m_currentExecution.reset(); + bytes t = ethereum()->blockChain().transaction(h, txi); + State s(ethereum()->state(txi, h)); + Executive e(s, ethereum()->blockChain(), 0); + Debugger dw(this, this); + dw.populate(e, Transaction(t, CheckSignature::Sender)); + dw.exec(); } } } @@ -1991,7 +1990,6 @@ void Main::keysChanged() void Main::on_debug_clicked() { - debugFinished(); try { u256 totalReq = value() + fee(); @@ -2002,16 +2000,10 @@ void Main::on_debug_clicked() Transaction t = isCreation() ? Transaction(value(), gasPrice(), ui->gas->value(), m_data, m_executiveState.transactionsFrom(dev::toAddress(s)), s) : Transaction(value(), gasPrice(), ui->gas->value(), fromString(ui->destination->currentText()), m_data, m_executiveState.transactionsFrom(dev::toAddress(s)), s); - auto r = t.rlp(); Debugger dw(this, this); Executive e(m_executiveState, ethereum()->blockChain(), 0); - dw.populate(e, &r); + dw.populate(e, t); dw.exec(); - - /*m_executiveState = ethereum()->postState(); - m_currentExecution = unique_ptr(new Executive(m_executiveState, ethereum()->blockChain(), 0)); - populateDebugger(&r); - m_currentExecution.reset();*/ return; } statusBar()->showMessage("Couldn't make transaction: no single account contains at least the required amount."); diff --git a/libethereum/BlockChain.h b/libethereum/BlockChain.h index 50ad78dac..0c5587d2a 100644 --- a/libethereum/BlockChain.h +++ b/libethereum/BlockChain.h @@ -112,6 +112,10 @@ public: bytes block(h256 _hash) const; bytes block() const { return block(currentHash()); } + /// Get a block's transaction (RLP format) for the given block hash (or the most recent mined if none given) & index. Thread-safe. + bytes transaction(h256 _hash, unsigned _i) const { bytes b = block(_hash); return RLP(b)[1][_i].data().toBytes(); } + bytes transaction(unsigned _i) const { return transaction(currentHash(), _i); } + /// Get a number for the given hash (or the most recent mined if none given). Thread-safe. unsigned number(h256 _hash) const { return details(_hash).number; } unsigned number() const { return number(currentHash()); } diff --git a/libethereum/Executive.cpp b/libethereum/Executive.cpp index cea7d21f4..f407a6f0b 100644 --- a/libethereum/Executive.cpp +++ b/libethereum/Executive.cpp @@ -54,6 +54,12 @@ bool Executive::setup(bytesConstRef _rlp) { // Entry point for a user-executed transaction. m_t = Transaction(_rlp, CheckSignature::Sender); + return setup(); +} + +bool Executive::setup() +{ + // Entry point for a user-executed transaction. // Avoid invalid transactions. auto nonceReq = m_s.transactionsFrom(m_t.sender()); diff --git a/libethereum/Executive.h b/libethereum/Executive.h index d743e3746..bb5563604 100644 --- a/libethereum/Executive.h +++ b/libethereum/Executive.h @@ -62,6 +62,9 @@ public: /// Set up the executive for evaluating a transaction. You must call finalize() following this. /// @returns true iff go() must be called (and thus a VM execution in required). bool setup(bytesConstRef _transaction); + /// Set up the executive for evaluating a transaction. You must call finalize() following this. + /// @returns true iff go() must be called (and thus a VM execution in required). + bool setup(Transaction const& _transaction) { m_t = _transaction; return setup(); } /// Finalise a transaction previously set up with setup(). /// @warning Only valid after setup(), and possibly go(). void finalize(); @@ -101,6 +104,8 @@ public: bool excepted() const { return m_excepted; } private: + bool setup(); + State& m_s; ///< The state to which this operation/transaction is applied. LastHashes m_lastHashes; std::shared_ptr m_ext; ///< The VM externality object for the VM execution or null if no VM is required. From 45776a0877d94acabe689249e68a51d56df7cb77 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 15 Feb 2015 13:50:52 +0100 Subject: [PATCH 185/213] Removed debug panel. Is this a record, perhaps? --- alethzero/Main.ui | 242 ++++------------------------- alethzero/MainWin.cpp | 346 +----------------------------------------- alethzero/MainWin.h | 119 +++++++-------- 3 files changed, 92 insertions(+), 615 deletions(-) diff --git a/alethzero/Main.ui b/alethzero/Main.ui index 328b4acba..fe475bae9 100644 --- a/alethzero/Main.ui +++ b/alethzero/Main.ui @@ -117,7 +117,7 @@ 0 0 1617 - 25 + 24 @@ -140,11 +140,11 @@ - T&ools + &Tools - + @@ -160,11 +160,8 @@ - Deb&ug + &Special - - - @@ -185,42 +182,28 @@ - - - D&ebugger - - - - &Dump Trace - - - - - - - - - - - - - - - &Whisper + + + &Debug + + + + + - - + + @@ -987,171 +970,6 @@ - - - false - - - QDockWidget::DockWidgetFeatureMask - - - Debugger - - - 1 - - - - false - - - - 6 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Qt::Horizontal - - - - - 1 - 0 - - - - Qt::Vertical - - - - - 0 - 0 - - - - QFrame::NoFrame - - - 0 - - - - - - Ubuntu Mono - - - - QFrame::NoFrame - - - 0 - - - - - - - 1 - 0 - - - - Qt::Vertical - - - - QFrame::NoFrame - - - 0 - - - true - - - Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - - - QFrame::NoFrame - - - 0 - - - true - - - Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - - - QFrame::NoFrame - - - 0 - - - true - - - Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - - - QFrame::NoFrame - - - true - - - - - - - - - - 0 - 0 - - - - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Qt::Horizontal - - - - - - QDockWidget::DockWidgetFeatureMask @@ -1776,7 +1594,7 @@ font-size: 14pt
true - Use &UPnP + &Use UPnP @@ -1800,7 +1618,7 @@ font-size: 14pt
&Mine - + &New Address @@ -1834,7 +1652,7 @@ font-size: 14pt
true - Mining &Paranoia + &Mining Paranoia @@ -1862,7 +1680,7 @@ font-size: 14pt
true - Show Ancient &Blocks + &Show Ancient Blocks @@ -1870,7 +1688,7 @@ font-size: 14pt
true - Show Anonymous &Accounts + Show &Anonymous Accounts @@ -1970,7 +1788,7 @@ font-size: 14pt
false - Debu&g Current Transaction + &Debug Current Transaction @@ -1978,7 +1796,7 @@ font-size: 14pt
false - D&ump Current Transaction State (post) + Dump &Current Transaction State (post) @@ -1986,7 +1804,7 @@ font-size: 14pt
false - D&ump Current Transaction State (pre) + Dump Current &Transaction State (pre) @@ -2007,7 +1825,7 @@ font-size: 14pt
true - &Use Private Chain... + Use &Private Chain... @@ -2015,7 +1833,7 @@ font-size: 14pt
true - &Enable LLL &Optimizer + &Enable LLL Optimizer @@ -2023,7 +1841,7 @@ font-size: 14pt
true - Reserved Debug 1 + &Reserved Debug 1 @@ -2031,7 +1849,7 @@ font-size: 14pt
true - Enable Local Addresses + &Enable Local Addresses @@ -2044,7 +1862,7 @@ font-size: 14pt
- Go! + &Go! @@ -2054,7 +1872,7 @@ font-size: 14pt
- Clear Pe&nd&ing + &Clear Pending @@ -2112,10 +1930,6 @@ font-size: 14pt
urlEdit webView nameReg - debugCode - debugStack - debugMemory - debugStorage diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 62bc5e069..f794f6758 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -1514,49 +1514,6 @@ void Main::on_debugDumpStatePre_triggered() on_debugDumpState_triggered(0); } -void Main::populateDebugger(dev::bytesConstRef _r) -{ - bool done = m_currentExecution->setup(_r); - if (!done) - { - debugFinished(); - vector levels; - m_codes.clear(); - bytes lastExtCode; - bytesConstRef lastData; - h256 lastHash; - h256 lastDataHash; - auto onOp = [&](uint64_t steps, Instruction inst, dev::bigint newMemSize, dev::bigint gasCost, VM* voidVM, ExtVMFace const* voidExt) - { - VM& vm = *voidVM; - ExtVM const& ext = *static_cast(voidExt); - if (ext.code != lastExtCode) - { - lastExtCode = ext.code; - lastHash = sha3(lastExtCode); - if (!m_codes.count(lastHash)) - m_codes[lastHash] = ext.code; - } - if (ext.data != lastData) - { - lastData = ext.data; - lastDataHash = sha3(lastData); - if (!m_codes.count(lastDataHash)) - m_codes[lastDataHash] = ext.data.toBytes(); - } - if (levels.size() < ext.depth) - levels.push_back(&m_history.back()); - else - levels.resize(ext.depth); - m_history.append(WorldState({steps, ext.myAddress, vm.curPC(), inst, newMemSize, vm.gas(), lastHash, lastDataHash, vm.stack(), vm.memory(), gasCost, ext.state().storage(ext.myAddress), levels})); - }; - m_currentExecution->go(onOp); - m_currentExecution->finalize(); - initDebugger(); - updateDebugger(); - } -} - void Main::on_contracts_currentItemChanged() { ui->contractInfo->clear(); @@ -1713,7 +1670,6 @@ string const Main::getFunctionHashes(dev::solidity::CompilerStack const &_compil void Main::on_data_textChanged() { - m_pcWarp.clear(); if (isCreation()) { string src = ui->data->toPlainText().toStdString(); @@ -1950,7 +1906,6 @@ void Main::on_send_clicked() for (auto i: m_myKeys) if (ethereum()->balanceAt(i.address(), 0) >= totalReq) { - debugFinished(); Secret s = i.secret(); if (isCreation()) { @@ -1966,8 +1921,7 @@ void Main::on_send_clicked() for (string& s: compiler.getContractNames()) { h256 contractHash = compiler.getContractCodeHash(s); - m_natspecDB.add(contractHash, - compiler.getMetadata(s, dev::solidity::DocumentationType::NatspecUser)); + m_natspecDB.add(contractHash, compiler.getMetadata(s, dev::solidity::DocumentationType::NatspecUser)); } } catch (...) @@ -1996,12 +1950,13 @@ void Main::on_debug_clicked() for (auto i: m_myKeys) if (ethereum()->balanceAt(i.address()) >= totalReq) { + State st(ethereum()->postState()); Secret s = i.secret(); Transaction t = isCreation() ? - Transaction(value(), gasPrice(), ui->gas->value(), m_data, m_executiveState.transactionsFrom(dev::toAddress(s)), s) : - Transaction(value(), gasPrice(), ui->gas->value(), fromString(ui->destination->currentText()), m_data, m_executiveState.transactionsFrom(dev::toAddress(s)), s); + Transaction(value(), gasPrice(), ui->gas->value(), m_data, st.transactionsFrom(dev::toAddress(s)), s) : + Transaction(value(), gasPrice(), ui->gas->value(), fromString(ui->destination->currentText()), m_data, st.transactionsFrom(dev::toAddress(s)), s); Debugger dw(this, this); - Executive e(m_executiveState, ethereum()->blockChain(), 0); + Executive e(st, ethereum()->blockChain(), 0); dw.populate(e, t); dw.exec(); return; @@ -2023,7 +1978,7 @@ bool beginsWith(Address _a, bytes const& _b) return true; } -void Main::on_create_triggered() +void Main::on_newAccount_triggered() { bool ok = true; enum { NoVanity = 0, FirstTwo, FirstTwoNextTwo, FirstThree, FirstFour, StringMatch }; @@ -2091,111 +2046,6 @@ void Main::on_killAccount_triggered() } } -void Main::on_debugStep_triggered() -{ - if (ui->debugTimeline->value() < m_history.size()) { - auto l = m_history[ui->debugTimeline->value()].levels.size(); - if ((ui->debugTimeline->value() + 1) < m_history.size() && m_history[ui->debugTimeline->value() + 1].levels.size() > l) - { - on_debugStepInto_triggered(); - if (m_history[ui->debugTimeline->value()].levels.size() > l) - on_debugStepOut_triggered(); - } - else - on_debugStepInto_triggered(); - } -} - -void Main::on_debugStepInto_triggered() -{ - ui->debugTimeline->setValue(ui->debugTimeline->value() + 1); - ui->callStack->setCurrentRow(0); -} - -void Main::on_debugStepOut_triggered() -{ - if (ui->debugTimeline->value() < m_history.size()) - { - auto ls = m_history[ui->debugTimeline->value()].levels.size(); - auto l = ui->debugTimeline->value(); - for (; l < m_history.size() && m_history[l].levels.size() >= ls; ++l) {} - ui->debugTimeline->setValue(l); - ui->callStack->setCurrentRow(0); - } -} - -void Main::on_debugStepBackInto_triggered() -{ - ui->debugTimeline->setValue(ui->debugTimeline->value() - 1); - ui->callStack->setCurrentRow(0); -} - -void Main::on_debugStepBack_triggered() -{ - auto l = m_history[ui->debugTimeline->value()].levels.size(); - if (ui->debugTimeline->value() > 0 && m_history[ui->debugTimeline->value() - 1].levels.size() > l) - { - on_debugStepBackInto_triggered(); - if (m_history[ui->debugTimeline->value()].levels.size() > l) - on_debugStepBackOut_triggered(); - } - else - on_debugStepBackInto_triggered(); -} - -void Main::on_debugStepBackOut_triggered() -{ - if (ui->debugTimeline->value() > 0 && m_history.size() > 0) - { - auto ls = m_history[min(ui->debugTimeline->value(), m_history.size() - 1)].levels.size(); - int l = ui->debugTimeline->value(); - for (; l > 0 && m_history[l].levels.size() >= ls; --l) {} - ui->debugTimeline->setValue(l); - ui->callStack->setCurrentRow(0); - } -} - -void Main::on_dumpTrace_triggered() -{ - QString fn = QFileDialog::getSaveFileName(this, "Select file to output EVM trace"); - ofstream f(fn.toStdString()); - if (f.is_open()) - for (WorldState const& ws: m_history) - f << ws.cur << " " << hex << toHex(dev::toCompactBigEndian(ws.curPC, 1)) << " " << hex << toHex(dev::toCompactBigEndian((int)(byte)ws.inst, 1)) << " " << hex << toHex(dev::toCompactBigEndian((uint64_t)ws.gas, 1)) << endl; -} - -void Main::on_dumpTracePretty_triggered() -{ - QString fn = QFileDialog::getSaveFileName(this, "Select file to output EVM trace"); - ofstream f(fn.toStdString()); - if (f.is_open()) - for (WorldState const& ws: m_history) - { - f << endl << " STACK" << endl; - for (auto i: ws.stack) - f << (h256)i << endl; - f << " MEMORY" << endl << dev::memDump(ws.memory); - f << " STORAGE" << endl; - for (auto const& i: ws.storage) - f << showbase << hex << i.first << ": " << i.second << endl; - f << dec << ws.levels.size() << " | " << ws.cur << " | #" << ws.steps << " | " << hex << setw(4) << setfill('0') << ws.curPC << " : " << instructionInfo(ws.inst).name << " | " << dec << ws.gas << " | -" << dec << ws.gasCost << " | " << ws.newMemSize << "x32"; - } -} - -void Main::on_dumpTraceStorage_triggered() -{ - QString fn = QFileDialog::getSaveFileName(this, "Select file to output EVM trace"); - ofstream f(fn.toStdString()); - if (f.is_open()) - for (WorldState const& ws: m_history) - { - if (ws.inst == Instruction::STOP || ws.inst == Instruction::RETURN || ws.inst == Instruction::SUICIDE) - for (auto i: ws.storage) - f << toHex(dev::toCompactBigEndian(i.first, 1)) << " " << toHex(dev::toCompactBigEndian(i.second, 1)) << endl; - f << ws.cur << " " << hex << toHex(dev::toCompactBigEndian(ws.curPC, 1)) << " " << hex << toHex(dev::toCompactBigEndian((int)(byte)ws.inst, 1)) << " " << hex << toHex(dev::toCompactBigEndian((uint64_t)ws.gas, 1)) << endl; - } -} - void Main::on_go_triggered() { if (!ui->net->isChecked()) @@ -2206,60 +2056,6 @@ void Main::on_go_triggered() web3()->connect(Host::pocHost()); } -void Main::on_callStack_currentItemChanged() -{ - updateDebugger(); -} - -void Main::alterDebugStateGroup(bool _enable) const -{ - ui->debugStep->setEnabled(_enable); - ui->debugStepInto->setEnabled(_enable); - ui->debugStepOut->setEnabled(_enable); - ui->debugStepBackInto->setEnabled(_enable); - ui->debugStepBackOut->setEnabled(_enable); - ui->dumpTrace->setEnabled(_enable); - ui->dumpTraceStorage->setEnabled(_enable); - ui->dumpTracePretty->setEnabled(_enable); - ui->debugStepBack->setEnabled(_enable); - ui->debugPanel->setEnabled(_enable); -} - -void Main::debugFinished() -{ - m_codes.clear(); - m_pcWarp.clear(); - m_history.clear(); - m_lastLevels.clear(); - m_lastCode = h256(); - ui->callStack->clear(); - ui->debugCode->clear(); - ui->debugStack->clear(); - ui->debugMemory->setHtml(""); - ui->debugStorage->setHtml(""); - ui->debugStateInfo->setText(""); - alterDebugStateGroup(false); -// ui->send->setEnabled(true); -} - -void Main::initDebugger() -{ -// ui->send->setEnabled(false); - if (m_history.size()) - { - alterDebugStateGroup(true); - ui->debugCode->setEnabled(false); - ui->debugTimeline->setMinimum(0); - ui->debugTimeline->setMaximum(m_history.size()); - ui->debugTimeline->setValue(0); - } -} - -void Main::on_debugTimeline_valueChanged() -{ - updateDebugger(); -} - QString Main::prettyU256(dev::u256 _n) const { unsigned inc = 0; @@ -2287,136 +2083,6 @@ QString Main::prettyU256(dev::u256 _n) const return QString::fromStdString(s.str()); } -void Main::updateDebugger() -{ - if (m_history.size()) - { - WorldState const& nws = m_history[min((int)m_history.size() - 1, ui->debugTimeline->value())]; - WorldState const& ws = ui->callStack->currentRow() > 0 ? *nws.levels[nws.levels.size() - ui->callStack->currentRow()] : nws; - - if (ui->debugTimeline->value() >= m_history.size()) - { - if (ws.gasCost > ws.gas) - ui->debugMemory->setHtml("

OUT-OF-GAS

"); - else if (ws.inst == Instruction::RETURN && ws.stack.size() >= 2) - { - unsigned from = (unsigned)ws.stack.back(); - unsigned size = (unsigned)ws.stack[ws.stack.size() - 2]; - unsigned o = 0; - bytes out(size, 0); - for (; o < size && from + o < ws.memory.size(); ++o) - out[o] = ws.memory[from + o]; - ui->debugMemory->setHtml("

RETURN

" + QString::fromStdString(dev::memDump(out, 16, true))); - } - else if (ws.inst == Instruction::STOP) - ui->debugMemory->setHtml("

STOP

"); - else if (ws.inst == Instruction::SUICIDE && ws.stack.size() >= 1) - ui->debugMemory->setHtml("

SUICIDE

0x" + QString::fromStdString(toString(right160(ws.stack.back())))); - else - ui->debugMemory->setHtml("

EXCEPTION

"); - - ostringstream ss; - ss << dec << "EXIT | GAS: " << dec << max(0, (dev::bigint)ws.gas - ws.gasCost); - ui->debugStateInfo->setText(QString::fromStdString(ss.str())); - ui->debugStorage->setHtml(""); - ui->debugCallData->setHtml(""); - m_lastData = h256(); - ui->callStack->clear(); - m_lastLevels.clear(); - ui->debugCode->clear(); - m_lastCode = h256(); - ui->debugStack->setHtml(""); - } - else - { - if (m_lastLevels != nws.levels || !ui->callStack->count()) - { - m_lastLevels = nws.levels; - ui->callStack->clear(); - for (unsigned i = 0; i <= nws.levels.size(); ++i) - { - WorldState const& s = i ? *nws.levels[nws.levels.size() - i] : nws; - ostringstream out; - out << s.cur.abridged(); - if (i) - out << " " << instructionInfo(s.inst).name << " @0x" << hex << s.curPC; - ui->callStack->addItem(QString::fromStdString(out.str())); - } - } - - if (ws.code != m_lastCode) - { - bytes const& code = m_codes[ws.code]; - QListWidget* dc = ui->debugCode; - dc->clear(); - m_pcWarp.clear(); - for (unsigned i = 0; i <= code.size(); ++i) - { - byte b = i < code.size() ? code[i] : 0; - try - { - QString s = QString::fromStdString(instructionInfo((Instruction)b).name); - ostringstream out; - out << hex << setw(4) << setfill('0') << i; - m_pcWarp[i] = dc->count(); - if (b >= (byte)Instruction::PUSH1 && b <= (byte)Instruction::PUSH32) - { - unsigned bc = b - (byte)Instruction::PUSH1 + 1; - s = "PUSH 0x" + QString::fromStdString(toHex(bytesConstRef(&code[i + 1], bc))); - i += bc; - } - dc->addItem(QString::fromStdString(out.str()) + " " + s); - } - catch (...) - { - cerr << "Unhandled exception!" << endl << - boost::current_exception_diagnostic_information(); - break; // probably hit data segment - } - } - m_lastCode = ws.code; - } - - if (ws.callData != m_lastData) - { - m_lastData = ws.callData; - if (ws.callData) - { - assert(m_codes.count(ws.callData)); - ui->debugCallData->setHtml(QString::fromStdString(dev::memDump(m_codes[ws.callData], 16, true))); - } - else - ui->debugCallData->setHtml(""); - } - - QString stack; - for (auto i: ws.stack) - stack.prepend("
" + prettyU256(i) + "
"); - ui->debugStack->setHtml(stack); - ui->debugMemory->setHtml(QString::fromStdString(dev::memDump(ws.memory, 16, true))); - assert(m_codes.count(ws.code)); - - if (m_codes[ws.code].size() >= (unsigned)ws.curPC) - { - int l = m_pcWarp[(unsigned)ws.curPC]; - ui->debugCode->setCurrentRow(max(0, l - 5)); - ui->debugCode->setCurrentRow(min(ui->debugCode->count() - 1, l + 5)); - ui->debugCode->setCurrentRow(l); - } - else - cwarn << "PC (" << (unsigned)ws.curPC << ") is after code range (" << m_codes[ws.code].size() << ")"; - - ostringstream ss; - ss << dec << "STEP: " << ws.steps << " | PC: 0x" << hex << ws.curPC << " : " << instructionInfo(ws.inst).name << " | ADDMEM: " << dec << ws.newMemSize << " words | COST: " << dec << ws.gasCost << " | GAS: " << dec << ws.gas; - ui->debugStateInfo->setText(QString::fromStdString(ss.str())); - stringstream s; - for (auto const& i: ws.storage) - s << "@" << prettyU256(i.first).toStdString() << "    " << prettyU256(i.second).toStdString() << "
"; - ui->debugStorage->setHtml(QString::fromStdString(s.str())); - } - } -} - void Main::on_post_clicked() { shh::Message m; diff --git a/alethzero/MainWin.h b/alethzero/MainWin.h index fa451b63f..d503a16dd 100644 --- a/alethzero/MainWin.h +++ b/alethzero/MainWin.h @@ -99,71 +99,85 @@ public slots: private slots: void eval(QString const& _js); - void on_connect_triggered(); - void on_mine_triggered(); - void on_send_clicked(); - void on_create_triggered(); - void on_killAccount_triggered(); + // Application + void on_about_triggered(); + void on_quit_triggered() { close(); } + + // Network + void on_go_triggered(); void on_net_triggered(); - void on_verbosity_valueChanged(); - void on_ourAccounts_doubleClicked(); - void ourAccountsRowsMoved(); - void on_accounts_doubleClicked(); - void on_destination_currentTextChanged(); - void on_data_textChanged(); + void on_connect_triggered(); void on_idealPeers_valueChanged(); + + // Mining + void on_mine_triggered(); + + // View + void on_refresh_triggered(); + void on_showAll_triggered() { refreshBlockChain(); } + void on_showAllAccounts_triggered() { refreshAccounts(); } + void on_preview_triggered(); + + // Transacting void on_value_valueChanged() { updateFee(); } void on_gas_valueChanged() { updateFee(); } void on_valueUnits_currentIndexChanged() { updateFee(); } void on_gasPriceUnits_currentIndexChanged() { updateFee(); } void on_gasPrice_valueChanged() { updateFee(); } - void on_log_doubleClicked(); - void on_blocks_currentItemChanged(); + void on_destination_currentTextChanged(); + void on_data_textChanged(); + void on_send_clicked(); + void on_debug_clicked(); + + // Account management + void on_newAccount_triggered(); + void on_killAccount_triggered(); + void on_importKey_triggered(); + void on_importKeyFile_triggered(); + void on_exportKey_triggered(); + + // Tools + void on_loadJS_triggered(); + + // Stuff concerning the blocks/transactions/accounts panels + void ourAccountsRowsMoved(); + void on_ourAccounts_doubleClicked(); + void on_accounts_doubleClicked(); void on_contracts_doubleClicked(); void on_contracts_currentItemChanged(); void on_transactionQueue_currentItemChanged(); - void on_about_triggered(); - void on_paranoia_triggered(); - void on_nameReg_textChanged(); - void on_preview_triggered(); - void on_quit_triggered() { close(); } + void on_blockChainFilter_textChanged(); + void on_blocks_currentItemChanged(); + + // Logging + void on_log_doubleClicked(); + void on_verbosity_valueChanged(); + + // Misc void on_urlEdit_returnPressed(); - void on_debugStep_triggered(); - void on_debugStepBack_triggered(); - void on_debug_clicked(); - void on_debugTimeline_valueChanged(); void on_jsInput_returnPressed(); + void on_nameReg_textChanged(); + + // Special (debug) stuff + void on_paranoia_triggered(); void on_killBlockchain_triggered(); void on_clearPending_triggered(); - void on_importKey_triggered(); - void on_exportKey_triggered(); void on_inject_triggered(); - void on_showAll_triggered() { refreshBlockChain(); } - void on_showAllAccounts_triggered() { refreshAccounts(); } - void on_loadJS_triggered(); - void on_blockChainFilter_textChanged(); void on_forceMining_triggered(); - void on_dumpTrace_triggered(); - void on_dumpTraceStorage_triggered(); - void on_dumpTracePretty_triggered(); - void on_debugStepInto_triggered(); - void on_debugStepOut_triggered(); - void on_debugStepBackOut_triggered(); - void on_debugStepBackInto_triggered(); - void on_callStack_currentItemChanged(); - void on_debugCurrent_triggered(); - void on_debugDumpState_triggered(int _add = 1); - void on_debugDumpStatePre_triggered(); - void on_refresh_triggered(); void on_usePrivate_triggered(); void on_enableOptimizer_triggered(); void on_turboMining_triggered(); - void on_go_triggered(); - void on_importKeyFile_triggered(); - void on_post_clicked(); - void on_newIdentity_triggered(); void on_jitvm_triggered(); + // Debugger + void on_debugCurrent_triggered(); + void on_debugDumpState_triggered(int _add = 1); + void on_debugDumpStatePre_triggered(); + + // Whisper + void on_newIdentity_triggered(); + void on_post_clicked(); + void refreshWhisper(); void refreshBlockChain(); void addNewId(QString _ids); @@ -178,13 +192,6 @@ private: dev::Address getNameReg() const; dev::Address getCurrencies() const; - void populateDebugger(dev::bytesConstRef r); - void initDebugger(); - void updateDebugger(); - void debugFinished(); - - void alterDebugStateGroup(bool _enable) const; - void updateFee(); void readSettings(bool _skipGeometry = false); void writeSettings(); @@ -249,16 +256,6 @@ private: unsigned m_backupGas; - dev::eth::State m_executiveState; - std::unique_ptr m_currentExecution; - dev::h256 m_lastCode; - dev::h256 m_lastData; - std::vector m_lastLevels; - - QMap m_pcWarp; - QList m_history; - std::map m_codes; // and pcWarps - bool m_enableOptimizer = true; QNetworkAccessManager m_webCtrl; From bfc037f68858b03d02cafc182a3ca45d7ce2c308 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 15 Feb 2015 18:00:49 +0100 Subject: [PATCH 186/213] Transact dialog supports all the NatSpec stuff. --- alethzero/CMakeLists.txt | 3 +- alethzero/Context.cpp | 33 +++ alethzero/Context.h | 27 +++ alethzero/Debugger.ui | 34 ++- alethzero/Main.ui | 286 +++--------------------- alethzero/MainWin.cpp | 320 +-------------------------- alethzero/MainWin.h | 45 +--- alethzero/NatspecHandler.h | 5 +- alethzero/OurWebThreeStubServer.cpp | 2 +- alethzero/Transact.cpp | 325 ++++++++++++++++++++++++++++ alethzero/Transact.h | 82 +++++++ alethzero/Transact.ui | 244 +++++++++++++++++++++ libethcore/CommonEth.cpp | 10 - libethcore/CommonEth.h | 33 ++- 14 files changed, 810 insertions(+), 639 deletions(-) create mode 100644 alethzero/Transact.cpp create mode 100644 alethzero/Transact.h create mode 100644 alethzero/Transact.ui diff --git a/alethzero/CMakeLists.txt b/alethzero/CMakeLists.txt index eba34ca75..9e41260fe 100644 --- a/alethzero/CMakeLists.txt +++ b/alethzero/CMakeLists.txt @@ -16,6 +16,7 @@ include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) qt5_wrap_ui(ui_Main.h Main.ui) qt5_wrap_ui(ui_Debugger.h Debugger.ui) +qt5_wrap_ui(ui_Transact.h Transact.ui) file(GLOB HEADERS "*.h") @@ -28,7 +29,7 @@ endif () # eth_add_executable is defined in cmake/EthExecutableHelper.cmake eth_add_executable(${EXECUTABLE} ICON alethzero - UI_RESOURCES alethzero.icns Main.ui Debugger.ui + UI_RESOURCES alethzero.icns Main.ui Debugger.ui Transact.ui WIN_RESOURCES alethzero.rc ) diff --git a/alethzero/Context.cpp b/alethzero/Context.cpp index 0505a03e0..d187e6d47 100644 --- a/alethzero/Context.cpp +++ b/alethzero/Context.cpp @@ -20,7 +20,40 @@ */ #include "Context.h" +#include +#include +using namespace std; +using namespace dev; +using namespace dev::eth; + +NatSpecFace::~NatSpecFace() +{ +} Context::~Context() { } + +void initUnits(QComboBox* _b) +{ + for (auto n = (unsigned)units().size(); n-- != 0; ) + _b->addItem(QString::fromStdString(units()[n].second), n); +} + +vector keysAsVector(QList const& keys) +{ + auto list = keys.toStdList(); + return {begin(list), end(list)}; +} + +bool sourceIsSolidity(string const& _source) +{ + // TODO: Improve this heuristic + return (_source.substr(0, 8) == "contract" || _source.substr(0, 5) == "//sol"); +} + +bool sourceIsSerpent(string const& _source) +{ + // TODO: Improve this heuristic + return (_source.substr(0, 5) == "//ser"); +} diff --git a/alethzero/Context.h b/alethzero/Context.h index 2a41988a3..a2fb1a130 100644 --- a/alethzero/Context.h +++ b/alethzero/Context.h @@ -22,11 +22,38 @@ #pragma once #include +#include #include +#include #include +class QComboBox; + namespace dev { namespace eth { class StateDiff; } } +#define Small "font-size: small; " +#define Mono "font-family: Ubuntu Mono, Monospace, Lucida Console, Courier New; font-weight: bold; " +#define Div(S) "
" +#define Span(S) "" + +void initUnits(QComboBox* _b); + +std::vector keysAsVector(QList const& _keys); + +bool sourceIsSolidity(std::string const& _source); +bool sourceIsSerpent(std::string const& _source); + +class NatSpecFace +{ +public: + virtual ~NatSpecFace(); + + virtual void add(dev::h256 const& _contractHash, std::string const& _doc) = 0; + virtual std::string retrieve(dev::h256 const& _contractHash) const = 0; + virtual std::string getUserNotice(std::string const& json, const dev::bytes& _transactionData) = 0; + virtual std::string getUserNotice(dev::h256 const& _contractHash, dev::bytes const& _transactionDacta) = 0; +}; + class Context { public: diff --git a/alethzero/Debugger.ui b/alethzero/Debugger.ui index 59b706fab..6751655ae 100644 --- a/alethzero/Debugger.ui +++ b/alethzero/Debugger.ui @@ -17,12 +17,24 @@ - QFrame::StyledPanel + QFrame::NoFrame QFrame::Raised + + 0 + + + 0 + + + 0 + + + 0 + @@ -83,6 +95,12 @@ + + + 0 + 0 + + Qt::Horizontal @@ -213,12 +231,24 @@ - QFrame::StyledPanel + QFrame::NoFrame QFrame::Raised + + 0 + + + 0 + + + 0 + + + 0 + diff --git a/alethzero/Main.ui b/alethzero/Main.ui index fe475bae9..b7c4f6c96 100644 --- a/alethzero/Main.ui +++ b/alethzero/Main.ui @@ -144,6 +144,7 @@ + @@ -168,7 +169,6 @@ - @@ -516,237 +516,11 @@ false + - - - - 0 - 0 - - - - - 510 - 386 - - - - QDockWidget::DockWidgetFeatureMask - - - Transact - - - 1 - - - - - - - - 0 - 0 - - - - &Data - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - data - - - - - - - Qt::Vertical - - - - QFrame::NoFrame - - - 0 - - - - - Qt::ClickFocus - - - QFrame::NoFrame - - - 0 - - - true - - - - - - - - &Gas - - - gas - - - - - - - - 0 - 0 - - - - &To - - - destination - - - - - - - gas - - - 1 - - - 430000000 - - - 10000 - - - - - - - - - - - - - @ - - - 1 - - - 430000000 - - - - - - - false - - - true - - - - - - - - - - - - - 430000000 - - - 0 - - - - - - - &Amount - - - value - - - - - - - - 0 - 0 - - - - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - true - - - - (Create Contract) - - - - - - - - &Execute - - - - - - - - 0 - 0 - - - - - - - - - - - De&bug - - - - - - QDockWidget::DockWidgetFeatureMask @@ -1384,9 +1158,6 @@ font-size: 14pt Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - data - @@ -1439,9 +1210,6 @@ font-size: 14pt TTL - - destination - @@ -1455,9 +1223,6 @@ font-size: 14pt From - - destination - @@ -1471,9 +1236,6 @@ font-size: 14pt To - - destination - @@ -1504,9 +1266,6 @@ font-size: 14pt Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - data - @@ -1533,9 +1292,6 @@ font-size: 14pt Work to Prove - - destination - @@ -1620,7 +1376,7 @@ font-size: 14pt - &New Address + &New Address... @@ -1891,6 +1647,11 @@ font-size: 14pt &Kill Account + + + New &Transaction... + + @@ -1913,23 +1674,30 @@ font-size: 14pt - destination - calculatedName - value - valueUnits - gas - gasPrice - gasPriceUnits - data - send - idealPeers - port - clientName + shhTo + shhFrom + shhTtl + shhTopic + shhWork + shhData + log + post verbosity + jsConsole tabWidget urlEdit webView + idealPeers + forceAddress + port + clientName + transactionQueue + pendingInfo + blockChainFilter nameReg + nodes + whispers + jsInput diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index f794f6758..1d497cc0b 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -56,6 +56,8 @@ #include "MiningView.h" #include "BuildInfo.h" #include "OurWebThreeStubServer.h" +#include "Transact.h" +#include "Debugger.h" #include "ui_Main.h" using namespace std; using namespace dev; @@ -63,17 +65,6 @@ using namespace dev::p2p; using namespace dev::eth; namespace js = json_spirit; -#define Small "font-size: small; " -#define Mono "font-family: Ubuntu Mono, Monospace, Lucida Console, Courier New; font-weight: bold; " -#define Div(S) "
" -#define Span(S) "" - -static void initUnits(QComboBox* _b) -{ - for (auto n = (unsigned)units().size(); n-- != 0; ) - _b->addItem(QString::fromStdString(units()[n].second), n); -} - QString Main::fromRaw(h256 _n, unsigned* _inc) { if (_n) @@ -99,12 +90,6 @@ QString Main::fromRaw(h256 _n, unsigned* _inc) return QString(); } -static vector keysAsVector(QList const& keys) -{ - auto list = keys.toStdList(); - return {begin(list), end(list)}; -} - QString contentsOfQResource(string const& res) { QFile file(QString::fromStdString(res)); @@ -120,7 +105,8 @@ Address c_newConfig = Address("c6d9d2cd449a754c494264e1809c50e34d64562b"); Main::Main(QWidget *parent) : QMainWindow(parent), - ui(new Ui::Main) + ui(new Ui::Main), + m_transact(this, this) { setWindowFlags(Qt::Window); ui->setupUi(this); @@ -149,12 +135,6 @@ Main::Main(QWidget *parent) : ui->configDock->close(); on_verbosity_valueChanged(); - initUnits(ui->gasPriceUnits); - initUnits(ui->valueUnits); - ui->valueUnits->setCurrentIndex(6); - ui->gasPriceUnits->setCurrentIndex(4); - ui->gasPrice->setValue(10); - on_destination_currentTextChanged(); statusBar()->addPermanentWidget(ui->balance); statusBar()->addPermanentWidget(ui->peerCount); @@ -373,12 +353,6 @@ void Main::on_forceMining_triggered() ethereum()->setForceMining(ui->forceMining->isChecked()); } -void Main::on_enableOptimizer_triggered() -{ - m_enableOptimizer = ui->enableOptimizer->isChecked(); - on_data_textChanged(); -} - QString Main::contents(QString _s) { return QString::fromStdString(dev::asString(dev::contents(_s.toStdString()))); @@ -412,6 +386,12 @@ void Main::load(QString _s) }*/ } +void Main::on_newTransaction_triggered() +{ + m_transact.setEnvironment(m_myKeys, ethereum(), &m_natSpecDB); + m_transact.exec(); +} + void Main::on_loadJS_triggered() { QString f = QFileDialog::getOpenFileName(this, "Load Javascript", QString(), "Javascript (*.js);;All files (*)"); @@ -673,7 +653,6 @@ void Main::writeSettings() s.setValue("paranoia", ui->paranoia->isChecked()); s.setValue("showAll", ui->showAll->isChecked()); s.setValue("showAllAccounts", ui->showAllAccounts->isChecked()); - s.setValue("enableOptimizer", m_enableOptimizer); s.setValue("clientName", ui->clientName->text()); s.setValue("idealPeers", ui->idealPeers->value()); s.setValue("port", ui->port->value()); @@ -743,8 +722,6 @@ void Main::readSettings(bool _skipGeometry) ui->paranoia->setChecked(s.value("paranoia", false).toBool()); ui->showAll->setChecked(s.value("showAll", false).toBool()); ui->showAllAccounts->setChecked(s.value("showAllAccounts", false).toBool()); - m_enableOptimizer = s.value("enableOptimizer", true).toBool(); - ui->enableOptimizer->setChecked(m_enableOptimizer); ui->clientName->setText(s.value("clientName", "").toString()); if (ui->clientName->text().isEmpty()) ui->clientName->setText(QInputDialog::getText(nullptr, "Enter identity", "Enter a name that will identify you on the peer network")); @@ -991,7 +968,6 @@ void Main::refreshNetwork() void Main::refreshAll() { - refreshDestination(); refreshBlockChain(); refreshBlockCount(); refreshPending(); @@ -1042,20 +1018,6 @@ void Main::refreshAccounts() } } -void Main::refreshDestination() -{ - cwatch << "refreshDestination()"; - QString s; - for (auto i: ethereum()->addresses()) - if ((s = pretty(i)).size()) - // A namereg address - if (ui->destination->findText(s, Qt::MatchExactly | Qt::MatchCaseSensitive) == -1) - ui->destination->addItem(s); - for (int i = 0; i < ui->destination->count(); ++i) - if (ui->destination->itemText(i) != "(Create Contract)" && !fromString(ui->destination->itemText(i))) - ui->destination->removeItem(i--); -} - void Main::refreshBlockCount() { cwatch << "refreshBlockCount()"; @@ -1573,19 +1535,6 @@ void Main::on_contracts_doubleClicked() qApp->clipboard()->setText(QString::fromStdString(toHex(h.asArray()))); } -void Main::on_destination_currentTextChanged() -{ - if (ui->destination->currentText().size() && ui->destination->currentText() != "(Create Contract)") - if (Address a = fromString(ui->destination->currentText())) - ui->calculatedName->setText(render(a)); - else - ui->calculatedName->setText("Unknown Address"); - else - ui->calculatedName->setText("Create Contract"); - on_data_textChanged(); -// updateFee(); -} - static shh::FullTopic topicFromText(QString _s) { shh::BuildTopic ret; @@ -1640,133 +1589,6 @@ static shh::FullTopic topicFromText(QString _s) return ret; } -bool Main::sourceIsSolidity(string const& _source) -{ - // TODO: Improve this heuristic - return (_source.substr(0, 8) == "contract" || _source.substr(0, 5) == "//sol"); -} - -static bool sourceIsSerpent(string const& _source) -{ - // TODO: Improve this heuristic - return (_source.substr(0, 5) == "//ser"); -} - -string const Main::getFunctionHashes(dev::solidity::CompilerStack const &_compiler, - string const& _contractName) -{ - string ret = ""; - auto const& contract = _compiler.getContractDefinition(_contractName); - auto interfaceFunctions = contract.getInterfaceFunctions(); - - for (auto const& it: interfaceFunctions) - { - ret += it.first.abridged(); - ret += " :"; - ret += it.second->getDeclaration().getName() + "\n"; - } - return ret; -} - -void Main::on_data_textChanged() -{ - if (isCreation()) - { - string src = ui->data->toPlainText().toStdString(); - vector errors; - QString lll; - QString solidity; - if (src.find_first_not_of("1234567890abcdefABCDEF") == string::npos && src.size() % 2 == 0) - { - m_data = fromHex(src); - } - else if (sourceIsSolidity(src)) - { - dev::solidity::CompilerStack compiler; - try - { -// compiler.addSources(dev::solidity::StandardSources); - m_data = compiler.compile(src, m_enableOptimizer); - solidity = "

Solidity

"; - solidity += "
var " + QString::fromStdString(compiler.defaultContractName()) + " = web3.eth.contractFromAbi(" + QString::fromStdString(compiler.getInterface()).replace(QRegExp("\\s"), "").toHtmlEscaped() + ");
"; - solidity += "
" + QString::fromStdString(compiler.getSolidityInterface()).toHtmlEscaped() + "
"; - solidity += "
" + QString::fromStdString(getFunctionHashes(compiler)).toHtmlEscaped() + "
"; - } - catch (dev::Exception const& exception) - { - ostringstream error; - solidity::SourceReferenceFormatter::printExceptionInformation(error, exception, "Error", compiler); - solidity = "

Solidity

" + QString::fromStdString(error.str()).toHtmlEscaped() + "
"; - } - catch (...) - { - solidity = "

Solidity

Uncaught exception.
"; - } - } -#ifndef _MSC_VER - else if (sourceIsSerpent(src)) - { - try - { - m_data = dev::asBytes(::compile(src)); - for (auto& i: errors) - i = "(LLL " + i + ")"; - } - catch (string err) - { - errors.push_back("Serpent " + err); - } - } -#endif - else - { - m_data = compileLLL(src, m_enableOptimizer, &errors); - if (errors.empty()) - { - auto asmcode = compileLLLToAsm(src, false); - lll = "

Pre

" + QString::fromStdString(asmcode).toHtmlEscaped() + "
"; - if (m_enableOptimizer) - { - asmcode = compileLLLToAsm(src, true); - lll = "

Opt

" + QString::fromStdString(asmcode).toHtmlEscaped() + "
" + lll; - } - } - } - QString errs; - if (errors.size()) - { - errs = "

Errors

"; - for (auto const& i: errors) - errs.append("
" + QString::fromStdString(i).toHtmlEscaped() + "
"); - } - ui->code->setHtml(errs + lll + solidity + "

Code

" + QString::fromStdString(disassemble(m_data)).toHtmlEscaped() + "

Hex

" Div(Mono) + QString::fromStdString(toHex(m_data)) + "
"); - ui->gas->setMinimum((qint64)Client::txGas(m_data, 0)); - if (!ui->gas->isEnabled()) - ui->gas->setValue(m_backupGas); - ui->gas->setEnabled(true); - } - else - { - m_data = parseData(ui->data->toPlainText().toStdString()); - ui->code->setHtml(QString::fromStdString(dev::memDump(m_data, 8, true))); - if (ethereum()->codeAt(fromString(ui->destination->currentText()), 0).size()) - { - ui->gas->setMinimum((qint64)Client::txGas(m_data, 1)); - if (!ui->gas->isEnabled()) - ui->gas->setValue(m_backupGas); - ui->gas->setEnabled(true); - } - else - { - if (ui->gas->isEnabled()) - m_backupGas = ui->gas->value(); - ui->gas->setValue((qint64)Client::txGas(m_data)); - ui->gas->setEnabled(false); - } - } - updateFee(); -} - void Main::on_clearPending_triggered() { writeSettings(); @@ -1791,54 +1613,6 @@ void Main::on_killBlockchain_triggered() refreshAll(); } -bool Main::isCreation() const -{ - return ui->destination->currentText().isEmpty() || ui->destination->currentText() == "(Create Contract)"; -} - -u256 Main::fee() const -{ - return ui->gas->value() * gasPrice(); -} - -u256 Main::value() const -{ - if (ui->valueUnits->currentIndex() == -1) - return 0; - return ui->value->value() * units()[units().size() - 1 - ui->valueUnits->currentIndex()].first; -} - -u256 Main::gasPrice() const -{ - if (ui->gasPriceUnits->currentIndex() == -1) - return 0; - return ui->gasPrice->value() * units()[units().size() - 1 - ui->gasPriceUnits->currentIndex()].first; -} - -u256 Main::total() const -{ - return value() + fee(); -} - -void Main::updateFee() -{ - ui->fee->setText(QString("(gas sub-total: %1)").arg(formatBalance(fee()).c_str())); - auto totalReq = total(); - ui->total->setText(QString("Total: %1").arg(formatBalance(totalReq).c_str())); - - bool ok = false; - for (auto i: m_myKeys) - if (ethereum()->balanceAt(i.address()) >= totalReq) - { - ok = true; - break; - } - ui->send->setEnabled(ok); - QPalette p = ui->total->palette(); - p.setColor(QPalette::WindowText, QColor(ok ? 0x00 : 0x80, 0x00, 0x00)); - ui->total->setPalette(p); -} - void Main::on_net_triggered() { ui->port->setEnabled(!ui->net->isChecked()); @@ -1900,76 +1674,12 @@ void Main::on_mine_triggered() ethereum()->stopMining(); } -void Main::on_send_clicked() -{ - u256 totalReq = value() + fee(); - for (auto i: m_myKeys) - if (ethereum()->balanceAt(i.address(), 0) >= totalReq) - { - Secret s = i.secret(); - if (isCreation()) - { - // If execution is a contract creation, add Natspec to - // a local Natspec LEVELDB - ethereum()->transact(s, value(), m_data, ui->gas->value(), gasPrice()); - string src = ui->data->toPlainText().toStdString(); - if (sourceIsSolidity(src)) - try - { - dev::solidity::CompilerStack compiler; - m_data = compiler.compile(src, m_enableOptimizer); - for (string& s: compiler.getContractNames()) - { - h256 contractHash = compiler.getContractCodeHash(s); - m_natspecDB.add(contractHash, compiler.getMetadata(s, dev::solidity::DocumentationType::NatspecUser)); - } - } - catch (...) - { - statusBar()->showMessage("Couldn't compile Solidity Contract."); - } - } - else - ethereum()->transact(s, value(), fromString(ui->destination->currentText()), m_data, ui->gas->value(), gasPrice()); - return; - } - statusBar()->showMessage("Couldn't make transaction: no single account contains at least the required amount."); -} - void Main::keysChanged() { onBalancesChange(); m_server->setAccounts(keysAsVector(m_myKeys)); } -void Main::on_debug_clicked() -{ - try - { - u256 totalReq = value() + fee(); - for (auto i: m_myKeys) - if (ethereum()->balanceAt(i.address()) >= totalReq) - { - State st(ethereum()->postState()); - Secret s = i.secret(); - Transaction t = isCreation() ? - Transaction(value(), gasPrice(), ui->gas->value(), m_data, st.transactionsFrom(dev::toAddress(s)), s) : - Transaction(value(), gasPrice(), ui->gas->value(), fromString(ui->destination->currentText()), m_data, st.transactionsFrom(dev::toAddress(s)), s); - Debugger dw(this, this); - Executive e(st, ethereum()->blockChain(), 0); - dw.populate(e, t); - dw.exec(); - return; - } - statusBar()->showMessage("Couldn't make transaction: no single account contains at least the required amount."); - } - catch (dev::Exception const& _e) - { - statusBar()->showMessage("Error running transaction: " + QString::fromStdString(diagnostic_information(_e))); - // this output is aimed at developers, reconsider using _e.what for more user friendly output. - } -} - bool beginsWith(Address _a, bytes const& _b) { for (unsigned i = 0; i < min(20, _b.size()); ++i) @@ -2095,16 +1805,6 @@ void Main::on_post_clicked() whisper()->inject(m.seal(from, topicFromText(ui->shhTopic->toPlainText()), ui->shhTtl->value(), ui->shhWork->value())); } -string Main::lookupNatSpec(dev::h256 const& _contractHash) const -{ - return m_natspecDB.retrieve(_contractHash); -} - -string Main::lookupNatSpecUserNotice(dev::h256 const& _contractHash, dev::bytes const& _transactionData) -{ - return m_natspecDB.getUserNotice(_contractHash, _transactionData); -} - int Main::authenticate(QString _title, QString _text) { QMessageBox userInput(this); diff --git a/alethzero/MainWin.h b/alethzero/MainWin.h index d503a16dd..6c4a97301 100644 --- a/alethzero/MainWin.h +++ b/alethzero/MainWin.h @@ -37,7 +37,7 @@ #include #include #include "Context.h" -#include "Debugger.h" +#include "Transact.h" #include "NatspecHandler.h" namespace Ui { @@ -72,11 +72,8 @@ public: dev::eth::Client* ethereum() const { return m_webThree->ethereum(); } std::shared_ptr whisper() const { return m_webThree->whisper(); } - std::string lookupNatSpec(dev::h256 const& _contractHash) const; - std::string lookupNatSpecUserNotice(dev::h256 const& _contractHash, dev::bytes const& _transactionData); + NatSpecFace* natSpec() { return &m_natSpecDB; } - QList owned() const { return m_myIdentities + m_myKeys; } - QVariant evalRaw(QString const& _js); QString pretty(dev::Address _a) const override; @@ -85,6 +82,10 @@ public: dev::Address fromString(QString const& _a) const override; std::string renderDiff(dev::eth::StateDiff const& _d) const override; + QList owned() const { return m_myIdentities + m_myKeys; } + + dev::u256 gasPrice() const { return 10 * dev::eth::szabo; } + public slots: void load(QString _file); void note(QString _entry); @@ -118,17 +119,6 @@ private slots: void on_showAllAccounts_triggered() { refreshAccounts(); } void on_preview_triggered(); - // Transacting - void on_value_valueChanged() { updateFee(); } - void on_gas_valueChanged() { updateFee(); } - void on_valueUnits_currentIndexChanged() { updateFee(); } - void on_gasPriceUnits_currentIndexChanged() { updateFee(); } - void on_gasPrice_valueChanged() { updateFee(); } - void on_destination_currentTextChanged(); - void on_data_textChanged(); - void on_send_clicked(); - void on_debug_clicked(); - // Account management void on_newAccount_triggered(); void on_killAccount_triggered(); @@ -137,6 +127,7 @@ private slots: void on_exportKey_triggered(); // Tools + void on_newTransaction_triggered(); void on_loadJS_triggered(); // Stuff concerning the blocks/transactions/accounts panels @@ -165,7 +156,6 @@ private slots: void on_inject_triggered(); void on_forceMining_triggered(); void on_usePrivate_triggered(); - void on_enableOptimizer_triggered(); void on_turboMining_triggered(); void on_jitvm_triggered(); @@ -196,12 +186,6 @@ private: void readSettings(bool _skipGeometry = false); void writeSettings(); - bool isCreation() const; - dev::u256 fee() const; - dev::u256 total() const; - dev::u256 value() const; - dev::u256 gasPrice() const; - unsigned installWatch(dev::eth::LogFilter const& _tf, WatchHandler const& _f); unsigned installWatch(dev::h256 _tf, WatchHandler const& _f); void uninstallWatch(unsigned _w); @@ -228,15 +212,9 @@ private: void refreshAll(); void refreshPending(); void refreshAccounts(); - void refreshDestination(); void refreshBlockCount(); void refreshBalances(); - /// Attempts to infer that @c _source contains Solidity code - bool sourceIsSolidity(std::string const& _source); - /// @eturns all method hashes of a Solidity contract in a string - std::string const getFunctionHashes(dev::solidity::CompilerStack const &_compiler, std::string const& _contractName = ""); - std::unique_ptr ui; std::unique_ptr m_webThree; @@ -251,13 +229,8 @@ private: QList m_myKeys; QList m_myIdentities; QString m_privateChain; - dev::bytes m_data; dev::Address m_nameReg; - unsigned m_backupGas; - - bool m_enableOptimizer = true; - QNetworkAccessManager m_webCtrl; QList> m_consoleHistory; @@ -269,5 +242,7 @@ private: std::unique_ptr m_server; static QString fromRaw(dev::h256 _n, unsigned* _inc = nullptr); - NatspecHandler m_natspecDB; + NatspecHandler m_natSpecDB; + + Transact m_transact; }; diff --git a/alethzero/NatspecHandler.h b/alethzero/NatspecHandler.h index 98677dbc2..15ceb7b0b 100644 --- a/alethzero/NatspecHandler.h +++ b/alethzero/NatspecHandler.h @@ -28,10 +28,11 @@ #pragma warning(pop) #include #include +#include "Context.h" namespace ldb = leveldb; -class NatspecHandler +class NatspecHandler: public NatSpecFace { public: NatspecHandler(); @@ -40,7 +41,7 @@ class NatspecHandler /// Stores locally in a levelDB a key value pair of contract code hash to natspec documentation void add(dev::h256 const& _contractHash, std::string const& _doc); /// Retrieves the natspec documentation as a string given a contract code hash - std::string retrieve(dev::h256 const& _contractHash) const; + std::string retrieve(dev::h256 const& _contractHash) const override; /// Given a json natspec string and the transaction data return the user notice std::string getUserNotice(std::string const& json, const dev::bytes& _transactionData); diff --git a/alethzero/OurWebThreeStubServer.cpp b/alethzero/OurWebThreeStubServer.cpp index 89d616756..06f5fc637 100644 --- a/alethzero/OurWebThreeStubServer.cpp +++ b/alethzero/OurWebThreeStubServer.cpp @@ -92,7 +92,7 @@ bool OurWebThreeStubServer::authenticate(TransactionSkeleton const& _t) } // TODO: include total cost in Ether - string userNotice = m_main->lookupNatSpecUserNotice(contractCodeHash, _t.data); + string userNotice = m_main->natSpec()->getUserNotice(contractCodeHash, _t.data); if (userNotice.empty()) return showUnknownCallNotice(_t); diff --git a/alethzero/Transact.cpp b/alethzero/Transact.cpp new file mode 100644 index 000000000..4ac0bbcbf --- /dev/null +++ b/alethzero/Transact.cpp @@ -0,0 +1,325 @@ +/* + 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 Transact.cpp + * @author Gav Wood + * @date 2015 + */ + +#include "Transact.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef _MSC_VER +#include +#include +#endif +#include "Debugger.h" +#include "ui_Transact.h" +using namespace std; +using namespace dev; +using namespace dev::eth; + +Transact::Transact(Context* _c, QWidget* _parent): + QDialog(_parent), + ui(new Ui::Transact), + m_context(_c) +{ + ui->setupUi(this); + + initUnits(ui->gasPriceUnits); + initUnits(ui->valueUnits); + ui->valueUnits->setCurrentIndex(6); + ui->gasPriceUnits->setCurrentIndex(4); + ui->gasPrice->setValue(10); + on_destination_currentTextChanged(); +} + +Transact::~Transact() +{ + delete ui; +} + +void Transact::setEnvironment(QList _myKeys, dev::eth::Client* _eth, NatSpecFace* _natSpecDB) +{ + m_myKeys = _myKeys; + m_ethereum = _eth; + m_natSpecDB = _natSpecDB; +} + +bool Transact::isCreation() const +{ + return ui->destination->currentText().isEmpty() || ui->destination->currentText() == "(Create Contract)"; +} + +u256 Transact::fee() const +{ + return ui->gas->value() * gasPrice(); +} + +u256 Transact::value() const +{ + if (ui->valueUnits->currentIndex() == -1) + return 0; + return ui->value->value() * units()[units().size() - 1 - ui->valueUnits->currentIndex()].first; +} + +u256 Transact::gasPrice() const +{ + if (ui->gasPriceUnits->currentIndex() == -1) + return 0; + return ui->gasPrice->value() * units()[units().size() - 1 - ui->gasPriceUnits->currentIndex()].first; +} + +u256 Transact::total() const +{ + return value() + fee(); +} + +void Transact::updateDestination() +{ + cwatch << "updateDestination()"; + QString s; + for (auto i: ethereum()->addresses()) + if ((s = m_context->pretty(i)).size()) + // A namereg address + if (ui->destination->findText(s, Qt::MatchExactly | Qt::MatchCaseSensitive) == -1) + ui->destination->addItem(s); + for (int i = 0; i < ui->destination->count(); ++i) + if (ui->destination->itemText(i) != "(Create Contract)" && !m_context->fromString(ui->destination->itemText(i))) + ui->destination->removeItem(i--); +} + +void Transact::updateFee() +{ + ui->fee->setText(QString("(gas sub-total: %1)").arg(formatBalance(fee()).c_str())); + auto totalReq = total(); + ui->total->setText(QString("Total: %1").arg(formatBalance(totalReq).c_str())); + + bool ok = false; + for (auto i: m_myKeys) + if (ethereum()->balanceAt(i.address()) >= totalReq) + { + ok = true; + break; + } + ui->send->setEnabled(ok); + QPalette p = ui->total->palette(); + p.setColor(QPalette::WindowText, QColor(ok ? 0x00 : 0x80, 0x00, 0x00)); + ui->total->setPalette(p); +} + +string Transact::getFunctionHashes(dev::solidity::CompilerStack const& _compiler, string const& _contractName) +{ + string ret = ""; + auto const& contract = _compiler.getContractDefinition(_contractName); + auto interfaceFunctions = contract.getInterfaceFunctions(); + + for (auto const& it: interfaceFunctions) + { + ret += it.first.abridged(); + ret += " :"; + ret += it.second->getDeclaration().getName() + "\n"; + } + return ret; +} + +void Transact::on_destination_currentTextChanged() +{ + if (ui->destination->currentText().size() && ui->destination->currentText() != "(Create Contract)") + if (Address a = m_context->fromString(ui->destination->currentText())) + ui->calculatedName->setText(m_context->render(a)); + else + ui->calculatedName->setText("Unknown Address"); + else + ui->calculatedName->setText("Create Contract"); + rejigData(); +// updateFee(); +} + +void Transact::rejigData() +{ + if (isCreation()) + { + string src = ui->data->toPlainText().toStdString(); + vector errors; + QString lll; + QString solidity; + if (src.find_first_not_of("1234567890abcdefABCDEF") == string::npos && src.size() % 2 == 0) + { + m_data = fromHex(src); + } + else if (sourceIsSolidity(src)) + { + dev::solidity::CompilerStack compiler; + try + { +// compiler.addSources(dev::solidity::StandardSources); + m_data = compiler.compile(src, ui->optimize->isChecked()); + solidity = "

Solidity

"; + solidity += "
var " + QString::fromStdString(compiler.defaultContractName()) + " = web3.eth.contractFromAbi(" + QString::fromStdString(compiler.getInterface()).replace(QRegExp("\\s"), "").toHtmlEscaped() + ");
"; + solidity += "
" + QString::fromStdString(compiler.getSolidityInterface()).toHtmlEscaped() + "
"; + solidity += "
" + QString::fromStdString(getFunctionHashes(compiler)).toHtmlEscaped() + "
"; + } + catch (dev::Exception const& exception) + { + ostringstream error; + solidity::SourceReferenceFormatter::printExceptionInformation(error, exception, "Error", compiler); + solidity = "

Solidity

" + QString::fromStdString(error.str()).toHtmlEscaped() + "
"; + } + catch (...) + { + solidity = "

Solidity

Uncaught exception.
"; + } + } +#ifndef _MSC_VER + else if (sourceIsSerpent(src)) + { + try + { + m_data = dev::asBytes(::compile(src)); + for (auto& i: errors) + i = "(LLL " + i + ")"; + } + catch (string err) + { + errors.push_back("Serpent " + err); + } + } +#endif + else + { + m_data = compileLLL(src, ui->optimize->isChecked(), &errors); + if (errors.empty()) + { + auto asmcode = compileLLLToAsm(src, false); + lll = "

Pre

" + QString::fromStdString(asmcode).toHtmlEscaped() + "
"; + if (ui->optimize->isChecked()) + { + asmcode = compileLLLToAsm(src, true); + lll = "

Opt

" + QString::fromStdString(asmcode).toHtmlEscaped() + "
" + lll; + } + } + } + QString errs; + if (errors.size()) + { + errs = "

Errors

"; + for (auto const& i: errors) + errs.append("
" + QString::fromStdString(i).toHtmlEscaped() + "
"); + } + ui->code->setHtml(errs + lll + solidity + "

Code

" + QString::fromStdString(disassemble(m_data)).toHtmlEscaped() + "

Hex

" Div(Mono) + QString::fromStdString(toHex(m_data)) + "
"); + ui->gas->setMinimum((qint64)Interface::txGas(m_data, 0)); + if (!ui->gas->isEnabled()) + ui->gas->setValue(m_backupGas); + ui->gas->setEnabled(true); + } + else + { + m_data = parseData(ui->data->toPlainText().toStdString()); + ui->code->setHtml(QString::fromStdString(dev::memDump(m_data, 8, true))); + if (ethereum()->codeAt(m_context->fromString(ui->destination->currentText()), 0).size()) + { + ui->gas->setMinimum((qint64)Interface::txGas(m_data, 1)); + if (!ui->gas->isEnabled()) + ui->gas->setValue(m_backupGas); + ui->gas->setEnabled(true); + } + else + { + if (ui->gas->isEnabled()) + m_backupGas = ui->gas->value(); + ui->gas->setValue((qint64)Interface::txGas(m_data)); + ui->gas->setEnabled(false); + } + } + updateFee(); +} + +void Transact::on_send_clicked() +{ + u256 totalReq = value() + fee(); + for (auto const& i: m_myKeys) + if (ethereum()->balanceAt(i.address(), 0) >= totalReq) + { + Secret s = i.secret(); + if (isCreation()) + { + // If execution is a contract creation, add Natspec to + // a local Natspec LEVELDB + ethereum()->transact(s, value(), m_data, ui->gas->value(), gasPrice()); + string src = ui->data->toPlainText().toStdString(); + if (sourceIsSolidity(src)) + try + { + dev::solidity::CompilerStack compiler; + m_data = compiler.compile(src, ui->optimize->isChecked()); + for (string const& s: compiler.getContractNames()) + { + h256 contractHash = compiler.getContractCodeHash(s); + m_natSpecDB->add(contractHash, compiler.getMetadata(s, dev::solidity::DocumentationType::NatspecUser)); + } + } + catch (...) + { + } + close(); + return; + } + else + ethereum()->transact(s, value(), m_context->fromString(ui->destination->currentText()), m_data, ui->gas->value(), gasPrice()); + return; + } + QMessageBox::critical(this, "Transaction Failed", "Couldn't make transaction: no single account contains at least the required amount."); +} + +void Transact::on_debug_clicked() +{ + try + { + u256 totalReq = value() + fee(); + for (auto i: m_myKeys) + if (ethereum()->balanceAt(i.address()) >= totalReq) + { + State st(ethereum()->postState()); + Secret s = i.secret(); + Transaction t = isCreation() ? + Transaction(value(), gasPrice(), ui->gas->value(), m_data, st.transactionsFrom(dev::toAddress(s)), s) : + Transaction(value(), gasPrice(), ui->gas->value(), m_context->fromString(ui->destination->currentText()), m_data, st.transactionsFrom(dev::toAddress(s)), s); + Debugger dw(m_context, this); + Executive e(st, ethereum()->blockChain(), 0); + dw.populate(e, t); + dw.exec(); + close(); + return; + } + QMessageBox::critical(this, "Transaction Failed", "Couldn't make transaction: no single account contains at least the required amount."); + } + catch (dev::Exception const& _e) + { + QMessageBox::critical(this, "Transaction Failed", "Couldn't make transaction. Low-level error: " + QString::fromStdString(diagnostic_information(_e))); + // this output is aimed at developers, reconsider using _e.what for more user friendly output. + } +} diff --git a/alethzero/Transact.h b/alethzero/Transact.h new file mode 100644 index 000000000..afb45f62d --- /dev/null +++ b/alethzero/Transact.h @@ -0,0 +1,82 @@ +/* + 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 Transact.h + * @author Gav Wood + * @date 2015 + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include "Context.h" + +namespace Ui { class Transact; } +namespace dev { namespace eth { class Client; } } +namespace dev { namespace solidity { class CompilerStack; } } + +class Transact: public QDialog +{ + Q_OBJECT + +public: + explicit Transact(Context* _context, QWidget* _parent = 0); + ~Transact(); + + void setEnvironment(QList _myKeys, dev::eth::Client* _eth, NatSpecFace* _natSpecDB); + +private slots: + void on_destination_currentTextChanged(); + void on_value_valueChanged() { updateFee(); } + void on_gas_valueChanged() { updateFee(); } + void on_valueUnits_currentIndexChanged() { updateFee(); } + void on_gasPriceUnits_currentIndexChanged() { updateFee(); } + void on_gasPrice_valueChanged() { updateFee(); } + void on_data_textChanged() { rejigData(); } + void on_optimize_clicked() { rejigData(); } + void on_send_clicked(); + void on_debug_clicked(); + void on_cancel_clicked() { close(); } + +private: + dev::eth::Client* ethereum() { return m_ethereum; } + void rejigData(); + + void updateDestination(); + void updateFee(); + bool isCreation() const; + dev::u256 fee() const; + dev::u256 total() const; + dev::u256 value() const; + dev::u256 gasPrice() const; + + std::string getFunctionHashes(dev::solidity::CompilerStack const& _compiler, std::string const& _contractName = std::string()); + + Ui::Transact* ui; + + unsigned m_backupGas; + dev::bytes m_data; + + QList m_myKeys; + dev::eth::Client* m_ethereum; + Context* m_context; + NatSpecFace* m_natSpecDB; +}; diff --git a/alethzero/Transact.ui b/alethzero/Transact.ui new file mode 100644 index 000000000..c66e47aa8 --- /dev/null +++ b/alethzero/Transact.ui @@ -0,0 +1,244 @@ + + + Transact + + + + 0 + 0 + 543 + 695 + + + + Dialog + + + + + + + + + 430000000 + + + 0 + + + + + + + &Amount + + + value + + + + + + + false + + + true + + + + + + + + + + Qt::Vertical + + + + QFrame::NoFrame + + + 0 + + + + + Qt::ClickFocus + + + QFrame::NoFrame + + + 0 + + + true + + + + + + + + + + + + 0 + 0 + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + &To + + + destination + + + + + + + + + + &Debug + + + + + + + &Execute + + + false + + + + + + + &Gas + + + gas + + + + + + + gas + + + 1 + + + 430000000 + + + 10000 + + + + + + + @ + + + 1 + + + 430000000 + + + + + + + &Optimise + + + true + + + + + + + + 0 + 0 + + + + D&ata + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + data + + + + + + + true + + + + (Create Contract) + + + + + + + + + 0 + 0 + + + + + + + + + + + &Cancel + + + Esc + + + + + + + + diff --git a/libethcore/CommonEth.cpp b/libethcore/CommonEth.cpp index 47344a156..e07eb04ba 100644 --- a/libethcore/CommonEth.cpp +++ b/libethcore/CommonEth.cpp @@ -35,16 +35,6 @@ namespace eth const unsigned c_protocolVersion = 53; const unsigned c_databaseVersion = 5; -template u256 exp10() -{ - return exp10() * u256(10); -} - -template <> u256 exp10<0>() -{ - return u256(1); -} - vector> const& units() { static const vector> s_units = diff --git a/libethcore/CommonEth.h b/libethcore/CommonEth.h index 966794953..79525082f 100644 --- a/libethcore/CommonEth.h +++ b/libethcore/CommonEth.h @@ -47,26 +47,21 @@ std::vector> const& units(); /// The log bloom's size (512 bit). using LogBloom = h512; +template inline u256 exp10() +{ + return exp10() * u256(10); +} + +template <> inline u256 exp10<0>() +{ + return u256(1); +} + // The various denominations; here for ease of use where needed within code. -/*static const u256 Uether = ((((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000000; -static const u256 Vether = ((((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000; -static const u256 Dether = ((((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000; -static const u256 Nether = (((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000000; -static const u256 Yether = (((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000; -static const u256 Zether = (((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000; -static const u256 Eether = ((u256(1000000000) * 1000000000) * 1000000000) * 1000000000; -static const u256 Pether = ((u256(1000000000) * 1000000000) * 1000000000) * 1000000; -static const u256 Tether = ((u256(1000000000) * 1000000000) * 1000000000) * 1000; -static const u256 Gether = (u256(1000000000) * 1000000000) * 1000000000; -static const u256 Mether = (u256(1000000000) * 1000000000) * 1000000; -static const u256 grand = (u256(1000000000) * 1000000000) * 1000;*/ -static const u256 ether = u256(1000000000) * 1000000000; -static const u256 finney = u256(1000000000) * 1000000; -static const u256 szabo = u256(1000000000) * 1000; -/*static const u256 Gwei = u256(1000000000); -static const u256 Mwei = u256(1000000); -static const u256 Kwei = u256(1000);*/ -static const u256 wei = u256(1); +static const u256 ether = exp10<18>(); +static const u256 finney = exp10<15>(); +static const u256 szabo = exp10<12>(); +static const u256 wei = exp10<0>(); } } From 2587b2deb2226944eca4ba01e9a6c43b4925190d Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 15 Feb 2015 22:20:20 +0100 Subject: [PATCH 187/213] Preview Natspec in New Transaction dialog. --- alethzero/MainWin.cpp | 2 +- alethzero/NatspecHandler.cpp | 13 ++++++------- alethzero/OurWebThreeStubServer.cpp | 1 - alethzero/Transact.cpp | 17 ++++++++++++++--- libdevcore/vector_ref.h | 2 +- 5 files changed, 22 insertions(+), 13 deletions(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 1d497cc0b..00fb29e2d 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -1491,7 +1491,7 @@ void Main::on_contracts_currentItemChanged() auto storage = ethereum()->storageAt(address); for (auto const& i: storage) s << "@" << showbase << hex << prettyU256(i.first).toStdString() << "    " << showbase << hex << prettyU256(i.second).toStdString() << "
"; - s << "

Body Code

" << disassemble(ethereum()->codeAt(address)); + s << "

Body Code (" << sha3(ethereum()->codeAt(address)).abridged() << ")

" << disassemble(ethereum()->codeAt(address)); s << Div(Mono) << toHex(ethereum()->codeAt(address)) << ""; ui->contractInfo->appendHtml(QString::fromStdString(s.str())); } diff --git a/alethzero/NatspecHandler.cpp b/alethzero/NatspecHandler.cpp index 25cc13d4a..bfdbaa178 100644 --- a/alethzero/NatspecHandler.cpp +++ b/alethzero/NatspecHandler.cpp @@ -50,16 +50,15 @@ NatspecHandler::~NatspecHandler() void NatspecHandler::add(dev::h256 const& _contractHash, string const& _doc) { - bytes k = _contractHash.asBytes(); - string v = _doc; - m_db->Put(m_writeOptions, ldb::Slice((char const*)k.data(), k.size()), ldb::Slice((char const*)v.data(), v.size())); + m_db->Put(m_writeOptions, _contractHash.ref(), _doc); + cdebug << "Registering NatSpec: " << _contractHash.abridged() << _doc; } string NatspecHandler::retrieve(dev::h256 const& _contractHash) const { - bytes k = _contractHash.asBytes(); string ret; - m_db->Get(m_readOptions, ldb::Slice((char const*)k.data(), k.size()), &ret); + m_db->Get(m_readOptions, _contractHash.ref(), &ret); + cdebug << "Looking up NatSpec: " << _contractHash.abridged() << ret; return ret; } @@ -69,8 +68,8 @@ string NatspecHandler::getUserNotice(string const& json, dev::bytes const& _tran Json::Value userNotice; string retStr; m_reader.parse(json, natspec); - bytes transactionFunctionPart(_transactionData.begin(), _transactionData.begin() + 4); - FixedHash<4> transactionFunctionHash(transactionFunctionPart); + + FixedHash<4> transactionFunctionHash((bytesConstRef(&_transactionData).cropped(0, 4).toBytes())); Json::Value methods = natspec["methods"]; for (Json::ValueIterator it = methods.begin(); it != methods.end(); ++it) diff --git a/alethzero/OurWebThreeStubServer.cpp b/alethzero/OurWebThreeStubServer.cpp index 06f5fc637..2d1dd0481 100644 --- a/alethzero/OurWebThreeStubServer.cpp +++ b/alethzero/OurWebThreeStubServer.cpp @@ -91,7 +91,6 @@ bool OurWebThreeStubServer::authenticate(TransactionSkeleton const& _t) return showSendNotice(_t); } - // TODO: include total cost in Ether string userNotice = m_main->natSpec()->getUserNotice(contractCodeHash, _t.data); if (userNotice.empty()) diff --git a/alethzero/Transact.cpp b/alethzero/Transact.cpp index 4ac0bbcbf..3031232c2 100644 --- a/alethzero/Transact.cpp +++ b/alethzero/Transact.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #ifndef _MSC_VER @@ -239,9 +240,18 @@ void Transact::rejigData() else { m_data = parseData(ui->data->toPlainText().toStdString()); - ui->code->setHtml(QString::fromStdString(dev::memDump(m_data, 8, true))); - if (ethereum()->codeAt(m_context->fromString(ui->destination->currentText()), 0).size()) + auto to = m_context->fromString(ui->destination->currentText()); + QString natspec; + if (ethereum()->codeAt(to, 0).size()) { + string userNotice = m_natSpecDB->getUserNotice(ethereum()->postState().codeHash(to), m_data); + if (userNotice.empty()) + natspec = "Destination contract unknown."; + else + { + NatspecExpressionEvaluator evaluator; + natspec = evaluator.evalExpression(QString::fromStdString(userNotice)); + } ui->gas->setMinimum((qint64)Interface::txGas(m_data, 1)); if (!ui->gas->isEnabled()) ui->gas->setValue(m_backupGas); @@ -249,11 +259,13 @@ void Transact::rejigData() } else { + natspec += "Destination not a contract."; if (ui->gas->isEnabled()) m_backupGas = ui->gas->value(); ui->gas->setValue((qint64)Interface::txGas(m_data)); ui->gas->setEnabled(false); } + ui->code->setHtml("

NatSpec

" + natspec + "

Dump

" + QString::fromStdString(dev::memDump(m_data, 8, true)) + "

Hex

" + Div(Mono) + QString::fromStdString(toHex(m_data)) + ""); } updateFee(); } @@ -312,7 +324,6 @@ void Transact::on_debug_clicked() Executive e(st, ethereum()->blockChain(), 0); dw.populate(e, t); dw.exec(); - close(); return; } QMessageBox::critical(this, "Transaction Failed", "Couldn't make transaction: no single account contains at least the required amount."); diff --git a/libdevcore/vector_ref.h b/libdevcore/vector_ref.h index f7ab4c14a..9039c3149 100644 --- a/libdevcore/vector_ref.h +++ b/libdevcore/vector_ref.h @@ -19,7 +19,7 @@ public: vector_ref(): m_data(nullptr), m_count(0) {} vector_ref(_T* _data, size_t _count): m_data(_data), m_count(_count) {} - vector_ref(std::string* _data): m_data((_T*)_data->data()), m_count(_data->size() / sizeof(_T)) {} + vector_ref(typename std::conditional::value, std::string const*, std::string*>::type _data): m_data((_T*)_data->data()), m_count(_data->size() / sizeof(_T)) {} vector_ref(typename std::conditional::value, std::vector::type> const*, std::vector<_T>*>::type _data): m_data(_data->data()), m_count(_data->size()) {} vector_ref(typename std::conditional::value, std::string const&, std::string&>::type _data): m_data((_T*)_data.data()), m_count(_data.size() / sizeof(_T)) {} #ifdef STORAGE_LEVELDB_INCLUDE_DB_H_ From d35da25b19cd0f82799e7aac5f70bb567bc57467 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Mon, 16 Feb 2015 11:04:05 +0100 Subject: [PATCH 188/213] extra data fix --- test/TestHelper.cpp | 20 +-- test/blInvalidHeaderTestFiller.json | 0 test/block.cpp | 232 +++++++++++++--------------- 3 files changed, 120 insertions(+), 132 deletions(-) create mode 100644 test/blInvalidHeaderTestFiller.json diff --git a/test/TestHelper.cpp b/test/TestHelper.cpp index 1e6b97f07..ff6939a5f 100644 --- a/test/TestHelper.cpp +++ b/test/TestHelper.cpp @@ -510,16 +510,16 @@ RLPStream createRLPStreamFromTransactionFields(json_spirit::mObject& _tObj) RLPStream rlpStream; rlpStream.appendList(_tObj.size()); - if (_tObj.count("nonce") > 0) + if (_tObj.count("nonce")) rlpStream << bigint(_tObj["nonce"].get_str()); - if (_tObj.count("gasPrice") > 0) + if (_tObj.count("gasPrice")) rlpStream << bigint(_tObj["gasPrice"].get_str()); - if (_tObj.count("gasLimit") > 0) + if (_tObj.count("gasLimit")) rlpStream << bigint(_tObj["gasLimit"].get_str()); - if (_tObj.count("to") > 0) + if (_tObj.count("to")) { if (_tObj["to"].get_str().empty()) rlpStream << ""; @@ -527,22 +527,22 @@ RLPStream createRLPStreamFromTransactionFields(json_spirit::mObject& _tObj) rlpStream << importByteArray(_tObj["to"].get_str()); } - if (_tObj.count("value") > 0) + if (_tObj.count("value")) rlpStream << bigint(_tObj["value"].get_str()); - if (_tObj.count("data") > 0) + if (_tObj.count("data")) rlpStream << importData(_tObj); - if (_tObj.count("v") > 0) + if (_tObj.count("v")) rlpStream << bigint(_tObj["v"].get_str()); - if (_tObj.count("r") > 0) + if (_tObj.count("r")) rlpStream << bigint(_tObj["r"].get_str()); - if (_tObj.count("s") > 0) + if (_tObj.count("s")) rlpStream << bigint(_tObj["s"].get_str()); - if (_tObj.count("extrafield") > 0) + if (_tObj.count("extrafield")) rlpStream << bigint(_tObj["extrafield"].get_str()); return rlpStream; diff --git a/test/blInvalidHeaderTestFiller.json b/test/blInvalidHeaderTestFiller.json new file mode 100644 index 000000000..e69de29bb diff --git a/test/block.cpp b/test/block.cpp index 4d1f5accc..891d89931 100644 --- a/test/block.cpp +++ b/test/block.cpp @@ -35,46 +35,46 @@ bytes createBlockRLPFromFields(mObject& _tObj) RLPStream rlpStream; rlpStream.appendList(_tObj.size()); - if (_tObj.count("parentHash") > 0) + if (_tObj.count("parentHash")) rlpStream << importByteArray(_tObj["parentHash"].get_str()); - if (_tObj.count("uncleHash") > 0) + if (_tObj.count("uncleHash")) rlpStream << importByteArray(_tObj["uncleHash"].get_str()); - if (_tObj.count("coinbase") > 0) + if (_tObj.count("coinbase")) rlpStream << importByteArray(_tObj["coinbase"].get_str()); - if (_tObj.count("stateRoot") > 0) + if (_tObj.count("stateRoot")) rlpStream << importByteArray(_tObj["stateRoot"].get_str()); - if (_tObj.count("transactionsTrie") > 0) + if (_tObj.count("transactionsTrie")) rlpStream << importByteArray(_tObj["transactionsTrie"].get_str()); - if (_tObj.count("receiptTrie") > 0) + if (_tObj.count("receiptTrie")) rlpStream << importByteArray(_tObj["receiptTrie"].get_str()); - if (_tObj.count("bloom") > 0) + if (_tObj.count("bloom")) rlpStream << importByteArray(_tObj["bloom"].get_str()); - if (_tObj.count("difficulty") > 0) + if (_tObj.count("difficulty")) rlpStream << bigint(_tObj["difficulty"].get_str()); - if (_tObj.count("number") > 0) + if (_tObj.count("number")) rlpStream << bigint(_tObj["number"].get_str()); - if (_tObj.count("gasLimit") > 0) + if (_tObj.count("gasLimit")) rlpStream << bigint(_tObj["gasLimit"].get_str()); - if (_tObj.count("gasUsed") > 0) + if (_tObj.count("gasUsed")) rlpStream << bigint(_tObj["gasUsed"].get_str()); - if (_tObj.count("timestamp") > 0) + if (_tObj.count("timestamp")) rlpStream << bigint(_tObj["timestamp"].get_str()); - if (_tObj.count("extraData") > 0) + if (_tObj.count("extraData")) rlpStream << importByteArray(_tObj["extraData"].get_str()); - if (_tObj.count("nonce") > 0) + if (_tObj.count("nonce")) rlpStream << importByteArray(_tObj["nonce"].get_str()); return rlpStream.out(); @@ -87,43 +87,37 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) cerr << i.first << endl; mObject& o = i.second.get_obj(); - BOOST_REQUIRE(o.count("genesisBlockHeader") > 0); - cout << "construc genesis\n"; - - // construct RLP of the genesis block - const bytes c_blockRLP = createBlockRLPFromFields(o["genesisBlockHeader"].get_obj()); - const RLP c_bRLP(c_blockRLP); + BOOST_REQUIRE(o.count("genesisBlockHeader")); BlockInfo blockFromFields; - try { + // construct genesis block + const bytes c_blockRLP = createBlockRLPFromFields(o["genesisBlockHeader"].get_obj()); + const RLP c_bRLP(c_blockRLP); blockFromFields.populateFromHeader(c_bRLP, false); } catch (Exception const& _e) { cnote << "block population did throw an exception: " << diagnostic_information(_e); BOOST_ERROR("Failed block population with Exception: " << _e.what()); - return; + continue; } catch (std::exception const& _e) { BOOST_ERROR("Failed block population with Exception: " << _e.what()); - return; + continue; } catch(...) { cnote << "block population did throw an unknown exception\n"; - return; + continue; } - BOOST_REQUIRE(o.count("pre") > 0); - cout << "read state\n"; + BOOST_REQUIRE(o.count("pre")); ImportTest importer(o["pre"].get_obj()); State state(Address(), OverlayDB(), BaseState::Empty); importer.importState(o["pre"].get_obj(), state); - - // commit changes to DB state.commit(); if (_fillin) @@ -136,7 +130,8 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) // find new valid nonce ProofOfWork pow; MineInfo ret; - tie(ret, blockFromFields.nonce) = pow.mine(blockFromFields.headerHash(WithoutNonce), blockFromFields.difficulty, 1000, true, false); + while (!ProofOfWork::verify(blockFromFields.headerHash(WithoutNonce), blockFromFields.nonce, blockFromFields.difficulty)) + tie(ret, blockFromFields.nonce) = pow.mine(blockFromFields.headerHash(WithoutNonce), blockFromFields.difficulty, 1000, true, true); //update genesis block in json file o["genesisBlockHeader"].get_obj()["stateRoot"] = toString(blockFromFields.stateRoot); @@ -157,12 +152,9 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) // construct blockchain BlockChain bc(block.out(), string(), true); - cout << "constructed bc\n"; - if (_fillin) { - BOOST_REQUIRE(o.count("transactions") > 0); - cout << "read transactions\n"; + BOOST_REQUIRE(o.count("transactions")); TransactionQueue txs; @@ -195,12 +187,10 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) } // write valid txs - cout << "number of valid txs: " << txs.transactions().size(); mArray txArray; Transactions txList; for (auto const& txi: txs.transactions()) { - cout << "AHA0" << endl; Transaction tx(txi.second, CheckSignature::Sender); txList.push_back(tx); mObject txObject; @@ -213,82 +203,61 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) txObject["v"] = to_string(tx.signature().v + 27); txObject["to"] = toString(tx.receiveAddress()); txObject["value"] = toString(tx.value()); - cout << "AHA0.5" << endl; txArray.push_back(txObject); } - cout << "AHA1" << endl; - o["transactions"] = txArray; + o["transactions"] = txArray; o["rlp"] = "0x" + toHex(state.blockData()); - // write block header - - mObject oBlockHeader; BlockInfo current_BlockHeader = state.info(); - oBlockHeader["parentHash"] = toString(current_BlockHeader.parentHash); - oBlockHeader["uncleHash"] = toString(current_BlockHeader.sha3Uncles); - oBlockHeader["coinbase"] = toString(current_BlockHeader.coinbaseAddress); - oBlockHeader["stateRoot"] = toString(current_BlockHeader.stateRoot); - oBlockHeader["transactionsTrie"] = toString(current_BlockHeader.transactionsRoot); - oBlockHeader["receiptTrie"] = toString(current_BlockHeader.receiptsRoot); - oBlockHeader["bloom"] = toString(current_BlockHeader.logBloom); - oBlockHeader["difficulty"] = toString(current_BlockHeader.difficulty); - oBlockHeader["number"] = toString(current_BlockHeader.number); - oBlockHeader["gasLimit"] = toString(current_BlockHeader.gasLimit); - oBlockHeader["gasUsed"] = toString(current_BlockHeader.gasUsed); - oBlockHeader["timestamp"] = toString(current_BlockHeader.timestamp); - oBlockHeader["extraData"] = toHex(current_BlockHeader.extraData); - oBlockHeader["nonce"] = toString(current_BlockHeader.nonce); - - - // overwrite (wrong) data from blockheader in filler" << endl; + // overwrite blockheader with (possible wrong) data from "blockheader" in filler; - if (o.count("blockHeader") > 0) + if (o.count("blockHeader")) { if (o["blockHeader"].get_obj().size() != 14) { BlockInfo tmp = current_BlockHeader; - if (o["blockHeader"].get_obj().count("parentHash") > 0) + if (o["blockHeader"].get_obj().count("parentHash")) tmp.parentHash = h256(o["blockHeader"].get_obj()["parentHash"].get_str()); - if (o["blockHeader"].get_obj().count("sha3Uncles") > 0) + if (o["blockHeader"].get_obj().count("sha3Uncles")) tmp.sha3Uncles = h256(o["blockHeader"].get_obj()["uncleHash"].get_str()); - if (o["blockHeader"].get_obj().count("coinbase") > 0) + if (o["blockHeader"].get_obj().count("coinbase")) tmp.coinbaseAddress = Address(o["blockHeader"].get_obj()["coinbase"].get_str()); - if (o["blockHeader"].get_obj().count("stateRoot") > 0) + if (o["blockHeader"].get_obj().count("stateRoot")) tmp.stateRoot = h256(o["blockHeader"].get_obj()["stateRoot"].get_str()); - if (o["blockHeader"].get_obj().count("transactionsTrie") > 0) + if (o["blockHeader"].get_obj().count("transactionsTrie")) tmp.transactionsRoot = h256(o["blockHeader"].get_obj()["transactionsTrie"].get_str()); - if (o["blockHeader"].get_obj().count("receiptTrie") > 0) + if (o["blockHeader"].get_obj().count("receiptTrie")) tmp.receiptsRoot = h256(o["blockHeader"].get_obj()["receiptTrie"].get_str()); - if (o["blockHeader"].get_obj().count("bloom") > 0) + if (o["blockHeader"].get_obj().count("bloom")) tmp.logBloom = LogBloom(o["blockHeader"].get_obj()["bloom"].get_str()); - if (o["blockHeader"].get_obj().count("difficulty") > 0) + if (o["blockHeader"].get_obj().count("difficulty")) tmp.difficulty = toInt(o["blockHeader"].get_obj()["difficulty"]); - if (o["blockHeader"].get_obj().count("number") > 0) + if (o["blockHeader"].get_obj().count("number")) tmp.number = toInt(o["blockHeader"].get_obj()["number"]); - if (o["blockHeader"].get_obj().count("gasLimit") > 0) + if (o["blockHeader"].get_obj().count("gasLimit")) tmp.gasLimit = toInt(o["blockHeader"].get_obj()["gasLimit"]); - if (o["blockHeader"].get_obj().count("gasUsed") > 0) + if (o["blockHeader"].get_obj().count("gasUsed")) tmp.gasUsed = toInt(o["blockHeader"].get_obj()["gasUsed"]); - if (o["blockHeader"].get_obj().count("timestamp") > 0) + if (o["blockHeader"].get_obj().count("timestamp")) tmp.timestamp = toInt(o["blockHeader"].get_obj()["timestamp"]); - if (o["blockHeader"].get_obj().count("extraData") > 0) + if (o["blockHeader"].get_obj().count("extraData")) tmp.extraData = importByteArray(o["blockHeader"].get_obj()["extraData"].get_str()); // find new valid nonce @@ -301,18 +270,41 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) MineInfo ret; while (!ProofOfWork::verify(current_BlockHeader.headerHash(WithoutNonce), current_BlockHeader.nonce, current_BlockHeader.difficulty)) tie(ret, current_BlockHeader.nonce) = pow.mine(current_BlockHeader.headerHash(WithoutNonce), current_BlockHeader.difficulty, 10000, true, true); - oBlockHeader["nonce"] = toString(current_BlockHeader.nonce); } } else { // take the blockheader as is - const bytes c_blockRLP = createBlockRLPFromFields(o["genesisBlockHeader"].get_obj()); + const bytes c_blockRLP = createBlockRLPFromFields(o["blockHeader"].get_obj()); const RLP c_bRLP(c_blockRLP); current_BlockHeader.populateFromHeader(c_bRLP, false); } } + // write block header + + mObject oBlockHeader; + oBlockHeader["parentHash"] = toString(current_BlockHeader.parentHash); + oBlockHeader["uncleHash"] = toString(current_BlockHeader.sha3Uncles); + oBlockHeader["coinbase"] = toString(current_BlockHeader.coinbaseAddress); + oBlockHeader["stateRoot"] = toString(current_BlockHeader.stateRoot); + oBlockHeader["transactionsTrie"] = toString(current_BlockHeader.transactionsRoot); + oBlockHeader["receiptTrie"] = toString(current_BlockHeader.receiptsRoot); + oBlockHeader["bloom"] = toString(current_BlockHeader.logBloom); + oBlockHeader["difficulty"] = toString(current_BlockHeader.difficulty); + oBlockHeader["number"] = toString(current_BlockHeader.number); + oBlockHeader["gasLimit"] = toString(current_BlockHeader.gasLimit); + oBlockHeader["gasUsed"] = toString(current_BlockHeader.gasUsed); + oBlockHeader["timestamp"] = toString(current_BlockHeader.timestamp); + oBlockHeader["extraData"] = toHex(current_BlockHeader.extraData); + oBlockHeader["nonce"] = toString(current_BlockHeader.nonce); + + o["blockHeader"] = oBlockHeader; + + // write uncle list + mArray aUncleList; // as of now, our parent is always the genesis block, so we can not have uncles. + o["uncleHeaders"] = aUncleList; + //txs: RLPStream txStream; @@ -324,8 +316,6 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) txStream.appendRaw(txrlp.out()); } - cout << "create block:" << endl; - RLPStream rlpStream2; current_BlockHeader.streamRLP(rlpStream2, WithNonce); @@ -334,40 +324,45 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) block2.appendRaw(txStream.out()); block2.appendRaw(RLPEmptyList); + o["rlp"] = "0x" + toHex(block2.out()); + if (sha3(RLP(state.blockData())[0].data()) != sha3(RLP(block2.out())[0].data())) - cout << "block 0 wrong" << endl; + cnote << "block header mismatch\n"; if (sha3(RLP(state.blockData())[1].data()) != sha3(RLP(block2.out())[1].data())) - cout << "block 1 wrong" << endl; + cnote << "txs mismatch\n"; if (sha3(RLP(state.blockData())[2].data()) != sha3(RLP(block2.out())[2].data())) - cout << "block 2 wrong" << endl; + cnote << "uncle list mismatch\n"; - - if (sha3(state.blockData()) != sha3(block2.out())) + try { - cout << "blocks do not match!" << endl; - o["rlp"] = "0x" + toHex(block2.out()); + ImportTest importerTmp(o["pre"].get_obj()); + State stateTmp(Address(), OverlayDB(), BaseState::Empty); + importerTmp.importState(o["pre"].get_obj(), stateTmp); + stateTmp.commit(); + BlockChain bcTmp(block.out(), "/tmp/", true); + stateTmp.sync(bcTmp); + bc.import(block2.out(), stateTmp.db()); + stateTmp.sync(bcTmp); + } + // if exception is thrown, RLP is invalid and no blockHeader, Transaction list, or Uncle list should be given + catch (...) + { + cnote << "block is invalid!\n"; o.erase(o.find("blockHeader")); o.erase(o.find("uncleHeaders")); o.erase(o.find("transactions")); } - else - { - o["blockHeader"] = oBlockHeader; - - // write uncle list - mArray aUncleList; // as of now, our parent is always the genesis block, so we can not have uncles. - o["uncleHeaders"] = aUncleList; - } } else { + bytes blockRLP; try { state.sync(bc); - bytes blockRLP = importByteArray(o["rlp"].get_str()); + blockRLP = importByteArray(o["rlp"].get_str()); bc.import(blockRLP, state.db()); state.sync(bc); } @@ -378,7 +373,7 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) BOOST_CHECK(o.count("blockHeader") == 0); BOOST_CHECK(o.count("transactions") == 0); BOOST_CHECK(o.count("uncleHeaders") == 0); - return; + continue; } catch (std::exception const& _e) { @@ -386,7 +381,7 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) BOOST_CHECK(o.count("blockHeader") == 0); BOOST_CHECK(o.count("transactions") == 0); BOOST_CHECK(o.count("uncleHeaders") == 0); - return; + continue; } catch(...) { @@ -394,11 +389,10 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) BOOST_CHECK(o.count("blockHeader") == 0); BOOST_CHECK(o.count("transactions") == 0); BOOST_CHECK(o.count("uncleHeaders") == 0); - return; + continue; } - cout << "valid block header\n"; - //cout << "block number: " << - BOOST_REQUIRE(o.count("blockHeader") > 0); + + BOOST_REQUIRE(o.count("blockHeader")); mObject tObj = o["blockHeader"].get_obj(); BlockInfo blockHeaderFromFields; @@ -427,8 +421,6 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) BOOST_CHECK_MESSAGE(blockHeaderFromFields == blockFromRlp, "However, blockHeaderFromFields != blockFromRlp!"); - cout << "checked block header bc\n"; - //Check transaction list Transactions txsFromField; @@ -437,19 +429,16 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) { mObject tx = txObj.get_obj(); - cout << "read single tx\n"; - - BOOST_REQUIRE(tx.count("nonce") > 0); - BOOST_REQUIRE(tx.count("gasPrice") > 0); - BOOST_REQUIRE(tx.count("gasLimit") > 0); - BOOST_REQUIRE(tx.count("to") > 0); - BOOST_REQUIRE(tx.count("value") > 0); - BOOST_REQUIRE(tx.count("v") > 0); - BOOST_REQUIRE(tx.count("r") > 0); - BOOST_REQUIRE(tx.count("s") > 0); - BOOST_REQUIRE(tx.count("data") > 0); + BOOST_REQUIRE(tx.count("nonce")); + BOOST_REQUIRE(tx.count("gasPrice")); + BOOST_REQUIRE(tx.count("gasLimit")); + BOOST_REQUIRE(tx.count("to")); + BOOST_REQUIRE(tx.count("value")); + BOOST_REQUIRE(tx.count("v")); + BOOST_REQUIRE(tx.count("r")); + BOOST_REQUIRE(tx.count("s")); + BOOST_REQUIRE(tx.count("data")); - cout << "construct single tx\n"; try { Transaction t(createRLPStreamFromTransactionFields(tx).out(), CheckSignature::Sender); @@ -458,18 +447,14 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) catch (Exception const& _e) { BOOST_ERROR("Failed transaction constructor with Exception: " << diagnostic_information(_e)); - } catch (exception const& _e) { - cout << _e.what() << endl; + cnote << _e.what(); } } - cout << "read txs bc\n"; - Transactions txsFromRlp; - bytes blockRLP = importByteArray(o["rlp"].get_str()); RLP root(blockRLP); for (auto const& tr: root[1]) { @@ -491,12 +476,10 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) BOOST_CHECK_MESSAGE(txsFromField[i].receiveAddress() == txsFromRlp[i].receiveAddress(), "transaction receiveAddress in rlp and in field do not match"); BOOST_CHECK_MESSAGE(txsFromField[i].value() == txsFromRlp[i].value(), "transaction receiveAddress in rlp and in field do not match"); - BOOST_CHECK_MESSAGE(txsFromField[i] == txsFromRlp[i], "however, transactions in rlp and in field do not match"); + BOOST_CHECK_MESSAGE(txsFromField[i] == txsFromRlp[i], "transactions in rlp and in transaction field do not match"); } - cout << "checked txs bc\n"; // check uncle list - BOOST_CHECK_MESSAGE((o["uncleList"].type() == json_spirit::null_type ? 0 : o["uncleList"].get_array().size()) == 0, "Uncle list is not empty, but the genesis block can not have uncles"); } } @@ -507,9 +490,14 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) BOOST_AUTO_TEST_SUITE(BlockTests) -BOOST_AUTO_TEST_CASE(blValidBlockTest) +//BOOST_AUTO_TEST_CASE(blValidBlockTest) +//{ +// dev::test::executeTests("blValidBlockTest", "/BlockTests", dev::test::doBlockTests); +//} + +BOOST_AUTO_TEST_CASE(blInvalidHeaderTest) { - dev::test::executeTests("blValidBlockTest", "/BlockTests", dev::test::doBlockTests); + dev::test::executeTests("blInvalidHeaderTest", "/BlockTests", dev::test::doBlockTests); } BOOST_AUTO_TEST_CASE(userDefinedFileBl) From 6c3f9ba5024f5aaef1855089601ecd2a2f79c9ff Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Mon, 16 Feb 2015 11:06:22 +0100 Subject: [PATCH 189/213] add invalid block header tests --- test/blInvalidHeaderTestFiller.json | 736 ++++++++++++++++++++++++++++ test/blValidBlockTestFiller.json | 391 +++++++++++++-- test/block.cpp | 8 +- 3 files changed, 1083 insertions(+), 52 deletions(-) diff --git a/test/blInvalidHeaderTestFiller.json b/test/blInvalidHeaderTestFiller.json index e69de29bb..0a8000d0f 100644 --- a/test/blInvalidHeaderTestFiller.json +++ b/test/blInvalidHeaderTestFiller.json @@ -0,0 +1,736 @@ +{ + "log1_wrongBlockNumber" : { + "blockHeader" : { + "number" : "2" + }, + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "10000", + "extraData" : "42", + "gasLimit" : "100000", + "gasUsed" : "0", + "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000", + "nonce" : "0", + "code" : "", + "storage": {} + }, + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "100", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG1 0 32 0) }", + "storage": {} + } + }, + "transactions" : [ + { + "data" : "", + "gasLimit" : "5000", + "gasPrice" : "10", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "5000000000" + } + ], + "uncleHeaders" : [ + ] + }, + + "log1_wrongBloom" : { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + }, + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "10000", + "extraData" : "42", + "gasLimit" : "100000", + "gasUsed" : "0", + "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000", + "nonce" : "0", + "code" : "", + "storage": {} + }, + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "100", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG1 0 32 0) }", + "storage": {} + } + }, + "transactions" : [ + { + "data" : "", + "gasLimit" : "5000", + "gasPrice" : "10", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "5000000000" + } + ], + "uncleHeaders" : [ + ] + }, + + "wrongCoinbase" : { + "blockHeader" : { + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1" + }, + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "10000", + "extraData" : "42", + "gasLimit" : "100000", + "gasUsed" : "0", + "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000", + "nonce" : "0", + "code" : "", + "storage": {} + }, + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "100", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG1 0 32 0) }", + "storage": {} + } + }, + "transactions" : [ + { + "data" : "", + "gasLimit" : "5000", + "gasPrice" : "10", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "5000000000" + } + ], + "uncleHeaders" : [ + ] + }, + + "wrongDifficulty" : { + "blockHeader" : { + "difficulty" : "10000" + }, + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "10000", + "extraData" : "42", + "gasLimit" : "100000", + "gasUsed" : "0", + "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000", + "nonce" : "0", + "code" : "", + "storage": {} + }, + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "100", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG1 0 32 0) }", + "storage": {} + } + }, + "transactions" : [ + { + "data" : "", + "gasLimit" : "5000", + "gasPrice" : "10", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "5000000000" + } + ], + "uncleHeaders" : [ + ] + }, + + "wrongExtraData" : { + "blockHeader" : { + "extraData" : "42" + }, + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "10000", + "extraData" : "42", + "gasLimit" : "100000", + "gasUsed" : "0", + "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000", + "nonce" : "0", + "code" : "", + "storage": {} + }, + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "100", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG1 0 32 0) }", + "storage": {} + } + }, + "transactions" : [ + { + "data" : "", + "gasLimit" : "5000", + "gasPrice" : "10", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "5000000000" + } + ], + "uncleHeaders" : [ + ] + }, + + "wrongGasLimit" : { + "blockHeader" : { + "gasLimit" : "100000" + }, + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "10000", + "extraData" : "42", + "gasLimit" : "100000", + "gasUsed" : "0", + "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000", + "nonce" : "0", + "code" : "", + "storage": {} + }, + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "100", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG1 0 32 0) }", + "storage": {} + } + }, + "transactions" : [ + { + "data" : "", + "gasLimit" : "5000", + "gasPrice" : "10", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "5000000000" + } + ], + "uncleHeaders" : [ + ] + }, + + "wrongGasUsed" : { + "blockHeader" : { + "gasUsed" : "0" + }, + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "10000", + "extraData" : "42", + "gasLimit" : "100000", + "gasUsed" : "0", + "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000", + "nonce" : "0", + "code" : "", + "storage": {} + }, + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "100", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG1 0 32 0) }", + "storage": {} + } + }, + "transactions" : [ + { + "data" : "", + "gasLimit" : "5000", + "gasPrice" : "10", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "5000000000" + } + ], + "uncleHeaders" : [ + ] + }, + + "wrongNonce" : { + "blockHeader" : { + "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d" + }, + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "10000", + "extraData" : "42", + "gasLimit" : "100000", + "gasUsed" : "0", + "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000", + "nonce" : "0", + "code" : "", + "storage": {} + }, + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "100", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG1 0 32 0) }", + "storage": {} + } + }, + "transactions" : [ + { + "data" : "", + "gasLimit" : "5000", + "gasPrice" : "10", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "5000000000" + } + ], + "uncleHeaders" : [ + ] + }, + + "wrongNumber" : { + "blockHeader" : { + "number" : "0" + }, + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "10000", + "extraData" : "42", + "gasLimit" : "100000", + "gasUsed" : "0", + "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000", + "nonce" : "0", + "code" : "", + "storage": {} + }, + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "100", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG1 0 32 0) }", + "storage": {} + } + }, + "transactions" : [ + { + "data" : "", + "gasLimit" : "5000", + "gasPrice" : "10", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "5000000000" + } + ], + "uncleHeaders" : [ + ] + }, + + "wrongParentHash" : { + "blockHeader" : { + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "10000", + "extraData" : "42", + "gasLimit" : "100000", + "gasUsed" : "0", + "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000", + "nonce" : "0", + "code" : "", + "storage": {} + }, + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "100", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG1 0 32 0) }", + "storage": {} + } + }, + "transactions" : [ + { + "data" : "", + "gasLimit" : "5000", + "gasPrice" : "10", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "5000000000" + } + ], + "uncleHeaders" : [ + ] + }, + + "wrongReceiptTrie" : { + "blockHeader" : { + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" + }, + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "10000", + "extraData" : "42", + "gasLimit" : "100000", + "gasUsed" : "0", + "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000", + "nonce" : "0", + "code" : "", + "storage": {} + }, + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "100", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG1 0 32 0) }", + "storage": {} + } + }, + "transactions" : [ + { + "data" : "", + "gasLimit" : "5000", + "gasPrice" : "10", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "5000000000" + } + ], + "uncleHeaders" : [ + ] + }, + + "wrongStateRoot" : { + "blockHeader" : { + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a" + }, + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "10000", + "extraData" : "42", + "gasLimit" : "100000", + "gasUsed" : "0", + "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000", + "nonce" : "0", + "code" : "", + "storage": {} + }, + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "100", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG1 0 32 0) }", + "storage": {} + } + }, + "transactions" : [ + { + "data" : "", + "gasLimit" : "5000", + "gasPrice" : "10", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "5000000000" + } + ], + "uncleHeaders" : [ + ] + }, + + "wrongTimestamp" : { + "blockHeader" : { + "timestamp" : "0x54c98c80" + }, + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "10000", + "extraData" : "42", + "gasLimit" : "100000", + "gasUsed" : "0", + "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000", + "nonce" : "0", + "code" : "", + "storage": {} + }, + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "100", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG1 0 32 0) }", + "storage": {} + } + }, + "transactions" : [ + { + "data" : "", + "gasLimit" : "5000", + "gasPrice" : "10", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "5000000000" + } + ], + "uncleHeaders" : [ + ] + }, + + "wrongTransactionsTrie" : { + "blockHeader" : { + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" + }, + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "10000", + "extraData" : "42", + "gasLimit" : "100000", + "gasUsed" : "0", + "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000", + "nonce" : "0", + "code" : "", + "storage": {} + }, + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "100", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG1 0 32 0) }", + "storage": {} + } + }, + "transactions" : [ + { + "data" : "", + "gasLimit" : "5000", + "gasPrice" : "10", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "5000000000" + } + ], + "uncleHeaders" : [ + ] + }, + + "wrongUncleHash" : { + "blockHeader" : { + "uncleHash" : "0x0dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "10000", + "extraData" : "42", + "gasLimit" : "100000", + "gasUsed" : "0", + "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000", + "nonce" : "0", + "code" : "", + "storage": {} + }, + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "100", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG1 0 32 0) }", + "storage": {} + } + }, + "transactions" : [ + { + "data" : "", + "gasLimit" : "5000", + "gasPrice" : "10", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "5000000000" + } + ], + "uncleHeaders" : [ + ] + } +} diff --git a/test/blValidBlockTestFiller.json b/test/blValidBlockTestFiller.json index db7138b5b..b84573789 100644 --- a/test/blValidBlockTestFiller.json +++ b/test/blValidBlockTestFiller.json @@ -1,51 +1,346 @@ { - "log1" : { - "blockHeader" : { - "number" : "2" - }, - "genesisBlockHeader" : { - "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", - "difficulty" : "10000", - "extraData" : "42", - "gasLimit" : "100000", - "gasUsed" : "0", - "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", - "number" : "0", - "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", - "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", - "timestamp" : "0x54c98c81", - "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" - }, - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "10000000000", - "nonce" : "0", - "code" : "", - "storage": {} - }, - "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "100", - "nonce" : "0", - "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG1 0 32 0) }", - "storage": {} - } - }, - "transactions" : [ - { - "data" : "", - "gasLimit" : "5000", - "gasPrice" : "10", - "nonce" : "0", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "value" : "5000000000" - } - ], - "uncleHeaders" : [ - ] - } + "diffTooLowToChange" : { + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "1023", + "extraData" : "42", + "gasLimit" : "100000", + "gasUsed" : "0", + "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transactions" : [ + { + "data" : "", + "gasLimit" : "850", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + + "diff1024" : { + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "1024", + "extraData" : "42", + "gasLimit" : "100000", + "gasUsed" : "0", + "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transactions" : [ + { + "data" : "", + "gasLimit" : "850", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + + "gasPrice0" : { + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "10000", + "extraData" : "42", + "gasLimit" : "100000", + "gasUsed" : "0", + "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transactions" : [ + { + "data" : "", + "gasLimit" : "850", + "gasPrice" : "0", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + + "gasLimitTooHigh" : { + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "10000", + "extraData" : "42", + "gasLimit" : "1000000", + "gasUsed" : "0", + "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transactions" : [ + { + "data" : "", + "gasLimit" : "850", + "gasPrice" : "0", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + + "SimpleTx" : { + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "10000", + "extraData" : "42", + "gasLimit" : "100000", + "gasUsed" : "0", + "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transactions" : [ + { + "data" : "", + "gasLimit" : "500", + "gasPrice" : "10", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + + "txOrder" : { + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "10000", + "extraData" : "42", + "gasLimit" : "100000", + "gasUsed" : "0", + "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transactions" : [ + { + "data" : "", + "gasLimit" : "500", + "gasPrice" : "10", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "7000000000" + }, + { + "data" : "", + "gasLimit" : "500", + "gasPrice" : "10", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "8000000000" + } + ], + "uncleHeaders" : [ + ] + }, + + "txEqualValue" : { + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "10000", + "extraData" : "42", + "gasLimit" : "100000", + "gasUsed" : "0", + "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transactions" : [ + { + "data" : "", + "gasLimit" : "500", + "gasPrice" : "10", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "5000000000" + }, + { + "data" : "", + "gasLimit" : "500", + "gasPrice" : "9", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "5000000000" + } + ], + "uncleHeaders" : [ + ] + }, + + "log1_correct" : { + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "10000", + "extraData" : "42", + "gasLimit" : "100000", + "gasUsed" : "0", + "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000", + "nonce" : "0", + "code" : "", + "storage": {} + }, + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "100", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG1 0 32 0) }", + "storage": {} + } + }, + "transactions" : [ + { + "data" : "", + "gasLimit" : "5000", + "gasPrice" : "10", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "5000000000" + } + ], + "uncleHeaders" : [ + ] + } } diff --git a/test/block.cpp b/test/block.cpp index 891d89931..aa1790f71 100644 --- a/test/block.cpp +++ b/test/block.cpp @@ -490,10 +490,10 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) BOOST_AUTO_TEST_SUITE(BlockTests) -//BOOST_AUTO_TEST_CASE(blValidBlockTest) -//{ -// dev::test::executeTests("blValidBlockTest", "/BlockTests", dev::test::doBlockTests); -//} +BOOST_AUTO_TEST_CASE(blValidBlockTest) +{ + dev::test::executeTests("blValidBlockTest", "/BlockTests", dev::test::doBlockTests); +} BOOST_AUTO_TEST_CASE(blInvalidHeaderTest) { From 4de92be65b87220194d5e99cc418137e075afe01 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Mon, 16 Feb 2015 11:49:15 +0100 Subject: [PATCH 190/213] fix typo --- test/blInvalidHeaderTestFiller.json | 51 +---------------------------- test/block.cpp | 2 +- 2 files changed, 2 insertions(+), 51 deletions(-) diff --git a/test/blInvalidHeaderTestFiller.json b/test/blInvalidHeaderTestFiller.json index 0a8000d0f..482eafc56 100644 --- a/test/blInvalidHeaderTestFiller.json +++ b/test/blInvalidHeaderTestFiller.json @@ -195,7 +195,7 @@ ] }, - "wrongExtraData" : { + "DifferentExtraData" : { "blockHeader" : { "extraData" : "42" }, @@ -342,55 +342,6 @@ ] }, - "wrongNonce" : { - "blockHeader" : { - "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d" - }, - "genesisBlockHeader" : { - "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", - "difficulty" : "10000", - "extraData" : "42", - "gasLimit" : "100000", - "gasUsed" : "0", - "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", - "number" : "0", - "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", - "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", - "timestamp" : "0x54c98c81", - "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" - }, - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "10000000000", - "nonce" : "0", - "code" : "", - "storage": {} - }, - "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "100", - "nonce" : "0", - "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG1 0 32 0) }", - "storage": {} - } - }, - "transactions" : [ - { - "data" : "", - "gasLimit" : "5000", - "gasPrice" : "10", - "nonce" : "0", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "value" : "5000000000" - } - ], - "uncleHeaders" : [ - ] - }, - "wrongNumber" : { "blockHeader" : { "number" : "0" diff --git a/test/block.cpp b/test/block.cpp index aa1790f71..19dcdf84b 100644 --- a/test/block.cpp +++ b/test/block.cpp @@ -224,7 +224,7 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) if (o["blockHeader"].get_obj().count("parentHash")) tmp.parentHash = h256(o["blockHeader"].get_obj()["parentHash"].get_str()); - if (o["blockHeader"].get_obj().count("sha3Uncles")) + if (o["blockHeader"].get_obj().count("uncleHash")) tmp.sha3Uncles = h256(o["blockHeader"].get_obj()["uncleHash"].get_str()); if (o["blockHeader"].get_obj().count("coinbase")) From 792b47deba0f41b3cde8e05ba15642729f5e5184 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Mon, 16 Feb 2015 12:00:33 +0100 Subject: [PATCH 191/213] fix GasUsed bug --- libethcore/BlockInfo.cpp | 4 ++-- libethcore/Exceptions.h | 1 + libethereum/State.cpp | 7 +++++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/libethcore/BlockInfo.cpp b/libethcore/BlockInfo.cpp index 3d1bcaa2a..194837818 100644 --- a/libethcore/BlockInfo.cpp +++ b/libethcore/BlockInfo.cpp @@ -157,8 +157,8 @@ void BlockInfo::verifyInternals(bytesConstRef _block) const { bytes k = rlp(i); t.insert(&k, tr.data()); - u256 gp = tr[1].toInt(); - mgp = min(mgp, gp); + u256 gasprice = tr[1].toInt(); + mgp = min(mgp, gasprice); // the minimum gas price is not used for anything //TODO delete? ++i; } if (transactionsRoot != t.root()) diff --git a/libethcore/Exceptions.h b/libethcore/Exceptions.h index 6127a3d00..3fd62afbd 100644 --- a/libethcore/Exceptions.h +++ b/libethcore/Exceptions.h @@ -51,6 +51,7 @@ struct UncleTooOld: virtual dev::Exception {}; class UncleInChain: virtual public dev::Exception { public: UncleInChain(h256Set _uncles, h256 _block): m_uncles(_uncles), m_block(_block) {} h256Set m_uncles; h256 m_block; virtual const char* what() const noexcept; }; struct DuplicateUncleNonce: virtual dev::Exception {}; struct InvalidStateRoot: virtual dev::Exception {}; +struct InvalidGasUsed: virtual dev::Exception {}; class InvalidTransactionsHash: virtual public dev::Exception { public: InvalidTransactionsHash(h256 _head, h256 _real): m_head(_head), m_real(_real) {} h256 m_head; h256 m_real; virtual const char* what() const noexcept; }; struct InvalidTransaction: virtual dev::Exception {}; struct InvalidDifficulty: virtual dev::Exception {}; diff --git a/libethereum/State.cpp b/libethereum/State.cpp index beab32abb..5b9da0cdd 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -600,6 +600,13 @@ u256 State::enact(bytesConstRef _block, BlockChain const& _bc, bool _checkNonce) BOOST_THROW_EXCEPTION(InvalidStateRoot()); } + if (m_currentBlock.gasUsed != gasUsed()) + { + // Rollback the trie. + m_db.rollback(); + BOOST_THROW_EXCEPTION(InvalidGasUsed() << RequirementError(bigint(gasUsed()), bigint(m_currentBlock.gasUsed))); + } + return tdIncrease; } From bc54b1e5ba333bc5429c50940f24169ae1e5b453 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Mon, 16 Feb 2015 12:23:08 +0100 Subject: [PATCH 192/213] remove unnecessary function --- test/TestHelper.h | 1 - 1 file changed, 1 deletion(-) diff --git a/test/TestHelper.h b/test/TestHelper.h index f7df3a2c0..c4dde1a60 100644 --- a/test/TestHelper.h +++ b/test/TestHelper.h @@ -53,7 +53,6 @@ public: void importState(json_spirit::mObject& _o, eth::State& _state); void importTransaction(json_spirit::mObject& _o); void exportTest(bytes _output, eth::State& _statePost); - std::map getStateMap(eth::State& _state){return _state.m_cache;} eth::State m_statePre; eth::State m_statePost; From 7097255ec57083242cfad9d6376254324e7bbdb6 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Mon, 16 Feb 2015 13:04:28 +0100 Subject: [PATCH 193/213] OS independency by using file system --- test/blValidBlockTestFiller.json | 707 ++++++++++++++++--------------- test/block.cpp | 3 +- 2 files changed, 373 insertions(+), 337 deletions(-) diff --git a/test/blValidBlockTestFiller.json b/test/blValidBlockTestFiller.json index b84573789..8099c0dd6 100644 --- a/test/blValidBlockTestFiller.json +++ b/test/blValidBlockTestFiller.json @@ -1,346 +1,381 @@ { - "diffTooLowToChange" : { - "genesisBlockHeader" : { - "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", - "difficulty" : "1023", - "extraData" : "42", - "gasLimit" : "100000", - "gasUsed" : "0", - "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", - "number" : "0", - "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", - "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", - "timestamp" : "0x54c98c81", - "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" - }, - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "10000000000", - "nonce" : "0", - "code" : "", - "storage": {} - } - }, - "transactions" : [ - { - "data" : "", - "gasLimit" : "850", - "gasPrice" : "1", - "nonce" : "0", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "value" : "10" - } - ], - "uncleHeaders" : [ - ] - }, + "diffTooLowToChange" : { + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "1023", + "extraData" : "42", + "gasLimit" : "100000", + "gasUsed" : "0", + "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transactions" : [ + { + "data" : "", + "gasLimit" : "850", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, - "diff1024" : { - "genesisBlockHeader" : { - "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", - "difficulty" : "1024", - "extraData" : "42", - "gasLimit" : "100000", - "gasUsed" : "0", - "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", - "number" : "0", - "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", - "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", - "timestamp" : "0x54c98c81", - "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" - }, - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "10000000000", - "nonce" : "0", - "code" : "", - "storage": {} - } - }, - "transactions" : [ - { - "data" : "", - "gasLimit" : "850", - "gasPrice" : "1", - "nonce" : "0", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "value" : "10" - } - ], - "uncleHeaders" : [ - ] - }, + "diff1024" : { + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "1024", + "extraData" : "42", + "gasLimit" : "100000", + "gasUsed" : "0", + "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transactions" : [ + { + "data" : "", + "gasLimit" : "850", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, - "gasPrice0" : { - "genesisBlockHeader" : { - "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", - "difficulty" : "10000", - "extraData" : "42", - "gasLimit" : "100000", - "gasUsed" : "0", - "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", - "number" : "0", - "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", - "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", - "timestamp" : "0x54c98c81", - "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" - }, - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "10000000000", - "nonce" : "0", - "code" : "", - "storage": {} - } - }, - "transactions" : [ - { - "data" : "", - "gasLimit" : "850", - "gasPrice" : "0", - "nonce" : "0", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "value" : "10" - } - ], - "uncleHeaders" : [ - ] - }, + "gasPrice0" : { + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "10000", + "extraData" : "42", + "gasLimit" : "100000", + "gasUsed" : "0", + "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transactions" : [ + { + "data" : "", + "gasLimit" : "850", + "gasPrice" : "0", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, - "gasLimitTooHigh" : { - "genesisBlockHeader" : { - "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", - "difficulty" : "10000", - "extraData" : "42", - "gasLimit" : "1000000", - "gasUsed" : "0", - "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", - "number" : "0", - "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", - "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", - "timestamp" : "0x54c98c81", - "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" - }, - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "10000000000", - "nonce" : "0", - "code" : "", - "storage": {} - } - }, - "transactions" : [ - { - "data" : "", - "gasLimit" : "850", - "gasPrice" : "0", - "nonce" : "0", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "value" : "10" - } - ], - "uncleHeaders" : [ - ] - }, + "gasLimitTooHigh" : { + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "10000", + "extraData" : "42", + "gasLimit" : "1000000", + "gasUsed" : "0", + "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transactions" : [ + { + "data" : "", + "gasLimit" : "850", + "gasPrice" : "0", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, - "SimpleTx" : { - "genesisBlockHeader" : { - "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", - "difficulty" : "10000", - "extraData" : "42", - "gasLimit" : "100000", - "gasUsed" : "0", - "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", - "number" : "0", - "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", - "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", - "timestamp" : "0x54c98c81", - "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" - }, - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "10000000000", - "nonce" : "0", - "code" : "", - "storage": {} - } - }, - "transactions" : [ - { - "data" : "", - "gasLimit" : "500", - "gasPrice" : "10", - "nonce" : "0", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "value" : "10" - } - ], - "uncleHeaders" : [ - ] - }, + "SimpleTx" : { + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "10000", + "extraData" : "42", + "gasLimit" : "100000", + "gasUsed" : "0", + "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transactions" : [ + { + "data" : "", + "gasLimit" : "500", + "gasPrice" : "10", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, - "txOrder" : { - "genesisBlockHeader" : { - "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", - "difficulty" : "10000", - "extraData" : "42", - "gasLimit" : "100000", - "gasUsed" : "0", - "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", - "number" : "0", - "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", - "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", - "timestamp" : "0x54c98c81", - "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" - }, - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "10000000000", - "nonce" : "0", - "code" : "", - "storage": {} - } - }, - "transactions" : [ - { - "data" : "", - "gasLimit" : "500", - "gasPrice" : "10", - "nonce" : "0", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "value" : "7000000000" - }, - { - "data" : "", - "gasLimit" : "500", - "gasPrice" : "10", - "nonce" : "0", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "value" : "8000000000" - } - ], - "uncleHeaders" : [ - ] - }, + "txOrder" : { + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "10000", + "extraData" : "42", + "gasLimit" : "100000", + "gasUsed" : "0", + "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transactions" : [ + { + "data" : "", + "gasLimit" : "500", + "gasPrice" : "10", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "7000000000" + }, + { + "data" : "", + "gasLimit" : "500", + "gasPrice" : "10", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "8000000000" + } + ], + "uncleHeaders" : [ + ] + }, - "txEqualValue" : { - "genesisBlockHeader" : { - "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", - "difficulty" : "10000", - "extraData" : "42", - "gasLimit" : "100000", - "gasUsed" : "0", - "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", - "number" : "0", - "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", - "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", - "timestamp" : "0x54c98c81", - "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" - }, - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "10000000000", - "nonce" : "0", - "code" : "", - "storage": {} - } - }, - "transactions" : [ - { - "data" : "", - "gasLimit" : "500", - "gasPrice" : "10", - "nonce" : "0", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "value" : "5000000000" - }, - { - "data" : "", - "gasLimit" : "500", - "gasPrice" : "9", - "nonce" : "0", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "value" : "5000000000" - } - ], - "uncleHeaders" : [ - ] - }, + "txEqualValue" : { + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "10000", + "extraData" : "42", + "gasLimit" : "100000", + "gasUsed" : "0", + "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transactions" : [ + { + "data" : "", + "gasLimit" : "500", + "gasPrice" : "10", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "5000000000" + }, + { + "data" : "", + "gasLimit" : "500", + "gasPrice" : "9", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "5000000000" + } + ], + "uncleHeaders" : [ + ] + }, - "log1_correct" : { - "genesisBlockHeader" : { - "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", - "difficulty" : "10000", - "extraData" : "42", - "gasLimit" : "100000", - "gasUsed" : "0", - "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", - "number" : "0", - "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", - "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", - "timestamp" : "0x54c98c81", - "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" - }, - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "10000000000", - "nonce" : "0", - "code" : "", - "storage": {} - }, - "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "100", - "nonce" : "0", - "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG1 0 32 0) }", - "storage": {} - } - }, - "transactions" : [ - { - "data" : "", - "gasLimit" : "5000", - "gasPrice" : "10", - "nonce" : "0", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "value" : "5000000000" - } - ], - "uncleHeaders" : [ - ] - } + "log1_correct" : { + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "10000", + "extraData" : "42", + "gasLimit" : "100000", + "gasUsed" : "0", + "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000", + "nonce" : "0", + "code" : "", + "storage": {} + }, + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "100", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG1 0 32 0) }", + "storage": {} + } + }, + "transactions" : [ + { + "data" : "", + "gasLimit" : "5000", + "gasPrice" : "10", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "5000000000" + } + ], + "uncleHeaders" : [ + ], + + "firstBlockTest" : { + "block" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "023101", + "extraData" : "42", + "gasLimit" : "0x0dddb6", + "gasUsed" : "100", + "nonce" : "0x498e88f5c14b0b60d6e14ce9c6cc958cbe16a1df8dd90210e50d2d77562a348d", + "number" : "62", + "parentHash" : "0xefb4db878627027c81b3bb1c7dd3a18dae3914a49cdd24a3e40ab3bbfbb240c5", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "pre" : { + }, + "transactions" : [ + { + "data" : "0x60056013565b6101918061001d6000396000f35b3360008190555056006001600060e060020a6000350480630a874df61461003a57806341c0e1b514610058578063a02b161e14610066578063dbbdf0831461007757005b610045600435610149565b80600160a060020a031660005260206000f35b610060610161565b60006000f35b6100716004356100d4565b60006000f35b61008560043560243561008b565b60006000f35b600054600160a060020a031632600160a060020a031614156100ac576100b1565b6100d0565b8060018360005260205260406000208190555081600060005260206000a15b5050565b600054600160a060020a031633600160a060020a031614158015610118575033600160a060020a0316600182600052602052604060002054600160a060020a031614155b61012157610126565b610146565b600060018260005260205260406000208190555080600060005260206000a15b50565b60006001826000526020526040600020549050919050565b600054600160a060020a031633600160a060020a0316146101815761018f565b600054600160a060020a0316ff5b56", + "gasLimit" : "0x0f3e6f", + "gasPrice" : "0x09184e72a000", + "nonce" : "0", + "r" : "0xd4287e915ebac7a8af390560fa53c8f0b7f13802ba0393d7afa5823c2560ca89", + "s" : "0xae75db31a34f7e386ad459646de98ec3a1c88cc91b11620b4ffd86871f579942", + "to" : "", + "v" : "0x1b", + "value" : "" + } + ], + } + + } } diff --git a/test/block.cpp b/test/block.cpp index 19dcdf84b..ce165bc42 100644 --- a/test/block.cpp +++ b/test/block.cpp @@ -20,6 +20,7 @@ * block test functions. */ +#include #include #include "TestHelper.h" @@ -341,7 +342,7 @@ void doBlockTests(json_spirit::mValue& _v, bool _fillin) State stateTmp(Address(), OverlayDB(), BaseState::Empty); importerTmp.importState(o["pre"].get_obj(), stateTmp); stateTmp.commit(); - BlockChain bcTmp(block.out(), "/tmp/", true); + BlockChain bcTmp(block.out(), getDataDir() + "/tmpBlockChain.bc", true); stateTmp.sync(bcTmp); bc.import(block2.out(), stateTmp.db()); stateTmp.sync(bcTmp); From dd0744e8a341e0c29ae395348c0d8dae84bfb33e Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Mon, 16 Feb 2015 13:48:25 +0100 Subject: [PATCH 194/213] fixed #1022 --- alethzero/CMakeLists.txt | 2 +- eth/CMakeLists.txt | 2 +- exp/CMakeLists.txt | 2 +- libdevcore/CMakeLists.txt | 2 +- libdevcrypto/CMakeLists.txt | 2 +- libethcore/CMakeLists.txt | 2 +- libethereum/CMakeLists.txt | 2 +- libethereumx/CMakeLists.txt | 3 ++- libevm/CMakeLists.txt | 2 +- libevmcore/CMakeLists.txt | 2 +- liblll/CMakeLists.txt | 2 +- libnatspec/CMakeLists.txt | 2 +- libp2p/CMakeLists.txt | 2 +- libserpent/CMakeLists.txt | 2 +- libsolidity/CMakeLists.txt | 2 +- libweb3jsonrpc/CMakeLists.txt | 4 ++-- libwebthree/CMakeLists.txt | 2 +- libwhisper/CMakeLists.txt | 2 +- lllc/CMakeLists.txt | 2 +- mix/CMakeLists.txt | 2 +- neth/CMakeLists.txt | 2 +- sc/CMakeLists.txt | 2 +- solc/CMakeLists.txt | 2 +- test/CMakeLists.txt | 2 +- third/CMakeLists.txt | 2 +- 25 files changed, 27 insertions(+), 26 deletions(-) diff --git a/alethzero/CMakeLists.txt b/alethzero/CMakeLists.txt index 9e41260fe..008721518 100644 --- a/alethzero/CMakeLists.txt +++ b/alethzero/CMakeLists.txt @@ -10,8 +10,8 @@ endif() set(CMAKE_INCLUDE_CURRENT_DIR ON) aux_source_directory(. SRC_LIST) -include_directories(..) include_directories(BEFORE ${JSONCPP_INCLUDE_DIRS}) +include_directories(BEFORE ..) include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) qt5_wrap_ui(ui_Main.h Main.ui) diff --git a/eth/CMakeLists.txt b/eth/CMakeLists.txt index 31aa8df96..ed65862a4 100644 --- a/eth/CMakeLists.txt +++ b/eth/CMakeLists.txt @@ -3,9 +3,9 @@ set(CMAKE_AUTOMOC OFF) aux_source_directory(. SRC_LIST) +include_directories(BEFORE ..) include_directories(${Boost_INCLUDE_DIRS}) include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) -include_directories(..) set(EXECUTABLE eth) diff --git a/exp/CMakeLists.txt b/exp/CMakeLists.txt index d0aadc8ae..548f48da8 100644 --- a/exp/CMakeLists.txt +++ b/exp/CMakeLists.txt @@ -3,8 +3,8 @@ set(CMAKE_AUTOMOC OFF) aux_source_directory(. SRC_LIST) +include_directories(BEFORE ..) include_directories(${LEVELDB_INCLUDE_DIRS}) -include_directories(..) set(EXECUTABLE exp) diff --git a/libdevcore/CMakeLists.txt b/libdevcore/CMakeLists.txt index 40aa7ce24..e3851b7ce 100644 --- a/libdevcore/CMakeLists.txt +++ b/libdevcore/CMakeLists.txt @@ -12,8 +12,8 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") aux_source_directory(. SRC_LIST) +include_directories(BEFORE ..) include_directories(${Boost_INCLUDE_DIRS}) -include_directories(..) set(EXECUTABLE devcore) diff --git a/libdevcrypto/CMakeLists.txt b/libdevcrypto/CMakeLists.txt index 4cd6daf21..e3c3a1677 100644 --- a/libdevcrypto/CMakeLists.txt +++ b/libdevcrypto/CMakeLists.txt @@ -9,10 +9,10 @@ set(CMAKE_AUTOMOC OFF) aux_source_directory(. SRC_LIST) +include_directories(BEFORE ..) include_directories(${Boost_INCLUDE_DIRS}) include_directories(${CRYPTOPP_INCLUDE_DIRS}) include_directories(${LEVELDB_INCLUDE_DIRS}) -include_directories(..) set(EXECUTABLE devcrypto) diff --git a/libethcore/CMakeLists.txt b/libethcore/CMakeLists.txt index 984aa3ce5..920f9f652 100644 --- a/libethcore/CMakeLists.txt +++ b/libethcore/CMakeLists.txt @@ -9,8 +9,8 @@ set(CMAKE_AUTOMOC OFF) aux_source_directory(. SRC_LIST) +include_directories(BEFORE ..) include_directories(${Boost_INCLUDE_DIRS}) -include_directories(..) set(EXECUTABLE ethcore) diff --git a/libethereum/CMakeLists.txt b/libethereum/CMakeLists.txt index 3906074fd..86157fdc2 100644 --- a/libethereum/CMakeLists.txt +++ b/libethereum/CMakeLists.txt @@ -11,8 +11,8 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") aux_source_directory(. SRC_LIST) +include_directories(BEFORE ..) include_directories(${LEVELDB_INCLUDE_DIRS}) -include_directories(..) set(EXECUTABLE ethereum) diff --git a/libethereumx/CMakeLists.txt b/libethereumx/CMakeLists.txt index 4a3cdcda7..373ff8d71 100644 --- a/libethereumx/CMakeLists.txt +++ b/libethereumx/CMakeLists.txt @@ -4,7 +4,8 @@ set(CMAKE_AUTOMOC OFF) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") aux_source_directory(. SRC_LIST) -include_directories(..) + +include_directories(BEFORE ..) set(EXECUTABLE ethereumx) diff --git a/libevm/CMakeLists.txt b/libevm/CMakeLists.txt index 4af5eb175..b04df70ea 100644 --- a/libevm/CMakeLists.txt +++ b/libevm/CMakeLists.txt @@ -13,8 +13,8 @@ aux_source_directory(. SRC_LIST) # we may not use it in libevm, but one of our dependecies is including boost in header file # and windows is failing to build without that +include_directories(BEFORE ..) include_directories(${Boost_INCLUDE_DIRS}) -include_directories(..) set(EXECUTABLE evm) diff --git a/libevmcore/CMakeLists.txt b/libevmcore/CMakeLists.txt index 9727ee1c9..0f8494804 100644 --- a/libevmcore/CMakeLists.txt +++ b/libevmcore/CMakeLists.txt @@ -11,8 +11,8 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") aux_source_directory(. SRC_LIST) +include_directories(BEFORE ..) include_directories(${Boost_INCLUDE_DIRS}) -include_directories(..) set(EXECUTABLE evmcore) diff --git a/liblll/CMakeLists.txt b/liblll/CMakeLists.txt index fb79d5873..3b9dc6030 100644 --- a/liblll/CMakeLists.txt +++ b/liblll/CMakeLists.txt @@ -11,8 +11,8 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") aux_source_directory(. SRC_LIST) +include_directories(BEFORE ..) include_directories(${Boost_INCLUDE_DIRS}) -include_directories(..) set(EXECUTABLE lll) diff --git a/libnatspec/CMakeLists.txt b/libnatspec/CMakeLists.txt index b5bd7903e..af15d56a9 100644 --- a/libnatspec/CMakeLists.txt +++ b/libnatspec/CMakeLists.txt @@ -13,7 +13,7 @@ set(CMAKE_AUTOMOC OFF) set(CMAKE_INCLUDE_CURRENT_DIR ON) aux_source_directory(. SRC_LIST) -include_directories(..) +include_directories(BEFORE ..) set(EXECUTABLE natspec) diff --git a/libp2p/CMakeLists.txt b/libp2p/CMakeLists.txt index 6f3f6b712..83309be78 100644 --- a/libp2p/CMakeLists.txt +++ b/libp2p/CMakeLists.txt @@ -11,6 +11,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") aux_source_directory(. SRC_LIST) +include_directories(BEFORE ..) # we may not use it in libp2p, but one of our dependecies is including leveldb in header file # and windows is failing to build without that include_directories(${LEVELDB_INCLUDE_DIRS}) @@ -18,7 +19,6 @@ include_directories(${LEVELDB_INCLUDE_DIRS}) if (MINIUPNPC_FOUND) include_directories(${MINIUPNPC_INCLUDE_DIRS}) endif() -include_directories(..) set(EXECUTABLE p2p) diff --git a/libserpent/CMakeLists.txt b/libserpent/CMakeLists.txt index 1c5b8e147..45dfa339d 100644 --- a/libserpent/CMakeLists.txt +++ b/libserpent/CMakeLists.txt @@ -11,7 +11,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") aux_source_directory(. SRC_LIST) -include_directories(..) +include_directories(BEFORE ..) set(EXECUTABLE serpent) diff --git a/libsolidity/CMakeLists.txt b/libsolidity/CMakeLists.txt index cccc5e165..2b1059c69 100644 --- a/libsolidity/CMakeLists.txt +++ b/libsolidity/CMakeLists.txt @@ -11,8 +11,8 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") aux_source_directory(. SRC_LIST) -include_directories(..) include_directories(BEFORE ${JSONCPP_INCLUDE_DIRS}) +include_directories(BEFORE ..) include_directories(${Boost_INCLUDE_DIRS}) set(EXECUTABLE solidity) diff --git a/libweb3jsonrpc/CMakeLists.txt b/libweb3jsonrpc/CMakeLists.txt index 34df1633a..867dd7e7e 100644 --- a/libweb3jsonrpc/CMakeLists.txt +++ b/libweb3jsonrpc/CMakeLists.txt @@ -9,8 +9,8 @@ set(CMAKE_AUTOMOC OFF) aux_source_directory(. SRC_LIST) -include_directories(..) -include_directories(${JSONCPP_INCLUDE_DIRS}) +include_directories(BEFORE ${JSONCPP_INCLUDE_DIRS}) +include_directories(BEFORE ..) include_directories(${MHD_INCLUDE_DIRS}) include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) include_directories(${LEVELDB_INCLUDE_DIRS}) diff --git a/libwebthree/CMakeLists.txt b/libwebthree/CMakeLists.txt index 1d8f23918..f22d4f94f 100644 --- a/libwebthree/CMakeLists.txt +++ b/libwebthree/CMakeLists.txt @@ -11,8 +11,8 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") aux_source_directory(. SRC_LIST) +include_directories(BEFORE ..) include_directories(${LEVELDB_INCLUDE_DIRS}) -include_directories(..) set(EXECUTABLE webthree) diff --git a/libwhisper/CMakeLists.txt b/libwhisper/CMakeLists.txt index 79879922e..160347484 100644 --- a/libwhisper/CMakeLists.txt +++ b/libwhisper/CMakeLists.txt @@ -11,7 +11,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") aux_source_directory(. SRC_LIST) -include_directories(..) +include_directories(BEFORE ..) include_directories(${LEVELDB_INCLUDE_DIRS}) set(EXECUTABLE whisper) diff --git a/lllc/CMakeLists.txt b/lllc/CMakeLists.txt index 2157fea74..4fdbdb85f 100644 --- a/lllc/CMakeLists.txt +++ b/lllc/CMakeLists.txt @@ -3,8 +3,8 @@ set(CMAKE_AUTOMOC OFF) aux_source_directory(. SRC_LIST) -include_directories(..) include_directories(BEFORE ${JSONCPP_INCLUDE_DIRS}) +include_directories(BEFORE ..) include_directories(${Boost_INCLUDE_DIRS}) set(EXECUTABLE lllc) diff --git a/mix/CMakeLists.txt b/mix/CMakeLists.txt index 4390a4eb0..24f111909 100644 --- a/mix/CMakeLists.txt +++ b/mix/CMakeLists.txt @@ -11,8 +11,8 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) aux_source_directory(. SRC_LIST) -include_directories(..) include_directories(BEFORE ${JSONCPP_INCLUDE_DIRS}) +include_directories(BEFORE ..) find_package (Qt5WebEngine QUIET) qt5_add_resources(UI_RESOURCES res.qrc) diff --git a/neth/CMakeLists.txt b/neth/CMakeLists.txt index 4db3d2cf4..caf7d2f97 100644 --- a/neth/CMakeLists.txt +++ b/neth/CMakeLists.txt @@ -2,9 +2,9 @@ cmake_policy(SET CMP0015 NEW) aux_source_directory(. SRC_LIST) +include_directories(BEFORE ..) include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) include_directories(${LEVELDB_INCLUDE_DIRS}) -include_directories(..) set(EXECUTABLE neth) diff --git a/sc/CMakeLists.txt b/sc/CMakeLists.txt index ee638bb52..313a47fab 100644 --- a/sc/CMakeLists.txt +++ b/sc/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_policy(SET CMP0015 NEW) aux_source_directory(. SRC_LIST) -include_directories(..) +include_directories(BEFORE ..) set(EXECUTABLE sc) diff --git a/solc/CMakeLists.txt b/solc/CMakeLists.txt index 747effad0..d3a39dbc8 100644 --- a/solc/CMakeLists.txt +++ b/solc/CMakeLists.txt @@ -3,8 +3,8 @@ set(CMAKE_AUTOMOC OFF) aux_source_directory(. SRC_LIST) -include_directories(..) include_directories(BEFORE ${JSONCPP_INCLUDE_DIRS}) +include_directories(BEFORE ..) include_directories(${Boost_INCLUDE_DIRS}) set(EXECUTABLE solc) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 6ba07f280..bc14918b8 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -4,8 +4,8 @@ aux_source_directory(. SRC_LIST) list(REMOVE_ITEM SRC_LIST "./createRandomTest.cpp") list(REMOVE_ITEM SRC_LIST "./checkRandomTest.cpp") -include_directories(..) include_directories(BEFORE ${JSONCPP_INCLUDE_DIRS}) +include_directories(BEFORE ..) include_directories(${Boost_INCLUDE_DIRS}) include_directories(${CRYPTOPP_INCLUDE_DIRS}) include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) diff --git a/third/CMakeLists.txt b/third/CMakeLists.txt index 3f4981e29..bde47988b 100644 --- a/third/CMakeLists.txt +++ b/third/CMakeLists.txt @@ -10,8 +10,8 @@ endif() set(CMAKE_INCLUDE_CURRENT_DIR ON) aux_source_directory(. SRC_LIST) +include_directories(BEFORE ..) include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) -include_directories(..) qt5_wrap_ui(ui_Main.h Main.ui) From 7aa3f18bce36e6bbf385f67bbdb9253e21e2b34a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Mon, 16 Feb 2015 15:26:54 +0100 Subject: [PATCH 195/213] ManyFunctions performance test: ~200 functions in a contract, half of them are called randomly --- test/ManyFunctions.sol | 1485 +++++++++++++++++++++++++++++ test/ManyFunctionsGenerator.py | 24 + test/vmPerformanceTestFiller.json | 29 + 3 files changed, 1538 insertions(+) create mode 100644 test/ManyFunctions.sol create mode 100644 test/ManyFunctionsGenerator.py diff --git a/test/ManyFunctions.sol b/test/ManyFunctions.sol new file mode 100644 index 000000000..60dc61c42 --- /dev/null +++ b/test/ManyFunctions.sol @@ -0,0 +1,1485 @@ + + function right1(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^79) + return right2(r); + return left2(r); + } + + function left1(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^79) + return left2(r); + return right2(r); + } + + + function right2(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^80) + return right3(r); + return left3(r); + } + + function left2(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^80) + return left3(r); + return right3(r); + } + + + function right3(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^81) + return right4(r); + return left4(r); + } + + function left3(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^81) + return left4(r); + return right4(r); + } + + + function right4(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^82) + return right5(r); + return left5(r); + } + + function left4(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^82) + return left5(r); + return right5(r); + } + + + function right5(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^83) + return right6(r); + return left6(r); + } + + function left5(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^83) + return left6(r); + return right6(r); + } + + + function right6(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^84) + return right7(r); + return left7(r); + } + + function left6(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^84) + return left7(r); + return right7(r); + } + + + function right7(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^85) + return right8(r); + return left8(r); + } + + function left7(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^85) + return left8(r); + return right8(r); + } + + + function right8(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^86) + return right9(r); + return left9(r); + } + + function left8(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^86) + return left9(r); + return right9(r); + } + + + function right9(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^87) + return right10(r); + return left10(r); + } + + function left9(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^87) + return left10(r); + return right10(r); + } + + + function right10(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^88) + return right11(r); + return left11(r); + } + + function left10(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^88) + return left11(r); + return right11(r); + } + + + function right11(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^89) + return right12(r); + return left12(r); + } + + function left11(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^89) + return left12(r); + return right12(r); + } + + + function right12(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^90) + return right13(r); + return left13(r); + } + + function left12(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^90) + return left13(r); + return right13(r); + } + + + function right13(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^91) + return right14(r); + return left14(r); + } + + function left13(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^91) + return left14(r); + return right14(r); + } + + + function right14(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^92) + return right15(r); + return left15(r); + } + + function left14(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^92) + return left15(r); + return right15(r); + } + + + function right15(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^93) + return right16(r); + return left16(r); + } + + function left15(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^93) + return left16(r); + return right16(r); + } + + + function right16(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^94) + return right17(r); + return left17(r); + } + + function left16(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^94) + return left17(r); + return right17(r); + } + + + function right17(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^95) + return right18(r); + return left18(r); + } + + function left17(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^95) + return left18(r); + return right18(r); + } + + + function right18(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^96) + return right19(r); + return left19(r); + } + + function left18(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^96) + return left19(r); + return right19(r); + } + + + function right19(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^97) + return right20(r); + return left20(r); + } + + function left19(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^97) + return left20(r); + return right20(r); + } + + + function right20(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^98) + return right21(r); + return left21(r); + } + + function left20(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^98) + return left21(r); + return right21(r); + } + + + function right21(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^99) + return right22(r); + return left22(r); + } + + function left21(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^99) + return left22(r); + return right22(r); + } + + + function right22(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^100) + return right23(r); + return left23(r); + } + + function left22(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^100) + return left23(r); + return right23(r); + } + + + function right23(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^101) + return right24(r); + return left24(r); + } + + function left23(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^101) + return left24(r); + return right24(r); + } + + + function right24(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^102) + return right25(r); + return left25(r); + } + + function left24(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^102) + return left25(r); + return right25(r); + } + + + function right25(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^103) + return right26(r); + return left26(r); + } + + function left25(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^103) + return left26(r); + return right26(r); + } + + + function right26(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^104) + return right27(r); + return left27(r); + } + + function left26(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^104) + return left27(r); + return right27(r); + } + + + function right27(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^105) + return right28(r); + return left28(r); + } + + function left27(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^105) + return left28(r); + return right28(r); + } + + + function right28(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^106) + return right29(r); + return left29(r); + } + + function left28(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^106) + return left29(r); + return right29(r); + } + + + function right29(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^107) + return right30(r); + return left30(r); + } + + function left29(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^107) + return left30(r); + return right30(r); + } + + + function right30(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^108) + return right31(r); + return left31(r); + } + + function left30(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^108) + return left31(r); + return right31(r); + } + + + function right31(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^109) + return right32(r); + return left32(r); + } + + function left31(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^109) + return left32(r); + return right32(r); + } + + + function right32(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^110) + return right33(r); + return left33(r); + } + + function left32(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^110) + return left33(r); + return right33(r); + } + + + function right33(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^111) + return right34(r); + return left34(r); + } + + function left33(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^111) + return left34(r); + return right34(r); + } + + + function right34(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^112) + return right35(r); + return left35(r); + } + + function left34(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^112) + return left35(r); + return right35(r); + } + + + function right35(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^113) + return right36(r); + return left36(r); + } + + function left35(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^113) + return left36(r); + return right36(r); + } + + + function right36(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^114) + return right37(r); + return left37(r); + } + + function left36(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^114) + return left37(r); + return right37(r); + } + + + function right37(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^115) + return right38(r); + return left38(r); + } + + function left37(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^115) + return left38(r); + return right38(r); + } + + + function right38(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^116) + return right39(r); + return left39(r); + } + + function left38(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^116) + return left39(r); + return right39(r); + } + + + function right39(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^117) + return right40(r); + return left40(r); + } + + function left39(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^117) + return left40(r); + return right40(r); + } + + + function right40(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^118) + return right41(r); + return left41(r); + } + + function left40(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^118) + return left41(r); + return right41(r); + } + + + function right41(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^119) + return right42(r); + return left42(r); + } + + function left41(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^119) + return left42(r); + return right42(r); + } + + + function right42(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^120) + return right43(r); + return left43(r); + } + + function left42(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^120) + return left43(r); + return right43(r); + } + + + function right43(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^121) + return right44(r); + return left44(r); + } + + function left43(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^121) + return left44(r); + return right44(r); + } + + + function right44(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^122) + return right45(r); + return left45(r); + } + + function left44(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^122) + return left45(r); + return right45(r); + } + + + function right45(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^123) + return right46(r); + return left46(r); + } + + function left45(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^123) + return left46(r); + return right46(r); + } + + + function right46(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^124) + return right47(r); + return left47(r); + } + + function left46(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^124) + return left47(r); + return right47(r); + } + + + function right47(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^125) + return right48(r); + return left48(r); + } + + function left47(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^125) + return left48(r); + return right48(r); + } + + + function right48(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^126) + return right49(r); + return left49(r); + } + + function left48(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^126) + return left49(r); + return right49(r); + } + + + function right49(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^127) + return right50(r); + return left50(r); + } + + function left49(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^127) + return left50(r); + return right50(r); + } + + + function right50(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^128) + return right51(r); + return left51(r); + } + + function left50(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^128) + return left51(r); + return right51(r); + } + + + function right51(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^129) + return right52(r); + return left52(r); + } + + function left51(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^129) + return left52(r); + return right52(r); + } + + + function right52(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^130) + return right53(r); + return left53(r); + } + + function left52(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^130) + return left53(r); + return right53(r); + } + + + function right53(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^131) + return right54(r); + return left54(r); + } + + function left53(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^131) + return left54(r); + return right54(r); + } + + + function right54(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^132) + return right55(r); + return left55(r); + } + + function left54(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^132) + return left55(r); + return right55(r); + } + + + function right55(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^133) + return right56(r); + return left56(r); + } + + function left55(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^133) + return left56(r); + return right56(r); + } + + + function right56(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^134) + return right57(r); + return left57(r); + } + + function left56(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^134) + return left57(r); + return right57(r); + } + + + function right57(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^135) + return right58(r); + return left58(r); + } + + function left57(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^135) + return left58(r); + return right58(r); + } + + + function right58(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^136) + return right59(r); + return left59(r); + } + + function left58(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^136) + return left59(r); + return right59(r); + } + + + function right59(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^137) + return right60(r); + return left60(r); + } + + function left59(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^137) + return left60(r); + return right60(r); + } + + + function right60(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^138) + return right61(r); + return left61(r); + } + + function left60(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^138) + return left61(r); + return right61(r); + } + + + function right61(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^139) + return right62(r); + return left62(r); + } + + function left61(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^139) + return left62(r); + return right62(r); + } + + + function right62(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^140) + return right63(r); + return left63(r); + } + + function left62(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^140) + return left63(r); + return right63(r); + } + + + function right63(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^141) + return right64(r); + return left64(r); + } + + function left63(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^141) + return left64(r); + return right64(r); + } + + + function right64(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^142) + return right65(r); + return left65(r); + } + + function left64(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^142) + return left65(r); + return right65(r); + } + + + function right65(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^143) + return right66(r); + return left66(r); + } + + function left65(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^143) + return left66(r); + return right66(r); + } + + + function right66(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^144) + return right67(r); + return left67(r); + } + + function left66(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^144) + return left67(r); + return right67(r); + } + + + function right67(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^145) + return right68(r); + return left68(r); + } + + function left67(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^145) + return left68(r); + return right68(r); + } + + + function right68(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^146) + return right69(r); + return left69(r); + } + + function left68(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^146) + return left69(r); + return right69(r); + } + + + function right69(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^147) + return right70(r); + return left70(r); + } + + function left69(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^147) + return left70(r); + return right70(r); + } + + + function right70(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^148) + return right71(r); + return left71(r); + } + + function left70(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^148) + return left71(r); + return right71(r); + } + + + function right71(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^149) + return right72(r); + return left72(r); + } + + function left71(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^149) + return left72(r); + return right72(r); + } + + + function right72(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^150) + return right73(r); + return left73(r); + } + + function left72(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^150) + return left73(r); + return right73(r); + } + + + function right73(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^151) + return right74(r); + return left74(r); + } + + function left73(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^151) + return left74(r); + return right74(r); + } + + + function right74(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^152) + return right75(r); + return left75(r); + } + + function left74(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^152) + return left75(r); + return right75(r); + } + + + function right75(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^153) + return right76(r); + return left76(r); + } + + function left75(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^153) + return left76(r); + return right76(r); + } + + + function right76(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^154) + return right77(r); + return left77(r); + } + + function left76(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^154) + return left77(r); + return right77(r); + } + + + function right77(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^155) + return right78(r); + return left78(r); + } + + function left77(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^155) + return left78(r); + return right78(r); + } + + + function right78(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^156) + return right79(r); + return left79(r); + } + + function left78(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^156) + return left79(r); + return right79(r); + } + + + function right79(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^157) + return right80(r); + return left80(r); + } + + function left79(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^157) + return left80(r); + return right80(r); + } + + + function right80(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^158) + return right81(r); + return left81(r); + } + + function left80(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^158) + return left81(r); + return right81(r); + } + + + function right81(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^159) + return right82(r); + return left82(r); + } + + function left81(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^159) + return left82(r); + return right82(r); + } + + + function right82(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^160) + return right83(r); + return left83(r); + } + + function left82(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^160) + return left83(r); + return right83(r); + } + + + function right83(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^161) + return right84(r); + return left84(r); + } + + function left83(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^161) + return left84(r); + return right84(r); + } + + + function right84(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^162) + return right85(r); + return left85(r); + } + + function left84(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^162) + return left85(r); + return right85(r); + } + + + function right85(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^163) + return right86(r); + return left86(r); + } + + function left85(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^163) + return left86(r); + return right86(r); + } + + + function right86(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^164) + return right87(r); + return left87(r); + } + + function left86(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^164) + return left87(r); + return right87(r); + } + + + function right87(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^165) + return right88(r); + return left88(r); + } + + function left87(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^165) + return left88(r); + return right88(r); + } + + + function right88(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^166) + return right89(r); + return left89(r); + } + + function left88(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^166) + return left89(r); + return right89(r); + } + + + function right89(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^167) + return right90(r); + return left90(r); + } + + function left89(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^167) + return left90(r); + return right90(r); + } + + + function right90(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^168) + return right91(r); + return left91(r); + } + + function left90(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^168) + return left91(r); + return right91(r); + } + + + function right91(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^169) + return right92(r); + return left92(r); + } + + function left91(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^169) + return left92(r); + return right92(r); + } + + + function right92(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^170) + return right93(r); + return left93(r); + } + + function left92(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^170) + return left93(r); + return right93(r); + } + + + function right93(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^171) + return right94(r); + return left94(r); + } + + function left93(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^171) + return left94(r); + return right94(r); + } + + + function right94(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^172) + return right95(r); + return left95(r); + } + + function left94(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^172) + return left95(r); + return right95(r); + } + + + function right95(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^173) + return right96(r); + return left96(r); + } + + function left95(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^173) + return left96(r); + return right96(r); + } + + + function right96(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^174) + return right97(r); + return left97(r); + } + + function left96(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^174) + return left97(r); + return right97(r); + } + + + function right97(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^175) + return right98(r); + return left98(r); + } + + function left97(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^175) + return left98(r); + return right98(r); + } + + + function right98(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^176) + return right99(r); + return left99(r); + } + + function left98(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^176) + return left99(r); + return right99(r); + } + + + function right99(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2^177) + return right100(r); + return left100(r); + } + + function left99(uint seed) returns (uint) { + var r = nextRand(nextRand(seed)); + if (r >= 2^177) + return left100(r); + return right100(r); + } + diff --git a/test/ManyFunctionsGenerator.py b/test/ManyFunctionsGenerator.py new file mode 100644 index 000000000..93eef784c --- /dev/null +++ b/test/ManyFunctionsGenerator.py @@ -0,0 +1,24 @@ + +n = 100 + +splitNumBegin = 128 - (n / 2) +i = 1 + +template = """ + function right{0}(uint seed) returns (uint) {{ + var r = nextRand(seed); + if (r >= 2^{2}) + return right{1}(r); + return left{1}(r); + }} + + function left{0}(uint seed) returns (uint) {{ + var r = nextRand(nextRand(seed)); + if (r >= 2^{2}) + return left{1}(r); + return right{1}(r); + }} +""" + +for i in range(1, n): + print template.format(i, i + 1, i + splitNumBegin) \ No newline at end of file diff --git a/test/vmPerformanceTestFiller.json b/test/vmPerformanceTestFiller.json index 3292916ec..eab8a2240 100644 --- a/test/vmPerformanceTestFiller.json +++ b/test/vmPerformanceTestFiller.json @@ -1,4 +1,33 @@ { + "manyFunctions100": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "100000000000", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "//" : "ManyFunctions.sol", + "code" : "0x60e060020a60003504806301f99ad7146108c3578063023a624a146108d857806303bdecf5146108ed57806305fe035f14610902578063082d8f4914610917578063090bf3b71461092c5780630bd9c534146109415780630c4bfa94146109565780630e20ebe21461096b5780630f76de0d1461098057806310cfcc191461099557806313ce15a9146109aa578063140dcec4146109bf57806314d07a3e146109d45780631687f112146109e957806316eb6603146109fe578063172cf71714610a135780631bd6f59614610a285780631cdb857114610a3d5780631cf74ece14610a525780631d09ba2c14610a675780631f69aa5114610a7c578063223dcc7414610a9157806325e524d314610aa6578063261de7c414610abb5780632632924d14610ad05780632909cc5d14610ae55780632981699814610afa5780632a85a45d14610b0f5780632ca36da014610b245780632cbf1f0d14610b395780632d0f557314610b4e5780632d97867814610b6357806331db9efd14610b7857806332064db714610b8d57806332931fbb14610ba2578063355f51a014610bb7578063361bb34014610bcc578063364ddb0e14610be15780633792a01814610bf657806338c68f8f14610c0b57806338e586fd14610c20578063392d42ae14610c3557806339a87bd914610c4a5780633a95a33214610c5f5780633b8ecdf914610c745780633cf0659a14610c895780633eaf992314610c9e5780633fe97ead14610cb35780633ff11c8b14610cc8578063404efc5314610cdd578063407fce7b14610cf257806340c3b18714610d07578063440208c314610d1c57806344e86b2f14610d31578063455df57914610d465780634689ab4d14610d5b57806346be2e0c14610d70578063487cd86f14610d8557806348e6178214610d9a57806349d4a34414610daf5780634a0f597414610dc45780634bc24ec514610dd95780634c2fe45614610dee5780634cc885d414610e035780634eaaad7b14610e185780634eb166af14610e2d5780635050093414610e42578063506bff1114610e57578063508762c114610e6c578063526938f814610e8157806354400c6014610e96578063559510d814610eab57806355a5f70214610ec057806356ca528f14610ed5578063570a2a1614610eea5780635dab2e0f14610eff5780635dca53d314610f1457806362017ebc14610f29578063621a25f814610f3e578063626d4a3614610f5357806362b6a28214610f6857806364faf22c14610f7d57806366d7ffde14610f9257806367b886e814610fa757806367e902c714610fbc57806369d7774014610fd15780636b7ae8e614610fe65780636c3b659114610ffb5780636e54181e146110105780636e978d91146110255780636f63d2ec1461103a578063706332d11461104f57806370ac4bb9146110645780637138ef521461107957806371dd46a91461108e57806372a7c229146110a35780637376fc8d146110b8578063738a2679146110cd57806374552650146110e2578063746fc8d0146110f757806379254bb81461110c5780637adaa3f8146111215780637e4eb35b14611136578063885ec18e1461114b5780638b9ff6b6146111605780638ce113dc146111755780638defbc5e1461118a5780638f4613d51461119f5780638fdc24ba146111b45780639002dba4146111c957806391d15735146111de57806391d43b23146111f357806393b14daa1461120857806394d63afd1461121d57806395805dad1461123257806396f68782146112475780639740e4a21461125c578063981290131461127157806399a3f0e8146112865780639acb1ad41461129b5780639be07908146112b05780639c15be0b146112c55780639d451c4d146112da5780639d8ee943146112ef5780639ef6ca0f14611304578063a0db0a2214611319578063a18e2eb91461132e578063a408384914611343578063a57544da14611358578063a5a83e4d1461136d578063a6843f3414611382578063a6dacdd714611397578063a8c4c8bc146113ac578063aa058a73146113c1578063aad62da2146113d6578063aaf3e4f4146113eb578063ab81e77314611400578063abc93aee14611415578063abde33f71461142a578063b114b96c1461143f578063b3df873714611454578063b4174cb014611469578063b5d02a561461147e578063b731e84814611493578063b7b96723146114a8578063bbcded7a146114bd578063bbececa9146114d2578063beca7440146114e7578063bf8981c0146114fc578063c028c67414611511578063c2385fa614611526578063c319a02c1461153b578063c569bae014611550578063c6715f8114611565578063c7b98dec1461157a578063c9acab841461158f578063ca9efc73146115a4578063cad80024146115b9578063cdadb0fa146115ce578063cdbdf391146115e3578063cf460fa5146115f8578063cf69318a1461160d578063d1835b8c14611622578063d353a1cb14611637578063d3e141e01461164c578063d5ec7e1d14611661578063d7ead1de14611676578063d90b02aa1461168b578063d959e244146116a0578063d9e68b44146116b5578063daacb24f146116ca578063dc12a805146116df578063dd946033146116f4578063dda5142414611709578063de6612171461171e578063dfb9560c14611733578063e03827d214611748578063e21720001461175d578063e2c718d814611772578063e3da539914611787578063e48e603f1461179c578063e5f9ec29146117b1578063e6c0459a146117c6578063e70addec146117db578063e7a01215146117f0578063ea7f4d2714611805578063ebb6c59f1461181a578063ed6302be1461182f578063ed64b36b14611844578063eecd278914611859578063f0ed14e01461186e578063f0f2134414611883578063f1e328f914611898578063f1e6f4cd146118ad578063f32fe995146118c2578063f75165c6146118d7578063f7ed71d0146118ec578063f80f44f314611901578063f8bc050514611916578063fbd3c51a1461192b578063fd72009014611940578063fed3a3001461195557005b6108ce600435611e83565b8060005260206000f35b6108e3600435611f50565b8060005260206000f35b6108f8600435613deb565b8060005260206000f35b61090d6004356119e8565b8060005260206000f35b610922600435612f82565b8060005260206000f35b6109376004356128fb565b8060005260206000f35b61094c60043561304f565b8060005260206000f35b61096160043561209b565b8060005260206000f35b610976600435614c0d565b8060005260206000f35b61098b60043561319a565b8060005260206000f35b6109a06004356122b3565b8060005260206000f35b6109b5600435613d1e565b8060005260206000f35b6109ca600435612598565b8060005260206000f35b6109df600435612875565b8060005260206000f35b6109f4600435613650565b8060005260206000f35b610a096004356133f9565b8060005260206000f35b610a1e6004356136d6565b8060005260206000f35b610a3360043561371d565b8060005260206000f35b610a48600435611ad9565b8060005260206000f35b610a5d60043561375c565b8060005260206000f35b610a72600435612168565b8060005260206000f35b610a8760043561425a565b8060005260206000f35b610a9c600435612121565b8060005260206000f35b610ab1600435611dbe565b8060005260206000f35b610ac6600435612b13565b8060005260206000f35b610adb600435612981565b8060005260206000f35b610af060043561222d565b8060005260206000f35b610b05600435613ac7565b8060005260206000f35b610b1a600435612db1565b8060005260206000f35b610b2f600435612e76565b8060005260206000f35b610b44600435613a80565b8060005260206000f35b610b59600435612c1f565b8060005260206000f35b610b6e6004356125d7565b8060005260206000f35b610b836004356147dd565b8060005260206000f35b610b98600435612445565b8060005260206000f35b610bad600435611a53565b8060005260206000f35b610bc2600435613373565b8060005260206000f35b610bd760043561332c565b8060005260206000f35b610bec600435613544565b8060005260206000f35b610c01600435611dfd565b8060005260206000f35b610c166004356145c5565b8060005260206000f35b610c2b600435611c2c565b8060005260206000f35b610c40600435612df0565b8060005260206000f35b610c55600435612a46565b8060005260206000f35b610c6a6004356137e2565b8060005260206000f35b610c7f600435611b20565b8060005260206000f35b610c946004356126a4565b8060005260206000f35b610ca9600435613d65565b8060005260206000f35b610cbe6004356133b2565b8060005260206000f35b610cd360043561464b565b8060005260206000f35b610ce8600435612769565b8060005260206000f35b610cfd600435612015565b8060005260206000f35b610d12600435612d6a565b8060005260206000f35b610d27600435611fd6565b8060005260206000f35b610d3c600435613f36565b8060005260206000f35b610d51600435614604565b8060005260206000f35b610d6660043561248c565b8060005260206000f35b610d7b600435612acc565b8060005260206000f35b610d90600435612b99565b8060005260206000f35b610da5600435611be5565b8060005260206000f35b610dba6004356129c8565b8060005260206000f35b610dcf6004356127ef565b8060005260206000f35b610de46004356139bb565b8060005260206000f35b610df9600435614b01565b8060005260206000f35b610e0e600435613bd3565b8060005260206000f35b610e23600435613fbc565b8060005260206000f35b610e38600435614003565b8060005260206000f35b610e4d600435612836565b8060005260206000f35b610e62600435611d77565b8060005260206000f35b610e77600435611eca565b8060005260206000f35b610e8c600435612c5e565b8060005260206000f35b610ea1600435612380565b8060005260206000f35b610eb66004356135ca565b8060005260206000f35b610ecb60043561315b565b8060005260206000f35b610ee06004356122fa565b8060005260206000f35b610ef560043561358b565b8060005260206000f35b610f0a6004356144f8565b8060005260206000f35b610f1f600435612942565b8060005260206000f35b610f34600435613220565b8060005260206000f35b610f49600435613c59565b8060005260206000f35b610f5e600435613697565b8060005260206000f35b610f73600435613008565b8060005260206000f35b610f88600435612339565b8060005260206000f35b610f9d60043561265d565b8060005260206000f35b610fb2600435614cd2565b8060005260206000f35b610fc76004356149f5565b8060005260206000f35b610fdc600435614a34565b8060005260206000f35b610ff16004356140c8565b8060005260206000f35b61100660043561453f565b8060005260206000f35b61101b60043561410f565b8060005260206000f35b6110306004356148e9565b8060005260206000f35b611045600435613c98565b8060005260206000f35b61105a6004356131e1565b8060005260206000f35b61106f600435612a8d565b8060005260206000f35b611084600435611e44565b8060005260206000f35b6110996004356123bf565b8060005260206000f35b6110ae600435612f43565b8060005260206000f35b6110c3600435613cdf565b8060005260206000f35b6110d860043561468a565b8060005260206000f35b6110ed600435614bc6565b8060005260206000f35b611102600435613267565b8060005260206000f35b6111176004356128bc565b8060005260206000f35b61112c600435612e37565b8060005260206000f35b61114160043561308e565b8060005260206000f35b611156600435611cf1565b8060005260206000f35b61116b6004356149ae565b8060005260206000f35b611180600435613935565b8060005260206000f35b611195600435612a07565b8060005260206000f35b6111aa600435611f09565b8060005260206000f35b6111bf600435614b40565b8060005260206000f35b6111d4600435612274565b8060005260206000f35b6111e9600435611f8f565b8060005260206000f35b6111fe600435614195565b8060005260206000f35b6112136004356120e2565b8060005260206000f35b611228600435611b5f565b8060005260206000f35b61123d60043561196a565b8060005260206000f35b611252600435613a41565b8060005260206000f35b611267600435614796565b8060005260206000f35b61127c6004356132a6565b8060005260206000f35b611291600435613e71565b8060005260206000f35b6112a6600435612d2b565b8060005260206000f35b6112bb600435614366565b8060005260206000f35b6112d0600435613c12565b8060005260206000f35b6112e560043561421b565b8060005260206000f35b6112fa600435613ef7565b8060005260206000f35b61130f600435612b52565b8060005260206000f35b611324600435611ba6565b8060005260206000f35b611339600435613e2a565b8060005260206000f35b61134e6004356130d5565b8060005260206000f35b611363600435612ca5565b8060005260206000f35b61137860043561496f565b8060005260206000f35b61138d6004356132ed565b8060005260206000f35b6113a26004356138af565b8060005260206000f35b6113b7600435613b4d565b8060005260206000f35b6113cc600435611cb2565b8060005260206000f35b6113e16004356148a2565b8060005260206000f35b6113f660043561481c565b8060005260206000f35b61140b6004356139fa565b8060005260206000f35b611420600435613b8c565b8060005260206000f35b61143560043561272a565b8060005260206000f35b61144a600435614d9f565b8060005260206000f35b61145f600435613438565b8060005260206000f35b61147460043561347f565b8060005260206000f35b6114896004356119b3565b8060005260206000f35b61149e600435614aba565b8060005260206000f35b6114b3600435611d38565b8060005260206000f35b6114c8600435614042565b8060005260206000f35b6114dd6004356142e0565b8060005260206000f35b6114f2600435613505565b8060005260206000f35b611507600435612ce4565b8060005260206000f35b61151c6004356144b9565b8060005260206000f35b6115316004356142a1565b8060005260206000f35b611546600435614d19565b8060005260206000f35b61155b600435614a7b565b8060005260206000f35b611570600435613114565b8060005260206000f35b611585600435611a14565b8060005260206000f35b61159a6004356138ee565b8060005260206000f35b6115af600435614472565b8060005260206000f35b6115c4600435613868565b8060005260206000f35b6115d9600435613829565b8060005260206000f35b6115ee600435612bd8565b8060005260206000f35b6116036004356121ee565b8060005260206000f35b611618600435613974565b8060005260206000f35b61162d6004356124cb565b8060005260206000f35b6116426004356119a9565b8060005260206000f35b611657600435611c6b565b8060005260206000f35b61166c600435612551565b8060005260206000f35b611681600435614089565b8060005260206000f35b6116966004356143ec565b8060005260206000f35b6116ab6004356126e3565b8060005260206000f35b6116c06004356119fa565b8060005260206000f35b6116d5600435612fc9565b8060005260206000f35b6116ea6004356137a3565b8060005260206000f35b6116ff600435614433565b8060005260206000f35b6117146004356143ad565b8060005260206000f35b61172960043561414e565b8060005260206000f35b61173e60043561261e565b8060005260206000f35b611753600435613eb0565b8060005260206000f35b611768600435613b06565b8060005260206000f35b61177d600435612406565b8060005260206000f35b611792600435614928565b8060005260206000f35b6117a7600435613611565b8060005260206000f35b6117bc6004356134be565b8060005260206000f35b6117d1600435614327565b8060005260206000f35b6117e6600435614757565b8060005260206000f35b6117fb600435611a9a565b8060005260206000f35b61181060043561205c565b8060005260206000f35b611825600435613f7d565b8060005260206000f35b61183a600435614d58565b8060005260206000f35b61184f6004356121a7565b8060005260206000f35b611864600435614710565b8060005260206000f35b611879600435614b87565b8060005260206000f35b61188e6004356127b0565b8060005260206000f35b6118a3600435613da4565b8060005260206000f35b6118b8600435612ebd565b8060005260206000f35b6118cd600435614c4c565b8060005260206000f35b6118e2600435612512565b8060005260206000f35b6118f7600435612efc565b8060005260206000f35b61190c600435614c93565b8060005260206000f35b6119216004356141d4565b8060005260206000f35b61193660043561457e565b8060005260206000f35b61194b6004356146d1565b8060005260206000f35b611960600435614863565b8060005260206000f35b60006000611977836119b3565b9050604c81101561198757611997565b61199081611a53565b91506119a3565b6119a081611a14565b91505b50919050565b6000819050919050565b600060007f5851f42d4c957f2c0000000000000000000000000000000000000000000000019050828102600101915050919050565b60006119f3826119a9565b9050919050565b6000611a0d611a08836119b3565b6119a9565b9050919050565b60006000611a21836119b3565b9050604d811015611a3157611a41565b611a3a81611a9a565b9150611a4d565b611a4a81611ad9565b91505b50919050565b60006000611a68611a63846119b3565b6119b3565b9050604d811015611a7857611a88565b611a8181611ad9565b9150611a94565b611a9181611a9a565b91505b50919050565b60006000611aa7836119b3565b90506052811015611ab757611ac7565b611ac081611b20565b9150611ad3565b611ad081611b5f565b91505b50919050565b60006000611aee611ae9846119b3565b6119b3565b90506052811015611afe57611b0e565b611b0781611b5f565b9150611b1a565b611b1781611b20565b91505b50919050565b60006000611b2d836119b3565b90506053811015611b3d57611b4d565b611b4681611ba6565b9150611b59565b611b5681611be5565b91505b50919050565b60006000611b74611b6f846119b3565b6119b3565b90506053811015611b8457611b94565b611b8d81611be5565b9150611ba0565b611b9d81611ba6565b91505b50919050565b60006000611bb3836119b3565b90506050811015611bc357611bd3565b611bcc81611c2c565b9150611bdf565b611bdc81611c6b565b91505b50919050565b60006000611bfa611bf5846119b3565b6119b3565b90506050811015611c0a57611c1a565b611c1381611c6b565b9150611c26565b611c2381611c2c565b91505b50919050565b60006000611c39836119b3565b90506051811015611c4957611c59565b611c5281611cb2565b9150611c65565b611c6281611cf1565b91505b50919050565b60006000611c80611c7b846119b3565b6119b3565b90506051811015611c9057611ca0565b611c9981611cf1565b9150611cac565b611ca981611cb2565b91505b50919050565b60006000611cbf836119b3565b90506056811015611ccf57611cdf565b611cd881611d38565b9150611ceb565b611ce881611d77565b91505b50919050565b60006000611d06611d01846119b3565b6119b3565b90506056811015611d1657611d26565b611d1f81611d77565b9150611d32565b611d2f81611d38565b91505b50919050565b60006000611d45836119b3565b90506057811015611d5557611d65565b611d5e81611dbe565b9150611d71565b611d6e81611dfd565b91505b50919050565b60006000611d8c611d87846119b3565b6119b3565b90506057811015611d9c57611dac565b611da581611dfd565b9150611db8565b611db581611dbe565b91505b50919050565b60006000611dcb836119b3565b90506054811015611ddb57611deb565b611de481611e44565b9150611df7565b611df481611e83565b91505b50919050565b60006000611e12611e0d846119b3565b6119b3565b90506054811015611e2257611e32565b611e2b81611e83565b9150611e3e565b611e3b81611e44565b91505b50919050565b60006000611e51836119b3565b90506055811015611e6157611e71565b611e6a81611eca565b9150611e7d565b611e7a81611f09565b91505b50919050565b60006000611e98611e93846119b3565b6119b3565b90506055811015611ea857611eb8565b611eb181611f09565b9150611ec4565b611ec181611eca565b91505b50919050565b60006000611ed7836119b3565b9050605a811015611ee757611ef7565b611ef081611f50565b9150611f03565b611f0081611f8f565b91505b50919050565b60006000611f1e611f19846119b3565b6119b3565b9050605a811015611f2e57611f3e565b611f3781611f8f565b9150611f4a565b611f4781611f50565b91505b50919050565b60006000611f5d836119b3565b9050605b811015611f6d57611f7d565b611f7681611fd6565b9150611f89565b611f8681612015565b91505b50919050565b60006000611fa4611f9f846119b3565b6119b3565b9050605b811015611fb457611fc4565b611fbd81612015565b9150611fd0565b611fcd81611fd6565b91505b50919050565b60006000611fe3836119b3565b90506058811015611ff357612003565b611ffc8161205c565b915061200f565b61200c8161209b565b91505b50919050565b6000600061202a612025846119b3565b6119b3565b9050605881101561203a5761204a565b6120438161209b565b9150612056565b6120538161205c565b91505b50919050565b60006000612069836119b3565b9050605981101561207957612089565b612082816120e2565b9150612095565b61209281612121565b91505b50919050565b600060006120b06120ab846119b3565b6119b3565b905060598110156120c0576120d0565b6120c981612121565b91506120dc565b6120d9816120e2565b91505b50919050565b600060006120ef836119b3565b9050605e8110156120ff5761210f565b61210881612168565b915061211b565b612118816121a7565b91505b50919050565b60006000612136612131846119b3565b6119b3565b9050605e81101561214657612156565b61214f816121a7565b9150612162565b61215f81612168565b91505b50919050565b60006000612175836119b3565b9050605f81101561218557612195565b61218e816121ee565b91506121a1565b61219e8161222d565b91505b50919050565b600060006121bc6121b7846119b3565b6119b3565b9050605f8110156121cc576121dc565b6121d58161222d565b91506121e8565b6121e5816121ee565b91505b50919050565b600060006121fb836119b3565b9050605c81101561220b5761221b565b61221481612274565b9150612227565b612224816122b3565b91505b50919050565b6000600061224261223d846119b3565b6119b3565b9050605c81101561225257612262565b61225b816122b3565b915061226e565b61226b81612274565b91505b50919050565b60006000612281836119b3565b9050605d811015612291576122a1565b61229a816122fa565b91506122ad565b6122aa81612339565b91505b50919050565b600060006122c86122c3846119b3565b6119b3565b9050605d8110156122d8576122e8565b6122e181612339565b91506122f4565b6122f1816122fa565b91505b50919050565b60006000612307836119b3565b9050606281101561231757612327565b61232081612380565b9150612333565b612330816123bf565b91505b50919050565b6000600061234e612349846119b3565b6119b3565b9050606281101561235e5761236e565b612367816123bf565b915061237a565b61237781612380565b91505b50919050565b6000600061238d836119b3565b9050606381101561239d576123ad565b6123a681612406565b91506123b9565b6123b681612445565b91505b50919050565b600060006123d46123cf846119b3565b6119b3565b905060638110156123e4576123f4565b6123ed81612445565b9150612400565b6123fd81612406565b91505b50919050565b60006000612413836119b3565b9050606081101561242357612433565b61242c8161248c565b915061243f565b61243c816124cb565b91505b50919050565b6000600061245a612455846119b3565b6119b3565b9050606081101561246a5761247a565b612473816124cb565b9150612486565b6124838161248c565b91505b50919050565b60006000612499836119b3565b905060618110156124a9576124b9565b6124b281612512565b91506124c5565b6124c281612551565b91505b50919050565b600060006124e06124db846119b3565b6119b3565b905060618110156124f057612500565b6124f981612551565b915061250c565b61250981612512565b91505b50919050565b6000600061251f836119b3565b9050606681101561252f5761253f565b61253881612598565b915061254b565b612548816125d7565b91505b50919050565b60006000612566612561846119b3565b6119b3565b9050606681101561257657612586565b61257f816125d7565b9150612592565b61258f81612598565b91505b50919050565b600060006125a5836119b3565b905060678110156125b5576125c5565b6125be8161261e565b91506125d1565b6125ce8161265d565b91505b50919050565b600060006125ec6125e7846119b3565b6119b3565b905060678110156125fc5761260c565b6126058161265d565b9150612618565b6126158161261e565b91505b50919050565b6000600061262b836119b3565b9050606481101561263b5761264b565b612644816126a4565b9150612657565b612654816126e3565b91505b50919050565b6000600061267261266d846119b3565b6119b3565b9050606481101561268257612692565b61268b816126e3565b915061269e565b61269b816126a4565b91505b50919050565b600060006126b1836119b3565b905060658110156126c1576126d1565b6126ca8161272a565b91506126dd565b6126da81612769565b91505b50919050565b600060006126f86126f3846119b3565b6119b3565b9050606581101561270857612718565b61271181612769565b9150612724565b6127218161272a565b91505b50919050565b60006000612737836119b3565b9050606a81101561274757612757565b612750816127b0565b9150612763565b612760816127ef565b91505b50919050565b6000600061277e612779846119b3565b6119b3565b9050606a81101561278e5761279e565b612797816127ef565b91506127aa565b6127a7816127b0565b91505b50919050565b600060006127bd836119b3565b9050606b8110156127cd576127dd565b6127d681612836565b91506127e9565b6127e681612875565b91505b50919050565b600060006128046127ff846119b3565b6119b3565b9050606b81101561281457612824565b61281d81612875565b9150612830565b61282d81612836565b91505b50919050565b60006000612843836119b3565b9050606881101561285357612863565b61285c816128bc565b915061286f565b61286c816128fb565b91505b50919050565b6000600061288a612885846119b3565b6119b3565b9050606881101561289a576128aa565b6128a3816128fb565b91506128b6565b6128b3816128bc565b91505b50919050565b600060006128c9836119b3565b905060698110156128d9576128e9565b6128e281612942565b91506128f5565b6128f281612981565b91505b50919050565b6000600061291061290b846119b3565b6119b3565b9050606981101561292057612930565b61292981612981565b915061293c565b61293981612942565b91505b50919050565b6000600061294f836119b3565b9050606e81101561295f5761296f565b61296881612a07565b915061297b565b61297881612a46565b91505b50919050565b60006000612996612991846119b3565b6119b3565b9050606e8110156129a6576129b6565b6129af81612a46565b91506129c2565b6129bf81612a07565b91505b50919050565b600060006129d5836119b3565b905060b38110156129e5576129f5565b6129ee816119e8565b9150612a01565b6129fe816119fa565b91505b50919050565b60006000612a14836119b3565b9050606f811015612a2457612a34565b612a2d81612a8d565b9150612a40565b612a3d81612acc565b91505b50919050565b60006000612a5b612a56846119b3565b6119b3565b9050606f811015612a6b57612a7b565b612a7481612acc565b9150612a87565b612a8481612a8d565b91505b50919050565b60006000612a9a836119b3565b9050606c811015612aaa57612aba565b612ab381612b13565b9150612ac6565b612ac381612b52565b91505b50919050565b60006000612ae1612adc846119b3565b6119b3565b9050606c811015612af157612b01565b612afa81612b52565b9150612b0d565b612b0a81612b13565b91505b50919050565b60006000612b20836119b3565b9050606d811015612b3057612b40565b612b3981612b99565b9150612b4c565b612b4981612bd8565b91505b50919050565b60006000612b67612b62846119b3565b6119b3565b9050606d811015612b7757612b87565b612b8081612bd8565b9150612b93565b612b9081612b99565b91505b50919050565b60006000612ba6836119b3565b90506072811015612bb657612bc6565b612bbf81612c1f565b9150612bd2565b612bcf81612c5e565b91505b50919050565b60006000612bed612be8846119b3565b6119b3565b90506072811015612bfd57612c0d565b612c0681612c5e565b9150612c19565b612c1681612c1f565b91505b50919050565b60006000612c2c836119b3565b90506073811015612c3c57612c4c565b612c4581612ca5565b9150612c58565b612c5581612ce4565b91505b50919050565b60006000612c73612c6e846119b3565b6119b3565b90506073811015612c8357612c93565b612c8c81612ce4565b9150612c9f565b612c9c81612ca5565b91505b50919050565b60006000612cb2836119b3565b90506070811015612cc257612cd2565b612ccb81612d2b565b9150612cde565b612cdb81612d6a565b91505b50919050565b60006000612cf9612cf4846119b3565b6119b3565b90506070811015612d0957612d19565b612d1281612d6a565b9150612d25565b612d2281612d2b565b91505b50919050565b60006000612d38836119b3565b90506071811015612d4857612d58565b612d5181612db1565b9150612d64565b612d6181612df0565b91505b50919050565b60006000612d7f612d7a846119b3565b6119b3565b90506071811015612d8f57612d9f565b612d9881612df0565b9150612dab565b612da881612db1565b91505b50919050565b60006000612dbe836119b3565b90506076811015612dce57612dde565b612dd781612e37565b9150612dea565b612de781612e76565b91505b50919050565b60006000612e05612e00846119b3565b6119b3565b90506076811015612e1557612e25565b612e1e81612e76565b9150612e31565b612e2e81612e37565b91505b50919050565b60006000612e44836119b3565b90506077811015612e5457612e64565b612e5d81612ebd565b9150612e70565b612e6d81612efc565b91505b50919050565b60006000612e8b612e86846119b3565b6119b3565b90506077811015612e9b57612eab565b612ea481612efc565b9150612eb7565b612eb481612ebd565b91505b50919050565b60006000612eca836119b3565b90506074811015612eda57612eea565b612ee381612f43565b9150612ef6565b612ef381612f82565b91505b50919050565b60006000612f11612f0c846119b3565b6119b3565b90506074811015612f2157612f31565b612f2a81612f82565b9150612f3d565b612f3a81612f43565b91505b50919050565b60006000612f50836119b3565b90506075811015612f6057612f70565b612f6981612fc9565b9150612f7c565b612f7981613008565b91505b50919050565b60006000612f97612f92846119b3565b6119b3565b90506075811015612fa757612fb7565b612fb081613008565b9150612fc3565b612fc081612fc9565b91505b50919050565b60006000612fd6836119b3565b9050607a811015612fe657612ff6565b612fef8161304f565b9150613002565b612fff8161308e565b91505b50919050565b6000600061301d613018846119b3565b6119b3565b9050607a81101561302d5761303d565b6130368161308e565b9150613049565b6130468161304f565b91505b50919050565b6000600061305c836119b3565b9050607b81101561306c5761307c565b613075816130d5565b9150613088565b61308581613114565b91505b50919050565b600060006130a361309e846119b3565b6119b3565b9050607b8110156130b3576130c3565b6130bc81613114565b91506130cf565b6130cc816130d5565b91505b50919050565b600060006130e2836119b3565b905060788110156130f257613102565b6130fb8161315b565b915061310e565b61310b8161319a565b91505b50919050565b60006000613129613124846119b3565b6119b3565b9050607881101561313957613149565b6131428161319a565b9150613155565b6131528161315b565b91505b50919050565b60006000613168836119b3565b9050607981101561317857613188565b613181816131e1565b9150613194565b61319181613220565b91505b50919050565b600060006131af6131aa846119b3565b6119b3565b905060798110156131bf576131cf565b6131c881613220565b91506131db565b6131d8816131e1565b91505b50919050565b600060006131ee836119b3565b9050607e8110156131fe5761320e565b61320781613267565b915061321a565b613217816132a6565b91505b50919050565b60006000613235613230846119b3565b6119b3565b9050607e81101561324557613255565b61324e816132a6565b9150613261565b61325e81613267565b91505b50919050565b60006000613274836119b3565b9050607f81101561328457613294565b61328d816132ed565b91506132a0565b61329d8161332c565b91505b50919050565b600060006132bb6132b6846119b3565b6119b3565b9050607f8110156132cb576132db565b6132d48161332c565b91506132e7565b6132e4816132ed565b91505b50919050565b600060006132fa836119b3565b9050607c81101561330a5761331a565b61331381613373565b9150613326565b613323816133b2565b91505b50919050565b6000600061334161333c846119b3565b6119b3565b9050607c81101561335157613361565b61335a816133b2565b915061336d565b61336a81613373565b91505b50919050565b60006000613380836119b3565b9050607d811015613390576133a0565b613399816133f9565b91506133ac565b6133a981613438565b91505b50919050565b600060006133c76133c2846119b3565b6119b3565b9050607d8110156133d7576133e7565b6133e081613438565b91506133f3565b6133f0816133f9565b91505b50919050565b60006000613406836119b3565b9050608281101561341657613426565b61341f8161347f565b9150613432565b61342f816134be565b91505b50919050565b6000600061344d613448846119b3565b6119b3565b9050608281101561345d5761346d565b613466816134be565b9150613479565b6134768161347f565b91505b50919050565b6000600061348c836119b3565b9050608381101561349c576134ac565b6134a581613505565b91506134b8565b6134b581613544565b91505b50919050565b600060006134d36134ce846119b3565b6119b3565b905060838110156134e3576134f3565b6134ec81613544565b91506134ff565b6134fc81613505565b91505b50919050565b60006000613512836119b3565b9050608081101561352257613532565b61352b8161358b565b915061353e565b61353b816135ca565b91505b50919050565b60006000613559613554846119b3565b6119b3565b9050608081101561356957613579565b613572816135ca565b9150613585565b6135828161358b565b91505b50919050565b60006000613598836119b3565b905060818110156135a8576135b8565b6135b181613611565b91506135c4565b6135c181613650565b91505b50919050565b600060006135df6135da846119b3565b6119b3565b905060818110156135ef576135ff565b6135f881613650565b915061360b565b61360881613611565b91505b50919050565b6000600061361e836119b3565b9050608681101561362e5761363e565b61363781613697565b915061364a565b613647816136d6565b91505b50919050565b60006000613665613660846119b3565b6119b3565b9050608681101561367557613685565b61367e816136d6565b9150613691565b61368e81613697565b91505b50919050565b600060006136a4836119b3565b905060878110156136b4576136c4565b6136bd8161371d565b91506136d0565b6136cd8161375c565b91505b50919050565b600060006136eb6136e6846119b3565b6119b3565b905060878110156136fb5761370b565b6137048161375c565b9150613717565b6137148161371d565b91505b50919050565b6000600061372a836119b3565b9050608481101561373a5761374a565b613743816137a3565b9150613756565b613753816137e2565b91505b50919050565b6000600061377161376c846119b3565b6119b3565b9050608481101561378157613791565b61378a816137e2565b915061379d565b61379a816137a3565b91505b50919050565b600060006137b0836119b3565b905060858110156137c0576137d0565b6137c981613829565b91506137dc565b6137d981613868565b91505b50919050565b600060006137f76137f2846119b3565b6119b3565b9050608581101561380757613817565b61381081613868565b9150613823565b61382081613829565b91505b50919050565b60006000613836836119b3565b9050608a81101561384657613856565b61384f816138af565b9150613862565b61385f816138ee565b91505b50919050565b6000600061387d613878846119b3565b6119b3565b9050608a81101561388d5761389d565b613896816138ee565b91506138a9565b6138a6816138af565b91505b50919050565b600060006138bc836119b3565b9050608b8110156138cc576138dc565b6138d581613935565b91506138e8565b6138e581613974565b91505b50919050565b600060006139036138fe846119b3565b6119b3565b9050608b81101561391357613923565b61391c81613974565b915061392f565b61392c81613935565b91505b50919050565b60006000613942836119b3565b9050608881101561395257613962565b61395b816139bb565b915061396e565b61396b816139fa565b91505b50919050565b60006000613989613984846119b3565b6119b3565b90506088811015613999576139a9565b6139a2816139fa565b91506139b5565b6139b2816139bb565b91505b50919050565b600060006139c8836119b3565b905060898110156139d8576139e8565b6139e181613a41565b91506139f4565b6139f181613a80565b91505b50919050565b60006000613a0f613a0a846119b3565b6119b3565b90506089811015613a1f57613a2f565b613a2881613a80565b9150613a3b565b613a3881613a41565b91505b50919050565b60006000613a4e836119b3565b9050608e811015613a5e57613a6e565b613a6781613ac7565b9150613a7a565b613a7781613b06565b91505b50919050565b60006000613a95613a90846119b3565b6119b3565b9050608e811015613aa557613ab5565b613aae81613b06565b9150613ac1565b613abe81613ac7565b91505b50919050565b60006000613ad4836119b3565b9050608f811015613ae457613af4565b613aed81613b4d565b9150613b00565b613afd81613b8c565b91505b50919050565b60006000613b1b613b16846119b3565b6119b3565b9050608f811015613b2b57613b3b565b613b3481613b8c565b9150613b47565b613b4481613b4d565b91505b50919050565b60006000613b5a836119b3565b9050608c811015613b6a57613b7a565b613b7381613bd3565b9150613b86565b613b8381613c12565b91505b50919050565b60006000613ba1613b9c846119b3565b6119b3565b9050608c811015613bb157613bc1565b613bba81613c12565b9150613bcd565b613bca81613bd3565b91505b50919050565b60006000613be0836119b3565b9050608d811015613bf057613c00565b613bf981613c59565b9150613c0c565b613c0981613c98565b91505b50919050565b60006000613c27613c22846119b3565b6119b3565b9050608d811015613c3757613c47565b613c4081613c98565b9150613c53565b613c5081613c59565b91505b50919050565b60006000613c66836119b3565b90506092811015613c7657613c86565b613c7f81613cdf565b9150613c92565b613c8f81613d1e565b91505b50919050565b60006000613cad613ca8846119b3565b6119b3565b90506092811015613cbd57613ccd565b613cc681613d1e565b9150613cd9565b613cd681613cdf565b91505b50919050565b60006000613cec836119b3565b90506093811015613cfc57613d0c565b613d0581613d65565b9150613d18565b613d1581613da4565b91505b50919050565b60006000613d33613d2e846119b3565b6119b3565b90506093811015613d4357613d53565b613d4c81613da4565b9150613d5f565b613d5c81613d65565b91505b50919050565b60006000613d72836119b3565b90506090811015613d8257613d92565b613d8b81613deb565b9150613d9e565b613d9b81613e2a565b91505b50919050565b60006000613db9613db4846119b3565b6119b3565b90506090811015613dc957613dd9565b613dd281613e2a565b9150613de5565b613de281613deb565b91505b50919050565b60006000613df8836119b3565b90506091811015613e0857613e18565b613e1181613e71565b9150613e24565b613e2181613eb0565b91505b50919050565b60006000613e3f613e3a846119b3565b6119b3565b90506091811015613e4f57613e5f565b613e5881613eb0565b9150613e6b565b613e6881613e71565b91505b50919050565b60006000613e7e836119b3565b90506096811015613e8e57613e9e565b613e9781613ef7565b9150613eaa565b613ea781613f36565b91505b50919050565b60006000613ec5613ec0846119b3565b6119b3565b90506096811015613ed557613ee5565b613ede81613f36565b9150613ef1565b613eee81613ef7565b91505b50919050565b60006000613f04836119b3565b90506097811015613f1457613f24565b613f1d81613f7d565b9150613f30565b613f2d81613fbc565b91505b50919050565b60006000613f4b613f46846119b3565b6119b3565b90506097811015613f5b57613f6b565b613f6481613fbc565b9150613f77565b613f7481613f7d565b91505b50919050565b60006000613f8a836119b3565b90506094811015613f9a57613faa565b613fa381614003565b9150613fb6565b613fb381614042565b91505b50919050565b60006000613fd1613fcc846119b3565b6119b3565b90506094811015613fe157613ff1565b613fea81614042565b9150613ffd565b613ffa81614003565b91505b50919050565b60006000614010836119b3565b9050609581101561402057614030565b61402981614089565b915061403c565b614039816140c8565b91505b50919050565b60006000614057614052846119b3565b6119b3565b9050609581101561406757614077565b614070816140c8565b9150614083565b61408081614089565b91505b50919050565b60006000614096836119b3565b9050609a8110156140a6576140b6565b6140af8161410f565b91506140c2565b6140bf8161414e565b91505b50919050565b600060006140dd6140d8846119b3565b6119b3565b9050609a8110156140ed576140fd565b6140f68161414e565b9150614109565b6141068161410f565b91505b50919050565b6000600061411c836119b3565b9050609b81101561412c5761413c565b61413581614195565b9150614148565b614145816141d4565b91505b50919050565b6000600061416361415e846119b3565b6119b3565b9050609b81101561417357614183565b61417c816141d4565b915061418f565b61418c81614195565b91505b50919050565b600060006141a2836119b3565b905060988110156141b2576141c2565b6141bb8161421b565b91506141ce565b6141cb8161425a565b91505b50919050565b600060006141e96141e4846119b3565b6119b3565b905060988110156141f957614209565b6142028161425a565b9150614215565b6142128161421b565b91505b50919050565b60006000614228836119b3565b9050609981101561423857614248565b614241816142a1565b9150614254565b614251816142e0565b91505b50919050565b6000600061426f61426a846119b3565b6119b3565b9050609981101561427f5761428f565b614288816142e0565b915061429b565b614298816142a1565b91505b50919050565b600060006142ae836119b3565b9050609e8110156142be576142ce565b6142c781614327565b91506142da565b6142d781614366565b91505b50919050565b600060006142f56142f0846119b3565b6119b3565b9050609e81101561430557614315565b61430e81614366565b9150614321565b61431e81614327565b91505b50919050565b60006000614334836119b3565b9050609f81101561434457614354565b61434d816143ad565b9150614360565b61435d816143ec565b91505b50919050565b6000600061437b614376846119b3565b6119b3565b9050609f81101561438b5761439b565b614394816143ec565b91506143a7565b6143a4816143ad565b91505b50919050565b600060006143ba836119b3565b9050609c8110156143ca576143da565b6143d381614433565b91506143e6565b6143e381614472565b91505b50919050565b600060006144016143fc846119b3565b6119b3565b9050609c81101561441157614421565b61441a81614472565b915061442d565b61442a81614433565b91505b50919050565b60006000614440836119b3565b9050609d81101561445057614460565b614459816144b9565b915061446c565b614469816144f8565b91505b50919050565b60006000614487614482846119b3565b6119b3565b9050609d811015614497576144a7565b6144a0816144f8565b91506144b3565b6144b0816144b9565b91505b50919050565b600060006144c6836119b3565b905060a28110156144d6576144e6565b6144df8161453f565b91506144f2565b6144ef8161457e565b91505b50919050565b6000600061450d614508846119b3565b6119b3565b905060a281101561451d5761452d565b6145268161457e565b9150614539565b6145368161453f565b91505b50919050565b6000600061454c836119b3565b905060a381101561455c5761456c565b614565816145c5565b9150614578565b61457581614604565b91505b50919050565b6000600061459361458e846119b3565b6119b3565b905060a38110156145a3576145b3565b6145ac81614604565b91506145bf565b6145bc816145c5565b91505b50919050565b600060006145d2836119b3565b905060a08110156145e2576145f2565b6145eb8161464b565b91506145fe565b6145fb8161468a565b91505b50919050565b60006000614619614614846119b3565b6119b3565b905060a081101561462957614639565b6146328161468a565b9150614645565b6146428161464b565b91505b50919050565b60006000614658836119b3565b905060a181101561466857614678565b614671816146d1565b9150614684565b61468181614710565b91505b50919050565b6000600061469f61469a846119b3565b6119b3565b905060a18110156146af576146bf565b6146b881614710565b91506146cb565b6146c8816146d1565b91505b50919050565b600060006146de836119b3565b905060a68110156146ee576146fe565b6146f781614757565b915061470a565b61470781614796565b91505b50919050565b60006000614725614720846119b3565b6119b3565b905060a681101561473557614745565b61473e81614796565b9150614751565b61474e81614757565b91505b50919050565b60006000614764836119b3565b905060a781101561477457614784565b61477d816147dd565b9150614790565b61478d8161481c565b91505b50919050565b600060006147ab6147a6846119b3565b6119b3565b905060a78110156147bb576147cb565b6147c48161481c565b91506147d7565b6147d4816147dd565b91505b50919050565b600060006147ea836119b3565b905060a48110156147fa5761480a565b61480381614863565b9150614816565b614813816148a2565b91505b50919050565b6000600061483161482c846119b3565b6119b3565b905060a481101561484157614851565b61484a816148a2565b915061485d565b61485a81614863565b91505b50919050565b60006000614870836119b3565b905060a581101561488057614890565b614889816148e9565b915061489c565b61489981614928565b91505b50919050565b600060006148b76148b2846119b3565b6119b3565b905060a58110156148c7576148d7565b6148d081614928565b91506148e3565b6148e0816148e9565b91505b50919050565b600060006148f6836119b3565b905060aa81101561490657614916565b61490f8161496f565b9150614922565b61491f816149ae565b91505b50919050565b6000600061493d614938846119b3565b6119b3565b905060aa81101561494d5761495d565b614956816149ae565b9150614969565b6149668161496f565b91505b50919050565b6000600061497c836119b3565b905060ab81101561498c5761499c565b614995816149f5565b91506149a8565b6149a581614a34565b91505b50919050565b600060006149c36149be846119b3565b6119b3565b905060ab8110156149d3576149e3565b6149dc81614a34565b91506149ef565b6149ec816149f5565b91505b50919050565b60006000614a02836119b3565b905060a8811015614a1257614a22565b614a1b81614a7b565b9150614a2e565b614a2b81614aba565b91505b50919050565b60006000614a49614a44846119b3565b6119b3565b905060a8811015614a5957614a69565b614a6281614aba565b9150614a75565b614a7281614a7b565b91505b50919050565b60006000614a88836119b3565b905060a9811015614a9857614aa8565b614aa181614b01565b9150614ab4565b614ab181614b40565b91505b50919050565b60006000614acf614aca846119b3565b6119b3565b905060a9811015614adf57614aef565b614ae881614b40565b9150614afb565b614af881614b01565b91505b50919050565b60006000614b0e836119b3565b905060ae811015614b1e57614b2e565b614b2781614b87565b9150614b3a565b614b3781614bc6565b91505b50919050565b60006000614b55614b50846119b3565b6119b3565b905060ae811015614b6557614b75565b614b6e81614bc6565b9150614b81565b614b7e81614b87565b91505b50919050565b60006000614b94836119b3565b905060af811015614ba457614bb4565b614bad81614c0d565b9150614bc0565b614bbd81614c4c565b91505b50919050565b60006000614bdb614bd6846119b3565b6119b3565b905060af811015614beb57614bfb565b614bf481614c4c565b9150614c07565b614c0481614c0d565b91505b50919050565b60006000614c1a836119b3565b905060ac811015614c2a57614c3a565b614c3381614c93565b9150614c46565b614c4381614cd2565b91505b50919050565b60006000614c61614c5c846119b3565b6119b3565b905060ac811015614c7157614c81565b614c7a81614cd2565b9150614c8d565b614c8a81614c93565b91505b50919050565b60006000614ca0836119b3565b905060ad811015614cb057614cc0565b614cb981614d19565b9150614ccc565b614cc981614d58565b91505b50919050565b60006000614ce7614ce2846119b3565b6119b3565b905060ad811015614cf757614d07565b614d0081614d58565b9150614d13565b614d1081614d19565b91505b50919050565b60006000614d26836119b3565b905060b2811015614d3657614d46565b614d3f816129c8565b9150614d52565b614d4f81614d9f565b91505b50919050565b60006000614d6d614d68846119b3565b6119b3565b905060b2811015614d7d57614d8d565b614d8681614d9f565b9150614d99565b614d96816129c8565b91505b50919050565b60006000614db4614daf846119b3565b6119b3565b905060b3811015614dc457614dd4565b614dcd816119fa565b9150614de0565b614ddd816119e8565b91505b5091905056", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "//" : "ManyFunctions.start(1)", + "data" : "0x95805DAD0000000000000000000000000000000000000000000000000000000000000001", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, "ackermann31": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", From 5b48aad97dafd3602d10e617d962238355e00e9e Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Mon, 16 Feb 2015 17:15:04 +0100 Subject: [PATCH 196/213] Removing events from Solidity Interface --- libsolidity/InterfaceHandler.cpp | 9 --------- test/SolidityInterface.cpp | 28 ++-------------------------- 2 files changed, 2 insertions(+), 35 deletions(-) diff --git a/libsolidity/InterfaceHandler.cpp b/libsolidity/InterfaceHandler.cpp index 7ecde8029..99a7db96e 100644 --- a/libsolidity/InterfaceHandler.cpp +++ b/libsolidity/InterfaceHandler.cpp @@ -108,16 +108,7 @@ unique_ptr InterfaceHandler::getABISolidityInterface(ContractDefinition ret.pop_back(); ret += "{}"; } - for (auto const& it: _contractDef.getInterfaceEvents()) - { - std::string params; - for (auto const& p: it->getParameters()) - params += (params.empty() ? "(" : ",") + p->getType()->toString() + (p->isIndexed() ? " indexed " : " ") + p->getName(); - if (!params.empty()) - params += ")"; - ret += "event " + it->getName() + params + ";"; - } return unique_ptr(new string(ret + "}")); } diff --git a/test/SolidityInterface.cpp b/test/SolidityInterface.cpp index 78de2356a..a73c118bb 100644 --- a/test/SolidityInterface.cpp +++ b/test/SolidityInterface.cpp @@ -111,24 +111,6 @@ BOOST_AUTO_TEST_CASE(exclude_fallback_function) BOOST_CHECK_EQUAL(getSourcePart(contract), "contract test{}"); } -BOOST_AUTO_TEST_CASE(event) -{ - ContractDefinition const& contract = checkInterface( - "contract test { event Event; }"); - BOOST_REQUIRE_EQUAL(1, contract.getEvents().size()); - BOOST_CHECK_EQUAL(getSourcePart(*contract.getEvents().front()), - "event Event;"); -} - -BOOST_AUTO_TEST_CASE(event_arguments) -{ - ContractDefinition const& contract = checkInterface( - "contract test { event Event(uint a, uint indexed b); }"); - BOOST_REQUIRE_EQUAL(1, contract.getEvents().size()); - BOOST_CHECK_EQUAL(getSourcePart(*contract.getEvents().front()), - "event Event(uint256 a,uint256 indexed b);"); -} - BOOST_AUTO_TEST_CASE(events) { char const* sourceCode = "contract test {\n" @@ -137,10 +119,8 @@ BOOST_AUTO_TEST_CASE(events) " event e2(); \n" "}\n"; ContractDefinition const& contract = checkInterface(sourceCode); - set expectation({"event e1(uint256 b,address indexed c);", "event e2;"}); - BOOST_REQUIRE_EQUAL(2, contract.getEvents().size()); - BOOST_CHECK(expectation == set({getSourcePart(*contract.getEvents().at(0)), - getSourcePart(*contract.getEvents().at(1))})); + // events should not appear in the Solidity Interface + BOOST_REQUIRE_EQUAL(0, contract.getEvents().size()); } BOOST_AUTO_TEST_CASE(inheritance) @@ -155,12 +135,8 @@ BOOST_AUTO_TEST_CASE(inheritance) " event derivedEvent(uint indexed evtArgDerived); \n" " }"; ContractDefinition const& contract = checkInterface(sourceCode); - set expectedEvents({"event derivedEvent(uint256 indexed evtArgDerived);", - "event baseEvent(string32 indexed evtArgBase);"}); set expectedFunctions({"function baseFunction(uint256 p)returns(uint256 i){}", "function derivedFunction(string32 p)returns(string32 i){}"}); - BOOST_CHECK(expectedEvents == set({getSourcePart(*contract.getEvents().at(0)), - getSourcePart(*contract.getEvents().at(1))})); BOOST_REQUIRE_EQUAL(2, contract.getDefinedFunctions().size()); BOOST_CHECK(expectedFunctions == set({getSourcePart(*contract.getDefinedFunctions().at(0)), getSourcePart(*contract.getDefinedFunctions().at(1))})); From 30d129a17c0dfc5ab9e698afb5a52beb0868d6db Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Mon, 16 Feb 2015 18:03:40 +0100 Subject: [PATCH 197/213] added shh_getMessages, fixed #899 --- libweb3jsonrpc/WebThreeStubServerBase.cpp | 23 +++++++++++++++++++++ libweb3jsonrpc/WebThreeStubServerBase.h | 1 + libweb3jsonrpc/abstractwebthreestubserver.h | 6 ++++++ libweb3jsonrpc/spec.json | 3 ++- test/webthreestubclient.h | 10 +++++++++ 5 files changed, 42 insertions(+), 1 deletion(-) diff --git a/libweb3jsonrpc/WebThreeStubServerBase.cpp b/libweb3jsonrpc/WebThreeStubServerBase.cpp index 27b8268da..f9f609c1b 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.cpp +++ b/libweb3jsonrpc/WebThreeStubServerBase.cpp @@ -613,6 +613,29 @@ Json::Value WebThreeStubServerBase::shh_changed(int _id) return ret; } +Json::Value WebThreeStubServerBase::shh_getMessages(int _id) +{ + Json::Value ret(Json::arrayValue); + auto pub = m_shhWatches[_id]; + if (!pub || m_ids.count(pub)) + for (h256 const& h: face()->watchMessages(_id)) + { + auto e = face()->envelope(h); + shh::Message m; + if (pub) + { + cwarn << "Silently decrypting message from identity" << pub.abridged() << ": User validation hook goes here."; + m = e.open(face()->fullTopic(_id), m_ids[pub]); + } + else + m = e.open(face()->fullTopic(_id)); + if (!m) + continue; + ret.append(toJson(h, e, m)); + } + return ret; +} + int WebThreeStubServerBase::shh_newFilter(Json::Value const& _json) { auto w = toWatch(_json); diff --git a/libweb3jsonrpc/WebThreeStubServerBase.h b/libweb3jsonrpc/WebThreeStubServerBase.h index 005ac4130..578acf9a9 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.h +++ b/libweb3jsonrpc/WebThreeStubServerBase.h @@ -113,6 +113,7 @@ public: virtual std::string shh_addToGroup(std::string const& _group, std::string const& _who); virtual Json::Value shh_changed(int _id); + virtual Json::Value shh_getMessages(int _id); virtual bool shh_haveIdentity(std::string const& _id); virtual int shh_newFilter(Json::Value const& _json); virtual std::string shh_newGroup(std::string const& _id, std::string const& _who); diff --git a/libweb3jsonrpc/abstractwebthreestubserver.h b/libweb3jsonrpc/abstractwebthreestubserver.h index 5bade41f6..98236bb68 100644 --- a/libweb3jsonrpc/abstractwebthreestubserver.h +++ b/libweb3jsonrpc/abstractwebthreestubserver.h @@ -63,6 +63,7 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServerbindAndAddMethod(jsonrpc::Procedure("shh_newFilter", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_INTEGER, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::shh_newFilterI); this->bindAndAddMethod(jsonrpc::Procedure("shh_uninstallFilter", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::shh_uninstallFilterI); this->bindAndAddMethod(jsonrpc::Procedure("shh_changed", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::shh_changedI); + this->bindAndAddMethod(jsonrpc::Procedure("shh_getMessages", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::shh_getMessagesI); } inline virtual void web3_sha3I(const Json::Value &request, Json::Value &response) @@ -281,6 +282,10 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServershh_changed(request[0u].asInt()); } + inline virtual void shh_getMessagesI(const Json::Value &request, Json::Value &response) + { + response = this->shh_getMessages(request[0u].asInt()); + } virtual std::string web3_sha3(const std::string& param1) = 0; virtual std::string eth_coinbase() = 0; virtual bool eth_setCoinbase(const std::string& param1) = 0; @@ -332,6 +337,7 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServerCallMethod("shh_getMessages",p); + if (result.isArray()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } }; #endif //JSONRPC_CPP_STUB_WEBTHREESTUBCLIENT_H_ From 0185ac5a0d4609732410d5962a2bd7ad867f90c3 Mon Sep 17 00:00:00 2001 From: Christian Date: Sat, 14 Feb 2015 00:43:02 +0100 Subject: [PATCH 198/213] "external" visibility specifier. --- libsolidity/AST.h | 7 ++-- libsolidity/DeclarationContainer.cpp | 13 ++++--- libsolidity/DeclarationContainer.h | 6 +++- libsolidity/NameAndTypeResolver.cpp | 9 ++--- libsolidity/Parser.cpp | 4 ++- libsolidity/Token.h | 4 ++- libsolidity/Types.cpp | 7 ++-- test/SolidityNameAndTypeResolution.cpp | 50 ++++++++++++++++++++++++++ test/SolidityParser.cpp | 18 ++++++++++ 9 files changed, 102 insertions(+), 16 deletions(-) diff --git a/libsolidity/AST.h b/libsolidity/AST.h index 51d8031a3..c40e24d1d 100644 --- a/libsolidity/AST.h +++ b/libsolidity/AST.h @@ -133,7 +133,8 @@ class Declaration: public ASTNode { public: enum class LValueType { None, Local, Storage }; - enum class Visibility { Default, Public, Protected, Private }; + /// Visibility ordered from restricted to unrestricted. + enum class Visibility { Default, Private, Protected, Public, External }; Declaration(Location const& _location, ASTPointer const& _name, Visibility _visibility = Visibility::Default): @@ -142,7 +143,9 @@ public: /// @returns the declared name. ASTString const& getName() const { return *m_name; } Visibility getVisibility() const { return m_visibility == Visibility::Default ? getDefaultVisibility() : m_visibility; } - bool isPublic() const { return getVisibility() == Visibility::Public; } + bool isPublic() const { return getVisibility() >= Visibility::Public; } + bool isVisibleInContract() const { return getVisibility() != Visibility::External; } + bool isVisibleInDerivedContracts() const { return isVisibleInContract() && getVisibility() >= Visibility::Protected; } /// @returns the scope this declaration resides in. Can be nullptr if it is the global scope. /// Available only after name and type resolution step. diff --git a/libsolidity/DeclarationContainer.cpp b/libsolidity/DeclarationContainer.cpp index 2e810a4cf..2594d4281 100644 --- a/libsolidity/DeclarationContainer.cpp +++ b/libsolidity/DeclarationContainer.cpp @@ -28,14 +28,19 @@ namespace dev namespace solidity { -bool DeclarationContainer::registerDeclaration(Declaration const& _declaration, bool _update) +bool DeclarationContainer::registerDeclaration(Declaration const& _declaration, bool _invisible, bool _update) { - if (_declaration.getName().empty()) + ASTString const& name(_declaration.getName()); + if (name.empty()) return true; - if (!_update && m_declarations.find(_declaration.getName()) != m_declarations.end()) + if (!_update && (m_declarations.count(name) || m_invisibleDeclarations.count(name))) return false; - m_declarations[_declaration.getName()] = &_declaration; + + if (_invisible) + m_invisibleDeclarations.insert(name); + else + m_declarations[name] = &_declaration; return true; } diff --git a/libsolidity/DeclarationContainer.h b/libsolidity/DeclarationContainer.h index 1216fcef2..f70881f5b 100644 --- a/libsolidity/DeclarationContainer.h +++ b/libsolidity/DeclarationContainer.h @@ -23,6 +23,7 @@ #pragma once #include +#include #include #include @@ -43,8 +44,10 @@ public: DeclarationContainer const* _enclosingContainer = nullptr): m_enclosingDeclaration(_enclosingDeclaration), m_enclosingContainer(_enclosingContainer) {} /// Registers the declaration in the scope unless its name is already declared or the name is empty. + /// @param _invisible if true, registers the declaration, reports name clashes but does not return it in @a resolveName + /// @param _update if true, replaces a potential declaration that is already present /// @returns false if the name was already declared. - bool registerDeclaration(Declaration const& _declaration, bool _update = false); + bool registerDeclaration(Declaration const& _declaration, bool _invisible = false, bool _update = false); Declaration const* resolveName(ASTString const& _name, bool _recursive = false) const; Declaration const* getEnclosingDeclaration() const { return m_enclosingDeclaration; } std::map const& getDeclarations() const { return m_declarations; } @@ -53,6 +56,7 @@ private: Declaration const* m_enclosingDeclaration; DeclarationContainer const* m_enclosingContainer; std::map m_declarations; + std::set m_invisibleDeclarations; }; } diff --git a/libsolidity/NameAndTypeResolver.cpp b/libsolidity/NameAndTypeResolver.cpp index dbe5693a8..ea70b65b4 100644 --- a/libsolidity/NameAndTypeResolver.cpp +++ b/libsolidity/NameAndTypeResolver.cpp @@ -86,7 +86,7 @@ void NameAndTypeResolver::checkTypeRequirements(ContractDefinition& _contract) void NameAndTypeResolver::updateDeclaration(Declaration const& _declaration) { - m_scopes[nullptr].registerDeclaration(_declaration, true); + m_scopes[nullptr].registerDeclaration(_declaration, false, true); solAssert(_declaration.getScope() == nullptr, "Updated declaration outside global scope."); } @@ -110,8 +110,9 @@ void NameAndTypeResolver::importInheritedScope(ContractDefinition const& _base) for (auto const& nameAndDeclaration: iterator->second.getDeclarations()) { Declaration const* declaration = nameAndDeclaration.second; - // Import if it was declared in the base and is not the constructor - if (declaration->getScope() == &_base && declaration->getName() != _base.getName()) + // Import if it was declared in the base, is not the constructor and is visible in derived classes + if (declaration->getScope() == &_base && declaration->getName() != _base.getName() && + declaration->isVisibleInDerivedContracts()) m_currentScope->registerDeclaration(*declaration); } } @@ -308,7 +309,7 @@ void DeclarationRegistrationHelper::closeCurrentScope() void DeclarationRegistrationHelper::registerDeclaration(Declaration& _declaration, bool _opensScope) { - if (!m_scopes[m_currentScope].registerDeclaration(_declaration)) + if (!m_scopes[m_currentScope].registerDeclaration(_declaration, !_declaration.isVisibleInContract())) BOOST_THROW_EXCEPTION(DeclarationError() << errinfo_sourceLocation(_declaration.getLocation()) << errinfo_comment("Identifier already declared.")); //@todo the exception should also contain the location of the first declaration diff --git a/libsolidity/Parser.cpp b/libsolidity/Parser.cpp index c96593f64..cf57ca50e 100644 --- a/libsolidity/Parser.cpp +++ b/libsolidity/Parser.cpp @@ -190,6 +190,8 @@ Declaration::Visibility Parser::parseVisibilitySpecifier(Token::Value _token) visibility = Declaration::Visibility::Protected; else if (_token == Token::Private) visibility = Declaration::Visibility::Private; + else if (_token == Token::External) + visibility = Declaration::Visibility::External; else solAssert(false, "Invalid visibility specifier."); m_scanner->next(); @@ -306,7 +308,7 @@ ASTPointer Parser::parseVariableDeclaration(VarDeclParserOp ASTPointer identifier; Token::Value token = m_scanner->getCurrentToken(); Declaration::Visibility visibility(Declaration::Visibility::Default); - if (_options.isStateVariable && Token::isVisibilitySpecifier(token)) + if (_options.isStateVariable && Token::isVariableVisibilitySpecifier(token)) visibility = parseVisibilitySpecifier(token); if (_options.allowIndexed && token == Token::Indexed) { diff --git a/libsolidity/Token.h b/libsolidity/Token.h index 3e599a6ee..7bf8a7ef0 100644 --- a/libsolidity/Token.h +++ b/libsolidity/Token.h @@ -150,6 +150,7 @@ namespace solidity K(Do, "do", 0) \ K(Else, "else", 0) \ K(Event, "event", 0) \ + K(External, "external", 0) \ K(Is, "is", 0) \ K(Indexed, "indexed", 0) \ K(For, "for", 0) \ @@ -378,7 +379,8 @@ public: static bool isUnaryOp(Value op) { return (Not <= op && op <= Delete) || op == Add || op == Sub; } static bool isCountOp(Value op) { return op == Inc || op == Dec; } static bool isShiftOp(Value op) { return (SHL <= op) && (op <= SHR); } - static bool isVisibilitySpecifier(Value op) { return op == Public || op == Private || op == Protected; } + static bool isVisibilitySpecifier(Value op) { return isVariableVisibilitySpecifier(op) || op == External; } + static bool isVariableVisibilitySpecifier(Value op) { return op == Public || op == Private || op == Protected; } static bool isEtherSubdenomination(Value op) { return op == SubWei || op == SubSzabo || op == SubFinney || op == Token::SubEther; } // Returns a string corresponding to the JS token string diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index 5d753645c..99515a3ac 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -572,7 +572,8 @@ MemberList const& ContractType::getMembers() const { for (ContractDefinition const* base: m_contract.getLinearizedBaseContracts()) for (ASTPointer const& function: base->getDefinedFunctions()) - if (!function->isConstructor() && !function->getName().empty()) + if (!function->isConstructor() && !function->getName().empty() && + function->isVisibleInDerivedContracts()) members.insert(make_pair(function->getName(), make_shared(*function, true))); } else @@ -957,10 +958,10 @@ MemberList const& TypeType::getMembers() const ContractDefinition const& contract = dynamic_cast(*m_actualType).getContractDefinition(); vector currentBases = m_currentContract->getLinearizedBaseContracts(); if (find(currentBases.begin(), currentBases.end(), &contract) != currentBases.end()) - // We are accessing the type of a base contract, so add all public and private + // We are accessing the type of a base contract, so add all public and protected // functions. Note that this does not add inherited functions on purpose. for (ASTPointer const& f: contract.getDefinedFunctions()) - if (!f->isConstructor() && !f->getName().empty()) + if (!f->isConstructor() && !f->getName().empty() && f->isVisibleInDerivedContracts()) members[f->getName()] = make_shared(*f); } else if (m_actualType->getCategory() == Category::Enum) diff --git a/test/SolidityNameAndTypeResolution.cpp b/test/SolidityNameAndTypeResolution.cpp index d6e4ed516..f30de96ce 100644 --- a/test/SolidityNameAndTypeResolution.cpp +++ b/test/SolidityNameAndTypeResolution.cpp @@ -1083,6 +1083,56 @@ BOOST_AUTO_TEST_CASE(enum_duplicate_values) BOOST_CHECK_THROW(parseTextAndResolveNames(text), DeclarationError); } +BOOST_AUTO_TEST_CASE(private_visibility) +{ + char const* sourceCode = R"( + contract base { + function f() private {} + } + contract derived is base { + function g() { f(); } + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), DeclarationError); +} + +BOOST_AUTO_TEST_CASE(private_visibility_via_explicit_base_access) +{ + char const* sourceCode = R"( + contract base { + function f() private {} + } + contract derived is base { + function g() { base.f(); } + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); +} + +BOOST_AUTO_TEST_CASE(external_visibility) +{ + char const* sourceCode = R"( + contract c { + function f() external {} + function g() { f(); } + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), DeclarationError); +} + +BOOST_AUTO_TEST_CASE(external_base_visibility) +{ + char const* sourceCode = R"( + contract base { + function f() external {} + } + contract derived is base { + function g() { base.f(); } + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/SolidityParser.cpp b/test/SolidityParser.cpp index af82f612a..5f9064e0c 100644 --- a/test/SolidityParser.cpp +++ b/test/SolidityParser.cpp @@ -735,6 +735,24 @@ BOOST_AUTO_TEST_CASE(malformed_enum_declaration) BOOST_CHECK_THROW(parseText(text), ParserError); } +BOOST_AUTO_TEST_CASE(external_function) +{ + char const* text = R"( + contract c { + function x() external {} + })"; + BOOST_CHECK_NO_THROW(parseTextExplainError(text)); +} + +BOOST_AUTO_TEST_CASE(external_variable) +{ + char const* text = R"( + contract c { + uint external x; + })"; + BOOST_CHECK_THROW(parseText(text), ParserError); +} + BOOST_AUTO_TEST_SUITE_END() } From ed0384b75922cd4834bc1a77dd5caf81c03d6dbd Mon Sep 17 00:00:00 2001 From: Christian Date: Sat, 14 Feb 2015 01:22:44 +0100 Subject: [PATCH 199/213] No write access to parameters of external functions. --- libsolidity/AST.cpp | 28 ++++++++++++++++-------- libsolidity/AST.h | 16 ++++++-------- libsolidity/ASTJsonConverter.cpp | 17 ++++++--------- libsolidity/Compiler.cpp | 23 ++++++++++++++------ test/SolidityEndToEndTest.cpp | 15 +++++++++++++ test/SolidityNameAndTypeResolution.cpp | 30 ++++++++++++++++++++++++++ 6 files changed, 95 insertions(+), 34 deletions(-) diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp index 0dbad433f..0fafd2d12 100644 --- a/libsolidity/AST.cpp +++ b/libsolidity/AST.cpp @@ -288,12 +288,23 @@ string FunctionDefinition::getCanonicalSignature() const return FunctionType(*this).getCanonicalSignature(getName()); } -Declaration::LValueType VariableDeclaration::getLValueType() const +bool VariableDeclaration::isLValue() const { - if (dynamic_cast(getScope()) || dynamic_cast(getScope())) - return Declaration::LValueType::Local; - else - return Declaration::LValueType::Storage; + if (auto const* function = dynamic_cast(getScope())) + if (function->getVisibility() == Declaration::Visibility::External && isFunctionParameter()) + return false; + return true; +} + +bool VariableDeclaration::isFunctionParameter() const +{ + auto const* function = dynamic_cast(getScope()); + if (!function) + return false; + for (auto const& variable: function->getParameters()) + if (variable.get() == this) + return true; + return false; } TypePointer ModifierDefinition::getType(ContractDefinition const*) const @@ -586,8 +597,7 @@ void MemberAccess::checkTypeRequirements() if (!m_type) BOOST_THROW_EXCEPTION(createTypeError("Member \"" + *m_memberName + "\" not found or not " "visible in " + type.toString())); - //@todo later, this will not always be STORAGE - m_lvalue = type.getCategory() == Type::Category::Struct ? Declaration::LValueType::Storage : Declaration::LValueType::None; + m_isLValue = (type.getCategory() == Type::Category::Struct); } void IndexAccess::checkTypeRequirements() @@ -599,14 +609,14 @@ void IndexAccess::checkTypeRequirements() MappingType const& type = dynamic_cast(*m_base->getType()); m_index->expectType(*type.getKeyType()); m_type = type.getValueType(); - m_lvalue = Declaration::LValueType::Storage; + m_isLValue = true; } void Identifier::checkTypeRequirements() { solAssert(m_referencedDeclaration, "Identifier not resolved."); - m_lvalue = m_referencedDeclaration->getLValueType(); + m_isLValue = m_referencedDeclaration->isLValue(); m_type = m_referencedDeclaration->getType(m_currentContract); if (!m_type) BOOST_THROW_EXCEPTION(createTypeError("Declaration referenced before type could be determined.")); diff --git a/libsolidity/AST.h b/libsolidity/AST.h index c40e24d1d..af45934f7 100644 --- a/libsolidity/AST.h +++ b/libsolidity/AST.h @@ -132,7 +132,6 @@ private: class Declaration: public ASTNode { public: - enum class LValueType { None, Local, Storage }; /// Visibility ordered from restricted to unrestricted. enum class Visibility { Default, Private, Protected, Public, External }; @@ -156,8 +155,7 @@ public: /// The current contract has to be given since this context can change the type, especially of /// contract types. virtual TypePointer getType(ContractDefinition const* m_currentContract = nullptr) const = 0; - /// @returns the lvalue type of expressions referencing this declaration - virtual LValueType getLValueType() const { return LValueType::None; } + virtual bool isLValue() const { return false; } protected: virtual Visibility getDefaultVisibility() const { return Visibility::Public; } @@ -448,8 +446,9 @@ public: TypePointer getType(ContractDefinition const* = nullptr) const { return m_type; } void setType(std::shared_ptr const& _type) { m_type = _type; } - virtual LValueType getLValueType() const override; + virtual bool isLValue() const override; bool isLocalVariable() const { return !!dynamic_cast(getScope()); } + bool isFunctionParameter() const; bool isStateVariable() const { return m_isStateVariable; } bool isIndexed() const { return m_isIndexed; } @@ -887,8 +886,7 @@ public: virtual void checkTypeRequirements() = 0; std::shared_ptr const& getType() const { return m_type; } - bool isLValue() const { return m_lvalue != Declaration::LValueType::None; } - bool isLocalLValue() const { return m_lvalue == Declaration::LValueType::Local; } + bool isLValue() const { return m_isLValue; } /// Helper function, infer the type via @ref checkTypeRequirements and then check that it /// is implicitly convertible to @a _expectedType. If not, throw exception. @@ -903,9 +901,9 @@ public: protected: //! Inferred type of the expression, only filled after a call to checkTypeRequirements(). std::shared_ptr m_type; - //! If this expression is an lvalue (i.e. something that can be assigned to) and is stored - //! locally or in storage. This is set during calls to @a checkTypeRequirements() - Declaration::LValueType m_lvalue = Declaration::LValueType::None; + //! If this expression is an lvalue (i.e. something that can be assigned to). + //! This is set during calls to @a checkTypeRequirements() + bool m_isLValue = false; //! Whether the outer expression requested the address (true) or the value (false) of this expression. bool m_lvalueRequested = false; }; diff --git a/libsolidity/ASTJsonConverter.cpp b/libsolidity/ASTJsonConverter.cpp index a216a59ac..04feafe2f 100644 --- a/libsolidity/ASTJsonConverter.cpp +++ b/libsolidity/ASTJsonConverter.cpp @@ -118,11 +118,7 @@ bool ASTJsonConverter::visit(FunctionDefinition const& _node) bool ASTJsonConverter::visit(VariableDeclaration const& _node) { - bool isLocalVariable = (_node.getLValueType() == VariableDeclaration::LValueType::Local); - addJsonNode("VariableDeclaration", - { make_pair("name", _node.getName()), - make_pair("local", boost::lexical_cast(isLocalVariable))}, - true); + addJsonNode("VariableDeclaration", { make_pair("name", _node.getName()) }, true); return true; } @@ -216,11 +212,12 @@ bool ASTJsonConverter::visit(ExpressionStatement const&) bool ASTJsonConverter::visit(Expression const& _node) { - addJsonNode("Expression", - { make_pair("type", getType(_node)), - make_pair("lvalue", boost::lexical_cast(_node.isLValue())), - make_pair("local_lvalue", boost::lexical_cast(_node.isLocalLValue())) }, - true); + addJsonNode( + "Expression", + { make_pair("type", getType(_node)), + make_pair("lvalue", boost::lexical_cast(_node.isLValue())) }, + true + ); return true; } diff --git a/libsolidity/Compiler.cpp b/libsolidity/Compiler.cpp index dad79bb06..4dbcbbfe6 100644 --- a/libsolidity/Compiler.cpp +++ b/libsolidity/Compiler.cpp @@ -255,12 +255,22 @@ bool Compiler::visit(FunctionDefinition const& _function) // stack upon entry: [return address] [arg0] [arg1] ... [argn] // reserve additional slots: [retarg0] ... [retargm] [localvar0] ... [localvarp] - unsigned parametersSize = CompilerUtils::getSizeOnStack(_function.getParameters()); - m_context.adjustStackOffset(parametersSize); - for (ASTPointer const& variable: _function.getParameters()) + if (_function.getVisibility() != Declaration::Visibility::External) { - m_context.addVariable(*variable, parametersSize); - parametersSize -= variable->getType()->getSizeOnStack(); + unsigned parametersSize = CompilerUtils::getSizeOnStack(_function.getParameters()); + m_context.adjustStackOffset(parametersSize); + for (ASTPointer const& variable: _function.getParameters()) + { + m_context.addVariable(*variable, parametersSize); + parametersSize -= variable->getType()->getSizeOnStack(); + } + } + else + { + unsigned calldataPos = CompilerUtils::dataStartOffset; + // calldatapos is _always_ dynamic. + for (ASTPointer const& variable: _function.getParameters()) + m_context.addCalldataVariable(*variable, calldataPos); } for (ASTPointer const& variable: _function.getReturnParameters()) m_context.addAndInitializeVariable(*variable); @@ -277,7 +287,8 @@ bool Compiler::visit(FunctionDefinition const& _function) // Note that the fact that the return arguments are of increasing index is vital for this // algorithm to work. - unsigned const c_argumentsSize = CompilerUtils::getSizeOnStack(_function.getParameters()); + unsigned const c_argumentsSize = (_function.getVisibility() == Declaration::Visibility::External + ? 0 : CompilerUtils::getSizeOnStack(_function.getParameters())); unsigned const c_returnValuesSize = CompilerUtils::getSizeOnStack(_function.getReturnParameters()); unsigned const c_localVariablesSize = CompilerUtils::getSizeOnStack(_function.getLocalVariables()); diff --git a/test/SolidityEndToEndTest.cpp b/test/SolidityEndToEndTest.cpp index 0325c4c6a..9899af29f 100644 --- a/test/SolidityEndToEndTest.cpp +++ b/test/SolidityEndToEndTest.cpp @@ -2534,6 +2534,21 @@ BOOST_AUTO_TEST_CASE(constructing_enums_from_ints) BOOST_CHECK(callContractFunction("test()") == encodeArgs(1)); } +BOOST_AUTO_TEST_CASE(external_function) +{ + char const* sourceCode = R"( + contract c { + function f(uint a) returns (uint) { return a; } + function test(uint a, uint b) external returns (uint r_a, uint r_b) { + r_a = f(a + 7); + r_b = b; + } + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("test(uint256,uint256)", 2, 3) == encodeArgs(2, 3+7)); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/SolidityNameAndTypeResolution.cpp b/test/SolidityNameAndTypeResolution.cpp index f30de96ce..6b337ac74 100644 --- a/test/SolidityNameAndTypeResolution.cpp +++ b/test/SolidityNameAndTypeResolution.cpp @@ -1133,6 +1133,36 @@ BOOST_AUTO_TEST_CASE(external_base_visibility) BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); } +BOOST_AUTO_TEST_CASE(external_argument_assign) +{ + char const* sourceCode = R"( + contract c { + function f(uint a) external { a = 1; } + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); +} + +BOOST_AUTO_TEST_CASE(external_argument_increment) +{ + char const* sourceCode = R"( + contract c { + function f(uint a) external { a++; } + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); +} + +BOOST_AUTO_TEST_CASE(external_argument_delete) +{ + char const* sourceCode = R"( + contract c { + function f(uint a) external { delete a; } + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); +} + BOOST_AUTO_TEST_SUITE_END() } From 9ba105a763764a2d956653fc99c93bde1a57a435 Mon Sep 17 00:00:00 2001 From: Christian Date: Sun, 15 Feb 2015 00:11:51 +0100 Subject: [PATCH 200/213] Move code to loadFromMemory. --- libsolidity/Compiler.cpp | 36 ++++++------------------ libsolidity/CompilerUtils.cpp | 45 +++++++++++++++--------------- libsolidity/CompilerUtils.h | 9 +++--- libsolidity/ExpressionCompiler.cpp | 7 ++--- 4 files changed, 38 insertions(+), 59 deletions(-) diff --git a/libsolidity/Compiler.cpp b/libsolidity/Compiler.cpp index 4dbcbbfe6..e14935873 100644 --- a/libsolidity/Compiler.cpp +++ b/libsolidity/Compiler.cpp @@ -147,7 +147,7 @@ void Compiler::appendFunctionSelector(ContractDefinition const& _contract) // retrieve the function signature hash from the calldata if (!interfaceFunctions.empty()) - CompilerUtils(m_context).loadFromMemory(0, 4, false, true); + CompilerUtils(m_context).loadFromMemory(0, IntegerType(CompilerUtils::dataStartOffset * 8), true); // stack now is: 1 0 for (auto const& it: interfaceFunctions) @@ -182,18 +182,10 @@ unsigned Compiler::appendCalldataUnpacker(TypePointers const& _typeParameters, b { // We do not check the calldata size, everything is zero-padded. unsigned dataOffset = CompilerUtils::dataStartOffset; // the 4 bytes of the function hash signature - //@todo this can be done more efficiently, saving some CALLDATALOAD calls + + bool const c_padToWords = true; for (TypePointer const& type: _typeParameters) - { - unsigned const c_numBytes = type->getCalldataEncodedSize(); - if (c_numBytes > 32) - BOOST_THROW_EXCEPTION(CompilerError() - << errinfo_comment("Type " + type->toString() + " not yet supported.")); - bool const c_leftAligned = type->getCategory() == Type::Category::String; - bool const c_padToWords = true; - dataOffset += CompilerUtils(m_context).loadFromMemory(dataOffset, c_numBytes, c_leftAligned, - !_fromMemory, c_padToWords); - } + dataOffset += CompilerUtils(m_context).loadFromMemory(dataOffset, *type, !_fromMemory, c_padToWords); return dataOffset; } @@ -255,22 +247,12 @@ bool Compiler::visit(FunctionDefinition const& _function) // stack upon entry: [return address] [arg0] [arg1] ... [argn] // reserve additional slots: [retarg0] ... [retargm] [localvar0] ... [localvarp] - if (_function.getVisibility() != Declaration::Visibility::External) - { - unsigned parametersSize = CompilerUtils::getSizeOnStack(_function.getParameters()); - m_context.adjustStackOffset(parametersSize); - for (ASTPointer const& variable: _function.getParameters()) - { - m_context.addVariable(*variable, parametersSize); - parametersSize -= variable->getType()->getSizeOnStack(); - } - } - else + unsigned parametersSize = CompilerUtils::getSizeOnStack(_function.getParameters()); + m_context.adjustStackOffset(parametersSize); + for (ASTPointer const& variable: _function.getParameters()) { - unsigned calldataPos = CompilerUtils::dataStartOffset; - // calldatapos is _always_ dynamic. - for (ASTPointer const& variable: _function.getParameters()) - m_context.addCalldataVariable(*variable, calldataPos); + m_context.addVariable(*variable, parametersSize); + parametersSize -= variable->getType()->getSizeOnStack(); } for (ASTPointer const& variable: _function.getReturnParameters()) m_context.addAndInitializeVariable(*variable); diff --git a/libsolidity/CompilerUtils.cpp b/libsolidity/CompilerUtils.cpp index dda1736d6..6f99dc7c2 100644 --- a/libsolidity/CompilerUtils.cpp +++ b/libsolidity/CompilerUtils.cpp @@ -33,33 +33,34 @@ namespace solidity const unsigned int CompilerUtils::dataStartOffset = 4; -unsigned CompilerUtils::loadFromMemory(unsigned _offset, unsigned _bytes, bool _leftAligned, - bool _fromCalldata, bool _padToWordBoundaries) +unsigned CompilerUtils::loadFromMemory(unsigned _offset, Type const& _type, + bool _fromCalldata, bool _padToWordBoundaries) { - if (_bytes == 0) - { + solAssert(_type.getCategory() != Type::Category::ByteArray, "Unable to statically load dynamic type."); + unsigned _encodedSize = _type.getCalldataEncodedSize(); + unsigned numBytes = _padToWordBoundaries ? getPaddedSize(_encodedSize) : _encodedSize; + bool leftAligned = _type.getCategory() == Type::Category::String; + if (numBytes == 0) m_context << u256(0); - return 0; - } - eth::Instruction load = _fromCalldata ? eth::Instruction::CALLDATALOAD : eth::Instruction::MLOAD; - solAssert(_bytes <= 32, "Memory load of more than 32 bytes requested."); - if (_bytes == 32 || _padToWordBoundaries) - { - m_context << u256(_offset) << load; - return 32; - } else { - // load data and add leading or trailing zeros by dividing/multiplying depending on alignment - u256 shiftFactor = u256(1) << ((32 - _bytes) * 8); - m_context << shiftFactor; - if (_leftAligned) - m_context << eth::Instruction::DUP1; - m_context << u256(_offset) << load << eth::Instruction::DIV; - if (_leftAligned) - m_context << eth::Instruction::MUL; - return _bytes; + eth::Instruction load = _fromCalldata ? eth::Instruction::CALLDATALOAD : eth::Instruction::MLOAD; + solAssert(numBytes <= 32, "Static memory load of more than 32 bytes requested."); + if (numBytes == 32) + m_context << u256(_offset) << load; + else + { + // load data and add leading or trailing zeros by dividing/multiplying depending on alignment + u256 shiftFactor = u256(1) << ((32 - numBytes) * 8); + m_context << shiftFactor; + if (leftAligned) + m_context << eth::Instruction::DUP1; + m_context << u256(_offset) << load << eth::Instruction::DIV; + if (leftAligned) + m_context << eth::Instruction::MUL; + } } + return numBytes; } unsigned CompilerUtils::storeInMemory(unsigned _offset, Type const& _type, bool _padToWordBoundaries) diff --git a/libsolidity/CompilerUtils.h b/libsolidity/CompilerUtils.h index fe28ceadf..89973b6be 100644 --- a/libsolidity/CompilerUtils.h +++ b/libsolidity/CompilerUtils.h @@ -37,14 +37,13 @@ public: /// Loads data from memory to the stack. /// @param _offset offset in memory (or calldata) - /// @param _bytes number of bytes to load - /// @param _leftAligned if true, store left aligned on stack (otherwise right aligned) + /// @param _type data type to load /// @param _fromCalldata if true, load from calldata, not from memory /// @param _padToWordBoundaries if true, assume the data is padded to word (32 byte) boundaries /// @returns the number of bytes consumed in memory (can be different from _bytes if - /// _padToWordBoundaries is true) - unsigned loadFromMemory(unsigned _offset, unsigned _bytes = 32, bool _leftAligned = false, - bool _fromCalldata = false, bool _padToWordBoundaries = false); + /// _padToWordBoundaries is true) + unsigned loadFromMemory(unsigned _offset, Type const& _type = IntegerType(256), + bool _fromCalldata = false, bool _padToWordBoundaries = false); /// Stores data from stack in memory. /// @param _offset offset in memory /// @param _type type of the data on the stack diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index 0f0e94f21..7128459a4 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -885,11 +885,8 @@ void ExpressionCompiler::appendExternalFunctionCall(FunctionType const& _functio m_context << eth::Instruction::POP; m_context << eth::Instruction::POP; // pop contract address - if (retSize > 0) - { - bool const c_leftAligned = firstType->getCategory() == Type::Category::String; - CompilerUtils(m_context).loadFromMemory(0, retSize, c_leftAligned, false, true); - } + if (firstType) + CompilerUtils(m_context).loadFromMemory(0, *firstType, false, true); } void ExpressionCompiler::appendArgumentsCopyToMemory(vector> const& _arguments, From 9111abbc8a3e77f7a56fa914e3c2b8f7cf271467 Mon Sep 17 00:00:00 2001 From: Christian Date: Sun, 15 Feb 2015 01:02:38 +0100 Subject: [PATCH 201/213] loadFromMemoryDynamic --- libsolidity/CompilerUtils.cpp | 63 ++++++++++++++++++++++------------- libsolidity/CompilerUtils.h | 9 +++-- test/SolidityCompiler.cpp | 10 +++--- 3 files changed, 51 insertions(+), 31 deletions(-) diff --git a/libsolidity/CompilerUtils.cpp b/libsolidity/CompilerUtils.cpp index 6f99dc7c2..0a95c3adb 100644 --- a/libsolidity/CompilerUtils.cpp +++ b/libsolidity/CompilerUtils.cpp @@ -37,32 +37,22 @@ unsigned CompilerUtils::loadFromMemory(unsigned _offset, Type const& _type, bool _fromCalldata, bool _padToWordBoundaries) { solAssert(_type.getCategory() != Type::Category::ByteArray, "Unable to statically load dynamic type."); - unsigned _encodedSize = _type.getCalldataEncodedSize(); - unsigned numBytes = _padToWordBoundaries ? getPaddedSize(_encodedSize) : _encodedSize; - bool leftAligned = _type.getCategory() == Type::Category::String; - if (numBytes == 0) - m_context << u256(0); - else - { - eth::Instruction load = _fromCalldata ? eth::Instruction::CALLDATALOAD : eth::Instruction::MLOAD; - solAssert(numBytes <= 32, "Static memory load of more than 32 bytes requested."); - if (numBytes == 32) - m_context << u256(_offset) << load; - else - { - // load data and add leading or trailing zeros by dividing/multiplying depending on alignment - u256 shiftFactor = u256(1) << ((32 - numBytes) * 8); - m_context << shiftFactor; - if (leftAligned) - m_context << eth::Instruction::DUP1; - m_context << u256(_offset) << load << eth::Instruction::DIV; - if (leftAligned) - m_context << eth::Instruction::MUL; - } - } - return numBytes; + m_context << u256(_offset); + return loadFromMemoryHelper(_type, _fromCalldata, _padToWordBoundaries); +} + +void CompilerUtils::loadFromMemoryDynamic(Type const& _type, bool _fromCalldata, bool _padToWordBoundaries) +{ + solAssert(_type.getCategory() != Type::Category::ByteArray, "Byte arrays not yet implemented."); + m_context << eth::Instruction::DUP1; + unsigned numBytes = loadFromMemoryHelper(_type, _fromCalldata, _padToWordBoundaries); + // update memory counter + for (unsigned i = 0; i < _type.getSizeOnStack(); ++i) + m_context << eth::swapInstruction(1 + i); + m_context << u256(numBytes) << eth::Instruction::ADD; } + unsigned CompilerUtils::storeInMemory(unsigned _offset, Type const& _type, bool _padToWordBoundaries) { solAssert(_type.getCategory() != Type::Category::ByteArray, "Unable to statically store dynamic type."); @@ -121,6 +111,7 @@ void CompilerUtils::storeInMemoryDynamic(Type const& _type, bool _padToWordBound unsigned numBytes = prepareMemoryStore(_type, _padToWordBoundaries); if (numBytes > 0) { + solAssert(_type.getSizeOnStack() == 1, "Memory store of types with stack size != 1 not implemented."); m_context << eth::Instruction::DUP2 << eth::Instruction::MSTORE; m_context << u256(numBytes) << eth::Instruction::ADD; } @@ -290,6 +281,30 @@ void CompilerUtils::copyByteArrayToStorage(ByteArrayType const& _targetType, } } +unsigned CompilerUtils::loadFromMemoryHelper(Type const& _type, bool _fromCalldata, bool _padToWordBoundaries) +{ + unsigned _encodedSize = _type.getCalldataEncodedSize(); + unsigned numBytes = _padToWordBoundaries ? getPaddedSize(_encodedSize) : _encodedSize; + bool leftAligned = _type.getCategory() == Type::Category::String; + if (numBytes == 0) + m_context << eth::Instruction::POP << u256(0); + else + { + solAssert(numBytes <= 32, "Static memory load of more than 32 bytes requested."); + m_context << (_fromCalldata ? eth::Instruction::CALLDATALOAD : eth::Instruction::MLOAD); + if (numBytes != 32) + { + // add leading or trailing zeros by dividing/multiplying depending on alignment + u256 shiftFactor = u256(1) << ((32 - numBytes) * 8); + m_context << shiftFactor << eth::Instruction::SWAP1 << eth::Instruction::DIV; + if (leftAligned) + m_context << shiftFactor << eth::Instruction::MUL; + } + } + + return numBytes; +} + void CompilerUtils::clearByteArray(ByteArrayType const& _type) const { solAssert(_type.getLocation() == ByteArrayType::Location::Storage, ""); diff --git a/libsolidity/CompilerUtils.h b/libsolidity/CompilerUtils.h index 89973b6be..5369d3bf2 100644 --- a/libsolidity/CompilerUtils.h +++ b/libsolidity/CompilerUtils.h @@ -40,10 +40,13 @@ public: /// @param _type data type to load /// @param _fromCalldata if true, load from calldata, not from memory /// @param _padToWordBoundaries if true, assume the data is padded to word (32 byte) boundaries - /// @returns the number of bytes consumed in memory (can be different from _bytes if - /// _padToWordBoundaries is true) + /// @returns the number of bytes consumed in memory. unsigned loadFromMemory(unsigned _offset, Type const& _type = IntegerType(256), bool _fromCalldata = false, bool _padToWordBoundaries = false); + /// Dynamic version of @see loadFromMemory, expects the memory offset on the stack. + /// Stack pre: memory_offset + /// Stack post: value... (memory_offset+length) + void loadFromMemoryDynamic(Type const& _type, bool _fromCalldata = false, bool _padToWordBoundaries = true); /// Stores data from stack in memory. /// @param _offset offset in memory /// @param _type type of the data on the stack @@ -92,6 +95,8 @@ public: private: /// Prepares the given type for storing in memory by shifting it if necessary. unsigned prepareMemoryStore(Type const& _type, bool _padToWordBoundaries) const; + /// Loads type from memory assuming memory offset is on stack top. + unsigned loadFromMemoryHelper(Type const& _type, bool _fromCalldata, bool _padToWordBoundaries); /// Appends a loop that clears a sequence of storage slots (excluding end). /// Stack pre: end_ref start_ref /// Stack post: end_ref diff --git a/test/SolidityCompiler.cpp b/test/SolidityCompiler.cpp index 17d9a7c07..1369b038f 100644 --- a/test/SolidityCompiler.cpp +++ b/test/SolidityCompiler.cpp @@ -96,7 +96,7 @@ BOOST_AUTO_TEST_CASE(smoke_test) "}\n"; bytes code = compileContract(sourceCode); - unsigned boilerplateSize = 69; + unsigned boilerplateSize = 70; bytes expectation({byte(Instruction::JUMPDEST), byte(Instruction::PUSH1), 0x0, // initialize local variable x byte(Instruction::PUSH1), 0x2, @@ -114,8 +114,8 @@ BOOST_AUTO_TEST_CASE(ifStatement) " function f() { bool x; if (x) 77; else if (!x) 78; else 79; }" "}\n"; bytes code = compileContract(sourceCode); - unsigned shift = 56; - unsigned boilerplateSize = 69; + unsigned shift = 57; + unsigned boilerplateSize = 70; bytes expectation({byte(Instruction::JUMPDEST), byte(Instruction::PUSH1), 0x0, byte(Instruction::DUP1), @@ -155,8 +155,8 @@ BOOST_AUTO_TEST_CASE(loops) " function f() { while(true){1;break;2;continue;3;return;4;} }" "}\n"; bytes code = compileContract(sourceCode); - unsigned shift = 56; - unsigned boilerplateSize = 69; + unsigned shift = 57; + unsigned boilerplateSize = 70; bytes expectation({byte(Instruction::JUMPDEST), byte(Instruction::JUMPDEST), byte(Instruction::PUSH1), 0x1, From cad718715bcfbe610be870787e85f5f68917409f Mon Sep 17 00:00:00 2001 From: Christian Date: Sun, 15 Feb 2015 02:00:33 +0100 Subject: [PATCH 202/213] Unpacking of dynamically sized arguments. --- libsolidity/Compiler.cpp | 35 ++++++++++++++++++++++++++++++----- libsolidity/Compiler.h | 4 ++-- libsolidity/Types.h | 3 +++ 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/libsolidity/Compiler.cpp b/libsolidity/Compiler.cpp index e14935873..98c9ffaac 100644 --- a/libsolidity/Compiler.cpp +++ b/libsolidity/Compiler.cpp @@ -178,15 +178,40 @@ void Compiler::appendFunctionSelector(ContractDefinition const& _contract) } } -unsigned Compiler::appendCalldataUnpacker(TypePointers const& _typeParameters, bool _fromMemory) +void Compiler::appendCalldataUnpacker(TypePointers const& _typeParameters, bool _fromMemory) { // We do not check the calldata size, everything is zero-padded. - unsigned dataOffset = CompilerUtils::dataStartOffset; // the 4 bytes of the function hash signature - + unsigned offset(CompilerUtils::dataStartOffset); bool const c_padToWords = true; + + unsigned dynamicParameterCount = 0; for (TypePointer const& type: _typeParameters) - dataOffset += CompilerUtils(m_context).loadFromMemory(dataOffset, *type, !_fromMemory, c_padToWords); - return dataOffset; + if (type->isDynamicallySized()) + dynamicParameterCount++; + offset += dynamicParameterCount * 32; + unsigned currentDynamicParameter = 0; + for (TypePointer const& type: _typeParameters) + if (type->isDynamicallySized()) + { + // value on stack: [memory_offset] (only if we are already in dynamic mode) + if (currentDynamicParameter == 0) + // switch from static to dynamic + m_context << u256(offset); + CompilerUtils(m_context).loadFromMemory( + CompilerUtils::dataStartOffset + currentDynamicParameter * 32, + IntegerType(256), !_fromMemory, c_padToWords); + // store new memory pointer + m_context << eth::Instruction::DUP2 << eth::Instruction::DUP2 << eth::Instruction::ADD; + currentDynamicParameter++; + // value on stack: offset length next_memory_offset + } + else if (currentDynamicParameter == 0) + // we can still use static load + offset += CompilerUtils(m_context).loadFromMemory(offset, *type, !_fromMemory, c_padToWords); + else + CompilerUtils(m_context).loadFromMemoryDynamic(*type, !_fromMemory, c_padToWords); + if (dynamicParameterCount > 0) + m_context << eth::Instruction::POP; } void Compiler::appendReturnValuePacker(TypePointers const& _typeParameters) diff --git a/libsolidity/Compiler.h b/libsolidity/Compiler.h index b3eae5b17..5d5b6d47b 100644 --- a/libsolidity/Compiler.h +++ b/libsolidity/Compiler.h @@ -52,8 +52,8 @@ private: void appendConstructorCall(FunctionDefinition const& _constructor); void appendFunctionSelector(ContractDefinition const& _contract); /// Creates code that unpacks the arguments for the given function represented by a vector of TypePointers. - /// From memory if @a _fromMemory is true, otherwise from call data. @returns the size of the data in bytes. - unsigned appendCalldataUnpacker(TypePointers const& _typeParameters, bool _fromMemory = false); + /// From memory if @a _fromMemory is true, otherwise from call data. + void appendCalldataUnpacker(TypePointers const& _typeParameters, bool _fromMemory = false); void appendReturnValuePacker(TypePointers const& _typeParameters); void registerStateVariables(ContractDefinition const& _contract); diff --git a/libsolidity/Types.h b/libsolidity/Types.h index 3b4eee57f..90812f564 100644 --- a/libsolidity/Types.h +++ b/libsolidity/Types.h @@ -122,6 +122,8 @@ public: /// is not a simple big-endian encoding or the type cannot be stored in calldata. /// Note that irrespective of this size, each calldata element is padded to a multiple of 32 bytes. virtual unsigned getCalldataEncodedSize() const { return 0; } + /// @returns true if the type is dynamically encoded in calldata + virtual bool isDynamicallySized() const { return false; } /// @returns number of bytes required to hold this value in storage. /// For dynamically "allocated" types, it returns the size of the statically allocated head, virtual u256 getStorageSize() const { return 1; } @@ -289,6 +291,7 @@ public: virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override; virtual TypePointer unaryOperatorResult(Token::Value _operator) const override; virtual bool operator==(const Type& _other) const override; + virtual bool isDynamicallySized() const { return true; } virtual unsigned getSizeOnStack() const override; virtual std::string toString() const override { return "bytes"; } virtual MemberList const& getMembers() const override { return s_byteArrayMemberList; } From bed225c9810b3ebecaa3540a4731e1bffa25b2f7 Mon Sep 17 00:00:00 2001 From: Christian Date: Mon, 16 Feb 2015 17:33:13 +0100 Subject: [PATCH 203/213] Calldata byte arrays stored on the stack. --- libsolidity/AST.cpp | 9 ++++++++ libsolidity/Compiler.cpp | 17 +++++++++----- libsolidity/CompilerUtils.cpp | 34 +++++++++++++++++----------- libsolidity/ExpressionCompiler.cpp | 19 ++++++++++++---- libsolidity/Types.cpp | 11 +++++++-- libsolidity/Types.h | 4 ++++ test/SolidityEndToEndTest.cpp | 36 ++++++++++++++++++++++++++---- 7 files changed, 101 insertions(+), 29 deletions(-) diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp index 0fafd2d12..c6d8f5c58 100644 --- a/libsolidity/AST.cpp +++ b/libsolidity/AST.cpp @@ -274,6 +274,15 @@ TypePointer FunctionDefinition::getType(ContractDefinition const*) const void FunctionDefinition::checkTypeRequirements() { + // change all byte arrays parameters to point to calldata + if (getVisibility() == Visibility::External) + for (ASTPointer const& var: getParameters()) + { + auto const& type = var->getType(); + solAssert(!!type, ""); + if (auto const* byteArrayType = dynamic_cast(type.get())) + var->setType(byteArrayType->copyForLocation(ByteArrayType::Location::CallData)); + } for (ASTPointer const& var: getParameters() + getReturnParameters()) if (!var->getType()->canLiveOutsideStorage()) BOOST_THROW_EXCEPTION(var->createTypeError("Type is required to live outside storage.")); diff --git a/libsolidity/Compiler.cpp b/libsolidity/Compiler.cpp index 98c9ffaac..14acc0113 100644 --- a/libsolidity/Compiler.cpp +++ b/libsolidity/Compiler.cpp @@ -193,17 +193,23 @@ void Compiler::appendCalldataUnpacker(TypePointers const& _typeParameters, bool for (TypePointer const& type: _typeParameters) if (type->isDynamicallySized()) { - // value on stack: [memory_offset] (only if we are already in dynamic mode) + // value on stack: [calldata_offset] (only if we are already in dynamic mode) if (currentDynamicParameter == 0) // switch from static to dynamic m_context << u256(offset); + // retrieve length CompilerUtils(m_context).loadFromMemory( CompilerUtils::dataStartOffset + currentDynamicParameter * 32, IntegerType(256), !_fromMemory, c_padToWords); - // store new memory pointer - m_context << eth::Instruction::DUP2 << eth::Instruction::DUP2 << eth::Instruction::ADD; + // stack: offset length + // add 32-byte padding to copy of length + m_context << u256(32) << eth::Instruction::DUP1 << u256(31) + << eth::Instruction::DUP4 << eth::Instruction::ADD + << eth::Instruction::DIV << eth::Instruction::MUL; + // stack: offset length padded_length + m_context << eth::Instruction::DUP3 << eth::Instruction::ADD; currentDynamicParameter++; - // value on stack: offset length next_memory_offset + // stack: offset length next_calldata_offset } else if (currentDynamicParameter == 0) // we can still use static load @@ -294,8 +300,7 @@ bool Compiler::visit(FunctionDefinition const& _function) // Note that the fact that the return arguments are of increasing index is vital for this // algorithm to work. - unsigned const c_argumentsSize = (_function.getVisibility() == Declaration::Visibility::External - ? 0 : CompilerUtils::getSizeOnStack(_function.getParameters())); + unsigned const c_argumentsSize = CompilerUtils::getSizeOnStack(_function.getParameters()); unsigned const c_returnValuesSize = CompilerUtils::getSizeOnStack(_function.getReturnParameters()); unsigned const c_localVariablesSize = CompilerUtils::getSizeOnStack(_function.getLocalVariables()); diff --git a/libsolidity/CompilerUtils.cpp b/libsolidity/CompilerUtils.cpp index 0a95c3adb..047bc6d62 100644 --- a/libsolidity/CompilerUtils.cpp +++ b/libsolidity/CompilerUtils.cpp @@ -70,9 +70,12 @@ void CompilerUtils::storeInMemoryDynamic(Type const& _type, bool _padToWordBound if (type.getLocation() == ByteArrayType::Location::CallData) { - m_context << eth::Instruction::CALLDATASIZE << u256(0) << eth::Instruction::DUP3 - << eth::Instruction::CALLDATACOPY - << eth::Instruction::CALLDATASIZE << eth::Instruction::ADD; + // stack: target source_offset source_len + m_context << eth::Instruction::DUP1 << eth::Instruction::DUP3 << eth::Instruction::DUP5 + // stack: target source_offset source_len source_len source_offset target + << eth::Instruction::CALLDATACOPY + << eth::Instruction::DUP3 << eth::Instruction::ADD + << eth::Instruction::SWAP2 << eth::Instruction::POP << eth::Instruction::POP; } else { @@ -171,29 +174,32 @@ void CompilerUtils::copyByteArrayToStorage(ByteArrayType const& _targetType, { case ByteArrayType::Location::CallData: { - // @todo this does not take length into account. It also assumes that after "CALLDATALENGTH" we only have zeros. + // This also assumes that after "length" we only have zeros, i.e. it cannot be used to + // slice a byte array from calldata. + + // stack: source_offset source_len target_ref // fetch old length and convert to words m_context << eth::Instruction::DUP1 << eth::Instruction::SLOAD; m_context << u256(31) << eth::Instruction::ADD << u256(32) << eth::Instruction::SWAP1 << eth::Instruction::DIV; - // stack here: target_ref target_length_words + // stack here: source_offset source_len target_ref target_length_words // actual array data is stored at SHA3(storage_offset) m_context << eth::Instruction::DUP2; CompilerUtils(m_context).computeHashStatic(); // compute target_data_end m_context << eth::Instruction::DUP1 << eth::Instruction::SWAP2 << eth::Instruction::ADD << eth::Instruction::SWAP1; - // stack here: target_ref target_data_end target_data_ref + // stack here: source_offset source_len target_ref target_data_end target_data_ref // store length (in bytes) - m_context << eth::Instruction::CALLDATASIZE; - m_context << eth::Instruction::DUP1 << eth::Instruction::DUP5 << eth::Instruction::SSTORE; + m_context << eth::Instruction::DUP4 << eth::Instruction::DUP1 << eth::Instruction::DUP5 + << eth::Instruction::SSTORE; // jump to end if length is zero m_context << eth::Instruction::ISZERO; eth::AssemblyItem copyLoopEnd = m_context.newTag(); m_context.appendConditionalJumpTo(copyLoopEnd); // store start offset - m_context << u256(0); - // stack now: target_ref target_data_end target_data_ref calldata_offset + m_context << eth::Instruction::DUP5; + // stack now: source_offset source_len target_ref target_data_end target_data_ref calldata_offset eth::AssemblyItem copyLoopStart = m_context.newTag(); m_context << copyLoopStart // copy from calldata and store @@ -204,16 +210,18 @@ void CompilerUtils::copyByteArrayToStorage(ByteArrayType const& _targetType, // increment calldata_offset by 32 << eth::Instruction::SWAP1 << u256(32) << eth::Instruction::ADD // check for loop condition - << eth::Instruction::DUP1 << eth::Instruction::CALLDATASIZE << eth::Instruction::GT; + << eth::Instruction::DUP1 << eth::Instruction::DUP6 << eth::Instruction::GT; m_context.appendConditionalJumpTo(copyLoopStart); m_context << eth::Instruction::POP; m_context << copyLoopEnd; // now clear leftover bytes of the old value - // stack now: target_ref target_data_end target_data_ref + // stack now: source_offset source_len target_ref target_data_end target_data_ref clearStorageLoop(); + // stack now: source_offset source_len target_ref target_data_end - m_context << eth::Instruction::POP; + m_context << eth::Instruction::POP << eth::Instruction::SWAP2 + << eth::Instruction::POP << eth::Instruction::POP; break; } case ByteArrayType::Location::Storage: diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index 7128459a4..3bf1c8c93 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -475,9 +475,7 @@ void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess) else if (member == "gasprice") m_context << eth::Instruction::GASPRICE; else if (member == "data") - { - // nothing to store on the stack - } + m_context << u256(0) << eth::Instruction::CALLDATASIZE; else BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown magic member.")); break; @@ -510,6 +508,7 @@ void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess) m_context << m_context.getFunctionEntryLabel(*function).pushTag(); return; } + solAssert(false, "Function not found in member access."); } else if (auto enumType = dynamic_cast(type.getActualType().get())) m_context << enumType->getMemberValue(_memberAccess.getMemberName()); @@ -518,7 +517,19 @@ void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess) case Type::Category::ByteArray: { solAssert(member == "length", "Illegal bytearray member."); - m_context << eth::Instruction::SLOAD; + auto const& type = dynamic_cast(*_memberAccess.getExpression().getType()); + switch (type.getLocation()) + { + case ByteArrayType::Location::CallData: + m_context << eth::Instruction::SWAP1 << eth::Instruction::POP; + break; + case ByteArrayType::Location::Storage: + m_context << eth::Instruction::SLOAD; + break; + default: + solAssert(false, "Unsupported byte array location."); + break; + } break; } default: diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index 99515a3ac..6149f34f8 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -540,12 +540,19 @@ bool ByteArrayType::operator==(Type const& _other) const unsigned ByteArrayType::getSizeOnStack() const { if (m_location == Location::CallData) - return 0; + // offset, length (stack top) + return 2; else + // offset return 1; } -const MemberList ByteArrayType::s_byteArrayMemberList = MemberList({{"length", make_shared(256)}}); +shared_ptr ByteArrayType::copyForLocation(ByteArrayType::Location _location) const +{ + return make_shared(_location); +} + +const MemberList ByteArrayType::s_byteArrayMemberList = MemberList({{"length", make_shared(256)}}); bool ContractType::operator==(Type const& _other) const { diff --git a/libsolidity/Types.h b/libsolidity/Types.h index 90812f564..b66857f0c 100644 --- a/libsolidity/Types.h +++ b/libsolidity/Types.h @@ -298,6 +298,10 @@ public: Location getLocation() const { return m_location; } + /// @returns a copy of this type with location changed to @a _location + /// @todo this might move as far up as Type later + std::shared_ptr copyForLocation(Location _location) const; + private: Location m_location; static const MemberList s_byteArrayMemberList; diff --git a/test/SolidityEndToEndTest.cpp b/test/SolidityEndToEndTest.cpp index 9899af29f..103b11269 100644 --- a/test/SolidityEndToEndTest.cpp +++ b/test/SolidityEndToEndTest.cpp @@ -2283,9 +2283,9 @@ BOOST_AUTO_TEST_CASE(bytes_from_calldata_to_memory) } )"; compileAndRun(sourceCode); - bytes calldata = bytes(61, 0x22) + bytes(12, 0x12); - sendMessage(calldata, false); - BOOST_CHECK(m_output == encodeArgs(dev::sha3(bytes{'a', 'b', 'c'} + calldata))); + bytes calldata1 = bytes(61, 0x22) + bytes(12, 0x12); + sendMessage(calldata1, false); + BOOST_CHECK(m_output == encodeArgs(dev::sha3(bytes{'a', 'b', 'c'} + calldata1))); } BOOST_AUTO_TEST_CASE(call_forward_bytes) @@ -2546,7 +2546,35 @@ BOOST_AUTO_TEST_CASE(external_function) } )"; compileAndRun(sourceCode); - BOOST_CHECK(callContractFunction("test(uint256,uint256)", 2, 3) == encodeArgs(2, 3+7)); + BOOST_CHECK(callContractFunction("test(uint256,uint256)", 2, 3) == encodeArgs(2+7, 3)); +} + +BOOST_AUTO_TEST_CASE(bytes_in_arguments) +{ + char const* sourceCode = R"( + contract c { + uint result; + function f(uint a, uint b) { result += a + b; } + function g(uint a) { result *= a; } + function test(uint a, bytes data1, bytes data2, uint b) external returns (uint r_a, uint r, uint r_b, uint l) { + r_a = a; + this.call(data1); + this.call(data2); + r = result; + r_b = b; + l = data1.length; + } + } + )"; + compileAndRun(sourceCode); + string innercalldata1 = asString(FixedHash<4>(dev::sha3("f(uint256,uint256)")).asBytes() + encodeArgs(8, 9)); + bytes calldata1 = encodeArgs(u256(innercalldata1.length()), 12, innercalldata1, 13); + string innercalldata2 = asString(FixedHash<4>(dev::sha3("g(uint256)")).asBytes() + encodeArgs(3)); + bytes calldata = encodeArgs( + u256(innercalldata1.length()), u256(innercalldata2.length()), + 12, innercalldata1, innercalldata2, 13); + BOOST_CHECK(callContractFunction("test(uint256,bytes,bytes,uint256)", calldata) + == encodeArgs(12, (8 + 9) * 3, 13, u256(innercalldata1.length()))); } BOOST_AUTO_TEST_SUITE_END() From 092312d4af60fa50589d5c0366482e88ef8f633a Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 16 Feb 2015 22:29:28 +0100 Subject: [PATCH 204/213] - small ui changes. - bug fix: mix, windows - unreadable fonts #1051. --- mix/qml/Debugger.qml | 7 +++++++ mix/qml/DefaultLabel.qml | 6 ------ mix/qml/DefaultTextField.qml | 7 ------- mix/qml/Ether.qml | 8 -------- mix/qml/StateDialog.qml | 2 +- mix/qml/TransactionDialog.qml | 10 +--------- mix/qml/WebPreview.qml | 14 ++++---------- 7 files changed, 13 insertions(+), 41 deletions(-) diff --git a/mix/qml/Debugger.qml b/mix/qml/Debugger.qml index 1dd05574f..098cc77d1 100644 --- a/mix/qml/Debugger.qml +++ b/mix/qml/Debugger.qml @@ -131,7 +131,14 @@ Rectangle { Layout.fillWidth: true Layout.minimumHeight: 60 height: 250 + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + anchors.leftMargin: machineStates.sideMargin + anchors.rightMargin: machineStates.sideMargin + anchors.topMargin: machineStates.sideMargin } + ScrollView { property int sideMargin: 10 diff --git a/mix/qml/DefaultLabel.qml b/mix/qml/DefaultLabel.qml index a1304e673..d8ef1faff 100644 --- a/mix/qml/DefaultLabel.qml +++ b/mix/qml/DefaultLabel.qml @@ -4,12 +4,6 @@ import "." Label { text: text - font.family: regularFont.name - font.pointSize: Style.generic.size.titlePointSize - SourceSansProLight - { - id: regularFont - } } diff --git a/mix/qml/DefaultTextField.qml b/mix/qml/DefaultTextField.qml index 6705273db..de306fa5e 100644 --- a/mix/qml/DefaultTextField.qml +++ b/mix/qml/DefaultTextField.qml @@ -3,11 +3,4 @@ import QtQuick.Controls 1.1 TextField { id: titleField - focus: true - font.family: regularFont.name - - SourceSansProRegular - { - id: regularFont; - } } diff --git a/mix/qml/Ether.qml b/mix/qml/Ether.qml index be41fced9..1a0f7ffe6 100644 --- a/mix/qml/Ether.qml +++ b/mix/qml/Ether.qml @@ -49,10 +49,6 @@ RowLayout { id: etherValueEdit; } - SourceSansProBold { - id: regularFont; - } - ComboBox { id: units @@ -87,15 +83,11 @@ RowLayout { ListElement { text: "Kwei"; } ListElement { text: "wei"; } } - style: ComboBoxStyle { - font: regularFont.name - } } Text { visible: displayFormattedValue id: formattedValue - font.family: regularFont.name } } diff --git a/mix/qml/StateDialog.qml b/mix/qml/StateDialog.qml index eeda2ae22..abb045497 100644 --- a/mix/qml/StateDialog.qml +++ b/mix/qml/StateDialog.qml @@ -12,7 +12,7 @@ Window { id: modalStateDialog modality: Qt.ApplicationModal - width: 450 + width: 520 height: 480 title: qsTr("Edit State") visible: false diff --git a/mix/qml/TransactionDialog.qml b/mix/qml/TransactionDialog.qml index a38886354..c71bd4155 100644 --- a/mix/qml/TransactionDialog.qml +++ b/mix/qml/TransactionDialog.qml @@ -10,7 +10,7 @@ import "." Window { id: modalTransactionDialog modality: Qt.ApplicationModal - width: 450 + width: 520 height: (paramsModel.count > 0 ? 500 : 300) visible: false color: StateDialogStyle.generic.backgroundColor @@ -174,11 +174,6 @@ Window { anchors.fill: parent anchors.margins: 10 - SourceSansProLight - { - id: lightFont - } - ColumnLayout { id: dialogContent anchors.top: parent.top @@ -204,9 +199,6 @@ Window { onCurrentIndexChanged: { loadParameters(); } - style: ComboBoxStyle { - font: lightFont.name - } } } diff --git a/mix/qml/WebPreview.qml b/mix/qml/WebPreview.qml index 88b992b54..5d4d0e617 100644 --- a/mix/qml/WebPreview.qml +++ b/mix/qml/WebPreview.qml @@ -162,11 +162,6 @@ Item { spacing: 0 Rectangle { - SourceSansProLight - { - id: regularFont - } - anchors.leftMargin: 4 color: WebPreviewStyle.general.headerBackgroundColor Layout.preferredWidth: parent.width @@ -188,9 +183,7 @@ Item { currentIndex: -1 onCurrentIndexChanged: changePage() anchors.verticalCenter: parent.verticalCenter - style: ComboBoxStyle { - font: regularFont.name - } + height: 21 } Action { @@ -205,12 +198,13 @@ Item { iconSource: "qrc:/qml/img/available_updates.png" action: buttonReloadAction anchors.verticalCenter: parent.verticalCenter - width: 26 - height: 26 + width: 21 + height: 21 } CheckBox { id: autoReloadOnSave checked: true + height: 21 anchors.verticalCenter: parent.verticalCenter style: CheckBoxStyle { label: DefaultLabel { From 7af5ac1252a289790e8d0ff346e29b0b6c850d2a Mon Sep 17 00:00:00 2001 From: arkpar Date: Sun, 15 Feb 2015 20:02:40 +0100 Subject: [PATCH 205/213] allow more than one contract --- libsolidity/Compiler.h | 2 + mix/CMakeLists.txt | 2 +- mix/ClientModel.cpp | 67 ++++++---- mix/ClientModel.h | 21 ++-- mix/CodeModel.cpp | 213 ++++++++++++++++++-------------- mix/CodeModel.h | 76 ++++++------ mix/QContractDefinition.cpp | 2 +- mix/QContractDefinition.h | 2 +- mix/StatusPane.cpp | 11 -- mix/StatusPane.h | 4 - mix/qml/CodeEditorView.qml | 2 +- mix/qml/Debugger.qml | 2 +- mix/qml/MainContent.qml | 2 +- mix/qml/ProjectList.qml | 21 ++-- mix/qml/ProjectModel.qml | 2 +- mix/qml/StateListModel.qml | 18 +-- mix/qml/StatusPane.qml | 14 ++- mix/qml/TransactionDialog.qml | 107 ++++++++++++---- mix/qml/WebPreview.qml | 12 +- mix/qml/html/WebContainer.html | 16 +-- mix/qml/js/ProjectModel.js | 77 ++++++++---- mix/qml/js/TransactionHelper.js | 1 - mix/qml/main.qml | 2 +- 23 files changed, 409 insertions(+), 267 deletions(-) diff --git a/libsolidity/Compiler.h b/libsolidity/Compiler.h index b3eae5b17..cbfb8dae0 100644 --- a/libsolidity/Compiler.h +++ b/libsolidity/Compiler.h @@ -20,6 +20,8 @@ * Solidity AST to EVM bytecode compiler. */ +#pragma once + #include #include #include diff --git a/mix/CMakeLists.txt b/mix/CMakeLists.txt index 4390a4eb0..892f2c1ed 100644 --- a/mix/CMakeLists.txt +++ b/mix/CMakeLists.txt @@ -71,4 +71,4 @@ eth_install_executable(${EXECUTABLE} #add qml asnd stdc files to project tree in Qt creator file(GLOB_RECURSE QMLFILES "qml/*.*") file(GLOB_RECURSE SOLFILES "stdc/*.*") -add_custom_target(dummy SOURCES ${QMLFILES} ${SOLFILES}) +add_custom_target(mix_qml SOURCES ${QMLFILES} ${SOLFILES}) diff --git a/mix/ClientModel.cpp b/mix/ClientModel.cpp index 57caf573c..91e5c98ab 100644 --- a/mix/ClientModel.cpp +++ b/mix/ClientModel.cpp @@ -65,7 +65,7 @@ private: ClientModel::ClientModel(AppContext* _context): - m_context(_context), m_running(false), m_rpcConnector(new RpcConnector()), m_contractAddress(Address()) + m_context(_context), m_running(false), m_rpcConnector(new RpcConnector()) { qRegisterMetaType("QBigInt*"); qRegisterMetaType("QIntType*"); @@ -136,9 +136,12 @@ void ClientModel::mine() }); } -QString ClientModel::contractAddress() const +QVariantMap ClientModel::contractAddresses() const { - return QString::fromStdString(dev::toJS(m_contractAddress)); + QVariantMap res; + for (auto const& c: m_contractAddresses) + res.insert(c.first, QString::fromStdString(dev::toJS(c.second))); + return res; } void ClientModel::debugDeployment() @@ -155,8 +158,8 @@ void ClientModel::setupState(QVariantMap _state) for (auto const& t: transactions) { QVariantMap transaction = t.toMap(); + QString contractId = transaction.value("contractId").toString(); QString functionId = transaction.value("functionId").toString(); - u256 gas = boost::get(qvariant_cast(transaction.value("gas"))->internalValue()); u256 value = (qvariant_cast(transaction.value("value")))->toU256Wei(); u256 gasPrice = (qvariant_cast(transaction.value("gasPrice")))->toU256Wei(); @@ -164,7 +167,9 @@ void ClientModel::setupState(QVariantMap _state) bool isStdContract = (transaction.value("stdContract").toBool()); if (isStdContract) { - TransactionSettings transactionSettings(functionId, transaction.value("url").toString()); + if (contractId.isEmpty()) //TODO: This is to support old project files, remove later + contractId = functionId; + TransactionSettings transactionSettings(contractId, transaction.value("url").toString()); transactionSettings.gasPrice = 10000000000000; transactionSettings.gas = 125000; transactionSettings.value = 0; @@ -172,8 +177,10 @@ void ClientModel::setupState(QVariantMap _state) } else { + if (contractId.isEmpty() && m_context->codeModel()->hasContract()) //TODO: This is to support old project files, remove later + contractId = m_context->codeModel()->contracts().keys()[0]; QVariantList qParams = transaction.value("qType").toList(); - TransactionSettings transactionSettings(functionId, value, gas, gasPrice); + TransactionSettings transactionSettings(contractId, functionId, value, gas, gasPrice); for (QVariant const& variant: qParams) { @@ -181,7 +188,7 @@ void ClientModel::setupState(QVariantMap _state) transactionSettings.parameterValues.push_back(param); } - if (transaction.value("executeConstructor").toBool()) + if (contractId == functionId || functionId == "Constructor") transactionSettings.functionId.clear(); transactionSequence.push_back(transactionSettings); @@ -194,8 +201,6 @@ void ClientModel::executeSequence(std::vector const& _seque { if (m_running) BOOST_THROW_EXCEPTION(ExecutionStateException()); - CompilationResult* compilerRes = m_context->codeModel()->code(); - std::shared_ptr contractDef = compilerRes->sharedContract(); m_running = true; emit runStarted(); @@ -206,7 +211,6 @@ void ClientModel::executeSequence(std::vector const& _seque { try { - bytes contractCode = compilerRes->bytes(); m_client->resetState(_balance); onStateReset(); for (TransactionSettings const& transaction: _sequence) @@ -216,14 +220,17 @@ void ClientModel::executeSequence(std::vector const& _seque if (!transaction.stdContractUrl.isEmpty()) { //std contract - dev::bytes const& stdContractCode = m_context->codeModel()->getStdContractCode(transaction.functionId, transaction.stdContractUrl); + dev::bytes const& stdContractCode = m_context->codeModel()->getStdContractCode(transaction.contractId, transaction.stdContractUrl); Address address = deployContract(stdContractCode, transaction); - m_stdContractAddresses[transaction.functionId] = address; - m_stdContractNames[address] = transaction.functionId; + m_stdContractAddresses[transaction.contractId] = address; + m_stdContractNames[address] = transaction.contractId; } else { //encode data + CompiledContract const& compilerRes = m_context->codeModel()->contract(transaction.contractId); + bytes contractCode = compilerRes.bytes(); + std::shared_ptr contractDef = compilerRes.sharedContract(); f = nullptr; if (transaction.functionId.isEmpty()) f = contractDef->constructor(); @@ -240,24 +247,31 @@ void ClientModel::executeSequence(std::vector const& _seque encoder.encode(f); for (int p = 0; p < transaction.parameterValues.size(); p++) { - if (f->parametersList().at(p)->type() != transaction.parameterValues.at(p)->declaration()->type()) - BOOST_THROW_EXCEPTION(ParameterChangedException() << FunctionName(f->parametersList().at(p)->type().toStdString())); + if (f->parametersList().size() <= p || f->parametersList().at(p)->type() != transaction.parameterValues.at(p)->declaration()->type()) + BOOST_THROW_EXCEPTION(ParameterChangedException() << FunctionName(transaction.functionId.toStdString())); encoder.push(transaction.parameterValues.at(p)->encodeValue()); } - if (transaction.functionId.isEmpty()) + if (transaction.functionId.isEmpty() || transaction.functionId == transaction.contractId) { bytes param = encoder.encodedData(); contractCode.insert(contractCode.end(), param.begin(), param.end()); Address newAddress = deployContract(contractCode, transaction); - if (newAddress != m_contractAddress) + auto contractAddressIter = m_contractAddresses.find(transaction.contractId); + if (contractAddressIter == m_contractAddresses.end() || newAddress != contractAddressIter->second) { - m_contractAddress = newAddress; - contractAddressChanged(); + m_contractAddresses[transaction.contractId] = newAddress; + m_contractNames[newAddress] = transaction.contractId; + contractAddressesChanged(); } } else - callContract(m_contractAddress, encoder.encodedData(), transaction); + { + auto contractAddressIter = m_contractAddresses.find(transaction.contractId); + if (contractAddressIter == m_contractAddresses.end()) + BOOST_THROW_EXCEPTION(dev::Exception() << dev::errinfo_comment("Contract not deployed: " + transaction.contractId.toStdString())); + callContract(contractAddressIter->second, encoder.encodedData(), transaction); + } } onNewTransaction(); } @@ -338,7 +352,8 @@ void ClientModel::callContract(Address const& _contract, bytes const& _data, Tra void ClientModel::onStateReset() { - m_contractAddress = dev::Address(); + m_contractAddresses.clear(); + m_contractNames.clear(); m_stdContractAddresses.clear(); m_stdContractNames.clear(); emit stateCleared(); @@ -389,14 +404,16 @@ void ClientModel::onNewTransaction() if (creation) returned = QString::fromStdString(toJS(tr.contractAddress)); - if (m_contractAddress != 0 && (tr.address == m_contractAddress || tr.contractAddress == m_contractAddress)) + Address contractAddress = tr.address != 0 ? tr.address : tr.contractAddress; + auto contractAddressIter = m_contractNames.find(contractAddress); + if (contractAddressIter != m_contractNames.end()) { - auto compilerRes = m_context->codeModel()->code(); - QContractDefinition* def = compilerRes->contract(); + CompiledContract const& compilerRes = m_context->codeModel()->contract(contractAddressIter->second); + const QContractDefinition* def = compilerRes.contract(); contract = def->name(); if (abi) { - QFunctionDefinition* funcDef = def->getFunction(functionHash); + QFunctionDefinition const* funcDef = def->getFunction(functionHash); if (funcDef) { function = funcDef->name(); diff --git a/mix/ClientModel.h b/mix/ClientModel.h index 530dc50cf..dda60cb10 100644 --- a/mix/ClientModel.h +++ b/mix/ClientModel.h @@ -46,13 +46,13 @@ class QVariableDefinition; struct TransactionSettings { TransactionSettings() {} - TransactionSettings(QString const& _functionId, u256 _value, u256 _gas, u256 _gasPrice): - functionId(_functionId), value(_value), gas(_gas), gasPrice(_gasPrice) {} - TransactionSettings(u256 _value, u256 _gas, u256 _gasPrice): - value(_value), gas(_gas), gasPrice(_gasPrice) {} + TransactionSettings(QString const& _contractId, QString const& _functionId, u256 _value, u256 _gas, u256 _gasPrice): + contractId(_contractId), functionId(_functionId), value(_value), gas(_gas), gasPrice(_gasPrice) {} TransactionSettings(QString const& _stdContractName, QString const& _stdContractUrl): - functionId(_stdContractName), stdContractUrl(_stdContractUrl) {} + contractId(_stdContractName), stdContractUrl(_stdContractUrl) {} + /// Contract name + QString contractId; /// Contract function name QString functionId; /// Transaction value @@ -121,8 +121,8 @@ public: Q_PROPERTY(bool running MEMBER m_running NOTIFY runStateChanged) /// @returns true if currently mining Q_PROPERTY(bool mining MEMBER m_mining NOTIFY miningStateChanged) - /// @returns address of the last executed contract - Q_PROPERTY(QString contractAddress READ contractAddress NOTIFY contractAddressChanged) + /// @returns deployed contracts addresses + Q_PROPERTY(QVariantMap contractAddresses READ contractAddresses NOTIFY contractAddressesChanged) /// ethereum.js RPC request entry point /// @param _message RPC request in Json format /// @returns RPC response in Json format @@ -161,7 +161,7 @@ signals: /// @param _message Error message void runFailed(QString const& _message); /// Contract address changed - void contractAddressChanged(); + void contractAddressesChanged(); /// Execution state changed void newBlock(); /// Execution state changed @@ -177,7 +177,7 @@ signals: void stateCleared(); private: - QString contractAddress() const; + QVariantMap contractAddresses() const; void executeSequence(std::vector const& _sequence, u256 _balance); dev::Address deployContract(bytes const& _code, TransactionSettings const& _tr = TransactionSettings()); void callContract(Address const& _contract, bytes const& _data, TransactionSettings const& _tr); @@ -191,7 +191,8 @@ private: std::unique_ptr m_client; std::unique_ptr m_rpcConnector; std::unique_ptr m_web3Server; - Address m_contractAddress; + std::map m_contractAddresses; + std::map m_contractNames; std::map m_stdContractAddresses; std::map m_stdContractNames; }; diff --git a/mix/CodeModel.cpp b/mix/CodeModel.cpp index aae9dac86..d605f1c6e 100644 --- a/mix/CodeModel.cpp +++ b/mix/CodeModel.cpp @@ -21,6 +21,7 @@ */ #include +#include #include #include #include @@ -38,51 +39,31 @@ using namespace dev::mix; -void BackgroundWorker::queueCodeChange(int _jobId, QString const& _content) +const std::set c_predefinedContracts = + { "Config", "Coin", "CoinReg", "coin", "service", "owned", "mortal", "NameReg", "named", "std", "configUser" }; + +void BackgroundWorker::queueCodeChange(int _jobId) { - m_model->runCompilationJob(_jobId, _content); + m_model->runCompilationJob(_jobId); } -CompilationResult::CompilationResult(): - QObject(nullptr), - m_successful(false), - m_codeHash(qHash(QString())), - m_contract(new QContractDefinition()), - m_contractInterface("[]"), - m_codeHighlighter(new CodeHighlighter()) -{} - -CompilationResult::CompilationResult(const dev::solidity::CompilerStack& _compiler): +CompiledContract::CompiledContract(const dev::solidity::CompilerStack& _compiler, QString const& _contractName, QString const& _source): QObject(nullptr), - m_successful(true), - m_codeHash(qHash(QString())) + m_sourceHash(qHash(_source)) { - if (!_compiler.getContractNames().empty()) - { - auto const& contractDefinition = _compiler.getContractDefinition(std::string()); - m_contract.reset(new QContractDefinition(&contractDefinition)); - m_bytes = _compiler.getBytecode(); - dev::solidity::InterfaceHandler interfaceHandler; - m_contractInterface = QString::fromStdString(*interfaceHandler.getABIInterface(contractDefinition)); - if (m_contractInterface.isEmpty()) - m_contractInterface = "[]"; - } - else - m_contract.reset(new QContractDefinition()); + auto const& contractDefinition = _compiler.getContractDefinition(_contractName.toStdString()); + m_contract.reset(new QContractDefinition(&contractDefinition)); + QQmlEngine::setObjectOwnership(m_contract.get(), QQmlEngine::CppOwnership); + m_bytes = _compiler.getBytecode(_contractName.toStdString()); + dev::solidity::InterfaceHandler interfaceHandler; + m_contractInterface = QString::fromStdString(*interfaceHandler.getABIInterface(contractDefinition)); + if (m_contractInterface.isEmpty()) + m_contractInterface = "[]"; + if (contractDefinition.getLocation().sourceName.get()) + m_documentId = QString::fromStdString(*contractDefinition.getLocation().sourceName); } -CompilationResult::CompilationResult(CompilationResult const& _prev, QString const& _compilerMessage): - QObject(nullptr), - m_successful(false), - m_codeHash(qHash(QString())), - m_contract(_prev.m_contract), - m_compilerMessage(_compilerMessage), - m_bytes(_prev.m_bytes), - m_contractInterface(_prev.m_contractInterface), - m_codeHighlighter(_prev.m_codeHighlighter) -{} - -QString CompilationResult::codeHex() const +QString CompiledContract::codeHex() const { return QString::fromStdString(toJS(m_bytes)); } @@ -90,27 +71,26 @@ QString CompilationResult::codeHex() const CodeModel::CodeModel(QObject* _parent): QObject(_parent), m_compiling(false), - m_result(new CompilationResult()), m_codeHighlighterSettings(new CodeHighlighterSettings()), m_backgroundWorker(this), m_backgroundJobId(0) { + m_backgroundThread.start(); m_backgroundWorker.moveToThread(&m_backgroundThread); connect(this, &CodeModel::scheduleCompilationJob, &m_backgroundWorker, &BackgroundWorker::queueCodeChange, Qt::QueuedConnection); - connect(this, &CodeModel::compilationCompleteInternal, this, &CodeModel::onCompilationComplete, Qt::QueuedConnection); - qRegisterMetaType("CompilationResult*"); + qRegisterMetaType("CompiledContract*"); qRegisterMetaType("QContractDefinition*"); qRegisterMetaType("QFunctionDefinition*"); qRegisterMetaType("QVariableDeclaration*"); qmlRegisterType("org.ethereum.qml", 1, 0, "QFunctionDefinition"); qmlRegisterType("org.ethereum.qml", 1, 0, "QVariableDeclaration"); - m_backgroundThread.start(); } CodeModel::~CodeModel() { stop(); disconnect(this); + releaseContracts(); } void CodeModel::stop() @@ -120,80 +100,133 @@ void CodeModel::stop() m_backgroundThread.wait(); } -void CodeModel::registerCodeChange(QString const& _code) +void CodeModel::reset(QVariantMap const& _documents) { + ///@todo: cancel bg job + Guard l(x_contractMap); + releaseContracts(); + Guard pl(x_pendingContracts); + m_pendingContracts.clear(); + + for (QVariantMap::const_iterator d = _documents.cbegin(); d != _documents.cend(); d++) + m_pendingContracts[d.key()] = d.value().toString(); // launch the background thread - uint hash = qHash(_code); - if (m_result->m_codeHash == hash) - return; - m_backgroundJobId++; m_compiling = true; emit stateChanged(); - emit scheduleCompilationJob(m_backgroundJobId, _code); + emit scheduleCompilationJob(++m_backgroundJobId); } -void CodeModel::runCompilationJob(int _jobId, QString const& _code) +void CodeModel::registerCodeChange(QString const& _documentId, QString const& _code) { - if (_jobId != m_backgroundJobId) - return; //obsolete job + { + Guard l(x_contractMap); + CompiledContract* contract = m_contractMap.value(_documentId); + if (contract != nullptr && contract->m_sourceHash == qHash(_code)) + return; - solidity::CompilerStack cs(true); - std::unique_ptr result; + Guard pl(x_pendingContracts); + m_pendingContracts[_documentId] = _code; + } + + // launch the background thread + m_compiling = true; + emit stateChanged(); + emit scheduleCompilationJob(++m_backgroundJobId); +} + +QVariantMap CodeModel::contracts() const +{ + QVariantMap result; + Guard l(x_contractMap); + for (ContractMap::const_iterator c = m_contractMap.cbegin(); c != m_contractMap.cend(); c++) + result.insert(c.key(), QVariant::fromValue(c.value())); + return result; +} - std::string source = _code.toStdString(); - // run syntax highlighting first - // @todo combine this with compilation step - auto codeHighlighter = std::make_shared(); - codeHighlighter->processSource(source); +CompiledContract* CodeModel::contractByDocumentId(QString _documentId) const +{ + Guard l(x_contractMap); + for (ContractMap::const_iterator c = m_contractMap.cbegin(); c != m_contractMap.cend(); c++) + if (c.value()->m_documentId == _documentId) + return c.value(); + return nullptr; +} + +CompiledContract const& CodeModel::contract(QString _name) const +{ + Guard l(x_contractMap); + CompiledContract* res = m_contractMap.value(_name); + if (res == nullptr) + BOOST_THROW_EXCEPTION(dev::Exception() << dev::errinfo_comment("Contract not found: " + _name.toStdString())); + return *res; +} - cs.addSource("configUser", R"(contract configUser{function configAddr()constant returns(address a){ return 0xf025d81196b72fba60a1d4dddad12eeb8360d828;}})"); +void CodeModel::releaseContracts() +{ + for (ContractMap::iterator c = m_contractMap.begin(); c != m_contractMap.end(); c++) + c.value()->deleteLater(); + m_contractMap.clear(); +} + +void CodeModel::runCompilationJob(int _jobId) +{ + if (_jobId != m_backgroundJobId) + return; //obsolete job - // run compilation + ContractMap result; + solidity::CompilerStack cs(true); try { - cs.addSource("", source); + cs.addSource("configUser", R"(contract configUser{function configAddr()constant returns(address a){ return 0xf025d81196b72fba60a1d4dddad12eeb8360d828;}})"); + { + Guard l(x_pendingContracts); + for (auto const& c: m_pendingContracts) + cs.addSource(c.first.toStdString(), c.second.toStdString()); + } cs.compile(false); - codeHighlighter->processAST(cs.getAST()); - result.reset(new CompilationResult(cs)); - qDebug() << QString(QApplication::tr("compilation succeeded")); + + { + Guard pl(x_pendingContracts); + Guard l(x_contractMap); + for (std::string n: cs.getContractNames()) + { + if (c_predefinedContracts.count(n) != 0) + continue; + QString name = QString::fromStdString(n); + auto sourceIter = m_pendingContracts.find(name); + QString source = sourceIter != m_pendingContracts.end() ? sourceIter->second : QString(); + CompiledContract* contract = new CompiledContract(cs, name, source); + QQmlEngine::setObjectOwnership(contract, QQmlEngine::CppOwnership); + result[name] = contract; + CompiledContract* prevContract = m_contractMap.value(name); + if (prevContract != nullptr && prevContract->contractInterface() != result[name]->contractInterface()) + emit contractInterfaceChanged(name); + } + releaseContracts(); + m_contractMap.swap(result); + emit codeChanged(); + emit compilationComplete(); + } } catch (dev::Exception const& _exception) { std::ostringstream error; solidity::SourceReferenceFormatter::printExceptionInformation(error, _exception, "Error", cs); - result.reset(new CompilationResult(*m_result, QString::fromStdString(error.str()))); - codeHighlighter->processError(_exception); - qDebug() << QString(QApplication::tr("compilation failed:") + " " + result->compilerMessage()); + solidity::Location const* location = boost::get_error_info(_exception); + QString message = QString::fromStdString(error.str()); + CompiledContract* contract = nullptr; + if (location && location->sourceName.get() && (contract = contractByDocumentId(QString::fromStdString(*location->sourceName)))) + message = message.replace(QString::fromStdString(*location->sourceName), contract->contract()->name()); //substitute the location to match our contract names + compilationError(message); } - result->m_codeHighlighter = codeHighlighter; - result->m_codeHash = qHash(_code); - - emit compilationCompleteInternal(result.release()); -} - -void CodeModel::onCompilationComplete(CompilationResult* _newResult) -{ m_compiling = false; - bool contractChanged = m_result->contractInterface() != _newResult->contractInterface(); - m_result.reset(_newResult); - emit compilationComplete(); emit stateChanged(); - if (m_result->successful()) - { - emit codeChanged(); - if (contractChanged) - emit contractInterfaceChanged(); - } } bool CodeModel::hasContract() const { - return m_result->successful(); -} - -void CodeModel::updateFormatting(QTextDocument* _document) -{ - m_result->codeHighlighter()->updateFormatting(_document, *m_codeHighlighterSettings); + Guard l(x_contractMap); + return m_contractMap.size() != 0; } dev::bytes const& CodeModel::getStdContractCode(const QString& _contractName, const QString& _url) diff --git a/mix/CodeModel.h b/mix/CodeModel.h index 0262aa094..48dbbcd6c 100644 --- a/mix/CodeModel.h +++ b/mix/CodeModel.h @@ -27,7 +27,9 @@ #include #include #include +#include #include +#include class QTextDocument; @@ -56,59 +58,50 @@ public: BackgroundWorker(CodeModel* _model): QObject(), m_model(_model) {} public slots: - void queueCodeChange(int _jobId, QString const& _content); + void queueCodeChange(int _jobId); private: CodeModel* m_model; }; ///Compilation result model. Contains all the compiled contract data required by UI -class CompilationResult: public QObject +class CompiledContract: public QObject { Q_OBJECT Q_PROPERTY(QContractDefinition* contract READ contract) - Q_PROPERTY(QString compilerMessage READ compilerMessage CONSTANT) - Q_PROPERTY(bool successful READ successful CONSTANT) Q_PROPERTY(QString contractInterface READ contractInterface CONSTANT) Q_PROPERTY(QString codeHex READ codeHex CONSTANT) + Q_PROPERTY(QString documentId MEMBER m_documentId CONSTANT) public: - /// Empty compilation result constructor - CompilationResult(); /// Successful compilation result constructor - CompilationResult(solidity::CompilerStack const& _compiler); - /// Failed compilation result constructor - CompilationResult(CompilationResult const& _prev, QString const& _compilerMessage); + CompiledContract(solidity::CompilerStack const& _compiler, QString const& _contractName, QString const& _source); /// @returns contract definition for QML property - QContractDefinition* contract() { return m_contract.get(); } + QContractDefinition* contract() const { return m_contract.get(); } /// @returns contract definition - std::shared_ptr sharedContract() { return m_contract; } - /// Indicates if the compilation was successful - bool successful() const { return m_successful; } - /// @returns compiler error message in case of unsuccessful compilation - QString compilerMessage() const { return m_compilerMessage; } + std::shared_ptr sharedContract() const { return m_contract; } /// @returns contract bytecode dev::bytes const& bytes() const { return m_bytes; } /// @returns contract bytecode as hex string QString codeHex() const; /// @returns contract definition in JSON format QString contractInterface() const { return m_contractInterface; } - /// Get code highlighter - std::shared_ptr codeHighlighter() { return m_codeHighlighter; } private: - bool m_successful; - uint m_codeHash; + uint m_sourceHash; std::shared_ptr m_contract; QString m_compilerMessage; ///< @todo: use some structure here dev::bytes m_bytes; QString m_contractInterface; - std::shared_ptr m_codeHighlighter; + QString m_documentId; friend class CodeModel; }; -/// Background code compiler + +using ContractMap = QHash; + +/// Code compilation model. Compiles contracts in background an provides compiled contract data class CodeModel: public QObject { Q_OBJECT @@ -117,56 +110,59 @@ public: CodeModel(QObject* _parent); ~CodeModel(); - /// @returns latest compilation result - CompilationResult* code() { return m_result.get(); } - /// @returns latest compilation resul - CompilationResult const* code() const { return m_result.get(); } - - Q_PROPERTY(CompilationResult* code READ code NOTIFY codeChanged) + Q_PROPERTY(QVariantMap contracts READ contracts NOTIFY codeChanged) Q_PROPERTY(bool compiling READ isCompiling NOTIFY stateChanged) Q_PROPERTY(bool hasContract READ hasContract NOTIFY codeChanged) + /// @returns latest compilation results for contracts + QVariantMap contracts() const; /// @returns compilation status bool isCompiling() const { return m_compiling; } - /// @returns true if contract has at least one function + /// @returns true there is a contract which has at least one function bool hasContract() const; - /// Apply text document formatting. @todo Move this to editor module - void updateFormatting(QTextDocument* _document); /// Get contract code by url. Contract is compiled on first access and cached dev::bytes const& getStdContractCode(QString const& _contractName, QString const& _url); + /// Get contract by name + CompiledContract const& contract(QString _name) const; + /// Find a contract by document id + /// @returns CompiledContract object or null if not found + Q_INVOKABLE CompiledContract* contractByDocumentId(QString _documentId) const; signals: /// Emited on compilation state change void stateChanged(); /// Emitted on compilation complete void compilationComplete(); + /// Emitted on compilation error + void compilationError(QString _error); /// Internal signal used to transfer compilation job to background thread - void scheduleCompilationJob(int _jobId, QString const& _content); + void scheduleCompilationJob(int _jobId); /// Emitted if there are any changes in the code model void codeChanged(); /// Emitted if there are any changes in the contract interface - void contractInterfaceChanged(); - /// Emitted on compilation complete. Internal - void compilationCompleteInternal(CompilationResult* _newResult); - -private slots: - void onCompilationComplete(CompilationResult* _newResult); + void contractInterfaceChanged(QString _documentId); public slots: /// Update code model on source code change - void registerCodeChange(QString const& _code); + void registerCodeChange(QString const& _documentId, QString const& _code); + /// Reset code model for a new project + void reset(QVariantMap const& _documents); private: - void runCompilationJob(int _jobId, QString const& _content); + void runCompilationJob(int _jobId); void stop(); + void releaseContracts(); std::atomic m_compiling; - std::unique_ptr m_result; + mutable dev::Mutex x_contractMap; + ContractMap m_contractMap; std::unique_ptr m_codeHighlighterSettings; QThread m_backgroundThread; BackgroundWorker m_backgroundWorker; int m_backgroundJobId = 0; //protects from starting obsolete compilation job std::map m_compiledContracts; //by name + dev::Mutex x_pendingContracts; + std::map m_pendingContracts; //name to source friend class BackgroundWorker; }; diff --git a/mix/QContractDefinition.cpp b/mix/QContractDefinition.cpp index 488e08ea3..eacaee2f9 100644 --- a/mix/QContractDefinition.cpp +++ b/mix/QContractDefinition.cpp @@ -42,7 +42,7 @@ QContractDefinition::QContractDefinition(dev::solidity::ContractDefinition const m_functions.append(new QFunctionDefinition(it.second));} -QFunctionDefinition* QContractDefinition::getFunction(dev::FixedHash<4> _hash) +QFunctionDefinition const* QContractDefinition::getFunction(dev::FixedHash<4> _hash) const { for (auto const& f: m_functions) if (f->hash() == _hash) diff --git a/mix/QContractDefinition.h b/mix/QContractDefinition.h index 22f913a70..4d586a239 100644 --- a/mix/QContractDefinition.h +++ b/mix/QContractDefinition.h @@ -47,7 +47,7 @@ public: QFunctionDefinition* constructor() const { return m_constructor; } QList const& functionsList() const { return m_functions; } /// Find function by hash, returns nullptr if not found - QFunctionDefinition* getFunction(dev::FixedHash<4> _hash); + QFunctionDefinition const* getFunction(dev::FixedHash<4> _hash) const; private: QList m_functions; QFunctionDefinition* m_constructor; diff --git a/mix/StatusPane.cpp b/mix/StatusPane.cpp index f74b8f22b..9022b7033 100644 --- a/mix/StatusPane.cpp +++ b/mix/StatusPane.cpp @@ -36,7 +36,6 @@ using namespace dev::mix; StatusPane::StatusPane(AppContext* _context): Extension(_context, ExtensionDisplayBehavior::HeaderView) { - connect(_context->codeModel(), &CodeModel::compilationComplete, this, &StatusPane::update); _context->appEngine()->rootContext()->setContextProperty("statusPane", this); } @@ -54,13 +53,3 @@ void StatusPane::start() const { } -CompilationResult* StatusPane::result() const -{ - return m_ctx->codeModel()->code(); -} - -void StatusPane::update() -{ - QObject* ctrl = m_view->findChild("statusPane", Qt::FindChildrenRecursively); - QMetaObject::invokeMethod(ctrl, "updateStatus"); -} diff --git a/mix/StatusPane.h b/mix/StatusPane.h index ee65252b5..28b5b449b 100644 --- a/mix/StatusPane.h +++ b/mix/StatusPane.h @@ -20,7 +20,6 @@ #pragma once #include "Extension.h" -#include "CodeModel.h" namespace dev { @@ -33,7 +32,6 @@ namespace mix class StatusPane: public Extension { Q_OBJECT - Q_PROPERTY(CompilationResult* result READ result CONSTANT) public: StatusPane(AppContext* _appContext); @@ -41,10 +39,8 @@ public: void start() const override; QString title() const override; QString contentUrl() const override; - CompilationResult* result() const; public slots: - void update(); }; } diff --git a/mix/qml/CodeEditorView.qml b/mix/qml/CodeEditorView.qml index 9c0b804d7..439c36199 100644 --- a/mix/qml/CodeEditorView.qml +++ b/mix/qml/CodeEditorView.qml @@ -43,7 +43,7 @@ Item { editor.onEditorTextChanged.connect(function() { documentEdit(document.documentId); if (document.isContract) - codeModel.registerCodeChange(editor.getText()); + codeModel.registerCodeChange(document.documentId, editor.getText()); }); editor.setText(data, document.syntaxMode); } diff --git a/mix/qml/Debugger.qml b/mix/qml/Debugger.qml index 098cc77d1..316ec86c7 100644 --- a/mix/qml/Debugger.qml +++ b/mix/qml/Debugger.qml @@ -25,7 +25,7 @@ Rectangle { function update(data, giveFocus) { - if (statusPane && statusPane.result.successful) + if (statusPane && codeModel.hasContract) { Debugger.init(data); debugScrollArea.visible = true; diff --git a/mix/qml/MainContent.qml b/mix/qml/MainContent.qml index 6c6781878..15a7a638f 100644 --- a/mix/qml/MainContent.qml +++ b/mix/qml/MainContent.qml @@ -34,7 +34,7 @@ Rectangle { onCompilationComplete: { if (firstCompile) { firstCompile = false; - if (codeModel.code.successful && runOnProjectLoad) + if (runOnProjectLoad) startQuickDebugging(); } } diff --git a/mix/qml/ProjectList.qml b/mix/qml/ProjectList.qml index 925bb0bab..d4875220a 100644 --- a/mix/qml/ProjectList.qml +++ b/mix/qml/ProjectList.qml @@ -101,14 +101,19 @@ Item { Connections { target: codeModel onCompilationComplete: { - if (modelData === "Contracts") - { - var ctr = projectModel.listModel.get(0); - if (codeModel.code.contract.name !== ctr.name) - { - ctr.name = codeModel.code.contract.name; - projectModel.listModel.set(0, ctr); - sectionModel.set(0, ctr); + if (modelData === "Contracts") { + var ci = 0; + for (var si = 0; si < projectModel.listModel.count; si++) { + var document = projectModel.listModel.get(si); + if (document.isContract) { + var compiledDoc = codeModel.contractByDocumentId(document.documentId); + if (compiledDoc && compiledDoc.documentId === document.documentId && compiledDoc.contract.name !== document.name) { + document.name = compiledDoc.contract.name; + projectModel.listModel.set(si, document); + sectionModel.set(ci, document); + } + ci++; + } } } } diff --git a/mix/qml/ProjectModel.qml b/mix/qml/ProjectModel.qml index e74be7a9b..97dec227c 100644 --- a/mix/qml/ProjectModel.qml +++ b/mix/qml/ProjectModel.qml @@ -45,7 +45,7 @@ Item { function newHtmlFile() { ProjectModelCode.newHtmlFile(); } function newJsFile() { ProjectModelCode.newJsFile(); } function newCssFile() { ProjectModelCode.newCssFile(); } - //function newContract() { ProjectModelCode.newContract(); } + function newContract() { ProjectModelCode.newContract(); } function openDocument(documentId) { ProjectModelCode.openDocument(documentId); } function openNextDocument() { ProjectModelCode.openNextDocument(); } function openPrevDocument() { ProjectModelCode.openPrevDocument(); } diff --git a/mix/qml/StateListModel.qml b/mix/qml/StateListModel.qml index c68a433f7..da02ce5e6 100644 --- a/mix/qml/StateListModel.qml +++ b/mix/qml/StateListModel.qml @@ -22,12 +22,12 @@ Item { function fromPlainTransactionItem(t) { var r = { + contractId: t.contractId, functionId: t.functionId, url: t.url, value: QEtherHelper.createEther(t.value.value, t.value.unit), gas: QEtherHelper.createBigInt(t.gas.value), //t.gas,//QEtherHelper.createEther(t.gas.value, t.gas.unit), gasPrice: QEtherHelper.createEther(t.gasPrice.value, t.gasPrice.unit), - executeConstructor: t.executeConstructor, stdContract: t.stdContract, parameters: {} }; @@ -78,12 +78,12 @@ Item { function toPlainTransactionItem(t) { var r = { + contractId: t.contractId, functionId: t.functionId, url: t.url, value: { value: t.value.value, unit: t.value.unit }, gas: { value: t.gas.value() }, gasPrice: { value: t.gasPrice.value, unit: t.gasPrice.unit }, - executeConstructor: t.executeConstructor, stdContract: t.stdContract, parameters: {} }; @@ -159,7 +159,6 @@ Item { value: QEtherHelper.createEther("100", QEther.Wei), gas: QEtherHelper.createBigInt("125000"), gasPrice: QEtherHelper.createEther("10000000000000", QEther.Wei), - executeConstructor: false, stdContract: false }; } @@ -178,16 +177,19 @@ Item { var contractTransaction = defaultTransactionItem(); var contractItem = contractLibrary.model.get(i); contractTransaction.url = contractItem.url; + contractTransaction.contractId = contractItem.name; contractTransaction.functionId = contractItem.name; contractTransaction.stdContract = true; item.transactions.push(contractTransaction); }; - //add constructor - var ctorTr = defaultTransactionItem(); - ctorTr.executeConstructor = true; - ctorTr.functionId = qsTr("Constructor"); - item.transactions.push(ctorTr); + //add constructors, //TODO: order by dependencies + for(var c in codeModel.contracts) { + var ctorTr = defaultTransactionItem(); + ctorTr.functionId = c; + ctorTr.contractId = c; + item.transactions.push(ctorTr); + } return item; } diff --git a/mix/qml/StatusPane.qml b/mix/qml/StatusPane.qml index ddadb9953..6a8a0093d 100644 --- a/mix/qml/StatusPane.qml +++ b/mix/qml/StatusPane.qml @@ -8,9 +8,9 @@ Rectangle { id: statusHeader objectName: "statusPane" - function updateStatus() + function updateStatus(message) { - if (statusPane.result.successful) + if (!message) { status.state = ""; status.text = qsTr("Compile without errors."); @@ -20,12 +20,12 @@ Rectangle { else { status.state = "error"; - var errorInfo = ErrorLocationFormater.extractErrorInfo(statusPane.result.compilerMessage, true); + var errorInfo = ErrorLocationFormater.extractErrorInfo(message, true); status.text = errorInfo.errorLocation + " " + errorInfo.errorDetail; logslink.visible = true; debugImg.state = ""; } - debugRunActionIcon.enabled = statusPane.result.successful; + debugRunActionIcon.enabled = codeModel.hasContract; } function infoMessage(text) @@ -35,7 +35,6 @@ Rectangle { logslink.visible = false; } - Connections { target:clientModel onRunStarted: infoMessage(qsTr("Running transactions...")); @@ -49,6 +48,11 @@ Rectangle { onDeploymentError: infoMessage(error); onDeploymentComplete: infoMessage(qsTr("Deployment complete")); } + Connections { + target: codeModel + onCompilationComplete: updateStatus(); + onCompilationError: updateStatus(_error); + } color: "transparent" anchors.fill: parent diff --git a/mix/qml/TransactionDialog.qml b/mix/qml/TransactionDialog.qml index c71bd4155..e5a8bc746 100644 --- a/mix/qml/TransactionDialog.qml +++ b/mix/qml/TransactionDialog.qml @@ -20,9 +20,9 @@ Window { property alias gas: gasValueEdit.gasValue; property alias gasPrice: gasPriceField.value; property alias transactionValue: valueField.value; + property string contractId: contractComboBox.currentValue(); property alias functionId: functionComboBox.currentText; property var itemParams; - property bool isConstructorTransaction; property bool useTransactionDefaultValue: false property var qType; @@ -39,32 +39,47 @@ Window { gasValueEdit.gasValue = item.gas; gasPriceField.value = item.gasPrice; valueField.value = item.value; + var contractId = item.contractId; var functionId = item.functionId; - isConstructorTransaction = item.executeConstructor; - rowFunction.visible = !item.executeConstructor; + rowFunction.visible = true; itemParams = item.parameters !== undefined ? item.parameters : {}; - functionsModel.clear(); + + contractsModel.clear(); + var contractIndex = -1; + var contracts = codeModel.contracts; + for (var c in contracts) { + contractsModel.append({ cid: c, text: contracts[c].contract.name }); + if (contracts[c].contract.name === contractId) + contractIndex = contractsModel.count - 1; + } + + if (contractIndex == -1 && contractsModel.count > 0) + contractIndex = 0; //@todo suggest unused contract + contractComboBox.currentIndex = contractIndex; + + loadFunctions(contractComboBox.currentValue()); + var functionIndex = -1; - var functions = codeModel.code.contract.functions; - for (var f = 0; f < functions.length; f++) { - functionsModel.append({ text: functions[f].name }); - if (functions[f].name === item.functionId) + for (var f = 0; f < functionsModel.count; f++) + if (functionsModel.get(f).text === item.functionId) functionIndex = f; - } if (functionIndex == -1 && functionsModel.count > 0) functionIndex = 0; //@todo suggest unused function functionComboBox.currentIndex = functionIndex; + paramsModel.clear(); - if (!item.executeConstructor) + if (functionId !== contractComboBox.currentValue()) loadParameters(); - else - { - var parameters = codeModel.code.contract.constructor.parameters; - for (var p = 0; p < parameters.length; p++) - loadParameter(parameters[p]); + else { + var contract = codeModel.contracts[contractId]; + if (contract) { + var parameters = contract.contract.constructor.parameters; + for (var p = 0; p < parameters.length; p++) + loadParameter(parameters[p]); + } } modalTransactionDialog.setX((Screen.width - width) / 2); modalTransactionDialog.setY((Screen.height - height) / 2); @@ -73,6 +88,21 @@ Window { valueField.focus = true; } + function loadFunctions(contractId) + { + functionsModel.clear(); + var contract = codeModel.contracts[contractId]; + if (contract) { + var functions = codeModel.contracts[contractId].contract.functions; + for (var f = 0; f < functions.length; f++) { + functionsModel.append({ text: functions[f].name }); + } + } + //append constructor + functionsModel.append({ text: contractId }); + + } + function loadParameter(parameter) { var type = parameter.type; @@ -104,10 +134,15 @@ Window { if (!paramsModel) return; if (functionComboBox.currentIndex >= 0 && functionComboBox.currentIndex < functionsModel.count) { - var func = codeModel.code.contract.functions[functionComboBox.currentIndex]; - var parameters = func.parameters; - for (var p = 0; p < parameters.length; p++) - loadParameter(parameters[p]); + var contract = codeModel.contracts[contractComboBox.currentValue()]; + if (contract) { + var func = contract.contract.functions[functionComboBox.currentIndex]; + if (func) { + var parameters = func.parameters; + for (var p = 0; p < parameters.length; p++) + loadParameter(parameters[p]); + } + } } } @@ -140,24 +175,21 @@ Window { if (!useTransactionDefaultValue) { item = { + contractId: transactionDialog.contractId, functionId: transactionDialog.functionId, gas: transactionDialog.gas, gasPrice: transactionDialog.gasPrice, value: transactionDialog.transactionValue, parameters: {}, - executeConstructor: isConstructorTransaction }; } else { item = TransactionHelper.defaultTransaction(); + item.contractId = transactionDialog.contractId; item.functionId = transactionDialog.functionId; - item.executeConstructor = isConstructorTransaction; } - if (isConstructorTransaction) - item.functionId = qsTr("Constructor"); - var orderedQType = []; for (var p = 0; p < transactionDialog.transactionParams.count; p++) { var parameter = transactionDialog.transactionParams.get(p); @@ -178,6 +210,33 @@ Window { id: dialogContent anchors.top: parent.top spacing: 10 + RowLayout + { + id: rowContract + Layout.fillWidth: true + height: 150 + DefaultLabel { + Layout.preferredWidth: 75 + text: qsTr("Contract") + } + ComboBox { + id: contractComboBox + function currentValue() { + return (currentIndex >=0 && currentIndex < contractsModel.count) ? contractsModel.get(currentIndex).cid : ""; + } + Layout.preferredWidth: 350 + currentIndex: -1 + textRole: "text" + editable: false + model: ListModel { + id: contractsModel + } + onCurrentIndexChanged: { + loadFunctions(currentValue()); + } + } + } + RowLayout { id: rowFunction diff --git a/mix/qml/WebPreview.qml b/mix/qml/WebPreview.qml index 5d4d0e617..9886a71c6 100644 --- a/mix/qml/WebPreview.qml +++ b/mix/qml/WebPreview.qml @@ -29,7 +29,16 @@ Item { } function updateContract() { - webView.runJavaScript("updateContract(\"" + codeModel.code.contract.name + "\", \"" + clientModel.contractAddress + "\", " + codeModel.code.contractInterface + ")"); + var contracts = {}; + for (var c in codeModel.contracts) { + var contract = codeModel.contracts[c]; + contracts[c] = { + name: contract.contract.name, + address: clientModel.contractAddresses[contract.contract.name], + interface: JSON.parse(contract.contractInterface), + }; + } + webView.runJavaScript("updateContracts(" + JSON.stringify(contracts) + ")"); } function reloadOnSave() { @@ -62,7 +71,6 @@ Item { Connections { target: clientModel - onContractAddressChanged: reload(); onRunComplete: reload(); } diff --git a/mix/qml/html/WebContainer.html b/mix/qml/html/WebContainer.html index 09a8734d5..26cac5103 100644 --- a/mix/qml/html/WebContainer.html +++ b/mix/qml/html/WebContainer.html @@ -15,16 +15,18 @@ reloadPage = function() { preview.contentWindow.location.reload(); }; -updateContract = function(name, address, contractFace) { +updateContracts = function(contracts) { if (window.web3) { window.web3.provider.polls = []; - var contract = window.web3.eth.contract(address, contractFace); window.contracts = {}; - window.contracts[name] = { - address: address, - interface: contractFace, - contract: contract, - }; + for (var c in contracts) { + var contract = window.web3.eth.contract(contracts[c].address, contracts[c].interface); + window.contracts[c] = { + address: c.address, + interface: c.interface, + contract: contract, + }; + } } }; diff --git a/mix/qml/js/ProjectModel.js b/mix/qml/js/ProjectModel.js index be6c07c5b..5a7bf4332 100644 --- a/mix/qml/js/ProjectModel.js +++ b/mix/qml/js/ProjectModel.js @@ -20,6 +20,9 @@ * Ethereum IDE client. */ +var htmlTemplate = "\n\n\n\n\n\n\n"; +var contractTemplate = "contract Contract {\n}\n"; + function saveAll() { saveProject(); } @@ -76,6 +79,16 @@ function loadProject(path) { projectSettings.lastProjectPath = path; projectLoading(projectData); projectLoaded() + + //TODO: move this to codemodel + var contractSources = {}; + for (var d = 0; d < listModel.count; d++) { + var doc = listModel.get(d); + if (doc.isContract) + contractSources[doc.documentId] = fileIo.readFile(doc.path); + } + codeModel.reset(contractSources); + } function addFile(fileName) { @@ -92,7 +105,7 @@ function addFile(fileName) { contract: false, path: p, fileName: fileName, - name: isContract ? "Contract" : fileName, + name: fileName, documentId: fileName, syntaxMode: syntaxMode, isText: isContract || isHtml || isCss || isJs, @@ -150,7 +163,7 @@ function openPrevDocument() { } function doCloseProject() { - console.log("closing project"); + console.log("Closing project"); projectListModel.clear(); projectPath = ""; currentDocumentId = ""; @@ -167,14 +180,14 @@ function doCreateProject(title, path) { var projectFile = dirPath + projectFileName; var indexFile = "index.html"; - var contractsFile = "contracts.sol"; + var contractsFile = "contract.sol"; var projectData = { title: title, files: [ contractsFile, indexFile ] }; //TODO: copy from template - fileIo.writeFile(dirPath + indexFile, "\n\n\n\n\n\n\n"); - fileIo.writeFile(dirPath + contractsFile, "contract Contract {\n}\n"); + fileIo.writeFile(dirPath + indexFile, htmlTemplate); + fileIo.writeFile(dirPath + contractsFile, contractTemplate); newProject(projectData); var json = JSON.stringify(projectData, null, "\t"); fileIo.writeFile(projectFile, json); @@ -222,7 +235,7 @@ function removeDocument(documentId) { } function newHtmlFile() { - createAndAddFile("page", "html", "\n"); + createAndAddFile("page", "html", htmlTemplate); } function newCssFile() { @@ -233,6 +246,11 @@ function newJsFile() { createAndAddFile("script", "js", "function foo() {\n}\n"); } +function newContract() { + createAndAddFile("contract", "sol", contractTemplate); +} + + function createAndAddFile(name, extension, content) { var fileName = generateFileName(name, extension); var filePath = projectPath + fileName; @@ -267,15 +285,21 @@ function deployProject(force) { var jsonRpcUrl = "http://localhost:8080"; console.log("Deploying " + deploymentId + " to " + jsonRpcUrl); deploymentStarted(); - var code = codeModel.codeHex - var rpcRequest = JSON.stringify({ - jsonrpc: "2.0", - method: "eth_transact", - params: [ { - "code": code - } ], - id: jsonRpcRequestId++ - }); + + var requests = []; + var requestNames = []; + for (var c in codeModel.contracts) { //TODO: order based on dependencies + var code = codeModel.contracts[c].codeHex; + requests.push({ + jsonrpc: "2.0", + method: "eth_transact", + params: [ { "code": code } ], + id: jsonRpcRequestId++ + }); + requestNames.push(c); + } + + var rpcRequest = JSON.stringify(requests);; var httpRequest = new XMLHttpRequest() httpRequest.open("POST", jsonRpcUrl, true); httpRequest.setRequestHeader("Content-type", "application/json"); @@ -285,9 +309,12 @@ function deployProject(force) { if (httpRequest.readyState === XMLHttpRequest.DONE) { if (httpRequest.status === 200) { var rpcResponse = JSON.parse(httpRequest.responseText); - var address = rpcResponse.result; - console.log("Created contract, address: " + address); - finalizeDeployment(deploymentId, address); + if (rpcResponse.length === requestNames.length) { + var contractAddresses = {}; + for (var r = 0; r < rpcResponse.lenght; r++) + contractAddresses[requestNames[r]] = rpcResponse.result; + finalizeDeployment(deploymentId, contractAddresses); + } } else { var errorText = qsTr("Deployment error: RPC server HTTP status ") + httpRequest.status; console.log(errorText); @@ -298,7 +325,7 @@ function deployProject(force) { httpRequest.send(rpcRequest); } -function finalizeDeployment(deploymentId, address) { +function finalizeDeployment(deploymentId, addresses) { //create a dir for frontend files and copy them var deploymentDir = projectPath + deploymentId + "/"; fileIo.makeDir(deploymentDir); @@ -326,16 +353,18 @@ function finalizeDeployment(deploymentId, address) { fileIo.copyFile(doc.path, deploymentDir + doc.fileName); } //write deployment js - var contractAccessor = "contracts[\"" + codeModel.code.contract.name + "\"]"; var deploymentJs = "// Autogenerated by Mix\n" + "web3 = require(\"web3\");\n" + - "contracts = {};\n" + - contractAccessor + " = {\n" + - "\tinterface: " + codeModel.code.contractInterface + ",\n" + - "\taddress: \"" + address + "\"\n" + + "contracts = {};\n"; + for (var c in codeModel.contracts) { + var contractAccessor = "contracts[\"" + codeModel.contracts[c].contract.name + "\"]"; + deploymentJs += contractAccessor + " = {\n" + + "\tinterface: " + codeModel.contracts[c].contractInterface + ",\n" + + "\taddress: \"" + addresses[c] + "\"\n" + "};\n" + contractAccessor + ".contract = web3.eth.contract(" + contractAccessor + ".address, " + contractAccessor + ".interface);\n"; + } fileIo.writeFile(deploymentDir + "deployment.js", deploymentJs); //copy scripts fileIo.copyFile("qrc:///js/bignumber.min.js", deploymentDir + "bignumber.min.js"); diff --git a/mix/qml/js/TransactionHelper.js b/mix/qml/js/TransactionHelper.js index 87dd74beb..62399161e 100644 --- a/mix/qml/js/TransactionHelper.js +++ b/mix/qml/js/TransactionHelper.js @@ -7,7 +7,6 @@ function defaultTransaction() functionId: "", gas: createBigInt("125000"), gasPrice: createEther("100000", QEther.Wei), - executeConstructor: false, parameters: {} }; } diff --git a/mix/qml/main.qml b/mix/qml/main.qml index 71d8c24bf..a1cf99de6 100644 --- a/mix/qml/main.qml +++ b/mix/qml/main.qml @@ -30,7 +30,7 @@ ApplicationWindow { MenuItem { action: addNewHtmlFileAction } MenuItem { action: addNewCssFileAction } MenuSeparator {} - //MenuItem { action: addNewContractAction } + MenuItem { action: addNewContractAction } MenuItem { action: closeProjectAction } MenuSeparator {} MenuItem { action: exitAppAction } From 37fa06106b651e1a50c2ea3f34164e19622d74df Mon Sep 17 00:00:00 2001 From: arkpar Date: Tue, 17 Feb 2015 09:23:23 +0100 Subject: [PATCH 206/213] fixed cppcheck warnings --- mix/ClientModel.cpp | 3 +-- mix/CodeHighlighter.cpp | 2 +- mix/CodeModel.cpp | 8 ++++---- mix/ContractCallDataEncoder.cpp | 2 +- mix/MixClient.cpp | 4 ++-- mix/QVariableDefinition.h | 4 ++-- 6 files changed, 11 insertions(+), 12 deletions(-) diff --git a/mix/ClientModel.cpp b/mix/ClientModel.cpp index 91e5c98ab..45198c114 100644 --- a/mix/ClientModel.cpp +++ b/mix/ClientModel.cpp @@ -216,7 +216,6 @@ void ClientModel::executeSequence(std::vector const& _seque for (TransactionSettings const& transaction: _sequence) { ContractCallDataEncoder encoder; - QFunctionDefinition const* f = nullptr; if (!transaction.stdContractUrl.isEmpty()) { //std contract @@ -229,9 +228,9 @@ void ClientModel::executeSequence(std::vector const& _seque { //encode data CompiledContract const& compilerRes = m_context->codeModel()->contract(transaction.contractId); + QFunctionDefinition const* f = nullptr; bytes contractCode = compilerRes.bytes(); std::shared_ptr contractDef = compilerRes.sharedContract(); - f = nullptr; if (transaction.functionId.isEmpty()) f = contractDef->constructor(); else diff --git a/mix/CodeHighlighter.cpp b/mix/CodeHighlighter.cpp index d76d8b73e..86dfe9e5d 100644 --- a/mix/CodeHighlighter.cpp +++ b/mix/CodeHighlighter.cpp @@ -119,7 +119,7 @@ void CodeHighlighter::processComments(std::string const& _source) //add single line comment int start = i; i += 2; - while (_source[i] != '\n' && i < size) + while (i < size && _source[i] != '\n') ++i; m_formats.push_back(FormatRange(CodeHighlighterSettings::Comment, start, i - start)); } diff --git a/mix/CodeModel.cpp b/mix/CodeModel.cpp index d605f1c6e..7a38594ce 100644 --- a/mix/CodeModel.cpp +++ b/mix/CodeModel.cpp @@ -108,7 +108,7 @@ void CodeModel::reset(QVariantMap const& _documents) Guard pl(x_pendingContracts); m_pendingContracts.clear(); - for (QVariantMap::const_iterator d = _documents.cbegin(); d != _documents.cend(); d++) + for (QVariantMap::const_iterator d = _documents.cbegin(); d != _documents.cend(); ++d) m_pendingContracts[d.key()] = d.value().toString(); // launch the background thread m_compiling = true; @@ -138,7 +138,7 @@ QVariantMap CodeModel::contracts() const { QVariantMap result; Guard l(x_contractMap); - for (ContractMap::const_iterator c = m_contractMap.cbegin(); c != m_contractMap.cend(); c++) + for (ContractMap::const_iterator c = m_contractMap.cbegin(); c != m_contractMap.cend(); ++c) result.insert(c.key(), QVariant::fromValue(c.value())); return result; } @@ -146,7 +146,7 @@ QVariantMap CodeModel::contracts() const CompiledContract* CodeModel::contractByDocumentId(QString _documentId) const { Guard l(x_contractMap); - for (ContractMap::const_iterator c = m_contractMap.cbegin(); c != m_contractMap.cend(); c++) + for (ContractMap::const_iterator c = m_contractMap.cbegin(); c != m_contractMap.cend(); ++c) if (c.value()->m_documentId == _documentId) return c.value(); return nullptr; @@ -163,7 +163,7 @@ CompiledContract const& CodeModel::contract(QString _name) const void CodeModel::releaseContracts() { - for (ContractMap::iterator c = m_contractMap.begin(); c != m_contractMap.end(); c++) + for (ContractMap::iterator c = m_contractMap.begin(); c != m_contractMap.end(); ++c) c.value()->deleteLater(); m_contractMap.clear(); } diff --git a/mix/ContractCallDataEncoder.cpp b/mix/ContractCallDataEncoder.cpp index 19ece2a4d..e31f79e9f 100644 --- a/mix/ContractCallDataEncoder.cpp +++ b/mix/ContractCallDataEncoder.cpp @@ -56,7 +56,7 @@ QList ContractCallDataEncoder::decode(QList r; for (int k = 0; k <_returnParameters.length(); k++) { - QVariableDeclaration* dec = (QVariableDeclaration*)_returnParameters.at(k); + QVariableDeclaration* dec = static_cast(_returnParameters.at(k)); QVariableDefinition* def = nullptr; if (dec->type().contains("int")) def = new QIntType(dec, QString()); diff --git a/mix/MixClient.cpp b/mix/MixClient.cpp index b2a367929..3b0a2a03b 100644 --- a/mix/MixClient.cpp +++ b/mix/MixClient.cpp @@ -117,8 +117,8 @@ void MixClient::executeTransaction(Transaction const& _t, State& _state, bool _c unsigned dataIndex = 0; auto onOp = [&](uint64_t steps, Instruction inst, dev::bigint newMemSize, dev::bigint gasCost, void* voidVM, void const* voidExt) { - VM& vm = *(VM*)voidVM; - ExtVM const& ext = *(ExtVM const*)voidExt; + VM& vm = *static_cast(voidVM); + ExtVM const& ext = *static_cast(voidExt); if (lastCode == nullptr || lastCode != &ext.code) { auto const& iter = codeIndexes.find(&ext.code); diff --git a/mix/QVariableDefinition.h b/mix/QVariableDefinition.h index ae9bf9459..1825c2567 100644 --- a/mix/QVariableDefinition.h +++ b/mix/QVariableDefinition.h @@ -135,8 +135,8 @@ class QBoolType: public QVariableDefinition Q_OBJECT public: - QBoolType() {} - QBoolType(QVariableDeclaration* _def, QString _value): QVariableDefinition(_def, _value) {} + QBoolType(): m_boolValue(false) {} + QBoolType(QVariableDeclaration* _def, QString _value): QVariableDefinition(_def, _value), m_boolValue(false) {} dev::bytes encodeValue() override; void decodeValue(dev::bytes const& _rawValue) override; /// @returns the boolean value for the current definition. From 69f3733501606d1e390ee24d2cad9872fca2570b Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Tue, 17 Feb 2015 09:24:58 +0100 Subject: [PATCH 207/213] Initialize FunctionType's m_isConstant attribute in the Event Constructor --- libsolidity/Types.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index 5d753645c..b41834d84 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -769,7 +769,7 @@ FunctionType::FunctionType(VariableDeclaration const& _varDecl): } FunctionType::FunctionType(const EventDefinition& _event): - m_location(Location::Event), m_declaration(&_event) + m_location(Location::Event), m_isConstant(true), m_declaration(&_event) { TypePointers params; vector paramNames; From 9e87abc136b31ae42a332e104900cc3eaccadf05 Mon Sep 17 00:00:00 2001 From: arkpar Date: Tue, 17 Feb 2015 11:14:53 +0100 Subject: [PATCH 208/213] minor fixes --- mix/qml/StateListModel.qml | 9 ++++++++- mix/qml/WebPreview.qml | 12 +++++++----- mix/qml/main.qml | 2 +- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/mix/qml/StateListModel.qml b/mix/qml/StateListModel.qml index da02ce5e6..52b0d542d 100644 --- a/mix/qml/StateListModel.qml +++ b/mix/qml/StateListModel.qml @@ -47,6 +47,10 @@ Item { varComponent = Qt.createComponent("qrc:/qml/QHashType.qml"); else if (type.indexOf("bool") !== -1) varComponent = Qt.createComponent("qrc:/qml/QBoolType.qml"); + else { + console.log("Unknown parameter type: " + type); + continue; + } var param = varComponent.createObject(stateListModel); var dec = Qt.createComponent("qrc:/qml/QVariableDeclaration.qml"); @@ -203,7 +207,7 @@ Item { } function debugDefaultState() { - if (defaultStateIndex >= 0) + if (defaultStateIndex >= 0 && defaultStateIndex < stateList.length) runState(defaultStateIndex); } @@ -221,6 +225,9 @@ Item { defaultStateIndex = 0; defaultStateChanged(); } + else if (defaultStateIndex > index) + defaultStateIndex--; + save(); } diff --git a/mix/qml/WebPreview.qml b/mix/qml/WebPreview.qml index 9886a71c6..0d0d70d31 100644 --- a/mix/qml/WebPreview.qml +++ b/mix/qml/WebPreview.qml @@ -24,8 +24,10 @@ Item { } function reload() { - updateContract(); - webView.runJavaScript("reloadPage()"); + if (initialized) { + updateContract(); + webView.runJavaScript("reloadPage()"); + } } function updateContract() { @@ -33,9 +35,9 @@ Item { for (var c in codeModel.contracts) { var contract = codeModel.contracts[c]; contracts[c] = { - name: contract.contract.name, - address: clientModel.contractAddresses[contract.contract.name], - interface: JSON.parse(contract.contractInterface), + name: contract.contract.name, + address: clientModel.contractAddresses[contract.contract.name], + interface: JSON.parse(contract.contractInterface), }; } webView.runJavaScript("updateContracts(" + JSON.stringify(contracts) + ")"); diff --git a/mix/qml/main.qml b/mix/qml/main.qml index a1cf99de6..c9e8c8225 100644 --- a/mix/qml/main.qml +++ b/mix/qml/main.qml @@ -95,7 +95,7 @@ ApplicationWindow { text: qsTr("Mine") shortcut: "Ctrl+M" onTriggered: clientModel.mine(); - enabled: codeModel.hasContract && !clientModel.running &&!clientModel.mining + enabled: codeModel.hasContract && !clientModel.running && !clientModel.mining } StateList { From a3278d1b117651751a9555038272c8a792ef1cf4 Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 17 Feb 2015 11:17:47 +0100 Subject: [PATCH 209/213] Bug fix - mix: windows - crash when click on 'Deploy to Network' #1077 --- mix/main.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mix/main.cpp b/mix/main.cpp index d0a19cfb5..8c5e7d046 100644 --- a/mix/main.cpp +++ b/mix/main.cpp @@ -36,6 +36,12 @@ int main(int _argc, char* _argv[]) //https://bugs.launchpad.net/ubuntu/+source/appmenu-qt5/+bug/1323853 putenv((char*)"QT_QPA_PLATFORMTHEME="); putenv((char*)"QSG_RENDER_LOOP=threaded"); +#endif +#ifdef _WIN32 + putenv((char*)"OPENSSL_CONF=c:\\"); +#endif +#ifdef _WIN64 + putenv((char*)"OPENSSL_CONF=c:\\"); #endif try { From 11a381915ddb7f09d74c5ba08ae99b804ad489f6 Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 17 Feb 2015 12:26:42 +0100 Subject: [PATCH 210/213] Change WIN32 (WIN64) test. --- mix/main.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/mix/main.cpp b/mix/main.cpp index 8c5e7d046..798520e39 100644 --- a/mix/main.cpp +++ b/mix/main.cpp @@ -37,11 +37,9 @@ int main(int _argc, char* _argv[]) putenv((char*)"QT_QPA_PLATFORMTHEME="); putenv((char*)"QSG_RENDER_LOOP=threaded"); #endif -#ifdef _WIN32 - putenv((char*)"OPENSSL_CONF=c:\\"); -#endif -#ifdef _WIN64 - putenv((char*)"OPENSSL_CONF=c:\\"); +#if (defined(_WIN32) || defined(_WIN64)) + if (!getenv("OPENSSL_CONF")) + putenv((char*)"OPENSSL_CONF=c:\\"); #endif try { From d9ebbfde48abf4d27d6c80aa9084fefed553317f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Tue, 17 Feb 2015 13:28:58 +0100 Subject: [PATCH 211/213] ManyFunctions performance test: replace xor with correct exp operator --- test/ManyFunctions.sol | 424 ++++++++++++++++-------------- test/ManyFunctionsGenerator.py | 4 +- test/vmPerformanceTestFiller.json | 2 +- 3 files changed, 229 insertions(+), 201 deletions(-) diff --git a/test/ManyFunctions.sol b/test/ManyFunctions.sol index 60dc61c42..691d98f46 100644 --- a/test/ManyFunctions.sol +++ b/test/ManyFunctions.sol @@ -1,14 +1,41 @@ +// Based on input param calls ~100 functions from ~200, random algorithm is really bad. +contract ManyFunctions { + + function start(uint seed) returns (uint) { + var r = nextRand(seed); + if (r >= 2**78) + return left1(r); + return right1(r); + } + + function finish(uint seed) returns (uint) { + return seed; + } + + function nextRand(uint seed) returns (uint) { + var a = 39948330534945941795786356397633709378407037920056054402537049186942880579585; + return a * seed + 1; + } + + function right100(uint seed) returns (uint) { + return finish(seed); + } + + function left100(uint seed) returns (uint) { + return finish(nextRand(seed)); + } + function right1(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^79) + if (r >= 2**79) return right2(r); return left2(r); } function left1(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^79) + if (r >= 2**79) return left2(r); return right2(r); } @@ -16,14 +43,14 @@ function right2(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^80) + if (r >= 2**80) return right3(r); return left3(r); } function left2(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^80) + if (r >= 2**80) return left3(r); return right3(r); } @@ -31,14 +58,14 @@ function right3(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^81) + if (r >= 2**81) return right4(r); return left4(r); } function left3(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^81) + if (r >= 2**81) return left4(r); return right4(r); } @@ -46,14 +73,14 @@ function right4(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^82) + if (r >= 2**82) return right5(r); return left5(r); } function left4(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^82) + if (r >= 2**82) return left5(r); return right5(r); } @@ -61,14 +88,14 @@ function right5(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^83) + if (r >= 2**83) return right6(r); return left6(r); } function left5(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^83) + if (r >= 2**83) return left6(r); return right6(r); } @@ -76,14 +103,14 @@ function right6(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^84) + if (r >= 2**84) return right7(r); return left7(r); } function left6(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^84) + if (r >= 2**84) return left7(r); return right7(r); } @@ -91,14 +118,14 @@ function right7(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^85) + if (r >= 2**85) return right8(r); return left8(r); } function left7(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^85) + if (r >= 2**85) return left8(r); return right8(r); } @@ -106,14 +133,14 @@ function right8(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^86) + if (r >= 2**86) return right9(r); return left9(r); } function left8(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^86) + if (r >= 2**86) return left9(r); return right9(r); } @@ -121,14 +148,14 @@ function right9(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^87) + if (r >= 2**87) return right10(r); return left10(r); } function left9(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^87) + if (r >= 2**87) return left10(r); return right10(r); } @@ -136,14 +163,14 @@ function right10(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^88) + if (r >= 2**88) return right11(r); return left11(r); } function left10(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^88) + if (r >= 2**88) return left11(r); return right11(r); } @@ -151,14 +178,14 @@ function right11(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^89) + if (r >= 2**89) return right12(r); return left12(r); } function left11(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^89) + if (r >= 2**89) return left12(r); return right12(r); } @@ -166,14 +193,14 @@ function right12(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^90) + if (r >= 2**90) return right13(r); return left13(r); } function left12(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^90) + if (r >= 2**90) return left13(r); return right13(r); } @@ -181,14 +208,14 @@ function right13(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^91) + if (r >= 2**91) return right14(r); return left14(r); } function left13(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^91) + if (r >= 2**91) return left14(r); return right14(r); } @@ -196,14 +223,14 @@ function right14(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^92) + if (r >= 2**92) return right15(r); return left15(r); } function left14(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^92) + if (r >= 2**92) return left15(r); return right15(r); } @@ -211,14 +238,14 @@ function right15(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^93) + if (r >= 2**93) return right16(r); return left16(r); } function left15(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^93) + if (r >= 2**93) return left16(r); return right16(r); } @@ -226,14 +253,14 @@ function right16(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^94) + if (r >= 2**94) return right17(r); return left17(r); } function left16(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^94) + if (r >= 2**94) return left17(r); return right17(r); } @@ -241,14 +268,14 @@ function right17(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^95) + if (r >= 2**95) return right18(r); return left18(r); } function left17(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^95) + if (r >= 2**95) return left18(r); return right18(r); } @@ -256,14 +283,14 @@ function right18(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^96) + if (r >= 2**96) return right19(r); return left19(r); } function left18(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^96) + if (r >= 2**96) return left19(r); return right19(r); } @@ -271,14 +298,14 @@ function right19(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^97) + if (r >= 2**97) return right20(r); return left20(r); } function left19(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^97) + if (r >= 2**97) return left20(r); return right20(r); } @@ -286,14 +313,14 @@ function right20(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^98) + if (r >= 2**98) return right21(r); return left21(r); } function left20(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^98) + if (r >= 2**98) return left21(r); return right21(r); } @@ -301,14 +328,14 @@ function right21(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^99) + if (r >= 2**99) return right22(r); return left22(r); } function left21(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^99) + if (r >= 2**99) return left22(r); return right22(r); } @@ -316,14 +343,14 @@ function right22(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^100) + if (r >= 2**100) return right23(r); return left23(r); } function left22(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^100) + if (r >= 2**100) return left23(r); return right23(r); } @@ -331,14 +358,14 @@ function right23(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^101) + if (r >= 2**101) return right24(r); return left24(r); } function left23(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^101) + if (r >= 2**101) return left24(r); return right24(r); } @@ -346,14 +373,14 @@ function right24(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^102) + if (r >= 2**102) return right25(r); return left25(r); } function left24(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^102) + if (r >= 2**102) return left25(r); return right25(r); } @@ -361,14 +388,14 @@ function right25(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^103) + if (r >= 2**103) return right26(r); return left26(r); } function left25(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^103) + if (r >= 2**103) return left26(r); return right26(r); } @@ -376,14 +403,14 @@ function right26(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^104) + if (r >= 2**104) return right27(r); return left27(r); } function left26(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^104) + if (r >= 2**104) return left27(r); return right27(r); } @@ -391,14 +418,14 @@ function right27(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^105) + if (r >= 2**105) return right28(r); return left28(r); } function left27(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^105) + if (r >= 2**105) return left28(r); return right28(r); } @@ -406,14 +433,14 @@ function right28(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^106) + if (r >= 2**106) return right29(r); return left29(r); } function left28(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^106) + if (r >= 2**106) return left29(r); return right29(r); } @@ -421,14 +448,14 @@ function right29(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^107) + if (r >= 2**107) return right30(r); return left30(r); } function left29(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^107) + if (r >= 2**107) return left30(r); return right30(r); } @@ -436,14 +463,14 @@ function right30(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^108) + if (r >= 2**108) return right31(r); return left31(r); } function left30(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^108) + if (r >= 2**108) return left31(r); return right31(r); } @@ -451,14 +478,14 @@ function right31(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^109) + if (r >= 2**109) return right32(r); return left32(r); } function left31(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^109) + if (r >= 2**109) return left32(r); return right32(r); } @@ -466,14 +493,14 @@ function right32(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^110) + if (r >= 2**110) return right33(r); return left33(r); } function left32(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^110) + if (r >= 2**110) return left33(r); return right33(r); } @@ -481,14 +508,14 @@ function right33(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^111) + if (r >= 2**111) return right34(r); return left34(r); } function left33(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^111) + if (r >= 2**111) return left34(r); return right34(r); } @@ -496,14 +523,14 @@ function right34(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^112) + if (r >= 2**112) return right35(r); return left35(r); } function left34(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^112) + if (r >= 2**112) return left35(r); return right35(r); } @@ -511,14 +538,14 @@ function right35(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^113) + if (r >= 2**113) return right36(r); return left36(r); } function left35(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^113) + if (r >= 2**113) return left36(r); return right36(r); } @@ -526,14 +553,14 @@ function right36(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^114) + if (r >= 2**114) return right37(r); return left37(r); } function left36(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^114) + if (r >= 2**114) return left37(r); return right37(r); } @@ -541,14 +568,14 @@ function right37(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^115) + if (r >= 2**115) return right38(r); return left38(r); } function left37(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^115) + if (r >= 2**115) return left38(r); return right38(r); } @@ -556,14 +583,14 @@ function right38(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^116) + if (r >= 2**116) return right39(r); return left39(r); } function left38(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^116) + if (r >= 2**116) return left39(r); return right39(r); } @@ -571,14 +598,14 @@ function right39(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^117) + if (r >= 2**117) return right40(r); return left40(r); } function left39(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^117) + if (r >= 2**117) return left40(r); return right40(r); } @@ -586,14 +613,14 @@ function right40(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^118) + if (r >= 2**118) return right41(r); return left41(r); } function left40(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^118) + if (r >= 2**118) return left41(r); return right41(r); } @@ -601,14 +628,14 @@ function right41(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^119) + if (r >= 2**119) return right42(r); return left42(r); } function left41(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^119) + if (r >= 2**119) return left42(r); return right42(r); } @@ -616,14 +643,14 @@ function right42(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^120) + if (r >= 2**120) return right43(r); return left43(r); } function left42(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^120) + if (r >= 2**120) return left43(r); return right43(r); } @@ -631,14 +658,14 @@ function right43(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^121) + if (r >= 2**121) return right44(r); return left44(r); } function left43(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^121) + if (r >= 2**121) return left44(r); return right44(r); } @@ -646,14 +673,14 @@ function right44(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^122) + if (r >= 2**122) return right45(r); return left45(r); } function left44(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^122) + if (r >= 2**122) return left45(r); return right45(r); } @@ -661,14 +688,14 @@ function right45(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^123) + if (r >= 2**123) return right46(r); return left46(r); } function left45(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^123) + if (r >= 2**123) return left46(r); return right46(r); } @@ -676,14 +703,14 @@ function right46(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^124) + if (r >= 2**124) return right47(r); return left47(r); } function left46(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^124) + if (r >= 2**124) return left47(r); return right47(r); } @@ -691,14 +718,14 @@ function right47(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^125) + if (r >= 2**125) return right48(r); return left48(r); } function left47(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^125) + if (r >= 2**125) return left48(r); return right48(r); } @@ -706,14 +733,14 @@ function right48(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^126) + if (r >= 2**126) return right49(r); return left49(r); } function left48(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^126) + if (r >= 2**126) return left49(r); return right49(r); } @@ -721,14 +748,14 @@ function right49(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^127) + if (r >= 2**127) return right50(r); return left50(r); } function left49(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^127) + if (r >= 2**127) return left50(r); return right50(r); } @@ -736,14 +763,14 @@ function right50(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^128) + if (r >= 2**128) return right51(r); return left51(r); } function left50(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^128) + if (r >= 2**128) return left51(r); return right51(r); } @@ -751,14 +778,14 @@ function right51(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^129) + if (r >= 2**129) return right52(r); return left52(r); } function left51(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^129) + if (r >= 2**129) return left52(r); return right52(r); } @@ -766,14 +793,14 @@ function right52(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^130) + if (r >= 2**130) return right53(r); return left53(r); } function left52(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^130) + if (r >= 2**130) return left53(r); return right53(r); } @@ -781,14 +808,14 @@ function right53(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^131) + if (r >= 2**131) return right54(r); return left54(r); } function left53(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^131) + if (r >= 2**131) return left54(r); return right54(r); } @@ -796,14 +823,14 @@ function right54(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^132) + if (r >= 2**132) return right55(r); return left55(r); } function left54(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^132) + if (r >= 2**132) return left55(r); return right55(r); } @@ -811,14 +838,14 @@ function right55(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^133) + if (r >= 2**133) return right56(r); return left56(r); } function left55(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^133) + if (r >= 2**133) return left56(r); return right56(r); } @@ -826,14 +853,14 @@ function right56(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^134) + if (r >= 2**134) return right57(r); return left57(r); } function left56(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^134) + if (r >= 2**134) return left57(r); return right57(r); } @@ -841,14 +868,14 @@ function right57(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^135) + if (r >= 2**135) return right58(r); return left58(r); } function left57(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^135) + if (r >= 2**135) return left58(r); return right58(r); } @@ -856,14 +883,14 @@ function right58(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^136) + if (r >= 2**136) return right59(r); return left59(r); } function left58(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^136) + if (r >= 2**136) return left59(r); return right59(r); } @@ -871,14 +898,14 @@ function right59(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^137) + if (r >= 2**137) return right60(r); return left60(r); } function left59(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^137) + if (r >= 2**137) return left60(r); return right60(r); } @@ -886,14 +913,14 @@ function right60(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^138) + if (r >= 2**138) return right61(r); return left61(r); } function left60(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^138) + if (r >= 2**138) return left61(r); return right61(r); } @@ -901,14 +928,14 @@ function right61(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^139) + if (r >= 2**139) return right62(r); return left62(r); } function left61(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^139) + if (r >= 2**139) return left62(r); return right62(r); } @@ -916,14 +943,14 @@ function right62(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^140) + if (r >= 2**140) return right63(r); return left63(r); } function left62(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^140) + if (r >= 2**140) return left63(r); return right63(r); } @@ -931,14 +958,14 @@ function right63(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^141) + if (r >= 2**141) return right64(r); return left64(r); } function left63(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^141) + if (r >= 2**141) return left64(r); return right64(r); } @@ -946,14 +973,14 @@ function right64(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^142) + if (r >= 2**142) return right65(r); return left65(r); } function left64(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^142) + if (r >= 2**142) return left65(r); return right65(r); } @@ -961,14 +988,14 @@ function right65(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^143) + if (r >= 2**143) return right66(r); return left66(r); } function left65(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^143) + if (r >= 2**143) return left66(r); return right66(r); } @@ -976,14 +1003,14 @@ function right66(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^144) + if (r >= 2**144) return right67(r); return left67(r); } function left66(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^144) + if (r >= 2**144) return left67(r); return right67(r); } @@ -991,14 +1018,14 @@ function right67(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^145) + if (r >= 2**145) return right68(r); return left68(r); } function left67(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^145) + if (r >= 2**145) return left68(r); return right68(r); } @@ -1006,14 +1033,14 @@ function right68(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^146) + if (r >= 2**146) return right69(r); return left69(r); } function left68(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^146) + if (r >= 2**146) return left69(r); return right69(r); } @@ -1021,14 +1048,14 @@ function right69(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^147) + if (r >= 2**147) return right70(r); return left70(r); } function left69(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^147) + if (r >= 2**147) return left70(r); return right70(r); } @@ -1036,14 +1063,14 @@ function right70(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^148) + if (r >= 2**148) return right71(r); return left71(r); } function left70(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^148) + if (r >= 2**148) return left71(r); return right71(r); } @@ -1051,14 +1078,14 @@ function right71(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^149) + if (r >= 2**149) return right72(r); return left72(r); } function left71(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^149) + if (r >= 2**149) return left72(r); return right72(r); } @@ -1066,14 +1093,14 @@ function right72(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^150) + if (r >= 2**150) return right73(r); return left73(r); } function left72(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^150) + if (r >= 2**150) return left73(r); return right73(r); } @@ -1081,14 +1108,14 @@ function right73(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^151) + if (r >= 2**151) return right74(r); return left74(r); } function left73(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^151) + if (r >= 2**151) return left74(r); return right74(r); } @@ -1096,14 +1123,14 @@ function right74(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^152) + if (r >= 2**152) return right75(r); return left75(r); } function left74(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^152) + if (r >= 2**152) return left75(r); return right75(r); } @@ -1111,14 +1138,14 @@ function right75(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^153) + if (r >= 2**153) return right76(r); return left76(r); } function left75(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^153) + if (r >= 2**153) return left76(r); return right76(r); } @@ -1126,14 +1153,14 @@ function right76(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^154) + if (r >= 2**154) return right77(r); return left77(r); } function left76(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^154) + if (r >= 2**154) return left77(r); return right77(r); } @@ -1141,14 +1168,14 @@ function right77(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^155) + if (r >= 2**155) return right78(r); return left78(r); } function left77(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^155) + if (r >= 2**155) return left78(r); return right78(r); } @@ -1156,14 +1183,14 @@ function right78(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^156) + if (r >= 2**156) return right79(r); return left79(r); } function left78(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^156) + if (r >= 2**156) return left79(r); return right79(r); } @@ -1171,14 +1198,14 @@ function right79(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^157) + if (r >= 2**157) return right80(r); return left80(r); } function left79(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^157) + if (r >= 2**157) return left80(r); return right80(r); } @@ -1186,14 +1213,14 @@ function right80(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^158) + if (r >= 2**158) return right81(r); return left81(r); } function left80(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^158) + if (r >= 2**158) return left81(r); return right81(r); } @@ -1201,14 +1228,14 @@ function right81(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^159) + if (r >= 2**159) return right82(r); return left82(r); } function left81(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^159) + if (r >= 2**159) return left82(r); return right82(r); } @@ -1216,14 +1243,14 @@ function right82(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^160) + if (r >= 2**160) return right83(r); return left83(r); } function left82(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^160) + if (r >= 2**160) return left83(r); return right83(r); } @@ -1231,14 +1258,14 @@ function right83(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^161) + if (r >= 2**161) return right84(r); return left84(r); } function left83(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^161) + if (r >= 2**161) return left84(r); return right84(r); } @@ -1246,14 +1273,14 @@ function right84(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^162) + if (r >= 2**162) return right85(r); return left85(r); } function left84(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^162) + if (r >= 2**162) return left85(r); return right85(r); } @@ -1261,14 +1288,14 @@ function right85(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^163) + if (r >= 2**163) return right86(r); return left86(r); } function left85(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^163) + if (r >= 2**163) return left86(r); return right86(r); } @@ -1276,14 +1303,14 @@ function right86(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^164) + if (r >= 2**164) return right87(r); return left87(r); } function left86(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^164) + if (r >= 2**164) return left87(r); return right87(r); } @@ -1291,14 +1318,14 @@ function right87(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^165) + if (r >= 2**165) return right88(r); return left88(r); } function left87(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^165) + if (r >= 2**165) return left88(r); return right88(r); } @@ -1306,14 +1333,14 @@ function right88(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^166) + if (r >= 2**166) return right89(r); return left89(r); } function left88(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^166) + if (r >= 2**166) return left89(r); return right89(r); } @@ -1321,14 +1348,14 @@ function right89(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^167) + if (r >= 2**167) return right90(r); return left90(r); } function left89(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^167) + if (r >= 2**167) return left90(r); return right90(r); } @@ -1336,14 +1363,14 @@ function right90(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^168) + if (r >= 2**168) return right91(r); return left91(r); } function left90(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^168) + if (r >= 2**168) return left91(r); return right91(r); } @@ -1351,14 +1378,14 @@ function right91(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^169) + if (r >= 2**169) return right92(r); return left92(r); } function left91(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^169) + if (r >= 2**169) return left92(r); return right92(r); } @@ -1366,14 +1393,14 @@ function right92(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^170) + if (r >= 2**170) return right93(r); return left93(r); } function left92(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^170) + if (r >= 2**170) return left93(r); return right93(r); } @@ -1381,14 +1408,14 @@ function right93(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^171) + if (r >= 2**171) return right94(r); return left94(r); } function left93(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^171) + if (r >= 2**171) return left94(r); return right94(r); } @@ -1396,14 +1423,14 @@ function right94(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^172) + if (r >= 2**172) return right95(r); return left95(r); } function left94(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^172) + if (r >= 2**172) return left95(r); return right95(r); } @@ -1411,14 +1438,14 @@ function right95(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^173) + if (r >= 2**173) return right96(r); return left96(r); } function left95(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^173) + if (r >= 2**173) return left96(r); return right96(r); } @@ -1426,14 +1453,14 @@ function right96(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^174) + if (r >= 2**174) return right97(r); return left97(r); } function left96(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^174) + if (r >= 2**174) return left97(r); return right97(r); } @@ -1441,14 +1468,14 @@ function right97(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^175) + if (r >= 2**175) return right98(r); return left98(r); } function left97(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^175) + if (r >= 2**175) return left98(r); return right98(r); } @@ -1456,14 +1483,14 @@ function right98(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^176) + if (r >= 2**176) return right99(r); return left99(r); } function left98(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^176) + if (r >= 2**176) return left99(r); return right99(r); } @@ -1471,15 +1498,16 @@ function right99(uint seed) returns (uint) { var r = nextRand(seed); - if (r >= 2^177) + if (r >= 2**177) return right100(r); return left100(r); } function left99(uint seed) returns (uint) { var r = nextRand(nextRand(seed)); - if (r >= 2^177) + if (r >= 2**177) return left100(r); return right100(r); } +} \ No newline at end of file diff --git a/test/ManyFunctionsGenerator.py b/test/ManyFunctionsGenerator.py index 93eef784c..b4f36af0e 100644 --- a/test/ManyFunctionsGenerator.py +++ b/test/ManyFunctionsGenerator.py @@ -7,14 +7,14 @@ i = 1 template = """ function right{0}(uint seed) returns (uint) {{ var r = nextRand(seed); - if (r >= 2^{2}) + if (r >= 2**{2}) return right{1}(r); return left{1}(r); }} function left{0}(uint seed) returns (uint) {{ var r = nextRand(nextRand(seed)); - if (r >= 2^{2}) + if (r >= 2**{2}) return left{1}(r); return right{1}(r); }} diff --git a/test/vmPerformanceTestFiller.json b/test/vmPerformanceTestFiller.json index eab8a2240..e33bd1955 100644 --- a/test/vmPerformanceTestFiller.json +++ b/test/vmPerformanceTestFiller.json @@ -13,7 +13,7 @@ "balance" : "1000000000000000000", "nonce" : "0", "//" : "ManyFunctions.sol", - "code" : "0x60e060020a60003504806301f99ad7146108c3578063023a624a146108d857806303bdecf5146108ed57806305fe035f14610902578063082d8f4914610917578063090bf3b71461092c5780630bd9c534146109415780630c4bfa94146109565780630e20ebe21461096b5780630f76de0d1461098057806310cfcc191461099557806313ce15a9146109aa578063140dcec4146109bf57806314d07a3e146109d45780631687f112146109e957806316eb6603146109fe578063172cf71714610a135780631bd6f59614610a285780631cdb857114610a3d5780631cf74ece14610a525780631d09ba2c14610a675780631f69aa5114610a7c578063223dcc7414610a9157806325e524d314610aa6578063261de7c414610abb5780632632924d14610ad05780632909cc5d14610ae55780632981699814610afa5780632a85a45d14610b0f5780632ca36da014610b245780632cbf1f0d14610b395780632d0f557314610b4e5780632d97867814610b6357806331db9efd14610b7857806332064db714610b8d57806332931fbb14610ba2578063355f51a014610bb7578063361bb34014610bcc578063364ddb0e14610be15780633792a01814610bf657806338c68f8f14610c0b57806338e586fd14610c20578063392d42ae14610c3557806339a87bd914610c4a5780633a95a33214610c5f5780633b8ecdf914610c745780633cf0659a14610c895780633eaf992314610c9e5780633fe97ead14610cb35780633ff11c8b14610cc8578063404efc5314610cdd578063407fce7b14610cf257806340c3b18714610d07578063440208c314610d1c57806344e86b2f14610d31578063455df57914610d465780634689ab4d14610d5b57806346be2e0c14610d70578063487cd86f14610d8557806348e6178214610d9a57806349d4a34414610daf5780634a0f597414610dc45780634bc24ec514610dd95780634c2fe45614610dee5780634cc885d414610e035780634eaaad7b14610e185780634eb166af14610e2d5780635050093414610e42578063506bff1114610e57578063508762c114610e6c578063526938f814610e8157806354400c6014610e96578063559510d814610eab57806355a5f70214610ec057806356ca528f14610ed5578063570a2a1614610eea5780635dab2e0f14610eff5780635dca53d314610f1457806362017ebc14610f29578063621a25f814610f3e578063626d4a3614610f5357806362b6a28214610f6857806364faf22c14610f7d57806366d7ffde14610f9257806367b886e814610fa757806367e902c714610fbc57806369d7774014610fd15780636b7ae8e614610fe65780636c3b659114610ffb5780636e54181e146110105780636e978d91146110255780636f63d2ec1461103a578063706332d11461104f57806370ac4bb9146110645780637138ef521461107957806371dd46a91461108e57806372a7c229146110a35780637376fc8d146110b8578063738a2679146110cd57806374552650146110e2578063746fc8d0146110f757806379254bb81461110c5780637adaa3f8146111215780637e4eb35b14611136578063885ec18e1461114b5780638b9ff6b6146111605780638ce113dc146111755780638defbc5e1461118a5780638f4613d51461119f5780638fdc24ba146111b45780639002dba4146111c957806391d15735146111de57806391d43b23146111f357806393b14daa1461120857806394d63afd1461121d57806395805dad1461123257806396f68782146112475780639740e4a21461125c578063981290131461127157806399a3f0e8146112865780639acb1ad41461129b5780639be07908146112b05780639c15be0b146112c55780639d451c4d146112da5780639d8ee943146112ef5780639ef6ca0f14611304578063a0db0a2214611319578063a18e2eb91461132e578063a408384914611343578063a57544da14611358578063a5a83e4d1461136d578063a6843f3414611382578063a6dacdd714611397578063a8c4c8bc146113ac578063aa058a73146113c1578063aad62da2146113d6578063aaf3e4f4146113eb578063ab81e77314611400578063abc93aee14611415578063abde33f71461142a578063b114b96c1461143f578063b3df873714611454578063b4174cb014611469578063b5d02a561461147e578063b731e84814611493578063b7b96723146114a8578063bbcded7a146114bd578063bbececa9146114d2578063beca7440146114e7578063bf8981c0146114fc578063c028c67414611511578063c2385fa614611526578063c319a02c1461153b578063c569bae014611550578063c6715f8114611565578063c7b98dec1461157a578063c9acab841461158f578063ca9efc73146115a4578063cad80024146115b9578063cdadb0fa146115ce578063cdbdf391146115e3578063cf460fa5146115f8578063cf69318a1461160d578063d1835b8c14611622578063d353a1cb14611637578063d3e141e01461164c578063d5ec7e1d14611661578063d7ead1de14611676578063d90b02aa1461168b578063d959e244146116a0578063d9e68b44146116b5578063daacb24f146116ca578063dc12a805146116df578063dd946033146116f4578063dda5142414611709578063de6612171461171e578063dfb9560c14611733578063e03827d214611748578063e21720001461175d578063e2c718d814611772578063e3da539914611787578063e48e603f1461179c578063e5f9ec29146117b1578063e6c0459a146117c6578063e70addec146117db578063e7a01215146117f0578063ea7f4d2714611805578063ebb6c59f1461181a578063ed6302be1461182f578063ed64b36b14611844578063eecd278914611859578063f0ed14e01461186e578063f0f2134414611883578063f1e328f914611898578063f1e6f4cd146118ad578063f32fe995146118c2578063f75165c6146118d7578063f7ed71d0146118ec578063f80f44f314611901578063f8bc050514611916578063fbd3c51a1461192b578063fd72009014611940578063fed3a3001461195557005b6108ce600435611e83565b8060005260206000f35b6108e3600435611f50565b8060005260206000f35b6108f8600435613deb565b8060005260206000f35b61090d6004356119e8565b8060005260206000f35b610922600435612f82565b8060005260206000f35b6109376004356128fb565b8060005260206000f35b61094c60043561304f565b8060005260206000f35b61096160043561209b565b8060005260206000f35b610976600435614c0d565b8060005260206000f35b61098b60043561319a565b8060005260206000f35b6109a06004356122b3565b8060005260206000f35b6109b5600435613d1e565b8060005260206000f35b6109ca600435612598565b8060005260206000f35b6109df600435612875565b8060005260206000f35b6109f4600435613650565b8060005260206000f35b610a096004356133f9565b8060005260206000f35b610a1e6004356136d6565b8060005260206000f35b610a3360043561371d565b8060005260206000f35b610a48600435611ad9565b8060005260206000f35b610a5d60043561375c565b8060005260206000f35b610a72600435612168565b8060005260206000f35b610a8760043561425a565b8060005260206000f35b610a9c600435612121565b8060005260206000f35b610ab1600435611dbe565b8060005260206000f35b610ac6600435612b13565b8060005260206000f35b610adb600435612981565b8060005260206000f35b610af060043561222d565b8060005260206000f35b610b05600435613ac7565b8060005260206000f35b610b1a600435612db1565b8060005260206000f35b610b2f600435612e76565b8060005260206000f35b610b44600435613a80565b8060005260206000f35b610b59600435612c1f565b8060005260206000f35b610b6e6004356125d7565b8060005260206000f35b610b836004356147dd565b8060005260206000f35b610b98600435612445565b8060005260206000f35b610bad600435611a53565b8060005260206000f35b610bc2600435613373565b8060005260206000f35b610bd760043561332c565b8060005260206000f35b610bec600435613544565b8060005260206000f35b610c01600435611dfd565b8060005260206000f35b610c166004356145c5565b8060005260206000f35b610c2b600435611c2c565b8060005260206000f35b610c40600435612df0565b8060005260206000f35b610c55600435612a46565b8060005260206000f35b610c6a6004356137e2565b8060005260206000f35b610c7f600435611b20565b8060005260206000f35b610c946004356126a4565b8060005260206000f35b610ca9600435613d65565b8060005260206000f35b610cbe6004356133b2565b8060005260206000f35b610cd360043561464b565b8060005260206000f35b610ce8600435612769565b8060005260206000f35b610cfd600435612015565b8060005260206000f35b610d12600435612d6a565b8060005260206000f35b610d27600435611fd6565b8060005260206000f35b610d3c600435613f36565b8060005260206000f35b610d51600435614604565b8060005260206000f35b610d6660043561248c565b8060005260206000f35b610d7b600435612acc565b8060005260206000f35b610d90600435612b99565b8060005260206000f35b610da5600435611be5565b8060005260206000f35b610dba6004356129c8565b8060005260206000f35b610dcf6004356127ef565b8060005260206000f35b610de46004356139bb565b8060005260206000f35b610df9600435614b01565b8060005260206000f35b610e0e600435613bd3565b8060005260206000f35b610e23600435613fbc565b8060005260206000f35b610e38600435614003565b8060005260206000f35b610e4d600435612836565b8060005260206000f35b610e62600435611d77565b8060005260206000f35b610e77600435611eca565b8060005260206000f35b610e8c600435612c5e565b8060005260206000f35b610ea1600435612380565b8060005260206000f35b610eb66004356135ca565b8060005260206000f35b610ecb60043561315b565b8060005260206000f35b610ee06004356122fa565b8060005260206000f35b610ef560043561358b565b8060005260206000f35b610f0a6004356144f8565b8060005260206000f35b610f1f600435612942565b8060005260206000f35b610f34600435613220565b8060005260206000f35b610f49600435613c59565b8060005260206000f35b610f5e600435613697565b8060005260206000f35b610f73600435613008565b8060005260206000f35b610f88600435612339565b8060005260206000f35b610f9d60043561265d565b8060005260206000f35b610fb2600435614cd2565b8060005260206000f35b610fc76004356149f5565b8060005260206000f35b610fdc600435614a34565b8060005260206000f35b610ff16004356140c8565b8060005260206000f35b61100660043561453f565b8060005260206000f35b61101b60043561410f565b8060005260206000f35b6110306004356148e9565b8060005260206000f35b611045600435613c98565b8060005260206000f35b61105a6004356131e1565b8060005260206000f35b61106f600435612a8d565b8060005260206000f35b611084600435611e44565b8060005260206000f35b6110996004356123bf565b8060005260206000f35b6110ae600435612f43565b8060005260206000f35b6110c3600435613cdf565b8060005260206000f35b6110d860043561468a565b8060005260206000f35b6110ed600435614bc6565b8060005260206000f35b611102600435613267565b8060005260206000f35b6111176004356128bc565b8060005260206000f35b61112c600435612e37565b8060005260206000f35b61114160043561308e565b8060005260206000f35b611156600435611cf1565b8060005260206000f35b61116b6004356149ae565b8060005260206000f35b611180600435613935565b8060005260206000f35b611195600435612a07565b8060005260206000f35b6111aa600435611f09565b8060005260206000f35b6111bf600435614b40565b8060005260206000f35b6111d4600435612274565b8060005260206000f35b6111e9600435611f8f565b8060005260206000f35b6111fe600435614195565b8060005260206000f35b6112136004356120e2565b8060005260206000f35b611228600435611b5f565b8060005260206000f35b61123d60043561196a565b8060005260206000f35b611252600435613a41565b8060005260206000f35b611267600435614796565b8060005260206000f35b61127c6004356132a6565b8060005260206000f35b611291600435613e71565b8060005260206000f35b6112a6600435612d2b565b8060005260206000f35b6112bb600435614366565b8060005260206000f35b6112d0600435613c12565b8060005260206000f35b6112e560043561421b565b8060005260206000f35b6112fa600435613ef7565b8060005260206000f35b61130f600435612b52565b8060005260206000f35b611324600435611ba6565b8060005260206000f35b611339600435613e2a565b8060005260206000f35b61134e6004356130d5565b8060005260206000f35b611363600435612ca5565b8060005260206000f35b61137860043561496f565b8060005260206000f35b61138d6004356132ed565b8060005260206000f35b6113a26004356138af565b8060005260206000f35b6113b7600435613b4d565b8060005260206000f35b6113cc600435611cb2565b8060005260206000f35b6113e16004356148a2565b8060005260206000f35b6113f660043561481c565b8060005260206000f35b61140b6004356139fa565b8060005260206000f35b611420600435613b8c565b8060005260206000f35b61143560043561272a565b8060005260206000f35b61144a600435614d9f565b8060005260206000f35b61145f600435613438565b8060005260206000f35b61147460043561347f565b8060005260206000f35b6114896004356119b3565b8060005260206000f35b61149e600435614aba565b8060005260206000f35b6114b3600435611d38565b8060005260206000f35b6114c8600435614042565b8060005260206000f35b6114dd6004356142e0565b8060005260206000f35b6114f2600435613505565b8060005260206000f35b611507600435612ce4565b8060005260206000f35b61151c6004356144b9565b8060005260206000f35b6115316004356142a1565b8060005260206000f35b611546600435614d19565b8060005260206000f35b61155b600435614a7b565b8060005260206000f35b611570600435613114565b8060005260206000f35b611585600435611a14565b8060005260206000f35b61159a6004356138ee565b8060005260206000f35b6115af600435614472565b8060005260206000f35b6115c4600435613868565b8060005260206000f35b6115d9600435613829565b8060005260206000f35b6115ee600435612bd8565b8060005260206000f35b6116036004356121ee565b8060005260206000f35b611618600435613974565b8060005260206000f35b61162d6004356124cb565b8060005260206000f35b6116426004356119a9565b8060005260206000f35b611657600435611c6b565b8060005260206000f35b61166c600435612551565b8060005260206000f35b611681600435614089565b8060005260206000f35b6116966004356143ec565b8060005260206000f35b6116ab6004356126e3565b8060005260206000f35b6116c06004356119fa565b8060005260206000f35b6116d5600435612fc9565b8060005260206000f35b6116ea6004356137a3565b8060005260206000f35b6116ff600435614433565b8060005260206000f35b6117146004356143ad565b8060005260206000f35b61172960043561414e565b8060005260206000f35b61173e60043561261e565b8060005260206000f35b611753600435613eb0565b8060005260206000f35b611768600435613b06565b8060005260206000f35b61177d600435612406565b8060005260206000f35b611792600435614928565b8060005260206000f35b6117a7600435613611565b8060005260206000f35b6117bc6004356134be565b8060005260206000f35b6117d1600435614327565b8060005260206000f35b6117e6600435614757565b8060005260206000f35b6117fb600435611a9a565b8060005260206000f35b61181060043561205c565b8060005260206000f35b611825600435613f7d565b8060005260206000f35b61183a600435614d58565b8060005260206000f35b61184f6004356121a7565b8060005260206000f35b611864600435614710565b8060005260206000f35b611879600435614b87565b8060005260206000f35b61188e6004356127b0565b8060005260206000f35b6118a3600435613da4565b8060005260206000f35b6118b8600435612ebd565b8060005260206000f35b6118cd600435614c4c565b8060005260206000f35b6118e2600435612512565b8060005260206000f35b6118f7600435612efc565b8060005260206000f35b61190c600435614c93565b8060005260206000f35b6119216004356141d4565b8060005260206000f35b61193660043561457e565b8060005260206000f35b61194b6004356146d1565b8060005260206000f35b611960600435614863565b8060005260206000f35b60006000611977836119b3565b9050604c81101561198757611997565b61199081611a53565b91506119a3565b6119a081611a14565b91505b50919050565b6000819050919050565b600060007f5851f42d4c957f2c0000000000000000000000000000000000000000000000019050828102600101915050919050565b60006119f3826119a9565b9050919050565b6000611a0d611a08836119b3565b6119a9565b9050919050565b60006000611a21836119b3565b9050604d811015611a3157611a41565b611a3a81611a9a565b9150611a4d565b611a4a81611ad9565b91505b50919050565b60006000611a68611a63846119b3565b6119b3565b9050604d811015611a7857611a88565b611a8181611ad9565b9150611a94565b611a9181611a9a565b91505b50919050565b60006000611aa7836119b3565b90506052811015611ab757611ac7565b611ac081611b20565b9150611ad3565b611ad081611b5f565b91505b50919050565b60006000611aee611ae9846119b3565b6119b3565b90506052811015611afe57611b0e565b611b0781611b5f565b9150611b1a565b611b1781611b20565b91505b50919050565b60006000611b2d836119b3565b90506053811015611b3d57611b4d565b611b4681611ba6565b9150611b59565b611b5681611be5565b91505b50919050565b60006000611b74611b6f846119b3565b6119b3565b90506053811015611b8457611b94565b611b8d81611be5565b9150611ba0565b611b9d81611ba6565b91505b50919050565b60006000611bb3836119b3565b90506050811015611bc357611bd3565b611bcc81611c2c565b9150611bdf565b611bdc81611c6b565b91505b50919050565b60006000611bfa611bf5846119b3565b6119b3565b90506050811015611c0a57611c1a565b611c1381611c6b565b9150611c26565b611c2381611c2c565b91505b50919050565b60006000611c39836119b3565b90506051811015611c4957611c59565b611c5281611cb2565b9150611c65565b611c6281611cf1565b91505b50919050565b60006000611c80611c7b846119b3565b6119b3565b90506051811015611c9057611ca0565b611c9981611cf1565b9150611cac565b611ca981611cb2565b91505b50919050565b60006000611cbf836119b3565b90506056811015611ccf57611cdf565b611cd881611d38565b9150611ceb565b611ce881611d77565b91505b50919050565b60006000611d06611d01846119b3565b6119b3565b90506056811015611d1657611d26565b611d1f81611d77565b9150611d32565b611d2f81611d38565b91505b50919050565b60006000611d45836119b3565b90506057811015611d5557611d65565b611d5e81611dbe565b9150611d71565b611d6e81611dfd565b91505b50919050565b60006000611d8c611d87846119b3565b6119b3565b90506057811015611d9c57611dac565b611da581611dfd565b9150611db8565b611db581611dbe565b91505b50919050565b60006000611dcb836119b3565b90506054811015611ddb57611deb565b611de481611e44565b9150611df7565b611df481611e83565b91505b50919050565b60006000611e12611e0d846119b3565b6119b3565b90506054811015611e2257611e32565b611e2b81611e83565b9150611e3e565b611e3b81611e44565b91505b50919050565b60006000611e51836119b3565b90506055811015611e6157611e71565b611e6a81611eca565b9150611e7d565b611e7a81611f09565b91505b50919050565b60006000611e98611e93846119b3565b6119b3565b90506055811015611ea857611eb8565b611eb181611f09565b9150611ec4565b611ec181611eca565b91505b50919050565b60006000611ed7836119b3565b9050605a811015611ee757611ef7565b611ef081611f50565b9150611f03565b611f0081611f8f565b91505b50919050565b60006000611f1e611f19846119b3565b6119b3565b9050605a811015611f2e57611f3e565b611f3781611f8f565b9150611f4a565b611f4781611f50565b91505b50919050565b60006000611f5d836119b3565b9050605b811015611f6d57611f7d565b611f7681611fd6565b9150611f89565b611f8681612015565b91505b50919050565b60006000611fa4611f9f846119b3565b6119b3565b9050605b811015611fb457611fc4565b611fbd81612015565b9150611fd0565b611fcd81611fd6565b91505b50919050565b60006000611fe3836119b3565b90506058811015611ff357612003565b611ffc8161205c565b915061200f565b61200c8161209b565b91505b50919050565b6000600061202a612025846119b3565b6119b3565b9050605881101561203a5761204a565b6120438161209b565b9150612056565b6120538161205c565b91505b50919050565b60006000612069836119b3565b9050605981101561207957612089565b612082816120e2565b9150612095565b61209281612121565b91505b50919050565b600060006120b06120ab846119b3565b6119b3565b905060598110156120c0576120d0565b6120c981612121565b91506120dc565b6120d9816120e2565b91505b50919050565b600060006120ef836119b3565b9050605e8110156120ff5761210f565b61210881612168565b915061211b565b612118816121a7565b91505b50919050565b60006000612136612131846119b3565b6119b3565b9050605e81101561214657612156565b61214f816121a7565b9150612162565b61215f81612168565b91505b50919050565b60006000612175836119b3565b9050605f81101561218557612195565b61218e816121ee565b91506121a1565b61219e8161222d565b91505b50919050565b600060006121bc6121b7846119b3565b6119b3565b9050605f8110156121cc576121dc565b6121d58161222d565b91506121e8565b6121e5816121ee565b91505b50919050565b600060006121fb836119b3565b9050605c81101561220b5761221b565b61221481612274565b9150612227565b612224816122b3565b91505b50919050565b6000600061224261223d846119b3565b6119b3565b9050605c81101561225257612262565b61225b816122b3565b915061226e565b61226b81612274565b91505b50919050565b60006000612281836119b3565b9050605d811015612291576122a1565b61229a816122fa565b91506122ad565b6122aa81612339565b91505b50919050565b600060006122c86122c3846119b3565b6119b3565b9050605d8110156122d8576122e8565b6122e181612339565b91506122f4565b6122f1816122fa565b91505b50919050565b60006000612307836119b3565b9050606281101561231757612327565b61232081612380565b9150612333565b612330816123bf565b91505b50919050565b6000600061234e612349846119b3565b6119b3565b9050606281101561235e5761236e565b612367816123bf565b915061237a565b61237781612380565b91505b50919050565b6000600061238d836119b3565b9050606381101561239d576123ad565b6123a681612406565b91506123b9565b6123b681612445565b91505b50919050565b600060006123d46123cf846119b3565b6119b3565b905060638110156123e4576123f4565b6123ed81612445565b9150612400565b6123fd81612406565b91505b50919050565b60006000612413836119b3565b9050606081101561242357612433565b61242c8161248c565b915061243f565b61243c816124cb565b91505b50919050565b6000600061245a612455846119b3565b6119b3565b9050606081101561246a5761247a565b612473816124cb565b9150612486565b6124838161248c565b91505b50919050565b60006000612499836119b3565b905060618110156124a9576124b9565b6124b281612512565b91506124c5565b6124c281612551565b91505b50919050565b600060006124e06124db846119b3565b6119b3565b905060618110156124f057612500565b6124f981612551565b915061250c565b61250981612512565b91505b50919050565b6000600061251f836119b3565b9050606681101561252f5761253f565b61253881612598565b915061254b565b612548816125d7565b91505b50919050565b60006000612566612561846119b3565b6119b3565b9050606681101561257657612586565b61257f816125d7565b9150612592565b61258f81612598565b91505b50919050565b600060006125a5836119b3565b905060678110156125b5576125c5565b6125be8161261e565b91506125d1565b6125ce8161265d565b91505b50919050565b600060006125ec6125e7846119b3565b6119b3565b905060678110156125fc5761260c565b6126058161265d565b9150612618565b6126158161261e565b91505b50919050565b6000600061262b836119b3565b9050606481101561263b5761264b565b612644816126a4565b9150612657565b612654816126e3565b91505b50919050565b6000600061267261266d846119b3565b6119b3565b9050606481101561268257612692565b61268b816126e3565b915061269e565b61269b816126a4565b91505b50919050565b600060006126b1836119b3565b905060658110156126c1576126d1565b6126ca8161272a565b91506126dd565b6126da81612769565b91505b50919050565b600060006126f86126f3846119b3565b6119b3565b9050606581101561270857612718565b61271181612769565b9150612724565b6127218161272a565b91505b50919050565b60006000612737836119b3565b9050606a81101561274757612757565b612750816127b0565b9150612763565b612760816127ef565b91505b50919050565b6000600061277e612779846119b3565b6119b3565b9050606a81101561278e5761279e565b612797816127ef565b91506127aa565b6127a7816127b0565b91505b50919050565b600060006127bd836119b3565b9050606b8110156127cd576127dd565b6127d681612836565b91506127e9565b6127e681612875565b91505b50919050565b600060006128046127ff846119b3565b6119b3565b9050606b81101561281457612824565b61281d81612875565b9150612830565b61282d81612836565b91505b50919050565b60006000612843836119b3565b9050606881101561285357612863565b61285c816128bc565b915061286f565b61286c816128fb565b91505b50919050565b6000600061288a612885846119b3565b6119b3565b9050606881101561289a576128aa565b6128a3816128fb565b91506128b6565b6128b3816128bc565b91505b50919050565b600060006128c9836119b3565b905060698110156128d9576128e9565b6128e281612942565b91506128f5565b6128f281612981565b91505b50919050565b6000600061291061290b846119b3565b6119b3565b9050606981101561292057612930565b61292981612981565b915061293c565b61293981612942565b91505b50919050565b6000600061294f836119b3565b9050606e81101561295f5761296f565b61296881612a07565b915061297b565b61297881612a46565b91505b50919050565b60006000612996612991846119b3565b6119b3565b9050606e8110156129a6576129b6565b6129af81612a46565b91506129c2565b6129bf81612a07565b91505b50919050565b600060006129d5836119b3565b905060b38110156129e5576129f5565b6129ee816119e8565b9150612a01565b6129fe816119fa565b91505b50919050565b60006000612a14836119b3565b9050606f811015612a2457612a34565b612a2d81612a8d565b9150612a40565b612a3d81612acc565b91505b50919050565b60006000612a5b612a56846119b3565b6119b3565b9050606f811015612a6b57612a7b565b612a7481612acc565b9150612a87565b612a8481612a8d565b91505b50919050565b60006000612a9a836119b3565b9050606c811015612aaa57612aba565b612ab381612b13565b9150612ac6565b612ac381612b52565b91505b50919050565b60006000612ae1612adc846119b3565b6119b3565b9050606c811015612af157612b01565b612afa81612b52565b9150612b0d565b612b0a81612b13565b91505b50919050565b60006000612b20836119b3565b9050606d811015612b3057612b40565b612b3981612b99565b9150612b4c565b612b4981612bd8565b91505b50919050565b60006000612b67612b62846119b3565b6119b3565b9050606d811015612b7757612b87565b612b8081612bd8565b9150612b93565b612b9081612b99565b91505b50919050565b60006000612ba6836119b3565b90506072811015612bb657612bc6565b612bbf81612c1f565b9150612bd2565b612bcf81612c5e565b91505b50919050565b60006000612bed612be8846119b3565b6119b3565b90506072811015612bfd57612c0d565b612c0681612c5e565b9150612c19565b612c1681612c1f565b91505b50919050565b60006000612c2c836119b3565b90506073811015612c3c57612c4c565b612c4581612ca5565b9150612c58565b612c5581612ce4565b91505b50919050565b60006000612c73612c6e846119b3565b6119b3565b90506073811015612c8357612c93565b612c8c81612ce4565b9150612c9f565b612c9c81612ca5565b91505b50919050565b60006000612cb2836119b3565b90506070811015612cc257612cd2565b612ccb81612d2b565b9150612cde565b612cdb81612d6a565b91505b50919050565b60006000612cf9612cf4846119b3565b6119b3565b90506070811015612d0957612d19565b612d1281612d6a565b9150612d25565b612d2281612d2b565b91505b50919050565b60006000612d38836119b3565b90506071811015612d4857612d58565b612d5181612db1565b9150612d64565b612d6181612df0565b91505b50919050565b60006000612d7f612d7a846119b3565b6119b3565b90506071811015612d8f57612d9f565b612d9881612df0565b9150612dab565b612da881612db1565b91505b50919050565b60006000612dbe836119b3565b90506076811015612dce57612dde565b612dd781612e37565b9150612dea565b612de781612e76565b91505b50919050565b60006000612e05612e00846119b3565b6119b3565b90506076811015612e1557612e25565b612e1e81612e76565b9150612e31565b612e2e81612e37565b91505b50919050565b60006000612e44836119b3565b90506077811015612e5457612e64565b612e5d81612ebd565b9150612e70565b612e6d81612efc565b91505b50919050565b60006000612e8b612e86846119b3565b6119b3565b90506077811015612e9b57612eab565b612ea481612efc565b9150612eb7565b612eb481612ebd565b91505b50919050565b60006000612eca836119b3565b90506074811015612eda57612eea565b612ee381612f43565b9150612ef6565b612ef381612f82565b91505b50919050565b60006000612f11612f0c846119b3565b6119b3565b90506074811015612f2157612f31565b612f2a81612f82565b9150612f3d565b612f3a81612f43565b91505b50919050565b60006000612f50836119b3565b90506075811015612f6057612f70565b612f6981612fc9565b9150612f7c565b612f7981613008565b91505b50919050565b60006000612f97612f92846119b3565b6119b3565b90506075811015612fa757612fb7565b612fb081613008565b9150612fc3565b612fc081612fc9565b91505b50919050565b60006000612fd6836119b3565b9050607a811015612fe657612ff6565b612fef8161304f565b9150613002565b612fff8161308e565b91505b50919050565b6000600061301d613018846119b3565b6119b3565b9050607a81101561302d5761303d565b6130368161308e565b9150613049565b6130468161304f565b91505b50919050565b6000600061305c836119b3565b9050607b81101561306c5761307c565b613075816130d5565b9150613088565b61308581613114565b91505b50919050565b600060006130a361309e846119b3565b6119b3565b9050607b8110156130b3576130c3565b6130bc81613114565b91506130cf565b6130cc816130d5565b91505b50919050565b600060006130e2836119b3565b905060788110156130f257613102565b6130fb8161315b565b915061310e565b61310b8161319a565b91505b50919050565b60006000613129613124846119b3565b6119b3565b9050607881101561313957613149565b6131428161319a565b9150613155565b6131528161315b565b91505b50919050565b60006000613168836119b3565b9050607981101561317857613188565b613181816131e1565b9150613194565b61319181613220565b91505b50919050565b600060006131af6131aa846119b3565b6119b3565b905060798110156131bf576131cf565b6131c881613220565b91506131db565b6131d8816131e1565b91505b50919050565b600060006131ee836119b3565b9050607e8110156131fe5761320e565b61320781613267565b915061321a565b613217816132a6565b91505b50919050565b60006000613235613230846119b3565b6119b3565b9050607e81101561324557613255565b61324e816132a6565b9150613261565b61325e81613267565b91505b50919050565b60006000613274836119b3565b9050607f81101561328457613294565b61328d816132ed565b91506132a0565b61329d8161332c565b91505b50919050565b600060006132bb6132b6846119b3565b6119b3565b9050607f8110156132cb576132db565b6132d48161332c565b91506132e7565b6132e4816132ed565b91505b50919050565b600060006132fa836119b3565b9050607c81101561330a5761331a565b61331381613373565b9150613326565b613323816133b2565b91505b50919050565b6000600061334161333c846119b3565b6119b3565b9050607c81101561335157613361565b61335a816133b2565b915061336d565b61336a81613373565b91505b50919050565b60006000613380836119b3565b9050607d811015613390576133a0565b613399816133f9565b91506133ac565b6133a981613438565b91505b50919050565b600060006133c76133c2846119b3565b6119b3565b9050607d8110156133d7576133e7565b6133e081613438565b91506133f3565b6133f0816133f9565b91505b50919050565b60006000613406836119b3565b9050608281101561341657613426565b61341f8161347f565b9150613432565b61342f816134be565b91505b50919050565b6000600061344d613448846119b3565b6119b3565b9050608281101561345d5761346d565b613466816134be565b9150613479565b6134768161347f565b91505b50919050565b6000600061348c836119b3565b9050608381101561349c576134ac565b6134a581613505565b91506134b8565b6134b581613544565b91505b50919050565b600060006134d36134ce846119b3565b6119b3565b905060838110156134e3576134f3565b6134ec81613544565b91506134ff565b6134fc81613505565b91505b50919050565b60006000613512836119b3565b9050608081101561352257613532565b61352b8161358b565b915061353e565b61353b816135ca565b91505b50919050565b60006000613559613554846119b3565b6119b3565b9050608081101561356957613579565b613572816135ca565b9150613585565b6135828161358b565b91505b50919050565b60006000613598836119b3565b905060818110156135a8576135b8565b6135b181613611565b91506135c4565b6135c181613650565b91505b50919050565b600060006135df6135da846119b3565b6119b3565b905060818110156135ef576135ff565b6135f881613650565b915061360b565b61360881613611565b91505b50919050565b6000600061361e836119b3565b9050608681101561362e5761363e565b61363781613697565b915061364a565b613647816136d6565b91505b50919050565b60006000613665613660846119b3565b6119b3565b9050608681101561367557613685565b61367e816136d6565b9150613691565b61368e81613697565b91505b50919050565b600060006136a4836119b3565b905060878110156136b4576136c4565b6136bd8161371d565b91506136d0565b6136cd8161375c565b91505b50919050565b600060006136eb6136e6846119b3565b6119b3565b905060878110156136fb5761370b565b6137048161375c565b9150613717565b6137148161371d565b91505b50919050565b6000600061372a836119b3565b9050608481101561373a5761374a565b613743816137a3565b9150613756565b613753816137e2565b91505b50919050565b6000600061377161376c846119b3565b6119b3565b9050608481101561378157613791565b61378a816137e2565b915061379d565b61379a816137a3565b91505b50919050565b600060006137b0836119b3565b905060858110156137c0576137d0565b6137c981613829565b91506137dc565b6137d981613868565b91505b50919050565b600060006137f76137f2846119b3565b6119b3565b9050608581101561380757613817565b61381081613868565b9150613823565b61382081613829565b91505b50919050565b60006000613836836119b3565b9050608a81101561384657613856565b61384f816138af565b9150613862565b61385f816138ee565b91505b50919050565b6000600061387d613878846119b3565b6119b3565b9050608a81101561388d5761389d565b613896816138ee565b91506138a9565b6138a6816138af565b91505b50919050565b600060006138bc836119b3565b9050608b8110156138cc576138dc565b6138d581613935565b91506138e8565b6138e581613974565b91505b50919050565b600060006139036138fe846119b3565b6119b3565b9050608b81101561391357613923565b61391c81613974565b915061392f565b61392c81613935565b91505b50919050565b60006000613942836119b3565b9050608881101561395257613962565b61395b816139bb565b915061396e565b61396b816139fa565b91505b50919050565b60006000613989613984846119b3565b6119b3565b90506088811015613999576139a9565b6139a2816139fa565b91506139b5565b6139b2816139bb565b91505b50919050565b600060006139c8836119b3565b905060898110156139d8576139e8565b6139e181613a41565b91506139f4565b6139f181613a80565b91505b50919050565b60006000613a0f613a0a846119b3565b6119b3565b90506089811015613a1f57613a2f565b613a2881613a80565b9150613a3b565b613a3881613a41565b91505b50919050565b60006000613a4e836119b3565b9050608e811015613a5e57613a6e565b613a6781613ac7565b9150613a7a565b613a7781613b06565b91505b50919050565b60006000613a95613a90846119b3565b6119b3565b9050608e811015613aa557613ab5565b613aae81613b06565b9150613ac1565b613abe81613ac7565b91505b50919050565b60006000613ad4836119b3565b9050608f811015613ae457613af4565b613aed81613b4d565b9150613b00565b613afd81613b8c565b91505b50919050565b60006000613b1b613b16846119b3565b6119b3565b9050608f811015613b2b57613b3b565b613b3481613b8c565b9150613b47565b613b4481613b4d565b91505b50919050565b60006000613b5a836119b3565b9050608c811015613b6a57613b7a565b613b7381613bd3565b9150613b86565b613b8381613c12565b91505b50919050565b60006000613ba1613b9c846119b3565b6119b3565b9050608c811015613bb157613bc1565b613bba81613c12565b9150613bcd565b613bca81613bd3565b91505b50919050565b60006000613be0836119b3565b9050608d811015613bf057613c00565b613bf981613c59565b9150613c0c565b613c0981613c98565b91505b50919050565b60006000613c27613c22846119b3565b6119b3565b9050608d811015613c3757613c47565b613c4081613c98565b9150613c53565b613c5081613c59565b91505b50919050565b60006000613c66836119b3565b90506092811015613c7657613c86565b613c7f81613cdf565b9150613c92565b613c8f81613d1e565b91505b50919050565b60006000613cad613ca8846119b3565b6119b3565b90506092811015613cbd57613ccd565b613cc681613d1e565b9150613cd9565b613cd681613cdf565b91505b50919050565b60006000613cec836119b3565b90506093811015613cfc57613d0c565b613d0581613d65565b9150613d18565b613d1581613da4565b91505b50919050565b60006000613d33613d2e846119b3565b6119b3565b90506093811015613d4357613d53565b613d4c81613da4565b9150613d5f565b613d5c81613d65565b91505b50919050565b60006000613d72836119b3565b90506090811015613d8257613d92565b613d8b81613deb565b9150613d9e565b613d9b81613e2a565b91505b50919050565b60006000613db9613db4846119b3565b6119b3565b90506090811015613dc957613dd9565b613dd281613e2a565b9150613de5565b613de281613deb565b91505b50919050565b60006000613df8836119b3565b90506091811015613e0857613e18565b613e1181613e71565b9150613e24565b613e2181613eb0565b91505b50919050565b60006000613e3f613e3a846119b3565b6119b3565b90506091811015613e4f57613e5f565b613e5881613eb0565b9150613e6b565b613e6881613e71565b91505b50919050565b60006000613e7e836119b3565b90506096811015613e8e57613e9e565b613e9781613ef7565b9150613eaa565b613ea781613f36565b91505b50919050565b60006000613ec5613ec0846119b3565b6119b3565b90506096811015613ed557613ee5565b613ede81613f36565b9150613ef1565b613eee81613ef7565b91505b50919050565b60006000613f04836119b3565b90506097811015613f1457613f24565b613f1d81613f7d565b9150613f30565b613f2d81613fbc565b91505b50919050565b60006000613f4b613f46846119b3565b6119b3565b90506097811015613f5b57613f6b565b613f6481613fbc565b9150613f77565b613f7481613f7d565b91505b50919050565b60006000613f8a836119b3565b90506094811015613f9a57613faa565b613fa381614003565b9150613fb6565b613fb381614042565b91505b50919050565b60006000613fd1613fcc846119b3565b6119b3565b90506094811015613fe157613ff1565b613fea81614042565b9150613ffd565b613ffa81614003565b91505b50919050565b60006000614010836119b3565b9050609581101561402057614030565b61402981614089565b915061403c565b614039816140c8565b91505b50919050565b60006000614057614052846119b3565b6119b3565b9050609581101561406757614077565b614070816140c8565b9150614083565b61408081614089565b91505b50919050565b60006000614096836119b3565b9050609a8110156140a6576140b6565b6140af8161410f565b91506140c2565b6140bf8161414e565b91505b50919050565b600060006140dd6140d8846119b3565b6119b3565b9050609a8110156140ed576140fd565b6140f68161414e565b9150614109565b6141068161410f565b91505b50919050565b6000600061411c836119b3565b9050609b81101561412c5761413c565b61413581614195565b9150614148565b614145816141d4565b91505b50919050565b6000600061416361415e846119b3565b6119b3565b9050609b81101561417357614183565b61417c816141d4565b915061418f565b61418c81614195565b91505b50919050565b600060006141a2836119b3565b905060988110156141b2576141c2565b6141bb8161421b565b91506141ce565b6141cb8161425a565b91505b50919050565b600060006141e96141e4846119b3565b6119b3565b905060988110156141f957614209565b6142028161425a565b9150614215565b6142128161421b565b91505b50919050565b60006000614228836119b3565b9050609981101561423857614248565b614241816142a1565b9150614254565b614251816142e0565b91505b50919050565b6000600061426f61426a846119b3565b6119b3565b9050609981101561427f5761428f565b614288816142e0565b915061429b565b614298816142a1565b91505b50919050565b600060006142ae836119b3565b9050609e8110156142be576142ce565b6142c781614327565b91506142da565b6142d781614366565b91505b50919050565b600060006142f56142f0846119b3565b6119b3565b9050609e81101561430557614315565b61430e81614366565b9150614321565b61431e81614327565b91505b50919050565b60006000614334836119b3565b9050609f81101561434457614354565b61434d816143ad565b9150614360565b61435d816143ec565b91505b50919050565b6000600061437b614376846119b3565b6119b3565b9050609f81101561438b5761439b565b614394816143ec565b91506143a7565b6143a4816143ad565b91505b50919050565b600060006143ba836119b3565b9050609c8110156143ca576143da565b6143d381614433565b91506143e6565b6143e381614472565b91505b50919050565b600060006144016143fc846119b3565b6119b3565b9050609c81101561441157614421565b61441a81614472565b915061442d565b61442a81614433565b91505b50919050565b60006000614440836119b3565b9050609d81101561445057614460565b614459816144b9565b915061446c565b614469816144f8565b91505b50919050565b60006000614487614482846119b3565b6119b3565b9050609d811015614497576144a7565b6144a0816144f8565b91506144b3565b6144b0816144b9565b91505b50919050565b600060006144c6836119b3565b905060a28110156144d6576144e6565b6144df8161453f565b91506144f2565b6144ef8161457e565b91505b50919050565b6000600061450d614508846119b3565b6119b3565b905060a281101561451d5761452d565b6145268161457e565b9150614539565b6145368161453f565b91505b50919050565b6000600061454c836119b3565b905060a381101561455c5761456c565b614565816145c5565b9150614578565b61457581614604565b91505b50919050565b6000600061459361458e846119b3565b6119b3565b905060a38110156145a3576145b3565b6145ac81614604565b91506145bf565b6145bc816145c5565b91505b50919050565b600060006145d2836119b3565b905060a08110156145e2576145f2565b6145eb8161464b565b91506145fe565b6145fb8161468a565b91505b50919050565b60006000614619614614846119b3565b6119b3565b905060a081101561462957614639565b6146328161468a565b9150614645565b6146428161464b565b91505b50919050565b60006000614658836119b3565b905060a181101561466857614678565b614671816146d1565b9150614684565b61468181614710565b91505b50919050565b6000600061469f61469a846119b3565b6119b3565b905060a18110156146af576146bf565b6146b881614710565b91506146cb565b6146c8816146d1565b91505b50919050565b600060006146de836119b3565b905060a68110156146ee576146fe565b6146f781614757565b915061470a565b61470781614796565b91505b50919050565b60006000614725614720846119b3565b6119b3565b905060a681101561473557614745565b61473e81614796565b9150614751565b61474e81614757565b91505b50919050565b60006000614764836119b3565b905060a781101561477457614784565b61477d816147dd565b9150614790565b61478d8161481c565b91505b50919050565b600060006147ab6147a6846119b3565b6119b3565b905060a78110156147bb576147cb565b6147c48161481c565b91506147d7565b6147d4816147dd565b91505b50919050565b600060006147ea836119b3565b905060a48110156147fa5761480a565b61480381614863565b9150614816565b614813816148a2565b91505b50919050565b6000600061483161482c846119b3565b6119b3565b905060a481101561484157614851565b61484a816148a2565b915061485d565b61485a81614863565b91505b50919050565b60006000614870836119b3565b905060a581101561488057614890565b614889816148e9565b915061489c565b61489981614928565b91505b50919050565b600060006148b76148b2846119b3565b6119b3565b905060a58110156148c7576148d7565b6148d081614928565b91506148e3565b6148e0816148e9565b91505b50919050565b600060006148f6836119b3565b905060aa81101561490657614916565b61490f8161496f565b9150614922565b61491f816149ae565b91505b50919050565b6000600061493d614938846119b3565b6119b3565b905060aa81101561494d5761495d565b614956816149ae565b9150614969565b6149668161496f565b91505b50919050565b6000600061497c836119b3565b905060ab81101561498c5761499c565b614995816149f5565b91506149a8565b6149a581614a34565b91505b50919050565b600060006149c36149be846119b3565b6119b3565b905060ab8110156149d3576149e3565b6149dc81614a34565b91506149ef565b6149ec816149f5565b91505b50919050565b60006000614a02836119b3565b905060a8811015614a1257614a22565b614a1b81614a7b565b9150614a2e565b614a2b81614aba565b91505b50919050565b60006000614a49614a44846119b3565b6119b3565b905060a8811015614a5957614a69565b614a6281614aba565b9150614a75565b614a7281614a7b565b91505b50919050565b60006000614a88836119b3565b905060a9811015614a9857614aa8565b614aa181614b01565b9150614ab4565b614ab181614b40565b91505b50919050565b60006000614acf614aca846119b3565b6119b3565b905060a9811015614adf57614aef565b614ae881614b40565b9150614afb565b614af881614b01565b91505b50919050565b60006000614b0e836119b3565b905060ae811015614b1e57614b2e565b614b2781614b87565b9150614b3a565b614b3781614bc6565b91505b50919050565b60006000614b55614b50846119b3565b6119b3565b905060ae811015614b6557614b75565b614b6e81614bc6565b9150614b81565b614b7e81614b87565b91505b50919050565b60006000614b94836119b3565b905060af811015614ba457614bb4565b614bad81614c0d565b9150614bc0565b614bbd81614c4c565b91505b50919050565b60006000614bdb614bd6846119b3565b6119b3565b905060af811015614beb57614bfb565b614bf481614c4c565b9150614c07565b614c0481614c0d565b91505b50919050565b60006000614c1a836119b3565b905060ac811015614c2a57614c3a565b614c3381614c93565b9150614c46565b614c4381614cd2565b91505b50919050565b60006000614c61614c5c846119b3565b6119b3565b905060ac811015614c7157614c81565b614c7a81614cd2565b9150614c8d565b614c8a81614c93565b91505b50919050565b60006000614ca0836119b3565b905060ad811015614cb057614cc0565b614cb981614d19565b9150614ccc565b614cc981614d58565b91505b50919050565b60006000614ce7614ce2846119b3565b6119b3565b905060ad811015614cf757614d07565b614d0081614d58565b9150614d13565b614d1081614d19565b91505b50919050565b60006000614d26836119b3565b905060b2811015614d3657614d46565b614d3f816129c8565b9150614d52565b614d4f81614d9f565b91505b50919050565b60006000614d6d614d68846119b3565b6119b3565b905060b2811015614d7d57614d8d565b614d8681614d9f565b9150614d99565b614d96816129c8565b91505b50919050565b60006000614db4614daf846119b3565b6119b3565b905060b3811015614dc457614dd4565b614dcd816119fa565b9150614de0565b614ddd816119e8565b91505b5091905056", + "code" : "0x60e060020a60003504806301f99ad7146108c3578063023a624a146108d857806303bdecf5146108ed57806305fe035f14610902578063082d8f4914610917578063090bf3b71461092c5780630bd9c534146109415780630c4bfa94146109565780630e20ebe21461096b5780630f76de0d1461098057806310cfcc191461099557806313ce15a9146109aa578063140dcec4146109bf57806314d07a3e146109d45780631687f112146109e957806316eb6603146109fe578063172cf71714610a135780631bd6f59614610a285780631cdb857114610a3d5780631cf74ece14610a525780631d09ba2c14610a675780631f69aa5114610a7c578063223dcc7414610a9157806325e524d314610aa6578063261de7c414610abb5780632632924d14610ad05780632909cc5d14610ae55780632981699814610afa5780632a85a45d14610b0f5780632ca36da014610b245780632cbf1f0d14610b395780632d0f557314610b4e5780632d97867814610b6357806331db9efd14610b7857806332064db714610b8d57806332931fbb14610ba2578063355f51a014610bb7578063361bb34014610bcc578063364ddb0e14610be15780633792a01814610bf657806338c68f8f14610c0b57806338e586fd14610c20578063392d42ae14610c3557806339a87bd914610c4a5780633a95a33214610c5f5780633b8ecdf914610c745780633cf0659a14610c895780633eaf992314610c9e5780633fe97ead14610cb35780633ff11c8b14610cc8578063404efc5314610cdd578063407fce7b14610cf257806340c3b18714610d07578063440208c314610d1c57806344e86b2f14610d31578063455df57914610d465780634689ab4d14610d5b57806346be2e0c14610d70578063487cd86f14610d8557806348e6178214610d9a57806349d4a34414610daf5780634a0f597414610dc45780634bc24ec514610dd95780634c2fe45614610dee5780634cc885d414610e035780634eaaad7b14610e185780634eb166af14610e2d5780635050093414610e42578063506bff1114610e57578063508762c114610e6c578063526938f814610e8157806354400c6014610e96578063559510d814610eab57806355a5f70214610ec057806356ca528f14610ed5578063570a2a1614610eea5780635dab2e0f14610eff5780635dca53d314610f1457806362017ebc14610f29578063621a25f814610f3e578063626d4a3614610f5357806362b6a28214610f6857806364faf22c14610f7d57806366d7ffde14610f9257806367b886e814610fa757806367e902c714610fbc57806369d7774014610fd15780636b7ae8e614610fe65780636c3b659114610ffb5780636e54181e146110105780636e978d91146110255780636f63d2ec1461103a578063706332d11461104f57806370ac4bb9146110645780637138ef521461107957806371dd46a91461108e57806372a7c229146110a35780637376fc8d146110b8578063738a2679146110cd57806374552650146110e2578063746fc8d0146110f757806379254bb81461110c5780637adaa3f8146111215780637e4eb35b14611136578063885ec18e1461114b5780638b9ff6b6146111605780638ce113dc146111755780638defbc5e1461118a5780638f4613d51461119f5780638fdc24ba146111b45780639002dba4146111c957806391d15735146111de57806391d43b23146111f357806393b14daa1461120857806394d63afd1461121d57806395805dad1461123257806396f68782146112475780639740e4a21461125c578063981290131461127157806399a3f0e8146112865780639acb1ad41461129b5780639be07908146112b05780639c15be0b146112c55780639d451c4d146112da5780639d8ee943146112ef5780639ef6ca0f14611304578063a0db0a2214611319578063a18e2eb91461132e578063a408384914611343578063a57544da14611358578063a5a83e4d1461136d578063a6843f3414611382578063a6dacdd714611397578063a8c4c8bc146113ac578063aa058a73146113c1578063aad62da2146113d6578063aaf3e4f4146113eb578063ab81e77314611400578063abc93aee14611415578063abde33f71461142a578063b114b96c1461143f578063b3df873714611454578063b4174cb014611469578063b5d02a561461147e578063b731e84814611493578063b7b96723146114a8578063bbcded7a146114bd578063bbececa9146114d2578063beca7440146114e7578063bf8981c0146114fc578063c028c67414611511578063c2385fa614611526578063c319a02c1461153b578063c569bae014611550578063c6715f8114611565578063c7b98dec1461157a578063c9acab841461158f578063ca9efc73146115a4578063cad80024146115b9578063cdadb0fa146115ce578063cdbdf391146115e3578063cf460fa5146115f8578063cf69318a1461160d578063d1835b8c14611622578063d353a1cb14611637578063d3e141e01461164c578063d5ec7e1d14611661578063d7ead1de14611676578063d90b02aa1461168b578063d959e244146116a0578063d9e68b44146116b5578063daacb24f146116ca578063dc12a805146116df578063dd946033146116f4578063dda5142414611709578063de6612171461171e578063dfb9560c14611733578063e03827d214611748578063e21720001461175d578063e2c718d814611772578063e3da539914611787578063e48e603f1461179c578063e5f9ec29146117b1578063e6c0459a146117c6578063e70addec146117db578063e7a01215146117f0578063ea7f4d2714611805578063ebb6c59f1461181a578063ed6302be1461182f578063ed64b36b14611844578063eecd278914611859578063f0ed14e01461186e578063f0f2134414611883578063f1e328f914611898578063f1e6f4cd146118ad578063f32fe995146118c2578063f75165c6146118d7578063f7ed71d0146118ec578063f80f44f314611901578063f8bc050514611916578063fbd3c51a1461192b578063fd72009014611940578063fed3a3001461195557005b6108ce600435612edf565b8060005260206000f35b6108e3600435612fb5565b8060005260206000f35b6108f8600435613f47565b8060005260206000f35b61090d600435612a11565b8060005260206000f35b6109226004356127ec565b8060005260206000f35b61093760043561215c565b8060005260206000f35b61094c6004356128c2565b8060005260206000f35b61096160043561310f565b8060005260206000f35b610976600435614e0b565b8060005260206000f35b61098b600435613269565b8060005260206000f35b6109a0600435611a82565b8060005260206000f35b6109b5600435613e71565b8060005260206000f35b6109ca600435611dd2565b8060005260206000f35b6109df6004356120d0565b8060005260206000f35b6109f4600435613755565b8060005260206000f35b610a096004356134e3565b8060005260206000f35b610a1e6004356137e1565b8060005260206000f35b610a3360043561382b565b8060005260206000f35b610a48600435612b0b565b8060005260206000f35b610a5d60043561386d565b8060005260206000f35b610a726004356131e5565b8060005260206000f35b610a876004356143e9565b8060005260206000f35b610a9c60043561319b565b8060005260206000f35b610ab1600435612e11565b8060005260206000f35b610ac660043561234a565b8060005260206000f35b610adb6004356121e8565b8060005260206000f35b610af06004356119f6565b8060005260206000f35b610b05600435613bff565b8060005260206000f35b610b1a600435612606565b8060005260206000f35b610b2f6004356126d4565b8060005260206000f35b610b44600435613bb5565b8060005260206000f35b610b59600435612462565b8060005260206000f35b610b6e600435611e14565b8060005260206000f35b610b836004356149ab565b8060005260206000f35b610b98600435611c26565b8060005260206000f35b610bad600435612a7f565b8060005260206000f35b610bc2600435613457565b8060005260206000f35b610bd760043561340d565b8060005260206000f35b610bec60043561363d565b8060005260206000f35b610c01600435612e53565b8060005260206000f35b610c1660043561477b565b8060005260206000f35b610c2b600435612c6d565b8060005260206000f35b610c40600435612648565b8060005260206000f35b610c55600435612274565b8060005260206000f35b610c6a6004356138f9565b8060005260206000f35b610c7f600435612b55565b8060005260206000f35b610c94600435611eea565b8060005260206000f35b610ca9600435613ebb565b8060005260206000f35b610cbe600435613499565b8060005260206000f35b610cd3600435614807565b8060005260206000f35b610ce8600435611fb8565b8060005260206000f35b610cfd600435613083565b8060005260206000f35b610d126004356125bc565b8060005260206000f35b610d27600435613041565b8060005260206000f35b610d3c6004356140a1565b8060005260206000f35b610d516004356147bd565b8060005260206000f35b610d66600435611c70565b8060005260206000f35b610d7b600435612300565b8060005260206000f35b610d906004356123d6565b8060005260206000f35b610da5600435612c23565b8060005260206000f35b610dba600435614faf565b8060005260206000f35b610dcf600435612044565b8060005260206000f35b610de4600435613ae7565b8060005260206000f35b610df9600435614cf3565b8060005260206000f35b610e0e600435613d17565b8060005260206000f35b610e2360043561412d565b8060005260206000f35b610e38600435614177565b8060005260206000f35b610e4d60043561208e565b8060005260206000f35b610e62600435612dc7565b8060005260206000f35b610e77600435612f29565b8060005260206000f35b610e8c6004356124a4565b8060005260206000f35b610ea1600435611b58565b8060005260206000f35b610eb66004356136c9565b8060005260206000f35b610ecb600435613227565b8060005260206000f35b610ee0600435611acc565b8060005260206000f35b610ef5600435613687565b8060005260206000f35b610f0a6004356146a5565b8060005260206000f35b610f1f6004356121a6565b8060005260206000f35b610f346004356132f5565b8060005260206000f35b610f49600435613da3565b8060005260206000f35b610f5e60043561379f565b8060005260206000f35b610f73600435612878565b8060005260206000f35b610f88600435611b0e565b8060005260206000f35b610f9d600435611ea0565b8060005260206000f35b610fb2600435614ed9565b8060005260206000f35b610fc7600435614bdb565b8060005260206000f35b610fdc600435614c1d565b8060005260206000f35b610ff1600435614245565b8060005260206000f35b6110066004356146ef565b8060005260206000f35b61101b60043561428f565b8060005260206000f35b611030600435614ac3565b8060005260206000f35b611045600435613de5565b8060005260206000f35b61105a6004356132b3565b8060005260206000f35b61106f6004356122be565b8060005260206000f35b611084600435612e9d565b8060005260206000f35b611099600435611b9a565b8060005260206000f35b6110ae6004356127aa565b8060005260206000f35b6110c3600435613e2f565b8060005260206000f35b6110d8600435614849565b8060005260206000f35b6110ed600435614dc1565b8060005260206000f35b61110260043561333f565b8060005260206000f35b61111760043561211a565b8060005260206000f35b61112c600435612692565b8060005260206000f35b611141600435612904565b8060005260206000f35b611156600435612d3b565b8060005260206000f35b61116b600435614b91565b8060005260206000f35b611180600435613a5b565b8060005260206000f35b611195600435612232565b8060005260206000f35b6111aa600435612f6b565b8060005260206000f35b6111bf600435614d35565b8060005260206000f35b6111d4600435611a40565b8060005260206000f35b6111e9600435612ff7565b8060005260206000f35b6111fe60043561431b565b8060005260206000f35b611213600435613159565b8060005260206000f35b611228600435612b97565b8060005260206000f35b61123d600435612990565b8060005260206000f35b611252600435613b73565b8060005260206000f35b611267600435614961565b8060005260206000f35b61127c600435613381565b8060005260206000f35b611291600435613fd3565b8060005260206000f35b6112a660043561257a565b8060005260206000f35b6112bb600435614501565b8060005260206000f35b6112d0600435613d59565b8060005260206000f35b6112e56004356143a7565b8060005260206000f35b6112fa60043561405f565b8060005260206000f35b61130f60043561238c565b8060005260206000f35b611324600435612be1565b8060005260206000f35b611339600435613f89565b8060005260206000f35b61134e60043561294e565b8060005260206000f35b6113636004356124ee565b8060005260206000f35b611378600435614b4f565b8060005260206000f35b61138d6004356133cb565b8060005260206000f35b6113a26004356139cf565b8060005260206000f35b6113b7600435613c8b565b8060005260206000f35b6113cc600435612cf9565b8060005260206000f35b6113e1600435614a79565b8060005260206000f35b6113f66004356149ed565b8060005260206000f35b61140b600435613b29565b8060005260206000f35b611420600435613ccd565b8060005260206000f35b611435600435611f76565b8060005260206000f35b61144a600435614ff1565b8060005260206000f35b61145f600435613525565b8060005260206000f35b61147460043561356f565b8060005260206000f35b6114896004356129dc565b8060005260206000f35b61149e600435614ca9565b8060005260206000f35b6114b3600435612d85565b8060005260206000f35b6114c86004356141b9565b8060005260206000f35b6114dd600435614475565b8060005260206000f35b6114f26004356135fb565b8060005260206000f35b611507600435612530565b8060005260206000f35b61151c600435614663565b8060005260206000f35b611531600435614433565b8060005260206000f35b611546600435614f23565b8060005260206000f35b61155b600435614c67565b8060005260206000f35b611570600435611d3e565b8060005260206000f35b611585600435612a3d565b8060005260206000f35b61159a600435613a11565b8060005260206000f35b6115af600435614619565b8060005260206000f35b6115c4600435613985565b8060005260206000f35b6115d9600435613943565b8060005260206000f35b6115ee600435612418565b8060005260206000f35b6116036004356119b4565b8060005260206000f35b611618600435613a9d565b8060005260206000f35b61162d600435611cb2565b8060005260206000f35b6116426004356129d2565b8060005260206000f35b611657600435612caf565b8060005260206000f35b61166c600435611d88565b8060005260206000f35b611681600435614203565b8060005260206000f35b61169660043561458d565b8060005260206000f35b6116ab600435611f2c565b8060005260206000f35b6116c0600435612a23565b8060005260206000f35b6116d5600435612836565b8060005260206000f35b6116ea6004356138b7565b8060005260206000f35b6116ff6004356145d7565b8060005260206000f35b61171460043561454b565b8060005260206000f35b6117296004356142d1565b8060005260206000f35b61173e600435611e5e565b8060005260206000f35b611753600435614015565b8060005260206000f35b611768600435613c41565b8060005260206000f35b61177d600435611be4565b8060005260206000f35b611792600435614b05565b8060005260206000f35b6117a7600435613713565b8060005260206000f35b6117bc6004356135b1565b8060005260206000f35b6117d16004356144bf565b8060005260206000f35b6117e660043561491f565b8060005260206000f35b6117fb600435612ac9565b8060005260206000f35b6118106004356130cd565b8060005260206000f35b6118256004356140eb565b8060005260206000f35b61183a600435614f65565b8060005260206000f35b61184f60043561196a565b8060005260206000f35b6118646004356148d5565b8060005260206000f35b611879600435614d7f565b8060005260206000f35b61188e600435612002565b8060005260206000f35b6118a3600435613efd565b8060005260206000f35b6118b860043561271e565b8060005260206000f35b6118cd600435614e4d565b8060005260206000f35b6118e2600435611cfc565b8060005260206000f35b6118f7600435612760565b8060005260206000f35b61190c600435614e97565b8060005260206000f35b61192160043561435d565b8060005260206000f35b611936600435614731565b8060005260206000f35b61194b600435614893565b8060005260206000f35b611960600435614a37565b8060005260206000f35b6000600061197f61197a846129dc565b6129dc565b9050605d60020a811015611992576119a2565b61199b816119f6565b91506119ae565b6119ab816119b4565b91505b50919050565b600060006119c1836129dc565b9050605e60020a8110156119d4576119e4565b6119dd81611a40565b91506119f0565b6119ed81611a82565b91505b50919050565b60006000611a0b611a06846129dc565b6129dc565b9050605e60020a811015611a1e57611a2e565b611a2781611a82565b9150611a3a565b611a3781611a40565b91505b50919050565b60006000611a4d836129dc565b9050605f60020a811015611a6057611a70565b611a6981611acc565b9150611a7c565b611a7981611b0e565b91505b50919050565b60006000611a97611a92846129dc565b6129dc565b9050605f60020a811015611aaa57611aba565b611ab381611b0e565b9150611ac6565b611ac381611acc565b91505b50919050565b60006000611ad9836129dc565b9050606060020a811015611aec57611afc565b611af581611b58565b9150611b08565b611b0581611b9a565b91505b50919050565b60006000611b23611b1e846129dc565b6129dc565b9050606060020a811015611b3657611b46565b611b3f81611b9a565b9150611b52565b611b4f81611b58565b91505b50919050565b60006000611b65836129dc565b9050606160020a811015611b7857611b88565b611b8181611be4565b9150611b94565b611b9181611c26565b91505b50919050565b60006000611baf611baa846129dc565b6129dc565b9050606160020a811015611bc257611bd2565b611bcb81611c26565b9150611bde565b611bdb81611be4565b91505b50919050565b60006000611bf1836129dc565b9050606260020a811015611c0457611c14565b611c0d81611c70565b9150611c20565b611c1d81611cb2565b91505b50919050565b60006000611c3b611c36846129dc565b6129dc565b9050606260020a811015611c4e57611c5e565b611c5781611cb2565b9150611c6a565b611c6781611c70565b91505b50919050565b60006000611c7d836129dc565b9050606360020a811015611c9057611ca0565b611c9981611cfc565b9150611cac565b611ca981611d88565b91505b50919050565b60006000611cc7611cc2846129dc565b6129dc565b9050606360020a811015611cda57611cea565b611ce381611d88565b9150611cf6565b611cf381611cfc565b91505b50919050565b60006000611d09836129dc565b9050606460020a811015611d1c57611d2c565b611d2581611dd2565b9150611d38565b611d3581611e14565b91505b50919050565b60006000611d53611d4e846129dc565b6129dc565b9050607a60020a811015611d6657611d76565b611d6f81613269565b9150611d82565b611d7f81613227565b91505b50919050565b60006000611d9d611d98846129dc565b6129dc565b9050606460020a811015611db057611dc0565b611db981611e14565b9150611dcc565b611dc981611dd2565b91505b50919050565b60006000611ddf836129dc565b9050606560020a811015611df257611e02565b611dfb81611e5e565b9150611e0e565b611e0b81611ea0565b91505b50919050565b60006000611e29611e24846129dc565b6129dc565b9050606560020a811015611e3c57611e4c565b611e4581611ea0565b9150611e58565b611e5581611e5e565b91505b50919050565b60006000611e6b836129dc565b9050606660020a811015611e7e57611e8e565b611e8781611eea565b9150611e9a565b611e9781611f2c565b91505b50919050565b60006000611eb5611eb0846129dc565b6129dc565b9050606660020a811015611ec857611ed8565b611ed181611f2c565b9150611ee4565b611ee181611eea565b91505b50919050565b60006000611ef7836129dc565b9050606760020a811015611f0a57611f1a565b611f1381611f76565b9150611f26565b611f2381611fb8565b91505b50919050565b60006000611f41611f3c846129dc565b6129dc565b9050606760020a811015611f5457611f64565b611f5d81611fb8565b9150611f70565b611f6d81611f76565b91505b50919050565b60006000611f83836129dc565b9050606860020a811015611f9657611fa6565b611f9f81612002565b9150611fb2565b611faf81612044565b91505b50919050565b60006000611fcd611fc8846129dc565b6129dc565b9050606860020a811015611fe057611ff0565b611fe981612044565b9150611ffc565b611ff981612002565b91505b50919050565b6000600061200f836129dc565b9050606960020a81101561202257612032565b61202b8161208e565b915061203e565b61203b816120d0565b91505b50919050565b60006000612059612054846129dc565b6129dc565b9050606960020a81101561206c5761207c565b612075816120d0565b9150612088565b6120858161208e565b91505b50919050565b6000600061209b836129dc565b9050606a60020a8110156120ae576120be565b6120b78161211a565b91506120ca565b6120c78161215c565b91505b50919050565b600060006120e56120e0846129dc565b6129dc565b9050606a60020a8110156120f857612108565b6121018161215c565b9150612114565b6121118161211a565b91505b50919050565b60006000612127836129dc565b9050606b60020a81101561213a5761214a565b612143816121a6565b9150612156565b612153816121e8565b91505b50919050565b6000600061217161216c846129dc565b6129dc565b9050606b60020a81101561218457612194565b61218d816121e8565b91506121a0565b61219d816121a6565b91505b50919050565b600060006121b3836129dc565b9050606c60020a8110156121c6576121d6565b6121cf81612232565b91506121e2565b6121df81612274565b91505b50919050565b600060006121fd6121f8846129dc565b6129dc565b9050606c60020a81101561221057612220565b61221981612274565b915061222c565b61222981612232565b91505b50919050565b6000600061223f836129dc565b9050606d60020a81101561225257612262565b61225b816122be565b915061226e565b61226b81612300565b91505b50919050565b60006000612289612284846129dc565b6129dc565b9050606d60020a81101561229c576122ac565b6122a581612300565b91506122b8565b6122b5816122be565b91505b50919050565b600060006122cb836129dc565b9050606e60020a8110156122de576122ee565b6122e78161234a565b91506122fa565b6122f78161238c565b91505b50919050565b60006000612315612310846129dc565b6129dc565b9050606e60020a81101561232857612338565b6123318161238c565b9150612344565b6123418161234a565b91505b50919050565b60006000612357836129dc565b9050606f60020a81101561236a5761237a565b612373816123d6565b9150612386565b61238381612418565b91505b50919050565b600060006123a161239c846129dc565b6129dc565b9050606f60020a8110156123b4576123c4565b6123bd81612418565b91506123d0565b6123cd816123d6565b91505b50919050565b600060006123e3836129dc565b9050607060020a8110156123f657612406565b6123ff81612462565b9150612412565b61240f816124a4565b91505b50919050565b6000600061242d612428846129dc565b6129dc565b9050607060020a81101561244057612450565b612449816124a4565b915061245c565b61245981612462565b91505b50919050565b6000600061246f836129dc565b9050607160020a81101561248257612492565b61248b816124ee565b915061249e565b61249b81612530565b91505b50919050565b600060006124b96124b4846129dc565b6129dc565b9050607160020a8110156124cc576124dc565b6124d581612530565b91506124e8565b6124e5816124ee565b91505b50919050565b600060006124fb836129dc565b9050607260020a81101561250e5761251e565b6125178161257a565b915061252a565b612527816125bc565b91505b50919050565b60006000612545612540846129dc565b6129dc565b9050607260020a81101561255857612568565b612561816125bc565b9150612574565b6125718161257a565b91505b50919050565b60006000612587836129dc565b9050607360020a81101561259a576125aa565b6125a381612606565b91506125b6565b6125b381612648565b91505b50919050565b600060006125d16125cc846129dc565b6129dc565b9050607360020a8110156125e4576125f4565b6125ed81612648565b9150612600565b6125fd81612606565b91505b50919050565b60006000612613836129dc565b9050607460020a81101561262657612636565b61262f81612692565b9150612642565b61263f816126d4565b91505b50919050565b6000600061265d612658846129dc565b6129dc565b9050607460020a81101561267057612680565b612679816126d4565b915061268c565b61268981612692565b91505b50919050565b6000600061269f836129dc565b9050607560020a8110156126b2576126c2565b6126bb8161271e565b91506126ce565b6126cb81612760565b91505b50919050565b600060006126e96126e4846129dc565b6129dc565b9050607560020a8110156126fc5761270c565b61270581612760565b9150612718565b6127158161271e565b91505b50919050565b6000600061272b836129dc565b9050607660020a81101561273e5761274e565b612747816127aa565b915061275a565b612757816127ec565b91505b50919050565b60006000612775612770846129dc565b6129dc565b9050607660020a81101561278857612798565b612791816127ec565b91506127a4565b6127a1816127aa565b91505b50919050565b600060006127b7836129dc565b9050607760020a8110156127ca576127da565b6127d381612836565b91506127e6565b6127e381612878565b91505b50919050565b600060006128016127fc846129dc565b6129dc565b9050607760020a81101561281457612824565b61281d81612878565b9150612830565b61282d81612836565b91505b50919050565b60006000612843836129dc565b9050607860020a81101561285657612866565b61285f816128c2565b9150612872565b61286f81612904565b91505b50919050565b6000600061288d612888846129dc565b6129dc565b9050607860020a8110156128a0576128b0565b6128a981612904565b91506128bc565b6128b9816128c2565b91505b50919050565b600060006128cf836129dc565b9050607960020a8110156128e2576128f2565b6128eb8161294e565b91506128fe565b6128fb81611d3e565b91505b50919050565b60006000612919612914846129dc565b6129dc565b9050607960020a81101561292c5761293c565b61293581611d3e565b9150612948565b6129458161294e565b91505b50919050565b6000600061295b836129dc565b9050607a60020a81101561296e5761297e565b61297781613227565b915061298a565b61298781613269565b91505b50919050565b6000600061299d836129dc565b9050604e60020a8110156129b0576129c0565b6129b981612a7f565b91506129cc565b6129c981612a3d565b91505b50919050565b6000819050919050565b600060007f5851f42d4c957f2c0000000000000000000000000000000000000000000000019050828102600101915050919050565b6000612a1c826129d2565b9050919050565b6000612a36612a31836129dc565b6129d2565b9050919050565b60006000612a4a836129dc565b9050604f60020a811015612a5d57612a6d565b612a6681612ac9565b9150612a79565b612a7681612b0b565b91505b50919050565b60006000612a94612a8f846129dc565b6129dc565b9050604f60020a811015612aa757612ab7565b612ab081612b0b565b9150612ac3565b612ac081612ac9565b91505b50919050565b60006000612ad6836129dc565b9050605060020a811015612ae957612af9565b612af281612b55565b9150612b05565b612b0281612b97565b91505b50919050565b60006000612b20612b1b846129dc565b6129dc565b9050605060020a811015612b3357612b43565b612b3c81612b97565b9150612b4f565b612b4c81612b55565b91505b50919050565b60006000612b62836129dc565b9050605160020a811015612b7557612b85565b612b7e81612be1565b9150612b91565b612b8e81612c23565b91505b50919050565b60006000612bac612ba7846129dc565b6129dc565b9050605160020a811015612bbf57612bcf565b612bc881612c23565b9150612bdb565b612bd881612be1565b91505b50919050565b60006000612bee836129dc565b9050605260020a811015612c0157612c11565b612c0a81612c6d565b9150612c1d565b612c1a81612caf565b91505b50919050565b60006000612c38612c33846129dc565b6129dc565b9050605260020a811015612c4b57612c5b565b612c5481612caf565b9150612c67565b612c6481612c6d565b91505b50919050565b60006000612c7a836129dc565b9050605360020a811015612c8d57612c9d565b612c9681612cf9565b9150612ca9565b612ca681612d3b565b91505b50919050565b60006000612cc4612cbf846129dc565b6129dc565b9050605360020a811015612cd757612ce7565b612ce081612d3b565b9150612cf3565b612cf081612cf9565b91505b50919050565b60006000612d06836129dc565b9050605460020a811015612d1957612d29565b612d2281612d85565b9150612d35565b612d3281612dc7565b91505b50919050565b60006000612d50612d4b846129dc565b6129dc565b9050605460020a811015612d6357612d73565b612d6c81612dc7565b9150612d7f565b612d7c81612d85565b91505b50919050565b60006000612d92836129dc565b9050605560020a811015612da557612db5565b612dae81612e11565b9150612dc1565b612dbe81612e53565b91505b50919050565b60006000612ddc612dd7846129dc565b6129dc565b9050605560020a811015612def57612dff565b612df881612e53565b9150612e0b565b612e0881612e11565b91505b50919050565b60006000612e1e836129dc565b9050605660020a811015612e3157612e41565b612e3a81612e9d565b9150612e4d565b612e4a81612edf565b91505b50919050565b60006000612e68612e63846129dc565b6129dc565b9050605660020a811015612e7b57612e8b565b612e8481612edf565b9150612e97565b612e9481612e9d565b91505b50919050565b60006000612eaa836129dc565b9050605760020a811015612ebd57612ecd565b612ec681612f29565b9150612ed9565b612ed681612f6b565b91505b50919050565b60006000612ef4612eef846129dc565b6129dc565b9050605760020a811015612f0757612f17565b612f1081612f6b565b9150612f23565b612f2081612f29565b91505b50919050565b60006000612f36836129dc565b9050605860020a811015612f4957612f59565b612f5281612fb5565b9150612f65565b612f6281612ff7565b91505b50919050565b60006000612f80612f7b846129dc565b6129dc565b9050605860020a811015612f9357612fa3565b612f9c81612ff7565b9150612faf565b612fac81612fb5565b91505b50919050565b60006000612fc2836129dc565b9050605960020a811015612fd557612fe5565b612fde81613041565b9150612ff1565b612fee81613083565b91505b50919050565b6000600061300c613007846129dc565b6129dc565b9050605960020a81101561301f5761302f565b61302881613083565b915061303b565b61303881613041565b91505b50919050565b6000600061304e836129dc565b9050605a60020a81101561306157613071565b61306a816130cd565b915061307d565b61307a8161310f565b91505b50919050565b60006000613098613093846129dc565b6129dc565b9050605a60020a8110156130ab576130bb565b6130b48161310f565b91506130c7565b6130c4816130cd565b91505b50919050565b600060006130da836129dc565b9050605b60020a8110156130ed576130fd565b6130f681613159565b9150613109565b6131068161319b565b91505b50919050565b6000600061312461311f846129dc565b6129dc565b9050605b60020a81101561313757613147565b6131408161319b565b9150613153565b61315081613159565b91505b50919050565b60006000613166836129dc565b9050605c60020a81101561317957613189565b613182816131e5565b9150613195565b6131928161196a565b91505b50919050565b600060006131b06131ab846129dc565b6129dc565b9050605c60020a8110156131c3576131d3565b6131cc8161196a565b91506131df565b6131dc816131e5565b91505b50919050565b600060006131f2836129dc565b9050605d60020a81101561320557613215565b61320e816119b4565b9150613221565b61321e816119f6565b91505b50919050565b60006000613234836129dc565b9050607b60020a81101561324757613257565b613250816132b3565b9150613263565b613260816132f5565b91505b50919050565b6000600061327e613279846129dc565b6129dc565b9050607b60020a811015613291576132a1565b61329a816132f5565b91506132ad565b6132aa816132b3565b91505b50919050565b600060006132c0836129dc565b9050607c60020a8110156132d3576132e3565b6132dc8161333f565b91506132ef565b6132ec81613381565b91505b50919050565b6000600061330a613305846129dc565b6129dc565b9050607c60020a81101561331d5761332d565b61332681613381565b9150613339565b6133368161333f565b91505b50919050565b6000600061334c836129dc565b9050607d60020a81101561335f5761336f565b613368816133cb565b915061337b565b6133788161340d565b91505b50919050565b60006000613396613391846129dc565b6129dc565b9050607d60020a8110156133a9576133b9565b6133b28161340d565b91506133c5565b6133c2816133cb565b91505b50919050565b600060006133d8836129dc565b9050607e60020a8110156133eb576133fb565b6133f481613457565b9150613407565b61340481613499565b91505b50919050565b6000600061342261341d846129dc565b6129dc565b9050607e60020a81101561343557613445565b61343e81613499565b9150613451565b61344e81613457565b91505b50919050565b60006000613464836129dc565b9050607f60020a81101561347757613487565b613480816134e3565b9150613493565b61349081613525565b91505b50919050565b600060006134ae6134a9846129dc565b6129dc565b9050607f60020a8110156134c1576134d1565b6134ca81613525565b91506134dd565b6134da816134e3565b91505b50919050565b600060006134f0836129dc565b9050608060020a81101561350357613513565b61350c8161356f565b915061351f565b61351c816135b1565b91505b50919050565b6000600061353a613535846129dc565b6129dc565b9050608060020a81101561354d5761355d565b613556816135b1565b9150613569565b6135668161356f565b91505b50919050565b6000600061357c836129dc565b9050608160020a81101561358f5761359f565b613598816135fb565b91506135ab565b6135a88161363d565b91505b50919050565b600060006135c66135c1846129dc565b6129dc565b9050608160020a8110156135d9576135e9565b6135e28161363d565b91506135f5565b6135f2816135fb565b91505b50919050565b60006000613608836129dc565b9050608260020a81101561361b5761362b565b61362481613687565b9150613637565b613634816136c9565b91505b50919050565b6000600061365261364d846129dc565b6129dc565b9050608260020a81101561366557613675565b61366e816136c9565b9150613681565b61367e81613687565b91505b50919050565b60006000613694836129dc565b9050608360020a8110156136a7576136b7565b6136b081613713565b91506136c3565b6136c081613755565b91505b50919050565b600060006136de6136d9846129dc565b6129dc565b9050608360020a8110156136f157613701565b6136fa81613755565b915061370d565b61370a81613713565b91505b50919050565b60006000613720836129dc565b9050608460020a81101561373357613743565b61373c8161379f565b915061374f565b61374c816137e1565b91505b50919050565b6000600061376a613765846129dc565b6129dc565b9050608460020a81101561377d5761378d565b613786816137e1565b9150613799565b6137968161379f565b91505b50919050565b600060006137ac836129dc565b9050608560020a8110156137bf576137cf565b6137c88161382b565b91506137db565b6137d88161386d565b91505b50919050565b600060006137f66137f1846129dc565b6129dc565b9050608560020a81101561380957613819565b6138128161386d565b9150613825565b6138228161382b565b91505b50919050565b60006000613838836129dc565b9050608660020a81101561384b5761385b565b613854816138b7565b9150613867565b613864816138f9565b91505b50919050565b6000600061388261387d846129dc565b6129dc565b9050608660020a811015613895576138a5565b61389e816138f9565b91506138b1565b6138ae816138b7565b91505b50919050565b600060006138c4836129dc565b9050608760020a8110156138d7576138e7565b6138e081613943565b91506138f3565b6138f081613985565b91505b50919050565b6000600061390e613909846129dc565b6129dc565b9050608760020a81101561392157613931565b61392a81613985565b915061393d565b61393a81613943565b91505b50919050565b60006000613950836129dc565b9050608860020a81101561396357613973565b61396c816139cf565b915061397f565b61397c81613a11565b91505b50919050565b6000600061399a613995846129dc565b6129dc565b9050608860020a8110156139ad576139bd565b6139b681613a11565b91506139c9565b6139c6816139cf565b91505b50919050565b600060006139dc836129dc565b9050608960020a8110156139ef576139ff565b6139f881613a5b565b9150613a0b565b613a0881613a9d565b91505b50919050565b60006000613a26613a21846129dc565b6129dc565b9050608960020a811015613a3957613a49565b613a4281613a9d565b9150613a55565b613a5281613a5b565b91505b50919050565b60006000613a68836129dc565b9050608a60020a811015613a7b57613a8b565b613a8481613ae7565b9150613a97565b613a9481613b29565b91505b50919050565b60006000613ab2613aad846129dc565b6129dc565b9050608a60020a811015613ac557613ad5565b613ace81613b29565b9150613ae1565b613ade81613ae7565b91505b50919050565b60006000613af4836129dc565b9050608b60020a811015613b0757613b17565b613b1081613b73565b9150613b23565b613b2081613bb5565b91505b50919050565b60006000613b3e613b39846129dc565b6129dc565b9050608b60020a811015613b5157613b61565b613b5a81613bb5565b9150613b6d565b613b6a81613b73565b91505b50919050565b60006000613b80836129dc565b9050608c60020a811015613b9357613ba3565b613b9c81613bff565b9150613baf565b613bac81613c41565b91505b50919050565b60006000613bca613bc5846129dc565b6129dc565b9050608c60020a811015613bdd57613bed565b613be681613c41565b9150613bf9565b613bf681613bff565b91505b50919050565b60006000613c0c836129dc565b9050608d60020a811015613c1f57613c2f565b613c2881613c8b565b9150613c3b565b613c3881613ccd565b91505b50919050565b60006000613c56613c51846129dc565b6129dc565b9050608d60020a811015613c6957613c79565b613c7281613ccd565b9150613c85565b613c8281613c8b565b91505b50919050565b60006000613c98836129dc565b9050608e60020a811015613cab57613cbb565b613cb481613d17565b9150613cc7565b613cc481613d59565b91505b50919050565b60006000613ce2613cdd846129dc565b6129dc565b9050608e60020a811015613cf557613d05565b613cfe81613d59565b9150613d11565b613d0e81613d17565b91505b50919050565b60006000613d24836129dc565b9050608f60020a811015613d3757613d47565b613d4081613da3565b9150613d53565b613d5081613de5565b91505b50919050565b60006000613d6e613d69846129dc565b6129dc565b9050608f60020a811015613d8157613d91565b613d8a81613de5565b9150613d9d565b613d9a81613da3565b91505b50919050565b60006000613db0836129dc565b9050609060020a811015613dc357613dd3565b613dcc81613e2f565b9150613ddf565b613ddc81613e71565b91505b50919050565b60006000613dfa613df5846129dc565b6129dc565b9050609060020a811015613e0d57613e1d565b613e1681613e71565b9150613e29565b613e2681613e2f565b91505b50919050565b60006000613e3c836129dc565b9050609160020a811015613e4f57613e5f565b613e5881613ebb565b9150613e6b565b613e6881613efd565b91505b50919050565b60006000613e86613e81846129dc565b6129dc565b9050609160020a811015613e9957613ea9565b613ea281613efd565b9150613eb5565b613eb281613ebb565b91505b50919050565b60006000613ec8836129dc565b9050609260020a811015613edb57613eeb565b613ee481613f47565b9150613ef7565b613ef481613f89565b91505b50919050565b60006000613f12613f0d846129dc565b6129dc565b9050609260020a811015613f2557613f35565b613f2e81613f89565b9150613f41565b613f3e81613f47565b91505b50919050565b60006000613f54836129dc565b9050609360020a811015613f6757613f77565b613f7081613fd3565b9150613f83565b613f8081614015565b91505b50919050565b60006000613f9e613f99846129dc565b6129dc565b9050609360020a811015613fb157613fc1565b613fba81614015565b9150613fcd565b613fca81613fd3565b91505b50919050565b60006000613fe0836129dc565b9050609460020a811015613ff357614003565b613ffc8161405f565b915061400f565b61400c816140a1565b91505b50919050565b6000600061402a614025846129dc565b6129dc565b9050609460020a81101561403d5761404d565b614046816140a1565b9150614059565b6140568161405f565b91505b50919050565b6000600061406c836129dc565b9050609560020a81101561407f5761408f565b614088816140eb565b915061409b565b6140988161412d565b91505b50919050565b600060006140b66140b1846129dc565b6129dc565b9050609560020a8110156140c9576140d9565b6140d28161412d565b91506140e5565b6140e2816140eb565b91505b50919050565b600060006140f8836129dc565b9050609660020a81101561410b5761411b565b61411481614177565b9150614127565b614124816141b9565b91505b50919050565b6000600061414261413d846129dc565b6129dc565b9050609660020a81101561415557614165565b61415e816141b9565b9150614171565b61416e81614177565b91505b50919050565b60006000614184836129dc565b9050609760020a811015614197576141a7565b6141a081614203565b91506141b3565b6141b081614245565b91505b50919050565b600060006141ce6141c9846129dc565b6129dc565b9050609760020a8110156141e1576141f1565b6141ea81614245565b91506141fd565b6141fa81614203565b91505b50919050565b60006000614210836129dc565b9050609860020a81101561422357614233565b61422c8161428f565b915061423f565b61423c816142d1565b91505b50919050565b6000600061425a614255846129dc565b6129dc565b9050609860020a81101561426d5761427d565b614276816142d1565b9150614289565b6142868161428f565b91505b50919050565b6000600061429c836129dc565b9050609960020a8110156142af576142bf565b6142b88161431b565b91506142cb565b6142c88161435d565b91505b50919050565b600060006142e66142e1846129dc565b6129dc565b9050609960020a8110156142f957614309565b6143028161435d565b9150614315565b6143128161431b565b91505b50919050565b60006000614328836129dc565b9050609a60020a81101561433b5761434b565b614344816143a7565b9150614357565b614354816143e9565b91505b50919050565b6000600061437261436d846129dc565b6129dc565b9050609a60020a81101561438557614395565b61438e816143e9565b91506143a1565b61439e816143a7565b91505b50919050565b600060006143b4836129dc565b9050609b60020a8110156143c7576143d7565b6143d081614433565b91506143e3565b6143e081614475565b91505b50919050565b600060006143fe6143f9846129dc565b6129dc565b9050609b60020a81101561441157614421565b61441a81614475565b915061442d565b61442a81614433565b91505b50919050565b60006000614440836129dc565b9050609c60020a81101561445357614463565b61445c816144bf565b915061446f565b61446c81614501565b91505b50919050565b6000600061448a614485846129dc565b6129dc565b9050609c60020a81101561449d576144ad565b6144a681614501565b91506144b9565b6144b6816144bf565b91505b50919050565b600060006144cc836129dc565b9050609d60020a8110156144df576144ef565b6144e88161454b565b91506144fb565b6144f88161458d565b91505b50919050565b60006000614516614511846129dc565b6129dc565b9050609d60020a81101561452957614539565b6145328161458d565b9150614545565b6145428161454b565b91505b50919050565b60006000614558836129dc565b9050609e60020a81101561456b5761457b565b614574816145d7565b9150614587565b61458481614619565b91505b50919050565b600060006145a261459d846129dc565b6129dc565b9050609e60020a8110156145b5576145c5565b6145be81614619565b91506145d1565b6145ce816145d7565b91505b50919050565b600060006145e4836129dc565b9050609f60020a8110156145f757614607565b61460081614663565b9150614613565b614610816146a5565b91505b50919050565b6000600061462e614629846129dc565b6129dc565b9050609f60020a81101561464157614651565b61464a816146a5565b915061465d565b61465a81614663565b91505b50919050565b60006000614670836129dc565b905060a060020a81101561468357614693565b61468c816146ef565b915061469f565b61469c81614731565b91505b50919050565b600060006146ba6146b5846129dc565b6129dc565b905060a060020a8110156146cd576146dd565b6146d681614731565b91506146e9565b6146e6816146ef565b91505b50919050565b600060006146fc836129dc565b905060a160020a81101561470f5761471f565b6147188161477b565b915061472b565b614728816147bd565b91505b50919050565b60006000614746614741846129dc565b6129dc565b905060a160020a81101561475957614769565b614762816147bd565b9150614775565b6147728161477b565b91505b50919050565b60006000614788836129dc565b905060a260020a81101561479b576147ab565b6147a481614807565b91506147b7565b6147b481614849565b91505b50919050565b600060006147d26147cd846129dc565b6129dc565b905060a260020a8110156147e5576147f5565b6147ee81614849565b9150614801565b6147fe81614807565b91505b50919050565b60006000614814836129dc565b905060a360020a81101561482757614837565b61483081614893565b9150614843565b614840816148d5565b91505b50919050565b6000600061485e614859846129dc565b6129dc565b905060a360020a81101561487157614881565b61487a816148d5565b915061488d565b61488a81614893565b91505b50919050565b600060006148a0836129dc565b905060a460020a8110156148b3576148c3565b6148bc8161491f565b91506148cf565b6148cc81614961565b91505b50919050565b600060006148ea6148e5846129dc565b6129dc565b905060a460020a8110156148fd5761490d565b61490681614961565b9150614919565b6149168161491f565b91505b50919050565b6000600061492c836129dc565b905060a560020a81101561493f5761494f565b614948816149ab565b915061495b565b614958816149ed565b91505b50919050565b60006000614976614971846129dc565b6129dc565b905060a560020a81101561498957614999565b614992816149ed565b91506149a5565b6149a2816149ab565b91505b50919050565b600060006149b8836129dc565b905060a660020a8110156149cb576149db565b6149d481614a37565b91506149e7565b6149e481614a79565b91505b50919050565b60006000614a026149fd846129dc565b6129dc565b905060a660020a811015614a1557614a25565b614a1e81614a79565b9150614a31565b614a2e81614a37565b91505b50919050565b60006000614a44836129dc565b905060a760020a811015614a5757614a67565b614a6081614ac3565b9150614a73565b614a7081614b05565b91505b50919050565b60006000614a8e614a89846129dc565b6129dc565b905060a760020a811015614aa157614ab1565b614aaa81614b05565b9150614abd565b614aba81614ac3565b91505b50919050565b60006000614ad0836129dc565b905060a860020a811015614ae357614af3565b614aec81614b4f565b9150614aff565b614afc81614b91565b91505b50919050565b60006000614b1a614b15846129dc565b6129dc565b905060a860020a811015614b2d57614b3d565b614b3681614b91565b9150614b49565b614b4681614b4f565b91505b50919050565b60006000614b5c836129dc565b905060a960020a811015614b6f57614b7f565b614b7881614bdb565b9150614b8b565b614b8881614c1d565b91505b50919050565b60006000614ba6614ba1846129dc565b6129dc565b905060a960020a811015614bb957614bc9565b614bc281614c1d565b9150614bd5565b614bd281614bdb565b91505b50919050565b60006000614be8836129dc565b905060aa60020a811015614bfb57614c0b565b614c0481614c67565b9150614c17565b614c1481614ca9565b91505b50919050565b60006000614c32614c2d846129dc565b6129dc565b905060aa60020a811015614c4557614c55565b614c4e81614ca9565b9150614c61565b614c5e81614c67565b91505b50919050565b60006000614c74836129dc565b905060ab60020a811015614c8757614c97565b614c9081614cf3565b9150614ca3565b614ca081614d35565b91505b50919050565b60006000614cbe614cb9846129dc565b6129dc565b905060ab60020a811015614cd157614ce1565b614cda81614d35565b9150614ced565b614cea81614cf3565b91505b50919050565b60006000614d00836129dc565b905060ac60020a811015614d1357614d23565b614d1c81614d7f565b9150614d2f565b614d2c81614dc1565b91505b50919050565b60006000614d4a614d45846129dc565b6129dc565b905060ac60020a811015614d5d57614d6d565b614d6681614dc1565b9150614d79565b614d7681614d7f565b91505b50919050565b60006000614d8c836129dc565b905060ad60020a811015614d9f57614daf565b614da881614e0b565b9150614dbb565b614db881614e4d565b91505b50919050565b60006000614dd6614dd1846129dc565b6129dc565b905060ad60020a811015614de957614df9565b614df281614e4d565b9150614e05565b614e0281614e0b565b91505b50919050565b60006000614e18836129dc565b905060ae60020a811015614e2b57614e3b565b614e3481614e97565b9150614e47565b614e4481614ed9565b91505b50919050565b60006000614e62614e5d846129dc565b6129dc565b905060ae60020a811015614e7557614e85565b614e7e81614ed9565b9150614e91565b614e8e81614e97565b91505b50919050565b60006000614ea4836129dc565b905060af60020a811015614eb757614ec7565b614ec081614f23565b9150614ed3565b614ed081614f65565b91505b50919050565b60006000614eee614ee9846129dc565b6129dc565b905060af60020a811015614f0157614f11565b614f0a81614f65565b9150614f1d565b614f1a81614f23565b91505b50919050565b60006000614f30836129dc565b905060b060020a811015614f4357614f53565b614f4c81614faf565b9150614f5f565b614f5c81614ff1565b91505b50919050565b60006000614f7a614f75846129dc565b6129dc565b905060b060020a811015614f8d57614f9d565b614f9681614ff1565b9150614fa9565b614fa681614faf565b91505b50919050565b60006000614fbc836129dc565b905060b160020a811015614fcf57614fdf565b614fd881612a11565b9150614feb565b614fe881612a23565b91505b50919050565b60006000615006615001846129dc565b6129dc565b905060b160020a81101561501957615029565b61502281612a23565b9150615035565b61503281612a11565b91505b5091905056", "storage": {} } }, From 6745e188c11c700a89828e546b2bbe79c5760e51 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Tue, 17 Feb 2015 18:05:41 +0100 Subject: [PATCH 212/213] JSON-RPC transactionCount && uncleCount, fixed #1027 --- libethereum/Client.cpp | 14 ++++++++ libethereum/Client.h | 2 ++ libethereum/Interface.h | 2 ++ libweb3jsonrpc/WebThreeStubServerBase.cpp | 20 +++++++++++ libweb3jsonrpc/WebThreeStubServerBase.h | 4 +++ libweb3jsonrpc/abstractwebthreestubserver.h | 24 +++++++++++++ libweb3jsonrpc/spec.json | 4 +++ mix/MixClient.cpp | 14 ++++++++ mix/MixClient.h | 2 ++ test/webthreestubclient.h | 40 +++++++++++++++++++++ 10 files changed, 126 insertions(+) diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index 4a49812df..d72762f36 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -714,6 +714,20 @@ BlockInfo Client::uncle(h256 _blockHash, unsigned _i) const return BlockInfo(); } +unsigned Client::transactionCount(h256 _blockHash) const +{ + auto bl = m_bc.block(_blockHash); + RLP b(bl); + return b[1].itemCount(); +} + +unsigned Client::uncleCount(h256 _blockHash) const +{ + auto bl = m_bc.block(_blockHash); + RLP b(bl); + return b[2].itemCount(); +} + LocalisedLogEntries Client::logs(LogFilter const& _f) const { LocalisedLogEntries ret; diff --git a/libethereum/Client.h b/libethereum/Client.h index cb4488b17..f4ab5ce76 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -229,6 +229,8 @@ public: virtual BlockDetails blockDetails(h256 _hash) const { return m_bc.details(_hash); } virtual Transaction transaction(h256 _blockHash, unsigned _i) const; virtual BlockInfo uncle(h256 _blockHash, unsigned _i) const; + virtual unsigned transactionCount(h256 _blockHash) const; + virtual unsigned uncleCount(h256 _blockHash) const; /// Differences between transactions. using Interface::diff; diff --git a/libethereum/Interface.h b/libethereum/Interface.h index 09a134f1f..847c181e0 100644 --- a/libethereum/Interface.h +++ b/libethereum/Interface.h @@ -103,6 +103,8 @@ public: virtual BlockDetails blockDetails(h256 _hash) const = 0; virtual Transaction transaction(h256 _blockHash, unsigned _i) const = 0; virtual BlockInfo uncle(h256 _blockHash, unsigned _i) const = 0; + virtual unsigned transactionCount(h256 _blockHash) const = 0; + virtual unsigned uncleCount(h256 _blockHash) const = 0; // [EXTRA API]: diff --git a/libweb3jsonrpc/WebThreeStubServerBase.cpp b/libweb3jsonrpc/WebThreeStubServerBase.cpp index 27b8268da..20efdc66b 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.cpp +++ b/libweb3jsonrpc/WebThreeStubServerBase.cpp @@ -367,6 +367,26 @@ double WebThreeStubServerBase::eth_countAt(string const& _address) return (double)(uint64_t)client()->countAt(jsToAddress(_address), client()->getDefault()); } +double WebThreeStubServerBase::eth_transactionCountByHash(std::string const& _hash) +{ + return client()->transactionCount(jsToFixed<32>(_hash)); +} + +double WebThreeStubServerBase::eth_transactionCountByNumber(int _number) +{ + return client()->transactionCount(client()->hashFromNumber(_number)); +} + +double WebThreeStubServerBase::eth_uncleCountByHash(std::string const& _hash) +{ + return client()->transactionCount(jsToFixed<32>(_hash)); +} + +double WebThreeStubServerBase::eth_uncleCountByNumber(int _number) +{ + return client()->transactionCount(client()->hashFromNumber(_number)); +} + int WebThreeStubServerBase::eth_defaultBlock() { return client()->getDefault(); diff --git a/libweb3jsonrpc/WebThreeStubServerBase.h b/libweb3jsonrpc/WebThreeStubServerBase.h index 005ac4130..368acb33d 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.h +++ b/libweb3jsonrpc/WebThreeStubServerBase.h @@ -76,6 +76,10 @@ public: virtual std::string eth_coinbase(); virtual Json::Value eth_compilers(); virtual double eth_countAt(std::string const& _address); + virtual double eth_transactionCountByHash(std::string const& _hash); + virtual double eth_transactionCountByNumber(int _number); + virtual double eth_uncleCountByHash(std::string const& _hash); + virtual double eth_uncleCountByNumber(int _number); virtual int eth_defaultBlock(); virtual std::string eth_gasPrice(); virtual Json::Value eth_filterLogs(int _id); diff --git a/libweb3jsonrpc/abstractwebthreestubserver.h b/libweb3jsonrpc/abstractwebthreestubserver.h index 5bade41f6..dc3cea392 100644 --- a/libweb3jsonrpc/abstractwebthreestubserver.h +++ b/libweb3jsonrpc/abstractwebthreestubserver.h @@ -29,6 +29,10 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServerbindAndAddMethod(jsonrpc::Procedure("eth_stateAt", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_stateAtI); this->bindAndAddMethod(jsonrpc::Procedure("eth_storageAt", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_storageAtI); this->bindAndAddMethod(jsonrpc::Procedure("eth_countAt", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_REAL, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_countAtI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_transactionCountByHash", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_REAL, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_transactionCountByHashI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_transactionCountByNumber", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_REAL, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::eth_transactionCountByNumberI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_uncleCountByHash", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_REAL, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_uncleCountByHashI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_uncleCountByNumber", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_REAL, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::eth_uncleCountByNumberI); this->bindAndAddMethod(jsonrpc::Procedure("eth_codeAt", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_codeAtI); this->bindAndAddMethod(jsonrpc::Procedure("eth_transact", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::eth_transactI); this->bindAndAddMethod(jsonrpc::Procedure("eth_call", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::eth_callI); @@ -141,6 +145,22 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServereth_countAt(request[0u].asString()); } + inline virtual void eth_transactionCountByHashI(const Json::Value &request, Json::Value &response) + { + response = this->eth_transactionCountByHash(request[0u].asString()); + } + inline virtual void eth_transactionCountByNumberI(const Json::Value &request, Json::Value &response) + { + response = this->eth_transactionCountByNumber(request[0u].asInt()); + } + inline virtual void eth_uncleCountByHashI(const Json::Value &request, Json::Value &response) + { + response = this->eth_uncleCountByHash(request[0u].asString()); + } + inline virtual void eth_uncleCountByNumberI(const Json::Value &request, Json::Value &response) + { + response = this->eth_uncleCountByNumber(request[0u].asInt()); + } inline virtual void eth_codeAtI(const Json::Value &request, Json::Value &response) { response = this->eth_codeAt(request[0u].asString()); @@ -298,6 +318,10 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServerCallMethod("eth_transactionCountByHash",p); + if (result.isDouble()) + return result.asDouble(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + double eth_transactionCountByNumber(int param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_transactionCountByNumber",p); + if (result.isDouble()) + return result.asDouble(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + double eth_uncleCountByHash(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_uncleCountByHash",p); + if (result.isDouble()) + return result.asDouble(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + double eth_uncleCountByNumber(int param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_uncleCountByNumber",p); + if (result.isDouble()) + return result.asDouble(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } std::string eth_codeAt(const std::string& param1) throw (jsonrpc::JsonRpcException) { Json::Value p; From b9a6fb71582e4d9ebf45730e6a937a78556ff183 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 17 Feb 2015 19:30:14 +0100 Subject: [PATCH 213/213] Warnings fix. --- alethzero/Context.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/alethzero/Context.h b/alethzero/Context.h index a2fb1a130..098690455 100644 --- a/alethzero/Context.h +++ b/alethzero/Context.h @@ -29,7 +29,7 @@ class QComboBox; -namespace dev { namespace eth { class StateDiff; } } +namespace dev { namespace eth { struct StateDiff; } } #define Small "font-size: small; " #define Mono "font-family: Ubuntu Mono, Monospace, Lucida Console, Courier New; font-weight: bold; "