Skip to content

Commit

Permalink
feat: implement begin blocker logic (#3)
Browse files Browse the repository at this point in the history
  • Loading branch information
johnletey authored Sep 26, 2024
1 parent 0ef1a33 commit 58a402e
Show file tree
Hide file tree
Showing 11 changed files with 178 additions and 3 deletions.
40 changes: 40 additions & 0 deletions e2e/fee_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package e2e

import (
"testing"

"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/strangelove-ventures/interchaintest/v8/ibc"

"github.com/stretchr/testify/require"
)

var COLLECTOR = "noble17xpfvakm2amg962yls6f84z3kell8c5lc6kgnn"

// TestBeginBlocker tests the module's begin blocker logic.
func TestBeginBlocker(t *testing.T) {
t.Parallel()

var wrapper Wrapper
ctx, _, _ := Suite(t, &wrapper, false)
validator := wrapper.chain.Validators[0]

oldBalance, err := wrapper.chain.BankQueryAllBalances(ctx, wrapper.owner.FormattedAddress())
require.NoError(t, err)

err = validator.BankSend(ctx, wrapper.owner.KeyName(), ibc.WalletAmount{
Address: wrapper.pendingOwner.FormattedAddress(),
Denom: "uusdc",
Amount: math.NewInt(1_000_000),
})
require.NoError(t, err)

balance, err := wrapper.chain.BankQueryAllBalances(ctx, COLLECTOR)
require.NoError(t, err)
require.True(t, balance.IsZero())

newBalance, err := wrapper.chain.BankQueryAllBalances(ctx, wrapper.owner.FormattedAddress())
require.NoError(t, err)
require.Equal(t, oldBalance.Sub(sdk.NewInt64Coin("uusdc", 1_000_000)), newBalance)
}
2 changes: 1 addition & 1 deletion simapp/app.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ modules:
"@type": cosmos.app.runtime.v1alpha1.Module
app_name: SimApp
pre_blockers: [ upgrade ]
begin_blockers: [ capability, staking, ibc ]
begin_blockers: [ authority, capability, staking, ibc ]
end_blockers: [ staking ]
init_genesis: [ capability, auth, bank, staking, ibc, genutil, transfer, upgrade, authority ]
override_store_keys:
Expand Down
6 changes: 6 additions & 0 deletions utils/mocks/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package mocks

import (
"cosmossdk.io/core/address"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth/codec"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/noble-assets/authority/x/authority/types"
)

Expand All @@ -13,3 +15,7 @@ type AccountKeeper struct{}
func (AccountKeeper) AddressCodec() address.Codec {
return codec.NewBech32Codec("noble")
}

func (k AccountKeeper) GetModuleAddress(moduleName string) sdk.AccAddress {
return authtypes.NewModuleAddress(moduleName)
}
5 changes: 5 additions & 0 deletions utils/mocks/authority.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ import (
)

func AuthorityKeeper(t testing.TB) (*keeper.Keeper, sdk.Context) {
return AuthorityKeeperWithBank(t, BankKeeper{})
}

func AuthorityKeeperWithBank(t testing.TB, bank types.BankKeeper) (*keeper.Keeper, sdk.Context) {
logger := log.NewNopLogger()

key := storetypes.NewKVStoreKey(types.ModuleName)
Expand All @@ -40,6 +44,7 @@ func AuthorityKeeper(t testing.TB) (*keeper.Keeper, sdk.Context) {
runtime.ProvideEventService(),
router,
AccountKeeper{},
bank,
), wrapper.Ctx
}

Expand Down
26 changes: 26 additions & 0 deletions utils/mocks/bank.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package mocks

import (
"context"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth/codec"
"github.com/noble-assets/authority/x/authority/types"
)

var cdc = codec.NewBech32Codec("noble")

var _ types.BankKeeper = BankKeeper{}

type BankKeeper struct {
Balances map[string]sdk.Coins
}

func (k BankKeeper) GetAllBalances(_ context.Context, bz sdk.AccAddress) sdk.Coins {
address, _ := cdc.BytesToString(bz)
return k.Balances[address]
}

func (k BankKeeper) SendCoins(_ context.Context, _, _ sdk.AccAddress, _ sdk.Coins) error {
return nil
}
28 changes: 28 additions & 0 deletions x/authority/keeper/abci.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package keeper

import (
"context"

"cosmossdk.io/errors"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
)

// BeginBlock sends all fees collected in the previous block to the module's owner.
func (k *Keeper) BeginBlock(ctx context.Context) error {
collector := k.accountKeeper.GetModuleAddress(authtypes.FeeCollectorName)
balance := k.bankKeeper.GetAllBalances(ctx, collector)
if balance.IsZero() {
return nil
}

owner, err := k.Owner.Get(ctx)
if err != nil {
return errors.Wrap(err, "failed to get owner from state")
}
address, err := k.accountKeeper.AddressCodec().StringToBytes(owner)
if err != nil {
return errors.Wrap(err, "failed to decode owner address")
}

return k.bankKeeper.SendCoins(ctx, collector, address, balance)
}
49 changes: 49 additions & 0 deletions x/authority/keeper/abci_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package keeper_test

import (
"testing"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/noble-assets/authority/utils"
"github.com/noble-assets/authority/utils/mocks"
"github.com/stretchr/testify/require"
)

func TestBeginBlock(t *testing.T) {
bank := mocks.BankKeeper{
Balances: make(map[string]sdk.Coins),
}
keeper, ctx := mocks.AuthorityKeeperWithBank(t, bank)

// ACT: Attempt to run begin blocker with empty fee collector.
err := keeper.BeginBlock(ctx)
// ASSERT: The action should've succeeded due to empty account.
require.NoError(t, err)

// ARRANGE: Give the fee collector some balance.
bank.Balances["noble17xpfvakm2amg962yls6f84z3kell8c5lc6kgnn"] = sdk.NewCoins(
sdk.NewInt64Coin("uusdc", 20_000),
)

// ACT: Attempt to run begin blocker with no owner set.
err = keeper.BeginBlock(ctx)
// ASSERT: The action should've failed due to no owner set.
require.ErrorContains(t, err, "failed to get owner from state")

// ARRANGE: Set an invalid owner in state.
require.NoError(t, keeper.Owner.Set(ctx, "cosmos10d07y265gmmuvt4z0w9aw880jnsr700j6zn9kn"))

// ACT: Attempt to run begin blocker with invalid owner set.
err = keeper.BeginBlock(ctx)
// ASSERT: The action should've failed due to invalid owner set.
require.ErrorContains(t, err, "failed to decode owner address")

// ARRANGE: Generate an owner account and set in state.
owner := utils.TestAccount()
require.NoError(t, keeper.Owner.Set(ctx, owner.Address))

// ACT: Attempt to run begin blocker.
err = keeper.BeginBlock(ctx)
// ASSERT: The action should've succeeded.
require.NoError(t, err)
}
3 changes: 3 additions & 0 deletions x/authority/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type Keeper struct {

router baseapp.MessageRouter
accountKeeper types.AccountKeeper
bankKeeper types.BankKeeper
}

func NewKeeper(
Expand All @@ -31,6 +32,7 @@ func NewKeeper(
eventService event.Service,
router baseapp.MessageRouter,
accountKeeper types.AccountKeeper,
bankKeeper types.BankKeeper,
) *Keeper {
builder := collections.NewSchemaBuilder(storeService)

Expand All @@ -45,6 +47,7 @@ func NewKeeper(

router: router,
accountKeeper: accountKeeper,
bankKeeper: bankKeeper,
}

schema, err := builder.Build()
Expand Down
2 changes: 1 addition & 1 deletion x/authority/keeper/msg_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ func TestTransferOwnership(t *testing.T) {
owner := utils.TestAccount()
require.NoError(t, k.Owner.Set(ctx, owner.Address))

// ACT: Attempt to tranfer ownership with invalid signer.
// ACT: Attempt to transfer ownership with invalid signer.
_, err := server.TransferOwnership(ctx, &types.MsgTransferOwnership{
Signer: utils.TestAccount().Address,
})
Expand Down
7 changes: 7 additions & 0 deletions x/authority/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const ConsensusVersion = 1
var (
_ module.AppModuleBasic = AppModule{}
_ appmodule.AppModule = AppModule{}
_ appmodule.HasBeginBlocker = AppModule{}
_ module.HasConsensusVersion = AppModule{}
_ module.HasGenesis = AppModule{}
_ module.HasServices = AppModule{}
Expand Down Expand Up @@ -96,6 +97,10 @@ func (AppModule) IsOnePerModuleType() {}

func (AppModule) IsAppModule() {}

func (m AppModule) BeginBlock(ctx context.Context) error {
return m.keeper.BeginBlock(ctx)
}

func (AppModule) ConsensusVersion() uint64 { return ConsensusVersion }

func (m AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, bz json.RawMessage) {
Expand Down Expand Up @@ -178,6 +183,7 @@ type ModuleInputs struct {

Router baseapp.MessageRouter
AccountKeeper types.AccountKeeper
BankKeeper types.BankKeeper
}

type ModuleOutputs struct {
Expand All @@ -195,6 +201,7 @@ func ProvideModule(in ModuleInputs) ModuleOutputs {
in.EventService,
in.Router,
in.AccountKeeper,
in.BankKeeper,
)
m := NewAppModule(k, in.AccountKeeper)

Expand Down
13 changes: 12 additions & 1 deletion x/authority/types/expected_keepers.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
package types

import "cosmossdk.io/core/address"
import (
"context"

"cosmossdk.io/core/address"
sdk "github.com/cosmos/cosmos-sdk/types"
)

type AccountKeeper interface {
AddressCodec() address.Codec
GetModuleAddress(moduleName string) sdk.AccAddress
}

type BankKeeper interface {
GetAllBalances(ctx context.Context, addr sdk.AccAddress) sdk.Coins
SendCoins(ctx context.Context, fromAddr, toAddr sdk.AccAddress, amt sdk.Coins) error
}

0 comments on commit 58a402e

Please sign in to comment.