rpc: Add importmempool RPC #27460

pull maflcko wants to merge 4 commits into bitcoin:master from maflcko:2304-import-mempool-rpc- changing 11 files +160 −32
  1. maflcko commented at 11:19 am on April 13, 2023: member

    Currently it is possible to import a mempool by placing it in the datadir and starting the node. However this has many issues:

    • Users aren’t expected to fiddle with the datadir, possibly corrupting it
    • An existing mempool file in the datadir may be overwritten
    • The node needs to be restarted
    • Importing an untrusted file this way is dangerous, because it can corrupt the mempool

    Fix all issues by adding a new RPC.

  2. DrahtBot commented at 11:19 am on April 13, 2023: contributor

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    Reviews

    See the guideline for information on the review process.

    If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #28207 (mempool: Persist with XOR by MarcoFalke)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

  3. DrahtBot renamed this:
    rpc: Add importmempool RPC
    rpc: Add importmempool RPC
    on Apr 13, 2023
  4. DrahtBot added the label RPC/REST/ZMQ on Apr 13, 2023
  5. ghost commented at 5:23 pm on April 13, 2023: none

    Hi @MarcoFalke

    More than 5 tests are failing

  6. maflcko force-pushed on Apr 13, 2023
  7. maflcko commented at 5:56 pm on April 13, 2023: member
    I changed the approach to force named RPC options, compatible with https://github.com/bitcoin/bitcoin/pull/26485
  8. in src/rpc/mempool.cpp:747 in d31a87fd0f outdated
    742+                  "mempool state."},
    743+             },
    744+             RPCArgOptions{.oneline_description = "\"options\""}},
    745+        },
    746+        RPCResult{RPCResult::Type::OBJ, "", "", std::vector<RPCResult>{}},
    747+        RPCExamples{HelpExampleCli("importmempool", "") + HelpExampleRpc("importmempool", "")},
    


    kevkevinpal commented at 6:32 pm on April 13, 2023:

    would it make sense to add a ./pathto/mempool.dat to the example param because right now when I type bitcoin-cli importmempool

    I get

    0Examples:
    1> bitcoin-cli importmempool
    2> curl --user myusername --data-binary '{"jsonrpc": "1.0", "id": "curltest", "method": "importmempool", "params": []}' -H 'content-type: text/plain;' http://127.0.0.1:8332/
    

    This might be confusing

    0        RPCExamples{HelpExampleCli("importmempool", "./pathto/mempool.dat") + HelpExampleRpc("importmempool", "./pathto/mempool.dat")},
    

    maflcko commented at 3:00 pm on April 14, 2023:
    thx, done
  9. kevkevinpal commented at 7:22 pm on April 13, 2023: contributor

    Concept ACK 846ff37fe7ac2a5b4f855faaadb3434158ed6364 (need to check latest commit)

    tested by doing the following in regtest

    bitcoin-cli createwallet "testwallet" bitcoin-cli getnewaddress bitcoin-cli generateto address 6 <previous commands output> bitcoin-cli generate 20 (did this a couple times) bitcoin-cli getbalance (validate you have a balance) bitcoin-cli getnewaddress bitcoin-cli send '{"<above output>": 0.1}' null "unset" null '{"fee_rate": 1}' (did this a few times)

    shutdown bitcoind copy mempool.dat from datadir to different location delete mempool.dat from datadir restart bitcoind bitcoin-cli importmempool ./mempool.dat

    Saw this in the logs 2023-04-13T19:12:01Z Imported mempool transactions from disk: 5 succeeded, 0 failed, 0 expired, 0 already there, 0 waiting for initial broadcast got {} as response from cli

    Might test again and check the exact values


    Checking diff of mempool.dat files

    did git diff ./datadir/regtest/mempool.dat mempool.dat and it gave me no changes in the vim editor to see but diff ./datadir/regtest/mempool.dat mempool.dat gave me Binary files ./datadir/regtest/mempool.dat and ./mempool.dat differ not sure if that matters

  10. in src/rpc/mempool.cpp:742 in d31a87fd0f outdated
    737+                  "Warning: Importing untrusted metadata may corrupt the mempool "
    738+                  "state."},
    739+                 {"apply_unbroadcast_set", RPCArg::Type::BOOL, RPCArg::Default{false},
    740+                  "Whether to apply the unbroadcast set metadata from the mempool file."
    741+                  "Warning: Importing untrusted metadata may corrupt the "
    742+                  "mempool state."},
    


    ajtowns commented at 4:50 am on April 14, 2023:
    Why would either of these “corrupt” the mempool state? They definitely might be undesirable (“unbroadcast” txs might reveal which node just loaded the mempool state, and “fee delta” may allow an attacker to pin txs to your mempool that will never be mined, or to get you to mine unprofitable txs), but the problems should be localised and not result in “corruption”, no?

    maflcko commented at 6:56 am on April 14, 2023:
    Yeah, happy to change the wording, if there is a suggestion I can copy-paste?

    maflcko commented at 6:59 am on April 14, 2023:
    Maybe "Warning: Importing untrusted metadata may lead to unexpected issues and undesirable bugs. Do not set this bool unless you understand exactly what it does."?

    ajtowns commented at 7:45 am on April 14, 2023:
    “undesirable behaviour” instead of bugs – this is a case of you telling it to do the wrong thing, so not really a bug? Otherwise sgtm.

    maflcko commented at 3:00 pm on April 14, 2023:
    thx, done
  11. in src/rpc/mempool.cpp:736 in d31a87fd0f outdated
    731+             RPCArg::Type::OBJ,
    732+             RPCArg::Optional::OMITTED,
    733+             "",
    734+             {
    735+                 {"apply_fee_delta_priority", RPCArg::Type::BOOL, RPCArg::Default{false},
    736+                  "Whether to apply the fee delta metadata from the mempool file. "
    


    ajtowns commented at 4:51 am on April 14, 2023:
    Maybe reference prioritisetransaction here explicitly?

    maflcko commented at 3:00 pm on April 14, 2023:
    thx, done
  12. in src/kernel/mempool_persist.h:24 in d31a87fd0f outdated
    23-                 Chainstate& active_chainstate,
    24-                 fsbridge::FopenFn mockable_fopen_function = fsbridge::fopen);
    25+struct ImportMempoolOptions {
    26+    fsbridge::FopenFn mockable_fopen_function{fsbridge::fopen};
    27+    bool apply_fee_delta_priority{true};
    28+    bool apply_unbroadcast_set{true};
    


    ajtowns commented at 6:15 am on April 14, 2023:

    Should this also include the ability to override the (added to the mempool) nTime data with the current time (or an explicitly nominated time)?

    Having a child transaction with an earlier nTime than its parent transaction might be confusing. I think the only way that can currently happen is with system/mock time shenanigans.


    maflcko commented at 3:02 pm on April 14, 2023:
    Just using the current time seems good enough. Might implement next week.

    maflcko commented at 4:50 pm on April 20, 2023:
    Done
  13. in src/rpc/mempool.cpp:726 in d31a87fd0f outdated
    718@@ -719,6 +719,56 @@ static RPCHelpMan getmempoolinfo()
    719     };
    720 }
    721 
    722+static RPCHelpMan importmempool()
    723+{
    724+    return RPCHelpMan{
    725+        "importmempool",
    726+        "Import the file and attempt to add its contents to the mempool.\n"
    


    ajtowns commented at 6:17 am on April 14, 2023:

    Change “the file” to “a mempool.dat file” ?

    Maybe reference the “savemempool” rpc as a way of updating mempool.dat with the current mempool?


    maflcko commented at 7:20 am on April 14, 2023:
    I guess it should also clarify that this is not a replacement for -persistmempool

    ajtowns commented at 7:46 am on April 14, 2023:
    (I more just meant “what the heck type of file do you want me to give it???”)

    maflcko commented at 3:00 pm on April 14, 2023:
    thx, done
  14. ajtowns commented at 6:21 am on April 14, 2023: contributor
    Approach ACK
  15. instagibbs commented at 1:29 pm on April 14, 2023: member
    concept ACK, will review
  16. in test/functional/mempool_persist.py:169 in d31a87fd0f outdated
    163+        assert_equal({}, self.nodes[0].importmempool(mempooldat0))
    164+        assert_equal(len(self.nodes[0].getrawmempool()), 7)
    165+        fees = self.nodes[0].getmempoolentry(txid=last_txid)["fees"]
    166+        assert_equal(fees["base"], fees["modified"])
    167+        assert_equal({}, self.nodes[0].importmempool(mempooldat0, {"apply_fee_delta_priority": True, "apply_unbroadcast_set": True}))
    168+        fees = self.nodes[0].getmempoolentry(txid=last_txid)["fees"]
    


    instagibbs commented at 2:10 pm on April 14, 2023:
    I’d like the test to load against two mempool files with differing txn subsets at least, showing that “additional” txs are loaded even if they weren’t there originally. Even better if they’re not strict subsets.

    maflcko commented at 3:01 pm on April 14, 2023:
    Might do next week/month, unless someone beats me to it


    maflcko commented at 3:29 pm on April 20, 2023:
    Nice, pushed your test
  17. maflcko force-pushed on Apr 14, 2023
  18. in src/kernel/mempool_persist.cpp:80 in 1ef7f7a512 outdated
    71@@ -73,7 +72,7 @@ bool LoadMempool(CTxMemPool& pool, const fs::path& load_path, Chainstate& active
    72             file >> nFeeDelta;
    73 
    74             CAmount amountdelta = nFeeDelta;
    75-            if (amountdelta) {
    76+            if (amountdelta && opts.apply_fee_delta_priority) {
    77                 pool.PrioritiseTransaction(tx->GetHash(), amountdelta);
    


    glozow commented at 5:11 pm on April 17, 2023:
    PrioritiseTransaction applies the delta on top, so if txmempool already has a tx prioritised + this mempool.dat contains priority for it, this will stack them instead of rewriting the existing priority. I don’t know if this is problematic, but probably good to keep in mind? (Wrote a test)

    maflcko commented at 3:26 pm on April 20, 2023:
    Correct. Do you want me to add it to the apply_fee_delta_priority doc?

    glozow commented at 3:31 pm on April 20, 2023:
    Sorry for being pedantic, yes please. Something like “fee delta priority from the file is added on top of any priority already present in the mempool”

    maflcko commented at 4:51 pm on April 20, 2023:
    thx, added doc
  19. glozow commented at 5:12 pm on April 17, 2023: member
    Concept ACK
  20. maflcko force-pushed on Apr 20, 2023
  21. maflcko force-pushed on Apr 20, 2023
  22. DrahtBot added the label CI failed on Apr 20, 2023
  23. DrahtBot removed the label CI failed on Apr 20, 2023
  24. svanstaa commented at 6:06 pm on April 26, 2023: none
    Why is use_current_time defaulting to true? As far as i understand, this would set all the broadcast times of the transactions in mempool.dat to the current time, effectively extending their lifetimes, to the point that (time-) expired txns would be dumped into the network again. So I would suggest defaulting the value to false, unless there is some rationale behind it that is not obvious.
  25. michaelfolkson commented at 6:21 pm on April 26, 2023: contributor

    Also while we’re sneaking PR review club questions on here what do people here use this for? I’m assuming it is useful for mempool dev work (specific details would be interesting) but I can’t imagine it is common for a user to want this.

    Concept ACK (the RPC approach seems superior assuming people are currently importing mempools without a RPC being available)

  26. maflcko commented at 7:41 am on April 27, 2023: member

    The use case would be wanting to sync both the chain and the mempool to include everything/most known by the network or one of your other nodes. This is trivially possible for the chain, however for the mempool it is not.

    One option would be to use the mempool P2P message type, or add a new message type. This would likely require lifting some restrictions or adding others to make it usable in a normal setting and still prevent privacy/DoS concerns. To what extent the existing mempool message type behavior can be modified will need to be considered in light of the discussion about its removal.

    Another option would be to use a new RPC to import a mempool. In light of people potentially loading untrusted mempool data, I opted to use the same mempool acceptance defaults that would be picked as if the transactions were synced/submitted over P2P.

  27. in test/functional/mempool_persist.py:167 in fab8b37025 outdated
    158@@ -159,6 +159,15 @@ def run_test(self):
    159         assert self.nodes[0].getmempoolinfo()["loaded"]
    160         assert_equal(len(self.nodes[0].getrawmempool()), 0)
    161 
    162+        self.log.debug("Import mempool at runtime to node0.")
    163+        assert_equal({}, self.nodes[0].importmempool(mempooldat0))
    164+        assert_equal(len(self.nodes[0].getrawmempool()), 7)
    165+        fees = self.nodes[0].getmempoolentry(txid=last_txid)["fees"]
    166+        assert_equal(fees["base"], fees["modified"])
    167+        assert_equal({}, self.nodes[0].importmempool(mempooldat0, {"apply_fee_delta_priority": True, "apply_unbroadcast_set": True}))
    


    ismaelsadeeq commented at 9:58 am on April 27, 2023:

    Approach ACK I think here since “apply_unbroadcast_set”: True` option is added, we should test mempool unbroadcast set list, else there would be no need for the second option.

    0        assert_equal({}, self.nodes[0].importmempool(mempooldat0, {"apply_fee_delta_priority": True, "apply_unbroadcast_set": True}))
    1        assert_equal(2, self.nodes[0].getmempoolinfo()['unbroadcastcount'])
    

    maflcko commented at 12:08 pm on May 17, 2023:
    Thanks, rebased and fixed up the nit
  28. DrahtBot added the label CI failed on May 17, 2023
  29. svanstaa commented at 11:51 am on May 17, 2023: none
    Concept ACK
  30. DrahtBot removed the label CI failed on May 17, 2023
  31. maflcko force-pushed on May 17, 2023
  32. kristapsk commented at 12:11 pm on May 17, 2023: contributor
    Concept ACK
  33. maflcko force-pushed on May 17, 2023
  34. DrahtBot added the label CI failed on May 17, 2023
  35. DrahtBot removed the label CI failed on May 17, 2023
  36. glozow commented at 3:08 pm on May 19, 2023: member
    ACK fa83be1c30d5b181c024a40bfb9d5ea15ce64aec
  37. mzumsande commented at 3:23 am on May 22, 2023: contributor
    Should the rpc be executable before the mempool load from ThreadImport has finished? I tried importing another mempool before the mempool from the datadir had finished loading, and I didn’t encounter any problems on first sight - but I’m not sure how useful that would be and I guess the final result would be dependent on races between the two mempools being loaded in parallel?
  38. maflcko commented at 10:14 am on May 22, 2023: member

    Should the rpc be executable before the mempool load from ThreadImport has finished?

    I’d say yes, because the transaction may also arrive via the P2P interface before the persisted mempool is loaded. (The RPC interface is designed to mimic the P2P one).

    However, a better check may be to refuse loading a mempool while in IBD? It seems better to error early instead of silently throwing away transactions that can not be applied to the current tip, because it is too old.

  39. DrahtBot added the label CI failed on May 26, 2023
  40. DrahtBot added the label Needs rebase on May 30, 2023
  41. maflcko force-pushed on Jun 9, 2023
  42. maflcko force-pushed on Jun 9, 2023
  43. DrahtBot removed the label Needs rebase on Jun 9, 2023
  44. DrahtBot removed the label CI failed on Jun 9, 2023
  45. maflcko commented at 11:05 am on June 9, 2023: member
    Added check for IBD
  46. DrahtBot added the label Needs rebase on Jul 6, 2023
  47. maflcko force-pushed on Jul 8, 2023
  48. DrahtBot removed the label Needs rebase on Jul 8, 2023
  49. in src/validation.cpp:4135 in fab7fe377d outdated
    4079@@ -4079,7 +4080,10 @@ void PruneBlockFilesManual(Chainstate& active_chainstate, int nManualPruneHeight
    4080 void Chainstate::LoadMempool(const fs::path& load_path, FopenFn mockable_fopen_function)
    4081 {
    4082     if (!m_mempool) return;
    4083-    ::ImportMempool(*m_mempool, load_path, *this, mockable_fopen_function);
    4084+    ImportMempool(*m_mempool, load_path, *this,
    4085+                  ImportMempoolOptions{
    4086+                      .mockable_fopen_function = std::move(mockable_fopen_function),
    


    ajtowns commented at 5:17 am on July 20, 2023:
    The default for ImportMempoolOptions::mockable_fopen_function isn’t actually used anywhere since LoadMempool overrides it. Maybe drop LoadMempool entirely and call kernel::ImportMempool directly from init.cpp and the fuzz test?

    maflcko commented at 9:52 am on August 7, 2023:
    thx, done
  50. in src/rpc/mempool.cpp:767 in fa43613bb9 outdated
    762+            const fs::path load_path{fs::u8path(request.params[0].get_str())};
    763+            const UniValue& use_current_time{request.params[1]["use_current_time"]};
    764+            const UniValue& apply_fee_delta{request.params[1]["apply_fee_delta_priority"]};
    765+            const UniValue& apply_unbroadcast{request.params[1]["apply_unbroadcast_set"]};
    766+            kernel::ImportMempoolOptions opts{
    767+                .use_current_time = use_current_time.isNull() ? true : use_current_time.get_bool(),
    


    ajtowns commented at 5:28 am on July 20, 2023:

    Might be worth adding a helper for the isNull ? default : get_native() pattern?

    0template<typename T>
    1T RPCDefaultArg(const UniValue&, T default);
    2template<>
    3bool RPCDefaultArg(const UniValue& uv, bool default) { return uv.isNull() ? default : uv.get_bool(); }
    4
    5const auto use_current_time = RPCDefaultArg<bool>(request.params[1]["use_current_time"], true);
    

    maflcko commented at 9:52 am on August 7, 2023:
    Maybe submit a pull with your suggestion applied to another RPC? Once and if it is merged, I could rebase this one.

    maflcko commented at 11:17 am on August 7, 2023:
  51. DrahtBot added the label Needs rebase on Jul 31, 2023
  52. maflcko force-pushed on Aug 1, 2023
  53. DrahtBot removed the label Needs rebase on Aug 1, 2023
  54. Remove Chainstate::LoadMempool
    The 3-line function is only called once outside of tests, so it is
    clearer to inline it.
    6888886cec
  55. doc: Clarify the getmempoolinfo.loaded RPC field documentation
    Also, clarify the LoadMempool doxygen.
    fa8866990d
  56. refactor: Add and use kernel::ImportMempoolOptions
    This allows optional named arguments with default values.
    fa20d734a2
  57. Add importmempool RPC
    test_importmempool_union contributed by glozow
    
    Co-authored-by: glozow <gloriajzhao@gmail.com>
    fa776e61cd
  58. maflcko force-pushed on Aug 7, 2023
  59. ajtowns commented at 11:54 am on August 7, 2023: contributor
    utACK fa776e61cd64a5ffd9a4be589ab8efeb5421861a
  60. DrahtBot requested review from glozow on Aug 7, 2023
  61. glozow commented at 12:58 pm on August 9, 2023: member
    reACK fa776e61cd64a5ffd9a4be589ab8efeb5421861a
  62. glozow requested review from mzumsande on Aug 9, 2023
  63. glozow requested review from instagibbs on Aug 9, 2023
  64. achow101 commented at 2:03 pm on August 15, 2023: member
    ACK fa776e61cd64a5ffd9a4be589ab8efeb5421861a
  65. achow101 merged this on Aug 15, 2023
  66. achow101 closed this on Aug 15, 2023

  67. maflcko deleted the branch on Aug 15, 2023
  68. sidhujag referenced this in commit 90fe85e6b9 on Aug 17, 2023
  69. mzumsande referenced this in commit 2394314442 on Aug 17, 2023
  70. fanquake referenced this in commit e4a855c4e0 on Aug 18, 2023
  71. Frank-GER referenced this in commit 0c4ff3e266 on Sep 8, 2023
  72. Retropex referenced this in commit a17140b6e6 on Oct 4, 2023
  73. Retropex referenced this in commit 5f62ed90f6 on Oct 4, 2023
  74. theStack referenced this in commit 19e99a0c53 on Oct 11, 2023
  75. fanquake commented at 6:12 pm on October 11, 2023: member
    Release notes added in #28637.

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2024-07-01 10:13 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me