arnaucube
arnaucube/hermez-nodePublic Self-hosted repository
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}