Browse Source

Add helper functions for getting best block heights/hashes

master
Con Kolivas 11 years ago
parent
commit
f2dc9c796f
  1. 98
      src/bitcoin.c
  2. 3
      src/bitcoin.h

98
src/bitcoin.c

@ -16,6 +16,8 @@
static const char *b58chars = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; static const char *b58chars = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
/* 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)
{ {
json_t *val, *res_val, *valid_val; json_t *val, *res_val, *valid_val;
@ -76,6 +78,8 @@ out:
return ret; return ret;
} }
/* Distill down a set of transactions into an efficient tree arrangement for
* stratum messages and fast work assembly. */
static bool gbt_merkle_bins(gbtbase_t *gbt, json_t *transaction_arr) static bool gbt_merkle_bins(gbtbase_t *gbt, json_t *transaction_arr)
{ {
int i, j, binleft, binlen; int i, j, binleft, binlen;
@ -166,6 +170,9 @@ static bool gbt_merkle_bins(gbtbase_t *gbt, json_t *transaction_arr)
static const char *gbt_req = "{\"method\": \"getblocktemplate\", \"params\": [{\"capabilities\": [\"coinbasetxn\", \"workid\", \"coinbase/append\"]}]}\n"; static const char *gbt_req = "{\"method\": \"getblocktemplate\", \"params\": [{\"capabilities\": [\"coinbasetxn\", \"workid\", \"coinbase/append\"]}]}\n";
/* Request getblocktemplate from bitcoind already connected with a connsock_t
* and then summarise the information to the most efficient set of data
* required to assemble a mining template, storing it in a gbtbase_t structure */
bool gen_gbtbase(connsock_t *cs, gbtbase_t *gbt) bool gen_gbtbase(connsock_t *cs, gbtbase_t *gbt)
{ {
json_t *transaction_arr, *coinbase_aux, *res_val, *val; json_t *transaction_arr, *coinbase_aux, *res_val, *val;
@ -188,7 +195,7 @@ bool gen_gbtbase(connsock_t *cs, gbtbase_t *gbt)
res_val = json_object_get(val, "result"); res_val = json_object_get(val, "result");
if (!res_val) { if (!res_val) {
LOGWARNING("Failed to get result in json response to getblocktemplate"); LOGWARNING("Failed to get result in json response to getblocktemplate");
return ret; goto out;
} }
previousblockhash = json_string_value(json_object_get(res_val, "previousblockhash")); previousblockhash = json_string_value(json_object_get(res_val, "previousblockhash"));
@ -224,7 +231,92 @@ bool gen_gbtbase(connsock_t *cs, gbtbase_t *gbt)
gbt->height = height; gbt->height = height;
out: out:
if (res_val) json_decref(val);
json_decref(res_val); return ret;
}
static const char *blockcount_req = "{\"method\": \"getblockcount\"}\n";
/* Request getblockcount from bitcoind, returning the count or -1 if the call
* fails. */
int get_blockcount(connsock_t *cs)
{
json_t *val, *res_val;
int ret = -1;
val = json_rpc_call(cs, blockcount_req);
if (!val) {
LOGWARNING("Failed to get valid json response to getblockcount");
return ret;
}
res_val = json_object_get(val, "result");
if (!res_val) {
LOGWARNING("Failed to get result in json response to getblockcount");
goto out;
}
ret = json_integer_value(res_val);
out:
json_decref(val);
return ret;
}
/* Request getblockhash from bitcoind for height, returning a freshly allocated
* string or NULL if it fails. */
char *get_blockhash(connsock_t *cs, int height)
{
char rpc_req[128], *ret = NULL;
json_t *val, *res_val;
const char *res_ret;
sprintf(rpc_req, "{\"method\": \"getblockhash\", \"params\": [%d]}\n", height);
val = json_rpc_call(cs, rpc_req);
if (!val) {
LOGWARNING("Failed to get valid json response to getblockhash");
return ret;
}
res_val = json_object_get(val, "result");
if (!res_val) {
LOGWARNING("Failed to get result in json response to getblockhash");
goto out;
}
res_ret = json_string_value(res_val);
if (!res_ret || !strlen(res_ret)) {
LOGWARNING("Got null string in result to getblockhash");
goto out;
}
ret = strdup(res_ret);
out:
json_decref(val);
return ret;
}
static const char *bestblockhash_req = "{\"method\": \"getbestblockhash\"}\n";
/* Request getbestblockhash from bitcoind, returning a freshly allocated
* string or NULL if it fails. bitcoind 0.9+ only */
char *get_bestblockhash(connsock_t *cs)
{
json_t *val, *res_val;
const char *res_ret;
char *ret = NULL;
val = json_rpc_call(cs, bestblockhash_req);
if (!val) {
LOGWARNING("Failed to get valid json response to getbestblockhash");
return ret;
}
res_val = json_object_get(val, "result");
if (!res_val) {
LOGWARNING("Failed to get result in json response to getbestblockhash");
goto out;
}
res_ret = json_string_value(res_val);
if (!res_ret || !strlen(res_ret)) {
LOGWARNING("Got null string in result to getbestblockhash");
goto out;
}
ret = strdup(res_ret);
out:
json_decref(val);
return ret; return ret;
} }

3
src/bitcoin.h

@ -12,5 +12,8 @@
bool validate_address(connsock_t *cs, const char *address); bool validate_address(connsock_t *cs, const char *address);
bool gen_gbtbase(connsock_t *cs, gbtbase_t *gbt); bool gen_gbtbase(connsock_t *cs, gbtbase_t *gbt);
int get_blockcount(connsock_t *cs);
char *get_blockhash(connsock_t *cs, int height);
char *get_bestblockhash(connsock_t *cs);
#endif /* BITCOIN_H */ #endif /* BITCOIN_H */

Loading…
Cancel
Save