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 NodePublicConfig: historydb.NodePublicConfig{
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)
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, 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.rw.Unlock()
94 return nil
95}
96
97// UpdateNetworkInfoBlock update Status.Network block related information
98func (u *Updater) UpdateNetworkInfoBlock(lastEthBlock, lastSyncBlock common.Block) {
99 u.rw.Lock()
100 u.state.Network.LastSyncBlock = lastSyncBlock.Num
101 u.state.Network.LastEthBlock = lastEthBlock.Num
102 u.rw.Unlock()
103}
104
105// UpdateNetworkInfo update Status.Network information
106func (u *Updater) UpdateNetworkInfo(
107 lastEthBlock, lastSyncBlock common.Block,
108 lastBatchNum common.BatchNum, currentSlot int64,
109) error {
110 // Get last batch in API format
111 lastBatch, err := u.hdb.GetBatchInternalAPI(lastBatchNum)
112 if tracerr.Unwrap(err) == sql.ErrNoRows {
113 lastBatch = nil
114 } else if err != nil {
115 return tracerr.Wrap(err)
116 }
117 u.rw.RLock()
118 auctionVars := u.vars.Auction
119 u.rw.RUnlock()
120 // Get next forgers
121 lastClosedSlot := currentSlot + int64(auctionVars.ClosedAuctionSlots)
122 nextForgers, err := u.hdb.GetNextForgersInternalAPI(auctionVars, &u.consts.Auction,
123 lastSyncBlock, currentSlot, lastClosedSlot)
124 if tracerr.Unwrap(err) == sql.ErrNoRows {
125 nextForgers = nil
126 } else if err != nil {
127 return tracerr.Wrap(err)
128 }
129
130 bucketUpdates, err := u.hdb.GetBucketUpdatesInternalAPI()
131 if err == sql.ErrNoRows {
132 bucketUpdates = nil
133 } else if err != nil {
134 return tracerr.Wrap(err)
135 }
136
137 u.rw.Lock()
138 // Update NodeInfo struct
139 for i, bucketParams := range u.state.Rollup.Buckets {
140 for _, bucketUpdate := range bucketUpdates {
141 if bucketUpdate.NumBucket == i {
142 bucketParams.Withdrawals = bucketUpdate.Withdrawals
143 u.state.Rollup.Buckets[i] = bucketParams
144 break
145 }
146 }
147 }
148 // Update pending L1s
149 pendingL1s, err := u.hdb.GetUnforgedL1UserTxsCount()
150 if err != nil {
151 return tracerr.Wrap(err)
152 }
153 u.state.Network.LastSyncBlock = lastSyncBlock.Num
154 u.state.Network.LastEthBlock = lastEthBlock.Num
155 u.state.Network.LastBatch = lastBatch
156 u.state.Network.CurrentSlot = currentSlot
157 u.state.Network.NextForgers = nextForgers
158 u.state.Network.PendingL1Txs = pendingL1s
159 u.rw.Unlock()
160 return nil
161}