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