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.
This commit is contained in:
Dave Collins 2017-01-27 19:54:25 -06:00
parent 6a54323258
commit 554460feda
No known key found for this signature in database
GPG key ID: B8904D9D9C93D1F2
3 changed files with 47 additions and 39 deletions

4
glide.lock generated
View file

@ -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:

View file

@ -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
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++

View file

@ -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
}