From 554460feda87a4dac87af8dd23761e220dde0b03 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Fri, 27 Jan 2017 19:54:25 -0600 Subject: [PATCH] rpctest: Update to use new filtered block ntfns. This modifies the rpctest harness and its associated memwallet to make use of the new filter-based notifications since the old notifications are now deprecated. It also updates the glide.lock file to require the necessary btcrpcclient version. --- glide.lock | 4 ++-- rpctest/memwallet.go | 37 +++++++++++++++++----------------- rpctest/rpc_harness.go | 45 ++++++++++++++++++++++++------------------ 3 files changed, 47 insertions(+), 39 deletions(-) diff --git a/glide.lock b/glide.lock index ed403760..6a1f63ea 100644 --- a/glide.lock +++ b/glide.lock @@ -1,10 +1,10 @@ hash: ea6e6ffa31517aacb35de06b097975229096253bf658d302f2d6652fde91b3f1 -updated: 2017-01-11T15:54:00.925235328-05:00 +updated: 2017-01-27T20:06:58.5779336-06:00 imports: - name: github.com/btcsuite/btclog version: 73889fb79bd687870312b6e40effcecffbd57d30 - name: github.com/btcsuite/btcrpcclient - version: 5ce0ed600997eafaed25ad4936c1d84ec6ad2b5a + version: abcdfb702a7ca67e4a32c10be380c63216bd69fe - name: github.com/btcsuite/btcutil version: 86346b5a958c0cf94186b87855469ae991be501c subpackages: diff --git a/rpctest/memwallet.go b/rpctest/memwallet.go index 791a0d94..f33fa818 100644 --- a/rpctest/memwallet.go +++ b/rpctest/memwallet.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016 The btcsuite developers +// Copyright (c) 2016-2017 The btcsuite developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -9,7 +9,6 @@ import ( "encoding/binary" "fmt" "sync" - "time" "github.com/btcsuite/btcd/blockchain" "github.com/btcsuite/btcd/btcec" @@ -55,8 +54,8 @@ func (u *utxo) isMature(height int32) bool { // used to sync up the memWallet each time a new block is connected to the main // chain. type chainUpdate struct { - blockHash *chainhash.Hash - blockHeight int32 + blockHeight int32 + filteredTxns []*btcutil.Tx } // undoEntry is functionally the opposite of a chainUpdate. An undoEntry is @@ -179,11 +178,11 @@ func (m *memWallet) SetRPCClient(rpcClient *btcrpcclient.Client) { // IngestBlock is a call-back which is to be triggered each time a new block is // connected to the main chain. Ingesting a block updates the wallet's internal // utxo state based on the outputs created and destroyed within each block. -func (m *memWallet) IngestBlock(blockHash *chainhash.Hash, height int32, t time.Time) { +func (m *memWallet) IngestBlock(height int32, header *wire.BlockHeader, filteredTxns []*btcutil.Tx) { // Append this new chain update to the end of the queue of new chain // updates. m.chainMtx.Lock() - m.chainUpdates = append(m.chainUpdates, &chainUpdate{blockHash, height}) + m.chainUpdates = append(m.chainUpdates, &chainUpdate{height, filteredTxns}) m.chainMtx.Unlock() // Launch a goroutine to signal the chainSyncer that a new update is @@ -210,21 +209,16 @@ func (m *memWallet) chainSyncer() { m.chainUpdates = m.chainUpdates[1:] m.chainMtx.Unlock() - // Fetch the new block so we can process it shortly below. - block, err := m.rpc.GetBlock(update.blockHash) - if err != nil { - return - } - - // Update the latest synced height, then process each - // transaction in the block creating and destroying utxos - // within the wallet as a result. + // Update the latest synced height, then process each filtered + // transaction in the block creating and destroying utxos within + // the wallet as a result. m.Lock() m.currentHeight = update.blockHeight undo := &undoEntry{ utxosDestroyed: make(map[wire.OutPoint]*utxo), } - for _, mtx := range block.Transactions { + for _, tx := range update.filteredTxns { + mtx := tx.MsgTx() isCoinbase := blockchain.IsCoinBaseTx(mtx) txHash := mtx.TxHash() m.evalOutputs(mtx.TxOut, &txHash, isCoinbase, undo) @@ -293,7 +287,7 @@ func (m *memWallet) evalInputs(inputs []*wire.TxIn, undo *undoEntry) { // UnwindBlock is a call-back which is to be executed each time a block is // disconnected from the main chain. Unwinding a block undoes the effect that a // particular block had on the wallet's internal utxo state. -func (m *memWallet) UnwindBlock(hash *chainhash.Hash, height int32, t time.Time) { +func (m *memWallet) UnwindBlock(height int32, header *wire.BlockHeader) { m.Lock() defer m.Unlock() @@ -310,7 +304,9 @@ func (m *memWallet) UnwindBlock(hash *chainhash.Hash, height int32, t time.Time) delete(m.reorgJournal, height) } -// newAddress returns a new address from the wallet's hd key chain. +// newAddress returns a new address from the wallet's hd key chain. It also +// loads the address into the RPC client's transaction filter to ensure any +// transactions that involve it are delivered via the notifications. func (m *memWallet) newAddress() (btcutil.Address, error) { index := m.hdIndex @@ -328,6 +324,11 @@ func (m *memWallet) newAddress() (btcutil.Address, error) { return nil, err } + err = m.rpc.LoadTxFilter(false, []btcutil.Address{addr}, nil) + if err != nil { + return nil, err + } + m.addrs[index] = addr m.hdIndex++ diff --git a/rpctest/rpc_harness.go b/rpctest/rpc_harness.go index fc071b86..7d1b5f7c 100644 --- a/rpctest/rpc_harness.go +++ b/rpctest/rpc_harness.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016 The btcsuite developers +// Copyright (c) 2016-2017 The btcsuite developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -160,28 +160,28 @@ func New(activeNet *chaincfg.Params, handlers *btcrpcclient.NotificationHandlers handlers = &btcrpcclient.NotificationHandlers{} } - // If a handler for the OnBlockConnected/OnBlockDisconnected callback - // has already been set, then we create a wrapper callback which - // executes both the currently registered callback, and the mem - // wallet's callback. - if handlers.OnBlockConnected != nil { - obc := handlers.OnBlockConnected - handlers.OnBlockConnected = func(hash *chainhash.Hash, height int32, t time.Time) { - wallet.IngestBlock(hash, height, t) - obc(hash, height, t) + // If a handler for the OnFilteredBlock{Connected,Disconnected} callback + // callback has already been set, then create a wrapper callback which + // executes both the currently registered callback and the mem wallet's + // callback. + if handlers.OnFilteredBlockConnected != nil { + obc := handlers.OnFilteredBlockConnected + handlers.OnFilteredBlockConnected = func(height int32, header *wire.BlockHeader, filteredTxns []*btcutil.Tx) { + wallet.IngestBlock(height, header, filteredTxns) + obc(height, header, filteredTxns) } } else { // Otherwise, we can claim the callback ourselves. - handlers.OnBlockConnected = wallet.IngestBlock + handlers.OnFilteredBlockConnected = wallet.IngestBlock } - if handlers.OnBlockDisconnected != nil { - obd := handlers.OnBlockConnected - handlers.OnBlockDisconnected = func(hash *chainhash.Hash, height int32, t time.Time) { - wallet.UnwindBlock(hash, height, t) - obd(hash, height, t) + if handlers.OnFilteredBlockDisconnected != nil { + obd := handlers.OnFilteredBlockDisconnected + handlers.OnFilteredBlockDisconnected = func(height int32, header *wire.BlockHeader) { + wallet.UnwindBlock(height, header) + obd(height, header) } } else { - handlers.OnBlockDisconnected = wallet.UnwindBlock + handlers.OnFilteredBlockDisconnected = wallet.UnwindBlock } h := &Harness{ @@ -220,8 +220,15 @@ func (h *Harness) SetUp(createTestChain bool, numMatureOutputs uint32) error { h.wallet.Start() - // Ensure the btcd properly dispatches our registered call-back for - // each new block. Otherwise, the memWallet won't function properly. + // Filter transactions that pay to the coinbase associated with the + // wallet. + filterAddrs := []btcutil.Address{h.wallet.coinbaseAddr} + if err := h.Node.LoadTxFilter(true, filterAddrs, nil); err != nil { + return err + } + + // Ensure btcd properly dispatches our registered call-back for each new + // block. Otherwise, the memWallet won't function properly. if err := h.Node.NotifyBlocks(); err != nil { return err }