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-3] - Module SubAccounts #4732

Closed
wants to merge 22 commits into from
Closed
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/architecture/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@ Please add a entry below in your Pull Request for an ADR.
### ADR Table of Contents

- [ADR-002-Docs-Structure](./adr-002-docs-structure.md)
- [ADR-003-Module-Sub-Accounts](./adr-003-module-sub-accounts.md)
112 changes: 112 additions & 0 deletions docs/architecture/adr-003-module-sub-accounts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# ADR 3: Module Sub-Accounts

## Changelog

## Context

Currently `ModuleAccount`s must be declared upon Supply Keeper initialization. In addition to this they don't allow for separation of fungible coins within an account.

We want to support the ability to define and manage sub-module-accounts.

## Decision

We will modify the existing `ModuleAccount` interface to support a heirarchical account structure.
The `ModuleAccount`s defined upon initialization of Supply Keeper are the roots of family trees.
Each `ModuleAccount` in a family tree may have zero or more children.
A `ModuleAccount` with one or more children is considered a parent to each child.
All `ModuleAccount`s have exactly one parent, unless they are the root of their family tree.

`ModuleAccount` permissions will be renamed to `Attribute`.
Each child's attributes must be a subset of their parent's attributes.
There is no limit on the number of children a `ModuleAccount` can have.
No `ModuleAccount`s can be removed from a family tree.
A `ModuleAccount` name is the path of the `ModuleAccount` names used to reach the child.
It starts with the root `ModuleAccount` name and is separated by a colon for each parent that follows until the child is reached.

Example name: `root:parent:child`

We will add a `TrackBalance` function which recursively updates the passive tracking of parent balances.
A `ModuleAccount` address is the hash of its name.
A `ModuleAccount` has no pubkeys.
The function `AddChildToModuleAccount` will be added to Supply Keeper,
It will validate that the granted attributes are a subset of the parent and then register the child's name with the Supply Keeper.

### Implementation Changes

Modify `ModuleAccount` interface in `x/supply`:

```go
type ModuleAccount interface {
colin-axner marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Member

Choose a reason for hiding this comment

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

Is it possible to add/delete attributes. Should parents be able to modify attributes of their children?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Discussion for this can be seen here #4762. Outside of the scope of this ADR in my opinion.

GetName() string
GetAddress() string
GetAttribute() []string
HasAttribute() bool
GetParent() string
GetChildren() []string
HasChild(string) bool
GetChildCoins() sdk.Coins
}
```

```go
// Implements the Account interface.
// ModuleAccount defines an account for modules that holds coins on a pool. A ModuleAccount
// may have sub-accounts known as children.
type ModuleAccount struct {
*authtypes.BaseAccount
Name string `json:"name" yaml:"name"` // name of the module
Attributes []string `json:"attributes" yaml:"attributes"` // permissions of module account
ChildCoins sdk.Coins `json:"child_coins" yaml:"child_coins"` // passive tracking of sum of child balances
Copy link
Member

Choose a reason for hiding this comment

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

I think this should be TreeCoins/TotalCoins or something similar and passively track sum of child + self balances

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am in favor of only passively tracking child balances and just calling GetChildCoins + GetCoins to get total. What do other people think?

Children []string `json:"children" yaml:"children"` // array of children names
Parent string `json:"parent" yaml:"parent"` // parent name
colin-axner marked this conversation as resolved.
Show resolved Hide resolved
}
```

```go
// Pseudocode
func TrackBalance(name string, delta sdk.Coins) {
if name == "" {
return
} else {
self.Balance += delta
}
TrackBalance(chopString(name)) // chop off last name after last ":"
return
}
```

**Attributes**:

Attributes for a root `ModuleAccount` are decalred upon initialization of the Supply Keeper.
colin-axner marked this conversation as resolved.
Show resolved Hide resolved
A child `ModuleAccount` must have a subset of its parents attributes.

**Other changes**

We will add an invariant check for the `ModuleAccount` `GetChildCoins()` function, which will iterate over all `ModuleAccounts` to see if the sum of their child balances equals the passive tracking which is returned in `GetChildCoins()`

## Status

Accepted

## Consequences

### Positive

* `ModuleAccount` can separate fungible coins.
* `ModuleAccount` can dynamically add accounts.
* Children can have a subset of its parent's attributes.

### Negative

* `ModuleAccount` cannot be removed from a family tree.
* `ModuleAccount` implementation has increased complexity.

### Neutral

* `ModuleAccount` passively tracks child balances.

## References

Specs: [ModuleAccount](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/supply/01_concepts.md#module-accounts)

Issues: [4657](https://github.com/cosmos/cosmos-sdk/issues/4657)