aboutsummaryrefslogtreecommitdiff
path: root/src/cryptonote_basic
diff options
context:
space:
mode:
Diffstat (limited to 'src/cryptonote_basic')
-rw-r--r--src/cryptonote_basic/account.cpp25
-rw-r--r--src/cryptonote_basic/account.h1
-rw-r--r--src/cryptonote_basic/blobdatatype.h4
-rw-r--r--src/cryptonote_basic/connection_context.h23
-rw-r--r--src/cryptonote_basic/cryptonote_basic.h35
-rw-r--r--src/cryptonote_basic/cryptonote_basic_impl.cpp6
-rw-r--r--src/cryptonote_basic/cryptonote_basic_impl.h2
-rw-r--r--src/cryptonote_basic/cryptonote_boost_serialization.h24
-rw-r--r--src/cryptonote_basic/cryptonote_format_utils.cpp130
-rw-r--r--src/cryptonote_basic/cryptonote_format_utils.h4
-rw-r--r--src/cryptonote_basic/difficulty.cpp2
-rw-r--r--src/cryptonote_basic/hardfork.cpp31
-rw-r--r--src/cryptonote_basic/hardfork.h10
-rw-r--r--src/cryptonote_basic/miner.cpp35
-rw-r--r--src/cryptonote_basic/miner.h5
15 files changed, 272 insertions, 65 deletions
diff --git a/src/cryptonote_basic/account.cpp b/src/cryptonote_basic/account.cpp
index e891a748d..edbc2c561 100644
--- a/src/cryptonote_basic/account.cpp
+++ b/src/cryptonote_basic/account.cpp
@@ -136,6 +136,16 @@ DISABLE_VS_WARNINGS(4244 4345)
void account_base::set_null()
{
m_keys = account_keys();
+ m_creation_timestamp = 0;
+ }
+ //-----------------------------------------------------------------
+ void account_base::deinit()
+ {
+ try{
+ m_keys.get_device().disconnect();
+ } catch (const std::exception &e){
+ MERROR("Device disconnect exception: " << e.what());
+ }
}
//-----------------------------------------------------------------
void account_base::forget_spend_key()
@@ -205,11 +215,16 @@ DISABLE_VS_WARNINGS(4244 4345)
void account_base::create_from_device(hw::device &hwdev)
{
m_keys.set_device(hwdev);
- MCDEBUG("ledger", "device type: "<<typeid(hwdev).name());
- hwdev.init();
- hwdev.connect();
- hwdev.get_public_address(m_keys.m_account_address);
- hwdev.get_secret_keys(m_keys.m_view_secret_key, m_keys.m_spend_secret_key);
+ MCDEBUG("device", "device type: "<<typeid(hwdev).name());
+ CHECK_AND_ASSERT_THROW_MES(hwdev.init(), "Device init failed");
+ CHECK_AND_ASSERT_THROW_MES(hwdev.connect(), "Device connect failed");
+ try {
+ CHECK_AND_ASSERT_THROW_MES(hwdev.get_public_address(m_keys.m_account_address), "Cannot get a device address");
+ CHECK_AND_ASSERT_THROW_MES(hwdev.get_secret_keys(m_keys.m_view_secret_key, m_keys.m_spend_secret_key), "Cannot get device secret");
+ } catch (const std::exception &e){
+ hwdev.disconnect();
+ throw;
+ }
struct tm timestamp = {0};
timestamp.tm_year = 2014 - 1900; // year 2014
timestamp.tm_mon = 4 - 1; // month april
diff --git a/src/cryptonote_basic/account.h b/src/cryptonote_basic/account.h
index 98bba55b1..021f84029 100644
--- a/src/cryptonote_basic/account.h
+++ b/src/cryptonote_basic/account.h
@@ -89,6 +89,7 @@ namespace cryptonote
hw::device& get_device() const {return m_keys.get_device();}
void set_device( hw::device &hwdev) {m_keys.set_device(hwdev);}
+ void deinit();
uint64_t get_createtime() const { return m_creation_timestamp; }
void set_createtime(uint64_t val) { m_creation_timestamp = val; }
diff --git a/src/cryptonote_basic/blobdatatype.h b/src/cryptonote_basic/blobdatatype.h
index 7d6ff0187..82484c0a8 100644
--- a/src/cryptonote_basic/blobdatatype.h
+++ b/src/cryptonote_basic/blobdatatype.h
@@ -30,7 +30,11 @@
#pragma once
+#include <string>
+#include "span.h"
+
namespace cryptonote
{
typedef std::string blobdata;
+ typedef epee::span<const char> blobdata_ref;
}
diff --git a/src/cryptonote_basic/connection_context.h b/src/cryptonote_basic/connection_context.h
index eb73ab0ea..112c13049 100644
--- a/src/cryptonote_basic/connection_context.h
+++ b/src/cryptonote_basic/connection_context.h
@@ -40,7 +40,7 @@ namespace cryptonote
struct cryptonote_connection_context: public epee::net_utils::connection_context_base
{
cryptonote_connection_context(): m_state(state_before_handshake), m_remote_blockchain_height(0), m_last_response_height(0),
- m_last_request_time(boost::posix_time::microsec_clock::universal_time()), m_callback_request_count(0), m_last_known_hash(crypto::null_hash) {}
+ m_last_request_time(boost::date_time::not_a_date_time), m_callback_request_count(0), m_last_known_hash(crypto::null_hash), m_pruning_seed(0), m_anchor(false) {}
enum state
{
@@ -59,6 +59,8 @@ namespace cryptonote
boost::posix_time::ptime m_last_request_time;
epee::copyable_atomic m_callback_request_count; //in debug purpose: problem with double callback rise
crypto::hash m_last_known_hash;
+ uint32_t m_pruning_seed;
+ bool m_anchor;
//size_t m_score; TODO: add score calculations
};
@@ -81,4 +83,23 @@ namespace cryptonote
}
}
+ inline char get_protocol_state_char(cryptonote_connection_context::state s)
+ {
+ switch (s)
+ {
+ case cryptonote_connection_context::state_before_handshake:
+ return 'h';
+ case cryptonote_connection_context::state_synchronizing:
+ return 's';
+ case cryptonote_connection_context::state_standby:
+ return 'w';
+ case cryptonote_connection_context::state_idle:
+ return 'i';
+ case cryptonote_connection_context::state_normal:
+ return 'n';
+ default:
+ return 'u';
+ }
+ }
+
}
diff --git a/src/cryptonote_basic/cryptonote_basic.h b/src/cryptonote_basic/cryptonote_basic.h
index d4558ef7b..c9c783a56 100644
--- a/src/cryptonote_basic/cryptonote_basic.h
+++ b/src/cryptonote_basic/cryptonote_basic.h
@@ -47,7 +47,6 @@
#include "crypto/crypto.h"
#include "crypto/hash.h"
#include "misc_language.h"
-#include "tx_extra.h"
#include "ringct/rctTypes.h"
#include "device/device.hpp"
@@ -176,7 +175,15 @@ namespace cryptonote
END_SERIALIZE()
public:
- transaction_prefix(){}
+ transaction_prefix(){ set_null(); }
+ void set_null()
+ {
+ version = 1;
+ unlock_time = 0;
+ vin.clear();
+ vout.clear();
+ extra.clear();
+ }
};
class transaction: public transaction_prefix
@@ -194,9 +201,11 @@ namespace cryptonote
mutable crypto::hash hash;
mutable size_t blob_size;
+ bool pruned;
+
transaction();
- transaction(const transaction &t): transaction_prefix(t), hash_valid(false), blob_size_valid(false), signatures(t.signatures), rct_signatures(t.rct_signatures) { if (t.is_hash_valid()) { hash = t.hash; set_hash_valid(true); } if (t.is_blob_size_valid()) { blob_size = t.blob_size; set_blob_size_valid(true); } }
- transaction &operator=(const transaction &t) { transaction_prefix::operator=(t); set_hash_valid(false); set_blob_size_valid(false); signatures = t.signatures; rct_signatures = t.rct_signatures; if (t.is_hash_valid()) { hash = t.hash; set_hash_valid(true); } if (t.is_blob_size_valid()) { blob_size = t.blob_size; set_blob_size_valid(true); } return *this; }
+ transaction(const transaction &t): transaction_prefix(t), hash_valid(false), blob_size_valid(false), signatures(t.signatures), rct_signatures(t.rct_signatures), pruned(t.pruned) { if (t.is_hash_valid()) { hash = t.hash; set_hash_valid(true); } if (t.is_blob_size_valid()) { blob_size = t.blob_size; set_blob_size_valid(true); } }
+ transaction &operator=(const transaction &t) { transaction_prefix::operator=(t); set_hash_valid(false); set_blob_size_valid(false); signatures = t.signatures; rct_signatures = t.rct_signatures; if (t.is_hash_valid()) { hash = t.hash; set_hash_valid(true); } if (t.is_blob_size_valid()) { blob_size = t.blob_size; set_blob_size_valid(true); } pruned = t.pruned; return *this; }
virtual ~transaction();
void set_null();
void invalidate_hashes();
@@ -204,6 +213,8 @@ namespace cryptonote
void set_hash_valid(bool v) const { hash_valid.store(v,std::memory_order_release); }
bool is_blob_size_valid() const { return blob_size_valid.load(std::memory_order_acquire); }
void set_blob_size_valid(bool v) const { blob_size_valid.store(v,std::memory_order_release); }
+ void set_hash(const crypto::hash &h) { hash = h; set_hash_valid(true); }
+ void set_blob_size(size_t sz) { blob_size = sz; set_blob_size_valid(true); }
BEGIN_SERIALIZE_OBJECT()
if (!typename Archive<W>::is_saving())
@@ -223,7 +234,7 @@ namespace cryptonote
if (!signatures_not_expected && vin.size() != signatures.size())
return false;
- for (size_t i = 0; i < vin.size(); ++i)
+ if (!pruned) for (size_t i = 0; i < vin.size(); ++i)
{
size_t signature_size = get_signature_size(vin[i]);
if (signatures_not_expected)
@@ -254,7 +265,7 @@ namespace cryptonote
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)
+ if (!pruned && rct_signatures.type != rct::RCTTypeNull)
{
ar.tag("rctsig_prunable");
ar.begin_object();
@@ -265,6 +276,8 @@ namespace cryptonote
}
}
}
+ if (!typename Archive<W>::is_saving())
+ pruned = false;
END_SERIALIZE()
template<bool W, template <bool> class Archive>
@@ -286,6 +299,8 @@ namespace cryptonote
ar.end_object();
}
}
+ if (!typename Archive<W>::is_saving())
+ pruned = true;
return true;
}
@@ -303,21 +318,17 @@ namespace cryptonote
inline
transaction::~transaction()
{
- //set_null();
}
inline
void transaction::set_null()
{
- version = 1;
- unlock_time = 0;
- vin.clear();
- vout.clear();
- extra.clear();
+ transaction_prefix::set_null();
signatures.clear();
rct_signatures.type = rct::RCTTypeNull;
set_hash_valid(false);
set_blob_size_valid(false);
+ pruned = false;
}
inline
diff --git a/src/cryptonote_basic/cryptonote_basic_impl.cpp b/src/cryptonote_basic/cryptonote_basic_impl.cpp
index b18ef1c5c..23a5bd5bd 100644
--- a/src/cryptonote_basic/cryptonote_basic_impl.cpp
+++ b/src/cryptonote_basic/cryptonote_basic_impl.cpp
@@ -40,7 +40,7 @@ using namespace epee;
#include "misc_language.h"
#include "common/base58.h"
#include "crypto/hash.h"
-#include "common/int-util.h"
+#include "int-util.h"
#include "common/dns_utils.h"
#undef MONERO_DEFAULT_LOG_CATEGORY
@@ -322,13 +322,13 @@ namespace cryptonote {
}
//--------------------------------------------------------------------------------
-bool parse_hash256(const std::string str_hash, crypto::hash& hash)
+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;
+ MERROR("invalid hash format: " << str_hash);
return false;
}
else
diff --git a/src/cryptonote_basic/cryptonote_basic_impl.h b/src/cryptonote_basic/cryptonote_basic_impl.h
index c804a88fa..0b8131a7a 100644
--- a/src/cryptonote_basic/cryptonote_basic_impl.h
+++ b/src/cryptonote_basic/cryptonote_basic_impl.h
@@ -124,5 +124,5 @@ namespace cryptonote {
bool operator ==(const cryptonote::block& a, const cryptonote::block& b);
}
-bool parse_hash256(const std::string str_hash, crypto::hash& hash);
+bool parse_hash256(const std::string &str_hash, crypto::hash& hash);
diff --git a/src/cryptonote_basic/cryptonote_boost_serialization.h b/src/cryptonote_basic/cryptonote_boost_serialization.h
index 0725a2bb8..a4228b849 100644
--- a/src/cryptonote_basic/cryptonote_boost_serialization.h
+++ b/src/cryptonote_basic/cryptonote_boost_serialization.h
@@ -45,6 +45,8 @@
#include "ringct/rctTypes.h"
#include "ringct/rctOps.h"
+BOOST_CLASS_VERSION(rct::ecdhTuple, 1)
+
//namespace cryptonote {
namespace boost
{
@@ -247,9 +249,19 @@ namespace boost
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
+ if (ver < 1)
+ {
+ a & x.mask;
+ a & x.amount;
+ return;
+ }
+ crypto::hash8 &amount = (crypto::hash8&)x.amount;
+ if (!Archive::is_saving::value)
+ {
+ memset(&x.mask, 0, sizeof(x.mask));
+ memset(&x.amount, 0, sizeof(x.amount));
+ }
+ a & amount;
}
template <class Archive>
@@ -295,7 +307,7 @@ namespace boost
a & x.type;
if (x.type == rct::RCTTypeNull)
return;
- if (x.type != rct::RCTTypeFull && x.type != rct::RCTTypeSimple && x.type != rct::RCTTypeBulletproof)
+ if (x.type != rct::RCTTypeFull && x.type != rct::RCTTypeSimple && x.type != rct::RCTTypeBulletproof && x.type != rct::RCTTypeBulletproof2)
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
@@ -323,7 +335,7 @@ namespace boost
a & x.type;
if (x.type == rct::RCTTypeNull)
return;
- if (x.type != rct::RCTTypeFull && x.type != rct::RCTTypeSimple && x.type != rct::RCTTypeBulletproof)
+ if (x.type != rct::RCTTypeFull && x.type != rct::RCTTypeSimple && x.type != rct::RCTTypeBulletproof && x.type != rct::RCTTypeBulletproof2)
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
@@ -337,7 +349,7 @@ namespace boost
if (x.p.rangeSigs.empty())
a & x.p.bulletproofs;
a & x.p.MGs;
- if (x.type == rct::RCTTypeBulletproof)
+ if (x.type == rct::RCTTypeBulletproof || x.type == rct::RCTTypeBulletproof2)
a & x.p.pseudoOuts;
}
}
diff --git a/src/cryptonote_basic/cryptonote_format_utils.cpp b/src/cryptonote_basic/cryptonote_format_utils.cpp
index 9e9c12605..f6daaab95 100644
--- a/src/cryptonote_basic/cryptonote_format_utils.cpp
+++ b/src/cryptonote_basic/cryptonote_format_utils.cpp
@@ -28,9 +28,6 @@
//
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
-#include "include_base_utils.h"
-using namespace epee;
-
#include <atomic>
#include <boost/algorithm/string.hpp>
#include "wipeable_string.h"
@@ -42,6 +39,8 @@ using namespace epee;
#include "crypto/hash.h"
#include "ringct/rctSigs.h"
+using namespace epee;
+
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "cn"
@@ -185,6 +184,7 @@ namespace cryptonote
CHECK_AND_ASSERT_MES(r, false, "Failed to parse transaction from blob");
CHECK_AND_ASSERT_MES(expand_transaction_1(tx, false), false, "Failed to expand transaction data");
tx.invalidate_hashes();
+ tx.set_blob_size(tx_blob.size());
return true;
}
//---------------------------------------------------------------
@@ -196,6 +196,7 @@ namespace cryptonote
bool r = tx.serialize_base(ba);
CHECK_AND_ASSERT_MES(r, false, "Failed to parse transaction from blob");
CHECK_AND_ASSERT_MES(expand_transaction_1(tx, true), false, "Failed to expand transaction data");
+ tx.invalidate_hashes();
return true;
}
//---------------------------------------------------------------
@@ -225,6 +226,22 @@ namespace cryptonote
return true;
}
//---------------------------------------------------------------
+ bool is_v1_tx(const blobdata_ref& tx_blob)
+ {
+ uint64_t version;
+ const char* begin = static_cast<const char*>(tx_blob.data());
+ const char* end = begin + tx_blob.size();
+ int read = tools::read_varint(begin, end, version);
+ if (read <= 0)
+ throw std::runtime_error("Internal error getting transaction version");
+ return version <= 1;
+ }
+ //---------------------------------------------------------------
+ bool is_v1_tx(const blobdata& tx_blob)
+ {
+ return is_v1_tx(blobdata_ref{tx_blob.data(), tx_blob.size()});
+ }
+ //---------------------------------------------------------------
bool generate_key_image_helper(const account_keys& ack, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, const crypto::public_key& out_key, const crypto::public_key& tx_public_key, const std::vector<crypto::public_key>& additional_tx_public_keys, size_t real_output_index, keypair& in_ephemeral, crypto::key_image& ki, hw::device &hwdev)
{
crypto::key_derivation recv_derivation = AUTO_VAL_INIT(recv_derivation);
@@ -380,11 +397,19 @@ namespace cryptonote
//---------------------------------------------------------------
uint64_t get_transaction_weight(const transaction &tx)
{
- std::ostringstream s;
- binary_archive<true> a(s);
- ::serialization::serialize(a, const_cast<transaction&>(tx));
- const cryptonote::blobdata blob = s.str();
- return get_transaction_weight(tx, blob.size());
+ size_t blob_size;
+ if (tx.is_blob_size_valid())
+ {
+ blob_size = tx.blob_size;
+ }
+ else
+ {
+ std::ostringstream s;
+ binary_archive<true> a(s);
+ ::serialization::serialize(a, const_cast<transaction&>(tx));
+ blob_size = s.str().size();
+ }
+ return get_transaction_weight(tx, blob_size);
}
//---------------------------------------------------------------
bool get_tx_fee(const transaction& tx, uint64_t & fee)
@@ -445,6 +470,91 @@ namespace cryptonote
return true;
}
//---------------------------------------------------------------
+ template<typename T>
+ static bool pick(binary_archive<true> &ar, std::vector<tx_extra_field> &fields, uint8_t tag)
+ {
+ std::vector<tx_extra_field>::iterator it;
+ while ((it = std::find_if(fields.begin(), fields.end(), [](const tx_extra_field &f) { return f.type() == typeid(T); })) != fields.end())
+ {
+ bool r = ::do_serialize(ar, tag);
+ CHECK_AND_NO_ASSERT_MES_L1(r, false, "failed to serialize tx extra field");
+ r = ::do_serialize(ar, boost::get<T>(*it));
+ CHECK_AND_NO_ASSERT_MES_L1(r, false, "failed to serialize tx extra field");
+ fields.erase(it);
+ }
+ return true;
+ }
+ //---------------------------------------------------------------
+ bool sort_tx_extra(const std::vector<uint8_t>& tx_extra, std::vector<uint8_t> &sorted_tx_extra, bool allow_partial)
+ {
+ std::vector<tx_extra_field> tx_extra_fields;
+
+ if(tx_extra.empty())
+ {
+ sorted_tx_extra.clear();
+ 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;
+ size_t processed = 0;
+ while (!eof)
+ {
+ tx_extra_field field;
+ bool r = ::do_serialize(ar, field);
+ if (!r)
+ {
+ MWARNING("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 (!allow_partial)
+ return false;
+ break;
+ }
+ tx_extra_fields.push_back(field);
+ processed = iss.tellg();
+
+ std::ios_base::iostate state = iss.rdstate();
+ eof = (EOF == iss.peek());
+ iss.clear(state);
+ }
+ if (!::serialization::check_stream_state(ar))
+ {
+ MWARNING("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 (!allow_partial)
+ return false;
+ }
+ MTRACE("Sorted " << processed << "/" << tx_extra.size());
+
+ std::ostringstream oss;
+ binary_archive<true> nar(oss);
+
+ // sort by:
+ if (!pick<tx_extra_pub_key>(nar, tx_extra_fields, TX_EXTRA_TAG_PUBKEY)) return false;
+ if (!pick<tx_extra_additional_pub_keys>(nar, tx_extra_fields, TX_EXTRA_TAG_ADDITIONAL_PUBKEYS)) return false;
+ if (!pick<tx_extra_nonce>(nar, tx_extra_fields, TX_EXTRA_NONCE)) return false;
+ if (!pick<tx_extra_merge_mining_tag>(nar, tx_extra_fields, TX_EXTRA_MERGE_MINING_TAG)) return false;
+ if (!pick<tx_extra_mysterious_minergate>(nar, tx_extra_fields, TX_EXTRA_MYSTERIOUS_MINERGATE_TAG)) return false;
+ if (!pick<tx_extra_padding>(nar, tx_extra_fields, TX_EXTRA_TAG_PADDING)) return false;
+
+ // if not empty, someone added a new type and did not add a case above
+ if (!tx_extra_fields.empty())
+ {
+ MERROR("tx_extra_fields not empty after sorting, someone forgot to add a case above");
+ return false;
+ }
+
+ std::string oss_str = oss.str();
+ if (allow_partial && processed < tx_extra.size())
+ {
+ MDEBUG("Appending unparsed data");
+ oss_str += std::string((const char*)tx_extra.data() + processed, tx_extra.size() - processed);
+ }
+ sorted_tx_extra = std::vector<uint8_t>(oss_str.begin(), oss_str.end());
+ 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;
@@ -798,7 +908,7 @@ namespace cryptonote
{
if (decimal_point == (unsigned int)-1)
decimal_point = default_decimal_point;
- switch (std::atomic_load(&default_decimal_point))
+ switch (decimal_point)
{
case 12:
return "monero";
@@ -811,7 +921,7 @@ namespace cryptonote
case 0:
return "piconero";
default:
- ASSERT_MES_AND_THROW("Invalid decimal point specification: " << default_decimal_point);
+ ASSERT_MES_AND_THROW("Invalid decimal point specification: " << decimal_point);
}
}
//---------------------------------------------------------------
diff --git a/src/cryptonote_basic/cryptonote_format_utils.h b/src/cryptonote_basic/cryptonote_format_utils.h
index 725c75f4e..994978c10 100644
--- a/src/cryptonote_basic/cryptonote_format_utils.h
+++ b/src/cryptonote_basic/cryptonote_format_utils.h
@@ -31,6 +31,7 @@
#pragma once
#include "blobdatatype.h"
#include "cryptonote_basic_impl.h"
+#include "tx_extra.h"
#include "account.h"
#include "subaddress_index.h"
#include "include_base_utils.h"
@@ -52,6 +53,8 @@ namespace cryptonote
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 parse_and_validate_tx_base_from_blob(const blobdata& tx_blob, transaction& tx);
+ bool is_v1_tx(const blobdata_ref& tx_blob);
+ bool is_v1_tx(const blobdata& tx_blob);
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)
@@ -65,6 +68,7 @@ namespace cryptonote
}
bool parse_tx_extra(const std::vector<uint8_t>& tx_extra, std::vector<tx_extra_field>& tx_extra_fields);
+ bool sort_tx_extra(const std::vector<uint8_t>& tx_extra, std::vector<uint8_t> &sorted_tx_extra, bool allow_partial = false);
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);
diff --git a/src/cryptonote_basic/difficulty.cpp b/src/cryptonote_basic/difficulty.cpp
index cb2a00a12..55e3e93b3 100644
--- a/src/cryptonote_basic/difficulty.cpp
+++ b/src/cryptonote_basic/difficulty.cpp
@@ -34,7 +34,7 @@
#include <cstdint>
#include <vector>
-#include "common/int-util.h"
+#include "int-util.h"
#include "crypto/hash.h"
#include "cryptonote_config.h"
#include "difficulty.h"
diff --git a/src/cryptonote_basic/hardfork.cpp b/src/cryptonote_basic/hardfork.cpp
index f05b25901..447d79aee 100644
--- a/src/cryptonote_basic/hardfork.cpp
+++ b/src/cryptonote_basic/hardfork.cpp
@@ -56,12 +56,13 @@ static uint8_t get_block_version(const cryptonote::block &b)
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)
+ default_threshold_percent(default_threshold_percent),
+ original_version(original_version),
+ original_version_till_height(original_version_till_height),
+ current_fork_index(0)
{
if (window_size == 0)
throw "window_size needs to be strictly positive";
@@ -221,7 +222,6 @@ bool HardFork::reorganize_from_block_height(uint64_t height)
if (height >= db.height())
return false;
- db.set_batch_transactions(true);
bool stop_batch = db.batch_start();
versions.clear();
@@ -305,6 +305,29 @@ bool HardFork::rescan_from_chain_height(uint64_t height)
return rescan_from_block_height(height - 1);
}
+void HardFork::on_block_popped(uint64_t nblocks)
+{
+ CHECK_AND_ASSERT_THROW_MES(nblocks > 0, "nblocks must be greater than 0");
+
+ CRITICAL_REGION_LOCAL(lock);
+
+ const uint64_t new_chain_height = db.height();
+ const uint64_t old_chain_height = new_chain_height + nblocks;
+ uint8_t version;
+ uint64_t height;
+ for (height = old_chain_height - 1; height >= new_chain_height; --height)
+ {
+ versions.pop_back();
+ version = db.get_hard_fork_version(height);
+ versions.push_front(version);
+ }
+
+ // does not take voting into account
+ for (current_fork_index = heights.size() - 1; current_fork_index > 0; --current_fork_index)
+ if (height >= heights[current_fork_index].height)
+ break;
+}
+
int HardFork::get_voted_fork_index(uint64_t height) const
{
CRITICAL_REGION_LOCAL(lock);
diff --git a/src/cryptonote_basic/hardfork.h b/src/cryptonote_basic/hardfork.h
index a63a66976..a3fc25dfa 100644
--- a/src/cryptonote_basic/hardfork.h
+++ b/src/cryptonote_basic/hardfork.h
@@ -150,6 +150,16 @@ namespace cryptonote
bool reorganize_from_chain_height(uint64_t height);
/**
+ * @brief called when one or more blocks are popped from the blockchain
+ *
+ * The current fork will be updated by looking up the db,
+ * which is much cheaper than recomputing everything
+ *
+ * @param new_chain_height the height of the chain after popping
+ */
+ void on_block_popped(uint64_t new_chain_height);
+
+ /**
* @brief returns current state at the given time
*
* Based on the approximate time of the last known hard fork,
diff --git a/src/cryptonote_basic/miner.cpp b/src/cryptonote_basic/miner.cpp
index d0b03593e..f4de2ed7e 100644
--- a/src/cryptonote_basic/miner.cpp
+++ b/src/cryptonote_basic/miner.cpp
@@ -33,8 +33,6 @@
#include <boost/utility/value_init.hpp>
#include <boost/interprocess/detail/atomic.hpp>
#include <boost/algorithm/string.hpp>
-#include <boost/limits.hpp>
-#include "include_base_utils.h"
#include "misc_language.h"
#include "syncobj.h"
#include "cryptonote_basic_impl.h"
@@ -54,19 +52,22 @@
#include <mach/mach_host.h>
#include <AvailabilityMacros.h>
#include <TargetConditionals.h>
-#endif
-
-#ifdef __FreeBSD__
-#include <devstat.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <machine/apm_bios.h>
-#include <stdio.h>
-#include <sys/resource.h>
-#include <sys/sysctl.h>
-#include <sys/times.h>
-#include <sys/types.h>
-#include <unistd.h>
+#elif defined(__linux__)
+ #include <unistd.h>
+ #include <sys/resource.h>
+ #include <sys/times.h>
+ #include <time.h>
+#elif defined(__FreeBSD__)
+ #include <devstat.h>
+ #include <errno.h>
+ #include <fcntl.h>
+ #include <machine/apm_bios.h>
+ #include <stdio.h>
+ #include <sys/resource.h>
+ #include <sys/sysctl.h>
+ #include <sys/times.h>
+ #include <sys/types.h>
+ #include <unistd.h>
#endif
#undef MONERO_DEFAULT_LOG_CATEGORY
@@ -146,7 +147,7 @@ namespace cryptonote
//-----------------------------------------------------------------------------------------------------
bool miner::request_block_template()
{
- block bl = AUTO_VAL_INIT(bl);
+ block bl;
difficulty_type di = AUTO_VAL_INIT(di);
uint64_t height = AUTO_VAL_INIT(height);
uint64_t expected_reward; //only used for RPC calls - could possibly be useful here too?
@@ -637,7 +638,7 @@ namespace cryptonote
boost::tribool battery_powered(on_battery_power());
if(!indeterminate( battery_powered ))
{
- on_ac_power = !battery_powered;
+ on_ac_power = !(bool)battery_powered;
}
}
diff --git a/src/cryptonote_basic/miner.h b/src/cryptonote_basic/miner.h
index 2bff784c7..e16d9f3b8 100644
--- a/src/cryptonote_basic/miner.h
+++ b/src/cryptonote_basic/miner.h
@@ -38,11 +38,6 @@
#include "math_helper.h"
#ifdef _WIN32
#include <windows.h>
-#elif defined(__linux__)
-#include <unistd.h>
-#include <sys/resource.h>
-#include <sys/times.h>
-#include <time.h>
#endif
namespace cryptonote