github.com/deso-protocol/core@v1.2.9/lib/blockchain.go (about)

     1  package lib
     2  
     3  import (
     4  	"bytes"
     5  	"container/list"
     6  	"encoding/hex"
     7  	"fmt"
     8  	"math"
     9  	"math/big"
    10  	"reflect"
    11  	"runtime/debug"
    12  	"sort"
    13  	"strings"
    14  	"time"
    15  
    16  	btcdchain "github.com/btcsuite/btcd/blockchain"
    17  	chainlib "github.com/btcsuite/btcd/blockchain"
    18  	"github.com/btcsuite/btcd/btcec"
    19  	"github.com/btcsuite/btcd/wire"
    20  	"github.com/davecgh/go-spew/spew"
    21  	"github.com/deso-protocol/go-deadlock"
    22  	merkletree "github.com/deso-protocol/go-merkle-tree"
    23  	"github.com/dgraph-io/badger/v3"
    24  	"github.com/golang/glog"
    25  	"github.com/pkg/errors"
    26  )
    27  
    28  // blockchain.go is the work-horse for validating DeSo blocks and updating the
    29  // database after each block is processed. The ProcessBlock function is probably
    30  // a good place to start to understand this file.
    31  
    32  const (
    33  	// MaxOrphansInMemory is the maximum number of orphan blocks that we're willing to keep in memory. We set
    34  	// a maximum here in order to prevent memory exhaustion from someone sending us too
    35  	// many unconnectedTxns.
    36  	MaxOrphansInMemory = 100
    37  
    38  	// MaxBlockIndexNodes needs to allow the block index to grow large enough to accommodate multiple
    39  	// forks of material length while allowing us to avoid an out-of-memory issue due to
    40  	// a "disk-fill" attack. Notice that because we will only ever download blocks
    41  	// after we have a header chain that has beaten all other header chains we're aware
    42  	// of, the common case for an attack will be someone sending us long useless header
    43  	// chains that we never actually download blocks for. This results in the block index
    44  	// bloating up (indefinitely if we don't prune it) due to storing useless headers
    45  	// but not resulting in the downloading of any blocks, which is a good thing.
    46  	//
    47  	// At ten minute block times, 5,000,000 comes out to roughly 95 years worth of blocks,
    48  	// which seems like a reasonable limit for now (if we had 25 years of blocks, we'd still
    49  	// have room for multiple forks each an entire history's length with this value). If
    50  	// each node takes up 100 bytes of space this amounts to around 500MB, which also seems
    51  	// like a reasonable size.
    52  	MaxBlockIndexNodes = 5000000
    53  )
    54  
    55  type BlockStatus uint32
    56  
    57  const (
    58  	StatusNone BlockStatus = 0
    59  
    60  	// Headers must always be Validated or ValidateFailed. We
    61  	// don't store orphan headers and therefore any header that we do
    62  	// have in our node index will be known definitively to be valid or
    63  	// invalid one way or the other.
    64  	StatusHeaderValidated = 1 << iota
    65  	StatusHeaderValidateFailed
    66  
    67  	StatusBlockProcessed
    68  	StatusBlockStored
    69  	StatusBlockValidated
    70  	StatusBlockValidateFailed
    71  
    72  	// These statuses are only used for Bitcoin header blocks in the BitcoinManager,
    73  	// not DeSo blocks. As such, you should only see these referenced in the BitcoinManager.
    74  	// We include them here because overloading the DeSo data structures to make it
    75  	// so that the BitcoinManager can use them is easier than defining whole new data
    76  	// structures that are incompatible with existing methods like LatestLocator(). If
    77  	// Go supported generics, this would probably not be necessary but it doesn't and
    78  	// so this is the path of least resistance.
    79  	StatusBitcoinHeaderValidated
    80  	StatusBitcoinHeaderValidateFailed
    81  )
    82  
    83  func (blockStatus BlockStatus) String() string {
    84  	if blockStatus == 0 {
    85  		return "NONE"
    86  	}
    87  
    88  	statuses := []string{}
    89  	if blockStatus&StatusHeaderValidated != 0 {
    90  		statuses = append(statuses, "HEADER_VALIDATED")
    91  		blockStatus ^= StatusHeaderValidated
    92  	}
    93  	if blockStatus&StatusHeaderValidateFailed != 0 {
    94  		statuses = append(statuses, "HEADER_VALIDATE_FAILED")
    95  		blockStatus ^= StatusHeaderValidateFailed
    96  	}
    97  	if blockStatus&StatusBlockProcessed != 0 {
    98  		statuses = append(statuses, "BLOCK_PROCESSED")
    99  		blockStatus ^= StatusBlockProcessed
   100  	}
   101  	if blockStatus&StatusBlockStored != 0 {
   102  		statuses = append(statuses, "BLOCK_STORED")
   103  		blockStatus ^= StatusBlockStored
   104  	}
   105  	if blockStatus&StatusBlockValidated != 0 {
   106  		statuses = append(statuses, "BLOCK_VALIDATED")
   107  		blockStatus ^= StatusBlockValidated
   108  	}
   109  	if blockStatus&StatusBlockValidateFailed != 0 {
   110  		statuses = append(statuses, "BLOCK_VALIDATE_FAILED")
   111  		blockStatus ^= StatusBlockValidateFailed
   112  	}
   113  
   114  	// If at this point the blockStatus isn't zeroed out then
   115  	// we have an unknown status remaining.
   116  	if blockStatus != 0 {
   117  		statuses = append(statuses, "ERROR_UNKNOWN_STATUS!")
   118  	}
   119  
   120  	return strings.Join(statuses, " | ")
   121  }
   122  
   123  // Add some fields in addition to the header to aid in the selection
   124  // of the best chain.
   125  type BlockNode struct {
   126  	// Pointer to a node representing the block's parent.
   127  	Parent *BlockNode
   128  
   129  	// The hash computed on this block.
   130  	Hash *BlockHash
   131  
   132  	// Height is the position in the block chain.
   133  	Height uint32
   134  
   135  	// The difficulty target for this block. Used to compute the next
   136  	// block's difficulty target so it can be validated.
   137  	DifficultyTarget *BlockHash
   138  
   139  	// A computation of the total amount of work that has been performed
   140  	// on this chain, including the current node.
   141  	CumWork *big.Int
   142  
   143  	// The block header.
   144  	Header *MsgDeSoHeader
   145  
   146  	// Status holds the validation state for the block and whether or not
   147  	// it's stored in the database.
   148  	Status BlockStatus
   149  }
   150  
   151  func _difficultyBitsToHash(diffBits uint32) (_diffHash *BlockHash) {
   152  	diffBigint := btcdchain.CompactToBig(diffBits)
   153  	return BigintToHash(diffBigint)
   154  }
   155  
   156  func ExtractBitcoinBurnTransactionsFromBitcoinBlock(
   157  	bitcoinBlock *wire.MsgBlock, bitcoinBurnAddress string, params *DeSoParams) []*wire.MsgTx {
   158  
   159  	burnTxns := []*wire.MsgTx{}
   160  	for _, txn := range bitcoinBlock.Transactions {
   161  		burnOutput, err := _computeBitcoinBurnOutput(
   162  			txn, bitcoinBurnAddress, params.BitcoinBtcdParams)
   163  		if err != nil {
   164  			glog.Errorf("ExtractBitcoinBurnTransactionsFromBitcoinBlock: Problem "+
   165  				"extracting Bitcoin transaction: %v", err)
   166  			continue
   167  		}
   168  
   169  		if burnOutput > 0 {
   170  			burnTxns = append(burnTxns, txn)
   171  		}
   172  	}
   173  
   174  	return burnTxns
   175  }
   176  
   177  func ExtractBitcoinBurnTransactionsFromBitcoinBlockWithMerkleProofs(
   178  	bitcoinBlock *wire.MsgBlock, burnAddress string, params *DeSoParams) (
   179  	_txns []*wire.MsgTx, _merkleProofs [][]*merkletree.ProofPart, _err error) {
   180  
   181  	// Extract the Bitcoin burn transactions.
   182  	burnTxns := ExtractBitcoinBurnTransactionsFromBitcoinBlock(
   183  		bitcoinBlock, burnAddress, params)
   184  
   185  	// If there weren't any burn transactions then there's nothing to do.
   186  	if len(burnTxns) == 0 {
   187  		return nil, nil, nil
   188  	}
   189  
   190  	// Compute all of the transaction hashes for the block.
   191  	txHashes := [][]byte{}
   192  	for _, txn := range bitcoinBlock.Transactions {
   193  		txnBytes := bytes.Buffer{}
   194  		err := txn.SerializeNoWitness(&txnBytes)
   195  		if err != nil {
   196  			return nil, nil, fmt.Errorf(
   197  				"ExtractBitcoinBurnTransactionsFromBitcoinBlockWithMerkleProofs: "+
   198  					"Error computing all the txn hashes for block: %v",
   199  				err)
   200  		}
   201  		txHashes = append(txHashes, txnBytes.Bytes())
   202  	}
   203  
   204  	// Compute a merkle tree for the block.
   205  	merkleTree := merkletree.NewTree(merkletree.Sha256DoubleHash, txHashes)
   206  
   207  	if !reflect.DeepEqual(merkleTree.Root.GetHash(), bitcoinBlock.Header.MerkleRoot[:]) {
   208  		return nil, nil, fmt.Errorf(
   209  			"ExtractBitcoinBurnTransactionsFromBitcoinBlockWithMerkleProofs: "+
   210  				"Merkle proof computed from txns %#v != to Merkle proof in Bitcoin block %#v",
   211  			merkleTree.Root.GetHash(), bitcoinBlock.Header.MerkleRoot[:])
   212  	}
   213  
   214  	// Use the Merkle tree to compute a Merkle proof for each transaction.
   215  	burnTxnsWithProofs := []*wire.MsgTx{}
   216  	merkleProofs := [][]*merkletree.ProofPart{}
   217  	for _, txn := range burnTxns {
   218  		txHash := txn.TxHash()
   219  		proof, err := merkleTree.CreateProof(txHash[:])
   220  		if err != nil {
   221  			return nil, nil, fmt.Errorf(
   222  				"ExtractBitcoinBurnTransactionsFromBitcoinBlockWithMerkleProofs: Problem "+
   223  					"computing Merkle proof for txn %v for block %v: %v",
   224  				txn, bitcoinBlock, err)
   225  		}
   226  
   227  		burnTxnsWithProofs = append(burnTxnsWithProofs, txn)
   228  		merkleProofs = append(merkleProofs, proof.PathToRoot)
   229  	}
   230  
   231  	return burnTxnsWithProofs, merkleProofs, nil
   232  }
   233  
   234  func ExtractBitcoinExchangeTransactionsFromBitcoinBlock(
   235  	bitcoinBlock *wire.MsgBlock, burnAddress string, params *DeSoParams) (
   236  	_txns []*MsgDeSoTxn, _err error) {
   237  
   238  	bitcoinBurnTxns, merkleProofs, err :=
   239  		ExtractBitcoinBurnTransactionsFromBitcoinBlockWithMerkleProofs(
   240  			bitcoinBlock, burnAddress, params)
   241  	if err != nil {
   242  		return nil, errors.Wrapf(err, "ExtractBitcoinExchangeTransactionsFromBitcoinBlock: "+
   243  			"Problem extracting raw Bitcoin burn transactions from Bitcoin Block")
   244  	}
   245  
   246  	bitcoinExchangeTxns := []*MsgDeSoTxn{}
   247  	blockHash := (BlockHash)(bitcoinBlock.BlockHash())
   248  	merkleRoot := (BlockHash)(bitcoinBlock.Header.MerkleRoot)
   249  	for ii := range bitcoinBurnTxns {
   250  		bitcoinExchangeMetadata := &BitcoinExchangeMetadata{
   251  			BitcoinTransaction: bitcoinBurnTxns[ii],
   252  			BitcoinBlockHash:   &blockHash,
   253  			BitcoinMerkleRoot:  &merkleRoot,
   254  			BitcoinMerkleProof: merkleProofs[ii],
   255  		}
   256  
   257  		// The only thing a BitcoinExchange transaction has set is its TxnMeta.
   258  		// Everything else is left blank because it is not needed. Note that the
   259  		// recipient of the DeSo that will be created is the first valid input in
   260  		// the BitcoinTransaction specified. Note also that the
   261  		// fee is deducted as a percentage of the eventual DeSo that will get
   262  		// created as a result of this transaction.
   263  		currentTxn := &MsgDeSoTxn{
   264  			TxnMeta: bitcoinExchangeMetadata,
   265  		}
   266  		bitcoinExchangeTxns = append(bitcoinExchangeTxns, currentTxn)
   267  	}
   268  
   269  	return bitcoinExchangeTxns, nil
   270  }
   271  
   272  func (nn *BlockNode) String() string {
   273  	var parentHash *BlockHash
   274  	if nn.Parent != nil {
   275  		parentHash = nn.Parent.Hash
   276  	}
   277  	tstamp := uint32(0)
   278  	if nn.Header != nil {
   279  		tstamp = uint32(nn.Header.TstampSecs)
   280  	}
   281  	return fmt.Sprintf("< TstampSecs: %d, Height: %d, Hash: %s, ParentHash %s, Status: %s, CumWork: %v>",
   282  		tstamp, nn.Header.Height, nn.Hash, parentHash, nn.Status, nn.CumWork)
   283  }
   284  
   285  // TODO: Height not needed in this since it's in the header.
   286  func NewBlockNode(
   287  	parent *BlockNode,
   288  	hash *BlockHash,
   289  	height uint32,
   290  	difficultyTarget *BlockHash,
   291  	cumWork *big.Int,
   292  	header *MsgDeSoHeader,
   293  	status BlockStatus) *BlockNode {
   294  
   295  	return &BlockNode{
   296  		Parent:           parent,
   297  		Hash:             hash,
   298  		Height:           height,
   299  		DifficultyTarget: difficultyTarget,
   300  		CumWork:          cumWork,
   301  		Header:           header,
   302  		Status:           status,
   303  	}
   304  }
   305  
   306  func (nn *BlockNode) Ancestor(height uint32) *BlockNode {
   307  	if height > nn.Height {
   308  		return nil
   309  	}
   310  
   311  	node := nn
   312  	for ; node != nil && node.Height != height; node = node.Parent {
   313  		// Keep iterating node until the condition no longer holds.
   314  	}
   315  
   316  	return node
   317  }
   318  
   319  // RelativeAncestor returns the ancestor block node a relative 'distance' blocks
   320  // before this node. This is equivalent to calling Ancestor with the node's
   321  // height minus provided distance.
   322  //
   323  // This function is safe for concurrent access.
   324  func (nn *BlockNode) RelativeAncestor(distance uint32) *BlockNode {
   325  	return nn.Ancestor(nn.Height - distance)
   326  }
   327  
   328  // CalcNextDifficultyTarget computes the difficulty target expected of the
   329  // next block.
   330  func CalcNextDifficultyTarget(
   331  	lastNode *BlockNode, version uint32, params *DeSoParams) (*BlockHash, error) {
   332  
   333  	// Compute the blocks in each difficulty cycle.
   334  	blocksPerRetarget := uint32(params.TimeBetweenDifficultyRetargets / params.TimeBetweenBlocks)
   335  
   336  	// We effectively skip the first difficulty retarget by returning the default
   337  	// difficulty value for the first cycle. Not doing this (or something like it)
   338  	// would cause the genesis block's timestamp, which could be off by several days
   339  	// to significantly skew the first cycle in a way that is mostly annoying for
   340  	// testing but also suboptimal for the mainnet.
   341  	minDiffBytes, err := hex.DecodeString(params.MinDifficultyTargetHex)
   342  	if err != nil {
   343  		return nil, errors.Wrapf(err, "CalcNextDifficultyTarget: Problem computing min difficulty")
   344  	}
   345  	var minDiffHash BlockHash
   346  	copy(minDiffHash[:], minDiffBytes)
   347  	if lastNode == nil || lastNode.Height <= blocksPerRetarget {
   348  		return &minDiffHash, nil
   349  	}
   350  
   351  	// If we get here we know we are dealing with a block whose height exceeds
   352  	// the height of the first difficulty adjustment (that is
   353  	//   lastNode.Height > blocksPerRetarget
   354  
   355  	// If we're not at a difficulty retarget point, return the previous
   356  	// block's difficulty.
   357  	if lastNode.Height%blocksPerRetarget != 0 {
   358  		return lastNode.DifficultyTarget, nil
   359  	}
   360  
   361  	// If we get here it means we reached a difficulty retarget point.
   362  	targetSecs := int64(params.TimeBetweenDifficultyRetargets / time.Second)
   363  	minRetargetTimeSecs := targetSecs / params.MaxDifficultyRetargetFactor
   364  	maxRetargetTimeSecs := targetSecs * params.MaxDifficultyRetargetFactor
   365  
   366  	firstNodeHeight := lastNode.Height - blocksPerRetarget
   367  	firstNode := lastNode.Ancestor(firstNodeHeight)
   368  	if firstNode == nil {
   369  		return nil, fmt.Errorf("CalcNextDifficultyTarget: Problem getting block at "+
   370  			"beginning of retarget interval at height %d during retarget from height %d",
   371  			firstNodeHeight, lastNode.Height)
   372  	}
   373  
   374  	actualTimeDiffSecs := int64(lastNode.Header.TstampSecs - firstNode.Header.TstampSecs)
   375  	clippedTimeDiffSecs := actualTimeDiffSecs
   376  	if actualTimeDiffSecs < minRetargetTimeSecs {
   377  		clippedTimeDiffSecs = minRetargetTimeSecs
   378  	} else if actualTimeDiffSecs > maxRetargetTimeSecs {
   379  		clippedTimeDiffSecs = maxRetargetTimeSecs
   380  	}
   381  
   382  	numerator := new(big.Int).Mul(
   383  		HashToBigint(lastNode.DifficultyTarget),
   384  		big.NewInt(clippedTimeDiffSecs))
   385  	nextDiffBigint := numerator.Div(numerator, big.NewInt(targetSecs))
   386  
   387  	// If the next difficulty is nil or if it passes the min difficulty, set it equal
   388  	// to the min difficulty. This should never happen except for weird instances where
   389  	// we're testing edge cases.
   390  	if nextDiffBigint == nil || nextDiffBigint.Cmp(HashToBigint(&minDiffHash)) > 0 {
   391  		nextDiffBigint = HashToBigint(&minDiffHash)
   392  	}
   393  
   394  	return BigintToHash(nextDiffBigint), nil
   395  }
   396  
   397  type OrphanBlock struct {
   398  	Block *MsgDeSoBlock
   399  	Hash  *BlockHash
   400  }
   401  
   402  type Blockchain struct {
   403  	db                              *badger.DB
   404  	postgres                        *Postgres
   405  	timeSource                      chainlib.MedianTimeSource
   406  	trustedBlockProducerPublicKeys  map[PkMapKey]bool
   407  	trustedBlockProducerStartHeight uint64
   408  	params                          *DeSoParams
   409  	eventManager                    *EventManager
   410  	// Returns true once all of the housekeeping in creating the
   411  	// blockchain is complete. This includes setting up the genesis block.
   412  	isInitialized bool
   413  
   414  	// Protects most of the fields below this point.
   415  	ChainLock deadlock.RWMutex
   416  
   417  	// These should only be accessed after acquiring the ChainLock.
   418  	//
   419  	// An in-memory index of the "tree" of blocks we are currently aware of.
   420  	// This index includes forks and side-chains but does not include unconnectedTxns.
   421  	blockIndex map[BlockHash]*BlockNode
   422  	// An in-memory slice of the blocks on the main chain only. The end of
   423  	// this slice is the best known tip that we have at any given time.
   424  	bestChain    []*BlockNode
   425  	bestChainMap map[BlockHash]*BlockNode
   426  
   427  	bestHeaderChain    []*BlockNode
   428  	bestHeaderChainMap map[BlockHash]*BlockNode
   429  
   430  	// We keep track of orphan blocks with the following data structures. Orphans
   431  	// are not written to disk and are only cached in memory. Moreover we only keep
   432  	// up to MaxOrphansInMemory of them in order to prevent memory exhaustion.
   433  	orphanList *list.List
   434  }
   435  
   436  func (bc *Blockchain) CopyBlockIndex() map[BlockHash]*BlockNode {
   437  	newBlockIndex := make(map[BlockHash]*BlockNode)
   438  	for kk, vv := range bc.blockIndex {
   439  		newBlockIndex[kk] = vv
   440  	}
   441  	return newBlockIndex
   442  }
   443  
   444  func (bc *Blockchain) CopyBestChain() ([]*BlockNode, map[BlockHash]*BlockNode) {
   445  	newBestChain := []*BlockNode{}
   446  	newBestChainMap := make(map[BlockHash]*BlockNode)
   447  	newBestChain = append(newBestChain, bc.bestChain...)
   448  	for kk, vv := range bc.bestChainMap {
   449  		newBestChainMap[kk] = vv
   450  	}
   451  
   452  	return newBestChain, newBestChainMap
   453  }
   454  
   455  func (bc *Blockchain) CopyBestHeaderChain() ([]*BlockNode, map[BlockHash]*BlockNode) {
   456  	newBestChain := []*BlockNode{}
   457  	newBestChainMap := make(map[BlockHash]*BlockNode)
   458  	newBestChain = append(newBestChain, bc.bestHeaderChain...)
   459  	for kk, vv := range bc.bestHeaderChainMap {
   460  		newBestChainMap[kk] = vv
   461  	}
   462  
   463  	return newBestChain, newBestChainMap
   464  }
   465  
   466  // _initChain initializes the in-memory data structures for the Blockchain object
   467  // by reading from the database. If the database has never been initialized before
   468  // then _initChain will initialize it to contain only the genesis block before
   469  // proceeding to read from it.
   470  func (bc *Blockchain) _initChain() error {
   471  	// See if we have a best chain hash stored in the db.
   472  	var bestBlockHash *BlockHash
   473  	if bc.postgres != nil {
   474  		chain := bc.postgres.GetChain(MAIN_CHAIN)
   475  		if chain != nil {
   476  			bestBlockHash = chain.TipHash
   477  		}
   478  	} else {
   479  		bestBlockHash = DbGetBestHash(bc.db, ChainTypeDeSoBlock)
   480  	}
   481  	// When we load up initially, the best header hash is just the tip of the best
   482  	// block chain, since we don't store headers for which we don't have corresponding
   483  	// blocks.
   484  	bestHeaderHash := bestBlockHash
   485  
   486  	// If there is no best chain hash in the db then it means we've never
   487  	// initialized anything so take the time to do it now.
   488  	if bestBlockHash == nil || bestHeaderHash == nil {
   489  		var err error
   490  
   491  		if bc.postgres != nil {
   492  			err = bc.postgres.InitGenesisBlock(bc.params, bc.db)
   493  		} else {
   494  			err = InitDbWithDeSoGenesisBlock(bc.params, bc.db, bc.eventManager)
   495  		}
   496  		if err != nil {
   497  			return errors.Wrapf(err, "_initChain: Problem initializing db with genesis block")
   498  		}
   499  
   500  		// After initializing the db to contain only the genesis block,
   501  		// set the best hash we're aware of equal to it.
   502  		bestBlockHash = MustDecodeHexBlockHash(bc.params.GenesisBlockHashHex)
   503  		bestHeaderHash = bestBlockHash
   504  	}
   505  
   506  	// At this point we should have bestHashes set and the db should have been
   507  	// initialized to contain a block index and a best chain that we can read
   508  	// in.
   509  
   510  	// Read in the nodes using the (<height, hash> -> node) index. The nodes will
   511  	// be iterated over starting with height 0 and ending with the height of the
   512  	// longest chain we're aware of. As we go, check that all the blocks connect
   513  	// to previous blocks we've read in and error if they don't. This works because
   514  	// reading blocks in height order as we do here ensures that we'll always
   515  	// add a block's parents, if they exist, before adding the block itself.
   516  	var err error
   517  	if bc.postgres != nil {
   518  		bc.blockIndex, err = bc.postgres.GetBlockIndex()
   519  	} else {
   520  		bc.blockIndex, err = GetBlockIndex(bc.db, false /*bitcoinNodes*/)
   521  	}
   522  	if err != nil {
   523  		return errors.Wrapf(err, "_initChain: Problem reading block index from db")
   524  	}
   525  
   526  	// At this point the blockIndex should contain a full node tree with all
   527  	// nodes pointing to valid parent nodes.
   528  	{
   529  		// Find the tip node with the best node hash.
   530  		tipNode := bc.blockIndex[*bestBlockHash]
   531  		if tipNode == nil {
   532  			return fmt.Errorf("_initChain(block): Best hash (%#v) not found in block index", bestBlockHash)
   533  		}
   534  
   535  		// Walk back from the best node to the genesis block and store them all
   536  		// in bestChain.
   537  		bc.bestChain, err = GetBestChain(tipNode, bc.blockIndex)
   538  		if err != nil {
   539  			return errors.Wrapf(err, "_initChain(block): Problem reading best chain from db")
   540  		}
   541  		for _, bestChainNode := range bc.bestChain {
   542  			bc.bestChainMap[*bestChainNode.Hash] = bestChainNode
   543  		}
   544  	}
   545  
   546  	// TODO: This code is a bit repetitive but this seemed clearer than factoring it out.
   547  	{
   548  		// Find the tip node with the best node hash.
   549  		tipNode := bc.blockIndex[*bestHeaderHash]
   550  		if tipNode == nil {
   551  			return fmt.Errorf("_initChain(header): Best hash (%#v) not found in block index", bestHeaderHash)
   552  		}
   553  
   554  		// Walk back from the best node to the genesis block and store them all
   555  		// in bestChain.
   556  		bc.bestHeaderChain, err = GetBestChain(tipNode, bc.blockIndex)
   557  		if err != nil {
   558  			return errors.Wrapf(err, "_initChain(header): Problem reading best chain from db")
   559  		}
   560  		for _, bestHeaderChainNode := range bc.bestHeaderChain {
   561  			bc.bestHeaderChainMap[*bestHeaderChainNode.Hash] = bestHeaderChainNode
   562  		}
   563  	}
   564  
   565  	bc.isInitialized = true
   566  
   567  	return nil
   568  }
   569  
   570  // NewBlockchain returns a new blockchain object. It initializes some in-memory
   571  // data structures by reading from the db. It also initializes the db if it hasn't
   572  // been initialized in the past. This function should only be called once per
   573  // db, and one should never run two blockhain objects over the same db at the same
   574  // time as they will likely step on each other and become inconsistent.
   575  func NewBlockchain(
   576  	trustedBlockProducerPublicKeyStrs []string,
   577  	trustedBlockProducerStartHeight uint64,
   578  	params *DeSoParams,
   579  	timeSource chainlib.MedianTimeSource,
   580  	db *badger.DB,
   581  	postgres *Postgres,
   582  	eventManager *EventManager,
   583  ) (*Blockchain, error) {
   584  
   585  	trustedBlockProducerPublicKeys := make(map[PkMapKey]bool)
   586  	for _, keyStr := range trustedBlockProducerPublicKeyStrs {
   587  		pkBytes, _, err := Base58CheckDecode(keyStr)
   588  		if err != nil {
   589  			return nil, fmt.Errorf("Error decoding trusted block producer public key: %v", err)
   590  		}
   591  		trustedBlockProducerPublicKeys[MakePkMapKey(pkBytes)] = true
   592  	}
   593  
   594  	bc := &Blockchain{
   595  		db:                              db,
   596  		postgres:                        postgres,
   597  		timeSource:                      timeSource,
   598  		trustedBlockProducerPublicKeys:  trustedBlockProducerPublicKeys,
   599  		trustedBlockProducerStartHeight: trustedBlockProducerStartHeight,
   600  		params:                          params,
   601  		eventManager:                    eventManager,
   602  
   603  		blockIndex:   make(map[BlockHash]*BlockNode),
   604  		bestChainMap: make(map[BlockHash]*BlockNode),
   605  
   606  		bestHeaderChainMap: make(map[BlockHash]*BlockNode),
   607  
   608  		orphanList: list.New(),
   609  	}
   610  
   611  	// Hold the chain lock whenever we modify this object from now on.
   612  	bc.ChainLock.Lock()
   613  	defer bc.ChainLock.Unlock()
   614  
   615  	// Initialize all the in-memory data structures by loading our state
   616  	// from the db. This function creates an initial database state containing
   617  	// only the genesis block if we've never initialized the database before.
   618  	if err := bc._initChain(); err != nil {
   619  		return nil, errors.Wrapf(err, "NewBlockchain: ")
   620  	}
   621  
   622  	return bc, nil
   623  }
   624  
   625  // log2FloorMasks defines the masks to use when quickly calculating
   626  // floor(log2(x)) in a constant log2(32) = 5 steps, where x is a uint32, using
   627  // shifts.  They are derived from (2^(2^x) - 1) * (2^(2^x)), for x in 4..0.
   628  var log2FloorMasks = []uint32{0xffff0000, 0xff00, 0xf0, 0xc, 0x2}
   629  
   630  // fastLog2Floor calculates and returns floor(log2(x)) in a constant 5 steps.
   631  func fastLog2Floor(n uint32) uint8 {
   632  	rv := uint8(0)
   633  	exponent := uint8(16)
   634  	for i := 0; i < 5; i++ {
   635  		if n&log2FloorMasks[i] != 0 {
   636  			rv += exponent
   637  			n >>= exponent
   638  		}
   639  		exponent >>= 1
   640  	}
   641  	return rv
   642  }
   643  
   644  // locateInventory returns the node of the block after the first known block in
   645  // the locator along with the number of subsequent nodes needed to either reach
   646  // the provided stop hash or the provided max number of entries.
   647  //
   648  // In addition, there are two special cases:
   649  //
   650  // - When no locators are provided, the stop hash is treated as a request for
   651  //   that block, so it will either return the node associated with the stop hash
   652  //   if it is known, or nil if it is unknown
   653  // - When locators are provided, but none of them are known, nodes starting
   654  //   after the genesis block will be returned
   655  //
   656  // This is primarily a helper function for the locateBlocks and locateHeaders
   657  // functions.
   658  //
   659  // This function MUST be called with the chain state lock held (for reads).
   660  func locateInventory(locator []*BlockHash, stopHash *BlockHash, maxEntries uint32,
   661  	blockIndex map[BlockHash]*BlockNode, bestChainList []*BlockNode,
   662  	bestChainMap map[BlockHash]*BlockNode) (*BlockNode, uint32) {
   663  
   664  	// There are no block locators so a specific block is being requested
   665  	// as identified by the stop hash.
   666  	stopNode, stopNodeExists := blockIndex[*stopHash]
   667  	if len(locator) == 0 {
   668  		if !stopNodeExists {
   669  			// No blocks with the stop hash were found so there is
   670  			// nothing to do.
   671  			return nil, 0
   672  		}
   673  		return stopNode, 1
   674  	}
   675  
   676  	// Find the most recent locator block hash in the main chain. In the
   677  	// case none of the hashes in the locator are in the main chain, fall
   678  	// back to the genesis block.
   679  	startNode := bestChainList[0]
   680  	for _, hash := range locator {
   681  		node, bestChainContainsNode := bestChainMap[*hash]
   682  		if bestChainContainsNode {
   683  			startNode = node
   684  			break
   685  		}
   686  	}
   687  
   688  	// Start at the block after the most recently known block. When there
   689  	// is no next block it means the most recently known block is the tip of
   690  	// the best chain, so there is nothing more to do.
   691  	nextNodeHeight := uint32(startNode.Header.Height) + 1
   692  	if uint32(len(bestChainList)) <= nextNodeHeight {
   693  		return nil, 0
   694  	}
   695  	startNode = bestChainList[nextNodeHeight]
   696  
   697  	// Calculate how many entries are needed.
   698  	tip := bestChainList[len(bestChainList)-1]
   699  	total := uint32((tip.Header.Height - startNode.Header.Height) + 1)
   700  	if stopNodeExists && stopNode.Header.Height >= startNode.Header.Height {
   701  
   702  		_, bestChainContainsStopNode := bestChainMap[*stopNode.Hash]
   703  		if bestChainContainsStopNode {
   704  			total = uint32((stopNode.Header.Height - startNode.Header.Height) + 1)
   705  		}
   706  	}
   707  	if total > maxEntries {
   708  		total = maxEntries
   709  	}
   710  
   711  	return startNode, total
   712  }
   713  
   714  // locateHeaders returns the headers of the blocks after the first known block
   715  // in the locator until the provided stop hash is reached, or up to the provided
   716  // max number of block headers.
   717  //
   718  // See the comment on the exported function for more details on special cases.
   719  //
   720  // This function MUST be called with the ChainLock held (for reads).
   721  func locateHeaders(locator []*BlockHash, stopHash *BlockHash, maxHeaders uint32,
   722  	blockIndex map[BlockHash]*BlockNode, bestChainList []*BlockNode,
   723  	bestChainMap map[BlockHash]*BlockNode) []*MsgDeSoHeader {
   724  
   725  	// Find the node after the first known block in the locator and the
   726  	// total number of nodes after it needed while respecting the stop hash
   727  	// and max entries.
   728  	node, total := locateInventory(locator, stopHash, maxHeaders,
   729  		blockIndex, bestChainList, bestChainMap)
   730  	if total == 0 {
   731  		return nil
   732  	}
   733  
   734  	// Populate and return the found headers.
   735  	headers := make([]*MsgDeSoHeader, 0, total)
   736  	for ii := uint32(0); ii < total; ii++ {
   737  		headers = append(headers, node.Header)
   738  		if uint32(len(headers)) == total {
   739  			break
   740  		}
   741  		node = bestChainList[node.Header.Height+1]
   742  	}
   743  	return headers
   744  }
   745  
   746  // LocateBestBlockChainHeaders returns the headers of the blocks after the first known block
   747  // in the locator until the provided stop hash is reached, or up to a max of
   748  // wire.MaxBlockHeadersPerMsg headers. Note that it returns the best headers
   749  // considering only headers for which we have blocks (that is, it considers the
   750  // best *block* chain we have rather than the best *header* chain). This is
   751  // the correct thing to do because in general this function is called in order
   752  // to serve a response to a peer's GetHeaders request.
   753  //
   754  // In addition, there are two special cases:
   755  //
   756  // - When no locators are provided, the stop hash is treated as a request for
   757  //   that header, so it will either return the header for the stop hash itself
   758  //   if it is known, or nil if it is unknown
   759  // - When locators are provided, but none of them are known, headers starting
   760  //   after the genesis block will be returned
   761  //
   762  // This function is safe for concurrent access.
   763  func (bc *Blockchain) LocateBestBlockChainHeaders(locator []*BlockHash, stopHash *BlockHash) []*MsgDeSoHeader {
   764  	headers := locateHeaders(locator, stopHash, MaxHeadersPerMsg,
   765  		bc.blockIndex, bc.bestChain, bc.bestChainMap)
   766  
   767  	return headers
   768  }
   769  
   770  // LatestLocator returns a block locator for the passed block node. The passed
   771  // node can be nil in which case the block locator for the current tip
   772  // associated with the view will be returned.
   773  //
   774  // BlockLocator is used to help locate a specific block.  The algorithm for
   775  // building the block locator is to add the hashes in reverse order until
   776  // the genesis block is reached.  In order to keep the list of locator hashes
   777  // to a reasonable number of entries, first the most recent previous 12 block
   778  // hashes are added, then the step is doubled each loop iteration to
   779  // exponentially decrease the number of hashes as a function of the distance
   780  // from the block being located.
   781  //
   782  // For example, assume a block chain with a side chain as depicted below:
   783  // 	genesis -> 1 -> 2 -> ... -> 15 -> 16  -> 17  -> 18
   784  // 	                              \-> 16a -> 17a
   785  //
   786  // The block locator for block 17a would be the hashes of blocks:
   787  // [17a 16a 15 14 13 12 11 10 9 8 7 6 4 genesis]
   788  //
   789  // Caller is responsible for acquiring the ChainLock before calling this function.
   790  func (bc *Blockchain) LatestLocator(tip *BlockNode) []*BlockHash {
   791  
   792  	// Calculate the max number of entries that will ultimately be in the
   793  	// block locator. See the description of the algorithm for how these
   794  	// numbers are derived.
   795  	var maxEntries uint8
   796  	if tip.Header.Height <= 12 {
   797  		maxEntries = uint8(tip.Header.Height) + 1
   798  	} else {
   799  		// Requested hash itself + previous 10 entries + genesis block.
   800  		// Then floor(log2(height-10)) entries for the skip portion.
   801  		adjustedHeight := uint32(tip.Header.Height) - 10
   802  		maxEntries = 12 + fastLog2Floor(adjustedHeight)
   803  	}
   804  	locator := make([]*BlockHash, 0, maxEntries)
   805  
   806  	step := int32(1)
   807  	for tip != nil {
   808  		locator = append(locator, tip.Hash)
   809  
   810  		// Nothing more to add once the genesis block has been added.
   811  		if tip.Header.Height == 0 {
   812  			break
   813  		}
   814  
   815  		// Calculate height of previous node to include ensuring the
   816  		// final node is the genesis block.
   817  		height := int32(tip.Header.Height) - step
   818  		if height < 0 {
   819  			height = 0
   820  		}
   821  
   822  		// When the node is in the current chain view, all of its
   823  		// ancestors must be too, so use a much faster O(1) lookup in
   824  		// that case.  Otherwise, fall back to walking backwards through
   825  		// the nodes of the other chain to the correct ancestor.
   826  		if _, exists := bc.bestHeaderChainMap[*tip.Hash]; exists {
   827  			tip = bc.bestHeaderChain[height]
   828  		} else {
   829  			tip = tip.Ancestor(uint32(height))
   830  		}
   831  
   832  		// Once 11 entries have been included, start doubling the
   833  		// distance between included hashes.
   834  		if len(locator) > 10 {
   835  			step *= 2
   836  		}
   837  	}
   838  
   839  	return locator
   840  }
   841  
   842  func (bc *Blockchain) HeaderLocatorWithNodeHash(blockHash *BlockHash) ([]*BlockHash, error) {
   843  	node, exists := bc.blockIndex[*blockHash]
   844  	if !exists {
   845  		return nil, fmt.Errorf("Blockchain.HeaderLocatorWithNodeHash: Node for hash %v is not in our blockIndex", blockHash)
   846  	}
   847  
   848  	return bc.LatestLocator(node), nil
   849  }
   850  
   851  // LatestHeaderLocator calls LatestLocator in order to fetch a locator
   852  // for the best header chain.
   853  func (bc *Blockchain) LatestHeaderLocator() []*BlockHash {
   854  	headerTip := bc.headerTip()
   855  
   856  	return bc.LatestLocator(headerTip)
   857  }
   858  
   859  func (bc *Blockchain) GetBlockNodesToFetch(
   860  	numBlocks int, _maxHeight int, blocksToIgnore map[BlockHash]bool) []*BlockNode {
   861  
   862  	// Get the tip of the main block chain.
   863  	bestBlockTip := bc.blockTip()
   864  
   865  	// If the maxHeight is set to < 0, then we don't want to use it as a constraint.
   866  	maxHeight := uint32(math.MaxUint32)
   867  	if _maxHeight >= 0 {
   868  		maxHeight = uint32(_maxHeight)
   869  	}
   870  
   871  	// If the tip of the best block chain is in the main header chain, make that
   872  	// the start point for our fetch.
   873  	headerNodeStart, blockTipExistsInBestHeaderChain := bc.bestHeaderChainMap[*bestBlockTip.Hash]
   874  	if !blockTipExistsInBestHeaderChain {
   875  		// If the hash of the tip of the best blockchain is not in the best header chain, then
   876  		// this is a case where the header chain has forked off from the best block
   877  		// chain. In this situation, the best header chain is taken as the source of truth
   878  		// and so we iterate backward over the best header chain starting at the tip
   879  		// until we find the first block that has StatusBlockProcessed. Then we fetch
   880  		// blocks starting from there. Note that, at minimum, the genesis block has
   881  		// StatusBlockProcessed so this loop is guaranteed to terminate successfully.
   882  		headerNodeStart = bc.headerTip()
   883  		for headerNodeStart != nil && (headerNodeStart.Status&StatusBlockProcessed) == 0 {
   884  			headerNodeStart = headerNodeStart.Parent
   885  		}
   886  
   887  		if headerNodeStart == nil {
   888  			// If for some reason we ended up with the headerNode being nil, log
   889  			// an error and set it to the genesis block.
   890  			glog.Errorf("GetBlockToFetch: headerNode was nil after iterating " +
   891  				"backward through best header chain; using genesis block")
   892  			headerNodeStart = bc.bestHeaderChain[0]
   893  		}
   894  	}
   895  
   896  	// At this point, headerNodeStart should point to a node in the best header
   897  	// chain that has StatusBlockProcessed set. As such, the blocks we need to
   898  	// fetch are those right after this one. Fetch the desired number.
   899  	currentHeight := headerNodeStart.Height + 1
   900  	blockNodesToFetch := []*BlockNode{}
   901  	heightLimit := maxHeight
   902  	if heightLimit >= uint32(len(bc.bestHeaderChain)) {
   903  		heightLimit = uint32(len(bc.bestHeaderChain) - 1)
   904  	}
   905  	for currentHeight <= heightLimit &&
   906  		len(blockNodesToFetch) < numBlocks {
   907  
   908  		// Get the current hash and increment the height.
   909  		currentNode := bc.bestHeaderChain[currentHeight]
   910  		currentHeight++
   911  
   912  		if _, exists := blocksToIgnore[*currentNode.Hash]; exists {
   913  			continue
   914  		}
   915  
   916  		blockNodesToFetch = append(blockNodesToFetch, currentNode)
   917  	}
   918  
   919  	// Return the nodes for the blocks we should fetch.
   920  	return blockNodesToFetch
   921  }
   922  
   923  func (bc *Blockchain) HasHeader(headerHash *BlockHash) bool {
   924  	_, exists := bc.blockIndex[*headerHash]
   925  	return exists
   926  }
   927  
   928  func (bc *Blockchain) HeaderAtHeight(blockHeight uint32) *BlockNode {
   929  	if blockHeight >= uint32(len(bc.bestHeaderChain)) {
   930  		return nil
   931  	}
   932  
   933  	return bc.bestHeaderChain[blockHeight]
   934  }
   935  
   936  func (bc *Blockchain) HasBlock(blockHash *BlockHash) bool {
   937  	node, nodeExists := bc.blockIndex[*blockHash]
   938  	if !nodeExists {
   939  		glog.V(2).Infof("Blockchain.HasBlock: Node with hash %v does not exist in node index", blockHash)
   940  		return false
   941  	}
   942  
   943  	if (node.Status & StatusBlockProcessed) == 0 {
   944  		glog.V(2).Infof("Blockchain.HasBlock: Node %v does not have StatusBlockProcessed so we don't have the block", node)
   945  		return false
   946  	}
   947  
   948  	// Node exists with StatusBlockProcess set means we have it.
   949  	return true
   950  }
   951  
   952  // Don't need a lock because blocks don't get removed from the db after they're added
   953  func (bc *Blockchain) GetBlock(blockHash *BlockHash) *MsgDeSoBlock {
   954  	blk, err := GetBlock(blockHash, bc.db)
   955  	if err != nil {
   956  		glog.V(2).Infof("Blockchain.GetBlock: Failed to fetch node with hash %v from the db: %v", blockHash, err)
   957  		return nil
   958  	}
   959  
   960  	return blk
   961  }
   962  
   963  func (bc *Blockchain) GetBlockAtHeight(height uint32) *MsgDeSoBlock {
   964  	numBlocks := uint32(len(bc.bestChain))
   965  
   966  	if height >= numBlocks {
   967  		return nil
   968  	}
   969  
   970  	return bc.GetBlock(bc.bestChain[height].Hash)
   971  }
   972  
   973  func (bc *Blockchain) isTipCurrent(tip *BlockNode) bool {
   974  	minChainWorkBytes, _ := hex.DecodeString(bc.params.MinChainWorkHex)
   975  
   976  	// Not current if the cumulative work is below the threshold.
   977  	if tip.CumWork.Cmp(BytesToBigint(minChainWorkBytes)) < 0 {
   978  		//glog.V(2).Infof("Blockchain.isTipCurrent: Tip not current because "+
   979  		//"CumWork (%v) is less than minChainWorkBytes (%v)",
   980  		//tip.CumWork, BytesToBigint(minChainWorkBytes))
   981  		return false
   982  	}
   983  
   984  	// Not current if the tip has a timestamp older than the maximum
   985  	// tip age.
   986  	tipTime := time.Unix(int64(tip.Header.TstampSecs), 0)
   987  	oldestAllowedTipTime := bc.timeSource.AdjustedTime().Add(-1 * bc.params.MaxTipAge)
   988  
   989  	return !tipTime.Before(oldestAllowedTipTime)
   990  }
   991  
   992  type SyncState uint8
   993  
   994  const (
   995  	// SyncStateSyncingHeaders indicates that our header chain is not current.
   996  	// This is the state a node will start in when it hasn't downloaded
   997  	// anything from its peers. Because we always download headers and
   998  	// validate them before we download blocks, SyncingHeaders implies that
   999  	// the block tip is also not current yet.
  1000  	SyncStateSyncingHeaders SyncState = iota
  1001  	// SyncStateSyncingBlocks indicates that our header chain is current but
  1002  	// that the block chain we have is not current yet. In particular, it
  1003  	// means, among other things, that the tip of the block chain is still
  1004  	// older than max tip age.
  1005  	SyncStateSyncingBlocks
  1006  	// SyncStateNeedBlocksss indicates that our header chain is current and our
  1007  	// block chain is current but that there are headers in our main chain for
  1008  	// which we have not yet processed blocks.
  1009  	SyncStateNeedBlocksss
  1010  	// SyncStateFullyCurrent indicates that our header chain is current and that
  1011  	// we've fetched all the blocks corresponding to this chain.
  1012  	SyncStateFullyCurrent
  1013  )
  1014  
  1015  func (ss SyncState) String() string {
  1016  	switch ss {
  1017  	case SyncStateSyncingHeaders:
  1018  		return "SYNCING_HEADERS"
  1019  	case SyncStateSyncingBlocks:
  1020  		return "SYNCING_BLOCKS"
  1021  	case SyncStateNeedBlocksss:
  1022  		return "NEED_BLOCKS"
  1023  	case SyncStateFullyCurrent:
  1024  		return "FULLY_CURRENT"
  1025  	default:
  1026  		return fmt.Sprintf("UNRECOGNIZED(%d) - make sure String() is up to date", ss)
  1027  	}
  1028  }
  1029  
  1030  //  - Latest block height is after the latest checkpoint (if enabled)
  1031  //  - Latest block has a timestamp newer than 24 hours ago
  1032  //
  1033  // This function MUST be called with the ChainLock held (for reads).
  1034  func (bc *Blockchain) chainState() SyncState {
  1035  	// If the header is not current, then we're in the SyncStateSyncingHeaders.
  1036  	headerTip := bc.headerTip()
  1037  	if !bc.isTipCurrent(headerTip) {
  1038  		return SyncStateSyncingHeaders
  1039  	}
  1040  
  1041  	// If the header tip is current but the block tip isn't then we're in
  1042  	// the SyncStateSyncingBlocks state.
  1043  	blockTip := bc.blockTip()
  1044  	if !bc.isTipCurrent(blockTip) {
  1045  		return SyncStateSyncingBlocks
  1046  	}
  1047  
  1048  	// If the header tip is current and the block tip is current but the block
  1049  	// tip is not equal to the header tip then we're in SyncStateNeedBlocks.
  1050  	if *blockTip.Hash != *headerTip.Hash {
  1051  		return SyncStateNeedBlocksss
  1052  	}
  1053  
  1054  	// If none of the checks above returned it means we're current.
  1055  	return SyncStateFullyCurrent
  1056  }
  1057  
  1058  func (bc *Blockchain) ChainState() SyncState {
  1059  	return bc.chainState()
  1060  }
  1061  
  1062  func (bc *Blockchain) isSyncing() bool {
  1063  	syncState := bc.chainState()
  1064  	return syncState == SyncStateSyncingHeaders || syncState == SyncStateSyncingBlocks
  1065  }
  1066  
  1067  // headerTip returns the tip of the header chain. Because we fetch headers
  1068  // before we fetch blocks, we track a chain for headers as separate from the
  1069  // main chain for blocks, which is why separate functions are required for
  1070  // each of them.
  1071  func (bc *Blockchain) headerTip() *BlockNode {
  1072  	if len(bc.bestHeaderChain) == 0 {
  1073  		return nil
  1074  	}
  1075  
  1076  	// Note this should always work because we should have the genesis block
  1077  	// in here.
  1078  	return bc.bestHeaderChain[len(bc.bestHeaderChain)-1]
  1079  }
  1080  
  1081  func (bc *Blockchain) HeaderTip() *BlockNode {
  1082  	return bc.headerTip()
  1083  }
  1084  
  1085  func (bc *Blockchain) DB() *badger.DB {
  1086  	return bc.db
  1087  }
  1088  
  1089  // blockTip returns the tip of the main block chain. We fetch headers first
  1090  // and then, once the header chain looks good, we fetch blocks. As such, we
  1091  // store two separate "best" chains: One containing the best headers, and
  1092  // the other containing the best blocks. The header chain is essentially a
  1093  // trail-blazer, validating headers as fast as it can before later fetching
  1094  // blocks for the headers that seem legitimate and adding them to the "real"
  1095  // best chain. If, while adding blocks to the best block chain, we realize
  1096  // some of the blocks are invalid, the best header chain is then adjusted to
  1097  // invalidate and chop off the headers corresponding to those blocks and
  1098  // their ancestors so the two generally stay in sync.
  1099  func (bc *Blockchain) blockTip() *BlockNode {
  1100  	var tip *BlockNode
  1101  
  1102  	if len(bc.bestChain) == 0 {
  1103  		return nil
  1104  	}
  1105  
  1106  	tip = bc.bestChain[len(bc.bestChain)-1]
  1107  
  1108  	return tip
  1109  }
  1110  
  1111  func (bc *Blockchain) BlockTip() *BlockNode {
  1112  	return bc.blockTip()
  1113  }
  1114  
  1115  func (bc *Blockchain) BestChain() []*BlockNode {
  1116  	return bc.bestChain
  1117  }
  1118  
  1119  func (bc *Blockchain) SetBestChain(bestChain []*BlockNode) {
  1120  	bc.bestChain = bestChain
  1121  }
  1122  
  1123  func (bc *Blockchain) SetBestChainMap(bestChain []*BlockNode, bestChainMap map[BlockHash]*BlockNode, blockIndex map[BlockHash]*BlockNode) {
  1124  	bc.bestChain = bestChain
  1125  	bc.bestChainMap = bestChainMap
  1126  	bc.blockIndex = blockIndex
  1127  }
  1128  
  1129  func (bc *Blockchain) _validateOrphanBlock(desoBlock *MsgDeSoBlock) error {
  1130  	// Error if the block is missing a parent hash or header.
  1131  	if desoBlock.Header == nil {
  1132  		return fmt.Errorf("_validateOrphanBlock: Block is missing header")
  1133  	}
  1134  	parentHash := desoBlock.Header.PrevBlockHash
  1135  	if parentHash == nil {
  1136  		return fmt.Errorf("_validateOrphanBlock: Block is missing parent hash")
  1137  	}
  1138  
  1139  	// Check that the block size isn't bigger than the max allowed. This prevents
  1140  	// an attack vector where someone might try and send us very large orphan blocks in
  1141  	// an attempt to exhaust our memory.
  1142  	serializedBlock, err := desoBlock.ToBytes(false)
  1143  	if err != nil {
  1144  		return fmt.Errorf("_validateOrphanBlock: Could not serialize block")
  1145  	}
  1146  	if uint64(len(serializedBlock)) > bc.params.MaxBlockSizeBytes {
  1147  		return RuleErrorBlockTooBig
  1148  	}
  1149  
  1150  	// No more validation is needed since the orphan will be properly validated
  1151  	// if and when we ever end up adding it to our block index either on the main
  1152  	// chain or on a side chain.
  1153  	//
  1154  	// TODO: It would be nice to do some kind of PoW check on unconnectedTxns, but it
  1155  	// seems useless because anyone who has access to MaxOrphansInMemory orphan
  1156  	// blocks has the ability to fill our orphan lists with garbage. Put another
  1157  	// way, a simple PoW check on orphan blocks doesn't seem to increase the cost
  1158  	// of an attack materially and could have negative effects if e.g. legitimate unconnectedTxns
  1159  	// earlier in the chain get filtered out because their difficulty is too low.
  1160  	// Moreover, while being attacked would be a minor inconvenience it doesn't
  1161  	// stop the node from reaching consensus eventually. So we'll punt on defending
  1162  	// against it unless/until it actually becomes a problem.
  1163  
  1164  	return nil
  1165  }
  1166  
  1167  // ProcessOrphanBlock runs some very basic validation on the orphan block and adds
  1168  // it to our orphan data structure if it passes. If there are too many orphan blocks
  1169  // in our data structure, it also evicts the oldest block to make room for this one.
  1170  //
  1171  // TODO: Currently we only remove orphan blocks if we have too many. This means in
  1172  // a steady state we are potentially keeping MaxOrphansInMemory at all times, which
  1173  // is wasteful of resources. Better would be to clean up orphan blocks once they're
  1174  // too old or something like that.
  1175  func (bc *Blockchain) ProcessOrphanBlock(desoBlock *MsgDeSoBlock, blockHash *BlockHash) error {
  1176  	err := bc._validateOrphanBlock(desoBlock)
  1177  	if err != nil {
  1178  		return errors.Wrapf(err, "ProcessOrphanBlock: Problem validating orphan block")
  1179  	}
  1180  
  1181  	// If this block is already in the orphan list then don't add it.
  1182  	//
  1183  	// TODO: We do a basic linear search here because there are so few unconnectedTxns
  1184  	// in our list. If we want to track more unconnectedTxns in the future we would probably
  1185  	// want to manage this with a map.
  1186  	for orphanElem := bc.orphanList.Front(); orphanElem != nil; orphanElem = orphanElem.Next() {
  1187  		orphanBlock := orphanElem.Value.(*OrphanBlock)
  1188  		if *orphanBlock.Hash == *blockHash {
  1189  			return RuleErrorDuplicateOrphan
  1190  		}
  1191  	}
  1192  
  1193  	// At this point we know we are adding a new orphan to the list.
  1194  
  1195  	// If we are at capacity remove an orphan block by simply deleting the front
  1196  	// element of the orphan list, which is also the oldest orphan.
  1197  	if bc.orphanList.Len() >= MaxOrphansInMemory {
  1198  		elemToRemove := bc.orphanList.Front()
  1199  		bc.orphanList.Remove(elemToRemove)
  1200  	}
  1201  
  1202  	// Add the orphan block to our data structure. We can also assume the orphan
  1203  	// is not a duplicate and therefore simply add a new entry to the end of the list.
  1204  	bc.orphanList.PushBack(&OrphanBlock{
  1205  		Block: desoBlock,
  1206  		Hash:  blockHash,
  1207  	})
  1208  
  1209  	return nil
  1210  }
  1211  
  1212  func (bc *Blockchain) MarkBlockInvalid(node *BlockNode, errOccurred RuleError) {
  1213  	// Print a stack trace when this happens
  1214  	glog.Errorf("MarkBlockInvalid: Block height: %v, Block hash: %v, Error: %v", node.Height, node.Hash, errOccurred)
  1215  	glog.Error("MarkBlockInvalid: Printing stack trace so error is easy to find: ")
  1216  	glog.Error(string(debug.Stack()))
  1217  
  1218  	// TODO: Not marking blocks invalid makes debugging easier when we hit an issuse,
  1219  	// and makes it so that we don't need to start the node from scratch when it has a
  1220  	// problem. But it can also make connecting to a bad peer more risky. In the future, once
  1221  	// syncing issues are all resolved, bad blocks should be marked as such and probably
  1222  	// not reprocessed.
  1223  	glog.Error("MarkBlockInvalid: Not marking blocks invalid for now because it makes debugging easier")
  1224  
  1225  	//panic(errOccurred)
  1226  
  1227  	// Mark the node's block as invalid.
  1228  	//node.Status |= StatusBlockValidateFailed
  1229  	//
  1230  	//// If this node happens to be in the main header chain, mark
  1231  	//// every node after this one in the header chain as invalid and
  1232  	//// remove these nodes from the header chain to keep it in sync.
  1233  	//if _, nodeInHeaderChain := bc.bestHeaderChainMap[*node.Hash]; nodeInHeaderChain {
  1234  	//	for ii := node.Height; ii < uint32(len(bc.bestHeaderChain)); ii++ {
  1235  	//		// Update the status of the node. Mark it as processed since that's used
  1236  	//		// to determine whether we shoudl fetch the block.
  1237  	//		headerNode := bc.bestHeaderChain[ii]
  1238  	//		headerNode.Status |= (StatusBlockProcessed & StatusBlockValidateFailed)
  1239  	//		if err := PutHeightHashToNodeInfo(headerNode, bc.db, false /*bitcoinNodes*/); err != nil {
  1240  	//			// Log if an error occurs but no need to return it.
  1241  	//			glog.Error(errors.Wrapf(err,
  1242  	//				"MarkBlockInvalid: Problem calling PutHeightHashToNodeInfo on header node"))
  1243  	//		}
  1244  	//
  1245  	//		delete(bc.bestHeaderChainMap, *headerNode.Hash)
  1246  	//	}
  1247  	//	// Chop off the nodes now that we've updated the status of all of them.
  1248  	//	bc.bestHeaderChain = bc.bestHeaderChain[:node.Height]
  1249  	//
  1250  	//	// Note there is no need to update the db for the header chain because we don't
  1251  	//	// store nodes for headers on the db.
  1252  	//
  1253  	//	// At this point the header main chain should be fully updated in memory
  1254  	//	// and in the db to reflect that all nodes from this one onward are invalid
  1255  	//	// and should no longer be considered as part of the main chain.
  1256  	//}
  1257  	//
  1258  	//// Update the node on the db to reflect the status change.
  1259  	////
  1260  	//// Put the node in our node index in the db under the
  1261  	////   <height uin32, blockhash BlockHash> -> <node info>
  1262  	//// index.
  1263  	//if err := PutHeightHashToNodeInfo(node, bc.db, false /*bitcoinNodes*/); err != nil {
  1264  	//	// Log if an error occurs but no need to return it.
  1265  	//	glog.Error(errors.Wrapf(err,
  1266  	//		"MarkBlockInvalid: Problem calling PutHeightHashToNodeInfo"))
  1267  	//}
  1268  }
  1269  
  1270  func _FindCommonAncestor(node1 *BlockNode, node2 *BlockNode) *BlockNode {
  1271  	if node1 == nil || node2 == nil {
  1272  		// If either node is nil then there can't be a common ancestor.
  1273  		return nil
  1274  	}
  1275  
  1276  	// Get the two nodes to be at the same height.
  1277  	if node1.Height > node2.Height {
  1278  		node1 = node1.Ancestor(node2.Height)
  1279  	} else if node1.Height < node2.Height {
  1280  		node2 = node2.Ancestor(node1.Height)
  1281  	}
  1282  
  1283  	// Iterate the nodes backward until they're either the same or we
  1284  	// reach the end of the lists. We only need to check node1 for nil
  1285  	// since they're the same height and we are iterating both back
  1286  	// in tandem.
  1287  	for node1 != nil && node1 != node2 {
  1288  		node1 = node1.Parent
  1289  		node2 = node2.Parent
  1290  	}
  1291  
  1292  	// By now either node1 == node2 and we found the common ancestor or
  1293  	// both nodes are nil, which means we reached the bottom without finding
  1294  	// a common ancestor.
  1295  	return node1
  1296  }
  1297  
  1298  func CheckTransactionSanity(txn *MsgDeSoTxn) error {
  1299  	// We don't check the sanity of block reward transactions.
  1300  	if txn.TxnMeta.GetTxnType() == TxnTypeBlockReward {
  1301  		return nil
  1302  	}
  1303  
  1304  	// All transactions are required to have a valid public key set unless they are one
  1305  	// of the following:
  1306  	// - BitcoinExchange transactions don't need a PublicKey because the public key can
  1307  	//   easily be derived from the BitcoinTransaction embedded in the TxnMeta.
  1308  	requiresPublicKey := txn.TxnMeta.GetTxnType() != TxnTypeBitcoinExchange
  1309  	if requiresPublicKey {
  1310  		if len(txn.PublicKey) != btcec.PubKeyBytesLenCompressed {
  1311  			return errors.Wrapf(RuleErrorTransactionMissingPublicKey, "CheckTransactionSanity: ")
  1312  		}
  1313  	}
  1314  
  1315  	// Every txn must have at least one input unless it is one of the following
  1316  	// transaction types.
  1317  	// - BitcoinExchange transactions will be rejected if they're duplicates in
  1318  	//   spite of the fact that they don't have inputs or outputs.
  1319  	//
  1320  	// Note this function isn't run on BlockReward transactions, but that they're
  1321  	// allowed to have zero inputs as well. In the case of BlockRewards, they could
  1322  	// have duplicates if someone uses the same public key without changing the
  1323  	// ExtraNonce field, but this is not the default behavior, and in general the
  1324  	// only thing a duplicate will do is make a previous transaction invalid, so
  1325  	// there's not much incentive to do it.
  1326  	//
  1327  	// TODO: The above is easily fixed by requiring something like block height to
  1328  	// be present in the ExtraNonce field.
  1329  	canHaveZeroInputs := (txn.TxnMeta.GetTxnType() == TxnTypeBitcoinExchange ||
  1330  		txn.TxnMeta.GetTxnType() == TxnTypePrivateMessage)
  1331  	if len(txn.TxInputs) == 0 && !canHaveZeroInputs {
  1332  		glog.V(2).Infof("CheckTransactionSanity: Txn needs at least one input: %v", spew.Sdump(txn))
  1333  		return RuleErrorTxnMustHaveAtLeastOneInput
  1334  	}
  1335  	// Every txn must have at least one output unless it is one of the following transaction
  1336  	// types.
  1337  	// - BitcoinExchange transactions are deduped using the hash of the Bitcoin transaction
  1338  	//   embedded in them and having an output adds no value because the output is implied
  1339  	//   by the Bitcoin transaction embedded in it. In particular, the output is automatically
  1340  	//   assumed to be the public key of the the first input in the Bitcoin transaction and
  1341  	//   the fee is automatically assumed to be some percentage of the DeSo being created
  1342  	//   (10bps at the time of this writing).
  1343  	//
  1344  	// - TxnTypeCreatorCoin are also ok to have no outputs (e.g. if you spend your whole deso
  1345  	//   balance on a creator coin)
  1346  	canHaveZeroOutputs := (txn.TxnMeta.GetTxnType() == TxnTypeBitcoinExchange ||
  1347  		txn.TxnMeta.GetTxnType() == TxnTypePrivateMessage ||
  1348  		txn.TxnMeta.GetTxnType() == TxnTypeCreatorCoin) // TODO: add a test for this case
  1349  
  1350  	if len(txn.TxOutputs) == 0 && !canHaveZeroOutputs {
  1351  		glog.V(2).Infof("CheckTransactionSanity: Txn needs at least one output: %v", spew.Sdump(txn))
  1352  		return RuleErrorTxnMustHaveAtLeastOneOutput
  1353  	}
  1354  
  1355  	// Loop through the outputs and do a few sanity checks.
  1356  	var totalOutNanos uint64
  1357  	for _, txout := range txn.TxOutputs {
  1358  		// Check that each output's amount is not bigger than the max as a
  1359  		// sanity check.
  1360  		if txout.AmountNanos > MaxNanos {
  1361  			return RuleErrorOutputExceedsMax
  1362  		}
  1363  		// Check that this output doesn't overflow the total as a sanity
  1364  		// check. This is frankly impossible since our maximum limit is
  1365  		// not close to the max size of a uint64 but check it nevertheless.
  1366  		if totalOutNanos >= math.MaxUint64-txout.AmountNanos {
  1367  			return RuleErrorOutputOverflowsTotal
  1368  		}
  1369  		// Check that the total isn't bigger than the max supply.
  1370  		if totalOutNanos > MaxNanos {
  1371  			return RuleErrorTotalOutputExceedsMax
  1372  		}
  1373  	}
  1374  
  1375  	// Loop through the inputs and do a few sanity checks.
  1376  	existingInputs := make(map[DeSoInput]bool)
  1377  	for _, txin := range txn.TxInputs {
  1378  		if _, exists := existingInputs[*txin]; exists {
  1379  			return RuleErrorDuplicateInputs
  1380  		}
  1381  		existingInputs[*txin] = true
  1382  	}
  1383  
  1384  	return nil
  1385  }
  1386  
  1387  func GetReorgBlocks(tip *BlockNode, newNode *BlockNode) (_commonAncestor *BlockNode, _detachNodes []*BlockNode, _attachNodes []*BlockNode) {
  1388  	// Find the common ancestor of this block and the main header chain.
  1389  	commonAncestor := _FindCommonAncestor(tip, newNode)
  1390  	// Log a warning if the reorg is going to be a big one.
  1391  	numBlocks := tip.Height - commonAncestor.Height
  1392  	if numBlocks > 10 {
  1393  		glog.Warningf("GetReorgBlocks: Proceeding with reorg of (%d) blocks from "+
  1394  			"block (%v) at height (%d) to block (%v) at height of (%d)",
  1395  			numBlocks, tip, tip.Height, newNode, newNode.Height)
  1396  	}
  1397  
  1398  	// Get the blocks to detach. Start at the tip and work backwards to the
  1399  	// common ancestor (but don't include the common ancestor since we don't
  1400  	// need to roll that back).
  1401  	//
  1402  	// detachBlocks will have the current tip as its first element and parents
  1403  	// of the tip thereafter.
  1404  	detachBlocks := []*BlockNode{}
  1405  	for currentBlock := tip; *currentBlock.Hash != *commonAncestor.Hash; currentBlock = currentBlock.Parent {
  1406  		detachBlocks = append(detachBlocks, currentBlock)
  1407  	}
  1408  
  1409  	// Get the blocks to attach. Start at the new node and work backwards to
  1410  	// the common ancestor (but don't include the common ancestor since we'll
  1411  	// be using it as the new tip after we detach all the blocks from the current
  1412  	// tip).
  1413  	//
  1414  	// attachNodes will have the new node as its first element and work back to
  1415  	// the node right after the common ancestor as its last element.
  1416  	attachBlocks := []*BlockNode{}
  1417  	for currentBlock := newNode; *currentBlock.Hash != *commonAncestor.Hash; currentBlock = currentBlock.Parent {
  1418  		attachBlocks = append(attachBlocks, currentBlock)
  1419  	}
  1420  	// Reverse attachBlocks so that the node right after the common ancestor
  1421  	// will be the first element and the node at the end of the list will be
  1422  	// the new node.
  1423  	for i, j := 0, len(attachBlocks)-1; i < j; i, j = i+1, j-1 {
  1424  		attachBlocks[i], attachBlocks[j] = attachBlocks[j], attachBlocks[i]
  1425  	}
  1426  
  1427  	return commonAncestor, detachBlocks, attachBlocks
  1428  }
  1429  
  1430  func updateBestChainInMemory(mainChainList []*BlockNode, mainChainMap map[BlockHash]*BlockNode, detachBlocks []*BlockNode, attachBlocks []*BlockNode) (
  1431  	chainList []*BlockNode, chainMap map[BlockHash]*BlockNode) {
  1432  
  1433  	// Remove the nodes we detached from the end of the best chain node list.
  1434  	tipIndex := len(mainChainList) - 1
  1435  	for blockOffset := 0; blockOffset < len(detachBlocks); blockOffset++ {
  1436  		blockIndex := tipIndex - blockOffset
  1437  		delete(mainChainMap, *mainChainList[blockIndex].Hash)
  1438  	}
  1439  	mainChainList = mainChainList[:len(mainChainList)-len(detachBlocks)]
  1440  
  1441  	// Add the nodes we attached to the end of the list. Note that this loop iterates
  1442  	// forward because because attachBlocks has the node right after the common ancestor
  1443  	// first, with the new tip at the end.
  1444  	for _, attachNode := range attachBlocks {
  1445  		mainChainList = append(mainChainList, attachNode)
  1446  		mainChainMap[*attachNode.Hash] = attachNode
  1447  	}
  1448  
  1449  	return mainChainList, mainChainMap
  1450  }
  1451  
  1452  // Caller must acquire the ChainLock for writing prior to calling this.
  1453  func (bc *Blockchain) processHeader(blockHeader *MsgDeSoHeader, headerHash *BlockHash) (_isMainChain bool, _isOrphan bool, _err error) {
  1454  	// Start by checking if the header already exists in our node
  1455  	// index. If it does, then return an error. We should generally
  1456  	// expect that processHeader will only be called on headers we
  1457  	// haven't seen before.
  1458  	_, nodeExists := bc.blockIndex[*headerHash]
  1459  	if nodeExists {
  1460  		return false, false, HeaderErrorDuplicateHeader
  1461  	}
  1462  
  1463  	// If we're here then it means we're processing a header we haven't
  1464  	// seen before.
  1465  
  1466  	// Reject the header if it is more than N seconds in the future.
  1467  	tstampDiff := int64(blockHeader.TstampSecs) - bc.timeSource.AdjustedTime().Unix()
  1468  	if tstampDiff > int64(bc.params.MaxTstampOffsetSeconds) {
  1469  		glog.V(1).Infof("HeaderErrorBlockTooFarInTheFuture: tstampDiff %d > "+
  1470  			"MaxTstampOffsetSeconds %d. blockHeader.TstampSecs=%d; adjustedTime=%d",
  1471  			tstampDiff, bc.params.MaxTstampOffsetSeconds, blockHeader.TstampSecs,
  1472  			bc.timeSource.AdjustedTime().Unix())
  1473  		return false, false, HeaderErrorBlockTooFarInTheFuture
  1474  	}
  1475  
  1476  	// Try to find this header's parent in our block index.
  1477  	// If we can't find the parent then this header is an orphan and we
  1478  	// can return early because we don't process unconnectedTxns.
  1479  	// TODO: Should we just return an error if the header is an orphan?
  1480  	if blockHeader.PrevBlockHash == nil {
  1481  		return false, false, HeaderErrorNilPrevHash
  1482  	}
  1483  	parentNode, parentNodeExists := bc.blockIndex[*blockHeader.PrevBlockHash]
  1484  	if !parentNodeExists {
  1485  		// This block is an orphan if its parent doesn't exist and we don't
  1486  		// process unconnectedTxns.
  1487  		return false, true, nil
  1488  	}
  1489  
  1490  	// If the parent node is invalid then this header is invalid as well. Note that
  1491  	// if the parent node exists then its header must either be Validated or
  1492  	// ValidateFailed.
  1493  	parentHeader := parentNode.Header
  1494  	if parentHeader == nil || (parentNode.Status&(StatusHeaderValidateFailed|StatusBlockValidateFailed)) != 0 {
  1495  		return false, false, errors.Wrapf(
  1496  			HeaderErrorInvalidParent, "Parent header: %v, Status check: %v, Parent node status: %v, Parent node header: %v",
  1497  			parentHeader, (parentNode.Status&(StatusHeaderValidateFailed|StatusBlockValidateFailed)) != 0,
  1498  			parentNode.Status,
  1499  			parentNode.Header)
  1500  	}
  1501  
  1502  	// Verify that the height is one greater than the parent.
  1503  	prevHeight := parentHeader.Height
  1504  	if blockHeader.Height != prevHeight+1 {
  1505  		glog.Errorf("processHeader: Height of block (=%d) is not equal to one greater "+
  1506  			"than the parent height (=%d)", blockHeader.Height, prevHeight)
  1507  		return false, false, HeaderErrorHeightInvalid
  1508  	}
  1509  
  1510  	// Make sure the block timestamp is greater than the previous block's timestamp.
  1511  	// Note Bitcoin checks that the timestamp is greater than the median
  1512  	// of the last 11 blocks. While this seems to work for Bitcoin for now it seems
  1513  	// vulnerable to a "time warp" attack (requires 51%) and
  1514  	// we can do a little better by forcing a harder constraint of making
  1515  	// sure a timestamp is larger than the of the previous block. It seems
  1516  	// the only real downside of this is some complexity on the miner side
  1517  	// of having to account for what happens if a block appears that is from
  1518  	// some nearby time in the future rather than the current time. But this
  1519  	// burden seems worth it in order to
  1520  	// preclude a known and fairly damaging attack from being possible. Moreover,
  1521  	// while there are more complicated schemes to fight other attacks based on
  1522  	// timestamp manipulation, their benefits seem marginal and not worth the
  1523  	// added complexity they entail for now.
  1524  	//
  1525  	// Discussion of time warp attack and potential fixes for BTC:
  1526  	// https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2018-August/016342.html
  1527  	// Discussion of more complex attacks and potential fixes:
  1528  	// https://github.com/zawy12/difficulty-algorithms/issues/30
  1529  	//
  1530  	// TODO: Consider a per-block difficulty adjustment scheme like Ethereum has.
  1531  	// This commentary is useful to consider with regard to that:
  1532  	//   https://github.com/zawy12/difficulty-algorithms/issues/45
  1533  	if blockHeader.TstampSecs <= parentHeader.TstampSecs {
  1534  		glog.Warningf("processHeader: Rejecting header because timestamp %v is "+
  1535  			"before timestamp of previous block %v",
  1536  			time.Unix(int64(blockHeader.TstampSecs), 0),
  1537  			time.Unix(int64(parentHeader.TstampSecs), 0))
  1538  		return false, false, HeaderErrorTimestampTooEarly
  1539  	}
  1540  
  1541  	// Check that the proof of work beats the difficulty as calculated from
  1542  	// the parent block. Note that if the parent block is in the block index
  1543  	// then it has necessarily had its difficulty validated, and so using it to
  1544  	// do this check makes sense.
  1545  	diffTarget, err := CalcNextDifficultyTarget(
  1546  		parentNode, blockHeader.Version, bc.params)
  1547  	if err != nil {
  1548  		return false, false, errors.Wrapf(err,
  1549  			"ProcessBlock: Problem computing difficulty "+
  1550  				"target from parent block %s", hex.EncodeToString(parentNode.Hash[:]))
  1551  	}
  1552  	diffTargetBigint := HashToBigint(diffTarget)
  1553  	blockHashBigint := HashToBigint(headerHash)
  1554  	if diffTargetBigint.Cmp(blockHashBigint) < 0 {
  1555  		return false, false,
  1556  			errors.Wrapf(HeaderErrorBlockDifficultyAboveTarget, "Target: %v, Actual: %v", diffTarget, headerHash)
  1557  	}
  1558  
  1559  	// At this point the header seems sane so we store it in the db and add
  1560  	// it to our in-memory block index. Note we're not doing this atomically.
  1561  	// Worst-case, we have a block in our db with no pointer to it in our index,
  1562  	// which isn't a big deal.
  1563  	//
  1564  	// Note in the calculation of CumWork below we are adding the work specified
  1565  	// in the difficulty *target* rather than the work actually done to mine the
  1566  	// block. There is a very good reason for this, which is that it materially
  1567  	// increases a miner's incentive to reveal their block immediately after it's
  1568  	// been mined as opposed to try and play games where they withhold their block
  1569  	// and try to mine on top of it before revealing it to everyone.
  1570  	newWork := BytesToBigint(ExpectedWorkForBlockHash(diffTarget)[:])
  1571  	cumWork := newWork.Add(newWork, parentNode.CumWork)
  1572  	newNode := NewBlockNode(
  1573  		parentNode,
  1574  		headerHash,
  1575  		uint32(blockHeader.Height),
  1576  		diffTarget,
  1577  		cumWork,
  1578  		blockHeader,
  1579  		StatusHeaderValidated)
  1580  
  1581  	// Note that we don't store a node for this header on the db until we have downloaded
  1582  	// a corresponding block. This has the effect of preventing us against disk-fill
  1583  	// attacks. If we instead stored headers on the db then we'd have to deal with an
  1584  	// attack that looks as follows:
  1585  	// - Attacker makes us download a lot of low-difficulty headers until we eventually
  1586  	//   get current and disconnect because the chainwork is too low (having stored all
  1587  	//   of those header nodes on the db).
  1588  	// - Attacker repeats this over and over again until our db on disk is really full.
  1589  	//
  1590  	// The above is mitigated because we don't download blocks until we have a header chain
  1591  	// with enough work, which means we won't store anything that doesn't have a lot of work
  1592  	// built on it.
  1593  
  1594  	// If all went well with storing the header, set it in our in-memory
  1595  	// index. If we're still syncing then it's safe to just set it. Otherwise, we
  1596  	// need to make a copy first since there could be some concurrency issues.
  1597  	if bc.isSyncing() {
  1598  		bc.blockIndex[*newNode.Hash] = newNode
  1599  	} else {
  1600  		newBlockIndex := bc.CopyBlockIndex()
  1601  		newBlockIndex[*newNode.Hash] = newNode
  1602  		bc.blockIndex = newBlockIndex
  1603  	}
  1604  
  1605  	// Update the header chain if this header has more cumulative work than
  1606  	// the header chain's tip. Note that we can assume all ancestors of this
  1607  	// header are valid at this point.
  1608  	isMainChain := false
  1609  	headerTip := bc.headerTip()
  1610  	if headerTip.CumWork.Cmp(newNode.CumWork) < 0 {
  1611  		isMainChain = true
  1612  
  1613  		_, detachBlocks, attachBlocks := GetReorgBlocks(headerTip, newNode)
  1614  		bc.bestHeaderChain, bc.bestHeaderChainMap = updateBestChainInMemory(
  1615  			bc.bestHeaderChain, bc.bestHeaderChainMap, detachBlocks, attachBlocks)
  1616  
  1617  		// Note that we don't store the best header hash here and so this is an
  1618  		// in-memory-only adjustment. See the comment above on preventing attacks.
  1619  	}
  1620  
  1621  	return isMainChain, false, nil
  1622  }
  1623  
  1624  // ProcessHeader is a wrapper around processHeader, which does the leg-work, that
  1625  // acquires the ChainLock first.
  1626  func (bc *Blockchain) ProcessHeader(blockHeader *MsgDeSoHeader, headerHash *BlockHash) (_isMainChain bool, _isOrphan bool, _err error) {
  1627  	bc.ChainLock.Lock()
  1628  	defer bc.ChainLock.Unlock()
  1629  
  1630  	return bc.processHeader(blockHeader, headerHash)
  1631  }
  1632  
  1633  // Note: It is the caller's responsibility to ensure that the BitcoinManager is
  1634  // time-current prior to calling ProcessBlock on any transactions that require the
  1635  // BitcoinManager for validation (e.g. BitcoinExchange transactions). Failure to
  1636  // do so will cause ProcessBlock to error on blocks that could otherwise be valid
  1637  // if a time-current BitcoinManager were available. If it is known for sure that
  1638  // no BitcoinExchange transactions need to be validated then it is OK for the
  1639  // BitcoinManager to not be time-current and even for it to be nil entirely. This
  1640  // is useful e.g. for tests where we want to exercise ProcessBlock without setting
  1641  // up a time-current BitcoinManager.
  1642  func (bc *Blockchain) ProcessBlock(desoBlock *MsgDeSoBlock, verifySignatures bool) (_isMainChain bool, _isOrphan bool, _err error) {
  1643  	// TODO: Move this to be more isolated.
  1644  	bc.ChainLock.Lock()
  1645  	defer bc.ChainLock.Unlock()
  1646  
  1647  	if desoBlock == nil {
  1648  		return false, false, fmt.Errorf("ProcessBlock: Block is nil")
  1649  	}
  1650  
  1651  	// Start by getting and validating the block's header.
  1652  	blockHeader := desoBlock.Header
  1653  	if blockHeader == nil {
  1654  		return false, false, fmt.Errorf("ProcessBlock: Block header was nil")
  1655  	}
  1656  	blockHash, err := blockHeader.Hash()
  1657  	if err != nil {
  1658  		return false, false, errors.Wrapf(err, "ProcessBlock: Problem computing block hash")
  1659  	}
  1660  	// If a trusted block producer public key is set, then we only accept blocks
  1661  	// if they have been signed by one of these public keys.
  1662  	if len(bc.trustedBlockProducerPublicKeys) > 0 {
  1663  		if blockHeader.Height >= bc.trustedBlockProducerStartHeight {
  1664  			if desoBlock.BlockProducerInfo == nil ||
  1665  				desoBlock.BlockProducerInfo.Signature == nil {
  1666  
  1667  				return false, false, errors.Wrapf(RuleErrorMissingBlockProducerSignature,
  1668  					"ProcessBlock: Block signature is required since "+
  1669  						"--trusted_block_producer_public_keys is set *and* block height "+
  1670  						"%v is >= --trusted_block_producer_block_height %v.", blockHeader.Height,
  1671  					bc.trustedBlockProducerStartHeight)
  1672  			}
  1673  			// At this point, we are confident that a signature is embedded in
  1674  			// the block.
  1675  
  1676  			// Verify that the public key has the valid length
  1677  			publicKey := desoBlock.BlockProducerInfo.PublicKey
  1678  			if len(publicKey) != btcec.PubKeyBytesLenCompressed {
  1679  				return false, false, errors.Wrapf(RuleErrorInvalidBlockProducerPublicKey,
  1680  					"ProcessBlock: Block producer public key is invalid even though "+
  1681  						"--trusted_block_producer_public_keys is set *and* block height "+
  1682  						"%v is >= --trusted_block_producer_block_height %v.", blockHeader.Height,
  1683  					bc.trustedBlockProducerStartHeight)
  1684  			}
  1685  
  1686  			// Verify that the public key is in the allowed set.
  1687  			if _, exists := bc.trustedBlockProducerPublicKeys[MakePkMapKey(publicKey)]; !exists {
  1688  				return false, false, errors.Wrapf(RuleErrorBlockProducerPublicKeyNotInWhitelist,
  1689  					"ProcessBlock: Block producer public key %v is not in the allowed list of "+
  1690  						"--trusted_block_producer_public_keys: %v.", PkToStringBoth(publicKey),
  1691  					bc.trustedBlockProducerPublicKeys)
  1692  			}
  1693  
  1694  			// Verify that the public key has not been forbidden.
  1695  			dbEntry := DbGetForbiddenBlockSignaturePubKey(bc.db, publicKey)
  1696  			if dbEntry != nil {
  1697  				return false, false, errors.Wrapf(RuleErrorForbiddenBlockProducerPublicKey,
  1698  					"ProcessBlock: Block producer public key %v is forbidden", PkToStringBoth(publicKey))
  1699  			}
  1700  
  1701  			// At this point we are confident that we have a valid public key that is
  1702  			// trusted.
  1703  
  1704  			signature := desoBlock.BlockProducerInfo.Signature
  1705  			pkObj, err := btcec.ParsePubKey(publicKey, btcec.S256())
  1706  			if err != nil {
  1707  				return false, false, errors.Wrapf(err,
  1708  					"ProcessBlock: Error parsing block producer public key: %v.",
  1709  					PkToStringBoth(publicKey))
  1710  			}
  1711  			if !signature.Verify(blockHash[:], pkObj) {
  1712  				return false, false, errors.Wrapf(RuleErrorInvalidBlockProducerSIgnature,
  1713  					"ProcessBlock: Error validating signature %v for public key %v: %v.",
  1714  					hex.EncodeToString(signature.Serialize()),
  1715  					PkToStringBoth(publicKey),
  1716  					err)
  1717  			}
  1718  		}
  1719  	}
  1720  
  1721  	// See if a node for the block exists in our node index.
  1722  	nodeToValidate, nodeExists := bc.blockIndex[*blockHash]
  1723  	// If no node exists for this block at all, then process the header
  1724  	// first before we do anything. This should create a node and set
  1725  	// the header validation status for it.
  1726  	if !nodeExists {
  1727  		_, isOrphan, err := bc.processHeader(blockHeader, blockHash)
  1728  		if err != nil {
  1729  			// If an error occurred processing the header, then the header
  1730  			// should be marked as invalid, which should be sufficient.
  1731  			return false, false, err
  1732  		}
  1733  		// If the header is an orphan, return early. We don't process orphan
  1734  		// blocks. If the block and its header are truly legitimate then we
  1735  		// should re-request it and its parents from a peer and reprocess it
  1736  		// once it is no longer an orphan.
  1737  		if isOrphan {
  1738  			return false, true, nil
  1739  		}
  1740  
  1741  		// Reset the pointers after having presumably added the header to the
  1742  		// block index.
  1743  		nodeToValidate, nodeExists = bc.blockIndex[*blockHash]
  1744  	}
  1745  	// At this point if the node still doesn't exist or if the header's validation
  1746  	// failed then we should return an error for the block. Note that at this point
  1747  	// the header must either be Validated or ValidateFailed.
  1748  	if !nodeExists || (nodeToValidate.Status&StatusHeaderValidated) == 0 {
  1749  		return false, false, RuleErrorInvalidBlockHeader
  1750  	}
  1751  
  1752  	// At this point, we are sure that the block's header is not an orphan and
  1753  	// that its header has been properly validated. The block itself could still
  1754  	// be an orphan, however, for example if we've processed the header of the parent but
  1755  	// not the parent block itself.
  1756  	//
  1757  	// Find the parent node in our block index. If the node doesn't exist or if the
  1758  	// node exists without StatusBlockProcessed, then the current block is an orphan.
  1759  	// In this case go ahead and return early. If its parents are truly legitimate then we
  1760  	// should re-request it and its parents from a node and reprocess it
  1761  	// once it is no longer an orphan.
  1762  	parentNode, parentNodeExists := bc.blockIndex[*blockHeader.PrevBlockHash]
  1763  	if !parentNodeExists || (parentNode.Status&StatusBlockProcessed) == 0 {
  1764  		return false, true, nil
  1765  	}
  1766  
  1767  	// At this point, because we know the block isn't an orphan, go ahead and mark
  1768  	// it as processed. This flag is basically used to avoid situations in which we
  1769  	// continuously try to fetch and reprocess a block because we forgot to mark
  1770  	// it as invalid (which would be a bug but this behavior allows us to handle
  1771  	// it more gracefully).
  1772  	nodeToValidate.Status |= StatusBlockProcessed
  1773  
  1774  	if bc.postgres != nil {
  1775  		if err := bc.postgres.UpsertBlock(nodeToValidate); err != nil {
  1776  			return false, false, errors.Wrapf(err,
  1777  				"ProcessBlock: Problem saving block with StatusBlockProcessed")
  1778  		}
  1779  	} else {
  1780  		if err := PutHeightHashToNodeInfo(nodeToValidate, bc.db, false /*bitcoinNodes*/); err != nil {
  1781  			return false, false, errors.Wrapf(
  1782  				err, "ProcessBlock: Problem calling PutHeightHashToNodeInfo with StatusBlockProcessed")
  1783  		}
  1784  	}
  1785  
  1786  	// Reject the block if any of the following apply to the parent:
  1787  	// - Its header is nil.
  1788  	// - Its header or its block validation failed.
  1789  	if parentNode.Header == nil ||
  1790  		(parentNode.Status&(StatusHeaderValidateFailed|StatusBlockValidateFailed)) != 0 {
  1791  
  1792  		bc.MarkBlockInvalid(nodeToValidate, RuleErrorPreviousBlockInvalid)
  1793  		return false, false, RuleErrorPreviousBlockInvalid
  1794  	}
  1795  
  1796  	// At this point, we know that we are processing a block we haven't seen
  1797  	// before and we know that the parent block is stored and not invalid.
  1798  
  1799  	// Make sure the block size is not too big.
  1800  	serializedBlock, err := desoBlock.ToBytes(false)
  1801  	if err != nil {
  1802  		// Don't mark the block invalid here since the serialization is
  1803  		// potentially a network issue not an issue with the actual block.
  1804  		return false, false, fmt.Errorf("ProcessBlock: Problem serializing block")
  1805  	}
  1806  	if uint64(len(serializedBlock)) > bc.params.MaxBlockSizeBytes {
  1807  		bc.MarkBlockInvalid(nodeToValidate, RuleErrorBlockTooBig)
  1808  		return false, false, RuleErrorBlockTooBig
  1809  	}
  1810  
  1811  	// Block must have at least one transaction.
  1812  	if len(desoBlock.Txns) == 0 {
  1813  		bc.MarkBlockInvalid(nodeToValidate, RuleErrorNoTxns)
  1814  		return false, false, RuleErrorNoTxns
  1815  	}
  1816  
  1817  	// The first transaction in a block must be a block reward.
  1818  	firstTxn := desoBlock.Txns[0]
  1819  	if firstTxn.TxnMeta.GetTxnType() != TxnTypeBlockReward {
  1820  		return false, false, RuleErrorFirstTxnMustBeBlockReward
  1821  	}
  1822  
  1823  	// Do some txn sanity checks.
  1824  	for _, txn := range desoBlock.Txns[1:] {
  1825  		// There shouldn't be more than one block reward in the transaction list.
  1826  		if txn.TxnMeta.GetTxnType() == TxnTypeBlockReward {
  1827  			bc.MarkBlockInvalid(nodeToValidate, RuleErrorMoreThanOneBlockReward)
  1828  			return false, false, RuleErrorMoreThanOneBlockReward
  1829  		}
  1830  
  1831  		if err := CheckTransactionSanity(txn); err != nil {
  1832  			bc.MarkBlockInvalid(
  1833  				nodeToValidate, RuleError(errors.Wrapf(RuleErrorTxnSanity, "Error: %v", err).Error()))
  1834  			return false, false, err
  1835  		}
  1836  	}
  1837  
  1838  	// Compute and check the merkle root of all the txns.
  1839  	merkleRoot, txHashes, err := ComputeMerkleRoot(desoBlock.Txns)
  1840  	if err != nil {
  1841  		// Don't mark the block invalid here since the serialization is
  1842  		// potentially a network issue not an issue with the actual block.
  1843  		return false, false, errors.Wrapf(err, "ProcessBlock: Problem computing merkle root")
  1844  	}
  1845  	if *merkleRoot != *blockHeader.TransactionMerkleRoot {
  1846  		bc.MarkBlockInvalid(nodeToValidate, RuleErrorInvalidTxnMerkleRoot)
  1847  		glog.Errorf("ProcessBlock: Merkle root in block %v does not match computed "+
  1848  			"merkle root %v", blockHeader.TransactionMerkleRoot, merkleRoot)
  1849  		return false, false, RuleErrorInvalidTxnMerkleRoot
  1850  	}
  1851  
  1852  	// Check for duplicate txns now that they're hashed.
  1853  	existingTxns := make(map[BlockHash]bool)
  1854  	for ii := range desoBlock.Txns {
  1855  		currentHash := *txHashes[ii]
  1856  		if _, exists := existingTxns[currentHash]; exists {
  1857  			bc.MarkBlockInvalid(nodeToValidate, RuleErrorDuplicateTxn)
  1858  			return false, false, RuleErrorDuplicateTxn
  1859  		}
  1860  		existingTxns[currentHash] = true
  1861  	}
  1862  
  1863  	// Try and store the block and its corresponding node info since it has passed
  1864  	// basic validation.
  1865  	nodeToValidate.Status |= StatusBlockStored
  1866  
  1867  	if bc.postgres != nil {
  1868  		if err = bc.postgres.UpsertBlock(nodeToValidate); err != nil {
  1869  			err = errors.Wrapf(err, "ProcessBlock: Problem saving block with StatusBlockStored")
  1870  		}
  1871  	} else {
  1872  		err = bc.db.Update(func(txn *badger.Txn) error {
  1873  			// Store the new block in the db under the
  1874  			//   <blockHash> -> <serialized block>
  1875  			// index.
  1876  			if err := PutBlockWithTxn(txn, desoBlock); err != nil {
  1877  				return errors.Wrapf(err, "ProcessBlock: Problem calling PutBlock")
  1878  			}
  1879  
  1880  			// Store the new block's node in our node index in the db under the
  1881  			//   <height uin32, blockhash BlockHash> -> <node info>
  1882  			// index.
  1883  			if err := PutHeightHashToNodeInfoWithTxn(txn, nodeToValidate, false /*bitcoinNodes*/); err != nil {
  1884  				return errors.Wrapf(err, "ProcessBlock: Problem calling PutHeightHashToNodeInfo before validation")
  1885  			}
  1886  
  1887  			return nil
  1888  		})
  1889  	}
  1890  
  1891  	if err != nil {
  1892  		return false, false, errors.Wrapf(err, "ProcessBlock: Problem storing block after basic validation")
  1893  	}
  1894  
  1895  	// Now we try and add the block to the main block chain (note that it should
  1896  	// already be on the main header chain if we've made it this far).
  1897  
  1898  	// Get the current tip.
  1899  	currentTip := bc.blockTip()
  1900  
  1901  	// See if the current tip is equal to the block's parent.
  1902  	isMainChain := false
  1903  
  1904  	if *parentNode.Hash == *currentTip.Hash {
  1905  		// Create a new UtxoView representing the current tip.
  1906  		//
  1907  		// TODO: An optimization can be made here where we pre-load all the inputs this txn
  1908  		// requires into the view before-hand. This basically requires two passes over
  1909  		// the txns to account for txns that spend previous txns in the block, but it would
  1910  		// almost certainly be more efficient than doing a separate db call for each input
  1911  		// and output.
  1912  		utxoView, err := NewUtxoView(bc.db, bc.params, bc.postgres)
  1913  		if err != nil {
  1914  			return false, false, errors.Wrapf(err, "ProcessBlock: Problem initializing UtxoView in simple connect to tip")
  1915  		}
  1916  
  1917  		// Preload the view with almost all of the data it will need to connect the block
  1918  		err = utxoView.Preload(desoBlock)
  1919  		if err != nil {
  1920  			glog.Errorf("ProcessBlock: Problem preloading the view: %v", err)
  1921  		}
  1922  
  1923  		// Verify that the utxo view is pointing to the current tip.
  1924  		if *utxoView.TipHash != *currentTip.Hash {
  1925  			//return false, false, fmt.Errorf("ProcessBlock: Tip hash for utxo view (%v) is "+
  1926  			//	"not the current tip hash (%v)", utxoView.TipHash, currentTip.Hash)
  1927  			glog.Errorf("ProcessBlock: Tip hash for utxo view (%v) is "+
  1928  				"not the current tip hash (%v)", utxoView.TipHash, currentTip.Hash)
  1929  		}
  1930  
  1931  		utxoOpsForBlock, err := utxoView.ConnectBlock(desoBlock, txHashes, verifySignatures, nil)
  1932  		if err != nil {
  1933  			if IsRuleError(err) {
  1934  				// If we have a RuleError, mark the block as invalid before
  1935  				// returning.
  1936  				bc.MarkBlockInvalid(nodeToValidate, RuleError(err.Error()))
  1937  				return false, false, err
  1938  			}
  1939  
  1940  			// If the error wasn't a RuleError, return without marking the
  1941  			// block as invalid, since this means the block may benefit from
  1942  			// being reprocessed in the future, which will happen if a reorg
  1943  			// puts this block on the main chain.
  1944  			return false, false, err
  1945  		}
  1946  		// If all of the above passed it means the block is valid. So set the
  1947  		// status flag on the block to indicate that and write the status to disk.
  1948  		nodeToValidate.Status |= StatusBlockValidated
  1949  
  1950  		// Now that we have a valid block that we know is connecting to the tip,
  1951  		// update our data structures to actually make this connection. Do this
  1952  		// in a transaction so that it is atomic.
  1953  		if bc.postgres != nil {
  1954  			if err = bc.postgres.UpsertBlockAndTransactions(nodeToValidate, desoBlock); err != nil {
  1955  				return false, false, errors.Wrapf(err, "ProcessBlock: Problem upserting block and transactions")
  1956  			}
  1957  
  1958  			// Write the modified utxo set to the view.
  1959  			// FIXME: This codepath breaks the balance computation in handleBlock for Rosetta
  1960  			// because it clears the UtxoView before balances can be snapshotted.
  1961  			if err := utxoView.FlushToDb(); err != nil {
  1962  				return false, false, errors.Wrapf(err, "ProcessBlock: Problem flushing view to db")
  1963  			}
  1964  		} else {
  1965  			err = bc.db.Update(func(txn *badger.Txn) error {
  1966  				// This will update the node's status.
  1967  				if err := PutHeightHashToNodeInfoWithTxn(txn, nodeToValidate, false /*bitcoinNodes*/); err != nil {
  1968  					return errors.Wrapf(
  1969  						err, "ProcessBlock: Problem calling PutHeightHashToNodeInfo after validation")
  1970  				}
  1971  
  1972  				// Set the best node hash to this one. Note the header chain should already
  1973  				// be fully aware of this block so we shouldn't update it here.
  1974  				if err := PutBestHashWithTxn(txn, blockHash, ChainTypeDeSoBlock); err != nil {
  1975  					return err
  1976  				}
  1977  
  1978  				// Write the modified utxo set to the view.
  1979  				if err := utxoView.FlushToDbWithTxn(txn); err != nil {
  1980  					return errors.Wrapf(err, "ProcessBlock: Problem writing utxo view to db on simple add to tip")
  1981  				}
  1982  
  1983  				// Write the utxo operations for this block to the db so we can have the
  1984  				// ability to roll it back in the future.
  1985  				if err := PutUtxoOperationsForBlockWithTxn(txn, blockHash, utxoOpsForBlock); err != nil {
  1986  					return errors.Wrapf(err, "ProcessBlock: Problem writing utxo operations to db on simple add to tip")
  1987  				}
  1988  
  1989  				return nil
  1990  			})
  1991  		}
  1992  
  1993  		if err != nil {
  1994  			return false, false, errors.Wrapf(err, "ProcessBlock: Problem writing block info to db on simple add to tip")
  1995  		}
  1996  
  1997  		// Now that we've set the best chain in the db, update our in-memory data
  1998  		// structure to reflect this. Do a quick check first to make sure it's consistent.
  1999  		lastIndex := len(bc.bestChain) - 1
  2000  		bestChainHash := bc.bestChain[lastIndex].Hash
  2001  
  2002  		if *bestChainHash != *nodeToValidate.Header.PrevBlockHash {
  2003  			return false, false, fmt.Errorf("ProcessBlock: Last block in bestChain "+
  2004  				"data structure (%v) is not equal to parent hash of block being "+
  2005  				"added to tip (%v)", bestChainHash, nodeToValidate.Header.PrevBlockHash)
  2006  		}
  2007  
  2008  		// If we're syncing there's no risk of concurrency issues. Otherwise, we
  2009  		// need to make a copy in order to be save.
  2010  		if bc.isSyncing() {
  2011  			bc.bestChain = append(bc.bestChain, nodeToValidate)
  2012  			bc.bestChainMap[*nodeToValidate.Hash] = nodeToValidate
  2013  		} else {
  2014  			newBestChain, newBestChainMap := bc.CopyBestChain()
  2015  			newBestChain = append(newBestChain, nodeToValidate)
  2016  			newBestChainMap[*nodeToValidate.Hash] = nodeToValidate
  2017  			bc.bestChain, bc.bestChainMap = newBestChain, newBestChainMap
  2018  		}
  2019  
  2020  		// This node is on the main chain so set this variable.
  2021  		isMainChain = true
  2022  
  2023  		// At this point we should have the following:
  2024  		// * The block has been written to disk.
  2025  		// * The block is in our in-memory node tree data structure.
  2026  		// * The node tree has been updated on disk.
  2027  		// * The block is on our in-memory main chain data structure.
  2028  		// * The on-disk data structure should be updated too:
  2029  		//   - The best hash should now be set to this block.
  2030  		//   - The <height -> hash> index representing the main chain should be updated
  2031  		//     to have this block.
  2032  		//   - The utxo db should be updated to reflect the effects of adding this block.
  2033  		//   - The utxo operations performed for this block should also be stored so we
  2034  		//     can roll the block back in the future if needed.
  2035  
  2036  		// Notify any listeners.
  2037  		if bc.eventManager != nil {
  2038  			bc.eventManager.blockConnected(&BlockEvent{
  2039  				Block:    desoBlock,
  2040  				UtxoView: utxoView,
  2041  				UtxoOps:  utxoOpsForBlock,
  2042  			})
  2043  		}
  2044  
  2045  	} else if nodeToValidate.CumWork.Cmp(currentTip.CumWork) <= 0 {
  2046  		// A block has less cumulative work than our tip. In this case, we just ignore
  2047  		// the block for now. It is stored in our <hash -> block_data> map on disk as well
  2048  		// as in our in-memory node tree data structure (which is also stored on disk).
  2049  		// Eventually, if enough work gets added to the block, then we'll
  2050  		// add it via a reorg.
  2051  	} else {
  2052  		// In this case the block is not attached to our tip and the cumulative work
  2053  		// of the block is greater than our tip. This means we have a fork that has
  2054  		// the potential to become our new main chain so we need to do a reorg to
  2055  		// process it. A reorg consists of the following:
  2056  		// 1) Find the common ancecstor of this block and the main chain.
  2057  		// 2) Roll back all of the main chain blocks back to this common ancestor.
  2058  		// 3) Verify and add the new blocks up to this one.
  2059  		//
  2060  		// Note that if verification fails while trying to add the new blocks then
  2061  		// we will not wind up accepting the changes. For this reason all of the
  2062  		// above steps are processed using an in-memory view before writing anything
  2063  		// to the database.
  2064  
  2065  		// Find the common ancestor of this block and the main chain.
  2066  		commonAncestor, detachBlocks, attachBlocks := GetReorgBlocks(currentTip, nodeToValidate)
  2067  		// Log a warning if the reorg is going to be a big one.
  2068  		numBlocks := currentTip.Height - commonAncestor.Height
  2069  		if numBlocks > 10 {
  2070  			glog.Warningf("ProcessBlock: Proceeding with reorg of (%d) blocks from "+
  2071  				"block (%v) at height (%d) to block (%v) at height of (%d)",
  2072  				numBlocks, currentTip, currentTip.Height, nodeToValidate, nodeToValidate.Height)
  2073  		}
  2074  
  2075  		// Create an empty view referencing the current tip.
  2076  		//
  2077  		// TODO: An optimization can be made here where we pre-load all the inputs this txn
  2078  		// requires into the view before-hand. This basically requires two passes over
  2079  		// the txns to account for txns that spend previous txns in the block, but it would
  2080  		// almost certainly be more efficient than doing a separate db call for each input
  2081  		// and output
  2082  		utxoView, err := NewUtxoView(bc.db, bc.params, bc.postgres)
  2083  		if err != nil {
  2084  			return false, false, errors.Wrapf(err, "processblock: Problem initializing UtxoView in reorg")
  2085  		}
  2086  		// Verify that the utxo view is pointing to the current tip.
  2087  		if *utxoView.TipHash != *currentTip.Hash {
  2088  			return false, false, fmt.Errorf("ProcessBlock: Tip hash for utxo view (%v) is "+
  2089  				"not the current tip hash (%v)", *utxoView.TipHash, *currentTip)
  2090  		}
  2091  
  2092  		// Go through and detach all of the blocks down to the common ancestor. We
  2093  		// shouldn't encounter any errors but if we do, return without marking the
  2094  		// block as invalid.
  2095  		for _, nodeToDetach := range detachBlocks {
  2096  			// Fetch the utxo operations for the block we're detaching. We need these
  2097  			// in order to be able to detach the block.
  2098  			utxoOps, err := GetUtxoOperationsForBlock(bc.db, nodeToDetach.Hash)
  2099  			if err != nil {
  2100  				return false, false, errors.Wrapf(err, "ProcessBlock: Problem fetching "+
  2101  					"utxo operations during detachment of block (%v) "+
  2102  					"in reorg", nodeToDetach)
  2103  			}
  2104  
  2105  			// Fetch the block itself since we need some info from it to roll
  2106  			// it back.
  2107  			blockToDetach, err := GetBlock(nodeToDetach.Hash, bc.db)
  2108  			if err != nil {
  2109  				return false, false, errors.Wrapf(err, "ProcessBlock: Problem fetching "+
  2110  					"block (%v) during detach in reorg", nodeToDetach)
  2111  			}
  2112  
  2113  			// Compute the hashes for all the transactions.
  2114  			txHashes, err := ComputeTransactionHashes(blockToDetach.Txns)
  2115  			if err != nil {
  2116  				return false, false, errors.Wrapf(err, "ProcessBlock: Problem computing "+
  2117  					"transaction hashes during detachment of block (%v)", nodeToDetach)
  2118  			}
  2119  
  2120  			// Now roll the block back in the view.
  2121  			if err := utxoView.DisconnectBlock(blockToDetach, txHashes, utxoOps); err != nil {
  2122  				return false, false, errors.Wrapf(err, "ProcessBlock: Problem rolling back "+
  2123  					"block (%v) during detachment in reorg", nodeToDetach)
  2124  			}
  2125  			// Double-check that the view's hash is now at the block's parent.
  2126  			if *utxoView.TipHash != *blockToDetach.Header.PrevBlockHash {
  2127  				return false, false, fmt.Errorf("ProcessBlock: Block hash in utxo view (%v) "+
  2128  					"does not match parent block hash (%v) after executing "+
  2129  					"DisconnectBlock", utxoView.TipHash, blockToDetach.Header.PrevBlockHash)
  2130  			}
  2131  		}
  2132  
  2133  		// If we made it here, we were able to successfully detach all of the blocks
  2134  		// such that the view is now at the common ancestor. Double-check that this is
  2135  		// the case.
  2136  		if *utxoView.TipHash != *commonAncestor.Hash {
  2137  			return false, false, fmt.Errorf("ProcessBlock: Block hash in utxo view (%v) "+
  2138  				"does not match common ancestor hash (%v) after executing "+
  2139  				"DisconnectBlock", utxoView.TipHash, commonAncestor.Hash)
  2140  		}
  2141  
  2142  		// Now that the view has the common ancestor as the tip, we can try and attach
  2143  		// each new block to it to see if the reorg will work.
  2144  		//
  2145  		// Keep track of the utxo operations we get from attaching the blocks.
  2146  		utxoOpsForAttachBlocks := [][][]*UtxoOperation{}
  2147  		// Also keep track of any errors that we might have come across.
  2148  		ruleErrorsFound := []RuleError{}
  2149  		// The first element will be the node right after the common ancestor and
  2150  		// the last element will be the new node we need to attach.
  2151  		for _, attachNode := range attachBlocks {
  2152  
  2153  			// Fetch the block itself since we need some info from it to try and
  2154  			// connect it.
  2155  			blockToAttach, err := GetBlock(attachNode.Hash, bc.db)
  2156  			if err != nil {
  2157  				return false, false, errors.Wrapf(err, "ProcessBlock: Problem fetching "+
  2158  					"block (%v) during attach in reorg", attachNode)
  2159  			}
  2160  
  2161  			// If the parent node has been marked as invalid then mark this node as
  2162  			// invalid as well.
  2163  			if (attachNode.Parent.Status & StatusBlockValidateFailed) != 0 {
  2164  				bc.MarkBlockInvalid(attachNode, RuleErrorPreviousBlockInvalid)
  2165  				continue
  2166  			}
  2167  
  2168  			// Compute the tx hashes for the block since we need them to perform
  2169  			// the connection.
  2170  			txHashes, err := ComputeTransactionHashes(blockToAttach.Txns)
  2171  			if err != nil {
  2172  				return false, false, errors.Wrapf(err, "ProcessBlock: Problem computing "+
  2173  					"transaction hashes during attachment of block (%v) in reorg", blockToAttach)
  2174  			}
  2175  
  2176  			// Initialize the utxo operations slice.
  2177  			utxoOps, err := utxoView.ConnectBlock(
  2178  				blockToAttach, txHashes, verifySignatures, nil)
  2179  			if err != nil {
  2180  				if IsRuleError(err) {
  2181  					// If we have a RuleError, mark the block as invalid. But don't return
  2182  					// yet because we need to mark all of the child blocks as invalid as
  2183  					// well first.
  2184  					bc.MarkBlockInvalid(attachNode, RuleError(err.Error()))
  2185  					ruleErrorsFound = append(ruleErrorsFound, RuleError(err.Error()))
  2186  					continue
  2187  				} else {
  2188  					// If the error wasn't a RuleError, return without marking the
  2189  					// block as invalid, since this means the block may benefit from
  2190  					// being reprocessed in the future.
  2191  					return false, false, errors.Wrapf(err, "ProcessBlock: Problem trying to attach block (%v) in reorg", attachNode)
  2192  				}
  2193  			}
  2194  
  2195  			// If we made it here then we were able to connect the block successfully.
  2196  			// So mark its status as valid and update the node index accordingly.
  2197  			attachNode.Status |= StatusBlockValidated
  2198  			if err := PutHeightHashToNodeInfo(attachNode, bc.db, false /*bitcoinNodes*/); err != nil {
  2199  				return false, false, errors.Wrapf(
  2200  					err, "ProcessBlock: Problem calling PutHeightHashToNodeInfo after validation in reorg")
  2201  			}
  2202  
  2203  			// Add the utxo operations to our list.
  2204  			utxoOpsForAttachBlocks = append(utxoOpsForAttachBlocks, utxoOps)
  2205  		}
  2206  
  2207  		// At this point, either we were able to attach all of the blocks OR the block
  2208  		// we are processing is invalid (possibly due to one of its parents to being
  2209  		// invalid). Regardless, because the attach worked if and only if the block we
  2210  		// are processing is valid, it is sufficient to use this block's validity to decide
  2211  		// if we want to perform this reorg.
  2212  		//
  2213  		// Recall that newNode is the node at the tip of the new chain we're trying to
  2214  		// reorg to which is also the last node in attachBlocks.
  2215  		newTipNode := attachBlocks[len(attachBlocks)-1]
  2216  		if (newTipNode.Status & StatusBlockValidateFailed) != 0 {
  2217  			// In the case where the new tip is invalid, we encountered an error while
  2218  			// processing. Return the first error we encountered. Note we should already
  2219  			// have marked all the blocks as invalid so no need to do it here.
  2220  			return false, false, ruleErrorsFound[0]
  2221  		}
  2222  
  2223  		// If we made it this far, we know the reorg will succeed and the view contains
  2224  		// the state after applying the reorg. With this information, it is possible to
  2225  		// roll back the blocks and fast forward the db to the post-reorg state with a
  2226  		// single transaction.
  2227  		err = bc.db.Update(func(txn *badger.Txn) error {
  2228  			// Set the best node hash to the new tip.
  2229  			if err := PutBestHashWithTxn(txn, newTipNode.Hash, ChainTypeDeSoBlock); err != nil {
  2230  				return err
  2231  			}
  2232  
  2233  			for _, detachNode := range detachBlocks {
  2234  				// Delete the utxo operations for the blocks we're detaching since we don't need
  2235  				// them anymore.
  2236  				if err := DeleteUtxoOperationsForBlockWithTxn(txn, detachNode.Hash); err != nil {
  2237  					return errors.Wrapf(err, "ProcessBlock: Problem deleting utxo operations for block")
  2238  				}
  2239  
  2240  				// Note we could be even more aggressive here by deleting the nodes and
  2241  				// corresponding blocks from the db here (i.e. not storing any side chain
  2242  				// data on the db). But this seems like a minor optimization that comes at
  2243  				// the minor cost of side chains not being retained by the network as reliably.
  2244  			}
  2245  
  2246  			for ii, attachNode := range attachBlocks {
  2247  				// Add the utxo operations for the blocks we're attaching so we can roll them back
  2248  				// in the future if necessary.
  2249  				if err := PutUtxoOperationsForBlockWithTxn(txn, attachNode.Hash, utxoOpsForAttachBlocks[ii]); err != nil {
  2250  					return errors.Wrapf(err, "ProcessBlock: Problem putting utxo operations for block")
  2251  				}
  2252  			}
  2253  
  2254  			// Write the modified utxo set to the view.
  2255  			if err := utxoView.FlushToDbWithTxn(txn); err != nil {
  2256  				return errors.Wrapf(err, "ProcessBlock: Problem flushing to db")
  2257  			}
  2258  
  2259  			return nil
  2260  		})
  2261  		if err != nil {
  2262  			return false, false, errors.Errorf("ProcessBlock: Problem updating: %v", err)
  2263  		}
  2264  
  2265  		// Now the the db has been updated, update our in-memory best chain. Note that there
  2266  		// is no need to update the node index because it was updated as we went along.
  2267  		newBestChain, newBestChainMap := bc.CopyBestChain()
  2268  		newBestChain, newBestChainMap = updateBestChainInMemory(
  2269  			newBestChain, newBestChainMap, detachBlocks, attachBlocks)
  2270  		bc.bestChain, bc.bestChainMap = newBestChain, newBestChainMap
  2271  
  2272  		// If we made it here then this block is on the main chain.
  2273  		isMainChain = true
  2274  
  2275  		// Signal to the server about all the blocks that were disconnected and
  2276  		// connected as a result of this operation. Do this in a goroutine so that
  2277  		// if ProcessBlock is called by a consumer of incomingMessages we don't
  2278  		// have any risk of deadlocking.
  2279  		for _, nodeToDetach := range detachBlocks {
  2280  			// Fetch the block itself since we need some info from it to roll
  2281  			// it back.
  2282  			blockToDetach, err := GetBlock(nodeToDetach.Hash, bc.db)
  2283  			if err != nil {
  2284  				return false, false, errors.Wrapf(err, "ProcessBlock: Problem fetching "+
  2285  					"block (%v) during detach in server signal", nodeToDetach)
  2286  			}
  2287  
  2288  			// If we have a Server object then call its function
  2289  			if bc.eventManager != nil {
  2290  				// FIXME: We need to add the UtxoOps here to handle reorgs properly in Rosetta
  2291  				// For now it's fine because reorgs are virtually impossible.
  2292  				bc.eventManager.blockDisconnected(&BlockEvent{Block: blockToDetach})
  2293  			}
  2294  		}
  2295  		for _, attachNode := range attachBlocks {
  2296  
  2297  			// Fetch the block itself since we need some info from it to try and
  2298  			// connect it.
  2299  			blockToAttach, err := GetBlock(attachNode.Hash, bc.db)
  2300  			if err != nil {
  2301  				return false, false, errors.Wrapf(err, "ProcessBlock: Problem fetching "+
  2302  					"block (%v) during attach in server signal", attachNode)
  2303  			}
  2304  			// If we have a Server object then call its function
  2305  			if bc.eventManager != nil {
  2306  				// FIXME: We need to add the UtxoOps here to handle reorgs properly in Rosetta
  2307  				// For now it's fine because reorgs are virtually impossible.
  2308  				bc.eventManager.blockConnected(&BlockEvent{Block: blockToAttach})
  2309  			}
  2310  		}
  2311  
  2312  		// If we have a Server object then call its function
  2313  		// TODO: Is this duplicated / necessary?
  2314  		if bc.eventManager != nil {
  2315  			// FIXME: We need to add the UtxoOps here to handle reorgs properly in Rosetta
  2316  			// For now it's fine because reorgs are virtually impossible.
  2317  			bc.eventManager.blockConnected(&BlockEvent{Block: desoBlock})
  2318  		}
  2319  	}
  2320  
  2321  	// If we've made it this far, the block has been validated and we have either added
  2322  	// the block to the tip, done nothing with it (because its cumwork isn't high enough)
  2323  	// or added it via a reorg and the db and our in-memory data structures reflect this
  2324  	// change.
  2325  	//
  2326  	// Now that we've done all of the above, we need to signal to the server that we've
  2327  	// accepted the block
  2328  
  2329  	// Signal the server that we've accepted this block in some way.
  2330  	if bc.eventManager != nil {
  2331  		bc.eventManager.blockAccepted(&BlockEvent{Block: desoBlock})
  2332  	}
  2333  
  2334  	// At this point, the block we were processing originally should have been added
  2335  	// to our data structures and any unconnectedTxns that are no longer unconnectedTxns should have
  2336  	// also been processed.
  2337  	return isMainChain, false, nil
  2338  }
  2339  
  2340  // ValidateTransaction creates a UtxoView and sees if the transaction can be connected
  2341  // to it. If a mempool is provided, this function tries to find dependencies of the
  2342  // passed-in transaction in the pool and connect them before trying to connect the
  2343  // passed-in transaction.
  2344  func (bc *Blockchain) ValidateTransaction(
  2345  	txnMsg *MsgDeSoTxn, blockHeight uint32, verifySignatures bool, mempool *DeSoMempool) error {
  2346  
  2347  	// Create a new UtxoView. If we have access to a mempool object, use it to
  2348  	// get an augmented view that factors in pending transactions.
  2349  	utxoView, err := NewUtxoView(bc.db, bc.params, bc.postgres)
  2350  	if err != nil {
  2351  		return errors.Wrapf(err, "ValidateTransaction: Problem Problem creating new utxo view: ")
  2352  	}
  2353  	if mempool != nil {
  2354  		utxoView, err = mempool.GetAugmentedUtxoViewForPublicKey(txnMsg.PublicKey, txnMsg)
  2355  		if err != nil {
  2356  			return errors.Wrapf(err, "ValidateTransaction: Problem getting augmented UtxoView from mempool: ")
  2357  		}
  2358  	}
  2359  
  2360  	// Hash the transaction.
  2361  	txHash := txnMsg.Hash()
  2362  	txnBytes, err := txnMsg.ToBytes(false)
  2363  	if err != nil {
  2364  		return errors.Wrapf(err, "ValidateTransaction: Error serializing txn: %v", err)
  2365  	}
  2366  	txnSize := int64(len(txnBytes))
  2367  	// We don't care about the utxoOps or the fee it returns.
  2368  	_, _, _, _, err = utxoView._connectTransaction(
  2369  		txnMsg,
  2370  		txHash,
  2371  		txnSize,
  2372  		blockHeight,
  2373  		verifySignatures,
  2374  		false, /*ignoreUtxos*/
  2375  	)
  2376  	if err != nil {
  2377  		return errors.Wrapf(err, "ValidateTransaction: Problem validating transaction: ")
  2378  	}
  2379  
  2380  	return nil
  2381  }
  2382  
  2383  var (
  2384  	maxHash = BlockHash{
  2385  		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  2386  		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  2387  		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  2388  		0xff, 0xff}
  2389  	maxHashBigint = HashToBigint(&maxHash)
  2390  	bigOneInt     = big.NewInt(1)
  2391  )
  2392  
  2393  // The number of hashing attempts in expectation it would take to produce the
  2394  // hash passed in. This is computed as:
  2395  //    E(min(X_i, ..., X_n)) where:
  2396  //    - n = (number of attempted hashes) and
  2397  //    - the X_i are all U(0, MAX_HASH)
  2398  // -> E(min(X_i, ..., X_n)) = MAX_HASH / (n + 1)
  2399  // -> E(n) ~= MAX_HASH / min_hash - 1
  2400  //    - where min_hash is the block hash
  2401  //
  2402  // We approximate this as MAX_HASH / (min_hash + 1), adding 1 to min_hash in
  2403  // order to mitigate the possibility of a divide-by-zero error.
  2404  //
  2405  // The value returned is the expected number of hashes performed to produce
  2406  // the input hash formatted as a big-endian big integer that uses the
  2407  // BlockHash type for convenience (though it is likely to be much lower
  2408  // in terms of magnitude than a typical BlockHash object).
  2409  func ExpectedWorkForBlockHash(hash *BlockHash) *BlockHash {
  2410  	hashBigint := HashToBigint(hash)
  2411  	ratioBigint := new(big.Int)
  2412  	ratioBigint.Div(maxHashBigint, hashBigint.Add(hashBigint, bigOneInt))
  2413  	return BigintToHash(ratioBigint)
  2414  }
  2415  
  2416  func ComputeTransactionHashes(txns []*MsgDeSoTxn) ([]*BlockHash, error) {
  2417  	txHashes := make([]*BlockHash, len(txns))
  2418  
  2419  	for ii, currentTxn := range txns {
  2420  		txHashes[ii] = currentTxn.Hash()
  2421  	}
  2422  
  2423  	return txHashes, nil
  2424  }
  2425  
  2426  func ComputeMerkleRoot(txns []*MsgDeSoTxn) (_merkle *BlockHash, _txHashes []*BlockHash, _err error) {
  2427  	if len(txns) == 0 {
  2428  		return nil, nil, fmt.Errorf("ComputeMerkleRoot: Block must contain at least one txn")
  2429  	}
  2430  
  2431  	// Compute the hashes of all the transactions.
  2432  	hashes := [][]byte{}
  2433  	for _, txn := range txns {
  2434  		txHash := txn.Hash()
  2435  		hashes = append(hashes, txHash[:])
  2436  	}
  2437  
  2438  	merkleTree := merkletree.NewTreeFromHashes(merkletree.Sha256DoubleHash, hashes)
  2439  
  2440  	rootHash := &BlockHash{}
  2441  	copy(rootHash[:], merkleTree.Root.GetHash()[:])
  2442  
  2443  	txHashes := []*BlockHash{}
  2444  	for _, leafNode := range merkleTree.Rows[0] {
  2445  		currentHash := &BlockHash{}
  2446  		copy(currentHash[:], leafNode.GetHash())
  2447  		txHashes = append(txHashes, currentHash)
  2448  	}
  2449  
  2450  	return rootHash, txHashes, nil
  2451  }
  2452  
  2453  func (bc *Blockchain) GetSpendableUtxosForPublicKey(spendPublicKeyBytes []byte, mempool *DeSoMempool, referenceUtxoView *UtxoView) ([]*UtxoEntry, error) {
  2454  	// If we have access to a mempool, use it to account for utxos we might not
  2455  	// get otherwise.
  2456  	utxoView, err := NewUtxoView(bc.db, bc.params, bc.postgres)
  2457  	if err != nil {
  2458  		return nil, errors.Wrapf(err, "Blockchain.GetSpendableUtxosForPublicKey: Problem initializing UtxoView: ")
  2459  	}
  2460  	// Use the reference UtxoView if provided. Otherwise try to get one from the mempool.
  2461  	// This improves efficiency when we have a UtxoView already handy.
  2462  	if referenceUtxoView != nil {
  2463  		utxoView = referenceUtxoView
  2464  	} else {
  2465  		if mempool != nil {
  2466  			utxoView, err = mempool.GetAugmentedUtxoViewForPublicKey(spendPublicKeyBytes, nil)
  2467  			if err != nil {
  2468  				return nil, errors.Wrapf(err, "Blockchain.GetSpendableUtxosForPublicKey: Problem getting augmented UtxoView from mempool: ")
  2469  			}
  2470  		}
  2471  	}
  2472  
  2473  	// Get unspent utxos from the view.
  2474  	utxoEntriesFound, err := utxoView.GetUnspentUtxoEntrysForPublicKey(spendPublicKeyBytes)
  2475  	if err != nil {
  2476  		return nil, errors.Wrapf(err, "Blockchain.GetSpendableUtxosForPublicKey: Problem getting spendable utxos from UtxoView: ")
  2477  	}
  2478  
  2479  	// Sort the UTXOs putting the smallest amounts first.
  2480  	//
  2481  	// TODO: There has generally been a lot of discussion and thought about
  2482  	// what the optimal coin selection algorithm should be over the years.
  2483  	// Here, we choose to keep things simple and just use the smallest UTXOs
  2484  	// first. It has its drawbacks and we should revisit it at some point,
  2485  	// but for now it seems like it should be fine, and the reduction of the
  2486  	// size of the UTXO set seems like a reasonable benefit of using it. See below
  2487  	// for more discussion:
  2488  	// https://bitcoin.stackexchange.com/questions/32145/what-are-the-trade-offs-between-the-different-algorithms-for-deciding-which-utxo
  2489  	sort.Slice(utxoEntriesFound, func(ii, jj int) bool {
  2490  		return utxoEntriesFound[ii].AmountNanos < utxoEntriesFound[jj].AmountNanos
  2491  	})
  2492  
  2493  	// Add UtxoEntrys to our list filtering out ones that aren't valid for various
  2494  	// reasons.
  2495  	spendableUtxoEntries := []*UtxoEntry{}
  2496  	for _, utxoEntry := range utxoEntriesFound {
  2497  		// If the utxo is an immature block reward, skip it. Use the block chain height
  2498  		// not the header chain height since the transaction will need to be validated
  2499  		// against existing transactions which are present only if we have blocks.
  2500  		//
  2501  		// Note we add one to the current block height since it is presumed this
  2502  		// transaction will at best be mined into the next block.
  2503  		blockHeight := bc.blockTip().Height + 1
  2504  		if _isEntryImmatureBlockReward(utxoEntry, blockHeight, bc.params) {
  2505  			continue
  2506  		}
  2507  
  2508  		// Don't consider utxos that are already consumed by the mempool.
  2509  		if mempool != nil && mempool.CheckSpend(*utxoEntry.UtxoKey) != nil {
  2510  			continue
  2511  		}
  2512  
  2513  		// If we get here we know the utxo is spendable so add it to our list.
  2514  		spendableUtxoEntries = append(spendableUtxoEntries, utxoEntry)
  2515  	}
  2516  
  2517  	return spendableUtxoEntries, nil
  2518  }
  2519  
  2520  func amountEqualsAdditionalOutputs(spendAmount uint64, additionalOutputs []*DeSoOutput) error {
  2521  	expectedAdditionalOutputSum := uint64(0)
  2522  	for _, output := range additionalOutputs {
  2523  		expectedAdditionalOutputSum += output.AmountNanos
  2524  	}
  2525  	if spendAmount != expectedAdditionalOutputSum {
  2526  		return fmt.Errorf("expected spendAmount to be %d, instead got %d", expectedAdditionalOutputSum, spendAmount)
  2527  	}
  2528  	return nil
  2529  }
  2530  
  2531  // Define a helper function for computing the upper bound of the size
  2532  // of a transaction and associated fees. This basically serializes the
  2533  // transaction without the signature and then accounts for the maximum possible
  2534  // size the signature could be.
  2535  func _computeMaxTxSize(_tx *MsgDeSoTxn) uint64 {
  2536  	// Compute the size of the transaction without the signature.
  2537  	txBytesNoSignature, _ := _tx.ToBytes(true /*preSignature*/)
  2538  	// Return the size the transaction would be if the signature had its
  2539  	// absolute maximum length.
  2540  
  2541  	// MaxDERSigLen is the maximum size that a DER signature can be.
  2542  	//
  2543  	// Note: I am pretty sure the true maximum is 71. But since this value is
  2544  	// dependent on the size of R and S, and since it's generally used for
  2545  	// safety purposes (e.g. ensuring that enough space has been allocated),
  2546  	// it seems better to pad it a bit and stay on the safe side. You can see
  2547  	// some discussion on getting to this number here:
  2548  	// https://bitcoin.stackexchange.com/questions/77191/what-is-the-maximum-size-of-a-der-encoded-ecdsa-signature
  2549  	const MaxDERSigLen = 74
  2550  
  2551  	return uint64(len(txBytesNoSignature)) + MaxDERSigLen
  2552  }
  2553  
  2554  // A helper for computing the max fee given a txn. Assumes the longest signature
  2555  // length.
  2556  func _computeMaxTxFee(_tx *MsgDeSoTxn, minFeeRateNanosPerKB uint64) uint64 {
  2557  	maxSizeBytes := _computeMaxTxSize(_tx)
  2558  	return maxSizeBytes * minFeeRateNanosPerKB / 1000
  2559  }
  2560  
  2561  func (bc *Blockchain) CreatePrivateMessageTxn(
  2562  	senderPublicKey []byte, recipientPublicKey []byte,
  2563  	unencryptedMessageText string, encryptedMessageText string,
  2564  	tstampNanos uint64,
  2565  	minFeeRateNanosPerKB uint64, mempool *DeSoMempool, additionalOutputs []*DeSoOutput) (
  2566  	_txn *MsgDeSoTxn, _totalInput uint64, _changeAmount uint64, _fees uint64, _err error) {
  2567  
  2568  	var encryptedMessageBytes []byte
  2569  	messageExtraData := make(map[string][]byte)
  2570  
  2571  	if encryptedMessageText == "" {
  2572  		// Encrypt the passed-in message text with the recipient's public key.
  2573  		//
  2574  		// Parse the recipient public key.
  2575  		recipientPk, err := btcec.ParsePubKey(recipientPublicKey, btcec.S256())
  2576  		if err != nil {
  2577  			return nil, 0, 0, 0, errors.Wrapf(err, "CreatePrivateMessageTxn: Problem parsing "+
  2578  				"recipient public key: ")
  2579  		}
  2580  		encryptedMessageBytes, err = EncryptBytesWithPublicKey(
  2581  			[]byte(unencryptedMessageText), recipientPk.ToECDSA())
  2582  		if err != nil {
  2583  			return nil, 0, 0, 0, errors.Wrapf(err, "CreatePrivateMessageTxn: Problem "+
  2584  				"encrypting message text to hex: ")
  2585  		}
  2586  
  2587  		// Add {V : 1} version field to ExtraData to indicate we are
  2588  		// encrypting using legacy public key method.
  2589  		messageExtraData["V"] = UintToBuf(1)
  2590  	} else {
  2591  		var err error
  2592  		// Message is already encrypted, so just decode it to hex format
  2593  		encryptedMessageBytes, err = hex.DecodeString(encryptedMessageText)
  2594  		if err != nil {
  2595  			return nil, 0, 0, 0, errors.Wrapf(err, "CreatePrivateMessageTxn: Problem "+
  2596  				"decoding message text to hex: ")
  2597  		}
  2598  
  2599  		// Add {V : 2} version field to ExtraData to indicate we are
  2600  		// encrypting using shared secret.
  2601  		messageExtraData["V"] = UintToBuf(2)
  2602  	}
  2603  
  2604  	// Don't allow encryptedMessageBytes to be nil.
  2605  	if len(encryptedMessageBytes) == 0 {
  2606  		encryptedMessageBytes = []byte{}
  2607  	}
  2608  
  2609  	// Create a transaction containing the encrypted message text.
  2610  	// A PrivateMessage transaction doesn't need any inputs or outputs (except additionalOutputs provided).
  2611  	txn := &MsgDeSoTxn{
  2612  		PublicKey: senderPublicKey,
  2613  		TxnMeta: &PrivateMessageMetadata{
  2614  			RecipientPublicKey: recipientPublicKey,
  2615  			EncryptedText:      encryptedMessageBytes,
  2616  			TimestampNanos:     tstampNanos,
  2617  		},
  2618  		ExtraData: messageExtraData,
  2619  		TxOutputs: additionalOutputs,
  2620  
  2621  		// We wait to compute the signature until we've added all the
  2622  		// inputs and change.
  2623  	}
  2624  
  2625  	totalInput, spendAmount, changeAmount, fees, err :=
  2626  		bc.AddInputsAndChangeToTransaction(txn, minFeeRateNanosPerKB, mempool)
  2627  	if err != nil {
  2628  		return nil, 0, 0, 0, errors.Wrapf(err, "CreatePrivateMessageTxn: Problem adding inputs: ")
  2629  	}
  2630  
  2631  	// Sanity-check that the spendAmount is zero.
  2632  	if err = amountEqualsAdditionalOutputs(spendAmount, additionalOutputs); err != nil {
  2633  		return nil, 0, 0, 0, fmt.Errorf("CreatePrivateMessageTxn: %v", err)
  2634  	}
  2635  
  2636  	return txn, totalInput, changeAmount, fees, nil
  2637  }
  2638  
  2639  func (bc *Blockchain) CreateLikeTxn(
  2640  	userPublicKey []byte, likedPostHash BlockHash, isUnlike bool,
  2641  	minFeeRateNanosPerKB uint64, mempool *DeSoMempool, additionalOutputs []*DeSoOutput) (
  2642  	_txn *MsgDeSoTxn, _totalInput uint64, _changeAmount uint64, _fees uint64,
  2643  	_err error) {
  2644  
  2645  	// A Like transaction doesn't need any inputs or outputs (except additionalOutputs provided).
  2646  	txn := &MsgDeSoTxn{
  2647  		PublicKey: userPublicKey,
  2648  		TxnMeta: &LikeMetadata{
  2649  			LikedPostHash: &likedPostHash,
  2650  			IsUnlike:      isUnlike,
  2651  		},
  2652  		TxOutputs: additionalOutputs,
  2653  		// We wait to compute the signature until we've added all the
  2654  		// inputs and change.
  2655  	}
  2656  
  2657  	totalInput, spendAmount, changeAmount, fees, err :=
  2658  		bc.AddInputsAndChangeToTransaction(txn, minFeeRateNanosPerKB, mempool)
  2659  	if err != nil {
  2660  		return nil, 0, 0, 0, errors.Wrapf(
  2661  			err, "CreateLikeTxn: Problem adding inputs: ")
  2662  	}
  2663  
  2664  	// Sanity-check that the spendAmount is zero.
  2665  	if err = amountEqualsAdditionalOutputs(spendAmount, additionalOutputs); err != nil {
  2666  		return nil, 0, 0, 0, fmt.Errorf("CreateLikeTxn: %v", err)
  2667  	}
  2668  
  2669  	return txn, totalInput, changeAmount, fees, nil
  2670  }
  2671  
  2672  func (bc *Blockchain) CreateFollowTxn(
  2673  	senderPublicKey []byte, followedPublicKey []byte, isUnfollow bool,
  2674  	minFeeRateNanosPerKB uint64, mempool *DeSoMempool, additionalOutputs []*DeSoOutput) (
  2675  	_txn *MsgDeSoTxn, _totalInput uint64, _changeAmount uint64, _fees uint64,
  2676  	_err error) {
  2677  
  2678  	// A Follow transaction doesn't need any inputs or outputs (except additionalOutputs provided).
  2679  	txn := &MsgDeSoTxn{
  2680  		PublicKey: senderPublicKey,
  2681  		TxnMeta: &FollowMetadata{
  2682  			FollowedPublicKey: followedPublicKey,
  2683  			IsUnfollow:        isUnfollow,
  2684  		},
  2685  		TxOutputs: additionalOutputs,
  2686  		// We wait to compute the signature until we've added all the
  2687  		// inputs and change.
  2688  	}
  2689  
  2690  	totalInput, spendAmount, changeAmount, fees, err :=
  2691  		bc.AddInputsAndChangeToTransaction(txn, minFeeRateNanosPerKB, mempool)
  2692  	if err != nil {
  2693  		return nil, 0, 0, 0, errors.Wrapf(
  2694  			err, "CreateFollowTxn: Problem adding inputs: ")
  2695  	}
  2696  
  2697  	// Sanity-check that the spendAmount is zero.
  2698  	if err = amountEqualsAdditionalOutputs(spendAmount, additionalOutputs); err != nil {
  2699  		return nil, 0, 0, 0, fmt.Errorf("CreateFollowTxn: %v", err)
  2700  	}
  2701  
  2702  	return txn, totalInput, changeAmount, fees, nil
  2703  }
  2704  
  2705  func (bc *Blockchain) CreateUpdateGlobalParamsTxn(updaterPublicKey []byte,
  2706  	usdCentsPerBitcoin int64,
  2707  	createProfileFeesNanos int64,
  2708  	createNFTFeesNanos int64,
  2709  	maxCopiesPerNFT int64,
  2710  	minimumNetworkFeeNanosPerKb int64,
  2711  	forbiddenPubKey []byte,
  2712  	// Standard transaction fields
  2713  	minFeeRateNanosPerKB uint64, mempool *DeSoMempool, additionalOutputs []*DeSoOutput) (
  2714  	_txn *MsgDeSoTxn, _totalInput uint64, _changeAmount uint64, _fees uint64, _err error) {
  2715  
  2716  	// Set RepostedPostHash and IsQuotedRepost on the extra data map as necessary to track reposting.
  2717  	extraData := make(map[string][]byte)
  2718  	if usdCentsPerBitcoin >= 0 {
  2719  		extraData[USDCentsPerBitcoinKey] = UintToBuf(uint64(usdCentsPerBitcoin))
  2720  	}
  2721  	if createProfileFeesNanos >= 0 {
  2722  		extraData[CreateProfileFeeNanosKey] = UintToBuf(uint64(createProfileFeesNanos))
  2723  	}
  2724  	if createNFTFeesNanos >= 0 {
  2725  		extraData[CreateNFTFeeNanosKey] = UintToBuf(uint64(createNFTFeesNanos))
  2726  	}
  2727  	if maxCopiesPerNFT >= 0 {
  2728  		extraData[MaxCopiesPerNFTKey] = UintToBuf(uint64(maxCopiesPerNFT))
  2729  	}
  2730  	if minimumNetworkFeeNanosPerKb >= 0 {
  2731  		extraData[MinNetworkFeeNanosPerKBKey] = UintToBuf(uint64(minimumNetworkFeeNanosPerKb))
  2732  	}
  2733  	if len(forbiddenPubKey) > 0 {
  2734  		extraData[ForbiddenBlockSignaturePubKeyKey] = forbiddenPubKey
  2735  	}
  2736  
  2737  	txn := &MsgDeSoTxn{
  2738  		PublicKey: updaterPublicKey,
  2739  		TxnMeta:   &UpdateGlobalParamsMetadata{},
  2740  		ExtraData: extraData,
  2741  		TxOutputs: additionalOutputs,
  2742  	}
  2743  
  2744  	// We don't need to make any tweaks to the amount because it's basically
  2745  	// a standard "pay per kilobyte" transaction.
  2746  	totalInput, spendAmount, changeAmount, fees, err :=
  2747  		bc.AddInputsAndChangeToTransaction(txn, minFeeRateNanosPerKB, mempool)
  2748  	if err != nil {
  2749  		return nil, 0, 0, 0, errors.Wrapf(err, "CreateUpdateGlobalParamsTxn: Problem adding inputs: ")
  2750  	}
  2751  
  2752  	// The spend amount should be zero for these txns.
  2753  	if err = amountEqualsAdditionalOutputs(spendAmount, additionalOutputs); err != nil {
  2754  		return nil, 0, 0, 0, fmt.Errorf("CreateUpdateGlobalParamsTxn %v", err)
  2755  	}
  2756  
  2757  	return txn, totalInput, changeAmount, fees, nil
  2758  }
  2759  
  2760  func (bc *Blockchain) CreateUpdateBitcoinUSDExchangeRateTxn(
  2761  	// Exchange rate update fields
  2762  	updaterPublicKey []byte,
  2763  	usdCentsPerbitcoin uint64,
  2764  	// Standard transaction fields
  2765  	minFeeRateNanosPerKB uint64, mempool *DeSoMempool, additionalOutputs []*DeSoOutput) (
  2766  	_txn *MsgDeSoTxn, _totalInput uint64, _changeAmount uint64, _fees uint64, _err error) {
  2767  
  2768  	// Create a transaction containing the UpdateBitcoinUSDExchangeRate fields.
  2769  	txn := &MsgDeSoTxn{
  2770  		PublicKey: updaterPublicKey,
  2771  		TxnMeta: &UpdateBitcoinUSDExchangeRateMetadataa{
  2772  			USDCentsPerBitcoin: usdCentsPerbitcoin,
  2773  		},
  2774  		TxOutputs: additionalOutputs,
  2775  		// We wait to compute the signature until we've added all the
  2776  		// inputs and change.
  2777  	}
  2778  
  2779  	// We don't need to make any tweaks to the amount because it's basically
  2780  	// a standard "pay per kilobyte" transaction.
  2781  	totalInput, spendAmount, changeAmount, fees, err :=
  2782  		bc.AddInputsAndChangeToTransaction(txn, minFeeRateNanosPerKB, mempool)
  2783  	if err != nil {
  2784  		return nil, 0, 0, 0, errors.Wrapf(err, "CreateUpdateBitcoinUSDExchangeRateTxn: Problem adding inputs: ")
  2785  	}
  2786  
  2787  	// The spend amount should be zero for these txns.
  2788  	if err = amountEqualsAdditionalOutputs(spendAmount, additionalOutputs); err != nil {
  2789  		return nil, 0, 0, 0, fmt.Errorf("CreateUpdateBitcoinUSDExchangeRateTxn: %v", err)
  2790  	}
  2791  
  2792  	return txn, totalInput, changeAmount, fees, nil
  2793  }
  2794  
  2795  func (bc *Blockchain) CreateSubmitPostTxn(
  2796  	// Post fields
  2797  	updaterPublicKey []byte,
  2798  	postHashToModify []byte,
  2799  	parentStakeID []byte,
  2800  	body []byte,
  2801  	repostPostHashBytes []byte,
  2802  	isQuotedRepost bool,
  2803  	tstampNanos uint64,
  2804  	postExtraData map[string][]byte,
  2805  	isHidden bool,
  2806  	// Standard transaction fields
  2807  	minFeeRateNanosPerKB uint64, mempool *DeSoMempool, additionalOutputs []*DeSoOutput) (
  2808  	_txn *MsgDeSoTxn, _totalInput uint64, _changeAmount uint64, _fees uint64, _err error) {
  2809  
  2810  	// Initialize txnExtraData to postExtraData.
  2811  	txnExtraData := postExtraData
  2812  	// Remove consensus level attributes from TxnExtraData if they exist.  The consensus logic will set them correctly.
  2813  	for _, key := range PostExtraDataConsensusKeys {
  2814  		delete(txnExtraData, key)
  2815  	}
  2816  
  2817  	// Set RepostedPostHash and IsQuotedRepost on the extra data map as necessary to track reposting.
  2818  	if len(repostPostHashBytes) > 0 {
  2819  		txnExtraData[RepostedPostHash] = repostPostHashBytes
  2820  		if isQuotedRepost {
  2821  			txnExtraData[IsQuotedRepostKey] = QuotedRepostVal
  2822  		} else {
  2823  			txnExtraData[IsQuotedRepostKey] = NotQuotedRepostVal
  2824  		}
  2825  	}
  2826  
  2827  	// Create a transaction containing the post fields.
  2828  	txn := &MsgDeSoTxn{
  2829  		PublicKey: updaterPublicKey,
  2830  		TxnMeta: &SubmitPostMetadata{
  2831  			PostHashToModify:         postHashToModify,
  2832  			ParentStakeID:            parentStakeID,
  2833  			Body:                     body,
  2834  			CreatorBasisPoints:       10 * 100,
  2835  			StakeMultipleBasisPoints: 1.25 * 100 * 100,
  2836  			TimestampNanos:           tstampNanos,
  2837  			IsHidden:                 isHidden,
  2838  		},
  2839  		TxOutputs: additionalOutputs,
  2840  		// We wait to compute the signature until we've added all the
  2841  		// inputs and change.
  2842  	}
  2843  	// Only set transaction's ExtraData if there is at least one key in the extra data map.
  2844  	if len(txnExtraData) > 0 {
  2845  		txn.ExtraData = txnExtraData
  2846  	}
  2847  
  2848  	// We don't need to make any tweaks to the amount because it's basically
  2849  	// a standard "pay per kilobyte" transaction.
  2850  	totalInput, spendAmount, changeAmount, fees, err :=
  2851  		bc.AddInputsAndChangeToTransaction(txn, minFeeRateNanosPerKB, mempool)
  2852  	if err != nil {
  2853  		return nil, 0, 0, 0, errors.Wrapf(err, "CreateSubmitPostTxn: Problem adding inputs: ")
  2854  	}
  2855  
  2856  	// The spend amount should be zero for post submissions.
  2857  	if err = amountEqualsAdditionalOutputs(spendAmount, additionalOutputs); err != nil {
  2858  		return nil, 0, 0, 0, fmt.Errorf("CreateSubmitPostTxn: %v", err)
  2859  	}
  2860  
  2861  	return txn, totalInput, changeAmount, fees, nil
  2862  }
  2863  
  2864  func (bc *Blockchain) CreateUpdateProfileTxn(
  2865  	UpdaterPublicKeyBytes []byte,
  2866  	// Optional. Only set when the owner of the profile is != to the updater.
  2867  	OptionalProfilePublicKeyBytes []byte,
  2868  	NewUsername string,
  2869  	NewDescription string,
  2870  	NewProfilePic string,
  2871  	NewCreatorBasisPoints uint64,
  2872  	NewStakeMultipleBasisPoints uint64,
  2873  	IsHidden bool,
  2874  	AdditionalFees uint64,
  2875  	// Standard transaction fields
  2876  	minFeeRateNanosPerKB uint64, mempool *DeSoMempool, additionalOutputs []*DeSoOutput) (
  2877  	_txn *MsgDeSoTxn, _totalInput uint64, _changeAmount uint64, _fees uint64, _err error) {
  2878  
  2879  	// Create a transaction containing the profile fields.
  2880  	txn := &MsgDeSoTxn{
  2881  		PublicKey: UpdaterPublicKeyBytes,
  2882  		TxnMeta: &UpdateProfileMetadata{
  2883  			ProfilePublicKey:            OptionalProfilePublicKeyBytes,
  2884  			NewUsername:                 []byte(NewUsername),
  2885  			NewDescription:              []byte(NewDescription),
  2886  			NewProfilePic:               []byte(NewProfilePic),
  2887  			NewCreatorBasisPoints:       NewCreatorBasisPoints,
  2888  			NewStakeMultipleBasisPoints: NewStakeMultipleBasisPoints,
  2889  			IsHidden:                    IsHidden,
  2890  		},
  2891  		TxOutputs: additionalOutputs,
  2892  		// We wait to compute the signature until we've added all the
  2893  		// inputs and change.
  2894  
  2895  	}
  2896  
  2897  	// We directly call AddInputsAndChangeToTransactionWithSubsidy so we can pass through the create profile fee.
  2898  	totalInput, spendAmount, changeAmount, fees, err :=
  2899  		bc.AddInputsAndChangeToTransactionWithSubsidy(txn, minFeeRateNanosPerKB, 0, mempool, AdditionalFees)
  2900  	if err != nil {
  2901  		return nil, 0, 0, 0, errors.Wrapf(err, "CreateUpdateProfileTxn: Problem adding inputs: ")
  2902  	}
  2903  
  2904  	// The spend amount should equal to the additional fees for profile submissions.
  2905  	if err = amountEqualsAdditionalOutputs(spendAmount-AdditionalFees, additionalOutputs); err != nil {
  2906  		return nil, 0, 0, 0, fmt.Errorf("CreateUpdateProfileTxn: %v", err)
  2907  	}
  2908  
  2909  	return txn, totalInput, changeAmount, fees, nil
  2910  }
  2911  
  2912  func (bc *Blockchain) CreateSwapIdentityTxn(
  2913  	UpdaterPublicKeyBytes []byte,
  2914  	FromPublicKeyBytes []byte,
  2915  	ToPublicKeyBytes []byte,
  2916  
  2917  	// Standard transaction fields
  2918  	minFeeRateNanosPerKB uint64, mempool *DeSoMempool, additionalOutputs []*DeSoOutput) (
  2919  	_txn *MsgDeSoTxn, _totalInput uint64, _changeAmount uint64, _fees uint64, _err error) {
  2920  
  2921  	// Create a transaction containing the profile fields.
  2922  	txn := &MsgDeSoTxn{
  2923  		PublicKey: UpdaterPublicKeyBytes,
  2924  		TxnMeta: &SwapIdentityMetadataa{
  2925  			FromPublicKey: FromPublicKeyBytes,
  2926  			ToPublicKey:   ToPublicKeyBytes,
  2927  		},
  2928  		TxOutputs: additionalOutputs,
  2929  		// We wait to compute the signature until we've added all the
  2930  		// inputs and change.
  2931  	}
  2932  
  2933  	// We don't need to make any tweaks to the amount because it's basically
  2934  	// a standard "pay per kilobyte" transaction.
  2935  	totalInput, spendAmount, changeAmount, fees, err :=
  2936  		bc.AddInputsAndChangeToTransaction(txn, minFeeRateNanosPerKB, mempool)
  2937  	if err != nil {
  2938  		return nil, 0, 0, 0, errors.Wrapf(err, "CreateUpdateProfileTxn: Problem adding inputs: ")
  2939  	}
  2940  
  2941  	// The spend amount should be zero for SwapIdentity txns.
  2942  	if err = amountEqualsAdditionalOutputs(spendAmount, additionalOutputs); err != nil {
  2943  		return nil, 0, 0, 0, fmt.Errorf("CreateUpdateProfileTxn: %v", err)
  2944  	}
  2945  
  2946  	return txn, totalInput, changeAmount, fees, nil
  2947  }
  2948  
  2949  func (bc *Blockchain) CreateCreatorCoinTxn(
  2950  	UpdaterPublicKey []byte,
  2951  	// See CreatorCoinMetadataa for an explanation of these fields.
  2952  	ProfilePublicKey []byte,
  2953  	OperationType CreatorCoinOperationType,
  2954  	DeSoToSellNanos uint64,
  2955  	CreatorCoinToSellNanos uint64,
  2956  	DeSoToAddNanos uint64,
  2957  	MinDeSoExpectedNanos uint64,
  2958  	MinCreatorCoinExpectedNanos uint64,
  2959  	// Standard transaction fields
  2960  	minFeeRateNanosPerKB uint64, mempool *DeSoMempool, additionalOutputs []*DeSoOutput) (
  2961  	_txn *MsgDeSoTxn, _totalInput uint64, _changeAmount uint64, _fees uint64, _err error) {
  2962  
  2963  	// Create a transaction containing the creator coin fields.
  2964  	txn := &MsgDeSoTxn{
  2965  		PublicKey: UpdaterPublicKey,
  2966  		TxnMeta: &CreatorCoinMetadataa{
  2967  			ProfilePublicKey,
  2968  			OperationType,
  2969  			DeSoToSellNanos,
  2970  			CreatorCoinToSellNanos,
  2971  			DeSoToAddNanos,
  2972  			MinDeSoExpectedNanos,
  2973  			MinCreatorCoinExpectedNanos,
  2974  		},
  2975  		TxOutputs: additionalOutputs,
  2976  		// We wait to compute the signature until we've added all the
  2977  		// inputs and change.
  2978  	}
  2979  
  2980  	// We don't need to make any tweaks to the amount because it's basically
  2981  	// a standard "pay per kilobyte" transaction.
  2982  	totalInput, spendAmount, changeAmount, fees, err :=
  2983  		bc.AddInputsAndChangeToTransaction(
  2984  			txn, minFeeRateNanosPerKB, mempool)
  2985  	if err != nil {
  2986  		return nil, 0, 0, 0, errors.Wrapf(err, "CreateCreatorCoinTxn: Problem adding inputs: ")
  2987  	}
  2988  	_ = spendAmount
  2989  
  2990  	// We want our transaction to have at least one input, even if it all
  2991  	// goes to change. This ensures that the transaction will not be "replayable."
  2992  	if len(txn.TxInputs) == 0 {
  2993  		return nil, 0, 0, 0, fmt.Errorf("CreateCreatorCoinTxn: CreatorCoin txn " +
  2994  			"must have at least one input but had zero inputs " +
  2995  			"instead. Try increasing the fee rate.")
  2996  	}
  2997  
  2998  	return txn, totalInput, changeAmount, fees, nil
  2999  }
  3000  
  3001  func (bc *Blockchain) CreateCreatorCoinTransferTxn(
  3002  	UpdaterPublicKey []byte,
  3003  	ProfilePublicKey []byte,
  3004  	CreatorCoinToTransferNanos uint64,
  3005  	RecipientPublicKey []byte,
  3006  	// Standard transaction fields
  3007  	minFeeRateNanosPerKB uint64, mempool *DeSoMempool, additionalOutputs []*DeSoOutput) (
  3008  	_txn *MsgDeSoTxn, _totalInput uint64, _changeAmount uint64, _fees uint64, _err error) {
  3009  
  3010  	// Create a transaction containing the creator coin fields.
  3011  	txn := &MsgDeSoTxn{
  3012  		PublicKey: UpdaterPublicKey,
  3013  		TxnMeta: &CreatorCoinTransferMetadataa{
  3014  			ProfilePublicKey,
  3015  			CreatorCoinToTransferNanos,
  3016  			RecipientPublicKey,
  3017  		},
  3018  		TxOutputs: additionalOutputs,
  3019  		// We wait to compute the signature until we've added all the
  3020  		// inputs and change.
  3021  	}
  3022  
  3023  	// We don't need to make any tweaks to the amount because it's basically
  3024  	// a standard "pay per kilobyte" transaction.
  3025  	totalInput, spendAmount, changeAmount, fees, err :=
  3026  		bc.AddInputsAndChangeToTransaction(txn, minFeeRateNanosPerKB, mempool)
  3027  	if err != nil {
  3028  		return nil, 0, 0, 0, errors.Wrapf(err, "CreateCreatorCoinTransferTxn: Problem adding inputs: ")
  3029  	}
  3030  	_ = spendAmount
  3031  
  3032  	// We want our transaction to have at least one input, even if it all
  3033  	// goes to change. This ensures that the transaction will not be "replayable."
  3034  	if len(txn.TxInputs) == 0 {
  3035  		return nil, 0, 0, 0, fmt.Errorf("CreateCreatorCoinTransferTxn: CreatorCoinTransfer txn " +
  3036  			"must have at least one input but had zero inputs " +
  3037  			"instead. Try increasing the fee rate.")
  3038  	}
  3039  
  3040  	return txn, totalInput, changeAmount, fees, nil
  3041  }
  3042  
  3043  func (bc *Blockchain) CreateCreateNFTTxn(
  3044  	UpdaterPublicKey []byte,
  3045  	NFTPostHash *BlockHash,
  3046  	NumCopies uint64,
  3047  	HasUnlockable bool,
  3048  	IsForSale bool,
  3049  	MinBidAmountNanos uint64,
  3050  	NFTFee uint64,
  3051  	NFTRoyaltyToCreatorBasisPoints uint64,
  3052  	NFTRoyaltyToCoinBasisPoints uint64,
  3053  	// Standard transaction fields
  3054  	minFeeRateNanosPerKB uint64, mempool *DeSoMempool, additionalOutputs []*DeSoOutput) (
  3055  	_txn *MsgDeSoTxn, _totalInput uint64, _changeAmount uint64, _fees uint64, _err error) {
  3056  
  3057  	// Create a transaction containing the create NFT fields.
  3058  	txn := &MsgDeSoTxn{
  3059  		PublicKey: UpdaterPublicKey,
  3060  		TxnMeta: &CreateNFTMetadata{
  3061  			NFTPostHash,
  3062  			NumCopies,
  3063  			HasUnlockable,
  3064  			IsForSale,
  3065  			MinBidAmountNanos,
  3066  			NFTRoyaltyToCreatorBasisPoints,
  3067  			NFTRoyaltyToCoinBasisPoints,
  3068  		},
  3069  		TxOutputs: additionalOutputs,
  3070  		// We wait to compute the signature until we've added all the
  3071  		// inputs and change.
  3072  	}
  3073  
  3074  	// We directly call AddInputsAndChangeToTransactionWithSubsidy so we can pass through the NFT fee.
  3075  	totalInput, _, changeAmount, fees, err :=
  3076  		bc.AddInputsAndChangeToTransactionWithSubsidy(txn, minFeeRateNanosPerKB, 0, mempool, NFTFee)
  3077  	if err != nil {
  3078  		return nil, 0, 0, 0, errors.Wrapf(err, "CreateCreateNFTTxn: Problem adding inputs: ")
  3079  	}
  3080  
  3081  	// We want our transaction to have at least one input, even if it all
  3082  	// goes to change. This ensures that the transaction will not be "replayable."
  3083  	if len(txn.TxInputs) == 0 {
  3084  		return nil, 0, 0, 0, fmt.Errorf("CreateCreateNFTTxn: CreateNFT txn " +
  3085  			"must have at least one input but had zero inputs " +
  3086  			"instead. Try increasing the fee rate.")
  3087  	}
  3088  
  3089  	return txn, totalInput, changeAmount, fees, nil
  3090  }
  3091  
  3092  func (bc *Blockchain) CreateNFTBidTxn(
  3093  	UpdaterPublicKey []byte,
  3094  	NFTPostHash *BlockHash,
  3095  	SerialNumber uint64,
  3096  	BidAmountNanos uint64,
  3097  	// Standard transaction fields
  3098  	minFeeRateNanosPerKB uint64, mempool *DeSoMempool, additionalOutputs []*DeSoOutput) (
  3099  	_txn *MsgDeSoTxn, _totalInput uint64, _changeAmount uint64, _fees uint64, _err error) {
  3100  
  3101  	// Create a transaction containing the NFT bid fields.
  3102  	txn := &MsgDeSoTxn{
  3103  		PublicKey: UpdaterPublicKey,
  3104  		TxnMeta: &NFTBidMetadata{
  3105  			NFTPostHash,
  3106  			SerialNumber,
  3107  			BidAmountNanos,
  3108  		},
  3109  		TxOutputs: additionalOutputs,
  3110  		// We wait to compute the signature until we've added all the
  3111  		// inputs and change.
  3112  	}
  3113  
  3114  	// Add inputs and change for a standard pay per KB transaction.
  3115  	totalInput, _, changeAmount, fees, err :=
  3116  		bc.AddInputsAndChangeToTransaction(txn, minFeeRateNanosPerKB, mempool)
  3117  	if err != nil {
  3118  		return nil, 0, 0, 0, errors.Wrapf(err, "CreateNFTBidTxn: Problem adding inputs: ")
  3119  	}
  3120  
  3121  	// We want our transaction to have at least one input, even if it all
  3122  	// goes to change. This ensures that the transaction will not be "replayable."
  3123  	if len(txn.TxInputs) == 0 {
  3124  		return nil, 0, 0, 0, fmt.Errorf("CreateNFTBidTxn: NFTBid txn " +
  3125  			"must have at least one input but had zero inputs " +
  3126  			"instead. Try increasing the fee rate.")
  3127  	}
  3128  
  3129  	return txn, totalInput, changeAmount, fees, nil
  3130  }
  3131  
  3132  func (bc *Blockchain) CreateNFTTransferTxn(
  3133  	SenderPublicKey []byte,
  3134  	ReceiverPublicKey []byte,
  3135  	NFTPostHash *BlockHash,
  3136  	SerialNumber uint64,
  3137  	EncryptedUnlockableTextBytes []byte,
  3138  	// Standard transaction fields
  3139  	minFeeRateNanosPerKB uint64, mempool *DeSoMempool, additionalOutputs []*DeSoOutput) (
  3140  	_txn *MsgDeSoTxn, _totalInput uint64, _changeAmount uint64, _fees uint64, _err error) {
  3141  
  3142  	// Create a transaction containing the NFT transfer fields.
  3143  	txn := &MsgDeSoTxn{
  3144  		PublicKey: SenderPublicKey,
  3145  		TxnMeta: &NFTTransferMetadata{
  3146  			NFTPostHash,
  3147  			SerialNumber,
  3148  			ReceiverPublicKey,
  3149  			EncryptedUnlockableTextBytes,
  3150  		},
  3151  		TxOutputs: additionalOutputs,
  3152  		// We wait to compute the signature until we've added all the
  3153  		// inputs and change.
  3154  	}
  3155  
  3156  	// Add inputs and change for a standard pay per KB transaction.
  3157  	totalInput, _, changeAmount, fees, err :=
  3158  		bc.AddInputsAndChangeToTransaction(txn, minFeeRateNanosPerKB, mempool)
  3159  	if err != nil {
  3160  		return nil, 0, 0, 0, errors.Wrapf(err, "CreateNFTTransferTxn: Problem adding inputs: ")
  3161  	}
  3162  
  3163  	// We want our transaction to have at least one input, even if it all
  3164  	// goes to change. This ensures that the transaction will not be "replayable."
  3165  	if len(txn.TxInputs) == 0 {
  3166  		return nil, 0, 0, 0, fmt.Errorf("CreateNFTTransferTxn: NFTTransfer txn must have " +
  3167  			"at least one input but had zero inputs instead. Try increasing the fee rate.")
  3168  	}
  3169  
  3170  	return txn, totalInput, changeAmount, fees, nil
  3171  }
  3172  
  3173  func (bc *Blockchain) CreateAcceptNFTTransferTxn(
  3174  	UpdaterPublicKey []byte,
  3175  	NFTPostHash *BlockHash,
  3176  	SerialNumber uint64,
  3177  	// Standard transaction fields
  3178  	minFeeRateNanosPerKB uint64, mempool *DeSoMempool, additionalOutputs []*DeSoOutput) (
  3179  	_txn *MsgDeSoTxn, _totalInput uint64, _changeAmount uint64, _fees uint64, _err error) {
  3180  
  3181  	// Create a transaction containing the accept NFT transfer fields.
  3182  	txn := &MsgDeSoTxn{
  3183  		PublicKey: UpdaterPublicKey,
  3184  		TxnMeta: &AcceptNFTTransferMetadata{
  3185  			NFTPostHash,
  3186  			SerialNumber,
  3187  		},
  3188  		TxOutputs: additionalOutputs,
  3189  		// We wait to compute the signature until we've added all the
  3190  		// inputs and change.
  3191  	}
  3192  
  3193  	// Add inputs and change for a standard pay per KB transaction.
  3194  	totalInput, _, changeAmount, fees, err :=
  3195  		bc.AddInputsAndChangeToTransaction(txn, minFeeRateNanosPerKB, mempool)
  3196  	if err != nil {
  3197  		return nil, 0, 0, 0, errors.Wrapf(err,
  3198  			"CreateAcceptNFTTransferTxn: Problem adding inputs: ")
  3199  	}
  3200  
  3201  	// We want our transaction to have at least one input, even if it all
  3202  	// goes to change. This ensures that the transaction will not be "replayable."
  3203  	if len(txn.TxInputs) == 0 {
  3204  		return nil, 0, 0, 0, fmt.Errorf(
  3205  			"CreateAcceptNFTTransferTxn: AcceptNFTTransfer txn must have at least one input" +
  3206  				" but had zero inputs instead. Try increasing the fee rate.")
  3207  	}
  3208  
  3209  	return txn, totalInput, changeAmount, fees, nil
  3210  }
  3211  
  3212  func (bc *Blockchain) CreateBurnNFTTxn(
  3213  	UpdaterPublicKey []byte,
  3214  	NFTPostHash *BlockHash,
  3215  	SerialNumber uint64,
  3216  	// Standard transaction fields
  3217  	minFeeRateNanosPerKB uint64, mempool *DeSoMempool, additionalOutputs []*DeSoOutput) (
  3218  	_txn *MsgDeSoTxn, _totalInput uint64, _changeAmount uint64, _fees uint64, _err error) {
  3219  
  3220  	// Create a transaction containing the burn NFT fields.
  3221  	txn := &MsgDeSoTxn{
  3222  		PublicKey: UpdaterPublicKey,
  3223  		TxnMeta: &BurnNFTMetadata{
  3224  			NFTPostHash,
  3225  			SerialNumber,
  3226  		},
  3227  		TxOutputs: additionalOutputs,
  3228  		// We wait to compute the signature until we've added all the
  3229  		// inputs and change.
  3230  	}
  3231  
  3232  	// Add inputs and change for a standard pay per KB transaction.
  3233  	totalInput, _, changeAmount, fees, err :=
  3234  		bc.AddInputsAndChangeToTransaction(txn, minFeeRateNanosPerKB, mempool)
  3235  	if err != nil {
  3236  		return nil, 0, 0, 0, errors.Wrapf(err, "CreateBurnNFTTxn: Problem adding inputs: ")
  3237  	}
  3238  
  3239  	// We want our transaction to have at least one input, even if it all
  3240  	// goes to change. This ensures that the transaction will not be "replayable."
  3241  	if len(txn.TxInputs) == 0 {
  3242  		return nil, 0, 0, 0, fmt.Errorf("CreateBurnNFTTxn: BurnNFT txn must have at least " +
  3243  			"one input but had zero inputs instead. Try increasing the fee rate.")
  3244  	}
  3245  
  3246  	return txn, totalInput, changeAmount, fees, nil
  3247  }
  3248  
  3249  func (bc *Blockchain) CreateAcceptNFTBidTxn(
  3250  	UpdaterPublicKey []byte,
  3251  	NFTPostHash *BlockHash,
  3252  	SerialNumber uint64,
  3253  	BidderPKID *PKID,
  3254  	BidAmountNanos uint64,
  3255  	EncryptedUnlockableTextBytes []byte,
  3256  	// Standard transaction fields
  3257  	minFeeRateNanosPerKB uint64, mempool *DeSoMempool, additionalOutputs []*DeSoOutput) (
  3258  	_txn *MsgDeSoTxn, _totalInput uint64, _changeAmount uint64, _fees uint64, _err error) {
  3259  
  3260  	// Create a new UtxoView. If we have access to a mempool object, use it to
  3261  	// get an augmented view that factors in pending transactions.
  3262  	utxoView, err := NewUtxoView(bc.db, bc.params, bc.postgres)
  3263  	if err != nil {
  3264  		return nil, 0, 0, 0, errors.Wrapf(err,
  3265  			"Blockchain.CreateAcceptNFTBidTxn: Problem creating new utxo view: ")
  3266  	}
  3267  	if mempool != nil {
  3268  		utxoView, err = mempool.GetAugmentedUniversalView()
  3269  		if err != nil {
  3270  			return nil, 0, 0, 0, errors.Wrapf(err,
  3271  				"Blockchain.CreateAcceptNFTBidTxn: Problem getting augmented UtxoView from mempool: ")
  3272  		}
  3273  	}
  3274  
  3275  	// Get the spendable UtxoEntrys.
  3276  	bidderPkBytes := utxoView.GetPublicKeyForPKID(BidderPKID)
  3277  	bidderSpendableUtxos, err := bc.GetSpendableUtxosForPublicKey(bidderPkBytes, nil, utxoView)
  3278  	if err != nil {
  3279  		return nil, 0, 0, 0, errors.Wrapf(err, "Blockchain.CreateAcceptNFTBidTxn: Problem getting spendable UtxoEntrys: ")
  3280  	}
  3281  
  3282  	// Add input utxos to the transaction until we have enough total input to cover
  3283  	// the amount we want to spend plus the maximum fee (or until we've exhausted
  3284  	// all the utxos available).
  3285  	bidderInputs := []*DeSoInput{}
  3286  	totalBidderInput := uint64(0)
  3287  	for _, utxoEntry := range bidderSpendableUtxos {
  3288  
  3289  		// If the amount of input we have isn't enough to cover the bid amount, add an input and continue.
  3290  		if totalBidderInput < BidAmountNanos {
  3291  			bidderInputs = append(bidderInputs, (*DeSoInput)(utxoEntry.UtxoKey))
  3292  
  3293  			amountToAdd := utxoEntry.AmountNanos
  3294  			// For Bitcoin burns, we subtract a tiny amount of slippage to the amount we can
  3295  			// spend. This makes reorderings more forgiving.
  3296  			if utxoEntry.UtxoType == UtxoTypeBitcoinBurn {
  3297  				amountToAdd = uint64(float64(amountToAdd) * .999)
  3298  			}
  3299  
  3300  			totalBidderInput += amountToAdd
  3301  			continue
  3302  		}
  3303  
  3304  		// If we get here, we know we have enough input to cover the upper bound
  3305  		// estimate of our amount needed so break.
  3306  		break
  3307  	}
  3308  
  3309  	// If we get here and we don't have sufficient input to cover the bid, error.
  3310  	if totalBidderInput < BidAmountNanos {
  3311  		return nil, 0, 0, 0, fmt.Errorf("Blockchain.CreateAcceptNFTBidTxn: Bidder has insufficient "+
  3312  			"UTXOs (%d total) to cover BidAmountNanos %d: ", totalBidderInput, BidAmountNanos)
  3313  	}
  3314  
  3315  	// Create a transaction containing the accept nft bid fields.
  3316  	txn := &MsgDeSoTxn{
  3317  		PublicKey: UpdaterPublicKey,
  3318  		TxnMeta: &AcceptNFTBidMetadata{
  3319  			NFTPostHash,
  3320  			SerialNumber,
  3321  			BidderPKID,
  3322  			BidAmountNanos,
  3323  			EncryptedUnlockableTextBytes,
  3324  			bidderInputs,
  3325  		},
  3326  		TxOutputs: additionalOutputs,
  3327  		// We wait to compute the signature until we've added all the
  3328  		// inputs and change.
  3329  	}
  3330  
  3331  	// Add inputs and change for a standard pay per KB transaction.
  3332  	totalInput, _, changeAmount, fees, err :=
  3333  		bc.AddInputsAndChangeToTransaction(txn, minFeeRateNanosPerKB, mempool)
  3334  	if err != nil {
  3335  		return nil, 0, 0, 0, errors.Wrapf(err, "CreateAcceptNFTBidTxn: Problem adding inputs: ")
  3336  	}
  3337  
  3338  	// We want our transaction to have at least one input, even if it all
  3339  	// goes to change. This ensures that the transaction will not be "replayable."
  3340  	if len(txn.TxInputs) == 0 {
  3341  		return nil, 0, 0, 0, fmt.Errorf("CreateAcceptNFTBidTxn: AcceptNFTBid txn " +
  3342  			"must have at least one input but had zero inputs " +
  3343  			"instead. Try increasing the fee rate.")
  3344  	}
  3345  
  3346  	return txn, totalInput, changeAmount, fees, nil
  3347  }
  3348  
  3349  func (bc *Blockchain) CreateUpdateNFTTxn(
  3350  	UpdaterPublicKey []byte,
  3351  	NFTPostHash *BlockHash,
  3352  	SerialNumber uint64,
  3353  	IsForSale bool,
  3354  	MinBidAmountNanos uint64,
  3355  	// Standard transaction fields
  3356  	minFeeRateNanosPerKB uint64, mempool *DeSoMempool, additionalOutputs []*DeSoOutput) (
  3357  	_txn *MsgDeSoTxn, _totalInput uint64, _changeAmount uint64, _fees uint64, _err error) {
  3358  
  3359  	// Create a transaction containing the update NFT fields.
  3360  	txn := &MsgDeSoTxn{
  3361  		PublicKey: UpdaterPublicKey,
  3362  		TxnMeta: &UpdateNFTMetadata{
  3363  			NFTPostHash,
  3364  			SerialNumber,
  3365  			IsForSale,
  3366  			MinBidAmountNanos,
  3367  		},
  3368  		TxOutputs: additionalOutputs,
  3369  		// We wait to compute the signature until we've added all the
  3370  		// inputs and change.
  3371  	}
  3372  
  3373  	// Add inputs and change for a standard pay per KB transaction.
  3374  	totalInput, spendAmount, changeAmount, fees, err :=
  3375  		bc.AddInputsAndChangeToTransaction(txn, minFeeRateNanosPerKB, mempool)
  3376  	if err != nil {
  3377  		return nil, 0, 0, 0, errors.Wrapf(err, "CreateUpdateNFTTxn: Problem adding inputs: ")
  3378  	}
  3379  	_ = spendAmount
  3380  
  3381  	// We want our transaction to have at least one input, even if it all
  3382  	// goes to change. This ensures that the transaction will not be "replayable."
  3383  	if len(txn.TxInputs) == 0 {
  3384  		return nil, 0, 0, 0, fmt.Errorf("CreateUpdateNFTTxn: AcceptNFTBid txn " +
  3385  			"must have at least one input but had zero inputs " +
  3386  			"instead. Try increasing the fee rate.")
  3387  	}
  3388  
  3389  	return txn, totalInput, changeAmount, fees, nil
  3390  }
  3391  
  3392  // Each diamond level is worth a fixed amount of DeSo. These amounts can be changed
  3393  // in the future by simply returning a new set of values after a particular block height.
  3394  func GetDeSoNanosDiamondLevelMapAtBlockHeight(
  3395  	blockHeight int64) map[int64]uint64 {
  3396  
  3397  	return map[int64]uint64{
  3398  		1: 50000,
  3399  		2: 500000,
  3400  		3: 5000000,
  3401  		4: 50000000,
  3402  		5: 500000000,
  3403  		6: 5000000000,
  3404  		7: 50000000000,
  3405  		8: 500000000000,
  3406  	}
  3407  }
  3408  
  3409  func GetDeSoNanosForDiamondLevelAtBlockHeight(
  3410  	diamondLevel int64, blockHeight int64) uint64 {
  3411  
  3412  	// Caller is responsible for passing a valid diamond level.
  3413  	desoNanosMap := GetDeSoNanosDiamondLevelMapAtBlockHeight(blockHeight)
  3414  	desoNanosForLevel, levelExists := desoNanosMap[diamondLevel]
  3415  	if !levelExists {
  3416  		// We allow a special case for diamondLevel zero, in which case we
  3417  		// know that the value should also be zero.
  3418  		if diamondLevel != 0 {
  3419  			// If a non-existent level is requested, return zero
  3420  			glog.Errorf("GetDeSoNanosForDiamondLevelAtBlockHeight: "+
  3421  				"Diamond level %v does not exist in map %v; this should never happen",
  3422  				diamondLevel, desoNanosMap)
  3423  		}
  3424  		return 0
  3425  	}
  3426  
  3427  	return desoNanosForLevel
  3428  }
  3429  
  3430  // At a particular diamond level, a fixed amount of DeSo is converted into creator coins
  3431  // and then sent to a user. This function computes the amount of creator coins required for
  3432  // a particular level.
  3433  func GetCreatorCoinNanosForDiamondLevelAtBlockHeight(
  3434  	coinsInCirculationNanos uint64, desoLockedNanos uint64,
  3435  	diamondLevel int64, blockHeight int64, params *DeSoParams) uint64 {
  3436  
  3437  	// No creator coins are required at level zero
  3438  	if diamondLevel == 0 {
  3439  		return 0
  3440  	}
  3441  
  3442  	// First get the amount of DeSo required by this level.
  3443  	desoNanosForLevel := GetDeSoNanosForDiamondLevelAtBlockHeight(
  3444  		diamondLevel, blockHeight)
  3445  
  3446  	// Figure out the amount of creator coins to print based on the user's CoinEntry.
  3447  	return CalculateCreatorCoinToMint(
  3448  		desoNanosForLevel, coinsInCirculationNanos,
  3449  		desoLockedNanos, params)
  3450  }
  3451  
  3452  func (bc *Blockchain) CreateCreatorCoinTransferTxnWithDiamonds(
  3453  	SenderPublicKey []byte,
  3454  	ReceiverPublicKey []byte,
  3455  	DiamondPostHash *BlockHash,
  3456  	DiamondLevel int64,
  3457  	// Standard transaction fields
  3458  	minFeeRateNanosPerKB uint64, mempool *DeSoMempool, additionalOutputs []*DeSoOutput) (
  3459  	_txn *MsgDeSoTxn, _totalInput uint64, _changeAmount uint64, _fees uint64, _err error) {
  3460  
  3461  	// Create a new UtxoView. If we have access to a mempool object, use it to
  3462  	// get an augmented view that factors in pending transactions.
  3463  	utxoView, err := NewUtxoView(bc.db, bc.params, bc.postgres)
  3464  	if err != nil {
  3465  		return nil, 0, 0, 0, errors.Wrapf(err,
  3466  			"Blockchain.CreateCreatorCoinTransferTxnWithDiamonds: "+
  3467  				"Problem creating new utxo view: ")
  3468  	}
  3469  	if mempool != nil {
  3470  		utxoView, err = mempool.GetAugmentedUniversalView()
  3471  		if err != nil {
  3472  			return nil, 0, 0, 0, errors.Wrapf(err,
  3473  				"Blockchain.CreateCreatorCoinTransferTxnWithDiamonds: "+
  3474  					"Problem getting augmented UtxoView from mempool: ")
  3475  		}
  3476  	}
  3477  
  3478  	blockHeight := bc.blockTip().Height + 1
  3479  	creatorCoinToTransferNanos, _, err := utxoView.ValidateDiamondsAndGetNumCreatorCoinNanos(
  3480  		SenderPublicKey, ReceiverPublicKey, DiamondPostHash, DiamondLevel, blockHeight)
  3481  	if err != nil {
  3482  		return nil, 0, 0, 0, errors.Wrapf(
  3483  			err, "Blockchain.CreateCreatorCoinTransferTxnWithDiamonds: Problem getting creator coin nanos: ")
  3484  	}
  3485  
  3486  	// Create a transaction containing the creator coin fields.
  3487  	txn := &MsgDeSoTxn{
  3488  		PublicKey: SenderPublicKey,
  3489  		TxnMeta: &CreatorCoinTransferMetadataa{
  3490  			SenderPublicKey,
  3491  			// Buffer the creatorCoinToTransferNanos to factor in some slippage in the
  3492  			// creator coin price. Transferring more than is needed is allowed, but
  3493  			// undershooting will cause the transaction to be rejected.
  3494  			uint64(float64(creatorCoinToTransferNanos) * 1.05),
  3495  			ReceiverPublicKey,
  3496  		},
  3497  		TxOutputs: additionalOutputs,
  3498  		// We wait to compute the signature until we've added all the
  3499  		// inputs and change.
  3500  	}
  3501  
  3502  	// Make a map for the diamond extra data.
  3503  	diamondsExtraData := make(map[string][]byte)
  3504  	diamondsExtraData[DiamondLevelKey] = IntToBuf(DiamondLevel)
  3505  	diamondsExtraData[DiamondPostHashKey] = DiamondPostHash[:]
  3506  	txn.ExtraData = diamondsExtraData
  3507  
  3508  	// We don't need to make any tweaks to the amount because it's basically
  3509  	// a standard "pay per kilobyte" transaction.
  3510  	totalInput, spendAmount, changeAmount, fees, err :=
  3511  		bc.AddInputsAndChangeToTransaction(txn, minFeeRateNanosPerKB, mempool)
  3512  	if err != nil {
  3513  		return nil, 0, 0, 0, errors.Wrapf(
  3514  			err, "CreateCreatorCoinTransferTxnWithDiamonds: Problem adding inputs: ")
  3515  	}
  3516  	_ = spendAmount
  3517  
  3518  	// We want our transaction to have at least one input, even if it all
  3519  	// goes to change. This ensures that the transaction will not be "replayable."
  3520  	if len(txn.TxInputs) == 0 {
  3521  		return nil, 0, 0, 0, fmt.Errorf(
  3522  			"CreateCreatorCoinTransferTxnWithDiamonds: CreatorCoinTransfer txn must have at" +
  3523  				" least one input but had zero inputs instead. Try increasing the fee rate.")
  3524  	}
  3525  
  3526  	return txn, totalInput, changeAmount, fees, nil
  3527  }
  3528  
  3529  func (bc *Blockchain) CreateAuthorizeDerivedKeyTxn(
  3530  	ownerPublicKey []byte,
  3531  	derivedPublicKey []byte,
  3532  	expirationBlock uint64,
  3533  	accessSignature []byte,
  3534  	deleteKey bool,
  3535  	derivedKeySignature bool,
  3536  	// Standard transaction fields
  3537  	minFeeRateNanosPerKB uint64, mempool *DeSoMempool, additionalOutputs []*DeSoOutput) (
  3538  	_txn *MsgDeSoTxn, _totalInput uint64, _changeAmount uint64, _fees uint64, _err error) {
  3539  
  3540  	// Verify that the signature is valid.
  3541  	err := _verifyAccessSignature(ownerPublicKey, derivedPublicKey,
  3542  		expirationBlock, accessSignature)
  3543  	if err != nil {
  3544  		return nil, 0, 0, 0, errors.Wrapf(err,
  3545  			"Blockchain.CreateAuthorizeDerivedKeyTxn: Problem verifying access signature")
  3546  	}
  3547  
  3548  	// Check that the expiration block is valid.
  3549  	blockHeight := bc.blockTip().Height + 1
  3550  	if expirationBlock <= uint64(blockHeight) {
  3551  		return nil, 0, 0, 0, fmt.Errorf(
  3552  			"Blockchain.CreateAuthorizeDerivedKeyTxn: Expired access signature")
  3553  	}
  3554  
  3555  	// Get the appropriate operation type.
  3556  	var operationType AuthorizeDerivedKeyOperationType
  3557  	if deleteKey {
  3558  		operationType = AuthorizeDerivedKeyOperationNotValid
  3559  	} else {
  3560  		operationType = AuthorizeDerivedKeyOperationValid
  3561  	}
  3562  
  3563  	extraData := make(map[string][]byte)
  3564  	if derivedKeySignature {
  3565  		extraData[DerivedPublicKey] = derivedPublicKey
  3566  	}
  3567  
  3568  	// Create a transaction containing the authorize derived key fields.
  3569  	txn := &MsgDeSoTxn{
  3570  		PublicKey: ownerPublicKey,
  3571  		TxnMeta: &AuthorizeDerivedKeyMetadata{
  3572  			derivedPublicKey,
  3573  			expirationBlock,
  3574  			operationType,
  3575  			accessSignature,
  3576  		},
  3577  		TxOutputs: additionalOutputs,
  3578  		ExtraData: extraData,
  3579  		// We wait to compute the signature until we've added all the
  3580  		// inputs and change.
  3581  	}
  3582  
  3583  	// We don't need to make any tweaks to the amount because it's basically
  3584  	// a standard "pay per kilobyte" transaction.
  3585  	totalInput, spendAmount, changeAmount, fees, err :=
  3586  		bc.AddInputsAndChangeToTransaction(txn, minFeeRateNanosPerKB, mempool)
  3587  	if err != nil {
  3588  		return nil, 0, 0, 0, errors.Wrapf(err, "CreateAuthorizeDerivedKeyTxn: Problem adding inputs: ")
  3589  	}
  3590  
  3591  	// Sanity-check that the spendAmount is zero.
  3592  	if spendAmount != 0 {
  3593  		return nil, 0, 0, 0, fmt.Errorf("CreateAuthorizeDerivedKeyTxn: Spend amount "+
  3594  			"should be zero but was %d instead: ", spendAmount)
  3595  	}
  3596  
  3597  	return txn, totalInput, changeAmount, fees, nil
  3598  }
  3599  
  3600  func (bc *Blockchain) CreateBasicTransferTxnWithDiamonds(
  3601  	SenderPublicKey []byte,
  3602  	DiamondPostHash *BlockHash,
  3603  	DiamondLevel int64,
  3604  	// Standard transaction fields
  3605  	minFeeRateNanosPerKB uint64, mempool *DeSoMempool, additionalOutputs []*DeSoOutput) (
  3606  	_txn *MsgDeSoTxn, _totalInput uint64, _spendAmount uint64, _changeAmount uint64, _fees uint64, _err error) {
  3607  
  3608  	// Create a new UtxoView. If we have access to a mempool object, use it to
  3609  	// get an augmented view that factors in pending transactions.
  3610  	utxoView, err := NewUtxoView(bc.db, bc.params, bc.postgres)
  3611  	if err != nil {
  3612  		return nil, 0, 0, 0, 0, errors.Wrapf(err,
  3613  			"Blockchain.CreateBasicTransferTxnWithDiamonds: "+
  3614  				"Problem creating new utxo view: ")
  3615  	}
  3616  	if mempool != nil {
  3617  		utxoView, err = mempool.GetAugmentedUniversalView()
  3618  		if err != nil {
  3619  			return nil, 0, 0, 0, 0, errors.Wrapf(err,
  3620  				"Blockchain.CreateBasicTransferTxnWithDiamonds: "+
  3621  					"Problem getting augmented UtxoView from mempool: ")
  3622  		}
  3623  	}
  3624  
  3625  	// Get the post that we are trying to diamond so that we have the receiver public key.
  3626  	diamondPostEntry := utxoView.GetPostEntryForPostHash(DiamondPostHash)
  3627  	if diamondPostEntry == nil || diamondPostEntry.isDeleted {
  3628  		return nil, 0, 0, 0, 0, fmt.Errorf(
  3629  			"Blockchain.CreateBasicTransferTxnWithDiamonds: " +
  3630  				"Problem getting post entry for post hash")
  3631  	}
  3632  
  3633  	blockHeight := bc.blockTip().Height + 1
  3634  	desoToTransferNanos, _, err := utxoView.ValidateDiamondsAndGetNumDeSoNanos(
  3635  		SenderPublicKey, diamondPostEntry.PosterPublicKey, DiamondPostHash, DiamondLevel, blockHeight)
  3636  	if err != nil {
  3637  		return nil, 0, 0, 0, 0, errors.Wrapf(
  3638  			err, "Blockchain.CreateBasicTransferTxnWithDiamonds: Problem getting deso nanos: ")
  3639  	}
  3640  
  3641  	// Build the basic transfer txn.
  3642  	txn := &MsgDeSoTxn{
  3643  		PublicKey: SenderPublicKey,
  3644  		TxnMeta:   &BasicTransferMetadata{},
  3645  		TxOutputs: append(additionalOutputs, &DeSoOutput{
  3646  			PublicKey:   diamondPostEntry.PosterPublicKey,
  3647  			AmountNanos: desoToTransferNanos,
  3648  		}),
  3649  		// TxInputs and TxOutputs will be set below.
  3650  		// This function does not compute a signature.
  3651  	}
  3652  
  3653  	// Make a map for the diamond extra data and add it.
  3654  	diamondsExtraData := make(map[string][]byte)
  3655  	diamondsExtraData[DiamondLevelKey] = IntToBuf(DiamondLevel)
  3656  	diamondsExtraData[DiamondPostHashKey] = DiamondPostHash[:]
  3657  	txn.ExtraData = diamondsExtraData
  3658  
  3659  	// We don't need to make any tweaks to the amount because it's basically
  3660  	// a standard "pay per kilobyte" transaction.
  3661  	totalInput, spendAmount, changeAmount, fees, err :=
  3662  		bc.AddInputsAndChangeToTransaction(txn, minFeeRateNanosPerKB, mempool)
  3663  	if err != nil {
  3664  		return nil, 0, 0, 0, 0, errors.Wrapf(
  3665  			err, "CreateBasicTransferTxnWithDiamonds: Problem adding inputs: ")
  3666  	}
  3667  	_ = spendAmount
  3668  
  3669  	// We want our transaction to have at least one input, even if it all
  3670  	// goes to change. This ensures that the transaction will not be "replayable."
  3671  	if len(txn.TxInputs) == 0 {
  3672  		return nil, 0, 0, 0, 0, fmt.Errorf(
  3673  			"CreateBasicTransferTxnWithDiamonds: CreatorCoinTransfer txn must have at" +
  3674  				" least one input but had zero inputs instead. Try increasing the fee rate.")
  3675  	}
  3676  
  3677  	return txn, totalInput, spendAmount, changeAmount, fees, nil
  3678  }
  3679  
  3680  func (bc *Blockchain) CreateMaxSpend(
  3681  	senderPkBytes []byte, recipientPkBytes []byte, minFeeRateNanosPerKB uint64,
  3682  	mempool *DeSoMempool, additionalOutputs []*DeSoOutput) (
  3683  	_txn *MsgDeSoTxn, _totalInputAdded uint64, _spendAmount uint64, _fee uint64, _err error) {
  3684  
  3685  	txn := &MsgDeSoTxn{
  3686  		PublicKey: senderPkBytes,
  3687  		TxnMeta:   &BasicTransferMetadata{},
  3688  		// Set a single output with the maximum possible size to ensure we don't
  3689  		// underestimate the fee. Note it must be a max size output because outputs
  3690  		// are encoded as uvarints.
  3691  		TxOutputs: append(additionalOutputs, &DeSoOutput{
  3692  			PublicKey:   recipientPkBytes,
  3693  			AmountNanos: math.MaxUint64,
  3694  		}),
  3695  		// TxInputs and TxOutputs will be set below.
  3696  		// This function does not compute a signature.
  3697  	}
  3698  
  3699  	// Get the spendable UtxoEntrys.
  3700  	spendableUtxos, err := bc.GetSpendableUtxosForPublicKey(senderPkBytes, mempool, nil)
  3701  	if err != nil {
  3702  		return nil, 0, 0, 0, errors.Wrapf(err, "CreateMaxSpend: Problem getting spendable UtxoEntrys: ")
  3703  	}
  3704  
  3705  	totalInput := uint64(0)
  3706  	for _, utxoEntry := range spendableUtxos {
  3707  		amountToAdd := utxoEntry.AmountNanos
  3708  		// For Bitcoin burns, we subtract a tiny amount of slippage to the amount we can
  3709  		// spend. This makes reorderings more forgiving.
  3710  		if utxoEntry.UtxoType == UtxoTypeBitcoinBurn {
  3711  			amountToAdd = uint64(float64(amountToAdd) * .999)
  3712  		}
  3713  		totalInput += amountToAdd
  3714  		txn.TxInputs = append(txn.TxInputs, (*DeSoInput)(utxoEntry.UtxoKey))
  3715  
  3716  		// Avoid creating transactions that are ridiculously huge. Note this is smaller
  3717  		// than what AddInputsAndChangeToTransaction will allow because we want to leave
  3718  		// some breathing room to avoid this transaction getting rejected.
  3719  		currentTxnSize := _computeMaxTxSize(txn)
  3720  		if currentTxnSize > bc.params.MaxBlockSizeBytes/3 {
  3721  			if len(txn.TxInputs) > 0 {
  3722  				// Cut off the last input if the transaction just became too large.
  3723  				txn.TxInputs = txn.TxInputs[:len(txn.TxInputs)-1]
  3724  			}
  3725  			break
  3726  		}
  3727  	}
  3728  
  3729  	txnFee := _computeMaxTxFee(txn, minFeeRateNanosPerKB)
  3730  
  3731  	if totalInput < txnFee {
  3732  		return nil, 0, 0, 0, fmt.Errorf("CreateMaxSpend: Total input value %d would "+
  3733  			"be less than the fee required to spend it %d", totalInput, txnFee)
  3734  	}
  3735  
  3736  	// We have multiple outputs, the last one of which pays the receiver whatever is left after subtracting off
  3737  	// the fee. We can just set the value of the dummy output we set up earlier.
  3738  	txn.TxOutputs[len(txn.TxOutputs)-1].AmountNanos = totalInput - txnFee
  3739  
  3740  	return txn, totalInput, totalInput - txnFee, txnFee, nil
  3741  }
  3742  
  3743  // AddInputsAndChangeToTransaction fetches and adds utxos to the transaction passed
  3744  // in to meet the desired spend amount while also satisfying the desired minimum fee
  3745  // rate. Additionally, if it's worth it, this function will add a change output
  3746  // sending excess DeSo back to the spend public key. Note that the final feerate of the
  3747  // transaction after calling this function may exceed the minimum feerate requested.
  3748  // This can happen if the signature occupies fewer bytes than the expected maximum
  3749  // number of bytes or if the change output occupies fewer bytes than the expected
  3750  // maximum (though there could be other ways for this to happen).
  3751  //
  3752  // The transaction passed in should not have any inputs on it before calling this
  3753  // function (an error is returned if it does). Additionally, the output of the
  3754  // transaction passed in is assumed to be the amount the caller wishes us to find
  3755  // inputs for.
  3756  //
  3757  // An error is returned if there is not enough input associated with this
  3758  // public key to satisfy the transaction's output (subject to the minimum feerate).
  3759  func (bc *Blockchain) AddInputsAndChangeToTransaction(
  3760  	txArg *MsgDeSoTxn, minFeeRateNanosPerKB uint64, mempool *DeSoMempool) (
  3761  	_totalInputAdded uint64, _spendAmount uint64, _totalChangeAdded uint64, _fee uint64, _err error) {
  3762  
  3763  	return bc.AddInputsAndChangeToTransactionWithSubsidy(txArg, minFeeRateNanosPerKB, 0, mempool, 0)
  3764  }
  3765  
  3766  func (bc *Blockchain) AddInputsAndChangeToTransactionWithSubsidy(
  3767  	txArg *MsgDeSoTxn, minFeeRateNanosPerKB uint64, inputSubsidy uint64, mempool *DeSoMempool, additionalFees uint64) (
  3768  	_totalInputAdded uint64, _spendAmount uint64, _totalChangeAdded uint64, _fee uint64, _err error) {
  3769  
  3770  	// The transaction we're working with should never have any inputs
  3771  	// set since we'll be setting the inputs here and dealing with a case where
  3772  	// inputs are partially set before-hand would significantly complicate this
  3773  	// function. So return an error if we find any inputs.
  3774  	if len(txArg.TxInputs) > 0 {
  3775  		return 0, 0, 0, 0, fmt.Errorf("_computeInputsForTxn: Transaction passed in "+
  3776  			"txArg should not have any inputs set but found the found %d inputs",
  3777  			len(txArg.TxInputs))
  3778  	}
  3779  
  3780  	// The output of the transaction is assumed to be the desired amount the
  3781  	// caller wants to find inputs for. Start by computing it.
  3782  	spendAmount := uint64(0)
  3783  	for _, desoOutput := range txArg.TxOutputs {
  3784  		spendAmount += desoOutput.AmountNanos
  3785  	}
  3786  	// If this is a CreatorCoin buy transaction, add the amount of DeSo the
  3787  	// user wants to spend on the buy to the amount of output we're asking this
  3788  	// function to provide for us.
  3789  	if txArg.TxnMeta.GetTxnType() == TxnTypeCreatorCoin {
  3790  		txMeta := txArg.TxnMeta.(*CreatorCoinMetadataa)
  3791  		if txMeta.OperationType == CreatorCoinOperationTypeBuy {
  3792  			// If this transaction is a buy then we need enough DeSo to
  3793  			// cover the buy.
  3794  			spendAmount += txMeta.DeSoToSellNanos
  3795  		}
  3796  	}
  3797  
  3798  	// Add additional fees to the spend amount.
  3799  	spendAmount += additionalFees
  3800  	// The public key of the transaction is assumed to be the one set at its
  3801  	// top level.
  3802  	spendPublicKeyBytes := txArg.PublicKey
  3803  
  3804  	// Make a copy of the transaction. This makes it so that we don't need
  3805  	// to modify the passed-in transaction until we're absolutely sure we don't
  3806  	// have an error.
  3807  	txCopyWithChangeOutput, err := txArg.Copy()
  3808  	if err != nil {
  3809  		return 0, 0, 0, 0, errors.Wrapf(err, "AddInputsAndChangeToTransaction: ")
  3810  	}
  3811  	// Since we generally want to compute an upper bound on the transaction
  3812  	// size, add a change output to the transaction to factor in the
  3813  	// worst-case situation in which a change output is required. This
  3814  	// assignment and ones like it that follow should leave the original
  3815  	// transaction's outputs/slices unchanged.
  3816  	changeOutput := &DeSoOutput{
  3817  		PublicKey: make([]byte, btcec.PubKeyBytesLenCompressed),
  3818  		// Since we want an upper bound on the transaction size, set the amount
  3819  		// to the maximum value since that will induce the serializer to encode
  3820  		// a maximum-sized uvarint.
  3821  		AmountNanos: math.MaxUint64,
  3822  	}
  3823  	txCopyWithChangeOutput.TxOutputs = append(txCopyWithChangeOutput.TxOutputs, changeOutput)
  3824  
  3825  	// Get the spendable UtxoEntrys.
  3826  	spendableUtxos, err := bc.GetSpendableUtxosForPublicKey(spendPublicKeyBytes, mempool, nil)
  3827  	if err != nil {
  3828  		return 0, 0, 0, 0, errors.Wrapf(err, "AddInputsAndChangeToTransaction: Problem getting spendable UtxoEntrys: ")
  3829  	}
  3830  
  3831  	// Add input utxos to the transaction until we have enough total input to cover
  3832  	// the amount we want to spend plus the maximum fee (or until we've exhausted
  3833  	// all the utxos available).
  3834  	utxoEntriesBeingUsed := []*UtxoEntry{}
  3835  	totalInput := inputSubsidy
  3836  	for _, utxoEntry := range spendableUtxos {
  3837  		// As an optimization, don't worry about the fee until the total input has
  3838  		// definitively exceeded the amount we want to spend. We do this because computing
  3839  		// the fee each time we add an input would result in N^2 behavior.
  3840  		maxAmountNeeded := spendAmount
  3841  		if totalInput >= spendAmount {
  3842  			maxAmountNeeded += _computeMaxTxFee(txCopyWithChangeOutput, minFeeRateNanosPerKB)
  3843  		}
  3844  
  3845  		// If the amount of input we have isn't enough to cover our upper bound on
  3846  		// the total amount we could need, add an input and continue.
  3847  		if totalInput < maxAmountNeeded {
  3848  			txCopyWithChangeOutput.TxInputs = append(txCopyWithChangeOutput.TxInputs, (*DeSoInput)(utxoEntry.UtxoKey))
  3849  			utxoEntriesBeingUsed = append(utxoEntriesBeingUsed, utxoEntry)
  3850  
  3851  			amountToAdd := utxoEntry.AmountNanos
  3852  			// For Bitcoin burns, we subtract a tiny amount of slippage to the amount we can
  3853  			// spend. This makes reorderings more forgiving.
  3854  			if utxoEntry.UtxoType == UtxoTypeBitcoinBurn {
  3855  				amountToAdd = uint64(float64(amountToAdd) * .999)
  3856  			}
  3857  			totalInput += amountToAdd
  3858  			continue
  3859  		}
  3860  
  3861  		// If we get here, we know we have enough input to cover the upper bound
  3862  		// estimate of our amount needed so break.
  3863  		break
  3864  	}
  3865  
  3866  	// At this point, utxoEntriesBeingUsed should contain enough to cover the
  3867  	// maximum amount we'd need in a worst-case scenario (or as close as we could
  3868  	// get to that point). Now we add these utxos to a new transaction in order
  3869  	// to properly compute the change we might need.
  3870  
  3871  	// Re-copy the passed-in transaction and re-add all the inputs we deemed
  3872  	// were necessary but this time don't add a change output unless it's strictly
  3873  	// necessary.
  3874  	finalTxCopy, _ := txArg.Copy()
  3875  	for _, utxoEntry := range utxoEntriesBeingUsed {
  3876  		finalTxCopy.TxInputs = append(finalTxCopy.TxInputs, (*DeSoInput)(utxoEntry.UtxoKey))
  3877  	}
  3878  	maxFeeWithoutChange := _computeMaxTxFee(finalTxCopy, minFeeRateNanosPerKB)
  3879  	if totalInput < (spendAmount + maxFeeWithoutChange) {
  3880  		// In this case the total input we were able to gather for the
  3881  		// transaction is insufficient to cover the amount we want to
  3882  		// spend plus the fee. Return an error in this case so that
  3883  		// either the spend amount or the fee rate can be adjusted.
  3884  		return 0, 0, 0, 0, fmt.Errorf("AddInputsAndChangeToTransaction: Sanity check failed: Total "+
  3885  			"input %d is not sufficient to "+
  3886  			"cover the spend amount (=%d) plus the fee (=%d, feerate=%d, txsize=%d), "+
  3887  			"total=%d", totalInput, spendAmount, maxFeeWithoutChange, minFeeRateNanosPerKB,
  3888  			_computeMaxTxSize(finalTxCopy), spendAmount+maxFeeWithoutChange)
  3889  	}
  3890  
  3891  	// Now that we know the input will cover the spend amount plus the fee, add
  3892  	// a change output if the value of including one definitely exceeds the cost.
  3893  	//
  3894  	// Note this is an approximation that will result in change not being included
  3895  	// in circumstances where the value of including it is very marginal but that
  3896  	// seems OK. It also will short-change the user a bit if their output is not
  3897  	// at the maximum size but that seems OK as well. In all of these circumstances
  3898  	// the user will get a slightly higher feerate than they asked for which isn't
  3899  	// really a problem.
  3900  	maxChangeFee := MaxDeSoOutputSizeBytes * minFeeRateNanosPerKB / 1000
  3901  	changeAmount := int64(totalInput) - int64(spendAmount) - int64(maxFeeWithoutChange) - int64(maxChangeFee)
  3902  	if changeAmount > 0 {
  3903  		finalTxCopy.TxOutputs = append(finalTxCopy.TxOutputs, &DeSoOutput{
  3904  			PublicKey:   spendPublicKeyBytes,
  3905  			AmountNanos: uint64(changeAmount),
  3906  		})
  3907  	} else {
  3908  		changeAmount = 0
  3909  	}
  3910  
  3911  	// The final fee is what's left after subtracting the spend amount and the
  3912  	// change from the total input.
  3913  	finalFee := totalInput - spendAmount - uint64(changeAmount)
  3914  
  3915  	// If the final transaction is absolutely huge, return an error.
  3916  	finalTxnSize := _computeMaxTxSize(finalTxCopy)
  3917  	if finalTxnSize > bc.params.MaxBlockSizeBytes/2 {
  3918  		return 0, 0, 0, 0, fmt.Errorf("AddInputsAndChangeToTransaction: "+
  3919  			"Transaction size (%d bytes) exceeds the maximum sane amount "+
  3920  			"allowed (%d bytes)", finalTxnSize, bc.params.MaxBlockSizeBytes/2)
  3921  	}
  3922  
  3923  	// At this point, the inputs cover the (spend amount plus transaction fee)
  3924  	// and the change output has been added if needed, with the total fees of
  3925  	// the transaction set such that the feerate exceeds the minFeeRatePerKB
  3926  	// passed in. Set the inputs and outputs of the transaction passed in and
  3927  	// return.
  3928  	txArg.TxInputs = finalTxCopy.TxInputs
  3929  	txArg.TxOutputs = finalTxCopy.TxOutputs
  3930  
  3931  	return totalInput, spendAmount, uint64(changeAmount), finalFee, nil
  3932  }
  3933  
  3934  func (bc *Blockchain) EstimateDefaultFeeRateNanosPerKB(
  3935  	medianThreshold float64, minFeeRateNanosPerKB uint64) uint64 {
  3936  
  3937  	// Get the block at the tip of our block chain.
  3938  	tipNode := bc.blockTip()
  3939  	blk, err := GetBlock(tipNode.Hash, bc.db)
  3940  	if err != nil {
  3941  		return minFeeRateNanosPerKB
  3942  	}
  3943  
  3944  	// If the block is less than X% full, use the min fee rate.
  3945  	blockBytes, err := blk.ToBytes(false /*preSignature*/)
  3946  	if err != nil {
  3947  		return minFeeRateNanosPerKB
  3948  	}
  3949  	numBytes := len(blockBytes)
  3950  	if float64(numBytes)/float64(bc.params.MaxBlockSizeBytes) < medianThreshold {
  3951  		return minFeeRateNanosPerKB
  3952  	}
  3953  
  3954  	// If the block is more than X% full, use the maximum between the min
  3955  	// fee rate and the median fees of all the transactions in the block.
  3956  	utxoView, err := NewUtxoView(bc.db, bc.params, bc.postgres)
  3957  	if err != nil {
  3958  		return minFeeRateNanosPerKB
  3959  	}
  3960  	utxoOps, err := GetUtxoOperationsForBlock(bc.db, tipNode.Hash)
  3961  	if err != nil {
  3962  		return minFeeRateNanosPerKB
  3963  	}
  3964  	// Compute the hashes for all the transactions.
  3965  	txHashes, err := ComputeTransactionHashes(blk.Txns)
  3966  	if err != nil {
  3967  		return minFeeRateNanosPerKB
  3968  	}
  3969  	if err := utxoView.DisconnectBlock(blk, txHashes, utxoOps); err != nil {
  3970  		return minFeeRateNanosPerKB
  3971  	}
  3972  
  3973  	allFeesNanosPerKB := []uint64{}
  3974  	for _, txn := range blk.Txns {
  3975  		txnBytes, err := txn.ToBytes(false /*preSignature*/)
  3976  		if err != nil {
  3977  			return minFeeRateNanosPerKB
  3978  		}
  3979  		numBytesInTxn := len(txnBytes)
  3980  		_, _, _, fees, err := utxoView.ConnectTransaction(
  3981  			txn, txn.Hash(), int64(numBytesInTxn), tipNode.Height, false /*verifySignatures*/, false /*ignoreUtxos*/)
  3982  		if err != nil {
  3983  			return minFeeRateNanosPerKB
  3984  		}
  3985  		allFeesNanosPerKB = append(
  3986  			allFeesNanosPerKB, uint64(fees)*1000/uint64(numBytesInTxn))
  3987  	}
  3988  
  3989  	// Sort all the fees.
  3990  	sort.Slice(allFeesNanosPerKB, func(ii, jj int) bool {
  3991  		return allFeesNanosPerKB[ii] < allFeesNanosPerKB[jj]
  3992  	})
  3993  
  3994  	// Choose a fee at the middle of the range, which represents the median.
  3995  	medianPos := len(allFeesNanosPerKB) / 2
  3996  
  3997  	// Useful for debugging.
  3998  	/*
  3999  		for _, val := range allFeesNanosPerKB {
  4000  			fmt.Printf("%d ", val)
  4001  		}
  4002  		fmt.Println()
  4003  	*/
  4004  
  4005  	if minFeeRateNanosPerKB > allFeesNanosPerKB[medianPos] {
  4006  		return minFeeRateNanosPerKB
  4007  	}
  4008  	return allFeesNanosPerKB[medianPos]
  4009  }