Skip to content

Conversation

@ebfull
Copy link

@ebfull ebfull commented Feb 25, 2016

This adds support for timelocked contracts which can be used to atomically
swap hash preimages over the blockchain. It is very similar to the script
used by the lightning network.

Written in collaboration with Pieter Wuille.

@jonasschnelli
Copy link
Contributor

Interesting!
Haven't looked at it in detail, but would this affect "policy" by adding the TX_HTLC as to the standard templates?

@sipa
Copy link
Member

sipa commented Feb 25, 2016 via email

@jonasschnelli
Copy link
Contributor

@sipa: Ah. Right. Then – I guess – the standard.cpp -> Solver() changes are only because we want to detect these types of P2SH scripts in the wallet.

@sipa
Copy link
Member

sipa commented Feb 25, 2016

@jonasschnelli To be clear: this indeed does make the HTLC type transaction standard in non-P2SH setting; it's however still smaller and cheaper than the largest raw multisig that is allowed. Perhaps that indeed shouldn't happen.

@gmaxwell
Copy link
Contributor

Concept ACK.

@dcousens
Copy link
Contributor

concept ACK

@petertodd
Copy link
Contributor

Interestingly, this is useful for Paypub, as well as ZKCP, among other things.

Concept ACK

@petertodd
Copy link
Contributor

@sipa For Paypub, having the payments be visible in the blockchain for the receiver is extremely useful; w/o the ability to do so in scriptPubKey you'd likely implement it with an extra OP_RETURN output (maybe until we have a better Bitmessage to use instead). Not necessarily an argument either for or against doing so, but worth noting.

@btcdrak
Copy link
Contributor

btcdrak commented Feb 26, 2016

Concept ACK

@paveljanik
Copy link
Contributor

Some tests fail with:

Running testscript wallet.py ...
Initializing test directory /tmp/testr_T8PJ
start_node: bitcoind started, calling bitcoin-cli -rpcwait getblockcount
start_node: calling bitcoin-cli -rpcwait getblockcount returned
JSONRPC error: preimage must be hexadecimal string (not '')

I can't reproduce locally 8)

@paveljanik
Copy link
Contributor

Concept ACK
Needs some tests. Needs BIP for new OP_ANYDATA.

@jonasschnelli
Copy link
Contributor

Concept ACK.

1.) Not sure if this requires a BIP, I guess we don't need a BIP for every contract template and I can't find the other template matching params (like OP_SMALLINTEGER) in the BIPs.

I also concept ACK the IsStandard rule for HTLC to allow blockchain-visible HTLC, though, this might require a BIP.

@sipa
Copy link
Member

sipa commented Feb 26, 2016 via email

@luke-jr
Copy link
Member

luke-jr commented Feb 26, 2016

I agree IsStandard changes do not need a BIP, but it seems any transaction type supported by the reference implementation necessarily involves coordination with other software/people, and therefore should have a BIP written describing how it works.

Is there a benefit to bare HTLC over P2SH (or SegWit) HTLC? If not, it seems pointless to expand the policy to allow for it. Note that many users do not enable bare multisig (and it should probably be disabled by default).

@ebfull
Copy link
Author

ebfull commented Feb 26, 2016

I don't think initially we should make this standard outside P2SH (yet), so that's definitely a change that should be made to this PR.

This work so far allows you to "import" a preimage into CWallet (so that you can redeem the atomic swap branch of the script) but it does not persist this to disk, and I'm curious if others think it should. (I'm skeptical of making bitcoind store secrets, especially if for some use cases they are ephemeral.)

@gmaxwell
Copy link
Contributor

@jtimon
Copy link
Contributor

jtimon commented Feb 26, 2016

Wow, concept ACK.

@sipa
Copy link
Member

sipa commented Mar 5, 2016

We should probably also wait until CSV is in, and add support for it in the constructed scripts here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This new line?

@gmaxwell
Copy link
Contributor

@sipa CSV is almost in, but I don't think we should be deploying enabled generation for them until the softfork is good and settled. Maybe behind a hidden option or testnet only?

@ebfull
Copy link
Author

ebfull commented Mar 30, 2016

Additionally, supporting RIPEMD160 for ZKCPs is a must. I will try to find some time to write an arithmetic circuit for it.

@ebfull
Copy link
Author

ebfull commented Jun 7, 2016

After segwit lands (?) I will try to rebase and clean this PR up.

@btcdrak
Copy link
Contributor

btcdrak commented Jun 26, 2016

@ebfull segwit has been merged to master and is also activated on testnet.

@gmaxwell
Copy link
Contributor

gmaxwell commented Jul 5, 2016

CSV is active on mainnet!

@ebfull
Copy link
Author

ebfull commented Jul 18, 2016

Rebased this on to master. Now supports RIPEMD160. Switched to CSV (block denominated mode). Added some RPC tests.

It can be trivially extended to use CLTV in the RPC, I just need to come up with a solid UX for it. The same goes for "relative" time strings like "10h" or "5d." Also, still need to bring over the "preimage" display that showed in listtransactions.

I'll try to work alongside #7534 for the remaining work, including submitting a BIP.

BOOST_FOREACH(opcodetype hasher, accepted_hashers) {
BOOST_FOREACH(opcodetype timeout_op, accepted_timeout_ops) {
mTemplates.insert(make_pair(TX_HTLC, CScript()
<< hasher << OP_ANYDATA << OP_EQUAL
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the "ELSE" case any relay node may replace the top stack with anything without invalidating the tx. See related discussion at https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2016-August/013036.html

@afk11
Copy link
Contributor

afk11 commented Nov 23, 2016

Needs rebase

@jtimon
Copy link
Contributor

jtimon commented Dec 27, 2016

Still needs rebase.

@ebfull
Copy link
Author

ebfull commented Dec 28, 2016

Before I rebase, I need to understand the consensus regarding preventing malleability of these scripts.

https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2016-August/013036.html

Multiple suggestions were made and I'm not personally qualified to pick from them.

@jl2012
Copy link
Contributor

jl2012 commented Dec 29, 2016

@ebfull: I'd suggest this one. But you may want to discuss it on mailing list to make sure it is compatible with other implementations (if any)

OP_IF [HASHOP] <digest> OP_EQUALVERIFY <seller pubkey> OP_ELSE <num> [TIMEOUTOP] OP_DROP <buyer pubkey> OP_ENDIF OP_CHECKSIG

@da2ce7
Copy link

da2ce7 commented Feb 20, 2017

@ebfull, this looks very interesting to me and many others. Would be wonderful for you can find the time to have a second look at this pull request since v0.14 has been forked off.

@ebfull
Copy link
Author

ebfull commented Feb 21, 2017

I will be rebasing using @jl2012's script as the foundation, and update my BIP draft.

if (m < 1 || m > n)
return false;
} else if (whichType == TX_HTLC) {
return false;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like you're assuming all TX_HTLC transactions are DOS attacks?
Why reject them all?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@arielgabizon Would this actually reject all TX_HTLC items? I had the impression or understand that there was a design such that these would actually be completed in most instances. In lnd, a description of this was given as follows: "If payment/htlc amount is too small, than such output is called dust. If for some reason channel have been force closed during payment, and dust htlc/payment haven't been settled (both sides haven't agreed to remove the htlc and change the balances accordingly), th(e)n we (do) not include it in commitment transaction (thereby giv(ing it) as a fee to miners) in order to make it valid." For reference to this comment (from a contributor in lnd) see: lightningnetwork/lnd#115 (comment)

With that said, I'm not sure of how the differences will play out between how bitcoin core is planning on handling it vs. how it is handled presently in the lnd development process.

cc @ebfull

Copy link
Contributor

@JeremyRubin JeremyRubin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concept Ack.

I did some code review, overall looks very clean and concise.

I was slightly concerned with the use of new template parameters, but I think that the proposed new ones are reasonable & general purpose.

I think that the preimage map should persist entries; but perhaps that can be done as a later PR. I would also suggest adding a Lock/Unlock feature in RPC, because I think that that would ensure safer use of entries stored in the preimage map for users.

case TX_HTLC:
{
std::vector<unsigned char> image(vSolutions[0]);
std::vector<unsigned char> preimage;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can reserve preimage.

{
// Only consider HTLC's "mine" if we own ALL the keys
// involved.
vector<valtype> keys;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please reserve keys.

};
const opcodetype accepted_timeout_ops[] = {OP_CHECKLOCKTIMEVERIFY, OP_CHECKSEQUENCEVERIFY};

BOOST_FOREACH(auto hasher, accepted_hashers) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't introduce any new BOOST_FOREACH



// template matching params
OP_BLOB20 = 0xf7,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer to not make any new template matching parameters, but I see how it would be inconvenient to otherwise.

opcodetype timeout_type)
{
CScript script;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check that hasher_type and image.size() match?

"\nArguments:\n"
"1. seller_key (string, required) The public key of the possessor of the preimage.\n"
"2. refund_key (string, required) The public key of the recipient of the refund.\n"
"3. hash (string, required) SHA256 or RIPEMD160 hash of the preimage.\n"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe hash should be optional, and if not supplied a GetRandHash preimage should be selected and returned to the caller.

std::vector<unsigned char>& preimage
) const;

bool AddPreimage(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that you should persist the PreimageMap to disk.

const std::vector<unsigned char>& image,
const std::vector<unsigned char>& preimage
);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add a RemovePreimage, LockPreimage, and UnlockPreimage call, which could be used to ensure that a node no longer has the ability to solve a particular HTLC or does not until explicitly allowed. These should also go to disk.

if (request.fHelp || request.params.size() != 1)
throw runtime_error(
"importpreimage \"data\"\n"
"\nImports a preimage for use in HTLC transactions. Only remains in memory.\n"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you add persistence, be sure to update here.

// Only consider HTLC's "mine" if we own ALL the keys
// involved.
vector<valtype> keys;
keys.push_back(vSolutions[1]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe just for safety, assert(vSolutions.size() > 3)

@ebfull
Copy link
Author

ebfull commented Mar 31, 2017

Thanks for the reviews @arielg and @JeremyRubin. I intend to rebase this again and clean it up.

Also, BIP199 has been submitted to start standardizing what is in this PR.

@ABISprotocol
Copy link

@ebfull Thanks for mentioning... that was my question, regarding BIP 199, when reading this thread.

A few questions actually -

  1. Does BIP 199 need to be at final before this (HTLC) can be implemented in Core wallet? Probably dumb process question.
  2. Bitcoin wiki on Lightning network states in part, regarding "key features," that "payments can be routed across more than one blockchain (including altcoins and sidechains) as long as all the chains support the same hash function to use for the hash lock, as well as the ability the ability to create time locks." Although I see that this is not actually part of the proposed functionality here by way of the commits, might it ultimately allow the payment routing across more than one blockchain with further development?
  3. TX_HTLC transactions - What is the way in which they are accepted and what would be a sample condition in which one would obviously be rejected?

@jb55
Copy link
Contributor

jb55 commented Oct 24, 2017

This still alive?

@ebfull
Copy link
Author

ebfull commented Oct 26, 2017

Unfortunately I'm too busy to carry the torch on this PR. :(

@fanquake
Copy link
Member

I'll close this then. If someone wants to restart/pickup this work they can cherry pick/reference and open a new PR.

# activation should happen at block height 432 (3 periods)
min_activation_height = 432
height = self.nodes[0].getblockcount()
assert(height < 432)
Copy link

@takahser takahser Nov 21, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we use assert(height < min_activation_height) here instead?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can.

@bitcoin bitcoin locked as resolved and limited conversation to collaborators Dec 16, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.