Add Fleet Torrent erasure extension with shard DHT and gossip.
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Content-addressed shard DHT on seeder agents with subnet_primary_seeder election, cross-subnet fleet_torrent_gossip, BGP swarm magnets, C2 torrent manifest, and k-of-n peer fetch with C2 fallback.
This commit is contained in:
83
server/internal/api/oath_ledger.go
Normal file
83
server/internal/api/oath_ledger.go
Normal file
@@ -0,0 +1,83 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
dbpkg "crypto-miner-server/internal/db"
|
||||
)
|
||||
|
||||
// OathLedgerBridge records immutable rows and broadcasts dashboard WS events.
|
||||
type OathLedgerBridge struct {
|
||||
DB *dbpkg.Database
|
||||
Hub *WSHub
|
||||
}
|
||||
|
||||
// Record appends one oath ledger row and emits oath_ledger_event when a hub is wired.
|
||||
func (b *OathLedgerBridge) Record(actor, actionType, agentID, strain, outcome string, whySource, payload interface{}) error {
|
||||
if b == nil || b.DB == nil {
|
||||
return nil
|
||||
}
|
||||
whyHash := dbpkg.HashWhyJSON(whySource)
|
||||
entry, err := b.DB.InsertOathLedger(actor, actionType, agentID, strain, whyHash, outcome, payload)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if b.Hub != nil && entry != nil {
|
||||
b.Hub.BroadcastOathLedgerEvent(*entry)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// BroadcastOathLedgerEvent pushes a live oath row to dashboard clients.
|
||||
func (h *WSHub) BroadcastOathLedgerEvent(entry dbpkg.OathLedgerEntry) {
|
||||
if h == nil {
|
||||
return
|
||||
}
|
||||
h.broadcastDashboard(Message{
|
||||
Type: "oath_ledger_event",
|
||||
Payload: mustMarshal(entry),
|
||||
})
|
||||
}
|
||||
|
||||
// GetOathLedger lists recent immutable accountability rows.
|
||||
func (f *FleetHandler) GetOathLedger(w http.ResponseWriter, r *http.Request) {
|
||||
if f.db == nil {
|
||||
writeJSON(w, []dbpkg.OathLedgerEntry{})
|
||||
return
|
||||
}
|
||||
limit := 100
|
||||
if raw := strings.TrimSpace(r.URL.Query().Get("limit")); raw != "" {
|
||||
if n, err := strconv.Atoi(raw); err == nil && n > 0 {
|
||||
limit = n
|
||||
}
|
||||
}
|
||||
rows, err := f.db.ListOathLedger(limit)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
if rows == nil {
|
||||
rows = []dbpkg.OathLedgerEntry{}
|
||||
}
|
||||
writeJSON(w, rows)
|
||||
}
|
||||
|
||||
func agentStrainFromDB(database *dbpkg.Database, agentID string) string {
|
||||
if database == nil || agentID == "" {
|
||||
return ""
|
||||
}
|
||||
ag, err := database.GetAgent(agentID)
|
||||
if err != nil || ag == nil {
|
||||
return ""
|
||||
}
|
||||
return ag.SpreadStrain
|
||||
}
|
||||
|
||||
func oathOutcomeFromError(err error) string {
|
||||
if err != nil {
|
||||
return dbpkg.OathOutcomeFail
|
||||
}
|
||||
return dbpkg.OathOutcomeSuccess
|
||||
}
|
||||
Reference in New Issue
Block a user