Skip to content

Commit 1c20fef

Browse files
committed
evo: introduce new ProTx version for extended addresses (ExtNetInfo)
1 parent 88b11b2 commit 1c20fef

10 files changed

+50
-24
lines changed

src/evo/dmnstate.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ 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), obj.nVersion >= ProTxVersion::ExtAddr),
101101
obj.scriptPayout,
102102
obj.scriptOperatorPayout,
103103
obj.platformNodeID,
@@ -255,7 +255,9 @@ class CDeterministicMNStateDiff
255255
}
256256
} else if constexpr (BaseType::mask == Field_netInfo) {
257257
if (obj.fields & member.mask) {
258-
READWRITE(NetInfoSerWrapper(const_cast<std::shared_ptr<NetInfoInterface>&>(obj.state.netInfo)));
258+
// As nVersion is stored after netInfo, we use a magic word to determine the underlying implementation
259+
// TODO: Implement this
260+
READWRITE(NetInfoSerWrapper(const_cast<std::shared_ptr<NetInfoInterface>&>(obj.state.netInfo), /*is_extended=*/false));
259261
}
260262
} else {
261263
if (obj.fields & member.mask) {

src/evo/netinfo.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ std::string NetInfoEntry::ToStringAddrPort() const
149149

150150
std::shared_ptr<NetInfoInterface> NetInfoInterface::MakeNetInfo(const uint16_t nVersion)
151151
{
152-
assert(nVersion > 0);
152+
assert(nVersion > 0 && nVersion < /*ProTxVersion::ExtAddr=*/3);
153153
return std::make_shared<MnNetInfo>();
154154
}
155155

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
template <typename Stream>
226232
NetInfoSerWrapper(deserialize_type, Stream& s) { s >> *this; }

src/evo/providertx.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ namespace ProTxVersion {
1818
{
1919
return ProTxVersion::GetMax(
2020
is_basic_override ? *is_basic_override
21-
: DeploymentActiveAfter(pindexPrev, Params().GetConsensus(), Consensus::DEPLOYMENT_V19));
21+
: DeploymentActiveAfter(pindexPrev, Params().GetConsensus(), Consensus::DEPLOYMENT_V19),
22+
DeploymentActiveAfter(pindexPrev, Params().GetConsensus(), Consensus::DEPLOYMENT_V23));
2223
}
2324
} // namespace ProTxVersion
2425

@@ -46,6 +47,9 @@ bool CProRegTx::IsTriviallyValid(gsl::not_null<const CBlockIndex*> pindexPrev, T
4647
if (!scriptPayout.IsPayToPublicKeyHash() && !scriptPayout.IsPayToScriptHash()) {
4748
return state.Invalid(TxValidationResult::TX_BAD_SPECIAL, "bad-protx-payee");
4849
}
50+
if (netInfo->CanStorePlatform() != (nVersion == ProTxVersion::ExtAddr)) {
51+
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-protx-netinfo-version");
52+
}
4953
for (const NetInfoEntry& entry : netInfo->GetEntries()) {
5054
if (!entry.IsTriviallyValid()) {
5155
return state.Invalid(TxValidationResult::TX_BAD_SPECIAL, "bad-protx-netinfo-bad");
@@ -120,6 +124,9 @@ bool CProUpServTx::IsTriviallyValid(gsl::not_null<const CBlockIndex*> pindexPrev
120124
if (nVersion < ProTxVersion::BasicBLS && nType == MnType::Evo) {
121125
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-protx-evo-version");
122126
}
127+
if (netInfo->CanStorePlatform() != (nVersion == ProTxVersion::ExtAddr)) {
128+
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-protx-netinfo-version");
129+
}
123130
if (netInfo->IsEmpty()) {
124131
return state.Invalid(TxValidationResult::TX_BAD_SPECIAL, "bad-protx-netinfo-empty");
125132
}

src/evo/providertx.h

Lines changed: 18 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
@@ -69,7 +79,7 @@ class CProRegTx
6979
READWRITE(
7080
obj.nVersion
7181
);
72-
if (obj.nVersion == 0 || obj.nVersion > ProTxVersion::GetMax(/*is_basic_scheme_active=*/true)) {
82+
if (obj.nVersion == 0 || obj.nVersion > ProTxVersion::GetMax(/*is_basic_scheme_active=*/true, /*is_extended_addr=*/true)) {
7383
// unknown version, bail out early
7484
return;
7585
}
@@ -78,7 +88,7 @@ class CProRegTx
7888
obj.nType,
7989
obj.nMode,
8090
obj.collateralOutpoint,
81-
NetInfoSerWrapper(const_cast<std::shared_ptr<NetInfoInterface>&>(obj.netInfo)),
91+
NetInfoSerWrapper(const_cast<std::shared_ptr<NetInfoInterface>&>(obj.netInfo), obj.nVersion >= ProTxVersion::ExtAddr),
8292
obj.keyIDOwner,
8393
CBLSLazyPublicKeyVersionWrapper(const_cast<CBLSLazyPublicKey&>(obj.pubKeyOperator), (obj.nVersion == ProTxVersion::LegacyBLS)),
8494
obj.keyIDVoting,
@@ -129,7 +139,7 @@ class CProUpServTx
129139
READWRITE(
130140
obj.nVersion
131141
);
132-
if (obj.nVersion == 0 || obj.nVersion > ProTxVersion::GetMax(/*is_basic_scheme_active=*/true)) {
142+
if (obj.nVersion == 0 || obj.nVersion > ProTxVersion::GetMax(/*is_basic_scheme_active=*/true, /*is_extended_addr=*/true)) {
133143
// unknown version, bail out early
134144
return;
135145
}
@@ -139,7 +149,7 @@ class CProUpServTx
139149
}
140150
READWRITE(
141151
obj.proTxHash,
142-
NetInfoSerWrapper(const_cast<std::shared_ptr<NetInfoInterface>&>(obj.netInfo)),
152+
NetInfoSerWrapper(const_cast<std::shared_ptr<NetInfoInterface>&>(obj.netInfo), obj.nVersion >= ProTxVersion::ExtAddr),
143153
obj.scriptOperatorPayout,
144154
obj.inputsHash
145155
);
@@ -182,7 +192,7 @@ class CProUpRegTx
182192
READWRITE(
183193
obj.nVersion
184194
);
185-
if (obj.nVersion == 0 || obj.nVersion > ProTxVersion::GetMax(/*is_basic_scheme_active=*/true)) {
195+
if (obj.nVersion == 0 || obj.nVersion > ProTxVersion::GetMax(/*is_basic_scheme_active=*/true, /*is_extended_addr=*/true)) {
186196
// unknown version, bail out early
187197
return;
188198
}
@@ -233,7 +243,7 @@ class CProUpRevTx
233243
READWRITE(
234244
obj.nVersion
235245
);
236-
if (obj.nVersion == 0 || obj.nVersion > ProTxVersion::GetMax(/*is_basic_scheme_active=*/true)) {
246+
if (obj.nVersion == 0 || obj.nVersion > ProTxVersion::GetMax(/*is_basic_scheme_active=*/true, /*is_extended_addr=*/true)) {
237247
// unknown version, bail out early
238248
return;
239249
}

src/evo/simplifiedmns.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ 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), obj.nVersion >= ProTxVersion::ExtAddr),
8181
CBLSLazyPublicKeyVersionWrapper(const_cast<CBLSLazyPublicKey&>(obj.pubKeyOperator), (obj.nVersion == ProTxVersion::LegacyBLS)),
8282
obj.keyIDVoting,
8383
obj.isValid

src/test/block_reward_reallocation_tests.cpp

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

117117
CProRegTx proTx;
118-
proTx.nVersion = ProTxVersion::GetMax(!bls::bls_legacy_scheme);
118+
proTx.nVersion = ProTxVersion::GetMax(!bls::bls_legacy_scheme, /*is_extended_addr=*/false);
119119
proTx.netInfo = NetInfoInterface::MakeNetInfo(proTx.nVersion);
120120
proTx.collateralOutpoint.n = 0;
121121
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
@@ -104,7 +104,7 @@ static CMutableTransaction CreateProRegTx(const CChain& active_chain, const CTxM
104104
operatorKeyRet.MakeNewKey();
105105

106106
CProRegTx proTx;
107-
proTx.nVersion = ProTxVersion::GetMax(!bls::bls_legacy_scheme);
107+
proTx.nVersion = ProTxVersion::GetMax(!bls::bls_legacy_scheme, /*is_extended_addr=*/false);
108108
proTx.netInfo = NetInfoInterface::MakeNetInfo(proTx.nVersion);
109109
proTx.collateralOutpoint.n = 0;
110110
BOOST_CHECK_EQUAL(proTx.netInfo->AddEntry(strprintf("1.1.1.1:%d", port)), NetInfoStatus::Success);
@@ -127,7 +127,7 @@ static CMutableTransaction CreateProRegTx(const CChain& active_chain, const CTxM
127127
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)
128128
{
129129
CProUpServTx proTx;
130-
proTx.nVersion = ProTxVersion::GetMax(!bls::bls_legacy_scheme);
130+
proTx.nVersion = ProTxVersion::GetMax(!bls::bls_legacy_scheme, /*is_extended_addr=*/false);
131131
proTx.netInfo = NetInfoInterface::MakeNetInfo(proTx.nVersion);
132132
proTx.proTxHash = proTxHash;
133133
BOOST_CHECK_EQUAL(proTx.netInfo->AddEntry(strprintf("1.1.1.1:%d", port)), NetInfoStatus::Success);
@@ -148,7 +148,7 @@ static CMutableTransaction CreateProUpServTx(const CChain& active_chain, const C
148148
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)
149149
{
150150
CProUpRegTx proTx;
151-
proTx.nVersion = ProTxVersion::GetMax(!bls::bls_legacy_scheme);
151+
proTx.nVersion = ProTxVersion::GetMax(!bls::bls_legacy_scheme, /*is_extended_addr=*/false);
152152
proTx.proTxHash = proTxHash;
153153
proTx.pubKeyOperator.Set(pubKeyOperator, bls::bls_legacy_scheme.load());
154154
proTx.keyIDVoting = keyIDVoting;
@@ -169,7 +169,7 @@ static CMutableTransaction CreateProUpRegTx(const CChain& active_chain, const CT
169169
static CMutableTransaction CreateProUpRevTx(const CChain& active_chain, const CTxMemPool& mempool, SimpleUTXOMap& utxos, const uint256& proTxHash, const CBLSSecretKey& operatorKey, const CKey& coinbaseKey)
170170
{
171171
CProUpRevTx proTx;
172-
proTx.nVersion = ProTxVersion::GetMax(!bls::bls_legacy_scheme);
172+
proTx.nVersion = ProTxVersion::GetMax(!bls::bls_legacy_scheme, /*is_extended_addr=*/false);
173173
proTx.proTxHash = proTxHash;
174174

175175
CMutableTransaction tx;
@@ -638,7 +638,7 @@ void FuncTestMempoolReorg(TestChainSetup& setup)
638638
BOOST_CHECK_EQUAL(block->GetHash(), chainman.ActiveChain().Tip()->GetBlockHash());
639639

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

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

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

src/test/evo_simplifiedmns_tests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ BOOST_AUTO_TEST_CASE(simplifiedmns_merkleroots)
1919
std::vector<CSimplifiedMNListEntry> entries;
2020
for (size_t i = 1; i < 16; i++) {
2121
CSimplifiedMNListEntry smle;
22-
smle.nVersion = ProTxVersion::GetMax(!bls::bls_legacy_scheme);
22+
smle.nVersion = ProTxVersion::GetMax(!bls::bls_legacy_scheme, /*is_extended_addr=*/false);
2323
smle.netInfo = NetInfoInterface::MakeNetInfo(smle.nVersion);
2424
smle.proRegTxHash.SetHex(strprintf("%064x", i));
2525
smle.confirmedHash.SetHex(strprintf("%064x", i));

src/test/evo_trivialvalidation.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ void trivialvalidation_runner(const CChain& active_chain, const std::string& jso
6262
txType = test[1].get_str();
6363
BOOST_CHECK(test[2].get_str() == "basic" || test[2].get_str() == "legacy");
6464
// Determine which pindexPrev to supply based on whether we want to validate legacy or basic
65+
// TODO: Introduce trivial validation test vectors for extended addresses
6566
const CBlockIndex* pindexPrev{(test[2].get_str() == "basic") ? active_chain[100] : active_chain[98]};
6667
assert(pindexPrev);
6768
// Raw transaction

0 commit comments

Comments
 (0)