|
|
@ -960,10 +960,225 @@ int64_t utxo_value(char *refcoin,char *srcaddr,bits256 txid,int32_t v) |
|
|
|
return(value); |
|
|
|
} |
|
|
|
|
|
|
|
struct addritem { int64_t total,numutxos; char addr[64]; } ADDRESSES[1200]; |
|
|
|
struct claimitem { int64_t total; int32_t numutxos,disputed; char oldaddr[64],destaddr[64],username[64]; } CLAIMS[1200]; |
|
|
|
int32_t verify_vin(char *refcoin,bits256 txid,int32_t v,char *cmpaddr) |
|
|
|
{ |
|
|
|
cJSON *txjson,*vins,*vin; int32_t numvins; char vinaddr[64],str[65]; |
|
|
|
vinaddr[0] = 0; |
|
|
|
if ( (txjson= get_rawtransaction(refcoin,"",txid)) != 0 ) |
|
|
|
{ |
|
|
|
if ( (vins= jarray(&numvins,txjson,"vin")) != 0 && v < numvins ) |
|
|
|
{ |
|
|
|
vin = jitem(vins,v); |
|
|
|
if ( utxo_value(refcoin,vinaddr,jbits256(vin,"txid"),jint(vin,"vout")) > 0 && strcmp(vinaddr,cmpaddr) == 0 ) |
|
|
|
return(0); |
|
|
|
printf("mismatched vinaddr.(%s) vs %s\n",vinaddr,cmpaddr); |
|
|
|
} |
|
|
|
} |
|
|
|
return(-1); |
|
|
|
} |
|
|
|
|
|
|
|
int32_t txid_in_vins(char *refcoin,bits256 txid,bits256 cmptxid) |
|
|
|
{ |
|
|
|
cJSON *txjson,*vins,*vin; int32_t numvins,v,vinvout; bits256 vintxid; char str[65]; |
|
|
|
if ( (txjson= get_rawtransaction(refcoin,"",txid)) != 0 ) |
|
|
|
{ |
|
|
|
if ( (vins= jarray(&numvins,txjson,"vin")) != 0 ) |
|
|
|
{ |
|
|
|
for (v=0; v<numvins; v++) |
|
|
|
{ |
|
|
|
vin = jitem(vins,v); |
|
|
|
vintxid = jbits256(vin,"txid"); |
|
|
|
vinvout = jint(vin,"vout"); |
|
|
|
if ( memcmp(&vintxid,&cmptxid,sizeof(vintxid)) == 0 && vinvout == 0 ) |
|
|
|
{ |
|
|
|
return(0); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return(-1); |
|
|
|
} |
|
|
|
|
|
|
|
void genpayout(char *coinstr,char *destaddr,int32_t amount) |
|
|
|
{ |
|
|
|
char cmd[1024]; |
|
|
|
sprintf(cmd,"curl -s --url \"http://127.0.0.1:7783\" --data \"{\\\"userpass\\\":\\\"$userpass\\\",\\\"method\\\":\\\"withdraw\\\",\\\"coin\\\":\\\"%s\\\",\\\"outputs\\\":[{\\\"%s\\\":%.8f},{\\\"RWXL82m4xnBTg1kk6PuS2xekonu7oEeiJG\\\":0.0002}],\\\"broadcast\\\":1}\"\nsleep 3\n",coinstr,destaddr,dstr(amount+20000)); |
|
|
|
printf("%s",cmd); |
|
|
|
} |
|
|
|
|
|
|
|
bits256 SECONDVIN; int32_t SECONDVOUT; |
|
|
|
|
|
|
|
void genrefund(char *cmd,char *coinstr,bits256 vintxid,char *destaddr,int64_t amount) |
|
|
|
{ |
|
|
|
char str[65],str2[65]; |
|
|
|
sprintf(cmd,"curl -s --url \"http://127.0.0.1:7783\" --data \"{\\\"userpass\\\":\\\"$userpass\\\",\\\"method\\\":\\\"withdraw\\\",\\\"coin\\\":\\\"%s\\\",\\\"onevin\\\":2,\\\"utxotxid\\\":\\\"%s\\\",\\\"utxovout\\\":1,\\\"utxotxid2\\\":\\\"%s\\\",\\\"utxovout2\\\":%d,\\\"outputs\\\":[{\\\"%s\\\":%.8f}],\\\"broadcast\\\":1}\"\nsleep 3\n",coinstr,bits256_str(str,vintxid),bits256_str(str2,SECONDVIN),SECONDVOUT,destaddr,dstr(amount)); |
|
|
|
system(cmd); |
|
|
|
} |
|
|
|
|
|
|
|
struct addritem |
|
|
|
{ |
|
|
|
int64_t total,numutxos; |
|
|
|
char addr[64]; |
|
|
|
|
|
|
|
} ADDRESSES[1200]; |
|
|
|
|
|
|
|
struct claimitem |
|
|
|
{ |
|
|
|
bits256 txid; |
|
|
|
int64_t total,refundvalue; |
|
|
|
int32_t numutxos,disputed,approved; |
|
|
|
char oldaddr[64],destaddr[64],username[64]; |
|
|
|
|
|
|
|
} CLAIMS[10000]; |
|
|
|
|
|
|
|
int32_t NUM_ADDRESSES,NUM_CLAIMS; |
|
|
|
|
|
|
|
int32_t itemvalid(char *refcoin,int64_t *refundedp,int64_t *waitingp,struct claimitem *item) |
|
|
|
{ |
|
|
|
cJSON *curljson,*txids; int32_t i,numtxids; char str[65],str2[65],url[1000],*retstr; bits256 txid; |
|
|
|
*refundedp = *waitingp = 0; |
|
|
|
if ( item->refundvalue < 0 ) |
|
|
|
return(-1); |
|
|
|
sprintf(url,"https://kmd.explorer.dexstats.info/insight-api-komodo/addr/%s",item->destaddr); |
|
|
|
if ( (retstr= send_curl(url,"/tmp/itemvalid")) != 0 ) |
|
|
|
{ |
|
|
|
if ( (curljson= cJSON_Parse(retstr)) != 0 ) |
|
|
|
{ |
|
|
|
if ( (txids= jarray(&numtxids,curljson,"transactions")) != 0 ) |
|
|
|
{ |
|
|
|
for (i=0; i<numtxids; i++) |
|
|
|
{ |
|
|
|
txid = jbits256i(txids,i); |
|
|
|
if ( txid_in_vins(refcoin,txid,item->txid) == 0 ) |
|
|
|
{ |
|
|
|
printf("found item->txid %s inside %s\n",bits256_str(str,item->txid),bits256_str(str2,txid)); |
|
|
|
item->approved = 1; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
free_json(curljson); |
|
|
|
} |
|
|
|
//printf("%s\n",retstr);
|
|
|
|
free(retstr); |
|
|
|
} |
|
|
|
if ( item->approved != 0 ) |
|
|
|
return(1); |
|
|
|
*waitingp = item->refundvalue; |
|
|
|
return(-1); |
|
|
|
} |
|
|
|
|
|
|
|
void scan_claims(int32_t issueflag,char *refcoin,int32_t batchid) |
|
|
|
{ |
|
|
|
char str[65]; int32_t i,num,numstolen=0,numcandidates=0,numinvalids=0,numrefunded=0,numwaiting=0; struct claimitem *item; int64_t batchmin,batchmax,waiting,refunded,possiblerefund=0,possiblestolen = 0,invalidsum=0,totalrefunded=0,waitingsum=0; |
|
|
|
if ( batchid == 0 ) |
|
|
|
{ |
|
|
|
batchmin = 0; |
|
|
|
batchmax = 7 * SATOSHIDEN; |
|
|
|
} |
|
|
|
else if ( batchid == 1 ) |
|
|
|
{ |
|
|
|
batchmin = 7 * SATOSHIDEN; |
|
|
|
batchmax = 777 * SATOSHIDEN; |
|
|
|
} |
|
|
|
else if ( batchid == 2 ) |
|
|
|
{ |
|
|
|
batchmin = 1;//777 * SATOSHIDEN;
|
|
|
|
batchmax = 17777 * SATOSHIDEN; |
|
|
|
} |
|
|
|
else if ( batchid == 3 ) |
|
|
|
{ |
|
|
|
batchmin = 17777 * SATOSHIDEN; |
|
|
|
batchmax = 1000000 * SATOSHIDEN; |
|
|
|
} |
|
|
|
for (i=0; i<NUM_CLAIMS; i++) |
|
|
|
{ |
|
|
|
item = &CLAIMS[i]; |
|
|
|
if ( item->refundvalue < batchmin || item->refundvalue >= batchmax ) |
|
|
|
continue; |
|
|
|
if ( itemvalid(refcoin,&refunded,&waiting,item) < 0 ) |
|
|
|
{ |
|
|
|
if ( refunded != 0 ) |
|
|
|
{ |
|
|
|
numrefunded++; |
|
|
|
totalrefunded += refunded; |
|
|
|
} |
|
|
|
else if ( waiting != 0 ) |
|
|
|
{ |
|
|
|
numwaiting++; |
|
|
|
waitingsum += waiting; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
invalidsum += item->refundvalue; |
|
|
|
numinvalids++; |
|
|
|
} |
|
|
|
continue; |
|
|
|
} |
|
|
|
if ( item->total > item->refundvalue*1.05 + 10*SATOSHIDEN ) |
|
|
|
{ |
|
|
|
//if ( (item->total-item->refundvalue) > 777*SATOSHIDEN )
|
|
|
|
printf("possible.%d stolen %s %.8f vs refund %.8f -> %.8f\n",batchid,item->oldaddr,dstr(item->total),dstr(item->refundvalue),dstr(item->total)-dstr(item->refundvalue)); |
|
|
|
numstolen++; |
|
|
|
possiblestolen += (item->total - item->refundvalue); |
|
|
|
item->approved = 0; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
printf("candidate.%d %s %.8f vs refund %.8f -> %s\n",batchid,item->oldaddr,dstr(item->total),dstr(item->refundvalue),item->destaddr); |
|
|
|
numcandidates++; |
|
|
|
possiblerefund += item->refundvalue; |
|
|
|
} |
|
|
|
} |
|
|
|
printf("batchid.%d TOTAL exposure %d %.8f, possible refund %d %.8f, invalids %d %.8f, numrefunded %d %.8f, waiting %d %.8f\n",batchid,numstolen,dstr(possiblestolen),numcandidates,dstr(possiblerefund),numinvalids,dstr(invalidsum),numrefunded,dstr(totalrefunded),numwaiting,dstr(waitingsum)); |
|
|
|
for (i=num=0; i<NUM_CLAIMS; i++) |
|
|
|
{ |
|
|
|
item = &CLAIMS[i]; |
|
|
|
if ( item->approved != 0 ) |
|
|
|
{ |
|
|
|
printf("%d.%d: approved.%d %s %.8f vs refund %.8f -> %s\n",i,num,batchid,item->oldaddr,dstr(item->total),dstr(item->refundvalue),item->destaddr); |
|
|
|
num++; |
|
|
|
if ( issueflag != 0 ) |
|
|
|
{ |
|
|
|
static FILE *fp; char cmd[1024]; |
|
|
|
if ( fp == 0 ) |
|
|
|
fp = fopen("refund.log","wb"); |
|
|
|
genrefund(cmd,refcoin,item->txid,item->destaddr,item->refundvalue); |
|
|
|
if ( fp != 0 ) |
|
|
|
{ |
|
|
|
fprintf(fp,"%s,%s,%s,%s,%s,%.8f,%s\n",item->username,refcoin,bits256_str(str,item->txid),item->oldaddr,item->destaddr,dstr(item->refundvalue),cmd); |
|
|
|
fflush(fp); |
|
|
|
} |
|
|
|
memset(&SECONDVIN,0,sizeof(SECONDVIN)); |
|
|
|
SECONDVOUT = 1; |
|
|
|
//printf(">>>>>>>>>>>>>>>>>> getchar after (%s)\n",cmd);
|
|
|
|
//getchar();
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
int32_t update_claimvalue(int32_t *disputedp,char *addr,int64_t amount,bits256 txid) |
|
|
|
{ |
|
|
|
int32_t i; struct claimitem *item; |
|
|
|
*disputedp = 0; |
|
|
|
for (i=0; i<NUM_CLAIMS; i++) |
|
|
|
{ |
|
|
|
if ( strcmp(addr,CLAIMS[i].oldaddr) == 0 ) |
|
|
|
{ |
|
|
|
item = &CLAIMS[i]; |
|
|
|
item->refundvalue = amount; |
|
|
|
if ( bits256_nonz(item->txid) != 0 ) |
|
|
|
printf("disputed.%d %s claimed %.8f vs %.8f\n",item->disputed,addr,dstr(item->total),dstr(amount)); |
|
|
|
item->txid = txid; |
|
|
|
if ( item->disputed != 0 ) |
|
|
|
*disputedp = 1; |
|
|
|
return(i); |
|
|
|
} |
|
|
|
} |
|
|
|
return(-1); |
|
|
|
} |
|
|
|
|
|
|
|
int64_t update_claimstats(char *username,char *oldaddr,char *destaddr,int64_t amount) |
|
|
|
{ |
|
|
|
int32_t i; struct claimitem *item; |
|
|
@ -988,7 +1203,7 @@ int64_t update_claimstats(char *username,char *oldaddr,char *destaddr,int64_t am |
|
|
|
strncpy(item->oldaddr,oldaddr,sizeof(item->oldaddr)); |
|
|
|
strncpy(item->destaddr,destaddr,sizeof(item->destaddr)); |
|
|
|
strncpy(item->username,username,sizeof(item->username)); |
|
|
|
//printf("new claim.%-4d: %36s %16.8f -> %36s %s\n",NUM_CLAIMS,oldaddr,dstr(amount),destaddr,username);
|
|
|
|
printf("new claim.%-4d: %36s %16.8f -> %36s %s\n",NUM_CLAIMS,oldaddr,dstr(amount),destaddr,username); |
|
|
|
return(amount); |
|
|
|
} |
|
|
|
|
|
|
@ -1042,16 +1257,6 @@ int64_t sum_of_vins(char *refcoin,int32_t *totalvinsp,int32_t *uniqaddrsp,bits25 |
|
|
|
return(total); |
|
|
|
} |
|
|
|
|
|
|
|
void genpayout(char *coinstr,char *destaddr,int32_t amount) |
|
|
|
{ |
|
|
|
char cmd[1024]; |
|
|
|
sprintf(cmd,"curl --url \"http://127.0.0.1:7783\" --data \"{\\\"userpass\\\":\\\"$userpass\\\",\\\"method\\\":\\\"withdraw\\\",\\\"coin\\\":\\\"%s\\\",\\\"outputs\\\":[{\\\"%s\\\":%.8f},{\\\"RWXL82m4xnBTg1kk6PuS2xekonu7oEeiJG\\\":0.0002}],\\\"broadcast\\\":1}\"\nsleep 3\n",coinstr,destaddr,dstr(amount+20000)); |
|
|
|
printf("%s",cmd); |
|
|
|
} |
|
|
|
|
|
|
|
// 602.(powerkin#8483,KMD ,RArt9a3piuz3YVhJorAWMnMYd1jwHKdEqo,16,39403c7c5c87e9ba087769cd10023d2b24d11ce4a277c3c41e7efd9da236ed60,RJ37ByppPqsLDauEgQbdwrr3GroTYC2ynE
|
|
|
|
|
|
|
|
|
|
|
|
void reconcile_claims(char *fname) |
|
|
|
{ |
|
|
|
FILE *fp; double amount; int32_t i,n,numlines = 0; char buf[1024],fields[16][256],*str; int64_t total = 0; |
|
|
@ -1069,7 +1274,7 @@ void reconcile_claims(char *fname) |
|
|
|
{ |
|
|
|
fields[n][i] = 0; |
|
|
|
i = 0; |
|
|
|
if ( n != 4 && n > 1 ) |
|
|
|
if ( n > 1 ) |
|
|
|
{ |
|
|
|
//printf("(%16s) ",fields[n]);
|
|
|
|
} |
|
|
@ -1082,7 +1287,7 @@ void reconcile_claims(char *fname) |
|
|
|
else fields[n][i++] = *str++; |
|
|
|
} |
|
|
|
//printf("%s\n",fields[0]);
|
|
|
|
total += update_claimstats(fields[0],fields[2],fields[5],atof(fields[3])*SATOSHIDEN + 0.0000000049); |
|
|
|
total += update_claimstats(fields[0],fields[2],fields[4],atof(fields[3])*SATOSHIDEN + 0.0000000049); |
|
|
|
numlines++; |
|
|
|
} |
|
|
|
fclose(fp); |
|
|
@ -1092,7 +1297,7 @@ void reconcile_claims(char *fname) |
|
|
|
|
|
|
|
int32_t main(int32_t argc,char **argv) |
|
|
|
{ |
|
|
|
char *coinstr,*addr,buf[64]; cJSON *retjson,*item; int32_t i,n,numsmall=0,numpayouts=0,num=0,totalvins=0,uniqaddrs=0; int64_t amount,total = 0,total2 = 0,payout,maxpayout,smallpayout=0,totalpayout = 0; |
|
|
|
char *coinstr,*addr,buf[64],srcaddr[64],str[65]; cJSON *retjson,*item; int32_t i,n,disputed,numdisputed,numsmall=0,numpayouts=0,numclaims=0,num=0,totalvins=0,uniqaddrs=0; int64_t amount,total = 0,total2 = 0,payout,maxpayout,smallpayout=0,totalpayout = 0,totaldisputed = 0,totaldisputed2 = 0,fundingamount = 0; |
|
|
|
if ( argc != 2 ) |
|
|
|
{ |
|
|
|
printf("argc needs to be 2: <prog> coin\n"); |
|
|
@ -1113,6 +1318,74 @@ int32_t main(int32_t argc,char **argv) |
|
|
|
{ |
|
|
|
sprintf(buf,"%s-Claims.csv",coinstr); |
|
|
|
reconcile_claims(buf); |
|
|
|
for (i=0; i<NUM_CLAIMS; i++) |
|
|
|
{ |
|
|
|
if ( CLAIMS[i].disputed != 0 ) |
|
|
|
{ |
|
|
|
totaldisputed += CLAIMS[i].total; |
|
|
|
printf("disputed %s %.8f\n",CLAIMS[i].oldaddr,dstr(CLAIMS[i].total)); |
|
|
|
} |
|
|
|
} |
|
|
|
printf("total disputed %.8f\n",dstr(totaldisputed)); |
|
|
|
totaldisputed2 = 0; |
|
|
|
if ( (retjson= get_listunspent(coinstr,"")) != 0 ) |
|
|
|
{ |
|
|
|
if ( (n= cJSON_GetArraySize(retjson)) > 0 ) |
|
|
|
{ |
|
|
|
for (i=0; i<n; i++) |
|
|
|
{ |
|
|
|
item = jitem(retjson,i); |
|
|
|
amount = jdouble(item,"amount")*SATOSHIDEN; |
|
|
|
if ( (addr= jstr(item,"address")) != 0 && strcmp(addr,"RWXL82m4xnBTg1kk6PuS2xekonu7oEeiJG") == 0 ) |
|
|
|
{ |
|
|
|
if ( amount != 20000 ) |
|
|
|
{ |
|
|
|
if ( amount > fundingamount ) |
|
|
|
{ |
|
|
|
fundingamount = amount; |
|
|
|
SECONDVIN = jbits256(item,"txid"); |
|
|
|
SECONDVOUT = jint(item,"vout"); |
|
|
|
printf("set SECONDVIN to %s/v%d %.8f\n",bits256_str(str,SECONDVIN),SECONDVOUT,dstr(amount)); |
|
|
|
} |
|
|
|
continue; |
|
|
|
} |
|
|
|
if ( strcmp(coinstr,"KMD") == 0 && verify_vin(coinstr,jbits256(item,"txid"),0,"R9JCEd6xnCxNUSpLrHEWvzPSh7CNXm7z75") < 0 ) |
|
|
|
{ |
|
|
|
printf("WARNING: imposter dust detected! %s\n",bits256_str(str,jbits256(item,"txid"))); |
|
|
|
continue; |
|
|
|
} |
|
|
|
else if ( strcmp(coinstr,"KMD") != 0 && verify_vin(coinstr,jbits256(item,"txid"),0,"R9MUnxXijovvSeT9sFuUX23TiFtVvZEGjT") < 0 ) |
|
|
|
{ |
|
|
|
printf("WARNING: imposter dust detected! %s\n",bits256_str(str,jbits256(item,"txid"))); |
|
|
|
continue; |
|
|
|
} |
|
|
|
amount = (utxo_value(coinstr,srcaddr,jbits256(item,"txid"),0) - 20000) * SATOSHIDEN; |
|
|
|
//printf("%d: %s claimvalue %.8f\n",num,srcaddr,dstr(amount));
|
|
|
|
num++; |
|
|
|
total2 += amount; |
|
|
|
if ( update_claimvalue(&disputed,srcaddr,amount,jbits256(item,"txid")) >= 0 ) |
|
|
|
{ |
|
|
|
if ( disputed != 0 ) |
|
|
|
{ |
|
|
|
totaldisputed2 += amount; |
|
|
|
numdisputed++; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
numclaims++; |
|
|
|
total += amount; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
free_json(retjson); |
|
|
|
printf("remaining refunds.%d %.8f, numclaims.%d %.8f, numdisputed.%d %.8f\n",num,dstr(total2),numclaims,dstr(total),numdisputed,dstr(totaldisputed2)); |
|
|
|
} |
|
|
|
//scan_claims(0,coinstr,0);
|
|
|
|
//scan_claims(0,coinstr,1);
|
|
|
|
scan_claims(0,coinstr,2); |
|
|
|
//scan_claims(0,coinstr,3);
|
|
|
|
} |
|
|
|
else if ( (retjson= get_listunspent(coinstr,"")) != 0 ) |
|
|
|
{ |
|
|
|