1
0
mirror of https://github.com/ACINQ/eclair.git synced 2025-01-19 05:33:59 +01:00

Added 'send' macro in test scenario (#10)

* added 'send' macro in test scenario

* formatting

* formatting
This commit is contained in:
Pierre-Marie Padiou 2016-05-31 13:04:09 +02:00 committed by Fabrice Drouin
parent bafd2a0d34
commit 1f0f8c0e44
19 changed files with 114 additions and 207 deletions

2
.gitignore vendored
View File

@ -25,3 +25,5 @@ target/
project/target
DeleteMe*.*
*~
result.txt

View File

@ -72,7 +72,8 @@ class Channel(val them: ActorRef, val blockchain: ActorRef, val params: OurChann
when(OPEN_WAIT_FOR_ANCHOR) {
case Event(open_anchor(anchorTxHash, anchorOutputIndex, anchorAmount), DATA_OPEN_WAIT_FOR_ANCHOR(ourParams, theirParams, theirRevocationHash, theirNextRevocationHash)) =>
val anchorTxid = anchorTxHash.reverse //see https://github.com/ElementsProject/lightning/issues/17
//see https://github.com/ElementsProject/lightning/issues/17
val anchorTxid = anchorTxHash.reverse
val anchorOutput = TxOut(Satoshi(anchorAmount), publicKeyScript = Scripts.anchorPubkeyScript(ourParams.commitPubKey, theirParams.commitPubKey))
// they fund the channel with their anchor tx, so the money is theirs
@ -261,11 +262,12 @@ class Channel(val them: ActorRef, val blockchain: ActorRef, val params: OurChann
when(NORMAL) {
case Event(CMD_ADD_HTLC(amount, rHash, expiry, nodeIds, origin), d@DATA_NORMAL(_, _, _, htlcIdx, _, _, ourChanges, _, _, _)) =>
case Event(CMD_ADD_HTLC(amount, rHash, expiry, nodeIds, origin, id_opt), d@DATA_NORMAL(_, _, _, htlcIdx, _, _, ourChanges, _, _, _)) =>
// TODO: should we take pending htlcs into account?
// TODO: assert(commitment.state.commit_changes(staged).us.pay_msat >= amount, "insufficient funds!")
// TODO: nodeIds are ignored
val htlc = update_add_htlc(htlcIdx + 1, amount, rHash, expiry, routing(ByteString.EMPTY))
val id: Long = id_opt.getOrElse(htlcIdx + 1)
val htlc = update_add_htlc(id, amount, rHash, expiry, routing(ByteString.EMPTY))
them ! htlc
stay using d.copy(htlcIdx = htlc.id, ourChanges = ourChanges.copy(proposed = ourChanges.proposed :+ htlc))

View File

@ -83,7 +83,17 @@ case object BITCOIN_CLOSE_DONE extends BlockchainEvent
*/
sealed trait Command
final case class CMD_ADD_HTLC(amount: Int, rHash: sha256_hash, expiry: locktime, nodeIds: Seq[String] = Seq.empty[String], originChannelId: Option[BinaryData] = None) extends Command
/**
*
*
* @param amount
* @param rHash
* @param expiry
* @param nodeIds
* @param originChannelId
* @param id should only be provided in tests otherwise it will be assigned automatically
*/
final case class CMD_ADD_HTLC(amount: Int, rHash: sha256_hash, expiry: locktime, nodeIds: Seq[String] = Seq.empty[String], originChannelId: Option[BinaryData] = None, id: Option[Long] = None) extends Command
final case class CMD_FULFILL_HTLC(id: Long, r: sha256_hash) extends Command
final case class CMD_FAIL_HTLC(id: Long, reason: String) extends Command
case object CMD_SIGN extends Command

View File

@ -1,6 +1,6 @@
# Simple test that we can commit an HTLC
# Initial state: A=1000000, B=0, both fee rates=10000
A:offer 1000000,9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
# Initial state: A=1000000 sat, B=0, both fee rates=10000 sat
A:offer 1,1000000,9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
B:recvoffer
A:commit
B:recvcommit

View File

@ -1,7 +1,7 @@
# Simple test that we can commit two HTLCs
# Initial state: A=1000000, B=0, both fee rates=10000
A:offer 1000000,7b3d979ca8330a94fa7e9e1b466d8b99e0bcdea1ec90596c0dcc8d7ef6b4300c
A:offer 2000000,6016bcc377c93692f2fe19fbad47eee6fb8f4cc98c56e935db5edb69806d84f6
# Initial state: A=1000000 sat, B=0, both fee rates=10000 sat
A:offer 1,1000000,7b3d979ca8330a94fa7e9e1b466d8b99e0bcdea1ec90596c0dcc8d7ef6b4300c
A:offer 3,2000000,6016bcc377c93692f2fe19fbad47eee6fb8f4cc98c56e935db5edb69806d84f6
A:commit
B:recvoffer
B:recvoffer

View File

@ -1,7 +1,7 @@
***A***
LOCAL COMMITS:
Commit 1:
Offered htlcs: (1,1000000) (2,2000000)
Offered htlcs: (1,1000000) (3,2000000)
Received htlcs:
Balance us: 997000000
Balance them: 0
@ -9,7 +9,7 @@ LOCAL COMMITS:
REMOTE COMMITS:
Commit 1:
Offered htlcs:
Received htlcs: (1,1000000) (2,2000000)
Received htlcs: (1,1000000) (3,2000000)
Balance us: 0
Balance them: 997000000
Fee rate: 10000
@ -17,13 +17,13 @@ REMOTE COMMITS:
LOCAL COMMITS:
Commit 1:
Offered htlcs:
Received htlcs: (1,1000000) (2,2000000)
Received htlcs: (1,1000000) (3,2000000)
Balance us: 0
Balance them: 997000000
Fee rate: 10000
REMOTE COMMITS:
Commit 1:
Offered htlcs: (1,1000000) (2,2000000)
Offered htlcs: (1,1000000) (3,2000000)
Received htlcs:
Balance us: 997000000
Balance them: 0

View File

@ -1,5 +1,6 @@
# Simple test that we can fulfill (remove) an HTLC after fully settled.
A:offer 1000000,b8928207364d445daa42f4ba8be0ef661b8d7190206c01f6ee8281566b3dec0a
# Initial state: A=1000000 sat, B=0, both fee rates=10000 sat
A:offer 1,1000000,b8928207364d445daa42f4ba8be0ef661b8d7190206c01f6ee8281566b3dec0a
B:recvoffer
A:commit
B:recvcommit

View File

@ -1,22 +0,0 @@
***A***
LOCAL COMMITS:
Commit 2:
Offered htlcs:
Received htlcs:
SIGNED
REMOTE COMMITS:
Commit 2:
Offered htlcs:
Received htlcs:
SIGNED
***B***
LOCAL COMMITS:
Commit 2:
Offered htlcs:
Received htlcs:
SIGNED
REMOTE COMMITS:
Commit 2:
Offered htlcs:
Received htlcs:
SIGNED

View File

@ -1,12 +1,12 @@
# Test A can commit twice; queueing two commits onto B's queue.
# Initial state: A=1000000, B=0, both fee rates=10000
A:offer 1000000,7b3d979ca8330a94fa7e9e1b466d8b99e0bcdea1ec90596c0dcc8d7ef6b4300c
# Initial state: A=1000000 sat, B=0, both fee rates=10000 sat
A:offer 1,1000000,7b3d979ca8330a94fa7e9e1b466d8b99e0bcdea1ec90596c0dcc8d7ef6b4300c
B:recvoffer
A:commit
B:recvcommit
A:recvrevoke
A:offer 2000000,6016bcc377c93692f2fe19fbad47eee6fb8f4cc98c56e935db5edb69806d84f6
A:offer 3,2000000,6016bcc377c93692f2fe19fbad47eee6fb8f4cc98c56e935db5edb69806d84f6
B:recvoffer
A:commit
B:recvcommit

View File

@ -1,7 +1,7 @@
***A***
LOCAL COMMITS:
Commit 1:
Offered htlcs: (1,1000000) (2,2000000)
Offered htlcs: (1,1000000) (3,2000000)
Received htlcs:
Balance us: 997000000
Balance them: 0
@ -9,7 +9,7 @@ LOCAL COMMITS:
REMOTE COMMITS:
Commit 2:
Offered htlcs:
Received htlcs: (1,1000000) (2,2000000)
Received htlcs: (1,1000000) (3,2000000)
Balance us: 0
Balance them: 997000000
Fee rate: 10000
@ -17,13 +17,13 @@ REMOTE COMMITS:
LOCAL COMMITS:
Commit 2:
Offered htlcs:
Received htlcs: (1,1000000) (2,2000000)
Received htlcs: (1,1000000) (3,2000000)
Balance us: 0
Balance them: 997000000
Fee rate: 10000
REMOTE COMMITS:
Commit 1:
Offered htlcs: (1,1000000) (2,2000000)
Offered htlcs: (1,1000000) (3,2000000)
Received htlcs:
Balance us: 997000000
Balance them: 0

View File

@ -1,32 +1,11 @@
# Offers which cross over still get resolved.
# Initial state: A=1000000, B=0, both fee rates=10000
A:offer 500000000,b8928207364d445daa42f4ba8be0ef661b8d7190206c01f6ee8281566b3dec0a
B:recvoffer
A:commit
B:recvcommit
A:recvrevoke
B:commit
A:recvcommit
B:recvrevoke
# Initial state: A=1000000 sat, B=0, both fee rates=10000 sat
A:send 500000000
# Intermediate state: A=500000 sat, B=500000 sat, both fee rates=10000 sat
B:fulfill 1,60303ae22b998861bce3b28f33eec1be758a213c86c93c076dbe9f558c11c752
B:commit
A:recvremove
A:recvcommit
B:recvrevoke
A:offer 1,1000000,7b3d979ca8330a94fa7e9e1b466d8b99e0bcdea1ec90596c0dcc8d7ef6b4300c
A:commit
B:recvcommit
A:recvrevoke
# Intermediate state: A=500000, B=500000, both fee rates=10000
echo ***A (intermediate)***
A:dump
echo ***B (intermediate)***
B:dump
A:offer 1000000,7b3d979ca8330a94fa7e9e1b466d8b99e0bcdea1ec90596c0dcc8d7ef6b4300c
A:commit
B:offer 2000000,6016bcc377c93692f2fe19fbad47eee6fb8f4cc98c56e935db5edb69806d84f6
B:offer 2,2000000,6016bcc377c93692f2fe19fbad47eee6fb8f4cc98c56e935db5edb69806d84f6
B:recvoffer
B:recvcommit
B:commit

View File

@ -1,60 +1,30 @@
***A (intermediate)***
LOCAL COMMITS:
Commit 2:
Offered htlcs:
Received htlcs:
Balance us: 500000000
Balance them: 500000000
Fee rate: 10000
REMOTE COMMITS:
Commit 2:
Offered htlcs:
Received htlcs:
Balance us: 500000000
Balance them: 500000000
Fee rate: 10000
***B (intermediate)***
LOCAL COMMITS:
Commit 2:
Offered htlcs:
Received htlcs:
Balance us: 500000000
Balance them: 500000000
Fee rate: 10000
REMOTE COMMITS:
Commit 2:
Offered htlcs:
Received htlcs:
Balance us: 500000000
Balance them: 500000000
Fee rate: 10000
***A***
LOCAL COMMITS:
Commit 3:
Offered htlcs: (2,1000000)
Received htlcs: (1,2000000)
Offered htlcs: (1,1000000)
Received htlcs: (2,2000000)
Balance us: 499000000
Balance them: 498000000
Fee rate: 10000
REMOTE COMMITS:
Commit 4:
Offered htlcs: (1,2000000)
Received htlcs: (2,1000000)
Offered htlcs: (2,2000000)
Received htlcs: (1,1000000)
Balance us: 498000000
Balance them: 499000000
Fee rate: 10000
***B***
LOCAL COMMITS:
Commit 4:
Offered htlcs: (1,2000000)
Received htlcs: (2,1000000)
Offered htlcs: (2,2000000)
Received htlcs: (1,1000000)
Balance us: 498000000
Balance them: 499000000
Fee rate: 10000
REMOTE COMMITS:
Commit 3:
Offered htlcs: (2,1000000)
Received htlcs: (1,2000000)
Offered htlcs: (1,1000000)
Received htlcs: (2,2000000)
Balance us: 499000000
Balance them: 498000000
Fee rate: 10000

View File

@ -1,31 +1,10 @@
# Commits which cross over still get resolved.
# Initial state: A=1000000, B=0, both fee rates=10000
A:offer 500000000,b8928207364d445daa42f4ba8be0ef661b8d7190206c01f6ee8281566b3dec0a
B:recvoffer
A:commit
B:recvcommit
A:recvrevoke
B:commit
A:recvcommit
B:recvrevoke
# Initial state: A=1000000 sat, B=0, both fee rates=10000 sat
A:send 500000000
# Intermediate state: A=500000 sat, B=500000 sat, both fee rates=10000 sat
B:fulfill 1,60303ae22b998861bce3b28f33eec1be758a213c86c93c076dbe9f558c11c752
B:commit
A:recvremove
A:recvcommit
B:recvrevoke
A:commit
B:recvcommit
A:recvrevoke
# Intermediate state: A=500000, B=500000, both fee rates=10000
echo ***A (intermediate)***
A:dump
echo ***B (intermediate)***
B:dump
A:offer 1000000,7b3d979ca8330a94fa7e9e1b466d8b99e0bcdea1ec90596c0dcc8d7ef6b4300c
B:offer 2000000,6016bcc377c93692f2fe19fbad47eee6fb8f4cc98c56e935db5edb69806d84f6
A:offer 1,1000000,7b3d979ca8330a94fa7e9e1b466d8b99e0bcdea1ec90596c0dcc8d7ef6b4300c
B:offer 2,2000000,6016bcc377c93692f2fe19fbad47eee6fb8f4cc98c56e935db5edb69806d84f6
A:commit
B:commit

View File

@ -1,60 +1,30 @@
***A (intermediate)***
LOCAL COMMITS:
Commit 2:
Offered htlcs:
Received htlcs:
Balance us: 500000000
Balance them: 500000000
Fee rate: 10000
REMOTE COMMITS:
Commit 2:
Offered htlcs:
Received htlcs:
Balance us: 500000000
Balance them: 500000000
Fee rate: 10000
***B (intermediate)***
LOCAL COMMITS:
Commit 2:
Offered htlcs:
Received htlcs:
Balance us: 500000000
Balance them: 500000000
Fee rate: 10000
REMOTE COMMITS:
Commit 2:
Offered htlcs:
Received htlcs:
Balance us: 500000000
Balance them: 500000000
Fee rate: 10000
***A***
LOCAL COMMITS:
Commit 4:
Offered htlcs: (2,1000000)
Received htlcs: (1,2000000)
Offered htlcs: (1,1000000)
Received htlcs: (2,2000000)
Balance us: 499000000
Balance them: 498000000
Fee rate: 10000
REMOTE COMMITS:
Commit 4:
Offered htlcs: (1,2000000)
Received htlcs: (2,1000000)
Offered htlcs: (2,2000000)
Received htlcs: (1,1000000)
Balance us: 498000000
Balance them: 499000000
Fee rate: 10000
***B***
LOCAL COMMITS:
Commit 4:
Offered htlcs: (1,2000000)
Received htlcs: (2,1000000)
Offered htlcs: (2,2000000)
Received htlcs: (1,1000000)
Balance us: 498000000
Balance them: 499000000
Fee rate: 10000
REMOTE COMMITS:
Commit 4:
Offered htlcs: (2,1000000)
Received htlcs: (1,2000000)
Offered htlcs: (1,1000000)
Received htlcs: (2,2000000)
Balance us: 499000000
Balance them: 498000000
Fee rate: 10000

View File

@ -1,22 +0,0 @@
***A***
LOCAL COMMITS:
Commit 2:
Offered htlcs: 1
Received htlcs: 2
SIGNED
REMOTE COMMITS:
Commit 2:
Offered htlcs: 2
Received htlcs: 1
SIGNED
***B***
LOCAL COMMITS:
Commit 2:
Offered htlcs: 2
Received htlcs: 1
SIGNED
REMOTE COMMITS:
Commit 2:
Offered htlcs: 1
Received htlcs: 2
SIGNED

View File

@ -1,6 +1,6 @@
package fr.acinq.eclair.channel
import akka.actor.ActorSystem
import akka.actor.{ActorRef, ActorSystem, Props}
import akka.testkit.{TestActorRef, TestFSMRef, TestKit}
import fr.acinq.eclair.blockchain.PollingWatcher
import fr.acinq.eclair.channel.TestConstants.{Alice, Bob}
@ -11,10 +11,10 @@ import org.scalatest.{BeforeAndAfterAll, Matchers, fixture}
*/
abstract class BaseChannelTestClass extends TestKit(ActorSystem("test")) with Matchers with fixture.FunSuiteLike with BeforeAndAfterAll {
type FixtureParam = Tuple3[TestFSMRef[State, Data, Channel], TestFSMRef[State, Data, Channel], TestActorRef[Pipe]]
type FixtureParam = Tuple3[TestFSMRef[State, Data, Channel], TestFSMRef[State, Data, Channel], ActorRef]
override def withFixture(test: OneArgTest) = {
val pipe: TestActorRef[Pipe] = TestActorRef[Pipe]
val pipe: ActorRef = system.actorOf(Props[Pipe])
val blockchainA = TestActorRef(new PollingWatcher(new TestBitcoinClient()))
val blockchainB = TestActorRef(new PollingWatcher(new TestBitcoinClient()))
val alice: TestFSMRef[State, Data, Channel] = TestFSMRef(new Channel(pipe, blockchainA, Alice.channelParams, "B"))

View File

@ -1,8 +1,9 @@
package fr.acinq.eclair.channel
import java.io.{File, FileInputStream}
import java.util.concurrent.{CountDownLatch, TimeUnit}
import akka.actor.ActorSystem
import akka.actor.{ActorRef, ActorSystem, Props}
import akka.testkit.{TestActorRef, TestFSMRef, TestKit}
import fr.acinq.eclair.blockchain.PollingWatcher
import fr.acinq.eclair.channel.TestConstants.{Alice, Bob}
@ -22,7 +23,8 @@ class NewRustyTestsSpec extends TestKit(ActorSystem("test")) with Matchers with
type FixtureParam = Tuple2[List[String], List[String]]
override def withFixture(test: OneArgTest) = {
val pipe: TestActorRef[SynchronizationPipe] = TestActorRef[SynchronizationPipe]
val latch = new CountDownLatch(1)
val pipe: ActorRef = system.actorOf(Props(new SynchronizationPipe(latch)))
val blockchainA = TestActorRef(new PollingWatcher(new TestBitcoinClient()))
val blockchainB = TestActorRef(new PollingWatcher(new TestBitcoinClient()))
val alice: TestFSMRef[State, Data, Channel] = TestFSMRef(new Channel(pipe, blockchainA, Alice.channelParams, "B"))
@ -33,7 +35,7 @@ class NewRustyTestsSpec extends TestKit(ActorSystem("test")) with Matchers with
awaitCond(bob.stateName == NORMAL)
}
pipe ! new File(getClass.getResource(s"/scenarii/${test.name}.script").getFile)
awaitCond(pipe.underlying.isTerminated, 30 seconds)
latch.await(30, TimeUnit.SECONDS)
val ref = Source.fromFile(getClass.getResource(s"/scenarii/${test.name}.script.expected").getFile).getLines().filterNot(_.startsWith("#")).toList
val res = Source.fromFile(new File("result.txt")).getLines().filterNot(_.startsWith("#")).toList
test((ref, res))

View File

@ -15,6 +15,7 @@ import scala.concurrent.duration._
/**
* Created by PM on 26/04/2016.
*/
@Ignore
@RunWith(classOf[JUnitRunner])
class NominalChannelSpec extends BaseChannelTestClass {

View File

@ -1,9 +1,10 @@
package fr.acinq.eclair.channel
import java.io.{BufferedWriter, File, FileWriter}
import java.util.concurrent.CountDownLatch
import akka.actor.{Actor, ActorLogging, ActorRef, Stash}
import fr.acinq.bitcoin.BinaryData
import fr.acinq.bitcoin.{BinaryData, Crypto}
import fr.acinq.eclair._
import lightning.locktime
import lightning.locktime.Locktime.Blocks
@ -21,10 +22,11 @@ import lightning.locktime.Locktime.Blocks
This pipe executes scripted tests and allows for
fine grained control on the order of messages
*/
class SynchronizationPipe() extends Actor with ActorLogging with Stash {
class SynchronizationPipe(latch: CountDownLatch) extends Actor with ActorLogging with Stash {
val offer = "(.):offer ([0-9]+),([0-9a-f]+)".r
val offer = "(.):offer ([0-9]+),([0-9]+),([0-9a-f]+)".r
val fulfill = "(.):fulfill ([0-9]+),([0-9a-f]+)".r
val send = "(.):send ([0-9]+)".r
val commit = "(.):commit".r
val feechange = "(.):feechange".r
val recv = "(.):recv.*".r
@ -37,8 +39,8 @@ class SynchronizationPipe() extends Actor with ActorLogging with Stash {
def exec(script: List[String], a: ActorRef, b: ActorRef): Unit = {
def resolve(x: String) = if (x == "A") a else b
script match {
case offer(x, amount, rhash) :: rest =>
resolve(x) ! CMD_ADD_HTLC(amount.toInt, BinaryData(rhash), locktime(Blocks(4)), Seq())
case offer(x, id, amount, rhash) :: rest =>
resolve(x) ! CMD_ADD_HTLC(amount.toInt, BinaryData(rhash), locktime(Blocks(4)), Seq(), id = Some(id.toLong))
exec(rest, a, b)
case fulfill(x, id, r) :: rest =>
resolve(x) ! CMD_FULFILL_HTLC(id.toInt, BinaryData(r))
@ -46,6 +48,28 @@ class SynchronizationPipe() extends Actor with ActorLogging with Stash {
case commit(x) :: rest =>
resolve(x) ! CMD_SIGN
exec(rest, a, b)
case send(x, amount) :: rest =>
// this is a macro for sending a given amount including commits and fulfill
val sender = x
val recipt = if (x == "A") "B" else "A"
val r: BinaryData = Crypto.sha256(scala.compat.Platform.currentTime.toString.getBytes)
val h: BinaryData = Crypto.sha256(r)
exec(s"$sender:offer 42,$amount,$h" ::
s"$recipt:recvoffer" ::
s"$sender:commit" ::
s"$recipt:recvcommit" ::
s"$sender:recvrevoke" ::
s"$recipt:commit" ::
s"$sender:recvcommit" ::
s"$recipt:recvrevoke" ::
s"$recipt:fulfill 42,$r" ::
s"$recipt:commit" ::
s"$sender:recvremove" ::
s"$sender:recvcommit" ::
s"$recipt:recvrevoke" ::
s"$sender:commit" ::
s"$recipt:recvcommit" ::
s"$sender:recvrevoke" :: rest, a, b)
/*case feechange(x) :: rest =>
resolve(x) ! CmdFeeChange()
exec(rest, a, b)*/
@ -69,7 +93,7 @@ class SynchronizationPipe() extends Actor with ActorLogging with Stash {
case List() | Nil =>
log.info(s"done")
fout.close()
context stop self
latch.countDown()
}
}
@ -85,8 +109,12 @@ class SynchronizationPipe() extends Actor with ActorLogging with Stash {
import scala.io.Source
val script = Source.fromFile(file).getLines().filterNot(_.startsWith("#")).toList
exec(script, a, b)
case msg if sender() == a => b forward msg
case msg if sender() == b => a forward msg
case msg if sender() == a =>
log.info(s"a -> b $msg")
b forward msg
case msg if sender() == b =>
log.info(s"b -> a $msg")
a forward msg
case msg => log.error("" + msg)
}
@ -125,4 +153,11 @@ class SynchronizationPipe() extends Actor with ActorLogging with Stash {
case other =>
stash()
}
override def preRestart(reason: Throwable, message: Option[Any]): Unit = {
reason.printStackTrace()
super.preRestart(reason, message)
}
}