-
Notifications
You must be signed in to change notification settings - Fork 3
Description
Background
This proposal is a deep fix to the issue of having the user construct the contract transaction in javascript. We have been discussing moving this into the addon, or the wrapper, to hide some of it from the end user, but at the deepest level, there is a redundancy which this proposal tries to look at the lowest level where it exists.
When trying to start downloading, using the extension::request::StartDownloading, the user of the extension has the following pieces of non-trivial information
protocol_session::PeerToStartDownloadInformationMap<libtorrent::tcp::endpoint> peerToStartDownloadInformationMap: what peers to use, and corresponding setup informationCoin::Transaction contractTx: a fully signed contract transaction
Importantly, the extension knows everything it needs to know to construct contractTx on it own, it only requires some means of financing it.
Problem
Requiring user to construct contractTx leaks lots of details about the payment channel into user code, which both makes it more complicated, to manage, test and change. It really should be avoidable to have the user to this redundant work, and instead give the extension the minimal amount of information.
Solutions
Replace contractTx in the extension::request::StartDownloading request with
struct Financing {
std::vector<Coin::TxIn>> inputs;
boost::option<Coin::TxOut> possible_change;
}
@brief Gets financing for given outputs and total fee rate constraint.
@param outputs ordered set of outputs, to be financed
@param fee minimum satoshies per Kb constraint required on final transaction
@return financing of the given outputs with given fee constraint
typedef std::function<Financing(const std::vector<Coin::TxOut> & outputs,int64_t fee)> Financier;
which is called by the extension to construct the final contract transaction.
Two approaches
There are two approaches to implementing a Financier instance.
-
have it make a direct call with whatever manages the UTXO set in the application, for example a wallet or UTXO manager. This introduces the potentially difficult problem of synchronizing the libtorrent thread with user thread(s).
-
preallocate the UTXO set, and capture it in the
Financier, and use it to sign when called.
The second option is better, as it avoids any need for synchronization, however, the ability to do so requires a sufficiently flexible signing infrastructure in the application.
Example: joystream-node-cpp
The first approach would require synchronizing with the nodejs thread, which is possible, but non-trivial.
The second approach would require altering the start_download binding in the addon to take some sort of utxo representation. This representation could be converted into an Coin::UnspentOutputSet instance, and capture this inside the Financier. This will require fixing the representation to a predetermined set of UTXO types, e.g. only p2sh, or p2pkh. So a user of the js wrapper would do something like
// p2pkh utxo
var utxo_1 = {
outpoint: ...
sk: ...
value: ...
};
plugin.start_download(..., [utxo_1]);