some bug fixes, but still needs work
There are quite a few debug prints in this commit that will need removed later, but for posterity (in case someone wants to debug this while I'm away), I left them in. Currently errors when syncing on the first block that has a "real" transaction. Seems to not be able to validate the ring signature, but I can't for the life of me figure out what's going wrong.
This commit is contained in:
parent
006afe2172
commit
1a546e3222
3 changed files with 74 additions and 36 deletions
|
@ -34,6 +34,8 @@
|
|||
#include "cryptonote_core/cryptonote_format_utils.h"
|
||||
#include "crypto/crypto.h"
|
||||
|
||||
using epee::string_tools::pod_to_hex;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
|
@ -69,6 +71,14 @@ struct lmdb_cur
|
|||
bool done;
|
||||
};
|
||||
|
||||
auto compare_uint64 = [](const MDB_val *a, const MDB_val *b) {
|
||||
uint64_t va = *(uint64_t*)a->mv_data;
|
||||
uint64_t vb = *(uint64_t*)b->mv_data;
|
||||
if (va < vb) return -1;
|
||||
else if (va == vb) return 0;
|
||||
else return 1;
|
||||
};
|
||||
|
||||
const char* LMDB_BLOCKS = "blocks";
|
||||
const char* LMDB_BLOCK_TIMESTAMPS = "block_timestamps";
|
||||
const char* LMDB_BLOCK_HEIGHTS = "block_heights";
|
||||
|
@ -418,6 +428,9 @@ void BlockchainLMDB::add_output(const crypto::hash& tx_hash, const tx_out& tx_ou
|
|||
throw DB_ERROR("Failed to add output global index to db transaction");
|
||||
}
|
||||
|
||||
LOG_PRINT_L0(__func__ << ": amount == " << amount << ", tx_index == " << local_index << "amount_index == " << get_num_outputs(amount) << ", tx_hash == " << pod_to_hex(tx_hash));
|
||||
|
||||
m_num_outputs++;
|
||||
}
|
||||
|
||||
void BlockchainLMDB::remove_output(const tx_out& tx_output)
|
||||
|
@ -661,6 +674,9 @@ void BlockchainLMDB::open(const std::string& filename)
|
|||
|
||||
lmdb_db_open(txn, LMDB_SPENT_KEYS, MDB_CREATE, m_spent_keys, "Failed to open db handle for m_outputs");
|
||||
|
||||
mdb_set_dupsort(txn, m_output_amounts, compare_uint64);
|
||||
mdb_set_dupsort(txn, m_tx_outputs, compare_uint64);
|
||||
|
||||
// get and keep current height
|
||||
MDB_stat db_stats;
|
||||
if (mdb_stat(txn, m_blocks, &db_stats))
|
||||
|
@ -1508,8 +1524,8 @@ tx_out_index BlockchainLMDB::get_output_tx_and_index(const uint64_t& amount, con
|
|||
auto result = mdb_cursor_get(cur, &k, &v, MDB_SET);
|
||||
if (result == MDB_NOTFOUND)
|
||||
{
|
||||
LOG_PRINT_L1("Attempting to get an output index by amount and amount index, but output not found");
|
||||
throw OUTPUT_DNE("Attempting to get an output index by amount and amount index, but output not found");
|
||||
LOG_PRINT_L1("Attempting to get an output index by amount and amount index, but amount not found");
|
||||
throw OUTPUT_DNE("Attempting to get an output index by amount and amount index, but amount not found");
|
||||
}
|
||||
else if (result)
|
||||
{
|
||||
|
@ -1519,6 +1535,7 @@ tx_out_index BlockchainLMDB::get_output_tx_and_index(const uint64_t& amount, con
|
|||
|
||||
size_t num_elems = 0;
|
||||
mdb_cursor_count(cur, &num_elems);
|
||||
LOG_PRINT_L0(__func__ << ": amount == " << amount << ", index == " << index << ", num_elem for amount == " << num_elems);
|
||||
if (num_elems <= index)
|
||||
{
|
||||
LOG_PRINT_L1("Attempting to get an output index by amount and amount index, but output not found");
|
||||
|
@ -1571,6 +1588,8 @@ tx_out_index BlockchainLMDB::get_output_tx_and_index(const uint64_t& amount, con
|
|||
|
||||
txn.commit();
|
||||
|
||||
LOG_PRINT_L0(__func__ << ": tx_hash == " << pod_to_hex(tx_hash) << " tx_index == " << *(uint64_t*)v.mv_data);
|
||||
|
||||
return tx_out_index(tx_hash, *(uint64_t *)v.mv_data);
|
||||
}
|
||||
|
||||
|
|
|
@ -180,6 +180,8 @@ bool Blockchain::scan_outputkeys_for_indexes(const txin_to_key& tx_in_to_key, vi
|
|||
return false;
|
||||
}
|
||||
|
||||
LOG_PRINT_L0(__func__ << ": amount == " << tx.vout[output_index.second].amount);
|
||||
|
||||
// call to the passed boost visitor to grab the public key for the output
|
||||
if(!vis.handle_output(tx, tx.vout[output_index.second]))
|
||||
{
|
||||
|
@ -496,15 +498,15 @@ bool Blockchain::get_short_chain_history(std::list<crypto::hash>& ids)
|
|||
CRITICAL_REGION_LOCAL(m_blockchain_lock);
|
||||
uint64_t i = 0;
|
||||
uint64_t current_multiplier = 1;
|
||||
uint64_t sz = m_db->height() - 1;
|
||||
uint64_t sz = m_db->height();
|
||||
|
||||
if(!sz)
|
||||
return true;
|
||||
|
||||
uint64_t current_back_offset = 0;
|
||||
while(current_back_offset <= sz)
|
||||
while(current_back_offset < sz)
|
||||
{
|
||||
ids.push_back(m_db->get_block_hash_from_height(sz-current_back_offset));
|
||||
ids.push_back(m_db->get_block_hash_from_height(sz - current_back_offset - 1));
|
||||
if(i < 10)
|
||||
{
|
||||
++current_back_offset;
|
||||
|
@ -585,7 +587,7 @@ void Blockchain::get_all_known_block_ids(std::list<crypto::hash> &main, std::lis
|
|||
LOG_PRINT_L2("Blockchain::" << __func__);
|
||||
CRITICAL_REGION_LOCAL(m_blockchain_lock);
|
||||
|
||||
for (auto& a : m_db->get_hashes_range(0, m_db->height()))
|
||||
for (auto& a : m_db->get_hashes_range(0, m_db->height() - 1))
|
||||
{
|
||||
main.push_back(a);
|
||||
}
|
||||
|
@ -861,13 +863,13 @@ bool Blockchain::validate_miner_transaction(const block& b, size_t cumulative_bl
|
|||
}
|
||||
if(base_reward + fee < money_in_use)
|
||||
{
|
||||
LOG_ERROR("coinbase transaction spend too much money (" << print_money(money_in_use) << "). Block reward is " << print_money(base_reward + fee) << "(" << print_money(base_reward) << "+" << print_money(fee) << ")");
|
||||
LOG_ERROR("coinbase transaction spend too much money (" << money_in_use << "). Block reward is " << base_reward + fee << "(" << base_reward << "+" << fee << ")");
|
||||
return false;
|
||||
}
|
||||
if(base_reward + fee != money_in_use)
|
||||
{
|
||||
LOG_ERROR("coinbase transaction doesn't use full amount of block reward: spent: "
|
||||
<< print_money(money_in_use) << ", block reward " << print_money(base_reward + fee) << "(" << print_money(base_reward) << "+" << print_money(fee) << ")");
|
||||
<< money_in_use << ", block reward " << base_reward + fee << "(" << base_reward << "+" << fee << ")");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -886,8 +888,8 @@ void Blockchain::get_last_n_blocks_sizes(std::vector<size_t>& sz, size_t count)
|
|||
return;
|
||||
|
||||
// add size of last <count> blocks to vector <sz> (or less, if blockchain size < count)
|
||||
size_t start_offset = (h+1) - std::min((h+1), count);
|
||||
for(size_t i = start_offset; i <= h; i++)
|
||||
size_t start_offset = h - std::min(h, count);
|
||||
for(size_t i = start_offset; i < h; i++)
|
||||
{
|
||||
sz.push_back(m_db->get_block_size(i));
|
||||
}
|
||||
|
@ -922,13 +924,12 @@ bool Blockchain::create_block_template(block& b, const account_public_address& m
|
|||
b.prev_id = get_tail_id();
|
||||
b.timestamp = time(NULL);
|
||||
|
||||
auto old_height = m_db->height();
|
||||
height = old_height + 1;
|
||||
height = m_db->height();
|
||||
diffic = get_difficulty_for_next_block();
|
||||
CHECK_AND_ASSERT_MES(diffic, false, "difficulty owverhead.");
|
||||
|
||||
median_size = m_current_block_cumul_sz_limit / 2;
|
||||
already_generated_coins = m_db->get_block_already_generated_coins(old_height);
|
||||
already_generated_coins = m_db->get_block_already_generated_coins(height - 1);
|
||||
|
||||
CRITICAL_REGION_END();
|
||||
|
||||
|
@ -1043,7 +1044,7 @@ bool Blockchain::complete_timestamps_vector(uint64_t start_top_height, std::vect
|
|||
|
||||
CRITICAL_REGION_LOCAL(m_blockchain_lock);
|
||||
size_t need_elements = BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW - timestamps.size();
|
||||
CHECK_AND_ASSERT_MES(start_top_height <= m_db->height(), false, "internal error: passed start_height > " << " m_db->height() -- " << start_top_height << " > " << m_db->height());
|
||||
CHECK_AND_ASSERT_MES(start_top_height < m_db->height(), false, "internal error: passed start_height not < " << " m_db->height() -- " << start_top_height << " >= " << m_db->height());
|
||||
size_t stop_offset = start_top_height > need_elements ? start_top_height - need_elements : 0;
|
||||
while (start_top_height != stop_offset);
|
||||
{
|
||||
|
@ -1107,7 +1108,7 @@ bool Blockchain::handle_alternative_block(const block& b, const crypto::hash& id
|
|||
if(alt_chain.size())
|
||||
{
|
||||
// make sure alt chain doesn't somehow start past the end of the main chain
|
||||
CHECK_AND_ASSERT_MES(m_db->height() > alt_chain.front()->second.height, false, "main blockchain wrong height");
|
||||
CHECK_AND_ASSERT_MES(m_db->height() - 1 > alt_chain.front()->second.height, false, "main blockchain wrong height");
|
||||
|
||||
// make sure that the blockchain contains the block that should connect
|
||||
// this alternate chain with it.
|
||||
|
@ -1979,8 +1980,8 @@ bool Blockchain::check_block_timestamp(const block& b)
|
|||
// need most recent 60 blocks, get index of first of those
|
||||
// using +1 because BlockchainDB::height() returns the index of the top block,
|
||||
// not the size of the blockchain (0-indexed)
|
||||
size_t offset = h - BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW + 1;
|
||||
for(;offset <= h; ++offset)
|
||||
size_t offset = h - BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW - 1;
|
||||
for(;offset < h; ++offset)
|
||||
{
|
||||
timestamps.push_back(m_db->get_block_timestamp(offset));
|
||||
}
|
||||
|
@ -2143,7 +2144,7 @@ bool Blockchain::handle_block_to_main_chain(const block& bl, const crypto::hash&
|
|||
}
|
||||
|
||||
uint64_t base_reward = 0;
|
||||
uint64_t already_generated_coins = m_db->height() ? m_db->get_block_already_generated_coins(m_db->height()) : 0;
|
||||
uint64_t already_generated_coins = m_db->height() ? m_db->get_block_already_generated_coins(m_db->height() - 1) : 0;
|
||||
if(!validate_miner_transaction(bl, cumulative_block_size, fee_summary, base_reward, already_generated_coins))
|
||||
{
|
||||
LOG_PRINT_L0("Block with id: " << id
|
||||
|
@ -2161,7 +2162,7 @@ bool Blockchain::handle_block_to_main_chain(const block& bl, const crypto::hash&
|
|||
cumulative_difficulty = current_diffic;
|
||||
already_generated_coins = already_generated_coins + base_reward;
|
||||
if(m_db->height())
|
||||
cumulative_difficulty += m_db->get_block_cumulative_difficulty(m_db->height());
|
||||
cumulative_difficulty += m_db->get_block_cumulative_difficulty(m_db->height() - 1);
|
||||
|
||||
update_next_cumulative_size_limit();
|
||||
|
||||
|
@ -2169,15 +2170,18 @@ bool Blockchain::handle_block_to_main_chain(const block& bl, const crypto::hash&
|
|||
|
||||
uint64_t new_height = 0;
|
||||
bool add_success = true;
|
||||
try
|
||||
if (!bvc.m_verifivation_failed)
|
||||
{
|
||||
new_height = m_db->add_block(bl, block_size, cumulative_difficulty, already_generated_coins, txs);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
//TODO: figure out the best way to deal with this failure
|
||||
LOG_ERROR("Error adding block with hash: " << id << " to blockchain, what = " << e.what());
|
||||
add_success = false;
|
||||
try
|
||||
{
|
||||
new_height = m_db->add_block(bl, block_size, cumulative_difficulty, already_generated_coins, txs);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
//TODO: figure out the best way to deal with this failure
|
||||
LOG_ERROR("Error adding block with hash: " << id << " to blockchain, what = " << e.what());
|
||||
add_success = false;
|
||||
}
|
||||
}
|
||||
|
||||
// if we failed for any reason to verify the block, return taken
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
#include "cryptonote_core/blockchain_db.h"
|
||||
#include "cryptonote_format_utils.h"
|
||||
|
||||
using epee::string_tools::pod_to_hex;
|
||||
|
||||
namespace cryptonote
|
||||
{
|
||||
|
||||
|
@ -43,20 +45,31 @@ void BlockchainDB::add_transaction(const crypto::hash& blk_hash, const transacti
|
|||
{
|
||||
crypto::hash tx_hash = get_transaction_hash(tx);
|
||||
|
||||
LOG_PRINT_L0("Adding tx with hash " << pod_to_hex(tx_hash) << " to BlockchainDB instance");
|
||||
LOG_PRINT_L0("Included in block with hash " << pod_to_hex(blk_hash));
|
||||
LOG_PRINT_L0("Unlock time == " << tx.unlock_time);
|
||||
|
||||
add_transaction_data(blk_hash, tx);
|
||||
|
||||
// iterate tx.vout using indices instead of C++11 foreach syntax because
|
||||
// we need the index
|
||||
for (uint64_t i = 0; i < tx.vout.size(); ++i)
|
||||
if (tx.vout.size() != 0) // it may be technically possible for a tx to have no outputs
|
||||
{
|
||||
add_output(tx_hash, tx.vout[i], i);
|
||||
}
|
||||
|
||||
for (const txin_v& tx_input : tx.vin)
|
||||
{
|
||||
if (tx_input.type() == typeid(txin_to_key))
|
||||
for (uint64_t i = 0; i < tx.vout.size(); ++i)
|
||||
{
|
||||
add_spent_key(boost::get<txin_to_key>(tx_input).k_image);
|
||||
add_output(tx_hash, tx.vout[i], i);
|
||||
}
|
||||
|
||||
for (const txin_v& tx_input : tx.vin)
|
||||
{
|
||||
if (tx_input.type() == typeid(txin_to_key))
|
||||
{
|
||||
add_spent_key(boost::get<txin_to_key>(tx_input).k_image);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_PRINT_L0("Is miner tx");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -68,10 +81,12 @@ uint64_t BlockchainDB::add_block( const block& blk
|
|||
, const std::vector<transaction>& txs
|
||||
)
|
||||
{
|
||||
crypto::hash blk_hash = get_block_hash(blk);
|
||||
LOG_PRINT_L0("Adding block with hash " << pod_to_hex(blk_hash) << " to BlockchainDB instance.");
|
||||
|
||||
// call out to subclass implementation to add the block & metadata
|
||||
add_block(blk, block_size, cumulative_difficulty, coins_generated);
|
||||
|
||||
crypto::hash blk_hash = get_block_hash(blk);
|
||||
// call out to add the transactions
|
||||
|
||||
add_transaction(blk_hash, blk.miner_tx);
|
||||
|
|
Loading…
Reference in a new issue