Пример #1
0
// Create and initialize a state object.
func CreateState(messageRouter common.MessageRouter) (s *State, err error) {
	s = new(State)
	// check that we have a non-nil messageSender
	if messageRouter == nil {
		err = fmt.Errorf("Cannot initialize with a nil messageRouter")
		return
	}

	// create a signature keypair for this state
	pubKey, secKey, err := crypto.CreateKeyPair()
	if err != nil {
		return
	}

	// calculate the value of an empty hash (default for storedEntropyStage2 on all hosts is a blank array)
	emptyHash, err := crypto.CalculateTruncatedHash(s.storedEntropyStage2[:])
	if err != nil {
		return
	}

	// set state variables to their defaults
	s.messageRouter = messageRouter
	s.self = new(participant)
	s.self.address = messageRouter.AddMessageHandler(s)
	s.self.publicKey = pubKey
	s.secretKey = secKey
	for i := range s.previousEntropyStage1 {
		s.previousEntropyStage1[i] = emptyHash
	}
	s.participantIndex = 255
	s.currentStep = 1
	s.wallets = make(map[string]uint64)

	return
}
Пример #2
0
// Create and initialize a state object. Set everything to default.
func CreateState(messageRouter common.MessageRouter) (s *State, err error) {
	// check that we have a non-nil messageSender
	if messageRouter == nil {
		err = fmt.Errorf("Cannot initialize with a nil messageRouter")
		return
	}

	// create a signature keypair for this state
	pubKey, secKey, err := crypto.CreateKeyPair()
	if err != nil {
		return
	}

	// initialize State with default values and keypair
	s = &State{
		messageRouter: messageRouter,
		self: &Participant{
			index:     255,
			address:   messageRouter.Address(),
			publicKey: pubKey,
		},
		secretKey:   secKey,
		currentStep: 1,
	}

	// register State and store our assigned ID
	s.self.address.ID = messageRouter.RegisterHandler(s)

	// a call to joinSia() may be placed here... behavior not fully defined
	return
}
Пример #3
0
// 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
}
Пример #4
0
// 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
}