mirror of
https://github.com/monero-project/monero.git
synced 2024-12-27 15:29:25 -05:00
Merge pull request #650
e298b14
Blockchain: Update comments on removing block (warptangent)b368e29
blockchain_import: Get hard fork version from HardFork (warptangent)e02577f
Move HardFork DB update to BlockchainDB::add_block() (warptangent)3800875
Make HardFork object available to BlockchainDB and derived DB implementations (warptangent)fd46c96
BlockchainDB/LMDB: Refactor block-scope DB txn handling for add block (warptangent)f3a6000
BlockchainDB/LMDB/BDB: Extract DB txn functions for block add/remove (warptangent)f47d5b0
BlockchainLMDB: Allow two HardFork functions to update DB during block add (warptangent)15ee0be
BlockchainLMDB: extract txn macros used during block add/remove (warptangent)
This commit is contained in:
commit
24ccdb9b6e
@ -781,6 +781,8 @@ BlockchainBDB::BlockchainBDB(bool batch_transactions) :
|
|||||||
m_batch_transactions = batch_transactions;
|
m_batch_transactions = batch_transactions;
|
||||||
m_write_txn = nullptr;
|
m_write_txn = nullptr;
|
||||||
m_height = 0;
|
m_height = 0;
|
||||||
|
|
||||||
|
m_hardfork = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlockchainBDB::open(const std::string& filename, const int db_flags)
|
void BlockchainBDB::open(const std::string& filename, const int db_flags)
|
||||||
@ -1831,6 +1833,21 @@ void BlockchainBDB::set_batch_transactions(bool batch_transactions)
|
|||||||
LOG_PRINT_L3("batch transactions " << (m_batch_transactions ? "enabled" : "disabled"));
|
LOG_PRINT_L3("batch transactions " << (m_batch_transactions ? "enabled" : "disabled"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BlockchainBDB::block_txn_start()
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
void BlockchainBDB::block_txn_stop()
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
void BlockchainBDB::block_txn_abort()
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t BlockchainBDB::add_block(const block& blk, const size_t& block_size, const difficulty_type& cumulative_difficulty, const uint64_t& coins_generated, const std::vector<transaction>& txs)
|
uint64_t BlockchainBDB::add_block(const block& blk, const size_t& block_size, const difficulty_type& cumulative_difficulty, const uint64_t& coins_generated, const std::vector<transaction>& txs)
|
||||||
{
|
{
|
||||||
LOG_PRINT_L3("BlockchainBDB::" << __func__);
|
LOG_PRINT_L3("BlockchainBDB::" << __func__);
|
||||||
|
@ -328,6 +328,10 @@ public:
|
|||||||
virtual void batch_stop();
|
virtual void batch_stop();
|
||||||
virtual void batch_abort();
|
virtual void batch_abort();
|
||||||
|
|
||||||
|
virtual void block_txn_start();
|
||||||
|
virtual void block_txn_stop();
|
||||||
|
virtual void block_txn_abort();
|
||||||
|
|
||||||
virtual void pop_block(block& blk, std::vector<transaction>& txs);
|
virtual void pop_block(block& blk, std::vector<transaction>& txs);
|
||||||
|
|
||||||
#if defined(BDB_BULK_CAN_THREAD)
|
#if defined(BDB_BULK_CAN_THREAD)
|
||||||
|
@ -99,6 +99,8 @@ uint64_t BlockchainDB::add_block( const block& blk
|
|||||||
, const std::vector<transaction>& txs
|
, const std::vector<transaction>& txs
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
block_txn_start();
|
||||||
|
|
||||||
TIME_MEASURE_START(time1);
|
TIME_MEASURE_START(time1);
|
||||||
crypto::hash blk_hash = get_block_hash(blk);
|
crypto::hash blk_hash = get_block_hash(blk);
|
||||||
TIME_MEASURE_FINISH(time1);
|
TIME_MEASURE_FINISH(time1);
|
||||||
@ -125,9 +127,21 @@ uint64_t BlockchainDB::add_block( const block& blk
|
|||||||
TIME_MEASURE_FINISH(time1);
|
TIME_MEASURE_FINISH(time1);
|
||||||
time_add_transaction += time1;
|
time_add_transaction += time1;
|
||||||
|
|
||||||
|
// DB's new height based on this added block is only incremented after this
|
||||||
|
// function returns, so height() here returns the new previous height.
|
||||||
|
uint64_t prev_height = height();
|
||||||
|
m_hardfork->add(blk, prev_height);
|
||||||
|
|
||||||
|
block_txn_stop();
|
||||||
|
|
||||||
++num_calls;
|
++num_calls;
|
||||||
|
|
||||||
return height();
|
return prev_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
@ -28,12 +28,15 @@
|
|||||||
#ifndef BLOCKCHAIN_DB_H
|
#ifndef BLOCKCHAIN_DB_H
|
||||||
#define BLOCKCHAIN_DB_H
|
#define BLOCKCHAIN_DB_H
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include "crypto/hash.h"
|
#include "crypto/hash.h"
|
||||||
#include "cryptonote_core/cryptonote_basic.h"
|
#include "cryptonote_core/cryptonote_basic.h"
|
||||||
#include "cryptonote_core/difficulty.h"
|
#include "cryptonote_core/difficulty.h"
|
||||||
|
#include "cryptonote_core/hardfork.h"
|
||||||
|
|
||||||
/* DB Driver Interface
|
/* DB Driver Interface
|
||||||
*
|
*
|
||||||
@ -322,6 +325,8 @@ protected:
|
|||||||
uint64_t time_commit1 = 0;
|
uint64_t time_commit1 = 0;
|
||||||
bool m_auto_remove_logs = true;
|
bool m_auto_remove_logs = true;
|
||||||
|
|
||||||
|
HardFork* m_hardfork;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// virtual dtor
|
// virtual dtor
|
||||||
@ -368,6 +373,12 @@ public:
|
|||||||
virtual void batch_stop() = 0;
|
virtual void batch_stop() = 0;
|
||||||
virtual void set_batch_transactions(bool) = 0;
|
virtual void set_batch_transactions(bool) = 0;
|
||||||
|
|
||||||
|
virtual void block_txn_start() = 0;
|
||||||
|
virtual void block_txn_stop() = 0;
|
||||||
|
virtual void block_txn_abort() = 0;
|
||||||
|
|
||||||
|
virtual void set_hard_fork(HardFork*& hf);
|
||||||
|
|
||||||
// adds a block with the given metadata to the top of the blockchain, returns the new height
|
// adds a block with the given metadata to the top of the blockchain, returns the new height
|
||||||
// NOTE: subclass implementations of this (or the functions it calls) need
|
// NOTE: subclass implementations of this (or the functions it calls) need
|
||||||
// to handle undoing any partially-added blocks in the event of a failure.
|
// to handle undoing any partially-added blocks in the event of a failure.
|
||||||
|
@ -945,6 +945,8 @@ BlockchainLMDB::BlockchainLMDB(bool batch_transactions)
|
|||||||
m_write_batch_txn = nullptr;
|
m_write_batch_txn = nullptr;
|
||||||
m_batch_active = false;
|
m_batch_active = false;
|
||||||
m_height = 0;
|
m_height = 0;
|
||||||
|
|
||||||
|
m_hardfork = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlockchainLMDB::open(const std::string& filename, const int mdb_flags)
|
void BlockchainLMDB::open(const std::string& filename, const int mdb_flags)
|
||||||
@ -1265,6 +1267,32 @@ void BlockchainLMDB::unlock()
|
|||||||
auto_txn.commit(); \
|
auto_txn.commit(); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
// The below two macros are for DB access within block add/remove, whether
|
||||||
|
// regular batch txn is in use or not. m_write_txn is used as a batch txn, even
|
||||||
|
// if it's only within block add/remove.
|
||||||
|
//
|
||||||
|
// DB access functions that may be called both within block add/remove and
|
||||||
|
// without should use these. If the function will be called ONLY within block
|
||||||
|
// add/remove, m_write_txn alone may be used instead of these macros.
|
||||||
|
|
||||||
|
#define TXN_BLOCK_PREFIX(flags); \
|
||||||
|
mdb_txn_safe auto_txn; \
|
||||||
|
mdb_txn_safe* txn_ptr = &auto_txn; \
|
||||||
|
if (m_batch_active || m_write_txn) \
|
||||||
|
txn_ptr = m_write_txn; \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
if (auto mdb_res = mdb_txn_begin(m_env, NULL, flags, auto_txn)) \
|
||||||
|
throw0(DB_ERROR(lmdb_error(std::string("Failed to create a transaction for the db in ")+__FUNCTION__+": ", mdb_res).c_str())); \
|
||||||
|
} \
|
||||||
|
|
||||||
|
#define TXN_BLOCK_POSTFIX_SUCCESS() \
|
||||||
|
do { \
|
||||||
|
if (! m_batch_active && ! m_write_txn) \
|
||||||
|
auto_txn.commit(); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
bool BlockchainLMDB::block_exists(const crypto::hash& h) const
|
bool BlockchainLMDB::block_exists(const crypto::hash& h) const
|
||||||
{
|
{
|
||||||
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
||||||
@ -2164,6 +2192,44 @@ void BlockchainLMDB::set_batch_transactions(bool batch_transactions)
|
|||||||
LOG_PRINT_L3("batch transactions " << (m_batch_transactions ? "enabled" : "disabled"));
|
LOG_PRINT_L3("batch transactions " << (m_batch_transactions ? "enabled" : "disabled"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BlockchainLMDB::block_txn_start()
|
||||||
|
{
|
||||||
|
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
||||||
|
if (! m_batch_active && m_write_txn)
|
||||||
|
throw0(DB_ERROR((std::string("Attempted to start new write txn when write txn already exists in ")+__FUNCTION__).c_str()));
|
||||||
|
if (! m_batch_active)
|
||||||
|
{
|
||||||
|
m_write_txn = new mdb_txn_safe();
|
||||||
|
if (auto mdb_res = mdb_txn_begin(m_env, NULL, 0, *m_write_txn))
|
||||||
|
throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", mdb_res).c_str()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BlockchainLMDB::block_txn_stop()
|
||||||
|
{
|
||||||
|
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
||||||
|
if (! m_batch_active)
|
||||||
|
{
|
||||||
|
TIME_MEASURE_START(time1);
|
||||||
|
m_write_txn->commit();
|
||||||
|
TIME_MEASURE_FINISH(time1);
|
||||||
|
time_commit1 += time1;
|
||||||
|
|
||||||
|
delete m_write_txn;
|
||||||
|
m_write_txn = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BlockchainLMDB::block_txn_abort()
|
||||||
|
{
|
||||||
|
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
||||||
|
if (! m_batch_active)
|
||||||
|
{
|
||||||
|
delete m_write_txn;
|
||||||
|
m_write_txn = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t BlockchainLMDB::add_block(const block& blk, const size_t& block_size, const difficulty_type& cumulative_difficulty, const uint64_t& coins_generated,
|
uint64_t BlockchainLMDB::add_block(const block& blk, const size_t& block_size, const difficulty_type& cumulative_difficulty, const uint64_t& coins_generated,
|
||||||
const std::vector<transaction>& txs)
|
const std::vector<transaction>& txs)
|
||||||
{
|
{
|
||||||
@ -2180,33 +2246,15 @@ uint64_t BlockchainLMDB::add_block(const block& blk, const size_t& block_size, c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mdb_txn_safe txn;
|
|
||||||
if (! m_batch_active)
|
|
||||||
{
|
|
||||||
if (auto mdb_res = mdb_txn_begin(m_env, NULL, 0, txn))
|
|
||||||
throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", mdb_res).c_str()));
|
|
||||||
m_write_txn = &txn;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t num_outputs = m_num_outputs;
|
uint64_t num_outputs = m_num_outputs;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
BlockchainDB::add_block(blk, block_size, cumulative_difficulty, coins_generated, txs);
|
BlockchainDB::add_block(blk, block_size, cumulative_difficulty, coins_generated, txs);
|
||||||
if (! m_batch_active)
|
|
||||||
{
|
|
||||||
m_write_txn = NULL;
|
|
||||||
|
|
||||||
TIME_MEASURE_START(time1);
|
|
||||||
txn.commit();
|
|
||||||
TIME_MEASURE_FINISH(time1);
|
|
||||||
time_commit1 += time1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
m_num_outputs = num_outputs;
|
m_num_outputs = num_outputs;
|
||||||
if (! m_batch_active)
|
block_txn_abort();
|
||||||
m_write_txn = NULL;
|
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2481,14 +2529,14 @@ void BlockchainLMDB::set_hard_fork_starting_height(uint8_t version, uint64_t hei
|
|||||||
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
||||||
check_open();
|
check_open();
|
||||||
|
|
||||||
TXN_PREFIX(0);
|
TXN_BLOCK_PREFIX(0);
|
||||||
|
|
||||||
MDB_val_copy<uint8_t> val_key(version);
|
MDB_val_copy<uint8_t> val_key(version);
|
||||||
MDB_val_copy<uint64_t> val_value(height);
|
MDB_val_copy<uint64_t> val_value(height);
|
||||||
if (auto result = mdb_put(*txn_ptr, m_hf_starting_heights, &val_key, &val_value, 0))
|
if (auto result = mdb_put(*txn_ptr, m_hf_starting_heights, &val_key, &val_value, 0))
|
||||||
throw1(DB_ERROR(std::string("Error adding hard fork starting height to db transaction: ").append(mdb_strerror(result)).c_str()));
|
throw1(DB_ERROR(std::string("Error adding hard fork starting height to db transaction: ").append(mdb_strerror(result)).c_str()));
|
||||||
|
|
||||||
TXN_POSTFIX_SUCCESS();
|
TXN_BLOCK_POSTFIX_SUCCESS();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t BlockchainLMDB::get_hard_fork_starting_height(uint8_t version) const
|
uint64_t BlockchainLMDB::get_hard_fork_starting_height(uint8_t version) const
|
||||||
@ -2516,14 +2564,14 @@ void BlockchainLMDB::set_hard_fork_version(uint64_t height, uint8_t version)
|
|||||||
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
||||||
check_open();
|
check_open();
|
||||||
|
|
||||||
TXN_PREFIX(0);
|
TXN_BLOCK_PREFIX(0);
|
||||||
|
|
||||||
MDB_val_copy<uint64_t> val_key(height);
|
MDB_val_copy<uint64_t> val_key(height);
|
||||||
MDB_val_copy<uint8_t> val_value(version);
|
MDB_val_copy<uint8_t> val_value(version);
|
||||||
if (auto result = mdb_put(*txn_ptr, m_hf_versions, &val_key, &val_value, 0))
|
if (auto result = mdb_put(*txn_ptr, m_hf_versions, &val_key, &val_value, 0))
|
||||||
throw1(DB_ERROR(std::string("Error adding hard fork version to db transaction: ").append(mdb_strerror(result)).c_str()));
|
throw1(DB_ERROR(std::string("Error adding hard fork version to db transaction: ").append(mdb_strerror(result)).c_str()));
|
||||||
|
|
||||||
TXN_POSTFIX_SUCCESS();
|
TXN_BLOCK_POSTFIX_SUCCESS();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t BlockchainLMDB::get_hard_fork_version(uint64_t height) const
|
uint8_t BlockchainLMDB::get_hard_fork_version(uint64_t height) const
|
||||||
|
@ -194,6 +194,10 @@ public:
|
|||||||
virtual void batch_stop();
|
virtual void batch_stop();
|
||||||
virtual void batch_abort();
|
virtual void batch_abort();
|
||||||
|
|
||||||
|
virtual void block_txn_start();
|
||||||
|
virtual void block_txn_stop();
|
||||||
|
virtual void block_txn_abort();
|
||||||
|
|
||||||
virtual void pop_block(block& blk, std::vector<transaction>& txs);
|
virtual void pop_block(block& blk, std::vector<transaction>& txs);
|
||||||
|
|
||||||
virtual bool can_thread_bulk_indices() const { return true; }
|
virtual bool can_thread_bulk_indices() const { return true; }
|
||||||
|
@ -400,11 +400,8 @@ int import_from_file(FakeCore& simple_core, const std::string& import_file_path,
|
|||||||
// size_t blob_size = 0;
|
// size_t blob_size = 0;
|
||||||
// get_transaction_hash(tx, hsh, blob_size);
|
// get_transaction_hash(tx, hsh, blob_size);
|
||||||
|
|
||||||
// we'd need to get the starting heights from the daemon
|
|
||||||
// to be correct once voting kicks in
|
|
||||||
uint64_t v2height = opt_testnet ? 624634 : 1009827;
|
|
||||||
|
|
||||||
uint8_t version = h < v2height ? 1 : 2;
|
uint8_t version = simple_core.m_storage.get_current_hard_fork_version();
|
||||||
tx_verification_context tvc = AUTO_VAL_INIT(tvc);
|
tx_verification_context tvc = AUTO_VAL_INIT(tvc);
|
||||||
bool r = true;
|
bool r = true;
|
||||||
r = simple_core.m_pool.add_tx(tx, tvc, true, true, version);
|
r = simple_core.m_pool.add_tx(tx, tvc, true, true, version);
|
||||||
@ -469,9 +466,6 @@ int import_from_file(FakeCore& simple_core, const std::string& import_file_path,
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
simple_core.add_block(b, block_size, cumulative_difficulty, coins_generated, txs);
|
simple_core.add_block(b, block_size, cumulative_difficulty, coins_generated, txs);
|
||||||
#if !defined(BLOCKCHAIN_DB) || (BLOCKCHAIN_DB == DB_LMDB)
|
|
||||||
simple_core.m_hardfork->add(b, h-1);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
catch (const std::exception& e)
|
catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
|
@ -290,6 +290,8 @@ bool Blockchain::init(BlockchainDB* db, const bool testnet, const bool fakechain
|
|||||||
}
|
}
|
||||||
m_hardfork->init();
|
m_hardfork->init();
|
||||||
|
|
||||||
|
m_db->set_hard_fork(m_hardfork);
|
||||||
|
|
||||||
// if the blockchain is new, add the genesis block
|
// if the blockchain is new, add the genesis block
|
||||||
// this feels kinda kludgy to do it this way, but can be looked at later.
|
// this feels kinda kludgy to do it this way, but can be looked at later.
|
||||||
// TODO: add function to create and store genesis block,
|
// TODO: add function to create and store genesis block,
|
||||||
@ -459,6 +461,11 @@ block Blockchain::pop_block_from_blockchain()
|
|||||||
{
|
{
|
||||||
cryptonote::tx_verification_context tvc = AUTO_VAL_INIT(tvc);
|
cryptonote::tx_verification_context tvc = AUTO_VAL_INIT(tvc);
|
||||||
|
|
||||||
|
// FIXME: HardFork
|
||||||
|
// Besides the below, popping a block should also remove the last entry
|
||||||
|
// in hf_versions.
|
||||||
|
//
|
||||||
|
// FIXME: HardFork
|
||||||
// This is not quite correct, as we really want to add the txes
|
// This is not quite correct, as we really want to add the txes
|
||||||
// to the pool based on the version determined after all blocks
|
// to the pool based on the version determined after all blocks
|
||||||
// are popped.
|
// are popped.
|
||||||
@ -2690,9 +2697,6 @@ bool Blockchain::handle_block_to_main_chain(const block& bl, const crypto::hash&
|
|||||||
|
|
||||||
TIME_MEASURE_FINISH(addblock);
|
TIME_MEASURE_FINISH(addblock);
|
||||||
|
|
||||||
// this will not fail since check succeeded above
|
|
||||||
m_hardfork->add(bl, new_height - 1);
|
|
||||||
|
|
||||||
// do this after updating the hard fork state since the size limit may change due to fork
|
// do this after updating the hard fork state since the size limit may change due to fork
|
||||||
update_next_cumulative_size_limit();
|
update_next_cumulative_size_limit();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user