hermez-node/stateapiupdater/stateapiupdater.go
stateapiupdater/stateapiupdater.goRaw
1package stateapiupdater
2
3import (
4 "database/sql"
5 "sync"
6
7 "github.com/hermeznetwork/hermez-node/common"
8 "github.com/hermeznetwork/hermez-node/db/historydb"
9 "github.com/hermeznetwork/tracerr"
10)
11
12// Updater is an utility object to facilitate updating the StateAPI
13type Updater struct {
14 hdb *historydb.HistoryDB
15 state historydb.StateAPI
16 config historydb.NodeConfig
17 vars common.SCVariablesPtr
18 consts historydb.Constants
19 rw sync.RWMutex
20}
21
22// NewUpdater creates a new Updater
23func NewUpdater(hdb *historydb.HistoryDB, config *historydb.NodeConfig, vars *common.SCVariables,
24 consts *historydb.Constants) *Updater {
25 u := Updater{
26 hdb: hdb,
27 config: *config,
28 consts: *consts,
29 state: historydb.StateAPI{
30 NodePublicInfo: historydb.NodePublicInfo{
31 ForgeDelay: config.ForgeDelay,
32 },
33 },
34 }
35 u.SetSCVars(vars.AsPtr())
36 return &u
37}
38
39// Store the State in the HistoryDB
40func (u *Updater) Store() error {
41 u.rw.RLock()
42 defer u.rw.RUnlock()
43 return tracerr.Wrap(u.hdb.SetStateInternalAPI(&u.state))
44}
45
46// SetSCVars sets the smart contract vars (ony updates those that are not nil)
47func (u *Updater) SetSCVars(vars *common.SCVariablesPtr) {
48 u.rw.Lock()
49 defer u.rw.Unlock()
50 if vars.Rollup != nil {
51 u.vars.Rollup = vars.Rollup
52 rollupVars := historydb.NewRollupVariablesAPI(u.vars.Rollup)
53 u.state.Rollup = *rollupVars
54 }
55 if vars.Auction != nil {
56 u.vars.Auction = vars.Auction
57 auctionVars := historydb.NewAuctionVariablesAPI(u.vars.Auction)
58 u.state.Auction = *auctionVars
59 }
60 if vars.WDelayer != nil {
61 u.vars.WDelayer = vars.WDelayer
62 u.state.WithdrawalDelayer = *u.vars.WDelayer
63 }
64}
65
66// UpdateRecommendedFee update Status.RecommendedFee information
67func (u *Updater) UpdateRecommendedFee() error {
68 recommendedFee, err := u.hdb.GetRecommendedFee(u.config.MinFeeUSD, u.config.MaxFeeUSD)
69 if err != nil {
70 return tracerr.Wrap(err)
71 }
72 u.rw.Lock()
73 u.state.RecommendedFee = *recommendedFee
74 u.rw.Unlock()
75 return nil
76}
77
78// UpdateMetrics update Status.Metrics information
79func (u *Updater) UpdateMetrics() error {
80 u.rw.RLock()
81 lastBatch := u.state.Network.LastBatch
82 u.rw.RUnlock()
83 if lastBatch == nil {
84 return nil
85 }
86 lastBatchNum := lastBatch.BatchNum
87 metrics, poolLoad, err := u.hdb.GetMetricsInternalAPI(lastBatchNum)
88 if err != nil {
89 return tracerr.Wrap(err)
90 }
91 u.rw.Lock()
92 u.state.Metrics = *metrics
93 u.state.NodePublicInfo.PoolLoad = poolLoad
94 u.rw.Unlock()
95 return nil
96}
97
98// UpdateNetworkInfoBlock update Status.Network block related information
99func (u *Updater) UpdateNetworkInfoBlock(lastEthBlock, lastSyncBlock common.Block) {
100 u.rw.Lock()
101 u.state.Network.LastSyncBlock = lastSyncBlock.Num
102 u.state.Network.LastEthBlock = lastEthBlock.Num
103 u.rw.Unlock()
104}
105
106// UpdateNetworkInfo update Status.Network information
107func (u *Updater) UpdateNetworkInfo(
108 lastEthBlock, lastSyncBlock common.Block,
109 lastBatchNum common.BatchNum, currentSlot int64,
110) error {
111 // Get last batch in API format
112 lastBatch, err := u.hdb.GetBatchInternalAPI(lastBatchNum)
113 if tracerr.Unwrap(err) == sql.ErrNoRows {
114 lastBatch = nil
115 } else if err != nil {
116 return tracerr.Wrap(err)
117 }
118 u.rw.RLock()
119 auctionVars := u.vars.Auction
120 u.rw.RUnlock()
121 // Get next forgers
122 lastClosedSlot := currentSlot + int64(auctionVars.ClosedAuctionSlots)
123 nextForgers, err := u.hdb.GetNextForgersInternalAPI(auctionVars, &u.consts.Auction,
124 lastSyncBlock, currentSlot, lastClosedSlot)
125 if tracerr.Unwrap(err) == sql.ErrNoRows {
126 nextForgers = nil
127 } else if err != nil {
128 return tracerr.Wrap(err)
129 }
130
131 bucketUpdates, err := u.hdb.GetBucketUpdatesInternalAPI()
132 if err == sql.ErrNoRows {
133 bucketUpdates = nil
134 } else if err != nil {
135 return tracerr.Wrap(err)
136 }
137
138 u.rw.Lock()
139 // Update NodeInfo struct
140 for i, bucketParams := range u.state.Rollup.Buckets {
141 for _, bucketUpdate := range bucketUpdates {
142 if bucketUpdate.NumBucket == i {
143 bucketParams.Withdrawals = bucketUpdate.Withdrawals
144 u.state.Rollup.Buckets[i] = bucketParams
145 break
146 }
147 }
148 }
149 u.state.Network.LastSyncBlock = lastSyncBlock.Num
150 u.state.Network.LastEthBlock = lastEthBlock.Num
151 u.state.Network.LastBatch = lastBatch
152 u.state.Network.CurrentSlot = currentSlot
153 u.state.Network.NextForgers = nextForgers
154 u.rw.Unlock()
155 return nil
156}