mirror of
https://github.com/ACINQ/eclair.git
synced 2024-11-20 10:39:19 +01:00
added logs and slightly changed signature of claimRevokedRemoteCommitTxOutputs
This commit is contained in:
parent
a58befd1ed
commit
22789d9395
@ -839,7 +839,7 @@ class Channel(val them: ActorRef, val blockchain: ActorRef, paymentHandler: Acto
|
||||
log.warning(s"funding tx spent in txid=${tx.txid}")
|
||||
|
||||
Helpers.Closing.claimRevokedRemoteCommitTxOutputs(d.commitments, tx) match {
|
||||
case Success(claimTxs) =>
|
||||
case Some(claimTxs) =>
|
||||
log.warning(s"txid=${tx.txid} was a revoked commitment, publishing the punishment tx")
|
||||
them ! Error(0, "Funding tx has been spent".getBytes)
|
||||
|
||||
@ -861,9 +861,9 @@ class Channel(val them: ActorRef, val blockchain: ActorRef, paymentHandler: Acto
|
||||
case _ => DATA_CLOSING(d.commitments, revokedCommitPublished = remoteCommitPublished :: Nil)
|
||||
}
|
||||
goto(CLOSING) using nextData
|
||||
case Failure(t) =>
|
||||
case None =>
|
||||
// the published tx was neither their current commitment nor a revoked one
|
||||
log.error(t, s"couldn't identify txid=${tx.txid}")
|
||||
log.error(s"couldn't identify txid=${tx.txid}, something very bad is going on!!!")
|
||||
goto(ERR_INFORMATION_LEAK)
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,12 @@
|
||||
package fr.acinq.eclair.channel
|
||||
|
||||
import fr.acinq.bitcoin.Crypto.{Point, Scalar, sha256}
|
||||
import fr.acinq.bitcoin.{BinaryData, Crypto, Satoshi}
|
||||
import fr.acinq.bitcoin.{BinaryData, Crypto, Satoshi, Transaction}
|
||||
import fr.acinq.eclair.crypto.{Generators, ShaChain}
|
||||
import fr.acinq.eclair.transactions.Transactions._
|
||||
import fr.acinq.eclair.transactions._
|
||||
import fr.acinq.eclair.wire._
|
||||
import grizzled.slf4j.Logging
|
||||
|
||||
// @formatter:off
|
||||
case class LocalChanges(proposed: List[UpdateMessage], signed: List[UpdateMessage], acked: List[UpdateMessage]) {
|
||||
@ -43,7 +44,7 @@ case class Commitments(localParams: LocalParams, remoteParams: RemoteParams,
|
||||
def addRemoteProposal(proposal: UpdateMessage): Commitments = Commitments.addRemoteProposal(this, proposal)
|
||||
}
|
||||
|
||||
object Commitments {
|
||||
object Commitments extends Logging {
|
||||
/**
|
||||
* add a change to our proposed change list
|
||||
*
|
||||
@ -230,6 +231,8 @@ object Commitments {
|
||||
val theirChanges1 = remoteChanges.copy(proposed = Nil, acked = remoteChanges.acked ++ remoteChanges.proposed)
|
||||
val commitments1 = commitments.copy(localCommit = ourCommit1, localChanges = ourChanges1, remoteChanges = theirChanges1)
|
||||
|
||||
logger.debug(s"current commit: index=${ourCommit1.index} htlc_in=${ourCommit1.spec.htlcs.filter(_.direction == IN).size} htlc_out=${ourCommit1.spec.htlcs.filter(_.direction == OUT).size} tx=${Transaction.write(ourCommit1.publishableTxs.commitTx.tx)}")
|
||||
|
||||
(commitments1, revocation)
|
||||
}
|
||||
|
||||
|
@ -187,9 +187,15 @@ object Helpers {
|
||||
}
|
||||
|
||||
/**
|
||||
* In reaction to the counterparty publishing a revoked commitment tx, we punish them by
|
||||
* When an unexpected transaction spending the funding tx is detected:
|
||||
* 1) we find out if the published transaction is one of remote's revoked txs
|
||||
* 2) and then:
|
||||
* a) if it is a revoked tx we build a set of transactions that will punish them by stealing all their funds
|
||||
* b) otherwise there is nothing we can do
|
||||
*
|
||||
* @return a list of transactions (one per HTLC that we can claim) if the tx is a revoked commitment, [[None]] otherwise
|
||||
*/
|
||||
def claimRevokedRemoteCommitTxOutputs(commitments: Commitments, tx: Transaction): Try[Seq[TransactionWithInputInfo]] = Try {
|
||||
def claimRevokedRemoteCommitTxOutputs(commitments: Commitments, tx: Transaction): Option[Seq[TransactionWithInputInfo]] = {
|
||||
import commitments._
|
||||
require(tx.txIn.size == 1, "commitment tx should have 1 input")
|
||||
val obscuredTxNumber = Transactions.decodeTxNumber(tx.txIn(0).sequence, tx.lockTime)
|
||||
@ -197,28 +203,31 @@ object Helpers {
|
||||
val txnumber = Transactions.obscuredCommitTxNumber(obscuredTxNumber, remoteParams.paymentBasepoint, localParams.paymentKey.toPoint)
|
||||
require(txnumber <= 0xffffffffffffL, "txnumber must be lesser than 48 bits long")
|
||||
// now we know what commit number this tx is referring to, we can derive the commitment point from the shachain
|
||||
val remotePerCommitmentSecret = remotePerCommitmentSecrets.getHash(0xFFFFFFFFFFFFFFFFL - txnumber).map(d => Scalar(d :+ 1.toByte)).getOrElse(throw new RuntimeException(s"cannot get commitment secret for txnumber=$txnumber"))
|
||||
val remotePerCommitmentPoint = remotePerCommitmentSecret.toPoint
|
||||
|
||||
val remoteDelayedPubkey = Generators.derivePubKey(remoteParams.delayedPaymentBasepoint, remotePerCommitmentPoint)
|
||||
val remoteRevocationPrivkey = Generators.revocationPrivKey(localParams.revocationSecret, remotePerCommitmentSecret)
|
||||
remotePerCommitmentSecrets.getHash(0xFFFFFFFFFFFFFFFFL - txnumber)
|
||||
.map(d => Scalar(d :+ 1.toByte))
|
||||
.map { remotePerCommitmentSecret =>
|
||||
val remotePerCommitmentPoint = remotePerCommitmentSecret.toPoint
|
||||
|
||||
// let's punish remote by stealing its main output
|
||||
val mainDelayedRevokedTx = {
|
||||
// TODO: we should use the current fee rate, not the initial fee rate that we get from localParams
|
||||
val txinfo = Transactions.makeMainPunishmentTx(tx, remoteRevocationPrivkey.toPoint, localParams.defaultFinalScriptPubKey, remoteParams.toSelfDelay, remoteDelayedPubkey, commitments.localParams.feeratePerKw)
|
||||
val sig = Transactions.sign(txinfo, remoteRevocationPrivkey)
|
||||
Transactions.addSigs(txinfo, sig)
|
||||
}
|
||||
val remoteDelayedPubkey = Generators.derivePubKey(remoteParams.delayedPaymentBasepoint, remotePerCommitmentPoint)
|
||||
val remoteRevocationPrivkey = Generators.revocationPrivKey(localParams.revocationSecret, remotePerCommitmentSecret)
|
||||
|
||||
// TODO: we don't claim htlcs outputs yet
|
||||
// let's punish remote by stealing its main output
|
||||
val mainDelayedRevokedTx = {
|
||||
// TODO: we should use the current fee rate, not the initial fee rate that we get from localParams
|
||||
val txinfo = Transactions.makeMainPunishmentTx(tx, remoteRevocationPrivkey.toPoint, localParams.defaultFinalScriptPubKey, remoteParams.toSelfDelay, remoteDelayedPubkey, commitments.localParams.feeratePerKw)
|
||||
val sig = Transactions.sign(txinfo, remoteRevocationPrivkey)
|
||||
Transactions.addSigs(txinfo, sig)
|
||||
}
|
||||
|
||||
val txes = mainDelayedRevokedTx :: Nil
|
||||
// TODO: we don't claim htlcs outputs yet
|
||||
|
||||
// OPTIONAL: let's check transactions are actually spendable
|
||||
require(txes.forall(Transactions.checkSpendable(_).isSuccess), "the tx we produced are not spendable!")
|
||||
val txes = mainDelayedRevokedTx :: Nil
|
||||
|
||||
txes
|
||||
// OPTIONAL: let's check transactions are actually spendable
|
||||
require(txes.forall(Transactions.checkSpendable(_).isSuccess), "the tx we produced are not spendable!")
|
||||
|
||||
txes
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user