func runTCPTimestampFromConfig(RoundsPerView int, signType, nMessages, nClients, nRounds, failureRate int, faultyNodes ...int) error { var hc *oldconfig.HostConfig var err error oldconfig.StartConfigPort += 2010 // load config with faulty or healthy hosts if len(faultyNodes) > 0 { hc, err = oldconfig.LoadConfig("../test/data/extcpconf.json", oldconfig.ConfigOptions{ConnType: "tcp", GenHosts: true, Faulty: true}) } else { hc, err = oldconfig.LoadConfig("../test/data/extcpconf.json", oldconfig.ConfigOptions{ConnType: "tcp", GenHosts: true}) } if err != nil { return err } // set FailureRates if len(faultyNodes) > 0 { for i := range hc.SNodes { hc.SNodes[i].FailureRate = failureRate } } for _, n := range hc.SNodes { n.RoundsPerView = RoundsPerView } err = hc.Run(true, sign.Type(signType)) if err != nil { return err } stampers, clients, err := hc.RunTimestamper(nClients) if err != nil { return err } for _, s := range stampers[1:] { go s.Run("regular", nRounds) } go stampers[0].Run("root", nRounds) log.Println("About to start sending client messages") for r := 1; r <= nRounds; r++ { var wg sync.WaitGroup for _, c := range clients { for i := 0; i < nMessages; i++ { messg := []byte("messg:" + strconv.Itoa(r) + "." + strconv.Itoa(i)) wg.Add(1) // CLIENT SENDING go func(c *stamp.Client, messg []byte, i int) { defer wg.Done() server := "NO VALID SERVER" retry: c.Mux.Lock() for k := range c.Servers { server = k break } c.Mux.Unlock() log.Infoln("timestamping") err := c.TimeStamp(messg, server) if err == stamp.ErrClientToTSTimeout { log.Errorln(err) return } if err != nil { time.Sleep(1 * time.Second) fmt.Println("retyring because err:", err) goto retry } log.Infoln("timestamped") }(c, messg, r) } } // wait between rounds wg.Wait() log.Println("done with round:", r, " of ", nRounds) } // give it some time before closing the connections // so that no essential messages are denied passing through the network time.Sleep(1 * time.Second) for _, h := range hc.SNodes { h.Close() } for _, c := range clients { c.Close() } return nil }
func Run(hostname, cfg, app string, rounds int, rootwait int, debug, testConnect bool, failureRate, rFail, fFail int, logger, suite string) { if debug { coco.DEBUG = true } // fmt.Println("EXEC TIMESTAMPER: " + hostname) if hostname == "" { fmt.Println("hostname is empty") log.Fatal("no hostname given") } // load the configuration //log.Println("loading configuration") var hc *oldconfig.HostConfig var err error s := GetSuite(suite) opts := oldconfig.ConfigOptions{ConnType: "tcp", Host: hostname, Suite: s} if failureRate > 0 || fFail > 0 { opts.Faulty = true } hc, err = oldconfig.LoadConfig(cfg, opts) if err != nil { fmt.Println(err) log.Fatal(err) } // set FailureRates if failureRate > 0 { for i := range hc.SNodes { hc.SNodes[i].FailureRate = failureRate } } // set root failures if rFail > 0 { for i := range hc.SNodes { hc.SNodes[i].FailAsRootEvery = rFail } } // set follower failures // a follower fails on %ffail round with failureRate probability for i := range hc.SNodes { hc.SNodes[i].FailAsFollowerEvery = fFail } // run this specific host // log.Println("RUNNING HOST CONFIG") err = hc.Run(app != "sign", sign.MerkleTree, hostname) if err != nil { log.Fatal(err) } defer func(sn *sign.Node) { log.Panicln("program has terminated:", hostname) sn.Close() }(hc.SNodes[0]) if app == "sign" { //log.Println("RUNNING Node") // if I am root do the announcement message if hc.SNodes[0].IsRoot(0) { time.Sleep(3 * time.Second) start := time.Now() iters := 10 for i := 0; i < iters; i++ { start = time.Now() //fmt.Println("ANNOUNCING") hc.SNodes[0].LogTest = []byte("Hello World") err = hc.SNodes[0].Announce(0, &sign.AnnouncementMessage{ LogTest: hc.SNodes[0].LogTest, Round: i}) if err != nil { log.Println(err) } elapsed := time.Since(start) log.WithFields(log.Fields{ "file": logutils.File(), "type": "root_announce", "round": i, "time": elapsed, }).Info("") } } else { // otherwise wait a little bit (hopefully it finishes by the end of this) time.Sleep(30 * time.Second) } } else if app == "stamp" || app == "vote" { // log.Println("RUNNING TIMESTAMPER") stampers, _, err := hc.RunTimestamper(0, hostname) // get rid of the hc information so it can be GC'ed hc = nil if err != nil { log.Fatal(err) } for _, s := range stampers { // only listen if this is the hostname specified if s.Name() == hostname { s.Logger = logger s.Hostname = hostname s.App = app if s.IsRoot(0) { log.Println("RUNNING ROOT SERVER AT:", hostname, rounds) log.Printf("Waiting: %d s\n", rootwait) // wait for the other nodes to get set up time.Sleep(time.Duration(rootwait) * time.Second) log.Println("STARTING ROOT ROUND") s.Run("root", rounds) // log.Println("\n\nROOT DONE\n\n") } else if !testConnect { log.Println("RUNNING REGULAR AT:", hostname) s.Run("regular", rounds) // log.Println("\n\nREGULAR DONE\n\n") } else { // testing connection log.Println("RUNNING TEST_CONNNECT AT:", hostname) s.Run("test_connect", rounds) } } } } }