You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

199 lines
9.9 KiB

9 years ago
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#include "iguana777.h"
int64_t iguana_packetsallocated(struct iguana_info *coin) { return(coin->R.packetsallocated - coin->R.packetsfreed); };
uint8_t *iguana_decompress(struct iguana_info *coin,int32_t height,int32_t *datalenp,uint8_t *bits,int32_t numbits,int32_t origdatalen)
{
uint32_t hdrlen,checklen;
memcpy(&hdrlen,bits,sizeof(hdrlen));
bits = &bits[sizeof(hdrlen)];
*datalenp = 0;
if ( (hdrlen & (1 << 31)) != 0 )
{
hdrlen ^= (1 << 31);
if ( (hdrlen >> 3) == origdatalen )
{
*datalenp = origdatalen;
return(bits);
} else printf("\n>>>>>>>>> iguana_decompress.%d numbits.%d %d != origlen.%d\n",height,hdrlen,hdrlen>>3,origdatalen), getchar();
}
else if ( hconv_bitlen(hdrlen) == hconv_bitlen(numbits) )
{
if ( (checklen= ramcoder_decompress(coin->R.decompressed,sizeof(coin->R.decompressed),bits,hdrlen,bits256_zero)) == origdatalen )
{
//printf("DECOMPRESSED %d to %d\n",hconv_bitlen(hdrlen),checklen);
*datalenp = origdatalen;
return(coin->R.decompressed);
}
else
{
printf("\n>>>>>>>>> iguana_decompress.%d hdrlen.%d checklen.%d != origdatalen.%d\n",height,hdrlen,checklen,origdatalen);
int32_t j;
for (j=0; j<hconv_bitlen(numbits); j++)
printf("%02x ",bits[j]);
printf("compressed.%d\n",numbits/8);
getchar();
}
}
else
{
printf("\n>>>>>>>>>> iguana_decompress.%d hdrlen.%d != numbits.%d\n",height,hdrlen,numbits);
int32_t j;
for (j=0; j<=numbits/8; j++)
printf("%02x ",bits[j]);
printf("compressed.%d\n",numbits/8);
getchar();
}
return(0);
}
/*struct iguana_msgtx *iguana_validpending(struct iguana_info *coin,struct iguana_pending *ptr,struct iguana_block *space)
{
struct iguana_block *checkblock; uint8_t *data; int32_t datalen,len; struct iguana_msgtx *tx = 0;
*space = ptr->block;
if ( coin->R.recvblocks == 0 || ptr->block.height >= coin->R.numwaitingbits )
{
printf("illegal pending height.%d vs %d\n",ptr->block.height,coin->R.numwaitingbits);
return(0);
}
if ( ptr->origdatalen > 0 && ptr->block.height < coin->longestchain && ptr->block.height < coin->blocks.hwmheight )
{
if ( (checkblock= iguana_block(coin,space,ptr->block.height)) != 0 )
{
if ( iguana_blockcmp(coin,checkblock,space,1) == 0 )
{
data = iguana_decompress(coin,ptr->block.height,&datalen,ptr->data,ptr->datalen << 3,ptr->origdatalen);
//printf("parsed.%d vs max.%d height.%d data.%p\n",coin->blocks.parsedblocks,coin->R.numwaitingbits,ptr->block.height,data);
if ( data != 0 && iguana_setdependencies(coin,space) == ptr->block.height )
{
if ( (tx= iguana_gentxarray(coin,&len,space,data,datalen)) != 0 && len == datalen )
return(tx);
} else printf("iguana_validpending: error gentx block.%d\n",coin->blocks.parsedblocks);
} else printf("iguana_validpending: error setting vars block.%d\n",ptr->block.height);
if ( tx != 0 )
iguana_freetx(tx,ptr->numtx);
} else printf("iguana_validpending cant get checkblock %d vs hwmheight.%d\n",ptr->block.height,coin->blocks.hwmheight);
}
return(0);
}*/
/*int32_t iguana_processrecv(struct iguana_info *coin)
{
int32_t height; struct iguana_block space; struct iguana_msgtx *tx = 0;
struct iguana_pending *ptr = 0; int32_t retval = -1;
height = coin->blocks.parsedblocks;
if ( coin->R.recvblocks != 0 && height < coin->R.numwaitingbits )
{
if ( (ptr= coin->R.recvblocks[height]) != 0 )
{
//printf("iguana_processrecv height.%d %p\n",height,ptr);
coin->R.recvblocks[height] = 0;
if ( (tx= iguana_validpending(coin,ptr,&space)) != 0 )
{
retval = iguana_parseblock(coin,&space,tx,ptr->numtx);
if ( space.L.numunspents+space.numvouts != coin->latest.dep.numunspents )
printf("block->firstvout+block->numvouts (%d+%d) != %d coin->latest.deps.numunspentinds\n",space.L.numunspents,space.numvouts,coin->latest.dep.numunspents), getchar();
if ( retval < 0 )
printf("iguana_processrecv: error parsing block.%d tx.%p\n",ptr->block.height,tx);
if ( tx != 0 )
iguana_freetx(tx,ptr->numtx);
} else printf("error getting pending %d %p\n",height,ptr);
if ( coin->R.maprecvdata == 0 )
{
coin->R.packetsfreed += ptr->allocsize;
myfree(ptr,ptr->allocsize);
}
}
else if ( time(NULL) > coin->parsetime+1 )
{
coin->parsetime = (uint32_t)time(NULL);
printf("backstop.%d %s\n",height,bits256_str(iguana_blockhash(coin,height)));
bits256 hash2 = iguana_blockhash(coin,height);
iguana_request_data(coin,coin->peers.ranked[0],&hash2,1,MSG_BLOCK,1);
iguana_waitclear(coin,height);
iguana_waitstart(coin,height);
iguana_updatewaiting(coin,height+1,100);
}
} else printf("processrecv: no recvbits!\n");
return(retval);
}
int32_t iguana_recvblock(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_block *block,struct iguana_msgtx *tx,int32_t numtx,uint8_t *data,int32_t origdatalen)
{
struct iguana_pending *ptr; int32_t allocsize,checklen,numbits; uint32_t datalen,hdrlen;
if ( coin->R.recvblocks == 0 || coin->R.recvblocks[block->height] != 0 )
{
coin->sleeptime++;
if ( coin->sleeptime > 10000 )
coin->sleeptime = 10000;
if ( 0 && addr != coin->peers.localaddr )
printf("%s recv duplicate at height.%d sleepmillis %.3f\n",addr->ipaddr,block->height,(double)coin->sleeptime/1000.); // add validation/merging
}
else
{
coin->sleeptime *= .995;
if ( coin->sleeptime < 1000 )
coin->sleeptime = 1000;
// validate block here
datalen = origdatalen;
hdrlen = (1 << 31) | (datalen << 3);
coin->R.srcdatalen += datalen;
if ( 0 && (numbits= ramcoder_compress(coin->R.compressed,sizeof(coin->R.compressed),data,datalen,coin->R.histo,bits256_zero)) > 0 )
{
memset(coin->R.checkbuf,0,datalen);
if ( (checklen= ramcoder_decompress(coin->R.checkbuf,sizeof(coin->R.checkbuf),coin->R.compressed,numbits,bits256_zero)) == datalen )
{
if ( memcmp(coin->R.checkbuf,data,datalen) == 0 )
{
hdrlen = numbits;
data = coin->R.compressed;
printf("height.%d datalen.%d -> numbits.%d %d compression ratio %.3f [%.4f]\n",block->height,datalen,numbits,hconv_bitlen(numbits),(double)datalen/hconv_bitlen(numbits),(double)coin->R.srcdatalen/(coin->R.compressedtotal+hconv_bitlen(numbits)+sizeof(hdrlen)));
datalen = hconv_bitlen(numbits);
} else printf("ramcoder data datalen.%d compare error\n",datalen), getchar();
}
else printf("ramcoder codec error origdatalen.%d numbits.%d datalen. %d -> %d\n",origdatalen,numbits,datalen,checklen), getchar();
} //else printf("ramcoder compress error %d -> numbits.%d\n",datalen,numbits), getchar();
coin->R.compressedtotal += (datalen + sizeof(hdrlen));
allocsize = (int32_t)(sizeof(*ptr) + datalen + sizeof(hdrlen));
if ( coin->R.maprecvdata != 0 )
{
ptr = iguana_tmpalloc(coin,"recv",&coin->R.RSPACE,allocsize);
if ( block->height > coin->R.RSPACE.maxheight )
coin->R.RSPACE.maxheight = block->height;
ptr->next = (int32_t)((long)iguana_tmpalloc(coin,"recv",&coin->R.RSPACE,0) - (long)ptr);
}
else
{
ptr = mycalloc('P',1,allocsize);
coin->R.packetsallocated += allocsize;
}
ptr->allocsize = allocsize;
ptr->datalen = datalen;
memcpy(ptr->data,&hdrlen,sizeof(hdrlen));
memcpy(&ptr->data[sizeof(hdrlen)],data,datalen);
ptr->ipbits = addr != 0 ? addr->ipbits : 0;
ptr->block = *block;
ptr->numtx = numtx;
ptr->origdatalen = origdatalen;
if ( (rand() % 1000) == 0 )
printf("%s recv.%d ptr.%p datalen.%d orig.%d %.3f | parsed.%d hwm.%d longest.%d | %d/%d elapsed %.2f\n",addr != 0 ? addr->ipaddr : "local",block->height,ptr,datalen,origdatalen,(double)origdatalen/datalen,coin->blocks.parsedblocks,coin->blocks.hwmheight,coin->longestchain,iguana_updatewaiting(coin,coin->blocks.parsedblocks,coin->width*10),coin->width*10,(double)(time(NULL)-coin->starttime)/60.);
coin->R.recvblocks[block->height] = ptr;
}
return(0);
}*/