feat: rpc submitchainlock short circuit if possible and always return… (#5806)

… best height

## Issue being fixed or feature implemented
Platform wants to know the height of the bestchainlock when they call
submitchainlock; sooo we change the API of submitchainlock to also
return the height

## What was done?
Adjust API and tests

## How Has This Been Tested?
New tests added for this behavior

## Breaking Changes
Not really any; I **guess** that return value could be considered
breaking change; but going from nothing -> something feels unlikely to
break anything although it in theory could.

## Checklist:
_Go over all the following points, and put an `x` in all the boxes that
apply._
- [ ] 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: UdjinM6 <UdjinM6@users.noreply.github.com>
Co-authored-by: Konstantin Akimov <knstqq@gmail.com>
This commit is contained in:
PastaPastaPasta 2024-02-01 10:14:59 -06:00 committed by GitHub
parent 1ec18b9ba8
commit d40ac79d4d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 17 additions and 4 deletions

View File

@ -0,0 +1,7 @@
RPC Changes
-----------
### `submitchainlock` RPC method updates
- **Return Value Addition**: The method now returns the height of the current best ChainLock, allowing clients to easily compare the provided ChainLock height with the current best one.
- **Error Handling**: Added a check for the provided block height. If the block height is not greater than the height of the current best ChainLock, the method will return the best ChainLock's height without attempting to process a new ChainLock.
- **Code Optimization**: Refactored the retrieval of the `LLMQContext` and the best ChainLock's height to occur before the signature validation. This change streamlines the logic and potentially reduces redundant computations when the provided block height is already known to be not the best.

View File

@ -1050,7 +1050,8 @@ static void submitchainlock_help(const JSONRPCRequest& request)
{"signature", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The signature of the ChainLock."},
{"blockHeight", RPCArg::Type::NUM, RPCArg::Optional::NO, "The height of the ChainLock."},
},
RPCResults{},
RPCResult{
RPCResult::Type::NUM, "", "The height of the current best ChainLock"},
RPCExamples{""},
}.Check(request);
}
@ -1065,6 +1066,9 @@ static UniValue submitchainlock(const JSONRPCRequest& request)
if (nBlockHeight <= 0) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid block height");
}
const LLMQContext& llmq_ctx = EnsureLLMQContext(EnsureAnyNodeContext(request.context));
const int32_t bestCLHeight = llmq_ctx.clhandler->GetBestChainLock().getHeight();
if (nBlockHeight <= bestCLHeight) return bestCLHeight;
CBLSSignature sig;
if (!sig.SetHexStr(request.params[1].get_str(), false) && !sig.SetHexStr(request.params[1].get_str(), true)) {
@ -1072,14 +1076,13 @@ static UniValue submitchainlock(const JSONRPCRequest& request)
}
const LLMQContext& llmq_ctx = EnsureLLMQContext(EnsureAnyNodeContext(request.context));
auto clsig = llmq::CChainLockSig(nBlockHeight, nBlockHash, sig);
if (!llmq_ctx.clhandler->VerifyChainLock(clsig)) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid signature");
}
llmq_ctx.clhandler->ProcessNewChainLock(-1, clsig, ::SerializeHash(clsig));
return true;
return llmq_ctx.clhandler->GetBestChainLock().getHeight();
}

View File

@ -119,7 +119,10 @@ class LLMQChainLocksTest(DashTestFramework):
assert best_0['height'] != best_1['height']
assert best_0['signature'] != best_1['signature']
assert_equal(best_0['known_block'], True)
self.nodes[0].submitchainlock(best_1['blockhash'], best_1['signature'], best_1['height'])
node_height = self.nodes[1].submitchainlock(best_0['blockhash'], best_0['signature'], best_0['height'])
rpc_height = self.nodes[0].submitchainlock(best_1['blockhash'], best_1['signature'], best_1['height'])
assert_equal(best_1['height'], node_height)
assert_equal(best_1['height'], rpc_height)
best_0 = self.nodes[0].getbestchainlock()
assert_equal(best_0['blockhash'], best_1['blockhash'])
assert_equal(best_0['height'], best_1['height'])