OSDN Git Service

Merge pull request #201 from Bytom/v0.1
[bytom/vapor.git] / vendor / github.com / btcsuite / btcd / blockchain / chain_test.go
diff --git a/vendor/github.com/btcsuite/btcd/blockchain/chain_test.go b/vendor/github.com/btcsuite/btcd/blockchain/chain_test.go
deleted file mode 100644 (file)
index afb07f9..0000000
+++ /dev/null
@@ -1,802 +0,0 @@
-// Copyright (c) 2013-2017 The btcsuite developers
-// Use of this source code is governed by an ISC
-// license that can be found in the LICENSE file.
-
-package blockchain
-
-import (
-       "reflect"
-       "testing"
-       "time"
-
-       "github.com/btcsuite/btcd/chaincfg"
-       "github.com/btcsuite/btcd/chaincfg/chainhash"
-       "github.com/btcsuite/btcd/wire"
-       "github.com/btcsuite/btcutil"
-)
-
-// TestHaveBlock tests the HaveBlock API to ensure proper functionality.
-func TestHaveBlock(t *testing.T) {
-       // Load up blocks such that there is a side chain.
-       // (genesis block) -> 1 -> 2 -> 3 -> 4
-       //                          \-> 3a
-       testFiles := []string{
-               "blk_0_to_4.dat.bz2",
-               "blk_3A.dat.bz2",
-       }
-
-       var blocks []*btcutil.Block
-       for _, file := range testFiles {
-               blockTmp, err := loadBlocks(file)
-               if err != nil {
-                       t.Errorf("Error loading file: %v\n", err)
-                       return
-               }
-               blocks = append(blocks, blockTmp...)
-       }
-
-       // Create a new database and chain instance to run tests against.
-       chain, teardownFunc, err := chainSetup("haveblock",
-               &chaincfg.MainNetParams)
-       if err != nil {
-               t.Errorf("Failed to setup chain instance: %v", err)
-               return
-       }
-       defer teardownFunc()
-
-       // Since we're not dealing with the real block chain, set the coinbase
-       // maturity to 1.
-       chain.TstSetCoinbaseMaturity(1)
-
-       for i := 1; i < len(blocks); i++ {
-               _, isOrphan, err := chain.ProcessBlock(blocks[i], BFNone)
-               if err != nil {
-                       t.Errorf("ProcessBlock fail on block %v: %v\n", i, err)
-                       return
-               }
-               if isOrphan {
-                       t.Errorf("ProcessBlock incorrectly returned block %v "+
-                               "is an orphan\n", i)
-                       return
-               }
-       }
-
-       // Insert an orphan block.
-       _, isOrphan, err := chain.ProcessBlock(btcutil.NewBlock(&Block100000),
-               BFNone)
-       if err != nil {
-               t.Errorf("Unable to process block: %v", err)
-               return
-       }
-       if !isOrphan {
-               t.Errorf("ProcessBlock indicated block is an not orphan when " +
-                       "it should be\n")
-               return
-       }
-
-       tests := []struct {
-               hash string
-               want bool
-       }{
-               // Genesis block should be present (in the main chain).
-               {hash: chaincfg.MainNetParams.GenesisHash.String(), want: true},
-
-               // Block 3a should be present (on a side chain).
-               {hash: "00000000474284d20067a4d33f6a02284e6ef70764a3a26d6a5b9df52ef663dd", want: true},
-
-               // Block 100000 should be present (as an orphan).
-               {hash: "000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506", want: true},
-
-               // Random hashes should not be available.
-               {hash: "123", want: false},
-       }
-
-       for i, test := range tests {
-               hash, err := chainhash.NewHashFromStr(test.hash)
-               if err != nil {
-                       t.Errorf("NewHashFromStr: %v", err)
-                       continue
-               }
-
-               result, err := chain.HaveBlock(hash)
-               if err != nil {
-                       t.Errorf("HaveBlock #%d unexpected error: %v", i, err)
-                       return
-               }
-               if result != test.want {
-                       t.Errorf("HaveBlock #%d got %v want %v", i, result,
-                               test.want)
-                       continue
-               }
-       }
-}
-
-// TestCalcSequenceLock tests the LockTimeToSequence function, and the
-// CalcSequenceLock method of a Chain instance. The tests exercise several
-// combinations of inputs to the CalcSequenceLock function in order to ensure
-// the returned SequenceLocks are correct for each test instance.
-func TestCalcSequenceLock(t *testing.T) {
-       netParams := &chaincfg.SimNetParams
-
-       // We need to activate CSV in order to test the processing logic, so
-       // manually craft the block version that's used to signal the soft-fork
-       // activation.
-       csvBit := netParams.Deployments[chaincfg.DeploymentCSV].BitNumber
-       blockVersion := int32(0x20000000 | (uint32(1) << csvBit))
-
-       // Generate enough synthetic blocks to activate CSV.
-       chain := newFakeChain(netParams)
-       node := chain.bestChain.Tip()
-       blockTime := node.Header().Timestamp
-       numBlocksToActivate := (netParams.MinerConfirmationWindow * 3)
-       for i := uint32(0); i < numBlocksToActivate; i++ {
-               blockTime = blockTime.Add(time.Second)
-               node = newFakeNode(node, blockVersion, 0, blockTime)
-               chain.index.AddNode(node)
-               chain.bestChain.SetTip(node)
-       }
-
-       // Create a utxo view with a fake utxo for the inputs used in the
-       // transactions created below.  This utxo is added such that it has an
-       // age of 4 blocks.
-       targetTx := btcutil.NewTx(&wire.MsgTx{
-               TxOut: []*wire.TxOut{{
-                       PkScript: nil,
-                       Value:    10,
-               }},
-       })
-       utxoView := NewUtxoViewpoint()
-       utxoView.AddTxOuts(targetTx, int32(numBlocksToActivate)-4)
-       utxoView.SetBestHash(&node.hash)
-
-       // Create a utxo that spends the fake utxo created above for use in the
-       // transactions created in the tests.  It has an age of 4 blocks.  Note
-       // that the sequence lock heights are always calculated from the same
-       // point of view that they were originally calculated from for a given
-       // utxo.  That is to say, the height prior to it.
-       utxo := wire.OutPoint{
-               Hash:  *targetTx.Hash(),
-               Index: 0,
-       }
-       prevUtxoHeight := int32(numBlocksToActivate) - 4
-
-       // Obtain the median time past from the PoV of the input created above.
-       // The MTP for the input is the MTP from the PoV of the block *prior*
-       // to the one that included it.
-       medianTime := node.RelativeAncestor(5).CalcPastMedianTime().Unix()
-
-       // The median time calculated from the PoV of the best block in the
-       // test chain.  For unconfirmed inputs, this value will be used since
-       // the MTP will be calculated from the PoV of the yet-to-be-mined
-       // block.
-       nextMedianTime := node.CalcPastMedianTime().Unix()
-       nextBlockHeight := int32(numBlocksToActivate) + 1
-
-       // Add an additional transaction which will serve as our unconfirmed
-       // output.
-       unConfTx := &wire.MsgTx{
-               TxOut: []*wire.TxOut{{
-                       PkScript: nil,
-                       Value:    5,
-               }},
-       }
-       unConfUtxo := wire.OutPoint{
-               Hash:  unConfTx.TxHash(),
-               Index: 0,
-       }
-
-       // Adding a utxo with a height of 0x7fffffff indicates that the output
-       // is currently unmined.
-       utxoView.AddTxOuts(btcutil.NewTx(unConfTx), 0x7fffffff)
-
-       tests := []struct {
-               tx      *wire.MsgTx
-               view    *UtxoViewpoint
-               mempool bool
-               want    *SequenceLock
-       }{
-               // A transaction of version one should disable sequence locks
-               // as the new sequence number semantics only apply to
-               // transactions version 2 or higher.
-               {
-                       tx: &wire.MsgTx{
-                               Version: 1,
-                               TxIn: []*wire.TxIn{{
-                                       PreviousOutPoint: utxo,
-                                       Sequence:         LockTimeToSequence(false, 3),
-                               }},
-                       },
-                       view: utxoView,
-                       want: &SequenceLock{
-                               Seconds:     -1,
-                               BlockHeight: -1,
-                       },
-               },
-               // A transaction with a single input with max sequence number.
-               // This sequence number has the high bit set, so sequence locks
-               // should be disabled.
-               {
-                       tx: &wire.MsgTx{
-                               Version: 2,
-                               TxIn: []*wire.TxIn{{
-                                       PreviousOutPoint: utxo,
-                                       Sequence:         wire.MaxTxInSequenceNum,
-                               }},
-                       },
-                       view: utxoView,
-                       want: &SequenceLock{
-                               Seconds:     -1,
-                               BlockHeight: -1,
-                       },
-               },
-               // A transaction with a single input whose lock time is
-               // expressed in seconds.  However, the specified lock time is
-               // below the required floor for time based lock times since
-               // they have time granularity of 512 seconds.  As a result, the
-               // seconds lock-time should be just before the median time of
-               // the targeted block.
-               {
-                       tx: &wire.MsgTx{
-                               Version: 2,
-                               TxIn: []*wire.TxIn{{
-                                       PreviousOutPoint: utxo,
-                                       Sequence:         LockTimeToSequence(true, 2),
-                               }},
-                       },
-                       view: utxoView,
-                       want: &SequenceLock{
-                               Seconds:     medianTime - 1,
-                               BlockHeight: -1,
-                       },
-               },
-               // A transaction with a single input whose lock time is
-               // expressed in seconds.  The number of seconds should be 1023
-               // seconds after the median past time of the last block in the
-               // chain.
-               {
-                       tx: &wire.MsgTx{
-                               Version: 2,
-                               TxIn: []*wire.TxIn{{
-                                       PreviousOutPoint: utxo,
-                                       Sequence:         LockTimeToSequence(true, 1024),
-                               }},
-                       },
-                       view: utxoView,
-                       want: &SequenceLock{
-                               Seconds:     medianTime + 1023,
-                               BlockHeight: -1,
-                       },
-               },
-               // A transaction with multiple inputs.  The first input has a
-               // lock time expressed in seconds.  The second input has a
-               // sequence lock in blocks with a value of 4.  The last input
-               // has a sequence number with a value of 5, but has the disable
-               // bit set.  So the first lock should be selected as it's the
-               // latest lock that isn't disabled.
-               {
-                       tx: &wire.MsgTx{
-                               Version: 2,
-                               TxIn: []*wire.TxIn{{
-                                       PreviousOutPoint: utxo,
-                                       Sequence:         LockTimeToSequence(true, 2560),
-                               }, {
-                                       PreviousOutPoint: utxo,
-                                       Sequence:         LockTimeToSequence(false, 4),
-                               }, {
-                                       PreviousOutPoint: utxo,
-                                       Sequence: LockTimeToSequence(false, 5) |
-                                               wire.SequenceLockTimeDisabled,
-                               }},
-                       },
-                       view: utxoView,
-                       want: &SequenceLock{
-                               Seconds:     medianTime + (5 << wire.SequenceLockTimeGranularity) - 1,
-                               BlockHeight: prevUtxoHeight + 3,
-                       },
-               },
-               // Transaction with a single input.  The input's sequence number
-               // encodes a relative lock-time in blocks (3 blocks).  The
-               // sequence lock should  have a value of -1 for seconds, but a
-               // height of 2 meaning it can be included at height 3.
-               {
-                       tx: &wire.MsgTx{
-                               Version: 2,
-                               TxIn: []*wire.TxIn{{
-                                       PreviousOutPoint: utxo,
-                                       Sequence:         LockTimeToSequence(false, 3),
-                               }},
-                       },
-                       view: utxoView,
-                       want: &SequenceLock{
-                               Seconds:     -1,
-                               BlockHeight: prevUtxoHeight + 2,
-                       },
-               },
-               // A transaction with two inputs with lock times expressed in
-               // seconds.  The selected sequence lock value for seconds should
-               // be the time further in the future.
-               {
-                       tx: &wire.MsgTx{
-                               Version: 2,
-                               TxIn: []*wire.TxIn{{
-                                       PreviousOutPoint: utxo,
-                                       Sequence:         LockTimeToSequence(true, 5120),
-                               }, {
-                                       PreviousOutPoint: utxo,
-                                       Sequence:         LockTimeToSequence(true, 2560),
-                               }},
-                       },
-                       view: utxoView,
-                       want: &SequenceLock{
-                               Seconds:     medianTime + (10 << wire.SequenceLockTimeGranularity) - 1,
-                               BlockHeight: -1,
-                       },
-               },
-               // A transaction with two inputs with lock times expressed in
-               // blocks.  The selected sequence lock value for blocks should
-               // be the height further in the future, so a height of 10
-               // indicating it can be included at height 11.
-               {
-                       tx: &wire.MsgTx{
-                               Version: 2,
-                               TxIn: []*wire.TxIn{{
-                                       PreviousOutPoint: utxo,
-                                       Sequence:         LockTimeToSequence(false, 1),
-                               }, {
-                                       PreviousOutPoint: utxo,
-                                       Sequence:         LockTimeToSequence(false, 11),
-                               }},
-                       },
-                       view: utxoView,
-                       want: &SequenceLock{
-                               Seconds:     -1,
-                               BlockHeight: prevUtxoHeight + 10,
-                       },
-               },
-               // A transaction with multiple inputs.  Two inputs are time
-               // based, and the other two are block based. The lock lying
-               // further into the future for both inputs should be chosen.
-               {
-                       tx: &wire.MsgTx{
-                               Version: 2,
-                               TxIn: []*wire.TxIn{{
-                                       PreviousOutPoint: utxo,
-                                       Sequence:         LockTimeToSequence(true, 2560),
-                               }, {
-                                       PreviousOutPoint: utxo,
-                                       Sequence:         LockTimeToSequence(true, 6656),
-                               }, {
-                                       PreviousOutPoint: utxo,
-                                       Sequence:         LockTimeToSequence(false, 3),
-                               }, {
-                                       PreviousOutPoint: utxo,
-                                       Sequence:         LockTimeToSequence(false, 9),
-                               }},
-                       },
-                       view: utxoView,
-                       want: &SequenceLock{
-                               Seconds:     medianTime + (13 << wire.SequenceLockTimeGranularity) - 1,
-                               BlockHeight: prevUtxoHeight + 8,
-                       },
-               },
-               // A transaction with a single unconfirmed input.  As the input
-               // is confirmed, the height of the input should be interpreted
-               // as the height of the *next* block.  So, a 2 block relative
-               // lock means the sequence lock should be for 1 block after the
-               // *next* block height, indicating it can be included 2 blocks
-               // after that.
-               {
-                       tx: &wire.MsgTx{
-                               Version: 2,
-                               TxIn: []*wire.TxIn{{
-                                       PreviousOutPoint: unConfUtxo,
-                                       Sequence:         LockTimeToSequence(false, 2),
-                               }},
-                       },
-                       view:    utxoView,
-                       mempool: true,
-                       want: &SequenceLock{
-                               Seconds:     -1,
-                               BlockHeight: nextBlockHeight + 1,
-                       },
-               },
-               // A transaction with a single unconfirmed input.  The input has
-               // a time based lock, so the lock time should be based off the
-               // MTP of the *next* block.
-               {
-                       tx: &wire.MsgTx{
-                               Version: 2,
-                               TxIn: []*wire.TxIn{{
-                                       PreviousOutPoint: unConfUtxo,
-                                       Sequence:         LockTimeToSequence(true, 1024),
-                               }},
-                       },
-                       view:    utxoView,
-                       mempool: true,
-                       want: &SequenceLock{
-                               Seconds:     nextMedianTime + 1023,
-                               BlockHeight: -1,
-                       },
-               },
-       }
-
-       t.Logf("Running %v SequenceLock tests", len(tests))
-       for i, test := range tests {
-               utilTx := btcutil.NewTx(test.tx)
-               seqLock, err := chain.CalcSequenceLock(utilTx, test.view, test.mempool)
-               if err != nil {
-                       t.Fatalf("test #%d, unable to calc sequence lock: %v", i, err)
-               }
-
-               if seqLock.Seconds != test.want.Seconds {
-                       t.Fatalf("test #%d got %v seconds want %v seconds",
-                               i, seqLock.Seconds, test.want.Seconds)
-               }
-               if seqLock.BlockHeight != test.want.BlockHeight {
-                       t.Fatalf("test #%d got height of %v want height of %v ",
-                               i, seqLock.BlockHeight, test.want.BlockHeight)
-               }
-       }
-}
-
-// nodeHashes is a convenience function that returns the hashes for all of the
-// passed indexes of the provided nodes.  It is used to construct expected hash
-// slices in the tests.
-func nodeHashes(nodes []*blockNode, indexes ...int) []chainhash.Hash {
-       hashes := make([]chainhash.Hash, 0, len(indexes))
-       for _, idx := range indexes {
-               hashes = append(hashes, nodes[idx].hash)
-       }
-       return hashes
-}
-
-// nodeHeaders is a convenience function that returns the headers for all of
-// the passed indexes of the provided nodes.  It is used to construct expected
-// located headers in the tests.
-func nodeHeaders(nodes []*blockNode, indexes ...int) []wire.BlockHeader {
-       headers := make([]wire.BlockHeader, 0, len(indexes))
-       for _, idx := range indexes {
-               headers = append(headers, nodes[idx].Header())
-       }
-       return headers
-}
-
-// TestLocateInventory ensures that locating inventory via the LocateHeaders and
-// LocateBlocks functions behaves as expected.
-func TestLocateInventory(t *testing.T) {
-       // Construct a synthetic block chain with a block index consisting of
-       // the following structure.
-       //      genesis -> 1 -> 2 -> ... -> 15 -> 16  -> 17  -> 18
-       //                                    \-> 16a -> 17a
-       tip := tstTip
-       chain := newFakeChain(&chaincfg.MainNetParams)
-       branch0Nodes := chainedNodes(chain.bestChain.Genesis(), 18)
-       branch1Nodes := chainedNodes(branch0Nodes[14], 2)
-       for _, node := range branch0Nodes {
-               chain.index.AddNode(node)
-       }
-       for _, node := range branch1Nodes {
-               chain.index.AddNode(node)
-       }
-       chain.bestChain.SetTip(tip(branch0Nodes))
-
-       // Create chain views for different branches of the overall chain to
-       // simulate a local and remote node on different parts of the chain.
-       localView := newChainView(tip(branch0Nodes))
-       remoteView := newChainView(tip(branch1Nodes))
-
-       // Create a chain view for a completely unrelated block chain to
-       // simulate a remote node on a totally different chain.
-       unrelatedBranchNodes := chainedNodes(nil, 5)
-       unrelatedView := newChainView(tip(unrelatedBranchNodes))
-
-       tests := []struct {
-               name       string
-               locator    BlockLocator       // locator for requested inventory
-               hashStop   chainhash.Hash     // stop hash for locator
-               maxAllowed uint32             // max to locate, 0 = wire const
-               headers    []wire.BlockHeader // expected located headers
-               hashes     []chainhash.Hash   // expected located hashes
-       }{
-               {
-                       // Empty block locators and unknown stop hash.  No
-                       // inventory should be located.
-                       name:     "no locators, no stop",
-                       locator:  nil,
-                       hashStop: chainhash.Hash{},
-                       headers:  nil,
-                       hashes:   nil,
-               },
-               {
-                       // Empty block locators and stop hash in side chain.
-                       // The expected result is the requested block.
-                       name:     "no locators, stop in side",
-                       locator:  nil,
-                       hashStop: tip(branch1Nodes).hash,
-                       headers:  nodeHeaders(branch1Nodes, 1),
-                       hashes:   nodeHashes(branch1Nodes, 1),
-               },
-               {
-                       // Empty block locators and stop hash in main chain.
-                       // The expected result is the requested block.
-                       name:     "no locators, stop in main",
-                       locator:  nil,
-                       hashStop: branch0Nodes[12].hash,
-                       headers:  nodeHeaders(branch0Nodes, 12),
-                       hashes:   nodeHashes(branch0Nodes, 12),
-               },
-               {
-                       // Locators based on remote being on side chain and a
-                       // stop hash local node doesn't know about.  The
-                       // expected result is the blocks after the fork point in
-                       // the main chain and the stop hash has no effect.
-                       name:     "remote side chain, unknown stop",
-                       locator:  remoteView.BlockLocator(nil),
-                       hashStop: chainhash.Hash{0x01},
-                       headers:  nodeHeaders(branch0Nodes, 15, 16, 17),
-                       hashes:   nodeHashes(branch0Nodes, 15, 16, 17),
-               },
-               {
-                       // Locators based on remote being on side chain and a
-                       // stop hash in side chain.  The expected result is the
-                       // blocks after the fork point in the main chain and the
-                       // stop hash has no effect.
-                       name:     "remote side chain, stop in side",
-                       locator:  remoteView.BlockLocator(nil),
-                       hashStop: tip(branch1Nodes).hash,
-                       headers:  nodeHeaders(branch0Nodes, 15, 16, 17),
-                       hashes:   nodeHashes(branch0Nodes, 15, 16, 17),
-               },
-               {
-                       // Locators based on remote being on side chain and a
-                       // stop hash in main chain, but before fork point.  The
-                       // expected result is the blocks after the fork point in
-                       // the main chain and the stop hash has no effect.
-                       name:     "remote side chain, stop in main before",
-                       locator:  remoteView.BlockLocator(nil),
-                       hashStop: branch0Nodes[13].hash,
-                       headers:  nodeHeaders(branch0Nodes, 15, 16, 17),
-                       hashes:   nodeHashes(branch0Nodes, 15, 16, 17),
-               },
-               {
-                       // Locators based on remote being on side chain and a
-                       // stop hash in main chain, but exactly at the fork
-                       // point.  The expected result is the blocks after the
-                       // fork point in the main chain and the stop hash has no
-                       // effect.
-                       name:     "remote side chain, stop in main exact",
-                       locator:  remoteView.BlockLocator(nil),
-                       hashStop: branch0Nodes[14].hash,
-                       headers:  nodeHeaders(branch0Nodes, 15, 16, 17),
-                       hashes:   nodeHashes(branch0Nodes, 15, 16, 17),
-               },
-               {
-                       // Locators based on remote being on side chain and a
-                       // stop hash in main chain just after the fork point.
-                       // The expected result is the blocks after the fork
-                       // point in the main chain up to and including the stop
-                       // hash.
-                       name:     "remote side chain, stop in main after",
-                       locator:  remoteView.BlockLocator(nil),
-                       hashStop: branch0Nodes[15].hash,
-                       headers:  nodeHeaders(branch0Nodes, 15),
-                       hashes:   nodeHashes(branch0Nodes, 15),
-               },
-               {
-                       // Locators based on remote being on side chain and a
-                       // stop hash in main chain some time after the fork
-                       // point.  The expected result is the blocks after the
-                       // fork point in the main chain up to and including the
-                       // stop hash.
-                       name:     "remote side chain, stop in main after more",
-                       locator:  remoteView.BlockLocator(nil),
-                       hashStop: branch0Nodes[16].hash,
-                       headers:  nodeHeaders(branch0Nodes, 15, 16),
-                       hashes:   nodeHashes(branch0Nodes, 15, 16),
-               },
-               {
-                       // Locators based on remote being on main chain in the
-                       // past and a stop hash local node doesn't know about.
-                       // The expected result is the blocks after the known
-                       // point in the main chain and the stop hash has no
-                       // effect.
-                       name:     "remote main chain past, unknown stop",
-                       locator:  localView.BlockLocator(branch0Nodes[12]),
-                       hashStop: chainhash.Hash{0x01},
-                       headers:  nodeHeaders(branch0Nodes, 13, 14, 15, 16, 17),
-                       hashes:   nodeHashes(branch0Nodes, 13, 14, 15, 16, 17),
-               },
-               {
-                       // Locators based on remote being on main chain in the
-                       // past and a stop hash in a side chain.  The expected
-                       // result is the blocks after the known point in the
-                       // main chain and the stop hash has no effect.
-                       name:     "remote main chain past, stop in side",
-                       locator:  localView.BlockLocator(branch0Nodes[12]),
-                       hashStop: tip(branch1Nodes).hash,
-                       headers:  nodeHeaders(branch0Nodes, 13, 14, 15, 16, 17),
-                       hashes:   nodeHashes(branch0Nodes, 13, 14, 15, 16, 17),
-               },
-               {
-                       // Locators based on remote being on main chain in the
-                       // past and a stop hash in the main chain before that
-                       // point.  The expected result is the blocks after the
-                       // known point in the main chain and the stop hash has
-                       // no effect.
-                       name:     "remote main chain past, stop in main before",
-                       locator:  localView.BlockLocator(branch0Nodes[12]),
-                       hashStop: branch0Nodes[11].hash,
-                       headers:  nodeHeaders(branch0Nodes, 13, 14, 15, 16, 17),
-                       hashes:   nodeHashes(branch0Nodes, 13, 14, 15, 16, 17),
-               },
-               {
-                       // Locators based on remote being on main chain in the
-                       // past and a stop hash in the main chain exactly at that
-                       // point.  The expected result is the blocks after the
-                       // known point in the main chain and the stop hash has
-                       // no effect.
-                       name:     "remote main chain past, stop in main exact",
-                       locator:  localView.BlockLocator(branch0Nodes[12]),
-                       hashStop: branch0Nodes[12].hash,
-                       headers:  nodeHeaders(branch0Nodes, 13, 14, 15, 16, 17),
-                       hashes:   nodeHashes(branch0Nodes, 13, 14, 15, 16, 17),
-               },
-               {
-                       // Locators based on remote being on main chain in the
-                       // past and a stop hash in the main chain just after
-                       // that point.  The expected result is the blocks after
-                       // the known point in the main chain and the stop hash
-                       // has no effect.
-                       name:     "remote main chain past, stop in main after",
-                       locator:  localView.BlockLocator(branch0Nodes[12]),
-                       hashStop: branch0Nodes[13].hash,
-                       headers:  nodeHeaders(branch0Nodes, 13),
-                       hashes:   nodeHashes(branch0Nodes, 13),
-               },
-               {
-                       // Locators based on remote being on main chain in the
-                       // past and a stop hash in the main chain some time
-                       // after that point.  The expected result is the blocks
-                       // after the known point in the main chain and the stop
-                       // hash has no effect.
-                       name:     "remote main chain past, stop in main after more",
-                       locator:  localView.BlockLocator(branch0Nodes[12]),
-                       hashStop: branch0Nodes[15].hash,
-                       headers:  nodeHeaders(branch0Nodes, 13, 14, 15),
-                       hashes:   nodeHashes(branch0Nodes, 13, 14, 15),
-               },
-               {
-                       // Locators based on remote being at exactly the same
-                       // point in the main chain and a stop hash local node
-                       // doesn't know about.  The expected result is no
-                       // located inventory.
-                       name:     "remote main chain same, unknown stop",
-                       locator:  localView.BlockLocator(nil),
-                       hashStop: chainhash.Hash{0x01},
-                       headers:  nil,
-                       hashes:   nil,
-               },
-               {
-                       // Locators based on remote being at exactly the same
-                       // point in the main chain and a stop hash at exactly
-                       // the same point.  The expected result is no located
-                       // inventory.
-                       name:     "remote main chain same, stop same point",
-                       locator:  localView.BlockLocator(nil),
-                       hashStop: tip(branch0Nodes).hash,
-                       headers:  nil,
-                       hashes:   nil,
-               },
-               {
-                       // Locators from remote that don't include any blocks
-                       // the local node knows.  This would happen if the
-                       // remote node is on a completely separate chain that
-                       // isn't rooted with the same genesis block.  The
-                       // expected result is the blocks after the genesis
-                       // block.
-                       name:     "remote unrelated chain",
-                       locator:  unrelatedView.BlockLocator(nil),
-                       hashStop: chainhash.Hash{},
-                       headers: nodeHeaders(branch0Nodes, 0, 1, 2, 3, 4, 5, 6,
-                               7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17),
-                       hashes: nodeHashes(branch0Nodes, 0, 1, 2, 3, 4, 5, 6,
-                               7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17),
-               },
-               {
-                       // Locators from remote for second block in main chain
-                       // and no stop hash, but with an overridden max limit.
-                       // The expected result is the blocks after the second
-                       // block limited by the max.
-                       name:       "remote genesis",
-                       locator:    locatorHashes(branch0Nodes, 0),
-                       hashStop:   chainhash.Hash{},
-                       maxAllowed: 3,
-                       headers:    nodeHeaders(branch0Nodes, 1, 2, 3),
-                       hashes:     nodeHashes(branch0Nodes, 1, 2, 3),
-               },
-               {
-                       // Poorly formed locator.
-                       //
-                       // Locator from remote that only includes a single
-                       // block on a side chain the local node knows.  The
-                       // expected result is the blocks after the genesis
-                       // block since even though the block is known, it is on
-                       // a side chain and there are no more locators to find
-                       // the fork point.
-                       name:     "weak locator, single known side block",
-                       locator:  locatorHashes(branch1Nodes, 1),
-                       hashStop: chainhash.Hash{},
-                       headers: nodeHeaders(branch0Nodes, 0, 1, 2, 3, 4, 5, 6,
-                               7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17),
-                       hashes: nodeHashes(branch0Nodes, 0, 1, 2, 3, 4, 5, 6,
-                               7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17),
-               },
-               {
-                       // Poorly formed locator.
-                       //
-                       // Locator from remote that only includes multiple
-                       // blocks on a side chain the local node knows however
-                       // none in the main chain.  The expected result is the
-                       // blocks after the genesis block since even though the
-                       // blocks are known, they are all on a side chain and
-                       // there are no more locators to find the fork point.
-                       name:     "weak locator, multiple known side blocks",
-                       locator:  locatorHashes(branch1Nodes, 1),
-                       hashStop: chainhash.Hash{},
-                       headers: nodeHeaders(branch0Nodes, 0, 1, 2, 3, 4, 5, 6,
-                               7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17),
-                       hashes: nodeHashes(branch0Nodes, 0, 1, 2, 3, 4, 5, 6,
-                               7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17),
-               },
-               {
-                       // Poorly formed locator.
-                       //
-                       // Locator from remote that only includes multiple
-                       // blocks on a side chain the local node knows however
-                       // none in the main chain but includes a stop hash in
-                       // the main chain.  The expected result is the blocks
-                       // after the genesis block up to the stop hash since
-                       // even though the blocks are known, they are all on a
-                       // side chain and there are no more locators to find the
-                       // fork point.
-                       name:     "weak locator, multiple known side blocks, stop in main",
-                       locator:  locatorHashes(branch1Nodes, 1),
-                       hashStop: branch0Nodes[5].hash,
-                       headers:  nodeHeaders(branch0Nodes, 0, 1, 2, 3, 4, 5),
-                       hashes:   nodeHashes(branch0Nodes, 0, 1, 2, 3, 4, 5),
-               },
-       }
-       for _, test := range tests {
-               // Ensure the expected headers are located.
-               var headers []wire.BlockHeader
-               if test.maxAllowed != 0 {
-                       // Need to use the unexported function to override the
-                       // max allowed for headers.
-                       chain.chainLock.RLock()
-                       headers = chain.locateHeaders(test.locator,
-                               &test.hashStop, test.maxAllowed)
-                       chain.chainLock.RUnlock()
-               } else {
-                       headers = chain.LocateHeaders(test.locator,
-                               &test.hashStop)
-               }
-               if !reflect.DeepEqual(headers, test.headers) {
-                       t.Errorf("%s: unxpected headers -- got %v, want %v",
-                               test.name, headers, test.headers)
-                       continue
-               }
-
-               // Ensure the expected block hashes are located.
-               maxAllowed := uint32(wire.MaxBlocksPerMsg)
-               if test.maxAllowed != 0 {
-                       maxAllowed = test.maxAllowed
-               }
-               hashes := chain.LocateBlocks(test.locator, &test.hashStop,
-                       maxAllowed)
-               if !reflect.DeepEqual(hashes, test.hashes) {
-                       t.Errorf("%s: unxpected hashes -- got %v, want %v",
-                               test.name, hashes, test.hashes)
-                       continue
-               }
-       }
-}