Return non-nil RPC results for 0 length slices.

If a JSON array result was successfully calculated, but the
slice/array is empty, the result must be marshaled as '[]' rather than
the JSON null value.  To do this in go, the RPC handlers should never
return nil slices for non-error returns, but return a non-nil slice
header with 0 length.

For example, an empty listtransactions result should be returned as
[]btcjson.ListTransactionsResult{}, rather than nil.
This commit is contained in:
Josh Rickmar 2014-06-12 13:58:23 -05:00
parent 3ff16d7539
commit e4c0fc81dd
3 changed files with 9 additions and 9 deletions

View file

@ -173,7 +173,7 @@ func (a *Account) CurrentAddress() (btcutil.Address, error) {
func (a *Account) ListSinceBlock(since, curBlockHeight int32, func (a *Account) ListSinceBlock(since, curBlockHeight int32,
minconf int) ([]btcjson.ListTransactionsResult, error) { minconf int) ([]btcjson.ListTransactionsResult, error) {
var txList []btcjson.ListTransactionsResult txList := []btcjson.ListTransactionsResult{}
for _, txRecord := range a.TxStore.Records() { for _, txRecord := range a.TxStore.Records() {
// Transaction records must only be considered if they occur // Transaction records must only be considered if they occur
// after the block height since. // after the block height since.
@ -208,7 +208,7 @@ func (a *Account) ListTransactions(from, count int) ([]btcjson.ListTransactionsR
return nil, err return nil, err
} }
var txList []btcjson.ListTransactionsResult txList := []btcjson.ListTransactionsResult{}
records := a.TxStore.Records() records := a.TxStore.Records()
lastLookupIdx := len(records) - count lastLookupIdx := len(records) - count
@ -237,7 +237,7 @@ func (a *Account) ListAddressTransactions(pkHashes map[string]struct{}) (
return nil, err return nil, err
} }
var txList []btcjson.ListTransactionsResult txList := []btcjson.ListTransactionsResult{}
for _, r := range a.TxStore.Records() { for _, r := range a.TxStore.Records() {
for _, c := range r.Credits() { for _, c := range r.Credits() {
// We only care about the case where len(addrs) == 1, // We only care about the case where len(addrs) == 1,
@ -278,7 +278,7 @@ func (a *Account) ListAllTransactions() ([]btcjson.ListTransactionsResult, error
// Search in reverse order: lookup most recently-added first. // Search in reverse order: lookup most recently-added first.
records := a.TxStore.Records() records := a.TxStore.Records()
var txList []btcjson.ListTransactionsResult txList := []btcjson.ListTransactionsResult{}
for i := len(records) - 1; i >= 0; i-- { for i := len(records) - 1; i >= 0; i-- {
jsonResults, err := records[i].ToJSON(a.name, bs.Height, a.Net()) jsonResults, err := records[i].ToJSON(a.name, bs.Height, a.Net())
if err != nil { if err != nil {
@ -295,7 +295,7 @@ func (a *Account) ListAllTransactions() ([]btcjson.ListTransactionsResult, error
func (a *Account) DumpPrivKeys() ([]string, error) { func (a *Account) DumpPrivKeys() ([]string, error) {
// Iterate over each active address, appending the private // Iterate over each active address, appending the private
// key to privkeys. // key to privkeys.
var privkeys []string privkeys := []string{}
for _, info := range a.Wallet.ActiveAddresses() { for _, info := range a.Wallet.ActiveAddresses() {
// Only those addresses with keys needed. // Only those addresses with keys needed.
pka, ok := info.(wallet.PubKeyAddress) pka, ok := info.(wallet.PubKeyAddress)

View file

@ -800,7 +800,7 @@ func (am *AccountManager) UnlockWallets(passphrase string) (err error) {
// DumpKeys returns all WIF-encoded private keys associated with all // DumpKeys returns all WIF-encoded private keys associated with all
// accounts. All wallets must be unlocked for this operation to succeed. // accounts. All wallets must be unlocked for this operation to succeed.
func (am *AccountManager) DumpKeys() ([]string, error) { func (am *AccountManager) DumpKeys() ([]string, error) {
var keys []string keys := []string{}
for _, a := range am.AllAccounts() { for _, a := range am.AllAccounts() {
switch walletKeys, err := a.DumpPrivKeys(); err { switch walletKeys, err := a.DumpPrivKeys(); err {
case wallet.ErrWalletLocked: case wallet.ErrWalletLocked:
@ -845,7 +845,7 @@ func (am *AccountManager) ListSinceBlock(since, curBlockHeight int32,
minconf int) ([]btcjson.ListTransactionsResult, error) { minconf int) ([]btcjson.ListTransactionsResult, error) {
// Create and fill a map of account names and their balances. // Create and fill a map of account names and their balances.
var txList []btcjson.ListTransactionsResult txList := []btcjson.ListTransactionsResult{}
for _, a := range am.AllAccounts() { for _, a := range am.AllAccounts() {
txTmp, err := a.ListSinceBlock(since, curBlockHeight, minconf) txTmp, err := a.ListSinceBlock(since, curBlockHeight, minconf)
if err != nil { if err != nil {
@ -901,7 +901,7 @@ func (am *AccountManager) ListUnspent(minconf, maxconf int,
filter := len(addresses) != 0 filter := len(addresses) != 0
var results []*btcjson.ListUnspentResult results := []*btcjson.ListUnspentResult{}
for _, a := range am.AllAccounts() { for _, a := range am.AllAccounts() {
unspent, err := a.TxStore.SortedUnspentOutputs() unspent, err := a.TxStore.SortedUnspentOutputs()
if err != nil { if err != nil {

View file

@ -29,7 +29,7 @@ import (
func (t *TxRecord) ToJSON(account string, chainHeight int32, func (t *TxRecord) ToJSON(account string, chainHeight int32,
net *btcnet.Params) ([]btcjson.ListTransactionsResult, error) { net *btcnet.Params) ([]btcjson.ListTransactionsResult, error) {
var results []btcjson.ListTransactionsResult results := []btcjson.ListTransactionsResult{}
if d := t.Debits(); d != nil { if d := t.Debits(); d != nil {
r, err := d.ToJSON(account, chainHeight, net) r, err := d.ToJSON(account, chainHeight, net)
if err != nil { if err != nil {