-
Notifications
You must be signed in to change notification settings - Fork 119
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
[1/2] custodian: look up proofs in local universe as well #726
Conversation
3db2a58
to
0b182fc
Compare
0b182fc
to
663c01f
Compare
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.
Nice work! Main comment is if we really want to overload Blob
(tho it already kinda is) vs using distinct types, and then an Either
to allow them both be used in instances where either of them will work.
Reading over this change, it struck me (once again), that we should probably try to consolidate all the different proof storage interfaces we have. At times it isn't super easy to follow where a proof if coming from or why, but the multi
wrappers do help a bit.
// Blob represents a serialized proof file, including the checksum. | ||
// Blob either represents a serialized proof file, including the checksum or a | ||
// single serialized issuance/transition proof. Which one it is can be found out | ||
// from the leading magic bytes (or the helper methods that inspect those). |
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 wonder if we would be better of making these into different types instead. We added the magic prefix bytes partially to avoid confusing them in the first place. With the type route, we'd break compilation if one was attempted to be passed in where the other was accepted. As is, we reply on runtime checks to avoid such classes of bugs.
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 could use the Either
type added in the multiverse root PR as an example. Then you can still use Blob
everywhere, but rely on type safety re protection of trying to use one vs the other.
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.
Yes, I think distinguishing between a single proof or a proof file would help a lot in the clarity of the code. But I think that would be a bigger refactor and should probably be done in a separate PR.
Do you think this is a reasonable temporary step for this PR?
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.
SGTM, down to make an issue for it so we can move on here. Main thing is we can supplement the byte level prefix with a type, and then accept that type contextually to cut down on possible bugs in this area.
c534ce1
to
994837f
Compare
994837f
to
54bc8e7
Compare
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 wonderful PR and itest 🎉
The callback for proof fetching is pretty neat also. Small Q on how we're fetching proofs overall + some nits.
Actually, given that some parts of this only handle transfer proofs, do these changes enable 'sideloaded' issuance proofs to get added to our local universe state? I think for transfers it's implicit as the transfer proof includes the issuance proof, but for those who want to manually sync issuance i'm not sure if we test that rn. |
This PR has two reviewers. I've had a review request for this. @guggero would you like me to review also? |
Yes, since the only way to side load a proof currently (without using dev mode), is the universe RPC's |
54bc8e7
to
32fe75c
Compare
32fe75c
to
dc08080
Compare
With the itest change, I think we still don't exercise import on the genesis proof? The second node has the default universe server set, so IIUC they sync the genesis proof at that point. Then they receive only the transfer proof, and import that successfully. What I meant earlier was to actually have the universe server unset for the second node and import the issuance proof manually via Latest changes LGTM otherwise. |
You mean because So I think the test does exactly what you propose? |
dc08080
to
6cc7b2a
Compare
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.
Good point re: testing issuance insertion as-is. LGTM!
With this commit we change the NotifyArchiver to the bare minimum that we actually need in the custodian.
With this commit we extract the logic for iteratively retrieving the full provenance for an asset by starting at the last proof then querying each previous proof until we arrive at the genesis. We will want to re-use this logic outside of the proof courier itself, so it's useful to extract into a general-purpose function where the actual retrieval of an individual proof is done in a callback and can be adjusted to the current proof storage (local or remote).
This is an optimization that allows us to only extract the asset from the proof when fetching the full proof provenance. That saves us a whole decode/encode round trip per proof.
In some situations we want a quick way to find out if we have a proof (or not) without actually fetching it, so we add a HasProof method to the proof.Archive interface. The MultiArchiver will return false if one of the backends does not have the proof, so we can use that method to find out if we have a discrepancy between the backends and should import a proof file.
With this commit we prepare the MultiverseStore to also act as a NotifyArchiver that can notify about new incoming proofs.
Because the universe only deals with individual proof leaves, we want the custodian to be able to deal with both proof files and single proofs. To make it easy to distinguish and convert between the two, we add some helper methods to the proof.Blob type.
Since we now might get either a full proof file or just a transition proof, the custodian needs to be updated to be able to deal with both.
This commit creates a new notifier that can relay registrations for new proofs to multiple notifier/archiver backends. We then use that to pass in both the local assets store as well as the multiverse store to the custodian to detect incoming proofs.
6cc7b2a
to
864b554
Compare
Rebased, ready for final review @Roasbeef. |
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.
LGTM 🍉
@@ -130,6 +130,18 @@ func All[T any](xs []T, pred func(T) bool) bool { | |||
return true | |||
} | |||
|
|||
// AllMapItems returns true if the passed predicate returns true for all items | |||
// in the map. | |||
func AllMapItems[T any, K comparable](xs map[K]T, pred func(T) bool) bool { |
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.
Cool! Looking forward to when/if they add more direct iterator stuff to the Go stdlib, then we'd only need one version of this.
// RegisterSubscriber adds a new subscriber for receiving events. The | ||
// registration request is forwarded to all registered archives. | ||
func (m *MultiArchiveNotifier) RegisterSubscriber( | ||
receiver *fn.EventReceiver[Blob], deliverExisting bool, |
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.
Leaving review note to self: does the subscriber need to be ready to handle multiple subscriptions notifications from all the archives for the same proof file?
@@ -76,6 +76,10 @@ var testCases = []*testCase{ | |||
test: testOfflineReceiverEventuallyReceives, | |||
proofCourierType: proof.HashmailCourierType, | |||
}, | |||
{ | |||
name: "addr send no proof courier with local universe import", | |||
test: testSendNoCourierUniverseImport, |
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 gofmt
'd?
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.
Linter says: it actually is!
Depends on #712.Fixes #578.
This PR updates the proof notification publish/subscribe mechanism in a way that allows us to pass in multiple proof sources to the custodian so it can detect incoming proofs from multiple sources.