[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
// 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.
type NodeSubCmd string

View File

@ -14,35 +14,31 @@ import (
"github.com/daglabs/btcd/wire"
)
// AddNodeSubCmd defines the type used in the addnode JSON-RPC command for the
// sub command field.
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 {
// AddManualNodeCmd defines the addmanualnode JSON-RPC command.
type AddManualNodeCmd struct {
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.
func NewAddNodeCmd(addr string, subCmd AddNodeSubCmd) *AddNodeCmd {
return &AddNodeCmd{
func NewAddManualNodeCmd(addr string, oneTry *bool) *AddManualNodeCmd {
return &AddManualNodeCmd{
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.
type GetAddedNodeInfoCmd struct {
DNS bool
Node *string
// GetManualNodeInfoCmd defines the getmanualnodeinfo JSON-RPC command.
type GetManualNodeInfoCmd struct {
Node string
Details *bool `jsonrpcdefault:"true"`
}
// NewGetAddedNodeInfoCmd returns a new instance which can be used to issue a
// getaddednodeinfo JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewGetAddedNodeInfoCmd(dns bool, node *string) *GetAddedNodeInfoCmd {
return &GetAddedNodeInfoCmd{
DNS: dns,
Node: node,
// NewGetManualNodeInfoCmd returns a new instance which can be used to issue a
// getmanualnodeinfo JSON-RPC command.
func NewGetManualNodeInfoCmd(node string, details *bool) *GetManualNodeInfoCmd {
return &GetManualNodeInfoCmd{
Details: details,
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.
flags := UsageFlag(0)
MustRegisterCmd("addnode", (*AddNodeCmd)(nil), flags)
MustRegisterCmd("addmanualnode", (*AddManualNodeCmd)(nil), flags)
MustRegisterCmd("createrawtransaction", (*CreateRawTransactionCmd)(nil), flags)
MustRegisterCmd("decoderawtransaction", (*DecodeRawTransactionCmd)(nil), flags)
MustRegisterCmd("decodescript", (*DecodeScriptCmd)(nil), flags)
MustRegisterCmd("getaddednodeinfo", (*GetAddedNodeInfoCmd)(nil), flags)
MustRegisterCmd("getallmanualnodesinfo", (*GetAllManualNodesInfoCmd)(nil), flags)
MustRegisterCmd("getbestblockhash", (*GetBestBlockHashCmd)(nil), flags)
MustRegisterCmd("getblock", (*GetBlockCmd)(nil), flags)
MustRegisterCmd("getblockdaginfo", (*GetBlockDAGInfoCmd)(nil), flags)
@ -781,6 +787,7 @@ func init() {
MustRegisterCmd("getgenerate", (*GetGenerateCmd)(nil), flags)
MustRegisterCmd("gethashespersec", (*GetHashesPerSecCmd)(nil), flags)
MustRegisterCmd("getinfo", (*GetInfoCmd)(nil), flags)
MustRegisterCmd("getmanualnodeinfo", (*GetManualNodeInfoCmd)(nil), flags)
MustRegisterCmd("getmempoolentry", (*GetMempoolEntryCmd)(nil), flags)
MustRegisterCmd("getmempoolinfo", (*GetMempoolInfoCmd)(nil), flags)
MustRegisterCmd("getmininginfo", (*GetMiningInfoCmd)(nil), flags)
@ -798,6 +805,7 @@ func init() {
MustRegisterCmd("ping", (*PingCmd)(nil), flags)
MustRegisterCmd("preciousblock", (*PreciousBlockCmd)(nil), flags)
MustRegisterCmd("reconsiderblock", (*ReconsiderBlockCmd)(nil), flags)
MustRegisterCmd("removemanualnode", (*RemoveManualNodeCmd)(nil), flags)
MustRegisterCmd("searchrawtransactions", (*SearchRawTransactionsCmd)(nil), flags)
MustRegisterCmd("sendrawtransaction", (*SendRawTransactionCmd)(nil), flags)
MustRegisterCmd("setgenerate", (*SetGenerateCmd)(nil), flags)

View File

@ -31,15 +31,15 @@ func TestDAGSvrCmds(t *testing.T) {
unmarshalled interface{}
}{
{
name: "addnode",
name: "addmanualnode",
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{} {
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}`,
unmarshalled: &btcjson.AddNodeCmd{Addr: "127.0.0.1", SubCmd: btcjson.ANRemove},
marshalled: `{"jsonrpc":"1.0","method":"addmanualnode","params":["127.0.0.1"],"id":1}`,
unmarshalled: &btcjson.AddManualNodeCmd{Addr: "127.0.0.1", OneTry: btcjson.Bool(false)},
},
{
name: "createrawtransaction",
@ -104,29 +104,15 @@ func TestDAGSvrCmds(t *testing.T) {
unmarshalled: &btcjson.DecodeScriptCmd{HexScript: "00"},
},
{
name: "getaddednodeinfo",
name: "getallmanualnodesinfo",
newCmd: func() (interface{}, error) {
return btcjson.NewCmd("getaddednodeinfo", true)
return btcjson.NewCmd("getallmanualnodesinfo")
},
staticCmd: func() interface{} {
return btcjson.NewGetAddedNodeInfoCmd(true, 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"),
return btcjson.NewGetAllManualNodesInfoCmd(nil)
},
marshalled: `{"jsonrpc":"1.0","method":"getallmanualnodesinfo","params":[],"id":1}`,
unmarshalled: &btcjson.GetAllManualNodesInfoCmd{Details: btcjson.Bool(true)},
},
{
name: "getbestblockhash",
@ -416,6 +402,20 @@ func TestDAGSvrCmds(t *testing.T) {
marshalled: `{"jsonrpc":"1.0","method":"getinfo","params":[],"id":1}`,
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",
newCmd: func() (interface{}, error) {
@ -727,6 +727,17 @@ func TestDAGSvrCmds(t *testing.T) {
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",
newCmd: func() (interface{}, error) {

View File

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

View File

@ -9,7 +9,6 @@ import (
"time"
"github.com/daglabs/btcd/dagconfig/daghash"
"github.com/daglabs/btcd/rpcclient"
)
// 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)
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
}

View File

@ -10,29 +10,6 @@ import (
"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
// AddNodeAsync RPC invocation (or an applicable error).
type FutureAddNodeResult chan *response
@ -44,39 +21,39 @@ func (r FutureAddNodeResult) Receive() error {
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
// returned instance.
//
// See AddNode for the blocking version and more details.
func (c *Client) AddNodeAsync(host string, command AddNodeCommand) FutureAddNodeResult {
cmd := btcjson.NewAddNodeCmd(host, btcjson.AddNodeSubCmd(command))
func (c *Client) AddManualNodeAsync(host string) FutureAddNodeResult {
cmd := btcjson.NewAddManualNodeCmd(host, btcjson.Bool(false))
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
// a one time connection to a peer.
//
// It may not be used to remove non-persistent peers.
func (c *Client) AddNode(host string, command AddNodeCommand) error {
return c.AddNodeAsync(host, command).Receive()
func (c *Client) AddManualNode(host string) error {
return c.AddManualNodeAsync(host).Receive()
}
// FutureGetAddedNodeInfoResult is a future promise to deliver the result of a
// GetAddedNodeInfoAsync RPC invocation (or an applicable error).
type FutureGetAddedNodeInfoResult chan *response
// FutureGetManualNodeInfoResult is a future promise to deliver the result of a
// GetManualNodeInfoAsync RPC invocation (or an applicable error).
type FutureGetManualNodeInfoResult chan *response
// Receive waits for the response promised by the future and returns information
// about manually added (persistent) peers.
func (r FutureGetAddedNodeInfoResult) Receive() ([]btcjson.GetAddedNodeInfoResult, error) {
func (r FutureGetManualNodeInfoResult) Receive() ([]btcjson.GetManualNodeInfoResult, error) {
res, err := receiveFuture(r)
if err != nil {
return nil, err
}
// Unmarshal as an array of getaddednodeinfo result objects.
var nodeInfo []btcjson.GetAddedNodeInfoResult
// Unmarshal as an array of getmanualnodeinfo result objects.
var nodeInfo []btcjson.GetManualNodeInfoResult
err = json.Unmarshal(res, &nodeInfo)
if err != nil {
return nil, err
@ -85,31 +62,31 @@ func (r FutureGetAddedNodeInfoResult) Receive() ([]btcjson.GetAddedNodeInfoResul
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 returned instance.
//
// See GetAddedNodeInfo for the blocking version and more details.
func (c *Client) GetAddedNodeInfoAsync(peer string) FutureGetAddedNodeInfoResult {
cmd := btcjson.NewGetAddedNodeInfoCmd(true, &peer)
// See GetManualNodeInfo for the blocking version and more details.
func (c *Client) GetManualNodeInfoAsync(peer string) FutureGetManualNodeInfoResult {
cmd := btcjson.NewGetManualNodeInfoCmd(peer, nil)
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.
func (c *Client) GetAddedNodeInfo(peer string) ([]btcjson.GetAddedNodeInfoResult, error) {
return c.GetAddedNodeInfoAsync(peer).Receive()
func (c *Client) GetManualNodeInfo(peer string) ([]btcjson.GetManualNodeInfoResult, error) {
return c.GetManualNodeInfoAsync(peer).Receive()
}
// FutureGetAddedNodeInfoNoDNSResult is a future promise to deliver the result
// of a GetAddedNodeInfoNoDNSAsync RPC invocation (or an applicable error).
type FutureGetAddedNodeInfoNoDNSResult chan *response
// FutureGetManualNodeInfoNoDNSResult is a future promise to deliver the result
// of a GetManualNodeInfoNoDNSAsync RPC invocation (or an applicable error).
type FutureGetManualNodeInfoNoDNSResult chan *response
// Receive waits for the response promised by the future and returns a list of
// manually added (persistent) peers.
func (r FutureGetAddedNodeInfoNoDNSResult) Receive() ([]string, error) {
func (r FutureGetManualNodeInfoNoDNSResult) Receive() ([]string, error) {
res, err := receiveFuture(r)
if err != nil {
return nil, err
@ -125,23 +102,23 @@ func (r FutureGetAddedNodeInfoNoDNSResult) Receive() ([]string, error) {
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
// function on the returned instance.
//
// See GetAddedNodeInfoNoDNS for the blocking version and more details.
func (c *Client) GetAddedNodeInfoNoDNSAsync(peer string) FutureGetAddedNodeInfoNoDNSResult {
cmd := btcjson.NewGetAddedNodeInfoCmd(false, &peer)
// See GetManualNodeInfoNoDNS for the blocking version and more details.
func (c *Client) GetManualNodeInfoNoDNSAsync(peer string) FutureGetManualNodeInfoNoDNSResult {
cmd := btcjson.NewGetManualNodeInfoCmd(peer, btcjson.Bool(false))
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.
//
// See GetAddedNodeInfo to obtain more information about each added (persistent)
// See GetManualNodeInfo to obtain more information about each added (persistent)
// peer.
func (c *Client) GetAddedNodeInfoNoDNS(peer string) ([]string, error) {
return c.GetAddedNodeInfoNoDNSAsync(peer).Receive()
func (c *Client) GetManualNodeInfoNoDNS(peer string) ([]string, error) {
return c.GetManualNodeInfoNoDNSAsync(peer).Receive()
}
// FutureGetConnectionCountResult is a future promise to deliver the result

View File

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

View File

@ -13,8 +13,8 @@ import (
"github.com/daglabs/btcd/netsync"
"github.com/daglabs/btcd/peer"
"github.com/daglabs/btcd/server/p2p"
"github.com/daglabs/btcd/wire"
"github.com/daglabs/btcd/util"
"github.com/daglabs/btcd/wire"
)
// 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.
func (cm *rpcConnManager) PersistentPeers() []rpcserverPeer {
replyChan := make(chan []*p2p.Peer)
cm.server.Query <- p2p.GetAddedNodesMsg{Reply: replyChan}
cm.server.Query <- p2p.GetManualNodesMsg{Reply: replyChan}
serverPeers := <-replyChan
// Convert to generic peers.

View File

@ -134,14 +134,14 @@ type commandHandler func(*Server, interface{}, <-chan struct{}) (interface{}, er
// a dependency loop.
var rpcHandlers map[string]commandHandler
var rpcHandlersBeforeInit = map[string]commandHandler{
"addnode": handleAddNode,
"addmanualnode": handleAddManualNode,
"createrawtransaction": handleCreateRawTransaction,
"debuglevel": handleDebugLevel,
"decoderawtransaction": handleDecodeRawTransaction,
"decodescript": handleDecodeScript,
"estimatefee": handleEstimateFee,
"generate": handleGenerate,
"getaddednodeinfo": handleGetAddedNodeInfo,
"getallmanualnodesinfo": handleGetAllManualNodesInfo,
"getbestblock": handleGetBestBlock,
"getbestblockhash": handleGetBestBlockHash,
"getblock": handleGetBlock,
@ -159,6 +159,7 @@ var rpcHandlersBeforeInit = map[string]commandHandler{
"gethashespersec": handleGetHashesPerSec,
"getheaders": handleGetHeaders,
"getinfo": handleGetInfo,
"getmanualnodeinfo": handleGetManualNodeInfo,
"getmempoolinfo": handleGetMempoolInfo,
"getmininginfo": handleGetMiningInfo,
"getnettotals": handleGetNetTotals,
@ -170,6 +171,7 @@ var rpcHandlersBeforeInit = map[string]commandHandler{
"help": handleHelp,
"node": handleNode,
"ping": handlePing,
"removemanualnode": handleRemoveManualNode,
"searchrawtransactions": handleSearchRawTransactions,
"sendrawtransaction": handleSendRawTransaction,
"setgenerate": handleSetGenerate,
@ -365,26 +367,38 @@ func handleAskWallet(s *Server, cmd interface{}, closeChan <-chan struct{}) (int
return nil, ErrRPCNoWallet
}
// handleAddNode handles addnode commands.
func handleAddNode(s *Server, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
c := cmd.(*btcjson.AddNodeCmd)
// handleAddManualNode handles addmanualnode commands.
func handleAddManualNode(s *Server, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
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
switch c.SubCmd {
case "add":
err = s.cfg.ConnMgr.Connect(addr, true)
case "remove":
err = s.cfg.ConnMgr.RemoveByAddr(addr)
case "onetry":
if oneTry {
err = s.cfg.ConnMgr.Connect(addr, false)
default:
} else {
err = s.cfg.ConnMgr.Connect(addr, true)
}
if err != nil {
return nil, &btcjson.RPCError{
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 {
return nil, &btcjson.RPCError{
Code: btcjson.ErrRPCInvalidParameter,
@ -403,7 +417,7 @@ func handleNode(s *Server, cmd interface{}, closeChan <-chan struct{}) (interfac
var addr string
var nodeID uint64
var errN, err error
params := s.cfg.ChainParams
params := s.cfg.DAGParams
switch c.SubCmd {
case "disconnect":
// 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
// some validity checks.
params := s.cfg.ChainParams
params := s.cfg.DAGParams
for encodedAddr, amount := range c.Amounts {
// Ensure amount is in the valid range for monetary amounts.
if amount <= 0 || amount > util.MaxSatoshi {
@ -784,7 +798,7 @@ func handleDecodeRawTransaction(s *Server, cmd interface{}, closeChan <-chan str
Version: mtx.Version,
Locktime: mtx.LockTime,
Vin: createVinList(&mtx),
Vout: createVoutList(&mtx, s.cfg.ChainParams, nil),
Vout: createVoutList(&mtx, s.cfg.DAGParams, 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
// and there is no additinal information about it anyways.
scriptClass, addrs, reqSigs, _ := txscript.ExtractPkScriptAddrs(script,
s.cfg.ChainParams)
s.cfg.DAGParams)
addresses := make([]string, len(addrs))
for i, addr := range addrs {
addresses[i] = addr.EncodeAddress()
}
// 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 {
context := "Failed to convert script to pay-to-script-hash"
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
// with the CPU.
if !s.cfg.ChainParams.GenerateSupported {
if !s.cfg.DAGParams.GenerateSupported {
return nil, &btcjson.RPCError{
Code: btcjson.ErrRPCDifficulty,
Message: fmt.Sprintf("No support for `generate` on "+
"the current network, %s, as it's unlikely to "+
"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
}
// handleGetAddedNodeInfo handles getaddednodeinfo commands.
func handleGetAddedNodeInfo(s *Server, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
c := cmd.(*btcjson.GetAddedNodeInfoCmd)
// getManualNodesInfo handles getmanualnodeinfo and getallmanualnodesinfo commands.
func getManualNodesInfo(s *Server, detailsArg *bool, node string) (interface{}, error) {
// 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).
peers := s.cfg.ConnMgr.PersistentPeers()
if c.Node != nil {
node := *c.Node
if node != "" {
found := false
for i, peer := range peers {
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.
if !c.DNS {
if !details {
results := make([]string, 0, len(peers))
for _, peer := range peers {
results = append(results, peer.ToPeer().Addr())
@ -947,15 +961,15 @@ func handleGetAddedNodeInfo(s *Server, cmd interface{}, closeChan <-chan struct{
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.
results := make([]*btcjson.GetAddedNodeInfoResult, 0, len(peers))
results := make([]*btcjson.GetManualNodeInfoResult, 0, len(peers))
for _, rpcPeer := range peers {
// Set the "address" of the peer which could be an ip address
// or a domain name.
peer := rpcPeer.ToPeer()
var result btcjson.GetAddedNodeInfoResult
result.AddedNode = peer.Addr()
var result btcjson.GetManualNodeInfoResult
result.ManualNode = peer.Addr()
result.Connected = btcjson.Bool(peer.Connected())
// 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.
addrs := make([]btcjson.GetAddedNodeInfoResultAddr, 0, len(ipList))
addrs := make([]btcjson.GetManualNodeInfoResultAddr, 0, len(ipList))
for _, ip := range ipList {
var addr btcjson.GetAddedNodeInfoResultAddr
var addr btcjson.GetManualNodeInfoResultAddr
addr.Address = ip
addr.Connected = "false"
if ip == host && peer.Connected() {
@ -1003,6 +1017,26 @@ func handleGetAddedNodeInfo(s *Server, cmd interface{}, closeChan <-chan struct{
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.
func handleGetBestBlock(s *Server, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
// 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)
}
params := s.cfg.ChainParams
params := s.cfg.DAGParams
blockHeader := &blk.MsgBlock().Header
blockReply := btcjson.GetBlockVerboseResult{
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) {
// Obtain a snapshot of the current best known DAG state. We'll
// populate the response to this call primarily from this snapshot.
params := s.cfg.ChainParams
params := s.cfg.DAGParams
dag := s.cfg.DAG
virtualBlock := dag.VirtualBlock()
@ -1290,7 +1324,7 @@ func handleGetBlockHeader(s *Server, cmd interface{}, closeChan <-chan struct{})
nextHashStrings = daghash.Strings(childHashes)
}
params := s.cfg.ChainParams
params := s.cfg.DAGParams
blockHeaderReply := btcjson.GetBlockHeaderVerboseResult{
Hash: c.Hash,
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.
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.
func handleGetDifficulty(s *Server, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
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.
@ -2236,7 +2270,7 @@ func handleGetInfo(s *Server, cmd interface{}, closeChan <-chan struct{}) (inter
TimeOffset: int64(s.cfg.TimeSource.Offset().Seconds()),
Connections: s.cfg.ConnMgr.ConnectedCount(),
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,
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
CurrentBlockSize: uint64(selectedBlock.MsgBlock().SerializeSize()),
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(),
GenProcLimit: s.cfg.CPUMiner.NumWorkers(),
HashesPerSec: int64(s.cfg.CPUMiner.HashesPerSecond()),
@ -2493,7 +2527,7 @@ func handleGetRawTransaction(s *Server, cmd interface{}, closeChan <-chan struct
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)
if err != nil {
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
// and there is no additional information about it anyways.
scriptClass, addrs, reqSigs, _ := txscript.ExtractPkScriptAddrs(pkScript,
s.cfg.ChainParams)
s.cfg.DAGParams)
addresses := make([]string, len(addrs))
for i, addr := range addrs {
addresses[i] = addr.EncodeAddress()
@ -2905,7 +2939,7 @@ func handleSearchRawTransactions(s *Server, cmd interface{}, closeChan <-chan st
}
// Attempt to decode the supplied address.
params := s.cfg.ChainParams
params := s.cfg.DAGParams
addr, err := util.DecodeAddress(c.Address, params.Prefix)
if err != nil {
return nil, &btcjson.RPCError{
@ -3305,7 +3339,7 @@ func handleValidateAddress(s *Server, cmd interface{}, closeChan <-chan struct{}
c := cmd.(*btcjson.ValidateAddressCmd)
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 {
// Return the default value (false) for IsValid.
return result, nil
@ -3338,7 +3372,7 @@ func verifyDAG(s *Server, level, depth int32) error {
// Level 1 does basic chain sanity checks.
if level > 0 {
err := blockdag.CheckBlockSanity(block,
s.cfg.ChainParams.PowLimit, s.cfg.TimeSource)
s.cfg.DAGParams.PowLimit, s.cfg.TimeSource)
if err != nil {
log.Errorf("Verify is unable to validate "+
"block at hash %v height %d: %v",
@ -3375,7 +3409,7 @@ func handleVerifyMessage(s *Server, cmd interface{}, closeChan <-chan struct{})
c := cmd.(*btcjson.VerifyMessageCmd)
// Decode the provided address.
params := s.cfg.ChainParams
params := s.cfg.DAGParams
addr, err := util.DecodeAddress(c.Address, params.Prefix)
if err != nil {
return nil, &btcjson.RPCError{
@ -4068,10 +4102,10 @@ type rpcserverConfig struct {
// These fields allow the RPC server to interface with the local block
// chain data and state.
TimeSource blockdag.MedianTimeSource
DAG *blockdag.BlockDAG
ChainParams *dagconfig.Params
DB database.DB
TimeSource blockdag.MedianTimeSource
DAG *blockdag.BlockDAG
DAGParams *dagconfig.Params
DB database.DB
// TxMemPool defines the transaction memory pool to interact with.
TxMemPool *mempool.TxPool
@ -4168,7 +4202,7 @@ func NewRPCServer(
ConnMgr: &rpcConnManager{p2pServer},
SyncMgr: &rpcSyncMgr{p2pServer, p2pServer.SyncManager},
TimeSource: p2pServer.TimeSource,
ChainParams: p2pServer.DAGParams,
DAGParams: p2pServer.DAGParams,
DB: db,
TxMemPool: p2pServer.TxMemPool,
Generator: blockTemplateGenerator,

View File

@ -29,10 +29,10 @@ var helpDescsEnUS = map[string]string{
"debuglevel--result0": "The string 'Done.'",
"debuglevel--result1": "The list of subsystems",
// AddNodeCmd help.
"addnode--synopsis": "Attempts to add or remove a persistent peer.",
"addnode-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",
// AddManualNodeCmd help.
"addmanualnode--synopsis": "Attempts to add or remove a persistent peer.",
"addmanualnode-addr": "IP address and port of the peer to operate on",
"addmanualnode-onetry": "When enabled, will try a single connection to a peer",
// NodeCmd help.
"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--result0": "The hashes, in order, of blocks generated by the call",
// GetAddedNodeInfoResultAddr help.
"getaddednodeinforesultaddr-address": "The ip address for this DNS entry",
"getaddednodeinforesultaddr-connected": "The connection 'direction' (inbound/outbound/false)",
// GetAllManualNodesInfo help.
"getallmanualnodesinfo--synopsis": "Returns information about manually added (persistent) peers.",
"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.
"getaddednodeinforesult-addednode": "The ip address or domain of the added peer",
"getaddednodeinforesult-connected": "Whether or not the peer is currently connected",
"getaddednodeinforesult-addresses": "DNS lookup and connection information about the peer",
// GetManualNodeInfoResultAddr help.
"getmanualnodeinforesultaddr-address": "The ip address for this DNS entry",
"getmanualnodeinforesultaddr-connected": "The connection 'direction' (inbound/outbound/false)",
// GetAddedNodeInfo help.
"getaddednodeinfo--synopsis": "Returns information about manually added (persistent) peers.",
"getaddednodeinfo-dns": "Specifies whether the returned data is a JSON object including DNS and connection information, or just a list of added peers",
"getaddednodeinfo-node": "Only return information about this specific peer instead of all added peers",
"getaddednodeinfo--condition0": "dns=false",
"getaddednodeinfo--condition1": "dns=true",
"getaddednodeinfo--result0": "List of added peers",
// GetManualNodeInfoResult help.
"getmanualnodeinforesult-manualnode": "The ip address or domain of the manually added peer",
"getmanualnodeinforesult-connected": "Whether or not the peer is currently connected",
"getmanualnodeinforesult-addresses": "DNS lookup and connection information about the peer",
// GetManualNodeInfo help.
"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-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 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.
"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" +
@ -663,14 +674,14 @@ var helpDescsEnUS = map[string]string{
// 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{}{
"addnode": nil,
"addmanualnode": nil,
"createrawtransaction": {(*string)(nil)},
"debuglevel": {(*string)(nil), (*string)(nil)},
"decoderawtransaction": {(*btcjson.TxRawDecodeResult)(nil)},
"decodescript": {(*btcjson.DecodeScriptResult)(nil)},
"estimatefee": {(*float64)(nil)},
"generate": {(*[]string)(nil)},
"getaddednodeinfo": {(*[]string)(nil), (*[]btcjson.GetAddedNodeInfoResult)(nil)},
"getallmanualnodesinfo": {(*[]string)(nil), (*[]btcjson.GetManualNodeInfoResult)(nil)},
"getbestblock": {(*btcjson.GetBestBlockResult)(nil)},
"getbestblockhash": {(*string)(nil)},
"getblock": {(*string)(nil), (*btcjson.GetBlockVerboseResult)(nil)},
@ -688,6 +699,7 @@ var rpcResultTypes = map[string][]interface{}{
"gethashespersec": {(*float64)(nil)},
"getheaders": {(*[]string)(nil)},
"getinfo": {(*btcjson.InfoDAGResult)(nil)},
"getmanualnodeinfo": {(*string)(nil), (*btcjson.GetManualNodeInfoResult)(nil)},
"getmempoolinfo": {(*btcjson.GetMempoolInfoResult)(nil)},
"getmininginfo": {(*btcjson.GetMiningInfoResult)(nil)},
"getnettotals": {(*btcjson.GetNetTotalsResult)(nil)},
@ -699,6 +711,7 @@ var rpcResultTypes = map[string][]interface{}{
"node": nil,
"help": {(*string)(nil), (*string)(nil)},
"ping": nil,
"removemanualnode": nil,
"searchrawtransactions": {(*string)(nil), (*[]btcjson.SearchRawTransactionsResult)(nil)},
"sendrawtransaction": {(*string)(nil)},
"setgenerate": nil,

View File

@ -655,7 +655,7 @@ func (m *wsNotificationManager) subscribedClients(tx *util.Tx,
for i, output := range msgTx.TxOut {
_, addrs, _, err := txscript.ExtractPkScriptAddrs(
output.PkScript, m.server.cfg.ChainParams)
output.PkScript, m.server.cfg.DAGParams)
if err != nil {
// Clients are not able to subscribe to
// nonstandard or non-address outputs.
@ -845,7 +845,7 @@ func (m *wsNotificationManager) notifyForNewTx(clients map[chan struct{}]*wsClie
continue
}
net := m.server.cfg.ChainParams
net := m.server.cfg.DAGParams
rawTx, err := createTxRawResult(net, mtx, txHashStr, nil,
"", 0, 0)
if err != nil {
@ -998,7 +998,7 @@ func (m *wsNotificationManager) notifyForTxOuts(ops map[wire.OutPoint]map[chan s
wscNotified := make(map[chan struct{}]struct{})
for i, txOut := range tx.MsgTx().TxOut {
_, txAddrs, _, err := txscript.ExtractPkScriptAddrs(
txOut.PkScript, m.server.cfg.ChainParams)
txOut.PkScript, m.server.cfg.DAGParams)
if err != nil {
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()
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
// 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 {
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
// 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 {
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
// contains relevant transactions, add it to the response.
bc := wsc.server.cfg.DAG
params := wsc.server.cfg.ChainParams
params := wsc.server.cfg.DAGParams
var lastBlockHash *daghash.Hash
for i := range blockHashes {
block, err := bc.BlockByHash(blockHashes[i])