Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions src/net_processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
#include <optional>
#include <ranges>
#include <typeinfo>
#include <vector>

using node::ReadBlockFromDisk;
using node::fImporting;
Expand Down Expand Up @@ -389,6 +390,10 @@ struct Peer {

/** Whether this peer has already sent us a getaddr message. */
bool m_getaddr_recvd GUARDED_BY(NetEventsInterface::g_msgproc_mutex){false};
/** Whether this peer has already requested sporks. */
bool m_getsporks_recvd GUARDED_BY(NetEventsInterface::g_msgproc_mutex){false};
/** Hashes of active sporks sent in the last getsporks response. */
std::vector<uint256> m_getsporks_last_response GUARDED_BY(NetEventsInterface::g_msgproc_mutex){};
/** Number of addresses that can be processed from this peer. Start at 1 to
* permit self-announcement. */
double m_addr_token_bucket GUARDED_BY(NetEventsInterface::g_msgproc_mutex){1.0};
Expand Down Expand Up @@ -5449,6 +5454,24 @@ void PeerManagerImpl::ProcessMessage(
if (msg_type == NetMsgType::GETSPORKS) {
// For 'getsporks', active sporks is sent to the requesting peer.
auto active_sporks = m_sporkman.ActiveSporks();
std::vector<uint256> active_spork_hashes;
for (const auto& pair : active_sporks) {
for (const auto& spork_pair : pair.second) {
active_spork_hashes.push_back(spork_pair.second.GetHash());
}
}
std::sort(active_spork_hashes.begin(), active_spork_hashes.end());

// Ignore repeated requests only while the active spork set is unchanged.
// Functional tests and some peers request sporks again after a spork
// update; those requests must receive the newer active set.
if (peer->m_getsporks_recvd && peer->m_getsporks_last_response == active_spork_hashes) {
LogPrint(BCLog::NET, "Ignoring repeated \"getsporks\". peer=%d\n", pfrom.GetId());
return;
}
peer->m_getsporks_recvd = true;
peer->m_getsporks_last_response = active_spork_hashes;

for (const auto& pair : active_sporks) {
for (const auto& signerSporkPair : pair.second) {
m_connman.PushMessage(&pfrom, CNetMsgMaker(pfrom.GetCommonVersion()).Make(NetMsgType::SPORK, signerSporkPair.second));
Expand Down
56 changes: 56 additions & 0 deletions test/functional/feature_sporks.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,48 @@
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.

from test_framework.p2p import MESSAGEMAP, P2PInterface
from test_framework.test_framework import BitcoinTestFramework


class msg_getsporks:
__slots__ = ()
msgtype = b"getsporks"

def deserialize(self, f):
pass

def serialize(self):
return b""

def __repr__(self):
return "msg_getsporks()"


class msg_spork_raw:
__slots__ = ("raw",)
msgtype = b"spork"

def __init__(self):
self.raw = b""

def deserialize(self, f):
self.raw = f.read()

def serialize(self):
return self.raw

def __repr__(self):
return f"msg_spork_raw(len={len(self.raw)})"


class SporkP2PInterface(P2PInterface):
def on_inv(self, message):
pass

def on_spork(self, message):
pass

'''
'''

Expand Down Expand Up @@ -44,6 +84,22 @@ def run_test(self):
self.set_test_spork_state(self.nodes[0], spork_new_state)
self.wait_until(lambda: self.get_test_spork_state(self.nodes[1]), timeout=10)

# GETSPORKS should not resend an unchanged active spork set, but must
# answer again after the active spork set changes on the same connection.
MESSAGEMAP[b"spork"] = msg_spork_raw
peer = self.nodes[0].add_p2p_connection(SporkP2PInterface())
peer.send_message(msg_getsporks())
peer.wait_until(lambda: peer.message_count["spork"] > 0)
peer.sync_with_ping()
spork_responses = peer.message_count["spork"]
peer.send_message(msg_getsporks())
peer.sync_with_ping()
assert peer.message_count["spork"] == spork_responses
Comment thread
coderabbitai[bot] marked this conversation as resolved.

self.nodes[0].sporkupdate("SPORK_17_QUORUM_DKG_ENABLED", 0)
peer.send_message(msg_getsporks())
peer.wait_until(lambda: peer.message_count["spork"] > spork_responses)

# restart nodes to check spork persistence
self.stop_node(0)
self.stop_node(1)
Expand Down
Loading