diff --git a/vochain/cometbft.go b/vochain/cometbft.go index 138380c7b..98f35e84d 100644 --- a/vochain/cometbft.go +++ b/vochain/cometbft.go @@ -18,6 +18,7 @@ import ( cometabcitypes "github.com/cometbft/cometbft/abci/types" cometapitypes "github.com/cometbft/cometbft/api/cometbft/types/v1" crypto256k1 "github.com/cometbft/cometbft/crypto/secp256k1" + comettypes "github.com/cometbft/cometbft/types" ethcommon "github.com/ethereum/go-ethereum/common" "go.vocdoni.io/dvote/crypto/ethereum" "go.vocdoni.io/dvote/log" @@ -607,6 +608,39 @@ func (app *BaseApplication) ApplySnapshotChunk(_ context.Context, log.Error(err) return nil, err } + + // Fetch the block before the snapshot, we'll need it to bootstrap other nodes + fetchAndSaveBlock := func(height int64) error { + cli, err := newCometRPCClient(app.Node.Config().StateSync.RPCServers[0]) + if err != nil { + return fmt.Errorf("cannot connect to remote RPC server: %w", err) + } + + b, err := cli.Block(context.TODO(), &height) + if err != nil { + return fmt.Errorf("cannot fetch block %d from remote RPC: %w", height, err) + } + + blockParts, err := b.Block.MakePartSet(comettypes.BlockPartSizeBytes) + if err != nil { + return err + } + + c, err := cli.Commit(context.TODO(), &height) + if err != nil { + return fmt.Errorf("cannot fetch commit %d from remote RPC: %w", height, err) + } + app.Node.BlockStore().SaveBlock(b.Block, blockParts, c.Commit) + + return nil + } + + if err := fetchAndSaveBlock(snapshotFromComet.height.Load()); err != nil { + log.Error("couldn't fetch and save block, rejecting snapshot: ", err) + return &cometabcitypes.ApplySnapshotChunkResponse{ + Result: cometabcitypes.APPLY_SNAPSHOT_CHUNK_RESULT_REJECT_SNAPSHOT, + }, nil + } } return &cometabcitypes.ApplySnapshotChunkResponse{