aboutsummaryrefslogtreecommitdiffstats
path: root/cmd
diff options
context:
space:
mode:
authorMission Liao <mission.liao@dexon.org>2018-08-21 16:43:37 +0800
committerGitHub <noreply@github.com>2018-08-21 16:43:37 +0800
commit2c816b5d636b8f7decd234582470a3d4c6b4a93a (patch)
tree5eff9d5f035dda8e3b2632ecce41f3c192e90f21 /cmd
parente8f99372159a89fb3128b870de1733a4777a5144 (diff)
downloaddexon-consensus-2c816b5d636b8f7decd234582470a3d4c6b4a93a.tar
dexon-consensus-2c816b5d636b8f7decd234582470a3d4c6b4a93a.tar.gz
dexon-consensus-2c816b5d636b8f7decd234582470a3d4c6b4a93a.tar.bz2
dexon-consensus-2c816b5d636b8f7decd234582470a3d4c6b4a93a.tar.lz
dexon-consensus-2c816b5d636b8f7decd234582470a3d4c6b4a93a.tar.xz
dexon-consensus-2c816b5d636b8f7decd234582470a3d4c6b4a93a.tar.zst
dexon-consensus-2c816b5d636b8f7decd234582470a3d4c6b4a93a.zip
simulation: add simulation with scheduler (#71)
- Add new field in test.Event: HistoryIndex HistoryIndex allow us to access them by their position in event history. - Record local time in test.App when receiving events. - Add statisitics module for slices of test.Event. - add new command line utility *dexcon-simulation-with-scheduler to verify the execution time of core.Consensus.
Diffstat (limited to 'cmd')
-rw-r--r--cmd/dexcon-simulation-with-scheduler/main.go100
1 files changed, 100 insertions, 0 deletions
diff --git a/cmd/dexcon-simulation-with-scheduler/main.go b/cmd/dexcon-simulation-with-scheduler/main.go
new file mode 100644
index 0000000..3ed71c3
--- /dev/null
+++ b/cmd/dexcon-simulation-with-scheduler/main.go
@@ -0,0 +1,100 @@
+package main
+
+import (
+ "flag"
+ "log"
+ "math"
+ "math/rand"
+ "os"
+ "runtime"
+ "runtime/pprof"
+ "time"
+
+ "github.com/dexon-foundation/dexon-consensus-core/core/test"
+ integration "github.com/dexon-foundation/dexon-consensus-core/integration_test"
+ "github.com/dexon-foundation/dexon-consensus-core/simulation/config"
+)
+
+var (
+ configFile = flag.String("config", "", "path to simulation config file")
+ cpuprofile = flag.String("cpuprofile", "", "write cpu profile to `file`")
+ memprofile = flag.String("memprofile", "", "write memory profile to `file`")
+ workerCount = flag.Int("workercount", 1, "count of concurrent workers")
+)
+
+func main() {
+ flag.Parse()
+ rand.Seed(time.Now().UnixNano())
+
+ if *configFile == "" {
+ log.Fatal("error: no configuration file specified")
+ }
+ if *cpuprofile != "" {
+ f, err := os.Create(*cpuprofile)
+ if err != nil {
+ log.Fatal("could not create CPU profile: ", err)
+ }
+ if err := pprof.StartCPUProfile(f); err != nil {
+ log.Fatal("could not start CPU profile: ", err)
+ }
+ defer pprof.StopCPUProfile()
+ }
+
+ cfg, err := config.Read(*configFile)
+ if err != nil {
+ log.Fatal("unable to read config: ", err)
+ }
+ // Setup latencies, validators.
+ networkLatency := &integration.NormalLatencyModel{
+ Sigma: cfg.Networking.Sigma,
+ Mean: cfg.Networking.Mean,
+ }
+ proposingLatency := &integration.NormalLatencyModel{
+ Sigma: cfg.Validator.ProposeIntervalSigma,
+ Mean: cfg.Validator.ProposeIntervalMean,
+ }
+ // Setup validators and other consensus related stuffs.
+ apps, dbs, validators, err := integration.PrepareValidators(
+ cfg.Validator.Num, networkLatency, proposingLatency)
+ if err != nil {
+ log.Fatal("could not setup validators: ", err)
+ }
+ blockPerValidator := int(math.Ceil(
+ float64(cfg.Validator.MaxBlock) / float64(cfg.Validator.Num)))
+ sch := test.NewScheduler(
+ test.NewStopByConfirmedBlocks(blockPerValidator, apps, dbs))
+ for vID, v := range validators {
+ sch.RegisterEventHandler(vID, v)
+ if err = sch.Seed(integration.NewProposeBlockEvent(
+ vID, time.Now().UTC())); err != nil {
+
+ log.Fatal("unable to set seed simulation events: ", err)
+ }
+ }
+ // Run the simulation.
+ sch.Run(*workerCount)
+ if err = integration.VerifyApps(apps); err != nil {
+ log.Fatal("consensus result is not incorrect: ", err)
+ }
+ // Prepare statistics.
+ stats, err := integration.NewStats(sch.CloneExecutionHistory(), apps)
+ if err != nil {
+ log.Fatal("could not generate statistics: ", err)
+ }
+ if *memprofile != "" {
+ f, err := os.Create(*memprofile)
+ if err != nil {
+ log.Fatal("could not create memory profile: ", err)
+ }
+ runtime.GC() // get up-to-date statistics
+ if err := pprof.WriteHeapProfile(f); err != nil {
+ log.Fatal("could not write memory profile: ", err)
+ }
+ f.Close()
+ }
+
+ log.Printf("BPS: %v\n", stats.BPS)
+ log.Printf("ExecutionTime: %v\n", stats.ExecutionTime)
+ log.Printf("Prepare: %v\n", time.Duration(stats.All.PrepareExecLatency))
+ log.Printf("Process: %v\n", time.Duration(stats.All.ProcessExecLatency))
+}