@ -1149,6 +1149,9 @@ static void add_base(ckpool_t *ckp, sdata_t *sdata, workbase_t *wb, bool *new_bl
static void broadcast_ping ( sdata_t * sdata ) ;
static void broadcast_ping ( sdata_t * sdata ) ;
# define REFCOUNT_REMOTE 100
# define REFCOUNT_LOCAL 5
/* Build a hashlist of all transactions, allowing us to compare with the list of
/* Build a hashlist of all transactions, allowing us to compare with the list of
* existing transactions to determine which need to be propagated */
* existing transactions to determine which need to be propagated */
static bool add_txn ( ckpool_t * ckp , sdata_t * sdata , txntable_t * * txns , const char * hash ,
static bool add_txn ( ckpool_t * ckp , sdata_t * sdata , txntable_t * * txns , const char * hash ,
@ -1163,9 +1166,9 @@ static bool add_txn(ckpool_t *ckp, sdata_t *sdata, txntable_t **txns, const char
HASH_FIND_STR ( sdata - > txns , hash , txn ) ;
HASH_FIND_STR ( sdata - > txns , hash , txn ) ;
if ( txn ) {
if ( txn ) {
if ( ! local )
if ( ! local )
txn - > refcount = 100 ;
txn - > refcount = REFCOUNT_REMOTE ;
else if ( txn - > refcount < 20 )
else if ( txn - > refcount < REFCOUNT_LOCAL )
txn - > refcount = 20 ;
txn - > refcount = REFCOUNT_LOCAL ;
txn - > seen = found = true ;
txn - > seen = found = true ;
}
}
ck_runlock ( & sdata - > workbase_lock ) ;
ck_runlock ( & sdata - > workbase_lock ) ;
@ -1177,9 +1180,9 @@ static bool add_txn(ckpool_t *ckp, sdata_t *sdata, txntable_t **txns, const char
memcpy ( txn - > hash , hash , 65 ) ;
memcpy ( txn - > hash , hash , 65 ) ;
txn - > data = strdup ( data ) ;
txn - > data = strdup ( data ) ;
if ( ! local | | ckp - > node )
if ( ! local | | ckp - > node )
txn - > refcount = 100 ;
txn - > refcount = REFCOUNT_REMOTE ;
else
else
txn - > refcount = 20 ;
txn - > refcount = REFCOUNT_LOCAL ;
HASH_ADD_STR ( * txns , hash , txn ) ;
HASH_ADD_STR ( * txns , hash , txn ) ;
return true ;
return true ;
@ -1565,44 +1568,10 @@ static void downstream_json(sdata_t *sdata, const json_t *val, const int64_t cli
}
}
/* Find any transactions that are missing from our transaction table during
/* Find any transactions that are missing from our transaction table during
* rebuild_txns by requesting their data from our bitcoind or requesting them
* rebuild_txns by requesting their data from another server . */
* from another server . */
static void request_txns ( ckpool_t * ckp , sdata_t * sdata , json_t * txns )
static void request_txns ( ckpool_t * ckp , sdata_t * sdata , json_t * txns )
{
{
json_t * val , * arr_val ;
json_t * val ;
size_t index ;
/* See if our bitcoind has the transactions first to avoid requesting
* them from another server . */
json_array_foreach ( txns , index , arr_val ) {
const char * hash = json_string_value ( arr_val ) ;
char * data = generator_get_txn ( ckp , hash ) ;
txntable_t * txn ;
if ( ! data )
continue ;
ck_wlock ( & sdata - > workbase_lock ) ;
HASH_FIND_STR ( sdata - > txns , hash , txn ) ;
if ( likely ( ! txn ) ) {
txn = ckzalloc ( sizeof ( txntable_t ) ) ;
memcpy ( txn - > hash , hash , 65 ) ;
txn - > data = data ;
txn - > refcount = 100 ;
HASH_ADD_STR ( sdata - > txns , hash , txn ) ;
} else
free ( data ) ;
ck_wunlock ( & sdata - > workbase_lock ) ;
/* We're removing this object so decrement index for next pass */
json_array_remove ( txns , index ) ;
index - - ;
}
if ( ! json_array_size ( txns ) ) {
LOGDEBUG ( " Retrieved all transactions from bitcoin in request_txns " ) ;
return ;
}
JSON_CPACK ( val , " {so} " , " hash " , txns ) ;
JSON_CPACK ( val , " {so} " , " hash " , txns ) ;
if ( ckp - > remote )
if ( ckp - > remote )
@ -1624,7 +1593,6 @@ static bool rebuild_txns(ckpool_t *ckp, sdata_t *sdata, workbase_t *wb, json_t *
json_t * txn_array , * missing_txns ;
json_t * txn_array , * missing_txns ;
char hash [ 68 ] = { } ;
char hash [ 68 ] = { } ;
bool ret = false ;
bool ret = false ;
txntable_t * txn ;
int i , len = 0 ;
int i , len = 0 ;
if ( likely ( hashes ) )
if ( likely ( hashes ) )
@ -1640,25 +1608,51 @@ static bool rebuild_txns(ckpool_t *ckp, sdata_t *sdata, workbase_t *wb, json_t *
txn_array = json_array ( ) ;
txn_array = json_array ( ) ;
missing_txns = json_array ( ) ;
missing_txns = json_array ( ) ;
ck_rlock ( & sdata - > workbase_lock ) ;
for ( i = 0 ; i < wb - > txns ; i + + ) {
for ( i = 0 ; i < wb - > txns ; i + + ) {
json_t * txn_val ;
json_t * txn_val = NULL ;
txntable_t * txn ;
char * data ;
memcpy ( hash , hashes + i * 65 , 64 ) ;
memcpy ( hash , hashes + i * 65 , 64 ) ;
ck_wlock ( & sdata - > workbase_lock ) ;
HASH_FIND_STR ( sdata - > txns , hash , txn ) ;
HASH_FIND_STR ( sdata - > txns , hash , txn ) ;
if ( unlikely ( ! txn ) ) {
if ( likely ( txn ) ) {
txn_val = json_string ( hash ) ;
txn - > refcount = REFCOUNT_REMOTE ;
json_array_append_new ( missing_txns , txn_val ) ;
ret = false ;
continue ;
}
txn - > refcount = 100 ;
txn - > seen = true ;
txn - > seen = true ;
JSON_CPACK ( txn_val , " {ss,ss} " ,
JSON_CPACK ( txn_val , " {ss,ss} " ,
" hash " , hash , " data " , txn - > data ) ;
" hash " , hash , " data " , txn - > data ) ;
json_array_append_new ( txn_array , txn_val ) ;
json_array_append_new ( txn_array , txn_val ) ;
}
}
ck_runlock ( & sdata - > workbase_lock ) ;
ck_wunlock ( & sdata - > workbase_lock ) ;
if ( likely ( txn_val ) )
continue ;
/* See if we can find it in our local bitcoind */
data = generator_get_txn ( ckp , hash ) ;
if ( ! data ) {
ret = false ;
continue ;
}
/* We've found it, let's add it to the table */
ck_wlock ( & sdata - > workbase_lock ) ;
/* One last check in case it got added while we dropped the lock */
HASH_FIND_STR ( sdata - > txns , hash , txn ) ;
if ( likely ( ! txn ) ) {
txn = ckzalloc ( sizeof ( txntable_t ) ) ;
memcpy ( txn - > hash , hash , 65 ) ;
txn - > data = data ;
txn - > refcount = REFCOUNT_REMOTE ;
HASH_ADD_STR ( sdata - > txns , hash , txn ) ;
} else {
txn_val = json_string ( hash ) ;
json_array_append_new ( missing_txns , txn_val ) ;
ret = false ;
free ( data ) ;
}
ck_wunlock ( & sdata - > workbase_lock ) ;
}
if ( ret ) {
if ( ret ) {
LOGINFO ( " Rebuilt txns into workbase with %d transactions " , ( int ) i ) ;
LOGINFO ( " Rebuilt txns into workbase with %d transactions " , ( int ) i ) ;