diff --git a/iguana/iguana777.h b/iguana/iguana777.h index 54b7758cf..a41935219 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -1074,6 +1074,10 @@ void calc_scrypthash(uint32_t *hash,void *data); int32_t iguana_rwvarstr(int32_t rwflag,uint8_t *serialized,int32_t maxlen,char *endianedp); bits256 bitcoin_sharedsecret(void *ctx,bits256 privkey,uint8_t *pubkey,int32_t plen); int32_t iguana_blockhdrsize(char *symbol,uint8_t zcash,uint8_t auxpow);//,uint8_t *serialized,int32_t maxlen); +int32_t iguana_blockROsize(uint8_t zcash); +void *iguana_blockzcopyRO(uint8_t zcash,struct iguana_blockRO *dest,int32_t desti,struct iguana_blockRO *src,int32_t srci); +void iguana_blockzcopy(uint8_t zcash,struct iguana_block *dest,struct iguana_block *src); +int32_t iguana_blocksizecheck(char *debugstr,uint8_t zcash,struct iguana_block *block); extern int32_t HDRnet,netBLOCKS; diff --git a/iguana/iguana_blocks.c b/iguana/iguana_blocks.c index 3bcc536c6..21b98a07b 100755 --- a/iguana/iguana_blocks.c +++ b/iguana/iguana_blocks.c @@ -96,7 +96,9 @@ void iguana_blockcopy(uint8_t zcash,uint8_t auxpow,struct iguana_info *coin,stru } else { - if ( block->RO.allocsize != origblock->RO.allocsize || block->RO.allocsize != sizeof(*block) + sizeof(*block->zRO) ) + iguana_blocksizecheck("blockcopy dest",coin->chain->zcash,block); + iguana_blocksizecheck("blockcopy src",coin->chain->zcash,origblock); + if ( block->RO.allocsize != origblock->RO.allocsize ) printf("missing space for zcash block.%d origblock.%d\n",block->RO.allocsize,origblock->RO.allocsize); else { @@ -210,6 +212,7 @@ struct iguana_block *iguana_blockhashset(char *debugstr,struct iguana_info *coin block = calloc(1,size); block->RO.hash2 = hash2; block->RO.allocsize = size; + iguana_blocksizecheck("blockhashset",coin->chain->zcash,block); block->hh.itemind = height, block->height = -1; HASH_ADD(hh,coin->blocks.hash,RO.hash2,sizeof(hash2),block); block->hh.next = block->hh.prev = 0; @@ -277,6 +280,50 @@ struct iguana_block *iguana_blockptr(char *debugstr,struct iguana_info *coin,int return(0); } +int32_t iguana_blocksizecheck(char *debugstr,uint8_t zcash,struct iguana_block *block) +{ + int32_t bsize = zcash != 0 ? sizeof(struct iguana_zblock) : sizeof(struct iguana_block); + if ( block->RO.allocsize != bsize ) + { + if ( block->RO.allocsize == 0 || block->RO.allocsize < bsize ) + { + printf("%s block validate warning: mismatched size %d vs %d\n",debugstr,block->RO.allocsize,bsize); + block->RO.allocsize = bsize; + } else return(-1); + return(bsize); + } + return(0); +} + +int32_t iguana_blockROsize(uint8_t zcash) +{ + return((int32_t)(sizeof(struct iguana_blockRO) + zcash*sizeof(struct iguana_msgblockhdr_zcash))); +} + +void *iguana_blockzcopyRO(uint8_t zcash,struct iguana_blockRO *dest,int32_t desti,struct iguana_blockRO *src,int32_t srci) +{ + int32_t bROsize = iguana_blockROsize(zcash); + dest = (void *)((long)dest + desti*bROsize); + src = (void *)((long)src + srci*bROsize); + memcpy(dest,src,bROsize); + return(src); +} + +void iguana_blockzcopy(uint8_t zcash,struct iguana_block *dest,struct iguana_block *src) +{ + iguana_blocksizecheck("blockcopy dest",zcash,dest); + iguana_blocksizecheck("blockcopy src",zcash,src); + if ( zcash == 0 ) + *dest = *src; + else + { + if ( src->RO.allocsize != sizeof(struct iguana_zblock) ) + printf("warning: iguana_blockcopy src size %d vs %d\n",src->RO.allocsize,(int32_t)sizeof(struct iguana_zblock)); + *(struct iguana_zblock *)dest = *(struct iguana_zblock *)src; + dest->RO.allocsize = sizeof(struct iguana_zblock); + } +} + int32_t iguana_blockvalidate(struct iguana_info *coin,int32_t *validp,struct iguana_block *block,int32_t dispflag) { bits256 hash2; uint8_t serialized[sizeof(struct iguana_msgblock) + 4096]; @@ -284,8 +331,7 @@ int32_t iguana_blockvalidate(struct iguana_info *coin,int32_t *validp,struct igu iguana_serialize_block(coin->chain,&hash2,serialized,block); *validp = (memcmp(hash2.bytes,block->RO.hash2.bytes,sizeof(hash2)) == 0); block->valid = *validp; - if ( block->RO.allocsize == 0 ) - block->RO.allocsize = coin->chain->zcash != 0 ? sizeof(*block) : sizeof(struct iguana_zblock); + iguana_blocksizecheck("blockvalidate",coin->chain->zcash,block); char str[65]; char str2[65]; if ( *validp == 0 ) { @@ -387,6 +433,7 @@ int32_t iguana_walkchain(struct iguana_info *coin,int32_t skipflag) } else if ( block->height >= 0 && block->height != height ) printf("walkchain height mismatch %d vs %d\n",block->height,height); + iguana_blocksizecheck("walkchain",coin->chain->zcash,block); if ( bits256_nonz(iguana_blockhash(coin,height)) != 0 && bits256_cmp(iguana_blockhash(coin,height),block->RO.hash2) != 0 ) { printf("walk error blockhash error at %d %s\n",height,bits256_str(str,iguana_blockhash(coin,height))); @@ -451,7 +498,6 @@ struct iguana_block *iguana_fastlink(struct iguana_info *coin,int32_t hwmheight) coin->blocks.maxblocks = (block->height + 1); if ( coin->blocks.maxblocks > coin->longestchain ) coin->longestchain = coin->blocks.maxblocks; - memcpy(&coin->blocks.hwmchain,block,block->RO.allocsize); block->valid = block->mainchain = 1; block->hdrsi = hdrsi, block->bundlei = bundlei; block->height = height; @@ -487,15 +533,13 @@ struct iguana_block *_iguana_chainlink(struct iguana_info *coin,struct iguana_bl bits256 *hash2p=0; double prevPoW = 0.; struct iguana_bundle *bp; if ( newblock == 0 ) return(0); - if ( newblock->RO.allocsize == 0 ) - newblock->RO.allocsize = coin->chain->zcash != 0 ? sizeof(*newblock) : sizeof(struct iguana_zblock); + iguana_blocksizecheck("chainlink new",coin->chain->zcash,newblock); hwmchain = (struct iguana_block *)&coin->blocks.hwmchain; if ( 0 && hwmchain->height > 0 && ((bp= coin->current) == 0 || hwmchain->height/coin->chain->bundlesize > bp->hdrsi+0*bp->isRT) ) return(0); if ( (block= iguana_blockfind("chainlink",coin,newblock->RO.hash2)) != 0 ) { - if ( block->RO.allocsize == 0 ) - block->RO.allocsize = coin->chain->zcash != 0 ? sizeof(*newblock) : sizeof(struct iguana_zblock); + iguana_blocksizecheck("chainlink",coin->chain->zcash,block); if ( memcmp(coin->chain->genesis_hashdata,block->RO.hash2.bytes,sizeof(bits256)) == 0 ) block->PoW = PoW_from_compact(block->RO.bits,coin->chain->unitval), height = 0; else if ( (prev= iguana_blockfind("chainprev",coin,block->RO.prev_block)) != 0 ) diff --git a/iguana/iguana_init.c b/iguana/iguana_init.c index 4871e415d..cfb53143e 100755 --- a/iguana/iguana_init.c +++ b/iguana/iguana_init.c @@ -86,7 +86,7 @@ bits256 iguana_genesis(struct iguana_info *coin,struct iguana_chain *chain) struct iguana_block *block,*ptr; struct iguana_msgblock msg; bits256 hash2; char str[65],str2[65]; uint8_t buf[8192],blockspace[sizeof(*block)+sizeof(*block->zRO)]; int32_t height,auxback; block = (void *)blockspace; memset(block,0,sizeof(blockspace)); - block->RO.allocsize = (int32_t)(sizeof(*block) + coin->chain->zcash*sizeof(*block->zRO)); + iguana_blocksizecheck("genesis",coin->chain->zcash,block); if ( chain->genesis_hex == 0 ) { printf("no genesis_hex for %s\n",coin->symbol); @@ -117,12 +117,13 @@ bits256 iguana_genesis(struct iguana_info *coin,struct iguana_chain *chain) if ( (ptr= iguana_blockhashset("genesis0",coin,0,hash2,1)) != 0 ) { iguana_blockcopy(coin->chain->zcash,coin->chain->auxpow,coin,ptr,block); + iguana_blocksizecheck("genesis ptr",coin->chain->zcash,ptr); ptr->mainchain = 1; ptr->height = 0; //coin->blocks.RO[0] = block.RO; if ( (height= iguana_chainextend(coin,ptr)) == 0 ) { - memcpy(block,ptr,block->RO.allocsize); + iguana_blockzcopy(coin->chain->zcash,block,ptr); printf("size.%d genesis block PoW %f ptr %f\n",block->RO.allocsize,block->PoW,ptr->PoW); coin->blocks.recvblocks = coin->blocks.issuedblocks = 1; } diff --git a/iguana/iguana_msg.c b/iguana/iguana_msg.c index 9022276fe..c4d77f290 100755 --- a/iguana/iguana_msg.c +++ b/iguana/iguana_msg.c @@ -217,7 +217,7 @@ int32_t iguana_serialize_block(struct iguana_chain *chain,bits256 *hash2p,uint8_ msg.H.nonce = block->RO.nonce; else { - if ( block->RO.allocsize == sizeof(*block)+sizeof(*block->zRO) ) + if ( block->RO.allocsize == sizeof(struct iguana_zblock) ) { msg.zH.bignonce = block->zRO[0].bignonce; msg.zH.numelements = ZCASH_SOLUTION_ELEMENTS; diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index d871b58e6..7844c4dc8 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -788,7 +788,7 @@ int32_t iguana_ramchain_prefetch(struct iguana_info *coin,struct iguana_ramchain int64_t _iguana_rdata_action(char *fname,FILE *fp,bits256 lhashes[IGUANA_NUMLHASHES],void *destptr,uint64_t fpos,uint32_t expanded,uint32_t numtxids,uint32_t numunspents,uint32_t numspends,uint32_t numpkinds,uint32_t numexternaltxids,uint32_t scriptspace,uint32_t txsparsebits,uint64_t numtxsparse,uint32_t pksparsebits,uint64_t numpksparse,uint64_t srcsize,RAMCHAIN_FUNC,int32_t numblocks,uint8_t zcash) { #define RAMCHAIN_LARG(ind) ((lhashes == 0) ? 0 : lhashes[ind].bytes) - FILE *fparg = 0; int32_t bROsize,iter; uint64_t txbits,pkbits,offset = 0; struct iguana_ramchaindata *rdata = destptr; + FILE *fparg = 0; int32_t iter; uint64_t txbits,pkbits,offset = 0; struct iguana_ramchaindata *rdata = destptr; if ( expanded != 0 ) { if( txsparsebits == 0 || numtxsparse == 0 ) @@ -823,9 +823,8 @@ int64_t _iguana_rdata_action(char *fname,FILE *fp,bits256 lhashes[IGUANA_NUMLHAS continue; } offset = sizeof(struct iguana_ramchaindata); - bROsize = (int32_t)(sizeof(struct iguana_blockRO) + zcash*sizeof(struct iguana_msgblockhdr_zcash)); //printf("bROsize.%d\n",bROsize); - B = iguana_ramchain_offset(fname,rdata,RAMCHAIN_LARG(IGUANA_LHASH_BLOCKS),fparg,fpos,B,&offset,(bROsize * numblocks),srcsize); + B = iguana_ramchain_offset(fname,rdata,RAMCHAIN_LARG(IGUANA_LHASH_BLOCKS),fparg,fpos,B,&offset,(iguana_blockROsize(zcash) * numblocks),srcsize); T = iguana_ramchain_offset(fname,rdata,RAMCHAIN_LARG(IGUANA_LHASH_TXIDS),fparg,fpos,T,&offset,(sizeof(struct iguana_txid) * numtxids),srcsize); if ( expanded != 0 ) { @@ -1473,18 +1472,19 @@ struct iguana_ramchain *_iguana_ramchain_map(struct iguana_info *coin,char *fnam } if ( B != 0 && bp != 0 ) { - int32_t bROsize = (int32_t)(sizeof(struct iguana_blockRO) + coin->chain->zcash*sizeof(struct iguana_msgblockhdr_zcash)); for (i=0; in; i++) { - bRO = (void *)((long)B + i*bROsize); if ( bp->blocks[i] == 0 && (bp->blocks[i]= iguana_blockhashset("mapchain",coin,-1,bRO->hash2,1)) == 0 ) { printf("Error getting blockptr\n"); return(0); } - memcpy(&bp->blocks[i]->RO,bRO,bROsize);//coin->blocks.RO[bp->bundleheight + i]; - //coin->blocks.RO[bp->bundleheight+i] = B[i]; - bp->hashes[i] = bRO->hash2; + if ( (bRO= iguana_blockzcopyRO(zcash,&bp->blocks[i]->RO,0,B,i)) != 0 ) + { + //memcpy(&bp->blocks[i]->RO,bRO,bROsize);//coin->blocks.RO[bp->bundleheight + i]; + //coin->blocks.RO[bp->bundleheight+i] = B[i]; + bp->hashes[i] = bRO->hash2; + } } } //printf("iguana_ramchain_map.(%s) size %ld vs %ld vs filesize.%ld numblocks.%d expanded.%d fpos.%d sum %ld\n",fname,(long)iguana_ramchain_size(RAMCHAIN_ARG,ramchain->numblocks,ramchain->H.data->scriptspace),(long)ramchain->H.data->allocsize,(long)filesize,ramchain->numblocks,expanded,(int32_t)fpos,(long)(fpos+ramchain->H.data->allocsize)); @@ -1945,8 +1945,7 @@ long iguana_ramchain_data(struct iguana_info *coin,struct iguana_peer *addr,stru { if ( (err= iguana_ramchain_verify(coin,ramchain)) == 0 ) { - int32_t bROsize = (int32_t)(sizeof(struct iguana_blockRO) + coin->chain->zcash*sizeof(struct iguana_msgblockhdr_zcash)); - memcpy(B,&block->RO,bROsize); + iguana_blockzcopyRO(coin->chain->zcash,B,0,&block->RO,0); ramchain->H.data->scriptspace = ramchain->H.scriptoffset = scriptspace; ramchain->H.data->stackspace = ramchain->H.stacksize = stackspace; if ( (fpos= (int32_t)iguana_ramchain_save(coin,RAMCHAIN_ARG,addr_ipbits,block->RO.hash2,block->RO.prev_block,bundlei,0,coin->chain->zcash)) >= 0 ) @@ -2293,10 +2292,9 @@ int32_t iguana_ramchain_expandedsave(struct iguana_info *coin,RAMCHAIN_FUNC,stru struct iguana_ramchain *iguana_bundleload(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct iguana_bundle *bp,int32_t extraflag) { static const bits256 zero; - struct iguana_blockRO *B; struct iguana_txid *T; int32_t i,bROsize,firsti = 1; char fname[512]; + struct iguana_blockRO *B; struct iguana_txid *T; int32_t i,firsti = 1; char fname[512]; struct iguana_block *block,*prev,*prev2; struct iguana_ramchain *mapchain; memset(ramchain,0,sizeof(*ramchain)); - bROsize = (int32_t)(sizeof(struct iguana_blockRO) + coin->chain->zcash*sizeof(struct iguana_msgblockhdr_zcash)); if ( (mapchain= iguana_ramchain_map(coin,fname,bp,bp->n,ramchain,0,0,bp->hashes[0],zero,0,0,extraflag,1)) != 0 ) { iguana_ramchain_link(mapchain,bp->hashes[0],bp->hdrsi,bp->bundleheight,0,bp->n,firsti,1); @@ -2320,12 +2318,10 @@ struct iguana_ramchain *iguana_bundleload(struct iguana_info *coin,struct iguana block->hdrsi = bp->hdrsi; block->bundlei = i; block->fpipbits = (uint32_t)calc_ipbits("127.0.0.1"); - memcpy(&block->RO,(void *)((long)B + i*bROsize),bROsize); + iguana_blockzcopyRO(coin->chain->zcash,&block->RO,0,B,i); //printf("%x ",(int32_t)B[i].hash2.ulongs[3]); iguana_hash2set(coin,"bundleload",bp,i,block->RO.hash2); bp->blocks[i] = block; - //if ( bits256_nonz(bp->hashes[i]) == 0 ) - // bp->hashes[i] = bRO->hash2; if ( (prev= block->hh.prev) != 0 ) prev2 = prev->hh.prev; if ( prev2 != 0 && prev != 0 && strcmp(coin->symbol,"BTCD") == 0 && bp->bundleheight > 20000 && prev != 0 && iguana_targetbits(coin,block,prev,prev2,1,coin->chain->targetspacing,coin->chain->targettimespan) != block->RO.bits ) @@ -2453,7 +2449,7 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str RAMCHAIN_DESTDECLARE; RAMCHAIN_DECLARE; RAMCHAIN_ZEROES; void **ptrs; long *filesizes; uint32_t *ipbits; char fname[1024]; struct iguana_ramchain *R,*mapchain,*dest,newchain; uint32_t fpipbits; bits256 prevhash2; - int32_t i,starti,bROsize,endi,bp_n,numtxids,valid,sigspace,pubkeyspace,numunspents,numspends,numpkinds,numexternaltxids,scriptspace; struct iguana_block *block; long fpos; + int32_t i,starti,endi,bp_n,numtxids,valid,sigspace,pubkeyspace,numunspents,numspends,numpkinds,numexternaltxids,scriptspace; struct iguana_block *block; long fpos; struct OS_memspace HASHMEM; int32_t err,j,num,hdrsi,bundlei,firsti= 1,retval = -1; memset(&HASHMEM,0,sizeof(HASHMEM)); starti = 0, endi = bp->n - 1; @@ -2544,7 +2540,6 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str dest->H.scriptoffset = 1; _iguana_ramchain_setptrs(RAMCHAIN_DESTPTRS,dest->H.data); iguana_ramchain_extras(coin,dest,&HASHMEM,0); - bROsize = (int32_t)(sizeof(struct iguana_blockRO) + coin->chain->zcash*sizeof(struct iguana_msgblockhdr_zcash)); for (i=starti; i<=endi; i++) { if ( coin->active == 0 ) @@ -2563,8 +2558,8 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str iguana_blockunmark(coin,block,bp,i,1); return(-1); } - destB[i] = block->RO; - //memcpy((void *)((long)destB + i*bROsize),&block->RO,bROsize); + iguana_blockzcopyRO(coin->chain->zcash,destB,i,&block->RO,0); + //destB[i] = block->RO; } else printf("error getting block (%d:%d) %p vs %p\n",bp->hdrsi,i,block,bp->blocks[i]); } dest->H.txidind = dest->H.unspentind = dest->H.spendind = dest->pkind = dest->H.data->firsti; @@ -2578,7 +2573,7 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str { iguana_blocksetcounters(coin,block,dest); //coin->blocks.RO[bp->bundleheight+bundlei] = block->RO; - memcpy((void *)((long)destB + bundlei*bROsize),&block->RO,bROsize);//[bundlei] = block->RO; + iguana_blockzcopyRO(coin->chain->zcash,destB,bundlei,&block->RO,0); //destB[bundlei] = block->RO; //fprintf(stderr,"(%d %d).%d ",R[bundlei].H.data->numtxids,dest->H.txidind,bundlei); if ( (err= iguana_ramchain_iterate(coin,dest,&R[bundlei],bp,bundlei)) != 0 ) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 0ddc85e4e..d66b238a1 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -327,6 +327,7 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i } } } + origtxdata->zblock.RO.allocsize = sizeof(origtxdata->zblock); if ( iguana_blockvalidate(coin,&valid,(struct iguana_block *)&origtxdata->zblock,1) < 0 ) { printf("got block that doesnt validate? %s\n",bits256_str(str,origtxdata->zblock.RO.hash2)); @@ -804,11 +805,6 @@ struct iguana_bundlereq *iguana_recvblockhdrs(struct iguana_info *coin,struct ig { //fprintf(stderr,"i.%d of %d bundleset\n",i,n); bp = 0, bundlei = -1; - /*src = (void *)((long)blocks + bsize*i); - memset(&zblock,0,sizeof(zblock)); - zblock.RO.allocsize = sizeof(zblock); - iguana_blockconv(coin->chain->zcash,coin->chain->auxpow,(struct iguana_block *)&zblock,src,zblock.RO.hash2,zblock.height); - iguana_serialize_block(coin->chain,&zblock.RO.hash2,serialized,(struct iguana_block *)&zblock);*/ if ( i > 0 && bits256_cmp(prevhash2,zblocks[i].RO.prev_block) == 0 ) { if ( (bp= iguana_bundleset(coin,&block,&bundlei,(struct iguana_block *)&zblocks[i])) != 0 ) @@ -852,10 +848,6 @@ struct iguana_bundlereq *iguana_recvblockhdrs(struct iguana_info *coin,struct ig addr->RThashes[i] = firstbp->hashes[0]; for (i=1; ichain->zcash,coin->chain->auxpow,(struct iguana_block *)&zblock,src,zblock.RO.hash2,zblock.height);*/ iguana_serialize_block(coin->chain,&addr->RThashes[i],serialized,(struct iguana_block *)&zblocks[i]); } //memcpy(addr->RThashes,blockhashes,bp->numspec * sizeof(*addr->RThashes)); diff --git a/iguana/iguana_spendvectors.c b/iguana/iguana_spendvectors.c index 7e081171c..46d1afafa 100755 --- a/iguana/iguana_spendvectors.c +++ b/iguana/iguana_spendvectors.c @@ -696,7 +696,7 @@ int32_t iguana_volatilesinit(struct iguana_info *coin) //char str[65]; //printf("set hwmchain.%d <- %s %p\n",bp->bundleheight+bp->n-1,bits256_str(str,bp->hashes[bp->n-1]),block); if ( block->height > coin->blocks.hwmchain.height ) - memcpy(&coin->blocks.hwmchain,block,block->RO.allocsize); + iguana_blockzcopy(coin->chain->zcash,(void *)&coin->blocks.hwmchain,block); } //printf("end volatilesinit\n"); if ( iguana_fastfindinit(coin) == 0 )//&& coin->PREFETCHLAG >= 0 ) diff --git a/iguana/iguana_tx.c b/iguana/iguana_tx.c index ae33648ec..7a7490e21 100755 --- a/iguana/iguana_tx.c +++ b/iguana/iguana_tx.c @@ -366,7 +366,7 @@ cJSON *iguana_blockjson(struct iguana_info *coin,struct iguana_block *block,int3 msg.H.merkle_root = block->RO.merkle_root; msg.H.timestamp = block->RO.timestamp; msg.H.bits = block->RO.bits; - if ( block->RO.allocsize == sizeof(*block)+sizeof(*block->zRO) ) + if ( block->RO.allocsize == sizeof(struct iguana_zblock) ) { msg.zH.bignonce = block->zRO[0].bignonce; msg.zH.numelements = ZCASH_SOLUTION_ELEMENTS;