Skip to content
95 changes: 72 additions & 23 deletions ethstorage/scanner/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,73 +5,122 @@ package scanner

import (
"fmt"
"time"

"github.com/ethstorage/go-ethstorage/ethstorage/flags/utils"
"github.com/urfave/cli"
)

const (
// Default Kvs per scan batch; bigger than this may cause run out of gas
defaultBatchSize = 8192
// Default intervals in minutes
defaultIntervalMeta = 3
defaultIntervalBlob = 60
// Minutes between fixing loops
fixingInterval = 12
// Minutes to wait before trying to fix pending mismatches
pendingWaitTime = 3
)

const (
modeDisabled = iota
// Compare local meta hashes with those in L1 contract
modeCheckMeta
// Compute meta hashes from local blobs and compare with those in L1 contract
modeCheckBlob
)

const (
ModeFlagName = "scanner.mode"
BatchSizeFlagName = "scanner.batch-size"
IntervalFlagName = "scanner.interval"
modeSetMeta scanModeSet = 1 << iota // 1
modeSetBlob // 2
)

const (
ModeFlagName = "scanner.mode"
BatchSizeFlagName = "scanner.batch-size"
IntervalMetaFlagName = "scanner.interval.meta"
IntervalBlobFlagName = "scanner.interval.blob"
)

const defaultInterval = 3 // in minutes
// scanModeSet is a combination of scanMode values used for configuration purposes.
type scanModeSet uint8

func (m scanModeSet) String() string {
if m == 0 {
return "disabled"
}

out := ""
if m&modeSetMeta != 0 {
out = "check-meta"
}
if m&modeSetBlob != 0 {
if out != "" {
out += "+"
}
out += "check-blob"
}
return out
}

func scannerEnv(name string) string {
return utils.PrefixEnvVar("SCANNER_" + name)
}

type Config struct {
Mode int
BatchSize int
Interval int
Mode scanModeSet
BatchSize int
IntervalMeta time.Duration
IntervalBlob time.Duration
}

func CLIFlags() []cli.Flag {
flags := []cli.Flag{
cli.IntFlag{
Name: ModeFlagName,
Usage: "Data scan mode, 0: disabled, 1: check meta, 2: check blob",
Usage: "Data scan mode (bitmask) : 0=disabled, 1=meta, 2=blob; combinations via sum/OR: 3=meta+blob",
EnvVar: scannerEnv("MODE"),
Value: 1,
},
cli.IntFlag{
Name: BatchSizeFlagName,
Usage: "Data scan batch size",
EnvVar: scannerEnv("BATCH_SIZE"),
Value: 8192,
Value: defaultBatchSize,
},
cli.IntFlag{
Name: IntervalFlagName,
Usage: fmt.Sprintf("Data scan interval in minutes, minimum %d (default)", defaultInterval),
EnvVar: scannerEnv("INTERVAL"),
Value: defaultInterval,
Name: IntervalMetaFlagName,
Usage: fmt.Sprintf("Data scan interval of check-meta mode in minutes (default %d)", defaultIntervalMeta),
EnvVar: scannerEnv("INTERVAL_META"),
Value: defaultIntervalMeta,
},
cli.IntFlag{
Name: IntervalBlobFlagName,
Usage: fmt.Sprintf("Data scan interval of check-blob mode in minutes (default %d)", defaultIntervalBlob),
EnvVar: scannerEnv("INTERVAL_BLOB"),
Value: defaultIntervalBlob,
},
}
return flags
}

const scanModeSetMask = modeSetMeta | modeSetBlob

func NewConfig(ctx *cli.Context) (*Config, error) {
mode := ctx.GlobalInt(ModeFlagName)
if mode == modeDisabled {
rawMode := scanModeSet(ctx.GlobalInt(ModeFlagName))
if rawMode == 0 {
return nil, nil
}
if mode != modeCheckMeta && mode != modeCheckBlob {
return nil, fmt.Errorf("invalid scanner mode: %d", mode)
}
if interval := ctx.GlobalInt(IntervalFlagName); interval < defaultInterval {
return nil, fmt.Errorf("scanner interval must be at least %d minutes", defaultInterval)
// Check for invalid bits outside the valid mask
if rawMode&^scanModeSetMask != 0 {
return nil, fmt.Errorf("invalid scanner mode: %d, valid values are 0 (disabled), 1 (meta), 2 (blob), or 3 (meta+blob)", rawMode)
}
mode := rawMode & scanModeSetMask
return &Config{
Mode: mode,
BatchSize: ctx.GlobalInt(BatchSizeFlagName),
Interval: ctx.GlobalInt(IntervalFlagName),
Mode: mode,
BatchSize: ctx.GlobalInt(BatchSizeFlagName),
IntervalMeta: time.Minute * time.Duration(ctx.GlobalInt(IntervalMetaFlagName)),
IntervalBlob: time.Minute * time.Duration(ctx.GlobalInt(IntervalBlobFlagName)),
}, nil
}
Loading
Loading