fix: Allow tx index to catch up with the block index in TestChainSetup dtor (#5454)

## Issue being fixed or feature implemented
TL;DR: Should hopefully fix crashes like
https://gitlab.com/dashpay/dash/-/jobs/4522256293

In dashd we flush all callbacks first and then destroy `g_txindex`. In
tests we had to move `g_txindex` to `TestChainSetup` and its dtor is
executed first, so the order is broken. It also explains why this crash
happens so rare. In most cases tx index is up to date and you need some
kind of a hiccup for scheduler to lag behind a bit. Basically, between
`g_txindex.reset()` and `FlushBackgroundCallbacks`
`BaseIndex::BlockConnected` finally arrives. But it’s processed on a
(now) null instance hence a crash. If it’s earlier - it’s processed
normally, if it’s later - it’s flushed without execution, so there is a
tiny window to catch this crash.

## What was done?
Give tx index a bit of time to process everything

## How Has This Been Tested?
run tests (but this crash is rare 🤷‍♂️ )

## Breaking Changes
n/a

## Checklist:
- [x] I have performed a self-review of my own code
- [x] 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)_
This commit is contained in:
UdjinM6 2023-06-28 19:00:38 +03:00
parent f3dc889e93
commit 27e68397d0
No known key found for this signature in database
GPG Key ID: 83592BD1400D58D9

View File

@ -365,6 +365,15 @@ CBlock TestChainSetup::CreateBlock(const std::vector<CMutableTransaction>& txns,
TestChainSetup::~TestChainSetup()
{
// Allow tx index to catch up with the block index cause otherwise
// we might be destroying it while scheduler still has some work for it
// e.g. via BlockConnected signal
int64_t time_start = GetTimeMillis();
while (!g_txindex->BlockUntilSyncedToCurrentChain()) {
static constexpr int64_t timeout_ms = 10 * 1000;
assert(time_start + timeout_ms > GetTimeMillis());
UninterruptibleSleep(std::chrono::milliseconds{100});
}
g_txindex->Interrupt();
g_txindex->Stop();
g_txindex.reset();