// // Created by mwo on 13/02/17. // #pragma once #include "CurrentBlockchainStatus.h" #include "tools.h" #include #include 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 identified_outputs; vector 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 * */ virtual void identify_inputs( unordered_map 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; // // 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() // {} //}; }