2017-09-26 07:47:39 +03:00
|
|
|
package lnwallet
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/sha256"
|
|
|
|
"encoding/hex"
|
|
|
|
"fmt"
|
|
|
|
"testing"
|
2019-01-27 21:20:41 +03:00
|
|
|
"time"
|
2017-09-26 07:47:39 +03:00
|
|
|
|
2018-06-05 04:34:16 +03:00
|
|
|
"github.com/btcsuite/btcd/btcec"
|
|
|
|
"github.com/btcsuite/btcd/chaincfg"
|
|
|
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
2019-01-27 21:20:41 +03:00
|
|
|
"github.com/btcsuite/btcd/txscript"
|
2018-06-05 04:34:16 +03:00
|
|
|
"github.com/btcsuite/btcd/wire"
|
|
|
|
"github.com/btcsuite/btcutil"
|
2018-07-31 10:17:17 +03:00
|
|
|
"github.com/davecgh/go-spew/spew"
|
|
|
|
"github.com/lightningnetwork/lnd/channeldb"
|
2019-01-16 17:47:43 +03:00
|
|
|
"github.com/lightningnetwork/lnd/input"
|
2018-07-31 10:17:17 +03:00
|
|
|
"github.com/lightningnetwork/lnd/keychain"
|
2019-10-31 05:43:05 +03:00
|
|
|
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
2018-07-31 10:17:17 +03:00
|
|
|
"github.com/lightningnetwork/lnd/lnwire"
|
|
|
|
"github.com/lightningnetwork/lnd/shachain"
|
2017-09-26 07:47:39 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This file implements that different types of transactions used in the
|
|
|
|
* lightning protocol are created correctly. To do so, the tests use the test
|
|
|
|
* vectors defined in Appendix B & C of BOLT 03.
|
|
|
|
*/
|
|
|
|
|
|
|
|
// testContext contains the test parameters defined in Appendix B & C of the
|
|
|
|
// BOLT 03 spec.
|
|
|
|
type testContext struct {
|
|
|
|
netParams *chaincfg.Params
|
|
|
|
block1 *btcutil.Block
|
|
|
|
|
|
|
|
fundingInputPrivKey *btcec.PrivateKey
|
|
|
|
localFundingPrivKey *btcec.PrivateKey
|
|
|
|
localPaymentPrivKey *btcec.PrivateKey
|
|
|
|
|
|
|
|
remoteFundingPubKey *btcec.PublicKey
|
|
|
|
localFundingPubKey *btcec.PublicKey
|
|
|
|
localRevocationPubKey *btcec.PublicKey
|
|
|
|
localPaymentPubKey *btcec.PublicKey
|
|
|
|
remotePaymentPubKey *btcec.PublicKey
|
|
|
|
localDelayPubKey *btcec.PublicKey
|
|
|
|
commitmentPoint *btcec.PublicKey
|
|
|
|
localPaymentBasePoint *btcec.PublicKey
|
|
|
|
remotePaymentBasePoint *btcec.PublicKey
|
|
|
|
|
|
|
|
fundingChangeAddress btcutil.Address
|
|
|
|
fundingInputUtxo *Utxo
|
|
|
|
fundingInputTxOut *wire.TxOut
|
|
|
|
fundingTx *btcutil.Tx
|
|
|
|
fundingOutpoint wire.OutPoint
|
|
|
|
shortChanID lnwire.ShortChannelID
|
|
|
|
|
|
|
|
htlcs []channeldb.HTLC
|
|
|
|
|
|
|
|
localCsvDelay uint16
|
|
|
|
fundingAmount btcutil.Amount
|
|
|
|
dustLimit btcutil.Amount
|
|
|
|
feePerKW btcutil.Amount
|
|
|
|
}
|
|
|
|
|
|
|
|
// getHTLC constructs an HTLC based on a configured HTLC with auxiliary data
|
|
|
|
// such as the remote signature from the htlcDesc. The partially defined HTLCs
|
|
|
|
// originate from the BOLT 03 spec and are contained in the test context.
|
|
|
|
func (tc *testContext) getHTLC(index int, desc *htlcDesc) (channeldb.HTLC, error) {
|
|
|
|
signature, err := hex.DecodeString(desc.remoteSigHex)
|
|
|
|
if err != nil {
|
|
|
|
return channeldb.HTLC{}, fmt.Errorf(
|
|
|
|
"Failed to parse serialized signature: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
htlc := tc.htlcs[desc.index]
|
|
|
|
return channeldb.HTLC{
|
|
|
|
Signature: signature,
|
|
|
|
RHash: htlc.RHash,
|
|
|
|
RefundTimeout: htlc.RefundTimeout,
|
|
|
|
Amt: htlc.Amt,
|
|
|
|
OutputIndex: int32(index),
|
|
|
|
Incoming: htlc.Incoming,
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// newTestContext populates a new testContext struct with the constant
|
|
|
|
// parameters defined in the BOLT 03 spec. This may return an error if any of
|
|
|
|
// the serialized parameters cannot be parsed.
|
|
|
|
func newTestContext() (tc *testContext, err error) {
|
|
|
|
tc = new(testContext)
|
|
|
|
|
|
|
|
const genesisHash = "0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206"
|
|
|
|
if tc.netParams, err = tc.createNetParams(genesisHash); err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
const block1Hex = "0000002006226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910fadbb20ea41a8423ea937e76e8151636bf6093b70eaff942930d20576600521fdc30f9858ffff7f20000000000101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff03510101ffffffff0100f2052a010000001976a9143ca33c2e4446f4a305f23c80df8ad1afdcf652f988ac00000000"
|
|
|
|
if tc.block1, err = blockFromHex(block1Hex); err != nil {
|
|
|
|
err = fmt.Errorf("Failed to parse serialized block: %v", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
const fundingInputPrivKeyHex = "6bd078650fcee8444e4e09825227b801a1ca928debb750eb36e6d56124bb20e8"
|
|
|
|
tc.fundingInputPrivKey, err = privkeyFromHex(fundingInputPrivKeyHex)
|
|
|
|
if err != nil {
|
|
|
|
err = fmt.Errorf("Failed to parse serialized privkey: %v", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
const localFundingPrivKeyHex = "30ff4956bbdd3222d44cc5e8a1261dab1e07957bdac5ae88fe3261ef321f3749"
|
|
|
|
tc.localFundingPrivKey, err = privkeyFromHex(localFundingPrivKeyHex)
|
|
|
|
if err != nil {
|
|
|
|
err = fmt.Errorf("Failed to parse serialized privkey: %v", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
const localPaymentPrivKeyHex = "bb13b121cdc357cd2e608b0aea294afca36e2b34cf958e2e6451a2f274694491"
|
|
|
|
tc.localPaymentPrivKey, err = privkeyFromHex(localPaymentPrivKeyHex)
|
|
|
|
if err != nil {
|
|
|
|
err = fmt.Errorf("Failed to parse serialized privkey: %v", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
const localFundingPubKeyHex = "023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb"
|
|
|
|
tc.localFundingPubKey, err = pubkeyFromHex(localFundingPubKeyHex)
|
|
|
|
if err != nil {
|
|
|
|
err = fmt.Errorf("Failed to parse serialized pubkey: %v", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
const remoteFundingPubKeyHex = "030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c1"
|
|
|
|
tc.remoteFundingPubKey, err = pubkeyFromHex(remoteFundingPubKeyHex)
|
|
|
|
if err != nil {
|
|
|
|
err = fmt.Errorf("Failed to parse serialized pubkey: %v", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
const localRevocationPubKeyHex = "0212a140cd0c6539d07cd08dfe09984dec3251ea808b892efeac3ede9402bf2b19"
|
|
|
|
tc.localRevocationPubKey, err = pubkeyFromHex(localRevocationPubKeyHex)
|
|
|
|
if err != nil {
|
|
|
|
err = fmt.Errorf("Failed to parse serialized pubkey: %v", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
const localPaymentPubKeyHex = "030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e7"
|
|
|
|
tc.localPaymentPubKey, err = pubkeyFromHex(localPaymentPubKeyHex)
|
|
|
|
if err != nil {
|
|
|
|
err = fmt.Errorf("Failed to parse serialized pubkey: %v", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
const remotePaymentPubKeyHex = "0394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b"
|
|
|
|
tc.remotePaymentPubKey, err = pubkeyFromHex(remotePaymentPubKeyHex)
|
|
|
|
if err != nil {
|
|
|
|
err = fmt.Errorf("Failed to parse serialized pubkey: %v", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
const localDelayPubKeyHex = "03fd5960528dc152014952efdb702a88f71e3c1653b2314431701ec77e57fde83c"
|
|
|
|
tc.localDelayPubKey, err = pubkeyFromHex(localDelayPubKeyHex)
|
|
|
|
if err != nil {
|
|
|
|
err = fmt.Errorf("Failed to parse serialized pubkey: %v", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
const commitmentPointHex = "025f7117a78150fe2ef97db7cfc83bd57b2e2c0d0dd25eaf467a4a1c2a45ce1486"
|
|
|
|
tc.commitmentPoint, err = pubkeyFromHex(commitmentPointHex)
|
|
|
|
if err != nil {
|
|
|
|
err = fmt.Errorf("Failed to parse serialized pubkey: %v", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
const localPaymentBasePointHex = "034f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa"
|
|
|
|
tc.localPaymentBasePoint, err = pubkeyFromHex(localPaymentBasePointHex)
|
|
|
|
if err != nil {
|
|
|
|
err = fmt.Errorf("Failed to parse serialized pubkey: %v", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
const remotePaymentBasePointHex = "032c0b7cf95324a07d05398b240174dc0c2be444d96b159aa6c7f7b1e668680991"
|
|
|
|
tc.remotePaymentBasePoint, err = pubkeyFromHex(remotePaymentBasePointHex)
|
|
|
|
if err != nil {
|
|
|
|
err = fmt.Errorf("Failed to parse serialized pubkey: %v", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-04-18 05:26:32 +03:00
|
|
|
const fundingChangeAddressStr = "bcrt1qgyeqfmptyh780dsk32qawsvdffc2g5q5sxamg0"
|
2017-09-26 07:47:39 +03:00
|
|
|
tc.fundingChangeAddress, err = btcutil.DecodeAddress(
|
|
|
|
fundingChangeAddressStr, tc.netParams)
|
|
|
|
if err != nil {
|
|
|
|
err = fmt.Errorf("Failed to parse address: %v", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
tc.fundingInputUtxo, tc.fundingInputTxOut, err = tc.extractFundingInput()
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
const fundingTxHex = "0200000001adbb20ea41a8423ea937e76e8151636bf6093b70eaff942930d20576600521fd000000006b48304502210090587b6201e166ad6af0227d3036a9454223d49a1f11839c1a362184340ef0240220577f7cd5cca78719405cbf1de7414ac027f0239ef6e214c90fcaab0454d84b3b012103535b32d5eb0a6ed0982a0479bbadc9868d9836f6ba94dd5a63be16d875069184ffffffff028096980000000000220020c015c4a6be010e21657068fc2e6a9d02b27ebe4d490a25846f7237f104d1a3cd20256d29010000001600143ca33c2e4446f4a305f23c80df8ad1afdcf652f900000000"
|
|
|
|
if tc.fundingTx, err = txFromHex(fundingTxHex); err != nil {
|
|
|
|
err = fmt.Errorf("Failed to parse serialized tx: %v", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
tc.fundingOutpoint = wire.OutPoint{
|
|
|
|
Hash: *tc.fundingTx.Hash(),
|
|
|
|
Index: 0,
|
|
|
|
}
|
|
|
|
|
|
|
|
tc.shortChanID = lnwire.ShortChannelID{
|
|
|
|
BlockHeight: 1,
|
|
|
|
TxIndex: 0,
|
|
|
|
TxPosition: 0,
|
|
|
|
}
|
|
|
|
|
2020-05-28 14:02:18 +03:00
|
|
|
tc.htlcs = make([]channeldb.HTLC, len(testHtlcs))
|
|
|
|
for i, htlc := range testHtlcs {
|
2017-09-26 07:47:39 +03:00
|
|
|
preimage, decodeErr := hex.DecodeString(htlc.preimage)
|
|
|
|
if decodeErr != nil {
|
|
|
|
err = fmt.Errorf("Failed to decode HTLC preimage: %v", decodeErr)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
tc.htlcs[i].RHash = sha256.Sum256(preimage)
|
|
|
|
tc.htlcs[i].Amt = htlc.amount
|
|
|
|
tc.htlcs[i].RefundTimeout = htlc.expiry
|
|
|
|
tc.htlcs[i].Incoming = htlc.incoming
|
|
|
|
}
|
|
|
|
|
|
|
|
tc.localCsvDelay = 144
|
|
|
|
tc.fundingAmount = 10000000
|
|
|
|
tc.dustLimit = 546
|
|
|
|
tc.feePerKW = 15000
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// createNetParams is used by newTestContext to construct new chain parameters
|
|
|
|
// as required by the BOLT 03 spec.
|
|
|
|
func (tc *testContext) createNetParams(genesisHashStr string) (*chaincfg.Params, error) {
|
|
|
|
params := chaincfg.RegressionNetParams
|
|
|
|
|
|
|
|
// Ensure regression net genesis block matches the one listed in BOLT spec.
|
|
|
|
expectedGenesisHash, err := chainhash.NewHashFromStr(genesisHashStr)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if !params.GenesisHash.IsEqual(expectedGenesisHash) {
|
|
|
|
err = fmt.Errorf("Expected regression net genesis hash to be %s, "+
|
|
|
|
"got %s", expectedGenesisHash, params.GenesisHash)
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return ¶ms, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// extractFundingInput returns references to the transaction output of the
|
|
|
|
// coinbase transaction which is used to fund the channel in the test vectors.
|
|
|
|
func (tc *testContext) extractFundingInput() (*Utxo, *wire.TxOut, error) {
|
|
|
|
expectedTxHashHex := "fd2105607605d2302994ffea703b09f66b6351816ee737a93e42a841ea20bbad"
|
|
|
|
expectedTxHash, err := chainhash.NewHashFromStr(expectedTxHashHex)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, fmt.Errorf("Failed to parse transaction hash: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
tx, err := tc.block1.Tx(0)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, fmt.Errorf("Failed to get coinbase transaction from "+
|
|
|
|
"block 1: %v", err)
|
|
|
|
}
|
|
|
|
txout := tx.MsgTx().TxOut[0]
|
|
|
|
|
|
|
|
var expectedAmount int64 = 5000000000
|
|
|
|
if txout.Value != expectedAmount {
|
|
|
|
return nil, nil, fmt.Errorf("Coinbase transaction output amount from "+
|
|
|
|
"block 1 does not match expected output amount: "+
|
|
|
|
"expected %v, got %v", expectedAmount, txout.Value)
|
|
|
|
}
|
|
|
|
if !tx.Hash().IsEqual(expectedTxHash) {
|
|
|
|
return nil, nil, fmt.Errorf("Coinbase transaction hash from block 1 "+
|
|
|
|
"does not match expected hash: expected %v, got %v", expectedTxHash,
|
|
|
|
tx.Hash())
|
|
|
|
}
|
|
|
|
|
|
|
|
block1Utxo := Utxo{
|
2018-02-18 02:25:55 +03:00
|
|
|
AddressType: WitnessPubKey,
|
2017-09-26 07:47:39 +03:00
|
|
|
Value: btcutil.Amount(txout.Value),
|
|
|
|
OutPoint: wire.OutPoint{
|
|
|
|
Hash: *tx.Hash(),
|
|
|
|
Index: 0,
|
|
|
|
},
|
|
|
|
PkScript: txout.PkScript,
|
|
|
|
}
|
|
|
|
return &block1Utxo, txout, nil
|
|
|
|
}
|
|
|
|
|
2020-05-28 14:02:18 +03:00
|
|
|
var testHtlcs = []struct {
|
|
|
|
incoming bool
|
|
|
|
amount lnwire.MilliSatoshi
|
|
|
|
expiry uint32
|
|
|
|
preimage string
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
incoming: true,
|
|
|
|
amount: 1000000,
|
|
|
|
expiry: 500,
|
|
|
|
preimage: "0000000000000000000000000000000000000000000000000000000000000000",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
incoming: true,
|
|
|
|
amount: 2000000,
|
|
|
|
expiry: 501,
|
|
|
|
preimage: "0101010101010101010101010101010101010101010101010101010101010101",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
incoming: false,
|
|
|
|
amount: 2000000,
|
|
|
|
expiry: 502,
|
|
|
|
preimage: "0202020202020202020202020202020202020202020202020202020202020202",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
incoming: false,
|
|
|
|
amount: 3000000,
|
|
|
|
expiry: 503,
|
|
|
|
preimage: "0303030303030303030303030303030303030303030303030303030303030303",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
incoming: true,
|
|
|
|
amount: 4000000,
|
|
|
|
expiry: 504,
|
|
|
|
preimage: "0404040404040404040404040404040404040404040404040404040404040404",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2020-06-02 15:39:52 +03:00
|
|
|
// htlcDesc is a description used to construct each HTLC in each test case.
|
|
|
|
type htlcDesc struct {
|
|
|
|
index int
|
|
|
|
remoteSigHex string
|
|
|
|
resolutionTxHex string
|
|
|
|
}
|
|
|
|
|
2020-06-02 15:40:33 +03:00
|
|
|
type testCase struct {
|
2020-05-28 14:02:18 +03:00
|
|
|
commitment channeldb.ChannelCommitment
|
|
|
|
htlcDescs []htlcDesc
|
|
|
|
expectedCommitmentTxHex string
|
|
|
|
remoteSigHex string
|
2020-06-02 15:40:33 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// testCases encode the raw test vectors specified in Appendix C of BOLT 03.
|
|
|
|
var testCases = []testCase{
|
2020-05-28 14:02:18 +03:00
|
|
|
{
|
|
|
|
commitment: channeldb.ChannelCommitment{
|
|
|
|
CommitHeight: 42,
|
|
|
|
LocalBalance: 7000000000,
|
|
|
|
RemoteBalance: 3000000000,
|
|
|
|
FeePerKw: 15000,
|
|
|
|
},
|
|
|
|
htlcDescs: []htlcDesc{},
|
|
|
|
expectedCommitmentTxHex: "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8002c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de84311054a56a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0400473044022051b75c73198c6deee1a875871c3961832909acd297c6b908d59e3319e5185a46022055c419379c5051a78d00dbbce11b5b664a0c22815fbcc6fcef6b1937c383693901483045022100f51d2e566a70ba740fc5d8c0f07b9b93d2ed741c3c0860c613173de7d39e7968022041376d520e9c0e1ad52248ddf4b22e12be8763007df977253ef45a4ca3bdb7c001475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220",
|
|
|
|
remoteSigHex: "3045022100f51d2e566a70ba740fc5d8c0f07b9b93d2ed741c3c0860c613173de7d39e7968022041376d520e9c0e1ad52248ddf4b22e12be8763007df977253ef45a4ca3bdb7c0",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
commitment: channeldb.ChannelCommitment{
|
|
|
|
CommitHeight: 42,
|
|
|
|
LocalBalance: 6988000000,
|
|
|
|
RemoteBalance: 3000000000,
|
|
|
|
FeePerKw: 647,
|
|
|
|
},
|
|
|
|
htlcDescs: []htlcDesc{
|
|
|
|
{
|
|
|
|
index: 0,
|
|
|
|
remoteSigHex: "30440220385a5afe75632f50128cbb029ee95c80156b5b4744beddc729ad339c9ca432c802202ba5f48550cad3379ac75b9b4fedb86a35baa6947f16ba5037fb8b11ab343740",
|
|
|
|
resolutionTxHex: "020000000001018323148ce2419f21ca3d6780053747715832e18ac780931a514b187768882bb60000000000000000000122020000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e05004730440220385a5afe75632f50128cbb029ee95c80156b5b4744beddc729ad339c9ca432c802202ba5f48550cad3379ac75b9b4fedb86a35baa6947f16ba5037fb8b11ab3437400147304402205999590b8a79fa346e003a68fd40366397119b2b0cdf37b149968d6bc6fbcc4702202b1e1fb5ab7864931caed4e732c359e0fe3d86a548b557be2246efb1708d579a012000000000000000000000000000000000000000000000000000000000000000008a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc688527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f401b175ac686800000000",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
index: 2,
|
|
|
|
remoteSigHex: "304402207ceb6678d4db33d2401fdc409959e57c16a6cb97a30261d9c61f29b8c58d34b90220084b4a17b4ca0e86f2d798b3698ca52de5621f2ce86f80bed79afa66874511b0",
|
|
|
|
resolutionTxHex: "020000000001018323148ce2419f21ca3d6780053747715832e18ac780931a514b187768882bb60100000000000000000124060000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e050047304402207ceb6678d4db33d2401fdc409959e57c16a6cb97a30261d9c61f29b8c58d34b90220084b4a17b4ca0e86f2d798b3698ca52de5621f2ce86f80bed79afa66874511b00147304402207ff03eb0127fc7c6cae49cc29e2a586b98d1e8969cf4a17dfa50b9c2647720b902205e2ecfda2252956c0ca32f175080e75e4e390e433feb1f8ce9f2ba55648a1dac01008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a914b43e1b38138a41b37f7cd9a1d274bc63e3a9b5d188ac6868f6010000",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
index: 1,
|
|
|
|
remoteSigHex: "304402206a401b29a0dff0d18ec903502c13d83e7ec019450113f4a7655a4ce40d1f65ba0220217723a084e727b6ca0cc8b6c69c014a7e4a01fcdcba3e3993f462a3c574d833",
|
|
|
|
resolutionTxHex: "020000000001018323148ce2419f21ca3d6780053747715832e18ac780931a514b187768882bb6020000000000000000010a060000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e050047304402206a401b29a0dff0d18ec903502c13d83e7ec019450113f4a7655a4ce40d1f65ba0220217723a084e727b6ca0cc8b6c69c014a7e4a01fcdcba3e3993f462a3c574d83301483045022100d50d067ca625d54e62df533a8f9291736678d0b86c28a61bb2a80cf42e702d6e02202373dde7e00218eacdafb9415fe0e1071beec1857d1af3c6a201a44cbc47c877012001010101010101010101010101010101010101010101010101010101010101018a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a9144b6b2e5444c2639cc0fb7bcea5afba3f3cdce23988527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f501b175ac686800000000",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
index: 3,
|
|
|
|
remoteSigHex: "30450221009b1c987ba599ee3bde1dbca776b85481d70a78b681a8d84206723e2795c7cac002207aac84ad910f8598c4d1c0ea2e3399cf6627a4e3e90131315bc9f038451ce39d",
|
|
|
|
resolutionTxHex: "020000000001018323148ce2419f21ca3d6780053747715832e18ac780931a514b187768882bb6030000000000000000010c0a0000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e05004830450221009b1c987ba599ee3bde1dbca776b85481d70a78b681a8d84206723e2795c7cac002207aac84ad910f8598c4d1c0ea2e3399cf6627a4e3e90131315bc9f038451ce39d01483045022100db9dc65291077a52728c622987e9895b7241d4394d6dcb916d7600a3e8728c22022036ee3ee717ba0bb5c45ee84bc7bbf85c0f90f26ae4e4a25a6b4241afa8a3f1cb01008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868f7010000",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
index: 4,
|
|
|
|
remoteSigHex: "3045022100cc28030b59f0914f45b84caa983b6f8effa900c952310708c2b5b00781117022022027ba2ccdf94d03c6d48b327f183f6e28c8a214d089b9227f94ac4f85315274f0",
|
|
|
|
resolutionTxHex: "020000000001018323148ce2419f21ca3d6780053747715832e18ac780931a514b187768882bb604000000000000000001da0d0000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100cc28030b59f0914f45b84caa983b6f8effa900c952310708c2b5b00781117022022027ba2ccdf94d03c6d48b327f183f6e28c8a214d089b9227f94ac4f85315274f00147304402202d1a3c0d31200265d2a2def2753ead4959ae20b4083e19553acfffa5dfab60bf022020ede134149504e15b88ab261a066de49848411e15e70f9e6a5462aec2949f8f012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
expectedCommitmentTxHex: "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8007e80300000000000022002052bfef0479d7b293c27e0f1eb294bea154c63a3294ef092c19af51409bce0e2ad007000000000000220020403d394747cae42e98ff01734ad5c08f82ba123d3d9a620abda88989651e2ab5d007000000000000220020748eba944fedc8827f6b06bc44678f93c0f9e6078b35c6331ed31e75f8ce0c2db80b000000000000220020c20b5d1f8584fd90443e7b7b720136174fa4b9333c261d04dbbd012635c0f419a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de843110e09c6a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e040048304502210094bfd8f5572ac0157ec76a9551b6c5216a4538c07cd13a51af4a54cb26fa14320220768efce8ce6f4a5efac875142ff19237c011343670adf9c7ac69704a120d116301483045022100a5c01383d3ec646d97e40f44318d49def817fcd61a0ef18008a665b3e151785502203e648efddd5838981ef55ec954be69c4a652d021e6081a100d034de366815e9b01475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220",
|
|
|
|
remoteSigHex: "3045022100a5c01383d3ec646d97e40f44318d49def817fcd61a0ef18008a665b3e151785502203e648efddd5838981ef55ec954be69c4a652d021e6081a100d034de366815e9b",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
commitment: channeldb.ChannelCommitment{
|
|
|
|
CommitHeight: 42,
|
|
|
|
LocalBalance: 6988000000,
|
|
|
|
RemoteBalance: 3000000000,
|
|
|
|
FeePerKw: 648,
|
|
|
|
},
|
|
|
|
htlcDescs: []htlcDesc{
|
|
|
|
{
|
|
|
|
index: 2,
|
|
|
|
remoteSigHex: "3044022062ef2e77591409d60d7817d9bb1e71d3c4a2931d1a6c7c8307422c84f001a251022022dad9726b0ae3fe92bda745a06f2c00f92342a186d84518588cf65f4dfaada8",
|
|
|
|
resolutionTxHex: "02000000000101579c183eca9e8236a5d7f5dcd79cfec32c497fdc0ec61533cde99ecd436cadd10000000000000000000123060000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500473044022062ef2e77591409d60d7817d9bb1e71d3c4a2931d1a6c7c8307422c84f001a251022022dad9726b0ae3fe92bda745a06f2c00f92342a186d84518588cf65f4dfaada801483045022100a4c574f00411dd2f978ca5cdc1b848c311cd7849c087ad2f21a5bce5e8cc5ae90220090ae39a9bce2fb8bc879d7e9f9022df249f41e25e51f1a9bf6447a9eeffc09801008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a914b43e1b38138a41b37f7cd9a1d274bc63e3a9b5d188ac6868f6010000",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
index: 1,
|
|
|
|
remoteSigHex: "3045022100e968cbbb5f402ed389fdc7f6cd2a80ed650bb42c79aeb2a5678444af94f6c78502204b47a1cb24ab5b0b6fe69fe9cfc7dba07b9dd0d8b95f372c1d9435146a88f8d4",
|
|
|
|
resolutionTxHex: "02000000000101579c183eca9e8236a5d7f5dcd79cfec32c497fdc0ec61533cde99ecd436cadd10100000000000000000109060000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100e968cbbb5f402ed389fdc7f6cd2a80ed650bb42c79aeb2a5678444af94f6c78502204b47a1cb24ab5b0b6fe69fe9cfc7dba07b9dd0d8b95f372c1d9435146a88f8d40147304402207679cf19790bea76a733d2fa0672bd43ab455687a068f815a3d237581f57139a0220683a1a799e102071c206b207735ca80f627ab83d6616b4bcd017c5d79ef3e7d0012001010101010101010101010101010101010101010101010101010101010101018a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a9144b6b2e5444c2639cc0fb7bcea5afba3f3cdce23988527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f501b175ac686800000000",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
index: 3,
|
|
|
|
remoteSigHex: "3045022100aa91932e305292cf9969cc23502bbf6cef83a5df39c95ad04a707c4f4fed5c7702207099fc0f3a9bfe1e7683c0e9aa5e76c5432eb20693bf4cb182f04d383dc9c8c2",
|
|
|
|
resolutionTxHex: "02000000000101579c183eca9e8236a5d7f5dcd79cfec32c497fdc0ec61533cde99ecd436cadd1020000000000000000010b0a0000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100aa91932e305292cf9969cc23502bbf6cef83a5df39c95ad04a707c4f4fed5c7702207099fc0f3a9bfe1e7683c0e9aa5e76c5432eb20693bf4cb182f04d383dc9c8c20147304402200df76fea718745f3c529bac7fd37923e7309ce38b25c0781e4cf514dd9ef8dc802204172295739dbae9fe0474dcee3608e3433b4b2af3a2e6787108b02f894dcdda301008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868f7010000",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
index: 4,
|
|
|
|
remoteSigHex: "3044022035cac88040a5bba420b1c4257235d5015309113460bc33f2853cd81ca36e632402202fc94fd3e81e9d34a9d01782a0284f3044370d03d60f3fc041e2da088d2de58f",
|
|
|
|
resolutionTxHex: "02000000000101579c183eca9e8236a5d7f5dcd79cfec32c497fdc0ec61533cde99ecd436cadd103000000000000000001d90d0000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500473044022035cac88040a5bba420b1c4257235d5015309113460bc33f2853cd81ca36e632402202fc94fd3e81e9d34a9d01782a0284f3044370d03d60f3fc041e2da088d2de58f0147304402200daf2eb7afd355b4caf6fb08387b5f031940ea29d1a9f35071288a839c9039e4022067201b562456e7948616c13acb876b386b511599b58ac1d94d127f91c50463a6012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
expectedCommitmentTxHex: "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8006d007000000000000220020403d394747cae42e98ff01734ad5c08f82ba123d3d9a620abda88989651e2ab5d007000000000000220020748eba944fedc8827f6b06bc44678f93c0f9e6078b35c6331ed31e75f8ce0c2db80b000000000000220020c20b5d1f8584fd90443e7b7b720136174fa4b9333c261d04dbbd012635c0f419a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de8431104e9d6a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0400483045022100a2270d5950c89ae0841233f6efea9c951898b301b2e89e0adbd2c687b9f32efa02207943d90f95b9610458e7c65a576e149750ff3accaacad004cd85e70b235e27de01473044022072714e2fbb93cdd1c42eb0828b4f2eff143f717d8f26e79d6ada4f0dcb681bbe02200911be4e5161dd6ebe59ff1c58e1997c4aea804f81db6b698821db6093d7b05701475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220",
|
|
|
|
remoteSigHex: "3044022072714e2fbb93cdd1c42eb0828b4f2eff143f717d8f26e79d6ada4f0dcb681bbe02200911be4e5161dd6ebe59ff1c58e1997c4aea804f81db6b698821db6093d7b057",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
commitment: channeldb.ChannelCommitment{
|
|
|
|
CommitHeight: 42,
|
|
|
|
LocalBalance: 6988000000,
|
|
|
|
RemoteBalance: 3000000000,
|
|
|
|
FeePerKw: 2069,
|
|
|
|
},
|
|
|
|
htlcDescs: []htlcDesc{
|
|
|
|
{
|
|
|
|
index: 2,
|
|
|
|
remoteSigHex: "3045022100d1cf354de41c1369336cf85b225ed033f1f8982a01be503668df756a7e668b66022001254144fb4d0eecc61908fccc3388891ba17c5d7a1a8c62bdd307e5a513f992",
|
|
|
|
resolutionTxHex: "02000000000101ca94a9ad516ebc0c4bdd7b6254871babfa978d5accafb554214137d398bfcf6a0000000000000000000175020000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100d1cf354de41c1369336cf85b225ed033f1f8982a01be503668df756a7e668b66022001254144fb4d0eecc61908fccc3388891ba17c5d7a1a8c62bdd307e5a513f99201473044022056eb1af429660e45a1b0b66568cb8c4a3aa7e4c9c292d5d6c47f86ebf2c8838f022065c3ac4ebe980ca7a41148569be4ad8751b0a724a41405697ec55035dae6640201008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a914b43e1b38138a41b37f7cd9a1d274bc63e3a9b5d188ac6868f6010000",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
index: 1,
|
|
|
|
remoteSigHex: "3045022100d065569dcb94f090345402736385efeb8ea265131804beac06dd84d15dd2d6880220664feb0b4b2eb985fadb6ec7dc58c9334ea88ce599a9be760554a2d4b3b5d9f4",
|
|
|
|
resolutionTxHex: "02000000000101ca94a9ad516ebc0c4bdd7b6254871babfa978d5accafb554214137d398bfcf6a0100000000000000000122020000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100d065569dcb94f090345402736385efeb8ea265131804beac06dd84d15dd2d6880220664feb0b4b2eb985fadb6ec7dc58c9334ea88ce599a9be760554a2d4b3b5d9f401483045022100914bb232cd4b2690ee3d6cb8c3713c4ac9c4fb925323068d8b07f67c8541f8d9022057152f5f1615b793d2d45aac7518989ae4fe970f28b9b5c77504799d25433f7f012001010101010101010101010101010101010101010101010101010101010101018a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a9144b6b2e5444c2639cc0fb7bcea5afba3f3cdce23988527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f501b175ac686800000000",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
index: 3,
|
|
|
|
remoteSigHex: "3045022100d4e69d363de993684eae7b37853c40722a4c1b4a7b588ad7b5d8a9b5006137a102207a069c628170ee34be5612747051bdcc087466dbaa68d5756ea81c10155aef18",
|
|
|
|
resolutionTxHex: "02000000000101ca94a9ad516ebc0c4bdd7b6254871babfa978d5accafb554214137d398bfcf6a020000000000000000015d060000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100d4e69d363de993684eae7b37853c40722a4c1b4a7b588ad7b5d8a9b5006137a102207a069c628170ee34be5612747051bdcc087466dbaa68d5756ea81c10155aef180147304402200e362443f7af830b419771e8e1614fc391db3a4eb799989abfc5ab26d6fcd032022039ab0cad1c14dfbe9446bf847965e56fe016e0cbcf719fd18c1bfbf53ecbd9f901008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868f7010000",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
index: 4,
|
|
|
|
remoteSigHex: "30450221008ec888e36e4a4b3dc2ed6b823319855b2ae03006ca6ae0d9aa7e24bfc1d6f07102203b0f78885472a67ff4fe5916c0bb669487d659527509516fc3a08e87a2cc0a7c",
|
|
|
|
resolutionTxHex: "02000000000101ca94a9ad516ebc0c4bdd7b6254871babfa978d5accafb554214137d398bfcf6a03000000000000000001f2090000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e05004830450221008ec888e36e4a4b3dc2ed6b823319855b2ae03006ca6ae0d9aa7e24bfc1d6f07102203b0f78885472a67ff4fe5916c0bb669487d659527509516fc3a08e87a2cc0a7c0147304402202c3e14282b84b02705dfd00a6da396c9fe8a8bcb1d3fdb4b20a4feba09440e8b02202b058b39aa9b0c865b22095edcd9ff1f71bbfe20aa4993755e54d042755ed0d5012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
expectedCommitmentTxHex: "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8006d007000000000000220020403d394747cae42e98ff01734ad5c08f82ba123d3d9a620abda88989651e2ab5d007000000000000220020748eba944fedc8827f6b06bc44678f93c0f9e6078b35c6331ed31e75f8ce0c2db80b000000000000220020c20b5d1f8584fd90443e7b7b720136174fa4b9333c261d04dbbd012635c0f419a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de84311077956a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e040047304402203ca8f31c6a47519f83255dc69f1894d9a6d7476a19f498d31eaf0cd3a85eeb63022026fd92dc752b33905c4c838c528b692a8ad4ced959990b5d5ee2ff940fa90eea01473044022001d55e488b8b035b2dd29d50b65b530923a416d47f377284145bc8767b1b6a75022019bb53ddfe1cefaf156f924777eaaf8fdca1810695a7d0a247ad2afba8232eb401475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220",
|
|
|
|
remoteSigHex: "3044022001d55e488b8b035b2dd29d50b65b530923a416d47f377284145bc8767b1b6a75022019bb53ddfe1cefaf156f924777eaaf8fdca1810695a7d0a247ad2afba8232eb4",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
commitment: channeldb.ChannelCommitment{
|
|
|
|
CommitHeight: 42,
|
|
|
|
LocalBalance: 6988000000,
|
|
|
|
RemoteBalance: 3000000000,
|
|
|
|
FeePerKw: 2070,
|
|
|
|
},
|
|
|
|
htlcDescs: []htlcDesc{
|
|
|
|
{
|
|
|
|
index: 2,
|
|
|
|
remoteSigHex: "3045022100eed143b1ee4bed5dc3cde40afa5db3e7354cbf9c44054b5f713f729356f08cf7022077161d171c2bbd9badf3c9934de65a4918de03bbac1450f715275f75b103f891",
|
|
|
|
resolutionTxHex: "0200000000010140a83ce364747ff277f4d7595d8d15f708418798922c40bc2b056aca5485a2180000000000000000000174020000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100eed143b1ee4bed5dc3cde40afa5db3e7354cbf9c44054b5f713f729356f08cf7022077161d171c2bbd9badf3c9934de65a4918de03bbac1450f715275f75b103f89101483045022100a0d043ed533e7fb1911e0553d31a8e2f3e6de19dbc035257f29d747c5e02f1f5022030cd38d8e84282175d49c1ebe0470db3ebd59768cf40780a784e248a43904fb801008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a914b43e1b38138a41b37f7cd9a1d274bc63e3a9b5d188ac6868f6010000",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
index: 3,
|
|
|
|
remoteSigHex: "3044022071e9357619fd8d29a411dc053b326a5224c5d11268070e88ecb981b174747c7a02202b763ae29a9d0732fa8836dd8597439460b50472183f420021b768981b4f7cf6",
|
|
|
|
resolutionTxHex: "0200000000010140a83ce364747ff277f4d7595d8d15f708418798922c40bc2b056aca5485a218010000000000000000015c060000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500473044022071e9357619fd8d29a411dc053b326a5224c5d11268070e88ecb981b174747c7a02202b763ae29a9d0732fa8836dd8597439460b50472183f420021b768981b4f7cf601483045022100adb1d679f65f96178b59f23ed37d3b70443118f345224a07ecb043eee2acc157022034d24524fe857144a3bcfff3065a9994d0a6ec5f11c681e49431d573e242612d01008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868f7010000",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
index: 4,
|
|
|
|
remoteSigHex: "3045022100c9458a4d2cbb741705577deb0a890e5cb90ee141be0400d3162e533727c9cb2102206edcf765c5dc5e5f9b976ea8149bf8607b5a0efb30691138e1231302b640d2a4",
|
|
|
|
resolutionTxHex: "0200000000010140a83ce364747ff277f4d7595d8d15f708418798922c40bc2b056aca5485a21802000000000000000001f1090000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100c9458a4d2cbb741705577deb0a890e5cb90ee141be0400d3162e533727c9cb2102206edcf765c5dc5e5f9b976ea8149bf8607b5a0efb30691138e1231302b640d2a40147304402200831422aa4e1ee6d55e0b894201770a8f8817a189356f2d70be76633ffa6a6f602200dd1b84a4855dc6727dd46c98daae43dfc70889d1ba7ef0087529a57c06e5e04012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
expectedCommitmentTxHex: "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8005d007000000000000220020403d394747cae42e98ff01734ad5c08f82ba123d3d9a620abda88989651e2ab5b80b000000000000220020c20b5d1f8584fd90443e7b7b720136174fa4b9333c261d04dbbd012635c0f419a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de843110da966a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e04004730440220443cb07f650aebbba14b8bc8d81e096712590f524c5991ac0ed3bbc8fd3bd0c7022028a635f548e3ca64b19b69b1ea00f05b22752f91daf0b6dab78e62ba52eb7fd001483045022100f2377f7a67b7fc7f4e2c0c9e3a7de935c32417f5668eda31ea1db401b7dc53030220415fdbc8e91d0f735e70c21952342742e25249b0d062d43efbfc564499f3752601475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220",
|
|
|
|
remoteSigHex: "3045022100f2377f7a67b7fc7f4e2c0c9e3a7de935c32417f5668eda31ea1db401b7dc53030220415fdbc8e91d0f735e70c21952342742e25249b0d062d43efbfc564499f37526",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
commitment: channeldb.ChannelCommitment{
|
|
|
|
CommitHeight: 42,
|
|
|
|
LocalBalance: 6988000000,
|
|
|
|
RemoteBalance: 3000000000,
|
|
|
|
FeePerKw: 2194,
|
|
|
|
},
|
|
|
|
htlcDescs: []htlcDesc{
|
|
|
|
{
|
|
|
|
index: 2,
|
|
|
|
remoteSigHex: "30450221009ed2f0a67f99e29c3c8cf45c08207b765980697781bb727fe0b1416de0e7622902206052684229bc171419ed290f4b615c943f819c0262414e43c5b91dcf72ddcf44",
|
|
|
|
resolutionTxHex: "02000000000101fb824d4e4dafc0f567789dee3a6bce8d411fe80f5563d8cdfdcc7d7e4447d43a0000000000000000000122020000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e05004830450221009ed2f0a67f99e29c3c8cf45c08207b765980697781bb727fe0b1416de0e7622902206052684229bc171419ed290f4b615c943f819c0262414e43c5b91dcf72ddcf4401473044022004ad5f04ae69c71b3b141d4db9d0d4c38d84009fb3cfeeae6efdad414487a9a0022042d3fe1388c1ff517d1da7fb4025663d372c14728ed52dc88608363450ff6a2f01008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a914b43e1b38138a41b37f7cd9a1d274bc63e3a9b5d188ac6868f6010000",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
index: 3,
|
|
|
|
remoteSigHex: "30440220155d3b90c67c33a8321996a9be5b82431b0c126613be751d400669da9d5c696702204318448bcd48824439d2c6a70be6e5747446be47ff45977cf41672bdc9b6b12d",
|
|
|
|
resolutionTxHex: "02000000000101fb824d4e4dafc0f567789dee3a6bce8d411fe80f5563d8cdfdcc7d7e4447d43a010000000000000000010a060000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e05004730440220155d3b90c67c33a8321996a9be5b82431b0c126613be751d400669da9d5c696702204318448bcd48824439d2c6a70be6e5747446be47ff45977cf41672bdc9b6b12d0147304402201707050c870c1f77cc3ed58d6d71bf281de239e9eabd8ef0955bad0d7fe38dcc02204d36d80d0019b3a71e646a08fa4a5607761d341ae8be371946ebe437c289c91501008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868f7010000",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
index: 4,
|
|
|
|
remoteSigHex: "3045022100a12a9a473ece548584aabdd051779025a5ed4077c4b7aa376ec7a0b1645e5a48022039490b333f53b5b3e2ddde1d809e492cba2b3e5fc3a436cd3ffb4cd3d500fa5a",
|
|
|
|
resolutionTxHex: "02000000000101fb824d4e4dafc0f567789dee3a6bce8d411fe80f5563d8cdfdcc7d7e4447d43a020000000000000000019a090000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100a12a9a473ece548584aabdd051779025a5ed4077c4b7aa376ec7a0b1645e5a48022039490b333f53b5b3e2ddde1d809e492cba2b3e5fc3a436cd3ffb4cd3d500fa5a01483045022100ff200bc934ab26ce9a559e998ceb0aee53bc40368e114ab9d3054d9960546e2802202496856ca163ac12c143110b6b3ac9d598df7254f2e17b3b94c3ab5301f4c3b0012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
expectedCommitmentTxHex: "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8005d007000000000000220020403d394747cae42e98ff01734ad5c08f82ba123d3d9a620abda88989651e2ab5b80b000000000000220020c20b5d1f8584fd90443e7b7b720136174fa4b9333c261d04dbbd012635c0f419a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de84311040966a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e040047304402203b1b010c109c2ecbe7feb2d259b9c4126bd5dc99ee693c422ec0a5781fe161ba0220571fe4e2c649dea9c7aaf7e49b382962f6a3494963c97d80fef9a430ca3f706101483045022100d33c4e541aa1d255d41ea9a3b443b3b822ad8f7f86862638aac1f69f8f760577022007e2a18e6931ce3d3a804b1c78eda1de17dbe1fb7a95488c9a4ec8620395334801475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220",
|
|
|
|
remoteSigHex: "3045022100d33c4e541aa1d255d41ea9a3b443b3b822ad8f7f86862638aac1f69f8f760577022007e2a18e6931ce3d3a804b1c78eda1de17dbe1fb7a95488c9a4ec86203953348",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
commitment: channeldb.ChannelCommitment{
|
|
|
|
CommitHeight: 42,
|
|
|
|
LocalBalance: 6988000000,
|
|
|
|
RemoteBalance: 3000000000,
|
|
|
|
FeePerKw: 2195,
|
|
|
|
},
|
|
|
|
htlcDescs: []htlcDesc{
|
|
|
|
{
|
|
|
|
index: 3,
|
|
|
|
remoteSigHex: "3045022100a8a78fa1016a5c5c3704f2e8908715a3cef66723fb95f3132ec4d2d05cd84fb4022025ac49287b0861ec21932405f5600cbce94313dbde0e6c5d5af1b3366d8afbfc",
|
|
|
|
resolutionTxHex: "020000000001014e16c488fa158431c1a82e8f661240ec0a71ba0ce92f2721a6538c510226ad5c0000000000000000000109060000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100a8a78fa1016a5c5c3704f2e8908715a3cef66723fb95f3132ec4d2d05cd84fb4022025ac49287b0861ec21932405f5600cbce94313dbde0e6c5d5af1b3366d8afbfc01483045022100be6ae1977fd7b630a53623f3f25c542317ccfc2b971782802a4f1ef538eb22b402207edc4d0408f8f38fd3c7365d1cfc26511b7cd2d4fecd8b005fba3cd5bc70439001008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868f7010000",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
index: 4,
|
|
|
|
remoteSigHex: "3045022100e769cb156aa2f7515d126cef7a69968629620ce82afcaa9e210969de6850df4602200b16b3f3486a229a48aadde520dbee31ae340dbadaffae74fbb56681fef27b92",
|
|
|
|
resolutionTxHex: "020000000001014e16c488fa158431c1a82e8f661240ec0a71ba0ce92f2721a6538c510226ad5c0100000000000000000199090000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100e769cb156aa2f7515d126cef7a69968629620ce82afcaa9e210969de6850df4602200b16b3f3486a229a48aadde520dbee31ae340dbadaffae74fbb56681fef27b92014730440220665b9cb4a978c09d1ca8977a534999bc8a49da624d0c5439451dd69cde1a003d022070eae0620f01f3c1bd029cc1488da13fb40fdab76f396ccd335479a11c5276d8012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
expectedCommitmentTxHex: "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8004b80b000000000000220020c20b5d1f8584fd90443e7b7b720136174fa4b9333c261d04dbbd012635c0f419a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de843110b8976a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e040047304402203b12d44254244b8ff3bb4129b0920fd45120ab42f553d9976394b099d500c99e02205e95bb7a3164852ef0c48f9e0eaf145218f8e2c41251b231f03cbdc4f29a54290147304402205e2f76d4657fb732c0dfc820a18a7301e368f5799e06b7828007633741bda6df0220458009ae59d0c6246065c419359e05eb2a4b4ef4a1b310cc912db44eb792429801475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220",
|
|
|
|
remoteSigHex: "304402205e2f76d4657fb732c0dfc820a18a7301e368f5799e06b7828007633741bda6df0220458009ae59d0c6246065c419359e05eb2a4b4ef4a1b310cc912db44eb7924298",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
commitment: channeldb.ChannelCommitment{
|
|
|
|
CommitHeight: 42,
|
|
|
|
LocalBalance: 6988000000,
|
|
|
|
RemoteBalance: 3000000000,
|
|
|
|
FeePerKw: 3702,
|
|
|
|
},
|
|
|
|
htlcDescs: []htlcDesc{
|
|
|
|
{
|
|
|
|
index: 3,
|
|
|
|
remoteSigHex: "3045022100dfb73b4fe961b31a859b2bb1f4f15cabab9265016dd0272323dc6a9e85885c54022059a7b87c02861ee70662907f25ce11597d7b68d3399443a831ae40e777b76bdb",
|
|
|
|
resolutionTxHex: "02000000000101b8de11eb51c22498fe39722c7227b6e55ff1a94146cf638458cb9bc6a060d3a30000000000000000000122020000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100dfb73b4fe961b31a859b2bb1f4f15cabab9265016dd0272323dc6a9e85885c54022059a7b87c02861ee70662907f25ce11597d7b68d3399443a831ae40e777b76bdb0147304402202765b9c9ece4f127fa5407faf66da4c5ce2719cdbe47cd3175fc7d48b482e43d02205605125925e07bad1e41c618a4b434d72c88a164981c4b8af5eaf4ee9142ec3a01008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868f7010000",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
index: 4,
|
|
|
|
remoteSigHex: "3045022100ea9dc2a7c3c3640334dab733bb4e036e32a3106dc707b24227874fa4f7da746802204d672f7ac0fe765931a8df10b81e53a3242dd32bd9dc9331eb4a596da87954e9",
|
|
|
|
resolutionTxHex: "02000000000101b8de11eb51c22498fe39722c7227b6e55ff1a94146cf638458cb9bc6a060d3a30100000000000000000176050000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100ea9dc2a7c3c3640334dab733bb4e036e32a3106dc707b24227874fa4f7da746802204d672f7ac0fe765931a8df10b81e53a3242dd32bd9dc9331eb4a596da87954e9014730440220048a41c660c4841693de037d00a407810389f4574b3286afb7bc392a438fa3f802200401d71fa87c64fe621b49ac07e3bf85157ac680acb977124da28652cc7f1a5c012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
expectedCommitmentTxHex: "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8004b80b000000000000220020c20b5d1f8584fd90443e7b7b720136174fa4b9333c261d04dbbd012635c0f419a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de8431106f916a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e040047304402200e930a43c7951162dc15a2b7344f48091c74c70f7024e7116e900d8bcfba861c022066fa6cbda3929e21daa2e7e16a4b948db7e8919ef978402360d1095ffdaff7b001483045022100c1a3b0b60ca092ed5080121f26a74a20cec6bdee3f8e47bae973fcdceb3eda5502207d467a9873c939bf3aa758014ae67295fedbca52412633f7e5b2670fc7c381c101475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220",
|
|
|
|
remoteSigHex: "3045022100c1a3b0b60ca092ed5080121f26a74a20cec6bdee3f8e47bae973fcdceb3eda5502207d467a9873c939bf3aa758014ae67295fedbca52412633f7e5b2670fc7c381c1",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
commitment: channeldb.ChannelCommitment{
|
|
|
|
CommitHeight: 42,
|
|
|
|
LocalBalance: 6988000000,
|
|
|
|
RemoteBalance: 3000000000,
|
|
|
|
FeePerKw: 3703,
|
|
|
|
},
|
|
|
|
htlcDescs: []htlcDesc{
|
|
|
|
{
|
|
|
|
index: 4,
|
|
|
|
remoteSigHex: "3044022044f65cf833afdcb9d18795ca93f7230005777662539815b8a601eeb3e57129a902206a4bf3e53392affbba52640627defa8dc8af61c958c9e827b2798ab45828abdd",
|
|
|
|
resolutionTxHex: "020000000001011c076aa7fb3d7460d10df69432c904227ea84bbf3134d4ceee5fb0f135ef206d0000000000000000000175050000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500473044022044f65cf833afdcb9d18795ca93f7230005777662539815b8a601eeb3e57129a902206a4bf3e53392affbba52640627defa8dc8af61c958c9e827b2798ab45828abdd01483045022100b94d931a811b32eeb885c28ddcf999ae1981893b21dd1329929543fe87ce793002206370107fdd151c5f2384f9ceb71b3107c69c74c8ed5a28a94a4ab2d27d3b0724012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
expectedCommitmentTxHex: "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8003a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de843110eb936a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0400473044022047305531dd44391dce03ae20f8735005c615eb077a974edb0059ea1a311857d602202e0ed6972fbdd1e8cb542b06e0929bc41b2ddf236e04cb75edd56151f4197506014830450221008b7c191dd46893b67b628e618d2dc8e81169d38bade310181ab77d7c94c6675e02203b4dd131fd7c9deb299560983dcdc485545c98f989f7ae8180c28289f9e6bdb001475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220",
|
|
|
|
remoteSigHex: "30450221008b7c191dd46893b67b628e618d2dc8e81169d38bade310181ab77d7c94c6675e02203b4dd131fd7c9deb299560983dcdc485545c98f989f7ae8180c28289f9e6bdb0",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
commitment: channeldb.ChannelCommitment{
|
|
|
|
CommitHeight: 42,
|
|
|
|
LocalBalance: 6988000000,
|
|
|
|
RemoteBalance: 3000000000,
|
|
|
|
FeePerKw: 4914,
|
|
|
|
},
|
|
|
|
htlcDescs: []htlcDesc{
|
|
|
|
{
|
|
|
|
index: 4,
|
|
|
|
remoteSigHex: "3045022100fcb38506bfa11c02874092a843d0cc0a8613c23b639832564a5f69020cb0f6ba02206508b9e91eaa001425c190c68ee5f887e1ad5b1b314002e74db9dbd9e42dbecf",
|
|
|
|
resolutionTxHex: "0200000000010110a3fdcbcd5db477cd3ad465e7f501ffa8c437e8301f00a6061138590add757f0000000000000000000122020000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100fcb38506bfa11c02874092a843d0cc0a8613c23b639832564a5f69020cb0f6ba02206508b9e91eaa001425c190c68ee5f887e1ad5b1b314002e74db9dbd9e42dbecf0148304502210086e76b460ddd3cea10525fba298405d3fe11383e56966a5091811368362f689a02200f72ee75657915e0ede89c28709acd113ede9e1b7be520e3bc5cda425ecd6e68012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
expectedCommitmentTxHex: "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8003a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de843110ae8f6a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e040047304402206a2679efa3c7aaffd2a447fd0df7aba8792858b589750f6a1203f9259173198a022008d52a0e77a99ab533c36206cb15ad7aeb2aa72b93d4b571e728cb5ec2f6fe260147304402206d6cb93969d39177a09d5d45b583f34966195b77c7e585cf47ac5cce0c90cefb022031d71ae4e33a4e80df7f981d696fbdee517337806a3c7138b7491e2cbb077a0e01475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220",
|
|
|
|
remoteSigHex: "304402206d6cb93969d39177a09d5d45b583f34966195b77c7e585cf47ac5cce0c90cefb022031d71ae4e33a4e80df7f981d696fbdee517337806a3c7138b7491e2cbb077a0e",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
commitment: channeldb.ChannelCommitment{
|
|
|
|
CommitHeight: 42,
|
|
|
|
LocalBalance: 6988000000,
|
|
|
|
RemoteBalance: 3000000000,
|
|
|
|
FeePerKw: 4915,
|
|
|
|
},
|
|
|
|
htlcDescs: []htlcDesc{},
|
|
|
|
expectedCommitmentTxHex: "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8002c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de843110fa926a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0400483045022100a012691ba6cea2f73fa8bac37750477e66363c6d28813b0bb6da77c8eb3fb0270220365e99c51304b0b1a6ab9ea1c8500db186693e39ec1ad5743ee231b0138384b90147304402200769ba89c7330dfa4feba447b6e322305f12ac7dac70ec6ba997ed7c1b598d0802204fe8d337e7fee781f9b7b1a06e580b22f4f79d740059560191d7db53f876555201475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220",
|
|
|
|
remoteSigHex: "304402200769ba89c7330dfa4feba447b6e322305f12ac7dac70ec6ba997ed7c1b598d0802204fe8d337e7fee781f9b7b1a06e580b22f4f79d740059560191d7db53f8765552",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
commitment: channeldb.ChannelCommitment{
|
|
|
|
CommitHeight: 42,
|
|
|
|
LocalBalance: 6988000000,
|
|
|
|
RemoteBalance: 3000000000,
|
|
|
|
FeePerKw: 9651180,
|
|
|
|
},
|
|
|
|
htlcDescs: []htlcDesc{},
|
|
|
|
expectedCommitmentTxHex: "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b800222020000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80ec0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de84311004004730440220514f977bf7edc442de8ce43ace9686e5ebdc0f893033f13e40fb46c8b8c6e1f90220188006227d175f5c35da0b092c57bea82537aed89f7778204dc5bacf4f29f2b901473044022037f83ff00c8e5fb18ae1f918ffc24e54581775a20ff1ae719297ef066c71caa9022039c529cccd89ff6c5ed1db799614533844bd6d101da503761c45c713996e3bbd01475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220",
|
|
|
|
remoteSigHex: "3044022037f83ff00c8e5fb18ae1f918ffc24e54581775a20ff1ae719297ef066c71caa9022039c529cccd89ff6c5ed1db799614533844bd6d101da503761c45c713996e3bbd",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
commitment: channeldb.ChannelCommitment{
|
|
|
|
CommitHeight: 42,
|
|
|
|
LocalBalance: 6988000000,
|
|
|
|
RemoteBalance: 3000000000,
|
|
|
|
FeePerKw: 9651181,
|
|
|
|
},
|
|
|
|
htlcDescs: []htlcDesc{},
|
|
|
|
expectedCommitmentTxHex: "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8001c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de8431100400473044022031a82b51bd014915fe68928d1abf4b9885353fb896cac10c3fdd88d7f9c7f2e00220716bda819641d2c63e65d3549b6120112e1aeaf1742eed94a471488e79e206b101473044022064901950be922e62cbe3f2ab93de2b99f37cff9fc473e73e394b27f88ef0731d02206d1dfa227527b4df44a07599289e207d6fd9cca60c0365682dcd3deaf739567e01475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220",
|
|
|
|
remoteSigHex: "3044022064901950be922e62cbe3f2ab93de2b99f37cff9fc473e73e394b27f88ef0731d02206d1dfa227527b4df44a07599289e207d6fd9cca60c0365682dcd3deaf739567e",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2017-09-26 07:47:39 +03:00
|
|
|
// TestCommitmentAndHTLCTransactions checks the test vectors specified in
|
|
|
|
// BOLT 03, Appendix C. This deterministically generates commitment and second
|
|
|
|
// level HTLC transactions and checks that they match the expected values.
|
|
|
|
func TestCommitmentAndHTLCTransactions(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
tc, err := newTestContext()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Generate random some keys that don't actually matter but need to be set.
|
|
|
|
var (
|
|
|
|
identityKey *btcec.PublicKey
|
|
|
|
localDelayBasePoint *btcec.PublicKey
|
|
|
|
)
|
|
|
|
generateKeys := []**btcec.PublicKey{
|
|
|
|
&identityKey,
|
|
|
|
&localDelayBasePoint,
|
|
|
|
}
|
|
|
|
for _, keyRef := range generateKeys {
|
|
|
|
privkey, err := btcec.NewPrivateKey(btcec.S256())
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Failed to generate new key: %v", err)
|
|
|
|
}
|
|
|
|
*keyRef = privkey.PubKey()
|
|
|
|
}
|
|
|
|
|
|
|
|
// Manually construct a new LightningChannel.
|
|
|
|
channelState := channeldb.OpenChannel{
|
2019-10-31 05:24:49 +03:00
|
|
|
ChanType: channeldb.SingleFunderTweaklessBit,
|
2017-09-26 07:47:39 +03:00
|
|
|
ChainHash: *tc.netParams.GenesisHash,
|
|
|
|
FundingOutpoint: tc.fundingOutpoint,
|
2018-05-02 02:27:20 +03:00
|
|
|
ShortChannelID: tc.shortChanID,
|
2017-09-26 07:47:39 +03:00
|
|
|
IsInitiator: true,
|
|
|
|
IdentityPub: identityKey,
|
|
|
|
LocalChanCfg: channeldb.ChannelConfig{
|
|
|
|
ChannelConstraints: channeldb.ChannelConstraints{
|
|
|
|
DustLimit: tc.dustLimit,
|
|
|
|
MaxPendingAmount: lnwire.NewMSatFromSatoshis(tc.fundingAmount),
|
2019-01-16 17:47:43 +03:00
|
|
|
MaxAcceptedHtlcs: input.MaxHTLCNumber,
|
2018-12-11 00:56:41 +03:00
|
|
|
CsvDelay: tc.localCsvDelay,
|
2017-09-26 07:47:39 +03:00
|
|
|
},
|
2018-02-18 02:25:55 +03:00
|
|
|
MultiSigKey: keychain.KeyDescriptor{
|
|
|
|
PubKey: tc.localFundingPubKey,
|
|
|
|
},
|
|
|
|
PaymentBasePoint: keychain.KeyDescriptor{
|
|
|
|
PubKey: tc.localPaymentBasePoint,
|
|
|
|
},
|
|
|
|
HtlcBasePoint: keychain.KeyDescriptor{
|
|
|
|
PubKey: tc.localPaymentBasePoint,
|
|
|
|
},
|
|
|
|
DelayBasePoint: keychain.KeyDescriptor{
|
|
|
|
PubKey: localDelayBasePoint,
|
|
|
|
},
|
2017-09-26 07:47:39 +03:00
|
|
|
},
|
|
|
|
RemoteChanCfg: channeldb.ChannelConfig{
|
2018-02-18 02:25:55 +03:00
|
|
|
MultiSigKey: keychain.KeyDescriptor{
|
|
|
|
PubKey: tc.remoteFundingPubKey,
|
|
|
|
},
|
|
|
|
PaymentBasePoint: keychain.KeyDescriptor{
|
|
|
|
PubKey: tc.remotePaymentBasePoint,
|
|
|
|
},
|
|
|
|
HtlcBasePoint: keychain.KeyDescriptor{
|
|
|
|
PubKey: tc.remotePaymentBasePoint,
|
|
|
|
},
|
2017-09-26 07:47:39 +03:00
|
|
|
},
|
|
|
|
Capacity: tc.fundingAmount,
|
|
|
|
RevocationProducer: shachain.NewRevocationProducer(zeroHash),
|
|
|
|
}
|
2019-01-16 17:47:43 +03:00
|
|
|
signer := &input.MockSigner{
|
|
|
|
Privkeys: []*btcec.PrivateKey{
|
2017-09-26 07:47:39 +03:00
|
|
|
tc.localFundingPrivKey, tc.localPaymentPrivKey,
|
|
|
|
},
|
2019-01-16 17:47:43 +03:00
|
|
|
NetParams: tc.netParams,
|
2017-09-26 07:47:39 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Construct a LightningChannel manually because we don't have nor need all
|
|
|
|
// of the dependencies.
|
|
|
|
channel := LightningChannel{
|
2020-01-06 13:42:03 +03:00
|
|
|
channelState: &channelState,
|
|
|
|
Signer: signer,
|
|
|
|
commitBuilder: NewCommitmentBuilder(&channelState),
|
2017-09-26 07:47:39 +03:00
|
|
|
}
|
|
|
|
err = channel.createSignDesc()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Failed to generate channel sign descriptor: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// The commitmentPoint is technically hidden in the spec, but we need it to
|
|
|
|
// generate the correct tweak.
|
2019-01-16 17:47:43 +03:00
|
|
|
tweak := input.SingleTweakBytes(tc.commitmentPoint, tc.localPaymentBasePoint)
|
2018-02-01 01:27:28 +03:00
|
|
|
keys := &CommitmentKeyRing{
|
|
|
|
CommitPoint: tc.commitmentPoint,
|
|
|
|
LocalCommitKeyTweak: tweak,
|
|
|
|
LocalHtlcKeyTweak: tweak,
|
|
|
|
LocalHtlcKey: tc.localPaymentPubKey,
|
|
|
|
RemoteHtlcKey: tc.remotePaymentPubKey,
|
2020-01-06 13:42:04 +03:00
|
|
|
ToLocalKey: tc.localDelayPubKey,
|
|
|
|
ToRemoteKey: tc.remotePaymentPubKey,
|
2018-02-01 01:27:28 +03:00
|
|
|
RevocationKey: tc.localRevocationPubKey,
|
2017-09-26 07:47:39 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
for i, test := range testCases {
|
|
|
|
expectedCommitmentTx, err := txFromHex(test.expectedCommitmentTxHex)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Case %d: Failed to parse serialized tx: %v", i, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Build required HTLC structs from raw test vector data.
|
|
|
|
htlcs := make([]channeldb.HTLC, len(test.htlcDescs), len(test.htlcDescs))
|
|
|
|
for i, htlcDesc := range test.htlcDescs {
|
|
|
|
htlcs[i], err = tc.getHTLC(i, &htlcDesc)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
theHTLCView := htlcViewFromHTLCs(htlcs)
|
|
|
|
|
2020-01-06 13:42:03 +03:00
|
|
|
feePerKw := chainfee.SatPerKWeight(test.commitment.FeePerKw)
|
|
|
|
isOurs := true
|
|
|
|
height := test.commitment.CommitHeight
|
|
|
|
|
2017-09-26 07:47:39 +03:00
|
|
|
// Create unsigned commitment transaction.
|
2020-01-06 13:42:03 +03:00
|
|
|
view, err := channel.commitBuilder.createUnsignedCommitmentTx(
|
|
|
|
test.commitment.LocalBalance,
|
|
|
|
test.commitment.RemoteBalance, isOurs, feePerKw,
|
|
|
|
height, theHTLCView, keys,
|
2018-02-25 06:12:16 +03:00
|
|
|
)
|
2017-09-26 07:47:39 +03:00
|
|
|
if err != nil {
|
|
|
|
t.Errorf("Case %d: Failed to create new commitment tx: %v", i, err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2020-01-06 13:42:03 +03:00
|
|
|
commitmentView := &commitment{
|
|
|
|
ourBalance: view.ourBalance,
|
|
|
|
theirBalance: view.theirBalance,
|
|
|
|
txn: view.txn,
|
|
|
|
fee: view.fee,
|
|
|
|
height: height,
|
|
|
|
feePerKw: feePerKw,
|
|
|
|
dustLimit: tc.dustLimit,
|
|
|
|
isOurs: isOurs,
|
|
|
|
}
|
|
|
|
|
2017-09-26 07:47:39 +03:00
|
|
|
// Initialize LocalCommit, which is used in getSignedCommitTx.
|
|
|
|
channelState.LocalCommitment = test.commitment
|
|
|
|
channelState.LocalCommitment.Htlcs = htlcs
|
|
|
|
channelState.LocalCommitment.CommitTx = commitmentView.txn
|
|
|
|
|
2018-02-01 01:27:28 +03:00
|
|
|
// This is the remote party's signature over the commitment
|
|
|
|
// transaction which is included in the commitment tx's witness
|
|
|
|
// data.
|
2017-09-26 07:47:39 +03:00
|
|
|
channelState.LocalCommitment.CommitSig, err = hex.DecodeString(test.remoteSigHex)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Case %d: Failed to parse serialized signature: %v",
|
|
|
|
i, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
commitTx, err := channel.getSignedCommitTx()
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("Case %d: Failed to sign commitment tx: %v", i, err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check that commitment transaction was created correctly.
|
|
|
|
if commitTx.WitnessHash() != *expectedCommitmentTx.WitnessHash() {
|
|
|
|
t.Errorf("Case %d: Generated unexpected commitment tx: "+
|
2018-02-25 06:12:16 +03:00
|
|
|
"expected %s, got %s", i, spew.Sdump(expectedCommitmentTx),
|
|
|
|
spew.Sdump(commitTx))
|
2017-09-26 07:47:39 +03:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2018-02-01 01:27:28 +03:00
|
|
|
// Generate second-level HTLC transactions for HTLCs in
|
|
|
|
// commitment tx.
|
2017-09-26 07:47:39 +03:00
|
|
|
htlcResolutions, err := extractHtlcResolutions(
|
2020-03-06 18:11:45 +03:00
|
|
|
chainfee.SatPerKWeight(test.commitment.FeePerKw), true,
|
|
|
|
signer, htlcs, keys, &channel.channelState.LocalChanCfg,
|
2020-01-06 13:42:02 +03:00
|
|
|
&channel.channelState.RemoteChanCfg, commitTx.TxHash(),
|
2020-03-06 18:11:45 +03:00
|
|
|
channel.channelState.ChanType,
|
2018-02-01 01:27:28 +03:00
|
|
|
)
|
2017-09-26 07:47:39 +03:00
|
|
|
if err != nil {
|
|
|
|
t.Errorf("Case %d: Failed to extract HTLC resolutions: %v", i, err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
resolutionIdx := 0
|
|
|
|
for j, htlcDesc := range test.htlcDescs {
|
|
|
|
// TODO: Check HTLC success transactions; currently not implemented.
|
|
|
|
// resolutionIdx can be replaced by j when this is handled.
|
|
|
|
if htlcs[j].Incoming {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
expectedTx, err := txFromHex(htlcDesc.resolutionTxHex)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Failed to parse serialized tx: %v", err)
|
|
|
|
}
|
|
|
|
|
2018-02-01 01:27:28 +03:00
|
|
|
htlcResolution := htlcResolutions.OutgoingHTLCs[resolutionIdx]
|
2017-09-26 07:47:39 +03:00
|
|
|
resolutionIdx++
|
|
|
|
|
|
|
|
actualTx := htlcResolution.SignedTimeoutTx
|
|
|
|
if actualTx == nil {
|
|
|
|
t.Errorf("Case %d: Failed to generate second level tx: "+
|
2018-02-01 01:27:28 +03:00
|
|
|
"output %d, %v", i, j,
|
|
|
|
htlcResolutions.OutgoingHTLCs[j])
|
2017-09-26 07:47:39 +03:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check that second-level HTLC transaction was created correctly.
|
|
|
|
if actualTx.WitnessHash() != *expectedTx.WitnessHash() {
|
|
|
|
t.Errorf("Case %d: Generated unexpected second level tx: "+
|
|
|
|
"output %d, expected %s, got %s", i, j,
|
|
|
|
expectedTx.WitnessHash(), actualTx.WitnessHash())
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// htlcViewFromHTLCs constructs an htlcView of PaymentDescriptors from a slice
|
|
|
|
// of channeldb.HTLC structs.
|
|
|
|
func htlcViewFromHTLCs(htlcs []channeldb.HTLC) *htlcView {
|
|
|
|
var theHTLCView htlcView
|
|
|
|
for _, htlc := range htlcs {
|
|
|
|
paymentDesc := &PaymentDescriptor{
|
|
|
|
RHash: htlc.RHash,
|
|
|
|
Timeout: htlc.RefundTimeout,
|
|
|
|
Amount: htlc.Amt,
|
|
|
|
}
|
|
|
|
if htlc.Incoming {
|
|
|
|
theHTLCView.theirUpdates =
|
|
|
|
append(theHTLCView.theirUpdates, paymentDesc)
|
|
|
|
} else {
|
|
|
|
theHTLCView.ourUpdates =
|
|
|
|
append(theHTLCView.ourUpdates, paymentDesc)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return &theHTLCView
|
|
|
|
}
|
2019-01-27 21:20:41 +03:00
|
|
|
|
|
|
|
func TestCommitTxStateHint(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
stateHintTests := []struct {
|
|
|
|
name string
|
|
|
|
from uint64
|
|
|
|
to uint64
|
|
|
|
inputs int
|
|
|
|
shouldFail bool
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "states 0 to 1000",
|
|
|
|
from: 0,
|
|
|
|
to: 1000,
|
|
|
|
inputs: 1,
|
|
|
|
shouldFail: false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "states 'maxStateHint-1000' to 'maxStateHint'",
|
|
|
|
from: maxStateHint - 1000,
|
|
|
|
to: maxStateHint,
|
|
|
|
inputs: 1,
|
|
|
|
shouldFail: false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "state 'maxStateHint+1'",
|
|
|
|
from: maxStateHint + 1,
|
|
|
|
to: maxStateHint + 10,
|
|
|
|
inputs: 1,
|
|
|
|
shouldFail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "commit transaction with two inputs",
|
|
|
|
inputs: 2,
|
|
|
|
shouldFail: true,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
var obfuscator [StateHintSize]byte
|
|
|
|
copy(obfuscator[:], testHdSeed[:StateHintSize])
|
|
|
|
timeYesterday := uint32(time.Now().Unix() - 24*60*60)
|
|
|
|
|
|
|
|
for _, test := range stateHintTests {
|
|
|
|
commitTx := wire.NewMsgTx(2)
|
|
|
|
|
|
|
|
// Add supplied number of inputs to the commitment transaction.
|
|
|
|
for i := 0; i < test.inputs; i++ {
|
|
|
|
commitTx.AddTxIn(&wire.TxIn{})
|
|
|
|
}
|
|
|
|
|
|
|
|
for i := test.from; i <= test.to; i++ {
|
|
|
|
stateNum := uint64(i)
|
|
|
|
|
|
|
|
err := SetStateNumHint(commitTx, stateNum, obfuscator)
|
|
|
|
if err != nil && !test.shouldFail {
|
|
|
|
t.Fatalf("unable to set state num %v: %v", i, err)
|
|
|
|
} else if err == nil && test.shouldFail {
|
|
|
|
t.Fatalf("Failed(%v): test should fail but did not", test.name)
|
|
|
|
}
|
|
|
|
|
|
|
|
locktime := commitTx.LockTime
|
|
|
|
sequence := commitTx.TxIn[0].Sequence
|
|
|
|
|
|
|
|
// Locktime should not be less than 500,000,000 and not larger
|
|
|
|
// than the time 24 hours ago. One day should provide a good
|
|
|
|
// enough buffer for the tests.
|
|
|
|
if locktime < 5e8 || locktime > timeYesterday {
|
|
|
|
if !test.shouldFail {
|
|
|
|
t.Fatalf("The value of locktime (%v) may cause the commitment "+
|
|
|
|
"transaction to be unspendable", locktime)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if sequence&wire.SequenceLockTimeDisabled == 0 {
|
|
|
|
if !test.shouldFail {
|
|
|
|
t.Fatalf("Sequence locktime is NOT disabled when it should be")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extractedStateNum := GetStateNumHint(commitTx, obfuscator)
|
|
|
|
if extractedStateNum != stateNum && !test.shouldFail {
|
|
|
|
t.Fatalf("state number mismatched, expected %v, got %v",
|
|
|
|
stateNum, extractedStateNum)
|
|
|
|
} else if extractedStateNum == stateNum && test.shouldFail {
|
|
|
|
t.Fatalf("Failed(%v): test should fail but did not", test.name)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
t.Logf("Passed: %v", test.name)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-01 06:10:45 +03:00
|
|
|
// testSpendValidation ensures that we're able to spend all outputs in the
|
|
|
|
// commitment transaction that we create.
|
|
|
|
func testSpendValidation(t *testing.T, tweakless bool) {
|
2019-01-27 21:20:41 +03:00
|
|
|
// We generate a fake output, and the corresponding txin. This output
|
|
|
|
// doesn't need to exist, as we'll only be validating spending from the
|
|
|
|
// transaction that references this.
|
|
|
|
txid, err := chainhash.NewHash(testHdSeed.CloneBytes())
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unable to create txid: %v", err)
|
|
|
|
}
|
|
|
|
fundingOut := &wire.OutPoint{
|
|
|
|
Hash: *txid,
|
|
|
|
Index: 50,
|
|
|
|
}
|
|
|
|
fakeFundingTxIn := wire.NewTxIn(fundingOut, nil, nil)
|
|
|
|
|
|
|
|
const channelBalance = btcutil.Amount(1 * 10e8)
|
2020-01-06 13:42:03 +03:00
|
|
|
const csvTimeout = 5
|
2019-01-27 21:20:41 +03:00
|
|
|
|
|
|
|
// We also set up set some resources for the commitment transaction.
|
|
|
|
// Each side currently has 1 BTC within the channel, with a total
|
|
|
|
// channel capacity of 2BTC.
|
2019-08-01 06:10:45 +03:00
|
|
|
aliceKeyPriv, aliceKeyPub := btcec.PrivKeyFromBytes(
|
|
|
|
btcec.S256(), testWalletPrivKey,
|
|
|
|
)
|
|
|
|
bobKeyPriv, bobKeyPub := btcec.PrivKeyFromBytes(
|
|
|
|
btcec.S256(), bobsPrivKey,
|
|
|
|
)
|
2019-01-27 21:20:41 +03:00
|
|
|
|
|
|
|
revocationPreimage := testHdSeed.CloneBytes()
|
2019-08-01 06:10:45 +03:00
|
|
|
commitSecret, commitPoint := btcec.PrivKeyFromBytes(
|
|
|
|
btcec.S256(), revocationPreimage,
|
|
|
|
)
|
2019-01-16 17:47:43 +03:00
|
|
|
revokePubKey := input.DeriveRevocationPubkey(bobKeyPub, commitPoint)
|
2019-01-27 21:20:41 +03:00
|
|
|
|
2019-01-16 17:47:43 +03:00
|
|
|
aliceDelayKey := input.TweakPubKey(aliceKeyPub, commitPoint)
|
2019-08-01 06:10:45 +03:00
|
|
|
|
|
|
|
// Bob will have the channel "force closed" on him, so for the sake of
|
|
|
|
// our commitments, if it's tweakless, his key will just be his regular
|
|
|
|
// pubkey.
|
2019-01-16 17:47:43 +03:00
|
|
|
bobPayKey := input.TweakPubKey(bobKeyPub, commitPoint)
|
2020-01-06 13:42:04 +03:00
|
|
|
channelType := channeldb.SingleFunderBit
|
2019-08-01 06:10:45 +03:00
|
|
|
if tweakless {
|
|
|
|
bobPayKey = bobKeyPub
|
2020-01-06 13:42:04 +03:00
|
|
|
channelType = channeldb.SingleFunderTweaklessBit
|
2019-08-01 06:10:45 +03:00
|
|
|
}
|
2019-01-27 21:20:41 +03:00
|
|
|
|
2019-01-16 17:47:43 +03:00
|
|
|
aliceCommitTweak := input.SingleTweakBytes(commitPoint, aliceKeyPub)
|
|
|
|
bobCommitTweak := input.SingleTweakBytes(commitPoint, bobKeyPub)
|
2019-01-27 21:20:41 +03:00
|
|
|
|
2019-01-16 17:47:43 +03:00
|
|
|
aliceSelfOutputSigner := &input.MockSigner{
|
|
|
|
Privkeys: []*btcec.PrivateKey{aliceKeyPriv},
|
2019-01-27 21:20:41 +03:00
|
|
|
}
|
|
|
|
|
2020-01-06 13:42:03 +03:00
|
|
|
aliceChanCfg := &channeldb.ChannelConfig{
|
|
|
|
ChannelConstraints: channeldb.ChannelConstraints{
|
|
|
|
DustLimit: DefaultDustLimit(),
|
|
|
|
CsvDelay: csvTimeout,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
bobChanCfg := &channeldb.ChannelConfig{
|
|
|
|
ChannelConstraints: channeldb.ChannelConstraints{
|
|
|
|
DustLimit: DefaultDustLimit(),
|
|
|
|
CsvDelay: csvTimeout,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2019-01-27 21:20:41 +03:00
|
|
|
// With all the test data set up, we create the commitment transaction.
|
|
|
|
// We only focus on a single party's transactions, as the scripts are
|
|
|
|
// identical with the roles reversed.
|
|
|
|
//
|
|
|
|
// This is Alice's commitment transaction, so she must wait a CSV delay
|
|
|
|
// of 5 blocks before sweeping the output, while bob can spend
|
|
|
|
// immediately with either the revocation key, or his regular key.
|
|
|
|
keyRing := &CommitmentKeyRing{
|
2020-01-06 13:42:04 +03:00
|
|
|
ToLocalKey: aliceDelayKey,
|
2019-01-27 21:20:41 +03:00
|
|
|
RevocationKey: revokePubKey,
|
2020-01-06 13:42:04 +03:00
|
|
|
ToRemoteKey: bobPayKey,
|
2019-01-27 21:20:41 +03:00
|
|
|
}
|
2019-08-01 06:10:45 +03:00
|
|
|
commitmentTx, err := CreateCommitTx(
|
2020-01-06 13:42:04 +03:00
|
|
|
channelType, *fakeFundingTxIn, keyRing, aliceChanCfg,
|
2020-03-06 18:11:46 +03:00
|
|
|
bobChanCfg, channelBalance, channelBalance, 0,
|
2019-08-01 06:10:45 +03:00
|
|
|
)
|
2019-01-27 21:20:41 +03:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unable to create commitment transaction: %v", nil)
|
|
|
|
}
|
|
|
|
|
|
|
|
delayOutput := commitmentTx.TxOut[0]
|
|
|
|
regularOutput := commitmentTx.TxOut[1]
|
|
|
|
|
|
|
|
// We're testing an uncooperative close, output sweep, so construct a
|
|
|
|
// transaction which sweeps the funds to a random address.
|
2019-01-16 17:47:43 +03:00
|
|
|
targetOutput, err := input.CommitScriptUnencumbered(aliceKeyPub)
|
2019-01-27 21:20:41 +03:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unable to create target output: %v", err)
|
|
|
|
}
|
|
|
|
sweepTx := wire.NewMsgTx(2)
|
|
|
|
sweepTx.AddTxIn(wire.NewTxIn(&wire.OutPoint{
|
|
|
|
Hash: commitmentTx.TxHash(),
|
|
|
|
Index: 0,
|
|
|
|
}, nil, nil))
|
|
|
|
sweepTx.AddTxOut(&wire.TxOut{
|
|
|
|
PkScript: targetOutput,
|
|
|
|
Value: 0.5 * 10e8,
|
|
|
|
})
|
|
|
|
|
|
|
|
// First, we'll test spending with Alice's key after the timeout.
|
2019-08-01 06:10:45 +03:00
|
|
|
delayScript, err := input.CommitScriptToSelf(
|
|
|
|
csvTimeout, aliceDelayKey, revokePubKey,
|
|
|
|
)
|
2019-01-27 21:20:41 +03:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unable to generate alice delay script: %v", err)
|
|
|
|
}
|
2019-01-16 17:47:43 +03:00
|
|
|
sweepTx.TxIn[0].Sequence = input.LockTimeToSequence(false, csvTimeout)
|
|
|
|
signDesc := &input.SignDescriptor{
|
2019-01-27 21:20:41 +03:00
|
|
|
WitnessScript: delayScript,
|
|
|
|
KeyDesc: keychain.KeyDescriptor{
|
|
|
|
PubKey: aliceKeyPub,
|
|
|
|
},
|
|
|
|
SingleTweak: aliceCommitTweak,
|
|
|
|
SigHashes: txscript.NewTxSigHashes(sweepTx),
|
|
|
|
Output: &wire.TxOut{
|
|
|
|
Value: int64(channelBalance),
|
|
|
|
},
|
|
|
|
HashType: txscript.SigHashAll,
|
|
|
|
InputIndex: 0,
|
|
|
|
}
|
2019-08-01 06:10:45 +03:00
|
|
|
aliceWitnessSpend, err := input.CommitSpendTimeout(
|
|
|
|
aliceSelfOutputSigner, signDesc, sweepTx,
|
|
|
|
)
|
2019-01-27 21:20:41 +03:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unable to generate delay commit spend witness: %v", err)
|
|
|
|
}
|
|
|
|
sweepTx.TxIn[0].Witness = aliceWitnessSpend
|
|
|
|
vm, err := txscript.NewEngine(delayOutput.PkScript,
|
|
|
|
sweepTx, 0, txscript.StandardVerifyFlags, nil,
|
|
|
|
nil, int64(channelBalance))
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unable to create engine: %v", err)
|
|
|
|
}
|
|
|
|
if err := vm.Execute(); err != nil {
|
|
|
|
t.Fatalf("spend from delay output is invalid: %v", err)
|
|
|
|
}
|
|
|
|
|
2019-01-16 17:47:43 +03:00
|
|
|
bobSigner := &input.MockSigner{Privkeys: []*btcec.PrivateKey{bobKeyPriv}}
|
2019-01-27 21:20:41 +03:00
|
|
|
|
|
|
|
// Next, we'll test bob spending with the derived revocation key to
|
|
|
|
// simulate the scenario when Alice broadcasts this commitment
|
|
|
|
// transaction after it's been revoked.
|
2019-01-16 17:47:43 +03:00
|
|
|
signDesc = &input.SignDescriptor{
|
2019-01-27 21:20:41 +03:00
|
|
|
KeyDesc: keychain.KeyDescriptor{
|
|
|
|
PubKey: bobKeyPub,
|
|
|
|
},
|
|
|
|
DoubleTweak: commitSecret,
|
|
|
|
WitnessScript: delayScript,
|
|
|
|
SigHashes: txscript.NewTxSigHashes(sweepTx),
|
|
|
|
Output: &wire.TxOut{
|
|
|
|
Value: int64(channelBalance),
|
|
|
|
},
|
|
|
|
HashType: txscript.SigHashAll,
|
|
|
|
InputIndex: 0,
|
|
|
|
}
|
2019-01-16 17:47:43 +03:00
|
|
|
bobWitnessSpend, err := input.CommitSpendRevoke(bobSigner, signDesc,
|
2019-01-27 21:20:41 +03:00
|
|
|
sweepTx)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unable to generate revocation witness: %v", err)
|
|
|
|
}
|
|
|
|
sweepTx.TxIn[0].Witness = bobWitnessSpend
|
|
|
|
vm, err = txscript.NewEngine(delayOutput.PkScript,
|
|
|
|
sweepTx, 0, txscript.StandardVerifyFlags, nil,
|
|
|
|
nil, int64(channelBalance))
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unable to create engine: %v", err)
|
|
|
|
}
|
|
|
|
if err := vm.Execute(); err != nil {
|
|
|
|
t.Fatalf("revocation spend is invalid: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// In order to test the final scenario, we modify the TxIn of the sweep
|
|
|
|
// transaction to instead point to the regular output (non delay)
|
|
|
|
// within the commitment transaction.
|
|
|
|
sweepTx.TxIn[0] = &wire.TxIn{
|
|
|
|
PreviousOutPoint: wire.OutPoint{
|
|
|
|
Hash: commitmentTx.TxHash(),
|
|
|
|
Index: 1,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
// Finally, we test bob sweeping his output as normal in the case that
|
|
|
|
// Alice broadcasts this commitment transaction.
|
2019-01-16 17:47:43 +03:00
|
|
|
bobScriptP2WKH, err := input.CommitScriptUnencumbered(bobPayKey)
|
2019-01-27 21:20:41 +03:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unable to create bob p2wkh script: %v", err)
|
|
|
|
}
|
2019-01-16 17:47:43 +03:00
|
|
|
signDesc = &input.SignDescriptor{
|
2019-01-27 21:20:41 +03:00
|
|
|
KeyDesc: keychain.KeyDescriptor{
|
|
|
|
PubKey: bobKeyPub,
|
|
|
|
},
|
|
|
|
WitnessScript: bobScriptP2WKH,
|
|
|
|
SigHashes: txscript.NewTxSigHashes(sweepTx),
|
|
|
|
Output: &wire.TxOut{
|
|
|
|
Value: int64(channelBalance),
|
|
|
|
PkScript: bobScriptP2WKH,
|
|
|
|
},
|
|
|
|
HashType: txscript.SigHashAll,
|
|
|
|
InputIndex: 0,
|
|
|
|
}
|
2019-08-01 06:10:45 +03:00
|
|
|
if !tweakless {
|
|
|
|
signDesc.SingleTweak = bobCommitTweak
|
|
|
|
}
|
|
|
|
bobRegularSpend, err := input.CommitSpendNoDelay(
|
|
|
|
bobSigner, signDesc, sweepTx, tweakless,
|
|
|
|
)
|
2019-01-27 21:20:41 +03:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unable to create bob regular spend: %v", err)
|
|
|
|
}
|
|
|
|
sweepTx.TxIn[0].Witness = bobRegularSpend
|
2019-08-01 06:10:45 +03:00
|
|
|
vm, err = txscript.NewEngine(
|
|
|
|
regularOutput.PkScript,
|
2019-01-27 21:20:41 +03:00
|
|
|
sweepTx, 0, txscript.StandardVerifyFlags, nil,
|
2019-08-01 06:10:45 +03:00
|
|
|
nil, int64(channelBalance),
|
|
|
|
)
|
2019-01-27 21:20:41 +03:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unable to create engine: %v", err)
|
|
|
|
}
|
|
|
|
if err := vm.Execute(); err != nil {
|
|
|
|
t.Fatalf("bob p2wkh spend is invalid: %v", err)
|
|
|
|
}
|
|
|
|
}
|
2019-08-01 06:10:45 +03:00
|
|
|
|
|
|
|
// TestCommitmentSpendValidation test the spendability of both outputs within
|
|
|
|
// the commitment transaction.
|
|
|
|
//
|
|
|
|
// The following spending cases are covered by this test:
|
|
|
|
// * Alice's spend from the delayed output on her commitment transaction.
|
|
|
|
// * Bob's spend from Alice's delayed output when she broadcasts a revoked
|
|
|
|
// commitment transaction.
|
|
|
|
// * Bob's spend from his unencumbered output within Alice's commitment
|
|
|
|
// transaction.
|
|
|
|
func TestCommitmentSpendValidation(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
// In the modern network, all channels use the new tweakless format,
|
|
|
|
// but we also need to support older nodes that want to open channels
|
|
|
|
// with the legacy format, so we'll test spending in both scenarios.
|
|
|
|
for _, tweakless := range []bool{true, false} {
|
|
|
|
tweakless := tweakless
|
|
|
|
t.Run(fmt.Sprintf("tweak=%v", tweakless), func(t *testing.T) {
|
|
|
|
testSpendValidation(t, tweakless)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|