test: fix intermittent failure in wallet_resendwallettransactions.py #28108

pull mzumsande wants to merge 1 commits into bitcoin:master from mzumsande:202307_resend_fix changing 1 files +6 −2
  1. mzumsande commented at 6:35 PM on July 19, 2023: contributor

    Fixes #28094

    The test bumps the mocktime for ~2 weeks and then triggers eviction from the mempool. But this bump will also cause a new resubmit, and if the timing is such that this resubmit happens right after the eviction and before the check that the tx was evicted, the test can fail as in #28094:

    node0 2023-07-17T21:31:23.809483Z (mocktime: 2023-08-02T09:46:27Z) [httpworker.1] [validation.cpp:267] [LimitMempoolSize] [mempool] Expired 2 transactions from the memory pool
    node0 2023-07-17T21:31:23.810079Z (mocktime: 2023-08-02T09:46:27Z) [scheduler] [wallet/wallet.h:895] [WalletLogPrintf] [default wallet] ResubmitWalletTransactions: resubmit 2 unconfirmed transactions
    node0 2023-07-17T21:31:23.810474Z (mocktime: 2023-08-02T09:46:27Z) [httpworker.2] [rpc/request.cpp:181] [parse] [rpc] ThreadRPCServer method=getmempoolentry user=__cookie__ 
    2023-07-17T21:31:23.811000Z TestFramework (ERROR): Assertion failed (...) AssertionError: No exception raised
    

    Fix this by flushing out the current resubmit call before triggering mempool eviction.

  2. test: fix intermittent failure in wallet_resendwallettransactions.py
    Before, it was possible that a resend was triggered right between
    eviction the txns from the mempool and the check that they were evicted.
    e667bd68a1
  3. DrahtBot commented at 6:35 PM on July 19, 2023: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

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

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    ACK jonatack, MarcoFalke, achow101

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

  4. DrahtBot added the label Tests on Jul 19, 2023
  5. in test/functional/wallet_resendwallettransactions.py:117 in e667bd68a1
     114 | +        # Flush out currently scheduled resubmit attempt now so that there can't be one right between eviction and check.
     115 | +        with node.assert_debug_log(['resubmit 2 unconfirmed transactions']):
     116 | +            node.setmocktime(evict_time)
     117 | +            node.mockscheduler(60)
     118 | +
     119 | +        # Evict these txs from the mempool
    


    jonatack commented at 7:10 PM on July 19, 2023:

    <details><summary>Some doc and logging ideas after a cursory look, feel free to ignore</summary><p>

    @@ -109,21 +109,22 @@ class ResendWalletTransactionsTest(BitcoinTestFramework):
             node.syncwithvalidationinterfacequeue()
     
             evict_time = block_time + 60 * 60 * DEFAULT_MEMPOOL_EXPIRY_HOURS + 5
    -        # Flush out currently scheduled resubmit attempt now so that there can't be one right between eviction and check.
    +
    +        self.log.info("Flush out currently scheduled resubmit attempt now so there cannot be one between eviction and check")
             with node.assert_debug_log(['resubmit 2 unconfirmed transactions']):
                 node.setmocktime(evict_time)
    -            node.mockscheduler(60)
    +            node.mockscheduler(60)  # Tell scheduler to call MaybeResendWalletTxs now
     
    -        # Evict these txs from the mempool
    +        self.log.info("Evict these txs from the mempool")
             indep_send = node.send(outputs=[{node.getnewaddress(): 1}], inputs=[indep_utxo])
             node.getmempoolentry(indep_send["txid"])
             assert_raises_rpc_error(-5, "Transaction not in mempool", node.getmempoolentry, txid)
             assert_raises_rpc_error(-5, "Transaction not in mempool", node.getmempoolentry, child_txid)
     
    -        # Rebroadcast and check that parent and child are both in the mempool
    +        self.log.info("Rebroadcast and check that parent and child are both in the mempool")
             with node.assert_debug_log(['resubmit 2 unconfirmed transactions']):
                 node.setmocktime(evict_time + 36 * 60 * 60) # 36 hrs is the upper limit of the resend timer
    -            node.mockscheduler(60)
    +            node.mockscheduler(60)  # Tell scheduler to call MaybeResendWalletTxs now
             node.getmempoolentry(txid)
             node.getmempoolentry(child_txid)
    
    

    </p></details>

  6. jonatack commented at 7:13 PM on July 19, 2023: contributor

    Light "this looks like the other tests in this file" ACK e667bd68a10512ddc784df44bdcb63ee441e5551

  7. maflcko commented at 5:45 AM on July 20, 2023: member

    Nice. lgtm ACK e667bd68a10512ddc784df44bdcb63ee441e5551

  8. in test/functional/wallet_resendwallettransactions.py:113 in e667bd68a1
     107 | @@ -108,9 +108,13 @@ def run_test(self):
     108 |          # Set correct m_best_block_time, which is used in ResubmitWalletTransactions
     109 |          node.syncwithvalidationinterfacequeue()
     110 |  
     111 | -        # Evict these txs from the mempool
     112 |          evict_time = block_time + 60 * 60 * DEFAULT_MEMPOOL_EXPIRY_HOURS + 5
     113 | -        node.setmocktime(evict_time)
     114 | +        # Flush out currently scheduled resubmit attempt now so that there can't be one right between eviction and check.
     115 | +        with node.assert_debug_log(['resubmit 2 unconfirmed transactions']):
    


    maflcko commented at 5:56 AM on July 20, 2023:

    Generally I am not really a fan of using assert_debug_log to sync. If you do, my preference would be to use the timeout argument. Even better would be to sync inside the body. Either with a call to syncwithvalidationinterfaceque or by modifying the RPC:

    diff --git a/src/rpc/node.cpp b/src/rpc/node.cpp
    index 3828401642..f614253195 100644
    --- a/src/rpc/node.cpp
    +++ b/src/rpc/node.cpp
    @@ -93,6 +93,7 @@ static RPCHelpMan mockscheduler()
         // protect against null pointer dereference
         CHECK_NONFATAL(node_context->scheduler);
         node_context->scheduler->MockForward(std::chrono::seconds(delta_seconds));
    +    SyncWithValidationInterfaceQueue();
     
         return UniValue::VNULL;
     },
    

    Otherwise, if someone removes the log, the test may fail again if the scheduler queue has several entries.


    maflcko commented at 1:11 PM on July 21, 2023:
  9. maflcko commented at 5:57 AM on July 20, 2023: member

    left a follow-up idea

  10. achow101 commented at 3:32 PM on July 20, 2023: member

    ACK e667bd68a10512ddc784df44bdcb63ee441e5551

  11. achow101 merged this on Jul 20, 2023
  12. achow101 closed this on Jul 20, 2023

  13. mzumsande deleted the branch on Jul 20, 2023
  14. mzumsande commented at 4:53 PM on July 20, 2023: contributor

    I didn't get to address the suggestions by @jonatack and @MarcoFalke in time - they make sense to me and could be done in a separate PR that reworks the test a bit deeper than just fixing the timeout - just noting that I'm probably not going to get to this, at least for the next couple of weeks.

  15. sidhujag referenced this in commit cfa97c3f82 on Jul 21, 2023
  16. bitcoin locked this on Jul 21, 2024

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: 2026-04-17 03:13 UTC

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