monza/stutter.go
Alex Vanin 4fc7478e1e [#1] Add '-f' flag to overwrite local cache
Sometimes multiple environments have blockchains with
the same magic number. In this case, user should not
reuse cached chain, because cache contains magic number
to identify different chains. With new '-f' flag user
will be able to repopulate cache with new data for the
chain with the same magic number.

Signed-off-by: Alex Vanin <a.vanin@yadro.com>
2023-10-19 17:20:45 +03:00

98 lines
2 KiB
Go

package main
import (
"context"
"errors"
"fmt"
"os"
"os/signal"
"time"
"git.frostfs.info/TrueCloudLab/monza/internal/chain"
"github.com/nspcc-dev/neo-go/pkg/core/block"
"github.com/urfave/cli/v2"
)
func stutter(c *cli.Context) (err error) {
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
// parse blockchain info
cacheDir := c.String(cacheFlagKey)
if len(cacheDir) == 0 {
cacheDir, err = defaultConfigDir()
if err != nil {
return err
}
}
blockchain, err := chain.Open(ctx, cacheDir, c.String(endpointFlagKey), false)
if err != nil {
return fmt.Errorf("cannot initialize remote blockchain client: %w", err)
}
defer func() {
blockchain.Close()
cancel()
}()
// parse block indices
from, to, err := parseInterval(c.String(fromFlagKey), c.String(toFlagKey), blockchain.Client)
if err != nil {
return err
}
threshold := c.Duration(stutterThresholdFlagKey)
// need at least two blocks
if to-from < 2 {
return errors.New("range must contain at least two blocks")
}
// fetch blocks
err = cacheBlocks(ctx, &params{
from: from,
to: to,
blockchain: blockchain,
workers: int(c.Uint64(workersFlagKey)),
disableBar: c.Bool(disableProgressBarFlagKey),
})
if err != nil {
return err
}
// process blocks one by one
var (
prev, curr *block.Block
prevTS, currTS time.Time
lastStutterBlock uint32
)
for i := from; i < to; i++ {
b, err := blockchain.Block(i)
if err != nil {
return fmt.Errorf("cannot fetch block %d: %w", i, err)
}
prev, prevTS = curr, currTS
curr = b
currTS = time.Unix(int64(b.Timestamp/1e3), 0)
if prev == nil { // first block case
continue
}
blockDelta := currTS.Sub(prevTS)
if blockDelta <= threshold {
continue
}
skippedBlocks := prev.Index - lastStutterBlock
if lastStutterBlock > 0 && skippedBlocks > 1 {
fmt.Printf("-- skipped %d blocks --\n", skippedBlocks-1)
}
PrintBlock(prev, "")
PrintBlock(curr, fmt.Sprintf("<- stutter for %s", blockDelta))
lastStutterBlock = curr.Index
}
return nil
}