|
|
@ -10,11 +10,11 @@ |
|
|
|
|
|
|
|
|
|
|
|
#include "ckdb.h" |
|
|
|
#include "ckdb.h" |
|
|
|
|
|
|
|
|
|
|
|
//#include <curl/curl.h>
|
|
|
|
#define BTCKEY ((const char *)"result") |
|
|
|
|
|
|
|
|
|
|
|
#define GETBLOCKHASHCMD "getblockhash" |
|
|
|
#define GETBLOCKHASHCMD "getblockhash" |
|
|
|
#define GETBLOCKHASH "{\"method\":\"" GETBLOCKHASHCMD "\",\"params\":[%d],\"id\":1}" |
|
|
|
#define GETBLOCKHASH "{\"method\":\"" GETBLOCKHASHCMD "\",\"params\":[%d],\"id\":1}" |
|
|
|
#define GETBLOCKHASHKEY ((const char *)"result") |
|
|
|
#define GETBLOCKHASHKEY NULL |
|
|
|
|
|
|
|
|
|
|
|
#define GETBLOCKCMD "getblock" |
|
|
|
#define GETBLOCKCMD "getblock" |
|
|
|
#define GETBLOCK "{\"method\":\"" GETBLOCKCMD "\",\"params\":[\"%s\"],\"id\":1}" |
|
|
|
#define GETBLOCK "{\"method\":\"" GETBLOCKCMD "\",\"params\":[\"%s\"],\"id\":1}" |
|
|
@ -145,13 +145,12 @@ static char *_btc_io(__maybe_unused const char *cmd, char *json, WHERE_FFL_ARGS) |
|
|
|
return res; |
|
|
|
return res; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static char *single_decode_str(char *ans, const char *cmd, const char *key) |
|
|
|
static json_t *single_decode(char *ans, const char *cmd, const char *key) |
|
|
|
{ |
|
|
|
{ |
|
|
|
json_t *json_data, *json_ob; |
|
|
|
json_t *json_data, *btc_ob, *json_ob = NULL; |
|
|
|
json_error_t err_val; |
|
|
|
json_error_t err_val; |
|
|
|
const char *json_str; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (ans) { |
|
|
|
if (ans && *ans) { |
|
|
|
json_data = json_loads(ans, JSON_DISABLE_EOF_CHECK, &err_val); |
|
|
|
json_data = json_loads(ans, JSON_DISABLE_EOF_CHECK, &err_val); |
|
|
|
if (!json_data) { |
|
|
|
if (!json_data) { |
|
|
|
char *text = safe_text(ans); |
|
|
|
char *text = safe_text(ans); |
|
|
@ -163,62 +162,76 @@ static char *single_decode_str(char *ans, const char *cmd, const char *key) |
|
|
|
err_val.text, text); |
|
|
|
err_val.text, text); |
|
|
|
free(text); |
|
|
|
free(text); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
json_ob = json_object_get(json_data, key); |
|
|
|
btc_ob = json_object_get(json_data, BTCKEY); |
|
|
|
if (!json_ob) { |
|
|
|
if (!btc_ob) { |
|
|
|
char *text = safe_text(ans); |
|
|
|
char *text = safe_text(ans); |
|
|
|
LOGERR("%s() Json %s reply missing key %s " |
|
|
|
LOGERR("%s() Json %s reply missing main key %s " |
|
|
|
"ans='%s'", |
|
|
|
"ans='%s'", |
|
|
|
__func__, cmd, key, text); |
|
|
|
__func__, cmd, key, text); |
|
|
|
free(text); |
|
|
|
free(text); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
if (!json_is_string(json_ob)) { |
|
|
|
if (key == NULL) |
|
|
|
char *text = safe_text(ans); |
|
|
|
json_ob = btc_ob; |
|
|
|
LOGERR("%s() Json %s key %s " |
|
|
|
else { |
|
|
|
"not a string ans='%s'", |
|
|
|
json_ob = json_object_get(btc_ob, key); |
|
|
|
__func__, cmd, key, text); |
|
|
|
if (!json_ob) { |
|
|
|
free(text); |
|
|
|
char *text = safe_text(ans); |
|
|
|
} else { |
|
|
|
LOGERR("%s() Json %s reply missing " |
|
|
|
json_str = json_string_value(json_ob); |
|
|
|
"sub-key %s ans='%s'", |
|
|
|
if (json_str) |
|
|
|
__func__, cmd, key, text); |
|
|
|
return strdup(json_str); |
|
|
|
free(text); |
|
|
|
else |
|
|
|
} |
|
|
|
return strdup(EMPTY); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return NULL; |
|
|
|
return json_ob; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static int64_t single_decode_int(char *ans, const char *cmd, const char *key) |
|
|
|
static char *single_decode_str(char *ans, const char *cmd, const char *key) |
|
|
|
{ |
|
|
|
{ |
|
|
|
json_t *json_data, *json_ob; |
|
|
|
const char *json_str; |
|
|
|
json_error_t err_val; |
|
|
|
char *str = NULL; |
|
|
|
|
|
|
|
json_t *json_ob; |
|
|
|
|
|
|
|
|
|
|
|
if (ans) { |
|
|
|
json_ob = single_decode(ans, cmd, key); |
|
|
|
json_data = json_loads(ans, JSON_DISABLE_EOF_CHECK, &err_val); |
|
|
|
if (json_ob) { |
|
|
|
if (!json_data) { |
|
|
|
if (!json_is_string(json_ob)) { |
|
|
|
char *text = safe_text(ans); |
|
|
|
char *text = safe_text(ans); |
|
|
|
LOGERR("%s() Json %s decode error " |
|
|
|
if (!key) |
|
|
|
"json_err=(%d:%d:%d)%s:%s ans='%s'", |
|
|
|
key = BTCKEY; |
|
|
|
__func__, cmd, |
|
|
|
LOGERR("%s() Json %s key %s " |
|
|
|
err_val.line, err_val.column, |
|
|
|
"not a string ans='%s'", |
|
|
|
err_val.position, err_val.source, |
|
|
|
__func__, cmd, key, text); |
|
|
|
err_val.text, text); |
|
|
|
|
|
|
|
free(text); |
|
|
|
free(text); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
json_ob = json_object_get(json_data, key); |
|
|
|
json_str = json_string_value(json_ob); |
|
|
|
if (!json_ob) { |
|
|
|
if (json_str) |
|
|
|
char *text = safe_text(ans); |
|
|
|
str = strdup(json_str); |
|
|
|
LOGERR("%s() Json %s reply missing key %s " |
|
|
|
|
|
|
|
"ans='%s'", |
|
|
|
|
|
|
|
__func__, cmd, key, text); |
|
|
|
|
|
|
|
free(text); |
|
|
|
|
|
|
|
} else |
|
|
|
|
|
|
|
return (int64_t)json_integer_value(json_ob); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return 0; |
|
|
|
return str; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int64_t single_decode_int(char *ans, const char *cmd, const char *key) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
json_t *json_ob; |
|
|
|
|
|
|
|
int64_t val = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
json_ob = single_decode(ans, cmd, key); |
|
|
|
|
|
|
|
if (json_ob) { |
|
|
|
|
|
|
|
if (!json_is_integer(json_ob)) { |
|
|
|
|
|
|
|
char *text = safe_text(ans); |
|
|
|
|
|
|
|
if (!key) |
|
|
|
|
|
|
|
key = BTCKEY; |
|
|
|
|
|
|
|
LOGERR("%s() Json %s key %s " |
|
|
|
|
|
|
|
"not an int ans='%s'", |
|
|
|
|
|
|
|
__func__, cmd, key, text); |
|
|
|
|
|
|
|
free(text); |
|
|
|
|
|
|
|
} else |
|
|
|
|
|
|
|
val = (int64_t)json_integer_value(json_ob); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return val; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static char *btc_blockhash(int32_t height) |
|
|
|
static char *btc_blockhash(int32_t height) |
|
|
@ -234,14 +247,14 @@ static char *btc_blockhash(int32_t height) |
|
|
|
return hash; |
|
|
|
return hash; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static __maybe_unused int32_t btc_confirms(int32_t height) |
|
|
|
static int32_t btc_confirms(char *hash) |
|
|
|
{ |
|
|
|
{ |
|
|
|
char buf[1024]; |
|
|
|
char buf[1024]; |
|
|
|
char *ans; |
|
|
|
char *ans; |
|
|
|
int32_t conf; |
|
|
|
int32_t conf; |
|
|
|
|
|
|
|
|
|
|
|
snprintf(buf, sizeof(buf), GETBLOCKHASH, height); |
|
|
|
snprintf(buf, sizeof(buf), GETBLOCK, hash); |
|
|
|
ans = btc_io(GETBLOCKHASHCMD, buf); |
|
|
|
ans = btc_io(GETBLOCKCMD, buf); |
|
|
|
conf = (int32_t)single_decode_int(ans, GETBLOCKCMD, GETBLOCKCONFKEY); |
|
|
|
conf = (int32_t)single_decode_int(ans, GETBLOCKCMD, GETBLOCKCONFKEY); |
|
|
|
free(ans); |
|
|
|
free(ans); |
|
|
|
return conf; |
|
|
|
return conf; |
|
|
@ -251,7 +264,9 @@ static __maybe_unused int32_t btc_confirms(int32_t height) |
|
|
|
void btc_blockstatus(BLOCKS *blocks) |
|
|
|
void btc_blockstatus(BLOCKS *blocks) |
|
|
|
{ |
|
|
|
{ |
|
|
|
char hash[TXT_BIG+1]; |
|
|
|
char hash[TXT_BIG+1]; |
|
|
|
|
|
|
|
char height_str[32]; |
|
|
|
char *blockhash; |
|
|
|
char *blockhash; |
|
|
|
|
|
|
|
int32_t confirms; |
|
|
|
size_t len; |
|
|
|
size_t len; |
|
|
|
tv_t now; |
|
|
|
tv_t now; |
|
|
|
bool ok; |
|
|
|
bool ok; |
|
|
@ -289,16 +304,14 @@ void btc_blockstatus(BLOCKS *blocks) |
|
|
|
return; |
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
if (strcmp(blockhash, hash) != 0) { |
|
|
|
if (strcmp(blockhash, hash) != 0) { |
|
|
|
char height_tmp[32]; |
|
|
|
snprintf(height_str, sizeof(height_str), "%d", blocks->height); |
|
|
|
|
|
|
|
|
|
|
|
snprintf(height_tmp, sizeof(height_tmp), "%d", blocks->height); |
|
|
|
|
|
|
|
LOGERR("%s() flagging block %d(%s) as %s pool=%s btc=%s", |
|
|
|
LOGERR("%s() flagging block %d(%s) as %s pool=%s btc=%s", |
|
|
|
__func__, |
|
|
|
__func__, |
|
|
|
blocks->height, height_tmp, |
|
|
|
blocks->height, height_str, |
|
|
|
blocks_confirmed(BLOCKS_ORPHAN_STR), |
|
|
|
blocks_confirmed(BLOCKS_ORPHAN_STR), |
|
|
|
hash, blockhash); |
|
|
|
hash, blockhash); |
|
|
|
|
|
|
|
|
|
|
|
ok = blocks_add(NULL, height_tmp, |
|
|
|
ok = blocks_add(NULL, height_str, |
|
|
|
blocks->blockhash, |
|
|
|
blocks->blockhash, |
|
|
|
BLOCKS_ORPHAN_STR, |
|
|
|
BLOCKS_ORPHAN_STR, |
|
|
|
EMPTY, EMPTY, EMPTY, EMPTY, |
|
|
|
EMPTY, EMPTY, EMPTY, EMPTY, |
|
|
@ -312,5 +325,24 @@ void btc_blockstatus(BLOCKS *blocks) |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// confirms = btc_confirms(hash);
|
|
|
|
confirms = btc_confirms(hash); |
|
|
|
|
|
|
|
if (confirms >= BLOCKS_42_VALUE) { |
|
|
|
|
|
|
|
snprintf(height_str, sizeof(height_str), "%d", blocks->height); |
|
|
|
|
|
|
|
LOGERR("%s() flagging block %d(%s) as %s confirms=%d(%d)", |
|
|
|
|
|
|
|
__func__, |
|
|
|
|
|
|
|
blocks->height, height_str, |
|
|
|
|
|
|
|
blocks_confirmed(BLOCKS_42_STR), |
|
|
|
|
|
|
|
confirms, BLOCKS_42_VALUE); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ok = blocks_add(NULL, height_str, |
|
|
|
|
|
|
|
blocks->blockhash, |
|
|
|
|
|
|
|
BLOCKS_42_STR, |
|
|
|
|
|
|
|
EMPTY, EMPTY, EMPTY, EMPTY, |
|
|
|
|
|
|
|
EMPTY, EMPTY, EMPTY, EMPTY, |
|
|
|
|
|
|
|
by_default, (char *)__func__, inet_default, |
|
|
|
|
|
|
|
&now, false, id_default, NULL); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!ok) |
|
|
|
|
|
|
|
blocks->ignore = true; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|