Implement the listunspent command

closes #54
This commit is contained in:
Owain G. Ainsworth 2014-02-13 18:43:52 +00:00
parent 70eb389029
commit ed264697e7
2 changed files with 97 additions and 1 deletions

View file

@ -496,6 +496,68 @@ func (am *AccountManager) GetTransaction(txid string) []accountTx {
return accumulatedTxen
}
// ListUnspent returns an array of objects representing the unspent
// wallet transactions fitting the given criteria. The confirmations will be
// more then minconf, less than maxconf and if addresses is populated only the
// addresses contained within it will be considered.
// a transaction on locally known wallets. If we know nothing about a
// 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
}
replies := []map[string]interface{}{}
for _, a := range am.AllAccounts() {
for _, u := range a.UtxoStore {
confirmations := 0
if u.Height != -1 {
confirmations = int(bs.Height - u.Height + 1)
}
if minconf != 0 && (u.Height == -1 ||
confirmations < minconf) {
continue
}
// check maxconf - doesn't apply if not confirmed.
if u.Height != -1 && confirmations > maxconf {
continue
}
addr, err := btcutil.NewAddressPubKeyHash(u.AddrHash[:],
cfg.Net())
if err != nil {
continue
}
// if we hve addresses, limit to that list.
if len(addresses) > 0 {
if _, ok := addresses[addr.EncodeAddress()]; !ok {
continue
}
}
entry := map[string]interface{}{
// check minconf/maxconf
"txid": u.Out.Hash.String(),
"vout": u.Out.Index,
"address": addr.EncodeAddress(),
"account": a.name,
"scriptPubKey": u.Subscript,
"amount": float64(u.Amt) / float64(btcutil.SatoshiPerBitcoin),
"confirmations": confirmations,
// TODO(oga) if the object is
// pay-to-script-hash we need to add the
// redeemscript.
}
replies = append(replies, entry)
}
}
return replies, nil
}
// RescanActiveAddresses begins a rescan for all active addresses for
// each account.
//

View file

@ -49,6 +49,7 @@ var rpcHandlers = map[string]cmdHandler{
"listaccounts": ListAccounts,
"listsinceblock": ListSinceBlock,
"listtransactions": ListTransactions,
"listunspent": ListUnspent,
"sendfrom": SendFrom,
"sendmany": SendMany,
"sendtoaddress": SendToAddress,
@ -74,7 +75,6 @@ var rpcHandlers = map[string]cmdHandler{
"listlockunspent": Unimplemented,
"listreceivedbyaccount": Unimplemented,
"listreceivedbyaddress": Unimplemented,
"listunspent": Unimplemented,
"lockunspent": Unimplemented,
"move": Unimplemented,
"setaccount": Unimplemented,
@ -1090,6 +1090,40 @@ func ListAllTransactions(icmd btcjson.Cmd) (interface{}, *btcjson.Error) {
}
}
// ListUnspent handles the listunspent command.
func ListUnspent(icmd btcjson.Cmd) (interface{}, *btcjson.Error) {
cmd, ok := icmd.(*btcjson.ListUnspentCmd)
if !ok {
return nil, &btcjson.ErrInternal
}
addresses := make(map[string]bool)
if len(cmd.Addresses) != 0 {
// confirm that all of them are good:
for _, as := range cmd.Addresses {
a, err := btcutil.DecodeAddr(as)
if err != nil {
return nil, &btcjson.ErrInvalidAddressOrKey
}
if _, ok := addresses[a.EncodeAddress()]; ok {
// duplicate
return nil, &btcjson.ErrInvalidParameter
}
addresses[a.EncodeAddress()] = true
}
}
results, err := AcctMgr.ListUnspent(cmd.MinConf, cmd.MaxConf, addresses)
if err != nil {
return nil, &btcjson.Error{
Code: btcjson.ErrWallet.Code,
Message: err.Error(),
}
}
return results, nil
}
// sendPairs is a helper routine to reduce duplicated code when creating and
// sending payment transactions.
func sendPairs(icmd btcjson.Cmd, account string, amounts map[string]int64,