github.com/BlockABC/godash@v0.0.0-20191112120524-f4aa3a32c566/blockchain/chainio.go (about)

     1  // Copyright (c) 2015-2016 The btcsuite developers
     2  // Copyright (c) 2016 The Dash developers
     3  // Use of this source code is governed by an ISC
     4  // license that can be found in the LICENSE file.
     5  
     6  package blockchain
     7  
     8  import (
     9  	"bytes"
    10  	"encoding/binary"
    11  	"fmt"
    12  	"math/big"
    13  	"sort"
    14  
    15  	"github.com/BlockABC/godash/database"
    16  	"github.com/BlockABC/godash/wire"
    17  	"github.com/BlockABC/godashutil"
    18  )
    19  
    20  var (
    21  	// hashIndexBucketName is the name of the db bucket used to house to the
    22  	// block hash -> block height index.
    23  	hashIndexBucketName = []byte("hashidx")
    24  
    25  	// heightIndexBucketName is the name of the db bucket used to house to
    26  	// the block height -> block hash index.
    27  	heightIndexBucketName = []byte("heightidx")
    28  
    29  	// chainStateKeyName is the name of the db key used to store the best
    30  	// chain state.
    31  	chainStateKeyName = []byte("chainstate")
    32  
    33  	// spendJournalBucketName is the name of the db bucket used to house
    34  	// transactions outputs that are spent in each block.
    35  	spendJournalBucketName = []byte("spendjournal")
    36  
    37  	// utxoSetBucketName is the name of the db bucket used to house the
    38  	// unspent transaction output set.
    39  	utxoSetBucketName = []byte("utxoset")
    40  
    41  	// byteOrder is the preferred byte order used for serializing numeric
    42  	// fields for storage in the database.
    43  	byteOrder = binary.LittleEndian
    44  )
    45  
    46  // errNotInMainChain signifies that a block hash or height that is not in the
    47  // main chain was requested.
    48  type errNotInMainChain string
    49  
    50  // Error implements the error interface.
    51  func (e errNotInMainChain) Error() string {
    52  	return string(e)
    53  }
    54  
    55  // isNotInMainChainErr returns whether or not the passed error is an
    56  // errNotInMainChain error.
    57  func isNotInMainChainErr(err error) bool {
    58  	_, ok := err.(errNotInMainChain)
    59  	return ok
    60  }
    61  
    62  // errDeserialize signifies that a problem was encountered when deserializing
    63  // data.
    64  type errDeserialize string
    65  
    66  // Error implements the error interface.
    67  func (e errDeserialize) Error() string {
    68  	return string(e)
    69  }
    70  
    71  // isDeserializeErr returns whether or not the passed error is an errDeserialize
    72  // error.
    73  func isDeserializeErr(err error) bool {
    74  	_, ok := err.(errDeserialize)
    75  	return ok
    76  }
    77  
    78  // -----------------------------------------------------------------------------
    79  // The transaction spend journal consists of an entry for each block connected
    80  // to the main chain which contains the transaction outputs the block spends
    81  // serialized such that the order is the reverse of the order they were spent.
    82  //
    83  // This is required because reorganizing the chain necessarily entails
    84  // disconnecting blocks to get back to the point of the fork which implies
    85  // unspending all of the transaction outputs that each block previously spent.
    86  // Since the utxo set, by definition, only contains unspent transaction outputs,
    87  // the spent transaction outputs must be resurrected from somewhere.  There is
    88  // more than one way this could be done, however this is the most straight
    89  // forward method that does not require having a transaction index and unpruned
    90  // blockchain.
    91  //
    92  // NOTE: This format is NOT self describing.  The additional details such as
    93  // the number of entries (transaction inputs) are expected to come from the
    94  // block itself and the utxo set.  The rationale in doing this is to save a
    95  // significant amount of space.  This is also the reason the spent outputs are
    96  // serialized in the reverse order they are spent because later transactions
    97  // are allowed to spend outputs from earlier ones in the same block.
    98  //
    99  // The serialized format is:
   100  //
   101  //   [<header code><version><compressed txout>],...
   102  //
   103  //   Field                Type     Size
   104  //   header code          VLQ      variable
   105  //   version              VLQ      variable
   106  //   compressed txout
   107  //     compressed amount  VLQ      variable
   108  //     compressed script  []byte   variable
   109  //
   110  // The serialized header code format is:
   111  //   bit 0 - containing transaction is a coinbase
   112  //   bits 1-x - height of the block that contains the spent txout
   113  //
   114  //   NOTE: The header code and version are only encoded when the spent txout was
   115  //   the final unspent output of the containing transaction.  Otherwise, the
   116  //   header code will be 0 and the version is not serialized at all.  This is
   117  //   done because that information is only needed when the utxo set no longer
   118  //   has it.
   119  //
   120  // Example 1:
   121  // From block 170 in main blockchain.
   122  //
   123  //    1301320511db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5c
   124  //    <><><------------------------------------------------------------------>
   125  //     | |                                  |
   126  //     | version                   compressed txout
   127  //    header code
   128  //
   129  //  - header code: 0x13 (coinbase, height 9)
   130  //  - transaction version: 1
   131  //  - compressed txout 0:
   132  //    - 0x32: VLQ-encoded compressed amount for 5000000000 (50 BTC)
   133  //    - 0x05: special script type pay-to-pubkey
   134  //    - 0x11...5c: x-coordinate of the pubkey
   135  //
   136  // Example 2:
   137  // Adapted from block 100025 in main blockchain.
   138  //
   139  //    0091f20f006edbc6c4d31bae9f1ccc38538a114bf42de65e868b99700186c64700b2fb57eadf61e106a100a7445a8c3f67898841ec
   140  //    <><----------------------------------------------><----><><---------------------------------------------->
   141  //     |                                |                  |   |                            |
   142  //     |                       compressed txout            |   version             compressed txout
   143  //    header code                                      header code
   144  //
   145  //  - Last spent output:
   146  //    - header code: 0x00 (was not the final unspent output for containing tx)
   147  //    - transaction version: Nothing since header code is 0
   148  //    - compressed txout:
   149  //      - 0x91f20f: VLQ-encoded compressed amount for 34405000000 (344.05 BTC)
   150  //      - 0x00: special script type pay-to-pubkey-hash
   151  //      - 0x6e...86: pubkey hash
   152  //  - Second to last spent output:
   153  //    - header code: 0x8b9970 (not coinbase, height 100024)
   154  //    - transaction version: 1
   155  //    - compressed txout:
   156  //      - 0x86c647: VLQ-encoded compressed amount for 13761000000 (137.61 BTC)
   157  //      - 0x00: special script type pay-to-pubkey-hash
   158  //      - 0xb2...ec: pubkey hash
   159  // -----------------------------------------------------------------------------
   160  
   161  // spentTxOut contains a spent transaction output and potentially additional
   162  // contextual information such as whether or not it was contained in a coinbase
   163  // transaction, the version of the transaction it was contained in, and which
   164  // block height the containing transaction was included in.  As described in
   165  // the comments above, the additional contextual information will only be valid
   166  // when this spent txout is spending the last unspent output of the containing
   167  // transaction.
   168  type spentTxOut struct {
   169  	compressed bool   // The amount and public key script are compressed.
   170  	version    int32  // The version of creating tx.
   171  	amount     int64  // The amount of the output.
   172  	pkScript   []byte // The public key script for the output.
   173  
   174  	// These fields are only set when this is spending the final output of
   175  	// the creating tx.
   176  	height     int32 // Height of the the block containing the creating tx.
   177  	isCoinBase bool  // Whether creating tx is a coinbase.
   178  }
   179  
   180  // spentTxOutHeaderCode returns the calculated header code to be used when
   181  // serializing the provided stxo entry.
   182  func spentTxOutHeaderCode(stxo *spentTxOut) uint64 {
   183  	// The header code is 0 when there is no height set for the stxo.
   184  	if stxo.height == 0 {
   185  		return 0
   186  	}
   187  
   188  	// As described in the serialization format comments, the header code
   189  	// encodes the height shifted over one bit and the coinbase flag in the
   190  	// lowest bit.
   191  	headerCode := uint64(stxo.height) << 1
   192  	if stxo.isCoinBase {
   193  		headerCode |= 0x01
   194  	}
   195  
   196  	return headerCode
   197  }
   198  
   199  // spentTxOutSerializeSize returns the number of bytes it would take to
   200  // serialize the passed stxo according to the format described above.
   201  func spentTxOutSerializeSize(stxo *spentTxOut) int {
   202  	headerCode := spentTxOutHeaderCode(stxo)
   203  	size := serializeSizeVLQ(headerCode)
   204  	if headerCode != 0 {
   205  		size += serializeSizeVLQ(uint64(stxo.version))
   206  	}
   207  	return size + compressedTxOutSize(uint64(stxo.amount), stxo.pkScript,
   208  		stxo.version, stxo.compressed)
   209  }
   210  
   211  // putSpentTxOut serializes the passed stxo according to the format described
   212  // above directly into the passed target byte slice.  The target byte slice must
   213  // be at least large enough to handle the number of bytes returned by the
   214  // spentTxOutSerializeSize function or it will panic.
   215  func putSpentTxOut(target []byte, stxo *spentTxOut) int {
   216  	headerCode := spentTxOutHeaderCode(stxo)
   217  	offset := putVLQ(target, headerCode)
   218  	if headerCode != 0 {
   219  		offset += putVLQ(target[offset:], uint64(stxo.version))
   220  	}
   221  	return offset + putCompressedTxOut(target[offset:], uint64(stxo.amount),
   222  		stxo.pkScript, stxo.version, stxo.compressed)
   223  }
   224  
   225  // decodeSpentTxOut decodes the passed serialized stxo entry, possibly followed
   226  // by other data, into the passed stxo struct.  It returns the number of bytes
   227  // read.
   228  //
   229  // Since the serialized stxo entry does not contain the height, version, or
   230  // coinbase flag of the containing transaction when it still has utxos, the
   231  // caller is responsible for passing in the containing transaction version in
   232  // that case.  The provided version is ignore when it is serialized as a part of
   233  // the stxo.
   234  //
   235  // An error will be returned if the version is not serialized as a part of the
   236  // stxo and is also not provided to the function.
   237  func decodeSpentTxOut(serialized []byte, stxo *spentTxOut, txVersion int32) (int, error) {
   238  	// Ensure there are bytes to decode.
   239  	if len(serialized) == 0 {
   240  		return 0, errDeserialize("no serialized bytes")
   241  	}
   242  
   243  	// Deserialize the header code.
   244  	code, offset := deserializeVLQ(serialized)
   245  	if offset >= len(serialized) {
   246  		return offset, errDeserialize("unexpected end of data after " +
   247  			"header code")
   248  	}
   249  
   250  	// Decode the header code and deserialize the containing transaction
   251  	// version if needed.
   252  	//
   253  	// Bit 0 indicates containing transaction is a coinbase.
   254  	// Bits 1-x encode height of containing transaction.
   255  	if code != 0 {
   256  		version, bytesRead := deserializeVLQ(serialized[offset:])
   257  		offset += bytesRead
   258  		if offset >= len(serialized) {
   259  			return offset, errDeserialize("unexpected end of data " +
   260  				"after version")
   261  		}
   262  
   263  		stxo.isCoinBase = code&0x01 != 0
   264  		stxo.height = int32(code >> 1)
   265  		stxo.version = int32(version)
   266  	} else {
   267  		// Ensure a tx version was specified if the stxo did not encode
   268  		// it.  This should never happen unless there is database
   269  		// corruption or this function is being called without the
   270  		// proper state.
   271  		if txVersion == 0 {
   272  			return offset, AssertError("decodeSpentTxOut called " +
   273  				"without a containing tx version when the " +
   274  				"serialized stxo that does not encode the " +
   275  				"version")
   276  		}
   277  		stxo.version = txVersion
   278  	}
   279  
   280  	// Decode the compressed txout.
   281  	compAmount, compScript, bytesRead, err := decodeCompressedTxOut(
   282  		serialized[offset:], stxo.version)
   283  	offset += bytesRead
   284  	if err != nil {
   285  		return offset, errDeserialize(fmt.Sprintf("unable to decode "+
   286  			"txout: %v", err))
   287  	}
   288  	stxo.amount = int64(compAmount)
   289  	stxo.pkScript = compScript
   290  	stxo.compressed = true
   291  	return offset, nil
   292  }
   293  
   294  // deserializeSpendJournalEntry decodes the passed serialized byte slice into a
   295  // slice of spent txouts according to the format described in detail above.
   296  //
   297  // Since the serialization format is not self describing, as noted in the
   298  // format comments, this function also requires the transactions that spend the
   299  // txouts and a utxo view that contains any remaining existing utxos in the
   300  // transactions referenced by the inputs to the passed transasctions.
   301  func deserializeSpendJournalEntry(serialized []byte, txns []*wire.MsgTx, view *UtxoViewpoint) ([]spentTxOut, error) {
   302  	// Calculate the total number of stxos.
   303  	var numStxos int
   304  	for _, tx := range txns {
   305  		numStxos += len(tx.TxIn)
   306  	}
   307  
   308  	// When a block has no spent txouts there is nothing to serialize.
   309  	if len(serialized) == 0 {
   310  		// Ensure the block actually has no stxos.  This should never
   311  		// happen unless there is database corruption or an empty entry
   312  		// erroneously made its way into the database.
   313  		if numStxos != 0 {
   314  			return nil, AssertError(fmt.Sprintf("mismatched spend "+
   315  				"journal serialization - no serialization for "+
   316  				"expected %d stxos", numStxos))
   317  		}
   318  
   319  		return nil, nil
   320  	}
   321  
   322  	// Loop backwards through all transactions so everything is read in
   323  	// reverse order to match the serialization order.
   324  	stxoIdx := numStxos - 1
   325  	stxoInFlight := make(map[wire.ShaHash]int)
   326  	offset := 0
   327  	stxos := make([]spentTxOut, numStxos)
   328  	for txIdx := len(txns) - 1; txIdx > -1; txIdx-- {
   329  		tx := txns[txIdx]
   330  
   331  		// Loop backwards through all of the transaction inputs and read
   332  		// the associated stxo.
   333  		for txInIdx := len(tx.TxIn) - 1; txInIdx > -1; txInIdx-- {
   334  			txIn := tx.TxIn[txInIdx]
   335  			stxo := &stxos[stxoIdx]
   336  			stxoIdx--
   337  
   338  			// Get the transaction version for the stxo based on
   339  			// whether or not it should be serialized as a part of
   340  			// the stxo.  Recall that it is only serialized when the
   341  			// stxo spends the final utxo of a transaction.  Since
   342  			// they are deserialized in reverse order, this means
   343  			// the first time an entry for a given containing tx is
   344  			// encountered that is not already in the utxo view it
   345  			// must have been the final spend and thus the extra
   346  			// data will be serialized with the stxo.  Otherwise,
   347  			// the version must be pulled from the utxo entry.
   348  			//
   349  			// Since the view is not actually modified as the stxos
   350  			// are read here and it's possible later entries
   351  			// reference earlier ones, an inflight map is maintained
   352  			// to detect this case and pull the tx version from the
   353  			// entry that contains the version information as just
   354  			// described.
   355  			var txVersion int32
   356  			originHash := &txIn.PreviousOutPoint.Hash
   357  			entry := view.LookupEntry(originHash)
   358  			if entry != nil {
   359  				txVersion = entry.Version()
   360  			} else if idx, ok := stxoInFlight[*originHash]; ok {
   361  				txVersion = stxos[idx].version
   362  			} else {
   363  				stxoInFlight[*originHash] = stxoIdx + 1
   364  			}
   365  
   366  			n, err := decodeSpentTxOut(serialized[offset:], stxo,
   367  				txVersion)
   368  			offset += n
   369  			if err != nil {
   370  				return nil, errDeserialize(fmt.Sprintf("unable "+
   371  					"to decode stxo for %v: %v",
   372  					txIn.PreviousOutPoint, err))
   373  			}
   374  		}
   375  	}
   376  
   377  	return stxos, nil
   378  }
   379  
   380  // serializeSpendJournalEntry serializes all of the passed spent txouts into a
   381  // single byte slice according to the format described in detail above.
   382  func serializeSpendJournalEntry(stxos []spentTxOut) []byte {
   383  	if len(stxos) == 0 {
   384  		return nil
   385  	}
   386  
   387  	// Calculate the size needed to serialize the entire journal entry.
   388  	var size int
   389  	for i := range stxos {
   390  		size += spentTxOutSerializeSize(&stxos[i])
   391  	}
   392  	serialized := make([]byte, size)
   393  
   394  	// Serialize each individual stxo directly into the slice in reverse
   395  	// order one after the other.
   396  	var offset int
   397  	for i := len(stxos) - 1; i > -1; i-- {
   398  		offset += putSpentTxOut(serialized[offset:], &stxos[i])
   399  	}
   400  
   401  	return serialized
   402  }
   403  
   404  // dbFetchSpendJournalEntry fetches the spend journal entry for the passed
   405  // block and deserializes it into a slice of spent txout entries.  The provided
   406  // view MUST have the utxos referenced by all of the transactions available for
   407  // the passed block since that information is required to reconstruct the spent
   408  // txouts.
   409  func dbFetchSpendJournalEntry(dbTx database.Tx, block *godashutil.Block, view *UtxoViewpoint) ([]spentTxOut, error) {
   410  	// Exclude the coinbase transaction since it can't spend anything.
   411  	spendBucket := dbTx.Metadata().Bucket(spendJournalBucketName)
   412  	serialized := spendBucket.Get(block.Sha()[:])
   413  	blockTxns := block.MsgBlock().Transactions[1:]
   414  	stxos, err := deserializeSpendJournalEntry(serialized, blockTxns, view)
   415  	if err != nil {
   416  		// Ensure any deserialization errors are returned as database
   417  		// corruption errors.
   418  		if isDeserializeErr(err) {
   419  			return nil, database.Error{
   420  				ErrorCode: database.ErrCorruption,
   421  				Description: fmt.Sprintf("corrupt spend "+
   422  					"information for %v: %v", block.Sha(),
   423  					err),
   424  			}
   425  		}
   426  
   427  		return nil, err
   428  	}
   429  
   430  	return stxos, nil
   431  }
   432  
   433  // dbPutSpendJournalEntry uses an existing database transaction to update the
   434  // spend journal entry for the given block hash using the provided slice of
   435  // spent txouts.   The spent txouts slice must contain an entry for every txout
   436  // the transactions in the block spend in the order they are spent.
   437  func dbPutSpendJournalEntry(dbTx database.Tx, blockHash *wire.ShaHash, stxos []spentTxOut) error {
   438  	spendBucket := dbTx.Metadata().Bucket(spendJournalBucketName)
   439  	serialized := serializeSpendJournalEntry(stxos)
   440  	return spendBucket.Put(blockHash[:], serialized)
   441  }
   442  
   443  // dbRemoveSpendJournalEntry uses an existing database transaction to remove the
   444  // spend journal entry for the passed block hash.
   445  func dbRemoveSpendJournalEntry(dbTx database.Tx, blockHash *wire.ShaHash) error {
   446  	spendBucket := dbTx.Metadata().Bucket(spendJournalBucketName)
   447  	return spendBucket.Delete(blockHash[:])
   448  }
   449  
   450  // -----------------------------------------------------------------------------
   451  // The unspent transaction output (utxo) set consists of an entry for each
   452  // transaction which contains a utxo serialized using a format that is highly
   453  // optimized to reduce space using domain specific compression algorithms.  This
   454  // format is a slightly modified version of the format used in Bitcoin Core.
   455  //
   456  // The serialized format is:
   457  //
   458  //   <version><height><header code><unspentness bitmap>[<compressed txouts>,...]
   459  //
   460  //   Field                Type     Size
   461  //   version              VLQ      variable
   462  //   block height         VLQ      variable
   463  //   header code          VLQ      variable
   464  //   unspentness bitmap   []byte   variable
   465  //   compressed txouts
   466  //     compressed amount  VLQ      variable
   467  //     compressed script  []byte   variable
   468  //
   469  // The serialized header code format is:
   470  //   bit 0 - containing transaction is a coinbase
   471  //   bit 1 - output zero is unspent
   472  //   bit 2 - output one is unspent
   473  //   bits 3-x - number of bytes in unspentness bitmap.  When both bits 1 and 2
   474  //     are unset, it encodes N-1 since there must be at least one unspent
   475  //     output.
   476  //
   477  // The rationale for the header code scheme is as follows:
   478  //   - Transactions which only pay to a single output and a change output are
   479  //     extremely common, thus an extra byte for the unspentness bitmap can be
   480  //     avoided for them by encoding those two outputs in the low order bits.
   481  //   - Given it is encoded as a VLQ which can encode values up to 127 with a
   482  //     single byte, that leaves 4 bits to represent the number of bytes in the
   483  //     unspentness bitmap while still only consuming a single byte for the
   484  //     header code.  In other words, an unspentness bitmap with up to 120
   485  //     transaction outputs can be encoded with a single-byte header code.
   486  //     This covers the vast majority of transactions.
   487  //   - Encoding N-1 bytes when both bits 1 and 2 are unset allows an additional
   488  //     8 outpoints to be encoded before causing the header code to require an
   489  //     additional byte.
   490  //
   491  // Example 1:
   492  // From tx in main blockchain:
   493  // Blk 1, 0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098
   494  //
   495  //    010103320496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52
   496  //    <><><><------------------------------------------------------------------>
   497  //     | | \--------\                               |
   498  //     | height     |                      compressed txout 0
   499  //  version    header code
   500  //
   501  //  - version: 1
   502  //  - height: 1
   503  //  - header code: 0x03 (coinbase, output zero unspent, 0 bytes of unspentness)
   504  //  - unspentness: Nothing since it is zero bytes
   505  //  - compressed txout 0:
   506  //    - 0x32: VLQ-encoded compressed amount for 5000000000 (50 BTC)
   507  //    - 0x04: special script type pay-to-pubkey
   508  //    - 0x96...52: x-coordinate of the pubkey
   509  //
   510  // Example 2:
   511  // From tx in main blockchain:
   512  // Blk 113931, 4a16969aa4764dd7507fc1de7f0baa4850a246de90c45e59a3207f9a26b5036f
   513  //
   514  //    0185f90b0a011200e2ccd6ec7c6e2e581349c77e067385fa8236bf8a800900b8025be1b3efc63b0ad48e7f9f10e87544528d58
   515  //    <><----><><><------------------------------------------><-------------------------------------------->
   516  //     |    |  | \-------------------\            |                            |
   517  //  version |  \--------\       unspentness       |                    compressed txout 2
   518  //        height     header code          compressed txout 0
   519  //
   520  //  - version: 1
   521  //  - height: 113931
   522  //  - header code: 0x0a (output zero unspent, 1 byte in unspentness bitmap)
   523  //  - unspentness: [0x01] (bit 0 is set, so output 0+2 = 2 is unspent)
   524  //    NOTE: It's +2 since the first two outputs are encoded in the header code
   525  //  - compressed txout 0:
   526  //    - 0x12: VLQ-encoded compressed amount for 20000000 (0.2 BTC)
   527  //    - 0x00: special script type pay-to-pubkey-hash
   528  //    - 0xe2...8a: pubkey hash
   529  //  - compressed txout 2:
   530  //    - 0x8009: VLQ-encoded compressed amount for 15000000 (0.15 BTC)
   531  //    - 0x00: special script type pay-to-pubkey-hash
   532  //    - 0xb8...58: pubkey hash
   533  //
   534  // Example 3:
   535  // From tx in main blockchain:
   536  // Blk 338156, 1b02d1c8cfef60a189017b9a420c682cf4a0028175f2f563209e4ff61c8c3620
   537  //
   538  //    0193d06c100000108ba5b9e763011dd46a006572d820e448e12d2bbb38640bc718e6
   539  //    <><----><><----><-------------------------------------------------->
   540  //     |    |  |   \-----------------\            |
   541  //  version |  \--------\       unspentness       |
   542  //        height     header code          compressed txout 22
   543  //
   544  //  - version: 1
   545  //  - height: 338156
   546  //  - header code: 0x10 (2+1 = 3 bytes in unspentness bitmap)
   547  //    NOTE: It's +1 since neither bit 1 nor 2 are set, so N-1 is encoded.
   548  //  - unspentness: [0x00 0x00 0x10] (bit 20 is set, so output 20+2 = 22 is unspent)
   549  //    NOTE: It's +2 since the first two outputs are encoded in the header code
   550  //  - compressed txout 22:
   551  //    - 0x8ba5b9e763: VLQ-encoded compressed amount for 366875659 (3.66875659 BTC)
   552  //    - 0x01: special script type pay-to-script-hash
   553  //    - 0x1d...e6: script hash
   554  // -----------------------------------------------------------------------------
   555  
   556  // utxoEntryHeaderCode returns the calculated header code to be used when
   557  // serializing the provided utxo entry and the number of bytes needed to encode
   558  // the unspentness bitmap.
   559  func utxoEntryHeaderCode(entry *UtxoEntry, highestOutputIndex uint32) (uint64, int, error) {
   560  	// The first two outputs are encoded separately, so offset the index
   561  	// accordingly to calculate the correct number of bytes needed to encode
   562  	// up to the highest unspent output index.
   563  	numBitmapBytes := int((highestOutputIndex + 6) / 8)
   564  
   565  	// As previously described, one less than the number of bytes is encoded
   566  	// when both output 0 and 1 are spent because there must be at least one
   567  	// unspent output.  Adjust the number of bytes to encode accordingly and
   568  	// encode the value by shifting it over 3 bits.
   569  	output0Unspent := !entry.IsOutputSpent(0)
   570  	output1Unspent := !entry.IsOutputSpent(1)
   571  	var numBitmapBytesAdjustment int
   572  	if !output0Unspent && !output1Unspent {
   573  		if numBitmapBytes == 0 {
   574  			return 0, 0, AssertError("attempt to serialize utxo " +
   575  				"header for fully spent transaction")
   576  		}
   577  		numBitmapBytesAdjustment = 1
   578  	}
   579  	headerCode := uint64(numBitmapBytes-numBitmapBytesAdjustment) << 3
   580  
   581  	// Set the coinbase, output 0, and output 1 bits in the header code
   582  	// accordingly.
   583  	if entry.isCoinBase {
   584  		headerCode |= 0x01 // bit 0
   585  	}
   586  	if output0Unspent {
   587  		headerCode |= 0x02 // bit 1
   588  	}
   589  	if output1Unspent {
   590  		headerCode |= 0x04 // bit 2
   591  	}
   592  
   593  	return headerCode, numBitmapBytes, nil
   594  }
   595  
   596  // serializeUtxoEntry returns the entry serialized to a format that is suitable
   597  // for long-term storage.  The format is described in detail above.
   598  func serializeUtxoEntry(entry *UtxoEntry) ([]byte, error) {
   599  	// Fully spent entries have no serialization.
   600  	if entry.IsFullySpent() {
   601  		return nil, nil
   602  	}
   603  
   604  	// Determine the output order by sorting the sparse output index keys.
   605  	outputOrder := make([]int, 0, len(entry.sparseOutputs))
   606  	for outputIndex := range entry.sparseOutputs {
   607  		outputOrder = append(outputOrder, int(outputIndex))
   608  	}
   609  	sort.Ints(outputOrder)
   610  
   611  	// Encode the header code and determine the number of bytes the
   612  	// unspentness bitmap needs.
   613  	highIndex := uint32(outputOrder[len(outputOrder)-1])
   614  	headerCode, numBitmapBytes, err := utxoEntryHeaderCode(entry, highIndex)
   615  	if err != nil {
   616  		return nil, err
   617  	}
   618  
   619  	// Calculate the size needed to serialize the entry.
   620  	size := serializeSizeVLQ(uint64(entry.version)) +
   621  		serializeSizeVLQ(uint64(entry.blockHeight)) +
   622  		serializeSizeVLQ(headerCode) + numBitmapBytes
   623  	for _, outputIndex := range outputOrder {
   624  		out := entry.sparseOutputs[uint32(outputIndex)]
   625  		if out.spent {
   626  			continue
   627  		}
   628  		size += compressedTxOutSize(uint64(out.amount), out.pkScript,
   629  			entry.version, out.compressed)
   630  	}
   631  
   632  	// Serialize the version, block height of the containing transaction,
   633  	// and header code.
   634  	serialized := make([]byte, size)
   635  	offset := putVLQ(serialized, uint64(entry.version))
   636  	offset += putVLQ(serialized[offset:], uint64(entry.blockHeight))
   637  	offset += putVLQ(serialized[offset:], headerCode)
   638  
   639  	// Serialize the unspentness bitmap.
   640  	for i := uint32(0); i < uint32(numBitmapBytes); i++ {
   641  		unspentBits := byte(0)
   642  		for j := uint32(0); j < 8; j++ {
   643  			// The first 2 outputs are encoded via the header code,
   644  			// so adjust the output index accordingly.
   645  			if !entry.IsOutputSpent(2 + i*8 + j) {
   646  				unspentBits |= 1 << uint8(j)
   647  			}
   648  		}
   649  		serialized[offset] = unspentBits
   650  		offset++
   651  	}
   652  
   653  	// Serialize the compressed unspent transaction outputs.  Outputs that
   654  	// are already compressed are serialized without modifications.
   655  	for _, outputIndex := range outputOrder {
   656  		out := entry.sparseOutputs[uint32(outputIndex)]
   657  		if out.spent {
   658  			continue
   659  		}
   660  
   661  		offset += putCompressedTxOut(serialized[offset:],
   662  			uint64(out.amount), out.pkScript, entry.version,
   663  			out.compressed)
   664  	}
   665  
   666  	return serialized, nil
   667  }
   668  
   669  // deserializeUtxoEntry decodes a utxo entry from the passed serialized byte
   670  // slice into a new UtxoEntry using a format that is suitable for long-term
   671  // storage.  The format is described in detail above.
   672  func deserializeUtxoEntry(serialized []byte) (*UtxoEntry, error) {
   673  	// Deserialize the version.
   674  	version, bytesRead := deserializeVLQ(serialized)
   675  	offset := bytesRead
   676  	if offset >= len(serialized) {
   677  		return nil, errDeserialize("unexpected end of data after version")
   678  	}
   679  
   680  	// Deserialize the block height.
   681  	blockHeight, bytesRead := deserializeVLQ(serialized[offset:])
   682  	offset += bytesRead
   683  	if offset >= len(serialized) {
   684  		return nil, errDeserialize("unexpected end of data after height")
   685  	}
   686  
   687  	// Deserialize the header code.
   688  	code, bytesRead := deserializeVLQ(serialized[offset:])
   689  	offset += bytesRead
   690  	if offset >= len(serialized) {
   691  		return nil, errDeserialize("unexpected end of data after header")
   692  	}
   693  
   694  	// Decode the header code.
   695  	//
   696  	// Bit 0 indicates whether the containing transaction is a coinbase.
   697  	// Bit 1 indicates output 0 is unspent.
   698  	// Bit 2 indicates output 1 is unspent.
   699  	// Bits 3-x encodes the number of non-zero unspentness bitmap bytes that
   700  	// follow.  When both output 0 and 1 are spent, it encodes N-1.
   701  	isCoinBase := code&0x01 != 0
   702  	output0Unspent := code&0x02 != 0
   703  	output1Unspent := code&0x04 != 0
   704  	numBitmapBytes := code >> 3
   705  	if !output0Unspent && !output1Unspent {
   706  		numBitmapBytes++
   707  	}
   708  
   709  	// Ensure there are enough bytes left to deserialize the unspentness
   710  	// bitmap.
   711  	if uint64(len(serialized[offset:])) < numBitmapBytes {
   712  		return nil, errDeserialize("unexpected end of data for " +
   713  			"unspentness bitmap")
   714  	}
   715  
   716  	// Create a new utxo entry with the details deserialized above to house
   717  	// all of the utxos.
   718  	entry := newUtxoEntry(int32(version), isCoinBase, int32(blockHeight))
   719  
   720  	// Add sparse output for unspent outputs 0 and 1 as needed based on the
   721  	// details provided by the header code.
   722  	var outputIndexes []uint32
   723  	if output0Unspent {
   724  		outputIndexes = append(outputIndexes, 0)
   725  	}
   726  	if output1Unspent {
   727  		outputIndexes = append(outputIndexes, 1)
   728  	}
   729  
   730  	// Decode the unspentness bitmap adding a sparse output for each unspent
   731  	// output.
   732  	for i := uint32(0); i < uint32(numBitmapBytes); i++ {
   733  		unspentBits := serialized[offset]
   734  		for j := uint32(0); j < 8; j++ {
   735  			if unspentBits&0x01 != 0 {
   736  				// The first 2 outputs are encoded via the
   737  				// header code, so adjust the output number
   738  				// accordingly.
   739  				outputNum := 2 + i*8 + j
   740  				outputIndexes = append(outputIndexes, outputNum)
   741  			}
   742  			unspentBits >>= 1
   743  		}
   744  		offset++
   745  	}
   746  
   747  	// Decode and add all of the utxos.
   748  	for i, outputIndex := range outputIndexes {
   749  		// Decode the next utxo.  The script and amount fields of the
   750  		// utxo output are left compressed so decompression can be
   751  		// avoided on those that are not accessed.  This is done since
   752  		// it is quite common for a redeeming transaction to only
   753  		// reference a single utxo from a referenced transaction.
   754  		compAmount, compScript, bytesRead, err := decodeCompressedTxOut(
   755  			serialized[offset:], int32(version))
   756  		if err != nil {
   757  			return nil, errDeserialize(fmt.Sprintf("unable to "+
   758  				"decode utxo at index %d: %v", i, err))
   759  		}
   760  		offset += bytesRead
   761  
   762  		entry.sparseOutputs[outputIndex] = &utxoOutput{
   763  			spent:      false,
   764  			compressed: true,
   765  			pkScript:   compScript,
   766  			amount:     int64(compAmount),
   767  		}
   768  	}
   769  
   770  	return entry, nil
   771  }
   772  
   773  // dbFetchUtxoEntry uses an existing database transaction to fetch all unspent
   774  // outputs for the provided Bitcoin transaction hash from the utxo set.
   775  //
   776  // When there is no entry for the provided hash, nil will be returned for the
   777  // both the entry and the error.
   778  func dbFetchUtxoEntry(dbTx database.Tx, hash *wire.ShaHash) (*UtxoEntry, error) {
   779  	// Fetch the unspent transaction output information for the passed
   780  	// transaction hash.  Return now when there is no entry.
   781  	utxoBucket := dbTx.Metadata().Bucket(utxoSetBucketName)
   782  	serializedUtxo := utxoBucket.Get(hash[:])
   783  	if serializedUtxo == nil {
   784  		return nil, nil
   785  	}
   786  
   787  	// A non-nil zero-length entry means there is an entry in the database
   788  	// for a fully spent transaction which should never be the case.
   789  	if len(serializedUtxo) == 0 {
   790  		return nil, AssertError(fmt.Sprintf("database contains entry "+
   791  			"for fully spent tx %v", hash))
   792  	}
   793  
   794  	// Deserialize the utxo entry and return it.
   795  	entry, err := deserializeUtxoEntry(serializedUtxo)
   796  	if err != nil {
   797  		// Ensure any deserialization errors are returned as database
   798  		// corruption errors.
   799  		if isDeserializeErr(err) {
   800  			return nil, database.Error{
   801  				ErrorCode: database.ErrCorruption,
   802  				Description: fmt.Sprintf("corrupt utxo entry "+
   803  					"for %v: %v", hash, err),
   804  			}
   805  		}
   806  
   807  		return nil, err
   808  	}
   809  
   810  	return entry, nil
   811  }
   812  
   813  // dbPutUtxoView uses an existing database transaction to update the utxo set
   814  // in the database based on the provided utxo view contents and state.  In
   815  // particular, only the entries that have been marked as modified are written
   816  // to the database.
   817  func dbPutUtxoView(dbTx database.Tx, view *UtxoViewpoint) error {
   818  	utxoBucket := dbTx.Metadata().Bucket(utxoSetBucketName)
   819  	for txHashIter, entry := range view.entries {
   820  		// No need to update the database if the entry was not modified.
   821  		if entry == nil || !entry.modified {
   822  			continue
   823  		}
   824  
   825  		// Serialize the utxo entry without any entries that have been
   826  		// spent.
   827  		serialized, err := serializeUtxoEntry(entry)
   828  		if err != nil {
   829  			return err
   830  		}
   831  
   832  		// Make a copy of the hash because the iterator changes on each
   833  		// loop iteration and thus slicing it directly would cause the
   834  		// data to change out from under the put/delete funcs below.
   835  		txHash := txHashIter
   836  
   837  		// Remove the utxo entry if it is now fully spent.
   838  		if serialized == nil {
   839  			if err := utxoBucket.Delete(txHash[:]); err != nil {
   840  				return err
   841  			}
   842  
   843  			continue
   844  		}
   845  
   846  		// At this point the utxo entry is not fully spent, so store its
   847  		// serialization in the database.
   848  		err = utxoBucket.Put(txHash[:], serialized)
   849  		if err != nil {
   850  			return err
   851  		}
   852  	}
   853  
   854  	return nil
   855  }
   856  
   857  // -----------------------------------------------------------------------------
   858  // The block index consists of two buckets with an entry for every block in the
   859  // main chain.  One bucket is for the hash to height mapping and the other is
   860  // for the height to hash mapping.
   861  //
   862  // The serialized format for values in the hash to height bucket is:
   863  //   <height>
   864  //
   865  //   Field      Type     Size
   866  //   height     uint32   4 bytes
   867  //
   868  // The serialized format for values in the height to hash bucket is:
   869  //   <hash>
   870  //
   871  //   Field      Type           Size
   872  //   hash       wire.ShaHash   wire.HashSize
   873  // -----------------------------------------------------------------------------
   874  
   875  // dbPutBlockIndex uses an existing database transaction to update or add the
   876  // block index entries for the hash to height and height to hash mappings for
   877  // the provided values.
   878  func dbPutBlockIndex(dbTx database.Tx, hash *wire.ShaHash, height int32) error {
   879  	// Serialize the height for use in the index entries.
   880  	var serializedHeight [4]byte
   881  	byteOrder.PutUint32(serializedHeight[:], uint32(height))
   882  
   883  	// Add the block hash to height mapping to the index.
   884  	meta := dbTx.Metadata()
   885  	hashIndex := meta.Bucket(hashIndexBucketName)
   886  	if err := hashIndex.Put(hash[:], serializedHeight[:]); err != nil {
   887  		return err
   888  	}
   889  
   890  	// Add the block height to hash mapping to the index.
   891  	heightIndex := meta.Bucket(heightIndexBucketName)
   892  	return heightIndex.Put(serializedHeight[:], hash[:])
   893  }
   894  
   895  // dbRemoveBlockIndex uses an existing database transaction remove block index
   896  // entries from the hash to height and height to hash mappings for the provided
   897  // values.
   898  func dbRemoveBlockIndex(dbTx database.Tx, hash *wire.ShaHash, height int32) error {
   899  	// Remove the block hash to height mapping.
   900  	meta := dbTx.Metadata()
   901  	hashIndex := meta.Bucket(hashIndexBucketName)
   902  	if err := hashIndex.Delete(hash[:]); err != nil {
   903  		return err
   904  	}
   905  
   906  	// Remove the block height to hash mapping.
   907  	var serializedHeight [4]byte
   908  	byteOrder.PutUint32(serializedHeight[:], uint32(height))
   909  	heightIndex := meta.Bucket(heightIndexBucketName)
   910  	return heightIndex.Delete(serializedHeight[:])
   911  }
   912  
   913  // dbFetchHeightByHash uses an existing database transaction to retrieve the
   914  // height for the provided hash from the index.
   915  func dbFetchHeightByHash(dbTx database.Tx, hash *wire.ShaHash) (int32, error) {
   916  	meta := dbTx.Metadata()
   917  	hashIndex := meta.Bucket(hashIndexBucketName)
   918  	serializedHeight := hashIndex.Get(hash[:])
   919  	if serializedHeight == nil {
   920  		str := fmt.Sprintf("block %s is not in the main chain", hash)
   921  		return 0, errNotInMainChain(str)
   922  	}
   923  
   924  	return int32(byteOrder.Uint32(serializedHeight)), nil
   925  }
   926  
   927  // dbFetchHashByHeight uses an existing database transaction to retrieve the
   928  // hash for the provided height from the index.
   929  func dbFetchHashByHeight(dbTx database.Tx, height int32) (*wire.ShaHash, error) {
   930  	var serializedHeight [4]byte
   931  	byteOrder.PutUint32(serializedHeight[:], uint32(height))
   932  
   933  	meta := dbTx.Metadata()
   934  	heightIndex := meta.Bucket(heightIndexBucketName)
   935  	hashBytes := heightIndex.Get(serializedHeight[:])
   936  	if hashBytes == nil {
   937  		str := fmt.Sprintf("no block at height %d exists", height)
   938  		return nil, errNotInMainChain(str)
   939  	}
   940  
   941  	var hash wire.ShaHash
   942  	copy(hash[:], hashBytes)
   943  	return &hash, nil
   944  }
   945  
   946  // -----------------------------------------------------------------------------
   947  // The best chain state consists of the best block hash and height, the total
   948  // number of transactions up to and including those in the best block, and the
   949  // accumulated work sum up to and including the best block.
   950  //
   951  // The serialized format is:
   952  //
   953  //   <block hash><block height><total txns><work sum length><work sum>
   954  //
   955  //   Field             Type           Size
   956  //   block hash        wire.ShaHash   wire.HashSize
   957  //   block height      uint32         4 bytes
   958  //   total txns        uint64         8 bytes
   959  //   work sum length   uint32         4 bytes
   960  //   work sum          big.Int        work sum length
   961  // -----------------------------------------------------------------------------
   962  
   963  // bestChainState represents the data to be stored the database for the current
   964  // best chain state.
   965  type bestChainState struct {
   966  	hash      wire.ShaHash
   967  	height    uint32
   968  	totalTxns uint64
   969  	workSum   *big.Int
   970  }
   971  
   972  // serializeBestChainState returns the serialization of the passed block best
   973  // chain state.  This is data to be stored in the chain state bucket.
   974  func serializeBestChainState(state bestChainState) []byte {
   975  	// Calculate the full size needed to serialize the chain state.
   976  	workSumBytes := state.workSum.Bytes()
   977  	workSumBytesLen := uint32(len(workSumBytes))
   978  	serializedLen := wire.HashSize + 4 + 8 + 4 + workSumBytesLen
   979  
   980  	// Serialize the chain state.
   981  	serializedData := make([]byte, serializedLen)
   982  	copy(serializedData[0:wire.HashSize], state.hash[:])
   983  	offset := uint32(wire.HashSize)
   984  	byteOrder.PutUint32(serializedData[offset:], state.height)
   985  	offset += 4
   986  	byteOrder.PutUint64(serializedData[offset:], state.totalTxns)
   987  	offset += 8
   988  	byteOrder.PutUint32(serializedData[offset:], workSumBytesLen)
   989  	offset += 4
   990  	copy(serializedData[offset:], workSumBytes)
   991  	return serializedData[:]
   992  }
   993  
   994  // deserializeBestChainState deserializes the passed serialized best chain
   995  // state.  This is data stored in the chain state bucket and is updated after
   996  // every block is connected or disconnected form the main chain.
   997  // block.
   998  func deserializeBestChainState(serializedData []byte) (bestChainState, error) {
   999  	// Ensure the serialized data has enough bytes to properly deserialize
  1000  	// the hash, height, total transactions, and work sum length.
  1001  	if len(serializedData) < wire.HashSize+16 {
  1002  		return bestChainState{}, database.Error{
  1003  			ErrorCode:   database.ErrCorruption,
  1004  			Description: "corrupt best chain state",
  1005  		}
  1006  	}
  1007  
  1008  	state := bestChainState{}
  1009  	copy(state.hash[:], serializedData[0:wire.HashSize])
  1010  	offset := uint32(wire.HashSize)
  1011  	state.height = byteOrder.Uint32(serializedData[offset : offset+4])
  1012  	offset += 4
  1013  	state.totalTxns = byteOrder.Uint64(serializedData[offset : offset+8])
  1014  	offset += 8
  1015  	workSumBytesLen := byteOrder.Uint32(serializedData[offset : offset+4])
  1016  	offset += 4
  1017  
  1018  	// Ensure the serialized data has enough bytes to deserialize the work
  1019  	// sum.
  1020  	if uint32(len(serializedData[offset:])) < workSumBytesLen {
  1021  		return bestChainState{}, database.Error{
  1022  			ErrorCode:   database.ErrCorruption,
  1023  			Description: "corrupt best chain state",
  1024  		}
  1025  	}
  1026  	workSumBytes := serializedData[offset : offset+workSumBytesLen]
  1027  	state.workSum = new(big.Int).SetBytes(workSumBytes)
  1028  
  1029  	return state, nil
  1030  }
  1031  
  1032  // dbPutBestState uses an existing database transaction to update the best chain
  1033  // state with the given parameters.
  1034  func dbPutBestState(dbTx database.Tx, snapshot *BestState, workSum *big.Int) error {
  1035  	// Serialize the current best chain state.
  1036  	serializedData := serializeBestChainState(bestChainState{
  1037  		hash:      *snapshot.Hash,
  1038  		height:    uint32(snapshot.Height),
  1039  		totalTxns: snapshot.TotalTxns,
  1040  		workSum:   workSum,
  1041  	})
  1042  
  1043  	// Store the current best chain state into the database.
  1044  	return dbTx.Metadata().Put(chainStateKeyName, serializedData)
  1045  }
  1046  
  1047  // createChainState initializes both the database and the chain state to the
  1048  // genesis block.  This includes creating the necessary buckets and inserting
  1049  // the genesis block, so it must only be called on an uninitialized database.
  1050  func (b *BlockChain) createChainState() error {
  1051  	// Create a new node from the genesis block and set it as the best node.
  1052  	genesisBlock := godashutil.NewBlock(b.chainParams.GenesisBlock)
  1053  	header := &genesisBlock.MsgBlock().Header
  1054  	node := newBlockNode(header, genesisBlock.Sha(), 0)
  1055  	node.inMainChain = true
  1056  	b.bestNode = node
  1057  
  1058  	// Add the new node to the index which is used for faster lookups.
  1059  	b.index[*node.hash] = node
  1060  
  1061  	// Initialize the state related to the best block.
  1062  	numTxns := uint64(len(genesisBlock.MsgBlock().Transactions))
  1063  	blockSize := uint64(genesisBlock.MsgBlock().SerializeSize())
  1064  	b.stateSnapshot = newBestState(b.bestNode, blockSize, numTxns, numTxns)
  1065  
  1066  	// Create the initial the database chain state including creating the
  1067  	// necessary index buckets and inserting the genesis block.
  1068  	err := b.db.Update(func(dbTx database.Tx) error {
  1069  		// Create the bucket that houses the chain block hash to height
  1070  		// index.
  1071  		meta := dbTx.Metadata()
  1072  		_, err := meta.CreateBucket(hashIndexBucketName)
  1073  		if err != nil {
  1074  			return err
  1075  		}
  1076  
  1077  		// Create the bucket that houses the chain block height to hash
  1078  		// index.
  1079  		_, err = meta.CreateBucket(heightIndexBucketName)
  1080  		if err != nil {
  1081  			return err
  1082  		}
  1083  
  1084  		// Create the bucket that houses the spend journal data.
  1085  		_, err = meta.CreateBucket(spendJournalBucketName)
  1086  		if err != nil {
  1087  			return err
  1088  		}
  1089  
  1090  		// Create the bucket that houses the utxo set.  Note that the
  1091  		// genesis block coinbase transaction is intentionally not
  1092  		// inserted here since it is not spendable by consensus rules.
  1093  		_, err = meta.CreateBucket(utxoSetBucketName)
  1094  		if err != nil {
  1095  			return err
  1096  		}
  1097  
  1098  		// Add the genesis block hash to height and height to hash
  1099  		// mappings to the index.
  1100  		err = dbPutBlockIndex(dbTx, b.bestNode.hash, b.bestNode.height)
  1101  		if err != nil {
  1102  			return err
  1103  		}
  1104  
  1105  		// Store the current best chain state into the database.
  1106  		err = dbPutBestState(dbTx, b.stateSnapshot, b.bestNode.workSum)
  1107  		if err != nil {
  1108  			return err
  1109  		}
  1110  
  1111  		// Store the genesis block into the database.
  1112  		return dbTx.StoreBlock(genesisBlock)
  1113  	})
  1114  	return err
  1115  }
  1116  
  1117  // initChainState attempts to load and initialize the chain state from the
  1118  // database.  When the db does not yet contain any chain state, both it and the
  1119  // chain state are initialized to the genesis block.
  1120  func (b *BlockChain) initChainState() error {
  1121  	// Attempt to load the chain state from the database.
  1122  	var isStateInitialized bool
  1123  	err := b.db.View(func(dbTx database.Tx) error {
  1124  		// Fetch the stored chain state from the database metadata.
  1125  		// When it doesn't exist, it means the database hasn't been
  1126  		// initialized for use with chain yet, so break out now to allow
  1127  		// that to happen under a writable database transaction.
  1128  		serializedData := dbTx.Metadata().Get(chainStateKeyName)
  1129  		if serializedData == nil {
  1130  			return nil
  1131  		}
  1132  		log.Tracef("Serialized chain state: %x", serializedData)
  1133  		state, err := deserializeBestChainState(serializedData)
  1134  		if err != nil {
  1135  			return err
  1136  		}
  1137  
  1138  		// Load the raw block bytes for the best block.
  1139  		blockBytes, err := dbTx.FetchBlock(&state.hash)
  1140  		if err != nil {
  1141  			return err
  1142  		}
  1143  		var block wire.MsgBlock
  1144  		err = block.Deserialize(bytes.NewReader(blockBytes))
  1145  		if err != nil {
  1146  			return err
  1147  		}
  1148  
  1149  		// Create a new node and set it as the best node.  The preceding
  1150  		// nodes will be loaded on demand as needed.
  1151  		header := &block.Header
  1152  		node := newBlockNode(header, &state.hash, int32(state.height))
  1153  		node.inMainChain = true
  1154  		node.workSum = state.workSum
  1155  		b.bestNode = node
  1156  
  1157  		// Add the new node to the indices for faster lookups.
  1158  		prevHash := node.parentHash
  1159  		b.index[*node.hash] = node
  1160  		b.depNodes[*prevHash] = append(b.depNodes[*prevHash], node)
  1161  
  1162  		// Initialize the state related to the best block.
  1163  		blockSize := uint64(len(blockBytes))
  1164  		numTxns := uint64(len(block.Transactions))
  1165  		b.stateSnapshot = newBestState(b.bestNode, blockSize, numTxns,
  1166  			state.totalTxns)
  1167  
  1168  		isStateInitialized = true
  1169  		return nil
  1170  	})
  1171  	if err != nil {
  1172  		return err
  1173  	}
  1174  
  1175  	// There is nothing more to do if the chain state was initialized.
  1176  	if isStateInitialized {
  1177  		return nil
  1178  	}
  1179  
  1180  	// At this point the database has not already been initialized, so
  1181  	// initialize both it and the chain state to the genesis block.
  1182  	return b.createChainState()
  1183  }
  1184  
  1185  // dbFetchHeaderByHash uses an existing database transaction to retrieve the
  1186  // block header for the provided hash.
  1187  func dbFetchHeaderByHash(dbTx database.Tx, hash *wire.ShaHash) (*wire.BlockHeader, error) {
  1188  	headerBytes, err := dbTx.FetchBlockHeader(hash)
  1189  	if err != nil {
  1190  		return nil, err
  1191  	}
  1192  
  1193  	var header wire.BlockHeader
  1194  	err = header.Deserialize(bytes.NewReader(headerBytes))
  1195  	if err != nil {
  1196  		return nil, err
  1197  	}
  1198  
  1199  	return &header, nil
  1200  }
  1201  
  1202  // dbFetchHeaderByHeight uses an existing database transaction to retrieve the
  1203  // block header for the provided height.
  1204  func dbFetchHeaderByHeight(dbTx database.Tx, height int32) (*wire.BlockHeader, error) {
  1205  	hash, err := dbFetchHashByHeight(dbTx, height)
  1206  	if err != nil {
  1207  		return nil, err
  1208  	}
  1209  
  1210  	return dbFetchHeaderByHash(dbTx, hash)
  1211  }
  1212  
  1213  // dbFetchBlockByHash uses an existing database transaction to retrieve the raw
  1214  // block for the provided hash, deserialize it, retrieve the appropriate height
  1215  // from the index, and return a godashutil.Block with the height set.
  1216  func dbFetchBlockByHash(dbTx database.Tx, hash *wire.ShaHash) (*godashutil.Block, error) {
  1217  	// First find the height associated with the provided hash in the index.
  1218  	blockHeight, err := dbFetchHeightByHash(dbTx, hash)
  1219  	if err != nil {
  1220  		return nil, err
  1221  	}
  1222  
  1223  	// Load the raw block bytes from the database.
  1224  	blockBytes, err := dbTx.FetchBlock(hash)
  1225  	if err != nil {
  1226  		return nil, err
  1227  	}
  1228  
  1229  	// Create the encapsulated block and set the height appropriately.
  1230  	block, err := godashutil.NewBlockFromBytes(blockBytes)
  1231  	if err != nil {
  1232  		return nil, err
  1233  	}
  1234  	block.SetHeight(blockHeight)
  1235  
  1236  	return block, nil
  1237  }
  1238  
  1239  // dbFetchBlockByHeight uses an existing database transaction to retrieve the
  1240  // raw block for the provided height, deserialize it, and return a godashutil.Block
  1241  // with the height set.
  1242  func dbFetchBlockByHeight(dbTx database.Tx, height int32) (*godashutil.Block, error) {
  1243  	// First find the hash associated with the provided height in the index.
  1244  	hash, err := dbFetchHashByHeight(dbTx, height)
  1245  	if err != nil {
  1246  		return nil, err
  1247  	}
  1248  
  1249  	// Load the raw block bytes from the database.
  1250  	blockBytes, err := dbTx.FetchBlock(hash)
  1251  	if err != nil {
  1252  		return nil, err
  1253  	}
  1254  
  1255  	// Create the encapsulated block and set the height appropriately.
  1256  	block, err := godashutil.NewBlockFromBytes(blockBytes)
  1257  	if err != nil {
  1258  		return nil, err
  1259  	}
  1260  	block.SetHeight(height)
  1261  
  1262  	return block, nil
  1263  }
  1264  
  1265  // dbMainChainHasBlock uses an existing database transaction to return whether
  1266  // or not the main chain contains the block identified by the provided hash.
  1267  func dbMainChainHasBlock(dbTx database.Tx, hash *wire.ShaHash) bool {
  1268  	hashIndex := dbTx.Metadata().Bucket(hashIndexBucketName)
  1269  	return hashIndex.Get(hash[:]) != nil
  1270  }
  1271  
  1272  // MainChainHasBlock returns whether or not the block with the given hash is in
  1273  // the main chain.
  1274  //
  1275  // This function is safe for concurrent access.
  1276  func (b *BlockChain) MainChainHasBlock(hash *wire.ShaHash) (bool, error) {
  1277  	var exists bool
  1278  	err := b.db.View(func(dbTx database.Tx) error {
  1279  		exists = dbMainChainHasBlock(dbTx, hash)
  1280  		return nil
  1281  	})
  1282  	return exists, err
  1283  }
  1284  
  1285  // BlockHeightByHash returns the height of the block with the given hash in the
  1286  // main chain.
  1287  //
  1288  // This function is safe for concurrent access.
  1289  func (b *BlockChain) BlockHeightByHash(hash *wire.ShaHash) (int32, error) {
  1290  	var height int32
  1291  	err := b.db.View(func(dbTx database.Tx) error {
  1292  		var err error
  1293  		height, err = dbFetchHeightByHash(dbTx, hash)
  1294  		return err
  1295  	})
  1296  	return height, err
  1297  }
  1298  
  1299  // BlockHashByHeight returns the hash of the block at the given height in the
  1300  // main chain.
  1301  //
  1302  // This function is safe for concurrent access.
  1303  func (b *BlockChain) BlockHashByHeight(blockHeight int32) (*wire.ShaHash, error) {
  1304  	var hash *wire.ShaHash
  1305  	err := b.db.View(func(dbTx database.Tx) error {
  1306  		var err error
  1307  		hash, err = dbFetchHashByHeight(dbTx, blockHeight)
  1308  		return err
  1309  	})
  1310  	return hash, err
  1311  }
  1312  
  1313  // BlockByHeight returns the block at the given height in the main chain.
  1314  //
  1315  // This function is safe for concurrent access.
  1316  func (b *BlockChain) BlockByHeight(blockHeight int32) (*godashutil.Block, error) {
  1317  	var block *godashutil.Block
  1318  	err := b.db.View(func(dbTx database.Tx) error {
  1319  		var err error
  1320  		block, err = dbFetchBlockByHeight(dbTx, blockHeight)
  1321  		return err
  1322  	})
  1323  	return block, err
  1324  }
  1325  
  1326  // BlockByHash returns the block from the main chain with the given hash with
  1327  // the appropriate chain height set.
  1328  //
  1329  // This function is safe for concurrent access.
  1330  func (b *BlockChain) BlockByHash(hash *wire.ShaHash) (*godashutil.Block, error) {
  1331  	var block *godashutil.Block
  1332  	err := b.db.View(func(dbTx database.Tx) error {
  1333  		var err error
  1334  		block, err = dbFetchBlockByHash(dbTx, hash)
  1335  		return err
  1336  	})
  1337  	return block, err
  1338  }
  1339  
  1340  // HeightRange returns a range of block hashes for the given start and end
  1341  // heights.  It is inclusive of the start height and exclusive of the end
  1342  // height.  The end height will be limited to the current main chain height.
  1343  //
  1344  // This function is safe for concurrent access.
  1345  func (b *BlockChain) HeightRange(startHeight, endHeight int32) ([]wire.ShaHash, error) {
  1346  	// Ensure requested heights are sane.
  1347  	if startHeight < 0 {
  1348  		return nil, fmt.Errorf("start height of fetch range must not "+
  1349  			"be less than zero - got %d", startHeight)
  1350  	}
  1351  	if endHeight < startHeight {
  1352  		return nil, fmt.Errorf("end height of fetch range must not "+
  1353  			"be less than the start height - got start %d, end %d",
  1354  			startHeight, endHeight)
  1355  	}
  1356  
  1357  	// There is nothing to do when the start and end heights are the same,
  1358  	// so return now to avoid the chain lock and a database transaction.
  1359  	if startHeight == endHeight {
  1360  		return nil, nil
  1361  	}
  1362  
  1363  	// Grab a lock on the chain to prevent it from changing due to a reorg
  1364  	// while building the hashes.
  1365  	b.chainLock.RLock()
  1366  	defer b.chainLock.RUnlock()
  1367  
  1368  	// When the requested start height is after the most recent best chain
  1369  	// height, there is nothing to do.
  1370  	latestHeight := b.bestNode.height
  1371  	if startHeight > latestHeight {
  1372  		return nil, nil
  1373  	}
  1374  
  1375  	// Limit the ending height to the latest height of the chain.
  1376  	if endHeight > latestHeight+1 {
  1377  		endHeight = latestHeight + 1
  1378  	}
  1379  
  1380  	// Fetch as many as are available within the specified range.
  1381  	var hashList []wire.ShaHash
  1382  	err := b.db.View(func(dbTx database.Tx) error {
  1383  		hashes := make([]wire.ShaHash, 0, endHeight-startHeight)
  1384  		for i := startHeight; i < endHeight; i++ {
  1385  			hash, err := dbFetchHashByHeight(dbTx, i)
  1386  			if err != nil {
  1387  				return err
  1388  			}
  1389  			hashes = append(hashes, *hash)
  1390  		}
  1391  
  1392  		// Set the list to be returned to the constructed list.
  1393  		hashList = hashes
  1394  		return nil
  1395  	})
  1396  	return hashList, err
  1397  }