diff --git a/cmd/dcrctl/config.go b/cmd/dcrctl/config.go index e82ab770..986771d7 100644 --- a/cmd/dcrctl/config.go +++ b/cmd/dcrctl/config.go @@ -16,12 +16,12 @@ import ( "runtime" "strings" - "github.com/decred/dcrd/dcrjson/v2" + "github.com/decred/dcrd/dcrjson/v3" "github.com/decred/dcrd/dcrutil" "github.com/decred/dcrd/internal/version" - // Register wallet dcrjson types so they're available. - _ "github.com/decred/dcrwallet/rpc/jsonrpc/types" + dcrdtypes "github.com/decred/dcrd/rpc/jsonrpc/types" + wallettypes "github.com/decred/dcrwallet/rpc/jsonrpc/types" flags "github.com/jessevdk/go-flags" ) @@ -47,50 +47,56 @@ var ( // listCommands categorizes and lists all of the usable commands along with // their one-line usage. func listCommands() { - const ( - categoryChain uint8 = iota - categoryWallet - numCategories - ) + var categories = []struct { + Header string + Method interface{} + Usages []string + }{{ + Header: "Chain Server Commands:", + Method: dcrdtypes.Method(""), + }, { + Header: "Wallet Server Commands (--wallet):", + Method: wallettypes.Method(""), + }} - // Get a list of registered commands and categorize and filter them. - cmdMethods := dcrjson.RegisteredCmdMethods() - categorized := make([][]string, numCategories) - for _, method := range cmdMethods { - flags, err := dcrjson.MethodUsageFlags(method) - if err != nil { - // This should never happen since the method was just - // returned from the package, but be safe. - continue - } + for i := range categories { + method := categories[i].Method + methods := dcrjson.RegisteredMethods(method) + for _, methodStr := range methods { + switch method.(type) { + case dcrdtypes.Method: + method = dcrdtypes.Method(methodStr) + case wallettypes.Method: + method = wallettypes.Method(methodStr) + } - // Skip the commands that aren't usable from this utility. - if flags&unusableFlags != 0 { - continue - } + flags, err := dcrjson.MethodUsageFlags(method) + if err != nil { + // This should never happen since the method was just + // returned from the package, but be safe. + continue + } - usage, err := dcrjson.MethodUsageText(method) - if err != nil { - // This should never happen since the method was just - // returned from the package, but be safe. - continue - } + // Skip the commands that aren't usable from this utility. + if flags&unusableFlags != 0 { + continue + } - // Categorize the command based on the usage flags. - category := categoryChain - if flags&dcrjson.UFWalletOnly != 0 { - category = categoryWallet + usage, err := dcrjson.MethodUsageText(method) + if err != nil { + // This should never happen since the method was just + // returned from the package, but be safe. + continue + } + + categories[i].Usages = append(categories[i].Usages, usage) } - categorized[category] = append(categorized[category], usage) } // Display the command according to their categories. - categoryTitles := make([]string, numCategories) - categoryTitles[categoryChain] = "Chain Server Commands:" - categoryTitles[categoryWallet] = "Wallet Server Commands (--wallet):" - for category := uint8(0); category < numCategories; category++ { - fmt.Println(categoryTitles[category]) - for _, usage := range categorized[category] { + for i := range categories { + fmt.Println(categories[i].Header) + for _, usage := range categories[i].Usages { fmt.Println(usage) } fmt.Println() diff --git a/cmd/dcrctl/dcrctl.go b/cmd/dcrctl/dcrctl.go index e5a9e1ae..d426fb69 100644 --- a/cmd/dcrctl/dcrctl.go +++ b/cmd/dcrctl/dcrctl.go @@ -15,7 +15,9 @@ import ( "path/filepath" "strings" - "github.com/decred/dcrd/dcrjson/v2" + "github.com/decred/dcrd/dcrjson/v3" + dcrdtypes "github.com/decred/dcrd/rpc/jsonrpc/types" + wallettypes "github.com/decred/dcrwallet/rpc/jsonrpc/types" ) const ( @@ -24,7 +26,7 @@ const ( ) // commandUsage display the usage for a specific command. -func commandUsage(method string) { +func commandUsage(method interface{}) { usage, err := dcrjson.MethodUsageText(method) if err != nil { // This should never happen since the method was already checked @@ -64,10 +66,15 @@ func main() { // Ensure the specified method identifies a valid registered command and // is one of the usable types. - method := args[0] + methodStr := args[0] + var method interface{} = dcrdtypes.Method(methodStr) usageFlags, err := dcrjson.MethodUsageFlags(method) if err != nil { - fmt.Fprintf(os.Stderr, "Unrecognized command '%s'\n", method) + method = wallettypes.Method(methodStr) + usageFlags, err = dcrjson.MethodUsageFlags(method) + } + if err != nil { + fmt.Fprintf(os.Stderr, "Unrecognized command %q\n", methodStr) fmt.Fprintln(os.Stderr, listCmdMessage) os.Exit(1) } diff --git a/config.go b/config.go index ca990b50..49f887c2 100644 --- a/config.go +++ b/config.go @@ -25,10 +25,10 @@ import ( "github.com/decred/dcrd/connmgr" "github.com/decred/dcrd/database" _ "github.com/decred/dcrd/database/ffldb" - "github.com/decred/dcrd/dcrjson/v2" "github.com/decred/dcrd/dcrutil" "github.com/decred/dcrd/internal/version" "github.com/decred/dcrd/mempool/v2" + "github.com/decred/dcrd/rpc/jsonrpc/types" "github.com/decred/dcrd/sampleconfig" "github.com/decred/slog" flags "github.com/jessevdk/go-flags" @@ -177,9 +177,9 @@ type config struct { miningAddrs []dcrutil.Address minRelayTxFee dcrutil.Amount whitelists []*net.IPNet - ipv4NetInfo dcrjson.NetworksResult - ipv6NetInfo dcrjson.NetworksResult - onionNetInfo dcrjson.NetworksResult + ipv4NetInfo types.NetworksResult + ipv6NetInfo types.NetworksResult + onionNetInfo types.NetworksResult } // serviceOptions defines the configuration options for the daemon as a service on @@ -423,8 +423,8 @@ func createDefaultConfigFile(destPath string) error { // generateNetworkInfo is a convenience function that creates a slice from the // available networks. -func (cfg *config) generateNetworkInfo() []dcrjson.NetworksResult { - return []dcrjson.NetworksResult{cfg.ipv4NetInfo, cfg.ipv6NetInfo, +func (cfg *config) generateNetworkInfo() []types.NetworksResult { + return []types.NetworksResult{cfg.ipv4NetInfo, cfg.ipv6NetInfo, cfg.onionNetInfo} } @@ -512,9 +512,9 @@ func loadConfig() (*config, []string, error) { NoExistsAddrIndex: defaultNoExistsAddrIndex, NoCFilters: defaultNoCFilters, AltDNSNames: defaultAltDNSNames, - ipv4NetInfo: dcrjson.NetworksResult{Name: "IPV4"}, - ipv6NetInfo: dcrjson.NetworksResult{Name: "IPV6"}, - onionNetInfo: dcrjson.NetworksResult{Name: "Onion"}, + ipv4NetInfo: types.NetworksResult{Name: "IPV4"}, + ipv6NetInfo: types.NetworksResult{Name: "IPV6"}, + onionNetInfo: types.NetworksResult{Name: "Onion"}, } // Service options which are only added on Windows. diff --git a/dcrjson/cmdinfo.go b/dcrjson/cmdinfo.go index 71173b9f..b3c1dd1b 100644 --- a/dcrjson/cmdinfo.go +++ b/dcrjson/cmdinfo.go @@ -21,17 +21,17 @@ func CmdMethod(cmd interface{}) (string, error) { method, ok := concreteTypeToMethod[rt] registerLock.RUnlock() if !ok { - str := fmt.Sprintf("%q is not registered", method) + str := fmt.Sprintf("%T is not registered", cmd) return "", makeError(ErrUnregisteredMethod, str) } - return method, nil + return reflect.ValueOf(method).String(), nil } // MethodUsageFlags returns the usage flags for the passed command method. The // provided method must be associated with a registered type. All commands // provided by this package are registered by default. -func MethodUsageFlags(method string) (UsageFlag, error) { +func MethodUsageFlags(method interface{}) (UsageFlag, error) { // Look up details about the provided method and error out if not // registered. registerLock.RLock() @@ -178,7 +178,7 @@ func fieldUsage(structField reflect.StructField, defaultVal *reflect.Value) stri // methodUsageText returns a one-line usage string for the provided command and // method info. This is the main work horse for the exported MethodUsageText // function. -func methodUsageText(rtp reflect.Type, defaults map[int]reflect.Value, method string) string { +func methodUsageText(rtp reflect.Type, defaults map[int]reflect.Value, method interface{}) string { // Generate the individual usage for each field in the command. Several // simplifying assumptions are made here because the RegisterCmd // function has already rigorously enforced the layout. @@ -209,7 +209,7 @@ func methodUsageText(rtp reflect.Type, defaults map[int]reflect.Value, method st } // Generate and return the one-line usage string. - usageStr := method + usageStr := reflect.ValueOf(method).String() if len(reqFieldUsages) > 0 { usageStr += " " + strings.Join(reqFieldUsages, " ") } @@ -222,7 +222,7 @@ func methodUsageText(rtp reflect.Type, defaults map[int]reflect.Value, method st // MethodUsageText returns a one-line usage string for the provided method. The // provided method must be associated with a registered type. All commands // provided by this package are registered by default. -func MethodUsageText(method string) (string, error) { +func MethodUsageText(method interface{}) (string, error) { // Look up details about the provided method and error out if not // registered. registerLock.RLock() diff --git a/dcrjson/cmdinfo_test.go b/dcrjson/cmdinfo_test.go index 51c92daa..a3fc03f3 100644 --- a/dcrjson/cmdinfo_test.go +++ b/dcrjson/cmdinfo_test.go @@ -28,12 +28,12 @@ func TestCmdMethod(t *testing.T) { }, { name: "nil pointer of registered type", - cmd: (*GetBlockCmd)(nil), + cmd: (*testGetBlockCmd)(nil), method: "getblock", }, { - name: "nil instance of registered type", - cmd: &GetBlockCountCmd{}, + name: "zero instance of registered type", + cmd: &testGetBlockCountCmd{}, method: "getblockcount", }, } diff --git a/dcrjson/cmdparse.go b/dcrjson/cmdparse.go index 2f09d952..19c9320e 100644 --- a/dcrjson/cmdparse.go +++ b/dcrjson/cmdparse.go @@ -43,7 +43,7 @@ func MarshalCmd(rpcVersion string, id interface{}, cmd interface{}) ([]byte, err method, ok := concreteTypeToMethod[rt] registerLock.RUnlock() if !ok { - str := fmt.Sprintf("%q is not registered", method) + str := fmt.Sprintf("%T is not registered", cmd) return nil, makeError(ErrUnregisteredMethod, str) } @@ -60,7 +60,7 @@ func MarshalCmd(rpcVersion string, id interface{}, cmd interface{}) ([]byte, err params := makeParams(rt.Elem(), rv.Elem()) // Generate and marshal the final JSON-RPC request. - rawCmd, err := NewRequest(rpcVersion, id, method, params) + rawCmd, err := NewRequest(rpcVersion, id, reflect.ValueOf(method).String(), params) if err != nil { return nil, err } @@ -105,16 +105,15 @@ func populateDefaults(numParams int, info *methodInfo, rv reflect.Value) { } } -// UnmarshalCmd unmarshals a JSON-RPC request into a suitable concrete command -// so long as the method type contained within the marshalled request is -// registered. -func UnmarshalCmd(r *Request) (interface{}, error) { +// ParseParams unmarshals and parses the parameters for a JSON-RPC request based +// on the registered method. +func ParseParams(method interface{}, params []json.RawMessage) (interface{}, error) { registerLock.RLock() - rtp, ok := methodToConcreteType[r.Method] - info := methodToInfo[r.Method] + rtp, ok := methodToConcreteType[method] + info := methodToInfo[method] registerLock.RUnlock() if !ok { - str := fmt.Sprintf("%q is not registered", r.Method) + str := fmt.Sprintf("%q is not registered", method) return nil, makeError(ErrUnregisteredMethod, str) } rt := rtp.Elem() @@ -122,7 +121,7 @@ func UnmarshalCmd(r *Request) (interface{}, error) { rv := rvp.Elem() // Ensure the number of parameters are correct. - numParams := len(r.Params) + numParams := len(params) if err := checkNumParams(numParams, &info); err != nil { return nil, err } @@ -133,7 +132,7 @@ func UnmarshalCmd(r *Request) (interface{}, error) { rvf := rv.Field(i) // Unmarshal the parameter into the struct field. concreteVal := rvf.Addr().Interface() - if err := json.Unmarshal(r.Params[i], &concreteVal); err != nil { + if err := json.Unmarshal(params[i], &concreteVal); err != nil { // The most common error is the wrong type, so // explicitly detect that error and make it nicer. fieldName := strings.ToLower(rt.Field(i).Name) @@ -509,7 +508,7 @@ func assignField(paramNum int, fieldName string, dest reflect.Value, src reflect // - Conversion from string to arrays, slices, structs, and maps by treating // the string as marshalled JSON and calling json.Unmarshal into the // destination field -func NewCmd(method string, args ...interface{}) (interface{}, error) { +func NewCmd(method interface{}, args ...interface{}) (interface{}, error) { // Look up details about the provided method. Any methods that aren't // registered are an error. registerLock.RLock() diff --git a/dcrjson/cmdparse_test.go b/dcrjson/cmdparse_test.go index 8e163f97..cf8e0b2a 100644 --- a/dcrjson/cmdparse_test.go +++ b/dcrjson/cmdparse_test.go @@ -1,5 +1,5 @@ // Copyright (c) 2014 The btcsuite developers -// Copyright (c) 2015-2016 The Decred developers +// Copyright (c) 2015-2019 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -419,13 +419,13 @@ func TestMarshalCmdErrors(t *testing.T) { { name: "nil instance of registered type", id: 1, - cmd: (*GetBlockCmd)(nil), + cmd: (*testGetBlockCmd)(nil), err: Error{Code: ErrInvalidType}, }, { - name: "nil instance of registered type", + name: "zero instance of registered type", id: []int{0, 1}, - cmd: &GetBlockCountCmd{}, + cmd: &testGetBlockCountCmd{}, err: Error{Code: ErrInvalidType}, }, } @@ -448,60 +448,46 @@ func TestMarshalCmdErrors(t *testing.T) { } } -// TestUnmarshalCmdErrors tests the error paths of the UnmarshalCmd function. -func TestUnmarshalCmdErrors(t *testing.T) { +// TestParseParamsErrors tests the error paths of the ParseParams function. +func TestParseParamsErrors(t *testing.T) { t.Parallel() tests := []struct { name string + method string + params []json.RawMessage request Request err Error }{ { - name: "unregistered type", - request: Request{ - Jsonrpc: "1.0", - Method: "bogusmethod", - Params: nil, - ID: nil, - }, - err: Error{Code: ErrUnregisteredMethod}, + name: "unregistered type", + method: "bogusmethod", + params: nil, + err: Error{Code: ErrUnregisteredMethod}, }, { - name: "incorrect number of params", - request: Request{ - Jsonrpc: "1.0", - Method: "getblockcount", - Params: []json.RawMessage{[]byte(`"bogusparam"`)}, - ID: nil, - }, - err: Error{Code: ErrNumParams}, + name: "incorrect number of params", + method: "getblockcount", + params: []json.RawMessage{[]byte(`"bogusparam"`)}, + err: Error{Code: ErrNumParams}, }, { - name: "invalid type for a parameter", - request: Request{ - Jsonrpc: "1.0", - Method: "getblock", - Params: []json.RawMessage{[]byte("1")}, - ID: nil, - }, - err: Error{Code: ErrInvalidType}, + name: "invalid type for a parameter", + method: "getblock", + params: []json.RawMessage{[]byte("1")}, + err: Error{Code: ErrInvalidType}, }, { - name: "invalid JSON for a parameter", - request: Request{ - Jsonrpc: "1.0", - Method: "getblock", - Params: []json.RawMessage{[]byte(`"1`)}, - ID: nil, - }, - err: Error{Code: ErrInvalidType}, + name: "invalid JSON for a parameter", + method: "getblock", + params: []json.RawMessage{[]byte(`"1`)}, + err: Error{Code: ErrInvalidType}, }, } t.Logf("Running %d tests", len(tests)) for i, test := range tests { - _, err := UnmarshalCmd(&test.request) + _, err := ParseParams(test.method, test.params) if reflect.TypeOf(err) != reflect.TypeOf(test.err) { t.Errorf("Test #%d (%s) wrong error type - got `%T` (%v), want `%T`", i, test.name, err, err, test.err) diff --git a/dcrjson/doc.go b/dcrjson/doc.go index 0a61b322..41b8078f 100644 --- a/dcrjson/doc.go +++ b/dcrjson/doc.go @@ -1,19 +1,16 @@ // Copyright (c) 2015 The btcsuite developers -// Copyright (c) 2015-2016 The Decred developers +// Copyright (c) 2015-2019 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. /* -Package dcrjson provides primitives for working with the Decred JSON-RPC API. +Package dcrjson provides infrastructure for working with the Decred JSON-RPC APIs. Overview -When communicating via the JSON-RPC protocol, all of the commands need to be +When communicating via the JSON-RPC protocol, all requests and responses must be marshalled to and from the the wire in the appropriate format. This package -provides data structures and primitives to ease this process. - -In addition, it also provides some additional features such as custom command -registration, command categorization, and reflection-based help generation. +provides infrastructure and primitives to ease this process. JSON-RPC Protocol Overview @@ -37,7 +34,7 @@ method (a.k.a. command) being sent. Each parameter can be as simple as an int or a complex structure containing many nested fields. The id field is used to identify a request and will be included in the associated response. -When working with asynchronous transports, such as websockets, spontaneous +When working with streamed RPC transports, such as websockets, spontaneous notifications are also possible. As indicated, they are the same as a request object, except they have the id field set to null. Therefore, servers will ignore requests with the id field set to null, while clients can choose to @@ -50,24 +47,16 @@ for the most part, the error field will be set as described on failure. Marshalling and Unmarshalling -Based upon the discussion above, it should be easy to see how the types of this -package map into the required parts of the protocol - - - Request Objects (type Request) - - Commands (type Cmd) - - Notifications (type Ntfn) - - Response Objects (type Response) - - Result (type Result) - To simplify the marshalling of the requests and responses, the MarshalCmd and MarshalResponse functions are provided. They return the raw bytes ready to be sent across the wire. Unmarshalling a received Request object is a two step process: 1) Unmarshal the raw bytes into a Request struct instance via json.Unmarshal - 2) Use UnmarshalCmd on the Result field of the unmarshalled Request to create - a concrete command or notification instance with all struct fields set - accordingly + 2) Use ParseParams on the Method and Params fields of the unmarshalled Request + to create a concrete command or notification instance with all struct fields + set accordingly. The concrete types must have been registered for the method + by an external package This approach is used since it provides the caller with access to the additional fields in the request that are not part of the command such as the ID. @@ -82,18 +71,16 @@ fields in the response such as the ID and Error. Command Creation -This package provides two approaches for creating a new command. This first, -and preferred, method is to use one of the NewCmd functions. This allows -static compile-time checking to help ensure the parameters stay in sync with -the struct definitions. - -The second approach is the NewCmd function which takes a method (command) name +This package provides the NewCmd function which takes a method (command) name and variable arguments. The function includes full checking to ensure the parameters are accurate according to provided method, however these checks are, obviously, run-time which means any mistakes won't be found until the code is actually executed. However, it is quite useful for user-supplied commands that are intentionally dynamic. +External packages can and should implement types implementing Command for use +with MarshalCmd/ParseParams. + Custom Command Registration The command handling of this package is built around the concept of registered @@ -117,8 +104,7 @@ Help Generation To facilitate providing consistent help to users of the RPC server, this package exposes the GenerateHelp and function which uses reflection on registered -commands or notifications, as well as the provided expected result types, to -generate the final help text. +commands or notifications to generate the final help text. In addition, the MethodUsageText function is provided to generate consistent one-line usage for registered commands and notifications using reflection. diff --git a/dcrjson/example_test.go b/dcrjson/example_test.go index a390a88e..cebc9b80 100644 --- a/dcrjson/example_test.go +++ b/dcrjson/example_test.go @@ -1,5 +1,5 @@ // Copyright (c) 2014 The btcsuite developers -// Copyright (c) 2015-2016 The Decred developers +// Copyright (c) 2015-2019 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -19,8 +19,10 @@ func ExampleMarshalCmd() { // optional fields. Also, notice the call to Bool which is a // convenience function for creating a pointer out of a primitive for // optional parameters. + // + // testGetBlockCmd was registered at init by the test. blockHash := "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f" - gbCmd := NewGetBlockCmd(blockHash, Bool(false), nil) + gbCmd := &testGetBlockCmd{Hash: blockHash, Verbose: Bool(false), VerboseTx: nil} // Marshal the command to the format suitable for sending to the RPC // server. Typically the client would increment the id here which is @@ -41,8 +43,8 @@ func ExampleMarshalCmd() { } // This example demonstrates how to unmarshal a JSON-RPC request and then -// unmarshal the concrete request into a concrete command. -func ExampleUnmarshalCmd() { +// parse the parameters into a concrete type. +func ExampleParseParams() { // Ordinarily this would be read from the wire, but for this example, // it is hard coded here for clarity. data := []byte(`{"jsonrpc":"1.0","method":"getblock","params":["000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",false],"id":1}`) @@ -67,17 +69,17 @@ func ExampleUnmarshalCmd() { return } - // Unmarshal the request into a concrete command. - cmd, err := UnmarshalCmd(&request) + // Unmarshal the request into concrete params. + params, err := ParseParams(request.Method, request.Params) if err != nil { fmt.Println(err) return } - // Type assert the command to the appropriate type. - gbCmd, ok := cmd.(*GetBlockCmd) + // Type assert the params to the appropriate type. + gbCmd, ok := params.(*testGetBlockCmd) if !ok { - fmt.Printf("Incorrect command type: %T\n", cmd) + fmt.Printf("Incorrect params type: %T\n", params) return } diff --git a/dcrjson/go.mod b/dcrjson/go.mod index 675279bc..d52305d5 100644 --- a/dcrjson/go.mod +++ b/dcrjson/go.mod @@ -1,4 +1,4 @@ -module github.com/decred/dcrd/dcrjson/v2 +module github.com/decred/dcrd/dcrjson/v3 go 1.11 diff --git a/dcrjson/help.go b/dcrjson/help.go index 8dd50a17..a097aed2 100644 --- a/dcrjson/help.go +++ b/dcrjson/help.go @@ -503,7 +503,7 @@ func isValidResultType(kind reflect.Kind) bool { // "help--condition1": "command specified" // "help--result0": "List of commands" // "help--result1": "Help for specified command" -func GenerateHelp(method string, descs map[string]string, resultTypes ...interface{}) (string, error) { +func GenerateHelp(method interface{}, descs map[string]string, resultTypes ...interface{}) (string, error) { // Look up details about the provided method and error out if not // registered. registerLock.RLock() @@ -511,7 +511,7 @@ func GenerateHelp(method string, descs map[string]string, resultTypes ...interfa info := methodToInfo[method] registerLock.RUnlock() if !ok { - str := fmt.Sprintf("%q is not registered", method) + str := fmt.Sprintf("%#v is not registered", method) return "", makeError(ErrUnregisteredMethod, str) } @@ -553,7 +553,8 @@ func GenerateHelp(method string, descs map[string]string, resultTypes ...interfa } // Generate and return the help for the method. - help := methodHelp(xT, rtp, info.defaults, method, resultTypes) + methodStr := reflect.ValueOf(method).String() + help := methodHelp(xT, rtp, info.defaults, methodStr, resultTypes) if missingKey != "" { return help, makeError(ErrMissingDescription, missingKey) } diff --git a/dcrjson/helpers.go b/dcrjson/helpers.go index d16d5947..2a4a4e37 100644 --- a/dcrjson/helpers.go +++ b/dcrjson/helpers.go @@ -84,12 +84,3 @@ func String(v string) *string { *p = v return p } - -// EstimateSmartFeeModeAddr is a helper routine that allocates a new -// EstimateSmartFeeMode value to store v and returns a pointer to it. This is -// useful when assigning optional parameters. -func EstimateSmartFeeModeAddr(v EstimateSmartFeeMode) *EstimateSmartFeeMode { - p := new(EstimateSmartFeeMode) - *p = v - return p -} diff --git a/dcrjson/helpers_test.go b/dcrjson/helpers_test.go index 343f82cd..a6796fd9 100644 --- a/dcrjson/helpers_test.go +++ b/dcrjson/helpers_test.go @@ -100,16 +100,6 @@ func TestHelpers(t *testing.T) { return &val }(), }, - { - name: "estimatesmartfeemode", - f: func() interface{} { - return EstimateSmartFeeModeAddr("abc") - }, - expected: func() interface{} { - val := EstimateSmartFeeMode("abc") - return &val - }(), - }, } t.Logf("Running %d tests", len(tests)) diff --git a/dcrjson/register.go b/dcrjson/register.go index ab3a4892..ab2e0157 100644 --- a/dcrjson/register.go +++ b/dcrjson/register.go @@ -1,5 +1,5 @@ // Copyright (c) 2014 The btcsuite developers -// Copyright (c) 2015-2016 The Decred developers +// Copyright (c) 2015-2019 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -20,9 +20,7 @@ import ( type UsageFlag uint32 const ( - // UFWalletOnly indicates that the command can only be used with an RPC - // server that supports wallet commands. - UFWalletOnly UsageFlag = 1 << iota + _ UsageFlag = 1 << iota // unused, was UFWalletOnly // UFWebsocketOnly indicates that the command can only be used when // communicating with an RPC server over websockets. This typically @@ -42,13 +40,15 @@ const ( // Map of UsageFlag values back to their constant names for pretty printing. var usageFlagStrings = map[UsageFlag]string{ - UFWalletOnly: "UFWalletOnly", UFWebsocketOnly: "UFWebsocketOnly", UFNotification: "UFNotification", } // String returns the UsageFlag in human-readable form. func (fl UsageFlag) String() string { + // Mask off the deprecated WalletOnly bit + fl &^= 0x01 + // No flags are set. if fl == 0 { return "0x0" @@ -56,9 +56,9 @@ func (fl UsageFlag) String() string { // Add individual bit flags. s := "" - for flag := UFWalletOnly; flag < highestUsageFlagBit; flag <<= 1 { - if fl&flag == flag { - s += usageFlagStrings[flag] + "|" + for flag := UsageFlag(1); flag < highestUsageFlagBit; flag <<= 1 { + if name, ok := usageFlagStrings[fl&flag]; ok { + s += name + "|" fl -= flag } } @@ -86,9 +86,9 @@ type methodInfo struct { var ( // These fields are used to map the registered types to method names. registerLock sync.RWMutex - methodToConcreteType = make(map[string]reflect.Type) - methodToInfo = make(map[string]methodInfo) - concreteTypeToMethod = make(map[reflect.Type]string) + methodToConcreteType = make(map[interface{}]reflect.Type) + methodToInfo = make(map[interface{}]methodInfo) + concreteTypeToMethod = make(map[reflect.Type]interface{}) ) // baseKindString returns the base kind for a given reflect.Type after @@ -125,10 +125,10 @@ func isAcceptableKind(kind reflect.Kind) bool { return true } -// RegisterCmd registers a new command that will automatically marshal to and -// from JSON-RPC with full type checking and positional parameter support. It -// also accepts usage flags which identify the circumstances under which the -// command can be used. +// Register registers a method that will automatically marshal to and from +// JSON-RPC with full type checking and positional parameter support. It also +// accepts usage flags which identify the circumstances under which the command +// can be used. // // This package automatically registers all of the exported commands by default // using this function, however it is also exported so callers can easily @@ -137,8 +137,9 @@ func isAcceptableKind(kind reflect.Kind) bool { // The type format is very strict since it needs to be able to automatically // marshal to and from JSON-RPC 1.0. The following enumerates the requirements: // -// - The provided command must be a single pointer to a struct -// - All fields must be exported +// - The method must be a string or string type +// - The provided params must be a pointer to a struct +// - All parameter fields must be exported // - The order of the positional parameters in the marshalled JSON will be in // the same order as declared in the struct definition // - Struct embedding is not supported @@ -151,16 +152,29 @@ func isAcceptableKind(kind reflect.Kind) bool { // - A field that has a 'jsonrpcdefault' struct tag must be an optional field // (pointer) // +// Duplicate registrations with identical method and params types are allowed. +// All other duplicate registrations of a method will error. +// // NOTE: This function only needs to be able to examine the structure of the // passed struct, so it does not need to be an actual instance. Therefore, it // is recommended to simply pass a nil pointer cast to the appropriate type. // For example, (*FooCmd)(nil). -func RegisterCmd(method string, cmd interface{}, flags UsageFlag) error { +func Register(method interface{}, params interface{}, flags UsageFlag) error { registerLock.Lock() defer registerLock.Unlock() - if _, ok := methodToConcreteType[method]; ok { - str := fmt.Sprintf("method %q is already registered", method) + if reflect.ValueOf(method).Kind() != reflect.String { + str := fmt.Sprintf("method %q is not a string type", method) + return makeError(ErrInvalidType, str) + } + + rtp := reflect.TypeOf(params) + if paramsType, ok := methodToConcreteType[method]; ok { + if rtp == paramsType { + return nil + } + str := fmt.Sprintf("method %q is already registered for "+ + "type %T", method, paramsType) return makeError(ErrDuplicateMethod, str) } @@ -171,7 +185,6 @@ func RegisterCmd(method string, cmd interface{}, flags UsageFlag) error { return makeError(ErrInvalidUsageFlags, str) } - rtp := reflect.TypeOf(cmd) if rtp.Kind() != reflect.Ptr { str := fmt.Sprintf("type must be *struct not '%s (%s)'", rtp, rtp.Kind()) @@ -267,25 +280,29 @@ func RegisterCmd(method string, cmd interface{}, flags UsageFlag) error { return nil } -// MustRegisterCmd performs the same function as RegisterCmd except it panics -// if there is an error. This should only be called from package init -// functions. -func MustRegisterCmd(method string, cmd interface{}, flags UsageFlag) { - if err := RegisterCmd(method, cmd, flags); err != nil { - panic(fmt.Sprintf("failed to register type %q: %v\n", method, - err)) +// MustRegister performs the same function as Register except it panics if there +// is an error. This should only be called from package init functions. +// +// See Register for more details about correct usage. +func MustRegister(method interface{}, cmd interface{}, flags UsageFlag) { + if err := Register(method, cmd, flags); err != nil { + panic(err) } } -// RegisteredCmdMethods returns a sorted list of methods for all registered +// RegisteredMethods returns a sorted list of methods for all registered // commands. -func RegisteredCmdMethods() []string { +func RegisteredMethods(methodType interface{}) []string { registerLock.Lock() defer registerLock.Unlock() + typ := reflect.TypeOf(methodType) + methods := make([]string, 0, len(methodToInfo)) for k := range methodToInfo { - methods = append(methods, k) + if typ == reflect.TypeOf(k) { + methods = append(methods, reflect.ValueOf(k).String()) + } } sort.Strings(methods) diff --git a/dcrjson/register_test.go b/dcrjson/register_test.go index 57a5b2fb..5c2196e2 100644 --- a/dcrjson/register_test.go +++ b/dcrjson/register_test.go @@ -1,5 +1,5 @@ // Copyright (c) 2014 The btcsuite developers -// Copyright (c) 2015-2016 The Decred developers +// Copyright (c) 2015-2019 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -11,6 +11,27 @@ import ( "testing" ) +// Register methods for testing purposes. This does not conflict with +// registration performed by external packages as they are done in separate +// builds. +func init() { + MustRegister("getblock", (*testGetBlockCmd)(nil), 0) + MustRegister("getblockcount", (*testGetBlockCountCmd)(nil), 0) + MustRegister("session", (*testSessionCmd)(nil), UFWebsocketOnly) + MustRegister("help", (*testHelpCmd)(nil), 0) +} + +type testGetBlockCmd struct { + Hash string + Verbose *bool `jsonrpcdefault:"true"` + VerboseTx *bool `jsonrpcdefault:"false"` +} +type testGetBlockCountCmd struct{} +type testSessionCmd struct{} +type testHelpCmd struct { + Command *string +} + // TestUsageFlagStringer tests the stringized output for the UsageFlag type. func TestUsageFlagStringer(t *testing.T) { t.Parallel() @@ -20,12 +41,12 @@ func TestUsageFlagStringer(t *testing.T) { want string }{ {0, "0x0"}, - {UFWalletOnly, "UFWalletOnly"}, + {1, "0x0"}, // was UFWalletOnly {UFWebsocketOnly, "UFWebsocketOnly"}, {UFNotification, "UFNotification"}, - {UFWalletOnly | UFWebsocketOnly, "UFWalletOnly|UFWebsocketOnly"}, - {UFWalletOnly | UFWebsocketOnly | (1 << 31), - "UFWalletOnly|UFWebsocketOnly|0x80000000"}, + {UFWebsocketOnly | UFNotification, "UFWebsocketOnly|UFNotification"}, + {1 | UFWebsocketOnly | UFNotification | (1 << 31), + "UFWebsocketOnly|UFNotification|0x80000000"}, } // Detect additional usage flags that don't have the stringer added. @@ -206,8 +227,7 @@ func TestRegisterCmdErrors(t *testing.T) { t.Logf("Running %d tests", len(tests)) for i, test := range tests { - err := RegisterCmd(test.method, test.cmdFunc(), - test.flags) + err := Register(test.method, test.cmdFunc(), test.flags) if reflect.TypeOf(err) != reflect.TypeOf(test.err) { t.Errorf("Test #%d (%s) wrong error - got %T, "+ "want %T", i, test.name, err, test.err) @@ -237,7 +257,7 @@ func TestMustRegisterCmdPanic(t *testing.T) { }() // Intentionally try to register an invalid type to force a panic. - MustRegisterCmd("panicme", 0, 0) + MustRegister("panicme", 0, 0) } // TestRegisteredCmdMethods tests the RegisteredCmdMethods function ensure it @@ -245,8 +265,8 @@ func TestMustRegisterCmdPanic(t *testing.T) { func TestRegisteredCmdMethods(t *testing.T) { t.Parallel() - // Ensure the registered methods are returned. - methods := RegisteredCmdMethods() + // Ensure the registered methods for plain string methods are returned. + methods := RegisteredMethods("") if len(methods) == 0 { t.Fatal("RegisteredCmdMethods: no methods") } diff --git a/go.mod b/go.mod index cd61c438..a853624f 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,8 @@ require ( github.com/decred/dcrd/database v1.1.0 github.com/decred/dcrd/dcrec v1.0.0 github.com/decred/dcrd/dcrec/secp256k1 v1.0.2 - github.com/decred/dcrd/dcrjson/v2 v2.0.0 + github.com/decred/dcrd/dcrjson/v2 v2.2.0 + github.com/decred/dcrd/dcrjson/v3 v3.0.0 github.com/decred/dcrd/dcrutil v1.3.0 github.com/decred/dcrd/fees v1.0.0 github.com/decred/dcrd/gcs v1.0.2 @@ -25,10 +26,11 @@ require ( github.com/decred/dcrd/mempool/v2 v2.0.0 github.com/decred/dcrd/mining v1.1.0 github.com/decred/dcrd/peer v1.1.0 + github.com/decred/dcrd/rpc/jsonrpc/types v0.0.0 github.com/decred/dcrd/rpcclient/v2 v2.0.0 github.com/decred/dcrd/txscript v1.1.0 github.com/decred/dcrd/wire v1.2.0 - github.com/decred/dcrwallet/rpc/jsonrpc/types v1.0.0 + github.com/decred/dcrwallet/rpc/jsonrpc/types v1.1.0 github.com/decred/slog v1.0.0 github.com/gorilla/websocket v1.4.0 github.com/jessevdk/go-flags v1.4.0 @@ -47,7 +49,7 @@ replace ( github.com/decred/dcrd/connmgr => ./connmgr github.com/decred/dcrd/database => ./database github.com/decred/dcrd/dcrec => ./dcrec - github.com/decred/dcrd/dcrjson/v2 => ./dcrjson + github.com/decred/dcrd/dcrjson/v3 => ./dcrjson github.com/decred/dcrd/dcrutil/v2 => ./dcrutil github.com/decred/dcrd/fees => ./fees github.com/decred/dcrd/gcs => ./gcs @@ -57,7 +59,12 @@ replace ( github.com/decred/dcrd/mempool/v2 => ./mempool github.com/decred/dcrd/mining => ./mining github.com/decred/dcrd/peer => ./peer + github.com/decred/dcrd/rpc/jsonrpc/types => ./rpc/jsonrpc/types github.com/decred/dcrd/rpcclient/v2 => ./rpcclient github.com/decred/dcrd/txscript/v2 => ./txscript github.com/decred/dcrd/wire => ./wire ) + +replace github.com/decred/dcrd/dcrjson/v2 v2.2.0 => github.com/jrick/btcd/dcrjson/v2 v2.0.0-20190715200557-9fffa6c80ab0 + +replace github.com/decred/dcrwallet/rpc/jsonrpc/types v1.1.0 => github.com/jrick/btcwallet/rpc/jsonrpc/types v0.0.0-20190715193601-785bca9161e7 diff --git a/go.sum b/go.sum index 92cf6457..107aeee7 100644 --- a/go.sum +++ b/go.sum @@ -32,6 +32,10 @@ github.com/decred/dcrd/dcrec/secp256k1 v1.0.0/go.mod h1:JPMFscGlgXTV684jxQNDijae github.com/decred/dcrd/dcrec/secp256k1 v1.0.1/go.mod h1:lhu4eZFSfTJWUnR3CFRcpD+Vta0KUAqnhTsTksHXgy0= github.com/decred/dcrd/dcrec/secp256k1 v1.0.2 h1:awk7sYJ4pGWmtkiGHFfctztJjHMKGLV8jctGQhAbKe0= github.com/decred/dcrd/dcrec/secp256k1 v1.0.2/go.mod h1:CHTUIVfmDDd0KFVFpNX1pFVCBUegxW387nN0IGwNKR0= +github.com/decred/dcrd/dcrjson/v2 v2.0.0 h1:W0q4Alh36c5N318eUpfmU8kXoCNgImMLI87NIXni9Us= +github.com/decred/dcrd/dcrjson/v2 v2.0.0/go.mod h1:FYueNy8BREAFq04YNEwcTsmGFcNqY+ehUUO81w2igi4= +github.com/decred/dcrd/dcrjson/v2 v2.1.0-0.20190709184057-e4f5e3f84f39 h1:gRp7NXypQMNiK8MX4rxEgB7jWXZrpE9R3tqNYGoLeM0= +github.com/decred/dcrd/dcrjson/v2 v2.1.0-0.20190709184057-e4f5e3f84f39/go.mod h1:x4dY9EiT+awLvXz4wNzGlVtzR9EXYkZglXlrnDoLI6g= github.com/decred/dcrd/dcrutil v1.1.1/go.mod h1:Jsttr0pEvzPAw+qay1kS1/PsbZYPyhluiNwwY6yBJS4= github.com/decred/dcrd/dcrutil v1.2.0/go.mod h1:tUNHS2gj7ApeEVS8gb6O+4wJW7w3O2MSRyRdcjW1JxU= github.com/decred/dcrd/dcrutil v1.3.0 h1:LtKIiDnq925yJT/4OpIKKiU9/WaxfD9LfhxrpLSi0Qs= @@ -56,6 +60,12 @@ github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGAR github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jrick/bitset v1.0.0 h1:Ws0PXV3PwXqWK2n7Vz6idCdrV/9OrBXgHEJi27ZB9Dw= github.com/jrick/bitset v1.0.0/go.mod h1:ZOYB5Uvkla7wIEY4FEssPVi3IQXa02arznRaYaAEPe4= +github.com/jrick/btcd/dcrjson/v2 v2.0.0-20190712210503-292c1e5e80ac h1:2vTh3IBLNrz5hsSpL8ADkxaIRSU8UW64wqUC0wmADtc= +github.com/jrick/btcd/dcrjson/v2 v2.0.0-20190712210503-292c1e5e80ac/go.mod h1:JwKNPWI2B+oMTtj4zv5ale8682i99PF+ETEydAGdQIg= +github.com/jrick/btcd/dcrjson/v2 v2.0.0-20190715200557-9fffa6c80ab0 h1:wgwsgxMRl8Z3MohHq+RxTxsZI8S3qHdJq88tZkX9Rv8= +github.com/jrick/btcd/dcrjson/v2 v2.0.0-20190715200557-9fffa6c80ab0/go.mod h1:JwKNPWI2B+oMTtj4zv5ale8682i99PF+ETEydAGdQIg= +github.com/jrick/btcwallet/rpc/jsonrpc/types v0.0.0-20190715193601-785bca9161e7 h1:mzBwESVcoOOQRdj+redewvo14ZY8o7FndeaNvMjYqss= +github.com/jrick/btcwallet/rpc/jsonrpc/types v0.0.0-20190715193601-785bca9161e7/go.mod h1:3sSyqYX80jbLe3O/o3VgxHR82Up8lRLvhhbWZ26wCos= github.com/jrick/logrotate v1.0.0 h1:lQ1bL/n9mBNeIXoTUoYRlK4dHuNJVofX9oWqBtPnSzI= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= diff --git a/dcrjson/chainsvrcmds.go b/rpc/jsonrpc/types/chainsvrcmds.go similarity index 83% rename from dcrjson/chainsvrcmds.go rename to rpc/jsonrpc/types/chainsvrcmds.go index 28c69b6c..62611275 100644 --- a/dcrjson/chainsvrcmds.go +++ b/rpc/jsonrpc/types/chainsvrcmds.go @@ -6,11 +6,13 @@ // NOTE: This file is intended to house the RPC commands that are supported by // a chain server. -package dcrjson +package types import ( "encoding/json" "fmt" + + "github.com/decred/dcrd/dcrjson/v3" ) // AddNodeSubCmd defines the type used in the addnode JSON-RPC command for the @@ -268,27 +270,27 @@ func NewExistsAddressesCmd(addresses []string) *ExistsAddressesCmd { // ExistsMissedTicketsCmd defines the existsmissedtickets JSON-RPC command. type ExistsMissedTicketsCmd struct { - TxHashBlob string + TxHashes []string } // NewExistsMissedTicketsCmd returns a new instance which can be used to issue an // existsmissedtickets JSON-RPC command. -func NewExistsMissedTicketsCmd(txHashBlob string) *ExistsMissedTicketsCmd { +func NewExistsMissedTicketsCmd(txHashes []string) *ExistsMissedTicketsCmd { return &ExistsMissedTicketsCmd{ - TxHashBlob: txHashBlob, + TxHashes: txHashes, } } // ExistsExpiredTicketsCmd defines the existsexpiredtickets JSON-RPC command. type ExistsExpiredTicketsCmd struct { - TxHashBlob string + TxHashes []string } // NewExistsExpiredTicketsCmd returns a new instance which can be used to issue an // existsexpiredtickets JSON-RPC command. -func NewExistsExpiredTicketsCmd(txHashBlob string) *ExistsExpiredTicketsCmd { +func NewExistsExpiredTicketsCmd(txHashes []string) *ExistsExpiredTicketsCmd { return &ExistsExpiredTicketsCmd{ - TxHashBlob: txHashBlob, + TxHashes: txHashes, } } @@ -307,27 +309,27 @@ func NewExistsLiveTicketCmd(txHash string) *ExistsLiveTicketCmd { // ExistsLiveTicketsCmd defines the existslivetickets JSON-RPC command. type ExistsLiveTicketsCmd struct { - TxHashBlob string + TxHashes []string } // NewExistsLiveTicketsCmd returns a new instance which can be used to issue an // existslivetickets JSON-RPC command. -func NewExistsLiveTicketsCmd(txHashBlob string) *ExistsLiveTicketsCmd { +func NewExistsLiveTicketsCmd(txHashes []string) *ExistsLiveTicketsCmd { return &ExistsLiveTicketsCmd{ - TxHashBlob: txHashBlob, + TxHashes: txHashes, } } // ExistsMempoolTxsCmd defines the existsmempooltxs JSON-RPC command. type ExistsMempoolTxsCmd struct { - TxHashBlob string + TxHashes []string } // NewExistsMempoolTxsCmd returns a new instance which can be used to issue an // existslivetickets JSON-RPC command. -func NewExistsMempoolTxsCmd(txHashBlob string) *ExistsMempoolTxsCmd { +func NewExistsMempoolTxsCmd(txHashes []string) *ExistsMempoolTxsCmd { return &ExistsMempoolTxsCmd{ - TxHashBlob: txHashBlob, + TxHashes: txHashes, } } @@ -502,7 +504,7 @@ func convertTemplateRequestField(fieldName string, iface interface{}) (interface str := fmt.Sprintf("the %s field must be unspecified, a boolean, or "+ "a 64-bit integer", fieldName) - return nil, makeError(ErrInvalidType, str) + return nil, dcrjson.Error{Code: dcrjson.ErrInvalidType, Message: str} } // UnmarshalJSON provides a custom Unmarshal method for TemplateRequest. This @@ -653,13 +655,13 @@ func NewGetInfoCmd() *GetInfoCmd { // GetHeadersCmd defines the getheaders JSON-RPC command. type GetHeadersCmd struct { - BlockLocators string `json:"blocklocators"` - HashStop string `json:"hashstop"` + BlockLocators []string `json:"blocklocators"` + HashStop string `json:"hashstop"` } // NewGetHeadersCmd returns a new instance which can be used to issue a // getheaders JSON-RPC command. -func NewGetHeadersCmd(blockLocators string, hashStop string) *GetHeadersCmd { +func NewGetHeadersCmd(blockLocators []string, hashStop string) *GetHeadersCmd { return &GetHeadersCmd{ BlockLocators: blockLocators, HashStop: hashStop, @@ -1195,81 +1197,81 @@ func NewVersionCmd() *VersionCmd { return new(VersionCmd) } func init() { // No special flags for commands in this file. - flags := UsageFlag(0) + flags := dcrjson.UsageFlag(0) - MustRegisterCmd("addnode", (*AddNodeCmd)(nil), flags) - MustRegisterCmd("createrawssrtx", (*CreateRawSSRtxCmd)(nil), flags) - MustRegisterCmd("createrawsstx", (*CreateRawSStxCmd)(nil), flags) - MustRegisterCmd("createrawtransaction", (*CreateRawTransactionCmd)(nil), flags) - MustRegisterCmd("debuglevel", (*DebugLevelCmd)(nil), flags) - MustRegisterCmd("decoderawtransaction", (*DecodeRawTransactionCmd)(nil), flags) - MustRegisterCmd("decodescript", (*DecodeScriptCmd)(nil), flags) - MustRegisterCmd("estimatefee", (*EstimateFeeCmd)(nil), flags) - MustRegisterCmd("estimatesmartfee", (*EstimateSmartFeeCmd)(nil), flags) - MustRegisterCmd("estimatestakediff", (*EstimateStakeDiffCmd)(nil), flags) - MustRegisterCmd("existsaddress", (*ExistsAddressCmd)(nil), flags) - MustRegisterCmd("existsaddresses", (*ExistsAddressesCmd)(nil), flags) - MustRegisterCmd("existsmissedtickets", (*ExistsMissedTicketsCmd)(nil), flags) - MustRegisterCmd("existsexpiredtickets", (*ExistsExpiredTicketsCmd)(nil), flags) - MustRegisterCmd("existsliveticket", (*ExistsLiveTicketCmd)(nil), flags) - MustRegisterCmd("existslivetickets", (*ExistsLiveTicketsCmd)(nil), flags) - MustRegisterCmd("existsmempooltxs", (*ExistsMempoolTxsCmd)(nil), flags) - MustRegisterCmd("generate", (*GenerateCmd)(nil), flags) - MustRegisterCmd("getaddednodeinfo", (*GetAddedNodeInfoCmd)(nil), flags) - MustRegisterCmd("getbestblock", (*GetBestBlockCmd)(nil), flags) - MustRegisterCmd("getbestblockhash", (*GetBestBlockHashCmd)(nil), flags) - MustRegisterCmd("getblock", (*GetBlockCmd)(nil), flags) - MustRegisterCmd("getblockchaininfo", (*GetBlockChainInfoCmd)(nil), flags) - MustRegisterCmd("getblockcount", (*GetBlockCountCmd)(nil), flags) - MustRegisterCmd("getblockhash", (*GetBlockHashCmd)(nil), flags) - MustRegisterCmd("getblockheader", (*GetBlockHeaderCmd)(nil), flags) - MustRegisterCmd("getblocksubsidy", (*GetBlockSubsidyCmd)(nil), flags) - MustRegisterCmd("getblocktemplate", (*GetBlockTemplateCmd)(nil), flags) - MustRegisterCmd("getcfilter", (*GetCFilterCmd)(nil), flags) - MustRegisterCmd("getcfilterheader", (*GetCFilterHeaderCmd)(nil), flags) - MustRegisterCmd("getchaintips", (*GetChainTipsCmd)(nil), flags) - MustRegisterCmd("getcoinsupply", (*GetCoinSupplyCmd)(nil), flags) - MustRegisterCmd("getconnectioncount", (*GetConnectionCountCmd)(nil), flags) - MustRegisterCmd("getcurrentnet", (*GetCurrentNetCmd)(nil), flags) - MustRegisterCmd("getdifficulty", (*GetDifficultyCmd)(nil), flags) - MustRegisterCmd("getgenerate", (*GetGenerateCmd)(nil), flags) - MustRegisterCmd("gethashespersec", (*GetHashesPerSecCmd)(nil), flags) - MustRegisterCmd("getheaders", (*GetHeadersCmd)(nil), flags) - MustRegisterCmd("getinfo", (*GetInfoCmd)(nil), flags) - MustRegisterCmd("getmempoolinfo", (*GetMempoolInfoCmd)(nil), flags) - MustRegisterCmd("getmininginfo", (*GetMiningInfoCmd)(nil), flags) - MustRegisterCmd("getnetworkinfo", (*GetNetworkInfoCmd)(nil), flags) - MustRegisterCmd("getnettotals", (*GetNetTotalsCmd)(nil), flags) - MustRegisterCmd("getnetworkhashps", (*GetNetworkHashPSCmd)(nil), flags) - MustRegisterCmd("getpeerinfo", (*GetPeerInfoCmd)(nil), flags) - MustRegisterCmd("getrawmempool", (*GetRawMempoolCmd)(nil), flags) - MustRegisterCmd("getrawtransaction", (*GetRawTransactionCmd)(nil), flags) - MustRegisterCmd("getstakedifficulty", (*GetStakeDifficultyCmd)(nil), flags) - MustRegisterCmd("getstakeversioninfo", (*GetStakeVersionInfoCmd)(nil), flags) - MustRegisterCmd("getstakeversions", (*GetStakeVersionsCmd)(nil), flags) - MustRegisterCmd("getticketpoolvalue", (*GetTicketPoolValueCmd)(nil), flags) - MustRegisterCmd("gettxout", (*GetTxOutCmd)(nil), flags) - MustRegisterCmd("gettxoutsetinfo", (*GetTxOutSetInfoCmd)(nil), flags) - MustRegisterCmd("getvoteinfo", (*GetVoteInfoCmd)(nil), flags) - MustRegisterCmd("getwork", (*GetWorkCmd)(nil), flags) - MustRegisterCmd("help", (*HelpCmd)(nil), flags) - MustRegisterCmd("livetickets", (*LiveTicketsCmd)(nil), flags) - MustRegisterCmd("missedtickets", (*MissedTicketsCmd)(nil), flags) - MustRegisterCmd("node", (*NodeCmd)(nil), flags) - MustRegisterCmd("ping", (*PingCmd)(nil), flags) - MustRegisterCmd("rebroadcastmissed", (*RebroadcastMissedCmd)(nil), flags) - MustRegisterCmd("rebroadcastwinners", (*RebroadcastWinnersCmd)(nil), flags) - MustRegisterCmd("searchrawtransactions", (*SearchRawTransactionsCmd)(nil), flags) - MustRegisterCmd("sendrawtransaction", (*SendRawTransactionCmd)(nil), flags) - MustRegisterCmd("setgenerate", (*SetGenerateCmd)(nil), flags) - MustRegisterCmd("stop", (*StopCmd)(nil), flags) - MustRegisterCmd("submitblock", (*SubmitBlockCmd)(nil), flags) - MustRegisterCmd("ticketfeeinfo", (*TicketFeeInfoCmd)(nil), flags) - MustRegisterCmd("ticketsforaddress", (*TicketsForAddressCmd)(nil), flags) - MustRegisterCmd("ticketvwap", (*TicketVWAPCmd)(nil), flags) - MustRegisterCmd("txfeeinfo", (*TxFeeInfoCmd)(nil), flags) - MustRegisterCmd("validateaddress", (*ValidateAddressCmd)(nil), flags) - MustRegisterCmd("verifychain", (*VerifyChainCmd)(nil), flags) - MustRegisterCmd("verifymessage", (*VerifyMessageCmd)(nil), flags) - MustRegisterCmd("version", (*VersionCmd)(nil), flags) + dcrjson.MustRegister(Method("addnode"), (*AddNodeCmd)(nil), flags) + dcrjson.MustRegister(Method("createrawssrtx"), (*CreateRawSSRtxCmd)(nil), flags) + dcrjson.MustRegister(Method("createrawsstx"), (*CreateRawSStxCmd)(nil), flags) + dcrjson.MustRegister(Method("createrawtransaction"), (*CreateRawTransactionCmd)(nil), flags) + dcrjson.MustRegister(Method("debuglevel"), (*DebugLevelCmd)(nil), flags) + dcrjson.MustRegister(Method("decoderawtransaction"), (*DecodeRawTransactionCmd)(nil), flags) + dcrjson.MustRegister(Method("decodescript"), (*DecodeScriptCmd)(nil), flags) + dcrjson.MustRegister(Method("estimatefee"), (*EstimateFeeCmd)(nil), flags) + dcrjson.MustRegister(Method("estimatesmartfee"), (*EstimateSmartFeeCmd)(nil), flags) + dcrjson.MustRegister(Method("estimatestakediff"), (*EstimateStakeDiffCmd)(nil), flags) + dcrjson.MustRegister(Method("existsaddress"), (*ExistsAddressCmd)(nil), flags) + dcrjson.MustRegister(Method("existsaddresses"), (*ExistsAddressesCmd)(nil), flags) + dcrjson.MustRegister(Method("existsmissedtickets"), (*ExistsMissedTicketsCmd)(nil), flags) + dcrjson.MustRegister(Method("existsexpiredtickets"), (*ExistsExpiredTicketsCmd)(nil), flags) + dcrjson.MustRegister(Method("existsliveticket"), (*ExistsLiveTicketCmd)(nil), flags) + dcrjson.MustRegister(Method("existslivetickets"), (*ExistsLiveTicketsCmd)(nil), flags) + dcrjson.MustRegister(Method("existsmempooltxs"), (*ExistsMempoolTxsCmd)(nil), flags) + dcrjson.MustRegister(Method("generate"), (*GenerateCmd)(nil), flags) + dcrjson.MustRegister(Method("getaddednodeinfo"), (*GetAddedNodeInfoCmd)(nil), flags) + dcrjson.MustRegister(Method("getbestblock"), (*GetBestBlockCmd)(nil), flags) + dcrjson.MustRegister(Method("getbestblockhash"), (*GetBestBlockHashCmd)(nil), flags) + dcrjson.MustRegister(Method("getblock"), (*GetBlockCmd)(nil), flags) + dcrjson.MustRegister(Method("getblockchaininfo"), (*GetBlockChainInfoCmd)(nil), flags) + dcrjson.MustRegister(Method("getblockcount"), (*GetBlockCountCmd)(nil), flags) + dcrjson.MustRegister(Method("getblockhash"), (*GetBlockHashCmd)(nil), flags) + dcrjson.MustRegister(Method("getblockheader"), (*GetBlockHeaderCmd)(nil), flags) + dcrjson.MustRegister(Method("getblocksubsidy"), (*GetBlockSubsidyCmd)(nil), flags) + dcrjson.MustRegister(Method("getblocktemplate"), (*GetBlockTemplateCmd)(nil), flags) + dcrjson.MustRegister(Method("getcfilter"), (*GetCFilterCmd)(nil), flags) + dcrjson.MustRegister(Method("getcfilterheader"), (*GetCFilterHeaderCmd)(nil), flags) + dcrjson.MustRegister(Method("getchaintips"), (*GetChainTipsCmd)(nil), flags) + dcrjson.MustRegister(Method("getcoinsupply"), (*GetCoinSupplyCmd)(nil), flags) + dcrjson.MustRegister(Method("getconnectioncount"), (*GetConnectionCountCmd)(nil), flags) + dcrjson.MustRegister(Method("getcurrentnet"), (*GetCurrentNetCmd)(nil), flags) + dcrjson.MustRegister(Method("getdifficulty"), (*GetDifficultyCmd)(nil), flags) + dcrjson.MustRegister(Method("getgenerate"), (*GetGenerateCmd)(nil), flags) + dcrjson.MustRegister(Method("gethashespersec"), (*GetHashesPerSecCmd)(nil), flags) + dcrjson.MustRegister(Method("getheaders"), (*GetHeadersCmd)(nil), flags) + dcrjson.MustRegister(Method("getinfo"), (*GetInfoCmd)(nil), flags) + dcrjson.MustRegister(Method("getmempoolinfo"), (*GetMempoolInfoCmd)(nil), flags) + dcrjson.MustRegister(Method("getmininginfo"), (*GetMiningInfoCmd)(nil), flags) + dcrjson.MustRegister(Method("getnetworkinfo"), (*GetNetworkInfoCmd)(nil), flags) + dcrjson.MustRegister(Method("getnettotals"), (*GetNetTotalsCmd)(nil), flags) + dcrjson.MustRegister(Method("getnetworkhashps"), (*GetNetworkHashPSCmd)(nil), flags) + dcrjson.MustRegister(Method("getpeerinfo"), (*GetPeerInfoCmd)(nil), flags) + dcrjson.MustRegister(Method("getrawmempool"), (*GetRawMempoolCmd)(nil), flags) + dcrjson.MustRegister(Method("getrawtransaction"), (*GetRawTransactionCmd)(nil), flags) + dcrjson.MustRegister(Method("getstakedifficulty"), (*GetStakeDifficultyCmd)(nil), flags) + dcrjson.MustRegister(Method("getstakeversioninfo"), (*GetStakeVersionInfoCmd)(nil), flags) + dcrjson.MustRegister(Method("getstakeversions"), (*GetStakeVersionsCmd)(nil), flags) + dcrjson.MustRegister(Method("getticketpoolvalue"), (*GetTicketPoolValueCmd)(nil), flags) + dcrjson.MustRegister(Method("gettxout"), (*GetTxOutCmd)(nil), flags) + dcrjson.MustRegister(Method("gettxoutsetinfo"), (*GetTxOutSetInfoCmd)(nil), flags) + dcrjson.MustRegister(Method("getvoteinfo"), (*GetVoteInfoCmd)(nil), flags) + dcrjson.MustRegister(Method("getwork"), (*GetWorkCmd)(nil), flags) + dcrjson.MustRegister(Method("help"), (*HelpCmd)(nil), flags) + dcrjson.MustRegister(Method("livetickets"), (*LiveTicketsCmd)(nil), flags) + dcrjson.MustRegister(Method("missedtickets"), (*MissedTicketsCmd)(nil), flags) + dcrjson.MustRegister(Method("node"), (*NodeCmd)(nil), flags) + dcrjson.MustRegister(Method("ping"), (*PingCmd)(nil), flags) + dcrjson.MustRegister(Method("rebroadcastmissed"), (*RebroadcastMissedCmd)(nil), flags) + dcrjson.MustRegister(Method("rebroadcastwinners"), (*RebroadcastWinnersCmd)(nil), flags) + dcrjson.MustRegister(Method("searchrawtransactions"), (*SearchRawTransactionsCmd)(nil), flags) + dcrjson.MustRegister(Method("sendrawtransaction"), (*SendRawTransactionCmd)(nil), flags) + dcrjson.MustRegister(Method("setgenerate"), (*SetGenerateCmd)(nil), flags) + dcrjson.MustRegister(Method("stop"), (*StopCmd)(nil), flags) + dcrjson.MustRegister(Method("submitblock"), (*SubmitBlockCmd)(nil), flags) + dcrjson.MustRegister(Method("ticketfeeinfo"), (*TicketFeeInfoCmd)(nil), flags) + dcrjson.MustRegister(Method("ticketsforaddress"), (*TicketsForAddressCmd)(nil), flags) + dcrjson.MustRegister(Method("ticketvwap"), (*TicketVWAPCmd)(nil), flags) + dcrjson.MustRegister(Method("txfeeinfo"), (*TxFeeInfoCmd)(nil), flags) + dcrjson.MustRegister(Method("validateaddress"), (*ValidateAddressCmd)(nil), flags) + dcrjson.MustRegister(Method("verifychain"), (*VerifyChainCmd)(nil), flags) + dcrjson.MustRegister(Method("verifymessage"), (*VerifyMessageCmd)(nil), flags) + dcrjson.MustRegister(Method("version"), (*VersionCmd)(nil), flags) } diff --git a/dcrjson/chainsvrcmds_test.go b/rpc/jsonrpc/types/chainsvrcmds_test.go similarity index 75% rename from dcrjson/chainsvrcmds_test.go rename to rpc/jsonrpc/types/chainsvrcmds_test.go index b2b375b2..725f25b7 100644 --- a/dcrjson/chainsvrcmds_test.go +++ b/rpc/jsonrpc/types/chainsvrcmds_test.go @@ -3,7 +3,7 @@ // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. -package dcrjson +package types import ( "bytes" @@ -11,6 +11,8 @@ import ( "fmt" "reflect" "testing" + + "github.com/decred/dcrd/dcrjson/v3" ) // TestChainSvrCmds tests all of the chain server commands marshal and unmarshal @@ -31,7 +33,7 @@ func TestChainSvrCmds(t *testing.T) { { name: "addnode", newCmd: func() (interface{}, error) { - return NewCmd("addnode", "127.0.0.1", ANRemove) + return dcrjson.NewCmd(Method("addnode"), "127.0.0.1", ANRemove) }, staticCmd: func() interface{} { return NewAddNodeCmd("127.0.0.1", ANRemove) @@ -42,8 +44,9 @@ func TestChainSvrCmds(t *testing.T) { { name: "createrawtransaction", newCmd: func() (interface{}, error) { - return NewCmd("createrawtransaction", `[{"amount":0.0123,"txid":"123","vout":1}]`, + return dcrjson.NewCmd(Method("createrawtransaction"), `[{"amount":0.0123,"txid":"123","vout":1}]`, `{"456":0.0123}`) + }, staticCmd: func() interface{} { txInputs := []TransactionInput{ @@ -61,28 +64,29 @@ func TestChainSvrCmds(t *testing.T) { { name: "createrawtransaction optional", newCmd: func() (interface{}, error) { - return NewCmd("createrawtransaction", `[{"amount":0.0123,"txid":"123","vout":1,"tree":0}]`, + return dcrjson.NewCmd(Method("createrawtransaction"), `[{"amount":0.0123,"txid":"123","vout":1,"tree":0}]`, `{"456":0.0123}`, int64(12312333333), int64(12312333333)) + }, staticCmd: func() interface{} { txInputs := []TransactionInput{ {Amount: 0.0123, Txid: "123", Vout: 1}, } amounts := map[string]float64{"456": .0123} - return NewCreateRawTransactionCmd(txInputs, amounts, Int64(12312333333), Int64(12312333333)) + return NewCreateRawTransactionCmd(txInputs, amounts, dcrjson.Int64(12312333333), dcrjson.Int64(12312333333)) }, marshalled: `{"jsonrpc":"1.0","method":"createrawtransaction","params":[[{"amount":0.0123,"txid":"123","vout":1,"tree":0}],{"456":0.0123},12312333333,12312333333],"id":1}`, unmarshalled: &CreateRawTransactionCmd{ Inputs: []TransactionInput{{Amount: 0.0123, Txid: "123", Vout: 1}}, Amounts: map[string]float64{"456": .0123}, - LockTime: Int64(12312333333), - Expiry: Int64(12312333333), + LockTime: dcrjson.Int64(12312333333), + Expiry: dcrjson.Int64(12312333333), }, }, { name: "debuglevel", newCmd: func() (interface{}, error) { - return NewCmd("debuglevel", "trace") + return dcrjson.NewCmd(Method("debuglevel"), "trace") }, staticCmd: func() interface{} { return NewDebugLevelCmd("trace") @@ -95,7 +99,7 @@ func TestChainSvrCmds(t *testing.T) { { name: "decoderawtransaction", newCmd: func() (interface{}, error) { - return NewCmd("decoderawtransaction", "123") + return dcrjson.NewCmd(Method("decoderawtransaction"), "123") }, staticCmd: func() interface{} { return NewDecodeRawTransactionCmd("123") @@ -106,7 +110,7 @@ func TestChainSvrCmds(t *testing.T) { { name: "decodescript", newCmd: func() (interface{}, error) { - return NewCmd("decodescript", "00") + return dcrjson.NewCmd(Method("decodescript"), "00") }, staticCmd: func() interface{} { return NewDecodeScriptCmd("00") @@ -117,20 +121,20 @@ func TestChainSvrCmds(t *testing.T) { { name: "decodescript optional", newCmd: func() (interface{}, error) { - return NewCmd("decodescript", "00", Uint16(1)) + return dcrjson.NewCmd(Method("decodescript"), "00", dcrjson.Uint16(1)) }, staticCmd: func() interface{} { cmd := NewDecodeScriptCmd("00") - cmd.Version = Uint16(1) + cmd.Version = dcrjson.Uint16(1) return cmd }, marshalled: `{"jsonrpc":"1.0","method":"decodescript","params":["00",1],"id":1}`, - unmarshalled: &DecodeScriptCmd{HexScript: "00", Version: Uint16(1)}, + unmarshalled: &DecodeScriptCmd{HexScript: "00", Version: dcrjson.Uint16(1)}, }, { name: "estimatefee", newCmd: func() (interface{}, error) { - return NewCmd("estimatefee", 6) + return dcrjson.NewCmd(Method("estimatefee"), 6) }, staticCmd: func() interface{} { return NewEstimateFeeCmd(6) @@ -143,7 +147,7 @@ func TestChainSvrCmds(t *testing.T) { { name: "estimatesmartfee", newCmd: func() (interface{}, error) { - return NewCmd("estimatesmartfee", 6) + return dcrjson.NewCmd(Method("estimatesmartfee"), 6) }, staticCmd: func() interface{} { return NewEstimateSmartFeeCmd(6, nil) @@ -157,7 +161,7 @@ func TestChainSvrCmds(t *testing.T) { { name: "estimatesmartfee optional", newCmd: func() (interface{}, error) { - return NewCmd("estimatesmartfee", 6, EstimateSmartFeeConservative) + return dcrjson.NewCmd(Method("estimatesmartfee"), 6, EstimateSmartFeeConservative) }, staticCmd: func() interface{} { mode := EstimateSmartFeeConservative @@ -172,7 +176,7 @@ func TestChainSvrCmds(t *testing.T) { { name: "generate", newCmd: func() (interface{}, error) { - return NewCmd("generate", 1) + return dcrjson.NewCmd(Method("generate"), 1) }, staticCmd: func() interface{} { return NewGenerateCmd(1) @@ -185,7 +189,7 @@ func TestChainSvrCmds(t *testing.T) { { name: "getaddednodeinfo", newCmd: func() (interface{}, error) { - return NewCmd("getaddednodeinfo", true) + return dcrjson.NewCmd(Method("getaddednodeinfo"), true) }, staticCmd: func() interface{} { return NewGetAddedNodeInfoCmd(true, nil) @@ -196,21 +200,21 @@ func TestChainSvrCmds(t *testing.T) { { name: "getaddednodeinfo optional", newCmd: func() (interface{}, error) { - return NewCmd("getaddednodeinfo", true, "127.0.0.1") + return dcrjson.NewCmd(Method("getaddednodeinfo"), true, "127.0.0.1") }, staticCmd: func() interface{} { - return NewGetAddedNodeInfoCmd(true, String("127.0.0.1")) + return NewGetAddedNodeInfoCmd(true, dcrjson.String("127.0.0.1")) }, marshalled: `{"jsonrpc":"1.0","method":"getaddednodeinfo","params":[true,"127.0.0.1"],"id":1}`, unmarshalled: &GetAddedNodeInfoCmd{ DNS: true, - Node: String("127.0.0.1"), + Node: dcrjson.String("127.0.0.1"), }, }, { name: "getbestblock", newCmd: func() (interface{}, error) { - return NewCmd("getbestblock") + return dcrjson.NewCmd(Method("getbestblock")) }, staticCmd: func() interface{} { return NewGetBestBlockCmd() @@ -221,7 +225,7 @@ func TestChainSvrCmds(t *testing.T) { { name: "getbestblockhash", newCmd: func() (interface{}, error) { - return NewCmd("getbestblockhash") + return dcrjson.NewCmd(Method("getbestblockhash")) }, staticCmd: func() interface{} { return NewGetBestBlockHashCmd() @@ -232,7 +236,7 @@ func TestChainSvrCmds(t *testing.T) { { name: "getblock", newCmd: func() (interface{}, error) { - return NewCmd("getblock", "123") + return dcrjson.NewCmd(Method("getblock"), "123") }, staticCmd: func() interface{} { return NewGetBlockCmd("123", nil, nil) @@ -240,8 +244,8 @@ func TestChainSvrCmds(t *testing.T) { marshalled: `{"jsonrpc":"1.0","method":"getblock","params":["123"],"id":1}`, unmarshalled: &GetBlockCmd{ Hash: "123", - Verbose: Bool(true), - VerboseTx: Bool(false), + Verbose: dcrjson.Bool(true), + VerboseTx: dcrjson.Bool(false), }, }, { @@ -250,38 +254,38 @@ func TestChainSvrCmds(t *testing.T) { // Intentionally use a source param that is // more pointers than the destination to // exercise that path. - verbosePtr := Bool(true) - return NewCmd("getblock", "123", &verbosePtr) + verbosePtr := dcrjson.Bool(true) + return dcrjson.NewCmd(Method("getblock"), "123", &verbosePtr) }, staticCmd: func() interface{} { - return NewGetBlockCmd("123", Bool(true), nil) + return NewGetBlockCmd("123", dcrjson.Bool(true), nil) }, marshalled: `{"jsonrpc":"1.0","method":"getblock","params":["123",true],"id":1}`, unmarshalled: &GetBlockCmd{ Hash: "123", - Verbose: Bool(true), - VerboseTx: Bool(false), + Verbose: dcrjson.Bool(true), + VerboseTx: dcrjson.Bool(false), }, }, { name: "getblock required optional2", newCmd: func() (interface{}, error) { - return NewCmd("getblock", "123", true, true) + return dcrjson.NewCmd(Method("getblock"), "123", true, true) }, staticCmd: func() interface{} { - return NewGetBlockCmd("123", Bool(true), Bool(true)) + return NewGetBlockCmd("123", dcrjson.Bool(true), dcrjson.Bool(true)) }, marshalled: `{"jsonrpc":"1.0","method":"getblock","params":["123",true,true],"id":1}`, unmarshalled: &GetBlockCmd{ Hash: "123", - Verbose: Bool(true), - VerboseTx: Bool(true), + Verbose: dcrjson.Bool(true), + VerboseTx: dcrjson.Bool(true), }, }, { name: "getblockchaininfo", newCmd: func() (interface{}, error) { - return NewCmd("getblockchaininfo") + return dcrjson.NewCmd(Method("getblockchaininfo")) }, staticCmd: func() interface{} { return NewGetBlockChainInfoCmd() @@ -292,7 +296,7 @@ func TestChainSvrCmds(t *testing.T) { { name: "getblockcount", newCmd: func() (interface{}, error) { - return NewCmd("getblockcount") + return dcrjson.NewCmd(Method("getblockcount")) }, staticCmd: func() interface{} { return NewGetBlockCountCmd() @@ -303,7 +307,7 @@ func TestChainSvrCmds(t *testing.T) { { name: "getblockhash", newCmd: func() (interface{}, error) { - return NewCmd("getblockhash", 123) + return dcrjson.NewCmd(Method("getblockhash"), 123) }, staticCmd: func() interface{} { return NewGetBlockHashCmd(123) @@ -314,7 +318,7 @@ func TestChainSvrCmds(t *testing.T) { { name: "getblockheader", newCmd: func() (interface{}, error) { - return NewCmd("getblockheader", "123") + return dcrjson.NewCmd(Method("getblockheader"), "123") }, staticCmd: func() interface{} { return NewGetBlockHeaderCmd("123", nil) @@ -322,13 +326,13 @@ func TestChainSvrCmds(t *testing.T) { marshalled: `{"jsonrpc":"1.0","method":"getblockheader","params":["123"],"id":1}`, unmarshalled: &GetBlockHeaderCmd{ Hash: "123", - Verbose: Bool(true), + Verbose: dcrjson.Bool(true), }, }, { name: "getblocksubsidy", newCmd: func() (interface{}, error) { - return NewCmd("getblocksubsidy", 123, 256) + return dcrjson.NewCmd(Method("getblocksubsidy"), 123, 256) }, staticCmd: func() interface{} { return NewGetBlockSubsidyCmd(123, 256) @@ -342,7 +346,7 @@ func TestChainSvrCmds(t *testing.T) { { name: "getblocktemplate", newCmd: func() (interface{}, error) { - return NewCmd("getblocktemplate") + return dcrjson.NewCmd(Method("getblocktemplate")) }, staticCmd: func() interface{} { return NewGetBlockTemplateCmd(nil) @@ -353,7 +357,7 @@ func TestChainSvrCmds(t *testing.T) { { name: "getblocktemplate optional - template request", newCmd: func() (interface{}, error) { - return NewCmd("getblocktemplate", `{"mode":"template","capabilities":["longpoll","coinbasetxn"]}`) + return dcrjson.NewCmd(Method("getblocktemplate"), `{"mode":"template","capabilities":["longpoll","coinbasetxn"]}`) }, staticCmd: func() interface{} { template := TemplateRequest{ @@ -373,7 +377,7 @@ func TestChainSvrCmds(t *testing.T) { { name: "getblocktemplate optional - template request with tweaks", newCmd: func() (interface{}, error) { - return NewCmd("getblocktemplate", `{"mode":"template","capabilities":["longpoll","coinbasetxn"],"sigoplimit":500,"sizelimit":100000000,"maxversion":2}`) + return dcrjson.NewCmd(Method("getblocktemplate"), `{"mode":"template","capabilities":["longpoll","coinbasetxn"],"sigoplimit":500,"sizelimit":100000000,"maxversion":2}`) }, staticCmd: func() interface{} { template := TemplateRequest{ @@ -399,7 +403,7 @@ func TestChainSvrCmds(t *testing.T) { { name: "getblocktemplate optional - template request with tweaks 2", newCmd: func() (interface{}, error) { - return NewCmd("getblocktemplate", `{"mode":"template","capabilities":["longpoll","coinbasetxn"],"sigoplimit":true,"sizelimit":100000000,"maxversion":2}`) + return dcrjson.NewCmd(Method("getblocktemplate"), `{"mode":"template","capabilities":["longpoll","coinbasetxn"],"sigoplimit":true,"sizelimit":100000000,"maxversion":2}`) }, staticCmd: func() interface{} { template := TemplateRequest{ @@ -425,7 +429,7 @@ func TestChainSvrCmds(t *testing.T) { { name: "getcfilter", newCmd: func() (interface{}, error) { - return NewCmd("getcfilter", "123", "extended") + return dcrjson.NewCmd(Method("getcfilter"), "123", "extended") }, staticCmd: func() interface{} { return NewGetCFilterCmd("123", "extended") @@ -439,7 +443,7 @@ func TestChainSvrCmds(t *testing.T) { { name: "getcfilterheader", newCmd: func() (interface{}, error) { - return NewCmd("getcfilterheader", "123", "extended") + return dcrjson.NewCmd(Method("getcfilterheader"), "123", "extended") }, staticCmd: func() interface{} { return NewGetCFilterHeaderCmd("123", "extended") @@ -453,7 +457,7 @@ func TestChainSvrCmds(t *testing.T) { { name: "getchaintips", newCmd: func() (interface{}, error) { - return NewCmd("getchaintips") + return dcrjson.NewCmd(Method("getchaintips")) }, staticCmd: func() interface{} { return NewGetChainTipsCmd() @@ -464,7 +468,7 @@ func TestChainSvrCmds(t *testing.T) { { name: "getconnectioncount", newCmd: func() (interface{}, error) { - return NewCmd("getconnectioncount") + return dcrjson.NewCmd(Method("getconnectioncount")) }, staticCmd: func() interface{} { return NewGetConnectionCountCmd() @@ -475,7 +479,7 @@ func TestChainSvrCmds(t *testing.T) { { name: "getcurrentnet", newCmd: func() (interface{}, error) { - return NewCmd("getcurrentnet") + return dcrjson.NewCmd(Method("getcurrentnet")) }, staticCmd: func() interface{} { return NewGetCurrentNetCmd() @@ -486,7 +490,7 @@ func TestChainSvrCmds(t *testing.T) { { name: "getdifficulty", newCmd: func() (interface{}, error) { - return NewCmd("getdifficulty") + return dcrjson.NewCmd(Method("getdifficulty")) }, staticCmd: func() interface{} { return NewGetDifficultyCmd() @@ -497,7 +501,7 @@ func TestChainSvrCmds(t *testing.T) { { name: "getgenerate", newCmd: func() (interface{}, error) { - return NewCmd("getgenerate") + return dcrjson.NewCmd(Method("getgenerate")) }, staticCmd: func() interface{} { return NewGetGenerateCmd() @@ -508,7 +512,7 @@ func TestChainSvrCmds(t *testing.T) { { name: "gethashespersec", newCmd: func() (interface{}, error) { - return NewCmd("gethashespersec") + return dcrjson.NewCmd(Method("gethashespersec")) }, staticCmd: func() interface{} { return NewGetHashesPerSecCmd() @@ -519,7 +523,7 @@ func TestChainSvrCmds(t *testing.T) { { name: "getinfo", newCmd: func() (interface{}, error) { - return NewCmd("getinfo") + return dcrjson.NewCmd(Method("getinfo")) }, staticCmd: func() interface{} { return NewGetInfoCmd() @@ -530,7 +534,7 @@ func TestChainSvrCmds(t *testing.T) { { name: "getmempoolinfo", newCmd: func() (interface{}, error) { - return NewCmd("getmempoolinfo") + return dcrjson.NewCmd(Method("getmempoolinfo")) }, staticCmd: func() interface{} { return NewGetMempoolInfoCmd() @@ -541,7 +545,7 @@ func TestChainSvrCmds(t *testing.T) { { name: "getmininginfo", newCmd: func() (interface{}, error) { - return NewCmd("getmininginfo") + return dcrjson.NewCmd(Method("getmininginfo")) }, staticCmd: func() interface{} { return NewGetMiningInfoCmd() @@ -552,7 +556,7 @@ func TestChainSvrCmds(t *testing.T) { { name: "getnetworkinfo", newCmd: func() (interface{}, error) { - return NewCmd("getnetworkinfo") + return dcrjson.NewCmd(Method("getnetworkinfo")) }, staticCmd: func() interface{} { return NewGetNetworkInfoCmd() @@ -563,7 +567,7 @@ func TestChainSvrCmds(t *testing.T) { { name: "getnettotals", newCmd: func() (interface{}, error) { - return NewCmd("getnettotals") + return dcrjson.NewCmd(Method("getnettotals")) }, staticCmd: func() interface{} { return NewGetNetTotalsCmd() @@ -574,49 +578,49 @@ func TestChainSvrCmds(t *testing.T) { { name: "getnetworkhashps", newCmd: func() (interface{}, error) { - return NewCmd("getnetworkhashps") + return dcrjson.NewCmd(Method("getnetworkhashps")) }, staticCmd: func() interface{} { return NewGetNetworkHashPSCmd(nil, nil) }, marshalled: `{"jsonrpc":"1.0","method":"getnetworkhashps","params":[],"id":1}`, unmarshalled: &GetNetworkHashPSCmd{ - Blocks: Int(120), - Height: Int(-1), + Blocks: dcrjson.Int(120), + Height: dcrjson.Int(-1), }, }, { name: "getnetworkhashps optional1", newCmd: func() (interface{}, error) { - return NewCmd("getnetworkhashps", 200) + return dcrjson.NewCmd(Method("getnetworkhashps"), 200) }, staticCmd: func() interface{} { - return NewGetNetworkHashPSCmd(Int(200), nil) + return NewGetNetworkHashPSCmd(dcrjson.Int(200), nil) }, marshalled: `{"jsonrpc":"1.0","method":"getnetworkhashps","params":[200],"id":1}`, unmarshalled: &GetNetworkHashPSCmd{ - Blocks: Int(200), - Height: Int(-1), + Blocks: dcrjson.Int(200), + Height: dcrjson.Int(-1), }, }, { name: "getnetworkhashps optional2", newCmd: func() (interface{}, error) { - return NewCmd("getnetworkhashps", 200, 123) + return dcrjson.NewCmd(Method("getnetworkhashps"), 200, 123) }, staticCmd: func() interface{} { - return NewGetNetworkHashPSCmd(Int(200), Int(123)) + return NewGetNetworkHashPSCmd(dcrjson.Int(200), dcrjson.Int(123)) }, marshalled: `{"jsonrpc":"1.0","method":"getnetworkhashps","params":[200,123],"id":1}`, unmarshalled: &GetNetworkHashPSCmd{ - Blocks: Int(200), - Height: Int(123), + Blocks: dcrjson.Int(200), + Height: dcrjson.Int(123), }, }, { name: "getpeerinfo", newCmd: func() (interface{}, error) { - return NewCmd("getpeerinfo") + return dcrjson.NewCmd(Method("getpeerinfo")) }, staticCmd: func() interface{} { return NewGetPeerInfoCmd() @@ -627,47 +631,47 @@ func TestChainSvrCmds(t *testing.T) { { name: "getrawmempool", newCmd: func() (interface{}, error) { - return NewCmd("getrawmempool") + return dcrjson.NewCmd(Method("getrawmempool")) }, staticCmd: func() interface{} { return NewGetRawMempoolCmd(nil, nil) }, marshalled: `{"jsonrpc":"1.0","method":"getrawmempool","params":[],"id":1}`, unmarshalled: &GetRawMempoolCmd{ - Verbose: Bool(false), + Verbose: dcrjson.Bool(false), }, }, { name: "getrawmempool optional", newCmd: func() (interface{}, error) { - return NewCmd("getrawmempool", false) + return dcrjson.NewCmd(Method("getrawmempool"), false) }, staticCmd: func() interface{} { - return NewGetRawMempoolCmd(Bool(false), nil) + return NewGetRawMempoolCmd(dcrjson.Bool(false), nil) }, marshalled: `{"jsonrpc":"1.0","method":"getrawmempool","params":[false],"id":1}`, unmarshalled: &GetRawMempoolCmd{ - Verbose: Bool(false), + Verbose: dcrjson.Bool(false), }, }, { name: "getrawmempool optional 2", newCmd: func() (interface{}, error) { - return NewCmd("getrawmempool", false, "all") + return dcrjson.NewCmd(Method("getrawmempool"), false, "all") }, staticCmd: func() interface{} { - return NewGetRawMempoolCmd(Bool(false), String("all")) + return NewGetRawMempoolCmd(dcrjson.Bool(false), dcrjson.String("all")) }, marshalled: `{"jsonrpc":"1.0","method":"getrawmempool","params":[false,"all"],"id":1}`, unmarshalled: &GetRawMempoolCmd{ - Verbose: Bool(false), - TxType: String("all"), + Verbose: dcrjson.Bool(false), + TxType: dcrjson.String("all"), }, }, { name: "getrawtransaction", newCmd: func() (interface{}, error) { - return NewCmd("getrawtransaction", "123") + return dcrjson.NewCmd(Method("getrawtransaction"), "123") }, staticCmd: func() interface{} { return NewGetRawTransactionCmd("123", nil) @@ -675,27 +679,27 @@ func TestChainSvrCmds(t *testing.T) { marshalled: `{"jsonrpc":"1.0","method":"getrawtransaction","params":["123"],"id":1}`, unmarshalled: &GetRawTransactionCmd{ Txid: "123", - Verbose: Int(0), + Verbose: dcrjson.Int(0), }, }, { name: "getrawtransaction optional", newCmd: func() (interface{}, error) { - return NewCmd("getrawtransaction", "123", 1) + return dcrjson.NewCmd(Method("getrawtransaction"), "123", 1) }, staticCmd: func() interface{} { - return NewGetRawTransactionCmd("123", Int(1)) + return NewGetRawTransactionCmd("123", dcrjson.Int(1)) }, marshalled: `{"jsonrpc":"1.0","method":"getrawtransaction","params":["123",1],"id":1}`, unmarshalled: &GetRawTransactionCmd{ Txid: "123", - Verbose: Int(1), + Verbose: dcrjson.Int(1), }, }, { name: "getstakeversions", newCmd: func() (interface{}, error) { - return NewCmd("getstakeversions", "deadbeef", 1) + return dcrjson.NewCmd(Method("getstakeversions"), "deadbeef", 1) }, staticCmd: func() interface{} { return NewGetStakeVersionsCmd("deadbeef", 1) @@ -709,7 +713,7 @@ func TestChainSvrCmds(t *testing.T) { { name: "gettxout", newCmd: func() (interface{}, error) { - return NewCmd("gettxout", "123", 1) + return dcrjson.NewCmd(Method("gettxout"), "123", 1) }, staticCmd: func() interface{} { return NewGetTxOutCmd("123", 1, nil) @@ -718,28 +722,28 @@ func TestChainSvrCmds(t *testing.T) { unmarshalled: &GetTxOutCmd{ Txid: "123", Vout: 1, - IncludeMempool: Bool(true), + IncludeMempool: dcrjson.Bool(true), }, }, { name: "gettxout optional", newCmd: func() (interface{}, error) { - return NewCmd("gettxout", "123", 1, true) + return dcrjson.NewCmd(Method("gettxout"), "123", 1, true) }, staticCmd: func() interface{} { - return NewGetTxOutCmd("123", 1, Bool(true)) + return NewGetTxOutCmd("123", 1, dcrjson.Bool(true)) }, marshalled: `{"jsonrpc":"1.0","method":"gettxout","params":["123",1,true],"id":1}`, unmarshalled: &GetTxOutCmd{ Txid: "123", Vout: 1, - IncludeMempool: Bool(true), + IncludeMempool: dcrjson.Bool(true), }, }, { name: "gettxoutsetinfo", newCmd: func() (interface{}, error) { - return NewCmd("gettxoutsetinfo") + return dcrjson.NewCmd(Method("gettxoutsetinfo")) }, staticCmd: func() interface{} { return NewGetTxOutSetInfoCmd() @@ -750,7 +754,7 @@ func TestChainSvrCmds(t *testing.T) { { name: "getvoteinfo", newCmd: func() (interface{}, error) { - return NewCmd("getvoteinfo", 1) + return dcrjson.NewCmd(Method("getvoteinfo"), 1) }, staticCmd: func() interface{} { return NewGetVoteInfoCmd(1) @@ -763,7 +767,7 @@ func TestChainSvrCmds(t *testing.T) { { name: "getwork", newCmd: func() (interface{}, error) { - return NewCmd("getwork") + return dcrjson.NewCmd(Method("getwork")) }, staticCmd: func() interface{} { return NewGetWorkCmd(nil) @@ -776,20 +780,20 @@ func TestChainSvrCmds(t *testing.T) { { name: "getwork optional", newCmd: func() (interface{}, error) { - return NewCmd("getwork", "00112233") + return dcrjson.NewCmd(Method("getwork"), "00112233") }, staticCmd: func() interface{} { - return NewGetWorkCmd(String("00112233")) + return NewGetWorkCmd(dcrjson.String("00112233")) }, marshalled: `{"jsonrpc":"1.0","method":"getwork","params":["00112233"],"id":1}`, unmarshalled: &GetWorkCmd{ - Data: String("00112233"), + Data: dcrjson.String("00112233"), }, }, { name: "help", newCmd: func() (interface{}, error) { - return NewCmd("help") + return dcrjson.NewCmd(Method("help")) }, staticCmd: func() interface{} { return NewHelpCmd(nil) @@ -802,20 +806,20 @@ func TestChainSvrCmds(t *testing.T) { { name: "help optional", newCmd: func() (interface{}, error) { - return NewCmd("help", "getblock") + return dcrjson.NewCmd(Method("help"), "getblock") }, staticCmd: func() interface{} { - return NewHelpCmd(String("getblock")) + return NewHelpCmd(dcrjson.String("getblock")) }, marshalled: `{"jsonrpc":"1.0","method":"help","params":["getblock"],"id":1}`, unmarshalled: &HelpCmd{ - Command: String("getblock"), + Command: dcrjson.String("getblock"), }, }, { name: "node option remove", newCmd: func() (interface{}, error) { - return NewCmd("node", NRemove, "1.1.1.1") + return dcrjson.NewCmd(Method("node"), NRemove, "1.1.1.1") }, staticCmd: func() interface{} { return NewNodeCmd("remove", "1.1.1.1", nil) @@ -829,7 +833,7 @@ func TestChainSvrCmds(t *testing.T) { { name: "node option disconnect", newCmd: func() (interface{}, error) { - return NewCmd("node", NDisconnect, "1.1.1.1") + return dcrjson.NewCmd(Method("node"), NDisconnect, "1.1.1.1") }, staticCmd: func() interface{} { return NewNodeCmd("disconnect", "1.1.1.1", nil) @@ -843,22 +847,22 @@ func TestChainSvrCmds(t *testing.T) { { name: "node option connect", newCmd: func() (interface{}, error) { - return NewCmd("node", NConnect, "1.1.1.1", "perm") + return dcrjson.NewCmd(Method("node"), NConnect, "1.1.1.1", "perm") }, staticCmd: func() interface{} { - return NewNodeCmd("connect", "1.1.1.1", String("perm")) + return NewNodeCmd("connect", "1.1.1.1", dcrjson.String("perm")) }, marshalled: `{"jsonrpc":"1.0","method":"node","params":["connect","1.1.1.1","perm"],"id":1}`, unmarshalled: &NodeCmd{ SubCmd: NConnect, Target: "1.1.1.1", - ConnectSubCmd: String("perm"), + ConnectSubCmd: dcrjson.String("perm"), }, }, { name: "ping", newCmd: func() (interface{}, error) { - return NewCmd("ping") + return dcrjson.NewCmd(Method("ping")) }, staticCmd: func() interface{} { return NewPingCmd() @@ -869,7 +873,7 @@ func TestChainSvrCmds(t *testing.T) { { name: "searchrawtransactions", newCmd: func() (interface{}, error) { - return NewCmd("searchrawtransactions", "1Address") + return dcrjson.NewCmd(Method("searchrawtransactions"), "1Address") }, staticCmd: func() interface{} { return NewSearchRawTransactionsCmd("1Address", nil, nil, nil, nil, nil, nil) @@ -877,140 +881,140 @@ func TestChainSvrCmds(t *testing.T) { marshalled: `{"jsonrpc":"1.0","method":"searchrawtransactions","params":["1Address"],"id":1}`, unmarshalled: &SearchRawTransactionsCmd{ Address: "1Address", - Verbose: Int(1), - Skip: Int(0), - Count: Int(100), - VinExtra: Int(0), - Reverse: Bool(false), + Verbose: dcrjson.Int(1), + Skip: dcrjson.Int(0), + Count: dcrjson.Int(100), + VinExtra: dcrjson.Int(0), + Reverse: dcrjson.Bool(false), FilterAddrs: nil, }, }, { name: "searchrawtransactions", newCmd: func() (interface{}, error) { - return NewCmd("searchrawtransactions", "1Address", 0) + return dcrjson.NewCmd(Method("searchrawtransactions"), "1Address", 0) }, staticCmd: func() interface{} { return NewSearchRawTransactionsCmd("1Address", - Int(0), nil, nil, nil, nil, nil) + dcrjson.Int(0), nil, nil, nil, nil, nil) }, marshalled: `{"jsonrpc":"1.0","method":"searchrawtransactions","params":["1Address",0],"id":1}`, unmarshalled: &SearchRawTransactionsCmd{ Address: "1Address", - Verbose: Int(0), - Skip: Int(0), - Count: Int(100), - VinExtra: Int(0), - Reverse: Bool(false), + Verbose: dcrjson.Int(0), + Skip: dcrjson.Int(0), + Count: dcrjson.Int(100), + VinExtra: dcrjson.Int(0), + Reverse: dcrjson.Bool(false), FilterAddrs: nil, }, }, { name: "searchrawtransactions", newCmd: func() (interface{}, error) { - return NewCmd("searchrawtransactions", "1Address", 0, 5) + return dcrjson.NewCmd(Method("searchrawtransactions"), "1Address", 0, 5) }, staticCmd: func() interface{} { return NewSearchRawTransactionsCmd("1Address", - Int(0), Int(5), nil, nil, nil, nil) + dcrjson.Int(0), dcrjson.Int(5), nil, nil, nil, nil) }, marshalled: `{"jsonrpc":"1.0","method":"searchrawtransactions","params":["1Address",0,5],"id":1}`, unmarshalled: &SearchRawTransactionsCmd{ Address: "1Address", - Verbose: Int(0), - Skip: Int(5), - Count: Int(100), - VinExtra: Int(0), - Reverse: Bool(false), + Verbose: dcrjson.Int(0), + Skip: dcrjson.Int(5), + Count: dcrjson.Int(100), + VinExtra: dcrjson.Int(0), + Reverse: dcrjson.Bool(false), FilterAddrs: nil, }, }, { name: "searchrawtransactions", newCmd: func() (interface{}, error) { - return NewCmd("searchrawtransactions", "1Address", 0, 5, 10) + return dcrjson.NewCmd(Method("searchrawtransactions"), "1Address", 0, 5, 10) }, staticCmd: func() interface{} { return NewSearchRawTransactionsCmd("1Address", - Int(0), Int(5), Int(10), nil, nil, nil) + dcrjson.Int(0), dcrjson.Int(5), dcrjson.Int(10), nil, nil, nil) }, marshalled: `{"jsonrpc":"1.0","method":"searchrawtransactions","params":["1Address",0,5,10],"id":1}`, unmarshalled: &SearchRawTransactionsCmd{ Address: "1Address", - Verbose: Int(0), - Skip: Int(5), - Count: Int(10), - VinExtra: Int(0), - Reverse: Bool(false), + Verbose: dcrjson.Int(0), + Skip: dcrjson.Int(5), + Count: dcrjson.Int(10), + VinExtra: dcrjson.Int(0), + Reverse: dcrjson.Bool(false), FilterAddrs: nil, }, }, { name: "searchrawtransactions", newCmd: func() (interface{}, error) { - return NewCmd("searchrawtransactions", "1Address", 0, 5, 10, 1) + return dcrjson.NewCmd(Method("searchrawtransactions"), "1Address", 0, 5, 10, 1) }, staticCmd: func() interface{} { return NewSearchRawTransactionsCmd("1Address", - Int(0), Int(5), Int(10), Int(1), nil, nil) + dcrjson.Int(0), dcrjson.Int(5), dcrjson.Int(10), dcrjson.Int(1), nil, nil) }, marshalled: `{"jsonrpc":"1.0","method":"searchrawtransactions","params":["1Address",0,5,10,1],"id":1}`, unmarshalled: &SearchRawTransactionsCmd{ Address: "1Address", - Verbose: Int(0), - Skip: Int(5), - Count: Int(10), - VinExtra: Int(1), - Reverse: Bool(false), + Verbose: dcrjson.Int(0), + Skip: dcrjson.Int(5), + Count: dcrjson.Int(10), + VinExtra: dcrjson.Int(1), + Reverse: dcrjson.Bool(false), FilterAddrs: nil, }, }, { name: "searchrawtransactions", newCmd: func() (interface{}, error) { - return NewCmd("searchrawtransactions", "1Address", 0, 5, 10, 1, true) + return dcrjson.NewCmd(Method("searchrawtransactions"), "1Address", 0, 5, 10, 1, true) }, staticCmd: func() interface{} { return NewSearchRawTransactionsCmd("1Address", - Int(0), Int(5), Int(10), - Int(1), Bool(true), nil) + dcrjson.Int(0), dcrjson.Int(5), dcrjson.Int(10), + dcrjson.Int(1), dcrjson.Bool(true), nil) }, marshalled: `{"jsonrpc":"1.0","method":"searchrawtransactions","params":["1Address",0,5,10,1,true],"id":1}`, unmarshalled: &SearchRawTransactionsCmd{ Address: "1Address", - Verbose: Int(0), - Skip: Int(5), - Count: Int(10), - VinExtra: Int(1), - Reverse: Bool(true), + Verbose: dcrjson.Int(0), + Skip: dcrjson.Int(5), + Count: dcrjson.Int(10), + VinExtra: dcrjson.Int(1), + Reverse: dcrjson.Bool(true), FilterAddrs: nil, }, }, { name: "searchrawtransactions", newCmd: func() (interface{}, error) { - return NewCmd("searchrawtransactions", "1Address", 0, 5, 10, 1, true, []string{"1Address"}) + return dcrjson.NewCmd(Method("searchrawtransactions"), "1Address", 0, 5, 10, 1, true, []string{"1Address"}) }, staticCmd: func() interface{} { return NewSearchRawTransactionsCmd("1Address", - Int(0), Int(5), Int(10), - Int(1), Bool(true), &[]string{"1Address"}) + dcrjson.Int(0), dcrjson.Int(5), dcrjson.Int(10), + dcrjson.Int(1), dcrjson.Bool(true), &[]string{"1Address"}) }, marshalled: `{"jsonrpc":"1.0","method":"searchrawtransactions","params":["1Address",0,5,10,1,true,["1Address"]],"id":1}`, unmarshalled: &SearchRawTransactionsCmd{ Address: "1Address", - Verbose: Int(0), - Skip: Int(5), - Count: Int(10), - VinExtra: Int(1), - Reverse: Bool(true), + Verbose: dcrjson.Int(0), + Skip: dcrjson.Int(5), + Count: dcrjson.Int(10), + VinExtra: dcrjson.Int(1), + Reverse: dcrjson.Bool(true), FilterAddrs: &[]string{"1Address"}, }, }, { name: "sendrawtransaction", newCmd: func() (interface{}, error) { - return NewCmd("sendrawtransaction", "1122") + return dcrjson.NewCmd(Method("sendrawtransaction"), "1122") }, staticCmd: func() interface{} { return NewSendRawTransactionCmd("1122", nil) @@ -1018,27 +1022,27 @@ func TestChainSvrCmds(t *testing.T) { marshalled: `{"jsonrpc":"1.0","method":"sendrawtransaction","params":["1122"],"id":1}`, unmarshalled: &SendRawTransactionCmd{ HexTx: "1122", - AllowHighFees: Bool(false), + AllowHighFees: dcrjson.Bool(false), }, }, { name: "sendrawtransaction optional", newCmd: func() (interface{}, error) { - return NewCmd("sendrawtransaction", "1122", false) + return dcrjson.NewCmd(Method("sendrawtransaction"), "1122", false) }, staticCmd: func() interface{} { - return NewSendRawTransactionCmd("1122", Bool(false)) + return NewSendRawTransactionCmd("1122", dcrjson.Bool(false)) }, marshalled: `{"jsonrpc":"1.0","method":"sendrawtransaction","params":["1122",false],"id":1}`, unmarshalled: &SendRawTransactionCmd{ HexTx: "1122", - AllowHighFees: Bool(false), + AllowHighFees: dcrjson.Bool(false), }, }, { name: "setgenerate", newCmd: func() (interface{}, error) { - return NewCmd("setgenerate", true) + return dcrjson.NewCmd(Method("setgenerate"), true) }, staticCmd: func() interface{} { return NewSetGenerateCmd(true, nil) @@ -1046,27 +1050,27 @@ func TestChainSvrCmds(t *testing.T) { marshalled: `{"jsonrpc":"1.0","method":"setgenerate","params":[true],"id":1}`, unmarshalled: &SetGenerateCmd{ Generate: true, - GenProcLimit: Int(-1), + GenProcLimit: dcrjson.Int(-1), }, }, { name: "setgenerate optional", newCmd: func() (interface{}, error) { - return NewCmd("setgenerate", true, 6) + return dcrjson.NewCmd(Method("setgenerate"), true, 6) }, staticCmd: func() interface{} { - return NewSetGenerateCmd(true, Int(6)) + return NewSetGenerateCmd(true, dcrjson.Int(6)) }, marshalled: `{"jsonrpc":"1.0","method":"setgenerate","params":[true,6],"id":1}`, unmarshalled: &SetGenerateCmd{ Generate: true, - GenProcLimit: Int(6), + GenProcLimit: dcrjson.Int(6), }, }, { name: "stop", newCmd: func() (interface{}, error) { - return NewCmd("stop") + return dcrjson.NewCmd(Method("stop")) }, staticCmd: func() interface{} { return NewStopCmd() @@ -1077,7 +1081,7 @@ func TestChainSvrCmds(t *testing.T) { { name: "submitblock", newCmd: func() (interface{}, error) { - return NewCmd("submitblock", "112233") + return dcrjson.NewCmd(Method("submitblock"), "112233") }, staticCmd: func() interface{} { return NewSubmitBlockCmd("112233", nil) @@ -1091,7 +1095,7 @@ func TestChainSvrCmds(t *testing.T) { { name: "submitblock optional", newCmd: func() (interface{}, error) { - return NewCmd("submitblock", "112233", `{"workid":"12345"}`) + return dcrjson.NewCmd(Method("submitblock"), "112233", `{"workid":"12345"}`) }, staticCmd: func() interface{} { options := SubmitBlockOptions{ @@ -1110,7 +1114,7 @@ func TestChainSvrCmds(t *testing.T) { { name: "validateaddress", newCmd: func() (interface{}, error) { - return NewCmd("validateaddress", "1Address") + return dcrjson.NewCmd(Method("validateaddress"), "1Address") }, staticCmd: func() interface{} { return NewValidateAddressCmd("1Address") @@ -1123,49 +1127,49 @@ func TestChainSvrCmds(t *testing.T) { { name: "verifychain", newCmd: func() (interface{}, error) { - return NewCmd("verifychain") + return dcrjson.NewCmd(Method("verifychain")) }, staticCmd: func() interface{} { return NewVerifyChainCmd(nil, nil) }, marshalled: `{"jsonrpc":"1.0","method":"verifychain","params":[],"id":1}`, unmarshalled: &VerifyChainCmd{ - CheckLevel: Int64(3), - CheckDepth: Int64(288), + CheckLevel: dcrjson.Int64(3), + CheckDepth: dcrjson.Int64(288), }, }, { name: "verifychain optional1", newCmd: func() (interface{}, error) { - return NewCmd("verifychain", 2) + return dcrjson.NewCmd(Method("verifychain"), 2) }, staticCmd: func() interface{} { - return NewVerifyChainCmd(Int64(2), nil) + return NewVerifyChainCmd(dcrjson.Int64(2), nil) }, marshalled: `{"jsonrpc":"1.0","method":"verifychain","params":[2],"id":1}`, unmarshalled: &VerifyChainCmd{ - CheckLevel: Int64(2), - CheckDepth: Int64(288), + CheckLevel: dcrjson.Int64(2), + CheckDepth: dcrjson.Int64(288), }, }, { name: "verifychain optional2", newCmd: func() (interface{}, error) { - return NewCmd("verifychain", 2, 500) + return dcrjson.NewCmd(Method("verifychain"), 2, 500) }, staticCmd: func() interface{} { - return NewVerifyChainCmd(Int64(2), Int64(500)) + return NewVerifyChainCmd(dcrjson.Int64(2), dcrjson.Int64(500)) }, marshalled: `{"jsonrpc":"1.0","method":"verifychain","params":[2,500],"id":1}`, unmarshalled: &VerifyChainCmd{ - CheckLevel: Int64(2), - CheckDepth: Int64(500), + CheckLevel: dcrjson.Int64(2), + CheckDepth: dcrjson.Int64(500), }, }, { name: "verifymessage", newCmd: func() (interface{}, error) { - return NewCmd("verifymessage", "1Address", "301234", "test") + return dcrjson.NewCmd(Method("verifymessage"), "1Address", "301234", "test") }, staticCmd: func() interface{} { return NewVerifyMessageCmd("1Address", "301234", "test") @@ -1183,7 +1187,7 @@ func TestChainSvrCmds(t *testing.T) { for i, test := range tests { // Marshal the command as created by the new static command // creation function. - marshalled, err := MarshalCmd("1.0", testID, test.staticCmd()) + marshalled, err := dcrjson.MarshalCmd("1.0", testID, test.staticCmd()) if err != nil { t.Errorf("MarshalCmd #%d (%s) unexpected error: %v", i, test.name, err) @@ -1202,13 +1206,13 @@ func TestChainSvrCmds(t *testing.T) { // new command creation function. cmd, err := test.newCmd() if err != nil { - t.Errorf("Test #%d (%s) unexpected NewCmd error: %v ", + t.Errorf("Test #%d (%s) unexpected dcrjson.NewCmd error: %v ", i, test.name, err) } // Marshal the command as created by the generic new command // creation function. - marshalled, err = MarshalCmd("1.0", testID, cmd) + marshalled, err = dcrjson.MarshalCmd("1.0", testID, cmd) if err != nil { t.Errorf("MarshalCmd #%d (%s) unexpected error: %v", i, test.name, err) @@ -1222,7 +1226,7 @@ func TestChainSvrCmds(t *testing.T) { continue } - var request Request + var request dcrjson.Request if err := json.Unmarshal(marshalled, &request); err != nil { t.Errorf("Test #%d (%s) unexpected error while "+ "unmarshalling JSON-RPC request: %v", i, @@ -1230,9 +1234,9 @@ func TestChainSvrCmds(t *testing.T) { continue } - cmd, err = UnmarshalCmd(&request) + cmd, err = dcrjson.ParseParams(Method(request.Method), request.Params) if err != nil { - t.Errorf("UnmarshalCmd #%d (%s) unexpected error: %v", i, + t.Errorf("ParseParams #%d (%s) unexpected error: %v", i, test.name, err) continue } @@ -1268,13 +1272,13 @@ func TestChainSvrCmdErrors(t *testing.T) { name: "invalid template request sigoplimit field", result: &TemplateRequest{}, marshalled: `{"sigoplimit":"invalid"}`, - err: Error{Code: ErrInvalidType}, + err: dcrjson.Error{Code: dcrjson.ErrInvalidType}, }, { name: "invalid template request sizelimit field", result: &TemplateRequest{}, marshalled: `{"sizelimit":"invalid"}`, - err: Error{Code: ErrInvalidType}, + err: dcrjson.Error{Code: dcrjson.ErrInvalidType}, }, } @@ -1287,8 +1291,8 @@ func TestChainSvrCmdErrors(t *testing.T) { continue } - if terr, ok := test.err.(Error); ok { - gotErrorCode := err.(Error).Code + if terr, ok := test.err.(dcrjson.Error); ok { + gotErrorCode := err.(dcrjson.Error).Code if gotErrorCode != terr.Code { t.Errorf("Test #%d (%s) mismatched error code "+ "- got %v (%v), want %v", i, test.name, diff --git a/dcrjson/chainsvrresults.go b/rpc/jsonrpc/types/chainsvrresults.go similarity index 99% rename from dcrjson/chainsvrresults.go rename to rpc/jsonrpc/types/chainsvrresults.go index 7d335c8f..010c448f 100644 --- a/dcrjson/chainsvrresults.go +++ b/rpc/jsonrpc/types/chainsvrresults.go @@ -3,7 +3,7 @@ // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. -package dcrjson +package types import "encoding/json" diff --git a/dcrjson/chainsvrresults_test.go b/rpc/jsonrpc/types/chainsvrresults_test.go similarity index 99% rename from dcrjson/chainsvrresults_test.go rename to rpc/jsonrpc/types/chainsvrresults_test.go index c718710e..2aa24f77 100644 --- a/dcrjson/chainsvrresults_test.go +++ b/rpc/jsonrpc/types/chainsvrresults_test.go @@ -3,7 +3,7 @@ // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. -package dcrjson +package types import ( "encoding/json" diff --git a/dcrjson/chainsvrwscmds.go b/rpc/jsonrpc/types/chainsvrwscmds.go similarity index 82% rename from dcrjson/chainsvrwscmds.go rename to rpc/jsonrpc/types/chainsvrwscmds.go index f42639fc..69e4e541 100644 --- a/dcrjson/chainsvrwscmds.go +++ b/rpc/jsonrpc/types/chainsvrwscmds.go @@ -6,7 +6,9 @@ // NOTE: This file is intended to house the RPC commands that are supported by // a chain server, but are only available via websockets. -package dcrjson +package types + +import "github.com/decred/dcrd/dcrjson/v3" // AuthenticateCmd defines the authenticate JSON-RPC command. type AuthenticateCmd struct { @@ -150,34 +152,32 @@ func NewStopNotifyNewTransactionsCmd() *StopNotifyNewTransactionsCmd { // RescanCmd defines the rescan JSON-RPC command. type RescanCmd struct { - // Concatenated block hashes in non-byte-reversed hex encoding. Must - // have length evenly divisible by 2*chainhash.HashSize. - BlockHashes string + BlockHashes []string } // NewRescanCmd returns a new instance which can be used to issue a rescan // JSON-RPC command. -func NewRescanCmd(blockHashes string) *RescanCmd { +func NewRescanCmd(blockHashes []string) *RescanCmd { return &RescanCmd{BlockHashes: blockHashes} } func init() { // The commands in this file are only usable by websockets. - flags := UFWebsocketOnly + flags := dcrjson.UFWebsocketOnly - MustRegisterCmd("authenticate", (*AuthenticateCmd)(nil), flags) - MustRegisterCmd("loadtxfilter", (*LoadTxFilterCmd)(nil), flags) - MustRegisterCmd("notifyblocks", (*NotifyBlocksCmd)(nil), flags) - MustRegisterCmd("notifynewtransactions", (*NotifyNewTransactionsCmd)(nil), flags) - MustRegisterCmd("notifynewtickets", (*NotifyNewTicketsCmd)(nil), flags) - MustRegisterCmd("notifyspentandmissedtickets", + dcrjson.MustRegister(Method("authenticate"), (*AuthenticateCmd)(nil), flags) + dcrjson.MustRegister(Method("loadtxfilter"), (*LoadTxFilterCmd)(nil), flags) + dcrjson.MustRegister(Method("notifyblocks"), (*NotifyBlocksCmd)(nil), flags) + dcrjson.MustRegister(Method("notifynewtransactions"), (*NotifyNewTransactionsCmd)(nil), flags) + dcrjson.MustRegister(Method("notifynewtickets"), (*NotifyNewTicketsCmd)(nil), flags) + dcrjson.MustRegister(Method("notifyspentandmissedtickets"), (*NotifySpentAndMissedTicketsCmd)(nil), flags) - MustRegisterCmd("notifystakedifficulty", + dcrjson.MustRegister(Method("notifystakedifficulty"), (*NotifyStakeDifficultyCmd)(nil), flags) - MustRegisterCmd("notifywinningtickets", + dcrjson.MustRegister(Method("notifywinningtickets"), (*NotifyWinningTicketsCmd)(nil), flags) - MustRegisterCmd("session", (*SessionCmd)(nil), flags) - MustRegisterCmd("stopnotifyblocks", (*StopNotifyBlocksCmd)(nil), flags) - MustRegisterCmd("stopnotifynewtransactions", (*StopNotifyNewTransactionsCmd)(nil), flags) - MustRegisterCmd("rescan", (*RescanCmd)(nil), flags) + dcrjson.MustRegister(Method("session"), (*SessionCmd)(nil), flags) + dcrjson.MustRegister(Method("stopnotifyblocks"), (*StopNotifyBlocksCmd)(nil), flags) + dcrjson.MustRegister(Method("stopnotifynewtransactions"), (*StopNotifyNewTransactionsCmd)(nil), flags) + dcrjson.MustRegister(Method("rescan"), (*RescanCmd)(nil), flags) } diff --git a/dcrjson/chainsvrwscmds_test.go b/rpc/jsonrpc/types/chainsvrwscmds_test.go similarity index 77% rename from dcrjson/chainsvrwscmds_test.go rename to rpc/jsonrpc/types/chainsvrwscmds_test.go index f6ffb647..1579c716 100644 --- a/dcrjson/chainsvrwscmds_test.go +++ b/rpc/jsonrpc/types/chainsvrwscmds_test.go @@ -3,7 +3,7 @@ // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. -package dcrjson +package types import ( "bytes" @@ -11,6 +11,8 @@ import ( "fmt" "reflect" "testing" + + "github.com/decred/dcrd/dcrjson/v3" ) // TestChainSvrWsCmds tests all of the chain server websocket-specific commands @@ -31,7 +33,7 @@ func TestChainSvrWsCmds(t *testing.T) { { name: "authenticate", newCmd: func() (interface{}, error) { - return NewCmd("authenticate", "user", "pass") + return dcrjson.NewCmd(Method("authenticate"), "user", "pass") }, staticCmd: func() interface{} { return NewAuthenticateCmd("user", "pass") @@ -42,7 +44,7 @@ func TestChainSvrWsCmds(t *testing.T) { { name: "notifywinningtickets", newCmd: func() (interface{}, error) { - return NewCmd("notifywinningtickets") + return dcrjson.NewCmd(Method("notifywinningtickets")) }, staticCmd: func() interface{} { return NewNotifyWinningTicketsCmd() @@ -53,7 +55,7 @@ func TestChainSvrWsCmds(t *testing.T) { { name: "notifyspentandmissedtickets", newCmd: func() (interface{}, error) { - return NewCmd("notifyspentandmissedtickets") + return dcrjson.NewCmd(Method("notifyspentandmissedtickets")) }, staticCmd: func() interface{} { return NewNotifySpentAndMissedTicketsCmd() @@ -64,7 +66,7 @@ func TestChainSvrWsCmds(t *testing.T) { { name: "notifynewtickets", newCmd: func() (interface{}, error) { - return NewCmd("notifynewtickets") + return dcrjson.NewCmd(Method("notifynewtickets")) }, staticCmd: func() interface{} { return NewNotifyNewTicketsCmd() @@ -75,7 +77,7 @@ func TestChainSvrWsCmds(t *testing.T) { { name: "notifystakedifficulty", newCmd: func() (interface{}, error) { - return NewCmd("notifystakedifficulty") + return dcrjson.NewCmd(Method("notifystakedifficulty")) }, staticCmd: func() interface{} { return NewNotifyStakeDifficultyCmd() @@ -86,7 +88,7 @@ func TestChainSvrWsCmds(t *testing.T) { { name: "notifyblocks", newCmd: func() (interface{}, error) { - return NewCmd("notifyblocks") + return dcrjson.NewCmd(Method("notifyblocks")) }, staticCmd: func() interface{} { return NewNotifyBlocksCmd() @@ -97,7 +99,7 @@ func TestChainSvrWsCmds(t *testing.T) { { name: "stopnotifyblocks", newCmd: func() (interface{}, error) { - return NewCmd("stopnotifyblocks") + return dcrjson.NewCmd(Method("stopnotifyblocks")) }, staticCmd: func() interface{} { return NewStopNotifyBlocksCmd() @@ -108,33 +110,33 @@ func TestChainSvrWsCmds(t *testing.T) { { name: "notifynewtransactions", newCmd: func() (interface{}, error) { - return NewCmd("notifynewtransactions") + return dcrjson.NewCmd(Method("notifynewtransactions")) }, staticCmd: func() interface{} { return NewNotifyNewTransactionsCmd(nil) }, marshalled: `{"jsonrpc":"1.0","method":"notifynewtransactions","params":[],"id":1}`, unmarshalled: &NotifyNewTransactionsCmd{ - Verbose: Bool(false), + Verbose: dcrjson.Bool(false), }, }, { name: "notifynewtransactions optional", newCmd: func() (interface{}, error) { - return NewCmd("notifynewtransactions", true) + return dcrjson.NewCmd(Method("notifynewtransactions"), true) }, staticCmd: func() interface{} { - return NewNotifyNewTransactionsCmd(Bool(true)) + return NewNotifyNewTransactionsCmd(dcrjson.Bool(true)) }, marshalled: `{"jsonrpc":"1.0","method":"notifynewtransactions","params":[true],"id":1}`, unmarshalled: &NotifyNewTransactionsCmd{ - Verbose: Bool(true), + Verbose: dcrjson.Bool(true), }, }, { name: "stopnotifynewtransactions", newCmd: func() (interface{}, error) { - return NewCmd("stopnotifynewtransactions") + return dcrjson.NewCmd(Method("stopnotifynewtransactions")) }, staticCmd: func() interface{} { return NewStopNotifyNewTransactionsCmd() @@ -145,14 +147,14 @@ func TestChainSvrWsCmds(t *testing.T) { { name: "rescan", newCmd: func() (interface{}, error) { - return NewCmd("rescan", "0000000000000000000000000000000000000000000000000000000000000123") + return dcrjson.NewCmd(Method("rescan"), []string{"0000000000000000000000000000000000000000000000000000000000000123"}) }, staticCmd: func() interface{} { - return NewRescanCmd("0000000000000000000000000000000000000000000000000000000000000123") + return NewRescanCmd([]string{"0000000000000000000000000000000000000000000000000000000000000123"}) }, - marshalled: `{"jsonrpc":"1.0","method":"rescan","params":["0000000000000000000000000000000000000000000000000000000000000123"],"id":1}`, + marshalled: `{"jsonrpc":"1.0","method":"rescan","params":[["0000000000000000000000000000000000000000000000000000000000000123"]],"id":1}`, unmarshalled: &RescanCmd{ - BlockHashes: "0000000000000000000000000000000000000000000000000000000000000123", + BlockHashes: []string{"0000000000000000000000000000000000000000000000000000000000000123"}, }, }, } @@ -161,7 +163,7 @@ func TestChainSvrWsCmds(t *testing.T) { for i, test := range tests { // Marshal the command as created by the new static command // creation function. - marshalled, err := MarshalCmd("1.0", testID, test.staticCmd()) + marshalled, err := dcrjson.MarshalCmd("1.0", testID, test.staticCmd()) if err != nil { t.Errorf("MarshalCmd #%d (%s) unexpected error: %v", i, test.name, err) @@ -179,13 +181,13 @@ func TestChainSvrWsCmds(t *testing.T) { // new command creation function. cmd, err := test.newCmd() if err != nil { - t.Errorf("Test #%d (%s) unexpected NewCmd error: %v ", + t.Errorf("Test #%d (%s) unexpected dcrjson.NewCmd error: %v ", i, test.name, err) } // Marshal the command as created by the generic new command // creation function. - marshalled, err = MarshalCmd("1.0", testID, cmd) + marshalled, err = dcrjson.MarshalCmd("1.0", testID, cmd) if err != nil { t.Errorf("MarshalCmd #%d (%s) unexpected error: %v", i, test.name, err) @@ -199,7 +201,7 @@ func TestChainSvrWsCmds(t *testing.T) { continue } - var request Request + var request dcrjson.Request if err := json.Unmarshal(marshalled, &request); err != nil { t.Errorf("Test #%d (%s) unexpected error while "+ "unmarshalling JSON-RPC request: %v", i, @@ -207,9 +209,9 @@ func TestChainSvrWsCmds(t *testing.T) { continue } - cmd, err = UnmarshalCmd(&request) + cmd, err = dcrjson.ParseParams(Method(request.Method), request.Params) if err != nil { - t.Errorf("UnmarshalCmd #%d (%s) unexpected error: %v", i, + t.Errorf("ParseParams #%d (%s) unexpected error: %v", i, test.name, err) continue } diff --git a/dcrjson/chainsvrwsntfns.go b/rpc/jsonrpc/types/chainsvrwsntfns.go similarity index 81% rename from dcrjson/chainsvrwsntfns.go rename to rpc/jsonrpc/types/chainsvrwsntfns.go index 89cecd89..8c978940 100644 --- a/dcrjson/chainsvrwsntfns.go +++ b/rpc/jsonrpc/types/chainsvrwsntfns.go @@ -6,50 +6,52 @@ // NOTE: This file is intended to house the RPC websocket notifications that are // supported by a chain server. -package dcrjson +package types + +import "github.com/decred/dcrd/dcrjson/v3" const ( // BlockConnectedNtfnMethod is the method used for notifications from // the chain server that a block has been connected. - BlockConnectedNtfnMethod = "blockconnected" + BlockConnectedNtfnMethod Method = "blockconnected" // BlockDisconnectedNtfnMethod is the method used for notifications from // the chain server that a block has been disconnected. - BlockDisconnectedNtfnMethod = "blockdisconnected" + BlockDisconnectedNtfnMethod Method = "blockdisconnected" // NewTicketsNtfnMethod is the method of the daemon newtickets notification. - NewTicketsNtfnMethod = "newtickets" + NewTicketsNtfnMethod Method = "newtickets" // ReorganizationNtfnMethod is the method used for notifications that the // block chain is in the process of a reorganization. - ReorganizationNtfnMethod = "reorganization" + ReorganizationNtfnMethod Method = "reorganization" // TxAcceptedNtfnMethod is the method used for notifications from the // chain server that a transaction has been accepted into the mempool. - TxAcceptedNtfnMethod = "txaccepted" + TxAcceptedNtfnMethod Method = "txaccepted" // TxAcceptedVerboseNtfnMethod is the method used for notifications from // the chain server that a transaction has been accepted into the // mempool. This differs from TxAcceptedNtfnMethod in that it provides // more details in the notification. - TxAcceptedVerboseNtfnMethod = "txacceptedverbose" + TxAcceptedVerboseNtfnMethod Method = "txacceptedverbose" // RelevantTxAcceptedNtfnMethod is the method used for notifications // from the chain server that inform a client that a relevant // transaction was accepted by the mempool. - RelevantTxAcceptedNtfnMethod = "relevanttxaccepted" + RelevantTxAcceptedNtfnMethod Method = "relevanttxaccepted" // SpentAndMissedTicketsNtfnMethod is the method of the daemon // spentandmissedtickets notification. - SpentAndMissedTicketsNtfnMethod = "spentandmissedtickets" + SpentAndMissedTicketsNtfnMethod Method = "spentandmissedtickets" // StakeDifficultyNtfnMethod is the method of the daemon stakedifficulty // notification. - StakeDifficultyNtfnMethod = "stakedifficulty" + StakeDifficultyNtfnMethod Method = "stakedifficulty" // WinningTicketsNtfnMethod is the method of the daemon winningtickets // notification. - WinningTicketsNtfnMethod = "winningtickets" + WinningTicketsNtfnMethod Method = "winningtickets" ) // BlockConnectedNtfn defines the blockconnected JSON-RPC notification. @@ -215,16 +217,16 @@ func NewWinningTicketsNtfn(hash string, height int32, tickets map[string]string) func init() { // The commands in this file are only usable by websockets and are // notifications. - flags := UFWebsocketOnly | UFNotification + flags := dcrjson.UFWebsocketOnly | dcrjson.UFNotification - MustRegisterCmd(BlockConnectedNtfnMethod, (*BlockConnectedNtfn)(nil), flags) - MustRegisterCmd(BlockDisconnectedNtfnMethod, (*BlockDisconnectedNtfn)(nil), flags) - MustRegisterCmd(NewTicketsNtfnMethod, (*NewTicketsNtfn)(nil), flags) - MustRegisterCmd(ReorganizationNtfnMethod, (*ReorganizationNtfn)(nil), flags) - MustRegisterCmd(TxAcceptedNtfnMethod, (*TxAcceptedNtfn)(nil), flags) - MustRegisterCmd(TxAcceptedVerboseNtfnMethod, (*TxAcceptedVerboseNtfn)(nil), flags) - MustRegisterCmd(RelevantTxAcceptedNtfnMethod, (*RelevantTxAcceptedNtfn)(nil), flags) - MustRegisterCmd(SpentAndMissedTicketsNtfnMethod, (*SpentAndMissedTicketsNtfn)(nil), flags) - MustRegisterCmd(StakeDifficultyNtfnMethod, (*StakeDifficultyNtfn)(nil), flags) - MustRegisterCmd(WinningTicketsNtfnMethod, (*WinningTicketsNtfn)(nil), flags) + dcrjson.MustRegister(BlockConnectedNtfnMethod, (*BlockConnectedNtfn)(nil), flags) + dcrjson.MustRegister(BlockDisconnectedNtfnMethod, (*BlockDisconnectedNtfn)(nil), flags) + dcrjson.MustRegister(NewTicketsNtfnMethod, (*NewTicketsNtfn)(nil), flags) + dcrjson.MustRegister(ReorganizationNtfnMethod, (*ReorganizationNtfn)(nil), flags) + dcrjson.MustRegister(TxAcceptedNtfnMethod, (*TxAcceptedNtfn)(nil), flags) + dcrjson.MustRegister(TxAcceptedVerboseNtfnMethod, (*TxAcceptedVerboseNtfn)(nil), flags) + dcrjson.MustRegister(RelevantTxAcceptedNtfnMethod, (*RelevantTxAcceptedNtfn)(nil), flags) + dcrjson.MustRegister(SpentAndMissedTicketsNtfnMethod, (*SpentAndMissedTicketsNtfn)(nil), flags) + dcrjson.MustRegister(StakeDifficultyNtfnMethod, (*StakeDifficultyNtfn)(nil), flags) + dcrjson.MustRegister(WinningTicketsNtfnMethod, (*WinningTicketsNtfn)(nil), flags) } diff --git a/dcrjson/chainsvrwsntfns_test.go b/rpc/jsonrpc/types/chainsvrwsntfns_test.go similarity index 84% rename from dcrjson/chainsvrwsntfns_test.go rename to rpc/jsonrpc/types/chainsvrwsntfns_test.go index c7d908c6..6c94c8b7 100644 --- a/dcrjson/chainsvrwsntfns_test.go +++ b/rpc/jsonrpc/types/chainsvrwsntfns_test.go @@ -3,7 +3,7 @@ // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. -package dcrjson +package types import ( "bytes" @@ -11,6 +11,8 @@ import ( "fmt" "reflect" "testing" + + "github.com/decred/dcrd/dcrjson/v3" ) // TestChainSvrWsNtfns tests all of the chain server websocket-specific @@ -30,7 +32,7 @@ func TestChainSvrWsNtfns(t *testing.T) { { name: "blockconnected", newNtfn: func() (interface{}, error) { - return NewCmd("blockconnected", "header", []string{"tx0", "tx1"}) + return dcrjson.NewCmd(Method("blockconnected"), "header", []string{"tx0", "tx1"}) }, staticNtfn: func() interface{} { return NewBlockConnectedNtfn("header", []string{"tx0", "tx1"}) @@ -44,7 +46,7 @@ func TestChainSvrWsNtfns(t *testing.T) { { name: "blockdisconnected", newNtfn: func() (interface{}, error) { - return NewCmd("blockdisconnected", "header") + return dcrjson.NewCmd(Method("blockdisconnected"), "header") }, staticNtfn: func() interface{} { return NewBlockDisconnectedNtfn("header") @@ -57,7 +59,7 @@ func TestChainSvrWsNtfns(t *testing.T) { { name: "newtickets", newNtfn: func() (interface{}, error) { - return NewCmd("newtickets", "123", 100, 3, []string{"a", "b"}) + return dcrjson.NewCmd(Method("newtickets"), "123", 100, 3, []string{"a", "b"}) }, staticNtfn: func() interface{} { return NewNewTicketsNtfn("123", 100, 3, []string{"a", "b"}) @@ -73,7 +75,7 @@ func TestChainSvrWsNtfns(t *testing.T) { { name: "relevanttxaccepted", newNtfn: func() (interface{}, error) { - return NewCmd("relevanttxaccepted", "001122") + return dcrjson.NewCmd(Method("relevanttxaccepted"), "001122") }, staticNtfn: func() interface{} { return NewRelevantTxAcceptedNtfn("001122") @@ -86,7 +88,7 @@ func TestChainSvrWsNtfns(t *testing.T) { { name: "spentandmissedtickets", newNtfn: func() (interface{}, error) { - return NewCmd("spentandmissedtickets", "123", 100, 3, map[string]string{"a": "b"}) + return dcrjson.NewCmd(Method("spentandmissedtickets"), "123", 100, 3, map[string]string{"a": "b"}) }, staticNtfn: func() interface{} { return NewSpentAndMissedTicketsNtfn("123", 100, 3, map[string]string{"a": "b"}) @@ -102,7 +104,7 @@ func TestChainSvrWsNtfns(t *testing.T) { { name: "txaccepted", newNtfn: func() (interface{}, error) { - return NewCmd("txaccepted", "123", 1.5) + return dcrjson.NewCmd(Method("txaccepted"), "123", 1.5) }, staticNtfn: func() interface{} { return NewTxAcceptedNtfn("123", 1.5) @@ -116,7 +118,7 @@ func TestChainSvrWsNtfns(t *testing.T) { { name: "txacceptedverbose", newNtfn: func() (interface{}, error) { - return NewCmd("txacceptedverbose", `{"hex":"001122","txid":"123","version":1,"locktime":4294967295,"vin":null,"vout":null,"confirmations":0}`) + return dcrjson.NewCmd(Method("txacceptedverbose"), `{"hex":"001122","txid":"123","version":1,"locktime":4294967295,"vin":null,"vout":null,"confirmations":0}`) }, staticNtfn: func() interface{} { txResult := TxRawResult{ @@ -146,7 +148,7 @@ func TestChainSvrWsNtfns(t *testing.T) { { name: "winningtickets", newNtfn: func() (interface{}, error) { - return NewCmd("winningtickets", "123", 100, map[string]string{"a": "b"}) + return dcrjson.NewCmd(Method("winningtickets"), "123", 100, map[string]string{"a": "b"}) }, staticNtfn: func() interface{} { return NewWinningTicketsNtfn("123", 100, map[string]string{"a": "b"}) @@ -164,7 +166,7 @@ func TestChainSvrWsNtfns(t *testing.T) { for i, test := range tests { // Marshal the notification as created by the new static // creation function. The ID is nil for notifications. - marshalled, err := MarshalCmd("1.0", nil, test.staticNtfn()) + marshalled, err := dcrjson.MarshalCmd("1.0", nil, test.staticNtfn()) if err != nil { t.Errorf("MarshalCmd #%d (%s) unexpected error: %v", i, test.name, err) @@ -182,14 +184,14 @@ func TestChainSvrWsNtfns(t *testing.T) { // generic new notification creation function. cmd, err := test.newNtfn() if err != nil { - t.Errorf("Test #%d (%s) unexpected NewCmd error: %v ", + t.Errorf("Test #%d (%s) unexpected dcrjson.NewCmd error: %v ", i, test.name, err) } // Marshal the notification as created by the generic new // notification creation function. The ID is nil for // notifications. - marshalled, err = MarshalCmd("1.0", nil, cmd) + marshalled, err = dcrjson.MarshalCmd("1.0", nil, cmd) if err != nil { t.Errorf("MarshalCmd #%d (%s) unexpected error: %v", i, test.name, err) @@ -203,7 +205,7 @@ func TestChainSvrWsNtfns(t *testing.T) { continue } - var request Request + var request dcrjson.Request if err := json.Unmarshal(marshalled, &request); err != nil { t.Errorf("Test #%d (%s) unexpected error while "+ "unmarshalling JSON-RPC request: %v", i, @@ -211,9 +213,9 @@ func TestChainSvrWsNtfns(t *testing.T) { continue } - cmd, err = UnmarshalCmd(&request) + cmd, err = dcrjson.ParseParams(Method(request.Method), request.Params) if err != nil { - t.Errorf("UnmarshalCmd #%d (%s) unexpected error: %v", i, + t.Errorf("ParseParams #%d (%s) unexpected error: %v", i, test.name, err) continue } diff --git a/dcrjson/chainsvrwsresults.go b/rpc/jsonrpc/types/chainsvrwsresults.go similarity index 97% rename from dcrjson/chainsvrwsresults.go rename to rpc/jsonrpc/types/chainsvrwsresults.go index 53e76805..85879262 100644 --- a/dcrjson/chainsvrwsresults.go +++ b/rpc/jsonrpc/types/chainsvrwsresults.go @@ -3,7 +3,7 @@ // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. -package dcrjson +package types // SessionResult models the data from the session command. type SessionResult struct { diff --git a/rpc/jsonrpc/types/go.mod b/rpc/jsonrpc/types/go.mod new file mode 100644 index 00000000..15ed3370 --- /dev/null +++ b/rpc/jsonrpc/types/go.mod @@ -0,0 +1,7 @@ +module github.com/decred/dcrd/rpc/jsonrpc/types + +go 1.11 + +require github.com/decred/dcrd/dcrjson/v3 v3.0.0 + +replace github.com/decred/dcrd/dcrjson/v3 => ../../../dcrjson diff --git a/rpc/jsonrpc/types/go.sum b/rpc/jsonrpc/types/go.sum new file mode 100644 index 00000000..b3399742 --- /dev/null +++ b/rpc/jsonrpc/types/go.sum @@ -0,0 +1,8 @@ +github.com/dchest/blake256 v1.0.0 h1:6gUgI5MHdz9g0TdrgKqXsoDX+Zjxmm1Sc6OsoGru50I= +github.com/dchest/blake256 v1.0.0/go.mod h1:xXNWCE1jsAP8DAjP+rKw2MbeqLczjI3TRx2VK+9OEYY= +github.com/decred/dcrd v1.3.0 h1:EEXm7BdiROfazDtuFsOu9mfotnyy00bgCuVwUqaszFo= +github.com/decred/dcrd/chaincfg/chainhash v1.0.1 h1:0vG7U9+dSjSCaHQKdoSKURK2pOb47+b+8FK5q4+Je7M= +github.com/decred/dcrd/chaincfg/chainhash v1.0.1/go.mod h1:OVfvaOsNLS/A1y4Eod0Ip/Lf8qga7VXCQjUQLbkY0Go= +github.com/decred/dcrd/dcrjson v1.2.0 h1:3BFFQHq3/YO/zae9WLxQkXsX6AXKx3+M8H3yk4oXZi0= +github.com/decred/dcrd/dcrjson/v2 v2.0.0 h1:W0q4Alh36c5N318eUpfmU8kXoCNgImMLI87NIXni9Us= +github.com/decred/dcrd/dcrjson/v2 v2.0.0/go.mod h1:FYueNy8BREAFq04YNEwcTsmGFcNqY+ehUUO81w2igi4= diff --git a/rpc/jsonrpc/types/helpers.go b/rpc/jsonrpc/types/helpers.go new file mode 100644 index 00000000..884ab928 --- /dev/null +++ b/rpc/jsonrpc/types/helpers.go @@ -0,0 +1,10 @@ +package types + +// EstimateSmartFeeModeAddr is a helper routine that allocates a new +// EstimateSmartFeeMode value to store v and returns a pointer to it. This is +// useful when assigning optional parameters. +func EstimateSmartFeeModeAddr(v EstimateSmartFeeMode) *EstimateSmartFeeMode { + p := new(EstimateSmartFeeMode) + *p = v + return p +} diff --git a/rpc/jsonrpc/types/method.go b/rpc/jsonrpc/types/method.go new file mode 100644 index 00000000..412370c5 --- /dev/null +++ b/rpc/jsonrpc/types/method.go @@ -0,0 +1,8 @@ +// Copyright (c) 2019 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package types + +// Method is the type used to register method and parameter pairs with dcrjson. +type Method string diff --git a/rpcserver.go b/rpcserver.go index c43a89ab..73fe0136 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -42,10 +42,11 @@ import ( "github.com/decred/dcrd/chaincfg/chainhash" "github.com/decred/dcrd/database" "github.com/decred/dcrd/dcrec/secp256k1" - "github.com/decred/dcrd/dcrjson/v2" + "github.com/decred/dcrd/dcrjson/v3" "github.com/decred/dcrd/dcrutil" "github.com/decred/dcrd/internal/version" "github.com/decred/dcrd/mempool/v2" + "github.com/decred/dcrd/rpc/jsonrpc/types" "github.com/decred/dcrd/txscript" "github.com/decred/dcrd/wire" "github.com/jrick/bitset" @@ -53,9 +54,9 @@ import ( // API version constants const ( - jsonrpcSemverString = "5.1.0" - jsonrpcSemverMajor = 5 - jsonrpcSemverMinor = 1 + jsonrpcSemverString = "6.0.0" + jsonrpcSemverMajor = 6 + jsonrpcSemverMinor = 0 jsonrpcSemverPatch = 0 ) @@ -123,7 +124,7 @@ var ( // in the coinbase signature script. It is declared here to avoid the // overhead of creating a new object on every invocation for constant // data. - gbtCoinbaseAux = &dcrjson.GetBlockTemplateResultAux{ + gbtCoinbaseAux = &types.GetBlockTemplateResultAux{ Flags: hex.EncodeToString(builderScript(txscript. NewScriptBuilder().AddData([]byte(coinbaseFlags)))), } @@ -164,8 +165,8 @@ type commandHandler func(*rpcServer, interface{}, <-chan struct{}) (interface{}, // rpcHandlers maps RPC command strings to appropriate handler functions. // This is set by init because help references rpcHandlers and thus causes // a dependency loop. -var rpcHandlers map[string]commandHandler -var rpcHandlersBeforeInit = map[string]commandHandler{ +var rpcHandlers map[types.Method]commandHandler +var rpcHandlersBeforeInit = map[types.Method]commandHandler{ "addnode": handleAddNode, "createrawsstx": handleCreateRawSStx, "createrawssrtx": handleCreateRawSSRtx, @@ -489,7 +490,7 @@ func handleAskWallet(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) ( // handleAddNode handles addnode commands. func handleAddNode(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - c := cmd.(*dcrjson.AddNodeCmd) + c := cmd.(*types.AddNodeCmd) addr := normalizeAddress(c.Addr, activeNetParams.DefaultPort) var err error @@ -514,7 +515,7 @@ func handleAddNode(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (in // handleNode handles node commands. func handleNode(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - c := cmd.(*dcrjson.NodeCmd) + c := cmd.(*types.NodeCmd) var addr string var nodeID uint64 @@ -617,7 +618,7 @@ func messageToHex(msg wire.Message) (string, error) { // handleCreateRawTransaction handles createrawtransaction commands. func handleCreateRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - c := cmd.(*dcrjson.CreateRawTransactionCmd) + c := cmd.(*types.CreateRawTransactionCmd) // Validate expiry, if given. if c.Expiry != nil && *c.Expiry < 0 { @@ -733,7 +734,7 @@ func handleCreateRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan // handleCreateRawSStx handles createrawsstx commands. func handleCreateRawSStx(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - c := cmd.(*dcrjson.CreateRawSStxCmd) + c := cmd.(*types.CreateRawSStxCmd) // Basic sanity checks for the information coming from the cmd. if len(c.Inputs) != len(c.COuts) { @@ -942,7 +943,7 @@ func handleCreateRawSStx(s *rpcServer, cmd interface{}, closeChan <-chan struct{ // handleCreateRawSSRtx handles createrawssrtx commands. func handleCreateRawSSRtx(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - c := cmd.(*dcrjson.CreateRawSSRtxCmd) + c := cmd.(*types.CreateRawSSRtxCmd) // Only a single SStx should be given if len(c.Inputs) != 1 { @@ -1077,7 +1078,7 @@ func handleCreateRawSSRtx(s *rpcServer, cmd interface{}, closeChan <-chan struct // handleDebugLevel handles debuglevel commands. func handleDebugLevel(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - c := cmd.(*dcrjson.DebugLevelCmd) + c := cmd.(*types.DebugLevelCmd) // Special show command to list supported subsystems. if c.LevelSpec == "show" { @@ -1096,9 +1097,9 @@ func handleDebugLevel(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) // createVinList returns a slice of JSON objects for the inputs of the passed // transaction. -func createVinList(mtx *wire.MsgTx) []dcrjson.Vin { +func createVinList(mtx *wire.MsgTx) []types.Vin { // Coinbase transactions only have a single txin by definition. - vinList := make([]dcrjson.Vin, len(mtx.TxIn)) + vinList := make([]types.Vin, len(mtx.TxIn)) if blockchain.IsCoinBaseTx(mtx) { txIn := mtx.TxIn[0] vinEntry := &vinList[0] @@ -1139,7 +1140,7 @@ func createVinList(mtx *wire.MsgTx) []dcrjson.Vin { vinEntry.AmountIn = dcrutil.Amount(txIn.ValueIn).ToCoin() vinEntry.BlockHeight = txIn.BlockHeight vinEntry.BlockIndex = txIn.BlockIndex - vinEntry.ScriptSig = &dcrjson.ScriptSig{ + vinEntry.ScriptSig = &types.ScriptSig{ Asm: disbuf, Hex: hex.EncodeToString(txIn.SignatureScript), } @@ -1150,10 +1151,10 @@ func createVinList(mtx *wire.MsgTx) []dcrjson.Vin { // createVoutList returns a slice of JSON objects for the outputs of the passed // transaction. -func createVoutList(mtx *wire.MsgTx, chainParams *chaincfg.Params, filterAddrMap map[string]struct{}) []dcrjson.Vout { +func createVoutList(mtx *wire.MsgTx, chainParams *chaincfg.Params, filterAddrMap map[string]struct{}) []types.Vout { txType := stake.DetermineTxType(mtx) - voutList := make([]dcrjson.Vout, 0, len(mtx.TxOut)) + voutList := make([]types.Vout, 0, len(mtx.TxOut)) for i, v := range mtx.TxOut { // The disassembled string will contain [error] inline if the // script doesn't fully parse, so ignore the error here. @@ -1218,7 +1219,7 @@ func createVoutList(mtx *wire.MsgTx, chainParams *chaincfg.Params, filterAddrMap continue } - var vout dcrjson.Vout + var vout types.Vout voutSPK := &vout.ScriptPubKey vout.N = uint32(i) vout.Value = dcrutil.Amount(v.Value).ToCoin() @@ -1240,7 +1241,7 @@ func createVoutList(mtx *wire.MsgTx, chainParams *chaincfg.Params, filterAddrMap // createTxRawResult converts the passed transaction and associated parameters // to a raw transaction JSON object. -func createTxRawResult(chainParams *chaincfg.Params, mtx *wire.MsgTx, txHash string, blkIdx uint32, blkHeader *wire.BlockHeader, blkHash string, blkHeight int64, confirmations int64) (*dcrjson.TxRawResult, error) { +func createTxRawResult(chainParams *chaincfg.Params, mtx *wire.MsgTx, txHash string, blkIdx uint32, blkHeader *wire.BlockHeader, blkHash string, blkHeight int64, confirmations int64) (*types.TxRawResult, error) { mtxHex, err := messageToHex(mtx) if err != nil { return nil, err @@ -1251,7 +1252,7 @@ func createTxRawResult(chainParams *chaincfg.Params, mtx *wire.MsgTx, txHash str "expected %v", txHash, mtx.TxHash()) } - txReply := &dcrjson.TxRawResult{ + txReply := &types.TxRawResult{ Hex: mtxHex, Txid: txHash, Vin: createVinList(mtx), @@ -1276,7 +1277,7 @@ func createTxRawResult(chainParams *chaincfg.Params, mtx *wire.MsgTx, txHash str // handleDecodeRawTransaction handles decoderawtransaction commands. func handleDecodeRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - c := cmd.(*dcrjson.DecodeRawTransactionCmd) + c := cmd.(*types.DecodeRawTransactionCmd) // Deserialize the transaction. hexStr := c.HexTx @@ -1295,7 +1296,7 @@ func handleDecodeRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan } // Create and return the result. - txReply := dcrjson.TxRawDecodeResult{ + txReply := types.TxRawDecodeResult{ Txid: mtx.TxHash().String(), Version: int32(mtx.Version), Locktime: mtx.LockTime, @@ -1308,7 +1309,7 @@ func handleDecodeRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan // handleDecodeScript handles decodescript commands. func handleDecodeScript(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - c := cmd.(*dcrjson.DecodeScriptCmd) + c := cmd.(*types.DecodeScriptCmd) // Convert the hex script to bytes. hexStr := c.HexScript @@ -1348,7 +1349,7 @@ func handleDecodeScript(s *rpcServer, cmd interface{}, closeChan <-chan struct{} } // Generate and return the reply. - reply := dcrjson.DecodeScriptResult{ + reply := types.DecodeScriptResult{ Asm: disbuf, ReqSigs: int32(reqSigs), Type: scriptClass.String(), @@ -1372,14 +1373,14 @@ func handleEstimateFee(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) // The default estimation mode when unset is assumed as "conservative". As of // 2018-12, the only supported mode is "conservative". func handleEstimateSmartFee(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - c := cmd.(*dcrjson.EstimateSmartFeeCmd) + c := cmd.(*types.EstimateSmartFeeCmd) - mode := dcrjson.EstimateSmartFeeConservative + mode := types.EstimateSmartFeeConservative if c.Mode != nil { mode = *c.Mode } - if mode != dcrjson.EstimateSmartFeeConservative { + if mode != types.EstimateSmartFeeConservative { return nil, rpcInvalidError("Only the default and conservative modes " + "are supported for smart fee estimation at the moment") } @@ -1394,7 +1395,7 @@ func handleEstimateSmartFee(s *rpcServer, cmd interface{}, closeChan <-chan stru // handleEstimateStakeDiff implements the estimatestakediff command. func handleEstimateStakeDiff(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - c := cmd.(*dcrjson.EstimateStakeDiffCmd) + c := cmd.(*types.EstimateStakeDiffCmd) // Minimum possible stake difficulty. chain := s.server.chain @@ -1452,7 +1453,7 @@ func handleEstimateStakeDiff(s *rpcServer, cmd interface{}, closeChan <-chan str userEstFltPtr = &userEstFlt } - return &dcrjson.EstimateStakeDiffResult{ + return &types.EstimateStakeDiffResult{ Min: dcrutil.Amount(min).ToCoin(), Max: dcrutil.Amount(max).ToCoin(), Expected: dcrutil.Amount(expected).ToCoin(), @@ -1468,7 +1469,7 @@ func handleExistsAddress(s *rpcServer, cmd interface{}, closeChan <-chan struct{ "Configuration") } - c := cmd.(*dcrjson.ExistsAddressCmd) + c := cmd.(*types.ExistsAddressCmd) // Attempt to decode the supplied address. addr, err := dcrutil.DecodeAddress(c.Address) @@ -1493,7 +1494,7 @@ func handleExistsAddresses(s *rpcServer, cmd interface{}, closeChan <-chan struc "Configuration") } - c := cmd.(*dcrjson.ExistsAddressesCmd) + c := cmd.(*types.ExistsAddressesCmd) addresses := make([]dcrutil.Address, len(c.Addresses)) for i := range c.Addresses { // Attempt to decode the supplied address. @@ -1521,11 +1522,38 @@ func handleExistsAddresses(s *rpcServer, cmd interface{}, closeChan <-chan struc return hex.EncodeToString([]byte(set)), nil } +func decodeHashes(strs []string) ([]chainhash.Hash, error) { + hashes := make([]chainhash.Hash, len(strs)) + for i, s := range strs { + l, err := hex.Decode(hashes[i][:], []byte(s)) + if err != nil || l != 32 { + return nil, rpcDecodeHexError(s) + } + // unreverse hash string bytes + for j := 0; j < 16; j++ { + hashes[i][j], hashes[i][31-j] = hashes[i][31-j], hashes[i][j] + } + } + return hashes, nil +} + +func decodeHashPointers(strs []string) ([]*chainhash.Hash, error) { + hashes := make([]*chainhash.Hash, len(strs)) + for i, s := range strs { + h, err := chainhash.NewHashFromStr(s) + if err != nil { + return nil, rpcDecodeHexError(s) + } + hashes[i] = h + } + return hashes, nil +} + // handleExistsMissedTickets implements the existsmissedtickets command. func handleExistsMissedTickets(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - c := cmd.(*dcrjson.ExistsMissedTicketsCmd) + c := cmd.(*types.ExistsMissedTicketsCmd) - hashes, err := dcrjson.DecodeConcatenatedHashes(c.TxHashBlob) + hashes, err := decodeHashes(c.TxHashes) if err != nil { return nil, err } @@ -1549,9 +1577,9 @@ func handleExistsMissedTickets(s *rpcServer, cmd interface{}, closeChan <-chan s // handleExistsExpiredTickets implements the existsexpiredtickets command. func handleExistsExpiredTickets(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - c := cmd.(*dcrjson.ExistsExpiredTicketsCmd) + c := cmd.(*types.ExistsExpiredTicketsCmd) - hashes, err := dcrjson.DecodeConcatenatedHashes(c.TxHashBlob) + hashes, err := decodeHashes(c.TxHashes) if err != nil { return nil, err } @@ -1575,7 +1603,7 @@ func handleExistsExpiredTickets(s *rpcServer, cmd interface{}, closeChan <-chan // handleExistsLiveTicket implements the existsliveticket command. func handleExistsLiveTicket(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - c := cmd.(*dcrjson.ExistsLiveTicketCmd) + c := cmd.(*types.ExistsLiveTicketCmd) hash, err := chainhash.NewHashFromStr(c.TxHash) if err != nil { @@ -1587,9 +1615,9 @@ func handleExistsLiveTicket(s *rpcServer, cmd interface{}, closeChan <-chan stru // handleExistsLiveTickets implements the existslivetickets command. func handleExistsLiveTickets(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - c := cmd.(*dcrjson.ExistsLiveTicketsCmd) + c := cmd.(*types.ExistsLiveTicketsCmd) - hashes, err := dcrjson.DecodeConcatenatedHashes(c.TxHashBlob) + hashes, err := decodeHashes(c.TxHashes) if err != nil { return nil, err } @@ -1613,37 +1641,22 @@ func handleExistsLiveTickets(s *rpcServer, cmd interface{}, closeChan <-chan str // handleExistsMempoolTxs implements the existsmempooltxs command. func handleExistsMempoolTxs(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - c := cmd.(*dcrjson.ExistsMempoolTxsCmd) + c := cmd.(*types.ExistsMempoolTxsCmd) - txHashBlob, err := hex.DecodeString(c.TxHashBlob) + hashes, err := decodeHashPointers(c.TxHashes) if err != nil { - return nil, rpcDecodeHexError(c.TxHashBlob) - } - - // It needs to be an exact number of hashes. - if len(txHashBlob)%32 != 0 { - return nil, rpcInvalidError("Invalid hash blob length") - } - - hashesLen := len(txHashBlob) / 32 - hashes := make([]*chainhash.Hash, hashesLen) - for i := 0; i < hashesLen; i++ { - hashes[i], err = chainhash.NewHash( - txHashBlob[i*chainhash.HashSize : (i+1)*chainhash.HashSize]) - if err != nil { - return nil, rpcInternalError(err.Error(), "New hash") - } + return nil, err } exists := s.server.txMemPool.HaveTransactions(hashes) - if len(exists) != hashesLen { + if len(exists) != len(hashes) { return nil, rpcInternalError(fmt.Sprintf("got %v, want %v", - len(exists), hashesLen), + len(exists), len(hashes)), "Invalid mempool Tx ticket count") } // Convert the slice of bools into a compacted set of bit flags. - set := bitset.NewBytes(hashesLen) + set := bitset.NewBytes(len(hashes)) for i := range exists { if exists[i] { set.Set(i) @@ -1662,7 +1675,7 @@ func handleGenerate(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i "via --miningaddr", "Configuration") } - c := cmd.(*dcrjson.GenerateCmd) + c := cmd.(*types.GenerateCmd) // Respond with an error if the client is requesting 0 blocks to be generated. if c.NumBlocks == 0 { @@ -1689,7 +1702,7 @@ func handleGenerate(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i // handleGetAddedNodeInfo handles getaddednodeinfo commands. func handleGetAddedNodeInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - c := cmd.(*dcrjson.GetAddedNodeInfoCmd) + c := cmd.(*types.GetAddedNodeInfoCmd) // Retrieve a list of persistent (added) peers from the Decred server // and filter the list of peers per the specified address (if any). @@ -1719,11 +1732,11 @@ func handleGetAddedNodeInfo(s *rpcServer, cmd interface{}, closeChan <-chan stru // With the dns flag, the result is an array of JSON objects which // include the result of DNS lookups for each peer. - results := make([]*dcrjson.GetAddedNodeInfoResult, 0, len(peers)) + results := make([]*types.GetAddedNodeInfoResult, 0, len(peers)) for _, peer := range peers { // Set the "address" of the peer which could be an ip address // or a domain name. - var result dcrjson.GetAddedNodeInfoResult + var result types.GetAddedNodeInfoResult result.AddedNode = peer.Addr() result.Connected = dcrjson.Bool(peer.Connected()) @@ -1750,10 +1763,10 @@ func handleGetAddedNodeInfo(s *rpcServer, cmd interface{}, closeChan <-chan stru } // Add the addresses and connection info to the result. - addrs := make([]dcrjson.GetAddedNodeInfoResultAddr, 0, + addrs := make([]types.GetAddedNodeInfoResultAddr, 0, len(ipList)) for _, ip := range ipList { - var addr dcrjson.GetAddedNodeInfoResultAddr + var addr types.GetAddedNodeInfoResultAddr addr.Address = ip addr.Connected = "false" if ip == host && peer.Connected() { @@ -1772,7 +1785,7 @@ func handleGetBestBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{} // All other "get block" commands give either the height, the hash, or // both but require the block SHA. This gets both for the best block. best := s.chain.BestSnapshot() - result := &dcrjson.GetBestBlockResult{ + result := &types.GetBestBlockResult{ Hash: best.Hash.String(), Height: best.Height, } @@ -1807,7 +1820,7 @@ func getDifficultyRatio(bits uint32) float64 { // handleGetBlock implements the getblock command. func handleGetBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - c := cmd.(*dcrjson.GetBlockCmd) + c := cmd.(*types.GetBlockCmd) // Load the raw block bytes from the database. hash, err := chainhash.NewHashFromStr(c.Hash) @@ -1859,7 +1872,7 @@ func handleGetBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i } sbitsFloat := float64(blockHeader.SBits) / dcrutil.AtomsPerCoin - blockReply := dcrjson.GetBlockVerboseResult{ + blockReply := types.GetBlockVerboseResult{ Hash: c.Hash, Version: blockHeader.Version, MerkleRoot: blockHeader.MerkleRoot.String(), @@ -1903,7 +1916,7 @@ func handleGetBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i blockReply.STx = stxNames } else { txns := blk.Transactions() - rawTxns := make([]dcrjson.TxRawResult, len(txns)) + rawTxns := make([]types.TxRawResult, len(txns)) for i, tx := range txns { rawTxn, err := createTxRawResult(s.server.chainParams, tx.MsgTx(), tx.Hash().String(), uint32(i), @@ -1918,7 +1931,7 @@ func handleGetBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i blockReply.RawTx = rawTxns stxns := blk.STransactions() - rawSTxns := make([]dcrjson.TxRawResult, len(stxns)) + rawSTxns := make([]types.TxRawResult, len(stxns)) for i, tx := range stxns { rawSTxn, err := createTxRawResult(s.server.chainParams, tx.MsgTx(), tx.Hash().String(), uint32(i), @@ -1962,11 +1975,11 @@ func handleGetBlockchainInfo(s *rpcServer, cmd interface{}, closeChan <-chan str // Fetch the agendas of the consensus deployments as well as their // threshold states and state activation heights. - dInfo := make(map[string]dcrjson.AgendaInfo) + dInfo := make(map[string]types.AgendaInfo) params := s.server.chainParams for version, deployments := range params.Deployments { for _, agenda := range deployments { - aInfo := dcrjson.AgendaInfo{ + aInfo := types.AgendaInfo{ StartTime: agenda.StartTime, ExpireTime: agenda.ExpireTime, } @@ -1994,7 +2007,7 @@ func handleGetBlockchainInfo(s *rpcServer, cmd interface{}, closeChan <-chan str } // Generate rpc response. - response := dcrjson.GetBlockChainInfoResult{ + response := types.GetBlockChainInfoResult{ Chain: params.Name, Blocks: best.Height, Headers: best.Height, @@ -2020,7 +2033,7 @@ func handleGetBlockCount(s *rpcServer, cmd interface{}, closeChan <-chan struct{ // handleGetBlockHash implements the getblockhash command. func handleGetBlockHash(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - c := cmd.(*dcrjson.GetBlockHashCmd) + c := cmd.(*types.GetBlockHashCmd) hash, err := s.chain.BlockHashByHeight(c.Index) if err != nil { return nil, &dcrjson.RPCError{ @@ -2035,7 +2048,7 @@ func handleGetBlockHash(s *rpcServer, cmd interface{}, closeChan <-chan struct{} // handleGetBlockHeader implements the getblockheader command. func handleGetBlockHeader(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - c := cmd.(*dcrjson.GetBlockHeaderCmd) + c := cmd.(*types.GetBlockHeaderCmd) // Fetch the header from chain. hash, err := chainhash.NewHashFromStr(c.Hash) @@ -2088,7 +2101,7 @@ func handleGetBlockHeader(s *rpcServer, cmd interface{}, closeChan <-chan struct confirmations = 1 + best.Height - height } - blockHeaderReply := dcrjson.GetBlockHeaderVerboseResult{ + blockHeaderReply := types.GetBlockHeaderVerboseResult{ Hash: c.Hash, Confirmations: confirmations, Version: blockHeader.Version, @@ -2120,7 +2133,7 @@ func handleGetBlockHeader(s *rpcServer, cmd interface{}, closeChan <-chan struct // handleGetBlockSubsidy implements the getblocksubsidy command. func handleGetBlockSubsidy(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - c := cmd.(*dcrjson.GetBlockSubsidyCmd) + c := cmd.(*types.GetBlockSubsidyCmd) height := c.Height voters := c.Voters @@ -2138,7 +2151,7 @@ func handleGetBlockSubsidy(s *rpcServer, cmd interface{}, closeChan <-chan struc s.server.chainParams) total := dev + pos + pow - rep := dcrjson.GetBlockSubsidyResult{ + rep := types.GetBlockSubsidyResult{ Developer: dev, PoS: pos, PoW: pow, @@ -2432,11 +2445,11 @@ func (state *gbtWorkState) updateBlockTemplate(s *rpcServer, useCoinbaseValue bo } // blockTemplateResult returns the current block template associated with the -// state as a dcrjson.GetBlockTemplateResult that is ready to be encoded to +// state as a types.GetBlockTemplateResult that is ready to be encoded to // JSON and returned to the caller. // // This function MUST be called with the state locked. -func (state *gbtWorkState) blockTemplateResult(bm *blockManager, useCoinbaseValue bool, submitOld *bool) (*dcrjson.GetBlockTemplateResult, error) { +func (state *gbtWorkState) blockTemplateResult(bm *blockManager, useCoinbaseValue bool, submitOld *bool) (*types.GetBlockTemplateResult, error) { // Ensure the timestamps are still in valid range for the template. // This should really only ever happen if the local clock is changed // after the template is generated, but it's important to avoid serving @@ -2461,7 +2474,7 @@ func (state *gbtWorkState) blockTemplateResult(bm *blockManager, useCoinbaseValu // transaction. The result does not include the coinbase, so notice // the adjustments to the various lengths and indices. numTx := len(msgBlock.Transactions) - transactions := make([]dcrjson.GetBlockTemplateResultTx, 0, numTx-1) + transactions := make([]types.GetBlockTemplateResultTx, 0, numTx-1) txIndex := make(map[chainhash.Hash]int64, numTx) for i, tx := range msgBlock.Transactions { txHash := tx.TxHashFull() @@ -2511,7 +2524,7 @@ func (state *gbtWorkState) blockTemplateResult(bm *blockManager, useCoinbaseValu fee := template.Fees[i] sigOps := template.SigOpCounts[i] - resultTx := dcrjson.GetBlockTemplateResultTx{ + resultTx := types.GetBlockTemplateResultTx{ Data: hex.EncodeToString(txBuf.Bytes()), Hash: txHash.String(), Depends: depends, @@ -2525,7 +2538,7 @@ func (state *gbtWorkState) blockTemplateResult(bm *blockManager, useCoinbaseValu // Convert each stake transaction in the block template to a template // result transaction. numSTx := len(msgBlock.STransactions) - stransactions := make([]dcrjson.GetBlockTemplateResultTx, 0, numSTx) + stransactions := make([]types.GetBlockTemplateResultTx, 0, numSTx) stxIndex := make(map[chainhash.Hash]int64, numSTx) for i, stx := range msgBlock.STransactions { stxHash := stx.TxHashFull() @@ -2568,7 +2581,7 @@ func (state *gbtWorkState) blockTemplateResult(bm *blockManager, useCoinbaseValu fee := template.Fees[i+len(msgBlock.Transactions)] sigOps := template.SigOpCounts[i+len(msgBlock.Transactions)] - resultTx := dcrjson.GetBlockTemplateResultTx{ + resultTx := types.GetBlockTemplateResultTx{ Data: hex.EncodeToString(txBuf.Bytes()), Hash: stxHash.String(), Depends: depends, @@ -2600,7 +2613,7 @@ func (state *gbtWorkState) blockTemplateResult(bm *blockManager, useCoinbaseValu // Omitting CoinbaseTxn -> coinbase, generation targetDifficulty := fmt.Sprintf("%064x", blockchain.CompactToBig(header.Bits)) templateID := encodeTemplateID(state.prevHash, state.lastGenerated) - reply := dcrjson.GetBlockTemplateResult{ + reply := types.GetBlockTemplateResult{ Header: hex.EncodeToString(headerBytes), SigOpLimit: blockchain.MaxSigOpsPerBlock, SizeLimit: maxBlockSize, @@ -2638,7 +2651,7 @@ func (state *gbtWorkState) blockTemplateResult(bm *blockManager, useCoinbaseValu return nil, rpcInternalError(err.Error(), context) } - resultTx := dcrjson.GetBlockTemplateResultTx{ + resultTx := types.GetBlockTemplateResultTx{ Data: hex.EncodeToString(txBuf.Bytes()), Hash: tx.TxHash().String(), Depends: []int64{}, @@ -2757,7 +2770,7 @@ func handleGetBlockTemplateLongPoll(s *rpcServer, longPollID string, useCoinbase // in regards to whether or not it supports creating its own coinbase (the // coinbasetxn and coinbasevalue capabilities) and modifies the returned block // template accordingly. -func handleGetBlockTemplateRequest(s *rpcServer, request *dcrjson.TemplateRequest, closeChan <-chan struct{}) (interface{}, error) { +func handleGetBlockTemplateRequest(s *rpcServer, request *types.TemplateRequest, closeChan <-chan struct{}) (interface{}, error) { // Extract the relevant passed capabilities and restrict the result to // either a coinbase value or a coinbase transaction object depending // on the request. Default to only providing a coinbase value. @@ -2925,7 +2938,7 @@ func chainErrToGBTErrString(err error) string { // deals with block proposals. // // See https://en.bitcoin.it/wiki/BIP_0023 for more details. -func handleGetBlockTemplateProposal(s *rpcServer, request *dcrjson.TemplateRequest) (interface{}, error) { +func handleGetBlockTemplateProposal(s *rpcServer, request *types.TemplateRequest) (interface{}, error) { hexData := request.Data if hexData == "" { return false, rpcInvalidError("Data must contain the " + @@ -2990,7 +3003,7 @@ func handleGetBlockTemplate(s *rpcServer, cmd interface{}, closeChan <-chan stru "via --miningaddr", "Configuration") } - c := cmd.(*dcrjson.GetBlockTemplateCmd) + c := cmd.(*types.GetBlockTemplateCmd) request := c.Request // Set the default mode and override it if supplied. @@ -3012,9 +3025,9 @@ func handleGetBlockTemplate(s *rpcServer, cmd interface{}, closeChan <-chan stru // handleGetChainTips implements the getchaintips command. func handleGetChainTips(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { chainTips := s.chain.ChainTips() - result := make([]dcrjson.GetChainTipsResult, 0, len(chainTips)) + result := make([]types.GetChainTipsResult, 0, len(chainTips)) for _, tip := range chainTips { - result = append(result, dcrjson.GetChainTipsResult{ + result = append(result, types.GetChainTipsResult{ Height: tip.Height, Hash: tip.Hash.String(), BranchLen: tip.BranchLen, @@ -3064,7 +3077,7 @@ func handleGetCFilter(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) } } - c := cmd.(*dcrjson.GetCFilterCmd) + c := cmd.(*types.GetCFilterCmd) hash, err := chainhash.NewHashFromStr(c.Hash) if err != nil { return nil, rpcDecodeHexError(c.Hash) @@ -3107,7 +3120,7 @@ func handleGetCFilterHeader(s *rpcServer, cmd interface{}, closeChan <-chan stru } } - c := cmd.(*dcrjson.GetCFilterHeaderCmd) + c := cmd.(*types.GetCFilterHeaderCmd) hash, err := chainhash.NewHashFromStr(c.Hash) if err != nil { return nil, rpcDecodeHexError(c.Hash) @@ -3145,8 +3158,8 @@ func handleGetCFilterHeader(s *rpcServer, cmd interface{}, closeChan <-chan stru // handleGetHeaders implements the getheaders command. func handleGetHeaders(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - c := cmd.(*dcrjson.GetHeadersCmd) - blockLocators, err := dcrjson.DecodeConcatenatedHashes(c.BlockLocators) + c := cmd.(*types.GetHeadersCmd) + blockLocators, err := decodeHashes(c.BlockLocators) if err != nil { // Already a *dcrjson.RPCError return nil, err @@ -3185,14 +3198,14 @@ func handleGetHeaders(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) hexBlockHeaders[i] = hex.EncodeToString(buf.Bytes()) buf.Reset() } - return &dcrjson.GetHeadersResult{Headers: hexBlockHeaders}, nil + return &types.GetHeadersResult{Headers: hexBlockHeaders}, nil } // handleGetInfo implements the getinfo command. We only return the fields // that are not related to wallet functionality. func handleGetInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { best := s.chain.BestSnapshot() - ret := &dcrjson.InfoChainResult{ + ret := &types.InfoChainResult{ Version: int32(1000000*version.Major + 10000*version.Minor + 100*version.Patch), ProtocolVersion: int32(maxProtocolVersion), @@ -3217,7 +3230,7 @@ func handleGetMempoolInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct numBytes += int64(txD.Tx.MsgTx().SerializeSize()) } - ret := &dcrjson.GetMempoolInfoResult{ + ret := &types.GetMempoolInfoResult{ Size: int64(len(mempoolTxns)), Bytes: numBytes, } @@ -3230,7 +3243,7 @@ func handleGetMempoolInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct func handleGetMiningInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { // Create a default getnetworkhashps command to use defaults and make // use of the existing getnetworkhashps handler. - gnhpsCmd := dcrjson.NewGetNetworkHashPSCmd(nil, nil) + gnhpsCmd := types.NewGetNetworkHashPSCmd(nil, nil) networkHashesPerSecIface, err := handleGetNetworkHashPS(s, gnhpsCmd, closeChan) if err != nil { @@ -3250,7 +3263,7 @@ func handleGetMiningInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{ "Could not calculate next stake difficulty") } - result := dcrjson.GetMiningInfoResult{ + result := types.GetMiningInfoResult{ Blocks: best.Height, CurrentBlockSize: best.BlockSize, CurrentBlockTx: best.NumTxns, @@ -3269,7 +3282,7 @@ func handleGetMiningInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{ // handleGetNetTotals implements the getnettotals command. func handleGetNetTotals(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { totalBytesRecv, totalBytesSent := s.server.NetTotals() - reply := &dcrjson.GetNetTotalsResult{ + reply := &types.GetNetTotalsResult{ TotalBytesRecv: totalBytesRecv, TotalBytesSent: totalBytesSent, TimeMillis: time.Now().UTC().UnixNano() / int64(time.Millisecond), @@ -3283,7 +3296,7 @@ func handleGetNetworkHashPS(s *rpcServer, cmd interface{}, closeChan <-chan stru // zeros are inferred as int, and won't coerce to int64 because the // return value is an interface{}. - c := cmd.(*dcrjson.GetNetworkHashPSCmd) + c := cmd.(*types.GetNetworkHashPSCmd) // When the passed height is too high or zero, just return 0 now since // we can't reasonably calculate the number of network hashes per @@ -3377,10 +3390,10 @@ func handleGetNetworkHashPS(s *rpcServer, cmd interface{}, closeChan <-chan stru func handleGetPeerInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { peers := s.server.Peers() syncPeer := s.server.blockManager.SyncPeer() - infos := make([]*dcrjson.GetPeerInfoResult, 0, len(peers)) + infos := make([]*types.GetPeerInfoResult, 0, len(peers)) for _, p := range peers { statsSnap := p.StatsSnapshot() - info := &dcrjson.GetPeerInfoResult{ + info := &types.GetPeerInfoResult{ ID: statsSnap.ID, Addr: statsSnap.Addr, AddrLocal: p.LocalAddr().String(), @@ -3413,31 +3426,31 @@ func handleGetPeerInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) // handleGetRawMempool implements the getrawmempool command. func handleGetRawMempool(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - c := cmd.(*dcrjson.GetRawMempoolCmd) + c := cmd.(*types.GetRawMempoolCmd) // Choose the type to filter the results by based on the provided param. // A filter type of nil means no filtering. var filterType *stake.TxType if c.TxType != nil { - switch dcrjson.GetRawMempoolTxTypeCmd(*c.TxType) { - case dcrjson.GRMRegular: + switch types.GetRawMempoolTxTypeCmd(*c.TxType) { + case types.GRMRegular: filterType = new(stake.TxType) *filterType = stake.TxTypeRegular - case dcrjson.GRMTickets: + case types.GRMTickets: filterType = new(stake.TxType) *filterType = stake.TxTypeSStx - case dcrjson.GRMVotes: + case types.GRMVotes: filterType = new(stake.TxType) *filterType = stake.TxTypeSSGen - case dcrjson.GRMRevocations: + case types.GRMRevocations: filterType = new(stake.TxType) *filterType = stake.TxTypeSSRtx - case dcrjson.GRMAll: + case types.GRMAll: // Nothing to do default: - supported := []dcrjson.GetRawMempoolTxTypeCmd{dcrjson.GRMRegular, - dcrjson.GRMTickets, dcrjson.GRMVotes, dcrjson.GRMRevocations, - dcrjson.GRMAll} + supported := []types.GetRawMempoolTxTypeCmd{types.GRMRegular, + types.GRMTickets, types.GRMVotes, types.GRMRevocations, + types.GRMAll} return nil, rpcInvalidError("Invalid transaction type: %s -- "+ "supported types: %v", *c.TxType, supported) } @@ -3447,7 +3460,7 @@ func handleGetRawMempool(s *rpcServer, cmd interface{}, closeChan <-chan struct{ mp := s.server.txMemPool if c.Verbose != nil && *c.Verbose { descs := mp.VerboseTxDescs() - result := make(map[string]*dcrjson.GetRawMempoolVerboseResult, len(descs)) + result := make(map[string]*types.GetRawMempoolVerboseResult, len(descs)) for i := range descs { desc := descs[i] if filterType != nil && desc.Type != *filterType { @@ -3455,7 +3468,7 @@ func handleGetRawMempool(s *rpcServer, cmd interface{}, closeChan <-chan struct{ } tx := desc.Tx - mpd := &dcrjson.GetRawMempoolVerboseResult{ + mpd := &types.GetRawMempoolVerboseResult{ Size: int32(tx.MsgTx().SerializeSize()), Fee: dcrutil.Amount(desc.Fee).ToCoin(), Time: desc.Added.Unix(), @@ -3489,7 +3502,7 @@ func handleGetRawMempool(s *rpcServer, cmd interface{}, closeChan <-chan struct{ // handleGetRawTransaction implements the getrawtransaction command. func handleGetRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - c := cmd.(*dcrjson.GetRawTransactionCmd) + c := cmd.(*types.GetRawTransactionCmd) // Convert the provided transaction hash hex to a Hash. txHash, err := chainhash.NewHashFromStr(c.Txid) @@ -3629,7 +3642,7 @@ func handleGetStakeDifficulty(s *rpcServer, cmd interface{}, closeChan <-chan st } nextSdiffAmount := dcrutil.Amount(nextSdiff) - sDiffResult := &dcrjson.GetStakeDifficultyResult{ + sDiffResult := &types.GetStakeDifficultyResult{ CurrentStakeDifficulty: currentSdiff.ToCoin(), NextStakeDifficulty: nextSdiffAmount.ToCoin(), } @@ -3639,8 +3652,8 @@ func handleGetStakeDifficulty(s *rpcServer, cmd interface{}, closeChan <-chan st // convertVersionMap translates a map[int]int into a sorted array of // VersionCount that contains the same information. -func convertVersionMap(m map[int]int) []dcrjson.VersionCount { - sorted := make([]dcrjson.VersionCount, 0, len(m)) +func convertVersionMap(m map[int]int) []types.VersionCount { + sorted := make([]types.VersionCount, 0, len(m)) order := make([]int, 0, len(m)) for k := range m { order = append(order, k) @@ -3648,7 +3661,7 @@ func convertVersionMap(m map[int]int) []dcrjson.VersionCount { sort.Ints(order) for _, v := range order { - sorted = append(sorted, dcrjson.VersionCount{Version: uint32(v), + sorted = append(sorted, types.VersionCount{Version: uint32(v), Count: uint32(m[v])}) } @@ -3658,7 +3671,7 @@ func convertVersionMap(m map[int]int) []dcrjson.VersionCount { // handleGetStakeVersionInfo implements the getstakeversioninfo command. func handleGetStakeVersionInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { count := int32(1) - c, ok := cmd.(*dcrjson.GetStakeVersionInfoCmd) + c, ok := cmd.(*types.GetStakeVersionInfoCmd) if !ok { return nil, rpcInvalidError("Invalid type: %T", c) } @@ -3673,10 +3686,10 @@ func handleGetStakeVersionInfo(s *rpcServer, cmd interface{}, closeChan <-chan s interval := s.server.chainParams.StakeVersionInterval // Assemble JSON result. - result := dcrjson.GetStakeVersionInfoResult{ + result := types.GetStakeVersionInfoResult{ CurrentHeight: snapshot.Height, Hash: snapshot.Hash.String(), - Intervals: make([]dcrjson.VersionInterval, 0, count), + Intervals: make([]types.VersionInterval, 0, count), } startHeight := snapshot.Height @@ -3704,7 +3717,7 @@ func handleGetStakeVersionInfo(s *rpcServer, cmd interface{}, closeChan <-chan s voteVersions[int(vote.Version)]++ } } - versionInterval := dcrjson.VersionInterval{ + versionInterval := types.VersionInterval{ StartHeight: endHeight, EndHeight: startHeight, PoSVersions: convertVersionMap(posVersions), @@ -3730,7 +3743,7 @@ func handleGetStakeVersionInfo(s *rpcServer, cmd interface{}, closeChan <-chan s // handleGetStakeVersions implements the getstakeversions command. func handleGetStakeVersions(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - c := cmd.(*dcrjson.GetStakeVersionsCmd) + c := cmd.(*types.GetStakeVersionsCmd) hash, err := chainhash.NewHashFromStr(c.Hash) if err != nil { @@ -3747,21 +3760,21 @@ func handleGetStakeVersions(s *rpcServer, cmd interface{}, closeChan <-chan stru "Could not obtain stake versions") } - result := dcrjson.GetStakeVersionsResult{ - StakeVersions: make([]dcrjson.StakeVersions, 0, len(sv)), + result := types.GetStakeVersionsResult{ + StakeVersions: make([]types.StakeVersions, 0, len(sv)), } for _, v := range sv { - nsv := dcrjson.StakeVersions{ + nsv := types.StakeVersions{ Hash: v.Hash.String(), Height: v.Height, BlockVersion: v.BlockVersion, StakeVersion: v.StakeVersion, - Votes: make([]dcrjson.VersionBits, 0, + Votes: make([]types.VersionBits, 0, len(v.Votes)), } for _, vote := range v.Votes { nsv.Votes = append(nsv.Votes, - dcrjson.VersionBits{Version: vote.Version, + types.VersionBits{Version: vote.Version, Bits: vote.Bits}) } @@ -3784,7 +3797,7 @@ func handleGetTicketPoolValue(s *rpcServer, cmd interface{}, closeChan <-chan st // handleGetVoteInfo implements the getvoteinfo command. func handleGetVoteInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - c, ok := cmd.(*dcrjson.GetVoteInfoCmd) + c, ok := cmd.(*types.GetVoteInfoCmd) if !ok { return nil, rpcInvalidError("Invalid type: %T", c) } @@ -3794,7 +3807,7 @@ func handleGetVoteInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) interval := int64(s.server.chainParams.RuleChangeActivationInterval) quorum := s.server.chainParams.RuleChangeActivationQuorum // Assemble JSON result. - result := dcrjson.GetVoteInfoResult{ + result := types.GetVoteInfoResult{ CurrentHeight: snapshot.Height, StartHeight: s.chain.CalcWantHeight(interval, snapshot.Height) + 1, @@ -3819,13 +3832,13 @@ func handleGetVoteInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) "Could not obtain vote info") } - result.Agendas = make([]dcrjson.Agenda, 0, len(vi.Agendas)) + result.Agendas = make([]types.Agenda, 0, len(vi.Agendas)) for _, agenda := range vi.Agendas { - a := dcrjson.Agenda{ + a := types.Agenda{ ID: agenda.Vote.Id, Description: agenda.Vote.Description, Mask: agenda.Vote.Mask, - Choices: make([]dcrjson.Choice, 0, + Choices: make([]types.Choice, 0, len(agenda.Vote.Choices)), StartTime: agenda.StartTime, ExpireTime: agenda.ExpireTime, @@ -3833,7 +3846,7 @@ func handleGetVoteInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) // Handle choices. for _, choice := range agenda.Vote.Choices { - c := dcrjson.Choice{ + c := types.Choice{ ID: choice.Id, Description: choice.Description, Bits: choice.Bits, @@ -3913,7 +3926,7 @@ func bigToLEUint256(n *big.Int) [uint256Size]byte { // handleGetTxOut handles gettxout commands. func handleGetTxOut(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - c := cmd.(*dcrjson.GetTxOutCmd) + c := cmd.(*types.GetTxOutCmd) // Convert the provided transaction hash hex to a Hash. txHash, err := chainhash.NewHashFromStr(c.Txid) @@ -4004,12 +4017,12 @@ func handleGetTxOut(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i addresses[i] = addr.EncodeAddress() } - txOutReply := &dcrjson.GetTxOutResult{ + txOutReply := &types.GetTxOutResult{ BestBlock: bestBlockHash, Confirmations: confirmations, Value: dcrutil.Amount(value).ToUnit(dcrutil.AmountCoin), Version: int32(txVersion), - ScriptPubKey: dcrjson.ScriptPubKeyResult{ + ScriptPubKey: types.ScriptPubKeyResult{ Asm: disbuf, Hex: hex.EncodeToString(pkScript), ReqSigs: int32(reqSigs), @@ -4202,7 +4215,7 @@ func handleGetWorkRequest(s *rpcServer) (interface{}, error) { // an artifact of some legacy internal state in the reference // implementation, but it is required for compatibility. target := bigToLEUint256(blockchain.CompactToBig(msgBlock.Header.Bits)) - reply := &dcrjson.GetWorkResult{ + reply := &types.GetWorkResult{ Data: hex.EncodeToString(data), Target: hex.EncodeToString(target[:]), } @@ -4351,7 +4364,7 @@ func handleGetWork(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (in } } - c := cmd.(*dcrjson.GetWorkCmd) + c := cmd.(*types.GetWorkCmd) // Protect concurrent access from multiple RPC invocations for work // requests and submission. @@ -4371,15 +4384,15 @@ func handleGetWork(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (in // handleHelp implements the help command. func handleHelp(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - c := cmd.(*dcrjson.HelpCmd) + c := cmd.(*types.HelpCmd) // Provide a usage overview of all commands when no specific command // was specified. - var command string + var method types.Method if c.Command != nil { - command = *c.Command + method = types.Method(*c.Command) } - if command == "" { + if method == "" { usage, err := s.helpCacher.rpcUsage(false) if err != nil { context := "Failed to generate RPC usage" @@ -4392,12 +4405,12 @@ func handleHelp(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (inter // search the main list of handlers since help should not be provided // for commands that are unimplemented or related to wallet // functionality. - if _, ok := rpcHandlers[command]; !ok { - return nil, rpcInvalidError("Unknown command: %v", command) + if _, ok := rpcHandlers[method]; !ok { + return nil, rpcInvalidError("Unknown method: %v", method) } // Get the help for the command. - help, err := s.helpCacher.rpcMethodHelp(command) + help, err := s.helpCacher.rpcMethodHelp(method) if err != nil { context := "Failed to generate help" return nil, rpcInternalError(err.Error(), context) @@ -4418,7 +4431,7 @@ func handleLiveTickets(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) ltString[i] = lt[i].String() } - return dcrjson.LiveTicketsResult{Tickets: ltString}, nil + return types.LiveTicketsResult{Tickets: ltString}, nil } // handleMissedTickets implements the missedtickets command. @@ -4434,7 +4447,7 @@ func handleMissedTickets(s *rpcServer, cmd interface{}, closeChan <-chan struct{ mtString[i] = hash.String() } - return dcrjson.MissedTicketsResult{Tickets: mtString}, nil + return types.MissedTicketsResult{Tickets: mtString}, nil } // handlePing implements the ping command. @@ -4596,7 +4609,7 @@ func fetchInputTxos(s *rpcServer, tx *wire.MsgTx) (map[wire.OutPoint]wire.TxOut, // createVinListPrevOut returns a slice of JSON objects for the inputs of the // passed transaction. -func createVinListPrevOut(s *rpcServer, mtx *wire.MsgTx, chainParams *chaincfg.Params, vinExtra bool, filterAddrMap map[string]struct{}) ([]dcrjson.VinPrevOut, error) { +func createVinListPrevOut(s *rpcServer, mtx *wire.MsgTx, chainParams *chaincfg.Params, vinExtra bool, filterAddrMap map[string]struct{}) ([]types.VinPrevOut, error) { // Coinbase transactions only have a single txin by definition. if blockchain.IsCoinBaseTx(mtx) { // Only include the transaction if the filter map is empty @@ -4607,7 +4620,7 @@ func createVinListPrevOut(s *rpcServer, mtx *wire.MsgTx, chainParams *chaincfg.P } txIn := mtx.TxIn[0] - vinList := make([]dcrjson.VinPrevOut, 1) + vinList := make([]types.VinPrevOut, 1) vinList[0].Coinbase = hex.EncodeToString(txIn.SignatureScript) amountIn := dcrutil.Amount(txIn.ValueIn).ToCoin() vinList[0].AmountIn = &amountIn @@ -4616,7 +4629,7 @@ func createVinListPrevOut(s *rpcServer, mtx *wire.MsgTx, chainParams *chaincfg.P } // Use a dynamically sized list to accommodate the address filter. - vinList := make([]dcrjson.VinPrevOut, 0, len(mtx.TxIn)) + vinList := make([]types.VinPrevOut, 0, len(mtx.TxIn)) // Lookup all of the referenced transaction outputs needed to populate // the previous output information if requested. @@ -4637,7 +4650,7 @@ func createVinListPrevOut(s *rpcServer, mtx *wire.MsgTx, chainParams *chaincfg.P // Handle only the null input of a stakebase differently. if isSSGen && i == 0 { amountIn := dcrutil.Amount(txIn.ValueIn).ToCoin() - vinEntry := dcrjson.VinPrevOut{ + vinEntry := types.VinPrevOut{ Stakebase: hex.EncodeToString(txIn.SignatureScript), AmountIn: &amountIn, Sequence: txIn.Sequence, @@ -4656,7 +4669,7 @@ func createVinListPrevOut(s *rpcServer, mtx *wire.MsgTx, chainParams *chaincfg.P // requested and available. prevOut := &txIn.PreviousOutPoint amountIn := dcrutil.Amount(txIn.ValueIn).ToCoin() - vinEntry := dcrjson.VinPrevOut{ + vinEntry := types.VinPrevOut{ Txid: prevOut.Hash.String(), Vout: prevOut.Index, Tree: prevOut.Tree, @@ -4664,7 +4677,7 @@ func createVinListPrevOut(s *rpcServer, mtx *wire.MsgTx, chainParams *chaincfg.P BlockHeight: &txIn.BlockHeight, BlockIndex: &txIn.BlockIndex, Sequence: txIn.Sequence, - ScriptSig: &dcrjson.ScriptSig{ + ScriptSig: &types.ScriptSig{ Asm: disbuf, Hex: hex.EncodeToString(txIn.SignatureScript), }, @@ -4724,7 +4737,7 @@ func createVinListPrevOut(s *rpcServer, mtx *wire.MsgTx, chainParams *chaincfg.P // requested. if vinExtra { vinListEntry := &vinList[len(vinList)-1] - vinListEntry.PrevOut = &dcrjson.PrevOut{ + vinListEntry.PrevOut = &types.PrevOut{ Addresses: encodedAddrs, Value: dcrutil.Amount(originTxOut.Value).ToCoin(), } @@ -4766,7 +4779,7 @@ func handleSearchRawTransactions(s *rpcServer, cmd interface{}, closeChan <-chan // Override the flag for including extra previous output information in // each input if needed. - c := cmd.(*dcrjson.SearchRawTransactionsCmd) + c := cmd.(*types.SearchRawTransactionsCmd) vinExtra := false if c.VinExtra != nil { vinExtra = *c.VinExtra != 0 @@ -4942,7 +4955,7 @@ func handleSearchRawTransactions(s *rpcServer, cmd interface{}, closeChan <-chan // The verbose flag is set, so generate the JSON object and return it. best := s.chain.BestSnapshot() chainParams := s.server.chainParams - srtList := make([]dcrjson.SearchRawTransactionsResult, len(addressTxns)) + srtList := make([]types.SearchRawTransactionsResult, len(addressTxns)) for i := range addressTxns { // The deserialized transaction is needed, so deserialize the // retrieved transaction if it's in serialized form (which will @@ -5026,7 +5039,7 @@ func handleSearchRawTransactions(s *rpcServer, cmd interface{}, closeChan <-chan // handleSendRawTransaction implements the sendrawtransaction command. func handleSendRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - c := cmd.(*dcrjson.SendRawTransactionCmd) + c := cmd.(*types.SendRawTransactionCmd) // Deserialize and send off to tx relay allowHighFees := *c.AllowHighFees @@ -5092,7 +5105,7 @@ func handleSendRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan st // handleSetGenerate implements the setgenerate command. func handleSetGenerate(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - c := cmd.(*dcrjson.SetGenerateCmd) + c := cmd.(*types.SetGenerateCmd) // Disable generation regardless of the provided generate flag if the // maximum number of threads (goroutines for our purposes) is 0. @@ -5134,7 +5147,7 @@ func handleStop(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (inter // handleSubmitBlock implements the submitblock command. func handleSubmitBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - c := cmd.(*dcrjson.SubmitBlockCmd) + c := cmd.(*types.SubmitBlockCmd) // Deserialize the submitted block. hexStr := c.HexBlock @@ -5242,7 +5255,7 @@ func stdDev(s []dcrutil.Amount) dcrutil.Amount { // feeInfoForMempool returns the fee information for the passed tx type in the // memory pool. -func feeInfoForMempool(s *rpcServer, txType stake.TxType) *dcrjson.FeeInfoMempool { +func feeInfoForMempool(s *rpcServer, txType stake.TxType) *types.FeeInfoMempool { txDs := s.server.txMemPool.TxDescs() ticketFees := make([]dcrutil.Amount, 0, len(txDs)) for _, txD := range txDs { @@ -5253,7 +5266,7 @@ func feeInfoForMempool(s *rpcServer, txType stake.TxType) *dcrjson.FeeInfoMempoo } } - return &dcrjson.FeeInfoMempool{ + return &types.FeeInfoMempool{ Number: uint32(len(ticketFees)), Min: min(ticketFees).ToCoin(), Max: max(ticketFees).ToCoin(), @@ -5280,7 +5293,7 @@ func calcFeePerKb(tx *dcrutil.Tx) dcrutil.Amount { // feeInfoForBlock fetches the ticket fee information for a given tx type in a // block. -func ticketFeeInfoForBlock(s *rpcServer, height int64, txType stake.TxType) (*dcrjson.FeeInfoBlock, error) { +func ticketFeeInfoForBlock(s *rpcServer, height int64, txType stake.TxType) (*types.FeeInfoBlock, error) { bl, err := s.chain.BlockByHeight(height) if err != nil { return nil, err @@ -5320,7 +5333,7 @@ func ticketFeeInfoForBlock(s *rpcServer, height int64, txType stake.TxType) (*dc } } - return &dcrjson.FeeInfoBlock{ + return &types.FeeInfoBlock{ Height: uint32(height), Number: uint32(txNum), Min: min(txFees).ToCoin(), @@ -5333,7 +5346,7 @@ func ticketFeeInfoForBlock(s *rpcServer, height int64, txType stake.TxType) (*dc // ticketFeeInfoForRange fetches the ticket fee information for a given range // from [start, end). -func ticketFeeInfoForRange(s *rpcServer, start int64, end int64, txType stake.TxType) (*dcrjson.FeeInfoWindow, error) { +func ticketFeeInfoForRange(s *rpcServer, start int64, end int64, txType stake.TxType) (*types.FeeInfoWindow, error) { hashes, err := s.chain.HeightRange(start, end) if err != nil { return nil, err @@ -5365,7 +5378,7 @@ func ticketFeeInfoForRange(s *rpcServer, start int64, end int64, txType stake.Tx } } - return &dcrjson.FeeInfoWindow{ + return &types.FeeInfoWindow{ StartHeight: uint32(start), EndHeight: uint32(end), Number: uint32(len(txFees)), @@ -5379,7 +5392,7 @@ func ticketFeeInfoForRange(s *rpcServer, start int64, end int64, txType stake.Tx // handleTicketFeeInfo implements the ticketfeeinfo command. func handleTicketFeeInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - c := cmd.(*dcrjson.TicketFeeInfoCmd) + c := cmd.(*types.TicketFeeInfoCmd) bestHeight := s.server.chain.BestSnapshot().Height @@ -5387,7 +5400,7 @@ func handleTicketFeeInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{ feeInfoMempool := feeInfoForMempool(s, stake.TxTypeSStx) // Blocks requested, descending from the chain tip. - var feeInfoBlocks []dcrjson.FeeInfoBlock + var feeInfoBlocks []types.FeeInfoBlock blocks := uint32(0) if c.Blocks != nil { blocks = *c.Blocks @@ -5406,7 +5419,7 @@ func handleTicketFeeInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{ } } - var feeInfoWindows []dcrjson.FeeInfoWindow + var feeInfoWindows []types.FeeInfoWindow windows := uint32(0) if c.Windows != nil { windows = *c.Windows @@ -5451,7 +5464,7 @@ func handleTicketFeeInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{ } } - return &dcrjson.TicketFeeInfoResult{ + return &types.TicketFeeInfoResult{ FeeInfoMempool: *feeInfoMempool, FeeInfoBlocks: feeInfoBlocks, FeeInfoWindows: feeInfoWindows, @@ -5460,7 +5473,7 @@ func handleTicketFeeInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{ // handleTicketsForAddress implements the ticketsforaddress command. func handleTicketsForAddress(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - c := cmd.(*dcrjson.TicketsForAddressCmd) + c := cmd.(*types.TicketsForAddressCmd) addr, err := dcrutil.DecodeAddress(c.Address) if err != nil { @@ -5479,7 +5492,7 @@ func handleTicketsForAddress(s *rpcServer, cmd interface{}, closeChan <-chan str itr++ } - reply := &dcrjson.TicketsForAddressResult{ + reply := &types.TicketsForAddressResult{ Tickets: ticketStrings, } return reply, nil @@ -5487,7 +5500,7 @@ func handleTicketsForAddress(s *rpcServer, cmd interface{}, closeChan <-chan str // handleTicketVWAP implements the ticketvwap command. func handleTicketVWAP(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - c := cmd.(*dcrjson.TicketVWAPCmd) + c := cmd.(*types.TicketVWAPCmd) // The default VWAP is for the past WorkDiffWindows * WorkDiffWindowSize // many blocks. @@ -5545,7 +5558,7 @@ func handleTicketVWAP(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) // handleTxFeeInfo implements the txfeeinfo command. func handleTxFeeInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - c := cmd.(*dcrjson.TxFeeInfoCmd) + c := cmd.(*types.TxFeeInfoCmd) bestHeight := s.server.chain.BestSnapshot().Height @@ -5553,7 +5566,7 @@ func handleTxFeeInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) ( feeInfoMempool := feeInfoForMempool(s, stake.TxTypeRegular) // Blocks requested, descending from the chain tip. - var feeInfoBlocks []dcrjson.FeeInfoBlock + var feeInfoBlocks []types.FeeInfoBlock blocks := uint32(0) if c.Blocks != nil { blocks = *c.Blocks @@ -5575,7 +5588,7 @@ func handleTxFeeInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) ( // Get the fee info for the range requested, unless none is given. The // default range is for the past WorkDiffWindowSize many blocks. - var feeInfoRange dcrjson.FeeInfoRange + var feeInfoRange types.FeeInfoRange var start uint32 if c.RangeStart == nil { @@ -5612,7 +5625,7 @@ func handleTxFeeInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) ( "Could not obtain ticket fee info") } - feeInfoRange = dcrjson.FeeInfoRange{ + feeInfoRange = types.FeeInfoRange{ Number: feeInfo.Number, Min: feeInfo.Min, Max: feeInfo.Max, @@ -5621,7 +5634,7 @@ func handleTxFeeInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) ( StdDev: feeInfo.StdDev, } - return &dcrjson.TxFeeInfoResult{ + return &types.TxFeeInfoResult{ FeeInfoMempool: *feeInfoMempool, FeeInfoBlocks: feeInfoBlocks, FeeInfoRange: feeInfoRange, @@ -5630,8 +5643,8 @@ func handleTxFeeInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) ( // handleValidateAddress implements the validateaddress command. func handleValidateAddress(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - c := cmd.(*dcrjson.ValidateAddressCmd) - result := dcrjson.ValidateAddressChainResult{} + c := cmd.(*types.ValidateAddressCmd) + result := types.ValidateAddressChainResult{} addr, err := dcrutil.DecodeAddress(c.Address) if err != nil || !addr.IsForNet(s.server.chainParams) { // Return the default value (false) for IsValid. @@ -5681,7 +5694,7 @@ func verifyChain(s *rpcServer, level, depth int64) error { // handleVerifyChain implements the verifychain command. func handleVerifyChain(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - c := cmd.(*dcrjson.VerifyChainCmd) + c := cmd.(*types.VerifyChainCmd) var checkLevel, checkDepth int64 if c.CheckLevel != nil { @@ -5697,7 +5710,7 @@ func handleVerifyChain(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) // handleVerifyMessage implements the verifymessage command. func handleVerifyMessage(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - c := cmd.(*dcrjson.VerifyMessageCmd) + c := cmd.(*types.VerifyMessageCmd) // Decode the provided address. addr, err := dcrutil.DecodeAddress(c.Address) @@ -5765,7 +5778,7 @@ func handleVersion(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (in if build != "" { buildMeta = fmt.Sprintf("%s.%s", build, buildMeta) } - result := map[string]dcrjson.VersionResult{ + result := map[string]types.VersionResult{ "dcrdjsonrpcapi": { VersionString: jsonrpcSemverString, Major: jsonrpcSemverMajor, @@ -5973,8 +5986,8 @@ func (s *rpcServer) checkAuth(r *http.Request, require bool) (bool, bool, error) type parsedRPCCmd struct { jsonrpc string id interface{} - method string - cmd interface{} + method types.Method + params interface{} err *dcrjson.RPCError } @@ -5987,19 +6000,19 @@ func (s *rpcServer) standardCmdResult(cmd *parsedRPCCmd, closeChan <-chan struct if ok { goto handled } - _, ok = rpcAskWallet[cmd.method] + _, ok = rpcAskWallet[string(cmd.method)] if ok { handler = handleAskWallet goto handled } - _, ok = rpcUnimplemented[cmd.method] + _, ok = rpcUnimplemented[string(cmd.method)] if ok { handler = handleUnimplemented goto handled } return nil, dcrjson.ErrRPCMethodNotFound handled: - return handler(s, cmd.cmd, closeChan) + return handler(s, cmd.params, closeChan) } // parseCmd parses a JSON-RPC request object into known concrete command. The @@ -6010,10 +6023,10 @@ func parseCmd(request *dcrjson.Request) *parsedRPCCmd { parsedCmd := parsedRPCCmd{ jsonrpc: request.Jsonrpc, id: request.ID, - method: request.Method, + method: types.Method(request.Method), } - cmd, err := dcrjson.UnmarshalCmd(request) + params, err := dcrjson.ParseParams(types.Method(request.Method), request.Params) if err != nil { // When the error is because the method is not registered, // produce a method not found RPC error. @@ -6029,7 +6042,7 @@ func parseCmd(request *dcrjson.Request) *parsedRPCCmd { return &parsedCmd } - parsedCmd.cmd = cmd + parsedCmd.params = params return &parsedCmd } diff --git a/rpcserverhelp.go b/rpcserverhelp.go index ba5c999d..654c6d86 100644 --- a/rpcserverhelp.go +++ b/rpcserverhelp.go @@ -11,7 +11,8 @@ import ( "strings" "sync" - "github.com/decred/dcrd/dcrjson/v2" + "github.com/decred/dcrd/dcrjson/v3" + "github.com/decred/dcrd/rpc/jsonrpc/types" ) // helpDescsEnUS defines the English descriptions used for the help strings. @@ -169,14 +170,14 @@ var helpDescsEnUS = map[string]string{ "existsaddresses--result0": "Bitset of bools showing if addresses exist or not", // ExitsMissedTicketsCmd help. - "existsmissedtickets--synopsis": "Test for the existence of the provided tickets in the missed ticket map", - "existsmissedtickets-txhashblob": "Blob containing the hashes to check", - "existsmissedtickets--result0": "Bool blob showing if the ticket exists in the missed ticket database or not", + "existsmissedtickets--synopsis": "Test for the existence of the provided tickets in the missed ticket map", + "existsmissedtickets-txhashes": "Array of hashes to check", + "existsmissedtickets--result0": "Bool blob showing if the ticket exists in the missed ticket database or not", // ExistsExpiredTicketsCmd help. - "existsexpiredtickets--synopsis": "Test for the existence of the provided tickets in the expired ticket map", - "existsexpiredtickets-txhashblob": "Blob containing the hashes to check", - "existsexpiredtickets--result0": "Bool blob showing if ticket exists in the expired ticket database or not", + "existsexpiredtickets--synopsis": "Test for the existence of the provided tickets in the expired ticket map", + "existsexpiredtickets-txhashes": "Array of hashes to check", + "existsexpiredtickets--result0": "Bool blob showing if ticket exists in the expired ticket database or not", // ExistsLiveTicketCmd help. "existsliveticket--synopsis": "Test for the existence of the provided ticket", @@ -184,14 +185,14 @@ var helpDescsEnUS = map[string]string{ "existsliveticket--result0": "Bool showing if address exists in the live ticket database or not", // ExistsLiveTicketsCmd help. - "existslivetickets--synopsis": "Test for the existence of the provided tickets in the live ticket map", - "existslivetickets-txhashblob": "Blob containing the hashes to check", - "existslivetickets--result0": "Bool blob showing if ticket exists in the live ticket database or not", + "existslivetickets--synopsis": "Test for the existence of the provided tickets in the live ticket map", + "existslivetickets-txhashes": "Array of hashes to check", + "existslivetickets--result0": "Bool blob showing if ticket exists in the live ticket database or not", // ExistsMempoolTxsCmd help. - "existsmempooltxs--synopsis": "Test for the existence of the provided txs in the mempool", - "existsmempooltxs-txhashblob": "Blob containing the hashes to check", - "existsmempooltxs--result0": "Bool blob showing if txs exist in the mempool or not", + "existsmempooltxs--synopsis": "Test for the existence of the provided txs in the mempool", + "existsmempooltxs-txhashes": "Array of hashes to check", + "existsmempooltxs--result0": "Bool blob showing if txs exist in the mempool or not", // GenerateCmd help "generate--synopsis": "Generates a set number of blocks (simnet or regtest only) and returns a JSON\n" + @@ -571,7 +572,7 @@ var helpDescsEnUS = map[string]string{ // GetHeadersCmd help. "getheaders--synopsis": "Returns block headers starting with the first known block hash from the request", - "getheaders-blocklocators": "Concatenated hashes of blocks. Headers are returned starting from the first known hash in this list", + "getheaders-blocklocators": "Array of block locator hashes. Headers are returned starting from the first known hash in this list", "getheaders-hashstop": "Optional block hash to stop including block headers for", "getheadersresult-headers": "Serialized block headers of all located blocks, limited to some arbitrary maximum number of hashes (currently 2000, which matches the wire protocol headers message, but this is not guaranteed)", @@ -827,7 +828,7 @@ var helpDescsEnUS = map[string]string{ // Rescan help. "rescan--synopsis": "Rescan blocks for transactions matching the loaded transaction filter.", - "rescan-blockhashes": "Concatenated block hashes to rescan. Each next block must be a child of the previous.", + "rescan-blockhashes": "Array of block hashes to rescan. Each next block must be a child of the previous.", // -------- Decred-specific help -------- @@ -943,17 +944,17 @@ var helpDescsEnUS = map[string]string{ // rpcResultTypes specifies the result types that each RPC command can return. // This information is used to generate the help. Each result type must be a // pointer to the type (or nil to indicate no return value). -var rpcResultTypes = map[string][]interface{}{ +var rpcResultTypes = map[types.Method][]interface{}{ "addnode": nil, "createrawsstx": {(*string)(nil)}, "createrawssrtx": {(*string)(nil)}, "createrawtransaction": {(*string)(nil)}, "debuglevel": {(*string)(nil), (*string)(nil)}, - "decoderawtransaction": {(*dcrjson.TxRawDecodeResult)(nil)}, - "decodescript": {(*dcrjson.DecodeScriptResult)(nil)}, + "decoderawtransaction": {(*types.TxRawDecodeResult)(nil)}, + "decodescript": {(*types.DecodeScriptResult)(nil)}, "estimatefee": {(*float64)(nil)}, "estimatesmartfee": {(*float64)(nil)}, - "estimatestakediff": {(*dcrjson.EstimateStakeDiffResult)(nil)}, + "estimatestakediff": {(*types.EstimateStakeDiffResult)(nil)}, "existsaddress": {(*bool)(nil)}, "existsaddresses": {(*string)(nil)}, "existsmissedtickets": {(*string)(nil)}, @@ -961,66 +962,66 @@ var rpcResultTypes = map[string][]interface{}{ "existsliveticket": {(*bool)(nil)}, "existslivetickets": {(*string)(nil)}, "existsmempooltxs": {(*string)(nil)}, - "getaddednodeinfo": {(*[]string)(nil), (*[]dcrjson.GetAddedNodeInfoResult)(nil)}, - "getbestblock": {(*dcrjson.GetBestBlockResult)(nil)}, + "getaddednodeinfo": {(*[]string)(nil), (*[]types.GetAddedNodeInfoResult)(nil)}, + "getbestblock": {(*types.GetBestBlockResult)(nil)}, "generate": {(*[]string)(nil)}, "getbestblockhash": {(*string)(nil)}, - "getblock": {(*string)(nil), (*dcrjson.GetBlockVerboseResult)(nil)}, - "getblockchaininfo": {(*dcrjson.GetBlockChainInfoResult)(nil)}, + "getblock": {(*string)(nil), (*types.GetBlockVerboseResult)(nil)}, + "getblockchaininfo": {(*types.GetBlockChainInfoResult)(nil)}, "getblockcount": {(*int64)(nil)}, "getblockhash": {(*string)(nil)}, - "getblockheader": {(*string)(nil), (*dcrjson.GetBlockHeaderVerboseResult)(nil)}, - "getblocksubsidy": {(*dcrjson.GetBlockSubsidyResult)(nil)}, - "getblocktemplate": {(*dcrjson.GetBlockTemplateResult)(nil), (*string)(nil), nil}, + "getblockheader": {(*string)(nil), (*types.GetBlockHeaderVerboseResult)(nil)}, + "getblocksubsidy": {(*types.GetBlockSubsidyResult)(nil)}, + "getblocktemplate": {(*types.GetBlockTemplateResult)(nil), (*string)(nil), nil}, "getcfilter": {(*string)(nil)}, "getcfilterheader": {(*string)(nil)}, - "getchaintips": {(*[]dcrjson.GetChainTipsResult)(nil)}, + "getchaintips": {(*[]types.GetChainTipsResult)(nil)}, "getconnectioncount": {(*int32)(nil)}, "getcurrentnet": {(*uint32)(nil)}, "getdifficulty": {(*float64)(nil)}, - "getstakedifficulty": {(*dcrjson.GetStakeDifficultyResult)(nil)}, - "getstakeversioninfo": {(*dcrjson.GetStakeVersionInfoResult)(nil)}, - "getstakeversions": {(*dcrjson.GetStakeVersionsResult)(nil)}, + "getstakedifficulty": {(*types.GetStakeDifficultyResult)(nil)}, + "getstakeversioninfo": {(*types.GetStakeVersionInfoResult)(nil)}, + "getstakeversions": {(*types.GetStakeVersionsResult)(nil)}, "getgenerate": {(*bool)(nil)}, "gethashespersec": {(*float64)(nil)}, - "getheaders": {(*dcrjson.GetHeadersResult)(nil)}, - "getinfo": {(*dcrjson.InfoChainResult)(nil)}, - "getmempoolinfo": {(*dcrjson.GetMempoolInfoResult)(nil)}, - "getmininginfo": {(*dcrjson.GetMiningInfoResult)(nil)}, - "getnettotals": {(*dcrjson.GetNetTotalsResult)(nil)}, + "getheaders": {(*types.GetHeadersResult)(nil)}, + "getinfo": {(*types.InfoChainResult)(nil)}, + "getmempoolinfo": {(*types.GetMempoolInfoResult)(nil)}, + "getmininginfo": {(*types.GetMiningInfoResult)(nil)}, + "getnettotals": {(*types.GetNetTotalsResult)(nil)}, "getnetworkhashps": {(*int64)(nil)}, - "getpeerinfo": {(*[]dcrjson.GetPeerInfoResult)(nil)}, - "getrawmempool": {(*[]string)(nil), (*dcrjson.GetRawMempoolVerboseResult)(nil)}, - "getrawtransaction": {(*string)(nil), (*dcrjson.TxRawResult)(nil)}, + "getpeerinfo": {(*[]types.GetPeerInfoResult)(nil)}, + "getrawmempool": {(*[]string)(nil), (*types.GetRawMempoolVerboseResult)(nil)}, + "getrawtransaction": {(*string)(nil), (*types.TxRawResult)(nil)}, "getticketpoolvalue": {(*float64)(nil)}, - "gettxout": {(*dcrjson.GetTxOutResult)(nil)}, - "getvoteinfo": {(*dcrjson.GetVoteInfoResult)(nil)}, - "getwork": {(*dcrjson.GetWorkResult)(nil), (*bool)(nil)}, + "gettxout": {(*types.GetTxOutResult)(nil)}, + "getvoteinfo": {(*types.GetVoteInfoResult)(nil)}, + "getwork": {(*types.GetWorkResult)(nil), (*bool)(nil)}, "getcoinsupply": {(*int64)(nil)}, "help": {(*string)(nil), (*string)(nil)}, - "livetickets": {(*dcrjson.LiveTicketsResult)(nil)}, - "missedtickets": {(*dcrjson.MissedTicketsResult)(nil)}, + "livetickets": {(*types.LiveTicketsResult)(nil)}, + "missedtickets": {(*types.MissedTicketsResult)(nil)}, "node": nil, "ping": nil, "rebroadcastmissed": nil, "rebroadcastwinners": nil, - "searchrawtransactions": {(*string)(nil), (*[]dcrjson.SearchRawTransactionsResult)(nil)}, + "searchrawtransactions": {(*string)(nil), (*[]types.SearchRawTransactionsResult)(nil)}, "sendrawtransaction": {(*string)(nil)}, "setgenerate": nil, "stop": {(*string)(nil)}, "submitblock": {nil, (*string)(nil)}, - "ticketfeeinfo": {(*dcrjson.TicketFeeInfoResult)(nil)}, - "ticketsforaddress": {(*dcrjson.TicketsForAddressResult)(nil)}, + "ticketfeeinfo": {(*types.TicketFeeInfoResult)(nil)}, + "ticketsforaddress": {(*types.TicketsForAddressResult)(nil)}, "ticketvwap": {(*float64)(nil)}, - "txfeeinfo": {(*dcrjson.TxFeeInfoResult)(nil)}, - "validateaddress": {(*dcrjson.ValidateAddressChainResult)(nil)}, + "txfeeinfo": {(*types.TxFeeInfoResult)(nil)}, + "validateaddress": {(*types.ValidateAddressChainResult)(nil)}, "verifychain": {(*bool)(nil)}, "verifymessage": {(*bool)(nil)}, - "version": {(*map[string]dcrjson.VersionResult)(nil)}, + "version": {(*map[string]types.VersionResult)(nil)}, // Websocket commands. "loadtxfilter": nil, - "session": {(*dcrjson.SessionResult)(nil)}, + "session": {(*types.SessionResult)(nil)}, "notifywinningtickets": nil, "notifyspentandmissedtickets": nil, "notifynewtickets": nil, @@ -1041,13 +1042,13 @@ var rpcResultTypes = map[string][]interface{}{ type helpCacher struct { sync.Mutex usage string - methodHelp map[string]string + methodHelp map[types.Method]string } // rpcMethodHelp returns an RPC help string for the provided method. // // This function is safe for concurrent access. -func (c *helpCacher) rpcMethodHelp(method string) (string, error) { +func (c *helpCacher) rpcMethodHelp(method types.Method) (string, error) { c.Lock() defer c.Unlock() @@ -1060,7 +1061,7 @@ func (c *helpCacher) rpcMethodHelp(method string) (string, error) { resultTypes, ok := rpcResultTypes[method] if !ok { return "", errors.New("no result types specified for method " + - method) + string(method)) } // Generate, cache, and return the help. @@ -1114,6 +1115,6 @@ func (c *helpCacher) rpcUsage(includeWebsockets bool) (string, error) { // usage for the RPC server commands and caches the results for future calls. func newHelpCacher() *helpCacher { return &helpCacher{ - methodHelp: make(map[string]string), + methodHelp: make(map[types.Method]string), } } diff --git a/rpcwebsocket.go b/rpcwebsocket.go index d1096af5..50a1995d 100644 --- a/rpcwebsocket.go +++ b/rpcwebsocket.go @@ -25,8 +25,9 @@ import ( "github.com/decred/dcrd/blockchain" "github.com/decred/dcrd/blockchain/stake" "github.com/decred/dcrd/chaincfg/chainhash" - "github.com/decred/dcrd/dcrjson/v2" + "github.com/decred/dcrd/dcrjson/v3" "github.com/decred/dcrd/dcrutil" + "github.com/decred/dcrd/rpc/jsonrpc/types" "github.com/decred/dcrd/txscript" "github.com/decred/dcrd/wire" ) @@ -60,8 +61,8 @@ type wsCommandHandler func(*wsClient, interface{}) (interface{}, error) // wsHandlers maps RPC command strings to appropriate websocket handler // functions. This is set by init because help references wsHandlers and thus // causes a dependency loop. -var wsHandlers map[string]wsCommandHandler -var wsHandlersBeforeInit = map[string]wsCommandHandler{ +var wsHandlers map[types.Method]wsCommandHandler +var wsHandlersBeforeInit = map[types.Method]wsCommandHandler{ "loadtxfilter": handleLoadTxFilter, "notifyblocks": handleNotifyBlocks, "notifywinningtickets": handleWinningTickets, @@ -712,7 +713,7 @@ func (m *wsNotificationManager) notifyBlockConnected(clients map[chan struct{}]* // just accepted, there should be no issues serializing it. panic(err) } - ntfn := dcrjson.BlockConnectedNtfn{ + ntfn := types.BlockConnectedNtfn{ Header: hex.EncodeToString(headerBytes), SubscribedTxs: nil, // Set individually for each client } @@ -774,7 +775,7 @@ func (*wsNotificationManager) notifyBlockDisconnected(clients map[chan struct{}] // it. panic(err) } - ntfn := dcrjson.BlockDisconnectedNtfn{ + ntfn := types.BlockDisconnectedNtfn{ Header: hex.EncodeToString(headerBytes), } marshalledJSON, err := dcrjson.MarshalCmd("1.0", nil, &ntfn) @@ -798,7 +799,7 @@ func (m *wsNotificationManager) notifyReorganization(clients map[chan struct{}]* } // Notify interested websocket clients about the disconnected block. - ntfn := dcrjson.NewReorganizationNtfn(rd.OldHash.String(), + ntfn := types.NewReorganizationNtfn(rd.OldHash.String(), int32(rd.OldHeight), rd.NewHash.String(), int32(rd.NewHeight)) @@ -837,7 +838,7 @@ func (*wsNotificationManager) notifyWinningTickets( } // Notify interested websocket clients about the connected block. - ntfn := dcrjson.NewWinningTicketsNtfn(wtnd.BlockHash.String(), + ntfn := types.NewWinningTicketsNtfn(wtnd.BlockHash.String(), int32(wtnd.BlockHeight), ticketMap) marshalledJSON, err := dcrjson.MarshalCmd("1.0", nil, ntfn) @@ -877,7 +878,7 @@ func (*wsNotificationManager) notifySpentAndMissedTickets(clients map[chan struc } // Notify interested websocket clients about the connected block. - ntfn := dcrjson.NewSpentAndMissedTicketsNtfn(tnd.Hash.String(), + ntfn := types.NewSpentAndMissedTicketsNtfn(tnd.Hash.String(), int32(tnd.Height), tnd.StakeDifficulty, ticketMap) marshalledJSON, err := dcrjson.MarshalCmd("1.0", nil, ntfn) @@ -926,7 +927,7 @@ func (*wsNotificationManager) notifyNewTickets(clients map[chan struct{}]*wsClie } // Notify interested websocket clients about the connected block. - ntfn := dcrjson.NewNewTicketsNtfn(tnd.Hash.String(), int32(tnd.Height), + ntfn := types.NewNewTicketsNtfn(tnd.Hash.String(), int32(tnd.Height), tnd.StakeDifficulty, tickets) marshalledJSON, err := dcrjson.MarshalCmd("1.0", nil, ntfn) @@ -944,7 +945,7 @@ func (*wsNotificationManager) notifyNewTickets(clients map[chan struct{}]*wsClie // maturing ticket updates. func (*wsNotificationManager) notifyStakeDifficulty(clients map[chan struct{}]*wsClient, sdnd *StakeDifficultyNtfnData) { // Notify interested websocket clients about the connected block. - ntfn := dcrjson.NewStakeDifficultyNtfn(sdnd.BlockHash.String(), + ntfn := types.NewStakeDifficultyNtfn(sdnd.BlockHash.String(), int32(sdnd.BlockHeight), sdnd.StakeDifficulty) @@ -982,7 +983,7 @@ func (m *wsNotificationManager) notifyForNewTx(clients map[chan struct{}]*wsClie amount += txOut.Value } - ntfn := dcrjson.NewTxAcceptedNtfn(txHashStr, + ntfn := types.NewTxAcceptedNtfn(txHashStr, dcrutil.Amount(amount).ToCoin()) marshalledJSON, err := dcrjson.MarshalCmd("1.0", nil, ntfn) if err != nil { @@ -991,7 +992,7 @@ func (m *wsNotificationManager) notifyForNewTx(clients map[chan struct{}]*wsClie return } - var verboseNtfn *dcrjson.TxAcceptedVerboseNtfn + var verboseNtfn *types.TxAcceptedVerboseNtfn var marshalledJSONVerbose []byte for _, wsc := range clients { if wsc.verboseTxUpdates { @@ -1007,7 +1008,7 @@ func (m *wsNotificationManager) notifyForNewTx(clients map[chan struct{}]*wsClie return } - verboseNtfn = dcrjson.NewTxAcceptedVerboseNtfn(*rawTx) + verboseNtfn = types.NewTxAcceptedVerboseNtfn(*rawTx) marshalledJSONVerbose, err = dcrjson.MarshalCmd("1.0", nil, verboseNtfn) if err != nil { @@ -1087,7 +1088,7 @@ func (m *wsNotificationManager) notifyRelevantTxAccepted(tx *dcrutil.Tx, } if len(clientsToNotify) != 0 { - n := dcrjson.NewRelevantTxAcceptedNtfn(txHexString(msgTx)) + n := types.NewRelevantTxAcceptedNtfn(txHexString(msgTx)) marshalled, err := dcrjson.MarshalCmd("1.0", nil, n) if err != nil { rpcsLog.Errorf("Failed to marshal notification: %v", err) @@ -1307,7 +1308,7 @@ out: // the authenticate request, an authenticate request is received // when the client is already authenticated, or incorrect // authentication credentials are provided in the request. - switch authCmd, ok := cmd.cmd.(*dcrjson.AuthenticateCmd); { + switch authCmd, ok := cmd.params.(*types.AuthenticateCmd); { case c.authenticated && ok: rpcsLog.Warnf("Websocket client %s is already authenticated", c.addr) @@ -1544,7 +1545,7 @@ out: // the authenticate request, an authenticate request is received // when the client is already authenticated, or incorrect // authentication credentials are provided in the request. - switch authCmd, ok := cmd.cmd.(*dcrjson.AuthenticateCmd); { + switch authCmd, ok := cmd.params.(*types.AuthenticateCmd); { case c.authenticated && ok: rpcsLog.Warnf("Websocket client %s is already authenticated", c.addr) @@ -1610,7 +1611,7 @@ out: var resp interface{} wsHandler, ok := wsHandlers[cmd.method] if ok { - resp, err = wsHandler(c, cmd.cmd) + resp, err = wsHandler(c, cmd.params) } else { resp, err = c.server.standardCmdResult(cmd, nil) } @@ -1681,7 +1682,7 @@ func (c *wsClient) serviceRequest(r *parsedRPCCmd) { // exist fallback to handling the command as a standard command. wsHandler, ok := wsHandlers[r.method] if ok { - result, err = wsHandler(c, r.cmd) + result, err = wsHandler(c, r.params) } else { result, err = c.server.standardCmdResult(r, nil) } @@ -1924,18 +1925,18 @@ func newWebsocketClient(server *rpcServer, conn *websocket.Conn, // handleWebsocketHelp implements the help command for websocket connections. func handleWebsocketHelp(wsc *wsClient, icmd interface{}) (interface{}, error) { - cmd, ok := icmd.(*dcrjson.HelpCmd) + cmd, ok := icmd.(*types.HelpCmd) if !ok { return nil, dcrjson.ErrRPCInternal } // Provide a usage overview of all commands when no specific command // was specified. - var command string + var method types.Method if cmd.Command != nil { - command = *cmd.Command + method = types.Method(*cmd.Command) } - if command == "" { + if method == "" { usage, err := wsc.server.helpCacher.rpcUsage(true) if err != nil { context := "Failed to generate RPC usage" @@ -1947,21 +1948,19 @@ func handleWebsocketHelp(wsc *wsClient, icmd interface{}) (interface{}, error) { // Check that the command asked for is supported and implemented. // Search the list of websocket handlers as well as the main list of // handlers since help should only be provided for those cases. - valid := true - if _, ok := rpcHandlers[command]; !ok { - if _, ok := wsHandlers[command]; !ok { - valid = false - } + _, valid := rpcHandlers[method] + if !valid { + _, valid = wsHandlers[method] } if !valid { return nil, &dcrjson.RPCError{ Code: dcrjson.ErrRPCInvalidParameter, - Message: "Unknown command: " + command, + Message: "Unknown method: " + string(method), } } // Get the help for the command. - help, err := wsc.server.helpCacher.rpcMethodHelp(command) + help, err := wsc.server.helpCacher.rpcMethodHelp(method) if err != nil { context := "Failed to generate help" return nil, rpcInternalError(err.Error(), context) @@ -1972,7 +1971,7 @@ func handleWebsocketHelp(wsc *wsClient, icmd interface{}) (interface{}, error) { // handleLoadTxFilter implements the loadtxfilter command extension for // websocket connections. func handleLoadTxFilter(wsc *wsClient, icmd interface{}) (interface{}, error) { - cmd := icmd.(*dcrjson.LoadTxFilterCmd) + cmd := icmd.(*types.LoadTxFilterCmd) outPoints := make([]*wire.OutPoint, len(cmd.OutPoints)) for i := range cmd.OutPoints { @@ -2021,7 +2020,7 @@ func handleNotifyBlocks(wsc *wsClient, icmd interface{}) (interface{}, error) { // handleSession implements the session command extension for websocket // connections. func handleSession(wsc *wsClient, icmd interface{}) (interface{}, error) { - return &dcrjson.SessionResult{SessionID: wsc.sessionID}, nil + return &types.SessionResult{SessionID: wsc.sessionID}, nil } // handleWinningTickets implements the notifywinningtickets command @@ -2062,7 +2061,7 @@ func handleStopNotifyBlocks(wsc *wsClient, icmd interface{}) (interface{}, error // handleNotifyNewTransations implements the notifynewtransactions command // extension for websocket connections. func handleNotifyNewTransactions(wsc *wsClient, icmd interface{}) (interface{}, error) { - cmd, ok := icmd.(*dcrjson.NotifyNewTransactionsCmd) + cmd, ok := icmd.(*types.NotifyNewTransactionsCmd) if !ok { return nil, dcrjson.ErrRPCInternal } @@ -2165,7 +2164,7 @@ func rescanBlock(filter *wsClientFilter, block *dcrutil.Block) []string { // handleRescan implements the rescan command extension for websocket // connections. func handleRescan(wsc *wsClient, icmd interface{}) (interface{}, error) { - cmd, ok := icmd.(*dcrjson.RescanCmd) + cmd, ok := icmd.(*types.RescanCmd) if !ok { return nil, dcrjson.ErrRPCInternal } @@ -2181,12 +2180,12 @@ func handleRescan(wsc *wsClient, icmd interface{}) (interface{}, error) { } } - blockHashes, err := dcrjson.DecodeConcatenatedHashes(cmd.BlockHashes) + blockHashes, err := decodeHashes(cmd.BlockHashes) if err != nil { return nil, err } - discoveredData := make([]dcrjson.RescannedBlock, 0, len(blockHashes)) + discoveredData := make([]types.RescannedBlock, 0, len(blockHashes)) // Iterate over each block in the request and rescan. When a block // contains relevant transactions, add it to the response. @@ -2211,14 +2210,14 @@ func handleRescan(wsc *wsClient, icmd interface{}) (interface{}, error) { transactions := rescanBlock(filter, block) if len(transactions) != 0 { - discoveredData = append(discoveredData, dcrjson.RescannedBlock{ + discoveredData = append(discoveredData, types.RescannedBlock{ Hash: blockHashes[i].String(), Transactions: transactions, }) } } - return &dcrjson.RescanResult{DiscoveredData: discoveredData}, nil + return &types.RescanResult{DiscoveredData: discoveredData}, nil } func init() {