Skip to content

Commit fa9993f

Browse files
committed
evo: use interface shared ptr for netInfo instead of implementation
1 parent eb31209 commit fa9993f

File tree

8 files changed

+112
-16
lines changed

8 files changed

+112
-16
lines changed

src/evo/deterministicmns.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -507,9 +507,9 @@ void CDeterministicMNList::UpdateMN(const CDeterministicMN& oldDmn, const std::s
507507
// Using this temporary map as a checkpoint to roll back to in case of any issues.
508508
decltype(mnUniquePropertyMap) mnUniquePropertyMapSaved = mnUniquePropertyMap;
509509

510-
auto updateNetInfo = [this](const CDeterministicMN& dmn, const std::shared_ptr<MnNetInfo>& oldInfo,
511-
const std::shared_ptr<MnNetInfo>& newInfo) -> std::string {
512-
if ((oldInfo && newInfo) ? (*oldInfo != *newInfo) : (oldInfo != newInfo)) {
510+
auto updateNetInfo = [this](const CDeterministicMN& dmn, const std::shared_ptr<NetInfoInterface>& oldInfo,
511+
const std::shared_ptr<NetInfoInterface>& newInfo) -> std::string {
512+
if (!NetInfoInterface::IsEqual(oldInfo, newInfo)) {
513513
// We track each individual entry in netInfo as opposed to netInfo itself (preventing us from
514514
// using UpdateUniqueProperty()), so we need to successfully purge all old entries and insert
515515
// new entries to successfully update.

src/evo/deterministicmns.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,7 @@ class CDeterministicMNList
391391
DMNL_NO_TEMPLATE(MnNetInfo);
392392
DMNL_NO_TEMPLATE(NetInfoEntry);
393393
DMNL_NO_TEMPLATE(NetInfoInterface);
394+
DMNL_NO_TEMPLATE(std::shared_ptr<NetInfoInterface>);
394395
#undef DMNL_NO_TEMPLATE
395396
return ::SerializeHash(v);
396397
}

src/evo/dmnstate.h

Lines changed: 17 additions & 5 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-
std::shared_ptr<MnNetInfo> netInfo{MakeNetInfo()};
57+
std::shared_ptr<NetInfoInterface> netInfo{MakeNetInfo()};
5858
CScript scriptPayout;
5959
CScript scriptOperatorPayout;
6060

@@ -96,7 +96,7 @@ class CDeterministicMNState
9696
READWRITE(CBLSLazyPublicKeyVersionWrapper(const_cast<CBLSLazyPublicKey&>(obj.pubKeyOperator), obj.nVersion == ProTxVersion::LegacyBLS));
9797
READWRITE(
9898
obj.keyIDVoting,
99-
obj.netInfo,
99+
NetInfoSerWrapper(const_cast<std::shared_ptr<NetInfoInterface>&>(obj.netInfo)),
100100
obj.scriptPayout,
101101
obj.scriptOperatorPayout,
102102
obj.platformNodeID,
@@ -215,9 +215,17 @@ class CDeterministicMNStateDiff
215215
CDeterministicMNStateDiff(const CDeterministicMNState& a, const CDeterministicMNState& b)
216216
{
217217
boost::hana::for_each(members, [&](auto&& member) {
218-
if (member.get(a) != member.get(b)) {
219-
member.get(state) = member.get(b);
220-
fields |= member.mask;
218+
using BaseType = std::decay_t<decltype(member)>;
219+
if constexpr (BaseType::mask == Field_netInfo) {
220+
if (!NetInfoInterface::IsEqual(member.get(a), member.get(b))) {
221+
member.get(state) = member.get(b);
222+
fields |= member.mask;
223+
}
224+
} else {
225+
if (member.get(a) != member.get(b)) {
226+
member.get(state) = member.get(b);
227+
fields |= member.mask;
228+
}
221229
}
222230
});
223231
if (fields & Field_pubKeyOperator) {
@@ -244,6 +252,10 @@ class CDeterministicMNStateDiff
244252
SER_READ(obj, read_pubkey = true);
245253
READWRITE(CBLSLazyPublicKeyVersionWrapper(const_cast<CBLSLazyPublicKey&>(obj.state.pubKeyOperator), obj.state.nVersion == ProTxVersion::LegacyBLS));
246254
}
255+
} else if constexpr (BaseType::mask == Field_netInfo) {
256+
if (obj.fields & member.mask) {
257+
READWRITE(NetInfoSerWrapper(const_cast<std::shared_ptr<NetInfoInterface>&>(obj.state.netInfo)));
258+
}
247259
} else {
248260
if (obj.fields & member.mask) {
249261
READWRITE(member.get(obj.state));

src/evo/netinfo.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,29 @@ std::string NetInfoEntry::ToStringAddrPort() const
147147
m_data);
148148
}
149149

150+
bool NetInfoInterface::IsEqual(const std::shared_ptr<NetInfoInterface>& lhs, const std::shared_ptr<NetInfoInterface>& rhs)
151+
{
152+
if (lhs == rhs) {
153+
// Points to the same object or both blank
154+
return true;
155+
}
156+
157+
if (!lhs || !rhs) {
158+
// Unequal initialization status
159+
return false;
160+
}
161+
162+
if (const auto lhs_ptr{std::dynamic_pointer_cast<MnNetInfo>(lhs)}) {
163+
if (const auto rhs_ptr{std::dynamic_pointer_cast<MnNetInfo>(rhs)}) {
164+
// Successful downcasting of both lhs and rhs, can now deep compare
165+
return *lhs_ptr == *rhs_ptr;
166+
}
167+
}
168+
169+
// Downcasting failed, lhs and rhs are differing types
170+
return false;
171+
}
172+
150173
NetInfoStatus MnNetInfo::ValidateService(const CService& service)
151174
{
152175
if (!service.IsValid()) {

src/evo/netinfo.h

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,9 @@ using NetInfoList = std::vector<std::reference_wrapper<const NetInfoEntry>>;
128128

129129
class NetInfoInterface
130130
{
131+
public:
132+
static bool IsEqual(const std::shared_ptr<NetInfoInterface>& lhs, const std::shared_ptr<NetInfoInterface>& rhs);
133+
131134
public:
132135
virtual ~NetInfoInterface() = default;
133136

@@ -194,9 +197,45 @@ class MnNetInfo final : public NetInfoInterface
194197
void Clear() override { m_addr.Clear(); }
195198
};
196199

197-
inline std::shared_ptr<MnNetInfo> MakeNetInfo()
200+
inline std::shared_ptr<NetInfoInterface> MakeNetInfo()
198201
{
199202
return std::make_shared<MnNetInfo>();
200203
}
201204

205+
class NetInfoSerWrapper
206+
{
207+
private:
208+
std::shared_ptr<NetInfoInterface>& m_data;
209+
210+
public:
211+
NetInfoSerWrapper() = delete;
212+
NetInfoSerWrapper(const NetInfoSerWrapper&) = delete;
213+
NetInfoSerWrapper(std::shared_ptr<NetInfoInterface>& data) :
214+
m_data{data}
215+
{
216+
}
217+
template <typename Stream>
218+
NetInfoSerWrapper(deserialize_type, Stream& s) { s >> *this; }
219+
220+
~NetInfoSerWrapper() = default;
221+
222+
template <typename Stream>
223+
void Serialize(Stream& s) const
224+
{
225+
if (const auto ptr{std::dynamic_pointer_cast<MnNetInfo>(m_data)}) {
226+
s << *ptr;
227+
} else {
228+
// MakeNetInfo() supplied an unexpected implementation or we didn't call it and
229+
// are left with a nullptr. Neither should happen.
230+
assert(false);
231+
}
232+
}
233+
234+
template <typename Stream>
235+
void Unserialize(Stream& s)
236+
{
237+
m_data = std::make_shared<MnNetInfo>(deserialize, s);
238+
}
239+
};
240+
202241
#endif // BITCOIN_EVO_NETINFO_H

src/evo/providertx.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class CProRegTx
4141
MnType nType{MnType::Regular};
4242
uint16_t nMode{0}; // only 0 supported for now
4343
COutPoint collateralOutpoint{uint256(), (uint32_t)-1}; // if hash is null, we refer to a ProRegTx output
44-
std::shared_ptr<MnNetInfo> netInfo{MakeNetInfo()};
44+
std::shared_ptr<NetInfoInterface> netInfo{MakeNetInfo()};
4545
uint160 platformNodeID{};
4646
uint16_t platformP2PPort{0};
4747
uint16_t platformHTTPPort{0};
@@ -67,7 +67,7 @@ class CProRegTx
6767
obj.nType,
6868
obj.nMode,
6969
obj.collateralOutpoint,
70-
obj.netInfo,
70+
NetInfoSerWrapper(const_cast<std::shared_ptr<NetInfoInterface>&>(obj.netInfo)),
7171
obj.keyIDOwner,
7272
CBLSLazyPublicKeyVersionWrapper(const_cast<CBLSLazyPublicKey&>(obj.pubKeyOperator), (obj.nVersion == ProTxVersion::LegacyBLS)),
7373
obj.keyIDVoting,
@@ -110,7 +110,7 @@ class CProUpServTx
110110
uint16_t nVersion{ProTxVersion::LegacyBLS}; // message version
111111
MnType nType{MnType::Regular};
112112
uint256 proTxHash;
113-
std::shared_ptr<MnNetInfo> netInfo{MakeNetInfo()};
113+
std::shared_ptr<NetInfoInterface> netInfo{MakeNetInfo()};
114114
uint160 platformNodeID{};
115115
uint16_t platformP2PPort{0};
116116
uint16_t platformHTTPPort{0};
@@ -133,7 +133,7 @@ class CProUpServTx
133133
}
134134
READWRITE(
135135
obj.proTxHash,
136-
obj.netInfo,
136+
NetInfoSerWrapper(const_cast<std::shared_ptr<NetInfoInterface>&>(obj.netInfo)),
137137
obj.scriptOperatorPayout,
138138
obj.inputsHash
139139
);

src/evo/simplifiedmns.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class CSimplifiedMNListEntry
3535
public:
3636
uint256 proRegTxHash;
3737
uint256 confirmedHash;
38-
std::shared_ptr<MnNetInfo> netInfo{MakeNetInfo()};
38+
std::shared_ptr<NetInfoInterface> netInfo{MakeNetInfo()};
3939
CBLSLazyPublicKey pubKeyOperator;
4040
CKeyID keyIDVoting;
4141
bool isValid{false};
@@ -53,7 +53,7 @@ class CSimplifiedMNListEntry
5353
{
5454
return proRegTxHash == rhs.proRegTxHash &&
5555
confirmedHash == rhs.confirmedHash &&
56-
((netInfo && rhs.netInfo) ? (*netInfo == *rhs.netInfo) : (netInfo == rhs.netInfo)) &&
56+
NetInfoInterface::IsEqual(netInfo, rhs.netInfo) &&
5757
pubKeyOperator == rhs.pubKeyOperator &&
5858
keyIDVoting == rhs.keyIDVoting &&
5959
isValid == rhs.isValid &&
@@ -76,7 +76,7 @@ class CSimplifiedMNListEntry
7676
READWRITE(
7777
obj.proRegTxHash,
7878
obj.confirmedHash,
79-
obj.netInfo,
79+
NetInfoSerWrapper(const_cast<std::shared_ptr<NetInfoInterface>&>(obj.netInfo)),
8080
CBLSLazyPublicKeyVersionWrapper(const_cast<CBLSLazyPublicKey&>(obj.pubKeyOperator), (obj.nVersion == ProTxVersion::LegacyBLS)),
8181
obj.keyIDVoting,
8282
obj.isValid

src/test/evo_netinfo_tests.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,4 +214,25 @@ BOOST_AUTO_TEST_CASE(cservice_compatible)
214214
BOOST_CHECK(CheckIfSerSame(service, netInfo));
215215
}
216216

217+
BOOST_AUTO_TEST_CASE(interface_equality)
218+
{
219+
std::shared_ptr<NetInfoInterface> ptr_lhs{nullptr}, ptr_rhs{nullptr};
220+
221+
// Equal initialization state (uninitialized)
222+
BOOST_CHECK(NetInfoInterface::IsEqual(ptr_lhs, ptr_rhs));
223+
224+
// Unequal initialization state (lhs initialized, rhs unchanged)
225+
ptr_lhs = std::make_shared<MnNetInfo>();
226+
BOOST_CHECK(!NetInfoInterface::IsEqual(ptr_lhs, ptr_rhs));
227+
228+
// Equal initialization state (lhs unchanged, rhs initialized), same values
229+
ptr_rhs = std::make_shared<MnNetInfo>();
230+
BOOST_CHECK(ptr_lhs->IsEmpty() && ptr_rhs->IsEmpty());
231+
BOOST_CHECK(NetInfoInterface::IsEqual(ptr_lhs, ptr_rhs));
232+
233+
// Equal initialization state, same type, differing values
234+
BOOST_CHECK_EQUAL(ptr_rhs->AddEntry("1.1.1.1:9999"), NetInfoStatus::Success);
235+
BOOST_CHECK(!NetInfoInterface::IsEqual(ptr_lhs, ptr_rhs));
236+
}
237+
217238
BOOST_AUTO_TEST_SUITE_END()

0 commit comments

Comments
 (0)