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

ADR-003: Dynamic Capabilities #5828

Merged
merged 30 commits into from Mar 24, 2020
Merged

ADR-003: Dynamic Capabilities #5828

merged 30 commits into from Mar 24, 2020

Conversation

alexanderbez
Copy link
Contributor

@alexanderbez alexanderbez commented Mar 18, 2020

Description

Implementation of ADR 003 - Dynamic Capabilities.

ref: #5542

/cc @jackzampolin @cwgoes @AdityaSripal @fedekunze


For contributor use:

  • Targeted PR against correct branch (see CONTRIBUTING.md)
  • Linked to Github issue with discussion and accepted design OR link to spec that describes this work.
  • Code follows the module structure standards.
  • Wrote unit and integration tests
  • Updated relevant documentation (docs/) or specification (x/<module>/spec/)
  • Added relevant godoc comments.
  • Added a relevant changelog entry to the Unreleased section in CHANGELOG.md
  • Re-reviewed Files changed in the Github PR explorer

For admin use:

  • Added appropriate labels to PR (ex. WIP, R4R, docs, etc)
  • Reviewers assigned
  • Squashed all commits, uses message "Merge pull request #XYZ: [title]" (coding standards)

Copy link
Collaborator

@fedekunze fedekunze left a comment

Choose a reason for hiding this comment

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

👍 Core logic LGTM

@@ -326,6 +327,25 @@ func (key *TransientStoreKey) String() string {
return fmt.Sprintf("TransientStoreKey{%p, %s}", key, key.name)
}

// MemoryStoreKey defines a typed key to be used with an in-memory KVStore.
type MemoryStoreKey struct {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'd add a Type() sdk.StoreKeyType method to the sdk.StoreKey interface

return Keeper{
cdc: cdc,
storeKey: storeKey,
memKey: memKey,
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'd panic here if the memKey.Type() doesn't match sdk. MemoryStoreKey

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We could, but the app has to call InitializeAndSeal which does the check without us having to change the interface of StoreKey.

x/capability/keeper/keeper.go Outdated Show resolved Hide resolved
x/capability/types/errors.go Show resolved Hide resolved
x/capability/types/keys.go Show resolved Hide resolved
x/capability/types/keys.go Outdated Show resolved Hide resolved
@alexanderbez alexanderbez marked this pull request as ready for review March 20, 2020 19:12
@alexanderbez alexanderbez added R4R and removed WIP labels Mar 20, 2020
x/capability/docs/README.md Outdated Show resolved Hide resolved
x/capability/docs/README.md Outdated Show resolved Hide resolved
x/capability/docs/README.md Outdated Show resolved Hide resolved
x/capability/types/keys.go Outdated Show resolved Hide resolved

// Set attempts to add a given owner to the CapabilityOwners. If the owner already
// exists, an error will be returned.
func (co *CapabilityOwners) Set(owner Owner) error {
Copy link
Contributor

Choose a reason for hiding this comment

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

Just a note, this is O(n), it could be O(1) if we use a map (should be safe since iteration order won't change behaviour), or O(log n) if we do a binary search to check for duplicates & then insert.

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, I've already thought about this. But since the CapabilityOwners type is encoded and persisted to state, you cannot use a map. Even if you did use a map at runtime and use a slice when you persist, you'd still have O(n) conversion. I've thought of various ways to do this like keeping an ephemeral map/cache, but it doesn't seem clean.

However, binary search would work and we can cut down Set to O(log n). I'll address that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated. Note, worst case can still be O(n). Maybe this is overkill, idk. We could also define an initial capacity in the owner slice.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think it's fine for the time being.

Co-Authored-By: Aditya <adityasripal@gmail.com>
Copy link
Contributor

@cwgoes cwgoes left a comment

Choose a reason for hiding this comment

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

Great job @alexanderbez, looks almost entirely correct to me, a few changes to documentation needed (probably copied from a slightly out-of-date spec) and a few minor comments, but overall nearly there. 🎉

@AdityaSripal
Copy link
Member

@cwgoes

Think the ADR still has the outdated behavior in GetCapability:

e77496f#diff-b232b32a8f540d33f5040df6477179b1R175

GetCapability allows a module to fetch a capability which it has previously claimed by name. The module is not allowed to retrieve capabilities which it does not own. If another module claims a capability, the previously owning module will no longer be able to claim it.

@cwgoes
Copy link
Contributor

cwgoes commented Mar 23, 2020

@cwgoes

Think the ADR still has the outdated behavior in GetCapability:

e77496f#diff-b232b32a8f540d33f5040df6477179b1R175

GetCapability allows a module to fetch a capability which it has previously claimed by name. The module is not allowed to retrieve capabilities which it does not own. If another module claims a capability, the previously owning module will no longer be able to claim it.

Yes - we should delete the last sentence.

Copy link
Contributor

@cwgoes cwgoes left a comment

Choose a reason for hiding this comment

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

utACK 🎈 - thanks for the ADR updates.


// Set attempts to add a given owner to the CapabilityOwners. If the owner already
// exists, an error will be returned.
func (co *CapabilityOwners) Set(owner Owner) error {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it's fine for the time being.

store/mem/store.go Outdated Show resolved Hide resolved
x/capability/alias.go Show resolved Hide resolved
x/capability/alias.go Show resolved Hide resolved
Copy link
Member

@AdityaSripal AdityaSripal left a comment

Choose a reason for hiding this comment

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

utACK, good work @alexanderbez! looking forward to integrating this 👍

@alexanderbez alexanderbez merged commit dc737f5 into ibc-alpha Mar 24, 2020
@alexanderbez alexanderbez deleted the bez/adr-003-dynamic-cap branch March 24, 2020 14:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants