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: reduce dependency with comet pv in bls signer #10

Draft
wants to merge 3 commits into
base: feat/wrapped-filepv-removal
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/keepers/keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ func (ak *AppKeepers) InitKeepers(
checkpointingKeeper := checkpointingkeeper.NewKeeper(
appCodec,
runtime.NewKVStoreService(keys[checkpointingtypes.StoreKey]),
privSigner.PV,
&privSigner.PV.Bls,
epochingKeeper,
)

Expand Down
4 changes: 2 additions & 2 deletions cmd/babylond/cmd/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ func InitCmd(mbm module.BasicManager, defaultNodeHome string) *cobra.Command {
cmd := &cobra.Command{
Use: cosmosInitCmd.Use,
Short: cosmosInitCmd.Short,
Long: cosmosInitCmd.Long,
Long: `Initialize validators's and node's configuration files, including the generation and setup of BLS keys for validators.`,
Args: cosmosInitCmd.Args,
RunE: func(cmd *cobra.Command, args []string) error {
if err := cosmosInitCmd.RunE(cmd, args); err != nil {
Expand All @@ -27,6 +27,6 @@ func InitCmd(mbm module.BasicManager, defaultNodeHome string) *cobra.Command {
},
}
cmd.Flags().AddFlagSet(cosmosInitCmd.Flags())
cmd.Flags().String(flagBlsPassword, "", "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.")
cmd.Flags().String(flagBlsPassword, "", "The password for the BLS key. If a flag is not set, the password will be read from the prompt.")
return cmd
}
16 changes: 8 additions & 8 deletions cmd/babylond/cmd/migrate.go → cmd/babylond/cmd/migrate_bls.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ func MigrateBlsKeyCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "migrate-bls-key",
Short: "Migrate the contents of the priv_validator_key.json file into separate files of bls and comet",
Long: strings.TrimSpace(`migrate splits the contents of the priv_validator_key.json file,
Long: strings.TrimSpace(`Migration splits the contents of the priv_validator_key.json file,
which contained both the bls and comet keys used in previous versions, into separate files.

BLS keys are stored along with other validator keys in priv_validator_key.json in previous version,
BLS keys are stored along with the ed25519 validator key in priv_validator_key.json in the previous version,
which should exist before running the command (via babylond init or babylond testnet).

NOTE: Before proceeding with the migration, ensure you back up the priv_validator_key.json file to a secure location.
Expand Down Expand Up @@ -63,12 +63,12 @@ func migrate(homeDir, password string) error {
filepath := cmtcfg.PrivValidatorKeyFile()

if !cmtos.FileExists(filepath) {
return fmt.Errorf("priv_validator_key.json of previous version not found")
return fmt.Errorf("priv_validator_key.json of previous version not found in %s", filepath)
}

pv, err := loadPrevWrappedFilePV(filepath)
if err != nil {
return err
return fmt.Errorf("Error loading priv_validator_key.json from %v: %v\n", filepath, err)
}

prevCmtPrivKey := pv.PrivKey
Expand All @@ -86,13 +86,13 @@ func migrate(homeDir, password string) error {
blsPv := privval.NewBlsPV(prevBlsPrivKey, privval.DefaultBlsKeyFile(homeDir), privval.DefaultBlsPasswordFile(homeDir))

// before saving keys to files, verify that the migrated keys match
if err := verifyAfterMigration(
if err := verifyBeforeMigration(
prevCmtPrivKey,
cmtPv.Key.PrivKey,
prevBlsPrivKey,
blsPv.Key.PrivKey,
); err != nil {
return fmt.Errorf("failed to verify after migration: %w", err)
return fmt.Errorf("failed to verify before migration: %w", err)
}

// save key to files after verification
Expand All @@ -115,8 +115,8 @@ func loadPrevWrappedFilePV(filePath string) (*PrevWrappedFilePV, error) {
return &pvKey, nil
}

// verifyAfterMigration checks if the migrated keys match
func verifyAfterMigration(prevCmtPrivKey, newCmtPrivKey cmtcrypto.PrivKey, prevBlsPrivKey, newBlsPrivKey bls12381.PrivateKey) error {
// verifyBeforeMigration checks if the migrated keys match
func verifyBeforeMigration(prevCmtPrivKey, newCmtPrivKey cmtcrypto.PrivKey, prevBlsPrivKey, newBlsPrivKey bls12381.PrivateKey) error {
if bytes.Equal(prevCmtPrivKey.Bytes(), newCmtPrivKey.Bytes()) && bytes.Equal(prevBlsPrivKey, newBlsPrivKey) {
return nil
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func TestMigrate(t *testing.T) {
t.Run("verify after migration", func(t *testing.T) {
newCmtPv := cmtprivval.LoadFilePV(newPvKeyFile, newPvStateFile)
newBlsPv := privval.LoadBlsPV(newBlsKeyFile, newBlsPasswordFile)
err := verifyAfterMigration(
err := verifyBeforeMigration(
pvKey.PrivKey,
newCmtPv.Key.PrivKey,
pvKey.BlsPrivKey,
Expand Down Expand Up @@ -146,7 +146,7 @@ func TestVerifyAfterMigration(t *testing.T) {
cmtKey := ed25519.GenPrivKey()
blsKey := bls12381.GenPrivKey()

err := verifyAfterMigration(cmtKey, cmtKey, blsKey, blsKey)
err := verifyBeforeMigration(cmtKey, cmtKey, blsKey, blsKey)
require.NoError(t, err)
})

Expand All @@ -155,7 +155,7 @@ func TestVerifyAfterMigration(t *testing.T) {
cmtKey2 := ed25519.GenPrivKey()
blsKey := bls12381.GenPrivKey()

err := verifyAfterMigration(cmtKey1, cmtKey2, blsKey, blsKey)
err := verifyBeforeMigration(cmtKey1, cmtKey2, blsKey, blsKey)
require.Error(t, err)
require.Contains(t, err.Error(), "migrated keys do not match")
})
Expand All @@ -165,7 +165,7 @@ func TestVerifyAfterMigration(t *testing.T) {
blsKey1 := bls12381.GenPrivKey()
blsKey2 := bls12381.GenPrivKey()

err := verifyAfterMigration(cmtKey, cmtKey, blsKey1, blsKey2)
err := verifyBeforeMigration(cmtKey, cmtKey, blsKey1, blsKey2)
require.Error(t, err)
require.Contains(t, err.Error(), "migrated keys do not match")
})
Expand Down
19 changes: 19 additions & 0 deletions privval/bls.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/babylonlabs-io/babylon/crypto/bls12381"
"github.com/babylonlabs-io/babylon/crypto/erc2335"
"github.com/babylonlabs-io/babylon/x/checkpointing/keeper"
checkpointingtypes "github.com/babylonlabs-io/babylon/x/checkpointing/types"
cmtcfg "github.com/cometbft/cometbft/config"
cmtcrypto "github.com/cometbft/cometbft/crypto"
Expand All @@ -20,6 +21,8 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
)

var _ keeper.BlsSigner = &BlsPVKey{}

const (
DefaultBlsKeyName = "bls_key.json" // Default file name for BLS key
DefaultBlsPasswordName = "bls_password.txt" // Default file name for BLS password
Expand Down Expand Up @@ -181,3 +184,19 @@ func DefaultBlsKeyFile(home string) string {
func DefaultBlsPasswordFile(home string) string {
return filepath.Join(home, defaultBlsPasswordPath)
}

// SignMsgWithBls signs a message with BLS, implementing the BlsSigner interface
func (k *BlsPVKey) SignMsgWithBls(msg []byte) (bls12381.Signature, error) {
if k.PrivKey == nil {
return nil, fmt.Errorf("BLS private key does not exist: %w", checkpointingtypes.ErrBlsPrivKeyDoesNotExist)
}
return bls12381.Sign(k.PrivKey, msg), nil
}

// GetBlsPubkey returns the public key of the BLS, implementing the BlsSigner interface
func (k *BlsPVKey) GetBlsPubkey() (bls12381.PublicKey, error) {
if k.PrivKey == nil {
return nil, checkpointingtypes.ErrBlsPrivKeyDoesNotExist
}
return k.PrivKey.PubKey(), nil
}
26 changes: 0 additions & 26 deletions privval/file.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
package privval

import (
"fmt"

"github.com/babylonlabs-io/babylon/crypto/bls12381"
checkpointingtypes "github.com/babylonlabs-io/babylon/x/checkpointing/types"
cmtcrypto "github.com/cometbft/cometbft/crypto"
cmtprivval "github.com/cometbft/cometbft/privval"
)

Expand All @@ -22,24 +17,3 @@ func NewWrappedFilePV(comet cmtprivval.FilePVKey, bls BlsPVKey) *WrappedFilePV {
Bls: bls,
}
}

// SignMsgWithBls signs a message with BLS, implementing the BlsSigner interface
func (pv *WrappedFilePV) SignMsgWithBls(msg []byte) (bls12381.Signature, error) {
if pv.Bls.PrivKey == nil {
return nil, fmt.Errorf("BLS private key does not exist: %w", checkpointingtypes.ErrBlsPrivKeyDoesNotExist)
}
return bls12381.Sign(pv.Bls.PrivKey, msg), nil
}

// GetBlsPubkey returns the public key of the BLS, implementing the BlsSigner interface
func (pv *WrappedFilePV) GetBlsPubkey() (bls12381.PublicKey, error) {
if pv.Bls.PrivKey == nil {
return nil, checkpointingtypes.ErrBlsPrivKeyDoesNotExist
}
return pv.Bls.PrivKey.PubKey(), nil
}

// GetValidatorPubkey returns the public key of the validator, implementing the BlsSigner interface
func (pv *WrappedFilePV) GetValidatorPubkey() cmtcrypto.PubKey {
return pv.Comet.PrivKey.PubKey()
}
31 changes: 0 additions & 31 deletions testutil/mocks/bls_signer.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion testutil/signer/private.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func SetupTestPrivSigner() (*signer.PrivSigner, error) {
return privSigner, nil
}

// func GenesisKeyFromPrivSigner(ps *signer.PrivSigner, delegatorAddress sdk.ValAddress) (*checkpointingtypes.GenesisKey, error) {
// GenesisKeyFromPrivSigner returns a GenesisKey from a PrivSigner
func GenesisKeyFromPrivSigner(ps *signer.PrivSigner, delegatorAddress sdk.ValAddress) (*checkpointingtypes.GenesisKey, error) {
valKeys, err := privval.NewValidatorKeys(
ps.PV.Comet.PrivKey,
Expand All @@ -56,6 +56,7 @@ func GenesisKeyFromPrivSigner(ps *signer.PrivSigner, delegatorAddress sdk.ValAdd
)
}

// GeneratePrivSigner generates a PrivSigner for testing
func GeneratePrivSigner(nodeDir string) error {
nodeCfg := cmtconfig.DefaultConfig()
nodeCfg.SetRoot(nodeDir)
Expand Down
25 changes: 11 additions & 14 deletions x/checkpointing/keeper/bls_signer.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
package keeper

import (
"github.com/cometbft/cometbft/crypto"
sdk "github.com/cosmos/cosmos-sdk/types"
"context"
"fmt"

"github.com/babylonlabs-io/babylon/crypto/bls12381"
"github.com/babylonlabs-io/babylon/x/checkpointing/types"
sdk "github.com/cosmos/cosmos-sdk/types"
)

// BlsSigner is an interface for signing BLS messages
type BlsSigner interface {
// GetAddress() sdk.ValAddress
SignMsgWithBls(msg []byte) (bls12381.Signature, error)
GetBlsPubkey() (bls12381.PublicKey, error)
GetValidatorPubkey() crypto.PubKey
}

// SignBLS signs a BLS signature over the given information
Expand All @@ -22,14 +22,11 @@ func (k Keeper) SignBLS(epochNum uint64, blockHash types.BlockHash) (bls12381.Si
return k.blsSigner.SignMsgWithBls(signBytes)
}

// GetConAddressFromPubkey returns the consensus address
func (k Keeper) GetConAddressFromPubkey() sdk.ConsAddress {
pk := k.blsSigner.GetValidatorPubkey()
return sdk.ConsAddress(pk.Address())
}

// GetValAddressFromPubkey returns the validator address
func (k Keeper) GetValAddressFromPubkey() sdk.ValAddress {
pk := k.blsSigner.GetValidatorPubkey()
return sdk.ValAddress(pk.Address())
// GetValidatorAddress returns the validator address of the signer
func (k Keeper) GetValidatorAddress(ctx context.Context) (sdk.ValAddress, error) {
blsPubKey, err := k.blsSigner.GetBlsPubkey()
if err != nil {
return nil, fmt.Errorf("failed to get BLS public key: %w", err)
}
return k.GetValAddr(ctx, blsPubKey)
}
12 changes: 12 additions & 0 deletions x/checkpointing/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -402,26 +402,37 @@ func (k Keeper) GetBLSPubKeySet(ctx context.Context, epochNumber uint64) ([]*typ
return valWithblsKeys, nil
}

// GetBlsPubKey returns the BLS public key of the validator
func (k Keeper) GetBlsPubKey(ctx context.Context, address sdk.ValAddress) (bls12381.PublicKey, error) {
return k.RegistrationState(ctx).GetBlsPubKey(address)
}

// GetValAddr returns the validator address of the BLS public key
func (k Keeper) GetValAddr(ctx context.Context, key bls12381.PublicKey) (sdk.ValAddress, error) {
return k.RegistrationState(ctx).GetValAddr(key)
}

// GetEpoch returns the current epoch
func (k Keeper) GetEpoch(ctx context.Context) *epochingtypes.Epoch {
return k.epochingKeeper.GetEpoch(ctx)
}

// GetValidatorSet returns the validator set for a given epoch
func (k Keeper) GetValidatorSet(ctx context.Context, epochNumber uint64) epochingtypes.ValidatorSet {
return k.epochingKeeper.GetValidatorSet(ctx, epochNumber)
}

// GetTotalVotingPower returns the total voting power for a given epoch
func (k Keeper) GetTotalVotingPower(ctx context.Context, epochNumber uint64) int64 {
return k.epochingKeeper.GetTotalVotingPower(ctx, epochNumber)
}

// GetPubKeyByConsAddr returns the public key of a validator by consensus address
func (k Keeper) GetPubKeyByConsAddr(ctx context.Context, consAddr sdk.ConsAddress) (cmtprotocrypto.PublicKey, error) {
return k.epochingKeeper.GetPubKeyByConsAddr(ctx, consAddr)
}

// GetValidatorByConsAddr returns the validator by consensus address
func (k Keeper) GetValidatorByConsAddr(ctx context.Context, consAddr sdk.ConsAddress) (stakingtypes.Validator, error) {
return k.epochingKeeper.GetValidatorByConsAddr(ctx, consAddr)
}
Expand All @@ -438,6 +449,7 @@ func (k Keeper) GetLastFinalizedEpoch(ctx context.Context) uint64 {
return sdk.BigEndianToUint64(epochNumberBytes)
}

// GetEpochByHeight returns the epoch number for a given height
func (k Keeper) GetEpochByHeight(ctx context.Context, height uint64) uint64 {
return k.epochingKeeper.GetEpochNumByHeight(ctx, height)
}
Expand Down
13 changes: 13 additions & 0 deletions x/checkpointing/keeper/registration_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,19 @@ func (rs RegistrationState) GetBlsPubKey(addr sdk.ValAddress) (bls12381.PublicKe
return *pk, err
}

// GetBlsPubKey retrieves BLS public key by validator's address
func (rs RegistrationState) GetValAddr(key bls12381.PublicKey) (sdk.ValAddress, error) {
pkKey := types.BlsKeyToAddrKey(key)
rawBytes := rs.blsKeysToAddr.Get(pkKey)
if rawBytes == nil {
return nil, types.ErrValAddrDoesNotExist.Wrapf("validator address does not exist with BLS public key %s", key)
}
addr := new(sdk.ValAddress)
err := addr.Unmarshal(rawBytes)

return *addr, err
}

// Exists checks whether a BLS key exists
func (rs RegistrationState) Exists(addr sdk.ValAddress) bool {
pkKey := types.AddrToBlsKeyKey(addr)
Expand Down
1 change: 1 addition & 0 deletions x/checkpointing/types/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ var (
ErrConflictingCheckpoint = errorsmod.Register(ModuleName, 1213, "Conflicting checkpoint is found")
ErrInvalidAppHash = errorsmod.Register(ModuleName, 1214, "Provided app hash is Invalid")
ErrInsufficientVotingPower = errorsmod.Register(ModuleName, 1215, "Accumulated voting power is not greater than 2/3 of total power")
ErrValAddrDoesNotExist = errorsmod.Register(ModuleName, 1216, "validator address does not exist")
)
Loading
Loading