diff --git a/src/pool_block.cpp b/src/pool_block.cpp index 57e5102..25b86fe 100644 --- a/src/pool_block.cpp +++ b/src/pool_block.cpp @@ -412,6 +412,26 @@ uint64_t PoolBlock::get_payout(const Wallet& w) const return 0; } +static constexpr uint64_t VERSION2_MAINNET_TIMESTAMP = 1679173200U; // 2023-03-18 21:00 UTC +static constexpr uint64_t VERSION2_TESTNET_TIMESTAMP = 1674334800U; // 2023-01-21 21:00 UTC + +uint32_t PoolBlock::signal_v2_readiness(uint32_t extra_nonce) +{ + const uint64_t ts = (SideChain::network_type() == NetworkType::Mainnet) ? VERSION2_MAINNET_TIMESTAMP : VERSION2_TESTNET_TIMESTAMP; + if (time(nullptr) < static_cast(ts)) { + extra_nonce |= 0xFF000000UL; + extra_nonce &= ~0x00100000UL; + return extra_nonce; + } + return extra_nonce; +} + +int PoolBlock::get_sidechain_version() const +{ + const uint64_t ts = (SideChain::network_type() == NetworkType::Mainnet) ? VERSION2_MAINNET_TIMESTAMP : VERSION2_TESTNET_TIMESTAMP; + return (m_timestamp >= ts) ? 2 : 1; +} + hash PoolBlock::calculate_tx_key_seed() const { const char domain[] = "tx_key_seed"; diff --git a/src/pool_block.h b/src/pool_block.h index 8a1d1fd..e14f799 100644 --- a/src/pool_block.h +++ b/src/pool_block.h @@ -152,27 +152,11 @@ struct PoolBlock // but P2Pool can switch to using only TXOUT_TO_TAGGED_KEY for miner payouts starting from v15 FORCEINLINE uint8_t get_tx_type() const { return (m_majorVersion < HARDFORK_VIEW_TAGS_VERSION) ? TXOUT_TO_KEY : TXOUT_TO_TAGGED_KEY; } - static constexpr int VERSION2_TIMESTAMP = 1679173200; - // Signal hardfork readiness (only before the v2 hardfork) // TODO: remove this code after hardfork - FORCEINLINE static uint32_t signal_v2_readiness(uint32_t extra_nonce) - { - if (time(nullptr) < PoolBlock::VERSION2_TIMESTAMP) { - extra_nonce |= 0xFF000000UL; - extra_nonce &= ~0x00100000UL; - return extra_nonce; - } - return extra_nonce; - } + static uint32_t signal_v2_readiness(uint32_t extra_nonce); - FORCEINLINE int get_sidechain_version() const - { - // P2Pool forks to v2 at 2023-03-18 21:00 UTC - // Different miners can have different timestamps, - // so a temporary mix of v1 and v2 blocks is allowed - return (m_timestamp >= VERSION2_TIMESTAMP) ? 2 : 1; - } + int get_sidechain_version() const; typedef std::array full_id; diff --git a/src/side_chain.cpp b/src/side_chain.cpp index 5c229dc..a7de420 100644 --- a/src/side_chain.cpp +++ b/src/side_chain.cpp @@ -54,9 +54,10 @@ namespace p2pool { static constexpr uint8_t default_consensus_id[HASH_SIZE] = { 34,175,126,231,181,11,104,146,227,153,218,107,44,108,68,39,178,81,4,212,169,4,142,0,177,110,157,240,68,7,249,24 }; static constexpr uint8_t mini_consensus_id[HASH_SIZE] = { 57,130,201,26,149,174,199,250,66,80,189,18,108,216,194,220,136,23,63,24,64,113,221,44,219,86,39,163,53,24,126,196 }; +NetworkType SideChain::s_networkType = NetworkType::Invalid; + SideChain::SideChain(p2pool* pool, NetworkType type, const char* pool_name) : m_pool(pool) - , m_networkType(type) , m_chainTip{ nullptr } , m_seenWalletsLastPruneTime(0) , m_poolName(pool_name ? pool_name : "default") @@ -67,7 +68,15 @@ SideChain::SideChain(p2pool* pool, NetworkType type, const char* pool_name) , m_curDifficulty(m_minDifficulty) , m_precalcFinished(false) { - LOGINFO(1, log::LightCyan() << "network type = " << m_networkType); + if (s_networkType == NetworkType::Invalid) { + s_networkType = type; + } + else if (s_networkType != type) { + LOGERR(1, "can't run both " << s_networkType << " and " << type << " at the same time"); + PANIC_STOP(); + } + + LOGINFO(1, log::LightCyan() << "network type = " << type); if (m_pool && !load_config(m_pool->params().m_config)) { PANIC_STOP(); @@ -89,7 +98,7 @@ SideChain::SideChain(p2pool* pool, NetworkType type, const char* pool_name) char buf[log::Stream::BUF_SIZE + 1]; log::Stream s(buf); - s << m_networkType << '\0' + s << s_networkType << '\0' << m_poolName << '\0' << m_poolPassword << '\0' << m_targetBlockTime << '\0' @@ -201,6 +210,8 @@ SideChain::~SideChain() for (const auto& it : m_blocksById) { delete it.second; } + + s_networkType = NetworkType::Invalid; } void SideChain::fill_sidechain_data(PoolBlock& block, std::vector& shares) const @@ -1018,12 +1029,12 @@ double SideChain::get_reward_share(const Wallet& w) const return total_reward ? (static_cast(reward) / static_cast(total_reward)) : 0.0; } -uint64_t SideChain::network_major_version(uint64_t height) const +uint64_t SideChain::network_major_version(uint64_t height) { const hardfork_t* hard_forks; size_t num_hard_forks; - switch (m_networkType) + switch (s_networkType) { case NetworkType::Mainnet: default: diff --git a/src/side_chain.h b/src/side_chain.h index 0d152b0..395839c 100644 --- a/src/side_chain.h +++ b/src/side_chain.h @@ -66,8 +66,8 @@ public: // Consensus ID can therefore be used as a password to create private P2Pools const std::vector& consensus_id() const { return m_consensusId; } uint64_t chain_window_size() const { return m_chainWindowSize; } - NetworkType network_type() const { return m_networkType; } - uint64_t network_major_version(uint64_t height) const; + static NetworkType network_type() { return s_networkType; } + static uint64_t network_major_version(uint64_t height); FORCEINLINE difficulty_type difficulty() const { ReadLock lock(m_curDifficultyLock); return m_curDifficulty; } difficulty_type total_hashes() const; uint64_t block_time() const { return m_targetBlockTime; } @@ -88,7 +88,7 @@ public: private: p2pool* m_pool; P2PServer* p2pServer() const; - NetworkType m_networkType; + static NetworkType s_networkType; private: bool get_shares(const PoolBlock* tip, std::vector& shares, uint64_t* bottom_height = nullptr, bool quiet = false) const;