2020-09-25 15:19:01 +08:00
|
|
|
#include"Boltz/Detail/ServiceImpl.hpp"
|
2021-01-21 15:56:41 +08:00
|
|
|
#include"Boltz/Detail/create_connection.hpp"
|
2020-09-24 08:40:27 +08:00
|
|
|
#include"Boltz/Service.hpp"
|
|
|
|
|
#include"Boltz/ServiceFactory.hpp"
|
|
|
|
|
#include"Ev/Io.hpp"
|
|
|
|
|
#include"Ev/ThreadPool.hpp"
|
|
|
|
|
#include"Ev/yield.hpp"
|
|
|
|
|
#include"Secp256k1/SignerIF.hpp"
|
|
|
|
|
#include"Sqlite3.hpp"
|
|
|
|
|
#include"Util/make_unique.hpp"
|
|
|
|
|
|
|
|
|
|
namespace Boltz {
|
|
|
|
|
|
|
|
|
|
class ServiceFactory::Impl {
|
|
|
|
|
private:
|
|
|
|
|
Ev::ThreadPool& threadpool;
|
|
|
|
|
Sqlite3::Db db;
|
|
|
|
|
Secp256k1::SignerIF& signer;
|
2020-09-24 19:06:48 +08:00
|
|
|
Boltz::EnvIF& env;
|
2020-09-24 08:40:27 +08:00
|
|
|
std::string proxy;
|
2021-01-21 15:56:41 +08:00
|
|
|
bool always_use_proxy;
|
2020-09-24 08:40:27 +08:00
|
|
|
|
|
|
|
|
/* nullptr if we are currently initializing,
|
|
|
|
|
* pointer to false if currently uninitialized,
|
|
|
|
|
* pointer to true if already initialized. */
|
|
|
|
|
std::unique_ptr<bool> initted_flag;
|
|
|
|
|
|
|
|
|
|
Ev::Io<void> try_initialize() {
|
|
|
|
|
return Ev::yield().then([this]() {
|
|
|
|
|
if (!initted_flag)
|
|
|
|
|
/* Busy wait. */
|
|
|
|
|
return Ev::yield().then([this]() {
|
|
|
|
|
return try_initialize();
|
|
|
|
|
});
|
|
|
|
|
if (*initted_flag)
|
|
|
|
|
/* Do nothing. */
|
|
|
|
|
return Ev::lift();
|
|
|
|
|
/* Start initializing. */
|
|
|
|
|
initted_flag = nullptr;
|
|
|
|
|
return do_initialize();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
Ev::Io<void> do_initialize() {
|
|
|
|
|
/* Perform actual initialization. */
|
|
|
|
|
return db.transact().then([this](Sqlite3::Tx tx) {
|
|
|
|
|
tx.query_execute(R"QRY(
|
|
|
|
|
-- reverse submarine swaps.
|
|
|
|
|
CREATE TABLE IF NOT EXISTS "BoltzServiceFactory_rsub"
|
|
|
|
|
( id INTEGER PRIMARY KEY
|
|
|
|
|
|
2021-01-21 15:56:41 +08:00
|
|
|
-- The Boltz implementation that generated
|
2020-09-24 08:40:27 +08:00
|
|
|
-- this row.
|
2021-01-21 15:56:41 +08:00
|
|
|
-- Historically this was the access point,
|
|
|
|
|
-- but now it is "just" a label naming the
|
|
|
|
|
-- Boltz implementation.
|
2020-09-24 08:40:27 +08:00
|
|
|
, apiAccess TEXT NOT NULL
|
|
|
|
|
|
|
|
|
|
-- We generated these.
|
|
|
|
|
-- privkey used to tweak the signer.
|
|
|
|
|
-- these, and other data, are in hex.
|
|
|
|
|
, tweak TEXT NOT NULL
|
|
|
|
|
-- LN preimage.
|
|
|
|
|
, preimage TEXT NOT NULL
|
|
|
|
|
-- onchain address the C-Lightning node
|
|
|
|
|
-- controls.
|
|
|
|
|
, destinationAddress TEXT NOT NULL
|
|
|
|
|
|
|
|
|
|
-- from exchange, before paying invoice.
|
|
|
|
|
-- id from exchange.
|
|
|
|
|
, swapId TEXT NOT NULL
|
|
|
|
|
, redeemScript TEXT NOT NULL
|
|
|
|
|
, timeoutBlockheight INTEGER NOT NULL
|
|
|
|
|
-- in satoshi.
|
|
|
|
|
, onchainAmount INTEGER NOT NULL
|
|
|
|
|
|
2020-09-24 16:58:31 +08:00
|
|
|
-- whether lockup fields have been set.
|
|
|
|
|
-- 0 == false, 1 == true
|
|
|
|
|
, lockedUp INTEGER NOT NULL
|
|
|
|
|
|
2020-09-24 08:40:27 +08:00
|
|
|
-- from the exchange, after paying invoice.
|
|
|
|
|
-- These are the details of the lockup
|
|
|
|
|
-- transaction output.
|
|
|
|
|
, lockupTxid TEXT NULL
|
|
|
|
|
-- The output of the lockupTxid that contains
|
|
|
|
|
-- the value spendable by the redeem script.
|
|
|
|
|
, lockupOut INTEGER NULL
|
|
|
|
|
-- The blockheight at which we believe the
|
|
|
|
|
-- tx was confirmed.
|
|
|
|
|
, lockupConfirmedHeight INTEGER NULL
|
|
|
|
|
|
|
|
|
|
-- We generated these on seeing that
|
|
|
|
|
-- the transaction from the service
|
|
|
|
|
-- confirmed.
|
|
|
|
|
-- in satoshi.
|
2020-09-24 16:58:31 +08:00
|
|
|
, lockupClaimFees INTEGER NULL
|
2020-09-24 08:40:27 +08:00
|
|
|
|
|
|
|
|
-- additional data we might need.
|
|
|
|
|
, comment TEXT
|
|
|
|
|
);
|
|
|
|
|
CREATE INDEX IF NOT EXISTS
|
|
|
|
|
"BoltzServiceFactory_rsub_swapid"
|
|
|
|
|
ON "BoltzServiceFactory_rsub"
|
|
|
|
|
( swapId
|
|
|
|
|
, apiAccess
|
|
|
|
|
);
|
|
|
|
|
)QRY");
|
|
|
|
|
tx.commit();
|
|
|
|
|
|
|
|
|
|
initted_flag = Util::make_unique<bool>(true);
|
|
|
|
|
|
|
|
|
|
return Ev::yield();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
Impl() =delete;
|
|
|
|
|
|
|
|
|
|
Impl( Ev::ThreadPool& threadpool_
|
|
|
|
|
, Sqlite3::Db db_
|
|
|
|
|
, Secp256k1::SignerIF& signer_
|
2020-09-24 19:06:48 +08:00
|
|
|
, Boltz::EnvIF& env_
|
2020-09-24 08:40:27 +08:00
|
|
|
, std::string proxy_
|
2021-01-21 15:56:41 +08:00
|
|
|
, bool always_use_proxy_
|
2020-09-24 08:40:27 +08:00
|
|
|
) : threadpool(threadpool_)
|
|
|
|
|
, db(std::move(db_))
|
|
|
|
|
, signer(signer_)
|
2020-09-24 19:06:48 +08:00
|
|
|
, env(env_)
|
2020-09-24 08:40:27 +08:00
|
|
|
, proxy(std::move(proxy_))
|
2021-01-21 15:56:41 +08:00
|
|
|
, always_use_proxy(always_use_proxy_)
|
2020-09-24 08:40:27 +08:00
|
|
|
, initted_flag(Util::make_unique<bool>(false))
|
|
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
Ev::Io<std::unique_ptr<Service>>
|
2021-01-21 15:56:41 +08:00
|
|
|
create_service_detailed( std::string const& label
|
|
|
|
|
, std::string const& clearnet
|
|
|
|
|
, std::string const& onion
|
|
|
|
|
) {
|
|
|
|
|
return try_initialize().then([this, label, clearnet, onion]() {
|
2020-09-25 15:19:01 +08:00
|
|
|
auto ptr = std::unique_ptr<Service>();
|
|
|
|
|
ptr = Util::make_unique<Detail::ServiceImpl>
|
2021-01-21 15:56:41 +08:00
|
|
|
( db
|
2020-09-25 15:19:01 +08:00
|
|
|
, signer
|
|
|
|
|
, env
|
2021-01-21 15:56:41 +08:00
|
|
|
, label
|
|
|
|
|
, Detail::create_connection( threadpool
|
|
|
|
|
, clearnet
|
|
|
|
|
, onion
|
|
|
|
|
, proxy
|
|
|
|
|
, always_use_proxy
|
|
|
|
|
)
|
2020-09-25 15:19:01 +08:00
|
|
|
);
|
|
|
|
|
return Ev::lift(std::move(ptr));
|
2020-09-24 08:40:27 +08:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
ServiceFactory::ServiceFactory(ServiceFactory&&) =default;
|
|
|
|
|
ServiceFactory& ServiceFactory::operator=(ServiceFactory&&) =default;
|
|
|
|
|
ServiceFactory::~ServiceFactory() =default;
|
|
|
|
|
|
|
|
|
|
ServiceFactory::ServiceFactory( Ev::ThreadPool& threadpool
|
|
|
|
|
, Sqlite3::Db db
|
|
|
|
|
, Secp256k1::SignerIF& signer
|
2020-09-24 19:06:48 +08:00
|
|
|
, Boltz::EnvIF& env
|
2020-09-24 08:40:27 +08:00
|
|
|
, std::string proxy
|
2021-01-21 15:56:41 +08:00
|
|
|
, bool always_use_proxy
|
2020-09-24 08:40:27 +08:00
|
|
|
) : pimpl(Util::make_unique<Impl>( threadpool
|
|
|
|
|
, std::move(db)
|
|
|
|
|
, signer
|
2020-09-24 19:06:48 +08:00
|
|
|
, env
|
2020-09-24 08:40:27 +08:00
|
|
|
, std::move(proxy)
|
2021-01-21 15:56:41 +08:00
|
|
|
, always_use_proxy
|
2020-09-24 08:40:27 +08:00
|
|
|
))
|
|
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
Ev::Io<std::unique_ptr<Service>>
|
2021-01-21 15:56:41 +08:00
|
|
|
ServiceFactory::create_service_detailed( std::string const& label
|
|
|
|
|
, std::string const& clearnet
|
|
|
|
|
, std::string const& onion
|
|
|
|
|
) {
|
|
|
|
|
return pimpl->create_service_detailed(label, clearnet, onion);
|
2020-09-24 08:40:27 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|