Merge pull request #1928 from bnb-chain/develop
This commit is contained in:
commit
1dca486622
2
.github/workflows/build-test.yml
vendored
2
.github/workflows/build-test.yml
vendored
@ -15,7 +15,7 @@ jobs:
|
||||
unit-test:
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.19.x]
|
||||
go-version: [1.20.x]
|
||||
os: [ubuntu-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
|
2
.github/workflows/lint.yml
vendored
2
.github/workflows/lint.yml
vendored
@ -15,7 +15,7 @@ jobs:
|
||||
golang-lint:
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.19.x]
|
||||
go-version: [1.20.x]
|
||||
os: [ubuntu-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
|
2
.github/workflows/pre-release.yml
vendored
2
.github/workflows/pre-release.yml
vendored
@ -15,7 +15,7 @@ jobs:
|
||||
name: Build Release
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.19.x]
|
||||
go-version: [1.20.x]
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
|
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@ -14,7 +14,7 @@ jobs:
|
||||
name: Build Release
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.19.x]
|
||||
go-version: [1.20.x]
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
|
2
.github/workflows/unit-test.yml
vendored
2
.github/workflows/unit-test.yml
vendored
@ -15,7 +15,7 @@ jobs:
|
||||
unit-test:
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.19.x]
|
||||
go-version: [1.20.x]
|
||||
os: [ubuntu-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
|
@ -51,9 +51,6 @@ issues:
|
||||
- path: core/state/metrics.go
|
||||
linters:
|
||||
- unused
|
||||
- path: core/state/statedb_fuzz_test.go
|
||||
linters:
|
||||
- unused
|
||||
- path: core/txpool/legacypool/list.go
|
||||
linters:
|
||||
- staticcheck
|
||||
|
20
CHANGELOG.md
20
CHANGELOG.md
@ -1,4 +1,24 @@
|
||||
# Changelog
|
||||
## v1.3.1
|
||||
FEATURE
|
||||
* [\#1881](https://github.com/bnb-chain/bsc/pull/1881) feat: active pbss
|
||||
* [\#1882](https://github.com/bnb-chain/bsc/pull/1882) cmd/geth: add hbss to pbss convert tool
|
||||
* [\#1916](https://github.com/bnb-chain/bsc/pull/1916) feat: cherry-pick pbss patch commits from eth repo in v1.13.2
|
||||
* [\#1939](https://github.com/bnb-chain/bsc/pull/1939) dependency: go version to 1.20 and some dependencies in go.mod
|
||||
* [\#1955](https://github.com/bnb-chain/bsc/pull/1955) eth, trie/triedb/pathdb: pbss patches
|
||||
* [\#1962](https://github.com/bnb-chain/bsc/pull/1962) cherry pick pbss patches from go-ethereum
|
||||
|
||||
BUGFIX
|
||||
* [\#1923](https://github.com/bnb-chain/bsc/pull/1923) consensus/parlia: fix nextForkHash in Extra filed of block header
|
||||
* [\#1950](https://github.com/bnb-chain/bsc/pull/1950) fix: 2 APIs of get receipt related
|
||||
* [\#1951](https://github.com/bnb-chain/bsc/pull/1951) txpool: fix a potential crash issue in shutdown;
|
||||
* [\#1963](https://github.com/bnb-chain/bsc/pull/1963) fix: revert trie commited flag after delete statedb mpt cache
|
||||
|
||||
IMPROVEMENT
|
||||
* [\#1948](https://github.com/bnb-chain/bsc/pull/1948) performance: commitTire concurrently
|
||||
* [\#1949](https://github.com/bnb-chain/bsc/pull/1949) code: remove accountTrieCache and storageTrieCache
|
||||
* [\#1954](https://github.com/bnb-chain/bsc/pull/1954) trie: keep trie prefetch during validation phase
|
||||
|
||||
## v1.3.0
|
||||
#### RPC
|
||||
* [internal/ethapi: add debug_getRawReceipts RPC method (#24773)](https://github.com/bnb-chain/bsc/pull/1840/commits/ae7d834bc752a2d94fef9d354ee78fcb9425f3d1)
|
||||
|
@ -61,7 +61,7 @@ Many of the below are the same as or similar to go-ethereum.
|
||||
|
||||
For prerequisites and detailed build instructions please read the [Installation Instructions](https://geth.ethereum.org/docs/getting-started/installing-geth).
|
||||
|
||||
Building `geth` requires both a Go (version 1.19 or later) and a C compiler (GCC 5 or higher). You can install
|
||||
Building `geth` requires both a Go (version 1.20 or later) and a C compiler (GCC 5 or higher). You can install
|
||||
them using your favourite package manager. Once the dependencies are installed, run
|
||||
|
||||
```shell
|
||||
|
@ -2145,7 +2145,7 @@ func TestGolangBindings(t *testing.T) {
|
||||
t.Fatalf("failed to replace cometbft dependency to bnb-chain source: %v\n%s", err, out)
|
||||
}
|
||||
|
||||
tidier := exec.Command(gocmd, "mod", "tidy", "-compat=1.19")
|
||||
tidier := exec.Command(gocmd, "mod", "tidy", "-compat=1.20")
|
||||
tidier.Dir = pkg
|
||||
if out, err := tidier.CombinedOutput(); err != nil {
|
||||
t.Fatalf("failed to tidy Go module file: %v\n%s", err, out)
|
||||
|
@ -97,6 +97,7 @@ var (
|
||||
utils.TransactionHistoryFlag,
|
||||
utils.StateSchemeFlag,
|
||||
utils.StateHistoryFlag,
|
||||
utils.PathDBSyncFlag,
|
||||
utils.LightServeFlag,
|
||||
utils.LightIngressFlag,
|
||||
utils.LightEgressFlag,
|
||||
|
@ -23,6 +23,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/tsdb/fileutil"
|
||||
@ -360,7 +361,21 @@ func pruneBlock(ctx *cli.Context) error {
|
||||
if path == "" {
|
||||
return errors.New("prune failed, did not specify the AncientPath")
|
||||
}
|
||||
newAncientPath = filepath.Join(path, "ancient_back")
|
||||
newVersionPath := false
|
||||
files, err := os.ReadDir(oldAncientPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, file := range files {
|
||||
if file.IsDir() && file.Name() == "chain" {
|
||||
newVersionPath = true
|
||||
}
|
||||
}
|
||||
if newVersionPath && !strings.HasSuffix(oldAncientPath, "geth/chaindata/ancient/chain") {
|
||||
log.Error("datadir.ancient subdirectory incorrect", "got path", oldAncientPath, "want subdirectory", "geth/chaindata/ancient/chain/")
|
||||
return errors.New("datadir.ancient subdirectory incorrect")
|
||||
}
|
||||
newAncientPath = filepath.Join(path, "chain_back")
|
||||
|
||||
blockpruner = pruner.NewBlockPruner(chaindb, stack, oldAncientPath, newAncientPath, blockAmountReserved)
|
||||
|
||||
|
@ -314,6 +314,12 @@ var (
|
||||
Value: rawdb.HashScheme,
|
||||
Category: flags.StateCategory,
|
||||
}
|
||||
PathDBSyncFlag = &cli.BoolFlag{
|
||||
Name: "pathdb.sync",
|
||||
Usage: "sync flush nodes cache to disk in path schema",
|
||||
Value: false,
|
||||
Category: flags.StateCategory,
|
||||
}
|
||||
StateHistoryFlag = &cli.Uint64Flag{
|
||||
Name: "history.state",
|
||||
Usage: "Number of recent blocks to retain state history for (default = 90,000 blocks, 0 = entire chain)",
|
||||
@ -1951,6 +1957,9 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
|
||||
log.Warn("The flag --txlookuplimit is deprecated and will be removed, please use --history.transactions")
|
||||
cfg.TransactionHistory = ctx.Uint64(TransactionHistoryFlag.Name)
|
||||
}
|
||||
if ctx.IsSet(PathDBSyncFlag.Name) {
|
||||
cfg.PathSyncFlush = true
|
||||
}
|
||||
if ctx.String(GCModeFlag.Name) == "archive" && cfg.TransactionHistory != 0 {
|
||||
cfg.TransactionHistory = 0
|
||||
log.Warn("Disabled transaction unindexing for archive node")
|
||||
|
@ -950,7 +950,7 @@ func (p *Parlia) Prepare(chain consensus.ChainHeaderReader, header *types.Header
|
||||
}
|
||||
|
||||
header.Extra = header.Extra[:extraVanity-nextForkHashSize]
|
||||
nextForkHash := forkid.NewID(p.chainConfig, p.genesisHash, number, header.Time).Hash
|
||||
nextForkHash := forkid.NextForkHash(p.chainConfig, p.genesisHash, number, header.Time)
|
||||
header.Extra = append(header.Extra, nextForkHash[:]...)
|
||||
|
||||
if err := p.prepareValidators(header); err != nil {
|
||||
@ -1084,7 +1084,7 @@ func (p *Parlia) Finalize(chain consensus.ChainHeaderReader, header *types.Heade
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
nextForkHash := forkid.NewID(p.chainConfig, p.genesisHash, number, header.Time).Hash
|
||||
nextForkHash := forkid.NextForkHash(p.chainConfig, p.genesisHash, number, header.Time)
|
||||
if !snap.isMajorityFork(hex.EncodeToString(nextForkHash[:])) {
|
||||
log.Debug("there is a possible fork, and your client is not the majority. Please check...", "nextForkHash", hex.EncodeToString(nextForkHash[:]))
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
package parlia
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
mrand "math/rand"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/crypto/sha3"
|
||||
@ -47,7 +48,7 @@ func simulateValidatorOutOfService(totalValidators int, downValidators int) {
|
||||
validators[i] = true
|
||||
down[i] = i
|
||||
}
|
||||
rand.Shuffle(totalValidators, func(i, j int) {
|
||||
mrand.Shuffle(totalValidators, func(i, j int) {
|
||||
down[i], down[j] = down[j], down[i]
|
||||
})
|
||||
for i := 0; i < downValidators; i++ {
|
||||
@ -125,8 +126,8 @@ func simulateValidatorOutOfService(totalValidators int, downValidators int) {
|
||||
}
|
||||
|
||||
func producerBlockDelay(candidates map[int]bool, height, numOfValidators int) (int, uint64) {
|
||||
s := rand.NewSource(int64(height))
|
||||
r := rand.New(s)
|
||||
s := mrand.NewSource(int64(height))
|
||||
r := mrand.New(s)
|
||||
n := numOfValidators
|
||||
backOffSteps := make([]int, 0, n)
|
||||
for idx := 0; idx < n; idx++ {
|
||||
|
@ -155,6 +155,7 @@ type CacheConfig struct {
|
||||
NoTries bool // Insecure settings. Do not have any tries in databases if enabled.
|
||||
StateHistory uint64 // Number of blocks from head whose state histories are reserved.
|
||||
StateScheme string // Scheme used to store ethereum states and merkle tree nodes on top
|
||||
PathSyncFlush bool // Whether sync flush the trienodebuffer of pathdb to disk.
|
||||
|
||||
SnapshotNoBuild bool // Whether the background generation is allowed
|
||||
SnapshotWait bool // Wait for snapshot construction on startup. TODO(karalabe): This is a dirty hack for testing, nuke it
|
||||
@ -174,6 +175,7 @@ func (c *CacheConfig) triedbConfig() *trie.Config {
|
||||
}
|
||||
if c.StateScheme == rawdb.PathScheme {
|
||||
config.PathDB = &pathdb.Config{
|
||||
SyncFlush: c.PathSyncFlush,
|
||||
StateHistory: c.StateHistory,
|
||||
CleanCacheSize: c.TrieCleanLimit * 1024 * 1024,
|
||||
DirtyCacheSize: c.TrieDirtyLimit * 1024 * 1024,
|
||||
@ -396,11 +398,15 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
|
||||
var diskRoot common.Hash
|
||||
if bc.cacheConfig.SnapshotLimit > 0 {
|
||||
diskRoot = rawdb.ReadSnapshotRoot(bc.db)
|
||||
} else if bc.triedb.Scheme() == rawdb.PathScheme {
|
||||
_, diskRoot = rawdb.ReadAccountTrieNode(bc.db, nil)
|
||||
}
|
||||
if bc.triedb.Scheme() == rawdb.PathScheme {
|
||||
recoverable, _ := bc.triedb.Recoverable(diskRoot)
|
||||
if !bc.HasState(diskRoot) && !recoverable {
|
||||
diskRoot = bc.triedb.Head()
|
||||
}
|
||||
}
|
||||
if diskRoot != (common.Hash{}) {
|
||||
log.Warn("Head state missing, repairing", "number", head.Number, "hash", head.Hash(), "snaproot", diskRoot)
|
||||
log.Warn("Head state missing, repairing", "number", head.Number, "hash", head.Hash(), "diskRoot", diskRoot)
|
||||
|
||||
snapDisk, err := bc.setHeadBeyondRoot(head.Number.Uint64(), 0, diskRoot, true)
|
||||
if err != nil {
|
||||
@ -689,18 +695,18 @@ func (bc *BlockChain) loadLastState() error {
|
||||
blockTd = bc.GetTd(headBlock.Hash(), headBlock.NumberU64())
|
||||
)
|
||||
if headHeader.Hash() != headBlock.Hash() {
|
||||
log.Info("Loaded most recent local header", "number", headHeader.Number, "hash", headHeader.Hash(), "td", headerTd, "age", common.PrettyAge(time.Unix(int64(headHeader.Time), 0)))
|
||||
log.Info("Loaded most recent local header", "number", headHeader.Number, "hash", headHeader.Hash(), "hash", headHeader.Root, "td", headerTd, "age", common.PrettyAge(time.Unix(int64(headHeader.Time), 0)))
|
||||
}
|
||||
log.Info("Loaded most recent local block", "number", headBlock.Number(), "hash", headBlock.Hash(), "td", blockTd, "age", common.PrettyAge(time.Unix(int64(headBlock.Time()), 0)))
|
||||
log.Info("Loaded most recent local block", "number", headBlock.Number(), "hash", headBlock.Hash(), "root", headBlock.Root(), "td", blockTd, "age", common.PrettyAge(time.Unix(int64(headBlock.Time()), 0)))
|
||||
if headBlock.Hash() != currentSnapBlock.Hash() {
|
||||
snapTd := bc.GetTd(currentSnapBlock.Hash(), currentSnapBlock.Number.Uint64())
|
||||
log.Info("Loaded most recent local snap block", "number", currentSnapBlock.Number, "hash", currentSnapBlock.Hash(), "td", snapTd, "age", common.PrettyAge(time.Unix(int64(currentSnapBlock.Time), 0)))
|
||||
log.Info("Loaded most recent local snap block", "number", currentSnapBlock.Number, "hash", currentSnapBlock.Hash(), "root", currentSnapBlock.Root, "td", snapTd, "age", common.PrettyAge(time.Unix(int64(currentSnapBlock.Time), 0)))
|
||||
}
|
||||
if posa, ok := bc.engine.(consensus.PoSA); ok {
|
||||
if currentFinalizedHeader := posa.GetFinalizedHeader(bc, headHeader); currentFinalizedHeader != nil {
|
||||
if currentFinalizedBlock := bc.GetBlockByHash(currentFinalizedHeader.Hash()); currentFinalizedBlock != nil {
|
||||
finalTd := bc.GetTd(currentFinalizedBlock.Hash(), currentFinalizedBlock.NumberU64())
|
||||
log.Info("Loaded most recent local finalized block", "number", currentFinalizedBlock.Number(), "hash", currentFinalizedBlock.Hash(), "td", finalTd, "age", common.PrettyAge(time.Unix(int64(currentFinalizedBlock.Time()), 0)))
|
||||
log.Info("Loaded most recent local finalized block", "number", currentFinalizedBlock.Number(), "hash", currentFinalizedBlock.Hash(), "root", currentFinalizedBlock.Root(), "td", finalTd, "age", common.PrettyAge(time.Unix(int64(currentFinalizedBlock.Time()), 0)))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -802,6 +808,7 @@ func (bc *BlockChain) setHeadBeyondRoot(head uint64, time uint64, root common.Ha
|
||||
|
||||
// resetState resets the persistent state to genesis if it's not available.
|
||||
resetState := func() {
|
||||
log.Info("Reset to block with genesis state", "number", bc.genesisBlock.NumberU64(), "hash", bc.genesisBlock.Hash())
|
||||
// Short circuit if the genesis state is already present.
|
||||
if bc.HasState(bc.genesisBlock.Root()) {
|
||||
return
|
||||
@ -825,7 +832,6 @@ func (bc *BlockChain) setHeadBeyondRoot(head uint64, time uint64, root common.Ha
|
||||
// chain reparation mechanism without deleting any data!
|
||||
if currentBlock := bc.CurrentBlock(); currentBlock != nil && header.Number.Uint64() <= currentBlock.Number.Uint64() {
|
||||
newHeadBlock := bc.GetBlock(header.Hash(), header.Number.Uint64())
|
||||
lastBlockNum := header.Number.Uint64()
|
||||
if newHeadBlock == nil {
|
||||
log.Error("Gap in the chain, rewinding to genesis", "number", header.Number, "hash", header.Hash())
|
||||
newHeadBlock = bc.genesisBlock
|
||||
@ -835,10 +841,8 @@ func (bc *BlockChain) setHeadBeyondRoot(head uint64, time uint64, root common.Ha
|
||||
// keeping rewinding until we exceed the optional threshold
|
||||
// root hash
|
||||
beyondRoot := (root == common.Hash{}) // Flag whether we're beyond the requested root (no root, always true)
|
||||
enoughBeyondCount := false
|
||||
beyondCount := 0
|
||||
|
||||
for {
|
||||
beyondCount++
|
||||
// If a root threshold was requested but not yet crossed, check
|
||||
if root != (common.Hash{}) && !beyondRoot && newHeadBlock.Root() == root {
|
||||
beyondRoot, rootNumber = true, newHeadBlock.NumberU64()
|
||||
@ -854,24 +858,11 @@ func (bc *BlockChain) setHeadBeyondRoot(head uint64, time uint64, root common.Ha
|
||||
log.Error("Missing block in the middle, aiming genesis", "number", newHeadBlock.NumberU64()-1, "hash", newHeadBlock.ParentHash())
|
||||
newHeadBlock = bc.genesisBlock
|
||||
} else {
|
||||
log.Trace("Rewind passed pivot, aiming genesis", "number", newHeadBlock.NumberU64(), "hash", newHeadBlock.Hash(), "pivot", *pivot)
|
||||
log.Info("Rewind passed pivot, aiming genesis", "number", newHeadBlock.NumberU64(), "hash", newHeadBlock.Hash(), "pivot", *pivot)
|
||||
newHeadBlock = bc.genesisBlock
|
||||
}
|
||||
}
|
||||
if beyondRoot || (enoughBeyondCount && root != common.Hash{}) || newHeadBlock.NumberU64() == 0 {
|
||||
if enoughBeyondCount && (root != common.Hash{}) && rootNumber == 0 {
|
||||
for {
|
||||
lastBlockNum++
|
||||
block := bc.GetBlockByNumber(lastBlockNum)
|
||||
if block == nil {
|
||||
break
|
||||
}
|
||||
if block.Root() == root {
|
||||
rootNumber = block.NumberU64()
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if beyondRoot || newHeadBlock.NumberU64() == 0 {
|
||||
if newHeadBlock.NumberU64() == 0 {
|
||||
resetState()
|
||||
} else if !bc.HasState(newHeadBlock.Root()) {
|
||||
@ -1180,8 +1171,7 @@ func (bc *BlockChain) Stop() {
|
||||
// - HEAD-127: So we have a hard limit on the number of blocks reexecuted
|
||||
if !bc.cacheConfig.TrieDirtyDisabled {
|
||||
triedb := bc.triedb
|
||||
var once sync.Once
|
||||
|
||||
var once sync.Once
|
||||
for _, offset := range []uint64{0, 1, TriesInMemory - 1} {
|
||||
if number := bc.CurrentBlock().Number.Uint64(); number > offset {
|
||||
recent := bc.GetBlockByNumber(number - offset)
|
||||
@ -1191,9 +1181,9 @@ func (bc *BlockChain) Stop() {
|
||||
} else {
|
||||
rawdb.WriteSafePointBlockNumber(bc.db, recent.NumberU64())
|
||||
once.Do(func() {
|
||||
rawdb.WriteHeadBlockHash(bc.db, recent.Hash())
|
||||
rawdb.WriteHeadBlockHash(bc.db, recent.Hash())
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if snapBase != (common.Hash{}) {
|
||||
@ -1216,7 +1206,7 @@ func (bc *BlockChain) Stop() {
|
||||
for !bc.triegc.Empty() {
|
||||
triedb.Dereference(bc.triegc.PopItem())
|
||||
}
|
||||
if size, _ := triedb.Size(); size != 0 {
|
||||
if _, size, _, _ := triedb.Size(); size != 0 {
|
||||
log.Error("Dangling trie nodes after full cleanup")
|
||||
}
|
||||
}
|
||||
@ -1620,8 +1610,8 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
|
||||
if current := block.NumberU64(); current > bc.triesInMemory {
|
||||
// If we exceeded our memory allowance, flush matured singleton nodes to disk
|
||||
var (
|
||||
nodes, imgs = triedb.Size()
|
||||
limit = common.StorageSize(bc.cacheConfig.TrieDirtyLimit) * 1024 * 1024
|
||||
_, nodes, _, imgs = triedb.Size()
|
||||
limit = common.StorageSize(bc.cacheConfig.TrieDirtyLimit) * 1024 * 1024
|
||||
)
|
||||
if nodes > limit || imgs > 4*1024*1024 {
|
||||
triedb.Cap(limit - ethdb.IdealBatchSize)
|
||||
@ -2105,8 +2095,8 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error)
|
||||
stats.processed++
|
||||
stats.usedGas += usedGas
|
||||
|
||||
dirty, _ := bc.triedb.Size()
|
||||
stats.report(chain, it.index, dirty, setHead)
|
||||
trieDiffNodes, trieBufNodes, trieImmutableBufNodes, _ := bc.triedb.Size()
|
||||
stats.report(chain, it.index, trieDiffNodes, trieBufNodes, trieImmutableBufNodes, setHead)
|
||||
|
||||
if !setHead {
|
||||
// After merge we expect few side chains. Simply count
|
||||
|
@ -39,7 +39,7 @@ const statsReportLimit = 8 * time.Second
|
||||
|
||||
// report prints statistics if some number of blocks have been processed
|
||||
// or more than a few seconds have passed since the last message.
|
||||
func (st *insertStats) report(chain []*types.Block, index int, dirty common.StorageSize, setHead bool) {
|
||||
func (st *insertStats) report(chain []*types.Block, index int, trieDiffNodes, trieBufNodes, trieImmutableBufNodes common.StorageSize, setHead bool) {
|
||||
// Fetch the timings for the batch
|
||||
var (
|
||||
now = mclock.Now()
|
||||
@ -63,7 +63,13 @@ func (st *insertStats) report(chain []*types.Block, index int, dirty common.Stor
|
||||
if timestamp := time.Unix(int64(end.Time()), 0); time.Since(timestamp) > time.Minute {
|
||||
context = append(context, []interface{}{"age", common.PrettyAge(timestamp)}...)
|
||||
}
|
||||
context = append(context, []interface{}{"dirty", dirty}...)
|
||||
if trieDiffNodes != 0 { // pathdb
|
||||
context = append(context, []interface{}{"triediffs", trieDiffNodes}...)
|
||||
context = append(context, []interface{}{"triedirty", trieBufNodes}...)
|
||||
context = append(context, []interface{}{"trieimutabledirty", trieImmutableBufNodes}...)
|
||||
} else {
|
||||
context = append(context, []interface{}{"triedirty", trieBufNodes}...)
|
||||
}
|
||||
|
||||
if st.queued > 0 {
|
||||
context = append(context, []interface{}{"queued", st.queued}...)
|
||||
|
@ -1807,7 +1807,7 @@ func TestTrieForkGC(t *testing.T) {
|
||||
chain.stateCache.TrieDB().Dereference(blocks[len(blocks)-1-i].Root())
|
||||
chain.stateCache.TrieDB().Dereference(forks[len(blocks)-1-i].Root())
|
||||
}
|
||||
if nodes, _ := chain.TrieDB().Size(); nodes > 0 {
|
||||
if _, nodes, _, _ := chain.TrieDB().Size(); nodes > 0 {
|
||||
t.Fatalf("stale tries still alive after garbase collection")
|
||||
}
|
||||
}
|
||||
|
@ -98,6 +98,32 @@ func NewID(config *params.ChainConfig, genesis common.Hash, head, time uint64) I
|
||||
return ID{Hash: checksumToBytes(hash), Next: 0}
|
||||
}
|
||||
|
||||
// NextForkHash calculates the forkHash from genesis to the next fork block number or time
|
||||
func NextForkHash(config *params.ChainConfig, genesis common.Hash, head uint64, time uint64) [4]byte {
|
||||
// Calculate the starting checksum from the genesis hash
|
||||
hash := crc32.ChecksumIEEE(genesis[:])
|
||||
|
||||
// Calculate the next fork checksum
|
||||
forksByBlock, forksByTime := gatherForks(config)
|
||||
for _, fork := range forksByBlock {
|
||||
if fork > head {
|
||||
// Checksum the previous hash and nextFork number and return
|
||||
return checksumToBytes(checksumUpdate(hash, fork))
|
||||
}
|
||||
// Fork already passed, checksum the previous hash and the fork number
|
||||
hash = checksumUpdate(hash, fork)
|
||||
}
|
||||
for _, fork := range forksByTime {
|
||||
if fork > time {
|
||||
// Checksum the previous hash and nextFork time and return
|
||||
return checksumToBytes(checksumUpdate(hash, fork))
|
||||
}
|
||||
// Fork already passed, checksum the previous hash and the fork time
|
||||
hash = checksumUpdate(hash, fork)
|
||||
}
|
||||
return checksumToBytes(hash)
|
||||
}
|
||||
|
||||
// NewIDWithChain calculates the Ethereum fork ID from an existing chain instance.
|
||||
func NewIDWithChain(chain Blockchain) ID {
|
||||
head := chain.CurrentHeader()
|
||||
|
@ -89,6 +89,16 @@ func HasAccountTrieNode(db ethdb.KeyValueReader, path []byte, hash common.Hash)
|
||||
return h.hash(data) == hash
|
||||
}
|
||||
|
||||
// ExistsAccountTrieNode checks the presence of the account trie node with the
|
||||
// specified node path, regardless of the node hash.
|
||||
func ExistsAccountTrieNode(db ethdb.KeyValueReader, path []byte) bool {
|
||||
has, err := db.Has(accountTrieNodeKey(path))
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return has
|
||||
}
|
||||
|
||||
// WriteAccountTrieNode writes the provided account trie node into database.
|
||||
func WriteAccountTrieNode(db ethdb.KeyValueWriter, path []byte, node []byte) {
|
||||
if err := db.Put(accountTrieNodeKey(path), node); err != nil {
|
||||
@ -127,6 +137,16 @@ func HasStorageTrieNode(db ethdb.KeyValueReader, accountHash common.Hash, path [
|
||||
return h.hash(data) == hash
|
||||
}
|
||||
|
||||
// ExistsStorageTrieNode checks the presence of the storage trie node with the
|
||||
// specified account hash and node path, regardless of the node hash.
|
||||
func ExistsStorageTrieNode(db ethdb.KeyValueReader, accountHash common.Hash, path []byte) bool {
|
||||
has, err := db.Has(storageTrieNodeKey(accountHash, path))
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return has
|
||||
}
|
||||
|
||||
// WriteStorageTrieNode writes the provided storage trie node into database.
|
||||
func WriteStorageTrieNode(db ethdb.KeyValueWriter, accountHash common.Hash, path []byte, node []byte) {
|
||||
if err := db.Put(storageTrieNodeKey(accountHash, path), node); err != nil {
|
||||
|
@ -220,6 +220,9 @@ func (t *freezerTable) repair() error {
|
||||
}
|
||||
// Ensure the index is a multiple of indexEntrySize bytes
|
||||
if overflow := stat.Size() % indexEntrySize; overflow != 0 {
|
||||
if t.readonly {
|
||||
return fmt.Errorf("index file(path: %s, name: %s) size is not a multiple of %d", t.path, t.name, indexEntrySize)
|
||||
}
|
||||
truncateFreezerFile(t.index, stat.Size()-overflow) // New file can't trigger this path
|
||||
}
|
||||
// Retrieve the file sizes and prepare for truncation
|
||||
@ -278,6 +281,9 @@ func (t *freezerTable) repair() error {
|
||||
// Keep truncating both files until they come in sync
|
||||
contentExp = int64(lastIndex.offset)
|
||||
for contentExp != contentSize {
|
||||
if t.readonly {
|
||||
return fmt.Errorf("freezer table(path: %s, name: %s, num: %d) is corrupted", t.path, t.name, lastIndex.filenum)
|
||||
}
|
||||
verbose = true
|
||||
// Truncate the head file to the last offset pointer
|
||||
if contentExp < contentSize {
|
||||
|
@ -215,7 +215,11 @@ func accountSnapshotKey(hash common.Hash) []byte {
|
||||
|
||||
// storageSnapshotKey = SnapshotStoragePrefix + account hash + storage hash
|
||||
func storageSnapshotKey(accountHash, storageHash common.Hash) []byte {
|
||||
return append(append(SnapshotStoragePrefix, accountHash.Bytes()...), storageHash.Bytes()...)
|
||||
buf := make([]byte, len(SnapshotStoragePrefix)+common.HashLength+common.HashLength)
|
||||
n := copy(buf, SnapshotStoragePrefix)
|
||||
n += copy(buf[n:], accountHash.Bytes())
|
||||
copy(buf[n:], storageHash.Bytes())
|
||||
return buf
|
||||
}
|
||||
|
||||
// storageSnapshotsKey = SnapshotStoragePrefix + account hash + storage hash
|
||||
@ -274,7 +278,11 @@ func accountTrieNodeKey(path []byte) []byte {
|
||||
|
||||
// storageTrieNodeKey = trieNodeStoragePrefix + accountHash + nodePath.
|
||||
func storageTrieNodeKey(accountHash common.Hash, path []byte) []byte {
|
||||
return append(append(trieNodeStoragePrefix, accountHash.Bytes()...), path...)
|
||||
buf := make([]byte, len(trieNodeStoragePrefix)+common.HashLength+len(path))
|
||||
n := copy(buf, trieNodeStoragePrefix)
|
||||
n += copy(buf[n:], accountHash.Bytes())
|
||||
copy(buf[n:], path)
|
||||
return buf
|
||||
}
|
||||
|
||||
// IsLegacyTrieNode reports whether a provided database entry is a legacy trie
|
||||
|
@ -351,8 +351,9 @@ func (vt *verifyTask) sendVerifyRequest(n int) {
|
||||
}
|
||||
|
||||
if n < len(validPeers) && n > 0 {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
rand.Shuffle(len(validPeers), func(i, j int) { validPeers[i], validPeers[j] = validPeers[j], validPeers[i] })
|
||||
// rand.Seed(time.Now().UnixNano())
|
||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
r.Shuffle(len(validPeers), func(i, j int) { validPeers[i], validPeers[j] = validPeers[j], validPeers[i] })
|
||||
} else {
|
||||
n = len(validPeers)
|
||||
}
|
||||
|
@ -19,7 +19,6 @@ package state
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/lru"
|
||||
@ -29,25 +28,14 @@ import (
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
"github.com/ethereum/go-ethereum/trie"
|
||||
"github.com/ethereum/go-ethereum/trie/trienode"
|
||||
exlru "github.com/hashicorp/golang-lru" //ex: external
|
||||
)
|
||||
|
||||
const (
|
||||
// Number of codehash->size associations to keep.
|
||||
codeSizeCacheSize = 100000
|
||||
|
||||
// Number of state trie in cache
|
||||
accountTrieCacheSize = 32
|
||||
|
||||
// Number of storage Trie in cache
|
||||
storageTrieCacheSize = 2000
|
||||
|
||||
// Cache size granted for caching clean code.
|
||||
codeCacheSize = 64 * 1024 * 1024
|
||||
|
||||
purgeInterval = 600
|
||||
|
||||
maxAccountTrieSize = 1024 * 1024
|
||||
)
|
||||
|
||||
// Database wraps access to tries and contract code.
|
||||
@ -73,15 +61,6 @@ type Database interface {
|
||||
// TrieDB returns the underlying trie database for managing trie nodes.
|
||||
TrieDB() *trie.Database
|
||||
|
||||
// Cache the account trie tree
|
||||
CacheAccount(root common.Hash, t Trie)
|
||||
|
||||
// Cache the storage trie tree
|
||||
CacheStorage(addrHash common.Hash, root common.Hash, t Trie)
|
||||
|
||||
// Purge cache
|
||||
Purge()
|
||||
|
||||
// NoTries returns whether the database has tries storage.
|
||||
NoTries() bool
|
||||
}
|
||||
@ -191,53 +170,12 @@ func NewDatabaseWithNodeDB(db ethdb.Database, triedb *trie.Database) Database {
|
||||
}
|
||||
}
|
||||
|
||||
func NewDatabaseWithConfigAndCache(db ethdb.Database, config *trie.Config) Database {
|
||||
atc, _ := exlru.New(accountTrieCacheSize)
|
||||
stc, _ := exlru.New(storageTrieCacheSize)
|
||||
noTries := config != nil && config.NoTries
|
||||
|
||||
database := &cachingDB{
|
||||
disk: db,
|
||||
codeSizeCache: lru.NewCache[common.Hash, int](codeSizeCacheSize),
|
||||
codeCache: lru.NewSizeConstrainedCache[common.Hash, []byte](codeCacheSize),
|
||||
triedb: trie.NewDatabase(db, config),
|
||||
accountTrieCache: atc,
|
||||
storageTrieCache: stc,
|
||||
noTries: noTries,
|
||||
}
|
||||
if !noTries {
|
||||
go database.purgeLoop()
|
||||
}
|
||||
return database
|
||||
}
|
||||
|
||||
type cachingDB struct {
|
||||
disk ethdb.KeyValueStore
|
||||
codeSizeCache *lru.Cache[common.Hash, int]
|
||||
codeCache *lru.SizeConstrainedCache[common.Hash, []byte]
|
||||
triedb *trie.Database
|
||||
accountTrieCache *exlru.Cache
|
||||
storageTrieCache *exlru.Cache
|
||||
noTries bool
|
||||
}
|
||||
|
||||
type triePair struct {
|
||||
root common.Hash
|
||||
trie Trie
|
||||
}
|
||||
|
||||
func (db *cachingDB) purgeLoop() {
|
||||
for {
|
||||
time.Sleep(purgeInterval * time.Second)
|
||||
_, accounts, ok := db.accountTrieCache.GetOldest()
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
tr := accounts.(*trie.SecureTrie).GetRawTrie()
|
||||
if tr.Size() > maxAccountTrieSize {
|
||||
db.Purge()
|
||||
}
|
||||
}
|
||||
disk ethdb.KeyValueStore
|
||||
codeSizeCache *lru.Cache[common.Hash, int]
|
||||
codeCache *lru.SizeConstrainedCache[common.Hash, []byte]
|
||||
triedb *trie.Database
|
||||
noTries bool
|
||||
}
|
||||
|
||||
// OpenTrie opens the main account trie at a specific root hash.
|
||||
@ -245,11 +183,6 @@ func (db *cachingDB) OpenTrie(root common.Hash) (Trie, error) {
|
||||
if db.noTries {
|
||||
return trie.NewEmptyTrie(), nil
|
||||
}
|
||||
if db.accountTrieCache != nil {
|
||||
if tr, exist := db.accountTrieCache.Get(root); exist {
|
||||
return tr.(Trie).(*trie.SecureTrie).Copy(), nil
|
||||
}
|
||||
}
|
||||
tr, err := trie.NewStateTrie(trie.StateTrieID(root), db.triedb)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -262,16 +195,6 @@ func (db *cachingDB) OpenStorageTrie(stateRoot common.Hash, address common.Addre
|
||||
if db.noTries {
|
||||
return trie.NewEmptyTrie(), nil
|
||||
}
|
||||
if db.storageTrieCache != nil {
|
||||
if tries, exist := db.storageTrieCache.Get(crypto.Keccak256Hash(address.Bytes())); exist {
|
||||
triesPairs := tries.([3]*triePair)
|
||||
for _, triePair := range triesPairs {
|
||||
if triePair != nil && triePair.root == root {
|
||||
return triePair.trie.(*trie.SecureTrie).Copy(), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tr, err := trie.NewStateTrie(trie.StorageTrieID(stateRoot, crypto.Keccak256Hash(address.Bytes()), root), db.triedb)
|
||||
if err != nil {
|
||||
@ -280,56 +203,10 @@ func (db *cachingDB) OpenStorageTrie(stateRoot common.Hash, address common.Addre
|
||||
return tr, nil
|
||||
}
|
||||
|
||||
func (db *cachingDB) CacheAccount(root common.Hash, t Trie) {
|
||||
// only the hash scheme trie db support account cache, because the path scheme trie db
|
||||
// account trie bind the previous layer, touch the dirty data when next access. This is
|
||||
// related to the implementation of the Reader interface of pathdb.
|
||||
if db.TrieDB().Scheme() == rawdb.PathScheme {
|
||||
return
|
||||
}
|
||||
if db.accountTrieCache == nil {
|
||||
return
|
||||
}
|
||||
tr := t.(*trie.SecureTrie)
|
||||
db.accountTrieCache.Add(root, tr.ResetCopy())
|
||||
}
|
||||
|
||||
func (db *cachingDB) CacheStorage(addrHash common.Hash, root common.Hash, t Trie) {
|
||||
// ditto `CacheAccount`
|
||||
if db.TrieDB().Scheme() == rawdb.PathScheme {
|
||||
return
|
||||
}
|
||||
if db.storageTrieCache == nil {
|
||||
return
|
||||
}
|
||||
tr := t.(*trie.SecureTrie)
|
||||
if tries, exist := db.storageTrieCache.Get(addrHash); exist {
|
||||
triesArray := tries.([3]*triePair)
|
||||
newTriesArray := [3]*triePair{
|
||||
{root: root, trie: tr.ResetCopy()},
|
||||
triesArray[0],
|
||||
triesArray[1],
|
||||
}
|
||||
db.storageTrieCache.Add(addrHash, newTriesArray)
|
||||
} else {
|
||||
triesArray := [3]*triePair{{root: root, trie: tr.ResetCopy()}, nil, nil}
|
||||
db.storageTrieCache.Add(addrHash, triesArray)
|
||||
}
|
||||
}
|
||||
|
||||
func (db *cachingDB) NoTries() bool {
|
||||
return db.noTries
|
||||
}
|
||||
|
||||
func (db *cachingDB) Purge() {
|
||||
if db.storageTrieCache != nil {
|
||||
db.storageTrieCache.Purge()
|
||||
}
|
||||
if db.accountTrieCache != nil {
|
||||
db.accountTrieCache.Purge()
|
||||
}
|
||||
}
|
||||
|
||||
// CopyTrie returns an independent copy of the given trie.
|
||||
func (db *cachingDB) CopyTrie(t Trie) Trie {
|
||||
if t == nil {
|
||||
|
@ -149,17 +149,17 @@ func (s *stateObject) touch() {
|
||||
func (s *stateObject) getTrie() (Trie, error) {
|
||||
if s.trie == nil {
|
||||
// Try fetching from prefetcher first
|
||||
if s.data.Root != types.EmptyRootHash && s.db.prefetcher != nil {
|
||||
// When the miner is creating the pending state, there is no prefetcher
|
||||
s.trie = s.db.prefetcher.trie(s.addrHash, s.data.Root)
|
||||
}
|
||||
if s.trie == nil {
|
||||
tr, err := s.db.db.OpenStorageTrie(s.db.originalRoot, s.address, s.data.Root)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.trie = tr
|
||||
// if s.data.Root != types.EmptyRootHash && s.db.prefetcher != nil {
|
||||
// When the miner is creating the pending state, there is no prefetcher
|
||||
// s.trie = s.db.prefetcher.trie(s.addrHash, s.data.Root)
|
||||
// }
|
||||
// if s.trie == nil {
|
||||
tr, err := s.db.db.OpenStorageTrie(s.db.originalRoot, s.address, s.data.Root)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.trie = tr
|
||||
// }
|
||||
}
|
||||
return s.trie, nil
|
||||
}
|
||||
@ -464,9 +464,6 @@ func (s *stateObject) commit() (*trienode.NodeSet, error) {
|
||||
return nil, err
|
||||
}
|
||||
s.data.Root = root
|
||||
if s.data.Root != types.EmptyRootHash {
|
||||
s.db.db.CacheStorage(s.addrHash, s.data.Root, s.trie)
|
||||
}
|
||||
|
||||
// Update original account data after commit
|
||||
s.origin = s.data.Copy()
|
||||
|
@ -42,7 +42,12 @@ import (
|
||||
"github.com/ethereum/go-ethereum/trie/triestate"
|
||||
)
|
||||
|
||||
const defaultNumOfSlots = 100
|
||||
const (
|
||||
defaultNumOfSlots = 100
|
||||
// storageDeleteLimit denotes the highest permissible memory allocation
|
||||
// employed for contract storage deletion.
|
||||
storageDeleteLimit = 512 * 1024 * 1024
|
||||
)
|
||||
|
||||
type revision struct {
|
||||
id int
|
||||
@ -1342,63 +1347,134 @@ func (s *StateDB) clearJournalAndRefund() {
|
||||
s.validRevisions = s.validRevisions[:0] // Snapshots can be created without journal entries
|
||||
}
|
||||
|
||||
// deleteStorage iterates the storage trie belongs to the account and mark all
|
||||
// slots inside as deleted.
|
||||
func (s *StateDB) deleteStorage(addr common.Address, addrHash common.Hash, root common.Hash) (bool, map[common.Hash][]byte, *trienode.NodeSet, error) {
|
||||
start := time.Now()
|
||||
// fastDeleteStorage is the function that efficiently deletes the storage trie
|
||||
// of a specific account. It leverages the associated state snapshot for fast
|
||||
// storage iteration and constructs trie node deletion markers by creating
|
||||
// stack trie with iterated slots.
|
||||
func (s *StateDB) fastDeleteStorage(addrHash common.Hash, root common.Hash) (bool, common.StorageSize, map[common.Hash][]byte, *trienode.NodeSet, error) {
|
||||
iter, err := s.snaps.StorageIterator(s.originalRoot, addrHash, common.Hash{})
|
||||
if err != nil {
|
||||
return false, 0, nil, nil, err
|
||||
}
|
||||
defer iter.Release()
|
||||
|
||||
var (
|
||||
size common.StorageSize
|
||||
nodes = trienode.NewNodeSet(addrHash)
|
||||
slots = make(map[common.Hash][]byte)
|
||||
)
|
||||
stack := trie.NewStackTrie(func(owner common.Hash, path []byte, hash common.Hash, blob []byte) {
|
||||
nodes.AddNode(path, trienode.NewDeleted())
|
||||
size += common.StorageSize(len(path))
|
||||
})
|
||||
for iter.Next() {
|
||||
if size > storageDeleteLimit {
|
||||
return true, size, nil, nil, nil
|
||||
}
|
||||
slot := common.CopyBytes(iter.Slot())
|
||||
if err := iter.Error(); err != nil { // error might occur after Slot function
|
||||
return false, 0, nil, nil, err
|
||||
}
|
||||
size += common.StorageSize(common.HashLength + len(slot))
|
||||
slots[iter.Hash()] = slot
|
||||
|
||||
if err := stack.Update(iter.Hash().Bytes(), slot); err != nil {
|
||||
return false, 0, nil, nil, err
|
||||
}
|
||||
}
|
||||
if err := iter.Error(); err != nil { // error might occur during iteration
|
||||
return false, 0, nil, nil, err
|
||||
}
|
||||
if stack.Hash() != root {
|
||||
return false, 0, nil, nil, fmt.Errorf("snapshot is not matched, exp %x, got %x", root, stack.Hash())
|
||||
}
|
||||
return false, size, slots, nodes, nil
|
||||
}
|
||||
|
||||
// slowDeleteStorage serves as a less-efficient alternative to "fastDeleteStorage,"
|
||||
// employed when the associated state snapshot is not available. It iterates the
|
||||
// storage slots along with all internal trie nodes via trie directly.
|
||||
func (s *StateDB) slowDeleteStorage(addr common.Address, addrHash common.Hash, root common.Hash) (bool, common.StorageSize, map[common.Hash][]byte, *trienode.NodeSet, error) {
|
||||
tr, err := s.db.OpenStorageTrie(s.originalRoot, addr, root)
|
||||
if err != nil {
|
||||
return false, nil, nil, fmt.Errorf("failed to open storage trie, err: %w", err)
|
||||
return false, 0, nil, nil, fmt.Errorf("failed to open storage trie, err: %w", err)
|
||||
}
|
||||
// skip deleting storages for EmptyTrie
|
||||
if _, ok := tr.(*trie.EmptyTrie); ok {
|
||||
return false, nil, nil, nil
|
||||
return false, 0, nil, nil, nil
|
||||
}
|
||||
it, err := tr.NodeIterator(nil)
|
||||
if err != nil {
|
||||
return false, nil, nil, fmt.Errorf("failed to open storage iterator, err: %w", err)
|
||||
return false, 0, nil, nil, fmt.Errorf("failed to open storage iterator, err: %w", err)
|
||||
}
|
||||
var (
|
||||
set = trienode.NewNodeSet(addrHash)
|
||||
slots = make(map[common.Hash][]byte)
|
||||
stateSize common.StorageSize
|
||||
nodeSize common.StorageSize
|
||||
size common.StorageSize
|
||||
nodes = trienode.NewNodeSet(addrHash)
|
||||
slots = make(map[common.Hash][]byte)
|
||||
)
|
||||
for it.Next(true) {
|
||||
// arbitrary stateSize limit, make it configurable
|
||||
if stateSize+nodeSize > 512*1024*1024 {
|
||||
log.Info("Skip large storage deletion", "address", addr.Hex(), "states", stateSize, "nodes", nodeSize)
|
||||
if metrics.EnabledExpensive {
|
||||
slotDeletionSkip.Inc(1)
|
||||
}
|
||||
return true, nil, nil, nil
|
||||
if size > storageDeleteLimit {
|
||||
return true, size, nil, nil, nil
|
||||
}
|
||||
if it.Leaf() {
|
||||
slots[common.BytesToHash(it.LeafKey())] = common.CopyBytes(it.LeafBlob())
|
||||
stateSize += common.StorageSize(common.HashLength + len(it.LeafBlob()))
|
||||
size += common.StorageSize(common.HashLength + len(it.LeafBlob()))
|
||||
continue
|
||||
}
|
||||
if it.Hash() == (common.Hash{}) {
|
||||
continue
|
||||
}
|
||||
nodeSize += common.StorageSize(len(it.Path()))
|
||||
set.AddNode(it.Path(), trienode.NewDeleted())
|
||||
size += common.StorageSize(len(it.Path()))
|
||||
nodes.AddNode(it.Path(), trienode.NewDeleted())
|
||||
}
|
||||
if err := it.Error(); err != nil {
|
||||
return false, 0, nil, nil, err
|
||||
}
|
||||
return false, size, slots, nodes, nil
|
||||
}
|
||||
|
||||
// deleteStorage is designed to delete the storage trie of a designated account.
|
||||
// It could potentially be terminated if the storage size is excessively large,
|
||||
// potentially leading to an out-of-memory panic. The function will make an attempt
|
||||
// to utilize an efficient strategy if the associated state snapshot is reachable;
|
||||
// otherwise, it will resort to a less-efficient approach.
|
||||
func (s *StateDB) deleteStorage(addr common.Address, addrHash common.Hash, root common.Hash) (bool, map[common.Hash][]byte, *trienode.NodeSet, error) {
|
||||
var (
|
||||
start = time.Now()
|
||||
err error
|
||||
aborted bool
|
||||
size common.StorageSize
|
||||
slots map[common.Hash][]byte
|
||||
nodes *trienode.NodeSet
|
||||
)
|
||||
// The fast approach can be failed if the snapshot is not fully
|
||||
// generated, or it's internally corrupted. Fallback to the slow
|
||||
// one just in case.
|
||||
if s.snap != nil {
|
||||
aborted, size, slots, nodes, err = s.fastDeleteStorage(addrHash, root)
|
||||
}
|
||||
if s.snap == nil || err != nil {
|
||||
aborted, size, slots, nodes, err = s.slowDeleteStorage(addr, addrHash, root)
|
||||
}
|
||||
if err != nil {
|
||||
return false, nil, nil, err
|
||||
}
|
||||
if metrics.EnabledExpensive {
|
||||
if int64(len(slots)) > slotDeletionMaxCount.Value() {
|
||||
slotDeletionMaxCount.Update(int64(len(slots)))
|
||||
if aborted {
|
||||
slotDeletionSkip.Inc(1)
|
||||
}
|
||||
if int64(stateSize+nodeSize) > slotDeletionMaxSize.Value() {
|
||||
slotDeletionMaxSize.Update(int64(stateSize + nodeSize))
|
||||
n := int64(len(slots))
|
||||
if n > slotDeletionMaxCount.Value() {
|
||||
slotDeletionMaxCount.Update(n)
|
||||
}
|
||||
if int64(size) > slotDeletionMaxSize.Value() {
|
||||
slotDeletionMaxSize.Update(int64(size))
|
||||
}
|
||||
slotDeletionTimer.UpdateSince(start)
|
||||
slotDeletionCount.Mark(int64(len(slots)))
|
||||
slotDeletionSize.Mark(int64(stateSize + nodeSize))
|
||||
slotDeletionCount.Mark(n)
|
||||
slotDeletionSize.Mark(int64(size))
|
||||
}
|
||||
return false, slots, set, nil
|
||||
return aborted, slots, nodes, nil
|
||||
}
|
||||
|
||||
// handleDestruction processes all destruction markers and deletes the account
|
||||
@ -1615,9 +1691,6 @@ func (s *StateDB) Commit(block uint64, failPostCommitFunc func(), postCommitFunc
|
||||
return err
|
||||
}
|
||||
}
|
||||
if root != types.EmptyRootHash {
|
||||
s.db.CacheAccount(root, s.trie)
|
||||
}
|
||||
|
||||
origin := s.originalRoot
|
||||
if origin == (common.Hash{}) {
|
||||
@ -1732,6 +1805,7 @@ func (s *StateDB) Commit(block uint64, failPostCommitFunc func(), postCommitFunc
|
||||
go commmitTrie()
|
||||
} else {
|
||||
defer s.StopPrefetcher()
|
||||
commitFuncs = append(commitFuncs, commmitTrie)
|
||||
}
|
||||
commitRes := make(chan error, len(commitFuncs))
|
||||
for _, f := range commitFuncs {
|
||||
@ -1747,10 +1821,6 @@ func (s *StateDB) Commit(block uint64, failPostCommitFunc func(), postCommitFunc
|
||||
return common.Hash{}, nil, r
|
||||
}
|
||||
}
|
||||
// commitFuncs[1] and commmitTrie concurrent map `storages` iteration and map write
|
||||
if err := commmitTrie(); err != nil {
|
||||
return common.Hash{}, nil, err
|
||||
}
|
||||
|
||||
root := s.stateRoot
|
||||
if s.pipeCommit {
|
||||
|
@ -31,10 +31,12 @@ import (
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||
"github.com/ethereum/go-ethereum/core/state/snapshot"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
"github.com/ethereum/go-ethereum/trie"
|
||||
"github.com/ethereum/go-ethereum/trie/triedb/pathdb"
|
||||
"github.com/ethereum/go-ethereum/trie/triestate"
|
||||
)
|
||||
|
||||
@ -179,16 +181,28 @@ func (test *stateTest) run() bool {
|
||||
storageList = append(storageList, copy2DSet(states.Storages))
|
||||
}
|
||||
disk = rawdb.NewMemoryDatabase()
|
||||
tdb = trie.NewDatabase(disk, &trie.Config{OnCommit: onCommit})
|
||||
tdb = trie.NewDatabase(disk, &trie.Config{OnCommit: onCommit, PathDB: pathdb.Defaults})
|
||||
sdb = NewDatabaseWithNodeDB(disk, tdb)
|
||||
byzantium = rand.Intn(2) == 0
|
||||
)
|
||||
defer disk.Close()
|
||||
defer tdb.Close()
|
||||
|
||||
var snaps *snapshot.Tree
|
||||
if rand.Intn(3) == 0 {
|
||||
snaps, _ = snapshot.New(snapshot.Config{
|
||||
CacheSize: 1,
|
||||
Recovery: false,
|
||||
NoBuild: false,
|
||||
AsyncBuild: false,
|
||||
}, disk, tdb, types.EmptyRootHash, 128, false)
|
||||
}
|
||||
for i, actions := range test.actions {
|
||||
root := types.EmptyRootHash
|
||||
if i != 0 {
|
||||
root = roots[len(roots)-1]
|
||||
}
|
||||
state, err := New(root, sdb, nil)
|
||||
state, err := New(root, sdb, snaps)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -365,8 +379,7 @@ func (test *stateTest) verify(root common.Hash, next common.Hash, db *trie.Datab
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO(Nathan): enable this case after enabling pbss
|
||||
func testStateChanges(t *testing.T) {
|
||||
func TestStateChanges(t *testing.T) {
|
||||
config := &quick.Config{MaxCount: 1000}
|
||||
err := quick.Check((*stateTest).run, config)
|
||||
if cerr, ok := err.(*quick.CheckError); ok {
|
||||
|
@ -37,6 +37,8 @@ import (
|
||||
"github.com/ethereum/go-ethereum/trie"
|
||||
"github.com/ethereum/go-ethereum/trie/triedb/hashdb"
|
||||
"github.com/ethereum/go-ethereum/trie/triedb/pathdb"
|
||||
"github.com/ethereum/go-ethereum/trie/trienode"
|
||||
"github.com/holiman/uint256"
|
||||
)
|
||||
|
||||
// Tests that updating a state trie does not leak any database writes prior to
|
||||
@ -1112,3 +1114,57 @@ func TestResetObject(t *testing.T) {
|
||||
t.Fatalf("Unexpected storage slot value %v", slot)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeleteStorage(t *testing.T) {
|
||||
var (
|
||||
disk = rawdb.NewMemoryDatabase()
|
||||
tdb = trie.NewDatabase(disk, nil)
|
||||
db = NewDatabaseWithNodeDB(disk, tdb)
|
||||
snaps, _ = snapshot.New(snapshot.Config{CacheSize: 10}, disk, tdb, types.EmptyRootHash, 128, false)
|
||||
state, _ = New(types.EmptyRootHash, db, snaps)
|
||||
addr = common.HexToAddress("0x1")
|
||||
)
|
||||
// Initialize account and populate storage
|
||||
state.SetBalance(addr, big.NewInt(1))
|
||||
state.CreateAccount(addr)
|
||||
for i := 0; i < 1000; i++ {
|
||||
slot := common.Hash(uint256.NewInt(uint64(i)).Bytes32())
|
||||
value := common.Hash(uint256.NewInt(uint64(10 * i)).Bytes32())
|
||||
state.SetState(addr, slot, value)
|
||||
}
|
||||
root, _, _ := state.Commit(0, nil)
|
||||
// Init phase done, create two states, one with snap and one without
|
||||
fastState, _ := New(root, db, snaps)
|
||||
slowState, _ := New(root, db, nil)
|
||||
|
||||
obj := fastState.GetOrNewStateObject(addr)
|
||||
storageRoot := obj.data.Root
|
||||
|
||||
_, _, fastNodes, err := fastState.deleteStorage(addr, crypto.Keccak256Hash(addr[:]), storageRoot)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, _, slowNodes, err := slowState.deleteStorage(addr, crypto.Keccak256Hash(addr[:]), storageRoot)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
check := func(set *trienode.NodeSet) string {
|
||||
var a []string
|
||||
set.ForEachWithOrder(func(path string, n *trienode.Node) {
|
||||
if n.Hash != (common.Hash{}) {
|
||||
t.Fatal("delete should have empty hashes")
|
||||
}
|
||||
if len(n.Blob) != 0 {
|
||||
t.Fatal("delete should have have empty blobs")
|
||||
}
|
||||
a = append(a, fmt.Sprintf("%x", path))
|
||||
})
|
||||
return strings.Join(a, ",")
|
||||
}
|
||||
slowRes := check(slowNodes)
|
||||
fastRes := check(fastNodes)
|
||||
if slowRes != fastRes {
|
||||
t.Fatalf("difference found:\nfast: %v\nslow: %v\n", fastRes, slowRes)
|
||||
}
|
||||
}
|
||||
|
@ -319,11 +319,11 @@ func (p *TxPool) Pending(enforceTips bool) map[common.Address][]*LazyTransaction
|
||||
// SubscribeNewTxsEvent registers a subscription of NewTxsEvent and starts sending
|
||||
// events to the given channel.
|
||||
func (p *TxPool) SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event.Subscription {
|
||||
subs := make([]event.Subscription, len(p.subpools))
|
||||
for i, subpool := range p.subpools {
|
||||
subs := make([]event.Subscription, 0, len(p.subpools))
|
||||
for _, subpool := range p.subpools {
|
||||
sub := subpool.SubscribeTransactions(ch)
|
||||
if sub != nil { // sub will be nil when subpool have been shut down
|
||||
subs[i] = sub
|
||||
subs = append(subs, sub)
|
||||
}
|
||||
}
|
||||
return p.subs.Track(event.JoinSubscriptions(subs...))
|
||||
@ -332,11 +332,11 @@ func (p *TxPool) SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event.Subscrip
|
||||
// SubscribeNewTxsEvent registers a subscription of NewTxsEvent and starts sending
|
||||
// events to the given channel.
|
||||
func (p *TxPool) SubscribeReannoTxsEvent(ch chan<- core.ReannoTxsEvent) event.Subscription {
|
||||
subs := make([]event.Subscription, len(p.subpools))
|
||||
for i, subpool := range p.subpools {
|
||||
subs := make([]event.Subscription, 0, len(p.subpools))
|
||||
for _, subpool := range p.subpools {
|
||||
sub := subpool.SubscribeReannoTxsEvent(ch)
|
||||
if sub != nil { // sub will be nil when subpool have been shut down
|
||||
subs[i] = sub
|
||||
subs = append(subs, sub)
|
||||
}
|
||||
}
|
||||
return p.subs.Track(event.JoinSubscriptions(subs...))
|
||||
|
@ -63,6 +63,7 @@ import (
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
"github.com/ethereum/go-ethereum/trie/triedb/pathdb"
|
||||
)
|
||||
|
||||
// Config contains the configuration options of the ETH protocol.
|
||||
@ -129,7 +130,9 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
|
||||
log.Warn("Sanitizing invalid miner gas price", "provided", config.Miner.GasPrice, "updated", ethconfig.Defaults.Miner.GasPrice)
|
||||
config.Miner.GasPrice = new(big.Int).Set(ethconfig.Defaults.Miner.GasPrice)
|
||||
}
|
||||
if config.NoPruning && config.TrieDirtyCache > 0 {
|
||||
// Redistribute memory allocation from in-memory trie node garbage collection
|
||||
// to other caches when an archive node is requested.
|
||||
if config.StateScheme == rawdb.HashScheme && config.NoPruning && config.TrieDirtyCache > 0 {
|
||||
if config.SnapshotCache > 0 {
|
||||
config.TrieCleanCache += config.TrieDirtyCache * 3 / 5
|
||||
config.SnapshotCache += config.TrieDirtyCache * 2 / 5
|
||||
@ -138,6 +141,13 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
|
||||
}
|
||||
config.TrieDirtyCache = 0
|
||||
}
|
||||
// Optimize memory distribution by reallocating surplus allowance from the
|
||||
// dirty cache to the clean cache.
|
||||
if config.StateScheme == rawdb.PathScheme && config.TrieDirtyCache > pathdb.MaxDirtyBufferSize/1024/1024 {
|
||||
log.Info("Capped dirty cache size", "provided", common.StorageSize(config.TrieDirtyCache)*1024*1024, "adjusted", common.StorageSize(pathdb.MaxDirtyBufferSize))
|
||||
log.Info("Clean cache size", "provided", common.StorageSize(config.TrieCleanCache)*1024*1024)
|
||||
config.TrieDirtyCache = pathdb.MaxDirtyBufferSize / 1024 / 1024
|
||||
}
|
||||
log.Info("Allocated trie memory caches", "clean", common.StorageSize(config.TrieCleanCache)*1024*1024, "dirty", common.StorageSize(config.TrieDirtyCache)*1024*1024)
|
||||
|
||||
// Assemble the Ethereum object
|
||||
@ -215,6 +225,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
|
||||
Preimages: config.Preimages,
|
||||
StateHistory: config.StateHistory,
|
||||
StateScheme: config.StateScheme,
|
||||
PathSyncFlush: config.PathSyncFlush,
|
||||
}
|
||||
)
|
||||
bcOps := make([]core.BlockChainOption, 0)
|
||||
|
@ -123,6 +123,7 @@ type Config struct {
|
||||
TransactionHistory uint64 `toml:",omitempty"` // The maximum number of blocks from head whose tx indices are reserved.
|
||||
StateHistory uint64 `toml:",omitempty"` // The maximum number of blocks from head whose state histories are reserved.
|
||||
StateScheme string `toml:",omitempty"` // State scheme used to store ethereum state and merkle trie nodes on top
|
||||
PathSyncFlush bool `toml:",omitempty"` // State scheme used to store ethereum state and merkle trie nodes on top
|
||||
|
||||
// RequiredBlocks is a set of block number -> hash mappings which must be in the
|
||||
// canonical chain of all remote peers. Setting the option makes geth verify the
|
||||
|
@ -45,7 +45,6 @@ import (
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/metrics"
|
||||
"github.com/ethereum/go-ethereum/p2p"
|
||||
"github.com/ethereum/go-ethereum/trie/triedb/pathdb"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -979,7 +978,9 @@ func (h *handler) voteBroadcastLoop() {
|
||||
// sync is finished.
|
||||
func (h *handler) enableSyncedFeatures() {
|
||||
h.acceptTxs.Store(true)
|
||||
if h.chain.TrieDB().Scheme() == rawdb.PathScheme {
|
||||
h.chain.TrieDB().SetBufferSize(pathdb.DefaultBufferSize)
|
||||
}
|
||||
// In the bsc scenario, pathdb.MaxDirtyBufferSize (256MB) will be used.
|
||||
// The performance is better than DefaultDirtyBufferSize (64MB).
|
||||
//if h.chain.TrieDB().Scheme() == rawdb.PathScheme {
|
||||
// h.chain.TrieDB().SetBufferSize(pathdb.DefaultDirtyBufferSize)
|
||||
//}
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import (
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||
"github.com/ethereum/go-ethereum/core/txpool"
|
||||
"github.com/ethereum/go-ethereum/metrics"
|
||||
"github.com/ethereum/go-ethereum/p2p"
|
||||
@ -95,11 +96,15 @@ type TxPool interface {
|
||||
|
||||
// MakeProtocols constructs the P2P protocol definitions for `eth`.
|
||||
func MakeProtocols(backend Backend, network uint64, dnsdisc enode.Iterator) []p2p.Protocol {
|
||||
protocols := make([]p2p.Protocol, len(ProtocolVersions))
|
||||
for i, version := range ProtocolVersions {
|
||||
protocols := make([]p2p.Protocol, 0, len(ProtocolVersions))
|
||||
for _, version := range ProtocolVersions {
|
||||
version := version // Closure
|
||||
|
||||
protocols[i] = p2p.Protocol{
|
||||
// Path scheme does not support GetNodeData, don't advertise eth66 on it
|
||||
if version <= ETH66 && backend.Chain().TrieDB().Scheme() == rawdb.PathScheme {
|
||||
continue
|
||||
}
|
||||
protocols = append(protocols, p2p.Protocol{
|
||||
Name: ProtocolName,
|
||||
Version: version,
|
||||
Length: protocolLengths[version],
|
||||
@ -119,7 +124,7 @@ func MakeProtocols(backend Backend, network uint64, dnsdisc enode.Iterator) []p2
|
||||
},
|
||||
Attributes: []enr.Entry{currentENREntry(backend.Chain())},
|
||||
DialCandidates: dnsdisc,
|
||||
}
|
||||
})
|
||||
}
|
||||
return protocols
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
package trust
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"crypto/rand"
|
||||
|
||||
"github.com/ethereum/go-ethereum/p2p"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
|
@ -175,8 +175,8 @@ func (eth *Ethereum) hashState(ctx context.Context, block *types.Block, reexec u
|
||||
parent = root
|
||||
}
|
||||
if report {
|
||||
nodes, imgs := triedb.Size()
|
||||
log.Info("Historical state regenerated", "block", current.NumberU64(), "elapsed", time.Since(start), "nodes", nodes, "preimages", imgs)
|
||||
diff, nodes, immutablenodes, imgs := triedb.Size()
|
||||
log.Info("Historical state regenerated", "block", current.NumberU64(), "elapsed", time.Since(start), "layer", diff, "nodes", nodes, "immutablenodes", immutablenodes, "preimages", imgs)
|
||||
}
|
||||
return statedb, func() { triedb.Dereference(block.Root()) }, nil
|
||||
}
|
||||
|
@ -372,8 +372,8 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed
|
||||
// if the relevant state is available in disk.
|
||||
var preferDisk bool
|
||||
if statedb != nil {
|
||||
s1, s2 := statedb.Database().TrieDB().Size()
|
||||
preferDisk = s1+s2 > defaultTracechainMemLimit
|
||||
s1, s2, s3, s4 := statedb.Database().TrieDB().Size()
|
||||
preferDisk = s1+s2+s3+s4 > defaultTracechainMemLimit
|
||||
}
|
||||
statedb, release, err = api.backend.StateAtBlock(ctx, block, reexec, statedb, false, preferDisk)
|
||||
if err != nil {
|
||||
|
111
go.mod
111
go.mod
@ -1,6 +1,6 @@
|
||||
module github.com/ethereum/go-ethereum
|
||||
|
||||
go 1.19
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.3.0
|
||||
@ -13,14 +13,14 @@ require (
|
||||
github.com/btcsuite/btcd/btcec/v2 v2.3.2
|
||||
github.com/cespare/cp v1.1.1
|
||||
github.com/cloudflare/cloudflare-go v0.14.0
|
||||
github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811
|
||||
github.com/cockroachdb/pebble v0.0.0-20230906160148-46873a6a7a06
|
||||
github.com/cometbft/cometbft v0.37.0
|
||||
github.com/consensys/gnark-crypto v0.10.0
|
||||
github.com/crate-crypto/go-kzg-4844 v0.3.0
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/deckarep/golang-set/v2 v2.1.0
|
||||
github.com/docker/docker v20.10.19+incompatible
|
||||
github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3
|
||||
github.com/docker/docker v20.10.24+incompatible
|
||||
github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127
|
||||
github.com/ethereum/c-kzg-4844 v0.3.1
|
||||
github.com/fatih/color v1.13.0
|
||||
github.com/fatih/structs v1.1.0
|
||||
@ -32,10 +32,10 @@ require (
|
||||
github.com/go-stack/stack v1.8.1
|
||||
github.com/gofrs/flock v0.8.1
|
||||
github.com/golang-jwt/jwt/v4 v4.3.0
|
||||
github.com/golang/protobuf v1.5.2
|
||||
github.com/golang/protobuf v1.5.3
|
||||
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb
|
||||
github.com/google/gofuzz v1.2.0
|
||||
github.com/google/pprof v0.0.0-20230207041349-798e818bf904
|
||||
github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/gorilla/websocket v1.5.0
|
||||
github.com/graph-gophers/graphql-go v1.3.0
|
||||
@ -44,7 +44,7 @@ require (
|
||||
github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7
|
||||
github.com/holiman/bloomfilter/v2 v2.0.3
|
||||
github.com/holiman/uint256 v1.2.3
|
||||
github.com/huin/goupnp v1.0.3
|
||||
github.com/huin/goupnp v1.3.0
|
||||
github.com/influxdata/influxdb-client-go/v2 v2.4.0
|
||||
github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c
|
||||
github.com/jackpal/go-nat-pmp v1.0.2
|
||||
@ -54,7 +54,7 @@ require (
|
||||
github.com/kylelemons/godebug v1.1.0
|
||||
github.com/logrusorgru/aurora v2.0.3+incompatible
|
||||
github.com/mattn/go-colorable v0.1.13
|
||||
github.com/mattn/go-isatty v0.0.16
|
||||
github.com/mattn/go-isatty v0.0.18
|
||||
github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416
|
||||
github.com/olekukonko/tablewriter v0.0.5
|
||||
github.com/panjf2000/ants/v2 v2.4.5
|
||||
@ -62,11 +62,11 @@ require (
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/prometheus/tsdb v0.10.0
|
||||
github.com/protolambda/bls12-381-util v0.0.0-20220416220906-d8552aa452c7
|
||||
github.com/prysmaticlabs/prysm/v4 v4.0.2
|
||||
github.com/prysmaticlabs/prysm/v4 v4.0.8
|
||||
github.com/rs/cors v1.8.2
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible
|
||||
github.com/status-im/keycard-go v0.2.0
|
||||
github.com/stretchr/testify v1.8.1
|
||||
github.com/stretchr/testify v1.8.2
|
||||
github.com/supranational/blst v0.3.11
|
||||
github.com/syndtr/goleveldb v1.0.1
|
||||
github.com/tendermint/go-amino v0.14.1
|
||||
@ -74,15 +74,15 @@ require (
|
||||
github.com/tendermint/tendermint v0.31.15
|
||||
github.com/tidwall/wal v1.1.7
|
||||
github.com/tyler-smith/go-bip39 v1.1.0
|
||||
github.com/urfave/cli/v2 v2.24.1
|
||||
github.com/urfave/cli/v2 v2.25.7
|
||||
github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4 v1.1.3
|
||||
github.com/willf/bitset v1.1.3
|
||||
go.uber.org/automaxprocs v1.5.2
|
||||
golang.org/x/crypto v0.9.0
|
||||
golang.org/x/crypto v0.12.0
|
||||
golang.org/x/exp v0.0.0-20230810033253-352e893a4cad
|
||||
golang.org/x/sync v0.3.0
|
||||
golang.org/x/sys v0.9.0
|
||||
golang.org/x/text v0.9.0
|
||||
golang.org/x/sys v0.11.0
|
||||
golang.org/x/text v0.12.0
|
||||
golang.org/x/time v0.3.0
|
||||
golang.org/x/tools v0.9.1
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
||||
@ -94,7 +94,7 @@ require (
|
||||
contrib.go.opencensus.io/exporter/jaeger v0.2.1 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v0.21.1 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v0.8.3 // indirect
|
||||
github.com/BurntSushi/toml v1.2.1 // indirect
|
||||
github.com/BurntSushi/toml v1.3.2 // indirect
|
||||
github.com/DataDog/zstd v1.5.2 // indirect
|
||||
github.com/aristanetworks/goarista v0.0.0-20200805130819-fd197cf57d96 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.0.2 // indirect
|
||||
@ -108,12 +108,12 @@ require (
|
||||
github.com/bits-and-blooms/bitset v1.7.0 // indirect
|
||||
github.com/cespare/xxhash v1.1.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/chzyer/readline v1.5.0 // indirect
|
||||
github.com/chzyer/readline v1.5.1 // indirect
|
||||
github.com/cockroachdb/errors v1.9.1 // indirect
|
||||
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect
|
||||
github.com/cockroachdb/redact v1.1.3 // indirect
|
||||
github.com/consensys/bavard v0.1.13 // indirect
|
||||
github.com/containerd/cgroups v1.0.4 // indirect
|
||||
github.com/containerd/cgroups v1.1.0 // indirect
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
|
||||
github.com/cosmos/gogoproto v1.4.1 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
|
||||
@ -137,11 +137,11 @@ require (
|
||||
github.com/go-logfmt/logfmt v0.5.1 // indirect
|
||||
github.com/go-logr/logr v1.2.3 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/go-playground/locales v0.14.0 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.0 // indirect
|
||||
github.com/go-playground/validator/v10 v10.11.1 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.13.0 // indirect
|
||||
github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
|
||||
github.com/godbus/dbus/v5 v5.1.0 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
@ -153,10 +153,10 @@ require (
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.0.1 // indirect
|
||||
github.com/gtank/merlin v0.1.1 // indirect
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.1 // indirect
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.2 // indirect
|
||||
github.com/herumi/bls-eth-go-binary v0.0.0-20210917013441-d37c07cfda4e // indirect
|
||||
github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097 // indirect
|
||||
github.com/ipfs/go-cid v0.3.2 // indirect
|
||||
github.com/ipfs/go-cid v0.4.1 // indirect
|
||||
github.com/ipfs/go-log/v2 v2.5.1 // indirect
|
||||
github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect
|
||||
github.com/jmhodges/levigo v1.0.0 // indirect
|
||||
@ -164,17 +164,17 @@ require (
|
||||
github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a // indirect
|
||||
github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213 // indirect
|
||||
github.com/kilic/bls12-381 v0.1.0 // indirect
|
||||
github.com/klauspost/compress v1.15.15 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.1 // indirect
|
||||
github.com/koron/go-ssdp v0.0.3 // indirect
|
||||
github.com/klauspost/compress v1.16.4 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
|
||||
github.com/koron/go-ssdp v0.0.4 // indirect
|
||||
github.com/kr/pretty v0.3.1 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/leodido/go-urn v1.2.1 // indirect
|
||||
github.com/leodido/go-urn v1.2.3 // indirect
|
||||
github.com/libp2p/go-buffer-pool v0.1.0 // indirect
|
||||
github.com/libp2p/go-cidranger v1.1.0 // indirect
|
||||
github.com/libp2p/go-flow-metrics v0.1.0 // indirect
|
||||
github.com/libp2p/go-libp2p v0.26.2 // indirect
|
||||
github.com/libp2p/go-libp2p-asn-util v0.2.0 // indirect
|
||||
github.com/libp2p/go-libp2p v0.27.8 // indirect
|
||||
github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect
|
||||
github.com/libp2p/go-libp2p-pubsub v0.9.3 // indirect
|
||||
github.com/libp2p/go-mplex v0.7.0 // indirect
|
||||
github.com/libp2p/go-msgio v0.3.0 // indirect
|
||||
@ -187,7 +187,7 @@ require (
|
||||
github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect
|
||||
github.com/mattn/go-runewidth v0.0.14 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||
github.com/miekg/dns v1.1.50 // indirect
|
||||
github.com/miekg/dns v1.1.53 // indirect
|
||||
github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect
|
||||
github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect
|
||||
github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 // indirect
|
||||
@ -203,16 +203,16 @@ require (
|
||||
github.com/mr-tron/base58 v1.2.0 // indirect
|
||||
github.com/multiformats/go-base32 v0.1.0 // indirect
|
||||
github.com/multiformats/go-base36 v0.2.0 // indirect
|
||||
github.com/multiformats/go-multiaddr v0.8.0 // indirect
|
||||
github.com/multiformats/go-multiaddr v0.9.0 // indirect
|
||||
github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect
|
||||
github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect
|
||||
github.com/multiformats/go-multibase v0.1.1 // indirect
|
||||
github.com/multiformats/go-multicodec v0.7.0 // indirect
|
||||
github.com/multiformats/go-multibase v0.2.0 // indirect
|
||||
github.com/multiformats/go-multicodec v0.8.1 // indirect
|
||||
github.com/multiformats/go-multihash v0.2.1 // indirect
|
||||
github.com/multiformats/go-multistream v0.4.1 // indirect
|
||||
github.com/multiformats/go-varint v0.0.7 // indirect
|
||||
github.com/naoina/go-stringutil v0.1.0 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.5.1 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.9.2 // indirect
|
||||
github.com/opencontainers/runtime-spec v1.0.2 // indirect
|
||||
github.com/opentracing/opentracing-go v1.2.0 // indirect
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
|
||||
@ -221,24 +221,24 @@ require (
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/client_golang v1.14.0 // indirect
|
||||
github.com/prometheus/client_model v0.3.0 // indirect
|
||||
github.com/prometheus/common v0.39.0 // indirect
|
||||
github.com/prometheus/common v0.42.0 // indirect
|
||||
github.com/prometheus/procfs v0.9.0 // indirect
|
||||
github.com/prometheus/prom2json v1.3.0 // indirect
|
||||
github.com/prysmaticlabs/eth2-types v0.0.0-20210303084904-c9735a06829d // indirect
|
||||
github.com/prysmaticlabs/fastssz v0.0.0-20220628121656-93dfe28febab // indirect
|
||||
github.com/prysmaticlabs/fastssz v0.0.0-20221107182844-78142813af44 // indirect
|
||||
github.com/prysmaticlabs/go-bitfield v0.0.0-20210809151128-385d8c5e3fb7 // indirect
|
||||
github.com/prysmaticlabs/gohashtree v0.0.3-alpha // indirect
|
||||
github.com/prysmaticlabs/prombbolt v0.0.0-20210126082820-9b7adba6db7c // indirect
|
||||
github.com/prysmaticlabs/prysm v0.0.0-20220124113610-e26cde5e091b // indirect
|
||||
github.com/quic-go/qpack v0.4.0 // indirect
|
||||
github.com/quic-go/qtls-go1-19 v0.2.1 // indirect
|
||||
github.com/quic-go/qtls-go1-20 v0.1.1 // indirect
|
||||
github.com/quic-go/qtls-go1-19 v0.3.3 // indirect
|
||||
github.com/quic-go/qtls-go1-20 v0.2.3 // indirect
|
||||
github.com/quic-go/quic-go v0.33.0 // indirect
|
||||
github.com/quic-go/webtransport-go v0.5.2 // indirect
|
||||
github.com/r3labs/sse v0.0.0-20210224172625-26fe804710bc // indirect
|
||||
github.com/r3labs/sse/v2 v2.10.0 // indirect
|
||||
github.com/raulk/go-watchdog v1.3.0 // indirect
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
|
||||
github.com/rivo/uniseg v0.4.3 // indirect
|
||||
github.com/rivo/uniseg v0.4.4 // indirect
|
||||
github.com/rogpeppe/go-internal v1.9.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/sasha-s/go-deadlock v0.3.1 // indirect
|
||||
@ -250,9 +250,9 @@ require (
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.0 // indirect
|
||||
github.com/tidwall/tinylru v1.1.0 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.11 // indirect
|
||||
github.com/tklauser/numcpus v0.6.0 // indirect
|
||||
github.com/trailofbits/go-mutexasserts v0.0.0-20200708152505-19999e7d3cef // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.12 // indirect
|
||||
github.com/tklauser/numcpus v0.6.1 // indirect
|
||||
github.com/trailofbits/go-mutexasserts v0.0.0-20230328101604-8cdbc5f3d279 // indirect
|
||||
github.com/uber/jaeger-client-go v2.25.0+incompatible // indirect
|
||||
github.com/wealdtech/go-bytesutil v1.1.1 // indirect
|
||||
github.com/wealdtech/go-eth2-types/v2 v2.5.2 // indirect
|
||||
@ -262,31 +262,30 @@ require (
|
||||
go.etcd.io/bbolt v1.3.7 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.uber.org/atomic v1.10.0 // indirect
|
||||
go.uber.org/dig v1.15.0 // indirect
|
||||
go.uber.org/fx v1.18.2 // indirect
|
||||
go.uber.org/multierr v1.8.0 // indirect
|
||||
go.uber.org/dig v1.16.1 // indirect
|
||||
go.uber.org/fx v1.19.2 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.24.0 // indirect
|
||||
golang.org/x/mod v0.11.0 // indirect
|
||||
golang.org/x/net v0.10.0 // indirect
|
||||
golang.org/x/oauth2 v0.3.0 // indirect
|
||||
golang.org/x/term v0.8.0 // indirect
|
||||
google.golang.org/api v0.34.0 // indirect
|
||||
golang.org/x/oauth2 v0.5.0 // indirect
|
||||
golang.org/x/term v0.11.0 // indirect
|
||||
google.golang.org/api v0.44.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect
|
||||
google.golang.org/grpc v1.52.0 // indirect
|
||||
google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8 // indirect
|
||||
google.golang.org/grpc v1.53.0 // indirect
|
||||
google.golang.org/protobuf v1.30.0 // indirect
|
||||
gopkg.in/cenkalti/backoff.v1 v1.1.0 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
k8s.io/apimachinery v0.18.3 // indirect
|
||||
k8s.io/client-go v0.18.3 // indirect
|
||||
k8s.io/klog v1.0.0 // indirect
|
||||
k8s.io/apimachinery v0.20.0 // indirect
|
||||
k8s.io/client-go v0.20.0 // indirect
|
||||
k8s.io/klog/v2 v2.80.0 // indirect
|
||||
k8s.io/utils v0.0.0-20200520001619-278ece378a50 // indirect
|
||||
k8s.io/utils v0.0.0-20201110183641-67b214c5f920 // indirect
|
||||
lukechampine.com/blake3 v1.1.7 // indirect
|
||||
nhooyr.io/websocket v1.8.7 // indirect
|
||||
rsc.io/tmplfunc v0.0.3 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v3 v3.0.0 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.2 // indirect
|
||||
sigs.k8s.io/yaml v1.2.0 // indirect
|
||||
)
|
||||
|
||||
|
312
go.sum
312
go.sum
@ -18,6 +18,11 @@ cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKV
|
||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
||||
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
||||
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
||||
cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
|
||||
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
|
||||
cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
|
||||
cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
|
||||
cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
@ -57,19 +62,28 @@ github.com/Azure/azure-sdk-for-go/sdk/internal v0.8.3/go.mod h1:KLF4gFr6DcKFZwSu
|
||||
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.3.0 h1:Px2UA+2RvSSvv+RvJNuUB6n7rs5Wsel4dXLe90Um2n4=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.3.0/go.mod h1:tPaiy8S5bQ+S5sOiDlINkp7+Ef339+Nz5L5XO+cnOHo=
|
||||
github.com/Azure/azure-storage-blob-go v0.7.0/go.mod h1:f9YQKtsG1nMisotuTPpO0tjNuEjKRYAcJU8/ydDI++4=
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
|
||||
github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A=
|
||||
github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
|
||||
github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g=
|
||||
github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
|
||||
github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
|
||||
github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
|
||||
github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
|
||||
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=
|
||||
github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
|
||||
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg=
|
||||
github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno=
|
||||
@ -83,7 +97,9 @@ github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb0
|
||||
github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0=
|
||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||
github.com/Shopify/sarama v1.26.1/go.mod h1:NbSGBSSndYaIhRcBtY9V0U7AyH+x71bG668AuWys/yU=
|
||||
@ -124,6 +140,7 @@ github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
|
||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||
github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
|
||||
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
|
||||
@ -208,32 +225,36 @@ github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj
|
||||
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/logex v1.2.0 h1:+eqR0HfOetur4tgnC8ftU5imRnhi4te+BadWS95c5AM=
|
||||
github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY=
|
||||
github.com/chzyer/logex v1.2.1 h1:XHDu3E6q+gdHgsdTPH6ImJMIp436vR6MPtH8gP05QzM=
|
||||
github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/readline v1.5.0 h1:lSwwFrbNviGePhkewF1az4oLmcwqCZijQ2/Wi3BGHAI=
|
||||
github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic=
|
||||
github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI=
|
||||
github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/chzyer/test v0.0.0-20210722231415-061457976a23 h1:dZ0/VyGgQdVGAss6Ju0dt5P0QltE0SFY5Woh6hbIfiQ=
|
||||
github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/chzyer/test v1.0.0 h1:p3BQDXSxOhOG0P9z6/hGnII4LGiEPOYBhs8asl/fC04=
|
||||
github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8=
|
||||
github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs=
|
||||
github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudflare/cloudflare-go v0.14.0 h1:gFqGlGl/5f9UGXAaKapCGUfaTCgRKKnzu2VvzMZlOFA=
|
||||
github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
||||
github.com/cockroachdb/datadriven v1.0.2 h1:H9MtNqVoVhvd9nCBwOyDjUEdZCREqbIdCJD93PBm/jA=
|
||||
github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU=
|
||||
github.com/cockroachdb/datadriven v1.0.3-0.20230801171734-e384cf455877 h1:1MLK4YpFtIEo3ZtMA5C795Wtv5VuUnrXX7mQG+aHg6o=
|
||||
github.com/cockroachdb/errors v1.9.1 h1:yFVvsI0VxmRShfawbt/laCIDy/mtTqqnvoNgiy5bEV8=
|
||||
github.com/cockroachdb/errors v1.9.1/go.mod h1:2sxOtL2WIc096WSZqZ5h8fa17rdDq9HZOZLBCor4mBk=
|
||||
github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs=
|
||||
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE=
|
||||
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs=
|
||||
github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 h1:ytcWPaNPhNoGMWEhDvS3zToKcDpRsLuRolQJBVGdozk=
|
||||
github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811/go.mod h1:Nb5lgvnQ2+oGlE/EyZy4+2/CxRh9KfvCXnag1vtpxVM=
|
||||
github.com/cockroachdb/pebble v0.0.0-20230906160148-46873a6a7a06 h1:T+Np/xtzIjYM/P5NAw0e2Rf1FGvzDau1h54MKvx8G7w=
|
||||
github.com/cockroachdb/pebble v0.0.0-20230906160148-46873a6a7a06/go.mod h1:bynZ3gvVyhlvjLI7PT6dmZ7g76xzJ7HpxfjgkzCGz6s=
|
||||
github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5wfSQ=
|
||||
github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg=
|
||||
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
|
||||
@ -246,8 +267,8 @@ github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1
|
||||
github.com/consensys/gnark-crypto v0.10.0 h1:zRh22SR7o4K35SoNqouS9J/TKHTyU2QWaj5ldehyXtA=
|
||||
github.com/consensys/gnark-crypto v0.10.0/go.mod h1:Iq/P3HHl0ElSjsg2E1gsMwhAyxnxoKK5nVyZKd+/KhU=
|
||||
github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE=
|
||||
github.com/containerd/cgroups v1.0.4 h1:jN/mbWBEaz+T1pi5OFtnkQ+8qnmEbAr1Oo1FRm5B0dA=
|
||||
github.com/containerd/cgroups v1.0.4/go.mod h1:nLNQtsF7Sl2HxNebu77i1R0oDlhiTG+kO4JTrUzo6IA=
|
||||
github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
|
||||
github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw=
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
@ -321,16 +342,17 @@ github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/
|
||||
github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI=
|
||||
github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
|
||||
github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v20.10.19+incompatible h1:lzEmjivyNHFHMNAFLXORMBXyGIhw/UP4DvJwvyKYq64=
|
||||
github.com/docker/docker v20.10.19+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v20.10.24+incompatible h1:Ugvxm7a8+Gz6vqQYQQ2W7GYq5EUPaAiuPgIfVyI3dYE=
|
||||
github.com/docker/docker v20.10.24+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
|
||||
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
|
||||
github.com/dop251/goja v0.0.0-20211011172007-d99e4b8cbf48/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk=
|
||||
github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk=
|
||||
github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3 h1:+3HCtB74++ClLy8GgjUQYeC8R4ILzVcIe8+5edAJJnE=
|
||||
github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4=
|
||||
github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127 h1:qwcF+vdFrvPSEUDSX5RVoRccG8a5DhOdWdQ4zN62zzo=
|
||||
github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4=
|
||||
github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y=
|
||||
github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM=
|
||||
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
@ -353,6 +375,7 @@ github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4s
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
|
||||
@ -363,6 +386,7 @@ github.com/ethereum/c-kzg-4844 v0.3.1 h1:sR65+68+WdnMKxseNWxSJuAv2tsUrihTpVBTfM/
|
||||
github.com/ethereum/c-kzg-4844 v0.3.1/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0=
|
||||
github.com/ethereum/go-ethereum v1.10.13/go.mod h1:W3yfrFyL9C1pHcwY5hmRHVDaorTiQxhYBkKyu5mEDHw=
|
||||
github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
|
||||
@ -381,6 +405,7 @@ github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI
|
||||
github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ=
|
||||
github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag=
|
||||
github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
|
||||
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
||||
github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=
|
||||
github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
|
||||
github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk=
|
||||
@ -451,22 +476,28 @@ github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiU
|
||||
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
|
||||
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
|
||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
|
||||
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
|
||||
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
|
||||
github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
|
||||
github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
|
||||
github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
|
||||
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
|
||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
||||
github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU=
|
||||
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
|
||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
|
||||
github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho=
|
||||
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
|
||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
|
||||
github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ=
|
||||
github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU=
|
||||
github.com/go-playground/validator/v10 v10.13.0 h1:cFRQdfaSMCOSfGCCLB20MHvuoHb/s5G8L5pu2ppK5AQ=
|
||||
github.com/go-playground/validator/v10 v10.13.0/go.mod h1:dwu7+CG8/CtBiJFZDz4e+5Upb6OLw04gtBYw0mcG/z4=
|
||||
github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU=
|
||||
github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg=
|
||||
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
@ -475,8 +506,9 @@ github.com/go-stack/stack v1.6.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw=
|
||||
github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
|
||||
github.com/go-yaml/yaml v2.1.0+incompatible h1:RYi2hDdss1u4YE7GwixGzWwVo47T8UQwnTLB6vQiq+o=
|
||||
github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0=
|
||||
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0=
|
||||
@ -511,8 +543,8 @@ github.com/golang-jwt/jwt/v4 v4.3.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzw
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
||||
github.com/golang/gddo v0.0.0-20200528160355-8d077c1d8f4c/go.mod h1:sam69Hju0uq+5uvLJUMDlsKlQ21Vrs1Kd/1YFPNYdOU=
|
||||
github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ=
|
||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
@ -529,6 +561,7 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt
|
||||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
||||
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
|
||||
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
|
||||
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
||||
github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
@ -547,8 +580,10 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
@ -589,6 +624,7 @@ github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF
|
||||
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/orderedcode v0.0.1 h1:UzfcAexk9Vhv8+9pNOgRu41f16lHq725vPwnSeiG/Us=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
@ -597,8 +633,13 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf
|
||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20230207041349-798e818bf904 h1:4/hN5RUoecvl+RmJRE2YxKWtnnQls6rQjjW5oV7qg2U=
|
||||
github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg=
|
||||
github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b h1:Qcx5LM0fSiks9uCyFZwDBUasd3lxd1RM0GYpL+Li5o4=
|
||||
github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
|
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
@ -614,6 +655,7 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
|
||||
github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU=
|
||||
@ -672,8 +714,8 @@ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
|
||||
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs=
|
||||
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.1 h1:5pv5N1lT1fjLg2VQ5KWc7kmucp2x/kvFOnxuVTqZ6x4=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.1/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.2 h1:Dwmkdr5Nc/oBiXgJS3CDHNhJtIHkuZ3DZF5twqnfBdU=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.2/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
|
||||
github.com/hashicorp/hcl v0.0.0-20170914154624-68e816d1c783/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
||||
@ -694,12 +736,13 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO
|
||||
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
|
||||
github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc=
|
||||
github.com/huin/goupnp v1.0.2/go.mod h1:0dxJBVBHqTMjIUMkESDTNgOOx/Mw5wYIfyFmdzSamkM=
|
||||
github.com/huin/goupnp v1.0.3 h1:N8No57ls+MnjlB+JPiCVSOyy/ot7MJTqlo7rn+NYSqQ=
|
||||
github.com/huin/goupnp v1.0.3/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y=
|
||||
github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc=
|
||||
github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8=
|
||||
github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o=
|
||||
github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE=
|
||||
github.com/ianlancetaylor/cgosymbolizer v0.0.0-20200424224625-be1b05b0b279/go.mod h1:a5aratAVTWyz+nJMmDsN8O4XTfaLfdAsB1ysCmZX5Bw=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=
|
||||
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA=
|
||||
@ -727,8 +770,8 @@ github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUP
|
||||
github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj6+M=
|
||||
github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog=
|
||||
github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I=
|
||||
github.com/ipfs/go-cid v0.3.2 h1:OGgOd+JCFM+y1DjWPmVH+2/4POtpDzwcr7VgnB7mZXc=
|
||||
github.com/ipfs/go-cid v0.3.2/go.mod h1:gQ8pKqT/sUxGY+tIwy1RPpAojYu7jAyCp5Tz1svoupw=
|
||||
github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s=
|
||||
github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk=
|
||||
github.com/ipfs/go-datastore v0.4.1/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA=
|
||||
github.com/ipfs/go-datastore v0.4.4/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA=
|
||||
github.com/ipfs/go-datastore v0.5.0/go.mod h1:9zhEApYMTl17C8YDp7JmU7sQZi2/wqiYh73hakZ90Bk=
|
||||
@ -830,15 +873,15 @@ github.com/klauspost/compress v1.9.8/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0
|
||||
github.com/klauspost/compress v1.10.1/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw=
|
||||
github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4=
|
||||
github.com/klauspost/compress v1.16.4 h1:91KN02FnsOYhuunwU4ssRe8lc2JosWmizWa91B5v1PU=
|
||||
github.com/klauspost/compress v1.16.4/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||
github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.1 h1:U33DW0aiEj633gHYw3LoDNfkDiYnE5Q8M/TKJn2f2jI=
|
||||
github.com/klauspost/cpuid/v2 v2.2.1/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
|
||||
github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk=
|
||||
github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
|
||||
github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg=
|
||||
github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||
github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||
@ -848,8 +891,8 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxv
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk=
|
||||
github.com/koron/go-ssdp v0.0.2/go.mod h1:XoLfkAiA2KeZsYh4DbHxD7h3nR2AZNqVQOa+LJuqPYs=
|
||||
github.com/koron/go-ssdp v0.0.3 h1:JivLMY45N76b4p/vsWGOKewBQu6uf39y8l+AQ7sDKx8=
|
||||
github.com/koron/go-ssdp v0.0.3/go.mod h1:b2MxI6yh02pKrsyNoQUsk4+YNikaGhe4894J+Q5lDvA=
|
||||
github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0=
|
||||
github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
@ -859,6 +902,7 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
@ -870,8 +914,8 @@ github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL
|
||||
github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c=
|
||||
github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8=
|
||||
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
||||
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
|
||||
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
||||
github.com/leodido/go-urn v1.2.3 h1:6BE2vPT0lqoz3fmOesHZiaiFh7889ssCo2GMvLCfiuA=
|
||||
github.com/leodido/go-urn v1.2.3/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw=
|
||||
github.com/libp2p/go-addr-util v0.0.2/go.mod h1:Ecd6Fb3yIuLzq4bD7VcywcVSBtefcAwnUISBM3WG15E=
|
||||
@ -891,11 +935,11 @@ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS
|
||||
github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM=
|
||||
github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro=
|
||||
github.com/libp2p/go-libp2p v0.17.0/go.mod h1:Fkin50rsGdv5mm5BshBUtPRZknt9esfmYXBOYcwOTgw=
|
||||
github.com/libp2p/go-libp2p v0.26.2 h1:eHEoW/696FP7/6DxOvcrKfTD6Bi0DExxiMSZUJxswA0=
|
||||
github.com/libp2p/go-libp2p v0.26.2/go.mod h1:x75BN32YbwuY0Awm2Uix4d4KOz+/4piInkp4Wr3yOo8=
|
||||
github.com/libp2p/go-libp2p v0.27.8 h1:IX5x/4yKwyPQeVS2AXHZ3J4YATM9oHBGH1gBc23jBAI=
|
||||
github.com/libp2p/go-libp2p v0.27.8/go.mod h1:eCFFtd0s5i/EVKR7+5Ki8bM7qwkNW3TPTTSSW9sz8NE=
|
||||
github.com/libp2p/go-libp2p-asn-util v0.1.0/go.mod h1:wu+AnM9Ii2KgO5jMmS1rz9dvzTdj8BXqsPR9HR0XB7I=
|
||||
github.com/libp2p/go-libp2p-asn-util v0.2.0 h1:rg3+Os8jbnO5DxkC7K/Utdi+DkY3q/d1/1q+8WeNAsw=
|
||||
github.com/libp2p/go-libp2p-asn-util v0.2.0/go.mod h1:WoaWxbHKBymSN41hWSq/lGKJEca7TNm58+gGJi2WsLI=
|
||||
github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s=
|
||||
github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w=
|
||||
github.com/libp2p/go-libp2p-autonat v0.7.0/go.mod h1:uPvPn6J7cN+LCfFwW5tpOYvAz5NvPTc4iBamTV/WDMg=
|
||||
github.com/libp2p/go-libp2p-blankhost v0.2.0/go.mod h1:eduNKXGTioTuQAUcZ5epXi9vMl+t4d8ugUBRQ4SqaNQ=
|
||||
github.com/libp2p/go-libp2p-blankhost v0.3.0/go.mod h1:urPC+7U01nCGgJ3ZsV8jdwTp6Ji9ID0dMTvq+aJ+nZU=
|
||||
@ -1053,8 +1097,9 @@ github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOA
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98=
|
||||
github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
@ -1073,8 +1118,8 @@ github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/le
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
|
||||
github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4=
|
||||
github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA=
|
||||
github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
|
||||
github.com/miekg/dns v1.1.53 h1:ZBkuHr5dxHtB1caEOlZTLPo7D3L3TWckgUUs/RHfDxw=
|
||||
github.com/miekg/dns v1.1.53/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY=
|
||||
github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8=
|
||||
github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms=
|
||||
github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc=
|
||||
@ -1150,8 +1195,8 @@ github.com/multiformats/go-multiaddr v0.3.0/go.mod h1:dF9kph9wfJ+3VLAaeBqo9Of8x4
|
||||
github.com/multiformats/go-multiaddr v0.3.1/go.mod h1:uPbspcUPd5AfaP6ql3ujFY+QWzmBD8uLLL4bXW0XfGc=
|
||||
github.com/multiformats/go-multiaddr v0.3.3/go.mod h1:lCKNGP1EQ1eZ35Za2wlqnabm9xQkib3fyB+nZXHLag0=
|
||||
github.com/multiformats/go-multiaddr v0.4.0/go.mod h1:YcpyLH8ZPudLxQlemYBPhSm0/oCXAT8Z4mzFpyoPyRc=
|
||||
github.com/multiformats/go-multiaddr v0.8.0 h1:aqjksEcqK+iD/Foe1RRFsGZh8+XFiGo7FgUCZlpv3LU=
|
||||
github.com/multiformats/go-multiaddr v0.8.0/go.mod h1:Fs50eBDWvZu+l3/9S6xAE7ZYj6yhxlvaVZjakWN7xRs=
|
||||
github.com/multiformats/go-multiaddr v0.9.0 h1:3h4V1LHIk5w4hJHekMKWALPXErDfz/sggzwC/NcqbDQ=
|
||||
github.com/multiformats/go-multiaddr v0.9.0/go.mod h1:mI67Lb1EeTOYb8GQfL/7wpIZwc46ElrvzhYnoJOmTT0=
|
||||
github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A=
|
||||
github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk=
|
||||
github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E=
|
||||
@ -1163,10 +1208,10 @@ github.com/multiformats/go-multiaddr-net v0.1.5/go.mod h1:ilNnaM9HbmVFqsb/qcNysj
|
||||
github.com/multiformats/go-multiaddr-net v0.2.0/go.mod h1:gGdH3UXny6U3cKKYCvpXI5rnK7YaOIEOPVDI9tsJbEA=
|
||||
github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs=
|
||||
github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc=
|
||||
github.com/multiformats/go-multibase v0.1.1 h1:3ASCDsuLX8+j4kx58qnJ4YFq/JWTJpCyDW27ztsVTOI=
|
||||
github.com/multiformats/go-multibase v0.1.1/go.mod h1:ZEjHE+IsUrgp5mhlEAYjMtZwK1k4haNkcaPg9aoe1a8=
|
||||
github.com/multiformats/go-multicodec v0.7.0 h1:rTUjGOwjlhGHbEMbPoSUJowG1spZTVsITRANCjKTUAQ=
|
||||
github.com/multiformats/go-multicodec v0.7.0/go.mod h1:GUC8upxSBE4oG+q3kWZRw/+6yC1BqO550bjhWsJbZlw=
|
||||
github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g=
|
||||
github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk=
|
||||
github.com/multiformats/go-multicodec v0.8.1 h1:ycepHwavHafh3grIbR1jIXnKCsFm0fqsfEOsJ8NtKE8=
|
||||
github.com/multiformats/go-multicodec v0.8.1/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k=
|
||||
github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U=
|
||||
github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po=
|
||||
github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew=
|
||||
@ -1226,8 +1271,8 @@ github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9k
|
||||
github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E=
|
||||
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
|
||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||
github.com/onsi/ginkgo/v2 v2.5.1 h1:auzK7OI497k6x4OvWq+TKAcpcSAlod0doAH72oIN0Jw=
|
||||
github.com/onsi/ginkgo/v2 v2.5.1/go.mod h1:63DOGlLAH8+REH8jUGdL3YpCpu7JODesutUjdENfUAc=
|
||||
github.com/onsi/ginkgo/v2 v2.9.2 h1:BA2GMJOtfGAfagzYtrAlufIP0lq6QERkFmHLMLPwFSU=
|
||||
github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts=
|
||||
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
@ -1235,7 +1280,7 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J
|
||||
github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY=
|
||||
github.com/onsi/gomega v1.24.0 h1:+0glovB9Jd6z3VR+ScSwQqXVTIfJcGA9UBM8yzQxhqg=
|
||||
github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E=
|
||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
|
||||
github.com/openconfig/gnmi v0.0.0-20190823184014-89b2bf29312c/go.mod h1:t+O9It+LKzfOAhKTT5O0ehDix+MTqbtT0T9t+7zzOvc=
|
||||
github.com/openconfig/reference v0.0.0-20190727015836-8dfd928c9696/go.mod h1:ym2A+zigScwkSEb/cVQB0/ZMpU3rqiH6X7WRRsxgOGw=
|
||||
@ -1328,8 +1373,8 @@ github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16
|
||||
github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
|
||||
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
|
||||
github.com/prometheus/common v0.30.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
|
||||
github.com/prometheus/common v0.39.0 h1:oOyhkDq05hPZKItWVBkJ6g6AtGxi+fy7F4JvUV8uhsI=
|
||||
github.com/prometheus/common v0.39.0/go.mod h1:6XBZ7lYdLCbkAVhwRsWTZn+IN5AB9F/NXd5w0BbEX0Y=
|
||||
github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM=
|
||||
github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc=
|
||||
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
@ -1352,8 +1397,8 @@ github.com/protolambda/bls12-381-util v0.0.0-20220416220906-d8552aa452c7 h1:cZC+
|
||||
github.com/protolambda/bls12-381-util v0.0.0-20220416220906-d8552aa452c7/go.mod h1:IToEjHuttnUzwZI5KBSM/LOOW3qLbbrHOEfp3SbECGY=
|
||||
github.com/prysmaticlabs/eth2-types v0.0.0-20210303084904-c9735a06829d h1:1dN7YAqMN3oAJ0LceWcyv/U4jHLh+5urnSnr4br6zg4=
|
||||
github.com/prysmaticlabs/eth2-types v0.0.0-20210303084904-c9735a06829d/go.mod h1:kOmQ/zdobQf7HUohDTifDNFEZfNaSCIY5fkONPL+dWU=
|
||||
github.com/prysmaticlabs/fastssz v0.0.0-20220628121656-93dfe28febab h1:Y3PcvUrnneMWLuypZpwPz8P70/DQsz6KgV9JveKpyZs=
|
||||
github.com/prysmaticlabs/fastssz v0.0.0-20220628121656-93dfe28febab/go.mod h1:MA5zShstUwCQaE9faGHgCGvEWUbG87p4SAXINhmCkvg=
|
||||
github.com/prysmaticlabs/fastssz v0.0.0-20221107182844-78142813af44 h1:c3p3UzV4vFA7xaCDphnDWOjpxcadrQ26l5b+ypsvyxo=
|
||||
github.com/prysmaticlabs/fastssz v0.0.0-20221107182844-78142813af44/go.mod h1:MA5zShstUwCQaE9faGHgCGvEWUbG87p4SAXINhmCkvg=
|
||||
github.com/prysmaticlabs/go-bitfield v0.0.0-20210108222456-8e92c3709aa0/go.mod h1:hCwmef+4qXWjv0jLDbQdWnL0Ol7cS7/lCSS26WR+u6s=
|
||||
github.com/prysmaticlabs/go-bitfield v0.0.0-20210809151128-385d8c5e3fb7 h1:0tVE4tdWQK9ZpYygoV7+vS6QkDvQVySboMVEIxBJmXw=
|
||||
github.com/prysmaticlabs/go-bitfield v0.0.0-20210809151128-385d8c5e3fb7/go.mod h1:wmuf/mdK4VMD+jA9ThwcUKjg3a2XWM9cVfFYjDyY4j4=
|
||||
@ -1367,20 +1412,21 @@ github.com/prysmaticlabs/protoc-gen-go-cast v0.0.0-20211014160335-757fae4f38c6/g
|
||||
github.com/prysmaticlabs/protoc-gen-go-cast v0.0.0-20230228205207-28762a7b9294 h1:q9wE0ZZRdTUAAeyFP/w0SwBEnCqlVy2+on6X2/e+eAU=
|
||||
github.com/prysmaticlabs/prysm v0.0.0-20220124113610-e26cde5e091b h1:XULhE6PdzCYSe5OEVFhuixNqL3mYVOq/3M+SUGnKr1Y=
|
||||
github.com/prysmaticlabs/prysm v0.0.0-20220124113610-e26cde5e091b/go.mod h1:bFzDfaj4xtisRey9RPkMJOhOJVwmtH3FChV7NPKV1Nk=
|
||||
github.com/prysmaticlabs/prysm/v4 v4.0.2 h1:OU1Vw/eDp9BdWUBtO9z/mT5llIvBDLuNYKKTVyFpxrc=
|
||||
github.com/prysmaticlabs/prysm/v4 v4.0.2/go.mod h1:e7Xf3nTpWEzmoOpcORzjQ56ogT4uTC7BN8DTrcFD7cQ=
|
||||
github.com/prysmaticlabs/prysm/v4 v4.0.8 h1:F6Rt5gpaxbW50aP63jMmSXE16JW42HaEzUT55L9laaM=
|
||||
github.com/prysmaticlabs/prysm/v4 v4.0.8/go.mod h1:m01QCZ2qwuTpUQRfYj5gMkvEP+j6mPcMydG8mNcnYDY=
|
||||
github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
|
||||
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
|
||||
github.com/quic-go/qtls-go1-19 v0.2.1 h1:aJcKNMkH5ASEJB9FXNeZCyTEIHU1J7MmHyz1Q1TSG1A=
|
||||
github.com/quic-go/qtls-go1-19 v0.2.1/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI=
|
||||
github.com/quic-go/qtls-go1-20 v0.1.1 h1:KbChDlg82d3IHqaj2bn6GfKRj84Per2VGf5XV3wSwQk=
|
||||
github.com/quic-go/qtls-go1-20 v0.1.1/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM=
|
||||
github.com/quic-go/qtls-go1-19 v0.3.3 h1:wznEHvJwd+2X3PqftRha0SUKmGsnb6dfArMhy9PeJVE=
|
||||
github.com/quic-go/qtls-go1-19 v0.3.3/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI=
|
||||
github.com/quic-go/qtls-go1-20 v0.2.3 h1:m575dovXn1y2ATOb1XrRFcrv0F+EQmlowTkoraNkDPI=
|
||||
github.com/quic-go/qtls-go1-20 v0.2.3/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM=
|
||||
github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y0=
|
||||
github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA=
|
||||
github.com/quic-go/webtransport-go v0.5.2 h1:GA6Bl6oZY+g/flt00Pnu0XtivSD8vukOu3lYhJjnGEk=
|
||||
github.com/quic-go/webtransport-go v0.5.2/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU=
|
||||
github.com/r3labs/sse v0.0.0-20210224172625-26fe804710bc h1:zAsgcP8MhzAbhMnB1QQ2O7ZhWYVGYSR2iVcjzQuPV+o=
|
||||
github.com/r3labs/sse v0.0.0-20210224172625-26fe804710bc/go.mod h1:S8xSOnV3CgpNrWd0GQ/OoQfMtlg2uPRSuTzcSGrzwK8=
|
||||
github.com/r3labs/sse/v2 v2.10.0 h1:hFEkLLFY4LDifoHdiCN/LlGBAdVJYsANaLqNYa1l/v0=
|
||||
github.com/r3labs/sse/v2 v2.10.0/go.mod h1:Igau6Whc+F17QUgML1fYe1VPZzTV6EMCnYktEmkNJ7I=
|
||||
github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk=
|
||||
github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
@ -1389,14 +1435,13 @@ github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5X
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.4.3 h1:utMvzDsuh3suAEnhH0RdHmoPbU648o6CvXxTx4SBMOw=
|
||||
github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
|
||||
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||
github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
@ -1493,7 +1538,9 @@ github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3
|
||||
github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
@ -1504,8 +1551,9 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||
github.com/supranational/blst v0.3.5/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw=
|
||||
github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4=
|
||||
@ -1536,15 +1584,16 @@ github.com/tidwall/wal v1.1.7/go.mod h1:r6lR1j27W9EPalgHiB7zLJDYu3mzW5BQP5KrzBpY
|
||||
github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
|
||||
github.com/tjfoc/gmsm v1.3.0/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w=
|
||||
github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI=
|
||||
github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM=
|
||||
github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI=
|
||||
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
|
||||
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
|
||||
github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM=
|
||||
github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms=
|
||||
github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4=
|
||||
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
|
||||
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/trailofbits/go-mutexasserts v0.0.0-20200708152505-19999e7d3cef h1:8LRP+2JK8piIUU16ZDgWDXwjJcuJNTtCzadjTZj8Jf0=
|
||||
github.com/trailofbits/go-mutexasserts v0.0.0-20200708152505-19999e7d3cef/go.mod h1:+SV/613m53DNAmlXPTWGZhIyt4E/qDvn9g/lOPRiy0A=
|
||||
github.com/trailofbits/go-mutexasserts v0.0.0-20230328101604-8cdbc5f3d279 h1:+LynomhWB+14Plp/bOONEAZCtvCZk4leRbTvNzNVkL0=
|
||||
github.com/trailofbits/go-mutexasserts v0.0.0-20230328101604-8cdbc5f3d279/go.mod h1:GA3+Mq3kt3tYAfM0WZCu7ofy+GW9PuGysHfhr+6JX7s=
|
||||
github.com/twitchtv/twirp v7.1.0+incompatible/go.mod h1:RRJoFSAmTEh2weEqWtpPE3vFK5YBhA6bqp2l1kfCC5A=
|
||||
github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs=
|
||||
github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8=
|
||||
@ -1561,8 +1610,8 @@ github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijb
|
||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
||||
github.com/urfave/cli/v2 v2.24.1 h1:/QYYr7g0EhwXEML8jO+8OYt5trPnLHS0p3mrgExJ5NU=
|
||||
github.com/urfave/cli/v2 v2.24.1/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc=
|
||||
github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs=
|
||||
github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ=
|
||||
github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w=
|
||||
@ -1629,6 +1678,7 @@ go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
|
||||
go.opencensus.io v0.22.6/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
|
||||
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
|
||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||
@ -1645,10 +1695,10 @@ go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0
|
||||
go.uber.org/automaxprocs v1.3.0/go.mod h1:9CWT6lKIep8U41DDaPiH6eFscnTyjfTANNQNx6LrIcA=
|
||||
go.uber.org/automaxprocs v1.5.2 h1:2LxUOGiR3O6tw8ui5sZa2LAaHnsviZdVOUZw4fvbnME=
|
||||
go.uber.org/automaxprocs v1.5.2/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0=
|
||||
go.uber.org/dig v1.15.0 h1:vq3YWr8zRj1eFGC7Gvf907hE0eRjPTZ1d3xHadD6liE=
|
||||
go.uber.org/dig v1.15.0/go.mod h1:pKHs0wMynzL6brANhB2hLMro+zalv1osARTviTcqHLM=
|
||||
go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU=
|
||||
go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY=
|
||||
go.uber.org/dig v1.16.1 h1:+alNIBsl0qfY0j6epRubp/9obgtrObRAc5aD+6jbWY8=
|
||||
go.uber.org/dig v1.16.1/go.mod h1:557JTAUZT5bUK0SvCwikmLPPtdQhfvLYtO5tJgQSbnk=
|
||||
go.uber.org/fx v1.19.2 h1:SyFgYQFr1Wl0AYstE8vyYIzP4bFz2URrScjwC4cwUvY=
|
||||
go.uber.org/fx v1.19.2/go.mod h1:43G1VcqSzbIv77y00p1DRAsyZS8WdzuYdhZXmEUkMyQ=
|
||||
go.uber.org/goleak v1.0.0/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
||||
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
||||
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
||||
@ -1658,8 +1708,8 @@ go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+
|
||||
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
|
||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||
go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
|
||||
go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8=
|
||||
go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
@ -1697,6 +1747,7 @@ golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPh
|
||||
golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
@ -1704,9 +1755,8 @@ golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5
|
||||
golang.org/x/crypto v0.0.0-20210813211128-0a44fdfbc16e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
|
||||
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
|
||||
golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
|
||||
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
|
||||
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
@ -1748,6 +1798,8 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
@ -1803,7 +1855,9 @@ golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81R
|
||||
golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
@ -1813,7 +1867,6 @@ golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT
|
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
@ -1831,10 +1884,16 @@ golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4Iltr
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.3.0 h1:6l90koy8/LaBLmLu8jpHeHexzMwEita0zFfYlggy2F8=
|
||||
golang.org/x/oauth2 v0.3.0/go.mod h1:rQrIauxkUhJ6CuwEXwymO2/eh4xz2ZWF1nBkcxS+tGk=
|
||||
golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s=
|
||||
golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I=
|
||||
golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw=
|
||||
golang.org/x/sync v0.0.0-20170517211232-f52d1811a629/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@ -1878,6 +1937,7 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -1922,12 +1982,17 @@ golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -1944,7 +2009,6 @@ golang.org/x/sys v0.0.0-20210511113859-b0526f3d8744/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@ -1960,14 +2024,15 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
|
||||
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0=
|
||||
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
|
||||
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@ -1979,13 +2044,14 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
|
||||
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/time v0.0.0-20170424234030-8be79e1e0910/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
||||
@ -2011,6 +2077,7 @@ golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBn
|
||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
@ -2052,13 +2119,16 @@ golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc
|
||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
|
||||
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo=
|
||||
@ -2094,8 +2164,14 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M
|
||||
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
||||
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
||||
google.golang.org/api v0.34.0 h1:k40adF3uR+6x/+hO5Dh4ZFUqFp67vxvbpafFiJxl10A=
|
||||
google.golang.org/api v0.34.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
|
||||
google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
|
||||
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
|
||||
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
|
||||
google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
|
||||
google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
|
||||
google.golang.org/api v0.44.0 h1:URs6qR1lAxDsqWITsQXI4ZkGiYJ5dHtRNiCpfs2OeKA=
|
||||
google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
@ -2149,7 +2225,16 @@ google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6D
|
||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210207032614-bba0dbe2a9ea/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
|
||||
google.golang.org/genproto v0.0.0-20210426193834-eac7f76ac494/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=
|
||||
google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24=
|
||||
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w=
|
||||
@ -2179,14 +2264,16 @@ google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM
|
||||
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
|
||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
|
||||
google.golang.org/grpc v1.35.0-dev.0.20201218190559-666aea1fb34c/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
||||
google.golang.org/grpc v1.52.0 h1:kd48UiU7EHsV4rnLyOJRuP/Il/UHE7gdDAQ+SZI7nZk=
|
||||
google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY=
|
||||
google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc=
|
||||
google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw=
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.0.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
@ -2203,8 +2290,8 @@ google.golang.org/protobuf v1.25.1-0.20201208041424-160c7477e0e8/go.mod h1:hFxJC
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8 h1:KR8+MyP7/qOlV+8Af01LtjL04bu7on42eVsxT4EyBQk=
|
||||
google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
||||
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/bsm/ratelimit.v1 v1.0.0-20160220154919-db14e161995a/go.mod h1:KF9sEfUPAXdG8Oev9e99iLGnl2uJMjc5B+4y3O7x610=
|
||||
gopkg.in/cenkalti/backoff.v1 v1.1.0 h1:Arh75ttbsvlpVA7WtVpH4u9h6Zl46xuptxqLxPiSo4Y=
|
||||
@ -2274,25 +2361,31 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las=
|
||||
k8s.io/api v0.18.3 h1:2AJaUQdgUZLoDZHrun21PW2Nx9+ll6cUzvn3IKhSIn0=
|
||||
k8s.io/api v0.18.3/go.mod h1:UOaMwERbqJMfeeeHc8XJKawj4P9TgDRnViIqqBeH2QA=
|
||||
k8s.io/apimachinery v0.18.3 h1:pOGcbVAhxADgUYnjS08EFXs9QMl8qaH5U4fr5LGUrSk=
|
||||
k8s.io/api v0.20.0 h1:WwrYoZNM1W1aQEbyl8HNG+oWGzLpZQBlcerS9BQw9yI=
|
||||
k8s.io/api v0.20.0/go.mod h1:HyLC5l5eoS/ygQYl1BXBgFzWNlkHiAuyNAbevIn+FKg=
|
||||
k8s.io/apimachinery v0.18.3/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko=
|
||||
k8s.io/client-go v0.18.3 h1:QaJzz92tsN67oorwzmoB0a9r9ZVHuD5ryjbCKP0U22k=
|
||||
k8s.io/apimachinery v0.20.0 h1:jjzbTJRXk0unNS71L7h3lxGDH/2HPxMPaQY+MjECKL8=
|
||||
k8s.io/apimachinery v0.20.0/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
|
||||
k8s.io/client-go v0.18.3/go.mod h1:4a/dpQEvzAhT1BbuWW09qvIaGw6Gbu1gZYiQZIi1DMw=
|
||||
k8s.io/client-go v0.20.0 h1:Xlax8PKbZsjX4gFvNtt4F5MoJ1V5prDvCuoq9B7iax0=
|
||||
k8s.io/client-go v0.20.0/go.mod h1:4KWh/g+Ocd8KkCwKF8vUNnmqgv+EVnQDK4MBF4oB5tY=
|
||||
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||
k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||
k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
|
||||
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
|
||||
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
||||
k8s.io/klog/v2 v2.3.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||
k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||
k8s.io/klog/v2 v2.80.0 h1:lyJt0TWMPaGoODa8B8bUuxgHS3W/m/bNr2cca3brA/g=
|
||||
k8s.io/klog/v2 v2.80.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
|
||||
k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E=
|
||||
k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM=
|
||||
k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
|
||||
k8s.io/utils v0.0.0-20200520001619-278ece378a50 h1:ZtTUW5+ZWaoqjR3zOpRa7oFJ5d4aA22l4me/xArfOIc=
|
||||
k8s.io/utils v0.0.0-20200520001619-278ece378a50/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
k8s.io/utils v0.0.0-20201110183641-67b214c5f920 h1:CbnUZsM497iRC5QMVkHwyl8s2tB3g7yaSHkYPkpgelw=
|
||||
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0=
|
||||
lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA=
|
||||
nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g=
|
||||
@ -2304,8 +2397,9 @@ rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU=
|
||||
rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA=
|
||||
sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
|
||||
sigs.k8s.io/structured-merge-diff/v3 v3.0.0 h1:dOmIZBMfhcHS09XZkMyUgkq5trg3/jRyJYFZUiaOp8E=
|
||||
sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.2 h1:YHQV7Dajm86OuqnIR6zAelnDWBRjo+YhYV9PmGrh1s8=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
|
||||
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
||||
|
@ -1983,10 +1983,7 @@ func (s *TransactionAPI) GetTransactionReceiptsByBlockNumber(ctx context.Context
|
||||
txReceipts := make([]map[string]interface{}, 0, len(txs))
|
||||
for idx, receipt := range receipts {
|
||||
tx := txs[idx]
|
||||
var signer types.Signer = types.FrontierSigner{}
|
||||
if tx.Protected() {
|
||||
signer = types.NewEIP155Signer(tx.ChainId())
|
||||
}
|
||||
signer := types.MakeSigner(s.b.ChainConfig(), block.Number(), block.Time())
|
||||
from, _ := types.Sender(signer, tx)
|
||||
|
||||
fields := map[string]interface{}{
|
||||
@ -2001,6 +1998,8 @@ func (s *TransactionAPI) GetTransactionReceiptsByBlockNumber(ctx context.Context
|
||||
"contractAddress": nil,
|
||||
"logs": receipt.Logs,
|
||||
"logsBloom": receipt.Bloom,
|
||||
"type": hexutil.Uint(tx.Type()),
|
||||
"effectiveGasPrice": (*hexutil.Big)(receipt.EffectiveGasPrice),
|
||||
}
|
||||
|
||||
// Assign receipt status or post state.
|
||||
@ -2039,7 +2038,7 @@ func (s *TransactionAPI) GetTransactionDataAndReceipt(ctx context.Context, hash
|
||||
receipt := receipts[index]
|
||||
|
||||
// Derive the sender.
|
||||
header, err := s.b.HeaderByHash(ctx, hash)
|
||||
header, err := s.b.HeaderByHash(ctx, blockHash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -2077,6 +2076,8 @@ func (s *TransactionAPI) GetTransactionDataAndReceipt(ctx context.Context, hash
|
||||
"contractAddress": nil,
|
||||
"logs": receipt.Logs,
|
||||
"logsBloom": receipt.Bloom,
|
||||
"type": hexutil.Uint(tx.Type()),
|
||||
"effectiveGasPrice": (*hexutil.Big)(receipt.EffectiveGasPrice),
|
||||
}
|
||||
|
||||
// Assign receipt status or post state.
|
||||
|
@ -100,11 +100,6 @@ func (db *odrDatabase) TrieDB() *trie.Database {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *odrDatabase) CacheAccount(_ common.Hash, _ state.Trie) {}
|
||||
|
||||
func (db *odrDatabase) CacheStorage(_ common.Hash, _ common.Hash, _ state.Trie) {}
|
||||
|
||||
func (db *odrDatabase) Purge() {}
|
||||
func (db *odrDatabase) DiskDB() ethdb.KeyValueStore {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ import (
|
||||
const (
|
||||
VersionMajor = 1 // Major version component of the current release
|
||||
VersionMinor = 3 // Minor version component of the current release
|
||||
VersionPatch = 0 // Patch version component of the current release
|
||||
VersionPatch = 1 // Patch version component of the current release
|
||||
VersionMeta = "" // Version metadata to append to the version string
|
||||
)
|
||||
|
||||
|
@ -61,7 +61,7 @@ type backend interface {
|
||||
|
||||
// Size returns the current storage size of the memory cache in front of the
|
||||
// persistent database layer.
|
||||
Size() common.StorageSize
|
||||
Size() (common.StorageSize, common.StorageSize, common.StorageSize)
|
||||
|
||||
// Update performs a state transition by committing dirty nodes contained
|
||||
// in the given set in order to update state from the specified parent to
|
||||
@ -207,16 +207,16 @@ func (db *Database) Commit(root common.Hash, report bool) error {
|
||||
|
||||
// Size returns the storage size of dirty trie nodes in front of the persistent
|
||||
// database and the size of cached preimages.
|
||||
func (db *Database) Size() (common.StorageSize, common.StorageSize) {
|
||||
func (db *Database) Size() (common.StorageSize, common.StorageSize, common.StorageSize, common.StorageSize) {
|
||||
var (
|
||||
storages common.StorageSize
|
||||
preimages common.StorageSize
|
||||
diffs, nodes, immutablenodes common.StorageSize
|
||||
preimages common.StorageSize
|
||||
)
|
||||
storages = db.backend.Size()
|
||||
diffs, nodes, immutablenodes = db.backend.Size()
|
||||
if db.preimages != nil {
|
||||
preimages = db.preimages.size()
|
||||
}
|
||||
return storages, preimages
|
||||
return diffs, nodes, immutablenodes, preimages
|
||||
}
|
||||
|
||||
// Initialized returns an indicator if the state data is already initialized
|
||||
@ -353,3 +353,14 @@ func (db *Database) SetBufferSize(size int) error {
|
||||
}
|
||||
return pdb.SetBufferSize(size)
|
||||
}
|
||||
|
||||
// Head return the top non-fork difflayer/disklayer root hash for rewinding.
|
||||
// It's only supported by path-based database and will return an error for
|
||||
// others.
|
||||
func (db *Database) Head() common.Hash {
|
||||
pdb, ok := db.backend.(*pathdb.Database)
|
||||
if !ok {
|
||||
return common.Hash{}
|
||||
}
|
||||
return pdb.Head()
|
||||
}
|
||||
|
95
trie/sync.go
95
trie/sync.go
@ -27,6 +27,7 @@ import (
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/metrics"
|
||||
)
|
||||
|
||||
// ErrNotRequested is returned by the trie sync when it's requested to process a
|
||||
@ -42,6 +43,16 @@ var ErrAlreadyProcessed = errors.New("already processed")
|
||||
// memory if the node was configured with a significant number of peers.
|
||||
const maxFetchesPerDepth = 16384
|
||||
|
||||
var (
|
||||
// deletionGauge is the metric to track how many trie node deletions
|
||||
// are performed in total during the sync process.
|
||||
deletionGauge = metrics.NewRegisteredGauge("trie/sync/delete", nil)
|
||||
|
||||
// lookupGauge is the metric to track how many trie node lookups are
|
||||
// performed to determine if node needs to be deleted.
|
||||
lookupGauge = metrics.NewRegisteredGauge("trie/sync/lookup", nil)
|
||||
)
|
||||
|
||||
// SyncPath is a path tuple identifying a particular trie node either in a single
|
||||
// trie (account) or a layered trie (account -> storage).
|
||||
//
|
||||
@ -93,9 +104,10 @@ type LeafCallback func(keys [][]byte, path []byte, leaf []byte, parent common.Ha
|
||||
|
||||
// nodeRequest represents a scheduled or already in-flight trie node retrieval request.
|
||||
type nodeRequest struct {
|
||||
hash common.Hash // Hash of the trie node to retrieve
|
||||
path []byte // Merkle path leading to this node for prioritization
|
||||
data []byte // Data content of the node, cached until all subtrees complete
|
||||
hash common.Hash // Hash of the trie node to retrieve
|
||||
path []byte // Merkle path leading to this node for prioritization
|
||||
data []byte // Data content of the node, cached until all subtrees complete
|
||||
deletes [][]byte // List of internal path segments for trie nodes to delete
|
||||
|
||||
parent *nodeRequest // Parent state node referencing this entry
|
||||
deps int // Number of dependencies before allowed to commit this node
|
||||
@ -125,18 +137,20 @@ type CodeSyncResult struct {
|
||||
// syncMemBatch is an in-memory buffer of successfully downloaded but not yet
|
||||
// persisted data items.
|
||||
type syncMemBatch struct {
|
||||
nodes map[string][]byte // In-memory membatch of recently completed nodes
|
||||
hashes map[string]common.Hash // Hashes of recently completed nodes
|
||||
codes map[common.Hash][]byte // In-memory membatch of recently completed codes
|
||||
size uint64 // Estimated batch-size of in-memory data.
|
||||
nodes map[string][]byte // In-memory membatch of recently completed nodes
|
||||
hashes map[string]common.Hash // Hashes of recently completed nodes
|
||||
deletes map[string]struct{} // List of paths for trie node to delete
|
||||
codes map[common.Hash][]byte // In-memory membatch of recently completed codes
|
||||
size uint64 // Estimated batch-size of in-memory data.
|
||||
}
|
||||
|
||||
// newSyncMemBatch allocates a new memory-buffer for not-yet persisted trie nodes.
|
||||
func newSyncMemBatch() *syncMemBatch {
|
||||
return &syncMemBatch{
|
||||
nodes: make(map[string][]byte),
|
||||
hashes: make(map[string]common.Hash),
|
||||
codes: make(map[common.Hash][]byte),
|
||||
nodes: make(map[string][]byte),
|
||||
hashes: make(map[string]common.Hash),
|
||||
deletes: make(map[string]struct{}),
|
||||
codes: make(map[common.Hash][]byte),
|
||||
}
|
||||
}
|
||||
|
||||
@ -347,16 +361,23 @@ func (s *Sync) ProcessNode(result NodeSyncResult) error {
|
||||
// Commit flushes the data stored in the internal membatch out to persistent
|
||||
// storage, returning any occurred error.
|
||||
func (s *Sync) Commit(dbw ethdb.Batch) error {
|
||||
// Dump the membatch into a database dbw
|
||||
// Flush the pending node writes into database batch.
|
||||
for path, value := range s.membatch.nodes {
|
||||
owner, inner := ResolvePath([]byte(path))
|
||||
rawdb.WriteTrieNode(dbw, owner, inner, s.membatch.hashes[path], value, s.scheme)
|
||||
}
|
||||
// Flush the pending node deletes into the database batch.
|
||||
// Please note that each written and deleted node has a
|
||||
// unique path, ensuring no duplication occurs.
|
||||
for path := range s.membatch.deletes {
|
||||
owner, inner := ResolvePath([]byte(path))
|
||||
rawdb.DeleteTrieNode(dbw, owner, inner, common.Hash{} /* unused */, s.scheme)
|
||||
}
|
||||
// Flush the pending code writes into database batch.
|
||||
for hash, value := range s.membatch.codes {
|
||||
rawdb.WriteCode(dbw, hash, value)
|
||||
}
|
||||
// Drop the membatch data and return
|
||||
s.membatch = newSyncMemBatch()
|
||||
s.membatch = newSyncMemBatch() // reset the batch
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -425,6 +446,39 @@ func (s *Sync) children(req *nodeRequest, object node) ([]*nodeRequest, error) {
|
||||
node: node.Val,
|
||||
path: append(append([]byte(nil), req.path...), key...),
|
||||
}}
|
||||
// Mark all internal nodes between shortNode and its **in disk**
|
||||
// child as invalid. This is essential in the case of path mode
|
||||
// scheme; otherwise, state healing might overwrite existing child
|
||||
// nodes silently while leaving a dangling parent node within the
|
||||
// range of this internal path on disk. This would break the
|
||||
// guarantee for state healing.
|
||||
//
|
||||
// While it's possible for this shortNode to overwrite a previously
|
||||
// existing full node, the other branches of the fullNode can be
|
||||
// retained as they remain untouched and complete.
|
||||
//
|
||||
// This step is only necessary for path mode, as there is no deletion
|
||||
// in hash mode at all.
|
||||
if _, ok := node.Val.(hashNode); ok && s.scheme == rawdb.PathScheme {
|
||||
owner, inner := ResolvePath(req.path)
|
||||
for i := 1; i < len(key); i++ {
|
||||
// While checking for a non-existent item in Pebble can be less efficient
|
||||
// without a bloom filter, the relatively low frequency of lookups makes
|
||||
// the performance impact negligible.
|
||||
var exists bool
|
||||
if owner == (common.Hash{}) {
|
||||
exists = rawdb.ExistsAccountTrieNode(s.database, append(inner, key[:i]...))
|
||||
} else {
|
||||
exists = rawdb.ExistsStorageTrieNode(s.database, owner, append(inner, key[:i]...))
|
||||
}
|
||||
if exists {
|
||||
req.deletes = append(req.deletes, key[:i])
|
||||
deletionGauge.Inc(1)
|
||||
log.Debug("Detected dangling node", "owner", owner, "path", append(inner, key[:i]...))
|
||||
}
|
||||
}
|
||||
lookupGauge.Inc(int64(len(key) - 1))
|
||||
}
|
||||
case *fullNode:
|
||||
for i := 0; i < 17; i++ {
|
||||
if node.Children[i] != nil {
|
||||
@ -509,10 +563,19 @@ func (s *Sync) commitNodeRequest(req *nodeRequest) error {
|
||||
// Write the node content to the membatch
|
||||
s.membatch.nodes[string(req.path)] = req.data
|
||||
s.membatch.hashes[string(req.path)] = req.hash
|
||||
|
||||
// The size tracking refers to the db-batch, not the in-memory data.
|
||||
// Therefore, we ignore the req.path, and account only for the hash+data
|
||||
// which eventually is written to db.
|
||||
s.membatch.size += common.HashLength + uint64(len(req.data))
|
||||
if s.scheme == rawdb.PathScheme {
|
||||
s.membatch.size += uint64(len(req.path) + len(req.data))
|
||||
} else {
|
||||
s.membatch.size += common.HashLength + uint64(len(req.data))
|
||||
}
|
||||
// Delete the internal nodes which are marked as invalid
|
||||
for _, segment := range req.deletes {
|
||||
path := append(req.path, segment...)
|
||||
s.membatch.deletes[string(path)] = struct{}{}
|
||||
s.membatch.size += uint64(len(path))
|
||||
}
|
||||
delete(s.nodeReqs, string(req.path))
|
||||
s.fetches[len(req.path)]--
|
||||
|
||||
|
@ -70,31 +70,53 @@ func makeTestTrie(scheme string) (ethdb.Database, *Database, *StateTrie, map[str
|
||||
|
||||
// checkTrieContents cross references a reconstructed trie with an expected data
|
||||
// content map.
|
||||
func checkTrieContents(t *testing.T, db ethdb.Database, scheme string, root []byte, content map[string][]byte) {
|
||||
func checkTrieContents(t *testing.T, db ethdb.Database, scheme string, root []byte, content map[string][]byte, rawTrie bool) {
|
||||
// Check root availability and trie contents
|
||||
ndb := newTestDatabase(db, scheme)
|
||||
trie, err := NewStateTrie(TrieID(common.BytesToHash(root)), ndb)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create trie at %x: %v", root, err)
|
||||
}
|
||||
if err := checkTrieConsistency(db, scheme, common.BytesToHash(root)); err != nil {
|
||||
if err := checkTrieConsistency(db, scheme, common.BytesToHash(root), rawTrie); err != nil {
|
||||
t.Fatalf("inconsistent trie at %x: %v", root, err)
|
||||
}
|
||||
type reader interface {
|
||||
MustGet(key []byte) []byte
|
||||
}
|
||||
var r reader
|
||||
if rawTrie {
|
||||
trie, err := New(TrieID(common.BytesToHash(root)), ndb)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create trie at %x: %v", root, err)
|
||||
}
|
||||
r = trie
|
||||
} else {
|
||||
trie, err := NewStateTrie(TrieID(common.BytesToHash(root)), ndb)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create trie at %x: %v", root, err)
|
||||
}
|
||||
r = trie
|
||||
}
|
||||
for key, val := range content {
|
||||
if have := trie.MustGet([]byte(key)); !bytes.Equal(have, val) {
|
||||
if have := r.MustGet([]byte(key)); !bytes.Equal(have, val) {
|
||||
t.Errorf("entry %x: content mismatch: have %x, want %x", key, have, val)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// checkTrieConsistency checks that all nodes in a trie are indeed present.
|
||||
func checkTrieConsistency(db ethdb.Database, scheme string, root common.Hash) error {
|
||||
func checkTrieConsistency(db ethdb.Database, scheme string, root common.Hash, rawTrie bool) error {
|
||||
ndb := newTestDatabase(db, scheme)
|
||||
trie, err := NewStateTrie(TrieID(root), ndb)
|
||||
if err != nil {
|
||||
return nil // Consider a non existent state consistent
|
||||
var it NodeIterator
|
||||
if rawTrie {
|
||||
trie, err := New(TrieID(root), ndb)
|
||||
if err != nil {
|
||||
return nil // Consider a non existent state consistent
|
||||
}
|
||||
it = trie.MustNodeIterator(nil)
|
||||
} else {
|
||||
trie, err := NewStateTrie(TrieID(root), ndb)
|
||||
if err != nil {
|
||||
return nil // Consider a non existent state consistent
|
||||
}
|
||||
it = trie.MustNodeIterator(nil)
|
||||
}
|
||||
it := trie.MustNodeIterator(nil)
|
||||
for it.Next(true) {
|
||||
}
|
||||
return it.Error()
|
||||
@ -205,7 +227,7 @@ func testIterativeSync(t *testing.T, count int, bypath bool, scheme string) {
|
||||
}
|
||||
}
|
||||
// Cross check that the two tries are in sync
|
||||
checkTrieContents(t, diskdb, srcDb.Scheme(), srcTrie.Hash().Bytes(), srcData)
|
||||
checkTrieContents(t, diskdb, srcDb.Scheme(), srcTrie.Hash().Bytes(), srcData, false)
|
||||
}
|
||||
|
||||
// Tests that the trie scheduler can correctly reconstruct the state even if only
|
||||
@ -271,7 +293,7 @@ func testIterativeDelayedSync(t *testing.T, scheme string) {
|
||||
}
|
||||
}
|
||||
// Cross check that the two tries are in sync
|
||||
checkTrieContents(t, diskdb, srcDb.Scheme(), srcTrie.Hash().Bytes(), srcData)
|
||||
checkTrieContents(t, diskdb, srcDb.Scheme(), srcTrie.Hash().Bytes(), srcData, false)
|
||||
}
|
||||
|
||||
// Tests that given a root hash, a trie can sync iteratively on a single thread,
|
||||
@ -341,7 +363,7 @@ func testIterativeRandomSync(t *testing.T, count int, scheme string) {
|
||||
}
|
||||
}
|
||||
// Cross check that the two tries are in sync
|
||||
checkTrieContents(t, diskdb, srcDb.Scheme(), srcTrie.Hash().Bytes(), srcData)
|
||||
checkTrieContents(t, diskdb, srcDb.Scheme(), srcTrie.Hash().Bytes(), srcData, false)
|
||||
}
|
||||
|
||||
// Tests that the trie scheduler can correctly reconstruct the state even if only
|
||||
@ -413,7 +435,7 @@ func testIterativeRandomDelayedSync(t *testing.T, scheme string) {
|
||||
}
|
||||
}
|
||||
// Cross check that the two tries are in sync
|
||||
checkTrieContents(t, diskdb, srcDb.Scheme(), srcTrie.Hash().Bytes(), srcData)
|
||||
checkTrieContents(t, diskdb, srcDb.Scheme(), srcTrie.Hash().Bytes(), srcData, false)
|
||||
}
|
||||
|
||||
// Tests that a trie sync will not request nodes multiple times, even if they
|
||||
@ -484,7 +506,7 @@ func testDuplicateAvoidanceSync(t *testing.T, scheme string) {
|
||||
}
|
||||
}
|
||||
// Cross check that the two tries are in sync
|
||||
checkTrieContents(t, diskdb, srcDb.Scheme(), srcTrie.Hash().Bytes(), srcData)
|
||||
checkTrieContents(t, diskdb, srcDb.Scheme(), srcTrie.Hash().Bytes(), srcData, false)
|
||||
}
|
||||
|
||||
// Tests that at any point in time during a sync, only complete sub-tries are in
|
||||
@ -569,7 +591,7 @@ func testIncompleteSync(t *testing.T, scheme string) {
|
||||
nodeHash := addedHashes[i]
|
||||
value := rawdb.ReadTrieNode(diskdb, owner, inner, nodeHash, scheme)
|
||||
rawdb.DeleteTrieNode(diskdb, owner, inner, nodeHash, scheme)
|
||||
if err := checkTrieConsistency(diskdb, srcDb.Scheme(), root); err == nil {
|
||||
if err := checkTrieConsistency(diskdb, srcDb.Scheme(), root, false); err == nil {
|
||||
t.Fatalf("trie inconsistency not caught, missing: %x", path)
|
||||
}
|
||||
rawdb.WriteTrieNode(diskdb, owner, inner, nodeHash, value, scheme)
|
||||
@ -643,7 +665,7 @@ func testSyncOrdering(t *testing.T, scheme string) {
|
||||
}
|
||||
}
|
||||
// Cross check that the two tries are in sync
|
||||
checkTrieContents(t, diskdb, srcDb.Scheme(), srcTrie.Hash().Bytes(), srcData)
|
||||
checkTrieContents(t, diskdb, srcDb.Scheme(), srcTrie.Hash().Bytes(), srcData, false)
|
||||
|
||||
// Check that the trie nodes have been requested path-ordered
|
||||
for i := 0; i < len(reqs)-1; i++ {
|
||||
@ -664,7 +686,7 @@ func syncWith(t *testing.T, root common.Hash, db ethdb.Database, srcDb *Database
|
||||
|
||||
// The code requests are ignored here since there is no code
|
||||
// at the testing trie.
|
||||
paths, nodes, _ := sched.Missing(1)
|
||||
paths, nodes, _ := sched.Missing(0)
|
||||
var elements []trieElement
|
||||
for i := 0; i < len(paths); i++ {
|
||||
elements = append(elements, trieElement{
|
||||
@ -698,7 +720,7 @@ func syncWith(t *testing.T, root common.Hash, db ethdb.Database, srcDb *Database
|
||||
}
|
||||
batch.Write()
|
||||
|
||||
paths, nodes, _ = sched.Missing(1)
|
||||
paths, nodes, _ = sched.Missing(0)
|
||||
elements = elements[:0]
|
||||
for i := 0; i < len(paths); i++ {
|
||||
elements = append(elements, trieElement{
|
||||
@ -724,7 +746,7 @@ func testSyncMovingTarget(t *testing.T, scheme string) {
|
||||
// Create a destination trie and sync with the scheduler
|
||||
diskdb := rawdb.NewMemoryDatabase()
|
||||
syncWith(t, srcTrie.Hash(), diskdb, srcDb)
|
||||
checkTrieContents(t, diskdb, srcDb.Scheme(), srcTrie.Hash().Bytes(), srcData)
|
||||
checkTrieContents(t, diskdb, srcDb.Scheme(), srcTrie.Hash().Bytes(), srcData, false)
|
||||
|
||||
// Push more modifications into the src trie, to see if dest trie can still
|
||||
// sync with it(overwrite stale states)
|
||||
@ -748,7 +770,7 @@ func testSyncMovingTarget(t *testing.T, scheme string) {
|
||||
srcTrie, _ = NewStateTrie(TrieID(root), srcDb)
|
||||
|
||||
syncWith(t, srcTrie.Hash(), diskdb, srcDb)
|
||||
checkTrieContents(t, diskdb, srcDb.Scheme(), srcTrie.Hash().Bytes(), diff)
|
||||
checkTrieContents(t, diskdb, srcDb.Scheme(), srcTrie.Hash().Bytes(), diff, false)
|
||||
|
||||
// Revert added modifications from the src trie, to see if dest trie can still
|
||||
// sync with it(overwrite reverted states)
|
||||
@ -772,5 +794,98 @@ func testSyncMovingTarget(t *testing.T, scheme string) {
|
||||
srcTrie, _ = NewStateTrie(TrieID(root), srcDb)
|
||||
|
||||
syncWith(t, srcTrie.Hash(), diskdb, srcDb)
|
||||
checkTrieContents(t, diskdb, srcDb.Scheme(), srcTrie.Hash().Bytes(), reverted)
|
||||
checkTrieContents(t, diskdb, srcDb.Scheme(), srcTrie.Hash().Bytes(), reverted, false)
|
||||
}
|
||||
|
||||
// Tests if state syncer can correctly catch up the pivot move.
|
||||
func TestPivotMove(t *testing.T) {
|
||||
testPivotMove(t, rawdb.HashScheme, true)
|
||||
testPivotMove(t, rawdb.HashScheme, false)
|
||||
testPivotMove(t, rawdb.PathScheme, true)
|
||||
testPivotMove(t, rawdb.PathScheme, false)
|
||||
}
|
||||
|
||||
func testPivotMove(t *testing.T, scheme string, tiny bool) {
|
||||
var (
|
||||
srcDisk = rawdb.NewMemoryDatabase()
|
||||
srcTrieDB = newTestDatabase(srcDisk, scheme)
|
||||
srcTrie, _ = New(TrieID(types.EmptyRootHash), srcTrieDB)
|
||||
|
||||
deleteFn = func(key []byte, tr *Trie, states map[string][]byte) {
|
||||
tr.Delete(key)
|
||||
delete(states, string(key))
|
||||
}
|
||||
writeFn = func(key []byte, val []byte, tr *Trie, states map[string][]byte) {
|
||||
if val == nil {
|
||||
if tiny {
|
||||
val = randBytes(4)
|
||||
} else {
|
||||
val = randBytes(32)
|
||||
}
|
||||
}
|
||||
tr.Update(key, val)
|
||||
states[string(key)] = common.CopyBytes(val)
|
||||
}
|
||||
copyStates = func(states map[string][]byte) map[string][]byte {
|
||||
cpy := make(map[string][]byte)
|
||||
for k, v := range states {
|
||||
cpy[k] = v
|
||||
}
|
||||
return cpy
|
||||
}
|
||||
)
|
||||
stateA := make(map[string][]byte)
|
||||
writeFn([]byte{0x01, 0x23}, nil, srcTrie, stateA)
|
||||
writeFn([]byte{0x01, 0x24}, nil, srcTrie, stateA)
|
||||
writeFn([]byte{0x12, 0x33}, nil, srcTrie, stateA)
|
||||
writeFn([]byte{0x12, 0x34}, nil, srcTrie, stateA)
|
||||
writeFn([]byte{0x02, 0x34}, nil, srcTrie, stateA)
|
||||
writeFn([]byte{0x13, 0x44}, nil, srcTrie, stateA)
|
||||
|
||||
rootA, nodesA, _ := srcTrie.Commit(false)
|
||||
if err := srcTrieDB.Update(rootA, types.EmptyRootHash, 0, trienode.NewWithNodeSet(nodesA), nil); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := srcTrieDB.Commit(rootA, false); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// Create a destination trie and sync with the scheduler
|
||||
destDisk := rawdb.NewMemoryDatabase()
|
||||
syncWith(t, rootA, destDisk, srcTrieDB)
|
||||
checkTrieContents(t, destDisk, scheme, srcTrie.Hash().Bytes(), stateA, true)
|
||||
|
||||
// Delete element to collapse trie
|
||||
stateB := copyStates(stateA)
|
||||
srcTrie, _ = New(TrieID(rootA), srcTrieDB)
|
||||
deleteFn([]byte{0x02, 0x34}, srcTrie, stateB)
|
||||
deleteFn([]byte{0x13, 0x44}, srcTrie, stateB)
|
||||
writeFn([]byte{0x01, 0x24}, nil, srcTrie, stateB)
|
||||
|
||||
rootB, nodesB, _ := srcTrie.Commit(false)
|
||||
if err := srcTrieDB.Update(rootB, rootA, 0, trienode.NewWithNodeSet(nodesB), nil); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := srcTrieDB.Commit(rootB, false); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
syncWith(t, rootB, destDisk, srcTrieDB)
|
||||
checkTrieContents(t, destDisk, scheme, srcTrie.Hash().Bytes(), stateB, true)
|
||||
|
||||
// Add elements to expand trie
|
||||
stateC := copyStates(stateB)
|
||||
srcTrie, _ = New(TrieID(rootB), srcTrieDB)
|
||||
|
||||
writeFn([]byte{0x01, 0x24}, stateA[string([]byte{0x01, 0x24})], srcTrie, stateC)
|
||||
writeFn([]byte{0x02, 0x34}, nil, srcTrie, stateC)
|
||||
writeFn([]byte{0x13, 0x44}, nil, srcTrie, stateC)
|
||||
|
||||
rootC, nodesC, _ := srcTrie.Commit(false)
|
||||
if err := srcTrieDB.Update(rootC, rootB, 0, trienode.NewWithNodeSet(nodesC), nil); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := srcTrieDB.Commit(rootC, false); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
syncWith(t, rootC, destDisk, srcTrieDB)
|
||||
checkTrieContents(t, destDisk, scheme, srcTrie.Hash().Bytes(), stateC, true)
|
||||
}
|
||||
|
@ -610,10 +610,7 @@ func (t *Trie) Hash() common.Hash {
|
||||
func (t *Trie) Commit(collectLeaf bool) (common.Hash, *trienode.NodeSet, error) {
|
||||
defer t.tracer.reset()
|
||||
defer func() {
|
||||
// StateDB will cache the trie and reuse it to read and write,
|
||||
// the committed flag is true will prevent the cache trie access
|
||||
// the trie node.
|
||||
t.committed = false
|
||||
t.committed = true
|
||||
}()
|
||||
// Trie is empty and can be classified into two types of situations:
|
||||
// (a) The trie was empty and no update happens => return nil
|
||||
|
@ -641,7 +641,7 @@ func (db *Database) Update(root common.Hash, parent common.Hash, block uint64, n
|
||||
|
||||
// Size returns the current storage size of the memory cache in front of the
|
||||
// persistent database layer.
|
||||
func (db *Database) Size() common.StorageSize {
|
||||
func (db *Database) Size() (common.StorageSize, common.StorageSize, common.StorageSize) {
|
||||
db.lock.RLock()
|
||||
defer db.lock.RUnlock()
|
||||
|
||||
@ -649,7 +649,7 @@ func (db *Database) Size() common.StorageSize {
|
||||
// the total memory consumption, the maintenance metadata is also needed to be
|
||||
// counted.
|
||||
var metadataSize = common.StorageSize(len(db.dirties) * cachedNodeSize)
|
||||
return db.dirtiesSize + db.childrenSize + metadataSize
|
||||
return 0, db.dirtiesSize + db.childrenSize + metadataSize, 0
|
||||
}
|
||||
|
||||
// Close closes the trie database and releases all held resources.
|
||||
|
448
trie/triedb/pathdb/asyncnodebuffer.go
Normal file
448
trie/triedb/pathdb/asyncnodebuffer.go
Normal file
@ -0,0 +1,448 @@
|
||||
package pathdb
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/VictoriaMetrics/fastcache"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/trie/trienode"
|
||||
)
|
||||
|
||||
var _ trienodebuffer = &asyncnodebuffer{}
|
||||
|
||||
// asyncnodebuffer implement trienodebuffer interface, and aysnc the nodecache
|
||||
// to disk.
|
||||
type asyncnodebuffer struct {
|
||||
mux sync.RWMutex
|
||||
current *nodecache
|
||||
background *nodecache
|
||||
}
|
||||
|
||||
// newAsyncNodeBuffer initializes the async node buffer with the provided nodes.
|
||||
func newAsyncNodeBuffer(limit int, nodes map[common.Hash]map[string]*trienode.Node, layers uint64) *asyncnodebuffer {
|
||||
if nodes == nil {
|
||||
nodes = make(map[common.Hash]map[string]*trienode.Node)
|
||||
}
|
||||
var size uint64
|
||||
for _, subset := range nodes {
|
||||
for path, n := range subset {
|
||||
size += uint64(len(n.Blob) + len(path))
|
||||
}
|
||||
}
|
||||
|
||||
return &asyncnodebuffer{
|
||||
current: newNodeCache(uint64(limit), size, nodes, layers),
|
||||
background: newNodeCache(uint64(limit), 0, make(map[common.Hash]map[string]*trienode.Node), 0),
|
||||
}
|
||||
}
|
||||
|
||||
// node retrieves the trie node with given node info.
|
||||
func (a *asyncnodebuffer) node(owner common.Hash, path []byte, hash common.Hash) (*trienode.Node, error) {
|
||||
a.mux.RLock()
|
||||
defer a.mux.RUnlock()
|
||||
|
||||
node, err := a.current.node(owner, path, hash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if node == nil {
|
||||
return a.background.node(owner, path, hash)
|
||||
}
|
||||
return node, nil
|
||||
}
|
||||
|
||||
// commit merges the dirty nodes into the nodebuffer. This operation won't take
|
||||
// the ownership of the nodes map which belongs to the bottom-most diff layer.
|
||||
// It will just hold the node references from the given map which are safe to
|
||||
// copy.
|
||||
func (a *asyncnodebuffer) commit(nodes map[common.Hash]map[string]*trienode.Node) trienodebuffer {
|
||||
a.mux.Lock()
|
||||
defer a.mux.Unlock()
|
||||
|
||||
err := a.current.commit(nodes)
|
||||
if err != nil {
|
||||
log.Crit("[BUG] failed to commit nodes to asyncnodebuffer", "error", err)
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
// revert is the reverse operation of commit. It also merges the provided nodes
|
||||
// into the nodebuffer, the difference is that the provided node set should
|
||||
// revert the changes made by the last state transition.
|
||||
func (a *asyncnodebuffer) revert(db ethdb.KeyValueReader, nodes map[common.Hash]map[string]*trienode.Node) error {
|
||||
a.mux.Lock()
|
||||
defer a.mux.Unlock()
|
||||
|
||||
var err error
|
||||
a.current, err = a.current.merge(a.background)
|
||||
if err != nil {
|
||||
log.Crit("[BUG] failed to merge node cache under revert async node buffer", "error", err)
|
||||
}
|
||||
a.background.reset()
|
||||
return a.current.revert(db, nodes)
|
||||
}
|
||||
|
||||
// setSize is unsupported in asyncnodebuffer, due to the double buffer, blocking will occur.
|
||||
func (a *asyncnodebuffer) setSize(size int, db ethdb.KeyValueStore, clean *fastcache.Cache, id uint64) error {
|
||||
return errors.New("not supported")
|
||||
}
|
||||
|
||||
// reset cleans up the disk cache.
|
||||
func (a *asyncnodebuffer) reset() {
|
||||
a.mux.Lock()
|
||||
defer a.mux.Unlock()
|
||||
|
||||
a.current.reset()
|
||||
a.background.reset()
|
||||
}
|
||||
|
||||
// empty returns an indicator if nodebuffer contains any state transition inside.
|
||||
func (a *asyncnodebuffer) empty() bool {
|
||||
a.mux.RLock()
|
||||
defer a.mux.RUnlock()
|
||||
|
||||
return a.current.empty() && a.background.empty()
|
||||
}
|
||||
|
||||
// setSize sets the buffer size to the provided number, and invokes a flush
|
||||
// operation if the current memory usage exceeds the new limit.
|
||||
//func (b *nodebuffer) setSize(size int, db ethdb.KeyValueStore, clean *fastcache.Cache, id uint64) error {
|
||||
// b.limit = uint64(size)
|
||||
// return b.flush(db, clean, id, false)
|
||||
//}
|
||||
|
||||
// flush persists the in-memory dirty trie node into the disk if the configured
|
||||
// memory threshold is reached. Note, all data must be written atomically.
|
||||
func (a *asyncnodebuffer) flush(db ethdb.KeyValueStore, clean *fastcache.Cache, id uint64, force bool) error {
|
||||
a.mux.Lock()
|
||||
defer a.mux.Unlock()
|
||||
|
||||
if force {
|
||||
for {
|
||||
if atomic.LoadUint64(&a.background.immutable) == 1 {
|
||||
time.Sleep(time.Duration(DefaultBackgroundFlushInterval) * time.Second)
|
||||
log.Info("waiting background memory table flush to disk for force flush node buffer")
|
||||
continue
|
||||
}
|
||||
atomic.StoreUint64(&a.current.immutable, 1)
|
||||
return a.current.flush(db, clean, id)
|
||||
}
|
||||
}
|
||||
|
||||
if a.current.size < a.current.limit {
|
||||
return nil
|
||||
}
|
||||
|
||||
// background flush doing
|
||||
if atomic.LoadUint64(&a.background.immutable) == 1 {
|
||||
return nil
|
||||
}
|
||||
|
||||
atomic.StoreUint64(&a.current.immutable, 1)
|
||||
a.current, a.background = a.background, a.current
|
||||
|
||||
go func(persistId uint64) {
|
||||
for {
|
||||
err := a.background.flush(db, clean, persistId)
|
||||
if err == nil {
|
||||
log.Debug("succeed to flush background nodecahce to disk", "state_id", persistId)
|
||||
return
|
||||
}
|
||||
log.Error("failed to flush background nodecahce to disk", "state_id", persistId, "error", err)
|
||||
}
|
||||
}(id)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *asyncnodebuffer) getAllNodes() map[common.Hash]map[string]*trienode.Node {
|
||||
a.mux.Lock()
|
||||
defer a.mux.Unlock()
|
||||
|
||||
cached, err := a.current.merge(a.background)
|
||||
if err != nil {
|
||||
log.Crit("[BUG] failed to merge nodecache under revert asyncnodebuffer", "error", err)
|
||||
}
|
||||
return cached.nodes
|
||||
}
|
||||
|
||||
func (a *asyncnodebuffer) getLayers() uint64 {
|
||||
a.mux.RLock()
|
||||
defer a.mux.RUnlock()
|
||||
|
||||
return a.current.layers + a.background.layers
|
||||
}
|
||||
|
||||
func (a *asyncnodebuffer) getSize() (uint64, uint64) {
|
||||
a.mux.RLock()
|
||||
defer a.mux.RUnlock()
|
||||
|
||||
return a.current.size, a.background.size
|
||||
}
|
||||
|
||||
type nodecache struct {
|
||||
layers uint64 // The number of diff layers aggregated inside
|
||||
size uint64 // The size of aggregated writes
|
||||
limit uint64 // The maximum memory allowance in bytes
|
||||
nodes map[common.Hash]map[string]*trienode.Node // The dirty node set, mapped by owner and path
|
||||
immutable uint64 // The flag equal 1, flush nodes to disk background
|
||||
}
|
||||
|
||||
func newNodeCache(limit, size uint64, nodes map[common.Hash]map[string]*trienode.Node, layers uint64) *nodecache {
|
||||
return &nodecache{
|
||||
layers: layers,
|
||||
size: size,
|
||||
limit: limit,
|
||||
nodes: nodes,
|
||||
immutable: 0,
|
||||
}
|
||||
}
|
||||
|
||||
func (nc *nodecache) node(owner common.Hash, path []byte, hash common.Hash) (*trienode.Node, error) {
|
||||
subset, ok := nc.nodes[owner]
|
||||
if !ok {
|
||||
return nil, nil
|
||||
}
|
||||
n, ok := subset[string(path)]
|
||||
if !ok {
|
||||
return nil, nil
|
||||
}
|
||||
if n.Hash != hash {
|
||||
dirtyFalseMeter.Mark(1)
|
||||
log.Error("Unexpected trie node in node buffer", "owner", owner, "path", path, "expect", hash, "got", n.Hash)
|
||||
return nil, newUnexpectedNodeError("dirty", hash, n.Hash, owner, path, n.Blob)
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
func (nc *nodecache) commit(nodes map[common.Hash]map[string]*trienode.Node) error {
|
||||
if atomic.LoadUint64(&nc.immutable) == 1 {
|
||||
return errWriteImmutable
|
||||
}
|
||||
var (
|
||||
delta int64
|
||||
overwrite int64
|
||||
overwriteSize int64
|
||||
)
|
||||
for owner, subset := range nodes {
|
||||
current, exist := nc.nodes[owner]
|
||||
if !exist {
|
||||
// Allocate a new map for the subset instead of claiming it directly
|
||||
// from the passed map to avoid potential concurrent map read/write.
|
||||
// The nodes belong to original diff layer are still accessible even
|
||||
// after merging, thus the ownership of nodes map should still belong
|
||||
// to original layer and any mutation on it should be prevented.
|
||||
current = make(map[string]*trienode.Node)
|
||||
for path, n := range subset {
|
||||
current[path] = n
|
||||
delta += int64(len(n.Blob) + len(path))
|
||||
}
|
||||
nc.nodes[owner] = current
|
||||
continue
|
||||
}
|
||||
for path, n := range subset {
|
||||
if orig, exist := current[path]; !exist {
|
||||
delta += int64(len(n.Blob) + len(path))
|
||||
} else {
|
||||
delta += int64(len(n.Blob) - len(orig.Blob))
|
||||
overwrite++
|
||||
overwriteSize += int64(len(orig.Blob) + len(path))
|
||||
}
|
||||
current[path] = n
|
||||
}
|
||||
nc.nodes[owner] = current
|
||||
}
|
||||
nc.updateSize(delta)
|
||||
nc.layers++
|
||||
gcNodesMeter.Mark(overwrite)
|
||||
gcBytesMeter.Mark(overwriteSize)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (nc *nodecache) updateSize(delta int64) {
|
||||
size := int64(nc.size) + delta
|
||||
if size >= 0 {
|
||||
nc.size = uint64(size)
|
||||
return
|
||||
}
|
||||
s := nc.size
|
||||
nc.size = 0
|
||||
log.Error("Invalid pathdb buffer size", "prev", common.StorageSize(s), "delta", common.StorageSize(delta))
|
||||
}
|
||||
|
||||
func (nc *nodecache) reset() {
|
||||
atomic.StoreUint64(&nc.immutable, 0)
|
||||
nc.layers = 0
|
||||
nc.size = 0
|
||||
nc.nodes = make(map[common.Hash]map[string]*trienode.Node)
|
||||
}
|
||||
|
||||
func (nc *nodecache) empty() bool {
|
||||
return nc.layers == 0
|
||||
}
|
||||
|
||||
func (nc *nodecache) flush(db ethdb.KeyValueStore, clean *fastcache.Cache, id uint64) error {
|
||||
if atomic.LoadUint64(&nc.immutable) != 1 {
|
||||
return errFlushMutable
|
||||
}
|
||||
|
||||
// Ensure the target state id is aligned with the internal counter.
|
||||
head := rawdb.ReadPersistentStateID(db)
|
||||
if head+nc.layers != id {
|
||||
return fmt.Errorf("buffer layers (%d) cannot be applied on top of persisted state id (%d) to reach requested state id (%d)", nc.layers, head, id)
|
||||
}
|
||||
var (
|
||||
start = time.Now()
|
||||
batch = db.NewBatchWithSize(int(float64(nc.size) * DefaultBatchRedundancyRate))
|
||||
)
|
||||
nodes := writeNodes(batch, nc.nodes, clean)
|
||||
rawdb.WritePersistentStateID(batch, id)
|
||||
|
||||
// Flush all mutations in a single batch
|
||||
size := batch.ValueSize()
|
||||
if err := batch.Write(); err != nil {
|
||||
return err
|
||||
}
|
||||
commitBytesMeter.Mark(int64(size))
|
||||
commitNodesMeter.Mark(int64(nodes))
|
||||
commitTimeTimer.UpdateSince(start)
|
||||
log.Debug("Persisted pathdb nodes", "nodes", len(nc.nodes), "bytes", common.StorageSize(size), "elapsed", common.PrettyDuration(time.Since(start)))
|
||||
nc.reset()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (nc *nodecache) merge(nc1 *nodecache) (*nodecache, error) {
|
||||
if nc == nil && nc1 == nil {
|
||||
return nil, nil
|
||||
}
|
||||
if nc == nil || nc.empty() {
|
||||
res := copyNodeCache(nc1)
|
||||
atomic.StoreUint64(&res.immutable, 0)
|
||||
return nc1, nil
|
||||
}
|
||||
if nc1 == nil || nc1.empty() {
|
||||
res := copyNodeCache(nc)
|
||||
atomic.StoreUint64(&res.immutable, 0)
|
||||
return nc, nil
|
||||
}
|
||||
if atomic.LoadUint64(&nc.immutable) == atomic.LoadUint64(&nc1.immutable) {
|
||||
return nil, errIncompatibleMerge
|
||||
}
|
||||
|
||||
var (
|
||||
immutable *nodecache
|
||||
mutable *nodecache
|
||||
res = &nodecache{}
|
||||
)
|
||||
if atomic.LoadUint64(&nc.immutable) == 1 {
|
||||
immutable = nc
|
||||
mutable = nc1
|
||||
} else {
|
||||
immutable = nc1
|
||||
mutable = nc
|
||||
}
|
||||
res.size = immutable.size + mutable.size
|
||||
res.layers = immutable.layers + mutable.layers
|
||||
res.limit = immutable.size
|
||||
res.nodes = make(map[common.Hash]map[string]*trienode.Node)
|
||||
for acc, subTree := range immutable.nodes {
|
||||
if _, ok := res.nodes[acc]; !ok {
|
||||
res.nodes[acc] = make(map[string]*trienode.Node)
|
||||
}
|
||||
for path, node := range subTree {
|
||||
res.nodes[acc][path] = node
|
||||
}
|
||||
}
|
||||
|
||||
for acc, subTree := range mutable.nodes {
|
||||
if _, ok := res.nodes[acc]; !ok {
|
||||
res.nodes[acc] = make(map[string]*trienode.Node)
|
||||
}
|
||||
for path, node := range subTree {
|
||||
res.nodes[acc][path] = node
|
||||
}
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (nc *nodecache) revert(db ethdb.KeyValueReader, nodes map[common.Hash]map[string]*trienode.Node) error {
|
||||
if atomic.LoadUint64(&nc.immutable) == 1 {
|
||||
return errRevertImmutable
|
||||
}
|
||||
|
||||
// Short circuit if no embedded state transition to revert.
|
||||
if nc.layers == 0 {
|
||||
return errStateUnrecoverable
|
||||
}
|
||||
nc.layers--
|
||||
|
||||
// Reset the entire buffer if only a single transition left.
|
||||
if nc.layers == 0 {
|
||||
nc.reset()
|
||||
return nil
|
||||
}
|
||||
var delta int64
|
||||
for owner, subset := range nodes {
|
||||
current, ok := nc.nodes[owner]
|
||||
if !ok {
|
||||
panic(fmt.Sprintf("non-existent subset (%x)", owner))
|
||||
}
|
||||
for path, n := range subset {
|
||||
orig, ok := current[path]
|
||||
if !ok {
|
||||
// There is a special case in MPT that one child is removed from
|
||||
// a fullNode which only has two children, and then a new child
|
||||
// with different position is immediately inserted into the fullNode.
|
||||
// In this case, the clean child of the fullNode will also be
|
||||
// marked as dirty because of node collapse and expansion.
|
||||
//
|
||||
// In case of database rollback, don't panic if this "clean"
|
||||
// node occurs which is not present in buffer.
|
||||
var nhash common.Hash
|
||||
if owner == (common.Hash{}) {
|
||||
_, nhash = rawdb.ReadAccountTrieNode(db, []byte(path))
|
||||
} else {
|
||||
_, nhash = rawdb.ReadStorageTrieNode(db, owner, []byte(path))
|
||||
}
|
||||
// Ignore the clean node in the case described above.
|
||||
if nhash == n.Hash {
|
||||
continue
|
||||
}
|
||||
panic(fmt.Sprintf("non-existent node (%x %v) blob: %v", owner, path, crypto.Keccak256Hash(n.Blob).Hex()))
|
||||
}
|
||||
current[path] = n
|
||||
delta += int64(len(n.Blob)) - int64(len(orig.Blob))
|
||||
}
|
||||
}
|
||||
nc.updateSize(delta)
|
||||
return nil
|
||||
}
|
||||
|
||||
func copyNodeCache(n *nodecache) *nodecache {
|
||||
if n == nil {
|
||||
return nil
|
||||
}
|
||||
nc := &nodecache{
|
||||
layers: n.layers,
|
||||
size: n.size,
|
||||
limit: n.limit,
|
||||
immutable: atomic.LoadUint64(&n.immutable),
|
||||
nodes: make(map[common.Hash]map[string]*trienode.Node),
|
||||
}
|
||||
for acc, subTree := range n.nodes {
|
||||
if _, ok := nc.nodes[acc]; !ok {
|
||||
nc.nodes[acc] = make(map[string]*trienode.Node)
|
||||
}
|
||||
for path, node := range subTree {
|
||||
nc.nodes[acc][path] = node
|
||||
}
|
||||
}
|
||||
return nc
|
||||
}
|
@ -40,18 +40,26 @@ const (
|
||||
// defaultCleanSize is the default memory allowance of clean cache.
|
||||
defaultCleanSize = 16 * 1024 * 1024
|
||||
|
||||
// maxBufferSize is the maximum memory allowance of node buffer.
|
||||
// MaxDirtyBufferSize is the maximum memory allowance of node buffer.
|
||||
// Too large nodebuffer will cause the system to pause for a long
|
||||
// time when write happens. Also, the largest batch that pebble can
|
||||
// support is 4GB, node will panic if batch size exceeds this limit.
|
||||
maxBufferSize = 256 * 1024 * 1024
|
||||
MaxDirtyBufferSize = 256 * 1024 * 1024
|
||||
|
||||
// DefaultBufferSize is the default memory allowance of node buffer
|
||||
// DefaultDirtyBufferSize is the default memory allowance of node buffer
|
||||
// that aggregates the writes from above until it's flushed into the
|
||||
// disk. It's meant to be used once the initial sync is finished.
|
||||
// Do not increase the buffer size arbitrarily, otherwise the system
|
||||
// pause time will increase when the database writes happen.
|
||||
DefaultBufferSize = 64 * 1024 * 1024
|
||||
DefaultDirtyBufferSize = 64 * 1024 * 1024
|
||||
|
||||
// DefaultBackgroundFlushInterval defines the default the wait interval
|
||||
// that background node cache flush disk.
|
||||
DefaultBackgroundFlushInterval = 3
|
||||
|
||||
// DefaultBatchRedundancyRate defines the batch size, compatible write
|
||||
// size calculation is inaccurate
|
||||
DefaultBatchRedundancyRate = 1.1
|
||||
)
|
||||
|
||||
// layer is the interface implemented by all state layers which includes some
|
||||
@ -86,6 +94,7 @@ type layer interface {
|
||||
|
||||
// Config contains the settings for database.
|
||||
type Config struct {
|
||||
SyncFlush bool // Flag of trienodebuffer sync flush cache to disk
|
||||
StateHistory uint64 // Number of recent blocks to maintain state history for
|
||||
CleanCacheSize int // Maximum memory allowance (in bytes) for caching clean nodes
|
||||
DirtyCacheSize int // Maximum memory allowance (in bytes) for caching dirty nodes
|
||||
@ -96,9 +105,9 @@ type Config struct {
|
||||
// unreasonable or unworkable.
|
||||
func (c *Config) sanitize() *Config {
|
||||
conf := *c
|
||||
if conf.DirtyCacheSize > maxBufferSize {
|
||||
log.Warn("Sanitizing invalid node buffer size", "provided", common.StorageSize(conf.DirtyCacheSize), "updated", common.StorageSize(maxBufferSize))
|
||||
conf.DirtyCacheSize = maxBufferSize
|
||||
if conf.DirtyCacheSize > MaxDirtyBufferSize {
|
||||
log.Warn("Sanitizing invalid node buffer size", "provided", common.StorageSize(conf.DirtyCacheSize), "updated", common.StorageSize(MaxDirtyBufferSize))
|
||||
conf.DirtyCacheSize = MaxDirtyBufferSize
|
||||
}
|
||||
return &conf
|
||||
}
|
||||
@ -107,7 +116,7 @@ func (c *Config) sanitize() *Config {
|
||||
var Defaults = &Config{
|
||||
StateHistory: params.FullImmutabilityThreshold,
|
||||
CleanCacheSize: defaultCleanSize,
|
||||
DirtyCacheSize: DefaultBufferSize,
|
||||
DirtyCacheSize: DefaultDirtyBufferSize,
|
||||
}
|
||||
|
||||
// ReadOnly is the config in order to open database in read only mode.
|
||||
@ -180,7 +189,7 @@ func New(diskdb ethdb.Database, config *Config) *Database {
|
||||
log.Warn("Truncated extra state histories", "number", pruned)
|
||||
}
|
||||
}
|
||||
log.Warn("Path-based state scheme is an experimental feature")
|
||||
log.Warn("Path-based state scheme is an experimental feature", "sync", db.config.SyncFlush)
|
||||
return db
|
||||
}
|
||||
|
||||
@ -283,7 +292,7 @@ func (db *Database) Reset(root common.Hash) error {
|
||||
}
|
||||
// Re-construct a new disk layer backed by persistent state
|
||||
// with **empty clean cache and node buffer**.
|
||||
dl := newDiskLayer(root, 0, db, nil, newNodeBuffer(db.bufferSize, nil, 0))
|
||||
dl := newDiskLayer(root, 0, db, nil, NewTrieNodeBuffer(db.config.SyncFlush, db.bufferSize, nil, 0))
|
||||
db.tree.reset(dl)
|
||||
log.Info("Rebuilt trie database", "root", root)
|
||||
return nil
|
||||
@ -384,16 +393,16 @@ func (db *Database) Close() error {
|
||||
|
||||
// Size returns the current storage size of the memory cache in front of the
|
||||
// persistent database layer.
|
||||
func (db *Database) Size() (size common.StorageSize) {
|
||||
func (db *Database) Size() (diffs common.StorageSize, nodes common.StorageSize, immutableNodes common.StorageSize) {
|
||||
db.tree.forEach(func(layer layer) {
|
||||
if diff, ok := layer.(*diffLayer); ok {
|
||||
size += common.StorageSize(diff.memory)
|
||||
diffs += common.StorageSize(diff.memory)
|
||||
}
|
||||
if disk, ok := layer.(*diskLayer); ok {
|
||||
size += disk.size()
|
||||
nodes, immutableNodes = disk.size()
|
||||
}
|
||||
})
|
||||
return size
|
||||
return diffs, nodes, immutableNodes
|
||||
}
|
||||
|
||||
// Initialized returns an indicator if the state data is already
|
||||
@ -413,9 +422,9 @@ func (db *Database) SetBufferSize(size int) error {
|
||||
db.lock.Lock()
|
||||
defer db.lock.Unlock()
|
||||
|
||||
if size > maxBufferSize {
|
||||
log.Info("Capped node buffer size", "provided", common.StorageSize(size), "adjusted", common.StorageSize(maxBufferSize))
|
||||
size = maxBufferSize
|
||||
if size > MaxDirtyBufferSize {
|
||||
log.Info("Capped node buffer size", "provided", common.StorageSize(size), "adjusted", common.StorageSize(MaxDirtyBufferSize))
|
||||
size = MaxDirtyBufferSize
|
||||
}
|
||||
db.bufferSize = size
|
||||
return db.tree.bottom().setBufferSize(db.bufferSize)
|
||||
@ -425,3 +434,10 @@ func (db *Database) SetBufferSize(size int) error {
|
||||
func (db *Database) Scheme() string {
|
||||
return rawdb.PathScheme
|
||||
}
|
||||
|
||||
// Head return the top non-fork difflayer/disklayer root hash for rewinding.
|
||||
func (db *Database) Head() common.Hash {
|
||||
db.lock.Lock()
|
||||
defer db.lock.Unlock()
|
||||
return db.tree.front()
|
||||
}
|
||||
|
@ -96,11 +96,15 @@ type tester struct {
|
||||
snapStorages map[common.Hash]map[common.Hash]map[common.Hash][]byte
|
||||
}
|
||||
|
||||
func newTester(t *testing.T) *tester {
|
||||
func newTester(t *testing.T, historyLimit uint64) *tester {
|
||||
var (
|
||||
disk, _ = rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false, false, false, false)
|
||||
db = New(disk, &Config{CleanCacheSize: 256 * 1024, DirtyCacheSize: 256 * 1024})
|
||||
obj = &tester{
|
||||
db = New(disk, &Config{
|
||||
StateHistory: historyLimit,
|
||||
CleanCacheSize: 256 * 1024,
|
||||
DirtyCacheSize: 256 * 1024,
|
||||
})
|
||||
obj = &tester{
|
||||
db: db,
|
||||
preimages: make(map[common.Hash]common.Address),
|
||||
accounts: make(map[common.Hash][]byte),
|
||||
@ -376,7 +380,7 @@ func (t *tester) bottomIndex() int {
|
||||
|
||||
func TestDatabaseRollback(t *testing.T) {
|
||||
// Verify state histories
|
||||
tester := newTester(t)
|
||||
tester := newTester(t, 0)
|
||||
defer tester.release()
|
||||
|
||||
if err := tester.verifyHistory(); err != nil {
|
||||
@ -402,7 +406,7 @@ func TestDatabaseRollback(t *testing.T) {
|
||||
|
||||
func TestDatabaseRecoverable(t *testing.T) {
|
||||
var (
|
||||
tester = newTester(t)
|
||||
tester = newTester(t, 0)
|
||||
index = tester.bottomIndex()
|
||||
)
|
||||
defer tester.release()
|
||||
@ -441,7 +445,7 @@ func TestDatabaseRecoverable(t *testing.T) {
|
||||
|
||||
func TestReset(t *testing.T) {
|
||||
var (
|
||||
tester = newTester(t)
|
||||
tester = newTester(t, 0)
|
||||
index = tester.bottomIndex()
|
||||
)
|
||||
defer tester.release()
|
||||
@ -475,7 +479,7 @@ func TestReset(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCommit(t *testing.T) {
|
||||
tester := newTester(t)
|
||||
tester := newTester(t, 0)
|
||||
defer tester.release()
|
||||
|
||||
if err := tester.db.Commit(tester.lastHash(), false); err != nil {
|
||||
@ -499,7 +503,7 @@ func TestCommit(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestJournal(t *testing.T) {
|
||||
tester := newTester(t)
|
||||
tester := newTester(t, 0)
|
||||
defer tester.release()
|
||||
|
||||
if err := tester.db.Journal(tester.lastHash()); err != nil {
|
||||
@ -523,7 +527,7 @@ func TestJournal(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCorruptedJournal(t *testing.T) {
|
||||
tester := newTester(t)
|
||||
tester := newTester(t, 0)
|
||||
defer tester.release()
|
||||
|
||||
if err := tester.db.Journal(tester.lastHash()); err != nil {
|
||||
@ -552,6 +556,35 @@ func TestCorruptedJournal(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestTailTruncateHistory function is designed to test a specific edge case where,
|
||||
// when history objects are removed from the end, it should trigger a state flush
|
||||
// if the ID of the new tail object is even higher than the persisted state ID.
|
||||
//
|
||||
// For example, let's say the ID of the persistent state is 10, and the current
|
||||
// history objects range from ID(5) to ID(15). As we accumulate six more objects,
|
||||
// the history will expand to cover ID(11) to ID(21). ID(11) then becomes the
|
||||
// oldest history object, and its ID is even higher than the stored state.
|
||||
//
|
||||
// In this scenario, it is mandatory to update the persistent state before
|
||||
// truncating the tail histories. This ensures that the ID of the persistent state
|
||||
// always falls within the range of [oldest-history-id, latest-history-id].
|
||||
func TestTailTruncateHistory(t *testing.T) {
|
||||
tester := newTester(t, 10)
|
||||
defer tester.release()
|
||||
|
||||
tester.db.Close()
|
||||
tester.db = New(tester.db.diskdb, &Config{StateHistory: 10})
|
||||
|
||||
head, err := tester.db.freezer.Ancients()
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to obtain freezer head")
|
||||
}
|
||||
stored := rawdb.ReadPersistentStateID(tester.db.diskdb)
|
||||
if head != stored {
|
||||
t.Fatalf("Failed to truncate excess history object above, stored: %d, head: %d", stored, head)
|
||||
}
|
||||
}
|
||||
|
||||
// copyAccounts returns a deep-copied account set of the provided one.
|
||||
func copyAccounts(set map[common.Hash][]byte) map[common.Hash][]byte {
|
||||
copied := make(map[common.Hash][]byte, len(set))
|
||||
|
@ -71,7 +71,7 @@ func newDiffLayer(parent layer, root common.Hash, id uint64, block uint64, nodes
|
||||
dirtyWriteMeter.Mark(size)
|
||||
diffLayerNodesMeter.Mark(int64(count))
|
||||
diffLayerBytesMeter.Mark(int64(dl.memory))
|
||||
log.Debug("Created new diff layer", "id", id, "block", block, "nodes", count, "size", common.StorageSize(dl.memory))
|
||||
log.Debug("Created new diff layer", "id", id, "block", block, "nodes", count, "size", common.StorageSize(dl.memory), "root", dl.root)
|
||||
return dl
|
||||
}
|
||||
|
||||
@ -114,7 +114,7 @@ func (dl *diffLayer) node(owner common.Hash, path []byte, hash common.Hash, dept
|
||||
if n.Hash != hash {
|
||||
dirtyFalseMeter.Mark(1)
|
||||
log.Error("Unexpected trie node in diff layer", "owner", owner, "path", path, "expect", hash, "got", n.Hash)
|
||||
return nil, newUnexpectedNodeError("diff", hash, n.Hash, owner, path)
|
||||
return nil, newUnexpectedNodeError("diff", hash, n.Hash, owner, path, n.Blob)
|
||||
}
|
||||
dirtyHitMeter.Mark(1)
|
||||
dirtyNodeHitDepthHist.Update(int64(depth))
|
||||
|
@ -29,7 +29,7 @@ import (
|
||||
func emptyLayer() *diskLayer {
|
||||
return &diskLayer{
|
||||
db: New(rawdb.NewMemoryDatabase(), nil),
|
||||
buffer: newNodeBuffer(DefaultBufferSize, nil, 0),
|
||||
buffer: newNodeBuffer(DefaultDirtyBufferSize, nil, 0),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,25 +25,77 @@ import (
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/trie/trienode"
|
||||
"github.com/ethereum/go-ethereum/trie/triestate"
|
||||
"golang.org/x/crypto/sha3"
|
||||
)
|
||||
|
||||
// trienodebuffer is a collection of modified trie nodes to aggregate the disk
|
||||
// write. The content of the trienodebuffer must be checked before diving into
|
||||
// disk (since it basically is not-yet-written data).
|
||||
type trienodebuffer interface {
|
||||
// node retrieves the trie node with given node info.
|
||||
node(owner common.Hash, path []byte, hash common.Hash) (*trienode.Node, error)
|
||||
|
||||
// commit merges the dirty nodes into the trienodebuffer. This operation won't take
|
||||
// the ownership of the nodes map which belongs to the bottom-most diff layer.
|
||||
// It will just hold the node references from the given map which are safe to
|
||||
// copy.
|
||||
commit(nodes map[common.Hash]map[string]*trienode.Node) trienodebuffer
|
||||
|
||||
// revert is the reverse operation of commit. It also merges the provided nodes
|
||||
// into the trienodebuffer, the difference is that the provided node set should
|
||||
// revert the changes made by the last state transition.
|
||||
revert(db ethdb.KeyValueReader, nodes map[common.Hash]map[string]*trienode.Node) error
|
||||
|
||||
// flush persists the in-memory dirty trie node into the disk if the configured
|
||||
// memory threshold is reached. Note, all data must be written atomically.
|
||||
flush(db ethdb.KeyValueStore, clean *fastcache.Cache, id uint64, force bool) error
|
||||
|
||||
// setSize sets the buffer size to the provided number, and invokes a flush
|
||||
// operation if the current memory usage exceeds the new limit.
|
||||
setSize(size int, db ethdb.KeyValueStore, clean *fastcache.Cache, id uint64) error
|
||||
|
||||
// reset cleans up the disk cache.
|
||||
reset()
|
||||
|
||||
// empty returns an indicator if trienodebuffer contains any state transition inside.
|
||||
empty() bool
|
||||
|
||||
// getSize return the trienodebuffer used size.
|
||||
getSize() (uint64, uint64)
|
||||
|
||||
// getAllNodes return all the trie nodes are cached in trienodebuffer.
|
||||
getAllNodes() map[common.Hash]map[string]*trienode.Node
|
||||
|
||||
// getLayers return the size of cached difflayers.
|
||||
getLayers() uint64
|
||||
}
|
||||
|
||||
func NewTrieNodeBuffer(sync bool, limit int, nodes map[common.Hash]map[string]*trienode.Node, layers uint64) trienodebuffer {
|
||||
if sync {
|
||||
log.Info("new sync node buffer", "limit", common.StorageSize(limit), "layers", layers)
|
||||
return newNodeBuffer(limit, nodes, layers)
|
||||
}
|
||||
log.Info("new async node buffer", "limit", common.StorageSize(limit), "layers", layers)
|
||||
return newAsyncNodeBuffer(limit, nodes, layers)
|
||||
}
|
||||
|
||||
// diskLayer is a low level persistent layer built on top of a key-value store.
|
||||
type diskLayer struct {
|
||||
root common.Hash // Immutable, root hash to which this layer was made for
|
||||
id uint64 // Immutable, corresponding state id
|
||||
db *Database // Path-based trie database
|
||||
cleans *fastcache.Cache // GC friendly memory cache of clean node RLPs
|
||||
buffer *nodebuffer // Node buffer to aggregate writes
|
||||
buffer trienodebuffer // Node buffer to aggregate writes
|
||||
stale bool // Signals that the layer became stale (state progressed)
|
||||
lock sync.RWMutex // Lock used to protect stale flag
|
||||
}
|
||||
|
||||
// newDiskLayer creates a new disk layer based on the passing arguments.
|
||||
func newDiskLayer(root common.Hash, id uint64, db *Database, cleans *fastcache.Cache, buffer *nodebuffer) *diskLayer {
|
||||
func newDiskLayer(root common.Hash, id uint64, db *Database, cleans *fastcache.Cache, buffer trienodebuffer) *diskLayer {
|
||||
// Initialize a clean cache if the memory allowance is not zero
|
||||
// or reuse the provided cache if it is not nil (inherited from
|
||||
// the original disk layer).
|
||||
@ -150,7 +202,7 @@ func (dl *diskLayer) Node(owner common.Hash, path []byte, hash common.Hash) ([]b
|
||||
if nHash != hash {
|
||||
diskFalseMeter.Mark(1)
|
||||
log.Error("Unexpected trie node in disk", "owner", owner, "path", path, "expect", hash, "got", nHash)
|
||||
return nil, newUnexpectedNodeError("disk", hash, nHash, owner, path)
|
||||
return nil, newUnexpectedNodeError("disk", hash, nHash, owner, path, nBlob)
|
||||
}
|
||||
if dl.cleans != nil && len(nBlob) > 0 {
|
||||
dl.cleans.Set(key, nBlob)
|
||||
@ -172,37 +224,65 @@ func (dl *diskLayer) commit(bottom *diffLayer, force bool) (*diskLayer, error) {
|
||||
dl.lock.Lock()
|
||||
defer dl.lock.Unlock()
|
||||
|
||||
// Construct and store the state history first. If crash happens
|
||||
// after storing the state history but without flushing the
|
||||
// corresponding states(journal), the stored state history will
|
||||
// be truncated in the next restart.
|
||||
// Construct and store the state history first. If crash happens after storing
|
||||
// the state history but without flushing the corresponding states(journal),
|
||||
// the stored state history will be truncated from head in the next restart.
|
||||
var (
|
||||
overflow bool
|
||||
oldest uint64
|
||||
)
|
||||
if dl.db.freezer != nil {
|
||||
err := writeHistory(dl.db.diskdb, dl.db.freezer, bottom, dl.db.config.StateHistory)
|
||||
err := writeHistory(dl.db.freezer, bottom)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Determine if the persisted history object has exceeded the configured
|
||||
// limitation, set the overflow as true if so.
|
||||
tail, err := dl.db.freezer.Tail()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
limit := dl.db.config.StateHistory
|
||||
if limit != 0 && bottom.stateID()-tail > limit {
|
||||
overflow = true
|
||||
oldest = bottom.stateID() - limit + 1 // track the id of history **after truncation**
|
||||
}
|
||||
}
|
||||
// Mark the diskLayer as stale before applying any mutations on top.
|
||||
dl.stale = true
|
||||
|
||||
// Store the root->id lookup afterwards. All stored lookups are
|
||||
// identified by the **unique** state root. It's impossible that
|
||||
// in the same chain blocks are not adjacent but have the same
|
||||
// root.
|
||||
// Store the root->id lookup afterwards. All stored lookups are identified
|
||||
// by the **unique** state root. It's impossible that in the same chain
|
||||
// blocks are not adjacent but have the same root.
|
||||
if dl.id == 0 {
|
||||
rawdb.WriteStateID(dl.db.diskdb, dl.root, 0)
|
||||
}
|
||||
rawdb.WriteStateID(dl.db.diskdb, bottom.rootHash(), bottom.stateID())
|
||||
|
||||
// Construct a new disk layer by merging the nodes from the provided
|
||||
// diff layer, and flush the content in disk layer if there are too
|
||||
// many nodes cached. The clean cache is inherited from the original
|
||||
// disk layer for reusing.
|
||||
// Construct a new disk layer by merging the nodes from the provided diff
|
||||
// layer, and flush the content in disk layer if there are too many nodes
|
||||
// cached. The clean cache is inherited from the original disk layer.
|
||||
ndl := newDiskLayer(bottom.root, bottom.stateID(), dl.db, dl.cleans, dl.buffer.commit(bottom.nodes))
|
||||
err := ndl.buffer.flush(ndl.db.diskdb, ndl.cleans, ndl.id, force)
|
||||
if err != nil {
|
||||
|
||||
// In a unique scenario where the ID of the oldest history object (after tail
|
||||
// truncation) surpasses the persisted state ID, we take the necessary action
|
||||
// of forcibly committing the cached dirty nodes to ensure that the persisted
|
||||
// state ID remains higher.
|
||||
if !force && rawdb.ReadPersistentStateID(dl.db.diskdb) < oldest {
|
||||
force = true
|
||||
}
|
||||
if err := ndl.buffer.flush(ndl.db.diskdb, ndl.cleans, ndl.id, force); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// To remove outdated history objects from the end, we set the 'tail' parameter
|
||||
// to 'oldest-1' due to the offset between the freezer index and the history ID.
|
||||
if overflow {
|
||||
pruned, err := truncateFromTail(ndl.db.diskdb, ndl.db.freezer, oldest-1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
log.Debug("Pruned state history", "items", pruned, "tailid", oldest)
|
||||
}
|
||||
return ndl, nil
|
||||
}
|
||||
|
||||
@ -254,7 +334,7 @@ func (dl *diskLayer) revert(h *history, loader triestate.TrieLoader) (*diskLayer
|
||||
return newDiskLayer(h.meta.parent, dl.id-1, dl.db, dl.cleans, dl.buffer), nil
|
||||
}
|
||||
|
||||
// setBufferSize sets the node buffer size to the provided value.
|
||||
// setBufferSize sets the trie node buffer size to the provided value.
|
||||
func (dl *diskLayer) setBufferSize(size int) error {
|
||||
dl.lock.RLock()
|
||||
defer dl.lock.RUnlock()
|
||||
@ -266,14 +346,15 @@ func (dl *diskLayer) setBufferSize(size int) error {
|
||||
}
|
||||
|
||||
// size returns the approximate size of cached nodes in the disk layer.
|
||||
func (dl *diskLayer) size() common.StorageSize {
|
||||
func (dl *diskLayer) size() (common.StorageSize, common.StorageSize) {
|
||||
dl.lock.RLock()
|
||||
defer dl.lock.RUnlock()
|
||||
|
||||
if dl.stale {
|
||||
return 0
|
||||
return 0, 0
|
||||
}
|
||||
return common.StorageSize(dl.buffer.size)
|
||||
dirtyNodes, dirtyimmutableNodes := dl.buffer.getSize()
|
||||
return common.StorageSize(dirtyNodes), common.StorageSize(dirtyimmutableNodes)
|
||||
}
|
||||
|
||||
// resetCache releases the memory held by clean cache to prevent memory leak.
|
||||
|
@ -21,6 +21,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -44,8 +45,26 @@ var (
|
||||
// errUnexpectedNode is returned if the requested node with specified path is
|
||||
// not hash matched with expectation.
|
||||
errUnexpectedNode = errors.New("unexpected node")
|
||||
|
||||
// errWriteImmutable is returned if write to background immutable nodecache
|
||||
// under asyncnodebuffer
|
||||
errWriteImmutable = errors.New("write immutable nodecache")
|
||||
|
||||
// errFlushMutable is returned if flush the background mutable nodecache
|
||||
// to disk, under asyncnodebuffer
|
||||
errFlushMutable = errors.New("flush mutable nodecache")
|
||||
|
||||
// errIncompatibleMerge is returned when merge node cache occurs error.
|
||||
errIncompatibleMerge = errors.New("incompatible nodecache merge")
|
||||
|
||||
// errRevertImmutable is returned if revert the background immutable nodecache
|
||||
errRevertImmutable = errors.New("revert immutable nodecache")
|
||||
)
|
||||
|
||||
func newUnexpectedNodeError(loc string, expHash common.Hash, gotHash common.Hash, owner common.Hash, path []byte) error {
|
||||
return fmt.Errorf("%w, loc: %s, node: (%x %v), %x!=%x", errUnexpectedNode, loc, owner, path, expHash, gotHash)
|
||||
func newUnexpectedNodeError(loc string, expHash common.Hash, gotHash common.Hash, owner common.Hash, path []byte, blob []byte) error {
|
||||
blobHex := "nil"
|
||||
if len(blob) > 0 {
|
||||
blobHex = hexutil.Encode(blob)
|
||||
}
|
||||
return fmt.Errorf("%w, loc: %s, node: (%x %v), %x!=%x, blob: %s", errUnexpectedNode, loc, owner, path, expHash, gotHash, blobHex)
|
||||
}
|
||||
|
@ -512,38 +512,28 @@ func readHistory(freezer *rawdb.ResettableFreezer, id uint64) (*history, error)
|
||||
return &dec, nil
|
||||
}
|
||||
|
||||
// writeHistory writes the state history with provided state set. After
|
||||
// storing the corresponding state history, it will also prune the stale
|
||||
// histories from the disk with the given threshold.
|
||||
func writeHistory(db ethdb.KeyValueStore, freezer *rawdb.ResettableFreezer, dl *diffLayer, limit uint64) error {
|
||||
// writeHistory persists the state history with the provided state set.
|
||||
func writeHistory(freezer *rawdb.ResettableFreezer, dl *diffLayer) error {
|
||||
// Short circuit if state set is not available.
|
||||
if dl.states == nil {
|
||||
return errors.New("state change set is not available")
|
||||
}
|
||||
var (
|
||||
err error
|
||||
n int
|
||||
start = time.Now()
|
||||
h = newHistory(dl.rootHash(), dl.parentLayer().rootHash(), dl.block, dl.states)
|
||||
start = time.Now()
|
||||
history = newHistory(dl.rootHash(), dl.parentLayer().rootHash(), dl.block, dl.states)
|
||||
)
|
||||
accountData, storageData, accountIndex, storageIndex := h.encode()
|
||||
accountData, storageData, accountIndex, storageIndex := history.encode()
|
||||
dataSize := common.StorageSize(len(accountData) + len(storageData))
|
||||
indexSize := common.StorageSize(len(accountIndex) + len(storageIndex))
|
||||
|
||||
// Write history data into five freezer table respectively.
|
||||
rawdb.WriteStateHistory(freezer, dl.stateID(), h.meta.encode(), accountIndex, storageIndex, accountData, storageData)
|
||||
rawdb.WriteStateHistory(freezer, dl.stateID(), history.meta.encode(), accountIndex, storageIndex, accountData, storageData)
|
||||
|
||||
// Prune stale state histories based on the config.
|
||||
if limit != 0 && dl.stateID() > limit {
|
||||
n, err = truncateFromTail(db, freezer, dl.stateID()-limit)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
historyDataBytesMeter.Mark(int64(dataSize))
|
||||
historyIndexBytesMeter.Mark(int64(indexSize))
|
||||
historyBuildTimeMeter.UpdateSince(start)
|
||||
log.Debug("Stored state history", "id", dl.stateID(), "block", dl.block, "data", dataSize, "index", indexSize, "pruned", n, "elapsed", common.PrettyDuration(time.Since(start)))
|
||||
log.Debug("Stored state history", "id", dl.stateID(), "block", dl.block, "data", dataSize, "index", indexSize, "elapsed", common.PrettyDuration(time.Since(start)))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||
@ -129,7 +130,7 @@ func (db *Database) loadLayers() layer {
|
||||
log.Info("Failed to load journal, discard it", "err", err)
|
||||
}
|
||||
// Return single layer with persistent state.
|
||||
return newDiskLayer(root, rawdb.ReadPersistentStateID(db.diskdb), db, nil, newNodeBuffer(db.bufferSize, nil, 0))
|
||||
return newDiskLayer(root, rawdb.ReadPersistentStateID(db.diskdb), db, nil, NewTrieNodeBuffer(db.config.SyncFlush, db.bufferSize, nil, 0))
|
||||
}
|
||||
|
||||
// loadDiskLayer reads the binary blob from the layer journal, reconstructing
|
||||
@ -169,7 +170,7 @@ func (db *Database) loadDiskLayer(r *rlp.Stream) (layer, error) {
|
||||
nodes[entry.Owner] = subset
|
||||
}
|
||||
// Calculate the internal state transitions by id difference.
|
||||
base := newDiskLayer(root, id, db, nil, newNodeBuffer(db.bufferSize, nodes, id-stored))
|
||||
base := newDiskLayer(root, id, db, nil, NewTrieNodeBuffer(db.config.SyncFlush, db.bufferSize, nodes, id-stored))
|
||||
return base, nil
|
||||
}
|
||||
|
||||
@ -259,8 +260,9 @@ func (dl *diskLayer) journal(w io.Writer) error {
|
||||
return err
|
||||
}
|
||||
// Step three, write all unwritten nodes into the journal
|
||||
nodes := make([]journalNodes, 0, len(dl.buffer.nodes))
|
||||
for owner, subset := range dl.buffer.nodes {
|
||||
bufferNodes := dl.buffer.getAllNodes()
|
||||
nodes := make([]journalNodes, 0, len(bufferNodes))
|
||||
for owner, subset := range bufferNodes {
|
||||
entry := journalNodes{Owner: owner}
|
||||
for path, node := range subset {
|
||||
entry.Nodes = append(entry.Nodes, journalNode{Path: []byte(path), Blob: node.Blob})
|
||||
@ -270,7 +272,7 @@ func (dl *diskLayer) journal(w io.Writer) error {
|
||||
if err := rlp.Encode(w, nodes); err != nil {
|
||||
return err
|
||||
}
|
||||
log.Debug("Journaled pathdb disk layer", "root", dl.root, "nodes", len(dl.buffer.nodes))
|
||||
log.Debug("Journaled pathdb disk layer", "root", dl.root, "nodes", len(bufferNodes))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -341,6 +343,14 @@ func (db *Database) Journal(root common.Hash) error {
|
||||
if l == nil {
|
||||
return fmt.Errorf("triedb layer [%#x] missing", root)
|
||||
}
|
||||
disk := db.tree.bottom()
|
||||
if l, ok := l.(*diffLayer); ok {
|
||||
log.Info("Persisting dirty state to disk", "head", l.block, "root", root, "layers", l.id-disk.id+disk.buffer.getLayers())
|
||||
} else { // disk layer only on noop runs (likely) or deep reorgs (unlikely)
|
||||
log.Info("Persisting dirty state to disk", "root", root, "layers", disk.buffer.getLayers())
|
||||
}
|
||||
start := time.Now()
|
||||
|
||||
// Run the journaling
|
||||
db.lock.Lock()
|
||||
defer db.lock.Unlock()
|
||||
@ -373,6 +383,6 @@ func (db *Database) Journal(root common.Hash) error {
|
||||
|
||||
// Set the db in read only mode to reject all following mutations
|
||||
db.readOnly = true
|
||||
log.Info("Stored journal in triedb", "disk", diskroot, "size", common.StorageSize(journal.Len()))
|
||||
log.Info("Persisted dirty state to disk", "size", common.StorageSize(journal.Len()), "elapsed", common.PrettyDuration(time.Since(start)))
|
||||
return nil
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import (
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/trie/trienode"
|
||||
"github.com/ethereum/go-ethereum/trie/triestate"
|
||||
)
|
||||
@ -212,3 +213,46 @@ func (tree *layerTree) bottom() *diskLayer {
|
||||
}
|
||||
return current.(*diskLayer)
|
||||
}
|
||||
|
||||
// front return the top non-fork difflayer/disklayer root hash for rewinding.
|
||||
func (tree *layerTree) front() common.Hash {
|
||||
tree.lock.RLock()
|
||||
defer tree.lock.RUnlock()
|
||||
|
||||
chain := make(map[common.Hash][]common.Hash)
|
||||
var base common.Hash
|
||||
for _, layer := range tree.layers {
|
||||
switch dl := layer.(type) {
|
||||
case *diskLayer:
|
||||
if dl.stale {
|
||||
log.Info("pathdb top disklayer is stale")
|
||||
return base
|
||||
}
|
||||
base = dl.rootHash()
|
||||
case *diffLayer:
|
||||
if _, ok := chain[dl.parentLayer().rootHash()]; !ok {
|
||||
chain[dl.parentLayer().rootHash()] = make([]common.Hash, 0)
|
||||
}
|
||||
chain[dl.parentLayer().rootHash()] = append(chain[dl.parentLayer().rootHash()], dl.rootHash())
|
||||
default:
|
||||
log.Crit("unsupported layer type")
|
||||
}
|
||||
}
|
||||
if (base == common.Hash{}) {
|
||||
log.Info("pathdb top difflayer is empty")
|
||||
return base
|
||||
}
|
||||
parent := base
|
||||
for {
|
||||
children, ok := chain[parent]
|
||||
if !ok {
|
||||
log.Info("pathdb top difflayer", "root", parent)
|
||||
return parent
|
||||
}
|
||||
if len(children) != 1 {
|
||||
log.Info("pathdb top difflayer is forked", "common ancestor root", parent)
|
||||
return parent
|
||||
}
|
||||
parent = children[0]
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,8 @@ import (
|
||||
"github.com/ethereum/go-ethereum/trie/trienode"
|
||||
)
|
||||
|
||||
var _ trienodebuffer = &nodebuffer{}
|
||||
|
||||
// nodebuffer is a collection of modified trie nodes to aggregate the disk
|
||||
// write. The content of the nodebuffer must be checked before diving into
|
||||
// disk (since it basically is not-yet-written data).
|
||||
@ -71,7 +73,7 @@ func (b *nodebuffer) node(owner common.Hash, path []byte, hash common.Hash) (*tr
|
||||
if n.Hash != hash {
|
||||
dirtyFalseMeter.Mark(1)
|
||||
log.Error("Unexpected trie node in node buffer", "owner", owner, "path", path, "expect", hash, "got", n.Hash)
|
||||
return nil, newUnexpectedNodeError("dirty", hash, n.Hash, owner, path)
|
||||
return nil, newUnexpectedNodeError("dirty", hash, n.Hash, owner, path, n.Blob)
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
@ -80,7 +82,7 @@ func (b *nodebuffer) node(owner common.Hash, path []byte, hash common.Hash) (*tr
|
||||
// the ownership of the nodes map which belongs to the bottom-most diff layer.
|
||||
// It will just hold the node references from the given map which are safe to
|
||||
// copy.
|
||||
func (b *nodebuffer) commit(nodes map[common.Hash]map[string]*trienode.Node) *nodebuffer {
|
||||
func (b *nodebuffer) commit(nodes map[common.Hash]map[string]*trienode.Node) trienodebuffer {
|
||||
var (
|
||||
delta int64
|
||||
overwrite int64
|
||||
@ -97,14 +99,14 @@ func (b *nodebuffer) commit(nodes map[common.Hash]map[string]*trienode.Node) *no
|
||||
current = make(map[string]*trienode.Node)
|
||||
for path, n := range subset {
|
||||
current[path] = n
|
||||
delta += int64(len(n.Blob) + len(path))
|
||||
delta += int64(len(n.Blob) + len(path) + len(owner))
|
||||
}
|
||||
b.nodes[owner] = current
|
||||
continue
|
||||
}
|
||||
for path, n := range subset {
|
||||
if orig, exist := current[path]; !exist {
|
||||
delta += int64(len(n.Blob) + len(path))
|
||||
delta += int64(len(n.Blob) + len(path) + len(owner))
|
||||
} else {
|
||||
delta += int64(len(n.Blob) - len(orig.Blob))
|
||||
overwrite++
|
||||
@ -217,7 +219,11 @@ func (b *nodebuffer) flush(db ethdb.KeyValueStore, clean *fastcache.Cache, id ui
|
||||
}
|
||||
var (
|
||||
start = time.Now()
|
||||
batch = db.NewBatchWithSize(int(b.size))
|
||||
// Although the calculation of b.size has been as accurate as possible,
|
||||
// some omissions were still found during testing and code review, but
|
||||
// we are still not sure it is completely accurate. For better protection,
|
||||
// some redundancy is added here.
|
||||
batch = db.NewBatchWithSize(int(float64(b.size) * DefaultBatchRedundancyRate))
|
||||
)
|
||||
nodes := writeNodes(batch, b.nodes, clean)
|
||||
rawdb.WritePersistentStateID(batch, id)
|
||||
@ -273,3 +279,18 @@ func cacheKey(owner common.Hash, path []byte) []byte {
|
||||
}
|
||||
return append(owner.Bytes(), path...)
|
||||
}
|
||||
|
||||
// getSize return the nodebuffer used size.
|
||||
func (b *nodebuffer) getSize() (uint64, uint64) {
|
||||
return b.size, 0
|
||||
}
|
||||
|
||||
// getAllNodes return all the trie nodes are cached in nodebuffer.
|
||||
func (b *nodebuffer) getAllNodes() map[common.Hash]map[string]*trienode.Node {
|
||||
return b.nodes
|
||||
}
|
||||
|
||||
// getLayers return the size of cached difflayers.
|
||||
func (b *nodebuffer) getLayers() uint64 {
|
||||
return b.layers
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user