aboutsummaryrefslogtreecommitdiff
path: root/src/cryptonote_core
diff options
context:
space:
mode:
authorkenshi84 <kenshi84@protonmail.ch>2017-01-27 00:07:23 +0900
committerkenshi84 <kenshi84@protonmail.ch>2017-02-08 22:45:15 +0900
commit8027ce0c75f882de0523e668defa0bc3c8564e96 (patch)
tree40066ffa7c7afb28907291c93863d8cfdb14920c /src/cryptonote_core
parentMerge pull request #1679 (diff)
downloadmonero-8027ce0c75f882de0523e668defa0bc3c8564e96.tar.xz
extract some basic code from libcryptonote_core into libcryptonote_basic
Diffstat (limited to 'src/cryptonote_core')
-rw-r--r--src/cryptonote_core/CMakeLists.txt23
-rw-r--r--src/cryptonote_core/account.cpp143
-rw-r--r--src/cryptonote_core/account.h92
-rw-r--r--src/cryptonote_core/account_boost_serialization.h57
-rw-r--r--src/cryptonote_core/blockchain.cpp11
-rw-r--r--src/cryptonote_core/blockchain.h12
-rw-r--r--src/cryptonote_core/checkpoints.cpp368
-rw-r--r--src/cryptonote_core/checkpoints.h217
-rw-r--r--src/cryptonote_core/connection_context.h77
-rw-r--r--src/cryptonote_core/cryptonote_basic.h397
-rw-r--r--src/cryptonote_core/cryptonote_basic_impl.cpp347
-rw-r--r--src/cryptonote_core/cryptonote_basic_impl.h142
-rw-r--r--src/cryptonote_core/cryptonote_boost_serialization.h301
-rw-r--r--src/cryptonote_core/cryptonote_core.cpp4
-rw-r--r--src/cryptonote_core/cryptonote_core.h6
-rw-r--r--src/cryptonote_core/cryptonote_format_utils.cpp1193
-rw-r--r--src/cryptonote_core/cryptonote_format_utils.h274
-rw-r--r--src/cryptonote_core/cryptonote_stat_info.h53
-rw-r--r--src/cryptonote_core/cryptonote_tx_utils.cpp493
-rw-r--r--src/cryptonote_core/cryptonote_tx_utils.h101
-rw-r--r--src/cryptonote_core/difficulty.cpp165
-rw-r--r--src/cryptonote_core/difficulty.h56
-rw-r--r--src/cryptonote_core/hardfork.cpp416
-rw-r--r--src/cryptonote_core/hardfork.h265
-rw-r--r--src/cryptonote_core/miner.cpp414
-rw-r--r--src/cryptonote_core/miner.h126
-rw-r--r--src/cryptonote_core/tx_extra.h182
-rw-r--r--src/cryptonote_core/tx_pool.cpp4
-rw-r--r--src/cryptonote_core/tx_pool.h4
-rw-r--r--src/cryptonote_core/verification_context.h61
30 files changed, 616 insertions, 5388 deletions
diff --git a/src/cryptonote_core/CMakeLists.txt b/src/cryptonote_core/CMakeLists.txt
index ad1745b7f..a5f25041b 100644
--- a/src/cryptonote_core/CMakeLists.txt
+++ b/src/cryptonote_core/CMakeLists.txt
@@ -27,38 +27,19 @@
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set(cryptonote_core_sources
- account.cpp
blockchain.cpp
- checkpoints.cpp
- cryptonote_basic_impl.cpp
cryptonote_core.cpp
- cryptonote_format_utils.cpp
- difficulty.cpp
- miner.cpp
tx_pool.cpp
- hardfork.cpp)
+ cryptonote_tx_utils.cpp)
set(cryptonote_core_headers)
set(cryptonote_core_private_headers
- account.h
- account_boost_serialization.h
blockchain_storage_boost_serialization.h
blockchain.h
- checkpoints.h
- connection_context.h
- cryptonote_basic.h
- cryptonote_basic_impl.h
- cryptonote_boost_serialization.h
cryptonote_core.h
- cryptonote_format_utils.h
- cryptonote_stat_info.h
- difficulty.h
- miner.h
- tx_extra.h
tx_pool.h
- verification_context.h
- hardfork.h)
+ cryptonote_tx_utils.h)
if(PER_BLOCK_CHECKPOINT)
set(Blocks "blocks")
diff --git a/src/cryptonote_core/account.cpp b/src/cryptonote_core/account.cpp
deleted file mode 100644
index 8f2db6863..000000000
--- a/src/cryptonote_core/account.cpp
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright (c) 2014-2016, 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 <fstream>
-
-#include "include_base_utils.h"
-#include "account.h"
-#include "warnings.h"
-#include "crypto/crypto.h"
-extern "C"
-{
-#include "crypto/keccak.h"
-}
-#include "cryptonote_core/cryptonote_basic_impl.h"
-#include "cryptonote_core/cryptonote_format_utils.h"
-
-#undef MONERO_DEFAULT_LOG_CATEGORY
-#define MONERO_DEFAULT_LOG_CATEGORY "account"
-
-using namespace std;
-
-DISABLE_VS_WARNINGS(4244 4345)
-
- namespace cryptonote
-{
- //-----------------------------------------------------------------
- account_base::account_base()
- {
- set_null();
- }
- //-----------------------------------------------------------------
- void account_base::set_null()
- {
- m_keys = account_keys();
- }
- //-----------------------------------------------------------------
- void account_base::forget_spend_key()
- {
- m_keys.m_spend_secret_key = crypto::secret_key();
- }
- //-----------------------------------------------------------------
- crypto::secret_key account_base::generate(const crypto::secret_key& recovery_key, bool recover, bool two_random)
- {
- crypto::secret_key first = generate_keys(m_keys.m_account_address.m_spend_public_key, m_keys.m_spend_secret_key, recovery_key, recover);
-
- // rng for generating second set of keys is hash of first rng. means only one set of electrum-style words needed for recovery
- crypto::secret_key second;
- keccak((uint8_t *)&m_keys.m_spend_secret_key, sizeof(crypto::secret_key), (uint8_t *)&second, sizeof(crypto::secret_key));
-
- generate_keys(m_keys.m_account_address.m_view_public_key, m_keys.m_view_secret_key, second, two_random ? false : true);
-
- struct tm timestamp = {0};
- timestamp.tm_year = 2014 - 1900; // year 2014
- timestamp.tm_mon = 6 - 1; // month june
- timestamp.tm_mday = 8; // 8th of june
- timestamp.tm_hour = 0;
- timestamp.tm_min = 0;
- timestamp.tm_sec = 0;
-
- if (recover)
- {
- m_creation_timestamp = mktime(&timestamp);
- if (m_creation_timestamp == (uint64_t)-1) // failure
- m_creation_timestamp = 0; // lowest value
- }
- else
- {
- m_creation_timestamp = time(NULL);
- }
- return first;
- }
- //-----------------------------------------------------------------
- void account_base::create_from_keys(const cryptonote::account_public_address& address, const crypto::secret_key& spendkey, const crypto::secret_key& viewkey)
- {
- m_keys.m_account_address = address;
- m_keys.m_spend_secret_key = spendkey;
- m_keys.m_view_secret_key = viewkey;
-
- struct tm timestamp = {0};
- timestamp.tm_year = 2014 - 1900; // year 2014
- timestamp.tm_mon = 4 - 1; // month april
- timestamp.tm_mday = 15; // 15th of april
- timestamp.tm_hour = 0;
- timestamp.tm_min = 0;
- timestamp.tm_sec = 0;
-
- m_creation_timestamp = mktime(&timestamp);
- if (m_creation_timestamp == (uint64_t)-1) // failure
- m_creation_timestamp = 0; // lowest value
- }
- //-----------------------------------------------------------------
- void account_base::create_from_viewkey(const cryptonote::account_public_address& address, const crypto::secret_key& viewkey)
- {
- crypto::secret_key fake;
- memset(&fake, 0, sizeof(fake));
- create_from_keys(address, fake, viewkey);
- }
- //-----------------------------------------------------------------
- const account_keys& account_base::get_keys() const
- {
- return m_keys;
- }
- //-----------------------------------------------------------------
- std::string account_base::get_public_address_str(bool testnet) const
- {
- //TODO: change this code into base 58
- return get_account_address_as_str(testnet, m_keys.m_account_address);
- }
- //-----------------------------------------------------------------
- std::string account_base::get_public_integrated_address_str(const crypto::hash8 &payment_id, bool testnet) const
- {
- //TODO: change this code into base 58
- return get_account_integrated_address_as_str(testnet, m_keys.m_account_address, payment_id);
- }
- //-----------------------------------------------------------------
-}
diff --git a/src/cryptonote_core/account.h b/src/cryptonote_core/account.h
deleted file mode 100644
index 41a119b07..000000000
--- a/src/cryptonote_core/account.h
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright (c) 2014-2016, 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
-
-#pragma once
-
-#include "cryptonote_core/cryptonote_basic.h"
-#include "crypto/crypto.h"
-#include "serialization/keyvalue_serialization.h"
-
-namespace cryptonote
-{
-
- struct account_keys
- {
- account_public_address m_account_address;
- crypto::secret_key m_spend_secret_key;
- crypto::secret_key m_view_secret_key;
-
- BEGIN_KV_SERIALIZE_MAP()
- KV_SERIALIZE(m_account_address)
- KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE(m_spend_secret_key)
- KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE(m_view_secret_key)
- END_KV_SERIALIZE_MAP()
- };
-
- /************************************************************************/
- /* */
- /************************************************************************/
- class account_base
- {
- public:
- account_base();
- crypto::secret_key generate(const crypto::secret_key& recovery_key = crypto::secret_key(), bool recover = false, bool two_random = false);
- void create_from_keys(const cryptonote::account_public_address& address, const crypto::secret_key& spendkey, const crypto::secret_key& viewkey);
- void create_from_viewkey(const cryptonote::account_public_address& address, const crypto::secret_key& viewkey);
- const account_keys& get_keys() const;
- std::string get_public_address_str(bool testnet) const;
- std::string get_public_integrated_address_str(const crypto::hash8 &payment_id, bool testnet) const;
-
- uint64_t get_createtime() const { return m_creation_timestamp; }
- void set_createtime(uint64_t val) { m_creation_timestamp = val; }
-
- bool load(const std::string& file_path);
- bool store(const std::string& file_path);
-
- void forget_spend_key();
-
- template <class t_archive>
- inline void serialize(t_archive &a, const unsigned int /*ver*/)
- {
- a & m_keys;
- a & m_creation_timestamp;
- }
-
- BEGIN_KV_SERIALIZE_MAP()
- KV_SERIALIZE(m_keys)
- KV_SERIALIZE(m_creation_timestamp)
- END_KV_SERIALIZE_MAP()
-
- private:
- void set_null();
- account_keys m_keys;
- uint64_t m_creation_timestamp;
- };
-}
diff --git a/src/cryptonote_core/account_boost_serialization.h b/src/cryptonote_core/account_boost_serialization.h
deleted file mode 100644
index 4151d9b50..000000000
--- a/src/cryptonote_core/account_boost_serialization.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (c) 2014-2016, 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
-
-#pragma once
-
-#include "account.h"
-#include "cryptonote_core/cryptonote_boost_serialization.h"
-
-//namespace cryptonote {
-namespace boost
-{
- namespace serialization
- {
- template <class Archive>
- inline void serialize(Archive &a, cryptonote::account_keys &x, const boost::serialization::version_type ver)
- {
- a & x.m_account_address;
- a & x.m_spend_secret_key;
- a & x.m_view_secret_key;
- }
-
- template <class Archive>
- inline void serialize(Archive &a, cryptonote::account_public_address &x, const boost::serialization::version_type ver)
- {
- a & x.m_spend_public_key;
- a & x.m_view_public_key;
- }
-
- }
-}
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp
index b344c5597..a81286632 100644
--- a/src/cryptonote_core/blockchain.cpp
+++ b/src/cryptonote_core/blockchain.cpp
@@ -34,14 +34,13 @@
#include <boost/range/adaptor/reversed.hpp>
#include "include_base_utils.h"
-#include "cryptonote_basic_impl.h"
+#include "cryptonote_basic/cryptonote_basic_impl.h"
#include "tx_pool.h"
#include "blockchain.h"
#include "blockchain_db/blockchain_db.h"
-#include "cryptonote_format_utils.h"
-#include "cryptonote_boost_serialization.h"
+#include "cryptonote_basic/cryptonote_boost_serialization.h"
#include "cryptonote_config.h"
-#include "miner.h"
+#include "cryptonote_basic/miner.h"
#include "misc_language.h"
#include "profile_tools.h"
#include "file_io_utils.h"
@@ -49,8 +48,8 @@
#include "common/boost_serialization_helper.h"
#include "warnings.h"
#include "crypto/hash.h"
-#include "cryptonote_core/checkpoints.h"
-#include "cryptonote_core/cryptonote_core.h"
+#include "cryptonote_basic/checkpoints.h"
+#include "cryptonote_core.h"
#include "ringct/rctSigs.h"
#include "common/perf_timer.h"
#if defined(PER_BLOCK_CHECKPOINT)
diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h
index cd452faf4..c806c3505 100644
--- a/src/cryptonote_core/blockchain.h
+++ b/src/cryptonote_core/blockchain.h
@@ -42,16 +42,16 @@
#include "syncobj.h"
#include "string_tools.h"
-#include "cryptonote_basic.h"
+#include "cryptonote_basic/cryptonote_basic.h"
#include "common/util.h"
#include "cryptonote_protocol/cryptonote_protocol_defs.h"
#include "rpc/core_rpc_server_commands_defs.h"
-#include "difficulty.h"
-#include "cryptonote_core/cryptonote_format_utils.h"
-#include "verification_context.h"
+#include "cryptonote_basic/difficulty.h"
+#include "cryptonote_tx_utils.h"
+#include "cryptonote_basic/verification_context.h"
#include "crypto/hash.h"
-#include "checkpoints.h"
-#include "hardfork.h"
+#include "cryptonote_basic/checkpoints.h"
+#include "cryptonote_basic/hardfork.h"
#include "blockchain_db/blockchain_db.h"
namespace cryptonote
diff --git a/src/cryptonote_core/checkpoints.cpp b/src/cryptonote_core/checkpoints.cpp
deleted file mode 100644
index 3cf804ede..000000000
--- a/src/cryptonote_core/checkpoints.cpp
+++ /dev/null
@@ -1,368 +0,0 @@
-// Copyright (c) 2014-2016, 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 "include_base_utils.h"
-
-using namespace epee;
-
-#include "checkpoints.h"
-
-#include "common/dns_utils.h"
-#include "include_base_utils.h"
-#include <sstream>
-#include <random>
-
-#undef MONERO_DEFAULT_LOG_CATEGORY
-#define MONERO_DEFAULT_LOG_CATEGORY "checkpoints"
-
-namespace
-{
- bool dns_records_match(const std::vector<std::string>& a, const std::vector<std::string>& b)
- {
- if (a.size() != b.size()) return false;
-
- for (const auto& record_in_a : a)
- {
- bool ok = false;
- for (const auto& record_in_b : b)
- {
- if (record_in_a == record_in_b)
- {
- ok = true;
- break;
- }
- }
- if (!ok) return false;
- }
-
- return true;
- }
-} // anonymous namespace
-
-namespace cryptonote
-{
- //---------------------------------------------------------------------------
- checkpoints::checkpoints()
- {
- }
- //---------------------------------------------------------------------------
- bool checkpoints::add_checkpoint(uint64_t height, const std::string& hash_str)
- {
- crypto::hash h = null_hash;
- bool r = epee::string_tools::parse_tpod_from_hex_string(hash_str, h);
- CHECK_AND_ASSERT_MES(r, false, "Failed to parse checkpoint hash string into binary representation!");
-
- // return false if adding at a height we already have AND the hash is different
- if (m_points.count(height))
- {
- CHECK_AND_ASSERT_MES(h == m_points[height], false, "Checkpoint at given height already exists, and hash for new checkpoint was different!");
- }
- m_points[height] = h;
- return true;
- }
- //---------------------------------------------------------------------------
- bool checkpoints::is_in_checkpoint_zone(uint64_t height) const
- {
- return !m_points.empty() && (height <= (--m_points.end())->first);
- }
- //---------------------------------------------------------------------------
- bool checkpoints::check_block(uint64_t height, const crypto::hash& h, bool& is_a_checkpoint) const
- {
- auto it = m_points.find(height);
- is_a_checkpoint = it != m_points.end();
- if(!is_a_checkpoint)
- return true;
-
- if(it->second == h)
- {
- MINFO("CHECKPOINT PASSED FOR HEIGHT " << height << " " << h);
- return true;
- }else
- {
- MWARNING("CHECKPOINT FAILED FOR HEIGHT " << height << ". EXPECTED HASH: " << it->second << ", FETCHED HASH: " << h);
- return false;
- }
- }
- //---------------------------------------------------------------------------
- bool checkpoints::check_block(uint64_t height, const crypto::hash& h) const
- {
- bool ignored;
- return check_block(height, h, ignored);
- }
- //---------------------------------------------------------------------------
- //FIXME: is this the desired behavior?
- bool checkpoints::is_alternative_block_allowed(uint64_t blockchain_height, uint64_t block_height) const
- {
- if (0 == block_height)
- return false;
-
- auto it = m_points.upper_bound(blockchain_height);
- // Is blockchain_height before the first checkpoint?
- if (it == m_points.begin())
- return true;
-
- --it;
- uint64_t checkpoint_height = it->first;
- return checkpoint_height < block_height;
- }
- //---------------------------------------------------------------------------
- uint64_t checkpoints::get_max_height() const
- {
- std::map< uint64_t, crypto::hash >::const_iterator highest =
- std::max_element( m_points.begin(), m_points.end(),
- ( boost::bind(&std::map< uint64_t, crypto::hash >::value_type::first, _1) <
- boost::bind(&std::map< uint64_t, crypto::hash >::value_type::first, _2 ) ) );
- return highest->first;
- }
- //---------------------------------------------------------------------------
- const std::map<uint64_t, crypto::hash>& checkpoints::get_points() const
- {
- return m_points;
- }
-
- bool checkpoints::check_for_conflicts(const checkpoints& other) const
- {
- for (auto& pt : other.get_points())
- {
- if (m_points.count(pt.first))
- {
- CHECK_AND_ASSERT_MES(pt.second == m_points.at(pt.first), false, "Checkpoint at given height already exists, and hash for new checkpoint was different!");
- }
- }
- return true;
- }
-
- bool checkpoints::init_default_checkpoints()
- {
- ADD_CHECKPOINT(1, "771fbcd656ec1464d3a02ead5e18644030007a0fc664c0a964d30922821a8148");
- ADD_CHECKPOINT(10, "c0e3b387e47042f72d8ccdca88071ff96bff1ac7cde09ae113dbb7ad3fe92381");
- ADD_CHECKPOINT(100, "ac3e11ca545e57c49fca2b4e8c48c03c23be047c43e471e1394528b1f9f80b2d");
- ADD_CHECKPOINT(1000, "5acfc45acffd2b2e7345caf42fa02308c5793f15ec33946e969e829f40b03876");
- ADD_CHECKPOINT(10000, "c758b7c81f928be3295d45e230646de8b852ec96a821eac3fea4daf3fcac0ca2");
- ADD_CHECKPOINT(22231, "7cb10e29d67e1c069e6e11b17d30b809724255fee2f6868dc14cfc6ed44dfb25");
- ADD_CHECKPOINT(29556, "53c484a8ed91e4da621bb2fa88106dbde426fe90d7ef07b9c1e5127fb6f3a7f6");
- ADD_CHECKPOINT(50000, "0fe8758ab06a8b9cb35b7328fd4f757af530a5d37759f9d3e421023231f7b31c");
- ADD_CHECKPOINT(80000, "a62dcd7b536f22e003ebae8726e9e7276f63d594e264b6f0cd7aab27b66e75e3");
- ADD_CHECKPOINT(202612, "bbd604d2ba11ba27935e006ed39c9bfdd99b76bf4a50654bc1e1e61217962698");
- ADD_CHECKPOINT(202613, "e2aa337e78df1f98f462b3b1e560c6b914dec47b610698b7b7d1e3e86b6197c2");
- ADD_CHECKPOINT(202614, "c29e3dc37d8da3e72e506e31a213a58771b24450144305bcba9e70fa4d6ea6fb");
- ADD_CHECKPOINT(205000, "5d3d7a26e6dc7535e34f03def711daa8c263785f73ec1fadef8a45880fde8063");
- ADD_CHECKPOINT(220000, "9613f455933c00e3e33ac315cc6b455ee8aa0c567163836858c2d9caff111553");
- ADD_CHECKPOINT(230300, "bae7a80c46859db355556e3a9204a337ae8f24309926a1312323fdecf1920e61");
- ADD_CHECKPOINT(230700, "93e631240ceac831da1aebfc5dac8f722c430463024763ebafa888796ceaeedf");
- ADD_CHECKPOINT(231350, "b5add137199b820e1ea26640e5c3e121fd85faa86a1e39cf7e6cc097bdeb1131");
- ADD_CHECKPOINT(232150, "955de8e6b6508af2c24f7334f97beeea651d78e9ade3ab18fec3763be3201aa8");
- ADD_CHECKPOINT(249380, "654fb0a81ce3e5caf7e3264a70f447d4bd07586c08fa50f6638cc54da0a52b2d");
- ADD_CHECKPOINT(460000, "75037a7aed3e765db96c75bcf908f59d690a5f3390baebb9edeafd336a1c4831");
- ADD_CHECKPOINT(500000, "2428f0dbe49796be05ed81b347f53e1f7f44aed0abf641446ec2b94cae066b02");
- ADD_CHECKPOINT(600000, "f5828ebf7d7d1cb61762c4dfe3ccf4ecab2e1aad23e8113668d981713b7a54c5");
- ADD_CHECKPOINT(700000, "12be9b3d210b93f574d2526abb9c1ab2a881b479131fd0d4f7dac93875f503cd");
- ADD_CHECKPOINT(825000, "56503f9ad766774b575be3aff73245e9d159be88132c93d1754764f28da2ff60");
- ADD_CHECKPOINT(900000, "d9958d0e7dcf91a5a7b11de225927bf7efc6eb26240315ce12372be902cc1337");
- ADD_CHECKPOINT(913193, "5292d5d56f6ba4de33a58d9a34d263e2cb3c6fee0aed2286fd4ac7f36d53c85f");
- ADD_CHECKPOINT(1000000, "a886ef5149902d8342475fee9bb296341b891ac67c4842f47a833f23c00ed721");
- ADD_CHECKPOINT(1100000, "3fd720c5c8b3072fc1ccda922dec1ef25f9ed88a1e6ad4103d0fe00b180a5903");
- ADD_CHECKPOINT(1150000, "1dd16f626d18e1e988490dfd06de5920e22629c972c58b4d8daddea0038627b2");
- ADD_CHECKPOINT(1200000, "fa7d13a90850882060479d100141ff84286599ae39c3277c8ea784393f882d1f");
-
-
- return true;
- }
-
- bool checkpoints::load_checkpoints_from_json(const std::string json_hashfile_fullpath)
- {
- boost::system::error_code errcode;
- if (! (boost::filesystem::exists(json_hashfile_fullpath, errcode)))
- {
- LOG_PRINT_L1("Blockchain checkpoints file not found");
- return true;
- }
-
- LOG_PRINT_L1("Adding checkpoints from blockchain hashfile");
-
- uint64_t prev_max_height = get_max_height();
- LOG_PRINT_L1("Hard-coded max checkpoint height is " << prev_max_height);
- t_hash_json hashes;
- epee::serialization::load_t_from_json_file(hashes, json_hashfile_fullpath);
- for (std::vector<t_hashline>::const_iterator it = hashes.hashlines.begin(); it != hashes.hashlines.end(); )
- {
- uint64_t height;
- height = it->height;
- if (height <= prev_max_height) {
- LOG_PRINT_L1("ignoring checkpoint height " << height);
- } else {
- std::string blockhash = it->hash;
- LOG_PRINT_L1("Adding checkpoint height " << height << ", hash=" << blockhash);
- ADD_CHECKPOINT(height, blockhash);
- }
- ++it;
- }
-
- return true;
- }
-
- bool checkpoints::load_checkpoints_from_dns(bool testnet)
- {
- // All four MoneroPulse domains have DNSSEC on and valid
- static const std::vector<std::string> dns_urls = { "checkpoints.moneropulse.se"
- , "checkpoints.moneropulse.org"
- , "checkpoints.moneropulse.net"
- , "checkpoints.moneropulse.co"
- };
-
- static const std::vector<std::string> testnet_dns_urls = { "testpoints.moneropulse.se"
- , "testpoints.moneropulse.org"
- , "testpoints.moneropulse.net"
- , "testpoints.moneropulse.co"
- };
-
- std::vector<std::vector<std::string> > records;
- records.resize(dns_urls.size());
-
- std::random_device rd;
- std::mt19937 gen(rd());
- std::uniform_int_distribution<int> dis(0, dns_urls.size() - 1);
- size_t first_index = dis(gen);
-
- bool avail, valid;
- size_t cur_index = first_index;
- do
- {
- std::string url;
- if (testnet)
- {
- url = testnet_dns_urls[cur_index];
- }
- else
- {
- url = dns_urls[cur_index];
- }
-
- records[cur_index] = tools::DNSResolver::instance().get_txt_record(url, avail, valid);
- if (!avail)
- {
- records[cur_index].clear();
- LOG_PRINT_L2("DNSSEC not available for checkpoint update at URL: " << url << ", skipping.");
- }
- if (!valid)
- {
- records[cur_index].clear();
- LOG_PRINT_L2("DNSSEC validation failed for checkpoint update at URL: " << url << ", skipping.");
- }
-
- cur_index++;
- if (cur_index == dns_urls.size())
- {
- cur_index = 0;
- }
- records[cur_index].clear();
- } while (cur_index != first_index);
-
- size_t num_valid_records = 0;
-
- for( const auto& record_set : records)
- {
- if (record_set.size() != 0)
- {
- num_valid_records++;
- }
- }
-
- if (num_valid_records < 2)
- {
- LOG_PRINT_L0("WARNING: no two valid MoneroPulse DNS checkpoint records were received");
- return true;
- }
-
- int good_records_index = -1;
- for (size_t i = 0; i < records.size() - 1; ++i)
- {
- if (records[i].size() == 0) continue;
-
- for (size_t j = i + 1; j < records.size(); ++j)
- {
- if (dns_records_match(records[i], records[j]))
- {
- good_records_index = i;
- break;
- }
- }
- if (good_records_index >= 0) break;
- }
-
- if (good_records_index < 0)
- {
- LOG_PRINT_L0("WARNING: no two MoneroPulse DNS checkpoint records matched");
- return true;
- }
-
- for (auto& record : records[good_records_index])
- {
- auto pos = record.find(":");
- if (pos != std::string::npos)
- {
- uint64_t height;
- crypto::hash hash;
-
- // parse the first part as uint64_t,
- // if this fails move on to the next record
- std::stringstream ss(record.substr(0, pos));
- if (!(ss >> height))
- {
- continue;
- }
-
- // parse the second part as crypto::hash,
- // if this fails move on to the next record
- std::string hashStr = record.substr(pos + 1);
- if (!epee::string_tools::parse_tpod_from_hex_string(hashStr, hash))
- {
- continue;
- }
-
- ADD_CHECKPOINT(height, hashStr);
- }
- }
- return true;
- }
-
- bool checkpoints::load_new_checkpoints(const std::string json_hashfile_fullpath, bool testnet, bool dns)
- {
- bool result;
-
- result = load_checkpoints_from_json(json_hashfile_fullpath);
- if (dns)
- {
- result &= load_checkpoints_from_dns(testnet);
- }
-
- return result;
- }
-}
diff --git a/src/cryptonote_core/checkpoints.h b/src/cryptonote_core/checkpoints.h
deleted file mode 100644
index 71727753e..000000000
--- a/src/cryptonote_core/checkpoints.h
+++ /dev/null
@@ -1,217 +0,0 @@
-// Copyright (c) 2014-2016, 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
-
-#pragma once
-#include <map>
-#include <vector>
-#include "cryptonote_basic_impl.h"
-#include "misc_log_ex.h"
-#include "storages/portable_storage_template_helper.h" // epee json include
-
-#define ADD_CHECKPOINT(h, hash) CHECK_AND_ASSERT(add_checkpoint(h, hash), false);
-#define JSON_HASH_FILE_NAME "checkpoints.json"
-
-
-namespace cryptonote
-{
- /**
- * @brief A container for blockchain checkpoints
- *
- * A checkpoint is a pre-defined hash for the block at a given height.
- * Some of these are compiled-in, while others can be loaded at runtime
- * either from a json file or via DNS from a checkpoint-hosting server.
- */
- class checkpoints
- {
- public:
-
- /**
- * @brief default constructor
- */
- checkpoints();
-
- /**
- * @brief adds a checkpoint to the container
- *
- * @param height the height of the block the checkpoint is for
- * @param hash_str the hash of the block, as a string
- *
- * @return false if parsing the hash fails, or if the height is a duplicate
- * AND the existing checkpoint hash does not match the new one,
- * otherwise returns true
- */
- bool add_checkpoint(uint64_t height, const std::string& hash_str);
-
- /**
- * @brief checks if there is a checkpoint in the future
- *
- * This function checks if the height passed is lower than the highest
- * checkpoint.
- *
- * @param height the height to check against
- *
- * @return false if no checkpoints, otherwise returns whether or not
- * the height passed is lower than the highest checkpoint.
- */
- bool is_in_checkpoint_zone(uint64_t height) const;
-
- /**
- * @brief checks if the given height and hash agree with the checkpoints
- *
- * This function checks if the given height and hash exist in the
- * checkpoints container. If so, it returns whether or not the passed
- * parameters match the stored values.
- *
- * @param height the height to be checked
- * @param h the hash to be checked
- * @param is_a_checkpoint return-by-reference if there is a checkpoint at the given height
- *
- * @return true if there is no checkpoint at the given height,
- * true if the passed parameters match the stored checkpoint,
- * false otherwise
- */
- bool check_block(uint64_t height, const crypto::hash& h, bool& is_a_checkpoint) const;
-
- /**
- * @overload
- */
- bool check_block(uint64_t height, const crypto::hash& h) const;
-
- /**
- * @brief checks if alternate chain blocks should be kept for a given height
- *
- * this basically says if the blockchain is smaller than the first
- * checkpoint then alternate blocks are allowed. Alternatively, if the
- * last checkpoint *before* the end of the current chain is also before
- * the block to be added, then this is fine.
- *
- * @param blockchain_height the current blockchain height
- * @param block_height the height of the block to be added as alternate
- *
- * @return true if alternate blocks are allowed given the parameters,
- * otherwise false
- */
- bool is_alternative_block_allowed(uint64_t blockchain_height, uint64_t block_height) const;
-
- /**
- * @brief gets the highest checkpoint height
- *
- * @return the height of the highest checkpoint
- */
- uint64_t get_max_height() const;
-
- /**
- * @brief gets the checkpoints container
- *
- * @return a const reference to the checkpoints container
- */
- const std::map<uint64_t, crypto::hash>& get_points() const;
-
- /**
- * @brief checks if our checkpoints container conflicts with another
- *
- * A conflict refers to a case where both checkpoint sets have a checkpoint
- * for a specific height but their hashes for that height do not match.
- *
- * @param other the other checkpoints instance to check against
- *
- * @return false if any conflict is found, otherwise true
- */
- bool check_for_conflicts(const checkpoints& other) const;
-
- /**
- * @brief loads the default main chain checkpoints
- *
- * @return true unless adding a checkpoint fails
- */
- bool init_default_checkpoints();
-
- /**
- * @brief load new checkpoints
- *
- * Loads new checkpoints from the specified json file, as well as
- * (optionally) from DNS.
- *
- * @param json_hashfile_fullpath path to the json checkpoints file
- * @param testnet whether to load testnet checkpoints or mainnet
- * @param dns whether or not to load DNS checkpoints
- *
- * @return true if loading successful and no conflicts
- */
- bool load_new_checkpoints(const std::string json_hashfile_fullpath, bool testnet=false, bool dns=true);
-
- /**
- * @brief load new checkpoints from json
- *
- * @param json_hashfile_fullpath path to the json checkpoints file
- *
- * @return true if loading successful and no conflicts
- */
- bool load_checkpoints_from_json(const std::string json_hashfile_fullpath);
-
- /**
- * @brief load new checkpoints from DNS
- *
- * @param testnet whether to load testnet checkpoints or mainnet
- *
- * @return true if loading successful and no conflicts
- */
- bool load_checkpoints_from_dns(bool testnet = false);
-
- private:
-
-
- /**
- * @brief struct for loading a checkpoint from json
- */
- struct t_hashline
- {
- uint64_t height; //!< the height of the checkpoint
- std::string hash; //!< the hash for the checkpoint
- BEGIN_KV_SERIALIZE_MAP()
- KV_SERIALIZE(height)
- KV_SERIALIZE(hash)
- END_KV_SERIALIZE_MAP()
- };
-
- /**
- * @brief struct for loading many checkpoints from json
- */
- struct t_hash_json {
- std::vector<t_hashline> hashlines; //!< the checkpoint lines from the file
- BEGIN_KV_SERIALIZE_MAP()
- KV_SERIALIZE(hashlines)
- END_KV_SERIALIZE_MAP()
- };
-
- std::map<uint64_t, crypto::hash> m_points; //!< the checkpoints container
-
- };
-}
diff --git a/src/cryptonote_core/connection_context.h b/src/cryptonote_core/connection_context.h
deleted file mode 100644
index 7e62e77b9..000000000
--- a/src/cryptonote_core/connection_context.h
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright (c) 2014-2016, 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
-
-#pragma once
-#include <unordered_set>
-#include <atomic>
-#include "net/net_utils_base.h"
-#include "copyable_atomic.h"
-
-namespace cryptonote
-{
-
- struct cryptonote_connection_context: public epee::net_utils::connection_context_base
- {
-
- enum state
- {
- state_befor_handshake = 0, //default state
- state_synchronizing,
- state_idle,
- state_normal
- };
-
- state m_state;
- std::list<crypto::hash> m_needed_objects;
- std::unordered_set<crypto::hash> m_requested_objects;
- uint64_t m_remote_blockchain_height;
- uint64_t m_last_response_height;
- epee::copyable_atomic m_callback_request_count; //in debug purpose: problem with double callback rise
- //size_t m_score; TODO: add score calculations
- };
-
- inline std::string get_protocol_state_string(cryptonote_connection_context::state s)
- {
- switch (s)
- {
- case cryptonote_connection_context::state_befor_handshake:
- return "state_befor_handshake";
- case cryptonote_connection_context::state_synchronizing:
- return "state_synchronizing";
- case cryptonote_connection_context::state_idle:
- return "state_idle";
- case cryptonote_connection_context::state_normal:
- return "state_normal";
- default:
- return "unknown";
- }
- }
-
-}
diff --git a/src/cryptonote_core/cryptonote_basic.h b/src/cryptonote_core/cryptonote_basic.h
deleted file mode 100644
index da069a21a..000000000
--- a/src/cryptonote_core/cryptonote_basic.h
+++ /dev/null
@@ -1,397 +0,0 @@
-// Copyright (c) 2014-2016, 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
-
-#pragma once
-
-#include <boost/variant.hpp>
-#include <boost/functional/hash/hash.hpp>
-#include <vector>
-#include <cstring> // memcmp
-#include <sstream>
-#include "serialization/serialization.h"
-#include "serialization/variant.h"
-#include "serialization/vector.h"
-#include "serialization/binary_archive.h"
-#include "serialization/json_archive.h"
-#include "serialization/debug_archive.h"
-#include "serialization/crypto.h"
-#include "serialization/keyvalue_serialization.h" // eepe named serialization
-#include "string_tools.h"
-#include "cryptonote_config.h"
-#include "crypto/crypto.h"
-#include "crypto/hash.h"
-#include "misc_language.h"
-#include "tx_extra.h"
-#include "ringct/rctTypes.h"
-
-namespace cryptonote
-{
-
- const static crypto::hash null_hash = AUTO_VAL_INIT(null_hash);
- const static crypto::hash8 null_hash8 = AUTO_VAL_INIT(null_hash8);
- const static crypto::public_key null_pkey = AUTO_VAL_INIT(null_pkey);
-
- typedef std::vector<crypto::signature> ring_signature;
-
-
- /* outputs */
-
- struct txout_to_script
- {
- std::vector<crypto::public_key> keys;
- std::vector<uint8_t> script;
-
- BEGIN_SERIALIZE_OBJECT()
- FIELD(keys)
- FIELD(script)
- END_SERIALIZE()
- };
-
- struct txout_to_scripthash
- {
- crypto::hash hash;
- };
-
- struct txout_to_key
- {
- txout_to_key() { }
- txout_to_key(const crypto::public_key &_key) : key(_key) { }
- crypto::public_key key;
- };
-
-
- /* inputs */
-
- struct txin_gen
- {
- size_t height;
-
- BEGIN_SERIALIZE_OBJECT()
- VARINT_FIELD(height)
- END_SERIALIZE()
- };
-
- struct txin_to_script
- {
- crypto::hash prev;
- size_t prevout;
- std::vector<uint8_t> sigset;
-
- BEGIN_SERIALIZE_OBJECT()
- FIELD(prev)
- VARINT_FIELD(prevout)
- FIELD(sigset)
- END_SERIALIZE()
- };
-
- struct txin_to_scripthash
- {
- crypto::hash prev;
- size_t prevout;
- txout_to_script script;
- std::vector<uint8_t> sigset;
-
- BEGIN_SERIALIZE_OBJECT()
- FIELD(prev)
- VARINT_FIELD(prevout)
- FIELD(script)
- FIELD(sigset)
- END_SERIALIZE()
- };
-
- struct txin_to_key
- {
- uint64_t amount;
- std::vector<uint64_t> key_offsets;
- crypto::key_image k_image; // double spending protection
-
- BEGIN_SERIALIZE_OBJECT()
- VARINT_FIELD(amount)
- FIELD(key_offsets)
- FIELD(k_image)
- END_SERIALIZE()
- };
-
-
- typedef boost::variant<txin_gen, txin_to_script, txin_to_scripthash, txin_to_key> txin_v;
-
- typedef boost::variant<txout_to_script, txout_to_scripthash, txout_to_key> txout_target_v;
-
- //typedef std::pair<uint64_t, txout> out_t;
- struct tx_out
- {
- uint64_t amount;
- txout_target_v target;
-
- BEGIN_SERIALIZE_OBJECT()
- VARINT_FIELD(amount)
- FIELD(target)
- END_SERIALIZE()
-
-
- };
-
- class transaction_prefix
- {
-
- public:
- // tx information
- size_t version;
- uint64_t unlock_time; //number of block (or time), used as a limitation like: spend this tx not early then block/time
-
- std::vector<txin_v> vin;
- std::vector<tx_out> vout;
- //extra
- std::vector<uint8_t> extra;
-
- BEGIN_SERIALIZE()
- VARINT_FIELD(version)
- if(version == 0 || CURRENT_TRANSACTION_VERSION < version) return false;
- VARINT_FIELD(unlock_time)
- FIELD(vin)
- FIELD(vout)
- FIELD(extra)
- END_SERIALIZE()
-
- public:
- transaction_prefix(){}
- };
-
- class transaction: public transaction_prefix
- {
- public:
- std::vector<std::vector<crypto::signature> > signatures; //count signatures always the same as inputs count
- rct::rctSig rct_signatures;
-
- transaction();
- virtual ~transaction();
- void set_null();
-
- BEGIN_SERIALIZE_OBJECT()
- FIELDS(*static_cast<transaction_prefix *>(this))
-
- if (version == 1)
- {
- ar.tag("signatures");
- ar.begin_array();
- PREPARE_CUSTOM_VECTOR_SERIALIZATION(vin.size(), signatures);
- bool signatures_not_expected = signatures.empty();
- if (!signatures_not_expected && vin.size() != signatures.size())
- return false;
-
- for (size_t i = 0; i < vin.size(); ++i)
- {
- size_t signature_size = get_signature_size(vin[i]);
- if (signatures_not_expected)
- {
- if (0 == signature_size)
- continue;
- else
- return false;
- }
-
- PREPARE_CUSTOM_VECTOR_SERIALIZATION(signature_size, signatures[i]);
- if (signature_size != signatures[i].size())
- return false;
-
- FIELDS(signatures[i]);
-
- if (vin.size() - i > 1)
- ar.delimit_array();
- }
- ar.end_array();
- }
- else
- {
- ar.tag("rct_signatures");
- if (!vin.empty())
- {
- ar.begin_object();
- bool r = rct_signatures.serialize_rctsig_base(ar, vin.size(), vout.size());
- if (!r || !ar.stream().good()) return false;
- ar.end_object();
- if (rct_signatures.type != rct::RCTTypeNull)
- {
- ar.tag("rctsig_prunable");
- ar.begin_object();
- r = rct_signatures.p.serialize_rctsig_prunable(ar, rct_signatures.type, vin.size(), vout.size(),
- vin[0].type() == typeid(txin_to_key) ? boost::get<txin_to_key>(vin[0]).key_offsets.size() - 1 : 0);
- if (!r || !ar.stream().good()) return false;
- ar.end_object();
- }
- }
- }
- END_SERIALIZE()
-
- private:
- static size_t get_signature_size(const txin_v& tx_in);
- };
-
-
- inline
- transaction::transaction()
- {
- set_null();
- }
-
- inline
- transaction::~transaction()
- {
- //set_null();
- }
-
- inline
- void transaction::set_null()
- {
- version = 1;
- unlock_time = 0;
- vin.clear();
- vout.clear();
- extra.clear();
- signatures.clear();
- rct_signatures.type = rct::RCTTypeNull;
- }
-
- inline
- size_t transaction::get_signature_size(const txin_v& tx_in)
- {
- struct txin_signature_size_visitor : public boost::static_visitor<size_t>
- {
- size_t operator()(const txin_gen& txin) const{return 0;}
- size_t operator()(const txin_to_script& txin) const{return 0;}
- size_t operator()(const txin_to_scripthash& txin) const{return 0;}
- size_t operator()(const txin_to_key& txin) const {return txin.key_offsets.size();}
- };
-
- return boost::apply_visitor(txin_signature_size_visitor(), tx_in);
- }
-
-
-
- /************************************************************************/
- /* */
- /************************************************************************/
- struct block_header
- {
- uint8_t major_version;
- uint8_t minor_version; // now used as a voting mechanism, rather than how this particular block is built
- uint64_t timestamp;
- crypto::hash prev_id;
- uint32_t nonce;
-
- BEGIN_SERIALIZE()
- VARINT_FIELD(major_version)
- VARINT_FIELD(minor_version)
- VARINT_FIELD(timestamp)
- FIELD(prev_id)
- FIELD(nonce)
- END_SERIALIZE()
- };
-
- struct block: public block_header
- {
- transaction miner_tx;
- std::vector<crypto::hash> tx_hashes;
-
- BEGIN_SERIALIZE_OBJECT()
- FIELDS(*static_cast<block_header *>(this))
- FIELD(miner_tx)
- FIELD(tx_hashes)
- END_SERIALIZE()
- };
-
-
- /************************************************************************/
- /* */
- /************************************************************************/
- struct account_public_address
- {
- crypto::public_key m_spend_public_key;
- crypto::public_key m_view_public_key;
-
- BEGIN_SERIALIZE_OBJECT()
- FIELD(m_spend_public_key)
- FIELD(m_view_public_key)
- END_SERIALIZE()
-
- BEGIN_KV_SERIALIZE_MAP()
- KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE(m_spend_public_key)
- KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE(m_view_public_key)
- END_KV_SERIALIZE_MAP()
- };
-
- struct keypair
- {
- crypto::public_key pub;
- crypto::secret_key sec;
-
- static inline keypair generate()
- {
- keypair k;
- generate_keys(k.pub, k.sec);
- return k;
- }
- };
- //---------------------------------------------------------------
-
-}
-
-BLOB_SERIALIZER(cryptonote::txout_to_key);
-BLOB_SERIALIZER(cryptonote::txout_to_scripthash);
-
-VARIANT_TAG(binary_archive, cryptonote::txin_gen, 0xff);
-VARIANT_TAG(binary_archive, cryptonote::txin_to_script, 0x0);
-VARIANT_TAG(binary_archive, cryptonote::txin_to_scripthash, 0x1);
-VARIANT_TAG(binary_archive, cryptonote::txin_to_key, 0x2);
-VARIANT_TAG(binary_archive, cryptonote::txout_to_script, 0x0);
-VARIANT_TAG(binary_archive, cryptonote::txout_to_scripthash, 0x1);
-VARIANT_TAG(binary_archive, cryptonote::txout_to_key, 0x2);
-VARIANT_TAG(binary_archive, cryptonote::transaction, 0xcc);
-VARIANT_TAG(binary_archive, cryptonote::block, 0xbb);
-
-VARIANT_TAG(json_archive, cryptonote::txin_gen, "gen");
-VARIANT_TAG(json_archive, cryptonote::txin_to_script, "script");
-VARIANT_TAG(json_archive, cryptonote::txin_to_scripthash, "scripthash");
-VARIANT_TAG(json_archive, cryptonote::txin_to_key, "key");
-VARIANT_TAG(json_archive, cryptonote::txout_to_script, "script");
-VARIANT_TAG(json_archive, cryptonote::txout_to_scripthash, "scripthash");
-VARIANT_TAG(json_archive, cryptonote::txout_to_key, "key");
-VARIANT_TAG(json_archive, cryptonote::transaction, "tx");
-VARIANT_TAG(json_archive, cryptonote::block, "block");
-
-VARIANT_TAG(debug_archive, cryptonote::txin_gen, "gen");
-VARIANT_TAG(debug_archive, cryptonote::txin_to_script, "script");
-VARIANT_TAG(debug_archive, cryptonote::txin_to_scripthash, "scripthash");
-VARIANT_TAG(debug_archive, cryptonote::txin_to_key, "key");
-VARIANT_TAG(debug_archive, cryptonote::txout_to_script, "script");
-VARIANT_TAG(debug_archive, cryptonote::txout_to_scripthash, "scripthash");
-VARIANT_TAG(debug_archive, cryptonote::txout_to_key, "key");
-VARIANT_TAG(debug_archive, cryptonote::transaction, "tx");
-VARIANT_TAG(debug_archive, cryptonote::block, "block");
diff --git a/src/cryptonote_core/cryptonote_basic_impl.cpp b/src/cryptonote_core/cryptonote_basic_impl.cpp
deleted file mode 100644
index 338210f01..000000000
--- a/src/cryptonote_core/cryptonote_basic_impl.cpp
+++ /dev/null
@@ -1,347 +0,0 @@
-// Copyright (c) 2014-2016, 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 "include_base_utils.h"
-using namespace epee;
-
-#include "cryptonote_basic_impl.h"
-#include "string_tools.h"
-#include "serialization/binary_utils.h"
-#include "serialization/vector.h"
-#include "cryptonote_format_utils.h"
-#include "cryptonote_config.h"
-#include "misc_language.h"
-#include "common/base58.h"
-#include "crypto/hash.h"
-#include "common/int-util.h"
-#include "common/dns_utils.h"
-
-#undef MONERO_DEFAULT_LOG_CATEGORY
-#define MONERO_DEFAULT_LOG_CATEGORY "cn"
-
-namespace cryptonote {
-
- struct integrated_address {
- account_public_address adr;
- crypto::hash8 payment_id;
-
- BEGIN_SERIALIZE_OBJECT()
- FIELD(adr)
- FIELD(payment_id)
- END_SERIALIZE()
-
- BEGIN_KV_SERIALIZE_MAP()
- KV_SERIALIZE(adr)
- KV_SERIALIZE(payment_id)
- END_KV_SERIALIZE_MAP()
- };
-
- /************************************************************************/
- /* Cryptonote helper functions */
- /************************************************************************/
- //-----------------------------------------------------------------------------------------------
- size_t get_max_block_size()
- {
- return CRYPTONOTE_MAX_BLOCK_SIZE;
- }
- //-----------------------------------------------------------------------------------------------
- size_t get_max_tx_size()
- {
- return CRYPTONOTE_MAX_TX_SIZE;
- }
- //-----------------------------------------------------------------------------------------------
- bool get_block_reward(size_t median_size, size_t current_block_size, uint64_t already_generated_coins, uint64_t &reward, uint8_t version) {
- static_assert(DIFFICULTY_TARGET_V2%60==0&&DIFFICULTY_TARGET_V1%60==0,"difficulty targets must be a multiple of 60");
- const int target = version < 2 ? DIFFICULTY_TARGET_V1 : DIFFICULTY_TARGET_V2;
- const int target_minutes = target / 60;
- const int emission_speed_factor = EMISSION_SPEED_FACTOR_PER_MINUTE - (target_minutes-1);
-
- uint64_t base_reward = (MONEY_SUPPLY - already_generated_coins) >> emission_speed_factor;
- if (base_reward < FINAL_SUBSIDY_PER_MINUTE*target_minutes)
- {
- base_reward = FINAL_SUBSIDY_PER_MINUTE*target_minutes;
- }
-
- uint64_t full_reward_zone = version < 2 ? CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V1 : CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2;
-
- //make it soft
- if (median_size < full_reward_zone) {
- median_size = full_reward_zone;
- }
-
- if (current_block_size <= median_size) {
- reward = base_reward;
- return true;
- }
-
- if(current_block_size > 2 * median_size) {
- MERROR("Block cumulative size is too big: " << current_block_size << ", expected less than " << 2 * median_size);
- return false;
- }
-
- assert(median_size < std::numeric_limits<uint32_t>::max());
- assert(current_block_size < std::numeric_limits<uint32_t>::max());
-
- uint64_t product_hi;
- // BUGFIX: 32-bit saturation bug (e.g. ARM7), the result was being
- // treated as 32-bit by default.
- uint64_t multiplicand = 2 * median_size - current_block_size;
- multiplicand *= current_block_size;
- uint64_t product_lo = mul128(base_reward, multiplicand, &product_hi);
-
- uint64_t reward_hi;
- uint64_t reward_lo;
- div128_32(product_hi, product_lo, static_cast<uint32_t>(median_size), &reward_hi, &reward_lo);
- div128_32(reward_hi, reward_lo, static_cast<uint32_t>(median_size), &reward_hi, &reward_lo);
- assert(0 == reward_hi);
- assert(reward_lo < base_reward);
-
- reward = reward_lo;
- return true;
- }
- //------------------------------------------------------------------------------------
- uint8_t get_account_address_checksum(const public_address_outer_blob& bl)
- {
- const unsigned char* pbuf = reinterpret_cast<const unsigned char*>(&bl);
- uint8_t summ = 0;
- for(size_t i = 0; i!= sizeof(public_address_outer_blob)-1; i++)
- summ += pbuf[i];
-
- return summ;
- }
- //------------------------------------------------------------------------------------
- uint8_t get_account_integrated_address_checksum(const public_integrated_address_outer_blob& bl)
- {
- const unsigned char* pbuf = reinterpret_cast<const unsigned char*>(&bl);
- uint8_t summ = 0;
- for(size_t i = 0; i!= sizeof(public_integrated_address_outer_blob)-1; i++)
- summ += pbuf[i];
-
- return summ;
- }
- //-----------------------------------------------------------------------
- std::string get_account_address_as_str(
- bool testnet
- , account_public_address const & adr
- )
- {
- uint64_t address_prefix = testnet ?
- config::testnet::CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX : config::CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX;
-
- return tools::base58::encode_addr(address_prefix, t_serializable_object_to_blob(adr));
- }
- //-----------------------------------------------------------------------
- std::string get_account_integrated_address_as_str(
- bool testnet
- , account_public_address const & adr
- , crypto::hash8 const & payment_id
- )
- {
- uint64_t integrated_address_prefix = testnet ?
- config::testnet::CRYPTONOTE_PUBLIC_INTEGRATED_ADDRESS_BASE58_PREFIX : config::CRYPTONOTE_PUBLIC_INTEGRATED_ADDRESS_BASE58_PREFIX;
-
- integrated_address iadr = {
- adr, payment_id
- };
- return tools::base58::encode_addr(integrated_address_prefix, t_serializable_object_to_blob(iadr));
- }
- //-----------------------------------------------------------------------
- bool is_coinbase(const transaction& tx)
- {
- if(tx.vin.size() != 1)
- return false;
-
- if(tx.vin[0].type() != typeid(txin_gen))
- return false;
-
- return true;
- }
- //-----------------------------------------------------------------------
- bool get_account_integrated_address_from_str(
- account_public_address& adr
- , bool& has_payment_id
- , crypto::hash8& payment_id
- , bool testnet
- , std::string const & str
- )
- {
- uint64_t address_prefix = testnet ?
- config::testnet::CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX : config::CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX;
- uint64_t integrated_address_prefix = testnet ?
- config::testnet::CRYPTONOTE_PUBLIC_INTEGRATED_ADDRESS_BASE58_PREFIX : config::CRYPTONOTE_PUBLIC_INTEGRATED_ADDRESS_BASE58_PREFIX;
-
- if (2 * sizeof(public_address_outer_blob) != str.size())
- {
- blobdata data;
- uint64_t prefix;
- if (!tools::base58::decode_addr(str, prefix, data))
- {
- LOG_PRINT_L2("Invalid address format");
- return false;
- }
-
- if (integrated_address_prefix == prefix)
- {
- has_payment_id = true;
- }
- else if (address_prefix == prefix)
- {
- has_payment_id = false;
- }
- else {
- LOG_PRINT_L1("Wrong address prefix: " << prefix << ", expected " << address_prefix << " or " << integrated_address_prefix);
- return false;
- }
-
- if (has_payment_id)
- {
- integrated_address iadr;
- if (!::serialization::parse_binary(data, iadr))
- {
- LOG_PRINT_L1("Account public address keys can't be parsed");
- return false;
- }
- adr = iadr.adr;
- payment_id = iadr.payment_id;
- }
- else
- {
- if (!::serialization::parse_binary(data, adr))
- {
- LOG_PRINT_L1("Account public address keys can't be parsed");
- return false;
- }
- }
-
- if (!crypto::check_key(adr.m_spend_public_key) || !crypto::check_key(adr.m_view_public_key))
- {
- LOG_PRINT_L1("Failed to validate address keys");
- return false;
- }
- }
- else
- {
- // Old address format
- std::string buff;
- if(!string_tools::parse_hexstr_to_binbuff(str, buff))
- return false;
-
- if(buff.size()!=sizeof(public_address_outer_blob))
- {
- LOG_PRINT_L1("Wrong public address size: " << buff.size() << ", expected size: " << sizeof(public_address_outer_blob));
- return false;
- }
-
- public_address_outer_blob blob = *reinterpret_cast<const public_address_outer_blob*>(buff.data());
-
-
- if(blob.m_ver > CRYPTONOTE_PUBLIC_ADDRESS_TEXTBLOB_VER)
- {
- LOG_PRINT_L1("Unknown version of public address: " << blob.m_ver << ", expected " << CRYPTONOTE_PUBLIC_ADDRESS_TEXTBLOB_VER);
- return false;
- }
-
- if(blob.check_sum != get_account_address_checksum(blob))
- {
- LOG_PRINT_L1("Wrong public address checksum");
- return false;
- }
-
- //we success
- adr = blob.m_address;
- has_payment_id = false;
- }
-
- return true;
- }
- //-----------------------------------------------------------------------
- bool get_account_address_from_str(
- account_public_address& adr
- , bool testnet
- , std::string const & str
- )
- {
- bool has_payment_id;
- crypto::hash8 payment_id;
- return get_account_integrated_address_from_str(adr, has_payment_id, payment_id, testnet, str);
- }
- //--------------------------------------------------------------------------------
- bool get_account_address_from_str_or_url(
- cryptonote::account_public_address& address
- , bool& has_payment_id
- , crypto::hash8& payment_id
- , bool testnet
- , const std::string& str_or_url
- )
- {
- if (get_account_integrated_address_from_str(address, has_payment_id, payment_id, testnet, str_or_url))
- return true;
- bool dnssec_valid;
- std::string address_str = tools::dns_utils::get_account_address_as_str_from_url(str_or_url, dnssec_valid);
- return !address_str.empty() &&
- get_account_integrated_address_from_str(address, has_payment_id, payment_id, testnet, address_str);
- }
- //--------------------------------------------------------------------------------
- bool get_account_address_from_str_or_url(
- cryptonote::account_public_address& address
- , bool testnet
- , const std::string& str_or_url
- )
- {
- bool has_payment_id;
- crypto::hash8 payment_id;
- return get_account_address_from_str_or_url(address, has_payment_id, payment_id, testnet, str_or_url);
- }
- //--------------------------------------------------------------------------------
- bool operator ==(const cryptonote::transaction& a, const cryptonote::transaction& b) {
- return cryptonote::get_transaction_hash(a) == cryptonote::get_transaction_hash(b);
- }
-
- bool operator ==(const cryptonote::block& a, const cryptonote::block& b) {
- return cryptonote::get_block_hash(a) == cryptonote::get_block_hash(b);
- }
-}
-
-//--------------------------------------------------------------------------------
-bool parse_hash256(const std::string str_hash, crypto::hash& hash)
-{
- std::string buf;
- bool res = epee::string_tools::parse_hexstr_to_binbuff(str_hash, buf);
- if (!res || buf.size() != sizeof(crypto::hash))
- {
- std::cout << "invalid hash format: <" << str_hash << '>' << std::endl;
- return false;
- }
- else
- {
- buf.copy(reinterpret_cast<char *>(&hash), sizeof(crypto::hash));
- return true;
- }
-}
diff --git a/src/cryptonote_core/cryptonote_basic_impl.h b/src/cryptonote_core/cryptonote_basic_impl.h
deleted file mode 100644
index 5703a7d75..000000000
--- a/src/cryptonote_core/cryptonote_basic_impl.h
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright (c) 2014-2016, 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
-
-#pragma once
-
-#include "cryptonote_basic.h"
-#include "crypto/crypto.h"
-#include "crypto/hash.h"
-
-
-namespace cryptonote {
- /************************************************************************/
- /* */
- /************************************************************************/
- template<class t_array>
- struct array_hasher: std::unary_function<t_array&, std::size_t>
- {
- std::size_t operator()(const t_array& val) const
- {
- return boost::hash_range(&val.data[0], &val.data[sizeof(val.data)]);
- }
- };
-
-
-#pragma pack(push, 1)
- struct public_address_outer_blob
- {
- uint8_t m_ver;
- account_public_address m_address;
- uint8_t check_sum;
- };
- struct public_integrated_address_outer_blob
- {
- uint8_t m_ver;
- account_public_address m_address;
- crypto::hash8 payment_id;
- uint8_t check_sum;
- };
-#pragma pack (pop)
-
-
- /************************************************************************/
- /* Cryptonote helper functions */
- /************************************************************************/
- size_t get_max_block_size();
- size_t get_max_tx_size();
- bool get_block_reward(size_t median_size, size_t current_block_size, uint64_t already_generated_coins, uint64_t &reward, uint8_t version);
- uint8_t get_account_address_checksum(const public_address_outer_blob& bl);
- uint8_t get_account_integrated_address_checksum(const public_integrated_address_outer_blob& bl);
-
- std::string get_account_address_as_str(
- bool testnet
- , const account_public_address& adr
- );
-
- std::string get_account_integrated_address_as_str(
- bool testnet
- , const account_public_address& adr
- , const crypto::hash8& payment_id
- );
-
- bool get_account_integrated_address_from_str(
- account_public_address& adr
- , bool& has_payment_id
- , crypto::hash8& payment_id
- , bool testnet
- , const std::string& str
- );
-
- bool get_account_address_from_str(
- account_public_address& adr
- , bool testnet
- , const std::string& str
- );
-
- bool get_account_address_from_str_or_url(
- cryptonote::account_public_address& address
- , bool& has_payment_id
- , crypto::hash8& payment_id
- , bool testnet
- , const std::string& str_or_url
- );
-
- bool get_account_address_from_str_or_url(
- cryptonote::account_public_address& address
- , bool testnet
- , const std::string& str_or_url
- );
-
- bool is_coinbase(const transaction& tx);
-
- bool operator ==(const cryptonote::transaction& a, const cryptonote::transaction& b);
- bool operator ==(const cryptonote::block& a, const cryptonote::block& b);
-}
-
-template <class T>
-std::ostream &print256(std::ostream &o, const T &v) {
- return o << "<" << epee::string_tools::pod_to_hex(v) << ">";
-}
-template <class T>
-std::ostream &print64(std::ostream &o, const T &v) {
- return o << "<" << epee::string_tools::pod_to_hex(v) << ">";
-}
-
-bool parse_hash256(const std::string str_hash, crypto::hash& hash);
-
-namespace crypto {
- inline std::ostream &operator <<(std::ostream &o, const crypto::public_key &v) { return print256(o, v); }
- inline std::ostream &operator <<(std::ostream &o, const crypto::secret_key &v) { return print256(o, v); }
- inline std::ostream &operator <<(std::ostream &o, const crypto::key_derivation &v) { return print256(o, v); }
- inline std::ostream &operator <<(std::ostream &o, const crypto::key_image &v) { return print256(o, v); }
- inline std::ostream &operator <<(std::ostream &o, const crypto::signature &v) { return print256(o, v); }
- inline std::ostream &operator <<(std::ostream &o, const crypto::hash &v) { return print256(o, v); }
- inline std::ostream &operator <<(std::ostream &o, const crypto::hash8 &v) { return print64(o, v); }
-}
diff --git a/src/cryptonote_core/cryptonote_boost_serialization.h b/src/cryptonote_core/cryptonote_boost_serialization.h
deleted file mode 100644
index 409b9798c..000000000
--- a/src/cryptonote_core/cryptonote_boost_serialization.h
+++ /dev/null
@@ -1,301 +0,0 @@
-// Copyright (c) 2014-2016, 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
-
-#pragma once
-
-#include <boost/serialization/vector.hpp>
-#include <boost/serialization/utility.hpp>
-#include <boost/serialization/variant.hpp>
-#include <boost/serialization/set.hpp>
-#include <boost/serialization/map.hpp>
-#include <boost/serialization/is_bitwise_serializable.hpp>
-#include <boost/archive/binary_iarchive.hpp>
-#include <boost/archive/portable_binary_iarchive.hpp>
-#include <boost/archive/portable_binary_oarchive.hpp>
-#include "cryptonote_basic.h"
-#include "common/unordered_containers_boost_serialization.h"
-#include "crypto/crypto.h"
-#include "ringct/rctTypes.h"
-#include "ringct/rctOps.h"
-
-//namespace cryptonote {
-namespace boost
-{
- namespace serialization
- {
-
- //---------------------------------------------------
- template <class Archive>
- inline void serialize(Archive &a, crypto::public_key &x, const boost::serialization::version_type ver)
- {
- a & reinterpret_cast<char (&)[sizeof(crypto::public_key)]>(x);
- }
- template <class Archive>
- inline void serialize(Archive &a, crypto::secret_key &x, const boost::serialization::version_type ver)
- {
- a & reinterpret_cast<char (&)[sizeof(crypto::secret_key)]>(x);
- }
- template <class Archive>
- inline void serialize(Archive &a, crypto::key_derivation &x, const boost::serialization::version_type ver)
- {
- a & reinterpret_cast<char (&)[sizeof(crypto::key_derivation)]>(x);
- }
- template <class Archive>
- inline void serialize(Archive &a, crypto::key_image &x, const boost::serialization::version_type ver)
- {
- a & reinterpret_cast<char (&)[sizeof(crypto::key_image)]>(x);
- }
-
- template <class Archive>
- inline void serialize(Archive &a, crypto::signature &x, const boost::serialization::version_type ver)
- {
- a & reinterpret_cast<char (&)[sizeof(crypto::signature)]>(x);
- }
- template <class Archive>
- inline void serialize(Archive &a, crypto::hash &x, const boost::serialization::version_type ver)
- {
- a & reinterpret_cast<char (&)[sizeof(crypto::hash)]>(x);
- }
-
- template <class Archive>
- inline void serialize(Archive &a, cryptonote::txout_to_script &x, const boost::serialization::version_type ver)
- {
- a & x.keys;
- a & x.script;
- }
-
-
- template <class Archive>
- inline void serialize(Archive &a, cryptonote::txout_to_key &x, const boost::serialization::version_type ver)
- {
- a & x.key;
- }
-
- template <class Archive>
- inline void serialize(Archive &a, cryptonote::txout_to_scripthash &x, const boost::serialization::version_type ver)
- {
- a & x.hash;
- }
-
- template <class Archive>
- inline void serialize(Archive &a, cryptonote::txin_gen &x, const boost::serialization::version_type ver)
- {
- a & x.height;
- }
-
- template <class Archive>
- inline void serialize(Archive &a, cryptonote::txin_to_script &x, const boost::serialization::version_type ver)
- {
- a & x.prev;
- a & x.prevout;
- a & x.sigset;
- }
-
- template <class Archive>
- inline void serialize(Archive &a, cryptonote::txin_to_scripthash &x, const boost::serialization::version_type ver)
- {
- a & x.prev;
- a & x.prevout;
- a & x.script;
- a & x.sigset;
- }
-
- template <class Archive>
- inline void serialize(Archive &a, cryptonote::txin_to_key &x, const boost::serialization::version_type ver)
- {
- a & x.amount;
- a & x.key_offsets;
- a & x.k_image;
- }
-
- template <class Archive>
- inline void serialize(Archive &a, cryptonote::tx_out &x, const boost::serialization::version_type ver)
- {
- a & x.amount;
- a & x.target;
- }
-
-
- template <class Archive>
- inline void serialize(Archive &a, cryptonote::transaction_prefix &x, const boost::serialization::version_type ver)
- {
- a & x.version;
- a & x.unlock_time;
- a & x.vin;
- a & x.vout;
- a & x.extra;
- }
-
- template <class Archive>
- inline void serialize(Archive &a, cryptonote::transaction &x, const boost::serialization::version_type ver)
- {
- a & x.version;
- a & x.unlock_time;
- a & x.vin;
- a & x.vout;
- a & x.extra;
- if (x.version == 1)
- {
- a & x.signatures;
- }
- else
- {
- a & (rct::rctSigBase&)x.rct_signatures;
- if (x.rct_signatures.type != rct::RCTTypeNull)
- a & x.rct_signatures.p;
- }
- }
-
- template <class Archive>
- inline void serialize(Archive &a, cryptonote::block &b, const boost::serialization::version_type ver)
- {
- a & b.major_version;
- a & b.minor_version;
- a & b.timestamp;
- a & b.prev_id;
- a & b.nonce;
- //------------------
- a & b.miner_tx;
- a & b.tx_hashes;
- }
-
- template <class Archive>
- inline void serialize(Archive &a, rct::key &x, const boost::serialization::version_type ver)
- {
- a & reinterpret_cast<char (&)[sizeof(rct::key)]>(x);
- }
-
- template <class Archive>
- inline void serialize(Archive &a, rct::ctkey &x, const boost::serialization::version_type ver)
- {
- a & x.dest;
- a & x.mask;
- }
-
- template <class Archive>
- inline void serialize(Archive &a, rct::rangeSig &x, const boost::serialization::version_type ver)
- {
- a & x.asig;
- a & x.Ci;
- }
-
- template <class Archive>
- inline void serialize(Archive &a, rct::boroSig &x, const boost::serialization::version_type ver)
- {
- a & x.s0;
- a & x.s1;
- a & x.ee;
- }
-
- template <class Archive>
- inline void serialize(Archive &a, rct::mgSig &x, const boost::serialization::version_type ver)
- {
- a & x.ss;
- a & x.cc;
- // a & x.II; // not serialized, we can recover it from the tx vin
- }
-
- template <class Archive>
- inline void serialize(Archive &a, rct::ecdhTuple &x, const boost::serialization::version_type ver)
- {
- a & x.mask;
- a & x.amount;
- // a & x.senderPk; // not serialized, as we do not use it in monero currently
- }
-
- template <class Archive>
- inline typename std::enable_if<Archive::is_loading::value, void>::type serializeOutPk(Archive &a, rct::ctkeyV &outPk_, const boost::serialization::version_type ver)
- {
- rct::keyV outPk;
- a & outPk;
- outPk_.resize(outPk.size());
- for (size_t n = 0; n < outPk_.size(); ++n)
- {
- outPk_[n].dest = rct::identity();
- outPk_[n].mask = outPk[n];
- }
- }
-
- template <class Archive>
- inline typename std::enable_if<Archive::is_saving::value, void>::type serializeOutPk(Archive &a, rct::ctkeyV &outPk_, const boost::serialization::version_type ver)
- {
- rct::keyV outPk(outPk_.size());
- for (size_t n = 0; n < outPk_.size(); ++n)
- outPk[n] = outPk_[n].mask;
- a & outPk;
- }
-
- template <class Archive>
- inline void serialize(Archive &a, rct::rctSigBase &x, const boost::serialization::version_type ver)
- {
- a & x.type;
- if (x.type == rct::RCTTypeNull)
- return;
- if (x.type != rct::RCTTypeFull && x.type != rct::RCTTypeSimple)
- throw boost::archive::archive_exception(boost::archive::archive_exception::other_exception, "Unsupported rct type");
- // a & x.message; message is not serialized, as it can be reconstructed from the tx data
- // a & x.mixRing; mixRing is not serialized, as it can be reconstructed from the offsets
- if (x.type == rct::RCTTypeSimple)
- a & x.pseudoOuts;
- a & x.ecdhInfo;
- serializeOutPk(a, x.outPk, ver);
- a & x.txnFee;
- }
-
- template <class Archive>
- inline void serialize(Archive &a, rct::rctSigPrunable &x, const boost::serialization::version_type ver)
- {
- a & x.rangeSigs;
- a & x.MGs;
- }
-
- template <class Archive>
- inline void serialize(Archive &a, rct::rctSig &x, const boost::serialization::version_type ver)
- {
- a & x.type;
- if (x.type == rct::RCTTypeNull)
- return;
- if (x.type != rct::RCTTypeFull && x.type != rct::RCTTypeSimple)
- throw boost::archive::archive_exception(boost::archive::archive_exception::other_exception, "Unsupported rct type");
- // a & x.message; message is not serialized, as it can be reconstructed from the tx data
- // a & x.mixRing; mixRing is not serialized, as it can be reconstructed from the offsets
- if (x.type == rct::RCTTypeSimple)
- a & x.pseudoOuts;
- a & x.ecdhInfo;
- serializeOutPk(a, x.outPk, ver);
- a & x.txnFee;
- //--------------
- a & x.p.rangeSigs;
- a & x.p.MGs;
- }
-}
-}
-
-//}
diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp
index 900dc58ba..b940dba3c 100644
--- a/src/cryptonote_core/cryptonote_core.cpp
+++ b/src/cryptonote_core/cryptonote_core.cpp
@@ -38,11 +38,11 @@ using namespace epee;
#include "warnings.h"
#include "crypto/crypto.h"
#include "cryptonote_config.h"
-#include "cryptonote_format_utils.h"
+#include "cryptonote_tx_utils.h"
#include "misc_language.h"
#include <csignal>
#include <p2p/net_node.h>
-#include "cryptonote_core/checkpoints.h"
+#include "cryptonote_basic/checkpoints.h"
#include "ringct/rctTypes.h"
#include "blockchain_db/blockchain_db.h"
#include "blockchain_db/lmdb/db_lmdb.h"
diff --git a/src/cryptonote_core/cryptonote_core.h b/src/cryptonote_core/cryptonote_core.h
index 1b9518c96..fe1d11916 100644
--- a/src/cryptonote_core/cryptonote_core.h
+++ b/src/cryptonote_core/cryptonote_core.h
@@ -41,9 +41,9 @@
#include "storages/portable_storage_template_helper.h"
#include "tx_pool.h"
#include "blockchain.h"
-#include "miner.h"
-#include "connection_context.h"
-#include "cryptonote_core/cryptonote_stat_info.h"
+#include "cryptonote_basic/miner.h"
+#include "cryptonote_basic/connection_context.h"
+#include "cryptonote_basic/cryptonote_stat_info.h"
#include "warnings.h"
#include "crypto/hash.h"
diff --git a/src/cryptonote_core/cryptonote_format_utils.cpp b/src/cryptonote_core/cryptonote_format_utils.cpp
deleted file mode 100644
index 2e6917878..000000000
--- a/src/cryptonote_core/cryptonote_format_utils.cpp
+++ /dev/null
@@ -1,1193 +0,0 @@
-// Copyright (c) 2014-2016, 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 "include_base_utils.h"
-using namespace epee;
-
-#include "cryptonote_format_utils.h"
-#include "cryptonote_config.h"
-#include "miner.h"
-#include "crypto/crypto.h"
-#include "crypto/hash.h"
-#include "ringct/rctSigs.h"
-
-#undef MONERO_DEFAULT_LOG_CATEGORY
-#define MONERO_DEFAULT_LOG_CATEGORY "cn"
-
-#define ENCRYPTED_PAYMENT_ID_TAIL 0x8d
-
-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
-};
-
-namespace cryptonote
-{
- //---------------------------------------------------------------
- void get_transaction_prefix_hash(const transaction_prefix& tx, crypto::hash& h)
- {
- std::ostringstream s;
- binary_archive<true> a(s);
- ::serialization::serialize(a, const_cast<transaction_prefix&>(tx));
- crypto::cn_fast_hash(s.str().data(), s.str().size(), h);
- }
- //---------------------------------------------------------------
- crypto::hash get_transaction_prefix_hash(const transaction_prefix& tx)
- {
- crypto::hash h = null_hash;
- get_transaction_prefix_hash(tx, h);
- return h;
- }
- //---------------------------------------------------------------
- bool parse_and_validate_tx_from_blob(const blobdata& tx_blob, transaction& tx)
- {
- std::stringstream ss;
- ss << tx_blob;
- binary_archive<false> ba(ss);
- bool r = ::serialization::serialize(ba, tx);
- CHECK_AND_ASSERT_MES(r, false, "Failed to parse transaction from blob");
- return true;
- }
- //---------------------------------------------------------------
- bool parse_and_validate_tx_from_blob(const blobdata& tx_blob, transaction& tx, crypto::hash& tx_hash, crypto::hash& tx_prefix_hash)
- {
- std::stringstream ss;
- ss << tx_blob;
- binary_archive<false> ba(ss);
- bool r = ::serialization::serialize(ba, tx);
- CHECK_AND_ASSERT_MES(r, false, "Failed to parse transaction from blob");
- //TODO: validate tx
-
- get_transaction_hash(tx, tx_hash);
- get_transaction_prefix_hash(tx, tx_prefix_hash);
- return true;
- }
- //---------------------------------------------------------------
- bool construct_miner_tx(size_t height, size_t median_size, uint64_t already_generated_coins, size_t current_block_size, uint64_t fee, const account_public_address &miner_address, transaction& tx, const blobdata& extra_nonce, size_t max_outs, uint8_t hard_fork_version) {
- tx.vin.clear();
- tx.vout.clear();
- tx.extra.clear();
-
- keypair txkey = keypair::generate();
- add_tx_pub_key_to_extra(tx, txkey.pub);
- if(!extra_nonce.empty())
- if(!add_extra_nonce_to_tx_extra(tx.extra, extra_nonce))
- return false;
-
- txin_gen in;
- in.height = height;
-
- uint64_t block_reward;
- if(!get_block_reward(median_size, current_block_size, already_generated_coins, block_reward, hard_fork_version))
- {
- LOG_PRINT_L0("Block is too big");
- return false;
- }
-
-#if defined(DEBUG_CREATE_BLOCK_TEMPLATE)
- LOG_PRINT_L1("Creating block template: reward " << block_reward <<
- ", fee " << fee);
-#endif
- block_reward += fee;
-
- // from hard fork 2, we cut out the low significant digits. This makes the tx smaller, and
- // keeps the paid amount almost the same. The unpaid remainder gets pushed back to the
- // emission schedule
- // from hard fork 4, we use a single "dusty" output. This makes the tx even smaller,
- // and avoids the quantization. These outputs will be added as rct outputs with identity
- // masks, to they can be used as rct inputs.
- if (hard_fork_version >= 2 && hard_fork_version < 4) {
- block_reward = block_reward - block_reward % ::config::BASE_REWARD_CLAMP_THRESHOLD;
- }
-
- std::vector<uint64_t> out_amounts;
- decompose_amount_into_digits(block_reward, hard_fork_version >= 2 ? 0 : ::config::DEFAULT_DUST_THRESHOLD,
- [&out_amounts](uint64_t a_chunk) { out_amounts.push_back(a_chunk); },
- [&out_amounts](uint64_t a_dust) { out_amounts.push_back(a_dust); });
-
- CHECK_AND_ASSERT_MES(1 <= max_outs, false, "max_out must be non-zero");
- if (height == 0 || hard_fork_version >= 4)
- {
- // the genesis block was not decomposed, for unknown reasons
- while (max_outs < out_amounts.size())
- {
- //out_amounts[out_amounts.size() - 2] += out_amounts.back();
- //out_amounts.resize(out_amounts.size() - 1);
- out_amounts[1] += out_amounts[0];
- for (size_t n = 1; n < out_amounts.size(); ++n)
- out_amounts[n - 1] = out_amounts[n];
- out_amounts.resize(out_amounts.size() - 1);
- }
- }
- else
- {
- CHECK_AND_ASSERT_MES(max_outs >= out_amounts.size(), false, "max_out exceeded");
- }
-
- uint64_t summary_amounts = 0;
- for (size_t no = 0; no < out_amounts.size(); no++)
- {
- crypto::key_derivation derivation = AUTO_VAL_INIT(derivation);;
- crypto::public_key out_eph_public_key = AUTO_VAL_INIT(out_eph_public_key);
- bool r = crypto::generate_key_derivation(miner_address.m_view_public_key, txkey.sec, derivation);
- CHECK_AND_ASSERT_MES(r, false, "while creating outs: failed to generate_key_derivation(" << miner_address.m_view_public_key << ", " << txkey.sec << ")");
-
- r = crypto::derive_public_key(derivation, no, miner_address.m_spend_public_key, out_eph_public_key);
- CHECK_AND_ASSERT_MES(r, false, "while creating outs: failed to derive_public_key(" << derivation << ", " << no << ", "<< miner_address.m_spend_public_key << ")");
-
- txout_to_key tk;
- tk.key = out_eph_public_key;
-
- tx_out out;
- summary_amounts += out.amount = out_amounts[no];
- out.target = tk;
- tx.vout.push_back(out);
- }
-
- CHECK_AND_ASSERT_MES(summary_amounts == block_reward, false, "Failed to construct miner tx, summary_amounts = " << summary_amounts << " not equal block_reward = " << block_reward);
-
- if (hard_fork_version >= 4)
- tx.version = 2;
- else
- tx.version = 1;
-
- //lock
- tx.unlock_time = height + CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW;
- tx.vin.push_back(in);
- //LOG_PRINT("MINER_TX generated ok, block_reward=" << print_money(block_reward) << "(" << print_money(block_reward - fee) << "+" << print_money(fee)
- // << "), current_block_size=" << current_block_size << ", already_generated_coins=" << already_generated_coins << ", tx_id=" << get_transaction_hash(tx), LOG_LEVEL_2);
- return true;
- }
- //---------------------------------------------------------------
- bool generate_key_image_helper(const account_keys& ack, const crypto::public_key& tx_public_key, size_t real_output_index, keypair& in_ephemeral, crypto::key_image& ki)
- {
- crypto::key_derivation recv_derivation = AUTO_VAL_INIT(recv_derivation);
- bool r = crypto::generate_key_derivation(tx_public_key, ack.m_view_secret_key, recv_derivation);
- CHECK_AND_ASSERT_MES(r, false, "key image helper: failed to generate_key_derivation(" << tx_public_key << ", " << ack.m_view_secret_key << ")");
-
- r = crypto::derive_public_key(recv_derivation, real_output_index, ack.m_account_address.m_spend_public_key, in_ephemeral.pub);
- CHECK_AND_ASSERT_MES(r, false, "key image helper: failed to derive_public_key(" << recv_derivation << ", " << real_output_index << ", " << ack.m_account_address.m_spend_public_key << ")");
-
- crypto::derive_secret_key(recv_derivation, real_output_index, ack.m_spend_secret_key, in_ephemeral.sec);
-
- crypto::generate_key_image(in_ephemeral.pub, in_ephemeral.sec, ki);
- return true;
- }
- //---------------------------------------------------------------
- uint64_t power_integral(uint64_t a, uint64_t b)
- {
- if(b == 0)
- return 1;
- uint64_t total = a;
- for(uint64_t i = 1; i != b; i++)
- total *= a;
- return total;
- }
- //---------------------------------------------------------------
- bool parse_amount(uint64_t& amount, const std::string& str_amount_)
- {
- std::string str_amount = str_amount_;
- boost::algorithm::trim(str_amount);
-
- size_t point_index = str_amount.find_first_of('.');
- size_t fraction_size;
- if (std::string::npos != point_index)
- {
- fraction_size = str_amount.size() - point_index - 1;
- while (CRYPTONOTE_DISPLAY_DECIMAL_POINT < fraction_size && '0' == str_amount.back())
- {
- str_amount.erase(str_amount.size() - 1, 1);
- --fraction_size;
- }
- if (CRYPTONOTE_DISPLAY_DECIMAL_POINT < fraction_size)
- return false;
- str_amount.erase(point_index, 1);
- }
- else
- {
- fraction_size = 0;
- }
-
- if (str_amount.empty())
- return false;
-
- if (fraction_size < CRYPTONOTE_DISPLAY_DECIMAL_POINT)
- {
- str_amount.append(CRYPTONOTE_DISPLAY_DECIMAL_POINT - fraction_size, '0');
- }
-
- return string_tools::get_xtype_from_string(amount, str_amount);
- }
- //---------------------------------------------------------------
- bool get_tx_fee(const transaction& tx, uint64_t & fee)
- {
- if (tx.version > 1)
- {
- fee = tx.rct_signatures.txnFee;
- return true;
- }
- uint64_t amount_in = 0;
- uint64_t amount_out = 0;
- for(auto& in: tx.vin)
- {
- CHECK_AND_ASSERT_MES(in.type() == typeid(txin_to_key), 0, "unexpected type id in transaction");
- amount_in += boost::get<txin_to_key>(in).amount;
- }
- for(auto& o: tx.vout)
- amount_out += o.amount;
-
- CHECK_AND_ASSERT_MES(amount_in >= amount_out, false, "transaction spend (" <<amount_in << ") more than it has (" << amount_out << ")");
- fee = amount_in - amount_out;
- return true;
- }
- //---------------------------------------------------------------
- uint64_t get_tx_fee(const transaction& tx)
- {
- uint64_t r = 0;
- if(!get_tx_fee(tx, r))
- return 0;
- return r;
- }
- //---------------------------------------------------------------
- bool parse_tx_extra(const std::vector<uint8_t>& tx_extra, std::vector<tx_extra_field>& tx_extra_fields)
- {
- tx_extra_fields.clear();
-
- if(tx_extra.empty())
- return true;
-
- std::string extra_str(reinterpret_cast<const char*>(tx_extra.data()), tx_extra.size());
- std::istringstream iss(extra_str);
- binary_archive<false> ar(iss);
-
- bool eof = false;
- while (!eof)
- {
- tx_extra_field field;
- bool r = ::do_serialize(ar, field);
- CHECK_AND_NO_ASSERT_MES_L1(r, false, "failed to deserialize extra field. extra = " << string_tools::buff_to_hex_nodelimer(std::string(reinterpret_cast<const char*>(tx_extra.data()), tx_extra.size())));
- tx_extra_fields.push_back(field);
-
- std::ios_base::iostate state = iss.rdstate();
- eof = (EOF == iss.peek());
- iss.clear(state);
- }
- CHECK_AND_NO_ASSERT_MES_L1(::serialization::check_stream_state(ar), false, "failed to deserialize extra field. extra = " << string_tools::buff_to_hex_nodelimer(std::string(reinterpret_cast<const char*>(tx_extra.data()), tx_extra.size())));
-
- return true;
- }
- //---------------------------------------------------------------
- crypto::public_key get_tx_pub_key_from_extra(const std::vector<uint8_t>& tx_extra, size_t pk_index)
- {
- std::vector<tx_extra_field> tx_extra_fields;
- parse_tx_extra(tx_extra, tx_extra_fields);
-
- tx_extra_pub_key pub_key_field;
- if(!find_tx_extra_field_by_type(tx_extra_fields, pub_key_field, pk_index))
- return null_pkey;
-
- return pub_key_field.pub_key;
- }
- //---------------------------------------------------------------
- crypto::public_key get_tx_pub_key_from_extra(const transaction_prefix& tx_prefix, size_t pk_index)
- {
- return get_tx_pub_key_from_extra(tx_prefix.extra, pk_index);
- }
- //---------------------------------------------------------------
- crypto::public_key get_tx_pub_key_from_extra(const transaction& tx, size_t pk_index)
- {
- return get_tx_pub_key_from_extra(tx.extra, pk_index);
- }
- //---------------------------------------------------------------
- bool add_tx_pub_key_to_extra(transaction& tx, const crypto::public_key& tx_pub_key)
- {
- tx.extra.resize(tx.extra.size() + 1 + sizeof(crypto::public_key));
- tx.extra[tx.extra.size() - 1 - sizeof(crypto::public_key)] = TX_EXTRA_TAG_PUBKEY;
- *reinterpret_cast<crypto::public_key*>(&tx.extra[tx.extra.size() - sizeof(crypto::public_key)]) = tx_pub_key;
- return true;
- }
- //---------------------------------------------------------------
- bool add_extra_nonce_to_tx_extra(std::vector<uint8_t>& tx_extra, const blobdata& extra_nonce)
- {
- CHECK_AND_ASSERT_MES(extra_nonce.size() <= TX_EXTRA_NONCE_MAX_COUNT, false, "extra nonce could be 255 bytes max");
- size_t start_pos = tx_extra.size();
- tx_extra.resize(tx_extra.size() + 2 + extra_nonce.size());
- //write tag
- tx_extra[start_pos] = TX_EXTRA_NONCE;
- //write len
- ++start_pos;
- tx_extra[start_pos] = static_cast<uint8_t>(extra_nonce.size());
- //write data
- ++start_pos;
- memcpy(&tx_extra[start_pos], extra_nonce.data(), extra_nonce.size());
- return true;
- }
- //---------------------------------------------------------------
- bool remove_field_from_tx_extra(std::vector<uint8_t>& tx_extra, const std::type_info &type)
- {
- if (tx_extra.empty())
- return true;
- std::string extra_str(reinterpret_cast<const char*>(tx_extra.data()), tx_extra.size());
- std::istringstream iss(extra_str);
- binary_archive<false> ar(iss);
- std::ostringstream oss;
- binary_archive<true> newar(oss);
-
- bool eof = false;
- while (!eof)
- {
- tx_extra_field field;
- bool r = ::do_serialize(ar, field);
- CHECK_AND_NO_ASSERT_MES_L1(r, false, "failed to deserialize extra field. extra = " << string_tools::buff_to_hex_nodelimer(std::string(reinterpret_cast<const char*>(tx_extra.data()), tx_extra.size())));
- if (field.type() != type)
- ::do_serialize(newar, field);
-
- std::ios_base::iostate state = iss.rdstate();
- eof = (EOF == iss.peek());
- iss.clear(state);
- }
- CHECK_AND_NO_ASSERT_MES_L1(::serialization::check_stream_state(ar), false, "failed to deserialize extra field. extra = " << string_tools::buff_to_hex_nodelimer(std::string(reinterpret_cast<const char*>(tx_extra.data()), tx_extra.size())));
- tx_extra.clear();
- std::string s = oss.str();
- tx_extra.reserve(s.size());
- std::copy(s.begin(), s.end(), std::back_inserter(tx_extra));
- return true;
- }
- //---------------------------------------------------------------
- void set_payment_id_to_tx_extra_nonce(blobdata& extra_nonce, const crypto::hash& payment_id)
- {
- extra_nonce.clear();
- extra_nonce.push_back(TX_EXTRA_NONCE_PAYMENT_ID);
- const uint8_t* payment_id_ptr = reinterpret_cast<const uint8_t*>(&payment_id);
- std::copy(payment_id_ptr, payment_id_ptr + sizeof(payment_id), std::back_inserter(extra_nonce));
- }
- //---------------------------------------------------------------
- void set_encrypted_payment_id_to_tx_extra_nonce(blobdata& extra_nonce, const crypto::hash8& payment_id)
- {
- extra_nonce.clear();
- extra_nonce.push_back(TX_EXTRA_NONCE_ENCRYPTED_PAYMENT_ID);
- const uint8_t* payment_id_ptr = reinterpret_cast<const uint8_t*>(&payment_id);
- std::copy(payment_id_ptr, payment_id_ptr + sizeof(payment_id), std::back_inserter(extra_nonce));
- }
- //---------------------------------------------------------------
- bool get_payment_id_from_tx_extra_nonce(const blobdata& extra_nonce, crypto::hash& payment_id)
- {
- if(sizeof(crypto::hash) + 1 != extra_nonce.size())
- return false;
- if(TX_EXTRA_NONCE_PAYMENT_ID != extra_nonce[0])
- return false;
- payment_id = *reinterpret_cast<const crypto::hash*>(extra_nonce.data() + 1);
- return true;
- }
- //---------------------------------------------------------------
- bool get_encrypted_payment_id_from_tx_extra_nonce(const blobdata& extra_nonce, crypto::hash8& payment_id)
- {
- if(sizeof(crypto::hash8) + 1 != extra_nonce.size())
- return false;
- if (TX_EXTRA_NONCE_ENCRYPTED_PAYMENT_ID != extra_nonce[0])
- return false;
- payment_id = *reinterpret_cast<const crypto::hash8*>(extra_nonce.data() + 1);
- return true;
- }
- //---------------------------------------------------------------
- crypto::public_key get_destination_view_key_pub(const std::vector<tx_destination_entry> &destinations, const account_keys &sender_keys)
- {
- if (destinations.empty())
- return null_pkey;
- for (size_t n = 1; n < destinations.size(); ++n)
- {
- if (!memcmp(&destinations[n].addr, &sender_keys.m_account_address, sizeof(destinations[0].addr)))
- continue;
- if (destinations[n].amount == 0)
- continue;
- if (memcmp(&destinations[n].addr, &destinations[0].addr, sizeof(destinations[0].addr)))
- return null_pkey;
- }
- return destinations[0].addr.m_view_public_key;
- }
- //---------------------------------------------------------------
- bool encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key)
- {
- crypto::key_derivation derivation;
- crypto::hash hash;
- char data[33]; /* A hash, and an extra byte */
-
- if (!generate_key_derivation(public_key, secret_key, derivation))
- return false;
-
- memcpy(data, &derivation, 32);
- data[32] = ENCRYPTED_PAYMENT_ID_TAIL;
- cn_fast_hash(data, 33, hash);
-
- for (size_t b = 0; b < 8; ++b)
- payment_id.data[b] ^= hash.data[b];
-
- return true;
- }
- bool decrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key)
- {
- // Encryption and decryption are the same operation (xor with a key)
- return encrypt_payment_id(payment_id, public_key, secret_key);
- }
- //---------------------------------------------------------------
- bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::vector<tx_source_entry>& sources, const std::vector<tx_destination_entry>& destinations, std::vector<uint8_t> extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, bool rct)
- {
- std::vector<rct::key> amount_keys;
- tx.set_null();
- amount_keys.clear();
-
- tx.version = rct ? 2 : 1;
- tx.unlock_time = unlock_time;
-
- tx.extra = extra;
- keypair txkey = keypair::generate();
- remove_field_from_tx_extra(tx.extra, typeid(tx_extra_pub_key));
- add_tx_pub_key_to_extra(tx, txkey.pub);
- tx_key = txkey.sec;
-
- // if we have a stealth payment id, find it and encrypt it with the tx key now
- std::vector<tx_extra_field> tx_extra_fields;
- if (parse_tx_extra(tx.extra, tx_extra_fields))
- {
- tx_extra_nonce extra_nonce;
- if (find_tx_extra_field_by_type(tx_extra_fields, extra_nonce))
- {
- crypto::hash8 payment_id = null_hash8;
- if (get_encrypted_payment_id_from_tx_extra_nonce(extra_nonce.nonce, payment_id))
- {
- LOG_PRINT_L2("Encrypting payment id " << payment_id);
- crypto::public_key view_key_pub = get_destination_view_key_pub(destinations, sender_account_keys);
- if (view_key_pub == null_pkey)
- {
- LOG_ERROR("Destinations have to have exactly one output to support encrypted payment ids");
- return false;
- }
-
- if (!encrypt_payment_id(payment_id, view_key_pub, txkey.sec))
- {
- LOG_ERROR("Failed to encrypt payment id");
- return false;
- }
-
- std::string extra_nonce;
- set_encrypted_payment_id_to_tx_extra_nonce(extra_nonce, payment_id);
- remove_field_from_tx_extra(tx.extra, typeid(tx_extra_nonce));
- if (!add_extra_nonce_to_tx_extra(tx.extra, extra_nonce))
- {
- LOG_ERROR("Failed to add encrypted payment id to tx extra");
- return false;
- }
- LOG_PRINT_L1("Encrypted payment ID: " << payment_id);
- }
- }
- }
- else
- {
- LOG_ERROR("Failed to parse tx extra");
- return false;
- }
-
- struct input_generation_context_data
- {
- keypair in_ephemeral;
- };
- std::vector<input_generation_context_data> in_contexts;
-
- uint64_t summary_inputs_money = 0;
- //fill inputs
- int idx = -1;
- for(const tx_source_entry& src_entr: sources)
- {
- ++idx;
- if(src_entr.real_output >= src_entr.outputs.size())
- {
- LOG_ERROR("real_output index (" << src_entr.real_output << ")bigger than output_keys.size()=" << src_entr.outputs.size());
- return false;
- }
- summary_inputs_money += src_entr.amount;
-
- //key_derivation recv_derivation;
- in_contexts.push_back(input_generation_context_data());
- keypair& in_ephemeral = in_contexts.back().in_ephemeral;
- crypto::key_image img;
- if(!generate_key_image_helper(sender_account_keys, src_entr.real_out_tx_key, src_entr.real_output_in_tx_index, in_ephemeral, img))
- return false;
-
- //check that derivated key is equal with real output key
- if( !(in_ephemeral.pub == src_entr.outputs[src_entr.real_output].second.dest) )
- {
- LOG_ERROR("derived public key mismatch with output public key at index " << idx << ", real out " << src_entr.real_output << "! "<< ENDL << "derived_key:"
- << string_tools::pod_to_hex(in_ephemeral.pub) << ENDL << "real output_public_key:"
- << string_tools::pod_to_hex(src_entr.outputs[src_entr.real_output].second) );
- LOG_ERROR("amount " << src_entr.amount << ", rct " << src_entr.rct);
- LOG_ERROR("tx pubkey " << src_entr.real_out_tx_key << ", real_output_in_tx_index " << src_entr.real_output_in_tx_index);
- return false;
- }
-
- //put key image into tx input
- txin_to_key input_to_key;
- input_to_key.amount = src_entr.amount;
- input_to_key.k_image = img;
-
- //fill outputs array and use relative offsets
- for(const tx_source_entry::output_entry& out_entry: src_entr.outputs)
- input_to_key.key_offsets.push_back(out_entry.first);
-
- input_to_key.key_offsets = absolute_output_offsets_to_relative(input_to_key.key_offsets);
- tx.vin.push_back(input_to_key);
- }
-
- // "Shuffle" outs
- std::vector<tx_destination_entry> shuffled_dsts(destinations);
- std::sort(shuffled_dsts.begin(), shuffled_dsts.end(), [](const tx_destination_entry& de1, const tx_destination_entry& de2) { return de1.amount < de2.amount; } );
-
- uint64_t summary_outs_money = 0;
- //fill outputs
- size_t output_index = 0;
- for(const tx_destination_entry& dst_entr: shuffled_dsts)
- {
- CHECK_AND_ASSERT_MES(dst_entr.amount > 0 || tx.version > 1, false, "Destination with wrong amount: " << dst_entr.amount);
- crypto::key_derivation derivation;
- crypto::public_key out_eph_public_key;
- bool r = crypto::generate_key_derivation(dst_entr.addr.m_view_public_key, txkey.sec, derivation);
- CHECK_AND_ASSERT_MES(r, false, "at creation outs: failed to generate_key_derivation(" << dst_entr.addr.m_view_public_key << ", " << txkey.sec << ")");
-
- if (tx.version > 1)
- {
- crypto::secret_key scalar1;
- crypto::derivation_to_scalar(derivation, output_index, scalar1);
- amount_keys.push_back(rct::sk2rct(scalar1));
- }
- r = crypto::derive_public_key(derivation, output_index, dst_entr.addr.m_spend_public_key, out_eph_public_key);
- CHECK_AND_ASSERT_MES(r, false, "at creation outs: failed to derive_public_key(" << derivation << ", " << output_index << ", "<< dst_entr.addr.m_spend_public_key << ")");
-
- tx_out out;
- out.amount = dst_entr.amount;
- txout_to_key tk;
- tk.key = out_eph_public_key;
- out.target = tk;
- tx.vout.push_back(out);
- output_index++;
- summary_outs_money += dst_entr.amount;
- }
-
- //check money
- if(summary_outs_money > summary_inputs_money )
- {
- LOG_ERROR("Transaction inputs money ("<< summary_inputs_money << ") less than outputs money (" << summary_outs_money << ")");
- return false;
- }
-
- // check for watch only wallet
- bool zero_secret_key = true;
- for (size_t i = 0; i < sizeof(sender_account_keys.m_spend_secret_key); ++i)
- zero_secret_key &= (sender_account_keys.m_spend_secret_key.data[i] == 0);
- if (zero_secret_key)
- {
- MDEBUG("Null secret key, skipping signatures");
- }
-
- if (tx.version == 1)
- {
- //generate ring signatures
- crypto::hash tx_prefix_hash;
- get_transaction_prefix_hash(tx, tx_prefix_hash);
-
- std::stringstream ss_ring_s;
- size_t i = 0;
- for(const tx_source_entry& src_entr: sources)
- {
- ss_ring_s << "pub_keys:" << ENDL;
- std::vector<const crypto::public_key*> keys_ptrs;
- std::vector<crypto::public_key> keys(src_entr.outputs.size());
- size_t ii = 0;
- for(const tx_source_entry::output_entry& o: src_entr.outputs)
- {
- keys[ii] = rct2pk(o.second.dest);
- keys_ptrs.push_back(&keys[ii]);
- ss_ring_s << o.second.dest << ENDL;
- ++ii;
- }
-
- tx.signatures.push_back(std::vector<crypto::signature>());
- std::vector<crypto::signature>& sigs = tx.signatures.back();
- sigs.resize(src_entr.outputs.size());
- if (!zero_secret_key)
- crypto::generate_ring_signature(tx_prefix_hash, boost::get<txin_to_key>(tx.vin[i]).k_image, keys_ptrs, in_contexts[i].in_ephemeral.sec, src_entr.real_output, sigs.data());
- ss_ring_s << "signatures:" << ENDL;
- std::for_each(sigs.begin(), sigs.end(), [&](const crypto::signature& s){ss_ring_s << s << ENDL;});
- ss_ring_s << "prefix_hash:" << tx_prefix_hash << ENDL << "in_ephemeral_key: " << in_contexts[i].in_ephemeral.sec << ENDL << "real_output: " << src_entr.real_output;
- i++;
- }
-
- MCINFO("construct_tx", "transaction_created: " << get_transaction_hash(tx) << ENDL << obj_to_json_str(tx) << ENDL << ss_ring_s.str());
- }
- else
- {
- size_t n_total_outs = sources[0].outputs.size(); // only for non-simple rct
-
- // the non-simple version is slightly smaller, but assumes all real inputs
- // are on the same index, so can only be used if there just one ring.
- bool use_simple_rct = sources.size() > 1;
-
- if (!use_simple_rct)
- {
- // non simple ringct requires all real inputs to be at the same index for all inputs
- for(const tx_source_entry& src_entr: sources)
- {
- if(src_entr.real_output != sources.begin()->real_output)
- {
- LOG_ERROR("All inputs must have the same index for non-simple ringct");
- return false;
- }
- }
-
- // enforce same mixin for all outputs
- for (size_t i = 1; i < sources.size(); ++i) {
- if (n_total_outs != sources[i].outputs.size()) {
- LOG_ERROR("Non-simple ringct transaction has varying mixin");
- return false;
- }
- }
- }
-
- uint64_t amount_in = 0, amount_out = 0;
- rct::ctkeyV inSk;
- // mixRing indexing is done the other way round for simple
- rct::ctkeyM mixRing(use_simple_rct ? sources.size() : n_total_outs);
- rct::keyV destinations;
- std::vector<uint64_t> inamounts, outamounts;
- std::vector<unsigned int> index;
- for (size_t i = 0; i < sources.size(); ++i)
- {
- rct::ctkey ctkey;
- amount_in += sources[i].amount;
- inamounts.push_back(sources[i].amount);
- index.push_back(sources[i].real_output);
- // inSk: (secret key, mask)
- ctkey.dest = rct::sk2rct(in_contexts[i].in_ephemeral.sec);
- ctkey.mask = sources[i].mask;
- inSk.push_back(ctkey);
- // inPk: (public key, commitment)
- // will be done when filling in mixRing
- }
- for (size_t i = 0; i < tx.vout.size(); ++i)
- {
- destinations.push_back(rct::pk2rct(boost::get<txout_to_key>(tx.vout[i].target).key));
- outamounts.push_back(tx.vout[i].amount);
- amount_out += tx.vout[i].amount;
- }
-
- if (use_simple_rct)
- {
- // mixRing indexing is done the other way round for simple
- for (size_t i = 0; i < sources.size(); ++i)
- {
- mixRing[i].resize(sources[i].outputs.size());
- for (size_t n = 0; n < sources[i].outputs.size(); ++n)
- {
- mixRing[i][n] = sources[i].outputs[n].second;
- }
- }
- }
- else
- {
- for (size_t i = 0; i < n_total_outs; ++i) // same index assumption
- {
- mixRing[i].resize(sources.size());
- for (size_t n = 0; n < sources.size(); ++n)
- {
- mixRing[i][n] = sources[n].outputs[i].second;
- }
- }
- }
-
- // fee
- if (!use_simple_rct && amount_in > amount_out)
- outamounts.push_back(amount_in - amount_out);
-
- // zero out all amounts to mask rct outputs, real amounts are now encrypted
- for (size_t i = 0; i < tx.vin.size(); ++i)
- {
- if (sources[i].rct)
- boost::get<txin_to_key>(tx.vin[i]).amount = 0;
- }
- for (size_t i = 0; i < tx.vout.size(); ++i)
- tx.vout[i].amount = 0;
-
- crypto::hash tx_prefix_hash;
- get_transaction_prefix_hash(tx, tx_prefix_hash);
- rct::ctkeyV outSk;
- if (use_simple_rct)
- tx.rct_signatures = rct::genRctSimple(rct::hash2rct(tx_prefix_hash), inSk, destinations, inamounts, outamounts, amount_in - amount_out, mixRing, amount_keys, index, outSk);
- else
- tx.rct_signatures = rct::genRct(rct::hash2rct(tx_prefix_hash), inSk, destinations, outamounts, mixRing, amount_keys, sources[0].real_output, outSk); // same index assumption
-
- CHECK_AND_ASSERT_MES(tx.vout.size() == outSk.size(), false, "outSk size does not match vout");
-
- MCINFO("construct_tx", "transaction_created: " << get_transaction_hash(tx) << ENDL << obj_to_json_str(tx) << ENDL);
- }
-
- return true;
- }
- //---------------------------------------------------------------
- bool construct_tx(const account_keys& sender_account_keys, const std::vector<tx_source_entry>& sources, const std::vector<tx_destination_entry>& destinations, std::vector<uint8_t> extra, transaction& tx, uint64_t unlock_time)
- {
- crypto::secret_key tx_key;
- return construct_tx_and_get_tx_key(sender_account_keys, sources, destinations, extra, tx, unlock_time, tx_key);
- }
- //---------------------------------------------------------------
- bool get_inputs_money_amount(const transaction& tx, uint64_t& money)
- {
- money = 0;
- for(const auto& in: tx.vin)
- {
- CHECKED_GET_SPECIFIC_VARIANT(in, const txin_to_key, tokey_in, false);
- money += tokey_in.amount;
- }
- return true;
- }
- //---------------------------------------------------------------
- uint64_t get_block_height(const block& b)
- {
- CHECK_AND_ASSERT_MES(b.miner_tx.vin.size() == 1, 0, "wrong miner tx in block: " << get_block_hash(b) << ", b.miner_tx.vin.size() != 1");
- CHECKED_GET_SPECIFIC_VARIANT(b.miner_tx.vin[0], const txin_gen, coinbase_in, 0);
- return coinbase_in.height;
- }
- //---------------------------------------------------------------
- bool check_inputs_types_supported(const transaction& tx)
- {
- for(const auto& in: tx.vin)
- {
- CHECK_AND_ASSERT_MES(in.type() == typeid(txin_to_key), false, "wrong variant type: "
- << in.type().name() << ", expected " << typeid(txin_to_key).name()
- << ", in transaction id=" << get_transaction_hash(tx));
-
- }
- return true;
- }
- //-----------------------------------------------------------------------------------------------
- bool check_outs_valid(const transaction& tx)
- {
- for(const tx_out& out: tx.vout)
- {
- CHECK_AND_ASSERT_MES(out.target.type() == typeid(txout_to_key), false, "wrong variant type: "
- << out.target.type().name() << ", expected " << typeid(txout_to_key).name()
- << ", in transaction id=" << get_transaction_hash(tx));
-
- if (tx.version == 1)
- {
- CHECK_AND_NO_ASSERT_MES(0 < out.amount, false, "zero amount output in transaction id=" << get_transaction_hash(tx));
- }
-
- if(!check_key(boost::get<txout_to_key>(out.target).key))
- return false;
- }
- return true;
- }
- //-----------------------------------------------------------------------------------------------
- bool check_money_overflow(const transaction& tx)
- {
- return check_inputs_overflow(tx) && check_outs_overflow(tx);
- }
- //---------------------------------------------------------------
- bool check_inputs_overflow(const transaction& tx)
- {
- uint64_t money = 0;
- for(const auto& in: tx.vin)
- {
- CHECKED_GET_SPECIFIC_VARIANT(in, const txin_to_key, tokey_in, false);
- if(money > tokey_in.amount + money)
- return false;
- money += tokey_in.amount;
- }
- return true;
- }
- //---------------------------------------------------------------
- bool check_outs_overflow(const transaction& tx)
- {
- uint64_t money = 0;
- for(const auto& o: tx.vout)
- {
- if(money > o.amount + money)
- return false;
- money += o.amount;
- }
- return true;
- }
- //---------------------------------------------------------------
- uint64_t get_outs_money_amount(const transaction& tx)
- {
- uint64_t outputs_amount = 0;
- for(const auto& o: tx.vout)
- outputs_amount += o.amount;
- return outputs_amount;
- }
- //---------------------------------------------------------------
- std::string short_hash_str(const crypto::hash& h)
- {
- std::string res = string_tools::pod_to_hex(h);
- CHECK_AND_ASSERT_MES(res.size() == 64, res, "wrong hash256 with string_tools::pod_to_hex conversion");
- auto erased_pos = res.erase(8, 48);
- res.insert(8, "....");
- return res;
- }
- //---------------------------------------------------------------
- bool is_out_to_acc(const account_keys& acc, const txout_to_key& out_key, const crypto::public_key& tx_pub_key, size_t output_index)
- {
- crypto::key_derivation derivation;
- generate_key_derivation(tx_pub_key, acc.m_view_secret_key, derivation);
- crypto::public_key pk;
- derive_public_key(derivation, output_index, acc.m_account_address.m_spend_public_key, pk);
- return pk == out_key.key;
- }
- //---------------------------------------------------------------
- bool is_out_to_acc_precomp(const crypto::public_key& spend_public_key, const txout_to_key& out_key, const crypto::key_derivation& derivation, size_t output_index)
- {
- crypto::public_key pk;
- derive_public_key(derivation, output_index, spend_public_key, pk);
- return pk == out_key.key;
- }
- //---------------------------------------------------------------
- bool lookup_acc_outs(const account_keys& acc, const transaction& tx, std::vector<size_t>& outs, uint64_t& money_transfered)
- {
- crypto::public_key tx_pub_key = get_tx_pub_key_from_extra(tx);
- if(null_pkey == tx_pub_key)
- return false;
- return lookup_acc_outs(acc, tx, tx_pub_key, outs, money_transfered);
- }
- //---------------------------------------------------------------
- bool lookup_acc_outs(const account_keys& acc, const transaction& tx, const crypto::public_key& tx_pub_key, std::vector<size_t>& outs, uint64_t& money_transfered)
- {
- money_transfered = 0;
- size_t i = 0;
- for(const tx_out& o: tx.vout)
- {
- CHECK_AND_ASSERT_MES(o.target.type() == typeid(txout_to_key), false, "wrong type id in transaction out" );
- if(is_out_to_acc(acc, boost::get<txout_to_key>(o.target), tx_pub_key, i))
- {
- outs.push_back(i);
- money_transfered += o.amount;
- }
- i++;
- }
- return true;
- }
- //---------------------------------------------------------------
- void get_blob_hash(const blobdata& blob, crypto::hash& res)
- {
- cn_fast_hash(blob.data(), blob.size(), res);
- }
- //---------------------------------------------------------------
- std::string print_money(uint64_t amount)
- {
- std::string s = std::to_string(amount);
- if(s.size() < CRYPTONOTE_DISPLAY_DECIMAL_POINT+1)
- {
- s.insert(0, CRYPTONOTE_DISPLAY_DECIMAL_POINT+1 - s.size(), '0');
- }
- s.insert(s.size() - CRYPTONOTE_DISPLAY_DECIMAL_POINT, ".");
- return s;
- }
- //---------------------------------------------------------------
- crypto::hash get_blob_hash(const blobdata& blob)
- {
- crypto::hash h = null_hash;
- get_blob_hash(blob, h);
- return h;
- }
- //---------------------------------------------------------------
- crypto::hash get_transaction_hash(const transaction& t)
- {
- crypto::hash h = null_hash;
- get_transaction_hash(t, h, NULL);
- return h;
- }
- //---------------------------------------------------------------
- bool get_transaction_hash(const transaction& t, crypto::hash& res)
- {
- return get_transaction_hash(t, res, NULL);
- }
- //---------------------------------------------------------------
- bool get_transaction_hash(const transaction& t, crypto::hash& res, size_t* blob_size)
- {
- // v1 transactions hash the entire blob
- if (t.version == 1)
- {
- size_t ignored_blob_size, &blob_size_ref = blob_size ? *blob_size : ignored_blob_size;
- return get_object_hash(t, res, blob_size_ref);
- }
-
- // v2 transactions hash different parts together, than hash the set of those hashes
- crypto::hash hashes[3];
-
- // prefix
- get_transaction_prefix_hash(t, hashes[0]);
-
- transaction &tt = const_cast<transaction&>(t);
-
- // base rct
- {
- std::stringstream ss;
- binary_archive<true> ba(ss);
- const size_t inputs = t.vin.size();
- const size_t outputs = t.vout.size();
- bool r = tt.rct_signatures.serialize_rctsig_base(ba, inputs, outputs);
- CHECK_AND_ASSERT_MES(r, false, "Failed to serialize rct signatures base");
- cryptonote::get_blob_hash(ss.str(), hashes[1]);
- }
-
- // prunable rct
- if (t.rct_signatures.type == rct::RCTTypeNull)
- {
- hashes[2] = cryptonote::null_hash;
- }
- else
- {
- std::stringstream ss;
- binary_archive<true> ba(ss);
- const size_t inputs = t.vin.size();
- const size_t outputs = t.vout.size();
- const size_t mixin = t.vin.empty() ? 0 : t.vin[0].type() == typeid(txin_to_key) ? boost::get<txin_to_key>(t.vin[0]).key_offsets.size() - 1 : 0;
- bool r = tt.rct_signatures.p.serialize_rctsig_prunable(ba, t.rct_signatures.type, inputs, outputs, mixin);
- CHECK_AND_ASSERT_MES(r, false, "Failed to serialize rct signatures prunable");
- cryptonote::get_blob_hash(ss.str(), hashes[2]);
- }
-
- // the tx hash is the hash of the 3 hashes
- res = cn_fast_hash(hashes, sizeof(hashes));
-
- // we still need the size
- if (blob_size)
- *blob_size = get_object_blobsize(t);
-
- return true;
- }
- //---------------------------------------------------------------
- bool get_transaction_hash(const transaction& t, crypto::hash& res, size_t& blob_size)
- {
- return get_transaction_hash(t, res, &blob_size);
- }
- //---------------------------------------------------------------
- blobdata get_block_hashing_blob(const block& b)
- {
- blobdata blob = t_serializable_object_to_blob(static_cast<block_header>(b));
- crypto::hash tree_root_hash = get_tx_tree_hash(b);
- blob.append(reinterpret_cast<const char*>(&tree_root_hash), sizeof(tree_root_hash));
- blob.append(tools::get_varint_data(b.tx_hashes.size()+1));
- return blob;
- }
- //---------------------------------------------------------------
- bool get_block_hash(const block& b, crypto::hash& res)
- {
- // EXCEPTION FOR BLOCK 202612
- const std::string correct_blob_hash_202612 = "3a8a2b3a29b50fc86ff73dd087ea43c6f0d6b8f936c849194d5c84c737903966";
- const std::string existing_block_id_202612 = "bbd604d2ba11ba27935e006ed39c9bfdd99b76bf4a50654bc1e1e61217962698";
- crypto::hash block_blob_hash = get_blob_hash(block_to_blob(b));
-
- if (string_tools::pod_to_hex(block_blob_hash) == correct_blob_hash_202612)
- {
- string_tools::hex_to_pod(existing_block_id_202612, res);
- return true;
- }
- bool hash_result = get_object_hash(get_block_hashing_blob(b), res);
-
- if (hash_result)
- {
- // make sure that we aren't looking at a block with the 202612 block id but not the correct blobdata
- if (string_tools::pod_to_hex(res) == existing_block_id_202612)
- {
- LOG_ERROR("Block with block id for 202612 but incorrect block blob hash found!");
- res = null_hash;
- return false;
- }
- }
- return hash_result;
- }
- //---------------------------------------------------------------
- crypto::hash get_block_hash(const block& b)
- {
- crypto::hash p = null_hash;
- get_block_hash(b, p);
- return p;
- }
- //---------------------------------------------------------------
- bool generate_genesis_block(
- block& bl
- , std::string const & genesis_tx
- , uint32_t nonce
- )
- {
- //genesis block
- bl = boost::value_initialized<block>();
-
-
- account_public_address ac = boost::value_initialized<account_public_address>();
- std::vector<size_t> sz;
- construct_miner_tx(0, 0, 0, 0, 0, ac, bl.miner_tx); // zero fee in genesis
- blobdata txb = tx_to_blob(bl.miner_tx);
- std::string hex_tx_represent = string_tools::buff_to_hex_nodelimer(txb);
-
- std::string genesis_coinbase_tx_hex = config::GENESIS_TX;
-
- blobdata tx_bl;
- string_tools::parse_hexstr_to_binbuff(genesis_coinbase_tx_hex, tx_bl);
- bool r = parse_and_validate_tx_from_blob(tx_bl, bl.miner_tx);
- CHECK_AND_ASSERT_MES(r, false, "failed to parse coinbase tx from hard coded blob");
- bl.major_version = CURRENT_BLOCK_MAJOR_VERSION;
- bl.minor_version = CURRENT_BLOCK_MINOR_VERSION;
- bl.timestamp = 0;
- bl.nonce = nonce;
- miner::find_nonce_for_given_block(bl, 1, 0);
- return true;
- }
- //---------------------------------------------------------------
- bool get_block_longhash(const block& b, crypto::hash& res, uint64_t height)
- {
- // block 202612 bug workaround
- const std::string longhash_202612 = "84f64766475d51837ac9efbef1926486e58563c95a19fef4aec3254f03000000";
- if (height == 202612)
- {
- string_tools::hex_to_pod(longhash_202612, res);
- return true;
- }
- block b_local = b; //workaround to avoid const errors with do_serialize
- blobdata bd = get_block_hashing_blob(b);
- crypto::cn_slow_hash(bd.data(), bd.size(), res);
- return true;
- }
- //---------------------------------------------------------------
- std::vector<uint64_t> relative_output_offsets_to_absolute(const std::vector<uint64_t>& off)
- {
- std::vector<uint64_t> res = off;
- for(size_t i = 1; i < res.size(); i++)
- res[i] += res[i-1];
- return res;
- }
- //---------------------------------------------------------------
- std::vector<uint64_t> absolute_output_offsets_to_relative(const std::vector<uint64_t>& off)
- {
- std::vector<uint64_t> res = off;
- if(!off.size())
- return res;
- std::sort(res.begin(), res.end());//just to be sure, actually it is already should be sorted
- for(size_t i = res.size()-1; i != 0; i--)
- res[i] -= res[i-1];
-
- return res;
- }
- //---------------------------------------------------------------
- crypto::hash get_block_longhash(const block& b, uint64_t height)
- {
- crypto::hash p = null_hash;
- get_block_longhash(b, p, height);
- return p;
- }
- //---------------------------------------------------------------
- bool parse_and_validate_block_from_blob(const blobdata& b_blob, block& b)
- {
- std::stringstream ss;
- ss << b_blob;
- binary_archive<false> ba(ss);
- bool r = ::serialization::serialize(ba, b);
- CHECK_AND_ASSERT_MES(r, false, "Failed to parse block from blob");
- return true;
- }
- //---------------------------------------------------------------
- blobdata block_to_blob(const block& b)
- {
- return t_serializable_object_to_blob(b);
- }
- //---------------------------------------------------------------
- bool block_to_blob(const block& b, blobdata& b_blob)
- {
- return t_serializable_object_to_blob(b, b_blob);
- }
- //---------------------------------------------------------------
- blobdata tx_to_blob(const transaction& tx)
- {
- return t_serializable_object_to_blob(tx);
- }
- //---------------------------------------------------------------
- bool tx_to_blob(const transaction& tx, blobdata& b_blob)
- {
- return t_serializable_object_to_blob(tx, b_blob);
- }
- //---------------------------------------------------------------
- void get_tx_tree_hash(const std::vector<crypto::hash>& tx_hashes, crypto::hash& h)
- {
- tree_hash(tx_hashes.data(), tx_hashes.size(), h);
- }
- //---------------------------------------------------------------
- crypto::hash get_tx_tree_hash(const std::vector<crypto::hash>& tx_hashes)
- {
- crypto::hash h = null_hash;
- get_tx_tree_hash(tx_hashes, h);
- return h;
- }
- //---------------------------------------------------------------
- crypto::hash get_tx_tree_hash(const block& b)
- {
- std::vector<crypto::hash> txs_ids;
- crypto::hash h = null_hash;
- size_t bl_sz = 0;
- get_transaction_hash(b.miner_tx, h, bl_sz);
- txs_ids.push_back(h);
- for(auto& th: b.tx_hashes)
- txs_ids.push_back(th);
- return get_tx_tree_hash(txs_ids);
- }
- //---------------------------------------------------------------
- bool is_valid_decomposed_amount(uint64_t amount)
- {
- const uint64_t *begin = valid_decomposed_outputs;
- const uint64_t *end = valid_decomposed_outputs + sizeof(valid_decomposed_outputs) / sizeof(valid_decomposed_outputs[0]);
- return std::binary_search(begin, end, amount);
- }
- //---------------------------------------------------------------
-}
diff --git a/src/cryptonote_core/cryptonote_format_utils.h b/src/cryptonote_core/cryptonote_format_utils.h
deleted file mode 100644
index a6610e60d..000000000
--- a/src/cryptonote_core/cryptonote_format_utils.h
+++ /dev/null
@@ -1,274 +0,0 @@
-// Copyright (c) 2014-2016, 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
-
-#pragma once
-#include "cryptonote_protocol/cryptonote_protocol_defs.h"
-#include "cryptonote_core/cryptonote_basic_impl.h"
-#include "account.h"
-#include "include_base_utils.h"
-#include "crypto/crypto.h"
-#include "crypto/hash.h"
-#include "ringct/rctOps.h"
-#include <boost/serialization/vector.hpp>
-#include <boost/serialization/utility.hpp>
-
-namespace cryptonote
-{
- //---------------------------------------------------------------
- void get_transaction_prefix_hash(const transaction_prefix& tx, crypto::hash& h);
- crypto::hash get_transaction_prefix_hash(const transaction_prefix& tx);
- bool parse_and_validate_tx_from_blob(const blobdata& tx_blob, transaction& tx, crypto::hash& tx_hash, crypto::hash& tx_prefix_hash);
- bool parse_and_validate_tx_from_blob(const blobdata& tx_blob, transaction& tx);
- bool construct_miner_tx(size_t height, size_t median_size, uint64_t already_generated_coins, size_t current_block_size, uint64_t fee, const account_public_address &miner_address, transaction& tx, const blobdata& extra_nonce = blobdata(), size_t max_outs = 999, uint8_t hard_fork_version = 1);
- bool encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key);
- bool decrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key);
-
- struct tx_source_entry
- {
- typedef std::pair<uint64_t, rct::ctkey> output_entry;
-
- std::vector<output_entry> outputs; //index + key + optional ringct commitment
- size_t real_output; //index in outputs vector of real output_entry
- crypto::public_key real_out_tx_key; //incoming real tx public key
- size_t real_output_in_tx_index; //index in transaction outputs vector
- uint64_t amount; //money
- bool rct; //true if the output is rct
- rct::key mask; //ringct amount mask
-
- void push_output(uint64_t idx, const crypto::public_key &k, uint64_t amount) { outputs.push_back(std::make_pair(idx, rct::ctkey({rct::pk2rct(k), rct::zeroCommit(amount)}))); }
- };
-
- struct tx_destination_entry
- {
- uint64_t amount; //money
- account_public_address addr; //destination address
-
- tx_destination_entry() : amount(0), addr(AUTO_VAL_INIT(addr)) { }
- tx_destination_entry(uint64_t a, const account_public_address &ad) : amount(a), addr(ad) { }
-
- BEGIN_SERIALIZE_OBJECT()
- VARINT_FIELD(amount)
- FIELD(addr)
- END_SERIALIZE()
- };
-
- //---------------------------------------------------------------
- bool construct_tx(const account_keys& sender_account_keys, const std::vector<tx_source_entry>& sources, const std::vector<tx_destination_entry>& destinations, std::vector<uint8_t> extra, transaction& tx, uint64_t unlock_time);
- bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::vector<tx_source_entry>& sources, const std::vector<tx_destination_entry>& destinations, std::vector<uint8_t> extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, bool rct = false);
-
- template<typename T>
- bool find_tx_extra_field_by_type(const std::vector<tx_extra_field>& tx_extra_fields, T& field, size_t index = 0)
- {
- auto it = std::find_if(tx_extra_fields.begin(), tx_extra_fields.end(), [&index](const tx_extra_field& f) { return typeid(T) == f.type() && !index--; });
- if(tx_extra_fields.end() == it)
- return false;
-
- field = boost::get<T>(*it);
- return true;
- }
-
- bool parse_tx_extra(const std::vector<uint8_t>& tx_extra, std::vector<tx_extra_field>& tx_extra_fields);
- crypto::public_key get_tx_pub_key_from_extra(const std::vector<uint8_t>& tx_extra, size_t pk_index = 0);
- crypto::public_key get_tx_pub_key_from_extra(const transaction_prefix& tx, size_t pk_index = 0);
- crypto::public_key get_tx_pub_key_from_extra(const transaction& tx, size_t pk_index = 0);
- bool add_tx_pub_key_to_extra(transaction& tx, const crypto::public_key& tx_pub_key);
- bool add_extra_nonce_to_tx_extra(std::vector<uint8_t>& tx_extra, const blobdata& extra_nonce);
- bool remove_field_from_tx_extra(std::vector<uint8_t>& tx_extra, const std::type_info &type);
- void set_payment_id_to_tx_extra_nonce(blobdata& extra_nonce, const crypto::hash& payment_id);
- void set_encrypted_payment_id_to_tx_extra_nonce(blobdata& extra_nonce, const crypto::hash8& payment_id);
- bool get_payment_id_from_tx_extra_nonce(const blobdata& extra_nonce, crypto::hash& payment_id);
- bool get_encrypted_payment_id_from_tx_extra_nonce(const blobdata& extra_nonce, crypto::hash8& payment_id);
- bool is_out_to_acc(const account_keys& acc, const txout_to_key& out_key, const crypto::public_key& tx_pub_key, size_t output_index);
- bool is_out_to_acc_precomp(const crypto::public_key& spend_public_key, const txout_to_key& out_key, const crypto::key_derivation& derivation, size_t output_index);
- bool lookup_acc_outs(const account_keys& acc, const transaction& tx, const crypto::public_key& tx_pub_key, std::vector<size_t>& outs, uint64_t& money_transfered);
- bool lookup_acc_outs(const account_keys& acc, const transaction& tx, std::vector<size_t>& outs, uint64_t& money_transfered);
- bool get_tx_fee(const transaction& tx, uint64_t & fee);
- uint64_t get_tx_fee(const transaction& tx);
- bool generate_key_image_helper(const account_keys& ack, const crypto::public_key& tx_public_key, size_t real_output_index, keypair& in_ephemeral, crypto::key_image& ki);
- void get_blob_hash(const blobdata& blob, crypto::hash& res);
- crypto::hash get_blob_hash(const blobdata& blob);
- std::string short_hash_str(const crypto::hash& h);
-
- crypto::hash get_transaction_hash(const transaction& t);
- bool get_transaction_hash(const transaction& t, crypto::hash& res);
- bool get_transaction_hash(const transaction& t, crypto::hash& res, size_t& blob_size);
- bool get_transaction_hash(const transaction& t, crypto::hash& res, size_t* blob_size);
- blobdata get_block_hashing_blob(const block& b);
- bool get_block_hash(const block& b, crypto::hash& res);
- crypto::hash get_block_hash(const block& b);
- bool get_block_longhash(const block& b, crypto::hash& res, uint64_t height);
- crypto::hash get_block_longhash(const block& b, uint64_t height);
- bool generate_genesis_block(
- block& bl
- , std::string const & genesis_tx
- , uint32_t nonce
- );
- bool parse_and_validate_block_from_blob(const blobdata& b_blob, block& b);
- bool get_inputs_money_amount(const transaction& tx, uint64_t& money);
- uint64_t get_outs_money_amount(const transaction& tx);
- bool check_inputs_types_supported(const transaction& tx);
- bool check_outs_valid(const transaction& tx);
- bool parse_amount(uint64_t& amount, const std::string& str_amount);
-
- bool check_money_overflow(const transaction& tx);
- bool check_outs_overflow(const transaction& tx);
- bool check_inputs_overflow(const transaction& tx);
- uint64_t get_block_height(const block& b);
- std::vector<uint64_t> relative_output_offsets_to_absolute(const std::vector<uint64_t>& off);
- std::vector<uint64_t> absolute_output_offsets_to_relative(const std::vector<uint64_t>& off);
- std::string print_money(uint64_t amount);
- //---------------------------------------------------------------
- template<class t_object>
- bool t_serializable_object_to_blob(const t_object& to, blobdata& b_blob)
- {
- std::stringstream ss;
- binary_archive<true> ba(ss);
- bool r = ::serialization::serialize(ba, const_cast<t_object&>(to));
- b_blob = ss.str();
- return r;
- }
- //---------------------------------------------------------------
- template<class t_object>
- blobdata t_serializable_object_to_blob(const t_object& to)
- {
- blobdata b;
- t_serializable_object_to_blob(to, b);
- return b;
- }
- //---------------------------------------------------------------
- template<class t_object>
- bool get_object_hash(const t_object& o, crypto::hash& res)
- {
- get_blob_hash(t_serializable_object_to_blob(o), res);
- return true;
- }
- //---------------------------------------------------------------
- template<class t_object>
- size_t get_object_blobsize(const t_object& o)
- {
- blobdata b = t_serializable_object_to_blob(o);
- return b.size();
- }
- //---------------------------------------------------------------
- template<class t_object>
- bool get_object_hash(const t_object& o, crypto::hash& res, size_t& blob_size)
- {
- blobdata bl = t_serializable_object_to_blob(o);
- blob_size = bl.size();
- get_blob_hash(bl, res);
- return true;
- }
- //---------------------------------------------------------------
- template <typename T>
- std::string obj_to_json_str(T& obj)
- {
- std::stringstream ss;
- json_archive<true> ar(ss, true);
- bool r = ::serialization::serialize(ar, obj);
- CHECK_AND_ASSERT_MES(r, "", "obj_to_json_str failed: serialization::serialize returned false");
- return ss.str();
- }
- //---------------------------------------------------------------
- // 62387455827 -> 455827 + 7000000 + 80000000 + 300000000 + 2000000000 + 60000000000, where 455827 <= dust_threshold
- template<typename chunk_handler_t, typename dust_handler_t>
- void decompose_amount_into_digits(uint64_t amount, uint64_t dust_threshold, const chunk_handler_t& chunk_handler, const dust_handler_t& dust_handler)
- {
- if (0 == amount)
- {
- return;
- }
-
- bool is_dust_handled = false;
- uint64_t dust = 0;
- uint64_t order = 1;
- while (0 != amount)
- {
- uint64_t chunk = (amount % 10) * order;
- amount /= 10;
- order *= 10;
-
- if (dust + chunk <= dust_threshold)
- {
- dust += chunk;
- }
- else
- {
- if (!is_dust_handled && 0 != dust)
- {
- dust_handler(dust);
- is_dust_handled = true;
- }
- if (0 != chunk)
- {
- chunk_handler(chunk);
- }
- }
- }
-
- if (!is_dust_handled && 0 != dust)
- {
- dust_handler(dust);
- }
- }
- //---------------------------------------------------------------
- blobdata block_to_blob(const block& b);
- bool block_to_blob(const block& b, blobdata& b_blob);
- blobdata tx_to_blob(const transaction& b);
- bool tx_to_blob(const transaction& b, blobdata& b_blob);
- void get_tx_tree_hash(const std::vector<crypto::hash>& tx_hashes, crypto::hash& h);
- crypto::hash get_tx_tree_hash(const std::vector<crypto::hash>& tx_hashes);
- crypto::hash get_tx_tree_hash(const block& b);
- bool is_valid_decomposed_amount(uint64_t amount);
-
-#define CHECKED_GET_SPECIFIC_VARIANT(variant_var, specific_type, variable_name, fail_return_val) \
- CHECK_AND_ASSERT_MES(variant_var.type() == typeid(specific_type), fail_return_val, "wrong variant type: " << variant_var.type().name() << ", expected " << typeid(specific_type).name()); \
- specific_type& variable_name = boost::get<specific_type>(variant_var);
-
-}
-
-BOOST_CLASS_VERSION(cryptonote::tx_source_entry, 0)
-
-namespace boost
-{
- namespace serialization
- {
- template <class Archive>
- inline void serialize(Archive &a, cryptonote::tx_source_entry &x, const boost::serialization::version_type ver)
- {
- a & x.outputs;
- a & x.real_output;
- a & x.real_out_tx_key;
- a & x.real_output_in_tx_index;
- a & x.amount;
- a & x.rct;
- a & x.mask;
- }
- }
-}
diff --git a/src/cryptonote_core/cryptonote_stat_info.h b/src/cryptonote_core/cryptonote_stat_info.h
deleted file mode 100644
index d44904b6d..000000000
--- a/src/cryptonote_core/cryptonote_stat_info.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) 2014-2016, 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
-
-#pragma once
-#include "serialization/keyvalue_serialization.h"
-
-
-namespace cryptonote
-{
- struct core_stat_info
- {
- uint64_t tx_pool_size;
- uint64_t blockchain_height;
- uint64_t mining_speed;
- uint64_t alternative_blocks;
- std::string top_block_id_str;
-
- BEGIN_KV_SERIALIZE_MAP()
- KV_SERIALIZE(tx_pool_size)
- KV_SERIALIZE(blockchain_height)
- KV_SERIALIZE(mining_speed)
- KV_SERIALIZE(alternative_blocks)
- KV_SERIALIZE(top_block_id_str)
- END_KV_SERIALIZE_MAP()
- };
-}
diff --git a/src/cryptonote_core/cryptonote_tx_utils.cpp b/src/cryptonote_core/cryptonote_tx_utils.cpp
new file mode 100644
index 000000000..42e612e2f
--- /dev/null
+++ b/src/cryptonote_core/cryptonote_tx_utils.cpp
@@ -0,0 +1,493 @@
+// Copyright (c) 2014-2016, 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 "include_base_utils.h"
+using namespace epee;
+
+#include "cryptonote_tx_utils.h"
+#include "cryptonote_config.h"
+#include "cryptonote_basic/miner.h"
+#include "crypto/crypto.h"
+#include "crypto/hash.h"
+#include "ringct/rctSigs.h"
+
+namespace cryptonote
+{
+ //---------------------------------------------------------------
+ bool construct_miner_tx(size_t height, size_t median_size, uint64_t already_generated_coins, size_t current_block_size, uint64_t fee, const account_public_address &miner_address, transaction& tx, const blobdata& extra_nonce, size_t max_outs, uint8_t hard_fork_version) {
+ tx.vin.clear();
+ tx.vout.clear();
+ tx.extra.clear();
+
+ keypair txkey = keypair::generate();
+ add_tx_pub_key_to_extra(tx, txkey.pub);
+ if(!extra_nonce.empty())
+ if(!add_extra_nonce_to_tx_extra(tx.extra, extra_nonce))
+ return false;
+
+ txin_gen in;
+ in.height = height;
+
+ uint64_t block_reward;
+ if(!get_block_reward(median_size, current_block_size, already_generated_coins, block_reward, hard_fork_version))
+ {
+ LOG_PRINT_L0("Block is too big");
+ return false;
+ }
+
+#if defined(DEBUG_CREATE_BLOCK_TEMPLATE)
+ LOG_PRINT_L1("Creating block template: reward " << block_reward <<
+ ", fee " << fee);
+#endif
+ block_reward += fee;
+
+ // from hard fork 2, we cut out the low significant digits. This makes the tx smaller, and
+ // keeps the paid amount almost the same. The unpaid remainder gets pushed back to the
+ // emission schedule
+ // from hard fork 4, we use a single "dusty" output. This makes the tx even smaller,
+ // and avoids the quantization. These outputs will be added as rct outputs with identity
+ // masks, to they can be used as rct inputs.
+ if (hard_fork_version >= 2 && hard_fork_version < 4) {
+ block_reward = block_reward - block_reward % ::config::BASE_REWARD_CLAMP_THRESHOLD;
+ }
+
+ std::vector<uint64_t> out_amounts;
+ decompose_amount_into_digits(block_reward, hard_fork_version >= 2 ? 0 : ::config::DEFAULT_DUST_THRESHOLD,
+ [&out_amounts](uint64_t a_chunk) { out_amounts.push_back(a_chunk); },
+ [&out_amounts](uint64_t a_dust) { out_amounts.push_back(a_dust); });
+
+ CHECK_AND_ASSERT_MES(1 <= max_outs, false, "max_out must be non-zero");
+ if (height == 0 || hard_fork_version >= 4)
+ {
+ // the genesis block was not decomposed, for unknown reasons
+ while (max_outs < out_amounts.size())
+ {
+ //out_amounts[out_amounts.size() - 2] += out_amounts.back();
+ //out_amounts.resize(out_amounts.size() - 1);
+ out_amounts[1] += out_amounts[0];
+ for (size_t n = 1; n < out_amounts.size(); ++n)
+ out_amounts[n - 1] = out_amounts[n];
+ out_amounts.resize(out_amounts.size() - 1);
+ }
+ }
+ else
+ {
+ CHECK_AND_ASSERT_MES(max_outs >= out_amounts.size(), false, "max_out exceeded");
+ }
+
+ uint64_t summary_amounts = 0;
+ for (size_t no = 0; no < out_amounts.size(); no++)
+ {
+ crypto::key_derivation derivation = AUTO_VAL_INIT(derivation);;
+ crypto::public_key out_eph_public_key = AUTO_VAL_INIT(out_eph_public_key);
+ bool r = crypto::generate_key_derivation(miner_address.m_view_public_key, txkey.sec, derivation);
+ CHECK_AND_ASSERT_MES(r, false, "while creating outs: failed to generate_key_derivation(" << miner_address.m_view_public_key << ", " << txkey.sec << ")");
+
+ r = crypto::derive_public_key(derivation, no, miner_address.m_spend_public_key, out_eph_public_key);
+ CHECK_AND_ASSERT_MES(r, false, "while creating outs: failed to derive_public_key(" << derivation << ", " << no << ", "<< miner_address.m_spend_public_key << ")");
+
+ txout_to_key tk;
+ tk.key = out_eph_public_key;
+
+ tx_out out;
+ summary_amounts += out.amount = out_amounts[no];
+ out.target = tk;
+ tx.vout.push_back(out);
+ }
+
+ CHECK_AND_ASSERT_MES(summary_amounts == block_reward, false, "Failed to construct miner tx, summary_amounts = " << summary_amounts << " not equal block_reward = " << block_reward);
+
+ if (hard_fork_version >= 4)
+ tx.version = 2;
+ else
+ tx.version = 1;
+
+ //lock
+ tx.unlock_time = height + CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW;
+ tx.vin.push_back(in);
+ //LOG_PRINT("MINER_TX generated ok, block_reward=" << print_money(block_reward) << "(" << print_money(block_reward - fee) << "+" << print_money(fee)
+ // << "), current_block_size=" << current_block_size << ", already_generated_coins=" << already_generated_coins << ", tx_id=" << get_transaction_hash(tx), LOG_LEVEL_2);
+ return true;
+ }
+ //---------------------------------------------------------------
+ crypto::public_key get_destination_view_key_pub(const std::vector<tx_destination_entry> &destinations, const account_keys &sender_keys)
+ {
+ if (destinations.empty())
+ return null_pkey;
+ for (size_t n = 1; n < destinations.size(); ++n)
+ {
+ if (!memcmp(&destinations[n].addr, &sender_keys.m_account_address, sizeof(destinations[0].addr)))
+ continue;
+ if (destinations[n].amount == 0)
+ continue;
+ if (memcmp(&destinations[n].addr, &destinations[0].addr, sizeof(destinations[0].addr)))
+ return null_pkey;
+ }
+ return destinations[0].addr.m_view_public_key;
+ }
+ //---------------------------------------------------------------
+ bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::vector<tx_source_entry>& sources, const std::vector<tx_destination_entry>& destinations, std::vector<uint8_t> extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, bool rct)
+ {
+ std::vector<rct::key> amount_keys;
+ tx.set_null();
+ amount_keys.clear();
+
+ tx.version = rct ? 2 : 1;
+ tx.unlock_time = unlock_time;
+
+ tx.extra = extra;
+ keypair txkey = keypair::generate();
+ remove_field_from_tx_extra(tx.extra, typeid(tx_extra_pub_key));
+ add_tx_pub_key_to_extra(tx, txkey.pub);
+ tx_key = txkey.sec;
+
+ // if we have a stealth payment id, find it and encrypt it with the tx key now
+ std::vector<tx_extra_field> tx_extra_fields;
+ if (parse_tx_extra(tx.extra, tx_extra_fields))
+ {
+ tx_extra_nonce extra_nonce;
+ if (find_tx_extra_field_by_type(tx_extra_fields, extra_nonce))
+ {
+ crypto::hash8 payment_id = null_hash8;
+ if (get_encrypted_payment_id_from_tx_extra_nonce(extra_nonce.nonce, payment_id))
+ {
+ LOG_PRINT_L2("Encrypting payment id " << payment_id);
+ crypto::public_key view_key_pub = get_destination_view_key_pub(destinations, sender_account_keys);
+ if (view_key_pub == null_pkey)
+ {
+ LOG_ERROR("Destinations have to have exactly one output to support encrypted payment ids");
+ return false;
+ }
+
+ if (!encrypt_payment_id(payment_id, view_key_pub, txkey.sec))
+ {
+ LOG_ERROR("Failed to encrypt payment id");
+ return false;
+ }
+
+ std::string extra_nonce;
+ set_encrypted_payment_id_to_tx_extra_nonce(extra_nonce, payment_id);
+ remove_field_from_tx_extra(tx.extra, typeid(tx_extra_nonce));
+ if (!add_extra_nonce_to_tx_extra(tx.extra, extra_nonce))
+ {
+ LOG_ERROR("Failed to add encrypted payment id to tx extra");
+ return false;
+ }
+ LOG_PRINT_L1("Encrypted payment ID: " << payment_id);
+ }
+ }
+ }
+ else
+ {
+ LOG_ERROR("Failed to parse tx extra");
+ return false;
+ }
+
+ struct input_generation_context_data
+ {
+ keypair in_ephemeral;
+ };
+ std::vector<input_generation_context_data> in_contexts;
+
+ uint64_t summary_inputs_money = 0;
+ //fill inputs
+ int idx = -1;
+ for(const tx_source_entry& src_entr: sources)
+ {
+ ++idx;
+ if(src_entr.real_output >= src_entr.outputs.size())
+ {
+ LOG_ERROR("real_output index (" << src_entr.real_output << ")bigger than output_keys.size()=" << src_entr.outputs.size());
+ return false;
+ }
+ summary_inputs_money += src_entr.amount;
+
+ //key_derivation recv_derivation;
+ in_contexts.push_back(input_generation_context_data());
+ keypair& in_ephemeral = in_contexts.back().in_ephemeral;
+ crypto::key_image img;
+ if(!generate_key_image_helper(sender_account_keys, src_entr.real_out_tx_key, src_entr.real_output_in_tx_index, in_ephemeral, img))
+ return false;
+
+ //check that derivated key is equal with real output key
+ if( !(in_ephemeral.pub == src_entr.outputs[src_entr.real_output].second.dest) )
+ {
+ LOG_ERROR("derived public key mismatch with output public key at index " << idx << ", real out " << src_entr.real_output << "! "<< ENDL << "derived_key:"
+ << string_tools::pod_to_hex(in_ephemeral.pub) << ENDL << "real output_public_key:"
+ << string_tools::pod_to_hex(src_entr.outputs[src_entr.real_output].second) );
+ LOG_ERROR("amount " << src_entr.amount << ", rct " << src_entr.rct);
+ LOG_ERROR("tx pubkey " << src_entr.real_out_tx_key << ", real_output_in_tx_index " << src_entr.real_output_in_tx_index);
+ return false;
+ }
+
+ //put key image into tx input
+ txin_to_key input_to_key;
+ input_to_key.amount = src_entr.amount;
+ input_to_key.k_image = img;
+
+ //fill outputs array and use relative offsets
+ for(const tx_source_entry::output_entry& out_entry: src_entr.outputs)
+ input_to_key.key_offsets.push_back(out_entry.first);
+
+ input_to_key.key_offsets = absolute_output_offsets_to_relative(input_to_key.key_offsets);
+ tx.vin.push_back(input_to_key);
+ }
+
+ // "Shuffle" outs
+ std::vector<tx_destination_entry> shuffled_dsts(destinations);
+ std::sort(shuffled_dsts.begin(), shuffled_dsts.end(), [](const tx_destination_entry& de1, const tx_destination_entry& de2) { return de1.amount < de2.amount; } );
+
+ uint64_t summary_outs_money = 0;
+ //fill outputs
+ size_t output_index = 0;
+ for(const tx_destination_entry& dst_entr: shuffled_dsts)
+ {
+ CHECK_AND_ASSERT_MES(dst_entr.amount > 0 || tx.version > 1, false, "Destination with wrong amount: " << dst_entr.amount);
+ crypto::key_derivation derivation;
+ crypto::public_key out_eph_public_key;
+ bool r = crypto::generate_key_derivation(dst_entr.addr.m_view_public_key, txkey.sec, derivation);
+ CHECK_AND_ASSERT_MES(r, false, "at creation outs: failed to generate_key_derivation(" << dst_entr.addr.m_view_public_key << ", " << txkey.sec << ")");
+
+ if (tx.version > 1)
+ {
+ crypto::secret_key scalar1;
+ crypto::derivation_to_scalar(derivation, output_index, scalar1);
+ amount_keys.push_back(rct::sk2rct(scalar1));
+ }
+ r = crypto::derive_public_key(derivation, output_index, dst_entr.addr.m_spend_public_key, out_eph_public_key);
+ CHECK_AND_ASSERT_MES(r, false, "at creation outs: failed to derive_public_key(" << derivation << ", " << output_index << ", "<< dst_entr.addr.m_spend_public_key << ")");
+
+ tx_out out;
+ out.amount = dst_entr.amount;
+ txout_to_key tk;
+ tk.key = out_eph_public_key;
+ out.target = tk;
+ tx.vout.push_back(out);
+ output_index++;
+ summary_outs_money += dst_entr.amount;
+ }
+
+ //check money
+ if(summary_outs_money > summary_inputs_money )
+ {
+ LOG_ERROR("Transaction inputs money ("<< summary_inputs_money << ") less than outputs money (" << summary_outs_money << ")");
+ return false;
+ }
+
+ // check for watch only wallet
+ bool zero_secret_key = true;
+ for (size_t i = 0; i < sizeof(sender_account_keys.m_spend_secret_key); ++i)
+ zero_secret_key &= (sender_account_keys.m_spend_secret_key.data[i] == 0);
+ if (zero_secret_key)
+ {
+ MDEBUG("Null secret key, skipping signatures");
+ }
+
+ if (tx.version == 1)
+ {
+ //generate ring signatures
+ crypto::hash tx_prefix_hash;
+ get_transaction_prefix_hash(tx, tx_prefix_hash);
+
+ std::stringstream ss_ring_s;
+ size_t i = 0;
+ for(const tx_source_entry& src_entr: sources)
+ {
+ ss_ring_s << "pub_keys:" << ENDL;
+ std::vector<const crypto::public_key*> keys_ptrs;
+ std::vector<crypto::public_key> keys(src_entr.outputs.size());
+ size_t ii = 0;
+ for(const tx_source_entry::output_entry& o: src_entr.outputs)
+ {
+ keys[ii] = rct2pk(o.second.dest);
+ keys_ptrs.push_back(&keys[ii]);
+ ss_ring_s << o.second.dest << ENDL;
+ ++ii;
+ }
+
+ tx.signatures.push_back(std::vector<crypto::signature>());
+ std::vector<crypto::signature>& sigs = tx.signatures.back();
+ sigs.resize(src_entr.outputs.size());
+ if (!zero_secret_key)
+ crypto::generate_ring_signature(tx_prefix_hash, boost::get<txin_to_key>(tx.vin[i]).k_image, keys_ptrs, in_contexts[i].in_ephemeral.sec, src_entr.real_output, sigs.data());
+ ss_ring_s << "signatures:" << ENDL;
+ std::for_each(sigs.begin(), sigs.end(), [&](const crypto::signature& s){ss_ring_s << s << ENDL;});
+ ss_ring_s << "prefix_hash:" << tx_prefix_hash << ENDL << "in_ephemeral_key: " << in_contexts[i].in_ephemeral.sec << ENDL << "real_output: " << src_entr.real_output;
+ i++;
+ }
+
+ MCINFO("construct_tx", "transaction_created: " << get_transaction_hash(tx) << ENDL << obj_to_json_str(tx) << ENDL << ss_ring_s.str());
+ }
+ else
+ {
+ size_t n_total_outs = sources[0].outputs.size(); // only for non-simple rct
+
+ // the non-simple version is slightly smaller, but assumes all real inputs
+ // are on the same index, so can only be used if there just one ring.
+ bool use_simple_rct = sources.size() > 1;
+
+ if (!use_simple_rct)
+ {
+ // non simple ringct requires all real inputs to be at the same index for all inputs
+ for(const tx_source_entry& src_entr: sources)
+ {
+ if(src_entr.real_output != sources.begin()->real_output)
+ {
+ LOG_ERROR("All inputs must have the same index for non-simple ringct");
+ return false;
+ }
+ }
+
+ // enforce same mixin for all outputs
+ for (size_t i = 1; i < sources.size(); ++i) {
+ if (n_total_outs != sources[i].outputs.size()) {
+ LOG_ERROR("Non-simple ringct transaction has varying mixin");
+ return false;
+ }
+ }
+ }
+
+ uint64_t amount_in = 0, amount_out = 0;
+ rct::ctkeyV inSk;
+ // mixRing indexing is done the other way round for simple
+ rct::ctkeyM mixRing(use_simple_rct ? sources.size() : n_total_outs);
+ rct::keyV destinations;
+ std::vector<uint64_t> inamounts, outamounts;
+ std::vector<unsigned int> index;
+ for (size_t i = 0; i < sources.size(); ++i)
+ {
+ rct::ctkey ctkey;
+ amount_in += sources[i].amount;
+ inamounts.push_back(sources[i].amount);
+ index.push_back(sources[i].real_output);
+ // inSk: (secret key, mask)
+ ctkey.dest = rct::sk2rct(in_contexts[i].in_ephemeral.sec);
+ ctkey.mask = sources[i].mask;
+ inSk.push_back(ctkey);
+ // inPk: (public key, commitment)
+ // will be done when filling in mixRing
+ }
+ for (size_t i = 0; i < tx.vout.size(); ++i)
+ {
+ destinations.push_back(rct::pk2rct(boost::get<txout_to_key>(tx.vout[i].target).key));
+ outamounts.push_back(tx.vout[i].amount);
+ amount_out += tx.vout[i].amount;
+ }
+
+ if (use_simple_rct)
+ {
+ // mixRing indexing is done the other way round for simple
+ for (size_t i = 0; i < sources.size(); ++i)
+ {
+ mixRing[i].resize(sources[i].outputs.size());
+ for (size_t n = 0; n < sources[i].outputs.size(); ++n)
+ {
+ mixRing[i][n] = sources[i].outputs[n].second;
+ }
+ }
+ }
+ else
+ {
+ for (size_t i = 0; i < n_total_outs; ++i) // same index assumption
+ {
+ mixRing[i].resize(sources.size());
+ for (size_t n = 0; n < sources.size(); ++n)
+ {
+ mixRing[i][n] = sources[n].outputs[i].second;
+ }
+ }
+ }
+
+ // fee
+ if (!use_simple_rct && amount_in > amount_out)
+ outamounts.push_back(amount_in - amount_out);
+
+ // zero out all amounts to mask rct outputs, real amounts are now encrypted
+ for (size_t i = 0; i < tx.vin.size(); ++i)
+ {
+ if (sources[i].rct)
+ boost::get<txin_to_key>(tx.vin[i]).amount = 0;
+ }
+ for (size_t i = 0; i < tx.vout.size(); ++i)
+ tx.vout[i].amount = 0;
+
+ crypto::hash tx_prefix_hash;
+ get_transaction_prefix_hash(tx, tx_prefix_hash);
+ rct::ctkeyV outSk;
+ if (use_simple_rct)
+ tx.rct_signatures = rct::genRctSimple(rct::hash2rct(tx_prefix_hash), inSk, destinations, inamounts, outamounts, amount_in - amount_out, mixRing, amount_keys, index, outSk);
+ else
+ tx.rct_signatures = rct::genRct(rct::hash2rct(tx_prefix_hash), inSk, destinations, outamounts, mixRing, amount_keys, sources[0].real_output, outSk); // same index assumption
+
+ CHECK_AND_ASSERT_MES(tx.vout.size() == outSk.size(), false, "outSk size does not match vout");
+
+ MCINFO("construct_tx", "transaction_created: " << get_transaction_hash(tx) << ENDL << obj_to_json_str(tx) << ENDL);
+ }
+
+ return true;
+ }
+ //---------------------------------------------------------------
+ bool construct_tx(const account_keys& sender_account_keys, const std::vector<tx_source_entry>& sources, const std::vector<tx_destination_entry>& destinations, std::vector<uint8_t> extra, transaction& tx, uint64_t unlock_time)
+ {
+ crypto::secret_key tx_key;
+ return construct_tx_and_get_tx_key(sender_account_keys, sources, destinations, extra, tx, unlock_time, tx_key);
+ }
+ //---------------------------------------------------------------
+ bool generate_genesis_block(
+ block& bl
+ , std::string const & genesis_tx
+ , uint32_t nonce
+ )
+ {
+ //genesis block
+ bl = boost::value_initialized<block>();
+
+
+ account_public_address ac = boost::value_initialized<account_public_address>();
+ std::vector<size_t> sz;
+ construct_miner_tx(0, 0, 0, 0, 0, ac, bl.miner_tx); // zero fee in genesis
+ blobdata txb = tx_to_blob(bl.miner_tx);
+ std::string hex_tx_represent = string_tools::buff_to_hex_nodelimer(txb);
+
+ std::string genesis_coinbase_tx_hex = config::GENESIS_TX;
+
+ blobdata tx_bl;
+ string_tools::parse_hexstr_to_binbuff(genesis_coinbase_tx_hex, tx_bl);
+ bool r = parse_and_validate_tx_from_blob(tx_bl, bl.miner_tx);
+ CHECK_AND_ASSERT_MES(r, false, "failed to parse coinbase tx from hard coded blob");
+ bl.major_version = CURRENT_BLOCK_MAJOR_VERSION;
+ bl.minor_version = CURRENT_BLOCK_MINOR_VERSION;
+ bl.timestamp = 0;
+ bl.nonce = nonce;
+ miner::find_nonce_for_given_block(bl, 1, 0);
+ return true;
+ }
+ //---------------------------------------------------------------
+}
diff --git a/src/cryptonote_core/cryptonote_tx_utils.h b/src/cryptonote_core/cryptonote_tx_utils.h
new file mode 100644
index 000000000..859318fe5
--- /dev/null
+++ b/src/cryptonote_core/cryptonote_tx_utils.h
@@ -0,0 +1,101 @@
+// Copyright (c) 2014-2016, 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
+
+#pragma once
+#include "cryptonote_basic/cryptonote_format_utils.h"
+#include <boost/serialization/vector.hpp>
+#include <boost/serialization/utility.hpp>
+
+namespace cryptonote
+{
+ //---------------------------------------------------------------
+ bool construct_miner_tx(size_t height, size_t median_size, uint64_t already_generated_coins, size_t current_block_size, uint64_t fee, const account_public_address &miner_address, transaction& tx, const blobdata& extra_nonce = blobdata(), size_t max_outs = 999, uint8_t hard_fork_version = 1);
+
+ struct tx_source_entry
+ {
+ typedef std::pair<uint64_t, rct::ctkey> output_entry;
+
+ std::vector<output_entry> outputs; //index + key + optional ringct commitment
+ size_t real_output; //index in outputs vector of real output_entry
+ crypto::public_key real_out_tx_key; //incoming real tx public key
+ size_t real_output_in_tx_index; //index in transaction outputs vector
+ uint64_t amount; //money
+ bool rct; //true if the output is rct
+ rct::key mask; //ringct amount mask
+
+ void push_output(uint64_t idx, const crypto::public_key &k, uint64_t amount) { outputs.push_back(std::make_pair(idx, rct::ctkey({rct::pk2rct(k), rct::zeroCommit(amount)}))); }
+ };
+
+ struct tx_destination_entry
+ {
+ uint64_t amount; //money
+ account_public_address addr; //destination address
+
+ tx_destination_entry() : amount(0), addr(AUTO_VAL_INIT(addr)) { }
+ tx_destination_entry(uint64_t a, const account_public_address &ad) : amount(a), addr(ad) { }
+
+ BEGIN_SERIALIZE_OBJECT()
+ VARINT_FIELD(amount)
+ FIELD(addr)
+ END_SERIALIZE()
+ };
+
+ //---------------------------------------------------------------
+ crypto::public_key get_destination_view_key_pub(const std::vector<tx_destination_entry> &destinations, const account_keys &sender_keys);
+ bool construct_tx(const account_keys& sender_account_keys, const std::vector<tx_source_entry>& sources, const std::vector<tx_destination_entry>& destinations, std::vector<uint8_t> extra, transaction& tx, uint64_t unlock_time);
+ bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::vector<tx_source_entry>& sources, const std::vector<tx_destination_entry>& destinations, std::vector<uint8_t> extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, bool rct = false);
+
+ bool generate_genesis_block(
+ block& bl
+ , std::string const & genesis_tx
+ , uint32_t nonce
+ );
+
+}
+
+BOOST_CLASS_VERSION(cryptonote::tx_source_entry, 0)
+
+namespace boost
+{
+ namespace serialization
+ {
+ template <class Archive>
+ inline void serialize(Archive &a, cryptonote::tx_source_entry &x, const boost::serialization::version_type ver)
+ {
+ a & x.outputs;
+ a & x.real_output;
+ a & x.real_out_tx_key;
+ a & x.real_output_in_tx_index;
+ a & x.amount;
+ a & x.rct;
+ a & x.mask;
+ }
+ }
+}
diff --git a/src/cryptonote_core/difficulty.cpp b/src/cryptonote_core/difficulty.cpp
deleted file mode 100644
index 1c5b9cfbd..000000000
--- a/src/cryptonote_core/difficulty.cpp
+++ /dev/null
@@ -1,165 +0,0 @@
-// Copyright (c) 2014-2016, 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 <algorithm>
-#include <cassert>
-#include <cstddef>
-#include <cstdint>
-#include <vector>
-
-#include "common/int-util.h"
-#include "crypto/hash.h"
-#include "cryptonote_config.h"
-#include "difficulty.h"
-
-#undef MONERO_DEFAULT_LOG_CATEGORY
-#define MONERO_DEFAULT_LOG_CATEGORY "difficulty"
-
-namespace cryptonote {
-
- using std::size_t;
- using std::uint64_t;
- using std::vector;
-
-#if defined(__x86_64__)
- static inline void mul(uint64_t a, uint64_t b, uint64_t &low, uint64_t &high) {
- low = mul128(a, b, &high);
- }
-
-#else
-
- static inline void mul(uint64_t a, uint64_t b, uint64_t &low, uint64_t &high) {
- // __int128 isn't part of the standard, so the previous function wasn't portable. mul128() in Windows is fine,
- // but this portable function should be used elsewhere. Credit for this function goes to latexi95.
-
- uint64_t aLow = a & 0xFFFFFFFF;
- uint64_t aHigh = a >> 32;
- uint64_t bLow = b & 0xFFFFFFFF;
- uint64_t bHigh = b >> 32;
-
- uint64_t res = aLow * bLow;
- uint64_t lowRes1 = res & 0xFFFFFFFF;
- uint64_t carry = res >> 32;
-
- res = aHigh * bLow + carry;
- uint64_t highResHigh1 = res >> 32;
- uint64_t highResLow1 = res & 0xFFFFFFFF;
-
- res = aLow * bHigh;
- uint64_t lowRes2 = res & 0xFFFFFFFF;
- carry = res >> 32;
-
- res = aHigh * bHigh + carry;
- uint64_t highResHigh2 = res >> 32;
- uint64_t highResLow2 = res & 0xFFFFFFFF;
-
- //Addition
-
- uint64_t r = highResLow1 + lowRes2;
- carry = r >> 32;
- low = (r << 32) | lowRes1;
- r = highResHigh1 + highResLow2 + carry;
- uint64_t d3 = r & 0xFFFFFFFF;
- carry = r >> 32;
- r = highResHigh2 + carry;
- high = d3 | (r << 32);
- }
-
-#endif
-
- static inline bool cadd(uint64_t a, uint64_t b) {
- return a + b < a;
- }
-
- static inline bool cadc(uint64_t a, uint64_t b, bool c) {
- return a + b < a || (c && a + b == (uint64_t) -1);
- }
-
- bool check_hash(const crypto::hash &hash, difficulty_type difficulty) {
- uint64_t low, high, top, cur;
- // First check the highest word, this will most likely fail for a random hash.
- mul(swap64le(((const uint64_t *) &hash)[3]), difficulty, top, high);
- if (high != 0) {
- return false;
- }
- mul(swap64le(((const uint64_t *) &hash)[0]), difficulty, low, cur);
- mul(swap64le(((const uint64_t *) &hash)[1]), difficulty, low, high);
- bool carry = cadd(cur, low);
- cur = high;
- mul(swap64le(((const uint64_t *) &hash)[2]), difficulty, low, high);
- carry = cadc(cur, low, carry);
- carry = cadc(high, top, carry);
- return !carry;
- }
-
- difficulty_type next_difficulty(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, size_t target_seconds) {
-
- if(timestamps.size() > DIFFICULTY_WINDOW)
- {
- timestamps.resize(DIFFICULTY_WINDOW);
- cumulative_difficulties.resize(DIFFICULTY_WINDOW);
- }
-
-
- size_t length = timestamps.size();
- assert(length == cumulative_difficulties.size());
- if (length <= 1) {
- return 1;
- }
- static_assert(DIFFICULTY_WINDOW >= 2, "Window is too small");
- assert(length <= DIFFICULTY_WINDOW);
- sort(timestamps.begin(), timestamps.end());
- size_t cut_begin, cut_end;
- static_assert(2 * DIFFICULTY_CUT <= DIFFICULTY_WINDOW - 2, "Cut length is too large");
- if (length <= DIFFICULTY_WINDOW - 2 * DIFFICULTY_CUT) {
- cut_begin = 0;
- cut_end = length;
- } else {
- cut_begin = (length - (DIFFICULTY_WINDOW - 2 * DIFFICULTY_CUT) + 1) / 2;
- cut_end = cut_begin + (DIFFICULTY_WINDOW - 2 * DIFFICULTY_CUT);
- }
- assert(/*cut_begin >= 0 &&*/ cut_begin + 2 <= cut_end && cut_end <= length);
- uint64_t time_span = timestamps[cut_end - 1] - timestamps[cut_begin];
- if (time_span == 0) {
- time_span = 1;
- }
- difficulty_type total_work = cumulative_difficulties[cut_end - 1] - cumulative_difficulties[cut_begin];
- assert(total_work > 0);
- uint64_t low, high;
- mul(total_work, target_seconds, low, high);
- // blockchain errors "difficulty overhead" if this function returns zero.
- // TODO: consider throwing an exception instead
- if (high != 0 || low + time_span - 1 < low) {
- return 0;
- }
- return (low + time_span - 1) / time_span;
- }
-
-}
diff --git a/src/cryptonote_core/difficulty.h b/src/cryptonote_core/difficulty.h
deleted file mode 100644
index 910f97035..000000000
--- a/src/cryptonote_core/difficulty.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright (c) 2014-2016, 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
-
-#pragma once
-
-#include <cstdint>
-#include <vector>
-
-#include "crypto/hash.h"
-
-namespace cryptonote
-{
- typedef std::uint64_t difficulty_type;
-
- /**
- * @brief checks if a hash fits the given difficulty
- *
- * The hash passes if (hash * difficulty) < 2^192.
- * Phrased differently, if (hash * difficulty) fits without overflow into
- * the least significant 192 bits of the 256 bit multiplication result.
- *
- * @param hash the hash to check
- * @param difficulty the difficulty to check against
- *
- * @return true if valid, else false
- */
- bool check_hash(const crypto::hash &hash, difficulty_type difficulty);
- difficulty_type next_difficulty(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, size_t target_seconds);
-}
diff --git a/src/cryptonote_core/hardfork.cpp b/src/cryptonote_core/hardfork.cpp
deleted file mode 100644
index 13d7d717d..000000000
--- a/src/cryptonote_core/hardfork.cpp
+++ /dev/null
@@ -1,416 +0,0 @@
-// Copyright (c) 2014-2016, 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.
-
-#include <algorithm>
-#include <cstdio>
-
-#include "cryptonote_core/cryptonote_basic.h"
-#include "blockchain_db/blockchain_db.h"
-#include "hardfork.h"
-
-#undef MONERO_DEFAULT_LOG_CATEGORY
-#define MONERO_DEFAULT_LOG_CATEGORY "hardfork"
-
-using namespace cryptonote;
-
-static uint8_t get_block_vote(const cryptonote::block &b)
-{
- // Pre-hardfork blocks have a minor version hardcoded to 0.
- // For the purposes of voting, we consider 0 to refer to
- // version number 1, which is what all blocks from the genesis
- // block are. It makes things simpler.
- if (b.minor_version == 0)
- return 1;
- return b.minor_version;
-}
-
-static uint8_t get_block_version(const cryptonote::block &b)
-{
- return b.major_version;
-}
-
-HardFork::HardFork(cryptonote::BlockchainDB &db, uint8_t original_version, uint64_t original_version_till_height, time_t forked_time, time_t update_time, uint64_t window_size, uint8_t default_threshold_percent):
- db(db),
- original_version(original_version),
- original_version_till_height(original_version_till_height),
- forked_time(forked_time),
- update_time(update_time),
- window_size(window_size),
- default_threshold_percent(default_threshold_percent)
-{
- if (window_size == 0)
- throw "window_size needs to be strictly positive";
- if (default_threshold_percent > 100)
- throw "default_threshold_percent needs to be between 0 and 100";
-}
-
-bool HardFork::add_fork(uint8_t version, uint64_t height, uint8_t threshold, time_t time)
-{
- CRITICAL_REGION_LOCAL(lock);
-
- // add in order
- if (version == 0)
- return false;
- if (!heights.empty()) {
- if (version <= heights.back().version)
- return false;
- if (height <= heights.back().height)
- return false;
- if (time <= heights.back().time)
- return false;
- }
- if (threshold > 100)
- return false;
- heights.push_back(Params(version, height, threshold, time));
- return true;
-}
-
-bool HardFork::add_fork(uint8_t version, uint64_t height, time_t time)
-{
- return add_fork(version, height, default_threshold_percent, time);
-}
-
-uint8_t HardFork::get_effective_version(uint8_t voting_version) const
-{
- if (!heights.empty()) {
- uint8_t max_version = heights.back().version;
- if (voting_version > max_version)
- voting_version = max_version;
- }
- return voting_version;
-}
-
-bool HardFork::do_check(uint8_t block_version, uint8_t voting_version) const
-{
- return block_version == heights[current_fork_index].version
- && voting_version >= heights[current_fork_index].version;
-}
-
-bool HardFork::check(const cryptonote::block &block) const
-{
- CRITICAL_REGION_LOCAL(lock);
- return do_check(::get_block_version(block), ::get_block_vote(block));
-}
-
-bool HardFork::do_check_for_height(uint8_t block_version, uint8_t voting_version, uint64_t height) const
-{
- int fork_index = get_voted_fork_index(height);
- return block_version == heights[fork_index].version
- && voting_version >= heights[fork_index].version;
-}
-
-bool HardFork::check_for_height(const cryptonote::block &block, uint64_t height) const
-{
- CRITICAL_REGION_LOCAL(lock);
- return do_check_for_height(::get_block_version(block), ::get_block_vote(block), height);
-}
-
-bool HardFork::add(uint8_t block_version, uint8_t voting_version, uint64_t height)
-{
- CRITICAL_REGION_LOCAL(lock);
-
- if (!do_check(block_version, voting_version))
- return false;
-
- db.set_hard_fork_version(height, heights[current_fork_index].version);
-
- voting_version = get_effective_version(voting_version);
-
- while (versions.size() >= window_size) {
- const uint8_t old_version = versions.front();
- assert(last_versions[old_version] >= 1);
- last_versions[old_version]--;
- versions.pop_front();
- }
-
- last_versions[voting_version]++;
- versions.push_back(voting_version);
-
- uint8_t voted = get_voted_fork_index(height + 1);
- if (voted > current_fork_index) {
- current_fork_index = voted;
- }
-
- return true;
-}
-
-bool HardFork::add(const cryptonote::block &block, uint64_t height)
-{
- return add(::get_block_version(block), ::get_block_vote(block), height);
-}
-
-void HardFork::init()
-{
- CRITICAL_REGION_LOCAL(lock);
-
- // add a placeholder for the default version, to avoid special cases
- if (heights.empty())
- heights.push_back(Params(original_version, 0, 0, 0));
-
- versions.clear();
- for (size_t n = 0; n < 256; ++n)
- last_versions[n] = 0;
- current_fork_index = 0;
-
- // restore state from DB
- uint64_t height = db.height();
- if (height > window_size)
- height -= window_size - 1;
- else
- height = 1;
-
- bool populate = false;
- try
- {
- db.get_hard_fork_version(0);
- }
- catch (...) { populate = true; }
- if (populate) {
- LOG_PRINT_L0("The DB has no hard fork info, reparsing from start");
- height = 1;
- }
- LOG_PRINT_L1("reorganizing from " << height);
- if (populate) {
- reorganize_from_chain_height(height);
- // reorg will not touch the genesis block, use this as a flag for populating done
- db.set_hard_fork_version(0, original_version);
- }
- else {
- rescan_from_chain_height(height);
- }
- LOG_PRINT_L1("reorganization done");
-}
-
-uint8_t HardFork::get_block_version(uint64_t height) const
-{
- if (height <= original_version_till_height)
- return original_version;
-
- const cryptonote::block &block = db.get_block_from_height(height);
- return ::get_block_version(block);
-}
-
-bool HardFork::reorganize_from_block_height(uint64_t height)
-{
- CRITICAL_REGION_LOCAL(lock);
- if (height >= db.height())
- return false;
-
- db.set_batch_transactions(true);
- db.batch_start();
-
- versions.clear();
-
- for (size_t n = 0; n < 256; ++n)
- 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 (current_fork_index > 0 && heights[current_fork_index].version > start_version) {
- --current_fork_index;
- }
- for (uint64_t h = rescan_height; h <= height; ++h) {
- cryptonote::block b = db.get_block_from_height(h);
- const uint8_t v = get_effective_version(get_block_vote(b));
- last_versions[v]++;
- versions.push_back(v);
- }
-
- uint8_t voted = get_voted_fork_index(height + 1);
- if (voted > current_fork_index) {
- current_fork_index = voted;
- }
-
- const uint64_t bc_height = db.height();
- for (uint64_t h = height + 1; h < bc_height; ++h) {
- add(db.get_block_from_height(h), h);
- }
-
- db.batch_stop();
-
- return true;
-}
-
-bool HardFork::reorganize_from_chain_height(uint64_t height)
-{
- if (height == 0)
- return false;
- return reorganize_from_block_height(height - 1);
-}
-
-bool HardFork::rescan_from_block_height(uint64_t height)
-{
- CRITICAL_REGION_LOCAL(lock);
- db.block_txn_start(true);
- if (height >= db.height()) {
- db.block_txn_stop();
- return false;
- }
-
- versions.clear();
-
- for (size_t n = 0; n < 256; ++n)
- last_versions[n] = 0;
- for (uint64_t h = height; h < db.height(); ++h) {
- cryptonote::block b = db.get_block_from_height(h);
- const uint8_t v = get_effective_version(get_block_vote(b));
- last_versions[v]++;
- versions.push_back(v);
- }
-
- uint8_t lastv = db.get_hard_fork_version(db.height() - 1);
- current_fork_index = 0;
- while (current_fork_index + 1 < heights.size() && heights[current_fork_index].version != lastv)
- ++current_fork_index;
-
- uint8_t voted = get_voted_fork_index(db.height());
- if (voted > current_fork_index) {
- current_fork_index = voted;
- }
-
- db.block_txn_stop();
-
- return true;
-}
-
-bool HardFork::rescan_from_chain_height(uint64_t height)
-{
- if (height == 0)
- return false;
- return rescan_from_block_height(height - 1);
-}
-
-int HardFork::get_voted_fork_index(uint64_t height) const
-{
- CRITICAL_REGION_LOCAL(lock);
- uint32_t accumulated_votes = 0;
- for (unsigned int n = heights.size() - 1; n > current_fork_index; --n) {
- uint8_t v = heights[n].version;
- accumulated_votes += last_versions[v];
- uint32_t threshold = (window_size * heights[n].threshold + 99) / 100;
- if (height >= heights[n].height && accumulated_votes >= threshold) {
- return n;
- }
- }
- return current_fork_index;
-}
-
-HardFork::State HardFork::get_state(time_t t) const
-{
- CRITICAL_REGION_LOCAL(lock);
-
- // no hard forks setup yet
- if (heights.size() <= 1)
- return Ready;
-
- time_t t_last_fork = heights.back().time;
- if (t >= t_last_fork + forked_time)
- return LikelyForked;
- if (t >= t_last_fork + update_time)
- return UpdateNeeded;
- return Ready;
-}
-
-HardFork::State HardFork::get_state() const
-{
- return get_state(time(NULL));
-}
-
-uint8_t HardFork::get(uint64_t height) const
-{
- CRITICAL_REGION_LOCAL(lock);
- if (height > db.height()) {
- assert(false);
- return 255;
- }
- if (height == db.height()) {
- return get_current_version();
- }
- return db.get_hard_fork_version(height);
-}
-
-uint8_t HardFork::get_current_version() const
-{
- CRITICAL_REGION_LOCAL(lock);
- return heights[current_fork_index].version;
-}
-
-uint8_t HardFork::get_ideal_version() const
-{
- CRITICAL_REGION_LOCAL(lock);
- return heights.back().version;
-}
-
-uint8_t HardFork::get_ideal_version(uint64_t height) const
-{
- CRITICAL_REGION_LOCAL(lock);
- for (unsigned int n = heights.size() - 1; n > 0; --n) {
- if (height >= heights[n].height) {
- return heights[n].version;
- }
- }
- return original_version;
-}
-
-uint64_t HardFork::get_earliest_ideal_height_for_version(uint8_t version) const
-{
- for (unsigned int n = heights.size() - 1; n > 0; --n) {
- if (heights[n].version <= version)
- return heights[n].height;
- }
- return 0;
-}
-
-uint8_t HardFork::get_next_version() const
-{
- CRITICAL_REGION_LOCAL(lock);
- uint64_t height = db.height();
- for (unsigned int n = heights.size() - 1; n > 0; --n) {
- if (height >= heights[n].height) {
- return heights[n < heights.size() - 1 ? n + 1 : n].version;
- }
- }
- return original_version;
-}
-
-bool HardFork::get_voting_info(uint8_t version, uint32_t &window, uint32_t &votes, uint32_t &threshold, uint64_t &earliest_height, uint8_t &voting) const
-{
- CRITICAL_REGION_LOCAL(lock);
-
- const uint8_t current_version = heights[current_fork_index].version;
- const bool enabled = current_version >= version;
- window = versions.size();
- votes = 0;
- for (size_t n = version; n < 256; ++n)
- votes += last_versions[n];
- threshold = (window * heights[current_fork_index].threshold + 99) / 100;
- //assert((votes >= threshold) == enabled);
- earliest_height = get_earliest_ideal_height_for_version(version);
- voting = heights.back().version;
- return enabled;
-}
-
diff --git a/src/cryptonote_core/hardfork.h b/src/cryptonote_core/hardfork.h
deleted file mode 100644
index 8d2edfa2a..000000000
--- a/src/cryptonote_core/hardfork.h
+++ /dev/null
@@ -1,265 +0,0 @@
-// Copyright (c) 2014-2016, 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.
-
-#pragma once
-
-#include "syncobj.h"
-#include "cryptonote_core/cryptonote_basic.h"
-
-namespace cryptonote
-{
- class BlockchainDB;
-
- class HardFork
- {
- public:
- typedef enum {
- LikelyForked,
- UpdateNeeded,
- Ready,
- } State;
-
- static const uint64_t DEFAULT_ORIGINAL_VERSION_TILL_HEIGHT = 0; // <= actual height
- static const time_t DEFAULT_FORKED_TIME = 31557600; // a year in seconds
- static const time_t DEFAULT_UPDATE_TIME = 31557600 / 2;
- static const uint64_t DEFAULT_WINDOW_SIZE = 10080; // supermajority window check length - a week
- static const uint8_t DEFAULT_THRESHOLD_PERCENT = 80;
-
- /**
- * @brief creates a new HardFork object
- *
- * @param original_version the block version for blocks 0 through to the first fork
- * @param forked_time the time in seconds before thinking we're forked
- * @param update_time the time in seconds before thinking we need to update
- * @param window_size the size of the window in blocks to consider for version voting
- * @param default_threshold_percent the size of the majority in percents
- */
- HardFork(cryptonote::BlockchainDB &db, uint8_t original_version = 1, uint64_t original_version_till_height = DEFAULT_ORIGINAL_VERSION_TILL_HEIGHT, time_t forked_time = DEFAULT_FORKED_TIME, time_t update_time = DEFAULT_UPDATE_TIME, uint64_t window_size = DEFAULT_WINDOW_SIZE, uint8_t default_threshold_percent = DEFAULT_THRESHOLD_PERCENT);
-
- /**
- * @brief add a new hardfork height
- *
- * returns true if no error, false otherwise
- *
- * @param version the major block version for the fork
- * @param height The height the hardfork takes effect
- * @param threshold The threshold of votes needed for this fork (0-100)
- * @param time Approximate time of the hardfork (seconds since epoch)
- */
- bool add_fork(uint8_t version, uint64_t height, uint8_t threshold, time_t time);
-
- /**
- * @brief add a new hardfork height
- *
- * returns true if no error, false otherwise
- *
- * @param version the major block version for the fork
- * @param voting_version the minor block version for the fork, used for voting
- * @param height The height the hardfork takes effect
- * @param time Approximate time of the hardfork (seconds since epoch)
- */
- bool add_fork(uint8_t version, uint64_t height, time_t time);
-
- /**
- * @brief initialize the object
- *
- * Must be done after adding all the required hardforks via add above
- */
- void init();
-
- /**
- * @brief check whether a new block would be accepted
- *
- * returns true if the block is accepted, false otherwise
- *
- * @param block the new block
- *
- * This check is made by add. It is exposed publicly to allow
- * the caller to inexpensively check whether a block would be
- * accepted or rejected by its version number. Indeed, if this
- * check could only be done as part of add, the caller would
- * either have to add the block to the blockchain first, then
- * call add, then have to pop the block from the blockchain if
- * its version did not satisfy the hard fork requirements, or
- * call add first, then, if the hard fork requirements are met,
- * add the block to the blockchain, upon which a failure (the
- * block being invalid, double spending, etc) would cause the
- * hardfork object to reorganize.
- */
- bool check(const cryptonote::block &block) const;
-
- /**
- * @brief same as check, but for a particular height, rather than the top
- *
- * NOTE: this does not play well with voting, and relies on voting to be
- * disabled (that is, forks happen on the scheduled date, whether or not
- * enough blocks have voted for the fork).
- *
- * returns true if no error, false otherwise
- *
- * @param block the new block
- * @param height which height to check for
- */
- bool check_for_height(const cryptonote::block &block, uint64_t height) const;
-
- /**
- * @brief add a new block
- *
- * returns true if no error, false otherwise
- *
- * @param block the new block
- */
- bool add(const cryptonote::block &block, uint64_t height);
-
- /**
- * @brief called when the blockchain is reorganized
- *
- * This will rescan the blockchain to determine which hard forks
- * have been triggered
- *
- * returns true if no error, false otherwise
- *
- * @param blockchain the blockchain
- * @param height of the last block kept from the previous blockchain
- */
- bool reorganize_from_block_height(uint64_t height);
- bool reorganize_from_chain_height(uint64_t height);
-
- /**
- * @brief returns current state at the given time
- *
- * Based on the approximate time of the last known hard fork,
- * estimate whether we need to update, or if we're way behind
- *
- * @param t the time to consider
- */
- State get_state(time_t t) const;
- State get_state() const;
-
- /**
- * @brief returns the hard fork version for the given block height
- *
- * @param height height of the block to check
- */
- uint8_t get(uint64_t height) const;
-
- /**
- * @brief returns the latest "ideal" version
- *
- * This is the latest version that's been scheduled
- */
- uint8_t get_ideal_version() const;
-
- /**
- * @brief returns the "ideal" version for a given height
- *
- * @param height height of the block to check
- */
- uint8_t get_ideal_version(uint64_t height) const;
-
- /**
- * @brief returns the next version
- *
- * This is the version which will we fork to next
- */
- uint8_t get_next_version() const;
-
- /**
- * @brief returns the current version
- *
- * This is the latest version that's past its trigger date and had enough votes
- * at one point in the past.
- */
- uint8_t get_current_version() const;
-
- /**
- * @brief returns the earliest block a given version may activate
- */
- uint64_t get_earliest_ideal_height_for_version(uint8_t version) const;
-
- /**
- * @brief returns information about current voting state
- *
- * returns true if the given version is enabled (ie, the current version
- * is at least the passed version), false otherwise
- *
- * @param version the version to check voting for
- * @param window the number of blocks considered in voting
- * @param votes number of votes for next version
- * @param threshold number of votes needed to switch to next version
- * @param earliest_height earliest height at which the version can take effect
- */
- bool get_voting_info(uint8_t version, uint32_t &window, uint32_t &votes, uint32_t &threshold, uint64_t &earliest_height, uint8_t &voting) const;
-
- /**
- * @brief returns the size of the voting window in blocks
- */
- uint64_t get_window_size() const { return window_size; }
-
- private:
-
- uint8_t get_block_version(uint64_t height) const;
- bool do_check(uint8_t block_version, uint8_t voting_version) const;
- bool do_check_for_height(uint8_t block_version, uint8_t voting_version, uint64_t height) const;
- int get_voted_fork_index(uint64_t height) const;
- uint8_t get_effective_version(uint8_t voting_version) const;
- bool add(uint8_t block_version, uint8_t voting_version, uint64_t height);
-
- bool rescan_from_block_height(uint64_t height);
- bool rescan_from_chain_height(uint64_t height);
-
- private:
-
- BlockchainDB &db;
-
- time_t forked_time;
- time_t update_time;
- uint64_t window_size;
- uint8_t default_threshold_percent;
-
- uint8_t original_version;
- uint64_t original_version_till_height;
-
- struct Params {
- uint8_t version;
- uint8_t threshold;
- uint64_t height;
- time_t time;
- Params(uint8_t version, uint64_t height, uint8_t threshold, time_t time): version(version), threshold(threshold), height(height), time(time) {}
- };
- std::vector<Params> heights;
-
- std::deque<uint8_t> versions; /* rolling window of the last N blocks' versions */
- unsigned int last_versions[256]; /* count of the block versions in the last N blocks */
- uint32_t current_fork_index;
-
- mutable epee::critical_section lock;
- };
-
-} // namespace cryptonote
-
diff --git a/src/cryptonote_core/miner.cpp b/src/cryptonote_core/miner.cpp
deleted file mode 100644
index 88c631f80..000000000
--- a/src/cryptonote_core/miner.cpp
+++ /dev/null
@@ -1,414 +0,0 @@
-// Copyright (c) 2014-2016, 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 <sstream>
-#include <numeric>
-#include <boost/utility/value_init.hpp>
-#include <boost/interprocess/detail/atomic.hpp>
-#include <boost/limits.hpp>
-#include "misc_language.h"
-#include "include_base_utils.h"
-#include "cryptonote_basic_impl.h"
-#include "cryptonote_format_utils.h"
-#include "file_io_utils.h"
-#include "common/command_line.h"
-#include "string_coding.h"
-#include "storages/portable_storage_template_helper.h"
-
-#undef MONERO_DEFAULT_LOG_CATEGORY
-#define MONERO_DEFAULT_LOG_CATEGORY "miner"
-
-using namespace epee;
-
-#include "miner.h"
-
-
-extern "C" void slow_hash_allocate_state();
-extern "C" void slow_hash_free_state();
-namespace cryptonote
-{
-
- namespace
- {
- const command_line::arg_descriptor<std::string> arg_extra_messages = {"extra-messages-file", "Specify file for extra messages to include into coinbase transactions", "", true};
- const command_line::arg_descriptor<std::string> arg_start_mining = {"start-mining", "Specify wallet address to mining for", "", true};
- const command_line::arg_descriptor<uint32_t> arg_mining_threads = {"mining-threads", "Specify mining threads count", 0, true};
- }
-
-
- miner::miner(i_miner_handler* phandler):m_stop(1),
- m_template(boost::value_initialized<block>()),
- m_template_no(0),
- m_diffic(0),
- m_thread_index(0),
- m_phandler(phandler),
- m_height(0),
- m_pausers_count(0),
- m_threads_total(0),
- m_starter_nonce(0),
- m_last_hr_merge_time(0),
- m_hashes(0),
- m_do_print_hashrate(false),
- m_do_mining(false),
- m_current_hash_rate(0)
- {
-
- }
- //-----------------------------------------------------------------------------------------------------
- miner::~miner()
- {
- stop();
- }
- //-----------------------------------------------------------------------------------------------------
- bool miner::set_block_template(const block& bl, const difficulty_type& di, uint64_t height)
- {
- CRITICAL_REGION_LOCAL(m_template_lock);
- m_template = bl;
- m_diffic = di;
- m_height = height;
- ++m_template_no;
- m_starter_nonce = crypto::rand<uint32_t>();
- return true;
- }
- //-----------------------------------------------------------------------------------------------------
- bool miner::on_block_chain_update()
- {
- if(!is_mining())
- return true;
-
- return request_block_template();
- }
- //-----------------------------------------------------------------------------------------------------
- bool miner::request_block_template()
- {
- block bl = AUTO_VAL_INIT(bl);
- difficulty_type di = AUTO_VAL_INIT(di);
- uint64_t height = AUTO_VAL_INIT(height);
- cryptonote::blobdata extra_nonce;
- if(m_extra_messages.size() && m_config.current_extra_message_index < m_extra_messages.size())
- {
- extra_nonce = m_extra_messages[m_config.current_extra_message_index];
- }
-
- if(!m_phandler->get_block_template(bl, m_mine_address, di, height, extra_nonce))
- {
- LOG_ERROR("Failed to get_block_template(), stopping mining");
- return false;
- }
- set_block_template(bl, di, height);
- return true;
- }
- //-----------------------------------------------------------------------------------------------------
- bool miner::on_idle()
- {
- m_update_block_template_interval.do_call([&](){
- if(is_mining())request_block_template();
- return true;
- });
-
- m_update_merge_hr_interval.do_call([&](){
- merge_hr();
- return true;
- });
-
- return true;
- }
- //-----------------------------------------------------------------------------------------------------
- void miner::do_print_hashrate(bool do_hr)
- {
- m_do_print_hashrate = do_hr;
- }
- //-----------------------------------------------------------------------------------------------------
- void miner::merge_hr()
- {
- if(m_last_hr_merge_time && is_mining())
- {
- m_current_hash_rate = m_hashes * 1000 / ((misc_utils::get_tick_count() - m_last_hr_merge_time + 1));
- CRITICAL_REGION_LOCAL(m_last_hash_rates_lock);
- m_last_hash_rates.push_back(m_current_hash_rate);
- if(m_last_hash_rates.size() > 19)
- m_last_hash_rates.pop_front();
- if(m_do_print_hashrate)
- {
- uint64_t total_hr = std::accumulate(m_last_hash_rates.begin(), m_last_hash_rates.end(), 0);
- float hr = static_cast<float>(total_hr)/static_cast<float>(m_last_hash_rates.size());
- std::cout << "hashrate: " << std::setprecision(4) << std::fixed << hr << ENDL;
- }
- }
- m_last_hr_merge_time = misc_utils::get_tick_count();
- m_hashes = 0;
- }
- //-----------------------------------------------------------------------------------------------------
- void miner::init_options(boost::program_options::options_description& desc)
- {
- command_line::add_arg(desc, arg_extra_messages);
- command_line::add_arg(desc, arg_start_mining);
- command_line::add_arg(desc, arg_mining_threads);
- }
- //-----------------------------------------------------------------------------------------------------
- bool miner::init(const boost::program_options::variables_map& vm, bool testnet)
- {
- if(command_line::has_arg(vm, arg_extra_messages))
- {
- std::string buff;
- bool r = file_io_utils::load_file_to_string(command_line::get_arg(vm, arg_extra_messages), buff);
- CHECK_AND_ASSERT_MES(r, false, "Failed to load file with extra messages: " << command_line::get_arg(vm, arg_extra_messages));
- std::vector<std::string> extra_vec;
- boost::split(extra_vec, buff, boost::is_any_of("\n"), boost::token_compress_on );
- m_extra_messages.resize(extra_vec.size());
- for(size_t i = 0; i != extra_vec.size(); i++)
- {
- string_tools::trim(extra_vec[i]);
- if(!extra_vec[i].size())
- continue;
- std::string buff = string_encoding::base64_decode(extra_vec[i]);
- if(buff != "0")
- m_extra_messages[i] = buff;
- }
- m_config_folder_path = boost::filesystem::path(command_line::get_arg(vm, arg_extra_messages)).parent_path().string();
- m_config = AUTO_VAL_INIT(m_config);
- epee::serialization::load_t_from_json_file(m_config, m_config_folder_path + "/" + MINER_CONFIG_FILE_NAME);
- MINFO("Loaded " << m_extra_messages.size() << " extra messages, current index " << m_config.current_extra_message_index);
- }
-
- if(command_line::has_arg(vm, arg_start_mining))
- {
- if(!cryptonote::get_account_address_from_str(m_mine_address, testnet, command_line::get_arg(vm, arg_start_mining)))
- {
- LOG_ERROR("Target account address " << command_line::get_arg(vm, arg_start_mining) << " has wrong format, starting daemon canceled");
- return false;
- }
- m_threads_total = 1;
- m_do_mining = true;
- if(command_line::has_arg(vm, arg_mining_threads))
- {
- m_threads_total = command_line::get_arg(vm, arg_mining_threads);
- }
- }
-
- return true;
- }
- //-----------------------------------------------------------------------------------------------------
- bool miner::is_mining() const
- {
- return !m_stop;
- }
- //-----------------------------------------------------------------------------------------------------
- const account_public_address& miner::get_mining_address() const
- {
- return m_mine_address;
- }
- //-----------------------------------------------------------------------------------------------------
- uint32_t miner::get_threads_count() const {
- return m_threads_total;
- }
- //-----------------------------------------------------------------------------------------------------
- bool miner::start(const account_public_address& adr, size_t threads_count, const boost::thread::attributes& attrs)
- {
- m_mine_address = adr;
- m_threads_total = static_cast<uint32_t>(threads_count);
- m_starter_nonce = crypto::rand<uint32_t>();
- CRITICAL_REGION_LOCAL(m_threads_lock);
- if(is_mining())
- {
- LOG_ERROR("Starting miner but it's already started");
- return false;
- }
-
- if(!m_threads.empty())
- {
- LOG_ERROR("Unable to start miner because there are active mining threads");
- return false;
- }
-
- if(!m_template_no)
- request_block_template();//lets update block template
-
- boost::interprocess::ipcdetail::atomic_write32(&m_stop, 0);
- boost::interprocess::ipcdetail::atomic_write32(&m_thread_index, 0);
-
- for(size_t i = 0; i != threads_count; i++)
- {
- m_threads.push_back(boost::thread(attrs, boost::bind(&miner::worker_thread, this)));
- }
-
- LOG_PRINT_L0("Mining has started with " << threads_count << " threads, good luck!" );
- return true;
- }
- //-----------------------------------------------------------------------------------------------------
- uint64_t miner::get_speed() const
- {
- if(is_mining()) {
- return m_current_hash_rate;
- }
- else {
- return 0;
- }
- }
- //-----------------------------------------------------------------------------------------------------
- void miner::send_stop_signal()
- {
- boost::interprocess::ipcdetail::atomic_write32(&m_stop, 1);
- }
- //-----------------------------------------------------------------------------------------------------
- bool miner::stop()
- {
- MTRACE("Miner has received stop signal");
-
- if (!is_mining())
- {
- MDEBUG("Not mining - nothing to stop" );
- return true;
- }
-
- send_stop_signal();
- CRITICAL_REGION_LOCAL(m_threads_lock);
-
- for(boost::thread& th: m_threads)
- th.join();
-
- MINFO("Mining has been stopped, " << m_threads.size() << " finished" );
- m_threads.clear();
- return true;
- }
- //-----------------------------------------------------------------------------------------------------
- bool miner::find_nonce_for_given_block(block& bl, const difficulty_type& diffic, uint64_t height)
- {
- for(; bl.nonce != std::numeric_limits<uint32_t>::max(); bl.nonce++)
- {
- crypto::hash h;
- get_block_longhash(bl, h, height);
-
- if(check_hash(h, diffic))
- {
- return true;
- }
- }
- return false;
- }
- //-----------------------------------------------------------------------------------------------------
- void miner::on_synchronized()
- {
- if(m_do_mining)
- {
- boost::thread::attributes attrs;
- attrs.set_stack_size(THREAD_STACK_SIZE);
-
- start(m_mine_address, m_threads_total, attrs);
- }
- }
- //-----------------------------------------------------------------------------------------------------
- void miner::pause()
- {
- CRITICAL_REGION_LOCAL(m_miners_count_lock);
- ++m_pausers_count;
- if(m_pausers_count == 1 && is_mining())
- MDEBUG("MINING PAUSED");
- }
- //-----------------------------------------------------------------------------------------------------
- void miner::resume()
- {
- CRITICAL_REGION_LOCAL(m_miners_count_lock);
- --m_pausers_count;
- if(m_pausers_count < 0)
- {
- m_pausers_count = 0;
- MERROR("Unexpected miner::resume() called");
- }
- if(!m_pausers_count && is_mining())
- MDEBUG("MINING RESUMED");
- }
- //-----------------------------------------------------------------------------------------------------
- bool miner::worker_thread()
- {
- uint32_t th_local_index = boost::interprocess::ipcdetail::atomic_inc32(&m_thread_index);
- MGINFO("Miner thread was started ["<< th_local_index << "]");
- MLOG_SET_THREAD_NAME(std::string("[miner ") + std::to_string(th_local_index) + "]");
- uint32_t nonce = m_starter_nonce + th_local_index;
- uint64_t height = 0;
- difficulty_type local_diff = 0;
- uint32_t local_template_ver = 0;
- block b;
- slow_hash_allocate_state();
- while(!m_stop)
- {
- if(m_pausers_count)//anti split workaround
- {
- misc_utils::sleep_no_w(100);
- continue;
- }
-
- if(local_template_ver != m_template_no)
- {
- CRITICAL_REGION_BEGIN(m_template_lock);
- b = m_template;
- local_diff = m_diffic;
- height = m_height;
- CRITICAL_REGION_END();
- local_template_ver = m_template_no;
- nonce = m_starter_nonce + th_local_index;
- }
-
- if(!local_template_ver)//no any set_block_template call
- {
- LOG_PRINT_L2("Block template not set yet");
- epee::misc_utils::sleep_no_w(1000);
- continue;
- }
-
- b.nonce = nonce;
- crypto::hash h;
- get_block_longhash(b, h, height);
-
- if(check_hash(h, local_diff))
- {
- //we lucky!
- ++m_config.current_extra_message_index;
- MGINFO_GREEN("Found block for difficulty: " << local_diff);
- if(!m_phandler->handle_block_found(b))
- {
- --m_config.current_extra_message_index;
- }else
- {
- //success update, lets update config
- if (!m_config_folder_path.empty())
- epee::serialization::store_t_to_json_file(m_config, m_config_folder_path + "/" + MINER_CONFIG_FILE_NAME);
- }
- }
- nonce+=m_threads_total;
- ++m_hashes;
- }
- slow_hash_free_state();
- MGINFO("Miner thread stopped ["<< th_local_index << "]");
- return true;
- }
- //-----------------------------------------------------------------------------------------------------
-}
-
diff --git a/src/cryptonote_core/miner.h b/src/cryptonote_core/miner.h
deleted file mode 100644
index f24f6e960..000000000
--- a/src/cryptonote_core/miner.h
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright (c) 2014-2016, 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
-
-#pragma once
-
-#include <boost/program_options.hpp>
-#include <atomic>
-#include "cryptonote_basic.h"
-#include "difficulty.h"
-#include "math_helper.h"
-
-
-namespace cryptonote
-{
-
- struct i_miner_handler
- {
- virtual bool handle_block_found(block& b) = 0;
- virtual bool get_block_template(block& b, const account_public_address& adr, difficulty_type& diffic, uint64_t& height, const blobdata& ex_nonce) = 0;
- protected:
- ~i_miner_handler(){};
- };
-
- /************************************************************************/
- /* */
- /************************************************************************/
- class miner
- {
- public:
- miner(i_miner_handler* phandler);
- ~miner();
- bool init(const boost::program_options::variables_map& vm, bool testnet);
- static void init_options(boost::program_options::options_description& desc);
- bool set_block_template(const block& bl, const difficulty_type& diffic, uint64_t height);
- bool on_block_chain_update();
- bool start(const account_public_address& adr, size_t threads_count, const boost::thread::attributes& attrs);
- uint64_t get_speed() const;
- uint32_t get_threads_count() const;
- void send_stop_signal();
- bool stop();
- bool is_mining() const;
- const account_public_address& get_mining_address() const;
- bool on_idle();
- void on_synchronized();
- //synchronous analog (for fast calls)
- static bool find_nonce_for_given_block(block& bl, const difficulty_type& diffic, uint64_t height);
- void pause();
- void resume();
- void do_print_hashrate(bool do_hr);
-
- private:
- bool worker_thread();
- bool request_block_template();
- void merge_hr();
-
- struct miner_config
- {
- uint64_t current_extra_message_index;
-
- BEGIN_KV_SERIALIZE_MAP()
- KV_SERIALIZE(current_extra_message_index)
- END_KV_SERIALIZE_MAP()
- };
-
-
- volatile uint32_t m_stop;
- epee::critical_section m_template_lock;
- block m_template;
- std::atomic<uint32_t> m_template_no;
- std::atomic<uint32_t> m_starter_nonce;
- difficulty_type m_diffic;
- uint64_t m_height;
- volatile uint32_t m_thread_index;
- volatile uint32_t m_threads_total;
- std::atomic<int32_t> m_pausers_count;
- epee::critical_section m_miners_count_lock;
-
- std::list<boost::thread> m_threads;
- epee::critical_section m_threads_lock;
- i_miner_handler* m_phandler;
- account_public_address m_mine_address;
- epee::math_helper::once_a_time_seconds<5> m_update_block_template_interval;
- epee::math_helper::once_a_time_seconds<2> m_update_merge_hr_interval;
- std::vector<blobdata> m_extra_messages;
- miner_config m_config;
- std::string m_config_folder_path;
- std::atomic<uint64_t> m_last_hr_merge_time;
- std::atomic<uint64_t> m_hashes;
- std::atomic<uint64_t> m_current_hash_rate;
- epee::critical_section m_last_hash_rates_lock;
- std::list<uint64_t> m_last_hash_rates;
- bool m_do_print_hashrate;
- bool m_do_mining;
-
- };
-}
-
-
-
diff --git a/src/cryptonote_core/tx_extra.h b/src/cryptonote_core/tx_extra.h
deleted file mode 100644
index 6f5fbe466..000000000
--- a/src/cryptonote_core/tx_extra.h
+++ /dev/null
@@ -1,182 +0,0 @@
-// Copyright (c) 2014-2016, 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
-
-#pragma once
-
-
-#define TX_EXTRA_PADDING_MAX_COUNT 255
-#define TX_EXTRA_NONCE_MAX_COUNT 255
-
-#define TX_EXTRA_TAG_PADDING 0x00
-#define TX_EXTRA_TAG_PUBKEY 0x01
-#define TX_EXTRA_NONCE 0x02
-#define TX_EXTRA_MERGE_MINING_TAG 0x03
-#define TX_EXTRA_MYSTERIOUS_MINERGATE_TAG 0xDE
-
-#define TX_EXTRA_NONCE_PAYMENT_ID 0x00
-#define TX_EXTRA_NONCE_ENCRYPTED_PAYMENT_ID 0x01
-
-namespace cryptonote
-{
- struct tx_extra_padding
- {
- size_t size;
-
- // load
- template <template <bool> class Archive>
- bool do_serialize(Archive<false>& ar)
- {
- // size - 1 - because of variant tag
- for (size = 1; size <= TX_EXTRA_PADDING_MAX_COUNT; ++size)
- {
- std::ios_base::iostate state = ar.stream().rdstate();
- bool eof = EOF == ar.stream().peek();
- ar.stream().clear(state);
-
- if (eof)
- break;
-
- uint8_t zero;
- if (!::do_serialize(ar, zero))
- return false;
-
- if (0 != zero)
- return false;
- }
-
- return size <= TX_EXTRA_PADDING_MAX_COUNT;
- }
-
- // store
- template <template <bool> class Archive>
- bool do_serialize(Archive<true>& ar)
- {
- if(TX_EXTRA_PADDING_MAX_COUNT < size)
- return false;
-
- // i = 1 - because of variant tag
- for (size_t i = 1; i < size; ++i)
- {
- uint8_t zero = 0;
- if (!::do_serialize(ar, zero))
- return false;
- }
- return true;
- }
- };
-
- struct tx_extra_pub_key
- {
- crypto::public_key pub_key;
-
- BEGIN_SERIALIZE()
- FIELD(pub_key)
- END_SERIALIZE()
- };
-
- struct tx_extra_nonce
- {
- std::string nonce;
-
- BEGIN_SERIALIZE()
- FIELD(nonce)
- if(TX_EXTRA_NONCE_MAX_COUNT < nonce.size()) return false;
- END_SERIALIZE()
- };
-
- struct tx_extra_merge_mining_tag
- {
- struct serialize_helper
- {
- tx_extra_merge_mining_tag& mm_tag;
-
- serialize_helper(tx_extra_merge_mining_tag& mm_tag_) : mm_tag(mm_tag_)
- {
- }
-
- BEGIN_SERIALIZE()
- VARINT_FIELD_N("depth", mm_tag.depth)
- FIELD_N("merkle_root", mm_tag.merkle_root)
- END_SERIALIZE()
- };
-
- size_t depth;
- crypto::hash merkle_root;
-
- // load
- template <template <bool> class Archive>
- bool do_serialize(Archive<false>& ar)
- {
- std::string field;
- if(!::do_serialize(ar, field))
- return false;
-
- std::istringstream iss(field);
- binary_archive<false> iar(iss);
- serialize_helper helper(*this);
- return ::serialization::serialize(iar, helper);
- }
-
- // store
- template <template <bool> class Archive>
- bool do_serialize(Archive<true>& ar)
- {
- std::ostringstream oss;
- binary_archive<true> oar(oss);
- serialize_helper helper(*this);
- if(!::do_serialize(oar, helper))
- return false;
-
- std::string field = oss.str();
- return ::serialization::serialize(ar, field);
- }
- };
-
- struct tx_extra_mysterious_minergate
- {
- std::string data;
-
- BEGIN_SERIALIZE()
- FIELD(data)
- END_SERIALIZE()
- };
-
- // tx_extra_field format, except tx_extra_padding and tx_extra_pub_key:
- // varint tag;
- // varint size;
- // varint data[];
- typedef boost::variant<tx_extra_padding, tx_extra_pub_key, tx_extra_nonce, tx_extra_merge_mining_tag, tx_extra_mysterious_minergate> tx_extra_field;
-}
-
-VARIANT_TAG(binary_archive, cryptonote::tx_extra_padding, TX_EXTRA_TAG_PADDING);
-VARIANT_TAG(binary_archive, cryptonote::tx_extra_pub_key, TX_EXTRA_TAG_PUBKEY);
-VARIANT_TAG(binary_archive, cryptonote::tx_extra_nonce, TX_EXTRA_NONCE);
-VARIANT_TAG(binary_archive, cryptonote::tx_extra_merge_mining_tag, TX_EXTRA_MERGE_MINING_TAG);
-VARIANT_TAG(binary_archive, cryptonote::tx_extra_mysterious_minergate, TX_EXTRA_MYSTERIOUS_MINERGATE_TAG);
diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp
index e37ddec0d..9188f8329 100644
--- a/src/cryptonote_core/tx_pool.cpp
+++ b/src/cryptonote_core/tx_pool.cpp
@@ -34,8 +34,8 @@
#include <vector>
#include "tx_pool.h"
-#include "cryptonote_format_utils.h"
-#include "cryptonote_boost_serialization.h"
+#include "cryptonote_tx_utils.h"
+#include "cryptonote_basic/cryptonote_boost_serialization.h"
#include "cryptonote_config.h"
#include "blockchain.h"
#include "common/boost_serialization_helper.h"
diff --git a/src/cryptonote_core/tx_pool.h b/src/cryptonote_core/tx_pool.h
index 2712f75bb..e9c9e3f36 100644
--- a/src/cryptonote_core/tx_pool.h
+++ b/src/cryptonote_core/tx_pool.h
@@ -41,8 +41,8 @@
#include "string_tools.h"
#include "syncobj.h"
#include "math_helper.h"
-#include "cryptonote_basic_impl.h"
-#include "verification_context.h"
+#include "cryptonote_basic/cryptonote_basic_impl.h"
+#include "cryptonote_basic/verification_context.h"
#include "crypto/hash.h"
#include "rpc/core_rpc_server_commands_defs.h"
diff --git a/src/cryptonote_core/verification_context.h b/src/cryptonote_core/verification_context.h
deleted file mode 100644
index 0bb635e84..000000000
--- a/src/cryptonote_core/verification_context.h
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (c) 2014-2016, 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
-
-#pragma once
-namespace cryptonote
-{
- /************************************************************************/
- /* */
- /************************************************************************/
- struct tx_verification_context
- {
- bool m_should_be_relayed;
- bool m_verifivation_failed; //bad tx, should drop connection
- bool m_verifivation_impossible; //the transaction is related with an alternative blockchain
- bool m_added_to_pool;
- bool m_low_mixin;
- bool m_double_spend;
- bool m_invalid_input;
- bool m_invalid_output;
- bool m_too_big;
- bool m_overspend;
- bool m_fee_too_low;
- bool m_not_rct;
- };
-
- struct block_verification_context
- {
- bool m_added_to_main_chain;
- bool m_verifivation_failed; //bad block, should drop connection
- bool m_marked_as_orphaned;
- bool m_already_exists;
- bool m_partial_block_reward;
- };
-}