]>
Commit | Line | Data |
---|---|---|
6b5cfbb4 | 1 | /****************************************************************************** |
713c2a94 | 2 | * Copyright © 2014-2018 The SuperNET Developers. * |
6b5cfbb4 | 3 | * * |
4 | * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * | |
5 | * the top-level directory of this distribution for the individual copyright * | |
6 | * holder information and the developer policies on copyright and licensing. * | |
7 | * * | |
8 | * Unless otherwise agreed in a custom licensing agreement, no part of the * | |
9 | * SuperNET software, including this file may be copied, modified, propagated * | |
10 | * or distributed except according to the terms contained in the LICENSE file * | |
11 | * * | |
12 | * Removal or modification of this copyright notice is prohibited. * | |
13 | * * | |
14 | ******************************************************************************/ | |
15 | ||
16 | #ifndef H_KOMODOKV_H | |
17 | #define H_KOMODOKV_H | |
18 | ||
5416af1d | 19 | #include "komodo_defs.h" |
20 | ||
6b5cfbb4 | 21 | int32_t komodo_kvcmp(uint8_t *refvalue,uint16_t refvaluesize,uint8_t *value,uint16_t valuesize) |
22 | { | |
23 | if ( refvalue == 0 && value == 0 ) | |
24 | return(0); | |
25 | else if ( refvalue == 0 || value == 0 ) | |
26 | return(-1); | |
27 | else if ( refvaluesize != valuesize ) | |
28 | return(-1); | |
29 | else return(memcmp(refvalue,value,valuesize)); | |
30 | } | |
31 | ||
32 | int32_t komodo_kvnumdays(uint32_t flags) | |
33 | { | |
34 | int32_t numdays; | |
35 | if ( (numdays= ((flags>>2)&0x3ff)+1) > 365 ) | |
36 | numdays = 365; | |
37 | return(numdays); | |
38 | } | |
39 | ||
40 | int32_t komodo_kvduration(uint32_t flags) | |
41 | { | |
42 | return(komodo_kvnumdays(flags) * KOMODO_KVDURATION); | |
43 | } | |
44 | ||
45 | uint64_t komodo_kvfee(uint32_t flags,int32_t opretlen,int32_t keylen) | |
46 | { | |
579d2374 | 47 | int32_t numdays,k; uint64_t fee; |
48 | if ( (k= keylen) > 32 ) | |
49 | k = 32; | |
6b5cfbb4 | 50 | numdays = komodo_kvnumdays(flags); |
579d2374 | 51 | if ( (fee= (numdays*(opretlen * opretlen / k))) < 100000 ) |
6b5cfbb4 | 52 | fee = 100000; |
53 | return(fee); | |
54 | } | |
55 | ||
a663f236 | 56 | int32_t komodo_kvsearch(uint256 *pubkeyp,int32_t current_height,uint32_t *flagsp,int32_t *heightp,uint8_t value[IGUANA_MAXSCRIPTSIZE],uint8_t *key,int32_t keylen) |
57 | { | |
58 | struct komodo_kv *ptr; int32_t duration,retval = -1; | |
59 | *heightp = -1; | |
60 | *flagsp = 0; | |
61 | memset(pubkeyp,0,sizeof(*pubkeyp)); | |
62 | portable_mutex_lock(&KOMODO_KV_mutex); | |
63 | HASH_FIND(hh,KOMODO_KV,key,keylen,ptr); | |
64 | if ( ptr != 0 ) | |
65 | { | |
66 | duration = komodo_kvduration(ptr->flags); | |
67 | //printf("duration.%d flags.%d current.%d ht.%d keylen.%d valuesize.%d\n",duration,ptr->flags,current_height,ptr->height,ptr->keylen,ptr->valuesize); | |
68 | if ( current_height > (ptr->height + duration) ) | |
69 | { | |
70 | HASH_DELETE(hh,KOMODO_KV,ptr); | |
71 | if ( ptr->value != 0 ) | |
72 | free(ptr->value); | |
73 | if ( ptr->key != 0 ) | |
74 | free(ptr->key); | |
75 | free(ptr); | |
76 | } | |
77 | else | |
78 | { | |
79 | *heightp = ptr->height; | |
80 | *flagsp = ptr->flags; | |
81 | int32_t i; for (i=0; i<32; i++) | |
31c5d002 | 82 | { |
ebeae1eb | 83 | //printf("%02x",((uint8_t *)&ptr->pubkey)[31-i]); |
31c5d002 | 84 | ((uint8_t *)pubkeyp)[i] = ((uint8_t *)&ptr->pubkey)[31-i]; |
85 | } | |
ebeae1eb | 86 | //printf(" ptr->pubkey\n"); |
a663f236 | 87 | memcpy(pubkeyp,&ptr->pubkey,sizeof(*pubkeyp)); |
8a382987 | 88 | if ( (retval= ptr->valuesize) > 0 ) |
a663f236 | 89 | memcpy(value,ptr->value,retval); |
90 | } | |
91 | } | |
92 | portable_mutex_unlock(&KOMODO_KV_mutex); | |
8a382987 | 93 | if ( retval < 0 ) |
94 | { | |
95 | // search rawmempool | |
96 | } | |
a663f236 | 97 | return(retval); |
98 | } | |
99 | ||
6b5cfbb4 | 100 | void komodo_kvupdate(uint8_t *opretbuf,int32_t opretlen,uint64_t value) |
101 | { | |
87f82355 | 102 | static uint256 zeroes; |
b8847947 | 103 | uint32_t flags; uint256 pubkey,refpubkey,sig; int32_t i,refvaluesize,hassig,coresize,haspubkey,height,kvheight; uint16_t keylen,valuesize,newflag = 0; uint8_t *key,*valueptr,keyvalue[IGUANA_MAXSCRIPTSIZE]; struct komodo_kv *ptr; char *transferpubstr,*tstr; uint64_t fee; |
3e71f585 | 104 | if ( ASSETCHAINS_SYMBOL[0] == 0 ) // disable KV for KMD |
105 | return; | |
6b5cfbb4 | 106 | iguana_rwnum(0,&opretbuf[1],sizeof(keylen),&keylen); |
107 | iguana_rwnum(0,&opretbuf[3],sizeof(valuesize),&valuesize); | |
108 | iguana_rwnum(0,&opretbuf[5],sizeof(height),&height); | |
109 | iguana_rwnum(0,&opretbuf[9],sizeof(flags),&flags); | |
110 | key = &opretbuf[13]; | |
6fc1969b | 111 | if ( keylen+13 > opretlen ) |
112 | { | |
00603efa | 113 | static uint32_t counter; |
9a3917ed | 114 | if ( ++counter < 1 ) |
00603efa | 115 | printf("komodo_kvupdate: keylen.%d + 13 > opretlen.%d, this can be ignored\n",keylen,opretlen); |
f2b068bd | 116 | return; |
6fc1969b | 117 | } |
6b5cfbb4 | 118 | valueptr = &key[keylen]; |
119 | fee = komodo_kvfee(flags,opretlen,keylen); | |
120 | //printf("fee %.8f vs %.8f flags.%d keylen.%d valuesize.%d height.%d (%02x %02x %02x) (%02x %02x %02x)\n",(double)fee/COIN,(double)value/COIN,flags,keylen,valuesize,height,key[0],key[1],key[2],valueptr[0],valueptr[1],valueptr[2]); | |
121 | if ( value >= fee ) | |
122 | { | |
123 | coresize = (int32_t)(sizeof(flags)+sizeof(height)+sizeof(keylen)+sizeof(valuesize)+keylen+valuesize+1); | |
a9aca4da | 124 | if ( opretlen == coresize || opretlen == coresize+sizeof(uint256) || opretlen == coresize+2*sizeof(uint256) ) |
6b5cfbb4 | 125 | { |
126 | memset(&pubkey,0,sizeof(pubkey)); | |
127 | memset(&sig,0,sizeof(sig)); | |
a9aca4da | 128 | if ( (haspubkey= (opretlen >= coresize+sizeof(uint256))) != 0 ) |
6b5cfbb4 | 129 | { |
130 | for (i=0; i<32; i++) | |
131 | ((uint8_t *)&pubkey)[i] = opretbuf[coresize+i]; | |
132 | } | |
a9aca4da | 133 | if ( (hassig= (opretlen == coresize+sizeof(uint256)*2)) != 0 ) |
6b5cfbb4 | 134 | { |
135 | for (i=0; i<32; i++) | |
a9aca4da | 136 | ((uint8_t *)&sig)[i] = opretbuf[coresize+sizeof(uint256)+i]; |
6b5cfbb4 | 137 | } |
b8847947 | 138 | memcpy(keyvalue,key,keylen); |
139 | if ( (refvaluesize= komodo_kvsearch((uint256 *)&refpubkey,height,&flags,&kvheight,&keyvalue[keylen],key,keylen)) >= 0 ) | |
6b5cfbb4 | 140 | { |
141 | if ( memcmp(&zeroes,&refpubkey,sizeof(refpubkey)) != 0 ) | |
142 | { | |
b8847947 | 143 | if ( komodo_kvsigverify(keyvalue,keylen+refvaluesize,refpubkey,sig) < 0 ) |
6b5cfbb4 | 144 | { |
707451ae | 145 | printf("komodo_kvsigverify error [%d]\n",coresize-13); |
6b5cfbb4 | 146 | return; |
147 | } | |
148 | } | |
149 | } | |
150 | portable_mutex_lock(&KOMODO_KV_mutex); | |
151 | HASH_FIND(hh,KOMODO_KV,key,keylen,ptr); | |
6b5cfbb4 | 152 | if ( ptr != 0 ) |
153 | { | |
83af8cbf | 154 | //if ( (ptr->flags & KOMODO_KVPROTECTED) != 0 ) |
6b5cfbb4 | 155 | { |
084de19d | 156 | tstr = (char *)"transfer:"; |
a287221c | 157 | transferpubstr = (char *)&valueptr[strlen(tstr)]; |
158 | if ( strncmp(tstr,(char *)valueptr,strlen(tstr)) == 0 && is_hexstr(transferpubstr,0) == 64 ) | |
6b5cfbb4 | 159 | { |
fdab5c73 | 160 | printf("transfer.(%s) to [%s]? ishex.%d\n",key,transferpubstr,is_hexstr(transferpubstr,0)); |
6b5cfbb4 | 161 | for (i=0; i<32; i++) |
162 | ((uint8_t *)&pubkey)[31-i] = _decode_hex(&transferpubstr[i*2]); | |
163 | } | |
164 | } | |
165 | } | |
166 | else if ( ptr == 0 ) | |
167 | { | |
168 | ptr = (struct komodo_kv *)calloc(1,sizeof(*ptr)); | |
6b5cfbb4 | 169 | ptr->key = (uint8_t *)calloc(1,keylen); |
170 | ptr->keylen = keylen; | |
171 | memcpy(ptr->key,key,keylen); | |
172 | newflag = 1; | |
173 | HASH_ADD_KEYPTR(hh,KOMODO_KV,ptr->key,ptr->keylen,ptr); | |
ce5dd547 | 174 | //printf("KV add.(%s) (%s)\n",ptr->key,valueptr); |
6b5cfbb4 | 175 | } |
36a759fc | 176 | if ( newflag != 0 || (ptr->flags & KOMODO_KVPROTECTED) == 0 ) |
6b5cfbb4 | 177 | { |
178 | if ( ptr->value != 0 ) | |
179 | free(ptr->value), ptr->value = 0; | |
180 | if ( (ptr->valuesize= valuesize) != 0 ) | |
181 | { | |
182 | ptr->value = (uint8_t *)calloc(1,valuesize); | |
183 | memcpy(ptr->value,valueptr,valuesize); | |
184 | } | |
4f616c5a | 185 | } else fprintf(stderr,"newflag.%d zero or protected %d\n",newflag,(ptr->flags & KOMODO_KVPROTECTED)); |
ebeae1eb | 186 | /*for (i=0; i<32; i++) |
a663f236 | 187 | printf("%02x",((uint8_t *)&ptr->pubkey)[i]); |
188 | printf(" <- "); | |
189 | for (i=0; i<32; i++) | |
190 | printf("%02x",((uint8_t *)&pubkey)[i]); | |
ebeae1eb | 191 | printf(" new pubkey\n");*/ |
a9d3adf5 | 192 | memcpy(&ptr->pubkey,&pubkey,sizeof(ptr->pubkey)); |
193 | ptr->height = height; | |
7e907fdd | 194 | ptr->flags = flags; // jl777 used to or in KVPROTECTED |
6b5cfbb4 | 195 | portable_mutex_unlock(&KOMODO_KV_mutex); |
4f616c5a | 196 | } else fprintf(stderr,"size mismatch %d vs %d\n",opretlen,coresize); |
197 | } else fprintf(stderr,"not enough fee\n"); | |
6b5cfbb4 | 198 | } |
199 | ||
200 | #endif |