// UnmarshalSia implements the encoding.SiaUnmarshaler interface. func (c *Currency) UnmarshalSia(r io.Reader) error { b, err := encoding.ReadPrefix(r, 256) if err != nil { return err } c.i.SetBytes(b) 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) }
// threadedProbeHost tries to fetch the settings of a host. If successful, the // host is put in the set of active hosts. If unsuccessful, the host id deleted // from the set of active hosts. func (hdb *HostDB) threadedProbeHosts() { for hostEntry := range hdb.scanPool { // Request settings from the queued host entry. var settings modules.HostSettings err := func() error { conn, err := hdb.dialer.DialTimeout(hostEntry.NetAddress, hostRequestTimeout) if err != nil { return err } defer conn.Close() err = encoding.WriteObject(conn, modules.RPCSettings) if err != nil { return err } // COMPATv0.4.8 - If first decoding attempt fails, try decoding // into the old HostSettings type. Because we decode twice, we // must read the data into memory first. settingsBytes, err := encoding.ReadPrefix(conn, maxSettingsLen) if err != nil { return err } err = encoding.Unmarshal(settingsBytes, &settings) if err != nil { var oldSettings oldHostSettings err = encoding.Unmarshal(settingsBytes, &oldSettings) if err != nil { return err } // Convert the old type. settings = modules.HostSettings{ NetAddress: oldSettings.NetAddress, TotalStorage: oldSettings.TotalStorage, MinDuration: oldSettings.MinDuration, MaxDuration: oldSettings.MaxDuration, WindowSize: oldSettings.WindowSize, Price: oldSettings.Price, Collateral: oldSettings.Collateral, UnlockHash: oldSettings.UnlockHash, } } return nil }() // Now that network communication is done, lock the hostdb to modify the // host entry. func() { hdb.mu.Lock() defer hdb.mu.Unlock() // Regardless of whether the host responded, add it to allHosts. if _, exists := hdb.allHosts[hostEntry.NetAddress]; !exists { hdb.allHosts[hostEntry.NetAddress] = hostEntry } // If the scan was unsuccessful, decrement the host's reliability. if err != nil { hdb.decrementReliability(hostEntry.NetAddress, UnreachablePenalty) return } // Update the host settings, reliability, and weight. The old NetAddress // must be preserved. settings.NetAddress = hostEntry.HostSettings.NetAddress hostEntry.HostSettings = settings hostEntry.reliability = MaxReliability hostEntry.weight = calculateHostWeight(*hostEntry) hostEntry.online = true // If 'MaxActiveHosts' has not been reached, add the host to the // activeHosts tree. if _, exists := hdb.activeHosts[hostEntry.NetAddress]; !exists && len(hdb.activeHosts) < MaxActiveHosts { hdb.insertNode(hostEntry) } }() } }