Skip to content

Commit 47b1f96

Browse files
committed
feat(reexecute): add p-chain
1 parent 22000c2 commit 47b1f96

File tree

1 file changed

+185
-0
lines changed

1 file changed

+185
-0
lines changed
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
// Copyright (C) 2019-2025, Ava Labs, Inc. All rights reserved.
2+
// See the file LICENSE for licensing terms.
3+
4+
package vm
5+
6+
import (
7+
"flag"
8+
"fmt"
9+
"path/filepath"
10+
"testing"
11+
"time"
12+
13+
"github.com/prometheus/client_golang/prometheus"
14+
"github.com/stretchr/testify/require"
15+
"go.uber.org/zap"
16+
17+
"github.com/ava-labs/avalanchego/api/metrics"
18+
"github.com/ava-labs/avalanchego/chains"
19+
"github.com/ava-labs/avalanchego/database/leveldb"
20+
"github.com/ava-labs/avalanchego/genesis"
21+
"github.com/ava-labs/avalanchego/ids"
22+
"github.com/ava-labs/avalanchego/snow/uptime"
23+
"github.com/ava-labs/avalanchego/snow/validators"
24+
"github.com/ava-labs/avalanchego/tests"
25+
"github.com/ava-labs/avalanchego/tests/reexecute"
26+
"github.com/ava-labs/avalanchego/upgrade/upgradetest"
27+
"github.com/ava-labs/avalanchego/utils/constants"
28+
"github.com/ava-labs/avalanchego/vms/platformvm"
29+
"github.com/ava-labs/avalanchego/vms/platformvm/config"
30+
)
31+
32+
var mainnetPChainID = ids.FromStringOrPanic("11111111111111111111111111111111LpoYY")
33+
34+
var (
35+
blockDirArg string
36+
currentStateDirArg string
37+
startBlockArg uint64
38+
endBlockArg uint64
39+
chanSizeArg int
40+
executionTimeout time.Duration
41+
42+
metricsServerEnabledArg bool
43+
metricsServerPortArg uint64
44+
45+
runnerNameArg string
46+
)
47+
48+
func TestMain(m *testing.M) {
49+
flag.StringVar(&blockDirArg, "block-dir", blockDirArg, "Block DB directory to read from during re-execution.")
50+
flag.StringVar(&currentStateDirArg, "current-state-dir", currentStateDirArg, "Current state directory including VM DB and Chain Data Directory for re-execution.")
51+
flag.Uint64Var(&startBlockArg, "start-block", 101, "Start block to begin execution (exclusive).")
52+
flag.Uint64Var(&endBlockArg, "end-block", 200, "End block to end execution (inclusive).")
53+
flag.IntVar(&chanSizeArg, "chan-size", 100, "Size of the channel to use for block processing.")
54+
flag.DurationVar(&executionTimeout, "execution-timeout", 0, "Benchmark execution timeout. After this timeout has elapsed, terminate the benchmark without error. If 0, no timeout is applied.")
55+
56+
flag.BoolVar(&metricsServerEnabledArg, "metrics-server-enabled", false, "Whether to enable the metrics server.")
57+
flag.Uint64Var(&metricsServerPortArg, "metrics-server-port", 0, "The port the metrics server will listen to.")
58+
59+
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.")
60+
61+
m.Run()
62+
}
63+
64+
func BenchmarkReexecuteRange(b *testing.B) {
65+
require.Equalf(b, 1, b.N, "BenchmarkReexecuteRange expects to run a single iteration because it overwrites the input current-state, but found (b.N=%d)", b.N)
66+
b.Run(fmt.Sprintf("[%d,%d]-Runner-%s", startBlockArg, endBlockArg, runnerNameArg), func(b *testing.B) {
67+
benchmarkReexecuteRange(
68+
b,
69+
blockDirArg,
70+
currentStateDirArg,
71+
startBlockArg,
72+
endBlockArg,
73+
chanSizeArg,
74+
metricsServerEnabledArg,
75+
metricsServerPortArg,
76+
)
77+
})
78+
}
79+
80+
func benchmarkReexecuteRange(
81+
b *testing.B,
82+
blockDir string,
83+
currentStateDir string,
84+
startBlock uint64,
85+
endBlock uint64,
86+
chanSize int,
87+
metricsServerEnabled bool,
88+
metricsPort uint64,
89+
) {
90+
r := require.New(b)
91+
ctx := b.Context()
92+
93+
// Create the prefix gatherer passed to the VM and register it with the top-level,
94+
// labeled gatherer.
95+
prefixGatherer := metrics.NewPrefixGatherer()
96+
97+
vmMultiGatherer := metrics.NewPrefixGatherer()
98+
// XXX: find out what the correct P-chain prefix is
99+
r.NoError(prefixGatherer.Register("avalanche_p", vmMultiGatherer))
100+
101+
log := tests.NewDefaultLogger("p-chain-reexecution")
102+
if metricsServerEnabled {
103+
reexecute.StartServer(b, log, prefixGatherer, metricsPort)
104+
}
105+
106+
var (
107+
vmDBDir = filepath.Join(currentStateDir, "db")
108+
chainDataDir = filepath.Join(currentStateDir, "chain-data-dir")
109+
)
110+
111+
log.Info("re-executing block range with params",
112+
zap.String("block-dir", blockDir),
113+
zap.String("vm-db-dir", vmDBDir),
114+
zap.String("chain-data-dir", chainDataDir),
115+
zap.Uint64("start-block", startBlock),
116+
zap.Uint64("end-block", endBlock),
117+
zap.Int("chan-size", chanSize),
118+
)
119+
120+
dbLogger := tests.NewDefaultLogger("db")
121+
122+
db, err := leveldb.New(vmDBDir, nil, dbLogger, prometheus.NewRegistry())
123+
r.NoError(err)
124+
defer func() {
125+
log.Info("shutting down DB")
126+
r.NoError(db.Close())
127+
}()
128+
129+
genesisConfig := genesis.GetConfig(constants.MainnetID)
130+
genesisBytes, _, err := genesis.FromConfig(genesisConfig)
131+
r.NoError(err)
132+
133+
vmParams := reexecute.VMParams{
134+
GenesisBytes: genesisBytes,
135+
SubnetID: constants.PrimaryNetworkID,
136+
ChainID: mainnetPChainID,
137+
}
138+
139+
vm, err := reexecute.NewMainnetVM(
140+
ctx,
141+
&platformvm.Factory{
142+
Internal: mainnetPChainInternalConfig(),
143+
},
144+
db,
145+
chainDataDir,
146+
vmMultiGatherer,
147+
vmParams,
148+
)
149+
r.NoError(err)
150+
defer func() {
151+
log.Info("shutting down VM")
152+
r.NoError(vm.Shutdown(ctx))
153+
}()
154+
155+
executor := reexecute.NewVMExecutor(
156+
b,
157+
vm,
158+
blockDir,
159+
startBlock,
160+
endBlock,
161+
chanSize,
162+
executionTimeout,
163+
prefixGatherer,
164+
)
165+
166+
r.NoError(executor.Run(ctx))
167+
}
168+
169+
func mainnetPChainInternalConfig() config.Internal {
170+
return config.Internal{
171+
Chains: chains.TestManager,
172+
UptimeLockedCalculator: uptime.NewLockedCalculator(),
173+
SybilProtectionEnabled: true,
174+
Validators: validators.NewManager(),
175+
DynamicFeeConfig: genesis.MainnetParams.DynamicFeeConfig,
176+
ValidatorFeeConfig: genesis.MainnetParams.ValidatorFeeConfig,
177+
MinValidatorStake: genesis.MainnetParams.MinValidatorStake,
178+
MaxValidatorStake: genesis.MainnetParams.MaxValidatorStake,
179+
MinDelegatorStake: genesis.MainnetParams.MinDelegatorStake,
180+
MinStakeDuration: genesis.MainnetParams.MinStakeDuration,
181+
MaxStakeDuration: genesis.MainnetParams.MaxStakeDuration,
182+
RewardConfig: genesis.MainnetParams.RewardConfig,
183+
UpgradeConfig: upgradetest.GetConfig(upgradetest.Latest),
184+
}
185+
}

0 commit comments

Comments
 (0)