chainhash: Abstract hash logic to new package. (#729)
This is mostly a backport of some of the same modifications made in Decred along with a few additional things cleaned up. In particular, this updates the code to make use of the new chainhash package. Also, since this required API changes anyways and the hash algorithm is no longer tied specifically to SHA, all other functions throughout the code base which had "Sha" in their name have been changed to Hash so they are not incorrectly implying the hash algorithm. The following is an overview of the changes: - Remove the wire.ShaHash type - Update all references to wire.ShaHash to the new chainhash.Hash type - Rename the following functions and update all references: - wire.BlockHeader.BlockSha -> BlockHash - wire.MsgBlock.BlockSha -> BlockHash - wire.MsgBlock.TxShas -> TxHashes - wire.MsgTx.TxSha -> TxHash - blockchain.ShaHashToBig -> HashToBig - peer.ShaFunc -> peer.HashFunc - Rename all variables that included sha in their name to include hash instead - Update for function name changes in other dependent packages such as btcutil - Update copyright dates on all modified files - Update glide.lock file to use the required version of btcutil
This commit is contained in:
parent
b6b1e55d1e
commit
bd4e64d1d4
82 changed files with 916 additions and 1150 deletions
|
@ -22,6 +22,7 @@ import (
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -299,7 +300,7 @@ func (a *AddrManager) getNewBucket(netAddr, srcAddr *wire.NetAddress) int {
|
||||||
data1 = append(data1, a.key[:]...)
|
data1 = append(data1, a.key[:]...)
|
||||||
data1 = append(data1, []byte(GroupKey(netAddr))...)
|
data1 = append(data1, []byte(GroupKey(netAddr))...)
|
||||||
data1 = append(data1, []byte(GroupKey(srcAddr))...)
|
data1 = append(data1, []byte(GroupKey(srcAddr))...)
|
||||||
hash1 := wire.DoubleSha256(data1)
|
hash1 := chainhash.DoubleHashB(data1)
|
||||||
hash64 := binary.LittleEndian.Uint64(hash1)
|
hash64 := binary.LittleEndian.Uint64(hash1)
|
||||||
hash64 %= newBucketsPerGroup
|
hash64 %= newBucketsPerGroup
|
||||||
var hashbuf [8]byte
|
var hashbuf [8]byte
|
||||||
|
@ -309,7 +310,7 @@ func (a *AddrManager) getNewBucket(netAddr, srcAddr *wire.NetAddress) int {
|
||||||
data2 = append(data2, GroupKey(srcAddr)...)
|
data2 = append(data2, GroupKey(srcAddr)...)
|
||||||
data2 = append(data2, hashbuf[:]...)
|
data2 = append(data2, hashbuf[:]...)
|
||||||
|
|
||||||
hash2 := wire.DoubleSha256(data2)
|
hash2 := chainhash.DoubleHashB(data2)
|
||||||
return int(binary.LittleEndian.Uint64(hash2) % newBucketCount)
|
return int(binary.LittleEndian.Uint64(hash2) % newBucketCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,7 +320,7 @@ func (a *AddrManager) getTriedBucket(netAddr *wire.NetAddress) int {
|
||||||
data1 := []byte{}
|
data1 := []byte{}
|
||||||
data1 = append(data1, a.key[:]...)
|
data1 = append(data1, a.key[:]...)
|
||||||
data1 = append(data1, []byte(NetAddressKey(netAddr))...)
|
data1 = append(data1, []byte(NetAddressKey(netAddr))...)
|
||||||
hash1 := wire.DoubleSha256(data1)
|
hash1 := chainhash.DoubleHashB(data1)
|
||||||
hash64 := binary.LittleEndian.Uint64(hash1)
|
hash64 := binary.LittleEndian.Uint64(hash1)
|
||||||
hash64 %= triedBucketsPerGroup
|
hash64 %= triedBucketsPerGroup
|
||||||
var hashbuf [8]byte
|
var hashbuf [8]byte
|
||||||
|
@ -329,7 +330,7 @@ func (a *AddrManager) getTriedBucket(netAddr *wire.NetAddress) int {
|
||||||
data2 = append(data2, GroupKey(netAddr)...)
|
data2 = append(data2, GroupKey(netAddr)...)
|
||||||
data2 = append(data2, hashbuf[:]...)
|
data2 = append(data2, hashbuf[:]...)
|
||||||
|
|
||||||
hash2 := wire.DoubleSha256(data2)
|
hash2 := chainhash.DoubleHashB(data2)
|
||||||
return int(binary.LittleEndian.Uint64(hash2) % triedBucketCount)
|
return int(binary.LittleEndian.Uint64(hash2) % triedBucketCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block, flags BehaviorFlags)
|
||||||
// Create a new block node for the block and add it to the in-memory
|
// Create a new block node for the block and add it to the in-memory
|
||||||
// block chain (could be either a side chain or the main chain).
|
// block chain (could be either a side chain or the main chain).
|
||||||
blockHeader := &block.MsgBlock().Header
|
blockHeader := &block.MsgBlock().Header
|
||||||
newNode := newBlockNode(blockHeader, block.Sha(), blockHeight)
|
newNode := newBlockNode(blockHeader, block.Hash(), blockHeight)
|
||||||
if prevNode != nil {
|
if prevNode != nil {
|
||||||
newNode.parent = prevNode
|
newNode.parent = prevNode
|
||||||
newNode.height = blockHeight
|
newNode.height = blockHeight
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
package blockchain
|
package blockchain
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/database"
|
"github.com/btcsuite/btcd/database"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
)
|
)
|
||||||
|
@ -24,7 +25,7 @@ import (
|
||||||
//
|
//
|
||||||
// The block locator for block 17a would be the hashes of blocks:
|
// The block locator for block 17a would be the hashes of blocks:
|
||||||
// [17a 16a 15 14 13 12 11 10 9 8 6 2 genesis]
|
// [17a 16a 15 14 13 12 11 10 9 8 6 2 genesis]
|
||||||
type BlockLocator []*wire.ShaHash
|
type BlockLocator []*chainhash.Hash
|
||||||
|
|
||||||
// blockLocatorFromHash returns a block locator for the passed block hash.
|
// blockLocatorFromHash returns a block locator for the passed block hash.
|
||||||
// See BlockLocator for details on the algotirhm used to create a block locator.
|
// See BlockLocator for details on the algotirhm used to create a block locator.
|
||||||
|
@ -38,7 +39,7 @@ type BlockLocator []*wire.ShaHash
|
||||||
// consist of the passed hash
|
// consist of the passed hash
|
||||||
//
|
//
|
||||||
// This function MUST be called with the chain state lock held (for reads).
|
// This function MUST be called with the chain state lock held (for reads).
|
||||||
func (b *BlockChain) blockLocatorFromHash(hash *wire.ShaHash) BlockLocator {
|
func (b *BlockChain) blockLocatorFromHash(hash *chainhash.Hash) BlockLocator {
|
||||||
// The locator contains the requested hash at the very least.
|
// The locator contains the requested hash at the very least.
|
||||||
locator := make(BlockLocator, 0, wire.MaxBlockLocatorsPerMsg)
|
locator := make(BlockLocator, 0, wire.MaxBlockLocatorsPerMsg)
|
||||||
locator = append(locator, hash)
|
locator = append(locator, hash)
|
||||||
|
@ -159,7 +160,7 @@ func (b *BlockChain) blockLocatorFromHash(hash *wire.ShaHash) BlockLocator {
|
||||||
// consist of the passed hash
|
// consist of the passed hash
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (b *BlockChain) BlockLocatorFromHash(hash *wire.ShaHash) BlockLocator {
|
func (b *BlockChain) BlockLocatorFromHash(hash *chainhash.Hash) BlockLocator {
|
||||||
b.chainLock.RLock()
|
b.chainLock.RLock()
|
||||||
locator := b.blockLocatorFromHash(hash)
|
locator := b.blockLocatorFromHash(hash)
|
||||||
b.chainLock.RUnlock()
|
b.chainLock.RUnlock()
|
||||||
|
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/chaincfg"
|
"github.com/btcsuite/btcd/chaincfg"
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/database"
|
"github.com/btcsuite/btcd/database"
|
||||||
"github.com/btcsuite/btcd/txscript"
|
"github.com/btcsuite/btcd/txscript"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
|
@ -44,13 +45,13 @@ type blockNode struct {
|
||||||
children []*blockNode
|
children []*blockNode
|
||||||
|
|
||||||
// hash is the double sha 256 of the block.
|
// hash is the double sha 256 of the block.
|
||||||
hash *wire.ShaHash
|
hash *chainhash.Hash
|
||||||
|
|
||||||
// parentHash is the double sha 256 of the parent block. This is kept
|
// parentHash is the double sha 256 of the parent block. This is kept
|
||||||
// here over simply relying on parent.hash directly since block nodes
|
// here over simply relying on parent.hash directly since block nodes
|
||||||
// are sparse and the parent node might not be in memory when its hash
|
// are sparse and the parent node might not be in memory when its hash
|
||||||
// is needed.
|
// is needed.
|
||||||
parentHash *wire.ShaHash
|
parentHash *chainhash.Hash
|
||||||
|
|
||||||
// height is the position in the block chain.
|
// height is the position in the block chain.
|
||||||
height int32
|
height int32
|
||||||
|
@ -74,13 +75,13 @@ type blockNode struct {
|
||||||
// completely disconnected from the chain and the workSum value is just the work
|
// completely disconnected from the chain and the workSum value is just the work
|
||||||
// for the passed block. The work sum is updated accordingly when the node is
|
// for the passed block. The work sum is updated accordingly when the node is
|
||||||
// inserted into a chain.
|
// inserted into a chain.
|
||||||
func newBlockNode(blockHeader *wire.BlockHeader, blockSha *wire.ShaHash, height int32) *blockNode {
|
func newBlockNode(blockHeader *wire.BlockHeader, blockHash *chainhash.Hash, height int32) *blockNode {
|
||||||
// Make a copy of the hash so the node doesn't keep a reference to part
|
// Make a copy of the hash so the node doesn't keep a reference to part
|
||||||
// of the full block/block header preventing it from being garbage
|
// of the full block/block header preventing it from being garbage
|
||||||
// collected.
|
// collected.
|
||||||
prevHash := blockHeader.PrevBlock
|
prevHash := blockHeader.PrevBlock
|
||||||
node := blockNode{
|
node := blockNode{
|
||||||
hash: blockSha,
|
hash: blockHash,
|
||||||
parentHash: &prevHash,
|
parentHash: &prevHash,
|
||||||
workSum: CalcWork(blockHeader.Bits),
|
workSum: CalcWork(blockHeader.Bits),
|
||||||
height: height,
|
height: height,
|
||||||
|
@ -133,12 +134,12 @@ func removeChildNode(children []*blockNode, node *blockNode) []*blockNode {
|
||||||
// However, the returned snapshot must be treated as immutable since it is
|
// However, the returned snapshot must be treated as immutable since it is
|
||||||
// shared by all callers.
|
// shared by all callers.
|
||||||
type BestState struct {
|
type BestState struct {
|
||||||
Hash *wire.ShaHash // The hash of the block.
|
Hash *chainhash.Hash // The hash of the block.
|
||||||
Height int32 // The height of the block.
|
Height int32 // The height of the block.
|
||||||
Bits uint32 // The difficulty bits of the block.
|
Bits uint32 // The difficulty bits of the block.
|
||||||
BlockSize uint64 // The size of the block.
|
BlockSize uint64 // The size of the block.
|
||||||
NumTxns uint64 // The number of txns in the block.
|
NumTxns uint64 // The number of txns in the block.
|
||||||
TotalTxns uint64 // The total number of txns in the chain.
|
TotalTxns uint64 // The total number of txns in the chain.
|
||||||
}
|
}
|
||||||
|
|
||||||
// newBestState returns a new best stats instance for the given parameters.
|
// newBestState returns a new best stats instance for the given parameters.
|
||||||
|
@ -181,16 +182,16 @@ type BlockChain struct {
|
||||||
// These fields are related to the memory block index. They are
|
// These fields are related to the memory block index. They are
|
||||||
// protected by the chain lock.
|
// protected by the chain lock.
|
||||||
bestNode *blockNode
|
bestNode *blockNode
|
||||||
index map[wire.ShaHash]*blockNode
|
index map[chainhash.Hash]*blockNode
|
||||||
depNodes map[wire.ShaHash][]*blockNode
|
depNodes map[chainhash.Hash][]*blockNode
|
||||||
|
|
||||||
// These fields are related to handling of orphan blocks. They are
|
// These fields are related to handling of orphan blocks. They are
|
||||||
// protected by a combination of the chain lock and the orphan lock.
|
// protected by a combination of the chain lock and the orphan lock.
|
||||||
orphanLock sync.RWMutex
|
orphanLock sync.RWMutex
|
||||||
orphans map[wire.ShaHash]*orphanBlock
|
orphans map[chainhash.Hash]*orphanBlock
|
||||||
prevOrphans map[wire.ShaHash][]*orphanBlock
|
prevOrphans map[chainhash.Hash][]*orphanBlock
|
||||||
oldestOrphan *orphanBlock
|
oldestOrphan *orphanBlock
|
||||||
blockCache map[wire.ShaHash]*btcutil.Block
|
blockCache map[chainhash.Hash]*btcutil.Block
|
||||||
|
|
||||||
// These fields are related to checkpoint handling. They are protected
|
// These fields are related to checkpoint handling. They are protected
|
||||||
// by the chain lock.
|
// by the chain lock.
|
||||||
|
@ -230,7 +231,7 @@ func (b *BlockChain) DisableVerify(disable bool) {
|
||||||
// be like part of the main chain, on a side chain, or in the orphan pool.
|
// be like part of the main chain, on a side chain, or in the orphan pool.
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (b *BlockChain) HaveBlock(hash *wire.ShaHash) (bool, error) {
|
func (b *BlockChain) HaveBlock(hash *chainhash.Hash) (bool, error) {
|
||||||
b.chainLock.RLock()
|
b.chainLock.RLock()
|
||||||
defer b.chainLock.RUnlock()
|
defer b.chainLock.RUnlock()
|
||||||
|
|
||||||
|
@ -251,7 +252,7 @@ func (b *BlockChain) HaveBlock(hash *wire.ShaHash) (bool, error) {
|
||||||
// duplicate orphans and react accordingly.
|
// duplicate orphans and react accordingly.
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (b *BlockChain) IsKnownOrphan(hash *wire.ShaHash) bool {
|
func (b *BlockChain) IsKnownOrphan(hash *chainhash.Hash) bool {
|
||||||
// Protect concurrent access. Using a read lock only so multiple
|
// Protect concurrent access. Using a read lock only so multiple
|
||||||
// readers can query without blocking each other.
|
// readers can query without blocking each other.
|
||||||
b.orphanLock.RLock()
|
b.orphanLock.RLock()
|
||||||
|
@ -268,7 +269,7 @@ func (b *BlockChain) IsKnownOrphan(hash *wire.ShaHash) bool {
|
||||||
// map of orphan blocks.
|
// map of orphan blocks.
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (b *BlockChain) GetOrphanRoot(hash *wire.ShaHash) *wire.ShaHash {
|
func (b *BlockChain) GetOrphanRoot(hash *chainhash.Hash) *chainhash.Hash {
|
||||||
// Protect concurrent access. Using a read lock only so multiple
|
// Protect concurrent access. Using a read lock only so multiple
|
||||||
// readers can query without blocking each other.
|
// readers can query without blocking each other.
|
||||||
b.orphanLock.RLock()
|
b.orphanLock.RLock()
|
||||||
|
@ -298,7 +299,7 @@ func (b *BlockChain) removeOrphanBlock(orphan *orphanBlock) {
|
||||||
defer b.orphanLock.Unlock()
|
defer b.orphanLock.Unlock()
|
||||||
|
|
||||||
// Remove the orphan block from the orphan pool.
|
// Remove the orphan block from the orphan pool.
|
||||||
orphanHash := orphan.block.Sha()
|
orphanHash := orphan.block.Hash()
|
||||||
delete(b.orphans, *orphanHash)
|
delete(b.orphans, *orphanHash)
|
||||||
|
|
||||||
// Remove the reference from the previous orphan index too. An indexing
|
// Remove the reference from the previous orphan index too. An indexing
|
||||||
|
@ -308,7 +309,7 @@ func (b *BlockChain) removeOrphanBlock(orphan *orphanBlock) {
|
||||||
prevHash := &orphan.block.MsgBlock().Header.PrevBlock
|
prevHash := &orphan.block.MsgBlock().Header.PrevBlock
|
||||||
orphans := b.prevOrphans[*prevHash]
|
orphans := b.prevOrphans[*prevHash]
|
||||||
for i := 0; i < len(orphans); i++ {
|
for i := 0; i < len(orphans); i++ {
|
||||||
hash := orphans[i].block.Sha()
|
hash := orphans[i].block.Hash()
|
||||||
if hash.IsEqual(orphanHash) {
|
if hash.IsEqual(orphanHash) {
|
||||||
copy(orphans[i:], orphans[i+1:])
|
copy(orphans[i:], orphans[i+1:])
|
||||||
orphans[len(orphans)-1] = nil
|
orphans[len(orphans)-1] = nil
|
||||||
|
@ -366,7 +367,7 @@ func (b *BlockChain) addOrphanBlock(block *btcutil.Block) {
|
||||||
block: block,
|
block: block,
|
||||||
expiration: expiration,
|
expiration: expiration,
|
||||||
}
|
}
|
||||||
b.orphans[*block.Sha()] = oBlock
|
b.orphans[*block.Hash()] = oBlock
|
||||||
|
|
||||||
// Add to previous hash lookup index for faster dependency lookups.
|
// Add to previous hash lookup index for faster dependency lookups.
|
||||||
prevHash := &block.MsgBlock().Header.PrevBlock
|
prevHash := &block.MsgBlock().Header.PrevBlock
|
||||||
|
@ -382,7 +383,7 @@ func (b *BlockChain) addOrphanBlock(block *btcutil.Block) {
|
||||||
//
|
//
|
||||||
// This function MUST be called with the chain state lock held (for writes).
|
// This function MUST be called with the chain state lock held (for writes).
|
||||||
// The database transaction may be read-only.
|
// The database transaction may be read-only.
|
||||||
func (b *BlockChain) loadBlockNode(dbTx database.Tx, hash *wire.ShaHash) (*blockNode, error) {
|
func (b *BlockChain) loadBlockNode(dbTx database.Tx, hash *chainhash.Hash) (*blockNode, error) {
|
||||||
// Load the block header and height from the db.
|
// Load the block header and height from the db.
|
||||||
blockHeader, err := dbFetchHeaderByHash(dbTx, hash)
|
blockHeader, err := dbFetchHeaderByHash(dbTx, hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -732,7 +733,7 @@ func (b *BlockChain) getReorganizeNodes(node *blockNode) (*list.List, *list.List
|
||||||
// dbMaybeStoreBlock stores the provided block in the database if it's not
|
// dbMaybeStoreBlock stores the provided block in the database if it's not
|
||||||
// already there.
|
// already there.
|
||||||
func dbMaybeStoreBlock(dbTx database.Tx, block *btcutil.Block) error {
|
func dbMaybeStoreBlock(dbTx database.Tx, block *btcutil.Block) error {
|
||||||
hasBlock, err := dbTx.HasBlock(block.Sha())
|
hasBlock, err := dbTx.HasBlock(block.Hash())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -787,7 +788,7 @@ func (b *BlockChain) connectBlock(node *blockNode, block *btcutil.Block, view *U
|
||||||
|
|
||||||
// Add the block hash and height to the block index which tracks
|
// Add the block hash and height to the block index which tracks
|
||||||
// the main chain.
|
// the main chain.
|
||||||
err = dbPutBlockIndex(dbTx, block.Sha(), node.height)
|
err = dbPutBlockIndex(dbTx, block.Hash(), node.height)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -802,7 +803,7 @@ func (b *BlockChain) connectBlock(node *blockNode, block *btcutil.Block, view *U
|
||||||
|
|
||||||
// Update the transaction spend journal by adding a record for
|
// Update the transaction spend journal by adding a record for
|
||||||
// the block that contains all txos spent by it.
|
// the block that contains all txos spent by it.
|
||||||
err = dbPutSpendJournalEntry(dbTx, block.Sha(), stxos)
|
err = dbPutSpendJournalEntry(dbTx, block.Hash(), stxos)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -911,7 +912,7 @@ func (b *BlockChain) disconnectBlock(node *blockNode, block *btcutil.Block, view
|
||||||
|
|
||||||
// Remove the block hash and height from the block index which
|
// Remove the block hash and height from the block index which
|
||||||
// tracks the main chain.
|
// tracks the main chain.
|
||||||
err = dbRemoveBlockIndex(dbTx, block.Sha(), node.height)
|
err = dbRemoveBlockIndex(dbTx, block.Hash(), node.height)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -926,7 +927,7 @@ func (b *BlockChain) disconnectBlock(node *blockNode, block *btcutil.Block, view
|
||||||
|
|
||||||
// Update the transaction spend journal by removing the record
|
// Update the transaction spend journal by removing the record
|
||||||
// that contains all txos spent by the block .
|
// that contains all txos spent by the block .
|
||||||
err = dbRemoveSpendJournalEntry(dbTx, block.Sha())
|
err = dbRemoveSpendJournalEntry(dbTx, block.Hash())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -1243,7 +1244,7 @@ func (b *BlockChain) connectBestChain(node *blockNode, block *btcutil.Block, fla
|
||||||
}
|
}
|
||||||
if fastAdd {
|
if fastAdd {
|
||||||
log.Warnf("fastAdd set in the side chain case? %v\n",
|
log.Warnf("fastAdd set in the side chain case? %v\n",
|
||||||
block.Sha())
|
block.Hash())
|
||||||
}
|
}
|
||||||
|
|
||||||
// We're extending (or creating) a side chain which may or may not
|
// We're extending (or creating) a side chain which may or may not
|
||||||
|
@ -1462,11 +1463,11 @@ func New(config *Config) (*BlockChain, error) {
|
||||||
sigCache: config.SigCache,
|
sigCache: config.SigCache,
|
||||||
indexManager: config.IndexManager,
|
indexManager: config.IndexManager,
|
||||||
bestNode: nil,
|
bestNode: nil,
|
||||||
index: make(map[wire.ShaHash]*blockNode),
|
index: make(map[chainhash.Hash]*blockNode),
|
||||||
depNodes: make(map[wire.ShaHash][]*blockNode),
|
depNodes: make(map[chainhash.Hash][]*blockNode),
|
||||||
orphans: make(map[wire.ShaHash]*orphanBlock),
|
orphans: make(map[chainhash.Hash]*orphanBlock),
|
||||||
prevOrphans: make(map[wire.ShaHash][]*orphanBlock),
|
prevOrphans: make(map[chainhash.Hash][]*orphanBlock),
|
||||||
blockCache: make(map[wire.ShaHash]*btcutil.Block),
|
blockCache: make(map[chainhash.Hash]*btcutil.Block),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the chain state from the passed database. When the db
|
// Initialize the chain state from the passed database. When the db
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2013-2014 The btcsuite developers
|
// Copyright (c) 2013-2016 The btcsuite developers
|
||||||
// Use of this source code is governed by an ISC
|
// Use of this source code is governed by an ISC
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ import (
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/blockchain"
|
"github.com/btcsuite/btcd/blockchain"
|
||||||
"github.com/btcsuite/btcd/chaincfg"
|
"github.com/btcsuite/btcd/chaincfg"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcutil"
|
"github.com/btcsuite/btcutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -92,9 +92,9 @@ func TestHaveBlock(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, test := range tests {
|
for i, test := range tests {
|
||||||
hash, err := wire.NewShaHashFromStr(test.hash)
|
hash, err := chainhash.NewHashFromStr(test.hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("NewShaHashFromStr: %v", err)
|
t.Errorf("NewHashFromStr: %v", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"math/big"
|
"math/big"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/database"
|
"github.com/btcsuite/btcd/database"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
"github.com/btcsuite/btcutil"
|
"github.com/btcsuite/btcutil"
|
||||||
|
@ -321,7 +322,7 @@ func deserializeSpendJournalEntry(serialized []byte, txns []*wire.MsgTx, view *U
|
||||||
// Loop backwards through all transactions so everything is read in
|
// Loop backwards through all transactions so everything is read in
|
||||||
// reverse order to match the serialization order.
|
// reverse order to match the serialization order.
|
||||||
stxoIdx := numStxos - 1
|
stxoIdx := numStxos - 1
|
||||||
stxoInFlight := make(map[wire.ShaHash]int)
|
stxoInFlight := make(map[chainhash.Hash]int)
|
||||||
offset := 0
|
offset := 0
|
||||||
stxos := make([]spentTxOut, numStxos)
|
stxos := make([]spentTxOut, numStxos)
|
||||||
for txIdx := len(txns) - 1; txIdx > -1; txIdx-- {
|
for txIdx := len(txns) - 1; txIdx > -1; txIdx-- {
|
||||||
|
@ -408,7 +409,7 @@ func serializeSpendJournalEntry(stxos []spentTxOut) []byte {
|
||||||
func dbFetchSpendJournalEntry(dbTx database.Tx, block *btcutil.Block, view *UtxoViewpoint) ([]spentTxOut, error) {
|
func dbFetchSpendJournalEntry(dbTx database.Tx, block *btcutil.Block, view *UtxoViewpoint) ([]spentTxOut, error) {
|
||||||
// Exclude the coinbase transaction since it can't spend anything.
|
// Exclude the coinbase transaction since it can't spend anything.
|
||||||
spendBucket := dbTx.Metadata().Bucket(spendJournalBucketName)
|
spendBucket := dbTx.Metadata().Bucket(spendJournalBucketName)
|
||||||
serialized := spendBucket.Get(block.Sha()[:])
|
serialized := spendBucket.Get(block.Hash()[:])
|
||||||
blockTxns := block.MsgBlock().Transactions[1:]
|
blockTxns := block.MsgBlock().Transactions[1:]
|
||||||
stxos, err := deserializeSpendJournalEntry(serialized, blockTxns, view)
|
stxos, err := deserializeSpendJournalEntry(serialized, blockTxns, view)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -418,7 +419,7 @@ func dbFetchSpendJournalEntry(dbTx database.Tx, block *btcutil.Block, view *Utxo
|
||||||
return nil, database.Error{
|
return nil, database.Error{
|
||||||
ErrorCode: database.ErrCorruption,
|
ErrorCode: database.ErrCorruption,
|
||||||
Description: fmt.Sprintf("corrupt spend "+
|
Description: fmt.Sprintf("corrupt spend "+
|
||||||
"information for %v: %v", block.Sha(),
|
"information for %v: %v", block.Hash(),
|
||||||
err),
|
err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -433,7 +434,7 @@ func dbFetchSpendJournalEntry(dbTx database.Tx, block *btcutil.Block, view *Utxo
|
||||||
// spend journal entry for the given block hash using the provided slice of
|
// spend journal entry for the given block hash using the provided slice of
|
||||||
// spent txouts. The spent txouts slice must contain an entry for every txout
|
// spent txouts. The spent txouts slice must contain an entry for every txout
|
||||||
// the transactions in the block spend in the order they are spent.
|
// the transactions in the block spend in the order they are spent.
|
||||||
func dbPutSpendJournalEntry(dbTx database.Tx, blockHash *wire.ShaHash, stxos []spentTxOut) error {
|
func dbPutSpendJournalEntry(dbTx database.Tx, blockHash *chainhash.Hash, stxos []spentTxOut) error {
|
||||||
spendBucket := dbTx.Metadata().Bucket(spendJournalBucketName)
|
spendBucket := dbTx.Metadata().Bucket(spendJournalBucketName)
|
||||||
serialized := serializeSpendJournalEntry(stxos)
|
serialized := serializeSpendJournalEntry(stxos)
|
||||||
return spendBucket.Put(blockHash[:], serialized)
|
return spendBucket.Put(blockHash[:], serialized)
|
||||||
|
@ -441,7 +442,7 @@ func dbPutSpendJournalEntry(dbTx database.Tx, blockHash *wire.ShaHash, stxos []s
|
||||||
|
|
||||||
// dbRemoveSpendJournalEntry uses an existing database transaction to remove the
|
// dbRemoveSpendJournalEntry uses an existing database transaction to remove the
|
||||||
// spend journal entry for the passed block hash.
|
// spend journal entry for the passed block hash.
|
||||||
func dbRemoveSpendJournalEntry(dbTx database.Tx, blockHash *wire.ShaHash) error {
|
func dbRemoveSpendJournalEntry(dbTx database.Tx, blockHash *chainhash.Hash) error {
|
||||||
spendBucket := dbTx.Metadata().Bucket(spendJournalBucketName)
|
spendBucket := dbTx.Metadata().Bucket(spendJournalBucketName)
|
||||||
return spendBucket.Delete(blockHash[:])
|
return spendBucket.Delete(blockHash[:])
|
||||||
}
|
}
|
||||||
|
@ -774,7 +775,7 @@ func deserializeUtxoEntry(serialized []byte) (*UtxoEntry, error) {
|
||||||
//
|
//
|
||||||
// When there is no entry for the provided hash, nil will be returned for the
|
// When there is no entry for the provided hash, nil will be returned for the
|
||||||
// both the entry and the error.
|
// both the entry and the error.
|
||||||
func dbFetchUtxoEntry(dbTx database.Tx, hash *wire.ShaHash) (*UtxoEntry, error) {
|
func dbFetchUtxoEntry(dbTx database.Tx, hash *chainhash.Hash) (*UtxoEntry, error) {
|
||||||
// Fetch the unspent transaction output information for the passed
|
// Fetch the unspent transaction output information for the passed
|
||||||
// transaction hash. Return now when there is no entry.
|
// transaction hash. Return now when there is no entry.
|
||||||
utxoBucket := dbTx.Metadata().Bucket(utxoSetBucketName)
|
utxoBucket := dbTx.Metadata().Bucket(utxoSetBucketName)
|
||||||
|
@ -867,14 +868,14 @@ func dbPutUtxoView(dbTx database.Tx, view *UtxoViewpoint) error {
|
||||||
// The serialized format for values in the height to hash bucket is:
|
// The serialized format for values in the height to hash bucket is:
|
||||||
// <hash>
|
// <hash>
|
||||||
//
|
//
|
||||||
// Field Type Size
|
// Field Type Size
|
||||||
// hash wire.ShaHash wire.HashSize
|
// hash chainhash.Hash chainhash.HashSize
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
// dbPutBlockIndex uses an existing database transaction to update or add the
|
// dbPutBlockIndex uses an existing database transaction to update or add the
|
||||||
// block index entries for the hash to height and height to hash mappings for
|
// block index entries for the hash to height and height to hash mappings for
|
||||||
// the provided values.
|
// the provided values.
|
||||||
func dbPutBlockIndex(dbTx database.Tx, hash *wire.ShaHash, height int32) error {
|
func dbPutBlockIndex(dbTx database.Tx, hash *chainhash.Hash, height int32) error {
|
||||||
// Serialize the height for use in the index entries.
|
// Serialize the height for use in the index entries.
|
||||||
var serializedHeight [4]byte
|
var serializedHeight [4]byte
|
||||||
byteOrder.PutUint32(serializedHeight[:], uint32(height))
|
byteOrder.PutUint32(serializedHeight[:], uint32(height))
|
||||||
|
@ -894,7 +895,7 @@ func dbPutBlockIndex(dbTx database.Tx, hash *wire.ShaHash, height int32) error {
|
||||||
// dbRemoveBlockIndex uses an existing database transaction remove block index
|
// dbRemoveBlockIndex uses an existing database transaction remove block index
|
||||||
// entries from the hash to height and height to hash mappings for the provided
|
// entries from the hash to height and height to hash mappings for the provided
|
||||||
// values.
|
// values.
|
||||||
func dbRemoveBlockIndex(dbTx database.Tx, hash *wire.ShaHash, height int32) error {
|
func dbRemoveBlockIndex(dbTx database.Tx, hash *chainhash.Hash, height int32) error {
|
||||||
// Remove the block hash to height mapping.
|
// Remove the block hash to height mapping.
|
||||||
meta := dbTx.Metadata()
|
meta := dbTx.Metadata()
|
||||||
hashIndex := meta.Bucket(hashIndexBucketName)
|
hashIndex := meta.Bucket(hashIndexBucketName)
|
||||||
|
@ -911,7 +912,7 @@ func dbRemoveBlockIndex(dbTx database.Tx, hash *wire.ShaHash, height int32) erro
|
||||||
|
|
||||||
// dbFetchHeightByHash uses an existing database transaction to retrieve the
|
// dbFetchHeightByHash uses an existing database transaction to retrieve the
|
||||||
// height for the provided hash from the index.
|
// height for the provided hash from the index.
|
||||||
func dbFetchHeightByHash(dbTx database.Tx, hash *wire.ShaHash) (int32, error) {
|
func dbFetchHeightByHash(dbTx database.Tx, hash *chainhash.Hash) (int32, error) {
|
||||||
meta := dbTx.Metadata()
|
meta := dbTx.Metadata()
|
||||||
hashIndex := meta.Bucket(hashIndexBucketName)
|
hashIndex := meta.Bucket(hashIndexBucketName)
|
||||||
serializedHeight := hashIndex.Get(hash[:])
|
serializedHeight := hashIndex.Get(hash[:])
|
||||||
|
@ -925,7 +926,7 @@ func dbFetchHeightByHash(dbTx database.Tx, hash *wire.ShaHash) (int32, error) {
|
||||||
|
|
||||||
// dbFetchHashByHeight uses an existing database transaction to retrieve the
|
// dbFetchHashByHeight uses an existing database transaction to retrieve the
|
||||||
// hash for the provided height from the index.
|
// hash for the provided height from the index.
|
||||||
func dbFetchHashByHeight(dbTx database.Tx, height int32) (*wire.ShaHash, error) {
|
func dbFetchHashByHeight(dbTx database.Tx, height int32) (*chainhash.Hash, error) {
|
||||||
var serializedHeight [4]byte
|
var serializedHeight [4]byte
|
||||||
byteOrder.PutUint32(serializedHeight[:], uint32(height))
|
byteOrder.PutUint32(serializedHeight[:], uint32(height))
|
||||||
|
|
||||||
|
@ -937,7 +938,7 @@ func dbFetchHashByHeight(dbTx database.Tx, height int32) (*wire.ShaHash, error)
|
||||||
return nil, errNotInMainChain(str)
|
return nil, errNotInMainChain(str)
|
||||||
}
|
}
|
||||||
|
|
||||||
var hash wire.ShaHash
|
var hash chainhash.Hash
|
||||||
copy(hash[:], hashBytes)
|
copy(hash[:], hashBytes)
|
||||||
return &hash, nil
|
return &hash, nil
|
||||||
}
|
}
|
||||||
|
@ -951,18 +952,18 @@ func dbFetchHashByHeight(dbTx database.Tx, height int32) (*wire.ShaHash, error)
|
||||||
//
|
//
|
||||||
// <block hash><block height><total txns><work sum length><work sum>
|
// <block hash><block height><total txns><work sum length><work sum>
|
||||||
//
|
//
|
||||||
// Field Type Size
|
// Field Type Size
|
||||||
// block hash wire.ShaHash wire.HashSize
|
// block hash chainhash.Hash chainhash.HashSize
|
||||||
// block height uint32 4 bytes
|
// block height uint32 4 bytes
|
||||||
// total txns uint64 8 bytes
|
// total txns uint64 8 bytes
|
||||||
// work sum length uint32 4 bytes
|
// work sum length uint32 4 bytes
|
||||||
// work sum big.Int work sum length
|
// work sum big.Int work sum length
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
// bestChainState represents the data to be stored the database for the current
|
// bestChainState represents the data to be stored the database for the current
|
||||||
// best chain state.
|
// best chain state.
|
||||||
type bestChainState struct {
|
type bestChainState struct {
|
||||||
hash wire.ShaHash
|
hash chainhash.Hash
|
||||||
height uint32
|
height uint32
|
||||||
totalTxns uint64
|
totalTxns uint64
|
||||||
workSum *big.Int
|
workSum *big.Int
|
||||||
|
@ -974,12 +975,12 @@ func serializeBestChainState(state bestChainState) []byte {
|
||||||
// Calculate the full size needed to serialize the chain state.
|
// Calculate the full size needed to serialize the chain state.
|
||||||
workSumBytes := state.workSum.Bytes()
|
workSumBytes := state.workSum.Bytes()
|
||||||
workSumBytesLen := uint32(len(workSumBytes))
|
workSumBytesLen := uint32(len(workSumBytes))
|
||||||
serializedLen := wire.HashSize + 4 + 8 + 4 + workSumBytesLen
|
serializedLen := chainhash.HashSize + 4 + 8 + 4 + workSumBytesLen
|
||||||
|
|
||||||
// Serialize the chain state.
|
// Serialize the chain state.
|
||||||
serializedData := make([]byte, serializedLen)
|
serializedData := make([]byte, serializedLen)
|
||||||
copy(serializedData[0:wire.HashSize], state.hash[:])
|
copy(serializedData[0:chainhash.HashSize], state.hash[:])
|
||||||
offset := uint32(wire.HashSize)
|
offset := uint32(chainhash.HashSize)
|
||||||
byteOrder.PutUint32(serializedData[offset:], state.height)
|
byteOrder.PutUint32(serializedData[offset:], state.height)
|
||||||
offset += 4
|
offset += 4
|
||||||
byteOrder.PutUint64(serializedData[offset:], state.totalTxns)
|
byteOrder.PutUint64(serializedData[offset:], state.totalTxns)
|
||||||
|
@ -997,7 +998,7 @@ func serializeBestChainState(state bestChainState) []byte {
|
||||||
func deserializeBestChainState(serializedData []byte) (bestChainState, error) {
|
func deserializeBestChainState(serializedData []byte) (bestChainState, error) {
|
||||||
// Ensure the serialized data has enough bytes to properly deserialize
|
// Ensure the serialized data has enough bytes to properly deserialize
|
||||||
// the hash, height, total transactions, and work sum length.
|
// the hash, height, total transactions, and work sum length.
|
||||||
if len(serializedData) < wire.HashSize+16 {
|
if len(serializedData) < chainhash.HashSize+16 {
|
||||||
return bestChainState{}, database.Error{
|
return bestChainState{}, database.Error{
|
||||||
ErrorCode: database.ErrCorruption,
|
ErrorCode: database.ErrCorruption,
|
||||||
Description: "corrupt best chain state",
|
Description: "corrupt best chain state",
|
||||||
|
@ -1005,8 +1006,8 @@ func deserializeBestChainState(serializedData []byte) (bestChainState, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
state := bestChainState{}
|
state := bestChainState{}
|
||||||
copy(state.hash[:], serializedData[0:wire.HashSize])
|
copy(state.hash[:], serializedData[0:chainhash.HashSize])
|
||||||
offset := uint32(wire.HashSize)
|
offset := uint32(chainhash.HashSize)
|
||||||
state.height = byteOrder.Uint32(serializedData[offset : offset+4])
|
state.height = byteOrder.Uint32(serializedData[offset : offset+4])
|
||||||
offset += 4
|
offset += 4
|
||||||
state.totalTxns = byteOrder.Uint64(serializedData[offset : offset+8])
|
state.totalTxns = byteOrder.Uint64(serializedData[offset : offset+8])
|
||||||
|
@ -1050,7 +1051,7 @@ func (b *BlockChain) createChainState() error {
|
||||||
// Create a new node from the genesis block and set it as the best node.
|
// Create a new node from the genesis block and set it as the best node.
|
||||||
genesisBlock := btcutil.NewBlock(b.chainParams.GenesisBlock)
|
genesisBlock := btcutil.NewBlock(b.chainParams.GenesisBlock)
|
||||||
header := &genesisBlock.MsgBlock().Header
|
header := &genesisBlock.MsgBlock().Header
|
||||||
node := newBlockNode(header, genesisBlock.Sha(), 0)
|
node := newBlockNode(header, genesisBlock.Hash(), 0)
|
||||||
node.inMainChain = true
|
node.inMainChain = true
|
||||||
b.bestNode = node
|
b.bestNode = node
|
||||||
|
|
||||||
|
@ -1183,7 +1184,7 @@ func (b *BlockChain) initChainState() error {
|
||||||
|
|
||||||
// dbFetchHeaderByHash uses an existing database transaction to retrieve the
|
// dbFetchHeaderByHash uses an existing database transaction to retrieve the
|
||||||
// block header for the provided hash.
|
// block header for the provided hash.
|
||||||
func dbFetchHeaderByHash(dbTx database.Tx, hash *wire.ShaHash) (*wire.BlockHeader, error) {
|
func dbFetchHeaderByHash(dbTx database.Tx, hash *chainhash.Hash) (*wire.BlockHeader, error) {
|
||||||
headerBytes, err := dbTx.FetchBlockHeader(hash)
|
headerBytes, err := dbTx.FetchBlockHeader(hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -1212,7 +1213,7 @@ func dbFetchHeaderByHeight(dbTx database.Tx, height int32) (*wire.BlockHeader, e
|
||||||
// dbFetchBlockByHash uses an existing database transaction to retrieve the raw
|
// dbFetchBlockByHash uses an existing database transaction to retrieve the raw
|
||||||
// block for the provided hash, deserialize it, retrieve the appropriate height
|
// block for the provided hash, deserialize it, retrieve the appropriate height
|
||||||
// from the index, and return a btcutil.Block with the height set.
|
// from the index, and return a btcutil.Block with the height set.
|
||||||
func dbFetchBlockByHash(dbTx database.Tx, hash *wire.ShaHash) (*btcutil.Block, error) {
|
func dbFetchBlockByHash(dbTx database.Tx, hash *chainhash.Hash) (*btcutil.Block, error) {
|
||||||
// First find the height associated with the provided hash in the index.
|
// First find the height associated with the provided hash in the index.
|
||||||
blockHeight, err := dbFetchHeightByHash(dbTx, hash)
|
blockHeight, err := dbFetchHeightByHash(dbTx, hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1263,7 +1264,7 @@ func dbFetchBlockByHeight(dbTx database.Tx, height int32) (*btcutil.Block, error
|
||||||
|
|
||||||
// dbMainChainHasBlock uses an existing database transaction to return whether
|
// dbMainChainHasBlock uses an existing database transaction to return whether
|
||||||
// or not the main chain contains the block identified by the provided hash.
|
// or not the main chain contains the block identified by the provided hash.
|
||||||
func dbMainChainHasBlock(dbTx database.Tx, hash *wire.ShaHash) bool {
|
func dbMainChainHasBlock(dbTx database.Tx, hash *chainhash.Hash) bool {
|
||||||
hashIndex := dbTx.Metadata().Bucket(hashIndexBucketName)
|
hashIndex := dbTx.Metadata().Bucket(hashIndexBucketName)
|
||||||
return hashIndex.Get(hash[:]) != nil
|
return hashIndex.Get(hash[:]) != nil
|
||||||
}
|
}
|
||||||
|
@ -1272,7 +1273,7 @@ func dbMainChainHasBlock(dbTx database.Tx, hash *wire.ShaHash) bool {
|
||||||
// the main chain.
|
// the main chain.
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (b *BlockChain) MainChainHasBlock(hash *wire.ShaHash) (bool, error) {
|
func (b *BlockChain) MainChainHasBlock(hash *chainhash.Hash) (bool, error) {
|
||||||
var exists bool
|
var exists bool
|
||||||
err := b.db.View(func(dbTx database.Tx) error {
|
err := b.db.View(func(dbTx database.Tx) error {
|
||||||
exists = dbMainChainHasBlock(dbTx, hash)
|
exists = dbMainChainHasBlock(dbTx, hash)
|
||||||
|
@ -1285,7 +1286,7 @@ func (b *BlockChain) MainChainHasBlock(hash *wire.ShaHash) (bool, error) {
|
||||||
// main chain.
|
// main chain.
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (b *BlockChain) BlockHeightByHash(hash *wire.ShaHash) (int32, error) {
|
func (b *BlockChain) BlockHeightByHash(hash *chainhash.Hash) (int32, error) {
|
||||||
var height int32
|
var height int32
|
||||||
err := b.db.View(func(dbTx database.Tx) error {
|
err := b.db.View(func(dbTx database.Tx) error {
|
||||||
var err error
|
var err error
|
||||||
|
@ -1299,8 +1300,8 @@ func (b *BlockChain) BlockHeightByHash(hash *wire.ShaHash) (int32, error) {
|
||||||
// main chain.
|
// main chain.
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (b *BlockChain) BlockHashByHeight(blockHeight int32) (*wire.ShaHash, error) {
|
func (b *BlockChain) BlockHashByHeight(blockHeight int32) (*chainhash.Hash, error) {
|
||||||
var hash *wire.ShaHash
|
var hash *chainhash.Hash
|
||||||
err := b.db.View(func(dbTx database.Tx) error {
|
err := b.db.View(func(dbTx database.Tx) error {
|
||||||
var err error
|
var err error
|
||||||
hash, err = dbFetchHashByHeight(dbTx, blockHeight)
|
hash, err = dbFetchHashByHeight(dbTx, blockHeight)
|
||||||
|
@ -1326,7 +1327,7 @@ func (b *BlockChain) BlockByHeight(blockHeight int32) (*btcutil.Block, error) {
|
||||||
// the appropriate chain height set.
|
// the appropriate chain height set.
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (b *BlockChain) BlockByHash(hash *wire.ShaHash) (*btcutil.Block, error) {
|
func (b *BlockChain) BlockByHash(hash *chainhash.Hash) (*btcutil.Block, error) {
|
||||||
var block *btcutil.Block
|
var block *btcutil.Block
|
||||||
err := b.db.View(func(dbTx database.Tx) error {
|
err := b.db.View(func(dbTx database.Tx) error {
|
||||||
var err error
|
var err error
|
||||||
|
@ -1341,7 +1342,7 @@ func (b *BlockChain) BlockByHash(hash *wire.ShaHash) (*btcutil.Block, error) {
|
||||||
// height. The end height will be limited to the current main chain height.
|
// height. The end height will be limited to the current main chain height.
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (b *BlockChain) HeightRange(startHeight, endHeight int32) ([]wire.ShaHash, error) {
|
func (b *BlockChain) HeightRange(startHeight, endHeight int32) ([]chainhash.Hash, error) {
|
||||||
// Ensure requested heights are sane.
|
// Ensure requested heights are sane.
|
||||||
if startHeight < 0 {
|
if startHeight < 0 {
|
||||||
return nil, fmt.Errorf("start height of fetch range must not "+
|
return nil, fmt.Errorf("start height of fetch range must not "+
|
||||||
|
@ -1377,9 +1378,9 @@ func (b *BlockChain) HeightRange(startHeight, endHeight int32) ([]wire.ShaHash,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch as many as are available within the specified range.
|
// Fetch as many as are available within the specified range.
|
||||||
var hashList []wire.ShaHash
|
var hashList []chainhash.Hash
|
||||||
err := b.db.View(func(dbTx database.Tx) error {
|
err := b.db.View(func(dbTx database.Tx) error {
|
||||||
hashes := make([]wire.ShaHash, 0, endHeight-startHeight)
|
hashes := make([]chainhash.Hash, 0, endHeight-startHeight)
|
||||||
for i := startHeight; i < endHeight; i++ {
|
for i := startHeight; i < endHeight; i++ {
|
||||||
hash, err := dbFetchHashByHeight(dbTx, i)
|
hash, err := dbFetchHashByHeight(dbTx, i)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/database"
|
"github.com/btcsuite/btcd/database"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
)
|
)
|
||||||
|
@ -264,7 +265,7 @@ func TestSpendJournalSerialization(t *testing.T) {
|
||||||
Version: 1,
|
Version: 1,
|
||||||
TxIn: []*wire.TxIn{{
|
TxIn: []*wire.TxIn{{
|
||||||
PreviousOutPoint: wire.OutPoint{
|
PreviousOutPoint: wire.OutPoint{
|
||||||
Hash: *newShaHashFromStr("0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9"),
|
Hash: *newHashFromStr("0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9"),
|
||||||
Index: 0,
|
Index: 0,
|
||||||
},
|
},
|
||||||
SignatureScript: hexToBytes("47304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901"),
|
SignatureScript: hexToBytes("47304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901"),
|
||||||
|
@ -300,7 +301,7 @@ func TestSpendJournalSerialization(t *testing.T) {
|
||||||
Version: 1,
|
Version: 1,
|
||||||
TxIn: []*wire.TxIn{{
|
TxIn: []*wire.TxIn{{
|
||||||
PreviousOutPoint: wire.OutPoint{
|
PreviousOutPoint: wire.OutPoint{
|
||||||
Hash: *newShaHashFromStr("c0ed017828e59ad5ed3cf70ee7c6fb0f426433047462477dc7a5d470f987a537"),
|
Hash: *newHashFromStr("c0ed017828e59ad5ed3cf70ee7c6fb0f426433047462477dc7a5d470f987a537"),
|
||||||
Index: 1,
|
Index: 1,
|
||||||
},
|
},
|
||||||
SignatureScript: hexToBytes("493046022100c167eead9840da4a033c9a56470d7794a9bb1605b377ebe5688499b39f94be59022100fb6345cab4324f9ea0b9ee9169337534834638d818129778370f7d378ee4a325014104d962cac5390f12ddb7539507065d0def320d68c040f2e73337c3a1aaaab7195cb5c4d02e0959624d534f3c10c3cf3d73ca5065ebd62ae986b04c6d090d32627c"),
|
SignatureScript: hexToBytes("493046022100c167eead9840da4a033c9a56470d7794a9bb1605b377ebe5688499b39f94be59022100fb6345cab4324f9ea0b9ee9169337534834638d818129778370f7d378ee4a325014104d962cac5390f12ddb7539507065d0def320d68c040f2e73337c3a1aaaab7195cb5c4d02e0959624d534f3c10c3cf3d73ca5065ebd62ae986b04c6d090d32627c"),
|
||||||
|
@ -318,7 +319,7 @@ func TestSpendJournalSerialization(t *testing.T) {
|
||||||
Version: 1,
|
Version: 1,
|
||||||
TxIn: []*wire.TxIn{{
|
TxIn: []*wire.TxIn{{
|
||||||
PreviousOutPoint: wire.OutPoint{
|
PreviousOutPoint: wire.OutPoint{
|
||||||
Hash: *newShaHashFromStr("92fbe1d4be82f765dfabc9559d4620864b05cc897c4db0e29adac92d294e52b7"),
|
Hash: *newHashFromStr("92fbe1d4be82f765dfabc9559d4620864b05cc897c4db0e29adac92d294e52b7"),
|
||||||
Index: 0,
|
Index: 0,
|
||||||
},
|
},
|
||||||
SignatureScript: hexToBytes("483045022100e256743154c097465cf13e89955e1c9ff2e55c46051b627751dee0144183157e02201d8d4f02cde8496aae66768f94d35ce54465bd4ae8836004992d3216a93a13f00141049d23ce8686fe9b802a7a938e8952174d35dd2c2089d4112001ed8089023ab4f93a3c9fcd5bfeaa9727858bf640dc1b1c05ec3b434bb59837f8640e8810e87742"),
|
SignatureScript: hexToBytes("483045022100e256743154c097465cf13e89955e1c9ff2e55c46051b627751dee0144183157e02201d8d4f02cde8496aae66768f94d35ce54465bd4ae8836004992d3216a93a13f00141049d23ce8686fe9b802a7a938e8952174d35dd2c2089d4112001ed8089023ab4f93a3c9fcd5bfeaa9727858bf640dc1b1c05ec3b434bb59837f8640e8810e87742"),
|
||||||
|
@ -333,8 +334,8 @@ func TestSpendJournalSerialization(t *testing.T) {
|
||||||
}},
|
}},
|
||||||
LockTime: 0,
|
LockTime: 0,
|
||||||
}},
|
}},
|
||||||
utxoView: &UtxoViewpoint{entries: map[wire.ShaHash]*UtxoEntry{
|
utxoView: &UtxoViewpoint{entries: map[chainhash.Hash]*UtxoEntry{
|
||||||
*newShaHashFromStr("c0ed017828e59ad5ed3cf70ee7c6fb0f426433047462477dc7a5d470f987a537"): {
|
*newHashFromStr("c0ed017828e59ad5ed3cf70ee7c6fb0f426433047462477dc7a5d470f987a537"): {
|
||||||
version: 1,
|
version: 1,
|
||||||
isCoinBase: false,
|
isCoinBase: false,
|
||||||
blockHeight: 100024,
|
blockHeight: 100024,
|
||||||
|
@ -364,14 +365,14 @@ func TestSpendJournalSerialization(t *testing.T) {
|
||||||
Version: 1,
|
Version: 1,
|
||||||
TxIn: []*wire.TxIn{{
|
TxIn: []*wire.TxIn{{
|
||||||
PreviousOutPoint: wire.OutPoint{
|
PreviousOutPoint: wire.OutPoint{
|
||||||
Hash: *newShaHashFromStr("c0ed017828e59ad5ed3cf70ee7c6fb0f426433047462477dc7a5d470f987a537"),
|
Hash: *newHashFromStr("c0ed017828e59ad5ed3cf70ee7c6fb0f426433047462477dc7a5d470f987a537"),
|
||||||
Index: 1,
|
Index: 1,
|
||||||
},
|
},
|
||||||
SignatureScript: hexToBytes(""),
|
SignatureScript: hexToBytes(""),
|
||||||
Sequence: 0xffffffff,
|
Sequence: 0xffffffff,
|
||||||
}, {
|
}, {
|
||||||
PreviousOutPoint: wire.OutPoint{
|
PreviousOutPoint: wire.OutPoint{
|
||||||
Hash: *newShaHashFromStr("c0ed017828e59ad5ed3cf70ee7c6fb0f426433047462477dc7a5d470f987a537"),
|
Hash: *newHashFromStr("c0ed017828e59ad5ed3cf70ee7c6fb0f426433047462477dc7a5d470f987a537"),
|
||||||
Index: 2,
|
Index: 2,
|
||||||
},
|
},
|
||||||
SignatureScript: hexToBytes(""),
|
SignatureScript: hexToBytes(""),
|
||||||
|
@ -386,8 +387,8 @@ func TestSpendJournalSerialization(t *testing.T) {
|
||||||
}},
|
}},
|
||||||
LockTime: 0,
|
LockTime: 0,
|
||||||
}},
|
}},
|
||||||
utxoView: &UtxoViewpoint{entries: map[wire.ShaHash]*UtxoEntry{
|
utxoView: &UtxoViewpoint{entries: map[chainhash.Hash]*UtxoEntry{
|
||||||
*newShaHashFromStr("c0ed017828e59ad5ed3cf70ee7c6fb0f426433047462477dc7a5d470f987a537"): {
|
*newHashFromStr("c0ed017828e59ad5ed3cf70ee7c6fb0f426433047462477dc7a5d470f987a537"): {
|
||||||
version: 1,
|
version: 1,
|
||||||
isCoinBase: false,
|
isCoinBase: false,
|
||||||
blockHeight: 100000,
|
blockHeight: 100000,
|
||||||
|
@ -456,7 +457,7 @@ func TestSpendJournalErrors(t *testing.T) {
|
||||||
Version: 1,
|
Version: 1,
|
||||||
TxIn: []*wire.TxIn{{
|
TxIn: []*wire.TxIn{{
|
||||||
PreviousOutPoint: wire.OutPoint{
|
PreviousOutPoint: wire.OutPoint{
|
||||||
Hash: *newShaHashFromStr("0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9"),
|
Hash: *newHashFromStr("0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9"),
|
||||||
Index: 0,
|
Index: 0,
|
||||||
},
|
},
|
||||||
SignatureScript: hexToBytes("47304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901"),
|
SignatureScript: hexToBytes("47304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901"),
|
||||||
|
@ -474,7 +475,7 @@ func TestSpendJournalErrors(t *testing.T) {
|
||||||
Version: 1,
|
Version: 1,
|
||||||
TxIn: []*wire.TxIn{{
|
TxIn: []*wire.TxIn{{
|
||||||
PreviousOutPoint: wire.OutPoint{
|
PreviousOutPoint: wire.OutPoint{
|
||||||
Hash: *newShaHashFromStr("0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9"),
|
Hash: *newHashFromStr("0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9"),
|
||||||
Index: 0,
|
Index: 0,
|
||||||
},
|
},
|
||||||
SignatureScript: hexToBytes("47304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901"),
|
SignatureScript: hexToBytes("47304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901"),
|
||||||
|
@ -927,7 +928,7 @@ func TestBestChainStateSerialization(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "genesis",
|
name: "genesis",
|
||||||
state: bestChainState{
|
state: bestChainState{
|
||||||
hash: *newShaHashFromStr("000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"),
|
hash: *newHashFromStr("000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"),
|
||||||
height: 0,
|
height: 0,
|
||||||
totalTxns: 1,
|
totalTxns: 1,
|
||||||
workSum: func() *big.Int {
|
workSum: func() *big.Int {
|
||||||
|
@ -940,7 +941,7 @@ func TestBestChainStateSerialization(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "block 1",
|
name: "block 1",
|
||||||
state: bestChainState{
|
state: bestChainState{
|
||||||
hash: *newShaHashFromStr("00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048"),
|
hash: *newHashFromStr("00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048"),
|
||||||
height: 1,
|
height: 1,
|
||||||
totalTxns: 2,
|
totalTxns: 2,
|
||||||
workSum: func() *big.Int {
|
workSum: func() *big.Int {
|
||||||
|
|
|
@ -8,9 +8,9 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/chaincfg"
|
"github.com/btcsuite/btcd/chaincfg"
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/database"
|
"github.com/btcsuite/btcd/database"
|
||||||
"github.com/btcsuite/btcd/txscript"
|
"github.com/btcsuite/btcd/txscript"
|
||||||
"github.com/btcsuite/btcd/wire"
|
|
||||||
"github.com/btcsuite/btcutil"
|
"github.com/btcsuite/btcutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -18,13 +18,13 @@ import (
|
||||||
// best block chain that a good checkpoint candidate must be.
|
// best block chain that a good checkpoint candidate must be.
|
||||||
const CheckpointConfirmations = 2016
|
const CheckpointConfirmations = 2016
|
||||||
|
|
||||||
// newShaHashFromStr converts the passed big-endian hex string into a
|
// newHashFromStr converts the passed big-endian hex string into a
|
||||||
// wire.ShaHash. It only differs from the one available in wire in that
|
// chainhash.Hash. It only differs from the one available in chainhash in that
|
||||||
// it ignores the error since it will only (and must only) be called with
|
// it ignores the error since it will only (and must only) be called with
|
||||||
// hard-coded, and therefore known good, hashes.
|
// hard-coded, and therefore known good, hashes.
|
||||||
func newShaHashFromStr(hexStr string) *wire.ShaHash {
|
func newHashFromStr(hexStr string) *chainhash.Hash {
|
||||||
sha, _ := wire.NewShaHashFromStr(hexStr)
|
hash, _ := chainhash.NewHashFromStr(hexStr)
|
||||||
return sha
|
return hash
|
||||||
}
|
}
|
||||||
|
|
||||||
// DisableCheckpoints provides a mechanism to disable validation against
|
// DisableCheckpoints provides a mechanism to disable validation against
|
||||||
|
@ -85,7 +85,7 @@ func (b *BlockChain) LatestCheckpoint() *chaincfg.Checkpoint {
|
||||||
// checkpoint data for the passed block height.
|
// checkpoint data for the passed block height.
|
||||||
//
|
//
|
||||||
// This function MUST be called with the chain lock held (for reads).
|
// This function MUST be called with the chain lock held (for reads).
|
||||||
func (b *BlockChain) verifyCheckpoint(height int32, hash *wire.ShaHash) bool {
|
func (b *BlockChain) verifyCheckpoint(height int32, hash *chainhash.Hash) bool {
|
||||||
if b.noCheckpoints || len(b.chainParams.Checkpoints) == 0 {
|
if b.noCheckpoints || len(b.chainParams.Checkpoints) == 0 {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -269,7 +269,7 @@ func (b *BlockChain) IsCheckpointCandidate(block *btcutil.Block) (bool, error) {
|
||||||
var isCandidate bool
|
var isCandidate bool
|
||||||
err := b.db.View(func(dbTx database.Tx) error {
|
err := b.db.View(func(dbTx database.Tx) error {
|
||||||
// A checkpoint must be in the main chain.
|
// A checkpoint must be in the main chain.
|
||||||
blockHeight, err := dbFetchHeightByHash(dbTx, block.Sha())
|
blockHeight, err := dbFetchHeightByHash(dbTx, block.Hash())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Only return an error if it's not due to the block not
|
// Only return an error if it's not due to the block not
|
||||||
// being in the main chain.
|
// being in the main chain.
|
||||||
|
|
|
@ -15,6 +15,7 @@ import (
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/blockchain"
|
"github.com/btcsuite/btcd/blockchain"
|
||||||
"github.com/btcsuite/btcd/chaincfg"
|
"github.com/btcsuite/btcd/chaincfg"
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/database"
|
"github.com/btcsuite/btcd/database"
|
||||||
_ "github.com/btcsuite/btcd/database/ffldb"
|
_ "github.com/btcsuite/btcd/database/ffldb"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
|
@ -146,7 +147,7 @@ func loadUtxoView(filename string) (*blockchain.UtxoViewpoint, error) {
|
||||||
view := blockchain.NewUtxoViewpoint()
|
view := blockchain.NewUtxoViewpoint()
|
||||||
for {
|
for {
|
||||||
// Hash of the utxo entry.
|
// Hash of the utxo entry.
|
||||||
var hash wire.ShaHash
|
var hash chainhash.Hash
|
||||||
_, err := io.ReadAtLeast(r, hash[:], len(hash[:]))
|
_, err := io.ReadAtLeast(r, hash[:], len(hash[:]))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Expected EOF at the right offset.
|
// Expected EOF at the right offset.
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"math/big"
|
"math/big"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -52,11 +52,11 @@ var (
|
||||||
oneLsh256 = new(big.Int).Lsh(bigOne, 256)
|
oneLsh256 = new(big.Int).Lsh(bigOne, 256)
|
||||||
)
|
)
|
||||||
|
|
||||||
// ShaHashToBig converts a wire.ShaHash into a big.Int that can be used to
|
// HashToBig converts a chainhash.Hash into a big.Int that can be used to
|
||||||
// perform math comparisons.
|
// perform math comparisons.
|
||||||
func ShaHashToBig(hash *wire.ShaHash) *big.Int {
|
func HashToBig(hash *chainhash.Hash) *big.Int {
|
||||||
// A ShaHash is in little-endian, but the big package wants the bytes
|
// A Hash is in little-endian, but the big package wants the bytes in
|
||||||
// in big-endian, so reverse them.
|
// big-endian, so reverse them.
|
||||||
buf := *hash
|
buf := *hash
|
||||||
blen := len(buf)
|
blen := len(buf)
|
||||||
for i := 0; i < blen/2; i++ {
|
for i := 0; i < blen/2; i++ {
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/blockchain"
|
"github.com/btcsuite/btcd/blockchain"
|
||||||
"github.com/btcsuite/btcd/chaincfg"
|
"github.com/btcsuite/btcd/chaincfg"
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/database"
|
"github.com/btcsuite/btcd/database"
|
||||||
"github.com/btcsuite/btcd/txscript"
|
"github.com/btcsuite/btcd/txscript"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
|
@ -125,7 +126,7 @@ var (
|
||||||
|
|
||||||
// fetchBlockHashFunc defines a callback function to use in order to convert a
|
// fetchBlockHashFunc defines a callback function to use in order to convert a
|
||||||
// serialized block ID to an associated block hash.
|
// serialized block ID to an associated block hash.
|
||||||
type fetchBlockHashFunc func(serializedID []byte) (*wire.ShaHash, error)
|
type fetchBlockHashFunc func(serializedID []byte) (*chainhash.Hash, error)
|
||||||
|
|
||||||
// serializeAddrIndexEntry serializes the provided block id and transaction
|
// serializeAddrIndexEntry serializes the provided block id and transaction
|
||||||
// location according to the format described in detail above.
|
// location according to the format described in detail above.
|
||||||
|
@ -568,8 +569,8 @@ type AddrIndex struct {
|
||||||
// This allows fairly efficient updates when transactions are removed
|
// This allows fairly efficient updates when transactions are removed
|
||||||
// once they are included into a block.
|
// once they are included into a block.
|
||||||
unconfirmedLock sync.RWMutex
|
unconfirmedLock sync.RWMutex
|
||||||
txnsByAddr map[[addrKeySize]byte]map[wire.ShaHash]*btcutil.Tx
|
txnsByAddr map[[addrKeySize]byte]map[chainhash.Hash]*btcutil.Tx
|
||||||
addrsByTx map[wire.ShaHash]map[[addrKeySize]byte]struct{}
|
addrsByTx map[chainhash.Hash]map[[addrKeySize]byte]struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the AddrIndex type implements the Indexer interface.
|
// Ensure the AddrIndex type implements the Indexer interface.
|
||||||
|
@ -703,7 +704,7 @@ func (idx *AddrIndex) ConnectBlock(dbTx database.Tx, block *btcutil.Block, view
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the internal block ID associated with the block.
|
// Get the internal block ID associated with the block.
|
||||||
blockID, err := dbFetchBlockIDByHash(dbTx, block.Sha())
|
blockID, err := dbFetchBlockIDByHash(dbTx, block.Hash())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -771,7 +772,7 @@ func (idx *AddrIndex) TxRegionsForAddress(dbTx database.Tx, addr btcutil.Address
|
||||||
err = idx.db.View(func(dbTx database.Tx) error {
|
err = idx.db.View(func(dbTx database.Tx) error {
|
||||||
// Create closure to lookup the block hash given the ID using
|
// Create closure to lookup the block hash given the ID using
|
||||||
// the database transaction.
|
// the database transaction.
|
||||||
fetchBlockHash := func(id []byte) (*wire.ShaHash, error) {
|
fetchBlockHash := func(id []byte) (*chainhash.Hash, error) {
|
||||||
// Deserialize and populate the result.
|
// Deserialize and populate the result.
|
||||||
return dbFetchBlockHashBySerializedID(dbTx, id)
|
return dbFetchBlockHashBySerializedID(dbTx, id)
|
||||||
}
|
}
|
||||||
|
@ -809,16 +810,16 @@ func (idx *AddrIndex) indexUnconfirmedAddresses(pkScript []byte, tx *btcutil.Tx)
|
||||||
idx.unconfirmedLock.Lock()
|
idx.unconfirmedLock.Lock()
|
||||||
addrIndexEntry := idx.txnsByAddr[addrKey]
|
addrIndexEntry := idx.txnsByAddr[addrKey]
|
||||||
if addrIndexEntry == nil {
|
if addrIndexEntry == nil {
|
||||||
addrIndexEntry = make(map[wire.ShaHash]*btcutil.Tx)
|
addrIndexEntry = make(map[chainhash.Hash]*btcutil.Tx)
|
||||||
idx.txnsByAddr[addrKey] = addrIndexEntry
|
idx.txnsByAddr[addrKey] = addrIndexEntry
|
||||||
}
|
}
|
||||||
addrIndexEntry[*tx.Sha()] = tx
|
addrIndexEntry[*tx.Hash()] = tx
|
||||||
|
|
||||||
// Add a mapping from the transaction to the address.
|
// Add a mapping from the transaction to the address.
|
||||||
addrsByTxEntry := idx.addrsByTx[*tx.Sha()]
|
addrsByTxEntry := idx.addrsByTx[*tx.Hash()]
|
||||||
if addrsByTxEntry == nil {
|
if addrsByTxEntry == nil {
|
||||||
addrsByTxEntry = make(map[[addrKeySize]byte]struct{})
|
addrsByTxEntry = make(map[[addrKeySize]byte]struct{})
|
||||||
idx.addrsByTx[*tx.Sha()] = addrsByTxEntry
|
idx.addrsByTx[*tx.Hash()] = addrsByTxEntry
|
||||||
}
|
}
|
||||||
addrsByTxEntry[addrKey] = struct{}{}
|
addrsByTxEntry[addrKey] = struct{}{}
|
||||||
idx.unconfirmedLock.Unlock()
|
idx.unconfirmedLock.Unlock()
|
||||||
|
@ -862,7 +863,7 @@ func (idx *AddrIndex) AddUnconfirmedTx(tx *btcutil.Tx, utxoView *blockchain.Utxo
|
||||||
// (memory-only) address index.
|
// (memory-only) address index.
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (idx *AddrIndex) RemoveUnconfirmedTx(hash *wire.ShaHash) {
|
func (idx *AddrIndex) RemoveUnconfirmedTx(hash *chainhash.Hash) {
|
||||||
idx.unconfirmedLock.Lock()
|
idx.unconfirmedLock.Lock()
|
||||||
defer idx.unconfirmedLock.Unlock()
|
defer idx.unconfirmedLock.Unlock()
|
||||||
|
|
||||||
|
@ -920,8 +921,8 @@ func NewAddrIndex(db database.DB, chainParams *chaincfg.Params) *AddrIndex {
|
||||||
return &AddrIndex{
|
return &AddrIndex{
|
||||||
db: db,
|
db: db,
|
||||||
chainParams: chainParams,
|
chainParams: chainParams,
|
||||||
txnsByAddr: make(map[[addrKeySize]byte]map[wire.ShaHash]*btcutil.Tx),
|
txnsByAddr: make(map[[addrKeySize]byte]map[chainhash.Hash]*btcutil.Tx),
|
||||||
addrsByTx: make(map[wire.ShaHash]map[[addrKeySize]byte]struct{}),
|
addrsByTx: make(map[chainhash.Hash]map[[addrKeySize]byte]struct{}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/blockchain"
|
"github.com/btcsuite/btcd/blockchain"
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/database"
|
"github.com/btcsuite/btcd/database"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
"github.com/btcsuite/btcutil"
|
"github.com/btcsuite/btcutil"
|
||||||
|
@ -28,17 +29,17 @@ var (
|
||||||
//
|
//
|
||||||
// [<block hash><block height>],...
|
// [<block hash><block height>],...
|
||||||
//
|
//
|
||||||
// Field Type Size
|
// Field Type Size
|
||||||
// block hash wire.ShaHash wire.HashSize
|
// block hash chainhash.Hash chainhash.HashSize
|
||||||
// block height uint32 4 bytes
|
// block height uint32 4 bytes
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
// dbPutIndexerTip uses an existing database transaction to update or add the
|
// dbPutIndexerTip uses an existing database transaction to update or add the
|
||||||
// current tip for the given index to the provided values.
|
// current tip for the given index to the provided values.
|
||||||
func dbPutIndexerTip(dbTx database.Tx, idxKey []byte, hash *wire.ShaHash, height int32) error {
|
func dbPutIndexerTip(dbTx database.Tx, idxKey []byte, hash *chainhash.Hash, height int32) error {
|
||||||
serialized := make([]byte, wire.HashSize+4)
|
serialized := make([]byte, chainhash.HashSize+4)
|
||||||
copy(serialized, hash[:])
|
copy(serialized, hash[:])
|
||||||
byteOrder.PutUint32(serialized[wire.HashSize:], uint32(height))
|
byteOrder.PutUint32(serialized[chainhash.HashSize:], uint32(height))
|
||||||
|
|
||||||
indexesBucket := dbTx.Metadata().Bucket(indexTipsBucketName)
|
indexesBucket := dbTx.Metadata().Bucket(indexTipsBucketName)
|
||||||
return indexesBucket.Put(idxKey, serialized)
|
return indexesBucket.Put(idxKey, serialized)
|
||||||
|
@ -46,10 +47,10 @@ func dbPutIndexerTip(dbTx database.Tx, idxKey []byte, hash *wire.ShaHash, height
|
||||||
|
|
||||||
// dbFetchIndexerTip uses an existing database transaction to retrieve the
|
// dbFetchIndexerTip uses an existing database transaction to retrieve the
|
||||||
// hash and height of the current tip for the provided index.
|
// hash and height of the current tip for the provided index.
|
||||||
func dbFetchIndexerTip(dbTx database.Tx, idxKey []byte) (*wire.ShaHash, int32, error) {
|
func dbFetchIndexerTip(dbTx database.Tx, idxKey []byte) (*chainhash.Hash, int32, error) {
|
||||||
indexesBucket := dbTx.Metadata().Bucket(indexTipsBucketName)
|
indexesBucket := dbTx.Metadata().Bucket(indexTipsBucketName)
|
||||||
serialized := indexesBucket.Get(idxKey)
|
serialized := indexesBucket.Get(idxKey)
|
||||||
if len(serialized) < wire.HashSize+4 {
|
if len(serialized) < chainhash.HashSize+4 {
|
||||||
return nil, 0, database.Error{
|
return nil, 0, database.Error{
|
||||||
ErrorCode: database.ErrCorruption,
|
ErrorCode: database.ErrCorruption,
|
||||||
Description: fmt.Sprintf("unexpected end of data for "+
|
Description: fmt.Sprintf("unexpected end of data for "+
|
||||||
|
@ -57,9 +58,9 @@ func dbFetchIndexerTip(dbTx database.Tx, idxKey []byte) (*wire.ShaHash, int32, e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var hash wire.ShaHash
|
var hash chainhash.Hash
|
||||||
copy(hash[:], serialized[:wire.HashSize])
|
copy(hash[:], serialized[:chainhash.HashSize])
|
||||||
height := int32(byteOrder.Uint32(serialized[wire.HashSize:]))
|
height := int32(byteOrder.Uint32(serialized[chainhash.HashSize:]))
|
||||||
return &hash, height, nil
|
return &hash, height, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +80,7 @@ func dbIndexConnectBlock(dbTx database.Tx, indexer Indexer, block *btcutil.Block
|
||||||
return AssertError(fmt.Sprintf("dbIndexConnectBlock must be "+
|
return AssertError(fmt.Sprintf("dbIndexConnectBlock must be "+
|
||||||
"called with a block that extends the current index "+
|
"called with a block that extends the current index "+
|
||||||
"tip (%s, tip %s, block %s)", indexer.Name(),
|
"tip (%s, tip %s, block %s)", indexer.Name(),
|
||||||
curTipHash, block.Sha()))
|
curTipHash, block.Hash()))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notify the indexer with the connected block so it can index it.
|
// Notify the indexer with the connected block so it can index it.
|
||||||
|
@ -88,7 +89,7 @@ func dbIndexConnectBlock(dbTx database.Tx, indexer Indexer, block *btcutil.Block
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the current index tip.
|
// Update the current index tip.
|
||||||
return dbPutIndexerTip(dbTx, idxKey, block.Sha(), block.Height())
|
return dbPutIndexerTip(dbTx, idxKey, block.Hash(), block.Height())
|
||||||
}
|
}
|
||||||
|
|
||||||
// dbIndexDisconnectBlock removes all of the index entries associated with the
|
// dbIndexDisconnectBlock removes all of the index entries associated with the
|
||||||
|
@ -103,11 +104,11 @@ func dbIndexDisconnectBlock(dbTx database.Tx, indexer Indexer, block *btcutil.Bl
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !curTipHash.IsEqual(block.Sha()) {
|
if !curTipHash.IsEqual(block.Hash()) {
|
||||||
return AssertError(fmt.Sprintf("dbIndexDisconnectBlock must "+
|
return AssertError(fmt.Sprintf("dbIndexDisconnectBlock must "+
|
||||||
"be called with the block at the current index tip "+
|
"be called with the block at the current index tip "+
|
||||||
"(%s, tip %s, block %s)", indexer.Name(),
|
"(%s, tip %s, block %s)", indexer.Name(),
|
||||||
curTipHash, block.Sha()))
|
curTipHash, block.Hash()))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notify the indexer with the disconnected block so it can remove all
|
// Notify the indexer with the disconnected block so it can remove all
|
||||||
|
@ -207,7 +208,7 @@ func (m *Manager) maybeCreateIndexes(dbTx database.Tx) error {
|
||||||
|
|
||||||
// Set the tip for the index to values which represent an
|
// Set the tip for the index to values which represent an
|
||||||
// uninitialized index.
|
// uninitialized index.
|
||||||
err := dbPutIndexerTip(dbTx, idxKey, &wire.ShaHash{}, -1)
|
err := dbPutIndexerTip(dbTx, idxKey, &chainhash.Hash{}, -1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -266,7 +267,7 @@ func (m *Manager) Init(chain *blockchain.BlockChain) error {
|
||||||
|
|
||||||
// Fetch the current tip for the index.
|
// Fetch the current tip for the index.
|
||||||
var height int32
|
var height int32
|
||||||
var hash *wire.ShaHash
|
var hash *chainhash.Hash
|
||||||
err := m.db.View(func(dbTx database.Tx) error {
|
err := m.db.View(func(dbTx database.Tx) error {
|
||||||
idxKey := indexer.Key()
|
idxKey := indexer.Key()
|
||||||
hash, height, err = dbFetchIndexerTip(dbTx, idxKey)
|
hash, height, err = dbFetchIndexerTip(dbTx, idxKey)
|
||||||
|
@ -449,7 +450,7 @@ func indexNeedsInputs(index Indexer) bool {
|
||||||
|
|
||||||
// dbFetchTx looks up the passed transaction hash in the transaction index and
|
// dbFetchTx looks up the passed transaction hash in the transaction index and
|
||||||
// loads it from the database.
|
// loads it from the database.
|
||||||
func dbFetchTx(dbTx database.Tx, hash *wire.ShaHash) (*wire.MsgTx, error) {
|
func dbFetchTx(dbTx database.Tx, hash *chainhash.Hash) (*wire.MsgTx, error) {
|
||||||
// Look up the location of the transaction.
|
// Look up the location of the transaction.
|
||||||
blockRegion, err := dbFetchTxIndexEntry(dbTx, hash)
|
blockRegion, err := dbFetchTxIndexEntry(dbTx, hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/blockchain"
|
"github.com/btcsuite/btcd/blockchain"
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/database"
|
"github.com/btcsuite/btcd/database"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
"github.com/btcsuite/btcutil"
|
"github.com/btcsuite/btcutil"
|
||||||
|
@ -62,18 +63,18 @@ var (
|
||||||
// The serialized format for keys and values in the block hash to ID bucket is:
|
// The serialized format for keys and values in the block hash to ID bucket is:
|
||||||
// <hash> = <ID>
|
// <hash> = <ID>
|
||||||
//
|
//
|
||||||
// Field Type Size
|
// Field Type Size
|
||||||
// hash wire.ShaHash 32 bytes
|
// hash chainhash.Hash 32 bytes
|
||||||
// ID uint32 4 bytes
|
// ID uint32 4 bytes
|
||||||
// -----
|
// -----
|
||||||
// Total: 36 bytes
|
// Total: 36 bytes
|
||||||
//
|
//
|
||||||
// The serialized format for keys and values in the ID to block hash bucket is:
|
// The serialized format for keys and values in the ID to block hash bucket is:
|
||||||
// <ID> = <hash>
|
// <ID> = <hash>
|
||||||
//
|
//
|
||||||
// Field Type Size
|
// Field Type Size
|
||||||
// ID uint32 4 bytes
|
// ID uint32 4 bytes
|
||||||
// hash wire.ShaHash 32 bytes
|
// hash chainhash.Hash 32 bytes
|
||||||
// -----
|
// -----
|
||||||
// Total: 36 bytes
|
// Total: 36 bytes
|
||||||
//
|
//
|
||||||
|
@ -81,9 +82,9 @@ var (
|
||||||
//
|
//
|
||||||
// <txhash> = <block id><start offset><tx length>
|
// <txhash> = <block id><start offset><tx length>
|
||||||
//
|
//
|
||||||
// Field Type Size
|
// Field Type Size
|
||||||
// txhash wire.ShaHash 32 bytes
|
// txhash chainhash.Hash 32 bytes
|
||||||
// block id uint32 4 bytes
|
// block id uint32 4 bytes
|
||||||
// start offset uint32 4 bytes
|
// start offset uint32 4 bytes
|
||||||
// tx length uint32 4 bytes
|
// tx length uint32 4 bytes
|
||||||
// -----
|
// -----
|
||||||
|
@ -93,7 +94,7 @@ var (
|
||||||
// dbPutBlockIDIndexEntry uses an existing database transaction to update or add
|
// dbPutBlockIDIndexEntry uses an existing database transaction to update or add
|
||||||
// the index entries for the hash to id and id to hash mappings for the provided
|
// the index entries for the hash to id and id to hash mappings for the provided
|
||||||
// values.
|
// values.
|
||||||
func dbPutBlockIDIndexEntry(dbTx database.Tx, hash *wire.ShaHash, id uint32) error {
|
func dbPutBlockIDIndexEntry(dbTx database.Tx, hash *chainhash.Hash, id uint32) error {
|
||||||
// Serialize the height for use in the index entries.
|
// Serialize the height for use in the index entries.
|
||||||
var serializedID [4]byte
|
var serializedID [4]byte
|
||||||
byteOrder.PutUint32(serializedID[:], id)
|
byteOrder.PutUint32(serializedID[:], id)
|
||||||
|
@ -112,7 +113,7 @@ func dbPutBlockIDIndexEntry(dbTx database.Tx, hash *wire.ShaHash, id uint32) err
|
||||||
|
|
||||||
// dbRemoveBlockIDIndexEntry uses an existing database transaction remove index
|
// dbRemoveBlockIDIndexEntry uses an existing database transaction remove index
|
||||||
// entries from the hash to id and id to hash mappings for the provided hash.
|
// entries from the hash to id and id to hash mappings for the provided hash.
|
||||||
func dbRemoveBlockIDIndexEntry(dbTx database.Tx, hash *wire.ShaHash) error {
|
func dbRemoveBlockIDIndexEntry(dbTx database.Tx, hash *chainhash.Hash) error {
|
||||||
// Remove the block hash to ID mapping.
|
// Remove the block hash to ID mapping.
|
||||||
meta := dbTx.Metadata()
|
meta := dbTx.Metadata()
|
||||||
hashIndex := meta.Bucket(idByHashIndexBucketName)
|
hashIndex := meta.Bucket(idByHashIndexBucketName)
|
||||||
|
@ -131,7 +132,7 @@ func dbRemoveBlockIDIndexEntry(dbTx database.Tx, hash *wire.ShaHash) error {
|
||||||
|
|
||||||
// dbFetchBlockIDByHash uses an existing database transaction to retrieve the
|
// dbFetchBlockIDByHash uses an existing database transaction to retrieve the
|
||||||
// block id for the provided hash from the index.
|
// block id for the provided hash from the index.
|
||||||
func dbFetchBlockIDByHash(dbTx database.Tx, hash *wire.ShaHash) (uint32, error) {
|
func dbFetchBlockIDByHash(dbTx database.Tx, hash *chainhash.Hash) (uint32, error) {
|
||||||
hashIndex := dbTx.Metadata().Bucket(idByHashIndexBucketName)
|
hashIndex := dbTx.Metadata().Bucket(idByHashIndexBucketName)
|
||||||
serializedID := hashIndex.Get(hash[:])
|
serializedID := hashIndex.Get(hash[:])
|
||||||
if serializedID == nil {
|
if serializedID == nil {
|
||||||
|
@ -143,21 +144,21 @@ func dbFetchBlockIDByHash(dbTx database.Tx, hash *wire.ShaHash) (uint32, error)
|
||||||
|
|
||||||
// dbFetchBlockHashBySerializedID uses an existing database transaction to
|
// dbFetchBlockHashBySerializedID uses an existing database transaction to
|
||||||
// retrieve the hash for the provided serialized block id from the index.
|
// retrieve the hash for the provided serialized block id from the index.
|
||||||
func dbFetchBlockHashBySerializedID(dbTx database.Tx, serializedID []byte) (*wire.ShaHash, error) {
|
func dbFetchBlockHashBySerializedID(dbTx database.Tx, serializedID []byte) (*chainhash.Hash, error) {
|
||||||
idIndex := dbTx.Metadata().Bucket(hashByIDIndexBucketName)
|
idIndex := dbTx.Metadata().Bucket(hashByIDIndexBucketName)
|
||||||
hashBytes := idIndex.Get(serializedID)
|
hashBytes := idIndex.Get(serializedID)
|
||||||
if hashBytes == nil {
|
if hashBytes == nil {
|
||||||
return nil, errNoBlockIDEntry
|
return nil, errNoBlockIDEntry
|
||||||
}
|
}
|
||||||
|
|
||||||
var hash wire.ShaHash
|
var hash chainhash.Hash
|
||||||
copy(hash[:], hashBytes)
|
copy(hash[:], hashBytes)
|
||||||
return &hash, nil
|
return &hash, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// dbFetchBlockHashByID uses an existing database transaction to retrieve the
|
// dbFetchBlockHashByID uses an existing database transaction to retrieve the
|
||||||
// hash for the provided block id from the index.
|
// hash for the provided block id from the index.
|
||||||
func dbFetchBlockHashByID(dbTx database.Tx, id uint32) (*wire.ShaHash, error) {
|
func dbFetchBlockHashByID(dbTx database.Tx, id uint32) (*chainhash.Hash, error) {
|
||||||
var serializedID [4]byte
|
var serializedID [4]byte
|
||||||
byteOrder.PutUint32(serializedID[:], id)
|
byteOrder.PutUint32(serializedID[:], id)
|
||||||
return dbFetchBlockHashBySerializedID(dbTx, serializedID[:])
|
return dbFetchBlockHashBySerializedID(dbTx, serializedID[:])
|
||||||
|
@ -176,7 +177,7 @@ func putTxIndexEntry(target []byte, blockID uint32, txLoc wire.TxLoc) {
|
||||||
// dbPutTxIndexEntry uses an existing database transaction to update the
|
// dbPutTxIndexEntry uses an existing database transaction to update the
|
||||||
// transaction index given the provided serialized data that is expected to have
|
// transaction index given the provided serialized data that is expected to have
|
||||||
// been serialized putTxIndexEntry.
|
// been serialized putTxIndexEntry.
|
||||||
func dbPutTxIndexEntry(dbTx database.Tx, txHash *wire.ShaHash, serializedData []byte) error {
|
func dbPutTxIndexEntry(dbTx database.Tx, txHash *chainhash.Hash, serializedData []byte) error {
|
||||||
txIndex := dbTx.Metadata().Bucket(txIndexKey)
|
txIndex := dbTx.Metadata().Bucket(txIndexKey)
|
||||||
return txIndex.Put(txHash[:], serializedData)
|
return txIndex.Put(txHash[:], serializedData)
|
||||||
}
|
}
|
||||||
|
@ -185,7 +186,7 @@ func dbPutTxIndexEntry(dbTx database.Tx, txHash *wire.ShaHash, serializedData []
|
||||||
// region for the provided transaction hash from the transaction index. When
|
// region for the provided transaction hash from the transaction index. When
|
||||||
// there is no entry for the provided hash, nil will be returned for the both
|
// there is no entry for the provided hash, nil will be returned for the both
|
||||||
// the region and the error.
|
// the region and the error.
|
||||||
func dbFetchTxIndexEntry(dbTx database.Tx, txHash *wire.ShaHash) (*database.BlockRegion, error) {
|
func dbFetchTxIndexEntry(dbTx database.Tx, txHash *chainhash.Hash) (*database.BlockRegion, error) {
|
||||||
// Load the record from the database and return now if it doesn't exist.
|
// Load the record from the database and return now if it doesn't exist.
|
||||||
txIndex := dbTx.Metadata().Bucket(txIndexKey)
|
txIndex := dbTx.Metadata().Bucket(txIndexKey)
|
||||||
serializedData := txIndex.Get(txHash[:])
|
serializedData := txIndex.Get(txHash[:])
|
||||||
|
@ -213,7 +214,7 @@ func dbFetchTxIndexEntry(dbTx database.Tx, txHash *wire.ShaHash) (*database.Bloc
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deserialize the final entry.
|
// Deserialize the final entry.
|
||||||
region := database.BlockRegion{Hash: &wire.ShaHash{}}
|
region := database.BlockRegion{Hash: &chainhash.Hash{}}
|
||||||
copy(region.Hash[:], hash[:])
|
copy(region.Hash[:], hash[:])
|
||||||
region.Offset = byteOrder.Uint32(serializedData[4:8])
|
region.Offset = byteOrder.Uint32(serializedData[4:8])
|
||||||
region.Len = byteOrder.Uint32(serializedData[8:12])
|
region.Len = byteOrder.Uint32(serializedData[8:12])
|
||||||
|
@ -241,7 +242,7 @@ func dbAddTxIndexEntries(dbTx database.Tx, block *btcutil.Block, blockID uint32)
|
||||||
for i, tx := range block.Transactions() {
|
for i, tx := range block.Transactions() {
|
||||||
putTxIndexEntry(serializedValues[offset:], blockID, txLocs[i])
|
putTxIndexEntry(serializedValues[offset:], blockID, txLocs[i])
|
||||||
endOffset := offset + txEntrySize
|
endOffset := offset + txEntrySize
|
||||||
err := dbPutTxIndexEntry(dbTx, tx.Sha(),
|
err := dbPutTxIndexEntry(dbTx, tx.Hash(),
|
||||||
serializedValues[offset:endOffset:endOffset])
|
serializedValues[offset:endOffset:endOffset])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -254,7 +255,7 @@ func dbAddTxIndexEntries(dbTx database.Tx, block *btcutil.Block, blockID uint32)
|
||||||
|
|
||||||
// dbRemoveTxIndexEntry uses an existing database transaction to remove the most
|
// dbRemoveTxIndexEntry uses an existing database transaction to remove the most
|
||||||
// recent transaction index entry for the given hash.
|
// recent transaction index entry for the given hash.
|
||||||
func dbRemoveTxIndexEntry(dbTx database.Tx, txHash *wire.ShaHash) error {
|
func dbRemoveTxIndexEntry(dbTx database.Tx, txHash *chainhash.Hash) error {
|
||||||
txIndex := dbTx.Metadata().Bucket(txIndexKey)
|
txIndex := dbTx.Metadata().Bucket(txIndexKey)
|
||||||
serializedData := txIndex.Get(txHash[:])
|
serializedData := txIndex.Get(txHash[:])
|
||||||
if len(serializedData) == 0 {
|
if len(serializedData) == 0 {
|
||||||
|
@ -269,7 +270,7 @@ func dbRemoveTxIndexEntry(dbTx database.Tx, txHash *wire.ShaHash) error {
|
||||||
// latest transaction entry for every transaction in the passed block.
|
// latest transaction entry for every transaction in the passed block.
|
||||||
func dbRemoveTxIndexEntries(dbTx database.Tx, block *btcutil.Block) error {
|
func dbRemoveTxIndexEntries(dbTx database.Tx, block *btcutil.Block) error {
|
||||||
for _, tx := range block.Transactions() {
|
for _, tx := range block.Transactions() {
|
||||||
err := dbRemoveTxIndexEntry(dbTx, tx.Sha())
|
err := dbRemoveTxIndexEntry(dbTx, tx.Hash())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -397,7 +398,7 @@ func (idx *TxIndex) ConnectBlock(dbTx database.Tx, block *btcutil.Block, view *b
|
||||||
|
|
||||||
// Add the new block ID index entry for the block being connected and
|
// Add the new block ID index entry for the block being connected and
|
||||||
// update the current internal block ID accordingly.
|
// update the current internal block ID accordingly.
|
||||||
err := dbPutBlockIDIndexEntry(dbTx, block.Sha(), newBlockID)
|
err := dbPutBlockIDIndexEntry(dbTx, block.Hash(), newBlockID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -418,7 +419,7 @@ func (idx *TxIndex) DisconnectBlock(dbTx database.Tx, block *btcutil.Block, view
|
||||||
|
|
||||||
// Remove the block ID index entry for the block being disconnected and
|
// Remove the block ID index entry for the block being disconnected and
|
||||||
// decrement the current internal block ID to account for it.
|
// decrement the current internal block ID to account for it.
|
||||||
if err := dbRemoveBlockIDIndexEntry(dbTx, block.Sha()); err != nil {
|
if err := dbRemoveBlockIDIndexEntry(dbTx, block.Hash()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
idx.curBlockID--
|
idx.curBlockID--
|
||||||
|
@ -431,7 +432,7 @@ func (idx *TxIndex) DisconnectBlock(dbTx database.Tx, block *btcutil.Block, view
|
||||||
// will be returned for the both the entry and the error.
|
// will be returned for the both the entry and the error.
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (idx *TxIndex) TxBlockRegion(hash *wire.ShaHash) (*database.BlockRegion, error) {
|
func (idx *TxIndex) TxBlockRegion(hash *chainhash.Hash) (*database.BlockRegion, error) {
|
||||||
var region *database.BlockRegion
|
var region *database.BlockRegion
|
||||||
err := idx.db.View(func(dbTx database.Tx) error {
|
err := idx.db.View(func(dbTx database.Tx) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2013-2014 The btcsuite developers
|
// Copyright (c) 2013-2016 The btcsuite developers
|
||||||
// Use of this source code is governed by an ISC
|
// Use of this source code is governed by an ISC
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ package blockchain
|
||||||
import (
|
import (
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcutil"
|
"github.com/btcsuite/btcutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -28,14 +28,14 @@ func nextPowerOfTwo(n int) int {
|
||||||
// HashMerkleBranches takes two hashes, treated as the left and right tree
|
// HashMerkleBranches takes two hashes, treated as the left and right tree
|
||||||
// nodes, and returns the hash of their concatenation. This is a helper
|
// nodes, and returns the hash of their concatenation. This is a helper
|
||||||
// function used to aid in the generation of a merkle tree.
|
// function used to aid in the generation of a merkle tree.
|
||||||
func HashMerkleBranches(left *wire.ShaHash, right *wire.ShaHash) *wire.ShaHash {
|
func HashMerkleBranches(left *chainhash.Hash, right *chainhash.Hash) *chainhash.Hash {
|
||||||
// Concatenate the left and right nodes.
|
// Concatenate the left and right nodes.
|
||||||
var sha [wire.HashSize * 2]byte
|
var hash [chainhash.HashSize * 2]byte
|
||||||
copy(sha[:wire.HashSize], left[:])
|
copy(hash[:chainhash.HashSize], left[:])
|
||||||
copy(sha[wire.HashSize:], right[:])
|
copy(hash[chainhash.HashSize:], right[:])
|
||||||
|
|
||||||
newSha := wire.DoubleSha256SH(sha[:])
|
newHash := chainhash.DoubleHashH(hash[:])
|
||||||
return &newSha
|
return &newHash
|
||||||
}
|
}
|
||||||
|
|
||||||
// BuildMerkleTreeStore creates a merkle tree from a slice of transactions,
|
// BuildMerkleTreeStore creates a merkle tree from a slice of transactions,
|
||||||
|
@ -66,16 +66,16 @@ func HashMerkleBranches(left *wire.ShaHash, right *wire.ShaHash) *wire.ShaHash {
|
||||||
// are calculated by concatenating the left node with itself before hashing.
|
// are calculated by concatenating the left node with itself before hashing.
|
||||||
// Since this function uses nodes that are pointers to the hashes, empty nodes
|
// Since this function uses nodes that are pointers to the hashes, empty nodes
|
||||||
// will be nil.
|
// will be nil.
|
||||||
func BuildMerkleTreeStore(transactions []*btcutil.Tx) []*wire.ShaHash {
|
func BuildMerkleTreeStore(transactions []*btcutil.Tx) []*chainhash.Hash {
|
||||||
// Calculate how many entries are required to hold the binary merkle
|
// Calculate how many entries are required to hold the binary merkle
|
||||||
// tree as a linear array and create an array of that size.
|
// tree as a linear array and create an array of that size.
|
||||||
nextPoT := nextPowerOfTwo(len(transactions))
|
nextPoT := nextPowerOfTwo(len(transactions))
|
||||||
arraySize := nextPoT*2 - 1
|
arraySize := nextPoT*2 - 1
|
||||||
merkles := make([]*wire.ShaHash, arraySize)
|
merkles := make([]*chainhash.Hash, arraySize)
|
||||||
|
|
||||||
// Create the base transaction shas and populate the array with them.
|
// Create the base transaction hashes and populate the array with them.
|
||||||
for i, tx := range transactions {
|
for i, tx := range transactions {
|
||||||
merkles[i] = tx.Sha()
|
merkles[i] = tx.Hash()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start the array offset after the last transaction and adjusted to the
|
// Start the array offset after the last transaction and adjusted to the
|
||||||
|
@ -90,14 +90,14 @@ func BuildMerkleTreeStore(transactions []*btcutil.Tx) []*wire.ShaHash {
|
||||||
// When there is no right child, the parent is generated by
|
// When there is no right child, the parent is generated by
|
||||||
// hashing the concatenation of the left child with itself.
|
// hashing the concatenation of the left child with itself.
|
||||||
case merkles[i+1] == nil:
|
case merkles[i+1] == nil:
|
||||||
newSha := HashMerkleBranches(merkles[i], merkles[i])
|
newHash := HashMerkleBranches(merkles[i], merkles[i])
|
||||||
merkles[offset] = newSha
|
merkles[offset] = newHash
|
||||||
|
|
||||||
// The normal case sets the parent node to the double sha256
|
// The normal case sets the parent node to the double sha256
|
||||||
// of the concatentation of the left and right children.
|
// of the concatentation of the left and right children.
|
||||||
default:
|
default:
|
||||||
newSha := HashMerkleBranches(merkles[i], merkles[i+1])
|
newHash := HashMerkleBranches(merkles[i], merkles[i+1])
|
||||||
merkles[offset] = newSha
|
merkles[offset] = newHash
|
||||||
}
|
}
|
||||||
offset++
|
offset++
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,8 @@ package blockchain
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/database"
|
"github.com/btcsuite/btcd/database"
|
||||||
"github.com/btcsuite/btcd/wire"
|
|
||||||
"github.com/btcsuite/btcutil"
|
"github.com/btcsuite/btcutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ const (
|
||||||
// the main chain or any side chains.
|
// the main chain or any side chains.
|
||||||
//
|
//
|
||||||
// This function MUST be called with the chain state lock held (for reads).
|
// This function MUST be called with the chain state lock held (for reads).
|
||||||
func (b *BlockChain) blockExists(hash *wire.ShaHash) (bool, error) {
|
func (b *BlockChain) blockExists(hash *chainhash.Hash) (bool, error) {
|
||||||
// Check memory chain first (could be main chain or side chain blocks).
|
// Check memory chain first (could be main chain or side chain blocks).
|
||||||
if _, ok := b.index[*hash]; ok {
|
if _, ok := b.index[*hash]; ok {
|
||||||
return true, nil
|
return true, nil
|
||||||
|
@ -66,11 +66,11 @@ func (b *BlockChain) blockExists(hash *wire.ShaHash) (bool, error) {
|
||||||
// are needed to pass along to maybeAcceptBlock.
|
// are needed to pass along to maybeAcceptBlock.
|
||||||
//
|
//
|
||||||
// This function MUST be called with the chain state lock held (for writes).
|
// This function MUST be called with the chain state lock held (for writes).
|
||||||
func (b *BlockChain) processOrphans(hash *wire.ShaHash, flags BehaviorFlags) error {
|
func (b *BlockChain) processOrphans(hash *chainhash.Hash, flags BehaviorFlags) error {
|
||||||
// Start with processing at least the passed hash. Leave a little room
|
// Start with processing at least the passed hash. Leave a little room
|
||||||
// for additional orphan blocks that need to be processed without
|
// for additional orphan blocks that need to be processed without
|
||||||
// needing to grow the array in the common case.
|
// needing to grow the array in the common case.
|
||||||
processHashes := make([]*wire.ShaHash, 0, 10)
|
processHashes := make([]*chainhash.Hash, 0, 10)
|
||||||
processHashes = append(processHashes, hash)
|
processHashes = append(processHashes, hash)
|
||||||
for len(processHashes) > 0 {
|
for len(processHashes) > 0 {
|
||||||
// Pop the first hash to process from the slice.
|
// Pop the first hash to process from the slice.
|
||||||
|
@ -96,7 +96,7 @@ func (b *BlockChain) processOrphans(hash *wire.ShaHash, flags BehaviorFlags) err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the orphan from the orphan pool.
|
// Remove the orphan from the orphan pool.
|
||||||
orphanHash := orphan.block.Sha()
|
orphanHash := orphan.block.Hash()
|
||||||
b.removeOrphanBlock(orphan)
|
b.removeOrphanBlock(orphan)
|
||||||
i--
|
i--
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ func (b *BlockChain) ProcessBlock(block *btcutil.Block, flags BehaviorFlags) (bo
|
||||||
fastAdd := flags&BFFastAdd == BFFastAdd
|
fastAdd := flags&BFFastAdd == BFFastAdd
|
||||||
dryRun := flags&BFDryRun == BFDryRun
|
dryRun := flags&BFDryRun == BFDryRun
|
||||||
|
|
||||||
blockHash := block.Sha()
|
blockHash := block.Hash()
|
||||||
log.Tracef("Processing block %v", blockHash)
|
log.Tracef("Processing block %v", blockHash)
|
||||||
|
|
||||||
// The block must not already exist in the main chain or side chains.
|
// The block must not already exist in the main chain or side chains.
|
||||||
|
|
|
@ -61,7 +61,7 @@ out:
|
||||||
str := fmt.Sprintf("unable to find input "+
|
str := fmt.Sprintf("unable to find input "+
|
||||||
"transaction %v referenced from "+
|
"transaction %v referenced from "+
|
||||||
"transaction %v", originTxHash,
|
"transaction %v", originTxHash,
|
||||||
txVI.tx.Sha())
|
txVI.tx.Hash())
|
||||||
err := ruleError(ErrMissingTx, str)
|
err := ruleError(ErrMissingTx, str)
|
||||||
v.sendResult(err)
|
v.sendResult(err)
|
||||||
break out
|
break out
|
||||||
|
@ -74,7 +74,7 @@ out:
|
||||||
str := fmt.Sprintf("unable to find unspent "+
|
str := fmt.Sprintf("unable to find unspent "+
|
||||||
"output %v script referenced from "+
|
"output %v script referenced from "+
|
||||||
"transaction %s:%d",
|
"transaction %s:%d",
|
||||||
txIn.PreviousOutPoint, txVI.tx.Sha(),
|
txIn.PreviousOutPoint, txVI.tx.Hash(),
|
||||||
txVI.txInIndex)
|
txVI.txInIndex)
|
||||||
err := ruleError(ErrBadTxInput, str)
|
err := ruleError(ErrBadTxInput, str)
|
||||||
v.sendResult(err)
|
v.sendResult(err)
|
||||||
|
@ -89,7 +89,7 @@ out:
|
||||||
str := fmt.Sprintf("failed to parse input "+
|
str := fmt.Sprintf("failed to parse input "+
|
||||||
"%s:%d which references output %s:%d - "+
|
"%s:%d which references output %s:%d - "+
|
||||||
"%v (input script bytes %x, prev output "+
|
"%v (input script bytes %x, prev output "+
|
||||||
"script bytes %x)", txVI.tx.Sha(),
|
"script bytes %x)", txVI.tx.Hash(),
|
||||||
txVI.txInIndex, originTxHash,
|
txVI.txInIndex, originTxHash,
|
||||||
originTxIndex, err, sigScript, pkScript)
|
originTxIndex, err, sigScript, pkScript)
|
||||||
err := ruleError(ErrScriptMalformed, str)
|
err := ruleError(ErrScriptMalformed, str)
|
||||||
|
@ -102,7 +102,7 @@ out:
|
||||||
str := fmt.Sprintf("failed to validate input "+
|
str := fmt.Sprintf("failed to validate input "+
|
||||||
"%s:%d which references output %s:%d - "+
|
"%s:%d which references output %s:%d - "+
|
||||||
"%v (input script bytes %x, prev output "+
|
"%v (input script bytes %x, prev output "+
|
||||||
"script bytes %x)", txVI.tx.Sha(),
|
"script bytes %x)", txVI.tx.Hash(),
|
||||||
txVI.txInIndex, originTxHash,
|
txVI.txInIndex, originTxHash,
|
||||||
originTxIndex, err, sigScript, pkScript)
|
originTxIndex, err, sigScript, pkScript)
|
||||||
err := ruleError(ErrScriptValidation, str)
|
err := ruleError(ErrScriptValidation, str)
|
||||||
|
|
|
@ -7,9 +7,9 @@ package blockchain
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/database"
|
"github.com/btcsuite/btcd/database"
|
||||||
"github.com/btcsuite/btcd/txscript"
|
"github.com/btcsuite/btcd/txscript"
|
||||||
"github.com/btcsuite/btcd/wire"
|
|
||||||
"github.com/btcsuite/btcutil"
|
"github.com/btcsuite/btcutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -172,19 +172,19 @@ func newUtxoEntry(version int32, isCoinBase bool, blockHeight int32) *UtxoEntry
|
||||||
// The unspent outputs are needed by other transactions for things such as
|
// The unspent outputs are needed by other transactions for things such as
|
||||||
// script validation and double spend prevention.
|
// script validation and double spend prevention.
|
||||||
type UtxoViewpoint struct {
|
type UtxoViewpoint struct {
|
||||||
entries map[wire.ShaHash]*UtxoEntry
|
entries map[chainhash.Hash]*UtxoEntry
|
||||||
bestHash wire.ShaHash
|
bestHash chainhash.Hash
|
||||||
}
|
}
|
||||||
|
|
||||||
// BestHash returns the hash of the best block in the chain the view currently
|
// BestHash returns the hash of the best block in the chain the view currently
|
||||||
// respresents.
|
// respresents.
|
||||||
func (view *UtxoViewpoint) BestHash() *wire.ShaHash {
|
func (view *UtxoViewpoint) BestHash() *chainhash.Hash {
|
||||||
return &view.bestHash
|
return &view.bestHash
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetBestHash sets the hash of the best block in the chain the view currently
|
// SetBestHash sets the hash of the best block in the chain the view currently
|
||||||
// respresents.
|
// respresents.
|
||||||
func (view *UtxoViewpoint) SetBestHash(hash *wire.ShaHash) {
|
func (view *UtxoViewpoint) SetBestHash(hash *chainhash.Hash) {
|
||||||
view.bestHash = *hash
|
view.bestHash = *hash
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,7 +192,7 @@ func (view *UtxoViewpoint) SetBestHash(hash *wire.ShaHash) {
|
||||||
// current state of the view. It will return nil if the passed transaction
|
// current state of the view. It will return nil if the passed transaction
|
||||||
// hash does not exist in the view or is otherwise not available such as when
|
// hash does not exist in the view or is otherwise not available such as when
|
||||||
// it has been disconnected during a reorg.
|
// it has been disconnected during a reorg.
|
||||||
func (view *UtxoViewpoint) LookupEntry(txHash *wire.ShaHash) *UtxoEntry {
|
func (view *UtxoViewpoint) LookupEntry(txHash *chainhash.Hash) *UtxoEntry {
|
||||||
entry, ok := view.entries[*txHash]
|
entry, ok := view.entries[*txHash]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil
|
return nil
|
||||||
|
@ -208,11 +208,11 @@ func (view *UtxoViewpoint) LookupEntry(txHash *wire.ShaHash) *UtxoEntry {
|
||||||
func (view *UtxoViewpoint) AddTxOuts(tx *btcutil.Tx, blockHeight int32) {
|
func (view *UtxoViewpoint) AddTxOuts(tx *btcutil.Tx, blockHeight int32) {
|
||||||
// When there are not already any utxos associated with the transaction,
|
// When there are not already any utxos associated with the transaction,
|
||||||
// add a new entry for it to the view.
|
// add a new entry for it to the view.
|
||||||
entry := view.LookupEntry(tx.Sha())
|
entry := view.LookupEntry(tx.Hash())
|
||||||
if entry == nil {
|
if entry == nil {
|
||||||
entry = newUtxoEntry(tx.MsgTx().Version, IsCoinBase(tx),
|
entry = newUtxoEntry(tx.MsgTx().Version, IsCoinBase(tx),
|
||||||
blockHeight)
|
blockHeight)
|
||||||
view.entries[*tx.Sha()] = entry
|
view.entries[*tx.Hash()] = entry
|
||||||
} else {
|
} else {
|
||||||
entry.blockHeight = blockHeight
|
entry.blockHeight = blockHeight
|
||||||
}
|
}
|
||||||
|
@ -321,7 +321,7 @@ func (view *UtxoViewpoint) connectTransactions(block *btcutil.Block, stxos *[]sp
|
||||||
|
|
||||||
// Update the best hash for view to include this block since all of its
|
// Update the best hash for view to include this block since all of its
|
||||||
// transactions have been connected.
|
// transactions have been connected.
|
||||||
view.SetBestHash(block.Sha())
|
view.SetBestHash(block.Hash())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -349,11 +349,11 @@ func (view *UtxoViewpoint) disconnectTransactions(block *btcutil.Block, stxos []
|
||||||
// because the code relies on its existence in the view in order
|
// because the code relies on its existence in the view in order
|
||||||
// to signal modifications have happened.
|
// to signal modifications have happened.
|
||||||
isCoinbase := txIdx == 0
|
isCoinbase := txIdx == 0
|
||||||
entry := view.entries[*tx.Sha()]
|
entry := view.entries[*tx.Hash()]
|
||||||
if entry == nil {
|
if entry == nil {
|
||||||
entry = newUtxoEntry(tx.MsgTx().Version, isCoinbase,
|
entry = newUtxoEntry(tx.MsgTx().Version, isCoinbase,
|
||||||
block.Height())
|
block.Height())
|
||||||
view.entries[*tx.Sha()] = entry
|
view.entries[*tx.Hash()] = entry
|
||||||
}
|
}
|
||||||
entry.modified = true
|
entry.modified = true
|
||||||
entry.sparseOutputs = make(map[uint32]*utxoOutput)
|
entry.sparseOutputs = make(map[uint32]*utxoOutput)
|
||||||
|
@ -416,7 +416,7 @@ func (view *UtxoViewpoint) disconnectTransactions(block *btcutil.Block, stxos []
|
||||||
}
|
}
|
||||||
|
|
||||||
// Entries returns the underlying map that stores of all the utxo entries.
|
// Entries returns the underlying map that stores of all the utxo entries.
|
||||||
func (view *UtxoViewpoint) Entries() map[wire.ShaHash]*UtxoEntry {
|
func (view *UtxoViewpoint) Entries() map[chainhash.Hash]*UtxoEntry {
|
||||||
return view.entries
|
return view.entries
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -440,7 +440,7 @@ func (view *UtxoViewpoint) commit() {
|
||||||
// Upon completion of this function, the view will contain an entry for each
|
// Upon completion of this function, the view will contain an entry for each
|
||||||
// requested transaction. Fully spent transactions, or those which otherwise
|
// requested transaction. Fully spent transactions, or those which otherwise
|
||||||
// don't exist, will result in a nil entry in the view.
|
// don't exist, will result in a nil entry in the view.
|
||||||
func (view *UtxoViewpoint) fetchUtxosMain(db database.DB, txSet map[wire.ShaHash]struct{}) error {
|
func (view *UtxoViewpoint) fetchUtxosMain(db database.DB, txSet map[chainhash.Hash]struct{}) error {
|
||||||
// Nothing to do if there are no requested hashes.
|
// Nothing to do if there are no requested hashes.
|
||||||
if len(txSet) == 0 {
|
if len(txSet) == 0 {
|
||||||
return nil
|
return nil
|
||||||
|
@ -472,14 +472,14 @@ func (view *UtxoViewpoint) fetchUtxosMain(db database.DB, txSet map[wire.ShaHash
|
||||||
// fetchUtxos loads utxo details about provided set of transaction hashes into
|
// fetchUtxos loads utxo details about provided set of transaction hashes into
|
||||||
// the view from the database as needed unless they already exist in the view in
|
// the view from the database as needed unless they already exist in the view in
|
||||||
// which case they are ignored.
|
// which case they are ignored.
|
||||||
func (view *UtxoViewpoint) fetchUtxos(db database.DB, txSet map[wire.ShaHash]struct{}) error {
|
func (view *UtxoViewpoint) fetchUtxos(db database.DB, txSet map[chainhash.Hash]struct{}) error {
|
||||||
// Nothing to do if there are no requested hashes.
|
// Nothing to do if there are no requested hashes.
|
||||||
if len(txSet) == 0 {
|
if len(txSet) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filter entries that are already in the view.
|
// Filter entries that are already in the view.
|
||||||
txNeededSet := make(map[wire.ShaHash]struct{})
|
txNeededSet := make(map[chainhash.Hash]struct{})
|
||||||
for hash := range txSet {
|
for hash := range txSet {
|
||||||
// Already loaded into the current view.
|
// Already loaded into the current view.
|
||||||
if _, ok := view.entries[hash]; ok {
|
if _, ok := view.entries[hash]; ok {
|
||||||
|
@ -501,16 +501,16 @@ func (view *UtxoViewpoint) fetchInputUtxos(db database.DB, block *btcutil.Block)
|
||||||
// Build a map of in-flight transactions because some of the inputs in
|
// Build a map of in-flight transactions because some of the inputs in
|
||||||
// this block could be referencing other transactions earlier in this
|
// this block could be referencing other transactions earlier in this
|
||||||
// block which are not yet in the chain.
|
// block which are not yet in the chain.
|
||||||
txInFlight := map[wire.ShaHash]int{}
|
txInFlight := map[chainhash.Hash]int{}
|
||||||
transactions := block.Transactions()
|
transactions := block.Transactions()
|
||||||
for i, tx := range transactions {
|
for i, tx := range transactions {
|
||||||
txInFlight[*tx.Sha()] = i
|
txInFlight[*tx.Hash()] = i
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loop through all of the transaction inputs (except for the coinbase
|
// Loop through all of the transaction inputs (except for the coinbase
|
||||||
// which has no inputs) collecting them into sets of what is needed and
|
// which has no inputs) collecting them into sets of what is needed and
|
||||||
// what is already known (in-flight).
|
// what is already known (in-flight).
|
||||||
txNeededSet := make(map[wire.ShaHash]struct{})
|
txNeededSet := make(map[chainhash.Hash]struct{})
|
||||||
for i, tx := range transactions[1:] {
|
for i, tx := range transactions[1:] {
|
||||||
for _, txIn := range tx.MsgTx().TxIn {
|
for _, txIn := range tx.MsgTx().TxIn {
|
||||||
// It is acceptable for a transaction input to reference
|
// It is acceptable for a transaction input to reference
|
||||||
|
@ -550,7 +550,7 @@ func (view *UtxoViewpoint) fetchInputUtxos(db database.DB, block *btcutil.Block)
|
||||||
// NewUtxoViewpoint returns a new empty unspent transaction output view.
|
// NewUtxoViewpoint returns a new empty unspent transaction output view.
|
||||||
func NewUtxoViewpoint() *UtxoViewpoint {
|
func NewUtxoViewpoint() *UtxoViewpoint {
|
||||||
return &UtxoViewpoint{
|
return &UtxoViewpoint{
|
||||||
entries: make(map[wire.ShaHash]*UtxoEntry),
|
entries: make(map[chainhash.Hash]*UtxoEntry),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -568,8 +568,8 @@ func (b *BlockChain) FetchUtxoView(tx *btcutil.Tx) (*UtxoViewpoint, error) {
|
||||||
// inputs of the passed transaction. Also, add the passed transaction
|
// inputs of the passed transaction. Also, add the passed transaction
|
||||||
// itself as a way for the caller to detect duplicates that are not
|
// itself as a way for the caller to detect duplicates that are not
|
||||||
// fully spent.
|
// fully spent.
|
||||||
txNeededSet := make(map[wire.ShaHash]struct{})
|
txNeededSet := make(map[chainhash.Hash]struct{})
|
||||||
txNeededSet[*tx.Sha()] = struct{}{}
|
txNeededSet[*tx.Hash()] = struct{}{}
|
||||||
if !IsCoinBase(tx) {
|
if !IsCoinBase(tx) {
|
||||||
for _, txIn := range tx.MsgTx().TxIn {
|
for _, txIn := range tx.MsgTx().TxIn {
|
||||||
txNeededSet[txIn.PreviousOutPoint.Hash] = struct{}{}
|
txNeededSet[txIn.PreviousOutPoint.Hash] = struct{}{}
|
||||||
|
@ -593,7 +593,7 @@ func (b *BlockChain) FetchUtxoView(tx *btcutil.Tx) (*UtxoViewpoint, error) {
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent access however the returned entry (if
|
// This function is safe for concurrent access however the returned entry (if
|
||||||
// any) is NOT.
|
// any) is NOT.
|
||||||
func (b *BlockChain) FetchUtxoEntry(txHash *wire.ShaHash) (*UtxoEntry, error) {
|
func (b *BlockChain) FetchUtxoEntry(txHash *chainhash.Hash) (*UtxoEntry, error) {
|
||||||
b.chainLock.RLock()
|
b.chainLock.RLock()
|
||||||
defer b.chainLock.RUnlock()
|
defer b.chainLock.RUnlock()
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/chaincfg"
|
"github.com/btcsuite/btcd/chaincfg"
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/txscript"
|
"github.com/btcsuite/btcd/txscript"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
"github.com/btcsuite/btcutil"
|
"github.com/btcsuite/btcutil"
|
||||||
|
@ -56,20 +57,20 @@ var (
|
||||||
// constant is used because the tests need the ability to modify it.
|
// constant is used because the tests need the ability to modify it.
|
||||||
coinbaseMaturity = int32(CoinbaseMaturity)
|
coinbaseMaturity = int32(CoinbaseMaturity)
|
||||||
|
|
||||||
// zeroHash is the zero value for a wire.ShaHash and is defined as
|
// zeroHash is the zero value for a chainhash.Hash and is defined as
|
||||||
// a package level variable to avoid the need to create a new instance
|
// a package level variable to avoid the need to create a new instance
|
||||||
// every time a check is needed.
|
// every time a check is needed.
|
||||||
zeroHash = &wire.ShaHash{}
|
zeroHash = &chainhash.Hash{}
|
||||||
|
|
||||||
// block91842Hash is one of the two nodes which violate the rules
|
// block91842Hash is one of the two nodes which violate the rules
|
||||||
// set forth in BIP0030. It is defined as a package level variable to
|
// set forth in BIP0030. It is defined as a package level variable to
|
||||||
// avoid the need to create a new instance every time a check is needed.
|
// avoid the need to create a new instance every time a check is needed.
|
||||||
block91842Hash = newShaHashFromStr("00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec")
|
block91842Hash = newHashFromStr("00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec")
|
||||||
|
|
||||||
// block91880Hash is one of the two nodes which violate the rules
|
// block91880Hash is one of the two nodes which violate the rules
|
||||||
// set forth in BIP0030. It is defined as a package level variable to
|
// set forth in BIP0030. It is defined as a package level variable to
|
||||||
// avoid the need to create a new instance every time a check is needed.
|
// avoid the need to create a new instance every time a check is needed.
|
||||||
block91880Hash = newShaHashFromStr("00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721")
|
block91880Hash = newHashFromStr("00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721")
|
||||||
)
|
)
|
||||||
|
|
||||||
// isNullOutpoint determines whether or not a previous transaction output point
|
// isNullOutpoint determines whether or not a previous transaction output point
|
||||||
|
@ -320,8 +321,8 @@ func checkProofOfWork(header *wire.BlockHeader, powLimit *big.Int, flags Behavio
|
||||||
// to avoid proof of work checks is set.
|
// to avoid proof of work checks is set.
|
||||||
if flags&BFNoPoWCheck != BFNoPoWCheck {
|
if flags&BFNoPoWCheck != BFNoPoWCheck {
|
||||||
// The block hash must be less than the claimed target.
|
// The block hash must be less than the claimed target.
|
||||||
hash := header.BlockSha()
|
hash := header.BlockHash()
|
||||||
hashNum := ShaHashToBig(&hash)
|
hashNum := HashToBig(&hash)
|
||||||
if hashNum.Cmp(target) > 0 {
|
if hashNum.Cmp(target) > 0 {
|
||||||
str := fmt.Sprintf("block hash of %064x is higher than "+
|
str := fmt.Sprintf("block hash of %064x is higher than "+
|
||||||
"expected max of %064x", hashNum, target)
|
"expected max of %064x", hashNum, target)
|
||||||
|
@ -386,7 +387,7 @@ func CountP2SHSigOps(tx *btcutil.Tx, isCoinBaseTx bool, utxoView *UtxoViewpoint)
|
||||||
if txEntry == nil || txEntry.IsOutputSpent(originTxIndex) {
|
if txEntry == nil || txEntry.IsOutputSpent(originTxIndex) {
|
||||||
str := fmt.Sprintf("unable to find unspent output "+
|
str := fmt.Sprintf("unable to find unspent output "+
|
||||||
"%v referenced from transaction %s:%d",
|
"%v referenced from transaction %s:%d",
|
||||||
txIn.PreviousOutPoint, tx.Sha(), txInIndex)
|
txIn.PreviousOutPoint, tx.Hash(), txInIndex)
|
||||||
return 0, ruleError(ErrMissingTx, str)
|
return 0, ruleError(ErrMissingTx, str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -535,9 +536,9 @@ func checkBlockSanity(block *btcutil.Block, powLimit *big.Int, timeSource Median
|
||||||
// Check for duplicate transactions. This check will be fairly quick
|
// Check for duplicate transactions. This check will be fairly quick
|
||||||
// since the transaction hashes are already cached due to building the
|
// since the transaction hashes are already cached due to building the
|
||||||
// merkle tree above.
|
// merkle tree above.
|
||||||
existingTxHashes := make(map[wire.ShaHash]struct{})
|
existingTxHashes := make(map[chainhash.Hash]struct{})
|
||||||
for _, tx := range transactions {
|
for _, tx := range transactions {
|
||||||
hash := tx.Sha()
|
hash := tx.Hash()
|
||||||
if _, exists := existingTxHashes[*hash]; exists {
|
if _, exists := existingTxHashes[*hash]; exists {
|
||||||
str := fmt.Sprintf("block contains duplicate "+
|
str := fmt.Sprintf("block contains duplicate "+
|
||||||
"transaction %v", hash)
|
"transaction %v", hash)
|
||||||
|
@ -667,7 +668,7 @@ func (b *BlockChain) checkBlockHeaderContext(header *wire.BlockHeader, prevNode
|
||||||
blockHeight := prevNode.height + 1
|
blockHeight := prevNode.height + 1
|
||||||
|
|
||||||
// Ensure chain matches up to predetermined checkpoints.
|
// Ensure chain matches up to predetermined checkpoints.
|
||||||
blockHash := header.BlockSha()
|
blockHash := header.BlockHash()
|
||||||
if !b.verifyCheckpoint(blockHeight, &blockHash) {
|
if !b.verifyCheckpoint(blockHeight, &blockHash) {
|
||||||
str := fmt.Sprintf("block at height %d does not match "+
|
str := fmt.Sprintf("block at height %d does not match "+
|
||||||
"checkpoint hash", blockHeight)
|
"checkpoint hash", blockHeight)
|
||||||
|
@ -760,7 +761,7 @@ func (b *BlockChain) checkBlockContext(block *btcutil.Block, prevNode *blockNode
|
||||||
header.Timestamp) {
|
header.Timestamp) {
|
||||||
|
|
||||||
str := fmt.Sprintf("block contains unfinalized "+
|
str := fmt.Sprintf("block contains unfinalized "+
|
||||||
"transaction %v", tx.Sha())
|
"transaction %v", tx.Hash())
|
||||||
return ruleError(ErrUnfinalizedTx, str)
|
return ruleError(ErrUnfinalizedTx, str)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -797,9 +798,9 @@ func (b *BlockChain) checkBlockContext(block *btcutil.Block, prevNode *blockNode
|
||||||
func (b *BlockChain) checkBIP0030(node *blockNode, block *btcutil.Block, view *UtxoViewpoint) error {
|
func (b *BlockChain) checkBIP0030(node *blockNode, block *btcutil.Block, view *UtxoViewpoint) error {
|
||||||
// Fetch utxo details for all of the transactions in this block.
|
// Fetch utxo details for all of the transactions in this block.
|
||||||
// Typically, there will not be any utxos for any of the transactions.
|
// Typically, there will not be any utxos for any of the transactions.
|
||||||
fetchSet := make(map[wire.ShaHash]struct{})
|
fetchSet := make(map[chainhash.Hash]struct{})
|
||||||
for _, tx := range block.Transactions() {
|
for _, tx := range block.Transactions() {
|
||||||
fetchSet[*tx.Sha()] = struct{}{}
|
fetchSet[*tx.Hash()] = struct{}{}
|
||||||
}
|
}
|
||||||
err := view.fetchUtxos(b.db, fetchSet)
|
err := view.fetchUtxos(b.db, fetchSet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -809,11 +810,11 @@ func (b *BlockChain) checkBIP0030(node *blockNode, block *btcutil.Block, view *U
|
||||||
// Duplicate transactions are only allowed if the previous transaction
|
// Duplicate transactions are only allowed if the previous transaction
|
||||||
// is fully spent.
|
// is fully spent.
|
||||||
for _, tx := range block.Transactions() {
|
for _, tx := range block.Transactions() {
|
||||||
txEntry := view.LookupEntry(tx.Sha())
|
txEntry := view.LookupEntry(tx.Hash())
|
||||||
if txEntry != nil && !txEntry.IsFullySpent() {
|
if txEntry != nil && !txEntry.IsFullySpent() {
|
||||||
str := fmt.Sprintf("tried to overwrite transaction %v "+
|
str := fmt.Sprintf("tried to overwrite transaction %v "+
|
||||||
"at block height %d that is not fully spent",
|
"at block height %d that is not fully spent",
|
||||||
tx.Sha(), txEntry.blockHeight)
|
tx.Hash(), txEntry.blockHeight)
|
||||||
return ruleError(ErrOverwriteTx, str)
|
return ruleError(ErrOverwriteTx, str)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -838,7 +839,7 @@ func CheckTransactionInputs(tx *btcutil.Tx, txHeight int32, utxoView *UtxoViewpo
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
txHash := tx.Sha()
|
txHash := tx.Hash()
|
||||||
var totalSatoshiIn int64
|
var totalSatoshiIn int64
|
||||||
for txInIndex, txIn := range tx.MsgTx().TxIn {
|
for txInIndex, txIn := range tx.MsgTx().TxIn {
|
||||||
// Ensure the referenced input transaction is available.
|
// Ensure the referenced input transaction is available.
|
||||||
|
@ -847,7 +848,7 @@ func CheckTransactionInputs(tx *btcutil.Tx, txHeight int32, utxoView *UtxoViewpo
|
||||||
if utxoEntry == nil {
|
if utxoEntry == nil {
|
||||||
str := fmt.Sprintf("unable to find unspent output "+
|
str := fmt.Sprintf("unable to find unspent output "+
|
||||||
"%v referenced from transaction %s:%d",
|
"%v referenced from transaction %s:%d",
|
||||||
txIn.PreviousOutPoint, tx.Sha(), txInIndex)
|
txIn.PreviousOutPoint, tx.Hash(), txInIndex)
|
||||||
return 0, ruleError(ErrMissingTx, str)
|
return 0, ruleError(ErrMissingTx, str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1171,7 +1172,7 @@ func (b *BlockChain) CheckConnectBlock(block *btcutil.Block) error {
|
||||||
defer b.chainLock.Unlock()
|
defer b.chainLock.Unlock()
|
||||||
|
|
||||||
prevNode := b.bestNode
|
prevNode := b.bestNode
|
||||||
newNode := newBlockNode(&block.MsgBlock().Header, block.Sha(),
|
newNode := newBlockNode(&block.MsgBlock().Header, block.Hash(),
|
||||||
prevNode.height+1)
|
prevNode.height+1)
|
||||||
newNode.parent = prevNode
|
newNode.parent = prevNode
|
||||||
newNode.workSum.Add(prevNode.workSum, newNode.workSum)
|
newNode.workSum.Add(prevNode.workSum, newNode.workSum)
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/blockchain"
|
"github.com/btcsuite/btcd/blockchain"
|
||||||
"github.com/btcsuite/btcd/chaincfg"
|
"github.com/btcsuite/btcd/chaincfg"
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
"github.com/btcsuite/btcutil"
|
"github.com/btcsuite/btcutil"
|
||||||
)
|
)
|
||||||
|
@ -61,7 +62,7 @@ func TestCheckBlockSanity(t *testing.T) {
|
||||||
// and handled properly.
|
// and handled properly.
|
||||||
func TestCheckSerializedHeight(t *testing.T) {
|
func TestCheckSerializedHeight(t *testing.T) {
|
||||||
// Create an empty coinbase template to be used in the tests below.
|
// Create an empty coinbase template to be used in the tests below.
|
||||||
coinbaseOutpoint := wire.NewOutPoint(&wire.ShaHash{}, math.MaxUint32)
|
coinbaseOutpoint := wire.NewOutPoint(&chainhash.Hash{}, math.MaxUint32)
|
||||||
coinbaseTx := wire.NewMsgTx()
|
coinbaseTx := wire.NewMsgTx()
|
||||||
coinbaseTx.Version = 2
|
coinbaseTx.Version = 2
|
||||||
coinbaseTx.AddTxIn(wire.NewTxIn(coinbaseOutpoint, nil))
|
coinbaseTx.AddTxIn(wire.NewTxIn(coinbaseOutpoint, nil))
|
||||||
|
@ -127,13 +128,13 @@ func TestCheckSerializedHeight(t *testing.T) {
|
||||||
var Block100000 = wire.MsgBlock{
|
var Block100000 = wire.MsgBlock{
|
||||||
Header: wire.BlockHeader{
|
Header: wire.BlockHeader{
|
||||||
Version: 1,
|
Version: 1,
|
||||||
PrevBlock: wire.ShaHash([32]byte{ // Make go vet happy.
|
PrevBlock: chainhash.Hash([32]byte{ // Make go vet happy.
|
||||||
0x50, 0x12, 0x01, 0x19, 0x17, 0x2a, 0x61, 0x04,
|
0x50, 0x12, 0x01, 0x19, 0x17, 0x2a, 0x61, 0x04,
|
||||||
0x21, 0xa6, 0xc3, 0x01, 0x1d, 0xd3, 0x30, 0xd9,
|
0x21, 0xa6, 0xc3, 0x01, 0x1d, 0xd3, 0x30, 0xd9,
|
||||||
0xdf, 0x07, 0xb6, 0x36, 0x16, 0xc2, 0xcc, 0x1f,
|
0xdf, 0x07, 0xb6, 0x36, 0x16, 0xc2, 0xcc, 0x1f,
|
||||||
0x1c, 0xd0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x1c, 0xd0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
}), // 000000000002d01c1fccc21636b607dfd930d31d01c3a62104612a1719011250
|
}), // 000000000002d01c1fccc21636b607dfd930d31d01c3a62104612a1719011250
|
||||||
MerkleRoot: wire.ShaHash([32]byte{ // Make go vet happy.
|
MerkleRoot: chainhash.Hash([32]byte{ // Make go vet happy.
|
||||||
0x66, 0x57, 0xa9, 0x25, 0x2a, 0xac, 0xd5, 0xc0,
|
0x66, 0x57, 0xa9, 0x25, 0x2a, 0xac, 0xd5, 0xc0,
|
||||||
0xb2, 0x94, 0x09, 0x96, 0xec, 0xff, 0x95, 0x22,
|
0xb2, 0x94, 0x09, 0x96, 0xec, 0xff, 0x95, 0x22,
|
||||||
0x28, 0xc3, 0x06, 0x7c, 0xc3, 0x8d, 0x48, 0x85,
|
0x28, 0xc3, 0x06, 0x7c, 0xc3, 0x8d, 0x48, 0x85,
|
||||||
|
@ -149,7 +150,7 @@ var Block100000 = wire.MsgBlock{
|
||||||
TxIn: []*wire.TxIn{
|
TxIn: []*wire.TxIn{
|
||||||
{
|
{
|
||||||
PreviousOutPoint: wire.OutPoint{
|
PreviousOutPoint: wire.OutPoint{
|
||||||
Hash: wire.ShaHash{},
|
Hash: chainhash.Hash{},
|
||||||
Index: 0xffffffff,
|
Index: 0xffffffff,
|
||||||
},
|
},
|
||||||
SignatureScript: []byte{
|
SignatureScript: []byte{
|
||||||
|
@ -183,7 +184,7 @@ var Block100000 = wire.MsgBlock{
|
||||||
TxIn: []*wire.TxIn{
|
TxIn: []*wire.TxIn{
|
||||||
{
|
{
|
||||||
PreviousOutPoint: wire.OutPoint{
|
PreviousOutPoint: wire.OutPoint{
|
||||||
Hash: wire.ShaHash([32]byte{ // Make go vet happy.
|
Hash: chainhash.Hash([32]byte{ // Make go vet happy.
|
||||||
0x03, 0x2e, 0x38, 0xe9, 0xc0, 0xa8, 0x4c, 0x60,
|
0x03, 0x2e, 0x38, 0xe9, 0xc0, 0xa8, 0x4c, 0x60,
|
||||||
0x46, 0xd6, 0x87, 0xd1, 0x05, 0x56, 0xdc, 0xac,
|
0x46, 0xd6, 0x87, 0xd1, 0x05, 0x56, 0xdc, 0xac,
|
||||||
0xc4, 0x1d, 0x27, 0x5e, 0xc5, 0x5f, 0xc0, 0x07,
|
0xc4, 0x1d, 0x27, 0x5e, 0xc5, 0x5f, 0xc0, 0x07,
|
||||||
|
@ -252,7 +253,7 @@ var Block100000 = wire.MsgBlock{
|
||||||
TxIn: []*wire.TxIn{
|
TxIn: []*wire.TxIn{
|
||||||
{
|
{
|
||||||
PreviousOutPoint: wire.OutPoint{
|
PreviousOutPoint: wire.OutPoint{
|
||||||
Hash: wire.ShaHash([32]byte{ // Make go vet happy.
|
Hash: chainhash.Hash([32]byte{ // Make go vet happy.
|
||||||
0xc3, 0x3e, 0xbf, 0xf2, 0xa7, 0x09, 0xf1, 0x3d,
|
0xc3, 0x3e, 0xbf, 0xf2, 0xa7, 0x09, 0xf1, 0x3d,
|
||||||
0x9f, 0x9a, 0x75, 0x69, 0xab, 0x16, 0xa3, 0x27,
|
0x9f, 0x9a, 0x75, 0x69, 0xab, 0x16, 0xa3, 0x27,
|
||||||
0x86, 0xaf, 0x7d, 0x7e, 0x2d, 0xe0, 0x92, 0x65,
|
0x86, 0xaf, 0x7d, 0x7e, 0x2d, 0xe0, 0x92, 0x65,
|
||||||
|
@ -320,7 +321,7 @@ var Block100000 = wire.MsgBlock{
|
||||||
TxIn: []*wire.TxIn{
|
TxIn: []*wire.TxIn{
|
||||||
{
|
{
|
||||||
PreviousOutPoint: wire.OutPoint{
|
PreviousOutPoint: wire.OutPoint{
|
||||||
Hash: wire.ShaHash([32]byte{ // Make go vet happy.
|
Hash: chainhash.Hash([32]byte{ // Make go vet happy.
|
||||||
0x0b, 0x60, 0x72, 0xb3, 0x86, 0xd4, 0xa7, 0x73,
|
0x0b, 0x60, 0x72, 0xb3, 0x86, 0xd4, 0xa7, 0x73,
|
||||||
0x23, 0x52, 0x37, 0xf6, 0x4c, 0x11, 0x26, 0xac,
|
0x23, 0x52, 0x37, 0xf6, 0x4c, 0x11, 0x26, 0xac,
|
||||||
0x3b, 0x24, 0x0c, 0x84, 0xb9, 0x17, 0xa3, 0x90,
|
0x3b, 0x24, 0x0c, 0x84, 0xb9, 0x17, 0xa3, 0x90,
|
||||||
|
|
119
blockmanager.go
119
blockmanager.go
|
@ -15,6 +15,7 @@ import (
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/blockchain"
|
"github.com/btcsuite/btcd/blockchain"
|
||||||
"github.com/btcsuite/btcd/chaincfg"
|
"github.com/btcsuite/btcd/chaincfg"
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/database"
|
"github.com/btcsuite/btcd/database"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
"github.com/btcsuite/btcutil"
|
"github.com/btcsuite/btcutil"
|
||||||
|
@ -34,20 +35,20 @@ const (
|
||||||
blockDbNamePrefix = "blocks"
|
blockDbNamePrefix = "blocks"
|
||||||
|
|
||||||
// maxRejectedTxns is the maximum number of rejected transactions
|
// maxRejectedTxns is the maximum number of rejected transactions
|
||||||
// shas to store in memory.
|
// hashes to store in memory.
|
||||||
maxRejectedTxns = 1000
|
maxRejectedTxns = 1000
|
||||||
|
|
||||||
// maxRequestedBlocks is the maximum number of requested block
|
// maxRequestedBlocks is the maximum number of requested block
|
||||||
// shas to store in memory.
|
// hashes to store in memory.
|
||||||
maxRequestedBlocks = wire.MaxInvPerMsg
|
maxRequestedBlocks = wire.MaxInvPerMsg
|
||||||
|
|
||||||
// maxRequestedTxns is the maximum number of requested transactions
|
// maxRequestedTxns is the maximum number of requested transactions
|
||||||
// shas to store in memory.
|
// hashes to store in memory.
|
||||||
maxRequestedTxns = wire.MaxInvPerMsg
|
maxRequestedTxns = wire.MaxInvPerMsg
|
||||||
)
|
)
|
||||||
|
|
||||||
// zeroHash is the zero value hash (all zeros). It is defined as a convenience.
|
// zeroHash is the zero value hash (all zeros). It is defined as a convenience.
|
||||||
var zeroHash wire.ShaHash
|
var zeroHash chainhash.Hash
|
||||||
|
|
||||||
// newPeerMsg signifies a newly connected peer to the block handler.
|
// newPeerMsg signifies a newly connected peer to the block handler.
|
||||||
type newPeerMsg struct {
|
type newPeerMsg struct {
|
||||||
|
@ -130,7 +131,7 @@ type pauseMsg struct {
|
||||||
// between checkpoints.
|
// between checkpoints.
|
||||||
type headerNode struct {
|
type headerNode struct {
|
||||||
height int32
|
height int32
|
||||||
sha *wire.ShaHash
|
hash *chainhash.Hash
|
||||||
}
|
}
|
||||||
|
|
||||||
// chainState tracks the state of the best chain as blocks are inserted. This
|
// chainState tracks the state of the best chain as blocks are inserted. This
|
||||||
|
@ -141,7 +142,7 @@ type headerNode struct {
|
||||||
// is inserted and protecting it with a mutex.
|
// is inserted and protecting it with a mutex.
|
||||||
type chainState struct {
|
type chainState struct {
|
||||||
sync.Mutex
|
sync.Mutex
|
||||||
newestHash *wire.ShaHash
|
newestHash *chainhash.Hash
|
||||||
newestHeight int32
|
newestHeight int32
|
||||||
pastMedianTime time.Time
|
pastMedianTime time.Time
|
||||||
pastMedianTimeErr error
|
pastMedianTimeErr error
|
||||||
|
@ -151,7 +152,7 @@ type chainState struct {
|
||||||
// chain.
|
// chain.
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (c *chainState) Best() (*wire.ShaHash, int32) {
|
func (c *chainState) Best() (*chainhash.Hash, int32) {
|
||||||
c.Lock()
|
c.Lock()
|
||||||
defer c.Unlock()
|
defer c.Unlock()
|
||||||
|
|
||||||
|
@ -165,9 +166,9 @@ type blockManager struct {
|
||||||
started int32
|
started int32
|
||||||
shutdown int32
|
shutdown int32
|
||||||
chain *blockchain.BlockChain
|
chain *blockchain.BlockChain
|
||||||
rejectedTxns map[wire.ShaHash]struct{}
|
rejectedTxns map[chainhash.Hash]struct{}
|
||||||
requestedTxns map[wire.ShaHash]struct{}
|
requestedTxns map[chainhash.Hash]struct{}
|
||||||
requestedBlocks map[wire.ShaHash]struct{}
|
requestedBlocks map[chainhash.Hash]struct{}
|
||||||
progressLogger *blockProgressLogger
|
progressLogger *blockProgressLogger
|
||||||
receivedLogBlocks int64
|
receivedLogBlocks int64
|
||||||
receivedLogTx int64
|
receivedLogTx int64
|
||||||
|
@ -187,7 +188,7 @@ type blockManager struct {
|
||||||
|
|
||||||
// resetHeaderState sets the headers-first mode state to values appropriate for
|
// resetHeaderState sets the headers-first mode state to values appropriate for
|
||||||
// syncing from a new peer.
|
// syncing from a new peer.
|
||||||
func (b *blockManager) resetHeaderState(newestHash *wire.ShaHash, newestHeight int32) {
|
func (b *blockManager) resetHeaderState(newestHash *chainhash.Hash, newestHeight int32) {
|
||||||
b.headersFirstMode = false
|
b.headersFirstMode = false
|
||||||
b.headerList.Init()
|
b.headerList.Init()
|
||||||
b.startHeader = nil
|
b.startHeader = nil
|
||||||
|
@ -196,7 +197,7 @@ func (b *blockManager) resetHeaderState(newestHash *wire.ShaHash, newestHeight i
|
||||||
// block into the header pool. This allows the next downloaded header
|
// block into the header pool. This allows the next downloaded header
|
||||||
// to prove it links to the chain properly.
|
// to prove it links to the chain properly.
|
||||||
if b.nextCheckpoint != nil {
|
if b.nextCheckpoint != nil {
|
||||||
node := headerNode{height: newestHeight, sha: newestHash}
|
node := headerNode{height: newestHeight, hash: newestHash}
|
||||||
b.headerList.PushBack(&node)
|
b.headerList.PushBack(&node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -205,7 +206,7 @@ func (b *blockManager) resetHeaderState(newestHash *wire.ShaHash, newestHeight i
|
||||||
// This allows fast access to chain information since btcchain is currently not
|
// This allows fast access to chain information since btcchain is currently not
|
||||||
// safe for concurrent access and the block manager is typically quite busy
|
// safe for concurrent access and the block manager is typically quite busy
|
||||||
// processing block and inventory.
|
// processing block and inventory.
|
||||||
func (b *blockManager) updateChainState(newestHash *wire.ShaHash, newestHeight int32) {
|
func (b *blockManager) updateChainState(newestHash *chainhash.Hash, newestHeight int32) {
|
||||||
b.chainState.Lock()
|
b.chainState.Lock()
|
||||||
defer b.chainState.Unlock()
|
defer b.chainState.Unlock()
|
||||||
|
|
||||||
|
@ -290,7 +291,7 @@ func (b *blockManager) startSync(peers *list.List) {
|
||||||
// Clear the requestedBlocks if the sync peer changes, otherwise
|
// Clear the requestedBlocks if the sync peer changes, otherwise
|
||||||
// we may ignore blocks we need that the last sync peer failed
|
// we may ignore blocks we need that the last sync peer failed
|
||||||
// to send.
|
// to send.
|
||||||
b.requestedBlocks = make(map[wire.ShaHash]struct{})
|
b.requestedBlocks = make(map[chainhash.Hash]struct{})
|
||||||
|
|
||||||
locator, err := b.chain.LatestBlockLocator()
|
locator, err := b.chain.LatestBlockLocator()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -440,7 +441,7 @@ func (b *blockManager) handleTxMsg(tmsg *txMsg) {
|
||||||
// spec to proliferate. While this is not ideal, there is no check here
|
// spec to proliferate. While this is not ideal, there is no check here
|
||||||
// to disconnect peers for sending unsolicited transactions to provide
|
// to disconnect peers for sending unsolicited transactions to provide
|
||||||
// interoperability.
|
// interoperability.
|
||||||
txHash := tmsg.tx.Sha()
|
txHash := tmsg.tx.Hash()
|
||||||
|
|
||||||
// Ignore transactions that we have already rejected. Do not
|
// Ignore transactions that we have already rejected. Do not
|
||||||
// send a reject message here because if the transaction was already
|
// send a reject message here because if the transaction was already
|
||||||
|
@ -517,8 +518,8 @@ func (b *blockManager) current() bool {
|
||||||
// handleBlockMsg handles block messages from all peers.
|
// handleBlockMsg handles block messages from all peers.
|
||||||
func (b *blockManager) handleBlockMsg(bmsg *blockMsg) {
|
func (b *blockManager) handleBlockMsg(bmsg *blockMsg) {
|
||||||
// If we didn't ask for this block then the peer is misbehaving.
|
// If we didn't ask for this block then the peer is misbehaving.
|
||||||
blockSha := bmsg.block.Sha()
|
blockHash := bmsg.block.Hash()
|
||||||
if _, exists := bmsg.peer.requestedBlocks[*blockSha]; !exists {
|
if _, exists := bmsg.peer.requestedBlocks[*blockHash]; !exists {
|
||||||
// The regression test intentionally sends some blocks twice
|
// The regression test intentionally sends some blocks twice
|
||||||
// to test duplicate block insertion fails. Don't disconnect
|
// to test duplicate block insertion fails. Don't disconnect
|
||||||
// the peer or ignore the block when we're in regression test
|
// the peer or ignore the block when we're in regression test
|
||||||
|
@ -526,7 +527,7 @@ func (b *blockManager) handleBlockMsg(bmsg *blockMsg) {
|
||||||
// duplicate blocks.
|
// duplicate blocks.
|
||||||
if !cfg.RegressionTest {
|
if !cfg.RegressionTest {
|
||||||
bmgrLog.Warnf("Got unrequested block %v from %s -- "+
|
bmgrLog.Warnf("Got unrequested block %v from %s -- "+
|
||||||
"disconnecting", blockSha, bmsg.peer.Addr())
|
"disconnecting", blockHash, bmsg.peer.Addr())
|
||||||
bmsg.peer.Disconnect()
|
bmsg.peer.Disconnect()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -545,9 +546,9 @@ func (b *blockManager) handleBlockMsg(bmsg *blockMsg) {
|
||||||
firstNodeEl := b.headerList.Front()
|
firstNodeEl := b.headerList.Front()
|
||||||
if firstNodeEl != nil {
|
if firstNodeEl != nil {
|
||||||
firstNode := firstNodeEl.Value.(*headerNode)
|
firstNode := firstNodeEl.Value.(*headerNode)
|
||||||
if blockSha.IsEqual(firstNode.sha) {
|
if blockHash.IsEqual(firstNode.hash) {
|
||||||
behaviorFlags |= blockchain.BFFastAdd
|
behaviorFlags |= blockchain.BFFastAdd
|
||||||
if firstNode.sha.IsEqual(b.nextCheckpoint.Hash) {
|
if firstNode.hash.IsEqual(b.nextCheckpoint.Hash) {
|
||||||
isCheckpointBlock = true
|
isCheckpointBlock = true
|
||||||
} else {
|
} else {
|
||||||
b.headerList.Remove(firstNodeEl)
|
b.headerList.Remove(firstNodeEl)
|
||||||
|
@ -559,8 +560,8 @@ func (b *blockManager) handleBlockMsg(bmsg *blockMsg) {
|
||||||
// Remove block from request maps. Either chain will know about it and
|
// Remove block from request maps. Either chain will know about it and
|
||||||
// so we shouldn't have any more instances of trying to fetch it, or we
|
// so we shouldn't have any more instances of trying to fetch it, or we
|
||||||
// will fail the insert and thus we'll retry next time we get an inv.
|
// will fail the insert and thus we'll retry next time we get an inv.
|
||||||
delete(bmsg.peer.requestedBlocks, *blockSha)
|
delete(bmsg.peer.requestedBlocks, *blockHash)
|
||||||
delete(b.requestedBlocks, *blockSha)
|
delete(b.requestedBlocks, *blockHash)
|
||||||
|
|
||||||
// Process the block to include validation, best chain selection, orphan
|
// Process the block to include validation, best chain selection, orphan
|
||||||
// handling, etc.
|
// handling, etc.
|
||||||
|
@ -571,11 +572,11 @@ func (b *blockManager) handleBlockMsg(bmsg *blockMsg) {
|
||||||
// it as such. Otherwise, something really did go wrong, so log
|
// it as such. Otherwise, something really did go wrong, so log
|
||||||
// it as an actual error.
|
// it as an actual error.
|
||||||
if _, ok := err.(blockchain.RuleError); ok {
|
if _, ok := err.(blockchain.RuleError); ok {
|
||||||
bmgrLog.Infof("Rejected block %v from %s: %v", blockSha,
|
bmgrLog.Infof("Rejected block %v from %s: %v", blockHash,
|
||||||
bmsg.peer, err)
|
bmsg.peer, err)
|
||||||
} else {
|
} else {
|
||||||
bmgrLog.Errorf("Failed to process block %v: %v",
|
bmgrLog.Errorf("Failed to process block %v: %v",
|
||||||
blockSha, err)
|
blockHash, err)
|
||||||
}
|
}
|
||||||
if dbErr, ok := err.(database.Error); ok && dbErr.ErrorCode ==
|
if dbErr, ok := err.(database.Error); ok && dbErr.ErrorCode ==
|
||||||
database.ErrCorruption {
|
database.ErrCorruption {
|
||||||
|
@ -586,21 +587,21 @@ func (b *blockManager) handleBlockMsg(bmsg *blockMsg) {
|
||||||
// send it.
|
// send it.
|
||||||
code, reason := errToRejectErr(err)
|
code, reason := errToRejectErr(err)
|
||||||
bmsg.peer.PushRejectMsg(wire.CmdBlock, code, reason,
|
bmsg.peer.PushRejectMsg(wire.CmdBlock, code, reason,
|
||||||
blockSha, false)
|
blockHash, false)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Meta-data about the new block this peer is reporting. We use this
|
// Meta-data about the new block this peer is reporting. We use this
|
||||||
// below to update this peer's lastest block height and the heights of
|
// below to update this peer's lastest block height and the heights of
|
||||||
// other peers based on their last announced block sha. This allows us
|
// other peers based on their last announced block hash. This allows us
|
||||||
// to dynamically update the block heights of peers, avoiding stale heights
|
// to dynamically update the block heights of peers, avoiding stale
|
||||||
// when looking for a new sync peer. Upon acceptance of a block or
|
// heights when looking for a new sync peer. Upon acceptance of a block
|
||||||
// recognition of an orphan, we also use this information to update
|
// or recognition of an orphan, we also use this information to update
|
||||||
// the block heights over other peers who's invs may have been ignored
|
// the block heights over other peers who's invs may have been ignored
|
||||||
// if we are actively syncing while the chain is not yet current or
|
// if we are actively syncing while the chain is not yet current or
|
||||||
// who may have lost the lock announcment race.
|
// who may have lost the lock announcment race.
|
||||||
var heightUpdate int32
|
var heightUpdate int32
|
||||||
var blkShaUpdate *wire.ShaHash
|
var blkHashUpdate *chainhash.Hash
|
||||||
|
|
||||||
// Request the parents for the orphan block from the peer that sent it.
|
// Request the parents for the orphan block from the peer that sent it.
|
||||||
if isOrphan {
|
if isOrphan {
|
||||||
|
@ -620,11 +621,11 @@ func (b *blockManager) handleBlockMsg(bmsg *blockMsg) {
|
||||||
bmgrLog.Debugf("Extracted height of %v from "+
|
bmgrLog.Debugf("Extracted height of %v from "+
|
||||||
"orphan block", cbHeight)
|
"orphan block", cbHeight)
|
||||||
heightUpdate = int32(cbHeight)
|
heightUpdate = int32(cbHeight)
|
||||||
blkShaUpdate = blockSha
|
blkHashUpdate = blockHash
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
orphanRoot := b.chain.GetOrphanRoot(blockSha)
|
orphanRoot := b.chain.GetOrphanRoot(blockHash)
|
||||||
locator, err := b.chain.LatestBlockLocator()
|
locator, err := b.chain.LatestBlockLocator()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
bmgrLog.Warnf("Failed to get block locator for the "+
|
bmgrLog.Warnf("Failed to get block locator for the "+
|
||||||
|
@ -646,17 +647,17 @@ func (b *blockManager) handleBlockMsg(bmsg *blockMsg) {
|
||||||
// Update this peer's latest block height, for future
|
// Update this peer's latest block height, for future
|
||||||
// potential sync node candidacy.
|
// potential sync node candidacy.
|
||||||
heightUpdate = best.Height
|
heightUpdate = best.Height
|
||||||
blkShaUpdate = best.Hash
|
blkHashUpdate = best.Hash
|
||||||
|
|
||||||
// Clear the rejected transactions.
|
// Clear the rejected transactions.
|
||||||
b.rejectedTxns = make(map[wire.ShaHash]struct{})
|
b.rejectedTxns = make(map[chainhash.Hash]struct{})
|
||||||
|
|
||||||
// Allow any clients performing long polling via the
|
// Allow any clients performing long polling via the
|
||||||
// getblocktemplate RPC to be notified when the new block causes
|
// getblocktemplate RPC to be notified when the new block causes
|
||||||
// their old block template to become stale.
|
// their old block template to become stale.
|
||||||
rpcServer := b.server.rpcServer
|
rpcServer := b.server.rpcServer
|
||||||
if rpcServer != nil {
|
if rpcServer != nil {
|
||||||
rpcServer.gbtWorkState.NotifyBlockConnected(blockSha)
|
rpcServer.gbtWorkState.NotifyBlockConnected(blockHash)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -664,10 +665,10 @@ func (b *blockManager) handleBlockMsg(bmsg *blockMsg) {
|
||||||
// the server for updating peer heights if this is an orphan or our
|
// the server for updating peer heights if this is an orphan or our
|
||||||
// chain is "current". This avoids sending a spammy amount of messages
|
// chain is "current". This avoids sending a spammy amount of messages
|
||||||
// if we're syncing the chain from scratch.
|
// if we're syncing the chain from scratch.
|
||||||
if blkShaUpdate != nil && heightUpdate != 0 {
|
if blkHashUpdate != nil && heightUpdate != 0 {
|
||||||
bmsg.peer.UpdateLastBlockHeight(heightUpdate)
|
bmsg.peer.UpdateLastBlockHeight(heightUpdate)
|
||||||
if isOrphan || b.current() {
|
if isOrphan || b.current() {
|
||||||
go b.server.UpdatePeerHeights(blkShaUpdate, int32(heightUpdate), bmsg.peer)
|
go b.server.UpdatePeerHeights(blkHashUpdate, int32(heightUpdate), bmsg.peer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -695,7 +696,7 @@ func (b *blockManager) handleBlockMsg(bmsg *blockMsg) {
|
||||||
prevHash := b.nextCheckpoint.Hash
|
prevHash := b.nextCheckpoint.Hash
|
||||||
b.nextCheckpoint = b.findNextHeaderCheckpoint(prevHeight)
|
b.nextCheckpoint = b.findNextHeaderCheckpoint(prevHeight)
|
||||||
if b.nextCheckpoint != nil {
|
if b.nextCheckpoint != nil {
|
||||||
locator := blockchain.BlockLocator([]*wire.ShaHash{prevHash})
|
locator := blockchain.BlockLocator([]*chainhash.Hash{prevHash})
|
||||||
err := bmsg.peer.PushGetHeadersMsg(locator, b.nextCheckpoint.Hash)
|
err := bmsg.peer.PushGetHeadersMsg(locator, b.nextCheckpoint.Hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
bmgrLog.Warnf("Failed to send getheaders message to "+
|
bmgrLog.Warnf("Failed to send getheaders message to "+
|
||||||
|
@ -714,7 +715,7 @@ func (b *blockManager) handleBlockMsg(bmsg *blockMsg) {
|
||||||
b.headersFirstMode = false
|
b.headersFirstMode = false
|
||||||
b.headerList.Init()
|
b.headerList.Init()
|
||||||
bmgrLog.Infof("Reached the final checkpoint -- switching to normal mode")
|
bmgrLog.Infof("Reached the final checkpoint -- switching to normal mode")
|
||||||
locator := blockchain.BlockLocator([]*wire.ShaHash{blockSha})
|
locator := blockchain.BlockLocator([]*chainhash.Hash{blockHash})
|
||||||
err = bmsg.peer.PushGetBlocksMsg(locator, &zeroHash)
|
err = bmsg.peer.PushGetBlocksMsg(locator, &zeroHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
bmgrLog.Warnf("Failed to send getblocks message to peer %s: %v",
|
bmgrLog.Warnf("Failed to send getblocks message to peer %s: %v",
|
||||||
|
@ -744,7 +745,7 @@ func (b *blockManager) fetchHeaderBlocks() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
iv := wire.NewInvVect(wire.InvTypeBlock, node.sha)
|
iv := wire.NewInvVect(wire.InvTypeBlock, node.hash)
|
||||||
haveInv, err := b.haveInventory(iv)
|
haveInv, err := b.haveInventory(iv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
bmgrLog.Warnf("Unexpected failure when checking for "+
|
bmgrLog.Warnf("Unexpected failure when checking for "+
|
||||||
|
@ -752,8 +753,8 @@ func (b *blockManager) fetchHeaderBlocks() {
|
||||||
"fetch: %v", err)
|
"fetch: %v", err)
|
||||||
}
|
}
|
||||||
if !haveInv {
|
if !haveInv {
|
||||||
b.requestedBlocks[*node.sha] = struct{}{}
|
b.requestedBlocks[*node.hash] = struct{}{}
|
||||||
b.syncPeer.requestedBlocks[*node.sha] = struct{}{}
|
b.syncPeer.requestedBlocks[*node.hash] = struct{}{}
|
||||||
gdmsg.AddInvVect(iv)
|
gdmsg.AddInvVect(iv)
|
||||||
numRequested++
|
numRequested++
|
||||||
}
|
}
|
||||||
|
@ -787,9 +788,9 @@ func (b *blockManager) handleHeadersMsg(hmsg *headersMsg) {
|
||||||
// Process all of the received headers ensuring each one connects to the
|
// Process all of the received headers ensuring each one connects to the
|
||||||
// previous and that checkpoints match.
|
// previous and that checkpoints match.
|
||||||
receivedCheckpoint := false
|
receivedCheckpoint := false
|
||||||
var finalHash *wire.ShaHash
|
var finalHash *chainhash.Hash
|
||||||
for _, blockHeader := range msg.Headers {
|
for _, blockHeader := range msg.Headers {
|
||||||
blockHash := blockHeader.BlockSha()
|
blockHash := blockHeader.BlockHash()
|
||||||
finalHash = &blockHash
|
finalHash = &blockHash
|
||||||
|
|
||||||
// Ensure there is a previous header to compare against.
|
// Ensure there is a previous header to compare against.
|
||||||
|
@ -803,9 +804,9 @@ func (b *blockManager) handleHeadersMsg(hmsg *headersMsg) {
|
||||||
|
|
||||||
// Ensure the header properly connects to the previous one and
|
// Ensure the header properly connects to the previous one and
|
||||||
// add it to the list of headers.
|
// add it to the list of headers.
|
||||||
node := headerNode{sha: &blockHash}
|
node := headerNode{hash: &blockHash}
|
||||||
prevNode := prevNodeEl.Value.(*headerNode)
|
prevNode := prevNodeEl.Value.(*headerNode)
|
||||||
if prevNode.sha.IsEqual(&blockHeader.PrevBlock) {
|
if prevNode.hash.IsEqual(&blockHeader.PrevBlock) {
|
||||||
node.height = prevNode.height + 1
|
node.height = prevNode.height + 1
|
||||||
e := b.headerList.PushBack(&node)
|
e := b.headerList.PushBack(&node)
|
||||||
if b.startHeader == nil {
|
if b.startHeader == nil {
|
||||||
|
@ -821,17 +822,17 @@ func (b *blockManager) handleHeadersMsg(hmsg *headersMsg) {
|
||||||
|
|
||||||
// Verify the header at the next checkpoint height matches.
|
// Verify the header at the next checkpoint height matches.
|
||||||
if node.height == b.nextCheckpoint.Height {
|
if node.height == b.nextCheckpoint.Height {
|
||||||
if node.sha.IsEqual(b.nextCheckpoint.Hash) {
|
if node.hash.IsEqual(b.nextCheckpoint.Hash) {
|
||||||
receivedCheckpoint = true
|
receivedCheckpoint = true
|
||||||
bmgrLog.Infof("Verified downloaded block "+
|
bmgrLog.Infof("Verified downloaded block "+
|
||||||
"header against checkpoint at height "+
|
"header against checkpoint at height "+
|
||||||
"%d/hash %s", node.height, node.sha)
|
"%d/hash %s", node.height, node.hash)
|
||||||
} else {
|
} else {
|
||||||
bmgrLog.Warnf("Block header at height %d/hash "+
|
bmgrLog.Warnf("Block header at height %d/hash "+
|
||||||
"%s from peer %s does NOT match "+
|
"%s from peer %s does NOT match "+
|
||||||
"expected checkpoint hash of %s -- "+
|
"expected checkpoint hash of %s -- "+
|
||||||
"disconnecting", node.height,
|
"disconnecting", node.height,
|
||||||
node.sha, hmsg.peer.Addr(),
|
node.hash, hmsg.peer.Addr(),
|
||||||
b.nextCheckpoint.Hash)
|
b.nextCheckpoint.Hash)
|
||||||
hmsg.peer.Disconnect()
|
hmsg.peer.Disconnect()
|
||||||
return
|
return
|
||||||
|
@ -858,7 +859,7 @@ func (b *blockManager) handleHeadersMsg(hmsg *headersMsg) {
|
||||||
// This header is not a checkpoint, so request the next batch of
|
// This header is not a checkpoint, so request the next batch of
|
||||||
// headers starting from the latest known header and ending with the
|
// headers starting from the latest known header and ending with the
|
||||||
// next checkpoint.
|
// next checkpoint.
|
||||||
locator := blockchain.BlockLocator([]*wire.ShaHash{finalHash})
|
locator := blockchain.BlockLocator([]*chainhash.Hash{finalHash})
|
||||||
err := hmsg.peer.PushGetHeadersMsg(locator, b.nextCheckpoint.Hash)
|
err := hmsg.peer.PushGetHeadersMsg(locator, b.nextCheckpoint.Hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
bmgrLog.Warnf("Failed to send getheaders message to "+
|
bmgrLog.Warnf("Failed to send getheaders message to "+
|
||||||
|
@ -1067,7 +1068,7 @@ func (b *blockManager) handleInvMsg(imsg *invMsg) {
|
||||||
// limitMap is a helper function for maps that require a maximum limit by
|
// limitMap is a helper function for maps that require a maximum limit by
|
||||||
// evicting a random transaction if adding a new value would cause it to
|
// evicting a random transaction if adding a new value would cause it to
|
||||||
// overflow the maximum allowed.
|
// overflow the maximum allowed.
|
||||||
func (b *blockManager) limitMap(m map[wire.ShaHash]struct{}, limit int) {
|
func (b *blockManager) limitMap(m map[chainhash.Hash]struct{}, limit int) {
|
||||||
if len(m)+1 > limit {
|
if len(m)+1 > limit {
|
||||||
// Remove a random entry from the map. For most compilers, Go's
|
// Remove a random entry from the map. For most compilers, Go's
|
||||||
// range statement iterates starting at a random item although
|
// range statement iterates starting at a random item although
|
||||||
|
@ -1139,7 +1140,7 @@ out:
|
||||||
// their old block template to become stale.
|
// their old block template to become stale.
|
||||||
rpcServer := b.server.rpcServer
|
rpcServer := b.server.rpcServer
|
||||||
if rpcServer != nil {
|
if rpcServer != nil {
|
||||||
rpcServer.gbtWorkState.NotifyBlockConnected(msg.block.Sha())
|
rpcServer.gbtWorkState.NotifyBlockConnected(msg.block.Hash())
|
||||||
}
|
}
|
||||||
|
|
||||||
msg.reply <- processBlockResponse{
|
msg.reply <- processBlockResponse{
|
||||||
|
@ -1188,7 +1189,7 @@ func (b *blockManager) handleNotifyMsg(notification *blockchain.Notification) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate the inventory vector and relay it.
|
// Generate the inventory vector and relay it.
|
||||||
iv := wire.NewInvVect(wire.InvTypeBlock, block.Sha())
|
iv := wire.NewInvVect(wire.InvTypeBlock, block.Hash())
|
||||||
b.server.RelayInventory(iv, block.MsgBlock().Header)
|
b.server.RelayInventory(iv, block.MsgBlock().Header)
|
||||||
|
|
||||||
// A block has been connected to the main block chain.
|
// A block has been connected to the main block chain.
|
||||||
|
@ -1209,8 +1210,8 @@ func (b *blockManager) handleNotifyMsg(notification *blockchain.Notification) {
|
||||||
for _, tx := range block.Transactions()[1:] {
|
for _, tx := range block.Transactions()[1:] {
|
||||||
b.server.txMemPool.RemoveTransaction(tx, false)
|
b.server.txMemPool.RemoveTransaction(tx, false)
|
||||||
b.server.txMemPool.RemoveDoubleSpends(tx)
|
b.server.txMemPool.RemoveDoubleSpends(tx)
|
||||||
b.server.txMemPool.RemoveOrphan(tx.Sha())
|
b.server.txMemPool.RemoveOrphan(tx.Hash())
|
||||||
acceptedTxs := b.server.txMemPool.ProcessOrphans(tx.Sha())
|
acceptedTxs := b.server.txMemPool.ProcessOrphans(tx.Hash())
|
||||||
b.server.AnnounceNewTransactions(acceptedTxs)
|
b.server.AnnounceNewTransactions(acceptedTxs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1219,7 +1220,7 @@ func (b *blockManager) handleNotifyMsg(notification *blockchain.Notification) {
|
||||||
// all the transactions (except the coinbase) as no
|
// all the transactions (except the coinbase) as no
|
||||||
// longer needing rebroadcasting.
|
// longer needing rebroadcasting.
|
||||||
for _, tx := range block.Transactions()[1:] {
|
for _, tx := range block.Transactions()[1:] {
|
||||||
iv := wire.NewInvVect(wire.InvTypeTx, tx.Sha())
|
iv := wire.NewInvVect(wire.InvTypeTx, tx.Hash())
|
||||||
b.server.RemoveRebroadcastInventory(iv)
|
b.server.RemoveRebroadcastInventory(iv)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1387,9 +1388,9 @@ func (b *blockManager) Pause() chan<- struct{} {
|
||||||
func newBlockManager(s *server, indexManager blockchain.IndexManager) (*blockManager, error) {
|
func newBlockManager(s *server, indexManager blockchain.IndexManager) (*blockManager, error) {
|
||||||
bm := blockManager{
|
bm := blockManager{
|
||||||
server: s,
|
server: s,
|
||||||
rejectedTxns: make(map[wire.ShaHash]struct{}),
|
rejectedTxns: make(map[chainhash.Hash]struct{}),
|
||||||
requestedTxns: make(map[wire.ShaHash]struct{}),
|
requestedTxns: make(map[chainhash.Hash]struct{}),
|
||||||
requestedBlocks: make(map[wire.ShaHash]struct{}),
|
requestedBlocks: make(map[chainhash.Hash]struct{}),
|
||||||
progressLogger: newBlockProgressLogger("Processed", bmgrLog),
|
progressLogger: newBlockProgressLogger("Processed", bmgrLog),
|
||||||
msgChan: make(chan interface{}, cfg.MaxPeers*3),
|
msgChan: make(chan interface{}, cfg.MaxPeers*3),
|
||||||
headerList: list.New(),
|
headerList: list.New(),
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/btcec"
|
"github.com/btcsuite/btcd/btcec"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
)
|
)
|
||||||
|
|
||||||
// This example demonstrates signing a message with a secp256k1 private key that
|
// This example demonstrates signing a message with a secp256k1 private key that
|
||||||
|
@ -26,7 +26,7 @@ func Example_signMessage() {
|
||||||
|
|
||||||
// Sign a message using the private key.
|
// Sign a message using the private key.
|
||||||
message := "test message"
|
message := "test message"
|
||||||
messageHash := wire.DoubleSha256([]byte(message))
|
messageHash := chainhash.DoubleHashB([]byte(message))
|
||||||
signature, err := privKey.Sign(messageHash)
|
signature, err := privKey.Sign(messageHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
|
@ -79,7 +79,7 @@ func Example_verifySignature() {
|
||||||
|
|
||||||
// Verify the signature for the message using the public key.
|
// Verify the signature for the message using the public key.
|
||||||
message := "test message"
|
message := "test message"
|
||||||
messageHash := wire.DoubleSha256([]byte(message))
|
messageHash := chainhash.DoubleHashB([]byte(message))
|
||||||
verified := signature.Verify(messageHash, pubKey)
|
verified := signature.Verify(messageHash, pubKey)
|
||||||
fmt.Println("Signature Verified?", verified)
|
fmt.Println("Signature Verified?", verified)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014 The btcsuite developers
|
// Copyright (c) 2014-2016 The btcsuite developers
|
||||||
// Use of this source code is governed by an ISC
|
// Use of this source code is governed by an ISC
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ package chaincfg
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -17,7 +18,7 @@ var genesisCoinbaseTx = wire.MsgTx{
|
||||||
TxIn: []*wire.TxIn{
|
TxIn: []*wire.TxIn{
|
||||||
{
|
{
|
||||||
PreviousOutPoint: wire.OutPoint{
|
PreviousOutPoint: wire.OutPoint{
|
||||||
Hash: wire.ShaHash{},
|
Hash: chainhash.Hash{},
|
||||||
Index: 0xffffffff,
|
Index: 0xffffffff,
|
||||||
},
|
},
|
||||||
SignatureScript: []byte{
|
SignatureScript: []byte{
|
||||||
|
@ -56,7 +57,7 @@ var genesisCoinbaseTx = wire.MsgTx{
|
||||||
|
|
||||||
// genesisHash is the hash of the first block in the block chain for the main
|
// genesisHash is the hash of the first block in the block chain for the main
|
||||||
// network (genesis block).
|
// network (genesis block).
|
||||||
var genesisHash = wire.ShaHash([wire.HashSize]byte{ // Make go vet happy.
|
var genesisHash = chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy.
|
||||||
0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72,
|
0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72,
|
||||||
0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f,
|
0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f,
|
||||||
0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c,
|
0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c,
|
||||||
|
@ -65,7 +66,7 @@ var genesisHash = wire.ShaHash([wire.HashSize]byte{ // Make go vet happy.
|
||||||
|
|
||||||
// genesisMerkleRoot is the hash of the first transaction in the genesis block
|
// genesisMerkleRoot is the hash of the first transaction in the genesis block
|
||||||
// for the main network.
|
// for the main network.
|
||||||
var genesisMerkleRoot = wire.ShaHash([wire.HashSize]byte{ // Make go vet happy.
|
var genesisMerkleRoot = chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy.
|
||||||
0x3b, 0xa3, 0xed, 0xfd, 0x7a, 0x7b, 0x12, 0xb2,
|
0x3b, 0xa3, 0xed, 0xfd, 0x7a, 0x7b, 0x12, 0xb2,
|
||||||
0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f, 0x61,
|
0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f, 0x61,
|
||||||
0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32,
|
0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32,
|
||||||
|
@ -77,7 +78,7 @@ var genesisMerkleRoot = wire.ShaHash([wire.HashSize]byte{ // Make go vet happy.
|
||||||
var genesisBlock = wire.MsgBlock{
|
var genesisBlock = wire.MsgBlock{
|
||||||
Header: wire.BlockHeader{
|
Header: wire.BlockHeader{
|
||||||
Version: 1,
|
Version: 1,
|
||||||
PrevBlock: wire.ShaHash{}, // 0000000000000000000000000000000000000000000000000000000000000000
|
PrevBlock: chainhash.Hash{}, // 0000000000000000000000000000000000000000000000000000000000000000
|
||||||
MerkleRoot: genesisMerkleRoot, // 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b
|
MerkleRoot: genesisMerkleRoot, // 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b
|
||||||
Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 18:15:05 +0000 UTC
|
Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 18:15:05 +0000 UTC
|
||||||
Bits: 0x1d00ffff, // 486604799 [00000000ffff0000000000000000000000000000000000000000000000000000]
|
Bits: 0x1d00ffff, // 486604799 [00000000ffff0000000000000000000000000000000000000000000000000000]
|
||||||
|
@ -88,7 +89,7 @@ var genesisBlock = wire.MsgBlock{
|
||||||
|
|
||||||
// regTestGenesisHash is the hash of the first block in the block chain for the
|
// regTestGenesisHash is the hash of the first block in the block chain for the
|
||||||
// regression test network (genesis block).
|
// regression test network (genesis block).
|
||||||
var regTestGenesisHash = wire.ShaHash([wire.HashSize]byte{ // Make go vet happy.
|
var regTestGenesisHash = chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy.
|
||||||
0x06, 0x22, 0x6e, 0x46, 0x11, 0x1a, 0x0b, 0x59,
|
0x06, 0x22, 0x6e, 0x46, 0x11, 0x1a, 0x0b, 0x59,
|
||||||
0xca, 0xaf, 0x12, 0x60, 0x43, 0xeb, 0x5b, 0xbf,
|
0xca, 0xaf, 0x12, 0x60, 0x43, 0xeb, 0x5b, 0xbf,
|
||||||
0x28, 0xc3, 0x4f, 0x3a, 0x5e, 0x33, 0x2a, 0x1f,
|
0x28, 0xc3, 0x4f, 0x3a, 0x5e, 0x33, 0x2a, 0x1f,
|
||||||
|
@ -105,7 +106,7 @@ var regTestGenesisMerkleRoot = genesisMerkleRoot
|
||||||
var regTestGenesisBlock = wire.MsgBlock{
|
var regTestGenesisBlock = wire.MsgBlock{
|
||||||
Header: wire.BlockHeader{
|
Header: wire.BlockHeader{
|
||||||
Version: 1,
|
Version: 1,
|
||||||
PrevBlock: wire.ShaHash{}, // 0000000000000000000000000000000000000000000000000000000000000000
|
PrevBlock: chainhash.Hash{}, // 0000000000000000000000000000000000000000000000000000000000000000
|
||||||
MerkleRoot: regTestGenesisMerkleRoot, // 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b
|
MerkleRoot: regTestGenesisMerkleRoot, // 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b
|
||||||
Timestamp: time.Unix(1296688602, 0), // 2011-02-02 23:16:42 +0000 UTC
|
Timestamp: time.Unix(1296688602, 0), // 2011-02-02 23:16:42 +0000 UTC
|
||||||
Bits: 0x207fffff, // 545259519 [7fffff0000000000000000000000000000000000000000000000000000000000]
|
Bits: 0x207fffff, // 545259519 [7fffff0000000000000000000000000000000000000000000000000000000000]
|
||||||
|
@ -116,7 +117,7 @@ var regTestGenesisBlock = wire.MsgBlock{
|
||||||
|
|
||||||
// testNet3GenesisHash is the hash of the first block in the block chain for the
|
// testNet3GenesisHash is the hash of the first block in the block chain for the
|
||||||
// test network (version 3).
|
// test network (version 3).
|
||||||
var testNet3GenesisHash = wire.ShaHash([wire.HashSize]byte{ // Make go vet happy.
|
var testNet3GenesisHash = chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy.
|
||||||
0x43, 0x49, 0x7f, 0xd7, 0xf8, 0x26, 0x95, 0x71,
|
0x43, 0x49, 0x7f, 0xd7, 0xf8, 0x26, 0x95, 0x71,
|
||||||
0x08, 0xf4, 0xa3, 0x0f, 0xd9, 0xce, 0xc3, 0xae,
|
0x08, 0xf4, 0xa3, 0x0f, 0xd9, 0xce, 0xc3, 0xae,
|
||||||
0xba, 0x79, 0x97, 0x20, 0x84, 0xe9, 0x0e, 0xad,
|
0xba, 0x79, 0x97, 0x20, 0x84, 0xe9, 0x0e, 0xad,
|
||||||
|
@ -133,7 +134,7 @@ var testNet3GenesisMerkleRoot = genesisMerkleRoot
|
||||||
var testNet3GenesisBlock = wire.MsgBlock{
|
var testNet3GenesisBlock = wire.MsgBlock{
|
||||||
Header: wire.BlockHeader{
|
Header: wire.BlockHeader{
|
||||||
Version: 1,
|
Version: 1,
|
||||||
PrevBlock: wire.ShaHash{}, // 0000000000000000000000000000000000000000000000000000000000000000
|
PrevBlock: chainhash.Hash{}, // 0000000000000000000000000000000000000000000000000000000000000000
|
||||||
MerkleRoot: testNet3GenesisMerkleRoot, // 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b
|
MerkleRoot: testNet3GenesisMerkleRoot, // 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b
|
||||||
Timestamp: time.Unix(1296688602, 0), // 2011-02-02 23:16:42 +0000 UTC
|
Timestamp: time.Unix(1296688602, 0), // 2011-02-02 23:16:42 +0000 UTC
|
||||||
Bits: 0x1d00ffff, // 486604799 [00000000ffff0000000000000000000000000000000000000000000000000000]
|
Bits: 0x1d00ffff, // 486604799 [00000000ffff0000000000000000000000000000000000000000000000000000]
|
||||||
|
@ -144,7 +145,7 @@ var testNet3GenesisBlock = wire.MsgBlock{
|
||||||
|
|
||||||
// simNetGenesisHash is the hash of the first block in the block chain for the
|
// simNetGenesisHash is the hash of the first block in the block chain for the
|
||||||
// simulation test network.
|
// simulation test network.
|
||||||
var simNetGenesisHash = wire.ShaHash([wire.HashSize]byte{ // Make go vet happy.
|
var simNetGenesisHash = chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy.
|
||||||
0xf6, 0x7a, 0xd7, 0x69, 0x5d, 0x9b, 0x66, 0x2a,
|
0xf6, 0x7a, 0xd7, 0x69, 0x5d, 0x9b, 0x66, 0x2a,
|
||||||
0x72, 0xff, 0x3d, 0x8e, 0xdb, 0xbb, 0x2d, 0xe0,
|
0x72, 0xff, 0x3d, 0x8e, 0xdb, 0xbb, 0x2d, 0xe0,
|
||||||
0xbf, 0xa6, 0x7b, 0x13, 0x97, 0x4b, 0xb9, 0x91,
|
0xbf, 0xa6, 0x7b, 0x13, 0x97, 0x4b, 0xb9, 0x91,
|
||||||
|
@ -161,7 +162,7 @@ var simNetGenesisMerkleRoot = genesisMerkleRoot
|
||||||
var simNetGenesisBlock = wire.MsgBlock{
|
var simNetGenesisBlock = wire.MsgBlock{
|
||||||
Header: wire.BlockHeader{
|
Header: wire.BlockHeader{
|
||||||
Version: 1,
|
Version: 1,
|
||||||
PrevBlock: wire.ShaHash{}, // 0000000000000000000000000000000000000000000000000000000000000000
|
PrevBlock: chainhash.Hash{}, // 0000000000000000000000000000000000000000000000000000000000000000
|
||||||
MerkleRoot: simNetGenesisMerkleRoot, // 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b
|
MerkleRoot: simNetGenesisMerkleRoot, // 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b
|
||||||
Timestamp: time.Unix(1401292357, 0), // 2014-05-28 15:52:37 +0000 UTC
|
Timestamp: time.Unix(1401292357, 0), // 2014-05-28 15:52:37 +0000 UTC
|
||||||
Bits: 0x207fffff, // 545259519 [7fffff0000000000000000000000000000000000000000000000000000000000]
|
Bits: 0x207fffff, // 545259519 [7fffff0000000000000000000000000000000000000000000000000000000000]
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014 The btcsuite developers
|
// Copyright (c) 2014-2016 The btcsuite developers
|
||||||
// Use of this source code is governed by an ISC
|
// Use of this source code is governed by an ISC
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ func TestGenesisBlock(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check hash of the block against expected hash.
|
// Check hash of the block against expected hash.
|
||||||
hash := MainNetParams.GenesisBlock.BlockSha()
|
hash := MainNetParams.GenesisBlock.BlockHash()
|
||||||
if !MainNetParams.GenesisHash.IsEqual(&hash) {
|
if !MainNetParams.GenesisHash.IsEqual(&hash) {
|
||||||
t.Fatalf("TestGenesisBlock: Genesis block hash does not "+
|
t.Fatalf("TestGenesisBlock: Genesis block hash does not "+
|
||||||
"appear valid - got %v, want %v", spew.Sdump(hash),
|
"appear valid - got %v, want %v", spew.Sdump(hash),
|
||||||
|
@ -56,7 +56,7 @@ func TestRegTestGenesisBlock(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check hash of the block against expected hash.
|
// Check hash of the block against expected hash.
|
||||||
hash := RegressionNetParams.GenesisBlock.BlockSha()
|
hash := RegressionNetParams.GenesisBlock.BlockHash()
|
||||||
if !RegressionNetParams.GenesisHash.IsEqual(&hash) {
|
if !RegressionNetParams.GenesisHash.IsEqual(&hash) {
|
||||||
t.Fatalf("TestRegTestGenesisBlock: Genesis block hash does "+
|
t.Fatalf("TestRegTestGenesisBlock: Genesis block hash does "+
|
||||||
"not appear valid - got %v, want %v", spew.Sdump(hash),
|
"not appear valid - got %v, want %v", spew.Sdump(hash),
|
||||||
|
@ -83,7 +83,7 @@ func TestTestNet3GenesisBlock(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check hash of the block against expected hash.
|
// Check hash of the block against expected hash.
|
||||||
hash := TestNet3Params.GenesisBlock.BlockSha()
|
hash := TestNet3Params.GenesisBlock.BlockHash()
|
||||||
if !TestNet3Params.GenesisHash.IsEqual(&hash) {
|
if !TestNet3Params.GenesisHash.IsEqual(&hash) {
|
||||||
t.Fatalf("TestTestNet3GenesisBlock: Genesis block hash does "+
|
t.Fatalf("TestTestNet3GenesisBlock: Genesis block hash does "+
|
||||||
"not appear valid - got %v, want %v", spew.Sdump(hash),
|
"not appear valid - got %v, want %v", spew.Sdump(hash),
|
||||||
|
@ -110,7 +110,7 @@ func TestSimNetGenesisBlock(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check hash of the block against expected hash.
|
// Check hash of the block against expected hash.
|
||||||
hash := SimNetParams.GenesisBlock.BlockSha()
|
hash := SimNetParams.GenesisBlock.BlockHash()
|
||||||
if !SimNetParams.GenesisHash.IsEqual(&hash) {
|
if !SimNetParams.GenesisHash.IsEqual(&hash) {
|
||||||
t.Fatalf("TestSimNetGenesisBlock: Genesis block hash does "+
|
t.Fatalf("TestSimNetGenesisBlock: Genesis block hash does "+
|
||||||
"not appear valid - got %v, want %v", spew.Sdump(hash),
|
"not appear valid - got %v, want %v", spew.Sdump(hash),
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014 The btcsuite developers
|
// Copyright (c) 2014-2016 The btcsuite developers
|
||||||
// Use of this source code is governed by an ISC
|
// Use of this source code is governed by an ISC
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -45,7 +46,7 @@ var (
|
||||||
// selection criteria.
|
// selection criteria.
|
||||||
type Checkpoint struct {
|
type Checkpoint struct {
|
||||||
Height int32
|
Height int32
|
||||||
Hash *wire.ShaHash
|
Hash *chainhash.Hash
|
||||||
}
|
}
|
||||||
|
|
||||||
// Params defines a Bitcoin network by its parameters. These parameters may be
|
// Params defines a Bitcoin network by its parameters. These parameters may be
|
||||||
|
@ -59,7 +60,7 @@ type Params struct {
|
||||||
|
|
||||||
// Chain parameters
|
// Chain parameters
|
||||||
GenesisBlock *wire.MsgBlock
|
GenesisBlock *wire.MsgBlock
|
||||||
GenesisHash *wire.ShaHash
|
GenesisHash *chainhash.Hash
|
||||||
PowLimit *big.Int
|
PowLimit *big.Int
|
||||||
PowLimitBits uint32
|
PowLimitBits uint32
|
||||||
SubsidyHalvingInterval int32
|
SubsidyHalvingInterval int32
|
||||||
|
@ -123,24 +124,24 @@ var MainNetParams = Params{
|
||||||
|
|
||||||
// Checkpoints ordered from oldest to newest.
|
// Checkpoints ordered from oldest to newest.
|
||||||
Checkpoints: []Checkpoint{
|
Checkpoints: []Checkpoint{
|
||||||
{11111, newShaHashFromStr("0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d")},
|
{11111, newHashFromStr("0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d")},
|
||||||
{33333, newShaHashFromStr("000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6")},
|
{33333, newHashFromStr("000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6")},
|
||||||
{74000, newShaHashFromStr("0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20")},
|
{74000, newHashFromStr("0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20")},
|
||||||
{105000, newShaHashFromStr("00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97")},
|
{105000, newHashFromStr("00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97")},
|
||||||
{134444, newShaHashFromStr("00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe")},
|
{134444, newHashFromStr("00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe")},
|
||||||
{168000, newShaHashFromStr("000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763")},
|
{168000, newHashFromStr("000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763")},
|
||||||
{193000, newShaHashFromStr("000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317")},
|
{193000, newHashFromStr("000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317")},
|
||||||
{210000, newShaHashFromStr("000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e")},
|
{210000, newHashFromStr("000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e")},
|
||||||
{216116, newShaHashFromStr("00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e")},
|
{216116, newHashFromStr("00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e")},
|
||||||
{225430, newShaHashFromStr("00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932")},
|
{225430, newHashFromStr("00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932")},
|
||||||
{250000, newShaHashFromStr("000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214")},
|
{250000, newHashFromStr("000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214")},
|
||||||
{267300, newShaHashFromStr("000000000000000a83fbd660e918f218bf37edd92b748ad940483c7c116179ac")},
|
{267300, newHashFromStr("000000000000000a83fbd660e918f218bf37edd92b748ad940483c7c116179ac")},
|
||||||
{279000, newShaHashFromStr("0000000000000001ae8c72a0b0c301f67e3afca10e819efa9041e458e9bd7e40")},
|
{279000, newHashFromStr("0000000000000001ae8c72a0b0c301f67e3afca10e819efa9041e458e9bd7e40")},
|
||||||
{300255, newShaHashFromStr("0000000000000000162804527c6e9b9f0563a280525f9d08c12041def0a0f3b2")},
|
{300255, newHashFromStr("0000000000000000162804527c6e9b9f0563a280525f9d08c12041def0a0f3b2")},
|
||||||
{319400, newShaHashFromStr("000000000000000021c6052e9becade189495d1c539aa37c58917305fd15f13b")},
|
{319400, newHashFromStr("000000000000000021c6052e9becade189495d1c539aa37c58917305fd15f13b")},
|
||||||
{343185, newShaHashFromStr("0000000000000000072b8bf361d01a6ba7d445dd024203fafc78768ed4368554")},
|
{343185, newHashFromStr("0000000000000000072b8bf361d01a6ba7d445dd024203fafc78768ed4368554")},
|
||||||
{352940, newShaHashFromStr("000000000000000010755df42dba556bb72be6a32f3ce0b6941ce4430152c9ff")},
|
{352940, newHashFromStr("000000000000000010755df42dba556bb72be6a32f3ce0b6941ce4430152c9ff")},
|
||||||
{382320, newShaHashFromStr("00000000000000000a8dc6ed5b133d0eb2fd6af56203e4159789b092defd8ab2")},
|
{382320, newHashFromStr("00000000000000000a8dc6ed5b133d0eb2fd6af56203e4159789b092defd8ab2")},
|
||||||
},
|
},
|
||||||
|
|
||||||
// Enforce current block version once majority of the network has
|
// Enforce current block version once majority of the network has
|
||||||
|
@ -242,7 +243,7 @@ var TestNet3Params = Params{
|
||||||
|
|
||||||
// Checkpoints ordered from oldest to newest.
|
// Checkpoints ordered from oldest to newest.
|
||||||
Checkpoints: []Checkpoint{
|
Checkpoints: []Checkpoint{
|
||||||
{546, newShaHashFromStr("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70")},
|
{546, newHashFromStr("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70")},
|
||||||
},
|
},
|
||||||
|
|
||||||
// Enforce current block version once majority of the network has
|
// Enforce current block version once majority of the network has
|
||||||
|
@ -411,12 +412,12 @@ func HDPrivateKeyToPublicKeyID(id []byte) ([]byte, error) {
|
||||||
return pubBytes, nil
|
return pubBytes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// newShaHashFromStr converts the passed big-endian hex string into a
|
// newHashFromStr converts the passed big-endian hex string into a
|
||||||
// wire.ShaHash. It only differs from the one available in wire in that
|
// chainhash.Hash. It only differs from the one available in chainhash in that
|
||||||
// it panics on an error since it will only (and must only) be called with
|
// it panics on an error since it will only (and must only) be called with
|
||||||
// hard-coded, and therefore known good, hashes.
|
// hard-coded, and therefore known good, hashes.
|
||||||
func newShaHashFromStr(hexStr string) *wire.ShaHash {
|
func newHashFromStr(hexStr string) *chainhash.Hash {
|
||||||
sha, err := wire.NewShaHashFromStr(hexStr)
|
hash, err := chainhash.NewHashFromStr(hexStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Ordinarily I don't like panics in library code since it
|
// Ordinarily I don't like panics in library code since it
|
||||||
// can take applications down without them having a chance to
|
// can take applications down without them having a chance to
|
||||||
|
@ -427,7 +428,7 @@ func newShaHashFromStr(hexStr string) *wire.ShaHash {
|
||||||
// 100% predictable.
|
// 100% predictable.
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
return sha
|
return hash
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|
|
@ -14,7 +14,7 @@ func TestInvalidHashStr(t *testing.T) {
|
||||||
t.Errorf("Expected panic for invalid hash, got nil")
|
t.Errorf("Expected panic for invalid hash, got nil")
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
newShaHashFromStr("banana")
|
newHashFromStr("banana")
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestMustRegisterPanic ensures the mustRegister function panics when used to
|
// TestMustRegisterPanic ensures the mustRegister function panics when used to
|
||||||
|
|
|
@ -13,12 +13,13 @@ import (
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/blockchain"
|
"github.com/btcsuite/btcd/blockchain"
|
||||||
"github.com/btcsuite/btcd/blockchain/indexers"
|
"github.com/btcsuite/btcd/blockchain/indexers"
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/database"
|
"github.com/btcsuite/btcd/database"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
"github.com/btcsuite/btcutil"
|
"github.com/btcsuite/btcutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
var zeroHash = wire.ShaHash{}
|
var zeroHash = chainhash.Hash{}
|
||||||
|
|
||||||
// importResults houses the stats and result as an import operation.
|
// importResults houses the stats and result as an import operation.
|
||||||
type importResults struct {
|
type importResults struct {
|
||||||
|
@ -103,8 +104,8 @@ func (bi *blockImporter) processBlock(serializedBlock []byte) (bool, error) {
|
||||||
bi.receivedLogTx += int64(len(block.MsgBlock().Transactions))
|
bi.receivedLogTx += int64(len(block.MsgBlock().Transactions))
|
||||||
|
|
||||||
// Skip blocks that already exist.
|
// Skip blocks that already exist.
|
||||||
blockSha := block.Sha()
|
blockHash := block.Hash()
|
||||||
exists, err := bi.chain.HaveBlock(blockSha)
|
exists, err := bi.chain.HaveBlock(blockHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
@ -134,7 +135,7 @@ func (bi *blockImporter) processBlock(serializedBlock []byte) (bool, error) {
|
||||||
}
|
}
|
||||||
if isOrphan {
|
if isOrphan {
|
||||||
return false, fmt.Errorf("import file contains an orphan "+
|
return false, fmt.Errorf("import file contains an orphan "+
|
||||||
"block: %v", blockSha)
|
"block: %v", blockHash)
|
||||||
}
|
}
|
||||||
|
|
||||||
return true, nil
|
return true, nil
|
||||||
|
|
|
@ -11,8 +11,8 @@ import (
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/blockchain"
|
"github.com/btcsuite/btcd/blockchain"
|
||||||
"github.com/btcsuite/btcd/chaincfg"
|
"github.com/btcsuite/btcd/chaincfg"
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/database"
|
"github.com/btcsuite/btcd/database"
|
||||||
"github.com/btcsuite/btcd/wire"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const blockDbNamePrefix = "blocks"
|
const blockDbNamePrefix = "blocks"
|
||||||
|
@ -39,7 +39,7 @@ func loadBlockDB() (database.DB, error) {
|
||||||
// candidates at the last checkpoint that is already hard coded into btcchain
|
// candidates at the last checkpoint that is already hard coded into btcchain
|
||||||
// since there is no point in finding candidates before already existing
|
// since there is no point in finding candidates before already existing
|
||||||
// checkpoints.
|
// checkpoints.
|
||||||
func findCandidates(chain *blockchain.BlockChain, latestHash *wire.ShaHash) ([]*chaincfg.Checkpoint, error) {
|
func findCandidates(chain *blockchain.BlockChain, latestHash *chainhash.Hash) ([]*chaincfg.Checkpoint, error) {
|
||||||
// Start with the latest block of the main chain.
|
// Start with the latest block of the main chain.
|
||||||
block, err := chain.BlockByHash(latestHash)
|
block, err := chain.BlockByHash(latestHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -102,7 +102,7 @@ func findCandidates(chain *blockchain.BlockChain, latestHash *wire.ShaHash) ([]*
|
||||||
if isCandidate {
|
if isCandidate {
|
||||||
checkpoint := chaincfg.Checkpoint{
|
checkpoint := chaincfg.Checkpoint{
|
||||||
Height: block.Height(),
|
Height: block.Height(),
|
||||||
Hash: block.Sha(),
|
Hash: block.Hash(),
|
||||||
}
|
}
|
||||||
candidates = append(candidates, &checkpoint)
|
candidates = append(candidates, &checkpoint)
|
||||||
}
|
}
|
||||||
|
|
15
cpuminer.go
15
cpuminer.go
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014 The btcsuite developers
|
// Copyright (c) 2014-2016 The btcsuite developers
|
||||||
// Use of this source code is governed by an ISC
|
// Use of this source code is governed by an ISC
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/blockchain"
|
"github.com/btcsuite/btcd/blockchain"
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/mining"
|
"github.com/btcsuite/btcd/mining"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
"github.com/btcsuite/btcutil"
|
"github.com/btcsuite/btcutil"
|
||||||
|
@ -155,7 +156,7 @@ func (m *CPUMiner) submitBlock(block *btcutil.Block) bool {
|
||||||
// The block was accepted.
|
// The block was accepted.
|
||||||
coinbaseTx := block.MsgBlock().Transactions[0].TxOut[0]
|
coinbaseTx := block.MsgBlock().Transactions[0].TxOut[0]
|
||||||
minrLog.Infof("Block submitted via CPU miner accepted (hash %s, "+
|
minrLog.Infof("Block submitted via CPU miner accepted (hash %s, "+
|
||||||
"amount %v)", block.Sha(), btcutil.Amount(coinbaseTx.Value))
|
"amount %v)", block.Hash(), btcutil.Amount(coinbaseTx.Value))
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,12 +239,12 @@ func (m *CPUMiner) solveBlock(msgBlock *wire.MsgBlock, blockHeight int32,
|
||||||
// increment the number of hashes completed for each
|
// increment the number of hashes completed for each
|
||||||
// attempt accordingly.
|
// attempt accordingly.
|
||||||
header.Nonce = i
|
header.Nonce = i
|
||||||
hash := header.BlockSha()
|
hash := header.BlockHash()
|
||||||
hashesCompleted += 2
|
hashesCompleted += 2
|
||||||
|
|
||||||
// The block is solved when the new block hash is less
|
// The block is solved when the new block hash is less
|
||||||
// than the target difficulty. Yay!
|
// than the target difficulty. Yay!
|
||||||
if blockchain.ShaHashToBig(&hash).Cmp(targetDifficulty) <= 0 {
|
if blockchain.HashToBig(&hash).Cmp(targetDifficulty) <= 0 {
|
||||||
m.updateHashes <- hashesCompleted
|
m.updateHashes <- hashesCompleted
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -508,7 +509,7 @@ func (m *CPUMiner) NumWorkers() int32 {
|
||||||
// detecting when it is performing stale work and reacting accordingly by
|
// detecting when it is performing stale work and reacting accordingly by
|
||||||
// generating a new block template. When a block is solved, it is submitted.
|
// generating a new block template. When a block is solved, it is submitted.
|
||||||
// The function returns a list of the hashes of generated blocks.
|
// The function returns a list of the hashes of generated blocks.
|
||||||
func (m *CPUMiner) GenerateNBlocks(n uint32) ([]*wire.ShaHash, error) {
|
func (m *CPUMiner) GenerateNBlocks(n uint32) ([]*chainhash.Hash, error) {
|
||||||
m.Lock()
|
m.Lock()
|
||||||
|
|
||||||
// Respond with an error if there's virtually 0 chance of CPU-mining a block.
|
// Respond with an error if there's virtually 0 chance of CPU-mining a block.
|
||||||
|
@ -538,7 +539,7 @@ func (m *CPUMiner) GenerateNBlocks(n uint32) ([]*wire.ShaHash, error) {
|
||||||
minrLog.Tracef("Generating %d blocks", n)
|
minrLog.Tracef("Generating %d blocks", n)
|
||||||
|
|
||||||
i := uint32(0)
|
i := uint32(0)
|
||||||
blockHashes := make([]*wire.ShaHash, n, n)
|
blockHashes := make([]*chainhash.Hash, n, n)
|
||||||
|
|
||||||
// Start a ticker which is used to signal checks for stale work and
|
// Start a ticker which is used to signal checks for stale work and
|
||||||
// updates to the speed monitor.
|
// updates to the speed monitor.
|
||||||
|
@ -583,7 +584,7 @@ func (m *CPUMiner) GenerateNBlocks(n uint32) ([]*wire.ShaHash, error) {
|
||||||
if m.solveBlock(template.Block, curHeight+1, ticker, nil) {
|
if m.solveBlock(template.Block, curHeight+1, ticker, nil) {
|
||||||
block := btcutil.NewBlock(template.Block)
|
block := btcutil.NewBlock(template.Block)
|
||||||
m.submitBlock(block)
|
m.submitBlock(block)
|
||||||
blockHashes[i] = block.Sha()
|
blockHashes[i] = block.Hash()
|
||||||
i++
|
i++
|
||||||
if i == n {
|
if i == n {
|
||||||
minrLog.Tracef("Generated %d blocks", i)
|
minrLog.Tracef("Generated %d blocks", i)
|
||||||
|
|
|
@ -9,8 +9,8 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/database"
|
"github.com/btcsuite/btcd/database"
|
||||||
"github.com/btcsuite/btcd/wire"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// fetchBlockCmd defines the configuration options for the fetchblock command.
|
// fetchBlockCmd defines the configuration options for the fetchblock command.
|
||||||
|
@ -31,7 +31,7 @@ func (cmd *fetchBlockCmd) Execute(args []string) error {
|
||||||
if len(args) < 1 {
|
if len(args) < 1 {
|
||||||
return errors.New("required block hash parameter not specified")
|
return errors.New("required block hash parameter not specified")
|
||||||
}
|
}
|
||||||
blockHash, err := wire.NewShaHashFromStr(args[0])
|
blockHash, err := chainhash.NewHashFromStr(args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,8 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/database"
|
"github.com/btcsuite/btcd/database"
|
||||||
"github.com/btcsuite/btcd/wire"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// blockRegionCmd defines the configuration options for the fetchblockregion
|
// blockRegionCmd defines the configuration options for the fetchblockregion
|
||||||
|
@ -44,7 +44,7 @@ func (cmd *blockRegionCmd) Execute(args []string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse arguments.
|
// Parse arguments.
|
||||||
blockHash, err := wire.NewShaHashFromStr(args[0])
|
blockHash, err := chainhash.NewHashFromStr(args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ func (cmd *blockRegionCmd) Execute(args []string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.Infof("Loaded block region in %v", time.Now().Sub(startTime))
|
log.Infof("Loaded block region in %v", time.Now().Sub(startTime))
|
||||||
log.Infof("Double SHA256: %s", wire.DoubleSha256SH(regionBytes))
|
log.Infof("Double Hash: %s", chainhash.DoubleHashH(regionBytes))
|
||||||
log.Infof("Region Hex: %s", hex.EncodeToString(regionBytes))
|
log.Infof("Region Hex: %s", hex.EncodeToString(regionBytes))
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/database"
|
"github.com/btcsuite/btcd/database"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
"github.com/btcsuite/btcutil"
|
"github.com/btcsuite/btcutil"
|
||||||
|
@ -32,7 +33,7 @@ var (
|
||||||
|
|
||||||
// zeroHash is a simply a hash with all zeros. It is defined here to
|
// zeroHash is a simply a hash with all zeros. It is defined here to
|
||||||
// avoid creating it multiple times.
|
// avoid creating it multiple times.
|
||||||
zeroHash = wire.ShaHash{}
|
zeroHash = chainhash.Hash{}
|
||||||
)
|
)
|
||||||
|
|
||||||
// importResults houses the stats and result as an import operation.
|
// importResults houses the stats and result as an import operation.
|
||||||
|
@ -119,7 +120,7 @@ func (bi *blockImporter) processBlock(serializedBlock []byte) (bool, error) {
|
||||||
// Skip blocks that already exist.
|
// Skip blocks that already exist.
|
||||||
var exists bool
|
var exists bool
|
||||||
err = bi.db.View(func(tx database.Tx) error {
|
err = bi.db.View(func(tx database.Tx) error {
|
||||||
exists, err = tx.HasBlock(block.Sha())
|
exists, err = tx.HasBlock(block.Hash())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,8 @@ package main
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/database"
|
"github.com/btcsuite/btcd/database"
|
||||||
"github.com/btcsuite/btcd/wire"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// headersCmd defines the configuration options for the loadheaders command.
|
// headersCmd defines the configuration options for the loadheaders command.
|
||||||
|
@ -52,7 +52,7 @@ func (cmd *headersCmd) Execute(args []string) error {
|
||||||
numLoaded := 0
|
numLoaded := 0
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
blockIdxBucket.ForEach(func(k, v []byte) error {
|
blockIdxBucket.ForEach(func(k, v []byte) error {
|
||||||
var hash wire.ShaHash
|
var hash chainhash.Hash
|
||||||
copy(hash[:], k)
|
copy(hash[:], k)
|
||||||
_, err := tx.FetchBlockHeader(&hash)
|
_, err := tx.FetchBlockHeader(&hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -75,9 +75,9 @@ func (cmd *headersCmd) Execute(args []string) error {
|
||||||
// Bulk load headers.
|
// Bulk load headers.
|
||||||
err = db.View(func(tx database.Tx) error {
|
err = db.View(func(tx database.Tx) error {
|
||||||
blockIdxBucket := tx.Metadata().Bucket(blockIdxName)
|
blockIdxBucket := tx.Metadata().Bucket(blockIdxName)
|
||||||
hashes := make([]wire.ShaHash, 0, 500000)
|
hashes := make([]chainhash.Hash, 0, 500000)
|
||||||
blockIdxBucket.ForEach(func(k, v []byte) error {
|
blockIdxBucket.ForEach(func(k, v []byte) error {
|
||||||
var hash wire.ShaHash
|
var hash chainhash.Hash
|
||||||
copy(hash[:], k)
|
copy(hash[:], k)
|
||||||
hashes = append(hashes, hash)
|
hashes = append(hashes, hash)
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -17,6 +17,7 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/database"
|
"github.com/btcsuite/btcd/database"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
)
|
)
|
||||||
|
@ -504,7 +505,7 @@ func (s *blockStore) writeBlock(rawBlock []byte) (blockLocation, error) {
|
||||||
// read from the file.
|
// read from the file.
|
||||||
//
|
//
|
||||||
// Format: <network><block length><serialized block><checksum>
|
// Format: <network><block length><serialized block><checksum>
|
||||||
func (s *blockStore) readBlock(hash *wire.ShaHash, loc blockLocation) ([]byte, error) {
|
func (s *blockStore) readBlock(hash *chainhash.Hash, loc blockLocation) ([]byte, error) {
|
||||||
// Get the referenced block file handle opening the file as needed. The
|
// Get the referenced block file handle opening the file as needed. The
|
||||||
// function also handles closing files as needed to avoid going over the
|
// function also handles closing files as needed to avoid going over the
|
||||||
// max allowed open files.
|
// max allowed open files.
|
||||||
|
|
|
@ -14,6 +14,7 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/database"
|
"github.com/btcsuite/btcd/database"
|
||||||
"github.com/btcsuite/btcd/database/internal/treap"
|
"github.com/btcsuite/btcd/database/internal/treap"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
|
@ -944,7 +945,7 @@ func (b *bucket) Delete(key []byte) error {
|
||||||
// pendingBlock houses a block that will be written to disk when the database
|
// pendingBlock houses a block that will be written to disk when the database
|
||||||
// transaction is committed.
|
// transaction is committed.
|
||||||
type pendingBlock struct {
|
type pendingBlock struct {
|
||||||
hash *wire.ShaHash
|
hash *chainhash.Hash
|
||||||
bytes []byte
|
bytes []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -962,7 +963,7 @@ type transaction struct {
|
||||||
|
|
||||||
// Blocks that need to be stored on commit. The pendingBlocks map is
|
// Blocks that need to be stored on commit. The pendingBlocks map is
|
||||||
// kept to allow quick lookups of pending data by block hash.
|
// kept to allow quick lookups of pending data by block hash.
|
||||||
pendingBlocks map[wire.ShaHash]int
|
pendingBlocks map[chainhash.Hash]int
|
||||||
pendingBlockData []pendingBlock
|
pendingBlockData []pendingBlock
|
||||||
|
|
||||||
// Keys that need to be stored or deleted on commit.
|
// Keys that need to be stored or deleted on commit.
|
||||||
|
@ -1124,7 +1125,7 @@ func (tx *transaction) Metadata() database.Bucket {
|
||||||
}
|
}
|
||||||
|
|
||||||
// hasBlock returns whether or not a block with the given hash exists.
|
// hasBlock returns whether or not a block with the given hash exists.
|
||||||
func (tx *transaction) hasBlock(hash *wire.ShaHash) bool {
|
func (tx *transaction) hasBlock(hash *chainhash.Hash) bool {
|
||||||
// Return true if the block is pending to be written on commit since
|
// Return true if the block is pending to be written on commit since
|
||||||
// it exists from the viewpoint of this transaction.
|
// it exists from the viewpoint of this transaction.
|
||||||
if _, exists := tx.pendingBlocks[*hash]; exists {
|
if _, exists := tx.pendingBlocks[*hash]; exists {
|
||||||
|
@ -1158,7 +1159,7 @@ func (tx *transaction) StoreBlock(block *btcutil.Block) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reject the block if it already exists.
|
// Reject the block if it already exists.
|
||||||
blockHash := block.Sha()
|
blockHash := block.Hash()
|
||||||
if tx.hasBlock(blockHash) {
|
if tx.hasBlock(blockHash) {
|
||||||
str := fmt.Sprintf("block %s already exists", blockHash)
|
str := fmt.Sprintf("block %s already exists", blockHash)
|
||||||
return makeDbErr(database.ErrBlockExists, str, nil)
|
return makeDbErr(database.ErrBlockExists, str, nil)
|
||||||
|
@ -1176,7 +1177,7 @@ func (tx *transaction) StoreBlock(block *btcutil.Block) error {
|
||||||
// map so it is easy to determine the block is pending based on the
|
// map so it is easy to determine the block is pending based on the
|
||||||
// block hash.
|
// block hash.
|
||||||
if tx.pendingBlocks == nil {
|
if tx.pendingBlocks == nil {
|
||||||
tx.pendingBlocks = make(map[wire.ShaHash]int)
|
tx.pendingBlocks = make(map[chainhash.Hash]int)
|
||||||
}
|
}
|
||||||
tx.pendingBlocks[*blockHash] = len(tx.pendingBlockData)
|
tx.pendingBlocks[*blockHash] = len(tx.pendingBlockData)
|
||||||
tx.pendingBlockData = append(tx.pendingBlockData, pendingBlock{
|
tx.pendingBlockData = append(tx.pendingBlockData, pendingBlock{
|
||||||
|
@ -1195,7 +1196,7 @@ func (tx *transaction) StoreBlock(block *btcutil.Block) error {
|
||||||
// - ErrTxClosed if the transaction has already been closed
|
// - ErrTxClosed if the transaction has already been closed
|
||||||
//
|
//
|
||||||
// This function is part of the database.Tx interface implementation.
|
// This function is part of the database.Tx interface implementation.
|
||||||
func (tx *transaction) HasBlock(hash *wire.ShaHash) (bool, error) {
|
func (tx *transaction) HasBlock(hash *chainhash.Hash) (bool, error) {
|
||||||
// Ensure transaction state is valid.
|
// Ensure transaction state is valid.
|
||||||
if err := tx.checkClosed(); err != nil {
|
if err := tx.checkClosed(); err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
|
@ -1211,7 +1212,7 @@ func (tx *transaction) HasBlock(hash *wire.ShaHash) (bool, error) {
|
||||||
// - ErrTxClosed if the transaction has already been closed
|
// - ErrTxClosed if the transaction has already been closed
|
||||||
//
|
//
|
||||||
// This function is part of the database.Tx interface implementation.
|
// This function is part of the database.Tx interface implementation.
|
||||||
func (tx *transaction) HasBlocks(hashes []wire.ShaHash) ([]bool, error) {
|
func (tx *transaction) HasBlocks(hashes []chainhash.Hash) ([]bool, error) {
|
||||||
// Ensure transaction state is valid.
|
// Ensure transaction state is valid.
|
||||||
if err := tx.checkClosed(); err != nil {
|
if err := tx.checkClosed(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -1227,7 +1228,7 @@ func (tx *transaction) HasBlocks(hashes []wire.ShaHash) ([]bool, error) {
|
||||||
|
|
||||||
// fetchBlockRow fetches the metadata stored in the block index for the provided
|
// fetchBlockRow fetches the metadata stored in the block index for the provided
|
||||||
// hash. It will return ErrBlockNotFound if there is no entry.
|
// hash. It will return ErrBlockNotFound if there is no entry.
|
||||||
func (tx *transaction) fetchBlockRow(hash *wire.ShaHash) ([]byte, error) {
|
func (tx *transaction) fetchBlockRow(hash *chainhash.Hash) ([]byte, error) {
|
||||||
blockRow := tx.blockIdxBucket.Get(hash[:])
|
blockRow := tx.blockIdxBucket.Get(hash[:])
|
||||||
if blockRow == nil {
|
if blockRow == nil {
|
||||||
str := fmt.Sprintf("block %s does not exist", hash)
|
str := fmt.Sprintf("block %s does not exist", hash)
|
||||||
|
@ -1253,7 +1254,7 @@ func (tx *transaction) fetchBlockRow(hash *wire.ShaHash) ([]byte, error) {
|
||||||
// implementations.
|
// implementations.
|
||||||
//
|
//
|
||||||
// This function is part of the database.Tx interface implementation.
|
// This function is part of the database.Tx interface implementation.
|
||||||
func (tx *transaction) FetchBlockHeader(hash *wire.ShaHash) ([]byte, error) {
|
func (tx *transaction) FetchBlockHeader(hash *chainhash.Hash) ([]byte, error) {
|
||||||
// Ensure transaction state is valid.
|
// Ensure transaction state is valid.
|
||||||
if err := tx.checkClosed(); err != nil {
|
if err := tx.checkClosed(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -1292,7 +1293,7 @@ func (tx *transaction) FetchBlockHeader(hash *wire.ShaHash) ([]byte, error) {
|
||||||
// allows support for memory-mapped database implementations.
|
// allows support for memory-mapped database implementations.
|
||||||
//
|
//
|
||||||
// This function is part of the database.Tx interface implementation.
|
// This function is part of the database.Tx interface implementation.
|
||||||
func (tx *transaction) FetchBlockHeaders(hashes []wire.ShaHash) ([][]byte, error) {
|
func (tx *transaction) FetchBlockHeaders(hashes []chainhash.Hash) ([][]byte, error) {
|
||||||
// Ensure transaction state is valid.
|
// Ensure transaction state is valid.
|
||||||
if err := tx.checkClosed(); err != nil {
|
if err := tx.checkClosed(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -1348,7 +1349,7 @@ func (tx *transaction) FetchBlockHeaders(hashes []wire.ShaHash) ([][]byte, error
|
||||||
// allows support for memory-mapped database implementations.
|
// allows support for memory-mapped database implementations.
|
||||||
//
|
//
|
||||||
// This function is part of the database.Tx interface implementation.
|
// This function is part of the database.Tx interface implementation.
|
||||||
func (tx *transaction) FetchBlock(hash *wire.ShaHash) ([]byte, error) {
|
func (tx *transaction) FetchBlock(hash *chainhash.Hash) ([]byte, error) {
|
||||||
// Ensure transaction state is valid.
|
// Ensure transaction state is valid.
|
||||||
if err := tx.checkClosed(); err != nil {
|
if err := tx.checkClosed(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -1395,7 +1396,7 @@ func (tx *transaction) FetchBlock(hash *wire.ShaHash) ([]byte, error) {
|
||||||
// allows support for memory-mapped database implementations.
|
// allows support for memory-mapped database implementations.
|
||||||
//
|
//
|
||||||
// This function is part of the database.Tx interface implementation.
|
// This function is part of the database.Tx interface implementation.
|
||||||
func (tx *transaction) FetchBlocks(hashes []wire.ShaHash) ([][]byte, error) {
|
func (tx *transaction) FetchBlocks(hashes []chainhash.Hash) ([][]byte, error) {
|
||||||
// Ensure transaction state is valid.
|
// Ensure transaction state is valid.
|
||||||
if err := tx.checkClosed(); err != nil {
|
if err := tx.checkClosed(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -26,6 +26,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/chaincfg"
|
"github.com/btcsuite/btcd/chaincfg"
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/database"
|
"github.com/btcsuite/btcd/database"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
"github.com/btcsuite/btcutil"
|
"github.com/btcsuite/btcutil"
|
||||||
|
@ -1120,10 +1121,10 @@ func testFetchBlockIOMissing(tc *testContext, tx database.Tx) bool {
|
||||||
// Test the individual block APIs one block at a time to ensure they
|
// Test the individual block APIs one block at a time to ensure they
|
||||||
// return the expected error. Also, build the data needed to test the
|
// return the expected error. Also, build the data needed to test the
|
||||||
// bulk APIs below while looping.
|
// bulk APIs below while looping.
|
||||||
allBlockHashes := make([]wire.ShaHash, len(tc.blocks))
|
allBlockHashes := make([]chainhash.Hash, len(tc.blocks))
|
||||||
allBlockRegions := make([]database.BlockRegion, len(tc.blocks))
|
allBlockRegions := make([]database.BlockRegion, len(tc.blocks))
|
||||||
for i, block := range tc.blocks {
|
for i, block := range tc.blocks {
|
||||||
blockHash := block.Sha()
|
blockHash := block.Hash()
|
||||||
allBlockHashes[i] = *blockHash
|
allBlockHashes[i] = *blockHash
|
||||||
|
|
||||||
txLocs, err := block.TxLoc()
|
txLocs, err := block.TxLoc()
|
||||||
|
@ -1225,12 +1226,12 @@ func testFetchBlockIO(tc *testContext, tx database.Tx) bool {
|
||||||
|
|
||||||
// Test the individual block APIs one block at a time. Also, build the
|
// Test the individual block APIs one block at a time. Also, build the
|
||||||
// data needed to test the bulk APIs below while looping.
|
// data needed to test the bulk APIs below while looping.
|
||||||
allBlockHashes := make([]wire.ShaHash, len(tc.blocks))
|
allBlockHashes := make([]chainhash.Hash, len(tc.blocks))
|
||||||
allBlockBytes := make([][]byte, len(tc.blocks))
|
allBlockBytes := make([][]byte, len(tc.blocks))
|
||||||
allBlockTxLocs := make([][]wire.TxLoc, len(tc.blocks))
|
allBlockTxLocs := make([][]wire.TxLoc, len(tc.blocks))
|
||||||
allBlockRegions := make([]database.BlockRegion, len(tc.blocks))
|
allBlockRegions := make([]database.BlockRegion, len(tc.blocks))
|
||||||
for i, block := range tc.blocks {
|
for i, block := range tc.blocks {
|
||||||
blockHash := block.Sha()
|
blockHash := block.Hash()
|
||||||
allBlockHashes[i] = *blockHash
|
allBlockHashes[i] = *blockHash
|
||||||
|
|
||||||
blockBytes, err := block.Bytes()
|
blockBytes, err := block.Bytes()
|
||||||
|
@ -1322,7 +1323,7 @@ func testFetchBlockIO(tc *testContext, tx database.Tx) bool {
|
||||||
|
|
||||||
// Ensure fetching a block that doesn't exist returns the
|
// Ensure fetching a block that doesn't exist returns the
|
||||||
// expected error.
|
// expected error.
|
||||||
badBlockHash := &wire.ShaHash{}
|
badBlockHash := &chainhash.Hash{}
|
||||||
testName := fmt.Sprintf("FetchBlock(%s) invalid block",
|
testName := fmt.Sprintf("FetchBlock(%s) invalid block",
|
||||||
badBlockHash)
|
badBlockHash)
|
||||||
wantErrCode := database.ErrBlockNotFound
|
wantErrCode := database.ErrBlockNotFound
|
||||||
|
@ -1465,9 +1466,9 @@ func testFetchBlockIO(tc *testContext, tx database.Tx) bool {
|
||||||
// Ensure fetching blocks for which one doesn't exist returns the
|
// Ensure fetching blocks for which one doesn't exist returns the
|
||||||
// expected error.
|
// expected error.
|
||||||
testName := "FetchBlocks invalid hash"
|
testName := "FetchBlocks invalid hash"
|
||||||
badBlockHashes := make([]wire.ShaHash, len(allBlockHashes)+1)
|
badBlockHashes := make([]chainhash.Hash, len(allBlockHashes)+1)
|
||||||
copy(badBlockHashes, allBlockHashes)
|
copy(badBlockHashes, allBlockHashes)
|
||||||
badBlockHashes[len(badBlockHashes)-1] = wire.ShaHash{}
|
badBlockHashes[len(badBlockHashes)-1] = chainhash.Hash{}
|
||||||
wantErrCode := database.ErrBlockNotFound
|
wantErrCode := database.ErrBlockNotFound
|
||||||
_, err = tx.FetchBlocks(badBlockHashes)
|
_, err = tx.FetchBlocks(badBlockHashes)
|
||||||
if !checkDbError(tc.t, testName, err, wantErrCode) {
|
if !checkDbError(tc.t, testName, err, wantErrCode) {
|
||||||
|
@ -1487,7 +1488,7 @@ func testFetchBlockIO(tc *testContext, tx database.Tx) bool {
|
||||||
testName = "FetchBlockRegions invalid hash"
|
testName = "FetchBlockRegions invalid hash"
|
||||||
badBlockRegions := make([]database.BlockRegion, len(allBlockRegions)+1)
|
badBlockRegions := make([]database.BlockRegion, len(allBlockRegions)+1)
|
||||||
copy(badBlockRegions, allBlockRegions)
|
copy(badBlockRegions, allBlockRegions)
|
||||||
badBlockRegions[len(badBlockRegions)-1].Hash = &wire.ShaHash{}
|
badBlockRegions[len(badBlockRegions)-1].Hash = &chainhash.Hash{}
|
||||||
wantErrCode = database.ErrBlockNotFound
|
wantErrCode = database.ErrBlockNotFound
|
||||||
_, err = tx.FetchBlockRegions(badBlockRegions)
|
_, err = tx.FetchBlockRegions(badBlockRegions)
|
||||||
if !checkDbError(tc.t, testName, err, wantErrCode) {
|
if !checkDbError(tc.t, testName, err, wantErrCode) {
|
||||||
|
@ -1843,10 +1844,10 @@ func testClosedTxInterface(tc *testContext, tx database.Tx) bool {
|
||||||
// Test the individual block APIs one block at a time to ensure they
|
// Test the individual block APIs one block at a time to ensure they
|
||||||
// return the expected error. Also, build the data needed to test the
|
// return the expected error. Also, build the data needed to test the
|
||||||
// bulk APIs below while looping.
|
// bulk APIs below while looping.
|
||||||
allBlockHashes := make([]wire.ShaHash, len(tc.blocks))
|
allBlockHashes := make([]chainhash.Hash, len(tc.blocks))
|
||||||
allBlockRegions := make([]database.BlockRegion, len(tc.blocks))
|
allBlockRegions := make([]database.BlockRegion, len(tc.blocks))
|
||||||
for i, block := range tc.blocks {
|
for i, block := range tc.blocks {
|
||||||
blockHash := block.Sha()
|
blockHash := block.Hash()
|
||||||
allBlockHashes[i] = *blockHash
|
allBlockHashes[i] = *blockHash
|
||||||
|
|
||||||
txLocs, err := block.TxLoc()
|
txLocs, err := block.TxLoc()
|
||||||
|
@ -2014,7 +2015,7 @@ func testConcurrecy(tc *testContext) bool {
|
||||||
// test failures on slower systems.
|
// test failures on slower systems.
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
err := tc.db.View(func(tx database.Tx) error {
|
err := tc.db.View(func(tx database.Tx) error {
|
||||||
_, err := tx.FetchBlock(tc.blocks[0].Sha())
|
_, err := tx.FetchBlock(tc.blocks[0].Hash())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -2039,7 +2040,7 @@ func testConcurrecy(tc *testContext) bool {
|
||||||
reader := func(blockNum int) {
|
reader := func(blockNum int) {
|
||||||
err := tc.db.View(func(tx database.Tx) error {
|
err := tc.db.View(func(tx database.Tx) error {
|
||||||
time.Sleep(sleepTime)
|
time.Sleep(sleepTime)
|
||||||
_, err := tx.FetchBlock(tc.blocks[blockNum].Sha())
|
_, err := tx.FetchBlock(tc.blocks[blockNum].Hash())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -441,7 +441,7 @@ func testBlockFileErrors(tc *testContext) bool {
|
||||||
|
|
||||||
// Ensure errors in readBlock and readBlockRegion when requesting a file
|
// Ensure errors in readBlock and readBlockRegion when requesting a file
|
||||||
// number that doesn't exist.
|
// number that doesn't exist.
|
||||||
block0Hash := tc.blocks[0].Sha()
|
block0Hash := tc.blocks[0].Hash()
|
||||||
testName = "readBlock invalid file number"
|
testName = "readBlock invalid file number"
|
||||||
invalidLoc := blockLocation{
|
invalidLoc := blockLocation{
|
||||||
blockFileNum: ^uint32(0),
|
blockFileNum: ^uint32(0),
|
||||||
|
@ -530,7 +530,7 @@ func testCorruption(tc *testContext) bool {
|
||||||
// Ensure corruption is detected by intentionally modifying the bytes
|
// Ensure corruption is detected by intentionally modifying the bytes
|
||||||
// stored to the mock file and reading the block.
|
// stored to the mock file and reading the block.
|
||||||
block0Bytes, _ := tc.blocks[0].Bytes()
|
block0Bytes, _ := tc.blocks[0].Bytes()
|
||||||
block0Hash := tc.blocks[0].Sha()
|
block0Hash := tc.blocks[0].Hash()
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
offset uint32
|
offset uint32
|
||||||
fixChecksum bool
|
fixChecksum bool
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
package database
|
package database
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcutil"
|
"github.com/btcsuite/btcutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -198,7 +198,7 @@ type Bucket interface {
|
||||||
// BlockRegion specifies a particular region of a block identified by the
|
// BlockRegion specifies a particular region of a block identified by the
|
||||||
// specified hash, given an offset and length.
|
// specified hash, given an offset and length.
|
||||||
type BlockRegion struct {
|
type BlockRegion struct {
|
||||||
Hash *wire.ShaHash
|
Hash *chainhash.Hash
|
||||||
Offset uint32
|
Offset uint32
|
||||||
Len uint32
|
Len uint32
|
||||||
}
|
}
|
||||||
|
@ -237,7 +237,7 @@ type Tx interface {
|
||||||
// - ErrTxClosed if the transaction has already been closed
|
// - ErrTxClosed if the transaction has already been closed
|
||||||
//
|
//
|
||||||
// Other errors are possible depending on the implementation.
|
// Other errors are possible depending on the implementation.
|
||||||
HasBlock(hash *wire.ShaHash) (bool, error)
|
HasBlock(hash *chainhash.Hash) (bool, error)
|
||||||
|
|
||||||
// HasBlocks returns whether or not the blocks with the provided hashes
|
// HasBlocks returns whether or not the blocks with the provided hashes
|
||||||
// exist in the database.
|
// exist in the database.
|
||||||
|
@ -247,7 +247,7 @@ type Tx interface {
|
||||||
// - ErrTxClosed if the transaction has already been closed
|
// - ErrTxClosed if the transaction has already been closed
|
||||||
//
|
//
|
||||||
// Other errors are possible depending on the implementation.
|
// Other errors are possible depending on the implementation.
|
||||||
HasBlocks(hashes []wire.ShaHash) ([]bool, error)
|
HasBlocks(hashes []chainhash.Hash) ([]bool, error)
|
||||||
|
|
||||||
// FetchBlockHeader returns the raw serialized bytes for the block
|
// FetchBlockHeader returns the raw serialized bytes for the block
|
||||||
// header identified by the given hash. The raw bytes are in the format
|
// header identified by the given hash. The raw bytes are in the format
|
||||||
|
@ -270,7 +270,7 @@ type Tx interface {
|
||||||
// has ended results in undefined behavior. This constraint prevents
|
// has ended results in undefined behavior. This constraint prevents
|
||||||
// additional data copies and allows support for memory-mapped database
|
// additional data copies and allows support for memory-mapped database
|
||||||
// implementations.
|
// implementations.
|
||||||
FetchBlockHeader(hash *wire.ShaHash) ([]byte, error)
|
FetchBlockHeader(hash *chainhash.Hash) ([]byte, error)
|
||||||
|
|
||||||
// FetchBlockHeaders returns the raw serialized bytes for the block
|
// FetchBlockHeaders returns the raw serialized bytes for the block
|
||||||
// headers identified by the given hashes. The raw bytes are in the
|
// headers identified by the given hashes. The raw bytes are in the
|
||||||
|
@ -297,7 +297,7 @@ type Tx interface {
|
||||||
// has ended results in undefined behavior. This constraint prevents
|
// has ended results in undefined behavior. This constraint prevents
|
||||||
// additional data copies and allows support for memory-mapped database
|
// additional data copies and allows support for memory-mapped database
|
||||||
// implementations.
|
// implementations.
|
||||||
FetchBlockHeaders(hashes []wire.ShaHash) ([][]byte, error)
|
FetchBlockHeaders(hashes []chainhash.Hash) ([][]byte, error)
|
||||||
|
|
||||||
// FetchBlock returns the raw serialized bytes for the block identified
|
// FetchBlock returns the raw serialized bytes for the block identified
|
||||||
// by the given hash. The raw bytes are in the format returned by
|
// by the given hash. The raw bytes are in the format returned by
|
||||||
|
@ -314,7 +314,7 @@ type Tx interface {
|
||||||
// has ended results in undefined behavior. This constraint prevents
|
// has ended results in undefined behavior. This constraint prevents
|
||||||
// additional data copies and allows support for memory-mapped database
|
// additional data copies and allows support for memory-mapped database
|
||||||
// implementations.
|
// implementations.
|
||||||
FetchBlock(hash *wire.ShaHash) ([]byte, error)
|
FetchBlock(hash *chainhash.Hash) ([]byte, error)
|
||||||
|
|
||||||
// FetchBlocks returns the raw serialized bytes for the blocks
|
// FetchBlocks returns the raw serialized bytes for the blocks
|
||||||
// identified by the given hashes. The raw bytes are in the format
|
// identified by the given hashes. The raw bytes are in the format
|
||||||
|
@ -332,7 +332,7 @@ type Tx interface {
|
||||||
// has ended results in undefined behavior. This constraint prevents
|
// has ended results in undefined behavior. This constraint prevents
|
||||||
// additional data copies and allows support for memory-mapped database
|
// additional data copies and allows support for memory-mapped database
|
||||||
// implementations.
|
// implementations.
|
||||||
FetchBlocks(hashes []wire.ShaHash) ([][]byte, error)
|
FetchBlocks(hashes []chainhash.Hash) ([][]byte, error)
|
||||||
|
|
||||||
// FetchBlockRegion returns the raw serialized bytes for the given
|
// FetchBlockRegion returns the raw serialized bytes for the given
|
||||||
// block region.
|
// block region.
|
||||||
|
|
|
@ -913,7 +913,7 @@ The following is an overview of the JSON-RPC notifications used for Websocket co
|
||||||
|---|---|
|
|---|---|
|
||||||
|Method|txaccepted|
|
|Method|txaccepted|
|
||||||
|Request|[notifynewtransactions](#notifynewtransactions)|
|
|Request|[notifynewtransactions](#notifynewtransactions)|
|
||||||
|Parameters|1. TxSha (string) hex-encoded bytes of the transaction hash<br />2. Amount (numeric) sum of the value of all the transaction outpoints|
|
|Parameters|1. TxHash (string) hex-encoded bytes of the transaction hash<br />2. Amount (numeric) sum of the value of all the transaction outpoints|
|
||||||
|Description|Notifies when a new transaction has been accepted and the client has requested standard transaction details.|
|
|Description|Notifies when a new transaction has been accepted and the client has requested standard transaction details.|
|
||||||
|Example|Example txaccepted notification for mainnet transaction id "16c54c9d02fe570b9d41b518c0daefae81cc05c69bbe842058e84c6ed5826261" (newlines added for readability):<br />`{`<br /> `"jsonrpc": "1.0",`<br /> `"method": "txaccepted",`<br /> `"params":`<br /> `[`<br /> `"16c54c9d02fe570b9d41b518c0daefae81cc05c69bbe842058e84c6ed5826261",`<br /> `55838384`<br /> `],`<br /> `"id": null`<br />`}`|
|
|Example|Example txaccepted notification for mainnet transaction id "16c54c9d02fe570b9d41b518c0daefae81cc05c69bbe842058e84c6ed5826261" (newlines added for readability):<br />`{`<br /> `"jsonrpc": "1.0",`<br /> `"method": "txaccepted",`<br /> `"params":`<br /> `[`<br /> `"16c54c9d02fe570b9d41b518c0daefae81cc05c69bbe842058e84c6ed5826261",`<br /> `55838384`<br /> `],`<br /> `"id": null`<br />`}`|
|
||||||
[Return to Overview](#NotificationOverview)<br />
|
[Return to Overview](#NotificationOverview)<br />
|
||||||
|
@ -1052,6 +1052,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"github.com/btcsuite/btcrpcclient"
|
"github.com/btcsuite/btcrpcclient"
|
||||||
"github.com/btcsuite/btcutil"
|
"github.com/btcsuite/btcutil"
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
|
@ -1089,7 +1090,7 @@ func main() {
|
||||||
// command with the verbose flag set to true and the verboseTx flag
|
// command with the verbose flag set to true and the verboseTx flag
|
||||||
// set to false.
|
// set to false.
|
||||||
genesisHashStr := "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"
|
genesisHashStr := "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"
|
||||||
blockHash, err := wire.NewShaHashFromStr(genesisHashStr)
|
blockHash, err := chainhash.NewHashFromStr(genesisHashStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -1142,6 +1143,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"github.com/btcsuite/btcrpcclient"
|
"github.com/btcsuite/btcrpcclient"
|
||||||
"github.com/btcsuite/btcutil"
|
"github.com/btcsuite/btcutil"
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
|
@ -1153,10 +1155,10 @@ func main() {
|
||||||
// Setup handlers for blockconnected and blockdisconnected
|
// Setup handlers for blockconnected and blockdisconnected
|
||||||
// notifications.
|
// notifications.
|
||||||
ntfnHandlers := btcrpcclient.NotificationHandlers{
|
ntfnHandlers := btcrpcclient.NotificationHandlers{
|
||||||
OnBlockConnected: func(hash *wire.ShaHash, height int32) {
|
OnBlockConnected: func(hash *chainhash.Hash, height int32) {
|
||||||
log.Printf("Block connected: %v (%d)", hash, height)
|
log.Printf("Block connected: %v (%d)", hash, height)
|
||||||
},
|
},
|
||||||
OnBlockDisconnected: func(hash *wire.ShaHash, height int32) {
|
OnBlockDisconnected: func(hash *chainhash.Hash, height int32) {
|
||||||
log.Printf("Block disconnected: %v", hash, height)
|
log.Printf("Block disconnected: %v", hash, height)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
16
glide.lock
generated
16
glide.lock
generated
|
@ -1,14 +1,14 @@
|
||||||
hash: 9b8ff781a12daad991983e9a421a320e905eecc4e9ff0b0643e790f472bc78c8
|
hash: 9b8ff781a12daad991983e9a421a320e905eecc4e9ff0b0643e790f472bc78c8
|
||||||
updated: 2016-05-06T10:10:16.348595-05:00
|
updated: 2016-08-08T12:54:38.3626881-05:00
|
||||||
imports:
|
imports:
|
||||||
- name: github.com/btcsuite/btclog
|
- name: github.com/btcsuite/btclog
|
||||||
version: f96df2375f37300305f329b8e5258764b4f19a7f
|
version: f96df2375f37300305f329b8e5258764b4f19a7f
|
||||||
- name: github.com/btcsuite/btcutil
|
- name: github.com/btcsuite/btcutil
|
||||||
version: 2c26dd81a59fd671a2218d63ad138a6dd4d693bd
|
version: 22c91fa80a5e90e3feda26cf6d43adc249306188
|
||||||
subpackages:
|
subpackages:
|
||||||
- .
|
- .
|
||||||
- bloom
|
|
||||||
- base58
|
- base58
|
||||||
|
- bloom
|
||||||
- name: github.com/btcsuite/fastsha256
|
- name: github.com/btcsuite/fastsha256
|
||||||
version: 302ad4db268b46f9ebda3078f6f7397f96047735
|
version: 302ad4db268b46f9ebda3078f6f7397f96047735
|
||||||
- name: github.com/btcsuite/go-flags
|
- name: github.com/btcsuite/go-flags
|
||||||
|
@ -25,17 +25,17 @@ imports:
|
||||||
version: 7834afc9e8cd15233b6c3d97e12674a31ca24602
|
version: 7834afc9e8cd15233b6c3d97e12674a31ca24602
|
||||||
subpackages:
|
subpackages:
|
||||||
- leveldb
|
- leveldb
|
||||||
|
- leveldb/cache
|
||||||
- leveldb/comparer
|
- leveldb/comparer
|
||||||
- leveldb/errors
|
- leveldb/errors
|
||||||
- leveldb/filter
|
- leveldb/filter
|
||||||
- leveldb/iterator
|
- leveldb/iterator
|
||||||
- leveldb/opt
|
|
||||||
- leveldb/util
|
|
||||||
- leveldb/cache
|
|
||||||
- leveldb/journal
|
- leveldb/journal
|
||||||
- leveldb/memdb
|
- leveldb/memdb
|
||||||
|
- leveldb/opt
|
||||||
- leveldb/storage
|
- leveldb/storage
|
||||||
- leveldb/table
|
- leveldb/table
|
||||||
|
- leveldb/util
|
||||||
- name: github.com/btcsuite/seelog
|
- name: github.com/btcsuite/seelog
|
||||||
version: 313961b101eb55f65ae0f03ddd4e322731763b6c
|
version: 313961b101eb55f65ae0f03ddd4e322731763b6c
|
||||||
- name: github.com/btcsuite/snappy-go
|
- name: github.com/btcsuite/snappy-go
|
||||||
|
@ -47,11 +47,11 @@ imports:
|
||||||
subpackages:
|
subpackages:
|
||||||
- eventlog
|
- eventlog
|
||||||
- mgr
|
- mgr
|
||||||
- svc
|
|
||||||
- registry
|
- registry
|
||||||
|
- svc
|
||||||
- winapi
|
- winapi
|
||||||
- name: github.com/davecgh/go-spew
|
- name: github.com/davecgh/go-spew
|
||||||
version: 5215b55f46b2b919f50a1df0eaa5886afe4e3b3d
|
version: 5215b55f46b2b919f50a1df0eaa5886afe4e3b3d
|
||||||
subpackages:
|
subpackages:
|
||||||
- spew
|
- spew
|
||||||
devImports: []
|
testImports: []
|
||||||
|
|
85
mempool.go
85
mempool.go
|
@ -16,6 +16,7 @@ import (
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/blockchain"
|
"github.com/btcsuite/btcd/blockchain"
|
||||||
"github.com/btcsuite/btcd/blockchain/indexers"
|
"github.com/btcsuite/btcd/blockchain/indexers"
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/mining"
|
"github.com/btcsuite/btcd/mining"
|
||||||
"github.com/btcsuite/btcd/txscript"
|
"github.com/btcsuite/btcd/txscript"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
|
@ -103,9 +104,9 @@ type txMemPool struct {
|
||||||
|
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
cfg mempoolConfig
|
cfg mempoolConfig
|
||||||
pool map[wire.ShaHash]*mempoolTxDesc
|
pool map[chainhash.Hash]*mempoolTxDesc
|
||||||
orphans map[wire.ShaHash]*btcutil.Tx
|
orphans map[chainhash.Hash]*btcutil.Tx
|
||||||
orphansByPrev map[wire.ShaHash]map[wire.ShaHash]*btcutil.Tx
|
orphansByPrev map[chainhash.Hash]map[chainhash.Hash]*btcutil.Tx
|
||||||
outpoints map[wire.OutPoint]*btcutil.Tx
|
outpoints map[wire.OutPoint]*btcutil.Tx
|
||||||
pennyTotal float64 // exponentially decaying total for penny spends.
|
pennyTotal float64 // exponentially decaying total for penny spends.
|
||||||
lastPennyUnix int64 // unix time of last ``penny spend''
|
lastPennyUnix int64 // unix time of last ``penny spend''
|
||||||
|
@ -118,7 +119,7 @@ var _ mining.TxSource = (*txMemPool)(nil)
|
||||||
// RemoveOrphan. See the comment for RemoveOrphan for more details.
|
// RemoveOrphan. See the comment for RemoveOrphan for more details.
|
||||||
//
|
//
|
||||||
// This function MUST be called with the mempool lock held (for writes).
|
// This function MUST be called with the mempool lock held (for writes).
|
||||||
func (mp *txMemPool) removeOrphan(txHash *wire.ShaHash) {
|
func (mp *txMemPool) removeOrphan(txHash *chainhash.Hash) {
|
||||||
// Nothing to do if passed tx is not an orphan.
|
// Nothing to do if passed tx is not an orphan.
|
||||||
tx, exists := mp.orphans[*txHash]
|
tx, exists := mp.orphans[*txHash]
|
||||||
if !exists {
|
if !exists {
|
||||||
|
@ -129,7 +130,7 @@ func (mp *txMemPool) removeOrphan(txHash *wire.ShaHash) {
|
||||||
for _, txIn := range tx.MsgTx().TxIn {
|
for _, txIn := range tx.MsgTx().TxIn {
|
||||||
originTxHash := txIn.PreviousOutPoint.Hash
|
originTxHash := txIn.PreviousOutPoint.Hash
|
||||||
if orphans, exists := mp.orphansByPrev[originTxHash]; exists {
|
if orphans, exists := mp.orphansByPrev[originTxHash]; exists {
|
||||||
delete(orphans, *tx.Sha())
|
delete(orphans, *tx.Hash())
|
||||||
|
|
||||||
// Remove the map entry altogether if there are no
|
// Remove the map entry altogether if there are no
|
||||||
// longer any orphans which depend on it.
|
// longer any orphans which depend on it.
|
||||||
|
@ -147,7 +148,7 @@ func (mp *txMemPool) removeOrphan(txHash *wire.ShaHash) {
|
||||||
// previous orphan index.
|
// previous orphan index.
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (mp *txMemPool) RemoveOrphan(txHash *wire.ShaHash) {
|
func (mp *txMemPool) RemoveOrphan(txHash *chainhash.Hash) {
|
||||||
mp.Lock()
|
mp.Lock()
|
||||||
mp.removeOrphan(txHash)
|
mp.removeOrphan(txHash)
|
||||||
mp.Unlock()
|
mp.Unlock()
|
||||||
|
@ -162,7 +163,7 @@ func (mp *txMemPool) limitNumOrphans() error {
|
||||||
mp.cfg.Policy.MaxOrphanTxs > 0 {
|
mp.cfg.Policy.MaxOrphanTxs > 0 {
|
||||||
|
|
||||||
// Generate a cryptographically random hash.
|
// Generate a cryptographically random hash.
|
||||||
randHashBytes := make([]byte, wire.HashSize)
|
randHashBytes := make([]byte, chainhash.HashSize)
|
||||||
_, err := rand.Read(randHashBytes)
|
_, err := rand.Read(randHashBytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -174,12 +175,12 @@ func (mp *txMemPool) limitNumOrphans() error {
|
||||||
// to Go's range statement over maps) as a fallback if none of
|
// to Go's range statement over maps) as a fallback if none of
|
||||||
// the hashes in the orphan pool are larger than the random
|
// the hashes in the orphan pool are larger than the random
|
||||||
// hash.
|
// hash.
|
||||||
var foundHash *wire.ShaHash
|
var foundHash *chainhash.Hash
|
||||||
for txHash := range mp.orphans {
|
for txHash := range mp.orphans {
|
||||||
if foundHash == nil {
|
if foundHash == nil {
|
||||||
foundHash = &txHash
|
foundHash = &txHash
|
||||||
}
|
}
|
||||||
txHashNum := blockchain.ShaHashToBig(&txHash)
|
txHashNum := blockchain.HashToBig(&txHash)
|
||||||
if txHashNum.Cmp(randHashNum) > 0 {
|
if txHashNum.Cmp(randHashNum) > 0 {
|
||||||
foundHash = &txHash
|
foundHash = &txHash
|
||||||
break
|
break
|
||||||
|
@ -200,17 +201,17 @@ func (mp *txMemPool) addOrphan(tx *btcutil.Tx) {
|
||||||
// random orphan is evicted to make room if needed.
|
// random orphan is evicted to make room if needed.
|
||||||
mp.limitNumOrphans()
|
mp.limitNumOrphans()
|
||||||
|
|
||||||
mp.orphans[*tx.Sha()] = tx
|
mp.orphans[*tx.Hash()] = tx
|
||||||
for _, txIn := range tx.MsgTx().TxIn {
|
for _, txIn := range tx.MsgTx().TxIn {
|
||||||
originTxHash := txIn.PreviousOutPoint.Hash
|
originTxHash := txIn.PreviousOutPoint.Hash
|
||||||
if _, exists := mp.orphansByPrev[originTxHash]; !exists {
|
if _, exists := mp.orphansByPrev[originTxHash]; !exists {
|
||||||
mp.orphansByPrev[originTxHash] =
|
mp.orphansByPrev[originTxHash] =
|
||||||
make(map[wire.ShaHash]*btcutil.Tx)
|
make(map[chainhash.Hash]*btcutil.Tx)
|
||||||
}
|
}
|
||||||
mp.orphansByPrev[originTxHash][*tx.Sha()] = tx
|
mp.orphansByPrev[originTxHash][*tx.Hash()] = tx
|
||||||
}
|
}
|
||||||
|
|
||||||
txmpLog.Debugf("Stored orphan transaction %v (total: %d)", tx.Sha(),
|
txmpLog.Debugf("Stored orphan transaction %v (total: %d)", tx.Hash(),
|
||||||
len(mp.orphans))
|
len(mp.orphans))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,7 +247,7 @@ func (mp *txMemPool) maybeAddOrphan(tx *btcutil.Tx) error {
|
||||||
// exists in the main pool.
|
// exists in the main pool.
|
||||||
//
|
//
|
||||||
// This function MUST be called with the mempool lock held (for reads).
|
// This function MUST be called with the mempool lock held (for reads).
|
||||||
func (mp *txMemPool) isTransactionInPool(hash *wire.ShaHash) bool {
|
func (mp *txMemPool) isTransactionInPool(hash *chainhash.Hash) bool {
|
||||||
if _, exists := mp.pool[*hash]; exists {
|
if _, exists := mp.pool[*hash]; exists {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -258,7 +259,7 @@ func (mp *txMemPool) isTransactionInPool(hash *wire.ShaHash) bool {
|
||||||
// exists in the main pool.
|
// exists in the main pool.
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (mp *txMemPool) IsTransactionInPool(hash *wire.ShaHash) bool {
|
func (mp *txMemPool) IsTransactionInPool(hash *chainhash.Hash) bool {
|
||||||
// Protect concurrent access.
|
// Protect concurrent access.
|
||||||
mp.RLock()
|
mp.RLock()
|
||||||
defer mp.RUnlock()
|
defer mp.RUnlock()
|
||||||
|
@ -270,7 +271,7 @@ func (mp *txMemPool) IsTransactionInPool(hash *wire.ShaHash) bool {
|
||||||
// in the orphan pool.
|
// in the orphan pool.
|
||||||
//
|
//
|
||||||
// This function MUST be called with the mempool lock held (for reads).
|
// This function MUST be called with the mempool lock held (for reads).
|
||||||
func (mp *txMemPool) isOrphanInPool(hash *wire.ShaHash) bool {
|
func (mp *txMemPool) isOrphanInPool(hash *chainhash.Hash) bool {
|
||||||
if _, exists := mp.orphans[*hash]; exists {
|
if _, exists := mp.orphans[*hash]; exists {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -282,7 +283,7 @@ func (mp *txMemPool) isOrphanInPool(hash *wire.ShaHash) bool {
|
||||||
// in the orphan pool.
|
// in the orphan pool.
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (mp *txMemPool) IsOrphanInPool(hash *wire.ShaHash) bool {
|
func (mp *txMemPool) IsOrphanInPool(hash *chainhash.Hash) bool {
|
||||||
// Protect concurrent access.
|
// Protect concurrent access.
|
||||||
mp.RLock()
|
mp.RLock()
|
||||||
defer mp.RUnlock()
|
defer mp.RUnlock()
|
||||||
|
@ -294,7 +295,7 @@ func (mp *txMemPool) IsOrphanInPool(hash *wire.ShaHash) bool {
|
||||||
// in the main pool or in the orphan pool.
|
// in the main pool or in the orphan pool.
|
||||||
//
|
//
|
||||||
// This function MUST be called with the mempool lock held (for reads).
|
// This function MUST be called with the mempool lock held (for reads).
|
||||||
func (mp *txMemPool) haveTransaction(hash *wire.ShaHash) bool {
|
func (mp *txMemPool) haveTransaction(hash *chainhash.Hash) bool {
|
||||||
return mp.isTransactionInPool(hash) || mp.isOrphanInPool(hash)
|
return mp.isTransactionInPool(hash) || mp.isOrphanInPool(hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,7 +303,7 @@ func (mp *txMemPool) haveTransaction(hash *wire.ShaHash) bool {
|
||||||
// in the main pool or in the orphan pool.
|
// in the main pool or in the orphan pool.
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (mp *txMemPool) HaveTransaction(hash *wire.ShaHash) bool {
|
func (mp *txMemPool) HaveTransaction(hash *chainhash.Hash) bool {
|
||||||
// Protect concurrent access.
|
// Protect concurrent access.
|
||||||
mp.RLock()
|
mp.RLock()
|
||||||
defer mp.RUnlock()
|
defer mp.RUnlock()
|
||||||
|
@ -315,7 +316,7 @@ func (mp *txMemPool) HaveTransaction(hash *wire.ShaHash) bool {
|
||||||
//
|
//
|
||||||
// This function MUST be called with the mempool lock held (for writes).
|
// This function MUST be called with the mempool lock held (for writes).
|
||||||
func (mp *txMemPool) removeTransaction(tx *btcutil.Tx, removeRedeemers bool) {
|
func (mp *txMemPool) removeTransaction(tx *btcutil.Tx, removeRedeemers bool) {
|
||||||
txHash := tx.Sha()
|
txHash := tx.Hash()
|
||||||
if removeRedeemers {
|
if removeRedeemers {
|
||||||
// Remove any transactions which rely on this one.
|
// Remove any transactions which rely on this one.
|
||||||
for i := uint32(0); i < uint32(len(tx.MsgTx().TxOut)); i++ {
|
for i := uint32(0); i < uint32(len(tx.MsgTx().TxOut)); i++ {
|
||||||
|
@ -371,7 +372,7 @@ func (mp *txMemPool) RemoveDoubleSpends(tx *btcutil.Tx) {
|
||||||
|
|
||||||
for _, txIn := range tx.MsgTx().TxIn {
|
for _, txIn := range tx.MsgTx().TxIn {
|
||||||
if txRedeemer, ok := mp.outpoints[txIn.PreviousOutPoint]; ok {
|
if txRedeemer, ok := mp.outpoints[txIn.PreviousOutPoint]; ok {
|
||||||
if !txRedeemer.Sha().IsEqual(tx.Sha()) {
|
if !txRedeemer.Hash().IsEqual(tx.Hash()) {
|
||||||
mp.removeTransaction(txRedeemer, true)
|
mp.removeTransaction(txRedeemer, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -386,7 +387,7 @@ func (mp *txMemPool) RemoveDoubleSpends(tx *btcutil.Tx) {
|
||||||
func (mp *txMemPool) addTransaction(utxoView *blockchain.UtxoViewpoint, tx *btcutil.Tx, height int32, fee int64) {
|
func (mp *txMemPool) addTransaction(utxoView *blockchain.UtxoViewpoint, tx *btcutil.Tx, height int32, fee int64) {
|
||||||
// Add the transaction to the pool and mark the referenced outpoints
|
// Add the transaction to the pool and mark the referenced outpoints
|
||||||
// as spent by the pool.
|
// as spent by the pool.
|
||||||
mp.pool[*tx.Sha()] = &mempoolTxDesc{
|
mp.pool[*tx.Hash()] = &mempoolTxDesc{
|
||||||
TxDesc: mining.TxDesc{
|
TxDesc: mining.TxDesc{
|
||||||
Tx: tx,
|
Tx: tx,
|
||||||
Added: time.Now(),
|
Added: time.Now(),
|
||||||
|
@ -418,7 +419,7 @@ func (mp *txMemPool) checkPoolDoubleSpend(tx *btcutil.Tx) error {
|
||||||
if txR, exists := mp.outpoints[txIn.PreviousOutPoint]; exists {
|
if txR, exists := mp.outpoints[txIn.PreviousOutPoint]; exists {
|
||||||
str := fmt.Sprintf("output %v already spent by "+
|
str := fmt.Sprintf("output %v already spent by "+
|
||||||
"transaction %v in the memory pool",
|
"transaction %v in the memory pool",
|
||||||
txIn.PreviousOutPoint, txR.Sha())
|
txIn.PreviousOutPoint, txR.Hash())
|
||||||
return txRuleError(wire.RejectDuplicate, str)
|
return txRuleError(wire.RejectDuplicate, str)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -456,7 +457,7 @@ func (mp *txMemPool) fetchInputUtxos(tx *btcutil.Tx) (*blockchain.UtxoViewpoint,
|
||||||
// orphans.
|
// orphans.
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (mp *txMemPool) FetchTransaction(txHash *wire.ShaHash) (*btcutil.Tx, error) {
|
func (mp *txMemPool) FetchTransaction(txHash *chainhash.Hash) (*btcutil.Tx, error) {
|
||||||
// Protect concurrent access.
|
// Protect concurrent access.
|
||||||
mp.RLock()
|
mp.RLock()
|
||||||
defer mp.RUnlock()
|
defer mp.RUnlock()
|
||||||
|
@ -473,8 +474,8 @@ func (mp *txMemPool) FetchTransaction(txHash *wire.ShaHash) (*btcutil.Tx, error)
|
||||||
// more details.
|
// more details.
|
||||||
//
|
//
|
||||||
// This function MUST be called with the mempool lock held (for writes).
|
// This function MUST be called with the mempool lock held (for writes).
|
||||||
func (mp *txMemPool) maybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit bool) ([]*wire.ShaHash, error) {
|
func (mp *txMemPool) maybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit bool) ([]*chainhash.Hash, error) {
|
||||||
txHash := tx.Sha()
|
txHash := tx.Hash()
|
||||||
|
|
||||||
// Don't accept the transaction if it already exists in the pool. This
|
// Don't accept the transaction if it already exists in the pool. This
|
||||||
// applies to orphan transactions as well. This check is intended to
|
// applies to orphan transactions as well. This check is intended to
|
||||||
|
@ -575,7 +576,7 @@ func (mp *txMemPool) maybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit boo
|
||||||
// don't exist. Adding orphans to the orphan pool is not handled by
|
// don't exist. Adding orphans to the orphan pool is not handled by
|
||||||
// this function, and the caller should use maybeAddOrphan if this
|
// this function, and the caller should use maybeAddOrphan if this
|
||||||
// behavior is desired.
|
// behavior is desired.
|
||||||
var missingParents []*wire.ShaHash
|
var missingParents []*chainhash.Hash
|
||||||
for originHash, entry := range utxoView.Entries() {
|
for originHash, entry := range utxoView.Entries() {
|
||||||
if entry == nil || entry.IsFullySpent() {
|
if entry == nil || entry.IsFullySpent() {
|
||||||
// Must make a copy of the hash here since the iterator
|
// Must make a copy of the hash here since the iterator
|
||||||
|
@ -735,7 +736,7 @@ func (mp *txMemPool) maybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit boo
|
||||||
// be added to the orphan pool.
|
// be added to the orphan pool.
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (mp *txMemPool) MaybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit bool) ([]*wire.ShaHash, error) {
|
func (mp *txMemPool) MaybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit bool) ([]*chainhash.Hash, error) {
|
||||||
// Protect concurrent access.
|
// Protect concurrent access.
|
||||||
mp.Lock()
|
mp.Lock()
|
||||||
defer mp.Unlock()
|
defer mp.Unlock()
|
||||||
|
@ -747,7 +748,7 @@ func (mp *txMemPool) MaybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit boo
|
||||||
// ProcessOrphans. See the comment for ProcessOrphans for more details.
|
// ProcessOrphans. See the comment for ProcessOrphans for more details.
|
||||||
//
|
//
|
||||||
// This function MUST be called with the mempool lock held (for writes).
|
// This function MUST be called with the mempool lock held (for writes).
|
||||||
func (mp *txMemPool) processOrphans(hash *wire.ShaHash) []*btcutil.Tx {
|
func (mp *txMemPool) processOrphans(hash *chainhash.Hash) []*btcutil.Tx {
|
||||||
var acceptedTxns []*btcutil.Tx
|
var acceptedTxns []*btcutil.Tx
|
||||||
|
|
||||||
// Start with processing at least the passed hash.
|
// Start with processing at least the passed hash.
|
||||||
|
@ -756,7 +757,7 @@ func (mp *txMemPool) processOrphans(hash *wire.ShaHash) []*btcutil.Tx {
|
||||||
for processHashes.Len() > 0 {
|
for processHashes.Len() > 0 {
|
||||||
// Pop the first hash to process.
|
// Pop the first hash to process.
|
||||||
firstElement := processHashes.Remove(processHashes.Front())
|
firstElement := processHashes.Remove(processHashes.Front())
|
||||||
processHash := firstElement.(*wire.ShaHash)
|
processHash := firstElement.(*chainhash.Hash)
|
||||||
|
|
||||||
// Look up all orphans that are referenced by the transaction we
|
// Look up all orphans that are referenced by the transaction we
|
||||||
// just accepted. This will typically only be one, but it could
|
// just accepted. This will typically only be one, but it could
|
||||||
|
@ -782,7 +783,7 @@ func (mp *txMemPool) processOrphans(hash *wire.ShaHash) []*btcutil.Tx {
|
||||||
// potentially moving orphans to the memory pool, but
|
// potentially moving orphans to the memory pool, but
|
||||||
// leaving them in the orphan pool if not all parent
|
// leaving them in the orphan pool if not all parent
|
||||||
// transactions are known yet.
|
// transactions are known yet.
|
||||||
orphanHash := tx.Sha()
|
orphanHash := tx.Hash()
|
||||||
mp.removeOrphan(orphanHash)
|
mp.removeOrphan(orphanHash)
|
||||||
|
|
||||||
// Potentially accept the transaction into the
|
// Potentially accept the transaction into the
|
||||||
|
@ -794,7 +795,7 @@ func (mp *txMemPool) processOrphans(hash *wire.ShaHash) []*btcutil.Tx {
|
||||||
// failed transaction.
|
// failed transaction.
|
||||||
txmpLog.Debugf("Unable to move "+
|
txmpLog.Debugf("Unable to move "+
|
||||||
"orphan transaction %v to mempool: %v",
|
"orphan transaction %v to mempool: %v",
|
||||||
tx.Sha(), err)
|
tx.Hash(), err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -839,7 +840,7 @@ func (mp *txMemPool) processOrphans(hash *wire.ShaHash) []*btcutil.Tx {
|
||||||
// no transactions were moved from the orphan pool to the mempool.
|
// no transactions were moved from the orphan pool to the mempool.
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (mp *txMemPool) ProcessOrphans(hash *wire.ShaHash) []*btcutil.Tx {
|
func (mp *txMemPool) ProcessOrphans(hash *chainhash.Hash) []*btcutil.Tx {
|
||||||
mp.Lock()
|
mp.Lock()
|
||||||
acceptedTxns := mp.processOrphans(hash)
|
acceptedTxns := mp.processOrphans(hash)
|
||||||
mp.Unlock()
|
mp.Unlock()
|
||||||
|
@ -863,7 +864,7 @@ func (mp *txMemPool) ProcessTransaction(tx *btcutil.Tx, allowOrphan, rateLimit b
|
||||||
mp.Lock()
|
mp.Lock()
|
||||||
defer mp.Unlock()
|
defer mp.Unlock()
|
||||||
|
|
||||||
txmpLog.Tracef("Processing transaction %v", tx.Sha())
|
txmpLog.Tracef("Processing transaction %v", tx.Hash())
|
||||||
|
|
||||||
// Potentially accept the transaction to the memory pool.
|
// Potentially accept the transaction to the memory pool.
|
||||||
missingParents, err := mp.maybeAcceptTransaction(tx, true, rateLimit)
|
missingParents, err := mp.maybeAcceptTransaction(tx, true, rateLimit)
|
||||||
|
@ -876,7 +877,7 @@ func (mp *txMemPool) ProcessTransaction(tx *btcutil.Tx, allowOrphan, rateLimit b
|
||||||
// transaction (they may no longer be orphans if all inputs
|
// transaction (they may no longer be orphans if all inputs
|
||||||
// are now available) and repeat for those accepted
|
// are now available) and repeat for those accepted
|
||||||
// transactions until there are no more.
|
// transactions until there are no more.
|
||||||
newTxs := mp.processOrphans(tx.Sha())
|
newTxs := mp.processOrphans(tx.Hash())
|
||||||
acceptedTxs := make([]*btcutil.Tx, len(newTxs)+1)
|
acceptedTxs := make([]*btcutil.Tx, len(newTxs)+1)
|
||||||
|
|
||||||
// Add the parent transaction first so remote nodes
|
// Add the parent transaction first so remote nodes
|
||||||
|
@ -901,7 +902,7 @@ func (mp *txMemPool) ProcessTransaction(tx *btcutil.Tx, allowOrphan, rateLimit b
|
||||||
// which is not really always the case.
|
// which is not really always the case.
|
||||||
str := fmt.Sprintf("orphan transaction %v references "+
|
str := fmt.Sprintf("orphan transaction %v references "+
|
||||||
"outputs of unknown or fully-spent "+
|
"outputs of unknown or fully-spent "+
|
||||||
"transaction %v", tx.Sha(), missingParents[0])
|
"transaction %v", tx.Hash(), missingParents[0])
|
||||||
return nil, txRuleError(wire.RejectDuplicate, str)
|
return nil, txRuleError(wire.RejectDuplicate, str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -925,15 +926,15 @@ func (mp *txMemPool) Count() int {
|
||||||
return len(mp.pool)
|
return len(mp.pool)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TxShas returns a slice of hashes for all of the transactions in the memory
|
// TxHashes returns a slice of hashes for all of the transactions in the memory
|
||||||
// pool.
|
// pool.
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (mp *txMemPool) TxShas() []*wire.ShaHash {
|
func (mp *txMemPool) TxHashes() []*chainhash.Hash {
|
||||||
mp.RLock()
|
mp.RLock()
|
||||||
defer mp.RUnlock()
|
defer mp.RUnlock()
|
||||||
|
|
||||||
hashes := make([]*wire.ShaHash, len(mp.pool))
|
hashes := make([]*chainhash.Hash, len(mp.pool))
|
||||||
i := 0
|
i := 0
|
||||||
for hash := range mp.pool {
|
for hash := range mp.pool {
|
||||||
hashCopy := hash
|
hashCopy := hash
|
||||||
|
@ -994,9 +995,9 @@ func (mp *txMemPool) LastUpdated() time.Time {
|
||||||
func newTxMemPool(cfg *mempoolConfig) *txMemPool {
|
func newTxMemPool(cfg *mempoolConfig) *txMemPool {
|
||||||
memPool := &txMemPool{
|
memPool := &txMemPool{
|
||||||
cfg: *cfg,
|
cfg: *cfg,
|
||||||
pool: make(map[wire.ShaHash]*mempoolTxDesc),
|
pool: make(map[chainhash.Hash]*mempoolTxDesc),
|
||||||
orphans: make(map[wire.ShaHash]*btcutil.Tx),
|
orphans: make(map[chainhash.Hash]*btcutil.Tx),
|
||||||
orphansByPrev: make(map[wire.ShaHash]map[wire.ShaHash]*btcutil.Tx),
|
orphansByPrev: make(map[chainhash.Hash]map[chainhash.Hash]*btcutil.Tx),
|
||||||
outpoints: make(map[wire.OutPoint]*btcutil.Tx),
|
outpoints: make(map[wire.OutPoint]*btcutil.Tx),
|
||||||
}
|
}
|
||||||
return memPool
|
return memPool
|
||||||
|
|
41
mining.go
41
mining.go
|
@ -11,6 +11,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/blockchain"
|
"github.com/btcsuite/btcd/blockchain"
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/mining"
|
"github.com/btcsuite/btcd/mining"
|
||||||
"github.com/btcsuite/btcd/txscript"
|
"github.com/btcsuite/btcd/txscript"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
|
@ -53,7 +54,7 @@ type txPrioItem struct {
|
||||||
// on. It will only be set when the transaction references other
|
// on. It will only be set when the transaction references other
|
||||||
// transactions in the source pool and hence must come after them in
|
// transactions in the source pool and hence must come after them in
|
||||||
// a block.
|
// a block.
|
||||||
dependsOn map[wire.ShaHash]struct{}
|
dependsOn map[chainhash.Hash]struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// txPriorityQueueLessFunc describes a function that can be used as a compare
|
// txPriorityQueueLessFunc describes a function that can be used as a compare
|
||||||
|
@ -236,7 +237,7 @@ func createCoinbaseTx(coinbaseScript []byte, nextBlockHeight int32, addr btcutil
|
||||||
tx.AddTxIn(&wire.TxIn{
|
tx.AddTxIn(&wire.TxIn{
|
||||||
// Coinbase transactions have no inputs, so previous outpoint is
|
// Coinbase transactions have no inputs, so previous outpoint is
|
||||||
// zero hash and max index.
|
// zero hash and max index.
|
||||||
PreviousOutPoint: *wire.NewOutPoint(&wire.ShaHash{},
|
PreviousOutPoint: *wire.NewOutPoint(&chainhash.Hash{},
|
||||||
wire.MaxPrevOutIndex),
|
wire.MaxPrevOutIndex),
|
||||||
SignatureScript: coinbaseScript,
|
SignatureScript: coinbaseScript,
|
||||||
Sequence: wire.MaxTxInSequenceNum,
|
Sequence: wire.MaxTxInSequenceNum,
|
||||||
|
@ -276,7 +277,7 @@ func logSkippedDeps(tx *btcutil.Tx, deps *list.List) {
|
||||||
for e := deps.Front(); e != nil; e = e.Next() {
|
for e := deps.Front(); e != nil; e = e.Next() {
|
||||||
item := e.Value.(*txPrioItem)
|
item := e.Value.(*txPrioItem)
|
||||||
minrLog.Tracef("Skipping tx %s since it depends on %s\n",
|
minrLog.Tracef("Skipping tx %s since it depends on %s\n",
|
||||||
item.tx.Sha(), tx.Sha())
|
item.tx.Hash(), tx.Hash())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -436,7 +437,7 @@ func NewBlockTemplate(policy *mining.Policy, server *server, payToAddress btcuti
|
||||||
// dependsOn map kept with each dependent transaction helps quickly
|
// dependsOn map kept with each dependent transaction helps quickly
|
||||||
// determine which dependent transactions are now eligible for inclusion
|
// determine which dependent transactions are now eligible for inclusion
|
||||||
// in the block once each transaction has been included.
|
// in the block once each transaction has been included.
|
||||||
dependers := make(map[wire.ShaHash]*list.List)
|
dependers := make(map[chainhash.Hash]*list.List)
|
||||||
|
|
||||||
// Create slices to hold the fees and number of signature operations
|
// Create slices to hold the fees and number of signature operations
|
||||||
// for each of the selected transactions and add an entry for the
|
// for each of the selected transactions and add an entry for the
|
||||||
|
@ -458,13 +459,13 @@ mempoolLoop:
|
||||||
// non-finalized transactions.
|
// non-finalized transactions.
|
||||||
tx := txDesc.Tx
|
tx := txDesc.Tx
|
||||||
if blockchain.IsCoinBase(tx) {
|
if blockchain.IsCoinBase(tx) {
|
||||||
minrLog.Tracef("Skipping coinbase tx %s", tx.Sha())
|
minrLog.Tracef("Skipping coinbase tx %s", tx.Hash())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if !blockchain.IsFinalizedTransaction(tx, nextBlockHeight,
|
if !blockchain.IsFinalizedTransaction(tx, nextBlockHeight,
|
||||||
timeSource.AdjustedTime()) {
|
timeSource.AdjustedTime()) {
|
||||||
|
|
||||||
minrLog.Tracef("Skipping non-finalized tx %s", tx.Sha())
|
minrLog.Tracef("Skipping non-finalized tx %s", tx.Hash())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -476,7 +477,7 @@ mempoolLoop:
|
||||||
utxos, err := blockManager.chain.FetchUtxoView(tx)
|
utxos, err := blockManager.chain.FetchUtxoView(tx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
minrLog.Warnf("Unable to fetch utxo view for tx %s: "+
|
minrLog.Warnf("Unable to fetch utxo view for tx %s: "+
|
||||||
"%v", tx.Sha(), err)
|
"%v", tx.Hash(), err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -493,7 +494,7 @@ mempoolLoop:
|
||||||
minrLog.Tracef("Skipping tx %s because "+
|
minrLog.Tracef("Skipping tx %s because "+
|
||||||
"it references unspent output "+
|
"it references unspent output "+
|
||||||
"%s which is not available",
|
"%s which is not available",
|
||||||
tx.Sha(), txIn.PreviousOutPoint)
|
tx.Hash(), txIn.PreviousOutPoint)
|
||||||
continue mempoolLoop
|
continue mempoolLoop
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -508,7 +509,7 @@ mempoolLoop:
|
||||||
depList.PushBack(prioItem)
|
depList.PushBack(prioItem)
|
||||||
if prioItem.dependsOn == nil {
|
if prioItem.dependsOn == nil {
|
||||||
prioItem.dependsOn = make(
|
prioItem.dependsOn = make(
|
||||||
map[wire.ShaHash]struct{})
|
map[chainhash.Hash]struct{})
|
||||||
}
|
}
|
||||||
prioItem.dependsOn[*originHash] = struct{}{}
|
prioItem.dependsOn[*originHash] = struct{}{}
|
||||||
|
|
||||||
|
@ -562,15 +563,15 @@ mempoolLoop:
|
||||||
// any) and remove the entry for this transaction as it will
|
// any) and remove the entry for this transaction as it will
|
||||||
// either be included or skipped, but in either case the deps
|
// either be included or skipped, but in either case the deps
|
||||||
// are no longer needed.
|
// are no longer needed.
|
||||||
deps := dependers[*tx.Sha()]
|
deps := dependers[*tx.Hash()]
|
||||||
delete(dependers, *tx.Sha())
|
delete(dependers, *tx.Hash())
|
||||||
|
|
||||||
// Enforce maximum block size. Also check for overflow.
|
// Enforce maximum block size. Also check for overflow.
|
||||||
txSize := uint32(tx.MsgTx().SerializeSize())
|
txSize := uint32(tx.MsgTx().SerializeSize())
|
||||||
blockPlusTxSize := blockSize + txSize
|
blockPlusTxSize := blockSize + txSize
|
||||||
if blockPlusTxSize < blockSize || blockPlusTxSize >= policy.BlockMaxSize {
|
if blockPlusTxSize < blockSize || blockPlusTxSize >= policy.BlockMaxSize {
|
||||||
minrLog.Tracef("Skipping tx %s because it would exceed "+
|
minrLog.Tracef("Skipping tx %s because it would exceed "+
|
||||||
"the max block size", tx.Sha())
|
"the max block size", tx.Hash())
|
||||||
logSkippedDeps(tx, deps)
|
logSkippedDeps(tx, deps)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -581,7 +582,7 @@ mempoolLoop:
|
||||||
if blockSigOps+numSigOps < blockSigOps ||
|
if blockSigOps+numSigOps < blockSigOps ||
|
||||||
blockSigOps+numSigOps > blockchain.MaxSigOpsPerBlock {
|
blockSigOps+numSigOps > blockchain.MaxSigOpsPerBlock {
|
||||||
minrLog.Tracef("Skipping tx %s because it would "+
|
minrLog.Tracef("Skipping tx %s because it would "+
|
||||||
"exceed the maximum sigops per block", tx.Sha())
|
"exceed the maximum sigops per block", tx.Hash())
|
||||||
logSkippedDeps(tx, deps)
|
logSkippedDeps(tx, deps)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -589,7 +590,7 @@ mempoolLoop:
|
||||||
blockUtxos)
|
blockUtxos)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
minrLog.Tracef("Skipping tx %s due to error in "+
|
minrLog.Tracef("Skipping tx %s due to error in "+
|
||||||
"CountP2SHSigOps: %v", tx.Sha(), err)
|
"CountP2SHSigOps: %v", tx.Hash(), err)
|
||||||
logSkippedDeps(tx, deps)
|
logSkippedDeps(tx, deps)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -598,7 +599,7 @@ mempoolLoop:
|
||||||
blockSigOps+numSigOps > blockchain.MaxSigOpsPerBlock {
|
blockSigOps+numSigOps > blockchain.MaxSigOpsPerBlock {
|
||||||
minrLog.Tracef("Skipping tx %s because it would "+
|
minrLog.Tracef("Skipping tx %s because it would "+
|
||||||
"exceed the maximum sigops per block (p2sh)",
|
"exceed the maximum sigops per block (p2sh)",
|
||||||
tx.Sha())
|
tx.Hash())
|
||||||
logSkippedDeps(tx, deps)
|
logSkippedDeps(tx, deps)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -611,7 +612,7 @@ mempoolLoop:
|
||||||
|
|
||||||
minrLog.Tracef("Skipping tx %s with feePerKB %d "+
|
minrLog.Tracef("Skipping tx %s with feePerKB %d "+
|
||||||
"< TxMinFreeFee %d and block size %d >= "+
|
"< TxMinFreeFee %d and block size %d >= "+
|
||||||
"minBlockSize %d", tx.Sha(), prioItem.feePerKB,
|
"minBlockSize %d", tx.Hash(), prioItem.feePerKB,
|
||||||
policy.TxMinFreeFee, blockPlusTxSize,
|
policy.TxMinFreeFee, blockPlusTxSize,
|
||||||
policy.BlockMinSize)
|
policy.BlockMinSize)
|
||||||
logSkippedDeps(tx, deps)
|
logSkippedDeps(tx, deps)
|
||||||
|
@ -653,7 +654,7 @@ mempoolLoop:
|
||||||
blockUtxos)
|
blockUtxos)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
minrLog.Tracef("Skipping tx %s due to error in "+
|
minrLog.Tracef("Skipping tx %s due to error in "+
|
||||||
"CheckTransactionInputs: %v", tx.Sha(), err)
|
"CheckTransactionInputs: %v", tx.Hash(), err)
|
||||||
logSkippedDeps(tx, deps)
|
logSkippedDeps(tx, deps)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -661,7 +662,7 @@ mempoolLoop:
|
||||||
txscript.StandardVerifyFlags, server.sigCache)
|
txscript.StandardVerifyFlags, server.sigCache)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
minrLog.Tracef("Skipping tx %s due to error in "+
|
minrLog.Tracef("Skipping tx %s due to error in "+
|
||||||
"ValidateTransactionScripts: %v", tx.Sha(), err)
|
"ValidateTransactionScripts: %v", tx.Hash(), err)
|
||||||
logSkippedDeps(tx, deps)
|
logSkippedDeps(tx, deps)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -683,7 +684,7 @@ mempoolLoop:
|
||||||
txSigOpCounts = append(txSigOpCounts, numSigOps)
|
txSigOpCounts = append(txSigOpCounts, numSigOps)
|
||||||
|
|
||||||
minrLog.Tracef("Adding tx %s (priority %.2f, feePerKB %d)",
|
minrLog.Tracef("Adding tx %s (priority %.2f, feePerKB %d)",
|
||||||
prioItem.tx.Sha(), prioItem.priority, prioItem.feePerKB)
|
prioItem.tx.Hash(), prioItem.priority, prioItem.feePerKB)
|
||||||
|
|
||||||
// Add transactions which depend on this one (and also do not
|
// Add transactions which depend on this one (and also do not
|
||||||
// have any other unsatisified dependencies) to the priority
|
// have any other unsatisified dependencies) to the priority
|
||||||
|
@ -694,7 +695,7 @@ mempoolLoop:
|
||||||
// there are no more dependencies after this
|
// there are no more dependencies after this
|
||||||
// one.
|
// one.
|
||||||
item := e.Value.(*txPrioItem)
|
item := e.Value.(*txPrioItem)
|
||||||
delete(item.dependsOn, *tx.Sha())
|
delete(item.dependsOn, *tx.Hash())
|
||||||
if len(item.dependsOn) == 0 {
|
if len(item.dependsOn) == 0 {
|
||||||
heap.Push(priorityQueue, item)
|
heap.Push(priorityQueue, item)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015 The btcsuite developers
|
// Copyright (c) 2014-2016 The btcsuite developers
|
||||||
// Use of this source code is governed by an ISC
|
// Use of this source code is governed by an ISC
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ package mining
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcutil"
|
"github.com/btcsuite/btcutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -44,5 +44,5 @@ type TxSource interface {
|
||||||
|
|
||||||
// HaveTransaction returns whether or not the passed transaction hash
|
// HaveTransaction returns whether or not the passed transaction hash
|
||||||
// exists in the source pool.
|
// exists in the source pool.
|
||||||
HaveTransaction(hash *wire.ShaHash) bool
|
HaveTransaction(hash *chainhash.Hash) bool
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2015 The btcsuite developers
|
// Copyright (c) 2015-2016 The btcsuite developers
|
||||||
// Use of this source code is governed by an ISC
|
// Use of this source code is governed by an ISC
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/txscript"
|
"github.com/btcsuite/btcd/txscript"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
"github.com/btcsuite/btclog"
|
"github.com/btcsuite/btclog"
|
||||||
|
@ -131,7 +132,7 @@ func invSummary(invList []*wire.InvVect) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// locatorSummary returns a block locator as a human-readable string.
|
// locatorSummary returns a block locator as a human-readable string.
|
||||||
func locatorSummary(locator []*wire.ShaHash, stopHash *wire.ShaHash) string {
|
func locatorSummary(locator []*chainhash.Hash, stopHash *chainhash.Hash) string {
|
||||||
if len(locator) > 0 {
|
if len(locator) > 0 {
|
||||||
return fmt.Sprintf("locator %s, stop %s", locator[0], stopHash)
|
return fmt.Sprintf("locator %s, stop %s", locator[0], stopHash)
|
||||||
}
|
}
|
||||||
|
@ -195,12 +196,12 @@ func messageSummary(msg wire.Message) string {
|
||||||
|
|
||||||
case *wire.MsgTx:
|
case *wire.MsgTx:
|
||||||
return fmt.Sprintf("hash %s, %d inputs, %d outputs, lock %s",
|
return fmt.Sprintf("hash %s, %d inputs, %d outputs, lock %s",
|
||||||
msg.TxSha(), len(msg.TxIn), len(msg.TxOut),
|
msg.TxHash(), len(msg.TxIn), len(msg.TxOut),
|
||||||
formatLockTime(msg.LockTime))
|
formatLockTime(msg.LockTime))
|
||||||
|
|
||||||
case *wire.MsgBlock:
|
case *wire.MsgBlock:
|
||||||
header := &msg.Header
|
header := &msg.Header
|
||||||
return fmt.Sprintf("hash %s, ver %d, %d tx, %s", msg.BlockSha(),
|
return fmt.Sprintf("hash %s, ver %d, %d tx, %s", msg.BlockHash(),
|
||||||
header.Version, len(msg.Transactions), header.Timestamp)
|
header.Version, len(msg.Transactions), header.Timestamp)
|
||||||
|
|
||||||
case *wire.MsgInv:
|
case *wire.MsgInv:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2013-2015 The btcsuite developers
|
// Copyright (c) 2013-2016 The btcsuite developers
|
||||||
// Use of this source code is governed by an ISC
|
// Use of this source code is governed by an ISC
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -21,7 +22,7 @@ func TestMruInventoryMap(t *testing.T) {
|
||||||
numInvVects := 10
|
numInvVects := 10
|
||||||
invVects := make([]*wire.InvVect, 0, numInvVects)
|
invVects := make([]*wire.InvVect, 0, numInvVects)
|
||||||
for i := 0; i < numInvVects; i++ {
|
for i := 0; i < numInvVects; i++ {
|
||||||
hash := &wire.ShaHash{byte(i)}
|
hash := &chainhash.Hash{byte(i)}
|
||||||
iv := wire.NewInvVect(wire.InvTypeBlock, hash)
|
iv := wire.NewInvVect(wire.InvTypeBlock, hash)
|
||||||
invVects = append(invVects, iv)
|
invVects = append(invVects, iv)
|
||||||
}
|
}
|
||||||
|
@ -81,7 +82,7 @@ testLoop:
|
||||||
mruInvMap.Add(invVects[origLruIndex])
|
mruInvMap.Add(invVects[origLruIndex])
|
||||||
|
|
||||||
iv := wire.NewInvVect(wire.InvTypeBlock,
|
iv := wire.NewInvVect(wire.InvTypeBlock,
|
||||||
&wire.ShaHash{0x00, 0x01})
|
&chainhash.Hash{0x00, 0x01})
|
||||||
mruInvMap.Add(iv)
|
mruInvMap.Add(iv)
|
||||||
|
|
||||||
// Ensure the original lru entry still exists since it
|
// Ensure the original lru entry still exists since it
|
||||||
|
@ -121,8 +122,8 @@ testLoop:
|
||||||
func TestMruInventoryMapStringer(t *testing.T) {
|
func TestMruInventoryMapStringer(t *testing.T) {
|
||||||
// Create a couple of fake inventory vectors to use in testing the mru
|
// Create a couple of fake inventory vectors to use in testing the mru
|
||||||
// inventory stringer code.
|
// inventory stringer code.
|
||||||
hash1 := &wire.ShaHash{0x01}
|
hash1 := &chainhash.Hash{0x01}
|
||||||
hash2 := &wire.ShaHash{0x02}
|
hash2 := &chainhash.Hash{0x02}
|
||||||
iv1 := wire.NewInvVect(wire.InvTypeBlock, hash1)
|
iv1 := wire.NewInvVect(wire.InvTypeBlock, hash1)
|
||||||
iv2 := wire.NewInvVect(wire.InvTypeBlock, hash2)
|
iv2 := wire.NewInvVect(wire.InvTypeBlock, hash2)
|
||||||
|
|
||||||
|
@ -152,9 +153,9 @@ func BenchmarkMruInventoryList(b *testing.B) {
|
||||||
numInvVects := 100000
|
numInvVects := 100000
|
||||||
invVects := make([]*wire.InvVect, 0, numInvVects)
|
invVects := make([]*wire.InvVect, 0, numInvVects)
|
||||||
for i := 0; i < numInvVects; i++ {
|
for i := 0; i < numInvVects; i++ {
|
||||||
hashBytes := make([]byte, wire.HashSize)
|
hashBytes := make([]byte, chainhash.HashSize)
|
||||||
rand.Read(hashBytes)
|
rand.Read(hashBytes)
|
||||||
hash, _ := wire.NewShaHash(hashBytes)
|
hash, _ := chainhash.NewHash(hashBytes)
|
||||||
iv := wire.NewInvVect(wire.InvTypeBlock, hash)
|
iv := wire.NewInvVect(wire.InvTypeBlock, hash)
|
||||||
invVects = append(invVects, iv)
|
invVects = append(invVects, iv)
|
||||||
}
|
}
|
||||||
|
|
39
peer/peer.go
39
peer/peer.go
|
@ -19,6 +19,7 @@ import (
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/blockchain"
|
"github.com/btcsuite/btcd/blockchain"
|
||||||
"github.com/btcsuite/btcd/chaincfg"
|
"github.com/btcsuite/btcd/chaincfg"
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
"github.com/btcsuite/go-socks/socks"
|
"github.com/btcsuite/go-socks/socks"
|
||||||
"github.com/davecgh/go-spew/spew"
|
"github.com/davecgh/go-spew/spew"
|
||||||
|
@ -72,7 +73,7 @@ var (
|
||||||
|
|
||||||
// zeroHash is the zero value hash (all zeros). It is defined as a
|
// zeroHash is the zero value hash (all zeros). It is defined as a
|
||||||
// convenience.
|
// convenience.
|
||||||
zeroHash wire.ShaHash
|
zeroHash chainhash.Hash
|
||||||
|
|
||||||
// sentNonces houses the unique nonces that are generated when pushing
|
// sentNonces houses the unique nonces that are generated when pushing
|
||||||
// version messages that are used to detect self connections.
|
// version messages that are used to detect self connections.
|
||||||
|
@ -202,7 +203,7 @@ type Config struct {
|
||||||
// peer will report a block height of 0, however it is good practice for
|
// peer will report a block height of 0, however it is good practice for
|
||||||
// peers to specify this so their currently best known is accurately
|
// peers to specify this so their currently best known is accurately
|
||||||
// reported.
|
// reported.
|
||||||
NewestBlock ShaFunc
|
NewestBlock HashFunc
|
||||||
|
|
||||||
// BestLocalAddress returns the best local address for a given address.
|
// BestLocalAddress returns the best local address for a given address.
|
||||||
BestLocalAddress AddrFunc
|
BestLocalAddress AddrFunc
|
||||||
|
@ -352,9 +353,9 @@ type StatsSnap struct {
|
||||||
LastPingMicros int64
|
LastPingMicros int64
|
||||||
}
|
}
|
||||||
|
|
||||||
// ShaFunc is a function which returns a block sha, height and error
|
// HashFunc is a function which returns a block hash, height and error
|
||||||
// It is used as a callback to get newest block details.
|
// It is used as a callback to get newest block details.
|
||||||
type ShaFunc func() (sha *wire.ShaHash, height int32, err error)
|
type HashFunc func() (hash *chainhash.Hash, height int32, err error)
|
||||||
|
|
||||||
// AddrFunc is a func which takes an address and returns a related address.
|
// AddrFunc is a func which takes an address and returns a related address.
|
||||||
type AddrFunc func(remoteAddr *wire.NetAddress) *wire.NetAddress
|
type AddrFunc func(remoteAddr *wire.NetAddress) *wire.NetAddress
|
||||||
|
@ -420,11 +421,11 @@ type Peer struct {
|
||||||
|
|
||||||
knownInventory *mruInventoryMap
|
knownInventory *mruInventoryMap
|
||||||
prevGetBlocksMtx sync.Mutex
|
prevGetBlocksMtx sync.Mutex
|
||||||
prevGetBlocksBegin *wire.ShaHash
|
prevGetBlocksBegin *chainhash.Hash
|
||||||
prevGetBlocksStop *wire.ShaHash
|
prevGetBlocksStop *chainhash.Hash
|
||||||
prevGetHdrsMtx sync.Mutex
|
prevGetHdrsMtx sync.Mutex
|
||||||
prevGetHdrsBegin *wire.ShaHash
|
prevGetHdrsBegin *chainhash.Hash
|
||||||
prevGetHdrsStop *wire.ShaHash
|
prevGetHdrsStop *chainhash.Hash
|
||||||
|
|
||||||
// These fields keep track of statistics for the peer and are protected
|
// These fields keep track of statistics for the peer and are protected
|
||||||
// by the statsMtx mutex.
|
// by the statsMtx mutex.
|
||||||
|
@ -433,7 +434,7 @@ type Peer struct {
|
||||||
timeConnected time.Time
|
timeConnected time.Time
|
||||||
startingHeight int32
|
startingHeight int32
|
||||||
lastBlock int32
|
lastBlock int32
|
||||||
lastAnnouncedBlock *wire.ShaHash
|
lastAnnouncedBlock *chainhash.Hash
|
||||||
lastPingNonce uint64 // Set to nonce if we have a pending ping.
|
lastPingNonce uint64 // Set to nonce if we have a pending ping.
|
||||||
lastPingTime time.Time // Time we sent last ping.
|
lastPingTime time.Time // Time we sent last ping.
|
||||||
lastPingMicros int64 // Time for last ping to return.
|
lastPingMicros int64 // Time for last ping to return.
|
||||||
|
@ -468,15 +469,15 @@ func (p *Peer) UpdateLastBlockHeight(newHeight int32) {
|
||||||
p.statsMtx.Unlock()
|
p.statsMtx.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateLastAnnouncedBlock updates meta-data about the last block sha this
|
// UpdateLastAnnouncedBlock updates meta-data about the last block hash this
|
||||||
// peer is known to have announced.
|
// peer is known to have announced.
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (p *Peer) UpdateLastAnnouncedBlock(blkSha *wire.ShaHash) {
|
func (p *Peer) UpdateLastAnnouncedBlock(blkHash *chainhash.Hash) {
|
||||||
log.Tracef("Updating last blk for peer %v, %v", p.addr, blkSha)
|
log.Tracef("Updating last blk for peer %v, %v", p.addr, blkHash)
|
||||||
|
|
||||||
p.statsMtx.Lock()
|
p.statsMtx.Lock()
|
||||||
p.lastAnnouncedBlock = blkSha
|
p.lastAnnouncedBlock = blkHash
|
||||||
p.statsMtx.Unlock()
|
p.statsMtx.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -584,7 +585,7 @@ func (p *Peer) UserAgent() string {
|
||||||
// LastAnnouncedBlock returns the last announced block of the remote peer.
|
// LastAnnouncedBlock returns the last announced block of the remote peer.
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (p *Peer) LastAnnouncedBlock() *wire.ShaHash {
|
func (p *Peer) LastAnnouncedBlock() *chainhash.Hash {
|
||||||
p.statsMtx.RLock()
|
p.statsMtx.RLock()
|
||||||
defer p.statsMtx.RUnlock()
|
defer p.statsMtx.RUnlock()
|
||||||
|
|
||||||
|
@ -852,10 +853,10 @@ func (p *Peer) PushAddrMsg(addresses []*wire.NetAddress) ([]*wire.NetAddress, er
|
||||||
// and stop hash. It will ignore back-to-back duplicate requests.
|
// and stop hash. It will ignore back-to-back duplicate requests.
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (p *Peer) PushGetBlocksMsg(locator blockchain.BlockLocator, stopHash *wire.ShaHash) error {
|
func (p *Peer) PushGetBlocksMsg(locator blockchain.BlockLocator, stopHash *chainhash.Hash) error {
|
||||||
// Extract the begin hash from the block locator, if one was specified,
|
// Extract the begin hash from the block locator, if one was specified,
|
||||||
// to use for filtering duplicate getblocks requests.
|
// to use for filtering duplicate getblocks requests.
|
||||||
var beginHash *wire.ShaHash
|
var beginHash *chainhash.Hash
|
||||||
if len(locator) > 0 {
|
if len(locator) > 0 {
|
||||||
beginHash = locator[0]
|
beginHash = locator[0]
|
||||||
}
|
}
|
||||||
|
@ -896,10 +897,10 @@ func (p *Peer) PushGetBlocksMsg(locator blockchain.BlockLocator, stopHash *wire.
|
||||||
// and stop hash. It will ignore back-to-back duplicate requests.
|
// and stop hash. It will ignore back-to-back duplicate requests.
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (p *Peer) PushGetHeadersMsg(locator blockchain.BlockLocator, stopHash *wire.ShaHash) error {
|
func (p *Peer) PushGetHeadersMsg(locator blockchain.BlockLocator, stopHash *chainhash.Hash) error {
|
||||||
// Extract the begin hash from the block locator, if one was specified,
|
// Extract the begin hash from the block locator, if one was specified,
|
||||||
// to use for filtering duplicate getheaders requests.
|
// to use for filtering duplicate getheaders requests.
|
||||||
var beginHash *wire.ShaHash
|
var beginHash *chainhash.Hash
|
||||||
if len(locator) > 0 {
|
if len(locator) > 0 {
|
||||||
beginHash = locator[0]
|
beginHash = locator[0]
|
||||||
}
|
}
|
||||||
|
@ -943,7 +944,7 @@ func (p *Peer) PushGetHeadersMsg(locator blockchain.BlockLocator, stopHash *wire
|
||||||
// function to block until the reject message has actually been sent.
|
// function to block until the reject message has actually been sent.
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (p *Peer) PushRejectMsg(command string, code wire.RejectCode, reason string, hash *wire.ShaHash, wait bool) {
|
func (p *Peer) PushRejectMsg(command string, code wire.RejectCode, reason string, hash *chainhash.Hash, wait bool) {
|
||||||
// Don't bother sending the reject message if the protocol version
|
// Don't bother sending the reject message if the protocol version
|
||||||
// is too low.
|
// is too low.
|
||||||
if p.VersionKnown() && p.ProtocolVersion() < wire.RejectVersion {
|
if p.VersionKnown() && p.ProtocolVersion() < wire.RejectVersion {
|
||||||
|
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/chaincfg"
|
"github.com/btcsuite/btcd/chaincfg"
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/peer"
|
"github.com/btcsuite/btcd/peer"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
"github.com/btcsuite/go-socks/socks"
|
"github.com/btcsuite/go-socks/socks"
|
||||||
|
@ -450,7 +451,7 @@ func TestPeerListeners(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"OnBlock",
|
"OnBlock",
|
||||||
wire.NewMsgBlock(wire.NewBlockHeader(&wire.ShaHash{}, &wire.ShaHash{}, 1, 1)),
|
wire.NewMsgBlock(wire.NewBlockHeader(&chainhash.Hash{}, &chainhash.Hash{}, 1, 1)),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"OnInv",
|
"OnInv",
|
||||||
|
@ -470,7 +471,7 @@ func TestPeerListeners(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"OnGetBlocks",
|
"OnGetBlocks",
|
||||||
wire.NewMsgGetBlocks(&wire.ShaHash{}),
|
wire.NewMsgGetBlocks(&chainhash.Hash{}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"OnGetHeaders",
|
"OnGetHeaders",
|
||||||
|
@ -490,7 +491,7 @@ func TestPeerListeners(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"OnMerkleBlock",
|
"OnMerkleBlock",
|
||||||
wire.NewMsgMerkleBlock(wire.NewBlockHeader(&wire.ShaHash{}, &wire.ShaHash{}, 1, 1)),
|
wire.NewMsgMerkleBlock(wire.NewBlockHeader(&chainhash.Hash{}, &chainhash.Hash{}, 1, 1)),
|
||||||
},
|
},
|
||||||
// only one version message is allowed
|
// only one version message is allowed
|
||||||
// only one verack message is allowed
|
// only one verack message is allowed
|
||||||
|
@ -522,7 +523,7 @@ func TestPeerListeners(t *testing.T) {
|
||||||
func TestOutboundPeer(t *testing.T) {
|
func TestOutboundPeer(t *testing.T) {
|
||||||
|
|
||||||
peerCfg := &peer.Config{
|
peerCfg := &peer.Config{
|
||||||
NewestBlock: func() (*wire.ShaHash, int32, error) {
|
NewestBlock: func() (*chainhash.Hash, int32, error) {
|
||||||
return nil, 0, errors.New("newest block not found")
|
return nil, 0, errors.New("newest block not found")
|
||||||
},
|
},
|
||||||
UserAgentName: "peer",
|
UserAgentName: "peer",
|
||||||
|
@ -562,7 +563,7 @@ func TestOutboundPeer(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test Queue Inv
|
// Test Queue Inv
|
||||||
fakeBlockHash := &wire.ShaHash{0: 0x00, 1: 0x01}
|
fakeBlockHash := &chainhash.Hash{0: 0x00, 1: 0x01}
|
||||||
fakeInv := wire.NewInvVect(wire.InvTypeBlock, fakeBlockHash)
|
fakeInv := wire.NewInvVect(wire.InvTypeBlock, fakeBlockHash)
|
||||||
|
|
||||||
// Should be noops as the peer could not connect.
|
// Should be noops as the peer could not connect.
|
||||||
|
@ -578,9 +579,9 @@ func TestOutboundPeer(t *testing.T) {
|
||||||
p.Disconnect()
|
p.Disconnect()
|
||||||
|
|
||||||
// Test NewestBlock
|
// Test NewestBlock
|
||||||
var newestBlock = func() (*wire.ShaHash, int32, error) {
|
var newestBlock = func() (*chainhash.Hash, int32, error) {
|
||||||
hashStr := "14a0810ac680a3eb3f82edc878cea25ec41d6b790744e5daeef"
|
hashStr := "14a0810ac680a3eb3f82edc878cea25ec41d6b790744e5daeef"
|
||||||
hash, err := wire.NewShaHashFromStr(hashStr)
|
hash, err := chainhash.NewHashFromStr(hashStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
@ -598,16 +599,16 @@ func TestOutboundPeer(t *testing.T) {
|
||||||
p1.Connect(c1)
|
p1.Connect(c1)
|
||||||
|
|
||||||
// Test update latest block
|
// Test update latest block
|
||||||
latestBlockSha, err := wire.NewShaHashFromStr("1a63f9cdff1752e6375c8c76e543a71d239e1a2e5c6db1aa679")
|
latestBlockHash, err := chainhash.NewHashFromStr("1a63f9cdff1752e6375c8c76e543a71d239e1a2e5c6db1aa679")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("NewShaHashFromStr: unexpected err %v\n", err)
|
t.Errorf("NewHashFromStr: unexpected err %v\n", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
p1.UpdateLastAnnouncedBlock(latestBlockSha)
|
p1.UpdateLastAnnouncedBlock(latestBlockHash)
|
||||||
p1.UpdateLastBlockHeight(234440)
|
p1.UpdateLastBlockHeight(234440)
|
||||||
if p1.LastAnnouncedBlock() != latestBlockSha {
|
if p1.LastAnnouncedBlock() != latestBlockHash {
|
||||||
t.Errorf("LastAnnouncedBlock: wrong block - got %v, want %v",
|
t.Errorf("LastAnnouncedBlock: wrong block - got %v, want %v",
|
||||||
p1.LastAnnouncedBlock(), latestBlockSha)
|
p1.LastAnnouncedBlock(), latestBlockHash)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -637,11 +638,11 @@ func TestOutboundPeer(t *testing.T) {
|
||||||
t.Errorf("PushAddrMsg: unexpected err %v\n", err)
|
t.Errorf("PushAddrMsg: unexpected err %v\n", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := p2.PushGetBlocksMsg(nil, &wire.ShaHash{}); err != nil {
|
if err := p2.PushGetBlocksMsg(nil, &chainhash.Hash{}); err != nil {
|
||||||
t.Errorf("PushGetBlocksMsg: unexpected err %v\n", err)
|
t.Errorf("PushGetBlocksMsg: unexpected err %v\n", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := p2.PushGetHeadersMsg(nil, &wire.ShaHash{}); err != nil {
|
if err := p2.PushGetHeadersMsg(nil, &chainhash.Hash{}); err != nil {
|
||||||
t.Errorf("PushGetHeadersMsg: unexpected err %v\n", err)
|
t.Errorf("PushGetHeadersMsg: unexpected err %v\n", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2013-2015 The btcsuite developers
|
// Copyright (c) 2013-2016 The btcsuite developers
|
||||||
// Use of this source code is governed by an ISC
|
// Use of this source code is governed by an ISC
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ import (
|
||||||
"github.com/btcsuite/btcd/blockchain"
|
"github.com/btcsuite/btcd/blockchain"
|
||||||
"github.com/btcsuite/btcd/btcec"
|
"github.com/btcsuite/btcd/btcec"
|
||||||
"github.com/btcsuite/btcd/chaincfg"
|
"github.com/btcsuite/btcd/chaincfg"
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/txscript"
|
"github.com/btcsuite/btcd/txscript"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
"github.com/btcsuite/btcutil"
|
"github.com/btcsuite/btcutil"
|
||||||
|
@ -279,7 +280,7 @@ func TestDust(t *testing.T) {
|
||||||
// TestCheckTransactionStandard tests the checkTransactionStandard API.
|
// TestCheckTransactionStandard tests the checkTransactionStandard API.
|
||||||
func TestCheckTransactionStandard(t *testing.T) {
|
func TestCheckTransactionStandard(t *testing.T) {
|
||||||
// Create some dummy, but otherwise standard, data for transactions.
|
// Create some dummy, but otherwise standard, data for transactions.
|
||||||
prevOutHash, err := wire.NewShaHashFromStr("01")
|
prevOutHash, err := chainhash.NewHashFromStr("01")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("NewShaHashFromStr: unexpected error: %v", err)
|
t.Fatalf("NewShaHashFromStr: unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
101
rpcserver.go
101
rpcserver.go
|
@ -31,6 +31,7 @@ import (
|
||||||
"github.com/btcsuite/btcd/btcec"
|
"github.com/btcsuite/btcd/btcec"
|
||||||
"github.com/btcsuite/btcd/btcjson"
|
"github.com/btcsuite/btcd/btcjson"
|
||||||
"github.com/btcsuite/btcd/chaincfg"
|
"github.com/btcsuite/btcd/chaincfg"
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/database"
|
"github.com/btcsuite/btcd/database"
|
||||||
"github.com/btcsuite/btcd/mining"
|
"github.com/btcsuite/btcd/mining"
|
||||||
"github.com/btcsuite/btcd/txscript"
|
"github.com/btcsuite/btcd/txscript"
|
||||||
|
@ -64,7 +65,7 @@ const (
|
||||||
// consists of a zero hash plus the internal sha256 padding. See
|
// consists of a zero hash plus the internal sha256 padding. See
|
||||||
// the getworkDataLen comment for details about the internal sha256
|
// the getworkDataLen comment for details about the internal sha256
|
||||||
// padding format.
|
// padding format.
|
||||||
hash1Len = (1 + ((wire.HashSize + 8) / fastsha256.BlockSize)) *
|
hash1Len = (1 + ((chainhash.HashSize + 8) / fastsha256.BlockSize)) *
|
||||||
fastsha256.BlockSize
|
fastsha256.BlockSize
|
||||||
|
|
||||||
// gbtNonceRange is two 32-bit big-endian hexadecimal integers which
|
// gbtNonceRange is two 32-bit big-endian hexadecimal integers which
|
||||||
|
@ -304,7 +305,7 @@ func rpcDecodeHexError(gotHex string) *btcjson.RPCError {
|
||||||
// rpcNoTxInfoError is a convenience function for returning a nicely formatted
|
// rpcNoTxInfoError is a convenience function for returning a nicely formatted
|
||||||
// RPC error which indiactes there is no information available for the provided
|
// RPC error which indiactes there is no information available for the provided
|
||||||
// transaction hash.
|
// transaction hash.
|
||||||
func rpcNoTxInfoError(txHash *wire.ShaHash) *btcjson.RPCError {
|
func rpcNoTxInfoError(txHash *chainhash.Hash) *btcjson.RPCError {
|
||||||
return btcjson.NewRPCError(btcjson.ErrRPCNoTxInfo,
|
return btcjson.NewRPCError(btcjson.ErrRPCNoTxInfo,
|
||||||
fmt.Sprintf("No information available about transaction %v",
|
fmt.Sprintf("No information available about transaction %v",
|
||||||
txHash))
|
txHash))
|
||||||
|
@ -323,17 +324,17 @@ type workState struct {
|
||||||
sync.Mutex
|
sync.Mutex
|
||||||
lastTxUpdate time.Time
|
lastTxUpdate time.Time
|
||||||
lastGenerated time.Time
|
lastGenerated time.Time
|
||||||
prevHash *wire.ShaHash
|
prevHash *chainhash.Hash
|
||||||
msgBlock *wire.MsgBlock
|
msgBlock *wire.MsgBlock
|
||||||
extraNonce uint64
|
extraNonce uint64
|
||||||
blockInfo map[wire.ShaHash]*workStateBlockInfo
|
blockInfo map[chainhash.Hash]*workStateBlockInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
// newWorkState returns a new instance of a workState with all internal fields
|
// newWorkState returns a new instance of a workState with all internal fields
|
||||||
// initialized and ready to use.
|
// initialized and ready to use.
|
||||||
func newWorkState() *workState {
|
func newWorkState() *workState {
|
||||||
return &workState{
|
return &workState{
|
||||||
blockInfo: make(map[wire.ShaHash]*workStateBlockInfo),
|
blockInfo: make(map[chainhash.Hash]*workStateBlockInfo),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,10 +344,10 @@ type gbtWorkState struct {
|
||||||
sync.Mutex
|
sync.Mutex
|
||||||
lastTxUpdate time.Time
|
lastTxUpdate time.Time
|
||||||
lastGenerated time.Time
|
lastGenerated time.Time
|
||||||
prevHash *wire.ShaHash
|
prevHash *chainhash.Hash
|
||||||
minTimestamp time.Time
|
minTimestamp time.Time
|
||||||
template *BlockTemplate
|
template *BlockTemplate
|
||||||
notifyMap map[wire.ShaHash]map[int64]chan struct{}
|
notifyMap map[chainhash.Hash]map[int64]chan struct{}
|
||||||
timeSource blockchain.MedianTimeSource
|
timeSource blockchain.MedianTimeSource
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -354,7 +355,7 @@ type gbtWorkState struct {
|
||||||
// fields initialized and ready to use.
|
// fields initialized and ready to use.
|
||||||
func newGbtWorkState(timeSource blockchain.MedianTimeSource) *gbtWorkState {
|
func newGbtWorkState(timeSource blockchain.MedianTimeSource) *gbtWorkState {
|
||||||
return &gbtWorkState{
|
return &gbtWorkState{
|
||||||
notifyMap: make(map[wire.ShaHash]map[int64]chan struct{}),
|
notifyMap: make(map[chainhash.Hash]map[int64]chan struct{}),
|
||||||
timeSource: timeSource,
|
timeSource: timeSource,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -534,7 +535,7 @@ func handleCreateRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan
|
||||||
// some validity checks.
|
// some validity checks.
|
||||||
mtx := wire.NewMsgTx()
|
mtx := wire.NewMsgTx()
|
||||||
for _, input := range c.Inputs {
|
for _, input := range c.Inputs {
|
||||||
txHash, err := wire.NewShaHashFromStr(input.Txid)
|
txHash, err := chainhash.NewHashFromStr(input.Txid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, rpcDecodeHexError(input.Txid)
|
return nil, rpcDecodeHexError(input.Txid)
|
||||||
}
|
}
|
||||||
|
@ -781,7 +782,7 @@ func handleDecodeRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan
|
||||||
|
|
||||||
// Create and return the result.
|
// Create and return the result.
|
||||||
txReply := btcjson.TxRawDecodeResult{
|
txReply := btcjson.TxRawDecodeResult{
|
||||||
Txid: mtx.TxSha().String(),
|
Txid: mtx.TxHash().String(),
|
||||||
Version: mtx.Version,
|
Version: mtx.Version,
|
||||||
Locktime: mtx.LockTime,
|
Locktime: mtx.LockTime,
|
||||||
Vin: createVinList(&mtx),
|
Vin: createVinList(&mtx),
|
||||||
|
@ -1005,7 +1006,7 @@ func handleGetBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i
|
||||||
c := cmd.(*btcjson.GetBlockCmd)
|
c := cmd.(*btcjson.GetBlockCmd)
|
||||||
|
|
||||||
// Load the raw block bytes from the database.
|
// Load the raw block bytes from the database.
|
||||||
hash, err := wire.NewShaHashFromStr(c.Hash)
|
hash, err := chainhash.NewHashFromStr(c.Hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, rpcDecodeHexError(c.Hash)
|
return nil, rpcDecodeHexError(c.Hash)
|
||||||
}
|
}
|
||||||
|
@ -1077,7 +1078,7 @@ func handleGetBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i
|
||||||
transactions := blk.Transactions()
|
transactions := blk.Transactions()
|
||||||
txNames := make([]string, len(transactions))
|
txNames := make([]string, len(transactions))
|
||||||
for i, tx := range transactions {
|
for i, tx := range transactions {
|
||||||
txNames[i] = tx.Sha().String()
|
txNames[i] = tx.Hash().String()
|
||||||
}
|
}
|
||||||
|
|
||||||
blockReply.Tx = txNames
|
blockReply.Tx = txNames
|
||||||
|
@ -1086,7 +1087,7 @@ func handleGetBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i
|
||||||
rawTxns := make([]btcjson.TxRawResult, len(txns))
|
rawTxns := make([]btcjson.TxRawResult, len(txns))
|
||||||
for i, tx := range txns {
|
for i, tx := range txns {
|
||||||
rawTxn, err := createTxRawResult(s.server.chainParams,
|
rawTxn, err := createTxRawResult(s.server.chainParams,
|
||||||
tx.MsgTx(), tx.Sha().String(), blockHeader,
|
tx.MsgTx(), tx.Hash().String(), blockHeader,
|
||||||
hash.String(), blockHeight, best.Height)
|
hash.String(), blockHeight, best.Height)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -1124,7 +1125,7 @@ func handleGetBlockHeader(s *rpcServer, cmd interface{}, closeChan <-chan struct
|
||||||
c := cmd.(*btcjson.GetBlockHeaderCmd)
|
c := cmd.(*btcjson.GetBlockHeaderCmd)
|
||||||
|
|
||||||
// Load the raw header bytes from the database.
|
// Load the raw header bytes from the database.
|
||||||
hash, err := wire.NewShaHashFromStr(c.Hash)
|
hash, err := chainhash.NewHashFromStr(c.Hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, rpcDecodeHexError(c.Hash)
|
return nil, rpcDecodeHexError(c.Hash)
|
||||||
}
|
}
|
||||||
|
@ -1194,7 +1195,7 @@ func handleGetBlockHeader(s *rpcServer, cmd interface{}, closeChan <-chan struct
|
||||||
|
|
||||||
// encodeTemplateID encodes the passed details into an ID that can be used to
|
// encodeTemplateID encodes the passed details into an ID that can be used to
|
||||||
// uniquely identify a block template.
|
// uniquely identify a block template.
|
||||||
func encodeTemplateID(prevHash *wire.ShaHash, lastGenerated time.Time) string {
|
func encodeTemplateID(prevHash *chainhash.Hash, lastGenerated time.Time) string {
|
||||||
return fmt.Sprintf("%s-%d", prevHash.String(), lastGenerated.Unix())
|
return fmt.Sprintf("%s-%d", prevHash.String(), lastGenerated.Unix())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1203,13 +1204,13 @@ func encodeTemplateID(prevHash *wire.ShaHash, lastGenerated time.Time) string {
|
||||||
// that are using long polling for block templates. The ID consists of the
|
// that are using long polling for block templates. The ID consists of the
|
||||||
// previous block hash for the associated template and the time the associated
|
// previous block hash for the associated template and the time the associated
|
||||||
// template was generated.
|
// template was generated.
|
||||||
func decodeTemplateID(templateID string) (*wire.ShaHash, int64, error) {
|
func decodeTemplateID(templateID string) (*chainhash.Hash, int64, error) {
|
||||||
fields := strings.Split(templateID, "-")
|
fields := strings.Split(templateID, "-")
|
||||||
if len(fields) != 2 {
|
if len(fields) != 2 {
|
||||||
return nil, 0, errors.New("invalid longpollid format")
|
return nil, 0, errors.New("invalid longpollid format")
|
||||||
}
|
}
|
||||||
|
|
||||||
prevHash, err := wire.NewShaHashFromStr(fields[0])
|
prevHash, err := chainhash.NewHashFromStr(fields[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, errors.New("invalid longpollid format")
|
return nil, 0, errors.New("invalid longpollid format")
|
||||||
}
|
}
|
||||||
|
@ -1225,7 +1226,7 @@ func decodeTemplateID(templateID string) (*wire.ShaHash, int64, error) {
|
||||||
// notified when block templates are stale.
|
// notified when block templates are stale.
|
||||||
//
|
//
|
||||||
// This function MUST be called with the state locked.
|
// This function MUST be called with the state locked.
|
||||||
func (state *gbtWorkState) notifyLongPollers(latestHash *wire.ShaHash, lastGenerated time.Time) {
|
func (state *gbtWorkState) notifyLongPollers(latestHash *chainhash.Hash, lastGenerated time.Time) {
|
||||||
// Notify anything that is waiting for a block template update from a
|
// Notify anything that is waiting for a block template update from a
|
||||||
// hash which is not the hash of the tip of the best chain since their
|
// hash which is not the hash of the tip of the best chain since their
|
||||||
// work is now invalid.
|
// work is now invalid.
|
||||||
|
@ -1272,12 +1273,12 @@ func (state *gbtWorkState) notifyLongPollers(latestHash *wire.ShaHash, lastGener
|
||||||
// NotifyBlockConnected uses the newly-connected block to notify any long poll
|
// NotifyBlockConnected uses the newly-connected block to notify any long poll
|
||||||
// clients with a new block template when their existing block template is
|
// clients with a new block template when their existing block template is
|
||||||
// stale due to the newly connected block.
|
// stale due to the newly connected block.
|
||||||
func (state *gbtWorkState) NotifyBlockConnected(blockSha *wire.ShaHash) {
|
func (state *gbtWorkState) NotifyBlockConnected(blockHash *chainhash.Hash) {
|
||||||
go func() {
|
go func() {
|
||||||
state.Lock()
|
state.Lock()
|
||||||
defer state.Unlock()
|
defer state.Unlock()
|
||||||
|
|
||||||
state.notifyLongPollers(blockSha, state.lastTxUpdate)
|
state.notifyLongPollers(blockHash, state.lastTxUpdate)
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1311,7 +1312,7 @@ func (state *gbtWorkState) NotifyMempoolTx(lastUpdated time.Time) {
|
||||||
// without requiring a different channel for each client.
|
// without requiring a different channel for each client.
|
||||||
//
|
//
|
||||||
// This function MUST be called with the state locked.
|
// This function MUST be called with the state locked.
|
||||||
func (state *gbtWorkState) templateUpdateChan(prevHash *wire.ShaHash, lastGenerated int64) chan struct{} {
|
func (state *gbtWorkState) templateUpdateChan(prevHash *chainhash.Hash, lastGenerated int64) chan struct{} {
|
||||||
// Either get the current list of channels waiting for updates about
|
// Either get the current list of channels waiting for updates about
|
||||||
// changes to block template for the previous hash or create a new one.
|
// changes to block template for the previous hash or create a new one.
|
||||||
channels, ok := state.notifyMap[*prevHash]
|
channels, ok := state.notifyMap[*prevHash]
|
||||||
|
@ -1500,9 +1501,9 @@ func (state *gbtWorkState) blockTemplateResult(useCoinbaseValue bool, submitOld
|
||||||
// the adjustments to the various lengths and indices.
|
// the adjustments to the various lengths and indices.
|
||||||
numTx := len(msgBlock.Transactions)
|
numTx := len(msgBlock.Transactions)
|
||||||
transactions := make([]btcjson.GetBlockTemplateResultTx, 0, numTx-1)
|
transactions := make([]btcjson.GetBlockTemplateResultTx, 0, numTx-1)
|
||||||
txIndex := make(map[wire.ShaHash]int64, numTx)
|
txIndex := make(map[chainhash.Hash]int64, numTx)
|
||||||
for i, tx := range msgBlock.Transactions {
|
for i, tx := range msgBlock.Transactions {
|
||||||
txHash := tx.TxSha()
|
txHash := tx.TxHash()
|
||||||
txIndex[txHash] = int64(i)
|
txIndex[txHash] = int64(i)
|
||||||
|
|
||||||
// Skip the coinbase transaction.
|
// Skip the coinbase transaction.
|
||||||
|
@ -1594,7 +1595,7 @@ func (state *gbtWorkState) blockTemplateResult(useCoinbaseValue bool, submitOld
|
||||||
|
|
||||||
resultTx := btcjson.GetBlockTemplateResultTx{
|
resultTx := btcjson.GetBlockTemplateResultTx{
|
||||||
Data: hex.EncodeToString(txBuf.Bytes()),
|
Data: hex.EncodeToString(txBuf.Bytes()),
|
||||||
Hash: tx.TxSha().String(),
|
Hash: tx.TxHash().String(),
|
||||||
Depends: []int64{},
|
Depends: []int64{},
|
||||||
Fee: template.Fees[0],
|
Fee: template.Fees[0],
|
||||||
SigOps: template.SigOpCounts[0],
|
SigOps: template.SigOpCounts[0],
|
||||||
|
@ -2260,7 +2261,7 @@ func handleGetRawMempool(s *rpcServer, cmd interface{}, closeChan <-chan struct{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result[tx.Sha().String()] = mpd
|
result[tx.Hash().String()] = mpd
|
||||||
}
|
}
|
||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
|
@ -2270,7 +2271,7 @@ func handleGetRawMempool(s *rpcServer, cmd interface{}, closeChan <-chan struct{
|
||||||
// verbose flag is not set.
|
// verbose flag is not set.
|
||||||
hashStrings := make([]string, len(descs))
|
hashStrings := make([]string, len(descs))
|
||||||
for i := range hashStrings {
|
for i := range hashStrings {
|
||||||
hashStrings[i] = descs[i].Tx.Sha().String()
|
hashStrings[i] = descs[i].Tx.Hash().String()
|
||||||
}
|
}
|
||||||
|
|
||||||
return hashStrings, nil
|
return hashStrings, nil
|
||||||
|
@ -2280,8 +2281,8 @@ func handleGetRawMempool(s *rpcServer, cmd interface{}, closeChan <-chan struct{
|
||||||
func handleGetRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
|
func handleGetRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
|
||||||
c := cmd.(*btcjson.GetRawTransactionCmd)
|
c := cmd.(*btcjson.GetRawTransactionCmd)
|
||||||
|
|
||||||
// Convert the provided transaction hash hex to a ShaHash.
|
// Convert the provided transaction hash hex to a Hash.
|
||||||
txHash, err := wire.NewShaHashFromStr(c.Txid)
|
txHash, err := chainhash.NewHashFromStr(c.Txid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, rpcDecodeHexError(c.Txid)
|
return nil, rpcDecodeHexError(c.Txid)
|
||||||
}
|
}
|
||||||
|
@ -2294,7 +2295,7 @@ func handleGetRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan str
|
||||||
// Try to fetch the transaction from the memory pool and if that fails,
|
// Try to fetch the transaction from the memory pool and if that fails,
|
||||||
// try the block database.
|
// try the block database.
|
||||||
var mtx *wire.MsgTx
|
var mtx *wire.MsgTx
|
||||||
var blkHash *wire.ShaHash
|
var blkHash *chainhash.Hash
|
||||||
var blkHeight int32
|
var blkHeight int32
|
||||||
tx, err := s.server.txMemPool.FetchTransaction(txHash)
|
tx, err := s.server.txMemPool.FetchTransaction(txHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -2448,15 +2449,15 @@ func reverseUint32Array(b []byte) {
|
||||||
func handleGetTxOut(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
|
func handleGetTxOut(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
|
||||||
c := cmd.(*btcjson.GetTxOutCmd)
|
c := cmd.(*btcjson.GetTxOutCmd)
|
||||||
|
|
||||||
// Convert the provided transaction hash hex to a ShaHash.
|
// Convert the provided transaction hash hex to a Hash.
|
||||||
txHash, err := wire.NewShaHashFromStr(c.Txid)
|
txHash, err := chainhash.NewHashFromStr(c.Txid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, rpcDecodeHexError(c.Txid)
|
return nil, rpcDecodeHexError(c.Txid)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If requested and the tx is available in the mempool try to fetch it
|
// If requested and the tx is available in the mempool try to fetch it
|
||||||
// from there, otherwise attempt to fetch from the block database.
|
// from there, otherwise attempt to fetch from the block database.
|
||||||
var bestBlockSha string
|
var bestBlockHash string
|
||||||
var confirmations int32
|
var confirmations int32
|
||||||
var txVersion int32
|
var txVersion int32
|
||||||
var value int64
|
var value int64
|
||||||
|
@ -2491,7 +2492,7 @@ func handleGetTxOut(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i
|
||||||
}
|
}
|
||||||
|
|
||||||
best := s.chain.BestSnapshot()
|
best := s.chain.BestSnapshot()
|
||||||
bestBlockSha = best.Hash.String()
|
bestBlockHash = best.Hash.String()
|
||||||
confirmations = 0
|
confirmations = 0
|
||||||
txVersion = mtx.Version
|
txVersion = mtx.Version
|
||||||
value = txOut.Value
|
value = txOut.Value
|
||||||
|
@ -2513,7 +2514,7 @@ func handleGetTxOut(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i
|
||||||
}
|
}
|
||||||
|
|
||||||
best := s.chain.BestSnapshot()
|
best := s.chain.BestSnapshot()
|
||||||
bestBlockSha = best.Hash.String()
|
bestBlockHash = best.Hash.String()
|
||||||
confirmations = 1 + best.Height - entry.BlockHeight()
|
confirmations = 1 + best.Height - entry.BlockHeight()
|
||||||
txVersion = entry.Version()
|
txVersion = entry.Version()
|
||||||
value = entry.AmountByIndex(c.Vout)
|
value = entry.AmountByIndex(c.Vout)
|
||||||
|
@ -2537,7 +2538,7 @@ func handleGetTxOut(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i
|
||||||
}
|
}
|
||||||
|
|
||||||
txOutReply := &btcjson.GetTxOutResult{
|
txOutReply := &btcjson.GetTxOutResult{
|
||||||
BestBlock: bestBlockSha,
|
BestBlock: bestBlockHash,
|
||||||
Confirmations: int64(confirmations),
|
Confirmations: int64(confirmations),
|
||||||
Value: btcutil.Amount(value).ToBTC(),
|
Value: btcutil.Amount(value).ToBTC(),
|
||||||
Version: txVersion,
|
Version: txVersion,
|
||||||
|
@ -2576,7 +2577,7 @@ func handleGetWorkRequest(s *rpcServer) (interface{}, error) {
|
||||||
// variations if the best block changed.
|
// variations if the best block changed.
|
||||||
if state.prevHash != nil && !state.prevHash.IsEqual(latestHash) {
|
if state.prevHash != nil && !state.prevHash.IsEqual(latestHash) {
|
||||||
state.extraNonce = 0
|
state.extraNonce = 0
|
||||||
state.blockInfo = make(map[wire.ShaHash]*workStateBlockInfo)
|
state.blockInfo = make(map[chainhash.Hash]*workStateBlockInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset the previous best hash the block template was generated
|
// Reset the previous best hash the block template was generated
|
||||||
|
@ -2690,8 +2691,8 @@ func handleGetWorkRequest(s *rpcServer) (interface{}, error) {
|
||||||
// useless, but it is required for compatibility with the reference
|
// useless, but it is required for compatibility with the reference
|
||||||
// implementation.
|
// implementation.
|
||||||
var hash1 [hash1Len]byte
|
var hash1 [hash1Len]byte
|
||||||
hash1[wire.HashSize] = 0x80
|
hash1[chainhash.HashSize] = 0x80
|
||||||
binary.BigEndian.PutUint64(hash1[len(hash1)-8:], wire.HashSize*8)
|
binary.BigEndian.PutUint64(hash1[len(hash1)-8:], chainhash.HashSize*8)
|
||||||
|
|
||||||
// The final result reverses each of the fields to little endian.
|
// The final result reverses each of the fields to little endian.
|
||||||
// In particular, the data, hash1, and midstate fields are treated as
|
// In particular, the data, hash1, and midstate fields are treated as
|
||||||
|
@ -2817,7 +2818,7 @@ func handleGetWorkSubmission(s *rpcServer, hexData string) (interface{}, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// The block was accepted.
|
// The block was accepted.
|
||||||
rpcsLog.Infof("Block submitted via getwork accepted: %s", block.Sha())
|
rpcsLog.Infof("Block submitted via getwork accepted: %s", block.Hash())
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2931,7 +2932,7 @@ func handlePing(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (inter
|
||||||
// possible.
|
// possible.
|
||||||
type retrievedTx struct {
|
type retrievedTx struct {
|
||||||
txBytes []byte
|
txBytes []byte
|
||||||
blkHash *wire.ShaHash // Only set when transaction is in a block.
|
blkHash *chainhash.Hash // Only set when transaction is in a block.
|
||||||
tx *btcutil.Tx
|
tx *btcutil.Tx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2951,7 +2952,7 @@ func fetchInputTxos(s *rpcServer, tx *wire.MsgTx) (map[wire.OutPoint]wire.TxOut,
|
||||||
if origin.Index >= uint32(len(txOuts)) {
|
if origin.Index >= uint32(len(txOuts)) {
|
||||||
errStr := fmt.Sprintf("unable to find output "+
|
errStr := fmt.Sprintf("unable to find output "+
|
||||||
"%v referenced from transaction %s:%d",
|
"%v referenced from transaction %s:%d",
|
||||||
origin, tx.TxSha(), txInIndex)
|
origin, tx.TxHash(), txInIndex)
|
||||||
return nil, internalRPCError(errStr, "")
|
return nil, internalRPCError(errStr, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2992,7 +2993,7 @@ func fetchInputTxos(s *rpcServer, tx *wire.MsgTx) (map[wire.OutPoint]wire.TxOut,
|
||||||
if origin.Index >= uint32(len(msgTx.TxOut)) {
|
if origin.Index >= uint32(len(msgTx.TxOut)) {
|
||||||
errStr := fmt.Sprintf("unable to find output %v "+
|
errStr := fmt.Sprintf("unable to find output %v "+
|
||||||
"referenced from transaction %s:%d", origin,
|
"referenced from transaction %s:%d", origin,
|
||||||
tx.TxSha(), txInIndex)
|
tx.TxHash(), txInIndex)
|
||||||
return nil, internalRPCError(errStr, "")
|
return nil, internalRPCError(errStr, "")
|
||||||
}
|
}
|
||||||
originOutputs[*origin] = *msgTx.TxOut[origin.Index]
|
originOutputs[*origin] = *msgTx.TxOut[origin.Index]
|
||||||
|
@ -3350,7 +3351,7 @@ func handleSearchRawTransactions(s *rpcServer, cmd interface{}, closeChan <-chan
|
||||||
|
|
||||||
result := &srtList[i]
|
result := &srtList[i]
|
||||||
result.Hex = hexTxns[i]
|
result.Hex = hexTxns[i]
|
||||||
result.Txid = mtx.TxSha().String()
|
result.Txid = mtx.TxHash().String()
|
||||||
result.Vin, err = createVinListPrevOut(s, mtx, chainParams,
|
result.Vin, err = createVinListPrevOut(s, mtx, chainParams,
|
||||||
vinExtra, filterAddrMap)
|
vinExtra, filterAddrMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -3447,11 +3448,11 @@ func handleSendRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan st
|
||||||
// error is returned to the client with the deserialization
|
// error is returned to the client with the deserialization
|
||||||
// error code (to match bitcoind behavior).
|
// error code (to match bitcoind behavior).
|
||||||
if _, ok := err.(RuleError); ok {
|
if _, ok := err.(RuleError); ok {
|
||||||
rpcsLog.Debugf("Rejected transaction %v: %v", tx.Sha(),
|
rpcsLog.Debugf("Rejected transaction %v: %v", tx.Hash(),
|
||||||
err)
|
err)
|
||||||
} else {
|
} else {
|
||||||
rpcsLog.Errorf("Failed to process transaction %v: %v",
|
rpcsLog.Errorf("Failed to process transaction %v: %v",
|
||||||
tx.Sha(), err)
|
tx.Hash(), err)
|
||||||
}
|
}
|
||||||
return nil, &btcjson.RPCError{
|
return nil, &btcjson.RPCError{
|
||||||
Code: btcjson.ErrRPCDeserialization,
|
Code: btcjson.ErrRPCDeserialization,
|
||||||
|
@ -3463,10 +3464,10 @@ func handleSendRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan st
|
||||||
|
|
||||||
// Keep track of all the sendrawtransaction request txns so that they
|
// Keep track of all the sendrawtransaction request txns so that they
|
||||||
// can be rebroadcast if they don't make their way into a block.
|
// can be rebroadcast if they don't make their way into a block.
|
||||||
iv := wire.NewInvVect(wire.InvTypeTx, tx.Sha())
|
iv := wire.NewInvVect(wire.InvTypeTx, tx.Hash())
|
||||||
s.server.AddRebroadcastInventory(iv, tx)
|
s.server.AddRebroadcastInventory(iv, tx)
|
||||||
|
|
||||||
return tx.Sha().String(), nil
|
return tx.Hash().String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleSetGenerate implements the setgenerate command.
|
// handleSetGenerate implements the setgenerate command.
|
||||||
|
@ -3538,7 +3539,7 @@ func handleSubmitBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{})
|
||||||
return fmt.Sprintf("rejected: %s", err.Error()), nil
|
return fmt.Sprintf("rejected: %s", err.Error()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
rpcsLog.Infof("Accepted block %s via submitblock", block.Sha())
|
rpcsLog.Infof("Accepted block %s via submitblock", block.Hash())
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3584,7 +3585,7 @@ func verifyChain(s *rpcServer, level, depth int32) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rpcsLog.Errorf("Verify is unable to validate "+
|
rpcsLog.Errorf("Verify is unable to validate "+
|
||||||
"block at hash %v height %d: %v",
|
"block at hash %v height %d: %v",
|
||||||
block.Sha(), height, err)
|
block.Hash(), height, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3645,7 +3646,7 @@ func handleVerifyMessage(s *rpcServer, cmd interface{}, closeChan <-chan struct{
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
wire.WriteVarString(&buf, 0, "Bitcoin Signed Message:\n")
|
wire.WriteVarString(&buf, 0, "Bitcoin Signed Message:\n")
|
||||||
wire.WriteVarString(&buf, 0, c.Message)
|
wire.WriteVarString(&buf, 0, c.Message)
|
||||||
expectedMessageHash := wire.DoubleSha256(buf.Bytes())
|
expectedMessageHash := chainhash.DoubleHashB(buf.Bytes())
|
||||||
pk, wasCompressed, err := btcec.RecoverCompact(btcec.S256(), sig,
|
pk, wasCompressed, err := btcec.RecoverCompact(btcec.S256(), sig,
|
||||||
expectedMessageHash)
|
expectedMessageHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -20,6 +20,7 @@ import (
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/blockchain"
|
"github.com/btcsuite/btcd/blockchain"
|
||||||
"github.com/btcsuite/btcd/btcjson"
|
"github.com/btcsuite/btcd/btcjson"
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/database"
|
"github.com/btcsuite/btcd/database"
|
||||||
"github.com/btcsuite/btcd/txscript"
|
"github.com/btcsuite/btcd/txscript"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
|
@ -418,7 +419,7 @@ func (*wsNotificationManager) notifyBlockConnected(clients map[chan struct{}]*ws
|
||||||
block *btcutil.Block) {
|
block *btcutil.Block) {
|
||||||
|
|
||||||
// Notify interested websocket clients about the connected block.
|
// Notify interested websocket clients about the connected block.
|
||||||
ntfn := btcjson.NewBlockConnectedNtfn(block.Sha().String(),
|
ntfn := btcjson.NewBlockConnectedNtfn(block.Hash().String(),
|
||||||
int32(block.Height()), block.MsgBlock().Header.Timestamp.Unix())
|
int32(block.Height()), block.MsgBlock().Header.Timestamp.Unix())
|
||||||
marshalledJSON, err := btcjson.MarshalCmd(nil, ntfn)
|
marshalledJSON, err := btcjson.MarshalCmd(nil, ntfn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -442,7 +443,7 @@ func (*wsNotificationManager) notifyBlockDisconnected(clients map[chan struct{}]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notify interested websocket clients about the disconnected block.
|
// Notify interested websocket clients about the disconnected block.
|
||||||
ntfn := btcjson.NewBlockDisconnectedNtfn(block.Sha().String(),
|
ntfn := btcjson.NewBlockDisconnectedNtfn(block.Hash().String(),
|
||||||
int32(block.Height()), block.MsgBlock().Header.Timestamp.Unix())
|
int32(block.Height()), block.MsgBlock().Header.Timestamp.Unix())
|
||||||
marshalledJSON, err := btcjson.MarshalCmd(nil, ntfn)
|
marshalledJSON, err := btcjson.MarshalCmd(nil, ntfn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -470,7 +471,7 @@ func (m *wsNotificationManager) UnregisterNewMempoolTxsUpdates(wsc *wsClient) {
|
||||||
// notifyForNewTx notifies websocket clients that have registered for updates
|
// notifyForNewTx notifies websocket clients that have registered for updates
|
||||||
// when a new transaction is added to the memory pool.
|
// when a new transaction is added to the memory pool.
|
||||||
func (m *wsNotificationManager) notifyForNewTx(clients map[chan struct{}]*wsClient, tx *btcutil.Tx) {
|
func (m *wsNotificationManager) notifyForNewTx(clients map[chan struct{}]*wsClient, tx *btcutil.Tx) {
|
||||||
txShaStr := tx.Sha().String()
|
txHashStr := tx.Hash().String()
|
||||||
mtx := tx.MsgTx()
|
mtx := tx.MsgTx()
|
||||||
|
|
||||||
var amount int64
|
var amount int64
|
||||||
|
@ -478,7 +479,7 @@ func (m *wsNotificationManager) notifyForNewTx(clients map[chan struct{}]*wsClie
|
||||||
amount += txOut.Value
|
amount += txOut.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
ntfn := btcjson.NewTxAcceptedNtfn(txShaStr, btcutil.Amount(amount).ToBTC())
|
ntfn := btcjson.NewTxAcceptedNtfn(txHashStr, btcutil.Amount(amount).ToBTC())
|
||||||
marshalledJSON, err := btcjson.MarshalCmd(nil, ntfn)
|
marshalledJSON, err := btcjson.MarshalCmd(nil, ntfn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rpcsLog.Errorf("Failed to marshal tx notification: %s", err.Error())
|
rpcsLog.Errorf("Failed to marshal tx notification: %s", err.Error())
|
||||||
|
@ -495,7 +496,7 @@ func (m *wsNotificationManager) notifyForNewTx(clients map[chan struct{}]*wsClie
|
||||||
}
|
}
|
||||||
|
|
||||||
net := m.server.server.chainParams
|
net := m.server.server.chainParams
|
||||||
rawTx, err := createTxRawResult(net, mtx, txShaStr, nil,
|
rawTx, err := createTxRawResult(net, mtx, txHashStr, nil,
|
||||||
"", 0, 0)
|
"", 0, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
@ -601,7 +602,7 @@ func blockDetails(block *btcutil.Block, txIndex int) *btcjson.BlockDetails {
|
||||||
}
|
}
|
||||||
return &btcjson.BlockDetails{
|
return &btcjson.BlockDetails{
|
||||||
Height: int32(block.Height()),
|
Height: int32(block.Height()),
|
||||||
Hash: block.Sha().String(),
|
Hash: block.Hash().String(),
|
||||||
Index: txIndex,
|
Index: txIndex,
|
||||||
Time: block.MsgBlock().Header.Timestamp.Unix(),
|
Time: block.MsgBlock().Header.Timestamp.Unix(),
|
||||||
}
|
}
|
||||||
|
@ -654,7 +655,7 @@ func (m *wsNotificationManager) notifyForTxOuts(ops map[wire.OutPoint]map[chan s
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
op := []*wire.OutPoint{wire.NewOutPoint(tx.Sha(), uint32(i))}
|
op := []*wire.OutPoint{wire.NewOutPoint(tx.Hash(), uint32(i))}
|
||||||
for wscQuit, wsc := range cmap {
|
for wscQuit, wsc := range cmap {
|
||||||
m.addSpentRequests(ops, wsc, op)
|
m.addSpentRequests(ops, wsc, op)
|
||||||
|
|
||||||
|
@ -1607,7 +1608,7 @@ func checkAddressValidity(addrs []string) error {
|
||||||
func deserializeOutpoints(serializedOuts []btcjson.OutPoint) ([]*wire.OutPoint, error) {
|
func deserializeOutpoints(serializedOuts []btcjson.OutPoint) ([]*wire.OutPoint, error) {
|
||||||
outpoints := make([]*wire.OutPoint, 0, len(serializedOuts))
|
outpoints := make([]*wire.OutPoint, 0, len(serializedOuts))
|
||||||
for i := range serializedOuts {
|
for i := range serializedOuts {
|
||||||
blockHash, err := wire.NewShaHashFromStr(serializedOuts[i].Hash)
|
blockHash, err := chainhash.NewHashFromStr(serializedOuts[i].Hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, rpcDecodeHexError(serializedOuts[i].Hash)
|
return nil, rpcDecodeHexError(serializedOuts[i].Hash)
|
||||||
}
|
}
|
||||||
|
@ -1747,7 +1748,7 @@ func rescanBlock(wsc *wsClient, lookups *rescanKeys, blk *btcutil.Block) {
|
||||||
}
|
}
|
||||||
|
|
||||||
outpoint := wire.OutPoint{
|
outpoint := wire.OutPoint{
|
||||||
Hash: *tx.Sha(),
|
Hash: *tx.Hash(),
|
||||||
Index: uint32(txOutIdx),
|
Index: uint32(txOutIdx),
|
||||||
}
|
}
|
||||||
lookups.unspent[outpoint] = struct{}{}
|
lookups.unspent[outpoint] = struct{}{}
|
||||||
|
@ -1786,7 +1787,7 @@ func rescanBlock(wsc *wsClient, lookups *rescanKeys, blk *btcutil.Block) {
|
||||||
// range of blocks. If this condition does not hold true, the JSON-RPC error
|
// range of blocks. If this condition does not hold true, the JSON-RPC error
|
||||||
// for an unrecoverable reorganize is returned.
|
// for an unrecoverable reorganize is returned.
|
||||||
func recoverFromReorg(chain *blockchain.BlockChain, minBlock, maxBlock int32,
|
func recoverFromReorg(chain *blockchain.BlockChain, minBlock, maxBlock int32,
|
||||||
lastBlock *wire.ShaHash) ([]wire.ShaHash, error) {
|
lastBlock *chainhash.Hash) ([]chainhash.Hash, error) {
|
||||||
|
|
||||||
hashList, err := chain.HeightRange(minBlock, maxBlock)
|
hashList, err := chain.HeightRange(minBlock, maxBlock)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1818,7 +1819,7 @@ func recoverFromReorg(chain *blockchain.BlockChain, minBlock, maxBlock int32,
|
||||||
|
|
||||||
// descendantBlock returns the appropriate JSON-RPC error if a current block
|
// descendantBlock returns the appropriate JSON-RPC error if a current block
|
||||||
// fetched during a reorganize is not a direct child of the parent block hash.
|
// fetched during a reorganize is not a direct child of the parent block hash.
|
||||||
func descendantBlock(prevHash *wire.ShaHash, curBlock *btcutil.Block) error {
|
func descendantBlock(prevHash *chainhash.Hash, curBlock *btcutil.Block) error {
|
||||||
curHash := &curBlock.MsgBlock().Header.PrevBlock
|
curHash := &curBlock.MsgBlock().Header.PrevBlock
|
||||||
if !prevHash.IsEqual(curHash) {
|
if !prevHash.IsEqual(curHash) {
|
||||||
rpcsLog.Errorf("Stopping rescan for reorged block %v "+
|
rpcsLog.Errorf("Stopping rescan for reorged block %v "+
|
||||||
|
@ -1847,7 +1848,7 @@ func handleRescan(wsc *wsClient, icmd interface{}) (interface{}, error) {
|
||||||
outpoints := make([]*wire.OutPoint, 0, len(cmd.OutPoints))
|
outpoints := make([]*wire.OutPoint, 0, len(cmd.OutPoints))
|
||||||
for i := range cmd.OutPoints {
|
for i := range cmd.OutPoints {
|
||||||
cmdOutpoint := &cmd.OutPoints[i]
|
cmdOutpoint := &cmd.OutPoints[i]
|
||||||
blockHash, err := wire.NewShaHashFromStr(cmdOutpoint.Hash)
|
blockHash, err := chainhash.NewHashFromStr(cmdOutpoint.Hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, rpcDecodeHexError(cmdOutpoint.Hash)
|
return nil, rpcDecodeHexError(cmdOutpoint.Hash)
|
||||||
}
|
}
|
||||||
|
@ -1922,7 +1923,7 @@ func handleRescan(wsc *wsClient, icmd interface{}) (interface{}, error) {
|
||||||
|
|
||||||
chain := wsc.server.chain
|
chain := wsc.server.chain
|
||||||
|
|
||||||
minBlockHash, err := wire.NewShaHashFromStr(cmd.BeginBlock)
|
minBlockHash, err := chainhash.NewHashFromStr(cmd.BeginBlock)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, rpcDecodeHexError(cmd.BeginBlock)
|
return nil, rpcDecodeHexError(cmd.BeginBlock)
|
||||||
}
|
}
|
||||||
|
@ -1936,7 +1937,7 @@ func handleRescan(wsc *wsClient, icmd interface{}) (interface{}, error) {
|
||||||
|
|
||||||
maxBlock := int32(math.MaxInt32)
|
maxBlock := int32(math.MaxInt32)
|
||||||
if cmd.EndBlock != nil {
|
if cmd.EndBlock != nil {
|
||||||
maxBlockHash, err := wire.NewShaHashFromStr(*cmd.EndBlock)
|
maxBlockHash, err := chainhash.NewHashFromStr(*cmd.EndBlock)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, rpcDecodeHexError(*cmd.EndBlock)
|
return nil, rpcDecodeHexError(*cmd.EndBlock)
|
||||||
}
|
}
|
||||||
|
@ -1952,7 +1953,7 @@ func handleRescan(wsc *wsClient, icmd interface{}) (interface{}, error) {
|
||||||
// lastBlock and lastBlockHash track the previously-rescanned block.
|
// lastBlock and lastBlockHash track the previously-rescanned block.
|
||||||
// They equal nil when no previous blocks have been rescanned.
|
// They equal nil when no previous blocks have been rescanned.
|
||||||
var lastBlock *btcutil.Block
|
var lastBlock *btcutil.Block
|
||||||
var lastBlockHash *wire.ShaHash
|
var lastBlockHash *chainhash.Hash
|
||||||
|
|
||||||
// A ticker is created to wait at least 10 seconds before notifying the
|
// A ticker is created to wait at least 10 seconds before notifying the
|
||||||
// websocket client of the current progress completed by the rescan.
|
// websocket client of the current progress completed by the rescan.
|
||||||
|
@ -2094,7 +2095,7 @@ fetchRange:
|
||||||
default:
|
default:
|
||||||
rescanBlock(wsc, &lookups, blk)
|
rescanBlock(wsc, &lookups, blk)
|
||||||
lastBlock = blk
|
lastBlock = blk
|
||||||
lastBlockHash = blk.Sha()
|
lastBlockHash = blk.Hash()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Periodically notify the client of the progress
|
// Periodically notify the client of the progress
|
||||||
|
|
45
server.go
45
server.go
|
@ -24,6 +24,7 @@ import (
|
||||||
"github.com/btcsuite/btcd/blockchain"
|
"github.com/btcsuite/btcd/blockchain"
|
||||||
"github.com/btcsuite/btcd/blockchain/indexers"
|
"github.com/btcsuite/btcd/blockchain/indexers"
|
||||||
"github.com/btcsuite/btcd/chaincfg"
|
"github.com/btcsuite/btcd/chaincfg"
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/database"
|
"github.com/btcsuite/btcd/database"
|
||||||
"github.com/btcsuite/btcd/mining"
|
"github.com/btcsuite/btcd/mining"
|
||||||
"github.com/btcsuite/btcd/peer"
|
"github.com/btcsuite/btcd/peer"
|
||||||
|
@ -99,7 +100,7 @@ type relayMsg struct {
|
||||||
// updates, peer heights will be kept up to date, allowing for fresh data when
|
// updates, peer heights will be kept up to date, allowing for fresh data when
|
||||||
// selecting sync peer candidacy.
|
// selecting sync peer candidacy.
|
||||||
type updatePeerHeightsMsg struct {
|
type updatePeerHeightsMsg struct {
|
||||||
newSha *wire.ShaHash
|
newHash *chainhash.Hash
|
||||||
newHeight int32
|
newHeight int32
|
||||||
originPeer *serverPeer
|
originPeer *serverPeer
|
||||||
}
|
}
|
||||||
|
@ -218,12 +219,12 @@ type serverPeer struct {
|
||||||
|
|
||||||
server *server
|
server *server
|
||||||
persistent bool
|
persistent bool
|
||||||
continueHash *wire.ShaHash
|
continueHash *chainhash.Hash
|
||||||
relayMtx sync.Mutex
|
relayMtx sync.Mutex
|
||||||
disableRelayTx bool
|
disableRelayTx bool
|
||||||
requestQueue []*wire.InvVect
|
requestQueue []*wire.InvVect
|
||||||
requestedTxns map[wire.ShaHash]struct{}
|
requestedTxns map[chainhash.Hash]struct{}
|
||||||
requestedBlocks map[wire.ShaHash]struct{}
|
requestedBlocks map[chainhash.Hash]struct{}
|
||||||
filter *bloom.Filter
|
filter *bloom.Filter
|
||||||
knownAddresses map[string]struct{}
|
knownAddresses map[string]struct{}
|
||||||
banScore dynamicBanScore
|
banScore dynamicBanScore
|
||||||
|
@ -239,8 +240,8 @@ func newServerPeer(s *server, isPersistent bool) *serverPeer {
|
||||||
return &serverPeer{
|
return &serverPeer{
|
||||||
server: s,
|
server: s,
|
||||||
persistent: isPersistent,
|
persistent: isPersistent,
|
||||||
requestedTxns: make(map[wire.ShaHash]struct{}),
|
requestedTxns: make(map[chainhash.Hash]struct{}),
|
||||||
requestedBlocks: make(map[wire.ShaHash]struct{}),
|
requestedBlocks: make(map[chainhash.Hash]struct{}),
|
||||||
filter: bloom.LoadFilter(nil),
|
filter: bloom.LoadFilter(nil),
|
||||||
knownAddresses: make(map[string]struct{}),
|
knownAddresses: make(map[string]struct{}),
|
||||||
quit: make(chan struct{}),
|
quit: make(chan struct{}),
|
||||||
|
@ -251,7 +252,7 @@ func newServerPeer(s *server, isPersistent bool) *serverPeer {
|
||||||
|
|
||||||
// newestBlock returns the current best block hash and height using the format
|
// newestBlock returns the current best block hash and height using the format
|
||||||
// required by the configuration for the peer package.
|
// required by the configuration for the peer package.
|
||||||
func (sp *serverPeer) newestBlock() (*wire.ShaHash, int32, error) {
|
func (sp *serverPeer) newestBlock() (*chainhash.Hash, int32, error) {
|
||||||
best := sp.server.blockManager.chain.BestSnapshot()
|
best := sp.server.blockManager.chain.BestSnapshot()
|
||||||
return best.Hash, best.Height, nil
|
return best.Hash, best.Height, nil
|
||||||
}
|
}
|
||||||
|
@ -427,7 +428,7 @@ func (sp *serverPeer) OnMemPool(p *peer.Peer, msg *wire.MsgMemPool) {
|
||||||
for i, txDesc := range txDescs {
|
for i, txDesc := range txDescs {
|
||||||
// Another thread might have removed the transaction from the
|
// Another thread might have removed the transaction from the
|
||||||
// pool since the initial query.
|
// pool since the initial query.
|
||||||
hash := txDesc.Tx.Sha()
|
hash := txDesc.Tx.Hash()
|
||||||
if !txMemPool.IsTransactionInPool(hash) {
|
if !txMemPool.IsTransactionInPool(hash) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -457,7 +458,7 @@ func (sp *serverPeer) OnMemPool(p *peer.Peer, msg *wire.MsgMemPool) {
|
||||||
func (sp *serverPeer) OnTx(p *peer.Peer, msg *wire.MsgTx) {
|
func (sp *serverPeer) OnTx(p *peer.Peer, msg *wire.MsgTx) {
|
||||||
if cfg.BlocksOnly {
|
if cfg.BlocksOnly {
|
||||||
peerLog.Tracef("Ignoring tx %v from %v - blocksonly enabled",
|
peerLog.Tracef("Ignoring tx %v from %v - blocksonly enabled",
|
||||||
msg.TxSha(), p)
|
msg.TxHash(), p)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -465,7 +466,7 @@ func (sp *serverPeer) OnTx(p *peer.Peer, msg *wire.MsgTx) {
|
||||||
// Convert the raw MsgTx to a btcutil.Tx which provides some convenience
|
// Convert the raw MsgTx to a btcutil.Tx which provides some convenience
|
||||||
// methods and things such as hash caching.
|
// methods and things such as hash caching.
|
||||||
tx := btcutil.NewTx(msg)
|
tx := btcutil.NewTx(msg)
|
||||||
iv := wire.NewInvVect(wire.InvTypeTx, tx.Sha())
|
iv := wire.NewInvVect(wire.InvTypeTx, tx.Hash())
|
||||||
p.AddKnownInventory(iv)
|
p.AddKnownInventory(iv)
|
||||||
|
|
||||||
// Queue the transaction up to be handled by the block manager and
|
// Queue the transaction up to be handled by the block manager and
|
||||||
|
@ -485,7 +486,7 @@ func (sp *serverPeer) OnBlock(p *peer.Peer, msg *wire.MsgBlock, buf []byte) {
|
||||||
block := btcutil.NewBlockFromBlockAndBytes(msg, buf)
|
block := btcutil.NewBlockFromBlockAndBytes(msg, buf)
|
||||||
|
|
||||||
// Add the block to the known inventory for the peer.
|
// Add the block to the known inventory for the peer.
|
||||||
iv := wire.NewInvVect(wire.InvTypeBlock, block.Sha())
|
iv := wire.NewInvVect(wire.InvTypeBlock, block.Hash())
|
||||||
p.AddKnownInventory(iv)
|
p.AddKnownInventory(iv)
|
||||||
|
|
||||||
// Queue the block up to be handled by the block
|
// Queue the block up to be handled by the block
|
||||||
|
@ -970,7 +971,7 @@ func (s *server) AnnounceNewTransactions(newTxs []*btcutil.Tx) {
|
||||||
// accepted.
|
// accepted.
|
||||||
for _, tx := range newTxs {
|
for _, tx := range newTxs {
|
||||||
// Generate the inventory vector and relay it.
|
// Generate the inventory vector and relay it.
|
||||||
iv := wire.NewInvVect(wire.InvTypeTx, tx.Sha())
|
iv := wire.NewInvVect(wire.InvTypeTx, tx.Hash())
|
||||||
s.RelayInventory(iv, tx)
|
s.RelayInventory(iv, tx)
|
||||||
|
|
||||||
if s.rpcServer != nil {
|
if s.rpcServer != nil {
|
||||||
|
@ -987,14 +988,14 @@ func (s *server) AnnounceNewTransactions(newTxs []*btcutil.Tx) {
|
||||||
|
|
||||||
// pushTxMsg sends a tx message for the provided transaction hash to the
|
// pushTxMsg sends a tx message for the provided transaction hash to the
|
||||||
// connected peer. An error is returned if the transaction hash is not known.
|
// connected peer. An error is returned if the transaction hash is not known.
|
||||||
func (s *server) pushTxMsg(sp *serverPeer, sha *wire.ShaHash, doneChan chan<- struct{}, waitChan <-chan struct{}) error {
|
func (s *server) pushTxMsg(sp *serverPeer, hash *chainhash.Hash, doneChan chan<- struct{}, waitChan <-chan struct{}) error {
|
||||||
// Attempt to fetch the requested transaction from the pool. A
|
// Attempt to fetch the requested transaction from the pool. A
|
||||||
// call could be made to check for existence first, but simply trying
|
// call could be made to check for existence first, but simply trying
|
||||||
// to fetch a missing transaction results in the same behavior.
|
// to fetch a missing transaction results in the same behavior.
|
||||||
tx, err := s.txMemPool.FetchTransaction(sha)
|
tx, err := s.txMemPool.FetchTransaction(hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
peerLog.Tracef("Unable to fetch tx %v from transaction "+
|
peerLog.Tracef("Unable to fetch tx %v from transaction "+
|
||||||
"pool: %v", sha, err)
|
"pool: %v", hash, err)
|
||||||
|
|
||||||
if doneChan != nil {
|
if doneChan != nil {
|
||||||
doneChan <- struct{}{}
|
doneChan <- struct{}{}
|
||||||
|
@ -1014,7 +1015,7 @@ func (s *server) pushTxMsg(sp *serverPeer, sha *wire.ShaHash, doneChan chan<- st
|
||||||
|
|
||||||
// pushBlockMsg sends a block message for the provided block hash to the
|
// pushBlockMsg sends a block message for the provided block hash to the
|
||||||
// connected peer. An error is returned if the block hash is not known.
|
// connected peer. An error is returned if the block hash is not known.
|
||||||
func (s *server) pushBlockMsg(sp *serverPeer, hash *wire.ShaHash, doneChan chan<- struct{}, waitChan <-chan struct{}) error {
|
func (s *server) pushBlockMsg(sp *serverPeer, hash *chainhash.Hash, doneChan chan<- struct{}, waitChan <-chan struct{}) error {
|
||||||
// Fetch the raw block bytes from the database.
|
// Fetch the raw block bytes from the database.
|
||||||
var blockBytes []byte
|
var blockBytes []byte
|
||||||
err := sp.server.db.View(func(dbTx database.Tx) error {
|
err := sp.server.db.View(func(dbTx database.Tx) error {
|
||||||
|
@ -1080,7 +1081,7 @@ func (s *server) pushBlockMsg(sp *serverPeer, hash *wire.ShaHash, doneChan chan<
|
||||||
// the connected peer. Since a merkle block requires the peer to have a filter
|
// the connected peer. Since a merkle block requires the peer to have a filter
|
||||||
// loaded, this call will simply be ignored if there is no filter loaded. An
|
// loaded, this call will simply be ignored if there is no filter loaded. An
|
||||||
// error is returned if the block hash is not known.
|
// error is returned if the block hash is not known.
|
||||||
func (s *server) pushMerkleBlockMsg(sp *serverPeer, hash *wire.ShaHash, doneChan chan<- struct{}, waitChan <-chan struct{}) error {
|
func (s *server) pushMerkleBlockMsg(sp *serverPeer, hash *chainhash.Hash, doneChan chan<- struct{}, waitChan <-chan struct{}) error {
|
||||||
// Do not send a response if the peer doesn't have a filter loaded.
|
// Do not send a response if the peer doesn't have a filter loaded.
|
||||||
if !sp.filter.IsLoaded() {
|
if !sp.filter.IsLoaded() {
|
||||||
if doneChan != nil {
|
if doneChan != nil {
|
||||||
|
@ -1145,17 +1146,17 @@ func (s *server) handleUpdatePeerHeights(state *peerState, umsg updatePeerHeight
|
||||||
|
|
||||||
// This is a pointer to the underlying memory which doesn't
|
// This is a pointer to the underlying memory which doesn't
|
||||||
// change.
|
// change.
|
||||||
latestBlkSha := sp.LastAnnouncedBlock()
|
latestBlkHash := sp.LastAnnouncedBlock()
|
||||||
|
|
||||||
// Skip this peer if it hasn't recently announced any new blocks.
|
// Skip this peer if it hasn't recently announced any new blocks.
|
||||||
if latestBlkSha == nil {
|
if latestBlkHash == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the peer has recently announced a block, and this block
|
// If the peer has recently announced a block, and this block
|
||||||
// matches our newly accepted block, then update their block
|
// matches our newly accepted block, then update their block
|
||||||
// height.
|
// height.
|
||||||
if *latestBlkSha == *umsg.newSha {
|
if *latestBlkHash == *umsg.newHash {
|
||||||
sp.UpdateLastBlockHeight(umsg.newHeight)
|
sp.UpdateLastBlockHeight(umsg.newHeight)
|
||||||
sp.UpdateLastAnnouncedBlock(nil)
|
sp.UpdateLastAnnouncedBlock(nil)
|
||||||
}
|
}
|
||||||
|
@ -2036,9 +2037,9 @@ func (s *server) NetTotals() (uint64, uint64) {
|
||||||
// the latest connected main chain block, or a recognized orphan. These height
|
// the latest connected main chain block, or a recognized orphan. These height
|
||||||
// updates allow us to dynamically refresh peer heights, ensuring sync peer
|
// updates allow us to dynamically refresh peer heights, ensuring sync peer
|
||||||
// selection has access to the latest block heights for each peer.
|
// selection has access to the latest block heights for each peer.
|
||||||
func (s *server) UpdatePeerHeights(latestBlkSha *wire.ShaHash, latestHeight int32, updateSource *serverPeer) {
|
func (s *server) UpdatePeerHeights(latestBlkHash *chainhash.Hash, latestHeight int32, updateSource *serverPeer) {
|
||||||
s.peerHeightsUpdate <- updatePeerHeightsMsg{
|
s.peerHeightsUpdate <- updatePeerHeightsMsg{
|
||||||
newSha: latestBlkSha,
|
newHash: latestBlkHash,
|
||||||
newHeight: latestHeight,
|
newHeight: latestHeight,
|
||||||
originPeer: updateSource,
|
originPeer: updateSource,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2013-2015 The btcsuite developers
|
// Copyright (c) 2013-2016 The btcsuite developers
|
||||||
// Use of this source code is governed by an ISC
|
// Use of this source code is governed by an ISC
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ package txscript_test
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/txscript"
|
"github.com/btcsuite/btcd/txscript"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
)
|
)
|
||||||
|
@ -35,7 +36,7 @@ func TestBadPC(t *testing.T) {
|
||||||
TxIn: []*wire.TxIn{
|
TxIn: []*wire.TxIn{
|
||||||
{
|
{
|
||||||
PreviousOutPoint: wire.OutPoint{
|
PreviousOutPoint: wire.OutPoint{
|
||||||
Hash: wire.ShaHash([32]byte{
|
Hash: chainhash.Hash([32]byte{
|
||||||
0xc9, 0x97, 0xa5, 0xe5,
|
0xc9, 0x97, 0xa5, 0xe5,
|
||||||
0x6e, 0x10, 0x41, 0x02,
|
0x6e, 0x10, 0x41, 0x02,
|
||||||
0xfa, 0x20, 0x9c, 0x6a,
|
0xfa, 0x20, 0x9c, 0x6a,
|
||||||
|
@ -95,7 +96,7 @@ func TestCheckErrorCondition(t *testing.T) {
|
||||||
TxIn: []*wire.TxIn{
|
TxIn: []*wire.TxIn{
|
||||||
{
|
{
|
||||||
PreviousOutPoint: wire.OutPoint{
|
PreviousOutPoint: wire.OutPoint{
|
||||||
Hash: wire.ShaHash([32]byte{
|
Hash: chainhash.Hash([32]byte{
|
||||||
0xc9, 0x97, 0xa5, 0xe5,
|
0xc9, 0x97, 0xa5, 0xe5,
|
||||||
0x6e, 0x10, 0x41, 0x02,
|
0x6e, 0x10, 0x41, 0x02,
|
||||||
0xfa, 0x20, 0x9c, 0x6a,
|
0xfa, 0x20, 0x9c, 0x6a,
|
||||||
|
@ -187,7 +188,7 @@ func TestInvalidFlagCombinations(t *testing.T) {
|
||||||
TxIn: []*wire.TxIn{
|
TxIn: []*wire.TxIn{
|
||||||
{
|
{
|
||||||
PreviousOutPoint: wire.OutPoint{
|
PreviousOutPoint: wire.OutPoint{
|
||||||
Hash: wire.ShaHash([32]byte{
|
Hash: chainhash.Hash([32]byte{
|
||||||
0xc9, 0x97, 0xa5, 0xe5,
|
0xc9, 0x97, 0xa5, 0xe5,
|
||||||
0x6e, 0x10, 0x41, 0x02,
|
0x6e, 0x10, 0x41, 0x02,
|
||||||
0xfa, 0x20, 0x9c, 0x6a,
|
0xfa, 0x20, 0x9c, 0x6a,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015 The btcsuite developers
|
// Copyright (c) 2014-2016 The btcsuite developers
|
||||||
// Use of this source code is governed by an ISC
|
// Use of this source code is governed by an ISC
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ import (
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/btcec"
|
"github.com/btcsuite/btcd/btcec"
|
||||||
"github.com/btcsuite/btcd/chaincfg"
|
"github.com/btcsuite/btcd/chaincfg"
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/txscript"
|
"github.com/btcsuite/btcd/txscript"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
"github.com/btcsuite/btcutil"
|
"github.com/btcsuite/btcutil"
|
||||||
|
@ -101,7 +102,7 @@ func ExampleSignTxOutput() {
|
||||||
// would ordinarily be the real transaction that is being spent. It
|
// would ordinarily be the real transaction that is being spent. It
|
||||||
// contains a single output that pays to address in the amount of 1 BTC.
|
// contains a single output that pays to address in the amount of 1 BTC.
|
||||||
originTx := wire.NewMsgTx()
|
originTx := wire.NewMsgTx()
|
||||||
prevOut := wire.NewOutPoint(&wire.ShaHash{}, ^uint32(0))
|
prevOut := wire.NewOutPoint(&chainhash.Hash{}, ^uint32(0))
|
||||||
txIn := wire.NewTxIn(prevOut, []byte{txscript.OP_0, txscript.OP_0})
|
txIn := wire.NewTxIn(prevOut, []byte{txscript.OP_0, txscript.OP_0})
|
||||||
originTx.AddTxIn(txIn)
|
originTx.AddTxIn(txIn)
|
||||||
pkScript, err := txscript.PayToAddrScript(addr)
|
pkScript, err := txscript.PayToAddrScript(addr)
|
||||||
|
@ -111,7 +112,7 @@ func ExampleSignTxOutput() {
|
||||||
}
|
}
|
||||||
txOut := wire.NewTxOut(100000000, pkScript)
|
txOut := wire.NewTxOut(100000000, pkScript)
|
||||||
originTx.AddTxOut(txOut)
|
originTx.AddTxOut(txOut)
|
||||||
originTxHash := originTx.TxSha()
|
originTxHash := originTx.TxHash()
|
||||||
|
|
||||||
// Create the transaction to redeem the fake transaction.
|
// Create the transaction to redeem the fake transaction.
|
||||||
redeemTx := wire.NewMsgTx()
|
redeemTx := wire.NewMsgTx()
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2013-2015 The btcsuite developers
|
// Copyright (c) 2013-2016 The btcsuite developers
|
||||||
// Use of this source code is governed by an ISC
|
// Use of this source code is governed by an ISC
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ import (
|
||||||
"hash"
|
"hash"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/btcec"
|
"github.com/btcsuite/btcd/btcec"
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
"github.com/btcsuite/fastsha256"
|
"github.com/btcsuite/fastsha256"
|
||||||
"github.com/btcsuite/golangcrypto/ripemd160"
|
"github.com/btcsuite/golangcrypto/ripemd160"
|
||||||
|
@ -1833,7 +1834,7 @@ func opcodeHash256(op *parsedOpcode, vm *Engine) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
vm.dstack.PushByteArray(wire.DoubleSha256(buf))
|
vm.dstack.PushByteArray(chainhash.DoubleHashB(buf))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1934,7 +1935,7 @@ func opcodeCheckSig(op *parsedOpcode, vm *Engine) error {
|
||||||
|
|
||||||
var valid bool
|
var valid bool
|
||||||
if vm.sigCache != nil {
|
if vm.sigCache != nil {
|
||||||
var sigHash wire.ShaHash
|
var sigHash chainhash.Hash
|
||||||
copy(sigHash[:], hash)
|
copy(sigHash[:], hash)
|
||||||
|
|
||||||
valid = vm.sigCache.Exists(sigHash, signature, pubKey)
|
valid = vm.sigCache.Exists(sigHash, signature, pubKey)
|
||||||
|
@ -2148,7 +2149,7 @@ func opcodeCheckMultiSig(op *parsedOpcode, vm *Engine) error {
|
||||||
|
|
||||||
var valid bool
|
var valid bool
|
||||||
if vm.sigCache != nil {
|
if vm.sigCache != nil {
|
||||||
var sigHash wire.ShaHash
|
var sigHash chainhash.Hash
|
||||||
copy(sigHash[:], hash)
|
copy(sigHash[:], hash)
|
||||||
|
|
||||||
valid = vm.sigCache.Exists(sigHash, parsedSig, parsedPubKey)
|
valid = vm.sigCache.Exists(sigHash, parsedSig, parsedPubKey)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2013-2015 The btcsuite developers
|
// Copyright (c) 2013-2016 The btcsuite developers
|
||||||
// Use of this source code is governed by an ISC
|
// Use of this source code is governed by an ISC
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
. "github.com/btcsuite/btcd/txscript"
|
. "github.com/btcsuite/btcd/txscript"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
"github.com/btcsuite/btcutil"
|
"github.com/btcsuite/btcutil"
|
||||||
|
@ -159,15 +160,15 @@ func parseScriptFlags(flagStr string) (ScriptFlags, error) {
|
||||||
func createSpendingTx(sigScript, pkScript []byte) *wire.MsgTx {
|
func createSpendingTx(sigScript, pkScript []byte) *wire.MsgTx {
|
||||||
coinbaseTx := wire.NewMsgTx()
|
coinbaseTx := wire.NewMsgTx()
|
||||||
|
|
||||||
outPoint := wire.NewOutPoint(&wire.ShaHash{}, ^uint32(0))
|
outPoint := wire.NewOutPoint(&chainhash.Hash{}, ^uint32(0))
|
||||||
txIn := wire.NewTxIn(outPoint, []byte{OP_0, OP_0})
|
txIn := wire.NewTxIn(outPoint, []byte{OP_0, OP_0})
|
||||||
txOut := wire.NewTxOut(0, pkScript)
|
txOut := wire.NewTxOut(0, pkScript)
|
||||||
coinbaseTx.AddTxIn(txIn)
|
coinbaseTx.AddTxIn(txIn)
|
||||||
coinbaseTx.AddTxOut(txOut)
|
coinbaseTx.AddTxOut(txOut)
|
||||||
|
|
||||||
spendingTx := wire.NewMsgTx()
|
spendingTx := wire.NewMsgTx()
|
||||||
coinbaseTxSha := coinbaseTx.TxSha()
|
coinbaseTxHash := coinbaseTx.TxHash()
|
||||||
outPoint = wire.NewOutPoint(&coinbaseTxSha, 0)
|
outPoint = wire.NewOutPoint(&coinbaseTxHash, 0)
|
||||||
txIn = wire.NewTxIn(outPoint, sigScript)
|
txIn = wire.NewTxIn(outPoint, sigScript)
|
||||||
txOut = wire.NewTxOut(0, nil)
|
txOut = wire.NewTxOut(0, nil)
|
||||||
|
|
||||||
|
@ -405,14 +406,14 @@ testloop:
|
||||||
|
|
||||||
previoustx, ok := input[0].(string)
|
previoustx, ok := input[0].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
t.Errorf("bad test (%dth input sha not string)"+
|
t.Errorf("bad test (%dth input hash not string)"+
|
||||||
"%d: %v", j, i, test)
|
"%d: %v", j, i, test)
|
||||||
continue testloop
|
continue testloop
|
||||||
}
|
}
|
||||||
|
|
||||||
prevhash, err := wire.NewShaHashFromStr(previoustx)
|
prevhash, err := chainhash.NewHashFromStr(previoustx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("bad test (%dth input sha not sha %v)"+
|
t.Errorf("bad test (%dth input hash not hash %v)"+
|
||||||
"%d: %v", j, err, i, test)
|
"%d: %v", j, err, i, test)
|
||||||
continue testloop
|
continue testloop
|
||||||
}
|
}
|
||||||
|
@ -547,14 +548,14 @@ testloop:
|
||||||
|
|
||||||
previoustx, ok := input[0].(string)
|
previoustx, ok := input[0].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
t.Errorf("bad test (%dth input sha not string)"+
|
t.Errorf("bad test (%dth input hash not string)"+
|
||||||
"%d: %v", j, i, test)
|
"%d: %v", j, i, test)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
prevhash, err := wire.NewShaHashFromStr(previoustx)
|
prevhash, err := chainhash.NewHashFromStr(previoustx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("bad test (%dth input sha not sha %v)"+
|
t.Errorf("bad test (%dth input hash not hash %v)"+
|
||||||
"%d: %v", j, err, i, test)
|
"%d: %v", j, err, i, test)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -656,8 +657,8 @@ func TestCalcSignatureHash(t *testing.T) {
|
||||||
hash := TstCalcSignatureHash(parsedScript, hashType, tx,
|
hash := TstCalcSignatureHash(parsedScript, hashType, tx,
|
||||||
int(test[2].(float64)))
|
int(test[2].(float64)))
|
||||||
|
|
||||||
expectedHash, _ := wire.NewShaHashFromStr(test[4].(string))
|
expectedHash, _ := chainhash.NewHashFromStr(test[4].(string))
|
||||||
if !bytes.Equal(hash, expectedHash.Bytes()) {
|
if !bytes.Equal(hash, expectedHash[:]) {
|
||||||
t.Errorf("TestCalcSignatureHash failed test #%d: "+
|
t.Errorf("TestCalcSignatureHash failed test #%d: "+
|
||||||
"Signature hash mismatch.", i)
|
"Signature hash mismatch.", i)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2013-2015 The btcsuite developers
|
// Copyright (c) 2013-2016 The btcsuite developers
|
||||||
// Use of this source code is governed by an ISC
|
// Use of this source code is governed by an ISC
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -289,7 +290,7 @@ func calcSignatureHash(script []parsedOpcode, hashType SigHashType, tx *wire.Msg
|
||||||
// cleverly construct transactions which can steal those coins provided
|
// cleverly construct transactions which can steal those coins provided
|
||||||
// they can reuse signatures.
|
// they can reuse signatures.
|
||||||
if hashType&sigHashMask == SigHashSingle && idx >= len(tx.TxOut) {
|
if hashType&sigHashMask == SigHashSingle && idx >= len(tx.TxOut) {
|
||||||
var hash wire.ShaHash
|
var hash chainhash.Hash
|
||||||
hash[0] = 0x01
|
hash[0] = 0x01
|
||||||
return hash[:]
|
return hash[:]
|
||||||
}
|
}
|
||||||
|
@ -357,7 +358,7 @@ func calcSignatureHash(script []parsedOpcode, hashType SigHashType, tx *wire.Msg
|
||||||
var wbuf bytes.Buffer
|
var wbuf bytes.Buffer
|
||||||
txCopy.Serialize(&wbuf)
|
txCopy.Serialize(&wbuf)
|
||||||
binary.Write(&wbuf, binary.LittleEndian, hashType)
|
binary.Write(&wbuf, binary.LittleEndian, hashType)
|
||||||
return wire.DoubleSha256(wbuf.Bytes())
|
return chainhash.DoubleHashB(wbuf.Bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
// asSmallInt returns the passed opcode, which must be true according to
|
// asSmallInt returns the passed opcode, which must be true according to
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/btcec"
|
"github.com/btcsuite/btcd/btcec"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
)
|
)
|
||||||
|
|
||||||
// sigCacheEntry represents an entry in the SigCache. Entries within the
|
// sigCacheEntry represents an entry in the SigCache. Entries within the
|
||||||
|
@ -34,7 +34,7 @@ type sigCacheEntry struct {
|
||||||
// if they've already been seen and verified within the mempool.
|
// if they've already been seen and verified within the mempool.
|
||||||
type SigCache struct {
|
type SigCache struct {
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
validSigs map[wire.ShaHash]sigCacheEntry
|
validSigs map[chainhash.Hash]sigCacheEntry
|
||||||
maxEntries uint
|
maxEntries uint
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ type SigCache struct {
|
||||||
// cache to exceed the max.
|
// cache to exceed the max.
|
||||||
func NewSigCache(maxEntries uint) *SigCache {
|
func NewSigCache(maxEntries uint) *SigCache {
|
||||||
return &SigCache{
|
return &SigCache{
|
||||||
validSigs: make(map[wire.ShaHash]sigCacheEntry, maxEntries),
|
validSigs: make(map[chainhash.Hash]sigCacheEntry, maxEntries),
|
||||||
maxEntries: maxEntries,
|
maxEntries: maxEntries,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ func NewSigCache(maxEntries uint) *SigCache {
|
||||||
//
|
//
|
||||||
// NOTE: This function is safe for concurrent access. Readers won't be blocked
|
// NOTE: This function is safe for concurrent access. Readers won't be blocked
|
||||||
// unless there exists a writer, adding an entry to the SigCache.
|
// unless there exists a writer, adding an entry to the SigCache.
|
||||||
func (s *SigCache) Exists(sigHash wire.ShaHash, sig *btcec.Signature, pubKey *btcec.PublicKey) bool {
|
func (s *SigCache) Exists(sigHash chainhash.Hash, sig *btcec.Signature, pubKey *btcec.PublicKey) bool {
|
||||||
s.RLock()
|
s.RLock()
|
||||||
defer s.RUnlock()
|
defer s.RUnlock()
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ func (s *SigCache) Exists(sigHash wire.ShaHash, sig *btcec.Signature, pubKey *bt
|
||||||
//
|
//
|
||||||
// NOTE: This function is safe for concurrent access. Writers will block
|
// NOTE: This function is safe for concurrent access. Writers will block
|
||||||
// simultaneous readers until function execution has concluded.
|
// simultaneous readers until function execution has concluded.
|
||||||
func (s *SigCache) Add(sigHash wire.ShaHash, sig *btcec.Signature, pubKey *btcec.PublicKey) {
|
func (s *SigCache) Add(sigHash chainhash.Hash, sig *btcec.Signature, pubKey *btcec.PublicKey) {
|
||||||
s.Lock()
|
s.Lock()
|
||||||
defer s.Unlock()
|
defer s.Unlock()
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2015 The btcsuite developers
|
// Copyright (c) 2015-2016 The btcsuite developers
|
||||||
// Use of this source code is governed by an ISC
|
// Use of this source code is governed by an ISC
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -9,19 +9,19 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/btcec"
|
"github.com/btcsuite/btcd/btcec"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
)
|
)
|
||||||
|
|
||||||
// genRandomSig returns a random message, a signature of the message under the
|
// genRandomSig returns a random message, a signature of the message under the
|
||||||
// public key and the public key. This function is used to generate randomized
|
// public key and the public key. This function is used to generate randomized
|
||||||
// test data.
|
// test data.
|
||||||
func genRandomSig() (*wire.ShaHash, *btcec.Signature, *btcec.PublicKey, error) {
|
func genRandomSig() (*chainhash.Hash, *btcec.Signature, *btcec.PublicKey, error) {
|
||||||
privKey, err := btcec.NewPrivateKey(btcec.S256())
|
privKey, err := btcec.NewPrivateKey(btcec.S256())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var msgHash wire.ShaHash
|
var msgHash chainhash.Hash
|
||||||
if _, err := rand.Read(msgHash[:]); err != nil {
|
if _, err := rand.Read(msgHash[:]); err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2013-2015 The btcsuite developers
|
// Copyright (c) 2013-2016 The btcsuite developers
|
||||||
// Use of this source code is governed by an ISC
|
// Use of this source code is governed by an ISC
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ import (
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/btcec"
|
"github.com/btcsuite/btcd/btcec"
|
||||||
"github.com/btcsuite/btcd/chaincfg"
|
"github.com/btcsuite/btcd/chaincfg"
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/txscript"
|
"github.com/btcsuite/btcd/txscript"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
"github.com/btcsuite/btcutil"
|
"github.com/btcsuite/btcutil"
|
||||||
|
@ -106,21 +107,21 @@ func TestSignTxOutput(t *testing.T) {
|
||||||
TxIn: []*wire.TxIn{
|
TxIn: []*wire.TxIn{
|
||||||
{
|
{
|
||||||
PreviousOutPoint: wire.OutPoint{
|
PreviousOutPoint: wire.OutPoint{
|
||||||
Hash: wire.ShaHash{},
|
Hash: chainhash.Hash{},
|
||||||
Index: 0,
|
Index: 0,
|
||||||
},
|
},
|
||||||
Sequence: 4294967295,
|
Sequence: 4294967295,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
PreviousOutPoint: wire.OutPoint{
|
PreviousOutPoint: wire.OutPoint{
|
||||||
Hash: wire.ShaHash{},
|
Hash: chainhash.Hash{},
|
||||||
Index: 1,
|
Index: 1,
|
||||||
},
|
},
|
||||||
Sequence: 4294967295,
|
Sequence: 4294967295,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
PreviousOutPoint: wire.OutPoint{
|
PreviousOutPoint: wire.OutPoint{
|
||||||
Hash: wire.ShaHash{},
|
Hash: chainhash.Hash{},
|
||||||
Index: 2,
|
Index: 2,
|
||||||
},
|
},
|
||||||
Sequence: 4294967295,
|
Sequence: 4294967295,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2013-2015 The btcsuite developers
|
// Copyright (c) 2013-2016 The btcsuite developers
|
||||||
// Use of this source code is governed by an ISC
|
// Use of this source code is governed by an ISC
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -12,6 +12,8 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
)
|
)
|
||||||
|
|
||||||
// genesisCoinbaseTx is the coinbase transaction for the genesis blocks for
|
// genesisCoinbaseTx is the coinbase transaction for the genesis blocks for
|
||||||
|
@ -21,7 +23,7 @@ var genesisCoinbaseTx = MsgTx{
|
||||||
TxIn: []*TxIn{
|
TxIn: []*TxIn{
|
||||||
{
|
{
|
||||||
PreviousOutPoint: OutPoint{
|
PreviousOutPoint: OutPoint{
|
||||||
Hash: ShaHash{},
|
Hash: chainhash.Hash{},
|
||||||
Index: 0xffffffff,
|
Index: 0xffffffff,
|
||||||
},
|
},
|
||||||
SignatureScript: []byte{
|
SignatureScript: []byte{
|
||||||
|
@ -194,7 +196,7 @@ func BenchmarkReadOutPoint(b *testing.B) {
|
||||||
// transaction output point.
|
// transaction output point.
|
||||||
func BenchmarkWriteOutPoint(b *testing.B) {
|
func BenchmarkWriteOutPoint(b *testing.B) {
|
||||||
op := &OutPoint{
|
op := &OutPoint{
|
||||||
Hash: ShaHash{},
|
Hash: chainhash.Hash{},
|
||||||
Index: 0,
|
Index: 0,
|
||||||
}
|
}
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
|
@ -383,9 +385,9 @@ func BenchmarkDecodeGetHeaders(b *testing.B) {
|
||||||
pver := ProtocolVersion
|
pver := ProtocolVersion
|
||||||
var m MsgGetHeaders
|
var m MsgGetHeaders
|
||||||
for i := 0; i < MaxBlockLocatorsPerMsg; i++ {
|
for i := 0; i < MaxBlockLocatorsPerMsg; i++ {
|
||||||
hash, err := NewShaHashFromStr(fmt.Sprintf("%x", i))
|
hash, err := chainhash.NewHashFromStr(fmt.Sprintf("%x", i))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.Fatalf("NewShaHashFromStr: unexpected error: %v", err)
|
b.Fatalf("NewHashFromStr: unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
m.AddBlockLocatorHash(hash)
|
m.AddBlockLocatorHash(hash)
|
||||||
}
|
}
|
||||||
|
@ -413,9 +415,9 @@ func BenchmarkDecodeHeaders(b *testing.B) {
|
||||||
pver := ProtocolVersion
|
pver := ProtocolVersion
|
||||||
var m MsgHeaders
|
var m MsgHeaders
|
||||||
for i := 0; i < MaxBlockHeadersPerMsg; i++ {
|
for i := 0; i < MaxBlockHeadersPerMsg; i++ {
|
||||||
hash, err := NewShaHashFromStr(fmt.Sprintf("%x", i))
|
hash, err := chainhash.NewHashFromStr(fmt.Sprintf("%x", i))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.Fatalf("NewShaHashFromStr: unexpected error: %v", err)
|
b.Fatalf("NewHashFromStr: unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
m.AddBlockHeader(NewBlockHeader(hash, hash, 0, uint32(i)))
|
m.AddBlockHeader(NewBlockHeader(hash, hash, 0, uint32(i)))
|
||||||
}
|
}
|
||||||
|
@ -443,9 +445,9 @@ func BenchmarkDecodeGetBlocks(b *testing.B) {
|
||||||
pver := ProtocolVersion
|
pver := ProtocolVersion
|
||||||
var m MsgGetBlocks
|
var m MsgGetBlocks
|
||||||
for i := 0; i < MaxBlockLocatorsPerMsg; i++ {
|
for i := 0; i < MaxBlockLocatorsPerMsg; i++ {
|
||||||
hash, err := NewShaHashFromStr(fmt.Sprintf("%x", i))
|
hash, err := chainhash.NewHashFromStr(fmt.Sprintf("%x", i))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.Fatalf("NewShaHashFromStr: unexpected error: %v", err)
|
b.Fatalf("NewHashFromStr: unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
m.AddBlockLocatorHash(hash)
|
m.AddBlockLocatorHash(hash)
|
||||||
}
|
}
|
||||||
|
@ -500,9 +502,9 @@ func BenchmarkDecodeInv(b *testing.B) {
|
||||||
pver := ProtocolVersion
|
pver := ProtocolVersion
|
||||||
var m MsgInv
|
var m MsgInv
|
||||||
for i := 0; i < MaxInvPerMsg; i++ {
|
for i := 0; i < MaxInvPerMsg; i++ {
|
||||||
hash, err := NewShaHashFromStr(fmt.Sprintf("%x", i))
|
hash, err := chainhash.NewHashFromStr(fmt.Sprintf("%x", i))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.Fatalf("NewShaHashFromStr: unexpected error: %v", err)
|
b.Fatalf("NewHashFromStr: unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
m.AddInvVect(NewInvVect(InvTypeBlock, hash))
|
m.AddInvVect(NewInvVect(InvTypeBlock, hash))
|
||||||
}
|
}
|
||||||
|
@ -530,9 +532,9 @@ func BenchmarkDecodeNotFound(b *testing.B) {
|
||||||
pver := ProtocolVersion
|
pver := ProtocolVersion
|
||||||
var m MsgNotFound
|
var m MsgNotFound
|
||||||
for i := 0; i < MaxInvPerMsg; i++ {
|
for i := 0; i < MaxInvPerMsg; i++ {
|
||||||
hash, err := NewShaHashFromStr(fmt.Sprintf("%x", i))
|
hash, err := chainhash.NewHashFromStr(fmt.Sprintf("%x", i))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.Fatalf("NewShaHashFromStr: unexpected error: %v", err)
|
b.Fatalf("NewHashFromStr: unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
m.AddInvVect(NewInvVect(InvTypeBlock, hash))
|
m.AddInvVect(NewInvVect(InvTypeBlock, hash))
|
||||||
}
|
}
|
||||||
|
@ -559,15 +561,15 @@ func BenchmarkDecodeMerkleBlock(b *testing.B) {
|
||||||
// Create a message with random data.
|
// Create a message with random data.
|
||||||
pver := ProtocolVersion
|
pver := ProtocolVersion
|
||||||
var m MsgMerkleBlock
|
var m MsgMerkleBlock
|
||||||
hash, err := NewShaHashFromStr(fmt.Sprintf("%x", 10000))
|
hash, err := chainhash.NewHashFromStr(fmt.Sprintf("%x", 10000))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.Fatalf("NewShaHashFromStr: unexpected error: %v", err)
|
b.Fatalf("NewHashFromStr: unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
m.Header = *NewBlockHeader(hash, hash, 0, uint32(10000))
|
m.Header = *NewBlockHeader(hash, hash, 0, uint32(10000))
|
||||||
for i := 0; i < 105; i++ {
|
for i := 0; i < 105; i++ {
|
||||||
hash, err := NewShaHashFromStr(fmt.Sprintf("%x", i))
|
hash, err := chainhash.NewHashFromStr(fmt.Sprintf("%x", i))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.Fatalf("NewShaHashFromStr: unexpected error: %v", err)
|
b.Fatalf("NewHashFromStr: unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
m.AddTxHash(hash)
|
m.AddTxHash(hash)
|
||||||
if i%8 == 0 {
|
if i%8 == 0 {
|
||||||
|
@ -591,17 +593,17 @@ func BenchmarkDecodeMerkleBlock(b *testing.B) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// BenchmarkTxSha performs a benchmark on how long it takes to hash a
|
// BenchmarkTxHash performs a benchmark on how long it takes to hash a
|
||||||
// transaction.
|
// transaction.
|
||||||
func BenchmarkTxSha(b *testing.B) {
|
func BenchmarkTxHash(b *testing.B) {
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
genesisCoinbaseTx.TxSha()
|
genesisCoinbaseTx.TxHash()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// BenchmarkDoubleSha256 performs a benchmark on how long it takes to perform a
|
// BenchmarkDoubleHashB performs a benchmark on how long it takes to perform a
|
||||||
// double sha 256 returning a byte slice.
|
// double hash returning a byte slice.
|
||||||
func BenchmarkDoubleSha256(b *testing.B) {
|
func BenchmarkDoubleHashB(b *testing.B) {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
if err := genesisCoinbaseTx.Serialize(&buf); err != nil {
|
if err := genesisCoinbaseTx.Serialize(&buf); err != nil {
|
||||||
b.Errorf("Serialize: unexpected error: %v", err)
|
b.Errorf("Serialize: unexpected error: %v", err)
|
||||||
|
@ -611,13 +613,13 @@ func BenchmarkDoubleSha256(b *testing.B) {
|
||||||
|
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
_ = DoubleSha256(txBytes)
|
_ = chainhash.DoubleHashB(txBytes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// BenchmarkDoubleSha256SH performs a benchmark on how long it takes to perform
|
// BenchmarkDoubleHashH performs a benchmark on how long it takes to perform
|
||||||
// a double sha 256 returning a ShaHash.
|
// a double hash returning a chainhash.Hash.
|
||||||
func BenchmarkDoubleSha256SH(b *testing.B) {
|
func BenchmarkDoubleHashH(b *testing.B) {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
if err := genesisCoinbaseTx.Serialize(&buf); err != nil {
|
if err := genesisCoinbaseTx.Serialize(&buf); err != nil {
|
||||||
b.Errorf("Serialize: unexpected error: %v", err)
|
b.Errorf("Serialize: unexpected error: %v", err)
|
||||||
|
@ -627,6 +629,6 @@ func BenchmarkDoubleSha256SH(b *testing.B) {
|
||||||
|
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
_ = DoubleSha256SH(txBytes)
|
_ = chainhash.DoubleHashH(txBytes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2013-2015 The btcsuite developers
|
// Copyright (c) 2013-2016 The btcsuite developers
|
||||||
// Use of this source code is governed by an ISC
|
// Use of this source code is governed by an ISC
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -8,6 +8,8 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"io"
|
"io"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
)
|
)
|
||||||
|
|
||||||
// BlockVersion is the current latest supported block version.
|
// BlockVersion is the current latest supported block version.
|
||||||
|
@ -16,7 +18,7 @@ const BlockVersion = 4
|
||||||
// MaxBlockHeaderPayload is the maximum number of bytes a block header can be.
|
// MaxBlockHeaderPayload is the maximum number of bytes a block header can be.
|
||||||
// Version 4 bytes + Timestamp 4 bytes + Bits 4 bytes + Nonce 4 bytes +
|
// Version 4 bytes + Timestamp 4 bytes + Bits 4 bytes + Nonce 4 bytes +
|
||||||
// PrevBlock and MerkleRoot hashes.
|
// PrevBlock and MerkleRoot hashes.
|
||||||
const MaxBlockHeaderPayload = 16 + (HashSize * 2)
|
const MaxBlockHeaderPayload = 16 + (chainhash.HashSize * 2)
|
||||||
|
|
||||||
// BlockHeader defines information about a block and is used in the bitcoin
|
// BlockHeader defines information about a block and is used in the bitcoin
|
||||||
// block (MsgBlock) and headers (MsgHeaders) messages.
|
// block (MsgBlock) and headers (MsgHeaders) messages.
|
||||||
|
@ -25,10 +27,10 @@ type BlockHeader struct {
|
||||||
Version int32
|
Version int32
|
||||||
|
|
||||||
// Hash of the previous block in the block chain.
|
// Hash of the previous block in the block chain.
|
||||||
PrevBlock ShaHash
|
PrevBlock chainhash.Hash
|
||||||
|
|
||||||
// Merkle tree reference to hash of all transactions for the block.
|
// Merkle tree reference to hash of all transactions for the block.
|
||||||
MerkleRoot ShaHash
|
MerkleRoot chainhash.Hash
|
||||||
|
|
||||||
// Time the block was created. This is, unfortunately, encoded as a
|
// Time the block was created. This is, unfortunately, encoded as a
|
||||||
// uint32 on the wire and therefore is limited to 2106.
|
// uint32 on the wire and therefore is limited to 2106.
|
||||||
|
@ -45,8 +47,8 @@ type BlockHeader struct {
|
||||||
// header.
|
// header.
|
||||||
const blockHeaderLen = 80
|
const blockHeaderLen = 80
|
||||||
|
|
||||||
// BlockSha computes the block identifier hash for the given block header.
|
// BlockHash computes the block identifier hash for the given block header.
|
||||||
func (h *BlockHeader) BlockSha() ShaHash {
|
func (h *BlockHeader) BlockHash() chainhash.Hash {
|
||||||
// Encode the header and double sha256 everything prior to the number of
|
// Encode the header and double sha256 everything prior to the number of
|
||||||
// transactions. Ignore the error returns since there is no way the
|
// transactions. Ignore the error returns since there is no way the
|
||||||
// encode could fail except being out of memory which would cause a
|
// encode could fail except being out of memory which would cause a
|
||||||
|
@ -54,7 +56,7 @@ func (h *BlockHeader) BlockSha() ShaHash {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
_ = writeBlockHeader(&buf, 0, h)
|
_ = writeBlockHeader(&buf, 0, h)
|
||||||
|
|
||||||
return DoubleSha256SH(buf.Bytes())
|
return chainhash.DoubleHashH(buf.Bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
|
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
|
||||||
|
@ -96,8 +98,8 @@ func (h *BlockHeader) Serialize(w io.Writer) error {
|
||||||
// NewBlockHeader returns a new BlockHeader using the provided previous block
|
// NewBlockHeader returns a new BlockHeader using the provided previous block
|
||||||
// hash, merkle root hash, difficulty bits, and nonce used to generate the
|
// hash, merkle root hash, difficulty bits, and nonce used to generate the
|
||||||
// block with defaults for the remaining fields.
|
// block with defaults for the remaining fields.
|
||||||
func NewBlockHeader(prevHash *ShaHash, merkleRootHash *ShaHash, bits uint32,
|
func NewBlockHeader(prevHash *chainhash.Hash, merkleRootHash *chainhash.Hash,
|
||||||
nonce uint32) *BlockHeader {
|
bits uint32, nonce uint32) *BlockHeader {
|
||||||
|
|
||||||
// Limit the timestamp to one second precision since the protocol
|
// Limit the timestamp to one second precision since the protocol
|
||||||
// doesn't support better.
|
// doesn't support better.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2013-2015 The btcsuite developers
|
// Copyright (c) 2013-2016 The btcsuite developers
|
||||||
// Use of this source code is governed by an ISC
|
// Use of this source code is governed by an ISC
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ import (
|
||||||
"math"
|
"math"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/btcsuite/fastsha256"
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -278,7 +278,7 @@ func readElement(r io.Reader, element interface{}) error {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
case *ShaHash:
|
case *chainhash.Hash:
|
||||||
_, err := io.ReadFull(r, e[:])
|
_, err := io.ReadFull(r, e[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -412,7 +412,7 @@ func writeElement(w io.Writer, element interface{}) error {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
case *ShaHash:
|
case *chainhash.Hash:
|
||||||
_, err := w.Write(e[:])
|
_, err := w.Write(e[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -693,17 +693,3 @@ func randomUint64(r io.Reader) (uint64, error) {
|
||||||
func RandomUint64() (uint64, error) {
|
func RandomUint64() (uint64, error) {
|
||||||
return randomUint64(rand.Reader)
|
return randomUint64(rand.Reader)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DoubleSha256 calculates sha256(sha256(b)) and returns the resulting bytes.
|
|
||||||
func DoubleSha256(b []byte) []byte {
|
|
||||||
first := fastsha256.Sum256(b)
|
|
||||||
second := fastsha256.Sum256(first[:])
|
|
||||||
return second[:]
|
|
||||||
}
|
|
||||||
|
|
||||||
// DoubleSha256SH calculates sha256(sha256(b)) and returns the resulting bytes
|
|
||||||
// as a ShaHash.
|
|
||||||
func DoubleSha256SH(b []byte) ShaHash {
|
|
||||||
first := fastsha256.Sum256(b)
|
|
||||||
return ShaHash(fastsha256.Sum256(first[:]))
|
|
||||||
}
|
|
||||||
|
|
|
@ -12,12 +12,13 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/davecgh/go-spew/spew"
|
"github.com/davecgh/go-spew/spew"
|
||||||
)
|
)
|
||||||
|
|
||||||
// mainNetGenesisHash is the hash of the first block in the block chain for the
|
// mainNetGenesisHash is the hash of the first block in the block chain for the
|
||||||
// main network (genesis block).
|
// main network (genesis block).
|
||||||
var mainNetGenesisHash = ShaHash([HashSize]byte{ // Make go vet happy.
|
var mainNetGenesisHash = chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy.
|
||||||
0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72,
|
0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72,
|
||||||
0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f,
|
0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f,
|
||||||
0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c,
|
0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c,
|
||||||
|
@ -26,7 +27,7 @@ var mainNetGenesisHash = ShaHash([HashSize]byte{ // Make go vet happy.
|
||||||
|
|
||||||
// mainNetGenesisMerkleRoot is the hash of the first transaction in the genesis
|
// mainNetGenesisMerkleRoot is the hash of the first transaction in the genesis
|
||||||
// block for the main network.
|
// block for the main network.
|
||||||
var mainNetGenesisMerkleRoot = ShaHash([HashSize]byte{ // Make go vet happy.
|
var mainNetGenesisMerkleRoot = chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy.
|
||||||
0x3b, 0xa3, 0xed, 0xfd, 0x7a, 0x7b, 0x12, 0xb2,
|
0x3b, 0xa3, 0xed, 0xfd, 0x7a, 0x7b, 0x12, 0xb2,
|
||||||
0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f, 0x61,
|
0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f, 0x61,
|
||||||
0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32,
|
0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32,
|
||||||
|
@ -103,7 +104,7 @@ func TestElementWire(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
(*ShaHash)(&[HashSize]byte{ // Make go vet happy.
|
(*chainhash.Hash)(&[chainhash.HashSize]byte{ // Make go vet happy.
|
||||||
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
|
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
|
||||||
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
|
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
|
||||||
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
|
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
|
||||||
|
@ -202,7 +203,7 @@ func TestElementWireErrors(t *testing.T) {
|
||||||
0, io.ErrShortWrite, io.EOF,
|
0, io.ErrShortWrite, io.EOF,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
(*ShaHash)(&[HashSize]byte{ // Make go vet happy.
|
(*chainhash.Hash)(&[chainhash.HashSize]byte{ // Make go vet happy.
|
||||||
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
|
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
|
||||||
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
|
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
|
||||||
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
|
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2013-2015 The btcsuite developers
|
// Copyright (c) 2013-2016 The btcsuite developers
|
||||||
// Use of this source code is governed by an ISC
|
// Use of this source code is governed by an ISC
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -7,6 +7,8 @@ package wire
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -15,7 +17,7 @@ const (
|
||||||
MaxInvPerMsg = 50000
|
MaxInvPerMsg = 50000
|
||||||
|
|
||||||
// Maximum payload size for an inventory vector.
|
// Maximum payload size for an inventory vector.
|
||||||
maxInvVectPayload = 4 + HashSize
|
maxInvVectPayload = 4 + chainhash.HashSize
|
||||||
)
|
)
|
||||||
|
|
||||||
// InvType represents the allowed types of inventory vectors. See InvVect.
|
// InvType represents the allowed types of inventory vectors. See InvVect.
|
||||||
|
@ -50,12 +52,12 @@ func (invtype InvType) String() string {
|
||||||
// as specified by the Type field, that a peer wants, has, or does not have to
|
// as specified by the Type field, that a peer wants, has, or does not have to
|
||||||
// another peer.
|
// another peer.
|
||||||
type InvVect struct {
|
type InvVect struct {
|
||||||
Type InvType // Type of data
|
Type InvType // Type of data
|
||||||
Hash ShaHash // Hash of the data
|
Hash chainhash.Hash // Hash of the data
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewInvVect returns a new InvVect using the provided type and hash.
|
// NewInvVect returns a new InvVect using the provided type and hash.
|
||||||
func NewInvVect(typ InvType, hash *ShaHash) *InvVect {
|
func NewInvVect(typ InvType, hash *chainhash.Hash) *InvVect {
|
||||||
return &InvVect{
|
return &InvVect{
|
||||||
Type: typ,
|
Type: typ,
|
||||||
Hash: *hash,
|
Hash: *hash,
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/davecgh/go-spew/spew"
|
"github.com/davecgh/go-spew/spew"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -39,7 +40,7 @@ func TestInvTypeStringer(t *testing.T) {
|
||||||
// TestInvVect tests the InvVect API.
|
// TestInvVect tests the InvVect API.
|
||||||
func TestInvVect(t *testing.T) {
|
func TestInvVect(t *testing.T) {
|
||||||
ivType := InvTypeBlock
|
ivType := InvTypeBlock
|
||||||
hash := ShaHash{}
|
hash := chainhash.Hash{}
|
||||||
|
|
||||||
// Ensure we get the same payload and signature back out.
|
// Ensure we get the same payload and signature back out.
|
||||||
iv := NewInvVect(ivType, &hash)
|
iv := NewInvVect(ivType, &hash)
|
||||||
|
@ -59,15 +60,15 @@ func TestInvVect(t *testing.T) {
|
||||||
func TestInvVectWire(t *testing.T) {
|
func TestInvVectWire(t *testing.T) {
|
||||||
// Block 203707 hash.
|
// Block 203707 hash.
|
||||||
hashStr := "3264bc2ac36a60840790ba1d475d01367e7c723da941069e9dc"
|
hashStr := "3264bc2ac36a60840790ba1d475d01367e7c723da941069e9dc"
|
||||||
baseHash, err := NewShaHashFromStr(hashStr)
|
baseHash, err := chainhash.NewHashFromStr(hashStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("NewShaHashFromStr: %v", err)
|
t.Errorf("NewHashFromStr: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// errInvVect is an inventory vector with an error.
|
// errInvVect is an inventory vector with an error.
|
||||||
errInvVect := InvVect{
|
errInvVect := InvVect{
|
||||||
Type: InvTypeError,
|
Type: InvTypeError,
|
||||||
Hash: ShaHash{},
|
Hash: chainhash.Hash{},
|
||||||
}
|
}
|
||||||
|
|
||||||
// errInvVectEncoded is the wire encoded bytes of errInvVect.
|
// errInvVectEncoded is the wire encoded bytes of errInvVect.
|
||||||
|
|
|
@ -9,6 +9,8 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MessageHeaderSize is the number of bytes in a bitcoin message header.
|
// MessageHeaderSize is the number of bytes in a bitcoin message header.
|
||||||
|
@ -237,7 +239,7 @@ func WriteMessageN(w io.Writer, msg Message, pver uint32, btcnet BitcoinNet) (in
|
||||||
hdr.magic = btcnet
|
hdr.magic = btcnet
|
||||||
hdr.command = cmd
|
hdr.command = cmd
|
||||||
hdr.length = uint32(lenp)
|
hdr.length = uint32(lenp)
|
||||||
copy(hdr.checksum[:], DoubleSha256(payload)[0:4])
|
copy(hdr.checksum[:], chainhash.DoubleHashB(payload)[0:4])
|
||||||
|
|
||||||
// Encode the header for the message. This is done to a buffer
|
// Encode the header for the message. This is done to a buffer
|
||||||
// rather than directly to the writer since writeElements doesn't
|
// rather than directly to the writer since writeElements doesn't
|
||||||
|
@ -338,7 +340,7 @@ func ReadMessageN(r io.Reader, pver uint32, btcnet BitcoinNet) (int, Message, []
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test checksum.
|
// Test checksum.
|
||||||
checksum := DoubleSha256(payload)[0:4]
|
checksum := chainhash.DoubleHashB(payload)[0:4]
|
||||||
if !bytes.Equal(checksum[:], hdr.checksum[:]) {
|
if !bytes.Equal(checksum[:], hdr.checksum[:]) {
|
||||||
str := fmt.Sprintf("payload checksum failed - header "+
|
str := fmt.Sprintf("payload checksum failed - header "+
|
||||||
"indicates %v, but actual checksum is %v.",
|
"indicates %v, but actual checksum is %v.",
|
||||||
|
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/davecgh/go-spew/spew"
|
"github.com/davecgh/go-spew/spew"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -56,7 +57,7 @@ func TestMessage(t *testing.T) {
|
||||||
msgVerack := NewMsgVerAck()
|
msgVerack := NewMsgVerAck()
|
||||||
msgGetAddr := NewMsgGetAddr()
|
msgGetAddr := NewMsgGetAddr()
|
||||||
msgAddr := NewMsgAddr()
|
msgAddr := NewMsgAddr()
|
||||||
msgGetBlocks := NewMsgGetBlocks(&ShaHash{})
|
msgGetBlocks := NewMsgGetBlocks(&chainhash.Hash{})
|
||||||
msgBlock := &blockOne
|
msgBlock := &blockOne
|
||||||
msgInv := NewMsgInv()
|
msgInv := NewMsgInv()
|
||||||
msgGetData := NewMsgGetData()
|
msgGetData := NewMsgGetData()
|
||||||
|
@ -71,7 +72,7 @@ func TestMessage(t *testing.T) {
|
||||||
msgFilterAdd := NewMsgFilterAdd([]byte{0x01})
|
msgFilterAdd := NewMsgFilterAdd([]byte{0x01})
|
||||||
msgFilterClear := NewMsgFilterClear()
|
msgFilterClear := NewMsgFilterClear()
|
||||||
msgFilterLoad := NewMsgFilterLoad([]byte{0x01}, 10, 0, BloomUpdateNone)
|
msgFilterLoad := NewMsgFilterLoad([]byte{0x01}, 10, 0, BloomUpdateNone)
|
||||||
bh := NewBlockHeader(&ShaHash{}, &ShaHash{}, 0, 0)
|
bh := NewBlockHeader(&chainhash.Hash{}, &chainhash.Hash{}, 0, 0)
|
||||||
msgMerkleBlock := NewMsgMerkleBlock(bh)
|
msgMerkleBlock := NewMsgMerkleBlock(bh)
|
||||||
msgReject := NewMsgReject("block", RejectDuplicate, "duplicate block")
|
msgReject := NewMsgReject("block", RejectDuplicate, "duplicate block")
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2013-2015 The btcsuite developers
|
// Copyright (c) 2013-2016 The btcsuite developers
|
||||||
// Use of this source code is governed by an ISC
|
// Use of this source code is governed by an ISC
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -8,6 +8,8 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
)
|
)
|
||||||
|
|
||||||
// defaultTransactionAlloc is the default size used for the backing array
|
// defaultTransactionAlloc is the default size used for the backing array
|
||||||
|
@ -224,18 +226,18 @@ func (msg *MsgBlock) MaxPayloadLength(pver uint32) uint32 {
|
||||||
return MaxBlockPayload
|
return MaxBlockPayload
|
||||||
}
|
}
|
||||||
|
|
||||||
// BlockSha computes the block identifier hash for this block.
|
// BlockHash computes the block identifier hash for this block.
|
||||||
func (msg *MsgBlock) BlockSha() ShaHash {
|
func (msg *MsgBlock) BlockHash() chainhash.Hash {
|
||||||
return msg.Header.BlockSha()
|
return msg.Header.BlockHash()
|
||||||
}
|
}
|
||||||
|
|
||||||
// TxShas returns a slice of hashes of all of transactions in this block.
|
// TxHashes returns a slice of hashes of all of transactions in this block.
|
||||||
func (msg *MsgBlock) TxShas() ([]ShaHash, error) {
|
func (msg *MsgBlock) TxHashes() ([]chainhash.Hash, error) {
|
||||||
shaList := make([]ShaHash, 0, len(msg.Transactions))
|
hashList := make([]chainhash.Hash, 0, len(msg.Transactions))
|
||||||
for _, tx := range msg.Transactions {
|
for _, tx := range msg.Transactions {
|
||||||
shaList = append(shaList, tx.TxSha())
|
hashList = append(hashList, tx.TxHash())
|
||||||
}
|
}
|
||||||
return shaList, nil
|
return hashList, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewMsgBlock returns a new bitcoin block message that conforms to the
|
// NewMsgBlock returns a new bitcoin block message that conforms to the
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/davecgh/go-spew/spew"
|
"github.com/davecgh/go-spew/spew"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -68,41 +69,41 @@ func TestBlock(t *testing.T) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestBlockTxShas tests the ability to generate a slice of all transaction
|
// TestBlockTxHashes tests the ability to generate a slice of all transaction
|
||||||
// hashes from a block accurately.
|
// hashes from a block accurately.
|
||||||
func TestBlockTxShas(t *testing.T) {
|
func TestBlockTxHashes(t *testing.T) {
|
||||||
// Block 1, transaction 1 hash.
|
// Block 1, transaction 1 hash.
|
||||||
hashStr := "0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098"
|
hashStr := "0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098"
|
||||||
wantHash, err := NewShaHashFromStr(hashStr)
|
wantHash, err := chainhash.NewHashFromStr(hashStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("NewShaHashFromStr: %v", err)
|
t.Errorf("NewHashFromStr: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
wantShas := []ShaHash{*wantHash}
|
wantHashes := []chainhash.Hash{*wantHash}
|
||||||
shas, err := blockOne.TxShas()
|
hashes, err := blockOne.TxHashes()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("TxShas: %v", err)
|
t.Errorf("TxHashes: %v", err)
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(shas, wantShas) {
|
if !reflect.DeepEqual(hashes, wantHashes) {
|
||||||
t.Errorf("TxShas: wrong transaction hashes - got %v, want %v",
|
t.Errorf("TxHashes: wrong transaction hashes - got %v, want %v",
|
||||||
spew.Sdump(shas), spew.Sdump(wantShas))
|
spew.Sdump(hashes), spew.Sdump(wantHashes))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestBlockSha tests the ability to generate the hash of a block accurately.
|
// TestBlockHash tests the ability to generate the hash of a block accurately.
|
||||||
func TestBlockSha(t *testing.T) {
|
func TestBlockHash(t *testing.T) {
|
||||||
// Block 1 hash.
|
// Block 1 hash.
|
||||||
hashStr := "839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048"
|
hashStr := "839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048"
|
||||||
wantHash, err := NewShaHashFromStr(hashStr)
|
wantHash, err := chainhash.NewHashFromStr(hashStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("NewShaHashFromStr: %v", err)
|
t.Errorf("NewHashFromStr: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the hash produced is expected.
|
// Ensure the hash produced is expected.
|
||||||
blockHash := blockOne.BlockSha()
|
blockHash := blockOne.BlockHash()
|
||||||
if !blockHash.IsEqual(wantHash) {
|
if !blockHash.IsEqual(wantHash) {
|
||||||
t.Errorf("BlockSha: wrong hash - got %v, want %v",
|
t.Errorf("BlockHash: wrong hash - got %v, want %v",
|
||||||
spew.Sprint(blockHash), spew.Sprint(wantHash))
|
spew.Sprint(blockHash), spew.Sprint(wantHash))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -478,13 +479,13 @@ func TestBlockSerializeSize(t *testing.T) {
|
||||||
var blockOne = MsgBlock{
|
var blockOne = MsgBlock{
|
||||||
Header: BlockHeader{
|
Header: BlockHeader{
|
||||||
Version: 1,
|
Version: 1,
|
||||||
PrevBlock: ShaHash([HashSize]byte{ // Make go vet happy.
|
PrevBlock: chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy.
|
||||||
0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72,
|
0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72,
|
||||||
0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f,
|
0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f,
|
||||||
0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c,
|
0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c,
|
||||||
0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
}),
|
}),
|
||||||
MerkleRoot: ShaHash([HashSize]byte{ // Make go vet happy.
|
MerkleRoot: chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy.
|
||||||
0x98, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44,
|
0x98, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44,
|
||||||
0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67,
|
0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67,
|
||||||
0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1,
|
0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1,
|
||||||
|
@ -501,7 +502,7 @@ var blockOne = MsgBlock{
|
||||||
TxIn: []*TxIn{
|
TxIn: []*TxIn{
|
||||||
{
|
{
|
||||||
PreviousOutPoint: OutPoint{
|
PreviousOutPoint: OutPoint{
|
||||||
Hash: ShaHash{},
|
Hash: chainhash.Hash{},
|
||||||
Index: 0xffffffff,
|
Index: 0xffffffff,
|
||||||
},
|
},
|
||||||
SignatureScript: []byte{
|
SignatureScript: []byte{
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2013-2015 The btcsuite developers
|
// Copyright (c) 2013-2016 The btcsuite developers
|
||||||
// Use of this source code is governed by an ISC
|
// Use of this source code is governed by an ISC
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -7,6 +7,8 @@ package wire
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MaxBlockLocatorsPerMsg is the maximum number of block locator hashes allowed
|
// MaxBlockLocatorsPerMsg is the maximum number of block locator hashes allowed
|
||||||
|
@ -30,12 +32,12 @@ const MaxBlockLocatorsPerMsg = 500
|
||||||
// closer to the genesis block you get.
|
// closer to the genesis block you get.
|
||||||
type MsgGetBlocks struct {
|
type MsgGetBlocks struct {
|
||||||
ProtocolVersion uint32
|
ProtocolVersion uint32
|
||||||
BlockLocatorHashes []*ShaHash
|
BlockLocatorHashes []*chainhash.Hash
|
||||||
HashStop ShaHash
|
HashStop chainhash.Hash
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddBlockLocatorHash adds a new block locator hash to the message.
|
// AddBlockLocatorHash adds a new block locator hash to the message.
|
||||||
func (msg *MsgGetBlocks) AddBlockLocatorHash(hash *ShaHash) error {
|
func (msg *MsgGetBlocks) AddBlockLocatorHash(hash *chainhash.Hash) error {
|
||||||
if len(msg.BlockLocatorHashes)+1 > MaxBlockLocatorsPerMsg {
|
if len(msg.BlockLocatorHashes)+1 > MaxBlockLocatorsPerMsg {
|
||||||
str := fmt.Sprintf("too many block locator hashes for message [max %v]",
|
str := fmt.Sprintf("too many block locator hashes for message [max %v]",
|
||||||
MaxBlockLocatorsPerMsg)
|
MaxBlockLocatorsPerMsg)
|
||||||
|
@ -67,8 +69,8 @@ func (msg *MsgGetBlocks) BtcDecode(r io.Reader, pver uint32) error {
|
||||||
|
|
||||||
// Create a contiguous slice of hashes to deserialize into in order to
|
// Create a contiguous slice of hashes to deserialize into in order to
|
||||||
// reduce the number of allocations.
|
// reduce the number of allocations.
|
||||||
locatorHashes := make([]ShaHash, count)
|
locatorHashes := make([]chainhash.Hash, count)
|
||||||
msg.BlockLocatorHashes = make([]*ShaHash, 0, count)
|
msg.BlockLocatorHashes = make([]*chainhash.Hash, 0, count)
|
||||||
for i := uint64(0); i < count; i++ {
|
for i := uint64(0); i < count; i++ {
|
||||||
hash := &locatorHashes[i]
|
hash := &locatorHashes[i]
|
||||||
err := readElement(r, hash)
|
err := readElement(r, hash)
|
||||||
|
@ -132,16 +134,16 @@ func (msg *MsgGetBlocks) Command() string {
|
||||||
func (msg *MsgGetBlocks) MaxPayloadLength(pver uint32) uint32 {
|
func (msg *MsgGetBlocks) MaxPayloadLength(pver uint32) uint32 {
|
||||||
// Protocol version 4 bytes + num hashes (varInt) + max block locator
|
// Protocol version 4 bytes + num hashes (varInt) + max block locator
|
||||||
// hashes + hash stop.
|
// hashes + hash stop.
|
||||||
return 4 + MaxVarIntPayload + (MaxBlockLocatorsPerMsg * HashSize) + HashSize
|
return 4 + MaxVarIntPayload + (MaxBlockLocatorsPerMsg * chainhash.HashSize) + chainhash.HashSize
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewMsgGetBlocks returns a new bitcoin getblocks message that conforms to the
|
// NewMsgGetBlocks returns a new bitcoin getblocks message that conforms to the
|
||||||
// Message interface using the passed parameters and defaults for the remaining
|
// Message interface using the passed parameters and defaults for the remaining
|
||||||
// fields.
|
// fields.
|
||||||
func NewMsgGetBlocks(hashStop *ShaHash) *MsgGetBlocks {
|
func NewMsgGetBlocks(hashStop *chainhash.Hash) *MsgGetBlocks {
|
||||||
return &MsgGetBlocks{
|
return &MsgGetBlocks{
|
||||||
ProtocolVersion: ProtocolVersion,
|
ProtocolVersion: ProtocolVersion,
|
||||||
BlockLocatorHashes: make([]*ShaHash, 0, MaxBlockLocatorsPerMsg),
|
BlockLocatorHashes: make([]*chainhash.Hash, 0, MaxBlockLocatorsPerMsg),
|
||||||
HashStop: *hashStop,
|
HashStop: *hashStop,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/davecgh/go-spew/spew"
|
"github.com/davecgh/go-spew/spew"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -19,16 +20,16 @@ func TestGetBlocks(t *testing.T) {
|
||||||
|
|
||||||
// Block 99500 hash.
|
// Block 99500 hash.
|
||||||
hashStr := "000000000002e7ad7b9eef9479e4aabc65cb831269cc20d2632c13684406dee0"
|
hashStr := "000000000002e7ad7b9eef9479e4aabc65cb831269cc20d2632c13684406dee0"
|
||||||
locatorHash, err := NewShaHashFromStr(hashStr)
|
locatorHash, err := chainhash.NewHashFromStr(hashStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("NewShaHashFromStr: %v", err)
|
t.Errorf("NewHashFromStr: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Block 100000 hash.
|
// Block 100000 hash.
|
||||||
hashStr = "3ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506"
|
hashStr = "3ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506"
|
||||||
hashStop, err := NewShaHashFromStr(hashStr)
|
hashStop, err := chainhash.NewHashFromStr(hashStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("NewShaHashFromStr: %v", err)
|
t.Errorf("NewHashFromStr: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure we get the same data back out.
|
// Ensure we get the same data back out.
|
||||||
|
@ -89,27 +90,27 @@ func TestGetBlocksWire(t *testing.T) {
|
||||||
|
|
||||||
// Block 99499 hash.
|
// Block 99499 hash.
|
||||||
hashStr := "2710f40c87ec93d010a6fd95f42c59a2cbacc60b18cf6b7957535"
|
hashStr := "2710f40c87ec93d010a6fd95f42c59a2cbacc60b18cf6b7957535"
|
||||||
hashLocator, err := NewShaHashFromStr(hashStr)
|
hashLocator, err := chainhash.NewHashFromStr(hashStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("NewShaHashFromStr: %v", err)
|
t.Errorf("NewHashFromStr: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Block 99500 hash.
|
// Block 99500 hash.
|
||||||
hashStr = "2e7ad7b9eef9479e4aabc65cb831269cc20d2632c13684406dee0"
|
hashStr = "2e7ad7b9eef9479e4aabc65cb831269cc20d2632c13684406dee0"
|
||||||
hashLocator2, err := NewShaHashFromStr(hashStr)
|
hashLocator2, err := chainhash.NewHashFromStr(hashStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("NewShaHashFromStr: %v", err)
|
t.Errorf("NewHashFromStr: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Block 100000 hash.
|
// Block 100000 hash.
|
||||||
hashStr = "3ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506"
|
hashStr = "3ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506"
|
||||||
hashStop, err := NewShaHashFromStr(hashStr)
|
hashStop, err := chainhash.NewHashFromStr(hashStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("NewShaHashFromStr: %v", err)
|
t.Errorf("NewHashFromStr: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MsgGetBlocks message with no block locators or stop hash.
|
// MsgGetBlocks message with no block locators or stop hash.
|
||||||
noLocators := NewMsgGetBlocks(&ShaHash{})
|
noLocators := NewMsgGetBlocks(&chainhash.Hash{})
|
||||||
noLocators.ProtocolVersion = pver
|
noLocators.ProtocolVersion = pver
|
||||||
noLocatorsEncoded := []byte{
|
noLocatorsEncoded := []byte{
|
||||||
0x62, 0xea, 0x00, 0x00, // Protocol version 60002
|
0x62, 0xea, 0x00, 0x00, // Protocol version 60002
|
||||||
|
@ -271,23 +272,23 @@ func TestGetBlocksWireErrors(t *testing.T) {
|
||||||
|
|
||||||
// Block 99499 hash.
|
// Block 99499 hash.
|
||||||
hashStr := "2710f40c87ec93d010a6fd95f42c59a2cbacc60b18cf6b7957535"
|
hashStr := "2710f40c87ec93d010a6fd95f42c59a2cbacc60b18cf6b7957535"
|
||||||
hashLocator, err := NewShaHashFromStr(hashStr)
|
hashLocator, err := chainhash.NewHashFromStr(hashStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("NewShaHashFromStr: %v", err)
|
t.Errorf("NewHashFromStr: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Block 99500 hash.
|
// Block 99500 hash.
|
||||||
hashStr = "2e7ad7b9eef9479e4aabc65cb831269cc20d2632c13684406dee0"
|
hashStr = "2e7ad7b9eef9479e4aabc65cb831269cc20d2632c13684406dee0"
|
||||||
hashLocator2, err := NewShaHashFromStr(hashStr)
|
hashLocator2, err := chainhash.NewHashFromStr(hashStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("NewShaHashFromStr: %v", err)
|
t.Errorf("NewHashFromStr: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Block 100000 hash.
|
// Block 100000 hash.
|
||||||
hashStr = "3ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506"
|
hashStr = "3ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506"
|
||||||
hashStop, err := NewShaHashFromStr(hashStr)
|
hashStop, err := chainhash.NewHashFromStr(hashStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("NewShaHashFromStr: %v", err)
|
t.Errorf("NewHashFromStr: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MsgGetBlocks message with multiple block locators and a stop hash.
|
// MsgGetBlocks message with multiple block locators and a stop hash.
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/davecgh/go-spew/spew"
|
"github.com/davecgh/go-spew/spew"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -36,7 +37,7 @@ func TestGetData(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure inventory vectors are added properly.
|
// Ensure inventory vectors are added properly.
|
||||||
hash := ShaHash{}
|
hash := chainhash.Hash{}
|
||||||
iv := NewInvVect(InvTypeBlock, &hash)
|
iv := NewInvVect(InvTypeBlock, &hash)
|
||||||
err := msg.AddInvVect(iv)
|
err := msg.AddInvVect(iv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -74,16 +75,16 @@ func TestGetData(t *testing.T) {
|
||||||
func TestGetDataWire(t *testing.T) {
|
func TestGetDataWire(t *testing.T) {
|
||||||
// Block 203707 hash.
|
// Block 203707 hash.
|
||||||
hashStr := "3264bc2ac36a60840790ba1d475d01367e7c723da941069e9dc"
|
hashStr := "3264bc2ac36a60840790ba1d475d01367e7c723da941069e9dc"
|
||||||
blockHash, err := NewShaHashFromStr(hashStr)
|
blockHash, err := chainhash.NewHashFromStr(hashStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("NewShaHashFromStr: %v", err)
|
t.Errorf("NewHashFromStr: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transation 1 of Block 203707 hash.
|
// Transation 1 of Block 203707 hash.
|
||||||
hashStr = "d28a3dc7392bf00a9855ee93dd9a81eff82a2c4fe57fbd42cfe71b487accfaf0"
|
hashStr = "d28a3dc7392bf00a9855ee93dd9a81eff82a2c4fe57fbd42cfe71b487accfaf0"
|
||||||
txHash, err := NewShaHashFromStr(hashStr)
|
txHash, err := chainhash.NewHashFromStr(hashStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("NewShaHashFromStr: %v", err)
|
t.Errorf("NewHashFromStr: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
iv := NewInvVect(InvTypeBlock, blockHash)
|
iv := NewInvVect(InvTypeBlock, blockHash)
|
||||||
|
@ -239,9 +240,9 @@ func TestGetDataWireErrors(t *testing.T) {
|
||||||
|
|
||||||
// Block 203707 hash.
|
// Block 203707 hash.
|
||||||
hashStr := "3264bc2ac36a60840790ba1d475d01367e7c723da941069e9dc"
|
hashStr := "3264bc2ac36a60840790ba1d475d01367e7c723da941069e9dc"
|
||||||
blockHash, err := NewShaHashFromStr(hashStr)
|
blockHash, err := chainhash.NewHashFromStr(hashStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("NewShaHashFromStr: %v", err)
|
t.Errorf("NewHashFromStr: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
iv := NewInvVect(InvTypeBlock, blockHash)
|
iv := NewInvVect(InvTypeBlock, blockHash)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2013-2015 The btcsuite developers
|
// Copyright (c) 2013-2016 The btcsuite developers
|
||||||
// Use of this source code is governed by an ISC
|
// Use of this source code is governed by an ISC
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -7,6 +7,8 @@ package wire
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MsgGetHeaders implements the Message interface and represents a bitcoin
|
// MsgGetHeaders implements the Message interface and represents a bitcoin
|
||||||
|
@ -27,12 +29,12 @@ import (
|
||||||
// closer to the genesis block you get.
|
// closer to the genesis block you get.
|
||||||
type MsgGetHeaders struct {
|
type MsgGetHeaders struct {
|
||||||
ProtocolVersion uint32
|
ProtocolVersion uint32
|
||||||
BlockLocatorHashes []*ShaHash
|
BlockLocatorHashes []*chainhash.Hash
|
||||||
HashStop ShaHash
|
HashStop chainhash.Hash
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddBlockLocatorHash adds a new block locator hash to the message.
|
// AddBlockLocatorHash adds a new block locator hash to the message.
|
||||||
func (msg *MsgGetHeaders) AddBlockLocatorHash(hash *ShaHash) error {
|
func (msg *MsgGetHeaders) AddBlockLocatorHash(hash *chainhash.Hash) error {
|
||||||
if len(msg.BlockLocatorHashes)+1 > MaxBlockLocatorsPerMsg {
|
if len(msg.BlockLocatorHashes)+1 > MaxBlockLocatorsPerMsg {
|
||||||
str := fmt.Sprintf("too many block locator hashes for message [max %v]",
|
str := fmt.Sprintf("too many block locator hashes for message [max %v]",
|
||||||
MaxBlockLocatorsPerMsg)
|
MaxBlockLocatorsPerMsg)
|
||||||
|
@ -64,8 +66,8 @@ func (msg *MsgGetHeaders) BtcDecode(r io.Reader, pver uint32) error {
|
||||||
|
|
||||||
// Create a contiguous slice of hashes to deserialize into in order to
|
// Create a contiguous slice of hashes to deserialize into in order to
|
||||||
// reduce the number of allocations.
|
// reduce the number of allocations.
|
||||||
locatorHashes := make([]ShaHash, count)
|
locatorHashes := make([]chainhash.Hash, count)
|
||||||
msg.BlockLocatorHashes = make([]*ShaHash, 0, count)
|
msg.BlockLocatorHashes = make([]*chainhash.Hash, 0, count)
|
||||||
for i := uint64(0); i < count; i++ {
|
for i := uint64(0); i < count; i++ {
|
||||||
hash := &locatorHashes[i]
|
hash := &locatorHashes[i]
|
||||||
err := readElement(r, hash)
|
err := readElement(r, hash)
|
||||||
|
@ -104,8 +106,8 @@ func (msg *MsgGetHeaders) BtcEncode(w io.Writer, pver uint32) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, sha := range msg.BlockLocatorHashes {
|
for _, hash := range msg.BlockLocatorHashes {
|
||||||
err := writeElement(w, sha)
|
err := writeElement(w, hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -130,13 +132,15 @@ func (msg *MsgGetHeaders) Command() string {
|
||||||
func (msg *MsgGetHeaders) MaxPayloadLength(pver uint32) uint32 {
|
func (msg *MsgGetHeaders) MaxPayloadLength(pver uint32) uint32 {
|
||||||
// Version 4 bytes + num block locator hashes (varInt) + max allowed block
|
// Version 4 bytes + num block locator hashes (varInt) + max allowed block
|
||||||
// locators + hash stop.
|
// locators + hash stop.
|
||||||
return 4 + MaxVarIntPayload + (MaxBlockLocatorsPerMsg * HashSize) + HashSize
|
return 4 + MaxVarIntPayload + (MaxBlockLocatorsPerMsg *
|
||||||
|
chainhash.HashSize) + chainhash.HashSize
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewMsgGetHeaders returns a new bitcoin getheaders message that conforms to
|
// NewMsgGetHeaders returns a new bitcoin getheaders message that conforms to
|
||||||
// the Message interface. See MsgGetHeaders for details.
|
// the Message interface. See MsgGetHeaders for details.
|
||||||
func NewMsgGetHeaders() *MsgGetHeaders {
|
func NewMsgGetHeaders() *MsgGetHeaders {
|
||||||
return &MsgGetHeaders{
|
return &MsgGetHeaders{
|
||||||
BlockLocatorHashes: make([]*ShaHash, 0, MaxBlockLocatorsPerMsg),
|
BlockLocatorHashes: make([]*chainhash.Hash, 0,
|
||||||
|
MaxBlockLocatorsPerMsg),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/davecgh/go-spew/spew"
|
"github.com/davecgh/go-spew/spew"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -19,9 +20,9 @@ func TestGetHeaders(t *testing.T) {
|
||||||
|
|
||||||
// Block 99500 hash.
|
// Block 99500 hash.
|
||||||
hashStr := "000000000002e7ad7b9eef9479e4aabc65cb831269cc20d2632c13684406dee0"
|
hashStr := "000000000002e7ad7b9eef9479e4aabc65cb831269cc20d2632c13684406dee0"
|
||||||
locatorHash, err := NewShaHashFromStr(hashStr)
|
locatorHash, err := chainhash.NewHashFromStr(hashStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("NewShaHashFromStr: %v", err)
|
t.Errorf("NewHashFromStr: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the command is expected value.
|
// Ensure the command is expected value.
|
||||||
|
@ -78,23 +79,23 @@ func TestGetHeadersWire(t *testing.T) {
|
||||||
|
|
||||||
// Block 99499 hash.
|
// Block 99499 hash.
|
||||||
hashStr := "2710f40c87ec93d010a6fd95f42c59a2cbacc60b18cf6b7957535"
|
hashStr := "2710f40c87ec93d010a6fd95f42c59a2cbacc60b18cf6b7957535"
|
||||||
hashLocator, err := NewShaHashFromStr(hashStr)
|
hashLocator, err := chainhash.NewHashFromStr(hashStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("NewShaHashFromStr: %v", err)
|
t.Errorf("NewHashFromStr: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Block 99500 hash.
|
// Block 99500 hash.
|
||||||
hashStr = "2e7ad7b9eef9479e4aabc65cb831269cc20d2632c13684406dee0"
|
hashStr = "2e7ad7b9eef9479e4aabc65cb831269cc20d2632c13684406dee0"
|
||||||
hashLocator2, err := NewShaHashFromStr(hashStr)
|
hashLocator2, err := chainhash.NewHashFromStr(hashStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("NewShaHashFromStr: %v", err)
|
t.Errorf("NewHashFromStr: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Block 100000 hash.
|
// Block 100000 hash.
|
||||||
hashStr = "3ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506"
|
hashStr = "3ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506"
|
||||||
hashStop, err := NewShaHashFromStr(hashStr)
|
hashStop, err := chainhash.NewHashFromStr(hashStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("NewShaHashFromStr: %v", err)
|
t.Errorf("NewHashFromStr: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MsgGetHeaders message with no block locators or stop hash.
|
// MsgGetHeaders message with no block locators or stop hash.
|
||||||
|
@ -261,23 +262,23 @@ func TestGetHeadersWireErrors(t *testing.T) {
|
||||||
|
|
||||||
// Block 99499 hash.
|
// Block 99499 hash.
|
||||||
hashStr := "2710f40c87ec93d010a6fd95f42c59a2cbacc60b18cf6b7957535"
|
hashStr := "2710f40c87ec93d010a6fd95f42c59a2cbacc60b18cf6b7957535"
|
||||||
hashLocator, err := NewShaHashFromStr(hashStr)
|
hashLocator, err := chainhash.NewHashFromStr(hashStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("NewShaHashFromStr: %v", err)
|
t.Errorf("NewHashFromStr: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Block 99500 hash.
|
// Block 99500 hash.
|
||||||
hashStr = "2e7ad7b9eef9479e4aabc65cb831269cc20d2632c13684406dee0"
|
hashStr = "2e7ad7b9eef9479e4aabc65cb831269cc20d2632c13684406dee0"
|
||||||
hashLocator2, err := NewShaHashFromStr(hashStr)
|
hashLocator2, err := chainhash.NewHashFromStr(hashStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("NewShaHashFromStr: %v", err)
|
t.Errorf("NewHashFromStr: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Block 100000 hash.
|
// Block 100000 hash.
|
||||||
hashStr = "3ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506"
|
hashStr = "3ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506"
|
||||||
hashStop, err := NewShaHashFromStr(hashStr)
|
hashStop, err := chainhash.NewHashFromStr(hashStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("NewShaHashFromStr: %v", err)
|
t.Errorf("NewHashFromStr: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MsgGetHeaders message with multiple block locators and a stop hash.
|
// MsgGetHeaders message with multiple block locators and a stop hash.
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/davecgh/go-spew/spew"
|
"github.com/davecgh/go-spew/spew"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -36,7 +37,7 @@ func TestInv(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure inventory vectors are added properly.
|
// Ensure inventory vectors are added properly.
|
||||||
hash := ShaHash{}
|
hash := chainhash.Hash{}
|
||||||
iv := NewInvVect(InvTypeBlock, &hash)
|
iv := NewInvVect(InvTypeBlock, &hash)
|
||||||
err := msg.AddInvVect(iv)
|
err := msg.AddInvVect(iv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -74,16 +75,16 @@ func TestInv(t *testing.T) {
|
||||||
func TestInvWire(t *testing.T) {
|
func TestInvWire(t *testing.T) {
|
||||||
// Block 203707 hash.
|
// Block 203707 hash.
|
||||||
hashStr := "3264bc2ac36a60840790ba1d475d01367e7c723da941069e9dc"
|
hashStr := "3264bc2ac36a60840790ba1d475d01367e7c723da941069e9dc"
|
||||||
blockHash, err := NewShaHashFromStr(hashStr)
|
blockHash, err := chainhash.NewHashFromStr(hashStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("NewShaHashFromStr: %v", err)
|
t.Errorf("NewHashFromStr: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transation 1 of Block 203707 hash.
|
// Transation 1 of Block 203707 hash.
|
||||||
hashStr = "d28a3dc7392bf00a9855ee93dd9a81eff82a2c4fe57fbd42cfe71b487accfaf0"
|
hashStr = "d28a3dc7392bf00a9855ee93dd9a81eff82a2c4fe57fbd42cfe71b487accfaf0"
|
||||||
txHash, err := NewShaHashFromStr(hashStr)
|
txHash, err := chainhash.NewHashFromStr(hashStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("NewShaHashFromStr: %v", err)
|
t.Errorf("NewHashFromStr: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
iv := NewInvVect(InvTypeBlock, blockHash)
|
iv := NewInvVect(InvTypeBlock, blockHash)
|
||||||
|
@ -239,9 +240,9 @@ func TestInvWireErrors(t *testing.T) {
|
||||||
|
|
||||||
// Block 203707 hash.
|
// Block 203707 hash.
|
||||||
hashStr := "3264bc2ac36a60840790ba1d475d01367e7c723da941069e9dc"
|
hashStr := "3264bc2ac36a60840790ba1d475d01367e7c723da941069e9dc"
|
||||||
blockHash, err := NewShaHashFromStr(hashStr)
|
blockHash, err := chainhash.NewHashFromStr(hashStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("NewShaHashFromStr: %v", err)
|
t.Errorf("NewHashFromStr: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
iv := NewInvVect(InvTypeBlock, blockHash)
|
iv := NewInvVect(InvTypeBlock, blockHash)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015 The btcsuite developers
|
// Copyright (c) 2014-2016 The btcsuite developers
|
||||||
// Use of this source code is governed by an ISC
|
// Use of this source code is governed by an ISC
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -7,6 +7,8 @@ package wire
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
)
|
)
|
||||||
|
|
||||||
// maxFlagsPerMerkleBlock is the maximum number of flag bytes that could
|
// maxFlagsPerMerkleBlock is the maximum number of flag bytes that could
|
||||||
|
@ -22,12 +24,12 @@ const maxFlagsPerMerkleBlock = maxTxPerBlock / 8
|
||||||
type MsgMerkleBlock struct {
|
type MsgMerkleBlock struct {
|
||||||
Header BlockHeader
|
Header BlockHeader
|
||||||
Transactions uint32
|
Transactions uint32
|
||||||
Hashes []*ShaHash
|
Hashes []*chainhash.Hash
|
||||||
Flags []byte
|
Flags []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddTxHash adds a new transaction hash to the message.
|
// AddTxHash adds a new transaction hash to the message.
|
||||||
func (msg *MsgMerkleBlock) AddTxHash(hash *ShaHash) error {
|
func (msg *MsgMerkleBlock) AddTxHash(hash *chainhash.Hash) error {
|
||||||
if len(msg.Hashes)+1 > maxTxPerBlock {
|
if len(msg.Hashes)+1 > maxTxPerBlock {
|
||||||
str := fmt.Sprintf("too many tx hashes for message [max %v]",
|
str := fmt.Sprintf("too many tx hashes for message [max %v]",
|
||||||
maxTxPerBlock)
|
maxTxPerBlock)
|
||||||
|
@ -70,8 +72,8 @@ func (msg *MsgMerkleBlock) BtcDecode(r io.Reader, pver uint32) error {
|
||||||
|
|
||||||
// Create a contiguous slice of hashes to deserialize into in order to
|
// Create a contiguous slice of hashes to deserialize into in order to
|
||||||
// reduce the number of allocations.
|
// reduce the number of allocations.
|
||||||
hashes := make([]ShaHash, count)
|
hashes := make([]chainhash.Hash, count)
|
||||||
msg.Hashes = make([]*ShaHash, 0, count)
|
msg.Hashes = make([]*chainhash.Hash, 0, count)
|
||||||
for i := uint64(0); i < count; i++ {
|
for i := uint64(0); i < count; i++ {
|
||||||
hash := &hashes[i]
|
hash := &hashes[i]
|
||||||
err := readElement(r, hash)
|
err := readElement(r, hash)
|
||||||
|
@ -160,7 +162,7 @@ func NewMsgMerkleBlock(bh *BlockHeader) *MsgMerkleBlock {
|
||||||
return &MsgMerkleBlock{
|
return &MsgMerkleBlock{
|
||||||
Header: *bh,
|
Header: *bh,
|
||||||
Transactions: 0,
|
Transactions: 0,
|
||||||
Hashes: make([]*ShaHash, 0),
|
Hashes: make([]*chainhash.Hash, 0),
|
||||||
Flags: make([]byte, 0),
|
Flags: make([]byte, 0),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/davecgh/go-spew/spew"
|
"github.com/davecgh/go-spew/spew"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -48,9 +49,9 @@ func TestMerkleBlock(t *testing.T) {
|
||||||
data := make([]byte, 32)
|
data := make([]byte, 32)
|
||||||
for i := 0; i < maxTxPerBlock; i++ {
|
for i := 0; i < maxTxPerBlock; i++ {
|
||||||
rand.Read(data)
|
rand.Read(data)
|
||||||
hash, err := NewShaHash(data)
|
hash, err := chainhash.NewHash(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("NewShaHash failed: %v\n", err)
|
t.Errorf("NewHash failed: %v\n", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,9 +63,9 @@ func TestMerkleBlock(t *testing.T) {
|
||||||
|
|
||||||
// Add one more Tx to test failure.
|
// Add one more Tx to test failure.
|
||||||
rand.Read(data)
|
rand.Read(data)
|
||||||
hash, err := NewShaHash(data)
|
hash, err := chainhash.NewHash(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("NewShaHash failed: %v\n", err)
|
t.Errorf("NewHash failed: %v\n", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -371,13 +372,13 @@ func TestMerkleBlockOverflowErrors(t *testing.T) {
|
||||||
var merkleBlockOne = MsgMerkleBlock{
|
var merkleBlockOne = MsgMerkleBlock{
|
||||||
Header: BlockHeader{
|
Header: BlockHeader{
|
||||||
Version: 1,
|
Version: 1,
|
||||||
PrevBlock: ShaHash([HashSize]byte{ // Make go vet happy.
|
PrevBlock: chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy.
|
||||||
0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72,
|
0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72,
|
||||||
0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f,
|
0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f,
|
||||||
0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c,
|
0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c,
|
||||||
0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
}),
|
}),
|
||||||
MerkleRoot: ShaHash([HashSize]byte{ // Make go vet happy.
|
MerkleRoot: chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy.
|
||||||
0x98, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44,
|
0x98, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44,
|
||||||
0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67,
|
0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67,
|
||||||
0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1,
|
0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1,
|
||||||
|
@ -388,8 +389,8 @@ var merkleBlockOne = MsgMerkleBlock{
|
||||||
Nonce: 0x9962e301, // 2573394689
|
Nonce: 0x9962e301, // 2573394689
|
||||||
},
|
},
|
||||||
Transactions: 1,
|
Transactions: 1,
|
||||||
Hashes: []*ShaHash{
|
Hashes: []*chainhash.Hash{
|
||||||
(*ShaHash)(&[HashSize]byte{ // Make go vet happy.
|
(*chainhash.Hash)(&[chainhash.HashSize]byte{ // Make go vet happy.
|
||||||
0x98, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44,
|
0x98, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44,
|
||||||
0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67,
|
0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67,
|
||||||
0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1,
|
0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1,
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/davecgh/go-spew/spew"
|
"github.com/davecgh/go-spew/spew"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -36,7 +37,7 @@ func TestNotFound(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure inventory vectors are added properly.
|
// Ensure inventory vectors are added properly.
|
||||||
hash := ShaHash{}
|
hash := chainhash.Hash{}
|
||||||
iv := NewInvVect(InvTypeBlock, &hash)
|
iv := NewInvVect(InvTypeBlock, &hash)
|
||||||
err := msg.AddInvVect(iv)
|
err := msg.AddInvVect(iv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -65,16 +66,16 @@ func TestNotFound(t *testing.T) {
|
||||||
func TestNotFoundWire(t *testing.T) {
|
func TestNotFoundWire(t *testing.T) {
|
||||||
// Block 203707 hash.
|
// Block 203707 hash.
|
||||||
hashStr := "3264bc2ac36a60840790ba1d475d01367e7c723da941069e9dc"
|
hashStr := "3264bc2ac36a60840790ba1d475d01367e7c723da941069e9dc"
|
||||||
blockHash, err := NewShaHashFromStr(hashStr)
|
blockHash, err := chainhash.NewHashFromStr(hashStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("NewShaHashFromStr: %v", err)
|
t.Errorf("NewHashFromStr: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transation 1 of Block 203707 hash.
|
// Transation 1 of Block 203707 hash.
|
||||||
hashStr = "d28a3dc7392bf00a9855ee93dd9a81eff82a2c4fe57fbd42cfe71b487accfaf0"
|
hashStr = "d28a3dc7392bf00a9855ee93dd9a81eff82a2c4fe57fbd42cfe71b487accfaf0"
|
||||||
txHash, err := NewShaHashFromStr(hashStr)
|
txHash, err := chainhash.NewHashFromStr(hashStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("NewShaHashFromStr: %v", err)
|
t.Errorf("NewHashFromStr: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
iv := NewInvVect(InvTypeBlock, blockHash)
|
iv := NewInvVect(InvTypeBlock, blockHash)
|
||||||
|
@ -230,9 +231,9 @@ func TestNotFoundWireErrors(t *testing.T) {
|
||||||
|
|
||||||
// Block 203707 hash.
|
// Block 203707 hash.
|
||||||
hashStr := "3264bc2ac36a60840790ba1d475d01367e7c723da941069e9dc"
|
hashStr := "3264bc2ac36a60840790ba1d475d01367e7c723da941069e9dc"
|
||||||
blockHash, err := NewShaHashFromStr(hashStr)
|
blockHash, err := chainhash.NewHashFromStr(hashStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("NewShaHashFromStr: %v", err)
|
t.Errorf("NewHashFromStr: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
iv := NewInvVect(InvTypeBlock, blockHash)
|
iv := NewInvVect(InvTypeBlock, blockHash)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015 The btcsuite developers
|
// Copyright (c) 2014-2016 The btcsuite developers
|
||||||
// Use of this source code is governed by an ISC
|
// Use of this source code is governed by an ISC
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -7,6 +7,8 @@ package wire
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RejectCode represents a numeric value by which a remote peer indicates
|
// RejectCode represents a numeric value by which a remote peer indicates
|
||||||
|
@ -66,7 +68,7 @@ type MsgReject struct {
|
||||||
|
|
||||||
// Hash identifies a specific block or transaction that was rejected
|
// Hash identifies a specific block or transaction that was rejected
|
||||||
// and therefore only applies the MsgBlock and MsgTx messages.
|
// and therefore only applies the MsgBlock and MsgTx messages.
|
||||||
Hash ShaHash
|
Hash chainhash.Hash
|
||||||
}
|
}
|
||||||
|
|
||||||
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
|
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2013-2015 The btcsuite developers
|
// Copyright (c) 2013-2016 The btcsuite developers
|
||||||
// Use of this source code is governed by an ISC
|
// Use of this source code is governed by an ISC
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -9,6 +9,8 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -35,7 +37,7 @@ const (
|
||||||
// minTxInPayload is the minimum payload size for a transaction input.
|
// minTxInPayload is the minimum payload size for a transaction input.
|
||||||
// PreviousOutPoint.Hash + PreviousOutPoint.Index 4 bytes + Varint for
|
// PreviousOutPoint.Hash + PreviousOutPoint.Index 4 bytes + Varint for
|
||||||
// SignatureScript length 1 byte + Sequence 4 bytes.
|
// SignatureScript length 1 byte + Sequence 4 bytes.
|
||||||
minTxInPayload = 9 + HashSize
|
minTxInPayload = 9 + chainhash.HashSize
|
||||||
|
|
||||||
// maxTxInPerMessage is the maximum number of transactions inputs that
|
// maxTxInPerMessage is the maximum number of transactions inputs that
|
||||||
// a transaction which fits into a message could possibly have.
|
// a transaction which fits into a message could possibly have.
|
||||||
|
@ -134,13 +136,13 @@ var scriptPool scriptFreeList = make(chan []byte, freeListMaxItems)
|
||||||
// OutPoint defines a bitcoin data type that is used to track previous
|
// OutPoint defines a bitcoin data type that is used to track previous
|
||||||
// transaction outputs.
|
// transaction outputs.
|
||||||
type OutPoint struct {
|
type OutPoint struct {
|
||||||
Hash ShaHash
|
Hash chainhash.Hash
|
||||||
Index uint32
|
Index uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewOutPoint returns a new bitcoin transaction outpoint point with the
|
// NewOutPoint returns a new bitcoin transaction outpoint point with the
|
||||||
// provided hash and index.
|
// provided hash and index.
|
||||||
func NewOutPoint(hash *ShaHash, index uint32) *OutPoint {
|
func NewOutPoint(hash *chainhash.Hash, index uint32) *OutPoint {
|
||||||
return &OutPoint{
|
return &OutPoint{
|
||||||
Hash: *hash,
|
Hash: *hash,
|
||||||
Index: index,
|
Index: index,
|
||||||
|
@ -155,9 +157,9 @@ func (o OutPoint) String() string {
|
||||||
// maximum message payload may increase in the future and this
|
// maximum message payload may increase in the future and this
|
||||||
// optimization may go unnoticed, so allocate space for 10 decimal
|
// optimization may go unnoticed, so allocate space for 10 decimal
|
||||||
// digits, which will fit any uint32.
|
// digits, which will fit any uint32.
|
||||||
buf := make([]byte, 2*HashSize+1, 2*HashSize+1+10)
|
buf := make([]byte, 2*chainhash.HashSize+1, 2*chainhash.HashSize+1+10)
|
||||||
copy(buf, o.Hash.String())
|
copy(buf, o.Hash.String())
|
||||||
buf[2*HashSize] = ':'
|
buf[2*chainhash.HashSize] = ':'
|
||||||
buf = strconv.AppendUint(buf, uint64(o.Index), 10)
|
buf = strconv.AppendUint(buf, uint64(o.Index), 10)
|
||||||
return string(buf)
|
return string(buf)
|
||||||
}
|
}
|
||||||
|
@ -236,15 +238,15 @@ func (msg *MsgTx) AddTxOut(to *TxOut) {
|
||||||
msg.TxOut = append(msg.TxOut, to)
|
msg.TxOut = append(msg.TxOut, to)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TxSha generates the ShaHash name for the transaction.
|
// TxHash generates the Hash for the transaction.
|
||||||
func (msg *MsgTx) TxSha() ShaHash {
|
func (msg *MsgTx) TxHash() chainhash.Hash {
|
||||||
// Encode the transaction and calculate double sha256 on the result.
|
// Encode the transaction and calculate double sha256 on the result.
|
||||||
// Ignore the error returns since the only way the encode could fail
|
// Ignore the error returns since the only way the encode could fail
|
||||||
// is being out of memory or due to nil pointers, both of which would
|
// is being out of memory or due to nil pointers, both of which would
|
||||||
// cause a run-time panic.
|
// cause a run-time panic.
|
||||||
buf := bytes.NewBuffer(make([]byte, 0, msg.SerializeSize()))
|
buf := bytes.NewBuffer(make([]byte, 0, msg.SerializeSize()))
|
||||||
_ = msg.Serialize(buf)
|
_ = msg.Serialize(buf)
|
||||||
return DoubleSha256SH(buf.Bytes())
|
return chainhash.DoubleHashH(buf.Bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy creates a deep copy of a transaction so that the original does not get
|
// Copy creates a deep copy of a transaction so that the original does not get
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/davecgh/go-spew/spew"
|
"github.com/davecgh/go-spew/spew"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -20,9 +21,9 @@ func TestTx(t *testing.T) {
|
||||||
|
|
||||||
// Block 100000 hash.
|
// Block 100000 hash.
|
||||||
hashStr := "3ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506"
|
hashStr := "3ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506"
|
||||||
hash, err := NewShaHashFromStr(hashStr)
|
hash, err := chainhash.NewHashFromStr(hashStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("NewShaHashFromStr: %v", err)
|
t.Errorf("NewHashFromStr: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the command is expected value.
|
// Ensure the command is expected value.
|
||||||
|
@ -127,13 +128,13 @@ func TestTx(t *testing.T) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestTxSha tests the ability to generate the hash of a transaction accurately.
|
// TestTxHash tests the ability to generate the hash of a transaction accurately.
|
||||||
func TestTxSha(t *testing.T) {
|
func TestTxHash(t *testing.T) {
|
||||||
// Hash of first transaction from block 113875.
|
// Hash of first transaction from block 113875.
|
||||||
hashStr := "f051e59b5e2503ac626d03aaeac8ab7be2d72ba4b7e97119c5852d70d52dcb86"
|
hashStr := "f051e59b5e2503ac626d03aaeac8ab7be2d72ba4b7e97119c5852d70d52dcb86"
|
||||||
wantHash, err := NewShaHashFromStr(hashStr)
|
wantHash, err := chainhash.NewHashFromStr(hashStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("NewShaHashFromStr: %v", err)
|
t.Errorf("NewHashFromStr: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,7 +142,7 @@ func TestTxSha(t *testing.T) {
|
||||||
msgTx := NewMsgTx()
|
msgTx := NewMsgTx()
|
||||||
txIn := TxIn{
|
txIn := TxIn{
|
||||||
PreviousOutPoint: OutPoint{
|
PreviousOutPoint: OutPoint{
|
||||||
Hash: ShaHash{},
|
Hash: chainhash.Hash{},
|
||||||
Index: 0xffffffff,
|
Index: 0xffffffff,
|
||||||
},
|
},
|
||||||
SignatureScript: []byte{0x04, 0x31, 0xdc, 0x00, 0x1b, 0x01, 0x62},
|
SignatureScript: []byte{0x04, 0x31, 0xdc, 0x00, 0x1b, 0x01, 0x62},
|
||||||
|
@ -168,9 +169,9 @@ func TestTxSha(t *testing.T) {
|
||||||
msgTx.LockTime = 0
|
msgTx.LockTime = 0
|
||||||
|
|
||||||
// Ensure the hash produced is expected.
|
// Ensure the hash produced is expected.
|
||||||
txHash := msgTx.TxSha()
|
txHash := msgTx.TxHash()
|
||||||
if !txHash.IsEqual(wantHash) {
|
if !txHash.IsEqual(wantHash) {
|
||||||
t.Errorf("TxSha: wrong hash - got %v, want %v",
|
t.Errorf("TxHash: wrong hash - got %v, want %v",
|
||||||
spew.Sprint(txHash), spew.Sprint(wantHash))
|
spew.Sprint(txHash), spew.Sprint(wantHash))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -645,7 +646,7 @@ var multiTx = &MsgTx{
|
||||||
TxIn: []*TxIn{
|
TxIn: []*TxIn{
|
||||||
{
|
{
|
||||||
PreviousOutPoint: OutPoint{
|
PreviousOutPoint: OutPoint{
|
||||||
Hash: ShaHash{},
|
Hash: chainhash.Hash{},
|
||||||
Index: 0xffffffff,
|
Index: 0xffffffff,
|
||||||
},
|
},
|
||||||
SignatureScript: []byte{
|
SignatureScript: []byte{
|
||||||
|
|
111
wire/shahash.go
111
wire/shahash.go
|
@ -1,111 +0,0 @@
|
||||||
// Copyright (c) 2013-2015 The btcsuite developers
|
|
||||||
// Use of this source code is governed by an ISC
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package wire
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/hex"
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
// HashSize is the array size used to store sha hashes. See ShaHash.
|
|
||||||
const HashSize = 32
|
|
||||||
|
|
||||||
// MaxHashStringSize is the maximum length of a ShaHash hash string.
|
|
||||||
const MaxHashStringSize = HashSize * 2
|
|
||||||
|
|
||||||
// ErrHashStrSize describes an error that indicates the caller specified a hash
|
|
||||||
// string that has too many characters.
|
|
||||||
var ErrHashStrSize = fmt.Errorf("max hash string length is %v bytes", MaxHashStringSize)
|
|
||||||
|
|
||||||
// ShaHash is used in several of the bitcoin messages and common structures. It
|
|
||||||
// typically represents the double sha256 of data.
|
|
||||||
type ShaHash [HashSize]byte
|
|
||||||
|
|
||||||
// String returns the ShaHash as the hexadecimal string of the byte-reversed
|
|
||||||
// hash.
|
|
||||||
func (hash ShaHash) String() string {
|
|
||||||
for i := 0; i < HashSize/2; i++ {
|
|
||||||
hash[i], hash[HashSize-1-i] = hash[HashSize-1-i], hash[i]
|
|
||||||
}
|
|
||||||
return hex.EncodeToString(hash[:])
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bytes returns the bytes which represent the hash as a byte slice.
|
|
||||||
//
|
|
||||||
// NOTE: This makes a copy of the bytes and should have probably been named
|
|
||||||
// CloneBytes. It is generally cheaper to just slice the hash directly thereby
|
|
||||||
// reusing the same bytes rather than calling this method.
|
|
||||||
func (hash *ShaHash) Bytes() []byte {
|
|
||||||
newHash := make([]byte, HashSize)
|
|
||||||
copy(newHash, hash[:])
|
|
||||||
|
|
||||||
return newHash
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetBytes sets the bytes which represent the hash. An error is returned if
|
|
||||||
// the number of bytes passed in is not HashSize.
|
|
||||||
func (hash *ShaHash) SetBytes(newHash []byte) error {
|
|
||||||
nhlen := len(newHash)
|
|
||||||
if nhlen != HashSize {
|
|
||||||
return fmt.Errorf("invalid sha length of %v, want %v", nhlen,
|
|
||||||
HashSize)
|
|
||||||
}
|
|
||||||
copy(hash[:], newHash)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsEqual returns true if target is the same as hash.
|
|
||||||
func (hash *ShaHash) IsEqual(target *ShaHash) bool {
|
|
||||||
return *hash == *target
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewShaHash returns a new ShaHash from a byte slice. An error is returned if
|
|
||||||
// the number of bytes passed in is not HashSize.
|
|
||||||
func NewShaHash(newHash []byte) (*ShaHash, error) {
|
|
||||||
var sh ShaHash
|
|
||||||
err := sh.SetBytes(newHash)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &sh, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewShaHashFromStr creates a ShaHash from a hash string. The string should be
|
|
||||||
// the hexadecimal string of a byte-reversed hash, but any missing characters
|
|
||||||
// result in zero padding at the end of the ShaHash.
|
|
||||||
func NewShaHashFromStr(hash string) (*ShaHash, error) {
|
|
||||||
// Return error if hash string is too long.
|
|
||||||
if len(hash) > MaxHashStringSize {
|
|
||||||
return nil, ErrHashStrSize
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hex decoder expects the hash to be a multiple of two.
|
|
||||||
if len(hash)%2 != 0 {
|
|
||||||
hash = "0" + hash
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert string hash to bytes.
|
|
||||||
buf, err := hex.DecodeString(hash)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Un-reverse the decoded bytes, copying into in leading bytes of a
|
|
||||||
// ShaHash. There is no need to explicitly pad the result as any
|
|
||||||
// missing (when len(buf) < HashSize) bytes from the decoded hex string
|
|
||||||
// will remain zeros at the end of the ShaHash.
|
|
||||||
var ret ShaHash
|
|
||||||
blen := len(buf)
|
|
||||||
mid := blen / 2
|
|
||||||
if blen%2 != 0 {
|
|
||||||
mid++
|
|
||||||
}
|
|
||||||
blen--
|
|
||||||
for i, b := range buf[:mid] {
|
|
||||||
ret[i], ret[blen-i] = buf[blen-i], b
|
|
||||||
}
|
|
||||||
return &ret, nil
|
|
||||||
}
|
|
|
@ -1,180 +0,0 @@
|
||||||
// Copyright (c) 2013-2016 The btcsuite developers
|
|
||||||
// Use of this source code is governed by an ISC
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package wire
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/hex"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
// TestShaHash tests the ShaHash API.
|
|
||||||
func TestShaHash(t *testing.T) {
|
|
||||||
|
|
||||||
// Hash of block 234439.
|
|
||||||
blockHashStr := "14a0810ac680a3eb3f82edc878cea25ec41d6b790744e5daeef"
|
|
||||||
blockHash, err := NewShaHashFromStr(blockHashStr)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("NewShaHashFromStr: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hash of block 234440 as byte slice.
|
|
||||||
buf := []byte{
|
|
||||||
0x79, 0xa6, 0x1a, 0xdb, 0xc6, 0xe5, 0xa2, 0xe1,
|
|
||||||
0x39, 0xd2, 0x71, 0x3a, 0x54, 0x6e, 0xc7, 0xc8,
|
|
||||||
0x75, 0x63, 0x2e, 0x75, 0xf1, 0xdf, 0x9c, 0x3f,
|
|
||||||
0xa6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
}
|
|
||||||
|
|
||||||
hash, err := NewShaHash(buf)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("NewShaHash: unexpected error %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure proper size.
|
|
||||||
if len(hash) != HashSize {
|
|
||||||
t.Errorf("NewShaHash: hash length mismatch - got: %v, want: %v",
|
|
||||||
len(hash), HashSize)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure contents match.
|
|
||||||
if !bytes.Equal(hash[:], buf) {
|
|
||||||
t.Errorf("NewShaHash: hash contents mismatch - got: %v, want: %v",
|
|
||||||
hash[:], buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure contents of hash of block 234440 don't match 234439.
|
|
||||||
if hash.IsEqual(blockHash) {
|
|
||||||
t.Errorf("IsEqual: hash contents should not match - got: %v, want: %v",
|
|
||||||
hash, blockHash)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set hash from byte slice and ensure contents match.
|
|
||||||
err = hash.SetBytes(blockHash.Bytes())
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("SetBytes: %v", err)
|
|
||||||
}
|
|
||||||
if !hash.IsEqual(blockHash) {
|
|
||||||
t.Errorf("IsEqual: hash contents mismatch - got: %v, want: %v",
|
|
||||||
hash, blockHash)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Invalid size for SetBytes.
|
|
||||||
err = hash.SetBytes([]byte{0x00})
|
|
||||||
if err == nil {
|
|
||||||
t.Errorf("SetBytes: failed to received expected err - got: nil")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Invalid size for NewShaHash.
|
|
||||||
invalidHash := make([]byte, HashSize+1)
|
|
||||||
_, err = NewShaHash(invalidHash)
|
|
||||||
if err == nil {
|
|
||||||
t.Errorf("NewShaHash: failed to received expected err - got: nil")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestShaHashString tests the stringized output for sha hashes.
|
|
||||||
func TestShaHashString(t *testing.T) {
|
|
||||||
// Block 100000 hash.
|
|
||||||
wantStr := "000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506"
|
|
||||||
hash := ShaHash([HashSize]byte{ // Make go vet happy.
|
|
||||||
0x06, 0xe5, 0x33, 0xfd, 0x1a, 0xda, 0x86, 0x39,
|
|
||||||
0x1f, 0x3f, 0x6c, 0x34, 0x32, 0x04, 0xb0, 0xd2,
|
|
||||||
0x78, 0xd4, 0xaa, 0xec, 0x1c, 0x0b, 0x20, 0xaa,
|
|
||||||
0x27, 0xba, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
})
|
|
||||||
|
|
||||||
hashStr := hash.String()
|
|
||||||
if hashStr != wantStr {
|
|
||||||
t.Errorf("String: wrong hash string - got %v, want %v",
|
|
||||||
hashStr, wantStr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestNewShaHashFromStr executes tests against the NewShaHashFromStr function.
|
|
||||||
func TestNewShaHashFromStr(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
in string
|
|
||||||
want ShaHash
|
|
||||||
err error
|
|
||||||
}{
|
|
||||||
// Genesis hash.
|
|
||||||
{
|
|
||||||
"000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",
|
|
||||||
mainNetGenesisHash,
|
|
||||||
nil,
|
|
||||||
},
|
|
||||||
|
|
||||||
// Genesis hash with stripped leading zeros.
|
|
||||||
{
|
|
||||||
"19d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",
|
|
||||||
mainNetGenesisHash,
|
|
||||||
nil,
|
|
||||||
},
|
|
||||||
|
|
||||||
// Empty string.
|
|
||||||
{
|
|
||||||
"",
|
|
||||||
ShaHash{},
|
|
||||||
nil,
|
|
||||||
},
|
|
||||||
|
|
||||||
// Single digit hash.
|
|
||||||
{
|
|
||||||
"1",
|
|
||||||
ShaHash([HashSize]byte{ // Make go vet happy.
|
|
||||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
}),
|
|
||||||
nil,
|
|
||||||
},
|
|
||||||
|
|
||||||
// Block 203707 with stripped leading zeros.
|
|
||||||
{
|
|
||||||
"3264bc2ac36a60840790ba1d475d01367e7c723da941069e9dc",
|
|
||||||
ShaHash([HashSize]byte{ // Make go vet happy.
|
|
||||||
0xdc, 0xe9, 0x69, 0x10, 0x94, 0xda, 0x23, 0xc7,
|
|
||||||
0xe7, 0x67, 0x13, 0xd0, 0x75, 0xd4, 0xa1, 0x0b,
|
|
||||||
0x79, 0x40, 0x08, 0xa6, 0x36, 0xac, 0xc2, 0x4b,
|
|
||||||
0x26, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
}),
|
|
||||||
nil,
|
|
||||||
},
|
|
||||||
|
|
||||||
// Hash string that is too long.
|
|
||||||
{
|
|
||||||
"01234567890123456789012345678901234567890123456789012345678912345",
|
|
||||||
ShaHash{},
|
|
||||||
ErrHashStrSize,
|
|
||||||
},
|
|
||||||
|
|
||||||
// Hash string that is contains non-hex chars.
|
|
||||||
{
|
|
||||||
"abcdefg",
|
|
||||||
ShaHash{},
|
|
||||||
hex.InvalidByteError('g'),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
unexpectedErrStr := "NewShaHashFromStr #%d failed to detect expected error - got: %v want: %v"
|
|
||||||
unexpectedResultStr := "NewShaHashFromStr #%d got: %v want: %v"
|
|
||||||
t.Logf("Running %d tests", len(tests))
|
|
||||||
for i, test := range tests {
|
|
||||||
result, err := NewShaHashFromStr(test.in)
|
|
||||||
if err != test.err {
|
|
||||||
t.Errorf(unexpectedErrStr, i, err, test.err)
|
|
||||||
continue
|
|
||||||
} else if err != nil {
|
|
||||||
// Got expected error. Move on to the next test.
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if !test.want.IsEqual(result) {
|
|
||||||
t.Errorf(unexpectedResultStr, i, result, &test.want)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in a new issue