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 }