From 24633a987f111d7fee4dab2f58b703e29d634488 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Fri, 27 May 2016 16:57:06 +0000 Subject: [PATCH 1/8] Bugfix: Use json_number_value in case jansson decided to parse numbers as a "real" --- blkmaker_jansson.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/blkmaker_jansson.c b/blkmaker_jansson.c index 6588978..d6e6a2f 100644 --- a/blkmaker_jansson.c +++ b/blkmaker_jansson.c @@ -107,12 +107,12 @@ err: #define GETNUM(key) do { \ GET(key, number); \ - tmpl->key = json_integer_value(v); \ + tmpl->key = json_number_value(v); \ } while(0) #define GETNUM_O2(key, skey) do { \ if ((v = json_object_get(json, #skey)) && json_is_number(v)) \ - tmpl->key = json_integer_value(v); \ + tmpl->key = json_number_value(v); \ } while(0) #define GETNUM_O(key) GETNUM_O2(key, key) From cc07c06238b73124586f52f9a704af959403f2f4 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Tue, 2 Sep 2014 17:17:52 +0000 Subject: [PATCH 2/8] jansson: Read time header mutation parameters --- blkmaker_jansson.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/blkmaker_jansson.c b/blkmaker_jansson.c index d6e6a2f..08809e5 100644 --- a/blkmaker_jansson.c +++ b/blkmaker_jansson.c @@ -194,6 +194,10 @@ const char *blktmpl_add_jansson(blktemplate_t *tmpl, const json_t *json, time_t GETSTR(workid, workid); GETNUM_O(expires); + GETNUM_O(maxtime); + GETNUM_O(maxtimeoff); + GETNUM_O(mintime); + GETNUM_O(mintimeoff); GETSTR(longpollid, lp.id); GETSTR(longpolluri, lp.uri); From 9f58bcb4aa11555871fb6863e6ae30774be29a71 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Tue, 26 Jul 2016 02:13:11 +0000 Subject: [PATCH 3/8] Bugfix: Check range of number values Ensure they survive the round-trip from double to their native type and (implicitly) back --- blkmaker_jansson.c | 45 ++++++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/blkmaker_jansson.c b/blkmaker_jansson.c index 08809e5..d374a14 100644 --- a/blkmaker_jansson.c +++ b/blkmaker_jansson.c @@ -8,6 +8,7 @@ #define _BSD_SOURCE #define _DEFAULT_SOURCE +#include #include #include @@ -105,17 +106,27 @@ err: return "Error decoding '" #key "'"; \ } while(0) -#define GETNUM(key) do { \ +#define GETNUM(key, type) do { \ GET(key, number); \ - tmpl->key = json_number_value(v); \ + const double tmpd = json_number_value(v); \ + const type tmp = tmpd; \ + if (tmpd != tmp) { \ + return "Invalid number value for '" #key "'"; \ + } \ + tmpl->key = tmp; \ } while(0) -#define GETNUM_O2(key, skey) do { \ - if ((v = json_object_get(json, #skey)) && json_is_number(v)) \ - tmpl->key = json_number_value(v); \ +#define GETNUM_O2(key, skey, type) do { \ + if ((v = json_object_get(json, #skey)) && json_is_number(v)) { \ + const double tmpd = json_number_value(v); \ + const type tmp = tmpd; \ + if (tmpd == tmp) { \ + tmpl->key = tmp; \ + } \ + } \ } while(0) -#define GETNUM_O(key) GETNUM_O2(key, key) +#define GETNUM_O(key, type) GETNUM_O2(key, key, type) #define GETSTR(key, skey) do { \ if ((v = json_object_get(json, #key)) && json_is_string(v)) \ @@ -181,23 +192,23 @@ const char *blktmpl_add_jansson(blktemplate_t *tmpl, const json_t *json, time_t GETHEX(bits, diffbits); my_flip(tmpl->diffbits, 4); - GETNUM(curtime); - GETNUM(height); + GETNUM(curtime, blktime_t); + GETNUM(height, blkheight_t); GETHEX(previousblockhash, prevblk); my_flip(tmpl->prevblk, 32); - GETNUM_O(sigoplimit); - GETNUM_O(sizelimit); - GETNUM(version); + GETNUM_O(sigoplimit, unsigned short); + GETNUM_O(sizelimit, unsigned long); + GETNUM(version, uint32_t); - GETNUM_O2(cbvalue, coinbasevalue); + GETNUM_O2(cbvalue, coinbasevalue, uint64_t); GETSTR(workid, workid); - GETNUM_O(expires); - GETNUM_O(maxtime); - GETNUM_O(maxtimeoff); - GETNUM_O(mintime); - GETNUM_O(mintimeoff); + GETNUM_O(expires, int16_t); + GETNUM_O(maxtime, blktime_t); + GETNUM_O(maxtimeoff, blktime_diff_t); + GETNUM_O(mintime, blktime_t); + GETNUM_O(mintimeoff, blktime_diff_t); GETSTR(longpollid, lp.id); GETSTR(longpolluri, lp.uri); From 12db22114ddd27c63c885ca74bffa2ba3a7ea342 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Tue, 26 Jul 2016 00:31:45 +0000 Subject: [PATCH 4/8] API break: Represent unknown txn {dependscount,fee_,sigops_} as -1 instead of 0 Also renamed the fields to break code relying on old interpretation --- blkmaker.c | 5 +++-- blkmaker_jansson.c | 6 ++++-- blktemplate.c | 21 +++++++++++++++++---- blktemplate.h | 9 ++++++--- private.h | 3 --- 5 files changed, 30 insertions(+), 14 deletions(-) diff --git a/blkmaker.c b/blkmaker.c index 98bc7cc..85a17ab 100644 --- a/blkmaker.c +++ b/blkmaker.c @@ -125,19 +125,20 @@ uint64_t blkmk_init_generation3(blktemplate_t * const tmpl, const void * const s return 0; } - struct blktxn_t *txn = calloc(1, sizeof(*tmpl->cbtxn)); + struct blktxn_t *txn = malloc(sizeof(*tmpl->cbtxn)); if (!txn) { free(data); return 0; } + blktxn_init(txn); txn->data = data; txn->datasz = off; if (tmpl->cbtxn) { - _blktxn_free(tmpl->cbtxn); + blktxn_clean(tmpl->cbtxn); free(tmpl->cbtxn); } tmpl->cbtxn = txn; diff --git a/blkmaker_jansson.c b/blkmaker_jansson.c index e5322fa..7018351 100644 --- a/blkmaker_jansson.c +++ b/blkmaker_jansson.c @@ -142,6 +142,8 @@ static const char *parse_txn(struct blktxn_t *txn, json_t *txnj) { json_t *vv; + blktxn_init(txn); + if (!((vv = json_object_get(txnj, "data")) && json_is_string(vv))) return "Missing or invalid type for transaction data"; const char *hexdata = json_string_value(vv); @@ -224,7 +226,7 @@ const char *blktmpl_add_jansson(blktemplate_t *tmpl, const json_t *json, time_t v = json_object_get(json, "transactions"); size_t txns = tmpl->txncount = json_array_size(v); - tmpl->txns = calloc(txns, sizeof(*tmpl->txns)); + tmpl->txns = malloc(txns * sizeof(*tmpl->txns)); tmpl->txns_datasz = 0; for (size_t i = 0; i < txns; ++i) { @@ -237,7 +239,7 @@ const char *blktmpl_add_jansson(blktemplate_t *tmpl, const json_t *json, time_t if ((v = json_object_get(json, "coinbasetxn")) && json_is_object(v)) { - tmpl->cbtxn = calloc(1, sizeof(*tmpl->cbtxn)); + tmpl->cbtxn = malloc(sizeof(*tmpl->cbtxn)); if ((s = parse_txn(tmpl->cbtxn, v))) return s; } diff --git a/blktemplate.c b/blktemplate.c index 055cc69..d39bd74 100644 --- a/blktemplate.c +++ b/blktemplate.c @@ -58,6 +58,20 @@ gbt_capabilities_t blktmpl_getcapability(const char *n) { return 0; } +void blktxn_init(struct blktxn_t * const txn) { + txn->data = NULL; + txn->datasz = 0; + txn->hash = NULL; + txn->hash_ = NULL; + + txn->dependscount = -1; + txn->depends = NULL; + + txn->fee_ = -1; + txn->required = false; + txn->sigops_ = -1; +} + blktemplate_t *blktmpl_create() { blktemplate_t *tmpl; tmpl = calloc(1, sizeof(*tmpl)); @@ -94,13 +108,12 @@ bool blktmpl_get_submitold(blktemplate_t *tmpl) { return tmpl->submitold; } -void _blktxn_free(struct blktxn_t *bt) { +void blktxn_clean(struct blktxn_t * const bt) { free(bt->data); free(bt->hash); free(bt->hash_); free(bt->depends); } -#define blktxn_free _blktxn_free static void blkaux_clean(struct blkaux_t * const aux) { @@ -110,11 +123,11 @@ void blkaux_clean(struct blkaux_t * const aux) { void blktmpl_free(blktemplate_t *tmpl) { for (unsigned long i = 0; i < tmpl->txncount; ++i) - blktxn_free(&tmpl->txns[i]); + blktxn_clean(&tmpl->txns[i]); free(tmpl->txns); if (tmpl->cbtxn) { - blktxn_free(tmpl->cbtxn); + blktxn_clean(tmpl->cbtxn); free(tmpl->cbtxn); } free(tmpl->_mrklbranch); diff --git a/blktemplate.h b/blktemplate.h index c7a3abf..e675bee 100644 --- a/blktemplate.h +++ b/blktemplate.h @@ -33,12 +33,12 @@ struct blktxn_t { // NOTE: The byte order of hash is backward; use hash_ instead txnhash_t *hash; - signed long dependcount; + signed long dependscount; unsigned long *depends; - uint64_t fee; + int64_t fee_; bool required; - int16_t sigops; + int16_t sigops_; txnhash_t *hash_; }; @@ -141,6 +141,9 @@ typedef struct { unsigned long txns_datasz; } blktemplate_t; +extern void blktxn_init(struct blktxn_t *); +extern void blktxn_clean(struct blktxn_t *); + extern blktemplate_t *blktmpl_create(); extern uint32_t blktmpl_addcaps(const blktemplate_t *); extern const struct blktmpl_longpoll_req *blktmpl_get_longpoll(blktemplate_t *); diff --git a/private.h b/private.h index 550c35d..6080ec2 100644 --- a/private.h +++ b/private.h @@ -11,9 +11,6 @@ extern bool _blkmk_dblsha256(void *hash, const void *data, size_t datasz); extern bool blkmk_sample_data_(blktemplate_t *, uint8_t *, unsigned int dataid); extern char *blkmk_assemble_submission2_(blktemplate_t *, const unsigned char *data, const void *extranonce, size_t extranoncesz, unsigned int dataid, blknonce_t nonce, bool foreign); -// blktemplate.c -extern void _blktxn_free(struct blktxn_t *); - // hex.c extern void _blkmk_bin2hex(char *out, const void *data, size_t datasz); extern bool _blkmk_hex2bin(void *o, const char *x, size_t len); From 4babc68a5f80e5082b6ed58024378cad192b1be8 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Tue, 26 Jul 2016 00:45:48 +0000 Subject: [PATCH 5/8] Parse transaction depends list --- blkmaker_jansson.c | 42 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/blkmaker_jansson.c b/blkmaker_jansson.c index 7018351..ba710b3 100644 --- a/blkmaker_jansson.c +++ b/blkmaker_jansson.c @@ -8,6 +8,7 @@ #define _BSD_SOURCE #define _DEFAULT_SOURCE +#include #include #include #include @@ -139,7 +140,7 @@ err: static void my_flip(void *, size_t); static -const char *parse_txn(struct blktxn_t *txn, json_t *txnj) { +const char *parse_txn(struct blktxn_t *txn, json_t *txnj, size_t my_tx_index) { json_t *vv; blktxn_init(txn); @@ -166,7 +167,40 @@ const char *parse_txn(struct blktxn_t *txn, json_t *txnj) { my_flip(*txn->hash_, sizeof(*txn->hash_)); } - // TODO: dependcount/depends, fee, required, sigops + if ((vv = json_object_get(txnj, "depends")) && json_is_array(vv)) { + size_t depcount = json_array_size(vv); + if (depcount <= LONG_MAX) { + json_t *v; + long i; + double f; + unsigned long ul; + + txn->depends = malloc(sizeof(*txn->depends) * depcount); + for (i = 0; i < depcount; ++i) { + v = json_array_get(vv, i); + if (!json_is_number(v)) { + break; + } + f = json_number_value(v); + ul = f; + if (f != ul || ul >= my_tx_index) { + // Out of range for storage type, fractional number, forward dependency, etc + break; + } + txn->depends[i] = ul; + } + if (i != depcount) { + // We failed somewhere + free(txn->depends); + txn->depends = NULL; + } else { + // Success, finish up with storing the count + txn->dependscount = depcount; + } + } + } + + // TODO: fee, required, sigops return NULL; } @@ -231,7 +265,7 @@ const char *blktmpl_add_jansson(blktemplate_t *tmpl, const json_t *json, time_t for (size_t i = 0; i < txns; ++i) { struct blktxn_t * const txn = &tmpl->txns[i]; - if ((s = parse_txn(txn, json_array_get(v, i)))) { + if ((s = parse_txn(txn, json_array_get(v, i), i + 1))) { return s; } tmpl->txns_datasz += txn->datasz; @@ -240,7 +274,7 @@ const char *blktmpl_add_jansson(blktemplate_t *tmpl, const json_t *json, time_t if ((v = json_object_get(json, "coinbasetxn")) && json_is_object(v)) { tmpl->cbtxn = malloc(sizeof(*tmpl->cbtxn)); - if ((s = parse_txn(tmpl->cbtxn, v))) + if ((s = parse_txn(tmpl->cbtxn, v, 0))) return s; } From b05c2c50de4435ebe64a02292bc94e5831796658 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Tue, 26 Jul 2016 00:48:12 +0000 Subject: [PATCH 6/8] Parse transaction fee --- blkmaker_jansson.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/blkmaker_jansson.c b/blkmaker_jansson.c index ba710b3..6a4e0e4 100644 --- a/blkmaker_jansson.c +++ b/blkmaker_jansson.c @@ -200,7 +200,18 @@ const char *parse_txn(struct blktxn_t *txn, json_t *txnj, size_t my_tx_index) { } } - // TODO: fee, required, sigops + if ((vv = json_object_get(txnj, "fee")) && json_is_number(vv)) { + double f; + int64_t i64; + + f = json_number_value(vv); + i64 = f; + if (i64 == f && i64 >= 0) { + txn->fee_ = i64; + } + } + + // TODO: required, sigops return NULL; } From ba398a34e72726cc244e2b17bdb2f9a6d31651ae Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Tue, 26 Jul 2016 00:48:55 +0000 Subject: [PATCH 7/8] Parse transaction required-flag --- blkmaker_jansson.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/blkmaker_jansson.c b/blkmaker_jansson.c index 6a4e0e4..940a14c 100644 --- a/blkmaker_jansson.c +++ b/blkmaker_jansson.c @@ -211,7 +211,11 @@ const char *parse_txn(struct blktxn_t *txn, json_t *txnj, size_t my_tx_index) { } } - // TODO: required, sigops + if ((vv = json_object_get(txnj, "required")) && json_is_true(vv)) { + txn->required = true; + } + + // TODO: sigops return NULL; } From 56187b67106c37450fdd89f6bacd4ce5a9142f0c Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Tue, 26 Jul 2016 00:50:03 +0000 Subject: [PATCH 8/8] Parse transaction sigops --- blkmaker_jansson.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/blkmaker_jansson.c b/blkmaker_jansson.c index 940a14c..390b08a 100644 --- a/blkmaker_jansson.c +++ b/blkmaker_jansson.c @@ -215,7 +215,13 @@ const char *parse_txn(struct blktxn_t *txn, json_t *txnj, size_t my_tx_index) { txn->required = true; } - // TODO: sigops + if ((vv = json_object_get(txnj, "sigops")) && json_is_number(vv)) { + const double f = json_number_value(vv); + int16_t i16 = f; + if (i16 == f && i16 >= 0) { + txn->sigops_ = i16; + } + } return NULL; }