mirror of
https://github.com/monero-project/monero.git
synced 2026-06-12 11:01:34 -07:00
Blockchain: option for fast manual block popping
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2014-2024, The Monero Project
|
||||
// Copyright (c) 2014-2026, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
@@ -172,13 +172,6 @@ void BlockchainDB::init_options(boost::program_options::options_description& des
|
||||
command_line::add_arg(desc, arg_db_salvage);
|
||||
}
|
||||
|
||||
void BlockchainDB::pop_block()
|
||||
{
|
||||
block blk;
|
||||
std::vector<transaction> txs;
|
||||
pop_block(blk, txs);
|
||||
}
|
||||
|
||||
void BlockchainDB::add_transaction(const crypto::hash& blk_hash, const transaction& tx, const epee::span<const std::uint8_t> blob, const crypto::hash* tx_hash_ptr, const crypto::hash* tx_prunable_hash_ptr)
|
||||
{
|
||||
bool miner_tx = false;
|
||||
@@ -311,7 +304,7 @@ void BlockchainDB::set_hard_fork(HardFork* hf)
|
||||
m_hardfork = hf;
|
||||
}
|
||||
|
||||
void BlockchainDB::pop_block(block& blk, std::vector<transaction>& txs)
|
||||
void BlockchainDB::pop_block(block& blk, std::vector<transaction>* txs)
|
||||
{
|
||||
blk = get_top_block();
|
||||
|
||||
@@ -319,10 +312,13 @@ void BlockchainDB::pop_block(block& blk, std::vector<transaction>& txs)
|
||||
|
||||
for (const auto& h : boost::adaptors::reverse(blk.tx_hashes))
|
||||
{
|
||||
cryptonote::transaction tx;
|
||||
if (!get_tx(h, tx) && !get_pruned_tx(h, tx))
|
||||
throw DB_ERROR("Failed to get pruned or unpruned transaction from the db");
|
||||
txs.push_back(std::move(tx));
|
||||
if (txs)
|
||||
{
|
||||
cryptonote::transaction tx;
|
||||
if (!get_tx(h, tx) && !get_pruned_tx(h, tx))
|
||||
throw DB_ERROR("Failed to get pruned or unpruned transaction from the db");
|
||||
txs->push_back(std::move(tx));
|
||||
}
|
||||
remove_transaction(h);
|
||||
}
|
||||
remove_transaction(get_transaction_hash(blk.miner_tx));
|
||||
@@ -481,8 +477,9 @@ void BlockchainDB::fixup()
|
||||
if (!has_key_image(ki))
|
||||
{
|
||||
LOG_PRINT_L1("Fixup: detected missing key images from block 202612! Popping blocks...");
|
||||
block blk;
|
||||
while (height() > 202612)
|
||||
pop_block();
|
||||
pop_block(blk, /*txs=*/nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2014-2024, The Monero Project
|
||||
// Copyright (c) 2014-2026, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
@@ -538,13 +538,6 @@ private:
|
||||
/*********************************************************************
|
||||
* private concrete members
|
||||
*********************************************************************/
|
||||
/**
|
||||
* @brief private version of pop_block, for undoing if an add_block fails
|
||||
*
|
||||
* This function simply calls pop_block(block& blk, std::vector<transaction>& txs)
|
||||
* with dummy parameters, as the returns-by-reference can be discarded.
|
||||
*/
|
||||
void pop_block();
|
||||
|
||||
// helper function to remove transaction from blockchain
|
||||
/**
|
||||
@@ -1151,13 +1144,12 @@ public:
|
||||
* implements remove_* functions.
|
||||
*
|
||||
* The subclass should return by reference the popped block and
|
||||
* its associated transactions
|
||||
* its associated transactions, if applicable to that overload
|
||||
*
|
||||
* @param blk return-by-reference the block which was popped
|
||||
* @param txs return-by-reference the transactions from the popped block
|
||||
* @param[out] blk the block which was popped
|
||||
* @param[out] txs the non-coinbase transactions from the popped block (optional)
|
||||
*/
|
||||
virtual void pop_block(block& blk, std::vector<transaction>& txs);
|
||||
|
||||
virtual void pop_block(block& blk, std::vector<transaction>* txs);
|
||||
|
||||
/**
|
||||
* @brief check if a transaction with a given hash exists
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2014-2024, The Monero Project
|
||||
// Copyright (c) 2014-2026, The Monero Project
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
@@ -4157,7 +4157,7 @@ uint64_t BlockchainLMDB::add_block(const std::pair<block, blobdata>& blk, size_t
|
||||
return ++m_height;
|
||||
}
|
||||
|
||||
void BlockchainLMDB::pop_block(block& blk, std::vector<transaction>& txs)
|
||||
void BlockchainLMDB::pop_block(block& blk, std::vector<transaction>* txs)
|
||||
{
|
||||
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
||||
check_open();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2014-2024, The Monero Project
|
||||
// Copyright (c) 2014-2026, The Monero Project
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
@@ -342,7 +342,7 @@ public:
|
||||
|
||||
bool block_rtxn_start(MDB_txn **mtxn, mdb_txn_cursors **mcur) const;
|
||||
|
||||
void pop_block(block& blk, std::vector<transaction>& txs) override;
|
||||
void pop_block(block& blk, std::vector<transaction>* txs) override;
|
||||
|
||||
bool can_thread_bulk_indices() const override { return true; }
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2014-2024, The Monero Project
|
||||
// Copyright (c) 2014-2026, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
@@ -100,11 +100,10 @@ int pop_blocks(cryptonote::core& core, int num_blocks)
|
||||
|
||||
int quit = 0;
|
||||
block popped_block;
|
||||
std::vector<transaction> popped_txs;
|
||||
for (int i=0; i < num_blocks; ++i)
|
||||
{
|
||||
// simple_core.m_storage.pop_block_from_blockchain() is private, so call directly through db
|
||||
core.get_blockchain_storage().get_db().pop_block(popped_block, popped_txs);
|
||||
core.get_blockchain_storage().get_db().pop_block(popped_block, /*txs=*/nullptr);
|
||||
quit = 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2014-2024, The Monero Project
|
||||
// Copyright (c) 2014-2026, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
@@ -408,10 +408,9 @@ bool Blockchain::init(BlockchainDB* db, const network_type nettype, bool offline
|
||||
MGINFO("Popping blocks... " << top_height);
|
||||
++num_popped_blocks;
|
||||
block popped_block;
|
||||
std::vector<transaction> popped_txs;
|
||||
try
|
||||
{
|
||||
m_db->pop_block(popped_block, popped_txs);
|
||||
m_db->pop_block(popped_block, /*txs=*/nullptr);
|
||||
}
|
||||
// anything that could cause this to throw is likely catastrophic,
|
||||
// so we re-throw
|
||||
@@ -548,7 +547,7 @@ bool Blockchain::deinit()
|
||||
//------------------------------------------------------------------
|
||||
// This function removes blocks from the top of blockchain.
|
||||
// It starts a batch and calls private method pop_block_from_blockchain().
|
||||
void Blockchain::pop_blocks(uint64_t nblocks)
|
||||
void Blockchain::pop_blocks(uint64_t nblocks, const bool keep_txs)
|
||||
{
|
||||
uint64_t i = 0;
|
||||
CRITICAL_REGION_LOCAL(m_tx_pool);
|
||||
@@ -563,7 +562,7 @@ void Blockchain::pop_blocks(uint64_t nblocks)
|
||||
nblocks = std::min(nblocks, blockchain_height - 1);
|
||||
while (i < nblocks && !m_cancel.load())
|
||||
{
|
||||
pop_block_from_blockchain();
|
||||
pop_block_from_blockchain(keep_txs);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
@@ -588,9 +587,9 @@ void Blockchain::pop_blocks(uint64_t nblocks)
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
// This function tells BlockchainDB to remove the top block from the
|
||||
// blockchain and then returns all transactions (except the miner tx, of course)
|
||||
// from it to the tx_pool
|
||||
block Blockchain::pop_block_from_blockchain()
|
||||
// blockchain and then, if keep_txs is true, returns all transactions
|
||||
// (except the miner tx, of course) from it to the tx_pool
|
||||
block Blockchain::pop_block_from_blockchain(bool keep_txs)
|
||||
{
|
||||
LOG_PRINT_L3("Blockchain::" << __func__);
|
||||
CRITICAL_REGION_LOCAL(m_blockchain_lock);
|
||||
@@ -606,7 +605,7 @@ block Blockchain::pop_block_from_blockchain()
|
||||
const uint8_t previous_hf_version = get_current_hard_fork_version();
|
||||
try
|
||||
{
|
||||
m_db->pop_block(popped_block, popped_txs);
|
||||
m_db->pop_block(popped_block, keep_txs ? &popped_txs : nullptr);
|
||||
}
|
||||
// anything that could cause this to throw is likely catastrophic,
|
||||
// so we re-throw
|
||||
@@ -626,7 +625,7 @@ block Blockchain::pop_block_from_blockchain()
|
||||
|
||||
// return transactions from popped block to the tx_pool
|
||||
size_t pruned = 0;
|
||||
for (transaction& tx : popped_txs)
|
||||
if (keep_txs) for (transaction& tx : popped_txs)
|
||||
{
|
||||
if (tx.pruned)
|
||||
{
|
||||
@@ -1117,7 +1116,7 @@ bool Blockchain::rollback_blockchain_switching(std::list<block>& original_chain,
|
||||
// remove blocks from blockchain until we get back to where we should be.
|
||||
while (m_db->height() != rollback_height)
|
||||
{
|
||||
pop_block_from_blockchain();
|
||||
pop_block_from_blockchain(/*keep_txs=*/true);
|
||||
}
|
||||
CHECK_AND_ASSERT_THROW_MES(update_next_cumulative_weight_limit(), "Error updating next cumulative weight limit");
|
||||
|
||||
@@ -1167,7 +1166,7 @@ bool Blockchain::switch_to_alternative_blockchain(std::list<block_extended_info>
|
||||
std::list<block> disconnected_chain;
|
||||
while (m_db->top_block_hash() != alt_chain.front().bl.prev_id)
|
||||
{
|
||||
block b = pop_block_from_blockchain();
|
||||
block b = pop_block_from_blockchain(/*keep_txs=*/true);
|
||||
disconnected_chain.push_front(b);
|
||||
}
|
||||
CHECK_AND_ASSERT_THROW_MES(update_next_cumulative_weight_limit(), "Error updating next cumulative weight limit");
|
||||
@@ -4342,7 +4341,7 @@ leave:
|
||||
if (!update_next_cumulative_weight_limit())
|
||||
{
|
||||
MERROR("Failed to update next cumulative weight limit");
|
||||
pop_block_from_blockchain();
|
||||
pop_block_from_blockchain(/*keep_txs=*/true);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2014-2024, The Monero Project
|
||||
// Copyright (c) 2014-2026, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
@@ -1131,8 +1131,9 @@ namespace cryptonote
|
||||
* @brief removes blocks from the top of the blockchain
|
||||
*
|
||||
* @param nblocks number of blocks to be removed
|
||||
* @param keep_txs whether to place popped non-coinbase transactions back into the mempool
|
||||
*/
|
||||
void pop_blocks(uint64_t nblocks);
|
||||
void pop_blocks(uint64_t nblocks, bool keep_txs);
|
||||
|
||||
/**
|
||||
* @brief checks whether a given block height is included in the precompiled block hash area
|
||||
@@ -1377,9 +1378,11 @@ namespace cryptonote
|
||||
/**
|
||||
* @brief removes the most recent block from the blockchain
|
||||
*
|
||||
* @param keep_txs whether to place popped non-coinbase transactions back into the mempool
|
||||
*
|
||||
* @return the block removed
|
||||
*/
|
||||
block pop_block_from_blockchain();
|
||||
block pop_block_from_blockchain(bool keep_txs);
|
||||
|
||||
/**
|
||||
* @brief validate and add a new block to the end of the blockchain
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2014-2024, The Monero Project
|
||||
// Copyright (c) 2014-2026, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
@@ -931,9 +931,14 @@ bool t_command_parser_executor::sync_info(const std::vector<std::string>& args)
|
||||
|
||||
bool t_command_parser_executor::pop_blocks(const std::vector<std::string>& args)
|
||||
{
|
||||
if (args.size() != 1)
|
||||
if (args.size() < 1)
|
||||
{
|
||||
std::cout << "Invalid syntax: One parameter expected. For more details, use the help command." << std::endl;
|
||||
std::cout << "Invalid syntax: At least one parameter expected. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
else if (args.size() > 2)
|
||||
{
|
||||
std::cout << "Invalid syntax: A maximum of two parameters expected. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -945,7 +950,22 @@ bool t_command_parser_executor::pop_blocks(const std::vector<std::string>& args)
|
||||
std::cout << "Invalid syntax: Number of blocks must be greater than 0. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
return m_executor.pop_blocks(nblocks);
|
||||
bool keep_txs = false;
|
||||
if (args.size() > 1)
|
||||
{
|
||||
const std::string keep_arg = args.at(1);
|
||||
if (keep_arg == "keep-txs")
|
||||
keep_txs = true;
|
||||
else if (keep_arg == "no-keep-txs")
|
||||
keep_txs = false;
|
||||
else
|
||||
{
|
||||
std::cout << "Invalid syntax: Unrecognized argument: '" << keep_arg
|
||||
<< "'. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return m_executor.pop_blocks(nblocks, keep_txs);
|
||||
}
|
||||
catch (const boost::bad_lexical_cast&)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2014-2024, The Monero Project
|
||||
// Copyright (c) 2014-2026, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
@@ -299,8 +299,8 @@ t_command_server::t_command_server(
|
||||
m_command_lookup.set_handler(
|
||||
"pop_blocks"
|
||||
, std::bind(&t_command_parser_executor::pop_blocks, &m_parser, p::_1)
|
||||
, "pop_blocks <nblocks>"
|
||||
, "Remove blocks from end of blockchain"
|
||||
, "pop_blocks <nblocks> [keep-txs|no-keep-txs]"
|
||||
, "Remove blocks from end of blockchain, optionally moving popped txs into the mempool (not default)"
|
||||
);
|
||||
m_command_lookup.set_handler(
|
||||
"version"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2014-2024, The Monero Project
|
||||
// Copyright (c) 2014-2026, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
@@ -2310,13 +2310,14 @@ bool t_rpc_command_executor::sync_info()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool t_rpc_command_executor::pop_blocks(uint64_t num_blocks)
|
||||
bool t_rpc_command_executor::pop_blocks(uint64_t num_blocks, bool keep_txs)
|
||||
{
|
||||
cryptonote::COMMAND_RPC_POP_BLOCKS::request req;
|
||||
cryptonote::COMMAND_RPC_POP_BLOCKS::response res;
|
||||
std::string fail_message = "pop_blocks failed";
|
||||
|
||||
req.nblocks = num_blocks;
|
||||
req.keep_txs = keep_txs;
|
||||
if (m_is_rpc)
|
||||
{
|
||||
if (!m_rpc_client->rpc_request(req, res, "/pop_blocks", fail_message.c_str()))
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
*/
|
||||
|
||||
// Copyright (c) 2014-2024, The Monero Project
|
||||
// Copyright (c) 2014-2026, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
@@ -154,7 +154,7 @@ public:
|
||||
|
||||
bool sync_info();
|
||||
|
||||
bool pop_blocks(uint64_t num_blocks);
|
||||
bool pop_blocks(uint64_t num_blocks, bool keep_txs);
|
||||
|
||||
bool prune_blockchain();
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2014-2024, The Monero Project
|
||||
// Copyright (c) 2014-2026, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
@@ -3174,7 +3174,7 @@ namespace cryptonote
|
||||
{
|
||||
RPC_TRACKER(pop_blocks);
|
||||
|
||||
m_core.get_blockchain_storage().pop_blocks(req.nblocks);
|
||||
m_core.get_blockchain_storage().pop_blocks(req.nblocks, req.keep_txs);
|
||||
|
||||
res.height = m_core.get_current_blockchain_height();
|
||||
res.status = CORE_RPC_STATUS_OK;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2014-2024, The Monero Project
|
||||
// Copyright (c) 2014-2026, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
@@ -101,7 +101,7 @@ inline const std::string get_rpc_status(const bool trusted_daemon, const std::st
|
||||
// advance which version they will stop working with
|
||||
// Don't go over 32767 for any of these
|
||||
#define CORE_RPC_VERSION_MAJOR 3
|
||||
#define CORE_RPC_VERSION_MINOR 17
|
||||
#define CORE_RPC_VERSION_MINOR 18
|
||||
#define MAKE_CORE_RPC_VERSION(major,minor) (((major)<<16)|(minor))
|
||||
#define CORE_RPC_VERSION MAKE_CORE_RPC_VERSION(CORE_RPC_VERSION_MAJOR, CORE_RPC_VERSION_MINOR)
|
||||
|
||||
@@ -2498,10 +2498,12 @@ inline const std::string get_rpc_status(const bool trusted_daemon, const std::st
|
||||
struct request_t: public rpc_request_base
|
||||
{
|
||||
uint64_t nblocks;
|
||||
bool keep_txs;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE_PARENT(rpc_request_base)
|
||||
KV_SERIALIZE(nblocks)
|
||||
KV_SERIALIZE_OPT(keep_txs, true)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
typedef epee::misc_utils::struct_init<request_t> request;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2019-2024, The Monero Project
|
||||
// Copyright (c) 2019-2026, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
@@ -96,7 +96,7 @@ public:
|
||||
*block_height = h - 1;
|
||||
return top;
|
||||
}
|
||||
virtual void pop_block(cryptonote::block &blk, std::vector<cryptonote::transaction> &txs) override { blocks.pop_back(); }
|
||||
virtual void pop_block(cryptonote::block &, std::vector<cryptonote::transaction> *) override { blocks.pop_back(); }
|
||||
virtual void set_hard_fork_version(uint64_t height, uint8_t version) override { if (height >= hf.size()) hf.resize(height + 1); hf[height] = version; }
|
||||
virtual uint8_t get_hard_fork_version(uint64_t height) const override { if (height >= hf.size()) return 255; return hf[height]; }
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2014-2024, The Monero Project
|
||||
// Copyright (c) 2014-2026, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
@@ -132,7 +132,7 @@ namespace
|
||||
return blocks[blocks.size()-1].bl;
|
||||
}
|
||||
|
||||
virtual void pop_block(cryptonote::block &blk, std::vector<cryptonote::transaction> &txs) override { if (!blocks.empty()) blocks.pop_back(); }
|
||||
virtual void pop_block(cryptonote::block &, std::vector<cryptonote::transaction> *) override { if (!blocks.empty()) blocks.pop_back(); }
|
||||
virtual void set_hard_fork_version(uint64_t height, uint8_t version) override { if (height >= hf.size()) hf.resize(height + 1); hf[height] = version; }
|
||||
virtual uint8_t get_hard_fork_version(uint64_t height) const override { if (height >= hf.size()) return 255; return hf[height]; }
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2019-2024, The Monero Project
|
||||
// Copyright (c) 2019-2026, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
@@ -90,7 +90,7 @@ public:
|
||||
*block_height = h - 1;
|
||||
return top;
|
||||
}
|
||||
virtual void pop_block(cryptonote::block &blk, std::vector<cryptonote::transaction> &txs) override { blocks.pop_back(); }
|
||||
virtual void pop_block(cryptonote::block &blk, std::vector<cryptonote::transaction> *txs) override { blocks.pop_back(); }
|
||||
|
||||
private:
|
||||
std::vector<block_t> blocks;
|
||||
@@ -206,9 +206,8 @@ TEST(long_term_block_weight, multi_pop)
|
||||
}
|
||||
|
||||
cryptonote::block b;
|
||||
std::vector<cryptonote::transaction> txs;
|
||||
for (uint64_t h = 0; h < num_pop; ++h)
|
||||
bc->get_db().pop_block(b, txs);
|
||||
bc->get_db().pop_block(b, /*txs=*/nullptr);
|
||||
ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
|
||||
|
||||
ASSERT_EQ(effective_median, bc->get_current_cumulative_block_weight_median());
|
||||
@@ -267,8 +266,7 @@ TEST(long_term_block_weight, pop_invariant_max)
|
||||
for (int i = 0; i < remove; ++i)
|
||||
{
|
||||
cryptonote::block b;
|
||||
std::vector<cryptonote::transaction> txs;
|
||||
bc->get_db().pop_block(b, txs);
|
||||
bc->get_db().pop_block(b, /*txs=*/nullptr);
|
||||
ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
|
||||
}
|
||||
for (int i = 0; i < add; ++i)
|
||||
@@ -317,8 +315,7 @@ TEST(long_term_block_weight, pop_invariant_random)
|
||||
for (int i = 0; i < remove; ++i)
|
||||
{
|
||||
cryptonote::block b;
|
||||
std::vector<cryptonote::transaction> txs;
|
||||
bc->get_db().pop_block(b, txs);
|
||||
bc->get_db().pop_block(b, /*txs=*/nullptr);
|
||||
ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
|
||||
const uint64_t effective_median = bc->get_current_cumulative_block_weight_median();
|
||||
const uint64_t effective_limit = bc->get_current_cumulative_block_weight_limit();
|
||||
|
||||
Reference in New Issue
Block a user