From 1c678fdb0f04d73c4efaf0b050329ce0ce59426f Mon Sep 17 00:00:00 2001 From: Cirrus Gai Date: Mon, 27 Jan 2025 17:41:43 +0800 Subject: [PATCH] chore: Improve fpd start (#294) Closes #289. With this pr, the `fpd start` flow becomes the follows: - If --eots-pk is specified, start the specified fp instance. Otherwise, - if no fp records found from db, start the daemon and show logs asking for registration - if there's one fp record found from db, start the daemon with the fp - if there are multiple fp record found from db, fail the cmd execution asking for set of --eots-pk --- CHANGELOG.md | 1 + docs/finality-provider-operation.md | 7 ++++- eotsmanager/cmd/eotsd/daemon/pop.go | 21 ++++++++++++-- finality-provider/cmd/cmd_test.go | 4 +-- .../cmd/fpd/daemon/daemon_commands.go | 2 ++ finality-provider/cmd/fpd/daemon/start.go | 29 ++++++++++++++----- finality-provider/service/app.go | 12 +++----- go.mod | 5 ++-- go.sum | 9 ++++-- itest/test_manager.go | 7 +++-- 10 files changed, 68 insertions(+), 29 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa0d6d3a..86d8cbc9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) * [#284](https://github.com/babylonlabs-io/finality-provider/pull/284) Add new command to delete pop * [#277](https://github.com/babylonlabs-io/finality-provider/pull/277) Poll many blocks in poller * [#291](https://github.com/babylonlabs-io/finality-provider/pull/291) chore: remove skip height +* [#294](https://github.com/babylonlabs-io/finality-provider/pull/294) chore: Improve fpd start * [#297](https://github.com/babylonlabs-io/finality-provider/pull/297) Add new command to validate pop * [#302](https://github.com/babylonlabs-io/finality-provider/pull/302) Update pop commands to write to a file diff --git a/docs/finality-provider-operation.md b/docs/finality-provider-operation.md index 9465138d..c3a60f34 100644 --- a/docs/finality-provider-operation.md +++ b/docs/finality-provider-operation.md @@ -580,7 +580,8 @@ your finality provider's details: "status": "REGISTERED" } "tx_hash": "C08377CF289DF0DC5FA462E6409ADCB65A3492C22A112C58EA449F4DC544A3B1" -} +} +Your finality provider is successfully created. Please restart your fpd. ``` The response includes: @@ -623,6 +624,10 @@ by running: fpd start --eots-pk ``` +If `--eots-pk` is not specified, the command will start the finality provider +if it is the only one stored in the database. If multiple finality providers +are in the database, specifying `--eots-pk` is required. + ### 5.2. Editing your finality provider If you need to edit your finality provider's information, you can use the diff --git a/eotsmanager/cmd/eotsd/daemon/pop.go b/eotsmanager/cmd/eotsd/daemon/pop.go index 8660ad54..bd79c880 100644 --- a/eotsmanager/cmd/eotsd/daemon/pop.go +++ b/eotsmanager/cmd/eotsd/daemon/pop.go @@ -6,6 +6,7 @@ import ( "fmt" "io" "os" + "path/filepath" "strconv" "github.com/btcsuite/btcd/btcec/v2/schnorr" @@ -19,6 +20,7 @@ import ( bbnparams "github.com/babylonlabs-io/babylon/app/params" bbntypes "github.com/babylonlabs-io/babylon/types" + "github.com/babylonlabs-io/finality-provider/codec" "github.com/babylonlabs-io/finality-provider/eotsmanager" "github.com/babylonlabs-io/finality-provider/eotsmanager/config" @@ -153,9 +155,10 @@ func NewPopDeleteCmd() *cobra.Command { } func validatePop(cmd *cobra.Command, args []string) error { - filePath := args[0] + path := args[0] - bzExportJSON, err := os.ReadFile(filePath) + // Add path validation + bzExportJSON, err := os.ReadFile(filepath.Clean(path)) if err != nil { return fmt.Errorf("failed to read pop file: %w", err) } @@ -363,7 +366,19 @@ func handleOutputJSON(cmd *cobra.Command, out any) error { } if len(outputFilePath) > 0 { - if err := os.WriteFile(outputFilePath, jsonBz, 0644); err != nil { + // Add path validation + cleanPath, err := filepath.Abs(filepath.Clean(outputFilePath)) + if err != nil { + return fmt.Errorf("invalid output file path: %w", err) + } + + // Create directory if it doesn't exist + dir := filepath.Dir(cleanPath) + if err := os.MkdirAll(dir, 0750); err != nil { + return fmt.Errorf("failed to create output directory: %w", err) + } + + if err := os.WriteFile(cleanPath, jsonBz, 0600); err != nil { return fmt.Errorf("failed to write output file: %w", err) } } diff --git a/finality-provider/cmd/cmd_test.go b/finality-provider/cmd/cmd_test.go index c4ddf729..e804c3b1 100644 --- a/finality-provider/cmd/cmd_test.go +++ b/finality-provider/cmd/cmd_test.go @@ -6,16 +6,16 @@ import ( "path/filepath" "testing" + "github.com/babylonlabs-io/babylon/testutil/datagen" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" + goflags "github.com/jessevdk/go-flags" "github.com/spf13/cobra" "github.com/stretchr/testify/require" - "github.com/babylonlabs-io/babylon/testutil/datagen" fpcmd "github.com/babylonlabs-io/finality-provider/finality-provider/cmd" fpcfg "github.com/babylonlabs-io/finality-provider/finality-provider/config" "github.com/babylonlabs-io/finality-provider/util" - goflags "github.com/jessevdk/go-flags" ) func TestPersistClientCtx(t *testing.T) { diff --git a/finality-provider/cmd/fpd/daemon/daemon_commands.go b/finality-provider/cmd/fpd/daemon/daemon_commands.go index 116c2bd0..e8308195 100644 --- a/finality-provider/cmd/fpd/daemon/daemon_commands.go +++ b/finality-provider/cmd/fpd/daemon/daemon_commands.go @@ -199,6 +199,8 @@ func runCommandCreateFP(ctx client.Context, cmd *cobra.Command, _ []string) erro printRespJSON(res) + cmd.Println("Your finality provider is successfully created. Please restart your fpd.") + return nil } diff --git a/finality-provider/cmd/fpd/daemon/start.go b/finality-provider/cmd/fpd/daemon/start.go index 3b65cb0a..c759331b 100644 --- a/finality-provider/cmd/fpd/daemon/start.go +++ b/finality-provider/cmd/fpd/daemon/start.go @@ -8,6 +8,7 @@ import ( "github.com/babylonlabs-io/babylon/types" "github.com/btcsuite/btcwallet/walletdb" "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/spf13/cobra" "go.uber.org/zap" @@ -31,6 +32,7 @@ func CommandStart() *cobra.Command { cmd.Flags().String(fpEotsPkFlag, "", "The EOTS public key of the finality-provider to start") cmd.Flags().String(passphraseFlag, "", "The pass phrase used to decrypt the private key") cmd.Flags().String(rpcListenerFlag, "", "The address that the RPC server listens to") + cmd.Flags().String(flags.FlagHome, fpcfg.DefaultFpdDir, "The application home directory") return cmd } @@ -121,20 +123,31 @@ func startApp( return fmt.Errorf("failed to start the finality provider app: %w", err) } - // no fp instance will be started if public key is not specified - if fpPkStr == "" { - return nil + // fp instance will be started if public key is specified + if fpPkStr != "" { + // start the finality-provider instance with the given public key + fpPk, err := types.NewBIP340PubKeyFromHex(fpPkStr) + if err != nil { + return fmt.Errorf("invalid finality provider public key %s: %w", fpPkStr, err) + } + + return fpApp.StartFinalityProvider(fpPk, passphrase) } - // start the finality-provider instance with the given public key - fpPk, err := types.NewBIP340PubKeyFromHex(fpPkStr) + storedFps, err := fpApp.GetFinalityProviderStore().GetAllStoredFinalityProviders() if err != nil { - return fmt.Errorf("invalid finality provider public key %s: %w", fpPkStr, err) + return err } - if err := fpApp.StartFinalityProvider(fpPk, passphrase); err != nil { - return fmt.Errorf("failed to start the finality-provider instance %s: %w", fpPkStr, err) + if len(storedFps) == 1 { + return fpApp.StartFinalityProvider(types.NewBIP340PubKeyFromBTCPK(storedFps[0].BtcPk), passphrase) } + if len(storedFps) > 1 { + return fmt.Errorf("%d finality providers found in DB. Please specify the EOTS public key", len(storedFps)) + } + + fpApp.Logger().Info("No finality providers found in DB. Waiting for registration.") + return nil } diff --git a/finality-provider/service/app.go b/finality-provider/service/app.go index 46dd46a7..0361ae84 100644 --- a/finality-provider/service/app.go +++ b/finality-provider/service/app.go @@ -176,6 +176,10 @@ func (app *FinalityProviderApp) GetFinalityProviderInstance() (*FinalityProvider return app.fpIns, nil } +func (app *FinalityProviderApp) Logger() *zap.Logger { + return app.logger +} + // StartFinalityProvider starts a finality provider instance with the given EOTS public key // Note: this should be called right after the finality-provider is registered func (app *FinalityProviderApp) StartFinalityProvider(fpPk *bbntypes.BIP340PubKey, passphrase string) error { @@ -418,14 +422,6 @@ func (app *FinalityProviderApp) CreateFinalityProvider( return nil, err } - if err = app.startFinalityProviderInstance(storedFp.GetBIP340BTCPK(), ""); err != nil { - app.logger.Error( - "failed to start fp instance", - zap.String("eots_pk", pkHex), - zap.Error(err), - ) - } - return &CreateFinalityProviderResult{ FpInfo: storedFp.ToFinalityProviderInfo(), TxHash: successResponse.txHash, diff --git a/go.mod b/go.mod index 2de1b9bc..74b485da 100644 --- a/go.mod +++ b/go.mod @@ -24,7 +24,6 @@ require ( github.com/golang/mock v1.6.0 github.com/jessevdk/go-flags v1.5.0 github.com/jsternberg/zap-logfmt v1.3.0 - github.com/lightningnetwork/lnd v0.16.4-beta.rc1 github.com/lightningnetwork/lnd/kvdb v1.4.1 github.com/ory/dockertest/v3 v3.9.1 github.com/prometheus/client_golang v1.20.5 @@ -51,6 +50,7 @@ require ( cosmossdk.io/depinject v1.0.0 // indirect cosmossdk.io/log v1.4.1 // indirect cosmossdk.io/store v1.1.0 // indirect + cosmossdk.io/tools/confix v0.1.2 // indirect cosmossdk.io/x/circuit v0.1.1 // indirect cosmossdk.io/x/evidence v0.1.1 // indirect cosmossdk.io/x/feegrant v0.1.1 // indirect @@ -93,7 +93,6 @@ require ( github.com/consensys/gnark-crypto v0.12.1 // indirect github.com/containerd/continuity v0.3.0 // indirect github.com/coreos/go-semver v0.3.0 // indirect - github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/cosmos/btcutil v1.0.5 // indirect github.com/cosmos/cosmos-db v1.0.2 // indirect @@ -106,6 +105,8 @@ require ( github.com/cosmos/ics23/go v0.10.0 // indirect github.com/cosmos/ledger-cosmos-go v0.13.3 // indirect github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect + github.com/creachadair/atomicfile v0.3.1 // indirect + github.com/creachadair/tomledit v0.0.24 // indirect github.com/danieljoos/wincred v1.1.2 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/decred/dcrd/crypto/blake256 v1.0.1 // indirect diff --git a/go.sum b/go.sum index 2ac3cee2..db1b4a8e 100644 --- a/go.sum +++ b/go.sum @@ -1330,6 +1330,8 @@ cosmossdk.io/math v1.4.0 h1:XbgExXFnXmF/CccPPEto40gOO7FpWu9yWNAZPN3nkNQ= cosmossdk.io/math v1.4.0/go.mod h1:O5PkD4apz2jZs4zqFdTr16e1dcaQCc5z6lkEnrrppuk= cosmossdk.io/store v1.1.0 h1:LnKwgYMc9BInn9PhpTFEQVbL9UK475G2H911CGGnWHk= cosmossdk.io/store v1.1.0/go.mod h1:oZfW/4Fc/zYqu3JmQcQdUJ3fqu5vnYTn3LZFFy8P8ng= +cosmossdk.io/tools/confix v0.1.2 h1:2hoM1oFCNisd0ltSAAZw2i4ponARPmlhuNu3yy0VwI4= +cosmossdk.io/tools/confix v0.1.2/go.mod h1:7XfcbK9sC/KNgVGxgLM0BrFbVcR/+6Dg7MFfpx7duYo= cosmossdk.io/x/circuit v0.1.1 h1:KPJCnLChWrxD4jLwUiuQaf5mFD/1m7Omyo7oooefBVQ= cosmossdk.io/x/circuit v0.1.1/go.mod h1:B6f/urRuQH8gjt4eLIXfZJucrbreuYrKh5CSjaOxr+Q= cosmossdk.io/x/evidence v0.1.1 h1:Ks+BLTa3uftFpElLTDp9L76t2b58htjVbSZ86aoK/E4= @@ -1554,7 +1556,6 @@ github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmf github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f h1:JOrtw2xFKzlg+cbHpyrpLDmnN1HqhBfnX7WDiW7eG2c= github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= @@ -1598,6 +1599,10 @@ github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 h1:d28BXYi+wUp github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs= github.com/crate-crypto/go-kzg-4844 v0.7.0 h1:C0vgZRk4q4EZ/JgPfzuSoxdCq3C3mOZMBShovmncxvA= github.com/crate-crypto/go-kzg-4844 v0.7.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc= +github.com/creachadair/atomicfile v0.3.1 h1:yQORkHjSYySh/tv5th1dkKcn02NEW5JleB84sjt+W4Q= +github.com/creachadair/atomicfile v0.3.1/go.mod h1:mwfrkRxFKwpNAflYZzytbSwxvbK6fdGRRlp0KEQc0qU= +github.com/creachadair/tomledit v0.0.24 h1:5Xjr25R2esu1rKCbQEmjZYlrhFkDspoAbAKb6QKQDhQ= +github.com/creachadair/tomledit v0.0.24/go.mod h1:9qHbShRWQzSCcn617cMzg4eab1vbLCOjOshAWSzWr8U= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= @@ -2167,8 +2172,6 @@ github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/lightningnetwork/lnd v0.16.4-beta.rc1 h1:L8ktsv1lM5esVtiOlEtOBqU1dCoDckbm0FkcketBskQ= -github.com/lightningnetwork/lnd v0.16.4-beta.rc1/go.mod h1:sK9F98TpFuO/fjLCX4jEjc65qr2GZGs8IquVde1N46I= github.com/lightningnetwork/lnd/healthcheck v1.2.2 h1:im+qcpgSuteqRCGeorT9yqVXuLrS6A7/acYzGgarMS4= github.com/lightningnetwork/lnd/healthcheck v1.2.2/go.mod h1:IWY0GChlarRbXFkFDdE4WY5POYJabe/7/H1iCZt4ZKs= github.com/lightningnetwork/lnd/kvdb v1.4.1 h1:l/nLBPLbdvP/lajMtrFMLzAi5OoLTH3+zUU6SwoEEv8= diff --git a/itest/test_manager.go b/itest/test_manager.go index f3276093..cbdfc22f 100644 --- a/itest/test_manager.go +++ b/itest/test_manager.go @@ -121,7 +121,7 @@ func StartManager(t *testing.T, ctx context.Context) *TestManager { require.Eventually(t, func() bool { bc, err = fpcc.NewBabylonController(cfg.BabylonConfig, &cfg.BTCNetParams, logger) return err == nil - }, 5*time.Second, eventuallyPollTime) + }, 10*time.Second, eventuallyPollTime) // 3. prepare EOTS manager eotsHomeDir := filepath.Join(testDir, "eots-home") @@ -171,7 +171,7 @@ func (tm *TestManager) AddFinalityProvider(t *testing.T, ctx context.Context) *s cfg.BabylonConfig.GRPCAddr = fmt.Sprintf("https://localhost:%s", tm.babylond.GetPort("9090/tcp")) fpBbnKeyInfo, err := testutil.CreateChainKey(cfg.BabylonConfig.KeyDirectory, cfg.BabylonConfig.ChainID, cfg.BabylonConfig.Key, cfg.BabylonConfig.KeyringBackend, passphrase, hdPath, "") require.NoError(t, err) - + // add some funds for new fp pay for fees '-' _, _, err = tm.manager.BabylondTxBankSend(t, fpBbnKeyInfo.AccAddress.String(), "1000000ubbn", "node0") require.NoError(t, err) @@ -197,6 +197,9 @@ func (tm *TestManager) AddFinalityProvider(t *testing.T, ctx context.Context) *s cfg.RPCListener = fmt.Sprintf("127.0.0.1:%d", testutil.AllocateUniquePort(t)) cfg.Metrics.Port = testutil.AllocateUniquePort(t) + err = fpApp.StartFinalityProvider(eotsPk, passphrase) + require.NoError(t, err) + fpServer := service.NewFinalityProviderServer(cfg, tm.logger, fpApp, fpdb) go func() { err = fpServer.RunUntilShutdown(ctx)