mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2024-12-31 16:21:21 +00:00
529d359ca6
An update to the devnet to introduce a local heimdall to facilitate multiple validators without the need for an external process, and hence validator registration/staking etc. In this initial release only span generation is supported. It has the following changes: * Introduction of a local grpc heimdall interface * Allocation of accounts via a devnet account generator () * Introduction on 'Services' for the network config "--chain bor-devnet --bor.localheimdall" will run a 2 validator network with a local service "--chain bor-devnet --bor.withoutheimdall" will sun a single validator with no heimdall service as before --------- Co-authored-by: Alex Sharp <alexsharp@Alexs-MacBook-Pro-2.local>
125 lines
2.3 KiB
Go
125 lines
2.3 KiB
Go
package scenarios
|
|
|
|
import (
|
|
"context"
|
|
"sync"
|
|
|
|
"github.com/ledgerwatch/erigon/cmd/devnet/devnetutils"
|
|
)
|
|
|
|
type SimulationInitializer func(*SimulationContext)
|
|
|
|
func Run(ctx context.Context, scenarios ...*Scenario) error {
|
|
if len(scenarios) == 0 {
|
|
return nil
|
|
}
|
|
|
|
return runner{scenarios: scenarios}.runWithOptions(ctx, getDefaultOptions())
|
|
}
|
|
|
|
type runner struct {
|
|
randomize bool
|
|
stopOnFailure bool
|
|
|
|
scenarios []*Scenario
|
|
|
|
simulationInitializer SimulationInitializer
|
|
}
|
|
|
|
func (r *runner) concurrent(ctx context.Context, rate int) (err error) {
|
|
var copyLock sync.Mutex
|
|
|
|
queue := make(chan int, rate)
|
|
scenarios := make([]*Scenario, len(r.scenarios))
|
|
|
|
if r.randomize {
|
|
for i := range r.scenarios {
|
|
j := devnetutils.RandomInt(i + 1)
|
|
scenarios[i] = r.scenarios[j]
|
|
}
|
|
|
|
} else {
|
|
copy(scenarios, r.scenarios)
|
|
}
|
|
|
|
simulationContext := SimulationContext{
|
|
suite: &suite{
|
|
randomize: r.randomize,
|
|
defaultContext: ctx,
|
|
stepRunners: stepRunners(ctx),
|
|
},
|
|
}
|
|
|
|
for i, s := range scenarios {
|
|
scenario := *s
|
|
|
|
queue <- i // reserve space in queue
|
|
|
|
runScenario := func(err *error, Scenario *Scenario) {
|
|
defer func() {
|
|
<-queue // free a space in queue
|
|
}()
|
|
|
|
if r.stopOnFailure && *err != nil {
|
|
return
|
|
}
|
|
|
|
// Copy base suite.
|
|
suite := *simulationContext.suite
|
|
|
|
if r.simulationInitializer != nil {
|
|
sc := SimulationContext{suite: &suite}
|
|
r.simulationInitializer(&sc)
|
|
}
|
|
|
|
_, serr := suite.runScenario(&scenario)
|
|
if suite.shouldFail(serr) {
|
|
copyLock.Lock()
|
|
*err = serr
|
|
copyLock.Unlock()
|
|
}
|
|
}
|
|
|
|
if rate == 1 {
|
|
// Running within the same goroutine for concurrency 1
|
|
// to preserve original stacks and simplify debugging.
|
|
runScenario(&err, &scenario)
|
|
} else {
|
|
go runScenario(&err, &scenario)
|
|
}
|
|
}
|
|
|
|
// wait until last are processed
|
|
for i := 0; i < rate; i++ {
|
|
queue <- i
|
|
}
|
|
|
|
close(queue)
|
|
|
|
return err
|
|
}
|
|
|
|
func (runner runner) runWithOptions(ctx context.Context, opt *Options) error {
|
|
//var output io.Writer = os.Stdout
|
|
//if nil != opt.Output {
|
|
// output = opt.Output
|
|
//}
|
|
|
|
if opt.Concurrency < 1 {
|
|
opt.Concurrency = 1
|
|
}
|
|
|
|
return runner.concurrent(ctx, opt.Concurrency)
|
|
}
|
|
|
|
type Options struct {
|
|
Concurrency int
|
|
}
|
|
|
|
func getDefaultOptions() *Options {
|
|
opt := &Options{
|
|
Concurrency: 1,
|
|
}
|
|
return opt
|
|
}
|