@@ -29,9 +29,9 @@ import fr.acinq.eclair.blockchain._
29
29
import fr .acinq .eclair .blockchain .bitcoind .ZmqWatcher
30
30
import fr .acinq .eclair .blockchain .bitcoind .ZmqWatcher ._
31
31
import fr .acinq .eclair .blockchain .bitcoind .rpc .BitcoinCoreClient
32
+ import fr .acinq .eclair .channel .Commitments .PostRevocationAction
32
33
import fr .acinq .eclair .channel .Helpers .Syncing .SyncResult
33
34
import fr .acinq .eclair .channel .Helpers .{Closing , Syncing , getRelayFees , scidForChannelUpdate }
34
- import fr .acinq .eclair .channel .Commitments .PostRevocationAction
35
35
import fr .acinq .eclair .channel .Monitoring .Metrics .ProcessMessage
36
36
import fr .acinq .eclair .channel .Monitoring .{Metrics , Tags }
37
37
import fr .acinq .eclair .channel ._
@@ -1072,30 +1072,30 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
1072
1072
case Event (BITCOIN_FUNDING_TIMEOUT , d : DATA_CLOSING ) => handleFundingTimeout(d)
1073
1073
1074
1074
case Event (w : WatchFundingConfirmedTriggered , d : DATA_CLOSING ) =>
1075
- val commitments1 = d.commitments.updateLocalFundingStatus(w.tx.txid, LocalFundingStatus . ConfirmedFundingTx (w.tx))
1076
- if (d.commitments.latest.fundingTxId == w.tx.txid) {
1077
- // The best funding tx candidate has been confirmed, alternative commitments have been pruned
1078
- stay() using d.copy( commitments = commitments1) storing()
1079
- } else {
1080
- // This is a corner case where:
1081
- // - we are using dual funding
1082
- // - *and* the funding tx was RBF-ed
1083
- // - *and* we went to CLOSING before any funding tx got confirmed (probably due to a local or remote error)
1084
- // - *and* an older version of the funding tx confirmed and reached min depth (it won't be re-orged out )
1085
- //
1086
- // This means that:
1087
- // - the whole current commitment tree has been double-spent and can safely be forgotten
1088
- // - from now on, we only need to keep track of the commitment associated to the funding tx that got confirmed
1089
- //
1090
- // Force-closing is our only option here, if we are in this state the channel was closing and it is too late
1091
- // to negotiate a mutual close.
1092
- log.info( " channelId={} was confirmed at blockHeight={} txIndex={} with a previous funding txid={} " , d.channelId, w.blockHeight, w.txIndex, w.tx.txid)
1093
- watchFundingSpent(commitments1.latest.commitment )
1094
- context.system.eventStream.publish( TransactionConfirmed (d.channelId, remoteNodeId, w.tx))
1095
- val commitTx = commitments1.latest.fullySignedLocalCommitTx(keyManager).tx
1096
- val localCommitPublished = Closing . LocalClose .claimCommitTxOutputs(keyManager, commitments1.latest, commitTx, nodeParams.currentBlockHeight, nodeParams.onChainFeeConf, d.finalScriptPubKey )
1097
- val d1 = DATA_CLOSING (commitments1, d.waitingSince, d.finalScriptPubKey, mutualCloseProposed = Nil , localCommitPublished = Some (localCommitPublished))
1098
- stay() using d1 storing() calling doPublish(localCommitPublished, commitments1.latest )
1075
+ acceptFundingTxConfirmed(w, d) match {
1076
+ case Right ((commitments1, _)) =>
1077
+ if (d. commitments.latest.fundingTxId == w.tx.txid) {
1078
+ // The best funding tx candidate has been confirmed, alternative commitments have been pruned
1079
+ stay() using d.copy(commitments = commitments1) storing()
1080
+ } else {
1081
+ // This is a corner case where:
1082
+ // - we are using dual funding
1083
+ // - *and* the funding tx was RBF-ed
1084
+ // - *and* we went to CLOSING before any funding tx got confirmed (probably due to a local or remote error )
1085
+ // - *and* an older version of the funding tx confirmed and reached min depth (it won't be re-orged out)
1086
+ //
1087
+ // This means that:
1088
+ // - the whole current commitment tree has been double-spent and can safely be forgotten
1089
+ // - from now on, we only need to keep track of the commitment associated to the funding tx that got confirmed
1090
+ //
1091
+ // Force-closing is our only option here, if we are in this state the channel was closing and it is too late
1092
+ // to negotiate a mutual close.
1093
+ log.info( " channelId={} was confirmed at blockHeight={} txIndex={} with a previous funding txid={} " , d.channelId, w.blockHeight, w.txIndex, w.tx.txid )
1094
+ val commitment = commitments1.latest
1095
+ val d1 = d.copy(commitments = commitments1)
1096
+ spendLocalCurrent(d1 )
1097
+ }
1098
+ case Left (_) => stay( )
1099
1099
}
1100
1100
1101
1101
case Event (WatchFundingSpentTriggered (tx), d : DATA_CLOSING ) =>
@@ -1563,52 +1563,58 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
1563
1563
case Event (TickChannelOpenTimeout , _) => stay()
1564
1564
1565
1565
case Event (w : WatchPublishedTriggered , d : PersistentChannelData ) =>
1566
- log.info(s " zero-conf funding txid= ${w.tx.txid} has been published " )
1567
1566
val fundingStatus = LocalFundingStatus .ZeroconfPublishedFundingTx (w.tx)
1568
- val commitments1 = d.commitments.updateLocalFundingStatus(w.tx.txid, fundingStatus)
1569
- watchFundingConfirmed(w.tx.txid, Some (nodeParams.channelConf.minDepthBlocks))
1570
- val d1 = d match {
1571
- // NB: we discard remote's stashed channel_ready, they will send it back at reconnection
1572
- case d : DATA_WAIT_FOR_FUNDING_CONFIRMED =>
1573
- val realScidStatus = RealScidStatus .Unknown
1574
- val shortIds = createShortIds(d.channelId, realScidStatus)
1575
- DATA_WAIT_FOR_CHANNEL_READY (commitments1, shortIds)
1576
- case d : DATA_WAIT_FOR_DUAL_FUNDING_CONFIRMED =>
1577
- val realScidStatus = RealScidStatus .Unknown
1578
- val shortIds = createShortIds(d.channelId, realScidStatus)
1579
- DATA_WAIT_FOR_DUAL_FUNDING_READY (commitments1, shortIds)
1580
- case d : DATA_WAIT_FOR_CHANNEL_READY => d.copy(commitments = commitments1)
1581
- case d : DATA_WAIT_FOR_DUAL_FUNDING_READY => d.copy(commitments = commitments1)
1582
- case d : DATA_NORMAL => d.copy(commitments = commitments1)
1583
- case d : DATA_SHUTDOWN => d.copy(commitments = commitments1)
1584
- case d : DATA_NEGOTIATING => d.copy(commitments = commitments1)
1585
- case d : DATA_WAIT_FOR_REMOTE_PUBLISH_FUTURE_COMMITMENT => d.copy(commitments = commitments1)
1586
- case d : DATA_CLOSING => d.copy(commitments = commitments1)
1587
- }
1588
- stay() using d1 storing()
1567
+ d.commitments.updateLocalFundingStatus(w.tx.txid, fundingStatus) match {
1568
+ case Right ((commitments1, _)) =>
1569
+ log.info(s " zero-conf funding txid= ${w.tx.txid} has been published " )
1570
+ watchFundingConfirmed(w.tx.txid, Some (nodeParams.channelConf.minDepthBlocks))
1571
+ val d1 = d match {
1572
+ // NB: we discard remote's stashed channel_ready, they will send it back at reconnection
1573
+ case d : DATA_WAIT_FOR_FUNDING_CONFIRMED =>
1574
+ val realScidStatus = RealScidStatus .Unknown
1575
+ val shortIds = createShortIds(d.channelId, realScidStatus)
1576
+ DATA_WAIT_FOR_CHANNEL_READY (commitments1, shortIds)
1577
+ case d : DATA_WAIT_FOR_DUAL_FUNDING_CONFIRMED =>
1578
+ val realScidStatus = RealScidStatus .Unknown
1579
+ val shortIds = createShortIds(d.channelId, realScidStatus)
1580
+ DATA_WAIT_FOR_DUAL_FUNDING_READY (commitments1, shortIds)
1581
+ case d : DATA_WAIT_FOR_CHANNEL_READY => d.copy(commitments = commitments1)
1582
+ case d : DATA_WAIT_FOR_DUAL_FUNDING_READY => d.copy(commitments = commitments1)
1583
+ case d : DATA_NORMAL => d.copy(commitments = commitments1)
1584
+ case d : DATA_SHUTDOWN => d.copy(commitments = commitments1)
1585
+ case d : DATA_NEGOTIATING => d.copy(commitments = commitments1)
1586
+ case d : DATA_WAIT_FOR_REMOTE_PUBLISH_FUTURE_COMMITMENT => d.copy(commitments = commitments1)
1587
+ case d : DATA_CLOSING => d.copy(commitments = commitments1)
1588
+ }
1589
+ stay() using d1 storing()
1590
+ case Left (_) => stay()
1591
+ }
1589
1592
1590
1593
case Event (w : WatchFundingConfirmedTriggered , d : PersistentChannelData ) =>
1591
- log.info(s " funding txid= ${w.tx.txid} has been confirmed " )
1592
- val commitments1 = acceptFundingTxConfirmed(w, d)
1593
- val d1 = d match {
1594
- // NB: we discard remote's stashed channel_ready, they will send it back at reconnection
1595
- case d : DATA_WAIT_FOR_FUNDING_CONFIRMED =>
1596
- val realScidStatus = RealScidStatus .Temporary (RealShortChannelId (w.blockHeight, w.txIndex, commitments1.latest.commitInput.outPoint.index.toInt))
1597
- val shortIds = createShortIds(d.channelId, realScidStatus)
1598
- DATA_WAIT_FOR_CHANNEL_READY (commitments1, shortIds)
1599
- case d : DATA_WAIT_FOR_DUAL_FUNDING_CONFIRMED =>
1600
- val realScidStatus = RealScidStatus .Temporary (RealShortChannelId (w.blockHeight, w.txIndex, commitments1.latest.commitInput.outPoint.index.toInt))
1601
- val shortIds = createShortIds(d.channelId, realScidStatus)
1602
- DATA_WAIT_FOR_DUAL_FUNDING_READY (commitments1, shortIds)
1603
- case d : DATA_WAIT_FOR_CHANNEL_READY => d.copy(commitments = commitments1)
1604
- case d : DATA_WAIT_FOR_DUAL_FUNDING_READY => d.copy(commitments = commitments1)
1605
- case d : DATA_NORMAL => d.copy(commitments = commitments1)
1606
- case d : DATA_SHUTDOWN => d.copy(commitments = commitments1)
1607
- case d : DATA_NEGOTIATING => d.copy(commitments = commitments1)
1608
- case d : DATA_WAIT_FOR_REMOTE_PUBLISH_FUTURE_COMMITMENT => d.copy(commitments = commitments1)
1609
- case d : DATA_CLOSING => d // there is a dedicated handler in CLOSING state
1610
- }
1611
- stay() using d1 storing()
1594
+ acceptFundingTxConfirmed(w, d) match {
1595
+ case Right ((commitments1, commitment)) =>
1596
+ log.info(s " funding txid= ${w.tx.txid} has been confirmed " )
1597
+ val d1 = d match {
1598
+ // NB: we discard remote's stashed channel_ready, they will send it back at reconnection
1599
+ case d : DATA_WAIT_FOR_FUNDING_CONFIRMED =>
1600
+ val realScidStatus = RealScidStatus .Temporary (RealShortChannelId (w.blockHeight, w.txIndex, commitment.commitInput.outPoint.index.toInt))
1601
+ val shortIds = createShortIds(d.channelId, realScidStatus)
1602
+ DATA_WAIT_FOR_CHANNEL_READY (commitments1, shortIds)
1603
+ case d : DATA_WAIT_FOR_DUAL_FUNDING_CONFIRMED =>
1604
+ val realScidStatus = RealScidStatus .Temporary (RealShortChannelId (w.blockHeight, w.txIndex, commitment.commitInput.outPoint.index.toInt))
1605
+ val shortIds = createShortIds(d.channelId, realScidStatus)
1606
+ DATA_WAIT_FOR_DUAL_FUNDING_READY (commitments1, shortIds)
1607
+ case d : DATA_WAIT_FOR_CHANNEL_READY => d.copy(commitments = commitments1)
1608
+ case d : DATA_WAIT_FOR_DUAL_FUNDING_READY => d.copy(commitments = commitments1)
1609
+ case d : DATA_NORMAL => d.copy(commitments = commitments1)
1610
+ case d : DATA_SHUTDOWN => d.copy(commitments = commitments1)
1611
+ case d : DATA_NEGOTIATING => d.copy(commitments = commitments1)
1612
+ case d : DATA_WAIT_FOR_REMOTE_PUBLISH_FUTURE_COMMITMENT => d.copy(commitments = commitments1)
1613
+ case d : DATA_CLOSING => d // there is a dedicated handler in CLOSING state
1614
+ }
1615
+ stay() using d1 storing()
1616
+ case Left (_) => stay()
1617
+ }
1612
1618
1613
1619
case Event (WatchFundingSpentTriggered (tx), d : DATA_NEGOTIATING ) if d.closingTxProposed.flatten.exists(_.unsignedTx.tx.txid == tx.txid) =>
1614
1620
// they can publish a closing tx with any sig we sent them, even if we are not done negotiating
0 commit comments