github.com/Synthesix/Sia@v1.3.3-0.20180413141344-f863baeed3ca/types/encoding.go (about)

     1  package types
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/binary"
     6  	"encoding/hex"
     7  	"encoding/json"
     8  	"fmt"
     9  	"io"
    10  	"math/big"
    11  	"strings"
    12  	"unsafe"
    13  
    14  	"github.com/Synthesix/Sia/build"
    15  	"github.com/Synthesix/Sia/crypto"
    16  	"github.com/Synthesix/Sia/encoding"
    17  )
    18  
    19  // sanityCheckWriter checks that the bytes written to w exactly match the
    20  // bytes in buf.
    21  type sanityCheckWriter struct {
    22  	w   io.Writer
    23  	buf *bytes.Buffer
    24  }
    25  
    26  func (s sanityCheckWriter) Write(p []byte) (int, error) {
    27  	if !bytes.Equal(p, s.buf.Next(len(p))) {
    28  		panic("encoding mismatch")
    29  	}
    30  	return s.w.Write(p)
    31  }
    32  
    33  // An encHelper provides convenience methods and reduces allocations during
    34  // encoding. All of its methods become no-ops after the encHelper encounters a
    35  // Write error.
    36  type encHelper struct {
    37  	w   io.Writer
    38  	buf []byte
    39  	err error
    40  }
    41  
    42  // reset reslices e's internal buffer to have a length of 0.
    43  func (e *encHelper) reset() {
    44  	e.buf = e.buf[:0]
    45  }
    46  
    47  // append appends a byte to e's internal buffer.
    48  func (e *encHelper) append(b byte) {
    49  	if e.err != nil {
    50  		return
    51  	}
    52  	e.buf = append(e.buf, b)
    53  }
    54  
    55  // flush writes e's internal buffer to the underlying io.Writer.
    56  func (e *encHelper) flush() (int, error) {
    57  	if e.err != nil {
    58  		return 0, e.err
    59  	}
    60  	n, err := e.w.Write(e.buf)
    61  	if e.err == nil {
    62  		e.err = err
    63  	}
    64  	return n, e.err
    65  }
    66  
    67  // Write implements the io.Writer interface.
    68  func (e *encHelper) Write(p []byte) (int, error) {
    69  	if e.err != nil {
    70  		return 0, e.err
    71  	}
    72  	e.buf = append(e.buf[:0], p...)
    73  	return e.flush()
    74  }
    75  
    76  // WriteUint64 writes a uint64 value to the underlying io.Writer.
    77  func (e *encHelper) WriteUint64(u uint64) {
    78  	if e.err != nil {
    79  		return
    80  	}
    81  	e.buf = e.buf[:8]
    82  	binary.LittleEndian.PutUint64(e.buf, u)
    83  	e.flush()
    84  }
    85  
    86  // WriteUint64 writes an int value to the underlying io.Writer.
    87  func (e *encHelper) WriteInt(i int) {
    88  	e.WriteUint64(uint64(i))
    89  }
    90  
    91  // WriteUint64 writes p to the underlying io.Writer, prefixed by its length.
    92  func (e *encHelper) WritePrefix(p []byte) {
    93  	e.WriteInt(len(p))
    94  	e.Write(p)
    95  }
    96  
    97  // Err returns the first non-nil error encountered by e.
    98  func (e *encHelper) Err() error {
    99  	return e.err
   100  }
   101  
   102  // encoder converts w to an encHelper. If w's underlying type is already
   103  // *encHelper, it is returned; otherwise, a new encHelper is allocated.
   104  func encoder(w io.Writer) *encHelper {
   105  	if e, ok := w.(*encHelper); ok {
   106  		return e
   107  	}
   108  	return &encHelper{
   109  		w:   w,
   110  		buf: make([]byte, 64), // large enough for everything but ArbitraryData
   111  	}
   112  }
   113  
   114  // A decHelper provides convenience methods and reduces allocations during
   115  // decoding. All of its methods become no-ops after the decHelper encounters a
   116  // Read error.
   117  type decHelper struct {
   118  	r   io.Reader
   119  	buf [8]byte
   120  	err error
   121  	n   int // total number of bytes read
   122  }
   123  
   124  // Read implements the io.Reader interface.
   125  func (d *decHelper) Read(p []byte) (int, error) {
   126  	if d.err != nil {
   127  		return 0, d.err
   128  	}
   129  	n, err := d.r.Read(p)
   130  	if d.err == nil {
   131  		d.err = err
   132  	}
   133  	d.n += n
   134  	if d.n > encoding.MaxObjectSize {
   135  		d.err = encoding.ErrObjectTooLarge(d.n)
   136  	}
   137  	return n, d.err
   138  }
   139  
   140  // ReadFull is shorthand for io.ReadFull(d, p).
   141  func (d *decHelper) ReadFull(p []byte) {
   142  	if d.err != nil {
   143  		return
   144  	}
   145  	io.ReadFull(d, p)
   146  }
   147  
   148  // ReadPrefix reads a length-prefix, allocates a byte slice with that length,
   149  // reads into the byte slice, and returns it. If the length prefix exceeds
   150  // encoding.MaxSliceSize, ReadPrefix returns nil and sets d.Err().
   151  func (d *decHelper) ReadPrefix() []byte {
   152  	n := d.NextPrefix(unsafe.Sizeof(byte(0))) // if too large, n == 0
   153  	b := make([]byte, n)
   154  	d.ReadFull(b)
   155  	if d.err != nil {
   156  		return nil
   157  	}
   158  	return b
   159  }
   160  
   161  // NextUint64 reads the next 8 bytes and returns them as a uint64.
   162  func (d *decHelper) NextUint64() uint64 {
   163  	d.ReadFull(d.buf[:])
   164  	if d.err != nil {
   165  		return 0
   166  	}
   167  	return encoding.DecUint64(d.buf[:])
   168  }
   169  
   170  // NextPrefix is like NextUint64, but performs sanity checks on the prefix.
   171  // Specifically, if the prefix multiplied by elemSize exceeds
   172  // encoding.MaxSliceSize, NextPrefix returns 0 and sets d.Err().
   173  func (d *decHelper) NextPrefix(elemSize uintptr) uint64 {
   174  	n := d.NextUint64()
   175  	if d.err != nil {
   176  		return 0
   177  	}
   178  	if n > 1<<31-1 || n*uint64(elemSize) > encoding.MaxSliceSize {
   179  		d.err = encoding.ErrSliceTooLarge{Len: n, ElemSize: uint64(elemSize)}
   180  		return 0
   181  	}
   182  	return n
   183  }
   184  
   185  // Err returns the first non-nil error encountered by d.
   186  func (d *decHelper) Err() error {
   187  	return d.err
   188  }
   189  
   190  // decoder converts r to a decHelper. If r's underlying type is already
   191  // *decHelper, it is returned; otherwise, a new decHelper is allocated.
   192  func decoder(r io.Reader) *decHelper {
   193  	if d, ok := r.(*decHelper); ok {
   194  		return d
   195  	}
   196  	return &decHelper{r: r}
   197  }
   198  
   199  // MarshalSia implements the encoding.SiaMarshaler interface.
   200  func (b Block) MarshalSia(w io.Writer) error {
   201  	if build.DEBUG {
   202  		// Sanity check: compare against the old encoding
   203  		buf := new(bytes.Buffer)
   204  		encoding.NewEncoder(buf).EncodeAll(
   205  			b.ParentID,
   206  			b.Nonce,
   207  			b.Timestamp,
   208  			b.MinerPayouts,
   209  			b.Transactions,
   210  		)
   211  		w = sanityCheckWriter{w, buf}
   212  	}
   213  
   214  	e := encoder(w)
   215  	e.Write(b.ParentID[:])
   216  	e.Write(b.Nonce[:])
   217  	e.WriteUint64(uint64(b.Timestamp))
   218  	e.WriteInt(len(b.MinerPayouts))
   219  	for i := range b.MinerPayouts {
   220  		b.MinerPayouts[i].MarshalSia(e)
   221  	}
   222  	e.WriteInt(len(b.Transactions))
   223  	for i := range b.Transactions {
   224  		if err := b.Transactions[i].MarshalSia(e); err != nil {
   225  			return err
   226  		}
   227  	}
   228  	return e.Err()
   229  }
   230  
   231  // UnmarshalSia implements the encoding.SiaUnmarshaler interface.
   232  func (b *Block) UnmarshalSia(r io.Reader) error {
   233  	if build.DEBUG {
   234  		// Sanity check: compare against the old decoding
   235  		buf := new(bytes.Buffer)
   236  		r = io.TeeReader(r, buf)
   237  
   238  		defer func() {
   239  			checkB := new(Block)
   240  			if err := encoding.UnmarshalAll(buf.Bytes(),
   241  				&checkB.ParentID,
   242  				&checkB.Nonce,
   243  				&checkB.Timestamp,
   244  				&checkB.MinerPayouts,
   245  				&checkB.Transactions,
   246  			); err != nil {
   247  				// don't check invalid blocks
   248  				return
   249  			}
   250  			if crypto.HashObject(b) != crypto.HashObject(checkB) {
   251  				panic("decoding differs!")
   252  			}
   253  		}()
   254  	}
   255  
   256  	d := decoder(r)
   257  	d.ReadFull(b.ParentID[:])
   258  	d.ReadFull(b.Nonce[:])
   259  	b.Timestamp = Timestamp(d.NextUint64())
   260  	// MinerPayouts
   261  	b.MinerPayouts = make([]SiacoinOutput, d.NextPrefix(unsafe.Sizeof(SiacoinOutput{})))
   262  	for i := range b.MinerPayouts {
   263  		b.MinerPayouts[i].UnmarshalSia(d)
   264  	}
   265  	// Transactions
   266  	b.Transactions = make([]Transaction, d.NextPrefix(unsafe.Sizeof(Transaction{})))
   267  	for i := range b.Transactions {
   268  		b.Transactions[i].UnmarshalSia(d)
   269  	}
   270  	return d.Err()
   271  }
   272  
   273  // MarshalJSON marshales a block id as a hex string.
   274  func (bid BlockID) MarshalJSON() ([]byte, error) {
   275  	return json.Marshal(bid.String())
   276  }
   277  
   278  // String prints the block id in hex.
   279  func (bid BlockID) String() string {
   280  	return fmt.Sprintf("%x", bid[:])
   281  }
   282  
   283  // LoadString loads a BlockID from a string
   284  func (bid *BlockID) LoadString(str string) error {
   285  	return (*crypto.Hash)(bid).LoadString(str)
   286  }
   287  
   288  // UnmarshalJSON decodes the json hex string of the block id.
   289  func (bid *BlockID) UnmarshalJSON(b []byte) error {
   290  	return (*crypto.Hash)(bid).UnmarshalJSON(b)
   291  }
   292  
   293  // MarshalSia implements the encoding.SiaMarshaler interface.
   294  func (cf CoveredFields) MarshalSia(w io.Writer) error {
   295  	e := encoder(w)
   296  	e.reset()
   297  	if cf.WholeTransaction {
   298  		e.append(1)
   299  	} else {
   300  		e.append(0)
   301  	}
   302  	e.flush()
   303  	fields := [][]uint64{
   304  		cf.SiacoinInputs,
   305  		cf.SiacoinOutputs,
   306  		cf.FileContracts,
   307  		cf.FileContractRevisions,
   308  		cf.StorageProofs,
   309  		cf.SiafundInputs,
   310  		cf.SiafundOutputs,
   311  		cf.MinerFees,
   312  		cf.ArbitraryData,
   313  		cf.TransactionSignatures,
   314  	}
   315  	for _, f := range fields {
   316  		e.WriteInt(len(f))
   317  		for _, u := range f {
   318  			e.WriteUint64(u)
   319  		}
   320  	}
   321  	return e.Err()
   322  }
   323  
   324  // MarshalSiaSize returns the encoded size of cf.
   325  func (cf CoveredFields) MarshalSiaSize() (size int) {
   326  	size++ // WholeTransaction
   327  	size += 8 + len(cf.SiacoinInputs)*8
   328  	size += 8 + len(cf.SiacoinOutputs)*8
   329  	size += 8 + len(cf.FileContracts)*8
   330  	size += 8 + len(cf.FileContractRevisions)*8
   331  	size += 8 + len(cf.StorageProofs)*8
   332  	size += 8 + len(cf.SiafundInputs)*8
   333  	size += 8 + len(cf.SiafundOutputs)*8
   334  	size += 8 + len(cf.MinerFees)*8
   335  	size += 8 + len(cf.ArbitraryData)*8
   336  	size += 8 + len(cf.TransactionSignatures)*8
   337  	return
   338  }
   339  
   340  // UnmarshalSia implements the encoding.SiaUnmarshaler interface.
   341  func (cf *CoveredFields) UnmarshalSia(r io.Reader) error {
   342  	d := decoder(r)
   343  	buf := make([]byte, 1)
   344  	d.ReadFull(buf)
   345  	cf.WholeTransaction = (buf[0] == 1)
   346  	fields := []*[]uint64{
   347  		&cf.SiacoinInputs,
   348  		&cf.SiacoinOutputs,
   349  		&cf.FileContracts,
   350  		&cf.FileContractRevisions,
   351  		&cf.StorageProofs,
   352  		&cf.SiafundInputs,
   353  		&cf.SiafundOutputs,
   354  		&cf.MinerFees,
   355  		&cf.ArbitraryData,
   356  		&cf.TransactionSignatures,
   357  	}
   358  	for i := range fields {
   359  		f := make([]uint64, d.NextPrefix(unsafe.Sizeof(uint64(0))))
   360  		for i := range f {
   361  			f[i] = d.NextUint64()
   362  		}
   363  		*fields[i] = f
   364  	}
   365  	return d.Err()
   366  }
   367  
   368  // MarshalJSON implements the json.Marshaler interface.
   369  func (c Currency) MarshalJSON() ([]byte, error) {
   370  	// Must enclosed the value in quotes; otherwise JS will convert it to a
   371  	// double and lose precision.
   372  	return []byte(`"` + c.String() + `"`), nil
   373  }
   374  
   375  // UnmarshalJSON implements the json.Unmarshaler interface. An error is
   376  // returned if a negative number is provided.
   377  func (c *Currency) UnmarshalJSON(b []byte) error {
   378  	// UnmarshalJSON does not expect quotes
   379  	b = bytes.Trim(b, `"`)
   380  	err := c.i.UnmarshalJSON(b)
   381  	if err != nil {
   382  		return err
   383  	}
   384  	if c.i.Sign() < 0 {
   385  		c.i = *big.NewInt(0)
   386  		return ErrNegativeCurrency
   387  	}
   388  	return nil
   389  }
   390  
   391  // MarshalSia implements the encoding.SiaMarshaler interface. It writes the
   392  // byte-slice representation of the Currency's internal big.Int to w. Note
   393  // that as the bytes of the big.Int correspond to the absolute value of the
   394  // integer, there is no way to marshal a negative Currency.
   395  func (c Currency) MarshalSia(w io.Writer) error {
   396  	// from math/big/arith.go
   397  	const (
   398  		_m    = ^big.Word(0)
   399  		_logS = _m>>8&1 + _m>>16&1 + _m>>32&1
   400  		_S    = 1 << _logS // number of bytes per big.Word
   401  	)
   402  
   403  	// get raw bits and seek to first zero byte
   404  	bits := c.i.Bits()
   405  	var i int
   406  	for i = len(bits)*_S - 1; i >= 0; i-- {
   407  		if bits[i/_S]>>(uint(i%_S)*8) != 0 {
   408  			break
   409  		}
   410  	}
   411  
   412  	// write length prefix
   413  	e := encoder(w)
   414  	e.WriteInt(i + 1)
   415  
   416  	// write bytes
   417  	e.reset()
   418  	for ; i >= 0; i-- {
   419  		e.append(byte(bits[i/_S] >> (uint(i%_S) * 8)))
   420  	}
   421  	e.flush()
   422  	return e.Err()
   423  }
   424  
   425  // MarshalSiaSize returns the encoded size of c.
   426  func (c Currency) MarshalSiaSize() int {
   427  	// from math/big/arith.go
   428  	const (
   429  		_m    = ^big.Word(0)
   430  		_logS = _m>>8&1 + _m>>16&1 + _m>>32&1
   431  		_S    = 1 << _logS // number of bytes per big.Word
   432  	)
   433  
   434  	// start with the number of Words * number of bytes per Word, then
   435  	// subtract trailing bytes that are 0
   436  	bits := c.i.Bits()
   437  	size := len(bits) * _S
   438  zeros:
   439  	for i := len(bits) - 1; i >= 0; i-- {
   440  		for j := _S - 1; j >= 0; j-- {
   441  			if (bits[i] >> uintptr(j*8)) != 0 {
   442  				break zeros
   443  			}
   444  			size--
   445  		}
   446  	}
   447  	return 8 + size // account for length prefix
   448  }
   449  
   450  // UnmarshalSia implements the encoding.SiaUnmarshaler interface.
   451  func (c *Currency) UnmarshalSia(r io.Reader) error {
   452  	d := decoder(r)
   453  	var dec Currency
   454  	dec.i.SetBytes(d.ReadPrefix())
   455  	*c = dec
   456  	return d.Err()
   457  }
   458  
   459  // HumanString prints the Currency using human readable units. The unit used
   460  // will be the largest unit that results in a value greater than 1. The value is
   461  // rounded to 4 significant digits.
   462  func (c Currency) HumanString() string {
   463  	pico := SiacoinPrecision.Div64(1e12)
   464  	if c.Cmp(pico) < 0 {
   465  		return c.String() + " H"
   466  	}
   467  
   468  	// iterate until we find a unit greater than c
   469  	mag := pico
   470  	unit := ""
   471  	for _, unit = range []string{"pS", "nS", "uS", "mS", "SC", "KS", "MS", "GS", "TS"} {
   472  		if c.Cmp(mag.Mul64(1e3)) < 0 {
   473  			break
   474  		} else if unit != "TS" {
   475  			// don't want to perform this multiply on the last iter; that
   476  			// would give us 1.235 TS instead of 1235 TS
   477  			mag = mag.Mul64(1e3)
   478  		}
   479  	}
   480  
   481  	num := new(big.Rat).SetInt(c.Big())
   482  	denom := new(big.Rat).SetInt(mag.Big())
   483  	res, _ := new(big.Rat).Mul(num, denom.Inv(denom)).Float64()
   484  
   485  	return fmt.Sprintf("%.4g %s", res, unit)
   486  }
   487  
   488  // String implements the fmt.Stringer interface.
   489  func (c Currency) String() string {
   490  	return c.i.String()
   491  }
   492  
   493  // Scan implements the fmt.Scanner interface, allowing Currency values to be
   494  // scanned from text.
   495  func (c *Currency) Scan(s fmt.ScanState, ch rune) error {
   496  	var dec Currency
   497  	err := dec.i.Scan(s, ch)
   498  	if err != nil {
   499  		return err
   500  	}
   501  	if dec.i.Sign() < 0 {
   502  		return ErrNegativeCurrency
   503  	}
   504  	*c = dec
   505  	return nil
   506  }
   507  
   508  // MarshalSia implements the encoding.SiaMarshaler interface.
   509  func (fc FileContract) MarshalSia(w io.Writer) error {
   510  	e := encoder(w)
   511  	e.WriteUint64(fc.FileSize)
   512  	e.Write(fc.FileMerkleRoot[:])
   513  	e.WriteUint64(uint64(fc.WindowStart))
   514  	e.WriteUint64(uint64(fc.WindowEnd))
   515  	fc.Payout.MarshalSia(e)
   516  	e.WriteInt(len(fc.ValidProofOutputs))
   517  	for _, sco := range fc.ValidProofOutputs {
   518  		sco.MarshalSia(e)
   519  	}
   520  	e.WriteInt(len(fc.MissedProofOutputs))
   521  	for _, sco := range fc.MissedProofOutputs {
   522  		sco.MarshalSia(e)
   523  	}
   524  	e.Write(fc.UnlockHash[:])
   525  	e.WriteUint64(fc.RevisionNumber)
   526  	return e.Err()
   527  }
   528  
   529  // MarshalSiaSize returns the encoded size of fc.
   530  func (fc FileContract) MarshalSiaSize() (size int) {
   531  	size += 8 // FileSize
   532  	size += len(fc.FileMerkleRoot)
   533  	size += 8 + 8 // WindowStart + WindowEnd
   534  	size += fc.Payout.MarshalSiaSize()
   535  	size += 8
   536  	for _, sco := range fc.ValidProofOutputs {
   537  		size += sco.Value.MarshalSiaSize()
   538  		size += len(sco.UnlockHash)
   539  	}
   540  	size += 8
   541  	for _, sco := range fc.MissedProofOutputs {
   542  		size += sco.Value.MarshalSiaSize()
   543  		size += len(sco.UnlockHash)
   544  	}
   545  	size += len(fc.UnlockHash)
   546  	size += 8 // RevisionNumber
   547  	return
   548  }
   549  
   550  // UnmarshalSia implements the encoding.SiaUnmarshaler interface.
   551  func (fc *FileContract) UnmarshalSia(r io.Reader) error {
   552  	d := decoder(r)
   553  	fc.FileSize = d.NextUint64()
   554  	d.ReadFull(fc.FileMerkleRoot[:])
   555  	fc.WindowStart = BlockHeight(d.NextUint64())
   556  	fc.WindowEnd = BlockHeight(d.NextUint64())
   557  	fc.Payout.UnmarshalSia(d)
   558  	fc.ValidProofOutputs = make([]SiacoinOutput, d.NextPrefix(unsafe.Sizeof(SiacoinOutput{})))
   559  	for i := range fc.ValidProofOutputs {
   560  		fc.ValidProofOutputs[i].UnmarshalSia(d)
   561  	}
   562  	fc.MissedProofOutputs = make([]SiacoinOutput, d.NextPrefix(unsafe.Sizeof(SiacoinOutput{})))
   563  	for i := range fc.MissedProofOutputs {
   564  		fc.MissedProofOutputs[i].UnmarshalSia(d)
   565  	}
   566  	d.ReadFull(fc.UnlockHash[:])
   567  	fc.RevisionNumber = d.NextUint64()
   568  	return d.Err()
   569  }
   570  
   571  // MarshalSia implements the encoding.SiaMarshaler interface.
   572  func (fcr FileContractRevision) MarshalSia(w io.Writer) error {
   573  	e := encoder(w)
   574  	e.Write(fcr.ParentID[:])
   575  	fcr.UnlockConditions.MarshalSia(e)
   576  	e.WriteUint64(fcr.NewRevisionNumber)
   577  	e.WriteUint64(fcr.NewFileSize)
   578  	e.Write(fcr.NewFileMerkleRoot[:])
   579  	e.WriteUint64(uint64(fcr.NewWindowStart))
   580  	e.WriteUint64(uint64(fcr.NewWindowEnd))
   581  	e.WriteInt(len(fcr.NewValidProofOutputs))
   582  	for _, sco := range fcr.NewValidProofOutputs {
   583  		sco.MarshalSia(e)
   584  	}
   585  	e.WriteInt(len(fcr.NewMissedProofOutputs))
   586  	for _, sco := range fcr.NewMissedProofOutputs {
   587  		sco.MarshalSia(e)
   588  	}
   589  	e.Write(fcr.NewUnlockHash[:])
   590  	return e.Err()
   591  }
   592  
   593  // MarshalSiaSize returns the encoded size of fcr.
   594  func (fcr FileContractRevision) MarshalSiaSize() (size int) {
   595  	size += len(fcr.ParentID)
   596  	size += fcr.UnlockConditions.MarshalSiaSize()
   597  	size += 8 // NewRevisionNumber
   598  	size += 8 // NewFileSize
   599  	size += len(fcr.NewFileMerkleRoot)
   600  	size += 8 + 8 // NewWindowStart + NewWindowEnd
   601  	size += 8
   602  	for _, sco := range fcr.NewValidProofOutputs {
   603  		size += sco.Value.MarshalSiaSize()
   604  		size += len(sco.UnlockHash)
   605  	}
   606  	size += 8
   607  	for _, sco := range fcr.NewMissedProofOutputs {
   608  		size += sco.Value.MarshalSiaSize()
   609  		size += len(sco.UnlockHash)
   610  	}
   611  	size += len(fcr.NewUnlockHash)
   612  	return
   613  }
   614  
   615  // UnmarshalSia implements the encoding.SiaUnmarshaler interface.
   616  func (fcr *FileContractRevision) UnmarshalSia(r io.Reader) error {
   617  	d := decoder(r)
   618  	d.ReadFull(fcr.ParentID[:])
   619  	fcr.UnlockConditions.UnmarshalSia(d)
   620  	fcr.NewRevisionNumber = d.NextUint64()
   621  	fcr.NewFileSize = d.NextUint64()
   622  	d.ReadFull(fcr.NewFileMerkleRoot[:])
   623  	fcr.NewWindowStart = BlockHeight(d.NextUint64())
   624  	fcr.NewWindowEnd = BlockHeight(d.NextUint64())
   625  	fcr.NewValidProofOutputs = make([]SiacoinOutput, d.NextPrefix(unsafe.Sizeof(SiacoinOutput{})))
   626  	for i := range fcr.NewValidProofOutputs {
   627  		fcr.NewValidProofOutputs[i].UnmarshalSia(d)
   628  	}
   629  	fcr.NewMissedProofOutputs = make([]SiacoinOutput, d.NextPrefix(unsafe.Sizeof(SiacoinOutput{})))
   630  	for i := range fcr.NewMissedProofOutputs {
   631  		fcr.NewMissedProofOutputs[i].UnmarshalSia(d)
   632  	}
   633  	d.ReadFull(fcr.NewUnlockHash[:])
   634  	return d.Err()
   635  }
   636  
   637  // MarshalJSON marshals an id as a hex string.
   638  func (fcid FileContractID) MarshalJSON() ([]byte, error) {
   639  	return json.Marshal(fcid.String())
   640  }
   641  
   642  // String prints the id in hex.
   643  func (fcid FileContractID) String() string {
   644  	return fmt.Sprintf("%x", fcid[:])
   645  }
   646  
   647  // UnmarshalJSON decodes the json hex string of the id.
   648  func (fcid *FileContractID) UnmarshalJSON(b []byte) error {
   649  	return (*crypto.Hash)(fcid).UnmarshalJSON(b)
   650  }
   651  
   652  // MarshalJSON marshals an id as a hex string.
   653  func (oid OutputID) MarshalJSON() ([]byte, error) {
   654  	return json.Marshal(oid.String())
   655  }
   656  
   657  // String prints the id in hex.
   658  func (oid OutputID) String() string {
   659  	return fmt.Sprintf("%x", oid[:])
   660  }
   661  
   662  // UnmarshalJSON decodes the json hex string of the id.
   663  func (oid *OutputID) UnmarshalJSON(b []byte) error {
   664  	return (*crypto.Hash)(oid).UnmarshalJSON(b)
   665  }
   666  
   667  // MarshalSia implements the encoding.SiaMarshaler interface.
   668  func (sci SiacoinInput) MarshalSia(w io.Writer) error {
   669  	e := encoder(w)
   670  	e.Write(sci.ParentID[:])
   671  	sci.UnlockConditions.MarshalSia(e)
   672  	return e.Err()
   673  }
   674  
   675  // UnmarshalSia implements the encoding.SiaUnmarshaler interface.
   676  func (sci *SiacoinInput) UnmarshalSia(r io.Reader) error {
   677  	d := decoder(r)
   678  	d.ReadFull(sci.ParentID[:])
   679  	sci.UnlockConditions.UnmarshalSia(d)
   680  	return d.Err()
   681  }
   682  
   683  // MarshalSia implements the encoding.SiaMarshaler interface.
   684  func (sco SiacoinOutput) MarshalSia(w io.Writer) error {
   685  	e := encoder(w)
   686  	sco.Value.MarshalSia(e)
   687  	e.Write(sco.UnlockHash[:])
   688  	return e.Err()
   689  }
   690  
   691  // UnmarshalSia implements the encoding.SiaUnmarshaler interface.
   692  func (sco *SiacoinOutput) UnmarshalSia(r io.Reader) error {
   693  	d := decoder(r)
   694  	sco.Value.UnmarshalSia(d)
   695  	d.ReadFull(sco.UnlockHash[:])
   696  	return d.Err()
   697  }
   698  
   699  // MarshalJSON marshals an id as a hex string.
   700  func (scoid SiacoinOutputID) MarshalJSON() ([]byte, error) {
   701  	return json.Marshal(scoid.String())
   702  }
   703  
   704  // String prints the id in hex.
   705  func (scoid SiacoinOutputID) String() string {
   706  	return fmt.Sprintf("%x", scoid[:])
   707  }
   708  
   709  // UnmarshalJSON decodes the json hex string of the id.
   710  func (scoid *SiacoinOutputID) UnmarshalJSON(b []byte) error {
   711  	return (*crypto.Hash)(scoid).UnmarshalJSON(b)
   712  }
   713  
   714  // MarshalSia implements the encoding.SiaMarshaler interface.
   715  func (sfi SiafundInput) MarshalSia(w io.Writer) error {
   716  	e := encoder(w)
   717  	e.Write(sfi.ParentID[:])
   718  	sfi.UnlockConditions.MarshalSia(e)
   719  	e.Write(sfi.ClaimUnlockHash[:])
   720  	return e.Err()
   721  }
   722  
   723  // UnmarshalSia implements the encoding.SiaUnmarshaler interface.
   724  func (sfi *SiafundInput) UnmarshalSia(r io.Reader) error {
   725  	d := decoder(r)
   726  	d.ReadFull(sfi.ParentID[:])
   727  	sfi.UnlockConditions.UnmarshalSia(d)
   728  	d.ReadFull(sfi.ClaimUnlockHash[:])
   729  	return d.Err()
   730  }
   731  
   732  // MarshalSia implements the encoding.SiaMarshaler interface.
   733  func (sfo SiafundOutput) MarshalSia(w io.Writer) error {
   734  	e := encoder(w)
   735  	sfo.Value.MarshalSia(e)
   736  	e.Write(sfo.UnlockHash[:])
   737  	sfo.ClaimStart.MarshalSia(e)
   738  	return e.Err()
   739  }
   740  
   741  // UnmarshalSia implements the encoding.SiaUnmarshaler interface.
   742  func (sfo *SiafundOutput) UnmarshalSia(r io.Reader) error {
   743  	d := decoder(r)
   744  	sfo.Value.UnmarshalSia(d)
   745  	d.ReadFull(sfo.UnlockHash[:])
   746  	sfo.ClaimStart.UnmarshalSia(d)
   747  	return d.Err()
   748  }
   749  
   750  // MarshalJSON marshals an id as a hex string.
   751  func (sfoid SiafundOutputID) MarshalJSON() ([]byte, error) {
   752  	return json.Marshal(sfoid.String())
   753  }
   754  
   755  // String prints the id in hex.
   756  func (sfoid SiafundOutputID) String() string {
   757  	return fmt.Sprintf("%x", sfoid[:])
   758  }
   759  
   760  // UnmarshalJSON decodes the json hex string of the id.
   761  func (sfoid *SiafundOutputID) UnmarshalJSON(b []byte) error {
   762  	return (*crypto.Hash)(sfoid).UnmarshalJSON(b)
   763  }
   764  
   765  // MarshalSia implements the encoding.SiaMarshaler interface.
   766  func (spk SiaPublicKey) MarshalSia(w io.Writer) error {
   767  	e := encoder(w)
   768  	e.Write(spk.Algorithm[:])
   769  	e.WritePrefix(spk.Key)
   770  	return e.Err()
   771  }
   772  
   773  // UnmarshalSia implements the encoding.SiaUnmarshaler interface.
   774  func (spk *SiaPublicKey) UnmarshalSia(r io.Reader) error {
   775  	d := decoder(r)
   776  	d.ReadFull(spk.Algorithm[:])
   777  	spk.Key = d.ReadPrefix()
   778  	return d.Err()
   779  }
   780  
   781  // LoadString is the inverse of SiaPublicKey.String().
   782  func (spk *SiaPublicKey) LoadString(s string) {
   783  	parts := strings.Split(s, ":")
   784  	if len(parts) != 2 {
   785  		return
   786  	}
   787  	var err error
   788  	spk.Key, err = hex.DecodeString(parts[1])
   789  	if err != nil {
   790  		spk.Key = nil
   791  		return
   792  	}
   793  	copy(spk.Algorithm[:], []byte(parts[0]))
   794  }
   795  
   796  // String defines how to print a SiaPublicKey - hex is used to keep things
   797  // compact during logging. The key type prefix and lack of a checksum help to
   798  // separate it from a sia address.
   799  func (spk *SiaPublicKey) String() string {
   800  	return spk.Algorithm.String() + ":" + fmt.Sprintf("%x", spk.Key)
   801  }
   802  
   803  // MarshalJSON marshals a specifier as a string.
   804  func (s Specifier) MarshalJSON() ([]byte, error) {
   805  	return json.Marshal(s.String())
   806  }
   807  
   808  // String returns the specifier as a string, trimming any trailing zeros.
   809  func (s Specifier) String() string {
   810  	var i int
   811  	for i = range s {
   812  		if s[i] == 0 {
   813  			break
   814  		}
   815  	}
   816  	return string(s[:i])
   817  }
   818  
   819  // UnmarshalJSON decodes the json string of the specifier.
   820  func (s *Specifier) UnmarshalJSON(b []byte) error {
   821  	var str string
   822  	if err := json.Unmarshal(b, &str); err != nil {
   823  		return err
   824  	}
   825  	copy(s[:], str)
   826  	return nil
   827  }
   828  
   829  // MarshalSia implements the encoding.SiaMarshaler interface.
   830  func (sp *StorageProof) MarshalSia(w io.Writer) error {
   831  	e := encoder(w)
   832  	e.Write(sp.ParentID[:])
   833  	e.Write(sp.Segment[:])
   834  	e.WriteInt(len(sp.HashSet))
   835  	for i := range sp.HashSet {
   836  		e.Write(sp.HashSet[i][:])
   837  	}
   838  	return e.Err()
   839  }
   840  
   841  // UnmarshalSia implements the encoding.SiaUnmarshaler interface.
   842  func (sp *StorageProof) UnmarshalSia(r io.Reader) error {
   843  	d := decoder(r)
   844  	d.ReadFull(sp.ParentID[:])
   845  	d.ReadFull(sp.Segment[:])
   846  	sp.HashSet = make([]crypto.Hash, d.NextPrefix(unsafe.Sizeof(crypto.Hash{})))
   847  	for i := range sp.HashSet {
   848  		d.ReadFull(sp.HashSet[i][:])
   849  	}
   850  	return d.Err()
   851  }
   852  
   853  // MarshalSia implements the encoding.SiaMarshaler interface.
   854  func (t Transaction) MarshalSia(w io.Writer) error {
   855  	if build.DEBUG {
   856  		// Sanity check: compare against the old encoding
   857  		buf := new(bytes.Buffer)
   858  		encoding.NewEncoder(buf).EncodeAll(
   859  			t.SiacoinInputs,
   860  			t.SiacoinOutputs,
   861  			t.FileContracts,
   862  			t.FileContractRevisions,
   863  			t.StorageProofs,
   864  			t.SiafundInputs,
   865  			t.SiafundOutputs,
   866  			t.MinerFees,
   867  			t.ArbitraryData,
   868  			t.TransactionSignatures,
   869  		)
   870  		w = sanityCheckWriter{w, buf}
   871  	}
   872  
   873  	e := encoder(w)
   874  	t.marshalSiaNoSignatures(e)
   875  	e.WriteInt(len((t.TransactionSignatures)))
   876  	for i := range t.TransactionSignatures {
   877  		t.TransactionSignatures[i].MarshalSia(e)
   878  	}
   879  	return e.Err()
   880  }
   881  
   882  // marshalSiaNoSignatures is a helper function for calculating certain hashes
   883  // that do not include the transaction's signatures.
   884  func (t Transaction) marshalSiaNoSignatures(w io.Writer) {
   885  	e := encoder(w)
   886  	e.WriteInt(len((t.SiacoinInputs)))
   887  	for i := range t.SiacoinInputs {
   888  		t.SiacoinInputs[i].MarshalSia(e)
   889  	}
   890  	e.WriteInt(len((t.SiacoinOutputs)))
   891  	for i := range t.SiacoinOutputs {
   892  		t.SiacoinOutputs[i].MarshalSia(e)
   893  	}
   894  	e.WriteInt(len((t.FileContracts)))
   895  	for i := range t.FileContracts {
   896  		t.FileContracts[i].MarshalSia(e)
   897  	}
   898  	e.WriteInt(len((t.FileContractRevisions)))
   899  	for i := range t.FileContractRevisions {
   900  		t.FileContractRevisions[i].MarshalSia(e)
   901  	}
   902  	e.WriteInt(len((t.StorageProofs)))
   903  	for i := range t.StorageProofs {
   904  		t.StorageProofs[i].MarshalSia(e)
   905  	}
   906  	e.WriteInt(len((t.SiafundInputs)))
   907  	for i := range t.SiafundInputs {
   908  		t.SiafundInputs[i].MarshalSia(e)
   909  	}
   910  	e.WriteInt(len((t.SiafundOutputs)))
   911  	for i := range t.SiafundOutputs {
   912  		t.SiafundOutputs[i].MarshalSia(e)
   913  	}
   914  	e.WriteInt(len((t.MinerFees)))
   915  	for i := range t.MinerFees {
   916  		t.MinerFees[i].MarshalSia(e)
   917  	}
   918  	e.WriteInt(len((t.ArbitraryData)))
   919  	for i := range t.ArbitraryData {
   920  		e.WritePrefix(t.ArbitraryData[i])
   921  	}
   922  }
   923  
   924  // MarshalSiaSize returns the encoded size of t.
   925  func (t Transaction) MarshalSiaSize() (size int) {
   926  	size += 8
   927  	for _, sci := range t.SiacoinInputs {
   928  		size += len(sci.ParentID)
   929  		size += sci.UnlockConditions.MarshalSiaSize()
   930  	}
   931  	size += 8
   932  	for _, sco := range t.SiacoinOutputs {
   933  		size += sco.Value.MarshalSiaSize()
   934  		size += len(sco.UnlockHash)
   935  	}
   936  	size += 8
   937  	for i := range t.FileContracts {
   938  		size += t.FileContracts[i].MarshalSiaSize()
   939  	}
   940  	size += 8
   941  	for i := range t.FileContractRevisions {
   942  		size += t.FileContractRevisions[i].MarshalSiaSize()
   943  	}
   944  	size += 8
   945  	for _, sp := range t.StorageProofs {
   946  		size += len(sp.ParentID)
   947  		size += len(sp.Segment)
   948  		size += 8 + len(sp.HashSet)*crypto.HashSize
   949  	}
   950  	size += 8
   951  	for _, sfi := range t.SiafundInputs {
   952  		size += len(sfi.ParentID)
   953  		size += len(sfi.ClaimUnlockHash)
   954  		size += sfi.UnlockConditions.MarshalSiaSize()
   955  	}
   956  	size += 8
   957  	for _, sfo := range t.SiafundOutputs {
   958  		size += sfo.Value.MarshalSiaSize()
   959  		size += len(sfo.UnlockHash)
   960  		size += sfo.ClaimStart.MarshalSiaSize()
   961  	}
   962  	size += 8
   963  	for i := range t.MinerFees {
   964  		size += t.MinerFees[i].MarshalSiaSize()
   965  	}
   966  	size += 8
   967  	for i := range t.ArbitraryData {
   968  		size += 8 + len(t.ArbitraryData[i])
   969  	}
   970  	size += 8
   971  	for _, ts := range t.TransactionSignatures {
   972  		size += len(ts.ParentID)
   973  		size += 8 // ts.PublicKeyIndex
   974  		size += 8 // ts.Timelock
   975  		size += ts.CoveredFields.MarshalSiaSize()
   976  		size += 8 + len(ts.Signature)
   977  	}
   978  
   979  	// Sanity check against the slower method.
   980  	if build.DEBUG {
   981  		expectedSize := len(encoding.Marshal(t))
   982  		if expectedSize != size {
   983  			panic("Transaction size different from expected size.")
   984  		}
   985  	}
   986  	return
   987  }
   988  
   989  // UnmarshalSia implements the encoding.SiaUnmarshaler interface.
   990  func (t *Transaction) UnmarshalSia(r io.Reader) error {
   991  	d := decoder(r)
   992  	t.SiacoinInputs = make([]SiacoinInput, d.NextPrefix(unsafe.Sizeof(SiacoinInput{})))
   993  	for i := range t.SiacoinInputs {
   994  		t.SiacoinInputs[i].UnmarshalSia(d)
   995  	}
   996  	t.SiacoinOutputs = make([]SiacoinOutput, d.NextPrefix(unsafe.Sizeof(SiacoinOutput{})))
   997  	for i := range t.SiacoinOutputs {
   998  		t.SiacoinOutputs[i].UnmarshalSia(d)
   999  	}
  1000  	t.FileContracts = make([]FileContract, d.NextPrefix(unsafe.Sizeof(FileContract{})))
  1001  	for i := range t.FileContracts {
  1002  		t.FileContracts[i].UnmarshalSia(d)
  1003  	}
  1004  	t.FileContractRevisions = make([]FileContractRevision, d.NextPrefix(unsafe.Sizeof(FileContractRevision{})))
  1005  	for i := range t.FileContractRevisions {
  1006  		t.FileContractRevisions[i].UnmarshalSia(d)
  1007  	}
  1008  	t.StorageProofs = make([]StorageProof, d.NextPrefix(unsafe.Sizeof(StorageProof{})))
  1009  	for i := range t.StorageProofs {
  1010  		t.StorageProofs[i].UnmarshalSia(d)
  1011  	}
  1012  	t.SiafundInputs = make([]SiafundInput, d.NextPrefix(unsafe.Sizeof(SiafundInput{})))
  1013  	for i := range t.SiafundInputs {
  1014  		t.SiafundInputs[i].UnmarshalSia(d)
  1015  	}
  1016  	t.SiafundOutputs = make([]SiafundOutput, d.NextPrefix(unsafe.Sizeof(SiafundOutput{})))
  1017  	for i := range t.SiafundOutputs {
  1018  		t.SiafundOutputs[i].UnmarshalSia(d)
  1019  	}
  1020  	t.MinerFees = make([]Currency, d.NextPrefix(unsafe.Sizeof(Currency{})))
  1021  	for i := range t.MinerFees {
  1022  		t.MinerFees[i].UnmarshalSia(d)
  1023  	}
  1024  	t.ArbitraryData = make([][]byte, d.NextPrefix(unsafe.Sizeof([]byte{})))
  1025  	for i := range t.ArbitraryData {
  1026  		t.ArbitraryData[i] = d.ReadPrefix()
  1027  	}
  1028  	t.TransactionSignatures = make([]TransactionSignature, d.NextPrefix(unsafe.Sizeof(TransactionSignature{})))
  1029  	for i := range t.TransactionSignatures {
  1030  		t.TransactionSignatures[i].UnmarshalSia(d)
  1031  	}
  1032  	return d.Err()
  1033  }
  1034  
  1035  // MarshalJSON marshals an id as a hex string.
  1036  func (tid TransactionID) MarshalJSON() ([]byte, error) {
  1037  	return json.Marshal(tid.String())
  1038  }
  1039  
  1040  // String prints the id in hex.
  1041  func (tid TransactionID) String() string {
  1042  	return fmt.Sprintf("%x", tid[:])
  1043  }
  1044  
  1045  // UnmarshalJSON decodes the json hex string of the id.
  1046  func (tid *TransactionID) UnmarshalJSON(b []byte) error {
  1047  	return (*crypto.Hash)(tid).UnmarshalJSON(b)
  1048  }
  1049  
  1050  // MarshalSia implements the encoding.SiaMarshaler interface.
  1051  func (ts TransactionSignature) MarshalSia(w io.Writer) error {
  1052  	e := encoder(w)
  1053  	e.Write(ts.ParentID[:])
  1054  	e.WriteUint64(ts.PublicKeyIndex)
  1055  	e.WriteUint64(uint64(ts.Timelock))
  1056  	ts.CoveredFields.MarshalSia(e)
  1057  	e.WritePrefix(ts.Signature)
  1058  	return e.Err()
  1059  }
  1060  
  1061  // UnmarshalSia implements the encoding.SiaUnmarshaler interface.
  1062  func (ts *TransactionSignature) UnmarshalSia(r io.Reader) error {
  1063  	d := decoder(r)
  1064  	d.ReadFull(ts.ParentID[:])
  1065  	ts.PublicKeyIndex = d.NextUint64()
  1066  	ts.Timelock = BlockHeight(d.NextUint64())
  1067  	ts.CoveredFields.UnmarshalSia(d)
  1068  	ts.Signature = d.ReadPrefix()
  1069  	return d.Err()
  1070  }
  1071  
  1072  // MarshalSia implements the encoding.SiaMarshaler interface.
  1073  func (uc UnlockConditions) MarshalSia(w io.Writer) error {
  1074  	e := encoder(w)
  1075  	e.WriteUint64(uint64(uc.Timelock))
  1076  	e.WriteInt(len(uc.PublicKeys))
  1077  	for _, spk := range uc.PublicKeys {
  1078  		spk.MarshalSia(e)
  1079  	}
  1080  	e.WriteUint64(uc.SignaturesRequired)
  1081  	return e.Err()
  1082  }
  1083  
  1084  // MarshalSiaSize returns the encoded size of uc.
  1085  func (uc UnlockConditions) MarshalSiaSize() (size int) {
  1086  	size += 8 // Timelock
  1087  	size += 8 // length prefix for PublicKeys
  1088  	for _, spk := range uc.PublicKeys {
  1089  		size += len(spk.Algorithm)
  1090  		size += 8 + len(spk.Key)
  1091  	}
  1092  	size += 8 // SignaturesRequired
  1093  	return
  1094  }
  1095  
  1096  // UnmarshalSia implements the encoding.SiaUnmarshaler interface.
  1097  func (uc *UnlockConditions) UnmarshalSia(r io.Reader) error {
  1098  	d := decoder(r)
  1099  	uc.Timelock = BlockHeight(d.NextUint64())
  1100  	uc.PublicKeys = make([]SiaPublicKey, d.NextPrefix(unsafe.Sizeof(SiaPublicKey{})))
  1101  	for i := range uc.PublicKeys {
  1102  		uc.PublicKeys[i].UnmarshalSia(d)
  1103  	}
  1104  	uc.SignaturesRequired = d.NextUint64()
  1105  	return d.Err()
  1106  }
  1107  
  1108  // MarshalJSON is implemented on the unlock hash to always produce a hex string
  1109  // upon marshalling.
  1110  func (uh UnlockHash) MarshalJSON() ([]byte, error) {
  1111  	return json.Marshal(uh.String())
  1112  }
  1113  
  1114  // UnmarshalJSON is implemented on the unlock hash to recover an unlock hash
  1115  // that has been encoded to a hex string.
  1116  func (uh *UnlockHash) UnmarshalJSON(b []byte) error {
  1117  	// Check the length of b.
  1118  	if len(b) != crypto.HashSize*2+UnlockHashChecksumSize*2+2 && len(b) != crypto.HashSize*2+2 {
  1119  		return ErrUnlockHashWrongLen
  1120  	}
  1121  	return uh.LoadString(string(b[1 : len(b)-1]))
  1122  }
  1123  
  1124  // String returns the hex representation of the unlock hash as a string - this
  1125  // includes a checksum.
  1126  func (uh UnlockHash) String() string {
  1127  	uhChecksum := crypto.HashObject(uh)
  1128  	return fmt.Sprintf("%x%x", uh[:], uhChecksum[:UnlockHashChecksumSize])
  1129  }
  1130  
  1131  // LoadString loads a hex representation (including checksum) of an unlock hash
  1132  // into an unlock hash object. An error is returned if the string is invalid or
  1133  // fails the checksum.
  1134  func (uh *UnlockHash) LoadString(strUH string) error {
  1135  	// Check the length of strUH.
  1136  	if len(strUH) != crypto.HashSize*2+UnlockHashChecksumSize*2 {
  1137  		return ErrUnlockHashWrongLen
  1138  	}
  1139  
  1140  	// Decode the unlock hash.
  1141  	var byteUnlockHash []byte
  1142  	var checksum []byte
  1143  	_, err := fmt.Sscanf(strUH[:crypto.HashSize*2], "%x", &byteUnlockHash)
  1144  	if err != nil {
  1145  		return err
  1146  	}
  1147  
  1148  	// Decode and verify the checksum.
  1149  	_, err = fmt.Sscanf(strUH[crypto.HashSize*2:], "%x", &checksum)
  1150  	if err != nil {
  1151  		return err
  1152  	}
  1153  	expectedChecksum := crypto.HashBytes(byteUnlockHash)
  1154  	if !bytes.Equal(expectedChecksum[:UnlockHashChecksumSize], checksum) {
  1155  		return ErrInvalidUnlockHashChecksum
  1156  	}
  1157  
  1158  	copy(uh[:], byteUnlockHash[:])
  1159  	return nil
  1160  }