From 189b65ddaf15353152ced7c658b03f79e46513e3 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 26 Apr 2017 19:00:41 -0600 Subject: [PATCH] Factor out filters to btcutil. --- spvsvc/spvchain/db.go | 9 ++-- spvsvc/spvchain/filter.go | 79 ------------------------------------ spvsvc/spvchain/spvchain.go | 8 ++-- spvsvc/spvchain/sync_test.go | 9 ++-- 4 files changed, 14 insertions(+), 91 deletions(-) delete mode 100644 spvsvc/spvchain/filter.go diff --git a/spvsvc/spvchain/db.go b/spvsvc/spvchain/db.go index 9e67806..c36aef3 100644 --- a/spvsvc/spvchain/db.go +++ b/spvsvc/spvchain/db.go @@ -464,20 +464,21 @@ func createSPVNS(namespace walletdb.Namespace, params *chaincfg.Params) error { log.Info("Creating wallet SPV namespace.") - basicFilter, err := BuildBasicFilter(params.GenesisBlock) + basicFilter, err := builder.BuildBasicFilter( + params.GenesisBlock) if err != nil { return err } - basicFilterTip := MakeHeaderForFilter(basicFilter, + basicFilterTip := builder.MakeHeaderForFilter(basicFilter, params.GenesisBlock.Header.PrevBlock) - extFilter, err := BuildExtFilter(params.GenesisBlock) + extFilter, err := builder.BuildExtFilter(params.GenesisBlock) if err != nil { return err } - extFilterTip := MakeHeaderForFilter(extFilter, + extFilterTip := builder.MakeHeaderForFilter(extFilter, params.GenesisBlock.Header.PrevBlock) err = putBlock(tx, params.GenesisBlock.Header, 0) diff --git a/spvsvc/spvchain/filter.go b/spvsvc/spvchain/filter.go deleted file mode 100644 index 7499bd8..0000000 --- a/spvsvc/spvchain/filter.go +++ /dev/null @@ -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) -} diff --git a/spvsvc/spvchain/spvchain.go b/spvsvc/spvchain/spvchain.go index 95337e3..29fe348 100644 --- a/spvsvc/spvchain/spvchain.go +++ b/spvsvc/spvchain/spvchain.go @@ -488,9 +488,9 @@ func (sp *serverPeer) OnAddr(_ *peer.Peer, msg *wire.MsgAddr) { func (sp *serverPeer) OnRead(_ *peer.Peer, bytesRead int, msg wire.Message, err error) { sp.server.AddBytesReceived(uint64(bytesRead)) - // Try to send a message to the subscriber channel if it isn't nil, but - // don't block on failure. Do this inside a goroutine to prevent the - // server from slowing down too fast. + // Send a message to each subscriber. Each message gets its own + // goroutine to prevent blocking on the mutex lock. + // TODO: Flood control. sp.mtxSubscribers.RLock() defer sp.mtxSubscribers.RUnlock() for subscription := range sp.recvSubscribers { @@ -1835,7 +1835,7 @@ func (s *ChainService) GetCFilter(blockHash chainhash.Hash, // can ignore this message. return } - if MakeHeaderForFilter(gotFilter, + if builder.MakeHeaderForFilter(gotFilter, *prevHeader) != *curHeader { // Filter data doesn't match diff --git a/spvsvc/spvchain/sync_test.go b/spvsvc/spvchain/sync_test.go index 903de9c..dfe392d 100644 --- a/spvsvc/spvchain/sync_test.go +++ b/spvsvc/spvchain/sync_test.go @@ -17,6 +17,7 @@ import ( "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btclog" "github.com/btcsuite/btcrpcclient" + "github.com/btcsuite/btcutil/gcs/builder" "github.com/btcsuite/btcwallet/spvsvc/spvchain" "github.com/btcsuite/btcwallet/waddrmgr" "github.com/btcsuite/btcwallet/walletdb" @@ -486,7 +487,7 @@ func testRandomBlocks(t *testing.T, svc *spvchain.ChainService, return } // Calculate basic filter from block. - calcFilter, err := spvchain.BuildBasicFilter( + calcFilter, err := builder.BuildBasicFilter( haveBlock.MsgBlock()) if err != nil { errChan <- fmt.Errorf("Couldn't build basic "+ @@ -521,7 +522,7 @@ func testRandomBlocks(t *testing.T, svc *spvchain.ChainService, return } // Check that the filter and header line up. - calcHeader := spvchain.MakeHeaderForFilter(calcFilter, + calcHeader := builder.MakeHeaderForFilter(calcFilter, *prevHeader) if !bytes.Equal(curHeader[:], calcHeader[:]) { errChan <- fmt.Errorf("Filter header doesn't "+ @@ -554,7 +555,7 @@ func testRandomBlocks(t *testing.T, svc *spvchain.ChainService, return } // Calculate extended filter from block - calcFilter, err = spvchain.BuildExtFilter( + calcFilter, err = builder.BuildExtFilter( haveBlock.MsgBlock()) if err != nil { errChan <- fmt.Errorf("Couldn't build extended"+ @@ -591,7 +592,7 @@ func testRandomBlocks(t *testing.T, svc *spvchain.ChainService, return } // Check that the filter and header line up. - calcHeader = spvchain.MakeHeaderForFilter(calcFilter, + calcHeader = builder.MakeHeaderForFilter(calcFilter, *prevHeader) if !bytes.Equal(curHeader[:], calcHeader[:]) { errChan <- fmt.Errorf("Filter header doesn't "+