forked from lthn/blockchain
added more logs, changed structure of furmat_utils
This commit is contained in:
parent
f4c789a0ee
commit
6e050fce8b
15 changed files with 601 additions and 392 deletions
|
|
@ -348,7 +348,7 @@ namespace net_utils
|
|||
LOG_FRAME("simple_http_connection_handler<t_connection_context>::handle_recognize_protocol_out(*)", LOG_LEVEL_3);
|
||||
|
||||
STATIC_REGEXP_EXPR_1(rexp_match_command_line, "^(((OPTIONS)|(GET)|(HEAD)|(POST)|(PUT)|(DELETE)|(TRACE)) (\\S+) HTTP/(\\d+).(\\d+))\r?\n", boost::regex::icase | boost::regex::normal);
|
||||
// 123 4 5 6 7 8 9 10 11 12
|
||||
// 123 4 5 6 7 8 9 10 11 12
|
||||
//size_t match_len = 0;
|
||||
boost::smatch result;
|
||||
if(boost::regex_search(m_cache, result, rexp_match_command_line, boost::match_default) && result[0].matched)
|
||||
|
|
|
|||
36
src/common/crypto_stream_operators.h
Normal file
36
src/common/crypto_stream_operators.h
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright (c) 2018-2019 Zano Project
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include "include_base_utils.h"
|
||||
#include "crypto/crypto.h"
|
||||
#include "crypto/hash.h"
|
||||
//------
|
||||
bool parse_hash256(const std::string str_hash, crypto::hash& hash);
|
||||
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 &print16(std::ostream &o, const T &v) {
|
||||
return o << "<" << epee::string_tools::pod_to_hex(v).substr(0, 5) << "..>";
|
||||
}
|
||||
|
||||
template <class T>
|
||||
std::string print16(const T &v) {
|
||||
return std::string("<") + epee::string_tools::pod_to_hex(v).substr(0, 5) + "..>";
|
||||
}
|
||||
|
||||
|
||||
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); }
|
||||
}
|
||||
|
|
@ -42,5 +42,7 @@ namespace tools
|
|||
{
|
||||
std::vector<unsigned char> text2binary(const std::string& text);
|
||||
std::string binary2text(const std::vector<unsigned char>& binary);
|
||||
std::string word_by_num(uint64_t n);
|
||||
uint64_t num_by_word(const std::string& w);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,12 +62,15 @@ namespace currency
|
|||
return m_seed;
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
std::string account_base::get_restore_braindata() const
|
||||
{
|
||||
std::string restore_buff = get_restore_data();
|
||||
std::vector<unsigned char> v;
|
||||
v.assign((unsigned char*)restore_buff.data(), (unsigned char*)restore_buff.data() + restore_buff.size());
|
||||
return tools::mnemonic_encoding::binary2text(v);
|
||||
std::string seed_brain_data = tools::mnemonic_encoding::binary2text(v);
|
||||
//m_creation_timestamp
|
||||
return seed_brain_data;
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
bool account_base::restore_keys(const std::string& restore_data)
|
||||
|
|
|
|||
|
|
@ -155,6 +155,10 @@
|
|||
#define WALLET_FILE_SIGNATURE 0x1111012101101011LL //Bender's nightmare
|
||||
#define WALLET_FILE_MAX_BODY_SIZE 0x88888888L //2GB
|
||||
#define WALLET_FILE_MAX_KEYS_SIZE 10000 //
|
||||
#define WALLET_BRAIN_DATE_OFFSET 1543622400
|
||||
#define WALLET_BRAIN_DATE_QUANTUM 604800 //by last word we encode a number of week since launch of the project,
|
||||
//which let us to address tools::mnemonic_encoding::NUMWORDS weeks after project launch
|
||||
//which is about 30 years
|
||||
|
||||
#define OFFER_MAXIMUM_LIFE_TIME (60*60*24*30) // 30 days
|
||||
|
||||
|
|
|
|||
|
|
@ -26,54 +26,18 @@ using namespace epee;
|
|||
#include "bc_attachments_helpers.h"
|
||||
#include "genesis.h"
|
||||
#include "genesis_acc.h"
|
||||
#include "common/mnemonic-encoding.h"
|
||||
|
||||
namespace currency
|
||||
{
|
||||
//---------------------------------------------------------------
|
||||
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));
|
||||
std::string data = s.str();
|
||||
crypto::cn_fast_hash(data.data(), data.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 add_tx_extra_alias(transaction& tx, const extra_alias_entry& alinfo)
|
||||
{
|
||||
tx.extra.push_back(alinfo);
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool parse_and_validate_tx_from_blob(const blobdata& tx_blob, transaction& tx, crypto::hash& tx_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
|
||||
|
||||
//crypto::cn_fast_hash(tx_blob.data(), tx_blob.size(), tx_hash);
|
||||
get_transaction_prefix_hash(tx, tx_hash);
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
/*
|
||||
bool construct_miner_tx(size_t height, size_t median_size, uint64_t already_generated_coins,
|
||||
|
|
@ -1246,6 +1210,15 @@ namespace currency
|
|||
return reward;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
// std::string get_word_from_timstamp(uint64_t timestamp)
|
||||
// {
|
||||
// uint64_t date_offset = timestamp ? timestamp - WALLET_BRAIN_DATE_OFFSET : 0;
|
||||
// date_offset = date_offset / WALLET_BRAIN_DATE_QUANTUM;
|
||||
//
|
||||
// return tools::mnemonic_encoding::word_by_num(timestamp);
|
||||
// }
|
||||
|
||||
//---------------------------------------------------------------
|
||||
bool sign_multisig_input_in_tx(currency::transaction& tx, size_t ms_input_index, const currency::account_keys& keys, const currency::transaction& source_tx, bool *p_is_input_fully_signed /* = nullptr */)
|
||||
{
|
||||
#define LOC_CHK(cond, msg) CHECK_AND_ASSERT_MES(cond, false, msg << ", ms input index: " << ms_input_index << ", tx: " << get_transaction_hash(tx) << ", source tx: " << get_transaction_hash(source_tx))
|
||||
|
|
@ -1620,11 +1593,7 @@ namespace currency
|
|||
att.push_back(tsa);
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
void get_blob_hash(const blobdata& blob, crypto::hash& res)
|
||||
{
|
||||
cn_fast_hash(blob.data(), blob.size(), res);
|
||||
}
|
||||
|
||||
|
||||
std::string print_fixed_decimal_point(uint64_t amount, size_t decimal_point)
|
||||
{
|
||||
|
|
@ -1648,32 +1617,6 @@ namespace currency
|
|||
return std::to_string(amount) + '.' + r.substr(0, r.find_last_not_of('0') + 1);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
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)
|
||||
{
|
||||
return get_transaction_prefix_hash(t);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool get_transaction_hash(const transaction& t, crypto::hash& res)
|
||||
{
|
||||
uint64_t blob_size = 0;
|
||||
return get_object_hash(static_cast<const transaction_prefix&>(t), res, blob_size);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool get_transaction_hash(const transaction& t, crypto::hash& res, uint64_t& blob_size)
|
||||
{
|
||||
blob_size = 0;
|
||||
bool r = get_object_hash(static_cast<const transaction_prefix&>(t), res, blob_size);
|
||||
blob_size = get_object_blobsize(t, blob_size);
|
||||
return r;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
/*bool get_transaction_hash(const transaction& t, crypto::hash& res, size_t& blob_size)
|
||||
{
|
||||
|
||||
|
|
@ -1926,27 +1869,6 @@ namespace currency
|
|||
return ss.str();
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
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((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)
|
||||
{
|
||||
return get_object_hash(get_block_hashing_blob(b), res);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
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)
|
||||
{
|
||||
//genesis block
|
||||
|
|
@ -2052,101 +1974,9 @@ namespace currency
|
|||
//---------------------------------------------------------------
|
||||
bool parse_and_validate_block_from_blob(const blobdata& b_blob, block& b)
|
||||
{
|
||||
return t_unserializable_object_from_blob(b, b_blob);
|
||||
return parse_and_validate_object_from_blob(b_blob, b);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
size_t get_object_blobsize(const transaction& t)
|
||||
{
|
||||
size_t tx_blob_size = get_object_blobsize(static_cast<const transaction_prefix&>(t));
|
||||
return get_object_blobsize(t, tx_blob_size);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
size_t get_object_blobsize(const transaction& t, uint64_t prefix_blob_size)
|
||||
{
|
||||
size_t tx_blob_size = prefix_blob_size;
|
||||
|
||||
if (is_coinbase(t))
|
||||
return tx_blob_size;
|
||||
|
||||
// for purged tx, with empty signatures and attachments, this function should return the blob size
|
||||
// which the tx would have if the signatures and attachments were correctly filled with actual data
|
||||
|
||||
// 1. signatures
|
||||
bool separately_signed_tx = get_tx_flags(t) & TX_FLAG_SIGNATURE_MODE_SEPARATE;
|
||||
|
||||
tx_blob_size += tools::get_varint_packed_size(t.vin.size()); // size of transaction::signatures (equals to total inputs count)
|
||||
|
||||
for (size_t i = 0; i != t.vin.size(); i++)
|
||||
{
|
||||
size_t sig_count = get_input_expected_signatures_count(t.vin[i]);
|
||||
if (separately_signed_tx && i == t.vin.size() - 1)
|
||||
++sig_count; // count in one more signature for the last input in a complete separately signed tx
|
||||
tx_blob_size += tools::get_varint_packed_size(sig_count); // size of transaction::signatures[i]
|
||||
tx_blob_size += sizeof(crypto::signature) * sig_count; // size of signatures' data itself
|
||||
}
|
||||
|
||||
// 2. attachments (try to find extra_attachment_info in tx prefix and count it in if succeed)
|
||||
extra_attachment_info eai = AUTO_VAL_INIT(eai);
|
||||
bool got_eai = false;
|
||||
if (separately_signed_tx)
|
||||
{
|
||||
// for separately-signed tx, try to obtain extra_attachment_info from the last input's etc_details
|
||||
const std::vector<txin_etc_details_v>* p_etc_details = get_input_etc_details(t.vin.back());
|
||||
got_eai = p_etc_details != nullptr && get_type_in_variant_container(*p_etc_details, eai);
|
||||
}
|
||||
if (!got_eai)
|
||||
got_eai = get_type_in_variant_container(t.extra, eai); // then from the extra
|
||||
|
||||
if (got_eai)
|
||||
tx_blob_size += eai.sz; // sz is a size of whole serialized attachment blob, including attachments vector size
|
||||
else
|
||||
tx_blob_size += tools::get_varint_packed_size(static_cast<size_t>(0)); // no extra_attachment_info found - just add zero vector's size, 'cause it's serialized anyway
|
||||
|
||||
return tx_blob_size;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
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;
|
||||
get_transaction_hash(b.miner_tx, h);
|
||||
txs_ids.push_back(h);
|
||||
BOOST_FOREACH(auto& th, b.tx_hashes)
|
||||
txs_ids.push_back(th);
|
||||
return get_tx_tree_hash(txs_ids);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool is_service_tx(const transaction& tx)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -11,10 +11,12 @@
|
|||
#include <unordered_set>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "currency_protocol/currency_protocol_defs.h"
|
||||
|
||||
#include "account.h"
|
||||
#include "include_base_utils.h"
|
||||
|
||||
#include "currency_format_utils_abstract.h"
|
||||
#include "common/crypto_stream_operators.h"
|
||||
#include "currency_protocol/currency_protocol_defs.h"
|
||||
#include "crypto/crypto.h"
|
||||
#include "crypto/hash.h"
|
||||
#include "difficulty.h"
|
||||
|
|
@ -23,6 +25,8 @@
|
|||
#include "bc_payments_id_service.h"
|
||||
#include "bc_attachments_helpers_basic.h"
|
||||
#include "blockchain_storage_basic.h"
|
||||
#include "currency_format_utils_blocks.h"
|
||||
#include "currency_format_utils_transactions.h"
|
||||
|
||||
// ------ get_tx_type_definition -------------
|
||||
#define GUI_TX_TYPE_NORMAL 0
|
||||
|
|
@ -42,31 +46,8 @@
|
|||
|
||||
|
||||
|
||||
//------
|
||||
bool parse_hash256(const std::string str_hash, crypto::hash& hash);
|
||||
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 &print16(std::ostream &o, const T &v) {
|
||||
return o << "<" << epee::string_tools::pod_to_hex(v).substr(0, 5) << "..>";
|
||||
}
|
||||
|
||||
template <class T>
|
||||
std::string print16(const T &v) {
|
||||
return std::string("<") + epee::string_tools::pod_to_hex(v).substr(0, 5) + "..>";
|
||||
}
|
||||
|
||||
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); }
|
||||
}
|
||||
|
||||
namespace currency
|
||||
{
|
||||
|
|
@ -182,10 +163,6 @@ namespace currency
|
|||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
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);
|
||||
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,
|
||||
|
|
@ -234,14 +211,6 @@ namespace currency
|
|||
|
||||
bool is_tx_expired(const transaction& tx, uint64_t expiration_ts_median);
|
||||
|
||||
template<class t_type>
|
||||
std::string print_t_array(const std::vector<t_type>& vec)
|
||||
{
|
||||
std::stringstream ss;
|
||||
for (auto& v : vec)
|
||||
ss << v << " ";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
uint64_t get_string_uint64_hash(const std::string& str);
|
||||
bool construct_tx_out(const tx_destination_entry& de, const crypto::secret_key& tx_sec_key, size_t output_index, transaction& tx, std::set<uint16_t>& deriv_cache, uint8_t tx_outs_attr = CURRENCY_TO_KEY_OUT_RELAXED);
|
||||
|
|
@ -302,8 +271,6 @@ namespace currency
|
|||
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);
|
||||
bool derive_public_key_from_target_address(const account_public_address& destination_addr, const crypto::secret_key& tx_sec_key, size_t index, crypto::public_key& out_eph_public_key, crypto::key_derivation& derivation);
|
||||
bool derive_public_key_from_target_address(const account_public_address& destination_addr, const crypto::secret_key& tx_sec_key, size_t index, crypto::public_key& out_eph_public_key);
|
||||
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);
|
||||
bool is_mixattr_applicable_for_fake_outs_counter(uint8_t mix_attr, uint64_t fake_attr_count);
|
||||
bool is_tx_spendtime_unlocked(uint64_t unlock_time, uint64_t current_blockchain_size, uint64_t current_time);
|
||||
|
|
@ -316,13 +283,7 @@ namespace currency
|
|||
|
||||
uint64_t get_reward_from_miner_tx(const transaction& tx);
|
||||
|
||||
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, uint64_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 generate_genesis_block(block& bl);
|
||||
const crypto::hash& get_genesis_hash(bool need_to_set = false, const crypto::hash& h = null_hash);
|
||||
bool parse_and_validate_block_from_blob(const blobdata& b_blob, block& b);
|
||||
|
|
@ -390,18 +351,6 @@ namespace currency
|
|||
bool fill_block_rpc_details(block_rpc_extended_info& pei_rpc, const block_extended_info& bei_chain, const crypto::hash& h);
|
||||
void append_per_block_increments_for_tx(const transaction& tx, std::unordered_map<uint64_t, uint32_t>& gindices);
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/************************************************************************/
|
||||
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)]);
|
||||
}
|
||||
};
|
||||
|
||||
template<class t_txin_v>
|
||||
typename std::conditional<std::is_const<t_txin_v>::value, const std::vector<txin_etc_details_v>, std::vector<txin_etc_details_v> >::type& get_txin_etc_options(t_txin_v& in)
|
||||
{
|
||||
|
|
@ -450,17 +399,6 @@ namespace currency
|
|||
bool have_attachment_service_in_container(const std::vector<attachment_v>& av, const std::string& service_id, const std::string& instruction);
|
||||
crypto::hash prepare_prefix_hash_for_sign(const transaction& tx, uint64_t in_index, const crypto::hash& tx_id);
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
template<class t_pod_type, class result_type>
|
||||
result_type get_pod_checksum(const t_pod_type& bl)
|
||||
{
|
||||
const unsigned char* pbuf = reinterpret_cast<const unsigned char*>(&bl);
|
||||
result_type summ = 0;
|
||||
for (size_t i = 0; i != sizeof(t_pod_type)-1; i++)
|
||||
summ += pbuf[i];
|
||||
|
||||
return summ;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
template<class tx_out_t>
|
||||
bool is_out_to_acc(const account_keys& acc, const tx_out_t& out_key, const crypto::public_key& tx_pub_key, size_t output_index)
|
||||
|
|
@ -469,83 +407,6 @@ namespace currency
|
|||
generate_key_derivation(tx_pub_key, acc.m_view_secret_key, derivation);
|
||||
return is_out_to_acc(acc, out_key, derivation, output_index);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
template<typename specic_type_t, typename variant_t_container>
|
||||
bool have_type_in_variant_container(const variant_t_container& av)
|
||||
{
|
||||
for (auto& ai : av)
|
||||
{
|
||||
if (ai.type() == typeid(specic_type_t))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
template<typename specic_type_t, typename variant_t_container>
|
||||
size_t count_type_in_variant_container(const variant_t_container& av)
|
||||
{
|
||||
size_t result = 0;
|
||||
for (auto& ai : av)
|
||||
{
|
||||
if (ai.type() == typeid(specic_type_t))
|
||||
++result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
template<typename specic_type_t, typename variant_t_container>
|
||||
bool get_type_in_variant_container(const variant_t_container& av, specic_type_t& a)
|
||||
{
|
||||
for (auto& ai : av)
|
||||
{
|
||||
if (ai.type() == typeid(specic_type_t))
|
||||
{
|
||||
a = boost::get<specic_type_t>(ai);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
template<typename variant_container_t>
|
||||
bool check_allowed_types_in_variant_container(const variant_container_t& container, const std::unordered_set<std::type_index>& allowed_types, bool elements_must_be_unique = true)
|
||||
{
|
||||
for (auto it = container.begin(); it != container.end(); ++it)
|
||||
{
|
||||
if (allowed_types.count(std::type_index(it->type())) == 0)
|
||||
return false;
|
||||
|
||||
if (elements_must_be_unique)
|
||||
{
|
||||
for (auto jt = it + 1; jt != container.end(); ++jt)
|
||||
if (it->type().hash_code() == jt->type().hash_code())
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
template<typename variant_container_t>
|
||||
bool check_allowed_types_in_variant_container(const variant_container_t& container, const variant_container_t& allowed_types_examples, bool elements_must_be_unique = true)
|
||||
{
|
||||
std::unordered_set<std::type_index> allowed_types;
|
||||
for (auto& el : allowed_types_examples)
|
||||
if (!allowed_types.insert(std::type_index(el.type())).second)
|
||||
return false; // invalid allowed_types_examples container
|
||||
|
||||
return check_allowed_types_in_variant_container(container, allowed_types, elements_must_be_unique);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
template<typename variant_container_t>
|
||||
std::string stringize_types_in_variant_container(const variant_container_t& container)
|
||||
{
|
||||
std::string result;
|
||||
for (auto it = container.begin(); it != container.end(); ++it)
|
||||
result = (result + it->type().name()) + (it + 1 != container.end() ? ", " : "");
|
||||
return result;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template<class t_container>
|
||||
bool validate_attachment_info(const t_container& container, const std::vector<attachment_v>& attachments, bool allow_no_info_for_non_empty_attachments_container)
|
||||
|
|
@ -692,51 +553,7 @@ namespace currency
|
|||
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
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>
|
||||
crypto::hash get_object_hash(const t_object& o)
|
||||
{
|
||||
crypto::hash h;
|
||||
get_object_hash(o, h);
|
||||
return h;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
|
||||
template<class t_object>
|
||||
size_t get_object_blobsize(const t_object& o)
|
||||
{
|
||||
blobdata b = t_serializable_object_to_blob(o);
|
||||
return b.size();
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
size_t get_object_blobsize(const transaction& t);
|
||||
size_t get_object_blobsize(const transaction& t, uint64_t prefix_blob_size);
|
||||
//---------------------------------------------------------------
|
||||
template<class t_object>
|
||||
bool get_object_hash(const t_object& o, crypto::hash& res, uint64_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(const T& obj)
|
||||
{
|
||||
std::stringstream ss;
|
||||
json_archive<true> ar(ss, true);
|
||||
bool r = ::serialization::serialize(ar, const_cast<T&>(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>
|
||||
|
|
@ -843,18 +660,6 @@ namespace currency
|
|||
}
|
||||
//---------------------------------------------------------------
|
||||
|
||||
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);
|
||||
|
||||
#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);
|
||||
|
||||
struct input_amount_getter : public boost::static_visitor<uint64_t>
|
||||
{
|
||||
template<class t_input>
|
||||
|
|
@ -866,7 +671,6 @@ namespace currency
|
|||
{
|
||||
return boost::apply_visitor(input_amount_getter(), v);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
std::ostream& operator <<(std::ostream& o, const ref_by_id& r);
|
||||
//---------------------------------------------------------------
|
||||
|
|
|
|||
217
src/currency_core/currency_format_utils_abstract.h
Normal file
217
src/currency_core/currency_format_utils_abstract.h
Normal file
|
|
@ -0,0 +1,217 @@
|
|||
// Copyright (c) 2018-2019 Zano Project
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <typeindex>
|
||||
#include <unordered_set>
|
||||
#include <unordered_map>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
|
||||
|
||||
#include "include_base_utils.h"
|
||||
#include "serialization/keyvalue_serialization.h"
|
||||
#include "crypto/crypto.h"
|
||||
#include "crypto/hash.h"
|
||||
#include "currency_core/currency_basic.h"
|
||||
#include "currency_protocol/blobdatatype.h"
|
||||
#include "common/crypto_stream_operators.h"
|
||||
|
||||
namespace currency
|
||||
{
|
||||
|
||||
template<typename type_t>
|
||||
std::string print_kv_structure(const type_t& v)
|
||||
{
|
||||
return epee::serialization::store_t_to_json(v);
|
||||
}
|
||||
|
||||
template<class t_type>
|
||||
std::string print_t_array(const std::vector<t_type>& vec)
|
||||
{
|
||||
std::stringstream ss;
|
||||
for (auto& v : vec)
|
||||
ss << v << " ";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/************************************************************************/
|
||||
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)]);
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
template<class t_pod_type, class result_type>
|
||||
result_type get_pod_checksum(const t_pod_type& bl)
|
||||
{
|
||||
const unsigned char* pbuf = reinterpret_cast<const unsigned char*>(&bl);
|
||||
result_type summ = 0;
|
||||
for (size_t i = 0; i != sizeof(t_pod_type)-1; i++)
|
||||
summ += pbuf[i];
|
||||
|
||||
return summ;
|
||||
}
|
||||
|
||||
template<typename object_t>
|
||||
bool parse_and_validate_object_from_blob(const blobdata& b_blob, object_t& b)
|
||||
{
|
||||
return t_unserializable_object_from_blob(b, b_blob);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
template<typename specic_type_t, typename variant_t_container>
|
||||
bool have_type_in_variant_container(const variant_t_container& av)
|
||||
{
|
||||
for (auto& ai : av)
|
||||
{
|
||||
if (ai.type() == typeid(specic_type_t))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
template<typename specic_type_t, typename variant_t_container>
|
||||
size_t count_type_in_variant_container(const variant_t_container& av)
|
||||
{
|
||||
size_t result = 0;
|
||||
for (auto& ai : av)
|
||||
{
|
||||
if (ai.type() == typeid(specic_type_t))
|
||||
++result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
template<typename specic_type_t, typename variant_t_container>
|
||||
bool get_type_in_variant_container(const variant_t_container& av, specic_type_t& a)
|
||||
{
|
||||
for (auto& ai : av)
|
||||
{
|
||||
if (ai.type() == typeid(specic_type_t))
|
||||
{
|
||||
a = boost::get<specic_type_t>(ai);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
template<typename variant_container_t>
|
||||
bool check_allowed_types_in_variant_container(const variant_container_t& container, const std::unordered_set<std::type_index>& allowed_types, bool elements_must_be_unique = true)
|
||||
{
|
||||
for (auto it = container.begin(); it != container.end(); ++it)
|
||||
{
|
||||
if (allowed_types.count(std::type_index(it->type())) == 0)
|
||||
return false;
|
||||
|
||||
if (elements_must_be_unique)
|
||||
{
|
||||
for (auto jt = it + 1; jt != container.end(); ++jt)
|
||||
if (it->type().hash_code() == jt->type().hash_code())
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
template<typename variant_container_t>
|
||||
bool check_allowed_types_in_variant_container(const variant_container_t& container, const variant_container_t& allowed_types_examples, bool elements_must_be_unique = true)
|
||||
{
|
||||
std::unordered_set<std::type_index> allowed_types;
|
||||
for (auto& el : allowed_types_examples)
|
||||
if (!allowed_types.insert(std::type_index(el.type())).second)
|
||||
return false; // invalid allowed_types_examples container
|
||||
|
||||
return check_allowed_types_in_variant_container(container, allowed_types, elements_must_be_unique);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
template<typename variant_container_t>
|
||||
std::string stringize_types_in_variant_container(const variant_container_t& container)
|
||||
{
|
||||
std::string result;
|
||||
for (auto it = container.begin(); it != container.end(); ++it)
|
||||
result = (result + it->type().name()) + (it + 1 != container.end() ? ", " : "");
|
||||
return result;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
inline
|
||||
void get_blob_hash(const blobdata& blob, crypto::hash& res)
|
||||
{
|
||||
cn_fast_hash(blob.data(), blob.size(), res);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
inline
|
||||
crypto::hash get_blob_hash(const blobdata& blob)
|
||||
{
|
||||
crypto::hash h = null_hash;
|
||||
get_blob_hash(blob, h);
|
||||
return h;
|
||||
}
|
||||
|
||||
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>
|
||||
crypto::hash get_object_hash(const t_object& o)
|
||||
{
|
||||
crypto::hash h;
|
||||
get_object_hash(o, h);
|
||||
return h;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
|
||||
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, uint64_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(const T& obj)
|
||||
{
|
||||
std::stringstream ss;
|
||||
json_archive<true> ar(ss, true);
|
||||
bool r = ::serialization::serialize(ar, const_cast<T&>(obj));
|
||||
CHECK_AND_ASSERT_MES(r, "", "obj_to_json_str failed: serialization::serialize returned false");
|
||||
return ss.str();
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
|
||||
//---------------------------------------------------------------
|
||||
size_t get_object_blobsize(const transaction& t);
|
||||
size_t get_object_blobsize(const transaction& t, uint64_t prefix_blob_size);
|
||||
|
||||
|
||||
|
||||
#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);
|
||||
|
||||
} // namespace currency
|
||||
|
||||
|
||||
|
||||
67
src/currency_core/currency_format_utils_blocks.cpp
Normal file
67
src/currency_core/currency_format_utils_blocks.cpp
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
// Copyright (c) 2018-2019 Zano Project
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
|
||||
#include "currency_format_utils_blocks.h"
|
||||
#include "serialization/serialization.h"
|
||||
#include "currency_format_utils_abstract.h"
|
||||
#include "currency_format_utils_transactions.h"
|
||||
namespace currency
|
||||
{
|
||||
//---------------------------------------------------------------
|
||||
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((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)
|
||||
{
|
||||
return get_object_hash(get_block_hashing_blob(b), res);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
crypto::hash get_block_hash(const block& b)
|
||||
{
|
||||
crypto::hash p = null_hash;
|
||||
get_block_hash(b, p);
|
||||
return p;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
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);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
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;
|
||||
get_transaction_hash(b.miner_tx, h);
|
||||
txs_ids.push_back(h);
|
||||
BOOST_FOREACH(auto& th, b.tx_hashes)
|
||||
txs_ids.push_back(th);
|
||||
return get_tx_tree_hash(txs_ids);
|
||||
}
|
||||
}
|
||||
25
src/currency_core/currency_format_utils_blocks.h
Normal file
25
src/currency_core/currency_format_utils_blocks.h
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
// Copyright (c) 2018-2019 Zano Project
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "include_base_utils.h"
|
||||
#include "crypto/crypto.h"
|
||||
#include "currency_core/currency_basic.h"
|
||||
#include "currency_protocol/blobdatatype.h"
|
||||
|
||||
namespace currency
|
||||
{
|
||||
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);
|
||||
|
||||
blobdata block_to_blob(const block& b);
|
||||
bool block_to_blob(const block& 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);
|
||||
|
||||
}
|
||||
134
src/currency_core/currency_format_utils_transactions.cpp
Normal file
134
src/currency_core/currency_format_utils_transactions.cpp
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
// Copyright (c) 2018-2019 Zano Project
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
|
||||
#include "currency_format_utils_transactions.h"
|
||||
#include "serialization/serialization.h"
|
||||
#include "currency_format_utils_abstract.h"
|
||||
#include "currency_format_utils.h"
|
||||
|
||||
namespace currency
|
||||
{
|
||||
//---------------------------------------------------------------
|
||||
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));
|
||||
std::string data = s.str();
|
||||
crypto::cn_fast_hash(data.data(), data.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)
|
||||
{
|
||||
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
|
||||
|
||||
//crypto::cn_fast_hash(tx_blob.data(), tx_blob.size(), tx_hash);
|
||||
get_transaction_prefix_hash(tx, tx_hash);
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
crypto::hash get_transaction_hash(const transaction& t)
|
||||
{
|
||||
return get_transaction_prefix_hash(t);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool get_transaction_hash(const transaction& t, crypto::hash& res)
|
||||
{
|
||||
uint64_t blob_size = 0;
|
||||
return get_object_hash(static_cast<const transaction_prefix&>(t), res, blob_size);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool get_transaction_hash(const transaction& t, crypto::hash& res, uint64_t& blob_size)
|
||||
{
|
||||
blob_size = 0;
|
||||
bool r = get_object_hash(static_cast<const transaction_prefix&>(t), res, blob_size);
|
||||
blob_size = get_object_blobsize(t, blob_size);
|
||||
return r;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
size_t get_object_blobsize(const transaction& t)
|
||||
{
|
||||
size_t tx_blob_size = get_object_blobsize(static_cast<const transaction_prefix&>(t));
|
||||
return get_object_blobsize(t, tx_blob_size);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
size_t get_object_blobsize(const transaction& t, uint64_t prefix_blob_size)
|
||||
{
|
||||
size_t tx_blob_size = prefix_blob_size;
|
||||
|
||||
if (is_coinbase(t))
|
||||
return tx_blob_size;
|
||||
|
||||
// for purged tx, with empty signatures and attachments, this function should return the blob size
|
||||
// which the tx would have if the signatures and attachments were correctly filled with actual data
|
||||
|
||||
// 1. signatures
|
||||
bool separately_signed_tx = get_tx_flags(t) & TX_FLAG_SIGNATURE_MODE_SEPARATE;
|
||||
|
||||
tx_blob_size += tools::get_varint_packed_size(t.vin.size()); // size of transaction::signatures (equals to total inputs count)
|
||||
|
||||
for (size_t i = 0; i != t.vin.size(); i++)
|
||||
{
|
||||
size_t sig_count = get_input_expected_signatures_count(t.vin[i]);
|
||||
if (separately_signed_tx && i == t.vin.size() - 1)
|
||||
++sig_count; // count in one more signature for the last input in a complete separately signed tx
|
||||
tx_blob_size += tools::get_varint_packed_size(sig_count); // size of transaction::signatures[i]
|
||||
tx_blob_size += sizeof(crypto::signature) * sig_count; // size of signatures' data itself
|
||||
}
|
||||
|
||||
// 2. attachments (try to find extra_attachment_info in tx prefix and count it in if succeed)
|
||||
extra_attachment_info eai = AUTO_VAL_INIT(eai);
|
||||
bool got_eai = false;
|
||||
if (separately_signed_tx)
|
||||
{
|
||||
// for separately-signed tx, try to obtain extra_attachment_info from the last input's etc_details
|
||||
const std::vector<txin_etc_details_v>* p_etc_details = get_input_etc_details(t.vin.back());
|
||||
got_eai = p_etc_details != nullptr && get_type_in_variant_container(*p_etc_details, eai);
|
||||
}
|
||||
if (!got_eai)
|
||||
got_eai = get_type_in_variant_container(t.extra, eai); // then from the extra
|
||||
|
||||
if (got_eai)
|
||||
tx_blob_size += eai.sz; // sz is a size of whole serialized attachment blob, including attachments vector size
|
||||
else
|
||||
tx_blob_size += tools::get_varint_packed_size(static_cast<size_t>(0)); // no extra_attachment_info found - just add zero vector's size, 'cause it's serialized anyway
|
||||
|
||||
return tx_blob_size;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
27
src/currency_core/currency_format_utils_transactions.h
Normal file
27
src/currency_core/currency_format_utils_transactions.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
// Copyright (c) 2018-2019 Zano Project
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "include_base_utils.h"
|
||||
#include "crypto/crypto.h"
|
||||
#include "currency_core/currency_basic.h"
|
||||
#include "currency_protocol/blobdatatype.h"
|
||||
|
||||
|
||||
namespace currency
|
||||
{
|
||||
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);
|
||||
bool parse_and_validate_tx_from_blob(const blobdata& tx_blob, transaction& tx);
|
||||
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, uint64_t& blob_size);
|
||||
size_t get_object_blobsize(const transaction& t);
|
||||
size_t get_object_blobsize(const transaction& t, uint64_t prefix_blob_size);
|
||||
blobdata tx_to_blob(const transaction& b);
|
||||
bool tx_to_blob(const transaction& b, blobdata& b_blob);
|
||||
}
|
||||
|
|
@ -104,7 +104,7 @@ namespace currency
|
|||
{
|
||||
std::list<blobdata> txs;
|
||||
std::list<block_complete_entry> blocks;
|
||||
std::list<crypto::hash> missed_ids;
|
||||
std::list<crypto::hash> missed_ids;
|
||||
uint64_t current_blockchain_height;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
|
|
@ -168,3 +168,5 @@ namespace currency
|
|||
};
|
||||
|
||||
}
|
||||
|
||||
#include "currency_protocol_defs_print.h"
|
||||
|
|
|
|||
44
src/currency_protocol/currency_protocol_defs_print.h
Normal file
44
src/currency_protocol/currency_protocol_defs_print.h
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
// Copyright (c) 2014-2018 Zano Project
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "currency_core/currency_format_utils_abstract.h"
|
||||
#include "currency_core/currency_format_utils_blocks.h"
|
||||
#include "storages/portable_storage_to_json.h"
|
||||
|
||||
namespace currency
|
||||
{
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
inline std::string print_complete_block_entry_list(const std::list<block_complete_entry>& blocks)
|
||||
{
|
||||
std::stringstream ss;
|
||||
size_t i = 0;
|
||||
for (const block_complete_entry& block_entry : blocks)
|
||||
{
|
||||
ss << "[" << i << "]";
|
||||
block b = AUTO_VAL_INIT(b);
|
||||
if (!parse_and_validate_object_from_blob(block_entry.block, b))
|
||||
{
|
||||
ss << "UNPARSED" << ENDL;
|
||||
}
|
||||
ss << get_block_hash(b) << ", parent: " << b.prev_id;
|
||||
|
||||
i++;
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
inline
|
||||
std::string print_kv_structure(const NOTIFY_RESPONSE_GET_OBJECTS::request& v)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "\"blocks\":{" << ENDL << print_complete_block_entry_list(v.blocks) << ENDL << "}, " << ENDL;
|
||||
ss << "\"missed_ids\":" << ENDL;
|
||||
::epee::serialization::dump_as_json(ss, v.missed_ids, 2);
|
||||
ss << ENDL << "\"current_blockchain_height\":" << v.current_blockchain_height;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2014-2018 Zano Project
|
||||
// Copyright (c) 2014-2018 Zano Project
|
||||
// Copyright (c) 2014-2018 The Louisdor Project
|
||||
// Copyright (c) 2012-2013 The Cryptonote developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
|
|
@ -355,6 +355,8 @@ namespace currency
|
|||
template<class t_core>
|
||||
int t_currency_protocol_handler<t_core>::handle_request_get_objects(int command, NOTIFY_REQUEST_GET_OBJECTS::request& arg, currency_connection_context& context)
|
||||
{
|
||||
LOG_PRINT_L3("[HANDLE]NOTIFY_REQUEST_GET_OBJECTS: " << ENDL << currency::print_kv_structure(arg));
|
||||
|
||||
if (arg.blocks.size() > CURRENCY_PROTOCOL_MAX_BLOCKS_REQUEST_COUNT)
|
||||
{
|
||||
LOG_ERROR_CCONTEXT("Requested objects count is to big (" << arg.blocks.size() <<")expected not more then " << CURRENCY_PROTOCOL_MAX_BLOCKS_REQUEST_COUNT);
|
||||
|
|
@ -367,8 +369,12 @@ namespace currency
|
|||
LOG_ERROR_CCONTEXT("failed to handle request NOTIFY_REQUEST_GET_OBJECTS, dropping connection");
|
||||
m_p2p->drop_connection(context);
|
||||
}
|
||||
LOG_PRINT_L2("[HANDLE]NOTIFY_RESPONSE_GET_OBJECTS: blocks.size()=" << rsp.blocks.size() << ", txs.size()=" << rsp.txs.size()
|
||||
|
||||
LOG_PRINT_L2("[HANDLE]NOTIFY_REQUEST_GET_OBJECTS, response NOTIFY_RESPONSE_GET_OBJECTS: blocks.size()=" << rsp.blocks.size() << ", txs.size()=" << rsp.txs.size()
|
||||
<< ", rsp.m_current_blockchain_height=" << rsp.current_blockchain_height << ", missed_ids.size()=" << rsp.missed_ids.size());
|
||||
|
||||
|
||||
LOG_PRINT_L3("[NOTIFY]NOTIFY_RESPONSE_GET_OBJECTS: " << ENDL << currency::print_kv_structure(rsp));
|
||||
post_notify<NOTIFY_RESPONSE_GET_OBJECTS>(rsp, context);
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -383,11 +389,16 @@ namespace currency
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#define CHECK_STOP_FLAG__DROP_AND_RETURN_IF_SET(ret_v, msg) if (check_stop_flag_and_drop_cc(context)) { LOG_PRINT_YELLOW("Stop flag detected within NOTIFY_RESPONSE_GET_OBJECTS. " << msg, LOG_LEVEL_0); return ret_v; }
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
template<class t_core>
|
||||
int t_currency_protocol_handler<t_core>::handle_response_get_objects(int command, NOTIFY_RESPONSE_GET_OBJECTS::request& arg, currency_connection_context& context)
|
||||
{
|
||||
LOG_PRINT_L3("[HANDLE]NOTIFY_RESPONSE_GET_OBJECTS: " << ENDL << currency::print_kv_structure(arg));
|
||||
LOG_PRINT_L2("NOTIFY_RESPONSE_GET_OBJECTS");
|
||||
if(context.m_last_response_height > arg.current_blockchain_height)
|
||||
{
|
||||
|
|
@ -511,7 +522,8 @@ namespace currency
|
|||
}
|
||||
if(bvc.m_marked_as_orphaned)
|
||||
{
|
||||
LOG_PRINT_L0("Block received at sync phase was marked as orphaned, dropping connection");
|
||||
LOG_PRINT_L0("Block received at sync phase was marked as orphaned, dropping connection, details on response: " << ENDL << print_kv_structure(arg));
|
||||
|
||||
m_p2p->drop_connection(context);
|
||||
m_p2p->add_ip_fail(context.m_remote_ip);
|
||||
return 1;
|
||||
|
|
@ -600,6 +612,7 @@ namespace currency
|
|||
}
|
||||
|
||||
LOG_PRINT_L2("[REQUESTING]NOTIFY_REQUEST_GET_OBJECTS: requested_cumulative_size=" << requested_cumulative_size << ", blocks.size()=" << req.blocks.size() << ", txs.size()=" << req.txs.size());
|
||||
LOG_PRINT_L3("[NOTIFY]NOTIFY_REQUEST_GET_OBJECTS: " << ENDL << currency::print_kv_structure(req));
|
||||
post_notify<NOTIFY_REQUEST_GET_OBJECTS>(req, context);
|
||||
}else if(context.m_last_response_height < context.m_remote_blockchain_height-1)
|
||||
{//we have to fetch more objects ids, request blockchain entry
|
||||
|
|
@ -725,6 +738,7 @@ namespace currency
|
|||
template<class t_core>
|
||||
int t_currency_protocol_handler<t_core>::handle_response_chain_entry(int command, NOTIFY_RESPONSE_CHAIN_ENTRY::request& arg, currency_connection_context& context)
|
||||
{
|
||||
LOG_PRINT_L3("[HANDLE]NOTIFY_RESPONSE_CHAIN_ENTRY: " << ENDL << currency::print_kv_structure(arg));
|
||||
LOG_PRINT_L2("NOTIFY_RESPONSE_CHAIN_ENTRY: m_block_ids.size()=" << arg.m_block_ids.size()
|
||||
<< ", m_start_height=" << arg.start_height << ", m_total_height=" << arg.total_height);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue