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)
+}