diff --git a/src/generator.c b/src/generator.c index 3a678efc..34f89671 100644 --- a/src/generator.c +++ b/src/generator.c @@ -180,6 +180,8 @@ struct generator_data { share_msg_t *shares; int64_t share_id; + server_instance_t *current_si; + proxy_instance_t *current_proxy; }; @@ -242,7 +244,7 @@ out: } /* Find the highest priority server alive and return it */ -static server_instance_t *live_server(ckpool_t *ckp) +static server_instance_t *live_server(ckpool_t *ckp, gdata_t *gdata) { server_instance_t *alive = NULL; connsock_t *cs; @@ -275,6 +277,7 @@ retry: sleep(5); goto retry; living: + gdata->current_si = alive; cs = &alive->cs; LOGINFO("Connected to live server %s:%s", cs->url, cs->port); send_proc(ckp->connector, alive ? "accept" : "reject"); @@ -321,7 +324,7 @@ static void gen_loop(proc_instance_t *pi) reconnect: clear_unix_msg(&umsg); old_si = si; - si = live_server(ckp); + si = live_server(ckp, ckp->gdata); if (!si) goto out; if (unlikely(!ckp->generator_ready)) { @@ -792,6 +795,38 @@ static void reconnect_generator(ckpool_t *ckp) send_proc(ckp->generator, "reconnect"); } +json_t *generator_genbase(ckpool_t *ckp) +{ + gdata_t *gdata = ckp->gdata; + server_instance_t *si; + gbtbase_t gbt = {}; + json_t *val = NULL; + connsock_t *cs; + + /* Use temporary variables to prevent deref while accessing */ + si = gdata->current_si; + if (unlikely(!si)) { + LOGWARNING("No live current server in generator_genbase"); + goto out; + } + cs = &si->cs; + if (unlikely(!cs)) { + LOGWARNING("No live connsock for current server in generator_genbase"); + goto out; + } + if (unlikely(!gen_gbtbase(cs, &gbt))) { + LOGWARNING("Failed to get block template from %s:%s", cs->url, cs->port); + si->alive = cs->alive = false; + reconnect_generator(ckp); + goto out; + } + val = gbt.json; + gbt.json = NULL; + clear_gbtbase(&gbt); +out: + return val; +} + static bool parse_notify(ckpool_t *ckp, proxy_instance_t *proxi, json_t *val) { const char *prev_hash, *bbversion, *nbit, *ntime; @@ -2800,7 +2835,7 @@ reconnect: if (ckp->node) { old_si = si; - si = live_server(ckp); + si = live_server(ckp, gdata); if (!si) goto out; cs = &si->cs; diff --git a/src/generator.h b/src/generator.h index 639af50a..8c0fdd89 100644 --- a/src/generator.h +++ b/src/generator.h @@ -13,6 +13,7 @@ #include "config.h" void generator_add_send(ckpool_t *ckp, json_t *val); +json_t *generator_genbase(ckpool_t *ckp); void *generator(void *arg); #endif /* GENERATOR_H */ diff --git a/src/stratifier.c b/src/stratifier.c index 5a39bcaf..7fd4ae16 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -1442,7 +1442,6 @@ static void *do_update(void *arg) bool ret = false; workbase_t *wb; time_t now_t; - char *buf; pthread_detach(pthread_self()); rename_proc("updater"); @@ -1458,12 +1457,8 @@ static void *do_update(void *arg) } else cksem_wait(&sdata->update_sem); retry: - buf = send_recv_generator(ckp, "getbase", prio); - if (unlikely(!buf)) { - LOGNOTICE("Get base in update_base delayed due to higher priority request"); - goto out; - } - if (unlikely(cmdmatch(buf, "failed"))) { + val = generator_genbase(ckp); + if (unlikely(!val)) { if (retries++ < 5 || prio == GEN_PRIORITY) { LOGWARNING("Generator returned failure in update_base, retry #%d", retries); goto retry; @@ -1476,7 +1471,6 @@ retry: wb = ckzalloc(sizeof(workbase_t)); wb->ckp = ckp; - val = json_loads(buf, 0, NULL); json_strcpy(wb->target, val, "target"); json_dblcpy(&wb->diff, val, "diff"); @@ -1542,7 +1536,6 @@ out: LOGINFO("Broadcast ping due to failed stratum base update"); broadcast_ping(sdata); } - dealloc(buf); out_free: free(ur->pth); free(ur);