code.vegaprotocol.io/vega@v0.79.0/datanode/networkhistory/block_commit_handler.go (about)

     1  // Copyright (C) 2023 Gobalsky Labs Limited
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as
     5  // published by the Free Software Foundation, either version 3 of the
     6  // License, or (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15  
    16  package networkhistory
    17  
    18  import (
    19  	"context"
    20  	"fmt"
    21  	"time"
    22  
    23  	"code.vegaprotocol.io/vega/logging"
    24  
    25  	"github.com/cenkalti/backoff"
    26  )
    27  
    28  type BlockCommitHandler struct {
    29  	log                       *logging.Logger
    30  	cfg                       Config
    31  	snapshotData              func(ctx context.Context, chainID string, toHeight int64) error
    32  	usingEventFile            bool
    33  	eventFileTimeBetweenBlock time.Duration
    34  
    35  	timeBetweenRetries time.Duration
    36  	maxRetries         uint64
    37  }
    38  
    39  func NewBlockCommitHandler(
    40  	log *logging.Logger,
    41  	cfg Config,
    42  	snapshotData func(ctx context.Context, chainID string, toHeight int64) error,
    43  	usingEventFile bool, eventFileTimeBetweenBlock time.Duration,
    44  	timeBetweenRetries time.Duration,
    45  	maxRetries uint64,
    46  ) *BlockCommitHandler {
    47  	return &BlockCommitHandler{
    48  		log:                       log.Named("block-commit-handler"),
    49  		cfg:                       cfg,
    50  		snapshotData:              snapshotData,
    51  		usingEventFile:            usingEventFile,
    52  		eventFileTimeBetweenBlock: eventFileTimeBetweenBlock,
    53  		timeBetweenRetries:        timeBetweenRetries,
    54  		maxRetries:                maxRetries,
    55  	}
    56  }
    57  
    58  func (b *BlockCommitHandler) OnBlockCommitted(ctx context.Context, chainID string, blockHeight int64, snapshotTaken bool) {
    59  	snapTaken := snapshotTaken
    60  	if b.usingEventFile && b.eventFileTimeBetweenBlock < time.Second {
    61  		snapTaken = blockHeight%1000 == 0
    62  	}
    63  
    64  	if blockHeight > 0 && bool(b.cfg.Publish) && snapTaken {
    65  		snapshotData := func() (opErr error) {
    66  			err := b.snapshotData(ctx, chainID, blockHeight)
    67  			if err != nil {
    68  				b.log.Errorf("failed to snapshot data, retrying in %v: %v", b.timeBetweenRetries, err)
    69  			}
    70  
    71  			return err
    72  		}
    73  
    74  		constantBackoff := backoff.NewConstantBackOff(b.timeBetweenRetries)
    75  		backoff.WithMaxRetries(constantBackoff, 6)
    76  
    77  		err := backoff.Retry(snapshotData, backoff.WithMaxRetries(constantBackoff, b.maxRetries))
    78  		if err != nil {
    79  			b.log.Panic(fmt.Sprintf("failed to snapshot data after %d retries", b.maxRetries), logging.Error(err))
    80  		}
    81  	}
    82  }