Skip to content

Commit 1bbd039

Browse files
committed
evo: introduce new ProTx version for extended addresses (ExtNetInfo)
1 parent 1bf8335 commit 1bbd039

13 files changed

+82
-48
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: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1327,7 +1327,8 @@ static std::optional<ProTx> GetValidatedPayload(const CTransaction& tx, gsl::not
13271327
return std::nullopt;
13281328
}
13291329
const bool is_basic_scheme_active{DeploymentActiveAfter(pindexPrev, Params().GetConsensus(), Consensus::DEPLOYMENT_V19)};
1330-
if (!opt_ptx->IsTriviallyValid(is_basic_scheme_active, state)) {
1330+
const bool is_extended_addr{DeploymentActiveAfter(pindexPrev, Params().GetConsensus(), Consensus::DEPLOYMENT_V23)};
1331+
if (!opt_ptx->IsTriviallyValid(is_basic_scheme_active, is_extended_addr, state)) {
13311332
// pass the state returned by the function above
13321333
return std::nullopt;
13331334
}

src/evo/dmnstate.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ class CDeterministicMNState
9696
READWRITE(CBLSLazyPublicKeyVersionWrapper(const_cast<CBLSLazyPublicKey&>(obj.pubKeyOperator), obj.nVersion == ProTxVersion::LegacyBLS));
9797
READWRITE(
9898
obj.keyIDVoting,
99-
NetInfoSerWrapper(const_cast<std::shared_ptr<NetInfoInterface>&>(obj.netInfo)),
99+
NetInfoSerWrapper(const_cast<std::shared_ptr<NetInfoInterface>&>(obj.netInfo), obj.nVersion >= ProTxVersion::ExtAddr),
100100
obj.scriptPayout,
101101
obj.scriptOperatorPayout,
102102
obj.platformNodeID,
@@ -254,7 +254,9 @@ class CDeterministicMNStateDiff
254254
}
255255
} else if constexpr (BaseType::mask == Field_netInfo) {
256256
if (obj.fields & member.mask) {
257-
READWRITE(NetInfoSerWrapper(const_cast<std::shared_ptr<NetInfoInterface>&>(obj.state.netInfo)));
257+
// As nVersion is stored after netInfo, we use a magic word to determine the underlying implementation
258+
// TODO: Implement this
259+
READWRITE(NetInfoSerWrapper(const_cast<std::shared_ptr<NetInfoInterface>&>(obj.state.netInfo), /*is_extended=*/false));
258260
}
259261
} else {
260262
if (obj.fields & member.mask) {

src/evo/netinfo.h

Lines changed: 10 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>
@@ -138,6 +139,7 @@ class NetInfoInterface
138139
virtual NetInfoList GetEntries() const = 0;
139140

140141
virtual const CService& GetPrimary() const = 0;
142+
virtual bool CanStorePlatform() const = 0;
141143
virtual bool IsEmpty() const = 0;
142144
virtual NetInfoStatus Validate() const = 0;
143145
virtual std::string ToString() const = 0;
@@ -191,6 +193,7 @@ class MnNetInfo final : public NetInfoInterface
191193

192194
const CService& GetPrimary() const override;
193195
bool IsEmpty() const override { return *this == MnNetInfo(); }
196+
bool CanStorePlatform() const override { return false; }
194197
NetInfoStatus Validate() const override;
195198
std::string ToString() const override;
196199

@@ -201,21 +204,25 @@ class MnNetInfo final : public NetInfoInterface
201204
template <typename T1>
202205
std::shared_ptr<NetInfoInterface> MakeNetInfo(const T1& obj)
203206
{
204-
assert(obj.nVersion > 0);
207+
assert(obj.nVersion > 0 && obj.nVersion < ProTxVersion::ExtAddr);
205208
return std::make_shared<MnNetInfo>();
206209
}
207210

208211
class NetInfoSerWrapper
209212
{
210213
private:
211214
std::shared_ptr<NetInfoInterface>& m_data;
215+
const bool m_is_extended{false};
212216

213217
public:
214218
NetInfoSerWrapper() = delete;
215219
NetInfoSerWrapper(const NetInfoSerWrapper&) = delete;
216-
NetInfoSerWrapper(std::shared_ptr<NetInfoInterface>& data) :
217-
m_data{data}
220+
NetInfoSerWrapper(std::shared_ptr<NetInfoInterface>& data, const bool is_extended) :
221+
m_data{data},
222+
m_is_extended{is_extended}
218223
{
224+
// TODO: Remove when extended addresses implementation is added in
225+
assert(!m_is_extended);
219226
}
220227
template <typename Stream>
221228
NetInfoSerWrapper(deserialize_type, Stream& s) { s >> *this; }

src/evo/providertx.cpp

Lines changed: 12 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) {
@@ -36,6 +36,9 @@ bool CProRegTx::IsTriviallyValid(bool is_basic_scheme_active, TxValidationState&
3636
if (!scriptPayout.IsPayToPublicKeyHash() && !scriptPayout.IsPayToScriptHash()) {
3737
return state.Invalid(TxValidationResult::TX_BAD_SPECIAL, "bad-protx-payee");
3838
}
39+
if (netInfo->CanStorePlatform() != (nVersion == ProTxVersion::ExtAddr)) {
40+
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-protx-netinfo-version");
41+
}
3942
for (const NetInfoEntry& entry : netInfo->GetEntries()) {
4043
if (!entry.IsTriviallyValid()) {
4144
return state.Invalid(TxValidationResult::TX_BAD_SPECIAL, "bad-protx-netinfo-bad");
@@ -102,14 +105,17 @@ std::string CProRegTx::ToString() const
102105
platformHTTPPort, netInfo->ToString());
103106
}
104107

105-
bool CProUpServTx::IsTriviallyValid(bool is_basic_scheme_active, TxValidationState& state) const
108+
bool CProUpServTx::IsTriviallyValid(bool is_basic_scheme_active, bool is_extended_addr, TxValidationState& state) const
106109
{
107-
if (nVersion == 0 || nVersion > GetMaxVersion(is_basic_scheme_active)) {
110+
if (nVersion == 0 || nVersion > GetMaxVersion(is_basic_scheme_active, is_extended_addr)) {
108111
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-protx-version");
109112
}
110113
if (nVersion < ProTxVersion::BasicBLS && nType == MnType::Evo) {
111114
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-protx-evo-version");
112115
}
116+
if (netInfo->CanStorePlatform() != (nVersion == ProTxVersion::ExtAddr)) {
117+
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-protx-netinfo-version");
118+
}
113119
if (netInfo->IsEmpty()) {
114120
return state.Invalid(TxValidationResult::TX_BAD_SPECIAL, "bad-protx-netinfo-empty");
115121
}
@@ -137,7 +143,7 @@ std::string CProUpServTx::ToString() const
137143
platformP2PPort, platformHTTPPort, netInfo->ToString());
138144
}
139145

140-
bool CProUpRegTx::IsTriviallyValid(bool is_basic_scheme_active, TxValidationState& state) const
146+
bool CProUpRegTx::IsTriviallyValid(bool is_basic_scheme_active, bool is_extended_addr, TxValidationState& state) const
141147
{
142148
if (nVersion == 0 || nVersion > GetMaxVersion(is_basic_scheme_active)) {
143149
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-protx-version");
@@ -170,7 +176,7 @@ std::string CProUpRegTx::ToString() const
170176
nVersion, proTxHash.ToString(), pubKeyOperator.ToString(), EncodeDestination(PKHash(keyIDVoting)), payee);
171177
}
172178

173-
bool CProUpRevTx::IsTriviallyValid(bool is_basic_scheme_active, TxValidationState& state) const
179+
bool CProUpRevTx::IsTriviallyValid(bool is_basic_scheme_active, bool is_extended_addr, TxValidationState& state) const
174180
{
175181
if (nVersion == 0 || nVersion > GetMaxVersion(is_basic_scheme_active)) {
176182
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
@@ -653,10 +653,12 @@ static UniValue protx_register_common_wrapper(const JSONRPCRequest& request,
653653
tx.nType = TRANSACTION_PROVIDER_REGISTER;
654654

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

657659
CProRegTx ptx;
658660
ptx.nType = mnType;
659-
ptx.nVersion = CProRegTx::GetMaxVersion(/*is_basic_scheme_active=*/!use_legacy);
661+
ptx.nVersion = CProRegTx::GetMaxVersion(/*is_basic_scheme_active=*/!use_legacy, is_extended_addr);
660662
ptx.netInfo = MakeNetInfo(ptx);
661663

662664
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)