Compare commits
1 commit
main
...
stim-bundl
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c0775d9d8b |
4 changed files with 78 additions and 37 deletions
|
|
@ -1,5 +1,8 @@
|
|||
package node
|
||||
|
||||
// pkg/node/dispatcher.go
|
||||
|
||||
/*
|
||||
func (n *NodeManager) DispatchUEPS(pkt *ueps.ParsedPacket) error {
|
||||
// 1. The "Threat" Circuit Breaker (L5 Guard)
|
||||
if pkt.Header.ThreatScore > 50000 {
|
||||
|
|
@ -32,3 +35,4 @@ func (n *NodeManager) DispatchUEPS(pkt *ueps.ParsedPacket) error {
|
|||
return fmt.Errorf("unknown intent ID: 0x%X", pkt.Header.IntentID)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -706,23 +706,3 @@ func (r *PeerRegistry) load() error {
|
|||
}
|
||||
|
||||
// Example usage inside a connection handler
|
||||
func (n *NodeManager) SendEthicalPacket(peerID string, intent uint8, data []byte) error {
|
||||
// 1. Get the shared secret for this specific peer (derived from ECDH)
|
||||
secret, err := n.DeriveSharedSecret(peerID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 2. Construct the UEPS frame
|
||||
// Intent 0x20 = e.g., "Distributed Compute"
|
||||
pkt := ueps.NewBuilder(intent, data)
|
||||
|
||||
// 3. Seal it
|
||||
wireBytes, err := pkt.MarshalAndSign(secret)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 4. Send wireBytes over your TCP connection...
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,14 @@
|
|||
package node
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/Snider/Mining/pkg/logging"
|
||||
"github.com/adrg/xdg"
|
||||
)
|
||||
|
||||
// MinerManager interface for the mining package integration.
|
||||
|
|
@ -76,7 +79,7 @@ func (w *Worker) HandleMessage(conn *PeerConnection, msg *Message) {
|
|||
case MsgGetLogs:
|
||||
response, err = w.handleGetLogs(msg)
|
||||
case MsgDeploy:
|
||||
response, err = w.handleDeploy(msg)
|
||||
response, err = w.handleDeploy(conn, msg)
|
||||
default:
|
||||
// Unknown message type - ignore or send error
|
||||
return
|
||||
|
|
@ -291,24 +294,42 @@ func (w *Worker) handleGetLogs(msg *Message) (*Message, error) {
|
|||
}
|
||||
|
||||
// handleDeploy handles deployment of profiles or miner bundles.
|
||||
func (w *Worker) handleDeploy(msg *Message) (*Message, error) {
|
||||
func (w *Worker) handleDeploy(conn *PeerConnection, msg *Message) (*Message, error) {
|
||||
var payload DeployPayload
|
||||
if err := msg.ParsePayload(&payload); err != nil {
|
||||
return nil, fmt.Errorf("invalid deploy payload: %w", err)
|
||||
}
|
||||
|
||||
// TODO: Implement STIM bundle decryption and installation
|
||||
// For now, just handle raw profile JSON
|
||||
switch payload.BundleType {
|
||||
case "profile":
|
||||
// Reconstruct Bundle object from payload
|
||||
bundle := &Bundle{
|
||||
Type: BundleType(payload.BundleType),
|
||||
Name: payload.Name,
|
||||
Data: payload.Data,
|
||||
Checksum: payload.Checksum,
|
||||
}
|
||||
|
||||
// Use shared secret as password (base64 encoded)
|
||||
password := ""
|
||||
if conn != nil && len(conn.SharedSecret) > 0 {
|
||||
password = base64.StdEncoding.EncodeToString(conn.SharedSecret)
|
||||
}
|
||||
|
||||
switch bundle.Type {
|
||||
case BundleProfile:
|
||||
if w.profileManager == nil {
|
||||
return nil, fmt.Errorf("profile manager not configured")
|
||||
}
|
||||
|
||||
// Decode the profile from the data
|
||||
// Decrypt and extract profile data
|
||||
profileData, err := ExtractProfileBundle(bundle, password)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to extract profile bundle: %w", err)
|
||||
}
|
||||
|
||||
// Unmarshal into interface{} to pass to ProfileManager
|
||||
var profile interface{}
|
||||
if err := json.Unmarshal(payload.Data, &profile); err != nil {
|
||||
return nil, fmt.Errorf("invalid profile data: %w", err)
|
||||
if err := json.Unmarshal(profileData, &profile); err != nil {
|
||||
return nil, fmt.Errorf("invalid profile data JSON: %w", err)
|
||||
}
|
||||
|
||||
if err := w.profileManager.SaveProfile(profile); err != nil {
|
||||
|
|
@ -326,13 +347,49 @@ func (w *Worker) handleDeploy(msg *Message) (*Message, error) {
|
|||
}
|
||||
return msg.Reply(MsgDeployAck, ack)
|
||||
|
||||
case "miner":
|
||||
// TODO: Implement miner binary deployment via TIM bundles
|
||||
return nil, fmt.Errorf("miner bundle deployment not yet implemented")
|
||||
case BundleMiner, BundleFull:
|
||||
// Determine installation directory
|
||||
// We use xdg.DataHome/lethean-desktop/miners/<bundle_name>
|
||||
minersDir := filepath.Join(xdg.DataHome, "lethean-desktop", "miners")
|
||||
installDir := filepath.Join(minersDir, payload.Name)
|
||||
|
||||
case "full":
|
||||
// TODO: Implement full deployment (miner + profiles)
|
||||
return nil, fmt.Errorf("full bundle deployment not yet implemented")
|
||||
logging.Info("deploying miner bundle", logging.Fields{
|
||||
"name": payload.Name,
|
||||
"path": installDir,
|
||||
"type": payload.BundleType,
|
||||
})
|
||||
|
||||
// Extract miner bundle
|
||||
minerPath, profileData, err := ExtractMinerBundle(bundle, password, installDir)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to extract miner bundle: %w", err)
|
||||
}
|
||||
|
||||
// If the bundle contained a profile config, save it
|
||||
if len(profileData) > 0 && w.profileManager != nil {
|
||||
var profile interface{}
|
||||
if err := json.Unmarshal(profileData, &profile); err != nil {
|
||||
logging.Warn("failed to parse profile from miner bundle", logging.Fields{"error": err})
|
||||
} else {
|
||||
if err := w.profileManager.SaveProfile(profile); err != nil {
|
||||
logging.Warn("failed to save profile from miner bundle", logging.Fields{"error": err})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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,
|
||||
})
|
||||
|
||||
return msg.Reply(MsgDeployAck, ack)
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown bundle type: %s", payload.BundleType)
|
||||
|
|
|
|||
|
|
@ -372,7 +372,7 @@ func TestWorker_HandleDeploy_Profile(t *testing.T) {
|
|||
}
|
||||
|
||||
// Without profile manager, should return error
|
||||
_, err = worker.handleDeploy(msg)
|
||||
_, err = worker.handleDeploy(nil, msg)
|
||||
if err == nil {
|
||||
t.Error("expected error when profile manager is nil")
|
||||
}
|
||||
|
|
@ -413,7 +413,7 @@ func TestWorker_HandleDeploy_UnknownType(t *testing.T) {
|
|||
t.Fatalf("failed to create deploy message: %v", err)
|
||||
}
|
||||
|
||||
_, err = worker.handleDeploy(msg)
|
||||
_, err = worker.handleDeploy(nil, msg)
|
||||
if err == nil {
|
||||
t.Error("expected error for unknown bundle type")
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue