Merge branch 'master' into segwit
This commit is contained in:
@@ -180,19 +180,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;
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
#define _BSD_SOURCE
|
||||
#define _DEFAULT_SOURCE
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -99,17 +101,27 @@ err:
|
||||
return "Error decoding '" #key "'"; \
|
||||
} while(0)
|
||||
|
||||
#define GETNUM(key) do { \
|
||||
#define GETNUM(key, type) do { \
|
||||
GET(key, number); \
|
||||
tmpl->key = json_integer_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_integer_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)) \
|
||||
@@ -128,9 +140,11 @@ 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);
|
||||
|
||||
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);
|
||||
@@ -172,7 +186,61 @@ const char *parse_txn(struct blktxn_t *txn, json_t *txnj) {
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if ((vv = json_object_get(txnj, "required")) && json_is_true(vv)) {
|
||||
txn->required = true;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -208,23 +276,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);
|
||||
@@ -232,12 +300,12 @@ 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)
|
||||
{
|
||||
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;
|
||||
@@ -245,8 +313,8 @@ 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));
|
||||
if ((s = parse_txn(tmpl->cbtxn, v)))
|
||||
tmpl->cbtxn = malloc(sizeof(*tmpl->cbtxn));
|
||||
if ((s = parse_txn(tmpl->cbtxn, v, 0)))
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
@@ -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,14 +108,13 @@ 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);
|
||||
free(bt->txid);
|
||||
}
|
||||
#define blktxn_free _blktxn_free
|
||||
|
||||
static
|
||||
void blkaux_clean(struct blkaux_t * const aux) {
|
||||
@@ -111,11 +124,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);
|
||||
|
||||
@@ -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_;
|
||||
int32_t weight;
|
||||
|
||||
txnhash_t *hash_;
|
||||
@@ -146,6 +146,9 @@ typedef struct {
|
||||
libblkmaker_hash_t *_witnessmrklroot;
|
||||
} 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 *);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user