1
0
Fork 0
mirror of https://github.com/ACINQ/eclair.git synced 2025-02-23 14:40:34 +01:00

Merge branch 'master' into wip-akkahttp

This commit is contained in:
pm47 2016-02-24 16:14:46 +01:00
commit c63c71db11
9 changed files with 95 additions and 49 deletions

View file

@ -56,10 +56,11 @@ eclair.bitcoind.rpcpassword (default: bar)
## Status
- [X] Network
- [ ] Routing
- [X] Channel state machine
- [X] Channel protocol
- [X] HTLC Scripts
- [ ] Unilateral close handling
- [ ] Relaying Payment
- [ ] Fee management
- [X] Blockchain watcher
- [ ] Storing states in a database

View file

@ -27,6 +27,9 @@ object Boot extends App with Logging {
implicit val formats = org.json4s.DefaultFormats
implicit val ec = ExecutionContext.Implicits.global
logger.info(s"hello!")
logger.info(s"nodeid=${Globals.node_id.pub}")
val config = ConfigFactory.load()
val chain = Await.result(bitcoin_client.invoke("getblockchaininfo").map(json => (json \ "chain").extract[String]), 10 seconds)
assert(chain == "testnet" || chain == "regtest", "you should be on testnet or regtest")

View file

@ -1,9 +1,9 @@
package fr.acinq.eclair
import com.typesafe.config.ConfigFactory
import fr.acinq.bitcoin.{BitcoinJsonRPCClient, Base58Check}
import fr.acinq.bitcoin.{Crypto, BitcoinJsonRPCClient}
import fr.acinq.eclair.channel.OurChannelParams
import fr.acinq.eclair.crypto.LightningCrypto._
import fr.acinq.eclair.crypto.LightningCrypto
import lightning.locktime
import lightning.locktime.Locktime.Seconds
@ -13,9 +13,10 @@ import lightning.locktime.Locktime.Seconds
*/
object Globals {
val config = ConfigFactory.load()
val node_id = KeyPair("0277863c1e40a2d4934ccf18e6679ea949d36bb0d1333fb098e99180df60d0195a","0623a602c7b0c96df445b999de31ca31682f0117ca2bf2fb149b9e09287d5d47")
val commit_priv = Base58Check.decode("cQPmcNr6pwBQPyGfab3SksE9nTCtx9ism9T4dkS9dETNU2KKtJHk")._2
val final_priv = Base58Check.decode("cUrAtLtV7GGddqdkhUxnbZVDWGJBTducpPoon3eKp9Vnr1zxs6BG")._2
val node_id = LightningCrypto.randomKeyPair()
val commit_priv = Crypto.sha256(node_id.priv) // TODO : just for testing
val final_priv = Crypto.sha256(commit_priv) // TODO : just for testing
val default_locktime = locktime(Seconds(86400))
val default_mindepth = 3

View file

@ -26,7 +26,6 @@ class PollingWatcher(client: BitcoinJsonRPCClient)(implicit ec: ExecutionContext
override def receive: Receive = ???
def watching(watches: Map[Watch, Cancellable]): Receive = {
case w: WatchConfirmedBasedOnOutputs => log.warning(s"ignoring $w (not implemented)")
case w: WatchLost => log.warning(s"ignoring $w (not implemented)")

View file

@ -12,7 +12,6 @@ import fr.acinq.eclair.channel.BlockchainEvent
trait Watch
final case class WatchConfirmed(channel: ActorRef, txId: BinaryData, minDepth: Int, event: BlockchainEvent) extends Watch
final case class WatchConfirmedBasedOnOutputs(channel: ActorRef, txIdSpent: BinaryData, txOut: Seq[TxOut], minDepth: Int, event: BlockchainEvent) extends Watch
final case class WatchSpent(channel: ActorRef, txId: BinaryData, outputIndex: Int, minDepth: Int, event: BlockchainEvent) extends Watch
final case class WatchLost(channel: ActorRef, txId: BinaryData, minDepth: Int, event: BlockchainEvent) extends Watch // notify me if confirmation number gets below minDepth

View file

@ -734,7 +734,6 @@ class Channel(val them: ActorRef, val blockchain: ActorRef, val params: OurChann
goto(CLOSING) using DATA_CLOSING(d.ourParams, d.theirParams, d.shaChain, d.commitment, ourCommitPublished = Some(d.commitment.tx))
case true =>
them ! close_channel_ack()
blockchain ! WatchConfirmed(self, signedFinalTx.txid, d.ourParams.minDepth, BITCOIN_CLOSE_DONE)
blockchain ! Publish(signedFinalTx)
goto(CLOSING) using DATA_CLOSING(d.ourParams, d.theirParams, d.shaChain, d.commitment, mutualClosePublished = Some(signedFinalTx))
}
@ -742,7 +741,8 @@ class Channel(val them: ActorRef, val blockchain: ActorRef, val params: OurChann
case Event((BITCOIN_ANCHOR_SPENT, tx: Transaction), d: CurrentCommitment) if (isMutualClose(tx, d.ourParams, d.theirParams, d.commitment)) =>
// it is possible that we received this before the close_channel_complete, we may still receive the latter
log.info(s"mutual close detected: $tx")
stay
blockchain ! WatchConfirmed(self, tx.txid, d.ourParams.minDepth, BITCOIN_CLOSE_DONE)
goto(CLOSING) using DATA_CLOSING(d.ourParams, d.theirParams, d.shaChain, d.commitment, mutualClosePublished = Some(tx))
case Event((BITCOIN_ANCHOR_SPENT, tx: Transaction), d: CurrentCommitment) if (isTheirCommit(tx, d.ourParams, d.theirParams, d.commitment)) =>
them ! handle_theircommit(tx, d.ourParams, d.theirParams, d.shaChain, d.commitment)
@ -754,8 +754,6 @@ class Channel(val them: ActorRef, val blockchain: ActorRef, val params: OurChann
case Event((BITCOIN_ANCHOR_SPENT, _), _) =>
goto(ERR_INFORMATION_LEAK)
case Event(BITCOIN_CLOSE_DONE, _) => goto(CLOSED)
}
/**
@ -768,7 +766,8 @@ class Channel(val them: ActorRef, val blockchain: ActorRef, val params: OurChann
case Event((BITCOIN_ANCHOR_SPENT, tx: Transaction), d: CurrentCommitment) if (isMutualClose(tx, d.ourParams, d.theirParams, d.commitment)) =>
// it is possible that we received this before the close_channel_ack, we may still receive the latter
log.info(s"mutual close detected: $tx")
stay
blockchain ! WatchConfirmed(self, tx.txid, d.ourParams.minDepth, BITCOIN_CLOSE_DONE)
goto(CLOSING) using DATA_CLOSING(d.ourParams, d.theirParams, d.shaChain, d.commitment, mutualClosePublished = Some(tx))
case Event((BITCOIN_ANCHOR_SPENT, tx: Transaction), d: CurrentCommitment) if (isTheirCommit(tx, d.ourParams, d.theirParams, d.commitment)) =>
them ! handle_theircommit(tx, d.ourParams, d.theirParams, d.shaChain, d.commitment)
@ -781,8 +780,6 @@ class Channel(val them: ActorRef, val blockchain: ActorRef, val params: OurChann
case Event((BITCOIN_ANCHOR_SPENT, _), _) =>
goto(ERR_INFORMATION_LEAK)
case Event(BITCOIN_CLOSE_DONE, _) => goto(CLOSED)
case Event(pkt: error, d: DATA_WAIT_FOR_CLOSE_ACK) =>
// no-op, because at this point we have already published the mutual close tx on the blockchain
goto(CLOSING) using DATA_CLOSING(d.ourParams, d.theirParams, d.shaChain, d.commitment, mutualClosePublished = Some(d.mutualCloseTx))
@ -796,6 +793,7 @@ class Channel(val them: ActorRef, val blockchain: ActorRef, val params: OurChann
case Event((BITCOIN_ANCHOR_SPENT, tx: Transaction), d@DATA_CLOSING(ourParams, theirParams, _, commitment, _, _, _, _)) if (isMutualClose(tx, ourParams, theirParams, commitment)) =>
log.info(s"mutual close detected: $tx")
blockchain ! WatchConfirmed(self, tx.txid, ourParams.minDepth, BITCOIN_CLOSE_DONE)
// wait for BITCOIN_CLOSE_DONE
// should we override the previous tx? (which may be different because of malleability)
stay using d.copy(mutualClosePublished = Some(tx))
@ -838,6 +836,10 @@ class Channel(val them: ActorRef, val blockchain: ActorRef, val params: OurChann
case Event(BITCOIN_SPEND_THEIRS_DONE, _) => goto(CLOSED)
case Event(BITCOIN_STEAL_DONE, _) => goto(CLOSED)
case Event(p: close_channel_complete, _) => stay // if bitcoin network is faster than lightning network (very unlikely to happen)
case Event(p: close_channel_ack, _) => stay // if bitcoin network is faster than lightning network (very unlikely to happen)
}
when(CLOSED) {
@ -922,8 +924,6 @@ class Channel(val them: ActorRef, val blockchain: ActorRef, val params: OurChann
val finalTx = makeFinalTx(commitment.tx.txIn, ourFinalPubKey, theirParams.finalPubKey, closingState)
val ourSig = bin2signature(Transaction.signInput(finalTx, 0, multiSig2of2(ourCommitPubKey, theirParams.commitPubKey), SIGHASH_ALL, ourParams.commitPrivKey))
val anchorTxId = commitment.tx.txIn(0).outPoint.txid // commit tx only has 1 input, which is the anchor
// we need to watch for BITCOIN_CLOSE_DONE with what we have here, because they may never answer with the fully signed closing tx and still publish it
blockchain ! WatchConfirmedBasedOnOutputs(self, anchorTxId, finalTx.txOut, ourParams.minDepth, BITCOIN_CLOSE_DONE)
close_channel(ourSig, cmd.fee)
}
@ -932,7 +932,6 @@ class Channel(val them: ActorRef, val blockchain: ActorRef, val params: OurChann
val finalTx = makeFinalTx(commitment.tx.txIn, ourFinalPubKey, theirParams.finalPubKey, closingState)
val ourSig = Transaction.signInput(finalTx, 0, multiSig2of2(ourCommitPubKey, theirParams.commitPubKey), SIGHASH_ALL, ourParams.commitPrivKey)
val signedFinalTx = finalTx.updateSigScript(0, sigScript2of2(pkt.sig, ourSig, theirParams.commitPubKey, ourCommitPubKey))
blockchain ! WatchConfirmed(self, signedFinalTx.txid, ourParams.minDepth, BITCOIN_CLOSE_DONE)
blockchain ! Publish(signedFinalTx)
(signedFinalTx, close_channel_complete(ourSig))
}

View file

@ -68,7 +68,7 @@ class AuthHandler(them: ActorRef, blockchain: ActorRef, our_params: OurChannelPa
stay using s.copy(totlen_in = new_totlen_in, acc_in = rest)
case Event(pkt(Auth(auth)), s: SessionData) =>
log.info(s"their_nodeid: ${BinaryData(auth.nodeId.key.toByteArray)}")
log.info(s"their_nodeid=${BinaryData(auth.nodeId.key.toByteArray)}")
assert(Crypto.verifySignature(Crypto.hash256(session_key.pub), signature2bin(auth.sessionSig), pubkey2bin(auth.nodeId)), "auth failed")
val channel = context.actorOf(Channel.props(self, blockchain, our_params), name = "channel")
goto(IO_NORMAL) using Normal(channel, s)

View file

@ -3,7 +3,7 @@ package fr.acinq.eclair.channel
import fr.acinq.bitcoin._
import fr.acinq.eclair._
import fr.acinq.eclair.channel.Scripts._
import fr.acinq.eclair.blockchain.{Publish, WatchConfirmed, WatchConfirmedBasedOnOutputs}
import fr.acinq.eclair.blockchain.{Publish, WatchConfirmed}
import lightning._
import org.junit.runner.RunWith
import org.scalatest.Ignore
@ -58,18 +58,18 @@ class ChannelOpenSpec extends TestHelper() {
"handle CMD_CLOSE in OPEN_WAITING_THEIRANCHOR" in {
val (node, ChannelDesc(Some(ourParams), Some(theirParams), Some(Commitment(_, ourCommitTx, state, _)))) = reachState_NOANCHOR(OPEN_WAITING_THEIRANCHOR)
node ! CMD_CLOSE(0)
expectMsgClass(classOf[WatchConfirmedBasedOnOutputs])
expectMsgClass(classOf[close_channel])
node ! CMD_GETSTATE
expectMsg(WAIT_FOR_CLOSE_COMPLETE)
// the only difference between their final tx and ours is the order of the outputs, because state is symmetric
val closingState = state.reverse.adjust_fees(Globals.closing_fee * 1000, ourParams.anchorAmount.isDefined)
val theirFinalTx = makeFinalTx(ourCommitTx.txIn, theirParams.finalPubKey, ourFinalPubKey, closingState)
val ourFinalSigForThem = bin2signature(Transaction.signInput(theirFinalTx, 0, multiSig2of2(ourCommitPubKey, theirParams.commitPubKey), SIGHASH_ALL, ourParams.commitPrivKey))
val finalTx = makeFinalTx(ourCommitTx.txIn, theirParams.finalPubKey, ourFinalPubKey, closingState)
val ourFinalSigForThem = bin2signature(Transaction.signInput(finalTx, 0, multiSig2of2(ourCommitPubKey, theirParams.commitPubKey), SIGHASH_ALL, ourParams.commitPrivKey))
node ! close_channel_complete(ourFinalSigForThem)
expectMsgClass(classOf[close_channel_ack])
expectMsgClass(classOf[WatchConfirmed])
expectMsgClass(classOf[Publish])
node ! (BITCOIN_ANCHOR_SPENT, finalTx)
expectMsgClass(classOf[WatchConfirmed])
node ! CMD_GETSTATE
expectMsg(CLOSING)
node ! BITCOIN_CLOSE_DONE
@ -77,21 +77,41 @@ class ChannelOpenSpec extends TestHelper() {
expectMsg(CLOSED)
}
"handle CMD_CLOSE in OPEN_WAITING_THEIRANCHOR (closing tx received early)" in {
val (node, ChannelDesc(Some(ourParams), Some(theirParams), Some(Commitment(_, ourCommitTx, state, _)))) = reachState_NOANCHOR(OPEN_WAITING_THEIRANCHOR)
node ! CMD_CLOSE(0)
expectMsgClass(classOf[close_channel])
node ! CMD_GETSTATE
expectMsg(WAIT_FOR_CLOSE_COMPLETE)
// the only difference between their final tx and ours is the order of the outputs, because state is symmetric
val closingState = state.reverse.adjust_fees(Globals.closing_fee * 1000, ourParams.anchorAmount.isDefined)
val finalTx = makeFinalTx(ourCommitTx.txIn, theirParams.finalPubKey, ourFinalPubKey, closingState)
val ourFinalSigForThem = bin2signature(Transaction.signInput(finalTx, 0, multiSig2of2(ourCommitPubKey, theirParams.commitPubKey), SIGHASH_ALL, ourParams.commitPrivKey))
node ! (BITCOIN_ANCHOR_SPENT, finalTx)
expectMsgClass(classOf[WatchConfirmed])
node ! CMD_GETSTATE
expectMsg(CLOSING)
node ! close_channel_complete(ourFinalSigForThem)
node ! BITCOIN_CLOSE_DONE
node ! CMD_GETSTATE
expectMsg(CLOSED)
}
"handle CMD_CLOSE in OPEN_WAITING_OURANCHOR" in {
val (node, ChannelDesc(Some(ourParams), Some(theirParams), Some(Commitment(_, ourCommitTx, state, _)))) = reachState_WITHANCHOR(OPEN_WAITING_OURANCHOR)
node ! CMD_CLOSE(0)
expectMsgClass(classOf[WatchConfirmedBasedOnOutputs])
expectMsgClass(classOf[close_channel])
node ! CMD_GETSTATE
expectMsg(WAIT_FOR_CLOSE_COMPLETE)
// the only difference between their final tx and ours is the order of the outputs, because state is symmetric
val closingState = state.reverse.adjust_fees(Globals.closing_fee * 1000, ourParams.anchorAmount.isDefined)
val theirFinalTx = makeFinalTx(ourCommitTx.txIn, theirParams.finalPubKey, ourFinalPubKey, closingState)
val ourFinalSigForThem = bin2signature(Transaction.signInput(theirFinalTx, 0, multiSig2of2(ourCommitPubKey, theirParams.commitPubKey), SIGHASH_ALL, ourParams.commitPrivKey))
val finalTx = makeFinalTx(ourCommitTx.txIn, theirParams.finalPubKey, ourFinalPubKey, closingState)
val ourFinalSigForThem = bin2signature(Transaction.signInput(finalTx, 0, multiSig2of2(ourCommitPubKey, theirParams.commitPubKey), SIGHASH_ALL, ourParams.commitPrivKey))
node ! close_channel_complete(ourFinalSigForThem)
expectMsgClass(classOf[close_channel_ack])
expectMsgClass(classOf[WatchConfirmed])
expectMsgClass(classOf[Publish])
node ! (BITCOIN_ANCHOR_SPENT, finalTx)
expectMsgClass(classOf[WatchConfirmed])
node ! CMD_GETSTATE
expectMsg(CLOSING)
node ! BITCOIN_CLOSE_DONE
@ -102,18 +122,18 @@ class ChannelOpenSpec extends TestHelper() {
"handle CMD_CLOSE in OPEN_WAIT_FOR_COMPLETE_THEIRANCHOR" in {
val (node, ChannelDesc(Some(ourParams), Some(theirParams), Some(Commitment(_, ourCommitTx, state, _)))) = reachState_NOANCHOR(OPEN_WAIT_FOR_COMPLETE_THEIRANCHOR)
node ! CMD_CLOSE(0)
expectMsgClass(classOf[WatchConfirmedBasedOnOutputs])
expectMsgClass(classOf[close_channel])
node ! CMD_GETSTATE
expectMsg(WAIT_FOR_CLOSE_COMPLETE)
// the only difference between their final tx and ours is the order of the outputs, because state is symmetric
val closingState = state.reverse.adjust_fees(Globals.closing_fee * 1000, ourParams.anchorAmount.isDefined)
val theirFinalTx = makeFinalTx(ourCommitTx.txIn, theirParams.finalPubKey, ourFinalPubKey, closingState)
val ourFinalSigForThem = bin2signature(Transaction.signInput(theirFinalTx, 0, multiSig2of2(ourCommitPubKey, theirParams.commitPubKey), SIGHASH_ALL, ourParams.commitPrivKey))
val finalTx = makeFinalTx(ourCommitTx.txIn, theirParams.finalPubKey, ourFinalPubKey, closingState)
val ourFinalSigForThem = bin2signature(Transaction.signInput(finalTx, 0, multiSig2of2(ourCommitPubKey, theirParams.commitPubKey), SIGHASH_ALL, ourParams.commitPrivKey))
node ! close_channel_complete(ourFinalSigForThem)
expectMsgClass(classOf[close_channel_ack])
expectMsgClass(classOf[WatchConfirmed])
expectMsgClass(classOf[Publish])
node ! (BITCOIN_ANCHOR_SPENT, finalTx)
expectMsgClass(classOf[WatchConfirmed])
node ! CMD_GETSTATE
expectMsg(CLOSING)
node ! BITCOIN_CLOSE_DONE
@ -124,18 +144,18 @@ class ChannelOpenSpec extends TestHelper() {
"handle CMD_CLOSE in OPEN_WAIT_FOR_COMPLETE_OURANCHOR" in {
val (node, ChannelDesc(Some(ourParams), Some(theirParams), Some(Commitment(_, ourCommitTx, state, _)))) = reachState_WITHANCHOR(OPEN_WAIT_FOR_COMPLETE_OURANCHOR)
node ! CMD_CLOSE(0)
expectMsgClass(classOf[WatchConfirmedBasedOnOutputs])
expectMsgClass(classOf[close_channel])
node ! CMD_GETSTATE
expectMsg(WAIT_FOR_CLOSE_COMPLETE)
// the only difference between their final tx and ours is the order of the outputs, because state is symmetric
val closingState = state.reverse.adjust_fees(Globals.closing_fee * 1000, ourParams.anchorAmount.isDefined)
val theirFinalTx = makeFinalTx(ourCommitTx.txIn, theirParams.finalPubKey, ourFinalPubKey, closingState)
val ourFinalSigForThem = bin2signature(Transaction.signInput(theirFinalTx, 0, multiSig2of2(ourCommitPubKey, theirParams.commitPubKey), SIGHASH_ALL, ourParams.commitPrivKey))
val finalTx = makeFinalTx(ourCommitTx.txIn, theirParams.finalPubKey, ourFinalPubKey, closingState)
val ourFinalSigForThem = bin2signature(Transaction.signInput(finalTx, 0, multiSig2of2(ourCommitPubKey, theirParams.commitPubKey), SIGHASH_ALL, ourParams.commitPrivKey))
node ! close_channel_complete(ourFinalSigForThem)
expectMsgClass(classOf[close_channel_ack])
expectMsgClass(classOf[WatchConfirmed])
expectMsgClass(classOf[Publish])
node ! (BITCOIN_ANCHOR_SPENT, finalTx)
expectMsgClass(classOf[WatchConfirmed])
node ! CMD_GETSTATE
expectMsg(CLOSING)
node ! BITCOIN_CLOSE_DONE
@ -147,15 +167,37 @@ class ChannelOpenSpec extends TestHelper() {
val (node, ChannelDesc(Some(ourParams), Some(theirParams), Some(Commitment(_, ourCommitTx, state, _)))) = reachState_NOANCHOR(OPEN_WAITING_THEIRANCHOR)
// the only difference between their final tx and ours is the order of the outputs, because state is symmetric
val closingState = state.reverse.adjust_fees(Globals.closing_fee * 1000, ourParams.anchorAmount.isDefined)
val theirFinalTx = makeFinalTx(ourCommitTx.txIn, theirParams.finalPubKey, ourFinalPubKey, closingState)
val ourFinalSigForThem = bin2signature(Transaction.signInput(theirFinalTx, 0, multiSig2of2(ourCommitPubKey, theirParams.commitPubKey), SIGHASH_ALL, ourParams.commitPrivKey))
val finalTx = makeFinalTx(ourCommitTx.txIn, theirParams.finalPubKey, ourFinalPubKey, closingState)
val ourFinalSigForThem = bin2signature(Transaction.signInput(finalTx, 0, multiSig2of2(ourCommitPubKey, theirParams.commitPubKey), SIGHASH_ALL, ourParams.commitPrivKey))
node ! close_channel(ourFinalSigForThem, 0)
expectMsgClass(classOf[WatchConfirmed])
expectMsgClass(classOf[Publish])
expectMsgClass(classOf[close_channel_complete])
node ! CMD_GETSTATE
expectMsg(WAIT_FOR_CLOSE_ACK)
node ! close_channel_ack()
node ! (BITCOIN_ANCHOR_SPENT, finalTx) // TODO: this event could be sent before the close_channel_ack
expectMsgClass(classOf[WatchConfirmed])
node ! CMD_GETSTATE
expectMsg(CLOSING)
node ! BITCOIN_CLOSE_DONE
node ! CMD_GETSTATE
expectMsg(CLOSED)
}
"handle PKT_CLOSE in OPEN_WAITING_THEIRANCHOR (closing tx received early)" in {
val (node, ChannelDesc(Some(ourParams), Some(theirParams), Some(Commitment(_, ourCommitTx, state, _)))) = reachState_NOANCHOR(OPEN_WAITING_THEIRANCHOR)
// the only difference between their final tx and ours is the order of the outputs, because state is symmetric
val closingState = state.reverse.adjust_fees(Globals.closing_fee * 1000, ourParams.anchorAmount.isDefined)
val finalTx = makeFinalTx(ourCommitTx.txIn, theirParams.finalPubKey, ourFinalPubKey, closingState)
val ourFinalSigForThem = bin2signature(Transaction.signInput(finalTx, 0, multiSig2of2(ourCommitPubKey, theirParams.commitPubKey), SIGHASH_ALL, ourParams.commitPrivKey))
node ! close_channel(ourFinalSigForThem, 0)
expectMsgClass(classOf[Publish])
expectMsgClass(classOf[close_channel_complete])
node ! CMD_GETSTATE
expectMsg(WAIT_FOR_CLOSE_ACK)
node ! (BITCOIN_ANCHOR_SPENT, finalTx)
expectMsgClass(classOf[WatchConfirmed])
node ! close_channel_ack()
node ! CMD_GETSTATE
expectMsg(CLOSING)
node ! BITCOIN_CLOSE_DONE
@ -167,15 +209,16 @@ class ChannelOpenSpec extends TestHelper() {
val (node, ChannelDesc(Some(ourParams), Some(theirParams), Some(Commitment(_, ourCommitTx, state, _)))) = reachState_WITHANCHOR(OPEN_WAITING_OURANCHOR)
// the only difference between their final tx and ours is the order of the outputs, because state is symmetric
val closingState = state.reverse.adjust_fees(Globals.closing_fee * 1000, ourParams.anchorAmount.isDefined)
val theirFinalTx = makeFinalTx(ourCommitTx.txIn, theirParams.finalPubKey, ourFinalPubKey, closingState)
val ourFinalSigForThem = bin2signature(Transaction.signInput(theirFinalTx, 0, multiSig2of2(ourCommitPubKey, theirParams.commitPubKey), SIGHASH_ALL, ourParams.commitPrivKey))
val finalTx = makeFinalTx(ourCommitTx.txIn, theirParams.finalPubKey, ourFinalPubKey, closingState)
val ourFinalSigForThem = bin2signature(Transaction.signInput(finalTx, 0, multiSig2of2(ourCommitPubKey, theirParams.commitPubKey), SIGHASH_ALL, ourParams.commitPrivKey))
node ! close_channel(ourFinalSigForThem, 0)
expectMsgClass(classOf[WatchConfirmed])
expectMsgClass(classOf[Publish])
expectMsgClass(classOf[close_channel_complete])
node ! CMD_GETSTATE
expectMsg(WAIT_FOR_CLOSE_ACK)
node ! close_channel_ack()
node ! (BITCOIN_ANCHOR_SPENT, finalTx)
expectMsgClass(classOf[WatchConfirmed])
node ! CMD_GETSTATE
expectMsg(CLOSING)
node ! BITCOIN_CLOSE_DONE
@ -187,15 +230,16 @@ class ChannelOpenSpec extends TestHelper() {
val (node, ChannelDesc(Some(ourParams), Some(theirParams), Some(Commitment(_, ourCommitTx, state, _)))) = reachState_NOANCHOR(OPEN_WAIT_FOR_COMPLETE_THEIRANCHOR)
// the only difference between their final tx and ours is the order of the outputs, because state is symmetric
val closingState = state.reverse.adjust_fees(Globals.closing_fee * 1000, ourParams.anchorAmount.isDefined)
val theirFinalTx = makeFinalTx(ourCommitTx.txIn, theirParams.finalPubKey, ourFinalPubKey, closingState)
val ourFinalSigForThem = bin2signature(Transaction.signInput(theirFinalTx, 0, multiSig2of2(ourCommitPubKey, theirParams.commitPubKey), SIGHASH_ALL, ourParams.commitPrivKey))
val finalTx = makeFinalTx(ourCommitTx.txIn, theirParams.finalPubKey, ourFinalPubKey, closingState)
val ourFinalSigForThem = bin2signature(Transaction.signInput(finalTx, 0, multiSig2of2(ourCommitPubKey, theirParams.commitPubKey), SIGHASH_ALL, ourParams.commitPrivKey))
node ! close_channel(ourFinalSigForThem, 0)
expectMsgClass(classOf[WatchConfirmed])
expectMsgClass(classOf[Publish])
expectMsgClass(classOf[close_channel_complete])
node ! CMD_GETSTATE
expectMsg(WAIT_FOR_CLOSE_ACK)
node ! close_channel_ack()
node ! (BITCOIN_ANCHOR_SPENT, finalTx)
expectMsgClass(classOf[WatchConfirmed])
node ! CMD_GETSTATE
expectMsg(CLOSING)
node ! BITCOIN_CLOSE_DONE
@ -207,15 +251,16 @@ class ChannelOpenSpec extends TestHelper() {
val (node, ChannelDesc(Some(ourParams), Some(theirParams), Some(Commitment(_, ourCommitTx, state, _)))) = reachState_WITHANCHOR(OPEN_WAIT_FOR_COMPLETE_OURANCHOR)
// the only difference between their final tx and ours is the order of the outputs, because state is symmetric
val closingState = state.reverse.adjust_fees(Globals.closing_fee * 1000, ourParams.anchorAmount.isDefined)
val theirFinalTx = makeFinalTx(ourCommitTx.txIn, theirParams.finalPubKey, ourFinalPubKey, closingState)
val ourFinalSigForThem = bin2signature(Transaction.signInput(theirFinalTx, 0, multiSig2of2(ourCommitPubKey, theirParams.commitPubKey), SIGHASH_ALL, ourParams.commitPrivKey))
val finalTx = makeFinalTx(ourCommitTx.txIn, theirParams.finalPubKey, ourFinalPubKey, closingState)
val ourFinalSigForThem = bin2signature(Transaction.signInput(finalTx, 0, multiSig2of2(ourCommitPubKey, theirParams.commitPubKey), SIGHASH_ALL, ourParams.commitPrivKey))
node ! close_channel(ourFinalSigForThem, 0)
expectMsgClass(classOf[WatchConfirmed])
expectMsgClass(classOf[Publish])
expectMsgClass(classOf[close_channel_complete])
node ! CMD_GETSTATE
expectMsg(WAIT_FOR_CLOSE_ACK)
node ! close_channel_ack()
node ! (BITCOIN_ANCHOR_SPENT, finalTx)
expectMsgClass(classOf[WatchConfirmed])
node ! CMD_GETSTATE
expectMsg(CLOSING)
node ! BITCOIN_CLOSE_DONE

View file

@ -40,7 +40,6 @@ class ChannelSpec extends TestKit(ActorSystem("TestSystem")) with WordSpecLike w
case m: WatchConfirmed => true
case m: WatchSpent => true
case m: WatchLost => true
case m: WatchConfirmedBasedOnOutputs => true
}
val pipe = system.actorOf(Props[ChannelSpec.Pipe])
val alice = system.actorOf(Channel.props(pipe, blockchain.ref, Alice.channelParams), "Alice")