You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
openmonero/src/OutputInputIdentification.h

249 lines
6.0 KiB

//
// Created by mwo on 13/02/17.
//
#pragma once
#include "CurrentBlockchainStatus.h"
#include <map>
#include <utility>
namespace xmreg
{
class OutputInputIdentificationException: public std::runtime_error
{
using std::runtime_error::runtime_error;
};
/*
* This class takes user address, viewkey
* and searches for outputs in a given tx
* and possible spendings/inputs.
*
* It is the key class for identification of incoming monero
* and candidate outcoming xmr for a user in a blockchain and in
* mempool.
*
* searching for our incoming and outgoing xmr has two components.
*
* FIRST. to search for the incoming xmr, we use address, viewkey and
* outputs public key. Its straight forward, as this is what viewkey was
* designed to do.
*
* SECOND. Searching for spendings (i.e., key images) is more difficult,
* because we dont have spendkey. But what we can do is, we can look for
* candidate key images. And this can be achieved by checking if any mixin
* in associated with the given key image, is our output. If it is our output,
* then we assume its our key image (i.e. we spend this output). Off course
* this is only
* assumption as our outputs can be used in key images of others for their
* mixin purposes. Thus, we sent to the frontend the list of key images
* that we think are yours, and the frontend, because it has spendkey,
* can filter out false positives.
*/
class OutputInputIdentification
{
public:
// define a structure to keep information about found
// outputs that we can need in later parts.
struct output_info
{
public_key pub_key;
uint64_t amount;
uint64_t idx_in_tx;
string rtc_outpk;
string rtc_mask;
string rtc_amount;
};
// define a structure to keep information about found
// inputs that we can need in later parts.
struct input_info
{
string key_img;
uint64_t amount;
public_key out_pub_key;
};
crypto::hash tx_hash;
crypto::hash tx_prefix_hash;
public_key tx_pub_key;
string tx_hash_str;
string tx_prefix_hash_str;
string tx_pub_key_str;
bool tx_is_coinbase;
bool is_rct;
uint8_t rct_type;
uint64_t total_received {0};
uint64_t mixin_no {0};
// for each output, in a tx, check if it belongs
// to the given account of specific address and viewkey
// public transaction key is combined with our viewkey
// to create, so called, derived key.
key_derivation derivation;
vector<output_info> identified_outputs;
vector<input_info> identified_inputs;
// default constructor. Useful for unit tests
OutputInputIdentification() = default;
OutputInputIdentification(const address_parse_info* _a,
const secret_key* _v,
const transaction* _tx,
crypto::hash const& _tx_hash,
bool is_coinbase);
/**
* FIRST step. search for the incoming xmr using address, viewkey and
* outputs public keys.
*/
virtual void
identify_outputs();
/**
* SECOND step. search for possible our inputs.
* We do this by comparing mixin public keys with
* our known output keys. If a metch is found, we assume
* that associated input is ours
*
* The known_outputs_keys parameter is optional. But when we have
* it, the identification is faster as we just check mixins public keys
* if they are in known_outputs_keys.
*
* searching without known_outputs_keys is not implemented yet here
* but it was done for the onion explorer. so later basically just
* copy and past here.
*
* known_outputs_keys is pair of <output public key, output amount>
*
*/
virtual void
identify_inputs(
unordered_map<public_key, uint64_t> const& known_outputs_keys,
CurrentBlockchainStatus* current_bc_status);
virtual string const&
get_tx_hash_str();
virtual string const&
get_tx_prefix_hash_str();
virtual string const&
get_tx_pub_key_str();
virtual uint64_t
get_mixin_no();
virtual ~OutputInputIdentification() = default;
private:
// address and viewkey for this search thread.
const address_parse_info* address_info;
const secret_key* viewkey;
// transaction that is beeing search
const transaction* tx;
};
//class BaseIdentifier {
//public:
// BaseIdentifier(address_parse_info const* _a,
// const secret_key* _v,
// const transaction* _tx)
// : address_info {_a}, viewkey {_v}, tx {_tx}
// {
// }
// virtual void identify() = 0;
//protected:
// // address and viewkey for this search thread.
// address_parse_info const* address_info;
// secret_key const* viewkey;
// // transaction that is beeing search
// transaction const* tx;
//};
//class OutputIdentifier : public BaseIdentifier
//{
// using BaseIdentifier::BaseIdentifier;
// using key_imgs_map = unordered_map<public_key, uint64_t>;
// // define a structure to keep information about found
// // outputs that we can need in later parts.
// struct output_info
// {
// public_key pub_key;
// uint64_t amount;
// uint64_t idx_in_tx;
// string rtc_outpk;
// string rtc_mask;
// string rtc_amount;
// };
//public:
// void
// set_known_outputs(key_imgs_map const* _known_outputs)
// {
// known_outputs_keys = _known_outputs;
// }
// void
// identify()
// {}
//private:
// key_imgs_map const* known_outputs_keys {nullptr};
//};
//class InpputIdentifier : public BaseIdentifier
//{
// using BaseIdentifier::BaseIdentifier;
// // define a structure to keep information about found
// // inputs that we can need in later parts.
// struct input_info
// {
// string key_img;
// uint64_t amount;
// public_key out_pub_key;
// };
//public:
// void
// identify()
// {}
//};
}