mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-06-05 21:56:50 +00:00
[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:
parent
9276494820
commit
1a2166cddf
107
blockdag/dag.go
107
blockdag/dag.go
@ -150,6 +150,7 @@ type BlockDAG struct {
|
||||
lastFinalityPoint *blockNode
|
||||
|
||||
SubnetworkStore *SubnetworkStore
|
||||
utxoDiffStore *utxoDiffStore
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
// 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)
|
||||
if err != nil {
|
||||
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,
|
||||
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.
|
||||
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.
|
||||
state := &dagState{
|
||||
TipHashes: dag.TipHashes(),
|
||||
LastFinalityPoint: dag.lastFinalityPoint.hash,
|
||||
}
|
||||
err := dbPutDAGState(dbTx, state)
|
||||
err = dbPutDAGState(dbTx, state)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -614,6 +620,11 @@ func (dag *BlockDAG) saveChangesFromBlock(node *blockNode, block *util.Block, vi
|
||||
// Apply the fee data into the database
|
||||
return dbStoreFeeData(dbTx, block.Hash(), feeData)
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dag.utxoDiffStore.clearDirtyEntries()
|
||||
return nil
|
||||
}
|
||||
|
||||
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) (
|
||||
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)
|
||||
}
|
||||
|
||||
@ -740,13 +751,13 @@ func (dag *BlockDAG) applyDAGChanges(node *blockNode, block *util.Block, newBloc
|
||||
dag.virtual.AddTip(node)
|
||||
|
||||
// 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 {
|
||||
return nil, fmt.Errorf("could not restore past UTXO for virtual %s: %s", dag.virtual, err)
|
||||
}
|
||||
|
||||
// Apply new utxoDiffs to all the tips
|
||||
err = updateTipsUTXO(dag.virtual.parents, dag.virtual, newVirtualUTXO)
|
||||
err = updateTipsUTXO(dag, newVirtualUTXO)
|
||||
if err != nil {
|
||||
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
|
||||
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)
|
||||
|
||||
// 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) (
|
||||
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 {
|
||||
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
|
||||
// To save traversals over the blue blocks, it also returns the transaction acceptance data for
|
||||
// all blue blocks
|
||||
func (node *blockNode) pastUTXO(virtual *virtualBlock, db database.DB) (
|
||||
func (node *blockNode) pastUTXO(dag *BlockDAG) (
|
||||
pastUTXO UTXOSet, bluesTxsAcceptanceData MultiBlockTxsAcceptanceData, err error) {
|
||||
|
||||
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 {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
blueBlocks, err := node.fetchBlueBlocks(db)
|
||||
blueBlocks, err := node.fetchBlueBlocks(dag.db)
|
||||
if err != nil {
|
||||
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
|
||||
func (node *blockNode) restoreUTXO(virtual *virtualBlock) (UTXOSet, error) {
|
||||
stack := []*blockNode{node}
|
||||
current := node
|
||||
func (node *blockNode) restoreUTXO(dag *BlockDAG) (UTXOSet, error) {
|
||||
stack := []*blockNode{}
|
||||
|
||||
for current.diffChild != nil {
|
||||
current = current.diffChild
|
||||
for current := node; current != nil; {
|
||||
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-- {
|
||||
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 {
|
||||
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
|
||||
// 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()
|
||||
return node.updateParentsDiffs(virtual, newBlockUTXO)
|
||||
return node.updateParentsDiffs(dag, newBlockUTXO)
|
||||
}
|
||||
|
||||
// updateParentsDiffs updates the diff of any parent whose DiffChild is this block
|
||||
func (node *blockNode) updateParentsDiffs(virtual *virtualBlock, newBlockUTXO UTXOSet) error {
|
||||
virtualDiffFromNewBlock, err := virtual.utxoSet.diffFrom(newBlockUTXO)
|
||||
func (node *blockNode) updateParentsDiffs(dag *BlockDAG, newBlockUTXO UTXOSet) error {
|
||||
virtualDiffFromNewBlock, err := dag.virtual.utxoSet.diffFrom(newBlockUTXO)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
node.diff = virtualDiffFromNewBlock
|
||||
err = dag.utxoDiffStore.setBlockDiff(node, virtualDiffFromNewBlock)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, parent := range node.parents {
|
||||
if parent.diffChild == nil {
|
||||
parentUTXO, err := parent.restoreUTXO(virtual)
|
||||
diffChild, err := dag.utxoDiffStore.diffChildByNode(parent)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if diffChild == nil {
|
||||
parentUTXO, err := parent.restoreUTXO(dag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
parent.diffChild = node
|
||||
parent.diff, err = newBlockUTXO.diffFrom(parentUTXO)
|
||||
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
|
||||
func updateTipsUTXO(tips blockSet, virtual *virtualBlock, virtualUTXO UTXOSet) error {
|
||||
for _, tip := range tips {
|
||||
tipUTXO, err := tip.restoreUTXO(virtual)
|
||||
func updateTipsUTXO(dag *BlockDAG, virtualUTXO UTXOSet) error {
|
||||
for _, tip := range dag.virtual.parents {
|
||||
tipUTXO, err := tip.restoreUTXO(dag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tip.diff, err = virtualUTXO.diffFrom(tipUTXO)
|
||||
diff, err := virtualUTXO.diffFrom(tipUTXO)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dag.utxoDiffStore.setBlockDiff(tip, diff)
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -1670,6 +1691,8 @@ func New(config *Config) (*BlockDAG, error) {
|
||||
subnetworkID: config.SubnetworkID,
|
||||
}
|
||||
|
||||
dag.utxoDiffStore = newUTXODiffStore(&dag)
|
||||
|
||||
// Initialize the chain state from the passed database. When the db
|
||||
// does not yet contain any DAG state, both it and the DAG state
|
||||
// will be initialized to contain only the genesis block.
|
||||
|
@ -54,6 +54,10 @@ var (
|
||||
// unspent transaction output set.
|
||||
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
|
||||
// subnetwork registry.
|
||||
subnetworksBucketName = []byte("subnetworks")
|
||||
@ -466,14 +470,18 @@ func (dag *BlockDAG) createDAGState() error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create the bucket that houses the utxo set and store its
|
||||
// version. Note that the genesis block coinbase transaction is
|
||||
// intentionally not inserted here since it is not spendable by
|
||||
// consensus rules.
|
||||
// Create the buckets that house the utxo set, the utxo diffs, and their
|
||||
// version.
|
||||
_, err = meta.CreateBucket(utxoSetBucketName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = meta.CreateBucket(utxoDiffsBucketName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = dbPutVersion(dbTx, utxoSetVersionKeyName,
|
||||
latestUTXOSetBucketVersion)
|
||||
if err != nil {
|
||||
@ -608,6 +616,7 @@ func (dag *BlockDAG) initDAGState() error {
|
||||
node := &blockNodes[i]
|
||||
initBlockNode(node, header, parents, dag.dagParams.K)
|
||||
node.status = status
|
||||
node.updateParentsChildren()
|
||||
dag.index.addNode(node)
|
||||
|
||||
if blockStatus(status).KnownValid() {
|
||||
|
@ -197,7 +197,7 @@ func GetVirtualFromParentsForTest(dag *BlockDAG, parentHashes []*daghash.Hash) (
|
||||
}
|
||||
virtual := newVirtualBlock(parents, dag.dagParams.K)
|
||||
|
||||
pastUTXO, _, err := virtual.pastUTXO(dag.virtual, dag.db)
|
||||
pastUTXO, _, err := virtual.pastUTXO(dag)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
321
blockdag/utxodiffstore.go
Normal file
321
blockdag/utxodiffstore.go
Normal 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)
|
||||
}
|
87
blockdag/utxodiffstore_test.go
Normal file
87
blockdag/utxodiffstore_test.go
Normal 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")
|
||||
}
|
||||
}
|
@ -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.
|
||||
// we will compare it with the key next.
|
||||
var buf bytes.Buffer
|
||||
wire.WriteVarString(&buf, 0, "Bitcoin Signed Message:\n")
|
||||
wire.WriteVarString(&buf, 0, c.Message)
|
||||
wire.WriteVarString(&buf, "Bitcoin Signed Message:\n")
|
||||
wire.WriteVarString(&buf, c.Message)
|
||||
expectedMessageHash := daghash.DoubleHashB(buf.Bytes())
|
||||
pk, wasCompressed, err := btcec.RecoverCompact(btcec.S256(), sig,
|
||||
expectedMessageHash)
|
||||
|
@ -195,7 +195,7 @@ func FromBytes(N uint32, P uint8, d []byte) (*Filter, error) {
|
||||
// filter as returned by NBytes().
|
||||
func FromNBytes(P uint8, d []byte) (*Filter, error) {
|
||||
buffer := bytes.NewBuffer(d)
|
||||
N, err := wire.ReadVarInt(buffer, varIntProtoVer)
|
||||
N, err := wire.ReadVarInt(buffer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -216,7 +216,7 @@ func FromPBytes(N uint32, d []byte) (*Filter, error) {
|
||||
func FromNPBytes(d []byte) (*Filter, error) {
|
||||
buffer := bytes.NewBuffer(d)
|
||||
|
||||
N, err := wire.ReadVarInt(buffer, varIntProtoVer)
|
||||
N, err := wire.ReadVarInt(buffer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -246,7 +246,7 @@ func (f *Filter) NBytes() ([]byte, error) {
|
||||
var buffer bytes.Buffer
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
@ -274,7 +274,7 @@ func (f *Filter) NPBytes() ([]byte, error) {
|
||||
var buffer bytes.Buffer
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ var genesisCoinbaseTx = NewNativeMsgTx(1, genesisCoinbaseTxIns, genesisCoinbaseT
|
||||
// a single byte variable length integer.
|
||||
func BenchmarkWriteVarInt1(b *testing.B) {
|
||||
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.
|
||||
func BenchmarkWriteVarInt3(b *testing.B) {
|
||||
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.
|
||||
func BenchmarkWriteVarInt5(b *testing.B) {
|
||||
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.
|
||||
func BenchmarkWriteVarInt9(b *testing.B) {
|
||||
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)
|
||||
for i := 0; i < b.N; i++ {
|
||||
r.Seek(0, 0)
|
||||
ReadVarInt(r, 0)
|
||||
ReadVarInt(r)
|
||||
}
|
||||
}
|
||||
|
||||
@ -108,7 +108,7 @@ func BenchmarkReadVarInt3(b *testing.B) {
|
||||
r := bytes.NewReader(buf)
|
||||
for i := 0; i < b.N; i++ {
|
||||
r.Seek(0, 0)
|
||||
ReadVarInt(r, 0)
|
||||
ReadVarInt(r)
|
||||
}
|
||||
}
|
||||
|
||||
@ -119,7 +119,7 @@ func BenchmarkReadVarInt5(b *testing.B) {
|
||||
r := bytes.NewReader(buf)
|
||||
for i := 0; i < b.N; i++ {
|
||||
r.Seek(0, 0)
|
||||
ReadVarInt(r, 0)
|
||||
ReadVarInt(r)
|
||||
}
|
||||
}
|
||||
|
||||
@ -130,7 +130,7 @@ func BenchmarkReadVarInt9(b *testing.B) {
|
||||
r := bytes.NewReader(buf)
|
||||
for i := 0; i < b.N; i++ {
|
||||
r.Seek(0, 0)
|
||||
ReadVarInt(r, 0)
|
||||
ReadVarInt(r)
|
||||
}
|
||||
}
|
||||
|
||||
@ -160,7 +160,7 @@ func BenchmarkReadVarStr10(b *testing.B) {
|
||||
// four byte variable length string.
|
||||
func BenchmarkWriteVarStr4(b *testing.B) {
|
||||
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.
|
||||
func BenchmarkWriteVarStr10(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
WriteVarString(ioutil.Discard, 0, "test012345")
|
||||
WriteVarString(ioutil.Discard, "test012345")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -158,7 +158,7 @@ func readBlockHeader(r io.Reader, pver uint32, bh *BlockHeader) error {
|
||||
bh.ParentHashes = make([]*daghash.Hash, numParentBlocks)
|
||||
for i := byte(0); i < numParentBlocks; i++ {
|
||||
hash := &daghash.Hash{}
|
||||
err := readElement(r, hash)
|
||||
err := ReadElement(r, hash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -178,7 +178,7 @@ func writeBlockHeader(w io.Writer, pver uint32, bh *BlockHeader) error {
|
||||
return err
|
||||
}
|
||||
for _, hash := range bh.ParentHashes {
|
||||
if err := writeElement(w, hash); err != nil {
|
||||
if err := WriteElement(w, hash); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -39,9 +39,9 @@ var errNonCanonicalVarInt = "non-canonical varint %x - discriminant %x must " +
|
||||
// time.Time since it is otherwise ambiguous.
|
||||
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.
|
||||
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
|
||||
// type assertions first.
|
||||
switch e := element.(type) {
|
||||
@ -186,7 +186,7 @@ func readElement(r io.Reader, element interface{}) error {
|
||||
// calls to readElement.
|
||||
func readElements(r io.Reader, elements ...interface{}) error {
|
||||
for _, element := range elements {
|
||||
err := readElement(r, element)
|
||||
err := ReadElement(r, element)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -194,8 +194,8 @@ func readElements(r io.Reader, elements ...interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// writeElement writes the little endian representation of element to w.
|
||||
func writeElement(w io.Writer, element interface{}) error {
|
||||
// WriteElement writes the little endian representation of element to w.
|
||||
func WriteElement(w io.Writer, element interface{}) error {
|
||||
// Attempt to write the element based on the concrete type via fast
|
||||
// type assertions first.
|
||||
switch e := element.(type) {
|
||||
@ -322,7 +322,7 @@ func writeElement(w io.Writer, element interface{}) error {
|
||||
// calls to writeElement.
|
||||
func writeElements(w io.Writer, elements ...interface{}) error {
|
||||
for _, element := range elements {
|
||||
err := writeElement(w, element)
|
||||
err := WriteElement(w, element)
|
||||
if err != nil {
|
||||
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.
|
||||
func ReadVarInt(r io.Reader, pver uint32) (uint64, error) {
|
||||
func ReadVarInt(r io.Reader) (uint64, error) {
|
||||
discriminant, err := binaryserializer.Uint8(r)
|
||||
if err != nil {
|
||||
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
|
||||
// on its value.
|
||||
func WriteVarInt(w io.Writer, pver uint32, val uint64) error {
|
||||
func WriteVarInt(w io.Writer, val uint64) error {
|
||||
if val < 0xfd {
|
||||
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
|
||||
// attacks and forced panics through malformed messages.
|
||||
func ReadVarString(r io.Reader, pver uint32) (string, error) {
|
||||
count, err := ReadVarInt(r, pver)
|
||||
count, err := ReadVarInt(r)
|
||||
if err != nil {
|
||||
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
|
||||
// the length of the string followed by the bytes that represent the string
|
||||
// itself.
|
||||
func WriteVarString(w io.Writer, pver uint32, str string) error {
|
||||
err := WriteVarInt(w, pver, uint64(len(str)))
|
||||
func WriteVarString(w io.Writer, str string) error {
|
||||
err := WriteVarInt(w, uint64(len(str)))
|
||||
if err != nil {
|
||||
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,
|
||||
fieldName string) ([]byte, error) {
|
||||
|
||||
count, err := ReadVarInt(r, pver)
|
||||
count, err := ReadVarInt(r)
|
||||
if err != nil {
|
||||
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.
|
||||
func WriteVarBytes(w io.Writer, pver uint32, bytes []byte) error {
|
||||
slen := uint64(len(bytes))
|
||||
err := WriteVarInt(w, pver, slen)
|
||||
err := WriteVarInt(w, slen)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -138,7 +138,7 @@ func TestElementWire(t *testing.T) {
|
||||
for i, test := range tests {
|
||||
// Write to wire format.
|
||||
var buf bytes.Buffer
|
||||
err := writeElement(&buf, test.in)
|
||||
err := WriteElement(&buf, test.in)
|
||||
if err != nil {
|
||||
t.Errorf("writeElement #%d error %v", i, err)
|
||||
continue
|
||||
@ -155,7 +155,7 @@ func TestElementWire(t *testing.T) {
|
||||
if reflect.ValueOf(test.in).Kind() != reflect.Ptr {
|
||||
val = reflect.New(reflect.TypeOf(test.in)).Interface()
|
||||
}
|
||||
err = readElement(rbuf, val)
|
||||
err = ReadElement(rbuf, val)
|
||||
if err != nil {
|
||||
t.Errorf("readElement #%d error %v", i, err)
|
||||
continue
|
||||
@ -218,7 +218,7 @@ func TestElementWireErrors(t *testing.T) {
|
||||
for i, test := range tests {
|
||||
// Encode to wire format.
|
||||
w := newFixedWriter(test.max)
|
||||
err := writeElement(w, test.in)
|
||||
err := WriteElement(w, test.in)
|
||||
if err != test.writeErr {
|
||||
t.Errorf("writeElement #%d wrong error got: %v, want: %v",
|
||||
i, err, test.writeErr)
|
||||
@ -231,7 +231,7 @@ func TestElementWireErrors(t *testing.T) {
|
||||
if reflect.ValueOf(test.in).Kind() != reflect.Ptr {
|
||||
val = reflect.New(reflect.TypeOf(test.in)).Interface()
|
||||
}
|
||||
err = readElement(r, val)
|
||||
err = ReadElement(r, val)
|
||||
if err != test.readErr {
|
||||
t.Errorf("readElement #%d wrong error got: %v, want: %v",
|
||||
i, err, test.readErr)
|
||||
@ -242,38 +242,33 @@ func TestElementWireErrors(t *testing.T) {
|
||||
|
||||
// TestVarIntWire tests wire encode and decode for variable length integers.
|
||||
func TestVarIntWire(t *testing.T) {
|
||||
pver := ProtocolVersion
|
||||
|
||||
tests := []struct {
|
||||
in uint64 // Value to encode
|
||||
out uint64 // Expected decoded value
|
||||
buf []byte // Wire encoding
|
||||
pver uint32 // Protocol version for wire encoding
|
||||
in uint64 // Value to encode
|
||||
out uint64 // Expected decoded value
|
||||
buf []byte // Wire encoding
|
||||
}{
|
||||
// Latest protocol version.
|
||||
// Single byte
|
||||
{0, 0, []byte{0x00}, pver},
|
||||
{0, 0, []byte{0x00}},
|
||||
// Max single byte
|
||||
{0xfc, 0xfc, []byte{0xfc}, pver},
|
||||
{0xfc, 0xfc, []byte{0xfc}},
|
||||
// Min 2-byte
|
||||
{0xfd, 0xfd, []byte{0xfd, 0x0fd, 0x00}, pver},
|
||||
{0xfd, 0xfd, []byte{0xfd, 0x0fd, 0x00}},
|
||||
// Max 2-byte
|
||||
{0xffff, 0xffff, []byte{0xfd, 0xff, 0xff}, pver},
|
||||
{0xffff, 0xffff, []byte{0xfd, 0xff, 0xff}},
|
||||
// Min 4-byte
|
||||
{0x10000, 0x10000, []byte{0xfe, 0x00, 0x00, 0x01, 0x00}, pver},
|
||||
{0x10000, 0x10000, []byte{0xfe, 0x00, 0x00, 0x01, 0x00}},
|
||||
// Max 4-byte
|
||||
{0xffffffff, 0xffffffff, []byte{0xfe, 0xff, 0xff, 0xff, 0xff}, pver},
|
||||
{0xffffffff, 0xffffffff, []byte{0xfe, 0xff, 0xff, 0xff, 0xff}},
|
||||
// Min 8-byte
|
||||
{
|
||||
0x100000000, 0x100000000,
|
||||
[]byte{0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00},
|
||||
pver,
|
||||
},
|
||||
// Max 8-byte
|
||||
{
|
||||
0xffffffffffffffff, 0xffffffffffffffff,
|
||||
[]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 {
|
||||
// Encode to wire format.
|
||||
var buf bytes.Buffer
|
||||
err := WriteVarInt(&buf, test.pver, test.in)
|
||||
err := WriteVarInt(&buf, test.in)
|
||||
if err != nil {
|
||||
t.Errorf("WriteVarInt #%d error %v", i, err)
|
||||
continue
|
||||
@ -294,7 +289,7 @@ func TestVarIntWire(t *testing.T) {
|
||||
|
||||
// Decode from wire format.
|
||||
rbuf := bytes.NewReader(test.buf)
|
||||
val, err := ReadVarInt(rbuf, test.pver)
|
||||
val, err := ReadVarInt(rbuf)
|
||||
if err != nil {
|
||||
t.Errorf("ReadVarInt #%d error %v", i, err)
|
||||
continue
|
||||
@ -310,34 +305,31 @@ func TestVarIntWire(t *testing.T) {
|
||||
// TestVarIntWireErrors performs negative tests against wire encode and decode
|
||||
// of variable length integers to confirm error paths work correctly.
|
||||
func TestVarIntWireErrors(t *testing.T) {
|
||||
pver := ProtocolVersion
|
||||
|
||||
tests := []struct {
|
||||
in uint64 // Value to encode
|
||||
buf []byte // Wire encoding
|
||||
pver uint32 // Protocol version for wire encoding
|
||||
max int // Max size of fixed buffer to induce errors
|
||||
writeErr error // Expected write error
|
||||
readErr error // Expected read error
|
||||
}{
|
||||
// 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.
|
||||
{0xfd, []byte{0xfd}, pver, 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}, 0, io.ErrShortWrite, io.EOF}, // error on writing length
|
||||
{0xfd, []byte{0xfd}, 2, io.ErrShortWrite, io.ErrUnexpectedEOF}, // error on writing actual data
|
||||
// Force errors on 4-byte read/write.
|
||||
{0x10000, []byte{0xfe}, pver, 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}, 0, io.ErrShortWrite, io.EOF}, // error on writing length
|
||||
{0x10000, []byte{0xfe}, 2, io.ErrShortWrite, io.ErrUnexpectedEOF}, // error on writing actual data
|
||||
// Force errors on 8-byte read/write.
|
||||
{0x100000000, []byte{0xff}, pver, 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}, 0, io.ErrShortWrite, io.EOF}, // error on writing length
|
||||
{0x100000000, []byte{0xff}, 2, io.ErrShortWrite, io.ErrUnexpectedEOF}, // error on writing actual data
|
||||
}
|
||||
|
||||
t.Logf("Running %d tests", len(tests))
|
||||
for i, test := range tests {
|
||||
// Encode to wire format.
|
||||
w := newFixedWriter(test.max)
|
||||
err := WriteVarInt(w, test.pver, test.in)
|
||||
err := WriteVarInt(w, test.in)
|
||||
if err != test.writeErr {
|
||||
t.Errorf("WriteVarInt #%d wrong error got: %v, want: %v",
|
||||
i, err, test.writeErr)
|
||||
@ -346,7 +338,7 @@ func TestVarIntWireErrors(t *testing.T) {
|
||||
|
||||
// Decode from wire format.
|
||||
r := newFixedReader(test.max, test.buf)
|
||||
_, err = ReadVarInt(r, test.pver)
|
||||
_, err = ReadVarInt(r)
|
||||
if err != test.readErr {
|
||||
t.Errorf("ReadVarInt #%d wrong error got: %v, want: %v",
|
||||
i, err, test.readErr)
|
||||
@ -397,7 +389,7 @@ func TestVarIntNonCanonical(t *testing.T) {
|
||||
for i, test := range tests {
|
||||
// Decode from wire format.
|
||||
rbuf := bytes.NewReader(test.in)
|
||||
val, err := ReadVarInt(rbuf, test.pver)
|
||||
val, err := ReadVarInt(rbuf)
|
||||
if _, ok := err.(*MessageError); !ok {
|
||||
t.Errorf("ReadVarInt #%d (%s) unexpected error %v", i,
|
||||
test.name, err)
|
||||
@ -472,7 +464,7 @@ func TestVarStringWire(t *testing.T) {
|
||||
for i, test := range tests {
|
||||
// Encode to wire format.
|
||||
var buf bytes.Buffer
|
||||
err := WriteVarString(&buf, test.pver, test.in)
|
||||
err := WriteVarString(&buf, test.in)
|
||||
if err != nil {
|
||||
t.Errorf("WriteVarString #%d error %v", i, err)
|
||||
continue
|
||||
@ -527,7 +519,7 @@ func TestVarStringWireErrors(t *testing.T) {
|
||||
for i, test := range tests {
|
||||
// Encode to wire format.
|
||||
w := newFixedWriter(test.max)
|
||||
err := WriteVarString(w, test.pver, test.in)
|
||||
err := WriteVarString(w, test.in)
|
||||
if err != test.writeErr {
|
||||
t.Errorf("WriteVarString #%d wrong error got: %v, want: %v",
|
||||
i, err, test.writeErr)
|
||||
|
@ -64,20 +64,20 @@ func (msg *MsgAddr) ClearAddresses() {
|
||||
func (msg *MsgAddr) BtcDecode(r io.Reader, pver uint32) error {
|
||||
msg.SubnetworkID = nil
|
||||
|
||||
err := readElement(r, &msg.IncludeAllSubnetworks)
|
||||
err := ReadElement(r, &msg.IncludeAllSubnetworks)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !msg.IncludeAllSubnetworks {
|
||||
var isFullNode bool
|
||||
err := readElement(r, &isFullNode)
|
||||
err := ReadElement(r, &isFullNode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !isFullNode {
|
||||
var subnetworkID subnetworkid.SubnetworkID
|
||||
err = readElement(r, &subnetworkID)
|
||||
err = ReadElement(r, &subnetworkID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -86,7 +86,7 @@ func (msg *MsgAddr) BtcDecode(r io.Reader, pver uint32) error {
|
||||
}
|
||||
|
||||
// Read addresses array
|
||||
count, err := ReadVarInt(r, pver)
|
||||
count, err := ReadVarInt(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -121,7 +121,7 @@ func (msg *MsgAddr) BtcEncode(w io.Writer, pver uint32) error {
|
||||
return messageError("MsgAddr.BtcEncode", str)
|
||||
}
|
||||
|
||||
err := writeElement(w, msg.IncludeAllSubnetworks)
|
||||
err := WriteElement(w, msg.IncludeAllSubnetworks)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -129,19 +129,19 @@ func (msg *MsgAddr) BtcEncode(w io.Writer, pver uint32) error {
|
||||
if !msg.IncludeAllSubnetworks {
|
||||
// Write subnetwork ID
|
||||
isFullNode := msg.SubnetworkID == nil
|
||||
err = writeElement(w, isFullNode)
|
||||
err = WriteElement(w, isFullNode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !isFullNode {
|
||||
err = writeElement(w, msg.SubnetworkID)
|
||||
err = WriteElement(w, msg.SubnetworkID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err = WriteVarInt(w, pver, uint64(count))
|
||||
err = WriteVarInt(w, uint64(count))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -161,12 +161,12 @@ func (alert *Alert) Serialize(w io.Writer, pver uint32) error {
|
||||
"[count %d, max %d]", count, maxCountSetCancel)
|
||||
return messageError("Alert.Serialize", str)
|
||||
}
|
||||
err = WriteVarInt(w, pver, uint64(count))
|
||||
err = WriteVarInt(w, uint64(count))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for i := 0; i < count; i++ {
|
||||
err = writeElement(w, alert.SetCancel[i])
|
||||
err = WriteElement(w, alert.SetCancel[i])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -183,30 +183,30 @@ func (alert *Alert) Serialize(w io.Writer, pver uint32) error {
|
||||
"[count %d, max %d]", count, maxCountSetSubVer)
|
||||
return messageError("Alert.Serialize", str)
|
||||
}
|
||||
err = WriteVarInt(w, pver, uint64(count))
|
||||
err = WriteVarInt(w, uint64(count))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for i := 0; i < count; i++ {
|
||||
err = WriteVarString(w, pver, alert.SetSubVer[i])
|
||||
err = WriteVarString(w, alert.SetSubVer[i])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
err = writeElement(w, alert.Priority)
|
||||
err = WriteElement(w, alert.Priority)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = WriteVarString(w, pver, alert.Comment)
|
||||
err = WriteVarString(w, alert.Comment)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = WriteVarString(w, pver, alert.StatusBar)
|
||||
err = WriteVarString(w, alert.StatusBar)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return WriteVarString(w, pver, alert.Reserved)
|
||||
return WriteVarString(w, alert.Reserved)
|
||||
}
|
||||
|
||||
// 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
|
||||
// count - the number of Cancel IDs, then
|
||||
// iterate count times and read them
|
||||
count, err := ReadVarInt(r, pver)
|
||||
count, err := ReadVarInt(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -232,7 +232,7 @@ func (alert *Alert) Deserialize(r io.Reader, pver uint32) error {
|
||||
}
|
||||
alert.SetCancel = make([]int32, count)
|
||||
for i := 0; i < int(count); i++ {
|
||||
err := readElement(r, &alert.SetCancel[i])
|
||||
err := ReadElement(r, &alert.SetCancel[i])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -245,7 +245,7 @@ func (alert *Alert) Deserialize(r io.Reader, pver uint32) error {
|
||||
|
||||
// SetSubVer: similar to SetCancel
|
||||
// but read count number of sub-version strings
|
||||
count, err = ReadVarInt(r, pver)
|
||||
count, err = ReadVarInt(r)
|
||||
if err != nil {
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ func (msg *MsgBlock) BtcDecode(r io.Reader, pver uint32) error {
|
||||
return err
|
||||
}
|
||||
|
||||
txCount, err := ReadVarInt(r, pver)
|
||||
txCount, err := ReadVarInt(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -124,7 +124,7 @@ func (msg *MsgBlock) DeserializeTxLoc(r *bytes.Buffer) ([]TxLoc, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
txCount, err := ReadVarInt(r, 0)
|
||||
txCount, err := ReadVarInt(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -166,7 +166,7 @@ func (msg *MsgBlock) BtcEncode(w io.Writer, pver uint32) error {
|
||||
return err
|
||||
}
|
||||
|
||||
err = WriteVarInt(w, pver, uint64(len(msg.Transactions)))
|
||||
err = WriteVarInt(w, uint64(len(msg.Transactions)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -43,20 +43,20 @@ func (msg *MsgCFCheckpt) AddCFHeader(header *daghash.Hash) error {
|
||||
// This is part of the Message interface implementation.
|
||||
func (msg *MsgCFCheckpt) BtcDecode(r io.Reader, pver uint32) error {
|
||||
// Read filter type
|
||||
err := readElement(r, &msg.FilterType)
|
||||
err := ReadElement(r, &msg.FilterType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Read stop hash
|
||||
msg.StopHash = &daghash.Hash{}
|
||||
err = readElement(r, msg.StopHash)
|
||||
err = ReadElement(r, msg.StopHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Read number of filter headers
|
||||
count, err := ReadVarInt(r, pver)
|
||||
count, err := ReadVarInt(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -66,7 +66,7 @@ func (msg *MsgCFCheckpt) BtcDecode(r io.Reader, pver uint32) error {
|
||||
msg.FilterHeaders = make([]*daghash.Hash, count)
|
||||
for i := uint64(0); i < count; i++ {
|
||||
var cfh daghash.Hash
|
||||
err := readElement(r, &cfh)
|
||||
err := ReadElement(r, &cfh)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -80,26 +80,26 @@ func (msg *MsgCFCheckpt) BtcDecode(r io.Reader, pver uint32) error {
|
||||
// This is part of the Message interface implementation.
|
||||
func (msg *MsgCFCheckpt) BtcEncode(w io.Writer, pver uint32) error {
|
||||
// Write filter type
|
||||
err := writeElement(w, msg.FilterType)
|
||||
err := WriteElement(w, msg.FilterType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Write stop hash
|
||||
err = writeElement(w, msg.StopHash)
|
||||
err = WriteElement(w, msg.StopHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Write length of FilterHeaders slice
|
||||
count := len(msg.FilterHeaders)
|
||||
err = WriteVarInt(w, pver, uint64(count))
|
||||
err = WriteVarInt(w, uint64(count))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, cfh := range msg.FilterHeaders {
|
||||
err := writeElement(w, cfh)
|
||||
err := WriteElement(w, cfh)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -49,27 +49,27 @@ func (msg *MsgCFHeaders) AddCFHash(hash *daghash.Hash) error {
|
||||
// This is part of the Message interface implementation.
|
||||
func (msg *MsgCFHeaders) BtcDecode(r io.Reader, pver uint32) error {
|
||||
// Read filter type
|
||||
err := readElement(r, &msg.FilterType)
|
||||
err := ReadElement(r, &msg.FilterType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Read stop hash
|
||||
msg.StopHash = &daghash.Hash{}
|
||||
err = readElement(r, msg.StopHash)
|
||||
err = ReadElement(r, msg.StopHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Read prev filter header
|
||||
msg.PrevFilterHeader = &daghash.Hash{}
|
||||
err = readElement(r, msg.PrevFilterHeader)
|
||||
err = ReadElement(r, msg.PrevFilterHeader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Read number of filter headers
|
||||
count, err := ReadVarInt(r, pver)
|
||||
count, err := ReadVarInt(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -87,7 +87,7 @@ func (msg *MsgCFHeaders) BtcDecode(r io.Reader, pver uint32) error {
|
||||
msg.FilterHashes = make([]*daghash.Hash, 0, count)
|
||||
for i := uint64(0); i < count; i++ {
|
||||
var cfh daghash.Hash
|
||||
err := readElement(r, &cfh)
|
||||
err := ReadElement(r, &cfh)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -101,19 +101,19 @@ func (msg *MsgCFHeaders) BtcDecode(r io.Reader, pver uint32) error {
|
||||
// This is part of the Message interface implementation.
|
||||
func (msg *MsgCFHeaders) BtcEncode(w io.Writer, pver uint32) error {
|
||||
// Write filter type
|
||||
err := writeElement(w, msg.FilterType)
|
||||
err := WriteElement(w, msg.FilterType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Write stop hash
|
||||
err = writeElement(w, msg.StopHash)
|
||||
err = WriteElement(w, msg.StopHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Write prev filter header
|
||||
err = writeElement(w, msg.PrevFilterHeader)
|
||||
err = WriteElement(w, msg.PrevFilterHeader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -127,13 +127,13 @@ func (msg *MsgCFHeaders) BtcEncode(w io.Writer, pver uint32) error {
|
||||
return messageError("MsgCFHeaders.BtcEncode", str)
|
||||
}
|
||||
|
||||
err = WriteVarInt(w, pver, uint64(count))
|
||||
err = WriteVarInt(w, uint64(count))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, cfh := range msg.FilterHashes {
|
||||
err := writeElement(w, cfh)
|
||||
err := WriteElement(w, cfh)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -41,13 +41,13 @@ type MsgCFilter struct {
|
||||
// This is part of the Message interface implementation.
|
||||
func (msg *MsgCFilter) BtcDecode(r io.Reader, pver uint32) error {
|
||||
// Read filter type
|
||||
err := readElement(r, &msg.FilterType)
|
||||
err := ReadElement(r, &msg.FilterType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Read the hash of the filter's block
|
||||
err = readElement(r, &msg.BlockHash)
|
||||
err = ReadElement(r, &msg.BlockHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -68,12 +68,12 @@ func (msg *MsgCFilter) BtcEncode(w io.Writer, pver uint32) error {
|
||||
return messageError("MsgCFilter.BtcEncode", str)
|
||||
}
|
||||
|
||||
err := writeElement(w, msg.FilterType)
|
||||
err := WriteElement(w, msg.FilterType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = writeElement(w, msg.BlockHash)
|
||||
err = WriteElement(w, msg.BlockHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -21,13 +21,13 @@ type MsgFeeFilter struct {
|
||||
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
|
||||
// This is part of the Message interface implementation.
|
||||
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.
|
||||
// This is part of the Message interface implementation.
|
||||
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
|
||||
|
@ -26,7 +26,7 @@ type MsgGetAddr struct {
|
||||
func (msg *MsgGetAddr) BtcDecode(r io.Reader, pver uint32) error {
|
||||
msg.SubnetworkID = nil
|
||||
|
||||
err := readElement(r, &msg.IncludeAllSubnetworks)
|
||||
err := ReadElement(r, &msg.IncludeAllSubnetworks)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -35,7 +35,7 @@ func (msg *MsgGetAddr) BtcDecode(r io.Reader, pver uint32) error {
|
||||
}
|
||||
|
||||
var isFullNode bool
|
||||
err = readElement(r, &isFullNode)
|
||||
err = ReadElement(r, &isFullNode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -44,7 +44,7 @@ func (msg *MsgGetAddr) BtcDecode(r io.Reader, pver uint32) error {
|
||||
}
|
||||
|
||||
var subnetworkID subnetworkid.SubnetworkID
|
||||
err = readElement(r, &subnetworkID)
|
||||
err = ReadElement(r, &subnetworkID)
|
||||
if err != nil {
|
||||
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.
|
||||
// This is part of the Message interface implementation.
|
||||
func (msg *MsgGetAddr) BtcEncode(w io.Writer, pver uint32) error {
|
||||
err := writeElement(w, msg.IncludeAllSubnetworks)
|
||||
err := WriteElement(w, msg.IncludeAllSubnetworks)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -66,13 +66,13 @@ func (msg *MsgGetAddr) BtcEncode(w io.Writer, pver uint32) error {
|
||||
}
|
||||
|
||||
isFullNode := msg.SubnetworkID == nil
|
||||
err = writeElement(w, isFullNode)
|
||||
err = WriteElement(w, isFullNode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !isFullNode {
|
||||
err = writeElement(w, msg.SubnetworkID)
|
||||
err = WriteElement(w, msg.SubnetworkID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -51,13 +51,13 @@ func (msg *MsgGetBlocks) AddBlockLocatorHash(hash *daghash.Hash) error {
|
||||
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
|
||||
// This is part of the Message interface implementation.
|
||||
func (msg *MsgGetBlocks) BtcDecode(r io.Reader, pver uint32) error {
|
||||
err := readElement(r, &msg.ProtocolVersion)
|
||||
err := ReadElement(r, &msg.ProtocolVersion)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Read num block locator hashes and limit to max.
|
||||
count, err := ReadVarInt(r, pver)
|
||||
count, err := ReadVarInt(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -73,7 +73,7 @@ func (msg *MsgGetBlocks) BtcDecode(r io.Reader, pver uint32) error {
|
||||
msg.BlockLocatorHashes = make([]*daghash.Hash, 0, count)
|
||||
for i := uint64(0); i < count; i++ {
|
||||
hash := &locatorHashes[i]
|
||||
err := readElement(r, hash)
|
||||
err := ReadElement(r, hash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -81,7 +81,7 @@ func (msg *MsgGetBlocks) BtcDecode(r io.Reader, pver uint32) error {
|
||||
}
|
||||
|
||||
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.
|
||||
@ -94,24 +94,24 @@ func (msg *MsgGetBlocks) BtcEncode(w io.Writer, pver uint32) error {
|
||||
return messageError("MsgGetBlocks.BtcEncode", str)
|
||||
}
|
||||
|
||||
err := writeElement(w, msg.ProtocolVersion)
|
||||
err := WriteElement(w, msg.ProtocolVersion)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = WriteVarInt(w, pver, uint64(count))
|
||||
err = WriteVarInt(w, uint64(count))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, hash := range msg.BlockLocatorHashes {
|
||||
err = writeElement(w, hash)
|
||||
err = WriteElement(w, hash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return writeElement(w, msg.HashStop)
|
||||
return WriteElement(w, msg.HashStop)
|
||||
}
|
||||
|
||||
// Command returns the protocol command string for the message. This is part
|
||||
|
@ -21,24 +21,24 @@ type MsgGetCFCheckpt struct {
|
||||
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
|
||||
// This is part of the Message interface implementation.
|
||||
func (msg *MsgGetCFCheckpt) BtcDecode(r io.Reader, pver uint32) error {
|
||||
err := readElement(r, &msg.FilterType)
|
||||
err := ReadElement(r, &msg.FilterType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
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.
|
||||
// This is part of the Message interface implementation.
|
||||
func (msg *MsgGetCFCheckpt) BtcEncode(w io.Writer, pver uint32) error {
|
||||
err := writeElement(w, msg.FilterType)
|
||||
err := WriteElement(w, msg.FilterType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return writeElement(w, msg.StopHash)
|
||||
return WriteElement(w, msg.StopHash)
|
||||
}
|
||||
|
||||
// Command returns the protocol command string for the message. This is part
|
||||
|
@ -22,34 +22,34 @@ type MsgGetCFHeaders struct {
|
||||
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
|
||||
// This is part of the Message interface implementation.
|
||||
func (msg *MsgGetCFHeaders) BtcDecode(r io.Reader, pver uint32) error {
|
||||
err := readElement(r, &msg.FilterType)
|
||||
err := ReadElement(r, &msg.FilterType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = readElement(r, &msg.StartHeight)
|
||||
err = ReadElement(r, &msg.StartHeight)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
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.
|
||||
// This is part of the Message interface implementation.
|
||||
func (msg *MsgGetCFHeaders) BtcEncode(w io.Writer, pver uint32) error {
|
||||
err := writeElement(w, msg.FilterType)
|
||||
err := WriteElement(w, msg.FilterType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = writeElement(w, &msg.StartHeight)
|
||||
err = WriteElement(w, &msg.StartHeight)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return writeElement(w, msg.StopHash)
|
||||
return WriteElement(w, msg.StopHash)
|
||||
}
|
||||
|
||||
// Command returns the protocol command string for the message. This is part
|
||||
|
@ -26,34 +26,34 @@ type MsgGetCFilters struct {
|
||||
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
|
||||
// This is part of the Message interface implementation.
|
||||
func (msg *MsgGetCFilters) BtcDecode(r io.Reader, pver uint32) error {
|
||||
err := readElement(r, &msg.FilterType)
|
||||
err := ReadElement(r, &msg.FilterType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = readElement(r, &msg.StartHeight)
|
||||
err = ReadElement(r, &msg.StartHeight)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
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.
|
||||
// This is part of the Message interface implementation.
|
||||
func (msg *MsgGetCFilters) BtcEncode(w io.Writer, pver uint32) error {
|
||||
err := writeElement(w, msg.FilterType)
|
||||
err := WriteElement(w, msg.FilterType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = writeElement(w, &msg.StartHeight)
|
||||
err = WriteElement(w, &msg.StartHeight)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return writeElement(w, msg.StopHash)
|
||||
return WriteElement(w, msg.StopHash)
|
||||
}
|
||||
|
||||
// Command returns the protocol command string for the message. This is part
|
||||
|
@ -38,7 +38,7 @@ func (msg *MsgGetData) AddInvVect(iv *InvVect) error {
|
||||
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
|
||||
// This is part of the Message interface implementation.
|
||||
func (msg *MsgGetData) BtcDecode(r io.Reader, pver uint32) error {
|
||||
count, err := ReadVarInt(r, pver)
|
||||
count, err := ReadVarInt(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -75,7 +75,7 @@ func (msg *MsgGetData) BtcEncode(w io.Writer, pver uint32) error {
|
||||
return messageError("MsgGetData.BtcEncode", str)
|
||||
}
|
||||
|
||||
err := WriteVarInt(w, pver, uint64(count))
|
||||
err := WriteVarInt(w, uint64(count))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -48,13 +48,13 @@ func (msg *MsgGetHeaders) AddBlockLocatorHash(hash *daghash.Hash) error {
|
||||
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
|
||||
// This is part of the Message interface implementation.
|
||||
func (msg *MsgGetHeaders) BtcDecode(r io.Reader, pver uint32) error {
|
||||
err := readElement(r, &msg.ProtocolVersion)
|
||||
err := ReadElement(r, &msg.ProtocolVersion)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Read num block locator hashes and limit to max.
|
||||
count, err := ReadVarInt(r, pver)
|
||||
count, err := ReadVarInt(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -70,7 +70,7 @@ func (msg *MsgGetHeaders) BtcDecode(r io.Reader, pver uint32) error {
|
||||
msg.BlockLocatorHashes = make([]*daghash.Hash, 0, count)
|
||||
for i := uint64(0); i < count; i++ {
|
||||
hash := &locatorHashes[i]
|
||||
err := readElement(r, hash)
|
||||
err := ReadElement(r, hash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -78,7 +78,7 @@ func (msg *MsgGetHeaders) BtcDecode(r io.Reader, pver uint32) error {
|
||||
}
|
||||
|
||||
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.
|
||||
@ -92,24 +92,24 @@ func (msg *MsgGetHeaders) BtcEncode(w io.Writer, pver uint32) error {
|
||||
return messageError("MsgGetHeaders.BtcEncode", str)
|
||||
}
|
||||
|
||||
err := writeElement(w, msg.ProtocolVersion)
|
||||
err := WriteElement(w, msg.ProtocolVersion)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = WriteVarInt(w, pver, uint64(count))
|
||||
err = WriteVarInt(w, uint64(count))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, hash := range msg.BlockLocatorHashes {
|
||||
err := writeElement(w, hash)
|
||||
err := WriteElement(w, hash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return writeElement(w, msg.HashStop)
|
||||
return WriteElement(w, msg.HashStop)
|
||||
}
|
||||
|
||||
// Command returns the protocol command string for the message. This is part
|
||||
|
@ -37,7 +37,7 @@ func (msg *MsgHeaders) AddBlockHeader(bh *BlockHeader) error {
|
||||
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
|
||||
// This is part of the Message interface implementation.
|
||||
func (msg *MsgHeaders) BtcDecode(r io.Reader, pver uint32) error {
|
||||
count, err := ReadVarInt(r, pver)
|
||||
count, err := ReadVarInt(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -60,7 +60,7 @@ func (msg *MsgHeaders) BtcDecode(r io.Reader, pver uint32) error {
|
||||
return err
|
||||
}
|
||||
|
||||
txCount, err := ReadVarInt(r, pver)
|
||||
txCount, err := ReadVarInt(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -88,7 +88,7 @@ func (msg *MsgHeaders) BtcEncode(w io.Writer, pver uint32) error {
|
||||
return messageError("MsgHeaders.BtcEncode", str)
|
||||
}
|
||||
|
||||
err := WriteVarInt(w, pver, uint64(count))
|
||||
err := WriteVarInt(w, uint64(count))
|
||||
if err != nil {
|
||||
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
|
||||
// artifact of the way the original implementation serializes
|
||||
// block headers, but it is required.
|
||||
err = WriteVarInt(w, pver, 0)
|
||||
err = WriteVarInt(w, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ func (msg *MsgInv) AddInvVect(iv *InvVect) error {
|
||||
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
|
||||
// This is part of the Message interface implementation.
|
||||
func (msg *MsgInv) BtcDecode(r io.Reader, pver uint32) error {
|
||||
count, err := ReadVarInt(r, pver)
|
||||
count, err := ReadVarInt(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -83,7 +83,7 @@ func (msg *MsgInv) BtcEncode(w io.Writer, pver uint32) error {
|
||||
return messageError("MsgInv.BtcEncode", str)
|
||||
}
|
||||
|
||||
err := WriteVarInt(w, pver, uint64(count))
|
||||
err := WriteVarInt(w, uint64(count))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -48,13 +48,13 @@ func (msg *MsgMerkleBlock) BtcDecode(r io.Reader, pver uint32) error {
|
||||
return err
|
||||
}
|
||||
|
||||
err = readElement(r, &msg.Transactions)
|
||||
err = ReadElement(r, &msg.Transactions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Read num block locator hashes and limit to max.
|
||||
count, err := ReadVarInt(r, pver)
|
||||
count, err := ReadVarInt(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -70,7 +70,7 @@ func (msg *MsgMerkleBlock) BtcDecode(r io.Reader, pver uint32) error {
|
||||
msg.Hashes = make([]*daghash.Hash, 0, count)
|
||||
for i := uint64(0); i < count; i++ {
|
||||
hash := &daghash.Hash{}
|
||||
err := readElement(r, hash)
|
||||
err := ReadElement(r, hash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -105,17 +105,17 @@ func (msg *MsgMerkleBlock) BtcEncode(w io.Writer, pver uint32) error {
|
||||
return err
|
||||
}
|
||||
|
||||
err = writeElement(w, msg.Transactions)
|
||||
err = WriteElement(w, msg.Transactions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = WriteVarInt(w, pver, uint64(numHashes))
|
||||
err = WriteVarInt(w, uint64(numHashes))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, hash := range msg.Hashes {
|
||||
err = writeElement(w, hash)
|
||||
err = WriteElement(w, hash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -274,7 +274,7 @@ func TestMerkleBlockOverflowErrors(t *testing.T) {
|
||||
// Create bytes for a merkle block that claims to have more than the max
|
||||
// allowed tx hashes.
|
||||
var buf bytes.Buffer
|
||||
WriteVarInt(&buf, pver, maxTxPerBlock+1)
|
||||
WriteVarInt(&buf, maxTxPerBlock+1)
|
||||
numHashesOffset := 157
|
||||
exceedMaxHashes := make([]byte, 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
|
||||
// allowed flag bytes.
|
||||
buf.Reset()
|
||||
WriteVarInt(&buf, pver, maxFlagsPerMerkleBlock+1)
|
||||
WriteVarInt(&buf, maxFlagsPerMerkleBlock+1)
|
||||
numFlagBytesOffset := 190
|
||||
exceedMaxFlagBytes := make([]byte, numFlagBytesOffset)
|
||||
copy(exceedMaxFlagBytes, merkleBlockOneBytes[:numFlagBytesOffset])
|
||||
|
@ -35,7 +35,7 @@ func (msg *MsgNotFound) AddInvVect(iv *InvVect) error {
|
||||
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
|
||||
// This is part of the Message interface implementation.
|
||||
func (msg *MsgNotFound) BtcDecode(r io.Reader, pver uint32) error {
|
||||
count, err := ReadVarInt(r, pver)
|
||||
count, err := ReadVarInt(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -72,7 +72,7 @@ func (msg *MsgNotFound) BtcEncode(w io.Writer, pver uint32) error {
|
||||
return messageError("MsgNotFound.BtcEncode", str)
|
||||
}
|
||||
|
||||
err := WriteVarInt(w, pver, uint64(count))
|
||||
err := WriteVarInt(w, uint64(count))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ type MsgPing struct {
|
||||
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
|
||||
// This is part of the Message interface implementation.
|
||||
func (msg *MsgPing) BtcDecode(r io.Reader, pver uint32) error {
|
||||
err := readElement(r, &msg.Nonce)
|
||||
err := ReadElement(r, &msg.Nonce)
|
||||
if err != nil {
|
||||
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.
|
||||
// This is part of the Message interface implementation.
|
||||
func (msg *MsgPing) BtcEncode(w io.Writer, pver uint32) error {
|
||||
err := writeElement(w, msg.Nonce)
|
||||
err := WriteElement(w, msg.Nonce)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -22,13 +22,13 @@ type MsgPong struct {
|
||||
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
|
||||
// This is part of the Message interface implementation.
|
||||
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.
|
||||
// This is part of the Message interface implementation.
|
||||
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
|
||||
|
@ -82,7 +82,7 @@ func (msg *MsgReject) BtcDecode(r io.Reader, pver uint32) error {
|
||||
msg.Cmd = cmd
|
||||
|
||||
// Code indicating why the command was rejected.
|
||||
err = readElement(r, &msg.Code)
|
||||
err = ReadElement(r, &msg.Code)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -99,7 +99,7 @@ func (msg *MsgReject) BtcDecode(r io.Reader, pver uint32) error {
|
||||
// identifies the specific block or transaction.
|
||||
if msg.Cmd == CmdBlock || msg.Cmd == CmdTx {
|
||||
msg.Hash = &daghash.Hash{}
|
||||
err := readElement(r, msg.Hash)
|
||||
err := ReadElement(r, msg.Hash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -112,20 +112,20 @@ func (msg *MsgReject) BtcDecode(r io.Reader, pver uint32) error {
|
||||
// This is part of the Message interface implementation.
|
||||
func (msg *MsgReject) BtcEncode(w io.Writer, pver uint32) error {
|
||||
// Command that was rejected.
|
||||
err := WriteVarString(w, pver, msg.Cmd)
|
||||
err := WriteVarString(w, msg.Cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Code indicating why the command was rejected.
|
||||
err = writeElement(w, msg.Code)
|
||||
err = WriteElement(w, msg.Code)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Human readable string with specific details (over and above the
|
||||
// reject code above) about why the command was rejected.
|
||||
err = WriteVarString(w, pver, msg.Reason)
|
||||
err = WriteVarString(w, msg.Reason)
|
||||
if err != nil {
|
||||
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
|
||||
// identifies the specific block or transaction.
|
||||
if msg.Cmd == CmdBlock || msg.Cmd == CmdTx {
|
||||
err := writeElement(w, msg.Hash)
|
||||
err := WriteElement(w, msg.Hash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -436,7 +436,7 @@ func (msg *MsgTx) BtcDecode(r io.Reader, pver uint32) error {
|
||||
}
|
||||
msg.Version = int32(version)
|
||||
|
||||
count, err := ReadVarInt(r, pver)
|
||||
count, err := ReadVarInt(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -488,7 +488,7 @@ func (msg *MsgTx) BtcDecode(r io.Reader, pver uint32) error {
|
||||
totalScriptSize += uint64(len(ti.SignatureScript))
|
||||
}
|
||||
|
||||
count, err = ReadVarInt(r, pver)
|
||||
count, err = ReadVarInt(r)
|
||||
if err != nil {
|
||||
returnScriptBuffers()
|
||||
return err
|
||||
@ -542,14 +542,14 @@ func (msg *MsgTx) BtcDecode(r io.Reader, pver uint32) error {
|
||||
}
|
||||
|
||||
var payloadHash daghash.Hash
|
||||
err = readElement(r, &payloadHash)
|
||||
err = ReadElement(r, &payloadHash)
|
||||
if err != nil {
|
||||
returnScriptBuffers()
|
||||
return err
|
||||
}
|
||||
msg.PayloadHash = &payloadHash
|
||||
|
||||
payloadLength, err := ReadVarInt(r, pver)
|
||||
payloadLength, err := ReadVarInt(r)
|
||||
if err != nil {
|
||||
returnScriptBuffers()
|
||||
return err
|
||||
@ -643,7 +643,7 @@ func (msg *MsgTx) encode(w io.Writer, pver uint32, encodingFlags txEncoding) err
|
||||
}
|
||||
|
||||
count := uint64(len(msg.TxIn))
|
||||
err = WriteVarInt(w, pver, count)
|
||||
err = WriteVarInt(w, count)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -656,7 +656,7 @@ func (msg *MsgTx) encode(w io.Writer, pver uint32, encodingFlags txEncoding) err
|
||||
}
|
||||
|
||||
count = uint64(len(msg.TxOut))
|
||||
err = WriteVarInt(w, pver, count)
|
||||
err = WriteVarInt(w, count)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -689,16 +689,16 @@ func (msg *MsgTx) encode(w io.Writer, pver uint32, encodingFlags txEncoding) err
|
||||
return err
|
||||
}
|
||||
|
||||
err = writeElement(w, msg.PayloadHash)
|
||||
err = WriteElement(w, msg.PayloadHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if encodingFlags&txEncodingExcludePayload != txEncodingExcludePayload {
|
||||
err = WriteVarInt(w, pver, uint64(len(msg.Payload)))
|
||||
err = WriteVarInt(w, uint64(len(msg.Payload)))
|
||||
w.Write(msg.Payload)
|
||||
} else {
|
||||
err = WriteVarInt(w, pver, 0)
|
||||
err = WriteVarInt(w, 0)
|
||||
}
|
||||
if err != nil {
|
||||
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
|
||||
// context in the 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 {
|
||||
return nil, err
|
||||
}
|
||||
@ -974,7 +974,7 @@ func readTxIn(r io.Reader, pver uint32, version int32, ti *TxIn) error {
|
||||
return err
|
||||
}
|
||||
|
||||
return readElement(r, &ti.Sequence)
|
||||
return ReadElement(r, &ti.Sequence)
|
||||
}
|
||||
|
||||
// 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
|
||||
// (TxOut).
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ func (msg *MsgVersion) BtcDecode(r io.Reader, pver uint32) error {
|
||||
|
||||
// Read subnetwork ID
|
||||
var isFullNode bool
|
||||
err = readElement(r, &isFullNode)
|
||||
err = ReadElement(r, &isFullNode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -105,7 +105,7 @@ func (msg *MsgVersion) BtcDecode(r io.Reader, pver uint32) error {
|
||||
msg.SubnetworkID = nil
|
||||
} else {
|
||||
var subnetworkID subnetworkid.SubnetworkID
|
||||
err = readElement(r, &subnetworkID)
|
||||
err = ReadElement(r, &subnetworkID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -121,7 +121,7 @@ func (msg *MsgVersion) BtcDecode(r io.Reader, pver uint32) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = readElement(buf, &msg.Nonce)
|
||||
err = ReadElement(buf, &msg.Nonce)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -136,13 +136,13 @@ func (msg *MsgVersion) BtcDecode(r io.Reader, pver uint32) error {
|
||||
msg.UserAgent = userAgent
|
||||
|
||||
msg.SelectedTip = &daghash.Hash{}
|
||||
err = readElement(buf, msg.SelectedTip)
|
||||
err = ReadElement(buf, msg.SelectedTip)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var relayTx bool
|
||||
err = readElement(r, &relayTx)
|
||||
err = ReadElement(r, &relayTx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -167,12 +167,12 @@ func (msg *MsgVersion) BtcEncode(w io.Writer, pver uint32) error {
|
||||
|
||||
// Write subnetwork ID
|
||||
isFullNode := msg.SubnetworkID == nil
|
||||
err = writeElement(w, isFullNode)
|
||||
err = WriteElement(w, isFullNode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !isFullNode {
|
||||
err = writeElement(w, msg.SubnetworkID)
|
||||
err = WriteElement(w, msg.SubnetworkID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -188,24 +188,24 @@ func (msg *MsgVersion) BtcEncode(w io.Writer, pver uint32) error {
|
||||
return err
|
||||
}
|
||||
|
||||
err = writeElement(w, msg.Nonce)
|
||||
err = WriteElement(w, msg.Nonce)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = WriteVarString(w, pver, msg.UserAgent)
|
||||
err = WriteVarString(w, msg.UserAgent)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = writeElement(w, msg.SelectedTip)
|
||||
err = WriteElement(w, msg.SelectedTip)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// The wire encoding for the field is true when transactions should be
|
||||
// relayed, so reverse it from the DisableRelayTx field.
|
||||
err = writeElement(w, !msg.DisableRelayTx)
|
||||
err = WriteElement(w, !msg.DisableRelayTx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -213,7 +213,7 @@ func TestVersionWireErrors(t *testing.T) {
|
||||
|
||||
// Encode the new UA length as a varint.
|
||||
var newUAVarIntBuf bytes.Buffer
|
||||
err := WriteVarInt(&newUAVarIntBuf, pver, uint64(len(newUA)))
|
||||
err := WriteVarInt(&newUAVarIntBuf, uint64(len(newUA)))
|
||||
if err != nil {
|
||||
t.Errorf("WriteVarInt: error %v", err)
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ func readNetAddress(r io.Reader, pver uint32, na *NetAddress, ts bool) error {
|
||||
var ip [16]byte
|
||||
|
||||
if ts {
|
||||
err := readElement(r, (*int64Time)(&na.Timestamp))
|
||||
err := ReadElement(r, (*int64Time)(&na.Timestamp))
|
||||
if err != nil {
|
||||
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.
|
||||
func writeNetAddress(w io.Writer, pver uint32, na *NetAddress, ts bool) error {
|
||||
if ts {
|
||||
err := writeElement(w, int64(na.Timestamp.Unix()))
|
||||
err := WriteElement(w, int64(na.Timestamp.Unix()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user