func (tfh *TestFileHandler) HandleMessage(payload []byte) { m := new(common.Message) m.Destination = tfh.dest m.Payload = []byte(tfh.data) tfh.tcpServ.SendMessage(m) tfh.done <- true }
// Announce ourself to the bootstrap address, who will announce us to the quorum func (s *State) JoinSia() (err error) { // Send join message to bootstrap address m := new(common.Message) m.Destination.Id = bootstrapId m.Destination.Host = bootstrapHost m.Destination.Port = bootstrapPort m.Payload = append([]byte(string(joinSia)), s.self.marshal()...) err = s.messageRouter.SendMessage(m) return }
// Takes a payload and sends it in a message to every participant in the quorum func (s *State) broadcast(payload []byte) { s.participantsLock.RLock() for i := range s.participants { if s.participants[i] != nil { m := new(common.Message) m.Payload = payload m.Destination = s.participants[i].address err := s.messageRouter.SendMessage(m) if err != nil { log.Errorln("messageSender returning an error") } } } s.participantsLock.RUnlock() }
// DownloadFile retrieves the erasure-coded segments corresponding to a given file from a quorum. // It reconstructs the original file from the segments using erasure.RebuildSector(). func DownloadFile(mr common.MessageRouter, fileHash crypto.Hash, length int, k int, quorum [common.QuorumSize]common.Address) (fileData []byte, err error) { // spawn a separate thread for each segment for i := range quorum { go func() { // send request m := new(common.Message) m.Destination = quorum[i] m.Payload = []byte{0x01} m.Payload = append(m.Payload, fileHash[:]...) mr.SendMessage(m) // wait for response }() } return }
// TestTCPDownloadFile tests the NewTCPServer and DownloadFile functions. // NewTCPServer must properly initialize a TCP server. // UploadFile splits a file into erasure-coded segments and distributes them across a quorum. // k is the number of non-redundant segments. // The file is padded to satisfy the erasure-coding requirements that: // len(fileData) = k*bytesPerSegment, and: // bytesPerSegment % 64 = 0 func UploadFile(mr common.MessageRouter, file *os.File, k int, quorum [common.QuorumSize]common.Address) (bytesPerSegment int, err error) { // read file fileInfo, err := file.Stat() if err != nil { return } if fileInfo.Size() > int64(common.QuorumSize*common.MaxSegmentSize) { err = fmt.Errorf("File exceeds maximum per-quorum size") return } fileData := make([]byte, fileInfo.Size()) _, err = io.ReadFull(file, fileData) if err != nil { return } // calculate EncodeRing parameters, padding file if necessary bytesPerSegment = len(fileData) / k if bytesPerSegment%64 != 0 { bytesPerSegment += 64 - (bytesPerSegment % 64) padding := k*bytesPerSegment - len(fileData) fileData = append(fileData, bytes.Repeat([]byte{0x00}, padding)...) } // create erasure-coded segments segments, err := erasure.EncodeRing(k, bytesPerSegment, fileData) if err != nil { return } // for now we just send segment i to node i // this may need to be randomized for security for i := range quorum { m := new(common.Message) m.Destination = quorum[i] m.Payload = append([]byte{byte(i)}, []byte(segments[i])...) err = mr.SendMessage(m) if err != nil { return } } return }
func (s *State) announceSignedHeartbeat(sh *signedHeartbeat) { for i := range s.participants { if s.participants[i] != nil { payload, err := sh.marshal() if err != nil { log.Fatalln(err) } m := new(common.Message) m.Payload = append([]byte{byte(1)}, payload...) m.Destination = s.participants[i].Address //time.Sleep(time.Millisecond) // prevents panics. No idea where original source of bug is. err = s.messageSender.SendMessage(m) if err != nil { log.Fatalln("Error while sending message") } } } }
// Add a participant to the state, tell the participant about ourselves func (s *State) addNewParticipant(payload []byte) { // extract index and participant object from payload participantIndex := payload[0] p, err := unmarshalParticipant(payload[1:]) if err != nil { return } // for this participant, make the heartbeat map and add the default heartbeat hb := new(heartbeat) emptyHash, err := crypto.CalculateTruncatedHash(hb.entropyStage2[:]) hb.entropyStage1 = emptyHash s.heartbeatsLock.Lock() s.participantsLock.Lock() s.heartbeats[participantIndex] = make(map[crypto.TruncatedHash]*heartbeat) s.heartbeats[participantIndex][emptyHash] = hb s.heartbeatsLock.Unlock() if *p == *s.self { // add our self object to the correct index in participants s.participants[participantIndex] = s.self s.tickingLock.Lock() s.ticking = true s.tickingLock.Unlock() go s.tick() } else { // add the participant to participants s.participants[participantIndex] = p // tell the new guy about ourselves m := new(common.Message) m.Destination = p.address m.Payload = append([]byte(string(newParticipant)), s.self.marshal()...) s.messageRouter.SendMessage(m) } s.participantsLock.Unlock() }
func (a *Announce) SendOutAnnounce(recipients []*Participant) error { //TODO Add code to actually send out to participants when it works. server, err := network.NewTCPServer(7777) if err != nil { log.Fatal("TCP Server not initialized") } for _, i := range recipients { s, err := json.Marshal(a) s = []byte(string(rune(0)) + string(s)) if err != nil { log.Fatal(err) } c := new(common.Message) c.Payload = s c.Destination = i.Address err = server.SendMessage(c) if err != nil { log.Fatal(err) } } return nil }