Skip to content

Commit

Permalink
feat: stateless lien module that upcalls to kernel
Browse files Browse the repository at this point in the history
  • Loading branch information
JimLarson committed Oct 3, 2021
1 parent 3f53592 commit 603c0cf
Show file tree
Hide file tree
Showing 10 changed files with 458 additions and 4 deletions.
14 changes: 13 additions & 1 deletion golang/cosmos/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ import (

gaiaappparams "github.com/Agoric/agoric-sdk/golang/cosmos/app/params"
"github.com/Agoric/agoric-sdk/golang/cosmos/vm"
"github.com/Agoric/agoric-sdk/golang/cosmos/x/lien"
"github.com/Agoric/agoric-sdk/golang/cosmos/x/swingset"
"github.com/Agoric/agoric-sdk/golang/cosmos/x/vbank"
"github.com/Agoric/agoric-sdk/golang/cosmos/x/vibc"
Expand Down Expand Up @@ -166,6 +167,7 @@ type GaiaApp struct { // nolint: golint
appCodec codec.Codec
interfaceRegistry types.InterfaceRegistry

lienPort int
vbankPort int
vibcPort int

Expand Down Expand Up @@ -198,6 +200,7 @@ type GaiaApp struct { // nolint: golint
SwingSetKeeper swingset.Keeper
VibcKeeper vibc.Keeper
VbankKeeper vbank.Keeper
LienKeeper lien.Keeper

// make scoped keepers public for test purposes
ScopedIBCKeeper capabilitykeeper.ScopedKeeper
Expand Down Expand Up @@ -292,9 +295,11 @@ func NewAgoricApp(
app.CapabilityKeeper.Seal()

// add keepers
app.AccountKeeper = authkeeper.NewAccountKeeper(
innerAk := authkeeper.NewAccountKeeper(
appCodec, keys[authtypes.StoreKey], app.GetSubspace(authtypes.ModuleName), authtypes.ProtoBaseAccount, maccPerms,
)
wrappedAccountKeeper := lien.NewWrappedAccountKeeper(innerAk)
app.AccountKeeper = wrappedAccountKeeper
app.BankKeeper = bankkeeper.NewBaseKeeper(
appCodec, keys[banktypes.StoreKey], app.AccountKeeper, app.GetSubspace(banktypes.ModuleName), app.ModuleAccountAddrs(),
)
Expand Down Expand Up @@ -403,6 +408,11 @@ func NewAgoricApp(
vbankModule := vbank.NewAppModule(app.VbankKeeper)
app.vbankPort = vm.RegisterPortHandler("bank", vbank.NewPortHandler(vbankModule, app.VbankKeeper))

// Lien keeper, and circular reference back to wrappedAccountKeeper
app.LienKeeper = lien.NewKeeper(wrappedAccountKeeper, app.BankKeeper, app.StakingKeeper, callToController)
wrappedAccountKeeper.SetWrapper(app.LienKeeper.GetAccountWrapper())
app.lienPort = vm.RegisterPortHandler("lien", app.LienKeeper)

// create evidence keeper with router
evidenceKeeper := evidencekeeper.NewKeeper(
appCodec, keys[evidencetypes.StoreKey], &app.StakingKeeper, app.SlashingKeeper,
Expand Down Expand Up @@ -548,6 +558,7 @@ type cosmosInitAction struct {
SupplyCoins sdk.Coins `json:"supplyCoins"`
VibcPort int `json:"vibcPort"`
VbankPort int `json:"vbankPort"`
LienPort int `json:"lienPort"`
}

// Name returns the name of the App
Expand All @@ -567,6 +578,7 @@ func (app *GaiaApp) MustInitController(ctx sdk.Context) {
SupplyCoins: sdk.NewCoins(app.BankKeeper.GetSupply(ctx, "urun")),
VibcPort: app.vibcPort,
VbankPort: app.vbankPort,
LienPort: app.lienPort,
}
bz, err := json.Marshal(action)
if err == nil {
Expand Down
15 changes: 15 additions & 0 deletions golang/cosmos/x/lien/alias.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package lien

import (
"github.com/Agoric/agoric-sdk/golang/cosmos/x/lien/keeper"
"github.com/Agoric/agoric-sdk/golang/cosmos/x/lien/types"
)

var (
NewKeeper = keeper.NewKeeper
NewWrappedAccountKeeper = types.NewWrappedAccountKeeper
)

type (
Keeper = keeper.Keeper
)
135 changes: 135 additions & 0 deletions golang/cosmos/x/lien/keeper/account.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package keeper

import (
"strings"
"time"

"github.com/Agoric/agoric-sdk/golang/cosmos/x/lien/types"

sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
vestexported "github.com/cosmos/cosmos-sdk/x/auth/vesting/exported"
)

func maxCoins(a, b sdk.Coins) sdk.Coins {
max := make([]sdk.Coin, 0)
for indexA, indexB := 0, 0; indexA < len(a) && indexB < len(b); {
coinA, coinB := a[indexA], b[indexB]
switch strings.Compare(coinA.Denom, coinB.Denom) {
case -1: // A < B
max = append(max, coinA)
indexA++
case 0: // A == B
maxCoin := coinA
if coinB.IsGTE(maxCoin) {
maxCoin = coinB
}
if !maxCoin.IsZero() {
max = append(max, maxCoin)
}
indexA++
indexB++
case 1: // A > B
max = append(max, coinB)
indexB++
}
}
return sdk.NewCoins(max...)
}

var _ vestexported.VestingAccount = &LienAccount{}

type LienAccount struct {
vestexported.VestingAccount
lienKeeper Keeper
}

// LockedCoins implements the method from the VestingAccount interface.
// It takes the maximum of the coins locked for liens and the cons
// locked in the wrapped VestingAccount.
func (la *LienAccount) LockedCoins(ctx sdk.Context) sdk.Coins {
wrappedLocked := la.VestingAccount.LockedCoins(ctx)
lienedLocked := la.LienedLockedCoins(ctx)
return maxCoins(wrappedLocked, lienedLocked)
}

func (la *LienAccount) LienedLockedCoins(ctx sdk.Context) sdk.Coins {
return la.lienKeeper.GetLien(ctx, la.GetAddress())
}

func NewAccountWrapper(lk Keeper) types.AccountWrapper {
return types.AccountWrapper{
Wrap: func(acc authtypes.AccountI) authtypes.AccountI {
if acc == nil {
return nil
}
return &LienAccount{
VestingAccount: makeVesting(acc),
lienKeeper: lk,
}
},
Unwrap: func(acc authtypes.AccountI) authtypes.AccountI {
if la, ok := acc.(*LienAccount); ok {
acc = la.VestingAccount
}
if uva, ok := acc.(*unlockedVestingAccount); ok {
acc = uva.AccountI
}
return acc
},
}
}

func makeVesting(acc authtypes.AccountI) vestexported.VestingAccount {
if v, ok := acc.(vestexported.VestingAccount); ok {
return v
}
return &unlockedVestingAccount{AccountI: acc}
}

// unlockedVestingAccount extends an ordinary account to be a vesting account
// by simulating an original vesting amount of zero. It will be still stored
// as the wrapped account.
type unlockedVestingAccount struct {
authtypes.AccountI
}

var _ vestexported.VestingAccount = (*unlockedVestingAccount)(nil)

func (uva *unlockedVestingAccount) LockedCoins(ctx sdk.Context) sdk.Coins {
return sdk.NewCoins()
}

func (uva *unlockedVestingAccount) TrackDelegation(blockTime time.Time, balance, amount sdk.Coins) {
}

func (uva *unlockedVestingAccount) TrackUndelegation(amount sdk.Coins) {
}

func (uva *unlockedVestingAccount) GetVestedCoins(blockTime time.Time) sdk.Coins {
return sdk.NewCoins()
}

func (uva *unlockedVestingAccount) GetVestingCoins(blockTime time.Time) sdk.Coins {
return sdk.NewCoins()
}

func (uva *unlockedVestingAccount) GetStartTime() int64 {
return 0
}

func (uva *unlockedVestingAccount) GetEndTime() int64 {
return 0
}

func (uva *unlockedVestingAccount) GetOriginalVesting() sdk.Coins {
return sdk.NewCoins()
}

func (uva *unlockedVestingAccount) GetDelegatedFree() sdk.Coins {
return sdk.NewCoins()
}

func (uva *unlockedVestingAccount) GetDelegatedVesting() sdk.Coins {
return sdk.NewCoins()
}
Loading

0 comments on commit 603c0cf

Please sign in to comment.