[DEV-195] Implement addmanualnode, getallmanualnodesinfo, getmanualnodeinfo and removemanualnode RPC-API calls (#87)

* [DEV-195] Implement addmanualnode, getallmanualnodesinfo, getmanualnodeinfo and removemanualnode RPC-API calls

* [DEV-195] fix wrong types for handleRemoveManualNode and handleGetManualNodeInfo

* [DEV-195] fix addednode terminology to manualnode

* [DEV-195] add default values to details and onetry

* [DEV-195] fix comments
This commit is contained in:
Ori Newman 2018-10-11 12:38:54 +03:00 committed by stasatdaglabs
parent bb10f8484c
commit b0aaa79ad0
11 changed files with 256 additions and 214 deletions

View File

@ -8,7 +8,7 @@
package btcjson package btcjson
// NodeSubCmd defines the type used in the addnode JSON-RPC command for the // NodeSubCmd defines the type used in the `node` JSON-RPC command for the
// sub command field. // sub command field.
type NodeSubCmd string type NodeSubCmd string

View File

@ -14,35 +14,31 @@ import (
"github.com/daglabs/btcd/wire" "github.com/daglabs/btcd/wire"
) )
// AddNodeSubCmd defines the type used in the addnode JSON-RPC command for the // AddManualNodeCmd defines the addmanualnode JSON-RPC command.
// sub command field. type AddManualNodeCmd struct {
type AddNodeSubCmd string
const (
// ANAdd indicates the specified host should be added as a persistent
// peer.
ANAdd AddNodeSubCmd = "add"
// ANRemove indicates the specified peer should be removed.
ANRemove AddNodeSubCmd = "remove"
// ANOneTry indicates the specified host should try to connect once,
// but it should not be made persistent.
ANOneTry AddNodeSubCmd = "onetry"
)
// AddNodeCmd defines the addnode JSON-RPC command.
type AddNodeCmd struct {
Addr string Addr string
SubCmd AddNodeSubCmd `jsonrpcusage:"\"add|remove|onetry\""` OneTry *bool `jsonrpcdefault:"false"`
} }
// NewAddNodeCmd returns a new instance which can be used to issue an addnode // NewAddManualNodeCmd returns a new instance which can be used to issue an addmanualnode
// JSON-RPC command. // JSON-RPC command.
func NewAddNodeCmd(addr string, subCmd AddNodeSubCmd) *AddNodeCmd { func NewAddManualNodeCmd(addr string, oneTry *bool) *AddManualNodeCmd {
return &AddNodeCmd{ return &AddManualNodeCmd{
Addr: addr, Addr: addr,
SubCmd: subCmd, OneTry: oneTry,
}
}
// RemoveManualNodeCmd defines the removemanualnode JSON-RPC command.
type RemoveManualNodeCmd struct {
Addr string
}
// NewRemoveManualNodeCmd returns a new instance which can be used to issue an removemanualnode
// JSON-RPC command.
func NewRemoveManualNodeCmd(addr string) *RemoveManualNodeCmd {
return &RemoveManualNodeCmd{
Addr: addr,
} }
} }
@ -100,21 +96,31 @@ func NewDecodeScriptCmd(hexScript string) *DecodeScriptCmd {
} }
} }
// GetAddedNodeInfoCmd defines the getaddednodeinfo JSON-RPC command. // GetManualNodeInfoCmd defines the getmanualnodeinfo JSON-RPC command.
type GetAddedNodeInfoCmd struct { type GetManualNodeInfoCmd struct {
DNS bool Node string
Node *string Details *bool `jsonrpcdefault:"true"`
} }
// NewGetAddedNodeInfoCmd returns a new instance which can be used to issue a // NewGetManualNodeInfoCmd returns a new instance which can be used to issue a
// getaddednodeinfo JSON-RPC command. // getmanualnodeinfo JSON-RPC command.
// func NewGetManualNodeInfoCmd(node string, details *bool) *GetManualNodeInfoCmd {
// The parameters which are pointers indicate they are optional. Passing nil return &GetManualNodeInfoCmd{
// for optional parameters will use the default value. Details: details,
func NewGetAddedNodeInfoCmd(dns bool, node *string) *GetAddedNodeInfoCmd { Node: node,
return &GetAddedNodeInfoCmd{ }
DNS: dns, }
Node: node,
// GetAllManualNodesInfoCmd defines the getallmanualnodesinfo JSON-RPC command.
type GetAllManualNodesInfoCmd struct {
Details *bool `jsonrpcdefault:"true"`
}
// NewGetAllManualNodesInfoCmd returns a new instance which can be used to issue a
// getallmanualnodesinfo JSON-RPC command.
func NewGetAllManualNodesInfoCmd(details *bool) *GetAllManualNodesInfoCmd {
return &GetAllManualNodesInfoCmd{
Details: details,
} }
} }
@ -761,11 +767,11 @@ func init() {
// No special flags for commands in this file. // No special flags for commands in this file.
flags := UsageFlag(0) flags := UsageFlag(0)
MustRegisterCmd("addnode", (*AddNodeCmd)(nil), flags) MustRegisterCmd("addmanualnode", (*AddManualNodeCmd)(nil), flags)
MustRegisterCmd("createrawtransaction", (*CreateRawTransactionCmd)(nil), flags) MustRegisterCmd("createrawtransaction", (*CreateRawTransactionCmd)(nil), flags)
MustRegisterCmd("decoderawtransaction", (*DecodeRawTransactionCmd)(nil), flags) MustRegisterCmd("decoderawtransaction", (*DecodeRawTransactionCmd)(nil), flags)
MustRegisterCmd("decodescript", (*DecodeScriptCmd)(nil), flags) MustRegisterCmd("decodescript", (*DecodeScriptCmd)(nil), flags)
MustRegisterCmd("getaddednodeinfo", (*GetAddedNodeInfoCmd)(nil), flags) MustRegisterCmd("getallmanualnodesinfo", (*GetAllManualNodesInfoCmd)(nil), flags)
MustRegisterCmd("getbestblockhash", (*GetBestBlockHashCmd)(nil), flags) MustRegisterCmd("getbestblockhash", (*GetBestBlockHashCmd)(nil), flags)
MustRegisterCmd("getblock", (*GetBlockCmd)(nil), flags) MustRegisterCmd("getblock", (*GetBlockCmd)(nil), flags)
MustRegisterCmd("getblockdaginfo", (*GetBlockDAGInfoCmd)(nil), flags) MustRegisterCmd("getblockdaginfo", (*GetBlockDAGInfoCmd)(nil), flags)
@ -781,6 +787,7 @@ func init() {
MustRegisterCmd("getgenerate", (*GetGenerateCmd)(nil), flags) MustRegisterCmd("getgenerate", (*GetGenerateCmd)(nil), flags)
MustRegisterCmd("gethashespersec", (*GetHashesPerSecCmd)(nil), flags) MustRegisterCmd("gethashespersec", (*GetHashesPerSecCmd)(nil), flags)
MustRegisterCmd("getinfo", (*GetInfoCmd)(nil), flags) MustRegisterCmd("getinfo", (*GetInfoCmd)(nil), flags)
MustRegisterCmd("getmanualnodeinfo", (*GetManualNodeInfoCmd)(nil), flags)
MustRegisterCmd("getmempoolentry", (*GetMempoolEntryCmd)(nil), flags) MustRegisterCmd("getmempoolentry", (*GetMempoolEntryCmd)(nil), flags)
MustRegisterCmd("getmempoolinfo", (*GetMempoolInfoCmd)(nil), flags) MustRegisterCmd("getmempoolinfo", (*GetMempoolInfoCmd)(nil), flags)
MustRegisterCmd("getmininginfo", (*GetMiningInfoCmd)(nil), flags) MustRegisterCmd("getmininginfo", (*GetMiningInfoCmd)(nil), flags)
@ -798,6 +805,7 @@ func init() {
MustRegisterCmd("ping", (*PingCmd)(nil), flags) MustRegisterCmd("ping", (*PingCmd)(nil), flags)
MustRegisterCmd("preciousblock", (*PreciousBlockCmd)(nil), flags) MustRegisterCmd("preciousblock", (*PreciousBlockCmd)(nil), flags)
MustRegisterCmd("reconsiderblock", (*ReconsiderBlockCmd)(nil), flags) MustRegisterCmd("reconsiderblock", (*ReconsiderBlockCmd)(nil), flags)
MustRegisterCmd("removemanualnode", (*RemoveManualNodeCmd)(nil), flags)
MustRegisterCmd("searchrawtransactions", (*SearchRawTransactionsCmd)(nil), flags) MustRegisterCmd("searchrawtransactions", (*SearchRawTransactionsCmd)(nil), flags)
MustRegisterCmd("sendrawtransaction", (*SendRawTransactionCmd)(nil), flags) MustRegisterCmd("sendrawtransaction", (*SendRawTransactionCmd)(nil), flags)
MustRegisterCmd("setgenerate", (*SetGenerateCmd)(nil), flags) MustRegisterCmd("setgenerate", (*SetGenerateCmd)(nil), flags)

View File

@ -31,15 +31,15 @@ func TestDAGSvrCmds(t *testing.T) {
unmarshalled interface{} unmarshalled interface{}
}{ }{
{ {
name: "addnode", name: "addmanualnode",
newCmd: func() (interface{}, error) { newCmd: func() (interface{}, error) {
return btcjson.NewCmd("addnode", "127.0.0.1", btcjson.ANRemove) return btcjson.NewCmd("addmanualnode", "127.0.0.1")
}, },
staticCmd: func() interface{} { staticCmd: func() interface{} {
return btcjson.NewAddNodeCmd("127.0.0.1", btcjson.ANRemove) return btcjson.NewAddManualNodeCmd("127.0.0.1", nil)
}, },
marshalled: `{"jsonrpc":"1.0","method":"addnode","params":["127.0.0.1","remove"],"id":1}`, marshalled: `{"jsonrpc":"1.0","method":"addmanualnode","params":["127.0.0.1"],"id":1}`,
unmarshalled: &btcjson.AddNodeCmd{Addr: "127.0.0.1", SubCmd: btcjson.ANRemove}, unmarshalled: &btcjson.AddManualNodeCmd{Addr: "127.0.0.1", OneTry: btcjson.Bool(false)},
}, },
{ {
name: "createrawtransaction", name: "createrawtransaction",
@ -104,29 +104,15 @@ func TestDAGSvrCmds(t *testing.T) {
unmarshalled: &btcjson.DecodeScriptCmd{HexScript: "00"}, unmarshalled: &btcjson.DecodeScriptCmd{HexScript: "00"},
}, },
{ {
name: "getaddednodeinfo", name: "getallmanualnodesinfo",
newCmd: func() (interface{}, error) { newCmd: func() (interface{}, error) {
return btcjson.NewCmd("getaddednodeinfo", true) return btcjson.NewCmd("getallmanualnodesinfo")
}, },
staticCmd: func() interface{} { staticCmd: func() interface{} {
return btcjson.NewGetAddedNodeInfoCmd(true, nil) return btcjson.NewGetAllManualNodesInfoCmd(nil)
},
marshalled: `{"jsonrpc":"1.0","method":"getaddednodeinfo","params":[true],"id":1}`,
unmarshalled: &btcjson.GetAddedNodeInfoCmd{DNS: true, Node: nil},
},
{
name: "getaddednodeinfo optional",
newCmd: func() (interface{}, error) {
return btcjson.NewCmd("getaddednodeinfo", true, "127.0.0.1")
},
staticCmd: func() interface{} {
return btcjson.NewGetAddedNodeInfoCmd(true, btcjson.String("127.0.0.1"))
},
marshalled: `{"jsonrpc":"1.0","method":"getaddednodeinfo","params":[true,"127.0.0.1"],"id":1}`,
unmarshalled: &btcjson.GetAddedNodeInfoCmd{
DNS: true,
Node: btcjson.String("127.0.0.1"),
}, },
marshalled: `{"jsonrpc":"1.0","method":"getallmanualnodesinfo","params":[],"id":1}`,
unmarshalled: &btcjson.GetAllManualNodesInfoCmd{Details: btcjson.Bool(true)},
}, },
{ {
name: "getbestblockhash", name: "getbestblockhash",
@ -416,6 +402,20 @@ func TestDAGSvrCmds(t *testing.T) {
marshalled: `{"jsonrpc":"1.0","method":"getinfo","params":[],"id":1}`, marshalled: `{"jsonrpc":"1.0","method":"getinfo","params":[],"id":1}`,
unmarshalled: &btcjson.GetInfoCmd{}, unmarshalled: &btcjson.GetInfoCmd{},
}, },
{
name: "getmanualnodeinfo",
newCmd: func() (interface{}, error) {
return btcjson.NewCmd("getmanualnodeinfo", "127.0.0.1")
},
staticCmd: func() interface{} {
return btcjson.NewGetManualNodeInfoCmd("127.0.0.1", nil)
},
marshalled: `{"jsonrpc":"1.0","method":"getmanualnodeinfo","params":["127.0.0.1"],"id":1}`,
unmarshalled: &btcjson.GetManualNodeInfoCmd{
Node: "127.0.0.1",
Details: btcjson.Bool(true),
},
},
{ {
name: "getmempoolentry", name: "getmempoolentry",
newCmd: func() (interface{}, error) { newCmd: func() (interface{}, error) {
@ -727,6 +727,17 @@ func TestDAGSvrCmds(t *testing.T) {
BlockHash: "123", BlockHash: "123",
}, },
}, },
{
name: "removemanualnode",
newCmd: func() (interface{}, error) {
return btcjson.NewCmd("removemanualnode", "127.0.0.1")
},
staticCmd: func() interface{} {
return btcjson.NewRemoveManualNodeCmd("127.0.0.1")
},
marshalled: `{"jsonrpc":"1.0","method":"removemanualnode","params":["127.0.0.1"],"id":1}`,
unmarshalled: &btcjson.RemoveManualNodeCmd{Addr: "127.0.0.1"},
},
{ {
name: "searchrawtransactions", name: "searchrawtransactions",
newCmd: func() (interface{}, error) { newCmd: func() (interface{}, error) {

View File

@ -61,18 +61,18 @@ type DecodeScriptResult struct {
P2sh string `json:"p2sh,omitempty"` P2sh string `json:"p2sh,omitempty"`
} }
// GetAddedNodeInfoResultAddr models the data of the addresses portion of the // GetManualNodeInfoResultAddr models the data of the addresses portion of the
// getaddednodeinfo command. // getmanualnodeinfo command.
type GetAddedNodeInfoResultAddr struct { type GetManualNodeInfoResultAddr struct {
Address string `json:"address"` Address string `json:"address"`
Connected string `json:"connected"` Connected string `json:"connected"`
} }
// GetAddedNodeInfoResult models the data from the getaddednodeinfo command. // GetManualNodeInfoResult models the data from the getmanualnodeinfo command.
type GetAddedNodeInfoResult struct { type GetManualNodeInfoResult struct {
AddedNode string `json:"addednode"` ManualNode string `json:"manualnode"`
Connected *bool `json:"connected,omitempty"` Connected *bool `json:"connected,omitempty"`
Addresses *[]GetAddedNodeInfoResultAddr `json:"addresses,omitempty"` Addresses *[]GetManualNodeInfoResultAddr `json:"addresses,omitempty"`
} }
// SoftForkDescription describes the current state of a soft-fork which was // SoftForkDescription describes the current state of a soft-fork which was

View File

@ -9,7 +9,6 @@ import (
"time" "time"
"github.com/daglabs/btcd/dagconfig/daghash" "github.com/daglabs/btcd/dagconfig/daghash"
"github.com/daglabs/btcd/rpcclient"
) )
// JoinType is an enum representing a particular type of "node join". A node // JoinType is an enum representing a particular type of "node join". A node
@ -115,7 +114,7 @@ func ConnectNode(from *Harness, to *Harness) error {
numPeers := len(peerInfo) numPeers := len(peerInfo)
targetAddr := to.node.config.listen targetAddr := to.node.config.listen
if err := from.Node.AddNode(targetAddr, rpcclient.ANAdd); err != nil { if err := from.Node.AddManualNode(targetAddr); err != nil {
return err return err
} }

View File

@ -10,29 +10,6 @@ import (
"github.com/daglabs/btcd/btcjson" "github.com/daglabs/btcd/btcjson"
) )
// AddNodeCommand enumerates the available commands that the AddNode function
// accepts.
type AddNodeCommand string
// Constants used to indicate the command for the AddNode function.
const (
// ANAdd indicates the specified host should be added as a persistent
// peer.
ANAdd AddNodeCommand = "add"
// ANRemove indicates the specified peer should be removed.
ANRemove AddNodeCommand = "remove"
// ANOneTry indicates the specified host should try to connect once,
// but it should not be made persistent.
ANOneTry AddNodeCommand = "onetry"
)
// String returns the AddNodeCommand in human-readable form.
func (cmd AddNodeCommand) String() string {
return string(cmd)
}
// FutureAddNodeResult is a future promise to deliver the result of an // FutureAddNodeResult is a future promise to deliver the result of an
// AddNodeAsync RPC invocation (or an applicable error). // AddNodeAsync RPC invocation (or an applicable error).
type FutureAddNodeResult chan *response type FutureAddNodeResult chan *response
@ -44,39 +21,39 @@ func (r FutureAddNodeResult) Receive() error {
return err return err
} }
// AddNodeAsync returns an instance of a type that can be used to get the result // AddManualNodeAsync returns an instance of a type that can be used to get the result
// of the RPC at some future time by invoking the Receive function on the // of the RPC at some future time by invoking the Receive function on the
// returned instance. // returned instance.
// //
// See AddNode for the blocking version and more details. // See AddNode for the blocking version and more details.
func (c *Client) AddNodeAsync(host string, command AddNodeCommand) FutureAddNodeResult { func (c *Client) AddManualNodeAsync(host string) FutureAddNodeResult {
cmd := btcjson.NewAddNodeCmd(host, btcjson.AddNodeSubCmd(command)) cmd := btcjson.NewAddManualNodeCmd(host, btcjson.Bool(false))
return c.sendCmd(cmd) return c.sendCmd(cmd)
} }
// AddNode attempts to perform the passed command on the passed persistent peer. // AddManualNode attempts to perform the passed command on the passed persistent peer.
// For example, it can be used to add or a remove a persistent peer, or to do // For example, it can be used to add or a remove a persistent peer, or to do
// a one time connection to a peer. // a one time connection to a peer.
// //
// It may not be used to remove non-persistent peers. // It may not be used to remove non-persistent peers.
func (c *Client) AddNode(host string, command AddNodeCommand) error { func (c *Client) AddManualNode(host string) error {
return c.AddNodeAsync(host, command).Receive() return c.AddManualNodeAsync(host).Receive()
} }
// FutureGetAddedNodeInfoResult is a future promise to deliver the result of a // FutureGetManualNodeInfoResult is a future promise to deliver the result of a
// GetAddedNodeInfoAsync RPC invocation (or an applicable error). // GetManualNodeInfoAsync RPC invocation (or an applicable error).
type FutureGetAddedNodeInfoResult chan *response type FutureGetManualNodeInfoResult chan *response
// Receive waits for the response promised by the future and returns information // Receive waits for the response promised by the future and returns information
// about manually added (persistent) peers. // about manually added (persistent) peers.
func (r FutureGetAddedNodeInfoResult) Receive() ([]btcjson.GetAddedNodeInfoResult, error) { func (r FutureGetManualNodeInfoResult) Receive() ([]btcjson.GetManualNodeInfoResult, error) {
res, err := receiveFuture(r) res, err := receiveFuture(r)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Unmarshal as an array of getaddednodeinfo result objects. // Unmarshal as an array of getmanualnodeinfo result objects.
var nodeInfo []btcjson.GetAddedNodeInfoResult var nodeInfo []btcjson.GetManualNodeInfoResult
err = json.Unmarshal(res, &nodeInfo) err = json.Unmarshal(res, &nodeInfo)
if err != nil { if err != nil {
return nil, err return nil, err
@ -85,31 +62,31 @@ func (r FutureGetAddedNodeInfoResult) Receive() ([]btcjson.GetAddedNodeInfoResul
return nodeInfo, nil return nodeInfo, nil
} }
// GetAddedNodeInfoAsync returns an instance of a type that can be used to get // GetManualNodeInfoAsync returns an instance of a type that can be used to get
// the result of the RPC at some future time by invoking the Receive function on // the result of the RPC at some future time by invoking the Receive function on
// the returned instance. // the returned instance.
// //
// See GetAddedNodeInfo for the blocking version and more details. // See GetManualNodeInfo for the blocking version and more details.
func (c *Client) GetAddedNodeInfoAsync(peer string) FutureGetAddedNodeInfoResult { func (c *Client) GetManualNodeInfoAsync(peer string) FutureGetManualNodeInfoResult {
cmd := btcjson.NewGetAddedNodeInfoCmd(true, &peer) cmd := btcjson.NewGetManualNodeInfoCmd(peer, nil)
return c.sendCmd(cmd) return c.sendCmd(cmd)
} }
// GetAddedNodeInfo returns information about manually added (persistent) peers. // GetManualNodeInfo returns information about manually added (persistent) peers.
// //
// See GetAddedNodeInfoNoDNS to retrieve only a list of the added (persistent) // See GetManualNodeInfoNoDNS to retrieve only a list of the added (persistent)
// peers. // peers.
func (c *Client) GetAddedNodeInfo(peer string) ([]btcjson.GetAddedNodeInfoResult, error) { func (c *Client) GetManualNodeInfo(peer string) ([]btcjson.GetManualNodeInfoResult, error) {
return c.GetAddedNodeInfoAsync(peer).Receive() return c.GetManualNodeInfoAsync(peer).Receive()
} }
// FutureGetAddedNodeInfoNoDNSResult is a future promise to deliver the result // FutureGetManualNodeInfoNoDNSResult is a future promise to deliver the result
// of a GetAddedNodeInfoNoDNSAsync RPC invocation (or an applicable error). // of a GetManualNodeInfoNoDNSAsync RPC invocation (or an applicable error).
type FutureGetAddedNodeInfoNoDNSResult chan *response type FutureGetManualNodeInfoNoDNSResult chan *response
// Receive waits for the response promised by the future and returns a list of // Receive waits for the response promised by the future and returns a list of
// manually added (persistent) peers. // manually added (persistent) peers.
func (r FutureGetAddedNodeInfoNoDNSResult) Receive() ([]string, error) { func (r FutureGetManualNodeInfoNoDNSResult) Receive() ([]string, error) {
res, err := receiveFuture(r) res, err := receiveFuture(r)
if err != nil { if err != nil {
return nil, err return nil, err
@ -125,23 +102,23 @@ func (r FutureGetAddedNodeInfoNoDNSResult) Receive() ([]string, error) {
return nodes, nil return nodes, nil
} }
// GetAddedNodeInfoNoDNSAsync returns an instance of a type that can be used to // GetManualNodeInfoNoDNSAsync returns an instance of a type that can be used to
// get the result of the RPC at some future time by invoking the Receive // get the result of the RPC at some future time by invoking the Receive
// function on the returned instance. // function on the returned instance.
// //
// See GetAddedNodeInfoNoDNS for the blocking version and more details. // See GetManualNodeInfoNoDNS for the blocking version and more details.
func (c *Client) GetAddedNodeInfoNoDNSAsync(peer string) FutureGetAddedNodeInfoNoDNSResult { func (c *Client) GetManualNodeInfoNoDNSAsync(peer string) FutureGetManualNodeInfoNoDNSResult {
cmd := btcjson.NewGetAddedNodeInfoCmd(false, &peer) cmd := btcjson.NewGetManualNodeInfoCmd(peer, btcjson.Bool(false))
return c.sendCmd(cmd) return c.sendCmd(cmd)
} }
// GetAddedNodeInfoNoDNS returns a list of manually added (persistent) peers. // GetManualNodeInfoNoDNS returns a list of manually added (persistent) peers.
// This works by setting the dns flag to false in the underlying RPC. // This works by setting the dns flag to false in the underlying RPC.
// //
// See GetAddedNodeInfo to obtain more information about each added (persistent) // See GetManualNodeInfo to obtain more information about each added (persistent)
// peer. // peer.
func (c *Client) GetAddedNodeInfoNoDNS(peer string) ([]string, error) { func (c *Client) GetManualNodeInfoNoDNS(peer string) ([]string, error) {
return c.GetAddedNodeInfoNoDNSAsync(peer).Receive() return c.GetManualNodeInfoNoDNSAsync(peer).Receive()
} }
// FutureGetConnectionCountResult is a future promise to deliver the result // FutureGetConnectionCountResult is a future promise to deliver the result

View File

@ -1615,8 +1615,8 @@ type getOutboundGroup struct {
reply chan int reply chan int
} }
//GetAddedNodesMsg is the message type which is used by the rpc server to get the list of persistent peers from the p2p server //GetManualNodesMsg is the message type which is used by the rpc server to get the list of persistent peers from the p2p server
type GetAddedNodesMsg struct { type GetManualNodesMsg struct {
Reply chan []*Peer Reply chan []*Peer
} }
@ -1712,7 +1712,7 @@ func (s *Server) handleQuery(state *peerState, querymsg interface{}) {
msg.reply <- 0 msg.reply <- 0
} }
// Request a list of the persistent (added) peers. // Request a list of the persistent (added) peers.
case GetAddedNodesMsg: case GetManualNodesMsg:
// Respond with a slice of the relevant peers. // Respond with a slice of the relevant peers.
peers := make([]*Peer, 0, len(state.persistentPeers)) peers := make([]*Peer, 0, len(state.persistentPeers))
for _, sp := range state.persistentPeers { for _, sp := range state.persistentPeers {

View File

@ -13,8 +13,8 @@ import (
"github.com/daglabs/btcd/netsync" "github.com/daglabs/btcd/netsync"
"github.com/daglabs/btcd/peer" "github.com/daglabs/btcd/peer"
"github.com/daglabs/btcd/server/p2p" "github.com/daglabs/btcd/server/p2p"
"github.com/daglabs/btcd/wire"
"github.com/daglabs/btcd/util" "github.com/daglabs/btcd/util"
"github.com/daglabs/btcd/wire"
) )
// rpcPeer provides a peer for use with the RPC server and implements the // rpcPeer provides a peer for use with the RPC server and implements the
@ -189,7 +189,7 @@ func (cm *rpcConnManager) ConnectedPeers() []rpcserverPeer {
// rpcserverConnManager interface implementation. // rpcserverConnManager interface implementation.
func (cm *rpcConnManager) PersistentPeers() []rpcserverPeer { func (cm *rpcConnManager) PersistentPeers() []rpcserverPeer {
replyChan := make(chan []*p2p.Peer) replyChan := make(chan []*p2p.Peer)
cm.server.Query <- p2p.GetAddedNodesMsg{Reply: replyChan} cm.server.Query <- p2p.GetManualNodesMsg{Reply: replyChan}
serverPeers := <-replyChan serverPeers := <-replyChan
// Convert to generic peers. // Convert to generic peers.

View File

@ -134,14 +134,14 @@ type commandHandler func(*Server, interface{}, <-chan struct{}) (interface{}, er
// a dependency loop. // a dependency loop.
var rpcHandlers map[string]commandHandler var rpcHandlers map[string]commandHandler
var rpcHandlersBeforeInit = map[string]commandHandler{ var rpcHandlersBeforeInit = map[string]commandHandler{
"addnode": handleAddNode, "addmanualnode": handleAddManualNode,
"createrawtransaction": handleCreateRawTransaction, "createrawtransaction": handleCreateRawTransaction,
"debuglevel": handleDebugLevel, "debuglevel": handleDebugLevel,
"decoderawtransaction": handleDecodeRawTransaction, "decoderawtransaction": handleDecodeRawTransaction,
"decodescript": handleDecodeScript, "decodescript": handleDecodeScript,
"estimatefee": handleEstimateFee, "estimatefee": handleEstimateFee,
"generate": handleGenerate, "generate": handleGenerate,
"getaddednodeinfo": handleGetAddedNodeInfo, "getallmanualnodesinfo": handleGetAllManualNodesInfo,
"getbestblock": handleGetBestBlock, "getbestblock": handleGetBestBlock,
"getbestblockhash": handleGetBestBlockHash, "getbestblockhash": handleGetBestBlockHash,
"getblock": handleGetBlock, "getblock": handleGetBlock,
@ -159,6 +159,7 @@ var rpcHandlersBeforeInit = map[string]commandHandler{
"gethashespersec": handleGetHashesPerSec, "gethashespersec": handleGetHashesPerSec,
"getheaders": handleGetHeaders, "getheaders": handleGetHeaders,
"getinfo": handleGetInfo, "getinfo": handleGetInfo,
"getmanualnodeinfo": handleGetManualNodeInfo,
"getmempoolinfo": handleGetMempoolInfo, "getmempoolinfo": handleGetMempoolInfo,
"getmininginfo": handleGetMiningInfo, "getmininginfo": handleGetMiningInfo,
"getnettotals": handleGetNetTotals, "getnettotals": handleGetNetTotals,
@ -170,6 +171,7 @@ var rpcHandlersBeforeInit = map[string]commandHandler{
"help": handleHelp, "help": handleHelp,
"node": handleNode, "node": handleNode,
"ping": handlePing, "ping": handlePing,
"removemanualnode": handleRemoveManualNode,
"searchrawtransactions": handleSearchRawTransactions, "searchrawtransactions": handleSearchRawTransactions,
"sendrawtransaction": handleSendRawTransaction, "sendrawtransaction": handleSendRawTransaction,
"setgenerate": handleSetGenerate, "setgenerate": handleSetGenerate,
@ -365,26 +367,38 @@ func handleAskWallet(s *Server, cmd interface{}, closeChan <-chan struct{}) (int
return nil, ErrRPCNoWallet return nil, ErrRPCNoWallet
} }
// handleAddNode handles addnode commands. // handleAddManualNode handles addmanualnode commands.
func handleAddNode(s *Server, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { func handleAddManualNode(s *Server, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
c := cmd.(*btcjson.AddNodeCmd) c := cmd.(*btcjson.AddManualNodeCmd)
addr := network.NormalizeAddress(c.Addr, s.cfg.ChainParams.DefaultPort) oneTry := c.OneTry != nil && *c.OneTry
addr := network.NormalizeAddress(c.Addr, s.cfg.DAGParams.DefaultPort)
var err error var err error
switch c.SubCmd { if oneTry {
case "add":
err = s.cfg.ConnMgr.Connect(addr, true)
case "remove":
err = s.cfg.ConnMgr.RemoveByAddr(addr)
case "onetry":
err = s.cfg.ConnMgr.Connect(addr, false) err = s.cfg.ConnMgr.Connect(addr, false)
default: } else {
err = s.cfg.ConnMgr.Connect(addr, true)
}
if err != nil {
return nil, &btcjson.RPCError{ return nil, &btcjson.RPCError{
Code: btcjson.ErrRPCInvalidParameter, Code: btcjson.ErrRPCInvalidParameter,
Message: "invalid subcommand for addnode", Message: err.Error(),
} }
} }
// no data returned unless an error.
return nil, nil
}
// handleRemoveManualNode handles removemanualnode command.
func handleRemoveManualNode(s *Server, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
c := cmd.(*btcjson.RemoveManualNodeCmd)
addr := network.NormalizeAddress(c.Addr, s.cfg.DAGParams.DefaultPort)
err := s.cfg.ConnMgr.RemoveByAddr(addr)
if err != nil { if err != nil {
return nil, &btcjson.RPCError{ return nil, &btcjson.RPCError{
Code: btcjson.ErrRPCInvalidParameter, Code: btcjson.ErrRPCInvalidParameter,
@ -403,7 +417,7 @@ func handleNode(s *Server, cmd interface{}, closeChan <-chan struct{}) (interfac
var addr string var addr string
var nodeID uint64 var nodeID uint64
var errN, err error var errN, err error
params := s.cfg.ChainParams params := s.cfg.DAGParams
switch c.SubCmd { switch c.SubCmd {
case "disconnect": case "disconnect":
// If we have a valid uint disconnect by node id. Otherwise, // If we have a valid uint disconnect by node id. Otherwise,
@ -546,7 +560,7 @@ func handleCreateRawTransaction(s *Server, cmd interface{}, closeChan <-chan str
// Add all transaction outputs to the transaction after performing // Add all transaction outputs to the transaction after performing
// some validity checks. // some validity checks.
params := s.cfg.ChainParams params := s.cfg.DAGParams
for encodedAddr, amount := range c.Amounts { for encodedAddr, amount := range c.Amounts {
// Ensure amount is in the valid range for monetary amounts. // Ensure amount is in the valid range for monetary amounts.
if amount <= 0 || amount > util.MaxSatoshi { if amount <= 0 || amount > util.MaxSatoshi {
@ -784,7 +798,7 @@ func handleDecodeRawTransaction(s *Server, cmd interface{}, closeChan <-chan str
Version: mtx.Version, Version: mtx.Version,
Locktime: mtx.LockTime, Locktime: mtx.LockTime,
Vin: createVinList(&mtx), Vin: createVinList(&mtx),
Vout: createVoutList(&mtx, s.cfg.ChainParams, nil), Vout: createVoutList(&mtx, s.cfg.DAGParams, nil),
} }
return txReply, nil return txReply, nil
} }
@ -811,14 +825,14 @@ func handleDecodeScript(s *Server, cmd interface{}, closeChan <-chan struct{}) (
// Ignore the error here since an error means the script couldn't parse // Ignore the error here since an error means the script couldn't parse
// and there is no additinal information about it anyways. // and there is no additinal information about it anyways.
scriptClass, addrs, reqSigs, _ := txscript.ExtractPkScriptAddrs(script, scriptClass, addrs, reqSigs, _ := txscript.ExtractPkScriptAddrs(script,
s.cfg.ChainParams) s.cfg.DAGParams)
addresses := make([]string, len(addrs)) addresses := make([]string, len(addrs))
for i, addr := range addrs { for i, addr := range addrs {
addresses[i] = addr.EncodeAddress() addresses[i] = addr.EncodeAddress()
} }
// Convert the script itself to a pay-to-script-hash address. // Convert the script itself to a pay-to-script-hash address.
p2sh, err := util.NewAddressScriptHash(script, s.cfg.ChainParams.Prefix) p2sh, err := util.NewAddressScriptHash(script, s.cfg.DAGParams.Prefix)
if err != nil { if err != nil {
context := "Failed to convert script to pay-to-script-hash" context := "Failed to convert script to pay-to-script-hash"
return nil, internalRPCError(err.Error(), context) return nil, internalRPCError(err.Error(), context)
@ -873,13 +887,13 @@ func handleGenerate(s *Server, cmd interface{}, closeChan <-chan struct{}) (inte
// Respond with an error if there's virtually 0 chance of mining a block // Respond with an error if there's virtually 0 chance of mining a block
// with the CPU. // with the CPU.
if !s.cfg.ChainParams.GenerateSupported { if !s.cfg.DAGParams.GenerateSupported {
return nil, &btcjson.RPCError{ return nil, &btcjson.RPCError{
Code: btcjson.ErrRPCDifficulty, Code: btcjson.ErrRPCDifficulty,
Message: fmt.Sprintf("No support for `generate` on "+ Message: fmt.Sprintf("No support for `generate` on "+
"the current network, %s, as it's unlikely to "+ "the current network, %s, as it's unlikely to "+
"be possible to mine a block with the CPU.", "be possible to mine a block with the CPU.",
s.cfg.ChainParams.Net), s.cfg.DAGParams.Net),
} }
} }
@ -913,15 +927,15 @@ func handleGenerate(s *Server, cmd interface{}, closeChan <-chan struct{}) (inte
return reply, nil return reply, nil
} }
// handleGetAddedNodeInfo handles getaddednodeinfo commands. // getManualNodesInfo handles getmanualnodeinfo and getallmanualnodesinfo commands.
func handleGetAddedNodeInfo(s *Server, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { func getManualNodesInfo(s *Server, detailsArg *bool, node string) (interface{}, error) {
c := cmd.(*btcjson.GetAddedNodeInfoCmd)
// Retrieve a list of persistent (added) peers from the server and details := detailsArg == nil || *detailsArg
// Retrieve a list of persistent (manual) peers from the server and
// filter the list of peers per the specified address (if any). // filter the list of peers per the specified address (if any).
peers := s.cfg.ConnMgr.PersistentPeers() peers := s.cfg.ConnMgr.PersistentPeers()
if c.Node != nil { if node != "" {
node := *c.Node
found := false found := false
for i, peer := range peers { for i, peer := range peers {
if peer.ToPeer().Addr() == node { if peer.ToPeer().Addr() == node {
@ -937,9 +951,9 @@ func handleGetAddedNodeInfo(s *Server, cmd interface{}, closeChan <-chan struct{
} }
} }
// Without the dns flag, the result is just a slice of the addresses as // Without the details flag, the result is just a slice of the addresses as
// strings. // strings.
if !c.DNS { if !details {
results := make([]string, 0, len(peers)) results := make([]string, 0, len(peers))
for _, peer := range peers { for _, peer := range peers {
results = append(results, peer.ToPeer().Addr()) results = append(results, peer.ToPeer().Addr())
@ -947,15 +961,15 @@ func handleGetAddedNodeInfo(s *Server, cmd interface{}, closeChan <-chan struct{
return results, nil return results, nil
} }
// With the dns flag, the result is an array of JSON objects which // With the details flag, the result is an array of JSON objects which
// include the result of DNS lookups for each peer. // include the result of DNS lookups for each peer.
results := make([]*btcjson.GetAddedNodeInfoResult, 0, len(peers)) results := make([]*btcjson.GetManualNodeInfoResult, 0, len(peers))
for _, rpcPeer := range peers { for _, rpcPeer := range peers {
// Set the "address" of the peer which could be an ip address // Set the "address" of the peer which could be an ip address
// or a domain name. // or a domain name.
peer := rpcPeer.ToPeer() peer := rpcPeer.ToPeer()
var result btcjson.GetAddedNodeInfoResult var result btcjson.GetManualNodeInfoResult
result.AddedNode = peer.Addr() result.ManualNode = peer.Addr()
result.Connected = btcjson.Bool(peer.Connected()) result.Connected = btcjson.Bool(peer.Connected())
// Split the address into host and port portions so we can do // Split the address into host and port portions so we can do
@ -987,9 +1001,9 @@ func handleGetAddedNodeInfo(s *Server, cmd interface{}, closeChan <-chan struct{
} }
// Add the addresses and connection info to the result. // Add the addresses and connection info to the result.
addrs := make([]btcjson.GetAddedNodeInfoResultAddr, 0, len(ipList)) addrs := make([]btcjson.GetManualNodeInfoResultAddr, 0, len(ipList))
for _, ip := range ipList { for _, ip := range ipList {
var addr btcjson.GetAddedNodeInfoResultAddr var addr btcjson.GetManualNodeInfoResultAddr
addr.Address = ip addr.Address = ip
addr.Connected = "false" addr.Connected = "false"
if ip == host && peer.Connected() { if ip == host && peer.Connected() {
@ -1003,6 +1017,26 @@ func handleGetAddedNodeInfo(s *Server, cmd interface{}, closeChan <-chan struct{
return results, nil return results, nil
} }
// handleGetManualNodeInfo handles getmanualnodeinfo commands.
func handleGetManualNodeInfo(s *Server, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
c := cmd.(*btcjson.GetManualNodeInfoCmd)
results, err := getManualNodesInfo(s, c.Details, c.Node)
if err != nil {
return nil, err
}
if resultsNonDetailed, ok := results.([]string); ok {
return resultsNonDetailed[0], nil
}
resultsDetailed := results.([]*btcjson.GetManualNodeInfoResult)
return resultsDetailed[0], nil
}
// handleGetAllManualNodesInfo handles getallmanualnodesinfo commands.
func handleGetAllManualNodesInfo(s *Server, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
c := cmd.(*btcjson.GetAllManualNodesInfoCmd)
return getManualNodesInfo(s, c.Details, "")
}
// handleGetBestBlock implements the getbestblock command. // handleGetBestBlock implements the getbestblock command.
func handleGetBestBlock(s *Server, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { func handleGetBestBlock(s *Server, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
// All other "get block" commands give either the height, the // All other "get block" commands give either the height, the
@ -1096,7 +1130,7 @@ func handleGetBlock(s *Server, cmd interface{}, closeChan <-chan struct{}) (inte
nextHashStrings = daghash.Strings(childHashes) nextHashStrings = daghash.Strings(childHashes)
} }
params := s.cfg.ChainParams params := s.cfg.DAGParams
blockHeader := &blk.MsgBlock().Header blockHeader := &blk.MsgBlock().Header
blockReply := btcjson.GetBlockVerboseResult{ blockReply := btcjson.GetBlockVerboseResult{
Hash: c.Hash, Hash: c.Hash,
@ -1163,7 +1197,7 @@ func softForkStatus(state blockdag.ThresholdState) (string, error) {
func handleGetBlockDAGInfo(s *Server, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { func handleGetBlockDAGInfo(s *Server, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
// Obtain a snapshot of the current best known DAG state. We'll // Obtain a snapshot of the current best known DAG state. We'll
// populate the response to this call primarily from this snapshot. // populate the response to this call primarily from this snapshot.
params := s.cfg.ChainParams params := s.cfg.DAGParams
dag := s.cfg.DAG dag := s.cfg.DAG
virtualBlock := dag.VirtualBlock() virtualBlock := dag.VirtualBlock()
@ -1290,7 +1324,7 @@ func handleGetBlockHeader(s *Server, cmd interface{}, closeChan <-chan struct{})
nextHashStrings = daghash.Strings(childHashes) nextHashStrings = daghash.Strings(childHashes)
} }
params := s.cfg.ChainParams params := s.cfg.DAGParams
blockHeaderReply := btcjson.GetBlockHeaderVerboseResult{ blockHeaderReply := btcjson.GetBlockHeaderVerboseResult{
Hash: c.Hash, Hash: c.Hash,
Confirmations: uint64(1 + s.cfg.DAG.Height() - blockHeight), //TODO: (Ori) This is probably wrong. Done only for compilation Confirmations: uint64(1 + s.cfg.DAG.Height() - blockHeight), //TODO: (Ori) This is probably wrong. Done only for compilation
@ -2165,13 +2199,13 @@ func handleGetConnectionCount(s *Server, cmd interface{}, closeChan <-chan struc
// handleGetCurrentNet implements the getcurrentnet command. // handleGetCurrentNet implements the getcurrentnet command.
func handleGetCurrentNet(s *Server, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { func handleGetCurrentNet(s *Server, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
return s.cfg.ChainParams.Net, nil return s.cfg.DAGParams.Net, nil
} }
// handleGetDifficulty implements the getdifficulty command. // handleGetDifficulty implements the getdifficulty command.
func handleGetDifficulty(s *Server, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { func handleGetDifficulty(s *Server, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
virtualBlock := s.cfg.DAG.VirtualBlock() virtualBlock := s.cfg.DAG.VirtualBlock()
return getDifficultyRatio(virtualBlock.SelectedTip().Header().Bits, s.cfg.ChainParams), nil return getDifficultyRatio(virtualBlock.SelectedTip().Header().Bits, s.cfg.DAGParams), nil
} }
// handleGetGenerate implements the getgenerate command. // handleGetGenerate implements the getgenerate command.
@ -2236,7 +2270,7 @@ func handleGetInfo(s *Server, cmd interface{}, closeChan <-chan struct{}) (inter
TimeOffset: int64(s.cfg.TimeSource.Offset().Seconds()), TimeOffset: int64(s.cfg.TimeSource.Offset().Seconds()),
Connections: s.cfg.ConnMgr.ConnectedCount(), Connections: s.cfg.ConnMgr.ConnectedCount(),
Proxy: config.MainConfig().Proxy, Proxy: config.MainConfig().Proxy,
Difficulty: getDifficultyRatio(virtualBlock.SelectedTip().Header().Bits, s.cfg.ChainParams), Difficulty: getDifficultyRatio(virtualBlock.SelectedTip().Header().Bits, s.cfg.DAGParams),
TestNet: config.MainConfig().TestNet3, TestNet: config.MainConfig().TestNet3,
RelayFee: config.MainConfig().MinRelayTxFee.ToBTC(), RelayFee: config.MainConfig().MinRelayTxFee.ToBTC(),
} }
@ -2294,7 +2328,7 @@ func handleGetMiningInfo(s *Server, cmd interface{}, closeChan <-chan struct{})
Blocks: int64(s.cfg.DAG.Height()), //TODO: (Ori) This is wrong. Done only for compilation Blocks: int64(s.cfg.DAG.Height()), //TODO: (Ori) This is wrong. Done only for compilation
CurrentBlockSize: uint64(selectedBlock.MsgBlock().SerializeSize()), CurrentBlockSize: uint64(selectedBlock.MsgBlock().SerializeSize()),
CurrentBlockTx: uint64(len(selectedBlock.MsgBlock().Transactions)), CurrentBlockTx: uint64(len(selectedBlock.MsgBlock().Transactions)),
Difficulty: getDifficultyRatio(virtualBlock.SelectedTip().Header().Bits, s.cfg.ChainParams), Difficulty: getDifficultyRatio(virtualBlock.SelectedTip().Header().Bits, s.cfg.DAGParams),
Generate: s.cfg.CPUMiner.IsMining(), Generate: s.cfg.CPUMiner.IsMining(),
GenProcLimit: s.cfg.CPUMiner.NumWorkers(), GenProcLimit: s.cfg.CPUMiner.NumWorkers(),
HashesPerSec: int64(s.cfg.CPUMiner.HashesPerSecond()), HashesPerSec: int64(s.cfg.CPUMiner.HashesPerSecond()),
@ -2493,7 +2527,7 @@ func handleGetRawTransaction(s *Server, cmd interface{}, closeChan <-chan struct
dagHeight = s.cfg.DAG.Height() dagHeight = s.cfg.DAG.Height()
} }
rawTxn, err := createTxRawResult(s.cfg.ChainParams, mtx, txHash.String(), rawTxn, err := createTxRawResult(s.cfg.DAGParams, mtx, txHash.String(),
blkHeader, blkHashStr, blkHeight, dagHeight) blkHeader, blkHashStr, blkHeight, dagHeight)
if err != nil { if err != nil {
return nil, err return nil, err
@ -2583,7 +2617,7 @@ func handleGetTxOut(s *Server, cmd interface{}, closeChan <-chan struct{}) (inte
// Ignore the error here since an error means the script couldn't parse // Ignore the error here since an error means the script couldn't parse
// and there is no additional information about it anyways. // and there is no additional information about it anyways.
scriptClass, addrs, reqSigs, _ := txscript.ExtractPkScriptAddrs(pkScript, scriptClass, addrs, reqSigs, _ := txscript.ExtractPkScriptAddrs(pkScript,
s.cfg.ChainParams) s.cfg.DAGParams)
addresses := make([]string, len(addrs)) addresses := make([]string, len(addrs))
for i, addr := range addrs { for i, addr := range addrs {
addresses[i] = addr.EncodeAddress() addresses[i] = addr.EncodeAddress()
@ -2905,7 +2939,7 @@ func handleSearchRawTransactions(s *Server, cmd interface{}, closeChan <-chan st
} }
// Attempt to decode the supplied address. // Attempt to decode the supplied address.
params := s.cfg.ChainParams params := s.cfg.DAGParams
addr, err := util.DecodeAddress(c.Address, params.Prefix) addr, err := util.DecodeAddress(c.Address, params.Prefix)
if err != nil { if err != nil {
return nil, &btcjson.RPCError{ return nil, &btcjson.RPCError{
@ -3305,7 +3339,7 @@ func handleValidateAddress(s *Server, cmd interface{}, closeChan <-chan struct{}
c := cmd.(*btcjson.ValidateAddressCmd) c := cmd.(*btcjson.ValidateAddressCmd)
result := btcjson.ValidateAddressResult{} result := btcjson.ValidateAddressResult{}
addr, err := util.DecodeAddress(c.Address, s.cfg.ChainParams.Prefix) addr, err := util.DecodeAddress(c.Address, s.cfg.DAGParams.Prefix)
if err != nil { if err != nil {
// Return the default value (false) for IsValid. // Return the default value (false) for IsValid.
return result, nil return result, nil
@ -3338,7 +3372,7 @@ func verifyDAG(s *Server, level, depth int32) error {
// Level 1 does basic chain sanity checks. // Level 1 does basic chain sanity checks.
if level > 0 { if level > 0 {
err := blockdag.CheckBlockSanity(block, err := blockdag.CheckBlockSanity(block,
s.cfg.ChainParams.PowLimit, s.cfg.TimeSource) s.cfg.DAGParams.PowLimit, s.cfg.TimeSource)
if err != nil { if err != nil {
log.Errorf("Verify is unable to validate "+ log.Errorf("Verify is unable to validate "+
"block at hash %v height %d: %v", "block at hash %v height %d: %v",
@ -3375,7 +3409,7 @@ func handleVerifyMessage(s *Server, cmd interface{}, closeChan <-chan struct{})
c := cmd.(*btcjson.VerifyMessageCmd) c := cmd.(*btcjson.VerifyMessageCmd)
// Decode the provided address. // Decode the provided address.
params := s.cfg.ChainParams params := s.cfg.DAGParams
addr, err := util.DecodeAddress(c.Address, params.Prefix) addr, err := util.DecodeAddress(c.Address, params.Prefix)
if err != nil { if err != nil {
return nil, &btcjson.RPCError{ return nil, &btcjson.RPCError{
@ -4068,10 +4102,10 @@ type rpcserverConfig struct {
// These fields allow the RPC server to interface with the local block // These fields allow the RPC server to interface with the local block
// chain data and state. // chain data and state.
TimeSource blockdag.MedianTimeSource TimeSource blockdag.MedianTimeSource
DAG *blockdag.BlockDAG DAG *blockdag.BlockDAG
ChainParams *dagconfig.Params DAGParams *dagconfig.Params
DB database.DB DB database.DB
// TxMemPool defines the transaction memory pool to interact with. // TxMemPool defines the transaction memory pool to interact with.
TxMemPool *mempool.TxPool TxMemPool *mempool.TxPool
@ -4168,7 +4202,7 @@ func NewRPCServer(
ConnMgr: &rpcConnManager{p2pServer}, ConnMgr: &rpcConnManager{p2pServer},
SyncMgr: &rpcSyncMgr{p2pServer, p2pServer.SyncManager}, SyncMgr: &rpcSyncMgr{p2pServer, p2pServer.SyncManager},
TimeSource: p2pServer.TimeSource, TimeSource: p2pServer.TimeSource,
ChainParams: p2pServer.DAGParams, DAGParams: p2pServer.DAGParams,
DB: db, DB: db,
TxMemPool: p2pServer.TxMemPool, TxMemPool: p2pServer.TxMemPool,
Generator: blockTemplateGenerator, Generator: blockTemplateGenerator,

View File

@ -29,10 +29,10 @@ var helpDescsEnUS = map[string]string{
"debuglevel--result0": "The string 'Done.'", "debuglevel--result0": "The string 'Done.'",
"debuglevel--result1": "The list of subsystems", "debuglevel--result1": "The list of subsystems",
// AddNodeCmd help. // AddManualNodeCmd help.
"addnode--synopsis": "Attempts to add or remove a persistent peer.", "addmanualnode--synopsis": "Attempts to add or remove a persistent peer.",
"addnode-addr": "IP address and port of the peer to operate on", "addmanualnode-addr": "IP address and port of the peer to operate on",
"addnode-subcmd": "'add' to add a persistent peer, 'remove' to remove a persistent peer, or 'onetry' to try a single connection to a peer", "addmanualnode-onetry": "When enabled, will try a single connection to a peer",
// NodeCmd help. // NodeCmd help.
"node--synopsis": "Attempts to add or remove a peer.", "node--synopsis": "Attempts to add or remove a peer.",
@ -128,22 +128,29 @@ var helpDescsEnUS = map[string]string{
"generate-numblocks": "Number of blocks to generate", "generate-numblocks": "Number of blocks to generate",
"generate--result0": "The hashes, in order, of blocks generated by the call", "generate--result0": "The hashes, in order, of blocks generated by the call",
// GetAddedNodeInfoResultAddr help. // GetAllManualNodesInfo help.
"getaddednodeinforesultaddr-address": "The ip address for this DNS entry", "getallmanualnodesinfo--synopsis": "Returns information about manually added (persistent) peers.",
"getaddednodeinforesultaddr-connected": "The connection 'direction' (inbound/outbound/false)", "getallmanualnodesinfo-details": "Specifies whether the returned data is a JSON object including DNS and connection information, or just a list of added peers",
"getallmanualnodesinfo--condition0": "details=false",
"getallmanualnodesinfo--condition1": "details=true",
"getallmanualnodesinfo--result0": "List of added peers",
// GetAddedNodeInfoResult help. // GetManualNodeInfoResultAddr help.
"getaddednodeinforesult-addednode": "The ip address or domain of the added peer", "getmanualnodeinforesultaddr-address": "The ip address for this DNS entry",
"getaddednodeinforesult-connected": "Whether or not the peer is currently connected", "getmanualnodeinforesultaddr-connected": "The connection 'direction' (inbound/outbound/false)",
"getaddednodeinforesult-addresses": "DNS lookup and connection information about the peer",
// GetAddedNodeInfo help. // GetManualNodeInfoResult help.
"getaddednodeinfo--synopsis": "Returns information about manually added (persistent) peers.", "getmanualnodeinforesult-manualnode": "The ip address or domain of the manually added peer",
"getaddednodeinfo-dns": "Specifies whether the returned data is a JSON object including DNS and connection information, or just a list of added peers", "getmanualnodeinforesult-connected": "Whether or not the peer is currently connected",
"getaddednodeinfo-node": "Only return information about this specific peer instead of all added peers", "getmanualnodeinforesult-addresses": "DNS lookup and connection information about the peer",
"getaddednodeinfo--condition0": "dns=false",
"getaddednodeinfo--condition1": "dns=true", // GetManualNodeInfo help.
"getaddednodeinfo--result0": "List of added peers", "getmanualnodeinfo--synopsis": "Returns information about manually added (persistent) peers.",
"getmanualnodeinfo-details": "Specifies whether the returned data is a JSON object including DNS and connection information, or just a list of added peers",
"getmanualnodeinfo-node": "Only return information about this specific peer instead of all added peers",
"getmanualnodeinfo--condition0": "details=false",
"getmanualnodeinfo--condition1": "details=true",
"getmanualnodeinfo--result0": "List of added peers",
// GetBestBlockResult help. // GetBestBlockResult help.
"getbestblockresult-hash": "Hex-encoded bytes of the best block hash", "getbestblockresult-hash": "Hex-encoded bytes of the best block hash",
@ -507,6 +514,10 @@ var helpDescsEnUS = map[string]string{
"ping--synopsis": "Queues a ping to be sent to each connected peer.\n" + "ping--synopsis": "Queues a ping to be sent to each connected peer.\n" +
"Ping times are provided by getpeerinfo via the pingtime and pingwait fields.", "Ping times are provided by getpeerinfo via the pingtime and pingwait fields.",
// RemoveManualNodeCmd help.
"removemanualnode--synopsis": "Removes a peer from the manual nodes list",
"removemanualnode-addr": "IP address and port of the peer to remove",
// SearchRawTransactionsCmd help. // SearchRawTransactionsCmd help.
"searchrawtransactions--synopsis": "Returns raw data for transactions involving the passed address.\n" + "searchrawtransactions--synopsis": "Returns raw data for transactions involving the passed address.\n" +
"Returned transactions are pulled from both the database, and transactions currently in the mempool.\n" + "Returned transactions are pulled from both the database, and transactions currently in the mempool.\n" +
@ -663,14 +674,14 @@ var helpDescsEnUS = map[string]string{
// This information is used to generate the help. Each result type must be a // 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). // pointer to the type (or nil to indicate no return value).
var rpcResultTypes = map[string][]interface{}{ var rpcResultTypes = map[string][]interface{}{
"addnode": nil, "addmanualnode": nil,
"createrawtransaction": {(*string)(nil)}, "createrawtransaction": {(*string)(nil)},
"debuglevel": {(*string)(nil), (*string)(nil)}, "debuglevel": {(*string)(nil), (*string)(nil)},
"decoderawtransaction": {(*btcjson.TxRawDecodeResult)(nil)}, "decoderawtransaction": {(*btcjson.TxRawDecodeResult)(nil)},
"decodescript": {(*btcjson.DecodeScriptResult)(nil)}, "decodescript": {(*btcjson.DecodeScriptResult)(nil)},
"estimatefee": {(*float64)(nil)}, "estimatefee": {(*float64)(nil)},
"generate": {(*[]string)(nil)}, "generate": {(*[]string)(nil)},
"getaddednodeinfo": {(*[]string)(nil), (*[]btcjson.GetAddedNodeInfoResult)(nil)}, "getallmanualnodesinfo": {(*[]string)(nil), (*[]btcjson.GetManualNodeInfoResult)(nil)},
"getbestblock": {(*btcjson.GetBestBlockResult)(nil)}, "getbestblock": {(*btcjson.GetBestBlockResult)(nil)},
"getbestblockhash": {(*string)(nil)}, "getbestblockhash": {(*string)(nil)},
"getblock": {(*string)(nil), (*btcjson.GetBlockVerboseResult)(nil)}, "getblock": {(*string)(nil), (*btcjson.GetBlockVerboseResult)(nil)},
@ -688,6 +699,7 @@ var rpcResultTypes = map[string][]interface{}{
"gethashespersec": {(*float64)(nil)}, "gethashespersec": {(*float64)(nil)},
"getheaders": {(*[]string)(nil)}, "getheaders": {(*[]string)(nil)},
"getinfo": {(*btcjson.InfoDAGResult)(nil)}, "getinfo": {(*btcjson.InfoDAGResult)(nil)},
"getmanualnodeinfo": {(*string)(nil), (*btcjson.GetManualNodeInfoResult)(nil)},
"getmempoolinfo": {(*btcjson.GetMempoolInfoResult)(nil)}, "getmempoolinfo": {(*btcjson.GetMempoolInfoResult)(nil)},
"getmininginfo": {(*btcjson.GetMiningInfoResult)(nil)}, "getmininginfo": {(*btcjson.GetMiningInfoResult)(nil)},
"getnettotals": {(*btcjson.GetNetTotalsResult)(nil)}, "getnettotals": {(*btcjson.GetNetTotalsResult)(nil)},
@ -699,6 +711,7 @@ var rpcResultTypes = map[string][]interface{}{
"node": nil, "node": nil,
"help": {(*string)(nil), (*string)(nil)}, "help": {(*string)(nil), (*string)(nil)},
"ping": nil, "ping": nil,
"removemanualnode": nil,
"searchrawtransactions": {(*string)(nil), (*[]btcjson.SearchRawTransactionsResult)(nil)}, "searchrawtransactions": {(*string)(nil), (*[]btcjson.SearchRawTransactionsResult)(nil)},
"sendrawtransaction": {(*string)(nil)}, "sendrawtransaction": {(*string)(nil)},
"setgenerate": nil, "setgenerate": nil,

View File

@ -655,7 +655,7 @@ func (m *wsNotificationManager) subscribedClients(tx *util.Tx,
for i, output := range msgTx.TxOut { for i, output := range msgTx.TxOut {
_, addrs, _, err := txscript.ExtractPkScriptAddrs( _, addrs, _, err := txscript.ExtractPkScriptAddrs(
output.PkScript, m.server.cfg.ChainParams) output.PkScript, m.server.cfg.DAGParams)
if err != nil { if err != nil {
// Clients are not able to subscribe to // Clients are not able to subscribe to
// nonstandard or non-address outputs. // nonstandard or non-address outputs.
@ -845,7 +845,7 @@ func (m *wsNotificationManager) notifyForNewTx(clients map[chan struct{}]*wsClie
continue continue
} }
net := m.server.cfg.ChainParams net := m.server.cfg.DAGParams
rawTx, err := createTxRawResult(net, mtx, txHashStr, nil, rawTx, err := createTxRawResult(net, mtx, txHashStr, nil,
"", 0, 0) "", 0, 0)
if err != nil { if err != nil {
@ -998,7 +998,7 @@ func (m *wsNotificationManager) notifyForTxOuts(ops map[wire.OutPoint]map[chan s
wscNotified := make(map[chan struct{}]struct{}) wscNotified := make(map[chan struct{}]struct{})
for i, txOut := range tx.MsgTx().TxOut { for i, txOut := range tx.MsgTx().TxOut {
_, txAddrs, _, err := txscript.ExtractPkScriptAddrs( _, txAddrs, _, err := txscript.ExtractPkScriptAddrs(
txOut.PkScript, m.server.cfg.ChainParams) txOut.PkScript, m.server.cfg.DAGParams)
if err != nil { if err != nil {
continue continue
} }
@ -1801,7 +1801,7 @@ func handleLoadTxFilter(wsc *wsClient, icmd interface{}) (interface{}, error) {
} }
} }
params := wsc.server.cfg.ChainParams params := wsc.server.cfg.DAGParams
wsc.Lock() wsc.Lock()
if cmd.Reload || wsc.filterData == nil { if cmd.Reload || wsc.filterData == nil {
@ -1891,7 +1891,7 @@ func handleNotifyReceived(wsc *wsClient, icmd interface{}) (interface{}, error)
// Decode addresses to validate input, but the strings slice is used // Decode addresses to validate input, but the strings slice is used
// directly if these are all ok. // directly if these are all ok.
err := checkAddressValidity(cmd.Addresses, wsc.server.cfg.ChainParams) err := checkAddressValidity(cmd.Addresses, wsc.server.cfg.DAGParams)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -1930,7 +1930,7 @@ func handleStopNotifyReceived(wsc *wsClient, icmd interface{}) (interface{}, err
// Decode addresses to validate input, but the strings slice is used // Decode addresses to validate input, but the strings slice is used
// directly if these are all ok. // directly if these are all ok.
err := checkAddressValidity(cmd.Addresses, wsc.server.cfg.ChainParams) err := checkAddressValidity(cmd.Addresses, wsc.server.cfg.DAGParams)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -2074,7 +2074,7 @@ func handleRescanBlocks(wsc *wsClient, icmd interface{}) (interface{}, error) {
// Iterate over each block in the request and rescan. When a block // Iterate over each block in the request and rescan. When a block
// contains relevant transactions, add it to the response. // contains relevant transactions, add it to the response.
bc := wsc.server.cfg.DAG bc := wsc.server.cfg.DAG
params := wsc.server.cfg.ChainParams params := wsc.server.cfg.DAGParams
var lastBlockHash *daghash.Hash var lastBlockHash *daghash.Hash
for i := range blockHashes { for i := range blockHashes {
block, err := bc.BlockByHash(blockHashes[i]) block, err := bc.BlockByHash(blockHashes[i])