aboutsummaryrefslogtreecommitdiff
path: root/src/cryptonote_basic
diff options
context:
space:
mode:
authorLee Clagett <code@leeclagett.com>2021-01-24 07:42:57 +0000
committerLee Clagett <code@leeclagett.com>2021-01-23 06:23:39 +0000
commit08e4497c6e3b3f434c0bb255c3942648f153fe66 (patch)
tree2564f4214e9e66b2dc03ce3c788bb080b963be56 /src/cryptonote_basic
parentMerge pull request #7669 (diff)
downloadmonero-08e4497c6e3b3f434c0bb255c3942648f153fe66.tar.xz
Improve cryptonote (block and tx) binary read performance
Diffstat (limited to 'src/cryptonote_basic')
-rw-r--r--src/cryptonote_basic/cryptonote_basic.h20
-rw-r--r--src/cryptonote_basic/cryptonote_format_utils.cpp60
-rw-r--r--src/cryptonote_basic/cryptonote_format_utils.h4
-rw-r--r--src/cryptonote_basic/tx_extra.h9
4 files changed, 26 insertions, 67 deletions
diff --git a/src/cryptonote_basic/cryptonote_basic.h b/src/cryptonote_basic/cryptonote_basic.h
index c70ae1df1..6394a7071 100644
--- a/src/cryptonote_basic/cryptonote_basic.h
+++ b/src/cryptonote_basic/cryptonote_basic.h
@@ -152,10 +152,6 @@ namespace cryptonote
};
- template<typename T> static inline unsigned int getpos(T &ar) { return 0; }
- template<> inline unsigned int getpos(binary_archive<true> &ar) { return ar.stream().tellp(); }
- template<> inline unsigned int getpos(binary_archive<false> &ar) { return ar.stream().tellg(); }
-
class transaction_prefix
{
@@ -236,17 +232,17 @@ namespace cryptonote
set_blob_size_valid(false);
}
- const unsigned int start_pos = getpos(ar);
+ const auto start_pos = ar.getpos();
FIELDS(*static_cast<transaction_prefix *>(this))
if (std::is_same<Archive<W>, binary_archive<W>>())
- prefix_size = getpos(ar) - start_pos;
+ prefix_size = ar.getpos() - start_pos;
if (version == 1)
{
if (std::is_same<Archive<W>, binary_archive<W>>())
- unprunable_size = getpos(ar) - start_pos;
+ unprunable_size = ar.getpos() - start_pos;
ar.tag("signatures");
ar.begin_array();
@@ -284,11 +280,11 @@ namespace cryptonote
{
ar.begin_object();
bool r = rct_signatures.serialize_rctsig_base(ar, vin.size(), vout.size());
- if (!r || !ar.stream().good()) return false;
+ if (!r || !ar.good()) return false;
ar.end_object();
if (std::is_same<Archive<W>, binary_archive<W>>())
- unprunable_size = getpos(ar) - start_pos;
+ unprunable_size = ar.getpos() - start_pos;
if (!pruned && rct_signatures.type != rct::RCTTypeNull)
{
@@ -296,7 +292,7 @@ namespace cryptonote
ar.begin_object();
r = rct_signatures.p.serialize_rctsig_prunable(ar, rct_signatures.type, vin.size(), vout.size(),
vin.size() > 0 && 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;
+ if (!r || !ar.good()) return false;
ar.end_object();
}
}
@@ -320,13 +316,13 @@ namespace cryptonote
{
ar.begin_object();
bool r = rct_signatures.serialize_rctsig_base(ar, vin.size(), vout.size());
- if (!r || !ar.stream().good()) return false;
+ if (!r || !ar.good()) return false;
ar.end_object();
}
}
if (!typename Archive<W>::is_saving())
pruned = true;
- return ar.stream().good();
+ return ar.good();
}
private:
diff --git a/src/cryptonote_basic/cryptonote_format_utils.cpp b/src/cryptonote_basic/cryptonote_format_utils.cpp
index b0c4a25d8..5cd40ce79 100644
--- a/src/cryptonote_basic/cryptonote_format_utils.cpp
+++ b/src/cryptonote_basic/cryptonote_format_utils.cpp
@@ -211,9 +211,7 @@ namespace cryptonote
//---------------------------------------------------------------
bool parse_and_validate_tx_from_blob(const blobdata_ref& tx_blob, transaction& tx)
{
- std::stringstream ss;
- ss << tx_blob;
- binary_archive<false> ba(ss);
+ binary_archive<false> ba{epee::strspan<std::uint8_t>(tx_blob)};
bool r = ::serialization::serialize(ba, tx);
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");
@@ -224,9 +222,7 @@ namespace cryptonote
//---------------------------------------------------------------
bool parse_and_validate_tx_base_from_blob(const blobdata_ref& tx_blob, transaction& tx)
{
- std::stringstream ss;
- ss << tx_blob;
- binary_archive<false> ba(ss);
+ binary_archive<false> ba{epee::strspan<std::uint8_t>(tx_blob)};
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");
@@ -236,9 +232,7 @@ namespace cryptonote
//---------------------------------------------------------------
bool parse_and_validate_tx_prefix_from_blob(const blobdata_ref& tx_blob, transaction_prefix& tx)
{
- std::stringstream ss;
- ss << tx_blob;
- binary_archive<false> ba(ss);
+ binary_archive<false> ba{epee::strspan<std::uint8_t>(tx_blob)};
bool r = ::serialization::serialize_noeof(ba, tx);
CHECK_AND_ASSERT_MES(r, false, "Failed to parse transaction prefix from blob");
return true;
@@ -246,9 +240,7 @@ namespace cryptonote
//---------------------------------------------------------------
bool parse_and_validate_tx_from_blob(const blobdata_ref& tx_blob, transaction& tx, crypto::hash& tx_hash)
{
- std::stringstream ss;
- ss << tx_blob;
- binary_archive<false> ba(ss);
+ binary_archive<false> ba{epee::strspan<std::uint8_t>(tx_blob)};
bool r = ::serialization::serialize(ba, tx);
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");
@@ -532,22 +524,15 @@ namespace cryptonote
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);
+ binary_archive<false> ar{epee::to_span(tx_extra)};
- bool eof = false;
- while (!eof)
+ do
{
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);
- }
+ } while (!ar.eof());
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;
@@ -578,13 +563,10 @@ namespace cryptonote
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);
+ binary_archive<false> ar{epee::to_span(tx_extra)};
- bool eof = false;
size_t processed = 0;
- while (!eof)
+ do
{
tx_extra_field field;
bool r = ::do_serialize(ar, field);
@@ -596,12 +578,8 @@ namespace cryptonote
break;
}
tx_extra_fields.push_back(field);
- processed = iss.tellg();
-
- std::ios_base::iostate state = iss.rdstate();
- eof = (EOF == iss.peek());
- iss.clear(state);
- }
+ processed = ar.getpos();
+ } while (!ar.eof());
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())));
@@ -752,24 +730,18 @@ namespace cryptonote
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);
+ binary_archive<false> ar{epee::strspan<std::uint8_t>(extra_str)};
std::ostringstream oss;
binary_archive<true> newar(oss);
- bool eof = false;
- while (!eof)
+ do
{
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);
- }
+ } while (!ar.eof());
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();
@@ -1357,9 +1329,7 @@ namespace cryptonote
//---------------------------------------------------------------
bool parse_and_validate_block_from_blob(const blobdata_ref& b_blob, block& b, crypto::hash *block_hash)
{
- std::stringstream ss;
- ss << b_blob;
- binary_archive<false> ba(ss);
+ binary_archive<false> ba{epee::strspan<std::uint8_t>(b_blob)};
bool r = ::serialization::serialize(ba, b);
CHECK_AND_ASSERT_MES(r, false, "Failed to parse block from blob");
b.invalidate_hashes();
diff --git a/src/cryptonote_basic/cryptonote_format_utils.h b/src/cryptonote_basic/cryptonote_format_utils.h
index b311bd2b2..3fe4c44e7 100644
--- a/src/cryptonote_basic/cryptonote_format_utils.h
+++ b/src/cryptonote_basic/cryptonote_format_utils.h
@@ -148,9 +148,7 @@ namespace cryptonote
template<class t_object>
bool t_serializable_object_from_blob(t_object& to, const blobdata& b_blob)
{
- std::stringstream ss;
- ss << b_blob;
- binary_archive<false> ba(ss);
+ binary_archive<false> ba{epee::strspan<std::uint8_t>(b_blob)};
bool r = ::serialization::serialize(ba, to);
return r;
}
diff --git a/src/cryptonote_basic/tx_extra.h b/src/cryptonote_basic/tx_extra.h
index 50f2e1438..76efc22d3 100644
--- a/src/cryptonote_basic/tx_extra.h
+++ b/src/cryptonote_basic/tx_extra.h
@@ -57,11 +57,7 @@ namespace cryptonote
// 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)
+ if (ar.eof())
break;
uint8_t zero;
@@ -139,8 +135,7 @@ namespace cryptonote
if(!::do_serialize(ar, field))
return false;
- std::istringstream iss(field);
- binary_archive<false> iar(iss);
+ binary_archive<false> iar{epee::strspan<std::uint8_t>(field)};
serialize_helper helper(*this);
return ::serialization::serialize(iar, helper);
}