From 990e4e0d44c81b7d0b45892e19afa7e0f1a3460c Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Sun, 14 Jun 2015 05:42:47 +0200 Subject: [PATCH 01/23] log polarity --- libethereum/Client.cpp | 37 ++++++++++++++++++++++++------------- libethereum/Client.h | 11 ++++++++++- libevm/ExtVMFace.h | 6 ++++-- 3 files changed, 38 insertions(+), 16 deletions(-) diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index 9d2c9a9e6..e25eb0d03 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -480,7 +480,7 @@ void Client::appendFromNewPending(TransactionReceipt const& _receipt, h256Hash& } } -void Client::appendFromNewBlock(h256 const& _block, h256Hash& io_changed) +void Client::appendFromBlock(h256 const& _block, bool _polarity, h256Hash& io_changed) { // TODO: more precise check on whether the txs match. auto d = m_bc.info(_block); @@ -503,7 +503,7 @@ void Client::appendFromNewBlock(h256 const& _block, h256Hash& io_changed) auto transactionHash = transaction(d.hash(), j).sha3(); // filter catches them for (LogEntry const& l: m) - i.second.changes.push_back(LocalisedLogEntry(l, d, transactionHash, j, logIndex)); + i.second.changes.push_back(LocalisedLogEntry(l, d, transactionHash, j, logIndex, _polarity)); io_changed.insert(i.first); } } @@ -656,10 +656,10 @@ void Client::syncTransactionQueue() h->noteNewTransactions(); } -void Client::onChainChanged(ImportRoute const& _ir) +void Client::onDeadBlocks(h256s const& _blocks, h256Hash& io_changed) { // insert transactions that we are declaring the dead part of the chain - for (auto const& h: _ir.deadBlocks()) + for (auto const& h: _blocks) { clog(ClientNote) << "Dead block:" << h; for (auto const& t: m_bc.transactions(h)) @@ -669,8 +669,14 @@ void Client::onChainChanged(ImportRoute const& _ir) } } + for (auto const& h: _blocks) + appendFromBlock(h, false, io_changed); +} + +void Client::onNewBlocks(h256s const& _blocks, h256Hash& io_changed) +{ // remove transactions from m_tq nicely rather than relying on out of date nonce later on. - for (auto const& h: _ir.liveBlocks()) + for (auto const& h: _blocks) { clog(ClientChat) << "Live block:" << h; for (auto const& th: m_bc.transactionHashes(h)) @@ -683,12 +689,12 @@ void Client::onChainChanged(ImportRoute const& _ir) if (auto h = m_host.lock()) h->noteNewBlocks(); - h256Hash changeds; - for (auto const& h: _ir.liveBlocks()) - appendFromNewBlock(h, changeds); - - // RESTART MINING + for (auto const& h: _blocks) + appendFromBlock(h, true, io_changed); +} +void Client::restartMining() +{ bool preChanged = false; State newPreMine; DEV_READ_GUARDED(x_preMine) @@ -717,15 +723,20 @@ void Client::onChainChanged(ImportRoute const& _ir) DEV_READ_GUARDED(x_working) DEV_WRITE_GUARDED(x_postMine) m_postMine = m_working; - changeds.insert(PendingChangedFilter); - onPostStateChanged(); } +} + +void Client::onChainChanged(ImportRoute const& _ir) +{ + h256Hash changeds; + onDeadBlocks(_ir.deadBlocks(), changeds); + onNewBlocks(_ir.liveBlocks(), changeds); + restartMining(); // Quick hack for now - the TQ at this point already has the prior pending transactions in it; // we should resync with it manually until we are stricter about what constitutes "knowing". onTransactionQueueReady(); - noteChanged(changeds); } diff --git a/libethereum/Client.h b/libethereum/Client.h index cba93290b..13ef08b35 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -251,7 +251,7 @@ protected: /// Collate the changed filters for the hash of the given block. /// Insert any filters that are activated into @a o_changed. - void appendFromNewBlock(h256 const& _blockHash, h256Hash& io_changed); + void appendFromBlock(h256 const& _blockHash, bool _polarity, h256Hash& io_changed); /// Record that the set of filters @a _filters have changed. /// This doesn't actually make any callbacks, but incrememnts some counters in m_watches. @@ -270,6 +270,15 @@ private: /// Called when wouldMine(), turboMining(), isChainBad(), forceMining(), pendingTransactions() have changed. void rejigMining(); + /// Called on chain changes + void onDeadBlocks(h256s const& _blocks, h256Hash& io_changed); + + /// Called on chain changes + void onNewBlocks(h256s const& _blocks, h256Hash& io_changed); + + /// Called after processing blocks by onChainChanged(_ir) + void restartMining(); + /// Magically called when the chain has changed. An import route is provided. /// Called by either submitWork() or in our main thread through syncBlockQueue(). void onChainChanged(ImportRoute const& _ir); diff --git a/libevm/ExtVMFace.h b/libevm/ExtVMFace.h index 357292853..24c55d816 100644 --- a/libevm/ExtVMFace.h +++ b/libevm/ExtVMFace.h @@ -75,8 +75,9 @@ struct LocalisedLogEntry: public LogEntry BlockInfo const& _bi, h256 _th, unsigned _ti, - unsigned _li - ): LogEntry(_le), blockHash(_bi.hash()), blockNumber((BlockNumber)_bi.number), transactionHash(_th), transactionIndex(_ti), logIndex(_li), mined(true) {}; + unsigned _li, + bool _polarity = true + ): LogEntry(_le), blockHash(_bi.hash()), blockNumber((BlockNumber)_bi.number), transactionHash(_th), transactionIndex(_ti), logIndex(_li), mined(true), polarity(_polarity) {}; h256 blockHash = h256(); BlockNumber blockNumber = 0; @@ -84,6 +85,7 @@ struct LocalisedLogEntry: public LogEntry unsigned transactionIndex = 0; unsigned logIndex = 0; bool mined = false; + bool polarity = true; h256 special = h256(); }; From e08fb98a32f32a585d9867ef0f31234ddc176d5e Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Sun, 14 Jun 2015 07:06:13 +0200 Subject: [PATCH 02/23] merge fix --- libethereum/Client.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index 63633225f..7d967f669 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -741,6 +741,10 @@ void Client::restartMining() onPostStateChanged(); } + + // Quick hack for now - the TQ at this point already has the prior pending transactions in it; + // we should resync with it manually until we are stricter about what constitutes "knowing". + onTransactionQueueReady(); } } @@ -750,10 +754,6 @@ void Client::onChainChanged(ImportRoute const& _ir) onDeadBlocks(_ir.deadBlocks, changeds); onNewBlocks(_ir.liveBlocks, changeds); restartMining(); - - // Quick hack for now - the TQ at this point already has the prior pending transactions in it; - // we should resync with it manually until we are stricter about what constitutes "knowing". - onTransactionQueueReady(); noteChanged(changeds); } From f77325de18f040764ac35443d0b2452e7d1cfa86 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Sun, 14 Jun 2015 10:14:54 +0200 Subject: [PATCH 03/23] block polarity enum && jsonrpc field --- libethereum/BlockChain.h | 3 ++- libethereum/Client.cpp | 6 +++--- libethereum/Client.h | 2 +- libethereum/ClientBase.cpp | 2 +- libevm/ExtVMFace.h | 11 +++++++++-- libweb3jsonrpc/WebThreeStubServerBase.cpp | 3 +++ 6 files changed, 19 insertions(+), 8 deletions(-) diff --git a/libethereum/BlockChain.h b/libethereum/BlockChain.h index e3fcf83c1..2d3abd922 100644 --- a/libethereum/BlockChain.h +++ b/libethereum/BlockChain.h @@ -81,7 +81,8 @@ using BlocksHash = std::unordered_map; using TransactionHashes = h256s; using UncleHashes = h256s; -struct ImportRoute { +struct ImportRoute +{ h256s deadBlocks; h256s liveBlocks; }; diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index 7d967f669..ea144c307 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -480,7 +480,7 @@ void Client::appendFromNewPending(TransactionReceipt const& _receipt, h256Hash& } } -void Client::appendFromBlock(h256 const& _block, bool _polarity, h256Hash& io_changed) +void Client::appendFromBlock(h256 const& _block, BlockPolarity _polarity, h256Hash& io_changed) { // TODO: more precise check on whether the txs match. auto d = m_bc.info(_block); @@ -682,7 +682,7 @@ void Client::onDeadBlocks(h256s const& _blocks, h256Hash& io_changed) } for (auto const& h: _blocks) - appendFromBlock(h, false, io_changed); + appendFromBlock(h, BlockPolarity::Dead, io_changed); } void Client::onNewBlocks(h256s const& _blocks, h256Hash& io_changed) @@ -702,7 +702,7 @@ void Client::onNewBlocks(h256s const& _blocks, h256Hash& io_changed) h->noteNewBlocks(); for (auto const& h: _blocks) - appendFromBlock(h, true, io_changed); + appendFromBlock(h, BlockPolarity::Live, io_changed); } void Client::restartMining() diff --git a/libethereum/Client.h b/libethereum/Client.h index eb05983b2..e25e8e0e4 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -251,7 +251,7 @@ protected: /// Collate the changed filters for the hash of the given block. /// Insert any filters that are activated into @a o_changed. - void appendFromBlock(h256 const& _blockHash, bool _polarity, h256Hash& io_changed); + void appendFromBlock(h256 const& _blockHash, BlockPolarity _polarity, h256Hash& io_changed); /// Record that the set of filters @a _filters have changed. /// This doesn't actually make any callbacks, but incrememnts some counters in m_watches. diff --git a/libethereum/ClientBase.cpp b/libethereum/ClientBase.cpp index d5bc0dbb9..2b25599cb 100644 --- a/libethereum/ClientBase.cpp +++ b/libethereum/ClientBase.cpp @@ -217,7 +217,7 @@ LocalisedLogEntries ClientBase::logs(LogFilter const& _f) const { total += le.size(); for (unsigned j = 0; j < le.size(); ++j) - ret.insert(ret.begin(), LocalisedLogEntry(le[j], info, th, i, logIndex)); + ret.insert(ret.begin(), LocalisedLogEntry(le[j], info, th, i, logIndex, BlockPolarity::Live)); } } diff --git a/libevm/ExtVMFace.h b/libevm/ExtVMFace.h index 24c55d816..2d65631e0 100644 --- a/libevm/ExtVMFace.h +++ b/libevm/ExtVMFace.h @@ -36,6 +36,13 @@ namespace dev namespace eth { +enum class BlockPolarity +{ + Unknown, + Dead, + Live +}; + struct LogEntry { LogEntry() {} @@ -76,7 +83,7 @@ struct LocalisedLogEntry: public LogEntry h256 _th, unsigned _ti, unsigned _li, - bool _polarity = true + BlockPolarity _polarity = BlockPolarity::Unknown ): LogEntry(_le), blockHash(_bi.hash()), blockNumber((BlockNumber)_bi.number), transactionHash(_th), transactionIndex(_ti), logIndex(_li), mined(true), polarity(_polarity) {}; h256 blockHash = h256(); @@ -85,7 +92,7 @@ struct LocalisedLogEntry: public LogEntry unsigned transactionIndex = 0; unsigned logIndex = 0; bool mined = false; - bool polarity = true; + BlockPolarity polarity = BlockPolarity::Unknown; h256 special = h256(); }; diff --git a/libweb3jsonrpc/WebThreeStubServerBase.cpp b/libweb3jsonrpc/WebThreeStubServerBase.cpp index f88443ee5..5bdd98e87 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.cpp +++ b/libweb3jsonrpc/WebThreeStubServerBase.cpp @@ -169,8 +169,11 @@ static Json::Value toJson(dev::eth::LocalisedLogEntry const& _e) res["data"] = toJS(_e.data); res["address"] = toJS(_e.address); res["topics"] = Json::Value(Json::arrayValue); + res["polarity"] = _e.polarity == BlockPolarity::Live ? true : false; + for (auto const& t: _e.topics) res["topics"].append(toJS(t)); + if (_e.mined) { res["type"] = "mined"; From d79569fb634c2d3340530c997c6cb733b949f4c7 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Mon, 15 Jun 2015 04:24:50 +0200 Subject: [PATCH 04/23] eth_getFilterChangesEx, eth_getFilterLogsEx returns json in proper format --- libweb3jsonrpc/WebThreeStubServerBase.cpp | 54 ++++++++++++++++++++++- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/libweb3jsonrpc/WebThreeStubServerBase.cpp b/libweb3jsonrpc/WebThreeStubServerBase.cpp index 5bdd98e87..54568672e 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.cpp +++ b/libweb3jsonrpc/WebThreeStubServerBase.cpp @@ -198,6 +198,56 @@ static Json::Value toJson(dev::eth::LocalisedLogEntry const& _e) return res; } +static Json::Value toJsonEx(dev::eth::LocalisedLogEntries const& _es) +{ + map entriesByBlock; + + for (dev::eth::LocalisedLogEntry const& e: _es) + { + if (e.topics.size() == 0) // skip special log + continue; + + if (entriesByBlock.count(e.blockHash) == 0) + entriesByBlock[e.blockHash] = LocalisedLogEntries(); + + entriesByBlock[e.blockHash].push_back(e); + } + + Json::Value res(Json::arrayValue); + for (auto const& i: entriesByBlock) + { + Json::Value currentBlock(Json::objectValue); + LocalisedLogEntry entry = i.second[0]; + if (entry.mined) + { + + currentBlock["blockNumber"] = entry.blockNumber; + currentBlock["blockHash"] = toJS(entry.blockHash); + currentBlock["type"] = "mined"; + } + else + currentBlock["type"] = "pending"; + + currentBlock["logs"] = Json::Value(Json::arrayValue); + + for (LocalisedLogEntry const& e: i.second) + { + Json::Value log(Json::objectValue); + log["logIndex"] = e.logIndex; + log["polarity"] = e.polarity == BlockPolarity::Live ? true : false; + log["transactionIndex"] = e.transactionIndex; + log["transactionHash"] = toJS(e.transactionHash); + log["address"] = toJS(e.address); + log["data"] = toJS(e.data); + log["topics"] = toJS(e.topics); + + currentBlock["logs"].append(log); + } + + res.append(currentBlock); + } +} + static Json::Value toJson(dev::eth::LocalisedLogEntries const& _es) { Json::Value res(Json::arrayValue); @@ -1001,7 +1051,7 @@ Json::Value WebThreeStubServerBase::eth_getFilterChangesEx(string const& _filter auto entries = client()->checkWatch(id); if (entries.size()) cnote << "FIRING WATCH" << id << entries.size(); - return toJson(entries); + return toJsonEx(entries); } catch (...) { @@ -1025,7 +1075,7 @@ Json::Value WebThreeStubServerBase::eth_getFilterLogsEx(string const& _filterId) { try { - return toJson(client()->logs(jsToInt(_filterId))); + return toJsonEx(client()->logs(jsToInt(_filterId))); } catch (...) { From 7355368df1a3acd6c250f61c877d10eb4fec3f5d Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Mon, 15 Jun 2015 04:50:26 +0200 Subject: [PATCH 05/23] missing return in toJsonEx --- libweb3jsonrpc/WebThreeStubServerBase.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libweb3jsonrpc/WebThreeStubServerBase.cpp b/libweb3jsonrpc/WebThreeStubServerBase.cpp index 54568672e..f750ea692 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.cpp +++ b/libweb3jsonrpc/WebThreeStubServerBase.cpp @@ -246,6 +246,8 @@ static Json::Value toJsonEx(dev::eth::LocalisedLogEntries const& _es) res.append(currentBlock); } + + return res; } static Json::Value toJson(dev::eth::LocalisedLogEntries const& _es) From e98317f2dd44389ee0d716f079a75a68f6a5affa Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 24 Jun 2015 23:07:05 +0200 Subject: [PATCH 06/23] blockchain isKnown block / transaction --- libethereum/BlockChain.h | 3 +++ libethereum/ClientBase.cpp | 16 ++++++++++++++++ libethereum/ClientBase.h | 4 ++++ libethereum/Interface.h | 3 +++ libweb3jsonrpc/WebThreeStubServerBase.cpp | 14 ++++++++++---- libweb3jsonrpc/WebThreeStubServerBase.h | 4 ++-- libweb3jsonrpc/abstractwebthreestubserver.h | 8 ++++---- libweb3jsonrpc/spec.json | 4 ++-- test/libweb3jsonrpc/webthreestubclient.h | 12 ++++++------ 9 files changed, 50 insertions(+), 18 deletions(-) diff --git a/libethereum/BlockChain.h b/libethereum/BlockChain.h index fc56c46b6..e97a0e7a3 100644 --- a/libethereum/BlockChain.h +++ b/libethereum/BlockChain.h @@ -184,6 +184,9 @@ public: std::vector withBlockBloom(LogBloom const& _b, unsigned _earliest, unsigned _latest) const; std::vector withBlockBloom(LogBloom const& _b, unsigned _earliest, unsigned _latest, unsigned _topLevel, unsigned _index) const; + /// Returns true if transaction is known. Thread-safe + bool isKnownTransaction(h256 const& _transactionHash) const { TransactionAddress ta = queryExtras(_transactionHash, m_transactionAddresses, x_transactionAddresses, NullTransactionAddress); return !!ta; } + /// Get a transaction from its hash. Thread-safe. bytes transaction(h256 const& _transactionHash) const { TransactionAddress ta = queryExtras(_transactionHash, m_transactionAddresses, x_transactionAddresses, NullTransactionAddress); if (!ta) return bytes(); return transaction(ta.blockHash, ta.index); } std::pair transactionLocation(h256 const& _transactionHash) const { TransactionAddress ta = queryExtras(_transactionHash, m_transactionAddresses, x_transactionAddresses, NullTransactionAddress); if (!ta) return std::pair(h256(), 0); return std::make_pair(ta.blockHash, ta.index); } diff --git a/libethereum/ClientBase.cpp b/libethereum/ClientBase.cpp index 2b25599cb..823bc6b35 100644 --- a/libethereum/ClientBase.cpp +++ b/libethereum/ClientBase.cpp @@ -467,3 +467,19 @@ int ClientBase::compareBlockHashes(h256 _h1, h256 _h2) const } return -1; } + +bool ClientBase::isKnown(h256 _hash) const +{ + return bc().isKnown(_hash); +} + +bool ClientBase::isKnown(BlockNumber _block) const +{ + return bc().numberHash(_block) != h256(); +} + +bool ClientBase::isKnownTransaction(h256 _transactionHash) const +{ + return bc().isKnownTransaction(_transactionHash); +} + diff --git a/libethereum/ClientBase.h b/libethereum/ClientBase.h index 8aa84101c..e46bfe24d 100644 --- a/libethereum/ClientBase.h +++ b/libethereum/ClientBase.h @@ -148,6 +148,10 @@ public: /// Get the coinbase address virtual Address address() const override; + virtual bool isKnown(h256 _hash) const override; + virtual bool isKnown(BlockNumber _block) const override; + virtual bool isKnownTransaction(h256 _transactionHash) const override; + /// TODO: consider moving it to a separate interface virtual void startMining() override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("ClientBase::startMining")); } diff --git a/libethereum/Interface.h b/libethereum/Interface.h index f631fb43e..204ce7dec 100644 --- a/libethereum/Interface.h +++ b/libethereum/Interface.h @@ -133,12 +133,15 @@ public: // [BLOCK QUERY API] + virtual bool isKnownTransaction(h256 _transactionHash) const = 0; virtual Transaction transaction(h256 _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; virtual int compareBlockHashes(h256 _h1, h256 _h2) const = 0; + virtual bool isKnown(BlockNumber _block) const = 0; + virtual bool isKnown(h256 _hash) const = 0; virtual BlockInfo blockInfo(h256 _hash) const = 0; virtual BlockDetails blockDetails(h256 _hash) const = 0; virtual Transaction transaction(h256 _blockHash, unsigned _i) const = 0; diff --git a/libweb3jsonrpc/WebThreeStubServerBase.cpp b/libweb3jsonrpc/WebThreeStubServerBase.cpp index 0be37b6c6..b92b7ffc1 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.cpp +++ b/libweb3jsonrpc/WebThreeStubServerBase.cpp @@ -186,11 +186,14 @@ string WebThreeStubServerBase::eth_getBlockTransactionCountByNumber(string const } } -string WebThreeStubServerBase::eth_getUncleCountByBlockHash(string const& _blockHash) +Json::Value WebThreeStubServerBase::eth_getUncleCountByBlockHash(string const& _blockHash) { try { - return toJS(client()->uncleCount(jsToFixed<32>(_blockHash))); + h256 blockHash = jsToFixed<32>(_blockHash); + if (!client()->isKnown(blockHash)) + return Json::Value(Json::nullValue); + return toJS(client()->uncleCount(blockHash)); } catch (...) { @@ -198,11 +201,14 @@ string WebThreeStubServerBase::eth_getUncleCountByBlockHash(string const& _block } } -string WebThreeStubServerBase::eth_getUncleCountByBlockNumber(string const& _blockNumber) +Json::Value WebThreeStubServerBase::eth_getUncleCountByBlockNumber(string const& _blockNumber) { try { - return toJS(client()->uncleCount(jsToBlockNumber(_blockNumber))); + BlockNumber blockNumber = jsToBlockNumber(_blockNumber); + if (!client()->isKnown(blockNumber)) + return Json::Value(Json::nullValue); + return toJS(client()->uncleCount(blockNumber)); } catch (...) { diff --git a/libweb3jsonrpc/WebThreeStubServerBase.h b/libweb3jsonrpc/WebThreeStubServerBase.h index d3e16d0f4..8e3de4c17 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.h +++ b/libweb3jsonrpc/WebThreeStubServerBase.h @@ -108,8 +108,8 @@ public: virtual std::string eth_getTransactionCount(std::string const& _address, std::string const& _blockNumber); virtual std::string eth_getBlockTransactionCountByHash(std::string const& _blockHash); virtual std::string eth_getBlockTransactionCountByNumber(std::string const& _blockNumber); - virtual std::string eth_getUncleCountByBlockHash(std::string const& _blockHash); - virtual std::string eth_getUncleCountByBlockNumber(std::string const& _blockNumber); + virtual Json::Value eth_getUncleCountByBlockHash(std::string const& _blockHash); + virtual Json::Value eth_getUncleCountByBlockNumber(std::string const& _blockNumber); virtual std::string eth_getCode(std::string const& _address, std::string const& _blockNumber); virtual std::string eth_sendTransaction(Json::Value const& _json); virtual std::string eth_call(Json::Value const& _json, std::string const& _blockNumber); diff --git a/libweb3jsonrpc/abstractwebthreestubserver.h b/libweb3jsonrpc/abstractwebthreestubserver.h index 82864a61a..20a248985 100644 --- a/libweb3jsonrpc/abstractwebthreestubserver.h +++ b/libweb3jsonrpc/abstractwebthreestubserver.h @@ -29,8 +29,8 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServerbindAndAddMethod(jsonrpc::Procedure("eth_getTransactionCount", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getTransactionCountI); this->bindAndAddMethod(jsonrpc::Procedure("eth_getBlockTransactionCountByHash", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getBlockTransactionCountByHashI); this->bindAndAddMethod(jsonrpc::Procedure("eth_getBlockTransactionCountByNumber", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getBlockTransactionCountByNumberI); - this->bindAndAddMethod(jsonrpc::Procedure("eth_getUncleCountByBlockHash", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getUncleCountByBlockHashI); - this->bindAndAddMethod(jsonrpc::Procedure("eth_getUncleCountByBlockNumber", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getUncleCountByBlockNumberI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_getUncleCountByBlockHash", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getUncleCountByBlockHashI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_getUncleCountByBlockNumber", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getUncleCountByBlockNumberI); this->bindAndAddMethod(jsonrpc::Procedure("eth_getCode", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getCodeI); this->bindAndAddMethod(jsonrpc::Procedure("eth_sendTransaction", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::eth_sendTransactionI); this->bindAndAddMethod(jsonrpc::Procedure("eth_call", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_OBJECT,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_callI); @@ -478,8 +478,8 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServerCallMethod("eth_getUncleCountByBlockHash",p); - if (result.isString()) - return result.asString(); + if (result.isObject()) + return result; else throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - std::string eth_getUncleCountByBlockNumber(const std::string& param1) throw (jsonrpc::JsonRpcException) + Json::Value eth_getUncleCountByBlockNumber(const std::string& param1) throw (jsonrpc::JsonRpcException) { Json::Value p; p.append(param1); Json::Value result = this->CallMethod("eth_getUncleCountByBlockNumber",p); - if (result.isString()) - return result.asString(); + if (result.isObject()) + return result; else throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } From 0c239358775c0a06dc8bae237ac75f26a0dcada1 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 24 Jun 2015 23:25:13 +0200 Subject: [PATCH 07/23] getBlockBy** and getBlockTransactionCountBy** return null if block is not found --- libethereum/ClientBase.cpp | 9 +++++-- libweb3jsonrpc/WebThreeStubServerBase.cpp | 26 +++++++++++++++++---- libweb3jsonrpc/WebThreeStubServerBase.h | 4 ++-- libweb3jsonrpc/abstractwebthreestubserver.h | 8 +++---- libweb3jsonrpc/spec.json | 4 ++-- test/libweb3jsonrpc/webthreestubclient.h | 12 +++++----- 6 files changed, 42 insertions(+), 21 deletions(-) diff --git a/libethereum/ClientBase.cpp b/libethereum/ClientBase.cpp index 823bc6b35..5f10267a6 100644 --- a/libethereum/ClientBase.cpp +++ b/libethereum/ClientBase.cpp @@ -470,12 +470,17 @@ int ClientBase::compareBlockHashes(h256 _h1, h256 _h2) const bool ClientBase::isKnown(h256 _hash) const { - return bc().isKnown(_hash); + return _hash == PendingBlockHash || + _hash == LatestBlockHash || + _hash == EarliestBlockHash || + bc().isKnown(_hash); } bool ClientBase::isKnown(BlockNumber _block) const { - return bc().numberHash(_block) != h256(); + return _block == PendingBlock || + _block == LatestBlock || + bc().numberHash(_block) != h256(); } bool ClientBase::isKnownTransaction(h256 _transactionHash) const diff --git a/libweb3jsonrpc/WebThreeStubServerBase.cpp b/libweb3jsonrpc/WebThreeStubServerBase.cpp index b92b7ffc1..fd740c74e 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.cpp +++ b/libweb3jsonrpc/WebThreeStubServerBase.cpp @@ -162,11 +162,15 @@ string WebThreeStubServerBase::eth_getTransactionCount(string const& _address, s } } -string WebThreeStubServerBase::eth_getBlockTransactionCountByHash(string const& _blockHash) +Json::Value WebThreeStubServerBase::eth_getBlockTransactionCountByHash(string const& _blockHash) { try { - return toJS(client()->transactionCount(jsToFixed<32>(_blockHash))); + h256 blockHash = jsToFixed<32>(_blockHash); + if (!client()->isKnown(blockHash)) + return Json::Value(Json::nullValue); + + return toJS(client()->transactionCount(blockHash)); } catch (...) { @@ -174,10 +178,14 @@ string WebThreeStubServerBase::eth_getBlockTransactionCountByHash(string const& } } -string WebThreeStubServerBase::eth_getBlockTransactionCountByNumber(string const& _blockNumber) +Json::Value WebThreeStubServerBase::eth_getBlockTransactionCountByNumber(string const& _blockNumber) { try { + BlockNumber blockNumber = jsToBlockNumber(_blockNumber); + if (!client()->isKnown(blockNumber)) + return Json::Value(Json::nullValue); + return toJS(client()->transactionCount(jsToBlockNumber(_blockNumber))); } catch (...) @@ -193,6 +201,7 @@ Json::Value WebThreeStubServerBase::eth_getUncleCountByBlockHash(string const& _ h256 blockHash = jsToFixed<32>(_blockHash); if (!client()->isKnown(blockHash)) return Json::Value(Json::nullValue); + return toJS(client()->uncleCount(blockHash)); } catch (...) @@ -208,6 +217,7 @@ Json::Value WebThreeStubServerBase::eth_getUncleCountByBlockNumber(string const& BlockNumber blockNumber = jsToBlockNumber(_blockNumber); if (!client()->isKnown(blockNumber)) return Json::Value(Json::nullValue); + return toJS(client()->uncleCount(blockNumber)); } catch (...) @@ -336,7 +346,10 @@ Json::Value WebThreeStubServerBase::eth_getBlockByHash(string const& _blockHash, { try { - auto h = jsToFixed<32>(_blockHash); + h256 h = jsToFixed<32>(_blockHash); + if (!client()->isKnown(h)) + return Json::Value(Json::nullValue); + if (_includeTransactions) return toJson(client()->blockInfo(h), client()->blockDetails(h), client()->uncleHashes(h), client()->transactions(h)); else @@ -352,7 +365,10 @@ Json::Value WebThreeStubServerBase::eth_getBlockByNumber(string const& _blockNum { try { - auto h = jsToBlockNumber(_blockNumber); + BlockNumber h = jsToBlockNumber(_blockNumber); + if (!client()->isKnown(h)) + return Json::Value(Json::nullValue); + if (_includeTransactions) return toJson(client()->blockInfo(h), client()->blockDetails(h), client()->uncleHashes(h), client()->transactions(h)); else diff --git a/libweb3jsonrpc/WebThreeStubServerBase.h b/libweb3jsonrpc/WebThreeStubServerBase.h index 8e3de4c17..94fbd1acb 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.h +++ b/libweb3jsonrpc/WebThreeStubServerBase.h @@ -106,8 +106,8 @@ public: virtual std::string eth_getBalance(std::string const& _address, std::string const& _blockNumber); virtual std::string eth_getStorageAt(std::string const& _address, std::string const& _position, std::string const& _blockNumber); virtual std::string eth_getTransactionCount(std::string const& _address, std::string const& _blockNumber); - virtual std::string eth_getBlockTransactionCountByHash(std::string const& _blockHash); - virtual std::string eth_getBlockTransactionCountByNumber(std::string const& _blockNumber); + virtual Json::Value eth_getBlockTransactionCountByHash(std::string const& _blockHash); + virtual Json::Value eth_getBlockTransactionCountByNumber(std::string const& _blockNumber); virtual Json::Value eth_getUncleCountByBlockHash(std::string const& _blockHash); virtual Json::Value eth_getUncleCountByBlockNumber(std::string const& _blockNumber); virtual std::string eth_getCode(std::string const& _address, std::string const& _blockNumber); diff --git a/libweb3jsonrpc/abstractwebthreestubserver.h b/libweb3jsonrpc/abstractwebthreestubserver.h index 20a248985..6d0db7394 100644 --- a/libweb3jsonrpc/abstractwebthreestubserver.h +++ b/libweb3jsonrpc/abstractwebthreestubserver.h @@ -27,8 +27,8 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServerbindAndAddMethod(jsonrpc::Procedure("eth_getBalance", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getBalanceI); this->bindAndAddMethod(jsonrpc::Procedure("eth_getStorageAt", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING,"param3",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getStorageAtI); this->bindAndAddMethod(jsonrpc::Procedure("eth_getTransactionCount", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getTransactionCountI); - this->bindAndAddMethod(jsonrpc::Procedure("eth_getBlockTransactionCountByHash", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getBlockTransactionCountByHashI); - this->bindAndAddMethod(jsonrpc::Procedure("eth_getBlockTransactionCountByNumber", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getBlockTransactionCountByNumberI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_getBlockTransactionCountByHash", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getBlockTransactionCountByHashI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_getBlockTransactionCountByNumber", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getBlockTransactionCountByNumberI); this->bindAndAddMethod(jsonrpc::Procedure("eth_getUncleCountByBlockHash", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getUncleCountByBlockHashI); this->bindAndAddMethod(jsonrpc::Procedure("eth_getUncleCountByBlockNumber", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getUncleCountByBlockNumberI); this->bindAndAddMethod(jsonrpc::Procedure("eth_getCode", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getCodeI); @@ -476,8 +476,8 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServerCallMethod("eth_getBlockTransactionCountByHash",p); - if (result.isString()) - return result.asString(); + if (result.isObject()) + return result; else throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - std::string eth_getBlockTransactionCountByNumber(const std::string& param1) throw (jsonrpc::JsonRpcException) + Json::Value eth_getBlockTransactionCountByNumber(const std::string& param1) throw (jsonrpc::JsonRpcException) { Json::Value p; p.append(param1); Json::Value result = this->CallMethod("eth_getBlockTransactionCountByNumber",p); - if (result.isString()) - return result.asString(); + if (result.isObject()) + return result; else throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } From 69230c59b7030ef28970618895ffd4dd0d0b648a Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Thu, 25 Jun 2015 09:51:22 +0200 Subject: [PATCH 08/23] fixed getting transaction by blockNumber and index --- libethereum/Interface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libethereum/Interface.h b/libethereum/Interface.h index 204ce7dec..1073b45ff 100644 --- a/libethereum/Interface.h +++ b/libethereum/Interface.h @@ -154,7 +154,7 @@ public: BlockInfo blockInfo(BlockNumber _block) const { return blockInfo(hashFromNumber(_block)); } BlockDetails blockDetails(BlockNumber _block) const { return blockDetails(hashFromNumber(_block)); } - Transaction transaction(BlockNumber _block, unsigned _i) const { if (_block == PendingBlock) { auto p = pending(); return _i < p.size() ? p[_i] : Transaction(); } return transaction(hashFromNumber(_block)); } + Transaction transaction(BlockNumber _block, unsigned _i) const { auto p = transactions(_block); return _i < p.size() ? p[_i] : Transaction(); } unsigned transactionCount(BlockNumber _block) const { if (_block == PendingBlock) { auto p = pending(); return p.size(); } return transactionCount(hashFromNumber(_block)); } Transactions transactions(BlockNumber _block) const { if (_block == PendingBlock) return pending(); return transactions(hashFromNumber(_block)); } TransactionHashes transactionHashes(BlockNumber _block) const { if (_block == PendingBlock) return pendingHashes(); return transactionHashes(hashFromNumber(_block)); } From 51c705e3d398d0bf62ed1583297f70f306a87c84 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Thu, 25 Jun 2015 10:08:01 +0200 Subject: [PATCH 09/23] fixed eth_getTransactionByHash when transactionHash is unknown --- libweb3jsonrpc/WebThreeStubServerBase.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libweb3jsonrpc/WebThreeStubServerBase.cpp b/libweb3jsonrpc/WebThreeStubServerBase.cpp index fd740c74e..bbf8ec225 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.cpp +++ b/libweb3jsonrpc/WebThreeStubServerBase.cpp @@ -385,6 +385,9 @@ Json::Value WebThreeStubServerBase::eth_getTransactionByHash(string const& _tran try { h256 h = jsToFixed<32>(_transactionHash); + if (!client()->isKnownTransaction(h)) + return Json::Value(Json::nullValue); + auto l = client()->transactionLocation(h); return toJson(client()->transaction(h), l, client()->numberFromHash(l.first)); } From 5c64ba8aae74722d95a961c9092253ec20c87c35 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Thu, 25 Jun 2015 11:19:16 +0200 Subject: [PATCH 10/23] fixed encoding unformatted data in eth_getStorageAt --- libweb3jsonrpc/WebThreeStubServerBase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libweb3jsonrpc/WebThreeStubServerBase.cpp b/libweb3jsonrpc/WebThreeStubServerBase.cpp index bbf8ec225..4e4d42469 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.cpp +++ b/libweb3jsonrpc/WebThreeStubServerBase.cpp @@ -142,7 +142,7 @@ string WebThreeStubServerBase::eth_getStorageAt(string const& _address, string c { try { - return toJS(client()->stateAt(jsToAddress(_address), jsToU256(_position), jsToBlockNumber(_blockNumber))); + return toJS(toCompactBigEndian(client()->stateAt(jsToAddress(_address), jsToU256(_position), jsToBlockNumber(_blockNumber)), 1)); } catch (...) { From 4ec30f961e438417f813fa3874ceb83542730207 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Tue, 7 Jul 2015 18:57:39 +0200 Subject: [PATCH 11/23] LocalisedTransaction && LocalisedTransactionReceipt --- libethereum/Client.cpp | 2 +- libethereum/ClientBase.cpp | 2 +- libethereum/Transaction.h | 24 ++++++++++++++++ libethereum/TransactionReceipt.h | 48 ++++++++++++++++++++++++++++++++ libevm/ExtVMFace.h | 19 +++++++------ 5 files changed, 84 insertions(+), 11 deletions(-) diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index fba8d51fa..db4578285 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -429,7 +429,7 @@ void Client::appendFromNewBlock(h256 const& _block, h256Hash& io_changed) auto transactionHash = transaction(d.hash(), j).sha3(); // filter catches them for (LogEntry const& l: m) - i.second.changes.push_back(LocalisedLogEntry(l, d, transactionHash, j, logIndex)); + i.second.changes.push_back(LocalisedLogEntry(l, d.hash(), (BlockNumber)d.number, transactionHash, j, logIndex)); io_changed.insert(i.first); } } diff --git a/libethereum/ClientBase.cpp b/libethereum/ClientBase.cpp index 2cef62680..6483f6c0c 100644 --- a/libethereum/ClientBase.cpp +++ b/libethereum/ClientBase.cpp @@ -203,7 +203,7 @@ LocalisedLogEntries ClientBase::logs(LogFilter const& _f) const { total += le.size(); for (unsigned j = 0; j < le.size(); ++j) - ret.insert(ret.begin(), LocalisedLogEntry(le[j], info, th, i, logIndex)); + ret.insert(ret.begin(), LocalisedLogEntry(le[j], info.hash(), (BlockNumber)info.number, th, i, logIndex)); } } diff --git a/libethereum/Transaction.h b/libethereum/Transaction.h index 8ed0043c9..d29e9837e 100644 --- a/libethereum/Transaction.h +++ b/libethereum/Transaction.h @@ -130,5 +130,29 @@ private: /// Nice name for vector of Transaction. using Transactions = std::vector; +class LocalisedTransaction: public Transaction +{ +public: + LocalisedTransaction( + Transaction const& _t, + std::pair const& _location, + BlockNumber _blockNumber + ): + Transaction(_t), + m_blockHash(_location.first), + m_blockNumber(_blockNumber), + m_transactionIndex(_location.second) + {} + + h256 const& blockHash() const { return m_blockHash; } + BlockNumber blockNumber() const { return m_blockNumber; } + unsigned transactionIndex() const { return m_transactionIndex; } + +private: + h256 m_blockHash; + BlockNumber m_blockNumber; + unsigned m_transactionIndex; +}; + } } diff --git a/libethereum/TransactionReceipt.h b/libethereum/TransactionReceipt.h index 0a0b154f4..8c102611a 100644 --- a/libethereum/TransactionReceipt.h +++ b/libethereum/TransactionReceipt.h @@ -58,5 +58,53 @@ using TransactionReceipts = std::vector; std::ostream& operator<<(std::ostream& _out, eth::TransactionReceipt const& _r); +class LocalisedTransactionReceipt: public TransactionReceipt +{ +public: + LocalisedTransactionReceipt( + TransactionReceipt const& _t, + h256 const& _hash, + h256 const& _blockHash, + BlockNumber _blockNumber, + unsigned _transactionIndex, + Address const& _contractAddress = Address() + ): + TransactionReceipt(_t), + m_hash(_hash), + m_blockHash(_blockHash), + m_blockNumber(_blockNumber), + m_transactionIndex(_transactionIndex), + m_contractAddress(_contractAddress) + {} + + h256 const& hash() const { return m_hash; } + h256 const& blockHash() const { return m_blockHash; } + BlockNumber blockNumber() const { return m_blockNumber; } + unsigned transactionIndex() const { return m_transactionIndex; } + Address const& contractAddress() const { return m_contractAddress; } + + LocalisedLogEntries localisedLogs() const + { + LocalisedLogEntries localisedEntries; + LogEntries entries = log(); + for (unsigned i = 0; i < entries.size(); i++) + localisedEntries.push_back(LocalisedLogEntry( + entries[i], + m_blockHash, + m_blockNumber, + m_hash, + m_transactionIndex, + i)); + return localisedEntries; + }; + +private: + h256 m_hash; + h256 m_blockHash; + BlockNumber m_blockNumber; + unsigned m_transactionIndex; + Address m_contractAddress; +}; + } } diff --git a/libevm/ExtVMFace.h b/libevm/ExtVMFace.h index 94c8e2fef..6b40b4101 100644 --- a/libevm/ExtVMFace.h +++ b/libevm/ExtVMFace.h @@ -76,17 +76,18 @@ struct LocalisedLogEntry: public LogEntry explicit LocalisedLogEntry( LogEntry const& _le, - BlockInfo const& _bi, - h256 _th, - unsigned _ti, - unsigned _li + h256 const& _blockHash, + BlockNumber _blockNumber, + h256 const& _transactionHash, + unsigned _transactionIndex, + unsigned _logIndex ): LogEntry(_le), - blockHash(_bi.hash()), - blockNumber((BlockNumber)_bi.number), - transactionHash(_th), - transactionIndex(_ti), - logIndex(_li), + blockHash(_blockHash), + blockNumber(_blockNumber), + transactionHash(_transactionHash), + transactionIndex(_transactionIndex), + logIndex(_logIndex), mined(true) {} From e961867fdfa87ac78f1e69ad76768b5741a29f35 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 8 Jul 2015 10:09:29 +0200 Subject: [PATCH 12/23] LocalisedTransactionReceipt in ClientBase and WebThreeStubServerBase --- libethereum/BlockChain.h | 5 +++- libethereum/ClientBase.cpp | 14 ++++++++++ libethereum/ClientBase.h | 1 + libethereum/Interface.h | 1 + libethereum/TransactionReceipt.h | 28 ++++++++++---------- libweb3jsonrpc/JsonHelper.cpp | 31 +++++++---------------- libweb3jsonrpc/JsonHelper.h | 3 +-- libweb3jsonrpc/WebThreeStubServerBase.cpp | 3 +-- 8 files changed, 44 insertions(+), 42 deletions(-) diff --git a/libethereum/BlockChain.h b/libethereum/BlockChain.h index 4cffca2df..987d605ce 100644 --- a/libethereum/BlockChain.h +++ b/libethereum/BlockChain.h @@ -142,8 +142,11 @@ public: BlockReceipts receipts(h256 const& _hash) const { return queryExtras(_hash, m_receipts, x_receipts, NullBlockReceipts); } BlockReceipts receipts() const { return receipts(currentHash()); } + /// Get the transaction by block hash and index; + TransactionReceipt transactionReceipt(h256 const& _blockHash, unsigned _i) const {return receipts(_blockHash).receipts[_i]; } + /// 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]; } + TransactionReceipt transactionReceipt(h256 const& _transactionHash) const {TransactionAddress ta = queryExtras(_transactionHash, m_transactionAddresses, x_transactionAddresses, NullTransactionAddress); if (!ta) return bytesConstRef(); return transactionReceipt(ta.blockHash, 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; } diff --git a/libethereum/ClientBase.cpp b/libethereum/ClientBase.cpp index 6483f6c0c..66ecfc2b4 100644 --- a/libethereum/ClientBase.cpp +++ b/libethereum/ClientBase.cpp @@ -332,6 +332,20 @@ TransactionReceipt ClientBase::transactionReceipt(h256 const& _transactionHash) return bc().transactionReceipt(_transactionHash); } +LocalisedTransactionReceipt ClientBase::localisedTransactionReceipt(h256 const& _transactionHash) const +{ + std::pair tl = bc().transactionLocation(_transactionHash); + Transaction t = Transaction(bc().transaction(tl.first, tl.second), CheckTransaction::Cheap); + TransactionReceipt tr = bc().transactionReceipt(tl.first, tl.second); + return LocalisedTransactionReceipt( + tr, + t.sha3(), + tl.first, + numberFromHash(tl.first), + tl.second, + toAddress(t.from(), t.nonce())); +} + pair ClientBase::transactionLocation(h256 const& _transactionHash) const { return bc().transactionLocation(_transactionHash); diff --git a/libethereum/ClientBase.h b/libethereum/ClientBase.h index 05766b3a1..e8795abd2 100644 --- a/libethereum/ClientBase.h +++ b/libethereum/ClientBase.h @@ -120,6 +120,7 @@ public: 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 LocalisedTransactionReceipt localisedTransactionReceipt(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 c65670a30..07758851c 100644 --- a/libethereum/Interface.h +++ b/libethereum/Interface.h @@ -136,6 +136,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 LocalisedTransactionReceipt localisedTransactionReceipt(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/libethereum/TransactionReceipt.h b/libethereum/TransactionReceipt.h index 8c102611a..ceb1123b5 100644 --- a/libethereum/TransactionReceipt.h +++ b/libethereum/TransactionReceipt.h @@ -75,35 +75,33 @@ public: m_blockNumber(_blockNumber), m_transactionIndex(_transactionIndex), m_contractAddress(_contractAddress) - {} - - h256 const& hash() const { return m_hash; } - h256 const& blockHash() const { return m_blockHash; } - BlockNumber blockNumber() const { return m_blockNumber; } - unsigned transactionIndex() const { return m_transactionIndex; } - Address const& contractAddress() const { return m_contractAddress; } - - LocalisedLogEntries localisedLogs() const { - LocalisedLogEntries localisedEntries; LogEntries entries = log(); for (unsigned i = 0; i < entries.size(); i++) - localisedEntries.push_back(LocalisedLogEntry( + m_localisedLogs.push_back(LocalisedLogEntry( entries[i], m_blockHash, m_blockNumber, m_hash, m_transactionIndex, - i)); - return localisedEntries; - }; + i + )); + } + + h256 const& hash() const { return m_hash; } + h256 const& blockHash() const { return m_blockHash; } + BlockNumber blockNumber() const { return m_blockNumber; } + unsigned transactionIndex() const { return m_transactionIndex; } + Address const& contractAddress() const { return m_contractAddress; } + LocalisedLogEntries const& localisedLogs() const { return m_localisedLogs; }; private: h256 m_hash; h256 m_blockHash; BlockNumber m_blockNumber; - unsigned m_transactionIndex; + unsigned m_transactionIndex = 0; Address m_contractAddress; + LocalisedLogEntries m_localisedLogs; }; } diff --git a/libweb3jsonrpc/JsonHelper.cpp b/libweb3jsonrpc/JsonHelper.cpp index 96312f625..34ab5ad7f 100644 --- a/libweb3jsonrpc/JsonHelper.cpp +++ b/libweb3jsonrpc/JsonHelper.cpp @@ -182,30 +182,17 @@ 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 toJson(dev::eth::LocalisedTransactionReceipt 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); - } + res["transactionHash"] = toJS(_t.hash()); + res["transactionIndex"] = _t.transactionIndex(); + res["blockHash"] = toJS(_t.blockHash()); + res["blockNumber"] = _t.blockNumber(); + res["cumulativeGasUsed"] = toJS(_t.gasUsed()); // TODO: check if this is fine + res["gasUsed"] = toJS(_t.gasUsed()); + res["contractAddress"] = toJS(_t.contractAddress()); + res["logs"] = dev::toJson(_t.localisedLogs()); return res; } diff --git a/libweb3jsonrpc/JsonHelper.h b/libweb3jsonrpc/JsonHelper.h index 421d11b78..8e42cf77a 100644 --- a/libweb3jsonrpc/JsonHelper.h +++ b/libweb3jsonrpc/JsonHelper.h @@ -57,8 +57,7 @@ Json::Value toJson(BlockInfo const& _bi, BlockDetails const& _bd, UncleHashes co 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(LocalisedTransactionReceipt 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 166fbb1bb..fd1555161 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.cpp +++ b/libweb3jsonrpc/WebThreeStubServerBase.cpp @@ -427,8 +427,7 @@ Json::Value WebThreeStubServerBase::eth_getTransactionReceipt(string const& _tra 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)); + return toJson(client()->localisedTransactionReceipt(h)); } catch (...) { From 7beb78413ce98c38f5d20984adca97f95a8a8b39 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 8 Jul 2015 10:40:54 +0200 Subject: [PATCH 13/23] LocalisedTransaction in ClientBase and WebThreeStubServerBase --- libethereum/ClientBase.cpp | 12 ++++++++++++ libethereum/ClientBase.h | 2 ++ libethereum/Interface.h | 2 ++ libethereum/Transaction.h | 9 +++++---- libweb3jsonrpc/JsonHelper.cpp | 20 ++++++++++++++++++++ libweb3jsonrpc/JsonHelper.h | 2 ++ libweb3jsonrpc/WebThreeStubServerBase.cpp | 9 +++------ 7 files changed, 46 insertions(+), 10 deletions(-) diff --git a/libethereum/ClientBase.cpp b/libethereum/ClientBase.cpp index 66ecfc2b4..141556411 100644 --- a/libethereum/ClientBase.cpp +++ b/libethereum/ClientBase.cpp @@ -317,6 +317,12 @@ Transaction ClientBase::transaction(h256 _transactionHash) const return Transaction(bc().transaction(_transactionHash), CheckTransaction::Cheap); } +LocalisedTransaction ClientBase::localisedTransaction(h256 _transactionHash) const +{ + std::pair tl = bc().transactionLocation(_transactionHash); + return localisedTransaction(tl.first, tl.second); +} + Transaction ClientBase::transaction(h256 _blockHash, unsigned _i) const { auto bl = bc().block(_blockHash); @@ -327,6 +333,12 @@ Transaction ClientBase::transaction(h256 _blockHash, unsigned _i) const return Transaction(); } +LocalisedTransaction ClientBase::localisedTransaction(h256 _blockHash, unsigned _i) const +{ + Transaction t = Transaction(bc().transaction(_blockHash, _i), CheckTransaction::Cheap); + return LocalisedTransaction(t, _blockHash, numberFromHash(_blockHash), _i); +} + TransactionReceipt ClientBase::transactionReceipt(h256 const& _transactionHash) const { return bc().transactionReceipt(_transactionHash); diff --git a/libethereum/ClientBase.h b/libethereum/ClientBase.h index e8795abd2..d0fbb4151 100644 --- a/libethereum/ClientBase.h +++ b/libethereum/ClientBase.h @@ -118,7 +118,9 @@ public: virtual BlockInfo blockInfo(h256 _hash) const override; virtual BlockDetails blockDetails(h256 _hash) const override; virtual Transaction transaction(h256 _transactionHash) const override; + virtual LocalisedTransaction localisedTransaction(h256 _transactionHash) const override; virtual Transaction transaction(h256 _blockHash, unsigned _i) const override; + virtual LocalisedTransaction localisedTransaction(h256 _blockHash, unsigned _i) const override; virtual TransactionReceipt transactionReceipt(h256 const& _transactionHash) const override; virtual LocalisedTransactionReceipt localisedTransactionReceipt(h256 const& _transactionHash) const override; virtual std::pair transactionLocation(h256 const& _transactionHash) const override; diff --git a/libethereum/Interface.h b/libethereum/Interface.h index 07758851c..0f1c5f2a3 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 LocalisedTransaction localisedTransaction(h256 _transactionHash) const = 0; virtual TransactionReceipt transactionReceipt(h256 const& _transactionHash) const = 0; virtual LocalisedTransactionReceipt localisedTransactionReceipt(h256 const& _transactionHash) const = 0; virtual std::pair transactionLocation(h256 const& _transactionHash) const = 0; @@ -147,6 +148,7 @@ public: virtual BlockInfo blockInfo(h256 _hash) const = 0; virtual BlockDetails blockDetails(h256 _hash) const = 0; virtual Transaction transaction(h256 _blockHash, unsigned _i) const = 0; + virtual LocalisedTransaction localisedTransaction(h256 _blockHash, unsigned _i) const = 0; virtual BlockInfo uncle(h256 _blockHash, unsigned _i) const = 0; virtual UncleHashes uncleHashes(h256 _blockHash) const = 0; virtual unsigned transactionCount(h256 _blockHash) const = 0; diff --git a/libethereum/Transaction.h b/libethereum/Transaction.h index d29e9837e..2332a6fdb 100644 --- a/libethereum/Transaction.h +++ b/libethereum/Transaction.h @@ -135,13 +135,14 @@ class LocalisedTransaction: public Transaction public: LocalisedTransaction( Transaction const& _t, - std::pair const& _location, - BlockNumber _blockNumber + h256 const& _blockHash, + BlockNumber _blockNumber, + unsigned _transactionIndex ): Transaction(_t), - m_blockHash(_location.first), + m_blockHash(_blockHash), m_blockNumber(_blockNumber), - m_transactionIndex(_location.second) + m_transactionIndex(_transactionIndex) {} h256 const& blockHash() const { return m_blockHash; } diff --git a/libweb3jsonrpc/JsonHelper.cpp b/libweb3jsonrpc/JsonHelper.cpp index 34ab5ad7f..ab976eddd 100644 --- a/libweb3jsonrpc/JsonHelper.cpp +++ b/libweb3jsonrpc/JsonHelper.cpp @@ -214,6 +214,26 @@ Json::Value toJson(dev::eth::Transaction const& _t) return res; } +Json::Value toJson(dev::eth::LocalisedTransaction const& _t) +{ + Json::Value res; + if (_t) + { + res["hash"] = toJS(_t.sha3()); + res["input"] = toJS(_t.data()); + res["to"] = _t.isCreation() ? Json::Value() : toJS(_t.receiveAddress()); + res["from"] = toJS(_t.safeSender()); + res["gas"] = toJS(_t.gas()); + res["gasPrice"] = toJS(_t.gasPrice()); + res["nonce"] = toJS(_t.nonce()); + res["value"] = toJS(_t.value()); + res["blockHash"] = toJS(_t.blockHash()); + res["transactionIndex"] = toJS(_t.transactionIndex()); + res["blockNumber"] = toJS(_t.blockNumber()); + } + return res; +} + Json::Value toJson(dev::eth::LocalisedLogEntry const& _e) { Json::Value res; diff --git a/libweb3jsonrpc/JsonHelper.h b/libweb3jsonrpc/JsonHelper.h index 8e42cf77a..3c652db7a 100644 --- a/libweb3jsonrpc/JsonHelper.h +++ b/libweb3jsonrpc/JsonHelper.h @@ -43,6 +43,7 @@ namespace eth { class Transaction; +class LocalisedTransaction; struct BlockDetails; class Interface; using Transactions = std::vector; @@ -56,6 +57,7 @@ Json::Value toJson(BlockInfo const& _bi, BlockDetails const& _bd, UncleHashes co 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(LocalisedTransaction const& _t); Json::Value toJson(TransactionReceipt const& _t); Json::Value toJson(LocalisedTransactionReceipt const& _t); Json::Value toJson(LocalisedLogEntry const& _e); diff --git a/libweb3jsonrpc/WebThreeStubServerBase.cpp b/libweb3jsonrpc/WebThreeStubServerBase.cpp index fd1555161..f91d29ea7 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.cpp +++ b/libweb3jsonrpc/WebThreeStubServerBase.cpp @@ -380,8 +380,7 @@ Json::Value WebThreeStubServerBase::eth_getTransactionByHash(string const& _tran if (!client()->isKnownTransaction(h)) return Json::Value(Json::nullValue); - auto l = client()->transactionLocation(h); - return toJson(client()->transaction(h), l, client()->numberFromHash(l.first)); + return toJson(client()->localisedTransaction(h)); } catch (...) { @@ -395,8 +394,7 @@ Json::Value WebThreeStubServerBase::eth_getTransactionByBlockHashAndIndex(string { h256 bh = jsToFixed<32>(_blockHash); unsigned ti = jsToInt(_transactionIndex); - Transaction t = client()->transaction(bh, ti); - return toJson(t, make_pair(bh, ti), client()->numberFromHash(bh)); + return toJson(client()->localisedTransaction(bh, ti)); } catch (...) { @@ -410,8 +408,7 @@ Json::Value WebThreeStubServerBase::eth_getTransactionByBlockNumberAndIndex(stri { BlockNumber bn = jsToBlockNumber(_blockNumber); unsigned ti = jsToInt(_transactionIndex); - Transaction t = client()->transaction(bn, ti); - return toJson(t, make_pair(client()->hashFromNumber(bn), ti), bn); + return toJson(client()->localisedTransaction(client()->hashFromNumber(bn), ti)); } catch (...) { From a5e31dc4e754a18784e27e4caba6c55db8318b3f Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 8 Jul 2015 10:45:41 +0200 Subject: [PATCH 14/23] style fixes --- libethereum/Transaction.h | 2 +- libethereum/TransactionReceipt.h | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libethereum/Transaction.h b/libethereum/Transaction.h index 2332a6fdb..b13630f6a 100644 --- a/libethereum/Transaction.h +++ b/libethereum/Transaction.h @@ -137,7 +137,7 @@ public: Transaction const& _t, h256 const& _blockHash, BlockNumber _blockNumber, - unsigned _transactionIndex + unsigned _transactionIndex ): Transaction(_t), m_blockHash(_blockHash), diff --git a/libethereum/TransactionReceipt.h b/libethereum/TransactionReceipt.h index ceb1123b5..6043cc5ee 100644 --- a/libethereum/TransactionReceipt.h +++ b/libethereum/TransactionReceipt.h @@ -63,11 +63,11 @@ class LocalisedTransactionReceipt: public TransactionReceipt public: LocalisedTransactionReceipt( TransactionReceipt const& _t, - h256 const& _hash, - h256 const& _blockHash, - BlockNumber _blockNumber, - unsigned _transactionIndex, - Address const& _contractAddress = Address() + h256 const& _hash, + h256 const& _blockHash, + BlockNumber _blockNumber, + unsigned _transactionIndex, + Address const& _contractAddress = Address() ): TransactionReceipt(_t), m_hash(_hash), From 596a2deaf6cfc1f293ae67ab39f1b09d77c5aada Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Thu, 9 Jul 2015 00:47:16 +0200 Subject: [PATCH 15/23] fixed style issues --- libethereum/BlockChain.h | 4 ++-- libethereum/ClientBase.cpp | 4 ++-- libethereum/ClientBase.h | 4 ++-- libethereum/Interface.h | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/libethereum/BlockChain.h b/libethereum/BlockChain.h index 9956226f2..ecaaee4c0 100644 --- a/libethereum/BlockChain.h +++ b/libethereum/BlockChain.h @@ -143,10 +143,10 @@ public: BlockReceipts receipts() const { return receipts(currentHash()); } /// Get the transaction by block hash and index; - TransactionReceipt transactionReceipt(h256 const& _blockHash, unsigned _i) const {return receipts(_blockHash).receipts[_i]; } + TransactionReceipt transactionReceipt(h256 const& _blockHash, unsigned _i) const { return receipts(_blockHash).receipts[_i]; } /// 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 transactionReceipt(ta.blockHash, ta.index); } + TransactionReceipt transactionReceipt(h256 const& _transactionHash) const { TransactionAddress ta = queryExtras(_transactionHash, m_transactionAddresses, x_transactionAddresses, NullTransactionAddress); if (!ta) return bytesConstRef(); return transactionReceipt(ta.blockHash, 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; } diff --git a/libethereum/ClientBase.cpp b/libethereum/ClientBase.cpp index 5a5f89b72..5d5af7c6b 100644 --- a/libethereum/ClientBase.cpp +++ b/libethereum/ClientBase.cpp @@ -317,7 +317,7 @@ Transaction ClientBase::transaction(h256 _transactionHash) const return Transaction(bc().transaction(_transactionHash), CheckTransaction::Cheap); } -LocalisedTransaction ClientBase::localisedTransaction(h256 _transactionHash) const +LocalisedTransaction ClientBase::localisedTransaction(h256 const& _transactionHash) const { std::pair tl = bc().transactionLocation(_transactionHash); return localisedTransaction(tl.first, tl.second); @@ -333,7 +333,7 @@ Transaction ClientBase::transaction(h256 _blockHash, unsigned _i) const return Transaction(); } -LocalisedTransaction ClientBase::localisedTransaction(h256 _blockHash, unsigned _i) const +LocalisedTransaction ClientBase::localisedTransaction(h256 const& _blockHash, unsigned _i) const { Transaction t = Transaction(bc().transaction(_blockHash, _i), CheckTransaction::Cheap); return LocalisedTransaction(t, _blockHash, numberFromHash(_blockHash), _i); diff --git a/libethereum/ClientBase.h b/libethereum/ClientBase.h index 31a0f7499..91a9daf29 100644 --- a/libethereum/ClientBase.h +++ b/libethereum/ClientBase.h @@ -118,9 +118,9 @@ public: virtual BlockInfo blockInfo(h256 _hash) const override; virtual BlockDetails blockDetails(h256 _hash) const override; virtual Transaction transaction(h256 _transactionHash) const override; - virtual LocalisedTransaction localisedTransaction(h256 _transactionHash) const override; + virtual LocalisedTransaction localisedTransaction(h256 const& _transactionHash) const override; virtual Transaction transaction(h256 _blockHash, unsigned _i) const override; - virtual LocalisedTransaction localisedTransaction(h256 _blockHash, unsigned _i) const override; + virtual LocalisedTransaction localisedTransaction(h256 const& _blockHash, unsigned _i) const override; virtual TransactionReceipt transactionReceipt(h256 const& _transactionHash) const override; virtual LocalisedTransactionReceipt localisedTransactionReceipt(h256 const& _transactionHash) const override; virtual std::pair transactionLocation(h256 const& _transactionHash) const override; diff --git a/libethereum/Interface.h b/libethereum/Interface.h index d030e666f..418b8e0ff 100644 --- a/libethereum/Interface.h +++ b/libethereum/Interface.h @@ -135,7 +135,7 @@ public: virtual bool isKnownTransaction(h256 const& _transactionHash) const = 0; virtual Transaction transaction(h256 _transactionHash) const = 0; - virtual LocalisedTransaction localisedTransaction(h256 _transactionHash) const = 0; + virtual LocalisedTransaction localisedTransaction(h256 const& _transactionHash) const = 0; virtual TransactionReceipt transactionReceipt(h256 const& _transactionHash) const = 0; virtual LocalisedTransactionReceipt localisedTransactionReceipt(h256 const& _transactionHash) const = 0; virtual std::pair transactionLocation(h256 const& _transactionHash) const = 0; @@ -148,7 +148,7 @@ public: virtual BlockInfo blockInfo(h256 _hash) const = 0; virtual BlockDetails blockDetails(h256 _hash) const = 0; virtual Transaction transaction(h256 _blockHash, unsigned _i) const = 0; - virtual LocalisedTransaction localisedTransaction(h256 _blockHash, unsigned _i) const = 0; + virtual LocalisedTransaction localisedTransaction(h256 const& _blockHash, unsigned _i) const = 0; virtual BlockInfo uncle(h256 _blockHash, unsigned _i) const = 0; virtual UncleHashes uncleHashes(h256 _blockHash) const = 0; virtual unsigned transactionCount(h256 _blockHash) const = 0; From c6371bec4921b47009b95d93bac64554f7fce5fb Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Thu, 9 Jul 2015 00:59:32 +0200 Subject: [PATCH 16/23] blockNumber is optional for LocalisedTransaction --- libethereum/ClientBase.cpp | 2 +- libethereum/Transaction.h | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/libethereum/ClientBase.cpp b/libethereum/ClientBase.cpp index 5d5af7c6b..b133e3731 100644 --- a/libethereum/ClientBase.cpp +++ b/libethereum/ClientBase.cpp @@ -336,7 +336,7 @@ Transaction ClientBase::transaction(h256 _blockHash, unsigned _i) const LocalisedTransaction ClientBase::localisedTransaction(h256 const& _blockHash, unsigned _i) const { Transaction t = Transaction(bc().transaction(_blockHash, _i), CheckTransaction::Cheap); - return LocalisedTransaction(t, _blockHash, numberFromHash(_blockHash), _i); + return LocalisedTransaction(t, _blockHash, _i, numberFromHash(_blockHash)); } TransactionReceipt ClientBase::transactionReceipt(h256 const& _transactionHash) const diff --git a/libethereum/Transaction.h b/libethereum/Transaction.h index b13630f6a..02373fe9e 100644 --- a/libethereum/Transaction.h +++ b/libethereum/Transaction.h @@ -136,23 +136,23 @@ public: LocalisedTransaction( Transaction const& _t, h256 const& _blockHash, - BlockNumber _blockNumber, - unsigned _transactionIndex + unsigned _transactionIndex, + BlockNumber _blockNumber = 0 ): Transaction(_t), m_blockHash(_blockHash), - m_blockNumber(_blockNumber), - m_transactionIndex(_transactionIndex) + m_transactionIndex(_transactionIndex), + m_blockNumber(_blockNumber) {} h256 const& blockHash() const { return m_blockHash; } - BlockNumber blockNumber() const { return m_blockNumber; } unsigned transactionIndex() const { return m_transactionIndex; } + BlockNumber blockNumber() const { return m_blockNumber; } private: h256 m_blockHash; - BlockNumber m_blockNumber; unsigned m_transactionIndex; + BlockNumber m_blockNumber; }; } From f6719db60fba03f3b0626e76f98e3eec97f0e922 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Tue, 14 Jul 2015 00:32:04 +0200 Subject: [PATCH 17/23] commit eth_getFilterLogs returns reverted logs --- libethereum/Client.cpp | 7 ++--- libethereum/ClientBase.cpp | 58 ++++++++++++++++++-------------------- libethereum/ClientBase.h | 1 + 3 files changed, 31 insertions(+), 35 deletions(-) diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index 42b5bbcf4..b485f7def 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -412,7 +412,6 @@ void Client::appendFromNewPending(TransactionReceipt const& _receipt, h256Hash& void Client::appendFromBlock(h256 const& _block, BlockPolarity _polarity, h256Hash& io_changed) { // TODO: more precise check on whether the txs match. - auto d = m_bc.info(_block); auto receipts = m_bc.receipts(_block).receipts; Guard l(x_filtersWatches); @@ -421,18 +420,16 @@ void Client::appendFromBlock(h256 const& _block, BlockPolarity _polarity, h256Ha for (pair& i: m_filters) { // acceptable number & looks like block may contain a matching log entry. - unsigned logIndex = 0; for (size_t j = 0; j < receipts.size(); j++) { - logIndex++; auto tr = receipts[j]; auto m = i.second.filter.matches(tr); if (m.size()) { - auto transactionHash = transaction(d.hash(), j).sha3(); + auto transactionHash = transaction(_block, j).sha3(); // filter catches them for (LogEntry const& l: m) - i.second.changes.push_back(LocalisedLogEntry(l, d.hash(), (BlockNumber)d.number, transactionHash, j, logIndex, _polarity)); + i.second.changes.push_back(LocalisedLogEntry(l, _block, (BlockNumber)bc().number(_block), transactionHash, j, 0, _polarity)); io_changed.insert(i.first); } } diff --git a/libethereum/ClientBase.cpp b/libethereum/ClientBase.cpp index 375fd74f7..440443156 100644 --- a/libethereum/ClientBase.cpp +++ b/libethereum/ClientBase.cpp @@ -171,49 +171,47 @@ LocalisedLogEntries ClientBase::logs(LogFilter const& _f) const // Might have a transaction that contains a matching log. TransactionReceipt const& tr = temp.receipt(i); LogEntries le = _f.matches(tr); - if (le.size()) - for (unsigned j = 0; j < le.size(); ++j) - ret.insert(ret.begin(), LocalisedLogEntry(le[j])); + for (unsigned j = 0; j < le.size(); ++j) + ret.insert(ret.begin(), LocalisedLogEntry(le[j])); } begin = bc().number(); } - + + // Handle blocks from main chain set matchingBlocks; for (auto const& i: _f.bloomPossibilities()) for (auto u: bc().withBlockBloom(i, end, begin)) matchingBlocks.insert(u); - unsigned falsePos = 0; for (auto n: matchingBlocks) + appendLogsFromBlock(_f, bc().numberHash(n), BlockPolarity::Live, ret); + + // Handle reverted blocks + h256s blocks; + h256 ancestor; + unsigned ancestorIndex; + tie(blocks, ancestor, ancestorIndex) = bc().treeRoute(_f.earliest(), _f.latest(), false); + + for (size_t i = 0; i < ancestorIndex; i++) + appendLogsFromBlock(_f, blocks[i], BlockPolarity::Dead, ret); + + return ret; +} + +void ClientBase::appendLogsFromBlock(LogFilter const& _f, h256 const& _blockHash, BlockPolarity _polarity, LocalisedLogEntries& io_logs) const +{ + auto receipts = bc().receipts(_blockHash).receipts; + for (size_t i = 0; i < receipts.size(); i++) { - int total = 0; - auto h = bc().numberHash(n); - auto info = bc().info(h); - auto receipts = bc().receipts(h).receipts; - unsigned logIndex = 0; - for (size_t i = 0; i < receipts.size(); i++) + TransactionReceipt receipt = receipts[i]; + if (_f.matches(receipt.bloom())) { - logIndex++; - TransactionReceipt receipt = receipts[i]; - if (_f.matches(receipt.bloom())) - { - auto th = transaction(info.hash(), i).sha3(); - LogEntries le = _f.matches(receipt); - if (le.size()) - { - total += le.size(); - for (unsigned j = 0; j < le.size(); ++j) - ret.insert(ret.begin(), LocalisedLogEntry(le[j], info.hash(), (BlockNumber)info.number, th, i, logIndex, BlockPolarity::Live)); - } - } - - if (!total) - falsePos++; + auto th = transaction(_blockHash, i).sha3(); + LogEntries le = _f.matches(receipt); + for (unsigned j = 0; j < le.size(); ++j) + io_logs.insert(io_logs.begin(), LocalisedLogEntry(le[j], _blockHash, (BlockNumber)bc().number(_blockHash), th, i, 0, _polarity)); } } - - cdebug << matchingBlocks.size() << "searched from" << (end - begin) << "skipped; " << falsePos << "false +ves"; - return ret; } unsigned ClientBase::installWatch(LogFilter const& _f, Reaping _r) diff --git a/libethereum/ClientBase.h b/libethereum/ClientBase.h index 91a9daf29..b68fc540f 100644 --- a/libethereum/ClientBase.h +++ b/libethereum/ClientBase.h @@ -104,6 +104,7 @@ public: virtual LocalisedLogEntries logs(unsigned _watchId) const override; virtual LocalisedLogEntries logs(LogFilter const& _filter) const override; + virtual void appendLogsFromBlock(LogFilter const& _filter, h256 const& _blockHash, BlockPolarity _polarity, LocalisedLogEntries& io_logs) const; /// Install, uninstall and query watches. virtual unsigned installWatch(LogFilter const& _filter, Reaping _r = Reaping::Automatic) override; From a72b51c86dc3105672e8b3f8370087af83d32ae4 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 15 Jul 2015 01:11:32 +0200 Subject: [PATCH 18/23] clear reverted block hashes from cache during imporing --- libethereum/BlockChain.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/libethereum/BlockChain.cpp b/libethereum/BlockChain.cpp index d9a54a1ee..b6890d160 100644 --- a/libethereum/BlockChain.cpp +++ b/libethereum/BlockChain.cpp @@ -597,10 +597,27 @@ ImportRoute BlockChain::import(VerifiedBlockRef const& _block, OverlayDB const& // Most of the time these two will be equal - only when we're doing a chain revert will they not be if (common != last) + { // If we are reverting previous blocks, we need to clear their blooms (in particular, to // rebuild any higher level blooms that they contributed to). clearBlockBlooms(number(common) + 1, number(last) + 1); + // clear reverted blockhashes + DEV_WRITE_GUARDED(x_blockHashes) + for (auto i = route.begin(); i != route.end() && *i != common; ++i) + { + BlockInfo tbi = BlockInfo(block(*i)); + auto h = h256(tbi.number); + for (auto j = m_blockHashes.begin(); j != m_blockHashes.end();) + { + if (j->first == h) + j = m_blockHashes.erase(j); + else + ++j; + } + } + } + // Go through ret backwards until hash != last.parent and update m_transactionAddresses, m_blockHashes for (auto i = route.rbegin(); i != route.rend() && *i != common; ++i) { From 358f9b49cd06366dac4b5073057df357a5baa234 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 15 Jul 2015 10:31:32 +0200 Subject: [PATCH 19/23] eth_getTransactionByBlockHash && eth_getTransactionByBlockNumber returns null when transactions are out of scope --- libethereum/ClientBase.cpp | 4 ++++ libethereum/ClientBase.h | 1 + libethereum/Interface.h | 1 + libweb3jsonrpc/WebThreeStubServerBase.cpp | 9 ++++++++- 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/libethereum/ClientBase.cpp b/libethereum/ClientBase.cpp index 440443156..4f913304d 100644 --- a/libethereum/ClientBase.cpp +++ b/libethereum/ClientBase.cpp @@ -503,3 +503,7 @@ bool ClientBase::isKnownTransaction(h256 const& _transactionHash) const return bc().isKnownTransaction(_transactionHash); } +bool ClientBase::isKnownTransaction(h256 const& _blockHash, unsigned _i) const +{ + return isKnown(_blockHash) && bc().transactions().size() > _i; +} diff --git a/libethereum/ClientBase.h b/libethereum/ClientBase.h index b68fc540f..9e513124a 100644 --- a/libethereum/ClientBase.h +++ b/libethereum/ClientBase.h @@ -152,6 +152,7 @@ public: virtual bool isKnown(h256 const& _hash) const override; virtual bool isKnown(BlockNumber _block) const override; virtual bool isKnownTransaction(h256 const& _transactionHash) const override; + virtual bool isKnownTransaction(h256 const& _blockHash, unsigned _i) const override; /// TODO: consider moving it to a separate interface diff --git a/libethereum/Interface.h b/libethereum/Interface.h index 418b8e0ff..753b712ea 100644 --- a/libethereum/Interface.h +++ b/libethereum/Interface.h @@ -134,6 +134,7 @@ public: // [BLOCK QUERY API] virtual bool isKnownTransaction(h256 const& _transactionHash) const = 0; + virtual bool isKnownTransaction(h256 const& _blockHash, unsigned _i) const = 0; virtual Transaction transaction(h256 _transactionHash) const = 0; virtual LocalisedTransaction localisedTransaction(h256 const& _transactionHash) const = 0; virtual TransactionReceipt transactionReceipt(h256 const& _transactionHash) const = 0; diff --git a/libweb3jsonrpc/WebThreeStubServerBase.cpp b/libweb3jsonrpc/WebThreeStubServerBase.cpp index a9d74d3ac..8b1962941 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.cpp +++ b/libweb3jsonrpc/WebThreeStubServerBase.cpp @@ -394,6 +394,9 @@ Json::Value WebThreeStubServerBase::eth_getTransactionByBlockHashAndIndex(string { h256 bh = jsToFixed<32>(_blockHash); unsigned ti = jsToInt(_transactionIndex); + if (!client()->isKnownTransaction(bh, ti)) + return Json::Value(Json::nullValue); + return toJson(client()->localisedTransaction(bh, ti)); } catch (...) @@ -407,8 +410,12 @@ Json::Value WebThreeStubServerBase::eth_getTransactionByBlockNumberAndIndex(stri try { BlockNumber bn = jsToBlockNumber(_blockNumber); + h256 bh = client()->hashFromNumber(bn); unsigned ti = jsToInt(_transactionIndex); - return toJson(client()->localisedTransaction(client()->hashFromNumber(bn), ti)); + if (!client()->isKnownTransaction(bh, ti)) + return Json::Value(Json::nullValue); + + return toJson(client()->localisedTransaction(bh, ti)); } catch (...) { From 2344e14f1bbbe56b628ef61fc945ff71c3cbdb50 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 15 Jul 2015 12:00:28 +0200 Subject: [PATCH 20/23] proper combinatorics in LogFilter::bloomPossibilities(), #2295 --- libethereum/LogFilter.cpp | 55 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 3 deletions(-) diff --git a/libethereum/LogFilter.cpp b/libethereum/LogFilter.cpp index 6e0fbd709..029869c7a 100644 --- a/libethereum/LogFilter.cpp +++ b/libethereum/LogFilter.cpp @@ -77,9 +77,58 @@ vector LogFilter::bloomPossibilities() const { // return combination of each of the addresses/topics vector ret; - // TODO proper combinatorics. - for (auto i: m_addresses) - ret.push_back(LogBloom().shiftBloom<3>(dev::sha3(i))); + + // | every address with every topic + for (auto const& i: m_addresses) + { + // 1st case, there are addresses and topics + // + // m_addresses = [a0, a1]; + // m_topics = [[t0], [t1a, t1b], [], []]; + // + // blooms = [ + // a0 | t0, a0 | t1a | t1b, + // a1 | t0, a1 | t1a | t1b + // ] + // + for (auto const& t: m_topics) + if (t.size()) + { + LogBloom b = LogBloom().shiftBloom<3>(dev::sha3(i)); + for (auto const &j: t) + b = b.shiftBloom<3>(dev::sha3(j)); + ret.push_back(b); + } + } + + // 2nd case, there are no topics + // + // m_addresses = [a0, a1]; + // m_topics = [[t0], [t1a, t1b], [], []]; + // + // blooms = [a0, a1]; + // + if (!ret.size()) + for (auto const& i: m_addresses) + ret.push_back(LogBloom().shiftBloom<3>(dev::sha3(i))); + + // 3rd case, there are no addresses, at least create blooms from topics + // + // m_addresses = []; + // m_topics = [[t0], [t1a, t1b], [], []]; + // + // blooms = [t0, t1a | t1b]; + // + if (!m_addresses.size()) + for (auto const& t: m_topics) + if (t.size()) + { + LogBloom b; + for (auto const &j: t) + b = b.shiftBloom<3>(dev::sha3(j)); + ret.push_back(b); + } + return ret; } From d692c959c79d47a3f37feebb70ee4c0d8c7c41ec Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 15 Jul 2015 12:26:04 +0200 Subject: [PATCH 21/23] fixed anonymous logs --- libethereum/ClientBase.cpp | 49 +++++++++++++++++++++++++------------- libethereum/LogFilter.cpp | 16 +++++++++++++ libethereum/LogFilter.h | 10 ++++++++ 3 files changed, 59 insertions(+), 16 deletions(-) diff --git a/libethereum/ClientBase.cpp b/libethereum/ClientBase.cpp index 4f913304d..fb81c2592 100644 --- a/libethereum/ClientBase.cpp +++ b/libethereum/ClientBase.cpp @@ -177,16 +177,8 @@ LocalisedLogEntries ClientBase::logs(LogFilter const& _f) const begin = bc().number(); } - // Handle blocks from main chain - set matchingBlocks; - for (auto const& i: _f.bloomPossibilities()) - for (auto u: bc().withBlockBloom(i, end, begin)) - matchingBlocks.insert(u); - - for (auto n: matchingBlocks) - appendLogsFromBlock(_f, bc().numberHash(n), BlockPolarity::Live, ret); - // Handle reverted blocks + // There are not so many, so let's iterate over them h256s blocks; h256 ancestor; unsigned ancestorIndex; @@ -195,6 +187,34 @@ LocalisedLogEntries ClientBase::logs(LogFilter const& _f) const for (size_t i = 0; i < ancestorIndex; i++) appendLogsFromBlock(_f, blocks[i], BlockPolarity::Dead, ret); + // cause end is our earliest block, let's compare it with our ancestor + // if ancestor is smaller let's move our end to it + // example: + // + // 3b -> 2b -> 1b + // -> g + // 3a -> 2a -> 1a + // + // if earliest is at 1a and latest is a 3b, coverting them to numbers + // will give us pair (1, 3) + // and we want to get all logs from g (ancestor) to 3 + // so we have to move 1a to g + end = min(end, (unsigned)numberFromHash(ancestor)); + + // Handle blocks from main chain + set matchingBlocks; + if (!_f.isRangeFilter()) + for (auto const& i: _f.bloomPossibilities()) + for (auto u: bc().withBlockBloom(i, end, begin)) + matchingBlocks.insert(u); + else + // if it is a range filter, we want to get all logs from all blocks in given range + for (unsigned i = end; i <= begin; i++) + matchingBlocks.insert(i); + + for (auto n: matchingBlocks) + appendLogsFromBlock(_f, bc().numberHash(n), BlockPolarity::Live, ret); + return ret; } @@ -204,13 +224,10 @@ void ClientBase::appendLogsFromBlock(LogFilter const& _f, h256 const& _blockHash for (size_t i = 0; i < receipts.size(); i++) { TransactionReceipt receipt = receipts[i]; - if (_f.matches(receipt.bloom())) - { - auto th = transaction(_blockHash, i).sha3(); - LogEntries le = _f.matches(receipt); - for (unsigned j = 0; j < le.size(); ++j) - io_logs.insert(io_logs.begin(), LocalisedLogEntry(le[j], _blockHash, (BlockNumber)bc().number(_blockHash), th, i, 0, _polarity)); - } + auto th = transaction(_blockHash, i).sha3(); + LogEntries le = _f.matches(receipt); + for (unsigned j = 0; j < le.size(); ++j) + io_logs.insert(io_logs.begin(), LocalisedLogEntry(le[j], _blockHash, (BlockNumber)bc().number(_blockHash), th, i, 0, _polarity)); } } diff --git a/libethereum/LogFilter.cpp b/libethereum/LogFilter.cpp index 029869c7a..95c07f2a3 100644 --- a/libethereum/LogFilter.cpp +++ b/libethereum/LogFilter.cpp @@ -46,6 +46,18 @@ h256 LogFilter::sha3() const return dev::sha3(s.out()); } +bool LogFilter::isRangeFilter() const +{ + if (m_addresses.size()) + return false; + + for (auto const& t: m_topics) + if (t.size()) + return false; + + return true; +} + bool LogFilter::matches(LogBloom _bloom) const { if (m_addresses.size()) @@ -134,6 +146,10 @@ vector LogFilter::bloomPossibilities() const LogEntries LogFilter::matches(TransactionReceipt const& _m) const { + // there are no addresses or topics to filter + if (isRangeFilter()) + return _m.log(); + LogEntries ret; if (matches(_m.bloom())) for (LogEntry const& e: _m.log()) diff --git a/libethereum/LogFilter.h b/libethereum/LogFilter.h index ff33346f8..092f173ef 100644 --- a/libethereum/LogFilter.h +++ b/libethereum/LogFilter.h @@ -50,10 +50,20 @@ public: void streamRLP(RLPStream& _s) const; h256 sha3() const; + /// hash of earliest block which should be filtered h256 earliest() const { return m_earliest; } + + /// hash of latest block which should be filtered h256 latest() const { return m_latest; } + /// Range filter is a filter which doesn't care about addresses or topics + /// Matches are all entries from earliest to latest + /// @returns true if addresses and topics are unspecified + bool isRangeFilter() const; + + /// @returns bloom possibilities for all addresses and topics std::vector bloomPossibilities() const; + bool matches(LogBloom _bloom) const; bool matches(State const& _s, unsigned _i) const; LogEntries matches(TransactionReceipt const& _r) const; From ad884353915db593364732a62ed8c56493599159 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 15 Jul 2015 13:35:19 +0200 Subject: [PATCH 22/23] logs are being returned in proper order, without ancestor --- libethereum/ClientBase.cpp | 17 +++++++++-------- libethereum/ClientBase.h | 2 +- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/libethereum/ClientBase.cpp b/libethereum/ClientBase.cpp index fb81c2592..9ac9d9647 100644 --- a/libethereum/ClientBase.cpp +++ b/libethereum/ClientBase.cpp @@ -185,7 +185,7 @@ LocalisedLogEntries ClientBase::logs(LogFilter const& _f) const tie(blocks, ancestor, ancestorIndex) = bc().treeRoute(_f.earliest(), _f.latest(), false); for (size_t i = 0; i < ancestorIndex; i++) - appendLogsFromBlock(_f, blocks[i], BlockPolarity::Dead, ret); + prependLogsFromBlock(_f, blocks[i], BlockPolarity::Dead, ret); // cause end is our earliest block, let's compare it with our ancestor // if ancestor is smaller let's move our end to it @@ -195,11 +195,11 @@ LocalisedLogEntries ClientBase::logs(LogFilter const& _f) const // -> g // 3a -> 2a -> 1a // - // if earliest is at 1a and latest is a 3b, coverting them to numbers - // will give us pair (1, 3) - // and we want to get all logs from g (ancestor) to 3 - // so we have to move 1a to g - end = min(end, (unsigned)numberFromHash(ancestor)); + // if earliest is at 2a and latest is a 3b, coverting them to numbers + // will give us pair (2, 3) + // and we want to get all logs from 1 (ancestor + 1) to 3 + // so we have to move 2a to g + 1 + end = min(end, (unsigned)numberFromHash(ancestor) + 1); // Handle blocks from main chain set matchingBlocks; @@ -213,12 +213,13 @@ LocalisedLogEntries ClientBase::logs(LogFilter const& _f) const matchingBlocks.insert(i); for (auto n: matchingBlocks) - appendLogsFromBlock(_f, bc().numberHash(n), BlockPolarity::Live, ret); + prependLogsFromBlock(_f, bc().numberHash(n), BlockPolarity::Live, ret); + reverse(ret.begin(), ret.end()); return ret; } -void ClientBase::appendLogsFromBlock(LogFilter const& _f, h256 const& _blockHash, BlockPolarity _polarity, LocalisedLogEntries& io_logs) const +void ClientBase::prependLogsFromBlock(LogFilter const& _f, h256 const& _blockHash, BlockPolarity _polarity, LocalisedLogEntries& io_logs) const { auto receipts = bc().receipts(_blockHash).receipts; for (size_t i = 0; i < receipts.size(); i++) diff --git a/libethereum/ClientBase.h b/libethereum/ClientBase.h index 9e513124a..2b762c0b4 100644 --- a/libethereum/ClientBase.h +++ b/libethereum/ClientBase.h @@ -104,7 +104,7 @@ public: virtual LocalisedLogEntries logs(unsigned _watchId) const override; virtual LocalisedLogEntries logs(LogFilter const& _filter) const override; - virtual void appendLogsFromBlock(LogFilter const& _filter, h256 const& _blockHash, BlockPolarity _polarity, LocalisedLogEntries& io_logs) const; + virtual void prependLogsFromBlock(LogFilter const& _filter, h256 const& _blockHash, BlockPolarity _polarity, LocalisedLogEntries& io_logs) const; /// Install, uninstall and query watches. virtual unsigned installWatch(LogFilter const& _filter, Reaping _r = Reaping::Automatic) override; From 2ff5f57355e016bee7ff2de0d97bc8bfd6c6f181 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 15 Jul 2015 17:18:34 +0200 Subject: [PATCH 23/23] getLogsEx && propert order of returned Ex logs --- libweb3jsonrpc/JsonHelper.cpp | 23 ++++++++++++++------- libweb3jsonrpc/JsonHelper.h | 2 +- libweb3jsonrpc/WebThreeStubServerBase.cpp | 14 ++++++++++++- libweb3jsonrpc/WebThreeStubServerBase.h | 1 + libweb3jsonrpc/abstractwebthreestubserver.h | 6 ++++++ libweb3jsonrpc/spec.json | 1 + test/libweb3jsonrpc/webthreestubclient.h | 10 +++++++++ 7 files changed, 47 insertions(+), 10 deletions(-) diff --git a/libweb3jsonrpc/JsonHelper.cpp b/libweb3jsonrpc/JsonHelper.cpp index 10bd50ea3..9ffb1db0d 100644 --- a/libweb3jsonrpc/JsonHelper.cpp +++ b/libweb3jsonrpc/JsonHelper.cpp @@ -277,13 +277,14 @@ Json::Value toJson(dev::eth::LogEntry const& _e) return res; } -Json::Value toJson(std::map const& _entriesByBlock) +Json::Value toJson(std::unordered_map const& _entriesByBlock, vector const& _order) { Json::Value res(Json::arrayValue); - for (auto const& i: _entriesByBlock) + for (auto const& i: _order) { + auto entries = _entriesByBlock.at(i); Json::Value currentBlock(Json::objectValue); - LocalisedLogEntry entry = i.second[0]; + LocalisedLogEntry entry = entries[0]; if (entry.mined) { @@ -294,18 +295,20 @@ Json::Value toJson(std::map const& _entries else currentBlock["type"] = "pending"; + currentBlock["polarity"] = entry.polarity == BlockPolarity::Live ? true : false; currentBlock["logs"] = Json::Value(Json::arrayValue); - for (LocalisedLogEntry const& e: i.second) + for (LocalisedLogEntry const& e: entries) { Json::Value log(Json::objectValue); log["logIndex"] = e.logIndex; - log["polarity"] = e.polarity == BlockPolarity::Live ? true : false; log["transactionIndex"] = e.transactionIndex; log["transactionHash"] = toJS(e.transactionHash); log["address"] = toJS(e.address); log["data"] = toJS(e.data); - log["topics"] = toJS(e.topics); + log["topics"] = Json::Value(Json::arrayValue); + for (auto const& t: e.topics) + log["topics"].append(toJS(t)); currentBlock["logs"].append(log); } @@ -318,7 +321,8 @@ Json::Value toJson(std::map const& _entries Json::Value toJsonByBlock(LocalisedLogEntries const& _entries) { - map entriesByBlock; + vector order; + unordered_map entriesByBlock; for (dev::eth::LocalisedLogEntry const& e: _entries) { @@ -326,12 +330,15 @@ Json::Value toJsonByBlock(LocalisedLogEntries const& _entries) continue; if (entriesByBlock.count(e.blockHash) == 0) + { entriesByBlock[e.blockHash] = LocalisedLogEntries(); + order.push_back(e.blockHash); + } entriesByBlock[e.blockHash].push_back(e); } - return toJson(entriesByBlock); + return toJson(entriesByBlock, order); } TransactionSkeleton toTransactionSkeleton(Json::Value const& _json) diff --git a/libweb3jsonrpc/JsonHelper.h b/libweb3jsonrpc/JsonHelper.h index 1cf633a2f..a5688d763 100644 --- a/libweb3jsonrpc/JsonHelper.h +++ b/libweb3jsonrpc/JsonHelper.h @@ -62,7 +62,7 @@ Json::Value toJson(TransactionReceipt const& _t); Json::Value toJson(LocalisedTransactionReceipt const& _t); Json::Value toJson(LocalisedLogEntry const& _e); Json::Value toJson(LogEntry const& _e); -Json::Value toJson(std::map const& _entriesByBlock); +Json::Value toJson(std::unordered_map const& _entriesByBlock); Json::Value toJsonByBlock(LocalisedLogEntries const& _entries); TransactionSkeleton toTransactionSkeleton(Json::Value const& _json); LogFilter toLogFilter(Json::Value const& _json); diff --git a/libweb3jsonrpc/WebThreeStubServerBase.cpp b/libweb3jsonrpc/WebThreeStubServerBase.cpp index 8b1962941..a223c37d4 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.cpp +++ b/libweb3jsonrpc/WebThreeStubServerBase.cpp @@ -725,7 +725,19 @@ Json::Value WebThreeStubServerBase::eth_getLogs(Json::Value const& _json) { try { - return toJson(client()->logs(toLogFilter(_json))); + return toJson(client()->logs(toLogFilter(_json, *client()))); + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + } +} + +Json::Value WebThreeStubServerBase::eth_getLogsEx(Json::Value const& _json) +{ + try + { + return toJsonByBlock(client()->logs(toLogFilter(_json))); } catch (...) { diff --git a/libweb3jsonrpc/WebThreeStubServerBase.h b/libweb3jsonrpc/WebThreeStubServerBase.h index d90015aec..62209a5b4 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.h +++ b/libweb3jsonrpc/WebThreeStubServerBase.h @@ -136,6 +136,7 @@ public: virtual Json::Value eth_getFilterLogs(std::string const& _filterId); virtual Json::Value eth_getFilterLogsEx(std::string const& _filterId); virtual Json::Value eth_getLogs(Json::Value const& _json); + virtual Json::Value eth_getLogsEx(Json::Value const& _json); virtual Json::Value eth_getWork(); virtual bool eth_submitWork(std::string const& _nonce, std::string const&, std::string const& _mixHash); virtual std::string eth_register(std::string const& _address); diff --git a/libweb3jsonrpc/abstractwebthreestubserver.h b/libweb3jsonrpc/abstractwebthreestubserver.h index 988271c95..48421b940 100644 --- a/libweb3jsonrpc/abstractwebthreestubserver.h +++ b/libweb3jsonrpc/abstractwebthreestubserver.h @@ -57,6 +57,7 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServerbindAndAddMethod(jsonrpc::Procedure("eth_getFilterLogs", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getFilterLogsI); this->bindAndAddMethod(jsonrpc::Procedure("eth_getFilterLogsEx", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getFilterLogsExI); this->bindAndAddMethod(jsonrpc::Procedure("eth_getLogs", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::eth_getLogsI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_getLogsEx", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::eth_getLogsExI); 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,"param2",jsonrpc::JSON_STRING,"param3",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_submitWorkI); this->bindAndAddMethod(jsonrpc::Procedure("eth_register", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_registerI); @@ -296,6 +297,10 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServereth_getLogs(request[0u]); } + inline virtual void eth_getLogsExI(const Json::Value &request, Json::Value &response) + { + response = this->eth_getLogsEx(request[0u]); + } inline virtual void eth_getWorkI(const Json::Value &request, Json::Value &response) { (void)request; @@ -511,6 +516,7 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServerCallMethod("eth_getLogsEx",p); + if (result.isArray()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } Json::Value eth_getWork() throw (jsonrpc::JsonRpcException) { Json::Value p;