erigon-pulse/turbo/snapshotsync/snapcfg/util.go
2023-01-25 09:55:26 +07:00

160 lines
4.3 KiB
Go

package snapcfg
import (
_ "embed"
"path/filepath"
"strconv"
"strings"
snapshothashes "github.com/ledgerwatch/erigon-snapshot"
"github.com/ledgerwatch/erigon/params/networkname"
"github.com/pelletier/go-toml/v2"
"golang.org/x/exp/slices"
)
var (
Mainnet = fromToml(snapshothashes.Mainnet)
Sepolia = fromToml(snapshothashes.Sepolia)
Goerli = fromToml(snapshothashes.Goerli)
Bsc = fromToml(snapshothashes.Bsc)
Mumbai = fromToml(snapshothashes.Mumbai)
BorMainnet = fromToml(snapshothashes.BorMainnet)
Gnosis = fromToml(snapshothashes.Gnosis)
MainnetHistory = fromToml(snapshothashes.MainnetHistory)
SepoliaHistory = fromToml(snapshothashes.SepoliaHistory)
GoerliHistory = fromToml(snapshothashes.GoerliHistory)
BscHistory = fromToml(snapshothashes.BscHistory)
MumbaiHistory = fromToml(snapshothashes.MumbaiHistory)
BorMainnetHistory = fromToml(snapshothashes.BorMainnetHistory)
GnosisHistory = fromToml(snapshothashes.GnosisHistory)
)
type PreverifiedItem struct {
Name string
Hash string
}
type Preverified []PreverifiedItem
type preverified map[string]string
func fromToml(in []byte) (out Preverified) {
var outMap preverified
if err := toml.Unmarshal(in, &outMap); err != nil {
panic(err)
}
return doSort(outMap)
}
func doSort(in preverified) Preverified {
out := make(Preverified, 0, len(in))
for k, v := range in {
out = append(out, PreverifiedItem{k, v})
}
slices.SortFunc(out, func(i, j PreverifiedItem) bool { return i.Name < j.Name })
return out
}
var (
MainnetChainSnapshotCfg = newCfg(Mainnet, MainnetHistory)
SepoliaChainSnapshotCfg = newCfg(Sepolia, SepoliaHistory)
GoerliChainSnapshotCfg = newCfg(Goerli, GoerliHistory)
BscChainSnapshotCfg = newCfg(Bsc, BscHistory)
MumbaiChainSnapshotCfg = newCfg(Mumbai, MumbaiHistory)
BorMainnetChainSnapshotCfg = newCfg(BorMainnet, BorMainnetHistory)
GnosisChainSnapshotCfg = newCfg(Gnosis, GnosisHistory)
)
func newCfg(preverified, preverifiedHistory Preverified) *Cfg {
return &Cfg{ExpectBlocks: maxBlockNum(preverified), Preverified: preverified, PreverifiedHistory: preverifiedHistory}
}
func maxBlockNum(preverified Preverified) uint64 {
max := uint64(0)
for _, p := range preverified {
_, fileName := filepath.Split(p.Name)
ext := filepath.Ext(fileName)
if ext != ".seg" {
continue
}
onlyName := fileName[:len(fileName)-len(ext)]
parts := strings.Split(onlyName, "-")
if parts[0] != "v1" {
panic("not implemented")
}
if parts[3] != "headers" {
continue
}
to, err := strconv.ParseUint(parts[2], 10, 64)
if err != nil {
panic(err)
}
if max < to {
max = to
}
}
if max == 0 { // to prevent underflow
return 0
}
return max*1_000 - 1
}
type Cfg struct {
ExpectBlocks uint64
Preverified Preverified
PreverifiedHistory Preverified
}
var KnownCfgs = map[string]*Cfg{
networkname.MainnetChainName: MainnetChainSnapshotCfg,
networkname.SepoliaChainName: SepoliaChainSnapshotCfg,
networkname.GoerliChainName: GoerliChainSnapshotCfg,
networkname.BSCChainName: BscChainSnapshotCfg,
networkname.MumbaiChainName: MumbaiChainSnapshotCfg,
networkname.BorMainnetChainName: BorMainnetChainSnapshotCfg,
networkname.GnosisChainName: GnosisChainSnapshotCfg,
}
// KnownCfg return list of preverified hashes for given network, but apply whiteList filter if it's not empty
func KnownCfg(networkName string, whiteList, whiteListHistory []string) *Cfg {
c, ok := KnownCfgs[networkName]
if !ok {
return newCfg(Preverified{}, Preverified{})
}
var result, result2 Preverified
if len(whiteList) == 0 {
result = c.Preverified
} else {
wlMap := make(map[string]struct{}, len(whiteList))
for _, fName := range whiteList {
wlMap[fName] = struct{}{}
}
result = make(Preverified, 0, len(c.Preverified))
for _, p := range c.Preverified {
if _, ok := wlMap[p.Name]; !ok {
continue
}
result = append(result, p)
}
}
if len(whiteList) == 0 {
result2 = c.PreverifiedHistory
} else {
wlMap2 := make(map[string]struct{}, len(whiteListHistory))
for _, fName := range whiteListHistory {
wlMap2[fName] = struct{}{}
}
result2 = make(Preverified, 0, len(c.PreverifiedHistory))
for _, p := range c.PreverifiedHistory {
if _, ok := wlMap2[p.Name]; !ok {
continue
}
result2 = append(result2, p)
}
}
return newCfg(result, result2)
}