Browse Source

Fix tx history crash for BTC/LTC. Disable support for QTUM, BTX, CRW.

blackjok3r
Artem Pikulin 6 years ago
parent
commit
abc79a5acb
  1. 98
      iguana/exchanges/LP_socket.c

98
iguana/exchanges/LP_socket.c

@ -1229,9 +1229,57 @@ int history_item_cmp(struct LP_tx_history_item *item1, struct LP_tx_history_item
return(item1->time < item2->time); return(item1->time < item2->time);
} }
void LP_electrum_get_tx_until_success(struct iguana_info *coin, char *tx_hash, cJSON **res) {
cJSON *params = cJSON_CreateArray();
jaddistr(params, tx_hash);
jaddi(params, cJSON_CreateBool(cJSON_True));
while(1) {
electrum_jsonarg(coin->symbol, coin->electrum, res, "blockchain.transaction.get", params,
ELECTRUM_TIMEOUT);
if (jobj(*res, "error") != NULL) {
printf("Error getting electrum tx %s %s %s\n", coin->symbol, jstri(params, 0), jprint(*res, 1));
*res = cJSON_CreateObject();
sleep(5);
continue;
} else {
break;
}
}
free_json(params);
}
char *LP_get_address_from_tx_out(cJSON *tx_out) {
cJSON *script_pub_key = jobj(tx_out, "scriptPubKey");
if (script_pub_key == 0) {
printf("No scriptPubKey on tx_out: %s\n", jprint(tx_out, 0));
return 0;
}
struct cJSON *addresses = jobj(script_pub_key, "addresses");
if (addresses == 0) {
printf("No addresses on tx_out: %s\n", jprint(tx_out, 0));
return NULL;
}
if (!is_cJSON_Array(addresses)) {
printf("Addresses are not array on tx out: %s\n", jprint(tx_out, 0));
return NULL;
}
if (cJSON_GetArraySize(addresses) > 1) {
printf("Addresses array size is > 1 on tx out: %s\n", jprint(tx_out, 0));
return NULL;
}
return jstri(addresses, 0);
}
void LP_electrum_txhistory_loop(void *_coin) void LP_electrum_txhistory_loop(void *_coin)
{ {
struct iguana_info *coin = _coin; struct iguana_info *coin = _coin;
if (strcmp(coin->symbol, "QTUM") == 0 || strcmp(coin->symbol, "CRW") == 0 || strcmp(coin->symbol, "BTX") == 0) {
printf("Tx history loop doesn't support QTUM, CRW and BTX! yet\n");
return;
}
while (coin != NULL && coin->electrum != NULL && coin->inactive == 0) { while (coin != NULL && coin->electrum != NULL && coin->inactive == 0) {
cJSON *history = cJSON_CreateObject(); cJSON *history = cJSON_CreateObject();
if (strcmp(coin->symbol, "BCH") == 0) { if (strcmp(coin->symbol, "BCH") == 0) {
@ -1242,7 +1290,7 @@ void LP_electrum_txhistory_loop(void *_coin)
ELECTRUM_TIMEOUT); ELECTRUM_TIMEOUT);
} }
if (jobj(history, "error") != NULL) { if (jobj(history, "error") != NULL) {
printf("Error getting electrum history %s\n", jprint(history, 1)); printf("Error getting electrum history of coin %s %s\n", coin->symbol, jprint(history, 1));
sleep(10); sleep(10);
continue; continue;
} }
@ -1251,6 +1299,7 @@ void LP_electrum_txhistory_loop(void *_coin)
cJSON *history_item = jitem(history, i); cJSON *history_item = jitem(history, i);
cJSON *tx_item = cJSON_CreateObject(); cJSON *tx_item = cJSON_CreateObject();
char *tx_hash = jstr(history_item, "tx_hash"); char *tx_hash = jstr(history_item, "tx_hash");
LP_electrum_get_tx_until_success(coin, tx_hash, &tx_item);
struct LP_tx_history_item *iter; struct LP_tx_history_item *iter;
int found = 0; int found = 0;
int confirmed = 0; int confirmed = 0;
@ -1277,42 +1326,47 @@ void LP_electrum_txhistory_loop(void *_coin)
continue; continue;
} }
cJSON *params = cJSON_CreateArray();
jaddistr(params, tx_hash);
jaddi(params, cJSON_CreateBool(cJSON_True));
while(1) {
electrum_jsonarg(coin->symbol, coin->electrum, &tx_item, "blockchain.transaction.get", params,
ELECTRUM_TIMEOUT);
if (jobj(tx_item, "error") != NULL) {
printf("Error getting electrum tx %s %s\n", jstri(params, 0), jprint(tx_item, 1));
tx_item = cJSON_CreateObject();
sleep(5);
continue;
} else {
break;
}
}
free_json(params);
if (!found) { if (!found) {
strcpy(item->txid, jstr(tx_item, "txid")); strcpy(item->txid, jstr(tx_item, "txid"));
// receive by default, but if at least 1 vin contains our address the category is send // receive by default, but if at least 1 vin contains our address the category is send
strcpy(item->category, "receive"); strcpy(item->category, "receive");
cJSON *vin = jobj(tx_item, "vin"); cJSON *vin = jobj(tx_item, "vin");
cJSON *prev_tx_item = NULL;
for (int j = 0; j < cJSON_GetArraySize(vin); j++) { for (int j = 0; j < cJSON_GetArraySize(vin); j++) {
cJSON *vin_item = jitem(vin, j); cJSON *vin_item = jitem(vin, j);
char *address = jstr(vin_item, "address");
if (address != NULL) {
if (strcmp(coin->smartaddr, jstr(vin_item, "address")) == 0) { if (strcmp(coin->smartaddr, jstr(vin_item, "address")) == 0) {
strcpy(item->category, "send"); strcpy(item->category, "send");
break; break;
} }
} else {
// At least BTC and LTC doesn't have an address field for Vins.
// Need to get previous tx and check the output
cJSON *params = cJSON_CreateArray();
// some transactions use few vouts of one prev tx so we can reuse it
if (prev_tx_item == 0 || strcmp(jstr(prev_tx_item, "txid"), jstr(vin_item, "txid")) != 0) {
if (prev_tx_item != 0) {
free_json(prev_tx_item);
prev_tx_item = NULL;
}
LP_electrum_get_tx_until_success(coin, jstr(vin_item, "txid"), &prev_tx_item);
}
char *vout_address = LP_get_address_from_tx_out(jitem(jobj(prev_tx_item, "vout"), jint(vin_item, "vout")));
if (strcmp(coin->smartaddr, vout_address) == 0) {
strcpy(item->category, "send");
break;
}
free_json(params);
}
} }
int size = 0; int size = 0;
cJSON *vout = jarray(&size, tx_item, "vout"); cJSON *vout = jarray(&size, tx_item, "vout");
for (int k = 0; k < size; k++) { for (int k = 0; k < size; k++) {
cJSON *vout_item = jitem(vout, k); cJSON *vout_item = jitem(vout, k);
int addresses_size = 0; char *vout_address = LP_get_address_from_tx_out(vout_item);
cJSON *addresses = jarray(&addresses_size, jobj(vout_item, "scriptPubKey"), "addresses"); if (vout_address != 0) {
for (int z = 0; z < addresses_size; z++) { if (strcmp(coin->smartaddr, vout_address) == 0) {
if (strcmp(coin->smartaddr, jstri(addresses, z)) == 0) {
if (strcmp(item->category, "receive") == 0) { if (strcmp(item->category, "receive") == 0) {
item->amount += jdouble(vout_item, "value"); item->amount += jdouble(vout_item, "value");
} }
@ -1327,7 +1381,7 @@ void LP_electrum_txhistory_loop(void *_coin)
if (juint(history_item, "height") > 0) { if (juint(history_item, "height") > 0) {
item->time = juint(tx_item, "time"); item->time = juint(tx_item, "time");
strcpy(item->blockhash, jstr(tx_item, "blockhash")); strcpy(item->blockhash, jstr(tx_item, "blockhash"));
item->blockindex = juint(tx_item, "height"); item->blockindex = juint(history_item, "height");
item->blocktime = juint(tx_item, "blocktime"); item->blocktime = juint(tx_item, "blocktime");
} else { } else {
// set current time temporary until confirmed // set current time temporary until confirmed

Loading…
Cancel
Save