diff --git a/cmd/babylond/cmd/create_bls_key.go b/cmd/babylond/cmd/create_bls_key.go index 6a6b62ea8..c6da4dc9d 100644 --- a/cmd/babylond/cmd/create_bls_key.go +++ b/cmd/babylond/cmd/create_bls_key.go @@ -14,6 +14,10 @@ import ( "github.com/babylonlabs-io/babylon/privval" ) +const ( + FlagPassword = "bls-password" +) + func CreateBlsKeyCmd() *cobra.Command { bech32PrefixAccAddr := appparams.Bech32PrefixAccAddr @@ -43,23 +47,25 @@ $ babylond create-bls-key %s1f5tnl46mk4dfp4nx3n2vnrvyw2h2ydz6ykhk3r --home ./ return err } - return CreateBlsKey(homeDir, addr) + var password string + password, _ = cmd.Flags().GetString(FlagPassword) + if password == "" { + password = privval.GetBlsPassword() + } + return CreateBlsKey(homeDir, password, addr) }, } cmd.Flags().String(flags.FlagHome, app.DefaultNodeHome, "The node home directory") - + cmd.Flags().String(FlagPassword, "", "The password for the BLS key. If a flag is set, the non-empty password should be provided. If a flag is not set, the password will be read from the prompt.") return cmd } -func CreateBlsKey(home string, addr sdk.AccAddress) error { - +func CreateBlsKey(home, password string, addr sdk.AccAddress) error { blsCfg := privval.DefaultBlsConfig() keyPath := filepath.Join(home, blsCfg.BlsKeyFile()) passwordPath := filepath.Join(home, blsCfg.BlsPasswordFile()) - password := privval.GetBlsPassword() - privval.GenBlsPV(keyPath, passwordPath, password, addr.String()) return nil } diff --git a/privval/bls.go b/privval/bls.go index e990db8e3..16753582b 100644 --- a/privval/bls.go +++ b/privval/bls.go @@ -131,6 +131,14 @@ func (k *BlsPVKey) Save(password, addr string) { } } +func (k *BlsPVKey) GetKeyFilePath() string { + return k.filePath +} + +func (k *BlsPVKey) GetPasswordFilePath() string { + return k.passwordPath +} + // ------------------------------------------------------------------------------- // ---------------------------- BLS Config --------------------------------------- // ------------------------------------------------------------------------------- diff --git a/privval/util.go b/privval/util.go index 802240580..213230cb2 100644 --- a/privval/util.go +++ b/privval/util.go @@ -11,7 +11,7 @@ func IsValidFilePath(paths ...string) error { // Check file path of bls key for _, path := range paths { if path == "" { - return fmt.Errorf("filePath for bls key not set") + return fmt.Errorf("filePath is not set completely") } if err := cmtos.EnsureDir(filepath.Dir(path), 0777); err != nil { return fmt.Errorf("failed to ensure key path dir: %w", err) diff --git a/test/e2e/configurer/upgrade.go b/test/e2e/configurer/upgrade.go index 123a3924f..18fd03064 100644 --- a/test/e2e/configurer/upgrade.go +++ b/test/e2e/configurer/upgrade.go @@ -4,6 +4,7 @@ import ( "encoding/hex" "encoding/json" "fmt" + "log" "os" "path/filepath" "sync" @@ -18,10 +19,13 @@ import ( "github.com/babylonlabs-io/babylon/app" appparams "github.com/babylonlabs-io/babylon/app/params" + "github.com/babylonlabs-io/babylon/privval" "github.com/babylonlabs-io/babylon/test/e2e/configurer/chain" "github.com/babylonlabs-io/babylon/test/e2e/configurer/config" "github.com/babylonlabs-io/babylon/test/e2e/containers" "github.com/babylonlabs-io/babylon/test/e2e/initialization" + + cmtos "github.com/cometbft/cometbft/libs/os" ) type UpgradeSettings struct { @@ -250,6 +254,54 @@ func (uc *UpgradeConfigurer) runForkUpgrade() { } } +// func saveFilesToVolume(node *chain.NodeConfig) error { +// dir := node.ConfigDir + +// cmtCfg := cmtcfg.DefaultConfig() +// cmtCfg.SetRoot(dir) + +// cmtKeyFile := cmtCfg.PrivValidatorKeyFile() +// cmtStateFile := cmtCfg.PrivValidatorStateFile() + +// blsCfg := privval.DefaultBlsConfig() +// blsCfg.SetRoot(dir) + +// blsKeyFile := blsCfg.BlsKeyFile() +// blsPasswordFile := blsCfg.BlsPasswordFile() + +// if err := privval.IsValidFilePath(cmtKeyFile, cmtStateFile, blsKeyFile, blsPasswordFile); err != nil { +// return err +// } + +// var password string +// if node.TempBlsInfo.Password == "" { +// log.Print("node.TempBlsInfo.Password is empty") +// password = "password" +// } else { +// password = node.TempBlsInfo.Password +// } + +// var blsPrivKey bls12381.PrivateKey +// if node.TempBlsInfo.PrivateKey == nil { +// log.Print("node.TempBlsInfo.PrivateKey is empty") +// blsPrivKey = bls12381.GenPrivKey() +// } else { +// blsPrivKey = node.TempBlsInfo.PrivateKey +// } +// blsPv := privval.NewBlsPV(blsPrivKey, blsKeyFile, blsPasswordFile, node.TempBlsInfo.DelegatorAddress) +// blsPv.Key.Save(password, node.TempBlsInfo.DelegatorAddress) + +// var privKey ed25519.PrivKey +// if node.PrivateKey == nil { +// log.Print("node.PrivateKey is empty") +// privKey = ed25519.GenPrivKey() +// } else { +// privKey = ed25519.PrivKey(node.PrivateKey) +// } +// cmtprivval.NewFilePV(privKey, cmtKeyFile, cmtStateFile).Save() +// return nil +// } + func (uc *UpgradeConfigurer) upgradeContainers(chainConfig *chain.Config, propHeight int64) error { // upgrade containers to the locally compiled daemon uc.t.Logf("starting upgrade for chain-id: %s...", chainConfig.Id) @@ -257,6 +309,34 @@ func (uc *UpgradeConfigurer) upgradeContainers(chainConfig *chain.Config, propHe uc.containerManager.CurrentTag = "latest" for _, node := range chainConfig.NodeConfigs { + // ======= TESTING START ======= + log.Print("==> upgradeContainers()") + log.Print("=> node.ConfigDir: ", node.ConfigDir) + + var keyIs, pwIs bool + + log.Print("=> bls") + if cmtos.FileExists(node.ConsensusKey.BlsPVKey.GetKeyFilePath()) { + log.Print("=> file exists: node.ConsensusKey.BlsPVKey.GetKeyFilePath(): ", node.ConsensusKey.BlsPVKey.GetKeyFilePath()) + keyIs = true + } else { + log.Print("=> file does not exist: node.ConsensusKey.BlsPVKey.GetKeyFilePath(): ", node.ConsensusKey.BlsPVKey.GetKeyFilePath()) + keyIs = false + } + + if cmtos.FileExists(node.ConsensusKey.BlsPVKey.GetPasswordFilePath()) { + log.Print("=> file exists: node.ConsensusKey.BlsPVKey.GetPasswordFilePath(): ", node.ConsensusKey.BlsPVKey.GetPasswordFilePath()) + pwIs = true + } else { + log.Print("=> file does not exist: node.ConsensusKey.BlsPVKey.GetPasswordFilePath(): ", node.ConsensusKey.BlsPVKey.GetPasswordFilePath()) + pwIs = false + } + + if keyIs && pwIs { + pv := privval.LoadBlsPV(node.ConsensusKey.BlsPVKey.GetKeyFilePath(), node.ConsensusKey.BlsPVKey.GetPasswordFilePath()) + log.Print("bls pv: ", pv) + } + // ======= TESTING END ======= if err := node.Run(); err != nil { return err } diff --git a/test/e2e/containers/containers.go b/test/e2e/containers/containers.go index b6863d1ef..8f4b5eb77 100644 --- a/test/e2e/containers/containers.go +++ b/test/e2e/containers/containers.go @@ -5,12 +5,18 @@ import ( "context" "errors" "fmt" + "log" "os" + "path/filepath" "regexp" "strings" "testing" "time" + "github.com/babylonlabs-io/babylon/privval" + cmtcfg "github.com/cometbft/cometbft/config" + cmtos "github.com/cometbft/cometbft/libs/os" + cmtprivval "github.com/cometbft/cometbft/privval" "github.com/ory/dockertest/v3" "github.com/ory/dockertest/v3/docker" "github.com/stretchr/testify/require" @@ -263,6 +269,42 @@ func (m *Manager) RunNodeResource(chainId string, containerName, valCondifDir st return nil, err } + // ======= TESTING START ======= + log.Print("==> RunNodeResource()") + log.Print("=> valCondifDir: ", valCondifDir) + // ======= TESTING END ======= + + // ======= CREATE KEY DIRECTLY ======= + cmtKeyFile := filepath.Join(valCondifDir, cmtcfg.DefaultConfig().PrivValidatorKeyFile()) + cmtStateFile := filepath.Join(valCondifDir, cmtcfg.DefaultConfig().PrivValidatorStateFile()) + blsKeyFile := filepath.Join(valCondifDir, privval.DefaultBlsConfig().BlsKeyFile()) + blsPasswordFile := filepath.Join(valCondifDir, privval.DefaultBlsConfig().BlsPasswordFile()) + + log.Print("=> cmtKeyFile: ", cmtKeyFile) + log.Print("=> cmtStateFile: ", cmtStateFile) + log.Print("=> blsKeyFile: ", blsKeyFile) + log.Print("=> blsPasswordFile: ", blsPasswordFile) + + if !cmtos.FileExists(cmtKeyFile) { + if err := privval.IsValidFilePath(cmtKeyFile, cmtStateFile); err != nil { + return nil, err + } + log.Print("=> file not exists: cmtKeyFile: ", cmtKeyFile) + log.Print("=> create new cometPv and save to file") + cmtprivval.GenFilePV(cmtKeyFile, cmtStateFile).Save() + } + + if !cmtos.FileExists(blsKeyFile) { + if err := privval.IsValidFilePath(blsKeyFile, blsPasswordFile); err != nil { + return nil, err + } + log.Print("=> file not exists: blsKeyFile: ", blsKeyFile) + log.Print("=> create new blsPv and save to file") + privval.GenBlsPV(blsKeyFile, blsPasswordFile, "password", "") + } + + // ======= CREATE KEY DIRECTLY ======= + runOpts := &dockertest.RunOptions{ Name: containerName, Repository: m.CurrentRepository, diff --git a/test/e2e/initialization/chain.go b/test/e2e/initialization/chain.go index d782f1401..696e5e96e 100644 --- a/test/e2e/initialization/chain.go +++ b/test/e2e/initialization/chain.go @@ -1,5 +1,11 @@ package initialization +import ( + "log" + + cmtos "github.com/cometbft/cometbft/libs/os" +) + const ( keyringPassphrase = "testpassphrase" keyringAppName = "testnet" @@ -26,6 +32,23 @@ func (c *internalChain) export() *Chain { exportNodes := make([]*Node, 0, len(c.nodes)) for _, v := range c.nodes { exportNodes = append(exportNodes, v.export()) + + // ======= TESTING START ======= + log.Print("==> export()") + log.Print("=> v.export().ConfigDir: ", v.export().ConfigDir) + + if cmtos.FileExists(v.export().ConsensusKey.BlsPVKey.GetKeyFilePath()) { + log.Print("=> file exists: blsKeyFile: ", v.export().ConsensusKey.BlsPVKey.GetKeyFilePath()) + } else { + log.Print("=> file does not exist: blsKeyFile: ", v.export().ConsensusKey.BlsPVKey.GetKeyFilePath()) + } + + if cmtos.FileExists(v.export().ConsensusKey.BlsPVKey.GetPasswordFilePath()) { + log.Print("=> file exists: blsPasswordFile: ", v.export().ConsensusKey.BlsPVKey.GetPasswordFilePath()) + } else { + log.Print("=> file does not exist: blsPasswordFile: ", v.export().ConsensusKey.BlsPVKey.GetPasswordFilePath()) + } + // ======= TESTING END ======= } return &Chain{ diff --git a/test/e2e/initialization/export.go b/test/e2e/initialization/export.go index 6c741a4c0..e4ab0622a 100644 --- a/test/e2e/initialization/export.go +++ b/test/e2e/initialization/export.go @@ -2,6 +2,8 @@ package initialization import ( "fmt" + + "github.com/babylonlabs-io/babylon/privval" ) type ChainMeta struct { @@ -19,6 +21,7 @@ type Node struct { PrivateKey []byte `json:"privateKey"` PeerId string `json:"peerId"` IsValidator bool `json:"isValidator"` + ConsensusKey privval.WrappedFilePVKey } type Chain struct { diff --git a/test/e2e/initialization/node.go b/test/e2e/initialization/node.go index d148c0d00..d3e8a90ba 100644 --- a/test/e2e/initialization/node.go +++ b/test/e2e/initialization/node.go @@ -3,6 +3,7 @@ package initialization import ( "encoding/json" "fmt" + "log" "os" "path" "path/filepath" @@ -34,8 +35,10 @@ import ( babylonApp "github.com/babylonlabs-io/babylon/app" appparams "github.com/babylonlabs-io/babylon/app/params" "github.com/babylonlabs-io/babylon/cmd/babylond/cmd" + "github.com/babylonlabs-io/babylon/crypto/bls12381" "github.com/babylonlabs-io/babylon/privval" "github.com/babylonlabs-io/babylon/test/e2e/util" + cmtos "github.com/cometbft/cometbft/libs/os" cmtprivval "github.com/cometbft/cometbft/privval" ) @@ -51,6 +54,14 @@ type internalNode struct { isValidator bool } +type TempBlsInfo struct { + PrivateKey bls12381.PrivateKey + Password string + DelegatorAddress string + KeyFilePath string + PasswordFilePath string +} + func newNode(chain *internalChain, nodeConfig *NodeConfig) (*internalNode, error) { node := &internalNode{ chain: chain, @@ -198,6 +209,34 @@ func (n *internalNode) createConsensusKey() error { CometPVKey: filePV.Key, BlsPVKey: blsPV.Key, } + + // ======= TESTING START ======= + log.Print("==> createConsensusKey()") + if cmtos.FileExists(pvKeyFile) { + log.Print("=> file exists: pvKeyFile: ", pvKeyFile) + } else { + log.Print("=> file does not exist: pvKeyFile: ", pvKeyFile) + } + + if cmtos.FileExists(blsPasswordFile) { + log.Print("=> file exists: blsPasswordFile: ", blsPasswordFile) + } else { + log.Print("=> file does not exist: blsPasswordFile: ", blsPasswordFile) + } + + if cmtos.FileExists(blsKeyFile) { + log.Print("=> file exists: blsKeyFile: ", blsKeyFile) + } else { + log.Print("=> file does not exist: blsKeyFile: ", blsKeyFile) + } + + if cmtos.FileExists(blsPasswordFile) { + log.Print("=> file exists: blsPasswordFile: ", blsPasswordFile) + } else { + log.Print("=> file does not exist: blsPasswordFile: ", blsPasswordFile) + } + // ======= TESTING END ======= + return nil } @@ -267,6 +306,7 @@ func (n *internalNode) export() *Node { PrivateKey: n.privateKey.Bytes(), PeerId: n.peerId, IsValidator: n.isValidator, + ConsensusKey: n.consensusKey, } } diff --git a/testutil/datagen/btc_blockchain.go b/testutil/datagen/btc_blockchain.go index d963e50e1..da0a207da 100644 --- a/testutil/datagen/btc_blockchain.go +++ b/testutil/datagen/btc_blockchain.go @@ -104,7 +104,7 @@ func GenRandomBtcdBlockWithTransactions( var proofs []*btcctypes.BTCSpvProof - for i, _ := range msgTxs { + for i := range msgTxs { headerBytes := bbn.NewBTCHeaderBytesFromBlockHeader(header) proof, err := btcctypes.SpvProofFromHeaderAndTransactions(&headerBytes, txBytes, uint(i)) if err != nil { diff --git a/testutil/datagen/init_val.go b/testutil/datagen/init_val.go index 10ee141c9..704df0fb6 100644 --- a/testutil/datagen/init_val.go +++ b/testutil/datagen/init_val.go @@ -2,6 +2,7 @@ package datagen import ( "fmt" + "path/filepath" cfg "github.com/cometbft/cometbft/config" "github.com/cometbft/cometbft/crypto/ed25519" @@ -40,10 +41,11 @@ func InitializeNodeValidatorFilesFromMnemonic(config *cfg.Config, mnemonic strin // bls config blsCfg := privval.DefaultBlsConfig() - blsCfg.SetRoot(config.RootDir) + // blsCfg.SetRoot(config.RootDir) + + blsKeyFile := filepath.Join(config.RootDir, blsCfg.BlsKeyFile()) + blsPasswordFile := filepath.Join(config.RootDir, blsCfg.BlsPasswordFile()) - blsKeyFile := blsCfg.BlsKeyFile() - blsPasswordFile := blsCfg.BlsPasswordFile() if err := privval.IsValidFilePath(blsKeyFile, blsPasswordFile); err != nil { return "", nil, err } diff --git a/testutil/signer/private_test.go b/testutil/signer/private_test.go new file mode 100644 index 000000000..6f72f9ee4 --- /dev/null +++ b/testutil/signer/private_test.go @@ -0,0 +1,37 @@ +package signer + +import ( + "path/filepath" + "testing" + + "github.com/babylonlabs-io/babylon/crypto/erc2335" + "github.com/babylonlabs-io/babylon/privval" + cmtconfig "github.com/cometbft/cometbft/config" + cmtprivval "github.com/cometbft/cometbft/privval" + "github.com/test-go/testify/assert" +) + +func TestGeneratePrivSigner(t *testing.T) { + nodeDir := t.TempDir() + + nodeCfg := cmtconfig.DefaultConfig() + blsCfg := privval.DefaultBlsConfig() + + pvKeyFile := filepath.Join(nodeDir, nodeCfg.PrivValidatorKeyFile()) + pvStateFile := filepath.Join(nodeDir, nodeCfg.PrivValidatorStateFile()) + blsKeyFile := filepath.Join(nodeDir, blsCfg.BlsKeyFile()) + blsPasswordFile := filepath.Join(nodeDir, blsCfg.BlsPasswordFile()) + + err := privval.IsValidFilePath(pvKeyFile, pvStateFile, blsKeyFile, blsPasswordFile) + assert.NoError(t, err) + + cometPV := cmtprivval.GenFilePV(pvKeyFile, pvStateFile) + cometPV.Key.Save() + cometPV.LastSignState.Save() + + privval.GenBlsPV(blsKeyFile, blsPasswordFile, "password", "") + + password, err := erc2335.LoadPaswordFromFile(blsPasswordFile) + assert.NoError(t, err) + t.Logf("password: %s", password) +}