]>
Commit | Line | Data |
---|---|---|
eeaaf554 | 1 | /****************************************************************************** |
713c2a94 | 2 | * Copyright © 2014-2018 The SuperNET Developers. * |
eeaaf554 | 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 | ||
9d365796 | 27 | #ifdef _WIN32 |
28 | #include <wincrypt.h> | |
29 | #endif | |
5416af1d | 30 | #include "komodo_defs.h" |
9d365796 | 31 | |
eeaaf554 | 32 | #define JUMBLR_ADDR "RGhxXpXSSBTBm9EvNsXnTQczthMCxHX91t" |
33 | #define JUMBLR_BTCADDR "18RmTJe9qMech8siuhYfMtHo8RtcN1obC6" | |
34 | #define JUMBLR_MAXSECRETADDRS 777 | |
3db947b8 | 35 | #define JUMBLR_SYNCHRONIZED_BLOCKS 10 |
c89c562b | 36 | #define JUMBLR_INCR 9.965 |
eeaaf554 | 37 | #define JUMBLR_FEE 0.001 |
38 | #define JUMBLR_TXFEE 0.01 | |
9bbeff91 | 39 | #define SMALLVAL 0.000000000000001 |
eeaaf554 | 40 | |
3f318aa4 | 41 | #define JUMBLR_ERROR_DUPLICATEDEPOSIT -1 |
42 | #define JUMBLR_ERROR_SECRETCANTBEDEPOSIT -2 | |
43 | #define JUMBLR_ERROR_TOOMANYSECRETS -3 | |
44165ded | 44 | #define JUMBLR_ERROR_NOTINWALLET -4 |
3f318aa4 | 45 | |
eeaaf554 | 46 | struct jumblr_item |
47 | { | |
48 | UT_hash_handle hh; | |
f3f124e1 | 49 | int64_t amount,fee,txfee; // fee and txfee not really used (yet) |
eeaaf554 | 50 | uint32_t spent,pad; |
f3f124e1 | 51 | char opid[66],src[128],dest[128],status; |
eeaaf554 | 52 | } *Jumblrs; |
53 | ||
54 | char Jumblr_secretaddrs[JUMBLR_MAXSECRETADDRS][64],Jumblr_deposit[64]; | |
55 | int32_t Jumblr_numsecretaddrs; // if 0 -> run silent mode | |
56 | ||
a8ec5e86 | 57 | char *jumblr_issuemethod(char *userpass,char *method,char *params,uint16_t port) |
b487a8fe | 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 | { | |
eb416c9c | 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")); | |
b487a8fe | 68 | else |
69 | { | |
70 | resjson = cJSON_CreateObject(); | |
eb416c9c | 71 | jaddstr(resjson,(char *)"error",(char *)"cant parse return"); |
b487a8fe | 72 | } |
73 | free_json(retjson); | |
74 | } | |
75 | free(retstr); | |
76 | } | |
77 | if ( resjson != 0 ) | |
78 | return(jprint(resjson,1)); | |
eb416c9c | 79 | else return(clonestr((char *)"{\"error\":\"unknown error\"}")); |
b487a8fe | 80 | } |
81 | ||
19acd959 | 82 | char *jumblr_importaddress(char *address) |
eeaaf554 | 83 | { |
84 | char params[1024]; | |
85 | sprintf(params,"[\"%s\", \"%s\", false]",address,address); | |
307d443c | 86 | return(jumblr_issuemethod(KMDUSERPASS,(char *)"importaddress",params,BITCOIND_RPCPORT)); |
eeaaf554 | 87 | } |
88 | ||
44165ded | 89 | char *jumblr_validateaddress(char *addr) |
90 | { | |
91 | char params[1024]; | |
db53f4bf | 92 | sprintf(params,"[\"%s\"]",addr); |
6ba30dbb | 93 | printf("validateaddress.%s\n",params); |
307d443c | 94 | return(jumblr_issuemethod(KMDUSERPASS,(char *)"validateaddress",params,BITCOIND_RPCPORT)); |
44165ded | 95 | } |
96 | ||
eeaaf554 | 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; | |
3f318aa4 | 111 | if ( secretaddr != 0 && secretaddr[0] != 0 ) |
eeaaf554 | 112 | { |
3f318aa4 | 113 | if ( Jumblr_numsecretaddrs < JUMBLR_MAXSECRETADDRS ) |
eeaaf554 | 114 | { |
3f318aa4 | 115 | if ( strcmp(Jumblr_deposit,secretaddr) != 0 ) |
116 | { | |
117 | if ( (ind= Jumblr_secretaddrfind(secretaddr)) < 0 ) | |
118 | { | |
c89c562b | 119 | ind = Jumblr_numsecretaddrs++; |
120 | safecopy(Jumblr_secretaddrs[ind],secretaddr,64); | |
121 | } | |
122 | return(ind); | |
3f318aa4 | 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; | |
eeaaf554 | 130 | } |
131 | return(Jumblr_numsecretaddrs); | |
132 | } | |
133 | ||
b487a8fe | 134 | int32_t Jumblr_depositaddradd(char *depositaddr) // external |
eeaaf554 | 135 | { |
44165ded | 136 | int32_t ind,retval = JUMBLR_ERROR_DUPLICATEDEPOSIT; char *retstr; cJSON *retjson,*ismine; |
eeaaf554 | 137 | if ( depositaddr == 0 ) |
19acd959 | 138 | depositaddr = (char *)""; |
9bbeff91 | 139 | if ( (ind= Jumblr_secretaddrfind(depositaddr)) < 0 ) |
eeaaf554 | 140 | { |
44165ded | 141 | if ( (retstr= jumblr_validateaddress(depositaddr)) != 0 ) |
b487a8fe | 142 | { |
143 | if ( (retjson= cJSON_Parse(retstr)) != 0 ) | |
144 | { | |
d430a5e8 | 145 | if ( (ismine= jobj(retjson,(char *)"ismine")) != 0 && cJSON_IsTrue(ismine) != 0 ) |
6ba30dbb | 146 | { |
a8ec5e86 | 147 | retval = 0; |
6ba30dbb | 148 | safecopy(Jumblr_deposit,depositaddr,sizeof(Jumblr_deposit)); |
149 | } | |
08952acd | 150 | else |
151 | { | |
152 | retval = JUMBLR_ERROR_NOTINWALLET; | |
d430a5e8 | 153 | printf("%s not in wallet: ismine.%p %d %s\n",depositaddr,ismine,cJSON_IsTrue(ismine),jprint(retjson,0)); |
08952acd | 154 | } |
b487a8fe | 155 | free_json(retjson); |
156 | } | |
157 | free(retstr); | |
158 | } | |
159 | } | |
160 | return(retval); | |
eeaaf554 | 161 | } |
162 | ||
9d365796 | 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 | ||
eeaaf554 | 173 | int32_t Jumblr_secretaddr(char *secretaddr) |
174 | { | |
175 | uint32_t r; | |
176 | if ( Jumblr_numsecretaddrs > 0 ) | |
177 | { | |
19acd959 | 178 | OS_randombytes((uint8_t *)&r,sizeof(r)); |
eeaaf554 | 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 | { | |
aa3be97e | 187 | if ( addr[0] == '"' && addr[strlen(addr)-1] == '"' ) |
c8e62868 | 188 | { |
aa3be97e | 189 | addr[strlen(addr)-1] = 0; |
190 | addr++; | |
c8e62868 | 191 | } |
aa3be97e | 192 | if ( addr[0] == 'z' && addr[1] == 'c' && strlen(addr) >= 40 ) |
193 | return('z'); | |
eeaaf554 | 194 | else if ( strlen(addr) < 40 ) |
195 | return('t'); | |
c8e62868 | 196 | printf("strange.(%s)\n",addr); |
197 | return(-1); | |
eeaaf554 | 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 | { | |
8ac54273 | 209 | struct jumblr_item *ptr = 0; |
210 | if ( opid != 0 && (ptr= jumblr_opidfind(opid)) == 0 ) | |
eeaaf554 | 211 | { |
19acd959 | 212 | ptr = (struct jumblr_item *)calloc(1,sizeof(*ptr)); |
eeaaf554 | 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 | ||
eeaaf554 | 221 | char *jumblr_zgetnewaddress() |
222 | { | |
223 | char params[1024]; | |
19acd959 | 224 | sprintf(params,"[]"); |
307d443c | 225 | return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_getnewaddress",params,BITCOIND_RPCPORT)); |
eeaaf554 | 226 | } |
227 | ||
228 | char *jumblr_zlistoperationids() | |
229 | { | |
230 | char params[1024]; | |
19acd959 | 231 | sprintf(params,"[]"); |
307d443c | 232 | return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_listoperationids",params,BITCOIND_RPCPORT)); |
eeaaf554 | 233 | } |
234 | ||
235 | char *jumblr_zgetoperationresult(char *opid) | |
236 | { | |
237 | char params[1024]; | |
238 | sprintf(params,"[[\"%s\"]]",opid); | |
307d443c | 239 | return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_getoperationresult",params,BITCOIND_RPCPORT)); |
eeaaf554 | 240 | } |
241 | ||
242 | char *jumblr_zgetoperationstatus(char *opid) | |
243 | { | |
244 | char params[1024]; | |
245 | sprintf(params,"[[\"%s\"]]",opid); | |
307d443c | 246 | return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_getoperationstatus",params,BITCOIND_RPCPORT)); |
eeaaf554 | 247 | } |
248 | ||
249 | char *jumblr_sendt_to_z(char *taddr,char *zaddr,double amount) | |
250 | { | |
c89c562b | 251 | char params[1024]; double fee = ((amount-3*JUMBLR_TXFEE) * JUMBLR_FEE) * 1.5; |
eeaaf554 | 252 | if ( jumblr_addresstype(zaddr) != 'z' || jumblr_addresstype(taddr) != 't' ) |
19acd959 | 253 | return(clonestr((char *)"{\"error\":\"illegal address in t to z\"}")); |
eeaaf554 | 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); |
61a0f96b | 255 | printf("t -> z: %s\n",params); |
307d443c | 256 | return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_sendmany",params,BITCOIND_RPCPORT)); |
eeaaf554 | 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' ) | |
19acd959 | 263 | return(clonestr((char *)"{\"error\":\"illegal address in z to z\"}")); |
c89c562b | 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); | |
61a0f96b | 266 | printf("z -> z: %s\n",params); |
307d443c | 267 | return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_sendmany",params,BITCOIND_RPCPORT)); |
eeaaf554 | 268 | } |
269 | ||
270 | char *jumblr_sendz_to_t(char *zaddr,char *taddr,double amount) | |
271 | { | |
c89c562b | 272 | char params[1024]; double fee = ((amount-JUMBLR_TXFEE) * JUMBLR_FEE) * 1.5; |
eeaaf554 | 273 | if ( jumblr_addresstype(zaddr) != 'z' || jumblr_addresstype(taddr) != 't' ) |
19acd959 | 274 | return(clonestr((char *)"{\"error\":\"illegal address in z to t\"}")); |
eeaaf554 | 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); |
61a0f96b | 276 | printf("z -> t: %s\n",params); |
307d443c | 277 | return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_sendmany",params,BITCOIND_RPCPORT)); |
eeaaf554 | 278 | } |
279 | ||
007d1a86 | 280 | char *jumblr_zlistaddresses() |
421d71a2 | 281 | { |
282 | char params[1024]; | |
007d1a86 | 283 | sprintf(params,"[]"); |
307d443c | 284 | return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_listaddresses",params,BITCOIND_RPCPORT)); |
421d71a2 | 285 | } |
286 | ||
eeaaf554 | 287 | char *jumblr_zlistreceivedbyaddress(char *addr) |
288 | { | |
289 | char params[1024]; | |
290 | sprintf(params,"[\"%s\", 1]",addr); | |
307d443c | 291 | return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_listreceivedbyaddress",params,BITCOIND_RPCPORT)); |
eeaaf554 | 292 | } |
293 | ||
294 | char *jumblr_getreceivedbyaddress(char *addr) | |
295 | { | |
296 | char params[1024]; | |
297 | sprintf(params,"[\"%s\", 1]",addr); | |
307d443c | 298 | return(jumblr_issuemethod(KMDUSERPASS,(char *)"getreceivedbyaddress",params,BITCOIND_RPCPORT)); |
eeaaf554 | 299 | } |
300 | ||
301 | char *jumblr_importprivkey(char *wifstr) | |
302 | { | |
303 | char params[1024]; | |
304 | sprintf(params,"[\"%s\", \"\", false]",wifstr); | |
307d443c | 305 | return(jumblr_issuemethod(KMDUSERPASS,(char *)"importprivkey",params,BITCOIND_RPCPORT)); |
eeaaf554 | 306 | } |
307 | ||
308 | char *jumblr_zgetbalance(char *addr) | |
309 | { | |
310 | char params[1024]; | |
311 | sprintf(params,"[\"%s\", 1]",addr); | |
307d443c | 312 | return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_getbalance",params,BITCOIND_RPCPORT)); |
eeaaf554 | 313 | } |
314 | ||
315 | char *jumblr_listunspent(char *coinaddr) | |
316 | { | |
317 | char params[1024]; | |
318 | sprintf(params,"[1, 99999999, [\"%s\"]]",coinaddr); | |
307d443c | 319 | return(jumblr_issuemethod(KMDUSERPASS,(char *)"listunspent",params,BITCOIND_RPCPORT)); |
eeaaf554 | 320 | } |
321 | ||
bbd64789 | 322 | char *jumblr_gettransaction(char *txidstr) |
323 | { | |
324 | char params[1024]; | |
325 | sprintf(params,"[\"%s\", 1]",txidstr); | |
307d443c | 326 | return(jumblr_issuemethod(KMDUSERPASS,(char *)"getrawtransaction",params,BITCOIND_RPCPORT)); |
bbd64789 | 327 | } |
328 | ||
329 | int32_t jumblr_numvins(bits256 txid) | |
330 | { | |
d506468b | 331 | char txidstr[65],params[1024],*retstr; cJSON *retjson,*vins; int32_t n,numvins = -1; |
bbd64789 | 332 | bits256_str(txidstr,txid); |
333 | if ( (retstr= jumblr_gettransaction(txidstr)) != 0 ) | |
334 | { | |
335 | if ( (retjson= cJSON_Parse(retstr)) != 0 ) | |
336 | { | |
c4818fd4 | 337 | if ( jobj(retjson,(char *)"vin") != 0 && ((vins= jarray(&n,retjson,(char *)"vin")) == 0 || n == 0) ) |
ad74c1a3 | 338 | { |
bbd64789 | 339 | numvins = n; |
c4818fd4 | 340 | //printf("numvins.%d\n",n); |
341 | } //else printf("no vin.(%s)\n",retstr); | |
bbd64789 | 342 | free_json(retjson); |
343 | } | |
344 | free(retstr); | |
345 | } | |
346 | return(numvins); | |
347 | } | |
348 | ||
eeaaf554 | 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 | { | |
78408e6b | 362 | char *retstr; double val; int64_t balance = 0; //cJSON *retjson; int32_t i,n; |
90da8c91 | 363 | /*if ( jumblr_addresstype(addr) == 't' ) |
eeaaf554 | 364 | { |
365 | if ( (retstr= jumblr_listunspent(addr)) != 0 ) | |
366 | { | |
61a0f96b | 367 | //printf("jumblr.[%s].(%s)\n","KMD",retstr); |
eeaaf554 | 368 | if ( (retjson= cJSON_Parse(retstr)) != 0 ) |
369 | { | |
d430a5e8 | 370 | if ( (n= cJSON_GetArraySize(retjson)) > 0 && cJSON_IsArray(retjson) != 0 ) |
eeaaf554 | 371 | for (i=0; i<n; i++) |
19acd959 | 372 | balance += SATOSHIDEN * jdouble(jitem(retjson,i),(char *)"amount"); |
eeaaf554 | 373 | free_json(retjson); |
374 | } | |
375 | free(retstr); | |
376 | } | |
377 | } | |
90da8c91 | 378 | else*/ if ( (retstr= jumblr_zgetbalance(addr)) != 0 ) |
eeaaf554 | 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 | }*/ | |
19acd959 | 401 | if ( (params= jobj(item,(char *)"params")) != 0 ) |
eeaaf554 | 402 | { |
403 | //printf("params.(%s)\n",jprint(params,0)); | |
19acd959 | 404 | if ( (from= jstr(params,(char *)"fromaddress")) != 0 ) |
eeaaf554 | 405 | { |
406 | safecopy(ptr->src,from,sizeof(ptr->src)); | |
407 | } | |
19acd959 | 408 | if ( (amounts= jarray(&n,params,(char *)"amounts")) != 0 ) |
eeaaf554 | 409 | { |
410 | for (i=0; i<n; i++) | |
411 | { | |
412 | dest = jitem(amounts,i); | |
413 | //printf("%s ",jprint(dest,0)); | |
19acd959 | 414 | if ( (addr= jstr(dest,(char *)"address")) != 0 && (amount= jdouble(dest,(char *)"amount")*SATOSHIDEN) > 0 ) |
eeaaf554 | 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 | } | |
19acd959 | 426 | ptr->txfee = jdouble(params,(char *)"fee") * SATOSHIDEN; |
eeaaf554 | 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 | { | |
d430a5e8 | 440 | if ( cJSON_GetArraySize(retjson) == 1 && cJSON_IsArray(retjson) != 0 ) |
eeaaf554 | 441 | { |
442 | item = jitem(retjson,0); | |
443 | //printf("%s\n",jprint(item,0)); | |
19acd959 | 444 | if ( (status= jstr(item,(char *)"status")) != 0 ) |
eeaaf554 | 445 | { |
19acd959 | 446 | if ( strcmp(status,(char *)"success") == 0 ) |
eeaaf554 | 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 | } | |
19acd959 | 457 | else if ( strcmp(status,(char *)"failed") == 0 ) |
eeaaf554 | 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; | |
eb23a642 | 475 | if ( is_hexstr(ptr->opid,0) == 64 ) |
476 | return; | |
eeaaf554 | 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 | { | |
eb23a642 | 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 | } | |
eeaaf554 | 495 | } |
496 | } | |
497 | } | |
498 | } | |
499 | ||
d430a5e8 SS |
500 | |
501 | bits256 jbits256(cJSON *json,char *field); | |
502 | ||
503 | ||
421d71a2 | 504 | void jumblr_zaddrinit(char *zaddr) |
505 | { | |
bbd64789 | 506 | struct jumblr_item *ptr; char *retstr,*totalstr; cJSON *item,*array; double total; bits256 txid; char txidstr[65],t_z,z_z; |
f3f124e1 | 507 | if ( (totalstr= jumblr_zgetbalance(zaddr)) != 0 ) |
421d71a2 | 508 | { |
e5dfb297 | 509 | if ( (total= atof(totalstr)) > SMALLVAL ) |
421d71a2 | 510 | { |
f3f124e1 | 511 | if ( (retstr= jumblr_zlistreceivedbyaddress(zaddr)) != 0 ) |
512 | { | |
513 | if ( (array= cJSON_Parse(retstr)) != 0 ) | |
514 | { | |
afae290a | 515 | t_z = z_z = 0; |
d430a5e8 | 516 | if ( cJSON_GetArraySize(array) == 1 && cJSON_IsArray(array) != 0 ) |
f3f124e1 | 517 | { |
518 | item = jitem(array,0); | |
b8623323 | 519 | if ( (uint64_t)((total+0.0000000049) * SATOSHIDEN) == (uint64_t)((jdouble(item,(char *)"amount")+0.0000000049) * SATOSHIDEN) ) |
f3f124e1 | 520 | { |
bbd64789 | 521 | txid = jbits256(item,(char *)"txid"); |
f3f124e1 | 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); | |
231bcedc | 528 | if ( jumblr_addresstype(ptr->dest) != 'z' ) |
529 | printf("error setting dest type to Z: %s\n",jprint(item,0)); | |
f3f124e1 | 530 | if ( jumblr_numvins(txid) == 0 ) |
531 | { | |
532 | z_z = 1; | |
231bcedc | 533 | strcpy(ptr->src,zaddr); |
eb23a642 | 534 | ptr->src[3] = '0'; |
535 | ptr->src[4] = '0'; | |
536 | ptr->src[5] = '0'; | |
f3f124e1 | 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 | } | |
255e8e69 | 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))); |
f3f124e1 | 550 | } |
551 | free_json(array); | |
552 | } | |
553 | free(retstr); | |
554 | } | |
421d71a2 | 555 | } |
f3f124e1 | 556 | free(totalstr); |
421d71a2 | 557 | } |
558 | } | |
559 | ||
eeaaf554 | 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 | { | |
d430a5e8 | 567 | if ( (n= cJSON_GetArraySize(array)) > 0 && cJSON_IsArray(array) != 0 ) |
eeaaf554 | 568 | { |
c89c562b | 569 | //printf("%s -> n%d\n",retstr,n); |
eeaaf554 | 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 | ||
ae85ad79 | 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])); | |
88de65be | 622 | printf("n.%d incrs r.%d -> %.8f\n",n,r,dstr(incrs[r])); |
ae85ad79 | 623 | return(incrs[r]); |
624 | } | |
625 | } | |
626 | return(0); | |
627 | } | |
628 | ||
eeaaf554 | 629 | void jumblr_iteration() |
630 | { | |
dca9da68 | 631 | static int32_t lastheight; static uint32_t lasttime; |
ae85ad79 | 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; |
eea03b7b | 633 | if ( JUMBLR_PAUSE != 0 ) |
634 | return; | |
421d71a2 | 635 | if ( lasttime == 0 ) |
636 | { | |
637 | if ( (retstr= jumblr_zlistaddresses()) != 0 ) | |
638 | { | |
639 | if ( (array= cJSON_Parse(retstr)) != 0 ) | |
640 | { | |
d430a5e8 | 641 | if ( (n= cJSON_GetArraySize(array)) > 0 && cJSON_IsArray(array) != 0 ) |
421d71a2 | 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 | } | |
4b729ec5 | 651 | height = (int32_t)chainActive.LastTip()->GetHeight(); |
a039c62d | 652 | if ( time(NULL) < lasttime+40 ) |
dca9da68 | 653 | return; |
654 | lasttime = (uint32_t)time(NULL); | |
421d71a2 | 655 | if ( lastheight == height ) |
656 | return; | |
6a1b2452 | 657 | lastheight = height; |
a039c62d | 658 | if ( (height % JUMBLR_SYNCHRONIZED_BLOCKS) != JUMBLR_SYNCHRONIZED_BLOCKS-3 ) |
eeaaf554 | 659 | return; |
660 | fee = JUMBLR_INCR * JUMBLR_FEE; | |
ae85ad79 | 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); | |
fd9256e8 | 664 | OS_randombytes((uint8_t *)&r,sizeof(r)); |
ae85ad79 | 665 | s = (r % 3); |
0a92b261 | 666 | //printf("jumblr_iteration r.%u s.%u\n",r,s); |
eeaaf554 | 667 | switch ( s ) |
668 | { | |
eb23a642 | 669 | case 0: // t -> z |
ae85ad79 | 670 | default: |
671 | if ( Jumblr_deposit[0] != 0 && (total= jumblr_balance(Jumblr_deposit)) >= smallest ) | |
eeaaf554 | 672 | { |
673 | if ( (zaddr= jumblr_zgetnewaddress()) != 0 ) | |
674 | { | |
20082066 | 675 | if ( zaddr[0] == '"' && zaddr[strlen(zaddr)-1] == '"' ) |
676 | { | |
677 | zaddr[strlen(zaddr)-1] = 0; | |
678 | addr = zaddr+1; | |
679 | } else addr = zaddr; | |
ae85ad79 | 680 | amount = jumblr_increment(r/3,height,total,biggest,medium,smallest); |
9d365796 | 681 | /* |
eeaaf554 | 682 | amount = 0; |
683 | if ( (height % (JUMBLR_SYNCHRONIZED_BLOCKS*JUMBLR_SYNCHRONIZED_BLOCKS)) == 0 && total >= SATOSHIDEN * ((JUMBLR_INCR + 3*fee)*100 + 3*JUMBLR_TXFEE) ) | |
ae85ad79 | 684 | amount = SATOSHIDEN * ((JUMBLR_INCR + 3*fee)*100 + 3*JUMBLR_TXFEE); |
eeaaf554 | 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); | |
ae85ad79 | 687 | else amount = SATOSHIDEN * ((JUMBLR_INCR + 3*fee) + 3*JUMBLR_TXFEE);*/ |
20082066 | 688 | if ( amount > 0 && (retstr= jumblr_sendt_to_z(Jumblr_deposit,addr,dstr(amount))) != 0 ) |
eeaaf554 | 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 | { | |
1cacba6a | 707 | if ( ptr->spent == 0 && ptr->status > 0 && jumblr_addresstype(ptr->src) == 't' && jumblr_addresstype(ptr->dest) == 'z' ) |
eeaaf554 | 708 | { |
1cacba6a | 709 | if ( (total= jumblr_balance(ptr->dest)) >= (fee + JUMBLR_FEE)*SATOSHIDEN ) |
eeaaf554 | 710 | { |
711 | if ( iter == 1 && counter == chosen_one ) | |
712 | { | |
713 | if ( (zaddr= jumblr_zgetnewaddress()) != 0 ) | |
714 | { | |
dca9da68 | 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 ) | |
eeaaf554 | 721 | { |
eb23a642 | 722 | printf("n.%d counter.%d chosen_one.%d send z_to_z.(%s)\n",n,counter,chosen_one,retstr); |
eeaaf554 | 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; | |
eb23a642 | 747 | case 2: // z -> t |
eeaaf554 | 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 | { | |
eb23a642 | 757 | //printf("status.%d %c %c %.8f\n",ptr->status,jumblr_addresstype(ptr->src),jumblr_addresstype(ptr->dest),dstr(ptr->amount)); |
1cacba6a | 758 | if ( ptr->spent == 0 && ptr->status > 0 && jumblr_addresstype(ptr->src) == 'z' && jumblr_addresstype(ptr->dest) == 'z' ) |
eeaaf554 | 759 | { |
1cacba6a | 760 | if ( (total= jumblr_balance(ptr->dest)) >= (fee + JUMBLR_FEE)*SATOSHIDEN ) |
eeaaf554 | 761 | { |
3db947b8 | 762 | if ( iter == 1 && counter == chosen_one ) |
eeaaf554 | 763 | { |
764 | Jumblr_secretaddr(secretaddr); | |
765 | if ( (retstr= jumblr_sendz_to_t(ptr->dest,secretaddr,dstr(total))) != 0 ) | |
766 | { | |
eb23a642 | 767 | printf("%s send z_to_t.(%s)\n",secretaddr,retstr); |
eeaaf554 | 768 | free(retstr); |
c89c562b | 769 | } else printf("null return from jumblr_sendz_to_t\n"); |
eeaaf554 | 770 | ptr->spent = (uint32_t)time(NULL); |
771 | break; | |
772 | } | |
773 | counter++; | |
3db947b8 | 774 | } //else printf("z->t spent.%u total %.8f error\n",ptr->spent,dstr(total)); |
eeaaf554 | 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); | |
3db947b8 | 787 | } //else printf("n.%d counter.%d chosen.%d\n",n,counter,chosen_one); |
eeaaf554 | 788 | } |
789 | } | |
790 | break; | |
791 | } | |
792 | } |