forked from cosmos/cosmos-sdk
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: WIP add bls cmd and fixing tx route issue
- Loading branch information
Showing
15 changed files
with
928 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
package cmd | ||
|
||
import ( | ||
"encoding/json" | ||
"errors" | ||
"fmt" | ||
|
||
tmos "github.com/cometbft/cometbft/libs/os" | ||
"github.com/spf13/cobra" | ||
|
||
"github.com/cosmos/cosmos-sdk/client" | ||
"github.com/cosmos/cosmos-sdk/server" | ||
"github.com/cosmos/cosmos-sdk/x/genutil" | ||
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" | ||
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" | ||
|
||
"cosmossdk.io/x/bls/types" | ||
) | ||
|
||
func AddGenBlsCmd(validator genutiltypes.MessageValidator) *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "add-genesis-bls [genesis_bls_file]", | ||
Short: "Add a genesis BLS key to genesis.json", | ||
Long: `Add a genesis BLS key per validator and update the pregenesis file in place to include their | ||
BLS keys in the checkpointing module's genesis state.' | ||
`, | ||
Args: cobra.ExactArgs(1), | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
clientCtx := client.GetClientContextFromCmd(cmd) | ||
serverCtx := server.GetServerContextFromCmd(cmd) | ||
config := serverCtx.Config | ||
config.SetRoot(clientCtx.HomeDir) | ||
|
||
// load genesis BLS key | ||
genKeyFilePath := args[0] | ||
if !tmos.FileExists(genKeyFilePath) { | ||
return errors.New("genesis BLS key file does not exist") | ||
} | ||
genKey, err := types.LoadGenesisKeyFromFile(genKeyFilePath) | ||
if err != nil { | ||
return err | ||
} | ||
err = genKey.Validate() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// load genesis state | ||
genFile := config.GenesisFile() | ||
appState, genDoc, err := genutiltypes.GenesisStateFromGenFile(genFile) | ||
if err != nil { | ||
return fmt.Errorf("failed to unmarshal genesis state: %w", err) | ||
} | ||
checkpointingGenState := types.GetGenesisStateFromAppState(clientCtx.Codec, appState) | ||
|
||
// check duplication | ||
gks := checkpointingGenState.GetGenesisKeys() | ||
for _, gk := range gks { | ||
if gk.ValidatorAddress == genKey.ValidatorAddress { | ||
return errors.New("validator address already exists") | ||
} | ||
} | ||
|
||
// check correspondence of genesis transactions | ||
// each genesis BLS key should have a corresponding | ||
// genesis transaction | ||
genTxState := genutiltypes.GetGenesisStateFromAppState(clientCtx.Codec, appState) | ||
foundInGenTx := false | ||
for _, genTx := range genTxState.GenTxs { | ||
tx, err := genutiltypes.ValidateAndGetGenTx(genTx, clientCtx.TxConfig.TxJSONDecoder(), validator) | ||
if err != nil { | ||
return err | ||
} | ||
msgs := tx.GetMsgs() | ||
if len(msgs) == 0 { | ||
return errors.New("invalid genesis transaction") | ||
} | ||
msgCreateValidator := msgs[0].(*stakingtypes.MsgCreateValidator) | ||
if msgCreateValidator.ValidatorAddress == genKey.ValidatorAddress { | ||
foundInGenTx = true | ||
} | ||
} | ||
if !foundInGenTx { | ||
return errors.New("corresponding genesis tx is not found, add genesis tx with the same validator address first") | ||
} | ||
|
||
gks = append(gks, genKey) | ||
checkpointingGenState.GenesisKeys = gks | ||
|
||
checkpointingGenStateBz, err := clientCtx.Codec.MarshalJSON(&checkpointingGenState) | ||
if err != nil { | ||
return fmt.Errorf("failed to marshal checkpointing genesis state: %w", err) | ||
} | ||
|
||
appState[types.ModuleName] = checkpointingGenStateBz | ||
|
||
appStateJSON, err := json.Marshal(appState) | ||
if err != nil { | ||
return fmt.Errorf("failed to marshal application genesis state: %w", err) | ||
} | ||
|
||
genDoc.AppState = appStateJSON | ||
return genutil.ExportGenesisFile(genDoc, genFile) | ||
}, | ||
} | ||
|
||
return cmd | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
package cmd_test | ||
|
||
//import ( | ||
// "context" | ||
// "fmt" | ||
// "path/filepath" | ||
// "testing" | ||
// | ||
// cmd "cosmossdk.io/simapp/simd/cmd/blscmd" | ||
// "cosmossdk.io/x/epoching/testepoching/datagen" | ||
// "github.com/cosmos/cosmos-sdk/server/config" | ||
// "github.com/cosmos/cosmos-sdk/testutil/cli" | ||
// "github.com/cosmos/cosmos-sdk/x/genutil" | ||
// | ||
// tmconfig "github.com/cometbft/cometbft/config" | ||
// tmjson "github.com/cometbft/cometbft/libs/json" | ||
// "github.com/cometbft/cometbft/libs/log" | ||
// "github.com/cometbft/cometbft/libs/tempfile" | ||
// "github.com/spf13/viper" | ||
// "github.com/stretchr/testify/require" | ||
// | ||
// "github.com/cosmos/cosmos-sdk/client" | ||
// "github.com/cosmos/cosmos-sdk/client/flags" | ||
// "github.com/cosmos/cosmos-sdk/server" | ||
// "github.com/cosmos/cosmos-sdk/testutil/network" | ||
// genutiltest "github.com/cosmos/cosmos-sdk/x/genutil/client/testutil" | ||
// genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" | ||
// | ||
// app "cosmossdk.io/simapp" | ||
// //"github.com/babylonchain/babylon/cmd/babylond/cmd" | ||
// "cosmossdk.io/privval" | ||
// //"github.com/babylonchain/babylon/testutil/cli" | ||
// //"github.com/babylonchain/babylon/testutil/datagen" | ||
// "cosmossdk.io/x/bls/types" | ||
//) | ||
// | ||
//// test adding genesis BLS keys without gentx | ||
//// error is expected | ||
//func Test_AddGenBlsCmdWithoutGentx(t *testing.T) { | ||
// home := t.TempDir() | ||
// logger := log.NewNopLogger() | ||
// tmcfg, err := genutiltest.CreateDefaultTendermintConfig(home) | ||
// require.NoError(t, err) | ||
// | ||
// appCodec := app.GetEncodingConfig().Marshaler | ||
// gentxModule := app.ModuleBasics[genutiltypes.ModuleName].(genutil.AppModuleBasic) | ||
// | ||
// err = genutiltest.ExecInitCmd(testMbm, home, appCodec) | ||
// require.NoError(t, err) | ||
// | ||
// serverCtx := server.NewContext(viper.New(), tmcfg, logger) | ||
// clientCtx := client.Context{}.WithCodec(appCodec).WithHomeDir(home) | ||
// cfg := serverCtx.Config | ||
// cfg.SetRoot(clientCtx.HomeDir) | ||
// | ||
// ctx := context.Background() | ||
// ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx) | ||
// ctx = context.WithValue(ctx, server.ServerContextKey, serverCtx) | ||
// | ||
// genKey := datagen.GenerateGenesisKey() | ||
// jsonBytes, err := tmjson.MarshalIndent(genKey, "", " ") | ||
// require.NoError(t, err) | ||
// genKeyFileName := filepath.Join(home, fmt.Sprintf("gen-bls-%s.json", genKey.ValidatorAddress)) | ||
// err = tempfile.WriteFileAtomic(genKeyFileName, jsonBytes, 0600) | ||
// require.NoError(t, err) | ||
// addGenBlsCmd := cmd.AddGenBlsCmd(gentxModule.GenTxValidator) | ||
// addGenBlsCmd.SetArgs( | ||
// []string{genKeyFileName}, | ||
// ) | ||
// err = addGenBlsCmd.ExecuteContext(ctx) | ||
// require.Error(t, err) | ||
//} | ||
// | ||
//// test adding genesis BLS keys with gentx | ||
//// error is expected if adding duplicate | ||
//func Test_AddGenBlsCmdWithGentx(t *testing.T) { | ||
// min := network.MinimumAppConfig() | ||
// cfg, _ := network.DefaultConfigWithAppConfig(min) | ||
// config.SetConfigTemplate(config.DefaultConfigTemplate) | ||
// cfg.NumValidators = 1 | ||
// | ||
// testNetwork, err := network.New(t, t.TempDir(), cfg) | ||
// require.NoError(t, err) | ||
// defer testNetwork.Cleanup() | ||
// | ||
// _, err = testNetwork.WaitForHeight(1) | ||
// require.NoError(t, err) | ||
// gentxModule := app.ModuleBasics[genutiltypes.ModuleName].(genutil.AppModuleBasic) | ||
// | ||
// targetCfg := tmconfig.DefaultConfig() | ||
// targetCfg.SetRoot(filepath.Join(testNetwork.Validators[0].Dir, "simd")) | ||
// targetGenesisFile := targetCfg.GenesisFile() | ||
// targetCtx := testNetwork.Validators[0].ClientCtx | ||
// for i := 0; i < cfg.NumValidators; i++ { | ||
// v := testNetwork.Validators[i] | ||
// // build and create genesis BLS key | ||
// genBlsCmd := cmd.GenBlsCmd() | ||
// nodeCfg := tmconfig.DefaultConfig() | ||
// homeDir := filepath.Join(v.Dir, "simd") | ||
// nodeCfg.SetRoot(homeDir) | ||
// keyPath := nodeCfg.PrivValidatorKeyFile() | ||
// statePath := nodeCfg.PrivValidatorStateFile() | ||
// filePV := privval.GenWrappedFilePV(keyPath, statePath) | ||
// defer filePV.Clean(keyPath, statePath) | ||
// filePV.SetAccAddress(v.Address) | ||
// _, err = cli.ExecTestCLICmd(v.ClientCtx, genBlsCmd, []string{fmt.Sprintf("--%s=%s", flags.FlagHome, homeDir)}) | ||
// require.NoError(t, err) | ||
// genKeyFileName := filepath.Join(filepath.Dir(keyPath), fmt.Sprintf("gen-bls-%s.json", v.ValAddress)) | ||
// genKey, err := types.LoadGenesisKeyFromFile(genKeyFileName) | ||
// require.NoError(t, err) | ||
// require.NotNil(t, genKey) | ||
// | ||
// // add genesis BLS key to the target context | ||
// addBlsCmd := cmd.AddGenBlsCmd(gentxModule.GenTxValidator) | ||
// _, err = cli.ExecTestCLICmd(targetCtx, addBlsCmd, []string{genKeyFileName}) | ||
// require.NoError(t, err) | ||
// appState, _, err := genutiltypes.GenesisStateFromGenFile(targetGenesisFile) | ||
// require.NoError(t, err) | ||
// // test duplicate | ||
// _, err = cli.ExecTestCLICmd(targetCtx, addBlsCmd, []string{genKeyFileName}) | ||
// require.Error(t, err) | ||
// | ||
// checkpointingGenState := types.GetGenesisStateFromAppState(v.ClientCtx.Codec, appState) | ||
// require.NotEmpty(t, checkpointingGenState.GenesisKeys) | ||
// gks := checkpointingGenState.GetGenesisKeys() | ||
// require.Equal(t, genKey, gks[i]) | ||
// } | ||
//} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
package cmd | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"path/filepath" | ||
"strings" | ||
|
||
tmconfig "github.com/cometbft/cometbft/config" | ||
tmos "github.com/cometbft/cometbft/libs/os" | ||
"github.com/spf13/cobra" | ||
|
||
app "cosmossdk.io/simapp" | ||
|
||
"cosmossdk.io/privval" | ||
"github.com/cosmos/cosmos-sdk/client/flags" | ||
"github.com/cosmos/cosmos-sdk/crypto/keys/bls12381" | ||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
) | ||
|
||
func CreateBlsKeyCmd() *cobra.Command { | ||
bech32PrefixAccAddr := sdk.Bech32PrefixAccAddr | ||
|
||
cmd := &cobra.Command{ | ||
Use: "create-bls-key [account-address]", | ||
Args: cobra.ExactArgs(1), | ||
Short: "Create a pair of BLS keys for a validator", | ||
Long: strings.TrimSpace( | ||
fmt.Sprintf(`create-bls will create a pair of BLS keys that are used to | ||
send BLS signatures for checkpointing. | ||
BLS keys are stored along with other validator keys in priv_validator_key.json, | ||
which should exist before running the command (via babylond init or babylond testnet). | ||
Example: | ||
$ babylond create-bls-key %s1f5tnl46mk4dfp4nx3n2vnrvyw2h2ydz6ykhk3r --home ./ | ||
`, | ||
bech32PrefixAccAddr, | ||
), | ||
), | ||
|
||
RunE: func(cmd *cobra.Command, args []string) error { | ||
homeDir, _ := cmd.Flags().GetString(flags.FlagHome) | ||
|
||
addr, err := sdk.AccAddressFromBech32(args[0]) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return CreateBlsKey(homeDir, addr) | ||
}, | ||
} | ||
|
||
cmd.Flags().String(flags.FlagHome, app.DefaultNodeHome, "The node home directory") | ||
|
||
return cmd | ||
} | ||
|
||
func CreateBlsKey(home string, addr sdk.AccAddress) error { | ||
nodeCfg := tmconfig.DefaultConfig() | ||
keyPath := filepath.Join(home, nodeCfg.PrivValidatorKeyFile()) | ||
statePath := filepath.Join(home, nodeCfg.PrivValidatorStateFile()) | ||
if !tmos.FileExists(keyPath) { | ||
return errors.New("validator key file does not exist") | ||
} | ||
pv := privval.LoadWrappedFilePV(keyPath, statePath) | ||
wrappedPV := privval.NewWrappedFilePV(pv.GetValPrivKey(), bls12381.GenPrivKey(), keyPath, statePath) | ||
wrappedPV.SetAccAddress(addr) | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package cmd | ||
|
||
import ( | ||
serverconfig "github.com/cosmos/cosmos-sdk/server/config" | ||
) | ||
|
||
const ( | ||
defaultKeyName = "" | ||
defaultGasPrice = "0.01ubbn" | ||
defaultGasAdjustment = 1.5 | ||
) | ||
|
||
func defaultSignerConfig() SignerConfig { | ||
return SignerConfig{ | ||
KeyName: defaultKeyName, | ||
GasPrice: defaultGasPrice, | ||
GasAdjustment: defaultGasAdjustment, | ||
} | ||
} | ||
|
||
type SignerConfig struct { | ||
KeyName string `mapstructure:"key-name"` | ||
GasPrice string `mapstructure:"gas-price"` | ||
GasAdjustment float64 `mapstructure:"gas-adjustment"` | ||
} | ||
|
||
type BabylonAppConfig struct { | ||
serverconfig.Config `mapstructure:",squash"` | ||
|
||
SignerConfig SignerConfig `mapstructure:"signer-config"` | ||
} | ||
|
||
func DefaultBabylonConfig() *BabylonAppConfig { | ||
return &BabylonAppConfig{ | ||
Config: *serverconfig.DefaultConfig(), | ||
SignerConfig: defaultSignerConfig(), | ||
} | ||
} | ||
|
||
func DefaultBabylonTemplate() string { | ||
return serverconfig.DefaultConfigTemplate + ` | ||
############################################################################### | ||
### Babylon BLS configuration ### | ||
############################################################################### | ||
[signer-config] | ||
# Configures which key that the BLS signer uses to sign BLS-sig transactions | ||
key-name = "{{ .SignerConfig.KeyName }}" | ||
# Configures the gas-price that the signer would like to pay | ||
gas-price = "{{ .SignerConfig.GasPrice }}" | ||
# Configures the adjustment of the gas cost of estimation | ||
gas-adjustment = "{{ .SignerConfig.GasAdjustment }}" | ||
` | ||
} |
Oops, something went wrong.