Fix transfers in simplewallet
This commit is contained in:
parent
4363a9f100
commit
c3b1a00085
14 changed files with 272 additions and 74 deletions
165
LICENSE
Normal file
165
LICENSE
Normal file
|
@ -0,0 +1,165 @@
|
|||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
|
@ -1,3 +1,7 @@
|
|||
Release notes 1.0.1
|
||||
|
||||
- Fix transfers in simplewallet
|
||||
|
||||
Release notes 1.0.0
|
||||
|
||||
- Multi-signatures
|
||||
|
|
|
@ -76,6 +76,7 @@ public:
|
|||
std::unique_lock<std::mutex> lk(m_mutex);
|
||||
m_closed = true;
|
||||
m_haveData.notify_all(); // wake up threads in pop()
|
||||
m_haveSpace.notify_all();
|
||||
|
||||
if (wait) {
|
||||
while (!m_queue.empty()) {
|
||||
|
|
|
@ -37,7 +37,8 @@ const unsigned EMISSION_SPEED_FACTOR = 18;
|
|||
static_assert(EMISSION_SPEED_FACTOR <= 8 * sizeof(uint64_t), "Bad EMISSION_SPEED_FACTOR");
|
||||
|
||||
const size_t CRYPTONOTE_REWARD_BLOCKS_WINDOW = 100;
|
||||
const size_t CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE = 10000; //size of block (bytes) after which reward for block calculated using block size
|
||||
const size_t CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE = 20000; //size of block (bytes) after which reward for block calculated using block size
|
||||
const size_t CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V1 = 10000;
|
||||
const size_t CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE = 600;
|
||||
const size_t CRYPTONOTE_DISPLAY_DECIMAL_POINT = 8;
|
||||
// COIN - number of smallest units in one coin
|
||||
|
|
|
@ -84,7 +84,10 @@ namespace cryptonote {
|
|||
|
||||
uint64_t baseReward = (m_moneySupply - alreadyGeneratedCoins) >> m_emissionSpeedFactor;
|
||||
|
||||
medianSize = std::max(medianSize, m_blockGrantedFullRewardZone);
|
||||
size_t blockGrantedFullRewardZone = penalizeFee ?
|
||||
m_blockGrantedFullRewardZone :
|
||||
cryptonote::parameters::CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V1;
|
||||
medianSize = std::max(medianSize, blockGrantedFullRewardZone);
|
||||
if (currentBlockSize > UINT64_C(2) * medianSize) {
|
||||
LOG_PRINT_L4("Block cumulative size is too big: " << currentBlockSize << ", expected less than " << 2 * medianSize);
|
||||
return false;
|
||||
|
|
|
@ -271,7 +271,7 @@ BOOST_CLASS_VERSION(cryptonote::BlockCacheSerializer, CURRENT_BLOCKCACHE_STORAGE
|
|||
blockchain_storage::blockchain_storage(const Currency& currency, tx_memory_pool& tx_pool):
|
||||
m_currency(currency),
|
||||
m_tx_pool(tx_pool),
|
||||
m_current_block_cumul_sz_limit(currency.blockGrantedFullRewardZone() * 2),
|
||||
m_current_block_cumul_sz_limit(0),
|
||||
m_is_in_checkpoint_zone(false),
|
||||
m_is_blockchain_storing(false),
|
||||
m_upgradeDetector(currency, m_blocks, BLOCK_MAJOR_VERSION_2) {
|
||||
|
@ -421,6 +421,8 @@ bool blockchain_storage::init(const std::string& config_folder, bool load_existi
|
|||
return false;
|
||||
}
|
||||
|
||||
update_next_comulative_size_limit();
|
||||
|
||||
uint64_t timestamp_diff = time(NULL) - m_blocks.back().bl.timestamp;
|
||||
if (!m_blocks.back().bl.timestamp) {
|
||||
timestamp_diff = time(NULL) - 1341378000;
|
||||
|
@ -1575,13 +1577,20 @@ bool blockchain_storage::getBlockCumulativeSize(const Block& block, size_t& cumu
|
|||
return missedTxs.empty();
|
||||
}
|
||||
|
||||
// Precondition: m_blockchain_lock is locked.
|
||||
bool blockchain_storage::update_next_comulative_size_limit() {
|
||||
uint8_t nextBlockMajorVersion = get_block_major_version_for_height(m_blocks.size());
|
||||
size_t nextBlockGrantedFullRewardZone = nextBlockMajorVersion == BLOCK_MAJOR_VERSION_1 ?
|
||||
parameters::CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V1 :
|
||||
m_currency.blockGrantedFullRewardZone();
|
||||
|
||||
std::vector<size_t> sz;
|
||||
get_last_n_blocks_sizes(sz, m_currency.rewardBlocksWindow());
|
||||
|
||||
uint64_t median = epee::misc_utils::median(sz);
|
||||
if (median <= m_currency.blockGrantedFullRewardZone())
|
||||
median = m_currency.blockGrantedFullRewardZone();
|
||||
if (median <= nextBlockGrantedFullRewardZone) {
|
||||
median = nextBlockGrantedFullRewardZone;
|
||||
}
|
||||
|
||||
m_current_block_cumul_sz_limit = median * 2;
|
||||
return true;
|
||||
|
@ -1752,7 +1761,6 @@ bool blockchain_storage::pushBlock(const Block& blockData, block_verification_co
|
|||
}
|
||||
|
||||
pushBlock(block);
|
||||
update_next_comulative_size_limit();
|
||||
TIME_MEASURE_FINISH(block_processing_time);
|
||||
LOG_PRINT_L1("+++++ BLOCK SUCCESSFULLY ADDED" << ENDL << "id:\t" << blockHash
|
||||
<< ENDL << "PoW:\t" << proof_of_work
|
||||
|
@ -1764,6 +1772,7 @@ bool blockchain_storage::pushBlock(const Block& blockData, block_verification_co
|
|||
bvc.m_added_to_main_chain = true;
|
||||
|
||||
m_upgradeDetector.blockPushed();
|
||||
update_next_comulative_size_limit();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1097,7 +1097,6 @@ int main(int argc, char* argv[])
|
|||
|
||||
tools::SignalHandler::install([&wrpc, &wal] {
|
||||
wrpc.send_stop_signal();
|
||||
wal.store();
|
||||
});
|
||||
LOG_PRINT_L0("Starting wallet rpc server");
|
||||
wrpc.run();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define BUILD_COMMIT_ID "@VERSION@"
|
||||
#define PROJECT_VERSION "1.0.0"
|
||||
#define PROJECT_VERSION_BUILD_NO "312"
|
||||
#define PROJECT_VERSION "1.0.1"
|
||||
#define PROJECT_VERSION_BUILD_NO "316"
|
||||
#define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO "(" BUILD_COMMIT_ID ")"
|
||||
|
|
|
@ -74,7 +74,7 @@ WalletTransactionSender::WalletTransactionSender(const cryptonote::Currency& cur
|
|||
m_unconfirmedTransactions(unconfirmedTransactions),
|
||||
m_isInitialized(false),
|
||||
m_isStoping(false) {
|
||||
m_upperTransactionSizeLimit = (m_currency.blockGrantedFullRewardZone() * 125) / 100 - m_currency.minerTxBlobReservedSize();
|
||||
m_upperTransactionSizeLimit = (cryptonote::parameters::CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V1 * 125) / 100 - m_currency.minerTxBlobReservedSize();
|
||||
}
|
||||
|
||||
void WalletTransactionSender::init(cryptonote::account_keys keys) {
|
||||
|
|
|
@ -131,7 +131,9 @@ void wallet2::processCheckedTransaction(const TxItem& item) {
|
|||
THROW_WALLET_EXCEPTION_IF(in_ephemeral.pub != boost::get<cryptonote::TransactionOutputToKey>(tx.vout[o].target).key,
|
||||
error::wallet_internal_error, "key_image generated ephemeral public key not matched with output_key");
|
||||
|
||||
m_key_images[td.m_key_image] = m_transfers.size() - 1;
|
||||
auto insertResult = m_key_images.insert(std::make_pair(td.m_key_image, m_transfers.size() - 1));
|
||||
THROW_WALLET_EXCEPTION_IF(!insertResult.second, error::wallet_internal_error, "Key image already exists");
|
||||
|
||||
LOG_PRINT_L0("Received money: " << m_currency.formatAmount(td.amount()) << ", with tx: " << get_transaction_hash(tx));
|
||||
if (0 != m_callback) {
|
||||
m_callback->on_money_received(height, td.m_tx, td.m_internal_output_index);
|
||||
|
@ -286,15 +288,18 @@ void wallet2::get_short_chain_history(std::list<crypto::hash>& ids) const
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
size_t wallet2::updateBlockchain(const cryptonote::COMMAND_RPC_QUERY_BLOCKS::response& res)
|
||||
{
|
||||
size_t wallet2::updateBlockchain(const cryptonote::COMMAND_RPC_QUERY_BLOCKS::response& res, std::unordered_set<crypto::hash>& newBlocks) {
|
||||
size_t blocks_added = 0;
|
||||
size_t current_index = res.start_height;
|
||||
|
||||
// update local blockchain
|
||||
for (const auto& item : res.items) {
|
||||
if (addNewBlockchainEntry(item.block_id, res.start_height, current_index))
|
||||
if (addNewBlockchainEntry(item.block_id, res.start_height, current_index)) {
|
||||
if (!item.block.empty()) {
|
||||
newBlocks.insert(item.block_id);
|
||||
}
|
||||
++blocks_added;
|
||||
}
|
||||
++current_index;
|
||||
}
|
||||
|
||||
|
@ -302,7 +307,7 @@ size_t wallet2::updateBlockchain(const cryptonote::COMMAND_RPC_QUERY_BLOCKS::res
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::processTransactions(const cryptonote::COMMAND_RPC_QUERY_BLOCKS::response& res)
|
||||
void wallet2::processTransactions(const cryptonote::COMMAND_RPC_QUERY_BLOCKS::response& res, const std::unordered_set<crypto::hash>& newBlocks)
|
||||
{
|
||||
size_t checkingThreads = std::thread::hardware_concurrency();
|
||||
|
||||
|
@ -315,13 +320,14 @@ void wallet2::processTransactions(const cryptonote::COMMAND_RPC_QUERY_BLOCKS::re
|
|||
TxQueue checkedQueue(checkingThreads * 2);
|
||||
|
||||
std::atomic<size_t> inputTx(0);
|
||||
std::atomic<size_t> checkedTx(0);
|
||||
|
||||
futures.push_back(std::async(std::launch::async, [&] {
|
||||
try {
|
||||
size_t current_index = res.start_height;
|
||||
for (const auto& item : res.items) {
|
||||
if (newBlocks.count(item.block_id)) {
|
||||
inputTx += processNewBlockchainEntry(incomingQueue, item, item.block_id, current_index);
|
||||
}
|
||||
++current_index;
|
||||
}
|
||||
incomingQueue.close();
|
||||
|
@ -338,7 +344,6 @@ void wallet2::processTransactions(const cryptonote::COMMAND_RPC_QUERY_BLOCKS::re
|
|||
futures.push_back(std::async(std::launch::async, [&] {
|
||||
TxQueueItem item;
|
||||
while (incomingQueue.pop(item)) {
|
||||
++checkedTx;
|
||||
lookup_acc_outs(m_account.get_keys(), item->tx, item->txPubKey, item->outs, item->txMoneyGotInOuts);
|
||||
checkedQueue.push(std::move(item));
|
||||
}
|
||||
|
@ -348,11 +353,19 @@ void wallet2::processTransactions(const cryptonote::COMMAND_RPC_QUERY_BLOCKS::re
|
|||
|
||||
size_t txCount = 0;
|
||||
|
||||
try {
|
||||
TxQueueItem item;
|
||||
while (checkedQueue.pop(item)) {
|
||||
processCheckedTransaction(*item);
|
||||
++txCount;
|
||||
}
|
||||
} catch (...) {
|
||||
checkedQueue.close();
|
||||
for (auto& f : futures) {
|
||||
f.wait();
|
||||
}
|
||||
throw;
|
||||
}
|
||||
|
||||
for (auto& f : futures) {
|
||||
f.get();
|
||||
|
@ -404,12 +417,9 @@ void wallet2::refresh(size_t & blocks_fetched, bool& received_money)
|
|||
{
|
||||
received_money = false;
|
||||
blocks_fetched = 0;
|
||||
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_tx) : null_hash;
|
||||
|
||||
std::future<void> processingTask;
|
||||
|
||||
epee::net_utils::http::http_simple_client queryClient;
|
||||
|
||||
auto r = connectClient(queryClient);
|
||||
|
@ -417,49 +427,46 @@ void wallet2::refresh(size_t & blocks_fetched, bool& received_money)
|
|||
|
||||
auto startTime = std::chrono::high_resolution_clock::now();
|
||||
|
||||
while(m_run.load(std::memory_order_relaxed))
|
||||
{
|
||||
try
|
||||
{
|
||||
auto res = std::make_shared<cryptonote::COMMAND_RPC_QUERY_BLOCKS::response>(queryBlocks(queryClient));
|
||||
cryptonote::COMMAND_RPC_QUERY_BLOCKS::response res;
|
||||
std::unordered_set<crypto::hash> newBlocks;
|
||||
|
||||
if (processingTask.valid())
|
||||
processingTask.get(); // sync with transaction processing
|
||||
size_t lastHeight = m_blockchain.size();
|
||||
size_t added_blocks = 0;
|
||||
|
||||
added_blocks = updateBlockchain(*res);
|
||||
while (m_run.load(std::memory_order_relaxed)) {
|
||||
try {
|
||||
std::future<void> processingTask;
|
||||
if (!newBlocks.empty()) {
|
||||
processingTask = std::async(std::launch::async, [&res, &newBlocks, this] { processTransactions(res, newBlocks); });
|
||||
}
|
||||
|
||||
if (!added_blocks) {
|
||||
cryptonote::COMMAND_RPC_QUERY_BLOCKS::response tempRes = queryBlocks(queryClient);
|
||||
if (!newBlocks.empty()) {
|
||||
processingTask.get();
|
||||
lastHeight = m_blockchain.size();
|
||||
newBlocks.clear();
|
||||
}
|
||||
|
||||
added_blocks = updateBlockchain(tempRes, newBlocks);
|
||||
if (added_blocks == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
res = std::move(tempRes);
|
||||
blocks_fetched += added_blocks;
|
||||
|
||||
bool hasFullBlocks = std::any_of(res->items.begin(), res->items.end(),
|
||||
[](const cryptonote::COMMAND_RPC_QUERY_BLOCKS::response_item& ri) { return !ri.block.empty(); });
|
||||
|
||||
if (hasFullBlocks) {
|
||||
processingTask = std::async(std::launch::async, [res, this] { processTransactions(*res); });
|
||||
}
|
||||
}
|
||||
catch (const std::exception&)
|
||||
{
|
||||
blocks_fetched += added_blocks;
|
||||
if(try_count < 3)
|
||||
{
|
||||
} catch (const std::exception&) {
|
||||
newBlocks.clear();
|
||||
blocks_fetched -= detach_blockchain(lastHeight);
|
||||
if (try_count < 3) {
|
||||
LOG_PRINT_L1("Another try pull_blocks (try_count=" << try_count << ")...");
|
||||
++try_count;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
LOG_ERROR("pull_blocks failed, try_count=" << try_count);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (processingTask.valid())
|
||||
processingTask.get();
|
||||
|
||||
auto duration = std::chrono::high_resolution_clock::now() - startTime;
|
||||
|
||||
if(last_tx_hash_id != (m_transfers.size() ? get_transaction_hash(m_transfers.back().m_tx) : null_hash))
|
||||
|
@ -485,22 +492,23 @@ bool wallet2::refresh(size_t & blocks_fetched, bool& received_money, bool& ok)
|
|||
return ok;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::detach_blockchain(uint64_t height)
|
||||
size_t wallet2::detach_blockchain(uint64_t height)
|
||||
{
|
||||
LOG_PRINT_L0("Detaching blockchain on height " << height);
|
||||
size_t transfers_detached = 0;
|
||||
|
||||
auto it = std::find_if(m_transfers.begin(), m_transfers.end(), [&](const transfer_details& td){return td.m_block_height >= height;});
|
||||
size_t i_start = it - m_transfers.begin();
|
||||
|
||||
for(size_t i = i_start; i!= m_transfers.size();i++)
|
||||
{
|
||||
auto it_ki = m_key_images.find(m_transfers[i].m_key_image);
|
||||
// do not rely on ordering by height in transfers
|
||||
for (auto it = m_transfers.begin(); it != m_transfers.end();) {
|
||||
if (it->m_block_height >= height) {
|
||||
auto it_ki = m_key_images.find(it->m_key_image);
|
||||
THROW_WALLET_EXCEPTION_IF(it_ki == m_key_images.end(), error::wallet_internal_error, "key image not found");
|
||||
m_key_images.erase(it_ki);
|
||||
it = m_transfers.erase(it);
|
||||
++transfers_detached;
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
m_transfers.erase(it, m_transfers.end());
|
||||
|
||||
size_t blocks_detached = m_blockchain.end() - (m_blockchain.begin()+height);
|
||||
m_blockchain.erase(m_blockchain.begin()+height, m_blockchain.end());
|
||||
|
@ -515,6 +523,7 @@ void wallet2::detach_blockchain(uint64_t height)
|
|||
}
|
||||
|
||||
LOG_PRINT_L0("Detached blockchain on height " << height << ", transfers detached " << transfers_detached << ", blocks detached " << blocks_detached);
|
||||
return blocks_detached;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool wallet2::deinit()
|
||||
|
|
|
@ -77,7 +77,7 @@ namespace tools
|
|||
public:
|
||||
wallet2(const cryptonote::Currency& currency) :
|
||||
m_currency(currency), m_run(true), m_callback(0) {
|
||||
m_upper_transaction_size_limit = (m_currency.blockGrantedFullRewardZone() * 125) / 100 - m_currency.minerTxBlobReservedSize();
|
||||
m_upper_transaction_size_limit = (cryptonote::parameters::CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V1 * 125) / 100 - m_currency.minerTxBlobReservedSize();
|
||||
}
|
||||
|
||||
struct transfer_details
|
||||
|
@ -200,11 +200,11 @@ namespace tools
|
|||
void processCheckedTransaction(const TxItem& item);
|
||||
|
||||
// returns number of blocks added
|
||||
size_t updateBlockchain(const cryptonote::COMMAND_RPC_QUERY_BLOCKS::response& res);
|
||||
void processTransactions(const cryptonote::COMMAND_RPC_QUERY_BLOCKS::response& res);
|
||||
size_t updateBlockchain(const cryptonote::COMMAND_RPC_QUERY_BLOCKS::response& res, std::unordered_set<crypto::hash>& newBlocks);
|
||||
void processTransactions(const cryptonote::COMMAND_RPC_QUERY_BLOCKS::response& res, const std::unordered_set<crypto::hash>& newBlocks);
|
||||
cryptonote::COMMAND_RPC_QUERY_BLOCKS::response queryBlocks(epee::net_utils::http::http_simple_client& client);
|
||||
|
||||
void detach_blockchain(uint64_t height);
|
||||
size_t detach_blockchain(uint64_t height);
|
||||
void get_short_chain_history(std::list<crypto::hash>& ids) const;
|
||||
bool is_tx_spendtime_unlocked(uint64_t unlock_time) const;
|
||||
bool is_transfer_unlocked(const transfer_details& td) const;
|
||||
|
|
|
@ -258,7 +258,10 @@ bool test_generator::constructMaxSizeBlock(cryptonote::Block& blk, const crypton
|
|||
getLastNBlockSizes(blockSizes, get_block_hash(blkPrev), medianBlockCount);
|
||||
|
||||
size_t median = misc_utils::median(blockSizes);
|
||||
median = std::max(median, m_currency.blockGrantedFullRewardZone());
|
||||
size_t blockGrantedFullRewardZone = defaultMajorVersion <= BLOCK_MAJOR_VERSION_1 ?
|
||||
cryptonote::parameters::CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V1 :
|
||||
m_currency.blockGrantedFullRewardZone();
|
||||
median = std::max(median, blockGrantedFullRewardZone);
|
||||
|
||||
uint64_t totalFee = 0;
|
||||
size_t txsSize = 0;
|
||||
|
|
|
@ -163,8 +163,8 @@ int main(int argc, char* argv[])
|
|||
GENERATE_AND_PLAY_EX(MultiSigTx_OutputSignatures(1, 1, true));
|
||||
GENERATE_AND_PLAY_EX(MultiSigTx_OutputSignatures(2, 2, true));
|
||||
GENERATE_AND_PLAY_EX(MultiSigTx_OutputSignatures(3, 2, true));
|
||||
GENERATE_AND_PLAY_EX(MultiSigTx_OutputSignatures(0, 0, false));
|
||||
GENERATE_AND_PLAY_EX(MultiSigTx_OutputSignatures(1, 0, false));
|
||||
GENERATE_AND_PLAY_EX(MultiSigTx_OutputSignatures(0, 0, true));
|
||||
GENERATE_AND_PLAY_EX(MultiSigTx_OutputSignatures(1, 0, true));
|
||||
GENERATE_AND_PLAY_EX(MultiSigTx_OutputSignatures(0, 1, false));
|
||||
GENERATE_AND_PLAY_EX(MultiSigTx_OutputSignatures(1, 2, false));
|
||||
GENERATE_AND_PLAY_EX(MultiSigTx_OutputSignatures(2, 3, false));
|
||||
|
|
|
@ -45,6 +45,10 @@ namespace {
|
|||
|
||||
gen_upgrade::gen_upgrade() : m_invalidBlockIndex(0), m_checkBlockTemplateVersionCallCounter(0),
|
||||
m_coinsInCirculationBeforeUpgrade(0), m_coinsInCirculationAfterUpgrade(0) {
|
||||
cryptonote::CurrencyBuilder currencyBuilder;
|
||||
currencyBuilder.maxBlockSizeInitial(std::numeric_limits<size_t>::max() / 2);
|
||||
m_currency = currencyBuilder.currency();
|
||||
|
||||
REGISTER_CALLBACK_METHOD(gen_upgrade, markInvalidBlock);
|
||||
REGISTER_CALLBACK_METHOD(gen_upgrade, checkBlockTemplateVersionIsV1);
|
||||
REGISTER_CALLBACK_METHOD(gen_upgrade, checkBlockTemplateVersionIsV2);
|
||||
|
|
Loading…
Reference in a new issue