Skip to content

Commit 3e65628

Browse files
committed
evo: introduce new ProTx version for extended addresses (ExtNetInfo)
1 parent b4fa7a2 commit 3e65628

13 files changed

+70
-28
lines changed

src/evo/deterministicmns.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -884,7 +884,8 @@ bool CDeterministicMNManager::BuildNewListFromBlock(const CBlock& block, gsl::no
884884
newState->ResetOperatorFields();
885885
newState->BanIfNotBanned(nHeight);
886886
// we update pubKeyOperator here, make sure state version matches
887-
newState->nVersion = opt_proTx->nVersion;
887+
// Make sure we don't accidentally downgrade the state version if using version after basic BLS
888+
newState->nVersion = newState->nVersion > ProTxVersion::BasicBLS ? newState->nVersion : opt_proTx->nVersion;
888889
newState->netInfo = NetInfoInterface::MakeNetInfo(newState->nVersion);
889890
newState->pubKeyOperator = opt_proTx->pubKeyOperator;
890891
}

src/evo/dmnstate.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,8 @@ class CDeterministicMNState
9797
READWRITE(CBLSLazyPublicKeyVersionWrapper(const_cast<CBLSLazyPublicKey&>(obj.pubKeyOperator), obj.nVersion == ProTxVersion::LegacyBLS));
9898
READWRITE(
9999
obj.keyIDVoting,
100-
NetInfoSerWrapper(const_cast<std::shared_ptr<NetInfoInterface>&>(obj.netInfo)),
100+
NetInfoSerWrapper(const_cast<std::shared_ptr<NetInfoInterface>&>(obj.netInfo),
101+
obj.nVersion >= ProTxVersion::ExtAddr),
101102
obj.scriptPayout,
102103
obj.scriptOperatorPayout,
103104
obj.platformNodeID,
@@ -255,7 +256,10 @@ class CDeterministicMNStateDiff
255256
}
256257
} else if constexpr (BaseType::mask == Field_netInfo) {
257258
if (obj.fields & member.mask) {
258-
READWRITE(NetInfoSerWrapper(const_cast<std::shared_ptr<NetInfoInterface>&>(obj.state.netInfo)));
259+
// As nVersion is stored after netInfo, we use a magic word to determine the underlying implementation
260+
// TODO: Implement this
261+
READWRITE(NetInfoSerWrapper(const_cast<std::shared_ptr<NetInfoInterface>&>(obj.state.netInfo),
262+
/*is_extended=*/false));
259263
}
260264
} else {
261265
if (obj.fields & member.mask) {

src/evo/netinfo.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <evo/netinfo.h>
66

77
#include <chainparams.h>
8+
#include <evo/providertx.h>
89
#include <netbase.h>
910
#include <span.h>
1011
#include <util/check.h>
@@ -149,7 +150,7 @@ std::string NetInfoEntry::ToStringAddrPort() const
149150

150151
std::shared_ptr<NetInfoInterface> NetInfoInterface::MakeNetInfo(const uint16_t nVersion)
151152
{
152-
assert(nVersion > 0);
153+
assert(nVersion > 0 && nVersion < ProTxVersion::ExtAddr);
153154
return std::make_shared<MnNetInfo>();
154155
}
155156

src/evo/netinfo.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ class NetInfoInterface
138138
virtual NetInfoList GetEntries() const = 0;
139139

140140
virtual const CService& GetPrimary() const = 0;
141+
virtual bool CanStorePlatform() const = 0;
141142
virtual bool IsEmpty() const = 0;
142143
virtual NetInfoStatus Validate() const = 0;
143144
virtual std::string ToString() const = 0;
@@ -194,6 +195,7 @@ class MnNetInfo final : public NetInfoInterface
194195

195196
const CService& GetPrimary() const override;
196197
bool IsEmpty() const override { return m_addr.IsEmpty(); }
198+
bool CanStorePlatform() const override { return false; }
197199
NetInfoStatus Validate() const override;
198200
std::string ToString() const override;
199201

@@ -214,13 +216,17 @@ class NetInfoSerWrapper
214216
{
215217
private:
216218
std::shared_ptr<NetInfoInterface>& m_data;
219+
const bool m_is_extended{false};
217220

218221
public:
219222
NetInfoSerWrapper() = delete;
220223
NetInfoSerWrapper(const NetInfoSerWrapper&) = delete;
221-
NetInfoSerWrapper(std::shared_ptr<NetInfoInterface>& data) :
222-
m_data{data}
224+
NetInfoSerWrapper(std::shared_ptr<NetInfoInterface>& data, const bool is_extended) :
225+
m_data{data},
226+
m_is_extended{is_extended}
223227
{
228+
// TODO: Remove when extended addresses implementation is added in
229+
assert(!m_is_extended);
224230
}
225231

226232
~NetInfoSerWrapper() = default;

src/evo/providertx.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,13 @@ template <typename T>
1818
[[nodiscard]] uint16_t GetMaxFromDeployment(gsl::not_null<const CBlockIndex*> pindexPrev,
1919
std::optional<bool> is_basic_override)
2020
{
21-
return ProTxVersion::GetMax(
22-
is_basic_override ? *is_basic_override
23-
: DeploymentActiveAfter(pindexPrev, Params().GetConsensus(), Consensus::DEPLOYMENT_V19));
21+
constexpr bool is_extaddr_eligible{std::is_same_v<std::decay_t<T>, CProRegTx> || std::is_same_v<std::decay_t<T>, CProUpServTx>};
22+
return ProTxVersion::GetMax(is_basic_override ? *is_basic_override
23+
: DeploymentActiveAfter(pindexPrev, Params().GetConsensus(),
24+
Consensus::DEPLOYMENT_V19),
25+
is_extaddr_eligible ? DeploymentActiveAfter(pindexPrev, Params().GetConsensus(),
26+
Consensus::DEPLOYMENT_V23)
27+
: false);
2428
}
2529
template uint16_t GetMaxFromDeployment<CProRegTx>(gsl::not_null<const CBlockIndex*> pindexPrev, std::optional<bool> is_basic_override);
2630
template uint16_t GetMaxFromDeployment<CProUpServTx>(gsl::not_null<const CBlockIndex*> pindexPrev, std::optional<bool> is_basic_override);
@@ -52,6 +56,9 @@ bool CProRegTx::IsTriviallyValid(gsl::not_null<const CBlockIndex*> pindexPrev, T
5256
if (!scriptPayout.IsPayToPublicKeyHash() && !scriptPayout.IsPayToScriptHash()) {
5357
return state.Invalid(TxValidationResult::TX_BAD_SPECIAL, "bad-protx-payee");
5458
}
59+
if (netInfo->CanStorePlatform() != (nVersion == ProTxVersion::ExtAddr)) {
60+
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-protx-netinfo-version");
61+
}
5562
for (const NetInfoEntry& entry : netInfo->GetEntries()) {
5663
if (!entry.IsTriviallyValid()) {
5764
return state.Invalid(TxValidationResult::TX_BAD_SPECIAL, "bad-protx-netinfo-bad");
@@ -126,6 +133,9 @@ bool CProUpServTx::IsTriviallyValid(gsl::not_null<const CBlockIndex*> pindexPrev
126133
if (nVersion < ProTxVersion::BasicBLS && nType == MnType::Evo) {
127134
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-protx-evo-version");
128135
}
136+
if (netInfo->CanStorePlatform() != (nVersion == ProTxVersion::ExtAddr)) {
137+
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-protx-netinfo-version");
138+
}
129139
if (netInfo->IsEmpty()) {
130140
return state.Invalid(TxValidationResult::TX_BAD_SPECIAL, "bad-protx-netinfo-empty");
131141
}

src/evo/providertx.h

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,22 @@ namespace ProTxVersion {
2727
enum : uint16_t {
2828
LegacyBLS = 1,
2929
BasicBLS = 2,
30+
ExtAddr = 3,
3031
};
3132

3233
/** Get highest permissible ProTx version based on flags set. */
33-
[[nodiscard]] constexpr uint16_t GetMax(const bool is_basic_scheme_active)
34+
[[nodiscard]] constexpr uint16_t GetMax(const bool is_basic_scheme_active, const bool is_extended_addr)
3435
{
35-
return is_basic_scheme_active ? ProTxVersion::BasicBLS : ProTxVersion::LegacyBLS;
36+
if (is_basic_scheme_active) {
37+
if (is_extended_addr) {
38+
// Requires *both* forks to be active to use extended addresses. is_basic_scheme_active could
39+
// be set to false due to RPC specialization, so we must evaluate is_extended_addr *last* to
40+
// avoid accidentally upgrading a legacy BLS node to basic BLS due to v23 activation.
41+
return ProTxVersion::ExtAddr;
42+
}
43+
return ProTxVersion::BasicBLS;
44+
}
45+
return ProTxVersion::LegacyBLS;
3646
}
3747

3848
/** Get highest permissible ProTx version based on deployment status
@@ -71,7 +81,8 @@ class CProRegTx
7181
READWRITE(
7282
obj.nVersion
7383
);
74-
if (obj.nVersion == 0 || obj.nVersion > ProTxVersion::GetMax(/*is_basic_scheme_active=*/true)) {
84+
if (obj.nVersion == 0 ||
85+
obj.nVersion > ProTxVersion::GetMax(/*is_basic_scheme_active=*/true, /*is_extended_addr=*/true)) {
7586
// unknown version, bail out early
7687
return;
7788
}
@@ -80,7 +91,8 @@ class CProRegTx
8091
obj.nType,
8192
obj.nMode,
8293
obj.collateralOutpoint,
83-
NetInfoSerWrapper(const_cast<std::shared_ptr<NetInfoInterface>&>(obj.netInfo)),
94+
NetInfoSerWrapper(const_cast<std::shared_ptr<NetInfoInterface>&>(obj.netInfo),
95+
obj.nVersion >= ProTxVersion::ExtAddr),
8496
obj.keyIDOwner,
8597
CBLSLazyPublicKeyVersionWrapper(const_cast<CBLSLazyPublicKey&>(obj.pubKeyOperator), (obj.nVersion == ProTxVersion::LegacyBLS)),
8698
obj.keyIDVoting,
@@ -131,7 +143,8 @@ class CProUpServTx
131143
READWRITE(
132144
obj.nVersion
133145
);
134-
if (obj.nVersion == 0 || obj.nVersion > ProTxVersion::GetMax(/*is_basic_scheme_active=*/true)) {
146+
if (obj.nVersion == 0 ||
147+
obj.nVersion > ProTxVersion::GetMax(/*is_basic_scheme_active=*/true, /*is_extended_addr=*/true)) {
135148
// unknown version, bail out early
136149
return;
137150
}
@@ -141,7 +154,8 @@ class CProUpServTx
141154
}
142155
READWRITE(
143156
obj.proTxHash,
144-
NetInfoSerWrapper(const_cast<std::shared_ptr<NetInfoInterface>&>(obj.netInfo)),
157+
NetInfoSerWrapper(const_cast<std::shared_ptr<NetInfoInterface>&>(obj.netInfo),
158+
obj.nVersion >= ProTxVersion::ExtAddr),
145159
obj.scriptOperatorPayout,
146160
obj.inputsHash
147161
);
@@ -184,7 +198,8 @@ class CProUpRegTx
184198
READWRITE(
185199
obj.nVersion
186200
);
187-
if (obj.nVersion == 0 || obj.nVersion > ProTxVersion::GetMax(/*is_basic_scheme_active=*/true)) {
201+
if (obj.nVersion == 0 ||
202+
obj.nVersion > ProTxVersion::GetMax(/*is_basic_scheme_active=*/true, /*is_extended_addr=*/true)) {
188203
// unknown version, bail out early
189204
return;
190205
}
@@ -235,7 +250,8 @@ class CProUpRevTx
235250
READWRITE(
236251
obj.nVersion
237252
);
238-
if (obj.nVersion == 0 || obj.nVersion > ProTxVersion::GetMax(/*is_basic_scheme_active=*/true)) {
253+
if (obj.nVersion == 0 ||
254+
obj.nVersion > ProTxVersion::GetMax(/*is_basic_scheme_active=*/true, /*is_extended_addr=*/true)) {
239255
// unknown version, bail out early
240256
return;
241257
}

src/evo/simplifiedmns.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ class CSimplifiedMNListEntry
7777
READWRITE(
7878
obj.proRegTxHash,
7979
obj.confirmedHash,
80-
NetInfoSerWrapper(const_cast<std::shared_ptr<NetInfoInterface>&>(obj.netInfo)),
80+
NetInfoSerWrapper(const_cast<std::shared_ptr<NetInfoInterface>&>(obj.netInfo),
81+
obj.nVersion >= ProTxVersion::ExtAddr),
8182
CBLSLazyPublicKeyVersionWrapper(const_cast<CBLSLazyPublicKey&>(obj.pubKeyOperator), (obj.nVersion == ProTxVersion::LegacyBLS)),
8283
obj.keyIDVoting,
8384
obj.isValid

src/rpc/evo.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1014,7 +1014,8 @@ static UniValue protx_update_service_common_wrapper(const JSONRPCRequest& reques
10141014
throw std::runtime_error(strprintf("masternode with proTxHash %s is not a %s", ptx.proTxHash.ToString(), GetMnType(mnType).description));
10151015
}
10161016

1017-
ptx.nVersion = dmn->pdmnState->nVersion;
1017+
ptx.nVersion = ProTxVersion::GetMaxFromDeployment<CProUpServTx>(WITH_LOCK(::cs_main, return chainman.ActiveChain().Tip()),
1018+
/*is_basic_override=*/dmn->pdmnState->nVersion > ProTxVersion::LegacyBLS);
10181019
ptx.netInfo = NetInfoInterface::MakeNetInfo(ptx.nVersion);
10191020

10201021
if (auto entryRet = ptx.netInfo->AddEntry(request.params[1].get_str()); entryRet != NetInfoStatus::Success) {

src/test/block_reward_reallocation_tests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ static CMutableTransaction CreateProRegTx(const CChain& active_chain, const CTxM
118118
operatorKeyRet.MakeNewKey();
119119

120120
CProRegTx proTx;
121-
proTx.nVersion = ProTxVersion::GetMax(!bls::bls_legacy_scheme);
121+
proTx.nVersion = ProTxVersion::GetMax(!bls::bls_legacy_scheme, /*is_extended_addr=*/false);
122122
proTx.netInfo = NetInfoInterface::MakeNetInfo(proTx.nVersion);
123123
proTx.collateralOutpoint.n = 0;
124124
BOOST_CHECK_EQUAL(proTx.netInfo->AddEntry(strprintf("1.1.1.1:%d", port)), NetInfoStatus::Success);

src/test/evo_deterministicmns_tests.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ static CMutableTransaction CreateProRegTx(const CChain& active_chain, const CTxM
106106
operatorKeyRet.MakeNewKey();
107107

108108
CProRegTx proTx;
109-
proTx.nVersion = ProTxVersion::GetMax(!bls::bls_legacy_scheme);
109+
proTx.nVersion = ProTxVersion::GetMax(!bls::bls_legacy_scheme, /*is_extended_addr=*/false);
110110
proTx.netInfo = NetInfoInterface::MakeNetInfo(proTx.nVersion);
111111
proTx.collateralOutpoint.n = 0;
112112
BOOST_CHECK_EQUAL(proTx.netInfo->AddEntry(strprintf("1.1.1.1:%d", port)), NetInfoStatus::Success);
@@ -129,7 +129,7 @@ static CMutableTransaction CreateProRegTx(const CChain& active_chain, const CTxM
129129
static CMutableTransaction CreateProUpServTx(const CChain& active_chain, const CTxMemPool& mempool, SimpleUTXOMap& utxos, const uint256& proTxHash, const CBLSSecretKey& operatorKey, int port, const CScript& scriptOperatorPayout, const CKey& coinbaseKey)
130130
{
131131
CProUpServTx proTx;
132-
proTx.nVersion = ProTxVersion::GetMax(!bls::bls_legacy_scheme);
132+
proTx.nVersion = ProTxVersion::GetMax(!bls::bls_legacy_scheme, /*is_extended_addr=*/false);
133133
proTx.netInfo = NetInfoInterface::MakeNetInfo(proTx.nVersion);
134134
proTx.proTxHash = proTxHash;
135135
BOOST_CHECK_EQUAL(proTx.netInfo->AddEntry(strprintf("1.1.1.1:%d", port)), NetInfoStatus::Success);
@@ -150,7 +150,7 @@ static CMutableTransaction CreateProUpServTx(const CChain& active_chain, const C
150150
static CMutableTransaction CreateProUpRegTx(const CChain& active_chain, const CTxMemPool& mempool, SimpleUTXOMap& utxos, const uint256& proTxHash, const CKey& mnKey, const CBLSPublicKey& pubKeyOperator, const CKeyID& keyIDVoting, const CScript& scriptPayout, const CKey& coinbaseKey)
151151
{
152152
CProUpRegTx proTx;
153-
proTx.nVersion = ProTxVersion::GetMax(!bls::bls_legacy_scheme);
153+
proTx.nVersion = ProTxVersion::GetMax(!bls::bls_legacy_scheme, /*is_extended_addr=*/false);
154154
proTx.proTxHash = proTxHash;
155155
proTx.pubKeyOperator.Set(pubKeyOperator, bls::bls_legacy_scheme.load());
156156
proTx.keyIDVoting = keyIDVoting;
@@ -171,7 +171,7 @@ static CMutableTransaction CreateProUpRegTx(const CChain& active_chain, const CT
171171
static CMutableTransaction CreateProUpRevTx(const CChain& active_chain, const CTxMemPool& mempool, SimpleUTXOMap& utxos, const uint256& proTxHash, const CBLSSecretKey& operatorKey, const CKey& coinbaseKey)
172172
{
173173
CProUpRevTx proTx;
174-
proTx.nVersion = ProTxVersion::GetMax(!bls::bls_legacy_scheme);
174+
proTx.nVersion = ProTxVersion::GetMax(!bls::bls_legacy_scheme, /*is_extended_addr=*/false);
175175
proTx.proTxHash = proTxHash;
176176

177177
CMutableTransaction tx;
@@ -640,7 +640,7 @@ void FuncTestMempoolReorg(TestChainSetup& setup)
640640
BOOST_CHECK_EQUAL(block->GetHash(), chainman.ActiveChain().Tip()->GetBlockHash());
641641

642642
CProRegTx payload;
643-
payload.nVersion = ProTxVersion::GetMax(!bls::bls_legacy_scheme);
643+
payload.nVersion = ProTxVersion::GetMax(!bls::bls_legacy_scheme, /*is_extended_addr=*/false);
644644
payload.netInfo = NetInfoInterface::MakeNetInfo(payload.nVersion);
645645
BOOST_CHECK_EQUAL(payload.netInfo->AddEntry("1.1.1.1:1"), NetInfoStatus::Success);
646646
payload.keyIDOwner = ownerKey.GetPubKey().GetID();
@@ -716,7 +716,7 @@ void FuncTestMempoolDualProregtx(TestChainSetup& setup)
716716
auto scriptPayout = GetScriptForDestination(PKHash(payoutKey.GetPubKey()));
717717

718718
CProRegTx payload;
719-
payload.nVersion = ProTxVersion::GetMax(!bls::bls_legacy_scheme);
719+
payload.nVersion = ProTxVersion::GetMax(!bls::bls_legacy_scheme, /*is_extended_addr=*/false);
720720
payload.netInfo = NetInfoInterface::MakeNetInfo(payload.nVersion);
721721
BOOST_CHECK_EQUAL(payload.netInfo->AddEntry("1.1.1.1:2"), NetInfoStatus::Success);
722722
payload.keyIDOwner = ownerKey.GetPubKey().GetID();
@@ -785,7 +785,7 @@ void FuncVerifyDB(TestChainSetup& setup)
785785
BOOST_CHECK_EQUAL(block->GetHash(), chainman.ActiveChain().Tip()->GetBlockHash());
786786

787787
CProRegTx payload;
788-
payload.nVersion = ProTxVersion::GetMax(!bls::bls_legacy_scheme);
788+
payload.nVersion = ProTxVersion::GetMax(!bls::bls_legacy_scheme, /*is_extended_addr=*/false);
789789
payload.netInfo = NetInfoInterface::MakeNetInfo(payload.nVersion);
790790
BOOST_CHECK_EQUAL(payload.netInfo->AddEntry("1.1.1.1:1"), NetInfoStatus::Success);
791791
payload.keyIDOwner = ownerKey.GetPubKey().GetID();

0 commit comments

Comments
 (0)