예제 #1
0
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()
}
예제 #2
0
// 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
}
예제 #3
0
// 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
}
예제 #4
0
파일: simul.go 프로젝트: nikirill/cothority
// 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")
	}
}
예제 #5
0
파일: utils.go 프로젝트: nikirill/cothority
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
}
예제 #6
0
파일: ntree.go 프로젝트: nikirill/cothority
// 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)
		}
	}
}
예제 #7
0
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
}
예제 #8
0
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)
}
예제 #9
0
// 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)
}
예제 #10
0
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)
}
예제 #11
0
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
		}
	}
}
예제 #12
0
파일: proxy.go 프로젝트: nikirill/cothority
// 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
}
예제 #13
0
// 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)
	}
}
예제 #14
0
// 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
}
예제 #15
0
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
			}
		}
	}
}
예제 #16
0
// 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
}
예제 #17
0
파일: ntree.go 프로젝트: nikirill/cothority
// 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)
	}
}
예제 #18
0
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
}
예제 #19
0
파일: ntree.go 프로젝트: nikirill/cothority
// 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)
	}

}
예제 #20
0
// 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))
}
예제 #21
0
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)
}
예제 #22
0
// 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()

}
예제 #23
0
// 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
}
예제 #24
0
// 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
		}
	}
}
예제 #25
0
파일: ntree.go 프로젝트: nikirill/cothority
// 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)
		}
	}
}
예제 #26
0
// 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)
}
예제 #27
0
// 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
}
예제 #28
0
파일: pbft.go 프로젝트: nikirill/cothority
// 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{}} }()
}
예제 #29
0
파일: pbft.go 프로젝트: nikirill/cothority
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)
		}
	}
}
예제 #30
0
// 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
}