]> Git Repo - VerusCoin.git/blob - src/komodo_utils.h
Set vrsctest rewards to 12 to match mainnet
[VerusCoin.git] / src / komodo_utils.h
1 /******************************************************************************
2  * Copyright © 2014-2018 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 #include "komodo_defs.h"
16 #include "key_io.h"
17 #include "pbaas/crosschainrpc.h"
18 #include "pbaas/identity.h"
19 #include <string.h>
20
21 #ifdef _WIN32
22 #include <sodium.h>
23 #include <boost/date_time/posix_time/posix_time.hpp>
24 #include <boost/thread.hpp>
25 #endif
26
27 #define dstr(x) ((double)(x) / SATOSHIDEN)
28 #define portable_mutex_t pthread_mutex_t
29 #define portable_mutex_init(ptr) pthread_mutex_init(ptr,NULL)
30 #define portable_mutex_lock pthread_mutex_lock
31 #define portable_mutex_unlock pthread_mutex_unlock
32
33 extern void verus_hash(void *result, const void *data, size_t len);
34
35 struct allocitem { uint32_t allocsize,type; };
36 struct queueitem { struct queueitem *next,*prev; uint32_t allocsize,type;  };
37
38 typedef struct queue
39 {
40         struct queueitem *list;
41         pthread_mutex_t mutex;
42     char name[64],initflag;
43 } queue_t;
44
45 #include "mini-gmp.c"
46
47 #define CRYPTO777_PUBSECPSTR "020e46e79a2a8d12b9b5d12c7a91adb4e454edfae43c0a0cb805427d2ac7613fd9"
48 #define CRYPTO777_KMDADDR "RXL3YXG2ceaB6C5hfJcN4fvmLH2C34knhA"
49 #define CRYPTO777_RMD160STR "f1dce4182fce875748c4986b240ff7d7bc3fffb0"
50
51 #define KOMODO_PUBTYPE 60
52
53 struct sha256_vstate { uint64_t length; uint32_t state[8],curlen; uint8_t buf[64]; };
54 struct rmd160_vstate { uint64_t length; uint8_t buf[64]; uint32_t curlen, state[5]; };
55
56 // following is ported from libtom
57
58 #define STORE32L(x, y)                                                                     \
59 { (y)[3] = (uint8_t)(((x)>>24)&255); (y)[2] = (uint8_t)(((x)>>16)&255);   \
60 (y)[1] = (uint8_t)(((x)>>8)&255); (y)[0] = (uint8_t)((x)&255); }
61
62 #define LOAD32L(x, y)                            \
63 { x = (uint32_t)(((uint64_t)((y)[3] & 255)<<24) | \
64 ((uint32_t)((y)[2] & 255)<<16) | \
65 ((uint32_t)((y)[1] & 255)<<8)  | \
66 ((uint32_t)((y)[0] & 255))); }
67
68 #define STORE64L(x, y)                                                                     \
69 { (y)[7] = (uint8_t)(((x)>>56)&255); (y)[6] = (uint8_t)(((x)>>48)&255);   \
70 (y)[5] = (uint8_t)(((x)>>40)&255); (y)[4] = (uint8_t)(((x)>>32)&255);   \
71 (y)[3] = (uint8_t)(((x)>>24)&255); (y)[2] = (uint8_t)(((x)>>16)&255);   \
72 (y)[1] = (uint8_t)(((x)>>8)&255); (y)[0] = (uint8_t)((x)&255); }
73
74 #define LOAD64L(x, y)                                                       \
75 { x = (((uint64_t)((y)[7] & 255))<<56)|(((uint64_t)((y)[6] & 255))<<48)| \
76 (((uint64_t)((y)[5] & 255))<<40)|(((uint64_t)((y)[4] & 255))<<32)| \
77 (((uint64_t)((y)[3] & 255))<<24)|(((uint64_t)((y)[2] & 255))<<16)| \
78 (((uint64_t)((y)[1] & 255))<<8)|(((uint64_t)((y)[0] & 255))); }
79
80 #define STORE32H(x, y)                                                                     \
81 { (y)[0] = (uint8_t)(((x)>>24)&255); (y)[1] = (uint8_t)(((x)>>16)&255);   \
82 (y)[2] = (uint8_t)(((x)>>8)&255); (y)[3] = (uint8_t)((x)&255); }
83
84 #define LOAD32H(x, y)                            \
85 { x = (uint32_t)(((uint64_t)((y)[0] & 255)<<24) | \
86 ((uint32_t)((y)[1] & 255)<<16) | \
87 ((uint32_t)((y)[2] & 255)<<8)  | \
88 ((uint32_t)((y)[3] & 255))); }
89
90 #define STORE64H(x, y)                                                                     \
91 { (y)[0] = (uint8_t)(((x)>>56)&255); (y)[1] = (uint8_t)(((x)>>48)&255);     \
92 (y)[2] = (uint8_t)(((x)>>40)&255); (y)[3] = (uint8_t)(((x)>>32)&255);     \
93 (y)[4] = (uint8_t)(((x)>>24)&255); (y)[5] = (uint8_t)(((x)>>16)&255);     \
94 (y)[6] = (uint8_t)(((x)>>8)&255); (y)[7] = (uint8_t)((x)&255); }
95
96 #define LOAD64H(x, y)                                                      \
97 { x = (((uint64_t)((y)[0] & 255))<<56)|(((uint64_t)((y)[1] & 255))<<48) | \
98 (((uint64_t)((y)[2] & 255))<<40)|(((uint64_t)((y)[3] & 255))<<32) | \
99 (((uint64_t)((y)[4] & 255))<<24)|(((uint64_t)((y)[5] & 255))<<16) | \
100 (((uint64_t)((y)[6] & 255))<<8)|(((uint64_t)((y)[7] & 255))); }
101
102 // Various logical functions
103 #define RORc(x, y) ( ((((uint32_t)(x)&0xFFFFFFFFUL)>>(uint32_t)((y)&31)) | ((uint32_t)(x)<<(uint32_t)(32-((y)&31)))) & 0xFFFFFFFFUL)
104 #define Ch(x,y,z)       (z ^ (x & (y ^ z)))
105 #define Maj(x,y,z)      (((x | y) & z) | (x & y))
106 #define S(x, n)         RORc((x),(n))
107 #define R(x, n)         (((x)&0xFFFFFFFFUL)>>(n))
108 #define Sigma0(x)       (S(x, 2) ^ S(x, 13) ^ S(x, 22))
109 #define Sigma1(x)       (S(x, 6) ^ S(x, 11) ^ S(x, 25))
110 #define Gamma0(x)       (S(x, 7) ^ S(x, 18) ^ R(x, 3))
111 #define Gamma1(x)       (S(x, 17) ^ S(x, 19) ^ R(x, 10))
112 #define MIN(x, y) ( ((x)<(y))?(x):(y) )
113
114 static inline int32_t sha256_vcompress(struct sha256_vstate * md,uint8_t *buf)
115 {
116     uint32_t S[8],W[64],t0,t1,i;
117     for (i=0; i<8; i++) // copy state into S
118         S[i] = md->state[i];
119     for (i=0; i<16; i++) // copy the state into 512-bits into W[0..15]
120         LOAD32H(W[i],buf + (4*i));
121     for (i=16; i<64; i++) // fill W[16..63]
122         W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
123
124 #define RND(a,b,c,d,e,f,g,h,i,ki)                    \
125 t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i];   \
126 t1 = Sigma0(a) + Maj(a, b, c);                  \
127 d += t0;                                        \
128 h  = t0 + t1;
129
130     RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98);
131     RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x71374491);
132     RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcf);
133     RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba5);
134     RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25b);
135     RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1);
136     RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4);
137     RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5);
138     RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98);
139     RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b01);
140     RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be);
141     RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3);
142     RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74);
143     RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe);
144     RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a7);
145     RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174);
146     RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c1);
147     RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786);
148     RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc6);
149     RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc);
150     RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f);
151     RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa);
152     RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dc);
153     RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da);
154     RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152);
155     RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d);
156     RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c8);
157     RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7);
158     RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf3);
159     RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147);
160     RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351);
161     RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x14292967);
162     RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a85);
163     RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b2138);
164     RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc);
165     RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d13);
166     RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a7354);
167     RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb);
168     RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e);
169     RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c85);
170     RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a1);
171     RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664b);
172     RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70);
173     RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a3);
174     RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819);
175     RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd6990624);
176     RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e3585);
177     RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa070);
178     RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116);
179     RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c08);
180     RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774c);
181     RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5);
182     RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3);
183     RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4a);
184     RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f);
185     RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3);
186     RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee);
187     RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f);
188     RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814);
189     RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc70208);
190     RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa);
191     RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506ceb);
192     RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7);
193     RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2);
194 #undef RND
195     for (i=0; i<8; i++) // feedback
196         md->state[i] = md->state[i] + S[i];
197     return(0);
198 }
199
200 #undef RORc
201 #undef Ch
202 #undef Maj
203 #undef S
204 #undef R
205 #undef Sigma0
206 #undef Sigma1
207 #undef Gamma0
208 #undef Gamma1
209
210 static inline void sha256_vinit(struct sha256_vstate * md)
211 {
212     md->curlen = 0;
213     md->length = 0;
214     md->state[0] = 0x6A09E667UL;
215     md->state[1] = 0xBB67AE85UL;
216     md->state[2] = 0x3C6EF372UL;
217     md->state[3] = 0xA54FF53AUL;
218     md->state[4] = 0x510E527FUL;
219     md->state[5] = 0x9B05688CUL;
220     md->state[6] = 0x1F83D9ABUL;
221     md->state[7] = 0x5BE0CD19UL;
222 }
223
224 static inline int32_t sha256_vprocess(struct sha256_vstate *md,const uint8_t *in,uint64_t inlen)
225 {
226     uint64_t n; int32_t err;
227     if ( md->curlen > sizeof(md->buf) )
228         return(-1);
229     while ( inlen > 0 )
230     {
231         if ( md->curlen == 0 && inlen >= 64 )
232         {
233             if ( (err= sha256_vcompress(md,(uint8_t *)in)) != 0 )
234                 return(err);
235             md->length += 64 * 8, in += 64, inlen -= 64;
236         }
237         else
238         {
239             n = MIN(inlen,64 - md->curlen);
240             memcpy(md->buf + md->curlen,in,(size_t)n);
241             md->curlen += n, in += n, inlen -= n;
242             if ( md->curlen == 64 )
243             {
244                 if ( (err= sha256_vcompress(md,md->buf)) != 0 )
245                     return(err);
246                 md->length += 8*64;
247                 md->curlen = 0;
248             }
249         }
250     }
251     return(0);
252 }
253
254 static inline int32_t sha256_vdone(struct sha256_vstate *md,uint8_t *out)
255 {
256     int32_t i;
257     if ( md->curlen >= sizeof(md->buf) )
258         return(-1);
259     md->length += md->curlen * 8; // increase the length of the message
260     md->buf[md->curlen++] = (uint8_t)0x80; // append the '1' bit
261     // if len > 56 bytes we append zeros then compress.  Then we can fall back to padding zeros and length encoding like normal.
262     if ( md->curlen > 56 )
263     {
264         while ( md->curlen < 64 )
265             md->buf[md->curlen++] = (uint8_t)0;
266         sha256_vcompress(md,md->buf);
267         md->curlen = 0;
268     }
269     while ( md->curlen < 56 ) // pad upto 56 bytes of zeroes
270         md->buf[md->curlen++] = (uint8_t)0;
271     STORE64H(md->length,md->buf+56); // store length
272     sha256_vcompress(md,md->buf);
273     for (i=0; i<8; i++) // copy output
274         STORE32H(md->state[i],out+(4*i));
275     return(0);
276 }
277
278 void vcalc_sha256(char deprecated[(256 >> 3) * 2 + 1],uint8_t hash[256 >> 3],uint8_t *src,int32_t len)
279 {
280     struct sha256_vstate md;
281     sha256_vinit(&md);
282     sha256_vprocess(&md,src,len);
283     sha256_vdone(&md,hash);
284 }
285
286 bits256 bits256_doublesha256(char *deprecated,uint8_t *data,int32_t datalen)
287 {
288     bits256 hash,hash2; int32_t i;
289     vcalc_sha256(0,hash.bytes,data,datalen);
290     vcalc_sha256(0,hash2.bytes,hash.bytes,sizeof(hash));
291     for (i=0; i<sizeof(hash); i++)
292         hash.bytes[i] = hash2.bytes[sizeof(hash) - 1 - i];
293     return(hash);
294 }
295
296
297 // rmd160: the five basic functions F(), G() and H()
298 #define F(x, y, z)        ((x) ^ (y) ^ (z))
299 #define G(x, y, z)        (((x) & (y)) | (~(x) & (z)))
300 #define H(x, y, z)        (((x) | ~(y)) ^ (z))
301 #define I(x, y, z)        (((x) & (z)) | ((y) & ~(z)))
302 #define J(x, y, z)        ((x) ^ ((y) | ~(z)))
303 #define ROLc(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
304
305 /* the ten basic operations FF() through III() */
306 #define FF(a, b, c, d, e, x, s)        \
307 (a) += F((b), (c), (d)) + (x);\
308 (a) = ROLc((a), (s)) + (e);\
309 (c) = ROLc((c), 10);
310
311 #define GG(a, b, c, d, e, x, s)        \
312 (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
313 (a) = ROLc((a), (s)) + (e);\
314 (c) = ROLc((c), 10);
315
316 #define HH(a, b, c, d, e, x, s)        \
317 (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
318 (a) = ROLc((a), (s)) + (e);\
319 (c) = ROLc((c), 10);
320
321 #define II(a, b, c, d, e, x, s)        \
322 (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
323 (a) = ROLc((a), (s)) + (e);\
324 (c) = ROLc((c), 10);
325
326 #define JJ(a, b, c, d, e, x, s)        \
327 (a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\
328 (a) = ROLc((a), (s)) + (e);\
329 (c) = ROLc((c), 10);
330
331 #define FFF(a, b, c, d, e, x, s)        \
332 (a) += F((b), (c), (d)) + (x);\
333 (a) = ROLc((a), (s)) + (e);\
334 (c) = ROLc((c), 10);
335
336 #define GGG(a, b, c, d, e, x, s)        \
337 (a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\
338 (a) = ROLc((a), (s)) + (e);\
339 (c) = ROLc((c), 10);
340
341 #define HHH(a, b, c, d, e, x, s)        \
342 (a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\
343 (a) = ROLc((a), (s)) + (e);\
344 (c) = ROLc((c), 10);
345
346 #define III(a, b, c, d, e, x, s)        \
347 (a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\
348 (a) = ROLc((a), (s)) + (e);\
349 (c) = ROLc((c), 10);
350
351 #define JJJ(a, b, c, d, e, x, s)        \
352 (a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\
353 (a) = ROLc((a), (s)) + (e);\
354 (c) = ROLc((c), 10);
355
356 static int32_t rmd160_vcompress(struct rmd160_vstate *md,uint8_t *buf)
357 {
358     uint32_t aa,bb,cc,dd,ee,aaa,bbb,ccc,ddd,eee,X[16];
359     int i;
360
361     /* load words X */
362     for (i = 0; i < 16; i++){
363         LOAD32L(X[i], buf + (4 * i));
364     }
365
366     /* load state */
367     aa = aaa = md->state[0];
368     bb = bbb = md->state[1];
369     cc = ccc = md->state[2];
370     dd = ddd = md->state[3];
371     ee = eee = md->state[4];
372
373     /* round 1 */
374     FF(aa, bb, cc, dd, ee, X[ 0], 11);
375     FF(ee, aa, bb, cc, dd, X[ 1], 14);
376     FF(dd, ee, aa, bb, cc, X[ 2], 15);
377     FF(cc, dd, ee, aa, bb, X[ 3], 12);
378     FF(bb, cc, dd, ee, aa, X[ 4],  5);
379     FF(aa, bb, cc, dd, ee, X[ 5],  8);
380     FF(ee, aa, bb, cc, dd, X[ 6],  7);
381     FF(dd, ee, aa, bb, cc, X[ 7],  9);
382     FF(cc, dd, ee, aa, bb, X[ 8], 11);
383     FF(bb, cc, dd, ee, aa, X[ 9], 13);
384     FF(aa, bb, cc, dd, ee, X[10], 14);
385     FF(ee, aa, bb, cc, dd, X[11], 15);
386     FF(dd, ee, aa, bb, cc, X[12],  6);
387     FF(cc, dd, ee, aa, bb, X[13],  7);
388     FF(bb, cc, dd, ee, aa, X[14],  9);
389     FF(aa, bb, cc, dd, ee, X[15],  8);
390
391     /* round 2 */
392     GG(ee, aa, bb, cc, dd, X[ 7],  7);
393     GG(dd, ee, aa, bb, cc, X[ 4],  6);
394     GG(cc, dd, ee, aa, bb, X[13],  8);
395     GG(bb, cc, dd, ee, aa, X[ 1], 13);
396     GG(aa, bb, cc, dd, ee, X[10], 11);
397     GG(ee, aa, bb, cc, dd, X[ 6],  9);
398     GG(dd, ee, aa, bb, cc, X[15],  7);
399     GG(cc, dd, ee, aa, bb, X[ 3], 15);
400     GG(bb, cc, dd, ee, aa, X[12],  7);
401     GG(aa, bb, cc, dd, ee, X[ 0], 12);
402     GG(ee, aa, bb, cc, dd, X[ 9], 15);
403     GG(dd, ee, aa, bb, cc, X[ 5],  9);
404     GG(cc, dd, ee, aa, bb, X[ 2], 11);
405     GG(bb, cc, dd, ee, aa, X[14],  7);
406     GG(aa, bb, cc, dd, ee, X[11], 13);
407     GG(ee, aa, bb, cc, dd, X[ 8], 12);
408
409     /* round 3 */
410     HH(dd, ee, aa, bb, cc, X[ 3], 11);
411     HH(cc, dd, ee, aa, bb, X[10], 13);
412     HH(bb, cc, dd, ee, aa, X[14],  6);
413     HH(aa, bb, cc, dd, ee, X[ 4],  7);
414     HH(ee, aa, bb, cc, dd, X[ 9], 14);
415     HH(dd, ee, aa, bb, cc, X[15],  9);
416     HH(cc, dd, ee, aa, bb, X[ 8], 13);
417     HH(bb, cc, dd, ee, aa, X[ 1], 15);
418     HH(aa, bb, cc, dd, ee, X[ 2], 14);
419     HH(ee, aa, bb, cc, dd, X[ 7],  8);
420     HH(dd, ee, aa, bb, cc, X[ 0], 13);
421     HH(cc, dd, ee, aa, bb, X[ 6],  6);
422     HH(bb, cc, dd, ee, aa, X[13],  5);
423     HH(aa, bb, cc, dd, ee, X[11], 12);
424     HH(ee, aa, bb, cc, dd, X[ 5],  7);
425     HH(dd, ee, aa, bb, cc, X[12],  5);
426
427     /* round 4 */
428     II(cc, dd, ee, aa, bb, X[ 1], 11);
429     II(bb, cc, dd, ee, aa, X[ 9], 12);
430     II(aa, bb, cc, dd, ee, X[11], 14);
431     II(ee, aa, bb, cc, dd, X[10], 15);
432     II(dd, ee, aa, bb, cc, X[ 0], 14);
433     II(cc, dd, ee, aa, bb, X[ 8], 15);
434     II(bb, cc, dd, ee, aa, X[12],  9);
435     II(aa, bb, cc, dd, ee, X[ 4],  8);
436     II(ee, aa, bb, cc, dd, X[13],  9);
437     II(dd, ee, aa, bb, cc, X[ 3], 14);
438     II(cc, dd, ee, aa, bb, X[ 7],  5);
439     II(bb, cc, dd, ee, aa, X[15],  6);
440     II(aa, bb, cc, dd, ee, X[14],  8);
441     II(ee, aa, bb, cc, dd, X[ 5],  6);
442     II(dd, ee, aa, bb, cc, X[ 6],  5);
443     II(cc, dd, ee, aa, bb, X[ 2], 12);
444
445     /* round 5 */
446     JJ(bb, cc, dd, ee, aa, X[ 4],  9);
447     JJ(aa, bb, cc, dd, ee, X[ 0], 15);
448     JJ(ee, aa, bb, cc, dd, X[ 5],  5);
449     JJ(dd, ee, aa, bb, cc, X[ 9], 11);
450     JJ(cc, dd, ee, aa, bb, X[ 7],  6);
451     JJ(bb, cc, dd, ee, aa, X[12],  8);
452     JJ(aa, bb, cc, dd, ee, X[ 2], 13);
453     JJ(ee, aa, bb, cc, dd, X[10], 12);
454     JJ(dd, ee, aa, bb, cc, X[14],  5);
455     JJ(cc, dd, ee, aa, bb, X[ 1], 12);
456     JJ(bb, cc, dd, ee, aa, X[ 3], 13);
457     JJ(aa, bb, cc, dd, ee, X[ 8], 14);
458     JJ(ee, aa, bb, cc, dd, X[11], 11);
459     JJ(dd, ee, aa, bb, cc, X[ 6],  8);
460     JJ(cc, dd, ee, aa, bb, X[15],  5);
461     JJ(bb, cc, dd, ee, aa, X[13],  6);
462
463     /* parallel round 1 */
464     JJJ(aaa, bbb, ccc, ddd, eee, X[ 5],  8);
465     JJJ(eee, aaa, bbb, ccc, ddd, X[14],  9);
466     JJJ(ddd, eee, aaa, bbb, ccc, X[ 7],  9);
467     JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11);
468     JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13);
469     JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15);
470     JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15);
471     JJJ(ddd, eee, aaa, bbb, ccc, X[ 4],  5);
472     JJJ(ccc, ddd, eee, aaa, bbb, X[13],  7);
473     JJJ(bbb, ccc, ddd, eee, aaa, X[ 6],  7);
474     JJJ(aaa, bbb, ccc, ddd, eee, X[15],  8);
475     JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11);
476     JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14);
477     JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14);
478     JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12);
479     JJJ(aaa, bbb, ccc, ddd, eee, X[12],  6);
480
481     /* parallel round 2 */
482     III(eee, aaa, bbb, ccc, ddd, X[ 6],  9);
483     III(ddd, eee, aaa, bbb, ccc, X[11], 13);
484     III(ccc, ddd, eee, aaa, bbb, X[ 3], 15);
485     III(bbb, ccc, ddd, eee, aaa, X[ 7],  7);
486     III(aaa, bbb, ccc, ddd, eee, X[ 0], 12);
487     III(eee, aaa, bbb, ccc, ddd, X[13],  8);
488     III(ddd, eee, aaa, bbb, ccc, X[ 5],  9);
489     III(ccc, ddd, eee, aaa, bbb, X[10], 11);
490     III(bbb, ccc, ddd, eee, aaa, X[14],  7);
491     III(aaa, bbb, ccc, ddd, eee, X[15],  7);
492     III(eee, aaa, bbb, ccc, ddd, X[ 8], 12);
493     III(ddd, eee, aaa, bbb, ccc, X[12],  7);
494     III(ccc, ddd, eee, aaa, bbb, X[ 4],  6);
495     III(bbb, ccc, ddd, eee, aaa, X[ 9], 15);
496     III(aaa, bbb, ccc, ddd, eee, X[ 1], 13);
497     III(eee, aaa, bbb, ccc, ddd, X[ 2], 11);
498
499     /* parallel round 3 */
500     HHH(ddd, eee, aaa, bbb, ccc, X[15],  9);
501     HHH(ccc, ddd, eee, aaa, bbb, X[ 5],  7);
502     HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15);
503     HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11);
504     HHH(eee, aaa, bbb, ccc, ddd, X[ 7],  8);
505     HHH(ddd, eee, aaa, bbb, ccc, X[14],  6);
506     HHH(ccc, ddd, eee, aaa, bbb, X[ 6],  6);
507     HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14);
508     HHH(aaa, bbb, ccc, ddd, eee, X[11], 12);
509     HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13);
510     HHH(ddd, eee, aaa, bbb, ccc, X[12],  5);
511     HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14);
512     HHH(bbb, ccc, ddd, eee, aaa, X[10], 13);
513     HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13);
514     HHH(eee, aaa, bbb, ccc, ddd, X[ 4],  7);
515     HHH(ddd, eee, aaa, bbb, ccc, X[13],  5);
516
517     /* parallel round 4 */
518     GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15);
519     GGG(bbb, ccc, ddd, eee, aaa, X[ 6],  5);
520     GGG(aaa, bbb, ccc, ddd, eee, X[ 4],  8);
521     GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11);
522     GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14);
523     GGG(ccc, ddd, eee, aaa, bbb, X[11], 14);
524     GGG(bbb, ccc, ddd, eee, aaa, X[15],  6);
525     GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14);
526     GGG(eee, aaa, bbb, ccc, ddd, X[ 5],  6);
527     GGG(ddd, eee, aaa, bbb, ccc, X[12],  9);
528     GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12);
529     GGG(bbb, ccc, ddd, eee, aaa, X[13],  9);
530     GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12);
531     GGG(eee, aaa, bbb, ccc, ddd, X[ 7],  5);
532     GGG(ddd, eee, aaa, bbb, ccc, X[10], 15);
533     GGG(ccc, ddd, eee, aaa, bbb, X[14],  8);
534
535     /* parallel round 5 */
536     FFF(bbb, ccc, ddd, eee, aaa, X[12] ,  8);
537     FFF(aaa, bbb, ccc, ddd, eee, X[15] ,  5);
538     FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12);
539     FFF(ddd, eee, aaa, bbb, ccc, X[ 4] ,  9);
540     FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12);
541     FFF(bbb, ccc, ddd, eee, aaa, X[ 5] ,  5);
542     FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14);
543     FFF(eee, aaa, bbb, ccc, ddd, X[ 7] ,  6);
544     FFF(ddd, eee, aaa, bbb, ccc, X[ 6] ,  8);
545     FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13);
546     FFF(bbb, ccc, ddd, eee, aaa, X[13] ,  6);
547     FFF(aaa, bbb, ccc, ddd, eee, X[14] ,  5);
548     FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15);
549     FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13);
550     FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11);
551     FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11);
552
553     /* combine results */
554     ddd += cc + md->state[1];               /* final result for md->state[0] */
555     md->state[1] = md->state[2] + dd + eee;
556     md->state[2] = md->state[3] + ee + aaa;
557     md->state[3] = md->state[4] + aa + bbb;
558     md->state[4] = md->state[0] + bb + ccc;
559     md->state[0] = ddd;
560
561     return 0;
562 }
563
564 /**
565  Initialize the hash state
566  @param md   The hash state you wish to initialize
567  @return 0 if successful
568  */
569 int rmd160_vinit(struct rmd160_vstate * md)
570 {
571     md->state[0] = 0x67452301UL;
572     md->state[1] = 0xefcdab89UL;
573     md->state[2] = 0x98badcfeUL;
574     md->state[3] = 0x10325476UL;
575     md->state[4] = 0xc3d2e1f0UL;
576     md->curlen   = 0;
577     md->length   = 0;
578     return 0;
579 }
580 #define HASH_PROCESS(func_name, compress_name, state_var, block_size)                       \
581 int func_name (struct rmd160_vstate * md, const unsigned char *in, unsigned long inlen)               \
582 {                                                                                           \
583 unsigned long n;                                                                        \
584 int           err;                                                                      \
585 if (md->curlen > sizeof(md->buf)) {                             \
586 return -1;                                                            \
587 }                                                                                       \
588 while (inlen > 0) {                                                                     \
589 if (md->curlen == 0 && inlen >= block_size) {                           \
590 if ((err = compress_name (md, (unsigned char *)in)) != 0) {               \
591 return err;                                                                   \
592 }                                                                                \
593 md->length += block_size * 8;                                        \
594 in             += block_size;                                                    \
595 inlen          -= block_size;                                                    \
596 } else {                                                                            \
597 n = MIN(inlen, (block_size - md->curlen));                           \
598 memcpy(md->buf + md->curlen, in, (size_t)n);              \
599 md->curlen += n;                                                     \
600 in             += n;                                                             \
601 inlen          -= n;                                                             \
602 if (md->curlen == block_size) {                                      \
603 if ((err = compress_name (md, md->buf)) != 0) {            \
604 return err;                                                                \
605 }                                                                             \
606 md->length += 8*block_size;                                       \
607 md->curlen = 0;                                                   \
608 }                                                                                \
609 }                                                                                    \
610 }                                                                                       \
611 return 0;                                                                        \
612 }
613
614 /**
615  Process a block of memory though the hash
616  @param md     The hash state
617  @param in     The data to hash
618  @param inlen  The length of the data (octets)
619  @return 0 if successful
620  */
621 HASH_PROCESS(rmd160_vprocess, rmd160_vcompress, rmd160, 64)
622
623 /**
624  Terminate the hash to get the digest
625  @param md  The hash state
626  @param out [out] The destination of the hash (20 bytes)
627  @return 0 if successful
628  */
629 int rmd160_vdone(struct rmd160_vstate * md, unsigned char *out)
630 {
631     int i;
632     if (md->curlen >= sizeof(md->buf)) {
633         return -1;
634     }
635     /* increase the length of the message */
636     md->length += md->curlen * 8;
637
638     /* append the '1' bit */
639     md->buf[md->curlen++] = (unsigned char)0x80;
640
641     /* if the length is currently above 56 bytes we append zeros
642      * then compress.  Then we can fall back to padding zeros and length
643      * encoding like normal.
644      */
645     if (md->curlen > 56) {
646         while (md->curlen < 64) {
647             md->buf[md->curlen++] = (unsigned char)0;
648         }
649         rmd160_vcompress(md, md->buf);
650         md->curlen = 0;
651     }
652     /* pad upto 56 bytes of zeroes */
653     while (md->curlen < 56) {
654         md->buf[md->curlen++] = (unsigned char)0;
655     }
656     /* store length */
657     STORE64L(md->length, md->buf+56);
658     rmd160_vcompress(md, md->buf);
659     /* copy output */
660     for (i = 0; i < 5; i++) {
661         STORE32L(md->state[i], out+(4*i));
662     }
663     return 0;
664 }
665
666 void calc_rmd160(char deprecated[41],uint8_t buf[20],uint8_t *msg,int32_t len)
667 {
668     struct rmd160_vstate md;
669     rmd160_vinit(&md);
670     rmd160_vprocess(&md,msg,len);
671     rmd160_vdone(&md, buf);
672 }
673 #undef F
674 #undef G
675 #undef H
676 #undef I
677 #undef J
678 #undef ROLc
679 #undef FF
680 #undef GG
681 #undef HH
682 #undef II
683 #undef JJ
684 #undef FFF
685 #undef GGG
686 #undef HHH
687 #undef III
688 #undef JJJ
689
690 static const uint32_t crc32_tab[] = {
691         0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
692         0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
693         0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
694         0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
695         0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
696         0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
697         0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
698         0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
699         0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
700         0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
701         0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
702         0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
703         0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
704         0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
705         0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
706         0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
707         0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
708         0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
709         0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
710         0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
711         0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
712         0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
713         0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
714         0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
715         0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
716         0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
717         0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
718         0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
719         0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
720         0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
721         0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
722         0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
723         0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
724         0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
725         0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
726         0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
727         0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
728         0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
729         0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
730         0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
731         0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
732         0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
733         0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
734 };
735
736 uint32_t calc_crc32(uint32_t crc,const void *buf,size_t size)
737 {
738         const uint8_t *p;
739
740         p = (const uint8_t *)buf;
741         crc = crc ^ ~0U;
742
743         while (size--)
744                 crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
745
746         return crc ^ ~0U;
747 }
748
749 void calc_rmd160_sha256(uint8_t rmd160[20],uint8_t *data,int32_t datalen)
750 {
751     bits256 hash;
752     vcalc_sha256(0,hash.bytes,data,datalen);
753     calc_rmd160(0,rmd160,hash.bytes,sizeof(hash));
754 }
755
756 int32_t bitcoin_addr2rmd160(uint8_t *addrtypep,uint8_t rmd160[20],char *coinaddr)
757 {
758     bits256 hash; uint8_t *buf,_buf[25]; int32_t len;
759     memset(rmd160,0,20);
760     *addrtypep = 0;
761     buf = _buf;
762     if ( (len= bitcoin_base58decode(buf,coinaddr)) >= 4 )
763     {
764         // validate with trailing hash, then remove hash
765         hash = bits256_doublesha256(0,buf,21);
766         *addrtypep = *buf;
767         memcpy(rmd160,buf+1,20);
768         if ( (buf[21]&0xff) == hash.bytes[31] && (buf[22]&0xff) == hash.bytes[30] &&(buf[23]&0xff) == hash.bytes[29] && (buf[24]&0xff) == hash.bytes[28] )
769         {
770             //printf("coinaddr.(%s) valid checksum addrtype.%02x\n",coinaddr,*addrtypep);
771             return(20);
772         }
773         else
774         {
775             int32_t i;
776             if ( len > 20 )
777             {
778                 hash = bits256_doublesha256(0,buf,len);
779             }
780             for (i=0; i<len; i++)
781                 printf("%02x ",buf[i]);
782             printf("\nhex checkhash.(%s) len.%d mismatch %02x %02x %02x %02x vs %02x %02x %02x %02x\n",coinaddr,len,buf[len-1]&0xff,buf[len-2]&0xff,buf[len-3]&0xff,buf[len-4]&0xff,hash.bytes[31],hash.bytes[30],hash.bytes[29],hash.bytes[28]);
783         }
784     }
785         return(0);
786 }
787
788 char *bitcoin_address(char *coinaddr,uint8_t addrtype,uint8_t *pubkey_or_rmd160,int32_t len)
789 {
790     int32_t i; uint8_t data[25]; bits256 hash;// char checkaddr[65];
791     if ( len != 20 )
792         calc_rmd160_sha256(data+1,pubkey_or_rmd160,len);
793     else memcpy(data+1,pubkey_or_rmd160,20);
794     //btc_convrmd160(checkaddr,addrtype,data+1);
795     data[0] = addrtype;
796     hash = bits256_doublesha256(0,data,21);
797     for (i=0; i<4; i++)
798         data[21+i] = hash.bytes[31-i];
799     if ( (coinaddr= bitcoin_base58encode(coinaddr,data,25)) != 0 )
800     {
801         //uint8_t checktype,rmd160[20];
802         //bitcoin_addr2rmd160(&checktype,rmd160,coinaddr);
803         //if ( strcmp(checkaddr,coinaddr) != 0 )
804         //    printf("checkaddr.(%s) vs coinaddr.(%s) %02x vs [%02x] memcmp.%d\n",checkaddr,coinaddr,addrtype,checktype,memcmp(rmd160,data+1,20));
805     }
806     return(coinaddr);
807 }
808
809 int32_t komodo_is_issuer()
810 {
811     if ( ASSETCHAINS_SYMBOL[0] != 0 && komodo_baseid(ASSETCHAINS_SYMBOL) >= 0 )
812         return(1);
813     else return(0);
814 }
815
816 int32_t bitweight(uint64_t x)
817 {
818     int i,wt = 0;
819     for (i=0; i<64; i++)
820         if ( (1LL << i) & x )
821             wt++;
822     return(wt);
823 }
824
825 int32_t _unhex(char c)
826 {
827     if ( c >= '0' && c <= '9' )
828         return(c - '0');
829     else if ( c >= 'a' && c <= 'f' )
830         return(c - 'a' + 10);
831     else if ( c >= 'A' && c <= 'F' )
832         return(c - 'A' + 10);
833     return(-1);
834 }
835
836 int32_t is_hexstr(char *str,int32_t n)
837 {
838     int32_t i;
839     if ( str == 0 || str[0] == 0 )
840         return(0);
841     for (i=0; str[i]!=0; i++)
842     {
843         if ( n > 0 && i >= n )
844             break;
845         if ( _unhex(str[i]) < 0 )
846             break;
847     }
848     if ( n == 0 )
849         return(i);
850     return(i == n);
851 }
852
853 int32_t unhex(char c)
854 {
855     int32_t hex;
856     if ( (hex= _unhex(c)) < 0 )
857     {
858         //printf("unhex: illegal hexchar.(%c)\n",c);
859     }
860     return(hex);
861 }
862
863 unsigned char _decode_hex(char *hex) { return((unhex(hex[0])<<4) | unhex(hex[1])); }
864
865 int32_t decode_hex(uint8_t *bytes,int32_t n,char *hex)
866 {
867     int32_t adjust,i = 0;
868     //printf("decode.(%s)\n",hex);
869     if ( is_hexstr(hex,n) <= 0 )
870     {
871         memset(bytes,0,n);
872         return(n);
873     }
874     if ( hex[n-1] == '\n' || hex[n-1] == '\r' )
875         hex[--n] = 0;
876     if ( n == 0 || (hex[n*2+1] == 0 && hex[n*2] != 0) )
877     {
878         if ( n > 0 )
879         {
880             bytes[0] = unhex(hex[0]);
881             printf("decode_hex n.%d hex[0] (%c) -> %d hex.(%s) [n*2+1: %d] [n*2: %d %c] len.%ld\n",n,hex[0],bytes[0],hex,hex[n*2+1],hex[n*2],hex[n*2],(long)strlen(hex));
882         }
883         bytes++;
884         hex++;
885         adjust = 1;
886     } else adjust = 0;
887     if ( n > 0 )
888     {
889         for (i=0; i<n; i++)
890             bytes[i] = _decode_hex(&hex[i*2]);
891     }
892     //bytes[i] = 0;
893     return(n + adjust);
894 }
895
896 char hexbyte(int32_t c)
897 {
898     c &= 0xf;
899     if ( c < 10 )
900         return('0'+c);
901     else if ( c < 16 )
902         return('a'+c-10);
903     else return(0);
904 }
905
906 int32_t init_hexbytes_noT(char *hexbytes,unsigned char *message,long len)
907 {
908     int32_t i;
909     if ( len <= 0 )
910     {
911         hexbytes[0] = 0;
912         return(1);
913     }
914     for (i=0; i<len; i++)
915     {
916         hexbytes[i*2] = hexbyte((message[i]>>4) & 0xf);
917         hexbytes[i*2 + 1] = hexbyte(message[i] & 0xf);
918         //printf("i.%d (%02x) [%c%c]\n",i,message[i],hexbytes[i*2],hexbytes[i*2+1]);
919     }
920     hexbytes[len*2] = 0;
921     //printf("len.%ld\n",len*2+1);
922     return((int32_t)len*2+1);
923 }
924
925 char *bits256_str(char hexstr[65],bits256 x)
926 {
927     init_hexbytes_noT(hexstr,x.bytes,sizeof(x));
928     return(hexstr);
929 }
930
931 int32_t iguana_rwnum(int32_t rwflag,uint8_t *serialized,int32_t len,void *endianedp)
932 {
933     int32_t i; uint64_t x;
934     if ( rwflag == 0 )
935     {
936         x = 0;
937         for (i=len-1; i>=0; i--)
938         {
939             x <<= 8;
940             x |= serialized[i];
941         }
942         switch ( len )
943         {
944             case 1: *(uint8_t *)endianedp = (uint8_t)x; break;
945             case 2: *(uint16_t *)endianedp = (uint16_t)x; break;
946             case 4: *(uint32_t *)endianedp = (uint32_t)x; break;
947             case 8: *(uint64_t *)endianedp = (uint64_t)x; break;
948         }
949     }
950     else
951     {
952         x = 0;
953         switch ( len )
954         {
955             case 1: x = *(uint8_t *)endianedp; break;
956             case 2: x = *(uint16_t *)endianedp; break;
957             case 4: x = *(uint32_t *)endianedp; break;
958             case 8: x = *(uint64_t *)endianedp; break;
959         }
960         for (i=0; i<len; i++,x >>= 8)
961             serialized[i] = (uint8_t)(x & 0xff);
962     }
963     return(len);
964 }
965
966 int32_t iguana_rwbignum(int32_t rwflag,uint8_t *serialized,int32_t len,uint8_t *endianedp)
967 {
968     int32_t i;
969     if ( rwflag == 0 )
970     {
971         for (i=0; i<len; i++)
972             endianedp[i] = serialized[i];
973     }
974     else
975     {
976         for (i=0; i<len; i++)
977             serialized[i] = endianedp[i];
978     }
979     return(len);
980 }
981
982 int32_t komodo_scriptitemlen(int32_t *opretlenp,uint8_t *script)
983 {
984     int32_t opretlen,len = 0;
985     if ( (opretlen= script[len++]) >= 0x4c )
986     {
987         if ( opretlen == 0x4c )
988             opretlen = script[len++];
989         else if ( opretlen == 0x4d )
990         {
991             opretlen = script[len] + (script[len+1] << 8);
992             len += 2;
993             //opretlen = script[len++];
994             //opretlen = (opretlen << 8) | script[len++];
995         }
996     }
997     *opretlenp = opretlen;
998     return(len);
999 }
1000
1001 int32_t komodo_opreturnscript(uint8_t *script,uint8_t type,uint8_t *opret,int32_t opretlen)
1002 {
1003     int32_t offset = 0;
1004     script[offset++] = 0x6a;
1005     opretlen++;
1006     if ( opretlen >= 0x4c )
1007     {
1008         if ( opretlen > 0xff )
1009         {
1010             script[offset++] = 0x4d;
1011             script[offset++] = opretlen & 0xff;
1012             script[offset++] = (opretlen >> 8) & 0xff;
1013         }
1014         else
1015         {
1016             script[offset++] = 0x4c;
1017             script[offset++] = opretlen;
1018         }
1019     } else script[offset++] = opretlen;
1020     script[offset++] = type; // covered by opretlen
1021     memcpy(&script[offset],opret,opretlen-1);
1022     return(offset + opretlen - 1);
1023 }
1024
1025 // get a pseudo random number that is the same for each block individually at all times and different
1026 // from all other blocks. the sequence is extremely likely, but not guaranteed to be unique for each block chain
1027 uint64_t komodo_block_prg(uint32_t nHeight)
1028 {
1029     if (strcmp(ASSETCHAINS_SYMBOL, "VRSC") != 0 || nHeight >= 12800)
1030     {
1031         uint64_t i, result = 0, hashSrc64 = ((uint64_t)ASSETCHAINS_MAGIC << 32) | (uint64_t)nHeight;
1032         uint8_t hashSrc[8];
1033         bits256 hashResult;
1034
1035         for ( i = 0; i < sizeof(hashSrc); i++ )
1036         {
1037             uint64_t x = hashSrc64 >> (i * 8);
1038             hashSrc[i] = (uint8_t)(x & 0xff);
1039         }
1040         verus_hash(hashResult.bytes, hashSrc, sizeof(hashSrc));
1041         for ( i = 0; i < 8; i++ )
1042         {
1043             result = (result << 8) | hashResult.bytes[i];
1044         }
1045         return result;
1046     }
1047     else
1048     {
1049         int i;
1050         uint8_t hashSrc[8];
1051         uint64_t result, hashSrc64 = (uint64_t)ASSETCHAINS_MAGIC << 32 + nHeight;
1052         bits256 hashResult;
1053
1054         for ( i = 0; i < sizeof(hashSrc); i++ )
1055         {
1056             hashSrc[i] = hashSrc64 & 0xff;
1057             hashSrc64 >>= 8;
1058             int8_t b = hashSrc[i];
1059         }
1060
1061         vcalc_sha256(0, hashResult.bytes, hashSrc, sizeof(hashSrc));
1062         for ( i = 0; i < 8; i++ )
1063         {
1064             result = (result << 8) + hashResult.bytes[i];
1065         }
1066         return result;
1067     }
1068 }
1069
1070 // given a block height, this returns the unlock time for that block height, derived from
1071 // the ASSETCHAINS_MAGIC number as well as the block height, providing different random numbers
1072 // for corresponding blocks across chains, but the same sequence in each chain 
1073 int64_t komodo_block_unlocktime(uint32_t nHeight)
1074 {
1075     uint64_t fromTime, toTime, unlocktime;
1076
1077     if ( ASSETCHAINS_TIMEUNLOCKFROM == ASSETCHAINS_TIMEUNLOCKTO )
1078         unlocktime = ASSETCHAINS_TIMEUNLOCKTO;
1079     else
1080     {
1081         if (strcmp(ASSETCHAINS_SYMBOL, "VRSC") != 0 || nHeight >= 12800)
1082         {
1083             unlocktime = komodo_block_prg(nHeight) % (ASSETCHAINS_TIMEUNLOCKTO - ASSETCHAINS_TIMEUNLOCKFROM);
1084             unlocktime += ASSETCHAINS_TIMEUNLOCKFROM;
1085         }
1086         else
1087         {
1088             unlocktime = komodo_block_prg(nHeight) / (0xffffffffffffffff / ((ASSETCHAINS_TIMEUNLOCKTO - ASSETCHAINS_TIMEUNLOCKFROM) + 1));
1089             // boundary and power of 2 can make it exceed to time by 1
1090             unlocktime = unlocktime + ASSETCHAINS_TIMEUNLOCKFROM;
1091             if (unlocktime > ASSETCHAINS_TIMEUNLOCKTO)
1092                 unlocktime--;
1093         }
1094     }
1095     return ((int64_t)unlocktime);
1096 }
1097
1098 long _stripwhite(char *buf,int accept)
1099 {
1100     int32_t i,j,c;
1101     if ( buf == 0 || buf[0] == 0 )
1102         return(0);
1103     for (i=j=0; buf[i]!=0; i++)
1104     {
1105         buf[j] = c = buf[i];
1106         if ( c == accept || (c != ' ' && c != '\n' && c != '\r' && c != '\t' && c != '\b') )
1107             j++;
1108     }
1109     buf[j] = 0;
1110     return(j);
1111 }
1112
1113 char *clonestr(char *str)
1114 {
1115     char *clone;
1116     if ( str == 0 || str[0] == 0 )
1117     {
1118         printf("warning cloning nullstr.%p\n",str);
1119 #ifdef __APPLE__
1120         while ( 1 ) sleep(1);
1121 #endif
1122         str = (char *)"<nullstr>";
1123     }
1124     clone = (char *)malloc(strlen(str)+16);
1125     strcpy(clone,str);
1126     return(clone);
1127 }
1128
1129 int32_t safecopy(char *dest,char *src,long len)
1130 {
1131     int32_t i = -1;
1132     if ( src != 0 && dest != 0 && src != dest )
1133     {
1134         if ( dest != 0 )
1135             memset(dest,0,len);
1136         for (i=0; i<len&&src[i]!=0; i++)
1137             dest[i] = src[i];
1138         if ( i == len )
1139         {
1140             printf("safecopy: %s too long %ld\n",src,len);
1141 #ifdef __APPLE__
1142             //getchar();
1143 #endif
1144             return(-1);
1145         }
1146         dest[i] = 0;
1147     }
1148     return(i);
1149 }
1150
1151 char *parse_conf_line(char *line,char *field)
1152 {
1153     line += strlen(field);
1154     for (; *line!='='&&*line!=0; line++)
1155         break;
1156     if ( *line == 0 )
1157         return(0);
1158     if ( *line == '=' )
1159         line++;
1160     while ( line[strlen(line)-1] == '\r' || line[strlen(line)-1] == '\n' || line[strlen(line)-1] == ' ' )
1161         line[strlen(line)-1] = 0;
1162     //printf("LINE.(%s)\n",line);
1163     _stripwhite(line,0);
1164     return(clonestr(line));
1165 }
1166
1167 double OS_milliseconds()
1168 {
1169     struct timeval tv; double millis;
1170     gettimeofday(&tv,NULL);
1171     millis = ((double)tv.tv_sec * 1000. + (double)tv.tv_usec / 1000.);
1172     //printf("tv_sec.%ld usec.%d %f\n",tv.tv_sec,tv.tv_usec,millis);
1173     return(millis);
1174 }
1175
1176 #ifndef _WIN32
1177 void OS_randombytes(unsigned char *x,long xlen)
1178 {
1179     static int fd = -1;
1180     int32_t i;
1181     if (fd == -1) {
1182         for (;;) {
1183             fd = open("/dev/urandom",O_RDONLY);
1184             if (fd != -1) break;
1185             sleep(1);
1186         }
1187     }
1188     while (xlen > 0) {
1189         if (xlen < 1048576) i = (int32_t)xlen; else i = 1048576;
1190         i = (int32_t)read(fd,x,i);
1191         if (i < 1) {
1192             sleep(1);
1193             continue;
1194         }
1195         if ( 0 )
1196         {
1197             int32_t j;
1198             for (j=0; j<i; j++)
1199                 printf("%02x ",x[j]);
1200             printf("-> %p\n",x);
1201         }
1202         x += i;
1203         xlen -= i;
1204     }
1205 }
1206 #endif
1207
1208 void lock_queue(queue_t *queue)
1209 {
1210     if ( queue->initflag == 0 )
1211     {
1212         portable_mutex_init(&queue->mutex);
1213         queue->initflag = 1;
1214     }
1215         portable_mutex_lock(&queue->mutex);
1216 }
1217
1218 void queue_enqueue(char *name,queue_t *queue,struct queueitem *item)
1219 {
1220     if ( queue->name[0] == 0 && name != 0 && name[0] != 0 )
1221         strcpy(queue->name,name);
1222     if ( item == 0 )
1223     {
1224         printf("FATAL type error: queueing empty value\n");
1225         return;
1226     }
1227     lock_queue(queue);
1228     DL_APPEND(queue->list,item);
1229     portable_mutex_unlock(&queue->mutex);
1230 }
1231
1232 struct queueitem *queue_dequeue(queue_t *queue)
1233 {
1234     struct queueitem *item = 0;
1235     lock_queue(queue);
1236     if ( queue->list != 0 )
1237     {
1238         item = queue->list;
1239         DL_DELETE(queue->list,item);
1240     }
1241         portable_mutex_unlock(&queue->mutex);
1242     return(item);
1243 }
1244
1245 void *queue_delete(queue_t *queue,struct queueitem *copy,int32_t copysize)
1246 {
1247     struct queueitem *item = 0;
1248     lock_queue(queue);
1249     if ( queue->list != 0 )
1250     {
1251         DL_FOREACH(queue->list,item)
1252         {
1253                                                 #ifdef _WIN32
1254                                                 if ( item == copy || (item->allocsize == copysize && memcmp((void *)((intptr_t)item + sizeof(struct queueitem)),(void *)((intptr_t)copy + sizeof(struct queueitem)),copysize) == 0) )
1255                                                 #else
1256             if ( item == copy || (item->allocsize == copysize && memcmp((void *)((long)item + sizeof(struct queueitem)),(void *)((long)copy + sizeof(struct queueitem)),copysize) == 0) )
1257                                                 #endif
1258             {
1259                 DL_DELETE(queue->list,item);
1260                 portable_mutex_unlock(&queue->mutex);
1261                 printf("name.(%s) deleted item.%p list.%p\n",queue->name,item,queue->list);
1262                 return(item);
1263             }
1264         }
1265     }
1266         portable_mutex_unlock(&queue->mutex);
1267     return(0);
1268 }
1269
1270 void *queue_free(queue_t *queue)
1271 {
1272     struct queueitem *item = 0;
1273     lock_queue(queue);
1274     if ( queue->list != 0 )
1275     {
1276         DL_FOREACH(queue->list,item)
1277         {
1278             DL_DELETE(queue->list,item);
1279             free(item);
1280         }
1281         //printf("name.(%s) dequeue.%p list.%p\n",queue->name,item,queue->list);
1282     }
1283         portable_mutex_unlock(&queue->mutex);
1284     return(0);
1285 }
1286
1287 void *queue_clone(queue_t *clone,queue_t *queue,int32_t size)
1288 {
1289     struct queueitem *ptr,*item = 0;
1290     lock_queue(queue);
1291     if ( queue->list != 0 )
1292     {
1293         DL_FOREACH(queue->list,item)
1294         {
1295             ptr = (struct queueitem *)calloc(1,sizeof(*ptr));
1296             memcpy(ptr,item,size);
1297             queue_enqueue(queue->name,clone,ptr);
1298         }
1299         //printf("name.(%s) dequeue.%p list.%p\n",queue->name,item,queue->list);
1300     }
1301         portable_mutex_unlock(&queue->mutex);
1302     return(0);
1303 }
1304
1305 int32_t queue_size(queue_t *queue)
1306 {
1307     int32_t count = 0;
1308     struct queueitem *tmp;
1309     lock_queue(queue);
1310     DL_COUNT(queue->list,tmp,count);
1311     portable_mutex_unlock(&queue->mutex);
1312         return count;
1313 }
1314
1315 void iguana_initQ(queue_t *Q,char *name)
1316 {
1317     struct queueitem *item,*I;
1318     memset(Q,0,sizeof(*Q));
1319     I = (struct queueitem *)calloc(1,sizeof(*I));
1320     strcpy(Q->name,name);
1321     queue_enqueue(name,Q,I);
1322     if ( (item= queue_dequeue(Q)) != 0 )
1323         free(item);
1324 }
1325
1326 uint16_t _komodo_userpass(char *username,char *password, FILE *fp)
1327 {
1328     char *rpcuser,*rpcpassword,*str,line[8192]; uint16_t port = 0;
1329     rpcuser = rpcpassword = 0;
1330     username[0] = password[0] = 0;
1331     while ( fgets(line,sizeof(line),fp) != 0 )
1332     {
1333         if ( line[0] == '#' )
1334             continue;
1335         //printf("line.(%s) %p %p\n",line,strstr(line,(char *)"rpcuser"),strstr(line,(char *)"rpcpassword"));
1336         if ( (str= strstr(line,(char *)"rpcuser")) != 0 )
1337             rpcuser = parse_conf_line(str,(char *)"rpcuser");
1338         else if ( (str= strstr(line,(char *)"rpcpassword")) != 0 )
1339             rpcpassword = parse_conf_line(str,(char *)"rpcpassword");
1340         else if ( (str= strstr(line,(char *)"rpcport")) != 0 )
1341         {
1342             port = atoi(parse_conf_line(str,(char *)"rpcport"));
1343             //fprintf(stderr,"rpcport.%u in file\n",port);
1344         }
1345     }
1346     if ( rpcuser != 0 && rpcpassword != 0 )
1347     {
1348         strcpy(username,rpcuser);
1349         strcpy(password,rpcpassword);
1350     }
1351     //printf("rpcuser.(%s) rpcpassword.(%s) KMDUSERPASS.(%s) %u\n",rpcuser,rpcpassword,KMDUSERPASS,port);
1352     if ( rpcuser != 0 )
1353         free(rpcuser);
1354     if ( rpcpassword != 0 )
1355         free(rpcpassword);
1356     return(port);
1357 }
1358
1359 void komodo_statefname(char *fname,char *symbol,char *str)
1360 {
1361     int32_t n,len;
1362     std::string checkName = std::string(symbol);
1363     if (checkName != "VRSC")
1364     {
1365         checkName = boost::to_lower_copy(std::string(ASSETCHAINS_SYMBOL));
1366     }
1367
1368     const char *chkName = checkName.c_str();
1369     sprintf(fname, "%s", GetDataDir(false).string().c_str());
1370     if ( (n = (int32_t)strlen(chkName)) != 0 )
1371     {
1372         len = (int32_t)strlen(fname);
1373         if ( strcmp(chkName, &fname[len - n]) == 0 )
1374             fname[len - n] = 0;
1375         else
1376         {
1377             printf("unexpected fname.(%s) vs %s [%s] n.%d len.%d (%s)\n",fname,symbol,ASSETCHAINS_SYMBOL,n,len,&fname[len - n]);
1378             return;
1379         }
1380     }
1381     else
1382     {
1383 #ifdef _WIN32
1384         strcat(fname,"\\");
1385 #else
1386         strcat(fname,"/");
1387 #endif
1388     }
1389     if ( symbol != 0 && symbol[0] != 0 && strcmp("KMD",symbol) != 0 )
1390     {
1391         strcat(fname, symbol);
1392         //printf("statefname.(%s) -> (%s)\n",symbol,fname);
1393 #ifdef _WIN32
1394         strcat(fname,"\\");
1395 #else
1396         strcat(fname,"/");
1397 #endif
1398     }
1399     strcat(fname,str);
1400     //printf("test.(%s) -> [%s] statename.(%s) %s\n",test,ASSETCHAINS_SYMBOL,symbol,fname);
1401 }
1402
1403 // create a config file. if this is a PBaaS chain, we assume that the loaded CCurrencyDefinition is complete, which may not
1404 // be the case when loading without VRSC active.
1405 void komodo_configfile(char *symbol, uint16_t rpcport)
1406 {
1407     std::string fileName(symbol);
1408     if (fileName != "VRSC")
1409     {
1410         fileName = boost::to_lower_copy(fileName);
1411     }
1412     const char *_symbol = fileName.c_str();
1413     static char myusername[512], mypassword[7168];
1414     FILE *fp; uint16_t kmdport; uint8_t buf2[33]; char fname[512],buf[128],username[512],password[7168]; uint32_t crc,r,r2,i;
1415     if ( !fileName.empty() && rpcport != 0 )
1416     {
1417         r = (uint32_t)time(NULL);
1418         r2 = OS_milliseconds();
1419         memcpy(buf,&r,sizeof(r));
1420         memcpy(&buf[sizeof(r)],&r2,sizeof(r2));
1421         memcpy(&buf[sizeof(r)+sizeof(r2)], _symbol, strlen(_symbol));
1422         crc = calc_crc32(0,(uint8_t *)buf,(int32_t)(sizeof(r)+sizeof(r2)+strlen(_symbol)));
1423                                 #ifdef _WIN32
1424                                 randombytes_buf(buf2,sizeof(buf2));
1425                                 #else
1426         OS_randombytes(buf2,sizeof(buf2));
1427                                 #endif
1428         for (i=0; i<sizeof(buf2); i++)
1429             sprintf(&password[i*2],"%02x",buf2[i]);
1430         password[i*2] = 0;
1431         sprintf(buf,"%s.conf", _symbol);
1432         BITCOIND_RPCPORT = rpcport;
1433 #ifdef _WIN32
1434         sprintf(fname,"%s\\%s",GetDataDir(false).string().c_str(), buf);
1435 #else
1436         sprintf(fname,"%s/%s",GetDataDir(false).string().c_str(), buf);
1437 #endif
1438         if ( (fp= fopen(fname,"rb")) == 0 )
1439         {
1440 #ifndef FROM_CLI
1441             if ( (fp= fopen(fname,"wb")) != 0 )
1442             {
1443                 fprintf(fp,"rpcuser=user%u\nrpcpassword=pass%s\nrpcport=%u\nserver=1\ntxindex=1\nrpcworkqueue=256\nrpcallowip=127.0.0.1\nrpchost=127.0.0.1\n",crc,password,rpcport);
1444
1445                 // add basic chain parameters for non-VRSC chains
1446                 if (_IsVerusActive())
1447                 {
1448                     // add Verus Coin Foundation sponsored testnet nodes
1449                     if (PBAAS_TESTMODE)
1450                     {
1451                         fprintf(fp,"addnode=%s\n", "168.119.27.242:18183");
1452                         fprintf(fp,"addnode=%s\n", "5.9.224.250:18183");
1453                         fprintf(fp,"addnode=%s\n", "95.216.104.210:18183");
1454                         fprintf(fp,"addnode=%s\n", "135.181.68.2:18183");
1455                     }
1456                 }
1457                 else
1458                 {
1459                     const char *charPtr;
1460                     // basic coin parameters. the rest will come from block 1
1461                     fprintf(fp,"ac_algo=verushash\nac_veruspos=50\nac_cc=1\n");
1462                     fprintf(fp,"launchsystemid=%s\n", EncodeDestination(CIdentityID(ConnectedChains.thisChain.launchSystemID)).c_str());
1463                     fprintf(fp,"startblock=%d\n", ConnectedChains.thisChain.startBlock);
1464                     fprintf(fp,"endblock=%d\n", ConnectedChains.thisChain.endBlock);
1465                     fprintf(fp,"ac_supply=%s\n", (charPtr = mapArgs["-ac_supply"].c_str())[0] == 0 ? "0" : charPtr);
1466                     fprintf(fp,"ac_halving=%s\n", (charPtr = mapArgs["-ac_halving"].c_str())[0] == 0 ? "0" : charPtr);
1467                     fprintf(fp,"ac_decay=%s\n", (charPtr = mapArgs["-ac_decay"].c_str())[0] == 0 ? "0" : charPtr);
1468                     fprintf(fp,"ac_reward=%s\n", (charPtr = mapArgs["-ac_reward"].c_str())[0] == 0 ? "0" : charPtr);
1469                     fprintf(fp,"ac_eras=%s\n", (charPtr = mapArgs["-ac_eras"].c_str())[0] == 0 ? "1" : charPtr);
1470                     fprintf(fp,"ac_end=%s\n", (charPtr = mapArgs["-ac_end"].c_str())[0] == 0 ? "0" : charPtr);
1471                     fprintf(fp,"ac_options=%s\n", (charPtr = mapArgs["-ac_options"].c_str())[0] == 0 ? "0" : charPtr);
1472
1473                     if (GetArg("-port", 0))
1474                     {
1475                         fprintf(fp,"port=%s\n", mapArgs["-port"].c_str());
1476                     }
1477
1478                     auto nodeIt = mapMultiArgs.find("-seednode");
1479                     if (nodeIt != mapMultiArgs.end())
1480                     {
1481                         std::vector<std::string> &nodeStrs = mapMultiArgs["-seednode"];
1482                         for (auto nodeStr : nodeStrs)
1483                         {
1484                             fprintf(fp,"seednode=%s\n", nodeStr.c_str());
1485                         }
1486                     }
1487                 }
1488                 fclose(fp);
1489                 printf("Created (%s)\n",fname);
1490             } else printf("Couldnt create (%s)\n",fname);
1491 #endif
1492         }
1493         else
1494         {
1495             _komodo_userpass(myusername, mypassword, fp);
1496             mapArgs["-rpcpassword"] = mypassword;
1497             mapArgs["-rpcusername"] = myusername;
1498             //fprintf(stderr,"myusername.(%s)\n",myusername);
1499             fclose(fp);
1500         }
1501     }
1502     strcpy(fname,GetDataDir().string().c_str());
1503 #ifdef _WIN32
1504     while ( fname[strlen(fname)-1] != '\\' )
1505         fname[strlen(fname)-1] = 0;
1506     strcat(fname,"komodo.conf");
1507 #else
1508     while ( fname[strlen(fname)-1] != '/' )
1509         fname[strlen(fname)-1] = 0;
1510 #ifdef __APPLE__
1511     strcat(fname,"Komodo.conf");
1512 #else
1513     strcat(fname,"komodo.conf");
1514 #endif
1515 #endif
1516     if ( (fp = fopen(fname,"rb")) != 0 )
1517     {
1518         if ( (kmdport= _komodo_userpass(username,password,fp)) != 0 )
1519             KMD_PORT = kmdport;
1520         sprintf(KMDUSERPASS,"%s:%s",username,password);
1521         fclose(fp);
1522 //printf("KOMODO.(%s) -> userpass.(%s)\n",fname,KMDUSERPASS);
1523     } //else printf("couldnt open.(%s)\n",fname);
1524 }
1525
1526 uint16_t komodo_userpass(char *userpass, char *symbol)
1527 {
1528     FILE *fp; uint16_t port = 0; char fname[512],username[512],password[512],confname[KOMODO_ASSETCHAIN_MAXLEN + 5];
1529     userpass[0] = 0;
1530     std::string fileName(symbol);
1531     if (fileName != "VRSC")
1532     {
1533         fileName = boost::to_lower_copy(fileName);
1534     }
1535     sprintf(confname, "%s.conf", fileName.c_str());
1536     komodo_statefname(fname, symbol, confname);
1537     if ( (fp= fopen(fname,"rb")) != 0 )
1538     {
1539         port = _komodo_userpass(username,password,fp);
1540         sprintf(userpass,"%s:%s",username,password);
1541         if ( strcmp(symbol,ASSETCHAINS_SYMBOL) == 0 )
1542             strcpy(ASSETCHAINS_USERPASS,userpass);
1543         fclose(fp);
1544     }
1545     return(port);
1546 }
1547
1548 uint32_t komodo_assetmagic(char *symbol,uint64_t supply,uint8_t *extraptr,int32_t extralen)
1549 {
1550     std::string name(symbol);
1551     if (name != "VRSC")
1552     {
1553         name = boost::to_lower_copy(name);
1554     }
1555     uint8_t buf[512]; uint32_t crc0=0; int32_t len = 0; bits256 hash;
1556
1557     len = iguana_rwnum(1,&buf[len],sizeof(supply),(void *)&supply);
1558     strcpy((char *)&buf[len], name.c_str());
1559     len += strlen(name.c_str());
1560     if ( extraptr != 0 && extralen != 0 )
1561     {
1562         vcalc_sha256(0,hash.bytes,extraptr,extralen);
1563         crc0 = hash.uints[0];
1564     }
1565     return(calc_crc32(crc0,buf,len));
1566 }
1567
1568 uint16_t komodo_assetport(uint32_t magic,int32_t extralen)
1569 {
1570     if (!_IsVerusActive())
1571     {
1572         if (uint16_t retVal = GetArg("-port", 0))
1573         {
1574             return retVal;
1575         }
1576     }
1577     if ( magic == 0x8de4eef9 )
1578         return(7770);
1579     else if ( extralen == 0 )
1580         return(8000 + (magic % 7777));
1581     else return(16000 + (magic % 49500));
1582 }
1583
1584 uint16_t komodo_port(char *symbol,uint64_t supply,uint32_t *magicp,uint8_t *extraptr,int32_t extralen)
1585 {
1586     *magicp = komodo_assetmagic(symbol,supply,extraptr,extralen);
1587     return(komodo_assetport(*magicp,extralen));
1588 }
1589
1590 /*void komodo_ports(uint16_t ports[MAX_CURRENCIES])
1591 {
1592     int32_t i; uint32_t magic;
1593     for (i=0; i<MAX_CURRENCIES; i++)
1594     {
1595         ports[i] = komodo_port(CURRENCIES[i],10,&magic);
1596         printf("%u ",ports[i]);
1597     }
1598     printf("ports\n");
1599 }*/
1600
1601 char *iguanafmtstr = (char *)"curl --url \"http://127.0.0.1:7776\" --data \"{\\\"conf\\\":\\\"%s.conf\\\",\\\"path\\\":\\\"${HOME#\"/\"}/.komodo/%s\\\",\\\"unitval\\\":\\\"20\\\",\\\"zcash\\\":1,\\\"RELAY\\\":-1,\\\"VALIDATE\\\":0,\\\"prefetchlag\\\":-1,\\\"poll\\\":100,\\\"active\\\":1,\\\"agent\\\":\\\"iguana\\\",\\\"method\\\":\\\"addcoin\\\",\\\"startpend\\\":4,\\\"endpend\\\":4,\\\"services\\\":129,\\\"maxpeers\\\":8,\\\"newcoin\\\":\\\"%s\\\",\\\"name\\\":\\\"%s\\\",\\\"hasheaders\\\":1,\\\"useaddmultisig\\\":0,\\\"netmagic\\\":\\\"%s\\\",\\\"p2p\\\":%u,\\\"rpc\\\":%u,\\\"pubval\\\":60,\\\"p2shval\\\":85,\\\"wifval\\\":188,\\\"txfee_satoshis\\\":\\\"10000\\\",\\\"isPoS\\\":0,\\\"minoutput\\\":10000,\\\"minconfirms\\\":2,\\\"genesishash\\\":\\\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\\\",\\\"protover\\\":170002,\\\"genesisblock\\\":\\\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\\\",\\\"debug\\\":0,\\\"seedipaddr\\\":\\\"%s\\\"}\"";
1602
1603
1604 int32_t komodo_whoami(char *pubkeystr,int32_t height,uint32_t timestamp)
1605 {
1606     int32_t i,notaryid;
1607     for (i=0; i<33; i++)
1608         sprintf(&pubkeystr[i<<1],"%02x",NOTARY_PUBKEY33[i]);
1609     pubkeystr[66] = 0;
1610     komodo_chosennotary(&notaryid,height,NOTARY_PUBKEY33,timestamp);
1611     return(notaryid);
1612 }
1613
1614 char *argv0suffix[] =
1615 {
1616     (char *)"verusd", (char *)"verus-cli", (char *)"verusd.exe", (char *)"verus-cli.exe", (char *)"verustestd", (char *)"verustest-cli", (char *)"verustestd.exe", (char *)"verustest-cli.exe"
1617 };
1618
1619 char *argv0names[] =
1620 {
1621     (char *)"VRSC", (char *)"VRSC", (char *)"VRSC", (char *)"VRSC", (char *)"VRSCTEST", (char *)"VRSCTEST", (char *)"VRSCTEST", (char *)"VRSCTEST"
1622 };
1623
1624 int64_t komodo_max_money()
1625 {
1626     return komodo_current_supply(10000000);
1627 }
1628
1629 uint64_t komodo_ac_block_subsidy(int nHeight)
1630 {
1631     // we have to find our era, start from beginning reward, and determine current subsidy
1632     int64_t numerator, denominator, subsidy = 0;
1633     int64_t subsidyDifference;
1634     int32_t numhalvings, curEra = 0, sign = 1;
1635     static uint64_t cached_subsidy; static int32_t cached_numhalvings; static int cached_era;
1636
1637     // check for backwards compat, older chains with no explicit rewards had 0.0001 block reward
1638     if ( ASSETCHAINS_ENDSUBSIDY[0] == 0 && ASSETCHAINS_REWARD[0] == 0 )
1639         subsidy = 0;
1640     else if ( (ASSETCHAINS_ENDSUBSIDY[0] == 0 && ASSETCHAINS_REWARD[0] != 0) || ASSETCHAINS_ENDSUBSIDY[0] != 0 )
1641     {
1642         // if we have an end block in the first era, find our current era
1643         if ( ASSETCHAINS_ENDSUBSIDY[0] != 0 )
1644         {
1645             for ( curEra = 0; curEra <= ASSETCHAINS_LASTERA; curEra++ )
1646             {
1647                 if ( ASSETCHAINS_ENDSUBSIDY[curEra] > nHeight || ASSETCHAINS_ENDSUBSIDY[curEra] == 0 )
1648                     break;
1649             }
1650         }
1651         if ( curEra <= ASSETCHAINS_LASTERA )
1652         {
1653             int64_t nStart = curEra ? ASSETCHAINS_ENDSUBSIDY[curEra - 1] : 0;
1654             subsidy = (int64_t)ASSETCHAINS_REWARD[curEra];
1655             if ( subsidy || (curEra != ASSETCHAINS_LASTERA && ASSETCHAINS_REWARD[curEra + 1] != 0) )
1656             {
1657                 if ( ASSETCHAINS_HALVING[curEra] != 0 )
1658                 {
1659                     if ( (numhalvings = ((nHeight - nStart) / ASSETCHAINS_HALVING[curEra])) > 0 )
1660                     {
1661                         if ( ASSETCHAINS_DECAY[curEra] == 0 )
1662                             subsidy >>= numhalvings;
1663                         else if ( ASSETCHAINS_DECAY[curEra] == 100000000 && ASSETCHAINS_ENDSUBSIDY[curEra] != 0 )
1664                         {
1665                             if ( curEra == ASSETCHAINS_LASTERA )
1666                             {
1667                                 subsidyDifference = subsidy;
1668                             }
1669                             else
1670                             {    
1671                                 // Ex: -ac_eras=3 -ac_reward=0,384,24 -ac_end=1440,260640,0 -ac_halving=1,1440,2103840 -ac_decay 100000000,97750000,0
1672                                 subsidyDifference = subsidy - ASSETCHAINS_REWARD[curEra + 1];
1673                                 if (subsidyDifference < 0)
1674                                 {
1675                                     sign = -1;
1676                                     subsidyDifference *= sign;
1677                                 }
1678                             }
1679                             denominator = ASSETCHAINS_ENDSUBSIDY[curEra] - nStart;
1680                             numerator = denominator - ((ASSETCHAINS_ENDSUBSIDY[curEra] - nHeight) + ((nHeight - nStart) % ASSETCHAINS_HALVING[curEra]));
1681                             subsidy = subsidy - sign * ((subsidyDifference * numerator) / denominator);
1682                         }
1683                         else
1684                         {
1685                             if ( cached_subsidy > 0 && cached_era == curEra && cached_numhalvings == numhalvings )
1686                                 subsidy = cached_subsidy;
1687                             else
1688                             {
1689                                 for (int i=0; i < numhalvings && subsidy != 0; i++)
1690                                     subsidy = (subsidy * ASSETCHAINS_DECAY[curEra]) / 100000000;
1691                                 cached_subsidy = subsidy;
1692                                 cached_numhalvings = numhalvings;
1693                                 cached_era = curEra;
1694                             }
1695                         }
1696                     }
1697                 }
1698             }
1699         }
1700     }
1701     if (nHeight == 1)
1702     {
1703         if (_IsVerusActive() && !PBAAS_TESTMODE)
1704         {
1705             subsidy += ASSETCHAINS_SUPPLY + (ASSETCHAINS_MAGIC & 0xffffff);
1706         }
1707         else
1708         {
1709             subsidy += ASSETCHAINS_SUPPLY;
1710         }
1711     }
1712     return(subsidy);
1713 }
1714
1715 extern int64_t MAX_MONEY;
1716 extern int64_t MAX_SUPPLY;
1717 extern std::string VERUS_DEFAULT_ZADDR;
1718 bool SetThisChain(const UniValue &chainDefinition);
1719 const uint256 &CurrencyDefHash();
1720
1721 void komodo_args(char *argv0)
1722 {
1723     extern const char *Notaries_elected1[][2];
1724
1725     std::string name; 
1726     char *dirname,fname[512],arg0str[64],magicstr[9]; 
1727     uint8_t magic[4],extrabuf[384],*extraptr=0; FILE *fp; 
1728     uint64_t val; 
1729     uint16_t port; 
1730     int32_t baseid,len,n,extralen = 0;
1731
1732     IS_KOMODO_NOTARY = GetBoolArg("-notary", false);
1733
1734     if ( GetBoolArg("-gen", false) != 0 )
1735     {
1736         KOMODO_MININGTHREADS = GetArg("-genproclimit",-1);
1737         if (KOMODO_MININGTHREADS == 0)
1738             mapArgs["-gen"] = "0";
1739     }
1740     else KOMODO_MININGTHREADS = 0;
1741
1742     if ( (KOMODO_EXCHANGEWALLET= GetBoolArg("-exchange", false)) != 0 )
1743         fprintf(stderr,"KOMODO_EXCHANGEWALLET mode active\n");
1744     DONATION_PUBKEY = GetArg("-donation", "");
1745     NOTARY_PUBKEY = GetArg("-pubkey", "");
1746     if ( strlen(NOTARY_PUBKEY.c_str()) == 66 )
1747     {
1748         CPubKey pubKey = CPubKey(ParseHex(NOTARY_PUBKEY));
1749         if (pubKey.IsValid())
1750         {
1751             USE_EXTERNAL_PUBKEY = 1;
1752             if ( IS_KOMODO_NOTARY == 0 )
1753             {
1754                 for (int i=0; i<64; i++)
1755                     if ( strcmp(NOTARY_PUBKEY.c_str(),Notaries_elected1[i][1]) == 0 )
1756                     {
1757                         IS_KOMODO_NOTARY = 1;
1758                         fprintf(stderr,"running as notary.%d %s\n",i,Notaries_elected1[i][0]);
1759                         break;
1760                     }
1761             }
1762         }
1763         //KOMODO_PAX = 1;
1764     } //else KOMODO_PAX = GetArg("-pax",0);
1765
1766     /*
1767     if ( argv0 != 0 )
1768     {
1769         len = (int32_t)strlen(argv0);
1770         for (int i = 0; i < sizeof(argv0suffix)/sizeof(*argv0suffix); i++)
1771         {
1772             n = (int32_t)strlen(argv0suffix[i]);
1773             if ( strcmp(&argv0[len - n],argv0suffix[i]) == 0 )
1774             {
1775                 //printf("ARGV0.(%s) -> matches suffix (%s) -> ac_name.(%s)\n",argv0,argv0suffix[i],argv0names[i]);
1776                 name = argv0names[i];
1777                 break;
1778             }
1779         }
1780     }
1781     */
1782
1783     // either the testmode parameter or calling this chain VRSCTEST will put us into testmode
1784     PBAAS_TESTMODE = GetBoolArg("-testmode", false);
1785
1786     // setting test mode also prevents the name of this chain from being set to VRSC
1787
1788     //printf("%s: initial name: %s\n", __func__, name.c_str());
1789
1790     // for testnet release, default to testnet
1791     name = GetArg("-chain", name == "" ? "VRSC" : name);
1792     name = GetArg("-ac_name", name);
1793
1794     std::string lowerName = boost::to_lower_copy(name);
1795
1796     if (lowerName != "vrsc")
1797     {
1798         PBAAS_TESTMODE = true;
1799     }
1800
1801     // both VRSC and VRSCTEST are names that cannot be
1802     // used as alternate chain names
1803     if ((PBAAS_TESTMODE && lowerName == "vrsc") || lowerName == "vrsctest")
1804     {
1805         // upper case name
1806         name = "VRSCTEST";
1807     }
1808     else if (lowerName == "vrsc")
1809     {
1810         name = "VRSC";
1811     }
1812
1813     //printf("%s: chain name: %s\n", __func__, name.c_str());
1814
1815     mapArgs["-ac_name"] = name;
1816     memset(ASSETCHAINS_SYMBOL, 0, sizeof(ASSETCHAINS_SYMBOL));
1817     strcpy(ASSETCHAINS_SYMBOL, name.c_str());
1818
1819     ASSETCHAINS_ALGO = ASSETCHAINS_VERUSHASH;
1820     ASSETCHAINS_LWMAPOS = 50;
1821     ASSETCHAINS_STAKED = 0;
1822
1823     bool paramsLoaded = false;
1824
1825     if (name == "VRSC")
1826     {
1827         // first setup Verus parameters
1828         mapArgs["-ac_algo"] = "verushash";
1829         mapArgs["-ac_cc"] = "1";
1830         mapArgs["-ac_supply"] = "0";
1831         mapArgs["-ac_eras"] = "3";
1832         mapArgs["-ac_reward"] = "0,38400000000,2400000000";
1833         mapArgs["-ac_halving"] = "1,43200,1051920";
1834         mapArgs["-ac_decay"] = "100000000,0,0";
1835         mapArgs["-ac_options"] = "72,0,0";      // OPTION_ID_REFERRALS + OPTION_CANBERESERVE
1836         mapArgs["-ac_end"] = "10080,226080,0";
1837         mapArgs["-ac_timelockgte"] = "19200000000";
1838         mapArgs["-ac_timeunlockfrom"] = "129600";
1839         mapArgs["-ac_timeunlockto"] = "1180800";
1840         mapArgs["-ac_veruspos"] = "50";
1841
1842         ASSETCHAINS_TIMELOCKGTE = 19200000000;
1843         ASSETCHAINS_TIMEUNLOCKFROM = 129600;
1844         ASSETCHAINS_TIMEUNLOCKTO = 1180800;
1845
1846         if (!ReadConfigFile("VRSC", mapArgs, mapMultiArgs))
1847         {
1848             LogPrintf("Config file for %s not found.\n", name.c_str());
1849         }
1850     }
1851     else if (name == "VRSCTEST")
1852     {
1853         // setup Verus test parameters
1854         mapArgs["-ac_algo"] = "verushash";
1855         mapArgs["-ac_cc"] = "1";
1856         mapArgs["-ac_supply"] = "5000000000000000";
1857         mapArgs["-ac_eras"] = "1";
1858         mapArgs["-ac_reward"] = "2400000000";
1859         std::string halving = GetArg("-ac_halving", "1991304"); // this assignment is required for an ARM compiler workaround
1860         mapArgs["-ac_halving"] = halving;    // allow testing easily with different values here
1861         mapArgs["-ac_decay"] = "0";
1862         mapArgs["-ac_options"] = "72";       // OPTION_ID_REFERRALS + OPTION_CANBERESERVE
1863         mapArgs["-ac_end"] = "0";
1864         mapArgs["-ac_veruspos"] = "50";
1865
1866         ASSETCHAINS_TIMELOCKGTE = _ASSETCHAINS_TIMELOCKOFF;
1867         ASSETCHAINS_TIMEUNLOCKFROM = 0;
1868         ASSETCHAINS_TIMEUNLOCKTO = 0;
1869
1870         if (!ReadConfigFile("VRSCTEST", mapArgs, mapMultiArgs))
1871         {
1872             LogPrintf("Config file for %s not found.\n", name.c_str());
1873         }
1874     }
1875     else
1876     {
1877         map<string, string> settings;
1878         map<string, vector<string>> settingsmulti;
1879
1880         // this is a PBaaS chain, so look for an installation on the local file system or check the Verus daemon if it's running
1881         // printf("Reading config file for %s\n", name.c_str());
1882         name = boost::to_lower_copy(name);
1883         if (!ReadConfigFile(name, mapArgs, mapMultiArgs))
1884         {
1885             // if we are requested to automatically load the information from the Verus chain, do it if we can find the daemon
1886             if (ReadConfigFile(PBAAS_TESTMODE ? "VRSCTEST" : "VRSC", settings, settingsmulti))
1887             {
1888                 auto user = settingsmulti.find("-rpcuser");
1889                 auto pwd = settingsmulti.find("-rpcpassword");
1890                 auto host = settingsmulti.find("-rpchost");
1891                 auto port = settingsmulti.find("-rpcport");
1892                 auto multiEnd = settingsmulti.end();
1893                 PBAAS_USERPASS = (user == multiEnd ? "" : user->second[0]) + ":" + ((pwd == multiEnd) ? "" : pwd->second[0]);
1894                 PBAAS_PORT = port == multiEnd ? 0 : atoi(port->second[0]);
1895                 PBAAS_HOST = host == multiEnd ? "" : host->second[0];
1896                 if (!PBAAS_HOST.size())
1897                 {
1898                     PBAAS_HOST = "127.0.0.1";
1899                 }
1900                 UniValue params(UniValue::VARR);
1901                 params.push_back(name);
1902
1903                 UniValue result;
1904                 try
1905                 {
1906                     result = RPCCallRoot("getcurrency", params);
1907                     // set local parameters
1908                     result = find_value(result, "result");
1909                     if (result.isNull() || !SetThisChain(result))
1910                     {
1911                         throw error("Cannot find blockchain data");
1912                     }
1913                     name = string(ASSETCHAINS_SYMBOL);
1914                     paramsLoaded = true;
1915                 }
1916                 catch(const std::exception& e)
1917                 {
1918                     if (result.size() > 0)
1919                     {
1920                         // load the mapArgs from the chain definition
1921                         printf("getcurrency result:\n");
1922                         auto keys = result.getKeys();
1923                         auto values = result.getValues();
1924                         for (int i = 0; i < keys.size(); i++)
1925                         {
1926                             printf("%s : %s\n", keys[i].c_str(), values[i].getValStr().c_str());
1927                         }
1928                     }
1929                     printf("Failure to read chain definition from config file or %s blockchain.\n", PBAAS_TESTMODE ? "VRSCTEST" : "VRSC");
1930                     printf("Cannot load config\n");
1931                     exit(1);
1932                 }
1933             }
1934             else
1935             {
1936                 printf("Config file for %s not found. Cannot load %s information from blockchain.\n", PBAAS_TESTMODE ? "VRSCTEST" : "VRSC", name.c_str());
1937                 exit(1);
1938             }
1939         }
1940         else
1941         {
1942             // if we are requested to automatically load the information from the Verus chain, do it if we can find the daemon
1943             if (ReadConfigFile(PBAAS_TESTMODE ? "VRSCTEST" : "VRSC", settings, settingsmulti))
1944             {
1945                 auto user = settingsmulti.find("-rpcuser");
1946                 auto pwd = settingsmulti.find("-rpcpassword");
1947                 auto host = settingsmulti.find("-rpchost");
1948                 auto port = settingsmulti.find("-rpcport");
1949                 auto multiEnd = settingsmulti.end();
1950                 PBAAS_USERPASS = (user == multiEnd ? "" : user->second[0]) + ":" + ((pwd == multiEnd) ? "" : pwd->second[0]);
1951                 PBAAS_PORT = port == multiEnd ? 0 : atoi(port->second[0]);
1952                 PBAAS_HOST = host == multiEnd ? "" : host->second[0];
1953                 if (!PBAAS_HOST.size())
1954                 {
1955                     PBAAS_HOST = "127.0.0.1";
1956                 }
1957             }
1958         }
1959     }
1960
1961     VERUS_CHAINNAME = PBAAS_TESTMODE ? "VRSCTEST" : "VRSC";
1962     VERUS_CHAINID = CCrossChainRPCData::GetID(VERUS_CHAINNAME);
1963     memset(ASSETCHAINS_SYMBOL, 0, sizeof(ASSETCHAINS_SYMBOL));
1964     strcpy(ASSETCHAINS_SYMBOL, name.c_str());
1965
1966     /*
1967     KOMODO_STOPAT = GetArg("-stopat",0);
1968     ASSETCHAINS_CC = GetArg("-ac_cc",1);
1969     KOMODO_CCACTIVATE = GetArg("-ac_ccactivate",0);
1970     ASSETCHAINS_PUBLIC = GetArg("-ac_public",0);
1971     ASSETCHAINS_PRIVATE = GetArg("-ac_private",0);
1972     */
1973     KOMODO_STOPAT = 0;
1974     ASSETCHAINS_CC = 1;
1975     KOMODO_CCACTIVATE = 0;
1976     ASSETCHAINS_PUBLIC = 0;
1977     ASSETCHAINS_PRIVATE = 0;
1978    
1979     if ( (KOMODO_REWIND= GetArg("-rewind",0)) != 0 )
1980     {
1981         printf("KOMODO_REWIND %d\n",KOMODO_REWIND);
1982     }
1983
1984     if ( name.size() )
1985     {
1986         if (!paramsLoaded)
1987         {
1988             ASSETCHAINS_ALGO = ASSETCHAINS_VERUSHASH;
1989
1990             ASSETCHAINS_LASTERA = GetArg("-ac_eras", 1);
1991             if ( ASSETCHAINS_LASTERA < 1 || ASSETCHAINS_LASTERA > ASSETCHAINS_MAX_ERAS )
1992             {
1993                 ASSETCHAINS_LASTERA = 1;
1994                 printf("ac_eras, if specified, must be between 1 and %u. ac_eras set to %u\n", ASSETCHAINS_MAX_ERAS, ASSETCHAINS_LASTERA);
1995             }
1996             ASSETCHAINS_LASTERA -= 1;
1997
1998             Split(GetArg("-ac_end",""),  ASSETCHAINS_ENDSUBSIDY, 0);
1999             Split(GetArg("-ac_reward",""),  ASSETCHAINS_REWARD, 0);
2000             Split(GetArg("-ac_halving",""),  ASSETCHAINS_HALVING, 0);
2001             Split(GetArg("-ac_decay",""),  ASSETCHAINS_DECAY, 0);
2002             Split(GetArg("-ac_options",""),  ASSETCHAINS_ERAOPTIONS, 0);
2003
2004             for (int j = 0; j < ASSETCHAINS_LASTERA; j++)
2005             {
2006                 if ( ASSETCHAINS_DECAY[j] == 100000000 && ASSETCHAINS_ENDSUBSIDY[0] == 0 )
2007                 {
2008                     ASSETCHAINS_DECAY[j] = 0;
2009                     printf("ERA%u: ASSETCHAINS_DECAY of 100000000 means linear and that needs ASSETCHAINS_ENDSUBSIDY\n", j);
2010                 }
2011                 else if ( ASSETCHAINS_DECAY[j] > 100000000 )
2012                 {
2013                     ASSETCHAINS_DECAY[j] = 0;
2014                     printf("ERA%u: ASSETCHAINS_DECAY can't be more than 100000000\n", j);
2015                 }
2016                 if (ASSETCHAINS_ERAOPTIONS[j] > UINT_MAX)
2017                 {
2018                     printf("ERA%u: ASSETCHAINS_ERAOPTIONS can't be more than max uint32_t\n", j);
2019                 }
2020             }
2021
2022             PBAAS_STARTBLOCK = GetArg("-startblock", 0);
2023             PBAAS_ENDBLOCK = GetArg("-endblock", 0);
2024
2025             // supply is the total of all pre-allocations
2026             ASSETCHAINS_SUPPLY = GetArg("-ac_supply", 0);
2027             ASSETCHAINS_RPCHOST = GetArg("-rpchost", "127.0.0.1");
2028         }
2029
2030         MAX_BLOCK_SIGOPS = 60000;
2031         ASSETCHAINS_COMMISSION = GetArg("-ac_perc",0);
2032         ASSETCHAINS_OVERRIDE_PUBKEY = GetArg("-ac_pubkey","");
2033         ASSETCHAINS_SAPLING = 1;
2034         ASSETCHAINS_OVERWINTER = 1;
2035
2036         if ( strlen(ASSETCHAINS_OVERRIDE_PUBKEY.c_str()) == 66 && ASSETCHAINS_COMMISSION > 0 && ASSETCHAINS_COMMISSION <= 100000000 )
2037             decode_hex(ASSETCHAINS_OVERRIDE_PUBKEY33,33,(char *)ASSETCHAINS_OVERRIDE_PUBKEY.c_str());
2038         else if ( ASSETCHAINS_COMMISSION != 0 )
2039         {
2040             ASSETCHAINS_COMMISSION = 0;
2041             printf("ASSETCHAINS_COMMISSION needs an ASSETCHAINS_OVERRIDE_PUBKEY and cant be more than 100000000 (100%%)\n");
2042         }
2043
2044         if ( ASSETCHAINS_ENDSUBSIDY[0] != 0 || ASSETCHAINS_REWARD[0] != 0 || ASSETCHAINS_HALVING[0] != 0 || ASSETCHAINS_DECAY[0] != 0 || ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_PUBLIC != 0 || ASSETCHAINS_PRIVATE != 0 )
2045         {
2046             // printf("perc.%llu\n",(long long)ASSETCHAINS_COMMISSION);
2047
2048             extraptr = extrabuf;
2049             memcpy(extraptr,ASSETCHAINS_OVERRIDE_PUBKEY33,33), extralen = 33;
2050
2051             // if we have one era, this should create the same data structure as it used to, same if we increase _MAX_ERAS
2052             for ( int i = 0; i <= ASSETCHAINS_LASTERA; i++ )
2053             {
2054                 //printf("ERA%u: end.%llu reward.%llu halving.%llu decay.%llu\n", i,
2055                 //       (long long)ASSETCHAINS_ENDSUBSIDY[i],
2056                 //       (long long)ASSETCHAINS_REWARD[i],
2057                 //       (long long)ASSETCHAINS_HALVING[i],
2058                 //       (long long)ASSETCHAINS_DECAY[i]);
2059
2060                 // TODO: Verify that we don't overrun extrabuf here, which is a 256 byte buffer
2061                 extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_ENDSUBSIDY[i]),(void *)&ASSETCHAINS_ENDSUBSIDY[i]);
2062                 extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_REWARD[i]),(void *)&ASSETCHAINS_REWARD[i]);
2063                 extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_HALVING[i]),(void *)&ASSETCHAINS_HALVING[i]);
2064                 extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_DECAY[i]),(void *)&ASSETCHAINS_DECAY[i]);
2065             }
2066
2067             if (ASSETCHAINS_LASTERA > 0)
2068             {
2069                 extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_LASTERA),(void *)&ASSETCHAINS_LASTERA);
2070             }
2071
2072             // hash in lock above for time locked coinbase transactions above a certain reward value only if the lock above
2073             // param was specified, otherwise, for compatibility, do nothing
2074             if ( ASSETCHAINS_TIMELOCKGTE != _ASSETCHAINS_TIMELOCKOFF )
2075             {
2076                 extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_TIMELOCKGTE),(void *)&ASSETCHAINS_TIMELOCKGTE);
2077                 extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_TIMEUNLOCKFROM),(void *)&ASSETCHAINS_TIMEUNLOCKFROM);
2078                 extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_TIMEUNLOCKTO),(void *)&ASSETCHAINS_TIMEUNLOCKTO);
2079             }
2080
2081             if ( ASSETCHAINS_ALGO != ASSETCHAINS_EQUIHASH )
2082             {
2083                 extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_ALGO),(void *)&ASSETCHAINS_ALGO);
2084             }
2085
2086             if ( ASSETCHAINS_LWMAPOS != 0 )
2087             {
2088                 extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_LWMAPOS),(void *)&ASSETCHAINS_LWMAPOS);
2089             }
2090
2091             // if we have extended PBaaS parameters
2092             if ( PBAAS_STARTBLOCK || PBAAS_ENDBLOCK )
2093             {
2094                 extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(PBAAS_STARTBLOCK),(void *)&PBAAS_STARTBLOCK);
2095                 extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(PBAAS_ENDBLOCK),(void *)&PBAAS_ENDBLOCK);
2096             }
2097
2098             val = ASSETCHAINS_COMMISSION | (((uint64_t)ASSETCHAINS_STAKED & 0xff) << 32) | (((uint64_t)ASSETCHAINS_CC & 0xffff) << 40) | ((ASSETCHAINS_PUBLIC != 0) << 7) | ((ASSETCHAINS_PRIVATE != 0) << 6);
2099             extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(val),(void *)&val);
2100
2101             if (ASSETCHAINS_LASTERA > 0 && ASSETCHAINS_ERAOPTIONS[0] & CCurrencyDefinition::OPTION_FRACTIONAL)
2102             {
2103                 uint32_t options = ASSETCHAINS_ERAOPTIONS[0];
2104                 extralen += iguana_rwnum(1, &extraptr[extralen], sizeof(options), (void *)&options);
2105             }
2106         }
2107
2108         memset(ASSETCHAINS_SYMBOL, 0, sizeof(ASSETCHAINS_SYMBOL));
2109         strcpy(ASSETCHAINS_SYMBOL, name.c_str());
2110
2111         ASSETCHAINS_CHAINID = CCrossChainRPCData::GetID(std::string(ASSETCHAINS_SYMBOL));
2112
2113         //printf("Chain name %s, chain hash, %s\n", ASSETCHAINS_SYMBOL, ASSETCHAINS_CHAINID.ToString().c_str());
2114
2115         MAX_MONEY = komodo_max_money();
2116
2117         //printf("baseid.%d MAX_MONEY.%s %.8f\n",baseid,ASSETCHAINS_SYMBOL,(double)MAX_MONEY/SATOSHIDEN);
2118         ASSETCHAINS_P2PPORT = komodo_port(ASSETCHAINS_SYMBOL,ASSETCHAINS_SUPPLY,&ASSETCHAINS_MAGIC,extraptr,extralen);
2119
2120         while ( (dirname= (char *)GetDataDir(false).string().c_str()) == 0 || dirname[0] == 0 )
2121         {
2122             fprintf(stderr,"waiting for datadir\n");
2123                                                 #ifndef _WIN32
2124             sleep(3);
2125                                                 #else
2126                                                 boost::this_thread::sleep(boost::posix_time::milliseconds(3000));
2127                                                 #endif
2128         }
2129         //fprintf(stderr,"Got datadir.(%s)\n",dirname);
2130         if ( ASSETCHAINS_SYMBOL[0] != 0 )
2131         {
2132             int32_t komodo_baseid(char *origbase);
2133             extern int COINBASE_MATURITY;
2134             if ( (port = komodo_userpass(ASSETCHAINS_USERPASS, ASSETCHAINS_SYMBOL)) != 0 )
2135             {
2136                 ASSETCHAINS_RPCPORT = port;
2137             }
2138             else 
2139             {
2140                 komodo_configfile(ASSETCHAINS_SYMBOL, ASSETCHAINS_P2PPORT + 1);
2141                 komodo_userpass(ASSETCHAINS_USERPASS, ASSETCHAINS_SYMBOL);      // make sure we set user and password on first load
2142             }
2143
2144             if (ASSETCHAINS_LASTERA == 0 && ASSETCHAINS_REWARD[0] == 0)
2145                 COINBASE_MATURITY = 1;
2146             //fprintf(stderr,"ASSETCHAINS_RPCPORT (%s) %u\n",ASSETCHAINS_SYMBOL,ASSETCHAINS_RPCPORT);
2147             ASSETCHAINS_RPCHOST = GetArg("-rpchost", "127.0.0.1");
2148         }
2149         if ( ASSETCHAINS_RPCPORT == 0 )
2150             ASSETCHAINS_RPCPORT = ASSETCHAINS_P2PPORT + 1;
2151         //ASSETCHAINS_NOTARIES = GetArg("-ac_notaries","");
2152         //komodo_assetchain_pubkeys((char *)ASSETCHAINS_NOTARIES.c_str());
2153         iguana_rwnum(1,magic,sizeof(ASSETCHAINS_MAGIC),(void *)&ASSETCHAINS_MAGIC);
2154         for (int i=0; i<4; i++)
2155             sprintf(&magicstr[i<<1],"%02x",magic[i]);
2156         magicstr[8] = 0;
2157 #ifndef FROM_CLI
2158         sprintf(fname,"%s_7776",ASSETCHAINS_SYMBOL);
2159         if ( (fp= fopen(fname,"wb")) != 0 )
2160         {
2161             fprintf(fp,iguanafmtstr,name.c_str(),name.c_str(),name.c_str(),name.c_str(),magicstr,ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT,"78.47.196.146");
2162             fclose(fp);
2163             //printf("created (%s)\n",fname);
2164         } else printf("error creating (%s)\n",fname);
2165 #endif
2166         if ( KOMODO_CCACTIVATE != 0 && ASSETCHAINS_CC < 2 )
2167         {
2168             ASSETCHAINS_CC = 2;
2169             fprintf(stderr,"smart utxo CC contracts will activate at height.%d\n",KOMODO_CCACTIVATE);
2170         }
2171
2172         ASSETCHAINS_RPCCREDENTIALS = string(ASSETCHAINS_USERPASS);
2173
2174         if (!paramsLoaded)
2175         {
2176             // we need to set the chain definition for this chain based on globals set above
2177             UniValue obj(UniValue::VOBJ);
2178
2179             obj.push_back(Pair("premine", ASSETCHAINS_SUPPLY));
2180             obj.push_back(Pair("name", ASSETCHAINS_SYMBOL));
2181
2182             obj.push_back(Pair("startblock", PBAAS_STARTBLOCK));
2183             obj.push_back(Pair("endblock", PBAAS_ENDBLOCK));
2184
2185             UniValue eras(UniValue::VARR);
2186             for (int i = 0; i <= ASSETCHAINS_LASTERA; i++)
2187             {
2188                 UniValue era(UniValue::VOBJ);
2189                 era.push_back(Pair("reward", ASSETCHAINS_REWARD[i]));
2190                 era.push_back(Pair("decay", ASSETCHAINS_DECAY[i]));
2191                 era.push_back(Pair("halving", ASSETCHAINS_HALVING[i]));
2192                 era.push_back(Pair("eraend", ASSETCHAINS_ENDSUBSIDY[i]));
2193                 era.push_back(Pair("eraoptions", ASSETCHAINS_ERAOPTIONS[i]));
2194                 eras.push_back(era);
2195             }
2196             obj.push_back(Pair("eras", eras));
2197
2198             std::vector<std::string> addn;
2199             UniValue nodeArr(UniValue::VARR);
2200             std::map<std::string, std::vector<std::string>>::iterator seedIt = mapMultiArgs.find("-seednode");
2201             if (seedIt != mapMultiArgs.end())
2202             {
2203                 for (auto oneSeedStr : seedIt->second)
2204                 {
2205                     nodeArr.push_back(CNodeData(oneSeedStr, "").ToUniValue());
2206                 }
2207                 obj.pushKV("nodes", nodeArr);
2208             }
2209
2210             // we do not have pre-allocation data here, so fake one lump sum of pre-allocation to a NULL address
2211             // this will get replaced from either block 1 of our chain, or a connection to VRSC
2212             if (ASSETCHAINS_SUPPLY)
2213             {
2214                 UniValue preallocArr(UniValue::VARR);
2215                 UniValue preallocObj(UniValue::VOBJ);
2216                 preallocObj.push_back(Pair("DestinationPending", ValueFromAmount((CAmount)ASSETCHAINS_SUPPLY)));
2217                 preallocArr.push_back(preallocObj);
2218                 obj.push_back(Pair("preallocations", preallocArr));
2219             }
2220             SetThisChain(obj);
2221             paramsLoaded = true;
2222         }
2223     }
2224     else
2225     {
2226         char fname[512],username[512],password[4096]; int32_t iter; FILE *fp;
2227         ASSETCHAINS_P2PPORT = 7770;
2228         ASSETCHAINS_RPCPORT = 7771;
2229         for (iter=0; iter<2; iter++)
2230         {
2231             strcpy(fname,GetDataDir().string().c_str());
2232 #ifdef _WIN32
2233             while ( fname[strlen(fname)-1] != '\\' )
2234                 fname[strlen(fname)-1] = 0;
2235             if ( iter == 0 )
2236                 strcat(fname,"Komodo\\komodo.conf");
2237             else strcat(fname,"Bitcoin\\bitcoin.conf");
2238 #else
2239             while ( fname[strlen(fname)-1] != '/' )
2240                 fname[strlen(fname)-1] = 0;
2241 #ifdef __APPLE__
2242             if ( iter == 0 )
2243                 strcat(fname,"Komodo/Komodo.conf");
2244             else strcat(fname,"Bitcoin/Bitcoin.conf");
2245 #else
2246             if ( iter == 0 )
2247                 strcat(fname,".komodo/komodo.conf");
2248             else strcat(fname,".bitcoin/bitcoin.conf");
2249 #endif
2250 #endif
2251             if ( (fp= fopen(fname,"rb")) != 0 )
2252             {
2253                 _komodo_userpass(username,password,fp);
2254                 sprintf(iter == 0 ? KMDUSERPASS : BTCUSERPASS,"%s:%s",username,password);
2255                 fclose(fp);
2256                 //printf("KOMODO.(%s) -> userpass.(%s)\n",fname,KMDUSERPASS);
2257             } //else printf("couldnt open.(%s)\n",fname);
2258             if ( IS_KOMODO_NOTARY == 0 )
2259                 break;
2260         }
2261     }
2262     if ( ASSETCHAINS_SYMBOL[0] != 0 )
2263     {
2264         BITCOIND_RPCPORT = GetArg("-rpcport", ASSETCHAINS_RPCPORT);
2265         //fprintf(stderr,"(%s) port.%u chain params initialized\n",ASSETCHAINS_SYMBOL,BITCOIND_RPCPORT);
2266     } else BITCOIND_RPCPORT = GetArg("-rpcport", BaseParams().RPCPort());
2267 }
2268
2269 void komodo_nameset(char *symbol,char *dest,char *source)
2270 {
2271     if ( source[0] == 0 )
2272     {
2273         strcpy(symbol,(char *)"KMD");
2274         strcpy(dest,(char *)"BTC");
2275     }
2276     else
2277     {
2278         strcpy(symbol,source);
2279         strcpy(dest,(char *)"KMD");
2280     }
2281 }
2282
2283 struct komodo_state *komodo_stateptrget(char *base)
2284 {
2285     int32_t baseid;
2286     if ( base == 0 || base[0] == 0 || strcmp(base,(char *)"KMD") == 0 )
2287         return(&KOMODO_STATES[33]);
2288     else if ( (baseid= komodo_baseid(base)) >= 0 )
2289         return(&KOMODO_STATES[baseid+1]);
2290     else return(&KOMODO_STATES[0]);
2291 }
2292
2293 struct komodo_state *komodo_stateptr(char *symbol,char *dest)
2294 {
2295     int32_t baseid;
2296     komodo_nameset(symbol,dest,ASSETCHAINS_SYMBOL);
2297     return(komodo_stateptrget(symbol));
2298 }
2299
2300 void komodo_prefetch(FILE *fp)
2301 {
2302     long fsize,fpos; int32_t incr = 16*1024*1024;
2303     fpos = ftell(fp);
2304     fseek(fp,0,SEEK_END);
2305     fsize = ftell(fp);
2306     if ( fsize > incr )
2307     {
2308         char *ignore = (char *)malloc(incr);
2309         if ( ignore != 0 )
2310         {
2311             rewind(fp);
2312             while ( fread(ignore,1,incr,fp) == incr ) // prefetch
2313                 fprintf(stderr,".");
2314             free(ignore);
2315         }
2316     }
2317     fseek(fp,fpos,SEEK_SET);
2318 }
2319
This page took 0.15959 seconds and 4 git commands to generate.