Skip to content

Commit 227b428

Browse files
committed
evo: introduce new ProTx version for extended addresses (ExtNetInfo)
1 parent 1f3afb3 commit 227b428

13 files changed

+93
-63
lines changed

src/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ BITCOIN_CORE_H = \
186186
evo/dmn_types.h \
187187
evo/cbtx.h \
188188
evo/chainhelper.h \
189+
evo/common.h \
189190
evo/creditpool.h \
190191
evo/deterministicmns.h \
191192
evo/dmnstate.h \

src/evo/common.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright (c) 2025 The Dash Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#ifndef BITCOIN_EVO_COMMON_H
6+
#define BITCOIN_EVO_COMMON_H
7+
8+
#include <cstdint>
9+
10+
namespace ProTxVersion {
11+
enum : uint16_t {
12+
LegacyBLS = 1,
13+
BasicBLS = 2,
14+
ExtAddr = 3,
15+
};
16+
} // namespace ProTxVersion
17+
18+
#endif // BITCOIN_EVO_COMMON_H

src/evo/deterministicmns.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1235,7 +1235,7 @@ void CDeterministicMNManager::CleanupCache(int nHeight)
12351235
}
12361236

12371237
template <typename ProTx>
1238-
static bool CheckService(const ProTx& proTx, TxValidationState& state)
1238+
static bool CheckService(const ProTx& proTx, bool is_extended_addr, TxValidationState& state)
12391239
{
12401240
switch (proTx.netInfo->Validate()) {
12411241
case NetInfoStatus::BadAddress:
@@ -1339,7 +1339,8 @@ static std::optional<ProTx> GetValidatedPayload(const CTransaction& tx, gsl::not
13391339
return std::nullopt;
13401340
}
13411341
const bool is_basic_scheme_active{DeploymentActiveAfter(pindexPrev, Params().GetConsensus(), Consensus::DEPLOYMENT_V19)};
1342-
if (!opt_ptx->IsTriviallyValid(is_basic_scheme_active, state)) {
1342+
const bool is_extended_addr{DeploymentActiveAfter(pindexPrev, Params().GetConsensus(), Consensus::DEPLOYMENT_V23)};
1343+
if (!opt_ptx->IsTriviallyValid(is_basic_scheme_active, is_extended_addr, state)) {
13431344
// pass the state returned by the function above
13441345
return std::nullopt;
13451346
}
@@ -1356,7 +1357,8 @@ bool CheckProRegTx(CDeterministicMNManager& dmnman, const CTransaction& tx, gsl:
13561357

13571358
// It's allowed to set addr to 0, which will put the MN into PoSe-banned state and require a ProUpServTx to be issues later
13581359
// If any of both is set, it must be valid however
1359-
if (!opt_ptx->netInfo->IsEmpty() && !CheckService(*opt_ptx, state)) {
1360+
const bool is_extended_addr{DeploymentActiveAfter(pindexPrev, Params().GetConsensus(), Consensus::DEPLOYMENT_V23)};
1361+
if (!opt_ptx->netInfo->IsEmpty() && !CheckService(*opt_ptx, is_extended_addr, state)) {
13601362
// pass the state returned by the function above
13611363
return false;
13621364
}
@@ -1476,7 +1478,8 @@ bool CheckProUpServTx(CDeterministicMNManager& dmnman, const CTransaction& tx, g
14761478
return false;
14771479
}
14781480

1479-
if (!CheckService(*opt_ptx, state)) {
1481+
const bool is_extended_addr{DeploymentActiveAfter(pindexPrev, Params().GetConsensus(), Consensus::DEPLOYMENT_V23)};
1482+
if (!CheckService(*opt_ptx, is_extended_addr, state)) {
14801483
// pass the state returned by the function above
14811484
return false;
14821485
}

src/evo/dmnstate.h

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ class CDeterministicMNState
100100
READWRITE(CBLSLazyPublicKeyVersionWrapper(const_cast<CBLSLazyPublicKey&>(obj.pubKeyOperator), obj.nVersion == ProTxVersion::LegacyBLS));
101101
READWRITE(
102102
obj.keyIDVoting,
103-
NetInfoSerWrapper(const_cast<std::shared_ptr<NetInfoInterface>&>(obj.netInfo)),
103+
NetInfoSerWrapper(const_cast<std::shared_ptr<NetInfoInterface>&>(obj.netInfo), obj.nVersion >= ProTxVersion::ExtAddr),
104104
obj.scriptPayout,
105105
obj.scriptOperatorPayout,
106106
obj.platformNodeID,
@@ -224,7 +224,7 @@ class CDeterministicMNStateDiff
224224
fields |= member.mask;
225225
}
226226
});
227-
if (fields & Field_pubKeyOperator) {
227+
if ((fields & Field_netInfo) || (fields & Field_pubKeyOperator)) {
228228
// pubKeyOperator needs nVersion
229229
state.nVersion = b.nVersion;
230230
fields |= Field_nVersion;
@@ -237,30 +237,34 @@ class CDeterministicMNStateDiff
237237
{
238238
READWRITE(VARINT(obj.fields));
239239

240-
// NOTE: reading pubKeyOperator requires nVersion
241-
bool read_pubkey{false};
242240
boost::hana::for_each(members, [&](auto&& member) {
243241
using BaseType = std::decay_t<decltype(member)>;
244-
if constexpr (BaseType::mask == Field_pubKeyOperator) {
242+
// NOTE: reading pubKeyOperator or netInfo requires nVersion
243+
if constexpr (BaseType::mask == Field_netInfo || BaseType::mask == Field_pubKeyOperator) {
245244
if (obj.fields & member.mask) {
246-
SER_READ(obj, read_pubkey = true);
247-
READWRITE(CBLSLazyPublicKeyVersionWrapper(const_cast<CBLSLazyPublicKey&>(obj.state.pubKeyOperator), obj.state.nVersion == ProTxVersion::LegacyBLS));
245+
SER_READ(obj, obj.fields |= Field_nVersion);
246+
}
247+
}
248+
if constexpr (BaseType::mask == Field_pubKeyOperator) {
249+
if ((obj.fields & member.mask) && (obj.fields & Field_nVersion)) {
250+
auto& pubKeyOperator{const_cast<CBLSLazyPublicKey&>(obj.state.pubKeyOperator)};
251+
if (ser_action.ForRead()) {
252+
pubKeyOperator.SetLegacy(/*specificLegacyScheme=*/obj.state.nVersion == ProTxVersion::LegacyBLS);
253+
}
254+
READWRITE(CBLSLazyPublicKeyVersionWrapper(pubKeyOperator,
255+
/*legacy=*/obj.state.nVersion == ProTxVersion::LegacyBLS));
248256
}
249257
} else if constexpr (BaseType::mask == Field_netInfo) {
250-
if (obj.fields & member.mask) {
251-
READWRITE(NetInfoSerWrapper(const_cast<std::shared_ptr<NetInfoInterface>&>(obj.state.netInfo)));
258+
if ((obj.fields & member.mask) && (obj.fields & Field_nVersion)) {
259+
READWRITE(NetInfoSerWrapper(const_cast<std::shared_ptr<NetInfoInterface>&>(obj.state.netInfo),
260+
/*is_extended=*/obj.state.nVersion >= ProTxVersion::ExtAddr));
252261
}
253262
} else {
254263
if (obj.fields & member.mask) {
255264
READWRITE(member.get(obj.state));
256265
}
257266
}
258267
});
259-
260-
if (read_pubkey) {
261-
SER_READ(obj, obj.fields |= Field_nVersion);
262-
SER_READ(obj, obj.state.pubKeyOperator.SetLegacy(obj.state.nVersion == ProTxVersion::LegacyBLS));
263-
}
264268
}
265269

266270
void ApplyToState(CDeterministicMNState& target) const

src/evo/netinfo.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#ifndef BITCOIN_EVO_NETINFO_H
66
#define BITCOIN_EVO_NETINFO_H
77

8+
#include <evo/common.h>
89
#include <netaddress.h>
910
#include <serialize.h>
1011
#include <streams.h>
@@ -215,21 +216,25 @@ class MnNetInfo final : public NetInfoInterface
215216
template <typename T1>
216217
std::shared_ptr<NetInfoInterface> MakeNetInfo(const T1& obj)
217218
{
218-
assert(obj.nVersion > 0);
219+
assert(obj.nVersion > 0 && obj.nVersion < ProTxVersion::ExtAddr);
219220
return std::make_shared<MnNetInfo>();
220221
}
221222

222223
class NetInfoSerWrapper
223224
{
224225
private:
225226
std::shared_ptr<NetInfoInterface>& m_data;
227+
const bool m_is_extended{false};
226228

227229
public:
228230
NetInfoSerWrapper() = delete;
229231
NetInfoSerWrapper(const NetInfoSerWrapper&) = delete;
230-
NetInfoSerWrapper(std::shared_ptr<NetInfoInterface>& data) :
231-
m_data{data}
232+
NetInfoSerWrapper(std::shared_ptr<NetInfoInterface>& data, const bool is_extended) :
233+
m_data{data},
234+
m_is_extended{is_extended}
232235
{
236+
// TODO: Remove when extended addresses implementation is added in
237+
assert(!m_is_extended);
233238
}
234239
template <typename Stream> NetInfoSerWrapper(deserialize_type, Stream& s) { s >> *this; }
235240

src/evo/providertx.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@
1212
#include <tinyformat.h>
1313
#include <util/underlying.h>
1414

15-
bool CProRegTx::IsTriviallyValid(bool is_basic_scheme_active, TxValidationState& state) const
15+
bool CProRegTx::IsTriviallyValid(bool is_basic_scheme_active, bool is_extended_addr, TxValidationState& state) const
1616
{
17-
if (nVersion == 0 || nVersion > GetMaxVersion(is_basic_scheme_active)) {
17+
if (nVersion == 0 || nVersion > GetMaxVersion(is_basic_scheme_active, is_extended_addr)) {
1818
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-protx-version");
1919
}
2020
if (nVersion < ProTxVersion::BasicBLS && nType == MnType::Evo) {
@@ -102,9 +102,9 @@ std::string CProRegTx::ToString() const
102102
platformHTTPPort, netInfo->ToString());
103103
}
104104

105-
bool CProUpServTx::IsTriviallyValid(bool is_basic_scheme_active, TxValidationState& state) const
105+
bool CProUpServTx::IsTriviallyValid(bool is_basic_scheme_active, bool is_extended_addr, TxValidationState& state) const
106106
{
107-
if (nVersion == 0 || nVersion > GetMaxVersion(is_basic_scheme_active)) {
107+
if (nVersion == 0 || nVersion > GetMaxVersion(is_basic_scheme_active, is_extended_addr)) {
108108
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-protx-version");
109109
}
110110
if (nVersion < ProTxVersion::BasicBLS && nType == MnType::Evo) {
@@ -137,7 +137,7 @@ std::string CProUpServTx::ToString() const
137137
platformP2PPort, platformHTTPPort, netInfo->ToString());
138138
}
139139

140-
bool CProUpRegTx::IsTriviallyValid(bool is_basic_scheme_active, TxValidationState& state) const
140+
bool CProUpRegTx::IsTriviallyValid(bool is_basic_scheme_active, bool is_extended_addr, TxValidationState& state) const
141141
{
142142
if (nVersion == 0 || nVersion > GetMaxVersion(is_basic_scheme_active)) {
143143
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-protx-version");
@@ -170,7 +170,7 @@ std::string CProUpRegTx::ToString() const
170170
nVersion, proTxHash.ToString(), pubKeyOperator.ToString(), EncodeDestination(PKHash(keyIDVoting)), payee);
171171
}
172172

173-
bool CProUpRevTx::IsTriviallyValid(bool is_basic_scheme_active, TxValidationState& state) const
173+
bool CProUpRevTx::IsTriviallyValid(bool is_basic_scheme_active, bool is_extended_addr, TxValidationState& state) const
174174
{
175175
if (nVersion == 0 || nVersion > GetMaxVersion(is_basic_scheme_active)) {
176176
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-protx-version");

src/evo/providertx.h

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#define BITCOIN_EVO_PROVIDERTX_H
77

88
#include <bls/bls.h>
9+
#include <evo/common.h>
910
#include <evo/netinfo.h>
1011
#include <evo/specialtx.h>
1112
#include <primitives/transaction.h>
@@ -20,21 +21,15 @@
2021

2122
class TxValidationState;
2223

23-
namespace ProTxVersion {
24-
enum : uint16_t {
25-
LegacyBLS = 1,
26-
BasicBLS = 2,
27-
};
28-
} // namespace ProTxVersion
29-
3024
class CProRegTx
3125
{
3226
public:
3327
static constexpr auto SPECIALTX_TYPE = TRANSACTION_PROVIDER_REGISTER;
3428

35-
[[nodiscard]] static constexpr uint16_t GetMaxVersion(const bool is_basic_scheme_active)
29+
[[nodiscard]] static constexpr uint16_t GetMaxVersion(const bool is_basic_scheme_active, const bool is_extended_addr)
3630
{
37-
return is_basic_scheme_active ? ProTxVersion::BasicBLS : ProTxVersion::LegacyBLS;
31+
return is_extended_addr ? ProTxVersion::ExtAddr
32+
: (is_basic_scheme_active ? ProTxVersion::BasicBLS : ProTxVersion::LegacyBLS);
3833
}
3934

4035
uint16_t nVersion{ProTxVersion::LegacyBLS}; // message version
@@ -58,7 +53,7 @@ class CProRegTx
5853
READWRITE(
5954
obj.nVersion
6055
);
61-
if (obj.nVersion == 0 || obj.nVersion > GetMaxVersion(/*is_basic_scheme_active=*/true)) {
56+
if (obj.nVersion == 0 || obj.nVersion > GetMaxVersion(/*is_basic_scheme_active=*/true, /*is_extended_addr=*/true)) {
6257
// unknown version, bail out early
6358
return;
6459
}
@@ -67,7 +62,7 @@ class CProRegTx
6762
obj.nType,
6863
obj.nMode,
6964
obj.collateralOutpoint,
70-
NetInfoSerWrapper(const_cast<std::shared_ptr<NetInfoInterface>&>(obj.netInfo)),
65+
NetInfoSerWrapper(const_cast<std::shared_ptr<NetInfoInterface>&>(obj.netInfo), obj.nVersion >= ProTxVersion::ExtAddr),
7166
obj.keyIDOwner,
7267
CBLSLazyPublicKeyVersionWrapper(const_cast<CBLSLazyPublicKey&>(obj.pubKeyOperator), (obj.nVersion == ProTxVersion::LegacyBLS)),
7368
obj.keyIDVoting,
@@ -94,17 +89,18 @@ class CProRegTx
9489

9590
[[nodiscard]] UniValue ToJson() const;
9691

97-
bool IsTriviallyValid(bool is_basic_scheme_active, TxValidationState& state) const;
92+
bool IsTriviallyValid(bool is_basic_scheme_active, bool is_extended_addr, TxValidationState& state) const;
9893
};
9994

10095
class CProUpServTx
10196
{
10297
public:
10398
static constexpr auto SPECIALTX_TYPE = TRANSACTION_PROVIDER_UPDATE_SERVICE;
10499

105-
[[nodiscard]] static constexpr uint16_t GetMaxVersion(const bool is_basic_scheme_active)
100+
[[nodiscard]] static constexpr uint16_t GetMaxVersion(const bool is_basic_scheme_active, const bool is_extended_addr)
106101
{
107-
return is_basic_scheme_active ? ProTxVersion::BasicBLS : ProTxVersion::LegacyBLS;
102+
return is_extended_addr ? ProTxVersion::ExtAddr
103+
: (is_basic_scheme_active ? ProTxVersion::BasicBLS : ProTxVersion::LegacyBLS);
108104
}
109105

110106
uint16_t nVersion{ProTxVersion::LegacyBLS}; // message version
@@ -123,7 +119,7 @@ class CProUpServTx
123119
READWRITE(
124120
obj.nVersion
125121
);
126-
if (obj.nVersion == 0 || obj.nVersion > GetMaxVersion(/*is_basic_scheme_active=*/true)) {
122+
if (obj.nVersion == 0 || obj.nVersion > GetMaxVersion(/*is_basic_scheme_active=*/true, /*is_extended_addr=*/true)) {
127123
// unknown version, bail out early
128124
return;
129125
}
@@ -133,7 +129,7 @@ class CProUpServTx
133129
}
134130
READWRITE(
135131
obj.proTxHash,
136-
NetInfoSerWrapper(const_cast<std::shared_ptr<NetInfoInterface>&>(obj.netInfo)),
132+
NetInfoSerWrapper(const_cast<std::shared_ptr<NetInfoInterface>&>(obj.netInfo), obj.nVersion >= ProTxVersion::ExtAddr),
137133
obj.scriptOperatorPayout,
138134
obj.inputsHash
139135
);
@@ -154,7 +150,7 @@ class CProUpServTx
154150

155151
[[nodiscard]] UniValue ToJson() const;
156152

157-
bool IsTriviallyValid(bool is_basic_scheme_active, TxValidationState& state) const;
153+
bool IsTriviallyValid(bool is_basic_scheme_active, bool is_extended_addr, TxValidationState& state) const;
158154
};
159155

160156
class CProUpRegTx
@@ -204,7 +200,7 @@ class CProUpRegTx
204200

205201
[[nodiscard]] UniValue ToJson() const;
206202

207-
bool IsTriviallyValid(bool is_basic_scheme_active, TxValidationState& state) const;
203+
bool IsTriviallyValid(bool is_basic_scheme_active, bool is_extended_addr, TxValidationState& state) const;
208204
};
209205

210206
class CProUpRevTx
@@ -257,7 +253,7 @@ class CProUpRevTx
257253

258254
[[nodiscard]] UniValue ToJson() const;
259255

260-
bool IsTriviallyValid(bool is_basic_scheme_active, TxValidationState& state) const;
256+
bool IsTriviallyValid(bool is_basic_scheme_active, bool is_extended_addr, TxValidationState& state) const;
261257
};
262258

263259
template <typename ProTx>
@@ -270,5 +266,4 @@ static bool CheckInputsHash(const CTransaction& tx, const ProTx& proTx, TxValida
270266
return true;
271267
}
272268

273-
274269
#endif // BITCOIN_EVO_PROVIDERTX_H

src/evo/simplifiedmns.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ class CSimplifiedMNListEntry
7676
READWRITE(
7777
obj.proRegTxHash,
7878
obj.confirmedHash,
79-
NetInfoSerWrapper(const_cast<std::shared_ptr<NetInfoInterface>&>(obj.netInfo)),
79+
NetInfoSerWrapper(const_cast<std::shared_ptr<NetInfoInterface>&>(obj.netInfo), obj.nVersion >= ProTxVersion::ExtAddr),
8080
CBLSLazyPublicKeyVersionWrapper(const_cast<CBLSLazyPublicKey&>(obj.pubKeyOperator), (obj.nVersion == ProTxVersion::LegacyBLS)),
8181
obj.keyIDVoting,
8282
obj.isValid

src/rpc/evo.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -654,10 +654,12 @@ static UniValue protx_register_common_wrapper(const JSONRPCRequest& request,
654654
tx.nType = TRANSACTION_PROVIDER_REGISTER;
655655

656656
const bool use_legacy = specific_legacy_bls_scheme;
657+
const bool is_extended_addr{DeploymentActiveAfter(WITH_LOCK(::cs_main, return chainman.ActiveChain().Tip()),
658+
Params().GetConsensus(), Consensus::DEPLOYMENT_V23)};
657659

658660
CProRegTx ptx;
659661
ptx.nType = mnType;
660-
ptx.nVersion = CProRegTx::GetMaxVersion(/*is_basic_scheme_active=*/!use_legacy);
662+
ptx.nVersion = CProRegTx::GetMaxVersion(/*is_basic_scheme_active=*/!use_legacy, is_extended_addr);
661663
ptx.netInfo = MakeNetInfo(ptx);
662664

663665
if (action == ProTxRegisterAction::Fund) {

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 = CProRegTx::GetMaxVersion(!bls::bls_legacy_scheme);
118+
proTx.nVersion = CProRegTx::GetMaxVersion(!bls::bls_legacy_scheme, /*is_extended_addr=*/false);
119119
proTx.netInfo = MakeNetInfo(proTx);
120120
proTx.collateralOutpoint.n = 0;
121121
BOOST_CHECK_EQUAL(proTx.netInfo->AddEntry(strprintf("1.1.1.1:%d", port)), NetInfoStatus::Success);

0 commit comments

Comments
 (0)