arnaucube
arnaucube/hermez-nodePublic Self-hosted repository
hermez-node/api/state.go
api/state.goRaw
  1package api
  2
  3import (
  4	"net/http"
  5	"time"
  6
  7	ethCommon "github.com/ethereum/go-ethereum/common"
  8	"github.com/gin-gonic/gin"
  9	"github.com/hermeznetwork/hermez-node/common"
 10	"github.com/hermeznetwork/hermez-node/db/historydb"
 11	"github.com/hermeznetwork/tracerr"
 12)
 13
 14// Network define status of the network
 15type Network struct {
 16	LastEthBlock  int64              `json:"lastEthereumBlock"`
 17	LastSyncBlock int64              `json:"lastSynchedBlock"`
 18	LastBatch     historydb.BatchAPI `json:"lastBatch"`
 19	CurrentSlot   int64              `json:"currentSlot"`
 20	NextForgers   []NextForger       `json:"nextForgers"`
 21}
 22
 23// NextForger  is a representation of the information of a coordinator and the period will forge
 24type NextForger struct {
 25	Coordinator historydb.CoordinatorAPI `json:"coordinator"`
 26	Period      Period                   `json:"period"`
 27}
 28
 29// Period is a representation of a period
 30type Period struct {
 31	SlotNum       int64     `json:"slotNum"`
 32	FromBlock     int64     `json:"fromBlock"`
 33	ToBlock       int64     `json:"toBlock"`
 34	FromTimestamp time.Time `json:"fromTimestamp"`
 35	ToTimestamp   time.Time `json:"toTimestamp"`
 36}
 37
 38var bootCoordinator historydb.CoordinatorAPI = historydb.CoordinatorAPI{
 39	ItemID: 0,
 40	Bidder: ethCommon.HexToAddress("0x111111111111111111111111111111111111111"),
 41	Forger: ethCommon.HexToAddress("0x111111111111111111111111111111111111111"),
 42	URL:    "https://bootCoordinator",
 43}
 44
 45func (a *API) getState(c *gin.Context) {
 46	// TODO: There are no events for the buckets information, so now this information will be 0
 47	a.status.RLock()
 48	status := a.status //nolint
 49	a.status.RUnlock()
 50	c.JSON(http.StatusOK, status) //nolint
 51}
 52
 53// SC Vars
 54
 55// SetRollupVariables set Status.Rollup variables
 56func (a *API) SetRollupVariables(rollupVariables common.RollupVariables) {
 57	a.status.Lock()
 58	a.status.Rollup = rollupVariables
 59	a.status.Unlock()
 60}
 61
 62// SetWDelayerVariables set Status.WithdrawalDelayer variables
 63func (a *API) SetWDelayerVariables(wDelayerVariables common.WDelayerVariables) {
 64	a.status.Lock()
 65	a.status.WithdrawalDelayer = wDelayerVariables
 66	a.status.Unlock()
 67}
 68
 69// SetAuctionVariables set Status.Auction variables
 70func (a *API) SetAuctionVariables(auctionVariables common.AuctionVariables) {
 71	a.status.Lock()
 72	a.status.Auction = auctionVariables
 73	a.status.Unlock()
 74}
 75
 76// Network
 77
 78// UpdateNetworkInfoBlock update Status.Network block related information
 79func (a *API) UpdateNetworkInfoBlock(
 80	lastEthBlock, lastSyncBlock common.Block,
 81) {
 82	a.status.Network.LastSyncBlock = lastSyncBlock.Num
 83	a.status.Network.LastEthBlock = lastEthBlock.Num
 84}
 85
 86// UpdateNetworkInfo update Status.Network information
 87func (a *API) UpdateNetworkInfo(
 88	lastEthBlock, lastSyncBlock common.Block,
 89	lastBatchNum common.BatchNum, currentSlot int64,
 90) error {
 91	lastBatch, err := a.h.GetBatchAPI(lastBatchNum)
 92	if err != nil {
 93		return tracerr.Wrap(err)
 94	}
 95	lastClosedSlot := currentSlot + int64(a.status.Auction.ClosedAuctionSlots)
 96	nextForgers, err := a.getNextForgers(lastSyncBlock, currentSlot, lastClosedSlot)
 97	if err != nil {
 98		return tracerr.Wrap(err)
 99	}
100	a.status.Lock()
101	a.status.Network.LastSyncBlock = lastSyncBlock.Num
102	a.status.Network.LastEthBlock = lastEthBlock.Num
103	a.status.Network.LastBatch = *lastBatch
104	a.status.Network.CurrentSlot = currentSlot
105	a.status.Network.NextForgers = nextForgers
106	a.status.Unlock()
107	return nil
108}
109
110// getNextForgers returns next forgers
111func (a *API) getNextForgers(lastBlock common.Block, currentSlot, lastClosedSlot int64) ([]NextForger, error) {
112	secondsPerBlock := int64(15) //nolint:gomnd
113	// currentSlot and lastClosedSlot included
114	limit := uint(lastClosedSlot - currentSlot + 1)
115	bids, _, err := a.h.GetBestBidsAPI(&currentSlot, &lastClosedSlot, nil, &limit, "ASC")
116	if err != nil {
117		return nil, tracerr.Wrap(err)
118	}
119	nextForgers := []NextForger{}
120	// Create nextForger for each slot
121	for i := currentSlot; i <= lastClosedSlot; i++ {
122		fromBlock := i*int64(a.cg.AuctionConstants.BlocksPerSlot) + a.cg.AuctionConstants.GenesisBlockNum
123		toBlock := (i+1)*int64(a.cg.AuctionConstants.BlocksPerSlot) + a.cg.AuctionConstants.GenesisBlockNum - 1
124		nextForger := NextForger{
125			Period: Period{
126				SlotNum:       i,
127				FromBlock:     fromBlock,
128				ToBlock:       toBlock,
129				FromTimestamp: lastBlock.Timestamp.Add(time.Second * time.Duration(secondsPerBlock*(fromBlock-lastBlock.Num))),
130				ToTimestamp:   lastBlock.Timestamp.Add(time.Second * time.Duration(secondsPerBlock*(toBlock-lastBlock.Num))),
131			},
132		}
133		foundBid := false
134		// If there is a bid for a slot, get forger (coordinator)
135		for j := range bids {
136			if bids[j].SlotNum == i {
137				foundBid = true
138				coordinator, err := a.h.GetCoordinatorAPI(bids[j].Bidder)
139				if err != nil {
140					return nil, tracerr.Wrap(err)
141				}
142				nextForger.Coordinator = *coordinator
143				break
144			}
145		}
146		// If there is no bid, the coordinator that will forge is boot coordinator
147		if !foundBid {
148			nextForger.Coordinator = bootCoordinator
149		}
150		nextForgers = append(nextForgers, nextForger)
151	}
152	return nextForgers, nil
153}
154
155// Metrics
156
157// UpdateMetrics update Status.Metrics information
158func (a *API) UpdateMetrics() error {
159	a.status.RLock()
160	batchNum := a.status.Network.LastBatch.BatchNum
161	a.status.RUnlock()
162	metrics, err := a.h.GetMetrics(batchNum)
163	if err != nil {
164		return tracerr.Wrap(err)
165	}
166	a.status.Lock()
167	a.status.Metrics = *metrics
168	a.status.Unlock()
169	return nil
170}
171
172// Recommended fee
173
174// UpdateRecommendedFee update Status.RecommendedFee information
175func (a *API) UpdateRecommendedFee() error {
176	feeExistingAccount, err := a.h.GetAvgTxFee()
177	if err != nil {
178		return tracerr.Wrap(err)
179	}
180	a.status.Lock()
181	a.status.RecommendedFee.ExistingAccount = feeExistingAccount
182	a.status.RecommendedFee.CreatesAccount = createAccountExtraFeePercentage * feeExistingAccount
183	a.status.RecommendedFee.CreatesAccountAndRegister = createAccountInternalExtraFeePercentage * feeExistingAccount
184	a.status.Unlock()
185	return nil
186}