From 773c9fae1d86cf361564e18263e2408816d7df2f Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Tue, 6 Feb 2018 09:35:48 +1100 Subject: [PATCH 1/5] Use the RPC output from bitcoind to determine if an address is a script or a segwit bech32 address, currently refusing to mine to a bech32 address. --- src/bitcoin.c | 51 +++++++++++++++++++++--------------------------- src/bitcoin.h | 4 ++-- src/ckpool.h | 4 ++++ src/generator.c | 13 ++++-------- src/generator.h | 4 ++-- src/libckpool.c | 12 ++++++------ src/stratifier.c | 31 ++++++++++++++++------------- 7 files changed, 57 insertions(+), 62 deletions(-) diff --git a/src/bitcoin.c b/src/bitcoin.c index 4381270f..646ad472 100644 --- a/src/bitcoin.c +++ b/src/bitcoin.c @@ -1,5 +1,5 @@ /* - * Copyright 2014-2017 Con Kolivas + * Copyright 2014-2018 Con Kolivas * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -16,7 +16,6 @@ #include "bitcoin.h" #include "stratifier.h" -static const char *b58chars = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; static char* understood_rules[] = {"segwit"}; static bool check_required_rule(const char* rule) @@ -32,37 +31,16 @@ static bool check_required_rule(const char* rule) /* Take a bitcoin address and do some sanity checks on it, then send it to * bitcoind to see if it's a valid address */ -bool validate_address(connsock_t *cs, const char *address) +bool validate_address(connsock_t *cs, const char *address, bool *script, bool *segwit) { - json_t *val, *res_val, *valid_val; + json_t *val, *res_val, *valid_val, *tmp_val; char rpc_req[128]; bool ret = false; - int len, i, j; if (unlikely(!address)) { LOGWARNING("Null address passed to validate_address"); return ret; } - len = strlen(address); - if (len < 27 || len > 36) { - LOGWARNING("Invalid address length %d passed to validate_address", len); - return ret; - } - for (i = 0; i < len; i++) { - char c = address[i]; - bool found = false; - - for (j = 0; j < 58; j++) { - if (c == b58chars[j]) { - found = true; - break; - } - } - if (!found) { - LOGNOTICE("Invalid char %.1s passed to validate_address", &c); - return ret; - } - } snprintf(rpc_req, 128, "{\"method\": \"validateaddress\", \"params\": [\"%s\"]}\n", address); val = json_rpc_call(cs, rpc_req); @@ -80,12 +58,27 @@ bool validate_address(connsock_t *cs, const char *address) LOGERR("Failed to get isvalid json response to validate_address"); goto out; } - if (!json_is_true(valid_val)) + if (!json_is_true(valid_val)) { LOGDEBUG("Bitcoin address %s is NOT valid", address); - else { - LOGDEBUG("Bitcoin address %s IS valid", address); - ret = true; + goto out; } + ret = true; + tmp_val = json_object_get(res_val, "isscript"); + if (unlikely(!tmp_val)) { + /* All recent bitcoinds should support this, if not, look for + * a 3x address to at least support it on mainnet */ + LOGDEBUG("No isscript support from bitcoind"); + if (address[0] == '3') + *script = true; + goto out; + } + *script = json_is_true(tmp_val); + tmp_val = json_object_get(res_val, "iswitness"); + if (unlikely(!tmp_val)) + goto out; + *segwit = json_is_true(tmp_val); + LOGDEBUG("Bitcoin address %s IS valid%s%s", address, *script ? " script" : "", + *segwit ? " segwit" : ""); out: if (val) json_decref(val); diff --git a/src/bitcoin.h b/src/bitcoin.h index 08f6bbe4..782a2073 100644 --- a/src/bitcoin.h +++ b/src/bitcoin.h @@ -1,5 +1,5 @@ /* - * Copyright 2014-2017 Con Kolivas + * Copyright 2014-2018 Con Kolivas * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -12,7 +12,7 @@ typedef struct genwork gbtbase_t; -bool validate_address(connsock_t *cs, const char *address); +bool validate_address(connsock_t *cs, const char *address, bool *script, bool *segwit); bool gen_gbtbase(connsock_t *cs, gbtbase_t *gbt); void clear_gbtbase(gbtbase_t *gbt); int get_blockcount(connsock_t *cs); diff --git a/src/ckpool.h b/src/ckpool.h index dc8716d0..c8b7f5e8 100644 --- a/src/ckpool.h +++ b/src/ckpool.h @@ -241,8 +241,12 @@ struct ckpool_instance { /* Coinbase data */ char *btcaddress; // Address to mine to + bool script; // Address is a script address + bool segwit; // Address is a segwit address char *btcsig; // Optional signature to add to coinbase char *donaddress; // Donation address + bool donscript; // Donation is a script + bool donsegwit; // Donation is segwit bool donvalid; // Donation address works on this network /* Stratum options */ diff --git a/src/generator.c b/src/generator.c index 4d7a1947..61cf4464 100644 --- a/src/generator.c +++ b/src/generator.c @@ -253,7 +253,7 @@ static bool server_alive(ckpool_t *ckp, server_instance_t *si, bool pinging) goto out; } clear_gbtbase(&gbt); - if (!ckp->node && !validate_address(cs, ckp->btcaddress)) { + if (!ckp->node && !validate_address(cs, ckp->btcaddress, &ckp->script, &ckp->segwit)) { LOGWARNING("Invalid btcaddress: %s !", ckp->btcaddress); goto out; } @@ -473,11 +473,6 @@ retry: memset(buf + 12 + 64, 0, 1); sprintf(blockmsg, "%sblock:%s", ret ? "" : "no", buf + 12); send_proc(ckp->stratifier, blockmsg); - } else if (cmdmatch(buf, "checkaddr:")) { - if (validate_address(cs, buf + 10)) - send_unix_msg(umsg->sockd, "true"); - else - send_unix_msg(umsg->sockd, "false"); } else if (cmdmatch(buf, "reconnect")) { goto reconnect; } else if (cmdmatch(buf, "loglevel")) { @@ -904,7 +899,7 @@ out: return ret; } -bool generator_checkaddr(ckpool_t *ckp, const char *addr) +bool generator_checkaddr(ckpool_t *ckp, const char *addr, bool *script, bool *segwit) { gdata_t *gdata = ckp->gdata; server_instance_t *si; @@ -917,7 +912,7 @@ bool generator_checkaddr(ckpool_t *ckp, const char *addr) goto out; } cs = &si->cs; - ret = validate_address(cs, addr); + ret = validate_address(cs, addr, script, segwit); out: return ret; } @@ -931,7 +926,7 @@ char *generator_get_txn(ckpool_t *ckp, const char *hash) si = gdata->current_si; if (unlikely(!si)) { - LOGWARNING("No live current server in generator_checkaddr"); + LOGWARNING("No live current server in generator_get_txn"); goto out; } cs = &si->cs; diff --git a/src/generator.h b/src/generator.h index 8b23f989..242466eb 100644 --- a/src/generator.h +++ b/src/generator.h @@ -1,5 +1,5 @@ /* - * Copyright 2014-2017 Con Kolivas + * Copyright 2014-2018 Con Kolivas * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -19,7 +19,7 @@ void generator_add_send(ckpool_t *ckp, json_t *val); struct genwork *generator_getbase(ckpool_t *ckp); int generator_getbest(ckpool_t *ckp, char *hash); -bool generator_checkaddr(ckpool_t *ckp, const char *addr); +bool generator_checkaddr(ckpool_t *ckp, const char *addr, bool *script, bool *segwit); char *generator_get_txn(ckpool_t *ckp, const char *hash); bool generator_submitblock(ckpool_t *ckp, const char *buf); void generator_preciousblock(ckpool_t *ckp, const char *hash); diff --git a/src/libckpool.c b/src/libckpool.c index bac71efa..694444ed 100644 --- a/src/libckpool.c +++ b/src/libckpool.c @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 Con Kolivas + * Copyright 2014-2018 Con Kolivas * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -1743,15 +1743,15 @@ void address_to_pubkeytxn(char *pkh, const char *addr) pkh[24] = 0xac; } -void address_to_scripttxn(char *pkh, const char *addr) +void address_to_scripttxn(char *psh, const char *addr) { char b58bin[25] = {}; b58tobin(b58bin, addr); - pkh[0] = 0xa9; - pkh[1] = 0x14; - memcpy(&pkh[2], &b58bin[1], 20); - pkh[22] = 0x87; + psh[0] = 0xa9; + psh[1] = 0x14; + memcpy(&psh[2], &b58bin[1], 20); + psh[22] = 0x87; } /* For encoding nHeight into coinbase, return how many bytes were used */ diff --git a/src/stratifier.c b/src/stratifier.c index 2e91dda7..06b81d3f 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -1,5 +1,5 @@ /* - * Copyright 2014-2017 Con Kolivas + * Copyright 2014-2018 Con Kolivas * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -113,6 +113,8 @@ struct user_instance { int id; char *secondaryuserid; bool btcaddress; + bool script; + bool segwit; /* A linked list of all connected instances of this user */ stratum_instance_t *clients; @@ -5313,7 +5315,9 @@ static user_instance_t *generate_user(ckpool_t *ckp, stratum_instance_t *client, /* Is this a btc address based username? */ if (!ckp->proxy && (new_user || !user->btcaddress) && (len > 26 && len < 35)) - user->btcaddress = generator_checkaddr(ckp, username); + user->btcaddress = generator_checkaddr(ckp, username, &user->script, &user->segwit); + if (user->segwit) /* Bech32 addresses currently unsupported */ + user->btcaddress = false; if (new_user) { LOGNOTICE("Added new user %s%s", username, user->btcaddress ? " as address based registration" : ""); @@ -6787,7 +6791,9 @@ static user_instance_t *generate_remote_user(ckpool_t *ckp, const char *workerna /* Is this a btc address based username? */ if (!ckp->proxy && (new_user || !user->btcaddress) && (len > 26 && len < 35)) - user->btcaddress = generator_checkaddr(ckp, username); + user->btcaddress = generator_checkaddr(ckp, username, &user->script, &user->segwit); + if (user->segwit) + user->btcaddress = false; if (new_user) { LOGNOTICE("Added new remote user %s%s", username, user->btcaddress ? " as address based registration" : ""); @@ -8557,13 +8563,6 @@ static void read_poolstats(ckpool_t *ckp, int *tvsec_diff) } } -/* Braindead check to see if this btcaddress is an M of N script address which - * is currently unsupported as a generation address. */ -static bool script_address(const char *btcaddress) -{ - return btcaddress[0] == '3'; -} - void *stratifier(void *arg) { proc_instance_t *pi = (proc_instance_t *)arg; @@ -8587,14 +8586,18 @@ void *stratifier(void *arg) cksleep_ms(10); if (!ckp->proxy) { - if (!generator_checkaddr(ckp, ckp->btcaddress)) { + if (!generator_checkaddr(ckp, ckp->btcaddress, &ckp->script, &ckp->segwit)) { LOGEMERG("Fatal: btcaddress invalid according to bitcoind"); goto out; } + if (ckp->segwit) { + LOGEMERG("Fatal: bech32 addresses not currently supported"); + goto out; + } /* Store this for use elsewhere */ hex2bin(scriptsig_header_bin, scriptsig_header, 41); - if (script_address(ckp->btcaddress)) { + if (ckp->script) { address_to_scripttxn(sdata->pubkeytxnbin, ckp->btcaddress); sdata->pubkeytxnlen = 23; } else { @@ -8602,9 +8605,9 @@ void *stratifier(void *arg) sdata->pubkeytxnlen = 25; } - if (generator_checkaddr(ckp, ckp->donaddress)) { + if (generator_checkaddr(ckp, ckp->donaddress, &ckp->donscript, &ckp->donsegwit)) { ckp->donvalid = true; - if (script_address(ckp->donaddress)) { + if (ckp->donscript) { sdata->donkeytxnlen = 23; address_to_scripttxn(sdata->donkeytxnbin, ckp->donaddress); } else { From b806916201607441ee07bfede3967c34af52d8e4 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Tue, 6 Feb 2018 10:12:22 +1100 Subject: [PATCH 2/5] Choose the generation transaction type and return the transaction length within libckpool. --- src/ckpool.h | 2 +- src/libckpool.c | 22 ++++++++++++++++++++-- src/libckpool.h | 5 ++--- src/stratifier.c | 40 ++++++++++++++-------------------------- 4 files changed, 37 insertions(+), 32 deletions(-) diff --git a/src/ckpool.h b/src/ckpool.h index c8b7f5e8..bc1cd564 100644 --- a/src/ckpool.h +++ b/src/ckpool.h @@ -1,5 +1,5 @@ /* - * Copyright 2014-2017 Con Kolivas + * Copyright 2014-2018 Con Kolivas * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/libckpool.c b/src/libckpool.c index 694444ed..e828c4a9 100644 --- a/src/libckpool.c +++ b/src/libckpool.c @@ -1730,7 +1730,9 @@ char *http_base64(const char *src) return (str); } -void address_to_pubkeytxn(char *pkh, const char *addr) +/* It's assumed that there is no chance of sending invalid chars to these + * functions as they should have been checked beforehand. */ +static void address_to_pubkeytxn(char *pkh, const char *addr) { char b58bin[25] = {}; @@ -1743,7 +1745,7 @@ void address_to_pubkeytxn(char *pkh, const char *addr) pkh[24] = 0xac; } -void address_to_scripttxn(char *psh, const char *addr) +static void address_to_scripttxn(char *psh, const char *addr) { char b58bin[25] = {}; @@ -1754,6 +1756,22 @@ void address_to_scripttxn(char *psh, const char *addr) psh[22] = 0x87; } +/* Convert an address to a transaction and return the length of the transaction */ +int address_to_txn(char *p2h, const char *addr, const bool script, const bool segwit) +{ + if (unlikely(segwit)) { + /* It should be impossible to hit this for now */ + LOGEMERG("Segwit bech32 address passed to address_to_txn while unsupported."); + return 0; + } + if (script) { + address_to_scripttxn(p2h, addr); + return 23; + } + address_to_pubkeytxn(p2h, addr); + return 25; +} + /* For encoding nHeight into coinbase, return how many bytes were used */ int ser_number(uchar *s, int32_t val) { diff --git a/src/libckpool.h b/src/libckpool.h index 306f1c6c..3d29995c 100644 --- a/src/libckpool.h +++ b/src/libckpool.h @@ -1,5 +1,5 @@ /* - * Copyright 2014-2017 Con Kolivas + * Copyright 2014-2018 Con Kolivas * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -561,8 +561,7 @@ void b58tobin(char *b58bin, const char *b58); int safecmp(const char *a, const char *b); bool cmdmatch(const char *buf, const char *cmd); -void address_to_pubkeytxn(char *pkh, const char *addr); -void address_to_scripttxn(char *pkh, const char *addr); +int address_to_txn(char *p2h, const char *addr, const bool script, const bool segwit); int ser_number(uchar *s, int32_t val); int get_sernumber(uchar *s); bool fulltest(const uchar *hash, const uchar *target); diff --git a/src/stratifier.c b/src/stratifier.c index 06b81d3f..6ffcac10 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -389,10 +389,10 @@ static const char *ckdb_seq_names[] = { struct stratifier_data { ckpool_t *ckp; - char pubkeytxnbin[25]; - int pubkeytxnlen; - char donkeytxnbin[25]; - int donkeytxnlen; + char txnbin[40]; + int txnlen; + char dontxnbin[40]; + int dontxnlen; pool_stats_t stats; /* Protects changes to pool stats */ @@ -615,9 +615,9 @@ static void generate_coinbase(const ckpool_t *ckp, workbase_t *wb) *u64 = htole64(g64); wb->coinb2len += 8; - wb->coinb2bin[wb->coinb2len++] = sdata->pubkeytxnlen; - memcpy(wb->coinb2bin + wb->coinb2len, sdata->pubkeytxnbin, sdata->pubkeytxnlen); - wb->coinb2len += sdata->pubkeytxnlen; + wb->coinb2bin[wb->coinb2len++] = sdata->txnlen; + memcpy(wb->coinb2bin + wb->coinb2len, sdata->txnbin, sdata->txnlen); + wb->coinb2len += sdata->txnlen; if (wb->insert_witness) { // 0 value @@ -636,9 +636,9 @@ static void generate_coinbase(const ckpool_t *ckp, workbase_t *wb) *u64 = htole64(d64); wb->coinb2len += 8; - wb->coinb2bin[wb->coinb2len++] = sdata->donkeytxnlen; - memcpy(wb->coinb2bin + wb->coinb2len, sdata->donkeytxnbin, sdata->donkeytxnlen); - wb->coinb2len += sdata->donkeytxnlen; + wb->coinb2bin[wb->coinb2len++] = sdata->dontxnlen; + memcpy(wb->coinb2bin + wb->coinb2len, sdata->dontxnbin, sdata->dontxnlen); + wb->coinb2len += sdata->dontxnlen; } wb->coinb2len += 4; // Blank lock @@ -2354,8 +2354,8 @@ static sdata_t *duplicate_sdata(const sdata_t *sdata) dsdata->ckp = sdata->ckp; /* Copy the transaction binaries for workbase creation */ - memcpy(dsdata->pubkeytxnbin, sdata->pubkeytxnbin, 25); - memcpy(dsdata->donkeytxnbin, sdata->donkeytxnbin, 25); + memcpy(dsdata->txnbin, sdata->txnbin, 40); + memcpy(dsdata->dontxnbin, sdata->dontxnbin, 40); /* Use the same work queues for all subproxies */ dsdata->ssends = sdata->ssends; @@ -8597,23 +8597,11 @@ void *stratifier(void *arg) /* Store this for use elsewhere */ hex2bin(scriptsig_header_bin, scriptsig_header, 41); - if (ckp->script) { - address_to_scripttxn(sdata->pubkeytxnbin, ckp->btcaddress); - sdata->pubkeytxnlen = 23; - } else { - address_to_pubkeytxn(sdata->pubkeytxnbin, ckp->btcaddress); - sdata->pubkeytxnlen = 25; - } + sdata->txnlen = address_to_txn(sdata->txnbin, ckp->btcaddress, ckp->script, ckp->segwit); if (generator_checkaddr(ckp, ckp->donaddress, &ckp->donscript, &ckp->donsegwit)) { ckp->donvalid = true; - if (ckp->donscript) { - sdata->donkeytxnlen = 23; - address_to_scripttxn(sdata->donkeytxnbin, ckp->donaddress); - } else { - sdata->donkeytxnlen = 25; - address_to_pubkeytxn(sdata->donkeytxnbin, ckp->donaddress); - } + sdata->dontxnlen = address_to_txn(sdata->dontxnbin, ckp->donaddress, ckp->script, ckp->segwit); } } From 61513a765b12947fae30535179194b1672dc82b5 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Tue, 6 Feb 2018 12:29:57 +1100 Subject: [PATCH 3/5] Implement native bech32 segwit address support. --- src/libckpool.c | 83 ++++++++++++++++++++++++++++++++++++++++-------- src/stratifier.c | 14 ++------ 2 files changed, 73 insertions(+), 24 deletions(-) diff --git a/src/libckpool.c b/src/libckpool.c index e828c4a9..21f77753 100644 --- a/src/libckpool.c +++ b/src/libckpool.c @@ -1730,9 +1730,54 @@ char *http_base64(const char *src) return (str); } +static const int8_t charset_rev[128] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 15, -1, 10, 17, 21, 20, 26, 30, 7, 5, -1, -1, -1, -1, -1, -1, + -1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1, + 1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1, + -1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1, + 1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1 +}; + /* It's assumed that there is no chance of sending invalid chars to these * functions as they should have been checked beforehand. */ -static void address_to_pubkeytxn(char *pkh, const char *addr) +static void bech32_decode(uint8_t *data, int *data_len, const char *input) +{ + int input_len = strlen(input), hrp_len, i; + + *data_len = 0; + while (*data_len < input_len && input[(input_len - 1) - *data_len] != '1') + ++(*data_len); + hrp_len = input_len - (1 + *data_len); + *(data_len) -= 6; + for (i = hrp_len + 1; i < input_len; i++) { + int v = (input[i] & 0x80) ? -1 : charset_rev[(int)input[i]]; + + if (i + 6 < input_len) + data[i - (1 + hrp_len)] = v; + } +} + +static void convert_bits(char *out, int *outlen, const uint8_t *in, + int inlen) +{ + const int outbits = 8, inbits = 5; + uint32_t val = 0, maxv = (((uint32_t)1) << outbits) - 1; + int bits = 0; + + while (inlen--) { + val = (val << inbits) | *(in++); + bits += inbits; + while (bits >= outbits) { + bits -= outbits; + out[(*outlen)++] = (val >> bits) & maxv; + } + } +} + +static int address_to_pubkeytxn(char *pkh, const char *addr) { char b58bin[25] = {}; @@ -1743,9 +1788,10 @@ static void address_to_pubkeytxn(char *pkh, const char *addr) memcpy(&pkh[3], &b58bin[1], 20); pkh[23] = 0x88; pkh[24] = 0xac; + return 25; } -static void address_to_scripttxn(char *psh, const char *addr) +static int address_to_scripttxn(char *psh, const char *addr) { char b58bin[25] = {}; @@ -1754,22 +1800,33 @@ static void address_to_scripttxn(char *psh, const char *addr) psh[1] = 0x14; memcpy(&psh[2], &b58bin[1], 20); psh[22] = 0x87; + return 23; +} + +static int segaddress_to_txn(char *p2h, const char *addr) +{ + int data_len, witdata_len = 0; + char *witdata = &p2h[2]; + uint8_t data[84]; + + bech32_decode(data, &data_len, addr); + p2h[0] = data[0]; + /* Witness version is > 0 */ + if (p2h[0]) + p2h[0] += 0x50; + convert_bits(witdata, &witdata_len, data + 1, data_len - 1); + p2h[1] = witdata_len; + return witdata_len + 2; } /* Convert an address to a transaction and return the length of the transaction */ int address_to_txn(char *p2h, const char *addr, const bool script, const bool segwit) { - if (unlikely(segwit)) { - /* It should be impossible to hit this for now */ - LOGEMERG("Segwit bech32 address passed to address_to_txn while unsupported."); - return 0; - } - if (script) { - address_to_scripttxn(p2h, addr); - return 23; - } - address_to_pubkeytxn(p2h, addr); - return 25; + if (segwit) + return segaddress_to_txn(p2h, addr); + if (script) + return address_to_scripttxn(p2h, addr); + return address_to_pubkeytxn(p2h, addr); } /* For encoding nHeight into coinbase, return how many bytes were used */ diff --git a/src/stratifier.c b/src/stratifier.c index 6ffcac10..1032a36f 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -389,9 +389,9 @@ static const char *ckdb_seq_names[] = { struct stratifier_data { ckpool_t *ckp; - char txnbin[40]; + char txnbin[48]; int txnlen; - char dontxnbin[40]; + char dontxnbin[48]; int dontxnlen; pool_stats_t stats; @@ -579,7 +579,7 @@ static void generate_coinbase(const ckpool_t *ckp, workbase_t *wb) len += wb->enonce1varlen; len += wb->enonce2varlen; - wb->coinb2bin = ckzalloc(256); + wb->coinb2bin = ckzalloc(512); memcpy(wb->coinb2bin, "\x0a\x63\x6b\x70\x6f\x6f\x6c", 7); wb->coinb2len = 7; if (ckp->btcsig) { @@ -5316,8 +5316,6 @@ static user_instance_t *generate_user(ckpool_t *ckp, stratum_instance_t *client, /* Is this a btc address based username? */ if (!ckp->proxy && (new_user || !user->btcaddress) && (len > 26 && len < 35)) user->btcaddress = generator_checkaddr(ckp, username, &user->script, &user->segwit); - if (user->segwit) /* Bech32 addresses currently unsupported */ - user->btcaddress = false; if (new_user) { LOGNOTICE("Added new user %s%s", username, user->btcaddress ? " as address based registration" : ""); @@ -6792,8 +6790,6 @@ static user_instance_t *generate_remote_user(ckpool_t *ckp, const char *workerna /* Is this a btc address based username? */ if (!ckp->proxy && (new_user || !user->btcaddress) && (len > 26 && len < 35)) user->btcaddress = generator_checkaddr(ckp, username, &user->script, &user->segwit); - if (user->segwit) - user->btcaddress = false; if (new_user) { LOGNOTICE("Added new remote user %s%s", username, user->btcaddress ? " as address based registration" : ""); @@ -8590,10 +8586,6 @@ void *stratifier(void *arg) LOGEMERG("Fatal: btcaddress invalid according to bitcoind"); goto out; } - if (ckp->segwit) { - LOGEMERG("Fatal: bech32 addresses not currently supported"); - goto out; - } /* Store this for use elsewhere */ hex2bin(scriptsig_header_bin, scriptsig_header, 41); From f6390b3c930a1561713fe2064f5f2e16eac4d3ec Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Wed, 7 Feb 2018 10:32:09 +1100 Subject: [PATCH 4/5] Remove length restriction on checking usernames for btc address to be compatible with segwit addresses. --- src/stratifier.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stratifier.c b/src/stratifier.c index 1032a36f..e1344f17 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -5314,7 +5314,7 @@ static user_instance_t *generate_user(ckpool_t *ckp, stratum_instance_t *client, ck_wunlock(&sdata->instance_lock); /* Is this a btc address based username? */ - if (!ckp->proxy && (new_user || !user->btcaddress) && (len > 26 && len < 35)) + if (!ckp->proxy && (new_user || !user->btcaddress)) user->btcaddress = generator_checkaddr(ckp, username, &user->script, &user->segwit); if (new_user) { LOGNOTICE("Added new user %s%s", username, user->btcaddress ? From 8fb1a97fb0b340f16c2721e432b789261a8e3992 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Wed, 7 Feb 2018 09:52:06 +1100 Subject: [PATCH 5/5] Silence warning with newer glibc. --- src/ckpmsg.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ckpmsg.c b/src/ckpmsg.c index 206b9056..c585192d 100644 --- a/src/ckpmsg.c +++ b/src/ckpmsg.c @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 Con Kolivas + * Copyright 2014-2018 Con Kolivas * Copyright 2014-2016 Andrew Smith * * This program is free software; you can redistribute it and/or modify it @@ -16,6 +16,7 @@ #include #include #include +#include #include "libckpool.h" #include "utlist.h"