]> Git Repo - VerusCoin.git/blob - src/komodo_jumblr.h
Test
[VerusCoin.git] / src / komodo_jumblr.h
1 /******************************************************************************
2  * Copyright © 2014-2017 The SuperNET Developers.                             *
3  *                                                                            *
4  * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at                  *
5  * the top-level directory of this distribution for the individual copyright  *
6  * holder information and the developer policies on copyright and licensing.  *
7  *                                                                            *
8  * Unless otherwise agreed in a custom licensing agreement, no part of the    *
9  * SuperNET software, including this file may be copied, modified, propagated *
10  * or distributed except according to the terms contained in the LICENSE file *
11  *                                                                            *
12  * Removal or modification of this copyright notice is prohibited.            *
13  *                                                                            *
14  ******************************************************************************/
15
16 /*
17  z_exportkey "zaddr"
18  z_exportwallet "filename"
19  z_getoperationstatus (["operationid", ... ])
20  z_gettotalbalance ( minconf )
21  z_importkey "zkey" ( rescan )
22  z_importwallet "filename"
23  z_listaddresses
24  z_sendmany "fromaddress" [{"address":... ,"amount":..., "memo":"<hex>"},...] ( minconf ) ( fee )
25  */
26
27 #ifdef _WIN32
28 #include <wincrypt.h>
29 #endif
30 #include "komodo_defs.h"
31
32 #define JUMBLR_ADDR "RGhxXpXSSBTBm9EvNsXnTQczthMCxHX91t"
33 #define JUMBLR_BTCADDR "18RmTJe9qMech8siuhYfMtHo8RtcN1obC6"
34 #define JUMBLR_MAXSECRETADDRS 777
35 #define JUMBLR_SYNCHRONIZED_BLOCKS 10
36 #define JUMBLR_INCR 9.965
37 #define JUMBLR_FEE 0.001
38 #define JUMBLR_TXFEE 0.01
39 #define SMALLVAL 0.000000000000001
40
41 #define JUMBLR_ERROR_DUPLICATEDEPOSIT -1
42 #define JUMBLR_ERROR_SECRETCANTBEDEPOSIT -2
43 #define JUMBLR_ERROR_TOOMANYSECRETS -3
44 #define JUMBLR_ERROR_NOTINWALLET -4
45
46 struct jumblr_item
47 {
48     UT_hash_handle hh;
49     int64_t amount,fee,txfee; // fee and txfee not really used (yet)
50     uint32_t spent,pad;
51     char opid[66],src[128],dest[128],status;
52 } *Jumblrs;
53
54 char Jumblr_secretaddrs[JUMBLR_MAXSECRETADDRS][64],Jumblr_deposit[64];
55 int32_t Jumblr_numsecretaddrs; // if 0 -> run silent mode
56
57 char *jumblr_issuemethod(char *userpass,char *method,char *params,uint16_t port)
58 {
59     cJSON *retjson,*resjson = 0; char *retstr;
60     if ( (retstr= komodo_issuemethod(userpass,method,params,port)) != 0 )
61     {
62         if ( (retjson= cJSON_Parse(retstr)) != 0 )
63         {
64             if ( jobj(retjson,(char *)"result") != 0 )
65                 resjson = jduplicate(jobj(retjson,(char *)"result"));
66             else if ( jobj(retjson,(char *)"error") != 0 )
67                 resjson = jduplicate(jobj(retjson,(char *)"error"));
68             else
69             {
70                 resjson = cJSON_CreateObject();
71                 jaddstr(resjson,(char *)"error",(char *)"cant parse return");
72             }
73             free_json(retjson);
74         }
75         free(retstr);
76     }
77     if ( resjson != 0 )
78         return(jprint(resjson,1));
79     else return(clonestr((char *)"{\"error\":\"unknown error\"}"));
80 }
81
82 char *jumblr_importaddress(char *address)
83 {
84     char params[1024];
85     sprintf(params,"[\"%s\", \"%s\", false]",address,address);
86     return(jumblr_issuemethod(KMDUSERPASS,(char *)"importaddress",params,BITCOIND_PORT));
87 }
88
89 char *jumblr_validateaddress(char *addr)
90 {
91     char params[1024];
92     sprintf(params,"[\"%s\"]",addr);
93     printf("validateaddress.%s\n",params);
94     return(jumblr_issuemethod(KMDUSERPASS,(char *)"validateaddress",params,BITCOIND_PORT));
95 }
96
97 int32_t Jumblr_secretaddrfind(char *searchaddr)
98 {
99     int32_t i;
100     for (i=0; i<Jumblr_numsecretaddrs; i++)
101     {
102         if ( strcmp(searchaddr,Jumblr_secretaddrs[i]) == 0 )
103             return(i);
104     }
105     return(-1);
106 }
107
108 int32_t Jumblr_secretaddradd(char *secretaddr) // external
109 {
110     int32_t ind;
111     if ( secretaddr != 0 && secretaddr[0] != 0 )
112     {
113         if ( Jumblr_numsecretaddrs < JUMBLR_MAXSECRETADDRS )
114         {
115             if ( strcmp(Jumblr_deposit,secretaddr) != 0 )
116             {
117                 if ( (ind= Jumblr_secretaddrfind(secretaddr)) < 0 )
118                 {
119                     ind = Jumblr_numsecretaddrs++;
120                     safecopy(Jumblr_secretaddrs[ind],secretaddr,64);
121                 }
122                 return(ind);
123             } else return(JUMBLR_ERROR_SECRETCANTBEDEPOSIT);
124         } else return(JUMBLR_ERROR_TOOMANYSECRETS);
125     }
126     else
127     {
128         memset(Jumblr_secretaddrs,0,sizeof(Jumblr_secretaddrs));
129         Jumblr_numsecretaddrs = 0;
130     }
131     return(Jumblr_numsecretaddrs);
132 }
133
134 int32_t Jumblr_depositaddradd(char *depositaddr) // external
135 {
136     int32_t ind,retval = JUMBLR_ERROR_DUPLICATEDEPOSIT; char *retstr; cJSON *retjson,*ismine;
137     if ( depositaddr == 0 )
138         depositaddr = (char *)"";
139     if ( (ind= Jumblr_secretaddrfind(depositaddr)) < 0 )
140     {
141         if ( (retstr= jumblr_validateaddress(depositaddr)) != 0 )
142         {
143             if ( (retjson= cJSON_Parse(retstr)) != 0 )
144             {
145                 if ( (ismine= jobj(retjson,(char *)"ismine")) != 0 && cJSON_IsTrue(ismine) != 0 )
146                 {
147                     retval = 0;
148                     safecopy(Jumblr_deposit,depositaddr,sizeof(Jumblr_deposit));
149                 }
150                 else
151                 {
152                     retval = JUMBLR_ERROR_NOTINWALLET;
153                     printf("%s not in wallet: ismine.%p %d %s\n",depositaddr,ismine,cJSON_IsTrue(ismine),jprint(retjson,0));
154                 }
155                 free_json(retjson);
156             }
157             free(retstr);
158         }
159     }
160     return(retval);
161 }
162
163 #ifdef _WIN32
164 void OS_randombytes(unsigned char *x,long xlen)
165 {
166     HCRYPTPROV prov = 0;
167     CryptAcquireContextW(&prov, NULL, NULL,PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT);
168     CryptGenRandom(prov, xlen, x);
169     CryptReleaseContext(prov, 0);
170 }
171 #endif
172
173 int32_t Jumblr_secretaddr(char *secretaddr)
174 {
175     uint32_t r;
176     if ( Jumblr_numsecretaddrs > 0 )
177     {
178         OS_randombytes((uint8_t *)&r,sizeof(r));
179         r %= Jumblr_numsecretaddrs;
180         safecopy(secretaddr,Jumblr_secretaddrs[r],64);
181     }
182     return(r);
183 }
184
185 int32_t jumblr_addresstype(char *addr)
186 {
187     if ( addr[0] == '"' && addr[strlen(addr)-1] == '"' )
188     {
189         addr[strlen(addr)-1] = 0;
190         addr++;
191     }
192     if ( addr[0] == 'z' && addr[1] == 'c' && strlen(addr) >= 40 )
193         return('z');
194     else if ( strlen(addr) < 40 )
195         return('t');
196     printf("strange.(%s)\n",addr);
197     return(-1);
198 }
199
200 struct jumblr_item *jumblr_opidfind(char *opid)
201 {
202     struct jumblr_item *ptr;
203     HASH_FIND(hh,Jumblrs,opid,(int32_t)strlen(opid),ptr);
204     return(ptr);
205 }
206
207 struct jumblr_item *jumblr_opidadd(char *opid)
208 {
209     struct jumblr_item *ptr = 0;
210     if ( opid != 0 && (ptr= jumblr_opidfind(opid)) == 0 )
211     {
212         ptr = (struct jumblr_item *)calloc(1,sizeof(*ptr));
213         safecopy(ptr->opid,opid,sizeof(ptr->opid));
214         HASH_ADD_KEYPTR(hh,Jumblrs,ptr->opid,(int32_t)strlen(ptr->opid),ptr);
215         if ( ptr != jumblr_opidfind(opid) )
216             printf("jumblr_opidadd.(%s) ERROR, couldnt find after add\n",opid);
217     }
218     return(ptr);
219 }
220
221 char *jumblr_zgetnewaddress()
222 {
223     char params[1024];
224     sprintf(params,"[]");
225     return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_getnewaddress",params,BITCOIND_PORT));
226 }
227
228 char *jumblr_zlistoperationids()
229 {
230     char params[1024];
231     sprintf(params,"[]");
232     return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_listoperationids",params,BITCOIND_PORT));
233 }
234
235 char *jumblr_zgetoperationresult(char *opid)
236 {
237     char params[1024];
238     sprintf(params,"[[\"%s\"]]",opid);
239     return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_getoperationresult",params,BITCOIND_PORT));
240 }
241
242 char *jumblr_zgetoperationstatus(char *opid)
243 {
244     char params[1024];
245     sprintf(params,"[[\"%s\"]]",opid);
246     return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_getoperationstatus",params,BITCOIND_PORT));
247 }
248
249 char *jumblr_sendt_to_z(char *taddr,char *zaddr,double amount)
250 {
251     char params[1024]; double fee = ((amount-3*JUMBLR_TXFEE) * JUMBLR_FEE) * 1.5;
252     if ( jumblr_addresstype(zaddr) != 'z' || jumblr_addresstype(taddr) != 't' )
253         return(clonestr((char *)"{\"error\":\"illegal address in t to z\"}"));
254     sprintf(params,"[\"%s\", [{\"address\":\"%s\",\"amount\":%.8f}, {\"address\":\"%s\",\"amount\":%.8f}], 1, %.8f]",taddr,zaddr,amount-fee-JUMBLR_TXFEE,JUMBLR_ADDR,fee,JUMBLR_TXFEE);
255     printf("t -> z: %s\n",params);
256     return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_sendmany",params,BITCOIND_PORT));
257 }
258
259 char *jumblr_sendz_to_z(char *zaddrS,char *zaddrD,double amount)
260 {
261     char params[1024]; double fee = (amount-2*JUMBLR_TXFEE) * JUMBLR_FEE;
262     if ( jumblr_addresstype(zaddrS) != 'z' || jumblr_addresstype(zaddrD) != 'z' )
263         return(clonestr((char *)"{\"error\":\"illegal address in z to z\"}"));
264     //sprintf(params,"[\"%s\", [{\"address\":\"%s\",\"amount\":%.8f}, {\"address\":\"%s\",\"amount\":%.8f}], 1, %.8f]",zaddrS,zaddrD,amount-fee-JUMBLR_TXFEE,JUMBLR_ADDR,fee,JUMBLR_TXFEE);
265     sprintf(params,"[\"%s\", [{\"address\":\"%s\",\"amount\":%.8f}], 1, %.8f]",zaddrS,zaddrD,amount-fee-JUMBLR_TXFEE,JUMBLR_TXFEE);
266     printf("z -> z: %s\n",params);
267     return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_sendmany",params,BITCOIND_PORT));
268 }
269
270 char *jumblr_sendz_to_t(char *zaddr,char *taddr,double amount)
271 {
272     char params[1024]; double fee = ((amount-JUMBLR_TXFEE) * JUMBLR_FEE) * 1.5;
273     if ( jumblr_addresstype(zaddr) != 'z' || jumblr_addresstype(taddr) != 't' )
274         return(clonestr((char *)"{\"error\":\"illegal address in z to t\"}"));
275     sprintf(params,"[\"%s\", [{\"address\":\"%s\",\"amount\":%.8f}, {\"address\":\"%s\",\"amount\":%.8f}], 1, %.8f]",zaddr,taddr,amount-fee-JUMBLR_TXFEE,JUMBLR_ADDR,fee,JUMBLR_TXFEE);
276     printf("z -> t: %s\n",params);
277     return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_sendmany",params,BITCOIND_PORT));
278 }
279
280 char *jumblr_zlistaddresses()
281 {
282     char params[1024];
283     sprintf(params,"[]");
284     return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_listaddresses",params,BITCOIND_PORT));
285 }
286
287 char *jumblr_zlistreceivedbyaddress(char *addr)
288 {
289     char params[1024];
290     sprintf(params,"[\"%s\", 1]",addr);
291     return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_listreceivedbyaddress",params,BITCOIND_PORT));
292 }
293
294 char *jumblr_getreceivedbyaddress(char *addr)
295 {
296     char params[1024];
297     sprintf(params,"[\"%s\", 1]",addr);
298     return(jumblr_issuemethod(KMDUSERPASS,(char *)"getreceivedbyaddress",params,BITCOIND_PORT));
299 }
300
301 char *jumblr_importprivkey(char *wifstr)
302 {
303     char params[1024];
304     sprintf(params,"[\"%s\", \"\", false]",wifstr);
305     return(jumblr_issuemethod(KMDUSERPASS,(char *)"importprivkey",params,BITCOIND_PORT));
306 }
307
308 char *jumblr_zgetbalance(char *addr)
309 {
310     char params[1024];
311     sprintf(params,"[\"%s\", 1]",addr);
312     return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_getbalance",params,BITCOIND_PORT));
313 }
314
315 char *jumblr_listunspent(char *coinaddr)
316 {
317     char params[1024];
318     sprintf(params,"[1, 99999999, [\"%s\"]]",coinaddr);
319     return(jumblr_issuemethod(KMDUSERPASS,(char *)"listunspent",params,BITCOIND_PORT));
320 }
321
322 char *jumblr_gettransaction(char *txidstr)
323 {
324     char params[1024];
325     sprintf(params,"[\"%s\", 1]",txidstr);
326     return(jumblr_issuemethod(KMDUSERPASS,(char *)"getrawtransaction",params,BITCOIND_PORT));
327 }
328
329 int32_t jumblr_numvins(bits256 txid)
330 {
331     char txidstr[65],params[1024],*retstr; cJSON *retjson,*vins; int32_t n,numvins = -1;
332     bits256_str(txidstr,txid);
333     if ( (retstr= jumblr_gettransaction(txidstr)) != 0 )
334     {
335         if ( (retjson= cJSON_Parse(retstr)) != 0 )
336         {
337             if ( jobj(retjson,(char *)"vin") != 0 && ((vins= jarray(&n,retjson,(char *)"vin")) == 0 || n == 0) )
338             {
339                 numvins = n;
340                 //printf("numvins.%d\n",n);
341             } //else printf("no vin.(%s)\n",retstr);
342             free_json(retjson);
343         }
344         free(retstr);
345     }
346     return(numvins);
347 }
348
349 int64_t jumblr_receivedby(char *addr)
350 {
351     char *retstr; int64_t total = 0;
352     if ( (retstr= jumblr_getreceivedbyaddress(addr)) != 0 )
353     {
354         total = atof(retstr) * SATOSHIDEN;
355         free(retstr);
356     }
357     return(total);
358 }
359
360 int64_t jumblr_balance(char *addr)
361 {
362     char *retstr; double val; int64_t balance = 0; //cJSON *retjson; int32_t i,n;
363     /*if ( jumblr_addresstype(addr) == 't' )
364     {
365         if ( (retstr= jumblr_listunspent(addr)) != 0 )
366         {
367             //printf("jumblr.[%s].(%s)\n","KMD",retstr);
368             if ( (retjson= cJSON_Parse(retstr)) != 0 )
369             {
370                 if ( (n= cJSON_GetArraySize(retjson)) > 0 && cJSON_IsArray(retjson) != 0 )
371                     for (i=0; i<n; i++)
372                         balance += SATOSHIDEN * jdouble(jitem(retjson,i),(char *)"amount");
373                 free_json(retjson);
374             }
375             free(retstr);
376         }
377     }
378     else*/ if ( (retstr= jumblr_zgetbalance(addr)) != 0 )
379     {
380         if ( (val= atof(retstr)) > SMALLVAL )
381             balance = val * SATOSHIDEN;
382         free(retstr);
383     }
384     return(balance);
385 }
386
387 int32_t jumblr_itemset(struct jumblr_item *ptr,cJSON *item,char *status)
388 {
389     cJSON *params,*amounts,*dest; char *from,*addr; int32_t i,n; int64_t amount;
390     /*"params" : {
391      "fromaddress" : "RDhEGYScNQYetCyG75Kf8Fg61UWPdwc1C5",
392      "amounts" : [
393      {
394      "address" : "zc9s3UdkDFTnnwHrMCr1vYy2WmkjhmTxXNiqC42s7BjeKBVUwk766TTSsrRPKfnX31Bbu8wbrTqnjDqskYGwx48FZMPHvft",
395      "amount" : 3.00000000
396      }
397      ],
398      "minconf" : 1,
399      "fee" : 0.00010000
400      }*/
401     if ( (params= jobj(item,(char *)"params")) != 0 )
402     {
403         //printf("params.(%s)\n",jprint(params,0));
404         if ( (from= jstr(params,(char *)"fromaddress")) != 0 )
405         {
406             safecopy(ptr->src,from,sizeof(ptr->src));
407         }
408         if ( (amounts= jarray(&n,params,(char *)"amounts")) != 0 )
409         {
410             for (i=0; i<n; i++)
411             {
412                 dest = jitem(amounts,i);
413                 //printf("%s ",jprint(dest,0));
414                 if ( (addr= jstr(dest,(char *)"address")) != 0 && (amount= jdouble(dest,(char *)"amount")*SATOSHIDEN) > 0 )
415                 {
416                     if ( strcmp(addr,JUMBLR_ADDR) == 0 )
417                         ptr->fee = amount;
418                     else
419                     {
420                         ptr->amount = amount;
421                         safecopy(ptr->dest,addr,sizeof(ptr->dest));
422                     }
423                 }
424             }
425         }
426         ptr->txfee = jdouble(params,(char *)"fee") * SATOSHIDEN;
427     }
428     return(1);
429 }
430
431 void jumblr_opidupdate(struct jumblr_item *ptr)
432 {
433     char *retstr,*status; cJSON *retjson,*item;
434     if ( ptr->status == 0 )
435     {
436         if ( (retstr= jumblr_zgetoperationstatus(ptr->opid)) != 0 )
437         {
438             if ( (retjson= cJSON_Parse(retstr)) != 0 )
439             {
440                 if ( cJSON_GetArraySize(retjson) == 1 && cJSON_IsArray(retjson) != 0 )
441                 {
442                     item = jitem(retjson,0);
443                     //printf("%s\n",jprint(item,0));
444                     if ( (status= jstr(item,(char *)"status")) != 0 )
445                     {
446                         if ( strcmp(status,(char *)"success") == 0 )
447                         {
448                             ptr->status = jumblr_itemset(ptr,item,status);
449                             if ( (jumblr_addresstype(ptr->src) == 't' && jumblr_addresstype(ptr->src) == 'z' && strcmp(ptr->src,Jumblr_deposit) != 0) || (jumblr_addresstype(ptr->src) == 'z' && jumblr_addresstype(ptr->src) == 't' && Jumblr_secretaddrfind(ptr->dest) < 0) )
450                             {
451                                 printf("a non-jumblr t->z pruned\n");
452                                 free(jumblr_zgetoperationresult(ptr->opid));
453                                 ptr->status = -1;
454                             }
455
456                         }
457                         else if ( strcmp(status,(char *)"failed") == 0 )
458                         {
459                             printf("jumblr_opidupdate %s failed\n",ptr->opid);
460                             free(jumblr_zgetoperationresult(ptr->opid));
461                             ptr->status = -1;
462                         }
463                     }
464                 }
465                 free_json(retjson);
466             }
467             free(retstr);
468         }
469     }
470 }
471
472 void jumblr_prune(struct jumblr_item *ptr)
473 {
474     struct jumblr_item *tmp; char oldsrc[128]; int32_t flag = 1;
475     if ( is_hexstr(ptr->opid,0) == 64 )
476         return;
477     printf("jumblr_prune %s\n",ptr->opid);
478     strcpy(oldsrc,ptr->src);
479     free(jumblr_zgetoperationresult(ptr->opid));
480     while ( flag != 0 )
481     {
482         flag = 0;
483         HASH_ITER(hh,Jumblrs,ptr,tmp)
484         {
485             if ( strcmp(oldsrc,ptr->dest) == 0 )
486             {
487                 if ( is_hexstr(ptr->opid,0) != 64 )
488                 {
489                     printf("jumblr_prune %s (%s -> %s) matched oldsrc\n",ptr->opid,ptr->src,ptr->dest);
490                     free(jumblr_zgetoperationresult(ptr->opid));
491                     strcpy(oldsrc,ptr->src);
492                     flag = 1;
493                     break;
494                 }
495             }
496         }
497     }
498 }
499
500
501 bits256 jbits256(cJSON *json,char *field);
502
503
504 void jumblr_zaddrinit(char *zaddr)
505 {
506     struct jumblr_item *ptr; char *retstr,*totalstr; cJSON *item,*array; double total; bits256 txid; char txidstr[65],t_z,z_z;
507     if ( (totalstr= jumblr_zgetbalance(zaddr)) != 0 )
508     {
509         if ( (total= atof(totalstr)) > SMALLVAL )
510         {
511             if ( (retstr= jumblr_zlistreceivedbyaddress(zaddr)) != 0 )
512             {
513                 if ( (array= cJSON_Parse(retstr)) != 0 )
514                 {
515                     t_z = z_z = 0;
516                     if ( cJSON_GetArraySize(array) == 1 && cJSON_IsArray(array) != 0 )
517                     {
518                         item = jitem(array,0);
519                         if ( (uint64_t)((total+0.0000000049) * SATOSHIDEN) == (uint64_t)((jdouble(item,(char *)"amount")+0.0000000049) * SATOSHIDEN) )
520                         {
521                             txid = jbits256(item,(char *)"txid");
522                             bits256_str(txidstr,txid);
523                             if ( (ptr= jumblr_opidadd(txidstr)) != 0 )
524                             {
525                                 ptr->amount = (total * SATOSHIDEN);
526                                 ptr->status = 1;
527                                 strcpy(ptr->dest,zaddr);
528                                 if ( jumblr_addresstype(ptr->dest) != 'z' )
529                                     printf("error setting dest type to Z: %s\n",jprint(item,0));
530                                 if ( jumblr_numvins(txid) == 0 )
531                                 {
532                                     z_z = 1;
533                                     strcpy(ptr->src,zaddr);
534                                     ptr->src[3] = '0';
535                                     ptr->src[4] = '0';
536                                     ptr->src[5] = '0';
537                                     if ( jumblr_addresstype(ptr->src) != 'z' )
538                                         printf("error setting address type to Z: %s\n",jprint(item,0));
539                                 }
540                                 else
541                                 {
542                                     t_z = 1;
543                                     strcpy(ptr->src,"taddr");
544                                     if ( jumblr_addresstype(ptr->src) != 't' )
545                                         printf("error setting address type to T: %s\n",jprint(item,0));
546                                 }
547                                 printf("%s %s %.8f t_z.%d z_z.%d\n",zaddr,txidstr,total,t_z,z_z); // cant be z->t from spend
548                             }
549                         } else printf("mismatched %s %s total %.8f vs %.8f -> %lld\n",zaddr,totalstr,dstr(SATOSHIDEN * total),dstr(SATOSHIDEN * jdouble(item,(char *)"amount")),(long long)((uint64_t)(total * SATOSHIDEN) - (uint64_t)(jdouble(item,(char *)"amount") * SATOSHIDEN)));
550                     }
551                     free_json(array);
552                 }
553                 free(retstr);
554             }
555         }
556         free(totalstr);
557     }
558 }
559
560 void jumblr_opidsupdate()
561 {
562     char *retstr; cJSON *array; int32_t i,n; struct jumblr_item *ptr;
563     if ( (retstr= jumblr_zlistoperationids()) != 0 )
564     {
565         if ( (array= cJSON_Parse(retstr)) != 0 )
566         {
567             if ( (n= cJSON_GetArraySize(array)) > 0 && cJSON_IsArray(array) != 0 )
568             {
569                 //printf("%s -> n%d\n",retstr,n);
570                 for (i=0; i<n; i++)
571                 {
572                     if ( (ptr= jumblr_opidadd(jstri(array,i))) != 0 )
573                     {
574                         if ( ptr->status == 0 )
575                             jumblr_opidupdate(ptr);
576                         //printf("%d: %s -> %s %.8f\n",ptr->status,ptr->src,ptr->dest,dstr(ptr->amount));
577                         if ( jumblr_addresstype(ptr->src) == 'z' && jumblr_addresstype(ptr->dest) == 't' )
578                             jumblr_prune(ptr);
579                     }
580                 }
581             }
582             free_json(array);
583         }
584         free(retstr);
585     }
586 }
587
588 uint64_t jumblr_increment(uint8_t r,int32_t height,uint64_t total,uint64_t biggest,uint64_t medium, uint64_t smallest)
589 {
590     int32_t i,n; uint64_t incrs[1000],remains = total;
591     height /= JUMBLR_SYNCHRONIZED_BLOCKS;
592     if ( (height % JUMBLR_SYNCHRONIZED_BLOCKS) == 0 || total >= 100*biggest )
593     {
594         if ( total >= biggest )
595             return(biggest);
596         else if ( total >= medium )
597             return(medium);
598         else if ( total >= smallest )
599             return(smallest);
600         else return(0);
601     }
602     else
603     {
604         n = 0;
605         while ( remains > smallest && n < sizeof(incrs)/sizeof(*incrs) )
606         {
607             if ( remains >= biggest )
608                 incrs[n] = biggest;
609             else if ( remains >= medium )
610                 incrs[n] = medium;
611             else if ( remains >= smallest )
612                 incrs[n] = smallest;
613             else break;
614             remains -= incrs[n];
615             n++;
616         }
617         if ( n > 0 )
618         {
619             r %= n;
620             for (i=0; i<n; i++)
621                 printf("%.8f ",dstr(incrs[i]));
622             printf("n.%d incrs r.%d -> %.8f\n",n,r,dstr(incrs[r]));
623             return(incrs[r]);
624         }
625     }
626     return(0);
627 }
628
629 void jumblr_iteration()
630 {
631     static int32_t lastheight; static uint32_t lasttime;
632     char *zaddr,*addr,*retstr,secretaddr[64]; cJSON *array; int32_t i,iter,height,counter,chosen_one,n; uint64_t smallest,medium,biggest,amount=0,total=0; double fee; struct jumblr_item *ptr,*tmp; uint16_t r,s;
633     if ( JUMBLR_PAUSE != 0 )
634         return;
635     if ( lasttime == 0 )
636     {
637         if ( (retstr= jumblr_zlistaddresses()) != 0 )
638         {
639             if ( (array= cJSON_Parse(retstr)) != 0 )
640             {
641                 if ( (n= cJSON_GetArraySize(array)) > 0 && cJSON_IsArray(array) != 0 )
642                 {
643                     for (i=0; i<n; i++)
644                         jumblr_zaddrinit(jstri(array,i));
645                 }
646                 free_json(array);
647             }
648             free(retstr);
649         }
650     }
651     height = (int32_t)chainActive.Tip()->nHeight;
652     if ( time(NULL) < lasttime+40 )
653         return;
654     lasttime = (uint32_t)time(NULL);
655     if ( lastheight == height )
656         return;
657     lastheight = height;
658     if ( (height % JUMBLR_SYNCHRONIZED_BLOCKS) != JUMBLR_SYNCHRONIZED_BLOCKS-3 )
659         return;
660     fee = JUMBLR_INCR * JUMBLR_FEE;
661     smallest = SATOSHIDEN * ((JUMBLR_INCR + 3*fee) + 3*JUMBLR_TXFEE);
662     medium = SATOSHIDEN * ((JUMBLR_INCR + 3*fee)*10 + 3*JUMBLR_TXFEE);
663     biggest = SATOSHIDEN * ((JUMBLR_INCR + 3*fee)*777 + 3*JUMBLR_TXFEE);
664     OS_randombytes((uint8_t *)&r,sizeof(r));
665     s = (r % 3);
666     //printf("jumblr_iteration r.%u s.%u\n",r,s);
667     switch ( s )
668     {
669         case 0: // t -> z
670         default:
671             if ( Jumblr_deposit[0] != 0 && (total= jumblr_balance(Jumblr_deposit)) >= smallest )
672             {
673                 if ( (zaddr= jumblr_zgetnewaddress()) != 0 )
674                 {
675                     if ( zaddr[0] == '"' && zaddr[strlen(zaddr)-1] == '"' )
676                     {
677                         zaddr[strlen(zaddr)-1] = 0;
678                         addr = zaddr+1;
679                     } else addr = zaddr;
680                     amount = jumblr_increment(r/3,height,total,biggest,medium,smallest);
681                 /*
682                     amount = 0;
683                     if ( (height % (JUMBLR_SYNCHRONIZED_BLOCKS*JUMBLR_SYNCHRONIZED_BLOCKS)) == 0 && total >= SATOSHIDEN * ((JUMBLR_INCR + 3*fee)*100 + 3*JUMBLR_TXFEE) )
684                     amount = SATOSHIDEN * ((JUMBLR_INCR + 3*fee)*100 + 3*JUMBLR_TXFEE);
685                     else if ( (r & 3) == 0 && total >= SATOSHIDEN * ((JUMBLR_INCR + 3*fee)*10 + 3*JUMBLR_TXFEE) )
686                         amount = SATOSHIDEN * ((JUMBLR_INCR + 3*fee)*10 + 3*JUMBLR_TXFEE);
687                     else amount = SATOSHIDEN * ((JUMBLR_INCR + 3*fee) + 3*JUMBLR_TXFEE);*/
688                     if ( amount > 0 && (retstr= jumblr_sendt_to_z(Jumblr_deposit,addr,dstr(amount))) != 0 )
689                     {
690                         printf("sendt_to_z.(%s)\n",retstr);
691                         free(retstr);
692                     }
693                     free(zaddr);
694                 } else printf("no zaddr from jumblr_zgetnewaddress\n");
695             }
696             else if ( Jumblr_deposit[0] != 0 )
697                 printf("%s total %.8f vs %.8f\n",Jumblr_deposit,dstr(total),(JUMBLR_INCR + 3*(fee+JUMBLR_TXFEE)));
698             break;
699         case 1: // z -> z
700             jumblr_opidsupdate();
701             chosen_one = -1;
702             for (iter=counter=0; iter<2; iter++)
703             {
704                 counter = n = 0;
705                 HASH_ITER(hh,Jumblrs,ptr,tmp)
706                 {
707                     if ( ptr->spent == 0 && ptr->status > 0 && jumblr_addresstype(ptr->src) == 't' && jumblr_addresstype(ptr->dest) == 'z' )
708                     {
709                         if ( (total= jumblr_balance(ptr->dest)) >= (fee + JUMBLR_FEE)*SATOSHIDEN )
710                         {
711                             if ( iter == 1 && counter == chosen_one )
712                             {
713                                 if ( (zaddr= jumblr_zgetnewaddress()) != 0 )
714                                 {
715                                     if ( zaddr[0] == '"' && zaddr[strlen(zaddr)-1] == '"' )
716                                     {
717                                         zaddr[strlen(zaddr)-1] = 0;
718                                         addr = zaddr+1;
719                                     } else addr = zaddr;
720                                     if ( (retstr= jumblr_sendz_to_z(ptr->dest,addr,dstr(total))) != 0 )
721                                     {
722                                         printf("n.%d counter.%d chosen_one.%d send z_to_z.(%s)\n",n,counter,chosen_one,retstr);
723                                         free(retstr);
724                                     }
725                                     ptr->spent = (uint32_t)time(NULL);
726                                     free(zaddr);
727                                     break;
728                                 }
729                             }
730                             counter++;
731                         }
732                     }
733                     n++;
734                 }
735                 if ( counter == 0 )
736                     break;
737                 if ( iter == 0 )
738                 {
739                     OS_randombytes((uint8_t *)&chosen_one,sizeof(chosen_one));
740                     if ( chosen_one < 0 )
741                         chosen_one = -chosen_one;
742                     chosen_one %= counter;
743                     printf("jumblr z->z chosen_one.%d of %d, from %d\n",chosen_one,counter,n);
744                 }
745             }
746             break;
747         case 2: // z -> t
748             if ( Jumblr_numsecretaddrs > 0 )
749             {
750                 jumblr_opidsupdate();
751                 chosen_one = -1;
752                 for (iter=0; iter<2; iter++)
753                 {
754                     counter = n = 0;
755                     HASH_ITER(hh,Jumblrs,ptr,tmp)
756                     {
757                         //printf("status.%d %c %c %.8f\n",ptr->status,jumblr_addresstype(ptr->src),jumblr_addresstype(ptr->dest),dstr(ptr->amount));
758                         if ( ptr->spent == 0 && ptr->status > 0 && jumblr_addresstype(ptr->src) == 'z' && jumblr_addresstype(ptr->dest) == 'z' )
759                         {
760                             if ( (total= jumblr_balance(ptr->dest)) >= (fee + JUMBLR_FEE)*SATOSHIDEN )
761                             {
762                                 if ( iter == 1 && counter == chosen_one )
763                                 {
764                                     Jumblr_secretaddr(secretaddr);
765                                     if ( (retstr= jumblr_sendz_to_t(ptr->dest,secretaddr,dstr(total))) != 0 )
766                                     {
767                                         printf("%s send z_to_t.(%s)\n",secretaddr,retstr);
768                                         free(retstr);
769                                     } else printf("null return from jumblr_sendz_to_t\n");
770                                     ptr->spent = (uint32_t)time(NULL);
771                                     break;
772                                 }
773                                 counter++;
774                             } //else printf("z->t spent.%u total %.8f error\n",ptr->spent,dstr(total));
775                         }
776                         n++;
777                     }
778                     if ( counter == 0 )
779                         break;
780                     if ( iter == 0 )
781                     {
782                         OS_randombytes((uint8_t *)&chosen_one,sizeof(chosen_one));
783                         if ( chosen_one < 0 )
784                             chosen_one = -chosen_one;
785                         chosen_one %= counter;
786                         printf("jumblr z->t chosen_one.%d of %d, from %d\n",chosen_one,counter,n);
787                     } //else printf("n.%d counter.%d chosen.%d\n",n,counter,chosen_one);
788                 }
789             }
790             break;
791     }
792 }
This page took 0.068525 seconds and 4 git commands to generate.