mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-09-12 13:42:10 +02:00
Merge bitcoin/bitcoin#35221: BIP 434 Support: Peer feature negotiation
da74ff9ca4test: Add functional test for BIP434 (Fabian Jahr)01b8a117d2test_framework: BIP 434 support (Anthony Towns)6a129983c9BIP434: FEATURE message support (Anthony Towns)3210fc477anet: Add AdvertisedVersion() for protocol version advertised to a peer (Anthony Towns)94ed45427cserialize: add LimitedVectorFormatter (Anthony Towns)1b3f776ebbserialize: string_view serialization (Anthony Towns) Pull request description: Adds support for [BIP 434](https://github.com/bitcoin/bips/blob/master/bip-0434.md). ACKs for top commit: fjahr: ACKda74ff9ca4pseudoramdom: ACKda74ff9ca4achow101: ACKda74ff9ca4darosior: ACKda74ff9ca4w0xlt: reACKda74ff9ca4sedited: ACKda74ff9ca4Tree-SHA512: 74aa01b9b296a1a498b3aa119af6db906453f0809ec7ae271fc26690491c3f5677bf2cd03817caf9e287f5b3bc977768cdfefbe74ed2dd0da1cd339e043fe010
This commit is contained in:
@@ -725,6 +725,15 @@ private:
|
||||
{
|
||||
m_connman.PushMessage(&node, NetMsg::Make(std::move(msg_type), std::forward<Args>(args)...));
|
||||
}
|
||||
template <typename... Args>
|
||||
void MakeAndPushFeature(CNode& node, std::string_view feature_id, Args&&... args) const
|
||||
{
|
||||
if (!Assume(feature_id.size() >= 4 && feature_id.size() <= MAX_FEATUREID_LENGTH)) return;
|
||||
std::vector<unsigned char> feature_data;
|
||||
VectorWriter{feature_data, 0, std::forward<Args>(args)...};
|
||||
if (!Assume(feature_data.size() <= MAX_FEATUREDATA_LENGTH)) return;
|
||||
MakeAndPushMessage(node, NetMsgType::FEATURE, feature_id, std::move(feature_data));
|
||||
}
|
||||
|
||||
/** Send a version message to a peer */
|
||||
void PushNodeVersion(CNode& pnode, const Peer& peer);
|
||||
@@ -1578,7 +1587,7 @@ void PeerManagerImpl::PushNodeVersion(CNode& pnode, const Peer& peer)
|
||||
MakeAndPushMessage(
|
||||
pnode,
|
||||
NetMsgType::VERSION,
|
||||
PROTOCOL_VERSION,
|
||||
pnode.AdvertisedVersion(),
|
||||
my_services,
|
||||
my_time,
|
||||
// your_services + CNetAddr::V1(your_addr) is the pre-version-31402 serialization of your_addr (without nTime)
|
||||
@@ -1592,7 +1601,7 @@ void PeerManagerImpl::PushNodeVersion(CNode& pnode, const Peer& peer)
|
||||
|
||||
LogDebug(
|
||||
BCLog::NET, "send version message: version=%d, blocks=%d%s, txrelay=%d, peer=%d\n",
|
||||
PROTOCOL_VERSION, my_height,
|
||||
pnode.AdvertisedVersion(), my_height,
|
||||
fLogIPs ? strprintf(", them=%s", your_addr.ToStringAddrPort()) : "",
|
||||
my_tx_relay, pnode.GetId());
|
||||
}
|
||||
@@ -3679,7 +3688,7 @@ void PeerManagerImpl::ProcessMessage(Peer& peer, CNode& pfrom, const std::string
|
||||
}
|
||||
|
||||
// Change version
|
||||
const int greatest_common_version = std::min(nVersion, PROTOCOL_VERSION);
|
||||
const int greatest_common_version = std::min(nVersion, pfrom.AdvertisedVersion());
|
||||
pfrom.SetCommonVersion(greatest_common_version);
|
||||
pfrom.nVersion = nVersion;
|
||||
|
||||
@@ -3754,6 +3763,11 @@ void PeerManagerImpl::ProcessMessage(Peer& peer, CNode& pfrom, const std::string
|
||||
}
|
||||
}
|
||||
|
||||
if (greatest_common_version >= FEATURE_VERSION) {
|
||||
// announce supported features
|
||||
// MakeAndPushFeature(pfrom, NetMsgFeature::FOO, uint32_t{1});
|
||||
}
|
||||
|
||||
MakeAndPushMessage(pfrom, NetMsgType::VERACK);
|
||||
|
||||
// Potentially mark this peer as a preferred download peer.
|
||||
@@ -3969,6 +3983,45 @@ void PeerManagerImpl::ProcessMessage(Peer& peer, CNode& pfrom, const std::string
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg_type == NetMsgType::FEATURE) {
|
||||
if (pfrom.fSuccessfullyConnected) {
|
||||
// Disconnect peers that send a FEATURE message after VERACK.
|
||||
LogDebug(BCLog::NET, "feature received after verack, %s", pfrom.DisconnectMsg());
|
||||
pfrom.fDisconnect = true;
|
||||
return;
|
||||
} else if (pfrom.GetCommonVersion() < FEATURE_VERSION) {
|
||||
// Disconnect peers that send a FEATURE message without valid version negotiation.
|
||||
LogDebug(BCLog::NET, "feature received with incompatible version %d, %s", pfrom.GetCommonVersion(), pfrom.DisconnectMsg());
|
||||
pfrom.fDisconnect = true;
|
||||
return;
|
||||
}
|
||||
|
||||
std::string feature_id;
|
||||
DataStream feature_data;
|
||||
try {
|
||||
vRecv >> LIMITED_STRING(feature_id, MAX_FEATUREID_LENGTH);
|
||||
std::vector<unsigned char> feature_data_vec;
|
||||
vRecv >> LIMITED_VECTOR(feature_data_vec, MAX_FEATUREDATA_LENGTH);
|
||||
feature_data = DataStream(feature_data_vec);
|
||||
} catch (const std::exception&) {
|
||||
feature_id.clear(); // use empty feature_id as error indicator
|
||||
}
|
||||
if (feature_id.size() < 4 || !vRecv.empty()) {
|
||||
LogDebug(BCLog::NET, "invalid feature payload, %s", pfrom.DisconnectMsg());
|
||||
pfrom.fDisconnect = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// if (feature_id == NetMsgFeature::FOO) {
|
||||
// ...
|
||||
// return;
|
||||
// }
|
||||
|
||||
// ignore unknown feature_id
|
||||
LogDebug(BCLog::NET, "unknown feature advertised: %s", SanitizeString(feature_id));
|
||||
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.
|
||||
|
||||
Reference in New Issue
Block a user