mirror of
https://github.com/btcsuite/btcd.git
synced 2024-11-19 01:40:07 +01:00
btcjson: turn warnings into StringOrArray type
Fixes #2224 and lightningnetwork/lnd#9053. Depending on the version of Bitcoin Core, the "warnings" field in the response to getnetworkinfo is either a single string value or an array of strings. We can easily parse those two variants with a custom type that implements an UnmarshalJSON method.
This commit is contained in:
parent
2b53ed1989
commit
ed879eac20
@ -8,6 +8,7 @@ import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
|
||||
@ -363,6 +364,49 @@ type LocalAddressesResult struct {
|
||||
Score int32 `json:"score"`
|
||||
}
|
||||
|
||||
// StringOrArray defines a type that can be used as type that is either a single
|
||||
// string value or a string array in JSON-RPC commands, depending on the version
|
||||
// of the chain backend.
|
||||
type StringOrArray []string
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface.
|
||||
func (h StringOrArray) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(h)
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaler interface.
|
||||
func (h *StringOrArray) UnmarshalJSON(data []byte) error {
|
||||
var unmarshalled interface{}
|
||||
if err := json.Unmarshal(data, &unmarshalled); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch v := unmarshalled.(type) {
|
||||
case string:
|
||||
*h = []string{v}
|
||||
|
||||
case []interface{}:
|
||||
s := make([]string, len(v))
|
||||
for i, e := range v {
|
||||
str, ok := e.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("invalid string_or_array "+
|
||||
"value: %v", unmarshalled)
|
||||
}
|
||||
|
||||
s[i] = str
|
||||
}
|
||||
|
||||
*h = s
|
||||
|
||||
default:
|
||||
return fmt.Errorf("invalid string_or_array value: %v",
|
||||
unmarshalled)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetNetworkInfoResult models the data returned from the getnetworkinfo
|
||||
// command.
|
||||
type GetNetworkInfoResult struct {
|
||||
@ -380,7 +424,7 @@ type GetNetworkInfoResult struct {
|
||||
RelayFee float64 `json:"relayfee"`
|
||||
IncrementalFee float64 `json:"incrementalfee"`
|
||||
LocalAddresses []LocalAddressesResult `json:"localaddresses"`
|
||||
Warnings string `json:"warnings"`
|
||||
Warnings StringOrArray `json:"warnings"`
|
||||
}
|
||||
|
||||
// GetNodeAddressesResult models the data returned from the getnodeaddresses
|
||||
|
@ -215,3 +215,51 @@ func TestChainSvrMiningInfoResults(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestGetNetworkInfoWarnings tests that we can use both a single string value
|
||||
// and an array of string values for the warnings field in GetNetworkInfoResult.
|
||||
func TestGetNetworkInfoWarnings(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
result string
|
||||
expected btcjson.GetNetworkInfoResult
|
||||
}{
|
||||
{
|
||||
name: "network info with single warning",
|
||||
result: `{"warnings": "this is a warning"}`,
|
||||
expected: btcjson.GetNetworkInfoResult{
|
||||
Warnings: btcjson.StringOrArray{
|
||||
"this is a warning",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "network info with array of warnings",
|
||||
result: `{"warnings": ["a", "or", "b"]}`,
|
||||
expected: btcjson.GetNetworkInfoResult{
|
||||
Warnings: btcjson.StringOrArray{
|
||||
"a", "or", "b",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
t.Logf("Running %d tests", len(tests))
|
||||
for i, test := range tests {
|
||||
var infoResult btcjson.GetNetworkInfoResult
|
||||
err := json.Unmarshal([]byte(test.result), &infoResult)
|
||||
if err != nil {
|
||||
t.Errorf("Test #%d (%s) unexpected error: %v", i,
|
||||
test.name, err)
|
||||
continue
|
||||
}
|
||||
if !reflect.DeepEqual(infoResult, test.expected) {
|
||||
t.Errorf("Test #%d (%s) unexpected marhsalled data - "+
|
||||
"got %+v, want %+v", i, test.name, infoResult,
|
||||
test.expected)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user