Skip to content
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

Track blockchain callback handlers per namespace #883

Merged
merged 6 commits into from
Jul 6, 2022

Conversation

awrichar
Copy link
Contributor

@awrichar awrichar commented Jun 29, 2022

Part of FIR-12

For blockchain batch pin events, direct them to an appropriate namespace:

  • If the multiparty contract is V1, the namespace is passed explicitly
  • If the multiparty contract is V2+, the namespace is packed into the subscription name (and is not sent in the event)

For blockchain network actions, direct them to an appropriate namespace:

  • If the multiparty contract is V1, send them to all handlers (the handler will filter based on whether the contract address matches the active contract)
  • If the multiparty contract is V2+, the namespace is packed into the subscription name

Caveat for pre-existing subscriptions: Old subscription names will not have a namespace included, so multiple namespaces will actually be sharing a single subscription. This is OK for V1 networks, as batch pin events always contain a namespace and network actions are sent to all handlers. A V2 network cannot function in this situation, so V2 contracts will be fundamentally incompatible with releases of FireFly prior to 1.1.

Tokens are also subject to the same problem where pre-existing subscriptions will not include namespace information, so they always send events to all handlers if namespace is unset.

Unanswered question: how does ff_system "go away" cleanly when migrating to a V2 contract? There is no entry for ff_system in the namespace config, so migration is weird and probably tied to the default namespace instead. UPDATE - see #884

Signed-off-by: Andrew Richardson <andrew.richardson@kaleido.io>
Signed-off-by: Andrew Richardson <andrew.richardson@kaleido.io>
@codecov-commenter
Copy link

codecov-commenter commented Jun 29, 2022

Codecov Report

Merging #883 (5d31178) into main (52e7744) will increase coverage by 0.00%.
The diff coverage is 100.00%.

@@           Coverage Diff           @@
##             main     #883   +/-   ##
=======================================
  Coverage   99.96%   99.96%           
=======================================
  Files         299      299           
  Lines       19500    19568   +68     
=======================================
+ Hits        19494    19562   +68     
  Misses          5        5           
  Partials        1        1           
Impacted Files Coverage Δ
internal/events/event_manager.go 100.00% <ø> (ø)
internal/blockchain/ethereum/ethereum.go 100.00% <100.00%> (ø)
internal/blockchain/fabric/fabric.go 100.00% <100.00%> (ø)
internal/events/network_action.go 100.00% <100.00%> (ø)
internal/multiparty/manager.go 100.00% <100.00%> (ø)
internal/multiparty/operations.go 100.00% <100.00%> (ø)
internal/orchestrator/bound_callbacks.go 100.00% <100.00%> (ø)
internal/orchestrator/orchestrator.go 100.00% <100.00%> (ø)
internal/tokens/fftokens/fftokens.go 99.56% <100.00%> (+<0.01%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 52e7744...5d31178. Read the comment docs.

Signed-off-by: Andrew Richardson <andrew.richardson@kaleido.io>
Signed-off-by: Andrew Richardson <andrew.richardson@kaleido.io>
Copy link
Contributor

@peterbroadhurst peterbroadhurst left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great - none of my comments explicitly need action, but won't merge so you can review them first.

if namespace == "" {
// V1 networks don't populate namespace, so deliver the event to every handler
for _, handler := range cb.handlers {
if err := handler.BlockchainNetworkAction(action, location, event, signingKey); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like there should be a check for delivery of this to a V2 handler, and immediate rejection (worried about V1 pre-migrated contracts leaking actions to an unrelated V2 namespace that's new/migrated and happens to share a remote-name like default). Will look out for this later in the review

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, found it, in the caller of this function:

// For V1 of the FireFly contract, action is sent to all namespaces
// For V2+, namespace is inferred from the subscription
var namespace string
if subInfo.version > 1 {
namespace = subInfo.namespace
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but you make a good point that if we can't infer the namespace from the subscription name, then V2 handlers should reject it outright. I think there should be a sanity check for that when we initialize the subscription info, to ensure that whenever we get to the point you noted above, subInfo.namespace is guaranteed to be valid for V2+ contracts.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK I pushed another commit to include this sanity check during init.

}
return nil
}

func (cb *callbacks) BlockchainEvent(event *blockchain.EventWithSubscription) error {
for _, cb := range cb.handlers {
// Send the event to all handlers and let them match it to a contract listener
// TODO: can we push more listener/namespace knowledge down to this layer?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the same namespace-encoded-in-sub-name trick should work here, right? (with a migration consideration I guess)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(not suggesting the TODO needs to be addressed in this PR)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, thanks for the prod - I need to add that follow-up to the board. Currently our listeners for custom events have no significance to their subscription names (it's just ff-sub-<listener UUID>, but it really doesn't matter at all). We should introduce a format that can be parsed (with a fallback to "send it to everyone" for pre-existing listeners).

if err := cb.BlockchainNetworkAction(action, event, signingKey); err != nil {
return err
func (cb *callbacks) BlockchainNetworkAction(ctx context.Context, namespace, action string, location *fftypes.JSONAny, event *blockchain.Event, signingKey *core.VerifierRef) error {
if namespace == "" {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't help but (re) note the code duplication here - fine by me if your assessment is it's still the right thing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, we were able to commonize a chunk of the init and ingress logic for the FireFly multiparty contract when Multiparty Manager came into being - but you're right that the other end (handling the events that pop out of the multiparty contract) still has a lot of duplication. I'll note it for another pass on whether more of it can be commonized into Event Manger or Multiparty Manager (or some new place).

@awrichar awrichar merged commit bcc66bb into hyperledger:main Jul 6, 2022
@awrichar awrichar deleted the blockchain branch July 6, 2022 18:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants