github.com/mit-dci/lit@v0.0.0-20221102210550-8c3d3b49f2ce/qln/htlc.go (about) 1 package qln 2 3 import ( 4 "bytes" 5 "fmt" 6 "time" 7 8 "github.com/mit-dci/lit/btcutil/chaincfg/chainhash" 9 "github.com/mit-dci/lit/btcutil/txscript" 10 "github.com/mit-dci/lit/consts" 11 "github.com/mit-dci/lit/crypto/fastsha256" 12 "github.com/mit-dci/lit/lnutil" 13 "github.com/mit-dci/lit/logging" 14 "github.com/mit-dci/lit/portxo" 15 "github.com/mit-dci/lit/sig64" 16 "github.com/mit-dci/lit/wire" 17 ) 18 19 func (nd *LitNode) OfferHTLC(qc *Qchan, amt uint32, RHash [32]byte, locktime uint32, data [32]byte) error { 20 logging.Infof("starting HTLC offer") 21 22 if qc.State.Failed { 23 return fmt.Errorf("cannot offer HTLC, channel failed") 24 } 25 26 if amt >= consts.MaxSendAmt { 27 return fmt.Errorf("max send 1G sat (1073741823)") 28 } 29 if amt == 0 { 30 return fmt.Errorf("have to send non-zero amount") 31 } 32 33 // see if channel is busy 34 // lock this channel 35 cts := false 36 for !cts { 37 qc.ChanMtx.Lock() 38 select { 39 case <-qc.ClearToSend: 40 cts = true 41 default: 42 qc.ChanMtx.Unlock() 43 } 44 } 45 // ClearToSend is now empty 46 47 // reload from disk here, after unlock 48 err := nd.ReloadQchanState(qc) 49 if err != nil { 50 // don't clear to send here; something is wrong with the channel 51 nd.FailChannel(qc) 52 qc.ChanMtx.Unlock() 53 return err 54 } 55 56 // check that channel is confirmed, if non-test coin 57 wal, ok := nd.SubWallet[qc.Coin()] 58 if !ok { 59 qc.ClearToSend <- true 60 qc.ChanMtx.Unlock() 61 return fmt.Errorf("Not connected to coin type %d\n", qc.Coin()) 62 } 63 64 if !wal.Params().TestCoin && qc.Height < 100 { 65 qc.ClearToSend <- true 66 qc.ChanMtx.Unlock() 67 return fmt.Errorf( 68 "height %d; must wait min 1 conf for non-test coin\n", qc.Height) 69 } 70 71 myAmt, _ := qc.GetChannelBalances() 72 myAmt -= qc.State.Fee + int64(amt) 73 74 // check if this push would lower my balance below minBal 75 if myAmt < consts.MinOutput { 76 qc.ClearToSend <- true 77 qc.ChanMtx.Unlock() 78 return fmt.Errorf("want to push %s but %s available after %s fee and %s consts.MinOutput", 79 lnutil.SatoshiColor(int64(amt)), 80 lnutil.SatoshiColor(qc.State.MyAmt-qc.State.Fee-consts.MinOutput), 81 lnutil.SatoshiColor(qc.State.Fee), 82 lnutil.SatoshiColor(consts.MinOutput)) 83 } 84 85 // if we got here, but channel is not in rest state, try to fix it. 86 if qc.State.Delta != 0 || qc.State.InProgHTLC != nil { 87 nd.FailChannel(qc) 88 qc.ChanMtx.Unlock() 89 return fmt.Errorf("channel not in rest state") 90 } 91 92 qc.State.Data = data 93 94 qc.State.InProgHTLC = new(HTLC) 95 qc.State.InProgHTLC.Idx = qc.State.HTLCIdx 96 qc.State.InProgHTLC.Incoming = false 97 qc.State.InProgHTLC.Amt = int64(amt) 98 qc.State.InProgHTLC.RHash = RHash 99 qc.State.InProgHTLC.Locktime = locktime 100 qc.State.InProgHTLC.TheirHTLCBase = qc.State.NextHTLCBase 101 102 qc.State.InProgHTLC.KeyGen.Depth = 5 103 qc.State.InProgHTLC.KeyGen.Step[0] = 44 | 1<<31 104 qc.State.InProgHTLC.KeyGen.Step[1] = qc.Coin() | 1<<31 105 qc.State.InProgHTLC.KeyGen.Step[2] = UseHTLCBase 106 qc.State.InProgHTLC.KeyGen.Step[3] = qc.State.HTLCIdx | 1<<31 107 qc.State.InProgHTLC.KeyGen.Step[4] = qc.Idx() | 1<<31 108 109 qc.State.InProgHTLC.MyHTLCBase, _ = nd.GetUsePub(qc.State.InProgHTLC.KeyGen, 110 UseHTLCBase) 111 112 // save to db with ONLY InProgHTLC changed 113 err = nd.SaveQchanState(qc) 114 if err != nil { 115 // don't clear to send here; something is wrong with the channel 116 nd.FailChannel(qc) 117 qc.ChanMtx.Unlock() 118 return err 119 } 120 121 logging.Infof("OfferHTLC: Sending HashSig") 122 123 err = nd.SendHashSig(qc) 124 if err != nil { 125 nd.FailChannel(qc) 126 qc.ChanMtx.Unlock() 127 return err 128 } 129 130 logging.Info("OfferHTLC: Done: sent HashSig") 131 132 logging.Info("got pre CTS...") 133 qc.ChanMtx.Unlock() 134 135 timeout := time.NewTimer(time.Second * consts.ChannelTimeout) 136 137 cts = false 138 for !cts { 139 qc.ChanMtx.Lock() 140 select { 141 case <-qc.ClearToSend: 142 cts = true 143 case <-timeout.C: 144 nd.FailChannel(qc) 145 qc.ChanMtx.Unlock() 146 return fmt.Errorf("channel failed: operation timed out") 147 default: 148 qc.ChanMtx.Unlock() 149 } 150 } 151 152 logging.Info("got post CTS...") 153 // since we cleared with that statement, fill it again before returning 154 qc.ClearToSend <- true 155 qc.ChanMtx.Unlock() 156 157 return nil 158 } 159 160 func (nd *LitNode) SendHashSig(q *Qchan) error { 161 q.State.StateIdx++ 162 163 q.State.MyAmt -= int64(q.State.InProgHTLC.Amt) 164 165 q.State.ElkPoint = q.State.NextElkPoint 166 q.State.NextElkPoint = q.State.N2ElkPoint 167 168 // make the signature to send over 169 commitmentSig, HTLCSigs, err := nd.SignState(q) 170 if err != nil { 171 return err 172 } 173 174 q.State.NextHTLCBase = q.State.N2HTLCBase 175 176 outMsg := lnutil.NewHashSigMsg(q.Peer(), q.Op, q.State.InProgHTLC.Amt, q.State.InProgHTLC.Locktime, q.State.InProgHTLC.RHash, commitmentSig, HTLCSigs, q.State.Data) 177 178 logging.Infof("Sending HashSig with %d HTLC sigs", len(HTLCSigs)) 179 180 nd.tmpSendLitMsg(outMsg) 181 182 return nil 183 } 184 185 func (nd *LitNode) HashSigHandler(msg lnutil.HashSigMsg, qc *Qchan) error { 186 logging.Infof("Got HashSig: %v", msg) 187 188 var collision bool 189 190 // we should be clear to send when we get a hashSig 191 select { 192 case <-qc.ClearToSend: 193 // keep going, normal 194 default: 195 // collision 196 collision = true 197 } 198 199 logging.Infof("COLLISION is (%t)\n", collision) 200 201 // load state from disk 202 err := nd.ReloadQchanState(qc) 203 if err != nil { 204 nd.FailChannel(qc) 205 return fmt.Errorf("HashSigHandler ReloadQchan err %s", err.Error()) 206 } 207 208 // TODO we should send a response that the channel is closed. 209 // or offer to double spend with a cooperative close? 210 // or update the remote node on closed channel status when connecting 211 // TODO should disallow 'break' command when connected to the other node 212 // or merge 'break' and 'close' UI so that it breaks when it can't 213 // connect, and closes when it can. 214 if qc.CloseData.Closed { 215 return fmt.Errorf("HashSigHandler err: %d, %d is closed.", 216 qc.Peer(), qc.Idx()) 217 } 218 219 inProgHTLC := qc.State.InProgHTLC 220 221 htlcIdx := qc.State.HTLCIdx 222 223 clearingIdxs := make([]uint32, 0) 224 for _, h := range qc.State.HTLCs { 225 if h.Clearing { 226 clearingIdxs = append(clearingIdxs, h.Idx) 227 } 228 } 229 230 // If we are colliding 231 if collision { 232 if qc.State.InProgHTLC != nil { 233 // HashSig-HashSig collision 234 // Set the Idx to the InProg one first - to allow signature 235 // verification. Correct later 236 htlcIdx = qc.State.InProgHTLC.Idx 237 } else if len(clearingIdxs) > 0 { 238 // HashSig-PreimageSig collision 239 // Remove the clearing state for signature verification and 240 // add back afterwards. 241 for _, idx := range clearingIdxs { 242 qh := &qc.State.HTLCs[idx] 243 qh.Clearing = false 244 } 245 qc.State.CollidingHashPreimage = true 246 } else { 247 // We are colliding with DeltaSig 248 qc.State.CollidingHashDelta = true 249 } 250 } 251 252 incomingHTLC := new(HTLC) 253 incomingHTLC.Idx = htlcIdx 254 incomingHTLC.Incoming = true 255 incomingHTLC.Amt = int64(msg.Amt) 256 incomingHTLC.RHash = msg.RHash 257 incomingHTLC.Locktime = msg.Locktime 258 incomingHTLC.TheirHTLCBase = qc.State.NextHTLCBase 259 260 incomingHTLC.KeyGen.Depth = 5 261 incomingHTLC.KeyGen.Step[0] = 44 | 1<<31 262 incomingHTLC.KeyGen.Step[1] = qc.Coin() | 1<<31 263 incomingHTLC.KeyGen.Step[2] = UseHTLCBase 264 incomingHTLC.KeyGen.Step[3] = htlcIdx | 1<<31 265 incomingHTLC.KeyGen.Step[4] = qc.Idx() | 1<<31 266 267 incomingHTLC.MyHTLCBase, _ = nd.GetUsePub(incomingHTLC.KeyGen, 268 UseHTLCBase) 269 270 // In order to check the incoming HTLC sigs, put it as the in progress one. 271 // We'll set the record straight later. 272 qc.State.InProgHTLC = incomingHTLC 273 274 // they have to actually send you money 275 if msg.Amt < consts.MinOutput { 276 nd.FailChannel(qc) 277 return fmt.Errorf("HashSigHandler err: HTLC amount %d less than minOutput", msg.Amt) 278 } 279 280 _, theirAmt := qc.GetChannelBalances() 281 theirAmt -= int64(msg.Amt) 282 283 // check if this push is takes them below minimum output size 284 if theirAmt < consts.MinOutput { 285 nd.FailChannel(qc) 286 return fmt.Errorf( 287 "making HTLC of size %s reduces them too low; counterparty bal %s fee %s consts.MinOutput %s", 288 lnutil.SatoshiColor(int64(msg.Amt)), 289 lnutil.SatoshiColor(theirAmt), 290 lnutil.SatoshiColor(qc.State.Fee), 291 lnutil.SatoshiColor(consts.MinOutput)) 292 } 293 294 // update to the next state to verify 295 qc.State.StateIdx++ 296 297 logging.Infof("Got message %x", msg.Data) 298 qc.State.Data = msg.Data 299 300 // verify sig for the next state. only save if this works 301 curElk := qc.State.ElkPoint 302 qc.State.ElkPoint = qc.State.NextElkPoint 303 304 // TODO: There are more signatures required 305 err = qc.VerifySigs(msg.CommitmentSignature, msg.HTLCSigs) 306 if err != nil { 307 nd.FailChannel(qc) 308 return fmt.Errorf("HashSigHandler err %s", err.Error()) 309 } 310 qc.State.ElkPoint = curElk 311 312 // After verification of signatures, add back the clearing state in case 313 // of HashSig-PreimageSig collisions 314 for _, idx := range clearingIdxs { 315 qh := &qc.State.HTLCs[idx] 316 qh.Clearing = true 317 } 318 319 // (seems odd, but everything so far we still do in case of collision, so 320 // only check here. If it's a collision, set, save, send gapSigRev 321 322 // save channel with new state, new sig, and positive delta set 323 // and maybe collision; still haven't checked 324 err = nd.SaveQchanState(qc) 325 if err != nil { 326 nd.FailChannel(qc) 327 return fmt.Errorf("HashSigHandler SaveQchanState err %s", err.Error()) 328 } 329 330 // If we are colliding Hashsig-Hashsig, determine who has what place in the 331 // HTLC structure 332 if collision && inProgHTLC != nil { 333 curIdx := qc.State.InProgHTLC.Idx 334 nextIdx := qc.State.HTLCIdx + 1 335 336 if bytes.Compare(qc.State.MyNextHTLCBase[:], qc.State.NextHTLCBase[:]) > 0 { 337 qc.State.CollidingHTLC = inProgHTLC 338 qc.State.InProgHTLC = incomingHTLC 339 } else { 340 qc.State.CollidingHTLC = incomingHTLC 341 qc.State.InProgHTLC = inProgHTLC 342 } 343 qc.State.InProgHTLC.Idx = curIdx 344 qc.State.CollidingHTLC.Idx = nextIdx 345 qc.State.CollidingHTLC.TheirHTLCBase = qc.State.N2HTLCBase 346 qc.State.CollidingHTLC.KeyGen.Depth = 5 347 qc.State.CollidingHTLC.KeyGen.Step[0] = 44 | 1<<31 348 qc.State.CollidingHTLC.KeyGen.Step[1] = qc.Coin() | 1<<31 349 qc.State.CollidingHTLC.KeyGen.Step[2] = UseHTLCBase 350 qc.State.CollidingHTLC.KeyGen.Step[3] = qc.State.CollidingHTLC.Idx | 1<<31 351 qc.State.CollidingHTLC.KeyGen.Step[4] = qc.Idx() | 1<<31 352 353 qc.State.CollidingHTLC.MyHTLCBase, _ = nd.GetUsePub(qc.State.CollidingHTLC.KeyGen, 354 UseHTLCBase) 355 } 356 357 var kg portxo.KeyGen 358 kg.Depth = 5 359 kg.Step[0] = 44 | 1<<31 360 kg.Step[1] = qc.Coin() | 1<<31 361 kg.Step[2] = UseHTLCBase 362 kg.Step[3] = qc.State.HTLCIdx + 2 | 1<<31 363 kg.Step[4] = qc.Idx() | 1<<31 364 365 qc.State.MyNextHTLCBase = qc.State.MyN2HTLCBase 366 qc.State.MyN2HTLCBase, err = nd.GetUsePub(kg, UseHTLCBase) 367 if err != nil { 368 nd.FailChannel(qc) 369 return err 370 } 371 372 // save channel with new HTLCBases 373 err = nd.SaveQchanState(qc) 374 if err != nil { 375 nd.FailChannel(qc) 376 return fmt.Errorf("HashSigHandler SaveQchanState err %s", err.Error()) 377 } 378 379 if qc.State.Collision != 0 || qc.State.CollidingHTLC != nil || qc.State.CollidingHashPreimage || qc.State.CollidingHashDelta { 380 err = nd.SendGapSigRev(qc) 381 if err != nil { 382 nd.FailChannel(qc) 383 return fmt.Errorf("HashSigHandler SendGapSigRev err %s", err.Error()) 384 } 385 } else { // saved to db, now proceed to create & sign their tx 386 err = nd.SendSigRev(qc) 387 if err != nil { 388 nd.FailChannel(qc) 389 return fmt.Errorf("HashSigHandler SendSigRev err %s", err.Error()) 390 } 391 } 392 return nil 393 } 394 395 func (nd *LitNode) ClearHTLC(qc *Qchan, R [16]byte, HTLCIdx uint32, data [32]byte) error { 396 if qc.State.Failed { 397 return fmt.Errorf("cannot clear, channel failed") 398 } 399 400 // see if channel is busy 401 // lock this channel 402 cts := false 403 for !cts { 404 qc.ChanMtx.Lock() 405 select { 406 case <-qc.ClearToSend: 407 cts = true 408 default: 409 qc.ChanMtx.Unlock() 410 } 411 } 412 // ClearToSend is now empty 413 414 // reload from disk here, after unlock 415 err := nd.ReloadQchanState(qc) 416 if err != nil { 417 // don't clear to send here; something is wrong with the channel 418 nd.FailChannel(qc) 419 qc.ChanMtx.Unlock() 420 return err 421 } 422 423 // check that channel is confirmed, if non-test coin 424 wal, ok := nd.SubWallet[qc.Coin()] 425 if !ok { 426 qc.ClearToSend <- true 427 qc.ChanMtx.Unlock() 428 return fmt.Errorf("Not connected to coin type %d\n", qc.Coin()) 429 } 430 431 if !wal.Params().TestCoin && qc.Height < 100 { 432 qc.ClearToSend <- true 433 qc.ChanMtx.Unlock() 434 return fmt.Errorf( 435 "height %d; must wait min 1 conf for non-test coin\n", qc.Height) 436 } 437 438 if int(HTLCIdx) >= len(qc.State.HTLCs) { 439 qc.ClearToSend <- true 440 qc.ChanMtx.Unlock() 441 return fmt.Errorf("HTLC idx %d out of range", HTLCIdx) 442 } 443 444 if qc.State.HTLCs[HTLCIdx].Cleared { 445 qc.ClearToSend <- true 446 qc.ChanMtx.Unlock() 447 return fmt.Errorf("HTLC %d already cleared", HTLCIdx) 448 } 449 450 var timeout bool 451 if R == [16]byte{} { 452 if int32(qc.State.HTLCs[HTLCIdx].Locktime) > wal.CurrentHeight() { 453 qc.ClearToSend <- true 454 qc.ChanMtx.Unlock() 455 return fmt.Errorf("Cannot timeout HTLC because locktime %d has not expired. Height: %d", qc.State.HTLCs[HTLCIdx].Locktime, wal.CurrentHeight()) 456 } 457 458 timeout = true 459 } 460 461 if !timeout { 462 RHash := fastsha256.Sum256(R[:]) 463 if qc.State.HTLCs[HTLCIdx].RHash != RHash { 464 qc.ClearToSend <- true 465 qc.ChanMtx.Unlock() 466 return fmt.Errorf("Preimage does not hash to expected value. Expected %x got %x", qc.State.HTLCs[HTLCIdx].RHash, RHash) 467 } 468 } 469 470 // if we got here, but channel is not in rest state, try to fix it. 471 if qc.State.Delta != 0 || qc.State.InProgHTLC != nil { 472 nd.FailChannel(qc) 473 qc.ChanMtx.Unlock() 474 return fmt.Errorf("channel not in rest state") 475 } 476 477 qc.State.HTLCs[HTLCIdx].Clearing = true 478 qc.State.HTLCs[HTLCIdx].R = R 479 qc.State.Data = data 480 481 // save to db with ONLY Clearing & R changed 482 err = nd.SaveQchanState(qc) 483 if err != nil { 484 // don't clear to send here; something is wrong with the channel 485 nd.FailChannel(qc) 486 qc.ChanMtx.Unlock() 487 return err 488 } 489 490 logging.Info("ClearHTLC: Sending PreimageSig") 491 492 err = nd.SendPreimageSig(qc, HTLCIdx) 493 if err != nil { 494 nd.FailChannel(qc) 495 qc.ChanMtx.Unlock() 496 return err 497 } 498 499 logging.Info("got pre CTS...") 500 qc.ChanMtx.Unlock() 501 502 timeoutTimer := time.NewTimer(time.Second * consts.ChannelTimeout) 503 504 cts = false 505 for !cts { 506 qc.ChanMtx.Lock() 507 select { 508 case <-qc.ClearToSend: 509 cts = true 510 case <-timeoutTimer.C: 511 nd.FailChannel(qc) 512 qc.ChanMtx.Unlock() 513 return fmt.Errorf("channel failed: operation timed out") 514 default: 515 qc.ChanMtx.Unlock() 516 } 517 } 518 519 logging.Info("got post CTS...") 520 // since we cleared with that statement, fill it again before returning 521 qc.ClearToSend <- true 522 qc.ChanMtx.Unlock() 523 524 return nil 525 } 526 527 func (nd *LitNode) SendPreimageSig(q *Qchan, Idx uint32) error { 528 q.State.StateIdx++ 529 530 if q.State.HTLCs[Idx].Incoming != (q.State.HTLCs[Idx].R == [16]byte{}) { 531 q.State.MyAmt += q.State.HTLCs[Idx].Amt 532 } 533 534 q.State.ElkPoint = q.State.NextElkPoint 535 q.State.NextElkPoint = q.State.N2ElkPoint 536 537 // make the signature to send over 538 commitmentSig, HTLCSigs, err := nd.SignState(q) 539 if err != nil { 540 return err 541 } 542 543 outMsg := lnutil.NewPreimageSigMsg(q.Peer(), q.Op, Idx, q.State.HTLCs[Idx].R, commitmentSig, HTLCSigs, q.State.Data) 544 545 logging.Infof("Sending PreimageSig with %d HTLC sigs", len(HTLCSigs)) 546 547 nd.tmpSendLitMsg(outMsg) 548 549 return nil 550 } 551 552 func (nd *LitNode) PreimageSigHandler(msg lnutil.PreimageSigMsg, qc *Qchan) error { 553 logging.Infof("Got PreimageSig: %v", msg) 554 555 var collision bool 556 557 // we should be clear to send when we get a preimageSig 558 select { 559 case <-qc.ClearToSend: 560 // keep going, normal 561 default: 562 // collision 563 collision = true 564 } 565 566 logging.Infof("COLLISION is (%t)\n", collision) 567 568 // load state from disk 569 err := nd.ReloadQchanState(qc) 570 if err != nil { 571 nd.FailChannel(qc) 572 return fmt.Errorf("PreimageSigHandler ReloadQchan err %s", err.Error()) 573 } 574 575 wal, ok := nd.SubWallet[qc.Coin()] 576 if !ok { 577 return fmt.Errorf("Not connected to coin type %d\n", qc.Coin()) 578 } 579 580 // TODO we should send a response that the channel is closed. 581 // or offer to double spend with a cooperative close? 582 // or update the remote node on closed channel status when connecting 583 // TODO should disallow 'break' command when connected to the other node 584 // or merge 'break' and 'close' UI so that it breaks when it can't 585 // connect, and closes when it can. 586 if qc.CloseData.Closed { 587 return fmt.Errorf("PreimageSigHandler err: %d, %d is closed.", 588 qc.Peer(), qc.Idx()) 589 } 590 591 clearingIdxs := make([]uint32, 0) 592 for _, h := range qc.State.HTLCs { 593 if h.Clearing { 594 clearingIdxs = append(clearingIdxs, h.Idx) 595 } 596 } 597 598 if qc.State.Delta > 0 { 599 logging.Errorf( 600 "PreimageSigHandler err: chan %d delta %d, expect rev, send empty rev", 601 qc.Idx(), qc.State.Delta) 602 603 return nd.SendREV(qc) 604 } 605 606 if int(msg.Idx) >= len(qc.State.HTLCs) { 607 return fmt.Errorf("HTLC Idx %d out of range", msg.Idx) 608 } 609 610 if qc.State.HTLCs[msg.Idx].Cleared { 611 return fmt.Errorf("HTLC %d already cleared", msg.Idx) 612 } 613 614 var timeout bool 615 if msg.R == [16]byte{} { 616 if int32(qc.State.HTLCs[msg.Idx].Locktime) > wal.CurrentHeight() { 617 return fmt.Errorf("Cannot timeout HTLC because locktime %d has not expired. Height: %d", qc.State.HTLCs[msg.Idx].Locktime, wal.CurrentHeight()) 618 } 619 620 timeout = true 621 } 622 623 RHash := fastsha256.Sum256(msg.R[:]) 624 if !timeout { 625 if qc.State.HTLCs[msg.Idx].RHash != RHash { 626 return fmt.Errorf("Preimage does not hash to expected value. Expected %x got %x", qc.State.HTLCs[msg.Idx].RHash, RHash) 627 } 628 } 629 630 go func() { 631 txids, err := nd.ClaimHTLC(msg.R) 632 if err != nil { 633 logging.Errorf("error claiming HTLCs: %s", err.Error()) 634 } 635 636 if len(txids) == 0 { 637 logging.Infof("found no other HTLCs to claim with R: %x, RHash: %x", msg.R, RHash) 638 } 639 640 for _, id := range txids { 641 logging.Infof("claimed HTLC with txid: %x", id) 642 } 643 }() 644 645 inProgHTLC := qc.State.InProgHTLC 646 if collision { 647 if inProgHTLC != nil { 648 // PreimageSig-HashSig collision. Temporarily remove inprog HTLC for 649 // verifying the signature, then do a GapSigRev 650 qc.State.InProgHTLC = nil 651 qc.State.CollidingHashPreimage = true 652 } else if len(clearingIdxs) > 0 { 653 // PreimageSig-PreimageSig collision. 654 // Remove the clearing state for signature verification and 655 // add back afterwards. 656 for _, idx := range clearingIdxs { 657 qh := &qc.State.HTLCs[idx] 658 qh.Clearing = false 659 } 660 qc.State.CollidingPreimages = true 661 } else { 662 // PreimageSig-DeltaSig collision. Figure out later. 663 qc.State.CollidingPreimageDelta = true 664 } 665 } 666 667 // update to the next state to verify 668 qc.State.StateIdx++ 669 670 logging.Infof("Got message %x", msg.Data) 671 qc.State.Data = msg.Data 672 673 h := &qc.State.HTLCs[msg.Idx] 674 675 h.Clearing = true 676 h.R = msg.R 677 678 if h.Incoming != timeout { 679 qc.State.MyAmt += h.Amt 680 } 681 682 // verify sig for the next state. only save if this works 683 684 stashElk := qc.State.ElkPoint 685 qc.State.ElkPoint = qc.State.NextElkPoint 686 // TODO: There are more signatures required 687 err = qc.VerifySigs(msg.CommitmentSignature, msg.HTLCSigs) 688 if err != nil { 689 nd.FailChannel(qc) 690 return fmt.Errorf("PreimageSigHandler err %s", err.Error()) 691 } 692 qc.State.ElkPoint = stashElk 693 694 qc.State.InProgHTLC = inProgHTLC 695 696 // After verification of signatures, add back the clearing state in case 697 // of PreimageSig-PreimageSig collisions 698 for _, idx := range clearingIdxs { 699 qh := &qc.State.HTLCs[idx] 700 qh.Clearing = true 701 } 702 703 if qc.State.CollidingHashPreimage { 704 var kg portxo.KeyGen 705 kg.Depth = 5 706 kg.Step[0] = 44 | 1<<31 707 kg.Step[1] = qc.Coin() | 1<<31 708 kg.Step[2] = UseHTLCBase 709 kg.Step[3] = qc.State.HTLCIdx + 2 | 1<<31 710 kg.Step[4] = qc.Idx() | 1<<31 711 712 qc.State.MyNextHTLCBase = qc.State.MyN2HTLCBase 713 qc.State.MyN2HTLCBase, err = nd.GetUsePub(kg, 714 UseHTLCBase) 715 716 if err != nil { 717 nd.FailChannel(qc) 718 return err 719 } 720 } 721 722 // (seems odd, but everything so far we still do in case of collision, so 723 // only check here. If it's a collision, set, save, send gapSigRev 724 725 // save channel with new state, new sig, and positive delta set 726 // and maybe collision; still haven't checked 727 err = nd.SaveQchanState(qc) 728 if err != nil { 729 nd.FailChannel(qc) 730 return fmt.Errorf("PreimageSigHandler SaveQchanState err %s", err.Error()) 731 } 732 733 if qc.State.Collision != 0 || qc.State.CollidingHashPreimage || qc.State.CollidingPreimages || qc.State.CollidingPreimageDelta { 734 err = nd.SendGapSigRev(qc) 735 if err != nil { 736 nd.FailChannel(qc) 737 return fmt.Errorf("PreimageSigHandler SendGapSigRev err %s", err.Error()) 738 } 739 } else { // saved to db, now proceed to create & sign their tx 740 err = nd.SendSigRev(qc) 741 if err != nil { 742 nd.FailChannel(qc) 743 return fmt.Errorf("PreimageSigHandler SendSigRev err %s", err.Error()) 744 } 745 } 746 return nil 747 } 748 749 func (nd *LitNode) SetHTLCClearedOnChain(q *Qchan, h HTLC) error { 750 q.ChanMtx.Lock() 751 err := nd.ReloadQchanState(q) 752 if err != nil { 753 logging.Errorf("Error reloading qchan state: %s", err.Error()) 754 q.ChanMtx.Unlock() 755 return err 756 } 757 qh := &q.State.HTLCs[h.Idx] 758 qh.ClearedOnChain = true 759 err = nd.SaveQchanState(q) 760 if err != nil { 761 logging.Errorf("Error saving qchan state: %s", err.Error()) 762 q.ChanMtx.Unlock() 763 return err 764 } 765 q.ChanMtx.Unlock() 766 767 return nil 768 } 769 770 // ClaimHTLC will claim an HTLC on-chain output from a broken channel using 771 // the given preimage. Returns the TXIDs of the claim transactions 772 func (nd *LitNode) ClaimHTLC(R [16]byte) ([][32]byte, error) { 773 txids := make([][32]byte, 0) 774 RHash := fastsha256.Sum256(R[:]) 775 htlcs, channels, err := nd.FindHTLCsByHash(RHash) 776 if err != nil { 777 return nil, err 778 } 779 for i, h := range htlcs { 780 781 // Outgoing HTLCs should not be claimed using the preimage, but 782 // using the timeout. So only claim incoming ones in this routine 783 if h.Incoming && !h.Cleared { 784 q := channels[i] 785 if q.CloseData.Closed { 786 copy(h.R[:], R[:]) 787 tx, err := nd.ClaimHTLCOnChain(q, h) 788 if err != nil { 789 logging.Errorf("Error claiming HTLC: %s", err.Error()) 790 continue 791 } 792 nd.SetHTLCClearedOnChain(q, h) 793 txids = append(txids, tx.TxHash()) 794 } else { 795 // For off-chain we need to fetch the channel from the node 796 // otherwise we're talking to a different instance of the channel 797 nd.RemoteMtx.Lock() 798 peer, ok := nd.RemoteCons[q.Peer()] 799 800 nd.RemoteMtx.Unlock() 801 if !ok { 802 logging.Errorf("Couldn't find peer %d in RemoteCons", q.Peer()) 803 continue 804 } 805 qc, ok := peer.QCs[q.Idx()] 806 if !ok { 807 logging.Errorf("Couldn't find channel %d in peer.QCs", q.Idx()) 808 continue 809 } 810 811 logging.Infof("Cleaing HTLC from channel [%d] idx [%d]\n", q.Idx(), h.Idx) 812 err = nd.ClearHTLC(qc, R, h.Idx, [32]byte{}) 813 if err != nil { 814 logging.Errorf("failed to clear HTLC: %s", err.Error()) 815 continue 816 } 817 } 818 819 nd.MultihopMutex.Lock() 820 defer nd.MultihopMutex.Unlock() 821 for idx, mu := range nd.InProgMultihop { 822 if bytes.Equal(mu.HHash[:], RHash[:]) && !mu.Succeeded { 823 nd.InProgMultihop[idx].Succeeded = true 824 nd.InProgMultihop[idx].PreImage = R 825 err = nd.SaveMultihopPayment(nd.InProgMultihop[idx]) 826 if err != nil { 827 return txids, err 828 } 829 } 830 } 831 } 832 } 833 return txids, nil 834 } 835 836 func (nd *LitNode) ClaimHTLCTimeouts(coinType uint32, height int32) ([][32]byte, error) { 837 txids := make([][32]byte, 0) 838 htlcs, channels, err := nd.FindHTLCsByTimeoutHeight(coinType, height) 839 if err != nil { 840 return nil, err 841 } 842 if len(htlcs) > 0 { 843 logging.Infof("Found [%d] HTLC Outpoints that have timed out\n", len(htlcs)) 844 for i, h := range htlcs { 845 if !h.Incoming { // only for timed out HTLCs! 846 q := channels[i] 847 if q.CloseData.Closed { 848 tx, err := nd.ClaimHTLCOnChain(q, h) 849 if err != nil { 850 logging.Errorf("Error claiming HTLC: %s", err.Error()) 851 continue 852 } 853 nd.SetHTLCClearedOnChain(q, h) 854 txids = append(txids, tx.TxHash()) 855 } else { 856 // For off-chain we need to fetch the channel from the node 857 // otherwise we're talking to a different instance of the channel 858 nd.RemoteMtx.Lock() 859 peer, ok := nd.RemoteCons[q.Peer()] 860 861 nd.RemoteMtx.Unlock() 862 if !ok { 863 return nil, fmt.Errorf("Couldn't find peer %d in RemoteCons", q.Peer()) 864 } 865 qc, ok := peer.QCs[q.Idx()] 866 if !ok { 867 return nil, fmt.Errorf("Couldn't find channel %d in peer.QCs", q.Idx()) 868 } 869 logging.Infof("Timing out HTLC from channel [%d] idx [%d]\n", q.Idx(), h.Idx) 870 err = nd.ClearHTLC(qc, [16]byte{}, h.Idx, [32]byte{}) 871 if err != nil { 872 logging.Errorf("error clearing HTLC: %s", err.Error()) 873 continue 874 } 875 } 876 } 877 } 878 } 879 return txids, nil 880 } 881 882 func (nd *LitNode) FindHTLCsByTimeoutHeight(coinType uint32, height int32) ([]HTLC, []*Qchan, error) { 883 htlcs := make([]HTLC, 0) 884 channels := make([]*Qchan, 0) 885 qc, err := nd.GetAllQchans() 886 if err != nil { 887 return nil, nil, err 888 } 889 for _, q := range qc { 890 err := nd.ReloadQchanState(q) 891 if err != nil { 892 return nil, nil, err 893 } 894 if q.Coin() == coinType { 895 for _, h := range q.State.HTLCs { 896 if !h.Incoming && !h.Cleared { 897 if height >= int32(h.Locktime) { 898 htlcs = append(htlcs, h) 899 channels = append(channels, q) 900 } else { 901 logging.Infof("Ignoring HTLC in chan [%d] idx [%d] - expires at block [%d] (now: %d)", q.Idx(), h.Idx, h.Locktime, height) 902 } 903 } 904 } 905 } 906 } 907 return htlcs, channels, nil 908 } 909 910 func (nd *LitNode) FindHTLCsByHash(hash [32]byte) ([]HTLC, []*Qchan, error) { 911 htlcs := make([]HTLC, 0) 912 channels := make([]*Qchan, 0) 913 qc, err := nd.GetAllQchans() 914 if err != nil { 915 return nil, nil, err 916 } 917 for _, q := range qc { 918 for _, h := range q.State.HTLCs { 919 if bytes.Equal(h.RHash[:], hash[:]) { 920 htlcs = append(htlcs, h) 921 channels = append(channels, q) 922 } 923 } 924 } 925 return htlcs, channels, nil 926 } 927 928 func (nd *LitNode) GetHTLC(op *wire.OutPoint) (HTLC, *Qchan, error) { 929 var empty HTLC 930 qc, err := nd.GetAllQchans() 931 if err != nil { 932 return empty, nil, err 933 } 934 for _, q := range qc { 935 tx, _, _, err := q.BuildStateTxs(false) 936 if err != nil { 937 return empty, nil, err 938 } 939 for _, h := range q.State.HTLCs { 940 txid := tx.TxHash() 941 _, i, err := GetHTLCOut(q, h, tx, false) 942 if err != nil { 943 return empty, nil, err 944 } 945 hashOp := wire.NewOutPoint(&txid, i) 946 if lnutil.OutPointsEqual(*op, *hashOp) { 947 return h, q, nil 948 } 949 } 950 } 951 return empty, nil, nil 952 } 953 954 func GetHTLCOut(q *Qchan, h HTLC, tx *wire.MsgTx, mine bool) (*wire.TxOut, uint32, error) { 955 for i, out := range tx.TxOut { 956 htlcOut, err := q.GenHTLCOut(h, mine) 957 if err != nil { 958 return nil, 0, err 959 } 960 if bytes.Compare(out.PkScript, htlcOut.PkScript) == 0 { 961 return out, uint32(i), nil 962 } 963 } 964 965 return nil, 0, fmt.Errorf("Could not find HTLC output with desired PkScript") 966 } 967 968 func (q *Qchan) GetCloseTxs() (*wire.MsgTx, []*wire.MsgTx, bool, error) { 969 for i, h := range q.State.HTLCs { 970 if !h.Cleared && h.Clearing { 971 q.State.HTLCs[i].Clearing = false 972 } 973 } 974 975 q.State.InProgHTLC = nil 976 q.State.CollidingHTLC = nil 977 978 mine := true 979 stateTx, htlcSpends, _, err := q.BuildStateTxs(mine) 980 if err != nil { 981 return nil, nil, false, err 982 } 983 984 stateTxID := stateTx.TxHash() 985 if !q.CloseData.CloseTxid.IsEqual(&stateTxID) { 986 mine = false 987 stateTx, htlcSpends, _, err = q.BuildStateTxs(mine) 988 if err != nil { 989 return nil, nil, false, err 990 } 991 992 stateTxID = stateTx.TxHash() 993 994 if !q.CloseData.CloseTxid.IsEqual(&stateTxID) { 995 return nil, nil, false, fmt.Errorf("Could not find/regenerate proper close TX") 996 } 997 } 998 return stateTx, htlcSpends, mine, nil 999 } 1000 1001 func (nd *LitNode) ClaimHTLCOnChain(q *Qchan, h HTLC) (*wire.MsgTx, error) { 1002 wal, ok := nd.SubWallet[q.Coin()] 1003 if !ok { 1004 return nil, fmt.Errorf("Unable to find wallet for cointype [%d]", q.Coin()) 1005 } 1006 1007 if !h.Incoming { 1008 unlockHeight := int32(h.Locktime) 1009 if wal.CurrentHeight() < unlockHeight { 1010 err := fmt.Errorf("Trying to claim timeout before timelock expires - wait until height %d", unlockHeight) 1011 logging.Error(err.Error()) 1012 return nil, err 1013 } 1014 1015 } 1016 1017 stateTx, htlcSpends, mine, err := q.GetCloseTxs() 1018 if err != nil { 1019 return nil, err 1020 } 1021 stateTxID := stateTx.TxHash() 1022 1023 htlcTxo, i, err := GetHTLCOut(q, h, stateTx, mine) 1024 if err != nil { 1025 return nil, err 1026 } 1027 1028 curElk, err := q.ElkSnd.AtIndex(q.State.StateIdx) 1029 if err != nil { 1030 return nil, err 1031 } 1032 elkScalar := lnutil.ElkScalar(curElk) 1033 HTLCPrivBase, err := wal.GetPriv(h.KeyGen) 1034 if err != nil { 1035 return nil, err 1036 } 1037 1038 HTLCPriv := lnutil.CombinePrivKeyWithBytes(HTLCPrivBase, elkScalar[:]) 1039 tx := wire.NewMsgTx() 1040 op := wire.NewOutPoint(&stateTxID, i) 1041 if mine { 1042 for _, s := range htlcSpends { 1043 if lnutil.OutPointsEqual(*op, s.TxIn[0].PreviousOutPoint) { 1044 tx = s 1045 break 1046 } 1047 } 1048 } else { 1049 // They broke. 1050 // Claim back to my wallet, i only need my sig & preimage (for success) 1051 // or just my sig when timed out. 1052 1053 tx.Version = 2 1054 tx.LockTime = 0 1055 1056 in := wire.NewTxIn(op, nil, nil) 1057 in.Sequence = 0 1058 1059 tx.AddTxIn(in) 1060 1061 pkh, err := wal.NewAdr() 1062 if err != nil { 1063 return nil, err 1064 } 1065 1066 if !h.Incoming { 1067 tx.LockTime = h.Locktime 1068 } 1069 1070 tx.AddTxOut(wire.NewTxOut(h.Amt-q.State.Fee, lnutil.DirectWPKHScriptFromPKH(pkh))) 1071 } 1072 hc := txscript.NewTxSigHashes(tx) 1073 1074 HTLCScript, err := q.GenHTLCScript(h, mine) 1075 if err != nil { 1076 return nil, err 1077 } 1078 1079 HTLCparsed, err := txscript.ParseScript(HTLCScript) 1080 if err != nil { 1081 return nil, err 1082 } 1083 1084 spendHTLCHash := txscript.CalcWitnessSignatureHash( 1085 HTLCparsed, hc, txscript.SigHashAll, tx, 0, htlcTxo.Value) 1086 1087 logging.Infof("Signing HTLC Hash [%x] with key [%x]\n", spendHTLCHash, HTLCPriv.PubKey().SerializeCompressed()) 1088 mySig, err := HTLCPriv.Sign(spendHTLCHash) 1089 if err != nil { 1090 return nil, err 1091 } 1092 1093 myBigSig := append(mySig.Serialize(), byte(txscript.SigHashAll)) 1094 theirBigSig := sig64.SigDecompress(h.Sig) 1095 theirBigSig = append(theirBigSig, byte(txscript.SigHashAll)) 1096 1097 if mine { 1098 tx.TxIn[0].Witness = make([][]byte, 5) 1099 tx.TxIn[0].Witness[0] = nil 1100 tx.TxIn[0].Witness[1] = theirBigSig 1101 tx.TxIn[0].Witness[2] = myBigSig 1102 if h.Incoming { 1103 tx.TxIn[0].Witness[3] = h.R[:] 1104 } else { 1105 tx.TxIn[0].Witness[3] = nil 1106 } 1107 tx.TxIn[0].Witness[4] = HTLCScript 1108 } else { 1109 tx.TxIn[0].Witness = make([][]byte, 3) 1110 tx.TxIn[0].Witness[0] = myBigSig 1111 1112 if h.Incoming { 1113 tx.TxIn[0].Witness[1] = h.R[:] 1114 } else { 1115 tx.TxIn[0].Witness[1] = nil 1116 } 1117 1118 tx.TxIn[0].Witness[2] = HTLCScript 1119 } 1120 1121 logging.Debug("Claiming HTLC on-chain. TX:") 1122 lnutil.PrintTx(tx) 1123 1124 wal.StopWatchingThis(*op) 1125 wal.DirectSendTx(tx) 1126 1127 if mine { 1128 // TODO: Refactor this into a function shared with close.go's GetCloseTxos 1129 // Store the timeout utxo into the wallit 1130 comNum := GetStateIdxFromTx(stateTx, q.GetChanHint(true)) 1131 1132 theirElkPoint, err := q.ElkPoint(false, comNum) 1133 if err != nil { 1134 return nil, err 1135 } 1136 1137 // build script to store in porTxo, make pubkeys 1138 timeoutPub := lnutil.AddPubsEZ(q.MyHAKDBase, theirElkPoint) 1139 revokePub := lnutil.CombinePubs(q.TheirHAKDBase, theirElkPoint) 1140 1141 script := lnutil.CommitScript(revokePub, timeoutPub, q.Delay) 1142 // script check. redundant / just in case 1143 genSH := fastsha256.Sum256(script) 1144 if !bytes.Equal(genSH[:], tx.TxOut[0].PkScript[2:34]) { 1145 logging.Warnf("got different observed and generated SH scripts.\n") 1146 logging.Warnf("in %s:%d, see %x\n", tx.TxHash().String(), 0, tx.TxOut[0].PkScript) 1147 logging.Warnf("generated %x \n", genSH) 1148 logging.Warnf("revokable pub %x\ntimeout pub %x\n", revokePub, timeoutPub) 1149 return tx, nil 1150 } 1151 1152 // create the ScriptHash, timeout portxo. 1153 var shTxo portxo.PorTxo // create new utxo and copy into it 1154 // use txidx's elkrem as it may not be most recent 1155 elk, err := q.ElkSnd.AtIndex(comNum) 1156 if err != nil { 1157 return nil, err 1158 } 1159 // keypath is the same, except for use 1160 shTxo.KeyGen = q.KeyGen 1161 shTxo.Op.Hash = tx.TxHash() 1162 shTxo.Op.Index = 0 1163 shTxo.Height = q.CloseData.CloseHeight 1164 shTxo.KeyGen.Step[2] = UseChannelHAKDBase 1165 1166 elkpoint := lnutil.ElkPointFromHash(elk) 1167 addhash := chainhash.DoubleHashH(append(elkpoint[:], q.MyHAKDBase[:]...)) 1168 1169 shTxo.PrivKey = addhash 1170 1171 shTxo.Mode = portxo.TxoP2WSHComp 1172 shTxo.Value = tx.TxOut[0].Value 1173 shTxo.Seq = uint32(q.Delay) 1174 shTxo.PreSigStack = make([][]byte, 1) // timeout has one presig item 1175 shTxo.PreSigStack[0] = nil // and that item is a nil (timeout) 1176 1177 shTxo.PkScript = script 1178 1179 wal.ExportUtxo(&shTxo) 1180 } 1181 1182 return tx, nil 1183 }