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

modified rusty's tests to pass with real channel implementation

This commit is contained in:
pm47 2016-05-30 18:10:12 +02:00
parent f26718d50c
commit bafd2a0d34
19 changed files with 694 additions and 3 deletions

View file

@ -0,0 +1,15 @@
# Simple test that we can commit an HTLC
# Initial state: A=1000000, B=0, both fee rates=10000
A:offer 1000000,9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
B:recvoffer
A:commit
B:recvcommit
A:recvrevoke
B:commit
A:recvcommit
B:recvrevoke
checksync
echo ***A***
A:dump
echo ***B***
B:dump

View file

@ -0,0 +1,30 @@
***A***
LOCAL COMMITS:
Commit 1:
Offered htlcs: (1,1000000)
Received htlcs:
Balance us: 999000000
Balance them: 0
Fee rate: 10000
REMOTE COMMITS:
Commit 1:
Offered htlcs:
Received htlcs: (1,1000000)
Balance us: 0
Balance them: 999000000
Fee rate: 10000
***B***
LOCAL COMMITS:
Commit 1:
Offered htlcs:
Received htlcs: (1,1000000)
Balance us: 0
Balance them: 999000000
Fee rate: 10000
REMOTE COMMITS:
Commit 1:
Offered htlcs: (1,1000000)
Received htlcs:
Balance us: 999000000
Balance them: 0
Fee rate: 10000

View file

@ -0,0 +1,18 @@
# 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
A:commit
B:recvoffer
B:recvoffer
B:recvcommit
A:recvrevoke
B:commit
A:recvcommit
B:recvrevoke
checksync
echo ***A***
A:dump
echo ***B***
B:dump

View file

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

View file

@ -0,0 +1,24 @@
# Simple test that we can fulfill (remove) an HTLC after fully settled.
A:offer 1000000,b8928207364d445daa42f4ba8be0ef661b8d7190206c01f6ee8281566b3dec0a
B:recvoffer
A:commit
B:recvcommit
A:recvrevoke
B:commit
A:recvcommit
B:recvrevoke
B:fulfill 1,60303ae22b998861bce3b28f33eec1be758a213c86c93c076dbe9f558c11c752
B:commit
A:recvremove
A:recvcommit
B:recvrevoke
A:commit
B:recvcommit
A:recvrevoke
checksync
echo ***A***
A:dump
echo ***B***
B:dump

View file

@ -0,0 +1,30 @@
***A***
LOCAL COMMITS:
Commit 2:
Offered htlcs:
Received htlcs:
Balance us: 999000000
Balance them: 1000000
Fee rate: 10000
REMOTE COMMITS:
Commit 2:
Offered htlcs:
Received htlcs:
Balance us: 1000000
Balance them: 999000000
Fee rate: 10000
***B***
LOCAL COMMITS:
Commit 2:
Offered htlcs:
Received htlcs:
Balance us: 1000000
Balance them: 999000000
Fee rate: 10000
REMOTE COMMITS:
Commit 2:
Offered htlcs:
Received htlcs:
Balance us: 999000000
Balance them: 1000000
Fee rate: 10000

View file

@ -0,0 +1,22 @@
***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

@ -0,0 +1,22 @@
# 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
B:recvoffer
A:commit
B:recvcommit
A:recvrevoke
A:offer 2000000,6016bcc377c93692f2fe19fbad47eee6fb8f4cc98c56e935db5edb69806d84f6
B:recvoffer
A:commit
B:recvcommit
A:recvrevoke
B:commit
A:recvcommit
B:recvrevoke
checksync
echo ***A***
A:dump
echo ***B***
B:dump

View file

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

View file

@ -0,0 +1,20 @@
# Test committing before receiving previous revocation.
A:nocommitwait
A:offer 1
A:commit
A:offer 3
A:commit
B:recvoffer
B:recvcommit
B:recvoffer
B:recvcommit
A:recvrevoke
A:recvrevoke
B:commit
A:recvcommit
B:recvrevoke
checksync
echo ***A***
A:dump
echo ***B***
B:dump

View file

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

View file

@ -0,0 +1,47 @@
# 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
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
A:commit
B:offer 2000000,6016bcc377c93692f2fe19fbad47eee6fb8f4cc98c56e935db5edb69806d84f6
B:recvoffer
B:recvcommit
B:commit
A:recvoffer
A:recvrevoke
A:recvcommit
B:recvrevoke
A:commit
B:recvcommit
A:recvrevoke
checksync
echo ***A***
A:dump
echo ***B***
B:dump

View file

@ -0,0 +1,60 @@
***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)
Balance us: 499000000
Balance them: 498000000
Fee rate: 10000
REMOTE COMMITS:
Commit 4:
Offered htlcs: (1,2000000)
Received htlcs: (2,1000000)
Balance us: 498000000
Balance them: 499000000
Fee rate: 10000
***B***
LOCAL COMMITS:
Commit 4:
Offered htlcs: (1,2000000)
Received htlcs: (2,1000000)
Balance us: 498000000
Balance them: 499000000
Fee rate: 10000
REMOTE COMMITS:
Commit 3:
Offered htlcs: (2,1000000)
Received htlcs: (1,2000000)
Balance us: 499000000
Balance them: 498000000
Fee rate: 10000

View file

@ -0,0 +1,52 @@
# 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
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:commit
B:commit
A:recvoffer
B:recvoffer
A:recvcommit
B:recvcommit
A:recvrevoke
B:recvrevoke
# They've got to come into sync eventually!
A:commit
B:commit
A:recvcommit
B:recvcommit
A:recvrevoke
B:recvrevoke
checksync
echo ***A***
A:dump
echo ***B***
B:dump

View file

@ -0,0 +1,60 @@
***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)
Balance us: 499000000
Balance them: 498000000
Fee rate: 10000
REMOTE COMMITS:
Commit 4:
Offered htlcs: (1,2000000)
Received htlcs: (2,1000000)
Balance us: 498000000
Balance them: 499000000
Fee rate: 10000
***B***
LOCAL COMMITS:
Commit 4:
Offered htlcs: (1,2000000)
Received htlcs: (2,1000000)
Balance us: 498000000
Balance them: 499000000
Fee rate: 10000
REMOTE COMMITS:
Commit 4:
Offered htlcs: (2,1000000)
Received htlcs: (1,2000000)
Balance us: 499000000
Balance them: 498000000
Fee rate: 10000

View file

@ -0,0 +1,22 @@
***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

@ -0,0 +1,57 @@
package fr.acinq.eclair.channel
import java.io.{File, FileInputStream}
import akka.actor.ActorSystem
import akka.testkit.{TestActorRef, TestFSMRef, TestKit}
import fr.acinq.eclair.blockchain.PollingWatcher
import fr.acinq.eclair.channel.TestConstants.{Alice, Bob}
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
import org.scalatest.{BeforeAndAfterAll, Ignore, Matchers, fixture}
import scala.io.Source
import scala.concurrent.duration._
/**
* Created by PM on 30/05/2016.
*/
@RunWith(classOf[JUnitRunner])
class NewRustyTestsSpec extends TestKit(ActorSystem("test")) with Matchers with fixture.FunSuiteLike with BeforeAndAfterAll {
type FixtureParam = Tuple2[List[String], List[String]]
override def withFixture(test: OneArgTest) = {
val pipe: TestActorRef[SynchronizationPipe] = TestActorRef[SynchronizationPipe]
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"))
val bob: TestFSMRef[State, Data, Channel] = TestFSMRef(new Channel(pipe, blockchainB, Bob.channelParams, "A"))
pipe !(alice, bob)
within(30 seconds) {
awaitCond(alice.stateName == NORMAL)
awaitCond(bob.stateName == NORMAL)
}
pipe ! new File(getClass.getResource(s"/scenarii/${test.name}.script").getFile)
awaitCond(pipe.underlying.isTerminated, 30 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))
}
override def afterAll {
TestKit.shutdownActorSystem(system)
}
test("01-offer1") { case (ref, res) => assert(ref === res)}
test("02-offer2") { case (ref, res) => assert(ref === res)}
test("03-fulfill1") { case (ref, res) => assert(ref === res)}
test("04-two-commits-onedir") { case (ref, res) => assert(ref === res)}
// test("05-two-commits-in-flight") { case (ref, res) => assert(ref === res)} DOES NOT PASS : cannot send two commit in a row (without having first revocation)
test("10-offers-crossover") { case (ref, res) => assert(ref === res)}
test("11-commits-crossover") { case (ref, res) => assert(ref === res)}
/*test("13-fee") { case (ref, res) => assert(ref === res)}
test("14-fee-twice") { case (ref, res) => assert(ref === res)}
test("15-fee-twice-back-to-back") { case (ref, res) => assert(ref === res)}*/
}

View file

@ -4,16 +4,18 @@ import akka.actor.FSM.{CurrentState, SubscribeTransitionCallBack, Transition}
import akka.testkit.TestProbe
import fr.acinq.bitcoin.{BinaryData, Crypto}
import fr.acinq.eclair._
import lightning.{locktime, update_add_htlc, update_fulfill_htlc}
import lightning.{locktime, update_add_htlc}
import lightning.locktime.Locktime.Blocks
import org.junit.runner.RunWith
import org.scalatest.Ignore
import org.scalatest.junit.JUnitRunner
import scala.collection.Set
import scala.collection.immutable.Set
import scala.concurrent.duration._
/**
* Created by PM on 26/04/2016.
*/
@RunWith(classOf[JUnitRunner])
class NominalChannelSpec extends BaseChannelTestClass {
test("open channel and reach normal state") { case (alice, bob, pipe) =>

View file

@ -0,0 +1,128 @@
package fr.acinq.eclair.channel
import java.io.{BufferedWriter, File, FileWriter}
import akka.actor.{Actor, ActorLogging, ActorRef, Stash}
import fr.acinq.bitcoin.BinaryData
import fr.acinq.eclair._
import lightning.locktime
import lightning.locktime.Locktime.Blocks
/**
* Created by PM on 30/05/2016.
*/
/*
Handles a bi-directional path between 2 actors
used to avoid the chicken-and-egg problem of:
a = new Channel(b)
b = new Channel(a)
This pipe executes scripted tests and allows for
fine grained control on the order of messages
*/
class SynchronizationPipe() extends Actor with ActorLogging with Stash {
val offer = "(.):offer ([0-9]+),([0-9a-f]+)".r
val fulfill = "(.):fulfill ([0-9]+),([0-9a-f]+)".r
val commit = "(.):commit".r
val feechange = "(.):feechange".r
val recv = "(.):recv.*".r
val nocommitwait = "(.):nocommitwait.*".r
val echo = "echo (.*)".r
val dump = "(.):dump".r
val fout = new BufferedWriter(new FileWriter("result.txt"))
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())
exec(rest, a, b)
case fulfill(x, id, r) :: rest =>
resolve(x) ! CMD_FULFILL_HTLC(id.toInt, BinaryData(r))
exec(rest, a, b)
case commit(x) :: rest =>
resolve(x) ! CMD_SIGN
exec(rest, a, b)
/*case feechange(x) :: rest =>
resolve(x) ! CmdFeeChange()
exec(rest, a, b)*/
case recv(x) :: rest =>
context.become(wait(a, b, script))
case nocommitwait(x) :: rest =>
log.warning("ignoring nocommitwait")
exec(rest, a, b)
case "checksync" :: rest =>
log.warning("ignoring checksync")
exec(rest, a, b)
case echo(s) :: rest =>
fout.write(s)
fout.newLine()
exec(rest, a, b)
case dump(x) :: rest =>
resolve(x) ! CMD_GETSTATEDATA
context.become(wait(a, b, script))
case "" :: rest =>
exec(rest, a, b)
case List() | Nil =>
log.info(s"done")
fout.close()
context stop self
}
}
def receive = {
case (a: ActorRef, b: ActorRef) =>
unstashAll()
context become passthrough(a, b)
case msg => stash()
}
def passthrough(a: ActorRef, b: ActorRef): Receive = {
case file: File =>
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 => log.error("" + msg)
}
def wait(a: ActorRef, b: ActorRef, script: List[String]): Receive = {
case msg if sender() == a && script.head.startsWith("B:recv") =>
b forward msg
unstashAll()
exec(script.drop(1), a, b)
case msg if sender() == b && script.head.startsWith("A:recv") =>
a forward msg
unstashAll()
exec(script.drop(1), a, b)
case d: DATA_NORMAL if script.head.endsWith(":dump") =>
def rtrim(s: String) = s.replaceAll("\\s+$", "")
val l = List(
"LOCAL COMMITS:",
s" Commit ${d.ourCommit.index}:",
s" Offered htlcs: ${d.ourCommit.spec.htlcs.filter(_.direction == OUT).map(h => (h.id, h.amountMsat)).mkString(" ")}",
s" Received htlcs: ${d.ourCommit.spec.htlcs.filter(_.direction == IN).map(h => (h.id, h.amountMsat)).mkString(" ")}",
s" Balance us: ${d.ourCommit.spec.amount_us_msat}",
s" Balance them: ${d.ourCommit.spec.amount_them_msat}",
s" Fee rate: ${d.ourCommit.spec.feeRate}",
"REMOTE COMMITS:",
s" Commit ${d.theirCommit.index}:",
s" Offered htlcs: ${d.theirCommit.spec.htlcs.filter(_.direction == OUT).map(h => (h.id, h.amountMsat)).mkString(" ")}",
s" Received htlcs: ${d.theirCommit.spec.htlcs.filter(_.direction == IN).map(h => (h.id, h.amountMsat)).mkString(" ")}",
s" Balance us: ${d.theirCommit.spec.amount_us_msat}",
s" Balance them: ${d.theirCommit.spec.amount_them_msat}",
s" Fee rate: ${d.theirCommit.spec.feeRate}")
.foreach(s => {
fout.write(rtrim(s))
fout.newLine()
})
unstashAll()
exec(script.drop(1), a, b)
case other =>
stash()
}
}