From cfe840169eb000d79b0af2a3a575d160eadedfb0 Mon Sep 17 00:00:00 2001 From: Mario Apra Date: Thu, 7 Nov 2024 16:19:58 +0000 Subject: [PATCH 1/2] Update public address handling in P2P initialization Add logic to fetch and set public address if not provided. This includes making an HTTP request to get the public IP and updating the address port to match the listen address. This ensures the P2P node can correctly identify and use its public address when not explicitly set. --- p2p/p2p.go | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/p2p/p2p.go b/p2p/p2p.go index 49633f49e..f456cc31b 100644 --- a/p2p/p2p.go +++ b/p2p/p2p.go @@ -3,9 +3,12 @@ package p2p import ( "context" "encoding/hex" + "encoding/json" "errors" "fmt" + "io" "math/rand" + "net/http" "strings" "sync" "time" @@ -73,6 +76,37 @@ func New(addr, publicAddr, version, peers, privKeyStr string, feederNode bool, b if err != nil { return nil, err } + } else { + timeout := 5 * time.Second + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + req, err := http.NewRequestWithContext(ctx, http.MethodGet, "http://ip-api.com/json/", http.NoBody) + if err != nil { + return nil, err + } + resp, err := http.DefaultClient.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + var ip struct { + Query string + } + err = json.Unmarshal(body, &ip) + if err != nil { + return nil, err + } + guessedPublicAddr := ip.Query + addrPort := addr[strings.LastIndex(addr, "/")+1:] + guessedPublicAddr = fmt.Sprintf("/ip4/%s/tcp/%s", guessedPublicAddr, addrPort) + publicMultiAddr, err = multiaddr.NewMultiaddr(guessedPublicAddr) + if err != nil { + return nil, err + } } prvKey, err := privateKey(privKeyStr) @@ -110,6 +144,16 @@ func New(addr, publicAddr, version, peers, privKeyStr string, feederNode bool, b if err != nil { return nil, err } + // Update public address port to match the listen address. + if publicAddr == "" { + // Update the port of publicMultiAddr to match the port of p2pHost.Addrs()[0] + port := p2pHost.Addrs()[0].String() + port = port[strings.LastIndex(port, "/")+1:] + publicMultiAddr, err = multiaddr.NewMultiaddr(fmt.Sprintf("%s/tcp/%s", publicMultiAddr.String(), port)) + if err != nil { + return nil, err + } + } // Todo: try to understand what will happen if user passes a multiaddr with p2p public and a private key which doesn't match. // For example, a user passes the following multiaddr: --p2p-addr=/ip4/0.0.0.0/tcp/7778/p2p/(SomePublicKey) and also passes a // --p2p-private-key="SomePrivateKey". However, the private public key pair don't match, in this case what will happen? From ea8697612018b151e85165c69fc06cf3879475c0 Mon Sep 17 00:00:00 2001 From: Mario Apra Date: Fri, 8 Nov 2024 07:52:28 +0000 Subject: [PATCH 2/2] dump --- Makefile | 10 +++++++ p2p/p2p.go | 61 ++++++++++++++++++++++------------------ p2p/starknet/handlers.go | 3 ++ p2p/sync.go | 8 ++++-- 4 files changed, 52 insertions(+), 30 deletions(-) diff --git a/Makefile b/Makefile index 951eb6d93..fd418f1bc 100644 --- a/Makefile +++ b/Makefile @@ -157,6 +157,16 @@ node3: --p2p-private-key="54a695e2a5d5717d5ba8730efcafe6f17251a1955733cffc55a4085fbf7f5d2c1b4009314092069ef7ca9b364ce3eb3072531c64dfb2799c6bad76720a5bdff0" \ --metrics-port=9093 +nodep2p1: juno-cached + ./build/juno \ + --network=sepolia \ + --disable-l1-verification \ + --log-level=info \ + --db-path=./p2p-dbs/nodep2p1 \ + --p2p \ + --p2p-peers=/ip4/35.231.95.227/tcp/7777/p2p/12D3KooWNKz9BJmyWVFUnod6SQYLG4dYZNhs3GrMpiot63Y1DLYS \ + --p2p-private-key=5f6cdc3aebcc74af494df054876100368ef6126e3a33fa65b90c765b381ffc37a0a63bbeeefab0740f24a6a38dabb513b9233254ad0020c721c23e69bc820089 + pathfinder: juno-cached ./build/juno \ --network=sepolia \ diff --git a/p2p/p2p.go b/p2p/p2p.go index f456cc31b..40fe284d3 100644 --- a/p2p/p2p.go +++ b/p2p/p2p.go @@ -29,6 +29,7 @@ import ( "github.com/libp2p/go-libp2p/core/network" "github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/core/protocol" + "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/relay" "github.com/multiformats/go-multiaddr" "google.golang.org/protobuf/proto" ) @@ -126,6 +127,22 @@ func New(addr, publicAddr, version, peers, privKeyStr string, feederNode bool, b return addrs } + var peersAddrInfoS []peer.AddrInfo + peersAddrInfoS, err = loadPeers(database) + if err != nil { + log.Warnw("Failed to load peers", "err", err) + } + splitted := strings.Split(peers, ",") + for _, peerStr := range splitted { + var peerAddr *peer.AddrInfo + peerAddr, err = peer.AddrInfoFromString(peerStr) + if err != nil { + return nil, fmt.Errorf("addr info from %q: %w", peerStr, err) + } + + peersAddrInfoS = append(peersAddrInfoS, *peerAddr) + } + p2pHost, err := libp2p.New( libp2p.ListenAddrs(sourceMultiAddr), libp2p.Identity(prvKey), @@ -133,8 +150,11 @@ func New(addr, publicAddr, version, peers, privKeyStr string, feederNode bool, b // Use address factory to add the public address to the list of // addresses that the node will advertise. libp2p.AddrsFactory(addressFactory), - // If we know the public ip, enable the relay service. - libp2p.EnableRelayService(), + // Automatically advertise the relay'ed address when it detects that + // the node is running behind a NAT. + libp2p.EnableAutoRelayWithStaticRelays(peersAddrInfoS), + // // If we know the public ip, enable the relay service. + // libp2p.EnableRelayService(), // When listening behind NAT, enable peers to try to poke thought the // NAT in order to reach the node. libp2p.EnableHolePunching(), @@ -149,43 +169,28 @@ func New(addr, publicAddr, version, peers, privKeyStr string, feederNode bool, b // Update the port of publicMultiAddr to match the port of p2pHost.Addrs()[0] port := p2pHost.Addrs()[0].String() port = port[strings.LastIndex(port, "/")+1:] - publicMultiAddr, err = multiaddr.NewMultiaddr(fmt.Sprintf("%s/tcp/%s", publicMultiAddr.String(), port)) + publicMultiAddr, err = multiaddr.NewMultiaddr(strings.ReplaceAll(publicMultiAddr.String(), "/tcp/0", "/tcp/" + port)) if err != nil { return nil, err } } + + // Force all nodes to be able to act as a relay node + _, err = relay.New(p2pHost) + if err != nil { + log.Warnw("Failed to instantiate the relay: %v", err) + } + // Todo: try to understand what will happen if user passes a multiaddr with p2p public and a private key which doesn't match. // For example, a user passes the following multiaddr: --p2p-addr=/ip4/0.0.0.0/tcp/7778/p2p/(SomePublicKey) and also passes a // --p2p-private-key="SomePrivateKey". However, the private public key pair don't match, in this case what will happen? - return NewWithHost(p2pHost, peers, feederNode, bc, snNetwork, log, database) + return NewWithHost(p2pHost, peersAddrInfoS, feederNode, bc, snNetwork, log, database) } -func NewWithHost(p2phost host.Host, peers string, feederNode bool, bc *blockchain.Blockchain, snNetwork *utils.Network, +func NewWithHost(p2phost host.Host, peersAddrInfoS []peer.AddrInfo, feederNode bool, bc *blockchain.Blockchain, snNetwork *utils.Network, log utils.SimpleLogger, database db.DB, ) (*Service, error) { - var ( - peersAddrInfoS []peer.AddrInfo - err error - ) - - peersAddrInfoS, err = loadPeers(database) - if err != nil { - log.Warnw("Failed to load peers", "err", err) - } - - if peers != "" { - splitted := strings.Split(peers, ",") - for _, peerStr := range splitted { - var peerAddr *peer.AddrInfo - peerAddr, err = peer.AddrInfoFromString(peerStr) - if err != nil { - return nil, fmt.Errorf("addr info from %q: %w", peerStr, err) - } - - peersAddrInfoS = append(peersAddrInfoS, *peerAddr) - } - } - + var err error p2pdht, err := makeDHT(p2phost, peersAddrInfoS) if err != nil { return nil, err diff --git a/p2p/starknet/handlers.go b/p2p/starknet/handlers.go index 28c4eee5f..c78e221ed 100644 --- a/p2p/starknet/handlers.go +++ b/p2p/starknet/handlers.go @@ -7,6 +7,7 @@ import ( "fmt" "iter" "sync" + "time" "github.com/NethermindEth/juno/adapters/core2p2p" "github.com/NethermindEth/juno/adapters/p2p2core" @@ -442,6 +443,8 @@ func (h *Handler) processIterationRequestMulti(iteration *spec.Iteration, finMsg type yieldFunc = func(proto.Message) bool return func(yield yieldFunc) { + time.Sleep(3 * time.Second) + return // while iterator is valid for it.Valid() { // pass it to handler function (some might be interested in header, others in entire block) diff --git a/p2p/sync.go b/p2p/sync.go index 2b2c79b0e..94106749f 100644 --- a/p2p/sync.go +++ b/p2p/sync.go @@ -66,6 +66,7 @@ func (s *syncService) start(ctx context.Context) { continue } + s.sleep(3 * time.Second) s.log.Infow("Start Pipeline", "Current height", nextHeight-1, "Start", nextHeight) // todo change iteration to fetch several objects uint64(min(blockBehind, maxBlocks)) @@ -125,6 +126,8 @@ func (s *syncService) processBlock(ctx context.Context, blockNumber uint64) erro ))) for b := range blocksCh { + continue + if b.err != nil { return fmt.Errorf("failed to process block: %w", b.err) } @@ -636,8 +639,9 @@ func (s *syncService) randomPeer() peer.ID { p := peers[rand.Intn(len(peers))] //nolint:gosec - s.log.Debugw("Number of peers", "len", len(peers)) - s.log.Debugw("Random chosen peer's info", "peerInfo", store.PeerInfo(p)) + s.log.Infow("Number of peers", "len", len(peers)) + s.log.Infow("Peers", "peers", peers) + s.log.Infow("Random chosen peer's info", "peerInfo", store.PeerInfo(p)) return p }