Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ tasks:
START_BLOCK: '{{.START_BLOCK}}'
END_BLOCK: '{{.END_BLOCK}}'
cmds:
- cmd: go test -timeout=0 -run=TestExportBlockRange github.com/ava-labs/avalanchego/tests/reexecute/c --block-dir-src={{.BLOCK_DIR_SRC}} --block-dir-dst={{.BLOCK_DIR_DST}} --start-block={{.START_BLOCK}} --end-block={{.END_BLOCK}}
- cmd: go run github.com/ava-labs/avalanchego/tests/reexecute/blockexport --block-dir-src={{.BLOCK_DIR_SRC}} --block-dir-dst={{.BLOCK_DIR_DST}} --start-block={{.START_BLOCK}} --end-block={{.END_BLOCK}}

export-dir-to-s3:
desc: Copies a directory to s3
Expand Down
69 changes: 69 additions & 0 deletions tests/reexecute/blockexport/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Copyright (C) 2019-2025, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package main

import (
"flag"

"github.com/prometheus/client_golang/prometheus"
"github.com/stretchr/testify/require"

"github.com/ava-labs/avalanchego/database/leveldb"
"github.com/ava-labs/avalanchego/tests"
"github.com/ava-labs/avalanchego/tests/reexecute"
"github.com/ava-labs/avalanchego/utils/logging"
"github.com/ava-labs/avalanchego/utils/units"
)

var (
blockDirSrcArg string
blockDirDstArg string
startBlockArg uint64
endBlockArg uint64
)

func init() {
flag.StringVar(&blockDirSrcArg, "block-dir-src", blockDirSrcArg, "Source block directory to copy from.")
flag.StringVar(&blockDirDstArg, "block-dir-dst", blockDirDstArg, "Destination block directory to write blocks into.")
flag.Uint64Var(&startBlockArg, "start-block", 101, "Start block to begin execution (exclusive).")
flag.Uint64Var(&endBlockArg, "end-block", 200, "End block to end execution (inclusive).")

flag.Parse()
}

func main() {
tc := tests.NewTestContext(tests.NewDefaultLogger(""))
defer tc.RecoverAndExit()

r := require.New(tc)

chanSize := 100
blockChan, err := reexecute.CreateBlockChanFromLevelDB(
tc,
blockDirSrcArg,
startBlockArg,
endBlockArg,
chanSize,
tc.DeferCleanup,
)
r.NoError(err)

db, err := leveldb.New(blockDirDstArg, nil, logging.NoLog{}, prometheus.NewRegistry())
r.NoError(err)
tc.DeferCleanup(func() {
r.NoError(db.Close())
})

batch := db.NewBatch()
for blkResult := range blockChan {
r.NoError(batch.Put(reexecute.BlockKey(blkResult.Height), blkResult.BlockBytes))

if batch.Size() > 10*units.MiB {
r.NoError(batch.Write())
batch = db.NewBatch()
}
}

r.NoError(batch.Write())
}
37 changes: 1 addition & 36 deletions tests/reexecute/c/vm_reexecute_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ import (
"github.com/ava-labs/avalanchego/utils/crypto/bls/signer/localsigner"
"github.com/ava-labs/avalanchego/utils/logging"
"github.com/ava-labs/avalanchego/utils/timer"
"github.com/ava-labs/avalanchego/utils/units"
"github.com/ava-labs/avalanchego/vms/metervm"
"github.com/ava-labs/avalanchego/vms/platformvm/warp"
)
Expand All @@ -55,8 +54,6 @@ var (

var (
blockDirArg string
blockDirSrcArg string
blockDirDstArg string
currentStateDirArg string
startBlockArg uint64
endBlockArg uint64
Expand Down Expand Up @@ -122,10 +119,6 @@ func TestMain(m *testing.M) {
flag.StringVar(&configNameArg, configKey, defaultConfigKey, fmt.Sprintf("Specifies the predefined config to use for the VM. Options include %s.", predefinedConfigOptionsStr))
flag.StringVar(&runnerNameArg, "runner", "dev", "Name of the runner executing this test. Added as a metric label and to the sub-benchmark's name to differentiate results on the runner key.")

// Flags specific to TestExportBlockRange.
flag.StringVar(&blockDirSrcArg, "block-dir-src", blockDirSrcArg, "Source block directory to copy from when running TestExportBlockRange.")
flag.StringVar(&blockDirDstArg, "block-dir-dst", blockDirDstArg, "Destination block directory to write blocks into when executing TestExportBlockRange.")

flag.Parse()

if metricsCollectorEnabledArg {
Expand Down Expand Up @@ -232,7 +225,7 @@ func benchmarkReexecuteRange(
zap.Int("chan-size", chanSize),
)

blockChan, err := reexecute.CreateBlockChanFromLevelDB(b, blockDir, startBlock, endBlock, chanSize)
blockChan, err := reexecute.CreateBlockChanFromLevelDB(b, blockDir, startBlock, endBlock, chanSize, b.Cleanup)
r.NoError(err)

dbLogger := tests.NewDefaultLogger("db")
Expand Down Expand Up @@ -477,34 +470,6 @@ func (e *vmExecutor) executeSequence(ctx context.Context, blkChan <-chan reexecu
return nil
}

func TestExportBlockRange(t *testing.T) {
exportBlockRange(t, blockDirSrcArg, blockDirDstArg, startBlockArg, endBlockArg, chanSizeArg)
}

func exportBlockRange(tb testing.TB, blockDirSrc string, blockDirDst string, startBlock, endBlock uint64, chanSize int) {
r := require.New(tb)
blockChan, err := reexecute.CreateBlockChanFromLevelDB(tb, blockDirSrc, startBlock, endBlock, chanSize)
r.NoError(err)

db, err := leveldb.New(blockDirDst, nil, logging.NoLog{}, prometheus.NewRegistry())
r.NoError(err)
tb.Cleanup(func() {
r.NoError(db.Close())
})

batch := db.NewBatch()
for blkResult := range blockChan {
r.NoError(batch.Put(reexecute.BlockKey(blkResult.Height), blkResult.BlockBytes))

if batch.Size() > 10*units.MiB {
r.NoError(batch.Write())
batch = db.NewBatch()
}
}

r.NoError(batch.Write())
}

type consensusMetrics struct {
lastAcceptedHeight prometheus.Gauge
}
Expand Down
10 changes: 6 additions & 4 deletions tests/reexecute/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ package reexecute
import (
"encoding/binary"
"fmt"
"testing"

"github.com/prometheus/client_golang/prometheus"
"github.com/stretchr/testify/require"
Expand All @@ -28,16 +27,19 @@ type BlockResult struct {
// It opens the database at sourceDir and iterates through blocks from startBlock to endBlock (inclusive).
// Blocks are read sequentially and sent to the returned channel as BlockResult values.
//
// cleanup is a function that registers cleanup callbacks and is used to ensure
// that the database being read from is properly closed prior to the test terminating.
//
// Any validation errors or iteration errors are sent as BlockResult with Err set, then the channel is closed.
func CreateBlockChanFromLevelDB(tb testing.TB, sourceDir string, startBlock, endBlock uint64, chanSize int) (<-chan BlockResult, error) {
r := require.New(tb)
func CreateBlockChanFromLevelDB(t require.TestingT, sourceDir string, startBlock, endBlock uint64, chanSize int, cleanup func(func())) (<-chan BlockResult, error) {
r := require.New(t)
ch := make(chan BlockResult, chanSize)

db, err := leveldb.New(sourceDir, nil, logging.NoLog{}, prometheus.NewRegistry())
if err != nil {
return nil, fmt.Errorf("failed to create leveldb database from %q: %w", sourceDir, err)
}
tb.Cleanup(func() {
cleanup(func() {
r.NoError(db.Close())
})

Expand Down