-
Notifications
You must be signed in to change notification settings - Fork 968
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Archival bucketlist #4403
base: master
Are you sure you want to change the base?
Archival bucketlist #4403
Conversation
76b6594
to
05d6144
Compare
5cace22
to
ca87d88
Compare
Cargo.toml
Outdated
@@ -3,7 +3,7 @@ members = ["src/rust", "lib/tracy-client-sys"] | |||
|
|||
[patch.crates-io] | |||
tracy-client-sys = { path = "lib/tracy-client-sys" } | |||
stellar-xdr = { git = "https://github.com/stellar/rs-stellar-xdr", rev = "ae805d0f8c28ca86327a834eea9ce7d29b0a63bb" } | |||
stellar-xdr = { git = "https://github.com/stellar/rs-stellar-xdr", rev = "9a31b81412712ab2dfbe32cbeaba6bdb754c264b" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to bump this to the most recent revision and wrap all the new XDR uses into the next version macro (or wait until the protocol release)
src/main/main.cpp
Outdated
@@ -382,7 +382,7 @@ main(int argc, char* const* argv) | |||
// built with vnext, causing a curr diff against next. This works now | |||
// because the xdr is indentical, but the moment that changes this checkk | |||
// will fail and will need to be fixed. | |||
checkXDRFileIdentity(); | |||
// checkXDRFileIdentity(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't forget to revert this
src/bucket/BucketList.cpp
Outdated
template <> BucketListDepth BucketListBase<LiveBucket>::kNumLevels = 11; | ||
|
||
// TODO: I made this number up, do some analysis and pick a better value or | ||
// make this a configurable network config. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just curious, can we actually change this value at runtime in-between ledgers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. We will probably end up making this a config setting at which point I'll change it to a dynamic runtime value, but for now it's easier just to inherit the older BucketList's global const value for this refactor.
src/bucket/BucketList.cpp
Outdated
|
||
for (uint32_t i = static_cast<uint32>(mLevels.size()) - 1; i != 0; --i) | ||
{ | ||
/* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't forget to remove this (or uncomment if that's universally useful for debuggin)
if (protocolVersionStartsFrom(currentHeader.ledgerVersion, | ||
ProtocolVersion::V_22)) | ||
{ | ||
// TODO: Hash Archive Bucket |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the status of this TODO? I.e. is the PR blocked on this?
@@ -1148,26 +1304,30 @@ BucketManagerImpl::assumeState(HistoryArchiveState const& has, | |||
ZoneScoped; | |||
releaseAssertOrThrow(mApp.getConfig().MODE_ENABLES_BUCKETLIST); | |||
|
|||
for (uint32_t i = 0; i < BucketList::kNumLevels; ++i) | |||
// TODO: Assume archival bucket state |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about this TODO?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The outstanding TODOs are outside the scope of this PR. I've added some additional context on their dependencies. They require changing the history archive structure, which is a pretty big endeavor.
{ | ||
result.push_back(entryOp->liveEntry()); | ||
result.push_back(*entryOp); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I understand this, why do we add entry unconditionally as it seems like it must have been archived at this point? Is that for getLedgerEntry
endpoint?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Archival is not enforced at the database level, but at the txn level. Core needs to query about Archival State for a variety of reasons. For example, to check if a new entry creation is valid, core needs to check that an archived version of that key does not exist in the Live bucketlist or the archival bucketlists, so we can't just return null whenever an entry is archived at the db level.
src/bucket/BucketSnapshot.h
Outdated
std::vector<BulkLoadReturnT>& result, | ||
LedgerKeyMeter* lkMeter) const; | ||
|
||
// friend struct BucketLevelSnapshot<BucketT>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove
src/bucket/LedgerCmp.h
Outdated
if (aty != HOT_ARCHIVE_DELETED && aty != HOT_ARCHIVE_LIVE) | ||
{ | ||
throw std::runtime_error( | ||
"Malformed bucket: expected DELETED/RESTORED key."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't have 'RESTORED' key category, do we?
src/util/ProtocolVersion.h
Outdated
@@ -33,7 +33,8 @@ enum class ProtocolVersion : uint32_t | |||
V_18, | |||
V_19, | |||
V_20, | |||
V_21 | |||
V_21, | |||
V_22 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't forget to update this to include v23 and use it where appropriate.
I also would suggest using a named constant instead of the direct version checks in order to make changes easier.
Note: changes in this PR impact BucketListDB quite a bit, I think we need to resolve #4433 to make sure we have good coverage. Wdyt? |
6bc3175
to
2114dbf
Compare
038ece0
to
6ca5887
Compare
6ca5887
to
344647f
Compare
Description
Resolves #4394
Depends on XDR changes in stellar/stellar-xdr#200.
This change refactors the BucketList so that we can have multiple Bucket Lists simultaneously. This is necessary for State Archival, where validators will maintain a live BucketList, hot archive BucketList, and cold archive BucketList. This change does not yet support writing the new archival BucketLists to history,
Each BucketList has small differences wrt to the entry types it stores, merge logic, and how lookups are done, but the overall BucketList level logic is the same. Because of this, it seemed easiest to template the Bucket related classes and specialize a few functions. The difference are as follows (I'll be updating the Archival CAP with this info soon)
Entry Types:
Live BucketList:
BucketEntry
Hot Archive BucketList:
HotArchiveBucketEntry
.This change was necessary due to how LedgerKeys are stored. In the Live BucketList, only
DEADENTRY
store plainLedgerKey
.DEADENTRY
is equivalent to null, so these LedgerKeys are dropped at the bottom level bucket.Hot Archives require two types that store LedgerKeys:
HA_LIVE
andHA_DELETED
.HA_LIVE
is equivalent to the "null" type in the Live BucketList, and is dropped in the bottom bucket. However,HA_DELETED
needs to be persisted.Merging:
In the hot archive,
LedgerEntry
are never updated. They may be overwritten by anotherHotArchiveBucketEntry
type, but theLedgerEntry
contents itself never change. This means that theINITENTRY
,LIVEENTRY
, andDEADENTRY
abstraction doesn't really make sense. This makes the merge logic for Hot Archive buckets very simple, the newer entry always overwrites the older entry.This PR adds the concept of a "Tombstone" entry. A tombstone entry essentially represents null in the given BucketList and can be dropped once it reaches the bottom bucket. On the live BucketList, DEADENTRY is the tombstone type. On the Hot Archive BucketList,
HA_LIVE
is the tombstone.BucketListDB lookup:
The live BucketList only ever returns
LedgerEntry
types when queried. Any DEADENTRY LedgerKey is simply omitted from the return, as this is the "null" tombstone type.Hot archive lookups must return both LedgerKey and LedgerEntry types. HA_LIVE entries are of type LedgerKey and can be omitted from the return since they are the tombstone type. However, HA_ARCHIVED entries are not tombstone entries and must be returned when found. Do to this, Hot Archive lookups return
HotArchiveBucketEntry
instead ofLedgerEntry
when queried.Future updates will add more functionality to Hot Archives, further distinguishing it from the live BucketList, and add a third BucketList type called the cold archive. This cold archive will add a third BucketEntry type and have different merge logic as well, so I think the templated Bucket classes, while verbose, are warranted.
This is currently a draft until the XDR changes are merged.
Checklist
clang-format
v8.0.0 (viamake format
or the Visual Studio extension)