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;
 }