1 /******************************************************************************
2 * Copyright © 2014-2018 The SuperNET Developers. *
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. *
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 *
12 * Removal or modification of this copyright notice is prohibited. *
14 ******************************************************************************/
16 #ifndef H_KOMODOCCDATA_H
17 #define H_KOMODOCCDATA_H
19 struct komodo_ccdata *CC_data;
20 int32_t CC_firstheight;
22 uint256 BuildMerkleTree(bool* fMutated, const std::vector<uint256> leaves, std::vector<uint256> &vMerkleTree);
24 uint256 komodo_calcMoM(int32_t height,int32_t MoMdepth)
26 static uint256 zero; CBlockIndex *pindex; int32_t i; std::vector<uint256> tree, leaves;
28 MoMdepth &= 0xffff; // In case it includes the ccid
29 if ( MoMdepth >= height )
31 for (i=0; i<MoMdepth; i++)
33 if ( (pindex= komodo_chainactive(height - i)) != 0 )
34 leaves.push_back(pindex->hashMerkleRoot);
38 return BuildMerkleTree(&fMutated, leaves, tree);
41 struct komodo_ccdata_entry *komodo_allMoMs(int32_t *nump,uint256 *MoMoMp,int32_t kmdstarti,int32_t kmdendi)
43 struct komodo_ccdata_entry *allMoMs=0; struct komodo_ccdata *ccdata,*tmpptr; int32_t i,num,max;
44 bool fMutated; std::vector<uint256> tree, leaves;
46 portable_mutex_lock(&KOMODO_CC_mutex);
47 DL_FOREACH_SAFE(CC_data,ccdata,tmpptr)
49 if ( ccdata->MoMdata.height <= kmdendi && ccdata->MoMdata.height >= kmdstarti )
54 allMoMs = (struct komodo_ccdata_entry *)realloc(allMoMs,max * sizeof(*allMoMs));
56 allMoMs[num].MoM = ccdata->MoMdata.MoM;
57 allMoMs[num].notarized_height = ccdata->MoMdata.notarized_height;
58 allMoMs[num].kmdheight = ccdata->MoMdata.height;
59 allMoMs[num].txi = ccdata->MoMdata.txi;
60 strcpy(allMoMs[num].symbol,ccdata->symbol);
63 if ( ccdata->MoMdata.height < kmdstarti )
66 portable_mutex_unlock(&KOMODO_CC_mutex);
67 if ( (*nump= num) > 0 )
70 leaves.push_back(allMoMs[i].MoM);
71 *MoMoMp = BuildMerkleTree(&fMutated, leaves, tree);
81 int32_t komodo_addpair(struct komodo_ccdataMoMoM *mdata,int32_t notarized_height,int32_t offset,int32_t maxpairs)
84 if ( mdata->numpairs >= maxpairs )
87 mdata->pairs = (struct komodo_ccdatapair *)realloc(mdata->pairs,sizeof(*mdata->pairs)*maxpairs);
88 //fprintf(stderr,"pairs reallocated to %p num.%d\n",mdata->pairs,mdata->numpairs);
91 fprintf(stderr,"komodo_addpair.maxpairs %d must be >= 0\n",(int32_t)maxpairs);
94 mdata->pairs[mdata->numpairs].notarized_height = notarized_height;
95 mdata->pairs[mdata->numpairs].MoMoMoffset = offset;
100 int32_t komodo_MoMoMdata(char *hexstr,int32_t hexsize,struct komodo_ccdataMoMoM *mdata,char *symbol,int32_t kmdheight,int32_t notarized_height)
102 uint8_t hexdata[8192]; struct komodo_ccdata *ccdata,*tmpptr; int32_t len,maxpairs,i,retval=-1,depth,starti,endi,CCid=0; struct komodo_ccdata_entry *allMoMs;
103 starti = endi = depth = len = maxpairs = 0;
105 if ( sizeof(hexdata)*2+1 > hexsize )
107 fprintf(stderr,"hexsize.%d too small for %d\n",hexsize,(int32_t)sizeof(hexdata));
110 memset(mdata,0,sizeof(*mdata));
111 portable_mutex_lock(&KOMODO_CC_mutex);
112 DL_FOREACH_SAFE(CC_data,ccdata,tmpptr)
114 if ( ccdata->MoMdata.height < kmdheight )
116 //fprintf(stderr,"%s notarized.%d kmd.%d\n",ccdata->symbol,ccdata->MoMdata.notarized_height,ccdata->MoMdata.height);
117 if ( strcmp(ccdata->symbol,symbol) == 0 )
121 endi = ccdata->MoMdata.height;
124 if ( (mdata->numpairs == 1 && notarized_height == 0) || ccdata->MoMdata.notarized_height <= notarized_height )
126 starti = ccdata->MoMdata.height + 1;
127 if ( notarized_height == 0 )
128 notarized_height = ccdata->MoMdata.notarized_height;
132 starti = ccdata->MoMdata.height;
135 portable_mutex_unlock(&KOMODO_CC_mutex);
136 mdata->kmdstarti = starti;
137 mdata->kmdendi = endi;
138 if ( starti != 0 && endi != 0 && endi >= starti )
140 if ( (allMoMs= komodo_allMoMs(&depth,&mdata->MoMoM,starti,endi)) != 0 )
142 mdata->MoMoMdepth = depth;
143 for (i=0; i<depth; i++)
145 if ( strcmp(symbol,allMoMs[i].symbol) == 0 )
146 maxpairs = komodo_addpair(mdata,allMoMs[i].notarized_height,i,maxpairs);
148 if ( mdata->numpairs > 0 )
150 len += iguana_rwnum(1,&hexdata[len],sizeof(CCid),(uint8_t *)&CCid);
151 len += iguana_rwnum(1,&hexdata[len],sizeof(uint32_t),(uint8_t *)&mdata->kmdstarti);
152 len += iguana_rwnum(1,&hexdata[len],sizeof(uint32_t),(uint8_t *)&mdata->kmdendi);
153 len += iguana_rwbignum(1,&hexdata[len],sizeof(mdata->MoMoM),(uint8_t *)&mdata->MoMoM);
154 len += iguana_rwnum(1,&hexdata[len],sizeof(uint32_t),(uint8_t *)&mdata->MoMoMdepth);
155 len += iguana_rwnum(1,&hexdata[len],sizeof(uint32_t),(uint8_t *)&mdata->numpairs);
156 for (i=0; i<mdata->numpairs; i++)
158 if ( len + sizeof(uint32_t)*2 > sizeof(hexdata) )
160 fprintf(stderr,"%s %d %d i.%d of %d exceeds hexdata.%d\n",symbol,kmdheight,notarized_height,i,mdata->numpairs,(int32_t)sizeof(hexdata));
163 len += iguana_rwnum(1,&hexdata[len],sizeof(uint32_t),(uint8_t *)&mdata->pairs[i].notarized_height);
164 len += iguana_rwnum(1,&hexdata[len],sizeof(uint32_t),(uint8_t *)&mdata->pairs[i].MoMoMoffset);
166 if ( i == mdata->numpairs && len*2+1 < hexsize )
168 init_hexbytes_noT(hexstr,hexdata,len);
169 //fprintf(stderr,"hexstr.(%s)\n",hexstr);
171 } else fprintf(stderr,"%s %d %d too much hexdata[%d] for hexstr[%d]\n",symbol,kmdheight,notarized_height,len,hexsize);
179 void komodo_purge_ccdata(int32_t height)
181 struct komodo_ccdata *ccdata,*tmpptr;
182 if ( ASSETCHAINS_SYMBOL[0] == 0 )
184 portable_mutex_lock(&KOMODO_CC_mutex);
185 DL_FOREACH_SAFE(CC_data,ccdata,tmpptr)
187 if ( ccdata->MoMdata.height >= height )
189 printf("PURGE %s notarized.%d\n",ccdata->symbol,ccdata->MoMdata.notarized_height);
190 DL_DELETE(CC_data,ccdata);
194 portable_mutex_unlock(&KOMODO_CC_mutex);
198 // purge notarized data
202 // this is just a demo of ccdata processing to create example data for the MoMoM and allMoMs calls
203 int32_t komodo_rwccdata(char *thischain,int32_t rwflag,struct komodo_ccdata *ccdata,struct komodo_ccdataMoMoM *MoMoMdata)
205 uint256 hash,zero; bits256 tmp; int32_t i,nonz; struct komodo_ccdata *ptr; struct notarized_checkpoint *np;
206 return(0); // disable this path as libscott method is much better
215 if ( ccdata->MoMdata.height > 0 && (CC_firstheight == 0 || ccdata->MoMdata.height < CC_firstheight) )
216 CC_firstheight = ccdata->MoMdata.height;
217 for (nonz=i=0; i<32; i++)
219 if ( (tmp.bytes[i]= ((uint8_t *)&ccdata->MoMdata.MoM)[31-i]) != 0 )
224 memcpy(&hash,&tmp,sizeof(hash));
225 //fprintf(stderr,"[%s] ccdata.%s id.%d notarized_ht.%d MoM.%s height.%d/t%d\n",ASSETCHAINS_SYMBOL,ccdata->symbol,ccdata->CCid,ccdata->MoMdata.notarized_height,hash.ToString().c_str(),ccdata->MoMdata.height,ccdata->MoMdata.txi);
226 if ( ASSETCHAINS_SYMBOL[0] == 0 )
228 if ( CC_data != 0 && (CC_data->MoMdata.height > ccdata->MoMdata.height || (CC_data->MoMdata.height == ccdata->MoMdata.height && CC_data->MoMdata.txi >= ccdata->MoMdata.txi)) )
230 printf("out of order detected? SKIP CC_data ht.%d/txi.%d vs ht.%d/txi.%d\n",CC_data->MoMdata.height,CC_data->MoMdata.txi,ccdata->MoMdata.height,ccdata->MoMdata.txi);
234 ptr = (struct komodo_ccdata *)calloc(1,sizeof(*ptr));
236 portable_mutex_lock(&KOMODO_CC_mutex);
237 DL_PREPEND(CC_data,ptr);
238 portable_mutex_unlock(&KOMODO_CC_mutex);
243 if ( MoMoMdata != 0 && MoMoMdata->pairs != 0 )
245 for (i=0; i<MoMoMdata->numpairs; i++)
247 if ( (np= komodo_npptr(MoMoMdata->pairs[i].notarized_height)) != 0 )
249 memset(&zero,0,sizeof(zero));
250 if ( memcmp(&np->MoMoM,&zero,sizeof(np->MoMoM)) == 0 )
252 np->MoMoM = MoMoMdata->MoMoM;
253 np->MoMoMdepth = MoMoMdata->MoMoMdepth;
254 np->MoMoMoffset = MoMoMdata->MoMoMoffset;
255 np->kmdstarti = MoMoMdata->kmdstarti;
256 np->kmdendi = MoMoMdata->kmdendi;
258 else if ( memcmp(&np->MoMoM,&MoMoMdata->MoMoM,sizeof(np->MoMoM)) != 0 || np->MoMoMdepth != MoMoMdata->MoMoMdepth || np->MoMoMoffset != MoMoMdata->MoMoMoffset || np->kmdstarti != MoMoMdata->kmdstarti || np->kmdendi != MoMoMdata->kmdendi )
260 fprintf(stderr,"preexisting MoMoM mismatch: %s (%d %d %d %d) vs %s (%d %d %d %d)\n",np->MoMoM.ToString().c_str(),np->MoMoMdepth,np->MoMoMoffset,np->kmdstarti,np->kmdendi,MoMoMdata->MoMoM.ToString().c_str(),MoMoMdata->MoMoMdepth,MoMoMdata->MoMoMoffset,MoMoMdata->kmdstarti,MoMoMdata->kmdendi);