-
Notifications
You must be signed in to change notification settings - Fork 18
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
Merge release/anemone-v1.1.3
into develop
#922
Conversation
… into feature/browse_object_field
…ylon-node into feature/browse_entity_iterator
… into feature/browse_object_field
…ylon-node into feature/browse_entity_iterator
This goes into `/feature/browse_api` long-lived branch. This implements https://radixdlt.atlassian.net/wiki/spaces/RPNV1/pages/3189211214/RNP-12+-+Browse+API+sub-API+within+Core+API#4.-Object-Field-Lookup
⚠️ This builds on top of #733 (re-uses some code) and ultimately wants to merge into `feature/browse_api` _(not `develop`!)_. This implements https://radixdlt.atlassian.net/wiki/spaces/RPNV1/pages/3189211214/RNP-12+-+Browse+API+sub-API+within+Core+API#1.-Entity-Listing but the main focus of the PR is on re-usable listing-with-pages-on-continuation-tokens infra (please see the heavily-documented abstractions introduced in `paging.rs`).
⚠️ This builds on top of #736 (refactors some stuff introduced there, in order to re-use it here) and ultimately wants to merge into `feature/browse_api` _(not `develop`!)_. This implements https://radixdlt.atlassian.net/wiki/spaces/RPNV1/pages/3189211214/RNP-12+-+Browse+API+sub-API+within+Core+API#2.-Entity-Information .
⚠️ This builds on top of #739 (doesn't strictly depend on anything, but touches some files due to small refactors) and ultimately wants to merge into `feature/browse_api` _(not `develop`!)_. This implements https://radixdlt.atlassian.net/wiki/spaces/RPNV1/pages/3189211214/RNP-12+-+Browse+API+sub-API+within+Core+API#5.-Object-Collection-Listing . ❗ **NOTE:** This PR contains a temporary provisional "faux paging" impl! We need to add support for "iterate from" to the Engine's `SubstateDatabase` - afterwards, we will super-easily migrate this to proper paging (literally `+1 -4` PR)
⚠️ This builds on top of #741 (uses the same mechanisms) and ultimately wants to merge into `feature/browse_api` _(not `develop`!)_. This implements https://radixdlt.atlassian.net/wiki/spaces/RPNV1/pages/3189211214/RNP-12+-+Browse+API+sub-API+within+Core+API#7.-KVStore-Collection-Listing . ❗ **NOTE:** (same as in #741) This PR contains a temporary provisional "faux paging" impl! We need to add support for "iterate from" to the Engine's `SubstateDatabase` (already pending at radixdlt/radixdlt-scrypto#1648) - afterwards, we will super-easily migrate this to proper paging (literally `+1 -4` PR)
⚠️ This builds on top of #743 and ultimately wants to merge into `feature/browse_api` _(not `develop`!)_. This implements https://radixdlt.atlassian.net/wiki/spaces/RPNV1/pages/3189211214/RNP-12+-+Browse+API+sub-API+within+Core+API#3.-Blueprint-Details .
⚠️ This builds on top of #744 and ultimately wants to merge into `feature/browse_api` _(not `develop`!)_. This is in the "Browse API" PR-chain, but actually it is a pretty generic feature: - Implemented Programmatic JSON **deser**ializer - We need it now (yeah for Browse API), and Engine does not offer one (they only serialize) - The impl is stolen from RET (and then heavily adjusted for Node's specifics; but not beyond recognition) - The plan is to either move this impl to Engine (or implement the same on the Engine's side), and we'll then be able to remove this code from Node (and maybe even from RET?) - created the Programmatic JSON **ser**ializer facade - Just so that it can live next to the **deser**ializer - ofc it is only facading the Engine's serialization impl - it is used to test the **deser**ializer for compatibility with Engine's **ser**ializer (the "round-trip codec test") Note: The **ser**ializer facade is used right away, but the **deser**ializer is currently unused (and rightfully produces warnings) [except in tests]; it will soon be used by Browse API's "lookup kv store/collection" endpoints.
⚠️ This builds on top of #747 (relies on the programmatic JSON deserialization support introduced there) and ultimately wants to merge into `feature/browse_api` _(not `develop`!)_. This implements [https://radixdlt.atlassian.net/wiki/spaces/RPNV1/pages/3189211214/RNP-12+-+Browse+API+sub-API+within+Core+API#3.-Blueprint-Details .](https://radixdlt.atlassian.net/wiki/spaces/RPNV1/pages/3189211214/RNP-12+-+Browse+API+sub-API+within+Core+API#8.-KVStore-Collection-Lookup) . (with all the infra already provided by the previous Browse API PRs, this one is actually trivial) (the only other remaining endpoint, `/browse/object/collection/entry`, should be trivial based on this one)
… into feature/browse_object_collection_entry
This goes into `/feature/browse_api` long-lived branch. This implements https://radixdlt.atlassian.net/wiki/spaces/RPNV1/pages/3189211214/RNP-12+-+Browse+API+sub-API+within+Core+API#6.-Object-Collection-Lookup 🎉 This is the last endpoint in the first slice of Browse API 🎉 (there will still be 2-3 PRs fixing some found bugs, including in Scrypto repo)
…ording to conditions).
## Summary Addresses item 4. of https://radixdlt.atlassian.net/browse/NODE-633, as in the title. ## Testing N/A, it is only docs change.
## Summary As discussed at https://rdxworks.slack.com/archives/C01M90Y2448/p1713868409449979?thread_ts=1713866025.075899&cid=C01M90Y2448 ## Details This change also renames a string marker in DB, which means that a ledger wipe will be needed if this branch was deployed anywhere before. ## Testing Just a rename, regression tests have to pass.
## Summary Addresses a build failure spotted at https://github.com/radixdlt/babylon-node/actions/runs/8797900181/job/24143785471#step:19:527. We recently had to bump a version, but it is not available for ARM (see https://packages.debian.org/bookworm/openjdk-17-jre-headless). ## Testing N/A, a build problem only.
Docker tags |
at_state_version: StateVersion, | ||
|
||
// Note: "Why do we even need to capture `'t`?" |
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.
Well, this is because of the fact that e.g. the SubstateTier
's into_iter_substate_summaries_from
method exposes an iterator with a lifetime of the underlying store rather than the entity tier (in other words, it can outlive the tier).
However, the underlying store comes from self.base_store.deref()
and we need someone to capture the constraint that the reference created lives longer than the &self
parameter in order to satisfy the SubstateDatabase
trait definition for list_entries_from
.
But self.base_store.deref()
could either resolve to some random lifetime if base_store
is a reference, or could resolve to &self.base_store
, so could be bounded by &self
.
We need some way of capturing that "the lifetime of self.base_store.deref()
" outlives ANY reference to self. This is actually extra information -- and this phantom lifetime is the best way of doing that.
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.
Perhaps it'd be clearer to actually make it a PhantomData<&'s S>
and have 's, S: 's, DS: Deref<Target = S>
.
Or just PhantomData<&'s ()>
. I think PhantomData<&'s DS>
is a little misleading - because it's not pretending to encompass a reference to DS
, but actually to some underlying store.
} | ||
} | ||
|
||
impl<'s, R: ReadableRocks + 's, DS: Deref<Target = StateManagerDatabase<R>>> ReNodeListingIndex |
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.
EntityListingIndex
*
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.
Various comments on the index building logic. I don't think any of this is a release blocker, although we'd ideally fix the logging.
Perhaps we can raise a ticket to tidy up the rest?
); | ||
if state_version.number() % TXN_FLUSH_INTERVAL == 0 || receipts_iter.peek().is_none() { | ||
info!( | ||
"ReNode listing indices updated to {}; flushing...", |
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.
Entity*
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.
That's also a lot! of info logs catching up on mainnet which has 75 million state versions right now.
Perhaps better to have info logs every 1 million transactions rather than every 10000? And then if you want logs every flush, perhaps make them debug!
logs?
use super::*; | ||
use std::ops::Range; | ||
|
||
pub trait ReNodeListingIndex { |
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.
EntityListingIndex*
} | ||
|
||
/// An Object's ID and its blueprint name. | ||
/// This is a "technical" structure stored in one of the ReNode-listing indices. |
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.
Entity*
@@ -764,6 +800,10 @@ impl ActualStateManagerDatabase { | |||
state_manager_database.restore_december_2023_lost_substates(network); | |||
state_manager_database.ensure_historical_substate_values(); | |||
|
|||
if state_manager_database.config.enable_entity_listing_indices { |
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.
It would be more consistent to use an ensure_
style and have this config check internal to the method? To either set up or tear down the index.
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're also missing the teardown logic for this index.
.peekable(); | ||
|
||
while let Some((state_version, receipt)) = receipts_iter.next() { | ||
self.batch_update_entity_listing_indices( |
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.
It's better to use the substate store than the receipt store for this IMO.
It's both faster, and doesn't require full receipt history to do.
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.
Not worth doing now, but in future, maybe worth raising as a separate ticket to change how we rebuild this index?
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.
Ohh actually I see that we have to use the transaction receipts, due to the way the index includes the state version and index in transaction bits! Okay, ignore this :)
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 went through the same journey when implementing that :p
db_context.flush(); | ||
} | ||
} | ||
info!("ReNode listing indices are caught up."); |
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.
Entity*
@@ -2154,6 +2315,57 @@ impl<R: ReadableRocks> IterableAccountChangeIndex for StateManagerDatabase<R> { | |||
} | |||
} | |||
|
|||
impl<R: ReadableRocks> ReNodeListingIndex for StateManagerDatabase<R> { |
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.
EntityListingIndex*
.next() | ||
.expect("next version"); | ||
|
||
let mut receipts_iter = db_context |
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.
Hmm I thought catchup_from_version
is actually previous_indexed_up_to_version
?
So shouldn't we start iterating from previous_indexed_up_to_version + 1
inclusive?
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.
Although I imagine setting these is idempotent, so we won't have duplicated entries? So it might be safe?
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.
a tiny .next()
(in line 2132 above) is the + 1
you are looking for :D
FOR ONCE I avoided the "off by one" 🎉 (I think 🤔)
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.
Ahh I thought that was a .next()
to return the first value from an iterator!
In retrospect, perhaps next
is a little too overloaded, but it's minor anyway?
In terms of this code, tiny suggestion - maybe separating out let catchup_from_version = previously_updated_to_version.next();
might make it clearer / more explicit for noobs like me?
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.
this I can do: e8b08cc 👍
}; | ||
let SubstateChangeAction::Create { new } = type_info_creation else { | ||
panic!( | ||
"type info substate should be immutable: {:?}", |
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.
This seems quite scary. e.g. this won't be true if the blueprint version is updated eventually.
But the entity id and blueprint name should be fixed by the system, so I think it's fine to just ignore updates.
}; | ||
let type_info = scrypto_decode::<TypeInfoSubstate>(new).expect("decode type info"); | ||
|
||
let entity_type = node_id.entity_type().expect("type of upserted ReNode"); |
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.
entity*
… `delete_all()`).
## Summary Addresses https://radixdlt.atlassian.net/browse/NODE-638 (i.e. all the comments on #922 (review)) ## Testing Just regression needs to pass.
Quality Gate passedIssues Measures |
Important
develop
.main
.release/*
branch.Summary
Tip
Start with the context of your PR. Why are you making this change? What does it address? Link back to an issue if relevant.
Then summarise the changes that were made. Bullet points are fine.
Details
Tip
This section is optional. Go into more detail about the changes that were made, or the thinking behind the changes.
Testing
Tip
Explain what testing / verification is done, including manual testing or automated testing.