Skip to content

Commit

Permalink
feat: WIP add bls cmd and fixing tx route issue
Browse files Browse the repository at this point in the history
  • Loading branch information
dongsam committed Jan 10, 2024
1 parent 08f38f4 commit b2aaf64
Show file tree
Hide file tree
Showing 15 changed files with 928 additions and 10 deletions.
1 change: 1 addition & 0 deletions simapp/app.go
Expand Up @@ -848,6 +848,7 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino
paramsKeeper.Subspace(slashingtypes.ModuleName)
paramsKeeper.Subspace(govtypes.ModuleName)
paramsKeeper.Subspace(crisistypes.ModuleName)
// TODO: params?

return paramsKeeper
}
108 changes: 108 additions & 0 deletions simapp/simd/cmd/blscmd/add_gen_bls.go
@@ -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
}
128 changes: 128 additions & 0 deletions simapp/simd/cmd/blscmd/add_gen_bls_test.go
@@ -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])
// }
//}
71 changes: 71 additions & 0 deletions simapp/simd/cmd/blscmd/create_bls_key.go
@@ -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
}
55 changes: 55 additions & 0 deletions simapp/simd/cmd/blscmd/custom_babylon_config.go
@@ -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 }}"
`
}

0 comments on commit b2aaf64

Please sign in to comment.