diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/DBCompatChecker.scala b/eclair-core/src/main/scala/fr/acinq/eclair/DBCompatChecker.scala
index fa05f0770..b9b22abaa 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/DBCompatChecker.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/DBCompatChecker.scala
@@ -28,7 +28,7 @@ object DBCompatChecker extends Logging {
* @param nodeParams
*/
def checkDBCompatibility(nodeParams: NodeParams): Unit =
- Try(nodeParams.channelsDb.listChannels()) match {
+ Try(nodeParams.db.channels.listLocalChannels()) match {
case Success(_) => {}
case Failure(_) => throw IncompatibleDBException
}
@@ -39,7 +39,7 @@ object DBCompatChecker extends Logging {
* @param nodeParams
*/
def checkNetworkDBCompatibility(nodeParams: NodeParams): Unit =
- Try(nodeParams.networkDb.listChannels(), nodeParams.networkDb.listNodes(), nodeParams.networkDb.listChannelUpdates()) match {
+ Try(nodeParams.db.network.listChannels(), nodeParams.db.network.listNodes(), nodeParams.db.network.listChannelUpdates()) match {
case Success(_) => {}
case Failure(_) => throw IncompatibleNetworkDBException
}
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/NodeParams.scala b/eclair-core/src/main/scala/fr/acinq/eclair/NodeParams.scala
index 6eb78f165..a6b06c953 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/NodeParams.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/NodeParams.scala
@@ -61,12 +61,7 @@ case class NodeParams(keyManager: KeyManager,
feeProportionalMillionth: Int,
reserveToFundingRatio: Double,
maxReserveToFundingRatio: Double,
- channelsDb: ChannelsDb,
- peersDb: PeersDb,
- networkDb: NetworkDb,
- pendingRelayDb: PendingRelayDb,
- paymentsDb: PaymentsDb,
- auditDb: AuditDb,
+ db: Databases,
revocationTimeout: FiniteDuration,
pingInterval: FiniteDuration,
pingTimeout: FiniteDuration,
@@ -129,29 +124,11 @@ object NodeParams {
}
}
- def makeNodeParams(datadir: File, config: Config, keyManager: KeyManager, torAddress_opt: Option[NodeAddress]): NodeParams = {
-
- datadir.mkdirs()
+ def makeNodeParams(config: Config, keyManager: KeyManager, torAddress_opt: Option[NodeAddress], database: Databases): NodeParams = {
val chain = config.getString("chain")
val chainHash = makeChainHash(chain)
- val chaindir = new File(datadir, chain)
- chaindir.mkdir()
-
- val sqlite = DriverManager.getConnection(s"jdbc:sqlite:${new File(chaindir, "eclair.sqlite")}")
- SqliteUtils.obtainExclusiveLock(sqlite) // there should only be one process writing to this file
- val channelsDb = new SqliteChannelsDb(sqlite)
- val peersDb = new SqlitePeersDb(sqlite)
- val pendingRelayDb = new SqlitePendingRelayDb(sqlite)
- val paymentsDb = new SqlitePaymentsDb(sqlite)
-
- val sqliteNetwork = DriverManager.getConnection(s"jdbc:sqlite:${new File(chaindir, "network.sqlite")}")
- val networkDb = new SqliteNetworkDb(sqliteNetwork)
-
- val sqliteAudit = DriverManager.getConnection(s"jdbc:sqlite:${new File(chaindir, "audit.sqlite")}")
- val auditDb = new SqliteAuditDb(sqliteAudit)
-
val color = ByteVector.fromValidHex(config.getString("node-color"))
require(color.size == 3, "color should be a 3-bytes hex buffer")
@@ -220,12 +197,7 @@ object NodeParams {
feeProportionalMillionth = config.getInt("fee-proportional-millionths"),
reserveToFundingRatio = config.getDouble("reserve-to-funding-ratio"),
maxReserveToFundingRatio = config.getDouble("max-reserve-to-funding-ratio"),
- channelsDb = channelsDb,
- peersDb = peersDb,
- networkDb = networkDb,
- pendingRelayDb = pendingRelayDb,
- paymentsDb = paymentsDb,
- auditDb = auditDb,
+ db = database,
revocationTimeout = FiniteDuration(config.getDuration("revocation-timeout").getSeconds, TimeUnit.SECONDS),
pingInterval = FiniteDuration(config.getDuration("ping-interval").getSeconds, TimeUnit.SECONDS),
pingTimeout = FiniteDuration(config.getDuration("ping-timeout").getSeconds, TimeUnit.SECONDS),
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/Setup.scala b/eclair-core/src/main/scala/fr/acinq/eclair/Setup.scala
index ffe2c095d..3cbaecdbf 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/Setup.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/Setup.scala
@@ -43,6 +43,7 @@ import fr.acinq.eclair.blockchain.fee.{ConstantFeeProvider, _}
import fr.acinq.eclair.blockchain.{EclairWallet, _}
import fr.acinq.eclair.channel.Register
import fr.acinq.eclair.crypto.LocalKeyManager
+import fr.acinq.eclair.db.Databases
import fr.acinq.eclair.io.{Authenticator, Server, Switchboard}
import fr.acinq.eclair.payment._
import fr.acinq.eclair.router._
@@ -67,7 +68,14 @@ import scala.concurrent.duration._
*/
class Setup(datadir: File,
overrideDefaults: Config = ConfigFactory.empty(),
- seed_opt: Option[ByteVector] = None)(implicit system: ActorSystem) extends Logging {
+ seed_opt: Option[ByteVector] = None,
+ db: Option[Databases] = None)(implicit system: ActorSystem) extends Logging {
+
+ implicit val materializer = ActorMaterializer()
+ implicit val timeout = Timeout(30 seconds)
+ implicit val formats = org.json4s.DefaultFormats
+ implicit val ec = ExecutionContext.Implicits.global
+ implicit val sttpBackend = OkHttpFutureBackend()
logger.info(s"hello!")
logger.info(s"version=${getClass.getPackage.getImplementationVersion} commit=${getClass.getPackage.getSpecificationVersion}")
@@ -76,17 +84,18 @@ class Setup(datadir: File,
// this will force the secure random instance to initialize itself right now, making sure it doesn't hang later (see comment in package.scala)
secureRandom.nextInt()
+ datadir.mkdirs()
val config = NodeParams.loadConfiguration(datadir, overrideDefaults)
val seed = seed_opt.getOrElse(NodeParams.getSeed(datadir))
val chain = config.getString("chain")
val keyManager = new LocalKeyManager(seed, NodeParams.makeChainHash(chain))
- implicit val materializer = ActorMaterializer()
- implicit val timeout = Timeout(30 seconds)
- implicit val formats = org.json4s.DefaultFormats
- implicit val ec = ExecutionContext.Implicits.global
- implicit val sttpBackend = OkHttpFutureBackend()
- val nodeParams = NodeParams.makeNodeParams(datadir, config, keyManager, initTor())
+ val database = db match {
+ case Some(d) => d
+ case None => Databases.sqliteJDBC(new File(datadir, chain))
+ }
+
+ val nodeParams = NodeParams.makeNodeParams(config, keyManager, initTor(), database)
val serverBindingAddress = new InetSocketAddress(
config.getString("server.binding-ip"),
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/api/Service.scala b/eclair-core/src/main/scala/fr/acinq/eclair/api/Service.scala
index f90e54b7b..69a078bb1 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/api/Service.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/api/Service.scala
@@ -321,9 +321,9 @@ trait Service extends Logging {
case _ => (0L, Long.MaxValue)
}
completeRpcFuture(req.id, Future(AuditResponse(
- sent = nodeParams.auditDb.listSent(from, to),
- received = nodeParams.auditDb.listReceived(from, to),
- relayed = nodeParams.auditDb.listRelayed(from, to))
+ sent = nodeParams.db.audit.listSent(from, to),
+ received = nodeParams.db.audit.listReceived(from, to),
+ relayed = nodeParams.db.audit.listRelayed(from, to))
))
case "networkfees" =>
@@ -331,10 +331,10 @@ trait Service extends Logging {
case JInt(from) :: JInt(to) :: Nil => (from.toLong, to.toLong)
case _ => (0L, Long.MaxValue)
}
- completeRpcFuture(req.id, Future(nodeParams.auditDb.listNetworkFees(from, to)))
+ completeRpcFuture(req.id, Future(nodeParams.db.audit.listNetworkFees(from, to)))
// retrieve fee stats
- case "channelstats" => completeRpcFuture(req.id, Future(nodeParams.auditDb.stats))
+ case "channelstats" => completeRpcFuture(req.id, Future(nodeParams.db.audit.stats))
// method name was not found
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/channel/Channel.scala b/eclair-core/src/main/scala/fr/acinq/eclair/channel/Channel.scala
index ed2050a68..1840b89c5 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/channel/Channel.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/channel/Channel.scala
@@ -645,7 +645,7 @@ class Channel(val nodeParams: NodeParams, wallet: EclairWallet, remoteNodeId: Pu
trimmedHtlcs collect {
case DirectedHtlc(_, u) =>
log.info(s"adding paymentHash=${u.paymentHash} cltvExpiry=${u.cltvExpiry} to htlcs db for commitNumber=$nextCommitNumber")
- nodeParams.channelsDb.addOrUpdateHtlcInfo(d.channelId, nextCommitNumber, u.paymentHash, u.cltvExpiry)
+ nodeParams.db.channels.addOrUpdateHtlcInfo(d.channelId, nextCommitNumber, u.paymentHash, u.cltvExpiry)
}
if (!Helpers.aboveReserve(d.commitments) && Helpers.aboveReserve(commitments1)) {
// we just went above reserve (can't go below), let's refresh our channel_update to enable/disable it accordingly
@@ -1300,7 +1300,7 @@ class Channel(val nodeParams: NodeParams, wallet: EclairWallet, remoteNodeId: Pu
stateData match {
case d: HasCommitments =>
log.info(s"deleting database record for channelId=${d.channelId}")
- nodeParams.channelsDb.removeChannel(d.channelId)
+ nodeParams.db.channels.removeChannel(d.channelId)
case _ => {}
}
log.info("shutting down")
@@ -1895,7 +1895,7 @@ class Channel(val nodeParams: NodeParams, wallet: EclairWallet, remoteNodeId: Pu
def handleRemoteSpentOther(tx: Transaction, d: HasCommitments) = {
log.warning(s"funding tx spent in txid=${tx.txid}")
- Helpers.Closing.claimRevokedRemoteCommitTxOutputs(keyManager, d.commitments, tx, nodeParams.channelsDb) match {
+ Helpers.Closing.claimRevokedRemoteCommitTxOutputs(keyManager, d.commitments, tx, nodeParams.db.channels) match {
case Some(revokedCommitPublished) =>
log.warning(s"txid=${tx.txid} was a revoked commitment, publishing the penalty tx")
val exc = FundingTxSpent(d.channelId, tx)
@@ -2053,7 +2053,7 @@ class Channel(val nodeParams: NodeParams, wallet: EclairWallet, remoteNodeId: Pu
def store[T](d: T)(implicit tp: T <:< HasCommitments): T = {
log.debug(s"updating database record for channelId={}", d.channelId)
- nodeParams.channelsDb.addOrUpdateChannel(d)
+ nodeParams.db.channels.addOrUpdateChannel(d)
context.system.eventStream.publish(ChannelPersisted(self, remoteNodeId, d.channelId, d))
d
}
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/db/ChannelsDb.scala b/eclair-core/src/main/scala/fr/acinq/eclair/db/ChannelsDb.scala
index 86e20a4aa..7f531280d 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/db/ChannelsDb.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/db/ChannelsDb.scala
@@ -25,7 +25,7 @@ trait ChannelsDb {
def removeChannel(channelId: ByteVector32)
- def listChannels(): Seq[HasCommitments]
+ def listLocalChannels(): Seq[HasCommitments]
def addOrUpdateHtlcInfo(channelId: ByteVector32, commitmentNumber: Long, paymentHash: ByteVector32, cltvExpiry: Long)
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/db/Databases.scala b/eclair-core/src/main/scala/fr/acinq/eclair/db/Databases.scala
new file mode 100644
index 000000000..ff2badd0a
--- /dev/null
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/db/Databases.scala
@@ -0,0 +1,50 @@
+package fr.acinq.eclair.db
+
+import java.io.File
+import java.sql.{Connection, DriverManager}
+
+import fr.acinq.eclair.db.sqlite._
+
+trait Databases {
+
+ val network: NetworkDb
+
+ val audit: AuditDb
+
+ val channels: ChannelsDb
+
+ val peers: PeersDb
+
+ val payments: PaymentsDb
+
+ val pendingRelay: PendingRelayDb
+
+}
+
+object Databases {
+
+ /**
+ * Given a parent folder it creates or loads all the databases from a JDBC connection
+ * @param dbdir
+ * @return
+ */
+ def sqliteJDBC(dbdir: File): Databases = {
+ dbdir.mkdir()
+ val sqliteEclair = DriverManager.getConnection(s"jdbc:sqlite:${new File(dbdir, "eclair.sqlite")}")
+ val sqliteNetwork = DriverManager.getConnection(s"jdbc:sqlite:${new File(dbdir, "network.sqlite")}")
+ val sqliteAudit = DriverManager.getConnection(s"jdbc:sqlite:${new File(dbdir, "audit.sqlite")}")
+ SqliteUtils.obtainExclusiveLock(sqliteEclair) // there should only be one process writing to this file
+
+ databaseByConnections(sqliteAudit, sqliteNetwork, sqliteEclair)
+ }
+
+ def databaseByConnections(auditJdbc: Connection, networkJdbc: Connection, eclairJdbc: Connection) = new Databases {
+ override val network = new SqliteNetworkDb(networkJdbc)
+ override val audit = new SqliteAuditDb(auditJdbc)
+ override val channels = new SqliteChannelsDb(eclairJdbc)
+ override val peers = new SqlitePeersDb(eclairJdbc)
+ override val payments = new SqlitePaymentsDb(eclairJdbc)
+ override val pendingRelay = new SqlitePendingRelayDb(eclairJdbc)
+ }
+
+}
\ No newline at end of file
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/db/sqlite/SqliteChannelsDb.scala b/eclair-core/src/main/scala/fr/acinq/eclair/db/sqlite/SqliteChannelsDb.scala
index 0ccc2fb2f..fdc10418f 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/db/sqlite/SqliteChannelsDb.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/db/sqlite/SqliteChannelsDb.scala
@@ -73,7 +73,7 @@ class SqliteChannelsDb(sqlite: Connection) extends ChannelsDb {
}
}
- override def listChannels(): Seq[HasCommitments] = {
+ override def listLocalChannels(): Seq[HasCommitments] = {
using(sqlite.createStatement) { statement =>
val rs = statement.executeQuery("SELECT data FROM local_channels")
codecSequence(rs, stateDataCodec)
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/io/Peer.scala b/eclair-core/src/main/scala/fr/acinq/eclair/io/Peer.scala
index e8c261a83..f58f60101 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/io/Peer.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/io/Peer.scala
@@ -95,7 +95,7 @@ class Peer(nodeParams: NodeParams, remoteNodeId: PublicKey, authenticator: Actor
val address_opt = if (outgoing) {
// we store the node address upon successful outgoing connection, so we can reconnect later
// any previous address is overwritten
- NodeAddress.fromParts(address.getHostString, address.getPort).map(nodeAddress => nodeParams.peersDb.addOrUpdatePeer(remoteNodeId, nodeAddress))
+ NodeAddress.fromParts(address.getHostString, address.getPort).map(nodeAddress => nodeParams.db.peers.addOrUpdatePeer(remoteNodeId, nodeAddress))
Some(address)
} else None
@@ -489,7 +489,7 @@ class Peer(nodeParams: NodeParams, remoteNodeId: PublicKey, authenticator: Actor
def stopPeer() = {
log.info("removing peer from db")
- nodeParams.peersDb.removePeer(remoteNodeId)
+ nodeParams.db.peers.removePeer(remoteNodeId)
stop(FSM.Normal)
}
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/io/Switchboard.scala b/eclair-core/src/main/scala/fr/acinq/eclair/io/Switchboard.scala
index 6801112a6..c2b6cf0b1 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/io/Switchboard.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/io/Switchboard.scala
@@ -44,8 +44,8 @@ class Switchboard(nodeParams: NodeParams, authenticator: ActorRef, watcher: Acto
// we load peers and channels from database
{
- val channels = nodeParams.channelsDb.listChannels()
- val peers = nodeParams.peersDb.listPeers()
+ val channels = nodeParams.db.channels.listLocalChannels()
+ val peers = nodeParams.db.peers.listPeers()
checkBrokenHtlcsLink(channels, nodeParams.privateKey) match {
case Nil => ()
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/payment/Auditor.scala b/eclair-core/src/main/scala/fr/acinq/eclair/payment/Auditor.scala
index 38514c9ee..76eeb4d1c 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/payment/Auditor.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/payment/Auditor.scala
@@ -27,7 +27,7 @@ import scala.concurrent.duration._
class Auditor(nodeParams: NodeParams) extends Actor with ActorLogging {
- val db = nodeParams.auditDb
+ val db = nodeParams.db.audit
context.system.eventStream.subscribe(self, classOf[PaymentEvent])
context.system.eventStream.subscribe(self, classOf[NetworkFeePaid])
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/payment/CommandBuffer.scala b/eclair-core/src/main/scala/fr/acinq/eclair/payment/CommandBuffer.scala
index 14336f3bd..37c6c5dd3 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/payment/CommandBuffer.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/payment/CommandBuffer.scala
@@ -24,7 +24,7 @@ import fr.acinq.eclair.channel._
class CommandBuffer(nodeParams: NodeParams, register: ActorRef) extends Actor with ActorLogging {
import CommandBuffer._
- import nodeParams.pendingRelayDb
+ import nodeParams.db._
context.system.eventStream.subscribe(self, classOf[ChannelStateChanged])
@@ -34,17 +34,17 @@ class CommandBuffer(nodeParams: NodeParams, register: ActorRef) extends Actor wi
// save command in db
register forward Register.Forward(channelId, cmd)
// we also store the preimage in a db (note that this happens *after* forwarding the fulfill to the channel, so we don't add latency)
- pendingRelayDb.addPendingRelay(channelId, htlcId, cmd)
+ pendingRelay.addPendingRelay(channelId, htlcId, cmd)
case CommandAck(channelId, htlcId) =>
//delete from db
log.debug(s"fulfill/fail acked for channelId=$channelId htlcId=$htlcId")
- pendingRelayDb.removePendingRelay(channelId, htlcId)
+ pendingRelay.removePendingRelay(channelId, htlcId)
case ChannelStateChanged(channel, _, _, WAIT_FOR_INIT_INTERNAL | OFFLINE | SYNCING, NORMAL | SHUTDOWN | CLOSING, d: HasCommitments) =>
import d.channelId
// if channel is in a state where it can have pending htlcs, we send them the fulfills we know of
- pendingRelayDb.listPendingRelay(channelId) match {
+ pendingRelay.listPendingRelay(channelId) match {
case Nil => ()
case msgs =>
log.info(s"re-sending ${msgs.size} unacked fulfills/fails to channel $channelId")
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/payment/LocalPaymentHandler.scala b/eclair-core/src/main/scala/fr/acinq/eclair/payment/LocalPaymentHandler.scala
index 940359e98..cbf9b7947 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/payment/LocalPaymentHandler.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/payment/LocalPaymentHandler.scala
@@ -65,7 +65,7 @@ class LocalPaymentHandler(nodeParams: NodeParams) extends Actor with ActorLoggin
} recover { case t => sender ! Status.Failure(t) }
case CheckPayment(paymentHash) =>
- nodeParams.paymentsDb.findByPaymentHash(paymentHash) match {
+ nodeParams.db.payments.findByPaymentHash(paymentHash) match {
case Some(_) => sender ! true
case _ => sender ! false
}
@@ -92,7 +92,7 @@ class LocalPaymentHandler(nodeParams: NodeParams) extends Actor with ActorLoggin
case _ =>
log.info(s"received payment for paymentHash=${htlc.paymentHash} amountMsat=${htlc.amountMsat}")
// amount is correct or was not specified in the payment request
- nodeParams.paymentsDb.addPayment(Payment(htlc.paymentHash, htlc.amountMsat, Platform.currentTime / 1000))
+ nodeParams.db.payments.addPayment(Payment(htlc.paymentHash, htlc.amountMsat, Platform.currentTime / 1000))
sender ! CMD_FULFILL_HTLC(htlc.id, paymentPreimage, commit = true)
context.system.eventStream.publish(PaymentReceived(MilliSatoshi(htlc.amountMsat), htlc.paymentHash, htlc.channelId))
context.become(run(hash2preimage - htlc.paymentHash))
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/router/Router.scala b/eclair-core/src/main/scala/fr/acinq/eclair/router/Router.scala
index 4c593daaf..e08a8e0e5 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/router/Router.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/router/Router.scala
@@ -136,7 +136,7 @@ class Router(nodeParams: NodeParams, watcher: ActorRef, initialized: Option[Prom
}
)
- val db = nodeParams.networkDb
+ val db = nodeParams.db.network
{
log.info("loading network announcements from db...")
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/StartupSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/StartupSpec.scala
index 675dd3f32..615373a3f 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/StartupSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/StartupSpec.scala
@@ -16,15 +16,10 @@
package fr.acinq.eclair
-import java.io.File
-import java.nio.file._
-import java.nio.file.attribute.BasicFileAttributes
-
import com.typesafe.config.ConfigFactory
import fr.acinq.bitcoin.Block
import fr.acinq.eclair.crypto.LocalKeyManager
import org.scalatest.FunSuite
-
import scala.util.Try
class StartupSpec extends FunSuite {
@@ -38,31 +33,18 @@ class StartupSpec extends FunSuite {
assert(baseUkraineAlias.getBytes.length === 27)
// we add 2 UTF-8 chars, each is 3-bytes long -> total new length 33 bytes!
- val goUkraineGo = threeBytesUTFChar+"BitcoinLightningNodeUkraine"+threeBytesUTFChar
+ val goUkraineGo = threeBytesUTFChar + "BitcoinLightningNodeUkraine" + threeBytesUTFChar
assert(goUkraineGo.length === 29)
assert(goUkraineGo.getBytes.length === 33) // too long for the alias, should be truncated
val illegalAliasConf = ConfigFactory.parseString(s"node-alias = $goUkraineGo")
val conf = illegalAliasConf.withFallback(ConfigFactory.parseResources("reference.conf").getConfig("eclair"))
- val tempConfParentDir = new File("temp-test.conf")
-
val keyManager = new LocalKeyManager(seed = randomKey.toBin, chainHash = Block.TestnetGenesisBlock.hash)
// try to create a NodeParams instance with a conf that contains an illegal alias
- val nodeParamsAttempt = Try(NodeParams.makeNodeParams(tempConfParentDir, conf, keyManager, None))
+ val nodeParamsAttempt = Try(NodeParams.makeNodeParams(conf, keyManager, None, TestConstants.inMemoryDb()))
assert(nodeParamsAttempt.isFailure && nodeParamsAttempt.failed.get.getMessage.contains("alias, too long"))
-
- // destroy conf files after the test
- Files.walkFileTree(tempConfParentDir.toPath, new SimpleFileVisitor[Path]() {
- override def visitFile(file: Path, attrs: BasicFileAttributes): FileVisitResult = {
- Files.deleteIfExists(file)
- FileVisitResult.CONTINUE
- }
- })
-
- tempConfParentDir.listFiles.foreach(_.delete())
- tempConfParentDir.deleteOnExit()
}
}
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/TestConstants.scala b/eclair-core/src/test/scala/fr/acinq/eclair/TestConstants.scala
index db5523e79..4af457569 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/TestConstants.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/TestConstants.scala
@@ -16,18 +16,18 @@
package fr.acinq.eclair
-import java.sql.DriverManager
+import java.sql.{Connection, DriverManager}
import fr.acinq.bitcoin.Crypto.PrivateKey
import fr.acinq.bitcoin.{Block, ByteVector32, Script}
import fr.acinq.eclair.NodeParams.BITCOIND
import fr.acinq.eclair.crypto.LocalKeyManager
+import fr.acinq.eclair.db._
import fr.acinq.eclair.db.sqlite._
import fr.acinq.eclair.io.Peer
import fr.acinq.eclair.router.RouterConf
import fr.acinq.eclair.wire.{Color, NodeAddress}
import scodec.bits.ByteVector
-
import scala.concurrent.duration._
/**
@@ -38,12 +38,15 @@ object TestConstants {
val pushMsat = 200000000L
val feeratePerKw = 10000L
+ def sqliteInMemory() = DriverManager.getConnection("jdbc:sqlite::memory:")
+
+ def inMemoryDb(connection: Connection = sqliteInMemory()): Databases = Databases.databaseByConnections(connection, connection, connection)
+
+
object Alice {
val seed = ByteVector32(ByteVector.fill(32)(1))
val keyManager = new LocalKeyManager(seed, Block.RegtestGenesisBlock.hash)
- def sqlite = DriverManager.getConnection("jdbc:sqlite::memory:")
-
// This is a function, and not a val! When called will return a new NodeParams
def nodeParams = NodeParams(
keyManager = keyManager,
@@ -66,12 +69,7 @@ object TestConstants {
feeProportionalMillionth = 10,
reserveToFundingRatio = 0.01, // note: not used (overridden below)
maxReserveToFundingRatio = 0.05,
- channelsDb = new SqliteChannelsDb(sqlite),
- peersDb = new SqlitePeersDb(sqlite),
- networkDb = new SqliteNetworkDb(sqlite),
- pendingRelayDb = new SqlitePendingRelayDb(sqlite),
- paymentsDb = new SqlitePaymentsDb(sqlite),
- auditDb = new SqliteAuditDb(sqlite),
+ db = inMemoryDb(sqliteInMemory),
revocationTimeout = 20 seconds,
pingInterval = 30 seconds,
pingTimeout = 10 seconds,
@@ -114,8 +112,6 @@ object TestConstants {
val seed = ByteVector32(ByteVector.fill(32)(2))
val keyManager = new LocalKeyManager(seed, Block.RegtestGenesisBlock.hash)
- def sqlite = DriverManager.getConnection("jdbc:sqlite::memory:")
-
def nodeParams = NodeParams(
keyManager = keyManager,
alias = "bob",
@@ -137,12 +133,7 @@ object TestConstants {
feeProportionalMillionth = 10,
reserveToFundingRatio = 0.01, // note: not used (overridden below)
maxReserveToFundingRatio = 0.05,
- channelsDb = new SqliteChannelsDb(sqlite),
- peersDb = new SqlitePeersDb(sqlite),
- networkDb = new SqliteNetworkDb(sqlite),
- pendingRelayDb = new SqlitePendingRelayDb(sqlite),
- paymentsDb = new SqlitePaymentsDb(sqlite),
- auditDb = new SqliteAuditDb(sqlite),
+ db = inMemoryDb(sqliteInMemory),
revocationTimeout = 20 seconds,
pingInterval = 30 seconds,
pingTimeout = 10 seconds,
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/e/NormalStateSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/e/NormalStateSpec.scala
index d6486a7a8..dddc43010 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/e/NormalStateSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/e/NormalStateSpec.scala
@@ -484,11 +484,11 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
// depending on who starts signing first, there will be one or two commitments because both sides have changes
assert(alice.stateData.asInstanceOf[DATA_NORMAL].commitments.localCommit.index === 1)
assert(bob.stateData.asInstanceOf[DATA_NORMAL].commitments.localCommit.index === 2)
- assert(alice.underlyingActor.nodeParams.channelsDb.listHtlcInfos(alice.stateData.asInstanceOf[DATA_NORMAL].channelId, 0).size == 0)
- assert(alice.underlyingActor.nodeParams.channelsDb.listHtlcInfos(alice.stateData.asInstanceOf[DATA_NORMAL].channelId, 1).size == 2)
- assert(alice.underlyingActor.nodeParams.channelsDb.listHtlcInfos(alice.stateData.asInstanceOf[DATA_NORMAL].channelId, 2).size == 4)
- assert(bob.underlyingActor.nodeParams.channelsDb.listHtlcInfos(bob.stateData.asInstanceOf[DATA_NORMAL].channelId, 0).size == 0)
- assert(bob.underlyingActor.nodeParams.channelsDb.listHtlcInfos(bob.stateData.asInstanceOf[DATA_NORMAL].channelId, 1).size == 3)
+ assert(alice.underlyingActor.nodeParams.db.channels.listHtlcInfos(alice.stateData.asInstanceOf[DATA_NORMAL].channelId, 0).size == 0)
+ assert(alice.underlyingActor.nodeParams.db.channels.listHtlcInfos(alice.stateData.asInstanceOf[DATA_NORMAL].channelId, 1).size == 2)
+ assert(alice.underlyingActor.nodeParams.db.channels.listHtlcInfos(alice.stateData.asInstanceOf[DATA_NORMAL].channelId, 2).size == 4)
+ assert(bob.underlyingActor.nodeParams.db.channels.listHtlcInfos(bob.stateData.asInstanceOf[DATA_NORMAL].channelId, 0).size == 0)
+ assert(bob.underlyingActor.nodeParams.db.channels.listHtlcInfos(bob.stateData.asInstanceOf[DATA_NORMAL].channelId, 1).size == 3)
}
test("recv CMD_SIGN (htlcs with same pubkeyScript but different amounts)") { f =>
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/db/SqliteChannelsDbSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/db/SqliteChannelsDbSpec.scala
index 9f7185cfe..9e218c70d 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/db/SqliteChannelsDbSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/db/SqliteChannelsDbSpec.scala
@@ -50,10 +50,10 @@ class SqliteChannelsDbSpec extends FunSuite {
intercept[SQLiteException](db.addOrUpdateHtlcInfo(channel.channelId, commitNumber, paymentHash1, cltvExpiry1)) // no related channel
- assert(db.listChannels().toSet === Set.empty)
+ assert(db.listLocalChannels().toSet === Set.empty)
db.addOrUpdateChannel(channel)
db.addOrUpdateChannel(channel)
- assert(db.listChannels() === List(channel))
+ assert(db.listLocalChannels() === List(channel))
assert(db.listHtlcInfos(channel.channelId, commitNumber).toList == Nil)
db.addOrUpdateHtlcInfo(channel.channelId, commitNumber, paymentHash1, cltvExpiry1)
@@ -62,7 +62,7 @@ class SqliteChannelsDbSpec extends FunSuite {
assert(db.listHtlcInfos(channel.channelId, 43).toList == Nil)
db.removeChannel(channel.channelId)
- assert(db.listChannels() === Nil)
+ assert(db.listLocalChannels() === Nil)
assert(db.listHtlcInfos(channel.channelId, commitNumber).toList == Nil)
}
diff --git a/pom.xml b/pom.xml
index 2d4b89a11..496aef988 100644
--- a/pom.xml
+++ b/pom.xml
@@ -217,6 +217,7 @@
${project.build.directory}
-Xmx1024m
+ -Dfile.encoding=UTF-8