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
|
// pkg/node/dispatcher.go
|
||||||
|
|
||||||
|
/*
|
||||||
func (n *NodeManager) DispatchUEPS(pkt *ueps.ParsedPacket) error {
|
func (n *NodeManager) DispatchUEPS(pkt *ueps.ParsedPacket) error {
|
||||||
// 1. The "Threat" Circuit Breaker (L5 Guard)
|
// 1. The "Threat" Circuit Breaker (L5 Guard)
|
||||||
if pkt.Header.ThreatScore > 50000 {
|
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)
|
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
|
// 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
|
package node
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Snider/Mining/pkg/logging"
|
"github.com/Snider/Mining/pkg/logging"
|
||||||
|
"github.com/adrg/xdg"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MinerManager interface for the mining package integration.
|
// MinerManager interface for the mining package integration.
|
||||||
|
|
@ -76,7 +79,7 @@ func (w *Worker) HandleMessage(conn *PeerConnection, msg *Message) {
|
||||||
case MsgGetLogs:
|
case MsgGetLogs:
|
||||||
response, err = w.handleGetLogs(msg)
|
response, err = w.handleGetLogs(msg)
|
||||||
case MsgDeploy:
|
case MsgDeploy:
|
||||||
response, err = w.handleDeploy(msg)
|
response, err = w.handleDeploy(conn, msg)
|
||||||
default:
|
default:
|
||||||
// Unknown message type - ignore or send error
|
// Unknown message type - ignore or send error
|
||||||
return
|
return
|
||||||
|
|
@ -291,24 +294,42 @@ func (w *Worker) handleGetLogs(msg *Message) (*Message, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleDeploy handles deployment of profiles or miner bundles.
|
// 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
|
var payload DeployPayload
|
||||||
if err := msg.ParsePayload(&payload); err != nil {
|
if err := msg.ParsePayload(&payload); err != nil {
|
||||||
return nil, fmt.Errorf("invalid deploy payload: %w", err)
|
return nil, fmt.Errorf("invalid deploy payload: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Implement STIM bundle decryption and installation
|
// Reconstruct Bundle object from payload
|
||||||
// For now, just handle raw profile JSON
|
bundle := &Bundle{
|
||||||
switch payload.BundleType {
|
Type: BundleType(payload.BundleType),
|
||||||
case "profile":
|
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 {
|
if w.profileManager == nil {
|
||||||
return nil, fmt.Errorf("profile manager not configured")
|
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{}
|
var profile interface{}
|
||||||
if err := json.Unmarshal(payload.Data, &profile); err != nil {
|
if err := json.Unmarshal(profileData, &profile); err != nil {
|
||||||
return nil, fmt.Errorf("invalid profile data: %w", err)
|
return nil, fmt.Errorf("invalid profile data JSON: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := w.profileManager.SaveProfile(profile); err != nil {
|
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)
|
return msg.Reply(MsgDeployAck, ack)
|
||||||
|
|
||||||
case "miner":
|
case BundleMiner, BundleFull:
|
||||||
// TODO: Implement miner binary deployment via TIM bundles
|
// Determine installation directory
|
||||||
return nil, fmt.Errorf("miner bundle deployment not yet implemented")
|
// 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":
|
logging.Info("deploying miner bundle", logging.Fields{
|
||||||
// TODO: Implement full deployment (miner + profiles)
|
"name": payload.Name,
|
||||||
return nil, fmt.Errorf("full bundle deployment not yet implemented")
|
"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:
|
default:
|
||||||
return nil, fmt.Errorf("unknown bundle type: %s", payload.BundleType)
|
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
|
// Without profile manager, should return error
|
||||||
_, err = worker.handleDeploy(msg)
|
_, err = worker.handleDeploy(nil, msg)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Error("expected error when profile manager is 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)
|
t.Fatalf("failed to create deploy message: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = worker.handleDeploy(msg)
|
_, err = worker.handleDeploy(nil, msg)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Error("expected error for unknown bundle type")
|
t.Error("expected error for unknown bundle type")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue