aboutsummaryrefslogtreecommitdiff
path: root/src/net_processing.cpp
diff options
context:
space:
mode:
authorGleb Naumenko <naumenko.gs@gmail.com>2021-03-19 13:07:15 +0200
committerGleb Naumenko <naumenko.gs@gmail.com>2022-10-17 12:35:44 +0300
commit88d326c8e3796b9685c141fa50628615d3e43a38 (patch)
tree98bb2b47ec3bf6a0c5a62d5c59f346d34fee8a55 /src/net_processing.cpp
parent36cf6bf2168f9f154a652c91bbb96480c2e1d044 (diff)
p2p: Finish negotiating reconciliation support
Once we received a reconciliation announcement support message from a peer and it doesn't violate our protocol, we store the negotiated parameters which will be used for future reconciliations.
Diffstat (limited to 'src/net_processing.cpp')
-rw-r--r--src/net_processing.cpp54
1 files changed, 53 insertions, 1 deletions
diff --git a/src/net_processing.cpp b/src/net_processing.cpp
index af8afe235e..350187bdda 100644
--- a/src/net_processing.cpp
+++ b/src/net_processing.cpp
@@ -1782,7 +1782,7 @@ PeerManagerImpl::PeerManagerImpl(CConnman& connman, AddrMan& addrman,
// While Erlay support is incomplete, it must be enabled explicitly via -txreconciliation.
// This argument can go away after Erlay support is complete.
if (gArgs.GetBoolArg("-txreconciliation", DEFAULT_TXRECONCILIATION_ENABLE)) {
- m_txreconciliation = std::make_unique<TxReconciliationTracker>();
+ m_txreconciliation = std::make_unique<TxReconciliationTracker>(TXRECONCILIATION_VERSION);
}
}
@@ -3477,6 +3477,58 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
return;
}
+ // Received from a peer demonstrating readiness to announce transactions via reconciliations.
+ // This feature negotiation must happen between VERSION and VERACK to avoid relay problems
+ // from switching announcement protocols after the connection is up.
+ if (msg_type == NetMsgType::SENDTXRCNCL) {
+ if (!m_txreconciliation) {
+ LogPrintLevel(BCLog::NET, BCLog::Level::Debug, "sendtxrcncl from peer=%d ignored, as our node does not have txreconciliation enabled\n", pfrom.GetId());
+ return;
+ }
+
+ if (pfrom.fSuccessfullyConnected) {
+ // Disconnect peers that send a SENDTXRCNCL message after VERACK.
+ LogPrintLevel(BCLog::NET, BCLog::Level::Debug, "sendtxrcncl received after verack from peer=%d; disconnecting\n", pfrom.GetId());
+ pfrom.fDisconnect = true;
+ return;
+ }
+
+ if (!peer->GetTxRelay()) {
+ // Disconnect peers that send a SENDTXRCNCL message even though we indicated we don't
+ // support transaction relay.
+ LogPrintLevel(BCLog::NET, BCLog::Level::Debug, "sendtxrcncl received from peer=%d to which we indicated no tx relay; disconnecting\n", pfrom.GetId());
+ pfrom.fDisconnect = true;
+ return;
+ }
+
+ bool is_peer_initiator, is_peer_responder;
+ uint32_t peer_txreconcl_version;
+ uint64_t remote_salt;
+ vRecv >> is_peer_initiator >> is_peer_responder >> peer_txreconcl_version >> remote_salt;
+
+ if (m_txreconciliation->IsPeerRegistered(pfrom.GetId())) {
+ // A peer is already registered, meaning we already received SENDTXRCNCL from them.
+ LogPrintLevel(BCLog::NET, BCLog::Level::Debug, "txreconciliation protocol violation from peer=%d (sendtxrcncl received from already registered peer); disconnecting\n", pfrom.GetId());
+ pfrom.fDisconnect = true;
+ return;
+ }
+
+ const ReconciliationRegisterResult result = m_txreconciliation->RegisterPeer(pfrom.GetId(), pfrom.IsInboundConn(),
+ is_peer_initiator, is_peer_responder,
+ peer_txreconcl_version,
+ remote_salt);
+
+ // If it's a protocol violation, disconnect.
+ // If the peer was not found (but something unexpected happened) or it was registered,
+ // nothing to be done.
+ if (result == ReconciliationRegisterResult::PROTOCOL_VIOLATION) {
+ LogPrintLevel(BCLog::NET, BCLog::Level::Debug, "txreconciliation protocol violation from peer=%d; disconnecting\n", pfrom.GetId());
+ pfrom.fDisconnect = true;
+ return;
+ }
+ return;
+ }
+
if (!pfrom.fSuccessfullyConnected) {
LogPrint(BCLog::NET, "Unsupported message \"%s\" prior to verack from peer=%d\n", SanitizeString(msg_type), pfrom.GetId());
return;