diff --git a/src/avalanche.h b/src/avalanche.h --- a/src/avalanche.h +++ b/src/avalanche.h @@ -351,4 +351,9 @@ friend struct AvalancheTest; }; +/** + * Global avalanche instance. + */ +extern std::unique_ptr<AvalancheProcessor> g_avalanche; + #endif // BITCOIN_AVALANCHE_H diff --git a/src/avalanche.cpp b/src/avalanche.cpp --- a/src/avalanche.cpp +++ b/src/avalanche.cpp @@ -23,6 +23,10 @@ */ static const size_t AVALANCHE_MAX_ELEMENT_POLL = 4096; +// Unfortunately, the bitcoind codebase is full of gloabl and we are kinda +// forced into it here. +std::unique_ptr<AvalancheProcessor> g_avalanche; + bool VoteRecord::registerVote(NodeId nodeid, uint32_t error) { // We just got a new vote, so there is one less inflight request. clearInflightRequest(); diff --git a/src/init.cpp b/src/init.cpp --- a/src/init.cpp +++ b/src/init.cpp @@ -11,6 +11,7 @@ #include <addrman.h> #include <amount.h> +#include <avalanche.h> #include <banman.h> #include <chain.h> #include <chainparams.h> @@ -153,6 +154,11 @@ InterruptREST(); InterruptTorControl(); InterruptMapPort(); + if (g_avalanche) { + // Avalanche needs to be stopped before we interrupt the thread group as + // the scheduler will stop working then. + g_avalanche->stopEventLoop(); + } if (g_connman) { g_connman->Interrupt(); } @@ -185,6 +191,14 @@ } StopMapPort(); + // Because avalanche and the network depend on each other, it is important + // to shut them down in that order: + // 1. Stop avalanche event loop. + // 2. Shutdown network processing. + // 3. Destroy AvalancheProcessor. + // 4. Destroy CConnman + g_avalanche->stopEventLoop(); + // Because these depend on each-other, we make sure that neither can be // using the other before destroying them. if (peerLogic) { @@ -207,6 +221,9 @@ // After the threads that potentially access these pointers have been // stopped, destruct and reset all to nullptr. peerLogic.reset(); + + // Destroy various global instances + g_avalanche.reset(); g_connman.reset(); g_banman.reset(); g_txindex.reset(); @@ -1953,9 +1970,9 @@ config, GetRand(std::numeric_limits<uint64_t>::max()), GetRand(std::numeric_limits<uint64_t>::max())); - peerLogic.reset(new PeerLogicValidation( + peerLogic = std::make_unique<PeerLogicValidation>( g_connman.get(), g_banman.get(), scheduler, - gArgs.GetBoolArg("-enablebip61", DEFAULT_ENABLE_BIP61))); + gArgs.GetBoolArg("-enablebip61", DEFAULT_ENABLE_BIP61)); RegisterValidationInterface(peerLogic.get()); // sanitize comments per BIP-0014, format user agent and check total size @@ -2084,6 +2101,9 @@ 1024; } + // Setp 6.5 (I guess ?): Initialize Avalanche. + g_avalanche = std::make_unique<AvalancheProcessor>(g_connman.get()); + // Step 7: load block chain fReindex = gArgs.GetBoolArg("-reindex", false); @@ -2499,5 +2519,8 @@ }, DUMP_BANS_INTERVAL * 1000); + // Start Avalanche's event loop. + g_avalanche->startEventLoop(scheduler); + return true; }