-
Notifications
You must be signed in to change notification settings - Fork 1.7k
/
head_saver.go
102 lines (81 loc) · 3.06 KB
/
head_saver.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package headtracker
import (
"context"
"fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/smartcontractkit/chainlink-common/pkg/logger"
"github.com/smartcontractkit/chainlink/v2/common/headtracker"
httypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker/types"
evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types"
)
type headSaver struct {
orm ORM
config Config
htConfig HeadTrackerConfig
logger logger.Logger
heads Heads
}
var _ headtracker.HeadSaver[*evmtypes.Head, common.Hash] = (*headSaver)(nil)
func NewHeadSaver(lggr logger.Logger, orm ORM, config Config, htConfig HeadTrackerConfig) httypes.HeadSaver {
return &headSaver{
orm: orm,
config: config,
htConfig: htConfig,
logger: logger.Named(lggr, "HeadSaver"),
heads: NewHeads(),
}
}
func (hs *headSaver) Save(ctx context.Context, head *evmtypes.Head) error {
if err := hs.orm.IdempotentInsertHead(ctx, head); err != nil {
return err
}
hs.heads.AddHeads(head)
return nil
}
func (hs *headSaver) Load(ctx context.Context, latestFinalized int64) (chain *evmtypes.Head, err error) {
minBlockNumber := hs.calculateMinBlockToKeep(latestFinalized)
heads, err := hs.orm.LatestHeads(ctx, minBlockNumber)
if err != nil {
return nil, err
}
hs.heads.AddHeads(heads...)
return hs.heads.LatestHead(), nil
}
func (hs *headSaver) calculateMinBlockToKeep(latestFinalized int64) int64 {
return max(latestFinalized-int64(hs.htConfig.HistoryDepth()), 0)
}
func (hs *headSaver) LatestHeadFromDB(ctx context.Context) (head *evmtypes.Head, err error) {
return hs.orm.LatestHead(ctx)
}
func (hs *headSaver) LatestChain() *evmtypes.Head {
head := hs.heads.LatestHead()
if head == nil {
return nil
}
if head.ChainLength() < hs.config.FinalityDepth() {
hs.logger.Debugw("chain shorter than FinalityDepth", "chainLen", head.ChainLength(), "evmFinalityDepth", hs.config.FinalityDepth())
}
return head
}
func (hs *headSaver) Chain(hash common.Hash) *evmtypes.Head {
return hs.heads.HeadByHash(hash)
}
func (hs *headSaver) MarkFinalized(ctx context.Context, finalized *evmtypes.Head) error {
minBlockToKeep := hs.calculateMinBlockToKeep(finalized.BlockNumber())
if !hs.heads.MarkFinalized(finalized.BlockHash(), minBlockToKeep) {
return fmt.Errorf("failed to find %s block in the canonical chain to mark it as finalized", finalized)
}
return hs.orm.TrimOldHeads(ctx, minBlockToKeep)
}
var NullSaver httypes.HeadSaver = &nullSaver{}
type nullSaver struct{}
func (*nullSaver) Save(ctx context.Context, head *evmtypes.Head) error { return nil }
func (*nullSaver) Load(ctx context.Context, latestFinalized int64) (*evmtypes.Head, error) {
return nil, nil
}
func (*nullSaver) LatestHeadFromDB(ctx context.Context) (*evmtypes.Head, error) { return nil, nil }
func (*nullSaver) LatestChain() *evmtypes.Head { return nil }
func (*nullSaver) Chain(hash common.Hash) *evmtypes.Head { return nil }
func (*nullSaver) MarkFinalized(ctx context.Context, latestFinalized *evmtypes.Head) error {
return nil
}