Skip to content

Commit

Permalink
cmd/ft: add method 'seednodes' into sub-cmd 'p2p' (#497)
Browse files Browse the repository at this point in the history
* cmd/ft: add method 'seednodes' into sub-cmd 'p2p'

* cmd/ftfinder: add seednodes rpc
  • Loading branch information
peekpi authored and erickyan86 committed Sep 28, 2019
1 parent f2d694c commit aed8b8a
Show file tree
Hide file tree
Showing 6 changed files with 178 additions and 115 deletions.
196 changes: 86 additions & 110 deletions cmd/ft/p2p.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,141 +28,117 @@ var p2pCmd = &cobra.Command{
Args: cobra.NoArgs,
}

var addCmd = &cobra.Command{
Use: "add <url>",
Short: "Connecting to a remote node.",
Long: `Connecting to a remote node.`,
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
var result bool
clientCall(ipcEndpoint, &result, "p2p_addPeer", args[0])
var commonCall = func(method string) func(*cobra.Command, []string) {
return func(cmd *cobra.Command, args []string) {
params := make([]interface{}, len(args))
for i, arg := range args {
params[i] = arg
}
result := clientCallRaw(ipcEndpoint, method, params...)
printJSON(result)
},
}
}

var removeCmd = &cobra.Command{
Use: "remove <url>",
Short: "Disconnects from a remote node if the connection exists.",
Long: `Disconnects from a remote node if the connection exists.`,
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
var result bool
clientCall(ipcEndpoint, &result, "p2p_removePeer", args[0])
printJSON(result)
var p2pSubCmds = []*cobra.Command{
&cobra.Command{
Use: "add <url>",
Short: "Connecting to a remote node.",
Long: `Connecting to a remote node.`,
Args: cobra.ExactArgs(1),
Run: commonCall("p2p_addPeer"),
},
}

var addtrustedCmd = &cobra.Command{
Use: "addtrusted <url>",
Short: "Allows a remote node to always connect, even if slots are full.",
Long: `Allows a remote node to always connect, even if slots are full.`,
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
var result bool
clientCall(ipcEndpoint, &result, "p2p_addTrustedPeer", args[0])
printJSON(result)
&cobra.Command{
Use: "remove <url>",
Short: "Disconnects from a remote node if the connection exists.",
Long: `Disconnects from a remote node if the connection exists.`,
Args: cobra.ExactArgs(1),
Run: commonCall("p2p_removePeer"),
},
}

var removetrustedCmd = &cobra.Command{
Use: "removetrusted <url>",
Short: "Removes a remote node from the trusted peer set, but it does not disconnect it automatically.",
Long: `Removes a remote node from the trusted peer set, but it does not disconnect it automatically.`,
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
var result bool
clientCall(ipcEndpoint, &result, "p2p_removeTrustedPeer", args[0])
printJSON(result)
&cobra.Command{
Use: "addtrusted <url>",
Short: "Allows a remote node to always connect, even if slots are full.",
Long: `Allows a remote node to always connect, even if slots are full.`,
Args: cobra.ExactArgs(1),
Run: commonCall("p2p_addTrustedPeer"),
},
}

var addbadCmd = &cobra.Command{
Use: "addbad <url>",
Short: "Add a bad node in black list.",
Long: `Add a bad node in black list..`,
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
var result bool
clientCall(ipcEndpoint, &result, "p2p_addBadNode", args[0])
printJSON(result)
&cobra.Command{
Use: "removetrusted <url>",
Short: "Removes a remote node from the trusted peer set, but it does not disconnect it automatically.",
Long: `Removes a remote node from the trusted peer set, but it does not disconnect it automatically.`,
Args: cobra.ExactArgs(1),
Run: commonCall("p2p_removeTrustedPeer"),
},
}

var removebadCmd = &cobra.Command{
Use: "removebad <url>",
Short: "Removes a bad node from the black peer set.",
Long: `Removes a bad node from the black peer set.`,
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
var result bool
clientCall(ipcEndpoint, &result, "p2p_removeBadNode", args[0])
printJSON(result)
&cobra.Command{
Use: "addbad <url>",
Short: "Add a bad node in black list.",
Long: `Add a bad node in black list..`,
Args: cobra.ExactArgs(1),
Run: commonCall("p2p_addBadNode"),
},
}

var countCmd = &cobra.Command{
Use: "count",
Short: "Return number of connected peers.",
Long: `Return number of connected peers.`,
Args: cobra.NoArgs,
Run: func(cmd *cobra.Command, args []string) {
var result int
clientCall(ipcEndpoint, &result, "p2p_peerCount")
printJSON(result)
&cobra.Command{
Use: "removebad <url>",
Short: "Removes a bad node from the black peer set.",
Long: `Removes a bad node from the black peer set.`,
Args: cobra.ExactArgs(1),
Run: commonCall("p2p_removeBadNode"),
},
}

var listCmd = &cobra.Command{
Use: "list",
Short: "Return connected peers list.",
Long: `Return connected peers list.`,
Args: cobra.NoArgs,
Run: func(cmd *cobra.Command, args []string) {
var result []string
clientCall(ipcEndpoint, &result, "p2p_peers")
printJSONList(result)
&cobra.Command{
Use: "count",
Short: "Return number of connected peers.",
Long: `Return number of connected peers.`,
Args: cobra.NoArgs,
Run: commonCall("p2p_peerCount"),
},
}

var badcountCmd = &cobra.Command{
Use: "badcount",
Short: "Return number of bad nodes .",
Long: `Return number of bad nodes .`,
Args: cobra.NoArgs,
Run: func(cmd *cobra.Command, args []string) {
var result int
clientCall(ipcEndpoint, &result, "p2p_badNodesCount")
printJSON(result)
&cobra.Command{
Use: "list",
Short: "Return connected peers list.",
Long: `Return connected peers list.`,
Args: cobra.NoArgs,
Run: commonCall("p2p_peers"),
},
}

var badlistCmd = &cobra.Command{
Use: "badlist",
Short: "Return bad nodes list.",
Long: `Return bad nodes list.`,
Args: cobra.NoArgs,
Run: func(cmd *cobra.Command, args []string) {
var result []string
clientCall(ipcEndpoint, &result, "p2p_badNodes")
printJSONList(result)
&cobra.Command{
Use: "badcount",
Short: "Return number of bad nodes .",
Long: `Return number of bad nodes .`,
Args: cobra.NoArgs,
Run: commonCall("p2p_badNodesCount"),
},
}

var selfnodeCmd = &cobra.Command{
Use: "selfnode",
Short: "Return self enode url.",
Long: `Return self enode url.`,
Args: cobra.NoArgs,
Run: func(cmd *cobra.Command, args []string) {
var result string
clientCall(ipcEndpoint, &result, "p2p_selfNode")
printJSON(result)
&cobra.Command{
Use: "badlist",
Short: "Return bad nodes list.",
Long: `Return bad nodes list.`,
Args: cobra.NoArgs,
Run: commonCall("p2p_badNodes"),
},

&cobra.Command{
Use: "selfnode",
Short: "Return self enode url.",
Long: `Return self enode url.`,
Args: cobra.NoArgs,
Run: commonCall("p2p_selfNode"),
},

&cobra.Command{
Use: "seednodes",
Short: "Return seed enode url.",
Long: `Return seed enode url.`,
Args: cobra.NoArgs,
Run: commonCall("p2p_seedNodes"),
},
}

func init() {
RootCmd.AddCommand(p2pCmd)
p2pCmd.AddCommand(addCmd, removeCmd, addtrustedCmd, removetrustedCmd,
addbadCmd, removebadCmd, countCmd, listCmd, badcountCmd, badlistCmd, selfnodeCmd)
p2pCmd.AddCommand(p2pSubCmds...)
p2pCmd.PersistentFlags().StringVarP(&ipcEndpoint, "ipcpath", "i", defaultIPCEndpoint(params.ClientIdentifier), "IPC Endpoint path")
}
14 changes: 14 additions & 0 deletions cmd/ft/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,20 @@ var tomlSettings = toml.Config{
},
}

func clientCallRaw(endpoint string, method string, args ...interface{}) json.RawMessage {
client, err := dialRPC(ipcEndpoint)
if err != nil {
jww.ERROR.Println(err)
os.Exit(-1)
}
msg, err := client.CallRaw(method, args...)
if err != nil {
jww.ERROR.Println(err)
os.Exit(-1)
}
return msg
}

func clientCall(endpoint string, result interface{}, method string, args ...interface{}) {
client, err := dialRPC(ipcEndpoint)
if err != nil {
Expand Down
24 changes: 21 additions & 3 deletions cmd/ftfinder/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,14 @@ import (
"github.com/fractalplatform/fractal/common"
"github.com/fractalplatform/fractal/node"
"github.com/fractalplatform/fractal/p2p"
"github.com/fractalplatform/fractal/rpc"
"github.com/spf13/cobra"
)

var nodeConfig = node.Config{
P2PConfig: &p2p.Config{},
P2PConfig: &p2p.Config{},
IPCPath: "ftfinder.ipc",
P2PNodeDatabase: "nodedb",
}

// RootCmd represents the base command when called without any subcommands
Expand All @@ -49,19 +52,34 @@ var RootCmd = &cobra.Command{
nodeConfig.P2PConfig.GenesisHash = common.HexToHash(hexStr)
nodeConfig.P2PConfig.Logger = log.New()
nodeConfig.P2PConfig.NodeDatabase = nodeConfig.NodeDB()
srv := p2p.Server{
srv := &p2p.Server{
Config: nodeConfig.P2PConfig,
}
for i, n := range srv.Config.BootstrapNodes {
fmt.Println(i, n.String())
}
srv.DiscoverOnly()
defer srv.Stop()
rpcListener, rpcHandler, err := rpc.StartIPCEndpoint(nodeConfig.IPCEndpoint(), []rpc.API{
rpc.API{
Namespace: "p2p",
Version: "1.0",
Service: &FinderRPC{srv},
Public: false,
},
})
if err != nil {
log.Error("ipc start failed", "error", err)
return
}
defer rpcHandler.Stop()
defer rpcListener.Close()

sigc := make(chan os.Signal, 1)
signal.Notify(sigc, syscall.SIGINT, syscall.SIGTERM)
defer signal.Stop(sigc)
<-sigc
log.Info("Got interrupt, shutting down...")
srv.Stop()
},
}

Expand Down
23 changes: 23 additions & 0 deletions cmd/ftfinder/rpc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package main

import (
"github.com/fractalplatform/fractal/p2p/enode"
)

type Backend interface {
SeedNodes() []*enode.Node
}

type FinderRPC struct {
b Backend
}

// SeedNodes returns all seed nodes.
func (fr *FinderRPC) SeedNodes() []string {
nodes := fr.b.SeedNodes()
ns := make([]string, len(nodes))
for i, node := range nodes {
ns[i] = node.String()
}
return ns
}
6 changes: 4 additions & 2 deletions p2p/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -535,11 +535,13 @@ func (srv *Server) DiscoverOnly() error {
if err != nil {
return err
}

srv.ntab = ntab
srv.loopWG.Add(1)
go func() {
timeout := time.NewTicker(10 * time.Minute)
defer srv.loopWG.Done()
defer timeout.Stop()
defer ntab.Close()
defer srv.ntab.Close()
for {
select {
case <-timeout.C:
Expand Down
30 changes: 30 additions & 0 deletions rpc/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,36 @@ func (c *Client) Call(result interface{}, method string, args ...interface{}) er
return c.CallContext(ctx, result, method, args...)
}

func (c *Client) CallRaw(method string, args ...interface{}) (json.RawMessage, error) {
ctx := context.Background()
msg, err := c.newMessage(method, args...)
if err != nil {
return nil, err
}
op := &requestOp{ids: []json.RawMessage{msg.ID}, resp: make(chan *jsonrpcMessage, 1)}

if c.isHTTP {
err = c.sendHTTP(ctx, op, msg)
} else {
err = c.send(ctx, op, msg)
}
if err != nil {
return nil, err
}

// dispatch has accepted the request and will close the channel it when it quits.
switch resp, err := op.wait(ctx); {
case err != nil:
return nil, err
case resp.Error != nil:
return nil, resp.Error
case len(resp.Result) == 0:
return nil, ErrNoResult
default:
return resp.Result, nil
}
}

// CallContext performs a JSON-RPC call with the given arguments. If the context is
// canceled before the call has successfully returned, CallContext returns immediately.
//
Expand Down

0 comments on commit aed8b8a

Please sign in to comment.