aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/blockchain_db/berkeleydb/db_bdb.cpp6
-rw-r--r--src/blockchain_db/berkeleydb/db_bdb.h3
-rw-r--r--src/blockchain_db/blockchain_db.cpp5
-rw-r--r--src/blockchain_db/blockchain_db.h2
-rw-r--r--src/blockchain_db/lmdb/db_lmdb.cpp14
-rw-r--r--src/blockchain_db/lmdb/db_lmdb.h2
-rw-r--r--src/cryptonote_core/blockchain.cpp8
-rw-r--r--src/cryptonote_core/blockchain.h3
-rw-r--r--src/cryptonote_core/hardfork.cpp4
-rw-r--r--tests/unit_tests/CMakeLists.txt1
-rw-r--r--tests/unit_tests/canonical_amounts.cpp83
11 files changed, 120 insertions, 11 deletions
diff --git a/src/blockchain_db/berkeleydb/db_bdb.cpp b/src/blockchain_db/berkeleydb/db_bdb.cpp
index 4799afebc..e37058a99 100644
--- a/src/blockchain_db/berkeleydb/db_bdb.cpp
+++ b/src/blockchain_db/berkeleydb/db_bdb.cpp
@@ -2200,8 +2200,14 @@ void BlockchainBDB::checkpoint_worker() const
LOG_PRINT_L0("Leaving BDB checkpoint thread.");
}
+bool BlockchainBDB::is_read_only() const
+{
+ return false;
+}
+
void BlockchainBDB::fixup()
{
+ LOG_PRINT_L3("BlockchainBDB::" << __func__);
// Always call parent as well
BlockchainDB::fixup();
}
diff --git a/src/blockchain_db/berkeleydb/db_bdb.h b/src/blockchain_db/berkeleydb/db_bdb.h
index ce3da91e8..906b320c7 100644
--- a/src/blockchain_db/berkeleydb/db_bdb.h
+++ b/src/blockchain_db/berkeleydb/db_bdb.h
@@ -405,6 +405,9 @@ private:
uint64_t get_output_global_index(const uint64_t& amount, const uint64_t& index);
void checkpoint_worker() const;
void check_open() const;
+
+ virtual bool is_read_only() const;
+
//
// fix up anything that may be wrong due to past bugs
virtual void fixup();
diff --git a/src/blockchain_db/blockchain_db.cpp b/src/blockchain_db/blockchain_db.cpp
index 4fa8cce26..0635f2000 100644
--- a/src/blockchain_db/blockchain_db.cpp
+++ b/src/blockchain_db/blockchain_db.cpp
@@ -199,6 +199,11 @@ void BlockchainDB::show_stats()
void BlockchainDB::fixup()
{
+ if (is_read_only()) {
+ LOG_PRINT_L1("Database is opened read only - skipping fixup check");
+ return;
+ }
+
// There was a bug that would cause key images for transactions without
// any outputs to not be added to the spent key image set. There are two
// instances of such transactions, in blocks 202612 and 685498.
diff --git a/src/blockchain_db/blockchain_db.h b/src/blockchain_db/blockchain_db.h
index 702de18b5..f6f50d2e9 100644
--- a/src/blockchain_db/blockchain_db.h
+++ b/src/blockchain_db/blockchain_db.h
@@ -503,6 +503,8 @@ public:
virtual void set_hard_fork_version(uint64_t height, uint8_t version) = 0;
virtual uint8_t get_hard_fork_version(uint64_t height) const = 0;
+ virtual bool is_read_only() const = 0;
+
// fix up anything that may be wrong due to past bugs
virtual void fixup();
diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp
index 325ed8b8c..d625e5a07 100644
--- a/src/blockchain_db/lmdb/db_lmdb.cpp
+++ b/src/blockchain_db/lmdb/db_lmdb.cpp
@@ -2496,8 +2496,22 @@ uint8_t BlockchainLMDB::get_hard_fork_version(uint64_t height) const
return ret;
}
+bool BlockchainLMDB::is_read_only() const
+{
+ unsigned int flags;
+ auto result = mdb_env_get_flags(m_env, &flags);
+ if (result)
+ throw0(DB_ERROR(std::string("Error getting database environment info: ").append(mdb_strerror(result)).c_str()));
+
+ if (flags & MDB_RDONLY)
+ return true;
+
+ return false;
+}
+
void BlockchainLMDB::fixup()
{
+ LOG_PRINT_L3("BlockchainLMDB::" << __func__);
// Always call parent as well
BlockchainDB::fixup();
}
diff --git a/src/blockchain_db/lmdb/db_lmdb.h b/src/blockchain_db/lmdb/db_lmdb.h
index d1d3b942d..7332d64c6 100644
--- a/src/blockchain_db/lmdb/db_lmdb.h
+++ b/src/blockchain_db/lmdb/db_lmdb.h
@@ -266,6 +266,8 @@ private:
void check_open() const;
+ virtual bool is_read_only() const;
+
// fix up anything that may be wrong due to past bugs
virtual void fixup();
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp
index 71a2b8841..feb31f2fc 100644
--- a/src/cryptonote_core/blockchain.cpp
+++ b/src/cryptonote_core/blockchain.cpp
@@ -490,7 +490,7 @@ block Blockchain::pop_block_from_blockchain()
}
}
}
- m_tx_pool.on_blockchain_dec(m_blocks.size()-1, get_tail_id());
+ m_tx_pool.on_blockchain_dec(m_db->height()-1, get_tail_id());
return popped_block;
}
@@ -499,11 +499,7 @@ bool Blockchain::reset_and_set_genesis_block(const block& b)
{
LOG_PRINT_L3("Blockchain::" << __func__);
CRITICAL_REGION_LOCAL(m_blockchain_lock);
- m_transactions.clear();
- m_blocks.clear();
- m_blocks_index.clear();
m_alternative_chains.clear();
- m_outputs.clear();
m_db->reset();
block_verification_context bvc = boost::value_initialized<block_verification_context>();
@@ -1251,7 +1247,7 @@ bool Blockchain::handle_alternative_block(const block& b, const crypto::hash& id
{
// if block parent is not part of main chain or an alternate chain,
// we ignore it
- CHECK_AND_ASSERT_MES(parent_in_main, false, "internal error: broken imperative condition it_main_prev != m_blocks_index.end()");
+ CHECK_AND_ASSERT_MES(parent_in_main, false, "internal error: broken imperative condition: parent_in_main");
complete_timestamps_vector(m_db->get_block_height(b.prev_id), timestamps);
}
diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h
index 2f9287e81..bc167f489 100644
--- a/src/cryptonote_core/blockchain.h
+++ b/src/cryptonote_core/blockchain.h
@@ -195,8 +195,6 @@ namespace cryptonote
mutable epee::critical_section m_blockchain_lock; // TODO: add here reader/writer lock
// main chain
- blocks_container m_blocks; // height -> block_extended_info
- blocks_by_id_index m_blocks_index; // crypto::hash -> height
transactions_container m_transactions;
size_t m_current_block_cumul_sz_limit;
@@ -230,7 +228,6 @@ namespace cryptonote
// some invalid blocks
blocks_ext_by_hash m_invalid_blocks; // crypto::hash -> block_extended_info
- outputs_container m_outputs;
checkpoints m_checkpoints;
diff --git a/src/cryptonote_core/hardfork.cpp b/src/cryptonote_core/hardfork.cpp
index 9bd4a337c..e8ac7be98 100644
--- a/src/cryptonote_core/hardfork.cpp
+++ b/src/cryptonote_core/hardfork.cpp
@@ -210,7 +210,7 @@ bool HardFork::reorganize_from_block_height(uint64_t height)
last_versions[n] = 0;
const uint64_t rescan_height = height >= (window_size - 1) ? height - (window_size -1) : 0;
const uint8_t start_version = height == 0 ? original_version : db.get_hard_fork_version(height);
- while (heights[current_fork_index].version > start_version) {
+ while (current_fork_index > 0 && heights[current_fork_index].version > start_version) {
db.set_hard_fork_starting_height(heights[current_fork_index].version, std::numeric_limits<uint64_t>::max());
--current_fork_index;
}
@@ -375,7 +375,7 @@ bool HardFork::get_voting_info(uint8_t version, uint32_t &window, uint32_t &vote
for (size_t n = version; n < 256; ++n)
votes += last_versions[n];
threshold = (window * heights[current_version].threshold + 99) / 100;
- assert((votes >= threshold) == enabled);
+ //assert((votes >= threshold) == enabled);
earliest_height = get_earliest_ideal_height_for_version(version);
voting = heights.back().version;
return enabled;
diff --git a/tests/unit_tests/CMakeLists.txt b/tests/unit_tests/CMakeLists.txt
index caf8e60ff..d13e09002 100644
--- a/tests/unit_tests/CMakeLists.txt
+++ b/tests/unit_tests/CMakeLists.txt
@@ -32,6 +32,7 @@ set(unit_tests_sources
base58.cpp
blockchain_db.cpp
block_reward.cpp
+ canonical_amounts.cpp
chacha8.cpp
checkpoints.cpp
decompose_amount_into_digits.cpp
diff --git a/tests/unit_tests/canonical_amounts.cpp b/tests/unit_tests/canonical_amounts.cpp
new file mode 100644
index 000000000..54159d5d4
--- /dev/null
+++ b/tests/unit_tests/canonical_amounts.cpp
@@ -0,0 +1,83 @@
+// Copyright (c) 2014-2015, The Monero Project
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification, are
+// permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this list of
+// conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice, this list
+// of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its contributors may be
+// used to endorse or promote products derived from this software without specific
+// prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
+
+#include "gtest/gtest.h"
+#include "cryptonote_core/cryptonote_format_utils.h"
+
+static const uint64_t valid_decomposed_outputs[] = {
+ (uint64_t)1, (uint64_t)2, (uint64_t)3, (uint64_t)4, (uint64_t)5, (uint64_t)6, (uint64_t)7, (uint64_t)8, (uint64_t)9, // 1 piconero
+ (uint64_t)10, (uint64_t)20, (uint64_t)30, (uint64_t)40, (uint64_t)50, (uint64_t)60, (uint64_t)70, (uint64_t)80, (uint64_t)90,
+ (uint64_t)100, (uint64_t)200, (uint64_t)300, (uint64_t)400, (uint64_t)500, (uint64_t)600, (uint64_t)700, (uint64_t)800, (uint64_t)900,
+ (uint64_t)1000, (uint64_t)2000, (uint64_t)3000, (uint64_t)4000, (uint64_t)5000, (uint64_t)6000, (uint64_t)7000, (uint64_t)8000, (uint64_t)9000,
+ (uint64_t)10000, (uint64_t)20000, (uint64_t)30000, (uint64_t)40000, (uint64_t)50000, (uint64_t)60000, (uint64_t)70000, (uint64_t)80000, (uint64_t)90000,
+ (uint64_t)100000, (uint64_t)200000, (uint64_t)300000, (uint64_t)400000, (uint64_t)500000, (uint64_t)600000, (uint64_t)700000, (uint64_t)800000, (uint64_t)900000,
+ (uint64_t)1000000, (uint64_t)2000000, (uint64_t)3000000, (uint64_t)4000000, (uint64_t)5000000, (uint64_t)6000000, (uint64_t)7000000, (uint64_t)8000000, (uint64_t)9000000, // 1 micronero
+ (uint64_t)10000000, (uint64_t)20000000, (uint64_t)30000000, (uint64_t)40000000, (uint64_t)50000000, (uint64_t)60000000, (uint64_t)70000000, (uint64_t)80000000, (uint64_t)90000000,
+ (uint64_t)100000000, (uint64_t)200000000, (uint64_t)300000000, (uint64_t)400000000, (uint64_t)500000000, (uint64_t)600000000, (uint64_t)700000000, (uint64_t)800000000, (uint64_t)900000000,
+ (uint64_t)1000000000, (uint64_t)2000000000, (uint64_t)3000000000, (uint64_t)4000000000, (uint64_t)5000000000, (uint64_t)6000000000, (uint64_t)7000000000, (uint64_t)8000000000, (uint64_t)9000000000,
+ (uint64_t)10000000000, (uint64_t)20000000000, (uint64_t)30000000000, (uint64_t)40000000000, (uint64_t)50000000000, (uint64_t)60000000000, (uint64_t)70000000000, (uint64_t)80000000000, (uint64_t)90000000000,
+ (uint64_t)100000000000, (uint64_t)200000000000, (uint64_t)300000000000, (uint64_t)400000000000, (uint64_t)500000000000, (uint64_t)600000000000, (uint64_t)700000000000, (uint64_t)800000000000, (uint64_t)900000000000,
+ (uint64_t)1000000000000, (uint64_t)2000000000000, (uint64_t)3000000000000, (uint64_t)4000000000000, (uint64_t)5000000000000, (uint64_t)6000000000000, (uint64_t)7000000000000, (uint64_t)8000000000000, (uint64_t)9000000000000, // 1 monero
+ (uint64_t)10000000000000, (uint64_t)20000000000000, (uint64_t)30000000000000, (uint64_t)40000000000000, (uint64_t)50000000000000, (uint64_t)60000000000000, (uint64_t)70000000000000, (uint64_t)80000000000000, (uint64_t)90000000000000,
+ (uint64_t)100000000000000, (uint64_t)200000000000000, (uint64_t)300000000000000, (uint64_t)400000000000000, (uint64_t)500000000000000, (uint64_t)600000000000000, (uint64_t)700000000000000, (uint64_t)800000000000000, (uint64_t)900000000000000,
+ (uint64_t)1000000000000000, (uint64_t)2000000000000000, (uint64_t)3000000000000000, (uint64_t)4000000000000000, (uint64_t)5000000000000000, (uint64_t)6000000000000000, (uint64_t)7000000000000000, (uint64_t)8000000000000000, (uint64_t)9000000000000000,
+ (uint64_t)10000000000000000, (uint64_t)20000000000000000, (uint64_t)30000000000000000, (uint64_t)40000000000000000, (uint64_t)50000000000000000, (uint64_t)60000000000000000, (uint64_t)70000000000000000, (uint64_t)80000000000000000, (uint64_t)90000000000000000,
+ (uint64_t)100000000000000000, (uint64_t)200000000000000000, (uint64_t)300000000000000000, (uint64_t)400000000000000000, (uint64_t)500000000000000000, (uint64_t)600000000000000000, (uint64_t)700000000000000000, (uint64_t)800000000000000000, (uint64_t)900000000000000000,
+ (uint64_t)1000000000000000000, (uint64_t)2000000000000000000, (uint64_t)3000000000000000000, (uint64_t)4000000000000000000, (uint64_t)5000000000000000000, (uint64_t)6000000000000000000, (uint64_t)7000000000000000000, (uint64_t)8000000000000000000, (uint64_t)9000000000000000000, // 1 meganero
+ (uint64_t)10000000000000000000ull
+};
+
+TEST(canonical_amounts, valid)
+{
+ for (size_t n = 0; n < sizeof(valid_decomposed_outputs) / sizeof(valid_decomposed_outputs[0]); ++n)
+ {
+ ASSERT_TRUE(cryptonote::is_valid_decomposed_amount(valid_decomposed_outputs[n]));
+ }
+}
+
+TEST(canonical_amounts, invalid)
+{
+ for (size_t n = 0; n < sizeof(valid_decomposed_outputs) / sizeof(valid_decomposed_outputs[0]); ++n)
+ {
+ // 10 and below have adjacent valid decomposed amounts
+ if (valid_decomposed_outputs[n] > 10)
+ {
+ ASSERT_FALSE(cryptonote::is_valid_decomposed_amount(valid_decomposed_outputs[n]+1));
+ ASSERT_FALSE(cryptonote::is_valid_decomposed_amount(valid_decomposed_outputs[n]-1));
+ }
+ }
+
+ ASSERT_FALSE(cryptonote::is_valid_decomposed_amount(0));
+ ASSERT_FALSE(cryptonote::is_valid_decomposed_amount(11));
+ ASSERT_FALSE(cryptonote::is_valid_decomposed_amount((uint64_t)-1));
+ ASSERT_FALSE(cryptonote::is_valid_decomposed_amount(10000000000001ul));
+ ASSERT_FALSE(cryptonote::is_valid_decomposed_amount(11000000000000ul));
+}
+