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&
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)
<< "," << subaddr_str
<< ",a:" << _acc.ai2str()
<< ",v:" << _acc.vk2str()
<< ",s:" << _acc.sk2str();

@ -104,6 +104,18 @@ Output::identify(transaction const& tx,
auto const& pub_spend_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)
{
// i will act as output indxes in the tx
@ -124,8 +136,16 @@ Output::identify(transaction const& tx,
// public monero address. Primary address is
// 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;
// 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(
txout_key.key, derivation, i,
subaddress_spendkey);
@ -138,9 +158,9 @@ Output::identify(transaction const& tx,
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
// of the address for which the Output identifier
// was instantiated
@ -148,17 +168,14 @@ Output::identify(transaction const& tx,
}
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_spendkey is one of its keys. this is
// because the map can contain spendkeys of subaddreses
// assiciated with primary address. primary address's
// spendkey will be one of the keys as a special case
assert(!acc->is_subaddress());
auto sacc = static_cast<PrimaryAccount*>(acc);
auto subaddr_idx = sacc->has_subaddress(subaddress_spendkey);
subaddr_idx = pacc->has_subaddress(subaddress_spendkey);
mine_output = bool {subaddr_idx};
}
@ -168,14 +185,20 @@ Output::identify(transaction const& tx,
if (!mine_output && !additional_tx_pub_keys.empty())
{
// check for output using additional tx public keys
crypto::public_key subaddress_spendkey;
hwdev.derive_subaddress_public_key(
txout_key.key, additional_derivations[i],
i,
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;
}
@ -246,11 +269,17 @@ Output::identify(transaction const& tx,
info{
txout_key.key, amount, i,
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)
} // for (uint64_t i = 0; i < tx.vout.size(); ++i)

@ -70,11 +70,6 @@ class Output : public BaseIdentifier
{
public:
//Output(address_parse_info const* _address,
//secret_key const* _viewkey)
//: BaseIdentifier(_address, _viewkey)
//{}
using BaseIdentifier::BaseIdentifier;
void identify(transaction const& tx,
@ -105,6 +100,17 @@ public:
rct::key rtc_mask;
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,
info const& _info);
};

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

@ -425,6 +425,15 @@ TEST(Subaddresses, RegularTwoOutputTxToSubaddress)
EXPECT_TRUE(identifier.get<0>()->get()
== 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