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/resolve ci error #7

Draft
wants to merge 10 commits into
base: main
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)

### Improvements

- [#396](https://github.com/babylonlabs-io/babylon/pull/396) BLS Key Separation and ERC2335 Implementation
- [#391](https://github.com/babylonlabs-io/babylon/pull/391) Fix e2e `TestBTCRewardsDistribution` flunky
check of rewards

Expand Down
26 changes: 18 additions & 8 deletions app/signer/private.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import (
"path/filepath"

cmtconfig "github.com/cometbft/cometbft/config"
cmtos "github.com/cometbft/cometbft/libs/os"

"github.com/babylonlabs-io/babylon/privval"
cmtprivval "github.com/cometbft/cometbft/privval"
)

type PrivSigner struct {
Expand All @@ -15,17 +15,27 @@ type PrivSigner struct {

func InitPrivSigner(nodeDir string) (*PrivSigner, error) {
nodeCfg := cmtconfig.DefaultConfig()
blsCfg := privval.DefaultBlsConfig()

pvKeyFile := filepath.Join(nodeDir, nodeCfg.PrivValidatorKeyFile())
err := cmtos.EnsureDir(filepath.Dir(pvKeyFile), 0777)
if err != nil {
return nil, err
}
pvStateFile := filepath.Join(nodeDir, nodeCfg.PrivValidatorStateFile())
err = cmtos.EnsureDir(filepath.Dir(pvStateFile), 0777)
if err != nil {
blsKeyFile := filepath.Join(nodeDir, blsCfg.BlsKeyFile())
blsPasswordFile := filepath.Join(nodeDir, blsCfg.BlsPasswordFile())

if err := privval.IsValidFilePath(pvKeyFile, pvStateFile, blsKeyFile, blsPasswordFile); err != nil {
return nil, err
}
wrappedPV := privval.LoadOrGenWrappedFilePV(pvKeyFile, pvStateFile)

cometPV := cmtprivval.LoadFilePV(pvKeyFile, pvStateFile)
blsPV := privval.LoadBlsPV(blsKeyFile, blsPasswordFile)

wrappedPV := &privval.WrappedFilePV{
Key: privval.WrappedFilePVKey{
CometPVKey: cometPV.Key,
BlsPVKey: blsPV.Key,
},
LastSignState: cometPV.LastSignState,
}

return &PrivSigner{
WrappedPV: wrappedPV,
Expand Down
4 changes: 2 additions & 2 deletions app/test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,14 +239,14 @@ func SetupWithBitcoinConf(t *testing.T, isCheckTx bool, btcConf bbn.SupportedBtc

ps, err := signer.SetupTestPrivSigner()
require.NoError(t, err)
valPubKey := ps.WrappedPV.Key.PubKey
valPubKey := ps.WrappedPV.Key.CometPVKey.PubKey
// generate genesis account
acc := authtypes.NewBaseAccount(valPubKey.Address().Bytes(), &cosmosed.PubKey{Key: valPubKey.Bytes()}, 0, 0)
balance := banktypes.Balance{
Address: acc.GetAddress().String(),
Coins: sdk.NewCoins(sdk.NewCoin(appparams.DefaultBondDenom, math.NewInt(100000000000000))),
}
ps.WrappedPV.Key.DelegatorAddress = acc.GetAddress().String()
ps.WrappedPV.Key.BlsPVKey.DelegatorAddress = acc.GetAddress().String()
// create validator set with single validator
genesisKey, err := signer.GenesisKeyFromPrivSigner(ps)
require.NoError(t, err)
Expand Down
5 changes: 5 additions & 0 deletions client/flags/flags.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package flags

const (
FlagBlsPassword = "bls-password"
)
29 changes: 5 additions & 24 deletions cmd/babylond/cmd/create_bls_key.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
package cmd

import (
"errors"
"fmt"
"path/filepath"
"strings"

cmtconfig "github.com/cometbft/cometbft/config"
cmtos "github.com/cometbft/cometbft/libs/os"
"github.com/cosmos/cosmos-sdk/client/flags"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/spf13/cobra"

"github.com/babylonlabs-io/babylon/app"
appparams "github.com/babylonlabs-io/babylon/app/params"
"github.com/babylonlabs-io/babylon/crypto/bls12381"
"github.com/babylonlabs-io/babylon/privval"
)

Expand Down Expand Up @@ -56,29 +52,14 @@
return cmd
}

func CreateBlsKey(home string, addr sdk.AccAddress) error {

Check failure on line 55 in cmd/babylond/cmd/create_bls_key.go

View workflow job for this annotation

GitHub Actions / lint_test / lint

unnecessary leading newline (whitespace)
nodeCfg := cmtconfig.DefaultConfig()
keyPath := filepath.Join(home, nodeCfg.PrivValidatorKeyFile())
statePath := filepath.Join(home, nodeCfg.PrivValidatorStateFile())

pv, err := LoadWrappedFilePV(keyPath, statePath)
if err != nil {
return err
}
blsCfg := privval.DefaultBlsConfig()
keyPath := filepath.Join(home, blsCfg.BlsKeyFile())
passwordPath := filepath.Join(home, blsCfg.BlsPasswordFile())

wrappedPV := privval.NewWrappedFilePV(pv.GetValPrivKey(), bls12381.GenPrivKey(), keyPath, statePath)
wrappedPV.SetAccAddress(addr)
password := privval.GetBlsPassword()

privval.GenBlsPV(keyPath, passwordPath, password, addr.String())
return nil
}

// LoadWrappedFilePV loads the wrapped file private key from the file path.
func LoadWrappedFilePV(keyPath, statePath string) (*privval.WrappedFilePV, error) {
if !cmtos.FileExists(keyPath) {
return nil, errors.New("validator key file does not exist")
}
if !cmtos.FileExists(statePath) {
return nil, errors.New("validator state file does not exist")
}
return privval.LoadWrappedFilePV(keyPath, statePath), nil
}
30 changes: 26 additions & 4 deletions cmd/babylond/cmd/genhelpers/bls_add_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package genhelpers_test
import (
"context"
"fmt"
"os"
"path/filepath"
"testing"

Expand All @@ -20,6 +21,7 @@ import (
cmtconfig "github.com/cometbft/cometbft/config"
tmjson "github.com/cometbft/cometbft/libs/json"
"github.com/cometbft/cometbft/libs/tempfile"
cmtprivval "github.com/cometbft/cometbft/privval"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/server"
Expand Down Expand Up @@ -147,13 +149,26 @@ func Test_CmdAddBlsWithGentx(t *testing.T) {
v := testNetwork.Validators[i]
// build and create genesis BLS key
genBlsCmd := genhelpers.CmdCreateBls()
nodeCfg := cmtconfig.DefaultConfig()
homeDir := filepath.Join(v.Dir, "simd")

nodeCfg := cmtconfig.DefaultConfig()
nodeCfg.SetRoot(homeDir)
blsCfg := privval.DefaultBlsConfig()
blsCfg.SetRoot(homeDir)

keyPath := nodeCfg.PrivValidatorKeyFile()
statePath := nodeCfg.PrivValidatorStateFile()
filePV := privval.GenWrappedFilePV(keyPath, statePath)
filePV.SetAccAddress(v.Address)
blsKeyFile := blsCfg.BlsKeyFile()
blsPasswordFile := blsCfg.BlsPasswordFile()

err := privval.IsValidFilePath(keyPath, statePath, blsKeyFile, blsPasswordFile)
require.NoError(t, err)

filePV := cmtprivval.GenFilePV(keyPath, statePath)
filePV.Key.Save()
filePV.LastSignState.Save()
privval.GenBlsPV(blsKeyFile, blsPasswordFile, "password", v.Address.String())

_, 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))
Expand All @@ -175,6 +190,13 @@ func Test_CmdAddBlsWithGentx(t *testing.T) {
require.NotEmpty(t, checkpointingGenState.GenesisKeys)
gks := checkpointingGenState.GetGenesisKeys()
require.Equal(t, genKey, gks[i])
filePV.Clean(keyPath, statePath)
Clean(keyPath, statePath, blsKeyFile, blsPasswordFile)
}
}

// Clean removes PVKey file and PVState file
func Clean(paths ...string) {
for _, path := range paths {
_ = os.RemoveAll(filepath.Dir(path))
}
}
23 changes: 18 additions & 5 deletions cmd/babylond/cmd/genhelpers/bls_create.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
package genhelpers

import (
"errors"
"path/filepath"
"strings"

cmtconfig "github.com/cometbft/cometbft/config"
cmtos "github.com/cometbft/cometbft/libs/os"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/spf13/cobra"

"github.com/babylonlabs-io/babylon/app"
"github.com/babylonlabs-io/babylon/privval"
cmtprivval "github.com/cometbft/cometbft/privval"
)

// CmdCreateBls CLI command to create BLS file with proof of possession.
Expand All @@ -35,13 +34,27 @@ $ babylond genbls --home ./
homeDir, _ := cmd.Flags().GetString(flags.FlagHome)

nodeCfg := cmtconfig.DefaultConfig()
blsCfg := privval.DefaultBlsConfig()

keyPath := filepath.Join(homeDir, nodeCfg.PrivValidatorKeyFile())
statePath := filepath.Join(homeDir, nodeCfg.PrivValidatorStateFile())
if !cmtos.FileExists(keyPath) {
return errors.New("validator key file does not exist")
blsKeyPath := filepath.Join(homeDir, blsCfg.BlsKeyFile())
blsPasswordPath := filepath.Join(homeDir, blsCfg.BlsPasswordFile())

if err := privval.IsValidFilePath(keyPath, statePath, blsKeyPath, blsPasswordPath); err != nil {
return err
}

wrappedPV := privval.LoadWrappedFilePV(keyPath, statePath)
filePV := cmtprivval.LoadFilePV(keyPath, statePath)
blsPV := privval.LoadBlsPV(blsKeyPath, blsPasswordPath)

wrappedPV := &privval.WrappedFilePV{
Key: privval.WrappedFilePVKey{
CometPVKey: filePV.Key,
BlsPVKey: blsPV.Key,
},
LastSignState: filePV.LastSignState,
}

outputFileName, err := wrappedPV.ExportGenBls(filepath.Dir(keyPath))
if err != nil {
Expand Down
21 changes: 17 additions & 4 deletions cmd/babylond/cmd/genhelpers/bls_create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/babylonlabs-io/babylon/privval"
"github.com/babylonlabs-io/babylon/testutil/signer"
"github.com/babylonlabs-io/babylon/x/checkpointing/types"
cmtprivval "github.com/cometbft/cometbft/privval"
)

func Test_CmdCreateBls(t *testing.T) {
Expand Down Expand Up @@ -70,21 +71,33 @@ func Test_CmdCreateBls(t *testing.T) {

// create BLS keys
nodeCfg := cmtconfig.DefaultConfig()
blsCfg := privval.DefaultBlsConfig()

keyPath := filepath.Join(home, nodeCfg.PrivValidatorKeyFile())
statePath := filepath.Join(home, nodeCfg.PrivValidatorStateFile())
filePV := privval.GenWrappedFilePV(keyPath, statePath)
defer filePV.Clean(keyPath, statePath)
filePV.SetAccAddress(addr)
blsKeyFile := filepath.Join(home, blsCfg.BlsKeyFile())
blsPasswordFile := filepath.Join(home, blsCfg.BlsPasswordFile())

err = privval.IsValidFilePath(keyPath, statePath, blsKeyFile, blsPasswordFile)
require.NoError(t, err)

filePV := cmtprivval.GenFilePV(keyPath, statePath)
filePV.Key.Save()

blsPV := privval.GenBlsPV(blsKeyFile, blsPasswordFile, "password", addr.String())
defer Clean(keyPath, statePath, blsKeyFile, blsPasswordFile)

// execute the gen-bls cmd
err = genBlsCmd.ExecuteContext(ctx)
require.NoError(t, err)
outputFilePath := filepath.Join(filepath.Dir(keyPath), fmt.Sprintf("gen-bls-%s.json", sdk.ValAddress(addr).String()))
require.NoError(t, err)
genKey, err := types.LoadGenesisKeyFromFile(outputFilePath)

require.NoError(t, err)
require.Equal(t, sdk.ValAddress(addr).String(), genKey.ValidatorAddress)
require.True(t, filePV.Key.BlsPubKey.Equal(*genKey.BlsKey.Pubkey))
require.Equal(t, filePV.Key.PubKey.Bytes(), genKey.ValPubkey.Bytes())
require.True(t, blsPV.Key.PubKey.Equal(*genKey.BlsKey.Pubkey))

require.True(t, genKey.BlsKey.Pop.IsValid(*genKey.BlsKey.Pubkey, genKey.ValPubkey))
}
83 changes: 83 additions & 0 deletions crypto/erc2335/erc2335.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package erc2335

import (
"crypto/rand"
"encoding/hex"
"encoding/json"
"fmt"
"os"

"github.com/pkg/errors"
keystorev4 "github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4"
)

type Erc2335KeyStore struct {
Crypto map[string]interface{} `json:"crypto"`
Version uint `json:"version"`
UUID string `json:"uuid"`
Path string `json:"path"`
Pubkey string `json:"pubkey"`
Description string `json:"description"`
}

// wonjoon: encrypt key pair to erc2335 keystore
// available to handle all keys in []byte format
func Encrypt(privKey, pubKey []byte, password string) ([]byte, error) {
if privKey == nil {
return nil, errors.New("private key cannot be nil")
}

encryptor := keystorev4.New()
cryptoFields, err := encryptor.Encrypt(privKey, password)
if err != nil {
return nil, errors.Wrap(err, "failed to encrypt private key")
}

// Create the keystore json structure
keystoreJSON := Erc2335KeyStore{
Crypto: cryptoFields,
Version: 4,
Pubkey: fmt.Sprintf("%x", pubKey),
}

return json.Marshal(keystoreJSON)
}

func LoadKeyStore(filePath string) (Erc2335KeyStore, error) {
var keystore Erc2335KeyStore

keyJSONBytes, err := os.ReadFile(filePath)
if err != nil {
return Erc2335KeyStore{}, err
}

if err := json.Unmarshal(keyJSONBytes, &keystore); err != nil {
return Erc2335KeyStore{}, err
}

return keystore, nil
}

// decrypt private key from erc2335 keystore
func Decrypt(keystore Erc2335KeyStore, password string) ([]byte, error) {
encryptor := keystorev4.New()
return encryptor.Decrypt(keystore.Crypto, password)
}

func SavePasswordToFile(password, filePath string) error {
return os.WriteFile(filePath, []byte(password), 0600)
}

func LoadPaswordFromFile(filePath string) (string, error) {
password, err := os.ReadFile(filePath)
return string(password), err
}

func CreateRandomPassword() string {
password := make([]byte, 32)
_, err := rand.Read(password)
if err != nil {
panic(err)
}
return hex.EncodeToString(password)
}
Loading
Loading