From be4cd3a3c37a1025fd45d19b2fe9e9ef385fe4d5 Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 6 Jul 2015 17:26:11 +0200 Subject: [PATCH 01/14] Some cosmetic work on TrieDB. --- libdevcore/TrieDB.h | 150 +++++++++++++++++++++++--------------------- 1 file changed, 80 insertions(+), 70 deletions(-) diff --git a/libdevcore/TrieDB.h b/libdevcore/TrieDB.h index f35cf893c..fb50fadb6 100644 --- a/libdevcore/TrieDB.h +++ b/libdevcore/TrieDB.h @@ -66,7 +66,7 @@ class GenericTrieDB public: using DB = _DB; - GenericTrieDB(DB* _db = nullptr): m_db(_db) {} + explicit GenericTrieDB(DB* _db = nullptr): m_db(_db) {} GenericTrieDB(DB* _db, h256 const& _root, Verification _v = Verification::Normal) { open(_db, _root, _v); } ~GenericTrieDB() {} @@ -96,11 +96,72 @@ public: /// True if the trie is initialised but empty (i.e. that the DB contains the root node which is empty). bool isEmpty() const { return m_root == c_shaNull && node(m_root).size(); } - h256 const& root() const { if (!node(m_root).size()) BOOST_THROW_EXCEPTION(BadRoot()); /*std::cout << "Returning root as " << ret << " (really " << m_root << ")" << std::endl;*/ return m_root; } // patch the root in the case of the empty trie. TODO: handle this properly. + h256 const& root() const { if (node(m_root).empty()) BOOST_THROW_EXCEPTION(BadRoot()); /*std::cout << "Returning root as " << ret << " (really " << m_root << ")" << std::endl;*/ return m_root; } // patch the root in the case of the empty trie. TODO: handle this properly. + + std::string at(bytes const& _key) const { return at(&_key); } + std::string at(bytesConstRef _key) const; + void insert(bytes const& _key, bytes const& _value) { insert(&_key, &_value); } + void insert(bytesConstRef _key, bytes const& _value) { insert(_key, &_value); } + void insert(bytes const& _key, bytesConstRef _value) { insert(&_key, _value); } + void insert(bytesConstRef _key, bytesConstRef _value); + void remove(bytes const& _key) { remove(&_key); } + void remove(bytesConstRef _key); + bool contains(bytes const& _key) { return contains(&_key); } + bool contains(bytesConstRef _key) { return !at(_key).empty(); } + + class iterator + { + public: + using value_type = std::pair; + + iterator() {} + explicit iterator(GenericTrieDB const* _db); + iterator(GenericTrieDB const* _db, bytesConstRef _key); + + iterator& operator++() { next(); return *this; } + + value_type operator*() const { return at(); } + value_type operator->() const { return at(); } + + bool operator==(iterator const& _c) const { return _c.m_trail == m_trail; } + bool operator!=(iterator const& _c) const { return _c.m_trail != m_trail; } + + value_type at() const; + + private: + void next(); + void next(NibbleSlice _key); + + struct Node + { + std::string rlp; + std::string key; // as hexPrefixEncoding. + byte child; // 255 -> entering, 16 -> actually at the node, 17 -> exiting, 0-15 -> actual children. + + // 255 -> 16 -> 0 -> 1 -> ... -> 15 -> 17 + + void setChild(unsigned _i) { child = _i; } + void setFirstChild() { child = 16; } + void incrementChild() { child = child == 16 ? 0 : child == 15 ? 17 : (child + 1); } + + bool operator==(Node const& _c) const { return rlp == _c.rlp && key == _c.key && child == _c.child; } + bool operator!=(Node const& _c) const { return !operator==(_c); } + }; + + protected: + std::vector m_trail; + GenericTrieDB const* m_that; + }; + + iterator begin() const { return iterator(this); } + iterator end() const { return iterator(); } + + iterator lower_bound(bytesConstRef _key) const { return iterator(this, _key); } void debugPrint() {} - void descendKey(h256 _k, h256Hash& _keyMask, bool _wasExt, std::ostream* _out, int _indent = 0) const + /// Used for debugging, scans the whole trie. + void descendKey(h256 const& _k, h256Hash& _keyMask, bool _wasExt, std::ostream* _out, int _indent = 0) const { _keyMask.erase(_k); if (_k == m_root && _k == c_shaNull) // root allowed to be empty @@ -108,6 +169,7 @@ public: descendList(RLP(node(_k)), _keyMask, _wasExt, _out, _indent); // if not, it must be a list } + /// Used for debugging, scans the whole trie. void descendEntry(RLP const& _r, h256Hash& _keyMask, bool _wasExt, std::ostream* _out, int _indent) const { if (_r.isData() && _r.size() == 32) @@ -118,6 +180,7 @@ public: BOOST_THROW_EXCEPTION(InvalidTrie()); } + /// Used for debugging, scans the whole trie. void descendList(RLP const& _r, h256Hash& _keyMask, bool _wasExt, std::ostream* _out, int _indent) const { if (_r.isList() && _r.itemCount() == 2 && (!_wasExt || _out)) @@ -139,6 +202,7 @@ public: BOOST_THROW_EXCEPTION(InvalidTrie()); } + /// Used for debugging, scans the whole trie. h256Hash leftOvers(std::ostream* _out = nullptr) const { h256Hash k = m_db->keys(); @@ -146,11 +210,14 @@ public: return k; } + /// Used for debugging, scans the whole trie. void debugStructure(std::ostream& _out) const { leftOvers(&_out); } + /// Used for debugging, scans the whole trie. + /// @param _requireNoLeftOvers if true, requires that all keys are reachable. bool check(bool _requireNoLeftOvers) const { try @@ -164,66 +231,6 @@ public: } } - std::string at(bytes const& _key) const { return at(&_key); } - std::string at(bytesConstRef _key) const; - void insert(bytes const& _key, bytes const& _value) { insert(&_key, &_value); } - void insert(bytesConstRef _key, bytes const& _value) { insert(_key, &_value); } - void insert(bytes const& _key, bytesConstRef _value) { insert(&_key, _value); } - void insert(bytesConstRef _key, bytesConstRef _value); - void remove(bytes const& _key) { remove(&_key); } - void remove(bytesConstRef _key); - bool contains(bytes const& _key) { return contains(&_key); } - bool contains(bytesConstRef _key) { return !at(_key).empty(); } - - class iterator - { - public: - using value_type = std::pair; - - iterator() {} - iterator(GenericTrieDB const* _db); - iterator(GenericTrieDB const* _db, bytesConstRef _key); - - iterator& operator++() { next(); return *this; } - - value_type operator*() const { return at(); } - value_type operator->() const { return at(); } - - bool operator==(iterator const& _c) const { return _c.m_trail == m_trail; } - bool operator!=(iterator const& _c) const { return _c.m_trail != m_trail; } - - value_type at() const; - - private: - void next(); - void next(NibbleSlice _key); - - struct Node - { - std::string rlp; - std::string key; // as hexPrefixEncoding. - byte child; // 255 -> entering, 16 -> actually at the node, 17 -> exiting, 0-15 -> actual children. - - // 255 -> 16 -> 0 -> 1 -> ... -> 15 -> 17 - - void setChild(unsigned _i) { child = _i; } - void setFirstChild() { child = 16; } - void incrementChild() { child = child == 16 ? 0 : child == 15 ? 17 : (child + 1); } - - bool operator==(Node const& _c) const { return rlp == _c.rlp && key == _c.key && child == _c.child; } - bool operator!=(Node const& _c) const { return !operator==(_c); } - }; - - protected: - std::vector m_trail; - GenericTrieDB const* m_that; - }; - - iterator begin() const { return this; } - iterator end() const { return iterator(); } - - iterator lower_bound(bytesConstRef _key) const { return iterator(this, _key); } - protected: DB* db() const { return m_db; } @@ -279,12 +286,12 @@ private: bool isTwoItemNode(RLP const& _n) const; std::string deref(RLP const& _n) const; - std::string node(h256 _h) const { return m_db->lookup(_h); } + std::string node(h256 const& _h) const { return m_db->lookup(_h); } // These are low-level node insertion functions that just go straight through into the DB. h256 forceInsertNode(bytesConstRef _v) { auto h = sha3(_v); forceInsertNode(h, _v); return h; } - void forceInsertNode(h256 _h, bytesConstRef _v) { m_db->insert(_h, _v); } - void forceKillNode(h256 _h) { m_db->kill(_h); } + void forceInsertNode(h256 const& _h, bytesConstRef _v) { m_db->insert(_h, _v); } + void forceKillNode(h256 const& _h) { m_db->kill(_h); } // This are semantically-aware node insertion functions that only kills when the node's // data is < 32 bytes. It can safely be used when pruning the trie but won't work correctly @@ -305,6 +312,9 @@ std::ostream& operator<<(std::ostream& _out, GenericTrieDB const& _db) return _out; } +/** + * Different view on a GenericTrieDB that can use different key types. + */ template class SpecificTrieDB: public Generic { @@ -753,14 +763,14 @@ template void GenericTrieDB::insert(bytesConstRef _key, bytesCons tdebug << "Insert" << toHex(_key.cropped(0, 4)) << "=>" << toHex(_value); #endif - std::string rv = node(m_root); - assert(rv.size()); - bytes b = mergeAt(RLP(rv), m_root, NibbleSlice(_key), _value); + std::string rootValue = node(m_root); + assert(rootValue.size()); + bytes b = mergeAt(RLP(rootValue), m_root, NibbleSlice(_key), _value); // mergeAt won't attempt to delete the node if it's less than 32 bytes // However, we know it's the root node and thus always hashed. // So, if it's less than 32 (and thus should have been deleted but wasn't) then we delete it here. - if (rv.size() < 32) + if (rootValue.size() < 32) forceKillNode(m_root); m_root = forceInsertNode(&b); } From 9fe95754fe3884f5f33d060613455dda18ac7fa9 Mon Sep 17 00:00:00 2001 From: Vlad Gluhovsky Date: Tue, 7 Jul 2015 00:53:48 +0200 Subject: [PATCH 02/14] FixedHash::operator++() introduced --- libdevcore/FixedHash.h | 1 + test/libdevcore/FixedHash.cpp | 36 +++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/libdevcore/FixedHash.h b/libdevcore/FixedHash.h index a5b65458c..449848654 100644 --- a/libdevcore/FixedHash.h +++ b/libdevcore/FixedHash.h @@ -105,6 +105,7 @@ public: FixedHash& operator&=(FixedHash const& _c) { for (unsigned i = 0; i < N; ++i) m_data[i] &= _c.m_data[i]; return *this; } FixedHash operator&(FixedHash const& _c) const { return FixedHash(*this) &= _c; } FixedHash operator~() const { FixedHash ret; for (unsigned i = 0; i < N; ++i) ret[i] = ~m_data[i]; return ret; } + FixedHash& operator++() { for (unsigned i = size; i > 0 && !++m_data[--i]; ) {}; return *this; } /// @returns true if all one-bits in @a _c are set in this object. bool contains(FixedHash const& _c) const { return (*this & _c) == _c; } diff --git a/test/libdevcore/FixedHash.cpp b/test/libdevcore/FixedHash.cpp index 9a6ebe0e0..e990a3bd0 100644 --- a/test/libdevcore/FixedHash.cpp +++ b/test/libdevcore/FixedHash.cpp @@ -100,6 +100,42 @@ BOOST_AUTO_TEST_CASE(FixedHashContains) BOOST_CHECK(!h1.contains(h3)); } +void incrementSingleIteration(unsigned seed) +{ + unsigned next = seed + 1; + + FixedHash<4> h1(seed); + FixedHash<4> h2 = h1; + FixedHash<4> h3(next); + + FixedHash<32> hh1(seed); + FixedHash<32> hh2 = hh1; + FixedHash<32> hh3(next); + + BOOST_CHECK_EQUAL(++h2, h3); + BOOST_CHECK_EQUAL(++hh2, hh3); + + BOOST_CHECK(h2 > h1); + BOOST_CHECK(hh2 > hh1); + + unsigned reverse1 = ((FixedHash<4>::Arith)h2).convert_to(); + unsigned reverse2 = ((FixedHash<32>::Arith)hh2).convert_to(); + + BOOST_CHECK_EQUAL(next, reverse1); + BOOST_CHECK_EQUAL(next, reverse2); +} + +BOOST_AUTO_TEST_CASE(FixedHashIncrement) +{ + incrementSingleIteration(0); + incrementSingleIteration(1); + incrementSingleIteration(0xBAD); + incrementSingleIteration(0xBEEF); + incrementSingleIteration(0xFFFF); + incrementSingleIteration(0xFEDCBA); + incrementSingleIteration(0x7FFFFFFF); +} + BOOST_AUTO_TEST_SUITE_END() } From 694ab29b8deba473b61a287c3af61b0105c13892 Mon Sep 17 00:00:00 2001 From: Vlad Gluhovsky Date: Tue, 7 Jul 2015 01:46:23 +0200 Subject: [PATCH 03/14] style update --- libdevcore/FixedHash.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libdevcore/FixedHash.h b/libdevcore/FixedHash.h index 449848654..bf0444774 100644 --- a/libdevcore/FixedHash.h +++ b/libdevcore/FixedHash.h @@ -105,7 +105,7 @@ public: FixedHash& operator&=(FixedHash const& _c) { for (unsigned i = 0; i < N; ++i) m_data[i] &= _c.m_data[i]; return *this; } FixedHash operator&(FixedHash const& _c) const { return FixedHash(*this) &= _c; } FixedHash operator~() const { FixedHash ret; for (unsigned i = 0; i < N; ++i) ret[i] = ~m_data[i]; return ret; } - FixedHash& operator++() { for (unsigned i = size; i > 0 && !++m_data[--i]; ) {}; return *this; } + FixedHash& operator++() { for (unsigned i = size; i > 0 && !++m_data[--i]; ) {} return *this; } /// @returns true if all one-bits in @a _c are set in this object. bool contains(FixedHash const& _c) const { return (*this & _c) == _c; } From 455a1aed741a326cb81d995219170d770e735680 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Tue, 7 Jul 2015 10:17:50 +0200 Subject: [PATCH 04/14] rpc eth_sendTransaction returns always transaction hash --- alethzero/OurWebThreeStubServer.cpp | 3 ++- alethzero/OurWebThreeStubServer.h | 2 +- libdevcrypto/Common.cpp | 6 ++++++ libdevcrypto/Common.h | 3 +++ libethereum/ClientBase.cpp | 4 ++-- libethereum/ClientBase.h | 2 +- libethereum/Interface.cpp | 3 ++- libethereum/Interface.h | 2 +- libweb3jsonrpc/AccountHolder.cpp | 10 ++++++---- libweb3jsonrpc/AccountHolder.h | 6 +++--- libweb3jsonrpc/WebThreeStubServerBase.cpp | 10 +--------- mix/MixClient.cpp | 4 ++-- mix/MixClient.h | 4 ++-- 13 files changed, 32 insertions(+), 27 deletions(-) diff --git a/alethzero/OurWebThreeStubServer.cpp b/alethzero/OurWebThreeStubServer.cpp index a13f2b8f7..056b0460d 100644 --- a/alethzero/OurWebThreeStubServer.cpp +++ b/alethzero/OurWebThreeStubServer.cpp @@ -99,10 +99,11 @@ bool OurAccountHolder::showUnknownCallNotice(TransactionSkeleton const& _t, bool "REJECT UNLESS YOU REALLY KNOW WHAT YOU ARE DOING!"); } -void OurAccountHolder::authenticate(TransactionSkeleton const& _t) +h256 OurAccountHolder::authenticate(TransactionSkeleton const& _t) { Guard l(x_queued); m_queued.push(_t); + return h256(); } void OurAccountHolder::doValidations() diff --git a/alethzero/OurWebThreeStubServer.h b/alethzero/OurWebThreeStubServer.h index cc950027e..26053ae36 100644 --- a/alethzero/OurWebThreeStubServer.h +++ b/alethzero/OurWebThreeStubServer.h @@ -43,7 +43,7 @@ protected: // easiest to return keyManager.addresses(); virtual dev::AddressHash realAccounts() const override; // use web3 to submit a signed transaction to accept - virtual void authenticate(dev::eth::TransactionSkeleton const& _t) override; + virtual dev::h256 authenticate(dev::eth::TransactionSkeleton const& _t) override; private: bool showAuthenticationPopup(std::string const& _title, std::string const& _text); diff --git a/libdevcrypto/Common.cpp b/libdevcrypto/Common.cpp index 219b28f3a..8bf95d02f 100644 --- a/libdevcrypto/Common.cpp +++ b/libdevcrypto/Common.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #if ETH_HAVE_SECP256K1 #include #endif @@ -90,6 +91,11 @@ Address dev::toAddress(Secret const& _secret) return toAddress(p); } +Address dev::toAddress(Address const& _from, u256 const& _nonce) +{ + return right160(sha3(rlpList(_from, _nonce))); +} + void dev::encrypt(Public const& _k, bytesConstRef _plain, bytes& o_cipher) { bytes io = _plain.toBytes(); diff --git a/libdevcrypto/Common.h b/libdevcrypto/Common.h index b3d2649b8..c45e060b2 100644 --- a/libdevcrypto/Common.h +++ b/libdevcrypto/Common.h @@ -85,6 +85,9 @@ Address toAddress(Public const& _public); /// @returns 0 if it's not a valid secret key. Address toAddress(Secret const& _secret); +// Convert transaction from and nonce to address. +Address toAddress(Address const& _from, u256 const& _nonce); + /// Encrypts plain text using Public key. void encrypt(Public const& _k, bytesConstRef _plain, bytes& o_cipher); diff --git a/libethereum/ClientBase.cpp b/libethereum/ClientBase.cpp index 9a221f351..73404f83d 100644 --- a/libethereum/ClientBase.cpp +++ b/libethereum/ClientBase.cpp @@ -45,7 +45,7 @@ State ClientBase::asOf(BlockNumber _h) const return asOf(bc().numberHash(_h)); } -Address ClientBase::submitTransaction(TransactionSkeleton const& _t, Secret const& _secret) +h256 ClientBase::submitTransaction(TransactionSkeleton const& _t, Secret const& _secret) { prepareForTransaction(); @@ -59,7 +59,7 @@ Address ClientBase::submitTransaction(TransactionSkeleton const& _t, Secret cons StructuredLogger::transactionReceived(t.sha3().abridged(), t.sender().abridged()); cnote << "New transaction " << t; - return _t.creation ? right160(sha3(rlpList(ts.from, ts.nonce))) : Address(); + return t.sha3(); } // TODO: remove try/catch, allow exceptions diff --git a/libethereum/ClientBase.h b/libethereum/ClientBase.h index 609bde580..e08429c96 100644 --- a/libethereum/ClientBase.h +++ b/libethereum/ClientBase.h @@ -77,7 +77,7 @@ public: /// Submits the given transaction. /// @returns the new contract's address (assuming it all goes through). - virtual Address submitTransaction(TransactionSkeleton const& _t, Secret const& _secret) override; + virtual h256 submitTransaction(TransactionSkeleton const& _t, Secret const& _secret) override; using Interface::submitTransaction; /// Makes the given call. Nothing is recorded into the state. diff --git a/libethereum/Interface.cpp b/libethereum/Interface.cpp index f7d2d2468..efa304bd5 100644 --- a/libethereum/Interface.cpp +++ b/libethereum/Interface.cpp @@ -46,5 +46,6 @@ Address Interface::submitTransaction(Secret const& _secret, u256 const& _endowme ts.gas = _gas; ts.gasPrice = _gasPrice; ts.nonce = _nonce; - return submitTransaction(ts, _secret); + submitTransaction(ts, _secret); + return toAddress(toAddress(_secret), _nonce); } diff --git a/libethereum/Interface.h b/libethereum/Interface.h index 3e68a1e70..564589eb6 100644 --- a/libethereum/Interface.h +++ b/libethereum/Interface.h @@ -67,7 +67,7 @@ public: /// Submits a new transaction. /// @returns the new contract's address (assuming it all goes through and it's contract creation). - virtual Address submitTransaction(TransactionSkeleton const& _t, Secret const& _secret) = 0; + virtual h256 submitTransaction(TransactionSkeleton const& _t, Secret const& _secret) = 0; /// Submits the given message-call transaction. void submitTransaction(Secret const& _secret, u256 const& _value, Address const& _dest, bytes const& _data = bytes(), u256 const& _gas = 10000, u256 const& _gasPrice = 10 * szabo, u256 const& _nonce = UndefinedU256); diff --git a/libweb3jsonrpc/AccountHolder.cpp b/libweb3jsonrpc/AccountHolder.cpp index 6f6c288e2..f4b3a9f9f 100644 --- a/libweb3jsonrpc/AccountHolder.cpp +++ b/libweb3jsonrpc/AccountHolder.cpp @@ -106,20 +106,22 @@ AddressHash SimpleAccountHolder::realAccounts() const return m_keyManager.accountsHash(); } -void SimpleAccountHolder::authenticate(dev::eth::TransactionSkeleton const& _t) +h256 SimpleAccountHolder::authenticate(dev::eth::TransactionSkeleton const& _t) { if (isRealAccount(_t.from)) - m_client()->submitTransaction(_t, m_keyManager.secret(_t.from, [&](){ return m_getPassword(_t.from); })); + return m_client()->submitTransaction(_t, m_keyManager.secret(_t.from, [&](){ return m_getPassword(_t.from); })); else if (isProxyAccount(_t.from)) queueTransaction(_t); + return h256(); } -void FixedAccountHolder::authenticate(dev::eth::TransactionSkeleton const& _t) +h256 FixedAccountHolder::authenticate(dev::eth::TransactionSkeleton const& _t) { if (isRealAccount(_t.from)) - m_client()->submitTransaction(_t, m_accounts[_t.from]); + return m_client()->submitTransaction(_t, m_accounts[_t.from]); else if (isProxyAccount(_t.from)) queueTransaction(_t); + return h256(); } diff --git a/libweb3jsonrpc/AccountHolder.h b/libweb3jsonrpc/AccountHolder.h index 559f8509a..4a30826ae 100644 --- a/libweb3jsonrpc/AccountHolder.h +++ b/libweb3jsonrpc/AccountHolder.h @@ -51,7 +51,7 @@ public: virtual AddressHash realAccounts() const = 0; // use m_web3's submitTransaction // or use AccountHolder::queueTransaction(_t) to accept - virtual void authenticate(dev::eth::TransactionSkeleton const& _t) = 0; + virtual h256 authenticate(dev::eth::TransactionSkeleton const& _t) = 0; Addresses allAccounts() const; bool isRealAccount(Address const& _account) const { return realAccounts().count(_account) > 0; } @@ -85,7 +85,7 @@ public: {} AddressHash realAccounts() const override; - void authenticate(dev::eth::TransactionSkeleton const& _t) override; + h256 authenticate(dev::eth::TransactionSkeleton const& _t) override; private: std::function m_getPassword; @@ -117,7 +117,7 @@ public: // use m_web3's submitTransaction // or use AccountHolder::queueTransaction(_t) to accept - void authenticate(dev::eth::TransactionSkeleton const& _t) override; + h256 authenticate(dev::eth::TransactionSkeleton const& _t) override; private: std::unordered_map m_accounts; diff --git a/libweb3jsonrpc/WebThreeStubServerBase.cpp b/libweb3jsonrpc/WebThreeStubServerBase.cpp index 6a8ab8bd6..fd0b4c514 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.cpp +++ b/libweb3jsonrpc/WebThreeStubServerBase.cpp @@ -242,21 +242,16 @@ string WebThreeStubServerBase::eth_sendTransaction(Json::Value const& _json) { try { - string ret; TransactionSkeleton t = toTransactionSkeleton(_json); if (!t.from) t.from = m_ethAccounts->defaultTransactAccount(); - if (t.creation) - ret = toJS(right160(sha3(rlpList(t.from, client()->countAt(t.from))))); if (t.gasPrice == UndefinedU256) t.gasPrice = 10 * dev::eth::szabo; // TODO: should be determined by user somehow. if (t.gas == UndefinedU256) t.gas = min(client()->gasLimitRemaining() / 5, client()->balanceAt(t.from) / t.gasPrice); - m_ethAccounts->authenticate(t); - - return ret; + return toJS(m_ethAccounts->authenticate(t)); } catch (...) { @@ -268,13 +263,10 @@ string WebThreeStubServerBase::eth_signTransaction(Json::Value const& _json) { try { - string ret; TransactionSkeleton t = toTransactionSkeleton(_json); if (!t.from) t.from = m_ethAccounts->defaultTransactAccount(); - if (t.creation) - ret = toJS(right160(sha3(rlpList(t.from, client()->countAt(t.from)))));; if (t.gasPrice == UndefinedU256) t.gasPrice = 10 * dev::eth::szabo; // TODO: should be determined by user somehow. if (t.gas == UndefinedU256) diff --git a/mix/MixClient.cpp b/mix/MixClient.cpp index 8c52e5923..7978ff1ac 100644 --- a/mix/MixClient.cpp +++ b/mix/MixClient.cpp @@ -303,14 +303,14 @@ State MixClient::asOf(h256 const& _block) const return ret; } -Address MixClient::submitTransaction(eth::TransactionSkeleton const& _ts, Secret const& _secret, bool _gasAuto) +h256 MixClient::submitTransaction(eth::TransactionSkeleton const& _ts, Secret const& _secret, bool _gasAuto) { WriteGuard l(x_state); TransactionSkeleton ts = _ts; ts.nonce = m_state.transactionsFrom(toAddress(_secret)); eth::Transaction t(ts, _secret); executeTransaction(t, m_state, false, _gasAuto, _secret); - return _ts.creation ? right160(sha3(rlpList(ts.to, ts.nonce))) : Address(); + return t.sha3(); } dev::eth::ExecutionResult MixClient::call(Address const& _from, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, bool _gasAuto, FudgeFactor _ff) diff --git a/mix/MixClient.h b/mix/MixClient.h index 1ac32df0f..e4ad9c133 100644 --- a/mix/MixClient.h +++ b/mix/MixClient.h @@ -58,8 +58,8 @@ public: dev::eth::ExecutionResult create(Address const& _secret, u256 _value, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * eth::szabo, eth::BlockNumber _blockNumber = eth::PendingBlock, eth::FudgeFactor _ff = eth::FudgeFactor::Strict) override; using ClientBase::submitTransaction; - virtual Address submitTransaction(eth::TransactionSkeleton const& _ts, Secret const& _secret) override { return submitTransaction(_ts, _secret, false); } - Address submitTransaction(eth::TransactionSkeleton const& _ts, Secret const& _secret, bool _gasAuto); + virtual h256 submitTransaction(eth::TransactionSkeleton const& _ts, Secret const& _secret) override { return submitTransaction(_ts, _secret, false); } + h256 submitTransaction(eth::TransactionSkeleton const& _ts, Secret const& _secret, bool _gasAuto); dev::eth::ExecutionResult call(Address const& _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, eth::BlockNumber _blockNumber, bool _gasAuto, eth::FudgeFactor _ff = eth::FudgeFactor::Strict); void setAddress(Address _us) override; From c89f56309db167ab7f39ba5c8e3eb3107f574dd2 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Tue, 7 Jul 2015 10:20:26 +0200 Subject: [PATCH 05/14] updated Interface and ClientBase method "sendTransaction" description --- libethereum/ClientBase.h | 2 +- libethereum/Interface.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libethereum/ClientBase.h b/libethereum/ClientBase.h index e08429c96..f0e830d1d 100644 --- a/libethereum/ClientBase.h +++ b/libethereum/ClientBase.h @@ -76,7 +76,7 @@ public: virtual ~ClientBase() {} /// Submits the given transaction. - /// @returns the new contract's address (assuming it all goes through). + /// @returns the new transaction's hash. virtual h256 submitTransaction(TransactionSkeleton const& _t, Secret const& _secret) override; using Interface::submitTransaction; diff --git a/libethereum/Interface.h b/libethereum/Interface.h index 564589eb6..0d40937b8 100644 --- a/libethereum/Interface.h +++ b/libethereum/Interface.h @@ -66,7 +66,7 @@ public: // [TRANSACTION API] /// Submits a new transaction. - /// @returns the new contract's address (assuming it all goes through and it's contract creation). + /// @returns the transaction's hash. virtual h256 submitTransaction(TransactionSkeleton const& _t, Secret const& _secret) = 0; /// Submits the given message-call transaction. From ef3ccfcdaaf8e330556d9e41eb921fd7a59998c3 Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 7 Jul 2015 10:53:58 +0200 Subject: [PATCH 06/14] Use rlpList to construct some RLPs. --- eth/main.cpp | 10 ++-------- libdevcore/TrieDB.h | 12 ++++-------- libethereum/BlockChainSync.cpp | 1 - libethereum/BlockDetails.h | 4 ++-- neth/main.cpp | 6 +----- 5 files changed, 9 insertions(+), 24 deletions(-) diff --git a/eth/main.cpp b/eth/main.cpp index e4facccee..6a66df6a2 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -1026,9 +1026,7 @@ void interactiveMode(eth::Client* c, std::shared_ptr gasP { string path; iss >> path; - RLPStream config(2); - config << signingKey << beneficiary; - writeFile(path, config.out()); + writeFile(path, rlpList(signingKey, beneficiary)); } else cwarn << "Require parameter: exportConfig PATH"; @@ -1477,11 +1475,7 @@ int main(int argc, char** argv) for (auto const& s: passwordsToNote) keyManager.notePassword(s); - { - RLPStream config(2); - config << signingKey << beneficiary; - writeFile(configFile, config.out()); - } + writeFile(configFile, rlpList(signingKey, beneficiary)); if (sessionKey) signingKey = sessionKey; diff --git a/libdevcore/TrieDB.h b/libdevcore/TrieDB.h index f35cf893c..5d3784909 100644 --- a/libdevcore/TrieDB.h +++ b/libdevcore/TrieDB.h @@ -1066,11 +1066,11 @@ template bytes GenericTrieDB::place(RLP const& _orig, NibbleSlice killNode(_orig); if (_orig.isEmpty()) - return (RLPStream(2) << hexPrefixEncode(_k, true) << _s).out(); + return rlpList(hexPrefixEncode(_k, true), _s); assert(_orig.isList() && (_orig.itemCount() == 2 || _orig.itemCount() == 17)); if (_orig.itemCount() == 2) - return (RLPStream(2) << _orig[0] << _s).out(); + return rlpList(_orig[0], _s); auto s = RLPStream(17); for (unsigned i = 0; i < 16; ++i) @@ -1152,7 +1152,7 @@ template bytes GenericTrieDB::graft(RLP const& _orig) } assert(n.itemCount() == 2); - return (RLPStream(2) << hexPrefixEncode(keyOf(_orig), keyOf(n), isLeaf(n)) << n[1]).out(); + return rlpList(hexPrefixEncode(keyOf(_orig), keyOf(n), isLeaf(n)), n[1]); // auto ret = // std::cout << keyOf(_orig) << " ++ " << keyOf(n) << " == " << keyOf(RLP(ret)) << std::endl; // return ret; @@ -1201,11 +1201,7 @@ template bytes GenericTrieDB::branch(RLP const& _orig) for (unsigned i = 0; i < 16; ++i) if (i == b) if (isLeaf(_orig) || k.size() > 1) - { - RLPStream bottom(2); - bottom << hexPrefixEncode(k.mid(1), isLeaf(_orig)) << _orig[1]; - streamNode(r, bottom.out()); - } + streamNode(r, rlpList(hexPrefixEncode(k.mid(1), isLeaf(_orig)), _orig[1])); else r << _orig[1]; else diff --git a/libethereum/BlockChainSync.cpp b/libethereum/BlockChainSync.cpp index 90dc70574..e22f10880 100644 --- a/libethereum/BlockChainSync.cpp +++ b/libethereum/BlockChainSync.cpp @@ -397,7 +397,6 @@ void PV60Sync::transition(std::shared_ptr _peer, SyncState _s, boo if (m_state == SyncState::Idle && _s != SyncState::Idle) _peer->m_requireTransactions = true; - RLPStream s; if (_s == SyncState::Hashes) { if (m_state == SyncState::Idle || m_state == SyncState::Hashes) diff --git a/libethereum/BlockDetails.h b/libethereum/BlockDetails.h index f1526b5fd..73026834e 100644 --- a/libethereum/BlockDetails.h +++ b/libethereum/BlockDetails.h @@ -59,7 +59,7 @@ struct BlockLogBlooms { BlockLogBlooms() {} BlockLogBlooms(RLP const& _r) { blooms = _r.toVector(); size = _r.data().size(); } - bytes rlp() const { RLPStream s; s << blooms; size = s.out().size(); return s.out(); } + bytes rlp() const { bytes r = dev::rlp(blooms); size = r.size(); return r; } LogBlooms blooms; mutable unsigned size; @@ -69,7 +69,7 @@ struct BlocksBlooms { BlocksBlooms() {} BlocksBlooms(RLP const& _r) { blooms = _r.toArray(); size = _r.data().size(); } - bytes rlp() const { RLPStream s; s << blooms; size = s.out().size(); return s.out(); } + bytes rlp() const { bytes r = dev::rlp(blooms); size = r.size(); return r; } std::array blooms; mutable unsigned size; diff --git a/neth/main.cpp b/neth/main.cpp index 65f46735f..d5cb4bb4b 100644 --- a/neth/main.cpp +++ b/neth/main.cpp @@ -363,11 +363,7 @@ int main(int argc, char** argv) coinbase = config[1].toHash
(); } else - { - RLPStream config(2); - config << us.secret() << coinbase; - writeFile(configFile, config.out()); - } + writeFile(configFile, rlpList(us.secret(), coinbase)); for (int i = 1; i < argc; ++i) { From d2a20ef120931e5a3ca1dd563266e30bb55daadc Mon Sep 17 00:00:00 2001 From: Vlad Gluhovsky Date: Tue, 7 Jul 2015 11:16:41 +0200 Subject: [PATCH 07/14] test updated --- test/libdevcore/FixedHash.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/libdevcore/FixedHash.cpp b/test/libdevcore/FixedHash.cpp index e990a3bd0..dc5ced2c1 100644 --- a/test/libdevcore/FixedHash.cpp +++ b/test/libdevcore/FixedHash.cpp @@ -134,6 +134,10 @@ BOOST_AUTO_TEST_CASE(FixedHashIncrement) incrementSingleIteration(0xFFFF); incrementSingleIteration(0xFEDCBA); incrementSingleIteration(0x7FFFFFFF); + + FixedHash<4> h(0xFFFFFFFF); + FixedHash<4> zero; + BOOST_CHECK_EQUAL(++h, zero); } BOOST_AUTO_TEST_SUITE_END() From 560b09777e54082860b06953f2ae50046f384518 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Tue, 7 Jul 2015 12:25:38 +0200 Subject: [PATCH 08/14] Throw on FixedHash failure of String construction I have had this bite me a few times when testing FixedHash with the string constructor. A capital "X" in the 0x prefix, wrong number of hex characters compared to the number of bytes the FixedHash has e.t.c. and there was no warning. The hash had a 0 value while I was assuming it worked fine. Having it throw in case of error will guarantee that this won't happen again. --- libdevcore/FixedHash.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libdevcore/FixedHash.h b/libdevcore/FixedHash.h index a5b65458c..88b42f16c 100644 --- a/libdevcore/FixedHash.h +++ b/libdevcore/FixedHash.h @@ -81,7 +81,7 @@ public: explicit FixedHash(byte const* _bs, ConstructFromPointerType) { memcpy(m_data.data(), _bs, N); } /// Explicitly construct, copying from a string. - explicit FixedHash(std::string const& _s, ConstructFromStringType _t = FromHex, ConstructFromHashType _ht = FailIfDifferent): FixedHash(_t == FromHex ? fromHex(_s) : dev::asBytes(_s), _ht) {} + explicit FixedHash(std::string const& _s, ConstructFromStringType _t = FromHex, ConstructFromHashType _ht = FailIfDifferent): FixedHash(_t == FromHex ? fromHex(_s, WhenError::Throw) : dev::asBytes(_s), _ht) {} /// Convert to arithmetic type. operator Arith() const { return fromBigEndian(m_data); } From cea26e8dab99665e170a1c40d6762523ad32c073 Mon Sep 17 00:00:00 2001 From: arkpar Date: Tue, 7 Jul 2015 13:22:33 +0200 Subject: [PATCH 09/14] Fixed clang warnings --- alethzero/CMakeLists.txt | 5 +++++ libethereum/TransactionQueue.h | 2 +- mix/CMakeLists.txt | 5 +++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/alethzero/CMakeLists.txt b/alethzero/CMakeLists.txt index 93609e54c..25bd3de59 100644 --- a/alethzero/CMakeLists.txt +++ b/alethzero/CMakeLists.txt @@ -7,6 +7,11 @@ if (${CMAKE_MAJOR_VERSION} GREATER 2) cmake_policy(SET CMP0043 OLD) endif() +if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") + # Supress warnings for qt headers for clang+ccache + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-inconsistent-missing-override") +endif () + set(CMAKE_INCLUDE_CURRENT_DIR ON) aux_source_directory(. SRC_LIST) diff --git a/libethereum/TransactionQueue.h b/libethereum/TransactionQueue.h index 407250530..ad8bd4a87 100644 --- a/libethereum/TransactionQueue.h +++ b/libethereum/TransactionQueue.h @@ -89,7 +89,7 @@ private: struct UnverifiedTransaction { UnverifiedTransaction() {} - UnverifiedTransaction(bytesConstRef const& _t, h512 const& _nodeId): transaction(std::move(_t.toBytes())), nodeId(_nodeId) {} + UnverifiedTransaction(bytesConstRef const& _t, h512 const& _nodeId): transaction(_t.toBytes()), nodeId(_nodeId) {} UnverifiedTransaction(UnverifiedTransaction&& _t): transaction(std::move(_t.transaction)) {} UnverifiedTransaction& operator=(UnverifiedTransaction&& _other) { transaction = std::move(_other.transaction); nodeId = std::move(_other.nodeId); return *this; } diff --git a/mix/CMakeLists.txt b/mix/CMakeLists.txt index 6a434534f..01102ee53 100644 --- a/mix/CMakeLists.txt +++ b/mix/CMakeLists.txt @@ -15,6 +15,11 @@ include_directories(BEFORE ${JSONCPP_INCLUDE_DIRS}) include_directories(${Boost_INCLUDE_DIRS}) include_directories(BEFORE ..) +if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") + # Supress warnings for qt headers for clang+ccache + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-inconsistent-missing-override") +endif () + find_package (Qt5WebEngine QUIET) qt5_add_resources(UI_RESOURCES res.qrc qml.qrc) From 9d0ef73c8eb8560e7b3bcd696363d2a7841acfb9 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Tue, 7 Jul 2015 14:05:25 +0200 Subject: [PATCH 10/14] eth_getTransactionReceipt --- libethereum/BlockChain.h | 3 +++ libethereum/ClientBase.cpp | 5 ++++ libethereum/ClientBase.h | 1 + libethereum/Interface.h | 1 + libweb3jsonrpc/JsonHelper.cpp | 27 +++++++++++++++++++++ libweb3jsonrpc/JsonHelper.h | 3 +++ libweb3jsonrpc/WebThreeStubServerBase.cpp | 17 +++++++++++++ libweb3jsonrpc/WebThreeStubServerBase.h | 1 + libweb3jsonrpc/abstractwebthreestubserver.h | 6 +++++ libweb3jsonrpc/spec.json | 1 + test/libweb3jsonrpc/webthreestubclient.h | 10 ++++++++ 11 files changed, 75 insertions(+) diff --git a/libethereum/BlockChain.h b/libethereum/BlockChain.h index 5b3a43d68..4cffca2df 100644 --- a/libethereum/BlockChain.h +++ b/libethereum/BlockChain.h @@ -142,6 +142,9 @@ public: BlockReceipts receipts(h256 const& _hash) const { return queryExtras(_hash, m_receipts, x_receipts, NullBlockReceipts); } BlockReceipts receipts() const { return receipts(currentHash()); } + /// Get the transaction receipt by transaction hash. Thread-safe. + TransactionReceipt transactionReceipt(h256 const& _transactionHash) const {TransactionAddress ta = queryExtras(_transactionHash, m_transactionAddresses, x_transactionAddresses, NullTransactionAddress); if (!ta) return bytesConstRef(); return receipts(ta.blockHash).receipts[ta.index]; } + /// Get a list of transaction hashes for a given block. Thread-safe. TransactionHashes transactionHashes(h256 const& _hash) const { auto b = block(_hash); RLP rlp(b); h256s ret; for (auto t: rlp[1]) ret.push_back(sha3(t.data())); return ret; } TransactionHashes transactionHashes() const { return transactionHashes(currentHash()); } diff --git a/libethereum/ClientBase.cpp b/libethereum/ClientBase.cpp index 73404f83d..2cef62680 100644 --- a/libethereum/ClientBase.cpp +++ b/libethereum/ClientBase.cpp @@ -327,6 +327,11 @@ Transaction ClientBase::transaction(h256 _blockHash, unsigned _i) const return Transaction(); } +TransactionReceipt ClientBase::transactionReceipt(h256 const& _transactionHash) const +{ + return bc().transactionReceipt(_transactionHash); +} + pair ClientBase::transactionLocation(h256 const& _transactionHash) const { return bc().transactionLocation(_transactionHash); diff --git a/libethereum/ClientBase.h b/libethereum/ClientBase.h index f0e830d1d..05766b3a1 100644 --- a/libethereum/ClientBase.h +++ b/libethereum/ClientBase.h @@ -119,6 +119,7 @@ public: virtual BlockDetails blockDetails(h256 _hash) const override; virtual Transaction transaction(h256 _transactionHash) const override; virtual Transaction transaction(h256 _blockHash, unsigned _i) const override; + virtual TransactionReceipt transactionReceipt(h256 const& _transactionHash) const override; virtual std::pair transactionLocation(h256 const& _transactionHash) const override; virtual Transactions transactions(h256 _blockHash) const override; virtual TransactionHashes transactionHashes(h256 _blockHash) const override; diff --git a/libethereum/Interface.h b/libethereum/Interface.h index 0d40937b8..c65670a30 100644 --- a/libethereum/Interface.h +++ b/libethereum/Interface.h @@ -135,6 +135,7 @@ public: virtual bool isKnownTransaction(h256 const& _transactionHash) const = 0; virtual Transaction transaction(h256 _transactionHash) const = 0; + virtual TransactionReceipt transactionReceipt(h256 const& _transactionHash) const = 0; virtual std::pair transactionLocation(h256 const& _transactionHash) const = 0; virtual h256 hashFromNumber(BlockNumber _number) const = 0; virtual BlockNumber numberFromHash(h256 _blockHash) const = 0; diff --git a/libweb3jsonrpc/JsonHelper.cpp b/libweb3jsonrpc/JsonHelper.cpp index 39a856446..96312f625 100644 --- a/libweb3jsonrpc/JsonHelper.cpp +++ b/libweb3jsonrpc/JsonHelper.cpp @@ -182,6 +182,33 @@ Json::Value toJson(dev::eth::TransactionReceipt const& _t) return res; } +Json::Value toJson(dev::eth::TransactionReceipt const& _tr, std::pair _location, BlockNumber _blockNumber, Transaction const& _t) +{ + Json::Value res; + h256 h = _t.sha3(); + res["transactionHash"] = toJS(h); + res["transactionIndex"] = _location.second; + res["blockHash"] = toJS(_location.first); + res["blockNumber"] = _blockNumber; + res["cumulativeGasUsed"] = toJS(_tr.gasUsed()); // TODO: check if this is fine + res["gasUsed"] = toJS(_tr.gasUsed()); + res["contractAddress"] = toJS(toAddress(_t.from(), _t.nonce())); + res["logs"] = Json::Value(Json::arrayValue); + for (unsigned i = 0; i < _tr.log().size(); i++) + { + LogEntry e = _tr.log()[i]; + Json::Value l = toJson(e); + l["type"] = "mined"; + l["blockNumber"] = _blockNumber; + l["blockHash"] = toJS(_location.first); + l["logIndex"] = i; + l["transactionHash"] = toJS(h); + l["transactionIndex"] = _location.second; + res["logs"].append(l); + } + return res; +} + Json::Value toJson(dev::eth::Transaction const& _t) { Json::Value res; diff --git a/libweb3jsonrpc/JsonHelper.h b/libweb3jsonrpc/JsonHelper.h index dd868f8de..421d11b78 100644 --- a/libweb3jsonrpc/JsonHelper.h +++ b/libweb3jsonrpc/JsonHelper.h @@ -50,12 +50,15 @@ using UncleHashes = h256s; using TransactionHashes = h256s; Json::Value toJson(BlockInfo const& _bi); +//TODO: wrap these params into one structure eg. "LocalisedTransaction" Json::Value toJson(Transaction const& _t, std::pair _location, BlockNumber _blockNumber); Json::Value toJson(BlockInfo const& _bi, BlockDetails const& _bd, UncleHashes const& _us, Transactions const& _ts); Json::Value toJson(BlockInfo const& _bi, BlockDetails const& _bd, UncleHashes const& _us, TransactionHashes const& _ts); Json::Value toJson(TransactionSkeleton const& _t); Json::Value toJson(Transaction const& _t); Json::Value toJson(TransactionReceipt const& _t); +//TODO: wrap these params into one structure eg. "LocalisedTransactionReceipt" +Json::Value toJson(TransactionReceipt const& _tr, std::pair _location, BlockNumber _blockNumber, Transaction const& _t); Json::Value toJson(LocalisedLogEntry const& _e); Json::Value toJson(LogEntry const& _e); TransactionSkeleton toTransactionSkeleton(Json::Value const& _json); diff --git a/libweb3jsonrpc/WebThreeStubServerBase.cpp b/libweb3jsonrpc/WebThreeStubServerBase.cpp index fd0b4c514..166fbb1bb 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.cpp +++ b/libweb3jsonrpc/WebThreeStubServerBase.cpp @@ -419,6 +419,23 @@ Json::Value WebThreeStubServerBase::eth_getTransactionByBlockNumberAndIndex(stri } } +Json::Value WebThreeStubServerBase::eth_getTransactionReceipt(string const& _transactionHash) +{ + try + { + h256 h = jsToFixed<32>(_transactionHash); + if (!client()->isKnownTransaction(h)) + return Json::Value(Json::nullValue); + + auto l = client()->transactionLocation(h); + return toJson(client()->transactionReceipt(h), l, client()->numberFromHash(l.first), client()->transaction(h)); + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + } +} + Json::Value WebThreeStubServerBase::eth_getUncleByBlockHashAndIndex(string const& _blockHash, string const& _uncleIndex) { try diff --git a/libweb3jsonrpc/WebThreeStubServerBase.h b/libweb3jsonrpc/WebThreeStubServerBase.h index 94fbd1acb..d90015aec 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.h +++ b/libweb3jsonrpc/WebThreeStubServerBase.h @@ -119,6 +119,7 @@ public: virtual Json::Value eth_getTransactionByHash(std::string const& _transactionHash); virtual Json::Value eth_getTransactionByBlockHashAndIndex(std::string const& _blockHash, std::string const& _transactionIndex); virtual Json::Value eth_getTransactionByBlockNumberAndIndex(std::string const& _blockNumber, std::string const& _transactionIndex); + virtual Json::Value eth_getTransactionReceipt(std::string const& _transactionHash); virtual Json::Value eth_getUncleByBlockHashAndIndex(std::string const& _blockHash, std::string const& _uncleIndex); virtual Json::Value eth_getUncleByBlockNumberAndIndex(std::string const& _blockNumber, std::string const& _uncleIndex); virtual Json::Value eth_getCompilers(); diff --git a/libweb3jsonrpc/abstractwebthreestubserver.h b/libweb3jsonrpc/abstractwebthreestubserver.h index 6d0db7394..988271c95 100644 --- a/libweb3jsonrpc/abstractwebthreestubserver.h +++ b/libweb3jsonrpc/abstractwebthreestubserver.h @@ -40,6 +40,7 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServerbindAndAddMethod(jsonrpc::Procedure("eth_getTransactionByHash", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getTransactionByHashI); this->bindAndAddMethod(jsonrpc::Procedure("eth_getTransactionByBlockHashAndIndex", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getTransactionByBlockHashAndIndexI); this->bindAndAddMethod(jsonrpc::Procedure("eth_getTransactionByBlockNumberAndIndex", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getTransactionByBlockNumberAndIndexI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_getTransactionReceipt", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getTransactionReceiptI); this->bindAndAddMethod(jsonrpc::Procedure("eth_getUncleByBlockHashAndIndex", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getUncleByBlockHashAndIndexI); this->bindAndAddMethod(jsonrpc::Procedure("eth_getUncleByBlockNumberAndIndex", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getUncleByBlockNumberAndIndexI); this->bindAndAddMethod(jsonrpc::Procedure("eth_getCompilers", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, NULL), &AbstractWebThreeStubServer::eth_getCompilersI); @@ -224,6 +225,10 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServereth_getTransactionByBlockNumberAndIndex(request[0u].asString(), request[1u].asString()); } + inline virtual void eth_getTransactionReceiptI(const Json::Value &request, Json::Value &response) + { + response = this->eth_getTransactionReceipt(request[0u].asString()); + } inline virtual void eth_getUncleByBlockHashAndIndexI(const Json::Value &request, Json::Value &response) { response = this->eth_getUncleByBlockHashAndIndex(request[0u].asString(), request[1u].asString()); @@ -489,6 +494,7 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServerCallMethod("eth_getTransactionReceipt",p); + if (result.isObject()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } Json::Value eth_getUncleByBlockHashAndIndex(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) { Json::Value p; From ce935070406754ae1f351dd3beccba32c43e4f41 Mon Sep 17 00:00:00 2001 From: Dimitry Khokhlov Date: Thu, 2 Jul 2015 22:37:53 +0400 Subject: [PATCH 11/14] Issues: BlockChain::rebuild + byteRef test --- libethereum/BlockChain.cpp | 2 +- test/libdevcore/core.cpp | 41 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 test/libdevcore/core.cpp diff --git a/libethereum/BlockChain.cpp b/libethereum/BlockChain.cpp index d8dbd266f..be3449a60 100644 --- a/libethereum/BlockChain.cpp +++ b/libethereum/BlockChain.cpp @@ -273,7 +273,7 @@ void BlockChain::rebuild(std::string const& _path, std::function. +*/ +/** @file core.cpp + * @author Dimitry Khokhlov + * @date 2014 + * CORE test functions. + */ + +#include +#include +#include + +BOOST_AUTO_TEST_SUITE(CoreLibTests) + +BOOST_AUTO_TEST_CASE(byteRef) +{ + cnote << "bytesRef copyTo and toString..."; + dev::bytes originalSequence = dev::fromHex("0102030405060708091011121314151617181920212223242526272829303132"); + dev::bytesRef _out(&originalSequence.at(0), 32); + dev::h256 ret("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"); + ret.ref().copyTo(_out); + + BOOST_CHECK_MESSAGE(_out.size() == 32, "Error wrong result size when h256::ref().copyTo(dev::bytesRef out)"); + BOOST_CHECK_MESSAGE(_out.toBytes() == originalSequence, "Error when h256::ref().copyTo(dev::bytesRef out)"); +} + +BOOST_AUTO_TEST_SUITE_END() From 5a84977bf43c48f3f103010354966e80f8aa63a3 Mon Sep 17 00:00:00 2001 From: Dimitry Khokhlov Date: Tue, 7 Jul 2015 16:16:17 +0400 Subject: [PATCH 12/14] fix: style --- test/libdevcore/core.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/libdevcore/core.cpp b/test/libdevcore/core.cpp index 696983cf5..e7c7c86a1 100644 --- a/test/libdevcore/core.cpp +++ b/test/libdevcore/core.cpp @@ -30,12 +30,12 @@ BOOST_AUTO_TEST_CASE(byteRef) { cnote << "bytesRef copyTo and toString..."; dev::bytes originalSequence = dev::fromHex("0102030405060708091011121314151617181920212223242526272829303132"); - dev::bytesRef _out(&originalSequence.at(0), 32); - dev::h256 ret("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"); - ret.ref().copyTo(_out); + dev::bytesRef out(&originalSequence.at(0), 32); + dev::h256 hash32("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"); + hash32.ref().copyTo(out); - BOOST_CHECK_MESSAGE(_out.size() == 32, "Error wrong result size when h256::ref().copyTo(dev::bytesRef out)"); - BOOST_CHECK_MESSAGE(_out.toBytes() == originalSequence, "Error when h256::ref().copyTo(dev::bytesRef out)"); + BOOST_CHECK_MESSAGE(out.size() == 32, "Error wrong result size when h256::ref().copyTo(dev::bytesRef out)"); + BOOST_CHECK_MESSAGE(out.toBytes() == originalSequence, "Error when h256::ref().copyTo(dev::bytesRef out)"); } BOOST_AUTO_TEST_SUITE_END() From f8a4ca2a5c5adcdb42ad50ea8c5f0dc800208dbb Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Tue, 7 Jul 2015 16:32:02 +0200 Subject: [PATCH 13/14] Disable auto adjust of batch size by default After reports from many miners the whole auto adjusting idea may or may not work depending the user's hardware. A much safer default value is 0 (to disable auto adjustment) --- libethcore/Ethash.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libethcore/Ethash.cpp b/libethcore/Ethash.cpp index 3baac3292..9ec6dd71f 100644 --- a/libethcore/Ethash.cpp +++ b/libethcore/Ethash.cpp @@ -56,7 +56,7 @@ namespace eth const unsigned Ethash::defaultLocalWorkSize = 64; const unsigned Ethash::defaultGlobalWorkSizeMultiplier = 512; // * CL_DEFAULT_LOCAL_WORK_SIZE -const unsigned Ethash::defaultMSPerBatch = 100; +const unsigned Ethash::defaultMSPerBatch = 0; const Ethash::WorkPackage Ethash::NullWorkPackage = Ethash::WorkPackage(); std::string Ethash::name() From 6f2731d3f30b53ba28380dcf3ff3c19292e523ad Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 7 Jul 2015 16:36:49 +0200 Subject: [PATCH 14/14] Style. --- libdevcore/Base64.cpp | 43 ++++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/libdevcore/Base64.cpp b/libdevcore/Base64.cpp index f97c82156..8ee2b29f7 100644 --- a/libdevcore/Base64.cpp +++ b/libdevcore/Base64.cpp @@ -27,6 +27,8 @@ /// Originally by René Nyffenegger, modified by some other guy and then devified by Gav Wood. #include "Base64.h" + +using namespace std; using namespace dev; static inline bool is_base64(byte c) @@ -44,14 +46,14 @@ static inline byte find_base64_char_index(byte c) else return 1 + find_base64_char_index('/'); } -std::string dev::toBase64(bytesConstRef _in) +string dev::toBase64(bytesConstRef _in) { static const char base64_chars[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789+/"; + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; - std::string ret; + string ret; int i = 0; int j = 0; byte char_array_3[3]; @@ -60,15 +62,17 @@ std::string dev::toBase64(bytesConstRef _in) auto buf = _in.data(); auto bufLen = _in.size(); - while (bufLen--) { + while (bufLen--) + { char_array_3[i++] = *(buf++); - if (i == 3) { + if (i == 3) + { char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); char_array_4[3] = char_array_3[2] & 0x3f; - for(i = 0; (i <4) ; i++) + for (i = 0; i < 4; i++) ret += base64_chars[char_array_4[i]]; i = 0; } @@ -76,7 +80,7 @@ std::string dev::toBase64(bytesConstRef _in) if (i) { - for(j = i; j < 3; j++) + for (j = i; j < 3; j++) char_array_3[j] = '\0'; char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; @@ -84,28 +88,31 @@ std::string dev::toBase64(bytesConstRef _in) char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); char_array_4[3] = char_array_3[2] & 0x3f; - for (j = 0; (j < i + 1); j++) + for (j = 0; j < i + 1; j++) ret += base64_chars[char_array_4[j]]; - while((i++ < 3)) + while (i++ < 3) ret += '='; } return ret; } -bytes dev::fromBase64(std::string const& encoded_string) +bytes dev::fromBase64(string const& encoded_string) { auto in_len = encoded_string.size(); int i = 0; int j = 0; int in_ = 0; - byte char_array_4[4], char_array_3[3]; + byte char_array_3[3]; + byte char_array_4[4]; bytes ret; - while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) { + while (in_len-- && encoded_string[in_] != '=' && is_base64(encoded_string[in_])) + { char_array_4[i++] = encoded_string[in_]; in_++; - if (i == 4) { + if (i == 4) + { for (i = 0; i < 4; i++) char_array_4[i] = find_base64_char_index(char_array_4[i]); @@ -119,7 +126,8 @@ bytes dev::fromBase64(std::string const& encoded_string) } } - if (i) { + if (i) + { for (j = i; j < 4; j++) char_array_4[j] = 0; @@ -130,7 +138,8 @@ bytes dev::fromBase64(std::string const& encoded_string) char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; - for (j = 0; (j < i - 1); j++) ret.push_back(char_array_3[j]); + for (j = 0; j < i - 1; j++) + ret.push_back(char_array_3[j]); } return ret;