From e98317f2dd44389ee0d716f079a75a68f6a5affa Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 24 Jun 2015 23:07:05 +0200 Subject: [PATCH] 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()); }