Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[P2P] [Tooling] Peer discovery peer list subcommand #892

Open
wants to merge 43 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
4badf3a
chore: simplify debug message broadcasting
bryanchriswhite Jun 13, 2023
2b83d32
refactor: CLI config parsing
bryanchriswhite Jul 7, 2023
eac7695
refactor: common CLI helpers
bryanchriswhite Jul 7, 2023
bca000b
chore: add `GetBusFromCmd()` CLI helper
bryanchriswhite Jul 11, 2023
5e963be
chore: consistent debug CLI identity
bryanchriswhite Jul 11, 2023
a883f08
chore: add `enable_peer_discovery_debug_rpc` to P2P config
bryanchriswhite Jul 6, 2023
83c3604
chore: add P2P debug message handling support
bryanchriswhite Jul 6, 2023
6ecca53
feat: add `peer` subcommand
bryanchriswhite Jun 6, 2023
d570b35
chore: add peer `--local` persistent flag
bryanchriswhite Jul 6, 2023
e952365
feat: add `peer list` subcommand
bryanchriswhite Jun 6, 2023
e80843c
chore: implement `PeerstoreProvider#GetUnstakedPeerstore()`
bryanchriswhite Jun 5, 2023
8f90e22
chore: add `PeerstoreProvider#GetStakedPeerstoreAtCurrentHeight()`
bryanchriswhite Jul 13, 2023
6e691cd
chore: interim bootstrapping changes (pre-#859)
bryanchriswhite Jul 11, 2023
430db08
fix: gofmt
bryanchriswhite Jul 12, 2023
440b59a
chore: ensure flag and config parsing
bryanchriswhite Jul 7, 2023
fcfa837
chore: add `GetBusFromCmd()` CLI helper
bryanchriswhite Jul 11, 2023
04dc0aa
chore: consistent debug CLI identity
bryanchriswhite Jul 11, 2023
3925c71
Merge branch 'refactor/cli' into feat/peer-discovery-list
bryanchriswhite Jul 13, 2023
1bbad38
fixup: add `peer list` subcommand
bryanchriswhite Jul 13, 2023
64abbc0
add generated helm docs
invalid-email-address Jul 13, 2023
d8b6296
squash: merge refactor/cli with main
h5law Jul 25, 2023
9ecc9e5
chore: address review comments
h5law Jul 25, 2023
1cbc249
Merge branch 'main' into refactor/cli
h5law Jul 25, 2023
ffbc539
fix merge error
h5law Jul 25, 2023
0cff1d2
Merge branch 'refactor/cli' into feat/peer-discovery-list
h5law Jul 25, 2023
39af37c
revert change
h5law Jul 25, 2023
c22011c
address comments
h5law Jul 25, 2023
1fc2bb4
chore: address comments
h5law Jul 25, 2023
764e171
clarify unstaked description
h5law Jul 25, 2023
9eb5a7e
Merge branch 'main' into feat/peer-discovery-list
h5law Jul 26, 2023
7380260
chore: up retry attempts and wait time, clarify error messages
h5law Jul 26, 2023
c03aa27
Merge branch 'main' into feat/peer-discovery-list
Olshansk Jul 26, 2023
da62de1
Fixed case messaging.DebugMessageEventType
Olshansk Jul 26, 2023
12e22e1
clairfy error log messages
h5law Jul 27, 2023
f8f5da5
fix waitgroup recovery in tests
h5law Jul 27, 2023
66a1347
chore: move comment line
h5law Jul 27, 2023
870805f
add NewListCommand function to fit CLI pattern
h5law Jul 27, 2023
64ec990
clarify errors
h5law Jul 27, 2023
ccec195
remove unneeded error casting as sync panics a string
h5law Jul 27, 2023
90385f0
tidy cli
h5law Jul 28, 2023
6d0d300
remove #810 from comment as merged
h5law Jul 28, 2023
c6488a5
shortern retries
h5law Jul 28, 2023
2317d42
bug: comment out buggy lines
h5law Jul 31, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat: add peer list subcommand
  • Loading branch information
bryanchriswhite committed Jul 13, 2023
commit e952365d9fd696194a76648b5b00d201ccbded5c
107 changes: 107 additions & 0 deletions app/client/cli/peer/list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package peer

import (
"fmt"

"github.com/spf13/cobra"
"google.golang.org/protobuf/types/known/anypb"

"github.com/pokt-network/pocket/app/client/cli/helpers"
"github.com/pokt-network/pocket/logger"
"github.com/pokt-network/pocket/p2p/debug"
"github.com/pokt-network/pocket/shared/messaging"
)

var (
listCmd = &cobra.Command{
Use: "list",
h5law marked this conversation as resolved.
Show resolved Hide resolved
Short: "Print addresses and service URLs of known peers",
RunE: listRunE,
}

ErrRouterType = fmt.Errorf("must specify one of --staked, --unstaked, or --all")
)

func init() {
PeerCmd.AddCommand(listCmd)
}

func listRunE(cmd *cobra.Command, _ []string) error {
var routerType debug.RouterType

bus, err := helpers.GetBusFromCmd(cmd)
if err != nil {
return err
}

switch {
case stakedFlag:
h5law marked this conversation as resolved.
Show resolved Hide resolved
if unstakedFlag || allFlag {
return ErrRouterType
}
routerType = debug.StakedRouterType
case unstakedFlag:
if stakedFlag || allFlag {
return ErrRouterType
}
routerType = debug.UnstakedRouterType
case allFlag:
if stakedFlag || unstakedFlag {
return ErrRouterType
}
routerType = debug.AllRouterTypes
default:
return ErrRouterType
}

debugMsg := &messaging.DebugMessage{
Action: messaging.DebugMessageAction_DEBUG_P2P_PEER_LIST,
Type: messaging.DebugMessageRoutingType_DEBUG_MESSAGE_TYPE_BROADCAST,
Message: &anypb.Any{
Value: []byte(routerType),
},
}
debugMsgAny, err := anypb.New(debugMsg)
if err != nil {
return fmt.Errorf("creating anypb from debug message: %w", err)
}

if localFlag {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my comments in #801. They're similar to this as well

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Olshansk can you clarify which comment you are referring to? And what you think should change here?

Copy link
Member

@Olshansk Olshansk Jul 25, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

E.g. #801 (comment)

@h5law Can you take a stab at #801 first? I (accidently) reviewed it before this one so I avoid repeating some of the stylistic recommendations here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Olshansk the reason I am tackling this first is that this is the base of #801 as such I feel it would be difficult to address #801 when the changes may need to be downwards propagated. Will go through #801 alongside from now on

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you. This one is on me

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have gone through #801 and I think I have already addressed most of the relavent comments in this PR as is

if err := debug.PrintPeerList(bus, routerType); err != nil {
return fmt.Errorf("printing peer list: %w", err)
}
return nil
}

// TECHDEBT(#810, #811): will need to wait for DHT bootstrapping to complete before
// p2p broadcast can be used with to reach unstaked actors.
// CONSIDERATION: add the peer commands to the interactive CLI as the P2P module
// instance could persist between commands. Other interactive CLI commands which
// rely on unstaked actor router broadcast are working as expected.

// TECHDEBT(#810, #811): use broadcast instead to reach all peers.
return sendToStakedPeers(cmd, debugMsgAny)
}

func sendToStakedPeers(cmd *cobra.Command, debugMsgAny *anypb.Any) error {
bus, err := helpers.GetBusFromCmd(cmd)
if err != nil {
return err
}

pstore, err := helpers.FetchPeerstore(cmd)
if err != nil {
logger.Global.Fatal().Err(err).Msg("Unable to retrieve the pstore")
}

if pstore.Size() == 0 {
logger.Global.Fatal().Msg("No validators found")
}

for _, peer := range pstore.GetPeerList() {
if err := bus.GetP2PModule().Send(peer.GetAddress(), debugMsgAny); err != nil {
logger.Global.Error().Err(err).Msg("Failed to send debug message")
}
}
return nil
}
4 changes: 2 additions & 2 deletions app/client/cli/peer/peer.go
Original file line number Diff line number Diff line change
@@ -20,8 +20,8 @@ var (
)

func init() {
PeerCmd.PersistentFlags().BoolVarP(&allFlag, "all", "a", false, "operations apply to both staked & unstaked router peerstores")
PeerCmd.PersistentFlags().BoolVarP(&allFlag, "all", "a", true, "operations apply to both staked & unstaked router peerstores")
PeerCmd.PersistentFlags().BoolVarP(&stakedFlag, "staked", "s", false, "operations only apply to staked router peerstore (i.e. raintree)")
PeerCmd.PersistentFlags().BoolVarP(&unstakedFlag, "unstaked", "u", false, "operations only apply to unstaked router peerstore (i.e. gossipsub)")
h5law marked this conversation as resolved.
Show resolved Hide resolved
PeerCmd.PersistentFlags().BoolVarP(&localFlag, "local", "l", false, "operations apply to the local (CLI binary's) P2P module rather than being sent to the --remote_cli_url")
PeerCmd.PersistentFlags().BoolVarP(&localFlag, "local", "l", false, "operations apply to the local (CLI binary's) P2P module instead of being broadcast")
}
28 changes: 28 additions & 0 deletions p2p/debug.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package p2p

import (
"fmt"
"github.com/pokt-network/pocket/p2p/debug"
typesP2P "github.com/pokt-network/pocket/p2p/types"
"github.com/pokt-network/pocket/shared/messaging"
)

func (m *p2pModule) handleDebugMessage(msg *messaging.DebugMessage) error {
switch msg.Action {
h5law marked this conversation as resolved.
Show resolved Hide resolved
case messaging.DebugMessageAction_DEBUG_P2P_PEER_LIST:
if !m.cfg.EnablePeerDiscoveryDebugRpc {
return typesP2P.ErrPeerDiscoveryDebugRPCDisabled
}
default:
// This debug message isn't intended for the P2P module, ignore it.
return nil
}

switch msg.Action {
case messaging.DebugMessageAction_DEBUG_P2P_PEER_LIST:
routerType := debug.RouterType(msg.Message.Value)
return debug.PrintPeerList(m.GetBus(), routerType)
default:
return fmt.Errorf("unsupported P2P debug message action: %s", msg.Action)
}
}
106 changes: 106 additions & 0 deletions p2p/debug/list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package debug
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

debug tag?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

adding //go:build debug causes the CLI to break, my guess is its not build with the debug tag? Will look into this further

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doing a ctrl f for go build is a good starting point here.

Screenshot 2023-07-25 at 3 47 51 PM

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the reason these cannot be put under debug is as follows. The cli calls the PrintPeerList function. So the peer subdir in the cli would also need to be with the debug tag. This calls the helper functions so that would need to be in a debug tag and thus all of the CLI would also need it.

I think it better to change the debug dir to something like printing or introspect perhaps.

WDYT @Olshansk


import (
"fmt"
"github.com/pokt-network/pocket/p2p/providers/peerstore_provider"
"github.com/pokt-network/pocket/p2p/types"
"github.com/pokt-network/pocket/shared/modules"
"os"
)

func PrintPeerList(bus modules.Bus, routerType RouterType) error {
h5law marked this conversation as resolved.
Show resolved Hide resolved
var (
peers types.PeerList
pstorePlurality = ""
)

// TECHDEBT(#810, #811): use `bus.GetPeerstoreProvider()` after peerstore provider
// is retrievable as a proper submodule.
pstoreProviderModule, err := bus.GetModulesRegistry().
GetModule(peerstore_provider.PeerstoreProviderSubmoduleName)
if err != nil {
return fmt.Errorf("getting peerstore provider: %w", err)
}
pstoreProvider, ok := pstoreProviderModule.(peerstore_provider.PeerstoreProvider)
if !ok {
return fmt.Errorf("unknown peerstore provider type: %T", pstoreProviderModule)
}
h5law marked this conversation as resolved.
Show resolved Hide resolved
//--
h5law marked this conversation as resolved.
Show resolved Hide resolved

switch routerType {
case StakedRouterType:
// TODO_THIS_COMMIT: what about unstaked peers actors?
// if !isStaked ...
pstore, err := pstoreProvider.GetStakedPeerstoreAtCurrentHeight()
if err != nil {
return fmt.Errorf("getting unstaked peerstore: %v", err)
}

peers = pstore.GetPeerList()
case UnstakedRouterType:
pstore, err := pstoreProvider.GetUnstakedPeerstore()
if err != nil {
return fmt.Errorf("getting unstaked peerstore: %v", err)
}

peers = pstore.GetPeerList()
case AllRouterTypes:
pstorePlurality = "s"

// TODO_THIS_COMMIT: what about unstaked peers actors?
// if !isStaked ...
stakedPStore, err := pstoreProvider.GetStakedPeerstoreAtCurrentHeight()
if err != nil {
return fmt.Errorf("getting unstaked peerstore: %v", err)
}
unstakedPStore, err := pstoreProvider.GetUnstakedPeerstore()
if err != nil {
return fmt.Errorf("getting unstaked peerstore: %v", err)
}

unstakedPeers := unstakedPStore.GetPeerList()
stakedPeers := stakedPStore.GetPeerList()
additionalPeers, _ := unstakedPeers.Delta(stakedPeers)

// NB: there should never be any "additional" peers. This would represent
// a staked actor who is not participating in background gossip for some
// reason. It's possible that a staked actor node which has restarted
// recently and hasn't yet completed background router bootstrapping may
// result in peers experiencing this state.
if len(additionalPeers) == 0 {
return PrintPeerListTable(unstakedPeers)
}

allPeers := append(types.PeerList{}, unstakedPeers...)
allPeers = append(allPeers, additionalPeers...)
peers = allPeers
default:
return fmt.Errorf("unsupported router type: %s", routerType)
}

if err := LogSelfAddress(bus); err != nil {
return fmt.Errorf("printing self address: %w", err)
}

// NB: Intentionally printing with `fmt` instead of the logger to match
// `utils.PrintPeerListTable` which does not use the logger due to
// incompatibilities with the tabwriter.
// (This doesn't seem to work as expected; i.e. not printing at all in tilt.)
if _, err := fmt.Fprintf(
os.Stdout,
"%s router peerstore%s:\n",
routerType,
pstorePlurality,
); err != nil {
return fmt.Errorf("printing to stdout: %w", err)
}

if err := PrintPeerListTable(peers); err != nil {
return fmt.Errorf("printing peer list: %w", err)
}
return nil
}

func getPeerstoreProvider() (peerstore_provider.PeerstoreProvider, error) {
return nil, nil
}
bryanchriswhite marked this conversation as resolved.
Show resolved Hide resolved
62 changes: 62 additions & 0 deletions p2p/debug/peers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package debug

import (
"fmt"
"os"

"github.com/pokt-network/pocket/p2p/types"
"github.com/pokt-network/pocket/p2p/utils"
"github.com/pokt-network/pocket/shared/modules"
)

type RouterType string

const (
StakedRouterType RouterType = "staked"
UnstakedRouterType RouterType = "unstaked"
AllRouterTypes RouterType = "all"
)

var peerListTableHeader = []string{"Peer ID", "Pokt Address", "ServiceURL"}

func LogSelfAddress(bus modules.Bus) error {
p2pModule := bus.GetP2PModule()
if p2pModule == nil {
return fmt.Errorf("no p2p module found on the bus")
}

selfAddr, err := p2pModule.GetAddress()
if err != nil {
return fmt.Errorf("getting self address: %w", err)
}

_, err = fmt.Fprintf(os.Stdout, "self address: %s", selfAddr.String())
return err
}

// PrintPeerListTable prints a table of the passed peers to stdout. Header row is defined
// by `peerListTableHeader`. Row printing behavior is defined by `peerListRowConsumerFactory`.
func PrintPeerListTable(peers types.PeerList) error {
return utils.PrintTable(peerListTableHeader, peerListRowConsumerFactory(peers))
}

func peerListRowConsumerFactory(peers types.PeerList) utils.RowConsumer {
return func(provideRow utils.RowProvider) error {
for _, peer := range peers {
libp2pAddrInfo, err := utils.Libp2pAddrInfoFromPeer(peer)
if err != nil {
return fmt.Errorf("converting peer to libp2p addr info: %w", err)
}

err = provideRow(
libp2pAddrInfo.ID.String(),
peer.GetAddress().String(),
peer.GetServiceURL(),
)
if err != nil {
return err
}
}
return nil
}
}
5 changes: 0 additions & 5 deletions p2p/event_handler.go
Original file line number Diff line number Diff line change
@@ -2,7 +2,6 @@ package p2p

import (
"fmt"

"google.golang.org/protobuf/types/known/anypb"

"github.com/pokt-network/pocket/shared/codec"
@@ -100,7 +99,3 @@ func (m *p2pModule) HandleEvent(event *anypb.Any) error {

return nil
}

func (m *p2pModule) handleDebugMessage(msg *messaging.DebugMessage) error {
return nil
}
Loading