mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-06-08 07:06:43 +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
|
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.
|
||||||
|
@ -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() {
|
||||||
|
@ -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
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.
|
// 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)
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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])
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user