[NOD-101] Create a bucket for utxo diffs (#245)

* [NOD-101] Create a bucket for utxo diffs

* [NOD-101] Add error when diff data is not found

* [NOD-101] Fix serialization comment
This commit is contained in:
Ori Newman 2019-04-11 16:09:44 +03:00 committed by Svarog
parent 9276494820
commit 1a2166cddf
37 changed files with 684 additions and 252 deletions

View File

@ -150,6 +150,7 @@ type BlockDAG struct {
lastFinalityPoint *blockNode lastFinalityPoint *blockNode
SubnetworkStore *SubnetworkStore SubnetworkStore *SubnetworkStore
utxoDiffStore *utxoDiffStore
} }
// HaveBlock returns whether or not the DAG instance has the block represented // HaveBlock returns whether or not the DAG instance has the block represented
@ -550,12 +551,6 @@ func (dag *BlockDAG) connectBlock(node *blockNode, block *util.Block, fastAdd bo
panic(err) panic(err)
} }
// Write any block status changes to DB before updating the DAG state.
err = dag.index.flushToDB()
if err != nil {
return err
}
err = dag.saveChangesFromBlock(node, block, virtualUTXODiff, txsAcceptanceData, newBlockFeeData) err = dag.saveChangesFromBlock(node, block, virtualUTXODiff, txsAcceptanceData, newBlockFeeData)
if err != nil { if err != nil {
return err return err
@ -567,14 +562,25 @@ func (dag *BlockDAG) connectBlock(node *blockNode, block *util.Block, fastAdd bo
func (dag *BlockDAG) saveChangesFromBlock(node *blockNode, block *util.Block, virtualUTXODiff *UTXODiff, func (dag *BlockDAG) saveChangesFromBlock(node *blockNode, block *util.Block, virtualUTXODiff *UTXODiff,
txsAcceptanceData MultiBlockTxsAcceptanceData, feeData compactFeeData) error { txsAcceptanceData MultiBlockTxsAcceptanceData, feeData compactFeeData) error {
// Write any block status changes to DB before updating the DAG state.
err := dag.index.flushToDB()
if err != nil {
return err
}
// Atomically insert info into the database. // Atomically insert info into the database.
return dag.db.Update(func(dbTx database.Tx) error { err = dag.db.Update(func(dbTx database.Tx) error {
err := dag.utxoDiffStore.flushToDB(dbTx)
if err != nil {
return err
}
// Update best block state. // Update best block state.
state := &dagState{ state := &dagState{
TipHashes: dag.TipHashes(), TipHashes: dag.TipHashes(),
LastFinalityPoint: dag.lastFinalityPoint.hash, LastFinalityPoint: dag.lastFinalityPoint.hash,
} }
err := dbPutDAGState(dbTx, state) err = dbPutDAGState(dbTx, state)
if err != nil { if err != nil {
return err return err
} }
@ -614,6 +620,11 @@ func (dag *BlockDAG) saveChangesFromBlock(node *blockNode, block *util.Block, vi
// Apply the fee data into the database // Apply the fee data into the database
return dbStoreFeeData(dbTx, block.Hash(), feeData) return dbStoreFeeData(dbTx, block.Hash(), feeData)
}) })
if err != nil {
return err
}
dag.utxoDiffStore.clearDirtyEntries()
return nil
} }
func (dag *BlockDAG) validateGasLimit(block *util.Block) error { func (dag *BlockDAG) validateGasLimit(block *util.Block) error {
@ -732,7 +743,7 @@ func (dag *BlockDAG) NextBlockFeeTransaction() (*wire.MsgTx, error) {
func (dag *BlockDAG) applyDAGChanges(node *blockNode, block *util.Block, newBlockUTXO UTXOSet, fastAdd bool) ( func (dag *BlockDAG) applyDAGChanges(node *blockNode, block *util.Block, newBlockUTXO UTXOSet, fastAdd bool) (
virtualUTXODiff *UTXODiff, err error) { virtualUTXODiff *UTXODiff, err error) {
if err = node.updateParents(dag.virtual, newBlockUTXO); err != nil { if err = node.updateParents(dag, newBlockUTXO); err != nil {
return nil, fmt.Errorf("failed updating parents of %s: %s", node, err) return nil, fmt.Errorf("failed updating parents of %s: %s", node, err)
} }
@ -740,13 +751,13 @@ func (dag *BlockDAG) applyDAGChanges(node *blockNode, block *util.Block, newBloc
dag.virtual.AddTip(node) dag.virtual.AddTip(node)
// Build a UTXO set for the new virtual block // Build a UTXO set for the new virtual block
newVirtualUTXO, _, err := dag.virtual.blockNode.pastUTXO(dag.virtual, dag.db) newVirtualUTXO, _, err := dag.virtual.blockNode.pastUTXO(dag)
if err != nil { if err != nil {
return nil, fmt.Errorf("could not restore past UTXO for virtual %s: %s", dag.virtual, err) return nil, fmt.Errorf("could not restore past UTXO for virtual %s: %s", dag.virtual, err)
} }
// Apply new utxoDiffs to all the tips // Apply new utxoDiffs to all the tips
err = updateTipsUTXO(dag.virtual.parents, dag.virtual, newVirtualUTXO) err = updateTipsUTXO(dag, newVirtualUTXO)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed updating the tips' UTXO: %s", err) return nil, fmt.Errorf("failed updating the tips' UTXO: %s", err)
} }
@ -756,11 +767,6 @@ func (dag *BlockDAG) applyDAGChanges(node *blockNode, block *util.Block, newBloc
virtualUTXODiff = diffSet.UTXODiff virtualUTXODiff = diffSet.UTXODiff
dag.meldVirtualUTXO(diffSet) dag.meldVirtualUTXO(diffSet)
// Set the status to valid for all index nodes to make sure the changes get
// written to the database.
for _, p := range node.parents {
dag.index.SetStatusFlags(p, statusValid)
}
dag.index.SetStatusFlags(node, statusValid) dag.index.SetStatusFlags(node, statusValid)
// And now we can update the finality point of the DAG (if required) // And now we can update the finality point of the DAG (if required)
@ -808,7 +814,7 @@ func (node *blockNode) addTxsToAcceptanceData(txsAcceptanceData MultiBlockTxsAcc
func (node *blockNode) verifyAndBuildUTXO(dag *BlockDAG, transactions []*util.Tx, fastAdd bool) ( func (node *blockNode) verifyAndBuildUTXO(dag *BlockDAG, transactions []*util.Tx, fastAdd bool) (
newBlockUTXO UTXOSet, txsAcceptanceData MultiBlockTxsAcceptanceData, newBlockFeeData compactFeeData, err error) { newBlockUTXO UTXOSet, txsAcceptanceData MultiBlockTxsAcceptanceData, newBlockFeeData compactFeeData, err error) {
pastUTXO, txsAcceptanceData, err := node.pastUTXO(dag.virtual, dag.db) pastUTXO, txsAcceptanceData, err := node.pastUTXO(dag)
if err != nil { if err != nil {
return nil, nil, nil, err return nil, nil, nil, err
} }
@ -910,18 +916,18 @@ func (node *blockNode) applyBlueBlocks(selectedParentUTXO UTXOSet, blueBlocks []
// pastUTXO returns the UTXO of a given block's past // pastUTXO returns the UTXO of a given block's past
// To save traversals over the blue blocks, it also returns the transaction acceptance data for // To save traversals over the blue blocks, it also returns the transaction acceptance data for
// all blue blocks // all blue blocks
func (node *blockNode) pastUTXO(virtual *virtualBlock, db database.DB) ( func (node *blockNode) pastUTXO(dag *BlockDAG) (
pastUTXO UTXOSet, bluesTxsAcceptanceData MultiBlockTxsAcceptanceData, err error) { pastUTXO UTXOSet, bluesTxsAcceptanceData MultiBlockTxsAcceptanceData, err error) {
if node.isGenesis() { if node.isGenesis() {
return genesisPastUTXO(virtual), MultiBlockTxsAcceptanceData{}, nil return genesisPastUTXO(dag.virtual), MultiBlockTxsAcceptanceData{}, nil
} }
selectedParentUTXO, err := node.selectedParent.restoreUTXO(virtual) selectedParentUTXO, err := node.selectedParent.restoreUTXO(dag)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
blueBlocks, err := node.fetchBlueBlocks(db) blueBlocks, err := node.fetchBlueBlocks(dag.db)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
@ -930,20 +936,26 @@ func (node *blockNode) pastUTXO(virtual *virtualBlock, db database.DB) (
} }
// restoreUTXO restores the UTXO of a given block from its diff // restoreUTXO restores the UTXO of a given block from its diff
func (node *blockNode) restoreUTXO(virtual *virtualBlock) (UTXOSet, error) { func (node *blockNode) restoreUTXO(dag *BlockDAG) (UTXOSet, error) {
stack := []*blockNode{node} stack := []*blockNode{}
current := node
for current.diffChild != nil { for current := node; current != nil; {
current = current.diffChild
stack = append(stack, current) stack = append(stack, current)
var err error
current, err = dag.utxoDiffStore.diffChildByNode(current)
if err != nil {
return nil, err
}
} }
utxo := UTXOSet(virtual.utxoSet) utxo := UTXOSet(dag.virtual.utxoSet)
var err error
for i := len(stack) - 1; i >= 0; i-- { for i := len(stack) - 1; i >= 0; i-- {
utxo, err = utxo.WithDiff(stack[i].diff) diff, err := dag.utxoDiffStore.diffByNode(stack[i])
if err != nil {
return nil, err
}
utxo, err = utxo.WithDiff(diff)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -954,31 +966,39 @@ func (node *blockNode) restoreUTXO(virtual *virtualBlock) (UTXOSet, error) {
// updateParents adds this block to the children sets of its parents // updateParents adds this block to the children sets of its parents
// and updates the diff of any parent whose DiffChild is this block // and updates the diff of any parent whose DiffChild is this block
func (node *blockNode) updateParents(virtual *virtualBlock, newBlockUTXO UTXOSet) error { func (node *blockNode) updateParents(dag *BlockDAG, newBlockUTXO UTXOSet) error {
node.updateParentsChildren() node.updateParentsChildren()
return node.updateParentsDiffs(virtual, newBlockUTXO) return node.updateParentsDiffs(dag, newBlockUTXO)
} }
// updateParentsDiffs updates the diff of any parent whose DiffChild is this block // updateParentsDiffs updates the diff of any parent whose DiffChild is this block
func (node *blockNode) updateParentsDiffs(virtual *virtualBlock, newBlockUTXO UTXOSet) error { func (node *blockNode) updateParentsDiffs(dag *BlockDAG, newBlockUTXO UTXOSet) error {
virtualDiffFromNewBlock, err := virtual.utxoSet.diffFrom(newBlockUTXO) virtualDiffFromNewBlock, err := dag.virtual.utxoSet.diffFrom(newBlockUTXO)
if err != nil { if err != nil {
return err return err
} }
node.diff = virtualDiffFromNewBlock err = dag.utxoDiffStore.setBlockDiff(node, virtualDiffFromNewBlock)
if err != nil {
return err
}
for _, parent := range node.parents { for _, parent := range node.parents {
if parent.diffChild == nil { diffChild, err := dag.utxoDiffStore.diffChildByNode(parent)
parentUTXO, err := parent.restoreUTXO(virtual)
if err != nil { if err != nil {
return err return err
} }
parent.diffChild = node if diffChild == nil {
parent.diff, err = newBlockUTXO.diffFrom(parentUTXO) parentUTXO, err := parent.restoreUTXO(dag)
if err != nil { if err != nil {
return err return err
} }
dag.utxoDiffStore.setBlockDiffChild(parent, node)
diff, err := newBlockUTXO.diffFrom(parentUTXO)
if err != nil {
return err
}
dag.utxoDiffStore.setBlockDiff(parent, diff)
} }
} }
@ -986,16 +1006,17 @@ func (node *blockNode) updateParentsDiffs(virtual *virtualBlock, newBlockUTXO UT
} }
// updateTipsUTXO builds and applies new diff UTXOs for all the DAG's tips // updateTipsUTXO builds and applies new diff UTXOs for all the DAG's tips
func updateTipsUTXO(tips blockSet, virtual *virtualBlock, virtualUTXO UTXOSet) error { func updateTipsUTXO(dag *BlockDAG, virtualUTXO UTXOSet) error {
for _, tip := range tips { for _, tip := range dag.virtual.parents {
tipUTXO, err := tip.restoreUTXO(virtual) tipUTXO, err := tip.restoreUTXO(dag)
if err != nil { if err != nil {
return err return err
} }
tip.diff, err = virtualUTXO.diffFrom(tipUTXO) diff, err := virtualUTXO.diffFrom(tipUTXO)
if err != nil { if err != nil {
return err return err
} }
dag.utxoDiffStore.setBlockDiff(tip, diff)
} }
return nil return nil
@ -1670,6 +1691,8 @@ func New(config *Config) (*BlockDAG, error) {
subnetworkID: config.SubnetworkID, subnetworkID: config.SubnetworkID,
} }
dag.utxoDiffStore = newUTXODiffStore(&dag)
// Initialize the chain state from the passed database. When the db // Initialize the chain state from the passed database. When the db
// does not yet contain any DAG state, both it and the DAG state // does not yet contain any DAG state, both it and the DAG state
// will be initialized to contain only the genesis block. // will be initialized to contain only the genesis block.

View File

@ -54,6 +54,10 @@ var (
// unspent transaction output set. // unspent transaction output set.
utxoSetBucketName = []byte("utxoset") utxoSetBucketName = []byte("utxoset")
// utxoDiffsBucketName is the name of the db bucket used to house the
// diffs and diff children of blocks.
utxoDiffsBucketName = []byte("utxodiffs")
// subnetworksBucketName is the name of the db bucket used to store the // subnetworksBucketName is the name of the db bucket used to store the
// subnetwork registry. // subnetwork registry.
subnetworksBucketName = []byte("subnetworks") subnetworksBucketName = []byte("subnetworks")
@ -466,14 +470,18 @@ func (dag *BlockDAG) createDAGState() error {
return err return err
} }
// Create the bucket that houses the utxo set and store its // Create the buckets that house the utxo set, the utxo diffs, and their
// version. Note that the genesis block coinbase transaction is // version.
// intentionally not inserted here since it is not spendable by
// consensus rules.
_, err = meta.CreateBucket(utxoSetBucketName) _, err = meta.CreateBucket(utxoSetBucketName)
if err != nil { if err != nil {
return err return err
} }
_, err = meta.CreateBucket(utxoDiffsBucketName)
if err != nil {
return err
}
err = dbPutVersion(dbTx, utxoSetVersionKeyName, err = dbPutVersion(dbTx, utxoSetVersionKeyName,
latestUTXOSetBucketVersion) latestUTXOSetBucketVersion)
if err != nil { if err != nil {
@ -608,6 +616,7 @@ func (dag *BlockDAG) initDAGState() error {
node := &blockNodes[i] node := &blockNodes[i]
initBlockNode(node, header, parents, dag.dagParams.K) initBlockNode(node, header, parents, dag.dagParams.K)
node.status = status node.status = status
node.updateParentsChildren()
dag.index.addNode(node) dag.index.addNode(node)
if blockStatus(status).KnownValid() { if blockStatus(status).KnownValid() {

View File

@ -197,7 +197,7 @@ func GetVirtualFromParentsForTest(dag *BlockDAG, parentHashes []*daghash.Hash) (
} }
virtual := newVirtualBlock(parents, dag.dagParams.K) virtual := newVirtualBlock(parents, dag.dagParams.K)
pastUTXO, _, err := virtual.pastUTXO(dag.virtual, dag.db) pastUTXO, _, err := virtual.pastUTXO(dag)
if err != nil { if err != nil {
return nil, err return nil, err
} }

321
blockdag/utxodiffstore.go Normal file
View File

@ -0,0 +1,321 @@
package blockdag
import (
"bytes"
"encoding/binary"
"fmt"
"io"
"sync"
"github.com/daglabs/btcd/dagconfig/daghash"
"github.com/daglabs/btcd/database"
"github.com/daglabs/btcd/wire"
)
type blockUTXODiffData struct {
diff *UTXODiff
diffChild *blockNode
}
type utxoDiffStore struct {
dag *BlockDAG
dirty map[daghash.Hash]struct{}
loaded map[daghash.Hash]*blockUTXODiffData
mtx sync.RWMutex
}
func newUTXODiffStore(dag *BlockDAG) *utxoDiffStore {
return &utxoDiffStore{
dag: dag,
dirty: make(map[daghash.Hash]struct{}),
loaded: make(map[daghash.Hash]*blockUTXODiffData),
}
}
func (diffStore *utxoDiffStore) setBlockDiff(node *blockNode, diff *UTXODiff) error {
diffStore.mtx.Lock()
defer diffStore.mtx.Unlock()
// load the diff data from DB to diffStore.loaded
_, exists, err := diffStore.diffDataByHash(node.hash)
if err != nil {
return err
}
if !exists {
diffStore.loaded[*node.hash] = &blockUTXODiffData{}
}
diffStore.loaded[*node.hash].diff = diff
diffStore.setBlockAsDirty(node.hash)
return nil
}
func (diffStore *utxoDiffStore) setBlockDiffChild(node *blockNode, diffChild *blockNode) error {
diffStore.mtx.Lock()
defer diffStore.mtx.Unlock()
// load the diff data from DB to diffStore.loaded
_, exists, err := diffStore.diffDataByHash(node.hash)
if err != nil {
return err
}
if !exists {
return diffNotFoundError(node)
}
diffStore.loaded[*node.hash].diffChild = diffChild
diffStore.setBlockAsDirty(node.hash)
return nil
}
func (diffStore *utxoDiffStore) setBlockAsDirty(blockHash *daghash.Hash) {
diffStore.dirty[*blockHash] = struct{}{}
}
func (diffStore *utxoDiffStore) diffDataByHash(hash *daghash.Hash) (*blockUTXODiffData, bool, error) {
if diffData, ok := diffStore.loaded[*hash]; ok {
return diffData, true, nil
}
diffData, err := diffStore.diffDataFromDB(hash)
if err != nil {
return nil, false, err
}
exists := diffData != nil
if exists {
diffStore.loaded[*hash] = diffData
}
return diffData, exists, nil
}
func diffNotFoundError(node *blockNode) error {
return fmt.Errorf("Couldn't find diff data for block %s", node.hash)
}
func (diffStore *utxoDiffStore) diffByNode(node *blockNode) (*UTXODiff, error) {
diffStore.mtx.RLock()
defer diffStore.mtx.RUnlock()
diffData, exists, err := diffStore.diffDataByHash(node.hash)
if err != nil {
return nil, err
}
if !exists {
return nil, diffNotFoundError(node)
}
return diffData.diff, nil
}
func (diffStore *utxoDiffStore) diffChildByNode(node *blockNode) (*blockNode, error) {
diffStore.mtx.RLock()
defer diffStore.mtx.RUnlock()
diffData, exists, err := diffStore.diffDataByHash(node.hash)
if err != nil {
return nil, err
}
if !exists {
return nil, diffNotFoundError(node)
}
return diffData.diffChild, nil
}
func (diffStore *utxoDiffStore) diffDataFromDB(hash *daghash.Hash) (*blockUTXODiffData, error) {
var diffData *blockUTXODiffData
err := diffStore.dag.db.View(func(dbTx database.Tx) error {
bucket := dbTx.Metadata().Bucket(utxoDiffsBucketName)
serializedBlockDiffData := bucket.Get(hash[:])
if serializedBlockDiffData != nil {
var err error
diffData, err = diffStore.deserializeBlockUTXODiffData(serializedBlockDiffData)
return err
}
return nil
})
if err != nil {
return nil, err
}
return diffData, nil
}
func (diffStore *utxoDiffStore) deserializeBlockUTXODiffData(serializedDiffDataBytes []byte) (*blockUTXODiffData, error) {
diffData := &blockUTXODiffData{}
serializedDiffData := bytes.NewBuffer(serializedDiffDataBytes)
var hasDiffChild bool
err := wire.ReadElement(serializedDiffData, &hasDiffChild)
if err != nil {
return nil, err
}
if hasDiffChild {
hash := &daghash.Hash{}
err := wire.ReadElement(serializedDiffData, hash)
if err != nil {
return nil, err
}
diffData.diffChild = diffStore.dag.index.LookupNode(hash)
}
diffData.diff = &UTXODiff{}
diffData.diff.toAdd, err = deserializeDiffEntries(serializedDiffData)
if err != nil {
return nil, err
}
diffData.diff.toRemove, err = deserializeDiffEntries(serializedDiffData)
if err != nil {
return nil, err
}
return diffData, nil
}
func deserializeDiffEntries(r io.Reader) (utxoCollection, error) {
count, err := wire.ReadVarInt(r)
if err != nil {
return nil, err
}
collection := utxoCollection{}
for i := uint64(0); i < count; i++ {
outPointSize, err := wire.ReadVarInt(r)
if err != nil {
return nil, err
}
serializedOutPoint := make([]byte, outPointSize)
err = binary.Read(r, byteOrder, serializedOutPoint)
if err != nil {
return nil, err
}
outPoint, err := deserializeOutPoint(serializedOutPoint)
if err != nil {
return nil, err
}
utxoEntrySize, err := wire.ReadVarInt(r)
if err != nil {
return nil, err
}
serializedEntry := make([]byte, utxoEntrySize)
err = binary.Read(r, byteOrder, serializedEntry)
if err != nil {
return nil, err
}
utxoEntry, err := deserializeUTXOEntry(serializedEntry)
if err != nil {
return nil, err
}
collection.add(*outPoint, utxoEntry)
}
return collection, nil
}
// serializeBlockUTXODiffData serializes diff data in the following format:
// Name | Data type | Description
// ------------ | --------- | -----------
// hasDiffChild | Boolean | Indicates if a diff child exist
// diffChild | Hash | The diffChild's hash. Empty if hasDiffChild is true.
// diff | UTXODiff | The diff data's diff
func serializeBlockUTXODiffData(diffData *blockUTXODiffData) ([]byte, error) {
w := &bytes.Buffer{}
hasDiffChild := diffData.diffChild != nil
err := wire.WriteElement(w, hasDiffChild)
if err != nil {
return nil, err
}
if hasDiffChild {
err := wire.WriteElement(w, diffData.diffChild.hash)
if err != nil {
return nil, err
}
}
err = serializeUTXODiff(w, diffData.diff)
if err != nil {
return nil, err
}
return w.Bytes(), nil
}
// serializeUTXODiff serializes UTXODiff by serializing
// UTXODiff.toAdd and UTXODiff.toRemove one after the other.
func serializeUTXODiff(w io.Writer, diff *UTXODiff) error {
err := serializeUTXOCollection(w, diff.toAdd)
if err != nil {
return err
}
err = serializeUTXOCollection(w, diff.toRemove)
if err != nil {
return err
}
return nil
}
// serializeUTXOCollection serializes utxoCollection by iterating over
// the utxo entries and serializing them and their corresponding outpoint
// prefixed by a varint that indicates their size.
func serializeUTXOCollection(w io.Writer, collection utxoCollection) error {
err := wire.WriteVarInt(w, uint64(len(collection)))
if err != nil {
return err
}
for outPoint, utxoEntry := range collection {
serializedOutPoint := *outpointKey(outPoint)
err = wire.WriteVarInt(w, uint64(len(serializedOutPoint)))
if err != nil {
return err
}
err := binary.Write(w, byteOrder, serializedOutPoint)
if err != nil {
return err
}
serializedUTXOEntry, err := serializeUTXOEntry(utxoEntry)
if err != nil {
return err
}
err = wire.WriteVarInt(w, uint64(len(serializedUTXOEntry)))
if err != nil {
return err
}
err = binary.Write(w, byteOrder, serializedUTXOEntry)
if err != nil {
return err
}
}
return nil
}
// flushToDB writes all dirty diff data to the database. If all writes
// succeed, this clears the dirty set.
func (diffStore *utxoDiffStore) flushToDB(dbTx database.Tx) error {
diffStore.mtx.Lock()
defer diffStore.mtx.Unlock()
if len(diffStore.dirty) == 0 {
return nil
}
for hash := range diffStore.dirty {
diffData := diffStore.loaded[hash]
err := dbStoreDiffData(dbTx, &hash, diffData)
if err != nil {
return err
}
}
return nil
}
func (diffStore *utxoDiffStore) clearDirtyEntries() {
diffStore.dirty = make(map[daghash.Hash]struct{})
}
// dbStoreDiffData stores the UTXO diff data to the database.
// This overwrites the current entry if there exists one.
func dbStoreDiffData(dbTx database.Tx, hash *daghash.Hash, diffData *blockUTXODiffData) error {
serializedDiffData, err := serializeBlockUTXODiffData(diffData)
if err != nil {
return err
}
return dbTx.Metadata().Bucket(utxoDiffsBucketName).Put(hash[:], serializedDiffData)
}

View File

@ -0,0 +1,87 @@
package blockdag
import (
"fmt"
"reflect"
"testing"
"github.com/daglabs/btcd/dagconfig"
"github.com/daglabs/btcd/dagconfig/daghash"
"github.com/daglabs/btcd/database"
"github.com/daglabs/btcd/wire"
)
func TestUTXODiffStore(t *testing.T) {
// Create a new database and DAG instance to run tests against.
dag, teardownFunc, err := DAGSetup("TestUTXODiffStore", Config{
DAGParams: &dagconfig.SimNetParams,
})
if err != nil {
t.Fatalf("TestUTXODiffStore: Failed to setup DAG instance: %v", err)
}
defer teardownFunc()
nodeCounter := byte(0)
createNode := func() *blockNode {
nodeCounter++
node := &blockNode{hash: &daghash.Hash{nodeCounter}}
dag.index.AddNode(node)
return node
}
// Check that an error is returned when asking for non existing node
nonExistingNode := createNode()
_, err = dag.utxoDiffStore.diffByNode(nonExistingNode)
expectedErrString := fmt.Sprintf("Couldn't find diff data for block %s", nonExistingNode.hash)
if err == nil || err.Error() != expectedErrString {
t.Errorf("diffByNode: expected error %s but got %s", expectedErrString, err)
}
// Add node's diff data to the utxoDiffStore and check if it's checked correctly.
node := createNode()
diff := NewUTXODiff()
diff.toAdd.add(wire.OutPoint{TxID: daghash.TxID{0x01}, Index: 0}, &UTXOEntry{amount: 1, pkScript: []byte{0x01}})
diff.toRemove.add(wire.OutPoint{TxID: daghash.TxID{0x02}, Index: 0}, &UTXOEntry{amount: 2, pkScript: []byte{0x02}})
if err := dag.utxoDiffStore.setBlockDiff(node, diff); err != nil {
t.Fatalf("setBlockDiff: unexpected error: %s", err)
}
diffChild := createNode()
if err := dag.utxoDiffStore.setBlockDiffChild(node, diffChild); err != nil {
t.Fatalf("setBlockDiffChild: unexpected error: %s", err)
}
if storeDiff, err := dag.utxoDiffStore.diffByNode(node); err != nil {
t.Fatalf("diffByNode: unexpected error: %s", err)
} else if !reflect.DeepEqual(storeDiff, diff) {
t.Errorf("Expected diff and storeDiff to be equal")
}
if storeDiffChild, err := dag.utxoDiffStore.diffChildByNode(node); err != nil {
t.Fatalf("diffByNode: unexpected error: %s", err)
} else if !reflect.DeepEqual(storeDiffChild, diffChild) {
t.Errorf("Expected diff and storeDiff to be equal")
}
// Flush changes to db, delete them from the dag.utxoDiffStore.loaded
// map, and check if the diff data is re-fetched from the database.
err = dag.db.Update(func(dbTx database.Tx) error {
return dag.utxoDiffStore.flushToDB(dbTx)
})
if err != nil {
t.Fatalf("Error flushing utxoDiffStore data to DB: %s", err)
}
delete(dag.utxoDiffStore.loaded, *node.hash)
if storeDiff, err := dag.utxoDiffStore.diffByNode(node); err != nil {
t.Fatalf("diffByNode: unexpected error: %s", err)
} else if !reflect.DeepEqual(storeDiff, diff) {
t.Errorf("Expected diff and storeDiff to be equal")
}
// Check if getBlockDiff caches the result in dag.utxoDiffStore.loaded
if loadedDiffData, ok := dag.utxoDiffStore.loaded[*node.hash]; !ok {
t.Errorf("the diff data wasn't added to loaded map after requesting it")
} else if !reflect.DeepEqual(loadedDiffData.diff, diff) {
t.Errorf("Expected diff and loadedDiff to be equal")
}
}

View File

@ -3561,8 +3561,8 @@ func handleVerifyMessage(s *Server, cmd interface{}, closeChan <-chan struct{})
// Validate the signature - this just shows that it was valid at all. // Validate the signature - this just shows that it was valid at all.
// we will compare it with the key next. // we will compare it with the key next.
var buf bytes.Buffer var buf bytes.Buffer
wire.WriteVarString(&buf, 0, "Bitcoin Signed Message:\n") wire.WriteVarString(&buf, "Bitcoin Signed Message:\n")
wire.WriteVarString(&buf, 0, c.Message) wire.WriteVarString(&buf, c.Message)
expectedMessageHash := daghash.DoubleHashB(buf.Bytes()) expectedMessageHash := daghash.DoubleHashB(buf.Bytes())
pk, wasCompressed, err := btcec.RecoverCompact(btcec.S256(), sig, pk, wasCompressed, err := btcec.RecoverCompact(btcec.S256(), sig,
expectedMessageHash) expectedMessageHash)

View File

@ -195,7 +195,7 @@ func FromBytes(N uint32, P uint8, d []byte) (*Filter, error) {
// filter as returned by NBytes(). // filter as returned by NBytes().
func FromNBytes(P uint8, d []byte) (*Filter, error) { func FromNBytes(P uint8, d []byte) (*Filter, error) {
buffer := bytes.NewBuffer(d) buffer := bytes.NewBuffer(d)
N, err := wire.ReadVarInt(buffer, varIntProtoVer) N, err := wire.ReadVarInt(buffer)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -216,7 +216,7 @@ func FromPBytes(N uint32, d []byte) (*Filter, error) {
func FromNPBytes(d []byte) (*Filter, error) { func FromNPBytes(d []byte) (*Filter, error) {
buffer := bytes.NewBuffer(d) buffer := bytes.NewBuffer(d)
N, err := wire.ReadVarInt(buffer, varIntProtoVer) N, err := wire.ReadVarInt(buffer)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -246,7 +246,7 @@ func (f *Filter) NBytes() ([]byte, error) {
var buffer bytes.Buffer var buffer bytes.Buffer
buffer.Grow(wire.VarIntSerializeSize(uint64(f.n)) + len(f.filterData)) buffer.Grow(wire.VarIntSerializeSize(uint64(f.n)) + len(f.filterData))
err := wire.WriteVarInt(&buffer, varIntProtoVer, uint64(f.n)) err := wire.WriteVarInt(&buffer, uint64(f.n))
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -274,7 +274,7 @@ func (f *Filter) NPBytes() ([]byte, error) {
var buffer bytes.Buffer var buffer bytes.Buffer
buffer.Grow(wire.VarIntSerializeSize(uint64(f.n)) + 1 + len(f.filterData)) buffer.Grow(wire.VarIntSerializeSize(uint64(f.n)) + 1 + len(f.filterData))
err := wire.WriteVarInt(&buffer, varIntProtoVer, uint64(f.n)) err := wire.WriteVarInt(&buffer, uint64(f.n))
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -62,7 +62,7 @@ var genesisCoinbaseTx = NewNativeMsgTx(1, genesisCoinbaseTxIns, genesisCoinbaseT
// a single byte variable length integer. // a single byte variable length integer.
func BenchmarkWriteVarInt1(b *testing.B) { func BenchmarkWriteVarInt1(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
WriteVarInt(ioutil.Discard, 0, 1) WriteVarInt(ioutil.Discard, 1)
} }
} }
@ -70,7 +70,7 @@ func BenchmarkWriteVarInt1(b *testing.B) {
// a three byte variable length integer. // a three byte variable length integer.
func BenchmarkWriteVarInt3(b *testing.B) { func BenchmarkWriteVarInt3(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
WriteVarInt(ioutil.Discard, 0, 65535) WriteVarInt(ioutil.Discard, 65535)
} }
} }
@ -78,7 +78,7 @@ func BenchmarkWriteVarInt3(b *testing.B) {
// a five byte variable length integer. // a five byte variable length integer.
func BenchmarkWriteVarInt5(b *testing.B) { func BenchmarkWriteVarInt5(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
WriteVarInt(ioutil.Discard, 0, 4294967295) WriteVarInt(ioutil.Discard, 4294967295)
} }
} }
@ -86,7 +86,7 @@ func BenchmarkWriteVarInt5(b *testing.B) {
// a nine byte variable length integer. // a nine byte variable length integer.
func BenchmarkWriteVarInt9(b *testing.B) { func BenchmarkWriteVarInt9(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
WriteVarInt(ioutil.Discard, 0, 18446744073709551615) WriteVarInt(ioutil.Discard, 18446744073709551615)
} }
} }
@ -97,7 +97,7 @@ func BenchmarkReadVarInt1(b *testing.B) {
r := bytes.NewReader(buf) r := bytes.NewReader(buf)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
r.Seek(0, 0) r.Seek(0, 0)
ReadVarInt(r, 0) ReadVarInt(r)
} }
} }
@ -108,7 +108,7 @@ func BenchmarkReadVarInt3(b *testing.B) {
r := bytes.NewReader(buf) r := bytes.NewReader(buf)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
r.Seek(0, 0) r.Seek(0, 0)
ReadVarInt(r, 0) ReadVarInt(r)
} }
} }
@ -119,7 +119,7 @@ func BenchmarkReadVarInt5(b *testing.B) {
r := bytes.NewReader(buf) r := bytes.NewReader(buf)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
r.Seek(0, 0) r.Seek(0, 0)
ReadVarInt(r, 0) ReadVarInt(r)
} }
} }
@ -130,7 +130,7 @@ func BenchmarkReadVarInt9(b *testing.B) {
r := bytes.NewReader(buf) r := bytes.NewReader(buf)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
r.Seek(0, 0) r.Seek(0, 0)
ReadVarInt(r, 0) ReadVarInt(r)
} }
} }
@ -160,7 +160,7 @@ func BenchmarkReadVarStr10(b *testing.B) {
// four byte variable length string. // four byte variable length string.
func BenchmarkWriteVarStr4(b *testing.B) { func BenchmarkWriteVarStr4(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
WriteVarString(ioutil.Discard, 0, "test") WriteVarString(ioutil.Discard, "test")
} }
} }
@ -168,7 +168,7 @@ func BenchmarkWriteVarStr4(b *testing.B) {
// ten byte variable length string. // ten byte variable length string.
func BenchmarkWriteVarStr10(b *testing.B) { func BenchmarkWriteVarStr10(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
WriteVarString(ioutil.Discard, 0, "test012345") WriteVarString(ioutil.Discard, "test012345")
} }
} }

View File

@ -158,7 +158,7 @@ func readBlockHeader(r io.Reader, pver uint32, bh *BlockHeader) error {
bh.ParentHashes = make([]*daghash.Hash, numParentBlocks) bh.ParentHashes = make([]*daghash.Hash, numParentBlocks)
for i := byte(0); i < numParentBlocks; i++ { for i := byte(0); i < numParentBlocks; i++ {
hash := &daghash.Hash{} hash := &daghash.Hash{}
err := readElement(r, hash) err := ReadElement(r, hash)
if err != nil { if err != nil {
return err return err
} }
@ -178,7 +178,7 @@ func writeBlockHeader(w io.Writer, pver uint32, bh *BlockHeader) error {
return err return err
} }
for _, hash := range bh.ParentHashes { for _, hash := range bh.ParentHashes {
if err := writeElement(w, hash); err != nil { if err := WriteElement(w, hash); err != nil {
return err return err
} }
} }

View File

@ -39,9 +39,9 @@ var errNonCanonicalVarInt = "non-canonical varint %x - discriminant %x must " +
// time.Time since it is otherwise ambiguous. // time.Time since it is otherwise ambiguous.
type int64Time time.Time type int64Time time.Time
// readElement reads the next sequence of bytes from r using little endian // ReadElement reads the next sequence of bytes from r using little endian
// depending on the concrete type of element pointed to. // depending on the concrete type of element pointed to.
func readElement(r io.Reader, element interface{}) error { func ReadElement(r io.Reader, element interface{}) error {
// Attempt to read the element based on the concrete type via fast // Attempt to read the element based on the concrete type via fast
// type assertions first. // type assertions first.
switch e := element.(type) { switch e := element.(type) {
@ -186,7 +186,7 @@ func readElement(r io.Reader, element interface{}) error {
// calls to readElement. // calls to readElement.
func readElements(r io.Reader, elements ...interface{}) error { func readElements(r io.Reader, elements ...interface{}) error {
for _, element := range elements { for _, element := range elements {
err := readElement(r, element) err := ReadElement(r, element)
if err != nil { if err != nil {
return err return err
} }
@ -194,8 +194,8 @@ func readElements(r io.Reader, elements ...interface{}) error {
return nil return nil
} }
// writeElement writes the little endian representation of element to w. // WriteElement writes the little endian representation of element to w.
func writeElement(w io.Writer, element interface{}) error { func WriteElement(w io.Writer, element interface{}) error {
// Attempt to write the element based on the concrete type via fast // Attempt to write the element based on the concrete type via fast
// type assertions first. // type assertions first.
switch e := element.(type) { switch e := element.(type) {
@ -322,7 +322,7 @@ func writeElement(w io.Writer, element interface{}) error {
// calls to writeElement. // calls to writeElement.
func writeElements(w io.Writer, elements ...interface{}) error { func writeElements(w io.Writer, elements ...interface{}) error {
for _, element := range elements { for _, element := range elements {
err := writeElement(w, element) err := WriteElement(w, element)
if err != nil { if err != nil {
return err return err
} }
@ -331,7 +331,7 @@ func writeElements(w io.Writer, elements ...interface{}) error {
} }
// ReadVarInt reads a variable length integer from r and returns it as a uint64. // ReadVarInt reads a variable length integer from r and returns it as a uint64.
func ReadVarInt(r io.Reader, pver uint32) (uint64, error) { func ReadVarInt(r io.Reader) (uint64, error) {
discriminant, err := binaryserializer.Uint8(r) discriminant, err := binaryserializer.Uint8(r)
if err != nil { if err != nil {
return 0, err return 0, err
@ -393,7 +393,7 @@ func ReadVarInt(r io.Reader, pver uint32) (uint64, error) {
// WriteVarInt serializes val to w using a variable number of bytes depending // WriteVarInt serializes val to w using a variable number of bytes depending
// on its value. // on its value.
func WriteVarInt(w io.Writer, pver uint32, val uint64) error { func WriteVarInt(w io.Writer, val uint64) error {
if val < 0xfd { if val < 0xfd {
return binaryserializer.PutUint8(w, uint8(val)) return binaryserializer.PutUint8(w, uint8(val))
} }
@ -451,7 +451,7 @@ func VarIntSerializeSize(val uint64) int {
// maximum block payload size since it helps protect against memory exhaustion // maximum block payload size since it helps protect against memory exhaustion
// attacks and forced panics through malformed messages. // attacks and forced panics through malformed messages.
func ReadVarString(r io.Reader, pver uint32) (string, error) { func ReadVarString(r io.Reader, pver uint32) (string, error) {
count, err := ReadVarInt(r, pver) count, err := ReadVarInt(r)
if err != nil { if err != nil {
return "", err return "", err
} }
@ -476,8 +476,8 @@ func ReadVarString(r io.Reader, pver uint32) (string, error) {
// WriteVarString serializes str to w as a variable length integer containing // WriteVarString serializes str to w as a variable length integer containing
// the length of the string followed by the bytes that represent the string // the length of the string followed by the bytes that represent the string
// itself. // itself.
func WriteVarString(w io.Writer, pver uint32, str string) error { func WriteVarString(w io.Writer, str string) error {
err := WriteVarInt(w, pver, uint64(len(str))) err := WriteVarInt(w, uint64(len(str)))
if err != nil { if err != nil {
return err return err
} }
@ -495,7 +495,7 @@ func WriteVarString(w io.Writer, pver uint32, str string) error {
func ReadVarBytes(r io.Reader, pver uint32, maxAllowed uint32, func ReadVarBytes(r io.Reader, pver uint32, maxAllowed uint32,
fieldName string) ([]byte, error) { fieldName string) ([]byte, error) {
count, err := ReadVarInt(r, pver) count, err := ReadVarInt(r)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -521,7 +521,7 @@ func ReadVarBytes(r io.Reader, pver uint32, maxAllowed uint32,
// containing the number of bytes, followed by the bytes themselves. // containing the number of bytes, followed by the bytes themselves.
func WriteVarBytes(w io.Writer, pver uint32, bytes []byte) error { func WriteVarBytes(w io.Writer, pver uint32, bytes []byte) error {
slen := uint64(len(bytes)) slen := uint64(len(bytes))
err := WriteVarInt(w, pver, slen) err := WriteVarInt(w, slen)
if err != nil { if err != nil {
return err return err
} }

View File

@ -138,7 +138,7 @@ func TestElementWire(t *testing.T) {
for i, test := range tests { for i, test := range tests {
// Write to wire format. // Write to wire format.
var buf bytes.Buffer var buf bytes.Buffer
err := writeElement(&buf, test.in) err := WriteElement(&buf, test.in)
if err != nil { if err != nil {
t.Errorf("writeElement #%d error %v", i, err) t.Errorf("writeElement #%d error %v", i, err)
continue continue
@ -155,7 +155,7 @@ func TestElementWire(t *testing.T) {
if reflect.ValueOf(test.in).Kind() != reflect.Ptr { if reflect.ValueOf(test.in).Kind() != reflect.Ptr {
val = reflect.New(reflect.TypeOf(test.in)).Interface() val = reflect.New(reflect.TypeOf(test.in)).Interface()
} }
err = readElement(rbuf, val) err = ReadElement(rbuf, val)
if err != nil { if err != nil {
t.Errorf("readElement #%d error %v", i, err) t.Errorf("readElement #%d error %v", i, err)
continue continue
@ -218,7 +218,7 @@ func TestElementWireErrors(t *testing.T) {
for i, test := range tests { for i, test := range tests {
// Encode to wire format. // Encode to wire format.
w := newFixedWriter(test.max) w := newFixedWriter(test.max)
err := writeElement(w, test.in) err := WriteElement(w, test.in)
if err != test.writeErr { if err != test.writeErr {
t.Errorf("writeElement #%d wrong error got: %v, want: %v", t.Errorf("writeElement #%d wrong error got: %v, want: %v",
i, err, test.writeErr) i, err, test.writeErr)
@ -231,7 +231,7 @@ func TestElementWireErrors(t *testing.T) {
if reflect.ValueOf(test.in).Kind() != reflect.Ptr { if reflect.ValueOf(test.in).Kind() != reflect.Ptr {
val = reflect.New(reflect.TypeOf(test.in)).Interface() val = reflect.New(reflect.TypeOf(test.in)).Interface()
} }
err = readElement(r, val) err = ReadElement(r, val)
if err != test.readErr { if err != test.readErr {
t.Errorf("readElement #%d wrong error got: %v, want: %v", t.Errorf("readElement #%d wrong error got: %v, want: %v",
i, err, test.readErr) i, err, test.readErr)
@ -242,38 +242,33 @@ func TestElementWireErrors(t *testing.T) {
// TestVarIntWire tests wire encode and decode for variable length integers. // TestVarIntWire tests wire encode and decode for variable length integers.
func TestVarIntWire(t *testing.T) { func TestVarIntWire(t *testing.T) {
pver := ProtocolVersion
tests := []struct { tests := []struct {
in uint64 // Value to encode in uint64 // Value to encode
out uint64 // Expected decoded value out uint64 // Expected decoded value
buf []byte // Wire encoding buf []byte // Wire encoding
pver uint32 // Protocol version for wire encoding
}{ }{
// Latest protocol version. // Latest protocol version.
// Single byte // Single byte
{0, 0, []byte{0x00}, pver}, {0, 0, []byte{0x00}},
// Max single byte // Max single byte
{0xfc, 0xfc, []byte{0xfc}, pver}, {0xfc, 0xfc, []byte{0xfc}},
// Min 2-byte // Min 2-byte
{0xfd, 0xfd, []byte{0xfd, 0x0fd, 0x00}, pver}, {0xfd, 0xfd, []byte{0xfd, 0x0fd, 0x00}},
// Max 2-byte // Max 2-byte
{0xffff, 0xffff, []byte{0xfd, 0xff, 0xff}, pver}, {0xffff, 0xffff, []byte{0xfd, 0xff, 0xff}},
// Min 4-byte // Min 4-byte
{0x10000, 0x10000, []byte{0xfe, 0x00, 0x00, 0x01, 0x00}, pver}, {0x10000, 0x10000, []byte{0xfe, 0x00, 0x00, 0x01, 0x00}},
// Max 4-byte // Max 4-byte
{0xffffffff, 0xffffffff, []byte{0xfe, 0xff, 0xff, 0xff, 0xff}, pver}, {0xffffffff, 0xffffffff, []byte{0xfe, 0xff, 0xff, 0xff, 0xff}},
// Min 8-byte // Min 8-byte
{ {
0x100000000, 0x100000000, 0x100000000, 0x100000000,
[]byte{0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00}, []byte{0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00},
pver,
}, },
// Max 8-byte // Max 8-byte
{ {
0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,
[]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
pver,
}, },
} }
@ -281,7 +276,7 @@ func TestVarIntWire(t *testing.T) {
for i, test := range tests { for i, test := range tests {
// Encode to wire format. // Encode to wire format.
var buf bytes.Buffer var buf bytes.Buffer
err := WriteVarInt(&buf, test.pver, test.in) err := WriteVarInt(&buf, test.in)
if err != nil { if err != nil {
t.Errorf("WriteVarInt #%d error %v", i, err) t.Errorf("WriteVarInt #%d error %v", i, err)
continue continue
@ -294,7 +289,7 @@ func TestVarIntWire(t *testing.T) {
// Decode from wire format. // Decode from wire format.
rbuf := bytes.NewReader(test.buf) rbuf := bytes.NewReader(test.buf)
val, err := ReadVarInt(rbuf, test.pver) val, err := ReadVarInt(rbuf)
if err != nil { if err != nil {
t.Errorf("ReadVarInt #%d error %v", i, err) t.Errorf("ReadVarInt #%d error %v", i, err)
continue continue
@ -310,34 +305,31 @@ func TestVarIntWire(t *testing.T) {
// TestVarIntWireErrors performs negative tests against wire encode and decode // TestVarIntWireErrors performs negative tests against wire encode and decode
// of variable length integers to confirm error paths work correctly. // of variable length integers to confirm error paths work correctly.
func TestVarIntWireErrors(t *testing.T) { func TestVarIntWireErrors(t *testing.T) {
pver := ProtocolVersion
tests := []struct { tests := []struct {
in uint64 // Value to encode in uint64 // Value to encode
buf []byte // Wire encoding buf []byte // Wire encoding
pver uint32 // Protocol version for wire encoding
max int // Max size of fixed buffer to induce errors max int // Max size of fixed buffer to induce errors
writeErr error // Expected write error writeErr error // Expected write error
readErr error // Expected read error readErr error // Expected read error
}{ }{
// Force errors on discriminant. // Force errors on discriminant.
{0, []byte{0x00}, pver, 0, io.ErrShortWrite, io.EOF}, {0, []byte{0x00}, 0, io.ErrShortWrite, io.EOF},
// Force errors on 2-byte read/write. // Force errors on 2-byte read/write.
{0xfd, []byte{0xfd}, pver, 0, io.ErrShortWrite, io.EOF}, // error on writing length {0xfd, []byte{0xfd}, 0, io.ErrShortWrite, io.EOF}, // error on writing length
{0xfd, []byte{0xfd}, pver, 2, io.ErrShortWrite, io.ErrUnexpectedEOF}, // error on writing actual data {0xfd, []byte{0xfd}, 2, io.ErrShortWrite, io.ErrUnexpectedEOF}, // error on writing actual data
// Force errors on 4-byte read/write. // Force errors on 4-byte read/write.
{0x10000, []byte{0xfe}, pver, 0, io.ErrShortWrite, io.EOF}, // error on writing length {0x10000, []byte{0xfe}, 0, io.ErrShortWrite, io.EOF}, // error on writing length
{0x10000, []byte{0xfe}, pver, 2, io.ErrShortWrite, io.ErrUnexpectedEOF}, // error on writing actual data {0x10000, []byte{0xfe}, 2, io.ErrShortWrite, io.ErrUnexpectedEOF}, // error on writing actual data
// Force errors on 8-byte read/write. // Force errors on 8-byte read/write.
{0x100000000, []byte{0xff}, pver, 0, io.ErrShortWrite, io.EOF}, // error on writing length {0x100000000, []byte{0xff}, 0, io.ErrShortWrite, io.EOF}, // error on writing length
{0x100000000, []byte{0xff}, pver, 2, io.ErrShortWrite, io.ErrUnexpectedEOF}, // error on writing actual data {0x100000000, []byte{0xff}, 2, io.ErrShortWrite, io.ErrUnexpectedEOF}, // error on writing actual data
} }
t.Logf("Running %d tests", len(tests)) t.Logf("Running %d tests", len(tests))
for i, test := range tests { for i, test := range tests {
// Encode to wire format. // Encode to wire format.
w := newFixedWriter(test.max) w := newFixedWriter(test.max)
err := WriteVarInt(w, test.pver, test.in) err := WriteVarInt(w, test.in)
if err != test.writeErr { if err != test.writeErr {
t.Errorf("WriteVarInt #%d wrong error got: %v, want: %v", t.Errorf("WriteVarInt #%d wrong error got: %v, want: %v",
i, err, test.writeErr) i, err, test.writeErr)
@ -346,7 +338,7 @@ func TestVarIntWireErrors(t *testing.T) {
// Decode from wire format. // Decode from wire format.
r := newFixedReader(test.max, test.buf) r := newFixedReader(test.max, test.buf)
_, err = ReadVarInt(r, test.pver) _, err = ReadVarInt(r)
if err != test.readErr { if err != test.readErr {
t.Errorf("ReadVarInt #%d wrong error got: %v, want: %v", t.Errorf("ReadVarInt #%d wrong error got: %v, want: %v",
i, err, test.readErr) i, err, test.readErr)
@ -397,7 +389,7 @@ func TestVarIntNonCanonical(t *testing.T) {
for i, test := range tests { for i, test := range tests {
// Decode from wire format. // Decode from wire format.
rbuf := bytes.NewReader(test.in) rbuf := bytes.NewReader(test.in)
val, err := ReadVarInt(rbuf, test.pver) val, err := ReadVarInt(rbuf)
if _, ok := err.(*MessageError); !ok { if _, ok := err.(*MessageError); !ok {
t.Errorf("ReadVarInt #%d (%s) unexpected error %v", i, t.Errorf("ReadVarInt #%d (%s) unexpected error %v", i,
test.name, err) test.name, err)
@ -472,7 +464,7 @@ func TestVarStringWire(t *testing.T) {
for i, test := range tests { for i, test := range tests {
// Encode to wire format. // Encode to wire format.
var buf bytes.Buffer var buf bytes.Buffer
err := WriteVarString(&buf, test.pver, test.in) err := WriteVarString(&buf, test.in)
if err != nil { if err != nil {
t.Errorf("WriteVarString #%d error %v", i, err) t.Errorf("WriteVarString #%d error %v", i, err)
continue continue
@ -527,7 +519,7 @@ func TestVarStringWireErrors(t *testing.T) {
for i, test := range tests { for i, test := range tests {
// Encode to wire format. // Encode to wire format.
w := newFixedWriter(test.max) w := newFixedWriter(test.max)
err := WriteVarString(w, test.pver, test.in) err := WriteVarString(w, test.in)
if err != test.writeErr { if err != test.writeErr {
t.Errorf("WriteVarString #%d wrong error got: %v, want: %v", t.Errorf("WriteVarString #%d wrong error got: %v, want: %v",
i, err, test.writeErr) i, err, test.writeErr)

View File

@ -64,20 +64,20 @@ func (msg *MsgAddr) ClearAddresses() {
func (msg *MsgAddr) BtcDecode(r io.Reader, pver uint32) error { func (msg *MsgAddr) BtcDecode(r io.Reader, pver uint32) error {
msg.SubnetworkID = nil msg.SubnetworkID = nil
err := readElement(r, &msg.IncludeAllSubnetworks) err := ReadElement(r, &msg.IncludeAllSubnetworks)
if err != nil { if err != nil {
return err return err
} }
if !msg.IncludeAllSubnetworks { if !msg.IncludeAllSubnetworks {
var isFullNode bool var isFullNode bool
err := readElement(r, &isFullNode) err := ReadElement(r, &isFullNode)
if err != nil { if err != nil {
return err return err
} }
if !isFullNode { if !isFullNode {
var subnetworkID subnetworkid.SubnetworkID var subnetworkID subnetworkid.SubnetworkID
err = readElement(r, &subnetworkID) err = ReadElement(r, &subnetworkID)
if err != nil { if err != nil {
return err return err
} }
@ -86,7 +86,7 @@ func (msg *MsgAddr) BtcDecode(r io.Reader, pver uint32) error {
} }
// Read addresses array // Read addresses array
count, err := ReadVarInt(r, pver) count, err := ReadVarInt(r)
if err != nil { if err != nil {
return err return err
} }
@ -121,7 +121,7 @@ func (msg *MsgAddr) BtcEncode(w io.Writer, pver uint32) error {
return messageError("MsgAddr.BtcEncode", str) return messageError("MsgAddr.BtcEncode", str)
} }
err := writeElement(w, msg.IncludeAllSubnetworks) err := WriteElement(w, msg.IncludeAllSubnetworks)
if err != nil { if err != nil {
return err return err
} }
@ -129,19 +129,19 @@ func (msg *MsgAddr) BtcEncode(w io.Writer, pver uint32) error {
if !msg.IncludeAllSubnetworks { if !msg.IncludeAllSubnetworks {
// Write subnetwork ID // Write subnetwork ID
isFullNode := msg.SubnetworkID == nil isFullNode := msg.SubnetworkID == nil
err = writeElement(w, isFullNode) err = WriteElement(w, isFullNode)
if err != nil { if err != nil {
return err return err
} }
if !isFullNode { if !isFullNode {
err = writeElement(w, msg.SubnetworkID) err = WriteElement(w, msg.SubnetworkID)
if err != nil { if err != nil {
return err return err
} }
} }
} }
err = WriteVarInt(w, pver, uint64(count)) err = WriteVarInt(w, uint64(count))
if err != nil { if err != nil {
return err return err
} }

View File

@ -161,12 +161,12 @@ func (alert *Alert) Serialize(w io.Writer, pver uint32) error {
"[count %d, max %d]", count, maxCountSetCancel) "[count %d, max %d]", count, maxCountSetCancel)
return messageError("Alert.Serialize", str) return messageError("Alert.Serialize", str)
} }
err = WriteVarInt(w, pver, uint64(count)) err = WriteVarInt(w, uint64(count))
if err != nil { if err != nil {
return err return err
} }
for i := 0; i < count; i++ { for i := 0; i < count; i++ {
err = writeElement(w, alert.SetCancel[i]) err = WriteElement(w, alert.SetCancel[i])
if err != nil { if err != nil {
return err return err
} }
@ -183,30 +183,30 @@ func (alert *Alert) Serialize(w io.Writer, pver uint32) error {
"[count %d, max %d]", count, maxCountSetSubVer) "[count %d, max %d]", count, maxCountSetSubVer)
return messageError("Alert.Serialize", str) return messageError("Alert.Serialize", str)
} }
err = WriteVarInt(w, pver, uint64(count)) err = WriteVarInt(w, uint64(count))
if err != nil { if err != nil {
return err return err
} }
for i := 0; i < count; i++ { for i := 0; i < count; i++ {
err = WriteVarString(w, pver, alert.SetSubVer[i]) err = WriteVarString(w, alert.SetSubVer[i])
if err != nil { if err != nil {
return err return err
} }
} }
err = writeElement(w, alert.Priority) err = WriteElement(w, alert.Priority)
if err != nil { if err != nil {
return err return err
} }
err = WriteVarString(w, pver, alert.Comment) err = WriteVarString(w, alert.Comment)
if err != nil { if err != nil {
return err return err
} }
err = WriteVarString(w, pver, alert.StatusBar) err = WriteVarString(w, alert.StatusBar)
if err != nil { if err != nil {
return err return err
} }
return WriteVarString(w, pver, alert.Reserved) return WriteVarString(w, alert.Reserved)
} }
// Deserialize decodes from r into the receiver using the alert protocol // Deserialize decodes from r into the receiver using the alert protocol
@ -221,7 +221,7 @@ func (alert *Alert) Deserialize(r io.Reader, pver uint32) error {
// SetCancel: first read a VarInt that contains // SetCancel: first read a VarInt that contains
// count - the number of Cancel IDs, then // count - the number of Cancel IDs, then
// iterate count times and read them // iterate count times and read them
count, err := ReadVarInt(r, pver) count, err := ReadVarInt(r)
if err != nil { if err != nil {
return err return err
} }
@ -232,7 +232,7 @@ func (alert *Alert) Deserialize(r io.Reader, pver uint32) error {
} }
alert.SetCancel = make([]int32, count) alert.SetCancel = make([]int32, count)
for i := 0; i < int(count); i++ { for i := 0; i < int(count); i++ {
err := readElement(r, &alert.SetCancel[i]) err := ReadElement(r, &alert.SetCancel[i])
if err != nil { if err != nil {
return err return err
} }
@ -245,7 +245,7 @@ func (alert *Alert) Deserialize(r io.Reader, pver uint32) error {
// SetSubVer: similar to SetCancel // SetSubVer: similar to SetCancel
// but read count number of sub-version strings // but read count number of sub-version strings
count, err = ReadVarInt(r, pver) count, err = ReadVarInt(r)
if err != nil { if err != nil {
return err return err
} }
@ -262,7 +262,7 @@ func (alert *Alert) Deserialize(r io.Reader, pver uint32) error {
} }
} }
err = readElement(r, &alert.Priority) err = ReadElement(r, &alert.Priority)
if err != nil { if err != nil {
return err return err
} }

View File

@ -66,7 +66,7 @@ func (msg *MsgBlock) BtcDecode(r io.Reader, pver uint32) error {
return err return err
} }
txCount, err := ReadVarInt(r, pver) txCount, err := ReadVarInt(r)
if err != nil { if err != nil {
return err return err
} }
@ -124,7 +124,7 @@ func (msg *MsgBlock) DeserializeTxLoc(r *bytes.Buffer) ([]TxLoc, error) {
return nil, err return nil, err
} }
txCount, err := ReadVarInt(r, 0) txCount, err := ReadVarInt(r)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -166,7 +166,7 @@ func (msg *MsgBlock) BtcEncode(w io.Writer, pver uint32) error {
return err return err
} }
err = WriteVarInt(w, pver, uint64(len(msg.Transactions))) err = WriteVarInt(w, uint64(len(msg.Transactions)))
if err != nil { if err != nil {
return err return err
} }

View File

@ -43,20 +43,20 @@ func (msg *MsgCFCheckpt) AddCFHeader(header *daghash.Hash) error {
// This is part of the Message interface implementation. // This is part of the Message interface implementation.
func (msg *MsgCFCheckpt) BtcDecode(r io.Reader, pver uint32) error { func (msg *MsgCFCheckpt) BtcDecode(r io.Reader, pver uint32) error {
// Read filter type // Read filter type
err := readElement(r, &msg.FilterType) err := ReadElement(r, &msg.FilterType)
if err != nil { if err != nil {
return err return err
} }
// Read stop hash // Read stop hash
msg.StopHash = &daghash.Hash{} msg.StopHash = &daghash.Hash{}
err = readElement(r, msg.StopHash) err = ReadElement(r, msg.StopHash)
if err != nil { if err != nil {
return err return err
} }
// Read number of filter headers // Read number of filter headers
count, err := ReadVarInt(r, pver) count, err := ReadVarInt(r)
if err != nil { if err != nil {
return err return err
} }
@ -66,7 +66,7 @@ func (msg *MsgCFCheckpt) BtcDecode(r io.Reader, pver uint32) error {
msg.FilterHeaders = make([]*daghash.Hash, count) msg.FilterHeaders = make([]*daghash.Hash, count)
for i := uint64(0); i < count; i++ { for i := uint64(0); i < count; i++ {
var cfh daghash.Hash var cfh daghash.Hash
err := readElement(r, &cfh) err := ReadElement(r, &cfh)
if err != nil { if err != nil {
return err return err
} }
@ -80,26 +80,26 @@ func (msg *MsgCFCheckpt) BtcDecode(r io.Reader, pver uint32) error {
// This is part of the Message interface implementation. // This is part of the Message interface implementation.
func (msg *MsgCFCheckpt) BtcEncode(w io.Writer, pver uint32) error { func (msg *MsgCFCheckpt) BtcEncode(w io.Writer, pver uint32) error {
// Write filter type // Write filter type
err := writeElement(w, msg.FilterType) err := WriteElement(w, msg.FilterType)
if err != nil { if err != nil {
return err return err
} }
// Write stop hash // Write stop hash
err = writeElement(w, msg.StopHash) err = WriteElement(w, msg.StopHash)
if err != nil { if err != nil {
return err return err
} }
// Write length of FilterHeaders slice // Write length of FilterHeaders slice
count := len(msg.FilterHeaders) count := len(msg.FilterHeaders)
err = WriteVarInt(w, pver, uint64(count)) err = WriteVarInt(w, uint64(count))
if err != nil { if err != nil {
return err return err
} }
for _, cfh := range msg.FilterHeaders { for _, cfh := range msg.FilterHeaders {
err := writeElement(w, cfh) err := WriteElement(w, cfh)
if err != nil { if err != nil {
return err return err
} }

View File

@ -49,27 +49,27 @@ func (msg *MsgCFHeaders) AddCFHash(hash *daghash.Hash) error {
// This is part of the Message interface implementation. // This is part of the Message interface implementation.
func (msg *MsgCFHeaders) BtcDecode(r io.Reader, pver uint32) error { func (msg *MsgCFHeaders) BtcDecode(r io.Reader, pver uint32) error {
// Read filter type // Read filter type
err := readElement(r, &msg.FilterType) err := ReadElement(r, &msg.FilterType)
if err != nil { if err != nil {
return err return err
} }
// Read stop hash // Read stop hash
msg.StopHash = &daghash.Hash{} msg.StopHash = &daghash.Hash{}
err = readElement(r, msg.StopHash) err = ReadElement(r, msg.StopHash)
if err != nil { if err != nil {
return err return err
} }
// Read prev filter header // Read prev filter header
msg.PrevFilterHeader = &daghash.Hash{} msg.PrevFilterHeader = &daghash.Hash{}
err = readElement(r, msg.PrevFilterHeader) err = ReadElement(r, msg.PrevFilterHeader)
if err != nil { if err != nil {
return err return err
} }
// Read number of filter headers // Read number of filter headers
count, err := ReadVarInt(r, pver) count, err := ReadVarInt(r)
if err != nil { if err != nil {
return err return err
} }
@ -87,7 +87,7 @@ func (msg *MsgCFHeaders) BtcDecode(r io.Reader, pver uint32) error {
msg.FilterHashes = make([]*daghash.Hash, 0, count) msg.FilterHashes = make([]*daghash.Hash, 0, count)
for i := uint64(0); i < count; i++ { for i := uint64(0); i < count; i++ {
var cfh daghash.Hash var cfh daghash.Hash
err := readElement(r, &cfh) err := ReadElement(r, &cfh)
if err != nil { if err != nil {
return err return err
} }
@ -101,19 +101,19 @@ func (msg *MsgCFHeaders) BtcDecode(r io.Reader, pver uint32) error {
// This is part of the Message interface implementation. // This is part of the Message interface implementation.
func (msg *MsgCFHeaders) BtcEncode(w io.Writer, pver uint32) error { func (msg *MsgCFHeaders) BtcEncode(w io.Writer, pver uint32) error {
// Write filter type // Write filter type
err := writeElement(w, msg.FilterType) err := WriteElement(w, msg.FilterType)
if err != nil { if err != nil {
return err return err
} }
// Write stop hash // Write stop hash
err = writeElement(w, msg.StopHash) err = WriteElement(w, msg.StopHash)
if err != nil { if err != nil {
return err return err
} }
// Write prev filter header // Write prev filter header
err = writeElement(w, msg.PrevFilterHeader) err = WriteElement(w, msg.PrevFilterHeader)
if err != nil { if err != nil {
return err return err
} }
@ -127,13 +127,13 @@ func (msg *MsgCFHeaders) BtcEncode(w io.Writer, pver uint32) error {
return messageError("MsgCFHeaders.BtcEncode", str) return messageError("MsgCFHeaders.BtcEncode", str)
} }
err = WriteVarInt(w, pver, uint64(count)) err = WriteVarInt(w, uint64(count))
if err != nil { if err != nil {
return err return err
} }
for _, cfh := range msg.FilterHashes { for _, cfh := range msg.FilterHashes {
err := writeElement(w, cfh) err := WriteElement(w, cfh)
if err != nil { if err != nil {
return err return err
} }

View File

@ -41,13 +41,13 @@ type MsgCFilter struct {
// This is part of the Message interface implementation. // This is part of the Message interface implementation.
func (msg *MsgCFilter) BtcDecode(r io.Reader, pver uint32) error { func (msg *MsgCFilter) BtcDecode(r io.Reader, pver uint32) error {
// Read filter type // Read filter type
err := readElement(r, &msg.FilterType) err := ReadElement(r, &msg.FilterType)
if err != nil { if err != nil {
return err return err
} }
// Read the hash of the filter's block // Read the hash of the filter's block
err = readElement(r, &msg.BlockHash) err = ReadElement(r, &msg.BlockHash)
if err != nil { if err != nil {
return err return err
} }
@ -68,12 +68,12 @@ func (msg *MsgCFilter) BtcEncode(w io.Writer, pver uint32) error {
return messageError("MsgCFilter.BtcEncode", str) return messageError("MsgCFilter.BtcEncode", str)
} }
err := writeElement(w, msg.FilterType) err := WriteElement(w, msg.FilterType)
if err != nil { if err != nil {
return err return err
} }
err = writeElement(w, msg.BlockHash) err = WriteElement(w, msg.BlockHash)
if err != nil { if err != nil {
return err return err
} }

View File

@ -21,13 +21,13 @@ type MsgFeeFilter struct {
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver. // BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation. // This is part of the Message interface implementation.
func (msg *MsgFeeFilter) BtcDecode(r io.Reader, pver uint32) error { func (msg *MsgFeeFilter) BtcDecode(r io.Reader, pver uint32) error {
return readElement(r, &msg.MinFee) return ReadElement(r, &msg.MinFee)
} }
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding. // BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation. // This is part of the Message interface implementation.
func (msg *MsgFeeFilter) BtcEncode(w io.Writer, pver uint32) error { func (msg *MsgFeeFilter) BtcEncode(w io.Writer, pver uint32) error {
return writeElement(w, msg.MinFee) return WriteElement(w, msg.MinFee)
} }
// Command returns the protocol command string for the message. This is part // Command returns the protocol command string for the message. This is part

View File

@ -26,7 +26,7 @@ type MsgGetAddr struct {
func (msg *MsgGetAddr) BtcDecode(r io.Reader, pver uint32) error { func (msg *MsgGetAddr) BtcDecode(r io.Reader, pver uint32) error {
msg.SubnetworkID = nil msg.SubnetworkID = nil
err := readElement(r, &msg.IncludeAllSubnetworks) err := ReadElement(r, &msg.IncludeAllSubnetworks)
if err != nil { if err != nil {
return err return err
} }
@ -35,7 +35,7 @@ func (msg *MsgGetAddr) BtcDecode(r io.Reader, pver uint32) error {
} }
var isFullNode bool var isFullNode bool
err = readElement(r, &isFullNode) err = ReadElement(r, &isFullNode)
if err != nil { if err != nil {
return err return err
} }
@ -44,7 +44,7 @@ func (msg *MsgGetAddr) BtcDecode(r io.Reader, pver uint32) error {
} }
var subnetworkID subnetworkid.SubnetworkID var subnetworkID subnetworkid.SubnetworkID
err = readElement(r, &subnetworkID) err = ReadElement(r, &subnetworkID)
if err != nil { if err != nil {
return err return err
} }
@ -56,7 +56,7 @@ func (msg *MsgGetAddr) BtcDecode(r io.Reader, pver uint32) error {
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding. // BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation. // This is part of the Message interface implementation.
func (msg *MsgGetAddr) BtcEncode(w io.Writer, pver uint32) error { func (msg *MsgGetAddr) BtcEncode(w io.Writer, pver uint32) error {
err := writeElement(w, msg.IncludeAllSubnetworks) err := WriteElement(w, msg.IncludeAllSubnetworks)
if err != nil { if err != nil {
return err return err
} }
@ -66,13 +66,13 @@ func (msg *MsgGetAddr) BtcEncode(w io.Writer, pver uint32) error {
} }
isFullNode := msg.SubnetworkID == nil isFullNode := msg.SubnetworkID == nil
err = writeElement(w, isFullNode) err = WriteElement(w, isFullNode)
if err != nil { if err != nil {
return err return err
} }
if !isFullNode { if !isFullNode {
err = writeElement(w, msg.SubnetworkID) err = WriteElement(w, msg.SubnetworkID)
if err != nil { if err != nil {
return err return err
} }

View File

@ -51,13 +51,13 @@ func (msg *MsgGetBlocks) AddBlockLocatorHash(hash *daghash.Hash) error {
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver. // BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation. // This is part of the Message interface implementation.
func (msg *MsgGetBlocks) BtcDecode(r io.Reader, pver uint32) error { func (msg *MsgGetBlocks) BtcDecode(r io.Reader, pver uint32) error {
err := readElement(r, &msg.ProtocolVersion) err := ReadElement(r, &msg.ProtocolVersion)
if err != nil { if err != nil {
return err return err
} }
// Read num block locator hashes and limit to max. // Read num block locator hashes and limit to max.
count, err := ReadVarInt(r, pver) count, err := ReadVarInt(r)
if err != nil { if err != nil {
return err return err
} }
@ -73,7 +73,7 @@ func (msg *MsgGetBlocks) BtcDecode(r io.Reader, pver uint32) error {
msg.BlockLocatorHashes = make([]*daghash.Hash, 0, count) msg.BlockLocatorHashes = make([]*daghash.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)
if err != nil { if err != nil {
return err return err
} }
@ -81,7 +81,7 @@ func (msg *MsgGetBlocks) BtcDecode(r io.Reader, pver uint32) error {
} }
msg.HashStop = &daghash.Hash{} msg.HashStop = &daghash.Hash{}
return readElement(r, msg.HashStop) return ReadElement(r, msg.HashStop)
} }
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding. // BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
@ -94,24 +94,24 @@ func (msg *MsgGetBlocks) BtcEncode(w io.Writer, pver uint32) error {
return messageError("MsgGetBlocks.BtcEncode", str) return messageError("MsgGetBlocks.BtcEncode", str)
} }
err := writeElement(w, msg.ProtocolVersion) err := WriteElement(w, msg.ProtocolVersion)
if err != nil { if err != nil {
return err return err
} }
err = WriteVarInt(w, pver, uint64(count)) err = WriteVarInt(w, uint64(count))
if err != nil { if err != nil {
return err return err
} }
for _, hash := range msg.BlockLocatorHashes { for _, hash := range msg.BlockLocatorHashes {
err = writeElement(w, hash) err = WriteElement(w, hash)
if err != nil { if err != nil {
return err return err
} }
} }
return writeElement(w, msg.HashStop) return WriteElement(w, msg.HashStop)
} }
// Command returns the protocol command string for the message. This is part // Command returns the protocol command string for the message. This is part

View File

@ -21,24 +21,24 @@ type MsgGetCFCheckpt struct {
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver. // BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation. // This is part of the Message interface implementation.
func (msg *MsgGetCFCheckpt) BtcDecode(r io.Reader, pver uint32) error { func (msg *MsgGetCFCheckpt) BtcDecode(r io.Reader, pver uint32) error {
err := readElement(r, &msg.FilterType) err := ReadElement(r, &msg.FilterType)
if err != nil { if err != nil {
return err return err
} }
msg.StopHash = &daghash.Hash{} msg.StopHash = &daghash.Hash{}
return readElement(r, msg.StopHash) return ReadElement(r, msg.StopHash)
} }
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding. // BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation. // This is part of the Message interface implementation.
func (msg *MsgGetCFCheckpt) BtcEncode(w io.Writer, pver uint32) error { func (msg *MsgGetCFCheckpt) BtcEncode(w io.Writer, pver uint32) error {
err := writeElement(w, msg.FilterType) err := WriteElement(w, msg.FilterType)
if err != nil { if err != nil {
return err return err
} }
return writeElement(w, msg.StopHash) return WriteElement(w, msg.StopHash)
} }
// Command returns the protocol command string for the message. This is part // Command returns the protocol command string for the message. This is part

View File

@ -22,34 +22,34 @@ type MsgGetCFHeaders struct {
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver. // BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation. // This is part of the Message interface implementation.
func (msg *MsgGetCFHeaders) BtcDecode(r io.Reader, pver uint32) error { func (msg *MsgGetCFHeaders) BtcDecode(r io.Reader, pver uint32) error {
err := readElement(r, &msg.FilterType) err := ReadElement(r, &msg.FilterType)
if err != nil { if err != nil {
return err return err
} }
err = readElement(r, &msg.StartHeight) err = ReadElement(r, &msg.StartHeight)
if err != nil { if err != nil {
return err return err
} }
msg.StopHash = &daghash.Hash{} msg.StopHash = &daghash.Hash{}
return readElement(r, msg.StopHash) return ReadElement(r, msg.StopHash)
} }
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding. // BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation. // This is part of the Message interface implementation.
func (msg *MsgGetCFHeaders) BtcEncode(w io.Writer, pver uint32) error { func (msg *MsgGetCFHeaders) BtcEncode(w io.Writer, pver uint32) error {
err := writeElement(w, msg.FilterType) err := WriteElement(w, msg.FilterType)
if err != nil { if err != nil {
return err return err
} }
err = writeElement(w, &msg.StartHeight) err = WriteElement(w, &msg.StartHeight)
if err != nil { if err != nil {
return err return err
} }
return writeElement(w, msg.StopHash) return WriteElement(w, msg.StopHash)
} }
// Command returns the protocol command string for the message. This is part // Command returns the protocol command string for the message. This is part

View File

@ -26,34 +26,34 @@ type MsgGetCFilters struct {
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver. // BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation. // This is part of the Message interface implementation.
func (msg *MsgGetCFilters) BtcDecode(r io.Reader, pver uint32) error { func (msg *MsgGetCFilters) BtcDecode(r io.Reader, pver uint32) error {
err := readElement(r, &msg.FilterType) err := ReadElement(r, &msg.FilterType)
if err != nil { if err != nil {
return err return err
} }
err = readElement(r, &msg.StartHeight) err = ReadElement(r, &msg.StartHeight)
if err != nil { if err != nil {
return err return err
} }
msg.StopHash = &daghash.Hash{} msg.StopHash = &daghash.Hash{}
return readElement(r, msg.StopHash) return ReadElement(r, msg.StopHash)
} }
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding. // BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation. // This is part of the Message interface implementation.
func (msg *MsgGetCFilters) BtcEncode(w io.Writer, pver uint32) error { func (msg *MsgGetCFilters) BtcEncode(w io.Writer, pver uint32) error {
err := writeElement(w, msg.FilterType) err := WriteElement(w, msg.FilterType)
if err != nil { if err != nil {
return err return err
} }
err = writeElement(w, &msg.StartHeight) err = WriteElement(w, &msg.StartHeight)
if err != nil { if err != nil {
return err return err
} }
return writeElement(w, msg.StopHash) return WriteElement(w, msg.StopHash)
} }
// Command returns the protocol command string for the message. This is part // Command returns the protocol command string for the message. This is part

View File

@ -38,7 +38,7 @@ func (msg *MsgGetData) AddInvVect(iv *InvVect) error {
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver. // BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation. // This is part of the Message interface implementation.
func (msg *MsgGetData) BtcDecode(r io.Reader, pver uint32) error { func (msg *MsgGetData) BtcDecode(r io.Reader, pver uint32) error {
count, err := ReadVarInt(r, pver) count, err := ReadVarInt(r)
if err != nil { if err != nil {
return err return err
} }
@ -75,7 +75,7 @@ func (msg *MsgGetData) BtcEncode(w io.Writer, pver uint32) error {
return messageError("MsgGetData.BtcEncode", str) return messageError("MsgGetData.BtcEncode", str)
} }
err := WriteVarInt(w, pver, uint64(count)) err := WriteVarInt(w, uint64(count))
if err != nil { if err != nil {
return err return err
} }

View File

@ -48,13 +48,13 @@ func (msg *MsgGetHeaders) AddBlockLocatorHash(hash *daghash.Hash) error {
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver. // BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation. // This is part of the Message interface implementation.
func (msg *MsgGetHeaders) BtcDecode(r io.Reader, pver uint32) error { func (msg *MsgGetHeaders) BtcDecode(r io.Reader, pver uint32) error {
err := readElement(r, &msg.ProtocolVersion) err := ReadElement(r, &msg.ProtocolVersion)
if err != nil { if err != nil {
return err return err
} }
// Read num block locator hashes and limit to max. // Read num block locator hashes and limit to max.
count, err := ReadVarInt(r, pver) count, err := ReadVarInt(r)
if err != nil { if err != nil {
return err return err
} }
@ -70,7 +70,7 @@ func (msg *MsgGetHeaders) BtcDecode(r io.Reader, pver uint32) error {
msg.BlockLocatorHashes = make([]*daghash.Hash, 0, count) msg.BlockLocatorHashes = make([]*daghash.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)
if err != nil { if err != nil {
return err return err
} }
@ -78,7 +78,7 @@ func (msg *MsgGetHeaders) BtcDecode(r io.Reader, pver uint32) error {
} }
msg.HashStop = &daghash.Hash{} msg.HashStop = &daghash.Hash{}
return readElement(r, msg.HashStop) return ReadElement(r, msg.HashStop)
} }
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding. // BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
@ -92,24 +92,24 @@ func (msg *MsgGetHeaders) BtcEncode(w io.Writer, pver uint32) error {
return messageError("MsgGetHeaders.BtcEncode", str) return messageError("MsgGetHeaders.BtcEncode", str)
} }
err := writeElement(w, msg.ProtocolVersion) err := WriteElement(w, msg.ProtocolVersion)
if err != nil { if err != nil {
return err return err
} }
err = WriteVarInt(w, pver, uint64(count)) err = WriteVarInt(w, uint64(count))
if err != nil { if err != nil {
return err return err
} }
for _, hash := range msg.BlockLocatorHashes { for _, hash := range msg.BlockLocatorHashes {
err := writeElement(w, hash) err := WriteElement(w, hash)
if err != nil { if err != nil {
return err return err
} }
} }
return writeElement(w, msg.HashStop) return WriteElement(w, msg.HashStop)
} }
// Command returns the protocol command string for the message. This is part // Command returns the protocol command string for the message. This is part

View File

@ -37,7 +37,7 @@ func (msg *MsgHeaders) AddBlockHeader(bh *BlockHeader) error {
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver. // BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation. // This is part of the Message interface implementation.
func (msg *MsgHeaders) BtcDecode(r io.Reader, pver uint32) error { func (msg *MsgHeaders) BtcDecode(r io.Reader, pver uint32) error {
count, err := ReadVarInt(r, pver) count, err := ReadVarInt(r)
if err != nil { if err != nil {
return err return err
} }
@ -60,7 +60,7 @@ func (msg *MsgHeaders) BtcDecode(r io.Reader, pver uint32) error {
return err return err
} }
txCount, err := ReadVarInt(r, pver) txCount, err := ReadVarInt(r)
if err != nil { if err != nil {
return err return err
} }
@ -88,7 +88,7 @@ func (msg *MsgHeaders) BtcEncode(w io.Writer, pver uint32) error {
return messageError("MsgHeaders.BtcEncode", str) return messageError("MsgHeaders.BtcEncode", str)
} }
err := WriteVarInt(w, pver, uint64(count)) err := WriteVarInt(w, uint64(count))
if err != nil { if err != nil {
return err return err
} }
@ -103,7 +103,7 @@ func (msg *MsgHeaders) BtcEncode(w io.Writer, pver uint32) error {
// of transactions on header messages. This is really just an // of transactions on header messages. This is really just an
// artifact of the way the original implementation serializes // artifact of the way the original implementation serializes
// block headers, but it is required. // block headers, but it is required.
err = WriteVarInt(w, pver, 0) err = WriteVarInt(w, 0)
if err != nil { if err != nil {
return err return err
} }

View File

@ -46,7 +46,7 @@ func (msg *MsgInv) AddInvVect(iv *InvVect) error {
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver. // BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation. // This is part of the Message interface implementation.
func (msg *MsgInv) BtcDecode(r io.Reader, pver uint32) error { func (msg *MsgInv) BtcDecode(r io.Reader, pver uint32) error {
count, err := ReadVarInt(r, pver) count, err := ReadVarInt(r)
if err != nil { if err != nil {
return err return err
} }
@ -83,7 +83,7 @@ func (msg *MsgInv) BtcEncode(w io.Writer, pver uint32) error {
return messageError("MsgInv.BtcEncode", str) return messageError("MsgInv.BtcEncode", str)
} }
err := WriteVarInt(w, pver, uint64(count)) err := WriteVarInt(w, uint64(count))
if err != nil { if err != nil {
return err return err
} }

View File

@ -48,13 +48,13 @@ func (msg *MsgMerkleBlock) BtcDecode(r io.Reader, pver uint32) error {
return err return err
} }
err = readElement(r, &msg.Transactions) err = ReadElement(r, &msg.Transactions)
if err != nil { if err != nil {
return err return err
} }
// Read num block locator hashes and limit to max. // Read num block locator hashes and limit to max.
count, err := ReadVarInt(r, pver) count, err := ReadVarInt(r)
if err != nil { if err != nil {
return err return err
} }
@ -70,7 +70,7 @@ func (msg *MsgMerkleBlock) BtcDecode(r io.Reader, pver uint32) error {
msg.Hashes = make([]*daghash.Hash, 0, count) msg.Hashes = make([]*daghash.Hash, 0, count)
for i := uint64(0); i < count; i++ { for i := uint64(0); i < count; i++ {
hash := &daghash.Hash{} hash := &daghash.Hash{}
err := readElement(r, hash) err := ReadElement(r, hash)
if err != nil { if err != nil {
return err return err
} }
@ -105,17 +105,17 @@ func (msg *MsgMerkleBlock) BtcEncode(w io.Writer, pver uint32) error {
return err return err
} }
err = writeElement(w, msg.Transactions) err = WriteElement(w, msg.Transactions)
if err != nil { if err != nil {
return err return err
} }
err = WriteVarInt(w, pver, uint64(numHashes)) err = WriteVarInt(w, uint64(numHashes))
if err != nil { if err != nil {
return err return err
} }
for _, hash := range msg.Hashes { for _, hash := range msg.Hashes {
err = writeElement(w, hash) err = WriteElement(w, hash)
if err != nil { if err != nil {
return err return err
} }

View File

@ -274,7 +274,7 @@ func TestMerkleBlockOverflowErrors(t *testing.T) {
// Create bytes for a merkle block that claims to have more than the max // Create bytes for a merkle block that claims to have more than the max
// allowed tx hashes. // allowed tx hashes.
var buf bytes.Buffer var buf bytes.Buffer
WriteVarInt(&buf, pver, maxTxPerBlock+1) WriteVarInt(&buf, maxTxPerBlock+1)
numHashesOffset := 157 numHashesOffset := 157
exceedMaxHashes := make([]byte, numHashesOffset) exceedMaxHashes := make([]byte, numHashesOffset)
copy(exceedMaxHashes, merkleBlockOneBytes[:numHashesOffset]) copy(exceedMaxHashes, merkleBlockOneBytes[:numHashesOffset])
@ -283,7 +283,7 @@ func TestMerkleBlockOverflowErrors(t *testing.T) {
// Create bytes for a merkle block that claims to have more than the max // Create bytes for a merkle block that claims to have more than the max
// allowed flag bytes. // allowed flag bytes.
buf.Reset() buf.Reset()
WriteVarInt(&buf, pver, maxFlagsPerMerkleBlock+1) WriteVarInt(&buf, maxFlagsPerMerkleBlock+1)
numFlagBytesOffset := 190 numFlagBytesOffset := 190
exceedMaxFlagBytes := make([]byte, numFlagBytesOffset) exceedMaxFlagBytes := make([]byte, numFlagBytesOffset)
copy(exceedMaxFlagBytes, merkleBlockOneBytes[:numFlagBytesOffset]) copy(exceedMaxFlagBytes, merkleBlockOneBytes[:numFlagBytesOffset])

View File

@ -35,7 +35,7 @@ func (msg *MsgNotFound) AddInvVect(iv *InvVect) error {
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver. // BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation. // This is part of the Message interface implementation.
func (msg *MsgNotFound) BtcDecode(r io.Reader, pver uint32) error { func (msg *MsgNotFound) BtcDecode(r io.Reader, pver uint32) error {
count, err := ReadVarInt(r, pver) count, err := ReadVarInt(r)
if err != nil { if err != nil {
return err return err
} }
@ -72,7 +72,7 @@ func (msg *MsgNotFound) BtcEncode(w io.Writer, pver uint32) error {
return messageError("MsgNotFound.BtcEncode", str) return messageError("MsgNotFound.BtcEncode", str)
} }
err := WriteVarInt(w, pver, uint64(count)) err := WriteVarInt(w, uint64(count))
if err != nil { if err != nil {
return err return err
} }

View File

@ -28,7 +28,7 @@ type MsgPing struct {
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver. // BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation. // This is part of the Message interface implementation.
func (msg *MsgPing) BtcDecode(r io.Reader, pver uint32) error { func (msg *MsgPing) BtcDecode(r io.Reader, pver uint32) error {
err := readElement(r, &msg.Nonce) err := ReadElement(r, &msg.Nonce)
if err != nil { if err != nil {
return err return err
} }
@ -39,7 +39,7 @@ func (msg *MsgPing) BtcDecode(r io.Reader, pver uint32) error {
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding. // BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation. // This is part of the Message interface implementation.
func (msg *MsgPing) BtcEncode(w io.Writer, pver uint32) error { func (msg *MsgPing) BtcEncode(w io.Writer, pver uint32) error {
err := writeElement(w, msg.Nonce) err := WriteElement(w, msg.Nonce)
if err != nil { if err != nil {
return err return err
} }

View File

@ -22,13 +22,13 @@ type MsgPong struct {
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver. // BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation. // This is part of the Message interface implementation.
func (msg *MsgPong) BtcDecode(r io.Reader, pver uint32) error { func (msg *MsgPong) BtcDecode(r io.Reader, pver uint32) error {
return readElement(r, &msg.Nonce) return ReadElement(r, &msg.Nonce)
} }
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding. // BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation. // This is part of the Message interface implementation.
func (msg *MsgPong) BtcEncode(w io.Writer, pver uint32) error { func (msg *MsgPong) BtcEncode(w io.Writer, pver uint32) error {
return writeElement(w, msg.Nonce) return WriteElement(w, msg.Nonce)
} }
// Command returns the protocol command string for the message. This is part // Command returns the protocol command string for the message. This is part

View File

@ -82,7 +82,7 @@ func (msg *MsgReject) BtcDecode(r io.Reader, pver uint32) error {
msg.Cmd = cmd msg.Cmd = cmd
// Code indicating why the command was rejected. // Code indicating why the command was rejected.
err = readElement(r, &msg.Code) err = ReadElement(r, &msg.Code)
if err != nil { if err != nil {
return err return err
} }
@ -99,7 +99,7 @@ func (msg *MsgReject) BtcDecode(r io.Reader, pver uint32) error {
// identifies the specific block or transaction. // identifies the specific block or transaction.
if msg.Cmd == CmdBlock || msg.Cmd == CmdTx { if msg.Cmd == CmdBlock || msg.Cmd == CmdTx {
msg.Hash = &daghash.Hash{} msg.Hash = &daghash.Hash{}
err := readElement(r, msg.Hash) err := ReadElement(r, msg.Hash)
if err != nil { if err != nil {
return err return err
} }
@ -112,20 +112,20 @@ func (msg *MsgReject) BtcDecode(r io.Reader, pver uint32) error {
// This is part of the Message interface implementation. // This is part of the Message interface implementation.
func (msg *MsgReject) BtcEncode(w io.Writer, pver uint32) error { func (msg *MsgReject) BtcEncode(w io.Writer, pver uint32) error {
// Command that was rejected. // Command that was rejected.
err := WriteVarString(w, pver, msg.Cmd) err := WriteVarString(w, msg.Cmd)
if err != nil { if err != nil {
return err return err
} }
// Code indicating why the command was rejected. // Code indicating why the command was rejected.
err = writeElement(w, msg.Code) err = WriteElement(w, msg.Code)
if err != nil { if err != nil {
return err return err
} }
// Human readable string with specific details (over and above the // Human readable string with specific details (over and above the
// reject code above) about why the command was rejected. // reject code above) about why the command was rejected.
err = WriteVarString(w, pver, msg.Reason) err = WriteVarString(w, msg.Reason)
if err != nil { if err != nil {
return err return err
} }
@ -133,7 +133,7 @@ func (msg *MsgReject) BtcEncode(w io.Writer, pver uint32) error {
// CmdBlock and CmdTx messages have an additional hash field that // CmdBlock and CmdTx messages have an additional hash field that
// identifies the specific block or transaction. // identifies the specific block or transaction.
if msg.Cmd == CmdBlock || msg.Cmd == CmdTx { if msg.Cmd == CmdBlock || msg.Cmd == CmdTx {
err := writeElement(w, msg.Hash) err := WriteElement(w, msg.Hash)
if err != nil { if err != nil {
return err return err
} }

View File

@ -436,7 +436,7 @@ func (msg *MsgTx) BtcDecode(r io.Reader, pver uint32) error {
} }
msg.Version = int32(version) msg.Version = int32(version)
count, err := ReadVarInt(r, pver) count, err := ReadVarInt(r)
if err != nil { if err != nil {
return err return err
} }
@ -488,7 +488,7 @@ func (msg *MsgTx) BtcDecode(r io.Reader, pver uint32) error {
totalScriptSize += uint64(len(ti.SignatureScript)) totalScriptSize += uint64(len(ti.SignatureScript))
} }
count, err = ReadVarInt(r, pver) count, err = ReadVarInt(r)
if err != nil { if err != nil {
returnScriptBuffers() returnScriptBuffers()
return err return err
@ -542,14 +542,14 @@ func (msg *MsgTx) BtcDecode(r io.Reader, pver uint32) error {
} }
var payloadHash daghash.Hash var payloadHash daghash.Hash
err = readElement(r, &payloadHash) err = ReadElement(r, &payloadHash)
if err != nil { if err != nil {
returnScriptBuffers() returnScriptBuffers()
return err return err
} }
msg.PayloadHash = &payloadHash msg.PayloadHash = &payloadHash
payloadLength, err := ReadVarInt(r, pver) payloadLength, err := ReadVarInt(r)
if err != nil { if err != nil {
returnScriptBuffers() returnScriptBuffers()
return err return err
@ -643,7 +643,7 @@ func (msg *MsgTx) encode(w io.Writer, pver uint32, encodingFlags txEncoding) err
} }
count := uint64(len(msg.TxIn)) count := uint64(len(msg.TxIn))
err = WriteVarInt(w, pver, count) err = WriteVarInt(w, count)
if err != nil { if err != nil {
return err return err
} }
@ -656,7 +656,7 @@ func (msg *MsgTx) encode(w io.Writer, pver uint32, encodingFlags txEncoding) err
} }
count = uint64(len(msg.TxOut)) count = uint64(len(msg.TxOut))
err = WriteVarInt(w, pver, count) err = WriteVarInt(w, count)
if err != nil { if err != nil {
return err return err
} }
@ -689,16 +689,16 @@ func (msg *MsgTx) encode(w io.Writer, pver uint32, encodingFlags txEncoding) err
return err return err
} }
err = writeElement(w, msg.PayloadHash) err = WriteElement(w, msg.PayloadHash)
if err != nil { if err != nil {
return err return err
} }
if encodingFlags&txEncodingExcludePayload != txEncodingExcludePayload { if encodingFlags&txEncodingExcludePayload != txEncodingExcludePayload {
err = WriteVarInt(w, pver, uint64(len(msg.Payload))) err = WriteVarInt(w, uint64(len(msg.Payload)))
w.Write(msg.Payload) w.Write(msg.Payload)
} else { } else {
err = WriteVarInt(w, pver, 0) err = WriteVarInt(w, 0)
} }
if err != nil { if err != nil {
return err return err
@ -937,7 +937,7 @@ func writeOutPoint(w io.Writer, pver uint32, version int32, op *OutPoint) error
// fieldName parameter is only used for the error message so it provides more // fieldName parameter is only used for the error message so it provides more
// context in the error. // context in the error.
func readScript(r io.Reader, pver uint32, maxAllowed uint32, fieldName string) ([]byte, error) { func readScript(r io.Reader, pver uint32, maxAllowed uint32, fieldName string) ([]byte, error) {
count, err := ReadVarInt(r, pver) count, err := ReadVarInt(r)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -974,7 +974,7 @@ func readTxIn(r io.Reader, pver uint32, version int32, ti *TxIn) error {
return err return err
} }
return readElement(r, &ti.Sequence) return ReadElement(r, &ti.Sequence)
} }
// writeTxIn encodes ti to the bitcoin protocol encoding for a transaction // writeTxIn encodes ti to the bitcoin protocol encoding for a transaction
@ -1000,7 +1000,7 @@ func writeTxIn(w io.Writer, pver uint32, version int32, ti *TxIn, encodingFlags
// readTxOut reads the next sequence of bytes from r as a transaction output // readTxOut reads the next sequence of bytes from r as a transaction output
// (TxOut). // (TxOut).
func readTxOut(r io.Reader, pver uint32, version int32, to *TxOut) error { func readTxOut(r io.Reader, pver uint32, version int32, to *TxOut) error {
err := readElement(r, &to.Value) err := ReadElement(r, &to.Value)
if err != nil { if err != nil {
return err return err
} }

View File

@ -97,7 +97,7 @@ func (msg *MsgVersion) BtcDecode(r io.Reader, pver uint32) error {
// Read subnetwork ID // Read subnetwork ID
var isFullNode bool var isFullNode bool
err = readElement(r, &isFullNode) err = ReadElement(r, &isFullNode)
if err != nil { if err != nil {
return err return err
} }
@ -105,7 +105,7 @@ func (msg *MsgVersion) BtcDecode(r io.Reader, pver uint32) error {
msg.SubnetworkID = nil msg.SubnetworkID = nil
} else { } else {
var subnetworkID subnetworkid.SubnetworkID var subnetworkID subnetworkid.SubnetworkID
err = readElement(r, &subnetworkID) err = ReadElement(r, &subnetworkID)
if err != nil { if err != nil {
return err return err
} }
@ -121,7 +121,7 @@ func (msg *MsgVersion) BtcDecode(r io.Reader, pver uint32) error {
if err != nil { if err != nil {
return err return err
} }
err = readElement(buf, &msg.Nonce) err = ReadElement(buf, &msg.Nonce)
if err != nil { if err != nil {
return err return err
} }
@ -136,13 +136,13 @@ func (msg *MsgVersion) BtcDecode(r io.Reader, pver uint32) error {
msg.UserAgent = userAgent msg.UserAgent = userAgent
msg.SelectedTip = &daghash.Hash{} msg.SelectedTip = &daghash.Hash{}
err = readElement(buf, msg.SelectedTip) err = ReadElement(buf, msg.SelectedTip)
if err != nil { if err != nil {
return err return err
} }
var relayTx bool var relayTx bool
err = readElement(r, &relayTx) err = ReadElement(r, &relayTx)
if err != nil { if err != nil {
return err return err
} }
@ -167,12 +167,12 @@ func (msg *MsgVersion) BtcEncode(w io.Writer, pver uint32) error {
// Write subnetwork ID // Write subnetwork ID
isFullNode := msg.SubnetworkID == nil isFullNode := msg.SubnetworkID == nil
err = writeElement(w, isFullNode) err = WriteElement(w, isFullNode)
if err != nil { if err != nil {
return err return err
} }
if !isFullNode { if !isFullNode {
err = writeElement(w, msg.SubnetworkID) err = WriteElement(w, msg.SubnetworkID)
if err != nil { if err != nil {
return err return err
} }
@ -188,24 +188,24 @@ func (msg *MsgVersion) BtcEncode(w io.Writer, pver uint32) error {
return err return err
} }
err = writeElement(w, msg.Nonce) err = WriteElement(w, msg.Nonce)
if err != nil { if err != nil {
return err return err
} }
err = WriteVarString(w, pver, msg.UserAgent) err = WriteVarString(w, msg.UserAgent)
if err != nil { if err != nil {
return err return err
} }
err = writeElement(w, msg.SelectedTip) err = WriteElement(w, msg.SelectedTip)
if err != nil { if err != nil {
return err return err
} }
// The wire encoding for the field is true when transactions should be // The wire encoding for the field is true when transactions should be
// relayed, so reverse it from the DisableRelayTx field. // relayed, so reverse it from the DisableRelayTx field.
err = writeElement(w, !msg.DisableRelayTx) err = WriteElement(w, !msg.DisableRelayTx)
if err != nil { if err != nil {
return err return err
} }

View File

@ -213,7 +213,7 @@ func TestVersionWireErrors(t *testing.T) {
// Encode the new UA length as a varint. // Encode the new UA length as a varint.
var newUAVarIntBuf bytes.Buffer var newUAVarIntBuf bytes.Buffer
err := WriteVarInt(&newUAVarIntBuf, pver, uint64(len(newUA))) err := WriteVarInt(&newUAVarIntBuf, uint64(len(newUA)))
if err != nil { if err != nil {
t.Errorf("WriteVarInt: error %v", err) t.Errorf("WriteVarInt: error %v", err)
} }

View File

@ -83,7 +83,7 @@ func readNetAddress(r io.Reader, pver uint32, na *NetAddress, ts bool) error {
var ip [16]byte var ip [16]byte
if ts { if ts {
err := readElement(r, (*int64Time)(&na.Timestamp)) err := ReadElement(r, (*int64Time)(&na.Timestamp))
if err != nil { if err != nil {
return err return err
} }
@ -113,7 +113,7 @@ func readNetAddress(r io.Reader, pver uint32, na *NetAddress, ts bool) error {
// like version do not include the timestamp. // like version do not include the timestamp.
func writeNetAddress(w io.Writer, pver uint32, na *NetAddress, ts bool) error { func writeNetAddress(w io.Writer, pver uint32, na *NetAddress, ts bool) error {
if ts { if ts {
err := writeElement(w, int64(na.Timestamp.Unix())) err := WriteElement(w, int64(na.Timestamp.Unix()))
if err != nil { if err != nil {
return err return err
} }