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			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}