test RegularTwoOutputTxToSubaddress added

pull/3/head
moneroexamples 5 years ago
parent 7c83702f92
commit 0741363499

@ -375,7 +375,20 @@ Account::ai_to_str(address_parse_info const& addr_info,
inline std::ostream& inline std::ostream&
operator<<(std::ostream& os, Account const& _acc) operator<<(std::ostream& os, Account const& _acc)
{ {
string subaddr_str {"n/a"};
if (_acc.subaddr_idx)
{
stringstream ss;
ss << *_acc.subaddr_idx;
subaddr_str = ss.str();
}
return os << "nt:" << static_cast<size_t>(_acc.nettype) return os << "nt:" << static_cast<size_t>(_acc.nettype)
<< "," << subaddr_str
<< ",a:" << _acc.ai2str() << ",a:" << _acc.ai2str()
<< ",v:" << _acc.vk2str() << ",v:" << _acc.vk2str()
<< ",s:" << _acc.sk2str(); << ",s:" << _acc.sk2str();

@ -104,6 +104,18 @@ Output::identify(transaction const& tx,
auto const& pub_spend_key auto const& pub_spend_key
= get_address()->address.m_spend_public_key; = get_address()->address.m_spend_public_key;
// if we have PrimaryAccount we can check
// if a given output belongs to any of its
// its subaddresses
PrimaryAccount* pacc {nullptr};
if (acc && !acc->is_subaddress())
{
// so we have primary address
pacc = static_cast<PrimaryAccount*>(acc);
}
for (auto i = 0u; i < tx.vout.size(); ++i) for (auto i = 0u; i < tx.vout.size(); ++i)
{ {
// i will act as output indxes in the tx // i will act as output indxes in the tx
@ -124,8 +136,16 @@ Output::identify(transaction const& tx,
// public monero address. Primary address is // public monero address. Primary address is
// a special case of subaddress. // a special case of subaddress.
// we are always going to have the subaddress_spend
// key if an output is ours
crypto::public_key subaddress_spendkey; crypto::public_key subaddress_spendkey;
// however we might not have its index, in case
// we are not using primary addresses directly
// but instead use a subaddress for searching
// outputs
std::unique_ptr<subaddress_index> subaddr_idx;
hwdev.derive_subaddress_public_key( hwdev.derive_subaddress_public_key(
txout_key.key, derivation, i, txout_key.key, derivation, i,
subaddress_spendkey); subaddress_spendkey);
@ -138,9 +158,9 @@ Output::identify(transaction const& tx,
bool mine_output {false}; bool mine_output {false};
if (!acc) if (!pacc)
{ {
// if acc is not given, we check generated // if pacc is not given, we check generated
// subaddress_spendkey against the spendkey // subaddress_spendkey against the spendkey
// of the address for which the Output identifier // of the address for which the Output identifier
// was instantiated // was instantiated
@ -148,17 +168,14 @@ Output::identify(transaction const& tx,
} }
else else
{ {
// if acc is given, we are going to use its // if pacc is given, we are going to use its
// subaddress unordered map to check if generated // subaddress unordered map to check if generated
// subaddress_spendkey is one of its keys. this is // subaddress_spendkey is one of its keys. this is
// because the map can contain spendkeys of subaddreses // because the map can contain spendkeys of subaddreses
// assiciated with primary address. primary address's // assiciated with primary address. primary address's
// spendkey will be one of the keys as a special case // spendkey will be one of the keys as a special case
assert(!acc->is_subaddress()); subaddr_idx = pacc->has_subaddress(subaddress_spendkey);
auto sacc = static_cast<PrimaryAccount*>(acc);
auto subaddr_idx = sacc->has_subaddress(subaddress_spendkey);
mine_output = bool {subaddr_idx}; mine_output = bool {subaddr_idx};
} }
@ -168,14 +185,20 @@ Output::identify(transaction const& tx,
if (!mine_output && !additional_tx_pub_keys.empty()) if (!mine_output && !additional_tx_pub_keys.empty())
{ {
// check for output using additional tx public keys // check for output using additional tx public keys
crypto::public_key subaddress_spendkey;
hwdev.derive_subaddress_public_key( hwdev.derive_subaddress_public_key(
txout_key.key, additional_derivations[i], txout_key.key, additional_derivations[i],
i, i,
subaddress_spendkey); subaddress_spendkey);
mine_output = (pub_spend_key == subaddress_spendkey); if (!pacc)
{
mine_output = (pub_spend_key == subaddress_spendkey);
}
else
{
subaddr_idx = pacc->has_subaddress(subaddress_spendkey);
mine_output = bool {subaddr_idx};
}
with_additional = true; with_additional = true;
} }
@ -246,11 +269,17 @@ Output::identify(transaction const& tx,
info{ info{
txout_key.key, amount, i, txout_key.key, amount, i,
derivation_to_save, derivation_to_save,
rtc_outpk, rtc_mask, rtc_amount rtc_outpk, rtc_mask, rtc_amount,
subaddress_spendkey
}); });
total_xmr += amount; if (subaddr_idx)
{
auto& out = identified_outputs.back();
out.subaddr_idx = *subaddr_idx;
}
total_xmr += amount;
} // if (mine_output) } // if (mine_output)
} // for (uint64_t i = 0; i < tx.vout.size(); ++i) } // for (uint64_t i = 0; i < tx.vout.size(); ++i)

@ -70,11 +70,6 @@ class Output : public BaseIdentifier
{ {
public: public:
//Output(address_parse_info const* _address,
//secret_key const* _viewkey)
//: BaseIdentifier(_address, _viewkey)
//{}
using BaseIdentifier::BaseIdentifier; using BaseIdentifier::BaseIdentifier;
void identify(transaction const& tx, void identify(transaction const& tx,
@ -105,6 +100,17 @@ public:
rct::key rtc_mask; rct::key rtc_mask;
rct::key rtc_amount; rct::key rtc_amount;
public_key subaddress_spendkey;
subaddress_index subaddr_idx {
UINT32_MAX, UINT32_MAX};
// the max value means not given
bool has_subaddress_index() const
{
return subaddr_idx.major != UINT32_MAX
&& subaddr_idx.minor != UINT32_MAX;
}
friend std::ostream& operator<<(std::ostream& os, friend std::ostream& operator<<(std::ostream& os,
info const& _info); info const& _info);
}; };

@ -362,6 +362,7 @@ TEST(SUBADDRESS, PupulateSubaddresses)
{ {
auto sacc = pacc->gen_subaddress(kv.second); auto sacc = pacc->gen_subaddress(kv.second);
if (!sacc) continue; if (!sacc) continue;
cout << *sacc << endl;
EXPECT_EQ(kv.first, sacc->psk()); EXPECT_EQ(kv.first, sacc->psk());
} }
} }

@ -425,6 +425,15 @@ TEST(Subaddresses, RegularTwoOutputTxToSubaddress)
EXPECT_TRUE(identifier.get<0>()->get() EXPECT_TRUE(identifier.get<0>()->get()
== jtx->recipients.at(0).outputs); == jtx->recipients.at(0).outputs);
auto const& output_info
= identifier.get<0>()->get().at(0);
EXPECT_TRUE(output_info.has_subaddress_index());
subaddress_index expected_idx {0, 6};
EXPECT_EQ(output_info.subaddr_idx, expected_idx);
} }

Loading…
Cancel
Save