1
0
Fork 0
forked from lthn/blockchain

initial code for upgrading walle sync protocol

This commit is contained in:
cryptozoidberg 2020-04-24 01:05:36 +02:00
parent 76b403b805
commit 4825b7c012
No known key found for this signature in database
GPG key ID: 22DEB97A54C6FDEC
3 changed files with 100 additions and 22 deletions

View file

@ -215,7 +215,8 @@
#define BC_OFFERS_CURRENCY_MARKET_FILENAME "market.bin"
#define WALLET_FILE_SERIALIZATION_VERSION (CURRENCY_FORMATION_VERSION+65)
#define WALLET_FILE_SERIALIZATION_VERSION (CURRENCY_FORMATION_VERSION+66)
#define CURRENT_MEMPOOL_ARCHIVE_VER (CURRENCY_FORMATION_VERSION+31)

View file

@ -1070,8 +1070,8 @@ void wallet2::process_unconfirmed(const currency::transaction& tx, std::vector<s
void wallet2::process_new_blockchain_entry(const currency::block& b, const currency::block_direct_data_entry& bche, const crypto::hash& bl_id, uint64_t height)
{
//handle transactions from new block
THROW_IF_TRUE_WALLET_EX(height != m_blockchain.size(), error::wallet_internal_error,
"current_index=" + std::to_string(height) + ", m_blockchain.size()=" + std::to_string(m_blockchain.size()));
THROW_IF_TRUE_WALLET_EX(height != get_blockchain_current_height(), error::wallet_internal_error,
"current_index=" + std::to_string(height) + ", get_blockchain_current_height()=" + std::to_string(get_blockchain_current_height()));
//optimization: seeking only for blocks that are not older then the wallet creation time plus 1 day. 1 day is for possible user incorrect time setup
if (b.timestamp + 60 * 60 * 24 > m_account.get_createtime())
@ -1091,7 +1091,7 @@ void wallet2::process_new_blockchain_entry(const currency::block& b, const curre
{
WLT_LOG_L3( "Skipped block by timestamp, height: " << height << ", block time " << b.timestamp << ", account time " << m_account.get_createtime());
}
m_blockchain.push_back(bl_id);
push_new_block_id(bl_id, height); //m_blockchain.push_back(bl_id);
++m_local_bc_height;
m_last_bc_timestamp = b.timestamp;
if (!is_pos_block(b))
@ -1100,12 +1100,61 @@ void wallet2::process_new_blockchain_entry(const currency::block& b, const curre
m_wcallback->on_new_block(height, b);
}
//----------------------------------------------------------------------------------------------------
void wallet2::push_new_block_id(const crypto::hash& id, uint64_t height)
{
//primary 10
//self check
if (!m_last_10_blocks.empty())
{
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(get_blockchain_current_height() == height, "Inernal error: get_blockchain_current_height(){" << get_blockchain_current_height() << "} == height{" << height << "} is not equal");
}
m_last_10_blocks[height] = id;
if (m_last_10_blocks.size() > WALLET_EVERYBLOCK_SIZE)
{
m_last_10_blocks.erase(m_last_10_blocks.begin());
}
//every 10-th
if (height % 10 == 0)
{
//self check
if (!m_last_144_blocks_every_10.empty())
{
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX((--m_last_144_blocks_every_10.end())->first + 10 == height, "Inernal error: (--m_last_144_blocks_every_10.end())->first + 10{" << (--m_last_144_blocks_every_10.end())->first + 10 << "} == height{" << height << "} is not equal");
}
m_last_144_blocks_every_10[height] = id;
}
//every 100-th
if (height % 100 == 0)
{
//self check
if (!m_last_144_blocks_every_100.empty())
{
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX((--m_last_144_blocks_every_100.end())->first + 100 == height, "Inernal error: (--m_last_144_blocks_every_100.end())->first + 100{" << (--m_last_144_blocks_every_100.end())->first + 100 << "} == height{" << height << "} is not equal");
}
m_last_144_blocks_every_100[height] = id;
}
//every 1000-th
//every 100-th
if (height % 1000 == 0)
{
//self check
if (!m_last_144_blocks_every_1000.empty())
{
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX((--m_last_144_blocks_every_1000.end())->first + 1000 == height, "Inernal error: (--m_last_144_blocks_every_1000.end())->first + 1000{" << (--m_last_144_blocks_every_1000.end())->first + 1000 << "} == height{" << height << "} is not equal");
}
m_last_144_blocks_every_1000[height] = id;
}
}
//----------------------------------------------------------------------------------------------------
void wallet2::get_short_chain_history(std::list<crypto::hash>& ids)
{
ids.clear();
size_t i = 0;
size_t current_multiplier = 1;
size_t sz = m_blockchain.size();
size_t sz = get_blockchain_current_height();
if(!sz)
return;
size_t current_back_offset = 1;
@ -1168,9 +1217,9 @@ void wallet2::pull_blocks(size_t& blocks_added, std::atomic<bool>& stop)
return;
}
THROW_IF_TRUE_WALLET_EX(res.status != CORE_RPC_STATUS_OK, error::get_blocks_error, res.status);
THROW_IF_TRUE_WALLET_EX(m_blockchain.size() && m_blockchain.size() <= res.start_height, error::wallet_internal_error,
THROW_IF_TRUE_WALLET_EX(get_blockchain_current_height() && get_blockchain_current_height() <= res.start_height, error::wallet_internal_error,
"wrong daemon response: m_start_height=" + std::to_string(res.start_height) +
" not less than local blockchain size=" + std::to_string(m_blockchain.size()));
" not less than local blockchain size=" + std::to_string(get_blockchain_current_height()));
handle_pulled_blocks(blocks_added, stop, res);
}
@ -1180,7 +1229,7 @@ void wallet2::handle_pulled_blocks(size_t& blocks_added, std::atomic<bool>& stop
{
size_t current_index = res.start_height;
if (res.start_height == 0 && m_blockchain.size() == 1 && !res.blocks.empty())
if (res.start_height == 0 && get_blockchain_current_height() == 1 && !res.blocks.empty())
{
const currency::block& genesis = res.blocks.front().block_ptr->bl;
THROW_IF_TRUE_WALLET_EX(get_block_height(genesis) != 0, error::wallet_internal_error, "first block expected to be genesis");
@ -1199,7 +1248,7 @@ void wallet2::handle_pulled_blocks(size_t& blocks_added, std::atomic<bool>& stop
//TODO: get_block_hash is slow
crypto::hash bl_id = get_block_hash(bl);
if (current_index >= m_blockchain.size())
if (current_index >= get_blockchain_current_height())
{
process_new_blockchain_entry(bl, bl_entry, bl_id, current_index);
++blocks_added;
@ -1233,7 +1282,7 @@ void wallet2::handle_pulled_blocks(size_t& blocks_added, std::atomic<bool>& stop
}
}
WLT_LOG_L1("[PULL BLOCKS] " << res.start_height << " --> " << m_blockchain.size());
WLT_LOG_L1("[PULL BLOCKS] " << res.start_height << " --> " << get_blockchain_current_height());
}
//----------------------------------------------------------------------------------------------------
uint64_t wallet2::get_sync_progress()
@ -1610,7 +1659,7 @@ void wallet2::refresh(size_t & blocks_fetched, bool& received_money, std::atomic
size_t added_blocks = 0;
size_t try_count = 0;
crypto::hash last_tx_hash_id = m_transfers.size() ? get_transaction_hash(m_transfers.back().m_ptx_wallet_info->m_tx) : null_hash;
m_height_of_start_sync = m_blockchain.size();
m_height_of_start_sync = get_blockchain_current_height();
m_last_sync_percent = 0;
while (!stop.load(std::memory_order_relaxed))
{
@ -2075,7 +2124,7 @@ void wallet2::load(const std::wstring& wallet_, const std::string& password)
{
reset_history();
}
m_local_bc_height = m_blockchain.size();
m_local_bc_height = get_blockchain_current_height();
THROW_IF_TRUE_WALLET_EX(need_to_resync, error::wallet_load_notice_wallet_restored, epee::string_encoding::convert_to_ansii(m_wallet_file));
WLT_LOG_L0("Loaded wallet file" << (m_watch_only ? " (WATCH ONLY) " : " ") << string_encoding::convert_to_ansii(m_wallet_file) << " with public address: " << m_account.get_public_address_str());
@ -2623,7 +2672,7 @@ bool wallet2::is_transfer_okay_for_pos(const transfer_details& tr, uint64_t& sta
return false;
//prevent staking of after-last-pow-coins
if (m_blockchain.size() - tr.m_ptx_wallet_info->m_block_height <= m_core_runtime_config.min_coinstake_age)
if (get_blockchain_current_height() - tr.m_ptx_wallet_info->m_block_height <= m_core_runtime_config.min_coinstake_age)
return false;
if (tr.m_ptx_wallet_info->m_block_height > m_last_pow_block_h)
@ -2945,20 +2994,20 @@ bool wallet2::is_transfer_unlocked(const transfer_details& td, bool for_pos_mini
if (td.m_flags&WALLET_TRANSFER_DETAIL_FLAG_BLOCKED)
return false;
if (td.m_ptx_wallet_info->m_block_height + WALLET_DEFAULT_TX_SPENDABLE_AGE > m_blockchain.size())
if (td.m_ptx_wallet_info->m_block_height + WALLET_DEFAULT_TX_SPENDABLE_AGE > get_blockchain_current_height())
return false;
uint64_t unlock_time = get_tx_unlock_time(td.m_ptx_wallet_info->m_tx, td.m_internal_output_index);
if (for_pos_mining && m_blockchain.size() > m_core_runtime_config.hard_fork1_starts_after_height)
if (for_pos_mining && get_blockchain_current_height() > m_core_runtime_config.hard_fork1_starts_after_height)
{
//allowed of staking locked coins with
stake_lock_time = unlock_time;
}
else
{
if (!currency::is_tx_spendtime_unlocked(unlock_time, m_blockchain.size(), m_core_runtime_config.get_core_time()))
if (!currency::is_tx_spendtime_unlocked(unlock_time, get_blockchain_current_height(), m_core_runtime_config.get_core_time()))
return false;
}
return true;
@ -4047,10 +4096,10 @@ void wallet2::process_genesis_if_needed(const currency::block& genesis)
if (!m_transfers.empty() || !m_key_images.empty())
return;
THROW_IF_TRUE_WALLET_EX(m_blockchain.size() > 1, error::wallet_internal_error, "Can't change wallet genesis block once the blockchain has been populated");
THROW_IF_TRUE_WALLET_EX(get_blockchain_current_height() > 1, error::wallet_internal_error, "Can't change wallet genesis block once the blockchain has been populated");
crypto::hash genesis_hash = get_block_hash(genesis);
if (m_blockchain.size() == 1 && m_blockchain[0] != genesis_hash)
if (get_blockchain_current_height() == 1 && m_blockchain[0] != genesis_hash)
WLT_LOG_L0("Changing genesis block for wallet " << m_account.get_public_address_str() << ":" << ENDL << " " << m_blockchain[0] << " -> " << genesis_hash);
m_blockchain.clear();
@ -4065,7 +4114,7 @@ void wallet2::process_genesis_if_needed(const currency::block& genesis)
void wallet2::set_genesis(const crypto::hash& genesis_hash)
{
THROW_IF_TRUE_WALLET_EX(m_blockchain.size() != 1, error::wallet_internal_error, "Can't change wallet genesis hash once the blockchain has been populated");
THROW_IF_TRUE_WALLET_EX(get_blockchain_current_height() != 1, error::wallet_internal_error, "Can't change wallet genesis hash once the blockchain has been populated");
WLT_LOG_L0("Changing genesis hash for wallet " << m_account.get_public_address_str() << ":" << ENDL << " " << m_blockchain[0] << " -> " << genesis_hash);
m_blockchain[0] = genesis_hash;
}

View file

@ -44,6 +44,12 @@
#define WALLET_DEFAULT_POS_MINT_PACKING_SIZE 100
#define WALLET_EVERYBLOCK_SIZE 10
#define WALLET_EVERY_10_BLOCKS_SIZE 144
#define WALLET_EVERY_100_BLOCKS_SIZE 144
#define WALLET_EVERY_1000_BLOCKS_SIZE 144
#undef LOG_DEFAULT_CHANNEL
#define LOG_DEFAULT_CHANNEL "wallet"
@ -632,7 +638,9 @@ namespace tools
uint64_t fee, size_t& outs_total, uint64_t& amount_total, size_t& outs_swept, currency::transaction* p_result_tx = nullptr, std::string* p_filename_or_unsigned_tx_blob_str = nullptr);
bool get_transfer_address(const std::string& adr_str, currency::account_public_address& addr, std::string& payment_id);
uint64_t get_blockchain_current_height() const { return m_blockchain.size(); }
uint64_t get_blockchain_current_height() const {
return m_last_10_blocks.empty() ? 0 : (--m_last_10_blocks.end())->first + 1;
}
template <class t_archive>
inline void serialize(t_archive &a, const unsigned int ver)
@ -665,8 +673,21 @@ namespace tools
return;
}
}
//convert from old version
if (ver < CURRENCY_FORMATION_VERSION + 65)
{
//TODO: a & m_blockchain;
}
else
{
a & m_genesis;
a & m_last_10_blocks;
a & m_last_144_blocks_every_10;
a & m_last_144_blocks_every_100;
a & m_last_144_blocks_every_1000;
}
a & m_blockchain;
a & m_transfers;
a & m_multisig_transfers;
a & m_key_images;
@ -870,6 +891,7 @@ private:
bool generate_packing_transaction_if_needed(currency::transaction& tx, uint64_t fake_outputs_number);
bool store_unsigned_tx_to_file_and_reserve_transfers(const finalize_tx_param& ftp, const std::string& filename, std::string* p_unsigned_tx_blob_str = nullptr);
void check_and_throw_if_self_directed_tx_with_payment_id_requested(const construct_tx_param& ctp);
void push_new_block_id(const crypto::hash& id, uint64_t height);
currency::account_base m_account;
bool m_watch_only;
@ -877,7 +899,13 @@ private:
std::wstring m_wallet_file;
std::wstring m_pending_ki_file;
std::string m_password;
std::vector<crypto::hash> m_blockchain;
//std::vector<crypto::hash> m_blockchain;
crypto::hash m_genesis;
std::map<uint64_t, crypto::hash> m_last_10_blocks;
std::map<uint64_t, crypto::hash> m_last_144_blocks_every_10; //1 day
std::map<uint64_t, crypto::hash> m_last_144_blocks_every_100; //10 days
std::map<uint64_t, crypto::hash> m_last_144_blocks_every_1000; //100 days
std::atomic<uint64_t> m_local_bc_height; //temporary workaround
std::atomic<uint64_t> m_last_bc_timestamp;
bool m_do_rise_transfer;