From 4283690c8cac5ccc289527034d6ea94870ccba46 Mon Sep 17 00:00:00 2001 From: Mikel Cortes Date: Thu, 20 Jun 2024 10:56:28 +0200 Subject: [PATCH] add flag to determine whether we want to advertise local IP to trusted Prysm node --- cmd/hermes/cmd_eth.go | 10 ++++++++++ eth/node.go | 23 +++++++++++++++++------ eth/node_config.go | 7 ++++--- eth/peerer.go | 31 ++++++++++++++++++++----------- host/host.go | 11 +++++++++++ 5 files changed, 62 insertions(+), 20 deletions(-) diff --git a/cmd/hermes/cmd_eth.go b/cmd/hermes/cmd_eth.go index 6609144..594cf79 100644 --- a/cmd/hermes/cmd_eth.go +++ b/cmd/hermes/cmd_eth.go @@ -27,6 +27,7 @@ var ethConfig = &struct { Libp2pHost string Libp2pPort int Libp2pPeerscoreSnapshotFreq time.Duration + LocalTrustedAddr bool PrysmHost string PrysmPortHTTP int PrysmPortGRPC int @@ -42,6 +43,7 @@ var ethConfig = &struct { Libp2pHost: "127.0.0.1", Libp2pPort: 0, Libp2pPeerscoreSnapshotFreq: 60 * time.Second, + LocalTrustedAddr: false, // default -> advertise the private multiaddress to our trusted Prysm node PrysmHost: "", PrysmPortHTTP: 3500, // default -> https://docs.prylabs.network/docs/prysm-usage/p2p-host-ip PrysmPortGRPC: 4000, // default -> https://docs.prylabs.network/docs/prysm-usage/p2p-host-ip @@ -139,6 +141,13 @@ var cmdEthFlags = []cli.Flag{ Destination: ðConfig.Libp2pPeerscoreSnapshotFreq, DefaultText: "random", }, + &cli.BoolFlag{ + Name: "local.trusted.addr", + EnvVars: []string{"HERMES_ETH_LOCAL_TRUSTED_ADDRESS"}, + Usage: "To advertise the localhost multiaddress to our trusted control Prysm node", + Value: ethConfig.LocalTrustedAddr, + Destination: ðConfig.LocalTrustedAddr, + }, &cli.StringFlag{ Name: "prysm.host", EnvVars: []string{"HERMES_ETH_PRYSM_HOST"}, @@ -219,6 +228,7 @@ func cmdEthAction(c *cli.Context) error { Libp2pPeerscoreSnapshotFreq: ethConfig.Libp2pPeerscoreSnapshotFreq, GossipSubMessageEncoder: encoder.SszNetworkEncoder{}, RPCEncoder: encoder.SszNetworkEncoder{}, + LocalTrustedAddr: ethConfig.LocalTrustedAddr, PrysmHost: ethConfig.PrysmHost, PrysmPortHTTP: ethConfig.PrysmPortHTTP, PrysmPortGRPC: ethConfig.PrysmPortGRPC, diff --git a/eth/node.go b/eth/node.go index dfa45f0..3309a7b 100644 --- a/eth/node.go +++ b/eth/node.go @@ -11,6 +11,7 @@ import ( "github.com/aws/aws-sdk-go-v2/service/kinesis" gk "github.com/dennis-tra/go-kinesis" "github.com/libp2p/go-libp2p/core/peer" + ma "github.com/multiformats/go-multiaddr" eth "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" "github.com/thejerf/suture/v4" "go.opentelemetry.io/otel/attribute" @@ -209,7 +210,7 @@ func NewNode(cfg *NodeConfig) (*Node, error) { reqResp: reqResp, pubSub: pubSub, pryClient: pryClient, - peerer: NewPeerer(h, pryClient), + peerer: NewPeerer(h, pryClient, cfg.LocalTrustedAddr), disc: disc, eventCallbacks: []func(ctx context.Context, event *host.TraceEvent){}, } @@ -398,15 +399,25 @@ func (n *Node) Start(ctx context.Context) error { connSignal := n.host.ConnSignal(timeoutCtx, addrInfo.ID) // register ourselves as a trusted peer by submitting our private ip address - privateMaddr, err := n.host.PrivateListenMaddr() - if err != nil { - return err + var trustedMaddr ma.Multiaddr + if n.cfg.LocalTrustedAddr { + trustedMaddr, err = n.host.LocalListenMaddr() + if err != nil { + return err + } + slog.Info("Adding ourselves as a trusted peer to Prysm", tele.LogAttrPeerID(n.host.ID()), "on local maddr", trustedMaddr) + } else { + trustedMaddr, err = n.host.PrivateListenMaddr() + if err != nil { + return err + } + slog.Info("Adding ourselves as a trusted peer to Prysm", tele.LogAttrPeerID(n.host.ID()), "on priv maddr", trustedMaddr) } - slog.Info("Adding ourselves as a trusted peer to Prysm", tele.LogAttrPeerID(n.host.ID()), "maddr", privateMaddr) - if err := n.pryClient.AddTrustedPeer(ctx, n.host.ID(), privateMaddr); err != nil { + if err := n.pryClient.AddTrustedPeer(ctx, n.host.ID(), trustedMaddr); err != nil { return fmt.Errorf("failed adding ourself as trusted peer: %w", err) } + defer func() { // unregister ourselves as a trusted peer from prysm. Context timeout // is not necessary because the pryClient applies a 5s timeout to each API call diff --git a/eth/node_config.go b/eth/node_config.go index 1653741..7a1ee9e 100644 --- a/eth/node_config.go +++ b/eth/node_config.go @@ -71,9 +71,10 @@ type NodeConfig struct { RPCEncoder encoder.NetworkEncoding // The address information where the Beacon API or Prysm's custom API is accessible at - PrysmHost string - PrysmPortHTTP int - PrysmPortGRPC int + LocalTrustedAddr bool + PrysmHost string + PrysmPortHTTP int + PrysmPortGRPC int // The AWS Kinesis Data Stream configuration AWSConfig *aws.Config // if set, we consider Kinesis to be enabled diff --git a/eth/peerer.go b/eth/peerer.go index ce5c8c3..6df444b 100644 --- a/eth/peerer.go +++ b/eth/peerer.go @@ -7,6 +7,7 @@ import ( "time" "github.com/libp2p/go-libp2p/core/network" + ma "github.com/multiformats/go-multiaddr" "github.com/probe-lab/hermes/host" "github.com/probe-lab/hermes/tele" "github.com/thejerf/suture/v4" @@ -17,8 +18,9 @@ import ( // [PeererClient] implementations can be used. In the case of Prysm, use the // [PrysmClient] implementation as it implements [PeererClient]. type Peerer struct { - host *host.Host - pryClient *PrysmClient + host *host.Host + pryClient *PrysmClient + localTrustedAddr bool } var _ suture.Service = (*Peerer)(nil) @@ -26,7 +28,7 @@ var _ suture.Service = (*Peerer)(nil) // NewPeerer creates a new instance of the Peerer struct. // It takes a pointer to a *host.Host and a [PeererClient] implementation as parameters. // It returns a pointer to the newly created Peerer instance. -func NewPeerer(h *host.Host, pryClient *PrysmClient) *Peerer { +func NewPeerer(h *host.Host, pryClient *PrysmClient, localTrustedAddr bool) *Peerer { return &Peerer{ host: h, pryClient: pryClient, @@ -69,15 +71,22 @@ func (p *Peerer) Serve(ctx context.Context) error { slog.Warn("Not registered as a trusted peer") - // we're not in the list of trusted peers - // get our private liste multiaddress and register again - privateMaddr, err := p.host.PrivateListenMaddr() - if err != nil { - return err - } - // register ourselves as a trusted peer - if err := p.pryClient.AddTrustedPeer(ctx, p.host.ID(), privateMaddr); err != nil { + // register ourselves as a trusted peer by submitting our private ip address + var trustedMaddr ma.Multiaddr + if p.localTrustedAddr { + trustedMaddr, err = p.host.LocalListenMaddr() + if err != nil { + return err + } + } else { + trustedMaddr, err = p.host.PrivateListenMaddr() + if err != nil { + return err + } + } + slog.Info("ensuring we are trusted by trusted Prysm with peer_id:", tele.LogAttrPeerID(p.host.ID()), "on local maddr", trustedMaddr) + if err := p.pryClient.AddTrustedPeer(ctx, p.host.ID(), trustedMaddr); err != nil { return fmt.Errorf("failed adding ourself as trusted peer: %w", err) } diff --git a/host/host.go b/host/host.go index e09dc24..9f6ceb1 100644 --- a/host/host.go +++ b/host/host.go @@ -268,6 +268,17 @@ func (h *Host) PrivateListenMaddr() (ma.Multiaddr, error) { return nil, fmt.Errorf("no private multi address found in %s", h.Addrs()) } +// LocalListenMaddr returns the first multiaddress in a localhost IP range that +// this host is listening on. +func (h *Host) LocalListenMaddr() (ma.Multiaddr, error) { + for _, maddr := range h.Addrs() { + if manet.IsIPLoopback(maddr) { + return maddr, nil + } + } + return nil, fmt.Errorf("no local multi address found in %s", h.Addrs()) +} + func (h *Host) TracedTopicHandler(handler TopicHandler) TopicHandler { return func(ctx context.Context, msg *pubsub.Message) error { slog.Debug("Handling gossip message", "topic", msg.GetTopic())