mirror of
https://github.com/arnaucube/hermez-node.git
synced 2026-02-07 03:16:45 +01:00
WIP
This commit is contained in:
12
api/api.go
12
api/api.go
@@ -34,20 +34,20 @@ func NewAPI(
|
||||
if explorerEndpoints && hdb == nil {
|
||||
return nil, tracerr.Wrap(errors.New("cannot serve Explorer endpoints without HistoryDB"))
|
||||
}
|
||||
ni, err := hdb.GetNodeInfo()
|
||||
consts, err := hdb.GetConstants()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
a := &API{
|
||||
h: hdb,
|
||||
cg: &configAPI{
|
||||
RollupConstants: *newRollupConstants(ni.Constants.RollupConstants),
|
||||
AuctionConstants: ni.Constants.AuctionConstants,
|
||||
WDelayerConstants: ni.Constants.WDelayerConstants,
|
||||
RollupConstants: *newRollupConstants(consts.Rollup),
|
||||
AuctionConstants: consts.Auction,
|
||||
WDelayerConstants: consts.WDelayer,
|
||||
},
|
||||
l2: l2db,
|
||||
chainID: ni.Constants.ChainID,
|
||||
hermezAddress: ni.Constants.HermezAddress,
|
||||
chainID: consts.ChainID,
|
||||
hermezAddress: consts.HermezAddress,
|
||||
}
|
||||
|
||||
// Add coordinator endpoints
|
||||
|
||||
@@ -186,6 +186,7 @@ type testCommon struct {
|
||||
var tc testCommon
|
||||
var config configAPI
|
||||
var api *API
|
||||
var stateAPIUpdater *StateAPIUpdater
|
||||
|
||||
// TestMain initializes the API server, and fill HistoryDB and StateDB with fake data,
|
||||
// emulating the task of the synchronizer in order to have data to be returned
|
||||
@@ -222,15 +223,27 @@ func TestMain(m *testing.M) {
|
||||
apiGin := gin.Default()
|
||||
// Reset DB
|
||||
test.WipeDB(hdb.DB())
|
||||
if err := hdb.SetInitialNodeInfo(10, 0.0, &historydb.Constants{
|
||||
RollupConstants: _config.RollupConstants,
|
||||
AuctionConstants: _config.AuctionConstants,
|
||||
WDelayerConstants: _config.WDelayerConstants,
|
||||
ChainID: chainID,
|
||||
HermezAddress: _config.HermezAddress,
|
||||
}); err != nil {
|
||||
|
||||
constants := &historydb.Constants{
|
||||
SCConsts: common.SCConsts{
|
||||
Rollup: _config.RollupConstants,
|
||||
Auction: _config.AuctionConstants,
|
||||
WDelayer: _config.WDelayerConstants,
|
||||
},
|
||||
ChainID: chainID,
|
||||
HermezAddress: _config.HermezAddress,
|
||||
}
|
||||
if err := hdb.SetConstants(constants); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
nodeConfig := &historydb.NodeConfig{
|
||||
MaxPoolTxs: 10,
|
||||
MinFeeUSD: 0,
|
||||
}
|
||||
if err := hdb.SetNodeConfig(nodeConfig); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
api, err = NewAPI(
|
||||
true,
|
||||
true,
|
||||
@@ -507,6 +520,12 @@ func TestMain(m *testing.M) {
|
||||
WithdrawalDelay: uint64(3000),
|
||||
}
|
||||
|
||||
stateAPIUpdater = NewStateAPIUpdater(hdb, nodeConfig, &common.SCVariables{
|
||||
Rollup: rollupVars,
|
||||
Auction: auctionVars,
|
||||
WDelayer: wdelayerVars,
|
||||
}, constants)
|
||||
|
||||
// Generate test data, as expected to be received/sended from/to the API
|
||||
testCoords := genTestCoordinators(commonCoords)
|
||||
testBids := genTestBids(commonBlocks, testCoords, bids)
|
||||
|
||||
@@ -99,14 +99,14 @@ func TestGetSlot(t *testing.T) {
|
||||
nil, &fetchedSlot,
|
||||
),
|
||||
)
|
||||
ni, err := api.h.GetNodeInfoAPI()
|
||||
assert.NoError(t, err)
|
||||
emptySlot := api.getEmptyTestSlot(slotNum, ni.APIState.Network.LastSyncBlock, tc.auctionVars)
|
||||
// ni, err := api.h.GetNodeInfoAPI()
|
||||
// assert.NoError(t, err)
|
||||
emptySlot := api.getEmptyTestSlot(slotNum, 0, tc.auctionVars)
|
||||
assertSlot(t, emptySlot, fetchedSlot)
|
||||
|
||||
// Invalid slotNum
|
||||
path := endpoint + strconv.Itoa(-2)
|
||||
err = doBadReq("GET", path, nil, 400)
|
||||
err := doBadReq("GET", path, nil, 400)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
@@ -129,10 +129,10 @@ func TestGetSlots(t *testing.T) {
|
||||
err := doGoodReqPaginated(path, historydb.OrderAsc, &testSlotsResponse{}, appendIter)
|
||||
assert.NoError(t, err)
|
||||
allSlots := tc.slots
|
||||
ni, err := api.h.GetNodeInfoAPI()
|
||||
assert.NoError(t, err)
|
||||
// ni, err := api.h.GetNodeInfoAPI()
|
||||
// assert.NoError(t, err)
|
||||
for i := tc.slots[len(tc.slots)-1].SlotNum; i < maxSlotNum; i++ {
|
||||
emptySlot := api.getEmptyTestSlot(i+1, ni.APIState.Network.LastSyncBlock, tc.auctionVars)
|
||||
emptySlot := api.getEmptyTestSlot(i+1, 0, tc.auctionVars)
|
||||
allSlots = append(allSlots, emptySlot)
|
||||
}
|
||||
assertSlots(t, allSlots, fetchedSlots)
|
||||
|
||||
68
api/state.go
68
api/state.go
@@ -3,6 +3,7 @@ package api
|
||||
import (
|
||||
"database/sql"
|
||||
"net/http"
|
||||
"sync"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/hermeznetwork/hermez-node/common"
|
||||
@@ -19,30 +20,39 @@ func (a *API) getState(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, stateAPI)
|
||||
}
|
||||
|
||||
type APIStateUpdater struct {
|
||||
// StateAPIUpdater is an utility object to facilitate updating the StateAPI
|
||||
type StateAPIUpdater struct {
|
||||
hdb *historydb.HistoryDB
|
||||
state historydb.StateAPI
|
||||
config historydb.NodeConfig
|
||||
vars common.SCVariablesPtr
|
||||
consts historydb.Constants
|
||||
rw sync.RWMutex
|
||||
}
|
||||
|
||||
func NewAPIStateUpdater(hdb *historydb.HistoryDB, config *historydb.NodeConfig, vars *common.SCVariables,
|
||||
consts *historydb.Constants) *APIStateUpdater {
|
||||
u := APIStateUpdater{
|
||||
// NewStateAPIUpdater creates a new StateAPIUpdater
|
||||
func NewStateAPIUpdater(hdb *historydb.HistoryDB, config *historydb.NodeConfig, vars *common.SCVariables,
|
||||
consts *historydb.Constants) *StateAPIUpdater {
|
||||
u := StateAPIUpdater{
|
||||
hdb: hdb,
|
||||
config: *config,
|
||||
consts: *consts,
|
||||
}
|
||||
u.SetSCVars(&common.SCVariablesPtr{&vars.Rollup, &vars.Auction, &vars.WDelayer})
|
||||
u.SetSCVars(vars.AsPtr())
|
||||
return &u
|
||||
}
|
||||
|
||||
func (u *APIStateUpdater) Store() error {
|
||||
return tracerr.Wrap(u.hdb.SetAPIState(&u.state))
|
||||
// Store the State in the HistoryDB
|
||||
func (u *StateAPIUpdater) Store() error {
|
||||
u.rw.RLock()
|
||||
defer u.rw.RUnlock()
|
||||
return tracerr.Wrap(u.hdb.SetStateInternalAPI(&u.state))
|
||||
}
|
||||
|
||||
func (u *APIStateUpdater) SetSCVars(vars *common.SCVariablesPtr) {
|
||||
// SetSCVars sets the smart contract vars (ony updates those that are not nil)
|
||||
func (u *StateAPIUpdater) SetSCVars(vars *common.SCVariablesPtr) {
|
||||
u.rw.Lock()
|
||||
defer u.rw.Unlock()
|
||||
if vars.Rollup != nil {
|
||||
u.vars.Rollup = vars.Rollup
|
||||
rollupVars := historydb.NewRollupVariablesAPI(u.vars.Rollup)
|
||||
@@ -59,25 +69,47 @@ func (u *APIStateUpdater) SetSCVars(vars *common.SCVariablesPtr) {
|
||||
}
|
||||
}
|
||||
|
||||
func (u *APIStateUpdater) UpdateMetrics() error {
|
||||
if u.state.Network.LastBatch == nil {
|
||||
// UpdateRecommendedFee update Status.RecommendedFee information
|
||||
func (u *StateAPIUpdater) UpdateRecommendedFee() error {
|
||||
recommendedFee, err := u.hdb.GetRecommendedFee(u.config.MinFeeUSD)
|
||||
if err != nil {
|
||||
return tracerr.Wrap(err)
|
||||
}
|
||||
u.rw.Lock()
|
||||
u.state.RecommendedFee = *recommendedFee
|
||||
u.rw.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateMetrics update Status.Metrics information
|
||||
func (u *StateAPIUpdater) UpdateMetrics() error {
|
||||
u.rw.RLock()
|
||||
lastBatch := u.state.Network.LastBatch
|
||||
u.rw.RUnlock()
|
||||
if lastBatch == nil {
|
||||
return nil
|
||||
}
|
||||
lastBatchNum := u.state.Network.LastBatch.BatchNum
|
||||
lastBatchNum := lastBatch.BatchNum
|
||||
metrics, err := u.hdb.GetMetricsInternalAPI(lastBatchNum)
|
||||
if err != nil {
|
||||
return tracerr.Wrap(err)
|
||||
}
|
||||
u.rw.Lock()
|
||||
u.state.Metrics = *metrics
|
||||
u.rw.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *APIStateUpdater) UpdateNetworkInfoBlock(lastEthBlock, lastSyncBlock common.Block) {
|
||||
// UpdateNetworkInfoBlock update Status.Network block related information
|
||||
func (u *StateAPIUpdater) UpdateNetworkInfoBlock(lastEthBlock, lastSyncBlock common.Block) {
|
||||
u.rw.Lock()
|
||||
u.state.Network.LastSyncBlock = lastSyncBlock.Num
|
||||
u.state.Network.LastEthBlock = lastEthBlock.Num
|
||||
u.rw.Unlock()
|
||||
}
|
||||
|
||||
func (u *APIStateUpdater) UpdateNetworkInfo(
|
||||
// UpdateNetworkInfo update Status.Network information
|
||||
func (u *StateAPIUpdater) UpdateNetworkInfo(
|
||||
lastEthBlock, lastSyncBlock common.Block,
|
||||
lastBatchNum common.BatchNum, currentSlot int64,
|
||||
) error {
|
||||
@@ -88,9 +120,12 @@ func (u *APIStateUpdater) UpdateNetworkInfo(
|
||||
} else if err != nil {
|
||||
return tracerr.Wrap(err)
|
||||
}
|
||||
u.rw.RLock()
|
||||
auctionVars := u.vars.Auction
|
||||
u.rw.RUnlock()
|
||||
// Get next forgers
|
||||
lastClosedSlot := currentSlot + int64(u.state.Auction.ClosedAuctionSlots)
|
||||
nextForgers, err := u.hdb.GetNextForgersInternalAPI(u.vars.Auction, &u.consts.Auction,
|
||||
lastClosedSlot := currentSlot + int64(auctionVars.ClosedAuctionSlots)
|
||||
nextForgers, err := u.hdb.GetNextForgersInternalAPI(auctionVars, &u.consts.Auction,
|
||||
lastSyncBlock, currentSlot, lastClosedSlot)
|
||||
if tracerr.Unwrap(err) == sql.ErrNoRows {
|
||||
nextForgers = nil
|
||||
@@ -104,6 +139,8 @@ func (u *APIStateUpdater) UpdateNetworkInfo(
|
||||
} else if err != nil {
|
||||
return tracerr.Wrap(err)
|
||||
}
|
||||
|
||||
u.rw.Lock()
|
||||
// Update NodeInfo struct
|
||||
for i, bucketParams := range u.state.Rollup.Buckets {
|
||||
for _, bucketUpdate := range bucketUpdates {
|
||||
@@ -119,5 +156,6 @@ func (u *APIStateUpdater) UpdateNetworkInfo(
|
||||
u.state.Network.LastBatch = lastBatch
|
||||
u.state.Network.CurrentSlot = currentSlot
|
||||
u.state.Network.NextForgers = nextForgers
|
||||
u.rw.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -29,10 +29,11 @@ type testNetwork struct {
|
||||
}
|
||||
|
||||
func TestSetRollupVariables(t *testing.T) {
|
||||
api.h.SetRollupVariables(&tc.rollupVars)
|
||||
stateAPIUpdater.SetSCVars(&common.SCVariablesPtr{Rollup: &tc.rollupVars})
|
||||
require.NoError(t, stateAPIUpdater.Store())
|
||||
ni, err := api.h.GetNodeInfoAPI()
|
||||
assert.NoError(t, err)
|
||||
assertEqualRollupVariables(t, tc.rollupVars, ni.APIState.Rollup, true)
|
||||
require.NoError(t, err)
|
||||
assertEqualRollupVariables(t, tc.rollupVars, ni.StateAPI.Rollup, true)
|
||||
}
|
||||
|
||||
func assertEqualRollupVariables(t *testing.T, rollupVariables common.RollupVariables, apiVariables historydb.RollupVariablesAPI, checkBuckets bool) {
|
||||
@@ -51,17 +52,19 @@ func assertEqualRollupVariables(t *testing.T, rollupVariables common.RollupVaria
|
||||
}
|
||||
|
||||
func TestSetWDelayerVariables(t *testing.T) {
|
||||
api.h.SetWDelayerVariables(&tc.wdelayerVars)
|
||||
stateAPIUpdater.SetSCVars(&common.SCVariablesPtr{WDelayer: &tc.wdelayerVars})
|
||||
require.NoError(t, stateAPIUpdater.Store())
|
||||
ni, err := api.h.GetNodeInfoAPI()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tc.wdelayerVars, ni.APIState.WithdrawalDelayer)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, tc.wdelayerVars, ni.StateAPI.WithdrawalDelayer)
|
||||
}
|
||||
|
||||
func TestSetAuctionVariables(t *testing.T) {
|
||||
api.h.SetAuctionVariables(&tc.auctionVars)
|
||||
stateAPIUpdater.SetSCVars(&common.SCVariablesPtr{Auction: &tc.auctionVars})
|
||||
require.NoError(t, stateAPIUpdater.Store())
|
||||
ni, err := api.h.GetNodeInfoAPI()
|
||||
assert.NoError(t, err)
|
||||
assertEqualAuctionVariables(t, tc.auctionVars, ni.APIState.Auction)
|
||||
require.NoError(t, err)
|
||||
assertEqualAuctionVariables(t, tc.auctionVars, ni.StateAPI.Auction)
|
||||
}
|
||||
|
||||
func assertEqualAuctionVariables(t *testing.T, auctionVariables common.AuctionVariables, apiVariables historydb.AuctionVariablesAPI) {
|
||||
@@ -113,16 +116,18 @@ func TestUpdateNetworkInfo(t *testing.T) {
|
||||
err := api.h.AddBucketUpdatesTest(api.h.DB(), bucketUpdates)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = api.h.UpdateNetworkInfo(lastBlock, lastBlock, lastBatchNum, currentSlotNum)
|
||||
assert.NoError(t, err)
|
||||
// stateAPIUpdater := NewStateAPIUpdater(hdb)
|
||||
err = stateAPIUpdater.UpdateNetworkInfo(lastBlock, lastBlock, lastBatchNum, currentSlotNum)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, stateAPIUpdater.Store())
|
||||
ni, err := api.h.GetNodeInfoAPI()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, lastBlock.Num, ni.APIState.Network.LastSyncBlock)
|
||||
assert.Equal(t, lastBatchNum, ni.APIState.Network.LastBatch.BatchNum)
|
||||
assert.Equal(t, currentSlotNum, ni.APIState.Network.CurrentSlot)
|
||||
assert.Equal(t, int(ni.APIState.Auction.ClosedAuctionSlots)+1, len(ni.APIState.Network.NextForgers))
|
||||
assert.Equal(t, ni.APIState.Rollup.Buckets[0].Withdrawals, apitypes.NewBigIntStr(big.NewInt(123)))
|
||||
assert.Equal(t, ni.APIState.Rollup.Buckets[2].Withdrawals, apitypes.NewBigIntStr(big.NewInt(43)))
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, lastBlock.Num, ni.StateAPI.Network.LastSyncBlock)
|
||||
assert.Equal(t, lastBatchNum, ni.StateAPI.Network.LastBatch.BatchNum)
|
||||
assert.Equal(t, currentSlotNum, ni.StateAPI.Network.CurrentSlot)
|
||||
assert.Equal(t, int(ni.StateAPI.Auction.ClosedAuctionSlots)+1, len(ni.StateAPI.Network.NextForgers))
|
||||
assert.Equal(t, ni.StateAPI.Rollup.Buckets[0].Withdrawals, apitypes.NewBigIntStr(big.NewInt(123)))
|
||||
assert.Equal(t, ni.StateAPI.Rollup.Buckets[2].Withdrawals, apitypes.NewBigIntStr(big.NewInt(43)))
|
||||
}
|
||||
|
||||
func TestUpdateMetrics(t *testing.T) {
|
||||
@@ -130,31 +135,33 @@ func TestUpdateMetrics(t *testing.T) {
|
||||
lastBlock := tc.blocks[3]
|
||||
lastBatchNum := common.BatchNum(12)
|
||||
currentSlotNum := int64(1)
|
||||
err := api.h.UpdateNetworkInfo(lastBlock, lastBlock, lastBatchNum, currentSlotNum)
|
||||
assert.NoError(t, err)
|
||||
err := stateAPIUpdater.UpdateNetworkInfo(lastBlock, lastBlock, lastBatchNum, currentSlotNum)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = api.h.UpdateMetrics()
|
||||
assert.NoError(t, err)
|
||||
err = stateAPIUpdater.UpdateMetrics()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, stateAPIUpdater.Store())
|
||||
ni, err := api.h.GetNodeInfoAPI()
|
||||
assert.NoError(t, err)
|
||||
assert.Greater(t, ni.APIState.Metrics.TransactionsPerBatch, float64(0))
|
||||
assert.Greater(t, ni.APIState.Metrics.BatchFrequency, float64(0))
|
||||
assert.Greater(t, ni.APIState.Metrics.TransactionsPerSecond, float64(0))
|
||||
assert.Greater(t, ni.APIState.Metrics.TotalAccounts, int64(0))
|
||||
assert.Greater(t, ni.APIState.Metrics.TotalBJJs, int64(0))
|
||||
assert.Greater(t, ni.APIState.Metrics.AvgTransactionFee, float64(0))
|
||||
require.NoError(t, err)
|
||||
assert.Greater(t, ni.StateAPI.Metrics.TransactionsPerBatch, float64(0))
|
||||
assert.Greater(t, ni.StateAPI.Metrics.BatchFrequency, float64(0))
|
||||
assert.Greater(t, ni.StateAPI.Metrics.TransactionsPerSecond, float64(0))
|
||||
assert.Greater(t, ni.StateAPI.Metrics.TotalAccounts, int64(0))
|
||||
assert.Greater(t, ni.StateAPI.Metrics.TotalBJJs, int64(0))
|
||||
assert.Greater(t, ni.StateAPI.Metrics.AvgTransactionFee, float64(0))
|
||||
}
|
||||
|
||||
func TestUpdateRecommendedFee(t *testing.T) {
|
||||
err := api.h.UpdateRecommendedFee()
|
||||
assert.NoError(t, err)
|
||||
err := stateAPIUpdater.UpdateRecommendedFee()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, stateAPIUpdater.Store())
|
||||
var minFeeUSD float64
|
||||
if api.l2 != nil {
|
||||
minFeeUSD = api.l2.MinFeeUSD()
|
||||
}
|
||||
ni, err := api.h.GetNodeInfoAPI()
|
||||
assert.NoError(t, err)
|
||||
assert.Greater(t, ni.APIState.RecommendedFee.ExistingAccount, minFeeUSD)
|
||||
require.NoError(t, err)
|
||||
assert.Greater(t, ni.StateAPI.RecommendedFee.ExistingAccount, minFeeUSD)
|
||||
// assert.Equal(t, ni.StateAPI.RecommendedFee.CreatesAccount,
|
||||
// ni.StateAPI.RecommendedFee.ExistingAccount*createAccountExtraFeePercentage)
|
||||
// assert.Equal(t, ni.StateAPI.RecommendedFee.CreatesAccountAndRegister,
|
||||
@@ -165,20 +172,23 @@ func TestGetState(t *testing.T) {
|
||||
lastBlock := tc.blocks[3]
|
||||
lastBatchNum := common.BatchNum(12)
|
||||
currentSlotNum := int64(1)
|
||||
api.h.SetRollupVariables(&tc.rollupVars)
|
||||
api.h.SetWDelayerVariables(&tc.wdelayerVars)
|
||||
api.h.SetAuctionVariables(&tc.auctionVars)
|
||||
err := api.h.UpdateNetworkInfo(lastBlock, lastBlock, lastBatchNum, currentSlotNum)
|
||||
assert.NoError(t, err)
|
||||
err = api.h.UpdateMetrics()
|
||||
assert.NoError(t, err)
|
||||
err = api.h.UpdateRecommendedFee()
|
||||
assert.NoError(t, err)
|
||||
stateAPIUpdater.SetSCVars(&common.SCVariablesPtr{
|
||||
Rollup: &tc.rollupVars,
|
||||
Auction: &tc.auctionVars,
|
||||
WDelayer: &tc.wdelayerVars,
|
||||
})
|
||||
err := stateAPIUpdater.UpdateNetworkInfo(lastBlock, lastBlock, lastBatchNum, currentSlotNum)
|
||||
require.NoError(t, err)
|
||||
err = stateAPIUpdater.UpdateMetrics()
|
||||
require.NoError(t, err)
|
||||
err = stateAPIUpdater.UpdateRecommendedFee()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, stateAPIUpdater.Store())
|
||||
|
||||
endpoint := apiURL + "state"
|
||||
var status testStatus
|
||||
|
||||
assert.NoError(t, doGoodReq("GET", endpoint, nil, &status))
|
||||
require.NoError(t, doGoodReq("GET", endpoint, nil, &status))
|
||||
|
||||
// SC vars
|
||||
// UpdateNetworkInfo will overwrite buckets withdrawal values
|
||||
|
||||
Reference in New Issue
Block a user