package main import ( "context" "encoding/json" "flag" "fmt" "net" "time" "github.com/libp2p/go-libp2p" "github.com/libp2p/go-libp2p/core/crypto" "github.com/libp2p/go-libp2p/core/peer" "github.com/multiformats/go-multiaddr" ) func main() { runServer := flag.Bool("run-server", false, "Should run as server") serverAddr := flag.String("server-address", "", "Server address") transport := flag.String("transport", "tcp", "Transport to use") uploadBytes := flag.Uint64("upload-bytes", 0, "Upload bytes") downloadBytes := flag.Uint64("download-bytes", 0, "Download bytes") flag.Parse() host, port, err := net.SplitHostPort(*serverAddr) if err != nil { log.Fatal(err) } tcpMultiAddrStr := fmt.Sprintf("/ip4/%s/tcp/%s", host, port) quicMultiAddrStr := fmt.Sprintf("/ip4/%s/udp/%s/quic-v1", host, port) var opts []libp2p.Option if *runServer { opts = append(opts, libp2p.ListenAddrStrings(tcpMultiAddrStr, quicMultiAddrStr)) // Generate stable fake identity. // // Using a stable identity (i.e. peer ID) allows the client to // connect to the server without a prior exchange of the // server's peer ID. priv, _, err := crypto.GenerateEd25519Key(&simpleReader{seed: 0}) if err != nil { log.Fatalf("failed to generate key: %s", err) } opts = append(opts, libp2p.Identity(priv)) } h, err := libp2p.New(opts...) if err != nil { log.Fatalf("failed to instantiate libp2p: %s", err) } perf := NewPerfService(h) if *runServer { for _, a := range h.Addrs() { fmt.Println(a.Encapsulate(multiaddr.StringCast("/p2p/" + h.ID().String()))) } select {} // run forever, exit on interrupt } var multiAddrStr string switch *transport { case "tcp": multiAddrStr = tcpMultiAddrStr case "quic-v1": multiAddrStr = quicMultiAddrStr default: fmt.Println("Invalid transport. Accepted values: 'tcp' or 'quic-v1'") return } // Peer ID corresponds to the above fake identity. multiAddrStr = multiAddrStr + "/p2p/12D3KooWDpJ7As7BWAwRMfu1VU2WCqNjvq387JEYKDBj4kx6nXTN" serverInfo, err := peer.AddrInfoFromString(multiAddrStr) if err != nil { log.Fatalf("failed to build address info: %s", err) } start := time.Now() err = h.Connect(context.Background(), *serverInfo) if err != nil { log.Fatalf("failed to dial peer: %s", err) } err = perf.RunPerf(context.Background(), serverInfo.ID, uint64(*uploadBytes), uint64(*downloadBytes)) if err != nil { log.Fatalf("failed to execute perf: %s", err) } jsonB, err := json.Marshal(Result{ TimeSeconds: time.Since(start).Seconds(), UploadBytes: *uploadBytes, DownloadBytes: *downloadBytes, Type: "final", }) if err != nil { log.Fatalf("failed to marshal perf result: %s", err) } fmt.Println(string(jsonB)) } type Result struct { Type string `json:"type"` TimeSeconds float64 `json:"timeSeconds"` UploadBytes uint64 `json:"uploadBytes"` DownloadBytes uint64 `json:"downloadBytes"` } type simpleReader struct { seed uint8 } func (r *simpleReader) Read(p []byte) (n int, err error) { for i := range p { p[i] = r.seed } return len(p), nil }