github.com/mit-dci/lit@v0.0.0-20221102210550-8c3d3b49f2ce/qln/pushpull.go (about) 1 package qln 2 3 import ( 4 "bytes" 5 "errors" 6 "fmt" 7 "time" 8 9 "github.com/mit-dci/lit/logging" 10 11 "github.com/mit-dci/lit/consts" 12 "github.com/mit-dci/lit/lnutil" 13 "github.com/mit-dci/lit/portxo" 14 ) 15 16 // Grab the coins that are rightfully yours! Plus some more. 17 // For right now, spend all outputs from channel close. 18 //func Grab(args []string) error { 19 // return SCon.GrabAll() 20 //} 21 22 /* 23 24 3 messages 25 26 pusher -> puller 27 DeltaSig: how much is being sent, and a signature for that state 28 29 pusher <- puller 30 SigRev: A signature and revocation of previous state 31 32 pusher -> puller 33 Rev: revocation 34 35 Every revocation contains the elkrem hash being revoked, and the next elkpoint. 36 37 SendNextMsg logic: 38 39 Message to send: channel state (sanity check) 40 41 DeltaSig: 42 delta < 0 43 you must be pushing. 44 45 SigRev: 46 delta > 0 47 you must be pulling. 48 49 Rev: 50 delta == 0 51 you must be done. 52 53 (note that puller also sends a (useless) rev once they've received the rev and 54 have their delta set to 0) 55 56 Note that when there's nothing to send, it'll send a REV message, 57 revoking the previous state which has already been revoked. 58 59 We could distinguish by writing to the db that we've sent the REV message... 60 but that doesn't seem that useful because we don't know if they got it so 61 we might have to send it again anyway. 62 */ 63 64 /* 65 66 2 options for dealing with push collision: 67 sequential and concurrent. 68 sequential has a deterministic priority which selects who to continue 69 the go-ahead node completes the push, then waits for the other node to push. 70 71 DeltaSig collision handling: 72 73 Send a DeltaSig. Delta < 0. 74 Receive a DeltaSig with Delta < 0; need to send a GapSigRev 75 COLLISION: Set the collision flag (delta-(130)) 76 update amount with increment from received deltaSig 77 verify received signature & save to disk, update state number 78 *your delta value stays the same* 79 Send GapSigRev: revocation of previous state, and sig for next state 80 Receive GapSigRev 81 Clear collision flag 82 set delta = -delta (turns positive) 83 Update amount, verity received signature & save to disk, update state number 84 Send Rev for previous state 85 Receive Rev for previous state 86 87 88 */ 89 90 // SendNextMsg determines what message needs to be sent next 91 // based on the channel state. It then calls the appropriate function. 92 func (nd *LitNode) ReSendMsg(qc *Qchan) error { 93 94 // DeltaSig 95 if qc.State.Delta < 0 { 96 logging.Infof("Sending previously sent DeltaSig\n") 97 return nd.SendDeltaSig(qc) 98 } 99 100 // SigRev 101 if qc.State.Delta > 0 { 102 logging.Infof("Sending previously sent SigRev\n") 103 return nd.SendSigRev(qc) 104 } 105 106 // Rev 107 return nd.SendREV(qc) 108 } 109 110 // PushChannel initiates a state update by sending a DeltaSig 111 func (nd *LitNode) PushChannel(qc *Qchan, amt uint32, data [32]byte) error { 112 if qc.State.Failed { 113 return fmt.Errorf("cannot push, channel failed") 114 } 115 116 // sanity checks 117 if amt >= consts.MaxSendAmt { 118 return fmt.Errorf("max send 1G sat (1073741823)") 119 } 120 if amt == 0 { 121 return fmt.Errorf("have to send non-zero amount") 122 } 123 124 logging.Infof("started push on channel %d of %d\n", qc.Idx(), amt) 125 126 // see if channel is busy 127 // lock this channel 128 cts := false 129 for !cts { 130 qc.ChanMtx.Lock() 131 select { 132 case <-qc.ClearToSend: 133 cts = true 134 default: 135 qc.ChanMtx.Unlock() 136 } 137 } 138 // ClearToSend is now empty 139 140 // reload from disk here, after unlock 141 err := nd.ReloadQchanState(qc) 142 if err != nil { 143 // don't clear to send here; something is wrong with the channel 144 nd.FailChannel(qc) 145 qc.ChanMtx.Unlock() 146 return err 147 } 148 149 // check that channel is confirmed, if non-test coin 150 wal, ok := nd.SubWallet[qc.Coin()] 151 if !ok { 152 qc.ClearToSend <- true 153 qc.ChanMtx.Unlock() 154 return fmt.Errorf("Not connected to coin type %d\n", qc.Coin()) 155 } 156 157 if !wal.Params().TestCoin && qc.Height < 100 { 158 qc.ClearToSend <- true 159 qc.ChanMtx.Unlock() 160 return fmt.Errorf( 161 "height %d; must wait min 1 conf for non-test coin\n", qc.Height) 162 } 163 164 myAmt, theirAmt := qc.GetChannelBalances() 165 myAmt -= qc.State.Fee - int64(amt) 166 theirAmt += int64(amt) - qc.State.Fee 167 168 // check if this push would lower my balance below minBal 169 if myAmt < consts.MinOutput { 170 qc.ClearToSend <- true 171 qc.ChanMtx.Unlock() 172 return fmt.Errorf("want to push %s but %s available after %s fee and %s", 173 lnutil.SatoshiColor(int64(amt)), 174 lnutil.SatoshiColor(myAmt), 175 lnutil.SatoshiColor(qc.State.Fee), 176 lnutil.SatoshiColor(consts.MinOutput)) 177 } 178 // check if this push is sufficient to get them above minBal 179 if theirAmt < consts.MinOutput { 180 qc.ClearToSend <- true 181 qc.ChanMtx.Unlock() 182 return fmt.Errorf( 183 "pushing %s insufficient; counterparty bal %s fee %s MinOutput %s", 184 lnutil.SatoshiColor(int64(amt)), 185 lnutil.SatoshiColor(theirAmt), 186 lnutil.SatoshiColor(qc.State.Fee), 187 lnutil.SatoshiColor(consts.MinOutput)) 188 } 189 190 // if we got here, but channel is not in rest state, try to fix it. 191 if qc.State.Delta != 0 { 192 nd.FailChannel(qc) 193 qc.ChanMtx.Unlock() 194 return fmt.Errorf("channel not in rest state") 195 } 196 197 qc.State.Data = data 198 logging.Infof("Sending message %x", data) 199 200 qc.State.Delta = int32(-amt) 201 202 if qc.State.Delta == 0 { 203 nd.FailChannel(qc) 204 qc.ChanMtx.Unlock() 205 return errors.New("PushChannel: Delta cannot be zero") 206 } 207 208 // save to db with ONLY delta changed 209 err = nd.SaveQchanState(qc) 210 qc.LastUpdate = uint64(time.Now().UnixNano() / 1000) 211 if err != nil { 212 // don't clear to send here; something is wrong with the channel 213 nd.FailChannel(qc) 214 qc.ChanMtx.Unlock() 215 return err 216 } 217 // move unlock to here so that delta is saved before 218 219 logging.Infof("PushChannel: Sending DeltaSig") 220 221 err = nd.SendDeltaSig(qc) 222 if err != nil { 223 // don't clear; something is wrong with the network 224 qc.ChanMtx.Unlock() 225 return err 226 } 227 228 logging.Infof("PushChannel: Done: sent DeltaSig") 229 230 logging.Infof("got pre CTS... \n") 231 // block until clear to send is full again 232 qc.ChanMtx.Unlock() 233 234 timeout := time.NewTimer(time.Second * consts.ChannelTimeout) 235 236 cts = false 237 for !cts { 238 qc.ChanMtx.Lock() 239 select { 240 case <-qc.ClearToSend: 241 cts = true 242 case <-timeout.C: 243 nd.FailChannel(qc) 244 qc.ChanMtx.Unlock() 245 return fmt.Errorf("channel failed: operation timed out") 246 default: 247 qc.ChanMtx.Unlock() 248 } 249 } 250 251 logging.Infof("got post CTS... \n") 252 // since we cleared with that statement, fill it again before returning 253 qc.ClearToSend <- true 254 qc.ChanMtx.Unlock() 255 256 return nil 257 } 258 259 // SendDeltaSig initiates a push, sending the amount to be pushed and the new sig. 260 func (nd *LitNode) SendDeltaSig(q *Qchan) error { 261 // increment state number, update balance, go to next elkpoint 262 q.State.StateIdx++ 263 q.State.MyAmt += int64(q.State.Delta) 264 q.State.ElkPoint = q.State.NextElkPoint 265 q.State.NextElkPoint = q.State.N2ElkPoint 266 // N2Elk is now invalid 267 268 // make the signature to send over 269 270 // TODO: There are extra signatures required now 271 sig, HTLCSigs, err := nd.SignState(q) 272 if err != nil { 273 return err 274 } 275 276 if q.State.Delta == 0 { 277 return errors.New("Delta cannot be zero") 278 } 279 280 outMsg := lnutil.NewDeltaSigMsg(q.Peer(), q.Op, -q.State.Delta, sig, HTLCSigs, q.State.Data) 281 282 logging.Infof("Sending DeltaSig: %v", outMsg) 283 284 nd.tmpSendLitMsg(outMsg) 285 286 return nil 287 } 288 289 // DeltaSigHandler takes in a DeltaSig and responds with a SigRev (normally) 290 // or a GapSigRev (if there's a collision) 291 // Leaves the channel either expecting a Rev (normally) or a GapSigRev (collision) 292 func (nd *LitNode) DeltaSigHandler(msg lnutil.DeltaSigMsg, qc *Qchan) error { 293 logging.Infof("Got DeltaSig: %v", msg) 294 295 var collision bool 296 //incomingDelta := uint32(math.Abs(float64(msg.Delta))) //int32 (may be negative, but should not be) 297 incomingDelta := msg.Delta 298 299 // we should be clear to send when we get a deltaSig 300 select { 301 case <-qc.ClearToSend: 302 // keep going, normal 303 default: 304 // collision 305 collision = true 306 } 307 308 logging.Infof("COLLISION is (%t)\n", collision) 309 310 // load state from disk 311 err := nd.ReloadQchanState(qc) 312 if err != nil { 313 nd.FailChannel(qc) 314 return fmt.Errorf("DeltaSigHandler ReloadQchan err %s", err.Error()) 315 } 316 317 // TODO we should send a response that the channel is closed. 318 // or offer to double spend with a cooperative close? 319 // or update the remote node on closed channel status when connecting 320 // TODO should disallow 'break' command when connected to the other node 321 // or merge 'break' and 'close' UI so that it breaks when it can't 322 // connect, and closes when it can. 323 if qc.CloseData.Closed { 324 return fmt.Errorf("DeltaSigHandler err: %d, %d is closed.", 325 qc.Peer(), qc.Idx()) 326 } 327 328 clearingIdxs := make([]uint32, 0) 329 for _, h := range qc.State.HTLCs { 330 if h.Clearing { 331 clearingIdxs = append(clearingIdxs, h.Idx) 332 } 333 } 334 335 inProgHTLC := qc.State.InProgHTLC 336 337 if collision { 338 if qc.State.InProgHTLC != nil { 339 // Collision between DeltaSig-HashSig 340 // Remove the in prog HTLC for checking signatures, 341 // add it back later to send gapsigrev 342 qc.State.InProgHTLC = nil 343 qc.State.CollidingHashDelta = true 344 345 var kg portxo.KeyGen 346 kg.Depth = 5 347 kg.Step[0] = 44 | 1<<31 348 kg.Step[1] = qc.Coin() | 1<<31 349 kg.Step[2] = UseHTLCBase 350 kg.Step[3] = qc.State.HTLCIdx + 2 | 1<<31 351 kg.Step[4] = qc.Idx() | 1<<31 352 353 qc.State.MyNextHTLCBase = qc.State.MyN2HTLCBase 354 qc.State.MyN2HTLCBase, err = nd.GetUsePub(kg, 355 UseHTLCBase) 356 } else if len(clearingIdxs) > 0 { 357 // Collision between DeltaSig-PreimageSig 358 // Remove the clearing state for signature verification and 359 // add back afterwards. 360 for _, idx := range clearingIdxs { 361 qh := &qc.State.HTLCs[idx] 362 qh.Clearing = false 363 } 364 qc.State.CollidingPreimageDelta = true 365 } else { 366 // Collision between DeltaSig-DeltaSig 367 368 // incoming delta saved as collision value, 369 // existing (negative) delta value retained. 370 qc.State.Collision = int32(incomingDelta) 371 logging.Infof("delta sig COLLISION (%d)\n", qc.State.Collision) 372 } 373 } 374 // detect if channel is already locked, and lock if not 375 // nd.PushClearMutex.Lock() 376 // if nd.PushClear[qc.Idx()] == nil { 377 // nd.PushClear[qc.Idx()] = make(chan bool, 1) 378 // } else { 379 // this means there was a collision 380 // reload from disk; collision may have happened after disk read 381 // err := nd.ReloadQchan(qc) 382 // if err != nil { 383 // return fmt.Errorf("DeltaSigHandler err %s", err.Error()) 384 // } 385 386 // } 387 388 if qc.State.Delta > 0 { 389 logging.Infof( 390 "DeltaSigHandler err: chan %d delta %d, expect rev, send empty rev", 391 qc.Idx(), qc.State.Delta) 392 393 return nd.SendREV(qc) 394 } 395 396 // If we collide with an HTLC operation, we can use the incoming Delta also. 397 if !collision || qc.State.InProgHTLC != nil { 398 // no collision, incoming (positive) delta saved. 399 qc.State.Delta = int32(incomingDelta) 400 } 401 402 // they have to actually send you money 403 if incomingDelta < 1 { 404 nd.FailChannel(qc) 405 return fmt.Errorf("DeltaSigHandler err: delta %d", incomingDelta) 406 } 407 408 myAmt, theirAmt := qc.GetChannelBalances() 409 theirAmt -= int64(incomingDelta) + qc.State.Fee 410 myAmt += int64(incomingDelta) - qc.State.Fee 411 412 // check if this push is takes them below minimum output size 413 if theirAmt < consts.MinOutput { 414 nd.FailChannel(qc) 415 return fmt.Errorf( 416 "pushing %s reduces them too low; counterparty bal %s fee %s consts.MinOutput %s", 417 lnutil.SatoshiColor(int64(incomingDelta)), 418 lnutil.SatoshiColor(theirAmt), 419 lnutil.SatoshiColor(qc.State.Fee), 420 lnutil.SatoshiColor(consts.MinOutput)) 421 } 422 423 // check if this push would lower my balance below minBal 424 if myAmt < consts.MinOutput { 425 nd.FailChannel(qc) 426 return fmt.Errorf("want to push %s but %s available after %s fee and %s consts.MinOutput", 427 lnutil.SatoshiColor(int64(incomingDelta)), 428 lnutil.SatoshiColor(myAmt), 429 lnutil.SatoshiColor(qc.State.Fee), 430 lnutil.SatoshiColor(consts.MinOutput)) 431 } 432 433 // update to the next state to verify 434 qc.LastUpdate = uint64(time.Now().UnixNano() / 1000) 435 qc.State.StateIdx++ 436 // regardless of collision, raise amt 437 qc.State.MyAmt += int64(incomingDelta) 438 439 logging.Infof("Got message %x", msg.Data) 440 qc.State.Data = msg.Data 441 442 // verify sig for the next state. only save if this works 443 stashElk := qc.State.ElkPoint 444 qc.State.ElkPoint = qc.State.NextElkPoint 445 // TODO: There are more signatures required 446 err = qc.VerifySigs(msg.Signature, msg.HTLCSigs) 447 if err != nil { 448 nd.FailChannel(qc) 449 return fmt.Errorf("DeltaSigHandler err %s", err.Error()) 450 } 451 qc.State.ElkPoint = stashElk 452 453 // After verification of signatures, add back the clearing state in case 454 // of PreimageSig-DeltaSig collisions 455 for _, idx := range clearingIdxs { 456 qh := &qc.State.HTLCs[idx] 457 qh.Clearing = true 458 } 459 460 qc.State.InProgHTLC = inProgHTLC 461 // (seems odd, but everything so far we still do in case of collision, so 462 // only check here. If it's a collision, set, save, send gapSigRev 463 464 // save channel with new state, new sig, and positive delta set 465 // and maybe collision; still haven't checked 466 err = nd.SaveQchanState(qc) 467 if err != nil { 468 nd.FailChannel(qc) 469 return fmt.Errorf("DeltaSigHandler SaveQchanState err %s", err.Error()) 470 } 471 472 if qc.State.Collision != 0 || qc.State.CollidingHashDelta || qc.State.CollidingPreimageDelta { 473 err = nd.SendGapSigRev(qc) 474 if err != nil { 475 nd.FailChannel(qc) 476 return fmt.Errorf("DeltaSigHandler SendGapSigRev err %s", err.Error()) 477 } 478 } else { // saved to db, now proceed to create & sign their tx 479 err = nd.SendSigRev(qc) 480 if err != nil { 481 nd.FailChannel(qc) 482 return fmt.Errorf("DeltaSigHandler SendSigRev err %s", err.Error()) 483 } 484 } 485 return nil 486 } 487 488 // SendGapSigRev is different; it signs for state+1 and revokes state-1 489 func (nd *LitNode) SendGapSigRev(q *Qchan) error { 490 // state should already be set to the "gap" state; generate signature for n+1 491 // the signature generation is similar to normal sigrev signing 492 // in these "send_whatever" methods we don't modify and save to disk 493 494 // state has been incremented in DeltaSigHandler so n is the gap state 495 // revoke n-1 496 elk, err := q.ElkSnd.AtIndex(q.State.StateIdx - 1) 497 if err != nil { 498 return err 499 } 500 501 // send elkpoint for n+2 502 n2ElkPoint, err := q.N2ElkPointForThem() 503 if err != nil { 504 return err 505 } 506 507 // go up to n+2 elkpoint for the signing 508 q.State.ElkPoint = q.State.N2ElkPoint 509 // state is already incremented from DeltaSigHandler, increment *again* for n+1 510 // (note that we've moved n here.) 511 q.State.StateIdx++ 512 // amt is delta (negative) plus current amt (collision already added in) 513 q.State.MyAmt += int64(q.State.Delta) 514 515 if q.State.InProgHTLC != nil { 516 if !q.State.InProgHTLC.Incoming { 517 q.State.MyAmt -= q.State.InProgHTLC.Amt 518 } 519 } 520 521 if q.State.CollidingHTLC != nil { 522 if !q.State.CollidingHTLC.Incoming { 523 q.State.MyAmt -= q.State.CollidingHTLC.Amt 524 } 525 } 526 527 for _, h := range q.State.HTLCs { 528 if h.Clearing && !h.Cleared && (h.Incoming != (h.R == [16]byte{})) { 529 q.State.MyAmt += h.Amt 530 } 531 } 532 533 // sign state n+1 534 535 // TODO: send the sigs 536 sig, HTLCSigs, err := nd.SignState(q) 537 if err != nil { 538 return err 539 } 540 541 // send 542 // GapSigRev is op (36), sig (64), ElkHash (32), NextElkPoint (33) 543 // total length 165 544 545 outMsg := lnutil.NewGapSigRev(q.KeyGen.Step[3]&0x7fffffff, q.Op, sig, *elk, n2ElkPoint, HTLCSigs, q.State.MyN2HTLCBase) 546 547 logging.Infof("Sending GapSigRev: %v", outMsg) 548 549 nd.tmpSendLitMsg(outMsg) 550 551 return nil 552 } 553 554 // SendSigRev sends a SigRev message based on channel info 555 func (nd *LitNode) SendSigRev(q *Qchan) error { 556 557 // revoke n-1 558 elk, err := q.ElkSnd.AtIndex(q.State.StateIdx - 1) 559 if err != nil { 560 return err 561 } 562 563 // state number and balance has already been updated if the incoming sig worked. 564 // go to next elkpoint for signing 565 // note that we have to keep the old elkpoint on disk for when the rev comes in 566 q.State.ElkPoint = q.State.NextElkPoint 567 // q.State.NextElkPoint = q.State.N2ElkPoint // not needed 568 // n2elk invalid here 569 570 // TODO: send the sigs 571 sig, HTLCSigs, err := nd.SignState(q) 572 if err != nil { 573 return err 574 } 575 576 // send commitment elkrem point for next round of messages 577 n2ElkPoint, err := q.N2ElkPointForThem() 578 if err != nil { 579 return err 580 } 581 582 outMsg := lnutil.NewSigRev(q.KeyGen.Step[3]&0x7fffffff, q.Op, sig, *elk, n2ElkPoint, HTLCSigs, q.State.MyN2HTLCBase) 583 584 logging.Infof("Sending SigRev: %v", outMsg) 585 586 nd.tmpSendLitMsg(outMsg) 587 return nil 588 } 589 590 // GapSigRevHandler takes in a GapSigRev, responds with a Rev, and 591 // leaves the channel in a state expecting a Rev. 592 func (nd *LitNode) GapSigRevHandler(msg lnutil.GapSigRevMsg, q *Qchan) error { 593 logging.Infof("Got GapSigRev: %v", msg) 594 595 // load qchan & state from DB 596 err := nd.ReloadQchanState(q) 597 if err != nil { 598 nd.FailChannel(q) 599 return fmt.Errorf("GapSigRevHandler err %s", err.Error()) 600 } 601 602 // check if we're supposed to get a GapSigRev now. Collision should be set 603 if q.State.Collision == 0 && q.State.CollidingHTLC == nil && !q.State.CollidingHashPreimage && !q.State.CollidingHashDelta && !q.State.CollidingPreimageDelta && !q.State.CollidingPreimages { 604 nd.FailChannel(q) 605 return fmt.Errorf( 606 "chan %d got GapSigRev but collision = 0, collidingHTLC = nil, q.State.CollidingHashPreimage = %t, q.State.CollidingHashDelta = %t, qc.State.CollidingPreimages = %t, qc.State.CollidingPreimageDelta = %t, delta = %d", 607 q.Idx(), q.State.CollidingHashPreimage, q.State.CollidingHashDelta, q.State.CollidingPreimages, q.State.CollidingPreimageDelta, q.State.Delta) 608 } 609 610 // stash for justice tx 611 prevAmt := q.State.MyAmt - int64(q.State.Collision) // myAmt before collision 612 613 q.State.MyAmt += int64(q.State.Delta) // delta should be negative 614 q.State.Delta = q.State.Collision // now delta is positive 615 q.State.Collision = 0 616 617 if q.State.InProgHTLC != nil { 618 if !q.State.InProgHTLC.Incoming { 619 q.State.MyAmt -= q.State.InProgHTLC.Amt 620 } 621 } 622 623 if q.State.CollidingHTLC != nil { 624 if !q.State.CollidingHTLC.Incoming { 625 q.State.MyAmt -= q.State.CollidingHTLC.Amt 626 } 627 } 628 629 for _, h := range q.State.HTLCs { 630 if h.Clearing && !h.Cleared && (h.Incoming != (h.R == [16]byte{})) { 631 q.State.MyAmt += h.Amt 632 } 633 } 634 635 // verify elkrem and save it in ram 636 err = q.AdvanceElkrem(&msg.Elk, msg.N2ElkPoint) 637 if err != nil { 638 nd.FailChannel(q) 639 return fmt.Errorf("GapSigRevHandler err %s", err.Error()) 640 // ! non-recoverable error, need to close the channel here. 641 } 642 643 // go up to n+2 elkpoint for the sig verification 644 stashElkPoint := q.State.ElkPoint 645 q.State.ElkPoint = q.State.NextElkPoint 646 647 // state is already incremented from DeltaSigHandler, increment again for n+2 648 // (note that we've moved n here.) 649 q.State.StateIdx++ 650 q.LastUpdate = uint64(time.Now().UnixNano() / 1000) 651 652 // verify the sig 653 654 // TODO: More sigs here that before 655 err = q.VerifySigs(msg.Signature, msg.HTLCSigs) 656 if err != nil { 657 nd.FailChannel(q) 658 return fmt.Errorf("GapSigRevHandler err %s", err.Error()) 659 } 660 // go back to sequential elkpoints 661 q.State.ElkPoint = stashElkPoint 662 663 if !bytes.Equal(msg.N2HTLCBase[:], q.State.N2HTLCBase[:]) { 664 q.State.NextHTLCBase = q.State.N2HTLCBase 665 q.State.N2HTLCBase = msg.N2HTLCBase 666 } 667 668 // If we were colliding, advance HTLCBase here. 669 if q.State.CollidingHTLC != nil { 670 var kg portxo.KeyGen 671 kg.Depth = 5 672 kg.Step[0] = 44 | 1<<31 673 kg.Step[1] = q.Coin() | 1<<31 674 kg.Step[2] = UseHTLCBase 675 kg.Step[3] = q.State.HTLCIdx + 3 | 1<<31 676 kg.Step[4] = q.Idx() | 1<<31 677 678 q.State.MyNextHTLCBase = q.State.MyN2HTLCBase 679 q.State.MyN2HTLCBase, err = nd.GetUsePub(kg, UseHTLCBase) 680 if err != nil { 681 nd.FailChannel(q) 682 return err 683 } 684 } 685 686 err = nd.SaveQchanState(q) 687 if err != nil { 688 nd.FailChannel(q) 689 return fmt.Errorf("GapSigRevHandler err %s", err.Error()) 690 } 691 err = nd.SendREV(q) 692 if err != nil { 693 nd.FailChannel(q) 694 return fmt.Errorf("GapSigRevHandler err %s", err.Error()) 695 } 696 697 // for justice, have to create signature for n-2. Remember the n-2 amount 698 699 q.State.StateIdx -= 2 700 q.State.MyAmt = prevAmt 701 702 err = nd.BuildJusticeSig(q) 703 if err != nil { 704 logging.Infof("GapSigRevHandler BuildJusticeSig err %s", err.Error()) 705 } 706 707 return nil 708 } 709 710 // SIGREVHandler takes in a SIGREV and responds with a REV (if everything goes OK) 711 // Leaves the channel in a clear / rest state. 712 func (nd *LitNode) SigRevHandler(msg lnutil.SigRevMsg, qc *Qchan) error { 713 logging.Infof("Got SigRev: %v", msg) 714 715 // load qchan & state from DB 716 err := nd.ReloadQchanState(qc) 717 if err != nil { 718 nd.FailChannel(qc) 719 return fmt.Errorf("SIGREVHandler err %s", err.Error()) 720 } 721 722 // check if we're supposed to get a SigRev now. Delta should be negative 723 if qc.State.Delta > 0 { 724 nd.FailChannel(qc) 725 return fmt.Errorf("SIGREVHandler err: chan %d got SigRev, expect Rev. delta %d", 726 qc.Idx(), qc.State.Delta) 727 } 728 729 var clearing bool 730 for _, h := range qc.State.HTLCs { 731 if h.Clearing { 732 clearing = true 733 break 734 } 735 } 736 737 if qc.State.Delta == 0 && qc.State.InProgHTLC == nil && !clearing { 738 // re-send last rev; they probably didn't get it 739 err = nd.SendREV(qc) 740 if err != nil { 741 nd.FailChannel(qc) 742 } 743 return err 744 } 745 746 if qc.State.Collision != 0 || qc.State.CollidingHTLC != nil { 747 nd.FailChannel(qc) 748 return fmt.Errorf("chan %d got SigRev, expect GapSigRev delta %d col %d", 749 qc.Idx(), qc.State.Delta, qc.State.Collision) 750 } 751 752 // stash previous amount here for watchtower sig creation 753 prevAmt := qc.State.MyAmt 754 755 qc.State.StateIdx++ 756 qc.State.MyAmt += int64(qc.State.Delta) 757 qc.State.Delta = 0 758 759 if qc.State.InProgHTLC != nil { 760 if !qc.State.InProgHTLC.Incoming { 761 qc.State.MyAmt -= qc.State.InProgHTLC.Amt 762 } 763 } 764 765 if qc.State.CollidingHTLC != nil { 766 if !qc.State.CollidingHTLC.Incoming { 767 qc.State.MyAmt -= qc.State.CollidingHTLC.Amt 768 } 769 } 770 771 for _, h := range qc.State.HTLCs { 772 if h.Clearing && !h.Cleared { 773 /* 774 Incoming: 775 Timeout: 776 They get money 777 Success: 778 We get money 779 !Incoming: 780 Timeout: 781 We get money 782 Success: 783 They get money 784 */ 785 786 if (h.Incoming && h.R != [16]byte{}) || (!h.Incoming && h.R == [16]byte{}) { 787 qc.State.MyAmt += h.Amt 788 } 789 } 790 } 791 792 // first verify sig. 793 // (if elkrem ingest fails later, at least we close out with a bit more money) 794 795 // TODO: more sigs here than before 796 curElk := qc.State.ElkPoint 797 qc.State.ElkPoint = qc.State.NextElkPoint 798 err = qc.VerifySigs(msg.Signature, msg.HTLCSigs) 799 if err != nil { 800 nd.FailChannel(qc) 801 return fmt.Errorf("SIGREVHandler err %s", err.Error()) 802 } 803 qc.State.ElkPoint = curElk 804 805 // verify elkrem and save it in ram 806 err = qc.AdvanceElkrem(&msg.Elk, msg.N2ElkPoint) 807 if err != nil { 808 nd.FailChannel(qc) 809 return fmt.Errorf("SIGREVHandler err %s", err.Error()) 810 // ! non-recoverable error, need to close the channel here. 811 } 812 // if the elkrem failed but sig didn't... we should update the DB to reflect 813 // that and try to close with the incremented amount, why not. 814 // TODO Implement that later though. 815 816 if qc.State.InProgHTLC != nil || qc.State.CollidingHashDelta { 817 var kg portxo.KeyGen 818 kg.Depth = 5 819 kg.Step[0] = 44 | 1<<31 820 kg.Step[1] = qc.Coin() | 1<<31 821 kg.Step[2] = UseHTLCBase 822 kg.Step[3] = qc.State.HTLCIdx + 2 | 1<<31 823 kg.Step[4] = qc.Idx() | 1<<31 824 825 qc.State.MyNextHTLCBase = qc.State.MyN2HTLCBase 826 qc.State.MyN2HTLCBase, err = nd.GetUsePub(kg, 827 UseHTLCBase) 828 829 if err != nil { 830 nd.FailChannel(qc) 831 return err 832 } 833 } 834 835 if qc.State.InProgHTLC != nil { 836 qc.State.HTLCs = append(qc.State.HTLCs, *qc.State.InProgHTLC) 837 qc.State.InProgHTLC = nil 838 qc.State.NextHTLCBase = qc.State.N2HTLCBase 839 qc.State.N2HTLCBase = msg.N2HTLCBase 840 841 qc.State.HTLCIdx++ 842 } 843 844 for idx, h := range qc.State.HTLCs { 845 if h.Clearing && !h.Cleared { 846 qc.State.HTLCs[idx].Cleared = true 847 } 848 } 849 850 // all verified; Save finished state to DB, puller is pretty much done. 851 err = nd.SaveQchanState(qc) 852 if err != nil { 853 nd.FailChannel(qc) 854 return fmt.Errorf("SIGREVHandler err %s", err.Error()) 855 } 856 857 logging.Infof("SIGREV OK, state %d, will send REV\n", qc.State.StateIdx) 858 err = nd.SendREV(qc) 859 if err != nil { 860 nd.FailChannel(qc) 861 return fmt.Errorf("SIGREVHandler err %s", err.Error()) 862 } 863 864 /* 865 Re-enable this if you want to print out the break TX for old states. 866 You can use this to debug justice. Don't enable in production since these 867 things can screw someone up if someone else maliciously grabs their log file 868 869 err = nd.PrintBreakTxForDebugging(qc) 870 if err != nil { 871 return fmt.Errorf("SIGREVHandler err %s", err.Error()) 872 } 873 */ 874 875 // now that we've saved & sent everything, before ending the function, we 876 // go BACK to create a txid/sig pair for watchtower. This feels like a kindof 877 // weird way to do it. Maybe there's a better way. 878 879 // get the peer's identity pubkey 880 peerIdx := qc.Peer() 881 peer := nd.PeerMan.GetPeerByIdx(int32(peerIdx)) 882 883 sigrevEvent := ChannelStateUpdateEvent{ 884 ChanIdx: qc.Idx(), 885 State: qc.State, 886 TheirPub: peer.GetPubkey(), 887 CoinType: qc.Coin(), 888 } 889 890 // send different action depending on whether or not a push or pull was received 891 if qc.State.Delta < 0 { 892 sigrevEvent.Action = "push" 893 } else if qc.State.Delta > 0 { 894 sigrevEvent.Action = "pull" 895 } else { 896 // sigrev is just so we don't have a "" action 897 sigrevEvent.Action = "sigrev" 898 } 899 900 if succeed, err := nd.Events.Publish(sigrevEvent); err != nil { 901 logging.Errorf("SigrevHandler publish err %s", err) 902 return nil 903 } else if !succeed { 904 logging.Errorf("SigrevHandler publish did not succeed") 905 return nil 906 } 907 908 qc.State.StateIdx-- 909 qc.State.MyAmt = prevAmt 910 911 err = nd.BuildJusticeSig(qc) 912 if err != nil { 913 logging.Infof("SigRevHandler BuildJusticeSig err %s", err.Error()) 914 } 915 916 // done updating channel, no new messages expected. Set clear to send 917 qc.ClearToSend <- true 918 919 return nil 920 } 921 922 // SendREV sends a REV message based on channel info 923 func (nd *LitNode) SendREV(q *Qchan) error { 924 // revoke previous already built state 925 elk, err := q.ElkSnd.AtIndex(q.State.StateIdx - 1) 926 if err != nil { 927 return err 928 } 929 // send commitment elkrem point for next round of messages 930 n2ElkPoint, err := q.N2ElkPointForThem() 931 if err != nil { 932 return err 933 } 934 935 outMsg := lnutil.NewRevMsg(q.Peer(), q.Op, *elk, n2ElkPoint, q.State.MyN2HTLCBase) 936 937 logging.Infof("Sending Rev: %v", outMsg) 938 939 nd.tmpSendLitMsg(outMsg) 940 941 return err 942 } 943 944 // REVHandler takes in a REV and clears the state's prev HAKD. This is the 945 // final message in the state update process and there is no response. 946 // Leaves the channel in a clear / rest state. 947 func (nd *LitNode) RevHandler(msg lnutil.RevMsg, qc *Qchan) error { 948 logging.Infof("Got Rev: %v", msg) 949 950 // load qchan & state from DB 951 err := nd.ReloadQchanState(qc) 952 if err != nil { 953 nd.FailChannel(qc) 954 return fmt.Errorf("REVHandler err %s", err.Error()) 955 } 956 957 var clearing bool 958 for _, h := range qc.State.HTLCs { 959 if h.Clearing { 960 clearing = true 961 break 962 } 963 } 964 965 // check if there's nothing for them to revoke 966 if qc.State.Delta == 0 && qc.State.InProgHTLC == nil && !clearing { 967 return fmt.Errorf("got REV, expected deltaSig, ignoring.") 968 } 969 // maybe this is an unexpected rev, asking us for a rev repeat 970 if qc.State.Delta < 0 { 971 logging.Infof("got Rev, expected SigRev. Re-sending last REV.\n") 972 return nd.SendREV(qc) 973 } 974 975 // verify elkrem 976 err = qc.AdvanceElkrem(&msg.Elk, msg.N2ElkPoint) 977 if err != nil { 978 nd.FailChannel(qc) 979 logging.Errorf(" ! non-recoverable error, need to close the channel here.\n") 980 return fmt.Errorf("REVHandler err %s", err.Error()) 981 } 982 prevAmt := qc.State.MyAmt - int64(qc.State.Delta) 983 qc.State.Delta = 0 984 qc.LastUpdate = uint64(time.Now().UnixNano() / 1000) 985 986 if !bytes.Equal(msg.N2HTLCBase[:], qc.State.N2HTLCBase[:]) { 987 qc.State.NextHTLCBase = qc.State.N2HTLCBase 988 qc.State.N2HTLCBase = msg.N2HTLCBase 989 } 990 // Clear collision state for HashSig-DeltaSig 991 qc.State.CollidingHashDelta = false 992 // Clear collision state for HashSig-PreimageSig 993 qc.State.CollidingHashPreimage = false 994 qc.State.CollidingPreimages = false 995 qc.State.CollidingPreimageDelta = false 996 997 if qc.State.InProgHTLC != nil { 998 qc.State.HTLCs = append(qc.State.HTLCs, *qc.State.InProgHTLC) 999 qc.State.InProgHTLC = nil 1000 qc.State.HTLCIdx++ 1001 } 1002 1003 if qc.State.CollidingHTLC != nil { 1004 qc.State.HTLCs = append(qc.State.HTLCs, *qc.State.CollidingHTLC) 1005 qc.State.CollidingHTLC = nil 1006 qc.State.HTLCIdx++ 1007 } 1008 1009 for idx, h := range qc.State.HTLCs { 1010 if h.Clearing && !h.Cleared { 1011 qc.State.HTLCs[idx].Cleared = true 1012 1013 nd.MultihopMutex.Lock() 1014 defer nd.MultihopMutex.Unlock() 1015 for i, mu := range nd.InProgMultihop { 1016 if bytes.Equal(mu.HHash[:], h.RHash[:]) && !mu.Succeeded { 1017 nd.InProgMultihop[i].Succeeded = true 1018 nd.InProgMultihop[i].PreImage = h.R 1019 err = nd.SaveMultihopPayment(nd.InProgMultihop[i]) 1020 if err != nil { 1021 return err 1022 } 1023 } 1024 } 1025 } 1026 } 1027 1028 // save to DB (new elkrem & point, delta zeroed) 1029 err = nd.SaveQchanState(qc) 1030 if err != nil { 1031 nd.FailChannel(qc) 1032 return fmt.Errorf("REVHandler err %s", err.Error()) 1033 } 1034 1035 /* 1036 Re-enable this if you want to print out the break TX for old states. 1037 You can use this to debug justice. Don't enable in production since these 1038 things can screw someone up if someone else maliciously grabs their log file 1039 1040 err = nd.PrintBreakTxForDebugging(qc) 1041 if err != nil { 1042 return fmt.Errorf("SIGREVHandler err %s", err.Error()) 1043 } 1044 */ 1045 1046 // after saving cleared updated state, go back to previous state and build 1047 // the justice signature 1048 1049 qc.State.StateIdx-- // back one state 1050 qc.State.MyAmt = prevAmt // use stashed previous state amount 1051 err = nd.BuildJusticeSig(qc) 1052 if err != nil { 1053 logging.Errorf("RevHandler BuildJusticeSig err %s", err.Error()) 1054 } 1055 1056 // got rev, assert clear to send 1057 qc.ClearToSend <- true 1058 1059 logging.Infof("REV OK, state %d all clear.\n", qc.State.StateIdx) 1060 return nil 1061 } 1062 1063 // FailChannel sets the fail flag on the channel and attempts to save it 1064 func (nd *LitNode) FailChannel(q *Qchan) { 1065 nd.ReloadQchanState(q) 1066 q.State.Failed = true 1067 nd.SaveQchanState(q) 1068 }