[wip] refactor laconic app cli
- use runtime, server v2 - move generic tx decoder to utils
This commit is contained in:
parent
c7e0753f08
commit
dd39fb2365
146
app/app.go
146
app/app.go
@ -2,35 +2,36 @@ package app
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
_ "embed"
|
_ "embed"
|
||||||
"io"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
corestore "cosmossdk.io/core/store"
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
|
"cosmossdk.io/core/transaction"
|
||||||
"cosmossdk.io/depinject"
|
"cosmossdk.io/depinject"
|
||||||
"cosmossdk.io/depinject/appconfig"
|
"cosmossdk.io/depinject/appconfig"
|
||||||
"cosmossdk.io/log"
|
"cosmossdk.io/log"
|
||||||
storetypes "cosmossdk.io/store/types"
|
"cosmossdk.io/runtime/v2"
|
||||||
|
server "cosmossdk.io/server/v2"
|
||||||
|
serverstore "cosmossdk.io/server/v2/store"
|
||||||
|
"cosmossdk.io/store/v2"
|
||||||
|
"cosmossdk.io/store/v2/root"
|
||||||
|
// crypto/keys/ed25519/keys.pb.go:123
|
||||||
|
coreserver "cosmossdk.io/core/server"
|
||||||
bankkeeper "cosmossdk.io/x/bank/keeper"
|
bankkeeper "cosmossdk.io/x/bank/keeper"
|
||||||
consensuskeeper "cosmossdk.io/x/consensus/keeper"
|
consensuskeeper "cosmossdk.io/x/consensus/keeper"
|
||||||
distrkeeper "cosmossdk.io/x/distribution/keeper"
|
distrkeeper "cosmossdk.io/x/distribution/keeper"
|
||||||
govkeeper "cosmossdk.io/x/gov/keeper"
|
govkeeper "cosmossdk.io/x/gov/keeper"
|
||||||
slashingkeeper "cosmossdk.io/x/slashing/keeper"
|
slashingkeeper "cosmossdk.io/x/slashing/keeper"
|
||||||
stakingkeeper "cosmossdk.io/x/staking/keeper"
|
stakingkeeper "cosmossdk.io/x/staking/keeper"
|
||||||
|
"git.vdb.to/cerc-io/laconicd/utils"
|
||||||
auctionkeeper "git.vdb.to/cerc-io/laconicd/x/auction/keeper"
|
auctionkeeper "git.vdb.to/cerc-io/laconicd/x/auction/keeper"
|
||||||
bondkeeper "git.vdb.to/cerc-io/laconicd/x/bond/keeper"
|
bondkeeper "git.vdb.to/cerc-io/laconicd/x/bond/keeper"
|
||||||
onboardingkeeper "git.vdb.to/cerc-io/laconicd/x/onboarding/keeper"
|
onboardingkeeper "git.vdb.to/cerc-io/laconicd/x/onboarding/keeper"
|
||||||
registrykeeper "git.vdb.to/cerc-io/laconicd/x/registry/keeper"
|
registrykeeper "git.vdb.to/cerc-io/laconicd/x/registry/keeper"
|
||||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
|
||||||
"github.com/cosmos/cosmos-sdk/client"
|
"github.com/cosmos/cosmos-sdk/client"
|
||||||
"github.com/cosmos/cosmos-sdk/codec"
|
"github.com/cosmos/cosmos-sdk/codec"
|
||||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||||
"github.com/cosmos/cosmos-sdk/runtime"
|
|
||||||
"github.com/cosmos/cosmos-sdk/server"
|
|
||||||
"github.com/cosmos/cosmos-sdk/server/api"
|
|
||||||
"github.com/cosmos/cosmos-sdk/server/config"
|
|
||||||
servertypes "github.com/cosmos/cosmos-sdk/server/types"
|
|
||||||
"github.com/cosmos/cosmos-sdk/types/module"
|
"github.com/cosmos/cosmos-sdk/types/module"
|
||||||
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
|
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
|
||||||
|
|
||||||
@ -48,6 +49,7 @@ import (
|
|||||||
_ "git.vdb.to/cerc-io/laconicd/x/bond/module" // import for side-effects
|
_ "git.vdb.to/cerc-io/laconicd/x/bond/module" // import for side-effects
|
||||||
_ "git.vdb.to/cerc-io/laconicd/x/onboarding/module" // import for side-effects
|
_ "git.vdb.to/cerc-io/laconicd/x/onboarding/module" // import for side-effects
|
||||||
_ "git.vdb.to/cerc-io/laconicd/x/registry/module" // import for side-effects
|
_ "git.vdb.to/cerc-io/laconicd/x/registry/module" // import for side-effects
|
||||||
|
_ "github.com/cosmos/cosmos-sdk/crypto/codec" // import for side-effects
|
||||||
_ "github.com/cosmos/cosmos-sdk/x/auth" // import for side-effects
|
_ "github.com/cosmos/cosmos-sdk/x/auth" // import for side-effects
|
||||||
_ "github.com/cosmos/cosmos-sdk/x/auth/tx/config" // import for side-effects
|
_ "github.com/cosmos/cosmos-sdk/x/auth/tx/config" // import for side-effects
|
||||||
)
|
)
|
||||||
@ -59,19 +61,19 @@ var DefaultNodeHome string
|
|||||||
var AppConfigYAML []byte
|
var AppConfigYAML []byte
|
||||||
|
|
||||||
var (
|
var (
|
||||||
_ runtime.AppI = (*LaconicApp)(nil)
|
_ server.AppI[transaction.Tx] = (*LaconicApp)(nil)
|
||||||
_ servertypes.Application = (*LaconicApp)(nil)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// LaconicApp extends an ABCI application, but with most of its parameters exported.
|
// LaconicApp extends an ABCI application, but with most of its parameters exported.
|
||||||
// They are exported for convenience in creating helper functions, as object
|
// They are exported for convenience in creating helper functions, as object
|
||||||
// capabilities aren't needed for testing.
|
// capabilities aren't needed for testing.
|
||||||
type LaconicApp struct {
|
type LaconicApp struct {
|
||||||
*runtime.App
|
*runtime.App[transaction.Tx]
|
||||||
// legacyAmino *codec.LegacyAmino
|
// legacyAmino *codec.LegacyAmino
|
||||||
appCodec codec.Codec
|
appCodec codec.Codec
|
||||||
txConfig client.TxConfig
|
txConfig client.TxConfig
|
||||||
interfaceRegistry codectypes.InterfaceRegistry
|
interfaceRegistry codectypes.InterfaceRegistry
|
||||||
|
store store.RootStore
|
||||||
|
|
||||||
// keepers
|
// keepers
|
||||||
AccountKeeper authkeeper.AccountKeeper
|
AccountKeeper authkeeper.AccountKeeper
|
||||||
@ -92,6 +94,11 @@ type LaconicApp struct {
|
|||||||
sm *module.SimulationManager
|
sm *module.SimulationManager
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type (
|
||||||
|
AppTx = transaction.Tx
|
||||||
|
AppBuilder = runtime.AppBuilder[AppTx]
|
||||||
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
userHomeDir, err := os.UserHomeDir()
|
userHomeDir, err := os.UserHomeDir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -105,32 +112,53 @@ func init() {
|
|||||||
func AppConfig() depinject.Config {
|
func AppConfig() depinject.Config {
|
||||||
return depinject.Configs(
|
return depinject.Configs(
|
||||||
appconfig.LoadYAML(AppConfigYAML),
|
appconfig.LoadYAML(AppConfigYAML),
|
||||||
|
runtime.DefaultServiceBindings(),
|
||||||
|
depinject.Supply(
|
||||||
|
utils.NewAddressCodec,
|
||||||
|
utils.NewValAddressCodec,
|
||||||
|
utils.NewConsAddressCodec,
|
||||||
|
),
|
||||||
|
depinject.Provide(
|
||||||
|
codec.ProvideInterfaceRegistry,
|
||||||
|
codec.ProvideAddressCodec,
|
||||||
|
codec.ProvideProtoCodec,
|
||||||
|
codec.ProvideLegacyAmino,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewLaconicApp returns a reference to an initialized LaconicApp.
|
// NewLaconicApp returns a reference to an initialized LaconicApp.
|
||||||
func NewLaconicApp(
|
func NewLaconicApp(
|
||||||
logger log.Logger,
|
logger log.Logger,
|
||||||
db corestore.KVStoreWithBatch,
|
// db corestore.KVStoreWithBatch,
|
||||||
traceStore io.Writer,
|
// traceStore io.Writer,
|
||||||
|
viper *viper.Viper,
|
||||||
loadLatest bool,
|
loadLatest bool,
|
||||||
appOpts servertypes.AppOptions,
|
// appOpts server.AppOptions, // TODO migrate?
|
||||||
baseAppOptions ...func(*baseapp.BaseApp),
|
appBuilderOpts ...runtime.AppBuilderOption[AppTx],
|
||||||
) (*LaconicApp, error) {
|
) (*LaconicApp, error) {
|
||||||
var (
|
var (
|
||||||
app = &LaconicApp{}
|
app LaconicApp
|
||||||
appBuilder *runtime.AppBuilder
|
appBuilder *AppBuilder
|
||||||
|
storeBuilder root.Builder
|
||||||
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
if err := depinject.Inject(
|
logfile := "/Users/roy/vulcanize/dump/laconic-debug/app_depinject.log"
|
||||||
|
if err := depinject.InjectDebug(
|
||||||
|
// depinject.Debug(),
|
||||||
|
depinject.DebugOptions(
|
||||||
|
depinject.FileLogger(logfile),
|
||||||
|
),
|
||||||
depinject.Configs(
|
depinject.Configs(
|
||||||
AppConfig(),
|
AppConfig(),
|
||||||
depinject.Supply(
|
depinject.Supply(
|
||||||
logger,
|
logger,
|
||||||
appOpts,
|
// appOpts,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
&appBuilder,
|
&appBuilder,
|
||||||
|
&storeBuilder,
|
||||||
&app.appCodec,
|
&app.appCodec,
|
||||||
// &app.legacyAmino,
|
// &app.legacyAmino,
|
||||||
&app.txConfig,
|
&app.txConfig,
|
||||||
@ -150,27 +178,44 @@ func NewLaconicApp(
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
app.App = appBuilder.Build(db, traceStore, baseAppOptions...)
|
// store/v2 follows a slightly more eager config life cycle than server components
|
||||||
|
storeConfig, err := serverstore.UnmarshalConfig(viper.AllSettings())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
app.store, err = storeBuilder.Build(logger, storeConfig)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
// register streaming services
|
// TODO: db config correct?
|
||||||
if err := app.RegisterStreamingServices(appOpts, app.kvStoreKeys()); err != nil {
|
// TODO: store tracer injection?
|
||||||
|
if app.App, err = appBuilder.Build(appBuilderOpts...); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
// // register streaming services
|
||||||
|
// if err := app.RegisterStreamingServices(appOpts, app.kvStoreKeys()); err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
|
||||||
/**** Module Options ****/
|
/**** Module Options ****/
|
||||||
|
|
||||||
// create the simulation manager and define the order of the modules for deterministic simulations
|
// create the simulation manager and define the order of the modules for deterministic simulations
|
||||||
// NOTE: this is not required apps that don't use the simulator for fuzz testing transactions
|
// NOTE: this is not required for apps that don't use the simulator for fuzz testing transactions
|
||||||
app.sm = module.NewSimulationManagerFromAppModules(
|
app.sm = module.NewSimulationManagerFromAppModules(
|
||||||
app.ModuleManager.Modules,
|
app.ModuleManager().Modules(),
|
||||||
make(map[string]module.AppModuleSimulation, 0))
|
make(map[string]module.AppModuleSimulation, 0))
|
||||||
app.sm.RegisterStoreDecoders()
|
app.sm.RegisterStoreDecoders()
|
||||||
|
|
||||||
if err := app.Load(loadLatest); err != nil {
|
// TODO: remove
|
||||||
return nil, err
|
if loadLatest {
|
||||||
|
if err = app.LoadLatest(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return &app, nil
|
||||||
return app, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// // LegacyAmino returns LaconicApp's amino codec.
|
// // LegacyAmino returns LaconicApp's amino codec.
|
||||||
@ -178,38 +223,27 @@ func NewLaconicApp(
|
|||||||
// return app.legacyAmino
|
// return app.legacyAmino
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
func (app *LaconicApp) InterfaceRegistry() coreserver.InterfaceRegistry {
|
||||||
|
return app.interfaceRegistry
|
||||||
|
}
|
||||||
|
|
||||||
// GetKey returns the KVStoreKey for the provided store key.
|
// GetKey returns the KVStoreKey for the provided store key.
|
||||||
func (app *LaconicApp) GetKey(storeKey string) *storetypes.KVStoreKey {
|
func (app *LaconicApp) GetStore() store.RootStore {
|
||||||
sk := app.UnsafeFindStoreKey(storeKey)
|
return app.store
|
||||||
kvStoreKey, ok := sk.(*storetypes.KVStoreKey)
|
|
||||||
if !ok {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return kvStoreKey
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *LaconicApp) kvStoreKeys() map[string]*storetypes.KVStoreKey {
|
// func (app *LaconicApp) kvStoreKeys() map[string]*store.KVStoreKey {
|
||||||
keys := make(map[string]*storetypes.KVStoreKey)
|
// keys := make(map[string]*store.KVStoreKey)
|
||||||
for _, k := range app.GetStoreKeys() {
|
// for _, k := range app.GetStoreKeys() {
|
||||||
if kv, ok := k.(*storetypes.KVStoreKey); ok {
|
// if kv, ok := k.(*storetypes.KVStoreKey); ok {
|
||||||
keys[kv.Name()] = kv
|
// keys[kv.Name()] = kv
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
return keys
|
// return keys
|
||||||
}
|
// }
|
||||||
|
|
||||||
// SimulationManager implements the SimulationApp interface
|
// SimulationManager implements the SimulationApp interface
|
||||||
func (app *LaconicApp) SimulationManager() *module.SimulationManager {
|
func (app *LaconicApp) SimulationManager() *module.SimulationManager {
|
||||||
return app.sm
|
return app.sm
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterAPIRoutes registers all application module routes with the provided
|
|
||||||
// API server.
|
|
||||||
func (app *LaconicApp) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig) {
|
|
||||||
app.App.RegisterAPIRoutes(apiSvr, apiConfig)
|
|
||||||
// register swagger API in app.go so that other applications can override easily
|
|
||||||
if err := server.RegisterSwaggerAPI(apiSvr.ClientCtx, apiSvr.Router, apiConfig.Swagger); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -25,6 +25,10 @@ modules:
|
|||||||
- bond
|
- bond
|
||||||
- registry
|
- registry
|
||||||
- onboarding
|
- onboarding
|
||||||
|
gas_config:
|
||||||
|
validate_tx_gas_limit: 100000,
|
||||||
|
query_gas_limit: 100000,
|
||||||
|
simulation_gas_limit: 100000,
|
||||||
override_store_keys:
|
override_store_keys:
|
||||||
- module_name: auth
|
- module_name: auth
|
||||||
kv_store_key: acc
|
kv_store_key: acc
|
||||||
|
270
app/export.go
270
app/export.go
@ -1,264 +1,48 @@
|
|||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
|
|
||||||
"cosmossdk.io/collections"
|
"cosmossdk.io/runtime/v2/services"
|
||||||
storetypes "cosmossdk.io/store/types"
|
|
||||||
slashingtypes "cosmossdk.io/x/slashing/types"
|
|
||||||
"cosmossdk.io/x/staking"
|
"cosmossdk.io/x/staking"
|
||||||
stakingtypes "cosmossdk.io/x/staking/types"
|
|
||||||
tmproto "github.com/cometbft/cometbft/api/cometbft/types/v1"
|
|
||||||
cmttypes "github.com/cometbft/cometbft/types"
|
|
||||||
servertypes "github.com/cosmos/cosmos-sdk/server/types"
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
||||||
|
|
||||||
"git.vdb.to/cerc-io/laconicd/utils"
|
v2 "github.com/cosmos/cosmos-sdk/x/genutil/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ExportAppStateAndValidators exports the state of the application for a genesis file.
|
// ExportAppStateAndValidators exports the state of the application for a genesis
|
||||||
|
// file.
|
||||||
|
// This is a demonstation of how to export a genesis file. Export may need extended at
|
||||||
|
// the user discretion for cleaning the genesis state at the end provided with jailAllowedAddrs
|
||||||
func (app *LaconicApp) ExportAppStateAndValidators(
|
func (app *LaconicApp) ExportAppStateAndValidators(
|
||||||
forZeroHeight bool,
|
|
||||||
jailAllowedAddrs []string,
|
jailAllowedAddrs []string,
|
||||||
modulesToExport []string,
|
) (v2.ExportedApp, error) {
|
||||||
) (servertypes.ExportedApp, error) {
|
ctx := context.Background()
|
||||||
// as if they could withdraw from the start of the next block
|
var exportedApp v2.ExportedApp
|
||||||
ctx := app.NewContextLegacy(true, tmproto.Header{Height: app.LastBlockHeight()})
|
|
||||||
|
|
||||||
// We export at last height + 1, because that's the height at which
|
latestHeight, err := app.LoadLatestHeight()
|
||||||
// CometBFT will start InitChain.
|
|
||||||
height := app.LastBlockHeight() + 1
|
|
||||||
if forZeroHeight {
|
|
||||||
height = 0
|
|
||||||
app.prepForZeroHeightGenesis(ctx, jailAllowedAddrs)
|
|
||||||
}
|
|
||||||
|
|
||||||
genState, err := app.ModuleManager.ExportGenesis(ctx)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return servertypes.ExportedApp{}, fmt.Errorf("failed to export genesis state: %w", err)
|
return exportedApp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
appState, err := json.MarshalIndent(genState, "", " ")
|
genesis, err := app.ExportGenesis(ctx, latestHeight)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return servertypes.ExportedApp{}, err
|
return exportedApp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
validators, err := staking.WriteValidators(ctx, app.StakingKeeper)
|
readerMap, err := app.GetStore().StateAt(latestHeight)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return servertypes.ExportedApp{}, err
|
return exportedApp, err
|
||||||
|
}
|
||||||
|
genesisCtx := services.NewGenesisContext(readerMap)
|
||||||
|
err = genesisCtx.Read(ctx, func(ctx context.Context) error {
|
||||||
|
exportedApp.Validators, err = staking.WriteValidators(ctx, app.StakingKeeper)
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return exportedApp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
cmtvalidators := make([]cmttypes.GenesisValidator, len(validators))
|
exportedApp.AppState = genesis
|
||||||
for i := range validators {
|
exportedApp.Height = int64(latestHeight)
|
||||||
cmtvalidators[i] = cmttypes.GenesisValidator{
|
return exportedApp, nil
|
||||||
Address: validators[i].Address.Bytes(),
|
|
||||||
PubKey: validators[i].PubKey,
|
|
||||||
Power: validators[i].Power,
|
|
||||||
Name: validators[i].Name,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return servertypes.ExportedApp{
|
|
||||||
AppState: appState,
|
|
||||||
Validators: cmtvalidators,
|
|
||||||
Height: height,
|
|
||||||
ConsensusParams: app.BaseApp.GetConsensusParams(ctx),
|
|
||||||
}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// prepare for fresh start at zero height
|
|
||||||
// NOTE zero height genesis is a temporary feature, which will be deprecated in favor of export at a block height
|
|
||||||
func (app *LaconicApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []string) {
|
|
||||||
applyAllowedAddrs := false
|
|
||||||
|
|
||||||
// check if there is a allowed address list
|
|
||||||
if len(jailAllowedAddrs) > 0 {
|
|
||||||
applyAllowedAddrs = true
|
|
||||||
}
|
|
||||||
|
|
||||||
addrCodec := utils.NewAddressCodec()
|
|
||||||
valAddrCodec := utils.NewValAddressCodec()
|
|
||||||
|
|
||||||
allowedAddrsMap := make(map[string]bool)
|
|
||||||
for _, addr := range jailAllowedAddrs {
|
|
||||||
_, err := valAddrCodec.StringToBytes(addr)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
allowedAddrsMap[addr] = true
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Handle fee distribution state. */
|
|
||||||
|
|
||||||
// withdraw all validator commission
|
|
||||||
_ = app.StakingKeeper.IterateValidators(ctx, func(_ int64, val sdk.ValidatorI) (stop bool) {
|
|
||||||
valBz, err := app.StakingKeeper.ValidatorAddressCodec().StringToBytes(val.GetOperator())
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, _ = app.DistrKeeper.WithdrawValidatorCommission(ctx, valBz)
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
|
|
||||||
// withdraw all delegator rewards
|
|
||||||
dels, err := app.StakingKeeper.GetAllDelegations(ctx)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, delegation := range dels {
|
|
||||||
valAddr, err := valAddrCodec.StringToBytes(delegation.ValidatorAddress)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
delAddr, err := addrCodec.StringToBytes(delegation.DelegatorAddress)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, _ = app.DistrKeeper.WithdrawDelegationRewards(ctx, delAddr, valAddr)
|
|
||||||
}
|
|
||||||
|
|
||||||
// clear validator slash events
|
|
||||||
app.DistrKeeper.ValidatorSlashEvents.Clear(ctx, nil)
|
|
||||||
|
|
||||||
// clear validator historical rewards
|
|
||||||
app.DistrKeeper.ValidatorHistoricalRewards.Clear(ctx, nil)
|
|
||||||
|
|
||||||
// set context height to zero
|
|
||||||
height := ctx.BlockHeight()
|
|
||||||
ctx = ctx.WithBlockHeight(0)
|
|
||||||
|
|
||||||
// reinitialize all validators
|
|
||||||
_ = app.StakingKeeper.IterateValidators(ctx, func(_ int64, val sdk.ValidatorI) (stop bool) {
|
|
||||||
valBz, err := app.StakingKeeper.ValidatorAddressCodec().StringToBytes(val.GetOperator())
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// donate any unwithdrawn outstanding reward fraction tokens to the community pool
|
|
||||||
scraps, err := app.DistrKeeper.GetValidatorOutstandingRewardsCoins(ctx, valBz)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
feePool, err := app.DistrKeeper.FeePool.Get(ctx)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
feePool.CommunityPool = feePool.CommunityPool.Add(scraps...)
|
|
||||||
if err := app.DistrKeeper.FeePool.Set(ctx, feePool); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := app.DistrKeeper.Hooks().AfterValidatorCreated(ctx, valBz); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
|
|
||||||
// reinitialize all delegations
|
|
||||||
for _, del := range dels {
|
|
||||||
valAddr, err := valAddrCodec.StringToBytes(del.ValidatorAddress)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
delAddr, err := addrCodec.StringToBytes(del.DelegatorAddress)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := app.DistrKeeper.Hooks().BeforeDelegationCreated(ctx, delAddr, valAddr); err != nil {
|
|
||||||
// never called as BeforeDelegationCreated always returns nil
|
|
||||||
panic(fmt.Errorf("error while incrementing period: %w", err))
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := app.DistrKeeper.Hooks().AfterDelegationModified(ctx, delAddr, valAddr); err != nil {
|
|
||||||
// never called as AfterDelegationModified always returns nil
|
|
||||||
panic(fmt.Errorf("error while creating a new delegation period record: %w", err))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// reset context height
|
|
||||||
ctx = ctx.WithBlockHeight(height)
|
|
||||||
|
|
||||||
/* Handle staking state. */
|
|
||||||
|
|
||||||
// iterate through redelegations, reset creation height
|
|
||||||
_ = app.StakingKeeper.IterateRedelegations(ctx, func(_ int64, red stakingtypes.Redelegation) (stop bool) {
|
|
||||||
for i := range red.Entries {
|
|
||||||
red.Entries[i].CreationHeight = 0
|
|
||||||
}
|
|
||||||
_ = app.StakingKeeper.SetRedelegation(ctx, red)
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
|
|
||||||
// iterate through unbonding delegations, reset creation height
|
|
||||||
_ = app.StakingKeeper.UnbondingDelegations.Walk(
|
|
||||||
ctx, nil,
|
|
||||||
func(_ collections.Pair[[]byte, []byte], ubd stakingtypes.UnbondingDelegation) (stop bool, err error) {
|
|
||||||
for i := range ubd.Entries {
|
|
||||||
ubd.Entries[i].CreationHeight = 0
|
|
||||||
}
|
|
||||||
_ = app.StakingKeeper.SetUnbondingDelegation(ctx, ubd)
|
|
||||||
return false, nil
|
|
||||||
})
|
|
||||||
|
|
||||||
// Iterate through validators by power descending, reset bond heights, and
|
|
||||||
// update bond intra-tx counters.
|
|
||||||
store := ctx.KVStore(app.GetKey(stakingtypes.StoreKey))
|
|
||||||
iter := storetypes.KVStoreReversePrefixIterator(store, stakingtypes.ValidatorsKey)
|
|
||||||
counter := int16(0)
|
|
||||||
|
|
||||||
for ; iter.Valid(); iter.Next() {
|
|
||||||
addr := sdk.ValAddress(stakingtypes.AddressFromValidatorsKey(iter.Key()))
|
|
||||||
validator, err := app.StakingKeeper.GetValidator(ctx, addr)
|
|
||||||
if errors.Is(err, stakingtypes.ErrNoValidatorFound) {
|
|
||||||
panic("expected validator, not found")
|
|
||||||
} else if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
validator.UnbondingHeight = 0
|
|
||||||
if applyAllowedAddrs && !allowedAddrsMap[addr.String()] {
|
|
||||||
validator.Jailed = true
|
|
||||||
}
|
|
||||||
|
|
||||||
_ = app.StakingKeeper.SetValidator(ctx, validator)
|
|
||||||
counter++
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := iter.Close(); err != nil {
|
|
||||||
app.Logger().Error("error while closing the key-value store reverse prefix iterator: ", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Handle slashing state. */
|
|
||||||
|
|
||||||
// reset start height on signing infos
|
|
||||||
err = app.SlashingKeeper.ValidatorSigningInfo.Walk(
|
|
||||||
ctx, nil,
|
|
||||||
func(addr sdk.ConsAddress, info slashingtypes.ValidatorSigningInfo) (stop bool, err error) {
|
|
||||||
info.StartHeight = 0
|
|
||||||
err = app.SlashingKeeper.ValidatorSigningInfo.Set(ctx, addr, info)
|
|
||||||
if err != nil {
|
|
||||||
return true, err
|
|
||||||
}
|
|
||||||
return false, nil
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -2,33 +2,35 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"fmt"
|
||||||
"io"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"golang.org/x/sync/errgroup"
|
|
||||||
|
|
||||||
corestore "cosmossdk.io/core/store"
|
corectx "cosmossdk.io/core/context"
|
||||||
"cosmossdk.io/log"
|
"cosmossdk.io/log"
|
||||||
|
serverv2 "cosmossdk.io/server/v2"
|
||||||
|
"cosmossdk.io/server/v2/api/grpc"
|
||||||
|
"cosmossdk.io/server/v2/api/rest"
|
||||||
|
"cosmossdk.io/server/v2/api/telemetry"
|
||||||
|
"cosmossdk.io/server/v2/cometbft"
|
||||||
|
serverstore "cosmossdk.io/server/v2/store"
|
||||||
confixcmd "cosmossdk.io/tools/confix/cmd"
|
confixcmd "cosmossdk.io/tools/confix/cmd"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/client"
|
"github.com/cosmos/cosmos-sdk/client"
|
||||||
"github.com/cosmos/cosmos-sdk/client/debug"
|
"github.com/cosmos/cosmos-sdk/client/debug"
|
||||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
|
||||||
"github.com/cosmos/cosmos-sdk/client/keys"
|
"github.com/cosmos/cosmos-sdk/client/keys"
|
||||||
"github.com/cosmos/cosmos-sdk/client/pruning"
|
|
||||||
"github.com/cosmos/cosmos-sdk/client/snapshot"
|
|
||||||
"github.com/cosmos/cosmos-sdk/server"
|
"github.com/cosmos/cosmos-sdk/server"
|
||||||
servertypes "github.com/cosmos/cosmos-sdk/server/types"
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
|
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
|
||||||
"github.com/cosmos/cosmos-sdk/x/genutil"
|
"github.com/cosmos/cosmos-sdk/x/genutil"
|
||||||
genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli"
|
genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli"
|
||||||
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
|
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
|
||||||
|
genutilv2 "github.com/cosmos/cosmos-sdk/x/genutil/v2"
|
||||||
|
genutilv2cli "github.com/cosmos/cosmos-sdk/x/genutil/v2/cli"
|
||||||
|
|
||||||
"git.vdb.to/cerc-io/laconicd/app"
|
"git.vdb.to/cerc-io/laconicd/app"
|
||||||
"git.vdb.to/cerc-io/laconicd/gql"
|
"git.vdb.to/cerc-io/laconicd/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func initRootCmd(rootCmd *cobra.Command, txConfig client.TxConfig, moduleManager moduleManager) {
|
func initRootCmd(rootCmd *cobra.Command, txConfig client.TxConfig, moduleManager moduleManager) {
|
||||||
@ -39,30 +41,47 @@ func initRootCmd(rootCmd *cobra.Command, txConfig client.TxConfig, moduleManager
|
|||||||
genutilcli.InitCmd(moduleManager),
|
genutilcli.InitCmd(moduleManager),
|
||||||
debug.Cmd(),
|
debug.Cmd(),
|
||||||
confixcmd.ConfigCommand(),
|
confixcmd.ConfigCommand(),
|
||||||
pruning.Cmd(newApp),
|
// TODO
|
||||||
snapshot.Cmd(newApp),
|
// pruning.Cmd(newApp),
|
||||||
|
// snapshot.Cmd(newApp),
|
||||||
)
|
)
|
||||||
|
|
||||||
server.AddCommands(rootCmd, newApp, server.StartCmdOptions[*app.LaconicApp]{
|
if err := serverv2.AddCommands(
|
||||||
PostSetup: func(
|
rootCmd,
|
||||||
_ *app.LaconicApp,
|
newApp,
|
||||||
svrCtx *server.Context,
|
initServerConfig(),
|
||||||
clientCtx client.Context,
|
cometbft.New(
|
||||||
ctx context.Context,
|
utils.GenericTxDecoder[app.AppTx]{txConfig},
|
||||||
g *errgroup.Group,
|
initCometOptions[app.AppTx](),
|
||||||
) error {
|
initCometConfig(),
|
||||||
g.Go(func() error {
|
),
|
||||||
return gql.Server(ctx, clientCtx, svrCtx.Logger.With("module", "gql-server"))
|
grpc.New[app.AppTx](),
|
||||||
})
|
serverstore.New[app.AppTx](),
|
||||||
return nil
|
telemetry.New[app.AppTx](),
|
||||||
},
|
rest.New[app.AppTx](),
|
||||||
},
|
|
||||||
)
|
// serverv2.StartCmdOptions[*app.LaconicApp]{
|
||||||
|
// PostSetup: func(
|
||||||
|
// _ *app.LaconicApp,
|
||||||
|
// svrCtx *server.Context,
|
||||||
|
// clientCtx client.Context,
|
||||||
|
// ctx context.Context,
|
||||||
|
// g *errgroup.Group,
|
||||||
|
// ) error {
|
||||||
|
// g.Go(func() error {
|
||||||
|
// return gql.Server(ctx, clientCtx, svrCtx.Logger.With("module", "gql-server"))
|
||||||
|
// })
|
||||||
|
// return nil
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
// add keybase, auxiliary RPC, query, genesis, and tx child commands
|
// add keybase, auxiliary RPC, query, genesis, and tx child commands
|
||||||
rootCmd.AddCommand(
|
rootCmd.AddCommand(
|
||||||
server.StatusCommand(),
|
server.StatusCommand(),
|
||||||
genutilcli.Commands(
|
genutilv2cli.Commands(
|
||||||
moduleManager.Modules()[genutiltypes.ModuleName].(genutil.AppModule),
|
moduleManager.Modules()[genutiltypes.ModuleName].(genutil.AppModule),
|
||||||
moduleManager,
|
moduleManager,
|
||||||
appExport),
|
appExport),
|
||||||
@ -117,69 +136,118 @@ func txCommand() *cobra.Command {
|
|||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
// newApp is an appCreator
|
func newApp(logger log.Logger, viper *viper.Viper) serverv2.AppI[app.AppTx] {
|
||||||
func newApp(
|
viper.Set(serverv2.FlagHome, app.DefaultNodeHome)
|
||||||
logger log.Logger,
|
lacapp, err := app.NewLaconicApp(logger, viper, true)
|
||||||
db corestore.KVStoreWithBatch,
|
|
||||||
traceStore io.Writer,
|
|
||||||
appOpts servertypes.AppOptions,
|
|
||||||
) *app.LaconicApp {
|
|
||||||
var _ = db
|
|
||||||
baseappOptions := server.DefaultBaseappOptions(appOpts)
|
|
||||||
app, err := app.NewLaconicApp(logger, db, traceStore, true, appOpts, baseappOptions...)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
return app
|
return serverv2.AppI[app.AppTx](lacapp)
|
||||||
}
|
}
|
||||||
|
|
||||||
// appExport creates a new app (optionally at a given height) and exports state.
|
// // newApp is an appCreator
|
||||||
|
// func newApp(
|
||||||
|
// logger log.Logger,
|
||||||
|
// db corestore.KVStoreWithBatch,
|
||||||
|
// traceStore io.Writer,
|
||||||
|
// appOpts servertypes.AppOptions,
|
||||||
|
// ) *app.LaconicApp {
|
||||||
|
// var _ = db
|
||||||
|
// // baseappOptions := server.DefaultBaseappOptions(appOpts)
|
||||||
|
// app, err := app.NewLaconicApp(logger, viper, true)
|
||||||
|
// if err != nil {
|
||||||
|
// panic(err)
|
||||||
|
// }
|
||||||
|
// return app
|
||||||
|
// }
|
||||||
|
|
||||||
|
// appExport creates a new simapp (optionally at a given height) and exports state.
|
||||||
func appExport(
|
func appExport(
|
||||||
logger log.Logger,
|
ctx context.Context,
|
||||||
db corestore.KVStoreWithBatch,
|
|
||||||
traceStore io.Writer,
|
|
||||||
height int64,
|
height int64,
|
||||||
forZeroHeight bool,
|
|
||||||
jailAllowedAddrs []string,
|
jailAllowedAddrs []string,
|
||||||
appOpts servertypes.AppOptions,
|
) (genutilv2.ExportedApp, error) {
|
||||||
modulesToExport []string,
|
value := ctx.Value(corectx.ViperContextKey)
|
||||||
) (servertypes.ExportedApp, error) {
|
viper, ok := value.(*viper.Viper)
|
||||||
var (
|
|
||||||
laconicApp *app.LaconicApp
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
|
|
||||||
// this check is necessary as we use the flag in x/upgrade.
|
|
||||||
// we can exit more gracefully by checking the flag here.
|
|
||||||
homePath, ok := appOpts.Get(flags.FlagHome).(string)
|
|
||||||
if !ok || homePath == "" {
|
|
||||||
return servertypes.ExportedApp{}, errors.New("application home not set")
|
|
||||||
}
|
|
||||||
|
|
||||||
viperAppOpts, ok := appOpts.(*viper.Viper)
|
|
||||||
if !ok {
|
if !ok {
|
||||||
return servertypes.ExportedApp{}, errors.New("appOpts is not viper.Viper")
|
return genutilv2.ExportedApp{},
|
||||||
|
fmt.Errorf("incorrect viper type %T: expected *viper.Viper in context", value)
|
||||||
|
}
|
||||||
|
value = ctx.Value(corectx.LoggerContextKey)
|
||||||
|
logger, ok := value.(log.Logger)
|
||||||
|
if !ok {
|
||||||
|
return genutilv2.ExportedApp{},
|
||||||
|
fmt.Errorf("incorrect logger type %T: expected log.Logger in context", value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// overwrite the FlagInvCheckPeriod
|
// overwrite the FlagInvCheckPeriod
|
||||||
viperAppOpts.Set(server.FlagInvCheckPeriod, 1)
|
viper.Set(server.FlagInvCheckPeriod, 1)
|
||||||
appOpts = viperAppOpts
|
viper.Set(serverv2.FlagHome, app.DefaultNodeHome)
|
||||||
|
|
||||||
|
lacapp, err := app.NewLaconicApp(logger, viper, false)
|
||||||
|
if err != nil {
|
||||||
|
return genutilv2.ExportedApp{}, err
|
||||||
|
}
|
||||||
if height != -1 {
|
if height != -1 {
|
||||||
laconicApp, err = app.NewLaconicApp(logger, db, traceStore, false, appOpts)
|
err = lacapp.LoadHeight(uint64(height))
|
||||||
if err != nil {
|
|
||||||
return servertypes.ExportedApp{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := laconicApp.LoadHeight(height); err != nil {
|
|
||||||
return servertypes.ExportedApp{}, err
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
laconicApp, err = app.NewLaconicApp(logger, db, traceStore, true, appOpts)
|
err = lacapp.LoadLatest()
|
||||||
if err != nil {
|
}
|
||||||
return servertypes.ExportedApp{}, err
|
if err != nil {
|
||||||
}
|
return genutilv2.ExportedApp{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return laconicApp.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs, modulesToExport)
|
return lacapp.ExportAppStateAndValidators(jailAllowedAddrs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// // appExport creates a new app (optionally at a given height) and exports state.
|
||||||
|
// func appExport(
|
||||||
|
// logger log.Logger,
|
||||||
|
// db corestore.KVStoreWithBatch,
|
||||||
|
// traceStore io.Writer,
|
||||||
|
// height int64,
|
||||||
|
// forZeroHeight bool,
|
||||||
|
// jailAllowedAddrs []string,
|
||||||
|
// appOpts servertypes.AppOptions,
|
||||||
|
// modulesToExport []string,
|
||||||
|
// ) (genutilv2.ExportedApp, error) {
|
||||||
|
// var (
|
||||||
|
// laconicApp *app.LaconicApp
|
||||||
|
// err error
|
||||||
|
// )
|
||||||
|
|
||||||
|
// // this check is necessary as we use the flag in x/upgrade.
|
||||||
|
// // we can exit more gracefully by checking the flag here.
|
||||||
|
// homePath, ok := appOpts.Get(flags.FlagHome).(string)
|
||||||
|
// if !ok || homePath == "" {
|
||||||
|
// return servertypes.ExportedApp{}, errors.New("application home not set")
|
||||||
|
// }
|
||||||
|
|
||||||
|
// viperAppOpts, ok := appOpts.(*viper.Viper)
|
||||||
|
// if !ok {
|
||||||
|
// return servertypes.ExportedApp{}, errors.New("appOpts is not viper.Viper")
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // overwrite the FlagInvCheckPeriod
|
||||||
|
// viperAppOpts.Set(server.FlagInvCheckPeriod, 1)
|
||||||
|
// appOpts = viperAppOpts
|
||||||
|
|
||||||
|
// if height != -1 {
|
||||||
|
// laconicApp, err = app.NewLaconicApp(logger, db, false)
|
||||||
|
// if err != nil {
|
||||||
|
// return servertypes.ExportedApp{}, err
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if err := laconicApp.LoadHeight(uint64(height)); err != nil {
|
||||||
|
// return servertypes.ExportedApp{}, err
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// panic("height cannot be < 0")
|
||||||
|
// laconicApp, err = app.NewLaconicApp(logger, db, true)
|
||||||
|
// if err != nil {
|
||||||
|
// return servertypes.ExportedApp{}, err
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return laconicApp.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs, modulesToExport)
|
||||||
|
// }
|
||||||
|
106
cmd/laconicd/cmd/config.go
Normal file
106
cmd/laconicd/cmd/config.go
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
cmtcfg "github.com/cometbft/cometbft/config"
|
||||||
|
|
||||||
|
"cosmossdk.io/core/transaction"
|
||||||
|
serverv2 "cosmossdk.io/server/v2"
|
||||||
|
"cosmossdk.io/server/v2/cometbft"
|
||||||
|
|
||||||
|
clientconfig "github.com/cosmos/cosmos-sdk/client/config"
|
||||||
|
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||||
|
)
|
||||||
|
|
||||||
|
// initAppConfig helps to override default client config template and configs.
|
||||||
|
// return "", nil if no custom configuration is required for the application.
|
||||||
|
func initClientConfig() (string, interface{}) {
|
||||||
|
type GasConfig struct {
|
||||||
|
GasAdjustment float64 `mapstructure:"gas-adjustment"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CustomClientConfig struct {
|
||||||
|
clientconfig.Config `mapstructure:",squash"`
|
||||||
|
|
||||||
|
GasConfig GasConfig `mapstructure:"gas"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Optionally allow the chain developer to overwrite the SDK's default client config.
|
||||||
|
clientCfg := clientconfig.DefaultConfig()
|
||||||
|
|
||||||
|
// The SDK's default keyring backend is set to "os".
|
||||||
|
// This is more secure than "test" and is the recommended value.
|
||||||
|
//
|
||||||
|
// In simapp, we set the default keyring backend to test, as SimApp is meant
|
||||||
|
// to be an example and testing application.
|
||||||
|
clientCfg.KeyringBackend = keyring.BackendTest
|
||||||
|
|
||||||
|
// Now we set the custom config default values.
|
||||||
|
customClientConfig := CustomClientConfig{
|
||||||
|
Config: *clientCfg,
|
||||||
|
GasConfig: GasConfig{
|
||||||
|
GasAdjustment: 1.5,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// The default SDK app template is defined in serverconfig.DefaultConfigTemplate.
|
||||||
|
// We append the custom config template to the default one.
|
||||||
|
// And we set the default config to the custom app template.
|
||||||
|
customClientConfigTemplate := clientconfig.DefaultClientConfigTemplate + strings.TrimSpace(`
|
||||||
|
# This is default the gas adjustment factor used in tx commands.
|
||||||
|
# It can be overwritten by the --gas-adjustment flag in each tx command.
|
||||||
|
gas-adjustment = {{ .GasConfig.GasAdjustment }}
|
||||||
|
`)
|
||||||
|
|
||||||
|
return customClientConfigTemplate, customClientConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow the chain developer to overwrite the server default app toml config.
|
||||||
|
func initServerConfig() serverv2.ServerConfig {
|
||||||
|
serverCfg := serverv2.DefaultServerConfig()
|
||||||
|
// The server's default minimum gas price is set to "0stake" inside
|
||||||
|
// app.toml. However, the chain developer can set a default app.toml value for their
|
||||||
|
// validators here. Please update value based on chain denom.
|
||||||
|
//
|
||||||
|
// In summary:
|
||||||
|
// - if you set serverCfg.MinGasPrices value, validators CAN tweak their
|
||||||
|
// own app.toml to override, or use this default value.
|
||||||
|
//
|
||||||
|
// In simapp, we set the min gas prices to 0.
|
||||||
|
serverCfg.MinGasPrices = "0stake"
|
||||||
|
|
||||||
|
return serverCfg
|
||||||
|
}
|
||||||
|
|
||||||
|
// initCometConfig helps to override default comet config template and configs.
|
||||||
|
func initCometConfig() cometbft.CfgOption {
|
||||||
|
cfg := cmtcfg.DefaultConfig()
|
||||||
|
|
||||||
|
// display only warn logs by default except for p2p and state
|
||||||
|
cfg.LogLevel = "*:warn,server:info,p2p:info,state:info"
|
||||||
|
// increase block timeout
|
||||||
|
cfg.Consensus.TimeoutCommit = 5 * time.Second
|
||||||
|
// overwrite default pprof listen address
|
||||||
|
cfg.RPC.PprofListenAddress = "localhost:6060"
|
||||||
|
|
||||||
|
return cometbft.OverwriteDefaultConfigTomlConfig(cfg)
|
||||||
|
}
|
||||||
|
|
||||||
|
func initCometOptions[T transaction.Tx]() cometbft.ServerOptions[T] {
|
||||||
|
serverOptions := cometbft.DefaultServerOptions[T]()
|
||||||
|
|
||||||
|
// overwrite app mempool, using max-txs option
|
||||||
|
// serverOptions.Mempool = func(cfg map[string]any) mempool.Mempool[T] {
|
||||||
|
// if maxTxs := cast.ToInt(cfg[cometbft.FlagMempoolMaxTxs]); maxTxs >= 0 {
|
||||||
|
// return sdkmempool.NewSenderNonceMempool(
|
||||||
|
// sdkmempool.SenderNonceMaxTxOpt(maxTxs),
|
||||||
|
// )
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return mempool.NoOpMempool[T]{}
|
||||||
|
// }
|
||||||
|
|
||||||
|
return serverOptions
|
||||||
|
}
|
@ -31,7 +31,6 @@ import (
|
|||||||
|
|
||||||
"git.vdb.to/cerc-io/laconicd/app"
|
"git.vdb.to/cerc-io/laconicd/app"
|
||||||
"git.vdb.to/cerc-io/laconicd/gql"
|
"git.vdb.to/cerc-io/laconicd/gql"
|
||||||
"git.vdb.to/cerc-io/laconicd/utils"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const EnvPrefix = "LACONIC"
|
const EnvPrefix = "LACONIC"
|
||||||
@ -54,16 +53,8 @@ func NewRootCmd() *cobra.Command {
|
|||||||
app.AppConfig(),
|
app.AppConfig(),
|
||||||
depinject.Supply(
|
depinject.Supply(
|
||||||
log.NewNopLogger(),
|
log.NewNopLogger(),
|
||||||
utils.NewAddressCodec,
|
|
||||||
utils.NewValAddressCodec,
|
|
||||||
utils.NewConsAddressCodec,
|
|
||||||
),
|
),
|
||||||
runtime.DefaultServiceBindings(),
|
|
||||||
depinject.Provide(
|
depinject.Provide(
|
||||||
codec.ProvideInterfaceRegistry,
|
|
||||||
codec.ProvideAddressCodec,
|
|
||||||
codec.ProvideProtoCodec,
|
|
||||||
codec.ProvideLegacyAmino,
|
|
||||||
ProvideClientContext,
|
ProvideClientContext,
|
||||||
ProvideKeyring,
|
ProvideKeyring,
|
||||||
),
|
),
|
||||||
@ -171,8 +162,8 @@ func ProvideClientContext(
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Workaround: Unset clientCtx.HomeDir and clientCtx.KeyringDir from depinject clientCtx as they are given precedence over
|
// Workaround: Unset clientCtx.HomeDir and clientCtx.KeyringDir from depinject clientCtx as they
|
||||||
// the CLI args (--home flag) in some commands
|
// are given precedence over the CLI args (--home flag) in some commands
|
||||||
// TODO: Implement proper fix
|
// TODO: Implement proper fix
|
||||||
clientCtx.HomeDir = ""
|
clientCtx.HomeDir = ""
|
||||||
clientCtx.KeyringDir = ""
|
clientCtx.KeyringDir = ""
|
||||||
@ -186,5 +177,5 @@ func ProvideKeyring(clientCtx client.Context, addressCodec address.Codec) (clien
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return keyring.NewAutoCLIKeyring(kb)
|
return keyring.NewAutoCLIKeyring(kb, addressCodec)
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,8 @@ import (
|
|||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
svrcmd "cosmossdk.io/server/v2"
|
||||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||||
svrcmd "github.com/cosmos/cosmos-sdk/server/cmd"
|
|
||||||
"github.com/cosmos/cosmos-sdk/x/genutil/client/cli"
|
"github.com/cosmos/cosmos-sdk/x/genutil/client/cli"
|
||||||
|
|
||||||
"git.vdb.to/cerc-io/laconicd/app"
|
"git.vdb.to/cerc-io/laconicd/app"
|
||||||
|
@ -4,18 +4,18 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
svrcmd "github.com/cosmos/cosmos-sdk/server/cmd"
|
|
||||||
|
|
||||||
"git.vdb.to/cerc-io/laconicd/app"
|
"git.vdb.to/cerc-io/laconicd/app"
|
||||||
"git.vdb.to/cerc-io/laconicd/app/params"
|
|
||||||
"git.vdb.to/cerc-io/laconicd/cmd/laconicd/cmd"
|
"git.vdb.to/cerc-io/laconicd/cmd/laconicd/cmd"
|
||||||
|
|
||||||
|
clientv2helpers "cosmossdk.io/client/v2/helpers"
|
||||||
|
serverv2 "cosmossdk.io/server/v2"
|
||||||
|
|
||||||
|
_ "git.vdb.to/cerc-io/laconicd/app/params" // import for side-effects
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
params.SetAddressPrefixes()
|
|
||||||
|
|
||||||
rootCmd := cmd.NewRootCmd()
|
rootCmd := cmd.NewRootCmd()
|
||||||
if err := svrcmd.Execute(rootCmd, "", app.DefaultNodeHome); err != nil {
|
if err := serverv2.Execute(rootCmd, clientv2helpers.EnvPrefix, app.DefaultNodeHome); err != nil {
|
||||||
fmt.Fprintln(rootCmd.OutOrStderr(), err)
|
fmt.Fprintln(rootCmd.OutOrStderr(), err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
12
go.mod
12
go.mod
@ -27,7 +27,7 @@ require (
|
|||||||
cosmossdk.io/tools/confix v0.1.0
|
cosmossdk.io/tools/confix v0.1.0
|
||||||
github.com/99designs/gqlgen v0.17.22
|
github.com/99designs/gqlgen v0.17.22
|
||||||
github.com/cometbft/cometbft v1.0.0-rc1.0.20240908111210-ab0be101882f
|
github.com/cometbft/cometbft v1.0.0-rc1.0.20240908111210-ab0be101882f
|
||||||
github.com/cometbft/cometbft/api v1.0.0-rc.1
|
github.com/cometbft/cometbft/api v1.0.0-rc.1 // indirect
|
||||||
github.com/cosmos/cosmos-db v1.0.3-0.20240911104526-ddc3f09bfc22
|
github.com/cosmos/cosmos-db v1.0.3-0.20240911104526-ddc3f09bfc22
|
||||||
github.com/cosmos/cosmos-proto v1.0.0-beta.5
|
github.com/cosmos/cosmos-proto v1.0.0-beta.5
|
||||||
github.com/cosmos/cosmos-sdk v1.0.0
|
github.com/cosmos/cosmos-sdk v1.0.0
|
||||||
@ -48,7 +48,7 @@ require (
|
|||||||
github.com/statechannels/go-nitro v0.1.2
|
github.com/statechannels/go-nitro v0.1.2
|
||||||
github.com/stretchr/testify v1.9.0
|
github.com/stretchr/testify v1.9.0
|
||||||
github.com/vektah/gqlparser/v2 v2.5.11
|
github.com/vektah/gqlparser/v2 v2.5.11
|
||||||
golang.org/x/sync v0.8.0
|
golang.org/x/sync v0.8.0 // indirect
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142
|
google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142
|
||||||
google.golang.org/grpc v1.67.1
|
google.golang.org/grpc v1.67.1
|
||||||
google.golang.org/protobuf v1.35.1
|
google.golang.org/protobuf v1.35.1
|
||||||
@ -56,6 +56,8 @@ require (
|
|||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
cosmossdk.io/server/v2/cometbft v0.0.0-20241017154543-c1707b830856
|
||||||
|
cosmossdk.io/store/v2 v2.0.0-00010101000000-000000000000
|
||||||
cosmossdk.io/x/accounts v1.0.0-alpha.4
|
cosmossdk.io/x/accounts v1.0.0-alpha.4
|
||||||
cosmossdk.io/x/bank v1.0.0-alpha.4
|
cosmossdk.io/x/bank v1.0.0-alpha.4
|
||||||
cosmossdk.io/x/consensus v0.0.0-20241007000829-38662ecb209f
|
cosmossdk.io/x/consensus v0.0.0-20241007000829-38662ecb209f
|
||||||
@ -73,9 +75,8 @@ require (
|
|||||||
cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 // indirect
|
cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 // indirect
|
||||||
cosmossdk.io/errors/v2 v2.0.0-20240731132947-df72853b3ca5 // indirect
|
cosmossdk.io/errors/v2 v2.0.0-20240731132947-df72853b3ca5 // indirect
|
||||||
cosmossdk.io/schema v0.3.1-0.20241010135032-192601639cac // indirect
|
cosmossdk.io/schema v0.3.1-0.20241010135032-192601639cac // indirect
|
||||||
cosmossdk.io/server/v2/appmanager v0.0.0-00010101000000-000000000000 // indirect
|
cosmossdk.io/server/v2/appmanager v0.0.0-20240802110823-cffeedff643d // indirect
|
||||||
cosmossdk.io/server/v2/stf v0.0.0-00010101000000-000000000000 // indirect
|
cosmossdk.io/server/v2/stf v0.0.0-20240708142107-25e99c54bac1 // indirect
|
||||||
cosmossdk.io/store/v2 v2.0.0-00010101000000-000000000000 // indirect
|
|
||||||
cosmossdk.io/x/epochs v0.0.0-20240522060652-a1ae4c3e0337 // indirect
|
cosmossdk.io/x/epochs v0.0.0-20240522060652-a1ae4c3e0337 // indirect
|
||||||
cosmossdk.io/x/tx v0.13.3 // indirect
|
cosmossdk.io/x/tx v0.13.3 // indirect
|
||||||
filippo.io/edwards25519 v1.1.0 // indirect
|
filippo.io/edwards25519 v1.1.0 // indirect
|
||||||
@ -254,6 +255,7 @@ replace (
|
|||||||
cosmossdk.io/runtime/v2 => ../cosmos-sdk/runtime/v2
|
cosmossdk.io/runtime/v2 => ../cosmos-sdk/runtime/v2
|
||||||
cosmossdk.io/server/v2 => ../cosmos-sdk/server/v2
|
cosmossdk.io/server/v2 => ../cosmos-sdk/server/v2
|
||||||
cosmossdk.io/server/v2/appmanager => ../cosmos-sdk/server/v2/appmanager
|
cosmossdk.io/server/v2/appmanager => ../cosmos-sdk/server/v2/appmanager
|
||||||
|
cosmossdk.io/server/v2/cometbft => ../cosmos-sdk/server/v2/cometbft
|
||||||
cosmossdk.io/server/v2/stf => ../cosmos-sdk/server/v2/stf
|
cosmossdk.io/server/v2/stf => ../cosmos-sdk/server/v2/stf
|
||||||
cosmossdk.io/store => ../cosmos-sdk/store
|
cosmossdk.io/store => ../cosmos-sdk/store
|
||||||
cosmossdk.io/store/v2 => ../cosmos-sdk/store/v2
|
cosmossdk.io/store/v2 => ../cosmos-sdk/store/v2
|
||||||
|
48
utils/tx.go
Normal file
48
utils/tx.go
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"cosmossdk.io/core/transaction"
|
||||||
|
"github.com/cosmos/cosmos-sdk/client"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ transaction.Codec[transaction.Tx] = &GenericTxDecoder[transaction.Tx]{}
|
||||||
|
|
||||||
|
type GenericTxDecoder[T transaction.Tx] struct {
|
||||||
|
TxConfig client.TxConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode implements transaction.Codec.
|
||||||
|
func (t GenericTxDecoder[T]) Decode(bz []byte) (T, error) {
|
||||||
|
var out T
|
||||||
|
tx, err := t.TxConfig.TxDecoder()(bz)
|
||||||
|
if err != nil {
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var ok bool
|
||||||
|
out, ok = tx.(T)
|
||||||
|
if !ok {
|
||||||
|
return out, errors.New("unexpected Tx type")
|
||||||
|
}
|
||||||
|
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeJSON implements transaction.Codec.
|
||||||
|
func (t GenericTxDecoder[T]) DecodeJSON(bz []byte) (T, error) {
|
||||||
|
var out T
|
||||||
|
tx, err := t.TxConfig.TxJSONDecoder()(bz)
|
||||||
|
if err != nil {
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var ok bool
|
||||||
|
out, ok = tx.(T)
|
||||||
|
if !ok {
|
||||||
|
return out, errors.New("unexpected Tx type")
|
||||||
|
}
|
||||||
|
|
||||||
|
return out, nil
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user