Add peer debug

This commit is contained in:
Arnaud 2025-09-17 14:37:34 +02:00 committed by Eric
parent 3f2c7b776e
commit f96f08943c
No known key found for this signature in database
5 changed files with 125 additions and 9 deletions

View File

@ -104,6 +104,10 @@ package main
return codex_connect(codexCtx, peerId, peerAddresses, peerAddressesSize, (CodexCallback) callback, resp);
}
static int cGoCodexPeerDebug(void* codexCtx, char* peerId, void* resp) {
return codex_peer_debug(codexCtx, peerId, (CodexCallback) callback, resp);
}
static int cGoCodexStart(void* codexCtx, void* resp) {
return codex_start(codexCtx, (CodexCallback) callback, resp);
}
@ -199,6 +203,15 @@ type CodexConfig struct {
LogFile string `json:"log-file,omitempty"`
}
type RestPeerRecord struct {
PeerId string `json:"peerId"`
SeqNo int `json:"seqNo"`
Addresses []string `json:"addresses,omitempty"`
}
// peerId* {.serialize.}: PeerId
// seqNo* {.serialize.}: uint64
// addresses* {.serialize.}: seq[AddressInfo]
type RestNode struct {
NodeId string `json:"nodeId"`
PeerId string `json:"peerId"`
@ -434,20 +447,49 @@ func (self *CodexNode) CodexConnect(peerId string, peerAddresses []string) error
var cPeerId = C.CString(peerId)
defer C.free(unsafe.Pointer(cPeerId))
var cAddresses = make([]*C.char, len(peerAddresses))
for i, addr := range peerAddresses {
cAddresses[i] = C.CString(addr)
defer C.free(unsafe.Pointer(cAddresses[i]))
}
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]))
}
if C.cGoCodexConnect(self.ctx, cPeerId, &cAddresses[0], C.uintptr_t(len(peerAddresses)), bridge.resp) != C.RET_OK {
return bridge.CallError("cGoCodexConnect")
if C.cGoCodexConnect(self.ctx, cPeerId, &cAddresses[0], C.uintptr_t(len(peerAddresses)), bridge.resp) != C.RET_OK {
return bridge.CallError("cGoCodexConnect")
}
} else {
if C.cGoCodexConnect(self.ctx, cPeerId, nil, 0, bridge.resp) != C.RET_OK {
return bridge.CallError("cGoCodexConnect")
}
}
_, err := bridge.wait()
return err
}
func (self *CodexNode) CodexPeerDebug(peerId string) (RestPeerRecord, error) {
var record RestPeerRecord
bridge := newBridgeCtx()
defer bridge.free()
var cPeerId = C.CString(peerId)
defer C.free(unsafe.Pointer(cPeerId))
if C.cGoCodexPeerDebug(self.ctx, cPeerId, bridge.resp) != C.RET_OK {
return record, bridge.CallError("cGoCodexPeerDebug")
}
value, err := bridge.wait()
if err != nil {
return record, err
}
err = json.Unmarshal([]byte(value), &record)
return record, err
}
func (self *CodexNode) CodexStart() error {
bridge := newBridgeCtx()
defer bridge.free()
@ -593,6 +635,20 @@ func main() {
log.Println("Codex Log Level set to TRACE")
// err = node.CodexConnect(peerId, []string{})
// if err != nil {
// log.Fatal("Error happened:", err.Error())
// }
// log.Println("Codex connecting to self...")
// val, err := node.CodexPeerDebug(peerId)
// if err != nil {
// log.Fatal("Error happened:", err.Error())
// }
// log.Println("Codex debugging self...", val)
// Wait for a SIGINT or SIGTERM signal
ch := make(chan os.Signal, 1)
signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)

View File

@ -4,6 +4,7 @@ import std/[options]
import chronos
import chronicles
import codexdht/discv5/spr
import ../../alloc
import ../../../codex/conf
import ../../../codex/rest/json
import ../../../codex/node
@ -12,16 +13,22 @@ from ../../../codex/codex import CodexServer, node
type NodeDebugMsgType* = enum
DEBUG
PEER
type NodeDebugRequest* = object
operation: NodeDebugMsgType
peerId: cstring
proc createShared*(T: type NodeDebugRequest, op: NodeDebugMsgType): ptr type T =
proc createShared*(
T: type NodeDebugRequest, op: NodeDebugMsgType, peerId: cstring = ""
): ptr type T =
var ret = createShared(T)
ret[].operation = op
ret[].peerId = peerId.alloc()
return ret
proc destroyShared(self: ptr NodeDebugRequest) =
deallocShared(self[].peerId)
deallocShared(self)
proc getDebug(
@ -42,6 +49,30 @@ proc getDebug(
return ok($json)
proc getPeer(
codex: ptr CodexServer, peerId: cstring
): Future[Result[string, string]] {.async: (raises: []).} =
when codex_enable_api_debug_peers:
let node = codex[].node
let res = PeerId.init($peerId)
if res.isErr:
return err("Invalid peer ID " & $peerId & ": " & $res.error())
let id = res.get()
try:
let peerRecord = await node.findPeer(id)
if peerRecord.isNone:
return err("Peer not found")
return ok($ %RestPeerRecord.init(peerRecord.get()))
except CancelledError:
return err("Operation cancelled")
except CatchableError as e:
return err("Error when finding peer: " & e.msg)
else:
return err("Peer debug API is disabled")
proc process*(
self: ptr NodeDebugRequest, codex: ptr CodexServer
): Future[Result[string, string]] {.async: (raises: []).} =
@ -55,5 +86,11 @@ proc process*(
error "DEBUG failed", error = res.error
return err($res.error)
return res
of NodeDebugMsgType.PEER:
let res = (await getPeer(codex, self.peerId))
if res.isErr:
error "PEER failed", error = res.error
return err($res.error)
return res
return ok("")

View File

@ -3,8 +3,8 @@
import std/[options]
import chronos
import chronicles
import ../../alloc
import libp2p
import ../../alloc
import ../../../codex/node
from ../../../codex/codex import CodexServer, node

View File

@ -74,6 +74,12 @@ int codex_connect(
CodexCallback callback,
void* userData);
int codex_peer_debug(
void* ctx,
const char* peerId,
CodexCallback callback,
void* userData);
int codex_start(void* ctx,
CodexCallback callback,
void* userData);

View File

@ -248,6 +248,23 @@ proc codex_connect(
return RET_OK
proc codex_peer_debug(
ctx: ptr CodexContext, peerId: cstring, callback: CodexCallback, userData: pointer
): cint {.dynlib, exportc.} =
initializeLibrary()
checkLibcodexParams(ctx, callback, userData)
let reqContent = NodeDebugRequest.createShared(NodeDebugMsgType.PEER, peerId = peerId)
codex_context.sendRequestToCodexThread(
ctx, RequestType.DEBUG, reqContent, callback, userData
).isOkOr:
let msg = "libcodex error: " & $error
callback(RET_ERR, unsafeAddr msg[0], cast[csize_t](len(msg)), userData)
return RET_ERR
return RET_OK
proc codex_destroy(
ctx: ptr CodexContext, callback: CodexCallback, userData: pointer
): cint {.dynlib, exportc.} =