Skip to content

Commit dfbc8a1

Browse files
committed
evo: allow swapping MnNetInfo with a differing underlying impl
1 parent 5ad962c commit dfbc8a1

23 files changed

+171
-85
lines changed

src/coinjoin/client.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ void CCoinJoinClientSession::ProcessMessage(CNode& peer, CChainState& active_cha
186186
if (!m_mn_sync.IsBlockchainSynced()) return;
187187

188188
if (!mixingMasternode) return;
189-
if (mixingMasternode->pdmnState->netInfo.GetPrimary() != peer.addr) return;
189+
if (mixingMasternode->pdmnState->netInfo->GetPrimary() != peer.addr) return;
190190

191191
if (msg_type == NetMsgType::DSSTATUSUPDATE) {
192192
CCoinJoinStatusUpdate psssup;
@@ -1106,7 +1106,7 @@ bool CCoinJoinClientSession::JoinExistingQueue(CAmount nBalanceNeedsAnonymized,
11061106

11071107
m_clientman.AddUsedMasternode(dsq.masternodeOutpoint);
11081108

1109-
if (connman.IsMasternodeOrDisconnectRequested(dmn->pdmnState->netInfo.GetPrimary())) {
1109+
if (connman.IsMasternodeOrDisconnectRequested(dmn->pdmnState->netInfo->GetPrimary())) {
11101110
WalletCJLogPrint(m_wallet, /* Continued */
11111111
"CCoinJoinClientSession::JoinExistingQueue -- skipping connection, masternode=%s\n", dmn->proTxHash.ToString());
11121112
continue;
@@ -1178,7 +1178,7 @@ bool CCoinJoinClientSession::StartNewQueue(CAmount nBalanceNeedsAnonymized, CCon
11781178
continue;
11791179
}
11801180

1181-
if (connman.IsMasternodeOrDisconnectRequested(dmn->pdmnState->netInfo.GetPrimary())) {
1181+
if (connman.IsMasternodeOrDisconnectRequested(dmn->pdmnState->netInfo->GetPrimary())) {
11821182
WalletCJLogPrint(m_wallet, "CCoinJoinClientSession::StartNewQueue -- skipping connection, masternode=%s\n",
11831183
dmn->proTxHash.ToString());
11841184
nTries++;
@@ -1218,7 +1218,7 @@ bool CCoinJoinClientSession::ProcessPendingDsaRequest(CConnman& connman)
12181218

12191219
CService mn_addr;
12201220
if (auto dmn = m_dmnman.GetListAtChainTip().GetMN(pendingDsaRequest.GetProTxHash())) {
1221-
mn_addr = Assert(dmn->pdmnState)->netInfo.GetPrimary();
1221+
mn_addr = Assert(dmn->pdmnState)->netInfo->GetPrimary();
12221222
} else {
12231223
WalletCJLogPrint(m_wallet, "CCoinJoinClientSession::%s -- cannot find address to connect, masternode=%s\n", __func__,
12241224
pendingDsaRequest.GetProTxHash().ToString());
@@ -1820,7 +1820,7 @@ void CCoinJoinClientSession::RelayIn(const CCoinJoinEntry& entry, CConnman& conn
18201820
{
18211821
if (!mixingMasternode) return;
18221822

1823-
connman.ForNode(mixingMasternode->pdmnState->netInfo.GetPrimary(), [&entry, &connman, this](CNode* pnode) {
1823+
connman.ForNode(mixingMasternode->pdmnState->netInfo->GetPrimary(), [&entry, &connman, this](CNode* pnode) {
18241824
WalletCJLogPrint(m_wallet, "CCoinJoinClientSession::RelayIn -- found master, relaying message to %s\n",
18251825
pnode->addr.ToStringAddrPort());
18261826
CNetMsgMaker msgMaker(pnode->GetCommonVersion());
@@ -1876,7 +1876,7 @@ void CCoinJoinClientSession::GetJsonInfo(UniValue& obj) const
18761876
assert(mixingMasternode->pdmnState);
18771877
obj.pushKV("protxhash", mixingMasternode->proTxHash.ToString());
18781878
obj.pushKV("outpoint", mixingMasternode->collateralOutpoint.ToStringShort());
1879-
obj.pushKV("service", mixingMasternode->pdmnState->netInfo.GetPrimary().ToStringAddrPort());
1879+
obj.pushKV("service", mixingMasternode->pdmnState->netInfo->GetPrimary().ToStringAddrPort());
18801880
}
18811881
obj.pushKV("denomination", ValueFromAmount(CoinJoin::DenominationToAmount(nSessionDenom)));
18821882
obj.pushKV("state", GetStateString());

src/evo/core_write.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767
ret.pushKV("type", ToUnderlying(nType));
6868
ret.pushKV("collateralHash", collateralOutpoint.hash.ToString());
6969
ret.pushKV("collateralIndex", (int)collateralOutpoint.n);
70-
ret.pushKV("service", netInfo.GetPrimary().ToStringAddrPort());
70+
ret.pushKV("service", netInfo->GetPrimary().ToStringAddrPort());
7171
ret.pushKV("ownerAddress", EncodeDestination(PKHash(keyIDOwner)));
7272
ret.pushKV("votingAddress", EncodeDestination(PKHash(keyIDVoting)));
7373
if (CTxDestination dest; ExtractDestination(scriptPayout, dest)) {
@@ -114,7 +114,7 @@
114114
ret.pushKV("version", nVersion);
115115
ret.pushKV("type", ToUnderlying(nType));
116116
ret.pushKV("proTxHash", proTxHash.ToString());
117-
ret.pushKV("service", netInfo.GetPrimary().ToStringAddrPort());
117+
ret.pushKV("service", netInfo->GetPrimary().ToStringAddrPort());
118118
if (CTxDestination dest; ExtractDestination(scriptOperatorPayout, dest)) {
119119
ret.pushKV("operatorPayoutAddress", EncodeDestination(dest));
120120
}

src/evo/deterministicmns.cpp

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,7 @@ void CDeterministicMNList::AddMN(const CDeterministicMNCPtr& dmn, bool fBumpTota
470470
throw(std::runtime_error(strprintf("%s: Can't add a masternode %s with a duplicate collateralOutpoint=%s", __func__,
471471
dmn->proTxHash.ToString(), dmn->collateralOutpoint.ToStringShort())));
472472
}
473-
for (const NetInfoEntry& entry : dmn->pdmnState->netInfo.GetEntries()) {
473+
for (const NetInfoEntry& entry : dmn->pdmnState->netInfo->GetEntries()) {
474474
if (const auto& service_opt{entry.GetAddrPort()}; service_opt.has_value()) {
475475
const CService& service{service_opt.value()};
476476
if (!AddUniqueProperty(*dmn, service)) {
@@ -524,7 +524,7 @@ void CDeterministicMNList::UpdateMN(const CDeterministicMN& oldDmn, const std::s
524524
// We track each individual entry in netInfo as opposed to netInfo itself (preventing us from
525525
// using UpdateUniqueProperty()), so we need to successfully purge all old entries and insert
526526
// new entries to successfully update.
527-
for (const NetInfoEntry& old_entry : oldState->netInfo.GetEntries()) {
527+
for (const NetInfoEntry& old_entry : oldState->netInfo->GetEntries()) {
528528
if (const auto& service_opt{old_entry.GetAddrPort()}; service_opt.has_value()) {
529529
const CService& service{service_opt.value()};
530530
if (!DeleteUniqueProperty(*dmn, service)) {
@@ -534,7 +534,7 @@ void CDeterministicMNList::UpdateMN(const CDeterministicMN& oldDmn, const std::s
534534
return strprintf("invalid address");
535535
}
536536
}
537-
for (const NetInfoEntry& new_entry : pdmnState->netInfo.GetEntries()) {
537+
for (const NetInfoEntry& new_entry : pdmnState->netInfo->GetEntries()) {
538538
if (const auto& service_opt{new_entry.GetAddrPort()}; service_opt.has_value()) {
539539
const CService& service{service_opt.value()};
540540
if (!AddUniqueProperty(*dmn, service)) {
@@ -607,7 +607,7 @@ void CDeterministicMNList::RemoveMN(const uint256& proTxHash)
607607
throw(std::runtime_error(strprintf("%s: Can't delete a masternode %s with a collateralOutpoint=%s", __func__,
608608
proTxHash.ToString(), dmn->collateralOutpoint.ToStringShort())));
609609
}
610-
for (const NetInfoEntry& entry : dmn->pdmnState->netInfo.GetEntries()) {
610+
for (const NetInfoEntry& entry : dmn->pdmnState->netInfo->GetEntries()) {
611611
if (const auto& service_opt{entry.GetAddrPort()}; service_opt.has_value()) {
612612
const CService& service{service_opt.value()};
613613
if (!DeleteUniqueProperty(*dmn, service)) {
@@ -833,7 +833,7 @@ bool CDeterministicMNManager::BuildNewListFromBlock(const CBlock& block, gsl::no
833833
}
834834
}
835835

836-
for (const NetInfoEntry& entry : proTx.netInfo.GetEntries()) {
836+
for (const NetInfoEntry& entry : proTx.netInfo->GetEntries()) {
837837
if (const auto& service_opt{entry.GetAddrPort()}; service_opt.has_value()) {
838838
const CService& service{service_opt.value()};
839839
if (newList.HasUniqueProperty(service)) {
@@ -851,7 +851,7 @@ bool CDeterministicMNManager::BuildNewListFromBlock(const CBlock& block, gsl::no
851851

852852
auto dmnState = std::make_shared<CDeterministicMNState>(proTx);
853853
dmnState->nRegisteredHeight = nHeight;
854-
if (proTx.netInfo.IsEmpty()) {
854+
if (proTx.netInfo->IsEmpty()) {
855855
// start in banned pdmnState as we need to wait for a ProUpServTx
856856
dmnState->BanIfNotBanned(nHeight);
857857
}
@@ -869,7 +869,7 @@ bool CDeterministicMNManager::BuildNewListFromBlock(const CBlock& block, gsl::no
869869
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-protx-payload");
870870
}
871871

872-
for (const NetInfoEntry& entry : opt_proTx->netInfo.GetEntries()) {
872+
for (const NetInfoEntry& entry : opt_proTx->netInfo->GetEntries()) {
873873
if (const auto& service_opt{entry.GetAddrPort()}; service_opt.has_value()) {
874874
const CService& service{service_opt.value()};
875875
if (newList.HasUniqueProperty(service) &&
@@ -934,6 +934,7 @@ bool CDeterministicMNManager::BuildNewListFromBlock(const CBlock& block, gsl::no
934934
newState->BanIfNotBanned(nHeight);
935935
// we update pubKeyOperator here, make sure state version matches
936936
newState->nVersion = opt_proTx->nVersion;
937+
newState->netInfo = MakeNetInfo(*newState);
937938
newState->pubKeyOperator = opt_proTx->pubKeyOperator;
938939
}
939940
newState->keyIDVoting = opt_proTx->keyIDVoting;
@@ -1236,7 +1237,7 @@ void CDeterministicMNManager::CleanupCache(int nHeight)
12361237
template <typename ProTx>
12371238
static bool CheckService(const ProTx& proTx, TxValidationState& state)
12381239
{
1239-
switch (proTx.netInfo.Validate()) {
1240+
switch (proTx.netInfo->Validate()) {
12401241
case NetInfoStatus::BadAddress:
12411242
return state.Invalid(TxValidationResult::TX_BAD_SPECIAL, "bad-protx-netinfo-addr");
12421243
case NetInfoStatus::BadInput:
@@ -1287,8 +1288,8 @@ static bool CheckPlatformFields(const ProTx& proTx, TxValidationState& state)
12871288
return state.Invalid(TxValidationResult::TX_BAD_SPECIAL, "bad-protx-platform-http-port");
12881289
}
12891290

1290-
if (proTx.platformP2PPort == proTx.platformHTTPPort || proTx.platformP2PPort == proTx.netInfo.GetPrimary().GetPort() ||
1291-
proTx.platformHTTPPort == proTx.netInfo.GetPrimary().GetPort()) {
1291+
if (proTx.platformP2PPort == proTx.platformHTTPPort || proTx.platformP2PPort == proTx.netInfo->GetPrimary().GetPort() ||
1292+
proTx.platformHTTPPort == proTx.netInfo->GetPrimary().GetPort()) {
12921293
return state.Invalid(TxValidationResult::TX_BAD_SPECIAL, "bad-protx-platform-dup-ports");
12931294
}
12941295

@@ -1353,7 +1354,7 @@ bool CheckProRegTx(CDeterministicMNManager& dmnman, const CTransaction& tx, gsl:
13531354

13541355
// 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
13551356
// If any of both is set, it must be valid however
1356-
if (!opt_ptx->netInfo.IsEmpty() && !CheckService(*opt_ptx, state)) {
1357+
if (!opt_ptx->netInfo->IsEmpty() && !CheckService(*opt_ptx, state)) {
13571358
// pass the state returned by the function above
13581359
return false;
13591360
}
@@ -1413,7 +1414,7 @@ bool CheckProRegTx(CDeterministicMNManager& dmnman, const CTransaction& tx, gsl:
14131414
auto mnList = dmnman.GetListForBlock(pindexPrev);
14141415

14151416
// only allow reusing of addresses when it's for the same collateral (which replaces the old MN)
1416-
for (const NetInfoEntry& entry : opt_ptx->netInfo.GetEntries()) {
1417+
for (const NetInfoEntry& entry : opt_ptx->netInfo->GetEntries()) {
14171418
if (const auto& service_opt{entry.GetAddrPort()}; service_opt.has_value()) {
14181419
const CService& service{service_opt.value()};
14191420
if (mnList.HasUniqueProperty(service) &&
@@ -1491,7 +1492,7 @@ bool CheckProUpServTx(CDeterministicMNManager& dmnman, const CTransaction& tx, g
14911492
}
14921493

14931494
// don't allow updating to addresses already used by other MNs
1494-
for (const NetInfoEntry& entry : opt_ptx->netInfo.GetEntries()) {
1495+
for (const NetInfoEntry& entry : opt_ptx->netInfo->GetEntries()) {
14951496
if (const auto& service_opt{entry.GetAddrPort()}; service_opt.has_value()) {
14961497
const CService& service{service_opt.value()};
14971498
if (mnList.HasUniqueProperty(service) && mnList.GetUniquePropertyMN(service)->proTxHash != opt_ptx->proTxHash) {

src/evo/deterministicmns.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,8 @@ class CDeterministicMNList
399399
DMNL_NO_TEMPLATE(CBLSPublicKey);
400400
DMNL_NO_TEMPLATE(MnNetInfo);
401401
DMNL_NO_TEMPLATE(NetInfoEntry);
402+
DMNL_NO_TEMPLATE(NetInfoInterface);
403+
DMNL_NO_TEMPLATE(std::shared_ptr<NetInfoInterface>);
402404
#undef DMNL_NO_TEMPLATE
403405
return ::SerializeHash(v);
404406
}

src/evo/dmnstate.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,14 @@ std::string CDeterministicMNState::ToString() const
3232
" %s",
3333
nVersion, nRegisteredHeight, nLastPaidHeight, nPoSePenalty, nPoSeRevivedHeight, nPoSeBanHeight,
3434
nRevocationReason, EncodeDestination(PKHash(keyIDOwner)), pubKeyOperator.ToString(),
35-
EncodeDestination(PKHash(keyIDVoting)), payoutAddress, operatorPayoutAddress, netInfo.ToString());
35+
EncodeDestination(PKHash(keyIDVoting)), payoutAddress, operatorPayoutAddress, netInfo->ToString());
3636
}
3737

3838
UniValue CDeterministicMNState::ToJson(MnType nType) const
3939
{
4040
UniValue obj(UniValue::VOBJ);
4141
obj.pushKV("version", nVersion);
42-
obj.pushKV("service", netInfo.GetPrimary().ToStringAddrPort());
42+
obj.pushKV("service", netInfo->GetPrimary().ToStringAddrPort());
4343
obj.pushKV("registeredHeight", nRegisteredHeight);
4444
obj.pushKV("lastPaidHeight", nLastPaidHeight);
4545
obj.pushKV("consecutivePayments", nConsecutivePayments);
@@ -73,7 +73,7 @@ UniValue CDeterministicMNStateDiff::ToJson(MnType nType) const
7373
obj.pushKV("version", state.nVersion);
7474
}
7575
if (fields & Field_netInfo) {
76-
obj.pushKV("service", state.netInfo.GetPrimary().ToStringAddrPort());
76+
obj.pushKV("service", state.netInfo->GetPrimary().ToStringAddrPort());
7777
}
7878
if (fields & Field_nRegisteredHeight) {
7979
obj.pushKV("registeredHeight", state.nRegisteredHeight);

src/evo/dmnstate.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class CDeterministicMNState
5454
CKeyID keyIDOwner;
5555
CBLSLazyPublicKey pubKeyOperator;
5656
CKeyID keyIDVoting;
57-
MnNetInfo netInfo;
57+
std::shared_ptr<NetInfoInterface> netInfo;
5858
CScript scriptPayout;
5959
CScript scriptOperatorPayout;
6060

@@ -100,7 +100,7 @@ class CDeterministicMNState
100100
READWRITE(CBLSLazyPublicKeyVersionWrapper(const_cast<CBLSLazyPublicKey&>(obj.pubKeyOperator), obj.nVersion == ProTxVersion::LegacyBLS));
101101
READWRITE(
102102
obj.keyIDVoting,
103-
obj.netInfo,
103+
NetInfoSerWrapper(const_cast<std::shared_ptr<NetInfoInterface>&>(obj.netInfo)),
104104
obj.scriptPayout,
105105
obj.scriptOperatorPayout,
106106
obj.platformNodeID,
@@ -112,7 +112,7 @@ class CDeterministicMNState
112112
{
113113
nVersion = ProTxVersion::LegacyBLS;
114114
pubKeyOperator = CBLSLazyPublicKey();
115-
netInfo.Clear();
115+
netInfo = MakeNetInfo(*this);
116116
scriptOperatorPayout = CScript();
117117
nRevocationReason = CProUpRevTx::REASON_NOT_SPECIFIED;
118118
platformNodeID = uint160();
@@ -246,6 +246,10 @@ class CDeterministicMNStateDiff
246246
SER_READ(obj, read_pubkey = true);
247247
READWRITE(CBLSLazyPublicKeyVersionWrapper(const_cast<CBLSLazyPublicKey&>(obj.state.pubKeyOperator), obj.state.nVersion == ProTxVersion::LegacyBLS));
248248
}
249+
} 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)));
252+
}
249253
} else {
250254
if (obj.fields & member.mask) {
251255
READWRITE(member.get(obj.state));

src/evo/netinfo.h

Lines changed: 76 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ class NetInfoEntry
6464
m_type = NetInfoType::Service;
6565
m_data = service;
6666
}
67+
template <typename Stream> NetInfoEntry(deserialize_type, Stream& s) { s >> *this; }
6768

6869
~NetInfoEntry() = default;
6970

@@ -146,7 +147,23 @@ class NetInfoEntry
146147

147148
using NetInfoList = std::vector<std::reference_wrapper<const NetInfoEntry>>;
148149

149-
class MnNetInfo
150+
class NetInfoInterface
151+
{
152+
public:
153+
virtual ~NetInfoInterface() = default;
154+
155+
virtual NetInfoStatus AddEntry(const std::string& service) = 0;
156+
virtual NetInfoList GetEntries() const = 0;
157+
158+
virtual const CService& GetPrimary() const = 0;
159+
virtual bool IsEmpty() const = 0;
160+
virtual NetInfoStatus Validate() const = 0;
161+
virtual std::string ToString() const = 0;
162+
163+
virtual void Clear() = 0;
164+
};
165+
166+
class MnNetInfo final : public NetInfoInterface
150167
{
151168
private:
152169
NetInfoEntry m_addr{};
@@ -156,6 +173,8 @@ class MnNetInfo
156173

157174
public:
158175
MnNetInfo() = default;
176+
template <typename Stream> MnNetInfo(deserialize_type, Stream& s) { s >> *this; }
177+
159178
~MnNetInfo() = default;
160179

161180
bool operator==(const MnNetInfo& rhs) const { return m_addr == rhs.m_addr; }
@@ -184,15 +203,64 @@ class MnNetInfo
184203
m_addr = NetInfoEntry{service};
185204
}
186205

187-
NetInfoStatus AddEntry(const std::string& service);
188-
NetInfoList GetEntries() const;
206+
NetInfoStatus AddEntry(const std::string& service) override;
207+
NetInfoList GetEntries() const override;
189208

190-
const CService& GetPrimary() const;
191-
bool IsEmpty() const { return *this == MnNetInfo(); }
192-
NetInfoStatus Validate() const;
193-
std::string ToString() const;
209+
const CService& GetPrimary() const override;
210+
bool IsEmpty() const override { return *this == MnNetInfo(); }
211+
NetInfoStatus Validate() const override;
212+
std::string ToString() const override;
194213

195-
void Clear() { m_addr.Clear(); }
214+
void Clear() override { m_addr.Clear(); }
215+
};
216+
217+
/* Selects NetInfoInterface implementation to use based on object version */
218+
template <typename T1>
219+
std::shared_ptr<NetInfoInterface> MakeNetInfo(const T1& obj)
220+
{
221+
assert(obj.nVersion > 0);
222+
return std::make_shared<MnNetInfo>();
223+
}
224+
225+
class NetInfoSerWrapper
226+
{
227+
private:
228+
std::shared_ptr<NetInfoInterface>& m_data;
229+
230+
public:
231+
NetInfoSerWrapper() = delete;
232+
NetInfoSerWrapper(const NetInfoSerWrapper&) = delete;
233+
NetInfoSerWrapper(std::shared_ptr<NetInfoInterface>& data) :
234+
m_data{data}
235+
{
236+
}
237+
template <typename Stream> NetInfoSerWrapper(deserialize_type, Stream& s) { s >> *this; }
238+
239+
~NetInfoSerWrapper() = default;
240+
241+
template <typename Stream>
242+
void Serialize(Stream& s) const
243+
{
244+
if (const auto& ptr{std::dynamic_pointer_cast<MnNetInfo>(m_data)}; ptr) {
245+
s << ptr;
246+
} else {
247+
throw std::ios_base::failure("Improperly constructed NetInfoInterface");
248+
}
249+
}
250+
251+
void Serialize(CSizeComputer& s) const
252+
{
253+
s.seek(::GetSerializeSize(MnNetInfo{}, s.GetVersion()));
254+
}
255+
256+
template <typename Stream>
257+
void Unserialize(Stream& s)
258+
{
259+
m_data.reset();
260+
std::shared_ptr<MnNetInfo> ptr;
261+
s >> ptr;
262+
m_data = std::move(ptr);
263+
}
196264
};
197265

198266
#endif // BITCOIN_EVO_NETINFO_H

0 commit comments

Comments
 (0)