Return correct JSON object for listunspent.

This change fixes the reply for listunspent to return a JSON object in
the same format as done by the reference implementation.  Previously,
listunspent would return an array of the same objects as returned for
listtransactions.
This commit is contained in:
Josh Rickmar 2014-03-31 10:11:37 -05:00
parent 189df5c535
commit 3f40e256c2
2 changed files with 53 additions and 10 deletions

View file

@ -711,11 +711,17 @@ func (a *Account) TotalReceived(confirms int) (float64, error) {
// confirmed checks whether a transaction at height txHeight has met
// minconf confirmations for a blockchain at height curHeight.
func confirmed(minconf int, txHeight, curHeight int32) bool {
if minconf == 0 {
return true
}
if txHeight != -1 && int(curHeight-txHeight+1) >= minconf {
return true
}
return false
return confirms(txHeight, curHeight) >= int32(minconf)
}
// confirms returns the number of confirmations for a transaction in a
// block at height txHeight (or -1 for an unconfirmed tx) given the chain
// height curHeight.
func confirms(txHeight, curHeight int32) int32 {
switch {
case txHeight == -1, txHeight > curHeight:
return 0
default:
return curHeight - txHeight + 1
}
}

View file

@ -18,6 +18,7 @@ package main
import (
"container/list"
"encoding/hex"
"errors"
"fmt"
"github.com/conformal/btcutil"
@ -574,19 +575,55 @@ func (am *AccountManager) GetTransaction(txsha *btcwire.ShaHash) []accountTx {
// transaction an empty array will be returned.
func (am *AccountManager) ListUnspent(minconf, maxconf int,
addresses map[string]bool) ([]map[string]interface{}, error) {
bs, err := GetCurBlock()
if err != nil {
return nil, err
}
filter := len(addresses) != 0
infos := []map[string]interface{}{}
for _, a := range am.AllAccounts() {
for _, record := range a.TxStore.UnspentOutputs() {
info := record.TxInfo(a.name, bs.Height, cfg.Net())[0]
for _, rtx := range a.TxStore.UnspentOutputs() {
confs := confirms(rtx.Height(), bs.Height)
switch {
case int(confs) < minconf, int(confs) > maxconf:
continue
}
_, addrs, _, _ := rtx.Addresses(cfg.Net())
if filter {
for _, addr := range addrs {
_, ok := addresses[addr.EncodeAddress()]
if ok {
goto include
}
}
continue
}
include:
outpoint := rtx.OutPoint()
info := map[string]interface{}{
"txid": outpoint.Hash.String(),
"vout": float64(outpoint.Index),
"account": a.Name(),
"scriptPubKey": hex.EncodeToString(rtx.PkScript()),
"amount": float64(rtx.Value()) / 1e8,
"confirmations": float64(confs),
}
// BUG: this should be a JSON array so that all
// addresses can be included, or removed (and the
// caller extracts addresses from the pkScript).
if len(addrs) > 0 {
info["address"] = addrs[0].EncodeAddress()
}
infos = append(infos, info)
}
}
return infos, nil
}