mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-07-11 06:46:59 +08:00
security+reliability: remove public decrypt endpoint, add panic recovery for goroutines
Security: - Remove /api/crypto/decrypt from public routes. The endpoint allowed anyone to decrypt ciphertext without authentication. Internal callers (exchange/model handlers) use the service directly and are behind auth. Reliability: - Add safe.Go / safe.GoNamed panic recovery wrapper (safe/go.go). Previously 31 goroutines had zero recover() calls — a single panic in any trader goroutine would crash the entire process. - Apply safe.GoNamed to all trader launch paths: - StartAll, RestoreRunning, LoadSingleTrader auto-start - API handler start/restart endpoints - Panics are now logged with full stack traces instead of crashing.
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"nofx/logger"
|
||||
"nofx/safe"
|
||||
"nofx/store"
|
||||
"nofx/trader"
|
||||
"sort"
|
||||
@@ -87,12 +88,14 @@ func (tm *TraderManager) StartAll() {
|
||||
|
||||
logger.Info("🚀 Starting all traders...")
|
||||
for id, t := range tm.traders {
|
||||
go func(traderID string, at *trader.AutoTrader) {
|
||||
traderID, at := id, t
|
||||
safe.GoNamed("trader-"+at.GetName(), func() {
|
||||
logger.Infof("▶️ Starting %s...", at.GetName())
|
||||
if err := at.Run(); err != nil {
|
||||
logger.Infof("❌ %s runtime error: %v", at.GetName(), err)
|
||||
}
|
||||
}(id, t)
|
||||
})
|
||||
_ = traderID
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,12 +138,13 @@ func (tm *TraderManager) AutoStartRunningTraders(st *store.Store) {
|
||||
startedCount := 0
|
||||
for id, t := range tm.traders {
|
||||
if runningTraderIDs[id] {
|
||||
go func(traderID string, at *trader.AutoTrader) {
|
||||
at := t
|
||||
safe.GoNamed("trader-restore-"+at.GetName(), func() {
|
||||
logger.Infof("▶️ Auto-restoring %s...", at.GetName())
|
||||
if err := at.Run(); err != nil {
|
||||
logger.Infof("❌ %s runtime error: %v", at.GetName(), err)
|
||||
}
|
||||
}(id, t)
|
||||
})
|
||||
startedCount++
|
||||
}
|
||||
}
|
||||
@@ -726,15 +730,16 @@ func (tm *TraderManager) addTraderFromStore(traderCfg *store.Trader, aiModelCfg
|
||||
// Auto-start if trader was running before shutdown
|
||||
if traderCfg.IsRunning {
|
||||
logger.Infof("🔄 Auto-starting trader '%s' (was running before shutdown)...", traderCfg.Name)
|
||||
go func(trader *trader.AutoTrader, traderName, traderID, userID string) {
|
||||
if err := trader.Run(); err != nil {
|
||||
logger.Warnf("⚠️ Trader '%s' stopped with error: %v", traderName, err)
|
||||
autoStartTrader, autoStartName, autoStartID, autoStartUserID := at, traderCfg.Name, traderCfg.ID, traderCfg.UserID
|
||||
safe.GoNamed("trader-autostart-"+autoStartName, func() {
|
||||
if err := autoStartTrader.Run(); err != nil {
|
||||
logger.Warnf("⚠️ Trader '%s' stopped with error: %v", autoStartName, err)
|
||||
// Update database to reflect stopped state
|
||||
if st != nil {
|
||||
_ = st.Trader().UpdateStatus(userID, traderID, false)
|
||||
_ = st.Trader().UpdateStatus(autoStartUserID, autoStartID, false)
|
||||
}
|
||||
}
|
||||
}(at, traderCfg.Name, traderCfg.ID, traderCfg.UserID)
|
||||
})
|
||||
logger.Infof("✅ Trader '%s' auto-started successfully", traderCfg.Name)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user