Skip to content

Simplifying buying #6

@bedeho

Description

@bedeho

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 information
  • Coin::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]);

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions