electrum

Electrum Bitcoin wallet
git clone https://git.parazyd.org/electrum
Log | Files | Refs | Submodules

commit d7244f67088ad9516c948db0e3fdf31ea1ef03bb
parent ab7a854f9a716192a52b179004ae9d625b9e1bd8
Author: Janus <ysangkok@gmail.com>
Date:   Tue, 17 Apr 2018 12:35:22 +0200

lnbase: make_htlc_tx

Diffstat:
Mlib/lnbase.py | 43++++++++++++++++++++++++++++++++++++++++++-
Mlib/tests/test_lnbase.py | 18++++++++++++++----
2 files changed, 56 insertions(+), 5 deletions(-)

diff --git a/lib/lnbase.py b/lib/lnbase.py @@ -21,7 +21,6 @@ import binascii import hashlib import hmac import cryptography.hazmat.primitives.ciphers.aead as AEAD -from . import ripemd from .bitcoin import (public_key_from_private_key, ser_to_point, point_to_ser, string_to_number, deserialize_privkey, EC_KEY, rev_hex, int_to_hex, @@ -277,6 +276,48 @@ def derive_blinded_pubkey(basepoint, per_commitment_point): def overall_weight(num_htlc): return 500 + 172 * num_htlc + 224 +HTLC_TIMEOUT_WEIGHT = 663 +HTLC_SUCCESS_WEIGHT = 703 + +def make_htlc_tx(cltv_timeout, htlc_output_txid, htlc_output_index, remotehtlcsig, localhtlcsig, payment_preimage, amount_msat, local_feerate, revocationpubkey, local_delayedpubkey): + assert type(cltv_timeout) is int + assert type(htlc_output_txid) is str + assert type(htlc_output_index) is int + assert type(remotehtlcsig) is bytes + assert type(localhtlcsig) is bytes + assert type(payment_preimage) is bytes + assert type(amount_msat) is int + assert type(local_feerate) is int + assert type(revocationpubkey) is bytes + assert type(local_delayedpubkey) is bytes + c_inputs = [{ + 'type': 'p2wsh', + 'x_pubkeys': [bh2u(x) for x in [revocationpubkey, local_delayedpubkey]], + 'signatures': [bh2u(x) for x in [remotehtlcsig, localhtlcsig, payment_preimage]], + 'num_sig': 2, + 'prevout_n': htlc_output_index, + 'prevout_hash': htlc_output_txid, + 'value': amount_msat // 1000, + 'coinbase': False, + 'sequence': 0x0 + }] + script = bytes([opcodes.OP_IF]) \ + + bfh(push_script(bh2u(revocationpubkey))) \ + + bytes([opcodes.OP_ELSE]) \ + + bitcoin.add_number_to_script(0) \ + + bytes([opcodes.OP_CSV, opcodes.OP_DROP]) \ + + bfh(push_script(bh2u(local_delayedpubkey))) \ + + bytes([opcodes.OP_ENDIF, opcodes.OP_CHECKSIG]) + + p2wsh = bitcoin.redeem_script_to_address('p2wsh', bh2u(script)) + weight = HTLC_SUCCESS_WEIGHT if cltv_timeout == 0 else HTLC_TIMEOUT_WEIGHT + fee = local_feerate * weight + output = (bitcoin.TYPE_ADDRESS, p2wsh, amount_msat // 1000 - fee) + c_outputs = [output] + tx = Transaction.from_io(c_inputs, c_outputs, locktime=cltv_timeout, version=2) + tx.BIP_LI01_sort() + return tx + def make_offered_htlc(revocation_pubkey, remote_htlcpubkey, local_htlcpubkey, payment_preimage): assert type(revocation_pubkey) is bytes assert type(remote_htlcpubkey) is bytes diff --git a/lib/tests/test_lnbase.py b/lib/tests/test_lnbase.py @@ -3,7 +3,7 @@ import json import unittest from lib.util import bh2u, bfh -from lib.lnbase import make_commitment, get_obscured_ctn, Peer, make_offered_htlc, make_received_htlc +from lib.lnbase import make_commitment, get_obscured_ctn, Peer, make_offered_htlc, make_received_htlc, make_htlc_tx from lib.lnbase import secret_to_pubkey, derive_pubkey, derive_privkey, derive_blinded_pubkey from lib.transaction import Transaction from lib import bitcoin @@ -116,7 +116,12 @@ class Test_LNBase(unittest.TestCase): # local_signature = 30440220275b0c325a5e9355650dc30c0eccfbc7efb23987c24b556b9dfdd40effca18d202206caceb2c067836c51f296740c7ae807ffcbfbf1dd3a0d56b6de9a5b247985f06 output_commit_tx = "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8007e80300000000000022002052bfef0479d7b293c27e0f1eb294bea154c63a3294ef092c19af51409bce0e2ad007000000000000220020403d394747cae42e98ff01734ad5c08f82ba123d3d9a620abda88989651e2ab5d007000000000000220020748eba944fedc8827f6b06bc44678f93c0f9e6078b35c6331ed31e75f8ce0c2db80b000000000000220020c20b5d1f8584fd90443e7b7b720136174fa4b9333c261d04dbbd012635c0f419a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de843110e0a06a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e04004730440220275b0c325a5e9355650dc30c0eccfbc7efb23987c24b556b9dfdd40effca18d202206caceb2c067836c51f296740c7ae807ffcbfbf1dd3a0d56b6de9a5b247985f060147304402204fd4928835db1ccdfc40f5c78ce9bd65249b16348df81f0c44328dcdefc97d630220194d3869c38bc732dd87d13d2958015e2fc16829e74cd4377f84d215c0b7060601475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220" - htlcs = [(htlc2, 2000_000), (htlc3, 3000_000), (htlc0, 1000_000), (htlc1, 2000_000), (htlc4, 4000_000)] + htlc0_msat = 1000_000 + htlc2_msat = 2000_000 + htlc3_msat = 3000_000 + htlc1_msat = 2000_000 + htlc4_msat = 4000_000 + htlcs = [(htlc2, htlc2_msat), (htlc3, htlc3_msat), (htlc0, htlc0_msat), (htlc1, htlc1_msat), (htlc4, htlc4_msat)] our_commit_tx = make_commitment(commitment_number, local_funding_pubkey, remote_funding_pubkey, remotepubkey, @@ -127,7 +132,6 @@ class Test_LNBase(unittest.TestCase): self.sign_and_insert_remote_sig(our_commit_tx, remote_signature) self.assertEqual(str(our_commit_tx), output_commit_tx) - num_htlcs = 5 # (HTLC 0) signature_for_output_0_remote_htlc = "304402206a6e59f18764a5bf8d4fa45eebc591566689441229c918b480fb2af8cc6a4aeb02205248f273be447684b33e3c8d1d85a8e0ca9fa0bae9ae33f0527ada9c162919a6" # (HTLC 2) @@ -140,7 +144,13 @@ class Test_LNBase(unittest.TestCase): signature_for_output_4_remote_htlc = "304402207e0410e45454b0978a623f36a10626ef17b27d9ad44e2760f98cfa3efb37924f0220220bd8acd43ecaa916a80bd4f919c495a2c58982ce7c8625153f8596692a801d" # local_signature = 304402207cb324fa0de88f452ffa9389678127ebcf4cabe1dd848b8e076c1a1962bf34720220116ed922b12311bd602d67e60d2529917f21c5b82f25ff6506c0f87886b4dfd5 output_htlc_success_tx_0 = "020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219700000000000000000001e8030000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e050047304402206a6e59f18764a5bf8d4fa45eebc591566689441229c918b480fb2af8cc6a4aeb02205248f273be447684b33e3c8d1d85a8e0ca9fa0bae9ae33f0527ada9c162919a60147304402207cb324fa0de88f452ffa9389678127ebcf4cabe1dd848b8e076c1a1962bf34720220116ed922b12311bd602d67e60d2529917f21c5b82f25ff6506c0f87886b4dfd5012000000000000000000000000000000000000000000000000000000000000000008a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc688527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f401b175ac686800000000" - # local_signature = 3045022100c89172099507ff50f4c925e6c5150e871fb6e83dd73ff9fbb72f6ce829a9633f02203a63821d9162e99f9be712a68f9e589483994feae2661e4546cd5b6cec007be5 + local_signature_htlc0 = "3045022100c89172099507ff50f4c925e6c5150e871fb6e83dd73ff9fbb72f6ce829a9633f02203a63821d9162e99f9be712a68f9e589483994feae2661e4546cd5b6cec007be5" # TODO derive ourselves + + our_htlc0_tx = make_htlc_tx(0, our_commit_tx.txid(), htlc_output_index=0, remotehtlcsig=bfh(signature_for_output_0_remote_htlc), localhtlcsig=bfh(local_signature_htlc0), payment_preimage=htlc0_payment_preimage, amount_msat=htlc0_msat, local_feerate=local_feerate_per_kw, revocationpubkey=local_revocation_pubkey, local_delayedpubkey=local_delayedpubkey) + print(our_htlc0_tx) + print(output_htlc_success_tx_0) + self.assertEqual(str(our_htlc0_tx), output_htlc_success_tx_0) + output_htlc_timeout_tx_2 = "020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219701000000000000000001d0070000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100d5275b3619953cb0c3b5aa577f04bc512380e60fa551762ce3d7a1bb7401cff9022037237ab0dac3fe100cde094e82e2bed9ba0ed1bb40154b48e56aa70f259e608b01483045022100c89172099507ff50f4c925e6c5150e871fb6e83dd73ff9fbb72f6ce829a9633f02203a63821d9162e99f9be712a68f9e589483994feae2661e4546cd5b6cec007be501008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a914b43e1b38138a41b37f7cd9a1d274bc63e3a9b5d188ac6868f6010000" # local_signature = 3045022100def389deab09cee69eaa1ec14d9428770e45bcbe9feb46468ecf481371165c2f022015d2e3c46600b2ebba8dcc899768874cc6851fd1ecb3fffd15db1cc3de7e10da output_htlc_success_tx_1 = "020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219702000000000000000001d0070000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e050047304402201b63ec807771baf4fdff523c644080de17f1da478989308ad13a58b51db91d360220568939d38c9ce295adba15665fa68f51d967e8ed14a007b751540a80b325f20201483045022100def389deab09cee69eaa1ec14d9428770e45bcbe9feb46468ecf481371165c2f022015d2e3c46600b2ebba8dcc899768874cc6851fd1ecb3fffd15db1cc3de7e10da012001010101010101010101010101010101010101010101010101010101010101018a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a9144b6b2e5444c2639cc0fb7bcea5afba3f3cdce23988527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f501b175ac686800000000"