diff --git a/go.mod b/go.mod index b8c8ac122d25..b77a2fe25ac6 100644 --- a/go.mod +++ b/go.mod @@ -181,6 +181,7 @@ require ( replace ( // use cosmos fork of keyring github.com/99designs/keyring => github.com/cosmos/keyring v1.2.0 + github.com/cometbft/cometbft => github.com/osmosis-labs/cometbft v0.0.0-20240103055822-28da358e3146 // dgrijalva/jwt-go is deprecated and doesn't receive security updates. // TODO: remove it: https://github.com/cosmos/cosmos-sdk/issues/13134 github.com/dgrijalva/jwt-go => github.com/golang-jwt/jwt/v4 v4.4.2 diff --git a/go.sum b/go.sum index f827f8cff5d1..6b8df5b084ab 100644 --- a/go.sum +++ b/go.sum @@ -312,8 +312,6 @@ github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZ github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/coinbase/rosetta-sdk-go/types v1.0.0 h1:jpVIwLcPoOeCR6o1tU+Xv7r5bMONNbHU7MuEHboiFuA= github.com/coinbase/rosetta-sdk-go/types v1.0.0/go.mod h1:eq7W2TMRH22GTW0N0beDnN931DW0/WOI1R2sdHNHG4c= -github.com/cometbft/cometbft v0.37.2 h1:XB0yyHGT0lwmJlFmM4+rsRnczPlHoAKFX6K8Zgc2/Jc= -github.com/cometbft/cometbft v0.37.2/go.mod h1:Y2MMMN//O5K4YKd8ze4r9jmk4Y7h0ajqILXbH5JQFVs= github.com/cometbft/cometbft-db v0.7.0 h1:uBjbrBx4QzU0zOEnU8KxoDl18dMNgDh+zZRUE0ucsbo= github.com/cometbft/cometbft-db v0.7.0/go.mod h1:yiKJIm2WKrt6x8Cyxtq9YTEcIMPcEe4XPxhgX59Fzf0= github.com/confio/ics23/go v0.9.0 h1:cWs+wdbS2KRPZezoaaj+qBleXgUk5WOQFMP3CQFGTr4= @@ -806,6 +804,8 @@ github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJ github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA= +github.com/osmosis-labs/cometbft v0.0.0-20240103055822-28da358e3146 h1:Qkshh58fZCRoHSzbyW8NJf1wBhf9bg1MPFZEuyuI9lE= +github.com/osmosis-labs/cometbft v0.0.0-20240103055822-28da358e3146/go.mod h1:Y2MMMN//O5K4YKd8ze4r9jmk4Y7h0ajqILXbH5JQFVs= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= diff --git a/server/mock/store.go b/server/mock/store.go index 192c58e5526e..45624f159c84 100644 --- a/server/mock/store.go +++ b/server/mock/store.go @@ -160,6 +160,10 @@ func (ms multiStore) LatestVersion() int64 { panic("not implemented") } +func (ms multiStore) GetCommitInfo(key int64) (*storetypes.CommitInfo, error) { + panic("not implemented") +} + var _ sdk.KVStore = kvStore{} type kvStore struct { diff --git a/server/start.go b/server/start.go index 061b736cf6a5..374dc5e98572 100644 --- a/server/start.go +++ b/server/start.go @@ -9,6 +9,8 @@ import ( "net/http" "os" "runtime/pprof" + "sort" + "strings" "time" "github.com/cometbft/cometbft/abci/server" @@ -22,6 +24,8 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" + "encoding/hex" + "cosmossdk.io/tools/rosetta" crgserver "cosmossdk.io/tools/rosetta/lib/server" "github.com/cosmos/cosmos-sdk/client" @@ -32,6 +36,7 @@ import ( servergrpc "github.com/cosmos/cosmos-sdk/server/grpc" "github.com/cosmos/cosmos-sdk/server/types" pruningtypes "github.com/cosmos/cosmos-sdk/store/pruning/types" + storetypes "github.com/cosmos/cosmos-sdk/store/types" "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/mempool" @@ -334,6 +339,18 @@ func startInProcess(ctx *Context, clientCtx client.Context, appCreator types.App if err := tmNode.Start(); err != nil { return err } + + // Start a goroutine to listen for appHash errors from consensus layer. + go func() { + for appHashError := range tmNode.BCReactor().AppHashErrorsCh() { + // If an error is received, call returnCommitInfo + if appHashError.Err != nil { + if commitInfoErr := returnCommitInfo(ctx, app, int64(appHashError.Height)); commitInfoErr != nil { + ctx.Logger.Error("failed to return commit info", "err", commitInfoErr) + } + } + } + }() } // Add the tx service to the gRPC router. We only need to register this @@ -566,3 +583,42 @@ func wrapCPUProfile(ctx *Context, callback func() error) error { return WaitForQuitSignals() } + +// returnCommitInfo returns the individual app hashes for every module given a version (height). +func returnCommitInfo(ctx *Context, app types.Application, version int64) error { + commitInfoForHeight, err := app.CommitMultiStore().GetCommitInfo(version) + if err != nil { + return err + } + + // Create a new slice of StoreInfos for storing the modified hashes. + storeInfos := make([]storetypes.StoreInfo, len(commitInfoForHeight.StoreInfos)) + + for i, storeInfo := range commitInfoForHeight.StoreInfos { + // Convert the hash to a hexadecimal string. + hash := strings.ToUpper(hex.EncodeToString(storeInfo.CommitId.Hash)) + + // Create a new StoreInfo with the modified hash. + storeInfos[i] = storetypes.StoreInfo{ + Name: storeInfo.Name, + CommitId: storetypes.CommitID{ + Version: storeInfo.CommitId.Version, + Hash: []byte(hash), + }, + } + } + + // Sort the storeInfos slice based on the module name. + sort.Slice(storeInfos, func(i, j int) bool { + return storeInfos[i].Name < storeInfos[j].Name + }) + + // Create a new CommitInfo with the modified StoreInfos. + commitInfoForHeight = &storetypes.CommitInfo{ + Version: commitInfoForHeight.Version, + StoreInfos: storeInfos, + } + + ctx.Logger.Error("your node has app hashed. Compare each module's hashes with a node that did not app hash to determine the problematic module", "commitInfo", commitInfoForHeight.String()) + return nil +} diff --git a/store/types/store.go b/store/types/store.go index 992173195661..01a71306d068 100644 --- a/store/types/store.go +++ b/store/types/store.go @@ -154,6 +154,9 @@ type CommitMultiStore interface { // Panics on a nil key. GetCommitKVStore(key StoreKey) CommitKVStore + // Panics on a nil version. + GetCommitInfo(ver int64) (*CommitInfo, error) + // Load the latest persisted version. Called once after all calls to // Mount*Store() are complete. LoadLatestVersion() error diff --git a/x/consensus/keeper/keeper.go b/x/consensus/keeper/keeper.go index a4a255055bfd..4a7ac9ffe2bc 100644 --- a/x/consensus/keeper/keeper.go +++ b/x/consensus/keeper/keeper.go @@ -56,3 +56,17 @@ func (k *Keeper) Set(ctx sdk.Context, cp *tmproto.ConsensusParams) { store := ctx.KVStore(k.storeKey) store.Set(types.ParamStoreKeyConsensusParams, k.cdc.MustMarshal(cp)) } + +func (k *Keeper) GetParamsNoUnmarshal(ctx sdk.Context) []byte { + store := ctx.KVStore(k.storeKey) + return store.Get(types.ParamStoreKeyConsensusParams) +} + +func (k *Keeper) UnmarshalParamBytes(ctx sdk.Context, bz []byte) (*tmproto.ConsensusParams, error) { + cp := &tmproto.ConsensusParams{} + if err := k.cdc.Unmarshal(bz, cp); err != nil { + return nil, err + } + + return cp, nil +}