github.com/lbryio/lbcd@v0.22.119/btcjson/chainsvrwscmds_test.go (about)

     1  // Copyright (c) 2014-2017 The btcsuite developers
     2  // Copyright (c) 2015-2017 The Decred developers
     3  // Use of this source code is governed by an ISC
     4  // license that can be found in the LICENSE file.
     5  
     6  package btcjson_test
     7  
     8  import (
     9  	"bytes"
    10  	"encoding/json"
    11  	"fmt"
    12  	"reflect"
    13  	"testing"
    14  
    15  	"github.com/lbryio/lbcd/btcjson"
    16  )
    17  
    18  // TestChainSvrWsCmds tests all of the chain server websocket-specific commands
    19  // marshal and unmarshal into valid results include handling of optional fields
    20  // being omitted in the marshalled command, while optional fields with defaults
    21  // have the default assigned on unmarshalled commands.
    22  func TestChainSvrWsCmds(t *testing.T) {
    23  	t.Parallel()
    24  
    25  	testID := int(1)
    26  	tests := []struct {
    27  		name         string
    28  		newCmd       func() (interface{}, error)
    29  		staticCmd    func() interface{}
    30  		marshalled   string
    31  		unmarshalled interface{}
    32  	}{
    33  		{
    34  			name: "authenticate",
    35  			newCmd: func() (interface{}, error) {
    36  				return btcjson.NewCmd("authenticate", "user", "pass")
    37  			},
    38  			staticCmd: func() interface{} {
    39  				return btcjson.NewAuthenticateCmd("user", "pass")
    40  			},
    41  			marshalled:   `{"jsonrpc":"1.0","method":"authenticate","params":["user","pass"],"id":1}`,
    42  			unmarshalled: &btcjson.AuthenticateCmd{Username: "user", Passphrase: "pass"},
    43  		},
    44  		{
    45  			name: "notifyblocks",
    46  			newCmd: func() (interface{}, error) {
    47  				return btcjson.NewCmd("notifyblocks")
    48  			},
    49  			staticCmd: func() interface{} {
    50  				return btcjson.NewNotifyBlocksCmd()
    51  			},
    52  			marshalled:   `{"jsonrpc":"1.0","method":"notifyblocks","params":[],"id":1}`,
    53  			unmarshalled: &btcjson.NotifyBlocksCmd{},
    54  		},
    55  		{
    56  			name: "stopnotifyblocks",
    57  			newCmd: func() (interface{}, error) {
    58  				return btcjson.NewCmd("stopnotifyblocks")
    59  			},
    60  			staticCmd: func() interface{} {
    61  				return btcjson.NewStopNotifyBlocksCmd()
    62  			},
    63  			marshalled:   `{"jsonrpc":"1.0","method":"stopnotifyblocks","params":[],"id":1}`,
    64  			unmarshalled: &btcjson.StopNotifyBlocksCmd{},
    65  		},
    66  		{
    67  			name: "notifynewtransactions",
    68  			newCmd: func() (interface{}, error) {
    69  				return btcjson.NewCmd("notifynewtransactions")
    70  			},
    71  			staticCmd: func() interface{} {
    72  				return btcjson.NewNotifyNewTransactionsCmd(nil)
    73  			},
    74  			marshalled: `{"jsonrpc":"1.0","method":"notifynewtransactions","params":[],"id":1}`,
    75  			unmarshalled: &btcjson.NotifyNewTransactionsCmd{
    76  				Verbose: btcjson.Bool(false),
    77  			},
    78  		},
    79  		{
    80  			name: "notifynewtransactions optional",
    81  			newCmd: func() (interface{}, error) {
    82  				return btcjson.NewCmd("notifynewtransactions", true)
    83  			},
    84  			staticCmd: func() interface{} {
    85  				return btcjson.NewNotifyNewTransactionsCmd(btcjson.Bool(true))
    86  			},
    87  			marshalled: `{"jsonrpc":"1.0","method":"notifynewtransactions","params":[true],"id":1}`,
    88  			unmarshalled: &btcjson.NotifyNewTransactionsCmd{
    89  				Verbose: btcjson.Bool(true),
    90  			},
    91  		},
    92  		{
    93  			name: "stopnotifynewtransactions",
    94  			newCmd: func() (interface{}, error) {
    95  				return btcjson.NewCmd("stopnotifynewtransactions")
    96  			},
    97  			staticCmd: func() interface{} {
    98  				return btcjson.NewStopNotifyNewTransactionsCmd()
    99  			},
   100  			marshalled:   `{"jsonrpc":"1.0","method":"stopnotifynewtransactions","params":[],"id":1}`,
   101  			unmarshalled: &btcjson.StopNotifyNewTransactionsCmd{},
   102  		},
   103  		{
   104  			name: "notifyreceived",
   105  			newCmd: func() (interface{}, error) {
   106  				return btcjson.NewCmd("notifyreceived", []string{"1Address"})
   107  			},
   108  			staticCmd: func() interface{} {
   109  				return btcjson.NewNotifyReceivedCmd([]string{"1Address"})
   110  			},
   111  			marshalled: `{"jsonrpc":"1.0","method":"notifyreceived","params":[["1Address"]],"id":1}`,
   112  			unmarshalled: &btcjson.NotifyReceivedCmd{
   113  				Addresses: []string{"1Address"},
   114  			},
   115  		},
   116  		{
   117  			name: "stopnotifyreceived",
   118  			newCmd: func() (interface{}, error) {
   119  				return btcjson.NewCmd("stopnotifyreceived", []string{"1Address"})
   120  			},
   121  			staticCmd: func() interface{} {
   122  				return btcjson.NewStopNotifyReceivedCmd([]string{"1Address"})
   123  			},
   124  			marshalled: `{"jsonrpc":"1.0","method":"stopnotifyreceived","params":[["1Address"]],"id":1}`,
   125  			unmarshalled: &btcjson.StopNotifyReceivedCmd{
   126  				Addresses: []string{"1Address"},
   127  			},
   128  		},
   129  		{
   130  			name: "notifyspent",
   131  			newCmd: func() (interface{}, error) {
   132  				return btcjson.NewCmd("notifyspent", `[{"hash":"123","index":0}]`)
   133  			},
   134  			staticCmd: func() interface{} {
   135  				ops := []btcjson.OutPoint{{Hash: "123", Index: 0}}
   136  				return btcjson.NewNotifySpentCmd(ops)
   137  			},
   138  			marshalled: `{"jsonrpc":"1.0","method":"notifyspent","params":[[{"hash":"123","index":0}]],"id":1}`,
   139  			unmarshalled: &btcjson.NotifySpentCmd{
   140  				OutPoints: []btcjson.OutPoint{{Hash: "123", Index: 0}},
   141  			},
   142  		},
   143  		{
   144  			name: "stopnotifyspent",
   145  			newCmd: func() (interface{}, error) {
   146  				return btcjson.NewCmd("stopnotifyspent", `[{"hash":"123","index":0}]`)
   147  			},
   148  			staticCmd: func() interface{} {
   149  				ops := []btcjson.OutPoint{{Hash: "123", Index: 0}}
   150  				return btcjson.NewStopNotifySpentCmd(ops)
   151  			},
   152  			marshalled: `{"jsonrpc":"1.0","method":"stopnotifyspent","params":[[{"hash":"123","index":0}]],"id":1}`,
   153  			unmarshalled: &btcjson.StopNotifySpentCmd{
   154  				OutPoints: []btcjson.OutPoint{{Hash: "123", Index: 0}},
   155  			},
   156  		},
   157  		{
   158  			name: "rescan",
   159  			newCmd: func() (interface{}, error) {
   160  				return btcjson.NewCmd("rescan", "123", `["1Address"]`, `[{"hash":"0000000000000000000000000000000000000000000000000000000000000123","index":0}]`)
   161  			},
   162  			staticCmd: func() interface{} {
   163  				addrs := []string{"1Address"}
   164  				ops := []btcjson.OutPoint{{
   165  					Hash:  "0000000000000000000000000000000000000000000000000000000000000123",
   166  					Index: 0,
   167  				}}
   168  				return btcjson.NewRescanCmd("123", addrs, ops, nil)
   169  			},
   170  			marshalled: `{"jsonrpc":"1.0","method":"rescan","params":["123",["1Address"],[{"hash":"0000000000000000000000000000000000000000000000000000000000000123","index":0}]],"id":1}`,
   171  			unmarshalled: &btcjson.RescanCmd{
   172  				BeginBlock: "123",
   173  				Addresses:  []string{"1Address"},
   174  				OutPoints:  []btcjson.OutPoint{{Hash: "0000000000000000000000000000000000000000000000000000000000000123", Index: 0}},
   175  				EndBlock:   nil,
   176  			},
   177  		},
   178  		{
   179  			name: "rescan optional",
   180  			newCmd: func() (interface{}, error) {
   181  				return btcjson.NewCmd("rescan", "123", `["1Address"]`, `[{"hash":"123","index":0}]`, "456")
   182  			},
   183  			staticCmd: func() interface{} {
   184  				addrs := []string{"1Address"}
   185  				ops := []btcjson.OutPoint{{Hash: "123", Index: 0}}
   186  				return btcjson.NewRescanCmd("123", addrs, ops, btcjson.String("456"))
   187  			},
   188  			marshalled: `{"jsonrpc":"1.0","method":"rescan","params":["123",["1Address"],[{"hash":"123","index":0}],"456"],"id":1}`,
   189  			unmarshalled: &btcjson.RescanCmd{
   190  				BeginBlock: "123",
   191  				Addresses:  []string{"1Address"},
   192  				OutPoints:  []btcjson.OutPoint{{Hash: "123", Index: 0}},
   193  				EndBlock:   btcjson.String("456"),
   194  			},
   195  		},
   196  		{
   197  			name: "loadtxfilter",
   198  			newCmd: func() (interface{}, error) {
   199  				return btcjson.NewCmd("loadtxfilter", false, `["1Address"]`, `[{"hash":"0000000000000000000000000000000000000000000000000000000000000123","index":0}]`)
   200  			},
   201  			staticCmd: func() interface{} {
   202  				addrs := []string{"1Address"}
   203  				ops := []btcjson.OutPoint{{
   204  					Hash:  "0000000000000000000000000000000000000000000000000000000000000123",
   205  					Index: 0,
   206  				}}
   207  				return btcjson.NewLoadTxFilterCmd(false, addrs, ops)
   208  			},
   209  			marshalled: `{"jsonrpc":"1.0","method":"loadtxfilter","params":[false,["1Address"],[{"hash":"0000000000000000000000000000000000000000000000000000000000000123","index":0}]],"id":1}`,
   210  			unmarshalled: &btcjson.LoadTxFilterCmd{
   211  				Reload:    false,
   212  				Addresses: []string{"1Address"},
   213  				OutPoints: []btcjson.OutPoint{{Hash: "0000000000000000000000000000000000000000000000000000000000000123", Index: 0}},
   214  			},
   215  		},
   216  		{
   217  			name: "rescanblocks",
   218  			newCmd: func() (interface{}, error) {
   219  				return btcjson.NewCmd("rescanblocks", `["0000000000000000000000000000000000000000000000000000000000000123"]`)
   220  			},
   221  			staticCmd: func() interface{} {
   222  				blockhashes := []string{"0000000000000000000000000000000000000000000000000000000000000123"}
   223  				return btcjson.NewRescanBlocksCmd(blockhashes)
   224  			},
   225  			marshalled: `{"jsonrpc":"1.0","method":"rescanblocks","params":[["0000000000000000000000000000000000000000000000000000000000000123"]],"id":1}`,
   226  			unmarshalled: &btcjson.RescanBlocksCmd{
   227  				BlockHashes: []string{"0000000000000000000000000000000000000000000000000000000000000123"},
   228  			},
   229  		},
   230  	}
   231  
   232  	t.Logf("Running %d tests", len(tests))
   233  	for i, test := range tests {
   234  		// Marshal the command as created by the new static command
   235  		// creation function.
   236  		marshalled, err := btcjson.MarshalCmd(btcjson.RpcVersion1, testID, test.staticCmd())
   237  		if err != nil {
   238  			t.Errorf("MarshalCmd #%d (%s) unexpected error: %v", i,
   239  				test.name, err)
   240  			continue
   241  		}
   242  
   243  		if !bytes.Equal(marshalled, []byte(test.marshalled)) {
   244  			t.Errorf("Test #%d (%s) unexpected marshalled data - "+
   245  				"got %s, want %s", i, test.name, marshalled,
   246  				test.marshalled)
   247  			continue
   248  		}
   249  
   250  		// Ensure the command is created without error via the generic
   251  		// new command creation function.
   252  		cmd, err := test.newCmd()
   253  		if err != nil {
   254  			t.Errorf("Test #%d (%s) unexpected NewCmd error: %v ",
   255  				i, test.name, err)
   256  		}
   257  
   258  		// Marshal the command as created by the generic new command
   259  		// creation function.
   260  		marshalled, err = btcjson.MarshalCmd(btcjson.RpcVersion1, testID, cmd)
   261  		if err != nil {
   262  			t.Errorf("MarshalCmd #%d (%s) unexpected error: %v", i,
   263  				test.name, err)
   264  			continue
   265  		}
   266  
   267  		if !bytes.Equal(marshalled, []byte(test.marshalled)) {
   268  			t.Errorf("Test #%d (%s) unexpected marshalled data - "+
   269  				"got %s, want %s", i, test.name, marshalled,
   270  				test.marshalled)
   271  			continue
   272  		}
   273  
   274  		var request btcjson.Request
   275  		if err := json.Unmarshal(marshalled, &request); err != nil {
   276  			t.Errorf("Test #%d (%s) unexpected error while "+
   277  				"unmarshalling JSON-RPC request: %v", i,
   278  				test.name, err)
   279  			continue
   280  		}
   281  
   282  		cmd, err = btcjson.UnmarshalCmd(&request)
   283  		if err != nil {
   284  			t.Errorf("UnmarshalCmd #%d (%s) unexpected error: %v", i,
   285  				test.name, err)
   286  			continue
   287  		}
   288  
   289  		if !reflect.DeepEqual(cmd, test.unmarshalled) {
   290  			t.Errorf("Test #%d (%s) unexpected unmarshalled command "+
   291  				"- got %s, want %s", i, test.name,
   292  				fmt.Sprintf("(%T) %+[1]v", cmd),
   293  				fmt.Sprintf("(%T) %+[1]v\n", test.unmarshalled))
   294  			continue
   295  		}
   296  	}
   297  }