transactions_test.go 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071
  1. package lnwallet
  2. import (
  3. "bytes"
  4. "crypto/rand"
  5. "encoding/binary"
  6. "encoding/hex"
  7. "encoding/json"
  8. "fmt"
  9. "io"
  10. "net"
  11. "os"
  12. "sort"
  13. "strings"
  14. "testing"
  15. "time"
  16. "github.com/btcsuite/btcd/btcec/v2"
  17. "github.com/btcsuite/btcd/btcutil"
  18. "github.com/btcsuite/btcd/chaincfg/chainhash"
  19. "github.com/btcsuite/btcd/txscript"
  20. "github.com/btcsuite/btcd/wire"
  21. "github.com/lightningnetwork/lnd/channeldb"
  22. "github.com/lightningnetwork/lnd/input"
  23. "github.com/lightningnetwork/lnd/keychain"
  24. "github.com/lightningnetwork/lnd/lntypes"
  25. "github.com/lightningnetwork/lnd/lnwallet/chainfee"
  26. "github.com/lightningnetwork/lnd/lnwire"
  27. "github.com/lightningnetwork/lnd/shachain"
  28. "github.com/stretchr/testify/require"
  29. )
  30. /**
  31. * This file implements that different types of transactions used in the
  32. * lightning protocol are created correctly. To do so, the tests use the test
  33. * vectors defined in Appendix B & C of BOLT 03.
  34. */
  35. // testContext contains the test parameters defined in Appendix B & C of the
  36. // BOLT 03 spec.
  37. type testContext struct {
  38. localFundingPrivkey *btcec.PrivateKey
  39. localPaymentBasepointSecret *btcec.PrivateKey
  40. localDelayedPaymentBasepointSecret *btcec.PrivateKey
  41. remoteFundingPrivkey *btcec.PrivateKey
  42. remoteRevocationBasepointSecret *btcec.PrivateKey
  43. remotePaymentBasepointSecret *btcec.PrivateKey
  44. localPerCommitSecret lntypes.Hash
  45. fundingTx *btcutil.Tx
  46. localCsvDelay uint16
  47. fundingAmount btcutil.Amount
  48. dustLimit btcutil.Amount
  49. commitHeight uint64
  50. t *testing.T
  51. }
  52. // newTestContext populates a new testContext struct with the constant
  53. // parameters defined in the BOLT 03 spec.
  54. func newTestContext(t *testing.T) *testContext {
  55. tc := new(testContext)
  56. priv := func(v string) *btcec.PrivateKey {
  57. k, err := privkeyFromHex(v)
  58. require.NoError(t, err)
  59. return k
  60. }
  61. tc.remoteFundingPrivkey = priv("1552dfba4f6cf29a62a0af13c8d6981d36d0ef8d61ba10fb0fe90da7634d7e13")
  62. tc.remoteRevocationBasepointSecret = priv("2222222222222222222222222222222222222222222222222222222222222222")
  63. tc.remotePaymentBasepointSecret = priv("4444444444444444444444444444444444444444444444444444444444444444")
  64. tc.localPaymentBasepointSecret = priv("1111111111111111111111111111111111111111111111111111111111111111")
  65. tc.localDelayedPaymentBasepointSecret = priv("3333333333333333333333333333333333333333333333333333333333333333")
  66. tc.localFundingPrivkey = priv("30ff4956bbdd3222d44cc5e8a1261dab1e07957bdac5ae88fe3261ef321f3749")
  67. var err error
  68. tc.localPerCommitSecret, err = lntypes.MakeHashFromStr("1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100")
  69. require.NoError(t, err)
  70. const fundingTxHex = "0200000001adbb20ea41a8423ea937e76e8151636bf6093b70eaff942930d20576600521fd000000006b48304502210090587b6201e166ad6af0227d3036a9454223d49a1f11839c1a362184340ef0240220577f7cd5cca78719405cbf1de7414ac027f0239ef6e214c90fcaab0454d84b3b012103535b32d5eb0a6ed0982a0479bbadc9868d9836f6ba94dd5a63be16d875069184ffffffff028096980000000000220020c015c4a6be010e21657068fc2e6a9d02b27ebe4d490a25846f7237f104d1a3cd20256d29010000001600143ca33c2e4446f4a305f23c80df8ad1afdcf652f900000000"
  71. tc.fundingTx, err = txFromHex(fundingTxHex)
  72. require.NoError(t, err)
  73. tc.localCsvDelay = 144
  74. tc.fundingAmount = 10000000
  75. tc.dustLimit = 546
  76. tc.commitHeight = 42
  77. tc.t = t
  78. return tc
  79. }
  80. type htlc struct {
  81. incoming bool
  82. amount lnwire.MilliSatoshi
  83. expiry uint32
  84. preimage string
  85. }
  86. var testHtlcsSet1 = []htlc{
  87. // htlc 0.
  88. {
  89. incoming: true,
  90. amount: 1000000,
  91. expiry: 500,
  92. preimage: "0000000000000000000000000000000000000000000000000" +
  93. "000000000000000",
  94. },
  95. // htlc 1.
  96. {
  97. incoming: true,
  98. amount: 2000000,
  99. expiry: 501,
  100. preimage: "0101010101010101010101010101010101010101010101010" +
  101. "101010101010101",
  102. },
  103. // htlc 2.
  104. {
  105. incoming: false,
  106. amount: 2000000,
  107. expiry: 502,
  108. preimage: "0202020202020202020202020202020202020202020202020" +
  109. "202020202020202",
  110. },
  111. // htlc 3.
  112. {
  113. incoming: false,
  114. amount: 3000000,
  115. expiry: 503,
  116. preimage: "03030303030303030303030303030303030303030303030303" +
  117. "03030303030303",
  118. },
  119. // htlc 4.
  120. {
  121. incoming: true,
  122. amount: 4000000,
  123. expiry: 504,
  124. preimage: "0404040404040404040404040404040404040404040404040" +
  125. "404040404040404",
  126. },
  127. }
  128. var testHtlcsSet2 = []htlc{
  129. // htlc 1.
  130. {
  131. incoming: true,
  132. amount: 2000000,
  133. expiry: 501,
  134. preimage: "01010101010101010101010101010101010101010101010101" +
  135. "01010101010101",
  136. },
  137. // htlc 5.
  138. {
  139. incoming: false,
  140. amount: 5000000,
  141. expiry: 506,
  142. preimage: "05050505050505050505050505050505050505050505050505" +
  143. "05050505050505",
  144. },
  145. // htlc 6.
  146. {
  147. incoming: false,
  148. amount: 5000001,
  149. expiry: 505,
  150. preimage: "05050505050505050505050505050505050505050505050505" +
  151. "05050505050505",
  152. },
  153. }
  154. // htlcDesc is a description used to construct each HTLC in each test case.
  155. type htlcDesc struct {
  156. RemoteSigHex string
  157. ResolutionTxHex string
  158. }
  159. type testCase struct {
  160. Name string
  161. LocalBalance lnwire.MilliSatoshi
  162. RemoteBalance lnwire.MilliSatoshi
  163. FeePerKw btcutil.Amount
  164. DustLimitSatoshis btcutil.Amount
  165. // UseTestHtlcs defined whether the fixed set of test htlc should be
  166. // added to the channel before checking the commitment assertions.
  167. UseTestHtlcs bool
  168. HtlcDescs []htlcDesc
  169. ExpectedCommitmentTxHex string
  170. RemoteSigHex string
  171. }
  172. // TestCommitmentAndHTLCTransactions checks the test vectors specified in
  173. // BOLT 03, Appendix C. This deterministically generates commitment and second
  174. // level HTLC transactions and checks that they match the expected values.
  175. func TestCommitmentAndHTLCTransactions(t *testing.T) {
  176. t.Parallel()
  177. vectorSets := []struct {
  178. name string
  179. jsonFile string
  180. chanType channeldb.ChannelType
  181. }{
  182. {
  183. name: "legacy",
  184. chanType: channeldb.SingleFunderBit,
  185. jsonFile: "test_vectors_legacy.json",
  186. },
  187. {
  188. name: "anchors",
  189. chanType: channeldb.SingleFunderTweaklessBit |
  190. channeldb.AnchorOutputsBit,
  191. jsonFile: "test_vectors_anchors.json",
  192. },
  193. {
  194. name: "zero fee htlc tx",
  195. chanType: channeldb.SingleFunderTweaklessBit |
  196. channeldb.AnchorOutputsBit |
  197. channeldb.ZeroHtlcTxFeeBit,
  198. jsonFile: "test_vectors_zero_fee_htlc_tx.json",
  199. },
  200. }
  201. for _, set := range vectorSets {
  202. set := set
  203. var testCases []testCase
  204. jsonText, err := os.ReadFile(set.jsonFile)
  205. require.NoError(t, err)
  206. err = json.Unmarshal(jsonText, &testCases)
  207. require.NoError(t, err)
  208. for _, test := range testCases {
  209. test := test
  210. name := fmt.Sprintf("%s-%s", set.name, test.Name)
  211. t.Run(name, func(t *testing.T) {
  212. t.Parallel()
  213. t.Run(test.Name, func(t *testing.T) {
  214. testVectors(t, set.chanType, test)
  215. })
  216. })
  217. }
  218. }
  219. }
  220. // addTestHtlcs adds the test vector htlcs to the update logs of the local and
  221. // remote node.
  222. func addTestHtlcs(t *testing.T, remote, local *LightningChannel,
  223. htlcSet []htlc) map[[20]byte]lntypes.Preimage {
  224. hash160map := make(map[[20]byte]lntypes.Preimage)
  225. for _, htlc := range htlcSet {
  226. preimage, err := lntypes.MakePreimageFromStr(htlc.preimage)
  227. require.NoError(t, err)
  228. hash := preimage.Hash()
  229. // Store ripemd160 hash of the payment hash to later identify
  230. // resolutions.
  231. var hash160 [20]byte
  232. copy(hash160[:], input.Ripemd160H(hash[:]))
  233. hash160map[hash160] = preimage
  234. // Add htlc to the channel.
  235. chanID := lnwire.NewChanIDFromOutPoint(remote.ChannelPoint())
  236. msg := &lnwire.UpdateAddHTLC{
  237. Amount: htlc.amount,
  238. ChanID: chanID,
  239. Expiry: htlc.expiry,
  240. PaymentHash: hash,
  241. }
  242. if htlc.incoming {
  243. htlcID, err := remote.addHTLC(msg, nil, NoBuffer)
  244. require.NoError(t, err, "unable to add htlc")
  245. msg.ID = htlcID
  246. _, err = local.ReceiveHTLC(msg)
  247. require.NoError(t, err, "unable to recv htlc")
  248. } else {
  249. htlcID, err := local.addHTLC(msg, nil, NoBuffer)
  250. require.NoError(t, err, "unable to add htlc")
  251. msg.ID = htlcID
  252. _, err = remote.ReceiveHTLC(msg)
  253. require.NoError(t, err, "unable to recv htlc")
  254. }
  255. }
  256. return hash160map
  257. }
  258. // testVectors executes a commit dance to end up with the commitment transaction
  259. // that is described in the test vectors and then asserts that all values are
  260. // correct.
  261. func testVectors(t *testing.T, chanType channeldb.ChannelType, test testCase) {
  262. tc := newTestContext(t)
  263. // Determine which htlc set to use.
  264. testHtlcs := testHtlcsSet1
  265. if strings.Contains(test.Name, "same amount and preimage") {
  266. testHtlcs = testHtlcsSet2
  267. }
  268. // If the test specifies a dust limit, then use it instead of the
  269. // default.
  270. if test.DustLimitSatoshis != 0 {
  271. tc.dustLimit = test.DustLimitSatoshis
  272. }
  273. // Balances in the test vectors are before subtraction of in-flight
  274. // htlcs. Convert to spendable balances.
  275. remoteBalance := test.RemoteBalance
  276. localBalance := test.LocalBalance
  277. if test.UseTestHtlcs {
  278. for _, htlc := range testHtlcs {
  279. if htlc.incoming {
  280. remoteBalance += htlc.amount
  281. } else {
  282. localBalance += htlc.amount
  283. }
  284. }
  285. }
  286. // Assert that the remote and local balances add up to the channel
  287. // capacity.
  288. require.EqualValues(t, lnwire.NewMSatFromSatoshis(tc.fundingAmount),
  289. remoteBalance+localBalance)
  290. // Set up a test channel on which the test commitment transaction is
  291. // going to be produced.
  292. remoteChannel, localChannel := createTestChannelsForVectors(
  293. tc,
  294. chanType, test.FeePerKw,
  295. remoteBalance.ToSatoshis(),
  296. localBalance.ToSatoshis(),
  297. )
  298. // Add htlcs (if any) to the update logs of both sides and save a hash
  299. // map that allows us to identify the htlcs in the scripts later on and
  300. // retrieve the corresponding preimage.
  301. var hash160map map[[20]byte]lntypes.Preimage
  302. if test.UseTestHtlcs {
  303. hash160map = addTestHtlcs(
  304. t, remoteChannel, localChannel, testHtlcs,
  305. )
  306. }
  307. // Execute commit dance to arrive at the point where the local node has
  308. // received the test commitment and the remote signature.
  309. localNewCommit, err := localChannel.SignNextCommitment()
  310. require.NoError(t, err, "local unable to sign commitment")
  311. err = remoteChannel.ReceiveNewCommitment(localNewCommit.CommitSigs)
  312. require.NoError(t, err)
  313. revMsg, _, _, err := remoteChannel.RevokeCurrentCommitment()
  314. require.NoError(t, err)
  315. _, _, _, _, err = localChannel.ReceiveRevocation(revMsg)
  316. require.NoError(t, err)
  317. remoteNewCommit, err := remoteChannel.SignNextCommitment()
  318. require.NoError(t, err)
  319. require.Equal(
  320. t, test.RemoteSigHex,
  321. hex.EncodeToString(
  322. remoteNewCommit.CommitSig.ToSignatureBytes(),
  323. ),
  324. )
  325. for i, sig := range remoteNewCommit.HtlcSigs {
  326. require.Equal(
  327. t, test.HtlcDescs[i].RemoteSigHex,
  328. hex.EncodeToString(sig.ToSignatureBytes()),
  329. )
  330. }
  331. err = localChannel.ReceiveNewCommitment(remoteNewCommit.CommitSigs)
  332. require.NoError(t, err)
  333. _, _, _, err = localChannel.RevokeCurrentCommitment()
  334. require.NoError(t, err)
  335. // Now the local node force closes the channel so that we can inspect
  336. // its state.
  337. forceCloseSum, err := localChannel.ForceClose()
  338. require.NoError(t, err)
  339. // Assert that the commitment transaction itself is as expected.
  340. var txBytes bytes.Buffer
  341. require.NoError(t, forceCloseSum.CloseTx.Serialize(&txBytes))
  342. require.Equal(
  343. t, test.ExpectedCommitmentTxHex,
  344. hex.EncodeToString(txBytes.Bytes()),
  345. )
  346. // Obtain the second level transactions that the local node's channel
  347. // state machine has produced. Store them in a map indexed by commit tx
  348. // output index. Also complete the second level transaction with the
  349. // preimage. This is normally done later in the contract resolver.
  350. secondLevelTxes := map[uint32]*wire.MsgTx{}
  351. storeTx := func(index uint32, tx *wire.MsgTx) {
  352. // Prevent overwrites.
  353. _, exists := secondLevelTxes[index]
  354. require.False(t, exists)
  355. secondLevelTxes[index] = tx
  356. }
  357. for _, r := range forceCloseSum.HtlcResolutions.IncomingHTLCs {
  358. successTx := r.SignedSuccessTx
  359. witnessScript := successTx.TxIn[0].Witness[4]
  360. var hash160 [20]byte
  361. copy(hash160[:], witnessScript[69:69+20])
  362. preimage := hash160map[hash160]
  363. successTx.TxIn[0].Witness[3] = preimage[:]
  364. storeTx(r.HtlcPoint().Index, successTx)
  365. }
  366. for _, r := range forceCloseSum.HtlcResolutions.OutgoingHTLCs {
  367. storeTx(r.HtlcPoint().Index, r.SignedTimeoutTx)
  368. }
  369. // Create a list of second level transactions ordered by commit tx
  370. // output index.
  371. var keys []uint32
  372. for k := range secondLevelTxes {
  373. keys = append(keys, k)
  374. }
  375. sort.Slice(keys, func(a, b int) bool {
  376. return keys[a] < keys[b]
  377. })
  378. // Assert that this list matches the test vectors.
  379. for i, idx := range keys {
  380. tx := secondLevelTxes[idx]
  381. var b bytes.Buffer
  382. err := tx.Serialize(&b)
  383. require.NoError(t, err)
  384. require.Equal(
  385. t,
  386. test.HtlcDescs[i].ResolutionTxHex,
  387. hex.EncodeToString(b.Bytes()),
  388. )
  389. }
  390. }
  391. func TestCommitTxStateHint(t *testing.T) {
  392. t.Parallel()
  393. stateHintTests := []struct {
  394. name string
  395. from uint64
  396. to uint64
  397. inputs int
  398. shouldFail bool
  399. }{
  400. {
  401. name: "states 0 to 1000",
  402. from: 0,
  403. to: 1000,
  404. inputs: 1,
  405. shouldFail: false,
  406. },
  407. {
  408. name: "states 'maxStateHint-1000' to 'maxStateHint'",
  409. from: maxStateHint - 1000,
  410. to: maxStateHint,
  411. inputs: 1,
  412. shouldFail: false,
  413. },
  414. {
  415. name: "state 'maxStateHint+1'",
  416. from: maxStateHint + 1,
  417. to: maxStateHint + 10,
  418. inputs: 1,
  419. shouldFail: true,
  420. },
  421. {
  422. name: "commit transaction with two inputs",
  423. inputs: 2,
  424. shouldFail: true,
  425. },
  426. }
  427. var obfuscator [StateHintSize]byte
  428. copy(obfuscator[:], testHdSeed[:StateHintSize])
  429. timeYesterday := uint32(time.Now().Unix() - 24*60*60)
  430. for _, test := range stateHintTests {
  431. commitTx := wire.NewMsgTx(2)
  432. // Add supplied number of inputs to the commitment transaction.
  433. for i := 0; i < test.inputs; i++ {
  434. commitTx.AddTxIn(&wire.TxIn{})
  435. }
  436. for i := test.from; i <= test.to; i++ {
  437. stateNum := uint64(i)
  438. err := SetStateNumHint(commitTx, stateNum, obfuscator)
  439. if err != nil && !test.shouldFail {
  440. t.Fatalf("unable to set state num %v: %v", i, err)
  441. } else if err == nil && test.shouldFail {
  442. t.Fatalf("Failed(%v): test should fail but did not", test.name)
  443. }
  444. locktime := commitTx.LockTime
  445. sequence := commitTx.TxIn[0].Sequence
  446. // Locktime should not be less than 500,000,000 and not larger
  447. // than the time 24 hours ago. One day should provide a good
  448. // enough buffer for the tests.
  449. if locktime < 5e8 || locktime > timeYesterday {
  450. if !test.shouldFail {
  451. t.Fatalf("The value of locktime (%v) may cause the commitment "+
  452. "transaction to be unspendable", locktime)
  453. }
  454. }
  455. if sequence&wire.SequenceLockTimeDisabled == 0 {
  456. if !test.shouldFail {
  457. t.Fatalf("Sequence locktime is NOT disabled when it should be")
  458. }
  459. }
  460. extractedStateNum := GetStateNumHint(commitTx, obfuscator)
  461. if extractedStateNum != stateNum && !test.shouldFail {
  462. t.Fatalf("state number mismatched, expected %v, got %v",
  463. stateNum, extractedStateNum)
  464. } else if extractedStateNum == stateNum && test.shouldFail {
  465. t.Fatalf("Failed(%v): test should fail but did not", test.name)
  466. }
  467. }
  468. t.Logf("Passed: %v", test.name)
  469. }
  470. }
  471. // testSpendValidation ensures that we're able to spend all outputs in the
  472. // commitment transaction that we create.
  473. func testSpendValidation(t *testing.T, tweakless bool) {
  474. // We generate a fake output, and the corresponding txin. This output
  475. // doesn't need to exist, as we'll only be validating spending from the
  476. // transaction that references this.
  477. txid, err := chainhash.NewHash(testHdSeed.CloneBytes())
  478. require.NoError(t, err, "unable to create txid")
  479. fundingOut := &wire.OutPoint{
  480. Hash: *txid,
  481. Index: 50,
  482. }
  483. fakeFundingTxIn := wire.NewTxIn(fundingOut, nil, nil)
  484. const channelBalance = btcutil.Amount(1 * 10e8)
  485. const csvTimeout = 5
  486. // We also set up set some resources for the commitment transaction.
  487. // Each side currently has 1 BTC within the channel, with a total
  488. // channel capacity of 2BTC.
  489. aliceKeyPriv, aliceKeyPub := btcec.PrivKeyFromBytes(
  490. testWalletPrivKey,
  491. )
  492. bobKeyPriv, bobKeyPub := btcec.PrivKeyFromBytes(
  493. bobsPrivKey,
  494. )
  495. revocationPreimage := testHdSeed.CloneBytes()
  496. commitSecret, commitPoint := btcec.PrivKeyFromBytes(
  497. revocationPreimage,
  498. )
  499. revokePubKey := input.DeriveRevocationPubkey(bobKeyPub, commitPoint)
  500. aliceDelayKey := input.TweakPubKey(aliceKeyPub, commitPoint)
  501. // Bob will have the channel "force closed" on him, so for the sake of
  502. // our commitments, if it's tweakless, his key will just be his regular
  503. // pubkey.
  504. bobPayKey := input.TweakPubKey(bobKeyPub, commitPoint)
  505. channelType := channeldb.SingleFunderBit
  506. if tweakless {
  507. bobPayKey = bobKeyPub
  508. channelType = channeldb.SingleFunderTweaklessBit
  509. }
  510. remoteCommitTweak := input.SingleTweakBytes(commitPoint, aliceKeyPub)
  511. localCommitTweak := input.SingleTweakBytes(commitPoint, bobKeyPub)
  512. aliceSelfOutputSigner := input.NewMockSigner(
  513. []*btcec.PrivateKey{aliceKeyPriv}, nil,
  514. )
  515. // Calculate the dust limit we'll use for the test.
  516. dustLimit := DustLimitForSize(input.UnknownWitnessSize)
  517. aliceChanCfg := &channeldb.ChannelConfig{
  518. ChannelConstraints: channeldb.ChannelConstraints{
  519. DustLimit: dustLimit,
  520. CsvDelay: csvTimeout,
  521. },
  522. }
  523. bobChanCfg := &channeldb.ChannelConfig{
  524. ChannelConstraints: channeldb.ChannelConstraints{
  525. DustLimit: dustLimit,
  526. CsvDelay: csvTimeout,
  527. },
  528. }
  529. // With all the test data set up, we create the commitment transaction.
  530. // We only focus on a single party's transactions, as the scripts are
  531. // identical with the roles reversed.
  532. //
  533. // This is Alice's commitment transaction, so she must wait a CSV delay
  534. // of 5 blocks before sweeping the output, while bob can spend
  535. // immediately with either the revocation key, or his regular key.
  536. keyRing := &CommitmentKeyRing{
  537. ToLocalKey: aliceDelayKey,
  538. RevocationKey: revokePubKey,
  539. ToRemoteKey: bobPayKey,
  540. }
  541. commitmentTx, err := CreateCommitTx(
  542. channelType, *fakeFundingTxIn, keyRing, aliceChanCfg,
  543. bobChanCfg, channelBalance, channelBalance, 0, true, 0,
  544. )
  545. if err != nil {
  546. t.Fatalf("unable to create commitment transaction: %v", nil)
  547. }
  548. delayOutput := commitmentTx.TxOut[0]
  549. regularOutput := commitmentTx.TxOut[1]
  550. // We're testing an uncooperative close, output sweep, so construct a
  551. // transaction which sweeps the funds to a random address.
  552. targetOutput, err := input.CommitScriptUnencumbered(aliceKeyPub)
  553. require.NoError(t, err, "unable to create target output")
  554. sweepTx := wire.NewMsgTx(2)
  555. sweepTx.AddTxIn(wire.NewTxIn(&wire.OutPoint{
  556. Hash: commitmentTx.TxHash(),
  557. Index: 0,
  558. }, nil, nil))
  559. sweepTx.AddTxOut(&wire.TxOut{
  560. PkScript: targetOutput,
  561. Value: 0.5 * 10e8,
  562. })
  563. // First, we'll test spending with Alice's key after the timeout.
  564. delayScript, err := input.CommitScriptToSelf(
  565. csvTimeout, aliceDelayKey, revokePubKey,
  566. )
  567. require.NoError(t, err, "unable to generate alice delay script")
  568. sweepTx.TxIn[0].Sequence = input.LockTimeToSequence(false, csvTimeout)
  569. signDesc := &input.SignDescriptor{
  570. WitnessScript: delayScript,
  571. KeyDesc: keychain.KeyDescriptor{
  572. PubKey: aliceKeyPub,
  573. },
  574. SingleTweak: remoteCommitTweak,
  575. SigHashes: input.NewTxSigHashesV0Only(sweepTx),
  576. Output: &wire.TxOut{
  577. Value: int64(channelBalance),
  578. },
  579. HashType: txscript.SigHashAll,
  580. InputIndex: 0,
  581. }
  582. aliceWitnessSpend, err := input.CommitSpendTimeout(
  583. aliceSelfOutputSigner, signDesc, sweepTx,
  584. )
  585. require.NoError(t, err, "unable to generate delay commit spend witness")
  586. sweepTx.TxIn[0].Witness = aliceWitnessSpend
  587. vm, err := txscript.NewEngine(
  588. delayOutput.PkScript, sweepTx, 0, txscript.StandardVerifyFlags,
  589. nil, nil, int64(channelBalance),
  590. txscript.NewCannedPrevOutputFetcher(nil, 0),
  591. )
  592. require.NoError(t, err, "unable to create engine")
  593. if err := vm.Execute(); err != nil {
  594. t.Fatalf("spend from delay output is invalid: %v", err)
  595. }
  596. localSigner := input.NewMockSigner([]*btcec.PrivateKey{bobKeyPriv}, nil)
  597. // Next, we'll test bob spending with the derived revocation key to
  598. // simulate the scenario when Alice broadcasts this commitment
  599. // transaction after it's been revoked.
  600. signDesc = &input.SignDescriptor{
  601. KeyDesc: keychain.KeyDescriptor{
  602. PubKey: bobKeyPub,
  603. },
  604. DoubleTweak: commitSecret,
  605. WitnessScript: delayScript,
  606. SigHashes: input.NewTxSigHashesV0Only(sweepTx),
  607. Output: &wire.TxOut{
  608. Value: int64(channelBalance),
  609. },
  610. HashType: txscript.SigHashAll,
  611. InputIndex: 0,
  612. }
  613. bobWitnessSpend, err := input.CommitSpendRevoke(localSigner, signDesc,
  614. sweepTx)
  615. require.NoError(t, err, "unable to generate revocation witness")
  616. sweepTx.TxIn[0].Witness = bobWitnessSpend
  617. vm, err = txscript.NewEngine(
  618. delayOutput.PkScript, sweepTx, 0, txscript.StandardVerifyFlags,
  619. nil, nil, int64(channelBalance),
  620. txscript.NewCannedPrevOutputFetcher(nil, 0),
  621. )
  622. require.NoError(t, err, "unable to create engine")
  623. if err := vm.Execute(); err != nil {
  624. t.Fatalf("revocation spend is invalid: %v", err)
  625. }
  626. // In order to test the final scenario, we modify the TxIn of the sweep
  627. // transaction to instead point to the regular output (non delay)
  628. // within the commitment transaction.
  629. sweepTx.TxIn[0] = &wire.TxIn{
  630. PreviousOutPoint: wire.OutPoint{
  631. Hash: commitmentTx.TxHash(),
  632. Index: 1,
  633. },
  634. }
  635. // Finally, we test bob sweeping his output as normal in the case that
  636. // Alice broadcasts this commitment transaction.
  637. bobScriptP2WKH, err := input.CommitScriptUnencumbered(bobPayKey)
  638. require.NoError(t, err, "unable to create bob p2wkh script")
  639. signDesc = &input.SignDescriptor{
  640. KeyDesc: keychain.KeyDescriptor{
  641. PubKey: bobKeyPub,
  642. },
  643. WitnessScript: bobScriptP2WKH,
  644. SigHashes: input.NewTxSigHashesV0Only(sweepTx),
  645. Output: &wire.TxOut{
  646. Value: int64(channelBalance),
  647. PkScript: bobScriptP2WKH,
  648. },
  649. HashType: txscript.SigHashAll,
  650. InputIndex: 0,
  651. }
  652. if !tweakless {
  653. signDesc.SingleTweak = localCommitTweak
  654. }
  655. bobRegularSpend, err := input.CommitSpendNoDelay(
  656. localSigner, signDesc, sweepTx, tweakless,
  657. )
  658. require.NoError(t, err, "unable to create bob regular spend")
  659. sweepTx.TxIn[0].Witness = bobRegularSpend
  660. vm, err = txscript.NewEngine(
  661. regularOutput.PkScript,
  662. sweepTx, 0, txscript.StandardVerifyFlags, nil,
  663. nil, int64(channelBalance),
  664. txscript.NewCannedPrevOutputFetcher(bobScriptP2WKH, 0),
  665. )
  666. require.NoError(t, err, "unable to create engine")
  667. if err := vm.Execute(); err != nil {
  668. t.Fatalf("bob p2wkh spend is invalid: %v", err)
  669. }
  670. }
  671. // TestCommitmentSpendValidation test the spendability of both outputs within
  672. // the commitment transaction.
  673. //
  674. // The following spending cases are covered by this test:
  675. // - Alice's spend from the delayed output on her commitment transaction.
  676. // - Bob's spend from Alice's delayed output when she broadcasts a revoked
  677. // commitment transaction.
  678. // - Bob's spend from his unencumbered output within Alice's commitment
  679. // transaction.
  680. func TestCommitmentSpendValidation(t *testing.T) {
  681. t.Parallel()
  682. // In the modern network, all channels use the new tweakless format,
  683. // but we also need to support older nodes that want to open channels
  684. // with the legacy format, so we'll test spending in both scenarios.
  685. for _, tweakless := range []bool{true, false} {
  686. tweakless := tweakless
  687. t.Run(fmt.Sprintf("tweak=%v", tweakless), func(t *testing.T) {
  688. testSpendValidation(t, tweakless)
  689. })
  690. }
  691. }
  692. type mockProducer struct {
  693. secret chainhash.Hash
  694. }
  695. func (p *mockProducer) AtIndex(uint64) (*chainhash.Hash, error) {
  696. return &p.secret, nil
  697. }
  698. func (p *mockProducer) Encode(w io.Writer) error {
  699. _, err := w.Write(p.secret[:])
  700. return err
  701. }
  702. // createTestChannelsForVectors creates two LightningChannel instances for the
  703. // test channel that is used to verify the test vectors.
  704. func createTestChannelsForVectors(tc *testContext, chanType channeldb.ChannelType,
  705. feeRate btcutil.Amount, remoteBalance, localBalance btcutil.Amount) (
  706. *LightningChannel, *LightningChannel) {
  707. t := tc.t
  708. prevOut := &wire.OutPoint{
  709. Hash: *tc.fundingTx.Hash(),
  710. Index: 0,
  711. }
  712. fundingTxIn := wire.NewTxIn(prevOut, nil, nil)
  713. // Generate random some keys that don't actually matter but need to be
  714. // set.
  715. var (
  716. remoteDummy1, remoteDummy2 *btcec.PrivateKey
  717. localDummy2, localDummy1 *btcec.PrivateKey
  718. )
  719. generateKeys := []**btcec.PrivateKey{
  720. &remoteDummy1, &remoteDummy2, &localDummy1, &localDummy2,
  721. }
  722. for _, keyRef := range generateKeys {
  723. privkey, err := btcec.NewPrivateKey()
  724. require.NoError(t, err)
  725. *keyRef = privkey
  726. }
  727. // Define channel configurations.
  728. remoteCfg := channeldb.ChannelConfig{
  729. ChannelConstraints: channeldb.ChannelConstraints{
  730. DustLimit: tc.dustLimit,
  731. MaxPendingAmount: lnwire.NewMSatFromSatoshis(
  732. tc.fundingAmount,
  733. ),
  734. ChanReserve: 0,
  735. MinHTLC: 0,
  736. MaxAcceptedHtlcs: input.MaxHTLCNumber / 2,
  737. CsvDelay: tc.localCsvDelay,
  738. },
  739. MultiSigKey: keychain.KeyDescriptor{
  740. PubKey: tc.remoteFundingPrivkey.PubKey(),
  741. },
  742. PaymentBasePoint: keychain.KeyDescriptor{
  743. PubKey: tc.remotePaymentBasepointSecret.PubKey(),
  744. },
  745. HtlcBasePoint: keychain.KeyDescriptor{
  746. PubKey: tc.remotePaymentBasepointSecret.PubKey(),
  747. },
  748. DelayBasePoint: keychain.KeyDescriptor{
  749. PubKey: remoteDummy1.PubKey(),
  750. },
  751. RevocationBasePoint: keychain.KeyDescriptor{
  752. PubKey: tc.remoteRevocationBasepointSecret.PubKey(),
  753. },
  754. }
  755. localCfg := channeldb.ChannelConfig{
  756. ChannelConstraints: channeldb.ChannelConstraints{
  757. DustLimit: tc.dustLimit,
  758. MaxPendingAmount: lnwire.NewMSatFromSatoshis(
  759. tc.fundingAmount,
  760. ),
  761. ChanReserve: 0,
  762. MinHTLC: 0,
  763. MaxAcceptedHtlcs: input.MaxHTLCNumber / 2,
  764. CsvDelay: tc.localCsvDelay,
  765. },
  766. MultiSigKey: keychain.KeyDescriptor{
  767. PubKey: tc.localFundingPrivkey.PubKey(),
  768. },
  769. PaymentBasePoint: keychain.KeyDescriptor{
  770. PubKey: tc.localPaymentBasepointSecret.PubKey(),
  771. },
  772. HtlcBasePoint: keychain.KeyDescriptor{
  773. PubKey: tc.localPaymentBasepointSecret.PubKey(),
  774. },
  775. DelayBasePoint: keychain.KeyDescriptor{
  776. PubKey: tc.localDelayedPaymentBasepointSecret.PubKey(),
  777. },
  778. RevocationBasePoint: keychain.KeyDescriptor{
  779. PubKey: localDummy1.PubKey(),
  780. },
  781. }
  782. // Create mock producers to force usage of the test vector commitment
  783. // point.
  784. remotePreimageProducer := &mockProducer{
  785. secret: chainhash.Hash(tc.localPerCommitSecret),
  786. }
  787. remoteCommitPoint := input.ComputeCommitmentPoint(
  788. tc.localPerCommitSecret[:],
  789. )
  790. localPreimageProducer := &mockProducer{
  791. secret: chainhash.Hash(tc.localPerCommitSecret),
  792. }
  793. localCommitPoint := input.ComputeCommitmentPoint(
  794. tc.localPerCommitSecret[:],
  795. )
  796. // Create temporary databases.
  797. dbRemote, err := channeldb.Open(t.TempDir())
  798. require.NoError(t, err)
  799. dbLocal, err := channeldb.Open(t.TempDir())
  800. require.NoError(t, err)
  801. // Create the initial commitment transactions for the channel.
  802. feePerKw := chainfee.SatPerKWeight(feeRate)
  803. commitWeight := lntypes.WeightUnit(input.CommitWeight)
  804. if chanType.HasAnchors() {
  805. commitWeight = input.AnchorCommitWeight
  806. }
  807. commitFee := feePerKw.FeeForWeight(commitWeight)
  808. var anchorAmt btcutil.Amount
  809. if chanType.HasAnchors() {
  810. anchorAmt = 2 * anchorSize
  811. }
  812. remoteCommitTx, localCommitTx, err := CreateCommitmentTxns(
  813. remoteBalance, localBalance-commitFee,
  814. &remoteCfg, &localCfg, remoteCommitPoint,
  815. localCommitPoint, *fundingTxIn, chanType, true, 0,
  816. )
  817. require.NoError(t, err)
  818. // Set up the full channel state.
  819. // Subtract one because extra sig exchange will take place during setup
  820. // to get to the right test point.
  821. var commitHeight = tc.commitHeight - 1
  822. remoteCommit := channeldb.ChannelCommitment{
  823. CommitHeight: commitHeight,
  824. LocalBalance: lnwire.NewMSatFromSatoshis(remoteBalance),
  825. RemoteBalance: lnwire.NewMSatFromSatoshis(localBalance - commitFee - anchorAmt),
  826. CommitFee: commitFee,
  827. FeePerKw: btcutil.Amount(feePerKw),
  828. CommitTx: remoteCommitTx,
  829. CommitSig: testSigBytes,
  830. }
  831. localCommit := channeldb.ChannelCommitment{
  832. CommitHeight: commitHeight,
  833. LocalBalance: lnwire.NewMSatFromSatoshis(localBalance - commitFee - anchorAmt),
  834. RemoteBalance: lnwire.NewMSatFromSatoshis(remoteBalance),
  835. CommitFee: commitFee,
  836. FeePerKw: btcutil.Amount(feePerKw),
  837. CommitTx: localCommitTx,
  838. CommitSig: testSigBytes,
  839. }
  840. var chanIDBytes [8]byte
  841. _, err = io.ReadFull(rand.Reader, chanIDBytes[:])
  842. require.NoError(t, err)
  843. shortChanID := lnwire.NewShortChanIDFromInt(
  844. binary.BigEndian.Uint64(chanIDBytes[:]),
  845. )
  846. remoteChannelState := &channeldb.OpenChannel{
  847. LocalChanCfg: remoteCfg,
  848. RemoteChanCfg: localCfg,
  849. IdentityPub: remoteDummy2.PubKey(),
  850. FundingOutpoint: *prevOut,
  851. ShortChannelID: shortChanID,
  852. ChanType: chanType,
  853. IsInitiator: false,
  854. Capacity: tc.fundingAmount,
  855. RemoteCurrentRevocation: localCommitPoint,
  856. RevocationProducer: remotePreimageProducer,
  857. RevocationStore: shachain.NewRevocationStore(),
  858. LocalCommitment: remoteCommit,
  859. RemoteCommitment: remoteCommit,
  860. Db: dbRemote.ChannelStateDB(),
  861. Packager: channeldb.NewChannelPackager(shortChanID),
  862. FundingTxn: tc.fundingTx.MsgTx(),
  863. }
  864. localChannelState := &channeldb.OpenChannel{
  865. LocalChanCfg: localCfg,
  866. RemoteChanCfg: remoteCfg,
  867. IdentityPub: localDummy2.PubKey(),
  868. FundingOutpoint: *prevOut,
  869. ShortChannelID: shortChanID,
  870. ChanType: chanType,
  871. IsInitiator: true,
  872. Capacity: tc.fundingAmount,
  873. RemoteCurrentRevocation: remoteCommitPoint,
  874. RevocationProducer: localPreimageProducer,
  875. RevocationStore: shachain.NewRevocationStore(),
  876. LocalCommitment: localCommit,
  877. RemoteCommitment: localCommit,
  878. Db: dbLocal.ChannelStateDB(),
  879. Packager: channeldb.NewChannelPackager(shortChanID),
  880. FundingTxn: tc.fundingTx.MsgTx(),
  881. }
  882. // Create mock signers that can sign for the keys that are used.
  883. localSigner := input.NewMockSigner([]*btcec.PrivateKey{
  884. tc.localPaymentBasepointSecret, tc.localDelayedPaymentBasepointSecret,
  885. tc.localFundingPrivkey, localDummy1, localDummy2,
  886. }, nil)
  887. remoteSigner := input.NewMockSigner([]*btcec.PrivateKey{
  888. tc.remoteFundingPrivkey, tc.remoteRevocationBasepointSecret,
  889. tc.remotePaymentBasepointSecret, remoteDummy1, remoteDummy2,
  890. }, nil)
  891. remotePool := NewSigPool(1, remoteSigner)
  892. channelRemote, err := NewLightningChannel(
  893. remoteSigner, remoteChannelState, remotePool,
  894. )
  895. require.NoError(t, err)
  896. require.NoError(t, remotePool.Start())
  897. localPool := NewSigPool(1, localSigner)
  898. channelLocal, err := NewLightningChannel(
  899. localSigner, localChannelState, localPool,
  900. )
  901. require.NoError(t, err)
  902. require.NoError(t, localPool.Start())
  903. // Create state hunt obfuscator for the commitment transaction.
  904. obfuscator := createStateHintObfuscator(remoteChannelState)
  905. err = SetStateNumHint(
  906. remoteCommitTx, commitHeight, obfuscator,
  907. )
  908. require.NoError(t, err)
  909. err = SetStateNumHint(
  910. localCommitTx, commitHeight, obfuscator,
  911. )
  912. require.NoError(t, err)
  913. // Initialize the database.
  914. addr := &net.TCPAddr{
  915. IP: net.ParseIP("127.0.0.1"),
  916. Port: 18556,
  917. }
  918. require.NoError(t, channelRemote.channelState.SyncPending(addr, 101))
  919. addr = &net.TCPAddr{
  920. IP: net.ParseIP("127.0.0.1"),
  921. Port: 18555,
  922. }
  923. require.NoError(t, channelLocal.channelState.SyncPending(addr, 101))
  924. // Now that the channel are open, simulate the start of a session by
  925. // having local and remote extend their revocation windows to each other.
  926. err = initRevocationWindows(channelRemote, channelLocal)
  927. require.NoError(t, err)
  928. // Return a clean up function that stops goroutines and removes the test
  929. // databases.
  930. t.Cleanup(func() {
  931. dbLocal.Close()
  932. dbRemote.Close()
  933. require.NoError(t, remotePool.Stop())
  934. require.NoError(t, localPool.Stop())
  935. })
  936. return channelRemote, channelLocal
  937. }