@@ -1292,6 +1292,30 @@ static std::optional<ProTx> GetValidatedPayload(const CTransaction& tx, gsl::not
12921292 return opt_ptx;
12931293}
12941294
1295+ /* *
1296+ * Validates potential changes to masternode state version by ProTx transaction version
1297+ * @param[in] pindexPrev Previous block index to validate DEPLOYMENT_V23 activation
1298+ * @param[in] state_version Current masternode state version
1299+ * @param[in] tx_version Proposed transaction version
1300+ * @param[out] state This may be set to an Error state if any error occurred processing them
1301+ * @returns true if version change is valid or DEPLOYMENT_V23 is not active
1302+ */
1303+ bool IsVersionChangeValid (gsl::not_null<const CBlockIndex*> pindexPrev, const uint16_t state_version, const uint16_t tx_version,
1304+ TxValidationState& state)
1305+ {
1306+ if (!DeploymentActiveAfter (pindexPrev, Params ().GetConsensus (), Consensus::DEPLOYMENT_V23)) {
1307+ // New restrictions only apply after v23 deployment
1308+ return true ;
1309+ }
1310+
1311+ if (state_version >= ProTxVersion::BasicBLS && tx_version == ProTxVersion::LegacyBLS) {
1312+ // Don't allow legacy scheme versioned transactions after upgrading to basic scheme
1313+ return state.Invalid (TxValidationResult::TX_CONSENSUS, " bad-protx-version-downgrade" );
1314+ }
1315+
1316+ return true ;
1317+ }
1318+
12951319bool CheckProRegTx (CDeterministicMNManager& dmnman, const CTransaction& tx, gsl::not_null<const CBlockIndex*> pindexPrev, TxValidationState& state, const CCoinsViewCache& view, bool check_sigs)
12961320{
12971321 const auto opt_ptx = GetValidatedPayload<CProRegTx>(tx, pindexPrev, state);
@@ -1439,6 +1463,11 @@ bool CheckProUpServTx(CDeterministicMNManager& dmnman, const CTransaction& tx, g
14391463 return state.Invalid (TxValidationResult::TX_CONSENSUS, " bad-protx-hash" );
14401464 }
14411465
1466+ if (!IsVersionChangeValid (pindexPrev, dmn->pdmnState ->nVersion , opt_ptx->nVersion , state)) {
1467+ // pass the state returned by the function above
1468+ return false ;
1469+ }
1470+
14421471 // don't allow updating to addresses already used by other MNs
14431472 for (const NetInfoEntry& entry : opt_ptx->netInfo ->GetEntries ()) {
14441473 if (const auto & service_opt{entry.GetAddrPort ()}; service_opt.has_value ()) {
@@ -1501,6 +1530,11 @@ bool CheckProUpRegTx(CDeterministicMNManager& dmnman, const CTransaction& tx, gs
15011530 return state.Invalid (TxValidationResult::TX_CONSENSUS, " bad-protx-hash" );
15021531 }
15031532
1533+ if (!IsVersionChangeValid (pindexPrev, dmn->pdmnState ->nVersion , opt_ptx->nVersion , state)) {
1534+ // pass the state returned by the function above
1535+ return false ;
1536+ }
1537+
15041538 // don't allow reuse of payee key for other keys (don't allow people to put the payee key onto an online server)
15051539 if (payoutDest == CTxDestination (PKHash (dmn->pdmnState ->keyIDOwner )) || payoutDest == CTxDestination (PKHash (opt_ptx->keyIDVoting ))) {
15061540 return state.Invalid (TxValidationResult::TX_BAD_SPECIAL, " bad-protx-payee-reuse" );
@@ -1560,6 +1594,11 @@ bool CheckProUpRevTx(CDeterministicMNManager& dmnman, const CTransaction& tx, gs
15601594 return state.Invalid (TxValidationResult::TX_CONSENSUS, " bad-protx-hash" );
15611595 }
15621596
1597+ if (!IsVersionChangeValid (pindexPrev, dmn->pdmnState ->nVersion , opt_ptx->nVersion , state)) {
1598+ // pass the state returned by the function above
1599+ return false ;
1600+ }
1601+
15631602 if (!CheckInputsHash (tx, *opt_ptx, state)) {
15641603 // pass the state returned by the function above
15651604 return false ;
0 commit comments