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: prune used merkle proof #218

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Open
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 @@ -44,6 +44,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
* [#211](https://github.com/babylonlabs-io/finality-provider/pull/211) Clean up unused cmd
* [#214](https://github.com/babylonlabs-io/finality-provider/pull/214) Gradual benchmark
* [#216](https://github.com/babylonlabs-io/finality-provider/pull/216) Add multiple fpd connecting to one eotsd in e2e tests
* [#218](https://github.com/babylonlabs-io/finality-provider/pull/218) Prune used merkle proof

## v0.13.1

Expand Down
57 changes: 57 additions & 0 deletions finality-provider/cmd/fpd/daemon/daemon_commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,63 @@ func runCommandEditFinalityDescription(cmd *cobra.Command, args []string) error
return nil
}

// CommandUnsafeDeleteMerkleProof removes merkle proof
func CommandUnsafeDeleteMerkleProof() *cobra.Command {
var cmd = &cobra.Command{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we have a command to delete this? kkk seems a bit scary

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, maybe more docs about the consequences?

Use: "unsafe-remove-merkle-proof [eots_pk]",
Aliases: []string{"rmp"},
Short: "Removes merkle proofs up to the specified target height",
Example: fmt.Sprintf(`fpd unsafe-remove-merkle-proof [eots_pk] --daemon-address %s`, defaultFpdDaemonAddress),
Args: cobra.ExactArgs(1),
RunE: runCommandUnsafeDeleteMerkleProof,
}
cmd.Flags().String(fpdDaemonAddressFlag, defaultFpdDaemonAddress, "The RPC server address of fpd")
cmd.Flags().String(chainIDFlag, "", "The identifier of the consumer chain")
cmd.Flags().Uint64(upToHeight, 0, "Target height to delete proofs")

if err := cmd.MarkFlagRequired(chainIDFlag); err != nil {
panic(err)
}

if err := cmd.MarkFlagRequired(upToHeight); err != nil {
panic(err)
}

return cmd
}

func runCommandUnsafeDeleteMerkleProof(cmd *cobra.Command, args []string) error {
fpPk, err := types.NewBIP340PubKeyFromHex(args[0])
if err != nil {
return err
}

flags := cmd.Flags()
daemonAddress, err := flags.GetString(fpdDaemonAddressFlag)
if err != nil {
return fmt.Errorf("failed to read flag %s: %w", fpdDaemonAddressFlag, err)
}

grpcClient, cleanUp, err := dc.NewFinalityProviderServiceGRpcClient(daemonAddress)
if err != nil {
return err
}
defer func() {
if err := cleanUp(); err != nil {
fmt.Printf("Failed to clean up grpc client: %v\n", err)
}
}()

chainID, _ := cmd.Flags().GetString(chainIDFlag)
targetHeight, _ := cmd.Flags().GetUint64(upToHeight)

if err := grpcClient.UnsafeRemoveMerkleProof(cmd.Context(), fpPk, chainID, targetHeight); err != nil {
return fmt.Errorf("failed to edit finality provider %v err %w", fpPk.MarshalHex(), err)
}

return nil
}

func printRespJSON(resp interface{}) {
jsonBytes, err := json.MarshalIndent(resp, "", " ")
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions finality-provider/cmd/fpd/daemon/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const (
signedFlag = "signed"
checkDoubleSignFlag = "check-double-sign"
fromFile = "from-file"
upToHeight = "up-to-height"

// flags for description
monikerFlag = "moniker"
Expand Down
2 changes: 1 addition & 1 deletion finality-provider/cmd/fpd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func main() {
daemon.CommandInfoFP(), daemon.CommandAddFinalitySig(), daemon.CommandUnjailFP(),
daemon.CommandEditFinalityDescription(), daemon.CommandCommitPubRand(),
incentivecli.NewWithdrawRewardCmd(), incentivecli.NewSetWithdrawAddressCmd(),
version.CommandVersion("fpd"),
version.CommandVersion("fpd"), daemon.CommandUnsafeDeleteMerkleProof(),
)

if err := cmd.Execute(); err != nil {
Expand Down
240 changes: 167 additions & 73 deletions finality-provider/proto/finality_providers.pb.go

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions finality-provider/proto/finality_providers.proto
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ service FinalityProviders {

// EditFinalityProvider edits finality provider
rpc EditFinalityProvider (EditFinalityProviderRequest) returns (EmptyResponse);

// UnsafeRemoveMerkleProof removes merkle proofs up to target height
rpc UnsafeRemoveMerkleProof (RemoveMerkleProofRequest) returns (EmptyResponse);
}

message GetInfoRequest {
Expand Down Expand Up @@ -245,5 +248,14 @@ message EditFinalityProviderRequest {
];
}

message RemoveMerkleProofRequest {
// btc_pk_hex is the hex string of the BTC secp256k1 PK of the finality provider encoded in BIP-340 spec
string btc_pk_hex = 1;
// chain_id is the identifier of the consumer chain
string chain_id = 2;
// target_height to to delete all proofs
uint64 target_height = 3;
}

// Define an empty response message
message EmptyResponse {}
39 changes: 39 additions & 0 deletions finality-provider/proto/finality_providers_grpc.pb.go

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

2 changes: 1 addition & 1 deletion finality-provider/service/benchmark_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func (fp *FinalityProviderInstance) commitPubRandPairsWithTiming(startHeight uin

// Measure addPubRandProofList
addProofStart := time.Now()
if err := fp.pubRandState.addPubRandProofList(pubRandList, proofList); err != nil {
if err := fp.pubRandState.addPubRandProofList(fp.GetChainID(), fp.btcPk.MustMarshal(), startHeight, uint64(fp.cfg.NumPubRand), proofList); err != nil {
return nil, timing, fmt.Errorf("failed to save public randomness to DB: %w", err)
}
timing.AddPubRandProofListTime = time.Since(addProofStart)
Expand Down
12 changes: 12 additions & 0 deletions finality-provider/service/client/rpcclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,3 +141,15 @@ func (c *FinalityProviderServiceGRpcClient) EditFinalityProvider(

return nil
}

// UnsafeRemoveMerkleProof - remove all proofs up to target height
func (c *FinalityProviderServiceGRpcClient) UnsafeRemoveMerkleProof(
ctx context.Context, fpPk *bbntypes.BIP340PubKey, chainID string, targetHeight uint64) error {
req := &proto.RemoveMerkleProofRequest{BtcPkHex: fpPk.MarshalHex(), ChainId: chainID, TargetHeight: targetHeight}
_, err := c.client.UnsafeRemoveMerkleProof(ctx, req)
if err != nil {
return err
}

return nil
}
19 changes: 15 additions & 4 deletions finality-provider/service/fp_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,7 @@ func (fp *FinalityProviderInstance) commitPubRandPairs(startHeight uint64) (*typ
commitment, proofList := types.GetPubRandCommitAndProofs(pubRandList)

// store them to database
if err := fp.pubRandState.addPubRandProofList(pubRandList, proofList); err != nil {
if err := fp.pubRandState.addPubRandProofList(fp.btcPk.MustMarshal(), fp.GetChainID(), startHeight, uint64(fp.cfg.NumPubRand), proofList); err != nil {
return nil, fmt.Errorf("failed to save public randomness to DB: %w", err)
}

Expand Down Expand Up @@ -641,14 +641,20 @@ func (fp *FinalityProviderInstance) SubmitBatchFinalitySignatures(blocks []*type
}

// get public randomness list
numPubRand := len(blocks)
// #nosec G115 -- performed the conversion check above
prList, err := fp.getPubRandList(blocks[0].Height, uint32(len(blocks)))
prList, err := fp.getPubRandList(blocks[0].Height, uint32(numPubRand))
if err != nil {
return nil, fmt.Errorf("failed to get public randomness list: %w", err)
}
// get proof list
// TODO: how to recover upon having an error in getPubRandProofList?
proofBytesList, err := fp.pubRandState.getPubRandProofList(prList)
proofBytesList, err := fp.pubRandState.getPubRandProofList(
fp.btcPk.MustMarshal(),
fp.GetChainID(),
blocks[0].Height,
uint64(numPubRand),
)
if err != nil {
return nil, fmt.Errorf("failed to get public randomness inclusion proof list: %w", err)
}
Expand Down Expand Up @@ -696,7 +702,7 @@ func (fp *FinalityProviderInstance) TestSubmitFinalitySignatureAndExtractPrivKey
pubRand := prList[0]

// get proof
proofBytes, err := fp.pubRandState.getPubRandProof(pubRand)
proofBytes, err := fp.pubRandState.getPubRandProof(fp.btcPk.MustMarshal(), fp.GetChainID(), b.Height)
if err != nil {
return nil, nil, fmt.Errorf("failed to get public randomness inclusion proof: %w", err)
}
Expand Down Expand Up @@ -1020,3 +1026,8 @@ func (fp *FinalityProviderInstance) GetFinalityProviderSlashedOrJailedWithRetry(

return slashed, jailed, nil
}

// TestGetPubProof only used for tests to get access to the store
func (fp *FinalityProviderInstance) TestGetPubProof(height uint64) ([]byte, error) {
return fp.pubRandState.getPubRandProof(fp.btcPk.MustMarshal(), fp.GetChainID(), height)
}
13 changes: 6 additions & 7 deletions finality-provider/service/pub_rand_store_adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package service

import (
"github.com/babylonlabs-io/finality-provider/finality-provider/store"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/cometbft/cometbft/crypto/merkle"
)

Expand All @@ -15,16 +14,16 @@ func newPubRandState(s *store.PubRandProofStore) *pubRandState {
}

func (st *pubRandState) addPubRandProofList(
pubRandList []*btcec.FieldVal,
pk, chainID []byte, height uint64, numPubRand uint64,
proofList []*merkle.Proof,
) error {
return st.s.AddPubRandProofList(pubRandList, proofList)
return st.s.AddPubRandProofList(chainID, pk, height, numPubRand, proofList)
}

func (st *pubRandState) getPubRandProof(pubRand *btcec.FieldVal) ([]byte, error) {
return st.s.GetPubRandProof(pubRand)
func (st *pubRandState) getPubRandProof(pk, chainID []byte, height uint64) ([]byte, error) {
return st.s.GetPubRandProof(chainID, pk, height)
}

func (st *pubRandState) getPubRandProofList(pubRandList []*btcec.FieldVal) ([][]byte, error) {
return st.s.GetPubRandProofList(pubRandList)
func (st *pubRandState) getPubRandProofList(pk, chainID []byte, height uint64, numPubRand uint64) ([][]byte, error) {
return st.s.GetPubRandProofList(chainID, pk, height, numPubRand)
}
14 changes: 14 additions & 0 deletions finality-provider/service/rpcserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,20 @@ func (r *rpcServer) QueryFinalityProviderList(_ context.Context, _ *proto.QueryF
return &proto.QueryFinalityProviderListResponse{FinalityProviders: fps}, nil
}

// UnsafeRemoveMerkleProof - removes proofs up to target height
func (r *rpcServer) UnsafeRemoveMerkleProof(_ context.Context, req *proto.RemoveMerkleProofRequest) (*proto.EmptyResponse, error) {
fpPk, err := parseEotsPk(req.BtcPkHex)
if err != nil {
return nil, err
}

if err := r.app.pubRandStore.RemovePubRandProofList([]byte(req.ChainId), fpPk.MustMarshal(), req.TargetHeight); err != nil {
return nil, err
}

return nil, nil
}

func parseEotsPk(eotsPkHex string) (*bbntypes.BIP340PubKey, error) {
if eotsPkHex == "" {
return nil, fmt.Errorf("eots-pk cannot be empty")
Expand Down
Loading
Loading