diff --git a/codex/p2p.go b/codex/p2p.go new file mode 100644 index 0000000..6d1561f --- /dev/null +++ b/codex/p2p.go @@ -0,0 +1,44 @@ +package codex + +/* + #include "bridge.h" + #include + + static int cGoCodexConnect(void* codexCtx, char* peerId, const char** peerAddresses, uintptr_t peerAddressesSize, void* resp) { + return codex_connect(codexCtx, peerId, peerAddresses, peerAddressesSize, (CodexCallback) callback, resp); + } +*/ +import "C" +import ( + "log" + "unsafe" +) + +func (node CodexNode) Connect(peerId string, peerAddresses []string) error { + bridge := newBridgeCtx() + defer bridge.free() + + var cPeerId = C.CString(peerId) + defer C.free(unsafe.Pointer(cPeerId)) + + if len(peerAddresses) > 0 { + var cAddresses = make([]*C.char, len(peerAddresses)) + for i, addr := range peerAddresses { + cAddresses[i] = C.CString(addr) + defer C.free(unsafe.Pointer(cAddresses[i])) + } + + log.Println("peerAddresses", cAddresses) + + if C.cGoCodexConnect(node.ctx, cPeerId, &cAddresses[0], C.uintptr_t(len(peerAddresses)), bridge.resp) != C.RET_OK { + return bridge.callError("cGoCodexConnect") + } + } else { + if C.cGoCodexConnect(node.ctx, cPeerId, nil, 0, bridge.resp) != C.RET_OK { + return bridge.callError("cGoCodexConnect") + } + } + + _, err := bridge.wait() + return err +} diff --git a/codex/p2p_test.go b/codex/p2p_test.go new file mode 100644 index 0000000..7d40b77 --- /dev/null +++ b/codex/p2p_test.go @@ -0,0 +1,165 @@ +package codex + +import ( + "log" + "testing" +) + +func TestConnectWithAddress(t *testing.T) { + var node1, node2 *CodexNode + var err error + + t.Cleanup(func() { + if node1 != nil { + if err := node1.Stop(); err != nil { + t.Logf("cleanup codex1: %v", err) + } + + if err := node1.Destroy(); err != nil { + t.Logf("cleanup codex1: %v", err) + } + } + + if node2 != nil { + if err := node2.Stop(); err != nil { + t.Logf("cleanup codex2: %v", err) + } + + if err := node2.Destroy(); err != nil { + t.Logf("cleanup codex2: %v", err) + } + } + }) + + node1, err = CodexNew(CodexConfig{ + DataDir: t.TempDir(), + LogFormat: LogFormatNoColors, + MetricsEnabled: false, + DiscoveryPort: 8090, + }) + if err != nil { + t.Fatalf("Failed to create codex1: %v", err) + } + + if err := node1.Start(); err != nil { + t.Fatalf("Failed to start codex1: %v", err) + } + + node2, err = CodexNew(CodexConfig{ + DataDir: t.TempDir(), + LogFormat: LogFormatNoColors, + MetricsEnabled: false, + DiscoveryPort: 8091, + }) + if err != nil { + t.Fatalf("Failed to create codex2: %v", err) + } + + if err := node2.Start(); err != nil { + t.Fatalf("Failed to start codex2: %v", err) + } + + info2, err := node2.Debug() + if err != nil { + t.Fatal(err) + } + + if err := node1.Connect(info2.ID, info2.Addrs); err != nil { + t.Fatalf("connect failed: %v", err) + } +} + +func TestCodexWithPeerId(t *testing.T) { + var bootstrap, node1, node2 *CodexNode + var err error + + t.Cleanup(func() { + if bootstrap != nil { + if err := bootstrap.Stop(); err != nil { + t.Logf("cleanup bootstrap: %v", err) + } + + if err := bootstrap.Destroy(); err != nil { + t.Logf("cleanup bootstrap: %v", err) + } + } + if node1 != nil { + if err := node1.Stop(); err != nil { + t.Logf("cleanup node1: %v", err) + } + + if err := node1.Destroy(); err != nil { + t.Logf("cleanup node1: %v", err) + } + } + if node2 != nil { + if err := node2.Stop(); err != nil { + t.Logf("cleanup node2: %v", err) + } + + if err := node2.Destroy(); err != nil { + t.Logf("cleanup node2: %v", err) + } + } + }) + + bootstrap, err = CodexNew(CodexConfig{ + DataDir: t.TempDir(), + LogFormat: LogFormatNoColors, + MetricsEnabled: false, + DiscoveryPort: 8092, + }) + if err != nil { + t.Fatalf("Failed to create bootstrap: %v", err) + } + + if err := bootstrap.Start(); err != nil { + t.Fatalf("Failed to start bootstrap: %v", err) + } + + spr, err := bootstrap.Spr() + if err != nil { + t.Fatalf("Failed to get bootstrap spr: %v", err) + } + + bootstrapNodes := []string{spr} + + node1, err = CodexNew(CodexConfig{ + DataDir: t.TempDir(), + LogFormat: LogFormatNoColors, + MetricsEnabled: false, + DiscoveryPort: 8090, + BootstrapNodes: bootstrapNodes, + }) + if err != nil { + t.Fatalf("Failed to create codex: %v", err) + } + + if err := node1.Start(); err != nil { + t.Fatalf("Failed to start codex: %v", err) + } + + node2, err = CodexNew(CodexConfig{ + DataDir: t.TempDir(), + LogFormat: LogFormatNoColors, + MetricsEnabled: false, + DiscoveryPort: 8091, + BootstrapNodes: bootstrapNodes, + }) + if err != nil { + t.Fatalf("Failed to create codex2: %v", err) + } + + if err := node2.Start(); err != nil { + t.Fatalf("Failed to start codex2: %v", err) + } + + peerId, err := node2.PeerId() + if err != nil { + t.Fatal(err) + } + + if err := node1.Connect(peerId, []string{}); err != nil { + log.Println(err) + } +}