diff --git a/config/settings.example.json b/config/settings.example.json index 7acf167..92d8bfe 100644 --- a/config/settings.example.json +++ b/config/settings.example.json @@ -1,9 +1,9 @@ { - "SequencerId": "SEQUENCER_ID", - "RelayerRendezvousPoint": "RELAYER_RENDEZVOUS_POINT", - "ClientRendezvousPoint": "CLIENT_RENDEZVOUS_POINT", "RelayerPrivateKey": "RELAYER_PRIVATE_KEY", "PowerloomReportingUrl": "POWERLOOM_REPORTING_URL", "SignerAccountAddress": "SIGNER_ACCOUNT_ADDRESS", - "LocalCollectorPort": "LOCAL_COLLECTOR_PORT" + "LocalCollectorPort": "LOCAL_COLLECTOR_PORT", + "TrustedRelayersListUrl" : "TRUSTED_RELAYERS_LIST_URL", + "SequencerNetworkPath" : "SEQUENCER_MULTIADDR", + "DataMarketAddress" : "DATA_MARKET_CONTRACT" } diff --git a/config/settings.go b/config/settings.go index f1412a6..09e6b21 100644 --- a/config/settings.go +++ b/config/settings.go @@ -17,6 +17,9 @@ type Settings struct { PowerloomReportingUrl string `json:"PowerloomReportingUrl"` SignerAccountAddress string `json:"SignerAccountAddress"` PortNumber string `json:"LocalCollectorPort"` + TrustedRelayersListUrl string `json:"TrustedRelayersListUrl"` + SequencerNetworkPath string `json:"Sequencers"` + DataMarketAddress string `json:"DataMarketAddress"` } func LoadConfig() { @@ -37,5 +40,10 @@ func LoadConfig() { if err != nil { log.Fatalf("Failed to decode config file: %v", err) } + + if config.TrustedRelayersListUrl == "" { + config.TrustedRelayersListUrl = "https://raw.githubusercontent.com/PowerLoom/snapshotter-lite-local-collector/feat/trusted-relayers/relayers.json" + } + SettingsObj = &config } diff --git a/config/settings.json b/config/settings.json new file mode 100644 index 0000000..e17dd5b --- /dev/null +++ b/config/settings.json @@ -0,0 +1,12 @@ +{ + "SequencerId": "QmdJbNsbHpFseUPKC9vLt4vMsfdxA4dyHPzsAWuzYz3Yxx", + "RelayerRendezvousPoint": "RELAYER_RENDEZVOUS_POINT", + "ClientRendezvousPoint": "CLIENT_RENDEZVOUS_POINT", + "RelayerPrivateKey": "RELAYER_PRIVATE_KEY", + "PowerloomReportingUrl": "POWERLOOM_REPORTING_URL", + "SignerAccountAddress": "SIGNER_ACCOUNT_ADDRESS", + "LocalCollectorPort": "LOCAL_COLLECTOR_PORT", + "TrustedRelayersListUrl" : "https://raw.githubusercontent.com/PowerLoom/snapshotter-lite-local-collector/feat/trusted-relayers/relayers.json", + "SequencerNetworkPath": "/dns/proto-snapshot-listener.aws2.powerloom.io/tcp/9100/p2p/QmTK9e9QNEotPkjWAdZT5bbYKV7PEJVu7iXzdVn3VZDEk9", + "DataMarketAddress" : "0xa8D4C62BD8831bca08C9a16b3e76C824c9658eA1" +} diff --git a/go.mod b/go.mod index b2e9a16..ab4589a 100644 --- a/go.mod +++ b/go.mod @@ -8,8 +8,10 @@ require ( github.com/libp2p/go-libp2p v0.32.2 github.com/libp2p/go-libp2p-kad-dht v0.25.2 github.com/multiformats/go-multiaddr v0.12.2 + github.com/pkg/errors v0.9.1 github.com/sethvargo/go-retry v0.2.4 github.com/sirupsen/logrus v1.9.3 + github.com/stretchr/testify v1.8.4 google.golang.org/grpc v1.62.0 google.golang.org/protobuf v1.32.0 ) @@ -20,6 +22,7 @@ require ( github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/containerd/cgroups v1.1.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/docker/go-units v0.5.0 // indirect @@ -84,7 +87,7 @@ require ( github.com/opencontainers/runtime-spec v1.1.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect - github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect github.com/prometheus/client_golang v1.16.0 // indirect github.com/prometheus/client_model v0.4.0 // indirect @@ -116,5 +119,6 @@ require ( golang.org/x/tools v0.18.0 // indirect gonum.org/v1/gonum v0.13.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect lukechampine.com/blake3 v1.2.1 // indirect ) diff --git a/go.sum b/go.sum index 9ba638d..86160d3 100644 --- a/go.sum +++ b/go.sum @@ -360,6 +360,7 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= diff --git a/pkgs/service/discovery.go b/pkgs/service/discovery.go index 58978b7..1aee952 100644 --- a/pkgs/service/discovery.go +++ b/pkgs/service/discovery.go @@ -2,7 +2,11 @@ package service import ( "context" - "fmt" + "encoding/json" + "github.com/pkg/errors" + "io" + "net/http" + "proto-snapshot-server/config" "sync" "github.com/cenkalti/backoff/v4" @@ -10,87 +14,130 @@ import ( "github.com/libp2p/go-libp2p/core/host" "github.com/libp2p/go-libp2p/core/network" "github.com/libp2p/go-libp2p/core/peer" - "github.com/libp2p/go-libp2p/core/peerstore" - "github.com/libp2p/go-libp2p/p2p/discovery/routing" ma "github.com/multiformats/go-multiaddr" log "github.com/sirupsen/logrus" ) -func isVisited(id peer.ID, visited []peer.ID) bool { - for _, v := range visited { - if v == id { - return true - } - } - return false +type Relayer struct { + ID string `json:"id"` + Name string `json:"name"` + RendezvousPoint string `json:"rendezvousPoint"` + Maddr string `json:"maddr"` } -func connectToStableRelayer(ctx context.Context, host host.Host, relayerAddr string) peer.ID { - stableRelayerMA, err := ma.NewMultiaddr("/ip4/104.248.63.86/tcp/5001/p2p/QmQSEao6C3SuPZ8cWiYccPqsd7LtWBTzNgXQZiAjeGTQpm") +type Sequencer struct { + ID string `json:"id"` + Maddr string `json:"maddr"` + DataMarketAddress string `json:"dataMarketAddress"` + Environment string `json:"environment"` +} + +func fetchSequencer(url string, dataMarketAddress string) (Sequencer, error) { + resp, err := http.Get(url) if err != nil { - log.Debugln("Failed to parse stable peer multiaddress: ", err) + log.Fatalf("Failed to fetch JSON: %v", err) } + defer resp.Body.Close() - peerInfo, err := peer.AddrInfoFromP2pAddr(stableRelayerMA) + body, err := io.ReadAll(resp.Body) if err != nil { - log.Debugln("Failed to extract peer info from multiaddress: %v", err) + log.Debugf("Failed to read response body: %v", err) } - // Add the peer to the peerstore - host.Peerstore().AddAddrs(peerInfo.ID, peerInfo.Addrs, peerstore.PermanentAddrTTL) + var sequencers []Sequencer + err = json.Unmarshal(body, &sequencers) + if err != nil { + log.Debugln("Failed to unmarshal JSON:", err) + } - if err := host.Connect(ctx, *peerInfo); err != nil { - log.Debugln("Failed to connect to stable relayer: %v", err) + for _, sequencer := range sequencers { + log.Debugf( + "ID: %s, Maddr: %s, Data Market Address: %s, Environment: %s\n", + sequencer.ID, + sequencer.Maddr, + sequencer.DataMarketAddress, + sequencer.Environment, + ) + + if sequencer.DataMarketAddress == dataMarketAddress { + return sequencer, nil + } } - fmt.Println("Connected to stable relayer:", peerInfo.ID) - return peerInfo.ID + return Sequencer{}, errors.New("Sequencer not found") } -func ConnectToPeer(ctx context.Context, routingDiscovery *routing.RoutingDiscovery, rendezvousString string, host host.Host, visited []peer.ID) peer.ID { - stableRelayer1 := "/ip4/104.248.63.86/tcp/5001/p2p/QmQSEao6C3SuPZ8cWiYccPqsd7LtWBTzNgXQZiAjeGTQpm" - stableRelayer2 := "/ip4/137.184.132.196/tcp/5001/p2p/QmU3xwsjRqQR4pjJQ7Cxhcb2tiPvaJ6Z5AHDULq7hHWvvj" +func fetchTrustedRelayers(url string) []Relayer { + resp, err := http.Get(url) + if err != nil { + log.Fatalf("Failed to fetch JSON: %v", err) + } + defer resp.Body.Close() - // Connect to stable relayers - peerID1 := connectToStableRelayer(ctx, host, stableRelayer1) - peerID2 := connectToStableRelayer(ctx, host, stableRelayer2) + body, err := io.ReadAll(resp.Body) + if err != nil { + log.Debugf("Failed to read response body: %v", err) + } - if peerID1 != "" { - return peerID1 + var relayers []Relayer + err = json.Unmarshal(body, &relayers) + if err != nil { + log.Debugln("Failed to unmarshal JSON:", err) } - if peerID2 != "" { - return peerID2 + + for _, relayer := range relayers { + log.Debugf("ID: %s, Name: %s, Rendezvous Point: %s, Maddr: %s\n", relayer.ID, relayer.Name, relayer.RendezvousPoint, relayer.Maddr) } - peerChan, err := routingDiscovery.FindPeers(ctx, rendezvousString) + return relayers +} + +func AddPeerConnection(ctx context.Context, host host.Host, relayerAddr string) bool { + stableRelayerMA, err := ma.NewMultiaddr(relayerAddr) + if err != nil { + log.Debugln("Failed to parse stable peer multiaddress: ", err) + } + peerInfo, err := peer.AddrInfoFromP2pAddr(stableRelayerMA) if err != nil { - log.Fatalf("Failed to find peers: %s", err) + log.Debugln("Failed to extract peer info from multiaddress:", err) } - log.Debugln("Triggering peer discovery") - log.Debugln("Skipping visited peers: ", visited) + if host.Network().Connectedness(peerInfo.ID) == network.Connected { + log.Debugln("Skipping connected relayer: ", peerInfo.ID) + return true + } - for relayer := range peerChan { - if relayer.ID == host.ID() { - continue // Skip self or peers with no addresses + err = host.Connect(ctx, *peerInfo) + if err != nil { + log.Errorf("Failed to connect to relayer %s: %s", peerInfo.ID, err) + return false + if err := backoff.Retry(func() error { return host.Connect(ctx, *peerInfo) }, backoff.WithMaxRetries(backoff.NewExponentialBackOff(), 1)); err != nil { + log.Errorf("Failed to connect to relayer %s: %s", peerInfo.ID, err) + } else { + log.Infof("Connected to new relayer: %s", peerInfo.ID) + return true } + } else { + log.Infof("Connected to new relayer: %s", peerInfo.ID) + log.Infoln("Connected: ", host.Network().ConnsToPeer(peerInfo.ID)) + return true + } - if host.Network().Connectedness(relayer.ID) != network.Connected { - // Connect to the relayer if not already connected - if err = backoff.Retry(func() error { return host.Connect(ctx, relayer) }, backoff.WithMaxRetries(backoff.NewExponentialBackOff(), 1)); err != nil { - log.Errorf("Failed to connect to relayer %s: %s", relayer.ID, err) - } else { - log.Infof("Connected to new relayer: %s", relayer.ID) - return relayer.ID - } - } else { - log.Debugln("Already connected to: ", relayer.ID) - // return relayer.ID + return false +} + +func ConnectToTrustedRelayers(ctx context.Context, host host.Host) []Relayer { + relayers := fetchTrustedRelayers(config.SettingsObj.TrustedRelayersListUrl) + var connectedRelayers []Relayer + + for _, relayer := range relayers { + if AddPeerConnection(ctx, host, relayer.Maddr) { + connectedRelayers = append(connectedRelayers, relayer) } } - log.Debugln("Active connections: ", activeConnections) - return "" + + return connectedRelayers } func ConfigureDHT(ctx context.Context, host host.Host) *dht.IpfsDHT { diff --git a/pkgs/service/discovery_test.go b/pkgs/service/discovery_test.go new file mode 100644 index 0000000..77f2e31 --- /dev/null +++ b/pkgs/service/discovery_test.go @@ -0,0 +1,214 @@ +package service + +import ( + "context" + "encoding/json" + "errors" + "github.com/libp2p/go-libp2p" + "github.com/libp2p/go-libp2p/core/peer" + ma "github.com/multiformats/go-multiaddr" + log "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" + "io" + "net/http" + "net/http/httptest" + "proto-snapshot-server/config" + "testing" +) + +type Settings struct { + TrustedRelayersListUrl string +} + +var SettingsObj *Settings + +func TestFetchTrustedRelayers(t *testing.T) { + // Sample JSON response + mockResponse := `[{ + "id": "QmQSEao6C3SuPZ8cWiYccPqsd7LtWBTzNgXQZiAjeGTQpm", + "name": "Relayer1", + "rendezvousPoint": "Relayer_POP_test_simulation_phase_1", + "maddr": "/ip4/104.248.63.86/tcp/5001/p2p/QmQSEao6C3SuPZ8cWiYccPqsd7LtWBTzNgXQZiAjeGTQpm" + }, { + "id": "QmU3xwsjRqQR4pjJQ7Cxhcb2tiPvaJ6Z5AHDULq7hHWvvj", + "name": "Relayer2", + "rendezvousPoint": "Relayer_POP_test_simulation_phase_1", + "maddr": "/ip4/137.184.132.196/tcp/5001/p2p/QmU3xwsjRqQR4pjJQ7Cxhcb2tiPvaJ6Z5AHDULq7hHWvvj" + }]` + + // Create a test server that returns the mock JSON response + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + io.WriteString(w, mockResponse) + })) + defer ts.Close() + + // Call the function to test + relayers := fetchTrustedRelayers("https://raw.githubusercontent.com/PowerLoom/snapshotter-lite-local-collector/feat/trusted-relayers/relayers.json") + + // Expected result + expected := []Relayer{ + { + ID: "QmQSEao6C3SuPZ8cWiYccPqsd7LtWBTzNgXQZiAjeGTQpm", + Name: "Relayer1", + RendezvousPoint: "Relayer_POP_test_simulation_phase_1", + Maddr: "/ip4/104.248.63.86/tcp/9100/p2p/QmQSEao6C3SuPZ8cWiYccPqsd7LtWBTzNgXQZiAjeGTQpm", + }, + { + ID: "QmU3xwsjRqQR4pjJQ7Cxhcb2tiPvaJ6Z5AHDULq7hHWvvj", + Name: "Relayer2", + RendezvousPoint: "Relayer_POP_test_simulation_phase_1", + Maddr: "/ip4/137.184.132.196/tcp/9100/p2p/QmU3xwsjRqQR4pjJQ7Cxhcb2tiPvaJ6Z5AHDULq7hHWvvj", + }, + } + + if len(relayers) != len(expected) { + t.Fatalf("expected %d relayers, got %d", len(expected), len(relayers)) + } + + for i, r := range relayers { + if r != expected[i] { + t.Errorf("expected relayer %v, got %v", expected[i], r) + } + } +} + +func TestAddPeerConnection(t *testing.T) { + host, err := libp2p.New() + if err != nil { + t.Fatalf("Failed to create host: %v", err) + } + defer host.Close() + ctx := context.Background() + relayerAddr := "/ip4/104.248.63.86/tcp/5001/p2p/QmQSEao6C3SuPZ8cWiYccPqsd7LtWBTzNgXQZiAjeGTQpm" + + result := AddPeerConnection(ctx, host, relayerAddr) + + if !result { + t.Error("expected true, got false") + } +} + +func TestConnectToTrustedRelayers(t *testing.T) { + mockResponse := `[{ + "id": "QmQSEao6C3SuPZ8cWiYccPqsd7LtWBTzNgXQZiAjeGTQpm", + "name": "Relayer1", + "rendezvousPoint": "Relayer_POP_test_simulation_phase_1", + "maddr": "/ip4/104.248.63.86/tcp/9100/p2p/QmQSEao6C3SuPZ8cWiYccPqsd7LtWBTzNgXQZiAjeGTQpm" + }, { + "id": "QmU3xwsjRqQR4pjJQ7Cxhcb2tiPvaJ6Z5AHDULq7hHWvvj", + "name": "Relayer2", + "rendezvousPoint": "Relayer_POP_test_simulation_phase_1", + "maddr": "/ip4/137.184.132.196/tcp/9100/p2p/QmU3xwsjRqQR4pjJQ7Cxhcb2tiPvaJ6Z5AHDULq7hHWvvj" + }]` + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + io.WriteString(w, mockResponse) + })) + + defer ts.Close() + + config.SettingsObj = &config.Settings{ + TrustedRelayersListUrl: ts.URL, + } + + host, err := libp2p.New() + if err != nil { + t.Fatalf("Failed to create host: %v", err) + } + defer host.Close() + + relayers := ConnectToTrustedRelayers(context.Background(), host) + + //time.Sleep(3 * time.Second) + + log.Println(host.Network().Connectedness(peer.ID(relayers[0].ID))) + log.Println(host.Network().Connectedness(peer.ID(relayers[1].ID))) + + host.Connect(context.Background(), peer.AddrInfo{ + ID: peer.ID("QmdJbNsbHpFseUPKC9vLt4vMsfdxA4dyHPzsAWuzYz3Yxx"), + Addrs: []ma.Multiaddr{ma.StringCast("/ip4/159.223.164.169/tcp/9100/p2p/QmdJbNsbHpFseUPKC9vLt4vMsfdxA4dyHPzsAWuzYz3Yxx")}, + }) + + //time.Sleep(3 * time.Second) + + log.Println(host.Network().Connectedness(peer.ID("QmdJbNsbHpFseUPKC9vLt4vMsfdxA4dyHPzsAWuzYz3Yxx"))) + // TODO: FINISH THIS TEST +} + +func TestFetchSequencer(t *testing.T) { + // Create mock data + sequencers := []Sequencer{ + { + ID: "QmTK9e9QNEotPkjWAdZT5bbYKV7PEJVu7iXzdVn3VZDEk9", + Maddr: "/dns/proto-snapshot-listener.aws2.powerloom.io/tcp/9100/p2p/QmTK9e9QNEotPkjWAdZT5bbYKV7PEJVu7iXzdVn3VZDEk9", + DataMarketAddress: "0xa8D4C62BD8831bca08C9a16b3e76C824c9658eA1", + Environment: "prod", + }, + { + ID: "QmbWC2TKXDWnYB1picmYwAMRUz7ACXLXDWyLibjHnaRyoN", + Maddr: "/dns/proto-snapshot-listener.aws2.powerloom.io/tcp/9100/p2p/QmbWC2TKXDWnYB1picmYwAMRUz7ACXLXDWyLibjHnaRyoN", + DataMarketAddress: "0x718b3f7B8ef6abA1D1440A26F92AC11EE167005a", + Environment: "staging", + }, + } + + // Convert mock data to JSON + jsonData, err := json.Marshal(sequencers) + assert.NoError(t, err) + + t.Log(string(jsonData)) + + // Create a test server with the mock JSON response + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(jsonData) + })) + defer server.Close() + + tests := []struct { + name string + dataMarketAddr string + environment string + expectedID string + expectedError error + }{ + { + name: "Valid sequencer found (prod)", + dataMarketAddr: "0xa8D4C62BD8831bca08C9a16b3e76C824c9658eA1", + environment: "prod", + expectedID: "QmTK9e9QNEotPkjWAdZT5bbYKV7PEJVu7iXzdVn3VZDEk9", + expectedError: nil, + }, + { + name: "Valid sequencer found (staging)", + dataMarketAddr: "0x718b3f7B8ef6abA1D1440A26F92AC11EE167005a", + environment: "staging", + expectedID: "QmbWC2TKXDWnYB1picmYwAMRUz7ACXLXDWyLibjHnaRyoN", + expectedError: nil, + }, + { + name: "Sequencer not found", + dataMarketAddr: "0x9999", + environment: "prod", + expectedID: "", + expectedError: errors.New("Sequencer not found"), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + sequencer, err := fetchSequencer(server.URL, tt.dataMarketAddr) + + if tt.expectedError != nil { + assert.Error(t, err) + assert.Equal(t, tt.expectedError.Error(), err.Error()) + } else { + assert.NoError(t, err) + assert.Equal(t, tt.expectedID, sequencer.ID) + } + }) + } +} diff --git a/pkgs/service/relay.go b/pkgs/service/relay.go index 2e5b3f1..894dfe2 100644 --- a/pkgs/service/relay.go +++ b/pkgs/service/relay.go @@ -2,6 +2,8 @@ package service import ( "context" + "fmt" + circuitv2 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/client" "proto-snapshot-server/config" "time" @@ -107,19 +109,64 @@ func ConfigureRelayer() { // return // } // ConnectToSequencer(peerId) + ConnectToSequencer() } +func ConnectToSequencerP2P(relayers []Relayer, p2pHost host.Host) bool { + for _, relayer := range relayers { + relayerMA, err := ma.NewMultiaddr(relayer.Maddr) + relayerInfo, err := peer.AddrInfoFromP2pAddr(relayerMA) + if reservation, err := circuitv2.Reserve(context.Background(), p2pHost, *relayerInfo); err != nil { + log.Fatalf("Failed to request reservation with relay: %v", err) + } else { + fmt.Println("Reservation with relay successful", reservation.Expiration, reservation.LimitDuration) + } + sequencerAddr, err := ma.NewMultiaddr(fmt.Sprintf("%s/p2p-circuit/p2p/%s", relayer.Maddr, config.SettingsObj.SequencerId)) + + if err != nil { + log.Debugln(err.Error()) + } + + log.Debugln("Connecting to Sequencer: ", sequencerAddr.String()) + isConnected := AddPeerConnection(context.Background(), p2pHost, sequencerAddr.String()) + if isConnected { + return true + } + } + return false +} + func ConnectToSequencer() { - // if peerId == "" { - // log.Debugln("Not connected to a relayer") - // return - // } - // sequencerAddr, err := ma.NewMultiaddr(fmt.Sprintf("/p2p/%s/p2p-circuit/p2p/%s", peerId, config.SettingsObj.SequencerId)) - sequencerAddr, err := ma.NewMultiaddr("/ip4/159.223.164.169/tcp/9100/p2p/QmdJbNsbHpFseUPKC9vLt4vMsfdxA4dyHPzsAWuzYz3Yxx") - if err != nil { - log.Debugln(err.Error()) - return + //trustedRelayers := ConnectToTrustedRelayers(context.Background(), rpctorelay) + //isConnectedP2P := ConnectToSequencerP2P(trustedRelayers, rpctorelay) + //if isConnectedP2P { + // log.Debugln("Successfully connected to the Sequencer: ", rpctorelay.Network().Connectedness(peer.ID(config.SettingsObj.SequencerId)), isConnectedP2P) + // return + //} else { + // log.Debugln("Failed to connect to the Sequencer") + //} + + var sequencerAddr ma.Multiaddr + var err error + + if config.SettingsObj.SequencerNetworkPath != "" { + sequencerAddr, err = ma.NewMultiaddr(config.SettingsObj.SequencerNetworkPath) + if err != nil { + log.Debugln(err.Error()) + return + } + } else { + sequencer, err := fetchSequencer("https://raw.githubusercontent.com/PowerLoom/snapshotter-lite-local-collector/feat/trusted-relayers/sequencers.json", config.SettingsObj.DataMarketAddress) + if err != nil { + log.Debugln(err.Error()) + } + config.SettingsObj.SequencerNetworkPath = sequencer.Maddr + sequencerAddr, err = ma.NewMultiaddr(sequencer.Maddr) + if err != nil { + log.Debugln(err.Error()) + return + } } sequencerInfo, err := peer.AddrInfoFromP2pAddr(sequencerAddr) diff --git a/pkgs/service/relay_test.go b/pkgs/service/relay_test.go new file mode 100644 index 0000000..b876899 --- /dev/null +++ b/pkgs/service/relay_test.go @@ -0,0 +1,61 @@ +package service + +import ( + "context" + "github.com/libp2p/go-libp2p" + "github.com/libp2p/go-libp2p/core/peer" + "io" + "log" + "net/http" + "net/http/httptest" + "proto-snapshot-server/config" + "testing" +) + +func TestConnectToSequencerP2P(t *testing.T) { + // Mock relayers data + mockResponse := `[{ + "id": "QmQSEao6C3SuPZ8cWiYccPqsd7LtWBTzNgXQZiAjeGTQpm", + "name": "Relayer1", + "rendezvousPoint": "Relayer_POP_test_simulation_phase_1", + "maddr": "/ip4/104.248.63.86/tcp/9100/p2p/QmQSEao6C3SuPZ8cWiYccPqsd7LtWBTzNgXQZiAjeGTQpm" + }, { + "id": "QmU3xwsjRqQR4pjJQ7Cxhcb2tiPvaJ6Z5AHDULq7hHWvvj", + "name": "Relayer2", + "rendezvousPoint": "Relayer_POP_test_simulation_phase_1", + "maddr": "/ip4/137.184.132.196/tcp/9100/p2p/QmU3xwsjRqQR4pjJQ7Cxhcb2tiPvaJ6Z5AHDULq7hHWvvj" + }]` + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + io.WriteString(w, mockResponse) + })) + + defer ts.Close() + + // Initialize the configuration settings + config.SettingsObj = &config.Settings{ + TrustedRelayersListUrl: ts.URL, + SequencerId: "QmdJbNsbHpFseUPKC9vLt4vMsfdxA4dyHPzsAWuzYz3Yxx", + } + + host, err := libp2p.New() + if err != nil { + t.Fatalf("Failed to create host: %v", err) + } + defer host.Close() + + // Fetch the relayers + relayers := ConnectToTrustedRelayers(context.Background(), host) + + // Test the function + result := ConnectToSequencerP2P(relayers, host) + + if !result { + t.Error("expected true, got false") + } + + log.Println("Connected to peer 1: ", host.Network().ConnsToPeer(peer.ID(relayers[0].ID))) + log.Println("Connected to peer 2: ", host.Network().ConnsToPeer(peer.ID(relayers[0].ID))) + log.Println("Connected to peer 3: ", host.Network().ConnsToPeer(peer.ID(config.SettingsObj.SequencerId))) +} diff --git a/relayers.json b/relayers.json new file mode 100644 index 0000000..2794d8c --- /dev/null +++ b/relayers.json @@ -0,0 +1,11 @@ +[{ + "id": "QmQSEao6C3SuPZ8cWiYccPqsd7LtWBTzNgXQZiAjeGTQpm", + "name": "Relayer1", + "rendezvousPoint": "Relayer_POP_test_simulation_phase_1", + "maddr": "/ip4/104.248.63.86/tcp/9100/p2p/QmQSEao6C3SuPZ8cWiYccPqsd7LtWBTzNgXQZiAjeGTQpm" +}, { + "id": "QmU3xwsjRqQR4pjJQ7Cxhcb2tiPvaJ6Z5AHDULq7hHWvvj", + "name": "Relayer2", + "rendezvousPoint": "Relayer_POP_test_simulation_phase_1", + "maddr": "/ip4/137.184.132.196/tcp/9100/p2p/QmU3xwsjRqQR4pjJQ7Cxhcb2tiPvaJ6Z5AHDULq7hHWvvj" +}] \ No newline at end of file diff --git a/sequencers.json b/sequencers.json new file mode 100644 index 0000000..274015a --- /dev/null +++ b/sequencers.json @@ -0,0 +1,14 @@ +[ + { + "id": "QmTK9e9QNEotPkjWAdZT5bbYKV7PEJVu7iXzdVn3VZDEk9", + "maddr": "/dns/proto-snapshot-listener.aws2.powerloom.io/tcp/9100/p2p/QmTK9e9QNEotPkjWAdZT5bbYKV7PEJVu7iXzdVn3VZDEk9", + "dataMarketAddress": "0xa8D4C62BD8831bca08C9a16b3e76C824c9658eA1", + "environment": "prod" + }, + { + "id": "QmbWC2TKXDWnYB1picmYwAMRUz7ACXLXDWyLibjHnaRyoN", + "maddr": "/dns/staging-proto-snapshot-listener.aws2.powerloom.io/tcp/9100/p2p/QmbWC2TKXDWnYB1picmYwAMRUz7ACXLXDWyLibjHnaRyoN", + "dataMarketAddress": "0xf46D4Dd56868371C0AF6Fe8DB1bD8F252B34b685", + "environment": "staging" + } +] diff --git a/server_autofill.sh b/server_autofill.sh index 5a716a2..9376993 100755 --- a/server_autofill.sh +++ b/server_autofill.sh @@ -5,22 +5,15 @@ set -e echo 'populating server settings from environment values...'; export LOCAL_COLLECTOR_PORT="${LOCAL_COLLECTOR_PORT:-50051}" -if [ -z "$CLIENT_RENDEZVOUS_POINT" ]; then - echo "CLIENT_RENDEZVOUS_POINT not found, please set this in your .env!"; - exit 1; -fi -if [ -z "$RELAYER_RENDEZVOUS_POINT" ]; then - echo "RELAYER_RENDEZVOUS_POINT not found, please set this in your .env!"; - exit 1; -fi -if [ -z "$SEQUENCER_ID" ]; then - echo "SEQUENCER_ID not found, please set this in your .env!"; - exit 1; -fi if [ -z "$LOCAL_COLLECTOR_PORT" ]; then echo "LOCAL_COLLECTOR_PORT not found, please set this in your .env!"; exit 1; fi +if [ -z "$DATA_MARKET_CONTRACT" ]; then + echo "DATA_MARKET_CONTRACT not found, please set this in your .env!"; + exit 1; +fi + cd config # Template to actual settings.json manipulation @@ -37,13 +30,13 @@ fi export RELAYER_PRIVATE_KEY # Replace placeholders in settings.json with actual values from environment variables -sed -i'.backup' -e "s#SEQUENCER_ID#$SEQUENCER_ID#" \ - -e "s#RELAYER_RENDEZVOUS_POINT#$RELAYER_RENDEZVOUS_POINT#" \ - -e "s#CLIENT_RENDEZVOUS_POINT#$CLIENT_RENDEZVOUS_POINT#" \ - -e "s#POWERLOOM_REPORTING_URL#$POWERLOOM_REPORTING_URL#" \ +sed -i'.backup' -e "s#POWERLOOM_REPORTING_URL#$POWERLOOM_REPORTING_URL#" \ -e "s#SIGNER_ACCOUNT_ADDRESS#$SIGNER_ACCOUNT_ADDRESS#" \ -e "s#LOCAL_COLLECTOR_PORT#$LOCAL_COLLECTOR_PORT#" \ - -e "s#RELAYER_PRIVATE_KEY#$RELAYER_PRIVATE_KEY#" settings.json + -e "s#RELAYER_PRIVATE_KEY#$RELAYER_PRIVATE_KEY#" settings.json \ + -e "s#SEQUENCER_MULTIADDR#$SEQUENCER_MULTIADDR#" \ + -e "s#TRUSTED_RELAYERS_LIST_URL#$TRUSTED_RELAYERS_LIST_URL#" settings.json \ + -e "s#DATA_MARKET_CONTRACT#$DATA_MARKET_CONTRACT#" settings.json # Cleanup backup file rm settings.json.backup