// 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 }
// 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 }
// 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 }
// 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) }
// 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) }
// 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) }
// 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 }
// 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) }
// 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 }