From d93ef09ed74d983e619029cac6063fc8fe9edc3d Mon Sep 17 00:00:00 2001 From: Nikhil Sharma Date: Thu, 12 Mar 2026 14:02:14 +0530 Subject: [PATCH 1/6] feat(poa): integrate PoA module for gov-only validator set Signed-off-by: Nikhil Sharma --- ante/cosmos.go | 2 ++ evmd/app.go | 44 +++++++++++++++++++++++++++++++++++++- evmd/config/permissions.go | 2 ++ evmd/go.mod | 11 ++++++---- evmd/go.sum | 14 ++++++------ go.mod | 6 ++++-- go.sum | 14 ++++++------ 7 files changed, 74 insertions(+), 19 deletions(-) diff --git a/ante/cosmos.go b/ante/cosmos.go index a83be204..ea014d12 100644 --- a/ante/cosmos.go +++ b/ante/cosmos.go @@ -5,6 +5,7 @@ import ( evmante "github.com/cosmos/evm/ante/evm" evmtypes "github.com/cosmos/evm/x/vm/types" ibcante "github.com/cosmos/ibc-go/v10/modules/core/ante" + poaante "github.com/xrplevm/node/v10/x/poa/ante" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth/ante" @@ -40,5 +41,6 @@ func newCosmosAnteHandler(ctx sdk.Context, options HandlerOptions) sdk.AnteHandl ante.NewSigVerificationDecorator(options.AccountKeeper, options.SignModeHandler), ante.NewIncrementSequenceDecorator(options.AccountKeeper), ibcante.NewRedundantRelayDecorator(options.IBCKeeper), + poaante.NewPoaDecorator(), ) } diff --git a/evmd/app.go b/evmd/app.go index b92e46e5..80d793ee 100644 --- a/evmd/app.go +++ b/evmd/app.go @@ -121,12 +121,17 @@ import ( "github.com/cosmos/cosmos-sdk/x/mint" mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper" minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" + paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper" + paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" "github.com/cosmos/cosmos-sdk/x/slashing" slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper" slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" "github.com/cosmos/cosmos-sdk/x/staking" stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/xrplevm/node/v10/x/poa" + poakeeper "github.com/xrplevm/node/v10/x/poa/keeper" + poatypes "github.com/xrplevm/node/v10/x/poa/types" ) func init() { @@ -160,6 +165,7 @@ type EVMD struct { // keys to access the substores keys map[string]*storetypes.KVStoreKey + tkeys map[string]*storetypes.TransientStoreKey oKeys map[string]*storetypes.ObjectStoreKey // keepers @@ -175,6 +181,8 @@ type EVMD struct { EvidenceKeeper evidencekeeper.Keeper FeeGrantKeeper feegrantkeeper.Keeper ConsensusParamsKeeper consensusparamkeeper.Keeper + ParamsKeeper paramskeeper.Keeper + PoaKeeper poakeeper.Keeper // IBC keepers IBCKeeper *ibckeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly @@ -233,12 +241,14 @@ func NewExampleApp( authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey, minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey, govtypes.StoreKey, consensusparamtypes.StoreKey, + paramstypes.StoreKey, upgradetypes.StoreKey, feegrant.StoreKey, evidencetypes.StoreKey, authzkeeper.StoreKey, // ibc keys ibcexported.StoreKey, ibctransfertypes.StoreKey, // Cosmos EVM store keys evmtypes.StoreKey, feemarkettypes.StoreKey, erc20types.StoreKey, precisebanktypes.StoreKey, ) + tkeys := storetypes.NewTransientStoreKeys(paramstypes.TStoreKey) oKeys := storetypes.NewObjectStoreKeys(banktypes.ObjectStoreKey, evmtypes.ObjectKey) var nonTransientKeys []storetypes.StoreKey @@ -267,10 +277,20 @@ func NewExampleApp( txConfig: txConfig, interfaceRegistry: interfaceRegistry, keys: keys, + tkeys: tkeys, oKeys: oKeys, } - // removed x/params: no ParamsKeeper initialization + // params keeper is used by the PoA module + // it is deprecated in the SDK but still required for the xrplevm/node PoA keeper + app.ParamsKeeper = paramskeeper.NewKeeper( + appCodec, + legacyAmino, + keys[paramstypes.StoreKey], + tkeys[paramstypes.TStoreKey], + ) + // Register subspace for PoA so GetSubspace(poatypes.ModuleName) returns a valid subspace. + app.ParamsKeeper.Subspace(poatypes.ModuleName).WithKeyTable(poatypes.ParamKeyTable()) // get authority address authAddr := authtypes.NewModuleAddress(govtypes.ModuleName).String() @@ -550,6 +570,15 @@ func NewExampleApp( tmLightClientModule := ibctm.NewLightClientModule(appCodec, storeProvider) clientKeeper.AddRoute(ibctm.ModuleName, &tmLightClientModule) + app.PoaKeeper = *poakeeper.NewKeeper( + appCodec, + app.GetSubspace(poatypes.ModuleName), + app.MsgServiceRouter(), + app.BankKeeper, + app.StakingKeeper, + authAddr, + ) + // Override the ICS20 app module transferModule := transfer.NewAppModule(app.TransferKeeper) @@ -570,6 +599,7 @@ func NewExampleApp( slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, nil, app.interfaceRegistry), distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, nil), staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, nil), + poa.NewAppModule(appCodec, app.PoaKeeper, app.BankKeeper, app.StakingKeeper, app.AccountKeeper, app.interfaceRegistry), upgrade.NewAppModule(app.UpgradeKeeper, app.AccountKeeper.AddressCodec()), evidence.NewAppModule(app.EvidenceKeeper), authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry), @@ -641,6 +671,7 @@ func NewExampleApp( banktypes.ModuleName, govtypes.ModuleName, stakingtypes.ModuleName, + poatypes.ModuleName, authtypes.ModuleName, // Cosmos EVM EndBlockers @@ -662,6 +693,7 @@ func NewExampleApp( genesisModuleOrder := []string{ authtypes.ModuleName, banktypes.ModuleName, distrtypes.ModuleName, stakingtypes.ModuleName, slashingtypes.ModuleName, govtypes.ModuleName, + poatypes.ModuleName, minttypes.ModuleName, ibcexported.ModuleName, @@ -718,6 +750,7 @@ func NewExampleApp( // initialize stores app.MountKVStores(keys) app.MountObjectStores(oKeys) + app.MountTransientStores(tkeys) maxGasWanted := cast.ToUint64(appOpts.Get(srvflags.EVMMaxTxGasWanted)) @@ -918,6 +951,15 @@ func (app *EVMD) GetKey(storeKey string) *storetypes.KVStoreKey { return app.keys[storeKey] } +// GetSubspace returns a params subspace for a given module name. +func (app *EVMD) GetSubspace(moduleName string) paramstypes.Subspace { + subspace, ok := app.ParamsKeeper.GetSubspace(moduleName) + if !ok { + panic(fmt.Sprintf("subspace for module %s not registered", moduleName)) + } + return subspace +} + // SimulationManager implements the SimulationApp interface func (app *EVMD) SimulationManager() *module.SimulationManager { return app.sm diff --git a/evmd/config/permissions.go b/evmd/config/permissions.go index 2aa0d5fa..79a3120a 100644 --- a/evmd/config/permissions.go +++ b/evmd/config/permissions.go @@ -15,6 +15,7 @@ import ( precisebanktypes "github.com/cosmos/evm/x/precisebank/types" vmtypes "github.com/cosmos/evm/x/vm/types" transfertypes "github.com/cosmos/ibc-go/v10/modules/apps/transfer/types" + poatypes "github.com/xrplevm/node/v10/x/poa/types" corevm "github.com/ethereum/go-ethereum/core/vm" ) @@ -59,6 +60,7 @@ var maccPerms = map[string][]string{ stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking}, stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking}, govtypes.ModuleName: {authtypes.Burner}, + poatypes.ModuleName: {authtypes.Minter, authtypes.Burner}, // Cosmos EVM modules vmtypes.ModuleName: {authtypes.Minter, authtypes.Burner}, diff --git a/evmd/go.mod b/evmd/go.mod index daa44827..5cccc0d6 100644 --- a/evmd/go.mod +++ b/evmd/go.mod @@ -5,7 +5,7 @@ go 1.25.5 require ( cosmossdk.io/api v0.9.2 cosmossdk.io/client/v2 v2.0.0-beta.7 - cosmossdk.io/core v0.11.3 + cosmossdk.io/core v0.12.0 cosmossdk.io/errors v1.0.2 cosmossdk.io/log v1.6.1 cosmossdk.io/math v1.5.3 @@ -17,9 +17,9 @@ require ( github.com/cometbft/cometbft v0.39.0-beta.2 github.com/cosmos/cosmos-db v1.1.3 github.com/cosmos/cosmos-sdk v0.54.0-rc.1.0.20260106173710-fd8291796e71 - github.com/cosmos/evm v0.2.0 + github.com/cosmos/evm v0.6.0 github.com/cosmos/gogoproto v1.7.2 - github.com/cosmos/ibc-go/v10 v10.0.0-beta.0.0.20251216200936-98a683ee20a3 + github.com/cosmos/ibc-go/v10 v10.3.1-0.20250909102629-ed3b125c7b6f github.com/ethereum/go-ethereum v1.16.7 github.com/onsi/ginkgo/v2 v2.23.4 github.com/onsi/gomega v1.38.0 @@ -28,6 +28,7 @@ require ( github.com/spf13/pflag v1.0.10 github.com/spf13/viper v1.21.0 github.com/stretchr/testify v1.11.1 + github.com/xrplevm/node/v10 v10.0.3 golang.org/x/sync v0.19.0 google.golang.org/grpc v1.78.0 ) @@ -119,7 +120,7 @@ require ( github.com/dgraph-io/badger/v4 v4.6.0 // indirect github.com/dgraph-io/ristretto/v2 v2.1.0 // indirect github.com/dlclark/regexp2 v1.7.0 // indirect - github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3 // indirect + github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/dvsekhvalnov/jose2go v1.7.0 // indirect github.com/ebitengine/purego v0.9.1 // indirect @@ -316,9 +317,11 @@ require ( ) replace ( + cosmossdk.io/core => cosmossdk.io/core v0.11.3 // use cosmos fork of keyring github.com/99designs/keyring => github.com/cosmos/keyring v1.2.0 github.com/cosmos/evm => ../ + github.com/cosmos/ibc-go/v10 => github.com/cosmos/ibc-go/v10 v10.0.0-beta.0.0.20251216200936-98a683ee20a3 // use Cosmos geth fork // branch: release/1.16 github.com/ethereum/go-ethereum => github.com/cosmos/go-ethereum v1.16.2-cosmos-1 diff --git a/evmd/go.sum b/evmd/go.sum index f5747706..d303a32f 100644 --- a/evmd/go.sum +++ b/evmd/go.sum @@ -262,8 +262,8 @@ github.com/cometbft/cometbft-db v0.14.1 h1:SxoamPghqICBAIcGpleHbmoPqy+crij/++eZz github.com/cometbft/cometbft-db v0.14.1/go.mod h1:KHP1YghilyGV/xjD5DP3+2hyigWx0WTp9X+0Gnx0RxQ= github.com/consensys/gnark-crypto v0.18.1 h1:RyLV6UhPRoYYzaFnPQA4qK3DyuDgkTgskDdoGqFt3fI= github.com/consensys/gnark-crypto v0.18.1/go.mod h1:L3mXGFTe1ZN+RSJ+CLjUt9x7PNdx8ubaYfDROyp2Z8c= -github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= -github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= +github.com/containerd/continuity v0.4.3 h1:6HVkalIp+2u1ZLH1J/pYX2oBVXlJZvh1X1A7bEZ9Su8= +github.com/containerd/continuity v0.4.3/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= @@ -348,8 +348,8 @@ github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6 github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= -github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3 h1:+3HCtB74++ClLy8GgjUQYeC8R4ILzVcIe8+5edAJJnE= -github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4= +github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127 h1:qwcF+vdFrvPSEUDSX5RVoRccG8a5DhOdWdQ4zN62zzo= +github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4= github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= @@ -798,8 +798,8 @@ github.com/onsi/gomega v1.38.0/go.mod h1:OcXcwId0b9QsE7Y49u+BTrL4IdKOBOKnD6VQNTJ github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI= -github.com/opencontainers/image-spec v1.1.0-rc5/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= +github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= +github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= github.com/opencontainers/runc v1.1.14 h1:rgSuzbmgz5DUJjeSnw337TxDbRuqjs6iqQck/2weR6w= github.com/opencontainers/runc v1.1.14/go.mod h1:E4C2z+7BxR7GHXp0hAY53mek+x49X1LjPNeMTfRGvOA= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= @@ -1022,6 +1022,8 @@ github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcY github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= +github.com/xrplevm/node/v10 v10.0.3 h1:t6E0j3Tn/lIJ6iqyVtMgEWUDlEike6KLsL31ZOpIm1k= +github.com/xrplevm/node/v10 v10.0.3/go.mod h1:1cB9zELDyCvc1gacxO0wrBjR2yfFoMjq2OEPFnGU5Ew= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= diff --git a/go.mod b/go.mod index dd6b00a2..69b8b6d9 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.25.5 require ( cosmossdk.io/api v0.9.2 - cosmossdk.io/core v0.11.3 + cosmossdk.io/core v0.12.0 cosmossdk.io/errors v1.0.2 cosmossdk.io/log v1.6.1 cosmossdk.io/math v1.5.3 @@ -21,7 +21,7 @@ require ( github.com/cosmos/cosmos-sdk v0.54.0-rc.1.0.20260106173710-fd8291796e71 github.com/cosmos/go-bip39 v1.0.0 github.com/cosmos/gogoproto v1.7.2 - github.com/cosmos/ibc-go/v10 v10.0.0-beta.0.0.20251216200936-98a683ee20a3 + github.com/cosmos/ibc-go/v10 v10.3.1-0.20250909102629-ed3b125c7b6f github.com/cosmos/ledger-cosmos-go v1.0.0 github.com/creachadair/tomledit v0.0.28 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc @@ -47,6 +47,7 @@ require ( github.com/tidwall/gjson v1.18.0 github.com/tidwall/sjson v1.2.5 github.com/tyler-smith/go-bip39 v1.1.0 + github.com/xrplevm/node/v10 v10.0.3 github.com/zondax/hid v0.9.2 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.64.0 go.opentelemetry.io/otel v1.39.0 @@ -312,6 +313,7 @@ require ( replace ( // use cosmos fork of keyring github.com/99designs/keyring => github.com/cosmos/keyring v1.2.0 + github.com/cosmos/ibc-go/v10 => github.com/cosmos/ibc-go/v10 v10.0.0-beta.0.0.20251216200936-98a683ee20a3 // use Cosmos geth fork // branch: release/1.16 github.com/ethereum/go-ethereum => github.com/cosmos/go-ethereum v1.16.2-cosmos-1 diff --git a/go.sum b/go.sum index 44d1503f..bc056c44 100644 --- a/go.sum +++ b/go.sum @@ -26,8 +26,8 @@ cosmossdk.io/api v0.9.2 h1:9i9ptOBdmoIEVEVWLtYYHjxZonlF/aOVODLFaxpmNtg= cosmossdk.io/api v0.9.2/go.mod h1:CWt31nVohvoPMTlPv+mMNCtC0a7BqRdESjCsstHcTkU= cosmossdk.io/collections v1.3.1 h1:09e+DUId2brWsNOQ4nrk+bprVmMUaDH9xvtZkeqIjVw= cosmossdk.io/collections v1.3.1/go.mod h1:ynvkP0r5ruAjbmedE+vQ07MT6OtJ0ZIDKrtJHK7Q/4c= -cosmossdk.io/core v0.11.3 h1:mei+MVDJOwIjIniaKelE3jPDqShCc/F4LkNNHh+4yfo= -cosmossdk.io/core v0.11.3/go.mod h1:9rL4RE1uDt5AJ4Tg55sYyHWXA16VmpHgbe0PbJc6N2Y= +cosmossdk.io/core v0.12.0 h1:aFuvkG6eDv0IQC+UDjx86wxNWVAxdCFk7OABJ1Vh4RU= +cosmossdk.io/core v0.12.0/go.mod h1:LaTtayWBSoacF5xNzoF8tmLhehqlA9z1SWiPuNC6X1w= cosmossdk.io/depinject v1.2.1 h1:eD6FxkIjlVaNZT+dXTQuwQTKZrFZ4UrfCq1RKgzyhMw= cosmossdk.io/depinject v1.2.1/go.mod h1:lqQEycz0H2JXqvOgVwTsjEdMI0plswI7p6KX+MVqFOM= cosmossdk.io/errors v1.0.2 h1:wcYiJz08HThbWxd/L4jObeLaLySopyyuUFB5w4AGpCo= @@ -257,8 +257,8 @@ github.com/cometbft/cometbft-db v0.14.1 h1:SxoamPghqICBAIcGpleHbmoPqy+crij/++eZz github.com/cometbft/cometbft-db v0.14.1/go.mod h1:KHP1YghilyGV/xjD5DP3+2hyigWx0WTp9X+0Gnx0RxQ= github.com/consensys/gnark-crypto v0.18.1 h1:RyLV6UhPRoYYzaFnPQA4qK3DyuDgkTgskDdoGqFt3fI= github.com/consensys/gnark-crypto v0.18.1/go.mod h1:L3mXGFTe1ZN+RSJ+CLjUt9x7PNdx8ubaYfDROyp2Z8c= -github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= -github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= +github.com/containerd/continuity v0.4.3 h1:6HVkalIp+2u1ZLH1J/pYX2oBVXlJZvh1X1A7bEZ9Su8= +github.com/containerd/continuity v0.4.3/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= @@ -779,8 +779,8 @@ github.com/onsi/gomega v1.38.0/go.mod h1:OcXcwId0b9QsE7Y49u+BTrL4IdKOBOKnD6VQNTJ github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI= -github.com/opencontainers/image-spec v1.1.0-rc5/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= +github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= +github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= github.com/opencontainers/runc v1.1.14 h1:rgSuzbmgz5DUJjeSnw337TxDbRuqjs6iqQck/2weR6w= github.com/opencontainers/runc v1.1.14/go.mod h1:E4C2z+7BxR7GHXp0hAY53mek+x49X1LjPNeMTfRGvOA= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= @@ -1002,6 +1002,8 @@ github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcY github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= +github.com/xrplevm/node/v10 v10.0.3 h1:t6E0j3Tn/lIJ6iqyVtMgEWUDlEike6KLsL31ZOpIm1k= +github.com/xrplevm/node/v10 v10.0.3/go.mod h1:1cB9zELDyCvc1gacxO0wrBjR2yfFoMjq2OEPFnGU5Ew= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= From ef9136fab2647c52726009efea9f16f86dfc3542 Mon Sep 17 00:00:00 2001 From: Nikhil Sharma Date: Thu, 12 Mar 2026 14:04:34 +0530 Subject: [PATCH 2/6] docs(poa): add POA add-validator-via-gov guide and example proposal JSON Signed-off-by: Nikhil Sharma --- evmd/docs/POA_ADD_VALIDATOR_VIA_GOV.md | 276 ++++++++++++++++++++++ evmd/docs/poa_add_validator_proposal.json | 25 ++ 2 files changed, 301 insertions(+) create mode 100644 evmd/docs/POA_ADD_VALIDATOR_VIA_GOV.md create mode 100644 evmd/docs/poa_add_validator_proposal.json diff --git a/evmd/docs/POA_ADD_VALIDATOR_VIA_GOV.md b/evmd/docs/POA_ADD_VALIDATOR_VIA_GOV.md new file mode 100644 index 00000000..70d4c171 --- /dev/null +++ b/evmd/docs/POA_ADD_VALIDATOR_VIA_GOV.md @@ -0,0 +1,276 @@ +# Add a PoA Validator via Governance — Step by Step + +This guide walks through adding a new validator using the PoA module and governance. Use it when the E2E script is not suitable or you want to run each step manually. + +**Paths in this repo (from repo root):** + +- **This guide:** `evmd/docs/POA_ADD_VALIDATOR_VIA_GOV.md` +- **Example proposal (template):** `evmd/docs/poa_add_validator_proposal.json` — replace `authority`, `validator_address`, and `pubkey` with your values from Steps 1–2. + +--- + +## How PoA prevents direct validator changes + +Under PoA (Proof of Authority), **normal staking is disabled** so the validator set is controlled only by governance: + +- The PoA **ante decorator** rejects any Cosmos tx that contains: + - `MsgDelegate` + - `MsgUndelegate` + - `MsgBeginRedelegate` + - `MsgCancelUnbondingDelegation` +- So users **cannot** delegate, undelegate, redelegate, or cancel unbonding. The validator set and delegations cannot be changed through regular txs. +- **Adding a validator** is only possible via a **governance proposal** whose message is `MsgAddValidator` with **authority** = gov module. When the proposal passes, the PoA module mints initial stake and creates the validator; it does **not** use a user’s self-bond or delegation. + +So “direct” validator creation (e.g. a user sending create-validator with their own funds) is not the path here; the only supported path is **gov proposal → MsgAddValidator**. + +### How to test that PoA is active + +Before running the add-validator flow, you can confirm PoA is blocking delegation: + +1. **Delegate (should fail)** + With the chain running and keys/chain-id matching your setup (e.g. `--home ~/.og-evm-devnet --chain-id 10740 --keyring-backend test`): + + ```bash + VALIDATOR=$(evmd query staking validators --home ~/.og-evm-devnet -o json 2>/dev/null | sed -n '/^{/,$ p' | jq -r '.validators[0].operator_address') + evmd tx staking delegate "$VALIDATOR" 1000000ogwei --from dev0 --keyring-backend test --home ~/.og-evm-devnet --chain-id 10740 -y + ``` + + **Expected:** The tx is **rejected** with an error containing **`tx type not allowed`**. That indicates the PoA ante is active and delegation is blocked. + +2. **Optional — other Cosmos txs still work** + For example, a bank send should succeed; only the staking messages above are blocked. + +Once you’ve confirmed that, you can safely follow the steps below to add a validator via governance. + +--- + +**Prerequisites** + +- Chain is running (e.g. from repo root: `./local_node.sh -y`). +- All commands below use: `--home ~/.og-evm-devnet --chain-id 10740 --keyring-backend test`. +- `jq` is optional but helpful for parsing; otherwise copy values from the command output. + +--- + +## Step 1. Get the gov module address (authority) + +Run: + +```bash +evmd query auth module-account gov --home ~/.og-evm-devnet -o json +``` + +In the output, ignore any lines like `=== REGISTERING TEE PRECOMPILE ===`. Find the JSON object and copy **`account.value.address`** (e.g. `og10d07y265gmmuvt4z0w9aw880jnsr700jrdya3k`). This is the **authority** for the proposal message. + +With jq (only the JSON line is parsed; if your evmd prints extra lines, copy the JSON block to a file first or use the next command): + +```bash +evmd query auth module-account gov --home ~/.og-evm-devnet -o json 2>/dev/null | sed -n '/^{/,$ p' | jq -r '.account.value.address' +``` + +Save this as **GOV_AUTHORITY** for the proposal. + +--- + +## Step 2. Create the new validator account and consensus key + +### 2a. Validator account (bech32 address) + +Add a key that will be the new validator’s account. **Do not fund this address.** + +```bash +evmd keys add newvalidator --keyring-backend test --home ~/.og-evm-devnet --no-backup +``` + +From the output, copy the **address** (e.g. `og1...`). This is **validator_address** in the proposal. The account must have no balance, no existing validator, and no delegations/unbonding when the proposal runs. + +### 2b. Consensus pubkey (ed25519) + +The chain expects a **consensus** key (ed25519), not the account key. Generate it in a **temporary directory** (do not use the running node’s config): + +```bash +mkdir -p /tmp/poa-consensus-keys && cd /tmp/poa-consensus-keys +cometbft gen-validator +``` + +`cometbft gen-validator` prints JSON to stdout. Find the **`pub_key.value`** field (a base64 string). Example: + +```json +"pub_key": {"type": "tendermint/PubKeyEd25519", "value": "aHlSZw+054g3XnuDblDq6TafZrXVK7xGuk9081g1FAk="} +``` + +Copy the **base64 value** (e.g. `aHlSZw+054g3XnuDblDq6TafZrXVK7xGuk9081g1FAk=`). You will use it in the proposal as the ed25519 pubkey. + +Optional: clean up the temp dir so no validator keys remain: + +```bash +rm -rf /tmp/poa-consensus-keys +``` + +--- + +## Step 3. Build the proposal JSON + +Create a file (e.g. `proposal.json`) with this structure, or copy and edit the repo example **`evmd/docs/poa_add_validator_proposal.json`**. Replace: + +- **authority** → gov module address from Step 1 +- **validator_address** → new validator account address from Step 2a +- **key** (inside pubkey) → base64 value from Step 2b + +```json +{ + "messages": [ + { + "@type": "/poa.MsgAddValidator", + "authority": "", + "validator_address": "", + "description": { + "moniker": "newvalidator", + "identity": "", + "website": "", + "security_contact": "", + "details": "" + }, + "pubkey": { + "@type": "/cosmos.crypto.ed25519.PubKey", + "key": "" + } + } + ], + "metadata": "Add PoA validator", + "deposit": "10000000ogwei", + "title": "Add validator", + "summary": "Add a second validator via PoA governance", + "expedited": false +} +``` + +Example with real-looking values: + +```json +{ + "messages": [ + { + "@type": "/poa.MsgAddValidator", + "authority": "og10d07y265gmmuvt4z0w9aw880jnsr700jrdya3k", + "validator_address": "og1xu4krmxl40ec0vlfx3lk38hkj0scw8z79ck225", + "description": { + "moniker": "newvalidator", + "identity": "", + "website": "", + "security_contact": "", + "details": "" + }, + "pubkey": { + "@type": "/cosmos.crypto.ed25519.PubKey", + "key": "aHlSZw+054g3XnuDblDq6TafZrXVK7xGuk9081g1FAk=" + } + } + ], + "metadata": "Add PoA validator", + "deposit": "10000000ogwei", + "title": "Add validator", + "summary": "Add a second validator via PoA governance", + "expedited": false +} +``` + +--- + +## Step 4. Submit the proposal + +Use **enough gas** (e.g. 500000) so the tx does not run out of gas. From repo root you can use the example file: + +```bash +evmd tx gov submit-proposal evmd/docs/poa_add_validator_proposal.json \ + --from dev0 \ + --gas-prices 3000ogwei \ + --gas 500000 \ + --home ~/.og-evm-devnet \ + --chain-id 10740 \ + -y \ + --keyring-backend test +``` + +Or use your own file (e.g. `proposal.json`) after replacing authority, validator_address, and pubkey: + +```bash +evmd tx gov submit-proposal proposal.json \ + --from dev0 \ + --gas-prices 3000ogwei \ + --gas 500000 \ + --home ~/.og-evm-devnet \ + --chain-id 10740 \ + -y \ + --keyring-backend test +``` + +Note the **proposal id** from the output (or list proposals): + +```bash +evmd query gov proposals --home ~/.og-evm-devnet -o json +``` + +Again, if output has non-JSON lines, use only the JSON part when parsing. The latest proposal’s `id` is the one you need. + +--- + +## Step 5. Vote + +Vote **soon** after the proposal enters the voting period (with `local_node.sh`, voting period is 30s). Use the key that has staking power (e.g. `mykey`): + +```bash +evmd tx gov vote yes \ + --from mykey \ + --gas-prices 3000ogwei \ + --gas 300000 \ + --home ~/.og-evm-devnet \ + --chain-id 10740 \ + -y \ + --keyring-backend test +``` + +Replace `` with the id from Step 4 (e.g. `1` or `2`). + +--- + +## Step 6. Wait and verify + +Wait for the voting period to end (e.g. 30–35 seconds with `local_node.sh`). Then check the proposal status: + +```bash +evmd query gov proposal --home ~/.og-evm-devnet +``` + +You should see **status: PROPOSAL_STATUS_PASSED**. + +List validators to confirm the new one is in the set: + +```bash +evmd query staking validators --home ~/.og-evm-devnet -o json +``` + +You should see **two** validators: the original and the new one (moniker e.g. `newvalidator`). + +--- + +## Troubleshooting + +| Issue | What to check | +|-------|----------------| +| jq parse error | evmd may print TEE/precompile lines before JSON. Use only the JSON part (e.g. copy from first `{` to last `}`) or use `sed -n '/^{/,$ p'` before piping to jq. | +| Submit out of gas | Use `--gas 500000` (or higher) on submit-proposal. | +| Vote: "inactive proposal" | Voting period (30s) ended before your vote was included. Submit a new proposal and vote immediately. | +| Execution fails | Ensure the new validator account has **no** balance, no existing validator, and no delegations/unbonding. | + +--- + +## Quick reference + +- **Gov authority:** `evmd query auth module-account gov --home ~/.og-evm-devnet -o json` → `account.value.address` +- **New validator address:** `evmd keys add newvalidator ...` → address in output +- **Consensus pubkey:** `cometbft gen-validator` in a temp dir → `pub_key.value` (base64) +- **Proposal:** One message `@type: /poa.MsgAddValidator` with authority, validator_address, description, pubkey; deposit `10000000ogwei` +- **Submit:** `evmd tx gov submit-proposal evmd/docs/poa_add_validator_proposal.json --from dev0 --gas 500000 ...` (from repo root; or use your own `proposal.json`) +- **Vote:** `evmd tx gov vote yes --from mykey ...` +- **Verify:** `evmd query staking validators --home ~/.og-evm-devnet` diff --git a/evmd/docs/poa_add_validator_proposal.json b/evmd/docs/poa_add_validator_proposal.json new file mode 100644 index 00000000..5b7ce72b --- /dev/null +++ b/evmd/docs/poa_add_validator_proposal.json @@ -0,0 +1,25 @@ +{ + "messages": [ + { + "@type": "/poa.MsgAddValidator", + "authority": "og10d07y265gmmuvt4z0w9aw880jnsr700jrdya3k", + "validator_address": "og1warvjhukk7th2xprz7mhfa48h32cfm9jw5dl0c", + "description": { + "moniker": "newvalidator", + "identity": "", + "website": "", + "security_contact": "", + "details": "" + }, + "pubkey": { + "@type": "/cosmos.crypto.ed25519.PubKey", + "key": "aHlSZw+054g3XnuDblDq6TafZrXVK7xGuk9081g1FAk=" + } + } + ], + "metadata": "Add PoA validator", + "deposit": "10000000ogwei", + "title": "Add validator", + "summary": "Add a second validator via PoA governance", + "expedited": false +} From 410958baab28748687c1cce60b43acdde39473bc Mon Sep 17 00:00:00 2001 From: Yogesh Shahi Date: Sun, 15 Mar 2026 04:04:20 +0530 Subject: [PATCH 3/6] docs(poa): rewrite add-validator guide and update README --- evmd/README.md | 13 +- evmd/docs/POA_ADD_VALIDATOR_VIA_GOV.md | 267 ++++++++++------------ evmd/docs/poa_add_validator_proposal.json | 6 +- 3 files changed, 136 insertions(+), 150 deletions(-) diff --git a/evmd/README.md b/evmd/README.md index 419b8aa5..42dfbea9 100644 --- a/evmd/README.md +++ b/evmd/README.md @@ -14,11 +14,11 @@ By default, this chain has the following configuration: | Option | Value | |---------------------|------------------------| -| Binary | `evmd` | -| Chain ID | `cosmos_262144-1` | +| Binary | `emvd` | +| Chain ID | `10740` | | Custom Opcodes | - | | Default Token Pairs | 1 for the native token | -| Denomination | `atest` | +| Denomination | `ogwei` | | EVM permissioning | permissionless | | Enabled Precompiles | all | @@ -55,6 +55,12 @@ unhappy lunar seat` ![RPC URL Settings](guide/rpc_url.png "RPC URL") ![Overview of required settings](guide/settings.png "Settings Overview") +## Proof of Authority (PoA) + +Currently this is a PoA chain. The validator set is managed through governance, not open staking. Regular staking transactions like delegate and undelegate are blocked at the ante handler level. Validators can only be added or removed via governance proposals. The PoA module is built by the [xrplevm/node](https://github.com/xrplevm/node) team. + +See [evmd/docs/POA_ADD_VALIDATOR_VIA_GOV.md](docs/POA_ADD_VALIDATOR_VIA_GOV.md) for a step-by-step guide on adding a validator. + ## Available Cosmos SDK Modules As mentioned above, this exemplary chain implementation is a reduced version of `simapp`. @@ -72,6 +78,7 @@ Specifically, instead of offering access to all Cosmos SDK modules, it just incl - `gov` - `mint` - `params` +- `poa` - `slashing` - `staking` - `upgrade` diff --git a/evmd/docs/POA_ADD_VALIDATOR_VIA_GOV.md b/evmd/docs/POA_ADD_VALIDATOR_VIA_GOV.md index 70d4c171..8f51832d 100644 --- a/evmd/docs/POA_ADD_VALIDATOR_VIA_GOV.md +++ b/evmd/docs/POA_ADD_VALIDATOR_VIA_GOV.md @@ -1,121 +1,127 @@ -# Add a PoA Validator via Governance — Step by Step +# Add a PoA Validator via Governance -This guide walks through adding a new validator using the PoA module and governance. Use it when the E2E script is not suitable or you want to run each step manually. +This guide walks you through adding a new validator using the PoA module and governance. The commands here are written for a local devnet. If you are setting this up on mainnet, the steps are the same but some values will differ. Check the [Notes for mainnet](#notes-for-mainnet) section at the end before you start. -**Paths in this repo (from repo root):** - -- **This guide:** `evmd/docs/POA_ADD_VALIDATOR_VIA_GOV.md` -- **Example proposal (template):** `evmd/docs/poa_add_validator_proposal.json` — replace `authority`, `validator_address`, and `pubkey` with your values from Steps 1–2. +Proposal template: `evmd/docs/poa_add_validator_proposal.json` (fill in your values from Steps 1 and 2) --- -## How PoA prevents direct validator changes - -Under PoA (Proof of Authority), **normal staking is disabled** so the validator set is controlled only by governance: +## How PoA works -- The PoA **ante decorator** rejects any Cosmos tx that contains: - - `MsgDelegate` - - `MsgUndelegate` - - `MsgBeginRedelegate` - - `MsgCancelUnbondingDelegation` -- So users **cannot** delegate, undelegate, redelegate, or cancel unbonding. The validator set and delegations cannot be changed through regular txs. -- **Adding a validator** is only possible via a **governance proposal** whose message is `MsgAddValidator` with **authority** = gov module. When the proposal passes, the PoA module mints initial stake and creates the validator; it does **not** use a user’s self-bond or delegation. +Under PoA (Proof of Authority), normal staking is disabled. The validator set is controlled only through governance. -So “direct” validator creation (e.g. a user sending create-validator with their own funds) is not the path here; the only supported path is **gov proposal → MsgAddValidator**. +The PoA ante decorator rejects any transaction that contains these message types: -### How to test that PoA is active +- `MsgDelegate` +- `MsgUndelegate` +- `MsgBeginRedelegate` +- `MsgCancelUnbondingDelegation` -Before running the add-validator flow, you can confirm PoA is blocking delegation: +This means nobody can delegate, undelegate, or redelegate through regular transactions. The only way to add a validator is through a governance proposal using `MsgAddValidator`. When the proposal passes, the PoA module mints the initial stake and creates the validator on its own. It does not rely on a user's self-bond or delegation. -1. **Delegate (should fail)** - With the chain running and keys/chain-id matching your setup (e.g. `--home ~/.og-evm-devnet --chain-id 10740 --keyring-backend test`): +--- - ```bash - VALIDATOR=$(evmd query staking validators --home ~/.og-evm-devnet -o json 2>/dev/null | sed -n '/^{/,$ p' | jq -r '.validators[0].operator_address') - evmd tx staking delegate "$VALIDATOR" 1000000ogwei --from dev0 --keyring-backend test --home ~/.og-evm-devnet --chain-id 10740 -y - ``` +## Prerequisites - **Expected:** The tx is **rejected** with an error containing **`tx type not allowed`**. That indicates the PoA ante is active and delegation is blocked. +- The chain is running. You can start it from the repo root with `./local_node.sh -y`. +- The examples in this guide use the devnet defaults: home directory `~/.og-evm-devnet`, chain ID `10740`, and the test keyring. Adjust these if your setup is different. See the "Notes for mainnet" section at the bottom for production differences. +- `jq` is helpful for parsing JSON output but not strictly required. +- `cometbft` CLI is needed for generating the consensus key in Step 2b. This guide was tested with cometbft v0.38.x. If you don't have it installed, follow the official install guide: https://docs.cometbft.com/v0.38/guides/install -2. **Optional — other Cosmos txs still work** - For example, a bank send should succeed; only the staking messages above are blocked. +### Quick check: is PoA active? -Once you’ve confirmed that, you can safely follow the steps below to add a validator via governance. +Before going through the full flow, you can verify that PoA is actually blocking delegation. Try sending a delegate transaction (it should fail): ---- +```bash +VALIDATOR=$(ogd query staking validators \ + --home ~/.og-evm-devnet -o json 2>/dev/null \ + | sed -n '/^{/,$ p' \ + | jq -r '.validators[0].operator_address') -**Prerequisites** +ogd tx staking delegate "$VALIDATOR" 1000000ogwei \ + --from dev0 \ + --keyring-backend test \ + --home ~/.og-evm-devnet \ + --chain-id 10740 \ + --gas-prices 300000ogwei \ + --gas 300000 \ + -y +``` -- Chain is running (e.g. from repo root: `./local_node.sh -y`). -- All commands below use: `--home ~/.og-evm-devnet --chain-id 10740 --keyring-backend test`. -- `jq` is optional but helpful for parsing; otherwise copy values from the command output. +You should see an error with `tx type not allowed`. That confirms the PoA ante decorator is working. Other transactions like bank sends will still go through normally. --- -## Step 1. Get the gov module address (authority) +## Step 1. Get the governance module address -Run: +Every governance proposal needs an `authority`, which is the address of the gov module. Query it like this: ```bash -evmd query auth module-account gov --home ~/.og-evm-devnet -o json +ogd query auth module-account gov \ + --home ~/.og-evm-devnet -o json 2>/dev/null \ + | sed -n '/^{/,$ p' \ + | jq -r '.account.value.address' ``` -In the output, ignore any lines like `=== REGISTERING TEE PRECOMPILE ===`. Find the JSON object and copy **`account.value.address`** (e.g. `og10d07y265gmmuvt4z0w9aw880jnsr700jrdya3k`). This is the **authority** for the proposal message. +You should get something like `og10d07y265gmmuvt4z0w9aw880jnsr700jrdya3k`. Save this value, you will need it as the `authority` field in the proposal JSON. -With jq (only the JSON line is parsed; if your evmd prints extra lines, copy the JSON block to a file first or use the next command): +> **Note:** `ogd` sometimes prints extra lines like `=== REGISTERING TEE PRECOMPILE ===` before the JSON. The `sed` command above filters those out. If you're not using jq, just look for the JSON block in the output and copy the address from `account.value.address`. -```bash -evmd query auth module-account gov --home ~/.og-evm-devnet -o json 2>/dev/null | sed -n '/^{/,$ p' | jq -r '.account.value.address' -``` +--- -Save this as **GOV_AUTHORITY** for the proposal. +## Step 2. Create the new validator's keys ---- +A validator in the Cosmos ecosystem needs two separate keys: -## Step 2. Create the new validator account and consensus key +- An **account key** (Step 2a): this is the validator's on-chain identity, a regular bech32 address. +- A **consensus key** (Step 2b): this is an ed25519 key that the validator uses to sign blocks. It is different from the account key. You will need this consensus key later in the proposal JSON. -### 2a. Validator account (bech32 address) +### 2a. Validator account -Add a key that will be the new validator’s account. **Do not fund this address.** +Create a new key for the validator. The PoA module expects a fresh account, so do not fund this address. If the address already has funds or an existing validator record, the proposal will fail. ```bash -evmd keys add newvalidator --keyring-backend test --home ~/.og-evm-devnet --no-backup +ogd keys add newvalidator \ + --keyring-backend test \ + --home ~/.og-evm-devnet \ + --no-backup ``` -From the output, copy the **address** (e.g. `og1...`). This is **validator_address** in the proposal. The account must have no balance, no existing validator, and no delegations/unbonding when the proposal runs. +> The `--no-backup` flag skips showing the mnemonic. This is fine for devnet/testing but you should back up the mnemonic for any real deployment. -### 2b. Consensus pubkey (ed25519) +Copy the `address` from the output (looks like `og1...`). This will be the `validator_address` in the proposal. -The chain expects a **consensus** key (ed25519), not the account key. Generate it in a **temporary directory** (do not use the running node’s config): +### 2b. Consensus key -```bash -mkdir -p /tmp/poa-consensus-keys && cd /tmp/poa-consensus-keys -cometbft gen-validator -``` +The consensus key is what the validator actually uses to participate in consensus and sign blocks. In Cosmos chains, this is always an ed25519 key, separate from the account key you created above. -`cometbft gen-validator` prints JSON to stdout. Find the **`pub_key.value`** field (a base64 string). Example: +Generate one using the `cometbft` CLI: -```json -"pub_key": {"type": "tendermint/PubKeyEd25519", "value": "aHlSZw+054g3XnuDblDq6TafZrXVK7xGuk9081g1FAk="} +```bash +cometbft gen-validator | jq -r '.Key.pub_key.value' ``` -Copy the **base64 value** (e.g. `aHlSZw+054g3XnuDblDq6TafZrXVK7xGuk9081g1FAk=`). You will use it in the proposal as the ed25519 pubkey. +This prints just the consensus key value you need. Copy it. You will plug this into the proposal JSON in the next step. -Optional: clean up the temp dir so no validator keys remain: +> **Heads up:** Every time you run `cometbft gen-validator`, it generates a new key. If you run it again, you will get a different key. So copy the value the first time and save it somewhere. -```bash -rm -rf /tmp/poa-consensus-keys -``` +If you want to see the full output including the private key, run `cometbft gen-validator | jq '.'` instead. The consensus key is the `value` string inside `Key.pub_key`. + +> **Important:** In a production setup, the consensus key's private portion must be securely stored on the machine that will actually run the validator node. For this devnet walkthrough, you only need the public key for the proposal. --- ## Step 3. Build the proposal JSON -Create a file (e.g. `proposal.json`) with this structure, or copy and edit the repo example **`evmd/docs/poa_add_validator_proposal.json`**. Replace: +Now put together the governance proposal. You can either create a new file or copy and edit the template at `evmd/docs/poa_add_validator_proposal.json`. + +Fill in the three values you collected: + +- `authority`: the gov module address from Step 1 +- `validator_address`: the new validator's account address from Step 2a +- `key` (inside `pubkey`): the consensus key from Step 2b -- **authority** → gov module address from Step 1 -- **validator_address** → new validator account address from Step 2a -- **key** (inside pubkey) → base64 value from Step 2b +`moniker` is the validator's display name. The other description fields (`identity`, `website`, `security_contact`, `details`) are optional and can be left empty. ```json { @@ -133,7 +139,7 @@ Create a file (e.g. `proposal.json`) with this structure, or copy and edit the r }, "pubkey": { "@type": "/cosmos.crypto.ed25519.PubKey", - "key": "" + "key": "" } } ], @@ -145,132 +151,105 @@ Create a file (e.g. `proposal.json`) with this structure, or copy and edit the r } ``` -Example with real-looking values: - -```json -{ - "messages": [ - { - "@type": "/poa.MsgAddValidator", - "authority": "og10d07y265gmmuvt4z0w9aw880jnsr700jrdya3k", - "validator_address": "og1xu4krmxl40ec0vlfx3lk38hkj0scw8z79ck225", - "description": { - "moniker": "newvalidator", - "identity": "", - "website": "", - "security_contact": "", - "details": "" - }, - "pubkey": { - "@type": "/cosmos.crypto.ed25519.PubKey", - "key": "aHlSZw+054g3XnuDblDq6TafZrXVK7xGuk9081g1FAk=" - } - } - ], - "metadata": "Add PoA validator", - "deposit": "10000000ogwei", - "title": "Add validator", - "summary": "Add a second validator via PoA governance", - "expedited": false -} -``` +Save this as `proposal.json` (or whatever name you prefer). --- ## Step 4. Submit the proposal -Use **enough gas** (e.g. 500000) so the tx does not run out of gas. From repo root you can use the example file: +Submit the proposal with enough gas. The chain uses EIP-1559 style fee pricing, so the base fee can rise over time. A gas price of `300000ogwei` works on devnet. For mainnet values, see the "Notes for mainnet" section below. ```bash -evmd tx gov submit-proposal evmd/docs/poa_add_validator_proposal.json \ +ogd tx gov submit-proposal proposal.json \ --from dev0 \ - --gas-prices 3000ogwei \ + --gas-prices 300000ogwei \ --gas 500000 \ --home ~/.og-evm-devnet \ --chain-id 10740 \ - -y \ - --keyring-backend test + --keyring-backend test \ + -y ``` -Or use your own file (e.g. `proposal.json`) after replacing authority, validator_address, and pubkey: +Note the proposal ID from the output. You can also list all proposals to find it: ```bash -evmd tx gov submit-proposal proposal.json \ - --from dev0 \ - --gas-prices 3000ogwei \ - --gas 500000 \ - --home ~/.og-evm-devnet \ - --chain-id 10740 \ - -y \ - --keyring-backend test +ogd query gov proposals \ + --home ~/.og-evm-devnet -o json 2>/dev/null \ + | sed -n '/^{/,$ p' \ + | jq '.proposals[-1].id' ``` -Note the **proposal id** from the output (or list proposals): - -```bash -evmd query gov proposals --home ~/.og-evm-devnet -o json -``` - -Again, if output has non-JSON lines, use only the JSON part when parsing. The latest proposal’s `id` is the one you need. - --- ## Step 5. Vote -Vote **soon** after the proposal enters the voting period (with `local_node.sh`, voting period is 30s). Use the key that has staking power (e.g. `mykey`): +Vote yes as soon as possible. With `local_node.sh`, the voting period is only 30 seconds, so you need to be quick. + +Use the key that has staking power (on the devnet, that's `mykey`, not `dev0`): ```bash -evmd tx gov vote yes \ +ogd tx gov vote yes \ --from mykey \ - --gas-prices 3000ogwei \ + --gas-prices 300000ogwei \ --gas 300000 \ --home ~/.og-evm-devnet \ --chain-id 10740 \ - -y \ - --keyring-backend test + --keyring-backend test \ + -y ``` -Replace `` with the id from Step 4 (e.g. `1` or `2`). +Replace `` with the ID from Step 4. + +> **Why `mykey` and not `dev0`?** Only accounts with staking power (existing validators or their delegators) can cast votes that count toward the tally. On the devnet, `mykey` is the initial validator's key. --- ## Step 6. Wait and verify -Wait for the voting period to end (e.g. 30–35 seconds with `local_node.sh`). Then check the proposal status: +Wait about 35 seconds for the voting period to end, then check the proposal status: ```bash -evmd query gov proposal --home ~/.og-evm-devnet +ogd query gov proposal --home ~/.og-evm-devnet ``` -You should see **status: PROPOSAL_STATUS_PASSED**. +You should see `status: PROPOSAL_STATUS_PASSED`. -List validators to confirm the new one is in the set: +Now list the validators: ```bash -evmd query staking validators --home ~/.og-evm-devnet -o json +ogd query staking validators --home ~/.og-evm-devnet -o json 2>/dev/null \ + | sed -n '/^{/,$ p' \ + | jq '[.validators[] | {moniker: .description.moniker, status: .status}]' ``` -You should see **two** validators: the original and the new one (moniker e.g. `newvalidator`). +You should see two validators: the original one and the new one (with moniker `newvalidator`). + +> **What happens next?** The validator is now registered on-chain, but for it to actually produce blocks, a node needs to be running with the matching consensus private key in its `config/priv_validator_key.json`. On devnet this does not matter since you are just testing the governance flow. --- ## Troubleshooting | Issue | What to check | -|-------|----------------| -| jq parse error | evmd may print TEE/precompile lines before JSON. Use only the JSON part (e.g. copy from first `{` to last `}`) or use `sed -n '/^{/,$ p'` before piping to jq. | -| Submit out of gas | Use `--gas 500000` (or higher) on submit-proposal. | -| Vote: "inactive proposal" | Voting period (30s) ended before your vote was included. Submit a new proposal and vote immediately. | -| Execution fails | Ensure the new validator account has **no** balance, no existing validator, and no delegations/unbonding. | +|-------|---------------| +| jq parse error | `ogd` sometimes prints TEE/precompile log lines before the JSON. Use `sed -n '/^{/,$ p'` to filter them out, or just copy the JSON block manually. | +| Submit fails with out of gas | Increase `--gas` (try 500000 or higher). | +| Submit fails with gas price too low | The EIP-1559 base fee rises over time. Increase `--gas-prices` (try 300000ogwei or higher). | +| Vote says "inactive proposal" | The 30s voting period ended before your vote landed. Submit a new proposal and vote right away. | +| Proposal execution fails | Make sure the new validator account has no balance, no existing validator record, and no delegations. | +| Key already exists | You already created a key with that name. Use `ogd keys delete newvalidator --keyring-backend test --home ~/.og-evm-devnet` or pick a different name. | --- -## Quick reference +## Notes for mainnet + +This guide is written for a local devnet. If you are doing this on mainnet, a few things will be different: -- **Gov authority:** `evmd query auth module-account gov --home ~/.og-evm-devnet -o json` → `account.value.address` -- **New validator address:** `evmd keys add newvalidator ...` → address in output -- **Consensus pubkey:** `cometbft gen-validator` in a temp dir → `pub_key.value` (base64) -- **Proposal:** One message `@type: /poa.MsgAddValidator` with authority, validator_address, description, pubkey; deposit `10000000ogwei` -- **Submit:** `evmd tx gov submit-proposal evmd/docs/poa_add_validator_proposal.json --from dev0 --gas 500000 ...` (from repo root; or use your own `proposal.json`) -- **Vote:** `evmd tx gov vote yes --from mykey ...` -- **Verify:** `evmd query staking validators --home ~/.og-evm-devnet` +- **Keyring backend.** You would not use `--keyring-backend test` on mainnet. Use `os` or `file` instead, and make sure you have the passphrase ready. The test backend stores keys unencrypted and is not safe for real funds. +- **Chain ID and home directory.** Replace `--chain-id 10740` and `--home ~/.og-evm-devnet` with your actual mainnet chain ID and node home directory. +- **Voting period.** On mainnet the voting period is much longer (days, not 30 seconds). You don't need to rush the vote. Coordinate with other validators to make sure the proposal reaches quorum. +- **Gas prices.** The base fee on mainnet will be different from devnet. Check current gas prices before submitting. You can use `ogd query feemarket base-fee` to see the current base fee. +- **Consensus key security.** On devnet we only care about the public key for the proposal. On mainnet, the private key must live on the validator machine in a secure location (typically `config/priv_validator_key.json`). Treat it like a password. If someone gets your consensus private key, they can double-sign on your behalf and get your validator slashed. +- **Validator account.** On mainnet, back up the mnemonic when creating the validator key. Do not use `--no-backup`. +- **Deposit amount.** The minimum deposit for a proposal may differ on mainnet. Check your chain's gov params with `ogd query gov params`. +- **Who submits and who votes.** On devnet we use `dev0` to submit and `mykey` to vote because that is how the local setup is configured. On mainnet, any funded account can submit a proposal, and all validators (or their delegators) with staking power can vote. diff --git a/evmd/docs/poa_add_validator_proposal.json b/evmd/docs/poa_add_validator_proposal.json index 5b7ce72b..372fcbb0 100644 --- a/evmd/docs/poa_add_validator_proposal.json +++ b/evmd/docs/poa_add_validator_proposal.json @@ -2,8 +2,8 @@ "messages": [ { "@type": "/poa.MsgAddValidator", - "authority": "og10d07y265gmmuvt4z0w9aw880jnsr700jrdya3k", - "validator_address": "og1warvjhukk7th2xprz7mhfa48h32cfm9jw5dl0c", + "authority": "", + "validator_address": "", "description": { "moniker": "newvalidator", "identity": "", @@ -13,7 +13,7 @@ }, "pubkey": { "@type": "/cosmos.crypto.ed25519.PubKey", - "key": "aHlSZw+054g3XnuDblDq6TafZrXVK7xGuk9081g1FAk=" + "key": "" } } ], From 9982214b68c23fbe17ddf88c853fa7cfd1a0f7ae Mon Sep 17 00:00:00 2001 From: Yogesh Shahi Date: Sun, 15 Mar 2026 04:04:28 +0530 Subject: [PATCH 4/6] fix(docker): add entrypoint and start command to localnet nodes --- Makefile | 2 +- docker-compose.yml | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 367e7ffe..1d257eb1 100644 --- a/Makefile +++ b/Makefile @@ -365,7 +365,7 @@ localnet-build-env: $(MAKE) -C contrib/images evmd-env localnet-build-nodes: - $(DOCKER) run --rm -v $(CURDIR)/.testnets:/data cosmos/evmd \ + $(DOCKER) run --rm --entrypoint evmd -v $(CURDIR)/.testnets:/data cosmos/ogd \ testnet init-files --validator-count 4 -o /data --starting-ip-address 192.168.10.2 --keyring-backend=test --chain-id=local-4221 --use-docker=true docker compose up -d diff --git a/docker-compose.yml b/docker-compose.yml index a02f9489..c8372325 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,6 +4,8 @@ services: evmdnode0: container_name: evmdnode0 image: "cosmos/evmd" + entrypoint: ["/usr/bin/wrapper.sh"] + command: ["start", "--chain-id", "local-4221", "--json-rpc.api", "eth,txpool,personal,net,debug,web3"] environment: - DEBUG=0 - ID=0 @@ -28,6 +30,8 @@ services: evmdnode1: container_name: evmdnode1 image: "cosmos/evmd" + entrypoint: ["/usr/bin/wrapper.sh"] + command: ["start", "--chain-id", "local-4221", "--json-rpc.api", "eth,txpool,personal,net,debug,web3"] environment: - DEBUG=0 - ID=1 @@ -52,6 +56,8 @@ services: evmdnode2: container_name: evmdnode2 image: "cosmos/evmd" + entrypoint: ["/usr/bin/wrapper.sh"] + command: ["start", "--chain-id", "local-4221", "--json-rpc.api", "eth,txpool,personal,net,debug,web3"] environment: - DEBUG=0 - ID=2 @@ -76,6 +82,8 @@ services: evmdnode3: container_name: evmdnode3 image: "cosmos/evmd" + entrypoint: ["/usr/bin/wrapper.sh"] + command: ["start", "--chain-id", "local-4221", "--json-rpc.api", "eth,txpool,personal,net,debug,web3"] environment: - DEBUG=0 - ID=3 From 552fc72b69792afc76460d728e5778fad1358b3d Mon Sep 17 00:00:00 2001 From: "balogh.adam@icloud.com" Date: Mon, 16 Mar 2026 19:52:14 -0400 Subject: [PATCH 5/6] revert to evmd --- Makefile | 2 +- evmd/docs/POA_ADD_VALIDATOR_VIA_GOV.md | 28 +++++++++++++------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Makefile b/Makefile index 1d257eb1..cdae709f 100644 --- a/Makefile +++ b/Makefile @@ -365,7 +365,7 @@ localnet-build-env: $(MAKE) -C contrib/images evmd-env localnet-build-nodes: - $(DOCKER) run --rm --entrypoint evmd -v $(CURDIR)/.testnets:/data cosmos/ogd \ + $(DOCKER) run --rm --entrypoint evmd -v $(CURDIR)/.testnets:/data cosmos/evmd \ testnet init-files --validator-count 4 -o /data --starting-ip-address 192.168.10.2 --keyring-backend=test --chain-id=local-4221 --use-docker=true docker compose up -d diff --git a/evmd/docs/POA_ADD_VALIDATOR_VIA_GOV.md b/evmd/docs/POA_ADD_VALIDATOR_VIA_GOV.md index 8f51832d..0a6cef86 100644 --- a/evmd/docs/POA_ADD_VALIDATOR_VIA_GOV.md +++ b/evmd/docs/POA_ADD_VALIDATOR_VIA_GOV.md @@ -33,12 +33,12 @@ This means nobody can delegate, undelegate, or redelegate through regular transa Before going through the full flow, you can verify that PoA is actually blocking delegation. Try sending a delegate transaction (it should fail): ```bash -VALIDATOR=$(ogd query staking validators \ +VALIDATOR=$(evmd query staking validators \ --home ~/.og-evm-devnet -o json 2>/dev/null \ | sed -n '/^{/,$ p' \ | jq -r '.validators[0].operator_address') -ogd tx staking delegate "$VALIDATOR" 1000000ogwei \ +evmd tx staking delegate "$VALIDATOR" 1000000ogwei \ --from dev0 \ --keyring-backend test \ --home ~/.og-evm-devnet \ @@ -57,7 +57,7 @@ You should see an error with `tx type not allowed`. That confirms the PoA ante d Every governance proposal needs an `authority`, which is the address of the gov module. Query it like this: ```bash -ogd query auth module-account gov \ +evmd query auth module-account gov \ --home ~/.og-evm-devnet -o json 2>/dev/null \ | sed -n '/^{/,$ p' \ | jq -r '.account.value.address' @@ -65,7 +65,7 @@ ogd query auth module-account gov \ You should get something like `og10d07y265gmmuvt4z0w9aw880jnsr700jrdya3k`. Save this value, you will need it as the `authority` field in the proposal JSON. -> **Note:** `ogd` sometimes prints extra lines like `=== REGISTERING TEE PRECOMPILE ===` before the JSON. The `sed` command above filters those out. If you're not using jq, just look for the JSON block in the output and copy the address from `account.value.address`. +> **Note:** `evmd` sometimes prints extra lines like `=== REGISTERING TEE PRECOMPILE ===` before the JSON. The `sed` command above filters those out. If you're not using jq, just look for the JSON block in the output and copy the address from `account.value.address`. --- @@ -81,7 +81,7 @@ A validator in the Cosmos ecosystem needs two separate keys: Create a new key for the validator. The PoA module expects a fresh account, so do not fund this address. If the address already has funds or an existing validator record, the proposal will fail. ```bash -ogd keys add newvalidator \ +evmd keys add newvalidator \ --keyring-backend test \ --home ~/.og-evm-devnet \ --no-backup @@ -160,7 +160,7 @@ Save this as `proposal.json` (or whatever name you prefer). Submit the proposal with enough gas. The chain uses EIP-1559 style fee pricing, so the base fee can rise over time. A gas price of `300000ogwei` works on devnet. For mainnet values, see the "Notes for mainnet" section below. ```bash -ogd tx gov submit-proposal proposal.json \ +evmd tx gov submit-proposal proposal.json \ --from dev0 \ --gas-prices 300000ogwei \ --gas 500000 \ @@ -173,7 +173,7 @@ ogd tx gov submit-proposal proposal.json \ Note the proposal ID from the output. You can also list all proposals to find it: ```bash -ogd query gov proposals \ +evmd query gov proposals \ --home ~/.og-evm-devnet -o json 2>/dev/null \ | sed -n '/^{/,$ p' \ | jq '.proposals[-1].id' @@ -188,7 +188,7 @@ Vote yes as soon as possible. With `local_node.sh`, the voting period is only 30 Use the key that has staking power (on the devnet, that's `mykey`, not `dev0`): ```bash -ogd tx gov vote yes \ +evmd tx gov vote yes \ --from mykey \ --gas-prices 300000ogwei \ --gas 300000 \ @@ -209,7 +209,7 @@ Replace `` with the ID from Step 4. Wait about 35 seconds for the voting period to end, then check the proposal status: ```bash -ogd query gov proposal --home ~/.og-evm-devnet +evmd query gov proposal --home ~/.og-evm-devnet ``` You should see `status: PROPOSAL_STATUS_PASSED`. @@ -217,7 +217,7 @@ You should see `status: PROPOSAL_STATUS_PASSED`. Now list the validators: ```bash -ogd query staking validators --home ~/.og-evm-devnet -o json 2>/dev/null \ +evmd query staking validators --home ~/.og-evm-devnet -o json 2>/dev/null \ | sed -n '/^{/,$ p' \ | jq '[.validators[] | {moniker: .description.moniker, status: .status}]' ``` @@ -232,12 +232,12 @@ You should see two validators: the original one and the new one (with moniker `n | Issue | What to check | |-------|---------------| -| jq parse error | `ogd` sometimes prints TEE/precompile log lines before the JSON. Use `sed -n '/^{/,$ p'` to filter them out, or just copy the JSON block manually. | +| jq parse error | `evmd` sometimes prints TEE/precompile log lines before the JSON. Use `sed -n '/^{/,$ p'` to filter them out, or just copy the JSON block manually. | | Submit fails with out of gas | Increase `--gas` (try 500000 or higher). | | Submit fails with gas price too low | The EIP-1559 base fee rises over time. Increase `--gas-prices` (try 300000ogwei or higher). | | Vote says "inactive proposal" | The 30s voting period ended before your vote landed. Submit a new proposal and vote right away. | | Proposal execution fails | Make sure the new validator account has no balance, no existing validator record, and no delegations. | -| Key already exists | You already created a key with that name. Use `ogd keys delete newvalidator --keyring-backend test --home ~/.og-evm-devnet` or pick a different name. | +| Key already exists | You already created a key with that name. Use `evmd keys delete newvalidator --keyring-backend test --home ~/.og-evm-devnet` or pick a different name. | --- @@ -248,8 +248,8 @@ This guide is written for a local devnet. If you are doing this on mainnet, a fe - **Keyring backend.** You would not use `--keyring-backend test` on mainnet. Use `os` or `file` instead, and make sure you have the passphrase ready. The test backend stores keys unencrypted and is not safe for real funds. - **Chain ID and home directory.** Replace `--chain-id 10740` and `--home ~/.og-evm-devnet` with your actual mainnet chain ID and node home directory. - **Voting period.** On mainnet the voting period is much longer (days, not 30 seconds). You don't need to rush the vote. Coordinate with other validators to make sure the proposal reaches quorum. -- **Gas prices.** The base fee on mainnet will be different from devnet. Check current gas prices before submitting. You can use `ogd query feemarket base-fee` to see the current base fee. +- **Gas prices.** The base fee on mainnet will be different from devnet. Check current gas prices before submitting. You can use `evmd query feemarket base-fee` to see the current base fee. - **Consensus key security.** On devnet we only care about the public key for the proposal. On mainnet, the private key must live on the validator machine in a secure location (typically `config/priv_validator_key.json`). Treat it like a password. If someone gets your consensus private key, they can double-sign on your behalf and get your validator slashed. - **Validator account.** On mainnet, back up the mnemonic when creating the validator key. Do not use `--no-backup`. -- **Deposit amount.** The minimum deposit for a proposal may differ on mainnet. Check your chain's gov params with `ogd query gov params`. +- **Deposit amount.** The minimum deposit for a proposal may differ on mainnet. Check your chain's gov params with `evmd query gov params`. - **Who submits and who votes.** On devnet we use `dev0` to submit and `mykey` to vote because that is how the local setup is configured. On mainnet, any funded account can submit a proposal, and all validators (or their delegators) with staking power can vote. From 7837d419e7e8c9e4924005550bb2134b787448e4 Mon Sep 17 00:00:00 2001 From: "balogh.adam@icloud.com" Date: Mon, 16 Mar 2026 21:15:36 -0400 Subject: [PATCH 6/6] cosmosdk core dep replace --- go.mod | 2 ++ go.sum | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 69b8b6d9..114891fd 100644 --- a/go.mod +++ b/go.mod @@ -311,6 +311,8 @@ require ( ) replace ( + // pin core to v0.11.3 — xrplevm/node pulls in v0.12.0 which breaks cosmos-sdk v0.54 + cosmossdk.io/core => cosmossdk.io/core v0.11.3 // use cosmos fork of keyring github.com/99designs/keyring => github.com/cosmos/keyring v1.2.0 github.com/cosmos/ibc-go/v10 => github.com/cosmos/ibc-go/v10 v10.0.0-beta.0.0.20251216200936-98a683ee20a3 diff --git a/go.sum b/go.sum index bc056c44..3b72ff3f 100644 --- a/go.sum +++ b/go.sum @@ -26,8 +26,8 @@ cosmossdk.io/api v0.9.2 h1:9i9ptOBdmoIEVEVWLtYYHjxZonlF/aOVODLFaxpmNtg= cosmossdk.io/api v0.9.2/go.mod h1:CWt31nVohvoPMTlPv+mMNCtC0a7BqRdESjCsstHcTkU= cosmossdk.io/collections v1.3.1 h1:09e+DUId2brWsNOQ4nrk+bprVmMUaDH9xvtZkeqIjVw= cosmossdk.io/collections v1.3.1/go.mod h1:ynvkP0r5ruAjbmedE+vQ07MT6OtJ0ZIDKrtJHK7Q/4c= -cosmossdk.io/core v0.12.0 h1:aFuvkG6eDv0IQC+UDjx86wxNWVAxdCFk7OABJ1Vh4RU= -cosmossdk.io/core v0.12.0/go.mod h1:LaTtayWBSoacF5xNzoF8tmLhehqlA9z1SWiPuNC6X1w= +cosmossdk.io/core v0.11.3 h1:mei+MVDJOwIjIniaKelE3jPDqShCc/F4LkNNHh+4yfo= +cosmossdk.io/core v0.11.3/go.mod h1:9rL4RE1uDt5AJ4Tg55sYyHWXA16VmpHgbe0PbJc6N2Y= cosmossdk.io/depinject v1.2.1 h1:eD6FxkIjlVaNZT+dXTQuwQTKZrFZ4UrfCq1RKgzyhMw= cosmossdk.io/depinject v1.2.1/go.mod h1:lqQEycz0H2JXqvOgVwTsjEdMI0plswI7p6KX+MVqFOM= cosmossdk.io/errors v1.0.2 h1:wcYiJz08HThbWxd/L4jObeLaLySopyyuUFB5w4AGpCo=