mirror of
https://github.com/SChernykh/p2pool.git
synced 2024-11-17 08:17:55 +00:00
BlockTemplate code refactoring
- Moved block constants to one place - Tuned block template max transaction limiter
This commit is contained in:
parent
44d2005ab1
commit
8bf045974f
5 changed files with 41 additions and 21 deletions
|
@ -34,9 +34,6 @@
|
||||||
|
|
||||||
static constexpr char log_category_prefix[] = "BlockTemplate ";
|
static constexpr char log_category_prefix[] = "BlockTemplate ";
|
||||||
|
|
||||||
// Max P2P message size (128 KB) minus BLOCK_RESPONSE header (5 bytes)
|
|
||||||
static constexpr size_t MAX_BLOCK_TEMPLATE_SIZE = 128 * 1024 - (1 + sizeof(uint32_t));
|
|
||||||
|
|
||||||
namespace p2pool {
|
namespace p2pool {
|
||||||
|
|
||||||
BlockTemplate::BlockTemplate(SideChain* sidechain, RandomX_Hasher_Base* hasher)
|
BlockTemplate::BlockTemplate(SideChain* sidechain, RandomX_Hasher_Base* hasher)
|
||||||
|
@ -168,9 +165,7 @@ BlockTemplate& BlockTemplate::operator=(const BlockTemplate& b)
|
||||||
static FORCEINLINE uint64_t get_base_reward(uint64_t already_generated_coins)
|
static FORCEINLINE uint64_t get_base_reward(uint64_t already_generated_coins)
|
||||||
{
|
{
|
||||||
const uint64_t result = ~already_generated_coins >> 19;
|
const uint64_t result = ~already_generated_coins >> 19;
|
||||||
|
return (result < BASE_BLOCK_REWARD) ? BASE_BLOCK_REWARD : result;
|
||||||
constexpr uint64_t min_reward = 600000000000ULL;
|
|
||||||
return (result < min_reward) ? min_reward : result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static FORCEINLINE uint64_t get_block_reward(uint64_t base_reward, uint64_t median_weight, uint64_t fees, uint64_t weight)
|
static FORCEINLINE uint64_t get_block_reward(uint64_t base_reward, uint64_t median_weight, uint64_t fees, uint64_t weight)
|
||||||
|
@ -353,14 +348,27 @@ void BlockTemplate::update(const MinerData& data, const Mempool& mempool, const
|
||||||
b->m_transactions.resize(1);
|
b->m_transactions.resize(1);
|
||||||
b->m_outputs.clear();
|
b->m_outputs.clear();
|
||||||
|
|
||||||
// Block template size without coinbase outputs and transactions (add 1+1 more bytes for output and tx count if they go above 128)
|
// Block template size without coinbase outputs and transactions (minus 2 bytes for output and tx count dummy varints)
|
||||||
size_t k = b->serialize_mainchain_data().size() + b->serialize_sidechain_data().size() + 2;
|
size_t k = b->serialize_mainchain_data().size() + b->serialize_sidechain_data().size() - 2;
|
||||||
|
|
||||||
// a rough estimation of outputs' size
|
// Add output and tx count real varints
|
||||||
// all outputs have <= 5 bytes for each output's reward, and up to 18 outputs can have 6 bytes for output's reward
|
writeVarint(m_shares.size(), [&k](uint8_t) { ++k; });
|
||||||
k += m_shares.size() * (5 /* reward */ + 1 /* tx_type */ + HASH_SIZE /* stealth address */ + 1 /* viewtag */) + 18;
|
writeVarint(m_mempoolTxs.size(), [&k](uint8_t) { ++k; });
|
||||||
|
|
||||||
const size_t max_transactions = (MAX_BLOCK_TEMPLATE_SIZE > k) ? ((MAX_BLOCK_TEMPLATE_SIZE - k) / HASH_SIZE) : 0;
|
// Add a rough upper bound estimation of outputs' size. All outputs have <= 5 bytes for each output's reward (< 0.034359738368 XMR per output)
|
||||||
|
k += m_shares.size() * (5 /* reward */ + 1 /* tx_type */ + HASH_SIZE /* stealth address */ + 1 /* viewtag */);
|
||||||
|
|
||||||
|
// >= 0.034359738368 XMR is required for a 6 byte varint, add 1 byte per each potential 6-byte varint
|
||||||
|
{
|
||||||
|
uint64_t r = BASE_BLOCK_REWARD;
|
||||||
|
for (const auto& tx : m_mempoolTxs) {
|
||||||
|
r += tx.fee;
|
||||||
|
}
|
||||||
|
k += r / 34359738368ULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t max_transactions = (MAX_BLOCK_SIZE > k) ? ((MAX_BLOCK_SIZE - k) / HASH_SIZE) : 0;
|
||||||
|
LOGINFO(6, max_transactions << " transactions can be taken with current block size limit");
|
||||||
|
|
||||||
if (max_transactions == 0) {
|
if (max_transactions == 0) {
|
||||||
m_mempoolTxs.clear();
|
m_mempoolTxs.clear();
|
||||||
|
@ -678,6 +686,7 @@ void BlockTemplate::update(const MinerData& data, const Mempool& mempool, const
|
||||||
|
|
||||||
m_fullDataBlob = m_blockTemplateBlob;
|
m_fullDataBlob = m_blockTemplateBlob;
|
||||||
m_fullDataBlob.insert(m_fullDataBlob.end(), sidechain_data.begin(), sidechain_data.end());
|
m_fullDataBlob.insert(m_fullDataBlob.end(), sidechain_data.begin(), sidechain_data.end());
|
||||||
|
LOGINFO(6, "blob size = " << m_fullDataBlob.size());
|
||||||
|
|
||||||
m_poolBlockTemplate->m_sidechainId = calc_sidechain_hash(0);
|
m_poolBlockTemplate->m_sidechainId = calc_sidechain_hash(0);
|
||||||
|
|
||||||
|
@ -705,9 +714,6 @@ void BlockTemplate::update(const MinerData& data, const Mempool& mempool, const
|
||||||
if (result != 0) {
|
if (result != 0) {
|
||||||
LOGERR(1, "pool block blob generation and/or parsing is broken, error " << result);
|
LOGERR(1, "pool block blob generation and/or parsing is broken, error " << result);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
LOGINFO(6, "blob size = " << m_fullDataBlob.size());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(m_minerTxKeccakState, 0, sizeof(m_minerTxKeccakState));
|
memset(m_minerTxKeccakState, 0, sizeof(m_minerTxKeccakState));
|
||||||
|
|
|
@ -61,8 +61,7 @@ P2PServer::P2PServer(p2pool* pool)
|
||||||
, m_fastestPeer(nullptr)
|
, m_fastestPeer(nullptr)
|
||||||
{
|
{
|
||||||
m_callbackBuf.resize(P2P_BUF_SIZE);
|
m_callbackBuf.resize(P2P_BUF_SIZE);
|
||||||
|
m_blockDeserializeBuf.reserve(MAX_BLOCK_SIZE);
|
||||||
m_blockDeserializeBuf.reserve(131072);
|
|
||||||
|
|
||||||
// Diffuse the initial state in case it has low quality
|
// Diffuse the initial state in case it has low quality
|
||||||
m_rng.discard(10000);
|
m_rng.discard(10000);
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "tcp_server.h"
|
#include "tcp_server.h"
|
||||||
|
#include "pool_block.h"
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
namespace p2pool {
|
namespace p2pool {
|
||||||
|
@ -26,7 +27,10 @@ class p2pool;
|
||||||
struct PoolBlock;
|
struct PoolBlock;
|
||||||
class BlockCache;
|
class BlockCache;
|
||||||
|
|
||||||
static constexpr size_t P2P_BUF_SIZE = 128 * 1024;
|
// Max block size plus BLOCK_RESPONSE header (5 bytes)
|
||||||
|
static constexpr uint64_t P2P_BUF_SIZE = MAX_BLOCK_SIZE + (1 + sizeof(uint32_t));
|
||||||
|
static_assert((P2P_BUF_SIZE & (P2P_BUF_SIZE - 1)) == 0, "P2P_BUF_SIZE is not a power of 2, fix MAX_BLOCK_SIZE");
|
||||||
|
|
||||||
static constexpr size_t PEER_LIST_RESPONSE_MAX_PEERS = 16;
|
static constexpr size_t PEER_LIST_RESPONSE_MAX_PEERS = 16;
|
||||||
static constexpr int DEFAULT_P2P_PORT = 37889;
|
static constexpr int DEFAULT_P2P_PORT = 37889;
|
||||||
static constexpr int DEFAULT_P2P_PORT_MINI = 37888;
|
static constexpr int DEFAULT_P2P_PORT_MINI = 37888;
|
||||||
|
|
|
@ -47,6 +47,12 @@ class SideChain;
|
||||||
* Pool block's PoW hash is calculated from the Monero block template part using Monero's consensus rules
|
* Pool block's PoW hash is calculated from the Monero block template part using Monero's consensus rules
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// 128 KB minus BLOCK_RESPONSE P2P protocol header (5 bytes)
|
||||||
|
static constexpr uint64_t MAX_BLOCK_SIZE = 128 * 1024 - 5;
|
||||||
|
|
||||||
|
// 0.6 XMR
|
||||||
|
static constexpr uint64_t BASE_BLOCK_REWARD = 600000000000ULL;
|
||||||
|
|
||||||
struct DifficultyData
|
struct DifficultyData
|
||||||
{
|
{
|
||||||
FORCEINLINE DifficultyData(uint64_t t, const difficulty_type& d) : m_timestamp(t), m_cumulativeDifficulty(d) {}
|
FORCEINLINE DifficultyData(uint64_t t, const difficulty_type& d) : m_timestamp(t), m_cumulativeDifficulty(d) {}
|
||||||
|
|
|
@ -27,7 +27,7 @@ int PoolBlock::deserialize(const uint8_t* data, size_t size, const SideChain& si
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
// Sanity check
|
// Sanity check
|
||||||
if (!data || (size > 128 * 1024)) {
|
if (!data || (size > MAX_BLOCK_SIZE)) {
|
||||||
return __LINE__;
|
return __LINE__;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,7 +139,7 @@ int PoolBlock::deserialize(const uint8_t* data, size_t size, const SideChain& si
|
||||||
READ_VARINT(tmp);
|
READ_VARINT(tmp);
|
||||||
|
|
||||||
// Sanity check
|
// Sanity check
|
||||||
if ((tmp == 0) || (tmp > 128 * 1024)) {
|
if ((tmp == 0) || (tmp > MAX_BLOCK_SIZE)) {
|
||||||
return __LINE__;
|
return __LINE__;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,7 +148,7 @@ int PoolBlock::deserialize(const uint8_t* data, size_t size, const SideChain& si
|
||||||
|
|
||||||
// Technically some p2pool node could keep stuffing block with transactions until reward is less than 0.6 XMR
|
// Technically some p2pool node could keep stuffing block with transactions until reward is less than 0.6 XMR
|
||||||
// But default transaction picking algorithm never does that. It's better to just ban such nodes
|
// But default transaction picking algorithm never does that. It's better to just ban such nodes
|
||||||
if (total_reward < 600000000000ULL) {
|
if (total_reward < BASE_BLOCK_REWARD) {
|
||||||
return __LINE__;
|
return __LINE__;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -341,6 +341,11 @@ int PoolBlock::deserialize(const uint8_t* data, size_t size, const SideChain& si
|
||||||
hash check;
|
hash check;
|
||||||
const std::vector<uint8_t>& consensus_id = sidechain.consensus_id();
|
const std::vector<uint8_t>& consensus_id = sidechain.consensus_id();
|
||||||
const int data_size = static_cast<int>((data_end - data_begin) + outputs_blob_size_diff + transactions_blob_size_diff);
|
const int data_size = static_cast<int>((data_end - data_begin) + outputs_blob_size_diff + transactions_blob_size_diff);
|
||||||
|
|
||||||
|
if (data_size > static_cast<int>(MAX_BLOCK_SIZE)) {
|
||||||
|
return __LINE__;
|
||||||
|
}
|
||||||
|
|
||||||
keccak_custom(
|
keccak_custom(
|
||||||
[nonce_offset, extra_nonce_offset, sidechain_hash_offset, data_begin, data_size, &consensus_id, &outputs_blob, outputs_blob_size_diff, outputs_offset, outputs_blob_size, transactions_blob, transactions_blob_size_diff, transactions_offset, transactions_blob_size](int offset) -> uint8_t
|
[nonce_offset, extra_nonce_offset, sidechain_hash_offset, data_begin, data_size, &consensus_id, &outputs_blob, outputs_blob_size_diff, outputs_offset, outputs_blob_size, transactions_blob, transactions_blob_size_diff, transactions_offset, transactions_blob_size](int offset) -> uint8_t
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue