Generate coinbase templates, fixing missing fields from gbt parser
This commit is contained in:
parent
3cd82a5dd1
commit
86159a60ec
@ -252,6 +252,9 @@ bool gen_gbtbase(connsock_t *cs, gbtbase_t *gbt)
|
||||
gbt->height = height;
|
||||
json_object_set_new_nocheck(gbt->json, "height", json_integer(height));
|
||||
|
||||
gbt->flags = strdup(flags);
|
||||
json_object_set_new_nocheck(gbt->json, "flags", json_string_nocheck(gbt->flags));
|
||||
|
||||
gbt_merkle_bins(gbt, transaction_arr);
|
||||
json_object_set_new_nocheck(gbt->json, "transactions", json_integer(gbt->transactions));
|
||||
if (gbt->transactions)
|
||||
@ -272,6 +275,7 @@ out:
|
||||
|
||||
void clear_gbtbase(gbtbase_t *gbt)
|
||||
{
|
||||
dealloc(gbt->flags);
|
||||
dealloc(gbt->txn_data);
|
||||
json_decref(gbt->json);
|
||||
gbt->json = NULL;
|
||||
|
||||
@ -19,8 +19,9 @@ struct gbtbase {
|
||||
char ntime[12];
|
||||
char bbversion[12];
|
||||
char nbit[12];
|
||||
int coinbasevalue;
|
||||
uint64_t coinbasevalue;
|
||||
int height;
|
||||
char *flags;
|
||||
int transactions;
|
||||
char *txn_data;
|
||||
int merkles;
|
||||
|
||||
115
src/stratifier.c
115
src/stratifier.c
@ -17,6 +17,12 @@
|
||||
#include "libckpool.h"
|
||||
#include "bitcoin.h"
|
||||
|
||||
static const char *scriptsig_header = "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff";
|
||||
static uchar scriptsig_header_bin[41];
|
||||
|
||||
static char pubkeytxnbin[25];
|
||||
static char pubkeytxn[52];
|
||||
|
||||
struct workbase {
|
||||
/* GBT/shared variables */
|
||||
char target[68];
|
||||
@ -27,14 +33,32 @@ struct workbase {
|
||||
char ntime[12];
|
||||
char bbversion[12];
|
||||
char nbit[12];
|
||||
int coinbasevalue;
|
||||
uint64_t coinbasevalue;
|
||||
int height;
|
||||
char *flags;
|
||||
int transactions;
|
||||
char *txn_data;
|
||||
int merkles;
|
||||
char merklehash[16][68];
|
||||
|
||||
/* Work variables */
|
||||
/* Template variables, lengths are binary lengths! */
|
||||
char coinb1[256]; // coinbase1
|
||||
uchar coinb1bin[128];
|
||||
int coinb1len; // length of above
|
||||
|
||||
char enonce1const[32]; // extranonce1 section that is constant
|
||||
uchar enonce1constbin[16];
|
||||
int enonce1constlen; // length of above - usually zero unless proxying
|
||||
int enonce1varlen; // length of unique extranonce1 string for each worker - usually 8
|
||||
|
||||
char enonce2const[16]; // extranonce2 section that is constant
|
||||
uchar enonce2constbin[8];
|
||||
int enonce2constlen; // length of above - usually zero unless proxying
|
||||
int enonce2varlen; // length of space left for extranonce2 - usually 8
|
||||
|
||||
char coinb2[128]; // coinbase2
|
||||
uchar coinb2bin[64];
|
||||
int coinb2len; // length of above
|
||||
};
|
||||
|
||||
typedef struct workbase workbase_t;
|
||||
@ -55,6 +79,10 @@ static inline void json_uintcpy(uint32_t *u32, json_t *val, const char *key)
|
||||
*u32 = (uint32_t)json_integer_value(json_object_get(val, key));
|
||||
}
|
||||
|
||||
static inline void json_uint64cpy(uint64_t *u64, json_t *val, const char *key)
|
||||
{
|
||||
*u64 = (uint64_t)json_integer_value(json_object_get(val, key));
|
||||
}
|
||||
static inline void json_intcpy(int *i, json_t *val, const char *key)
|
||||
{
|
||||
*i = json_integer_value(json_object_get(val, key));
|
||||
@ -65,6 +93,81 @@ static inline void json_strdup(char **buf, json_t *val, const char *key)
|
||||
*buf = strdup(json_string_value(json_object_get(val, key)));
|
||||
}
|
||||
|
||||
static void generate_coinbase(ckpool_t *ckp, workbase_t *wb)
|
||||
{
|
||||
int len, ofs = 0;
|
||||
uint64_t *u64;
|
||||
tv_t now;
|
||||
|
||||
/* Strings in wb should have been zero memset prior. Generate binary
|
||||
* templates first, then convert to hex */
|
||||
memcpy(wb->coinb1bin, scriptsig_header_bin, 41);
|
||||
ofs += 41; // Fixed header length;
|
||||
|
||||
ofs++; // Script length is filled in at the end @wb->coinb1bin[41];
|
||||
|
||||
/* Put block height at start of template */
|
||||
ofs += ser_number(wb->coinb1bin + ofs, wb->height);
|
||||
|
||||
/* Followed by flag */
|
||||
len = strlen(wb->flags) / 2;
|
||||
wb->coinb1bin[ofs++] = len;
|
||||
hex2bin(wb->coinb1bin + ofs, wb->flags, len);
|
||||
ofs += len;
|
||||
|
||||
/* Followed by timestamp */
|
||||
tv_time(&now);
|
||||
ofs += ser_number(wb->coinb1bin + ofs, now.tv_sec);
|
||||
|
||||
wb->coinb1len = ofs;
|
||||
|
||||
len = wb->coinb1len - 41;
|
||||
|
||||
/* Leave enonce1/2varlen constant at 8 bytes for bitcoind sources */
|
||||
wb->enonce1varlen = 8;
|
||||
len += wb->enonce1varlen;
|
||||
wb->enonce2varlen = 8;
|
||||
len += wb->enonce2varlen;
|
||||
|
||||
memcpy(wb->coinb2bin, "\x0a\x2f\x63\x6b\x70\x6f\x6f\x6c\x34\x32\x2f", 11);
|
||||
wb->coinb2len = 11;
|
||||
if (ckp->btcsig) {
|
||||
int siglen = strlen(ckp->btcsig);
|
||||
|
||||
LOGDEBUG("Len %d sig %s", siglen, ckp->btcsig);
|
||||
if (siglen) {
|
||||
wb->coinb2bin[wb->coinb2len++] = siglen;
|
||||
memcpy(wb->coinb2bin + wb->coinb2len, ckp->btcsig, siglen);
|
||||
wb->coinb2len += siglen;
|
||||
}
|
||||
}
|
||||
len += wb->coinb2len;
|
||||
|
||||
wb->coinb1bin[41] = len; /* Set the length now */
|
||||
__bin2hex(wb->coinb1, wb->coinb1bin, wb->coinb1len);
|
||||
LOGDEBUG("Coinb1: %s", wb->coinb1);
|
||||
/* Coinbase 1 complete */
|
||||
|
||||
memcpy(wb->coinb2bin + wb->coinb2len, "\xff\xff\xff\xff", 4);
|
||||
wb->coinb2len += 4;
|
||||
|
||||
wb->coinb2bin[wb->coinb2len++] = 1;
|
||||
u64 = (uint64_t *)&wb->coinb2bin[wb->coinb2len];
|
||||
*u64 = htole64(wb->coinbasevalue);
|
||||
wb->coinb2len += 8;
|
||||
|
||||
wb->coinb2bin[wb->coinb2len++] = 25;
|
||||
|
||||
memcpy(wb->coinb2bin + wb->coinb2len, pubkeytxnbin, 25);
|
||||
wb->coinb2len += 25;
|
||||
|
||||
wb->coinb2len += 4; // Blank lock
|
||||
|
||||
__bin2hex(wb->coinb2, wb->coinb2bin, wb->coinb2len);
|
||||
LOGDEBUG("Coinb2: %s", wb->coinb2);
|
||||
/* Coinbase 2 complete */
|
||||
}
|
||||
|
||||
/* This function assumes it will only receive a valid json gbt base template
|
||||
* since checking should have been done earlier, and creates the base template
|
||||
* for generating work templates. */
|
||||
@ -91,8 +194,9 @@ static void update_base(ckpool_t *ckp)
|
||||
json_strcpy(wb.ntime, val, "ntime");
|
||||
json_strcpy(wb.bbversion, val, "bbversion");
|
||||
json_strcpy(wb.nbit, val, "nbit");
|
||||
json_intcpy(&wb.coinbasevalue, val, "coinbasevalue");
|
||||
json_uint64cpy(&wb.coinbasevalue, val, "coinbasevalue");
|
||||
json_intcpy(&wb.height, val, "height");
|
||||
json_strdup(&wb.flags, val, "flags");
|
||||
json_intcpy(&wb.transactions, val, "transactions");
|
||||
if (wb.transactions)
|
||||
json_strdup(&wb.txn_data, val, "txn_data");
|
||||
@ -106,6 +210,7 @@ static void update_base(ckpool_t *ckp)
|
||||
strcpy(&wb.merklehash[i][0], json_string_value(json_array_get(arr, i)));
|
||||
}
|
||||
json_decref(val);
|
||||
generate_coinbase(ckp, &wb);
|
||||
}
|
||||
|
||||
static int strat_loop(ckpool_t *ckp, proc_instance_t *pi)
|
||||
@ -168,6 +273,10 @@ int stratifier(proc_instance_t *pi)
|
||||
ckpool_t *ckp = pi->ckp;
|
||||
int ret = 0;
|
||||
|
||||
/* Store this for use elsewhere */
|
||||
hex2bin(scriptsig_header_bin, scriptsig_header, 41);
|
||||
address_to_pubkeytxn(pubkeytxnbin, ckp->btcaddress);
|
||||
__bin2hex(pubkeytxn, pubkeytxnbin, 25);
|
||||
strat_loop(ckp, pi);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user