Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: make validator key injectable by application developers #21608

Merged
merged 12 commits into from
Sep 18, 2024
10 changes: 10 additions & 0 deletions runtime/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"slices"

abci "github.com/cometbft/cometbft/api/cometbft/abci/v1"
cmtcrypto "github.com/cometbft/cometbft/crypto"
cmted25519 "github.com/cometbft/cometbft/crypto/ed25519"
"google.golang.org/grpc"

runtimev1alpha1 "cosmossdk.io/api/cosmos/app/runtime/v1alpha1"
Expand All @@ -30,6 +32,8 @@ import (
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
)

type KeyGenF = func() (cmtcrypto.PrivKey, error)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we have a godoc here?


// App is a wrapper around BaseApp and ModuleManager that can be used in hybrid
// app.go/app config scenarios or directly as a servertypes.Application instance.
// To get an instance of *App, *AppBuilder must be requested as a dependency
Expand Down Expand Up @@ -308,3 +312,9 @@ var _ servertypes.Application = &App{}
type hasServicesV1 interface {
RegisterServices(grpc.ServiceRegistrar) error
}

func (a *App) ValidatorKeyProvider() KeyGenF {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

go doc here too please

return func() (cmtcrypto.PrivKey, error) {
return cmted25519.GenPrivKey(), nil
}
}
1 change: 1 addition & 0 deletions schema/diff/diff_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,7 @@ func TestCompareModuleSchemas(t *testing.T) {
}

func requireModuleSchema(t *testing.T, types ...schema.Type) schema.ModuleSchema {
t.Helper()
s, err := schema.CompileModuleSchema(types...)
if err != nil {
t.Fatal(err)
Expand Down
4 changes: 1 addition & 3 deletions server/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -374,9 +374,7 @@ func startCmtNode(
return nil, cleanupFn, err
}

pv, err := pvm.LoadOrGenFilePV(cfg.PrivValidatorKeyFile(), cfg.PrivValidatorStateFile(), func() (cmtcrypto.PrivKey, error) {
return cmted25519.GenPrivKey(), nil
}) // TODO: make this modular
pv, err := pvm.LoadOrGenFilePV(cfg.PrivValidatorKeyFile(), cfg.PrivValidatorStateFile(), app.ValidatorKeyProvider())
if err != nil {
return nil, cleanupFn, err
}
Expand Down
4 changes: 4 additions & 0 deletions server/types/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"io"

cmtproto "github.com/cometbft/cometbft/api/cometbft/types/v1"
cmtcrypto "github.com/cometbft/cometbft/crypto"
cmttypes "github.com/cometbft/cometbft/types"
"github.com/cosmos/gogoproto/grpc"

Expand Down Expand Up @@ -57,6 +58,9 @@ type (
// SnapshotManager return the snapshot manager
SnapshotManager() *snapshots.Manager

// ValidatorKeyProvider returns a function that generates a validator key
ValidatorKeyProvider() func() (cmtcrypto.PrivKey, error)

// Close is called in start cmd to gracefully cleanup resources.
// Must be safe to be called multiple times.
Close() error
Expand Down
7 changes: 7 additions & 0 deletions server/v2/cometbft/options.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,26 @@
package cometbft

import (
cmtcrypto "github.com/cometbft/cometbft/crypto"
cmted22519 "github.com/cometbft/cometbft/crypto/ed25519"

"cosmossdk.io/core/transaction"
"cosmossdk.io/server/v2/cometbft/handlers"
"cosmossdk.io/server/v2/cometbft/mempool"
"cosmossdk.io/server/v2/cometbft/types"
"cosmossdk.io/store/v2/snapshots"
)

type keyGenF = func() (cmtcrypto.PrivKey, error)

// ServerOptions defines the options for the CometBFT server.
type ServerOptions[T transaction.Tx] struct {
Mempool mempool.Mempool[T]
PrepareProposalHandler handlers.PrepareHandler[T]
ProcessProposalHandler handlers.ProcessHandler[T]
VerifyVoteExtensionHandler handlers.VerifyVoteExtensionhandler
ExtendVoteHandler handlers.ExtendVoteHandler
KeygenF keyGenF
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really like that it doesn't leak in the app in v2 🙏🏾

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we have a go doc here too? It's less descriptive than the above.


SnapshotOptions snapshots.SnapshotOptions

Expand All @@ -34,5 +40,6 @@ func DefaultServerOptions[T transaction.Tx]() ServerOptions[T] {
SnapshotOptions: snapshots.NewSnapshotOptions(0, 0),
AddrPeerFilter: nil,
IdPeerFilter: nil,
KeygenF: func() (cmtcrypto.PrivKey, error) { return cmted22519.GenPrivKey(), nil },
}
}
6 changes: 1 addition & 5 deletions server/v2/cometbft/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ import (
abciserver "github.com/cometbft/cometbft/abci/server"
cmtcmd "github.com/cometbft/cometbft/cmd/cometbft/commands"
cmtcfg "github.com/cometbft/cometbft/config"
cmtcrypto "github.com/cometbft/cometbft/crypto"
cmted25519 "github.com/cometbft/cometbft/crypto/ed25519"
"github.com/cometbft/cometbft/node"
"github.com/cometbft/cometbft/p2p"
pvm "github.com/cometbft/cometbft/privval"
Expand Down Expand Up @@ -159,9 +157,7 @@ func (s *CometBFTServer[T]) Start(ctx context.Context) error {
pv, err := pvm.LoadOrGenFilePV(
s.config.ConfigTomlConfig.PrivValidatorKeyFile(),
s.config.ConfigTomlConfig.PrivValidatorStateFile(),
func() (cmtcrypto.PrivKey, error) {
return cmted25519.GenPrivKey(), nil
},
s.serverOptions.KeygenF,
)
if err != nil {
return err
Expand Down
10 changes: 10 additions & 0 deletions simapp/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (
"path/filepath"

abci "github.com/cometbft/cometbft/api/cometbft/abci/v1"
cmtcrypto "github.com/cometbft/cometbft/crypto"
cmted25519 "github.com/cometbft/cometbft/crypto/ed25519"
"github.com/cosmos/gogoproto/proto"
"github.com/spf13/cast"

Expand Down Expand Up @@ -831,6 +833,14 @@ func (app *SimApp) RegisterNodeService(clientCtx client.Context, cfg config.Conf
nodeservice.RegisterNodeService(clientCtx, app.GRPCQueryRouter(), cfg)
}

// ValidatorKeyProvider returns a function that generates a validator key
// Supported key types are those supported by Comet: ed25519, secp256k1, bls12-381
func (app *SimApp) ValidatorKeyProvider() runtime.KeyGenF {
return func() (cmtcrypto.PrivKey, error) {
return cmted25519.GenPrivKey(), nil
}
}

// GetMaccPerms returns a copy of the module account permissions
//
// NOTE: This is solely to be used for testing purposes.
Expand Down
4 changes: 2 additions & 2 deletions types/module/simulation.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
// HasProposalContents defines the contents that can be used to simulate legacy governance (v1beta1) proposals
type HasProposalContents interface {
// content functions used to simulate governance proposals
ProposalContents(simState SimulationState) []simulation.WeightedProposalContent //nolint:staticcheck // legacy v1beta1 governance
ProposalContents(simState SimulationState) []simulation.WeightedProposalContent
}

// SimulationManager defines a simulation manager that provides the high level utility
Expand Down Expand Up @@ -158,7 +158,7 @@
GenTimestamp time.Time // genesis timestamp
UnbondTime time.Duration // staking unbond time stored to use it as the slashing maximum evidence duration
LegacyParamChange []simulation.LegacyParamChange // simulated parameter changes from modules
//nolint:staticcheck // legacy used for testing

LegacyProposalContents []simulation.WeightedProposalContent // proposal content generator functions with their default weight and app sim key

Check failure on line 162 in types/module/simulation.go

View workflow job for this annotation

GitHub Actions / golangci-lint

SA1019: simulation.WeightedProposalContent is deprecated: Use WeightedProposalMsg instead. (staticcheck)
ProposalMsgs []simulation.WeightedProposalMsg // proposal msg generator functions with their default weight and app sim key
}
6 changes: 3 additions & 3 deletions x/simulation/params.go
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you will probably need to revert this file to make the linter happy

Original file line number Diff line number Diff line change
Expand Up @@ -160,14 +160,14 @@

// WeightedProposalContent defines a common struct for proposal content defined by external modules (i.e outside gov)
//
//nolint:staticcheck // used for legacy testing

type WeightedProposalContent struct {
appParamsKey string // key used to retrieve the value of the weight from the simulation application params
defaultWeight int // default weight
contentSimulatorFn simulation.ContentSimulatorFn // content simulator function

Check failure on line 167 in x/simulation/params.go

View workflow job for this annotation

GitHub Actions / golangci-lint

SA1019: simulation.ContentSimulatorFn is deprecated: Use MsgSimulatorFn instead. (staticcheck)
}

func NewWeightedProposalContent(appParamsKey string, defaultWeight int, contentSimulatorFn simulation.ContentSimulatorFn) simulation.WeightedProposalContent { //nolint:staticcheck // used for legacy testing
func NewWeightedProposalContent(appParamsKey string, defaultWeight int, contentSimulatorFn simulation.ContentSimulatorFn) simulation.WeightedProposalContent {
return &WeightedProposalContent{appParamsKey: appParamsKey, defaultWeight: defaultWeight, contentSimulatorFn: contentSimulatorFn}
}

Expand All @@ -179,7 +179,7 @@
return w.defaultWeight
}

func (w WeightedProposalContent) ContentSimulatorFn() simulation.ContentSimulatorFn { //nolint:staticcheck // used for legacy testing
func (w WeightedProposalContent) ContentSimulatorFn() simulation.ContentSimulatorFn {
return w.contentSimulatorFn
}

Expand Down
2 changes: 1 addition & 1 deletion x/simulation/params_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func TestNewWeightedProposalContent(t *testing.T) {
key := "theKey"
weight := 1
content := &testContent{}
f := func(r *rand.Rand, ctx sdk.Context, accs []simtypes.Account) simtypes.Content { //nolint:staticcheck // used for legacy testing
f := func(r *rand.Rand, ctx sdk.Context, accs []simtypes.Account) simtypes.Content {
return content
}

Expand Down
Loading