func (s *simpleService) ProcessClientRequest(e *network.ServerIdentity, r *sda.ClientRequest) { msgT, pm, err := network.UnmarshalRegisteredType(r.Data, network.DefaultConstructors(network.Suite)) log.ErrFatal(err) if msgT != simpleRequestType { return } req := pm.(simpleRequest) tree := req.ServerIdentities.GenerateBinaryTree() tni := s.ctx.NewTreeNodeInstance(tree, tree.Root, "BackForth") proto, err := newBackForthProtocolRoot(tni, req.Val, func(n int) { if err := s.ctx.SendRaw(e, &simpleResponse{ Val: n, }); err != nil { log.Error(err) } }) if err != nil { log.Error(err) return } if err := s.ctx.RegisterProtocolInstance(proto); err != nil { log.Error(err) } go proto.Start() }
// handleCommitChallenge will verify the signature + check if no more than 1/3 // of participants refused to sign. func (bft *ProtocolBFTCoSi) handleChallengeCommit(ch *ChallengeCommit) error { ch.Challenge = bft.commit.Challenge(ch.Challenge) hash := bft.Suite().Hash() hash.Write(bft.Msg) h := hash.Sum(nil) // verify if the signature is correct if err := cosi.VerifyCosiSignatureWithException(bft.suite, bft.AggregatedPublic, h, ch.Signature, ch.Exceptions); err != nil { log.Error(bft.Name(), "Verification of the signature failed:", err) bft.signRefusal = true } // Check if we have no more than 1/3 failed nodes if len(ch.Exceptions) > int(bft.threshold) { log.Errorf("More than 1/3 (%d/%d) refused to sign ! ABORT", len(ch.Exceptions), len(bft.Roster().List)) bft.signRefusal = true } // store the exceptions for later usage bft.tempExceptions = ch.Exceptions log.Lvl4("BFTCoSi handle Challenge COMMIT") if bft.IsLeaf() { return bft.startResponseCommit() } if err := bft.SendToChildrenInParallel(ch); err != nil { log.Error(err) } return nil }
// EndAndCleanup sends a message to end the logging and closes the connection func EndAndCleanup() { if err := send(NewSingleMeasure("end", 0)); err != nil { log.Error("Error while sending 'end' message:", err) } if err := connection.Close(); err != nil { // at least tell that we could not close the connection: log.Error("Could not close connecttion:", err) } encoder = nil }
// RunTest a single test - takes a test-file as a string that will be copied // to the deterlab-server func RunTest(rc platform.RunConfig) (*monitor.Stats, error) { done := make(chan struct{}) CheckHosts(rc) rc.Delete("simulation") rs := monitor.NewStats(rc.Map(), "hosts", "bf") monitor := monitor.NewMonitor(rs) if err := deployP.Deploy(rc); err != nil { log.Error(err) return rs, err } monitor.SinkPort = monitorPort if err := deployP.Cleanup(); err != nil { log.Error(err) return rs, err } monitor.SinkPort = monitorPort go func() { if err := monitor.Listen(); err != nil { log.Fatal("Could not monitor.Listen():", err) } }() // Start monitor before so ssh tunnel can connect to the monitor // in case of deterlab. err := deployP.Start() if err != nil { log.Error(err) return rs, err } go func() { var err error if err = deployP.Wait(); err != nil { log.Lvl3("Test failed:", err) if err := deployP.Cleanup(); err != nil { log.Lvl3("Couldn't cleanup platform:", err) } done <- struct{}{} } log.Lvl3("Test complete:", rs) done <- struct{}{} }() timeOut := getRunWait(rc) // can timeout the command if it takes too long select { case <-done: monitor.Stop() return rs, nil case <-time.After(time.Second * time.Duration(timeOut)): monitor.Stop() return rs, errors.New("Simulation timeout") } }
func GetShaString(data []byte) (res string) { sha := sha256.New() if _, err := sha.Write(data[:]); err != nil { log.Error("Failed to hash data", err) } tmp := sha.Sum(nil) sha.Reset() if _, err := sha.Write(tmp); err != nil { log.Error("Failed to hash data", err) } hash := sha.Sum(nil) res = HashString(hash) return }
// listen will select on the differents channels func (nt *Ntree) listen() { for { select { // Dispatch the block through the whole tree case msg := <-nt.announceChan: log.Lvl3(nt.Name(), "Received Block announcement") nt.block = msg.BlockAnnounce.Block // verify the block go byzcoin.VerifyBlock(nt.block, "", "", nt.verifyBlockChan) if nt.IsLeaf() { nt.startBlockSignature() continue } for _, tn := range nt.Children() { err := nt.SendTo(tn, &msg.BlockAnnounce) if err != nil { log.Error(nt.Name(), "couldn't send to", tn.Name(), err) } } // generate your own signature / exception and pass that up to the // root case msg := <-nt.blockSignatureChan: nt.handleBlockSignature(&msg.NaiveBlockSignature) // Dispatch the signature + expcetion made before through the whole // tree case msg := <-nt.roundSignatureRequestChan: log.Lvl3(nt.Name(), " Signature Request Received") go nt.verifySignatureRequest(&msg.RoundSignatureRequest) if nt.IsLeaf() { nt.startSignatureResponse() continue } for _, tn := range nt.Children() { err := nt.SendTo(tn, &msg.RoundSignatureRequest) if err != nil { log.Error(nt.Name(), "couldn't sent to", tn.Name(), err) } } // Decide if we want to sign this or not case msg := <-nt.roundSignatureResponseChan: nt.handleRoundSignatureResponse(&msg.RoundSignatureResponse) } } }
func (dm *DummyProtocol) Start() error { dm.link <- true if dm.config.Send { if err := dm.SendTo(dm.TreeNode(), &DummyMsg{}); err != nil { log.Error(err) } // also send to the children if any if !dm.IsLeaf() { if err := dm.SendTo(dm.Children()[0], &DummyMsg{}); err != nil { log.Error(err) } } } return nil }
func (tl *TransactionList) HashSum() []byte { h := sha256.New() for _, tx := range tl.Txs { if _, err := h.Write([]byte(tx.Hash)); err != nil { log.Error("Couldn't hash TX list", err) } } if err := binary.Write(h, binary.LittleEndian, tl.TxCnt); err != nil { log.Error("Couldn't hash TX list", err) } if err := binary.Write(h, binary.LittleEndian, tl.Fees); err != nil { log.Error("Couldn't hash TX list", err) } return h.Sum(nil) }
// HashSum returns a hash representation of the header func (h *Header) HashSum() []byte { ha := sha256.New() if _, err := ha.Write([]byte(h.MerkleRoot)); err != nil { log.Error("Couldn't hash header", err) } if _, err := ha.Write([]byte(h.Parent)); err != nil { log.Error("Couldn't hash header", err) } if _, err := ha.Write([]byte(h.ParentKey)); err != nil { log.Error("Couldn't hash header", err) } if _, err := ha.Write([]byte(h.PublicKey)); err != nil { log.Error("Couldn't hash header", err) } return ha.Sum(nil) }
func (bft *ProtocolBFTCoSi) handleResponsePrepare(r *Response) error { // check if we have enough bft.tprMut.Lock() defer bft.tprMut.Unlock() bft.tempPrepareResponse = append(bft.tempPrepareResponse, r.Response) if len(bft.tempPrepareResponse) < len(bft.Children()) { return nil } // wait for verification bzrReturn, ok := bft.waitResponseVerification() if ok { // append response resp, err := bft.prepare.Response(bft.tempPrepareResponse) if err != nil { return err } bzrReturn.Response = resp } log.Lvl4("BFTCoSi Handle Response PREPARE") if bft.IsRoot() { // Notify 'commit'-round as we're root if err := bft.startChallengeCommit(); err != nil { log.Error(err) } return nil } return bft.SendTo(bft.Parent(), bzrReturn) }
func (n *TreeNodeInstance) dispatchMsgReader() { for { n.msgDispatchQueueMutex.Lock() if n.closing == true { log.Lvl3("Closing reader") n.msgDispatchQueueMutex.Unlock() return } if len(n.msgDispatchQueue) > 0 { log.Lvl4(n.Info(), "Read message and dispatching it", len(n.msgDispatchQueue)) msg := n.msgDispatchQueue[0] n.msgDispatchQueue = n.msgDispatchQueue[1:] n.msgDispatchQueueMutex.Unlock() err := n.dispatchMsgToProtocol(msg) if err != nil { log.Error("Error while dispatching message:", err) } } else { n.msgDispatchQueueMutex.Unlock() log.Lvl4(n.Info(), "Waiting for message") <-n.msgDispatchQueueWait } } }
// The core of the file: read any input from the connection and outputs it into // the server connection func proxyConnection(conn net.Conn, done chan bool) { dec := json.NewDecoder(conn) nerr := 0 for { m := SingleMeasure{} // Receive data if err := dec.Decode(&m); err != nil { if err == io.EOF { break } log.Lvl1("Error receiving data from", conn.RemoteAddr().String(), ":", err) nerr++ if nerr > 1 { log.Lvl1("Too many errors from", conn.RemoteAddr().String(), ": Abort connection") break } } log.Lvl3("Proxy received", m) // Proxy data back to monitor if err := serverEnc.Encode(m); err != nil { log.Lvl2("Error proxying data :", err) break } if m.Name == "end" { // the end log.Lvl2("Proxy detected end of measurement. Closing connection.") break } } if err := conn.Close(); err != nil { log.Error("Couldn't close connection:", err) } done <- true }
// ProcessClientRequest takes a request from a client, calculates the reply // and sends it back. func (p *ServiceProcessor) ProcessClientRequest(e *network.ServerIdentity, cr *ClientRequest) { reply := p.GetReply(e, cr.Data) if err := p.SendRaw(e, reply); err != nil { log.Error(err) } }
// Start will execute one cothority-binary for each server // configured func (d *Localhost) Start(args ...string) error { if err := os.Chdir(d.runDir); err != nil { return err } log.Lvl4("Localhost: chdir into", d.runDir) ex := d.runDir + "/" + d.Simulation d.running = true log.Lvl1("Starting", d.servers, "applications of", ex) for index := 0; index < d.servers; index++ { d.wgRun.Add(1) log.Lvl3("Starting", index) host := "localhost" + strconv.Itoa(index) cmdArgs := []string{"-address", host, "-monitor", "localhost:" + strconv.Itoa(d.monitorPort), "-simul", d.Simulation, "-debug", strconv.Itoa(log.DebugVisible()), } cmdArgs = append(args, cmdArgs...) log.Lvl3("CmdArgs are", cmdArgs) cmd := exec.Command(ex, cmdArgs...) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr go func(i int, h string) { log.Lvl3("Localhost: will start host", h) err := cmd.Run() if err != nil { log.Error("Error running localhost", h, ":", err) d.errChan <- err } d.wgRun.Done() log.Lvl3("host (index", i, ")", h, "done") }(index, host) } return nil }
func (sp *BackForthProtocol) dispatch() { for { select { // dispatch the first msg down case m := <-sp.forthChan: msg := &m.SimpleMessageForth for _, ch := range sp.Children() { sp.SendTo(ch, msg) } if sp.IsLeaf() { if err := sp.SendTo(sp.Parent(), &SimpleMessageBack{msg.Val}); err != nil { log.Error(err) } return } // pass the message up case m := <-sp.backChan: msg := m.SimpleMessageBack // call the handler if we are the root sp.counter++ if sp.counter == len(sp.Children()) { if sp.IsRoot() { sp.handler(msg.Val) } else { sp.SendTo(sp.Parent(), &msg) } sp.Done() return } } } }
// Wait for all processes to finish func (d *Localhost) Wait() error { log.Lvl3("Waiting for processes to finish") var err error go func() { d.wgRun.Wait() log.Lvl3("WaitGroup is 0") // write to error channel when done: d.errChan <- nil }() // if one of the hosts fails, stop waiting and return the error: select { case e := <-d.errChan: log.Lvl3("Finished waiting for hosts:", e) if e != nil { if err := d.Cleanup(); err != nil { log.Error("Couldn't cleanup running instances", err) } err = e } } log.Lvl2("Processes finished") return err }
// Start the last phase : send up the final signature func (nt *Ntree) startSignatureResponse() { log.Lvl3(nt.Name(), "Start Signature Response phase") nt.computeSignatureResponse() if err := nt.SendTo(nt.Parent(), nt.tempSignatureResponse); err != nil { log.Error(err) } }
func (c *Client) triggerTransactions(blocksPath string, nTxs int) error { log.Lvl2("ByzCoin Client will trigger up to", nTxs, "transactions") parser, err := blockchain.NewParser(blocksPath, magicNum) if err != nil { log.Error("Error: Couldn't parse blocks in", blocksPath, ".\nPlease download bitcoin blocks as .dat files first and place them in", blocksPath, "Either run a bitcoin node (recommended) or using a torrent.") return err } transactions, err := parser.Parse(0, ReadFirstNBlocks) if err != nil { return fmt.Errorf("Error while parsing transactions %v", err) } if len(transactions) == 0 { return errors.New("Couldn't read any transactions.") } if len(transactions) < nTxs { return fmt.Errorf("Read only %v but caller wanted %v", len(transactions), nTxs) } consumed := nTxs for consumed > 0 { for _, tr := range transactions { // "send" transaction to server (we skip tcp connection on purpose here) c.srv.AddTransaction(tr) } consumed-- } return nil }
// startBlockSignature will send the first signature up the tree. func (nt *Ntree) startBlockSignature() { log.Lvl3(nt.Name(), "Starting Block Signature Phase") nt.computeBlockSignature() if err := nt.SendTo(nt.Parent(), nt.tempBlockSig); err != nil { log.Error(err) } }
// Returns the sytem and the user time so far. func getRTime() (tSys, tUsr float64) { rusage := &syscall.Rusage{} if err := syscall.Getrusage(syscall.RUSAGE_SELF, rusage); err != nil { log.Error("Couldn't get rusage time:", err) } s, u := rusage.Stime, rusage.Utime return iiToF(int64(s.Sec), int64(s.Usec)), iiToF(int64(u.Sec), int64(u.Usec)) }
func HashHeader(h *Header) string { data := fmt.Sprintf("%v", h) sha := sha256.New() if _, err := sha.Write([]byte(data)); err != nil { log.Error("Couldn't hash header:", err) } hash := sha.Sum(nil) return hex.EncodeToString(hash) }
// Stop will close every connections it has // And will stop updating the stats func (m *Monitor) Stop() { log.Lvl2("Monitor Stop") m.listenerLock.Lock() if m.listener != nil { if err := m.listener.Close(); err != nil { log.Error("Couldn't close listener:", err) } } m.listenerLock.Unlock() m.mutexConn.Lock() for _, c := range m.conns { if err := c.Close(); err != nil { log.Error("Couldn't close connection:", err) } } m.mutexConn.Unlock() }
// GetSingleHost returns the 'SingleHost'-flag func (sc SimulationConfig) GetSingleHost() bool { var sh struct{ SingleHost bool } _, err := toml.Decode(sc.Config, &sh) if err != nil { log.Error("Couldn't decode string", sc.Config, "into toml.") return false } return sh.SingleHost }
// Dispatch is an infinite loop to handle messages from channels func (p *ProtocolExampleChannels) Dispatch() error { for { select { case announcement := <-p.ChannelAnnounce: if !p.IsLeaf() { // If we have children, send the same message to all of them for _, c := range p.Children() { err := p.SendTo(c, &announcement.Announce) if err != nil { log.Error(p.Info(), "failed to send to", c.Name(), err) } } } else { // If we're the leaf, start to reply err := p.SendTo(p.Parent(), &Reply{1}) if err != nil { log.Error(p.Info(), "failed to send reply to", p.Parent().Name(), err) } return nil } case reply := <-p.ChannelReply: children := 1 for _, c := range reply { children += c.ChildrenCount } log.Lvl3(p.ServerIdentity().Addresses, "is done with total of", children) if !p.IsRoot() { log.Lvl3("Sending to parent") err := p.SendTo(p.Parent(), &Reply{children}) if err != nil { log.Error(p.Info(), "failed to reply to", p.Parent().Name(), err) } } else { log.Lvl3("Root-node is done - nbr of children found:", children) p.ChildCount <- children } return nil } } }
// startSignatureRequest is the root starting the new phase. It will broadcast // the signature of everyone amongst the tree. func (nt *Ntree) startSignatureRequest(msg *NaiveBlockSignature) { log.Lvl3(nt.Name(), "Start Signature Request") sigRequest := &RoundSignatureRequest{msg} go nt.verifySignatureRequest(sigRequest) for _, tn := range nt.Children() { if err := nt.SendTo(tn, sigRequest); err != nil { log.Error(nt.Name(), "couldn't send to", tn.Name(), err) } } }
// Hash returns a hash representation of the block func (tr *TrBlock) HashSum() []byte { h := sha256.New() if _, err := h.Write(tr.Magic[:]); err != nil { log.Error("Couldn't hash block:", err) } if err := binary.Write(h, binary.LittleEndian, tr.BlockSize); err != nil { log.Error("Couldn't hash block:", err) } if _, err := h.Write([]byte(tr.HeaderHash)); err != nil { log.Error("Couldn't hash block:", err) } if _, err := h.Write(tr.Header.HashSum()); err != nil { log.Error("Couldn't hash block:", err) } if _, err := h.Write(tr.TransactionList.HashSum()); err != nil { log.Error("Couldn't hash block:", err) } return h.Sum(nil) }
// SimulDirToBlockDir creates a path to the 'protocols/byzcoin/block'-dir by // using 'dir' which comes from 'cothority/simul' // If that directory doesn't exist, it will be created. func SimulDirToBlockDir(dir string) string { reg, _ := regexp.Compile("simul/.*") blockDir := string(reg.ReplaceAll([]byte(dir), []byte("protocols/byzcoin/block"))) if _, err := os.Stat(blockDir); os.IsNotExist(err) { if err := os.Mkdir(blockDir, 0777); err != nil { log.Error("Couldn't create blocks directory", err) } } return blockDir }
// finish is called by the root to tell everyone the root is done func (p *Protocol) finish() { p.broadcast(func(tn *sda.TreeNode) { if err := p.SendTo(tn, &Finish{"Finish"}); err != nil { log.Error(p.Name(), "couldn't send 'finish' message to", tn.Name(), err) } }) // notify ourselves go func() { p.finishChan <- finishChan{nil, Finish{}} }() }
func (p *Protocol) handlePrepare(pre *Prepare) { if p.state != statePrepare { //log.Lvl3(p.Name(), "STORE prepare packet: wrong state") p.tempPrepareMsg = append(p.tempPrepareMsg, pre) return } p.prepMsgCount++ //log.Lvl3(p.Name(), "Handle Prepare", p.prepMsgCount, // "msgs and threshold is", p.threshold) var localThreshold = p.threshold // we dont have a "client", the root DONT send any prepare message // so for the rest of the nodes the threshold is less one. if !p.IsRoot() { localThreshold-- } if p.prepMsgCount >= localThreshold { // TRANSITION PREPARE => COMMIT log.Lvl3(p.Name(), "Threshold (", localThreshold, ") reached: broadcast Commit") p.state = stateCommit // reset counter p.prepMsgCount = 0 var err error com := &Commit{pre.HeaderHash} p.broadcast(func(tn *sda.TreeNode) { tempErr := p.SendTo(tn, com) if tempErr != nil { log.Error(p.Name(), "Error while broadcasting Commit =>", tempErr) err = tempErr } }) // Dispatch already the message we received earlier ! go func() { for _, msg := range p.tempCommitMsg { p.commitChan <- commitChan{nil, *msg} } p.tempCommitMsg = nil }() // sends to the channel the already commited messages if err != nil { log.Error("Error while broadcasting Commit msg", err) } } }
// Start sends the Announce message to all children func (p *ProtocolExampleChannels) Start() error { log.Lvl3("Starting ExampleChannels") for _, c := range p.Children() { if err := p.SendTo(c, &Announce{"Example is here"}); err != nil { log.Error(p.Info(), "failed to send Announcment to", c.Name(), err) } } return nil }