Example #1
0
// loadSharedFiles reads .sia data from reader and registers the contained
// files in the renter. It returns the nicknames of the loaded files.
func (r *Renter) loadSharedFiles(reader io.Reader) ([]string, error) {
	// read header
	var header [15]byte
	var version string
	var numFiles uint64
	err := encoding.NewDecoder(reader).DecodeAll(
		&header,
		&version,
		&numFiles,
	)
	if err != nil {
		return nil, err
	} else if header != shareHeader {
		return nil, ErrBadFile
	} else if version != shareVersion {
		return nil, ErrIncompatible
	}

	// Create decompressor.
	unzip, err := gzip.NewReader(reader)
	if err != nil {
		return nil, err
	}
	dec := encoding.NewDecoder(unzip)

	// Read each file.
	files := make([]*file, numFiles)
	for i := range files {
		files[i] = new(file)
		err := dec.Decode(files[i])
		if err != nil {
			return nil, err
		}

		// Make sure the file's name does not conflict with existing files.
		dupCount := 0
		origName := files[i].name
		for {
			_, exists := r.files[files[i].name]
			if !exists {
				break
			}
			dupCount++
			files[i].name = origName + "_" + strconv.Itoa(dupCount)
		}
	}

	// Add files to renter.
	names := make([]string, numFiles)
	for i, f := range files {
		r.files[f.name] = f
		names[i] = f.name
	}
	// Save the files.
	for _, f := range files {
		r.saveFile(f)
	}

	return names, nil
}
Example #2
0
// DecodeAnnouncement decodes announcement bytes into a host announcement,
// verifying the prefix and the signature.
func DecodeAnnouncement(fullAnnouncement []byte) (na NetAddress, spk types.SiaPublicKey, err error) {
	// Read the first part of the announcement to get the intended host
	// announcement.
	var ha HostAnnouncement
	dec := encoding.NewDecoder(bytes.NewReader(fullAnnouncement))
	err = dec.Decode(&ha)
	if err != nil {
		return "", types.SiaPublicKey{}, err
	}

	// Check that the announcement was registered as a host announcement.
	if ha.Specifier != PrefixHostAnnouncement {
		return "", types.SiaPublicKey{}, ErrAnnNotAnnouncement
	}
	// Check that the public key is a recognized type of public key.
	if ha.PublicKey.Algorithm != types.SignatureEd25519 {
		return "", types.SiaPublicKey{}, ErrAnnUnrecognizedSignature
	}

	// Read the signature out of the reader.
	var sig crypto.Signature
	err = dec.Decode(&sig)
	if err != nil {
		return "", types.SiaPublicKey{}, err
	}
	// Verify the signature.
	var pk crypto.PublicKey
	copy(pk[:], ha.PublicKey.Key)
	annHash := crypto.HashObject(ha)
	err = crypto.VerifyHash(annHash, pk, sig)
	if err != nil {
		return "", types.SiaPublicKey{}, err
	}
	return ha.NetAddress, ha.PublicKey, nil
}
Example #3
0
// UnmarshalSia implements the encoding.SiaUnmarshaller interface,
// reconstructing a file from the encoded bytes read from r.
func (f *file) UnmarshalSia(r io.Reader) error {
	dec := encoding.NewDecoder(r)

	// COMPATv0.4.3 - decode bytesUploaded and chunksUploaded into dummy vars.
	var bytesUploaded, chunksUploaded uint64

	// decode easy fields
	err := dec.DecodeAll(
		&f.name,
		&f.size,
		&f.masterKey,
		&f.pieceSize,
		&f.mode,
		&bytesUploaded,
		&chunksUploaded,
	)
	if err != nil {
		return err
	}

	// decode erasure coder
	var codeType string
	if err := dec.Decode(&codeType); err != nil {
		return err
	}
	switch codeType {
	case "Reed-Solomon":
		var nData, nParity uint64
		err = dec.DecodeAll(
			&nData,
			&nParity,
		)
		if err != nil {
			return err
		}
		rsc, err := NewRSCode(int(nData), int(nParity))
		if err != nil {
			return err
		}
		f.erasureCode = rsc
	default:
		return errors.New("unrecognized erasure code type: " + codeType)
	}

	// decode contracts
	var nContracts uint64
	if err := dec.Decode(&nContracts); err != nil {
		return err
	}
	f.contracts = make(map[types.FileContractID]fileContract)
	var contract fileContract
	for i := uint64(0); i < nContracts; i++ {
		if err := dec.Decode(&contract); err != nil {
			return err
		}
		f.contracts[contract.ID] = contract
	}
	return nil
}
Example #4
0
// UnmarshalSia implements the encoding.SiaUnmarshaler interface.
func (b *Block) UnmarshalSia(r io.Reader) error {
	io.ReadFull(r, b.ParentID[:])
	io.ReadFull(r, b.Nonce[:])
	tsBytes := make([]byte, 8)
	io.ReadFull(r, tsBytes)
	b.Timestamp = Timestamp(encoding.DecUint64(tsBytes))
	return encoding.NewDecoder(r).DecodeAll(&b.MinerPayouts, &b.Transactions)
}
Example #5
0
// minerHeaderHandlerPOST handles the API call to submit a block header to the
// miner.
func (api *API) minerHeaderHandlerPOST(w http.ResponseWriter, req *http.Request, _ httprouter.Params) {
	var bh types.BlockHeader
	err := encoding.NewDecoder(req.Body).Decode(&bh)
	if err != nil {
		WriteError(w, Error{err.Error()}, http.StatusBadRequest)
		return
	}
	err = api.miner.SubmitHeader(bh)
	if err != nil {
		WriteError(w, Error{err.Error()}, http.StatusBadRequest)
		return
	}
	WriteSuccess(w)
}
Example #6
0
// minerHeaderHandlerPOST handles the API call to submit a block header to the
// miner.
func (srv *Server) minerHeaderHandlerPOST(w http.ResponseWriter, req *http.Request, _ httprouter.Params) {
	var bh types.BlockHeader
	err := encoding.NewDecoder(req.Body).Decode(&bh)
	if err != nil {
		writeError(w, err.Error(), http.StatusBadRequest)
		return
	}
	err = srv.miner.SubmitHeader(bh)
	if err != nil {
		writeError(w, err.Error(), http.StatusBadRequest)
		return
	}
	writeSuccess(w)
}
Example #7
0
File: persist.go Project: dlmac/Sia
// load loads a file created by save.
func (f *file) load(r io.Reader) error {
	// TODO: error checking
	zip, err := gzip.NewReader(r)
	if err != nil {
		return err
	}
	defer zip.Close()
	dec := encoding.NewDecoder(zip)

	// decode easy fields
	dec.Decode(&f.name)
	dec.Decode(&f.size)
	dec.Decode(&f.masterKey)
	dec.Decode(&f.pieceSize)
	dec.Decode(&f.mode)
	dec.Decode(&f.bytesUploaded)
	dec.Decode(&f.chunksUploaded)

	// decode erasure coder
	var codeType string
	dec.Decode(&codeType)
	switch codeType {
	case "Reed-Solomon":
		var nData, nParity uint64
		dec.Decode(&nData)
		dec.Decode(&nParity)
		rsc, err := NewRSCode(int(nData), int(nParity))
		if err != nil {
			return err
		}
		f.erasureCode = rsc
	default:
		return errors.New("unrecognized erasure code type: " + codeType)
	}

	// decode contracts
	var nContracts uint64
	dec.Decode(&nContracts)
	f.contracts = make(map[modules.NetAddress]fileContract)
	var contract fileContract
	for i := uint64(0); i < nContracts; i++ {
		dec.Decode(&contract)
		f.contracts[contract.IP] = contract
	}
	return nil
}
Example #8
0
// ReadSignedObject reads a length-prefixed object prefixed by its signature,
// and verifies the signature.
func ReadSignedObject(r io.Reader, obj interface{}, maxLen uint64, pk PublicKey) error {
	// read the signature
	var sig Signature
	err := encoding.NewDecoder(r).Decode(&sig)
	if err != nil {
		return err
	}
	// read the encoded object
	encObj, err := encoding.ReadPrefix(r, maxLen)
	if err != nil {
		return err
	}
	// verify the signature
	if err := VerifyHash(HashBytes(encObj), pk, sig); err != nil {
		return err
	}
	// decode the object
	return encoding.Unmarshal(encObj, obj)
}
Example #9
0
File: persist.go Project: dlmac/Sia
// loadSharedFiles reads .sia data from reader and registers the contained
// files in the renter. It returns the nicknames of the loaded files.
func (r *Renter) loadSharedFiles(reader io.Reader) ([]string, error) {
	dec := encoding.NewDecoder(reader)

	// read header
	var header [15]byte
	dec.Decode(&header)
	if header != shareHeader {
		return nil, ErrBadFile
	}

	// decode version
	var version string
	dec.Decode(&version)
	if version != shareVersion {
		return nil, ErrIncompatible
	}

	// Read number of files
	var numFiles uint64
	err := dec.Decode(&numFiles)
	if err != nil {
		return nil, err
	}

	// Read each file.
	files := make([]*file, numFiles)
	for i := range files {
		files[i] = new(file)
		err := files[i].load(reader)
		if err != nil {
			return nil, err
		}

		// Make sure the file's name does not conflict with existing files.
		dupCount := 0
		origName := files[i].name
		for {
			_, exists := r.files[files[i].name]
			if !exists {
				break
			}
			dupCount++
			files[i].name = origName + "_" + strconv.Itoa(dupCount)
		}
	}

	// Add files to renter.
	names := make([]string, numFiles)
	for i, f := range files {
		r.files[f.name] = f
		names[i] = f.name
	}
	// Save the files, and their renter metadata.
	for _, f := range files {
		r.saveFile(f)
	}
	err = r.save()
	if err != nil {
		return nil, err
	}

	return names, nil
}