@ -286,7 +286,7 @@ int32_t iguana_bundlehash2add(struct iguana_info *coin,struct iguana_block **blo
struct iguana_bundle * iguana_bundlecreate ( struct iguana_info * coin , int32_t * bundleip , int32_t bundleheight , bits256 bundlehash2 , bits256 allhash , int32_t issueflag )
{
char str [ 65 ] , dirname [ 1024 ] ; struct iguana_bundle * bp = 0 ;
char str [ 65 ] , dirname [ 1024 ] ; struct iguana_bundle * prevbp , * bp = 0 ;
if ( bits256_nonz ( bundlehash2 ) > 0 )
{
bits256_str ( str , bundlehash2 ) ;
@ -312,8 +312,14 @@ struct iguana_bundle *iguana_bundlecreate(struct iguana_info *coin,int32_t *bund
bp - > coin = coin ;
bp - > avetime = coin - > avetime * 2. ;
coin - > bundles [ bp - > hdrsi ] = bp ;
if ( bp - > hdrsi > 0 & & coin - > bundles [ bp - > hdrsi - 1 ] ! = 0 )
coin - > bundles [ bp - > hdrsi - 1 ] - > nextbp = bp ;
if ( bp - > hdrsi > 0 )
{
if ( ( prevbp = coin - > bundles [ bp - > hdrsi - 1 ] ) ! = 0 )
{
prevbp - > nextbp = bp ;
prevbp - > nextbundlehash2 = bundlehash2 ;
}
}
* bundleip = 0 ;
bits256_str ( str , bundlehash2 ) ;
sprintf ( dirname , " %s/%s/%d " , GLOBALTMPDIR , coin - > symbol , bp - > bundleheight ) , OS_ensure_directory ( dirname ) ;
@ -321,7 +327,7 @@ struct iguana_bundle *iguana_bundlecreate(struct iguana_info *coin,int32_t *bund
iguana_bundlehash2add ( coin , 0 , bp , 0 , bundlehash2 ) ;
if ( issueflag ! = 0 )
{
iguana_blockQ ( " bundlecreate " , coin , bp , 0 , bundlehash2 , 1 ) ;
iguana_blockQ ( " bundlecreate " , coin , bp , 0 , bundlehash2 , 0 ) ;
queue_enqueue ( " hdrsQ " , & coin - > hdrsQ , queueitem ( str ) , 1 ) ;
}
if ( bp - > hdrsi > = coin - > bundlescount )
@ -388,247 +394,158 @@ void iguana_bundlepurgefiles(struct iguana_info *coin,struct iguana_bundle *bp)
}
}
int32_t iguana_bundleissue ( struct iguana_info * coin , struct iguana_bundle * bp , int32_t max , int32_t timelimit )
uint8_t iguana_recentpeers ( struct iguana_info * coin , int32_t * capacityp , struct iguana_peer * peers [ ] )
{
int32_t i , j , k , peerid , doneflag , len , forceflag , saved , starti , lag , doneval , nonz , total = 0 , maxval , numpeers , laggard = 0 , flag = 0 , finished = 0 , peercounts [ IGUANA_MAXPEERS ] , donecounts [ IGUANA_MAXPEERS ] , priority , counter = 0 ;
struct iguana_peer * addr ; uint32_t now ; struct iguana_block * block ;
bits256 hashes [ 50 ] , hash2 ; uint8_t serialized [ sizeof ( hashes ) + 256 ] ;
if ( bp = = 0 )
return ( 0 ) ;
now = ( uint32_t ) time ( NULL ) ;
memset ( peercounts , 0 , sizeof ( peercounts ) ) ;
memset ( donecounts , 0 , sizeof ( donecounts ) ) ;
if ( coin - > current ! = 0 )
starti = coin - > current - > hdrsi ;
else starti = 0 ;
priority = ( bp - > hdrsi < starti + coin - > peers . numranked ) ;
if ( strcmp ( " BTC " , coin - > symbol ) = = 0 )
lag = 10 + ( bp - > hdrsi - starti ) ;
else lag = 3 + ( bp - > hdrsi - starti ) / 10 ;
if ( coin - > current ! = bp )
lag * = 3 ;
if ( ( numpeers = coin - > peers . numranked ) > 3 & & 0 ) //(bp->numhashes == bp->n || bp->speculative != 0) )//&& bp->currentflag < bp->n )
struct iguana_peer * addr ; uint8_t m ; int32_t capacity , i , n = coin - > peers . numranked ;
for ( i = m = capacity = 0 ; i < n & & m < 0xff ; i + + )
{
if ( ( addr = coin - > peers . ranked [ i ] ) ! = 0 & & addr - > dead = = 0 & & addr - > usock > = 0 & & addr - > msgcounts . verack ! = 0 & & addr - > pendblocks < coin - > MAXPENDINGREQUESTS )
{
if ( peers ! = 0 )
peers [ m ] = addr ;
m + + ;
capacity + = ( coin - > MAXPENDINGREQUESTS - addr - > pendblocks ) ;
}
}
* capacityp = capacity ;
return ( m ) ;
}
struct iguana_block * iguana_bundleblock ( struct iguana_info * coin , bits256 * hash2p , struct iguana_bundle * bp , int32_t i )
{
struct iguana_block * block = 0 ;
memset ( hash2p , 0 , sizeof ( * hash2p ) ) ;
if ( i = = bp - > n )
{
if ( bits256_nonz ( bp - > nextbundlehash2 ) ! = 0 )
block = iguana_blockfind ( coin , bp - > nextbundlehash2 ) ;
else return ( 0 ) ;
}
if ( block ! = 0 | | ( block = bp - > blocks [ i ] ) ! = 0 | | ( bits256_nonz ( bp - > hashes [ i ] ) ! = 0 & & ( block = iguana_blockfind ( coin , bp - > hashes [ i ] ) ) ! = 0 ) )
{
if ( numpeers > 0xff )
numpeers = 0xff ; // fit into 8 bitfield
if ( bp - > currentflag = = 0 )
bp - > currenttime = now ;
if ( bp - > numhashes > = 1 )
* hash2p = block - > RO . hash2 ;
return ( block ) ;
}
else if ( bp - > speculative ! = 0 & & bits256_nonz ( bp - > speculative [ i ] ) ! = 0 )
{
* hash2p = bp - > speculative [ i ] ;
block = iguana_blockfind ( coin , bp - > speculative [ i ] ) ;
//char str[65]; printf("[%d:%d] %s\n",bp->hdrsi,i,bits256_str(str,*hash2p));
}
return ( block ) ;
}
int32_t iguana_blocksmissing ( struct iguana_info * coin , int32_t * nonzp , uint8_t missings [ IGUANA_MAXBUNDLESIZE / 8 + 1 ] , bits256 hashes [ ] , struct iguana_bundle * bp , int32_t capacity , int32_t lag )
{
int32_t i , nonz = 0 , m = 0 ; bits256 hash2 ; struct iguana_block * block ; uint32_t now = ( uint32_t ) time ( NULL ) ;
memset ( missings , 0 , IGUANA_MAXBUNDLESIZE / 8 + 1 ) ;
if ( bp - > emitfinish = = 0 )
{
for ( i = 0 ; i < bp - > n ; i + + )
{
for ( j = 0 ; j < numpeers ; j + + )
if ( bp - > speculativecache [ i ] ! = 0 )
{
if ( ( addr = coin - > peers . ranked [ j ] ) ! = 0 & & addr - > dead = = 0 & & addr - > usock > = 0 & & addr - > msgcounts . verack ! = 0 )
{
now = ( uint32_t ) time ( NULL ) ;
for ( i = j , k = doneval = maxval = 0 ; i < bp - > n & & k < sizeof ( hashes ) / sizeof ( * hashes ) ; i + = numpeers )
{
doneflag = peerid = 0 ;
if ( bits256_nonz ( bp - > hashes [ i ] ) ! = 0 )
{
hash2 = bp - > hashes [ i ] ;
if ( ( block = bp - > blocks [ i ] ) ! = 0 )
{
if ( ( peerid = block - > peerid ) = = 0 )
{
//printf("<%d>.%d ",i,j);
if ( block - > fpipbits ! = 0 | | bp - > speculativecache [ i ] ! = 0 )
doneflag = 1 ;
}
}
}
else if ( bp - > speculative ! = 0 & & i < bp - > numspec & & bits256_nonz ( bp - > speculative [ i ] ) ! = 0 )
{
hash2 = bp - > speculative [ i ] ;
if ( bp - > speculativecache [ i ] ! = 0 )
doneflag = peerid = 1 ;
}
if ( doneflag = = 0 )
{
hashes [ k + + ] = hash2 ;
bp - > issued [ i ] = now ;
if ( block ! = 0 )
{
block - > issued = now ;
block - > peerid = j + 1 ;
block - > numrequests + + ;
}
}
else
{
doneflag = 1 ;
if ( block ! = 0 )
{
block - > peerid = 1 ;
block - > numrequests + + ;
}
}
if ( bits256_nonz ( hash2 ) ! = 0 )
{
if ( peerid > 1 )
{
total + + ;
if ( doneflag ! = 0 )
{
donecounts [ peerid - 1 ] + + ;
if ( donecounts [ peerid - 1 ] > doneval )
doneval = donecounts [ peerid - 1 ] ;
}
else
{
peercounts [ peerid - 1 ] + + ;
if ( peercounts [ peerid - 1 ] > maxval )
maxval = peercounts [ peerid - 1 ] ;
}
}
}
}
if ( k > 0 )
{
if ( ( len = iguana_getdata ( coin , serialized , MSG_BLOCK , hashes , k ) ) > 0 )
{
iguana_send ( coin , addr , serialized , len ) ;
counter + = k ;
coin - > numreqsent + = k ;
addr - > pendblocks + = k ;
addr - > pendtime = ( uint32_t ) time ( NULL ) ;
bp - > currentflag + = k ;
}
//printf("a%d/%d ",j,k);
}
}
//printf("[%d:%d].havec ",bp->hdrsi,i);
continue ;
}
//printf("doneval.%d maxval.%d\n",doneval,maxval);
if ( 0 & & priority ! = 0 )
if ( ( block = iguana_bundleblock ( coin , & hash2 , bp , i ) ) ! = 0 )
{
double threshold ;
for ( i = nonz = 0 ; i < numpeers ; i + + )
if ( donecounts [ i ] + peercounts [ i ] ! = 0 )
nonz + + ;
if ( nonz ! = 0 & & total ! = 0 )
if ( block - > txvalid ! = 0 )
{
threshold = ( ( double ) total / nonz ) - 1. ;
for ( i = laggard = finished = 0 ; i < numpeers ; i + + )
{
if ( peercounts [ i ] > threshold )
laggard + + ;
if ( peercounts [ i ] = = 0 & & donecounts [ i ] > threshold )
finished + + ;
}
if ( finished > laggard * 10 & & numpeers > 2 * laggard & & laggard > 0 )
{
for ( i = 0 ; i < numpeers ; i + + )
{
if ( peercounts [ i ] > threshold & & ( addr = coin - > peers . ranked [ i ] ) ! = 0 & & now > bp - > currenttime + lag & & addr - > dead = = 0 )
{
if ( ( numpeers > 64 | | addr - > laggard + + > 13 ) & & coin - > current = = bp )
{
addr - > dead = ( uint32_t ) time ( NULL ) ;
addr - > rank = 0 ;
}
for ( j = 0 ; j < bp - > n ; j + + )
{
if ( ( ( block = bp - > blocks [ j ] ) ! = 0 & & block - > peerid = = i & & block - > fpipbits = = 0 ) | | bp - > speculativecache [ i ] = = 0 )
{
if ( bp = = coin - > current )
printf ( " %d " , j ) ;
flag + + ;
counter + + ;
if ( block ! = 0 )
{
block - > issued = now ;
block - > peerid = 0 ;
iguana_blockQ ( " kick " , coin , bp , j , block - > RO . hash2 , 0 ) ; //bp == coin->current);
} else iguana_blockQ ( " kick " , coin , bp , j , block - > RO . hash2 , 0 ) ; //bp == coin->current);
if ( bp = = coin - > current )
bp - > issued [ i ] = now ;
}
}
if ( flag ! = 0 & & bp = = coin - > current )
printf ( " slow peer.%d dead.%u (%s) reissued.%d [%d] \n " , i , addr - > dead , addr - > ipaddr , flag , bp - > hdrsi ) ;
}
}
}
if ( 0 & & laggard ! = 0 )
{
for ( i = 0 ; i < numpeers ; i + + )
printf ( " %d " , peercounts [ i ] ) ;
printf ( " peercounts.%d: finished %d, laggards.%d threshold %f \n " , bp - > hdrsi , finished , laggard , threshold ) ;
}
//printf("[%d:%d].block ",bp->hdrsi,i);
continue ;
}
}
for ( i = 0 ; i < bp - > n ; i + + )
if ( bits256_nonz ( hash2 ) ! = 0 & & now > bp - > issued [ i ] + lag )
{
if ( 0 & & ( block = bp - > blocks [ i ] ) ! = 0 & & iguana_blockstatus ( coin , block ) = = 0 & & bp - > speculativecache [ i ] = = 0 )
{
if ( now > block - > issued + lag )
{
counter + + ;
saved = block - > issued ;
if ( bp = = coin - > current )
forceflag = ( now > block - > issued + lag ) ;
else forceflag = ( now > block - > issued + 10 * lag ) ;
if ( priority ! = 0 )
{
printf ( " kick.[%d:%d] " , bp - > hdrsi , i ) ;
iguana_blockQ ( " kicka " , coin , bp , i , block - > RO . hash2 , 0 * forceflag ) ;
if ( forceflag ! = 0 & & ( addr = coin - > peers . ranked [ rand ( ) % numpeers ] ) ! = 0 )
iguana_sendblockreqPT ( coin , addr , bp , i , block - > RO . hash2 , 0 ) ;
} else iguana_blockQ ( " kickb " , coin , bp , i , block - > RO . hash2 , 0 * forceflag ) ;
if ( forceflag ! = 0 )
bp - > issued [ i ] = block - > issued = now ;
else bp - > issued [ i ] = block - > issued = saved ;
flag + + ;
} //else printf("%d ",now - block->issued);
}
if ( nonz < capacity & & hashes ! = 0 )
hashes [ nonz ] = hash2 ;
nonz + + ;
}
if ( flag ! = 0 & & priority ! = 0 & & laggard ! = 0 & & coin - > current = = bp )
printf ( " [%d] reissued.%d currentflag.%d ht.%d s.%d finished.%d most.%d laggards.%d maxunfinished.%d \n " , bp - > hdrsi , flag , bp - > currentflag , bp - > bundleheight , bp - > numsaved , finished , doneval , laggard , maxval ) ;
SETBIT ( missings , i ) ;
m + + ;
}
if ( bp = = coin - > current )
return ( counter ) ;
}
for ( i = 0 ; i < bp - > n ; i + + )
} else printf ( " [%d] emitfinish.%u \n " , bp - > hdrsi , bp - > emitfinish ) ;
* nonzp = nonz ;
//printf("missings.[%d] m.%d nonz.%d spec.%p[%d]\n",bp->hdrsi,m,nonz,bp->speculative,bp->numspec);
return ( m ) ;
}
int32_t iguana_sendhashes ( struct iguana_info * coin , struct iguana_peer * addr , int32_t msgtype , bits256 hashes [ ] , int32_t n )
{
int32_t len ; uint8_t serialized [ ( sizeof ( int32_t ) + sizeof ( * hashes ) ) * IGUANA_PENDINGREQUESTS + 1024 ] ;
if ( ( len = iguana_getdata ( coin , serialized , MSG_BLOCK , hashes , n ) ) > 0 )
{
if ( ( block = bp - > blocks [ i ] ) ! = 0 & & bp - > speculativecache [ i ] = = 0 )
if ( len > sizeof ( serialized ) )
{
if ( block - > fpipbits = = 0 | | block - > fpos < 0 | | block - > RO . recvlen = = 0 )
printf ( " iguana_sendhashes: len.%d size.%ld \n " , len , sizeof ( serialized ) ) ;
exit ( - 1 ) ;
}
iguana_send ( coin , addr , serialized , len ) ;
coin - > numreqsent + = n ;
addr - > pendblocks + = n ;
addr - > pendtime = ( uint32_t ) time ( NULL ) ;
//printf("sendhashes[%d] -> %s\n",n,addr->ipaddr);
} else n = 0 ;
return ( n ) ;
}
int32_t iguana_nextnonz ( uint8_t * missings , int32_t i , int32_t max )
{
for ( ; i < max ; i + + )
if ( GETBIT ( missings , i ) ! = 0 )
break ;
return ( i ) ;
}
int32_t iguana_bundlerequests ( struct iguana_info * coin , uint8_t missings [ IGUANA_MAXBUNDLESIZE / 8 + 1 ] , int32_t * missingp , int32_t * capacityp , struct iguana_bundle * bp , int32_t lag )
{
uint8_t numpeers ; int32_t i , j , avail , nonz = 0 , c , n , m = 0 , max , capacity , numsent ; bits256 hashes [ 500 ] , hash2 ;
struct iguana_block * block ; struct iguana_peer * peers [ 256 ] , * addr ; uint32_t now = ( uint32_t ) time ( NULL ) ;
max = ( int32_t ) ( sizeof ( hashes ) / sizeof ( * hashes ) ) ;
* missingp = * capacityp = 0 ;
if ( ( numpeers = iguana_recentpeers ( coin , & capacity , peers ) ) > 0 )
{
* capacityp = capacity ;
if ( ( n = iguana_blocksmissing ( coin , & avail , missings , hashes , bp , capacity < max ? capacity : max , lag ) ) > 0 & & avail > 0 )
{
* missingp = n ;
//printf("n.%d avail.%d numpeers.%d\n",n,avail,numpeers);
for ( i = 0 ; i < numpeers & & avail > 0 ; i + + )
{
if ( now > block - > issued + lag )
if ( ( addr = peers [ i ] ) ! = 0 & & ( c = ( coin - > MAXPENDINGREQUESTS - addr - > pendblocks ) ) > 0 )
{
block - > numrequests + + ;
if ( bp = = coin - > current )
printf ( " [%d:%d].%x " , bp - > hdrsi , i , block - > fpipbits ) ;
iguana_blockQ ( " kickc " , coin , bp , i , block - > RO . hash2 , 0 ) ; //bp == coin->current && now > block->issued+lag);
bp - > issued [ i ] = block - > issued = now ;
counter + + ;
if ( - - max < = 0 )
break ;
if ( c + m > max )
c = max - m ;
if ( avail < c )
c = avail ;
//printf("i.%d c.%d avail.%d m.%d max.%d\n",i,c,avail,m,max);
if ( c > 0 & & ( numsent = iguana_sendhashes ( coin , addr , MSG_BLOCK , & hashes [ m ] , c ) ) > 0 )
{
for ( j = 0 ; j < numsent ; j + + )
{
if ( ( nonz = iguana_nextnonz ( missings , nonz , bp - > n ) ) < bp - > n )
{
if ( ( block = iguana_bundleblock ( coin , & hash2 , bp , nonz ) ) ! = 0 )
hash2 = block - > RO . hash2 ;
bp - > issued [ nonz ] = now ;
//char str[65]; printf("issue.[%d:%d] %s %u\n",bp->hdrsi,nonz,bits256_str(str,hash2),now);
nonz + + ;
} else printf ( " bundlerequests unexpected nonz.%d c.%d m.%d n.%d numsent.%d i.%d \n " , nonz , c , m , n , numsent , i ) ;
}
m + = numsent ;
avail - = numsent ;
}
}
}
}
else if ( block ! = 0 & & block - > fpipbits = = 0 & & bits256_nonz ( bp - > hashes [ i ] ) ! = 0 & & now > bp - > issued [ i ] + lag )
{
if ( bp = = coin - > current )
printf ( " b[%d:%d].%x " , bp - > hdrsi , i , block - > fpipbits ) ;
iguana_blockQ ( " kickd " , coin , bp , i , bp - > hashes [ i ] , 0 ) ; //bp == coin->current && now > bp->issued[i]+lag*3);
bp - > issued [ i ] = now ;
counter + + ;
}
else if ( bp - > speculative ! = 0 & & bits256_nonz ( bp - > speculative [ i ] ) ! = 0 & & now > bp - > issued [ i ] + lag )
{
if ( bp = = coin - > current )
printf ( " [%d:%d] " , bp - > hdrsi , i ) ;
iguana_blockQ ( " kicke " , coin , bp , i , bp - > speculative [ i ] , 0 ) ;
bp - > issued [ i ] = now ;
counter + + ;
}
}
return ( counter ) ;
} //else printf("err avail.%d n.%d\n",avail,n);
} //else printf("numpeers.%d\n",numpeers);
return ( m ) ;
}
int32_t iguana_bundleready ( struct iguana_info * coin , struct iguana_bundle * bp )
{
int32_t i , ready , valid , hdrsi , checki ; struct iguana_block * block ; char fname [ 1024 ] ; static bits256 zero ;
int32_t i , ready , valid ; struct iguana_block * block ;
for ( i = ready = 0 ; i < bp - > n ; i + + )
{
if ( ( block = bp - > blocks [ i ] ) ! = 0 )
@ -636,17 +553,9 @@ int32_t iguana_bundleready(struct iguana_info *coin,struct iguana_bundle *bp)
//printf("(%x:%x) ",(uint32_t)block->RO.hash2.ulongs[3],(uint32_t)bp->hashes[i].ulongs[3]);
if ( iguana_blockvalidate ( coin , & valid , block , 1 ) < 0 | | block - > fpipbits = = 0 | | block - > fpos < 0 | | ( bp - > bundleheight + i > 0 & & bits256_nonz ( block - > RO . prev_block ) = = 0 ) )
{
fname [ 0 ] = 0 ;
if ( ( checki = iguana_peerfname ( coin , & hdrsi , GLOBALTMPDIR , fname , 0 , block - > RO . hash2 , zero , 1 , 1 ) ) ! = i )
printf ( " checki.%d vs %d mismatch? \n " , checki , i ) ;
if ( fname [ 0 ] ! = 0 )
OS_removefile ( fname , 0 ) ;
printf ( " >>>>>>> block contents error at ht.%d (%s) \n " , bp - > bundleheight + i , fname ) ;
printf ( " >>>>>>> block contents error at ht.%d [%d:%d] \n " , bp - > bundleheight + i , bp - > hdrsi , i ) ;
//char str[65]; patch.(%s) and reissue %s checki.%d vs %d\n",block->fpipbits,bp->bundleheight+i,bits256_str(str,block->RO.prev_block),fname,checki,i);
block - > fpipbits = 0 ;
block - > fpos = - 1 ;
block - > queued = 0 ;
block - > RO . recvlen = 0 ;
iguana_blockunmark ( coin , block , bp , i , 1 ) ;
} else ready + + ;
}
else
@ -661,7 +570,6 @@ int32_t iguana_bundleready(struct iguana_info *coin,struct iguana_bundle *bp)
int32_t iguana_bundlehdr ( struct iguana_info * coin , struct iguana_bundle * bp , int32_t starti )
{
int32_t counter = 0 ;
int32_t i ; uint32_t now ; struct iguana_block * block ;
if ( 0 & & bp - > isRT = = 0 & & ( bp - > hdrsi = = coin - > bundlescount - 1 | | bp = = coin - > current ) )
printf ( " hdr ITERATE.%d bundle.%d vs %d: h.%d n.%d r.%d s.%d c.%d finished.%d spec.%p[%d] \n " , bp - > hdrsi , bp - > bundleheight , coin - > longestchain - coin - > chain - > bundlesize , bp - > numhashes , bp - > n , bp - > numrecv , bp - > numsaved , bp - > numcached , bp - > emitfinish , bp - > speculative , bp - > numspec ) ;
if ( coin - > enableCACHE ! = 0 & & bp - > numhashes < bp - > n & & ( bp - > speculative = = 0 | | bp - > hdrsi > = coin - > longestchain / bp - > n ) )
@ -673,39 +581,11 @@ int32_t iguana_bundlehdr(struct iguana_info *coin,struct iguana_bundle *bp,int32
{
if ( time ( NULL ) > bp - > issued [ 1 ] + 10 )
{
iguana_blockQ ( " getnexthdr " , coin , bp , - 1 , bp - > speculative [ 1 ] , 1 ) ;
printf ( " request speculative[1] for bp.[%d] \n " , bp - > hdrsi ) ;
iguana_blockQ ( " getnexthdr " , coin , bp , - 1 , bp - > speculative [ 1 ] , 0 ) ;
bp - > issued [ 1 ] = ( uint32_t ) time ( NULL ) ;
}
}
if ( bp - > speculative ! = 0 ) //&& bp == coin->current )
{
now = ( uint32_t ) time ( NULL ) ;
for ( i = 1 ; i < bp - > numspec & & i < bp - > n ; i + + )
{
if ( bits256_nonz ( bp - > hashes [ i ] ) = = 0 & & bits256_nonz ( bp - > speculative [ i ] ) ! = 0 )
{
if ( ( block = bp - > blocks [ i ] ) = = 0 & & bp - > speculativecache [ i ] = = 0 & & now > bp - > issued [ i ] + 60 )
{
//printf("speculative.[%d:%d]\n",bp->hdrsi,i);
iguana_blockQ ( " speculative " , coin , bp , - i , bp - > speculative [ i ] , 0 ) ; //now > bp->issued[i]+60);
bp - > issued [ i ] = now ;
continue ;
}
}
else if ( 0 & & ( block = bp - > blocks [ i ] ) ! = 0 & & bp - > speculativecache [ i ] = = 0 & & block - > fpipbits = = 0 & & now > bp - > issued [ i ] + 60 )
{
printf ( " speculativeB.[%d:%d] \n " , bp - > hdrsi , i ) ;
iguana_blockQ ( " speculativeB " , coin , bp , i , block - > RO . hash2 , 1 ) ;
continue ;
}
if ( bits256_nonz ( bp - > speculative [ i ] ) ! = 0 & & now > bp - > issued [ i ] + 13 )
{
//printf("speculativeC [%d:%d]\n",bp->hdrsi,i);
iguana_blockQ ( " speculativeC " , coin , bp , - i , bp - > speculative [ i ] , 0 ) ;
bp - > issued [ i ] = now ;
}
}
}
return ( counter ) ;
}
@ -729,105 +609,43 @@ int32_t iguana_bundletweak(struct iguana_info *coin,struct iguana_bundle *bp)
if ( ( lastbp = coin - > lastpending ) ! = 0 & & lastbp - > hdrsi < coin - > bundlescount - 1 )
coin - > lastpending = coin - > bundles [ lastbp - > hdrsi + 1 ] ;
iguana_setmaxbundles ( coin ) ;
/*if ( (rand() % 3) == 0 )
{
if ( coin - > MAXBUNDLES > coin - > endPEND )
coin - > MAXBUNDLES - - ;
else if ( coin - > MAXBUNDLES < coin - > endPEND )
coin - > MAXBUNDLES + + ;
} */
return ( coin - > MAXBUNDLES ) ;
}
int64_t iguana_bundlecalcs ( struct iguana_info * coin , struct iguana_bundle * bp )
int64_t iguana_bundlecalcs ( struct iguana_info * coin , struct iguana_bundle * bp , int32_t lag )
{
int32_t bundlei , numhashes , numsaved , numcach ed, numrecv , minrequests ; FILE * fp ;
int64_t datasize ; struct iguana_block * block ; uint32_t now ; char fname [ 1024 ] ;
int32_t bundlei , numhashes , avail , numsaved , numrecv , minrequests ; uint8_t missings [ IGUANA_MAXBUNDLESIZE / 8 + 1 ] ;
int64_t datasize ; struct iguana_block * block ;
if ( bp - > emitfinish > coin - > startutc )
{
bp - > numhashes = bp - > numsaved = bp - > numcached = bp - > numrecv = bp - > n ;
return ( bp - > datasize ) ;
}
now = ( uint32_t ) time ( NULL ) ;
datasize = numhashes = numsaved = numcached = numrecv = minrequests = 0 ;
datasize = numhashes = numsaved = numrecv = minrequests = 0 ;
for ( bundlei = 0 ; bundlei < bp - > n ; bundlei + + )
{
block = bp - > blocks [ bundlei ] ;
if ( bits256_nonz ( bp - > hashes [ bundlei ] ) > 0 & & block ! = 0 )
if ( bits256_nonz ( bp - > hashes [ bundlei ] ) > 0 )
{
//checki = iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,bp->hashes[bundlei],bundlei>0?bp->hashes[bundlei-1]:zero,1);
if ( bits256_cmp ( block - > RO . hash2 , bp - > hashes [ bundlei ] ) = = 0 )
numhashes + + ;
if ( block ! = 0 & & b its256_cmp ( block - > RO . hash2 , bp - > hashes [ bundlei ] ) = = 0 )
{
/*if ( checki != bundlei || bundlei < 0 || bundlei >= coin->chain->bundlesize )
{
printf ( " iguana_bundlecalcs.(%s) illegal hdrsi.%d bundlei.%d checki.%d \n " , fname , hdrsi , bundlei , checki ) ;
continue ;
} */
if ( 0 & & coin - > current = = bp ) //&& (bp->isRT != 0 || bp->hdrsi > coin->bundlescount-3) )
{
if ( ( fp = fopen ( fname , " rb " ) ) ! = 0 )
{
fseek ( fp , 0 , SEEK_END ) ;
block - > RO . recvlen = ( uint32_t ) ftell ( fp ) ;
block - > fpipbits = 1 ;
block - > fpos = 0 ;
//printf("fp.[%d:%d] len.%d\n",hdrsi,bundlei,block->RO.recvlen);
fclose ( fp ) ;
}
else
{
//char str[65]; printf("missing.(%s) issue.%s\n",fname,bits256_str(str,bp->hashes[bundlei]));
block - > RO . recvlen = 0 ;
block - > fpipbits = 0 ;
block - > fpos = - 1 ;
//iguana_blockQ("missing",coin,0,-1,block->RO.hash2,1);
}
}
block - > hdrsi = bp - > hdrsi , block - > bundlei = bundlei ;
if ( bp - > minrequests = = 0 | | ( block - > numrequests > 0 & & block - > numrequests < bp - > minrequests ) )
bp - > minrequests = block - > numrequests ;
//if ( (bp->hdrsi == 0 && bundlei == 0) || bits256_nonz(block->RO.prev_block) != 0 )
if ( block - > fpipbits ! = 0 & & block - > fpos > = 0 )
numsaved + + ;
if ( block - > RO . recvlen ! = 0 )
{
if ( block - > fpipbits ! = 0 & & block - > fpos > = 0 )
numsaved + + ;
if ( block - > RO . recvlen ! = 0 | | block - > fpipbits ! = 0 | | block - > fpos > = 0 )
{
numrecv + + ;
datasize + = block - > RO . recvlen ;
}
numrecv + + ;
datasize + = block - > RO . recvlen ;
}
/*else if ( 0 && bp == coin->current && bp->speculativecache[bundlei] == 0 )
{
char str [ 65 ] ; printf ( " missing prev_block [%d:%d] %s \n " , bp - > hdrsi , bundlei , bits256_str ( str , bp - > hashes [ bundlei ] ) ) ;
if ( block ! = 0 )
{
block - > RO . recvlen = 0 ;
block - > fpipbits = 0 ;
block - > fpos = - 1 ;
}
else if ( now > bp - > issued [ bundlei ] + 13 )
iguana_blockQ ( " missing " , coin , bp , bundlei , bp - > hashes [ bundlei ] , 1 ) ;
} */
}
/*else
{
char str [ 65 ] , str2 [ 65 ] ; printf ( " mismatched [%d:%d] %s vs %s \n " , bp - > hdrsi , bundlei , bits256_str ( str , bp - > hashes [ bundlei ] ) , bits256_str ( str2 , block - > RO . hash2 ) ) ;
//iguana_blockQ("missing",coin,0,-1,block->RO.hash2,1);
bp - > issued [ bundlei ] = 0 ;
bp - > blocks [ bundlei ] = 0 ;
memset ( bp - > hashes [ bundlei ] . bytes , 0 , sizeof ( bp - > hashes [ bundlei ] ) ) ;
OS_removefile ( fname , 0 ) ;
} */
numhashes + + ;
bp - > checkedtmp + + ;
}
if ( ( ( block = bp - > blocks [ bundlei ] ) ! = 0 & & block - > fpipbits ! = 0 & & block - > fpos > = 0 ) | | bp - > speculativecache [ bundlei ] ! = 0 )
numcached + + ;
}
bp - > numcached = bp - > n - iguana_blocksmissing ( coin , & avail , missings , 0 , bp , 0 , lag ) ;
bp - > datasize = datasize ;
bp - > numhashes = numhashes ;
bp - > numsaved = numsaved ;
bp - > numcached = numcached ;
bp - > numrecv = numrecv ;
bp - > minrequests = minrequests ;
bp - > estsize = ( ( int64_t ) bp - > datasize * bp - > n ) / ( bp - > numrecv + 1 ) ;
@ -897,9 +715,9 @@ int32_t iguana_bundlefinalize(struct iguana_info *coin,struct iguana_bundle *bp,
return ( 1 ) ;
}
int32_t iguana_bundleiters ( struct iguana_info * coin , struct OS_memspace * mem , struct OS_memspace * memB , struct iguana_bundle * bp , int32_t timelimit )
int32_t iguana_bundleiters ( struct iguana_info * coin , struct OS_memspace * mem , struct OS_memspace * memB , struct iguana_bundle * bp , int32_t timelimit , int32_t lag )
{
int32_t range , starti , lasti , i , n , len , retval = 0 , max , counter = 0 ; struct iguana_block * block ; struct iguana_bundle * currentbp , * lastbp ; uint8_t serialized [ 512 ] ; struct iguana_peer * addr ; long lag ; struct iguana_blockreq * breq ;
int32_t range , starti , lasti , i , n , len , retval = 0 , max , counter = 0 ; struct iguana_block * block ; struct iguana_bundle * currentbp , * lastbp ; uint8_t serialized [ 512 ] ; struct iguana_peer * addr ; struct iguana_blockreq * breq ;
if ( coin - > started = = 0 | | coin - > active = = 0 )
{
printf ( " %s not ready yet \n " , coin - > symbol ) ;
@ -914,15 +732,9 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru
lastbp = coin - > lastpending ;
starti = currentbp = = 0 ? 0 : currentbp - > hdrsi ;
lasti = lastbp = = 0 ? coin - > bundlescount - 1 : lastbp - > hdrsi ;
if ( bp ! = coin - > current | | bp - > dirty ! = 0 )
{
iguana_bundlecalcs ( coin , bp ) ;
bp - > dirty = 0 ;
}
iguana_bundlecalcs ( coin , bp , lag ) ;
if ( bp - > hdrsi = = coin - > bundlescount - 1 )
{
iguana_autoextend ( coin , bp ) ;
}
//printf("ITER utxo.%u now.%u spec.%-4d bundle.%-4d h.%-4d r.%-4d s.%-4d F.%d T.%d issued.%d mb.%d/%d\n",bp->utxofinish,(uint32_t)time(NULL),bp->numspec,bp->bundleheight/coin->chain->bundlesize,bp->numhashes,bp->numrecv,bp->numsaved,bp->emitfinish,timelimit,counter,coin->MAXBUNDLES,coin->bundlescount);
bp - > nexttime = ( uint32_t ) ( time ( NULL ) + 1 ) ;
if ( bp - > numhashes < bp - > n & & bp - > bundleheight < coin - > longestchain - coin - > chain - > bundlesize )
@ -957,16 +769,16 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru
else if ( bp - > hdrsi = = starti | | ( bp - > hdrsi > = starti & & bp - > hdrsi < = starti + range ) ) //bits256_nonz(bp->allhash) != 0 &&
{
max = bp - > n ;
counter = iguana_bundleissue ( coin , bp , max , timelimit ) ;
//if ( bp == coin->current && coin->isRT == 0 )
// bp->nexttime--;
counter = 0 ; //iguana_bundleissue(coin,bp,max,timelimit);
if ( bp = = coin - > current & & coin - > isRT = = 0 )
bp - > nexttime - - ;
if ( bp - > isRT = = 0 & & bp = = coin - > current & & counter > 0 )
printf ( " ITER.rt%d now.%u spec.%-4d bundle.%-4d h.%-4d r.%-4d s.%-4d F.%d T.%d issued.%d mb.%d/%d \n " , bp - > isRT , ( uint32_t ) time ( NULL ) , bp - > numspec , bp - > bundleheight / coin - > chain - > bundlesize , bp - > numhashes , bp - > numrecv , bp - > numsaved , bp - > emitfinish , timelimit , counter , coin - > MAXBUNDLES , coin - > bundlescount ) ;
if ( bp - > hdrsi = = starti & & bp - > isRT = = 0 )
{
if ( coin - > stucktime ! = 0 )
{
lag = time ( NULL ) - coin - > stucktime ;
lag = ( int32_t ) time ( NULL ) - coin - > stucktime ;
if ( ( ( lag / coin - > MAXSTUCKTIME ) > > 1 ) > coin - > stuckiters )
{
coin - > stuckiters = ( int32_t ) lag / 60 ;
@ -986,7 +798,7 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru
}
if ( ( block = bp - > blocks [ i ] ) ! = 0 & & block - > fpipbits = = 0 & & bp - > speculativecache [ i ] = = 0 )
{
printf ( " [%d:%d] " , bp - > hdrsi , i ) ;
printf ( " s. [%d:%d] " , bp - > hdrsi , i ) ;
iguana_blockQ ( " stuck " , coin , bp , i , block - > RO . hash2 , 0 ) ;
iguana_blockQ ( " stuck " , coin , bp , i , block - > RO . hash2 , 1 ) ;
if ( coin - > peers . numranked > 8 & & ( addr = coin - > peers . ranked [ n % 8 ] ) ! = 0 & & addr - > usock > = 0 & & addr - > dead = = 0 & & addr - > msgcounts . verack ! = 0 )
@ -1002,7 +814,7 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru
}
}
if ( n > 0 )
printf ( " issued %d priority requests [%d] to unstick stuckiters.%d lag.%l d \n " , n , bp - > hdrsi , coin - > stuckiters , lag ) ;
printf ( " issued %d priority requests [%d] to unstick stuckiters.%d lag.%d \n " , n , bp - > hdrsi , coin - > stuckiters , lag ) ;
}
}
}
@ -1031,19 +843,69 @@ static int32_t revsortds(double *buf,uint32_t num,int32_t size)
return ( 0 ) ;
} */
void iguana_bundlestats ( struct iguana_info * coin , char * str )
int32_t iguana_cacheprocess ( struct iguana_info * coin , struct iguana_bundle * bp , int32_t bundlei )
{
int32_t recvlen ; struct iguana_msghdr H ; uint8_t * data ; struct iguana_block * block ;
if ( ( data = bp - > speculativecache [ bundlei ] ) ! = 0 & & bp - > speculative ! = 0 & & ( block = iguana_blockfind ( coin , bp - > speculative [ bundlei ] ) ) ! = 0 )
{
iguana_bundlehash2add ( coin , 0 , bp , bundlei , bp - > speculative [ bundlei ] ) ;
recvlen = * ( int32_t * ) data ;
memset ( & H , 0 , sizeof ( H ) ) ;
iguana_sethdr ( & H , coin - > chain - > netmagic , " block " , & data [ sizeof ( recvlen ) ] , recvlen ) ;
if ( coin - > internaladdr . RAWMEM . ptr = = 0 )
iguana_meminit ( & coin - > internaladdr . RAWMEM , " cache " , 0 , IGUANA_MAXPACKETSIZE + 65536 * 3 , 0 ) ;
if ( coin - > TXMEM . ptr = = 0 )
iguana_meminit ( & coin - > internaladdr . TXDATA , " txdata " , 0 , IGUANA_MAXPACKETSIZE * 1.5 , 0 ) ;
if ( coin - > internaladdr . HASHMEM . ptr = = 0 )
iguana_meminit ( & coin - > internaladdr . HASHMEM , " HASHPTRS " , 0 , 256 , 0 ) ;
if ( iguana_msgparser ( coin , & coin - > internaladdr , & coin - > internaladdr . RAWMEM , & coin - > internaladdr . TXDATA , & coin - > internaladdr . HASHMEM , & H , & data [ sizeof ( recvlen ) ] , recvlen ) < 0 )
printf ( " error parsing speculativecache.[%d:%d] \n " , bp - > hdrsi , bundlei ) ;
else block - > processed = 1 ;
//char str[65]; printf("iguana_cacheprocess [%d:%d] %s fp.%x len.%d:%d\n",bp->hdrsi,bundlei,bits256_str(str,bp->hashes[bundlei]),block->fpipbits,block->RO.recvlen,recvlen);
//myfree(data,recvlen + sizeof(recvlen));
//bp->speculativecache[bundlei] = 0;
return ( recvlen ) ;
}
return ( - 1 ) ;
}
int32_t iguana_bundlemissings ( struct iguana_info * coin , struct iguana_bundle * bp , int32_t capacity , int32_t lag )
{
uint8_t missings [ IGUANA_MAXBUNDLESIZE / 8 + 1 ] ; int32_t tmp , missing , avail , n ;
if ( bp = = coin - > current )
lag = 10 ;
missing = iguana_blocksmissing ( coin , & avail , missings , 0 , bp , 0 , lag ) ;
if ( bp - > missingstime = = 0 | | ( bp = = coin - > current & & missing < ( bp - > origmissings > > 1 ) ) | | missing < ( bp - > origmissings > > 3 ) | | time ( NULL ) > bp - > missingstime + lag )
{
if ( ( n = iguana_bundlerequests ( coin , missings , & bp - > origmissings , & tmp , bp , lag ) ) > 0 )
{
printf ( " bundle.[%d] missings.%d n.%d capacity %d -> %d \n " , bp - > hdrsi , bp - > origmissings , n , capacity , capacity - n ) ;
capacity - = n ;
bp - > missingstime = ( uint32_t ) time ( NULL ) ;
}
}
return ( capacity ) ;
}
void iguana_bundlestats ( struct iguana_info * coin , char * str , int32_t lag )
{
int32_t i , n , m , j , numv , count , pending , dispflag , numutxo , numbalances , numrecv , done , numhashes , numcached , numsaved , numemit ;
int64_t spaceused = 0 , estsize = 0 ; struct iguana_bundle * bp , * lastpending = 0 , * firstgap = 0 ; struct iguana_block * block , * prev ; uint32_t now ; bits256 hash2 ;
int32_t i , n , m , j , numv , count , starti , lasti , pending , capacity , dispflag , numutxo , numbalances , numrecv , done , numhashes , numcached , numsaved , numemit ; struct iguana_block * block ; bits256 hash2 ;
int64_t spaceused = 0 , estsize = 0 ; struct iguana_bundle * current bp, * lastb p , * bp , * lastpending = 0 , * firstgap = 0 ; uint32_t now ;
now = ( uint32_t ) time ( NULL ) ;
dispflag = 1 ; //(rand() % 1000) == 0;
numrecv = numhashes = numcached = numsaved = numemit = done = numutxo = numbalances = 0 ;
count = coin - > bundlescount ;
//sortbuf = calloc(count,sizeof(*sortbuf)*2);
currentbp = coin - > current ;
lastbp = coin - > lastpending ;
starti = currentbp = = 0 ? 0 : currentbp - > hdrsi ;
lasti = lastbp = = 0 ? coin - > bundlescount - 1 : lastbp - > hdrsi ;
iguana_recentpeers ( coin , & capacity , 0 ) ;
//sortbuf = calloc(count,sizeof(*sortbuf)*2);
for ( i = n = m = numv = pending = 0 ; i < count ; i + + )
{
if ( ( bp = coin - > bundles [ i ] ) ! = 0 )
{
iguana_bundlecalcs ( coin , bp , lag ) ;
if ( bp - > emitfinish > 1 )
{
for ( j = 0 ; j < bp - > n ; j + + )
@ -1054,186 +916,19 @@ void iguana_bundlestats(struct iguana_info *coin,char *str)
}
else
{
if ( bp - > hdrsi > = starti & & bp - > hdrsi < lasti )
capacity = iguana_bundlemissings ( coin , bp , capacity , lag ) ;
for ( j = 0 ; j < bp - > n ; j + + )
{
if ( bp - > speculativecache [ j ] ! = 0 )
{
iguana_blockhashset ( coin , - 1 , bp - > speculative [ j ] , 1 ) ;
numcached + + ;
}
}
}
if ( 0 & & bp - > numhashes < bp - > n & & bp - > speculative ! = 0 )
{
for ( j = 1 ; j < bp - > numspec & & j < bp - > n ; j + + )
{
if ( ( block = bp - > blocks [ j ] ) = = 0 )
{
if ( bits256_nonz ( bp - > hashes [ j ] ) ! = 0 )
block = iguana_blockfind ( coin , bp - > hashes [ j ] ) ;
else if ( bits256_nonz ( bp - > speculative [ j ] ) ! = 0 )
{
if ( ( block = iguana_blockfind ( coin , bp - > speculative [ j ] ) ) = = 0 )
block = iguana_blockhashset ( coin , - 1 , bp - > speculative [ j ] , 1 ) ;
}
}
else if ( bits256_nonz ( block - > RO . prev_block ) ! = 0 & & iguana_blockstatus ( coin , block ) ! = 0 )
continue ;
prev = bp - > blocks [ j - 1 ] ;
//printf("[%d:%d] prev.%p nonz.%d speculative.%d block.%p\n",bp->hdrsi,j,bp->blocks[j-1],bits256_nonz(bp->hashes[j]),bits256_nonz(bp->speculative[j]),bp->blocks[j]);
if ( block ! = 0 & & bp - > blocks [ j ] = = 0 ) //prev != 0 &&
{
//char str2[65]; printf("[%d:%d] prev.%p nonz.%d speculative.%d prev.%s vs %s ipbits.%x q.%d\n",bp->hdrsi,j,bp->blocks[j-1],bits256_nonz(bp->hashes[j]),bits256_nonz(bp->speculative[j]),bits256_str(str,prev->RO.hash2),bits256_str(str2,block->RO.prev_block),block->fpipbits,block->queued);
if ( iguana_blockstatus ( coin , block ) = = 0 & & bp - > speculativecache [ j ] = = 0 )
{
if ( block - > req ! = 0 )
{
block - > queued = 1 ;
queue_enqueue ( " cacheQ " , & coin - > cacheQ , & block - > req - > DL , 0 ) ;
block - > req = 0 ;
//printf("submit cached [%d:%d]\n",bp->hdrsi,j);
}
else if ( now > block - > issued + 10 )
{
block - > issued = now ;
//printf("submit speculative [%d:%d]\n",bp->hdrsi,j);
iguana_blockQ ( " spec " , coin , 0 , - 1 , block - > RO . hash2 , 0 ) ;
}
}
} // else break;
}
}
int32_t checki , hdrsi , havefile , missing , recvlen ; char fname [ 1024 ] ; FILE * fp ; struct iguana_msghdr H ; static bits256 zero ;
//if ( bp->speculative != 0 )
{
now = ( int32_t ) time ( NULL ) ;
for ( j = havefile = missing = 0 ; j < bp - > n ; j + + )
{
if ( bits256_nonz ( bp - > hashes [ j ] ) ! = 0 )
hash2 = bp - > hashes [ j ] ;
else if ( bp - > speculative ! = 0 )
hash2 = bp - > speculative [ j ] ;
if ( bits256_nonz ( hash2 ) = = 0 )
{
missing + + ;
continue ;
}
checki = iguana_peerfname ( coin , & hdrsi , GLOBALTMPDIR , fname , 0 , hash2 , zero , 1 , 0 ) ;
if ( 1 & & ( fp = fopen ( fname , " rb " ) ) ! = 0 )
{
havefile + + ;
fclose ( fp ) ;
continue ;
}
//if ( (block= bp->blocks[j]) != 0 && block->fpipbits != 0 && block->fpos >= 0 && block->RO.recvlen > 0 && bits256_nonz(block->RO.prev_block) != 0 )
// continue;
missing + + ;
if ( bp - > speculativecache [ j ] ! = 0 )
{
block = iguana_blockfind ( coin , bp - > speculative [ j ] ) ;
if ( block ! = 0 )
block - > queued = 1 ;
if ( bp - > speculativecache [ j ] ! = 0 & & block ! = 0 )
{
block - > bundlei = j ;
block - > hdrsi = bp - > hdrsi ;
bp - > blocks [ j ] = block ;
//printf("bundlehashadd set.%d recvlen.%d\n",j,recvlen);
iguana_bundlehash2add ( coin , 0 , bp , j , bp - > speculative [ j ] ) ;
recvlen = * ( int32_t * ) bp - > speculativecache [ j ] ;
memset ( & H , 0 , sizeof ( H ) ) ;
iguana_sethdr ( & H , coin - > chain - > netmagic , " block " , & bp - > speculativecache [ j ] [ sizeof ( recvlen ) ] , recvlen ) ;
if ( coin - > RAWMEM . ptr = = 0 )
iguana_meminit ( & coin - > RAWMEM , " cache " , 0 , IGUANA_MAXPACKETSIZE + 65536 * 3 , 0 ) ;
if ( coin - > TXMEM . ptr = = 0 )
iguana_meminit ( & coin - > TXMEM , " txdata " , 0 , IGUANA_MAXPACKETSIZE * 1.5 , 0 ) ;
if ( coin - > HASHMEM . ptr = = 0 )
iguana_meminit ( & coin - > HASHMEM , " HASHPTRS " , 0 , 256 , 0 ) ;
if ( iguana_msgparser ( coin , 0 , & coin - > RAWMEM , & coin - > TXMEM , & coin - > HASHMEM , & H , & bp - > speculativecache [ j ] [ sizeof ( recvlen ) ] , recvlen ) < 0 )
printf ( " error parsing speculativecache.[%d:%d] \n " , bp - > hdrsi , j ) ;
myfree ( bp - > speculativecache [ j ] , recvlen + sizeof ( recvlen ) ) ;
bp - > speculativecache [ j ] = 0 ;
}
else if ( bits256_nonz ( bp - > hashes [ j ] ) ! = 0 )
{
iguana_blockQ ( " currentstop " , coin , bp , j , hash2 , 0 ) ;
}
continue ;
}
if ( bp = = coin - > current & & ( now > bp - > issued [ j ] + 3 | | ( rand ( ) % 10 ) = = 0 ) )
{
fprintf ( stderr , " -[%d:%d].%d " , bp - > hdrsi , j , now - bp - > issued [ j ] ) ;
struct iguana_peer * addr ; int32_t r ;
if ( ( rand ( ) % 10 ) = = 0 & & ( r = coin - > peers . numranked ) ! = 0 & & ( addr = coin - > peers . ranked [ rand ( ) % r ] ) ! = 0 & & addr - > dead = = 0 & & addr - > usock > = 0 )
iguana_sendblockreqPT ( coin , addr , bp , j , hash2 , 0 ) ;
else iguana_blockQ ( " currentstop " , coin , bp , j , hash2 , 1 ) ;
//fprintf(stderr,"currentstop [%d:%d]\n",bp->hdrsi,j);
bp - > issued [ j ] = now ;
if ( ( block = iguana_blockhashset ( coin , - 1 , bp - > speculative [ j ] , 1 ) ) ! = 0 & & block - > processed = = 0 )
iguana_cacheprocess ( coin , bp , j ) ;
numcached + + ;
}
}
if ( bp = = coin - > current )
fprintf ( stderr , " [%d] check numcached.%d numhashes.%d numsaved.%d havefile.%d missing.%d \n " , bp - > hdrsi , bp - > numcached , bp - > numhashes , bp - > numsaved , havefile , missing ) ;
}
if ( bp - > speculative ! = 0 & & missing = = 0 )
{
hash2 = bp - > hashes [ 0 ] ;
for ( i = 1 ; i < bp - > n ; i + + )
{
/*if ( bits256_nonz(bp->speculative[i]) != 0 )
block = iguana_blockfind ( coin , bp - > speculative [ i ] ) ;
else if ( bits256_nonz ( bp - > hashes [ i ] ) ! = 0 )
block = iguana_blockfind ( coin , bp - > hashes [ i ] ) ; */
if ( ( block = bp - > blocks [ i ] ) = = 0 | | bits256_cmp ( block - > RO . prev_block , hash2 ) ! = 0 )
{
char str [ 65 ] , str2 [ 65 ] ;
printf ( " error with speculative prev at i.%d block.%p %s vs %s \n " , i , block , bits256_str ( str , bp - > hashes [ i ] ) , bits256_str ( str2 , hash2 ) ) ;
if ( block ! = 0 )
{
checki = iguana_peerfname ( coin , & hdrsi , GLOBALTMPDIR , fname , 0 , bp - > hashes [ i ] , zero , 1 , 0 ) ;
if ( fname [ 0 ] ! = 0 )
OS_removefile ( fname , 0 ) ;
printf ( " >>>>>>> block contents error at ht.%d (%s) \n " , bp - > bundleheight + i , fname ) ;
//char str[65]; patch.(%s) and reissue %s checki.%d vs %d\n",block->fpipbits,bp->bundleheight+i,bits256_str(str,block->RO.prev_block),fname,checki,i);
block - > fpipbits = 0 ;
block - > fpos = - 1 ;
block - > queued = 0 ;
block - > RO . recvlen = 0 ;
}
break ;
}
hash2 = block - > RO . hash2 ;
}
if ( i = = bp - > n & & iguana_bundlefinalize ( coin , bp , & coin - > MEM , coin - > MEMB ) = = 0 )
{
//free(bp->speculative);
//bp->speculative = 0;
}
}
/*if ( bp->speculative != 0 && missing == 0 )
{
if ( i = = bp - > n )
{
printf ( " have complete speculative bundle! \n " ) ;
for ( i = 1 ; i < bp - > n ; i + + )
{
if ( bits256_nonz ( bp - > speculative [ i ] ) ! = 0 & & bits256_nonz ( bp - > hashes [ i ] ) ! = 0 )
{
if ( ( block = iguana_blockfind ( coin , bp - > speculative [ i ] ) ) ! = 0 )
{
block - > bundlei = i ;
block - > hdrsi = bp - > hdrsi ;
bp - > blocks [ i ] = block ;
printf ( " bundlehashadd set.%d \n " , i ) ;
iguana_bundlehash2add ( coin , 0 , bp , i , bp - > speculative [ i ] ) ;
}
}
}
}
} */
//bp->rank = 0;
estsize + = bp - > estsize ; //iguana_bundlecalcs(coin,bp,done);
//bp->metric = bp->numhashes;
estsize + = bp - > estsize ;
bp - > metric = coin - > bundlescount - bp - > hdrsi ;
if ( done > coin - > bundlescount * IGUANA_HEADPERCENTAGE & & bp - > hdrsi > coin - > bundlescount * IGUANA_TAILPERCENTAGE )
bp - > metric * = 1000 ;
@ -1312,7 +1007,7 @@ void iguana_bundlestats(struct iguana_info *coin,char *str)
coin - > numsaved = numsaved ;
coin - > spaceused = spaceused ;
coin - > numverified = numv ;
char str4 [ 65 ] , str 5 [ 65 ] ;
char str5 [ 65 ] ;
if ( coin - > isRT = = 0 & & firstgap ! = 0 & & firstgap - > hdrsi < coin - > bundlescount - 1 )
{
if ( coin - > stuckmonitor ! = ( firstgap - > hdrsi * coin - > chain - > bundlesize * 10 ) + firstgap - > numsaved + firstgap - > numhashes + firstgap - > numcached )
@ -1336,8 +1031,21 @@ void iguana_bundlestats(struct iguana_info *coin,char *str)
myallocated ( 0 , 0 ) ;
coin - > lastdisp = ( uint32_t ) time ( NULL ) ;
}
if ( ( bp = coin - > current ) ! = 0 & & bp - > queued = = 0 )
iguana_bundleQ ( coin , firstgap , 1000 ) ;
if ( ( bp = coin - > current ) ! = 0 )
{
if ( coin - > blocks . hwmchain . height > = bp - > bundleheight & & coin - > blocks . hwmchain . height < bp - > bundleheight + bp - > n )
{
for ( i = coin - > blocks . hwmchain . height - bp - > bundleheight + 1 ; i < = bp - > n ; i + + )
{
if ( ( block = iguana_bundleblock ( coin , & hash2 , bp , i ) ) = = 0 & & bits256_nonz ( hash2 ) ! = 0 )
block = iguana_blockfind ( coin , hash2 ) ;
if ( block = = 0 | | _iguana_chainlink ( coin , block ) = = 0 )
break ;
}
}
if ( bp - > queued = = 0 )
iguana_bundleQ ( coin , firstgap , 1000 ) ;
}
iguana_setmaxbundles ( coin ) ;
strcpy ( coin - > statusstr , str ) ;
coin - > estsize = estsize ;