@ -327,7 +327,7 @@ P2PServer* SideChain::p2pServer() const
return m_pool ? m_pool - > p2p_server ( ) : nullptr ;
}
bool SideChain : : get_shares ( const PoolBlock * tip , std : : vector < MinerShare > & shares , bool quiet ) const
bool SideChain : : get_shares ( const PoolBlock * tip , std : : vector < MinerShare > & shares , uint64_t* bottom_height , bool quiet ) const
{
if ( tip - > m_txkeySecSeed . empty ( ) ) {
LOGERR ( 1 , " tx key seed is not set, fix the code! " ) ;
@ -432,6 +432,10 @@ bool SideChain::get_shares(const PoolBlock* tip, std::vector<MinerShare>& shares
cur = it - > second ;
} while ( true ) ;
if ( bottom_height ) {
* bottom_height = cur - > m_sidechainHeight ;
}
shares . assign ( shares_set . begin ( ) , shares_set . end ( ) ) ;
std : : sort ( shares . begin ( ) , shares . end ( ) , [ ] ( const auto & a , const auto & b ) { return * a . m_wallet < * b . m_wallet ; } ) ;
@ -878,7 +882,7 @@ bool SideChain::get_outputs_blob(PoolBlock* block, uint64_t total_reward, std::v
void SideChain : : print_status ( bool obtain_sidechain_lock ) const
{
std: : vector < hash > blocks_in_window ;
unordered_set < hash > blocks_in_window ;
blocks_in_window . reserve ( m_chainWindowSize * 9 / 8 ) ;
const difficulty_type diff = difficulty ( ) ;
@ -886,51 +890,58 @@ void SideChain::print_status(bool obtain_sidechain_lock) const
if ( obtain_sidechain_lock ) uv_rwlock_rdlock ( & m_sidechainLock ) ;
ON_SCOPE_LEAVE ( [ this , obtain_sidechain_lock ] ( ) { if ( obtain_sidechain_lock ) uv_rwlock_rdunlock ( & m_sidechainLock ) ; } ) ;
uint64_t rem ;
uint64_t pool_hashrate = udiv128 ( diff . hi , diff . lo , m_targetBlockTime , & rem ) ;
const uint64_t pool_hashrate = ( diff / m_targetBlockTime ) . lo ;
difficulty_type network_diff = m_pool - > miner_data ( ) . difficulty ;
uint64_t network_hashrate = udiv128 ( network_diff . hi , network_diff . lo , MONERO_BLOCK_TIME , & rem ) ;
const difficulty_type network_diff = m_pool - > miner_data ( ) . difficulty ;
const uint64_t network_hashrate = ( network_diff / MONERO_BLOCK_TIME ) . lo ;
const PoolBlock * tip = m_chainTip ;
std : : vector < MinerShare > shares ;
uint64_t bottom_height = 0 ;
get_shares ( tip , shares , & bottom_height , true ) ;
const uint64_t window_size = bottom_height ? ( tip - > m_sidechainHeight - bottom_height + 1U ) : m_chainWindowSize ;
uint64_t block_depth = 0 ;
const PoolBlock * cur = tip ;
const uint64_t tip_height = tip ? tip - > m_sidechainHeight : 0 ;
uint32_t total_blocks_in_window = 0 ;
uint32_t total_uncles_in_window = 0 ;
uint64_t total_blocks_in_window = 0 ;
uint64_t total_uncles_in_window = 0 ;
// each dot corresponds to window_size / 30 shares, with current values, 2160 / 30 = 72
std : : array < uint64_t , 30 > our_blocks_in_window { } ;
std : : array < uint64_t , 30 > our_uncles_in_window { } ;
// each dot corresponds to m_chainWindowSize / 30 shares, with current values, 2160 / 30 = 72
std : : array < uint32_t , 30 > our_blocks_in_window { } ;
std : : array < uint32_t , 30 > our_uncles_in_window { } ;
const Wallet & w = m_pool - > params ( ) . m_wallet ;
while ( cur ) {
blocks_in_window . emplace _back ( cur - > m_sidechainId ) ;
blocks_in_window . emplace ( cur - > m_sidechainId ) ;
+ + total_blocks_in_window ;
if ( cur - > m_minerWallet = = m_pool- > params ( ) . m_ wallet ) {
if ( cur - > m_minerWallet = = w) {
// this produces an integer division with quotient rounded up, avoids non-whole divisions from overflowing on total_blocks_in_window
const size_t window_index = ( total_blocks_in_window - 1 ) / ( ( m_chainWindowS ize + our_blocks_in_window . size ( ) - 1 ) / our_blocks_in_window . size ( ) ) ;
our_blocks_in_window [ std : : min ( window_index , our_blocks_in_window . size ( ) - 1 ) ] + + ; // clamp window_index, even if total_blocks_in_window is not larger than m_chainWindowS ize
const size_t window_index = ( total_blocks_in_window - 1 ) / ( ( window_s ize + our_blocks_in_window . size ( ) - 1 ) / our_blocks_in_window . size ( ) ) ;
our_blocks_in_window [ std : : min ( window_index , our_blocks_in_window . size ( ) - 1 ) ] + + ; // clamp window_index, even if total_blocks_in_window is not larger than window_s ize
}
+ + block_depth ;
if ( block_depth > = m_chainWindowS ize) {
if ( block_depth > = window_s ize) {
break ;
}
for ( const hash & uncle_id : cur - > m_uncles ) {
blocks_in_window . emplace _back ( uncle_id ) ;
blocks_in_window . emplace ( uncle_id ) ;
auto it = m_blocksById . find ( uncle_id ) ;
if ( it ! = m_blocksById . end ( ) ) {
PoolBlock * uncle = it - > second ;
if ( tip_height - uncle - > m_sidechainHeight < m_chainWindowS ize) {
if ( tip_height - uncle - > m_sidechainHeight < window_s ize) {
+ + total_uncles_in_window ;
if ( uncle - > m_minerWallet = = m_pool- > params ( ) . m_ wallet ) {
if ( uncle - > m_minerWallet = = w) {
// this produces an integer division with quotient rounded up, avoids non-whole divisions from overflowing on total_blocks_in_window
const size_t window_index = ( total_blocks_in_window - 1 ) / ( ( m_chainWindowS ize + our_uncles_in_window . size ( ) - 1 ) / our_uncles_in_window . size ( ) ) ;
our_uncles_in_window [ std : : min ( window_index , our_uncles_in_window . size ( ) - 1 ) ] + + ; // clamp window_index, even if total_blocks_in_window is not larger than m_chainWindowS ize
const size_t window_index = ( total_blocks_in_window - 1 ) / ( ( window_s ize + our_uncles_in_window . size ( ) - 1 ) / our_uncles_in_window . size ( ) ) ;
our_uncles_in_window [ std : : min ( window_index , our_uncles_in_window . size ( ) - 1 ) ] + + ; // clamp window_index, even if total_blocks_in_window is not larger than window_s ize
}
}
}
@ -942,65 +953,50 @@ void SideChain::print_status(bool obtain_sidechain_lock) const
uint64_t total_orphans = 0 ;
uint64_t our_orphans = 0 ;
uint64_t your_reward = 0 ;
uint64_t total_reward = 0 ;
if ( tip ) {
std : : sort ( blocks_in_window . begin ( ) , blocks_in_window . end ( ) ) ;
for ( uint64_t i = 0 ; ( i < m_chainWindowSize ) & & ( i < = tip_height ) ; + + i ) {
for ( uint64_t i = 0 ; ( i < window_size ) & & ( i < = tip_height ) ; + + i ) {
auto it = m_blocksByHeight . find ( tip_height - i ) ;
if ( it = = m_blocksByHeight . end ( ) ) {
continue ;
}
for ( const PoolBlock * block : it - > second ) {
if ( ! std : : binary_search ( blocks_in_window . begin ( ) , blocks_in_window . end ( ) , block - > m_sidechainId ) ) {
if ( blocks_in_window . find ( block - > m_sidechainId ) = = blocks_in_window . end ( ) ) {
LOGINFO ( 4 , " orphan block at height " < < log : : Gray ( ) < < block - > m_sidechainHeight < < log : : NoColor ( ) < < " : " < < log : : Gray ( ) < < block - > m_sidechainId ) ;
+ + total_orphans ;
if ( block - > m_minerWallet = = m_pool- > params ( ) . m_ wallet ) {
if ( block - > m_minerWallet = = w) {
+ + our_orphans ;
}
}
}
}
}
const Wallet & w = m_pool - > params ( ) . m_wallet ;
const uint8_t tx_type = tip - > get_tx_type ( ) ;
hash eph_public_key ;
for ( size_t i = 0 , n = tip - > m_outputs . size ( ) ; i < n ; + + i ) {
const PoolBlock : : TxOutput & out = tip - > m_outputs [ i ] ;
if ( ! your_reward ) {
if ( tx_type = = TXOUT_TO_TAGGED_KEY ) {
uint8_t view_tag ;
const uint8_t expected_view_tag = out . m_viewTag ;
if ( w . get_eph_public_key ( tip - > m_txkeySec , i , eph_public_key , view_tag , & expected_view_tag ) & & ( out . m_ephPublicKey = = eph_public_key ) ) {
your_reward = out . m_reward ;
}
}
else {
uint8_t view_tag ;
if ( w . get_eph_public_key ( tip - > m_txkeySec , i , eph_public_key , view_tag ) & & ( out . m_ephPublicKey = = eph_public_key ) ) {
your_reward = out . m_reward ;
}
}
}
total_reward + = out . m_reward ;
difficulty_type your_shares_weight , pplns_weight ;
for ( const MinerShare & s : shares ) {
if ( * s . m_wallet = = w ) {
your_shares_weight = s . m_weight ;
}
pplns_weight + = s . m_weight ;
}
uint64_t product [ 2 ] ;
product [ 0 ] = umul128 ( pool_hashrate , your_reward , & product [ 1 ] ) ;
const uint64_t hashrate_est = total_reward ? udiv128 ( product [ 1 ] , product [ 0 ] , total_reward , & rem ) : 0 ;
if ( pplns_weight = = 0 ) {
pplns_weight = m_minDifficulty ;
}
const uint64_t total_reward = m_pool - > block_template ( ) . get_reward ( ) ;
const uint64_t your_reward = ( ( your_shares_weight * total_reward ) / pplns_weight ) . lo ;
const uint64_t hashrate_est = ( ( your_shares_weight * pool_hashrate ) / pplns_weight ) . lo ;
const double block_share = total_reward ? ( ( static_cast < double > ( your_reward ) * 100.0 ) / static_cast < double > ( total_reward ) ) : 0.0 ;
const uint32_t our_blocks_in_window_total = std : : accumulate ( our_blocks_in_window . begin ( ) , our_blocks_in_window . end ( ) , 0U ) ;
const uint32_t our_uncles_in_window_total = std : : accumulate ( our_uncles_in_window . begin ( ) , our_uncles_in_window . end ( ) , 0U ) ;
const uint64_t our_blocks_in_window_total = std : : accumulate ( our_blocks_in_window . begin ( ) , our_blocks_in_window . end ( ) , 0ULL ) ;
const uint64_t our_uncles_in_window_total = std : : accumulate ( our_uncles_in_window . begin ( ) , our_uncles_in_window . end ( ) , 0ULL ) ;
std : : string our_blocks_in_window_chart ;
if ( our_blocks_in_window_total ) {
our_blocks_in_window_chart . reserve ( our_blocks_in_window . size ( ) + 32 ) ;
our_blocks_in_window_chart = " \n Your shares position = [ " ;
for ( uint 32 _t p : our_blocks_in_window ) {
for ( uint 64 _t p : our_blocks_in_window ) {
our_blocks_in_window_chart + = ( p ? ( ( p > 9 ) ? ' + ' : static_cast < char > ( ' 0 ' + p ) ) : ' . ' ) ;
}
our_blocks_in_window_chart + = ' ] ' ;
@ -1010,7 +1006,7 @@ void SideChain::print_status(bool obtain_sidechain_lock) const
if ( our_uncles_in_window_total ) {
our_uncles_in_window_chart . reserve ( our_uncles_in_window . size ( ) + 32 ) ;
our_uncles_in_window_chart = " \n Your uncles position = [ " ;
for ( uint 32 _t p : our_uncles_in_window ) {
for ( uint 64 _t p : our_uncles_in_window ) {
our_uncles_in_window_chart + = ( p ? ( ( p > 9 ) ? ' + ' : static_cast < char > ( ' 0 ' + p ) ) : ' . ' ) ;
}
our_uncles_in_window_chart + = ' ] ' ;
@ -1024,7 +1020,8 @@ void SideChain::print_status(bool obtain_sidechain_lock) const
" \n Side chain hashrate = " < < log : : Hashrate ( pool_hashrate ) < <
( hashrate_est ? " \n Your hashrate (pool-side) = " : " " ) < < ( hashrate_est ? log : : Hashrate ( hashrate_est ) : log : : Hashrate ( ) ) < <
" \n PPLNS window = " < < total_blocks_in_window < < " blocks (+ " < < total_uncles_in_window < < " uncles, " < < total_orphans < < " orphans) " < <
" \n Your wallet address = " < < m_pool - > params ( ) . m_wallet < <
" \n PPLNS window duration = " < < log : : Duration ( ( pplns_weight / pool_hashrate ) . lo ) < <
" \n Your wallet address = " < < w < <
" \n Your shares = " < < our_blocks_in_window_total < < " blocks (+ " < < our_uncles_in_window_total < < " uncles, " < < our_orphans < < " orphans) "
< < our_blocks_in_window_chart < < our_uncles_in_window_chart < <
" \n Block reward share = " < < block_share < < " % ( " < < log : : XMRAmount ( your_reward ) < < ' ) '
@ -2130,7 +2127,7 @@ void SideChain::launch_precalc(const PoolBlock* block)
continue ;
}
std : : vector < MinerShare > shares ;
if ( get_shares ( b , shares , true ) ) {
if ( get_shares ( b , shares , nullptr , true ) ) {
b - > m_precalculated = true ;
PrecalcJob * job = new PrecalcJob { b , std : : move ( shares ) } ;
{