Include P2PK outputs for rescanned P2PKH addrs.

This change fixes rescan to include transactions that pay to the
pubkey for a rescanned pubkey hash address.  This behavior was lost
when the rescan was optimized for specific types of the
btcutil.Address interface.

ok @davecgh
This commit is contained in:
Josh Rickmar 2014-04-25 09:02:23 -05:00
parent 27082ace79
commit bba0a0482d

View file

@ -1481,14 +1481,6 @@ type rescanKeys struct {
// rescanBlock rescans all transactions in a single block. This is a helper // rescanBlock rescans all transactions in a single block. This is a helper
// function for handleRescan. // function for handleRescan.
func rescanBlock(wsc *wsClient, lookups *rescanKeys, blk *btcutil.Block) { func rescanBlock(wsc *wsClient, lookups *rescanKeys, blk *btcutil.Block) {
// Vars used for map keys. If necessary, the byte slice for each
// checked item is copied into and then used as the lookup key.
// This is quite a bit more efficient than creating an address
// string as it saves on GC and performs less copying.
var compressedPubkey [33]byte
var uncompressedPubkey [65]byte
var outpoint btcwire.OutPoint
for _, tx := range blk.Transactions() { for _, tx := range blk.Transactions() {
// Hexadecimal representation of this tx. Only created if // Hexadecimal representation of this tx. Only created if
// needed, and reused for later notifications if already made. // needed, and reused for later notifications if already made.
@ -1545,25 +1537,36 @@ func rescanBlock(wsc *wsClient, lookups *rescanKeys, blk *btcutil.Block) {
} }
case *btcutil.AddressPubKey: case *btcutil.AddressPubKey:
pubkeyBytes := a.ScriptAddress() found := false
switch len(pubkeyBytes) { switch sa := a.ScriptAddress(); len(sa) {
case 33: // Compressed case 33: // Compressed
copy(compressedPubkey[:], pubkeyBytes) var key [33]byte
_, ok := lookups.compressedPubkeys[compressedPubkey] copy(key[:], sa)
if !ok { if _, ok := lookups.compressedPubkeys[key]; ok {
continue found = true
} }
case 65: // Uncompressed case 65: // Uncompressed
copy(uncompressedPubkey[:], pubkeyBytes) var key [65]byte
_, ok := lookups.uncompressedPubkeys[uncompressedPubkey] copy(key[:], sa)
if !ok { if _, ok := lookups.uncompressedPubkeys[key]; ok {
found = true
}
default:
rpcsLog.Warnf("Skipping rescanned pubkey of unknown "+
"serialized length %d", len(sa))
continue continue
} }
default: // wtf // If the transaction output pays to the pubkey of
// a rescanned P2PKH address, include it as well.
if !found {
pkh := a.AddressPubKeyHash()
if _, ok := lookups.pubKeyHashes[*pkh.Hash160()]; !ok {
continue continue
} }
}
default: default:
// A new address type must have been added. Encode as a // A new address type must have been added. Encode as a
@ -1575,8 +1578,10 @@ func rescanBlock(wsc *wsClient, lookups *rescanKeys, blk *btcutil.Block) {
} }
} }
copy(outpoint.Hash[:], tx.Sha()[:]) outpoint := btcwire.OutPoint{
outpoint.Index = uint32(txOutIdx) Hash: *tx.Sha(),
Index: uint32(txOutIdx),
}
lookups.unspent[outpoint] = struct{}{} lookups.unspent[outpoint] = struct{}{}
if recvNotified { if recvNotified {