mirror of
https://github.com/arnaucube/hermez-node.git
synced 2026-02-07 11:26:44 +01:00
Merge pull request #280 from hermeznetwork/feature/integration15
Add Sync stats, and report them in DebugAPI
This commit is contained in:
@@ -21,6 +21,7 @@ URL = "http://localhost:8545"
|
|||||||
|
|
||||||
[Synchronizer]
|
[Synchronizer]
|
||||||
SyncLoopInterval = "1s"
|
SyncLoopInterval = "1s"
|
||||||
|
StatsRefreshPeriod = "1s"
|
||||||
|
|
||||||
[Synchronizer.StartBlockNum]
|
[Synchronizer.StartBlockNum]
|
||||||
Rollup = 1
|
Rollup = 1
|
||||||
|
|||||||
@@ -43,3 +43,12 @@ type AuctionVariables struct {
|
|||||||
// Number of blocks at the end of a slot in which any coordinator can forge if the winner has not forged one before
|
// Number of blocks at the end of a slot in which any coordinator can forge if the winner has not forged one before
|
||||||
SlotDeadline uint8 `json:"slotDeadline" meddler:"slot_deadline" validate:"required"`
|
SlotDeadline uint8 `json:"slotDeadline" meddler:"slot_deadline" validate:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Copy returns a deep copy of the Variables
|
||||||
|
func (v *AuctionVariables) Copy() *AuctionVariables {
|
||||||
|
vCpy := *v
|
||||||
|
for i := range v.DefaultSlotSetBid {
|
||||||
|
vCpy.DefaultSlotSetBid[i] = new(big.Int).SetBytes(v.DefaultSlotSetBid[i].Bytes())
|
||||||
|
}
|
||||||
|
return &vCpy
|
||||||
|
}
|
||||||
|
|||||||
@@ -163,3 +163,9 @@ type RollupVariables struct {
|
|||||||
WithdrawalDelay uint64 `json:"withdrawalDelay" meddler:"withdrawal_delay" validate:"required"`
|
WithdrawalDelay uint64 `json:"withdrawalDelay" meddler:"withdrawal_delay" validate:"required"`
|
||||||
Buckets [RollupConstNumBuckets]Bucket `json:"buckets" meddler:"buckets,json"`
|
Buckets [RollupConstNumBuckets]Bucket `json:"buckets" meddler:"buckets,json"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Copy returns a deep copy of the Variables
|
||||||
|
func (v *RollupVariables) Copy() *RollupVariables {
|
||||||
|
vCpy := *v
|
||||||
|
return &vCpy
|
||||||
|
}
|
||||||
|
|||||||
@@ -23,3 +23,9 @@ type WDelayerVariables struct {
|
|||||||
EmergencyModeStartingTime uint64 `json:"emergencyModeStartingTime" meddler:"emergency_start_time"`
|
EmergencyModeStartingTime uint64 `json:"emergencyModeStartingTime" meddler:"emergency_start_time"`
|
||||||
EmergencyMode bool `json:"emergencyMode" meddler:"emergency_mode"`
|
EmergencyMode bool `json:"emergencyMode" meddler:"emergency_mode"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Copy returns a deep copy of the Variables
|
||||||
|
func (v *WDelayerVariables) Copy() *WDelayerVariables {
|
||||||
|
vCpy := *v
|
||||||
|
return &vCpy
|
||||||
|
}
|
||||||
|
|||||||
@@ -66,9 +66,10 @@ type Node struct {
|
|||||||
URL string `validate:"required"`
|
URL string `validate:"required"`
|
||||||
} `validate:"required"`
|
} `validate:"required"`
|
||||||
Synchronizer struct {
|
Synchronizer struct {
|
||||||
SyncLoopInterval Duration `validate:"required"`
|
SyncLoopInterval Duration `validate:"required"`
|
||||||
StartBlockNum synchronizer.ConfigStartBlockNum `validate:"required"`
|
StatsRefreshPeriod Duration `validate:"required"`
|
||||||
InitialVariables synchronizer.SCVariables `validate:"required"`
|
StartBlockNum synchronizer.ConfigStartBlockNum `validate:"required"`
|
||||||
|
InitialVariables synchronizer.SCVariables `validate:"required"`
|
||||||
} `validate:"required"`
|
} `validate:"required"`
|
||||||
SmartContracts struct {
|
SmartContracts struct {
|
||||||
Rollup ethCommon.Address `validate:"required"`
|
Rollup ethCommon.Address `validate:"required"`
|
||||||
|
|||||||
@@ -172,6 +172,7 @@ type RollupInterface interface {
|
|||||||
|
|
||||||
// Viewers
|
// Viewers
|
||||||
RollupRegisterTokensCount() (*big.Int, error)
|
RollupRegisterTokensCount() (*big.Int, error)
|
||||||
|
RollupLastForgedBatch() (int64, error)
|
||||||
|
|
||||||
//
|
//
|
||||||
// Smart Contract Status
|
// Smart Contract Status
|
||||||
@@ -400,14 +401,9 @@ func (c *RollupClient) RollupL1UserTxERC20Permit(fromBJJ *babyjub.PublicKey, fro
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RollupRegisterTokensCount is the interface to call the smart contract function
|
// RollupRegisterTokensCount is the interface to call the smart contract function
|
||||||
func (c *RollupClient) RollupRegisterTokensCount() (*big.Int, error) {
|
func (c *RollupClient) RollupRegisterTokensCount() (registerTokensCount *big.Int, err error) {
|
||||||
var registerTokensCount *big.Int
|
|
||||||
if err := c.client.Call(func(ec *ethclient.Client) error {
|
if err := c.client.Call(func(ec *ethclient.Client) error {
|
||||||
hermez, err := Hermez.NewHermez(c.address, ec)
|
registerTokensCount, err = c.hermez.RegisterTokensCount(nil)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
registerTokensCount, err = hermez.RegisterTokensCount(nil)
|
|
||||||
return err
|
return err
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -415,6 +411,18 @@ func (c *RollupClient) RollupRegisterTokensCount() (*big.Int, error) {
|
|||||||
return registerTokensCount, nil
|
return registerTokensCount, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RollupLastForgedBatch is the interface to call the smart contract function
|
||||||
|
func (c *RollupClient) RollupLastForgedBatch() (lastForgedBatch int64, err error) {
|
||||||
|
if err := c.client.Call(func(ec *ethclient.Client) error {
|
||||||
|
_lastForgedBatch, err := c.hermez.LastForgedBatch(nil)
|
||||||
|
lastForgedBatch = int64(_lastForgedBatch)
|
||||||
|
return err
|
||||||
|
}); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return lastForgedBatch, nil
|
||||||
|
}
|
||||||
|
|
||||||
// RollupUpdateForgeL1L2BatchTimeout is the interface to call the smart contract function
|
// RollupUpdateForgeL1L2BatchTimeout is the interface to call the smart contract function
|
||||||
func (c *RollupClient) RollupUpdateForgeL1L2BatchTimeout(newForgeL1L2BatchTimeout int64) (tx *types.Transaction, err error) {
|
func (c *RollupClient) RollupUpdateForgeL1L2BatchTimeout(newForgeL1L2BatchTimeout int64) (tx *types.Transaction, err error) {
|
||||||
if tx, err = c.client.CallAuth(
|
if tx, err = c.client.CallAuth(
|
||||||
|
|||||||
@@ -114,8 +114,9 @@ func NewNode(mode Mode, cfg *config.Node, coordCfg *config.Coordinator) (*Node,
|
|||||||
}
|
}
|
||||||
|
|
||||||
sync, err := synchronizer.NewSynchronizer(client, historyDB, stateDB, synchronizer.Config{
|
sync, err := synchronizer.NewSynchronizer(client, historyDB, stateDB, synchronizer.Config{
|
||||||
StartBlockNum: cfg.Synchronizer.StartBlockNum,
|
StartBlockNum: cfg.Synchronizer.StartBlockNum,
|
||||||
InitialVariables: cfg.Synchronizer.InitialVariables,
|
InitialVariables: cfg.Synchronizer.InitialVariables,
|
||||||
|
StatsRefreshPeriod: cfg.Synchronizer.StatsRefreshPeriod.Duration,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -159,9 +160,8 @@ func NewNode(mode Mode, cfg *config.Node, coordCfg *config.Coordinator) (*Node,
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
var debugAPI *debugapi.DebugAPI
|
var debugAPI *debugapi.DebugAPI
|
||||||
println("apiaddr", cfg.Debug.APIAddress)
|
|
||||||
if cfg.Debug.APIAddress != "" {
|
if cfg.Debug.APIAddress != "" {
|
||||||
debugAPI = debugapi.NewDebugAPI(cfg.Debug.APIAddress, stateDB)
|
debugAPI = debugapi.NewDebugAPI(cfg.Debug.APIAddress, stateDB, sync)
|
||||||
}
|
}
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
return &Node{
|
return &Node{
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import (
|
|||||||
"database/sql"
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum"
|
"github.com/ethereum/go-ethereum"
|
||||||
"github.com/hermeznetwork/hermez-node/common"
|
"github.com/hermeznetwork/hermez-node/common"
|
||||||
@@ -39,6 +41,93 @@ var (
|
|||||||
// Synchronized bool
|
// Synchronized bool
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
// Stats of the syncrhonizer
|
||||||
|
type Stats struct {
|
||||||
|
Eth struct {
|
||||||
|
RefreshPeriod time.Duration
|
||||||
|
Updated time.Time
|
||||||
|
FirstBlock int64
|
||||||
|
LastBlock int64
|
||||||
|
LastBatch int64
|
||||||
|
}
|
||||||
|
Sync struct {
|
||||||
|
Updated time.Time
|
||||||
|
LastBlock int64
|
||||||
|
LastBatch int64
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// StatsHolder stores stats and that allows reading and writing them
|
||||||
|
// concurrently
|
||||||
|
type StatsHolder struct {
|
||||||
|
stats Stats
|
||||||
|
rw sync.RWMutex
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewStatsHolder creates a new StatsHolder
|
||||||
|
func NewStatsHolder(firstBlock int64, refreshPeriod time.Duration) *StatsHolder {
|
||||||
|
stats := Stats{}
|
||||||
|
stats.Eth.RefreshPeriod = refreshPeriod
|
||||||
|
stats.Eth.FirstBlock = firstBlock
|
||||||
|
return &StatsHolder{stats: stats}
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateSync updates the synchronizer stats
|
||||||
|
func (s *StatsHolder) UpdateSync(lastBlock int64, lastBatch *common.BatchNum) {
|
||||||
|
now := time.Now()
|
||||||
|
s.rw.Lock()
|
||||||
|
s.stats.Sync.LastBlock = lastBlock
|
||||||
|
if lastBatch != nil {
|
||||||
|
s.stats.Sync.LastBatch = int64(*lastBatch)
|
||||||
|
}
|
||||||
|
s.stats.Sync.Updated = now
|
||||||
|
s.rw.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateEth updates the ethereum stats, only if the previous stats expired
|
||||||
|
func (s *StatsHolder) UpdateEth(ethClient eth.ClientInterface) error {
|
||||||
|
now := time.Now()
|
||||||
|
s.rw.RLock()
|
||||||
|
elapsed := now.Sub(s.stats.Eth.Updated)
|
||||||
|
s.rw.RUnlock()
|
||||||
|
if elapsed < s.stats.Eth.RefreshPeriod {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
lastBlock, err := ethClient.EthCurrentBlock()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
lastBatch, err := ethClient.RollupLastForgedBatch()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
s.rw.Lock()
|
||||||
|
s.stats.Eth.Updated = now
|
||||||
|
s.stats.Eth.LastBlock = lastBlock
|
||||||
|
s.stats.Eth.LastBatch = lastBatch
|
||||||
|
s.rw.Unlock()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyStats returns a copy of the inner Stats
|
||||||
|
func (s *StatsHolder) CopyStats() *Stats {
|
||||||
|
s.rw.RLock()
|
||||||
|
sCopy := s.stats
|
||||||
|
s.rw.RUnlock()
|
||||||
|
return &sCopy
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StatsHolder) blocksPerc() float64 {
|
||||||
|
return float64(s.stats.Sync.LastBlock-s.stats.Eth.FirstBlock) * 100.0 /
|
||||||
|
float64(s.stats.Eth.LastBlock-s.stats.Eth.FirstBlock)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StatsHolder) batchesPerc(batchNum int64) float64 {
|
||||||
|
return float64(batchNum) * 100.0 /
|
||||||
|
float64(s.stats.Eth.LastBatch)
|
||||||
|
}
|
||||||
|
|
||||||
// ConfigStartBlockNum sets the first block used to start tracking the smart
|
// ConfigStartBlockNum sets the first block used to start tracking the smart
|
||||||
// contracts
|
// contracts
|
||||||
type ConfigStartBlockNum struct {
|
type ConfigStartBlockNum struct {
|
||||||
@@ -56,8 +145,9 @@ type SCVariables struct {
|
|||||||
|
|
||||||
// Config is the Synchronizer configuration
|
// Config is the Synchronizer configuration
|
||||||
type Config struct {
|
type Config struct {
|
||||||
StartBlockNum ConfigStartBlockNum
|
StartBlockNum ConfigStartBlockNum
|
||||||
InitialVariables SCVariables
|
InitialVariables SCVariables
|
||||||
|
StatsRefreshPeriod time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
// Synchronizer implements the Synchronizer type
|
// Synchronizer implements the Synchronizer type
|
||||||
@@ -71,6 +161,7 @@ type Synchronizer struct {
|
|||||||
cfg Config
|
cfg Config
|
||||||
startBlockNum int64
|
startBlockNum int64
|
||||||
vars SCVariables
|
vars SCVariables
|
||||||
|
stats *StatsHolder
|
||||||
// firstSavedBlock *common.Block
|
// firstSavedBlock *common.Block
|
||||||
// mux sync.Mutex
|
// mux sync.Mutex
|
||||||
}
|
}
|
||||||
@@ -103,6 +194,7 @@ func NewSynchronizer(ethClient eth.ClientInterface, historyDB *historydb.History
|
|||||||
if startBlockNum < cfg.StartBlockNum.WDelayer {
|
if startBlockNum < cfg.StartBlockNum.WDelayer {
|
||||||
startBlockNum = cfg.StartBlockNum.WDelayer
|
startBlockNum = cfg.StartBlockNum.WDelayer
|
||||||
}
|
}
|
||||||
|
stats := NewStatsHolder(startBlockNum, cfg.StatsRefreshPeriod)
|
||||||
s := &Synchronizer{
|
s := &Synchronizer{
|
||||||
ethClient: ethClient,
|
ethClient: ethClient,
|
||||||
auctionConstants: *auctionConstants,
|
auctionConstants: *auctionConstants,
|
||||||
@@ -112,10 +204,16 @@ func NewSynchronizer(ethClient eth.ClientInterface, historyDB *historydb.History
|
|||||||
stateDB: stateDB,
|
stateDB: stateDB,
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
startBlockNum: startBlockNum,
|
startBlockNum: startBlockNum,
|
||||||
|
stats: stats,
|
||||||
}
|
}
|
||||||
return s, s.init()
|
return s, s.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Stats returns a copy of the Synchronizer Stats
|
||||||
|
func (s *Synchronizer) Stats() *Stats {
|
||||||
|
return s.stats.CopyStats()
|
||||||
|
}
|
||||||
|
|
||||||
// AuctionConstants returns the AuctionConstants read from the smart contract
|
// AuctionConstants returns the AuctionConstants read from the smart contract
|
||||||
func (s *Synchronizer) AuctionConstants() *common.AuctionConstants {
|
func (s *Synchronizer) AuctionConstants() *common.AuctionConstants {
|
||||||
return &s.auctionConstants
|
return &s.auctionConstants
|
||||||
@@ -133,11 +231,13 @@ func (s *Synchronizer) WDelayerConstants() *common.WDelayerConstants {
|
|||||||
|
|
||||||
func (s *Synchronizer) init() error {
|
func (s *Synchronizer) init() error {
|
||||||
rollup, auction, wDelayer, err := s.historyDB.GetSCVars()
|
rollup, auction, wDelayer, err := s.historyDB.GetSCVars()
|
||||||
|
// If SCVars are not in the HistoryDB, this is probably the first run
|
||||||
|
// of the Synchronizer: store the initial vars taken from config
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
rollup = &s.cfg.InitialVariables.Rollup
|
rollup = &s.cfg.InitialVariables.Rollup
|
||||||
auction = &s.cfg.InitialVariables.Auction
|
auction = &s.cfg.InitialVariables.Auction
|
||||||
wDelayer = &s.cfg.InitialVariables.WDelayer
|
wDelayer = &s.cfg.InitialVariables.WDelayer
|
||||||
log.Debug("Setting initial SCVars in HistoryDB")
|
log.Info("Setting initial SCVars in HistoryDB")
|
||||||
if err = s.historyDB.SetInitialSCVars(rollup, auction, wDelayer); err != nil {
|
if err = s.historyDB.SetInitialSCVars(rollup, auction, wDelayer); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -145,6 +245,47 @@ func (s *Synchronizer) init() error {
|
|||||||
s.vars.Rollup = *rollup
|
s.vars.Rollup = *rollup
|
||||||
s.vars.Auction = *auction
|
s.vars.Auction = *auction
|
||||||
s.vars.WDelayer = *wDelayer
|
s.vars.WDelayer = *wDelayer
|
||||||
|
|
||||||
|
// Update stats parameters so that they have valid values before the
|
||||||
|
// first Sync call
|
||||||
|
if err := s.stats.UpdateEth(s.ethClient); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var lastBlockNum int64
|
||||||
|
lastSavedBlock, err := s.historyDB.GetLastBlock()
|
||||||
|
if err != nil && err != sql.ErrNoRows {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// If there's no block in the DB (or we only have the default block 0),
|
||||||
|
// make sure that the stateDB is clean
|
||||||
|
if err == sql.ErrNoRows || lastSavedBlock.EthBlockNum == 0 {
|
||||||
|
if err := s.stateDB.Reset(0); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
lastBlockNum = lastSavedBlock.EthBlockNum
|
||||||
|
}
|
||||||
|
lastBatchNum, err := s.historyDB.GetLastBatchNum()
|
||||||
|
if err != nil && err != sql.ErrNoRows {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
lastBatchNum = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
s.stats.UpdateSync(lastBlockNum, &lastBatchNum)
|
||||||
|
|
||||||
|
log.Infow("Sync init block",
|
||||||
|
"syncLastBlock", s.stats.stats.Sync.LastBlock,
|
||||||
|
"syncBlocksPerc", s.stats.blocksPerc(),
|
||||||
|
"ethFirstBlock", s.stats.stats.Eth.FirstBlock,
|
||||||
|
"ethLastBlock", s.stats.stats.Eth.LastBlock,
|
||||||
|
)
|
||||||
|
log.Infow("Sync init batch",
|
||||||
|
"syncLastBatch", s.stats.stats.Sync.LastBatch,
|
||||||
|
"syncBatchesPerc", s.stats.batchesPerc(s.stats.stats.Sync.LastBatch),
|
||||||
|
"ethLastBatch", s.stats.stats.Eth.LastBatch,
|
||||||
|
)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,7 +323,14 @@ func (s *Synchronizer) Sync2(ctx context.Context, lastSavedBlock *common.Block)
|
|||||||
}
|
}
|
||||||
log.Debugf("ethBlock: num: %v, parent: %v, hash: %v", ethBlock.EthBlockNum, ethBlock.ParentHash.String(), ethBlock.Hash.String())
|
log.Debugf("ethBlock: num: %v, parent: %v, hash: %v", ethBlock.EthBlockNum, ethBlock.ParentHash.String(), ethBlock.Hash.String())
|
||||||
|
|
||||||
log.Debugw("Syncing...", "block", nextBlockNum)
|
if err := s.stats.UpdateEth(s.ethClient); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugw("Syncing...",
|
||||||
|
"block", nextBlockNum,
|
||||||
|
"ethLastBlock", s.stats.stats.Eth.LastBlock,
|
||||||
|
)
|
||||||
|
|
||||||
// Check that the obtianed ethBlock.ParentHash == prevEthBlock.Hash; if not, reorg!
|
// Check that the obtianed ethBlock.ParentHash == prevEthBlock.Hash; if not, reorg!
|
||||||
if lastSavedBlock != nil {
|
if lastSavedBlock != nil {
|
||||||
@@ -249,6 +397,26 @@ func (s *Synchronizer) Sync2(ctx context.Context, lastSavedBlock *common.Block)
|
|||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
batchesLen := len(rollupData.Batches)
|
||||||
|
if batchesLen == 0 {
|
||||||
|
s.stats.UpdateSync(ethBlock.EthBlockNum, nil)
|
||||||
|
} else {
|
||||||
|
s.stats.UpdateSync(ethBlock.EthBlockNum,
|
||||||
|
&rollupData.Batches[batchesLen-1].Batch.BatchNum)
|
||||||
|
}
|
||||||
|
log.Debugw("Synced block",
|
||||||
|
"syncLastBlock", s.stats.stats.Sync.LastBlock,
|
||||||
|
"syncBlocksPerc", s.stats.blocksPerc(),
|
||||||
|
"ethLastBlock", s.stats.stats.Eth.LastBlock,
|
||||||
|
)
|
||||||
|
for _, batchData := range rollupData.Batches {
|
||||||
|
log.Debugw("Synced batch",
|
||||||
|
"syncLastBatch", batchData.Batch.BatchNum,
|
||||||
|
"syncBatchesPerc", s.stats.batchesPerc(int64(batchData.Batch.BatchNum)),
|
||||||
|
"ethLastBatch", s.stats.stats.Eth.LastBatch,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return &blockData, nil, nil
|
return &blockData, nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -566,7 +734,7 @@ func (s *Synchronizer) rollupSync(ethBlock *common.Block) (*common.RollupData, e
|
|||||||
|
|
||||||
if varsUpdate {
|
if varsUpdate {
|
||||||
s.vars.Rollup.EthBlockNum = blockNum
|
s.vars.Rollup.EthBlockNum = blockNum
|
||||||
rollupData.Vars = &s.vars.Rollup
|
rollupData.Vars = s.vars.Rollup.Copy()
|
||||||
}
|
}
|
||||||
|
|
||||||
return &rollupData, nil
|
return &rollupData, nil
|
||||||
@@ -665,7 +833,7 @@ func (s *Synchronizer) auctionSync(ethBlock *common.Block) (*common.AuctionData,
|
|||||||
|
|
||||||
if varsUpdate {
|
if varsUpdate {
|
||||||
s.vars.Auction.EthBlockNum = blockNum
|
s.vars.Auction.EthBlockNum = blockNum
|
||||||
auctionData.Vars = &s.vars.Auction
|
auctionData.Vars = s.vars.Auction.Copy()
|
||||||
}
|
}
|
||||||
|
|
||||||
return &auctionData, nil
|
return &auctionData, nil
|
||||||
@@ -734,7 +902,7 @@ func (s *Synchronizer) wdelayerSync(ethBlock *common.Block) (*common.WDelayerDat
|
|||||||
|
|
||||||
if varsUpdate {
|
if varsUpdate {
|
||||||
s.vars.WDelayer.EthBlockNum = blockNum
|
s.vars.WDelayer.EthBlockNum = blockNum
|
||||||
wDelayerData.Vars = &s.vars.WDelayer
|
wDelayerData.Vars = s.vars.WDelayer.Copy()
|
||||||
}
|
}
|
||||||
|
|
||||||
return &wDelayerData, nil
|
return &wDelayerData, nil
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"github.com/hermeznetwork/hermez-node/common"
|
"github.com/hermeznetwork/hermez-node/common"
|
||||||
"github.com/hermeznetwork/hermez-node/db/statedb"
|
"github.com/hermeznetwork/hermez-node/db/statedb"
|
||||||
"github.com/hermeznetwork/hermez-node/log"
|
"github.com/hermeznetwork/hermez-node/log"
|
||||||
|
"github.com/hermeznetwork/hermez-node/synchronizer"
|
||||||
)
|
)
|
||||||
|
|
||||||
func handleNoRoute(c *gin.Context) {
|
func handleNoRoute(c *gin.Context) {
|
||||||
@@ -33,13 +34,15 @@ func badReq(err error, c *gin.Context) {
|
|||||||
type DebugAPI struct {
|
type DebugAPI struct {
|
||||||
addr string
|
addr string
|
||||||
stateDB *statedb.StateDB // synchronizer statedb
|
stateDB *statedb.StateDB // synchronizer statedb
|
||||||
|
sync *synchronizer.Synchronizer
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDebugAPI creates a new DebugAPI
|
// NewDebugAPI creates a new DebugAPI
|
||||||
func NewDebugAPI(addr string, stateDB *statedb.StateDB) *DebugAPI {
|
func NewDebugAPI(addr string, stateDB *statedb.StateDB, sync *synchronizer.Synchronizer) *DebugAPI {
|
||||||
return &DebugAPI{
|
return &DebugAPI{
|
||||||
stateDB: stateDB,
|
|
||||||
addr: addr,
|
addr: addr,
|
||||||
|
stateDB: stateDB,
|
||||||
|
sync: sync,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,6 +85,11 @@ func (a *DebugAPI) handleMTRoot(c *gin.Context) {
|
|||||||
c.JSON(http.StatusOK, root)
|
c.JSON(http.StatusOK, root)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *DebugAPI) handleSyncStats(c *gin.Context) {
|
||||||
|
stats := a.sync.Stats()
|
||||||
|
c.JSON(http.StatusOK, stats)
|
||||||
|
}
|
||||||
|
|
||||||
// Run starts the http server of the DebugAPI. To stop it, pass a context with
|
// Run starts the http server of the DebugAPI. To stop it, pass a context with
|
||||||
// cancelation (see `debugapi_test.go` for an example).
|
// cancelation (see `debugapi_test.go` for an example).
|
||||||
func (a *DebugAPI) Run(ctx context.Context) error {
|
func (a *DebugAPI) Run(ctx context.Context) error {
|
||||||
@@ -98,6 +106,8 @@ func (a *DebugAPI) Run(ctx context.Context) error {
|
|||||||
debugAPI.GET("sdb/accounts", a.handleAccounts)
|
debugAPI.GET("sdb/accounts", a.handleAccounts)
|
||||||
debugAPI.GET("sdb/accounts/:Idx", a.handleAccount)
|
debugAPI.GET("sdb/accounts/:Idx", a.handleAccount)
|
||||||
|
|
||||||
|
debugAPI.GET("sync/stats", a.handleSyncStats)
|
||||||
|
|
||||||
debugAPIServer := &http.Server{
|
debugAPIServer := &http.Server{
|
||||||
Addr: a.addr,
|
Addr: a.addr,
|
||||||
Handler: api,
|
Handler: api,
|
||||||
|
|||||||
@@ -50,7 +50,8 @@ func TestDebugAPI(t *testing.T) {
|
|||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
addr := "localhost:12345"
|
addr := "localhost:12345"
|
||||||
debugAPI := NewDebugAPI(addr, sdb)
|
// We won't test the sync/stats endpoint, so we can se the Syncrhonizer to nil
|
||||||
|
debugAPI := NewDebugAPI(addr, sdb, nil)
|
||||||
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
go func() {
|
go func() {
|
||||||
|
|||||||
@@ -762,6 +762,16 @@ func (c *Client) RollupRegisterTokensCount() (*big.Int, error) {
|
|||||||
return nil, errTODO
|
return nil, errTODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RollupLastForgedBatch is the interface to call the smart contract function
|
||||||
|
func (c *Client) RollupLastForgedBatch() (int64, error) {
|
||||||
|
c.rw.RLock()
|
||||||
|
defer c.rw.RUnlock()
|
||||||
|
|
||||||
|
currentBlock := c.currentBlock()
|
||||||
|
e := currentBlock.Rollup
|
||||||
|
return int64(len(e.State.ExitRoots)) - 1, nil
|
||||||
|
}
|
||||||
|
|
||||||
// RollupWithdrawCircuit is the interface to call the smart contract function
|
// RollupWithdrawCircuit is the interface to call the smart contract function
|
||||||
func (c *Client) RollupWithdrawCircuit(proofA, proofC [2]*big.Int, proofB [2][2]*big.Int, tokenID uint32, numExitRoot, idx int64, amount *big.Int, instantWithdraw bool) (*types.Transaction, error) {
|
func (c *Client) RollupWithdrawCircuit(proofA, proofC [2]*big.Int, proofB [2][2]*big.Int, tokenID uint32, numExitRoot, idx int64, amount *big.Int, instantWithdraw bool) (*types.Transaction, error) {
|
||||||
log.Error("TODO")
|
log.Error("TODO")
|
||||||
|
|||||||
Reference in New Issue
Block a user