diff --git a/doc/release-notes-6877.md b/doc/release-notes-6877.md new file mode 100644 index 0000000000000..8e2a997cdbe25 --- /dev/null +++ b/doc/release-notes-6877.md @@ -0,0 +1,4 @@ +P2P and Network Changes +----------------------- + +`MIN_PEER_PROTO_VERSION` has been bumped to `70221` diff --git a/src/evo/mnauth.cpp b/src/evo/mnauth.cpp index 3c2b080059c1e..376c96ecfaf40 100644 --- a/src/evo/mnauth.cpp +++ b/src/evo/mnauth.cpp @@ -38,13 +38,7 @@ void CMNAuth::PushMNAUTH(CNode& peer, CConnman& connman, const CActiveMasternode } auto pk = mn_activeman.GetPubKey(); const CBLSPublicKey pubKey(pk); - uint256 signHash = [&]() { - if (peer.nVersion < MNAUTH_NODE_VER_VERSION || nOurNodeVersion < MNAUTH_NODE_VER_VERSION) { - return ::SerializeHash(std::make_tuple(pubKey, receivedMNAuthChallenge, peer.IsInboundConn())); - } else { - return ::SerializeHash(std::make_tuple(pubKey, receivedMNAuthChallenge, peer.IsInboundConn(), nOurNodeVersion)); - } - }(); + const uint256 signHash{::SerializeHash(std::make_tuple(pubKey, receivedMNAuthChallenge, peer.IsInboundConn(), nOurNodeVersion))}; mnauth.proRegTxHash = mn_activeman.GetProTxHash(); @@ -97,18 +91,9 @@ MessageProcessingResult CMNAuth::ProcessMessage(CNode& peer, ServiceFlags node_s return MisbehavingError{10, "missing mnauth masternode"}; } - uint256 signHash; - int nOurNodeVersion{PROTOCOL_VERSION}; - if (Params().NetworkIDString() != CBaseChainParams::MAIN && gArgs.IsArgSet("-pushversion")) { - nOurNodeVersion = gArgs.GetIntArg("-pushversion", PROTOCOL_VERSION); - } const CBLSPublicKey pubKey(dmn->pdmnState->pubKeyOperator.Get()); // See comment in PushMNAUTH (fInbound is negated here as we're on the other side of the connection) - if (peer.nVersion < MNAUTH_NODE_VER_VERSION || nOurNodeVersion < MNAUTH_NODE_VER_VERSION) { - signHash = ::SerializeHash(std::make_tuple(pubKey, peer.GetSentMNAuthChallenge(), !peer.IsInboundConn())); - } else { - signHash = ::SerializeHash(std::make_tuple(pubKey, peer.GetSentMNAuthChallenge(), !peer.IsInboundConn(), peer.nVersion.load())); - } + const uint256 signHash{::SerializeHash(std::make_tuple(pubKey, peer.GetSentMNAuthChallenge(), !peer.IsInboundConn(), peer.nVersion.load()))}; LogPrint(BCLog::NET_NETCONN, "CMNAuth::%s -- constructed signHash for nVersion %d, peer=%d\n", __func__, peer.nVersion, peer.GetId()); if (!mnauth.sig.VerifyInsecure(dmn->pdmnState->pubKeyOperator.Get(), signHash, false)) { diff --git a/src/governance/governance.cpp b/src/governance/governance.cpp index 1ff5ddda0e012..7dd2b4a47099e 100644 --- a/src/governance/governance.cpp +++ b/src/governance/governance.cpp @@ -1005,19 +1005,6 @@ MessageProcessingResult CGovernanceManager::SyncObjects(CNode& peer, CConnman& c continue; } - if (peer.nVersion < GOVSCRIPT_PROTO_VERSION && govobj.GetObjectType() == GovernanceObject::PROPOSAL) { - // We know this proposal is valid locally, otherwise we would not store it. - // But we don't want to relay it to pre-GOVSCRIPT_PROTO_VERSION peers if payment_address is p2sh - // because they won't accept it anyway and will simply ban us eventually. - CProposalValidator validator(govobj.GetDataAsHexString(), false /* no script */); - if (!validator.Validate(false /* ignore expiration */)) { - // The only way we could get here is when proposal is valid but payment_address is actually p2sh. - LogPrintf("CGovernanceManager::%s -- not syncing p2sh govobj to older node: %s, peer=%d\n", __func__, - strHash, peer.GetId()); - continue; - } - } - // Push the inventory budget proposal message over to the other client LogPrint(BCLog::GOBJECT, "CGovernanceManager::%s -- syncing govobj: %s, peer=%d\n", __func__, strHash, peer.GetId()); ret.m_inventory.emplace_back(MSG_GOVERNANCE_OBJECT, nHash); diff --git a/src/governance/object.cpp b/src/governance/object.cpp index ddf3231537aa8..8945ec62f7fae 100644 --- a/src/governance/object.cpp +++ b/src/governance/object.cpp @@ -602,21 +602,8 @@ void CGovernanceObject::Relay(PeerManager& peerman, const CMasternodeSync& mn_sy return; } - int minProtoVersion = MIN_PEER_PROTO_VERSION; - if (m_obj.type == GovernanceObject::PROPOSAL) { - // We know this proposal is valid locally, otherwise we would not get to the point we should relay it. - // But we don't want to relay it to pre-GOVSCRIPT_PROTO_VERSION peers if payment_address is p2sh - // because they won't accept it anyway and will simply ban us eventually. - CProposalValidator validator(GetDataAsHexString(), false /* no script */); - if (!validator.Validate(false /* ignore expiration */)) { - // The only way we could get here is when proposal is valid but payment_address is actually p2sh. - LogPrint(BCLog::GOBJECT, "CGovernanceObject::Relay -- won't relay %s to older peers\n", GetHash().ToString()); - minProtoVersion = GOVSCRIPT_PROTO_VERSION; - } - } - CInv inv(MSG_GOVERNANCE_OBJECT, GetHash()); - peerman.RelayInv(inv, minProtoVersion); + peerman.RelayInv(inv); } void CGovernanceObject::UpdateSentinelVariables(const CDeterministicMNList& tip_mn_list) diff --git a/src/init.cpp b/src/init.cpp index 25b2ca72090c3..691e1fdf0bb00 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -2193,10 +2193,6 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) // ********************************************************* Step 8: start indexers if (args.GetBoolArg("-txindex", DEFAULT_TXINDEX)) { - if (const auto error{WITH_LOCK(cs_main, return CheckLegacyTxindex(*Assert(chainman.m_blockman.m_block_tree_db)))}) { - return InitError(*error); - } - g_txindex = std::make_unique(cache_sizes.tx_index, false, fReindex); if (!g_txindex->Start(chainman.ActiveChainstate())) { return false; diff --git a/src/llmq/quorums.cpp b/src/llmq/quorums.cpp index 196967cab3587..c73395a010714 100644 --- a/src/llmq/quorums.cpp +++ b/src/llmq/quorums.cpp @@ -482,10 +482,6 @@ bool CQuorumManager::RequestQuorumData(CNode* pfrom, CConnman& connman, CQuorumC LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- Invalid pfrom: nullptr\n", __func__); return false; } - if (pfrom->nVersion < LLMQ_DATA_MESSAGES_VERSION) { - LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- Version must be %d or greater.\n", __func__, LLMQ_DATA_MESSAGES_VERSION); - return false; - } if (pfrom->GetVerifiedProRegTxHash().IsNull()) { LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- pfrom is not a verified masternode\n", __func__); return false; diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 6e104ac8ab5b4..9e63581af17ab 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -650,13 +650,13 @@ class PeerManagerImpl final : public PeerManager void AskPeersForTransaction(const uint256& txid) EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex); /** Relay inventories to peers that find it relevant */ - void RelayInvFiltered(const CInv& inv, const CTransaction& relatedTx, const int minProtoVersion) EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex); + void RelayInvFiltered(const CInv& inv, const CTransaction& relatedTx) EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex); /** * This overload will not update node filters, use it only for the cases * when other messages will update related transaction data in filters */ - void RelayInvFiltered(const CInv& inv, const uint256& relatedTxHash, const int minProtoVersion) EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex); + void RelayInvFiltered(const CInv& inv, const uint256& relatedTxHash) EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex); void EraseObjectRequest(NodeId nodeid, const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(::cs_main); @@ -2402,7 +2402,7 @@ void PeerManagerImpl::RelayDSQ(const CCoinJoinQueue& queue) } } -void PeerManagerImpl::RelayInvFiltered(const CInv& inv, const CTransaction& relatedTx, const int minProtoVersion) +void PeerManagerImpl::RelayInvFiltered(const CInv& inv, const CTransaction& relatedTx) { // TODO: Migrate to iteration through m_peer_map m_connman.ForEachNode([&](CNode* pnode) { @@ -2410,7 +2410,7 @@ void PeerManagerImpl::RelayInvFiltered(const CInv& inv, const CTransaction& rela if (peer == nullptr) return; auto tx_relay = peer->GetTxRelay(); - if (pnode->nVersion < minProtoVersion || !pnode->CanRelay() || tx_relay == nullptr) { + if (!pnode->CanRelay() || tx_relay == nullptr) { return; } @@ -2427,7 +2427,7 @@ void PeerManagerImpl::RelayInvFiltered(const CInv& inv, const CTransaction& rela }); } -void PeerManagerImpl::RelayInvFiltered(const CInv& inv, const uint256& relatedTxHash, const int minProtoVersion) +void PeerManagerImpl::RelayInvFiltered(const CInv& inv, const uint256& relatedTxHash) { // TODO: Migrate to iteration through m_peer_map m_connman.ForEachNode([&](CNode* pnode) { @@ -2435,7 +2435,7 @@ void PeerManagerImpl::RelayInvFiltered(const CInv& inv, const uint256& relatedTx if (peer == nullptr) return; auto tx_relay = peer->GetTxRelay(); - if (pnode->nVersion < minProtoVersion || !pnode->CanRelay() || tx_relay == nullptr) { + if (!pnode->CanRelay() || tx_relay == nullptr) { return; } @@ -3525,9 +3525,9 @@ void PeerManagerImpl::PostProcessMessage(MessageProcessingResult&& result, NodeI if (result.m_inv_filter) { const auto& [inv, filter] = result.m_inv_filter.value(); if (std::holds_alternative(filter)) { - RelayInvFiltered(inv, *std::get(filter), ISDLOCK_PROTO_VERSION); + RelayInvFiltered(inv, *std::get(filter)); } else if (std::holds_alternative(filter)) { - RelayInvFiltered(inv, std::get(filter), ISDLOCK_PROTO_VERSION); + RelayInvFiltered(inv, std::get(filter)); } else { assert(false); } @@ -6211,7 +6211,6 @@ bool PeerManagerImpl::SendMessages(CNode* pto) const auto islock = m_llmq_ctx->isman->GetInstantSendLockByTxid(hash); if (islock == nullptr) continue; - if (pto->nVersion < ISDLOCK_PROTO_VERSION) continue; uint256 isLockHash{::SerializeHash(*islock)}; tx_relay->m_tx_inventory_known_filter.insert(isLockHash); queueAndMaybePushInv(CInv(MSG_ISDLOCK, isLockHash)); diff --git a/src/txdb.cpp b/src/txdb.cpp index 561be22d6c7a8..e1dddcfd90f8e 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -14,7 +15,9 @@ #include #include -#include +#include +#include +#include static constexpr uint8_t DB_COIN{'C'}; static constexpr uint8_t DB_BLOCK_FILES{'f'}; @@ -32,26 +35,9 @@ static constexpr uint8_t DB_LAST_BLOCK{'l'}; // Keys used in previous version that might still be found in the DB: static constexpr uint8_t DB_COINS{'c'}; -static constexpr uint8_t DB_TXINDEX_BLOCK{'T'}; -// uint8_t DB_TXINDEX{'t'} - -std::optional CheckLegacyTxindex(CBlockTreeDB& block_tree_db) -{ - CBlockLocator ignored{}; - if (block_tree_db.Read(DB_TXINDEX_BLOCK, ignored)) { - return _("The -txindex upgrade started by a previous version cannot be completed. Restart with the previous version or run a full -reindex."); - } - bool txindex_legacy_flag{false}; - block_tree_db.ReadFlag("txindex", txindex_legacy_flag); - if (txindex_legacy_flag) { - // Disable legacy txindex and warn once about occupied disk space - if (!block_tree_db.WriteFlag("txindex", false)) { - return Untranslated("Failed to write block index db flag 'txindex'='0'"); - } - return _("The block index db contains a legacy 'txindex'. To clear the occupied disk space, run a full -reindex, otherwise ignore this error. This error message will not be displayed again."); - } - return std::nullopt; -} +// CBlockTreeDB::DB_TXINDEX_BLOCK{'T'}; +// CBlockTreeDB::DB_TXINDEX{'t'} +// CBlockTreeDB::ReadFlag("txindex") bool CCoinsViewDB::NeedsUpgrade() { diff --git a/src/txdb.h b/src/txdb.h index e101ad8c523dd..2c812300dfad7 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -111,6 +111,4 @@ class CBlockTreeDB : public CDBWrapper EXCLUSIVE_LOCKS_REQUIRED(::cs_main); }; -std::optional CheckLegacyTxindex(CBlockTreeDB& block_tree_db); - #endif // BITCOIN_TXDB_H diff --git a/src/version.h b/src/version.h index 4364d77b6400b..6b5edffb77554 100644 --- a/src/version.h +++ b/src/version.h @@ -17,23 +17,11 @@ static const int PROTOCOL_VERSION = 70238; static const int INIT_PROTO_VERSION = 209; //! disconnect from peers older than this proto version -static const int MIN_PEER_PROTO_VERSION = 70216; +static const int MIN_PEER_PROTO_VERSION = 70221; //! minimum proto version of masternode to accept in DKGs static const int MIN_MASTERNODE_PROTO_VERSION = 70238; -//! protocol version is included in MNAUTH starting with this version -static const int MNAUTH_NODE_VER_VERSION = 70218; - -//! introduction of QGETDATA/QDATA messages -static const int LLMQ_DATA_MESSAGES_VERSION = 70219; - -//! introduction of instant send deterministic lock (ISDLOCK) -static const int ISDLOCK_PROTO_VERSION = 70220; - -//! GOVSCRIPT was activated in this version -static const int GOVSCRIPT_PROTO_VERSION = 70221; - //! ADDRV2 was introduced in this version static const int ADDRV2_PROTO_VERSION = 70223; diff --git a/test/functional/feature_llmq_simplepose.py b/test/functional/feature_llmq_simplepose.py index 1b7ce5294f747..0b3cfcb3953a4 100755 --- a/test/functional/feature_llmq_simplepose.py +++ b/test/functional/feature_llmq_simplepose.py @@ -19,6 +19,9 @@ ) from test_framework.util import assert_equal, force_finish_mnsync +# See version.h +MIN_MASTERNODE_PROTO_VERSION = 70238 + class LLMQSimplePoSeTest(DashTestFramework): def set_test_params(self): # rotating quorums add instability for this functional tests @@ -87,7 +90,7 @@ def close_mn_port(self, mn: MasternodeInfo): def force_old_mn_proto(self, mn: MasternodeInfo): self.stop_node(mn.nodeIdx) - self.start_masternode(mn, ["-pushversion=70216"]) + self.start_masternode(mn, [f"-pushversion={MIN_MASTERNODE_PROTO_VERSION - 1}"]) self.connect_nodes(mn.nodeIdx, 0) self.reset_probe_timeouts() return False, True diff --git a/test/functional/feature_txindex_compatibility.py b/test/functional/feature_txindex_compatibility.py deleted file mode 100755 index ed913f51372ff..0000000000000 --- a/test/functional/feature_txindex_compatibility.py +++ /dev/null @@ -1,97 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2021 The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. -"""Test that legacy txindex will be disabled on upgrade. - -Previous releases are required by this test, see test/README.md. -""" - -import os -import shutil - -from test_framework.test_framework import BitcoinTestFramework -from test_framework.wallet import MiniWallet - - -class MempoolCompatibilityTest(BitcoinTestFramework): - def set_test_params(self): - self.num_nodes = 3 - self.extra_args = [ - ["-reindex", "-txindex"], - ["-txindex=0"], - ["-txindex=0"], - ] - - def skip_test_if_missing_module(self): - self.skip_if_no_previous_releases() - - def setup_network(self): - self.add_nodes( - self.num_nodes, - self.extra_args, - versions=[ - 170003, # Last release with legacy txindex - None, # For MiniWallet, without migration code - 18020200, # Any release with migration code (0.18.x - 21.x) - # We are using v18.2.2 to avoid MigrateDBIfNeeded(2) routines as - # they don't handle a no-upgrade case correctly - ], - ) - # Delete v18.2.2 cached datadir to avoid making a legacy version try to - # make sense of our current database formats - shutil.rmtree(os.path.join(self.nodes[2].datadir, self.chain)) - self.start_nodes() - self.connect_nodes(0, 1) - self.connect_nodes(1, 2) - - def run_test(self): - mini_wallet = MiniWallet(self.nodes[1]) - mini_wallet.rescan_utxos() - spend_utxo = mini_wallet.get_utxo() - mini_wallet.send_self_transfer(from_node=self.nodes[1], utxo_to_spend=spend_utxo) - self.generate(self.nodes[1], 1) - - self.log.info("Check legacy txindex") - self.nodes[0].getrawtransaction(txid=spend_utxo["txid"]) # Requires -txindex - - self.stop_nodes() - legacy_chain_dir = os.path.join(self.nodes[0].datadir, self.chain) - - self.log.info("Migrate legacy txindex") - migrate_chain_dir = os.path.join(self.nodes[2].datadir, self.chain) - shutil.rmtree(migrate_chain_dir) - shutil.copytree(legacy_chain_dir, migrate_chain_dir) - with self.nodes[2].assert_debug_log([ - "Upgrading txindex database...", - "txindex is enabled at height 200", - ]): - self.start_node(2, extra_args=["-txindex"]) - self.nodes[2].getrawtransaction(txid=spend_utxo["txid"]) # Requires -txindex - - self.log.info("Drop legacy txindex") - drop_index_chain_dir = os.path.join(self.nodes[1].datadir, self.chain) - shutil.rmtree(drop_index_chain_dir) - shutil.copytree(legacy_chain_dir, drop_index_chain_dir) - self.nodes[1].assert_start_raises_init_error( - extra_args=["-txindex"], - expected_msg="Error: The block index db contains a legacy 'txindex'. To clear the occupied disk space, run a full -reindex, otherwise ignore this error. This error message will not be displayed again.", - ) - # Build txindex from scratch and check there is no error this time - self.start_node(1, extra_args=["-txindex"]) - self.nodes[2].getrawtransaction(txid=spend_utxo["txid"]) # Requires -txindex - - self.stop_nodes() - - self.log.info("Check migrated txindex cannot be read by legacy node") - err_msg = f": You need to rebuild the database using -reindex to change -txindex.{os.linesep}Please restart with -reindex or -reindex-chainstate to recover." - shutil.rmtree(legacy_chain_dir) - shutil.copytree(migrate_chain_dir, legacy_chain_dir) - self.nodes[0].assert_start_raises_init_error(extra_args=["-txindex"], expected_msg=err_msg) - shutil.rmtree(legacy_chain_dir) - shutil.copytree(drop_index_chain_dir, legacy_chain_dir) - self.nodes[0].assert_start_raises_init_error(extra_args=["-txindex"], expected_msg=err_msg) - - -if __name__ == "__main__": - MempoolCompatibilityTest().main() diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py index 602ba0ca70f7f..307415e661d35 100755 --- a/test/functional/test_runner.py +++ b/test/functional/test_runner.py @@ -373,7 +373,6 @@ 'p2p_ping.py', 'p2p_sendtxrcncl.py', 'rpc_scantxoutset.py', - 'feature_txindex_compatibility.py', 'feature_unsupported_utxo_db.py', 'feature_logging.py', 'feature_anchors.py',