Skip to content

Commit

Permalink
chore: Remove key creation in create-finality-provider (#168)
Browse files Browse the repository at this point in the history
Closes #162. Also marked some flags as required:
- eots-pk
- chain-id
- key-name
- commission
- moniker
  • Loading branch information
gitferry authored Nov 28, 2024
1 parent 36f1f9d commit 965510a
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 57 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ empty HD path to derive new key and use master private key.
* [#153](https://github.com/babylonlabs-io/finality-provider/pull/153) Add `unsafe-commit-pubrand` command
* [#154](https://github.com/babylonlabs-io/finality-provider/pull/154) Use sign schnorr instead of getting private key from EOTS manager
* [#167](https://github.com/babylonlabs-io/finality-provider/pull/167) Remove last processed height
* [#168](https://github.com/babylonlabs-io/finality-provider/pull/168) Remove key creation in `create-finality-provider`

### v0.12.1

Expand Down
43 changes: 30 additions & 13 deletions finality-provider/cmd/fpd/daemon/daemon_commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,8 @@ func CommandCreateFP() *cobra.Command {
Use: "create-finality-provider",
Aliases: []string{"cfp"},
Short: "Create a finality provider object and save it in database.",
Long: fmt.Sprintf(`
Create a new finality provider object and store it in the finality provider database.
It needs to have an operating EOTS manager available and running.
If the flag %s is set, it will ask for the key record from the EOTS manager for the
corresponding EOTS public key. If it is not set, it will create a new EOTS key`, fpEotsPkFlag),
Long: "Create a new finality provider object and store it in the finality provider database. " +
"It needs to have an operating EOTS manager available and running.",
Example: fmt.Sprintf(`fpd create-finality-provider --daemon-address %s ...`, defaultFpdDaemonAddress),
Args: cobra.NoArgs,
RunE: fpcmd.RunEWithClientCtx(runCommandCreateFP),
Expand All @@ -98,7 +94,24 @@ func CommandCreateFP() *cobra.Command {
f.String(websiteFlag, "", "An optional website link")
f.String(securityContactFlag, "", "An email for security contact")
f.String(detailsFlag, "", "Other optional details")
f.String(fpEotsPkFlag, "", "Optional hex EOTS public key, if not provided a new one will be created")
f.String(fpEotsPkFlag, "", "The hex string of the EOTS public key")

// make flags required
if err := cmd.MarkFlagRequired(chainIDFlag); err != nil {
panic(err)
}
if err := cmd.MarkFlagRequired(keyNameFlag); err != nil {
panic(err)
}
if err := cmd.MarkFlagRequired(monikerFlag); err != nil {
panic(err)
}
if err := cmd.MarkFlagRequired(commissionRateFlag); err != nil {
panic(err)
}
if err := cmd.MarkFlagRequired(fpEotsPkFlag); err != nil {
panic(err)
}

return cmd
}
Expand Down Expand Up @@ -129,6 +142,10 @@ func runCommandCreateFP(ctx client.Context, cmd *cobra.Command, _ []string) erro
return fmt.Errorf("not able to load key name: %w", err)
}

if keyName == "" {
return fmt.Errorf("keyname cannot be empty")
}

client, cleanUp, err := dc.NewFinalityProviderServiceGRpcClient(daemonAddress)
if err != nil {
return err
Expand All @@ -144,6 +161,10 @@ func runCommandCreateFP(ctx client.Context, cmd *cobra.Command, _ []string) erro
return fmt.Errorf("failed to read flag %s: %w", chainIDFlag, err)
}

if chainID == "" {
return fmt.Errorf("chain-id cannot be empty")
}

passphrase, err := flags.GetString(passphraseFlag)
if err != nil {
return fmt.Errorf("failed to read flag %s: %w", passphraseFlag, err)
Expand All @@ -159,12 +180,8 @@ func runCommandCreateFP(ctx client.Context, cmd *cobra.Command, _ []string) erro
return fmt.Errorf("failed to read flag %s: %w", fpEotsPkFlag, err)
}

if len(eotsPkHex) > 0 {
// if is set, validate before the creation request
_, err := types.NewBIP340PubKeyFromHex(eotsPkHex)
if err != nil {
return fmt.Errorf("invalid eots public key %s: %w", eotsPkHex, err)
}
if eotsPkHex == "" {
return fmt.Errorf("eots-pk cannot be empty")
}

info, err := client.CreateFinalityProvider(
Expand Down
33 changes: 11 additions & 22 deletions finality-provider/service/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -405,44 +405,33 @@ func (app *FinalityProviderApp) handleCreateFinalityProviderRequest(req *createF
fpAddr, err := kr.Address(req.passPhrase)
if err != nil {
// the chain key does not exist, should create the chain key first
keyInfo, err := kr.CreateChainKey(req.passPhrase, req.hdPath, "")
if err != nil {
return nil, fmt.Errorf("failed to create chain key %s: %w", req.keyName, err)
}
fpAddr = keyInfo.AccAddress
return nil, fmt.Errorf("the keyname %s does not exist, add the key first: %w", req.keyName, err)
}

// 2. create EOTS key
fpPk := req.eotsPk
// 2. create proof-of-possession
if req.eotsPk == nil {
fpPkBytes, err := app.eotsManager.CreateKey(req.keyName, req.passPhrase, req.hdPath)
if err != nil {
return nil, err
}
fpPk, err = bbntypes.NewBIP340PubKey(fpPkBytes)
if err != nil {
return nil, err
}
return nil, fmt.Errorf("eots pk cannot be nil")
}

// 3. create proof-of-possession
pop, err := app.CreatePop(fpAddr, fpPk, req.passPhrase)
pop, err := app.CreatePop(fpAddr, req.eotsPk, req.passPhrase)
if err != nil {
return nil, fmt.Errorf("failed to create proof-of-possession of the finality-provider: %w", err)
}

if err := app.fps.CreateFinalityProvider(fpAddr, fpPk.MustToBTCPK(), req.description, req.commission, req.keyName, req.chainID, pop.BtcSig); err != nil {
btcPk := req.eotsPk.MustToBTCPK()
if err := app.fps.CreateFinalityProvider(fpAddr, btcPk, req.description, req.commission, req.keyName, req.chainID, pop.BtcSig); err != nil {
return nil, fmt.Errorf("failed to save finality-provider: %w", err)
}
app.fpManager.metrics.RecordFpStatus(fpPk.MarshalHex(), proto.FinalityProviderStatus_CREATED)

pkHex := req.eotsPk.MarshalHex()
app.fpManager.metrics.RecordFpStatus(pkHex, proto.FinalityProviderStatus_CREATED)

app.logger.Info("successfully created a finality-provider",
zap.String("btc_pk", fpPk.MarshalHex()),
zap.String("eots_pk", pkHex),
zap.String("addr", fpAddr.String()),
zap.String("key_name", req.keyName),
)

storedFp, err := app.fps.GetFinalityProvider(fpPk.MustToBTCPK())
storedFp, err := app.fps.GetFinalityProvider(btcPk)
if err != nil {
return nil, err
}
Expand Down
36 changes: 21 additions & 15 deletions finality-provider/service/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,22 +83,16 @@ func FuzzRegisterFinalityProvider(f *testing.F) {
}()

var eotsPk *bbntypes.BIP340PubKey
eotsPk = nil
generateEotsKeyBefore := r.Int31n(10) > 5
if generateEotsKeyBefore {
// sometimes uses the previously generated EOTS pk
eotsKeyName := testutil.GenRandomHexStr(r, 4)
eotsPkBz, err := em.CreateKey(eotsKeyName, passphrase, hdPath)
require.NoError(t, err)
eotsPk, err = bbntypes.NewBIP340PubKey(eotsPkBz)
require.NoError(t, err)
}
eotsKeyName := testutil.GenRandomHexStr(r, 4)
require.NoError(t, err)
eotsPkBz, err := em.CreateKey(eotsKeyName, passphrase, hdPath)
require.NoError(t, err)
eotsPk, err = bbntypes.NewBIP340PubKey(eotsPkBz)
require.NoError(t, err)

// create a finality-provider object and save it to db
fp := testutil.GenStoredFinalityProvider(r, t, app, passphrase, hdPath, eotsPk)
if generateEotsKeyBefore {
require.Equal(t, eotsPk, bbntypes.NewBIP340PubKeyFromBTCPK(fp.BtcPk))
}
require.Equal(t, eotsPk, bbntypes.NewBIP340PubKeyFromBTCPK(fp.BtcPk))

btcSig := new(bbntypes.BIP340Signature)
err = btcSig.Unmarshal(fp.Pop.BtcSig)
Expand Down Expand Up @@ -199,7 +193,13 @@ func FuzzSyncFinalityProviderStatus(f *testing.F) {
err = app.Start()
require.NoError(t, err)

fp := testutil.GenStoredFinalityProvider(r, t, app, "", hdPath, nil)
eotsKeyName := testutil.GenRandomHexStr(r, 4)
require.NoError(t, err)
eotsPkBz, err := em.CreateKey(eotsKeyName, passphrase, hdPath)
require.NoError(t, err)
eotsPk, err := bbntypes.NewBIP340PubKey(eotsPkBz)
require.NoError(t, err)
fp := testutil.GenStoredFinalityProvider(r, t, app, "", hdPath, eotsPk)

require.Eventually(t, func() bool {
fpPk := fp.GetBIP340BTCPK()
Expand Down Expand Up @@ -277,7 +277,13 @@ func FuzzUnjailFinalityProvider(f *testing.F) {
}()
require.NoError(t, err)

fp := testutil.GenStoredFinalityProvider(r, t, app, "", hdPath, nil)
eotsKeyName := testutil.GenRandomHexStr(r, 4)
require.NoError(t, err)
eotsPkBz, err := em.CreateKey(eotsKeyName, passphrase, hdPath)
require.NoError(t, err)
eotsPk, err := bbntypes.NewBIP340PubKey(eotsPkBz)
require.NoError(t, err)
fp := testutil.GenStoredFinalityProvider(r, t, app, "", hdPath, eotsPk)
err = app.GetFinalityProviderStore().SetFpStatus(fp.BtcPk, proto.FinalityProviderStatus_JAILED)
require.NoError(t, err)

Expand Down
9 changes: 8 additions & 1 deletion finality-provider/service/fp_instance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"path/filepath"
"testing"

bbntypes "github.com/babylonlabs-io/babylon/types"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/require"
"go.uber.org/zap"
Expand Down Expand Up @@ -122,7 +123,13 @@ func startFinalityProviderAppWithRegisteredFp(t *testing.T, r *rand.Rand, cc cli
require.NoError(t, err)

// create registered finality-provider
fp := testutil.GenStoredFinalityProvider(r, t, app, passphrase, hdPath, nil)
eotsKeyName := testutil.GenRandomHexStr(r, 4)
require.NoError(t, err)
eotsPkBz, err := em.CreateKey(eotsKeyName, passphrase, hdPath)
require.NoError(t, err)
eotsPk, err := bbntypes.NewBIP340PubKey(eotsPkBz)
require.NoError(t, err)
fp := testutil.GenStoredFinalityProvider(r, t, app, passphrase, hdPath, eotsPk)
pubRandProofStore := app.GetPubRandProofStore()
fpStore := app.GetFinalityProviderStore()
err = fpStore.SetFpStatus(fp.BtcPk, proto.FinalityProviderStatus_REGISTERED)
Expand Down
11 changes: 6 additions & 5 deletions finality-provider/service/rpcserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func (r *rpcServer) CreateFinalityProvider(
return nil, err
}

eotsPk, err := parseOptEotsPk(req.EotsPkHex)
eotsPk, err := parseEotsPk(req.EotsPkHex)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -296,9 +296,10 @@ func (r *rpcServer) SignMessageFromChainKey(_ context.Context, req *proto.SignMe
return &proto.SignMessageFromChainKeyResponse{Signature: signature}, nil
}

func parseOptEotsPk(eotsPkHex string) (*bbntypes.BIP340PubKey, error) {
if len(eotsPkHex) > 0 {
return bbntypes.NewBIP340PubKeyFromHex(eotsPkHex)
func parseEotsPk(eotsPkHex string) (*bbntypes.BIP340PubKey, error) {
if eotsPkHex == "" {
return nil, fmt.Errorf("eots-pk cannot be empty")
}
return nil, nil

return bbntypes.NewBIP340PubKeyFromHex(eotsPkHex)
}
8 changes: 7 additions & 1 deletion itest/test_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,13 @@ func StartManagerWithFinalityProvider(t *testing.T) (*TestManager, *service.Fina
_, _, err = tm.manager.BabylondTxBankSend(t, fpBbnKeyInfo.AccAddress.String(), "1000000ubbn", "node0")
require.NoError(t, err)

res, err := app.CreateFinalityProvider(testFpName, testChainID, passphrase, hdPath, nil, desc, &commission)
eotsKeyName := "eots-key"
require.NoError(t, err)
eotsPkBz, err := tm.EOTSClient.CreateKey(eotsKeyName, passphrase, hdPath)
require.NoError(t, err)
eotsPk, err := bbntypes.NewBIP340PubKey(eotsPkBz)
require.NoError(t, err)
res, err := app.CreateFinalityProvider(testFpName, testChainID, passphrase, hdPath, eotsPk, desc, &commission)
require.NoError(t, err)
fpPk, err := bbntypes.NewBIP340PubKeyFromHex(res.FpInfo.BtcPkHex)
require.NoError(t, err)
Expand Down

0 comments on commit 965510a

Please sign in to comment.