diff --git a/libethereum/Client.h b/libethereum/Client.h index 3bf2015c4..d62af01b1 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -127,6 +127,8 @@ class Client : public ClientBase, protected Worker { /// Retrieve pending transactions Transactions pending() const override; + Transactions debugGetFutureTransactions() const { return m_tq.debugGetFutureTransactions(); } + /// Queues a block for import. ImportResult queueBlock( bytes const& _block, bool _isSafe = false ); diff --git a/libethereum/TransactionQueue.cpp b/libethereum/TransactionQueue.cpp index bfeee388f..6a075bf84 100644 --- a/libethereum/TransactionQueue.cpp +++ b/libethereum/TransactionQueue.cpp @@ -537,3 +537,14 @@ void TransactionQueue::verifierBody() { MICROPROFILE_LEAVE(); } } + +Transactions TransactionQueue::debugGetFutureTransactions() const { + Transactions res; + ReadGuard l( m_lock ); + for ( auto addressAndMap : m_future ) { + for ( auto nonceAndTransaction : addressAndMap.second ) { + res.push_back( nonceAndTransaction.second.transaction ); + } // for nonce + } // for address + return res; +} diff --git a/libethereum/TransactionQueue.h b/libethereum/TransactionQueue.h index 63ad3ee96..d089c4004 100644 --- a/libethereum/TransactionQueue.h +++ b/libethereum/TransactionQueue.h @@ -123,6 +123,8 @@ class TransactionQueue { template < class... Args > Transactions topTransactionsSync( unsigned _limit, Args... args ); + Transactions debugGetFutureTransactions() const; + /// Get a hash set of transactions in the queue /// @returns A hash set of all transactions in the queue const h256Hash knownTransactions() const; diff --git a/libweb3jsonrpc/Debug.cpp b/libweb3jsonrpc/Debug.cpp index 0ef884262..91cc76bca 100644 --- a/libweb3jsonrpc/Debug.cpp +++ b/libweb3jsonrpc/Debug.cpp @@ -314,3 +314,10 @@ uint64_t Debug::debug_doBlocksDbCompaction() { return boost::chrono::duration_cast< boost::chrono::milliseconds >( t2 - t1 ).count(); } + +Json::Value Debug::debug_getFutureTransactions() { + auto res = toJson( m_eth.debugGetFutureTransactions() ); + for ( auto& t : res ) + t.removeMember( "data" ); + return res; +} diff --git a/libweb3jsonrpc/Debug.h b/libweb3jsonrpc/Debug.h index f5337001d..6d85b9d7d 100644 --- a/libweb3jsonrpc/Debug.h +++ b/libweb3jsonrpc/Debug.h @@ -60,6 +60,8 @@ class Debug : public DebugFace { virtual uint64_t debug_doStateDbCompaction() override; virtual uint64_t debug_doBlocksDbCompaction() override; + virtual Json::Value debug_getFutureTransactions() override; + private: eth::Client const& m_eth; SkaleDebugInterface* m_debugInterface = nullptr; diff --git a/libweb3jsonrpc/DebugFace.h b/libweb3jsonrpc/DebugFace.h index ebcc07fe2..ade7094b0 100644 --- a/libweb3jsonrpc/DebugFace.h +++ b/libweb3jsonrpc/DebugFace.h @@ -98,6 +98,10 @@ class DebugFace : public ServerInterface< DebugFace > { this->bindAndAddMethod( jsonrpc::Procedure( "debug_doBlocksDbCompaction", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL ), &dev::rpc::DebugFace::debug_doBlocksDbCompactionI ); + + this->bindAndAddMethod( jsonrpc::Procedure( "debug_getFutureTransactions", + jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL ), + &dev::rpc::DebugFace::debug_getFutureTransactionsI ); } inline virtual void debug_accountRangeAtI( const Json::Value& request, Json::Value& response ) { response = this->debug_accountRangeAt( request[0u].asString(), request[1u].asInt(), @@ -179,6 +183,10 @@ class DebugFace : public ServerInterface< DebugFace > { response = this->debug_doBlocksDbCompaction(); } + virtual void debug_getFutureTransactionsI( const Json::Value&, Json::Value& response ) { + response = this->debug_getFutureTransactions(); + } + virtual Json::Value debug_accountRangeAt( const std::string& param1, int param2, const std::string& param3, int param4 ) = 0; virtual Json::Value debug_traceTransaction( @@ -206,6 +214,8 @@ class DebugFace : public ServerInterface< DebugFace > { virtual uint64_t debug_doStateDbCompaction() = 0; virtual uint64_t debug_doBlocksDbCompaction() = 0; + + virtual Json::Value debug_getFutureTransactions() = 0; }; } // namespace rpc diff --git a/test/unittests/libweb3jsonrpc/WebThreeStubClient.cpp b/test/unittests/libweb3jsonrpc/WebThreeStubClient.cpp index acdebbf42..680bdb57e 100644 --- a/test/unittests/libweb3jsonrpc/WebThreeStubClient.cpp +++ b/test/unittests/libweb3jsonrpc/WebThreeStubClient.cpp @@ -1344,3 +1344,13 @@ Json::Value WebThreeStubClient::debug_doBlocksDbCompaction() { throw jsonrpc::JsonRpcException( jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString() ); } + +Json::Value WebThreeStubClient::debug_getFutureTransactions() { + Json::Value p; + Json::Value result = this->CallMethod( "debug_getFutureTransactions", p ); + if ( result.isArray() ) + return result; + else + throw jsonrpc::JsonRpcException( + jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString() ); +} diff --git a/test/unittests/libweb3jsonrpc/WebThreeStubClient.h b/test/unittests/libweb3jsonrpc/WebThreeStubClient.h index a97f41d25..ad50db93a 100644 --- a/test/unittests/libweb3jsonrpc/WebThreeStubClient.h +++ b/test/unittests/libweb3jsonrpc/WebThreeStubClient.h @@ -160,6 +160,7 @@ class WebThreeStubClient : public jsonrpc::Client { const Json::Value& param3 ) noexcept( false ); Json::Value debug_doStateDbCompaction() noexcept( false ); Json::Value debug_doBlocksDbCompaction() noexcept( false ); + Json::Value debug_getFutureTransactions() noexcept( false ); }; #endif // JSONRPC_CPP_STUB_WEBTHREESTUBCLIENT_H_ diff --git a/test/unittests/libweb3jsonrpc/jsonrpc.cpp b/test/unittests/libweb3jsonrpc/jsonrpc.cpp index 7640a5b24..26e2c893c 100644 --- a/test/unittests/libweb3jsonrpc/jsonrpc.cpp +++ b/test/unittests/libweb3jsonrpc/jsonrpc.cpp @@ -2878,23 +2878,40 @@ BOOST_AUTO_TEST_CASE( mtm_import_future_txs ) { BOOST_REQUIRE( h1 ); BOOST_REQUIRE_EQUAL( tq->futureSize(), 1); + Json::Value call = fixture.rpcClient->debug_getFutureTransactions(); + BOOST_REQUIRE_EQUAL( call.size(), 1); + h256 h2 = fixture.client->importTransaction( tx3 ); BOOST_REQUIRE( h2 ); BOOST_REQUIRE_EQUAL( tq->futureSize(), 2); + + call = fixture.rpcClient->debug_getFutureTransactions(); + BOOST_REQUIRE_EQUAL( call.size(), 2); + BOOST_REQUIRE_EQUAL( call[0]["from"], string("0x")+txJson["from"].asString() ); + h256 h3 = fixture.client->importTransaction( tx2 ); BOOST_REQUIRE( h3 ); BOOST_REQUIRE_EQUAL( tq->futureSize(), 3); + call = fixture.rpcClient->debug_getFutureTransactions(); + BOOST_REQUIRE_EQUAL( call.size(), 3); + h256 h4 = fixture.client->importTransaction( tx1 ); BOOST_REQUIRE( h4 ); BOOST_REQUIRE_EQUAL( tq->futureSize(), 1); BOOST_REQUIRE_EQUAL( tq->status().current, 3); + call = fixture.rpcClient->debug_getFutureTransactions(); + BOOST_REQUIRE_EQUAL( call.size(), 1); + h256 h5 = fixture.client->importTransaction( tx4 ); BOOST_REQUIRE( h5 ); BOOST_REQUIRE_EQUAL( tq->futureSize(), 0); BOOST_REQUIRE_EQUAL( tq->status().current, 5); + call = fixture.rpcClient->debug_getFutureTransactions(); + BOOST_REQUIRE_EQUAL( call.size(), 0); + fixture.client->skaleHost()->pauseConsensus( false ); }