refactor(node): trim redundant AX comments
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
e5953e4b86
commit
849a716360
8 changed files with 0 additions and 76 deletions
|
|
@ -15,14 +15,12 @@ var bufferPool = sync.Pool{
|
|||
},
|
||||
}
|
||||
|
||||
// getBuffer retrieves a buffer from the pool.
|
||||
func getBuffer() *bytes.Buffer {
|
||||
buffer := bufferPool.Get().(*bytes.Buffer)
|
||||
buffer.Reset()
|
||||
return buffer
|
||||
}
|
||||
|
||||
// putBuffer returns a buffer to the pool.
|
||||
func putBuffer(buffer *bytes.Buffer) {
|
||||
// Don't pool buffers that grew too large (>64KB)
|
||||
if buffer.Cap() <= 65536 {
|
||||
|
|
|
|||
|
|
@ -46,20 +46,17 @@ type BundleManifest struct {
|
|||
|
||||
// bundle, err := CreateProfileBundle(profileJSON, "xmrig-default", "password")
|
||||
func CreateProfileBundle(profileJSON []byte, name string, password string) (*Bundle, error) {
|
||||
// Create a TIM with just the profile config
|
||||
timBundle, err := tim.New()
|
||||
if err != nil {
|
||||
return nil, core.E("CreateProfileBundle", "failed to create TIM", err)
|
||||
}
|
||||
timBundle.Config = profileJSON
|
||||
|
||||
// Encrypt to STIM format
|
||||
stimData, err := timBundle.ToSigil(password)
|
||||
if err != nil {
|
||||
return nil, core.E("CreateProfileBundle", "failed to encrypt bundle", err)
|
||||
}
|
||||
|
||||
// Calculate checksum
|
||||
checksum := calculateChecksum(stimData)
|
||||
|
||||
return &Bundle{
|
||||
|
|
@ -84,14 +81,12 @@ func CreateProfileBundleUnencrypted(profileJSON []byte, name string) (*Bundle, e
|
|||
|
||||
// bundle, err := CreateMinerBundle("/srv/miners/xmrig", profileJSON, "xmrig", "password")
|
||||
func CreateMinerBundle(minerPath string, profileJSON []byte, name string, password string) (*Bundle, error) {
|
||||
// Read miner binary
|
||||
minerContent, err := filesystemRead(minerPath)
|
||||
if err != nil {
|
||||
return nil, core.E("CreateMinerBundle", "failed to read miner binary", err)
|
||||
}
|
||||
minerData := []byte(minerContent)
|
||||
|
||||
// Create a tarball with the miner binary
|
||||
tarData, err := createTarball(map[string][]byte{
|
||||
core.PathBase(minerPath): minerData,
|
||||
})
|
||||
|
|
@ -99,24 +94,20 @@ func CreateMinerBundle(minerPath string, profileJSON []byte, name string, passwo
|
|||
return nil, core.E("CreateMinerBundle", "failed to create tarball", err)
|
||||
}
|
||||
|
||||
// Create DataNode from tarball
|
||||
dataNode, err := datanode.FromTar(tarData)
|
||||
if err != nil {
|
||||
return nil, core.E("CreateMinerBundle", "failed to create datanode", err)
|
||||
}
|
||||
|
||||
// Create TIM from DataNode
|
||||
timBundle, err := tim.FromDataNode(dataNode)
|
||||
if err != nil {
|
||||
return nil, core.E("CreateMinerBundle", "failed to create TIM", err)
|
||||
}
|
||||
|
||||
// Set profile as config if provided
|
||||
if profileJSON != nil {
|
||||
timBundle.Config = profileJSON
|
||||
}
|
||||
|
||||
// Encrypt to STIM format
|
||||
stimData, err := timBundle.ToSigil(password)
|
||||
if err != nil {
|
||||
return nil, core.E("CreateMinerBundle", "failed to encrypt bundle", err)
|
||||
|
|
@ -134,17 +125,14 @@ func CreateMinerBundle(minerPath string, profileJSON []byte, name string, passwo
|
|||
|
||||
// profileJSON, err := ExtractProfileBundle(bundle, "password")
|
||||
func ExtractProfileBundle(bundle *Bundle, password string) ([]byte, error) {
|
||||
// Verify checksum first
|
||||
if calculateChecksum(bundle.Data) != bundle.Checksum {
|
||||
return nil, core.E("ExtractProfileBundle", "checksum mismatch - bundle may be corrupted", nil)
|
||||
}
|
||||
|
||||
// If it's unencrypted JSON, just return it
|
||||
if isJSON(bundle.Data) {
|
||||
return bundle.Data, nil
|
||||
}
|
||||
|
||||
// Decrypt STIM format
|
||||
timBundle, err := tim.FromSigil(bundle.Data, password)
|
||||
if err != nil {
|
||||
return nil, core.E("ExtractProfileBundle", "failed to decrypt bundle", err)
|
||||
|
|
@ -155,24 +143,20 @@ func ExtractProfileBundle(bundle *Bundle, password string) ([]byte, error) {
|
|||
|
||||
// minerPath, profileJSON, err := ExtractMinerBundle(bundle, "password", "/srv/miners")
|
||||
func ExtractMinerBundle(bundle *Bundle, password string, destDir string) (string, []byte, error) {
|
||||
// Verify checksum
|
||||
if calculateChecksum(bundle.Data) != bundle.Checksum {
|
||||
return "", nil, core.E("ExtractMinerBundle", "checksum mismatch - bundle may be corrupted", nil)
|
||||
}
|
||||
|
||||
// Decrypt STIM format
|
||||
timBundle, err := tim.FromSigil(bundle.Data, password)
|
||||
if err != nil {
|
||||
return "", nil, core.E("ExtractMinerBundle", "failed to decrypt bundle", err)
|
||||
}
|
||||
|
||||
// Convert rootfs to tarball and extract
|
||||
tarData, err := timBundle.RootFS.ToTar()
|
||||
if err != nil {
|
||||
return "", nil, core.E("ExtractMinerBundle", "failed to convert rootfs to tar", err)
|
||||
}
|
||||
|
||||
// Extract tarball to destination
|
||||
minerPath, err := extractTarball(tarData, destDir)
|
||||
if err != nil {
|
||||
return "", nil, core.E("ExtractMinerBundle", "failed to extract tarball", err)
|
||||
|
|
@ -186,13 +170,11 @@ func VerifyBundle(bundle *Bundle) bool {
|
|||
return calculateChecksum(bundle.Data) == bundle.Checksum
|
||||
}
|
||||
|
||||
// calculateChecksum computes SHA-256 checksum of data.
|
||||
func calculateChecksum(data []byte) string {
|
||||
hash := sha256.Sum256(data)
|
||||
return hex.EncodeToString(hash[:])
|
||||
}
|
||||
|
||||
// isJSON checks if data starts with JSON characters.
|
||||
func isJSON(data []byte) bool {
|
||||
if len(data) == 0 {
|
||||
return false
|
||||
|
|
@ -201,7 +183,6 @@ func isJSON(data []byte) bool {
|
|||
return data[0] == '{' || data[0] == '['
|
||||
}
|
||||
|
||||
// createTarball creates a tar archive from a map of filename -> content.
|
||||
func createTarball(files map[string][]byte) ([]byte, error) {
|
||||
var buf bytes.Buffer
|
||||
tarWriter := tar.NewWriter(&buf)
|
||||
|
|
@ -248,7 +229,6 @@ func createTarball(files map[string][]byte) ([]byte, error) {
|
|||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
// extractTarball extracts a tar archive to a directory, returns first executable found.
|
||||
func extractTarball(tarData []byte, destDir string) (string, error) {
|
||||
// Ensure destDir is an absolute, clean path for security checks
|
||||
absDestDir := destDir
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ func NewController(nodeManager *NodeManager, peerRegistry *PeerRegistry, transpo
|
|||
return c
|
||||
}
|
||||
|
||||
// handleResponse processes incoming replies and routes them to the waiting request.
|
||||
func (c *Controller) handleResponse(_ *PeerConnection, message *Message) {
|
||||
if message.ReplyTo == "" {
|
||||
return // Not a response, let worker handle it
|
||||
|
|
@ -58,12 +57,6 @@ func (c *Controller) handleResponse(_ *PeerConnection, message *Message) {
|
|||
}
|
||||
}
|
||||
|
||||
// sendRequest registers a temporary response channel, sends message, and waits
|
||||
// for the matching reply or timeout.
|
||||
//
|
||||
// The response channel is intentionally never closed. Removing it from the
|
||||
// pending map is enough to stop future routing, and it avoids a late-response
|
||||
// close/send race after the caller has already timed out.
|
||||
func (c *Controller) sendRequest(peerID string, message *Message, timeout time.Duration) (*Message, error) {
|
||||
resolvedPeerID := peerID
|
||||
|
||||
|
|
@ -77,13 +70,10 @@ func (c *Controller) sendRequest(peerID string, message *Message, timeout time.D
|
|||
if err != nil {
|
||||
return nil, core.E("Controller.sendRequest", "failed to connect to peer", err)
|
||||
}
|
||||
// Use the real peer ID after handshake (it may have changed)
|
||||
resolvedPeerID = conn.Peer.ID
|
||||
// Update the message destination
|
||||
message.To = resolvedPeerID
|
||||
}
|
||||
|
||||
// Create response channel
|
||||
responseChannel := make(chan *Message, 1)
|
||||
|
||||
c.mutex.Lock()
|
||||
|
|
@ -98,12 +88,10 @@ func (c *Controller) sendRequest(peerID string, message *Message, timeout time.D
|
|||
c.mutex.Unlock()
|
||||
}()
|
||||
|
||||
// Send the message
|
||||
if err := c.transport.Send(resolvedPeerID, message); err != nil {
|
||||
return nil, core.E("Controller.sendRequest", "failed to send message", err)
|
||||
}
|
||||
|
||||
// Wait for response
|
||||
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||
defer cancel()
|
||||
|
||||
|
|
|
|||
|
|
@ -3,9 +3,7 @@ package node
|
|||
import core "dappco.re/go/core"
|
||||
|
||||
var (
|
||||
// err := ErrorIdentityNotInitialized
|
||||
ErrorIdentityNotInitialized = core.E("node", "node identity not initialized", nil)
|
||||
|
||||
// err := ErrorMinerManagerNotConfigured
|
||||
ErrorMinerManagerNotConfigured = core.E("node", "miner manager not configured", nil)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -199,15 +199,12 @@ func (n *NodeManager) DeriveSharedSecret(peerPubKeyBase64 string) ([]byte, error
|
|||
return hash[:], nil
|
||||
}
|
||||
|
||||
// savePrivateKey saves the private key to disk with restricted permissions.
|
||||
func (n *NodeManager) savePrivateKey() error {
|
||||
// Ensure directory exists
|
||||
dir := core.PathDir(n.keyPath)
|
||||
if err := filesystemEnsureDir(dir); err != nil {
|
||||
return core.E("NodeManager.savePrivateKey", "failed to create key directory", err)
|
||||
}
|
||||
|
||||
// Write private key
|
||||
if err := filesystemWrite(n.keyPath, string(n.privateKey)); err != nil {
|
||||
return core.E("NodeManager.savePrivateKey", "failed to write private key", err)
|
||||
}
|
||||
|
|
@ -215,9 +212,7 @@ func (n *NodeManager) savePrivateKey() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// saveIdentity saves the public identity to the config file.
|
||||
func (n *NodeManager) saveIdentity() error {
|
||||
// Ensure directory exists
|
||||
dir := core.PathDir(n.configPath)
|
||||
if err := filesystemEnsureDir(dir); err != nil {
|
||||
return core.E("NodeManager.saveIdentity", "failed to create config directory", err)
|
||||
|
|
@ -236,9 +231,7 @@ func (n *NodeManager) saveIdentity() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// loadIdentity loads the node identity from disk.
|
||||
func (n *NodeManager) loadIdentity() error {
|
||||
// Load identity config
|
||||
content, err := filesystemRead(n.configPath)
|
||||
if err != nil {
|
||||
return core.E("NodeManager.loadIdentity", "failed to read identity", err)
|
||||
|
|
@ -250,14 +243,12 @@ func (n *NodeManager) loadIdentity() error {
|
|||
return core.E("NodeManager.loadIdentity", "failed to unmarshal identity", result.Value.(error))
|
||||
}
|
||||
|
||||
// Load private key
|
||||
keyContent, err := filesystemRead(n.keyPath)
|
||||
if err != nil {
|
||||
return core.E("NodeManager.loadIdentity", "failed to read private key", err)
|
||||
}
|
||||
privateKey := []byte(keyContent)
|
||||
|
||||
// Reconstruct keypair from private key
|
||||
keyPair, err := stmf.LoadKeyPair(privateKey)
|
||||
if err != nil {
|
||||
return core.E("NodeManager.loadIdentity", "failed to load keypair", err)
|
||||
|
|
|
|||
|
|
@ -79,7 +79,6 @@ func (connection *Connection) WriteResponse(commandID uint32, payload []byte, re
|
|||
return connection.writeFrame(&header, payload)
|
||||
}
|
||||
|
||||
// writeFrame serialises header + payload and writes them atomically.
|
||||
func (connection *Connection) writeFrame(header *Header, payload []byte) error {
|
||||
headerBytes := EncodeHeader(header)
|
||||
|
||||
|
|
@ -109,7 +108,6 @@ func (connection *Connection) ReadPacket() (Header, []byte, error) {
|
|||
return Header{}, nil, err
|
||||
}
|
||||
|
||||
// Read header.
|
||||
var headerBytes [HeaderSize]byte
|
||||
if _, err := io.ReadFull(connection.networkConnection, headerBytes[:]); err != nil {
|
||||
return Header{}, nil, err
|
||||
|
|
|
|||
|
|
@ -64,7 +64,6 @@ const (
|
|||
// peerNamePattern validates peer names: alphanumeric, hyphens, underscores, and spaces.
|
||||
var peerNamePattern = regexp.MustCompile(`^[a-zA-Z0-9][a-zA-Z0-9\-_ ]{0,62}[a-zA-Z0-9]$|^[a-zA-Z0-9]$`)
|
||||
|
||||
// safeKeyPrefix returns a truncated key for logging, handling short keys safely
|
||||
func safeKeyPrefix(key string) string {
|
||||
if len(key) >= 16 {
|
||||
return key[:16] + "..."
|
||||
|
|
@ -75,9 +74,6 @@ func safeKeyPrefix(key string) string {
|
|||
return key
|
||||
}
|
||||
|
||||
// validatePeerName checks if a peer name is valid.
|
||||
// Peer names must be 1-64 characters, start and end with alphanumeric,
|
||||
// and contain only alphanumeric, hyphens, underscores, and spaces.
|
||||
func validatePeerName(name string) error {
|
||||
if name == "" {
|
||||
return nil // Empty names are allowed (optional field)
|
||||
|
|
@ -347,7 +343,6 @@ func (r *PeerRegistry) GetPeer(id string) *Peer {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Return a copy
|
||||
peerCopy := *peer
|
||||
return &peerCopy
|
||||
}
|
||||
|
|
@ -508,7 +503,6 @@ func (r *PeerRegistry) GetPeersByScore() []*Peer {
|
|||
|
||||
peers := slices.Collect(maps.Values(r.peers))
|
||||
|
||||
// Sort by score descending
|
||||
slices.SortFunc(peers, func(a, b *Peer) int {
|
||||
if b.Score > a.Score {
|
||||
return 1
|
||||
|
|
|
|||
|
|
@ -111,7 +111,6 @@ func (w *Worker) HandleMessage(peerConnection *PeerConnection, message *Message)
|
|||
}
|
||||
}
|
||||
|
||||
// handlePing responds to ping requests.
|
||||
func (w *Worker) handlePing(message *Message) (*Message, error) {
|
||||
var ping PingPayload
|
||||
if err := message.ParsePayload(&ping); err != nil {
|
||||
|
|
@ -126,7 +125,6 @@ func (w *Worker) handlePing(message *Message) (*Message, error) {
|
|||
return message.Reply(MessagePong, pong)
|
||||
}
|
||||
|
||||
// handleStats responds with current miner statistics.
|
||||
func (w *Worker) handleStats(message *Message) (*Message, error) {
|
||||
identity := w.nodeManager.GetIdentity()
|
||||
if identity == nil {
|
||||
|
|
@ -148,8 +146,6 @@ func (w *Worker) handleStats(message *Message) (*Message, error) {
|
|||
continue
|
||||
}
|
||||
|
||||
// Convert to MinerStatsItem - this is a simplified conversion
|
||||
// The actual implementation would need to match the mining package's stats structure
|
||||
item := convertMinerStats(miner, minerStats)
|
||||
stats.Miners = append(stats.Miners, item)
|
||||
}
|
||||
|
|
@ -158,7 +154,6 @@ func (w *Worker) handleStats(message *Message) (*Message, error) {
|
|||
return message.Reply(MessageStats, stats)
|
||||
}
|
||||
|
||||
// convertMinerStats converts a running miner's raw stats map to the wire protocol format.
|
||||
func convertMinerStats(miner MinerInstance, rawStats any) MinerStatsItem {
|
||||
item := MinerStatsItem{
|
||||
Name: miner.GetName(),
|
||||
|
|
@ -189,7 +184,6 @@ func convertMinerStats(miner MinerInstance, rawStats any) MinerStatsItem {
|
|||
return item
|
||||
}
|
||||
|
||||
// handleStartMiner starts a miner with the given profile.
|
||||
func (w *Worker) handleStartMiner(message *Message) (*Message, error) {
|
||||
if w.minerManager == nil {
|
||||
return nil, ErrorMinerManagerNotConfigured
|
||||
|
|
@ -200,12 +194,10 @@ func (w *Worker) handleStartMiner(message *Message) (*Message, error) {
|
|||
return nil, core.E("Worker.handleStartMiner", "invalid start miner payload", err)
|
||||
}
|
||||
|
||||
// Validate miner type is provided
|
||||
if payload.MinerType == "" {
|
||||
return nil, core.E("Worker.handleStartMiner", "miner type is required", nil)
|
||||
}
|
||||
|
||||
// Get the config from the profile or use the override
|
||||
var config any
|
||||
if payload.Config != nil {
|
||||
config = payload.Config
|
||||
|
|
@ -219,7 +211,6 @@ func (w *Worker) handleStartMiner(message *Message) (*Message, error) {
|
|||
return nil, core.E("Worker.handleStartMiner", "no config provided and no profile manager configured", nil)
|
||||
}
|
||||
|
||||
// Start the miner
|
||||
miner, err := w.minerManager.StartMiner(payload.MinerType, config)
|
||||
if err != nil {
|
||||
ack := MinerAckPayload{
|
||||
|
|
@ -236,7 +227,6 @@ func (w *Worker) handleStartMiner(message *Message) (*Message, error) {
|
|||
return message.Reply(MessageMinerAck, ack)
|
||||
}
|
||||
|
||||
// handleStopMiner stops a running miner.
|
||||
func (w *Worker) handleStopMiner(message *Message) (*Message, error) {
|
||||
if w.minerManager == nil {
|
||||
return nil, ErrorMinerManagerNotConfigured
|
||||
|
|
@ -259,7 +249,6 @@ func (w *Worker) handleStopMiner(message *Message) (*Message, error) {
|
|||
return message.Reply(MessageMinerAck, ack)
|
||||
}
|
||||
|
||||
// handleLogs returns console logs from a miner.
|
||||
func (w *Worker) handleLogs(message *Message) (*Message, error) {
|
||||
if w.minerManager == nil {
|
||||
return nil, ErrorMinerManagerNotConfigured
|
||||
|
|
@ -270,7 +259,6 @@ func (w *Worker) handleLogs(message *Message) (*Message, error) {
|
|||
return nil, core.E("Worker.handleLogs", "invalid logs payload", err)
|
||||
}
|
||||
|
||||
// Validate and limit the Lines parameter to prevent resource exhaustion
|
||||
const maxLogLines = 10000
|
||||
if payload.Lines <= 0 || payload.Lines > maxLogLines {
|
||||
payload.Lines = maxLogLines
|
||||
|
|
@ -292,7 +280,6 @@ func (w *Worker) handleLogs(message *Message) (*Message, error) {
|
|||
return message.Reply(MessageLogs, logs)
|
||||
}
|
||||
|
||||
// handleDeploy handles deployment of profiles or miner bundles.
|
||||
func (w *Worker) handleDeploy(peerConnection *PeerConnection, message *Message) (*Message, error) {
|
||||
var payload DeployPayload
|
||||
if err := message.ParsePayload(&payload); err != nil {
|
||||
|
|
@ -319,13 +306,11 @@ func (w *Worker) handleDeploy(peerConnection *PeerConnection, message *Message)
|
|||
return nil, core.E("Worker.handleDeploy", "profile manager not configured", nil)
|
||||
}
|
||||
|
||||
// Decrypt and extract profile data
|
||||
profileData, err := ExtractProfileBundle(bundle, password)
|
||||
if err != nil {
|
||||
return nil, core.E("Worker.handleDeploy", "failed to extract profile bundle", err)
|
||||
}
|
||||
|
||||
// Unmarshal into interface{} to pass to ProfileManager
|
||||
var profile any
|
||||
if result := core.JSONUnmarshal(profileData, &profile); !result.OK {
|
||||
return nil, core.E("Worker.handleDeploy", "invalid profile data JSON", result.Value.(error))
|
||||
|
|
@ -347,8 +332,6 @@ func (w *Worker) handleDeploy(peerConnection *PeerConnection, message *Message)
|
|||
return message.Reply(MessageDeployAck, ack)
|
||||
|
||||
case BundleMiner, BundleFull:
|
||||
// Determine the installation directory under the configured deployment
|
||||
// root for lethean-desktop/miners/<bundle_name>.
|
||||
minersDir := core.JoinPath(w.deploymentDirectory(), "lethean-desktop", "miners")
|
||||
installDir := core.JoinPath(minersDir, payload.Name)
|
||||
|
||||
|
|
@ -358,13 +341,11 @@ func (w *Worker) handleDeploy(peerConnection *PeerConnection, message *Message)
|
|||
"type": payload.BundleType,
|
||||
})
|
||||
|
||||
// Extract miner bundle
|
||||
minerPath, profileData, err := ExtractMinerBundle(bundle, password, installDir)
|
||||
if err != nil {
|
||||
return nil, core.E("Worker.handleDeploy", "failed to extract miner bundle", err)
|
||||
}
|
||||
|
||||
// If the bundle contained a profile config, save it
|
||||
if len(profileData) > 0 && w.profileManager != nil {
|
||||
var profile any
|
||||
if result := core.JSONUnmarshal(profileData, &profile); !result.OK {
|
||||
|
|
@ -376,13 +357,11 @@ func (w *Worker) handleDeploy(peerConnection *PeerConnection, message *Message)
|
|||
}
|
||||
}
|
||||
|
||||
// Success response
|
||||
ack := DeployAckPayload{
|
||||
Success: true,
|
||||
Name: payload.Name,
|
||||
}
|
||||
|
||||
// Log the installation
|
||||
logging.Info("miner bundle installed successfully", logging.Fields{
|
||||
"name": payload.Name,
|
||||
"miner_path": minerPath,
|
||||
|
|
@ -395,12 +374,10 @@ func (w *Worker) handleDeploy(peerConnection *PeerConnection, message *Message)
|
|||
}
|
||||
}
|
||||
|
||||
// worker.RegisterOnTransport()
|
||||
func (w *Worker) RegisterOnTransport() {
|
||||
w.transport.OnMessage(w.HandleMessage)
|
||||
}
|
||||
|
||||
// deploymentDirectory resolves the active deployment directory.
|
||||
func (w *Worker) deploymentDirectory() string {
|
||||
if w.DeploymentDirectory != "" {
|
||||
return w.DeploymentDirectory
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue