Skip to content

Commit

Permalink
Move reduce to DustExposure
Browse files Browse the repository at this point in the history
  • Loading branch information
t-bast committed Oct 7, 2021
1 parent de2b125 commit ca5acf3
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 68 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -387,12 +387,12 @@ object Commitments {

// If sending this htlc would overflow our dust exposure, we reject it.
val maxDustExposure = feeConf.feerateToleranceFor(commitments.remoteNodeId).dustTolerance.maxExposure
val localReduced = CommitmentSpec.reduceForDustExposure(commitments.localCommit.spec, commitments1.localChanges.all, commitments.remoteChanges.all)
val localReduced = DustExposure.reduceForDustExposure(commitments.localCommit.spec, commitments1.localChanges.all, commitments.remoteChanges.all)
val localDustExposureAfterAdd = DustExposure.computeExposure(localReduced, commitments.localParams.dustLimit, commitments.commitmentFormat)
if (localDustExposureAfterAdd > maxDustExposure) {
return Left(LocalDustHtlcExposureTooHigh(commitments.channelId, maxDustExposure, localDustExposureAfterAdd))
}
val remoteReduced = CommitmentSpec.reduceForDustExposure(remoteCommit1.spec, commitments.remoteChanges.all, commitments1.localChanges.all)
val remoteReduced = DustExposure.reduceForDustExposure(remoteCommit1.spec, commitments.remoteChanges.all, commitments1.localChanges.all)
val remoteDustExposureAfterAdd = DustExposure.computeExposure(remoteReduced, commitments.remoteParams.dustLimit, commitments.commitmentFormat)
if (remoteDustExposureAfterAdd > maxDustExposure) {
return Left(RemoteDustHtlcExposureTooHigh(commitments.channelId, maxDustExposure, remoteDustExposureAfterAdd))
Expand Down Expand Up @@ -558,12 +558,12 @@ object Commitments {
val maxDustExposure = feeConf.feerateToleranceFor(commitments.remoteNodeId).dustTolerance.maxExposure
// this is the commitment as it would be if our update_fee was immediately signed by both parties (it is only an
// estimate because there can be concurrent updates)
val localReduced = CommitmentSpec.reduceForDustExposure(commitments.localCommit.spec, commitments1.localChanges.all, commitments.remoteChanges.all)
val localReduced = DustExposure.reduceForDustExposure(commitments.localCommit.spec, commitments1.localChanges.all, commitments.remoteChanges.all)
val localDustExposureAfterFeeUpdate = DustExposure.computeExposure(localReduced, cmd.feeratePerKw, commitments.localParams.dustLimit, commitments.commitmentFormat)
if (localDustExposureAfterFeeUpdate > maxDustExposure) {
return Left(LocalDustHtlcExposureTooHigh(commitments.channelId, maxDustExposure, localDustExposureAfterFeeUpdate))
}
val remoteReduced = CommitmentSpec.reduceForDustExposure(commitments.remoteCommit.spec, commitments.remoteChanges.all, commitments1.localChanges.all)
val remoteReduced = DustExposure.reduceForDustExposure(commitments.remoteCommit.spec, commitments.remoteChanges.all, commitments1.localChanges.all)
val remoteDustExposureAfterFeeUpdate = DustExposure.computeExposure(remoteReduced, cmd.feeratePerKw, commitments.remoteParams.dustLimit, commitments.commitmentFormat)
if (remoteDustExposureAfterFeeUpdate > maxDustExposure) {
return Left(RemoteDustHtlcExposureTooHigh(commitments.channelId, maxDustExposure, remoteDustExposureAfterFeeUpdate))
Expand Down Expand Up @@ -606,14 +606,14 @@ object Commitments {
// if we would overflow our dust exposure with the new feerate, we reject this fee update
if (feeConf.feerateToleranceFor(commitments.remoteNodeId).dustTolerance.closeOnUpdateFeeOverflow) {
val maxDustExposure = feeConf.feerateToleranceFor(commitments.remoteNodeId).dustTolerance.maxExposure
val localReduced = CommitmentSpec.reduceForDustExposure(commitments.localCommit.spec, commitments.localChanges.all, commitments1.remoteChanges.all)
val localReduced = DustExposure.reduceForDustExposure(commitments.localCommit.spec, commitments.localChanges.all, commitments1.remoteChanges.all)
val localDustExposureAfterFeeUpdate = DustExposure.computeExposure(localReduced, fee.feeratePerKw, commitments.localParams.dustLimit, commitments.commitmentFormat)
if (localDustExposureAfterFeeUpdate > maxDustExposure) {
return Left(LocalDustHtlcExposureTooHigh(commitments.channelId, maxDustExposure, localDustExposureAfterFeeUpdate))
}
// this is the commitment as it would be if their update_fee was immediately signed by both parties (it is only an
// estimate because there can be concurrent updates)
val remoteReduced = CommitmentSpec.reduceForDustExposure(commitments.remoteCommit.spec, commitments1.remoteChanges.all, commitments.localChanges.all)
val remoteReduced = DustExposure.reduceForDustExposure(commitments.remoteCommit.spec, commitments1.remoteChanges.all, commitments.localChanges.all)
val remoteDustExposureAfterFeeUpdate = DustExposure.computeExposure(remoteReduced, fee.feeratePerKw, commitments.remoteParams.dustLimit, commitments.commitmentFormat)
if (remoteDustExposureAfterFeeUpdate > maxDustExposure) {
return Left(RemoteDustHtlcExposureTooHigh(commitments.channelId, maxDustExposure, remoteDustExposureAfterFeeUpdate))
Expand Down Expand Up @@ -782,9 +782,9 @@ object Commitments {
case OutgoingHtlc(add) if receivedHtlcs.contains(add) => false
case _ => true
})
val localReduced = CommitmentSpec.reduceForDustExposure(localSpecWithoutNewHtlcs, commitments.localChanges.all, commitments.remoteChanges.acked)
val localReduced = DustExposure.reduceForDustExposure(localSpecWithoutNewHtlcs, commitments.localChanges.all, commitments.remoteChanges.acked)
val localCommitDustExposure = DustExposure.computeExposure(localReduced, commitments.localParams.dustLimit, commitments.commitmentFormat)
val remoteReduced = CommitmentSpec.reduceForDustExposure(remoteSpecWithoutNewHtlcs, commitments.remoteChanges.acked, commitments.localChanges.all)
val remoteReduced = DustExposure.reduceForDustExposure(remoteSpecWithoutNewHtlcs, commitments.remoteChanges.acked, commitments.localChanges.all)
val remoteCommitDustExposure = DustExposure.computeExposure(remoteReduced, commitments.remoteParams.dustLimit, commitments.commitmentFormat)
// we sort incoming htlcs by decreasing amount: we want to prioritize higher amounts.
val sortedReceivedHtlcs = receivedHtlcs.sortBy(_.amountMsat).reverse
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import fr.acinq.eclair.MilliSatoshi
import fr.acinq.eclair.blockchain.fee.{FeeratePerByte, FeeratePerKw}
import fr.acinq.eclair.transactions.Transactions.CommitmentFormat
import fr.acinq.eclair.transactions._
import fr.acinq.eclair.wire.protocol.UpdateAddHtlc
import fr.acinq.eclair.wire.protocol._

/**
* Created by t-bast on 07/10/2021.
Expand Down Expand Up @@ -93,4 +93,63 @@ object DustExposure {
(acceptedHtlcs, rejectedHtlcs)
}

def reduceForDustExposure(localCommitSpec: CommitmentSpec, localChanges: List[UpdateMessage], remoteChanges: List[UpdateMessage]): CommitmentSpec = {
// NB: when computing dust exposure, we usually apply all pending updates (proposed, signed and acked), which means
// that we will sometimes apply fulfill/fail on htlcs that have already been removed: that's why we don't use the
// normal functions from CommitmentSpec that would throw when that happens.
def fulfillIncomingHtlc(spec: CommitmentSpec, htlcId: Long): CommitmentSpec = {
spec.findIncomingHtlcById(htlcId) match {
case Some(htlc) => spec.copy(toLocal = spec.toLocal + htlc.add.amountMsat, htlcs = spec.htlcs - htlc)
case None => spec
}
}

def fulfillOutgoingHtlc(spec: CommitmentSpec, htlcId: Long): CommitmentSpec = {
spec.findOutgoingHtlcById(htlcId) match {
case Some(htlc) => spec.copy(toRemote = spec.toRemote + htlc.add.amountMsat, htlcs = spec.htlcs - htlc)
case None => spec
}
}

def failIncomingHtlc(spec: CommitmentSpec, htlcId: Long): CommitmentSpec = {
spec.findIncomingHtlcById(htlcId) match {
case Some(htlc) => spec.copy(toRemote = spec.toRemote + htlc.add.amountMsat, htlcs = spec.htlcs - htlc)
case None => spec
}
}

def failOutgoingHtlc(spec: CommitmentSpec, htlcId: Long): CommitmentSpec = {
spec.findOutgoingHtlcById(htlcId) match {
case Some(htlc) => spec.copy(toLocal = spec.toLocal + htlc.add.amountMsat, htlcs = spec.htlcs - htlc)
case None => spec
}
}

val spec1 = localChanges.foldLeft(localCommitSpec) {
case (spec, u: UpdateAddHtlc) => CommitmentSpec.addHtlc(spec, OutgoingHtlc(u))
case (spec, _) => spec
}
val spec2 = remoteChanges.foldLeft(spec1) {
case (spec, u: UpdateAddHtlc) => CommitmentSpec.addHtlc(spec, IncomingHtlc(u))
case (spec, _) => spec
}
val spec3 = localChanges.foldLeft(spec2) {
case (spec, u: UpdateFulfillHtlc) => fulfillIncomingHtlc(spec, u.id)
case (spec, u: UpdateFailHtlc) => failIncomingHtlc(spec, u.id)
case (spec, u: UpdateFailMalformedHtlc) => failIncomingHtlc(spec, u.id)
case (spec, _) => spec
}
val spec4 = remoteChanges.foldLeft(spec3) {
case (spec, u: UpdateFulfillHtlc) => fulfillOutgoingHtlc(spec, u.id)
case (spec, u: UpdateFailHtlc) => failOutgoingHtlc(spec, u.id)
case (spec, u: UpdateFailMalformedHtlc) => failOutgoingHtlc(spec, u.id)
case (spec, _) => spec
}
val spec5 = (localChanges ++ remoteChanges).foldLeft(spec4) {
case (spec, u: UpdateFee) => spec.copy(commitTxFeerate = u.feeratePerKw)
case (spec, _) => spec
}
spec5
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -155,63 +155,4 @@ object CommitmentSpec {
spec5
}

def reduceForDustExposure(localCommitSpec: CommitmentSpec, localChanges: List[UpdateMessage], remoteChanges: List[UpdateMessage]): CommitmentSpec = {
// NB: when computing dust exposure, we usually apply all pending updates (proposed, signed and acked), which means
// that we will sometimes apply fulfill/fail on htlcs that have already been removed: that's why we don't use the
// normal function that would throw when that happens.
def safeFulfillIncomingHtlc(spec: CommitmentSpec, htlcId: Long): CommitmentSpec = {
spec.findIncomingHtlcById(htlcId) match {
case Some(htlc) => spec.copy(toLocal = spec.toLocal + htlc.add.amountMsat, htlcs = spec.htlcs - htlc)
case None => spec
}
}

def safeFulfillOutgoingHtlc(spec: CommitmentSpec, htlcId: Long): CommitmentSpec = {
spec.findOutgoingHtlcById(htlcId) match {
case Some(htlc) => spec.copy(toRemote = spec.toRemote + htlc.add.amountMsat, htlcs = spec.htlcs - htlc)
case None => spec
}
}

def safeFailIncomingHtlc(spec: CommitmentSpec, htlcId: Long): CommitmentSpec = {
spec.findIncomingHtlcById(htlcId) match {
case Some(htlc) => spec.copy(toRemote = spec.toRemote + htlc.add.amountMsat, htlcs = spec.htlcs - htlc)
case None => spec
}
}

def safeFailOutgoingHtlc(spec: CommitmentSpec, htlcId: Long): CommitmentSpec = {
spec.findOutgoingHtlcById(htlcId) match {
case Some(htlc) => spec.copy(toLocal = spec.toLocal + htlc.add.amountMsat, htlcs = spec.htlcs - htlc)
case None => spec
}
}

val spec1 = localChanges.foldLeft(localCommitSpec) {
case (spec, u: UpdateAddHtlc) => addHtlc(spec, OutgoingHtlc(u))
case (spec, _) => spec
}
val spec2 = remoteChanges.foldLeft(spec1) {
case (spec, u: UpdateAddHtlc) => addHtlc(spec, IncomingHtlc(u))
case (spec, _) => spec
}
val spec3 = localChanges.foldLeft(spec2) {
case (spec, u: UpdateFulfillHtlc) => safeFulfillIncomingHtlc(spec, u.id)
case (spec, u: UpdateFailHtlc) => safeFailIncomingHtlc(spec, u.id)
case (spec, u: UpdateFailMalformedHtlc) => safeFailIncomingHtlc(spec, u.id)
case (spec, _) => spec
}
val spec4 = remoteChanges.foldLeft(spec3) {
case (spec, u: UpdateFulfillHtlc) => safeFulfillOutgoingHtlc(spec, u.id)
case (spec, u: UpdateFailHtlc) => safeFailOutgoingHtlc(spec, u.id)
case (spec, u: UpdateFailMalformedHtlc) => safeFailOutgoingHtlc(spec, u.id)
case (spec, _) => spec
}
val spec5 = (localChanges ++ remoteChanges).foldLeft(spec4) {
case (spec, u: UpdateFee) => spec.copy(commitTxFeerate = u.feeratePerKw)
case (spec, _) => spec
}
spec5
}

}

0 comments on commit ca5acf3

Please sign in to comment.