diff --git a/libethereum/BlockChain.h b/libethereum/BlockChain.h index 638c9c3af..4f2a217c3 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/Client.cpp b/libethereum/Client.cpp index bddcf8d6c..42b5bbcf4 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -432,7 +432,7 @@ void Client::appendFromBlock(h256 const& _block, BlockPolarity _polarity, h256Ha 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, _polarity)); + i.second.changes.push_back(LocalisedLogEntry(l, d.hash(), (BlockNumber)d.number, transactionHash, j, logIndex, _polarity)); io_changed.insert(i.first); } } diff --git a/libethereum/ClientBase.cpp b/libethereum/ClientBase.cpp index f9a213881..375fd74f7 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, BlockPolarity::Live)); + ret.insert(ret.begin(), LocalisedLogEntry(le[j], info.hash(), (BlockNumber)info.number, th, i, logIndex, BlockPolarity::Live)); } } @@ -317,6 +317,12 @@ Transaction ClientBase::transaction(h256 _transactionHash) const return Transaction(bc().transaction(_transactionHash), CheckTransaction::Cheap); } +LocalisedTransaction ClientBase::localisedTransaction(h256 const& _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,11 +333,31 @@ Transaction ClientBase::transaction(h256 _blockHash, unsigned _i) const return Transaction(); } +LocalisedTransaction ClientBase::localisedTransaction(h256 const& _blockHash, unsigned _i) const +{ + Transaction t = Transaction(bc().transaction(_blockHash, _i), CheckTransaction::Cheap); + return LocalisedTransaction(t, _blockHash, _i, numberFromHash(_blockHash)); +} + TransactionReceipt ClientBase::transactionReceipt(h256 const& _transactionHash) const { 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 82f03def0..91a9daf29 100644 --- a/libethereum/ClientBase.h +++ b/libethereum/ClientBase.h @@ -118,8 +118,11 @@ 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 const& _transactionHash) const override; virtual Transaction transaction(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; 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 973433af9..418b8e0ff 100644 --- a/libethereum/Interface.h +++ b/libethereum/Interface.h @@ -135,7 +135,9 @@ public: virtual bool isKnownTransaction(h256 const& _transactionHash) 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; + 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; @@ -146,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 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; diff --git a/libethereum/Transaction.h b/libethereum/Transaction.h index 8ed0043c9..02373fe9e 100644 --- a/libethereum/Transaction.h +++ b/libethereum/Transaction.h @@ -130,5 +130,30 @@ private: /// Nice name for vector of Transaction. using Transactions = std::vector; +class LocalisedTransaction: public Transaction +{ +public: + LocalisedTransaction( + Transaction const& _t, + h256 const& _blockHash, + unsigned _transactionIndex, + BlockNumber _blockNumber = 0 + ): + Transaction(_t), + m_blockHash(_blockHash), + m_transactionIndex(_transactionIndex), + m_blockNumber(_blockNumber) + {} + + h256 const& blockHash() const { return m_blockHash; } + unsigned transactionIndex() const { return m_transactionIndex; } + BlockNumber blockNumber() const { return m_blockNumber; } + +private: + h256 m_blockHash; + unsigned m_transactionIndex; + BlockNumber m_blockNumber; +}; + } } diff --git a/libethereum/TransactionReceipt.h b/libethereum/TransactionReceipt.h index 0a0b154f4..6043cc5ee 100644 --- a/libethereum/TransactionReceipt.h +++ b/libethereum/TransactionReceipt.h @@ -58,5 +58,51 @@ 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) + { + LogEntries entries = log(); + for (unsigned i = 0; i < entries.size(); i++) + m_localisedLogs.push_back(LocalisedLogEntry( + entries[i], + m_blockHash, + m_blockNumber, + m_hash, + m_transactionIndex, + 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 = 0; + Address m_contractAddress; + LocalisedLogEntries m_localisedLogs; +}; + } } diff --git a/libevm/ExtVMFace.h b/libevm/ExtVMFace.h index 6c2057559..a1c14cea0 100644 --- a/libevm/ExtVMFace.h +++ b/libevm/ExtVMFace.h @@ -83,20 +83,21 @@ struct LocalisedLogEntry: public LogEntry explicit LocalisedLogEntry( LogEntry const& _le, - BlockInfo const& _bi, - h256 _th, - unsigned _ti, - unsigned _li, - BlockPolarity _polarity = BlockPolarity::Unknown + h256 const& _blockHash, + BlockNumber _blockNumber, + h256 const& _transactionHash, + unsigned _transactionIndex, + unsigned _logIndex, + BlockPolarity _polarity = BlockPolarity::Unknown ): LogEntry(_le), - blockHash(_bi.hash()), - blockNumber((BlockNumber)_bi.number), - transactionHash(_th), - transactionIndex(_ti), - logIndex(_li), - mined(true), - polarity(_polarity) + blockHash(_blockHash), + blockNumber(_blockNumber), + transactionHash(_transactionHash), + transactionIndex(_transactionIndex), + logIndex(_logIndex), + polarity(_polarity), + mined(true) {} h256 blockHash; @@ -104,8 +105,8 @@ struct LocalisedLogEntry: public LogEntry h256 transactionHash; unsigned transactionIndex = 0; unsigned logIndex = 0; - bool mined = false; BlockPolarity polarity = BlockPolarity::Unknown; + bool mined = false; bool isSpecial = false; h256 special; }; diff --git a/libweb3jsonrpc/JsonHelper.cpp b/libweb3jsonrpc/JsonHelper.cpp index ec69aba22..10bd50ea3 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; } @@ -227,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 0386a5b58..1cf633a2f 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,9 +57,9 @@ 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); -//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); Json::Value toJson(std::map const& _entriesByBlock); diff --git a/libweb3jsonrpc/WebThreeStubServerBase.cpp b/libweb3jsonrpc/WebThreeStubServerBase.cpp index 28b76b13a..a9d74d3ac 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 (...) { @@ -427,8 +424,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 (...) {