feat(rpc): gettxchainlocks should return mempool=false when tx not in mempool (#5742)

## Issue being fixed or feature implemented
Platform (in the scope of Withdrawals) need to be aware if a tx isn't in
mempool when requesting status of a tx using RPC `gettxchainlocks`.
cc @markin-io

## What was done?

- mempool is passed to `GetTransaction` and saving the result for
checking latter.
- If the returned tx_ref is nullptr, then the RPC returns null for the
corresponding tx in the array.

Example: 
`tx1` is mined and chainlocked, `tx2` is in mempool and `tx3` doesn't
exist.
The result now is:
`[
  {
    "height": 830,
    "chainlock": false,
    "mempool": true
  },
  {
    "height": -1,
    "chainlock": false,
    "mempool": true
  },
  {
    "height": -1,
    "chainlock": false,
    "mempool": false
  }
]`

## How Has This Been Tested?


## Breaking Changes


## Checklist:
- [x] I have performed a self-review of my own code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have added or updated relevant unit/integration/functional/e2e
tests
- [ ] I have made corresponding changes to the documentation
- [x] I have assigned this pull request to a milestone _(for repository
code-owners and collaborators only)_

---------

Co-authored-by: Konstantin Akimov <knstqq@gmail.com>
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
This commit is contained in:
Odysseas Gabrielides 2023-12-24 19:58:14 +02:00 committed by GitHub
parent 563cc34b4e
commit 25cef45858
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 25 additions and 8 deletions

View File

@ -0,0 +1,4 @@
RPC changes
-----------
RPC `gettxchainlocks` will also return the status `mempool` indicating wether the transaction is in the mempool or not.

View File

@ -269,7 +269,7 @@ static UniValue gettxchainlocks(const JSONRPCRequest& request)
{
RPCHelpMan{
"gettxchainlocks",
"\nReturns the block height each transaction was mined at and whether it is chainlocked or not.\n",
"\nReturns the block height at which each transaction was mined, and indicates whether it is in the mempool, chainlocked, or neither.\n",
{
{"txids", RPCArg::Type::ARR, RPCArg::Optional::NO, "The transaction ids (no more than 100)",
{
@ -284,6 +284,7 @@ static UniValue gettxchainlocks(const JSONRPCRequest& request)
{
{RPCResult::Type::NUM, "height", "The block height"},
{RPCResult::Type::BOOL, "chainlock", "Chainlock status for the block containing the transaction"},
{RPCResult::Type::BOOL, "mempool", "Mempool status for the transaction"},
}},
}
},
@ -320,7 +321,15 @@ static UniValue gettxchainlocks(const JSONRPCRequest& request)
int height{-1};
bool chainLock{false};
GetTransaction(nullptr, nullptr, txid, Params().GetConsensus(), hash_block);
const auto tx_ref = GetTransaction(nullptr, node.mempool.get(), txid, Params().GetConsensus(), hash_block);
if (tx_ref == nullptr) {
result.pushKV("height", -1);
result.pushKV("chainlock", false);
result.pushKV("mempool", false);
result_arr.push_back(result);
continue;
}
if (!hash_block.IsNull()) {
LOCK(cs_main);
@ -334,6 +343,7 @@ static UniValue gettxchainlocks(const JSONRPCRequest& request)
}
result.pushKV("height", height);
result.pushKV("chainlock", chainLock);
result.pushKV("mempool", height == -1);
result_arr.push_back(result);
}
return result_arr;

View File

@ -22,6 +22,9 @@ class RPCVerifyChainLockTest(DashTestFramework):
self.set_dash_test_params(5, 3, [["-whitelist=127.0.0.1"], [], [], [], []], fast_dip3_enforcement=True)
self.set_dash_llmq_test_params(3, 2)
def cl_helper(self, height, chainlock, mempool):
return {'height': height, 'chainlock': chainlock, 'mempool': mempool}
def run_test(self):
node0 = self.nodes[0]
node1 = self.nodes[1]
@ -63,12 +66,12 @@ class RPCVerifyChainLockTest(DashTestFramework):
height1 = node1.getblockcount()
tx0 = node0.getblock(node0.getbestblockhash())['tx'][0]
tx1 = node1.getblock(node1.getbestblockhash())['tx'][0]
locks0 = node0.gettxchainlocks([tx0, tx1])
locks1 = node1.gettxchainlocks([tx0, tx1])
unknown_cl_helper = {'height': -1, 'chainlock': False}
assert_equal(locks0, [{'height': height, 'chainlock': True}, unknown_cl_helper])
assert_equal(locks1, [unknown_cl_helper, {'height': height1, 'chainlock': False}])
tx2 = node0.sendtoaddress(node0.getnewaddress(), 1)
locks0 = node0.gettxchainlocks([tx0, tx1, tx2])
locks1 = node1.gettxchainlocks([tx0, tx1, tx2])
unknown_cl_helper = self.cl_helper(-1, False, False)
assert_equal(locks0, [self.cl_helper(height, True, False), unknown_cl_helper, self.cl_helper(-1, False, True)])
assert_equal(locks1, [unknown_cl_helper, self.cl_helper(height1, False, False), unknown_cl_helper])
if __name__ == '__main__':
RPCVerifyChainLockTest().main()