txreconciliation.h raw

   1  // Copyright (c) 2022-present The Bitcoin Core 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 BITCOIN_NODE_TXRECONCILIATION_H
   6  #define BITCOIN_NODE_TXRECONCILIATION_H
   7  
   8  #include <net.h>
   9  #include <sync.h>
  10  
  11  #include <memory>
  12  #include <tuple>
  13  
  14  /** Supported transaction reconciliation protocol version */
  15  static constexpr uint32_t TXRECONCILIATION_VERSION{1};
  16  
  17  enum class ReconciliationRegisterResult {
  18      NOT_FOUND,
  19      SUCCESS,
  20      ALREADY_REGISTERED,
  21      PROTOCOL_VIOLATION,
  22  };
  23  
  24  /**
  25   * Transaction reconciliation is a way for nodes to efficiently announce transactions.
  26   * This object keeps track of all txreconciliation-related communications with the peers.
  27   * The high-level protocol is:
  28   * 0.  Txreconciliation protocol handshake.
  29   * 1.  Once we receive a new transaction, add it to the set instead of announcing immediately.
  30   * 2.  At regular intervals, a txreconciliation initiator requests a sketch from a peer, where a
  31   *     sketch is a compressed representation of short form IDs of the transactions in their set.
  32   * 3.  Once the initiator received a sketch from the peer, the initiator computes a local sketch,
  33   *     and combines the two sketches to attempt finding the difference in *sets*.
  34   * 4a. If the difference was not larger than estimated, see SUCCESS below.
  35   * 4b. If the difference was larger than estimated, initial txreconciliation fails. The initiator
  36   *     requests a larger sketch via an extension round (allowed only once).
  37   *     - If extension succeeds (a larger sketch is sufficient), see SUCCESS below.
  38   *     - If extension fails (a larger sketch is insufficient), see FAILURE below.
  39   *
  40   * SUCCESS. The initiator knows full symmetrical difference and can request what the initiator is
  41   *          missing and announce to the peer what the peer is missing.
  42   *
  43   * FAILURE. The initiator notifies the peer about the failure and announces all transactions from
  44   *          the corresponding set. Once the peer received the failure notification, the peer
  45   *          announces all transactions from their set.
  46  
  47   * This is a modification of the Erlay protocol (https://arxiv.org/abs/1905.10518) with two
  48   * changes (sketch extensions instead of bisections, and an extra INV exchange round), both
  49   * are motivated in BIP-330.
  50   */
  51  class TxReconciliationTracker
  52  {
  53  private:
  54      class Impl;
  55      const std::unique_ptr<Impl> m_impl;
  56  
  57  public:
  58      explicit TxReconciliationTracker(uint32_t recon_version);
  59      ~TxReconciliationTracker();
  60  
  61      /**
  62       * Step 0. Generates initial part of the state (salt) required to reconcile txs with the peer.
  63       * The salt is used for short ID computation required for txreconciliation.
  64       * The function returns the salt.
  65       * A peer can't participate in future txreconciliations without this call.
  66       * This function must be called only once per peer.
  67       */
  68      uint64_t PreRegisterPeer(NodeId peer_id);
  69  
  70      /**
  71       * Step 0. Once the peer agreed to reconcile txs with us, generate the state required to track
  72       * ongoing reconciliations. Must be called only after pre-registering the peer and only once.
  73       */
  74      ReconciliationRegisterResult RegisterPeer(NodeId peer_id, bool is_peer_inbound,
  75                                                uint32_t peer_recon_version, uint64_t remote_salt);
  76  
  77      /**
  78       * Attempts to forget txreconciliation-related state of the peer (if we previously stored any).
  79       * After this, we won't be able to reconcile transactions with the peer.
  80       */
  81      void ForgetPeer(NodeId peer_id);
  82  
  83      /**
  84       * Check if a peer is registered to reconcile transactions with us.
  85       */
  86      bool IsPeerRegistered(NodeId peer_id) const;
  87  };
  88  
  89  #endif // BITCOIN_NODE_TXRECONCILIATION_H
  90