mempoolbridge.h raw

   1  // Copyright (c) 2026 The Limenka developers
   2  // Distributed under the MIT software license, see the accompanying
   3  // file COPYING or http://www.opensource.org/licenses/mit-license.php.
   4  
   5  #ifndef LIMENKA_NODE_MEMPOOLBRIDGE_H
   6  #define LIMENKA_NODE_MEMPOOLBRIDGE_H
   7  
   8  #include <kernel/messagestartchars.h>
   9  #include <netaddress.h>
  10  #include <primitives/transaction.h>
  11  #include <protocol.h>
  12  #include <sync.h>
  13  #include <validationinterface.h>
  14  
  15  #include <atomic>
  16  #include <map>
  17  #include <memory>
  18  #include <mutex>
  19  #include <optional>
  20  #include <set>
  21  #include <thread>
  22  #include <vector>
  23  
  24  namespace node {
  25  class NodeContext;
  26  } // namespace node
  27  namespace boost::asio { class io_context; }
  28  
  29  namespace node {
  30  
  31  // A foreign bitcoin-protocol network the bridge gossips with.
  32  struct BridgeNetwork {
  33      std::string name;
  34      MessageStartChars magic{};
  35      uint16_t default_port{0};
  36      std::vector<CService> peers;
  37  };
  38  
  39  /** Cross-chain mempool gossip bridge.
  40   *
  41   * Connects limenka to foreign bitcoin-protocol networks (spamchain
  42   * mainnet, blakecoin, whatever else forks from the same transaction
  43   * format) and unifies their mempools: transactions received from a
  44   * foreign peer are validated under limenka rules and enter the limenka
  45   * mempool; transactions entering the limenka mempool (local or foreign)
  46   * are announced to every foreign network.  Blocks and headers are never
  47   * requested or relayed - only transaction gossip crosses the boundary,
  48   * so the fork's consensus is untouched while the transaction flow can no
  49   * longer be separated from the parent chain's.
  50   *
  51   * Transactions that fail limenka validation (e.g. from a network whose
  52   * UTXO root differs, like blakecoin's testnet4 lab) are logged and
  53   * dropped, never forwarded - announcing invalid transactions would only
  54   * get the bridge banned from the destination network.
  55   */
  56  class MempoolBridge final : public CValidationInterface,
  57                              public std::enable_shared_from_this<MempoolBridge>
  58  {
  59  public:
  60      explicit MempoolBridge(node::NodeContext& node);
  61      ~MempoolBridge();
  62  
  63      // Parse a "-bridgepeer=net:host[:port]" argument.
  64      static std::optional<std::pair<std::string, CService>> ParseBridgePeer(const std::string& spec);
  65  
  66      bool Start(const std::vector<std::string>& peer_specs);
  67      void Stop();
  68  
  69      // CValidationInterface
  70      void TransactionAddedToMempool(const NewMempoolTransactionInfo& tx, uint64_t mempool_sequence) override;
  71  
  72  private:
  73      class Peer;
  74  
  75      node::NodeContext& m_node;
  76      std::unique_ptr<boost::asio::io_context> m_io;
  77      std::thread m_thread;
  78      std::atomic<bool> m_running{false};
  79  
  80      mutable RecursiveMutex m_net_mutex;
  81      std::vector<BridgeNetwork> m_networks GUARDED_BY(m_net_mutex);
  82      std::vector<std::shared_ptr<Peer>> m_peers GUARDED_BY(m_net_mutex);
  83  
  84      // wtxids already announced per network (loop suppression).
  85      mutable RecursiveMutex m_seen_mutex;
  86      std::map<std::string, std::set<uint256>> m_seen GUARDED_BY(m_seen_mutex);
  87  
  88      // Foreign transactions received (served back via getdata).
  89      mutable RecursiveMutex m_cache_mutex;
  90      std::map<uint256, CTransactionRef> m_tx_cache GUARDED_BY(m_cache_mutex);
  91  
  92      void OnForeignTx(const std::string& from_network, CTransactionRef tx);
  93      void AnnounceToNetwork(const BridgeNetwork& net, const CTransactionRef& tx, const uint256& wtxid);
  94      bool NoteSeen(const std::string& network, const uint256& wtxid);
  95      void MaintainConnections();
  96  
  97      // Transaction lookup for getdata serving (bridge cache + limenka mempool).
  98      bool HasTx(const uint256& hash) const;
  99      CTransactionRef GetTx(const uint256& hash) const;
 100  };
 101  
 102  } // namespace node
 103  
 104  #endif // LIMENKA_NODE_MEMPOOLBRIDGE_H
 105