Skip to content

Added RPC method `getdsproofscore`

Summary

This new method is intended to address and close #307 (closed). The new RPC takes a txid as its only argument and returns a number from 0.0 to 1.0.

  • 1.0 indicates no dsproofs exist for this tx or for any of its ancestors, but that it and all in-mempool ancestors can have a dsproof, so confidence should be high that the tx is ok.
  • 0.0 indicates that either this tx or one of its ancestors has a dsproof, or that it or one of its in-mempool ancestors can never have a proof (not P2PKH) -- so confidence should be low.
  • 0.25 is returned in the case where the tx has so many mempool ancestors that no conclusive determination could be made (but the ones that were checked are ok).
  • If txid doesn't exist in the mempool, the usual JSONRPCError is thrown (similar to how other RPCs work).

Code Changed

  • Refactored out the code from compressor.cpp that checked for p2pkh and p2sh and ensured this code (which was somewhat duplicated) all lives in CScript and is publicly accessible.
  • Added a static function checkIsProofPossibleForAllInputsOfTx to the DoubleSpendProof class, which basically answers the question: "is this tx itself eligible for a double-spend proof"?
  • Added the getdsproofscore RPC method to rpc/dsproof.cpp
  • Modified CTxMemPool::recursiveDSPSearch to be able to answer the "score" question we need for the getdsproofscore RPC.
    • Refactored CTxMemPool::recursiveDSPSearch and its helper to be a bit faster by working with txiter directly.
    • Added an additional constraint: in addition to the 1000 max-deep ancestor chain constraint, we also cannot examine more than 20k total ancestors. This ensures the RPC doesn't go out to lunch for too long and has a finite execution time that is bounded nicely, even in pathological cases. In this corner case an "inconclusive" score of 0.25 is returned by the RPC.
  • Fixup: compressor.cpp had questionable/UB use of memcpy
    • Fixed to not write to uint160 directly as if it were a simple C array .. but rather write to its .begin() using std::memcpy. This is not UB, whereas the previous code technically was.
    • Also renamed memcpy -> std::memcpy, and included the right header.
  • Added C++ unit tests for: CScript::IsPayToPubKeyHash and DoubleSpendProof::checkIsProofPossibleForAllInputsOfTx
  • Added Python functional testing of getdsproofscore

Task List

  • Add documentation to release-notes, etc.
  • Add functional tests

Test Plan

  • ninja all check && test/functional/test_runner.py bchn-rpc-dsproof
Edited by Calin Culianu

Merge request reports