mirror of
https://github.com/Xahau/xahaud.git
synced 2026-07-23 23:20:12 +00:00
fix(consensus): recycle member evidence cache
This commit is contained in:
@@ -829,6 +829,90 @@ public:
|
||||
}));
|
||||
}
|
||||
}
|
||||
{
|
||||
testcase(
|
||||
"UNLReport member manifest evidence evicts oldest retained "
|
||||
"master");
|
||||
|
||||
ManifestCache cache;
|
||||
std::optional<Manifest> oldest;
|
||||
std::optional<Manifest> secondOldest;
|
||||
std::optional<SecretKey> secondMasterSecret;
|
||||
std::optional<SecretKey> secondSigningSecret;
|
||||
for (std::size_t i = 0; i < maxUNLReportMemberEvidenceMasters; ++i)
|
||||
{
|
||||
auto const sk = randomSecretKey();
|
||||
auto const kp = randomKeyPair(KeyType::secp256k1);
|
||||
auto manifest = makeManifest(
|
||||
sk, KeyType::ed25519, kp.second, KeyType::secp256k1, 1);
|
||||
if (i == 0)
|
||||
oldest = clone(manifest);
|
||||
else if (i == 1)
|
||||
{
|
||||
secondOldest = clone(manifest);
|
||||
secondMasterSecret = sk;
|
||||
secondSigningSecret = kp.second;
|
||||
}
|
||||
BEAST_EXPECT(cache.observeUNLReportMemberManifestEvidence(
|
||||
makeSlice(manifest.serialized)));
|
||||
}
|
||||
|
||||
BEAST_EXPECT(oldest && secondOldest);
|
||||
BEAST_EXPECT(
|
||||
oldest &&
|
||||
!cache.observeUNLReportMemberManifestEvidence(
|
||||
makeSlice(oldest->serialized)));
|
||||
|
||||
auto const replacementSecret = randomSecretKey();
|
||||
auto const replacementKey = randomKeyPair(KeyType::secp256k1);
|
||||
auto const replacement = makeManifest(
|
||||
replacementSecret,
|
||||
KeyType::ed25519,
|
||||
replacementKey.second,
|
||||
KeyType::secp256k1,
|
||||
1);
|
||||
BEAST_EXPECT(cache.observeUNLReportMemberManifestEvidence(
|
||||
makeSlice(replacement.serialized)));
|
||||
|
||||
auto const snapshot =
|
||||
cache.getUNLReportMemberManifestEvidenceSnapshot();
|
||||
BEAST_EXPECT(snapshot.size() == maxUNLReportMemberEvidenceMasters);
|
||||
BEAST_EXPECT(oldest && !containsEvidence(snapshot, *oldest));
|
||||
BEAST_EXPECT(
|
||||
secondOldest && containsEvidence(snapshot, *secondOldest));
|
||||
BEAST_EXPECT(containsEvidence(snapshot, replacement));
|
||||
|
||||
BEAST_EXPECT(secondMasterSecret && secondSigningSecret);
|
||||
auto const refreshed = makeManifest(
|
||||
*secondMasterSecret,
|
||||
KeyType::ed25519,
|
||||
*secondSigningSecret,
|
||||
KeyType::secp256k1,
|
||||
2);
|
||||
BEAST_EXPECT(cache.observeUNLReportMemberManifestEvidence(
|
||||
makeSlice(refreshed.serialized)));
|
||||
|
||||
auto const nextSecret = randomSecretKey();
|
||||
auto const nextKey = randomKeyPair(KeyType::secp256k1);
|
||||
auto const next = makeManifest(
|
||||
nextSecret,
|
||||
KeyType::ed25519,
|
||||
nextKey.second,
|
||||
KeyType::secp256k1,
|
||||
1);
|
||||
BEAST_EXPECT(cache.observeUNLReportMemberManifestEvidence(
|
||||
makeSlice(next.serialized)));
|
||||
|
||||
auto const refreshedSnapshot =
|
||||
cache.getUNLReportMemberManifestEvidenceSnapshot();
|
||||
BEAST_EXPECT(
|
||||
refreshedSnapshot.size() == maxUNLReportMemberEvidenceMasters);
|
||||
BEAST_EXPECT(
|
||||
secondOldest &&
|
||||
!containsEvidence(refreshedSnapshot, *secondOldest));
|
||||
BEAST_EXPECT(containsEvidence(refreshedSnapshot, refreshed));
|
||||
BEAST_EXPECT(containsEvidence(refreshedSnapshot, next));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
namespace ripple {
|
||||
|
||||
inline constexpr std::size_t maxUNLReportMemberManifestSize = 2048;
|
||||
inline constexpr std::size_t maxUNLReportMemberEvidenceMasters = 256;
|
||||
inline constexpr std::size_t maxUNLReportMemberEvidencePerMaster = 2;
|
||||
|
||||
/*
|
||||
Validator key manifests
|
||||
@@ -266,9 +268,6 @@ private:
|
||||
beast::Journal j_;
|
||||
std::shared_mutex mutable mutex_;
|
||||
|
||||
static constexpr std::size_t maxUNLReportMemberEvidenceMasters_ = 256;
|
||||
static constexpr std::size_t maxUNLReportMemberEvidencePerMaster_ = 2;
|
||||
|
||||
/** Active manifests stored by master public key. */
|
||||
hash_map<PublicKey, Manifest> map_;
|
||||
|
||||
@@ -285,11 +284,13 @@ private:
|
||||
struct UNLReportMemberManifestEvidence
|
||||
{
|
||||
std::uint32_t sequence = 0;
|
||||
std::uint64_t retentionOrder = 0;
|
||||
std::vector<Manifest> manifests;
|
||||
};
|
||||
|
||||
hash_map<PublicKey, UNLReportMemberManifestEvidence>
|
||||
unlReportMemberManifestEvidence_;
|
||||
std::uint64_t unlReportMemberEvidenceRetentionOrder_ = 0;
|
||||
|
||||
std::atomic<std::uint32_t> seq_{0};
|
||||
|
||||
|
||||
@@ -597,8 +597,17 @@ ManifestCache::observeUNLReportMemberManifestEvidence(Slice serialized)
|
||||
if (iter == unlReportMemberManifestEvidence_.end())
|
||||
{
|
||||
if (unlReportMemberManifestEvidence_.size() >=
|
||||
maxUNLReportMemberEvidenceMasters_)
|
||||
return false;
|
||||
maxUNLReportMemberEvidenceMasters)
|
||||
{
|
||||
auto const oldest = std::min_element(
|
||||
unlReportMemberManifestEvidence_.begin(),
|
||||
unlReportMemberManifestEvidence_.end(),
|
||||
[](auto const& lhs, auto const& rhs) {
|
||||
return lhs.second.retentionOrder <
|
||||
rhs.second.retentionOrder;
|
||||
});
|
||||
unlReportMemberManifestEvidence_.erase(oldest);
|
||||
}
|
||||
|
||||
iter = unlReportMemberManifestEvidence_
|
||||
.emplace(masterKey, UNLReportMemberManifestEvidence{})
|
||||
@@ -622,10 +631,11 @@ ManifestCache::observeUNLReportMemberManifestEvidence(Slice serialized)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (evidence.manifests.size() >= maxUNLReportMemberEvidencePerMaster_)
|
||||
if (evidence.manifests.size() >= maxUNLReportMemberEvidencePerMaster)
|
||||
return false;
|
||||
|
||||
evidence.manifests.emplace_back(std::move(m));
|
||||
evidence.retentionOrder = ++unlReportMemberEvidenceRetentionOrder_;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -638,7 +648,7 @@ ManifestCache::getUNLReportMemberManifestEvidenceSnapshot() const
|
||||
snapshot.reserve(
|
||||
map_.size() +
|
||||
unlReportMemberManifestEvidence_.size() *
|
||||
maxUNLReportMemberEvidencePerMaster_);
|
||||
maxUNLReportMemberEvidencePerMaster);
|
||||
|
||||
for (auto const& [_, manifest] : map_)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user