2021-07-19 20:42:38 +02:00
|
|
|
#include "wallet.hpp"
|
|
|
|
|
|
|
|
#include "db_schema.hpp"
|
|
|
|
#include "wallet2½.hpp"
|
|
|
|
#include "block.hpp"
|
|
|
|
#include "block_tx.hpp"
|
2022-03-01 00:01:38 +01:00
|
|
|
#include "default_daemon_comms.hpp"
|
2021-07-19 20:42:38 +02:00
|
|
|
|
|
|
|
#include <common/hex.h>
|
|
|
|
#include <cryptonote_basic/cryptonote_basic.h>
|
|
|
|
|
|
|
|
#include <sqlitedb/database.hpp>
|
|
|
|
#include <oxenmq/oxenmq.h>
|
|
|
|
|
|
|
|
#include <filesystem>
|
|
|
|
#include <future>
|
2022-03-29 04:24:21 +02:00
|
|
|
#include <chrono>
|
|
|
|
#include <thread>
|
2021-07-19 20:42:38 +02:00
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
|
|
|
|
namespace wallet
|
|
|
|
{
|
|
|
|
Wallet::Wallet(
|
2021-12-06 21:57:16 +01:00
|
|
|
std::shared_ptr<oxenmq::OxenMQ> omq,
|
2021-07-19 20:42:38 +02:00
|
|
|
std::shared_ptr<Keyring> keys,
|
2021-12-06 21:57:16 +01:00
|
|
|
std::shared_ptr<TransactionConstructor> tx_constructor,
|
|
|
|
std::shared_ptr<DaemonComms> daemon_comms,
|
2021-07-19 20:42:38 +02:00
|
|
|
std::string_view dbFilename,
|
2022-08-23 01:25:49 +02:00
|
|
|
std::string_view dbPassword,
|
|
|
|
wallet::Config config_in)
|
2021-12-06 21:57:16 +01:00
|
|
|
: omq(omq)
|
2022-03-01 00:01:38 +01:00
|
|
|
, db{std::make_shared<WalletDB>(std::filesystem::path(dbFilename), dbPassword)}
|
2021-07-19 20:42:38 +02:00
|
|
|
, keys{keys}
|
2021-12-06 21:57:16 +01:00
|
|
|
, tx_scanner{keys, db}
|
|
|
|
, tx_constructor{tx_constructor}
|
|
|
|
, daemon_comms{daemon_comms}
|
2022-03-01 00:01:38 +01:00
|
|
|
, omq_server{request_handler}
|
2022-08-23 01:25:49 +02:00
|
|
|
, config(config_in)
|
2021-07-19 20:42:38 +02:00
|
|
|
{
|
2022-03-01 00:01:38 +01:00
|
|
|
if (not omq)
|
|
|
|
{
|
2022-04-05 04:14:08 +02:00
|
|
|
this->omq = std::make_shared<oxenmq::OxenMQ>();
|
2022-03-29 07:51:11 +02:00
|
|
|
this->daemon_comms = std::make_shared<DefaultDaemonComms>(omq, config.daemon);
|
2022-03-01 00:01:38 +01:00
|
|
|
}
|
|
|
|
if (not daemon_comms)
|
2022-03-29 07:51:11 +02:00
|
|
|
this->daemon_comms = std::make_shared<DefaultDaemonComms>(omq, config.daemon);
|
2022-03-01 00:01:38 +01:00
|
|
|
if (not tx_constructor)
|
2022-04-05 04:14:08 +02:00
|
|
|
this->tx_constructor = std::make_shared<TransactionConstructor>(db, daemon_comms); // TODO sean fix the input that is blank
|
|
|
|
|
2022-08-23 01:25:49 +02:00
|
|
|
omq_server.set_omq(this->omq, config.omq_rpc);
|
2022-03-01 00:01:38 +01:00
|
|
|
|
|
|
|
db->create_schema();
|
|
|
|
last_scan_height = db->last_scan_height();
|
|
|
|
scan_target_height = db->scan_target_height();
|
2021-07-19 20:42:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Wallet::init()
|
|
|
|
{
|
2022-04-05 04:14:08 +02:00
|
|
|
request_handler.set_wallet(weak_from_this());
|
2022-02-14 23:15:28 +01:00
|
|
|
omq->start();
|
|
|
|
daemon_comms->set_remote("ipc://./oxend.sock");
|
2022-03-29 04:24:21 +02:00
|
|
|
daemon_comms->register_wallet(*this, last_scan_height + 1 /*next needed block*/,
|
|
|
|
true /* update sync height */,
|
|
|
|
true /* new wallet */);
|
2021-07-19 20:42:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
Wallet::~Wallet()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2022-03-29 07:51:11 +02:00
|
|
|
void
|
|
|
|
Wallet::propogate_config()
|
|
|
|
{
|
|
|
|
daemon_comms->propogate_config();
|
|
|
|
}
|
|
|
|
|
2021-07-19 20:42:38 +02:00
|
|
|
uint64_t
|
2021-12-06 21:57:16 +01:00
|
|
|
Wallet::get_balance()
|
2021-07-19 20:42:38 +02:00
|
|
|
{
|
2022-03-01 00:01:38 +01:00
|
|
|
return db->overall_balance();
|
2021-07-19 20:42:38 +02:00
|
|
|
}
|
|
|
|
|
2022-08-23 01:25:49 +02:00
|
|
|
uint64_t
|
|
|
|
Wallet::get_unlocked_balance()
|
|
|
|
{
|
|
|
|
return 0; // TODO: this
|
|
|
|
}
|
|
|
|
|
2022-04-07 05:50:14 +02:00
|
|
|
cryptonote::account_keys
|
|
|
|
Wallet::export_keys()
|
|
|
|
{
|
|
|
|
return keys->export_keys();
|
|
|
|
};
|
|
|
|
|
2021-07-19 20:42:38 +02:00
|
|
|
void
|
2021-12-06 21:57:16 +01:00
|
|
|
Wallet::add_block(const Block& block)
|
2021-07-19 20:42:38 +02:00
|
|
|
{
|
2022-03-01 00:01:38 +01:00
|
|
|
auto db_tx = db->db_transaction();
|
2021-07-19 20:42:38 +02:00
|
|
|
|
2022-03-01 00:01:38 +01:00
|
|
|
db->store_block(block);
|
2021-07-19 20:42:38 +02:00
|
|
|
|
|
|
|
for (const auto& tx : block.transactions)
|
|
|
|
{
|
2021-12-06 21:57:16 +01:00
|
|
|
if (auto outputs = tx_scanner.scan_received(tx, block.height, block.timestamp);
|
2021-07-19 20:42:38 +02:00
|
|
|
not outputs.empty())
|
|
|
|
{
|
2022-03-01 00:01:38 +01:00
|
|
|
db->store_transaction(tx.hash, block.height, outputs);
|
2021-07-19 20:42:38 +02:00
|
|
|
}
|
|
|
|
|
2021-12-06 21:57:16 +01:00
|
|
|
if (auto spends = tx_scanner.scan_spent(tx.tx); not spends.empty())
|
2021-07-19 20:42:38 +02:00
|
|
|
{
|
2022-03-01 00:01:38 +01:00
|
|
|
db->store_spends(tx.hash, block.height, spends);
|
2021-07-19 20:42:38 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
db_tx.commit();
|
2022-03-01 00:01:38 +01:00
|
|
|
last_scan_height++;
|
2021-07-19 20:42:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2021-12-06 21:57:16 +01:00
|
|
|
Wallet::add_blocks(const std::vector<Block>& blocks)
|
2021-07-19 20:42:38 +02:00
|
|
|
{
|
|
|
|
if (not running)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (blocks.size() == 0)
|
|
|
|
//TODO: error handling; this shouldn't be able to happen
|
|
|
|
return;
|
|
|
|
|
2022-03-01 00:01:38 +01:00
|
|
|
if (blocks.front().height > last_scan_height + 1)
|
2021-07-19 20:42:38 +02:00
|
|
|
{
|
2022-03-01 00:01:38 +01:00
|
|
|
daemon_comms->register_wallet(*this, last_scan_height + 1 /*next needed block*/, true);
|
2021-07-19 20:42:38 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const auto& block : blocks)
|
|
|
|
{
|
2022-03-01 00:01:38 +01:00
|
|
|
if (block.height == last_scan_height + 1)
|
2021-12-06 21:57:16 +01:00
|
|
|
add_block(block);
|
2021-07-19 20:42:38 +02:00
|
|
|
}
|
2022-03-01 00:01:38 +01:00
|
|
|
daemon_comms->register_wallet(*this, last_scan_height + 1 /*next needed block*/, false);
|
2021-07-19 20:42:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2021-12-06 21:57:16 +01:00
|
|
|
Wallet::update_top_block_info(int64_t height, const crypto::hash& hash)
|
2021-07-19 20:42:38 +02:00
|
|
|
{
|
|
|
|
if (not running)
|
|
|
|
return;
|
|
|
|
|
2022-03-01 00:01:38 +01:00
|
|
|
db->update_top_block_info(height, hash);
|
2021-07-19 20:42:38 +02:00
|
|
|
|
|
|
|
scan_target_height = height;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2021-12-06 21:57:16 +01:00
|
|
|
Wallet::deregister()
|
2021-07-19 20:42:38 +02:00
|
|
|
{
|
|
|
|
running = false;
|
2022-03-29 04:24:21 +02:00
|
|
|
auto self = weak_from_this();
|
2021-07-19 20:42:38 +02:00
|
|
|
std::promise<void> p;
|
|
|
|
auto f = p.get_future();
|
2021-12-06 21:57:16 +01:00
|
|
|
daemon_comms->deregister_wallet(*this, p);
|
2021-07-19 20:42:38 +02:00
|
|
|
f.wait();
|
|
|
|
|
2022-03-29 04:24:21 +02:00
|
|
|
/*
|
|
|
|
// At this point, only the true "owner" should have a reference
|
|
|
|
using namespace std::chrono_literals;
|
|
|
|
while (self.use_count() > 1)
|
|
|
|
std::this_thread::sleep_for(50ms);
|
|
|
|
*/
|
|
|
|
}
|
2021-07-19 20:42:38 +02:00
|
|
|
|
|
|
|
} // namespace wallet
|