Browse Source

Merge pull request #267 from hermeznetwork/feature/api-state

API add get state
feature/sql-semaphore1
a_bennassar 4 years ago
committed by GitHub
parent
commit
a473070f65
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 234 additions and 9 deletions
  1. +1
    -1
      api/api.go
  2. +13
    -0
      api/api_test.go
  3. +135
    -0
      api/state.go
  4. +79
    -0
      api/state_test.go
  5. +6
    -0
      db/historydb/historydb.go
  6. +0
    -8
      db/historydb/views.go

+ 1
- 1
api/api.go

@ -12,7 +12,7 @@ import (
// Status define status of the network // Status define status of the network
type Status struct { type Status struct {
Network historydb.Network `json:"network"`
Network Network `json:"network"`
Metrics historydb.Metrics `json:"metrics"` Metrics historydb.Metrics `json:"metrics"`
Rollup common.RollupVariables `json:"rollup"` Rollup common.RollupVariables `json:"rollup"`
Auction common.AuctionVariables `json:"auction"` Auction common.AuctionVariables `json:"auction"`

+ 13
- 0
api/api_test.go

@ -52,6 +52,8 @@ type testCommon struct {
bids []testBid bids []testBid
slots []testSlot slots []testSlot
auctionVars common.AuctionVariables auctionVars common.AuctionVariables
rollupVars common.RollupVariables
wdelayerVars common.WDelayerVariables
} }
var tc testCommon var tc testCommon
@ -280,6 +282,15 @@ func TestMain(m *testing.M) {
ClosedAuctionSlots: uint16(2), ClosedAuctionSlots: uint16(2),
OpenAuctionSlots: uint16(5), OpenAuctionSlots: uint16(5),
} }
rollupVars := common.RollupVariables{
WithdrawalDelay: uint64(3000),
}
wdelayerVars := common.WDelayerVariables{
WithdrawalDelay: uint64(3000),
}
err = api.h.AddAuctionVars(&auctionVars) err = api.h.AddAuctionVars(&auctionVars)
if err != nil { if err != nil {
panic(err) panic(err)
@ -313,6 +324,8 @@ func TestMain(m *testing.M) {
bids: testBids, bids: testBids,
slots: api.genTestSlots(nSlots, lastBlockNum, testBids, auctionVars), slots: api.genTestSlots(nSlots, lastBlockNum, testBids, auctionVars),
auctionVars: auctionVars, auctionVars: auctionVars,
rollupVars: rollupVars,
wdelayerVars: wdelayerVars,
} }
// Fake server // Fake server

+ 135
- 0
api/state.go

@ -2,10 +2,145 @@ package api
import ( import (
"net/http" "net/http"
"time"
ethCommon "github.com/ethereum/go-ethereum/common"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/hermeznetwork/hermez-node/common"
"github.com/hermeznetwork/hermez-node/db/historydb"
) )
// Network define status of the network
type Network struct {
LastBlock int64 `json:"lastBlock"`
LastBatch historydb.BatchAPI `json:"lastBatch"`
CurrentSlot int64 `json:"currentSlot"`
NextForgers []NextForger `json:"nextForgers"`
}
// NextForger is a representation of the information of a coordinator and the period will forge
type NextForger struct {
Coordinator historydb.CoordinatorAPI
Period Period
}
// Period is a representation of a period
type Period struct {
SlotNum int64
FromBlock int64
ToBlock int64
FromTimestamp time.Time
ToTimestamp time.Time
}
var bootCoordinator historydb.CoordinatorAPI = historydb.CoordinatorAPI{
ItemID: 0,
Bidder: ethCommon.HexToAddress("0x111111111111111111111111111111111111111"),
Forger: ethCommon.HexToAddress("0x111111111111111111111111111111111111111"),
URL: "https://bootCoordinator",
}
func (a *API) getState(c *gin.Context) { func (a *API) getState(c *gin.Context) {
c.JSON(http.StatusOK, a.status) c.JSON(http.StatusOK, a.status)
} }
// SC Vars
// SetRollupVariables set Status.Rollup variables
func (a *API) SetRollupVariables(rollupVariables common.RollupVariables) {
a.status.Rollup = rollupVariables
}
// SetWDelayerVariables set Status.WithdrawalDelayer variables
func (a *API) SetWDelayerVariables(wDelayerVariables common.WDelayerVariables) {
a.status.WithdrawalDelayer = wDelayerVariables
}
// SetAuctionVariables set Status.Auction variables
func (a *API) SetAuctionVariables(auctionVariables common.AuctionVariables) {
a.status.Auction = auctionVariables
}
// Network
// UpdateNetworkInfo update Status.Network information
func (a *API) UpdateNetworkInfo(lastBlock common.Block, lastBatchNum common.BatchNum, currentSlot int64) error {
a.status.Network.LastBlock = lastBlock.EthBlockNum
lastBatch, err := a.h.GetBatchAPI(lastBatchNum)
if err != nil {
return err
}
a.status.Network.LastBatch = *lastBatch
a.status.Network.CurrentSlot = currentSlot
lastClosedSlot := currentSlot + int64(a.status.Auction.ClosedAuctionSlots)
nextForgers, err := a.GetNextForgers(lastBlock, currentSlot, lastClosedSlot)
if err != nil {
return err
}
a.status.Network.NextForgers = nextForgers
return nil
}
// GetNextForgers returns next forgers
func (a *API) GetNextForgers(lastBlock common.Block, currentSlot, lastClosedSlot int64) ([]NextForger, error) {
secondsPerBlock := int64(15) //nolint:gomnd
// currentSlot and lastClosedSlot included
limit := uint(lastClosedSlot - currentSlot + 1)
bids, _, err := a.h.GetBestBidsAPI(&currentSlot, &lastClosedSlot, nil, &limit, "ASC")
if err != nil {
return nil, err
}
nextForgers := []NextForger{}
// Create nextForger for each slot
for i := currentSlot; i <= lastClosedSlot; i++ {
fromBlock := i*int64(a.cg.AuctionConstants.BlocksPerSlot) + a.cg.AuctionConstants.GenesisBlockNum
toBlock := (i+1)*int64(a.cg.AuctionConstants.BlocksPerSlot) + a.cg.AuctionConstants.GenesisBlockNum - 1
nextForger := NextForger{
Period: Period{
SlotNum: i,
FromBlock: fromBlock,
ToBlock: toBlock,
FromTimestamp: lastBlock.Timestamp.Add(time.Second * time.Duration(secondsPerBlock*(fromBlock-lastBlock.EthBlockNum))),
ToTimestamp: lastBlock.Timestamp.Add(time.Second * time.Duration(secondsPerBlock*(toBlock-lastBlock.EthBlockNum))),
},
}
foundBid := false
// If there is a bid for a slot, get forger (coordinator)
for j := range bids {
if bids[j].SlotNum == i {
foundBid = true
coordinator, err := a.h.GetCoordinatorAPI(bids[j].Bidder)
if err != nil {
return nil, err
}
nextForger.Coordinator = *coordinator
break
}
}
// If there is no bid, the coordinator that will forge is boot coordinator
if !foundBid {
nextForger.Coordinator = bootCoordinator
}
nextForgers = append(nextForgers, nextForger)
}
return nextForgers, nil
}
// Metrics
// UpdateMetrics update Status.Metrics information
func (a *API) UpdateMetrics() error {
metrics, err := a.h.GetMetrics()
if err != nil {
return err
}
a.status.Metrics = metrics
return nil
}
// Recommended fee
// UpdateRecommendedFee update Status.RecommendedFee information
func (a *API) UpdateRecommendedFee() error {
return nil
}

+ 79
- 0
api/state_test.go

@ -0,0 +1,79 @@
package api
import (
"testing"
"time"
"github.com/hermeznetwork/hermez-node/common"
"github.com/stretchr/testify/assert"
)
const secondsPerBlock = 15
func TestSetRollupVariables(t *testing.T) {
rollupVars := &common.RollupVariables{}
assert.Equal(t, *rollupVars, api.status.Rollup)
api.SetRollupVariables(tc.rollupVars)
assert.Equal(t, tc.rollupVars, api.status.Rollup)
}
func TestSetWDelayerVariables(t *testing.T) {
wdelayerVars := &common.WDelayerVariables{}
assert.Equal(t, *wdelayerVars, api.status.WithdrawalDelayer)
api.SetWDelayerVariables(tc.wdelayerVars)
assert.Equal(t, tc.wdelayerVars, api.status.WithdrawalDelayer)
}
func TestSetAuctionVariables(t *testing.T) {
auctionVars := &common.AuctionVariables{}
assert.Equal(t, *auctionVars, api.status.Auction)
api.SetAuctionVariables(tc.auctionVars)
assert.Equal(t, tc.auctionVars, api.status.Auction)
}
func TestNextForgers(t *testing.T) {
// It's assumed that bids for each slot will be received in increasing order
bestBids := make(map[int64]testBid)
for j := range tc.bids {
bestBids[tc.bids[j].SlotNum] = tc.bids[j]
}
lastBlock := tc.blocks[len(tc.blocks)-1]
for i := int64(0); i < tc.slots[len(tc.slots)-1].SlotNum; i++ {
lastClosedSlot := i + int64(api.status.Auction.ClosedAuctionSlots)
nextForgers, err := api.GetNextForgers(tc.blocks[len(tc.blocks)-1], i, lastClosedSlot)
assert.NoError(t, err)
for j := i; j <= lastClosedSlot; j++ {
for q := range nextForgers {
if nextForgers[q].Period.SlotNum == j {
if nextForgers[q].Coordinator.ItemID != 0 {
assert.Equal(t, bestBids[j].Bidder, nextForgers[q].Coordinator.Bidder)
} else {
assert.Equal(t, bootCoordinator.Bidder, nextForgers[q].Coordinator.Bidder)
}
firstBlockSlot, lastBlockSlot := api.getFirstLastBlock(j)
fromTimestamp := lastBlock.Timestamp.Add(time.Second * time.Duration(secondsPerBlock*(firstBlockSlot-lastBlock.EthBlockNum)))
toTimestamp := lastBlock.Timestamp.Add(time.Second * time.Duration(secondsPerBlock*(lastBlockSlot-lastBlock.EthBlockNum)))
assert.Equal(t, fromTimestamp.Unix(), nextForgers[q].Period.FromTimestamp.Unix())
assert.Equal(t, toTimestamp.Unix(), nextForgers[q].Period.ToTimestamp.Unix())
}
}
}
}
}
func TestUpdateNetworkInfo(t *testing.T) {
status := &Network{}
assert.Equal(t, status.LastBlock, api.status.Network.LastBlock)
assert.Equal(t, status.LastBatch.BatchNum, api.status.Network.LastBatch.BatchNum)
assert.Equal(t, status.CurrentSlot, api.status.Network.CurrentSlot)
assert.Equal(t, status.NextForgers, api.status.Network.NextForgers)
lastBlock := tc.blocks[3]
lastBatchNum := common.BatchNum(3)
currentSlotNum := int64(1)
err := api.UpdateNetworkInfo(lastBlock, lastBatchNum, currentSlotNum)
assert.NoError(t, err)
assert.Equal(t, lastBlock.EthBlockNum, api.status.Network.LastBlock)
assert.Equal(t, lastBatchNum, api.status.Network.LastBatch.BatchNum)
assert.Equal(t, currentSlotNum, api.status.Network.CurrentSlot)
assert.Equal(t, int(api.status.Auction.ClosedAuctionSlots)+1, len(api.status.Network.NextForgers))
}

+ 6
- 0
db/historydb/historydb.go

@ -1482,3 +1482,9 @@ func (hdb *HistoryDB) GetAccountsAPI(tokenIDs []common.TokenID, ethAddr *ethComm
LastItem: accounts[0].LastItem, LastItem: accounts[0].LastItem,
}, nil }, nil
} }
// GetMetrics returns metrics
func (hdb *HistoryDB) GetMetrics() (Metrics, error) {
metrics := Metrics{}
return metrics, nil
}

+ 0
- 8
db/historydb/views.go

@ -298,14 +298,6 @@ type BatchAPI struct {
LastItem uint64 `json:"-" meddler:"last_item"` LastItem uint64 `json:"-" meddler:"last_item"`
} }
// Network define status of the network
type Network struct {
LastBlock int64 `json:"lastBlock"`
LastBatch BatchAPI `json:"lastBatch"`
CurrentSlot int64 `json:"currentSlot"`
NextForgers []CoordinatorAPI `json:"nextForgers"`
}
// Metrics define metrics of the network // Metrics define metrics of the network
type Metrics struct { type Metrics struct {
TransactionsPerBatch float64 `json:"transactionsPerBatch"` TransactionsPerBatch float64 `json:"transactionsPerBatch"`

Loading…
Cancel
Save