Skip to content

Commit

Permalink
feat!: Define Genesis state transition (#15999)
Browse files Browse the repository at this point in the history
  • Loading branch information
tac0turtle authored May 3, 2023
1 parent 672b1f9 commit d31f296
Show file tree
Hide file tree
Showing 14 changed files with 79 additions and 44 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* The signature of `NewSigVerificationDecorator` has been changed to accept a `x/tx/signing.HandlerMap`.
* The signature of `VerifySignature` has been changed to accept a `x/tx/signing.HandlerMap` and other structs from `x/tx` as arguments.
* The signature of `NewTxConfigWithTextual` has been deprecated and its signature changed to accept a `SignModeOptions`.
* (x/genutil) [#15999](https://github.com/cosmos/cosmos-sdk/pull/15999) Genutil now takes the `GenesisTxHanlder` interface instead of deliverTx. The interface is implemented on baseapp

### Client Breaking Changes

Expand Down
22 changes: 22 additions & 0 deletions baseapp/genesis.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package baseapp

import (
"errors"

"cosmossdk.io/core/genesis"
"github.com/cometbft/cometbft/abci/types"
)

var _ genesis.TxHandler = (*BaseApp)(nil)

// ExecuteGenesisTx implements genesis.GenesisState from
// cosmossdk.io/core/genesis to set initial state in genesis
func (ba BaseApp) ExecuteGenesisTx(tx []byte) error {
res := ba.DeliverTx(types.RequestDeliverTx{Tx: tx})

if res.Code != types.CodeTypeOK {
return errors.New(res.Log)
}

return nil
}
6 changes: 5 additions & 1 deletion core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,8 @@ Ref: https://keepachangelog.com/en/1.0.0/

### API-Breaking Changes

- (store)[14635](https://github.com/cosmos/cosmos-sdk/pull/14635) Add error handling to all methods on the `KVStore` interface
* (store)[14635](https://github.com/cosmos/cosmos-sdk/pull/14635) Add error handling to all methods on the `KVStore` interface

### Features

* (genesis) [#15999](https://github.com/cosmos/cosmos-sdk/pull/15999) Add `GenesisTxHandler` interface
6 changes: 6 additions & 0 deletions core/genesis/txhandler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package genesis

// TxHandler is an interface that modules can implement to provide genesis state transitions
type TxHandler interface {
ExecuteGenesisTx([]byte) error
}
8 changes: 8 additions & 0 deletions docs/docs/building-modules/08-genesis.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,11 @@ See an example of `ExportGenesis` from the `auth` module.
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/x/auth/keeper/genesis.go#L37-L49
```

### GenesisTxHandler

`GenesisTxHandler` is a way for modules to submit state transitions prior to the first block. This is used by `x/genutil` to submit the genesis transactions for the validators to be added to staking.

```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/core/genesis/txhandler.go#L3-L6
```
11 changes: 4 additions & 7 deletions runtime/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@ import (
"fmt"
"os"

"cosmossdk.io/core/genesis"
"cosmossdk.io/core/store"
"cosmossdk.io/log"
"github.com/cosmos/gogoproto/proto"
"google.golang.org/protobuf/reflect/protodesc"
"google.golang.org/protobuf/reflect/protoregistry"

abci "github.com/cometbft/cometbft/abci/types"

runtimev1alpha1 "cosmossdk.io/api/cosmos/app/runtime/v1alpha1"
appv1alpha1 "cosmossdk.io/api/cosmos/app/v1alpha1"
"cosmossdk.io/core/appmodule"
Expand Down Expand Up @@ -62,7 +61,7 @@ func init() {
ProvideKVStoreKey,
ProvideTransientStoreKey,
ProvideMemoryStoreKey,
ProvideDeliverTx,
ProvideGenesisTxHandler,
ProvideKVStoreService,
ProvideMemoryStoreService,
ProvideTransientStoreService,
Expand Down Expand Up @@ -211,10 +210,8 @@ func ProvideMemoryStoreKey(key depinject.ModuleKey, app *AppBuilder) *storetypes
return storeKey
}

func ProvideDeliverTx(appBuilder *AppBuilder) func(abci.RequestDeliverTx) abci.ResponseDeliverTx {
return func(tx abci.RequestDeliverTx) abci.ResponseDeliverTx {
return appBuilder.app.BaseApp.DeliverTx(tx)
}
func ProvideGenesisTxHandler(appBuilder *AppBuilder) genesis.TxHandler {
return appBuilder.app
}

func ProvideKVStoreService(config *runtimev1alpha1.Module, key depinject.ModuleKey, app *AppBuilder) store.KVStoreService {
Expand Down
2 changes: 1 addition & 1 deletion simapp/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ func NewSimApp(
// must be passed by reference here.
app.ModuleManager = module.NewManager(
genutil.NewAppModule(
app.AccountKeeper, app.StakingKeeper, app.BaseApp.DeliverTx,
app.AccountKeeper, app.StakingKeeper, app,
encodingConfig.TxConfig,
),
auth.NewAppModule(appCodec, app.AccountKeeper, authsims.RandomGenesisAccounts, app.GetSubspace(authtypes.ModuleName)),
Expand Down
4 changes: 2 additions & 2 deletions tests/integration/genutil/gentx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,13 +305,13 @@ func TestDeliverGenTxs(t *testing.T) {
if tc.expPass {
require.NotPanics(t, func() {
genutil.DeliverGenTxs(
f.ctx, genTxs, f.stakingKeeper, f.baseApp.DeliverTx,
f.ctx, genTxs, f.stakingKeeper, f.baseApp,
f.encodingConfig.TxConfig,
)
})
} else {
_, err := genutil.DeliverGenTxs(
f.ctx, genTxs, f.stakingKeeper, f.baseApp.DeliverTx,
f.ctx, genTxs, f.stakingKeeper, f.baseApp,
f.encodingConfig.TxConfig,
)

Expand Down
2 changes: 1 addition & 1 deletion tools/rosetta/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,8 @@ require (

// TODO: remove after merge of https://github.com/cosmos/cosmos-sdk/pull/15873 and tagging releases
replace (
cosmossdk.io/core => ../../core
cosmossdk.io/store => ../../store
cosmossdk.io/x/tx => ../../x/tx
cosmossdk.io/core => ../../core
github.com/cosmos/cosmos-sdk => ../..
)
2 changes: 0 additions & 2 deletions tools/rosetta/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@ cosmossdk.io/api v0.4.1 h1:0ikaYM6GyxTYYcfBiyR8YnLCfhNnhKpEFnaSepCTmqg=
cosmossdk.io/api v0.4.1/go.mod h1:jR7k5ok90LxW2lFUXvd8Vpo/dr4PpiyVegxdm7b1ZdE=
cosmossdk.io/collections v0.1.0 h1:nzJGeiq32KnZroSrhB6rPifw4I85Cgmzw/YAmr4luv8=
cosmossdk.io/collections v0.1.0/go.mod h1:xbauc0YsbUF8qKMVeBZl0pFCunxBIhKN/WlxpZ3lBuo=
cosmossdk.io/core v0.6.1 h1:OBy7TI2W+/gyn2z40vVvruK3di+cAluinA6cybFbE7s=
cosmossdk.io/core v0.6.1/go.mod h1:g3MMBCBXtxbDWBURDVnJE7XML4BG5qENhs0gzkcpuFA=
cosmossdk.io/depinject v1.0.0-alpha.3 h1:6evFIgj//Y3w09bqOUOzEpFj5tsxBqdc5CfkO7z+zfw=
cosmossdk.io/depinject v1.0.0-alpha.3/go.mod h1:eRbcdQ7MRpIPEM5YUJh8k97nxHpYbc3sMUnEtt8HPWU=
cosmossdk.io/errors v1.0.0-beta.7 h1:gypHW76pTQGVnHKo6QBkb4yFOJjC+sUGRc5Al3Odj1w=
Expand Down
3 changes: 2 additions & 1 deletion x/genutil/genesis.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package genutil

import (
"cosmossdk.io/core/genesis"
abci "github.com/cometbft/cometbft/abci/types"

"github.com/cosmos/cosmos-sdk/client"
Expand All @@ -11,7 +12,7 @@ import (
// InitGenesis - initialize accounts and deliver genesis transactions
func InitGenesis(
ctx sdk.Context, stakingKeeper types.StakingKeeper,
deliverTx deliverTxfn, genesisState types.GenesisState,
deliverTx genesis.TxHandler, genesisState types.GenesisState,
txEncodingConfig client.TxEncodingConfig,
) (validators []abci.ValidatorUpdate, err error) {
if len(genesisState.GenTxs) > 0 {
Expand Down
11 changes: 5 additions & 6 deletions x/genutil/gentx.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"fmt"

"cosmossdk.io/core/genesis"
abci "github.com/cometbft/cometbft/abci/types"

"github.com/cosmos/cosmos-sdk/client"
Expand Down Expand Up @@ -84,14 +85,12 @@ func ValidateAccountInGenesis(
return nil
}

type deliverTxfn func(abci.RequestDeliverTx) abci.ResponseDeliverTx

// DeliverGenTxs iterates over all genesis txs, decodes each into a Tx and
// invokes the provided deliverTxfn with the decoded Tx. It returns the result
// of the staking module's ApplyAndReturnValidatorSetUpdates.
func DeliverGenTxs(
ctx sdk.Context, genTxs []json.RawMessage,
stakingKeeper types.StakingKeeper, deliverTx deliverTxfn,
stakingKeeper types.StakingKeeper, deliverTx genesis.TxHandler,
txEncodingConfig client.TxEncodingConfig,
) ([]abci.ValidatorUpdate, error) {
for _, genTx := range genTxs {
Expand All @@ -105,9 +104,9 @@ func DeliverGenTxs(
return nil, fmt.Errorf("failed to encode GenTx '%s': %s", genTx, err)
}

res := deliverTx(abci.RequestDeliverTx{Tx: bz})
if !res.IsOK() {
return nil, fmt.Errorf("failed to execute DeliverTx for '%s': %s", genTx, res.Log)
err = deliverTx.ExecuteGenesisTx(bz)
if err != nil {
return nil, fmt.Errorf("failed to execute DeliverTx for '%s': %s", genTx, err)
}
}

Expand Down
38 changes: 18 additions & 20 deletions x/genutil/gentx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,23 @@ package genutil_test

import (
"encoding/json"
"errors"
"fmt"
"math/rand"
"testing"
"time"

"cosmossdk.io/core/genesis"
"cosmossdk.io/math"

storetypes "cosmossdk.io/store/types"
abci "github.com/cometbft/cometbft/abci/types"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/suite"

"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
"github.com/cosmos/cosmos-sdk/testutil"
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/cosmos/cosmos-sdk/x/genutil"
Expand Down Expand Up @@ -246,7 +246,7 @@ func (suite *GenTxTestSuite) TestDeliverGenTxs() {
testCases := []struct {
msg string
malleate func()
deliverTxFn func(abci.RequestDeliverTx) abci.ResponseDeliverTx
deliverTxFn genesis.TxHandler
expPass bool
}{
{
Expand All @@ -260,14 +260,7 @@ func (suite *GenTxTestSuite) TestDeliverGenTxs() {
suite.Require().NoError(err)
genTxs[0] = tx
},
func(_ abci.RequestDeliverTx) abci.ResponseDeliverTx {
return abci.ResponseDeliverTx{
Code: sdkerrors.ErrNoSignatures.ABCICode(),
GasWanted: int64(10000000),
GasUsed: int64(41913),
Log: "no signatures supplied",
}
},
GenesisState1{},
false,
},
{
Expand All @@ -293,15 +286,7 @@ func (suite *GenTxTestSuite) TestDeliverGenTxs() {
suite.Require().NoError(err)
genTxs[0] = genTx
},
func(tx abci.RequestDeliverTx) abci.ResponseDeliverTx {
return abci.ResponseDeliverTx{
Code: sdkerrors.ErrUnauthorized.ABCICode(),
GasWanted: int64(10000000),
GasUsed: int64(41353),
Log: "signature verification failed; please verify account number (4) and chain-id (): unauthorized",
Codespace: "sdk",
}
},
GenesisState2{},
true,
},
}
Expand All @@ -313,6 +298,7 @@ func (suite *GenTxTestSuite) TestDeliverGenTxs() {
tc.malleate()

if tc.expPass {
suite.stakingKeeper.EXPECT().ApplyAndReturnValidatorSetUpdates(gomock.Any()).Return(nil, nil).AnyTimes()
suite.Require().NotPanics(func() {
genutil.DeliverGenTxs(
suite.ctx, genTxs, suite.stakingKeeper, tc.deliverTxFn,
Expand All @@ -334,3 +320,15 @@ func (suite *GenTxTestSuite) TestDeliverGenTxs() {
func TestGenTxTestSuite(t *testing.T) {
suite.Run(t, new(GenTxTestSuite))
}

type GenesisState1 struct{}

func (GenesisState1) ExecuteGenesisTx(_ []byte) error {
return errors.New("no signatures supplied")
}

type GenesisState2 struct{}

func (GenesisState2) ExecuteGenesisTx(tx []byte) error {
return nil
}
7 changes: 4 additions & 3 deletions x/genutil/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

modulev1 "cosmossdk.io/api/cosmos/genutil/module/v1"
"cosmossdk.io/core/appmodule"
"cosmossdk.io/core/genesis"

"cosmossdk.io/depinject"

Expand Down Expand Up @@ -80,13 +81,13 @@ type AppModule struct {

accountKeeper types.AccountKeeper
stakingKeeper types.StakingKeeper
deliverTx deliverTxfn
deliverTx genesis.TxHandler
txEncodingConfig client.TxEncodingConfig
}

// NewAppModule creates a new AppModule object
func NewAppModule(accountKeeper types.AccountKeeper,
stakingKeeper types.StakingKeeper, deliverTx deliverTxfn,
stakingKeeper types.StakingKeeper, deliverTx genesis.TxHandler,
txEncodingConfig client.TxEncodingConfig,
) module.GenesisOnlyAppModule {
return module.NewGenesisOnlyAppModule(AppModule{
Expand Down Expand Up @@ -138,7 +139,7 @@ type ModuleInputs struct {

AccountKeeper types.AccountKeeper
StakingKeeper types.StakingKeeper
DeliverTx func(abci.RequestDeliverTx) abci.ResponseDeliverTx
DeliverTx genesis.TxHandler
Config client.TxConfig
}

Expand Down

0 comments on commit d31f296

Please sign in to comment.