Factor out filters to btcutil.

This commit is contained in:
Alex 2017-04-26 19:00:41 -06:00 committed by Olaoluwa Osuntokun
parent fe632ff233
commit 189b65ddaf
4 changed files with 14 additions and 91 deletions

View file

@ -464,20 +464,21 @@ func createSPVNS(namespace walletdb.Namespace, params *chaincfg.Params) error {
log.Info("Creating wallet SPV namespace.") log.Info("Creating wallet SPV namespace.")
basicFilter, err := BuildBasicFilter(params.GenesisBlock) basicFilter, err := builder.BuildBasicFilter(
params.GenesisBlock)
if err != nil { if err != nil {
return err return err
} }
basicFilterTip := MakeHeaderForFilter(basicFilter, basicFilterTip := builder.MakeHeaderForFilter(basicFilter,
params.GenesisBlock.Header.PrevBlock) params.GenesisBlock.Header.PrevBlock)
extFilter, err := BuildExtFilter(params.GenesisBlock) extFilter, err := builder.BuildExtFilter(params.GenesisBlock)
if err != nil { if err != nil {
return err return err
} }
extFilterTip := MakeHeaderForFilter(extFilter, extFilterTip := builder.MakeHeaderForFilter(extFilter,
params.GenesisBlock.Header.PrevBlock) params.GenesisBlock.Header.PrevBlock)
err = putBlock(tx, params.GenesisBlock.Header, 0) err = putBlock(tx, params.GenesisBlock.Header, 0)

View file

@ -1,79 +0,0 @@
package spvchain
import (
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil/gcs"
"github.com/btcsuite/btcutil/gcs/builder"
)
// TODO: Move these functions into github.com/btcsuite/btcutil/gcs/builder.
// BuildBasicFilter will be factored out into gcs.builder
func BuildBasicFilter(block *wire.MsgBlock) (*gcs.Filter, error) {
blockHash := block.BlockHash()
b := builder.WithKeyHash(&blockHash)
_, err := b.Key()
if err != nil {
str := "failed to create filter builder: %v"
return nil, log.Errorf(str, err)
}
for i, tx := range block.Transactions {
// Skip the inputs for the coinbase transaction
if i != 0 {
for _, txIn := range tx.TxIn {
b.AddOutPoint(txIn.PreviousOutPoint)
}
}
for _, txOut := range tx.TxOut {
b.AddScript(txOut.PkScript)
}
}
f, err := b.Build()
if err != nil {
str := "failed to build filter: %v"
return nil, log.Errorf(str, err)
}
return f, nil
}
// BuildExtFilter will be factored out into gcs.builder
func BuildExtFilter(block *wire.MsgBlock) (*gcs.Filter, error) {
blockHash := block.BlockHash()
b := builder.WithKeyHash(&blockHash)
_, err := b.Key()
if err != nil {
str := "failed to create filter builder: %v"
return nil, log.Errorf(str, err)
}
for i, tx := range block.Transactions {
txHash := tx.TxHash()
b.AddHash(&txHash)
// Skip the inputs for the coinbase transaction
if i != 0 {
for _, txIn := range tx.TxIn {
b.AddScript(txIn.SignatureScript)
}
}
}
f, err := b.Build()
if err != nil {
str := "failed to build filter: %v"
return nil, log.Errorf(str, err)
}
return f, nil
}
// GetFilterHash will be factored out into gcs.builder
func GetFilterHash(filter *gcs.Filter) chainhash.Hash {
return chainhash.HashH(filter.NBytes())
}
// MakeHeaderForFilter will be factored out into gcs.builder
func MakeHeaderForFilter(filter *gcs.Filter, prevHeader chainhash.Hash) chainhash.Hash {
filterTip := make([]byte, 2*chainhash.HashSize)
filterHash := GetFilterHash(filter)
copy(filterTip, filterHash[:])
copy(filterTip[chainhash.HashSize:], prevHeader[:])
return chainhash.HashH(filterTip)
}

View file

@ -488,9 +488,9 @@ func (sp *serverPeer) OnAddr(_ *peer.Peer, msg *wire.MsgAddr) {
func (sp *serverPeer) OnRead(_ *peer.Peer, bytesRead int, msg wire.Message, func (sp *serverPeer) OnRead(_ *peer.Peer, bytesRead int, msg wire.Message,
err error) { err error) {
sp.server.AddBytesReceived(uint64(bytesRead)) sp.server.AddBytesReceived(uint64(bytesRead))
// Try to send a message to the subscriber channel if it isn't nil, but // Send a message to each subscriber. Each message gets its own
// don't block on failure. Do this inside a goroutine to prevent the // goroutine to prevent blocking on the mutex lock.
// server from slowing down too fast. // TODO: Flood control.
sp.mtxSubscribers.RLock() sp.mtxSubscribers.RLock()
defer sp.mtxSubscribers.RUnlock() defer sp.mtxSubscribers.RUnlock()
for subscription := range sp.recvSubscribers { for subscription := range sp.recvSubscribers {
@ -1835,7 +1835,7 @@ func (s *ChainService) GetCFilter(blockHash chainhash.Hash,
// can ignore this message. // can ignore this message.
return return
} }
if MakeHeaderForFilter(gotFilter, if builder.MakeHeaderForFilter(gotFilter,
*prevHeader) != *prevHeader) !=
*curHeader { *curHeader {
// Filter data doesn't match // Filter data doesn't match

View file

@ -17,6 +17,7 @@ import (
"github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btclog" "github.com/btcsuite/btclog"
"github.com/btcsuite/btcrpcclient" "github.com/btcsuite/btcrpcclient"
"github.com/btcsuite/btcutil/gcs/builder"
"github.com/btcsuite/btcwallet/spvsvc/spvchain" "github.com/btcsuite/btcwallet/spvsvc/spvchain"
"github.com/btcsuite/btcwallet/waddrmgr" "github.com/btcsuite/btcwallet/waddrmgr"
"github.com/btcsuite/btcwallet/walletdb" "github.com/btcsuite/btcwallet/walletdb"
@ -486,7 +487,7 @@ func testRandomBlocks(t *testing.T, svc *spvchain.ChainService,
return return
} }
// Calculate basic filter from block. // Calculate basic filter from block.
calcFilter, err := spvchain.BuildBasicFilter( calcFilter, err := builder.BuildBasicFilter(
haveBlock.MsgBlock()) haveBlock.MsgBlock())
if err != nil { if err != nil {
errChan <- fmt.Errorf("Couldn't build basic "+ errChan <- fmt.Errorf("Couldn't build basic "+
@ -521,7 +522,7 @@ func testRandomBlocks(t *testing.T, svc *spvchain.ChainService,
return return
} }
// Check that the filter and header line up. // Check that the filter and header line up.
calcHeader := spvchain.MakeHeaderForFilter(calcFilter, calcHeader := builder.MakeHeaderForFilter(calcFilter,
*prevHeader) *prevHeader)
if !bytes.Equal(curHeader[:], calcHeader[:]) { if !bytes.Equal(curHeader[:], calcHeader[:]) {
errChan <- fmt.Errorf("Filter header doesn't "+ errChan <- fmt.Errorf("Filter header doesn't "+
@ -554,7 +555,7 @@ func testRandomBlocks(t *testing.T, svc *spvchain.ChainService,
return return
} }
// Calculate extended filter from block // Calculate extended filter from block
calcFilter, err = spvchain.BuildExtFilter( calcFilter, err = builder.BuildExtFilter(
haveBlock.MsgBlock()) haveBlock.MsgBlock())
if err != nil { if err != nil {
errChan <- fmt.Errorf("Couldn't build extended"+ errChan <- fmt.Errorf("Couldn't build extended"+
@ -591,7 +592,7 @@ func testRandomBlocks(t *testing.T, svc *spvchain.ChainService,
return return
} }
// Check that the filter and header line up. // Check that the filter and header line up.
calcHeader = spvchain.MakeHeaderForFilter(calcFilter, calcHeader = builder.MakeHeaderForFilter(calcFilter,
*prevHeader) *prevHeader)
if !bytes.Equal(curHeader[:], calcHeader[:]) { if !bytes.Equal(curHeader[:], calcHeader[:]) {
errChan <- fmt.Errorf("Filter header doesn't "+ errChan <- fmt.Errorf("Filter header doesn't "+