feat!: Define Genesis state transition (#15999)
This commit is contained in:
parent
672b1f9e15
commit
d31f2964b0
@ -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
|
||||
|
||||
|
||||
22
baseapp/genesis.go
Normal file
22
baseapp/genesis.go
Normal file
@ -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
|
||||
}
|
||||
@ -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
core/genesis/txhandler.go
Normal file
6
core/genesis/txhandler.go
Normal file
@ -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
|
||||
}
|
||||
@ -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
|
||||
```
|
||||
|
||||
@ -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"
|
||||
@ -62,7 +61,7 @@ func init() {
|
||||
ProvideKVStoreKey,
|
||||
ProvideTransientStoreKey,
|
||||
ProvideMemoryStoreKey,
|
||||
ProvideDeliverTx,
|
||||
ProvideGenesisTxHandler,
|
||||
ProvideKVStoreService,
|
||||
ProvideMemoryStoreService,
|
||||
ProvideTransientStoreService,
|
||||
@ -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 {
|
||||
|
||||
@ -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)),
|
||||
|
||||
@ -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,
|
||||
)
|
||||
|
||||
|
||||
@ -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 => ../..
|
||||
)
|
||||
|
||||
@ -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=
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package genutil
|
||||
|
||||
import (
|
||||
"cosmossdk.io/core/genesis"
|
||||
abci "github.com/cometbft/cometbft/abci/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
@ -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 {
|
||||
|
||||
@ -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"
|
||||
@ -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 {
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -2,15 +2,16 @@ 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"
|
||||
|
||||
@ -18,7 +19,6 @@ import (
|
||||
"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"
|
||||
@ -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
|
||||
}{
|
||||
{
|
||||
@ -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,
|
||||
},
|
||||
{
|
||||
@ -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,
|
||||
},
|
||||
}
|
||||
@ -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,
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@ import (
|
||||
|
||||
modulev1 "cosmossdk.io/api/cosmos/genutil/module/v1"
|
||||
"cosmossdk.io/core/appmodule"
|
||||
"cosmossdk.io/core/genesis"
|
||||
|
||||
"cosmossdk.io/depinject"
|
||||
|
||||
@ -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{
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user