aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt15
-rw-r--r--README.md2
-rwxr-xr-xcontrib/snap/daemon.bash12
-rwxr-xr-xcontrib/snap/log.bash3
-rwxr-xr-xcontrib/snap/wallet.bash7
-rw-r--r--snapcraft.yaml73
-rw-r--r--src/cryptonote_core/cryptonote_basic.h28
-rw-r--r--src/cryptonote_core/cryptonote_boost_serialization.h16
-rw-r--r--src/cryptonote_core/cryptonote_format_utils.cpp42
-rw-r--r--src/daemon/CMakeLists.txt1
-rw-r--r--src/daemon/rpc_command_executor.cpp2
-rw-r--r--src/ringct/rctSigs.cpp11
-rw-r--r--src/ringct/rctTypes.h155
-rw-r--r--src/simplewallet/CMakeLists.txt3
-rw-r--r--src/wallet/wallet2.cpp14
-rw-r--r--tests/unit_tests/serialization.cpp7
16 files changed, 307 insertions, 84 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0b0ce5a4e..1f6c9f8d0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -502,12 +502,15 @@ else()
# -DCHOST=... or -DCMAKE_AR=... and -DCMAKE_RANLIB=...
if (DEFINED CHOST)
set(CHOST_PREFIX "${CHOST}-")
- endif()
- if (NOT DEFINED CMAKE_AR)
- set(CMAKE_AR "${CHOST_PREFIX}gcc-ar")
- endif()
- if (NOT DEFINED CMAKE_RANLIB)
- set(CMAKE_RANLIB "${CHOST_PREFIX}gcc-ranlib")
+ if (NOT DEFINED CMAKE_AR)
+ set(CMAKE_AR "${CHOST_PREFIX}gcc-ar")
+ endif()
+ if (NOT DEFINED CMAKE_RANLIB)
+ set(CMAKE_RANLIB "${CHOST_PREFIX}gcc-ranlib")
+ endif()
+ else()
+ set(CMAKE_AR "gcc-ar")
+ set(CMAKE_RANLIB "gcc-ranlib")
endif()
endif()
endif()
diff --git a/README.md b/README.md
index 8a6a253f0..bcb61c948 100644
--- a/README.md
+++ b/README.md
@@ -66,7 +66,7 @@ Packages are available for
* OS X via [Homebrew](http://brew.sh)
brew tap sammy007/cryptonight
- brew install bitmonero --build-from-source
+ brew install monero --build-from-source
* Docker
diff --git a/contrib/snap/daemon.bash b/contrib/snap/daemon.bash
new file mode 100755
index 000000000..41d1275de
--- /dev/null
+++ b/contrib/snap/daemon.bash
@@ -0,0 +1,12 @@
+#!/bin/bash -e
+
+export LD_LIBRARY_PATH=${SNAP_LIBRARY_PATH}:${SNAP}/usr/lib/x86_64-linux-gnu
+export HOME=${SNAP_DATA}
+cd ${SNAP_DATA}
+
+ARGS=
+if [ -e "${SNAP_DATA}/etc/monerod.conf" ]; then
+ ARGS="--config-file ${SNAP_DATA}/etc/monerod.conf"
+fi
+
+exec ${SNAP}/bin/monerod --detach $ARGS
diff --git a/contrib/snap/log.bash b/contrib/snap/log.bash
new file mode 100755
index 000000000..c81efeb2c
--- /dev/null
+++ b/contrib/snap/log.bash
@@ -0,0 +1,3 @@
+#!/bin/bash -e
+
+exec tail -c +0 -F ${SNAP_DATA}/.bitmonero/bitmonero.log
diff --git a/contrib/snap/wallet.bash b/contrib/snap/wallet.bash
new file mode 100755
index 000000000..004f1371e
--- /dev/null
+++ b/contrib/snap/wallet.bash
@@ -0,0 +1,7 @@
+#!/bin/bash -e
+
+export LD_LIBRARY_PATH=${SNAP_LIBRARY_PATH}:${SNAP}/usr/lib/x86_64-linux-gnu
+export HOME=${SNAP_USER_DATA}
+cd ${SNAP_USER_DATA}
+
+exec ${SNAP}/usr/bin/rlwrap ${SNAP}/bin/monero-wallet-cli "$@"
diff --git a/snapcraft.yaml b/snapcraft.yaml
new file mode 100644
index 000000000..2ad7ad603
--- /dev/null
+++ b/snapcraft.yaml
@@ -0,0 +1,73 @@
+name: monero
+version: 0 # TODO: change this to release version in CI builds
+summary: "Monero: the secure, private, untraceable cryptocurrency https://getmonero.org"
+description: |
+ Monero is a private, secure, untraceable, decentralised digital currency.
+ You are your bank, you control your funds, and nobody can trace your transfers
+ unless you allow them to do so.
+grade: devel
+confinement: strict
+
+apps:
+ d:
+ daemon: forking
+ command: daemon.bash
+ plugs:
+ - network
+ - network-bind
+
+ log:
+ command: log.bash
+
+ monero:
+ command: wallet.bash
+ plugs:
+ - network
+
+parts:
+ wrapper:
+ plugin: dump
+ source: .
+ stage-packages:
+ - rlwrap
+ organize:
+ contrib/snap/daemon.bash: daemon.bash
+ contrib/snap/log.bash: log.bash
+ contrib/snap/wallet.bash: wallet.bash
+ snap:
+ - daemon.bash
+ - log.bash
+ - wallet.bash
+ - usr/bin/rlwrap
+
+ cmake-build:
+ plugin: cmake
+ configflags:
+ - -DBDB_STATIC=1
+ - -DUPNP_STATIC=1
+ - -DBoost_USE_STATIC_LIBS=1
+ - -DBoost_USE_STATIC_RUNTIME=1
+ - -DARCH=default
+ source: .
+ build-packages:
+ - gcc
+ - cmake
+ - pkg-config
+ - libunbound-dev
+ - libevent-dev
+ - libboost-all-dev
+ - libdb-dev
+ - libunwind-dev
+ - libminiupnpc-dev
+ - libldns-dev
+ - libexpat1-dev
+ - bison
+ - doxygen
+ - graphviz
+ stage-packages:
+ - libminiupnpc10
+ - libunbound2
+ - libunwind8
+ snap:
+ - bin
+ - usr
diff --git a/src/cryptonote_core/cryptonote_basic.h b/src/cryptonote_core/cryptonote_basic.h
index f54b8c2b3..da069a21a 100644
--- a/src/cryptonote_core/cryptonote_basic.h
+++ b/src/cryptonote_core/cryptonote_basic.h
@@ -230,24 +230,22 @@ namespace cryptonote
}
else
{
- FIELD(rct_signatures)
- switch (rct_signatures.type)
+ ar.tag("rct_signatures");
+ if (!vin.empty())
{
- case rct::RCTTypeNull:
- break;
- case rct::RCTTypeSimple:
- if (rct_signatures.mixRing.size() && rct_signatures.mixRing.size() != vin.size())
- return false;
- break;
- case rct::RCTTypeFull:
- for (size_t i = 0; i < rct_signatures.mixRing.size(); ++i)
+ ar.begin_object();
+ bool r = rct_signatures.serialize_rctsig_base(ar, vin.size(), vout.size());
+ if (!r || !ar.stream().good()) return false;
+ ar.end_object();
+ if (rct_signatures.type != rct::RCTTypeNull)
{
- if (rct_signatures.mixRing[i].size() != vin.size())
- return false;
+ ar.tag("rctsig_prunable");
+ ar.begin_object();
+ r = rct_signatures.p.serialize_rctsig_prunable(ar, rct_signatures.type, vin.size(), vout.size(),
+ vin[0].type() == typeid(txin_to_key) ? boost::get<txin_to_key>(vin[0]).key_offsets.size() - 1 : 0);
+ if (!r || !ar.stream().good()) return false;
+ ar.end_object();
}
- break;
- default:
- return false;
}
}
END_SERIALIZE()
diff --git a/src/cryptonote_core/cryptonote_boost_serialization.h b/src/cryptonote_core/cryptonote_boost_serialization.h
index c91f78c58..19b1a687e 100644
--- a/src/cryptonote_core/cryptonote_boost_serialization.h
+++ b/src/cryptonote_core/cryptonote_boost_serialization.h
@@ -162,12 +162,17 @@ namespace boost
a & x.vout;
a & x.extra;
if (x.version == 1)
+ {
a & x.signatures;
+ }
else
- a & x.rct_signatures;
+ {
+ a & (rct::rctSigBase&)x.rct_signatures;
+ if (x.rct_signatures.type != rct::RCTTypeNull)
+ a & x.rct_signatures.p;
+ }
}
-
template <class Archive>
inline void serialize(Archive &a, cryptonote::block &b, const boost::serialization::version_type ver)
{
@@ -263,6 +268,13 @@ namespace boost
}
template <class Archive>
+ inline void serialize(Archive &a, rct::rctSigPrunable &x, const boost::serialization::version_type ver)
+ {
+ a & x.rangeSigs;
+ a & x.MGs;
+ }
+
+ template <class Archive>
inline void serialize(Archive &a, rct::rctSig &x, const boost::serialization::version_type ver)
{
a & x.type;
diff --git a/src/cryptonote_core/cryptonote_format_utils.cpp b/src/cryptonote_core/cryptonote_format_utils.cpp
index 32b96f1fc..9667006a3 100644
--- a/src/cryptonote_core/cryptonote_format_utils.cpp
+++ b/src/cryptonote_core/cryptonote_format_utils.cpp
@@ -471,11 +471,11 @@ namespace cryptonote
//---------------------------------------------------------------
bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::vector<tx_source_entry>& sources, const std::vector<tx_destination_entry>& destinations, std::vector<uint8_t> extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, bool rct)
{
- std::vector<crypto::secret_key> amount_keys;
+ std::vector<rct::key> amount_keys;
tx.vin.clear();
tx.vout.clear();
tx.signatures.clear();
- tx.rct_signatures = rct::rctSig();
+ tx.rct_signatures.type = rct::RCTTypeNull;
amount_keys.clear();
tx.version = rct ? 2 : 1;
@@ -593,7 +593,7 @@ namespace cryptonote
{
crypto::secret_key scalar1;
crypto::derivation_to_scalar(derivation, output_index, scalar1);
- amount_keys.push_back(scalar1);
+ amount_keys.push_back(rct::sk2rct(scalar1));
}
r = crypto::derive_public_key(derivation, output_index, dst_entr.addr.m_spend_public_key, out_eph_public_key);
CHECK_AND_ASSERT_MES(r, false, "at creation outs: failed to derive_public_key(" << derivation << ", " << output_index << ", "<< dst_entr.addr.m_spend_public_key << ")");
@@ -750,9 +750,9 @@ namespace cryptonote
get_transaction_prefix_hash(tx, tx_prefix_hash);
rct::ctkeyV outSk;
if (use_simple_rct)
- tx.rct_signatures = rct::genRctSimple(rct::hash2rct(tx_prefix_hash), inSk, destinations, inamounts, outamounts, amount_in - amount_out, mixRing, (const rct::keyV&)amount_keys, index, outSk);
+ tx.rct_signatures = rct::genRctSimple(rct::hash2rct(tx_prefix_hash), inSk, destinations, inamounts, outamounts, amount_in - amount_out, mixRing, amount_keys, index, outSk);
else
- tx.rct_signatures = rct::genRct(rct::hash2rct(tx_prefix_hash), inSk, destinations, outamounts, mixRing, (const rct::keyV&)amount_keys, sources[0].real_output, outSk); // same index assumption
+ tx.rct_signatures = rct::genRct(rct::hash2rct(tx_prefix_hash), inSk, destinations, outamounts, mixRing, amount_keys, sources[0].real_output, outSk); // same index assumption
CHECK_AND_ASSERT_MES(tx.vout.size() == outSk.size(), false, "outSk size does not match vout");
@@ -948,11 +948,35 @@ namespace cryptonote
// prefix
get_transaction_prefix_hash(t, hashes[0]);
- // base rct data
- get_blob_hash(t_serializable_object_to_blob((const rct::rctSigBase&)t.rct_signatures), hashes[1]);
+ transaction &tt = const_cast<transaction&>(t);
- // prunable rct data
- get_blob_hash(t_serializable_object_to_blob(t.rct_signatures.p), hashes[2]);
+ // base rct
+ {
+ std::stringstream ss;
+ binary_archive<true> ba(ss);
+ const size_t inputs = t.vin.size();
+ const size_t outputs = t.vout.size();
+ bool r = tt.rct_signatures.serialize_rctsig_base(ba, inputs, outputs);
+ CHECK_AND_ASSERT_MES(r, false, "Failed to serialize rct signatures base");
+ cryptonote::get_blob_hash(ss.str(), hashes[1]);
+ }
+
+ // prunable rct
+ if (t.rct_signatures.type == rct::RCTTypeNull)
+ {
+ hashes[2] = cryptonote::null_hash;
+ }
+ else
+ {
+ std::stringstream ss;
+ binary_archive<true> ba(ss);
+ const size_t inputs = t.vin.size();
+ const size_t outputs = t.vout.size();
+ const size_t mixin = t.vin.empty() ? 0 : t.vin[0].type() == typeid(txin_to_key) ? boost::get<txin_to_key>(t.vin[0]).key_offsets.size() - 1 : 0;
+ bool r = tt.rct_signatures.p.serialize_rctsig_prunable(ba, t.rct_signatures.type, inputs, outputs, mixin);
+ CHECK_AND_ASSERT_MES(r, false, "Failed to serialize rct signatures prunable");
+ cryptonote::get_blob_hash(ss.str(), hashes[2]);
+ }
// the tx hash is the hash of the 3 hashes
res = cn_fast_hash(hashes, sizeof(hashes));
diff --git a/src/daemon/CMakeLists.txt b/src/daemon/CMakeLists.txt
index 511efcb36..a8c93aa0f 100644
--- a/src/daemon/CMakeLists.txt
+++ b/src/daemon/CMakeLists.txt
@@ -106,3 +106,4 @@ add_dependencies(daemon version)
set_property(TARGET daemon
PROPERTY
OUTPUT_NAME "monerod")
+install(TARGETS daemon DESTINATION bin)
diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp
index f10a5a3a6..b43e01e1f 100644
--- a/src/daemon/rpc_command_executor.cpp
+++ b/src/daemon/rpc_command_executor.cpp
@@ -261,7 +261,7 @@ bool t_rpc_command_executor::show_difficulty() {
tools::success_msg_writer() << "BH: " << res.height
<< ", TH: " << res.top_block_hash
<< ", DIFF: " << res.difficulty
- << ", HR: " << (int) res.difficulty / res.target << " H/s";
+ << ", HR: " << res.difficulty / res.target << " H/s";
return true;
}
diff --git a/src/ringct/rctSigs.cpp b/src/ringct/rctSigs.cpp
index f4dbd65c5..ed1f8cc0e 100644
--- a/src/ringct/rctSigs.cpp
+++ b/src/ringct/rctSigs.cpp
@@ -350,8 +350,16 @@ namespace rct {
keyV hashes;
hashes.push_back(rv.message);
crypto::hash h;
- cryptonote::get_blob_hash(cryptonote::t_serializable_object_to_blob((const rctSigBase&)rv), h);
+
+ std::stringstream ss;
+ binary_archive<true> ba(ss);
+ const size_t inputs = rv.pseudoOuts.size();
+ const size_t outputs = rv.ecdhInfo.size();
+ CHECK_AND_ASSERT_THROW_MES(const_cast<rctSig&>(rv).serialize_rctsig_base(ba, inputs, outputs),
+ "Failed to serialize rctSigBase");
+ cryptonote::get_blob_hash(ss.str(), h);
hashes.push_back(hash2rct(h));
+
keyV kv;
for (auto r: rv.p.rangeSigs)
{
@@ -364,7 +372,6 @@ namespace rct {
kv.push_back(r.Ci[n]);
}
hashes.push_back(cn_fast_hash(kv));
-
return cn_fast_hash(hashes);
}
diff --git a/src/ringct/rctTypes.h b/src/ringct/rctTypes.h
index f231d30fb..bfafebb83 100644
--- a/src/ringct/rctTypes.h
+++ b/src/ringct/rctTypes.h
@@ -188,49 +188,136 @@ namespace rct {
ctkeyV outPk;
xmr_amount txnFee; // contains b
- BEGIN_SERIALIZE()
- FIELD(type)
- if (type == RCTTypeNull)
- return true;
- // FIELD(message) - not serialized, it can be reconstructed
- // FIELD(mixRing) - not serialized, it can be reconstructed
- if (type == RCTTypeSimple)
- FIELD(pseudoOuts)
- FIELD(ecdhInfo)
- if (typename Archive<W>::is_saving()) {
- keyV outPk(this->outPk.size());
- for (size_t n = 0; n < outPk.size(); ++n)
- outPk[n] = this->outPk[n].mask;
- FIELD(outPk)
+ template<bool W, template <bool> class Archive>
+ bool serialize_rctsig_base(Archive<W> &ar, size_t inputs, size_t outputs)
+ {
+ FIELD(type)
+ if (type == RCTTypeNull)
+ return true;
+ if (type != RCTTypeFull && type != RCTTypeSimple)
+ return false;
+ VARINT_FIELD(txnFee)
+ // inputs/outputs not saved, only here for serialization help
+ // FIELD(message) - not serialized, it can be reconstructed
+ // FIELD(mixRing) - not serialized, it can be reconstructed
+ if (type == RCTTypeSimple)
+ {
+ ar.tag("pseudoOuts");
+ ar.begin_array();
+ PREPARE_CUSTOM_VECTOR_SERIALIZATION(inputs, pseudoOuts);
+ if (pseudoOuts.size() != inputs)
+ return false;
+ for (size_t i = 0; i < inputs; ++i)
+ {
+ FIELDS(pseudoOuts[i])
+ if (inputs - i > 1)
+ ar.delimit_array();
}
- else {
- keyV outPk;
- FIELD(outPk)
- this->outPk.resize(outPk.size());
- for (size_t n = 0; n < outPk.size(); ++n)
- this->outPk[n].mask = outPk[n];
- }
- VARINT_FIELD(txnFee)
- END_SERIALIZE()
+ ar.end_array();
+ }
+
+ ar.tag("ecdhInfo");
+ ar.begin_array();
+ PREPARE_CUSTOM_VECTOR_SERIALIZATION(outputs, ecdhInfo);
+ if (ecdhInfo.size() != outputs)
+ return false;
+ for (size_t i = 0; i < outputs; ++i)
+ {
+ FIELDS(ecdhInfo[i])
+ if (outputs - i > 1)
+ ar.delimit_array();
+ }
+ ar.end_array();
+
+ ar.tag("outPk");
+ ar.begin_array();
+ PREPARE_CUSTOM_VECTOR_SERIALIZATION(outputs, outPk);
+ if (outPk.size() != outputs)
+ return false;
+ for (size_t i = 0; i < outputs; ++i)
+ {
+ FIELDS(outPk[i].mask)
+ if (outputs - i > 1)
+ ar.delimit_array();
+ }
+ ar.end_array();
+ return true;
+ }
};
struct rctSigPrunable {
vector<rangeSig> rangeSigs;
vector<mgSig> MGs; // simple rct has N, full has 1
- BEGIN_SERIALIZE()
- FIELD(rangeSigs)
- FIELD(MGs)
- END_SERIALIZE()
+ template<bool W, template <bool> class Archive>
+ bool serialize_rctsig_prunable(Archive<W> &ar, uint8_t type, size_t inputs, size_t outputs, size_t mixin)
+ {
+ if (type == RCTTypeNull)
+ return true;
+ if (type != RCTTypeFull && type != RCTTypeSimple)
+ return false;
+ ar.tag("rangeSigs");
+ ar.begin_array();
+ PREPARE_CUSTOM_VECTOR_SERIALIZATION(outputs, rangeSigs);
+ if (rangeSigs.size() != outputs)
+ return false;
+ for (size_t i = 0; i < outputs; ++i)
+ {
+ FIELDS(rangeSigs[i])
+ if (outputs - i > 1)
+ ar.delimit_array();
+ }
+ ar.end_array();
+
+ ar.tag("MGs");
+ ar.begin_array();
+ // we keep a byte for size of MGs, because we don't know whether this is
+ // a simple or full rct signature, and it's starting to annoy the hell out of me
+ size_t mg_elements = type == RCTTypeSimple ? inputs : 1;
+ PREPARE_CUSTOM_VECTOR_SERIALIZATION(mg_elements, MGs);
+ if (MGs.size() != mg_elements)
+ return false;
+ for (size_t i = 0; i < mg_elements; ++i)
+ {
+ // we save the MGs contents directly, because we want it to save its
+ // arrays and matrices without the size prefixes, and the load can't
+ // know what size to expect if it's not in the data
+ ar.tag("ss");
+ ar.begin_array();
+ PREPARE_CUSTOM_VECTOR_SERIALIZATION(mixin + 1, MGs[i].ss);
+ if (MGs[i].ss.size() != mixin + 1)
+ return false;
+ for (size_t j = 0; j < mixin + 1; ++j)
+ {
+ ar.begin_array();
+ size_t mg_ss2_elements = (type == RCTTypeSimple ? 1 : inputs) + 1;
+ PREPARE_CUSTOM_VECTOR_SERIALIZATION(mg_ss2_elements, MGs[i].ss[j]);
+ if (MGs[i].ss[j].size() != mg_ss2_elements)
+ return false;
+ for (size_t k = 0; k < mg_ss2_elements; ++k)
+ {
+ FIELDS(MGs[i].ss[j][k])
+ if (mg_ss2_elements - j > 1)
+ ar.delimit_array();
+ }
+ ar.end_array();
+
+ if (mixin + 1 - j > 1)
+ ar.delimit_array();
+ }
+ ar.end_array();
+
+ FIELDS(MGs[i].cc)
+ // MGs[i].II not saved, it can be reconstructed
+ if (mg_elements - i > 1)
+ ar.delimit_array();
+ }
+ ar.end_array();
+ return true;
+ }
+
};
struct rctSig: public rctSigBase {
rctSigPrunable p;
-
- BEGIN_SERIALIZE_OBJECT()
- FIELDS(*static_cast<rctSigBase *>(this))
- if (type == RCTTypeNull)
- return true;
- FIELDS(p);
- END_SERIALIZE()
};
//other basepoint H = toPoint(cn_fast_hash(G)), G the basepoint
diff --git a/src/simplewallet/CMakeLists.txt b/src/simplewallet/CMakeLists.txt
index 97852c3dc..572819899 100644
--- a/src/simplewallet/CMakeLists.txt
+++ b/src/simplewallet/CMakeLists.txt
@@ -59,4 +59,5 @@ add_dependencies(simplewallet
version)
set_property(TARGET simplewallet
PROPERTY
- OUTPUT_NAME "monero-wallet-cli") \ No newline at end of file
+ OUTPUT_NAME "monero-wallet-cli")
+install(TARGETS simplewallet DESTINATION bin)
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index 9966dd3cd..75d532432 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -2807,9 +2807,10 @@ void wallet2::get_outs(std::vector<std::vector<entry>> &outs, const std::list<tr
continue;
if (!daemon_resp.outs[i].unlocked) // don't add locked outs
continue;
- if (o > 0 && daemon_resp.outs[i].key == daemon_resp.outs[i - 1].key) // don't add duplicates
+ auto item = std::make_tuple(req.outputs[i].index, daemon_resp.outs[i].key, daemon_resp.outs[i].mask);
+ if (std::find(outs.back().begin(), outs.back().end(), item) != outs.back().end()) // don't add duplicates
continue;
- outs.back().push_back(std::make_tuple(req.outputs[i].index, daemon_resp.outs[i].key, daemon_resp.outs[i].mask));
+ outs.back().push_back(item);
}
if (outs.back().size() < fake_outputs_count + 1)
{
@@ -2819,15 +2820,6 @@ void wallet2::get_outs(std::vector<std::vector<entry>> &outs, const std::list<tr
{
// sort the subsection, so any spares are reset in order
std::sort(outs.back().begin(), outs.back().end(), [](const entry &a, const entry &b) { return std::get<0>(a) < std::get<0>(b); });
-
- // sanity check
- for (size_t n = 1; n < outs.back().size(); ++n)
- {
- THROW_WALLET_EXCEPTION_IF(std::get<0>(outs.back()[n]) == std::get<0>(outs.back()[n-1]), error::wallet_internal_error,
- "Duplicate indices though we did not ask for any");
- THROW_WALLET_EXCEPTION_IF(std::get<1>(outs.back()[n]) == std::get<1>(outs.back()[n-1]), error::wallet_internal_error,
- "Duplicate keys after we have weeded them out");
- }
}
base += requested_outputs_count;
}
diff --git a/tests/unit_tests/serialization.cpp b/tests/unit_tests/serialization.cpp
index 40209f6ed..f51f9ec67 100644
--- a/tests/unit_tests/serialization.cpp
+++ b/tests/unit_tests/serialization.cpp
@@ -589,6 +589,7 @@ TEST(Serialization, serializes_ringct_types)
ASSERT_TRUE(serialization::parse_binary(blob, rg1));
ASSERT_TRUE(!memcmp(&rg0, &rg1, sizeof(rg0)));
+#if 0
ASSERT_TRUE(serialization::dump_binary(s0, blob));
ASSERT_TRUE(serialization::parse_binary(blob, s1));
ASSERT_TRUE(s0.type == s1.type);
@@ -621,16 +622,18 @@ TEST(Serialization, serializes_ringct_types)
// serialization only does the mask
ASSERT_TRUE(!memcmp(&s0.outPk[n].mask, &s1.outPk[n].mask, sizeof(s0.outPk[n].mask)));
}
+#endif
tx0.set_null();
tx0.version = 2;
cryptonote::txin_to_key txin_to_key1;
- txin_to_key1.key_offsets.resize(2);
+ txin_to_key1.key_offsets.resize(4);
cryptonote::txin_to_key txin_to_key2;
- txin_to_key2.key_offsets.resize(2);
+ txin_to_key2.key_offsets.resize(4);
tx0.vin.push_back(txin_to_key1);
tx0.vin.push_back(txin_to_key2);
tx0.vout.push_back(cryptonote::tx_out());
+ tx0.vout.push_back(cryptonote::tx_out());
tx0.rct_signatures = s0;
ASSERT_EQ(tx0.rct_signatures.p.rangeSigs.size(), 2);
ASSERT_TRUE(serialization::dump_binary(tx0, blob));