diff --git a/eclair-core/eclair-cli b/eclair-core/eclair-cli
index 89a05cdde7..be2102d71c 100755
--- a/eclair-core/eclair-cli
+++ b/eclair-core/eclair-cli
@@ -89,7 +89,7 @@ jq_filter='if type=="object" and .error != null then .error else .';
# apply special jq filter if we are in "short" ouput mode -- only for specific commands such as 'channels'
if [ "$short" = true ]; then
- jq_channel_filter="{ nodeId, shortChannelId: .data.shortChannelId, channelId, state, balanceSat: (try (.data.commitments.localCommit.spec.toLocalMsat / 1000 | floor) catch null), capacitySat: .data.commitments.commitInput.amountSatoshis, channelPoint: .data.commitments.commitInput.outPoint }";
+ jq_channel_filter="{ nodeId, shortChannelId: .data.shortChannelId, channelId, state, balanceSat: (try (.data.commitments.localCommit.spec.toLocal / 1000 | floor) catch null), capacitySat: .data.commitments.commitInput.amountSatoshis, channelPoint: .data.commitments.commitInput.outPoint }";
case $api_endpoint in
"channels") jq_filter="$jq_filter | map( $jq_channel_filter )" ;;
"channel") jq_filter="$jq_filter | $jq_channel_filter" ;;
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/CoinUtils.scala b/eclair-core/src/main/scala/fr/acinq/eclair/CoinUtils.scala
index e4453ab8aa..2e58bef4dd 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/CoinUtils.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/CoinUtils.scala
@@ -17,10 +17,8 @@
package fr.acinq.eclair
import java.text.{DecimalFormat, NumberFormat}
-
-import fr.acinq.bitcoin.{Btc, BtcAmount, MilliBtc, MilliSatoshi, Satoshi}
+import fr.acinq.bitcoin.{Btc, BtcAmount, MilliBtc, Satoshi}
import grizzled.slf4j.Logging
-
import scala.util.{Failure, Success, Try}
/**
@@ -154,7 +152,7 @@ object CoinUtils extends Logging {
}
def convertStringAmountToSat(amount: String, unit: String): Satoshi =
- fr.acinq.bitcoin.millisatoshi2satoshi(CoinUtils.convertStringAmountToMsat(amount, unit))
+ CoinUtils.convertStringAmountToMsat(amount, unit).truncateToSatoshi
/**
* Only BtcUnit, MBtcUnit, BitUnit, SatUnit and MSatUnit codes or label are supported.
@@ -223,6 +221,11 @@ object CoinUtils extends Logging {
if (withUnit) s"$formatted ${unit.shortLabel}" else formatted
}
+ def formatAmountInUnit(amount: MilliSatoshi, unit: CoinUnit, withUnit: Boolean): String = {
+ val formatted = COIN_FORMAT.format(rawAmountInUnit(amount, unit))
+ if (withUnit) s"$formatted ${unit.shortLabel}" else formatted
+ }
+
/**
* Converts the amount to the user preferred unit and returns the BigDecimal value.
* This method is useful to feed numeric text input without formatting.
@@ -237,7 +240,10 @@ object CoinUtils extends Logging {
case a => throw new IllegalArgumentException(s"unhandled unit $a")
}) match {
case Success(b) => b
- case Failure(t) => logger.error("can not convert amount to user unit", t)
+ case Failure(t) =>
+ logger.error("can not convert amount to user unit", t)
-1
}
+
+ def rawAmountInUnit(msat: MilliSatoshi, unit: CoinUnit): BigDecimal = BigDecimal(msat.amount) / unit.factorToMsat
}
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/Eclair.scala b/eclair-core/src/main/scala/fr/acinq/eclair/Eclair.scala
index e423806715..e22b621d35 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/Eclair.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/Eclair.scala
@@ -22,7 +22,7 @@ import akka.actor.ActorRef
import akka.pattern._
import akka.util.Timeout
import fr.acinq.bitcoin.Crypto.PublicKey
-import fr.acinq.bitcoin.{ByteVector32, MilliSatoshi, Satoshi}
+import fr.acinq.bitcoin.{ByteVector32, Satoshi}
import fr.acinq.eclair.channel.Register.{Forward, ForwardShortId}
import fr.acinq.eclair.channel._
import fr.acinq.eclair.db.{IncomingPayment, NetworkFee, OutgoingPayment, Stats}
@@ -60,13 +60,13 @@ trait Eclair {
def disconnect(nodeId: PublicKey)(implicit timeout: Timeout): Future[String]
- def open(nodeId: PublicKey, fundingSatoshis: Long, pushMsat_opt: Option[Long], fundingFeerateSatByte_opt: Option[Long], flags_opt: Option[Int], openTimeout_opt: Option[Timeout])(implicit timeout: Timeout): Future[String]
+ def open(nodeId: PublicKey, fundingAmount: Satoshi, pushAmount_opt: Option[MilliSatoshi], fundingFeerateSatByte_opt: Option[Long], flags_opt: Option[Int], openTimeout_opt: Option[Timeout])(implicit timeout: Timeout): Future[String]
def close(channelIdentifier: Either[ByteVector32, ShortChannelId], scriptPubKey_opt: Option[ByteVector])(implicit timeout: Timeout): Future[String]
def forceClose(channelIdentifier: Either[ByteVector32, ShortChannelId])(implicit timeout: Timeout): Future[String]
- def updateRelayFee(channelIdentifier: Either[ByteVector32, ShortChannelId], feeBaseMsat: Long, feeProportionalMillionths: Long)(implicit timeout: Timeout): Future[String]
+ def updateRelayFee(channelIdentifier: Either[ByteVector32, ShortChannelId], feeBase: MilliSatoshi, feeProportionalMillionths: Long)(implicit timeout: Timeout): Future[String]
def channelsInfo(toRemoteNode_opt: Option[PublicKey])(implicit timeout: Timeout): Future[Iterable[RES_GETINFO]]
@@ -74,17 +74,17 @@ trait Eclair {
def peersInfo()(implicit timeout: Timeout): Future[Iterable[PeerInfo]]
- def receive(description: String, amountMsat_opt: Option[Long], expire_opt: Option[Long], fallbackAddress_opt: Option[String], paymentPreimage_opt: Option[ByteVector32])(implicit timeout: Timeout): Future[PaymentRequest]
+ def receive(description: String, amount_opt: Option[MilliSatoshi], expire_opt: Option[Long], fallbackAddress_opt: Option[String], paymentPreimage_opt: Option[ByteVector32])(implicit timeout: Timeout): Future[PaymentRequest]
def receivedInfo(paymentHash: ByteVector32)(implicit timeout: Timeout): Future[Option[IncomingPayment]]
- def send(recipientNodeId: PublicKey, amountMsat: Long, paymentHash: ByteVector32, assistedRoutes: Seq[Seq[PaymentRequest.ExtraHop]] = Seq.empty, minFinalCltvExpiry_opt: Option[Long] = None, maxAttempts_opt: Option[Int] = None, feeThresholdSat_opt: Option[Long] = None, maxFeePct_opt: Option[Double] = None)(implicit timeout: Timeout): Future[UUID]
+ def send(recipientNodeId: PublicKey, amount: MilliSatoshi, paymentHash: ByteVector32, assistedRoutes: Seq[Seq[PaymentRequest.ExtraHop]] = Seq.empty, minFinalCltvExpiry_opt: Option[Long] = None, maxAttempts_opt: Option[Int] = None, feeThresholdSat_opt: Option[Satoshi] = None, maxFeePct_opt: Option[Double] = None)(implicit timeout: Timeout): Future[UUID]
def sentInfo(id: Either[UUID, ByteVector32])(implicit timeout: Timeout): Future[Seq[OutgoingPayment]]
- def findRoute(targetNodeId: PublicKey, amountMsat: Long, assistedRoutes: Seq[Seq[PaymentRequest.ExtraHop]] = Seq.empty)(implicit timeout: Timeout): Future[RouteResponse]
+ def findRoute(targetNodeId: PublicKey, amount: MilliSatoshi, assistedRoutes: Seq[Seq[PaymentRequest.ExtraHop]] = Seq.empty)(implicit timeout: Timeout): Future[RouteResponse]
- def sendToRoute(route: Seq[PublicKey], amountMsat: Long, paymentHash: ByteVector32, finalCltvExpiry: Long)(implicit timeout: Timeout): Future[UUID]
+ def sendToRoute(route: Seq[PublicKey], amount: MilliSatoshi, paymentHash: ByteVector32, finalCltvExpiry: Long)(implicit timeout: Timeout): Future[UUID]
def audit(from_opt: Option[Long], to_opt: Option[Long])(implicit timeout: Timeout): Future[AuditResponse]
@@ -122,13 +122,13 @@ class EclairImpl(appKit: Kit) extends Eclair {
(appKit.switchboard ? Peer.Disconnect(nodeId)).mapTo[String]
}
- override def open(nodeId: PublicKey, fundingSatoshis: Long, pushMsat_opt: Option[Long], fundingFeerateSatByte_opt: Option[Long], flags_opt: Option[Int], openTimeout_opt: Option[Timeout])(implicit timeout: Timeout): Future[String] = {
+ override def open(nodeId: PublicKey, fundingAmount: Satoshi, pushAmount_opt: Option[MilliSatoshi], fundingFeerateSatByte_opt: Option[Long], flags_opt: Option[Int], openTimeout_opt: Option[Timeout])(implicit timeout: Timeout): Future[String] = {
// we want the open timeout to expire *before* the default ask timeout, otherwise user won't get a generic response
val openTimeout = openTimeout_opt.getOrElse(Timeout(10 seconds))
(appKit.switchboard ? Peer.OpenChannel(
remoteNodeId = nodeId,
- fundingSatoshis = Satoshi(fundingSatoshis),
- pushMsat = pushMsat_opt.map(MilliSatoshi).getOrElse(MilliSatoshi(0)),
+ fundingSatoshis = fundingAmount,
+ pushMsat = pushAmount_opt.getOrElse(MilliSatoshi(0)),
fundingTxFeeratePerKw_opt = fundingFeerateSatByte_opt.map(feerateByte2Kw),
channelFlags = flags_opt.map(_.toByte),
timeout_opt = Some(openTimeout))).mapTo[String]
@@ -142,7 +142,7 @@ class EclairImpl(appKit: Kit) extends Eclair {
sendToChannel(channelIdentifier, CMD_FORCECLOSE).mapTo[String]
}
- override def updateRelayFee(channelIdentifier: Either[ByteVector32, ShortChannelId], feeBaseMsat: Long, feeProportionalMillionths: Long)(implicit timeout: Timeout): Future[String] = {
+ override def updateRelayFee(channelIdentifier: Either[ByteVector32, ShortChannelId], feeBaseMsat: MilliSatoshi, feeProportionalMillionths: Long)(implicit timeout: Timeout): Future[String] = {
sendToChannel(channelIdentifier, CMD_UPDATE_RELAY_FEE(feeBaseMsat, feeProportionalMillionths)).mapTo[String]
}
@@ -177,31 +177,31 @@ class EclairImpl(appKit: Kit) extends Eclair {
case Some(pk) => (appKit.router ? 'updatesMap).mapTo[Map[ChannelDesc, ChannelUpdate]].map(_.filter(e => e._1.a == pk || e._1.b == pk).values)
}
- override def receive(description: String, amountMsat_opt: Option[Long], expire_opt: Option[Long], fallbackAddress_opt: Option[String], paymentPreimage_opt: Option[ByteVector32])(implicit timeout: Timeout): Future[PaymentRequest] = {
+ override def receive(description: String, amount_opt: Option[MilliSatoshi], expire_opt: Option[Long], fallbackAddress_opt: Option[String], paymentPreimage_opt: Option[ByteVector32])(implicit timeout: Timeout): Future[PaymentRequest] = {
fallbackAddress_opt.map { fa => fr.acinq.eclair.addressToPublicKeyScript(fa, appKit.nodeParams.chainHash) } // if it's not a bitcoin address throws an exception
- (appKit.paymentHandler ? ReceivePayment(description = description, amountMsat_opt = amountMsat_opt.map(MilliSatoshi), expirySeconds_opt = expire_opt, fallbackAddress = fallbackAddress_opt, paymentPreimage = paymentPreimage_opt)).mapTo[PaymentRequest]
+ (appKit.paymentHandler ? ReceivePayment(description = description, amount_opt = amount_opt, expirySeconds_opt = expire_opt, fallbackAddress = fallbackAddress_opt, paymentPreimage = paymentPreimage_opt)).mapTo[PaymentRequest]
}
- override def findRoute(targetNodeId: PublicKey, amountMsat: Long, assistedRoutes: Seq[Seq[PaymentRequest.ExtraHop]] = Seq.empty)(implicit timeout: Timeout): Future[RouteResponse] = {
- (appKit.router ? RouteRequest(appKit.nodeParams.nodeId, targetNodeId, amountMsat, assistedRoutes)).mapTo[RouteResponse]
+ override def findRoute(targetNodeId: PublicKey, amount: MilliSatoshi, assistedRoutes: Seq[Seq[PaymentRequest.ExtraHop]] = Seq.empty)(implicit timeout: Timeout): Future[RouteResponse] = {
+ (appKit.router ? RouteRequest(appKit.nodeParams.nodeId, targetNodeId, amount, assistedRoutes)).mapTo[RouteResponse]
}
- override def sendToRoute(route: Seq[PublicKey], amountMsat: Long, paymentHash: ByteVector32, finalCltvExpiry: Long)(implicit timeout: Timeout): Future[UUID] = {
- (appKit.paymentInitiator ? SendPaymentToRoute(amountMsat, paymentHash, route, finalCltvExpiry)).mapTo[UUID]
+ override def sendToRoute(route: Seq[PublicKey], amount: MilliSatoshi, paymentHash: ByteVector32, finalCltvExpiry: Long)(implicit timeout: Timeout): Future[UUID] = {
+ (appKit.paymentInitiator ? SendPaymentToRoute(amount, paymentHash, route, finalCltvExpiry)).mapTo[UUID]
}
- override def send(recipientNodeId: PublicKey, amountMsat: Long, paymentHash: ByteVector32, assistedRoutes: Seq[Seq[PaymentRequest.ExtraHop]] = Seq.empty, minFinalCltvExpiry_opt: Option[Long], maxAttempts_opt: Option[Int], feeThresholdSat_opt: Option[Long], maxFeePct_opt: Option[Double])(implicit timeout: Timeout): Future[UUID] = {
+ override def send(recipientNodeId: PublicKey, amount: MilliSatoshi, paymentHash: ByteVector32, assistedRoutes: Seq[Seq[PaymentRequest.ExtraHop]] = Seq.empty, minFinalCltvExpiry_opt: Option[Long], maxAttempts_opt: Option[Int], feeThreshold_opt: Option[Satoshi], maxFeePct_opt: Option[Double])(implicit timeout: Timeout): Future[UUID] = {
val maxAttempts = maxAttempts_opt.getOrElse(appKit.nodeParams.maxPaymentAttempts)
val defaultRouteParams = Router.getDefaultRouteParams(appKit.nodeParams.routerConf)
val routeParams = defaultRouteParams.copy(
maxFeePct = maxFeePct_opt.getOrElse(defaultRouteParams.maxFeePct),
- maxFeeBaseMsat = feeThresholdSat_opt.map(_ * 1000).getOrElse(defaultRouteParams.maxFeeBaseMsat)
+ maxFeeBase = feeThreshold_opt.map(_.toMilliSatoshi).getOrElse(defaultRouteParams.maxFeeBase)
)
val sendPayment = minFinalCltvExpiry_opt match {
- case Some(minCltv) => SendPayment(amountMsat, paymentHash, recipientNodeId, assistedRoutes, finalCltvExpiry = minCltv, maxAttempts = maxAttempts, routeParams = Some(routeParams))
- case None => SendPayment(amountMsat, paymentHash, recipientNodeId, assistedRoutes, maxAttempts = maxAttempts, routeParams = Some(routeParams))
+ case Some(minCltv) => SendPayment(amount, paymentHash, recipientNodeId, assistedRoutes, finalCltvExpiry = minCltv, maxAttempts = maxAttempts, routeParams = Some(routeParams))
+ case None => SendPayment(amount, paymentHash, recipientNodeId, assistedRoutes, maxAttempts = maxAttempts, routeParams = Some(routeParams))
}
(appKit.paymentInitiator ? sendPayment).mapTo[UUID]
}
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 55f5fb2859..2daa66510f 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/NodeParams.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/NodeParams.scala
@@ -23,8 +23,8 @@ import java.util.concurrent.TimeUnit
import com.typesafe.config.{Config, ConfigFactory}
import fr.acinq.bitcoin.Crypto.PublicKey
-import fr.acinq.bitcoin.{Block, ByteVector32}
-import fr.acinq.eclair.NodeParams.{WatcherType}
+import fr.acinq.bitcoin.{Block, ByteVector32, Satoshi}
+import fr.acinq.eclair.NodeParams.WatcherType
import fr.acinq.eclair.blockchain.fee.{FeeEstimator, FeeTargets, OnChainFeeConf}
import fr.acinq.eclair.channel.Channel
import fr.acinq.eclair.crypto.KeyManager
@@ -33,7 +33,6 @@ import fr.acinq.eclair.router.RouterConf
import fr.acinq.eclair.tor.Socks5ProxyParams
import fr.acinq.eclair.wire.{Color, NodeAddress}
import scodec.bits.ByteVector
-
import scala.collection.JavaConversions._
import scala.concurrent.duration.FiniteDuration
@@ -47,17 +46,17 @@ case class NodeParams(keyManager: KeyManager,
globalFeatures: ByteVector,
localFeatures: ByteVector,
overrideFeatures: Map[PublicKey, (ByteVector, ByteVector)],
- dustLimitSatoshis: Long,
+ dustLimit: Satoshi,
onChainFeeConf: OnChainFeeConf,
maxHtlcValueInFlightMsat: UInt64,
maxAcceptedHtlcs: Int,
expiryDeltaBlocks: Int,
fulfillSafetyBeforeTimeoutBlocks: Int,
- htlcMinimumMsat: Int,
+ htlcMinimum: MilliSatoshi,
toRemoteDelayBlocks: Int,
maxToLocalDelayBlocks: Int,
minDepthBlocks: Int,
- feeBaseMsat: Int,
+ feeBase: MilliSatoshi,
feeProportionalMillionth: Int,
reserveToFundingRatio: Double,
maxReserveToFundingRatio: Double,
@@ -73,7 +72,7 @@ case class NodeParams(keyManager: KeyManager,
channelFlags: Byte,
watcherType: WatcherType,
paymentRequestExpiry: FiniteDuration,
- minFundingSatoshis: Long,
+ minFundingSatoshis: Satoshi,
routerConf: RouterConf,
socksProxy_opt: Option[Socks5ProxyParams],
maxPaymentAttempts: Int) {
@@ -137,7 +136,7 @@ object NodeParams {
case _ => BITCOIND
}
- val dustLimitSatoshis = config.getLong("dust-limit-satoshis")
+ val dustLimitSatoshis = Satoshi(config.getLong("dust-limit-satoshis"))
if (chainHash == Block.LivenetGenesisBlock.hash) {
require(dustLimitSatoshis >= Channel.MIN_DUSTLIMIT, s"dust limit must be greater than ${Channel.MIN_DUSTLIMIT}")
}
@@ -195,7 +194,7 @@ object NodeParams {
globalFeatures = ByteVector.fromValidHex(config.getString("global-features")),
localFeatures = ByteVector.fromValidHex(config.getString("local-features")),
overrideFeatures = overrideFeatures,
- dustLimitSatoshis = dustLimitSatoshis,
+ dustLimit = dustLimitSatoshis,
onChainFeeConf = OnChainFeeConf(
feeTargets = feeTargets,
feeEstimator = feeEstimator,
@@ -206,11 +205,11 @@ object NodeParams {
maxAcceptedHtlcs = maxAcceptedHtlcs,
expiryDeltaBlocks = expiryDeltaBlocks,
fulfillSafetyBeforeTimeoutBlocks = fulfillSafetyBeforeTimeoutBlocks,
- htlcMinimumMsat = config.getInt("htlc-minimum-msat"),
+ htlcMinimum = MilliSatoshi(config.getInt("htlc-minimum-msat")),
toRemoteDelayBlocks = config.getInt("to-remote-delay-blocks"),
maxToLocalDelayBlocks = config.getInt("max-to-local-delay-blocks"),
minDepthBlocks = config.getInt("mindepth-blocks"),
- feeBaseMsat = config.getInt("fee-base-msat"),
+ feeBase = MilliSatoshi(config.getInt("fee-base-msat")),
feeProportionalMillionth = config.getInt("fee-proportional-millionths"),
reserveToFundingRatio = config.getDouble("reserve-to-funding-ratio"),
maxReserveToFundingRatio = config.getDouble("max-reserve-to-funding-ratio"),
@@ -226,14 +225,14 @@ object NodeParams {
channelFlags = config.getInt("channel-flags").toByte,
watcherType = watcherType,
paymentRequestExpiry = FiniteDuration(config.getDuration("payment-request-expiry").getSeconds, TimeUnit.SECONDS),
- minFundingSatoshis = config.getLong("min-funding-satoshis"),
+ minFundingSatoshis = Satoshi(config.getLong("min-funding-satoshis")),
routerConf = RouterConf(
channelExcludeDuration = FiniteDuration(config.getDuration("router.channel-exclude-duration").getSeconds, TimeUnit.SECONDS),
routerBroadcastInterval = FiniteDuration(config.getDuration("router.broadcast-interval").getSeconds, TimeUnit.SECONDS),
randomizeRouteSelection = config.getBoolean("router.randomize-route-selection"),
searchMaxRouteLength = config.getInt("router.path-finding.max-route-length"),
searchMaxCltv = config.getInt("router.path-finding.max-cltv"),
- searchMaxFeeBaseSat = config.getLong("router.path-finding.fee-threshold-sat"),
+ searchMaxFeeBase = Satoshi(config.getLong("router.path-finding.fee-threshold-sat")),
searchMaxFeePct = config.getDouble("router.path-finding.max-fee-pct"),
searchHeuristicsEnabled = config.getBoolean("router.path-finding.heuristics-enable"),
searchRatioCltv = config.getDouble("router.path-finding.ratio-cltv"),
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/api/ExtraDirectives.scala b/eclair-core/src/main/scala/fr/acinq/eclair/api/ExtraDirectives.scala
index 9d5e1414f0..2973b53ec6 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/api/ExtraDirectives.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/api/ExtraDirectives.scala
@@ -22,10 +22,11 @@ import akka.http.scaladsl.model.StatusCodes._
import akka.http.scaladsl.server.{Directive1, Directives, MalformedFormFieldRejection, Route}
import fr.acinq.bitcoin.ByteVector32
import fr.acinq.bitcoin.Crypto.PublicKey
-import fr.acinq.eclair.ShortChannelId
+import fr.acinq.eclair.{MilliSatoshi, ShortChannelId}
import fr.acinq.eclair.api.FormParamExtractors.{sha256HashUnmarshaller, shortChannelIdUnmarshaller}
import fr.acinq.eclair.api.JsonSupport._
import fr.acinq.eclair.payment.PaymentRequest
+
import scala.concurrent.Future
import scala.util.{Failure, Success}
@@ -38,7 +39,7 @@ trait ExtraDirectives extends Directives {
val paymentHashFormParam = "paymentHash".as[ByteVector32](sha256HashUnmarshaller)
val fromFormParam = "from".as[Long]
val toFormParam = "to".as[Long]
- val amountMsatFormParam = "amountMsat".as[Long]
+ val amountMsatFormParam = "amountMsat".as[MilliSatoshi]
val invoiceFormParam = "invoice".as[PaymentRequest]
// custom directive to fail with HTTP 404 (and JSON response) if the element was not found
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/api/FormParamExtractors.scala b/eclair-core/src/main/scala/fr/acinq/eclair/api/FormParamExtractors.scala
index 17425cf368..cbe045faa8 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/api/FormParamExtractors.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/api/FormParamExtractors.scala
@@ -21,12 +21,13 @@ import java.util.UUID
import JsonSupport._
import akka.http.scaladsl.unmarshalling.Unmarshaller
import akka.util.Timeout
-import fr.acinq.bitcoin.ByteVector32
+import fr.acinq.bitcoin.{ByteVector32, Satoshi}
import fr.acinq.bitcoin.Crypto.PublicKey
-import fr.acinq.eclair.ShortChannelId
+import fr.acinq.eclair.{MilliSatoshi, ShortChannelId}
import fr.acinq.eclair.io.NodeURI
import fr.acinq.eclair.payment.PaymentRequest
import scodec.bits.ByteVector
+
import scala.concurrent.duration._
import scala.util.{Failure, Success, Try}
@@ -75,4 +76,13 @@ object FormParamExtractors {
}
}
+ implicit val satoshiUnmarshaller: Unmarshaller[String, Satoshi] = Unmarshaller.strict { str =>
+ Satoshi(str.toLong)
+ }
+
+ implicit val millisatoshiUnmarshaller: Unmarshaller[String, MilliSatoshi] = Unmarshaller.strict { str =>
+ MilliSatoshi(str.toLong)
+ }
+
+
}
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/api/JsonSerializers.scala b/eclair-core/src/main/scala/fr/acinq/eclair/api/JsonSerializers.scala
index a1a586941f..203c6c7f35 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/api/JsonSerializers.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/api/JsonSerializers.scala
@@ -23,7 +23,7 @@ import com.google.common.net.HostAndPort
import de.heikoseeberger.akkahttpjson4s.Json4sSupport
import de.heikoseeberger.akkahttpjson4s.Json4sSupport.ShouldWritePretty
import fr.acinq.bitcoin.Crypto.{PrivateKey, PublicKey}
-import fr.acinq.bitcoin.{ByteVector32, ByteVector64, MilliSatoshi, OutPoint, Transaction}
+import fr.acinq.bitcoin.{ByteVector32, ByteVector64, OutPoint, Satoshi, Transaction}
import fr.acinq.eclair.channel.{ChannelVersion, State}
import fr.acinq.eclair.crypto.ShaChain
import fr.acinq.eclair.db.OutgoingPaymentStatus
@@ -32,7 +32,7 @@ import fr.acinq.eclair.router.RouteResponse
import fr.acinq.eclair.transactions.Direction
import fr.acinq.eclair.transactions.Transactions.{InputInfo, TransactionWithInputInfo}
import fr.acinq.eclair.wire._
-import fr.acinq.eclair.{ShortChannelId, UInt64}
+import fr.acinq.eclair.{MilliSatoshi, ShortChannelId, UInt64}
import org.json4s.JsonAST._
import org.json4s.{CustomKeySerializer, CustomSerializer, TypeHints, jackson}
import scodec.bits.ByteVector
@@ -57,6 +57,10 @@ class UInt64Serializer extends CustomSerializer[UInt64](format => ({ null }, {
case x: UInt64 => JInt(x.toBigInt)
}))
+class SatoshiSerializer extends CustomSerializer[Satoshi](format => ({ null }, {
+ case x: Satoshi => JInt(x.amount)
+}))
+
class MilliSatoshiSerializer extends CustomSerializer[MilliSatoshi](format => ({ null }, {
case x: MilliSatoshi => JInt(x.amount)
}))
@@ -187,6 +191,7 @@ object JsonSupport extends Json4sSupport {
new ByteVector32Serializer +
new ByteVector64Serializer +
new UInt64Serializer +
+ new SatoshiSerializer +
new MilliSatoshiSerializer +
new ShortChannelIdSerializer +
new StateSerializer +
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 3d781cadc5..7d50d75217 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
@@ -31,14 +31,14 @@ import akka.stream.scaladsl.{BroadcastHub, Flow, Keep, Source}
import akka.stream.{ActorMaterializer, OverflowStrategy}
import akka.util.Timeout
import com.google.common.net.HostAndPort
-import fr.acinq.bitcoin.ByteVector32
+import fr.acinq.bitcoin.{ByteVector32, Satoshi}
import fr.acinq.bitcoin.Crypto.PublicKey
import fr.acinq.eclair.api.FormParamExtractors._
import fr.acinq.eclair.api.JsonSupport.CustomTypeHints
import fr.acinq.eclair.io.NodeURI
import fr.acinq.eclair.payment.PaymentLifecycle.PaymentFailed
import fr.acinq.eclair.payment.{PaymentReceived, PaymentRequest, _}
-import fr.acinq.eclair.{Eclair, ShortChannelId}
+import fr.acinq.eclair.{Eclair, MilliSatoshi, ShortChannelId}
import grizzled.slf4j.Logging
import org.json4s.jackson.Serialization
import scodec.bits.ByteVector
@@ -156,14 +156,14 @@ trait Service extends ExtraDirectives with Logging {
}
} ~
path("open") {
- formFields(nodeIdFormParam, "fundingSatoshis".as[Long], "pushMsat".as[Long].?, "fundingFeerateSatByte".as[Long].?, "channelFlags".as[Int].?, "openTimeoutSeconds".as[Timeout].?) {
+ formFields(nodeIdFormParam, "fundingSatoshis".as[Satoshi], "pushMsat".as[MilliSatoshi].?, "fundingFeerateSatByte".as[Long].?, "channelFlags".as[Int].?, "openTimeoutSeconds".as[Timeout].?) {
(nodeId, fundingSatoshis, pushMsat, fundingFeerateSatByte, channelFlags, openTimeout_opt) =>
complete(eclairApi.open(nodeId, fundingSatoshis, pushMsat, fundingFeerateSatByte, channelFlags, openTimeout_opt))
}
} ~
path("updaterelayfee") {
withChannelIdentifier { channelIdentifier =>
- formFields("feeBaseMsat".as[Long], "feeProportionalMillionths".as[Long]) { (feeBase, feeProportional) =>
+ formFields("feeBaseMsat".as[MilliSatoshi], "feeProportionalMillionths".as[Long]) { (feeBase, feeProportional) =>
complete(eclairApi.updateRelayFee(channelIdentifier, feeBase, feeProportional))
}
}
@@ -206,7 +206,7 @@ trait Service extends ExtraDirectives with Logging {
} ~
path("findroute") {
formFields(invoiceFormParam, amountMsatFormParam.?) {
- case (invoice@PaymentRequest(_, Some(amount), _, nodeId, _, _), None) => complete(eclairApi.findRoute(nodeId, amount.toLong, invoice.routingInfo))
+ case (invoice@PaymentRequest(_, Some(amount), _, nodeId, _, _), None) => complete(eclairApi.findRoute(nodeId, amount, invoice.routingInfo))
case (invoice, Some(overrideAmount)) => complete(eclairApi.findRoute(invoice.nodeId, overrideAmount, invoice.routingInfo))
case _ => reject(MalformedFormFieldRejection("invoice", "The invoice must have an amount or you need to specify one using 'amountMsat'"))
}
@@ -222,16 +222,16 @@ trait Service extends ExtraDirectives with Logging {
}
} ~
path("payinvoice") {
- formFields(invoiceFormParam, amountMsatFormParam.?, "maxAttempts".as[Int].?, "feeThresholdSat".as[Long].?, "maxFeePct".as[Double].?) {
+ formFields(invoiceFormParam, amountMsatFormParam.?, "maxAttempts".as[Int].?, "feeThresholdSat".as[Satoshi].?, "maxFeePct".as[Double].?) {
case (invoice@PaymentRequest(_, Some(amount), _, nodeId, _, _), None, maxAttempts, feeThresholdSat_opt, maxFeePct_opt) =>
- complete(eclairApi.send(nodeId, amount.toLong, invoice.paymentHash, invoice.routingInfo, invoice.minFinalCltvExpiry, maxAttempts, feeThresholdSat_opt, maxFeePct_opt))
+ complete(eclairApi.send(nodeId, amount, invoice.paymentHash, invoice.routingInfo, invoice.minFinalCltvExpiry, maxAttempts, feeThresholdSat_opt, maxFeePct_opt))
case (invoice, Some(overrideAmount), maxAttempts, feeThresholdSat_opt, maxFeePct_opt) =>
complete(eclairApi.send(invoice.nodeId, overrideAmount, invoice.paymentHash, invoice.routingInfo, invoice.minFinalCltvExpiry, maxAttempts, feeThresholdSat_opt, maxFeePct_opt))
case _ => reject(MalformedFormFieldRejection("invoice", "The invoice must have an amount or you need to specify one using the field 'amountMsat'"))
}
} ~
path("sendtonode") {
- formFields(amountMsatFormParam, paymentHashFormParam, nodeIdFormParam, "maxAttempts".as[Int].?, "feeThresholdSat".as[Long].?, "maxFeePct".as[Double].?) { (amountMsat, paymentHash, nodeId, maxAttempts_opt, feeThresholdSat_opt, maxFeePct_opt) =>
+ formFields(amountMsatFormParam, paymentHashFormParam, nodeIdFormParam, "maxAttempts".as[Int].?, "feeThresholdSat".as[Satoshi].?, "maxFeePct".as[Double].?) { (amountMsat, paymentHash, nodeId, maxAttempts_opt, feeThresholdSat_opt, maxFeePct_opt) =>
complete(eclairApi.send(nodeId, amountMsat, paymentHash, maxAttempts_opt = maxAttempts_opt, feeThresholdSat_opt = feeThresholdSat_opt, maxFeePct_opt = maxFeePct_opt))
}
} ~
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 72585ee2fd..d095f595fb 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
@@ -20,7 +20,7 @@ import akka.actor.{ActorRef, FSM, OneForOneStrategy, Props, Status, SupervisorSt
import akka.event.Logging.MDC
import akka.pattern.pipe
import fr.acinq.bitcoin.Crypto.{PrivateKey, PublicKey, sha256}
-import fr.acinq.bitcoin._
+import fr.acinq.bitcoin.{ByteVector32, OutPoint, Satoshi, Script, ScriptFlags, Transaction}
import fr.acinq.eclair._
import fr.acinq.eclair.blockchain._
import fr.acinq.eclair.channel.Helpers.{Closing, Funding}
@@ -48,11 +48,11 @@ object Channel {
val ANNOUNCEMENTS_MINCONF = 6
// https://github.com/lightningnetwork/lightning-rfc/blob/master/02-peer-protocol.md#requirements
- val MAX_FUNDING_SATOSHIS = 16777216L // = 2^24
+ val MAX_FUNDING = Satoshi(16777216L) // = 2^24
val MAX_ACCEPTED_HTLCS = 483
// we don't want the counterparty to use a dust limit lower than that, because they wouldn't only hurt themselves we may need them to publish their commit tx in certain cases (backup/restore)
- val MIN_DUSTLIMIT = 546
+ val MIN_DUSTLIMIT = Satoshi(546)
// we won't exchange more than this many signatures when negotiating the closing fee
val MAX_NEGOTIATION_ITERATIONS = 20
@@ -152,10 +152,10 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId
temporaryChannelId = temporaryChannelId,
fundingSatoshis = fundingSatoshis,
pushMsat = pushMsat,
- dustLimitSatoshis = localParams.dustLimitSatoshis,
+ dustLimitSatoshis = localParams.dustLimit,
maxHtlcValueInFlightMsat = localParams.maxHtlcValueInFlightMsat,
- channelReserveSatoshis = localParams.channelReserveSatoshis,
- htlcMinimumMsat = localParams.htlcMinimumMsat,
+ channelReserveSatoshis = localParams.channelReserve,
+ htlcMinimumMsat = localParams.htlcMinimum,
feeratePerKw = initialFeeratePerKw,
toSelfDelay = localParams.toSelfDelay,
maxAcceptedHtlcs = localParams.maxAcceptedHtlcs,
@@ -227,7 +227,7 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId
// we rebuild a new channel_update with values from the configuration because they may have changed while eclair was down
val candidateChannelUpdate = Announcements.makeChannelUpdate(nodeParams.chainHash, nodeParams.privateKey, remoteNodeId, normal.channelUpdate.shortChannelId, nodeParams.expiryDeltaBlocks,
- normal.commitments.remoteParams.htlcMinimumMsat, normal.channelUpdate.feeBaseMsat, normal.channelUpdate.feeProportionalMillionths, normal.commitments.localCommit.spec.totalFunds, enable = Announcements.isEnabled(normal.channelUpdate.channelFlags))
+ normal.commitments.remoteParams.htlcMinimum, normal.channelUpdate.feeBaseMsat, normal.channelUpdate.feeProportionalMillionths, normal.commitments.localCommit.spec.totalFunds, enable = Announcements.isEnabled(normal.channelUpdate.channelFlags))
val channelUpdate1 = if (Announcements.areSame(candidateChannelUpdate, normal.channelUpdate)) {
// if there was no configuration change we keep the existing channel update
normal.channelUpdate
@@ -274,11 +274,11 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId
// TODO: maybe also check uniqueness of temporary channel id
val minimumDepth = nodeParams.minDepthBlocks
val accept = AcceptChannel(temporaryChannelId = open.temporaryChannelId,
- dustLimitSatoshis = localParams.dustLimitSatoshis,
+ dustLimitSatoshis = localParams.dustLimit,
maxHtlcValueInFlightMsat = localParams.maxHtlcValueInFlightMsat,
- channelReserveSatoshis = localParams.channelReserveSatoshis,
+ channelReserveSatoshis = localParams.channelReserve,
minimumDepth = minimumDepth,
- htlcMinimumMsat = localParams.htlcMinimumMsat,
+ htlcMinimumMsat = localParams.htlcMinimum,
toSelfDelay = localParams.toSelfDelay,
maxAcceptedHtlcs = localParams.maxAcceptedHtlcs,
fundingPubkey = keyManager.fundingPublicKey(localParams.channelKeyPath).publicKey,
@@ -289,10 +289,10 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId
firstPerCommitmentPoint = keyManager.commitmentPoint(localParams.channelKeyPath, 0))
val remoteParams = RemoteParams(
nodeId = remoteNodeId,
- dustLimitSatoshis = open.dustLimitSatoshis,
+ dustLimit = open.dustLimitSatoshis,
maxHtlcValueInFlightMsat = open.maxHtlcValueInFlightMsat,
- channelReserveSatoshis = open.channelReserveSatoshis, // remote requires local to keep this much satoshis as direct payment
- htlcMinimumMsat = open.htlcMinimumMsat,
+ channelReserve = open.channelReserveSatoshis, // remote requires local to keep this much satoshis as direct payment
+ htlcMinimum = open.htlcMinimumMsat,
toSelfDelay = open.toSelfDelay,
maxAcceptedHtlcs = open.maxAcceptedHtlcs,
fundingPubKey = open.fundingPubkey,
@@ -322,10 +322,10 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId
// TODO: check equality of temporaryChannelId? or should be done upstream
val remoteParams = RemoteParams(
nodeId = remoteNodeId,
- dustLimitSatoshis = accept.dustLimitSatoshis,
+ dustLimit = accept.dustLimitSatoshis,
maxHtlcValueInFlightMsat = accept.maxHtlcValueInFlightMsat,
- channelReserveSatoshis = accept.channelReserveSatoshis, // remote requires local to keep this much satoshis as direct payment
- htlcMinimumMsat = accept.htlcMinimumMsat,
+ channelReserve = accept.channelReserveSatoshis, // remote requires local to keep this much satoshis as direct payment
+ htlcMinimum = accept.htlcMinimumMsat,
toSelfDelay = accept.toSelfDelay,
maxAcceptedHtlcs = accept.maxAcceptedHtlcs,
fundingPubKey = accept.fundingPubkey,
@@ -338,7 +338,7 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId
log.debug(s"remote params: $remoteParams")
val localFundingPubkey = keyManager.fundingPublicKey(localParams.channelKeyPath).publicKey
val fundingPubkeyScript = Script.write(Script.pay2wsh(Scripts.multiSig2of2(localFundingPubkey, remoteParams.fundingPubKey)))
- wallet.makeFundingTx(fundingPubkeyScript, Satoshi(fundingSatoshis), fundingTxFeeratePerKw).pipeTo(self)
+ wallet.makeFundingTx(fundingPubkeyScript, fundingSatoshis, fundingTxFeeratePerKw).pipeTo(self)
goto(WAIT_FOR_FUNDING_INTERNAL) using DATA_WAIT_FOR_FUNDING_INTERNAL(temporaryChannelId, localParams, remoteParams, fundingSatoshis, pushMsat, initialFeeratePerKw, accept.firstPerCommitmentPoint, open)
}
@@ -360,9 +360,9 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId
})
when(WAIT_FOR_FUNDING_INTERNAL)(handleExceptions {
- case Event(MakeFundingTxResponse(fundingTx, fundingTxOutputIndex, fundingTxFee), DATA_WAIT_FOR_FUNDING_INTERNAL(temporaryChannelId, localParams, remoteParams, fundingSatoshis, pushMsat, initialFeeratePerKw, remoteFirstPerCommitmentPoint, open)) =>
+ case Event(MakeFundingTxResponse(fundingTx, fundingTxOutputIndex, fundingTxFee), DATA_WAIT_FOR_FUNDING_INTERNAL(temporaryChannelId, localParams, remoteParams, fundingAmount, pushMsat, initialFeeratePerKw, remoteFirstPerCommitmentPoint, open)) =>
// let's create the first commitment tx that spends the yet uncommitted funding tx
- val (localSpec, localCommitTx, remoteSpec, remoteCommitTx) = Funding.makeFirstCommitTxs(keyManager, temporaryChannelId, localParams, remoteParams, fundingSatoshis, pushMsat, initialFeeratePerKw, fundingTx.hash, fundingTxOutputIndex, remoteFirstPerCommitmentPoint, nodeParams.onChainFeeConf.maxFeerateMismatch)
+ val (localSpec, localCommitTx, remoteSpec, remoteCommitTx) = Funding.makeFirstCommitTxs(keyManager, temporaryChannelId, localParams, remoteParams, fundingAmount, pushMsat, initialFeeratePerKw, fundingTx.hash, fundingTxOutputIndex, remoteFirstPerCommitmentPoint, nodeParams.onChainFeeConf.maxFeerateMismatch)
require(fundingTx.txOut(fundingTxOutputIndex).publicKeyScript == localCommitTx.input.txOut.publicKeyScript, s"pubkey script mismatch!")
val localSigOfRemoteTx = keyManager.sign(remoteCommitTx, keyManager.fundingPublicKey(localParams.channelKeyPath))
// signature of their initial commitment tx that pays remote pushMsat
@@ -401,9 +401,9 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId
})
when(WAIT_FOR_FUNDING_CREATED)(handleExceptions {
- case Event(FundingCreated(_, fundingTxHash, fundingTxOutputIndex, remoteSig), d@DATA_WAIT_FOR_FUNDING_CREATED(temporaryChannelId, localParams, remoteParams, fundingSatoshis, pushMsat, initialFeeratePerKw, remoteFirstPerCommitmentPoint, channelFlags, _)) =>
+ case Event(FundingCreated(_, fundingTxHash, fundingTxOutputIndex, remoteSig), d@DATA_WAIT_FOR_FUNDING_CREATED(temporaryChannelId, localParams, remoteParams, fundingAmount, pushMsat, initialFeeratePerKw, remoteFirstPerCommitmentPoint, channelFlags, _)) =>
// they fund the channel with their funding tx, so the money is theirs (but we are paid pushMsat)
- val (localSpec, localCommitTx, remoteSpec, remoteCommitTx) = Funding.makeFirstCommitTxs(keyManager, temporaryChannelId, localParams, remoteParams, fundingSatoshis: Long, pushMsat, initialFeeratePerKw, fundingTxHash, fundingTxOutputIndex, remoteFirstPerCommitmentPoint, nodeParams.onChainFeeConf.maxFeerateMismatch)
+ val (localSpec, localCommitTx, remoteSpec, remoteCommitTx) = Funding.makeFirstCommitTxs(keyManager, temporaryChannelId, localParams, remoteParams, fundingAmount, pushMsat, initialFeeratePerKw, fundingTxHash, fundingTxOutputIndex, remoteFirstPerCommitmentPoint, nodeParams.onChainFeeConf.maxFeerateMismatch)
// check remote signature validity
val localSigOfLocalTx = keyManager.sign(localCommitTx, keyManager.fundingPublicKey(localParams.channelKeyPath))
@@ -561,7 +561,7 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId
blockchain ! WatchConfirmed(self, commitments.commitInput.outPoint.txid, commitments.commitInput.txOut.publicKeyScript, ANNOUNCEMENTS_MINCONF, BITCOIN_FUNDING_DEEPLYBURIED)
context.system.eventStream.publish(ShortChannelIdAssigned(self, commitments.channelId, shortChannelId))
// we create a channel_update early so that we can use it to send payments through this channel, but it won't be propagated to other nodes since the channel is not yet announced
- val initialChannelUpdate = Announcements.makeChannelUpdate(nodeParams.chainHash, nodeParams.privateKey, remoteNodeId, shortChannelId, nodeParams.expiryDeltaBlocks, d.commitments.remoteParams.htlcMinimumMsat, nodeParams.feeBaseMsat, nodeParams.feeProportionalMillionth, commitments.localCommit.spec.totalFunds, enable = Helpers.aboveReserve(d.commitments))
+ val initialChannelUpdate = Announcements.makeChannelUpdate(nodeParams.chainHash, nodeParams.privateKey, remoteNodeId, shortChannelId, nodeParams.expiryDeltaBlocks, d.commitments.remoteParams.htlcMinimum, nodeParams.feeBase, nodeParams.feeProportionalMillionth, commitments.localCommit.spec.totalFunds, enable = Helpers.aboveReserve(d.commitments))
// we need to periodically re-send channel updates, otherwise channel will be considered stale and get pruned by network
context.system.scheduler.schedule(initialDelay = REFRESH_CHANNEL_UPDATE_INTERVAL, interval = REFRESH_CHANNEL_UPDATE_INTERVAL, receiver = self, message = BroadcastChannelUpdate(PeriodicRefresh))
goto(NORMAL) using DATA_NORMAL(commitments.copy(remoteNextCommitInfo = Right(nextPerCommitmentPoint)), shortChannelId, buried = false, None, initialChannelUpdate, None, None) storing()
@@ -704,7 +704,7 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId
val nextCommitNumber = nextRemoteCommit.index
// we persist htlc data in order to be able to claim htlc outputs in case a revoked tx is published by our
// counterparty, so only htlcs above remote's dust_limit matter
- val trimmedHtlcs = Transactions.trimOfferedHtlcs(Satoshi(d.commitments.remoteParams.dustLimitSatoshis), nextRemoteCommit.spec) ++ Transactions.trimReceivedHtlcs(Satoshi(d.commitments.remoteParams.dustLimitSatoshis), nextRemoteCommit.spec)
+ val trimmedHtlcs = Transactions.trimOfferedHtlcs(d.commitments.remoteParams.dustLimit, nextRemoteCommit.spec) ++ Transactions.trimReceivedHtlcs(d.commitments.remoteParams.dustLimit, nextRemoteCommit.spec)
trimmedHtlcs collect {
case DirectedHtlc(_, u) =>
log.info(s"adding paymentHash=${u.paymentHash} cltvExpiry=${u.cltvExpiry} to htlcs db for commitNumber=$nextCommitNumber")
@@ -716,9 +716,9 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId
self ! BroadcastChannelUpdate(AboveReserve)
}
context.system.eventStream.publish(ChannelSignatureSent(self, commitments1))
- if (nextRemoteCommit.spec.toRemoteMsat != d.commitments.remoteCommit.spec.toRemoteMsat) {
+ if (nextRemoteCommit.spec.toRemote != d.commitments.remoteCommit.spec.toRemote) {
// we send this event only when our balance changes (note that remoteCommit.toRemote == toLocal)
- context.system.eventStream.publish(AvailableBalanceChanged(self, d.channelId, d.shortChannelId, nextRemoteCommit.spec.toRemoteMsat, commitments1))
+ context.system.eventStream.publish(AvailableBalanceChanged(self, d.channelId, d.shortChannelId, nextRemoteCommit.spec.toRemote, commitments1))
}
// we expect a quick response from our peer
setTimer(RevocationTimeout.toString, RevocationTimeout(commitments1.remoteCommit.index, peer = context.parent), timeout = nodeParams.revocationTimeout, repeat = false)
@@ -1159,21 +1159,21 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId
when(NEGOTIATING)(handleExceptions {
case Event(c@ClosingSigned(_, remoteClosingFee, remoteSig), d: DATA_NEGOTIATING) =>
log.info(s"received closingFeeSatoshis=$remoteClosingFee")
- Closing.checkClosingSignature(keyManager, d.commitments, d.localShutdown.scriptPubKey, d.remoteShutdown.scriptPubKey, Satoshi(remoteClosingFee), remoteSig) match {
+ Closing.checkClosingSignature(keyManager, d.commitments, d.localShutdown.scriptPubKey, d.remoteShutdown.scriptPubKey, remoteClosingFee, remoteSig) match {
case Success(signedClosingTx) if d.closingTxProposed.last.lastOption.map(_.localClosingSigned.feeSatoshis).contains(remoteClosingFee) || d.closingTxProposed.flatten.size >= MAX_NEGOTIATION_ITERATIONS =>
// we close when we converge or when there were too many iterations
handleMutualClose(signedClosingTx, Left(d.copy(bestUnpublishedClosingTx_opt = Some(signedClosingTx))))
case Success(signedClosingTx) =>
// if we are fundee and we were waiting for them to send their first closing_signed, we don't have a lastLocalClosingFee, so we compute a firstClosingFee
- val lastLocalClosingFee = d.closingTxProposed.last.lastOption.map(_.localClosingSigned.feeSatoshis).map(Satoshi)
+ val lastLocalClosingFee = d.closingTxProposed.last.lastOption.map(_.localClosingSigned.feeSatoshis)
val nextClosingFee = Closing.nextClosingFee(
localClosingFee = lastLocalClosingFee.getOrElse(Closing.firstClosingFee(d.commitments, d.localShutdown.scriptPubKey, d.remoteShutdown.scriptPubKey, nodeParams.onChainFeeConf.feeEstimator, nodeParams.onChainFeeConf.feeTargets)),
- remoteClosingFee = Satoshi(remoteClosingFee))
+ remoteClosingFee = remoteClosingFee)
val (closingTx, closingSigned) = Closing.makeClosingTx(keyManager, d.commitments, d.localShutdown.scriptPubKey, d.remoteShutdown.scriptPubKey, nextClosingFee)
if (lastLocalClosingFee.contains(nextClosingFee)) {
// next computed fee is the same than the one we previously sent (probably because of rounding), let's close now
handleMutualClose(signedClosingTx, Left(d.copy(bestUnpublishedClosingTx_opt = Some(signedClosingTx))))
- } else if (nextClosingFee == Satoshi(remoteClosingFee)) {
+ } else if (nextClosingFee == remoteClosingFee) {
// we have converged!
val closingTxProposed1 = d.closingTxProposed match {
case previousNegotiations :+ currentNegotiation => previousNegotiations :+ (currentNegotiation :+ ClosingTxProposed(closingTx.tx, closingSigned))
@@ -1310,9 +1310,9 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId
}
// we may need to fail some htlcs in case a commitment tx was published and they have reached the timeout threshold
val timedoutHtlcs =
- Closing.timedoutHtlcs(d.commitments.localCommit, Satoshi(d.commitments.localParams.dustLimitSatoshis), tx) ++
- Closing.timedoutHtlcs(d.commitments.remoteCommit, Satoshi(d.commitments.remoteParams.dustLimitSatoshis), tx) ++
- d.commitments.remoteNextCommitInfo.left.toSeq.flatMap(r => Closing.timedoutHtlcs(r.nextRemoteCommit, Satoshi(d.commitments.remoteParams.dustLimitSatoshis), tx))
+ Closing.timedoutHtlcs(d.commitments.localCommit, d.commitments.localParams.dustLimit, tx) ++
+ Closing.timedoutHtlcs(d.commitments.remoteCommit, d.commitments.remoteParams.dustLimit, tx) ++
+ d.commitments.remoteNextCommitInfo.left.toSeq.flatMap(r => Closing.timedoutHtlcs(r.nextRemoteCommit, d.commitments.remoteParams.dustLimit, tx))
timedoutHtlcs.foreach { add =>
d.commitments.originChannels.get(add.id) match {
case Some(origin) =>
@@ -1339,7 +1339,7 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId
Closing
.onchainOutgoingHtlcs(d.commitments.localCommit, d.commitments.remoteCommit, d.commitments.remoteNextCommitInfo.left.toOption.map(_.nextRemoteCommit), tx)
.map(add => (add, d.commitments.originChannels.get(add.id).collect { case Local(id, _) => id })) // we resolve the payment id if this was a local payment
- .collect { case (add, Some(id)) => context.system.eventStream.publish(PaymentSettlingOnChain(id, amount = MilliSatoshi(add.amountMsat), add.paymentHash)) }
+ .collect { case (add, Some(id)) => context.system.eventStream.publish(PaymentSettlingOnChain(id, amount = add.amountMsat, add.paymentHash)) }
// we update the channel data
val d1 = d.copy(localCommitPublished = localCommitPublished1, remoteCommitPublished = remoteCommitPublished1, nextRemoteCommitPublished = nextRemoteCommitPublished1, futureRemoteCommitPublished = futureRemoteCommitPublished1, revokedCommitPublished = revokedCommitPublished1)
// and we also send events related to fee
@@ -2207,7 +2207,7 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId
def origin(c: CMD_ADD_HTLC): Origin = c.upstream match {
case Left(id) => Local(id, Some(sender)) // we were the origin of the payment
- case Right(u) => Relayed(u.channelId, u.id, u.amountMsat, c.amountMsat) // this is a relayed payment
+ case Right(u) => Relayed(u.channelId, u.id, u.amountMsat, c.amount) // this is a relayed payment
}
def feePaid(fee: Satoshi, tx: Transaction, desc: String, channelId: ByteVector32): Unit = {
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/channel/ChannelEvents.scala b/eclair-core/src/main/scala/fr/acinq/eclair/channel/ChannelEvents.scala
index e9104a7db4..e80ff51eca 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/channel/ChannelEvents.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/channel/ChannelEvents.scala
@@ -19,7 +19,8 @@ package fr.acinq.eclair.channel
import akka.actor.ActorRef
import fr.acinq.bitcoin.Crypto.PublicKey
import fr.acinq.bitcoin.{ByteVector32, Satoshi, Transaction}
-import fr.acinq.eclair.ShortChannelId
+import fr.acinq.eclair.{MilliSatoshi, ShortChannelId}
+import fr.acinq.eclair.api.MilliSatoshiSerializer
import fr.acinq.eclair.channel.Channel.ChannelError
import fr.acinq.eclair.channel.Helpers.Closing.ClosingType
import fr.acinq.eclair.wire.{ChannelAnnouncement, ChannelUpdate}
@@ -53,7 +54,7 @@ case class ChannelErrorOccured(channel: ActorRef, channelId: ByteVector32, remot
case class NetworkFeePaid(channel: ActorRef, remoteNodeId: PublicKey, channelId: ByteVector32, tx: Transaction, fee: Satoshi, txType: String) extends ChannelEvent
// NB: this event is only sent when the channel is available
-case class AvailableBalanceChanged(channel: ActorRef, channelId: ByteVector32, shortChannelId: ShortChannelId, localBalanceMsat: Long, commitments: Commitments) extends ChannelEvent
+case class AvailableBalanceChanged(channel: ActorRef, channelId: ByteVector32, shortChannelId: ShortChannelId, localBalance: MilliSatoshi, commitments: Commitments) extends ChannelEvent
case class ChannelPersisted(channel: ActorRef, remoteNodeId: PublicKey, channelId: ByteVector32, data: Data) extends ChannelEvent
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/channel/ChannelExceptions.scala b/eclair-core/src/main/scala/fr/acinq/eclair/channel/ChannelExceptions.scala
index 3546f22af6..56fc890eb5 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/channel/ChannelExceptions.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/channel/ChannelExceptions.scala
@@ -17,8 +17,8 @@
package fr.acinq.eclair.channel
import fr.acinq.bitcoin.Crypto.PrivateKey
-import fr.acinq.bitcoin.{ByteVector32, Transaction}
-import fr.acinq.eclair.UInt64
+import fr.acinq.bitcoin.{ByteVector32, Satoshi, Transaction}
+import fr.acinq.eclair.{MilliSatoshi, UInt64}
import fr.acinq.eclair.payment.Origin
import fr.acinq.eclair.wire.{ChannelUpdate, UpdateAddHtlc}
@@ -31,16 +31,16 @@ class ChannelException(val channelId: ByteVector32, message: String) extends Run
// @formatter:off
case class DebugTriggeredException (override val channelId: ByteVector32) extends ChannelException(channelId, "debug-mode triggered failure")
case class InvalidChainHash (override val channelId: ByteVector32, local: ByteVector32, remote: ByteVector32) extends ChannelException(channelId, s"invalid chainHash (local=$local remote=$remote)")
-case class InvalidFundingAmount (override val channelId: ByteVector32, fundingSatoshis: Long, min: Long, max: Long) extends ChannelException(channelId, s"invalid funding_satoshis=$fundingSatoshis (min=$min max=$max)")
-case class InvalidPushAmount (override val channelId: ByteVector32, pushMsat: Long, max: Long) extends ChannelException(channelId, s"invalid pushMsat=$pushMsat (max=$max)")
+case class InvalidFundingAmount (override val channelId: ByteVector32, fundingAmount: Satoshi, min: Satoshi, max: Satoshi) extends ChannelException(channelId, s"invalid funding_satoshis=$fundingAmount (min=$min max=$max)")
+case class InvalidPushAmount (override val channelId: ByteVector32, pushAmount: MilliSatoshi, max: MilliSatoshi) extends ChannelException(channelId, s"invalid pushAmount=$pushAmount (max=$max)")
case class InvalidMaxAcceptedHtlcs (override val channelId: ByteVector32, maxAcceptedHtlcs: Int, max: Int) extends ChannelException(channelId, s"invalid max_accepted_htlcs=$maxAcceptedHtlcs (max=$max)")
-case class DustLimitTooSmall (override val channelId: ByteVector32, dustLimitSatoshis: Long, min: Long) extends ChannelException(channelId, s"dustLimitSatoshis=$dustLimitSatoshis is too small (min=$min)")
-case class DustLimitTooLarge (override val channelId: ByteVector32, dustLimitSatoshis: Long, max: Long) extends ChannelException(channelId, s"dustLimitSatoshis=$dustLimitSatoshis is too large (max=$max)")
-case class DustLimitAboveOurChannelReserve (override val channelId: ByteVector32, dustLimitSatoshis: Long, channelReserveSatoshis: Long) extends ChannelException(channelId, s"dustLimitSatoshis dustLimitSatoshis=$dustLimitSatoshis is above our channelReserveSatoshis=$channelReserveSatoshis")
+case class DustLimitTooSmall (override val channelId: ByteVector32, dustLimit: Satoshi, min: Satoshi) extends ChannelException(channelId, s"dustLimit=$dustLimit is too small (min=$min)")
+case class DustLimitTooLarge (override val channelId: ByteVector32, dustLimit: Satoshi, max: Satoshi) extends ChannelException(channelId, s"dustLimit=$dustLimit is too large (max=$max)")
+case class DustLimitAboveOurChannelReserve (override val channelId: ByteVector32, dustLimit: Satoshi, channelReserve: Satoshi) extends ChannelException(channelId, s"dustLimit=$dustLimit is above our channelReserve=$channelReserve")
case class ToSelfDelayTooHigh (override val channelId: ByteVector32, toSelfDelay: Int, max: Int) extends ChannelException(channelId, s"unreasonable to_self_delay=$toSelfDelay (max=$max)")
-case class ChannelReserveTooHigh (override val channelId: ByteVector32, channelReserveSatoshis: Long, reserveToFundingRatio: Double, maxReserveToFundingRatio: Double) extends ChannelException(channelId, s"channelReserveSatoshis too high: reserve=$channelReserveSatoshis fundingRatio=$reserveToFundingRatio maxFundingRatio=$maxReserveToFundingRatio")
-case class ChannelReserveBelowOurDustLimit (override val channelId: ByteVector32, channelReserveSatoshis: Long, dustLimitSatoshis: Long) extends ChannelException(channelId, s"their channelReserveSatoshis=$channelReserveSatoshis is below our dustLimitSatoshis=$dustLimitSatoshis")
-case class ChannelReserveNotMet (override val channelId: ByteVector32, toLocalMsat: Long, toRemoteMsat: Long, reserveSatoshis: Long) extends ChannelException(channelId, s"channel reserve is not met toLocalMsat=$toLocalMsat toRemoteMsat=$toRemoteMsat reserveSat=$reserveSatoshis")
+case class ChannelReserveTooHigh (override val channelId: ByteVector32, channelReserve: Satoshi, reserveToFundingRatio: Double, maxReserveToFundingRatio: Double) extends ChannelException(channelId, s"channelReserve too high: reserve=$channelReserve fundingRatio=$reserveToFundingRatio maxFundingRatio=$maxReserveToFundingRatio")
+case class ChannelReserveBelowOurDustLimit (override val channelId: ByteVector32, channelReserve: Satoshi, dustLimit: Satoshi) extends ChannelException(channelId, s"their channelReserve=$channelReserve is below our dustLimit=$dustLimit")
+case class ChannelReserveNotMet (override val channelId: ByteVector32, toLocal: MilliSatoshi, toRemote: MilliSatoshi, reserve: Satoshi) extends ChannelException(channelId, s"channel reserve is not met toLocal=$toLocal toRemote=$toRemote reserve=$reserve")
case class ChannelFundingError (override val channelId: ByteVector32) extends ChannelException(channelId, "channel funding error")
case class NoMoreHtlcsClosingInProgress (override val channelId: ByteVector32) extends ChannelException(channelId, "cannot send new htlcs, closing in progress")
case class ClosingAlreadyInProgress (override val channelId: ByteVector32) extends ChannelException(channelId, "closing already in progress")
@@ -57,21 +57,21 @@ case class FeerateTooDifferent (override val channelId: ByteVect
case class InvalidCommitmentSignature (override val channelId: ByteVector32, tx: Transaction) extends ChannelException(channelId, s"invalid commitment signature: tx=$tx")
case class InvalidHtlcSignature (override val channelId: ByteVector32, tx: Transaction) extends ChannelException(channelId, s"invalid htlc signature: tx=$tx")
case class InvalidCloseSignature (override val channelId: ByteVector32, tx: Transaction) extends ChannelException(channelId, s"invalid close signature: tx=$tx")
-case class InvalidCloseFee (override val channelId: ByteVector32, feeSatoshi: Long) extends ChannelException(channelId, s"invalid close fee: fee_satoshis=$feeSatoshi")
+case class InvalidCloseFee (override val channelId: ByteVector32, fee: Satoshi) extends ChannelException(channelId, s"invalid close fee: fee_satoshis=$fee")
case class HtlcSigCountMismatch (override val channelId: ByteVector32, expected: Int, actual: Int) extends ChannelException(channelId, s"htlc sig count mismatch: expected=$expected actual: $actual")
case class ForcedLocalCommit (override val channelId: ByteVector32) extends ChannelException(channelId, s"forced local commit")
case class UnexpectedHtlcId (override val channelId: ByteVector32, expected: Long, actual: Long) extends ChannelException(channelId, s"unexpected htlc id: expected=$expected actual=$actual")
case class ExpiryTooSmall (override val channelId: ByteVector32, minimum: Long, actual: Long, blockCount: Long) extends ChannelException(channelId, s"expiry too small: minimum=$minimum actual=$actual blockCount=$blockCount")
case class ExpiryTooBig (override val channelId: ByteVector32, maximum: Long, actual: Long, blockCount: Long) extends ChannelException(channelId, s"expiry too big: maximum=$maximum actual=$actual blockCount=$blockCount")
-case class HtlcValueTooSmall (override val channelId: ByteVector32, minimum: Long, actual: Long) extends ChannelException(channelId, s"htlc value too small: minimum=$minimum actual=$actual")
+case class HtlcValueTooSmall (override val channelId: ByteVector32, minimum: MilliSatoshi, actual: MilliSatoshi) extends ChannelException(channelId, s"htlc value too small: minimum=$minimum actual=$actual")
case class HtlcValueTooHighInFlight (override val channelId: ByteVector32, maximum: UInt64, actual: UInt64) extends ChannelException(channelId, s"in-flight htlcs hold too much value: maximum=$maximum actual=$actual")
case class TooManyAcceptedHtlcs (override val channelId: ByteVector32, maximum: Long) extends ChannelException(channelId, s"too many accepted htlcs: maximum=$maximum")
-case class InsufficientFunds (override val channelId: ByteVector32, amountMsat: Long, missingSatoshis: Long, reserveSatoshis: Long, feesSatoshis: Long) extends ChannelException(channelId, s"insufficient funds: missingSatoshis=$missingSatoshis reserveSatoshis=$reserveSatoshis fees=$feesSatoshis")
+case class InsufficientFunds (override val channelId: ByteVector32, amount: MilliSatoshi, missing: Satoshi, reserve: Satoshi, fees: Satoshi) extends ChannelException(channelId, s"insufficient funds: missing=$missing reserve=$reserve fees=$fees")
case class InvalidHtlcPreimage (override val channelId: ByteVector32, id: Long) extends ChannelException(channelId, s"invalid htlc preimage for htlc id=$id")
case class UnknownHtlcId (override val channelId: ByteVector32, id: Long) extends ChannelException(channelId, s"unknown htlc id=$id")
case class CannotExtractSharedSecret (override val channelId: ByteVector32, htlc: UpdateAddHtlc) extends ChannelException(channelId, s"can't extract shared secret: paymentHash=${htlc.paymentHash} onion=${htlc.onionRoutingPacket}")
case class FundeeCannotSendUpdateFee (override val channelId: ByteVector32) extends ChannelException(channelId, s"only the funder should send update_fee messages")
-case class CannotAffordFees (override val channelId: ByteVector32, missingSatoshis: Long, reserveSatoshis: Long, feesSatoshis: Long) extends ChannelException(channelId, s"can't pay the fee: missingSatoshis=$missingSatoshis reserveSatoshis=$reserveSatoshis feesSatoshis=$feesSatoshis")
+case class CannotAffordFees (override val channelId: ByteVector32, missing: Satoshi, reserve: Satoshi, fees: Satoshi) extends ChannelException(channelId, s"can't pay the fee: missing=$missing reserve=$reserve fees=$fees")
case class CannotSignWithoutChanges (override val channelId: ByteVector32) extends ChannelException(channelId, "cannot sign when there are no changes")
case class CannotSignBeforeRevocation (override val channelId: ByteVector32) extends ChannelException(channelId, "cannot sign until next revocation hash is received")
case class UnexpectedRevocation (override val channelId: ByteVector32) extends ChannelException(channelId, "received unexpected RevokeAndAck message")
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/channel/ChannelTypes.scala b/eclair-core/src/main/scala/fr/acinq/eclair/channel/ChannelTypes.scala
index 48e6d6b57f..151cf582d5 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/channel/ChannelTypes.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/channel/ChannelTypes.scala
@@ -21,10 +21,11 @@ import java.util.UUID
import akka.actor.ActorRef
import fr.acinq.bitcoin.Crypto.PublicKey
import fr.acinq.bitcoin.{ByteVector32, DeterministicWallet, OutPoint, Satoshi, Transaction}
+import fr.acinq.eclair.api.MilliSatoshiSerializer
import fr.acinq.eclair.transactions.CommitmentSpec
import fr.acinq.eclair.transactions.Transactions.CommitTx
import fr.acinq.eclair.wire.{AcceptChannel, ChannelAnnouncement, ChannelReestablish, ChannelUpdate, ClosingSigned, FailureMessage, FundingCreated, FundingLocked, FundingSigned, Init, OnionRoutingPacket, OpenChannel, Shutdown, UpdateAddHtlc}
-import fr.acinq.eclair.{ShortChannelId, UInt64}
+import fr.acinq.eclair.{MilliSatoshi, ShortChannelId, UInt64}
import scodec.bits.{BitVector, ByteVector}
@@ -75,7 +76,7 @@ case object ERR_INFORMATION_LEAK extends State
8888888888 Y8P 8888888888 888 Y888 888 "Y8888P"
*/
-case class INPUT_INIT_FUNDER(temporaryChannelId: ByteVector32, fundingSatoshis: Long, pushMsat: Long, initialFeeratePerKw: Long, fundingTxFeeratePerKw: Long, localParams: LocalParams, remote: ActorRef, remoteInit: Init, channelFlags: Byte)
+case class INPUT_INIT_FUNDER(temporaryChannelId: ByteVector32, fundingAmount: Satoshi, pushAmount: MilliSatoshi, initialFeeratePerKw: Long, fundingTxFeeratePerKw: Long, localParams: LocalParams, remote: ActorRef, remoteInit: Init, channelFlags: Byte)
case class INPUT_INIT_FUNDEE(temporaryChannelId: ByteVector32, localParams: LocalParams, remote: ActorRef, remoteInit: Init)
case object INPUT_CLOSE_COMPLETE_TIMEOUT // when requesting a mutual close, we wait for as much as this timeout, then unilateral close
case object INPUT_DISCONNECTED
@@ -106,14 +107,14 @@ case class BITCOIN_PARENT_TX_CONFIRMED(childTx: Transaction) extends BitcoinEven
*/
sealed trait Command
-final case class CMD_ADD_HTLC(amountMsat: Long, paymentHash: ByteVector32, cltvExpiry: Long, onion: OnionRoutingPacket, upstream: Either[UUID, UpdateAddHtlc], commit: Boolean = false, previousFailures: Seq[AddHtlcFailed] = Seq.empty) extends Command
+final case class CMD_ADD_HTLC(amount: MilliSatoshi, paymentHash: ByteVector32, cltvExpiry: Long, onion: OnionRoutingPacket, upstream: Either[UUID, UpdateAddHtlc], commit: Boolean = false, previousFailures: Seq[AddHtlcFailed] = Seq.empty) extends Command
final case class CMD_FULFILL_HTLC(id: Long, r: ByteVector32, commit: Boolean = false) extends Command
final case class CMD_FAIL_HTLC(id: Long, reason: Either[ByteVector, FailureMessage], commit: Boolean = false) extends Command
final case class CMD_FAIL_MALFORMED_HTLC(id: Long, onionHash: ByteVector32, failureCode: Int, commit: Boolean = false) extends Command
final case class CMD_UPDATE_FEE(feeratePerKw: Long, commit: Boolean = false) extends Command
final case object CMD_SIGN extends Command
final case class CMD_CLOSE(scriptPubKey: Option[ByteVector]) extends Command
-final case class CMD_UPDATE_RELAY_FEE(feeBaseMsat: Long, feeProportionalMillionths: Long) extends Command
+final case class CMD_UPDATE_RELAY_FEE(feeBase: MilliSatoshi, feeProportionalMillionths: Long) extends Command
final case object CMD_FORCECLOSE extends Command
final case object CMD_GETSTATE extends Command
final case object CMD_GETSTATEDATA extends Command
@@ -148,8 +149,8 @@ case class RevokedCommitPublished(commitTx: Transaction, claimMainOutputTx: Opti
final case class DATA_WAIT_FOR_OPEN_CHANNEL(initFundee: INPUT_INIT_FUNDEE) extends Data
final case class DATA_WAIT_FOR_ACCEPT_CHANNEL(initFunder: INPUT_INIT_FUNDER, lastSent: OpenChannel) extends Data
-final case class DATA_WAIT_FOR_FUNDING_INTERNAL(temporaryChannelId: ByteVector32, localParams: LocalParams, remoteParams: RemoteParams, fundingSatoshis: Long, pushMsat: Long, initialFeeratePerKw: Long, remoteFirstPerCommitmentPoint: PublicKey, lastSent: OpenChannel) extends Data
-final case class DATA_WAIT_FOR_FUNDING_CREATED(temporaryChannelId: ByteVector32, localParams: LocalParams, remoteParams: RemoteParams, fundingSatoshis: Long, pushMsat: Long, initialFeeratePerKw: Long, remoteFirstPerCommitmentPoint: PublicKey, channelFlags: Byte, lastSent: AcceptChannel) extends Data
+final case class DATA_WAIT_FOR_FUNDING_INTERNAL(temporaryChannelId: ByteVector32, localParams: LocalParams, remoteParams: RemoteParams, fundingAmount: Satoshi, pushAmount: MilliSatoshi, initialFeeratePerKw: Long, remoteFirstPerCommitmentPoint: PublicKey, lastSent: OpenChannel) extends Data
+final case class DATA_WAIT_FOR_FUNDING_CREATED(temporaryChannelId: ByteVector32, localParams: LocalParams, remoteParams: RemoteParams, fundingAmount: Satoshi, pushAmount: MilliSatoshi, initialFeeratePerKw: Long, remoteFirstPerCommitmentPoint: PublicKey, channelFlags: Byte, lastSent: AcceptChannel) extends Data
final case class DATA_WAIT_FOR_FUNDING_SIGNED(channelId: ByteVector32, localParams: LocalParams, remoteParams: RemoteParams, fundingTx: Transaction, fundingTxFee: Satoshi, localSpec: CommitmentSpec, localCommitTx: CommitTx, remoteCommit: RemoteCommit, channelFlags: Byte, lastSent: FundingCreated) extends Data
final case class DATA_WAIT_FOR_FUNDING_CONFIRMED(commitments: Commitments,
fundingTx: Option[Transaction],
@@ -191,10 +192,10 @@ final case class DATA_WAIT_FOR_REMOTE_PUBLISH_FUTURE_COMMITMENT(commitments: Com
final case class LocalParams(nodeId: PublicKey,
channelKeyPath: DeterministicWallet.KeyPath,
- dustLimitSatoshis: Long,
+ dustLimit: Satoshi,
maxHtlcValueInFlightMsat: UInt64,
- channelReserveSatoshis: Long,
- htlcMinimumMsat: Long,
+ channelReserve: Satoshi,
+ htlcMinimum: MilliSatoshi,
toSelfDelay: Int,
maxAcceptedHtlcs: Int,
isFunder: Boolean,
@@ -203,10 +204,10 @@ final case class LocalParams(nodeId: PublicKey,
localFeatures: ByteVector)
final case class RemoteParams(nodeId: PublicKey,
- dustLimitSatoshis: Long,
+ dustLimit: Satoshi,
maxHtlcValueInFlightMsat: UInt64,
- channelReserveSatoshis: Long,
- htlcMinimumMsat: Long,
+ channelReserve: Satoshi,
+ htlcMinimum: MilliSatoshi,
toSelfDelay: Int,
maxAcceptedHtlcs: Int,
fundingPubKey: PublicKey,
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/channel/Commitments.scala b/eclair-core/src/main/scala/fr/acinq/eclair/channel/Commitments.scala
index 7c1bace272..21533f0dba 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/channel/Commitments.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/channel/Commitments.scala
@@ -19,13 +19,15 @@ package fr.acinq.eclair.channel
import akka.event.LoggingAdapter
import fr.acinq.bitcoin.Crypto.{PrivateKey, PublicKey, sha256}
import fr.acinq.bitcoin.{ByteVector32, ByteVector64, Crypto, Satoshi}
+import fr.acinq.eclair
+import fr.acinq.eclair._
import fr.acinq.eclair.blockchain.fee.{FeeEstimator, FeeTargets}
import fr.acinq.eclair.crypto.{Generators, KeyManager, ShaChain, Sphinx}
import fr.acinq.eclair.payment._
import fr.acinq.eclair.transactions.Transactions._
import fr.acinq.eclair.transactions._
import fr.acinq.eclair.wire._
-import fr.acinq.eclair.{Globals, UInt64}
+import fr.acinq.eclair.{Globals, MilliSatoshi, UInt64}
// @formatter:off
case class LocalChanges(proposed: List[UpdateMessage], signed: List[UpdateMessage], acked: List[UpdateMessage]) {
@@ -84,16 +86,16 @@ case class Commitments(channelVersion: ChannelVersion,
val announceChannel: Boolean = (channelFlags & 0x01) != 0
- lazy val availableBalanceForSendMsat: Long = {
+ lazy val availableBalanceForSend: MilliSatoshi = {
val reduced = CommitmentSpec.reduce(remoteCommit.spec, remoteChanges.acked, localChanges.proposed)
- val feesMsat = if (localParams.isFunder) Transactions.commitTxFee(Satoshi(remoteParams.dustLimitSatoshis), reduced).amount * 1000 else 0
- math.max(reduced.toRemoteMsat - remoteParams.channelReserveSatoshis * 1000 - feesMsat, 0)
+ val feesMsat = if (localParams.isFunder) commitTxFee(remoteParams.dustLimit, reduced).toMilliSatoshi else MilliSatoshi(0)
+ maxOf(reduced.toRemote - remoteParams.channelReserve.toMilliSatoshi - feesMsat, MilliSatoshi(0))
}
- lazy val availableBalanceForReceiveMsat: Long = {
+ lazy val availableBalanceForReceive: MilliSatoshi = {
val reduced = CommitmentSpec.reduce(localCommit.spec, localChanges.acked, remoteChanges.proposed)
- val feesMsat = if (localParams.isFunder) 0 else Transactions.commitTxFee(Satoshi(localParams.dustLimitSatoshis), reduced).amount * 1000
- math.max(reduced.toRemoteMsat - localParams.channelReserveSatoshis * 1000 - feesMsat, 0)
+ val feesMsat = if (localParams.isFunder) MilliSatoshi(0) else commitTxFee(localParams.dustLimit, reduced).toMilliSatoshi
+ maxOf(reduced.toRemote - localParams.channelReserve.toMilliSatoshi - feesMsat, MilliSatoshi(0))
}
}
@@ -132,12 +134,12 @@ object Commitments {
return Left(ExpiryTooBig(commitments.channelId, maximum = maxExpiry, actual = cmd.cltvExpiry, blockCount = blockCount))
}
- if (cmd.amountMsat < commitments.remoteParams.htlcMinimumMsat) {
- return Left(HtlcValueTooSmall(commitments.channelId, minimum = commitments.remoteParams.htlcMinimumMsat, actual = cmd.amountMsat))
+ if (cmd.amount < commitments.remoteParams.htlcMinimum) {
+ return Left(HtlcValueTooSmall(commitments.channelId, minimum = commitments.remoteParams.htlcMinimum, actual = cmd.amount))
}
// let's compute the current commitment *as seen by them* with this change taken into account
- val add = UpdateAddHtlc(commitments.channelId, commitments.localNextHtlcId, cmd.amountMsat, cmd.paymentHash, cmd.cltvExpiry, cmd.onion)
+ val add = UpdateAddHtlc(commitments.channelId, commitments.localNextHtlcId, cmd.amount, cmd.paymentHash, cmd.cltvExpiry, cmd.onion)
// we increment the local htlc index and add an entry to the origins map
val commitments1 = addLocalProposal(commitments, add).copy(localNextHtlcId = commitments.localNextHtlcId + 1, originChannels = commitments.originChannels + (add.id -> origin))
// we need to base the next current commitment on the last sig we sent, even if we didn't yet receive their revocation
@@ -146,7 +148,7 @@ object Commitments {
// the HTLC we are about to create is outgoing, but from their point of view it is incoming
val outgoingHtlcs = reduced.htlcs.filter(_.direction == IN)
- val htlcValueInFlight = UInt64(outgoingHtlcs.map(_.add.amountMsat).sum)
+ val htlcValueInFlight = UInt64(outgoingHtlcs.map(_.add.amountMsat).sum.toLong)
if (htlcValueInFlight > commitments1.remoteParams.maxHtlcValueInFlightMsat) {
// TODO: this should be a specific UPDATE error
return Left(HtlcValueTooHighInFlight(commitments.channelId, maximum = commitments1.remoteParams.maxHtlcValueInFlightMsat, actual = htlcValueInFlight))
@@ -158,10 +160,10 @@ object Commitments {
// a node cannot spend pending incoming htlcs, and need to keep funds above the reserve required by the counterparty, after paying the fee
// we look from remote's point of view, so if local is funder remote doesn't pay the fees
- val fees = if (commitments1.localParams.isFunder) Transactions.commitTxFee(Satoshi(commitments1.remoteParams.dustLimitSatoshis), reduced).amount else 0
- val missing = reduced.toRemoteMsat / 1000 - commitments1.remoteParams.channelReserveSatoshis - fees
- if (missing < 0) {
- return Left(InsufficientFunds(commitments.channelId, amountMsat = cmd.amountMsat, missingSatoshis = -1 * missing, reserveSatoshis = commitments1.remoteParams.channelReserveSatoshis, feesSatoshis = fees))
+ val fees = if (commitments1.localParams.isFunder) commitTxFee(commitments1.remoteParams.dustLimit, reduced) else Satoshi(0)
+ val missing = reduced.toRemote.truncateToSatoshi - commitments1.remoteParams.channelReserve - fees
+ if (missing < Satoshi(0)) {
+ return Left(InsufficientFunds(commitments.channelId, amount = cmd.amount, missing = -missing, reserve = commitments1.remoteParams.channelReserve, fees = fees))
}
Right(commitments1, add)
@@ -172,8 +174,8 @@ object Commitments {
throw UnexpectedHtlcId(commitments.channelId, expected = commitments.remoteNextHtlcId, actual = add.id)
}
- if (add.amountMsat < commitments.localParams.htlcMinimumMsat) {
- throw HtlcValueTooSmall(commitments.channelId, minimum = commitments.localParams.htlcMinimumMsat, actual = add.amountMsat)
+ if (add.amountMsat < commitments.localParams.htlcMinimum) {
+ throw HtlcValueTooSmall(commitments.channelId, minimum = commitments.localParams.htlcMinimum, actual = add.amountMsat)
}
// let's compute the current commitment *as seen by us* including this change
@@ -181,7 +183,7 @@ object Commitments {
val reduced = CommitmentSpec.reduce(commitments1.localCommit.spec, commitments1.localChanges.acked, commitments1.remoteChanges.proposed)
val incomingHtlcs = reduced.htlcs.filter(_.direction == IN)
- val htlcValueInFlight = UInt64(incomingHtlcs.map(_.add.amountMsat).sum)
+ val htlcValueInFlight = UInt64(incomingHtlcs.map(_.add.amountMsat).sum.toLong)
if (htlcValueInFlight > commitments1.localParams.maxHtlcValueInFlightMsat) {
throw HtlcValueTooHighInFlight(commitments.channelId, maximum = commitments1.localParams.maxHtlcValueInFlightMsat, actual = htlcValueInFlight)
}
@@ -191,10 +193,10 @@ object Commitments {
}
// a node cannot spend pending incoming htlcs, and need to keep funds above the reserve required by the counterparty, after paying the fee
- val fees = if (commitments1.localParams.isFunder) 0 else Transactions.commitTxFee(Satoshi(commitments1.localParams.dustLimitSatoshis), reduced).amount
- val missing = reduced.toRemoteMsat / 1000 - commitments1.localParams.channelReserveSatoshis - fees
- if (missing < 0) {
- throw InsufficientFunds(commitments.channelId, amountMsat = add.amountMsat, missingSatoshis = -1 * missing, reserveSatoshis = commitments1.localParams.channelReserveSatoshis, feesSatoshis = fees)
+ val fees = if (commitments1.localParams.isFunder) Satoshi(0) else Transactions.commitTxFee(commitments1.localParams.dustLimit, reduced)
+ val missing = reduced.toRemote.truncateToSatoshi - commitments1.localParams.channelReserve - fees
+ if (missing < Satoshi(0)) {
+ throw InsufficientFunds(commitments.channelId, amount = add.amountMsat, missing = -missing, reserve = commitments1.localParams.channelReserve, fees = fees)
}
commitments1
@@ -313,10 +315,10 @@ object Commitments {
// a node cannot spend pending incoming htlcs, and need to keep funds above the reserve required by the counterparty, after paying the fee
// we look from remote's point of view, so if local is funder remote doesn't pay the fees
- val fees = Transactions.commitTxFee(Satoshi(commitments1.remoteParams.dustLimitSatoshis), reduced).amount
- val missing = reduced.toRemoteMsat / 1000 - commitments1.remoteParams.channelReserveSatoshis - fees
- if (missing < 0) {
- throw CannotAffordFees(commitments.channelId, missingSatoshis = -1 * missing, reserveSatoshis = commitments1.localParams.channelReserveSatoshis, feesSatoshis = fees)
+ val fees = commitTxFee(commitments1.remoteParams.dustLimit, reduced)
+ val missing = reduced.toRemote.truncateToSatoshi - commitments1.remoteParams.channelReserve - fees
+ if (missing < Satoshi(0)) {
+ throw CannotAffordFees(commitments.channelId, missing = -missing, reserve = commitments1.localParams.channelReserve, fees = fees)
}
(commitments1, fee)
@@ -347,10 +349,10 @@ object Commitments {
val reduced = CommitmentSpec.reduce(commitments1.localCommit.spec, commitments1.localChanges.acked, commitments1.remoteChanges.proposed)
// a node cannot spend pending incoming htlcs, and need to keep funds above the reserve required by the counterparty, after paying the fee
- val fees = Transactions.commitTxFee(Satoshi(commitments1.remoteParams.dustLimitSatoshis), reduced).amount
- val missing = reduced.toRemoteMsat / 1000 - commitments1.localParams.channelReserveSatoshis - fees
- if (missing < 0) {
- throw CannotAffordFees(commitments.channelId, missingSatoshis = -1 * missing, reserveSatoshis = commitments1.localParams.channelReserveSatoshis, feesSatoshis = fees)
+ val fees = commitTxFee(commitments1.remoteParams.dustLimit, reduced)
+ val missing = reduced.toRemote.truncateToSatoshi - commitments1.localParams.channelReserve - fees
+ if (missing < Satoshi(0)) {
+ throw CannotAffordFees(commitments.channelId, missing = -missing, reserve = commitments1.localParams.channelReserve, fees = fees)
}
commitments1
@@ -527,8 +529,8 @@ object Commitments {
val remotePaymentPubkey = Generators.derivePubKey(remoteParams.paymentBasepoint, localPerCommitmentPoint)
val remoteHtlcPubkey = Generators.derivePubKey(remoteParams.htlcBasepoint, localPerCommitmentPoint)
val localRevocationPubkey = Generators.revocationPubKey(remoteParams.revocationBasepoint, localPerCommitmentPoint)
- val commitTx = Transactions.makeCommitTx(commitmentInput, commitTxNumber, keyManager.paymentPoint(localParams.channelKeyPath).publicKey, remoteParams.paymentBasepoint, localParams.isFunder, Satoshi(localParams.dustLimitSatoshis), localRevocationPubkey, remoteParams.toSelfDelay, localDelayedPaymentPubkey, remotePaymentPubkey, localHtlcPubkey, remoteHtlcPubkey, spec)
- val (htlcTimeoutTxs, htlcSuccessTxs) = Transactions.makeHtlcTxs(commitTx.tx, Satoshi(localParams.dustLimitSatoshis), localRevocationPubkey, remoteParams.toSelfDelay, localDelayedPaymentPubkey, localHtlcPubkey, remoteHtlcPubkey, spec)
+ val commitTx = Transactions.makeCommitTx(commitmentInput, commitTxNumber, keyManager.paymentPoint(localParams.channelKeyPath).publicKey, remoteParams.paymentBasepoint, localParams.isFunder, localParams.dustLimit, localRevocationPubkey, remoteParams.toSelfDelay, localDelayedPaymentPubkey, remotePaymentPubkey, localHtlcPubkey, remoteHtlcPubkey, spec)
+ val (htlcTimeoutTxs, htlcSuccessTxs) = Transactions.makeHtlcTxs(commitTx.tx, localParams.dustLimit, localRevocationPubkey, remoteParams.toSelfDelay, localDelayedPaymentPubkey, localHtlcPubkey, remoteHtlcPubkey, spec)
(commitTx, htlcTimeoutTxs, htlcSuccessTxs)
}
@@ -538,8 +540,8 @@ object Commitments {
val remoteDelayedPaymentPubkey = Generators.derivePubKey(remoteParams.delayedPaymentBasepoint, remotePerCommitmentPoint)
val remoteHtlcPubkey = Generators.derivePubKey(remoteParams.htlcBasepoint, remotePerCommitmentPoint)
val remoteRevocationPubkey = Generators.revocationPubKey(keyManager.revocationPoint(localParams.channelKeyPath).publicKey, remotePerCommitmentPoint)
- val commitTx = Transactions.makeCommitTx(commitmentInput, commitTxNumber, remoteParams.paymentBasepoint, keyManager.paymentPoint(localParams.channelKeyPath).publicKey, !localParams.isFunder, Satoshi(remoteParams.dustLimitSatoshis), remoteRevocationPubkey, localParams.toSelfDelay, remoteDelayedPaymentPubkey, localPaymentPubkey, remoteHtlcPubkey, localHtlcPubkey, spec)
- val (htlcTimeoutTxs, htlcSuccessTxs) = Transactions.makeHtlcTxs(commitTx.tx, Satoshi(remoteParams.dustLimitSatoshis), remoteRevocationPubkey, localParams.toSelfDelay, remoteDelayedPaymentPubkey, remoteHtlcPubkey, localHtlcPubkey, spec)
+ val commitTx = Transactions.makeCommitTx(commitmentInput, commitTxNumber, remoteParams.paymentBasepoint, keyManager.paymentPoint(localParams.channelKeyPath).publicKey, !localParams.isFunder, remoteParams.dustLimit, remoteRevocationPubkey, localParams.toSelfDelay, remoteDelayedPaymentPubkey, localPaymentPubkey, remoteHtlcPubkey, localHtlcPubkey, spec)
+ val (htlcTimeoutTxs, htlcSuccessTxs) = Transactions.makeHtlcTxs(commitTx.tx, remoteParams.dustLimit, remoteRevocationPubkey, localParams.toSelfDelay, remoteDelayedPaymentPubkey, remoteHtlcPubkey, localHtlcPubkey, spec)
(commitTx, htlcTimeoutTxs, htlcSuccessTxs)
}
@@ -574,18 +576,18 @@ object Commitments {
def specs2String(commitments: Commitments): String = {
s"""specs:
|localcommit:
- | toLocal: ${commitments.localCommit.spec.toLocalMsat}
- | toRemote: ${commitments.localCommit.spec.toRemoteMsat}
+ | toLocal: ${commitments.localCommit.spec.toLocal}
+ | toRemote: ${commitments.localCommit.spec.toRemote}
| htlcs:
|${commitments.localCommit.spec.htlcs.map(h => s" ${h.direction} ${h.add.id} ${h.add.cltvExpiry}").mkString("\n")}
|remotecommit:
- | toLocal: ${commitments.remoteCommit.spec.toLocalMsat}
- | toRemote: ${commitments.remoteCommit.spec.toRemoteMsat}
+ | toLocal: ${commitments.remoteCommit.spec.toLocal}
+ | toRemote: ${commitments.remoteCommit.spec.toRemote}
| htlcs:
|${commitments.remoteCommit.spec.htlcs.map(h => s" ${h.direction} ${h.add.id} ${h.add.cltvExpiry}").mkString("\n")}
|next remotecommit:
- | toLocal: ${commitments.remoteNextCommitInfo.left.toOption.map(_.nextRemoteCommit.spec.toLocalMsat).getOrElse("N/A")}
- | toRemote: ${commitments.remoteNextCommitInfo.left.toOption.map(_.nextRemoteCommit.spec.toRemoteMsat).getOrElse("N/A")}
+ | toLocal: ${commitments.remoteNextCommitInfo.left.toOption.map(_.nextRemoteCommit.spec.toLocal).getOrElse("N/A")}
+ | toRemote: ${commitments.remoteNextCommitInfo.left.toOption.map(_.nextRemoteCommit.spec.toRemote).getOrElse("N/A")}
| htlcs:
|${commitments.remoteNextCommitInfo.left.toOption.map(_.nextRemoteCommit.spec.htlcs.map(h => s" ${h.direction} ${h.add.id} ${h.add.cltvExpiry}").mkString("\n")).getOrElse("N/A")}""".stripMargin
}
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/channel/Helpers.scala b/eclair-core/src/main/scala/fr/acinq/eclair/channel/Helpers.scala
index 5cbe075fcb..1f49e73429 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/channel/Helpers.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/channel/Helpers.scala
@@ -20,6 +20,8 @@ import akka.event.LoggingAdapter
import fr.acinq.bitcoin.Crypto.{PrivateKey, PublicKey, ripemd160, sha256}
import fr.acinq.bitcoin.Script._
import fr.acinq.bitcoin.{OutPoint, _}
+import fr.acinq.eclair
+import fr.acinq.eclair._
import fr.acinq.eclair.blockchain.EclairWallet
import fr.acinq.eclair.blockchain.fee.{FeeEstimator, FeeTargets}
import fr.acinq.eclair.channel.Channel.REFRESH_CHANNEL_UPDATE_INTERVAL
@@ -88,10 +90,10 @@ object Helpers {
// BOLT #2: if the chain_hash value, within the open_channel, message is set to a hash of a chain that is unknown to the receiver:
// MUST reject the channel.
if (nodeParams.chainHash != open.chainHash) throw InvalidChainHash(open.temporaryChannelId, local = nodeParams.chainHash, remote = open.chainHash)
- if (open.fundingSatoshis < nodeParams.minFundingSatoshis || open.fundingSatoshis >= Channel.MAX_FUNDING_SATOSHIS) throw InvalidFundingAmount(open.temporaryChannelId, open.fundingSatoshis, nodeParams.minFundingSatoshis, Channel.MAX_FUNDING_SATOSHIS)
+ if (open.fundingSatoshis < nodeParams.minFundingSatoshis || open.fundingSatoshis >= Channel.MAX_FUNDING) throw InvalidFundingAmount(open.temporaryChannelId, open.fundingSatoshis, nodeParams.minFundingSatoshis, Channel.MAX_FUNDING)
// BOLT #2: The receiving node MUST fail the channel if: push_msat is greater than funding_satoshis * 1000.
- if (open.pushMsat > 1000 * open.fundingSatoshis) throw InvalidPushAmount(open.temporaryChannelId, open.pushMsat, 1000 * open.fundingSatoshis)
+ if (open.pushMsat > open.fundingSatoshis.toMilliSatoshi) throw InvalidPushAmount(open.temporaryChannelId, open.pushMsat, open.fundingSatoshis.toMilliSatoshi)
// BOLT #2: The receiving node MUST fail the channel if: to_self_delay is unreasonably large.
if (open.toSelfDelay > Channel.MAX_TO_SELF_DELAY || open.toSelfDelay > nodeParams.maxToLocalDelayBlocks) throw ToSelfDelayTooHigh(open.temporaryChannelId, open.toSelfDelay, nodeParams.maxToLocalDelayBlocks)
@@ -107,8 +109,8 @@ object Helpers {
// BOLT #2: The receiving node MUST fail the channel if both to_local and to_remote amounts for the initial commitment
// transaction are less than or equal to channel_reserve_satoshis (see BOLT 3).
- val (toLocalMsat, toRemoteMsat) = (open.pushMsat, open.fundingSatoshis * 1000 - open.pushMsat)
- if (toLocalMsat < open.channelReserveSatoshis * 1000 && toRemoteMsat < open.channelReserveSatoshis * 1000) {
+ val (toLocalMsat, toRemoteMsat) = (open.pushMsat, open.fundingSatoshis.toMilliSatoshi - open.pushMsat)
+ if (toLocalMsat < open.channelReserveSatoshis.toMilliSatoshi && toRemoteMsat < open.channelReserveSatoshis.toMilliSatoshi) {
throw ChannelReserveNotMet(open.temporaryChannelId, toLocalMsat, toRemoteMsat, open.channelReserveSatoshis)
}
@@ -122,7 +124,7 @@ object Helpers {
// we don't check that the funder's amount for the initial commitment transaction is sufficient for full fee payment
// now, but it will be done later when we receive `funding_created`
- val reserveToFundingRatio = open.channelReserveSatoshis.toDouble / Math.max(open.fundingSatoshis, 1)
+ val reserveToFundingRatio = open.channelReserveSatoshis.toLong.toDouble / Math.max(open.fundingSatoshis.toLong, 1)
if (reserveToFundingRatio > nodeParams.maxReserveToFundingRatio) throw ChannelReserveTooHigh(open.temporaryChannelId, open.channelReserveSatoshis, reserveToFundingRatio, nodeParams.maxReserveToFundingRatio)
}
@@ -151,7 +153,7 @@ object Helpers {
// MUST reject the channel. Other fields have the same requirements as their counterparts in open_channel.
if (open.channelReserveSatoshis < accept.dustLimitSatoshis) throw DustLimitAboveOurChannelReserve(accept.temporaryChannelId, accept.dustLimitSatoshis, open.channelReserveSatoshis)
- val reserveToFundingRatio = accept.channelReserveSatoshis.toDouble / Math.max(open.fundingSatoshis, 1)
+ val reserveToFundingRatio = accept.channelReserveSatoshis.toLong.toDouble / Math.max(open.fundingSatoshis.toLong, 1)
if (reserveToFundingRatio > nodeParams.maxReserveToFundingRatio) throw ChannelReserveTooHigh(open.temporaryChannelId, accept.channelReserveSatoshis, reserveToFundingRatio, nodeParams.maxReserveToFundingRatio)
}
@@ -219,10 +221,10 @@ object Helpers {
case Left(waitingForRevocation) => waitingForRevocation.nextRemoteCommit
case _ => commitments.remoteCommit
}
- val toRemoteSatoshis = remoteCommit.spec.toRemoteMsat / 1000
+ val toRemoteSatoshis = remoteCommit.spec.toRemote.truncateToSatoshi
// NB: this is an approximation (we don't take network fees into account)
- val result = toRemoteSatoshis > commitments.remoteParams.channelReserveSatoshis
- log.debug(s"toRemoteSatoshis=$toRemoteSatoshis reserve=${commitments.remoteParams.channelReserveSatoshis} aboveReserve=$result for remoteCommitNumber=${remoteCommit.index}")
+ val result = toRemoteSatoshis > commitments.remoteParams.channelReserve
+ log.debug(s"toRemoteSatoshis=$toRemoteSatoshis reserve=${commitments.remoteParams.channelReserve} aboveReserve=$result for remoteCommitNumber=${remoteCommit.index}")
result
}
@@ -252,24 +254,24 @@ object Helpers {
* @param remoteFirstPerCommitmentPoint
* @return (localSpec, localTx, remoteSpec, remoteTx, fundingTxOutput)
*/
- def makeFirstCommitTxs(keyManager: KeyManager, temporaryChannelId: ByteVector32, localParams: LocalParams, remoteParams: RemoteParams, fundingSatoshis: Long, pushMsat: Long, initialFeeratePerKw: Long, fundingTxHash: ByteVector32, fundingTxOutputIndex: Int, remoteFirstPerCommitmentPoint: PublicKey, maxFeerateMismatch: Double): (CommitmentSpec, CommitTx, CommitmentSpec, CommitTx) = {
- val toLocalMsat = if (localParams.isFunder) fundingSatoshis * 1000 - pushMsat else pushMsat
- val toRemoteMsat = if (localParams.isFunder) pushMsat else fundingSatoshis * 1000 - pushMsat
+ def makeFirstCommitTxs(keyManager: KeyManager, temporaryChannelId: ByteVector32, localParams: LocalParams, remoteParams: RemoteParams, fundingAmount: Satoshi, pushMsat: MilliSatoshi, initialFeeratePerKw: Long, fundingTxHash: ByteVector32, fundingTxOutputIndex: Int, remoteFirstPerCommitmentPoint: PublicKey, maxFeerateMismatch: Double): (CommitmentSpec, CommitTx, CommitmentSpec, CommitTx) = {
+ val toLocalMsat = if (localParams.isFunder) fundingAmount.toMilliSatoshi - pushMsat else pushMsat
+ val toRemoteMsat = if (localParams.isFunder) pushMsat else fundingAmount.toMilliSatoshi - pushMsat
- val localSpec = CommitmentSpec(Set.empty[DirectedHtlc], feeratePerKw = initialFeeratePerKw, toLocalMsat = toLocalMsat, toRemoteMsat = toRemoteMsat)
- val remoteSpec = CommitmentSpec(Set.empty[DirectedHtlc], feeratePerKw = initialFeeratePerKw, toLocalMsat = toRemoteMsat, toRemoteMsat = toLocalMsat)
+ val localSpec = CommitmentSpec(Set.empty[DirectedHtlc], feeratePerKw = initialFeeratePerKw, toLocal = toLocalMsat, toRemote = toRemoteMsat)
+ val remoteSpec = CommitmentSpec(Set.empty[DirectedHtlc], feeratePerKw = initialFeeratePerKw, toLocal = toRemoteMsat, toRemote = toLocalMsat)
if (!localParams.isFunder) {
// they are funder, therefore they pay the fee: we need to make sure they can afford it!
- val toRemoteMsat = remoteSpec.toLocalMsat
- val fees = Transactions.commitTxFee(Satoshi(remoteParams.dustLimitSatoshis), remoteSpec).amount
- val missing = toRemoteMsat / 1000 - localParams.channelReserveSatoshis - fees
- if (missing < 0) {
- throw CannotAffordFees(temporaryChannelId, missingSatoshis = -1 * missing, reserveSatoshis = localParams.channelReserveSatoshis, feesSatoshis = fees)
+ val toRemoteMsat = remoteSpec.toLocal
+ val fees = commitTxFee(remoteParams.dustLimit, remoteSpec)
+ val missing = toRemoteMsat.truncateToSatoshi - localParams.channelReserve - fees
+ if (missing < Satoshi(0)) {
+ throw CannotAffordFees(temporaryChannelId, missing = -missing, reserve = localParams.channelReserve, fees = fees)
}
}
- val commitmentInput = makeFundingInputInfo(fundingTxHash, fundingTxOutputIndex, Satoshi(fundingSatoshis), keyManager.fundingPublicKey(localParams.channelKeyPath).publicKey, remoteParams.fundingPubKey)
+ val commitmentInput = makeFundingInputInfo(fundingTxHash, fundingTxOutputIndex, fundingAmount, keyManager.fundingPublicKey(localParams.channelKeyPath).publicKey, remoteParams.fundingPubKey)
val localPerCommitmentPoint = keyManager.commitmentPoint(localParams.channelKeyPath, 0)
val (localCommitTx, _, _) = Commitments.makeLocalTxs(keyManager, 0, localParams, remoteParams, commitmentInput, localPerCommitmentPoint, localSpec)
val (remoteCommitTx, _, _) = Commitments.makeRemoteTxs(keyManager, 0, localParams, remoteParams, commitmentInput, remoteFirstPerCommitmentPoint, remoteSpec)
@@ -358,9 +360,9 @@ object Helpers {
*/
def nothingAtStake(data: HasCommitments): Boolean =
data.commitments.localCommit.index == 0 &&
- data.commitments.localCommit.spec.toLocalMsat == 0 &&
+ data.commitments.localCommit.spec.toLocal == MilliSatoshi(0) &&
data.commitments.remoteCommit.index == 0 &&
- data.commitments.remoteCommit.spec.toRemoteMsat == 0 &&
+ data.commitments.remoteCommit.spec.toRemote == MilliSatoshi(0) &&
data.commitments.remoteNextCommitInfo.isRight
/**
@@ -453,10 +455,10 @@ object Helpers {
require(isValidFinalScriptPubkey(remoteScriptPubkey), "invalid remoteScriptPubkey")
log.debug(s"making closing tx with closingFee={} and commitments:\n{}", closingFee, Commitments.specs2String(commitments))
// TODO: check that
- val dustLimitSatoshis = Satoshi(Math.max(localParams.dustLimitSatoshis, remoteParams.dustLimitSatoshis))
+ val dustLimitSatoshis = maxOf(localParams.dustLimit, remoteParams.dustLimit)
val closingTx = Transactions.makeClosingTx(commitInput, localScriptPubkey, remoteScriptPubkey, localParams.isFunder, dustLimitSatoshis, closingFee, localCommit.spec)
val localClosingSig = keyManager.sign(closingTx, keyManager.fundingPublicKey(commitments.localParams.channelKeyPath))
- val closingSigned = ClosingSigned(channelId, closingFee.amount, localClosingSig)
+ val closingSigned = ClosingSigned(channelId, closingFee, localClosingSig)
log.info(s"signed closing txid=${closingTx.tx.txid} with closingFeeSatoshis=${closingSigned.feeSatoshis}")
log.debug(s"closingTxid=${closingTx.tx.txid} closingTx=${closingTx.tx}}")
(closingTx, closingSigned)
@@ -467,7 +469,7 @@ object Helpers {
val lastCommitFeeSatoshi = commitments.commitInput.txOut.amount.amount - commitments.localCommit.publishableTxs.commitTx.tx.txOut.map(_.amount.amount).sum
if (remoteClosingFee.amount > lastCommitFeeSatoshi) {
log.error(s"remote proposed a commit fee higher than the last commitment fee: remoteClosingFeeSatoshi=${remoteClosingFee.amount} lastCommitFeeSatoshi=$lastCommitFeeSatoshi")
- throw InvalidCloseFee(commitments.channelId, remoteClosingFee.amount)
+ throw InvalidCloseFee(commitments.channelId, remoteClosingFee)
}
val (closingTx, closingSigned) = makeClosingTx(keyManager, commitments, localScriptPubkey, remoteScriptPubkey, remoteClosingFee)
val signedClosingTx = Transactions.addSigs(closingTx, keyManager.fundingPublicKey(commitments.localParams.channelKeyPath).publicKey, remoteParams.fundingPubKey, closingSigned.signature, remoteClosingSig)
@@ -508,7 +510,7 @@ object Helpers {
// first we will claim our main output as soon as the delay is over
val mainDelayedTx = generateTx("main-delayed-output")(Try {
- val claimDelayed = Transactions.makeClaimDelayedOutputTx(tx, Satoshi(localParams.dustLimitSatoshis), localRevocationPubkey, remoteParams.toSelfDelay, localDelayedPubkey, localParams.defaultFinalScriptPubKey, feeratePerKwDelayed)
+ val claimDelayed = Transactions.makeClaimDelayedOutputTx(tx, localParams.dustLimit, localRevocationPubkey, remoteParams.toSelfDelay, localDelayedPubkey, localParams.defaultFinalScriptPubKey, feeratePerKwDelayed)
val sig = keyManager.sign(claimDelayed, keyManager.delayedPaymentPoint(localParams.channelKeyPath), localPerCommitmentPoint)
Transactions.addSigs(claimDelayed, sig)
})
@@ -539,7 +541,7 @@ object Helpers {
generateTx("claim-htlc-delayed")(Try {
val claimDelayed = Transactions.makeClaimDelayedOutputTx(
txinfo.tx,
- Satoshi(localParams.dustLimitSatoshis),
+ localParams.dustLimit,
localRevocationPubkey,
remoteParams.toSelfDelay,
localDelayedPubkey,
@@ -590,7 +592,7 @@ object Helpers {
// incoming htlc for which we have the preimage: we spend it directly
case DirectedHtlc(OUT, add: UpdateAddHtlc) if preimages.exists(r => sha256(r) == add.paymentHash) => generateTx("claim-htlc-success")(Try {
val preimage = preimages.find(r => sha256(r) == add.paymentHash).get
- val txinfo = Transactions.makeClaimHtlcSuccessTx(remoteCommitTx.tx, outputsAlreadyUsed, Satoshi(localParams.dustLimitSatoshis), localHtlcPubkey, remoteHtlcPubkey, remoteRevocationPubkey, localParams.defaultFinalScriptPubKey, add, feeratePerKwHtlc)
+ val txinfo = Transactions.makeClaimHtlcSuccessTx(remoteCommitTx.tx, outputsAlreadyUsed, localParams.dustLimit, localHtlcPubkey, remoteHtlcPubkey, remoteRevocationPubkey, localParams.defaultFinalScriptPubKey, add, feeratePerKwHtlc)
outputsAlreadyUsed = outputsAlreadyUsed + txinfo.input.outPoint.index.toInt
val sig = keyManager.sign(txinfo, keyManager.htlcPoint(localParams.channelKeyPath), remoteCommit.remotePerCommitmentPoint)
Transactions.addSigs(txinfo, sig, preimage)
@@ -600,7 +602,7 @@ object Helpers {
// outgoing htlc: they may or may not have the preimage, the only thing to do is try to get back our funds after timeout
case DirectedHtlc(IN, add: UpdateAddHtlc) => generateTx("claim-htlc-timeout")(Try {
- val txinfo = Transactions.makeClaimHtlcTimeoutTx(remoteCommitTx.tx, outputsAlreadyUsed, Satoshi(localParams.dustLimitSatoshis), localHtlcPubkey, remoteHtlcPubkey, remoteRevocationPubkey, localParams.defaultFinalScriptPubKey, add, feeratePerKwHtlc)
+ val txinfo = Transactions.makeClaimHtlcTimeoutTx(remoteCommitTx.tx, outputsAlreadyUsed, localParams.dustLimit, localHtlcPubkey, remoteHtlcPubkey, remoteRevocationPubkey, localParams.defaultFinalScriptPubKey, add, feeratePerKwHtlc)
outputsAlreadyUsed = outputsAlreadyUsed + txinfo.input.outPoint.index.toInt
val sig = keyManager.sign(txinfo, keyManager.htlcPoint(localParams.channelKeyPath), remoteCommit.remotePerCommitmentPoint)
Transactions.addSigs(txinfo, sig)
@@ -630,7 +632,7 @@ object Helpers {
val feeratePerKwMain = feeEstimator.getFeeratePerKw(feeTargets.claimMainBlockTarget)
val mainTx = generateTx("claim-p2wpkh-output")(Try {
- val claimMain = Transactions.makeClaimP2WPKHOutputTx(tx, Satoshi(commitments.localParams.dustLimitSatoshis),
+ val claimMain = Transactions.makeClaimP2WPKHOutputTx(tx, commitments.localParams.dustLimit,
localPubkey, commitments.localParams.defaultFinalScriptPubKey, feeratePerKwMain)
val sig = keyManager.sign(claimMain, keyManager.paymentPoint(commitments.localParams.channelKeyPath), remotePerCommitmentPoint)
Transactions.addSigs(claimMain, localPubkey, sig)
@@ -679,14 +681,14 @@ object Helpers {
// first we will claim our main output right away
val mainTx = generateTx("claim-p2wpkh-output")(Try {
- val claimMain = Transactions.makeClaimP2WPKHOutputTx(tx, Satoshi(localParams.dustLimitSatoshis), localPubkey, localParams.defaultFinalScriptPubKey, feeratePerKwMain)
+ val claimMain = Transactions.makeClaimP2WPKHOutputTx(tx, localParams.dustLimit, localPubkey, localParams.defaultFinalScriptPubKey, feeratePerKwMain)
val sig = keyManager.sign(claimMain, keyManager.paymentPoint(localParams.channelKeyPath), remotePerCommitmentPoint)
Transactions.addSigs(claimMain, localPubkey, sig)
})
// then we punish them by stealing their main output
val mainPenaltyTx = generateTx("main-penalty")(Try {
- val txinfo = Transactions.makeMainPenaltyTx(tx, Satoshi(localParams.dustLimitSatoshis), remoteRevocationPubkey, localParams.defaultFinalScriptPubKey, localParams.toSelfDelay, remoteDelayedPaymentPubkey, feeratePerKwPenalty)
+ val txinfo = Transactions.makeMainPenaltyTx(tx, localParams.dustLimit, remoteRevocationPubkey, localParams.defaultFinalScriptPubKey, localParams.toSelfDelay, remoteDelayedPaymentPubkey, feeratePerKwPenalty)
val sig = keyManager.sign(txinfo, keyManager.revocationPoint(localParams.channelKeyPath), remotePerCommitmentSecret)
Transactions.addSigs(txinfo, sig)
})
@@ -706,7 +708,7 @@ object Helpers {
val htlcPenaltyTxs = tx.txOut.collect { case txOut if htlcsRedeemScripts.contains(txOut.publicKeyScript) =>
val htlcRedeemScript = htlcsRedeemScripts(txOut.publicKeyScript)
generateTx("htlc-penalty")(Try {
- val htlcPenalty = Transactions.makeHtlcPenaltyTx(tx, outputsAlreadyUsed, htlcRedeemScript, Satoshi(localParams.dustLimitSatoshis), localParams.defaultFinalScriptPubKey, feeratePerKwPenalty)
+ val htlcPenalty = Transactions.makeHtlcPenaltyTx(tx, outputsAlreadyUsed, htlcRedeemScript, localParams.dustLimit, localParams.defaultFinalScriptPubKey, feeratePerKwPenalty)
outputsAlreadyUsed = outputsAlreadyUsed + htlcPenalty.input.outPoint.index.toInt
val sig = keyManager.sign(htlcPenalty, keyManager.revocationPoint(localParams.channelKeyPath), remotePerCommitmentSecret)
Transactions.addSigs(htlcPenalty, sig, remoteRevocationPubkey)
@@ -762,7 +764,7 @@ object Helpers {
val feeratePerKwPenalty = feeEstimator.getFeeratePerKw(target = 1)
generateTx("claim-htlc-delayed-penalty")(Try {
- val htlcDelayedPenalty = Transactions.makeClaimDelayedOutputPenaltyTx(htlcTx, Satoshi(localParams.dustLimitSatoshis), remoteRevocationPubkey, localParams.toSelfDelay, remoteDelayedPaymentPubkey, localParams.defaultFinalScriptPubKey, feeratePerKwPenalty)
+ val htlcDelayedPenalty = Transactions.makeClaimDelayedOutputPenaltyTx(htlcTx, localParams.dustLimit, remoteRevocationPubkey, localParams.toSelfDelay, remoteDelayedPaymentPubkey, localParams.defaultFinalScriptPubKey, feeratePerKwPenalty)
val sig = keyManager.sign(htlcDelayedPenalty, keyManager.revocationPoint(localParams.channelKeyPath), remotePerCommitmentSecret)
val signedTx = Transactions.addSigs(htlcDelayedPenalty, sig)
// we need to make sure that the tx is indeed valid
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/db/AuditDb.scala b/eclair-core/src/main/scala/fr/acinq/eclair/db/AuditDb.scala
index 63dbe4d74f..5fccd441b1 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/db/AuditDb.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/db/AuditDb.scala
@@ -16,7 +16,7 @@
package fr.acinq.eclair.db
-import fr.acinq.bitcoin.ByteVector32
+import fr.acinq.bitcoin.{ByteVector32, Satoshi}
import fr.acinq.bitcoin.Crypto.PublicKey
import fr.acinq.eclair.channel._
import fr.acinq.eclair.payment.{PaymentReceived, PaymentRelayed, PaymentSent}
@@ -51,8 +51,8 @@ trait AuditDb {
}
-case class ChannelLifecycleEvent(channelId: ByteVector32, remoteNodeId: PublicKey, capacitySat: Long, isFunder: Boolean, isPrivate: Boolean, event: String)
+case class ChannelLifecycleEvent(channelId: ByteVector32, remoteNodeId: PublicKey, capacity: Satoshi, isFunder: Boolean, isPrivate: Boolean, event: String)
-case class NetworkFee(remoteNodeId: PublicKey, channelId: ByteVector32, txId: ByteVector32, feeSat: Long, txType: String, timestamp: Long)
+case class NetworkFee(remoteNodeId: PublicKey, channelId: ByteVector32, txId: ByteVector32, fee: Satoshi, txType: String, timestamp: Long)
-case class Stats(channelId: ByteVector32, avgPaymentAmountSatoshi: Long, paymentCount: Int, relayFeeSatoshi: Long, networkFeeSatoshi: Long)
+case class Stats(channelId: ByteVector32, avgPaymentAmount: Satoshi, paymentCount: Int, relayFee: Satoshi, networkFee: Satoshi)
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/db/PaymentsDb.scala b/eclair-core/src/main/scala/fr/acinq/eclair/db/PaymentsDb.scala
index b13e190446..b9f4aa838f 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/db/PaymentsDb.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/db/PaymentsDb.scala
@@ -17,7 +17,9 @@
package fr.acinq.eclair.db
import java.util.UUID
+
import fr.acinq.bitcoin.ByteVector32
+import fr.acinq.eclair.MilliSatoshi
import fr.acinq.eclair.payment.PaymentRequest
trait PaymentsDb {
@@ -60,10 +62,10 @@ trait PaymentsDb {
* Incoming payment object stored in DB.
*
* @param paymentHash identifier of the payment
- * @param amountMsat amount of the payment, in milli-satoshis
+ * @param amount amount of the payment, in milli-satoshis
* @param receivedAt absolute time in seconds since UNIX epoch when the payment was received.
*/
-case class IncomingPayment(paymentHash: ByteVector32, amountMsat: Long, receivedAt: Long)
+case class IncomingPayment(paymentHash: ByteVector32, amount: MilliSatoshi, receivedAt: Long)
/**
* Sent payment is every payment that is sent by this node, they may not be finalized and
@@ -72,12 +74,12 @@ case class IncomingPayment(paymentHash: ByteVector32, amountMsat: Long, received
* @param id internal payment identifier
* @param paymentHash payment_hash
* @param preimage the preimage of the payment_hash, known if the outgoing payment was successful
- * @param amountMsat amount of the payment, in milli-satoshis
+ * @param amount amount of the payment, in milli-satoshis
* @param createdAt absolute time in seconds since UNIX epoch when the payment was created.
* @param completedAt absolute time in seconds since UNIX epoch when the payment succeeded.
* @param status current status of the payment.
*/
-case class OutgoingPayment(id: UUID, paymentHash: ByteVector32, preimage:Option[ByteVector32], amountMsat: Long, createdAt: Long, completedAt: Option[Long], status: OutgoingPaymentStatus.Value)
+case class OutgoingPayment(id: UUID, paymentHash: ByteVector32, preimage:Option[ByteVector32], amount: MilliSatoshi, createdAt: Long, completedAt: Option[Long], status: OutgoingPaymentStatus.Value)
object OutgoingPaymentStatus extends Enumeration {
val PENDING = Value(1, "PENDING")
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/db/sqlite/SqliteAuditDb.scala b/eclair-core/src/main/scala/fr/acinq/eclair/db/sqlite/SqliteAuditDb.scala
index 519ed96b8d..c03bec2a84 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/db/sqlite/SqliteAuditDb.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/db/sqlite/SqliteAuditDb.scala
@@ -19,7 +19,8 @@ package fr.acinq.eclair.db.sqlite
import java.sql.{Connection, Statement}
import java.util.UUID
import fr.acinq.bitcoin.Crypto.PublicKey
-import fr.acinq.bitcoin.MilliSatoshi
+import fr.acinq.bitcoin.Satoshi
+import fr.acinq.eclair.MilliSatoshi
import fr.acinq.eclair.channel.{AvailableBalanceChanged, Channel, ChannelErrorOccured, NetworkFeePaid}
import fr.acinq.eclair.db.{AuditDb, ChannelLifecycleEvent, NetworkFee, Stats}
import fr.acinq.eclair.payment.{PaymentReceived, PaymentRelayed, PaymentSent}
@@ -83,9 +84,9 @@ class SqliteAuditDb(sqlite: Connection) extends AuditDb with Logging {
using(sqlite.prepareStatement("INSERT INTO balance_updated VALUES (?, ?, ?, ?, ?, ?)")) { statement =>
statement.setBytes(1, e.channelId.toArray)
statement.setBytes(2, e.commitments.remoteParams.nodeId.value.toArray)
- statement.setLong(3, e.localBalanceMsat)
+ statement.setLong(3, e.localBalance.toLong)
statement.setLong(4, e.commitments.commitInput.txOut.amount.toLong)
- statement.setLong(5, e.commitments.remoteParams.channelReserveSatoshis) // remote decides what our reserve should be
+ statement.setLong(5, e.commitments.remoteParams.channelReserve.toLong) // remote decides what our reserve should be
statement.setLong(6, Platform.currentTime)
statement.executeUpdate()
}
@@ -94,7 +95,7 @@ class SqliteAuditDb(sqlite: Connection) extends AuditDb with Logging {
using(sqlite.prepareStatement("INSERT INTO channel_events VALUES (?, ?, ?, ?, ?, ?, ?)")) { statement =>
statement.setBytes(1, e.channelId.toArray)
statement.setBytes(2, e.remoteNodeId.value.toArray)
- statement.setLong(3, e.capacitySat)
+ statement.setLong(3, e.capacity.toLong)
statement.setBoolean(4, e.isFunder)
statement.setBoolean(5, e.isPrivate)
statement.setString(6, e.event)
@@ -225,7 +226,7 @@ class SqliteAuditDb(sqlite: Connection) extends AuditDb with Logging {
remoteNodeId = PublicKey(rs.getByteVector("node_id")),
channelId = rs.getByteVector32("channel_id"),
txId = rs.getByteVector32("tx_id"),
- feeSat = rs.getLong("fee_sat"),
+ fee = Satoshi(rs.getLong("fee_sat")),
txType = rs.getString("tx_type"),
timestamp = rs.getLong("timestamp"))
}
@@ -267,10 +268,10 @@ class SqliteAuditDb(sqlite: Connection) extends AuditDb with Logging {
while (rs.next()) {
q = q :+ Stats(
channelId = rs.getByteVector32("channel_id"),
- avgPaymentAmountSatoshi = rs.getLong("avg_payment_amount_sat"),
+ avgPaymentAmount = Satoshi(rs.getLong("avg_payment_amount_sat")),
paymentCount = rs.getInt("payment_count"),
- relayFeeSatoshi = rs.getLong("relay_fee_sat"),
- networkFeeSatoshi = rs.getLong("network_fee_sat"))
+ relayFee = Satoshi(rs.getLong("relay_fee_sat")),
+ networkFee = Satoshi(rs.getLong("network_fee_sat")))
}
q
}
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/db/sqlite/SqlitePaymentsDb.scala b/eclair-core/src/main/scala/fr/acinq/eclair/db/sqlite/SqlitePaymentsDb.scala
index 8fd6ded566..127ec6be2e 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/db/sqlite/SqlitePaymentsDb.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/db/sqlite/SqlitePaymentsDb.scala
@@ -25,6 +25,7 @@ import fr.acinq.eclair.payment.PaymentRequest
import grizzled.slf4j.Logging
import scala.collection.immutable.Queue
import OutgoingPaymentStatus._
+import fr.acinq.eclair.MilliSatoshi
import concurrent.duration._
import scala.compat.Platform
@@ -47,7 +48,7 @@ class SqlitePaymentsDb(sqlite: Connection) extends PaymentsDb with Logging {
using(sqlite.prepareStatement("INSERT INTO sent_payments (id, payment_hash, amount_msat, created_at, status) VALUES (?, ?, ?, ?, ?)")) { statement =>
statement.setString(1, sent.id.toString)
statement.setBytes(2, sent.paymentHash.toArray)
- statement.setLong(3, sent.amountMsat)
+ statement.setLong(3, sent.amount.toLong)
statement.setLong(4, sent.createdAt)
statement.setString(5, sent.status.toString)
val res = statement.executeUpdate()
@@ -76,7 +77,7 @@ class SqlitePaymentsDb(sqlite: Connection) extends PaymentsDb with Logging {
UUID.fromString(rs.getString("id")),
rs.getByteVector32("payment_hash"),
rs.getByteVector32Nullable("preimage"),
- rs.getLong("amount_msat"),
+ MilliSatoshi(rs.getLong("amount_msat")),
rs.getLong("created_at"),
getNullableLong(rs, "completed_at"),
OutgoingPaymentStatus.withName(rs.getString("status"))
@@ -97,7 +98,7 @@ class SqlitePaymentsDb(sqlite: Connection) extends PaymentsDb with Logging {
UUID.fromString(rs.getString("id")),
rs.getByteVector32("payment_hash"),
rs.getByteVector32Nullable("preimage"),
- rs.getLong("amount_msat"),
+ MilliSatoshi(rs.getLong("amount_msat")),
rs.getLong("created_at"),
getNullableLong(rs, "completed_at"),
OutgoingPaymentStatus.withName(rs.getString("status"))
@@ -116,7 +117,7 @@ class SqlitePaymentsDb(sqlite: Connection) extends PaymentsDb with Logging {
UUID.fromString(rs.getString("id")),
rs.getByteVector32("payment_hash"),
rs.getByteVector32Nullable("preimage"),
- rs.getLong("amount_msat"),
+ MilliSatoshi(rs.getLong("amount_msat")),
rs.getLong("created_at"),
getNullableLong(rs, "completed_at"),
OutgoingPaymentStatus.withName(rs.getString("status"))
@@ -194,7 +195,7 @@ class SqlitePaymentsDb(sqlite: Connection) extends PaymentsDb with Logging {
override def addIncomingPayment(payment: IncomingPayment): Unit = {
using(sqlite.prepareStatement("UPDATE received_payments SET (received_msat, received_at) = (?, ?) WHERE payment_hash = ?")) { statement =>
- statement.setLong(1, payment.amountMsat)
+ statement.setLong(1, payment.amount.toLong)
statement.setLong(2, payment.receivedAt)
statement.setBytes(3, payment.paymentHash.toArray)
val res = statement.executeUpdate()
@@ -207,7 +208,7 @@ class SqlitePaymentsDb(sqlite: Connection) extends PaymentsDb with Logging {
statement.setBytes(1, paymentHash.toArray)
val rs = statement.executeQuery()
if (rs.next()) {
- Some(IncomingPayment(rs.getByteVector32("payment_hash"), rs.getLong("received_msat"), rs.getLong("received_at")))
+ Some(IncomingPayment(rs.getByteVector32("payment_hash"), MilliSatoshi(rs.getLong("received_msat")), rs.getLong("received_at")))
} else {
None
}
@@ -219,7 +220,7 @@ class SqlitePaymentsDb(sqlite: Connection) extends PaymentsDb with Logging {
val rs = statement.executeQuery("SELECT payment_hash, received_msat, received_at FROM received_payments WHERE received_msat > 0")
var q: Queue[IncomingPayment] = Queue()
while (rs.next()) {
- q = q :+ IncomingPayment(rs.getByteVector32("payment_hash"), rs.getLong("received_msat"), rs.getLong("received_at"))
+ q = q :+ IncomingPayment(rs.getByteVector32("payment_hash"), MilliSatoshi(rs.getLong("received_msat")), rs.getLong("received_at"))
}
q
}
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 dbc91f208e..3f672d2e71 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
@@ -25,7 +25,8 @@ import akka.event.Logging.MDC
import akka.util.Timeout
import com.google.common.net.HostAndPort
import fr.acinq.bitcoin.Crypto.PublicKey
-import fr.acinq.bitcoin.{ByteVector32, DeterministicWallet, MilliSatoshi, Protocol, Satoshi}
+import fr.acinq.bitcoin.{ByteVector32, DeterministicWallet, Protocol, Satoshi}
+import fr.acinq.eclair
import fr.acinq.eclair.blockchain.EclairWallet
import fr.acinq.eclair.channel._
import fr.acinq.eclair.crypto.TransportHandler
@@ -280,20 +281,20 @@ class Peer(val nodeParams: NodeParams, remoteNodeId: PublicKey, authenticator: A
stay
case Event(c: Peer.OpenChannel, d: ConnectedData) =>
- val (channel, localParams) = createNewChannel(nodeParams, funder = true, c.fundingSatoshis.toLong, origin_opt = Some(sender))
+ val (channel, localParams) = createNewChannel(nodeParams, funder = true, c.fundingSatoshis, origin_opt = Some(sender))
c.timeout_opt.map(openTimeout => context.system.scheduler.scheduleOnce(openTimeout.duration, channel, Channel.TickChannelOpenTimeout)(context.dispatcher))
val temporaryChannelId = randomBytes32
val channelFeeratePerKw = nodeParams.onChainFeeConf.feeEstimator.getFeeratePerKw(target = nodeParams.onChainFeeConf.feeTargets.commitmentBlockTarget)
val fundingTxFeeratePerKw = c.fundingTxFeeratePerKw_opt.getOrElse(nodeParams.onChainFeeConf.feeEstimator.getFeeratePerKw(target = nodeParams.onChainFeeConf.feeTargets.fundingBlockTarget))
log.info(s"requesting a new channel with fundingSatoshis=${c.fundingSatoshis}, pushMsat=${c.pushMsat} and fundingFeeratePerByte=${c.fundingTxFeeratePerKw_opt} temporaryChannelId=$temporaryChannelId localParams=$localParams")
- channel ! INPUT_INIT_FUNDER(temporaryChannelId, c.fundingSatoshis.amount, c.pushMsat.amount, channelFeeratePerKw, fundingTxFeeratePerKw, localParams, d.transport, d.remoteInit, c.channelFlags.getOrElse(nodeParams.channelFlags))
+ channel ! INPUT_INIT_FUNDER(temporaryChannelId, c.fundingSatoshis, c.pushMsat, channelFeeratePerKw, fundingTxFeeratePerKw, localParams, d.transport, d.remoteInit, c.channelFlags.getOrElse(nodeParams.channelFlags))
stay using d.copy(channels = d.channels + (TemporaryChannelId(temporaryChannelId) -> channel))
case Event(msg: wire.OpenChannel, d: ConnectedData) =>
d.transport ! TransportHandler.ReadAck(msg)
d.channels.get(TemporaryChannelId(msg.temporaryChannelId)) match {
case None =>
- val (channel, localParams) = createNewChannel(nodeParams, funder = false, fundingSatoshis = msg.fundingSatoshis, origin_opt = None)
+ val (channel, localParams) = createNewChannel(nodeParams, funder = false, fundingAmount = msg.fundingSatoshis, origin_opt = None)
val temporaryChannelId = msg.temporaryChannelId
log.info(s"accepting a new channel to $remoteNodeId temporaryChannelId=$temporaryChannelId localParams=$localParams")
channel ! INPUT_INIT_FUNDEE(temporaryChannelId, localParams, d.transport, d.remoteInit)
@@ -523,9 +524,9 @@ class Peer(val nodeParams: NodeParams, remoteNodeId: PublicKey, authenticator: A
case DISCONNECTED -> _ if nodeParams.autoReconnect => cancelTimer(RECONNECT_TIMER)
}
- def createNewChannel(nodeParams: NodeParams, funder: Boolean, fundingSatoshis: Long, origin_opt: Option[ActorRef]): (ActorRef, LocalParams) = {
+ def createNewChannel(nodeParams: NodeParams, funder: Boolean, fundingAmount: Satoshi, origin_opt: Option[ActorRef]): (ActorRef, LocalParams) = {
val defaultFinalScriptPubKey = Helpers.getFinalScriptPubKey(wallet, nodeParams.chainHash)
- val localParams = makeChannelParams(nodeParams, defaultFinalScriptPubKey, funder, fundingSatoshis)
+ val localParams = makeChannelParams(nodeParams, defaultFinalScriptPubKey, funder, fundingAmount)
val channel = spawnChannel(nodeParams, origin_opt)
(channel, localParams)
}
@@ -605,7 +606,7 @@ object Peer {
case class Disconnect(nodeId: PublicKey)
case object ResumeAnnouncements
case class OpenChannel(remoteNodeId: PublicKey, fundingSatoshis: Satoshi, pushMsat: MilliSatoshi, fundingTxFeeratePerKw_opt: Option[Long], channelFlags: Option[Byte], timeout_opt: Option[Timeout]) {
- require(fundingSatoshis.amount < Channel.MAX_FUNDING_SATOSHIS, s"fundingSatoshis must be less than ${Channel.MAX_FUNDING_SATOSHIS}")
+ require(fundingSatoshis < Channel.MAX_FUNDING, s"fundingSatoshis must be less than ${Channel.MAX_FUNDING}")
require(pushMsat.amount <= 1000 * fundingSatoshis.amount, s"pushMsat must be less or equal to fundingSatoshis")
require(fundingSatoshis.amount >= 0, s"fundingSatoshis must be positive")
require(pushMsat.amount >= 0, s"pushMsat must be positive")
@@ -628,22 +629,22 @@ object Peer {
// @formatter:on
- def makeChannelParams(nodeParams: NodeParams, defaultFinalScriptPubKey: ByteVector, isFunder: Boolean, fundingSatoshis: Long): LocalParams = {
+ def makeChannelParams(nodeParams: NodeParams, defaultFinalScriptPubKey: ByteVector, isFunder: Boolean, fundingAmount: Satoshi): LocalParams = {
val entropy = new Array[Byte](16)
secureRandom.nextBytes(entropy)
val bis = new ByteArrayInputStream(entropy)
val channelKeyPath = DeterministicWallet.KeyPath(Seq(Protocol.uint32(bis, ByteOrder.BIG_ENDIAN), Protocol.uint32(bis, ByteOrder.BIG_ENDIAN), Protocol.uint32(bis, ByteOrder.BIG_ENDIAN), Protocol.uint32(bis, ByteOrder.BIG_ENDIAN)))
- makeChannelParams(nodeParams, defaultFinalScriptPubKey, isFunder, fundingSatoshis, channelKeyPath)
+ makeChannelParams(nodeParams, defaultFinalScriptPubKey, isFunder, fundingAmount, channelKeyPath)
}
- def makeChannelParams(nodeParams: NodeParams, defaultFinalScriptPubKey: ByteVector, isFunder: Boolean, fundingSatoshis: Long, channelKeyPath: DeterministicWallet.KeyPath): LocalParams = {
+ def makeChannelParams(nodeParams: NodeParams, defaultFinalScriptPubKey: ByteVector, isFunder: Boolean, fundingAmount: Satoshi, channelKeyPath: DeterministicWallet.KeyPath): LocalParams = {
LocalParams(
nodeParams.nodeId,
channelKeyPath,
- dustLimitSatoshis = nodeParams.dustLimitSatoshis,
+ dustLimit = nodeParams.dustLimit,
maxHtlcValueInFlightMsat = nodeParams.maxHtlcValueInFlightMsat,
- channelReserveSatoshis = Math.max((nodeParams.reserveToFundingRatio * fundingSatoshis).toLong, nodeParams.dustLimitSatoshis), // BOLT #2: make sure that our reserve is above our dust limit
- htlcMinimumMsat = nodeParams.htlcMinimumMsat,
+ channelReserve = maxOf(Satoshi((nodeParams.reserveToFundingRatio * fundingAmount.toLong).toLong), nodeParams.dustLimit), // BOLT #2: make sure that our reserve is above our dust limit
+ htlcMinimum = nodeParams.htlcMinimum,
toSelfDelay = nodeParams.toRemoteDelayBlocks, // we choose their delay
maxAcceptedHtlcs = nodeParams.maxAcceptedHtlcs,
defaultFinalScriptPubKey = defaultFinalScriptPubKey,
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/package.scala b/eclair-core/src/main/scala/fr/acinq/eclair/package.scala
index 44adabf9eb..3ae5f2ffed 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/package.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/package.scala
@@ -126,7 +126,7 @@ package object eclair {
* @param msat amount in millisatoshi
* @return the fee (in msat) that a node should be paid to forward an HTLC of 'amount' millisatoshis
*/
- def nodeFee(baseMsat: Long, proportional: Long, msat: Long): Long = baseMsat + (proportional * msat) / 1000000
+ def nodeFee(baseMsat: MilliSatoshi, proportional: Long, msat: MilliSatoshi): MilliSatoshi = baseMsat + (msat * proportional) / 1000000
/**
*
@@ -159,4 +159,54 @@ package object eclair {
* We use this in the context of timestamp filtering, when we don't need an upper bound.
*/
val MaxEpochSeconds = Duration.fromNanos(Long.MaxValue).toSeconds
+
+ /**
+ * One MilliSatoshi is a thousand of a Satoshi, the smallest unit usable in bitcoin
+ * @param amount
+ */
+ case class MilliSatoshi(amount: Long) {
+ // @formatter:off
+ def toLong = amount
+ def +(other: MilliSatoshi) = MilliSatoshi(amount + other.amount)
+ def -(other: MilliSatoshi) = MilliSatoshi(amount - other.amount)
+ def *(m: Long) = MilliSatoshi(amount * m)
+ def /(d: Long) = MilliSatoshi(amount / d)
+ def compare(other: MilliSatoshi): Int = if (amount == other.amount) 0 else if (amount < other.amount) -1 else 1
+ def <= (that: MilliSatoshi): Boolean = compare(that) <= 0
+ def >= (that: MilliSatoshi): Boolean = compare(that) >= 0
+ def < (that: MilliSatoshi): Boolean = compare(that) < 0
+ def > (that: MilliSatoshi): Boolean = compare(that) > 0
+ def unary_-() = MilliSatoshi(-amount)
+ def truncateToSatoshi: Satoshi = Satoshi(amount / 1000)
+ // @formatter:on
+ }
+
+ implicit class ToMilliSatoshiConversion(amount: BtcAmount) {
+ def toMilliSatoshi: MilliSatoshi = amount match {
+ case sat: Satoshi => satoshi2millisatoshi(sat)
+ case millis: MilliBtc => satoshi2millisatoshi(millibtc2satoshi(millis))
+ case bitcoin: Btc => satoshi2millisatoshi(btc2satoshi(bitcoin))
+ }
+ }
+
+ implicit object NumericMilliSatoshi extends Numeric[MilliSatoshi] {
+ override def plus(x: MilliSatoshi, y: MilliSatoshi): MilliSatoshi = MilliSatoshi(x.amount + y.amount)
+ override def minus(x: MilliSatoshi, y: MilliSatoshi): MilliSatoshi = MilliSatoshi(x.amount - y.amount)
+ override def times(x: MilliSatoshi, y: MilliSatoshi): MilliSatoshi = MilliSatoshi(x.amount * y.amount)
+ override def negate(x: MilliSatoshi): MilliSatoshi = MilliSatoshi(-x.amount)
+ override def fromInt(x: Int): MilliSatoshi = MilliSatoshi(x)
+ override def toInt(x: MilliSatoshi): Int = x.toLong.toInt
+ override def toLong(x: MilliSatoshi): Long = x.toLong
+ override def toFloat(x: MilliSatoshi): Float = x.toLong
+ override def toDouble(x: MilliSatoshi): Double = x.toLong
+ override def compare(x: MilliSatoshi, y: MilliSatoshi): Int = x.compare(y)
+ }
+
+ private def satoshi2millisatoshi(input: Satoshi): MilliSatoshi = MilliSatoshi(input.amount * 1000L)
+
+ def maxOf(x: MilliSatoshi, y: MilliSatoshi) = MilliSatoshi(Math.max(x.amount, y.amount))
+ def minOf(x: MilliSatoshi, y: MilliSatoshi) = MilliSatoshi(Math.min(x.amount, y.amount))
+ def maxOf(x: Satoshi, y: Satoshi) = Satoshi(Math.max(x.amount, y.amount))
+ def minOf(x: Satoshi, y: Satoshi) = Satoshi(Math.min(x.amount, y.amount))
+
}
\ No newline at end of file
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 6136b928e4..0c79bd663c 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
@@ -18,12 +18,10 @@ package fr.acinq.eclair.payment
import akka.actor.{Actor, ActorLogging, Props}
import fr.acinq.bitcoin.ByteVector32
-import fr.acinq.eclair.NodeParams
-import fr.acinq.eclair.channel.Channel.{LocalError, RemoteError}
+import fr.acinq.eclair.{MilliSatoshi, NodeParams}
import fr.acinq.eclair.channel.Helpers.Closing.{LocalClose, MutualClose, RecoveryClose, RemoteClose, RevokedClose}
import fr.acinq.eclair.channel._
import fr.acinq.eclair.db.{AuditDb, ChannelLifecycleEvent}
-
import scala.concurrent.ExecutionContext
import scala.concurrent.duration._
@@ -57,7 +55,7 @@ class Auditor(nodeParams: NodeParams) extends Actor with ActorLogging {
case e: ChannelStateChanged =>
e match {
case ChannelStateChanged(_, _, remoteNodeId, WAIT_FOR_FUNDING_LOCKED, NORMAL, d: DATA_NORMAL) =>
- db.add(ChannelLifecycleEvent(d.channelId, remoteNodeId, d.commitments.commitInput.txOut.amount.toLong, d.commitments.localParams.isFunder, !d.commitments.announceChannel, "created"))
+ db.add(ChannelLifecycleEvent(d.channelId, remoteNodeId, d.commitments.commitInput.txOut.amount, d.commitments.localParams.isFunder, !d.commitments.announceChannel, "created"))
case _ => ()
}
@@ -69,7 +67,7 @@ class Auditor(nodeParams: NodeParams) extends Actor with ActorLogging {
case RecoveryClose => "recovery"
case RevokedClose => "revoked"
}
- db.add(ChannelLifecycleEvent(e.channelId, e.commitments.remoteParams.nodeId, e.commitments.commitInput.txOut.amount.toLong, e.commitments.localParams.isFunder, !e.commitments.announceChannel, event))
+ db.add(ChannelLifecycleEvent(e.channelId, e.commitments.remoteParams.nodeId, e.commitments.commitInput.txOut.amount, e.commitments.localParams.isFunder, !e.commitments.announceChannel, event))
}
@@ -109,11 +107,11 @@ class BalanceEventThrottler(db: AuditDb) extends Actor with ActorLogging {
case ProcessEvent(channelId) =>
pending.get(channelId) match {
case Some(BalanceUpdate(first, last)) =>
- if (first.commitments.remoteCommit.spec.toRemoteMsat == last.localBalanceMsat) {
+ if (first.commitments.remoteCommit.spec.toRemote == last.localBalance) {
// we don't log anything if the balance didn't change (e.g. it was a probe payment)
log.info(s"ignoring balance event for channelId=$channelId (changed was discarded)")
} else {
- log.info(s"processing balance event for channelId=$channelId balance=${first.localBalanceMsat}->${last.localBalanceMsat}")
+ log.info(s"processing balance event for channelId=$channelId balance=${first.localBalance}->${last.localBalance}")
// we log the last event, which contains the most up to date balance
db.add(last)
context.become(run(pending - channelId))
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/payment/Autoprobe.scala b/eclair-core/src/main/scala/fr/acinq/eclair/payment/Autoprobe.scala
index 94e33deb94..71396e096e 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/payment/Autoprobe.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/payment/Autoprobe.scala
@@ -21,8 +21,8 @@ import fr.acinq.bitcoin.Crypto.PublicKey
import fr.acinq.eclair.crypto.Sphinx.DecryptedFailurePacket
import fr.acinq.eclair.payment.PaymentLifecycle.{PaymentFailed, PaymentResult, RemoteFailure, SendPayment}
import fr.acinq.eclair.router.{Announcements, Data}
-import fr.acinq.eclair.wire.{IncorrectOrUnknownPaymentDetails}
-import fr.acinq.eclair.{NodeParams, randomBytes32, secureRandom}
+import fr.acinq.eclair.wire.IncorrectOrUnknownPaymentDetails
+import fr.acinq.eclair.{MilliSatoshi, NodeParams, randomBytes32, secureRandom}
import scala.concurrent.duration._
@@ -83,7 +83,7 @@ object Autoprobe {
val PROBING_INTERVAL = 20 seconds
- val PAYMENT_AMOUNT_MSAT = 100 * 1000 // this is below dust_limit so there won't be an output in the commitment tx
+ val PAYMENT_AMOUNT_MSAT = MilliSatoshi(100 * 1000) // this is below dust_limit so there won't be an output in the commitment tx
object TickProbe
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 1070f3ef37..d936a1474a 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
@@ -17,7 +17,7 @@
package fr.acinq.eclair.payment
import akka.actor.{Actor, ActorLogging, Props, Status}
-import fr.acinq.bitcoin.{Crypto, MilliSatoshi}
+import fr.acinq.bitcoin.{Crypto}
import fr.acinq.eclair.channel.{CMD_FAIL_HTLC, CMD_FULFILL_HTLC, Channel}
import fr.acinq.eclair.db.IncomingPayment
import fr.acinq.eclair.payment.PaymentLifecycle.ReceivePayment
@@ -69,18 +69,18 @@ class LocalPaymentHandler(nodeParams: NodeParams) extends Actor with ActorLoggin
sender ! CMD_FAIL_HTLC(htlc.id, Right(IncorrectOrUnknownPaymentDetails(htlc.amountMsat)), commit = true)
case _ if htlc.cltvExpiry < minFinalExpiry =>
sender ! CMD_FAIL_HTLC(htlc.id, Right(FinalExpiryTooSoon), commit = true)
- case Some(amount) if MilliSatoshi(htlc.amountMsat) < amount =>
- log.warning(s"received payment with amount too small for paymentHash=${htlc.paymentHash} amountMsat=${htlc.amountMsat}")
+ case Some(amount) if htlc.amountMsat < amount =>
+ log.warning(s"received payment with amount too small for paymentHash=${htlc.paymentHash} amount=${htlc.amountMsat}")
sender ! CMD_FAIL_HTLC(htlc.id, Right(IncorrectOrUnknownPaymentDetails(htlc.amountMsat)), commit = true)
- case Some(amount) if MilliSatoshi(htlc.amountMsat) > amount * 2 =>
- log.warning(s"received payment with amount too large for paymentHash=${htlc.paymentHash} amountMsat=${htlc.amountMsat}")
+ case Some(amount) if htlc.amountMsat > amount * 2 =>
+ log.warning(s"received payment with amount too large for paymentHash=${htlc.paymentHash} amount=${htlc.amountMsat}")
sender ! CMD_FAIL_HTLC(htlc.id, Right(IncorrectOrUnknownPaymentDetails(htlc.amountMsat)), commit = true)
case _ =>
- log.info(s"received payment for paymentHash=${htlc.paymentHash} amountMsat=${htlc.amountMsat}")
+ log.info(s"received payment for paymentHash=${htlc.paymentHash} amount=${htlc.amountMsat}")
// amount is correct or was not specified in the payment request
nodeParams.db.payments.addIncomingPayment(IncomingPayment(htlc.paymentHash, htlc.amountMsat, Platform.currentTime))
sender ! CMD_FULFILL_HTLC(htlc.id, paymentPreimage, commit = true)
- context.system.eventStream.publish(PaymentReceived(MilliSatoshi(htlc.amountMsat), htlc.paymentHash, htlc.channelId))
+ context.system.eventStream.publish(PaymentReceived(htlc.amountMsat, htlc.paymentHash, htlc.channelId))
}
case None =>
sender ! CMD_FAIL_HTLC(htlc.id, Right(IncorrectOrUnknownPaymentDetails(htlc.amountMsat)), commit = true)
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/payment/PaymentEvents.scala b/eclair-core/src/main/scala/fr/acinq/eclair/payment/PaymentEvents.scala
index 5901dce810..7b0f1b55c2 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/payment/PaymentEvents.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/payment/PaymentEvents.scala
@@ -17,7 +17,10 @@
package fr.acinq.eclair.payment
import java.util.UUID
-import fr.acinq.bitcoin.{ByteVector32, MilliSatoshi}
+
+import fr.acinq.bitcoin.ByteVector32
+import fr.acinq.eclair.MilliSatoshi
+
import scala.compat.Platform
/**
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/payment/PaymentLifecycle.scala b/eclair-core/src/main/scala/fr/acinq/eclair/payment/PaymentLifecycle.scala
index 907a68a25c..74374ec9d5 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/payment/PaymentLifecycle.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/payment/PaymentLifecycle.scala
@@ -20,7 +20,7 @@ import java.util.UUID
import akka.actor.{ActorRef, FSM, Props, Status}
import fr.acinq.bitcoin.Crypto.PublicKey
-import fr.acinq.bitcoin.{ByteVector32, MilliSatoshi}
+import fr.acinq.bitcoin.{ByteVector32, Satoshi}
import fr.acinq.eclair._
import fr.acinq.eclair.channel.{AddHtlcFailed, CMD_ADD_HTLC, Channel, Register}
import fr.acinq.eclair.crypto.{Sphinx, TransportHandler}
@@ -47,14 +47,14 @@ class PaymentLifecycle(nodeParams: NodeParams, id: UUID, router: ActorRef, regis
when(WAITING_FOR_REQUEST) {
case Event(c: SendPaymentToRoute, WaitingForRequest) =>
- val send = SendPayment(c.amountMsat, c.paymentHash, c.hops.last, finalCltvExpiry = c.finalCltvExpiry, maxAttempts = 1)
- paymentsDb.addOutgoingPayment(OutgoingPayment(id, c.paymentHash, None, c.amountMsat, Platform.currentTime, None, OutgoingPaymentStatus.PENDING))
+ val send = SendPayment(c.amount, c.paymentHash, c.hops.last, finalCltvExpiry = c.finalCltvExpiry, maxAttempts = 1)
+ paymentsDb.addOutgoingPayment(OutgoingPayment(id, c.paymentHash, None, c.amount, Platform.currentTime, None, OutgoingPaymentStatus.PENDING))
router ! FinalizeRoute(c.hops)
goto(WAITING_FOR_ROUTE) using WaitingForRoute(sender, send, failures = Nil)
case Event(c: SendPayment, WaitingForRequest) =>
- router ! RouteRequest(nodeParams.nodeId, c.targetNodeId, c.amountMsat, c.assistedRoutes, routeParams = c.routeParams)
- paymentsDb.addOutgoingPayment(OutgoingPayment(id, c.paymentHash, None, c.amountMsat, Platform.currentTime, None, OutgoingPaymentStatus.PENDING))
+ router ! RouteRequest(nodeParams.nodeId, c.targetNodeId, c.amount, c.assistedRoutes, routeParams = c.routeParams)
+ paymentsDb.addOutgoingPayment(OutgoingPayment(id, c.paymentHash, None, c.amount, Platform.currentTime, None, OutgoingPaymentStatus.PENDING))
goto(WAITING_FOR_ROUTE) using WaitingForRoute(sender, c, failures = Nil)
}
@@ -65,7 +65,7 @@ class PaymentLifecycle(nodeParams: NodeParams, id: UUID, router: ActorRef, regis
// we add one block in order to not have our htlc fail when a new block has just been found
val finalExpiry = Globals.blockCount.get().toInt + c.finalCltvExpiry.toInt + 1
- val (cmd, sharedSecrets) = buildCommand(id, c.amountMsat, finalExpiry, c.paymentHash, hops)
+ val (cmd, sharedSecrets) = buildCommand(id,c.amount, finalExpiry, c.paymentHash, hops)
register ! Register.ForwardShortId(firstHop.lastUpdate.shortChannelId, cmd)
goto(WAITING_FOR_PAYMENT_COMPLETE) using WaitingForComplete(s, c, cmd, failures, sharedSecrets, ignoreNodes, ignoreChannels, hops)
@@ -80,8 +80,8 @@ class PaymentLifecycle(nodeParams: NodeParams, id: UUID, router: ActorRef, regis
case Event(fulfill: UpdateFulfillHtlc, WaitingForComplete(s, c, cmd, _, _, _, _, hops)) =>
paymentsDb.updateOutgoingPayment(id, OutgoingPaymentStatus.SUCCEEDED, preimage = Some(fulfill.paymentPreimage))
- reply(s, PaymentSucceeded(id, cmd.amountMsat, c.paymentHash, fulfill.paymentPreimage, hops))
- context.system.eventStream.publish(PaymentSent(id, MilliSatoshi(c.amountMsat), MilliSatoshi(cmd.amountMsat - c.amountMsat), cmd.paymentHash, fulfill.paymentPreimage, fulfill.channelId))
+ reply(s, PaymentSucceeded(id, cmd.amount, c.paymentHash, fulfill.paymentPreimage, hops))
+ context.system.eventStream.publish(PaymentSent(id, c.amount, cmd.amount - c.amount, cmd.paymentHash, fulfill.paymentPreimage, fulfill.channelId))
stop(FSM.Normal)
case Event(fail: UpdateFailHtlc, WaitingForComplete(s, c, _, failures, sharedSecrets, ignoreNodes, ignoreChannels, hops)) =>
@@ -111,12 +111,12 @@ class PaymentLifecycle(nodeParams: NodeParams, id: UUID, router: ActorRef, regis
// in that case we don't know which node is sending garbage, let's try to blacklist all nodes except the one we are directly connected to and the destination node
val blacklist = hops.map(_.nextNodeId).drop(1).dropRight(1)
log.warning(s"blacklisting intermediate nodes=${blacklist.mkString(",")}")
- router ! RouteRequest(nodeParams.nodeId, c.targetNodeId, c.amountMsat, c.assistedRoutes, ignoreNodes ++ blacklist, ignoreChannels, c.routeParams)
+ router ! RouteRequest(nodeParams.nodeId, c.targetNodeId, c.amount, c.assistedRoutes, ignoreNodes ++ blacklist, ignoreChannels, c.routeParams)
goto(WAITING_FOR_ROUTE) using WaitingForRoute(s, c, failures :+ UnreadableRemoteFailure(hops))
case Success(e@Sphinx.DecryptedFailurePacket(nodeId, failureMessage: Node)) =>
log.info(s"received 'Node' type error message from nodeId=$nodeId, trying to route around it (failure=$failureMessage)")
// let's try to route around this node
- router ! RouteRequest(nodeParams.nodeId, c.targetNodeId, c.amountMsat, c.assistedRoutes, ignoreNodes + nodeId, ignoreChannels, c.routeParams)
+ router ! RouteRequest(nodeParams.nodeId, c.targetNodeId, c.amount, c.assistedRoutes, ignoreNodes + nodeId, ignoreChannels, c.routeParams)
goto(WAITING_FOR_ROUTE) using WaitingForRoute(s, c, failures :+ RemoteFailure(hops, e))
case Success(e@Sphinx.DecryptedFailurePacket(nodeId, failureMessage: Update)) =>
log.info(s"received 'Update' type error message from nodeId=$nodeId, retrying payment (failure=$failureMessage)")
@@ -144,18 +144,18 @@ class PaymentLifecycle(nodeParams: NodeParams, id: UUID, router: ActorRef, regis
// in any case, we forward the update to the router
router ! failureMessage.update
// let's try again, router will have updated its state
- router ! RouteRequest(nodeParams.nodeId, c.targetNodeId, c.amountMsat, c.assistedRoutes, ignoreNodes, ignoreChannels, c.routeParams)
+ router ! RouteRequest(nodeParams.nodeId, c.targetNodeId, c.amount, c.assistedRoutes, ignoreNodes, ignoreChannels, c.routeParams)
} else {
// this node is fishy, it gave us a bad sig!! let's filter it out
log.warning(s"got bad signature from node=$nodeId update=${failureMessage.update}")
- router ! RouteRequest(nodeParams.nodeId, c.targetNodeId, c.amountMsat, c.assistedRoutes, ignoreNodes + nodeId, ignoreChannels, c.routeParams)
+ router ! RouteRequest(nodeParams.nodeId, c.targetNodeId, c.amount, c.assistedRoutes, ignoreNodes + nodeId, ignoreChannels, c.routeParams)
}
goto(WAITING_FOR_ROUTE) using WaitingForRoute(s, c, failures :+ RemoteFailure(hops, e))
case Success(e@Sphinx.DecryptedFailurePacket(nodeId, failureMessage)) =>
log.info(s"received an error message from nodeId=$nodeId, trying to use a different channel (failure=$failureMessage)")
// let's try again without the channel outgoing from nodeId
val faultyChannel = hops.find(_.nodeId == nodeId).map(hop => ChannelDesc(hop.lastUpdate.shortChannelId, hop.nodeId, hop.nextNodeId))
- router ! RouteRequest(nodeParams.nodeId, c.targetNodeId, c.amountMsat, c.assistedRoutes, ignoreNodes, ignoreChannels ++ faultyChannel.toSet, c.routeParams)
+ router ! RouteRequest(nodeParams.nodeId, c.targetNodeId, c.amount, c.assistedRoutes, ignoreNodes, ignoreChannels ++ faultyChannel.toSet, c.routeParams)
goto(WAITING_FOR_ROUTE) using WaitingForRoute(s, c, failures :+ RemoteFailure(hops, e))
}
@@ -175,7 +175,7 @@ class PaymentLifecycle(nodeParams: NodeParams, id: UUID, router: ActorRef, regis
} else {
log.info(s"received an error message from local, trying to use a different channel (failure=${t.getMessage})")
val faultyChannel = ChannelDesc(hops.head.lastUpdate.shortChannelId, hops.head.nodeId, hops.head.nextNodeId)
- router ! RouteRequest(nodeParams.nodeId, c.targetNodeId, c.amountMsat, c.assistedRoutes, ignoreNodes, ignoreChannels + faultyChannel, c.routeParams)
+ router ! RouteRequest(nodeParams.nodeId, c.targetNodeId, c.amount, c.assistedRoutes, ignoreNodes, ignoreChannels + faultyChannel, c.routeParams)
goto(WAITING_FOR_ROUTE) using WaitingForRoute(s, c, failures :+ LocalFailure(t))
}
@@ -198,21 +198,21 @@ object PaymentLifecycle {
def props(nodeParams: NodeParams, id: UUID, router: ActorRef, register: ActorRef) = Props(classOf[PaymentLifecycle], nodeParams, id, router, register)
// @formatter:off
- case class ReceivePayment(amountMsat_opt: Option[MilliSatoshi], description: String, expirySeconds_opt: Option[Long] = None, extraHops: List[List[ExtraHop]] = Nil, fallbackAddress: Option[String] = None, paymentPreimage: Option[ByteVector32] = None)
+ case class ReceivePayment(amount_opt: Option[MilliSatoshi], description: String, expirySeconds_opt: Option[Long] = None, extraHops: List[List[ExtraHop]] = Nil, fallbackAddress: Option[String] = None, paymentPreimage: Option[ByteVector32] = None)
sealed trait GenericSendPayment
- case class SendPaymentToRoute(amountMsat: Long, paymentHash: ByteVector32, hops: Seq[PublicKey], finalCltvExpiry: Long = Channel.MIN_CLTV_EXPIRY) extends GenericSendPayment
- case class SendPayment(amountMsat: Long,
+ case class SendPaymentToRoute(amount: MilliSatoshi, paymentHash: ByteVector32, hops: Seq[PublicKey], finalCltvExpiry: Long = Channel.MIN_CLTV_EXPIRY) extends GenericSendPayment
+ case class SendPayment(amount: MilliSatoshi,
paymentHash: ByteVector32,
targetNodeId: PublicKey,
assistedRoutes: Seq[Seq[ExtraHop]] = Nil,
finalCltvExpiry: Long = Channel.MIN_CLTV_EXPIRY,
maxAttempts: Int,
routeParams: Option[RouteParams] = None) extends GenericSendPayment {
- require(amountMsat > 0, s"amountMsat must be > 0")
+ require(amount > MilliSatoshi(0), s"amountMsat must be > 0")
}
sealed trait PaymentResult
- case class PaymentSucceeded(id: UUID, amountMsat: Long, paymentHash: ByteVector32, paymentPreimage: ByteVector32, route: Seq[Hop]) extends PaymentResult // note: the amount includes fees
+ case class PaymentSucceeded(id: UUID, amount: MilliSatoshi, paymentHash: ByteVector32, paymentPreimage: ByteVector32, route: Seq[Hop]) extends PaymentResult // note: the amount includes fees
sealed trait PaymentFailure
case class LocalFailure(t: Throwable) extends PaymentFailure
case class RemoteFailure(route: Seq[Hop], e: Sphinx.DecryptedFailurePacket) extends PaymentFailure
@@ -246,7 +246,7 @@ object PaymentLifecycle {
/**
*
- * @param finalAmountMsat the final htlc amount in millisatoshis
+ * @param finalAmount the final htlc amount in millisatoshis
* @param finalExpiry the final htlc expiry in number of blocks
* @param hops the hops as computed by the router + extra routes from payment request
* @return a (firstAmountMsat, firstExpiry, payloads) tuple where:
@@ -254,19 +254,19 @@ object PaymentLifecycle {
* - firstExpiry is the cltv expiry for the first htlc in the route
* - a sequence of payloads that will be used to build the onion
*/
- def buildPayloads(finalAmountMsat: Long, finalExpiry: Long, hops: Seq[Hop]): (Long, Long, Seq[PerHopPayload]) =
- hops.reverse.foldLeft((finalAmountMsat, finalExpiry, PerHopPayload(ShortChannelId(0L), finalAmountMsat, finalExpiry) :: Nil)) {
+ def buildPayloads(finalAmount: MilliSatoshi, finalExpiry: Long, hops: Seq[Hop]): (MilliSatoshi, Long, Seq[PerHopPayload]) =
+ hops.reverse.foldLeft((finalAmount, finalExpiry, PerHopPayload(ShortChannelId(0L), finalAmount, finalExpiry) :: Nil)) {
case ((msat, expiry, payloads), hop) =>
val nextFee = nodeFee(hop.lastUpdate.feeBaseMsat, hop.lastUpdate.feeProportionalMillionths, msat)
(msat + nextFee, expiry + hop.lastUpdate.cltvExpiryDelta, PerHopPayload(hop.lastUpdate.shortChannelId, msat, expiry) +: payloads)
}
- def buildCommand(id: UUID, finalAmountMsat: Long, finalExpiry: Long, paymentHash: ByteVector32, hops: Seq[Hop]): (CMD_ADD_HTLC, Seq[(ByteVector32, PublicKey)]) = {
- val (firstAmountMsat, firstExpiry, payloads) = buildPayloads(finalAmountMsat, finalExpiry, hops.drop(1))
+ def buildCommand(id: UUID, finalAmount: MilliSatoshi, finalExpiry: Long, paymentHash: ByteVector32, hops: Seq[Hop]): (CMD_ADD_HTLC, Seq[(ByteVector32, PublicKey)]) = {
+ val (firstAmount, firstExpiry, payloads) = buildPayloads(finalAmount, finalExpiry, hops.drop(1))
val nodes = hops.map(_.nextNodeId)
// BOLT 2 requires that associatedData == paymentHash
val onion = buildOnion(nodes, payloads, paymentHash)
- CMD_ADD_HTLC(firstAmountMsat, paymentHash, firstExpiry, onion.packet, upstream = Left(id), commit = true) -> onion.sharedSecrets
+ CMD_ADD_HTLC(firstAmount, paymentHash, firstExpiry, onion.packet, upstream = Left(id), commit = true) -> onion.sharedSecrets
}
/**
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/payment/PaymentRequest.scala b/eclair-core/src/main/scala/fr/acinq/eclair/payment/PaymentRequest.scala
index b5c6da04f9..fc6ea0ca3e 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/payment/PaymentRequest.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/payment/PaymentRequest.scala
@@ -16,13 +16,14 @@
package fr.acinq.eclair.payment
+import fr.acinq.bitcoin.{Base58, Base58Check, Bech32, Block, ByteVector32, ByteVector64, Crypto}
import fr.acinq.bitcoin.Crypto.{PrivateKey, PublicKey}
-import fr.acinq.bitcoin.{MilliSatoshi, _}
-import fr.acinq.eclair.ShortChannelId
+import fr.acinq.eclair.{MilliSatoshi, ShortChannelId}
import fr.acinq.eclair.payment.PaymentRequest._
import scodec.Codec
import scodec.bits.{BitVector, ByteOrdering, ByteVector}
import scodec.codecs.{list, ubyte}
+
import scala.concurrent.duration._
import scala.compat.Platform
import scala.util.Try
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/payment/Relayer.scala b/eclair-core/src/main/scala/fr/acinq/eclair/payment/Relayer.scala
index d5d6b9f17e..7112bdd0ba 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/payment/Relayer.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/payment/Relayer.scala
@@ -21,14 +21,14 @@ import java.util.UUID
import akka.actor.{Actor, ActorLogging, ActorRef, Props, Status}
import akka.event.LoggingAdapter
import fr.acinq.bitcoin.Crypto.{PrivateKey, PublicKey}
-import fr.acinq.bitcoin.{ByteVector32, MilliSatoshi}
+import fr.acinq.bitcoin.ByteVector32
import fr.acinq.eclair.channel._
import fr.acinq.eclair.crypto.Sphinx
import fr.acinq.eclair.db.OutgoingPaymentStatus
import fr.acinq.eclair.payment.PaymentLifecycle.{PaymentFailed, PaymentSucceeded}
import fr.acinq.eclair.router.Announcements
import fr.acinq.eclair.wire._
-import fr.acinq.eclair.{NodeParams, ShortChannelId, nodeFee}
+import fr.acinq.eclair.{MilliSatoshi, NodeParams, ShortChannelId, nodeFee}
import grizzled.slf4j.Logging
import scodec.{Attempt, DecodeResult}
@@ -38,7 +38,7 @@ import scala.collection.mutable
sealed trait Origin
case class Local(id: UUID, sender: Option[ActorRef]) extends Origin // we don't persist reference to local actors
-case class Relayed(originChannelId: ByteVector32, originHtlcId: Long, amountMsatIn: Long, amountMsatOut: Long) extends Origin
+case class Relayed(originChannelId: ByteVector32, originHtlcId: Long, amountIn: MilliSatoshi, amountOut: MilliSatoshi) extends Origin
sealed trait ForwardMessage
case class ForwardAdd(add: UpdateAddHtlc, previousFailures: Seq[AddHtlcFailed] = Seq.empty) extends ForwardMessage
@@ -47,7 +47,7 @@ case class ForwardFail(fail: UpdateFailHtlc, to: Origin, htlc: UpdateAddHtlc) ex
case class ForwardFailMalformed(fail: UpdateFailMalformedHtlc, to: Origin, htlc: UpdateAddHtlc) extends ForwardMessage
case object GetUsableBalances
-case class UsableBalances(remoteNodeId: PublicKey, shortChannelId: ShortChannelId, canSendMsat: Long, canReceiveMsat: Long, isPublic: Boolean)
+case class UsableBalances(remoteNodeId: PublicKey, shortChannelId: ShortChannelId, canSend: MilliSatoshi, canReceive: MilliSatoshi, isPublic: Boolean)
// @formatter:on
@@ -77,8 +77,8 @@ class Relayer(nodeParams: NodeParams, register: ActorRef, paymentHandler: ActorR
.map(o => UsableBalances(
remoteNodeId = o.nextNodeId,
shortChannelId = o.channelUpdate.shortChannelId,
- canSendMsat = o.commitments.availableBalanceForSendMsat,
- canReceiveMsat = o.commitments.availableBalanceForReceiveMsat,
+ canSend = o.commitments.availableBalanceForSend,
+ canReceive = o.commitments.availableBalanceForReceive,
isPublic = o.commitments.announceChannel))
case LocalChannelUpdate(_, channelId, shortChannelId, remoteNodeId, _, channelUpdate, commitments) =>
@@ -158,17 +158,17 @@ class Relayer(nodeParams: NodeParams, register: ActorRef, paymentHandler: ActorR
to match {
case Local(id, None) =>
val feesPaid = MilliSatoshi(0)
- context.system.eventStream.publish(PaymentSent(id, MilliSatoshi(add.amountMsat), feesPaid, add.paymentHash, fulfill.paymentPreimage, fulfill.channelId))
+ context.system.eventStream.publish(PaymentSent(id, add.amountMsat, feesPaid, add.paymentHash, fulfill.paymentPreimage, fulfill.channelId))
// we sent the payment, but we probably restarted and the reference to the original sender was lost,
// we publish the failure on the event stream and update the status in paymentDb
nodeParams.db.payments.updateOutgoingPayment(id, OutgoingPaymentStatus.SUCCEEDED, Some(fulfill.paymentPreimage))
context.system.eventStream.publish(PaymentSucceeded(id, add.amountMsat, add.paymentHash, fulfill.paymentPreimage, Nil)) //
case Local(_, Some(sender)) =>
sender ! fulfill
- case Relayed(originChannelId, originHtlcId, amountMsatIn, amountMsatOut) =>
+ case Relayed(originChannelId, originHtlcId, amountIn, amountOut) =>
val cmd = CMD_FULFILL_HTLC(originHtlcId, fulfill.paymentPreimage, commit = true)
commandBuffer ! CommandBuffer.CommandSend(originChannelId, originHtlcId, cmd)
- context.system.eventStream.publish(PaymentRelayed(MilliSatoshi(amountMsatIn), MilliSatoshi(amountMsatOut), add.paymentHash, fromChannelId = originChannelId, toChannelId = fulfill.channelId))
+ context.system.eventStream.publish(PaymentRelayed(amountIn, amountOut, add.paymentHash, fromChannelId = originChannelId, toChannelId = fulfill.channelId))
}
case ForwardFail(fail, to, add) =>
@@ -215,7 +215,7 @@ object Relayer extends Logging {
sealed trait NextPayload
case class FinalPayload(add: UpdateAddHtlc, payload: PerHopPayload) extends NextPayload
case class RelayPayload(add: UpdateAddHtlc, payload: PerHopPayload, nextPacket: OnionRoutingPacket) extends NextPayload {
- val relayFeeMsat: Long = add.amountMsat - payload.amtToForward
+ val relayFeeMsat: MilliSatoshi = add.amountMsat - payload.amtToForward
val expiryDelta: Long = add.cltvExpiry - payload.outgoingCltvValue
}
// @formatter:on
@@ -330,10 +330,10 @@ object Relayer extends Logging {
val channelInfo_opt = channelUpdates.get(shortChannelId)
val channelUpdate_opt = channelInfo_opt.map(_.channelUpdate)
val relayResult = relayOrFail(relayPayload, channelUpdate_opt)
- log.debug(s"candidate channel for htlc #${add.id} paymentHash=${add.paymentHash}: shortChannelId={} balanceMsat={} channelUpdate={} relayResult={}", shortChannelId, channelInfo_opt.map(_.commitments.availableBalanceForSendMsat).getOrElse(""), channelUpdate_opt.getOrElse(""), relayResult)
+ log.debug(s"candidate channel for htlc #${add.id} paymentHash=${add.paymentHash}: shortChannelId={} balanceMsat={} channelUpdate={} relayResult={}", shortChannelId, channelInfo_opt.map(_.commitments.availableBalanceForSend).getOrElse(""), channelUpdate_opt.getOrElse(""), relayResult)
(shortChannelId, channelInfo_opt, relayResult)
}
- .collect { case (shortChannelId, Some(channelInfo), _: RelaySuccess) => (shortChannelId, channelInfo.commitments.availableBalanceForSendMsat) }
+ .collect { case (shortChannelId, Some(channelInfo), _: RelaySuccess) => (shortChannelId, channelInfo.commitments.availableBalanceForSend) }
.filter(_._2 > relayPayload.payload.amtToForward) // we only keep channels that have enough balance to handle this payment
.toList // needed for ordering
.sortBy(_._2) // we want to use the channel with the lowest available balance that can process the payment
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/router/Announcements.scala b/eclair-core/src/main/scala/fr/acinq/eclair/router/Announcements.scala
index 1e76f48b7b..abbfd61d4e 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/router/Announcements.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/router/Announcements.scala
@@ -19,7 +19,7 @@ package fr.acinq.eclair.router
import fr.acinq.bitcoin.Crypto.{PrivateKey, PublicKey, sha256, verifySignature}
import fr.acinq.bitcoin.{ByteVector32, ByteVector64, Crypto, LexicographicalOrdering}
import fr.acinq.eclair.wire._
-import fr.acinq.eclair.{Features, ShortChannelId, serializationResult}
+import fr.acinq.eclair.{Features, MilliSatoshi, ShortChannelId, serializationResult}
import scodec.bits.{BitVector, ByteVector}
import shapeless.HNil
@@ -37,7 +37,7 @@ object Announcements {
def nodeAnnouncementWitnessEncode(timestamp: Long, nodeId: PublicKey, rgbColor: Color, alias: String, features: ByteVector, addresses: List[NodeAddress], unknownFields: ByteVector): ByteVector =
sha256(sha256(serializationResult(LightningMessageCodecs.nodeAnnouncementWitnessCodec.encode(features :: timestamp :: nodeId :: rgbColor :: alias :: addresses :: unknownFields :: HNil))))
- def channelUpdateWitnessEncode(chainHash: ByteVector32, shortChannelId: ShortChannelId, timestamp: Long, messageFlags: Byte, channelFlags: Byte, cltvExpiryDelta: Int, htlcMinimumMsat: Long, feeBaseMsat: Long, feeProportionalMillionths: Long, htlcMaximumMsat: Option[Long], unknownFields: ByteVector): ByteVector =
+ def channelUpdateWitnessEncode(chainHash: ByteVector32, shortChannelId: ShortChannelId, timestamp: Long, messageFlags: Byte, channelFlags: Byte, cltvExpiryDelta: Int, htlcMinimumMsat: MilliSatoshi, feeBaseMsat: MilliSatoshi, feeProportionalMillionths: Long, htlcMaximumMsat: Option[MilliSatoshi], unknownFields: ByteVector): ByteVector =
sha256(sha256(serializationResult(LightningMessageCodecs.channelUpdateWitnessCodec.encode(chainHash :: shortChannelId :: timestamp :: messageFlags :: channelFlags :: cltvExpiryDelta :: htlcMinimumMsat :: feeBaseMsat :: feeProportionalMillionths :: htlcMaximumMsat :: unknownFields :: HNil))))
def signChannelAnnouncement(chainHash: ByteVector32, shortChannelId: ShortChannelId, localNodeSecret: PrivateKey, remoteNodeId: PublicKey, localFundingPrivKey: PrivateKey, remoteFundingKey: PublicKey, features: ByteVector): (ByteVector64, ByteVector64) = {
@@ -128,7 +128,7 @@ object Announcements {
def makeChannelFlags(isNode1: Boolean, enable: Boolean): Byte = BitVector.bits(!enable :: !isNode1 :: Nil).padLeft(8).toByte()
- def makeChannelUpdate(chainHash: ByteVector32, nodeSecret: PrivateKey, remoteNodeId: PublicKey, shortChannelId: ShortChannelId, cltvExpiryDelta: Int, htlcMinimumMsat: Long, feeBaseMsat: Long, feeProportionalMillionths: Long, htlcMaximumMsat: Long, enable: Boolean = true, timestamp: Long = Platform.currentTime.milliseconds.toSeconds): ChannelUpdate = {
+ def makeChannelUpdate(chainHash: ByteVector32, nodeSecret: PrivateKey, remoteNodeId: PublicKey, shortChannelId: ShortChannelId, cltvExpiryDelta: Int, htlcMinimumMsat: MilliSatoshi, feeBaseMsat: MilliSatoshi, feeProportionalMillionths: Long, htlcMaximumMsat: MilliSatoshi, enable: Boolean = true, timestamp: Long = Platform.currentTime.milliseconds.toSeconds): ChannelUpdate = {
val messageFlags = makeMessageFlags(hasOptionChannelHtlcMax = true) // NB: we always support option_channel_htlc_max
val channelFlags = makeChannelFlags(isNode1 = isNode1(nodeSecret.publicKey, remoteNodeId), enable = enable)
val htlcMaximumMsatOpt = Some(htlcMaximumMsat)
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/router/Graph.scala b/eclair-core/src/main/scala/fr/acinq/eclair/router/Graph.scala
index 178036a3ae..27e92a3238 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/router/Graph.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/router/Graph.scala
@@ -29,7 +29,7 @@ object Graph {
// @formatter:off
// A compound weight for an edge, weight is obtained with (cost X factor),'cost' contains the actual amount+fees in millisatoshi, 'cltvCumulative' the total CLTV necessary to reach this edge
- case class RichWeight(cost: Long, length: Int, cltv: Int, weight: Double) extends Ordered[RichWeight] {
+ case class RichWeight(cost: MilliSatoshi, length: Int, cltv: Int, weight: Double) extends Ordered[RichWeight] {
override def compare(that: RichWeight): Int = this.weight.compareTo(that.weight)
}
case class WeightRatios(cltvDeltaFactor: Double, ageFactor: Double, capacityFactor: Double) {
@@ -62,7 +62,7 @@ object Graph {
* @param graph
* @param sourceNode
* @param targetNode
- * @param amountMsat
+ * @param amount
* @param pathsToFind
* @param wr an object containing the ratios used to 'weight' edges when searching for the shortest path
* @param currentBlockHeight the height of the chain tip (latest block)
@@ -72,7 +72,7 @@ object Graph {
def yenKshortestPaths(graph: DirectedGraph,
sourceNode: PublicKey,
targetNode: PublicKey,
- amountMsat: Long,
+ amount: MilliSatoshi,
ignoredEdges: Set[ChannelDesc],
extraEdges: Set[GraphEdge],
pathsToFind: Int,
@@ -88,9 +88,9 @@ object Graph {
val candidates = new mutable.PriorityQueue[WeightedPath]
// find the shortest path, k = 0
- val initialWeight = RichWeight(cost = amountMsat, 0, 0, 0)
+ val initialWeight = RichWeight(cost = amount, 0, 0, 0)
val shortestPath = dijkstraShortestPath(graph, sourceNode, targetNode, ignoredEdges, extraEdges, initialWeight, boundaries, currentBlockHeight, wr)
- shortestPaths += WeightedPath(shortestPath, pathWeight(shortestPath, amountMsat, isPartial = false, currentBlockHeight, wr))
+ shortestPaths += WeightedPath(shortestPath, pathWeight(shortestPath, amount, isPartial = false, currentBlockHeight, wr))
// avoid returning a list with an empty path
if (shortestPath.isEmpty) return Seq.empty
@@ -110,7 +110,7 @@ object Graph {
// select the sub-path from the source to the spur node of the k-th previous shortest path
val rootPathEdges = if (i == 0) prevShortestPath.head :: Nil else prevShortestPath.take(i)
- val rootPathWeight = pathWeight(rootPathEdges, amountMsat, isPartial = true, currentBlockHeight, wr)
+ val rootPathWeight = pathWeight(rootPathEdges, amount, isPartial = true, currentBlockHeight, wr)
// links to be removed that are part of the previous shortest path and which share the same root path
val edgesToIgnore = shortestPaths.flatMap { weightedPath =>
@@ -136,7 +136,7 @@ object Graph {
case false => rootPathEdges ++ spurPath
}
- val candidatePath = WeightedPath(totalPath, pathWeight(totalPath, amountMsat, isPartial = false, currentBlockHeight, wr))
+ val candidatePath = WeightedPath(totalPath, pathWeight(totalPath, amount, isPartial = false, currentBlockHeight, wr))
if (boundaries(candidatePath.weight) && !shortestPaths.contains(candidatePath) && !candidates.exists(_ == candidatePath)) {
candidates.enqueue(candidatePath)
@@ -237,7 +237,7 @@ object Graph {
// we call containsKey first because "getOrDefault" is not available in JDK7
val neighborCost = weight.containsKey(neighbor) match {
- case false => RichWeight(Long.MaxValue, Int.MaxValue, Int.MaxValue, Double.MaxValue)
+ case false => RichWeight(MilliSatoshi(Long.MaxValue), Int.MaxValue, Int.MaxValue, Double.MaxValue)
case true => weight.get(neighbor)
}
@@ -281,7 +281,7 @@ object Graph {
private def edgeWeight(edge: GraphEdge, prev: RichWeight, isNeighborTarget: Boolean, currentBlockHeight: Long, weightRatios: Option[WeightRatios]): RichWeight = weightRatios match {
case None =>
val edgeCost = if (isNeighborTarget) prev.cost else edgeFeeCost(edge, prev.cost)
- RichWeight(cost = edgeCost, length = prev.length + 1, cltv = prev.cltv + edge.update.cltvExpiryDelta, weight = edgeCost)
+ RichWeight(cost = edgeCost, length = prev.length + 1, cltv = prev.cltv + edge.update.cltvExpiryDelta, weight = edgeCost.toLong)
case Some(wr) =>
import RoutingHeuristics._
@@ -291,8 +291,8 @@ object Graph {
val ageFactor = normalize(channelBlockHeight, min = currentBlockHeight - BLOCK_TIME_TWO_MONTHS, max = currentBlockHeight)
// Every edge is weighted by channel capacity, larger channels add less weight
- val edgeMaxCapacity = edge.update.htlcMaximumMsat.getOrElse(CAPACITY_CHANNEL_LOW_MSAT)
- val capFactor = 1 - normalize(edgeMaxCapacity, CAPACITY_CHANNEL_LOW_MSAT, CAPACITY_CHANNEL_HIGH_MSAT)
+ val edgeMaxCapacity = edge.update.htlcMaximumMsat.getOrElse(CAPACITY_CHANNEL_LOW)
+ val capFactor = 1 - normalize(edgeMaxCapacity.toLong, CAPACITY_CHANNEL_LOW.toLong, CAPACITY_CHANNEL_HIGH.toLong)
// Every edge is weighted by its clvt-delta value, normalized
val channelCltvDelta = edge.update.cltvExpiryDelta
@@ -303,7 +303,7 @@ object Graph {
// NB we're guaranteed to have weightRatios and factors > 0
val factor = (cltvFactor * wr.cltvDeltaFactor) + (ageFactor * wr.ageFactor) + (capFactor * wr.capacityFactor)
- val edgeWeight = if (isNeighborTarget) prev.weight else prev.weight + edgeCost * factor
+ val edgeWeight = if (isNeighborTarget) prev.weight else prev.weight + edgeCost.toLong * factor
RichWeight(cost = edgeCost, length = prev.length + 1, cltv = prev.cltv + channelCltvDelta, weight = edgeWeight)
}
@@ -317,17 +317,17 @@ object Graph {
* @param amountWithFees the value that this edge will have to carry along
* @return the new amount updated with the necessary fees for this edge
*/
- private def edgeFeeCost(edge: GraphEdge, amountWithFees: Long): Long = {
- if(edgeHasZeroFee(edge)) amountWithFees + nodeFee(baseMsat = 1, proportional = 0, amountWithFees)
+ private def edgeFeeCost(edge: GraphEdge, amountWithFees: MilliSatoshi):MilliSatoshi = {
+ if(edgeHasZeroFee(edge)) amountWithFees + nodeFee(baseMsat = MilliSatoshi(1), proportional = 0, amountWithFees)
else amountWithFees + nodeFee(edge.update.feeBaseMsat, edge.update.feeProportionalMillionths, amountWithFees)
}
private def edgeHasZeroFee(edge: GraphEdge): Boolean = {
- edge.update.feeBaseMsat == 0 && edge.update.feeProportionalMillionths == 0
+ edge.update.feeBaseMsat.toLong == 0 && edge.update.feeProportionalMillionths == 0
}
// Calculates the total cost of a path (amount + fees), direct channels with the source will have a cost of 0 (pay no fees)
- def pathWeight(path: Seq[GraphEdge], amountMsat: Long, isPartial: Boolean, currentBlockHeight: Long, wr: Option[WeightRatios]): RichWeight = {
+ def pathWeight(path: Seq[GraphEdge], amountMsat: MilliSatoshi, isPartial: Boolean, currentBlockHeight: Long, wr: Option[WeightRatios]): RichWeight = {
path.drop(if (isPartial) 0 else 1).foldRight(RichWeight(amountMsat, 0, 0, 0)) { (edge, prev) =>
edgeWeight(edge, prev, false, currentBlockHeight, wr)
}
@@ -340,8 +340,8 @@ object Graph {
val BLOCK_TIME_TWO_MONTHS = 8640
// Low/High bound for channel capacity
- val CAPACITY_CHANNEL_LOW_MSAT = 1000 * 1000L // 1000 sat
- val CAPACITY_CHANNEL_HIGH_MSAT = Channel.MAX_FUNDING_SATOSHIS * 1000L
+ val CAPACITY_CHANNEL_LOW = MilliSatoshi(1000 * 1000L) // 1000 sat
+ val CAPACITY_CHANNEL_HIGH = Channel.MAX_FUNDING.toMilliSatoshi
// Low/High bound for CLTV channel value
val CLTV_LOW = 9
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 77b70124eb..6e969dbb1e 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
@@ -19,7 +19,7 @@ package fr.acinq.eclair.router
import akka.Done
import akka.actor.{ActorRef, Props, Status}
import akka.event.Logging.MDC
-import fr.acinq.bitcoin.{ByteVector32, ByteVector64}
+import fr.acinq.bitcoin.{ByteVector32, ByteVector64, Satoshi}
import fr.acinq.bitcoin.Crypto.PublicKey
import fr.acinq.bitcoin.Script.{pay2wsh, write}
import fr.acinq.eclair._
@@ -47,7 +47,7 @@ import scala.util.{Random, Try}
case class RouterConf(randomizeRouteSelection: Boolean,
channelExcludeDuration: FiniteDuration,
routerBroadcastInterval: FiniteDuration,
- searchMaxFeeBaseSat: Long,
+ searchMaxFeeBase: Satoshi,
searchMaxFeePct: Double,
searchMaxRouteLength: Int,
searchMaxCltv: Int,
@@ -58,10 +58,10 @@ case class RouterConf(randomizeRouteSelection: Boolean,
case class ChannelDesc(shortChannelId: ShortChannelId, a: PublicKey, b: PublicKey)
case class Hop(nodeId: PublicKey, nextNodeId: PublicKey, lastUpdate: ChannelUpdate)
-case class RouteParams(randomize: Boolean, maxFeeBaseMsat: Long, maxFeePct: Double, routeMaxLength: Int, routeMaxCltv: Int, ratios: Option[WeightRatios])
+case class RouteParams(randomize: Boolean, maxFeeBase: MilliSatoshi, maxFeePct: Double, routeMaxLength: Int, routeMaxCltv: Int, ratios: Option[WeightRatios])
case class RouteRequest(source: PublicKey,
target: PublicKey,
- amountMsat: Long,
+ amount: MilliSatoshi,
assistedRoutes: Seq[Seq[ExtraHop]] = Nil,
ignoreNodes: Set[PublicKey] = Set.empty,
ignoreChannels: Set[ChannelDesc] = Set.empty,
@@ -732,7 +732,7 @@ object Router {
def toFakeUpdate(extraHop: ExtraHop): ChannelUpdate =
// the `direction` bit in flags will not be accurate but it doesn't matter because it is not used
// what matters is that the `disable` bit is 0 so that this update doesn't get filtered out
- ChannelUpdate(signature = ByteVector64.Zeroes, chainHash = ByteVector32.Zeroes, extraHop.shortChannelId, Platform.currentTime.milliseconds.toSeconds, messageFlags = 0, channelFlags = 0, extraHop.cltvExpiryDelta, htlcMinimumMsat = 0L, extraHop.feeBaseMsat, extraHop.feeProportionalMillionths, None)
+ ChannelUpdate(signature = ByteVector64.Zeroes, chainHash = ByteVector32.Zeroes, extraHop.shortChannelId, Platform.currentTime.milliseconds.toSeconds, messageFlags = 0, channelFlags = 0, extraHop.cltvExpiryDelta, htlcMinimumMsat = MilliSatoshi(0), MilliSatoshi(extraHop.feeBaseMsat), extraHop.feeProportionalMillionths, None)
def toFakeUpdates(extraRoute: Seq[ExtraHop], targetNodeId: PublicKey): Map[ChannelDesc, ChannelUpdate] = {
// BOLT 11: "For each entry, the pubkey is the node ID of the start of the channel", and the last node is the destination
@@ -827,7 +827,7 @@ object Router {
def getDefaultRouteParams(routerConf: RouterConf) = RouteParams(
randomize = routerConf.randomizeRouteSelection,
- maxFeeBaseMsat = routerConf.searchMaxFeeBaseSat * 1000, // converting sat -> msat
+ maxFeeBase = routerConf.searchMaxFeeBase.toMilliSatoshi,
maxFeePct = routerConf.searchMaxFeePct,
routeMaxLength = routerConf.searchMaxRouteLength,
routeMaxCltv = routerConf.searchMaxCltv,
@@ -848,7 +848,7 @@ object Router {
* @param g
* @param localNodeId
* @param targetNodeId
- * @param amountMsat the amount that will be sent along this route
+ * @param amount the amount that will be sent along this route
* @param numRoutes the number of shortest-paths to find
* @param extraEdges a set of extra edges we want to CONSIDER during the search
* @param ignoredEdges a set of extra edges we want to IGNORE during the search
@@ -858,7 +858,7 @@ object Router {
def findRoute(g: DirectedGraph,
localNodeId: PublicKey,
targetNodeId: PublicKey,
- amountMsat: Long,
+ amount: MilliSatoshi,
numRoutes: Int,
extraEdges: Set[GraphEdge] = Set.empty,
ignoredEdges: Set[ChannelDesc] = Set.empty,
@@ -869,14 +869,14 @@ object Router {
val currentBlockHeight = Globals.blockCount.get()
val boundaries: RichWeight => Boolean = { weight =>
- ((weight.cost - amountMsat) < routeParams.maxFeeBaseMsat || (weight.cost - amountMsat) < (routeParams.maxFeePct * amountMsat)) &&
+ ((weight.cost - amount) < routeParams.maxFeeBase || (weight.cost - amount) < amount * routeParams.maxFeePct.toLong) &&
weight.length <= routeParams.routeMaxLength && weight.length <= ROUTE_MAX_LENGTH &&
weight.cltv <= routeParams.routeMaxCltv
}
- val foundRoutes = Graph.yenKshortestPaths(g, localNodeId, targetNodeId, amountMsat, ignoredEdges, extraEdges, numRoutes, routeParams.ratios, currentBlockHeight, boundaries).toList match {
+ val foundRoutes = Graph.yenKshortestPaths(g, localNodeId, targetNodeId, amount, ignoredEdges, extraEdges, numRoutes, routeParams.ratios, currentBlockHeight, boundaries).toList match {
case Nil if routeParams.routeMaxLength < ROUTE_MAX_LENGTH => // if not found within the constraints we relax and repeat the search
- return findRoute(g, localNodeId, targetNodeId, amountMsat, numRoutes, extraEdges, ignoredEdges, routeParams.copy(routeMaxLength = ROUTE_MAX_LENGTH, routeMaxCltv = DEFAULT_ROUTE_MAX_CLTV))
+ return findRoute(g, localNodeId, targetNodeId, amount, numRoutes, extraEdges, ignoredEdges, routeParams.copy(routeMaxLength = ROUTE_MAX_LENGTH, routeMaxCltv = DEFAULT_ROUTE_MAX_CLTV))
case Nil => throw RouteNotFound
case routes => routes.find(_.path.size == 1) match {
case Some(directRoute) => directRoute :: Nil
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/transactions/CommitmentSpec.scala b/eclair-core/src/main/scala/fr/acinq/eclair/transactions/CommitmentSpec.scala
index 3448ecfe99..d4b201202d 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/transactions/CommitmentSpec.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/transactions/CommitmentSpec.scala
@@ -16,6 +16,7 @@
package fr.acinq.eclair.transactions
+import fr.acinq.eclair.MilliSatoshi
import fr.acinq.eclair.wire._
/**
@@ -30,8 +31,8 @@ case object OUT extends Direction { def opposite = IN }
case class DirectedHtlc(direction: Direction, add: UpdateAddHtlc)
-final case class CommitmentSpec(htlcs: Set[DirectedHtlc], feeratePerKw: Long, toLocalMsat: Long, toRemoteMsat: Long) {
- val totalFunds = toLocalMsat + toRemoteMsat + htlcs.toSeq.map(_.add.amountMsat).sum
+final case class CommitmentSpec(htlcs: Set[DirectedHtlc], feeratePerKw: Long, toLocal: MilliSatoshi, toRemote: MilliSatoshi) {
+ val totalFunds = toLocal + toRemote + htlcs.toSeq.map(_.add.amountMsat).sum
}
object CommitmentSpec {
@@ -43,16 +44,16 @@ object CommitmentSpec {
def addHtlc(spec: CommitmentSpec, direction: Direction, update: UpdateAddHtlc): CommitmentSpec = {
val htlc = DirectedHtlc(direction, update)
direction match {
- case OUT => spec.copy(toLocalMsat = spec.toLocalMsat - htlc.add.amountMsat, htlcs = spec.htlcs + htlc)
- case IN => spec.copy(toRemoteMsat = spec.toRemoteMsat - htlc.add.amountMsat, htlcs = spec.htlcs + htlc)
+ case OUT => spec.copy(toLocal = spec.toLocal - htlc.add.amountMsat, htlcs = spec.htlcs + htlc)
+ case IN => spec.copy(toRemote = spec.toRemote - htlc.add.amountMsat, htlcs = spec.htlcs + htlc)
}
}
// OUT means we are sending an UpdateFulfillHtlc message which means that we are fulfilling an HTLC that they sent
def fulfillHtlc(spec: CommitmentSpec, direction: Direction, htlcId: Long): CommitmentSpec = {
spec.htlcs.find(htlc => htlc.direction != direction && htlc.add.id == htlcId) match {
- case Some(htlc) if direction == OUT => spec.copy(toLocalMsat = spec.toLocalMsat + htlc.add.amountMsat, htlcs = spec.htlcs - htlc)
- case Some(htlc) if direction == IN => spec.copy(toRemoteMsat = spec.toRemoteMsat + htlc.add.amountMsat, htlcs = spec.htlcs - htlc)
+ case Some(htlc) if direction == OUT => spec.copy(toLocal = spec.toLocal + htlc.add.amountMsat, htlcs = spec.htlcs - htlc)
+ case Some(htlc) if direction == IN => spec.copy(toRemote = spec.toRemote + htlc.add.amountMsat, htlcs = spec.htlcs - htlc)
case None => throw new RuntimeException(s"cannot find htlc id=${htlcId}")
}
}
@@ -60,8 +61,8 @@ object CommitmentSpec {
// OUT means we are sending an UpdateFailHtlc message which means that we are failing an HTLC that they sent
def failHtlc(spec: CommitmentSpec, direction: Direction, htlcId: Long): CommitmentSpec = {
spec.htlcs.find(htlc => htlc.direction != direction && htlc.add.id == htlcId) match {
- case Some(htlc) if direction == OUT => spec.copy(toRemoteMsat = spec.toRemoteMsat + htlc.add.amountMsat, htlcs = spec.htlcs - htlc)
- case Some(htlc) if direction == IN => spec.copy(toLocalMsat = spec.toLocalMsat + htlc.add.amountMsat, htlcs = spec.htlcs - htlc)
+ case Some(htlc) if direction == OUT => spec.copy(toRemote = spec.toRemote + htlc.add.amountMsat, htlcs = spec.htlcs - htlc)
+ case Some(htlc) if direction == IN => spec.copy(toLocal = spec.toLocal + htlc.add.amountMsat, htlcs = spec.htlcs - htlc)
case None => throw new RuntimeException(s"cannot find htlc id=${htlcId}")
}
}
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/transactions/Transactions.scala b/eclair-core/src/main/scala/fr/acinq/eclair/transactions/Transactions.scala
index 0febeaab9e..9ea53c8a1b 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/transactions/Transactions.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/transactions/Transactions.scala
@@ -21,7 +21,8 @@ import java.nio.ByteOrder
import fr.acinq.bitcoin.Crypto.{PrivateKey, PublicKey, ripemd160}
import fr.acinq.bitcoin.Script._
import fr.acinq.bitcoin.SigVersion._
-import fr.acinq.bitcoin.{ByteVector32, ByteVector64, Crypto, LexicographicalOrdering, MilliSatoshi, OutPoint, Protocol, SIGHASH_ALL, Satoshi, Script, ScriptElt, ScriptFlags, ScriptWitness, Transaction, TxIn, TxOut, millisatoshi2satoshi}
+import fr.acinq.bitcoin._
+import fr.acinq.eclair._
import fr.acinq.eclair.transactions.Scripts._
import fr.acinq.eclair.wire.UpdateAddHtlc
import scodec.bits.ByteVector
@@ -121,7 +122,7 @@ object Transactions {
val htlcTimeoutFee = weight2fee(spec.feeratePerKw, htlcTimeoutWeight)
spec.htlcs
.filter(_.direction == OUT)
- .filter(htlc => MilliSatoshi(htlc.add.amountMsat) >= (dustLimit + htlcTimeoutFee))
+ .filter(htlc => htlc.add.amountMsat >= (dustLimit + htlcTimeoutFee).toMilliSatoshi)
.toSeq
}
@@ -129,7 +130,7 @@ object Transactions {
val htlcSuccessFee = weight2fee(spec.feeratePerKw, htlcSuccessWeight)
spec.htlcs
.filter(_.direction == IN)
- .filter(htlc => MilliSatoshi(htlc.add.amountMsat) >= (dustLimit + htlcSuccessFee))
+ .filter(htlc => htlc.add.amountMsat >= (dustLimit + htlcSuccessFee).toMilliSatoshi)
.toSeq
}
@@ -190,18 +191,18 @@ object Transactions {
val commitFee = commitTxFee(localDustLimit, spec)
val (toLocalAmount: Satoshi, toRemoteAmount: Satoshi) = if (localIsFunder) {
- (millisatoshi2satoshi(MilliSatoshi(spec.toLocalMsat)) - commitFee, millisatoshi2satoshi(MilliSatoshi(spec.toRemoteMsat)))
+ (spec.toLocal.truncateToSatoshi - commitFee, spec.toRemote.truncateToSatoshi)
} else {
- (millisatoshi2satoshi(MilliSatoshi(spec.toLocalMsat)), millisatoshi2satoshi(MilliSatoshi(spec.toRemoteMsat)) - commitFee)
+ (spec.toLocal.truncateToSatoshi, spec.toRemote.truncateToSatoshi - commitFee)
} // NB: we don't care if values are < 0, they will be trimmed if they are < dust limit anyway
val toLocalDelayedOutput_opt = if (toLocalAmount >= localDustLimit) Some(TxOut(toLocalAmount, pay2wsh(toLocalDelayed(localRevocationPubkey, toLocalDelay, localDelayedPaymentPubkey)))) else None
val toRemoteOutput_opt = if (toRemoteAmount >= localDustLimit) Some(TxOut(toRemoteAmount, pay2wpkh(remotePaymentPubkey))) else None
val htlcOfferedOutputs = trimOfferedHtlcs(localDustLimit, spec)
- .map(htlc => TxOut(MilliSatoshi(htlc.add.amountMsat), pay2wsh(htlcOffered(localHtlcPubkey, remoteHtlcPubkey, localRevocationPubkey, ripemd160(htlc.add.paymentHash.bytes)))))
+ .map(htlc => TxOut(htlc.add.amountMsat.truncateToSatoshi, pay2wsh(htlcOffered(localHtlcPubkey, remoteHtlcPubkey, localRevocationPubkey, ripemd160(htlc.add.paymentHash.bytes)))))
val htlcReceivedOutputs = trimReceivedHtlcs(localDustLimit, spec)
- .map(htlc => TxOut(MilliSatoshi(htlc.add.amountMsat), pay2wsh(htlcReceived(localHtlcPubkey, remoteHtlcPubkey, localRevocationPubkey, ripemd160(htlc.add.paymentHash.bytes), htlc.add.cltvExpiry))))
+ .map(htlc => TxOut(htlc.add.amountMsat.truncateToSatoshi, pay2wsh(htlcReceived(localHtlcPubkey, remoteHtlcPubkey, localRevocationPubkey, ripemd160(htlc.add.paymentHash.bytes), htlc.add.cltvExpiry))))
val txnumber = obscuredCommitTxNumber(commitTxNumber, localIsFunder, localPaymentBasePoint, remotePaymentBasePoint)
val (sequence, locktime) = encodeTxNumber(txnumber)
@@ -218,8 +219,8 @@ object Transactions {
val fee = weight2fee(feeratePerKw, htlcTimeoutWeight)
val redeemScript = htlcOffered(localHtlcPubkey, remoteHtlcPubkey, localRevocationPubkey, ripemd160(htlc.paymentHash.bytes))
val pubkeyScript = write(pay2wsh(redeemScript))
- val outputIndex = findPubKeyScriptIndex(commitTx, pubkeyScript, outputsAlreadyUsed, amount_opt = Some(Satoshi(htlc.amountMsat / 1000)))
- val amount = MilliSatoshi(htlc.amountMsat) - fee
+ val outputIndex = findPubKeyScriptIndex(commitTx, pubkeyScript, outputsAlreadyUsed, amount_opt = Some(htlc.amountMsat.truncateToSatoshi))
+ val amount = htlc.amountMsat.truncateToSatoshi - fee
if (amount < localDustLimit) {
throw AmountBelowDustLimit
}
@@ -235,8 +236,8 @@ object Transactions {
val fee = weight2fee(feeratePerKw, htlcSuccessWeight)
val redeemScript = htlcReceived(localHtlcPubkey, remoteHtlcPubkey, localRevocationPubkey, ripemd160(htlc.paymentHash.bytes), htlc.cltvExpiry)
val pubkeyScript = write(pay2wsh(redeemScript))
- val outputIndex = findPubKeyScriptIndex(commitTx, pubkeyScript, outputsAlreadyUsed, amount_opt = Some(Satoshi(htlc.amountMsat / 1000)))
- val amount = MilliSatoshi(htlc.amountMsat) - fee
+ val outputIndex = findPubKeyScriptIndex(commitTx, pubkeyScript, outputsAlreadyUsed, amount_opt = Some(htlc.amountMsat.truncateToSatoshi))
+ val amount = htlc.amountMsat.truncateToSatoshi - fee
if (amount < localDustLimit) {
throw AmountBelowDustLimit
}
@@ -266,7 +267,7 @@ object Transactions {
def makeClaimHtlcSuccessTx(commitTx: Transaction, outputsAlreadyUsed: Set[Int], localDustLimit: Satoshi, localHtlcPubkey: PublicKey, remoteHtlcPubkey: PublicKey, remoteRevocationPubkey: PublicKey, localFinalScriptPubKey: ByteVector, htlc: UpdateAddHtlc, feeratePerKw: Long): ClaimHtlcSuccessTx = {
val redeemScript = htlcOffered(remoteHtlcPubkey, localHtlcPubkey, remoteRevocationPubkey, ripemd160(htlc.paymentHash.bytes))
val pubkeyScript = write(pay2wsh(redeemScript))
- val outputIndex = findPubKeyScriptIndex(commitTx, pubkeyScript, outputsAlreadyUsed, amount_opt = Some(Satoshi(htlc.amountMsat / 1000)))
+ val outputIndex = findPubKeyScriptIndex(commitTx, pubkeyScript, outputsAlreadyUsed, amount_opt = Some(htlc.amountMsat.truncateToSatoshi))
val input = InputInfo(OutPoint(commitTx, outputIndex), commitTx.txOut(outputIndex), write(redeemScript))
val tx = Transaction(
@@ -289,7 +290,7 @@ object Transactions {
def makeClaimHtlcTimeoutTx(commitTx: Transaction, outputsAlreadyUsed: Set[Int], localDustLimit: Satoshi, localHtlcPubkey: PublicKey, remoteHtlcPubkey: PublicKey, remoteRevocationPubkey: PublicKey, localFinalScriptPubKey: ByteVector, htlc: UpdateAddHtlc, feeratePerKw: Long): ClaimHtlcTimeoutTx = {
val redeemScript = htlcReceived(remoteHtlcPubkey, localHtlcPubkey, remoteRevocationPubkey, ripemd160(htlc.paymentHash.bytes), htlc.cltvExpiry)
val pubkeyScript = write(pay2wsh(redeemScript))
- val outputIndex = findPubKeyScriptIndex(commitTx, pubkeyScript, outputsAlreadyUsed, amount_opt = Some(Satoshi(htlc.amountMsat / 1000)))
+ val outputIndex = findPubKeyScriptIndex(commitTx, pubkeyScript, outputsAlreadyUsed, amount_opt = Some(htlc.amountMsat.truncateToSatoshi))
val input = InputInfo(OutPoint(commitTx, outputIndex), commitTx.txOut(outputIndex), write(redeemScript))
// unsigned tx
@@ -447,9 +448,9 @@ object Transactions {
require(spec.htlcs.isEmpty, "there shouldn't be any pending htlcs")
val (toLocalAmount: Satoshi, toRemoteAmount: Satoshi) = if (localIsFunder) {
- (millisatoshi2satoshi(MilliSatoshi(spec.toLocalMsat)) - closingFee, millisatoshi2satoshi(MilliSatoshi(spec.toRemoteMsat)))
+ (spec.toLocal.truncateToSatoshi - closingFee, spec.toRemote.truncateToSatoshi)
} else {
- (millisatoshi2satoshi(MilliSatoshi(spec.toLocalMsat)), millisatoshi2satoshi(MilliSatoshi(spec.toRemoteMsat)) - closingFee)
+ (spec.toLocal.truncateToSatoshi, spec.toRemote.truncateToSatoshi - closingFee)
} // NB: we don't care if values are < 0, they will be trimmed if they are < dust limit anyway
val toLocalOutput_opt = if (toLocalAmount >= dustLimit) Some(TxOut(toLocalAmount, localScriptPubKey)) else None
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/wire/ChannelCodecs.scala b/eclair-core/src/main/scala/fr/acinq/eclair/wire/ChannelCodecs.scala
index 97937c05de..df95cd7972 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/wire/ChannelCodecs.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/wire/ChannelCodecs.scala
@@ -61,10 +61,10 @@ object ChannelCodecs extends Logging {
val localParamsCodec: Codec[LocalParams] = (
("nodeId" | publicKey) ::
("channelPath" | keyPathCodec) ::
- ("dustLimitSatoshis" | uint64overflow) ::
+ ("dustLimit" | satoshi) ::
("maxHtlcValueInFlightMsat" | uint64) ::
- ("channelReserveSatoshis" | uint64overflow) ::
- ("htlcMinimumMsat" | uint64overflow) ::
+ ("channelReserve" | satoshi) ::
+ ("htlcMinimum" | millisatoshi) ::
("toSelfDelay" | uint16) ::
("maxAcceptedHtlcs" | uint16) ::
("isFunder" | bool) ::
@@ -74,10 +74,10 @@ object ChannelCodecs extends Logging {
val remoteParamsCodec: Codec[RemoteParams] = (
("nodeId" | publicKey) ::
- ("dustLimitSatoshis" | uint64overflow) ::
+ ("dustLimit" | satoshi) ::
("maxHtlcValueInFlightMsat" | uint64) ::
- ("channelReserveSatoshis" | uint64overflow) ::
- ("htlcMinimumMsat" | uint64overflow) ::
+ ("channelReserve" | satoshi) ::
+ ("htlcMinimum" | millisatoshi) ::
("toSelfDelay" | uint16) ::
("maxAcceptedHtlcs" | uint16) ::
("fundingPubKey" | publicKey) ::
@@ -105,8 +105,8 @@ object ChannelCodecs extends Logging {
val commitmentSpecCodec: Codec[CommitmentSpec] = (
("htlcs" | setCodec(htlcCodec)) ::
("feeratePerKw" | uint32) ::
- ("toLocalMsat" | uint64overflow) ::
- ("toRemoteMsat" | uint64overflow)).as[CommitmentSpec]
+ ("toLocal" | millisatoshi) ::
+ ("toRemote" | millisatoshi)).as[CommitmentSpec]
val outPointCodec: Codec[OutPoint] = variableSizeBytes(uint16, bytes.xmap(d => OutPoint.read(d.toArray), d => OutPoint.write(d)))
@@ -186,8 +186,8 @@ object ChannelCodecs extends Logging {
val relayedCodec: Codec[Relayed] = (
("originChannelId" | bytes32) ::
("originHtlcId" | int64) ::
- ("amountMsatIn" | uint64overflow) ::
- ("amountMsatOut" | uint64overflow)).as[Relayed]
+ ("amountIn" | millisatoshi) ::
+ ("amountOut" | millisatoshi)).as[Relayed]
// this is for backward compatibility to handle legacy payments that didn't have identifiers
val UNKNOWN_UUID = UUID.fromString("00000000-0000-0000-0000-000000000000")
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/wire/CommonCodecs.scala b/eclair-core/src/main/scala/fr/acinq/eclair/wire/CommonCodecs.scala
index e56a3645fd..fc749c8fe8 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/wire/CommonCodecs.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/wire/CommonCodecs.scala
@@ -19,9 +19,9 @@ package fr.acinq.eclair.wire
import java.net.{Inet4Address, Inet6Address, InetAddress}
import fr.acinq.bitcoin.Crypto.{PrivateKey, PublicKey}
-import fr.acinq.bitcoin.{ByteVector32, ByteVector64}
import fr.acinq.eclair.crypto.Mac32
-import fr.acinq.eclair.{ShortChannelId, UInt64}
+import fr.acinq.bitcoin.{ByteVector32, ByteVector64, Satoshi}
+import fr.acinq.eclair.{MilliSatoshi, ShortChannelId, UInt64}
import org.apache.commons.codec.binary.Base32
import scodec.bits.{BitVector, ByteVector}
import scodec.codecs._
@@ -52,9 +52,11 @@ object CommonCodecs {
// this codec can be safely used for values < 2^63 and will fail otherwise
// (for something smarter see https://github.com/yzernik/bitcoin-scodec/blob/master/src/main/scala/io/github/yzernik/bitcoinscodec/structures/UInt64.scala)
val uint64overflow: Codec[Long] = int64.narrow(l => if (l >= 0) Attempt.Successful(l) else Attempt.failure(Err(s"overflow for value $l")), l => l)
-
val uint64: Codec[UInt64] = bytes(8).xmap(b => UInt64(b), a => a.toByteVector.padLeft(8))
+ val satoshi: Codec[Satoshi] = uint64overflow.xmapc(l => Satoshi(l))(_.toLong)
+ val millisatoshi: Codec[MilliSatoshi] = uint64overflow.xmapc(l => MilliSatoshi(l))(_.amount)
+
/**
* We impose a minimal encoding on some values (such as varint and truncated int) to ensure that signed hashes can be
* re-computed correctly.
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/wire/FailureMessage.scala b/eclair-core/src/main/scala/fr/acinq/eclair/wire/FailureMessage.scala
index a7cee716dd..db816407be 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/wire/FailureMessage.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/wire/FailureMessage.scala
@@ -17,8 +17,9 @@
package fr.acinq.eclair.wire
import fr.acinq.bitcoin.ByteVector32
+import fr.acinq.eclair.MilliSatoshi
import fr.acinq.eclair.crypto.Mac32
-import fr.acinq.eclair.wire.CommonCodecs.{sha256, uint64overflow}
+import fr.acinq.eclair.wire.CommonCodecs.{sha256, millisatoshi}
import fr.acinq.eclair.wire.LightningMessageCodecs.{channelUpdateCodec, lightningMessageCodec}
import scodec.codecs._
import scodec.{Attempt, Codec}
@@ -47,16 +48,16 @@ case class TemporaryChannelFailure(update: ChannelUpdate) extends Update { def m
case object PermanentChannelFailure extends Perm { def message = "channel is permanently unavailable" }
case object RequiredChannelFeatureMissing extends Perm { def message = "channel requires features not present in the onion" }
case object UnknownNextPeer extends Perm { def message = "processing node does not know the next peer in the route" }
-case class AmountBelowMinimum(amountMsat: Long, update: ChannelUpdate) extends Update { def message = s"payment amount was below the minimum required by the channel" }
-case class FeeInsufficient(amountMsat: Long, update: ChannelUpdate) extends Update { def message = s"payment fee was below the minimum required by the channel" }
+case class AmountBelowMinimum(amount: MilliSatoshi, update: ChannelUpdate) extends Update { def message = s"payment amount was below the minimum required by the channel" }
+case class FeeInsufficient(amount: MilliSatoshi, update: ChannelUpdate) extends Update { def message = s"payment fee was below the minimum required by the channel" }
case class ChannelDisabled(messageFlags: Byte, channelFlags: Byte, update: ChannelUpdate) extends Update { def message = "channel is currently disabled" }
case class IncorrectCltvExpiry(expiry: Long, update: ChannelUpdate) extends Update { def message = "payment expiry doesn't match the value in the onion" }
-case class IncorrectOrUnknownPaymentDetails(amountMsat: Long) extends Perm { def message = "incorrect payment amount or unknown payment hash" }
+case class IncorrectOrUnknownPaymentDetails(amount: MilliSatoshi) extends Perm { def message = "incorrect payment amount or unknown payment hash" }
case object IncorrectPaymentAmount extends Perm { def message = "payment amount is incorrect" }
case class ExpiryTooSoon(update: ChannelUpdate) extends Update { def message = "payment expiry is too close to the current block height for safe handling by the relaying node" }
case object FinalExpiryTooSoon extends FailureMessage { def message = "payment expiry is too close to the current block height for safe handling by the final node" }
case class FinalIncorrectCltvExpiry(expiry: Long) extends FailureMessage { def message = "payment expiry doesn't match the value in the onion" }
-case class FinalIncorrectHtlcAmount(amountMsat: Long) extends FailureMessage { def message = "payment amount is incorrect in the final htlc" }
+case class FinalIncorrectHtlcAmount(amount: MilliSatoshi) extends FailureMessage { def message = "payment amount is incorrect in the final htlc" }
case object ExpiryTooFar extends FailureMessage { def message = "payment expiry is too far in the future" }
// @formatter:on
@@ -85,16 +86,16 @@ object FailureMessageCodecs {
.typecase(PERM | 8, provide(PermanentChannelFailure))
.typecase(PERM | 9, provide(RequiredChannelFeatureMissing))
.typecase(PERM | 10, provide(UnknownNextPeer))
- .typecase(UPDATE | 11, (("amountMsat" | uint64overflow) :: ("channelUpdate" | channelUpdateWithLengthCodec)).as[AmountBelowMinimum])
- .typecase(UPDATE | 12, (("amountMsat" | uint64overflow) :: ("channelUpdate" | channelUpdateWithLengthCodec)).as[FeeInsufficient])
+ .typecase(UPDATE | 11, (("amountMsat" | millisatoshi) :: ("channelUpdate" | channelUpdateWithLengthCodec)).as[AmountBelowMinimum])
+ .typecase(UPDATE | 12, (("amountMsat" | millisatoshi) :: ("channelUpdate" | channelUpdateWithLengthCodec)).as[FeeInsufficient])
.typecase(UPDATE | 13, (("expiry" | uint32) :: ("channelUpdate" | channelUpdateWithLengthCodec)).as[IncorrectCltvExpiry])
.typecase(UPDATE | 14, ("channelUpdate" | channelUpdateWithLengthCodec).as[ExpiryTooSoon])
.typecase(UPDATE | 20, (("messageFlags" | byte) :: ("channelFlags" | byte) :: ("channelUpdate" | channelUpdateWithLengthCodec)).as[ChannelDisabled])
- .typecase(PERM | 15, ("amountMsat" | withDefaultValue(optional(bitsRemaining, uint64overflow), 0L)).as[IncorrectOrUnknownPaymentDetails])
+ .typecase(PERM | 15, ("amountMsat" | withDefaultValue(optional(bitsRemaining, millisatoshi), MilliSatoshi(0))).as[IncorrectOrUnknownPaymentDetails])
.typecase(PERM | 16, provide(IncorrectPaymentAmount))
.typecase(17, provide(FinalExpiryTooSoon))
.typecase(18, ("expiry" | uint32).as[FinalIncorrectCltvExpiry])
- .typecase(19, ("amountMsat" | uint64overflow).as[FinalIncorrectHtlcAmount])
+ .typecase(19, ("amountMsat" | millisatoshi).as[FinalIncorrectHtlcAmount])
.typecase(21, provide(ExpiryTooFar))
/**
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/wire/LightningMessageCodecs.scala b/eclair-core/src/main/scala/fr/acinq/eclair/wire/LightningMessageCodecs.scala
index b7e3891c43..055d9ffa16 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/wire/LightningMessageCodecs.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/wire/LightningMessageCodecs.scala
@@ -16,9 +16,11 @@
package fr.acinq.eclair.wire
-import fr.acinq.eclair.wire
+import fr.acinq.eclair.crypto.Sphinx
+import fr.acinq.eclair.{MilliSatoshi, wire}
import fr.acinq.eclair.wire.CommonCodecs._
import scodec.Codec
+import scodec.bits.ByteVector
import scodec.codecs._
/**
@@ -51,12 +53,12 @@ object LightningMessageCodecs {
val openChannelCodec: Codec[OpenChannel] = (
("chainHash" | bytes32) ::
("temporaryChannelId" | bytes32) ::
- ("fundingSatoshis" | uint64overflow) ::
- ("pushMsat" | uint64overflow) ::
- ("dustLimitSatoshis" | uint64overflow) ::
+ ("fundingSatoshis" | satoshi) ::
+ ("pushMsat" | millisatoshi) ::
+ ("dustLimitSatoshis" | satoshi) ::
("maxHtlcValueInFlightMsat" | uint64) ::
- ("channelReserveSatoshis" | uint64overflow) ::
- ("htlcMinimumMsat" | uint64overflow) ::
+ ("channelReserveSatoshis" | satoshi) ::
+ ("htlcMinimumMsat" | millisatoshi) ::
("feeratePerKw" | uint32) ::
("toSelfDelay" | uint16) ::
("maxAcceptedHtlcs" | uint16) ::
@@ -70,10 +72,10 @@ object LightningMessageCodecs {
val acceptChannelCodec: Codec[AcceptChannel] = (
("temporaryChannelId" | bytes32) ::
- ("dustLimitSatoshis" | uint64overflow) ::
+ ("dustLimitSatoshis" | satoshi) ::
("maxHtlcValueInFlightMsat" | uint64) ::
- ("channelReserveSatoshis" | uint64overflow) ::
- ("htlcMinimumMsat" | uint64overflow) ::
+ ("channelReserveSatoshis" | satoshi) ::
+ ("htlcMinimumMsat" | millisatoshi) ::
("minimumDepth" | uint32) ::
("toSelfDelay" | uint16) ::
("maxAcceptedHtlcs" | uint16) ::
@@ -104,13 +106,13 @@ object LightningMessageCodecs {
val closingSignedCodec: Codec[ClosingSigned] = (
("channelId" | bytes32) ::
- ("feeSatoshis" | uint64overflow) ::
+ ("feeSatoshis" | satoshi) ::
("signature" | bytes64)).as[ClosingSigned]
val updateAddHtlcCodec: Codec[UpdateAddHtlc] = (
("channelId" | bytes32) ::
("id" | uint64overflow) ::
- ("amountMsat" | uint64overflow) ::
+ ("amountMsat" | millisatoshi) ::
("paymentHash" | bytes32) ::
("expiry" | uint32) ::
("onionRoutingPacket" | OnionCodecs.paymentOnionPacketCodec)).as[UpdateAddHtlc]
@@ -189,10 +191,10 @@ object LightningMessageCodecs {
(("messageFlags" | byte) >>:~ { messageFlags =>
("channelFlags" | byte) ::
("cltvExpiryDelta" | uint16) ::
- ("htlcMinimumMsat" | uint64overflow) ::
- ("feeBaseMsat" | uint32) ::
+ ("htlcMinimumMsat" | millisatoshi) ::
+ ("feeBaseMsat" | uint32.xmapc(l => MilliSatoshi(l))(_.amount)) ::
("feeProportionalMillionths" | uint32) ::
- ("htlcMaximumMsat" | conditional((messageFlags & 1) != 0, uint64overflow)) ::
+ ("htlcMaximumMsat" | conditional((messageFlags & 1) != 0, millisatoshi)) ::
("unknownFields" | bytes)
})
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/wire/LightningMessageTypes.scala b/eclair-core/src/main/scala/fr/acinq/eclair/wire/LightningMessageTypes.scala
index 89be06884a..57d3738918 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/wire/LightningMessageTypes.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/wire/LightningMessageTypes.scala
@@ -20,9 +20,9 @@ import java.net.{Inet4Address, Inet6Address, InetAddress, InetSocketAddress}
import java.nio.charset.StandardCharsets
import com.google.common.base.Charsets
+import fr.acinq.bitcoin.{ByteVector32, ByteVector64, Satoshi}
import fr.acinq.bitcoin.Crypto.{PrivateKey, PublicKey}
-import fr.acinq.bitcoin.{ByteVector32, ByteVector64}
-import fr.acinq.eclair.{ShortChannelId, UInt64}
+import fr.acinq.eclair.{MilliSatoshi, ShortChannelId, UInt64}
import scodec.bits.ByteVector
import scala.util.Try
@@ -68,12 +68,12 @@ case class ChannelReestablish(channelId: ByteVector32,
case class OpenChannel(chainHash: ByteVector32,
temporaryChannelId: ByteVector32,
- fundingSatoshis: Long,
- pushMsat: Long,
- dustLimitSatoshis: Long,
+ fundingSatoshis: Satoshi,
+ pushMsat: MilliSatoshi,
+ dustLimitSatoshis: Satoshi,
maxHtlcValueInFlightMsat: UInt64,
- channelReserveSatoshis: Long,
- htlcMinimumMsat: Long,
+ channelReserveSatoshis: Satoshi,
+ htlcMinimumMsat: MilliSatoshi,
feeratePerKw: Long,
toSelfDelay: Int,
maxAcceptedHtlcs: Int,
@@ -86,10 +86,10 @@ case class OpenChannel(chainHash: ByteVector32,
channelFlags: Byte) extends ChannelMessage with HasTemporaryChannelId with HasChainHash
case class AcceptChannel(temporaryChannelId: ByteVector32,
- dustLimitSatoshis: Long,
+ dustLimitSatoshis: Satoshi,
maxHtlcValueInFlightMsat: UInt64,
- channelReserveSatoshis: Long,
- htlcMinimumMsat: Long,
+ channelReserveSatoshis: Satoshi,
+ htlcMinimumMsat: MilliSatoshi,
minimumDepth: Long,
toSelfDelay: Int,
maxAcceptedHtlcs: Int,
@@ -115,12 +115,12 @@ case class Shutdown(channelId: ByteVector32,
scriptPubKey: ByteVector) extends ChannelMessage with HasChannelId
case class ClosingSigned(channelId: ByteVector32,
- feeSatoshis: Long,
+ feeSatoshis: Satoshi,
signature: ByteVector64) extends ChannelMessage with HasChannelId
case class UpdateAddHtlc(channelId: ByteVector32,
id: Long,
- amountMsat: Long,
+ amountMsat: MilliSatoshi,
paymentHash: ByteVector32,
cltvExpiry: Long,
onionRoutingPacket: OnionRoutingPacket) extends HtlcMessage with UpdateMessage with HasChannelId
@@ -217,10 +217,10 @@ case class ChannelUpdate(signature: ByteVector64,
messageFlags: Byte,
channelFlags: Byte,
cltvExpiryDelta: Int,
- htlcMinimumMsat: Long,
- feeBaseMsat: Long,
+ htlcMinimumMsat: MilliSatoshi,
+ feeBaseMsat: MilliSatoshi,
feeProportionalMillionths: Long,
- htlcMaximumMsat: Option[Long],
+ htlcMaximumMsat: Option[MilliSatoshi],
unknownFields: ByteVector = ByteVector.empty) extends RoutingMessage with HasTimestamp with HasChainHash {
require(((messageFlags & 1) != 0) == htlcMaximumMsat.isDefined, "htlcMaximumMsat is not consistent with messageFlags")
}
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/wire/Onion.scala b/eclair-core/src/main/scala/fr/acinq/eclair/wire/Onion.scala
index 32d942f547..716f11b16e 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/wire/Onion.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/wire/Onion.scala
@@ -17,7 +17,7 @@
package fr.acinq.eclair.wire
import fr.acinq.bitcoin.ByteVector32
-import fr.acinq.eclair.ShortChannelId
+import fr.acinq.eclair.{MilliSatoshi, ShortChannelId}
import fr.acinq.eclair.crypto.Sphinx
import scodec.bits.{BitVector, ByteVector}
import scodec.codecs._
@@ -33,7 +33,7 @@ case class OnionRoutingPacket(version: Int,
hmac: ByteVector32)
case class PerHopPayload(shortChannelId: ShortChannelId,
- amtToForward: Long,
+ amtToForward: MilliSatoshi,
outgoingCltvValue: Long)
object OnionCodecs {
@@ -49,7 +49,7 @@ object OnionCodecs {
val perHopPayloadCodec: Codec[PerHopPayload] = (
("realm" | constant(ByteVector.fromByte(0))) ::
("short_channel_id" | CommonCodecs.shortchannelid) ::
- ("amt_to_forward" | CommonCodecs.uint64overflow) ::
+ ("amt_to_forward" | CommonCodecs.millisatoshi) ::
("outgoing_cltv_value" | uint32) ::
("unused_with_v0_version_on_header" | ignore(8 * 12))).as[PerHopPayload]
diff --git a/eclair-core/src/test/resources/api/usablebalances b/eclair-core/src/test/resources/api/usablebalances
index edbd4e5a97..c1ef6b4920 100644
--- a/eclair-core/src/test/resources/api/usablebalances
+++ b/eclair-core/src/test/resources/api/usablebalances
@@ -1 +1 @@
-[{"remoteNodeId":"03af0ed6052cf28d670665549bc86f4b721c9fdb309d40c58f5811f63966e005d0","shortChannelId":"0x0x1","canSendMsat":100000000,"canReceiveMsat":20000000,"isPublic":true},{"remoteNodeId":"03af0ed6052cf28d670665549bc86f4b721c9fdb309d40c58f5811f63966e005d0","shortChannelId":"0x0x2","canSendMsat":400000000,"canReceiveMsat":30000000,"isPublic":false}]
\ No newline at end of file
+[{"remoteNodeId":"03af0ed6052cf28d670665549bc86f4b721c9fdb309d40c58f5811f63966e005d0","shortChannelId":"0x0x1","canSend":100000000,"canReceive":20000000,"isPublic":true},{"remoteNodeId":"03af0ed6052cf28d670665549bc86f4b721c9fdb309d40c58f5811f63966e005d0","shortChannelId":"0x0x2","canSend":400000000,"canReceive":30000000,"isPublic":false}]
\ No newline at end of file
diff --git a/eclair-core/src/test/resources/scenarii/01-offer1.script.expected b/eclair-core/src/test/resources/scenarii/01-offer1.script.expected
index c3444f106f..5680bafccc 100644
--- a/eclair-core/src/test/resources/scenarii/01-offer1.script.expected
+++ b/eclair-core/src/test/resources/scenarii/01-offer1.script.expected
@@ -1,30 +1,30 @@
***A***
LOCAL COMMITS:
Commit 1:
- Offered htlcs: (0,1000000)
+ Offered htlcs: (0,MilliSatoshi(1000000))
Received htlcs:
- Balance us: 999000000
- Balance them: 1000000000
+ Balance us: MilliSatoshi(999000000)
+ Balance them: MilliSatoshi(1000000000)
Fee rate: 10000
REMOTE COMMITS:
Commit 1:
Offered htlcs:
- Received htlcs: (0,1000000)
- Balance us: 1000000000
- Balance them: 999000000
+ Received htlcs: (0,MilliSatoshi(1000000))
+ Balance us: MilliSatoshi(1000000000)
+ Balance them: MilliSatoshi(999000000)
Fee rate: 10000
***B***
LOCAL COMMITS:
Commit 1:
Offered htlcs:
- Received htlcs: (0,1000000)
- Balance us: 1000000000
- Balance them: 999000000
+ Received htlcs: (0,MilliSatoshi(1000000))
+ Balance us: MilliSatoshi(1000000000)
+ Balance them: MilliSatoshi(999000000)
Fee rate: 10000
REMOTE COMMITS:
Commit 1:
- Offered htlcs: (0,1000000)
+ Offered htlcs: (0,MilliSatoshi(1000000))
Received htlcs:
- Balance us: 999000000
- Balance them: 1000000000
+ Balance us: MilliSatoshi(999000000)
+ Balance them: MilliSatoshi(1000000000)
Fee rate: 10000
diff --git a/eclair-core/src/test/resources/scenarii/02-offer2.script.expected b/eclair-core/src/test/resources/scenarii/02-offer2.script.expected
index b12ec47413..2d71ea0dea 100644
--- a/eclair-core/src/test/resources/scenarii/02-offer2.script.expected
+++ b/eclair-core/src/test/resources/scenarii/02-offer2.script.expected
@@ -1,30 +1,30 @@
***A***
LOCAL COMMITS:
Commit 1:
- Offered htlcs: (0,1000000) (1,2000000)
+ Offered htlcs: (0,MilliSatoshi(1000000)) (1,MilliSatoshi(2000000))
Received htlcs:
- Balance us: 997000000
- Balance them: 1000000000
+ Balance us: MilliSatoshi(997000000)
+ Balance them: MilliSatoshi(1000000000)
Fee rate: 10000
REMOTE COMMITS:
Commit 1:
Offered htlcs:
- Received htlcs: (0,1000000) (1,2000000)
- Balance us: 1000000000
- Balance them: 997000000
+ Received htlcs: (0,MilliSatoshi(1000000)) (1,MilliSatoshi(2000000))
+ Balance us: MilliSatoshi(1000000000)
+ Balance them: MilliSatoshi(997000000)
Fee rate: 10000
***B***
LOCAL COMMITS:
Commit 1:
Offered htlcs:
- Received htlcs: (0,1000000) (1,2000000)
- Balance us: 1000000000
- Balance them: 997000000
+ Received htlcs: (0,MilliSatoshi(1000000)) (1,MilliSatoshi(2000000))
+ Balance us: MilliSatoshi(1000000000)
+ Balance them: MilliSatoshi(997000000)
Fee rate: 10000
REMOTE COMMITS:
Commit 1:
- Offered htlcs: (0,1000000) (1,2000000)
+ Offered htlcs: (0,MilliSatoshi(1000000)) (1,MilliSatoshi(2000000))
Received htlcs:
- Balance us: 997000000
- Balance them: 1000000000
+ Balance us: MilliSatoshi(997000000)
+ Balance them: MilliSatoshi(1000000000)
Fee rate: 10000
diff --git a/eclair-core/src/test/resources/scenarii/03-fulfill1.script.expected b/eclair-core/src/test/resources/scenarii/03-fulfill1.script.expected
index 1ffcada1d7..3c3fff0fe3 100644
--- a/eclair-core/src/test/resources/scenarii/03-fulfill1.script.expected
+++ b/eclair-core/src/test/resources/scenarii/03-fulfill1.script.expected
@@ -3,28 +3,28 @@ LOCAL COMMITS:
Commit 2:
Offered htlcs:
Received htlcs:
- Balance us: 999000000
- Balance them: 1001000000
+ Balance us: MilliSatoshi(999000000)
+ Balance them: MilliSatoshi(1001000000)
Fee rate: 10000
REMOTE COMMITS:
Commit 2:
Offered htlcs:
Received htlcs:
- Balance us: 1001000000
- Balance them: 999000000
+ Balance us: MilliSatoshi(1001000000)
+ Balance them: MilliSatoshi(999000000)
Fee rate: 10000
***B***
LOCAL COMMITS:
Commit 2:
Offered htlcs:
Received htlcs:
- Balance us: 1001000000
- Balance them: 999000000
+ Balance us: MilliSatoshi(1001000000)
+ Balance them: MilliSatoshi(999000000)
Fee rate: 10000
REMOTE COMMITS:
Commit 2:
Offered htlcs:
Received htlcs:
- Balance us: 999000000
- Balance them: 1001000000
+ Balance us: MilliSatoshi(999000000)
+ Balance them: MilliSatoshi(1001000000)
Fee rate: 10000
diff --git a/eclair-core/src/test/resources/scenarii/04-two-commits-onedir.script.expected b/eclair-core/src/test/resources/scenarii/04-two-commits-onedir.script.expected
index f9eacd72d4..965efa4bc8 100644
--- a/eclair-core/src/test/resources/scenarii/04-two-commits-onedir.script.expected
+++ b/eclair-core/src/test/resources/scenarii/04-two-commits-onedir.script.expected
@@ -3,28 +3,28 @@ LOCAL COMMITS:
Commit 1:
Offered htlcs: (0,1000000) (1,2000000)
Received htlcs:
- Balance us: 997000000
- Balance them: 1000000000
+ Balance us: MilliSatoshi(997000000)
+ Balance them: MilliSatoshi(1000000000)
Fee rate: 10000
REMOTE COMMITS:
Commit 2:
Offered htlcs:
Received htlcs: (0,1000000) (1,2000000)
- Balance us: 1000000000
- Balance them: 997000000
+ Balance us: MilliSatoshi(1000000000)
+ Balance them: MilliSatoshi(997000000)
Fee rate: 10000
***B***
LOCAL COMMITS:
Commit 2:
Offered htlcs:
Received htlcs: (0,1000000) (1,2000000)
- Balance us: 1000000000
- Balance them: 997000000
+ Balance us: MilliSatoshi(1000000000)
+ Balance them: MilliSatoshi(997000000)
Fee rate: 10000
REMOTE COMMITS:
Commit 1:
Offered htlcs: (0,1000000) (1,2000000)
Received htlcs:
- Balance us: 997000000
- Balance them: 1000000000
+ Balance us: MilliSatoshi(997000000)
+ Balance them: MilliSatoshi(1000000000)
Fee rate: 10000
diff --git a/eclair-core/src/test/resources/scenarii/10-offers-crossover.script.expected b/eclair-core/src/test/resources/scenarii/10-offers-crossover.script.expected
index dfbeddddb2..51469b487b 100644
--- a/eclair-core/src/test/resources/scenarii/10-offers-crossover.script.expected
+++ b/eclair-core/src/test/resources/scenarii/10-offers-crossover.script.expected
@@ -1,30 +1,30 @@
***A***
LOCAL COMMITS:
Commit 1:
- Offered htlcs: (0,1000000)
- Received htlcs: (0,2000000)
- Balance us: 999000000
- Balance them: 998000000
+ Offered htlcs: (0,MilliSatoshi(1000000))
+ Received htlcs: (0,MilliSatoshi(2000000))
+ Balance us: MilliSatoshi(999000000)
+ Balance them: MilliSatoshi(998000000)
Fee rate: 10000
REMOTE COMMITS:
Commit 2:
- Offered htlcs: (0,2000000)
- Received htlcs: (0,1000000)
- Balance us: 998000000
- Balance them: 999000000
+ Offered htlcs: (0,MilliSatoshi(2000000))
+ Received htlcs: (0,MilliSatoshi(1000000))
+ Balance us: MilliSatoshi(998000000)
+ Balance them: MilliSatoshi(999000000)
Fee rate: 10000
***B***
LOCAL COMMITS:
Commit 2:
- Offered htlcs: (0,2000000)
- Received htlcs: (0,1000000)
- Balance us: 998000000
- Balance them: 999000000
+ Offered htlcs: (0,MilliSatoshi(2000000))
+ Received htlcs: (0,MilliSatoshi(1000000))
+ Balance us: MilliSatoshi(998000000)
+ Balance them: MilliSatoshi(999000000)
Fee rate: 10000
REMOTE COMMITS:
Commit 1:
- Offered htlcs: (0,1000000)
- Received htlcs: (0,2000000)
- Balance us: 999000000
- Balance them: 998000000
+ Offered htlcs: (0,MilliSatoshi(1000000))
+ Received htlcs: (0,MilliSatoshi(2000000))
+ Balance us: MilliSatoshi(999000000)
+ Balance them: MilliSatoshi(998000000)
Fee rate: 10000
diff --git a/eclair-core/src/test/resources/scenarii/11-commits-crossover.script.expected b/eclair-core/src/test/resources/scenarii/11-commits-crossover.script.expected
index bf1061fa9a..2c52101d82 100644
--- a/eclair-core/src/test/resources/scenarii/11-commits-crossover.script.expected
+++ b/eclair-core/src/test/resources/scenarii/11-commits-crossover.script.expected
@@ -1,30 +1,30 @@
***A***
LOCAL COMMITS:
Commit 2:
- Offered htlcs: (0,1000000)
- Received htlcs: (0,2000000)
- Balance us: 999000000
- Balance them: 998000000
+ Offered htlcs: (0,MilliSatoshi(1000000))
+ Received htlcs: (0,MilliSatoshi(2000000))
+ Balance us: MilliSatoshi(999000000)
+ Balance them: MilliSatoshi(998000000)
Fee rate: 10000
REMOTE COMMITS:
Commit 2:
- Offered htlcs: (0,2000000)
- Received htlcs: (0,1000000)
- Balance us: 998000000
- Balance them: 999000000
+ Offered htlcs: (0,MilliSatoshi(2000000))
+ Received htlcs: (0,MilliSatoshi(1000000))
+ Balance us: MilliSatoshi(998000000)
+ Balance them: MilliSatoshi(999000000)
Fee rate: 10000
***B***
LOCAL COMMITS:
Commit 2:
- Offered htlcs: (0,2000000)
- Received htlcs: (0,1000000)
- Balance us: 998000000
- Balance them: 999000000
+ Offered htlcs: (0,MilliSatoshi(2000000))
+ Received htlcs: (0,MilliSatoshi(1000000))
+ Balance us: MilliSatoshi(998000000)
+ Balance them: MilliSatoshi(999000000)
Fee rate: 10000
REMOTE COMMITS:
Commit 2:
- Offered htlcs: (0,1000000)
- Received htlcs: (0,2000000)
- Balance us: 999000000
- Balance them: 998000000
+ Offered htlcs: (0,MilliSatoshi(1000000))
+ Received htlcs: (0,MilliSatoshi(2000000))
+ Balance us: MilliSatoshi(999000000)
+ Balance them: MilliSatoshi(998000000)
Fee rate: 10000
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/CoinUtilsSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/CoinUtilsSpec.scala
index ea294912a5..8e051c2c93 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/CoinUtilsSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/CoinUtilsSpec.scala
@@ -16,7 +16,7 @@
package fr.acinq.eclair
-import fr.acinq.bitcoin.{Btc, MilliBtc, MilliSatoshi, Satoshi}
+import fr.acinq.bitcoin.{Btc, MilliBtc, Satoshi}
import org.scalatest.FunSuite
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/EclairImplSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/EclairImplSpec.scala
index 2ab1b0b329..728815f5a3 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/EclairImplSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/EclairImplSpec.scala
@@ -16,18 +16,14 @@
package fr.acinq.eclair
-import java.io.File
-
import akka.actor.ActorSystem
import akka.testkit.{TestKit, TestProbe}
-import fr.acinq.bitcoin.{ByteVector32, MilliSatoshi}
-import fr.acinq.bitcoin.{ByteVector32, Crypto}
+import fr.acinq.bitcoin.{ByteVector32, Crypto, Satoshi}
import akka.util.Timeout
import fr.acinq.bitcoin.Crypto.PublicKey
import fr.acinq.eclair.blockchain.TestWallet
import fr.acinq.eclair.io.Peer.OpenChannel
import fr.acinq.eclair.payment.PaymentLifecycle.{ReceivePayment, SendPayment, SendPaymentToRoute}
-import org.scalatest.{Outcome, fixture}
import fr.acinq.eclair.payment.PaymentLifecycle.SendPayment
import fr.acinq.eclair.payment.PaymentRequest.ExtraHop
import org.scalatest.{Matchers, Outcome, fixture}
@@ -37,10 +33,8 @@ import fr.acinq.eclair.channel.{CMD_FORCECLOSE, Register}
import fr.acinq.eclair.payment.LocalPaymentHandler
import fr.acinq.eclair.channel._
import fr.acinq.eclair.db._
-import fr.acinq.eclair.payment.PaymentRequest
import fr.acinq.eclair.router.RouteCalculationSpec.makeUpdate
import org.mockito.scalatest.IdiomaticMockito
-
import scala.concurrent.Await
import scala.util.{Failure, Success}
import scala.concurrent.duration._
@@ -84,12 +78,12 @@ class EclairImplSpec extends TestKit(ActorSystem("mySystem")) with fixture.FunSu
val nodeId = PublicKey(hex"030bb6a5e0c6b203c7e2180fb78c7ba4bdce46126761d8201b91ddac089cdecc87")
// standard conversion
- eclair.open(nodeId, fundingSatoshis = 10000000L, pushMsat_opt = None, fundingFeerateSatByte_opt = Some(5), flags_opt = None, openTimeout_opt = None)
+ eclair.open(nodeId, fundingAmount = Satoshi(10000000L), pushAmount_opt = None, fundingFeerateSatByte_opt = Some(5), flags_opt = None, openTimeout_opt = None)
val open = switchboard.expectMsgType[OpenChannel]
assert(open.fundingTxFeeratePerKw_opt == Some(1250))
// check that minimum fee rate of 253 sat/bw is used
- eclair.open(nodeId, fundingSatoshis = 10000000L, pushMsat_opt = None, fundingFeerateSatByte_opt = Some(1), flags_opt = None, openTimeout_opt = None)
+ eclair.open(nodeId, fundingAmount = Satoshi(10000000L), pushAmount_opt = None, fundingFeerateSatByte_opt = Some(1), flags_opt = None, openTimeout_opt = None)
val open1 = switchboard.expectMsgType[OpenChannel]
assert(open1.fundingTxFeeratePerKw_opt == Some(MinimumFeeratePerKw))
}
@@ -100,37 +94,37 @@ class EclairImplSpec extends TestKit(ActorSystem("mySystem")) with fixture.FunSu
val eclair = new EclairImpl(kit)
val nodeId = PublicKey(hex"030bb6a5e0c6b203c7e2180fb78c7ba4bdce46126761d8201b91ddac089cdecc87")
- eclair.send(recipientNodeId = nodeId, amountMsat = 123, paymentHash = ByteVector32.Zeroes, assistedRoutes = Seq.empty, minFinalCltvExpiry_opt = None)
+ eclair.send(recipientNodeId = nodeId, amount = MilliSatoshi(123), paymentHash = ByteVector32.Zeroes, assistedRoutes = Seq.empty, minFinalCltvExpiry_opt = None)
val send = paymentInitiator.expectMsgType[SendPayment]
assert(send.targetNodeId == nodeId)
- assert(send.amountMsat == 123)
+ assert(send.amount == MilliSatoshi(123))
assert(send.paymentHash == ByteVector32.Zeroes)
assert(send.assistedRoutes == Seq.empty)
// with assisted routes
val hints = Seq(Seq(ExtraHop(Bob.nodeParams.nodeId, ShortChannelId("569178x2331x1"), feeBaseMsat = 10, feeProportionalMillionths = 1, cltvExpiryDelta = 12)))
- eclair.send(recipientNodeId = nodeId, amountMsat = 123, paymentHash = ByteVector32.Zeroes, assistedRoutes = hints, minFinalCltvExpiry_opt = None)
+ eclair.send(recipientNodeId = nodeId, amount = MilliSatoshi(123), paymentHash = ByteVector32.Zeroes, assistedRoutes = hints, minFinalCltvExpiry_opt = None)
val send1 = paymentInitiator.expectMsgType[SendPayment]
assert(send1.targetNodeId == nodeId)
- assert(send1.amountMsat == 123)
+ assert(send1.amount == MilliSatoshi(123))
assert(send1.paymentHash == ByteVector32.Zeroes)
assert(send1.assistedRoutes == hints)
// with finalCltvExpiry
- eclair.send(recipientNodeId = nodeId, amountMsat = 123, paymentHash = ByteVector32.Zeroes, assistedRoutes = Seq.empty, minFinalCltvExpiry_opt = Some(96))
+ eclair.send(recipientNodeId = nodeId, amount = MilliSatoshi(123), paymentHash = ByteVector32.Zeroes, assistedRoutes = Seq.empty, minFinalCltvExpiry_opt = Some(96))
val send2 = paymentInitiator.expectMsgType[SendPayment]
assert(send2.targetNodeId == nodeId)
- assert(send2.amountMsat == 123)
+ assert(send2.amount == MilliSatoshi(123))
assert(send2.paymentHash == ByteVector32.Zeroes)
assert(send2.finalCltvExpiry == 96)
// with custom route fees parameters
- eclair.send(recipientNodeId = nodeId, amountMsat = 123, paymentHash = ByteVector32.Zeroes, assistedRoutes = Seq.empty, minFinalCltvExpiry_opt = None, feeThresholdSat_opt = Some(123), maxFeePct_opt = Some(4.20))
+ eclair.send(recipientNodeId = nodeId, amount = MilliSatoshi(123), paymentHash = ByteVector32.Zeroes, assistedRoutes = Seq.empty, minFinalCltvExpiry_opt = None, feeThreshold_opt = Some(Satoshi(123)), maxFeePct_opt = Some(4.20))
val send3 = paymentInitiator.expectMsgType[SendPayment]
assert(send3.targetNodeId == nodeId)
- assert(send3.amountMsat == 123)
+ assert(send3.amount == MilliSatoshi(123))
assert(send3.paymentHash == ByteVector32.Zeroes)
- assert(send3.routeParams.get.maxFeeBaseMsat == 123 * 1000) // conversion sat -> msat
+ assert(send3.routeParams.get.maxFeeBase == Satoshi(123).toMilliSatoshi) // conversion sat -> msat
assert(send3.routeParams.get.maxFeePct == 4.20)
}
@@ -140,11 +134,11 @@ class EclairImplSpec extends TestKit(ActorSystem("mySystem")) with fixture.FunSu
val (a, b, c, d, e) = (randomKey.publicKey, randomKey.publicKey, randomKey.publicKey, randomKey.publicKey, randomKey.publicKey)
val updates = List(
- makeUpdate(1L, a, b, feeBaseMsat = 0, 0, minHtlcMsat = 0, maxHtlcMsat = None, cltvDelta = 13),
- makeUpdate(4L, a, e, feeBaseMsat = 0, 0, minHtlcMsat = 0, maxHtlcMsat = None, cltvDelta = 12),
- makeUpdate(2L, b, c, feeBaseMsat = 1, 0, minHtlcMsat = 0, maxHtlcMsat = None, cltvDelta = 500),
- makeUpdate(3L, c, d, feeBaseMsat = 1, 0, minHtlcMsat = 0, maxHtlcMsat = None, cltvDelta = 500),
- makeUpdate(7L, e, c, feeBaseMsat = 2, 0, minHtlcMsat = 0, maxHtlcMsat = None, cltvDelta = 12)
+ makeUpdate(1L, a, b, feeBase = MilliSatoshi(0), 0, minHtlc = MilliSatoshi(0), maxHtlc = None, cltvDelta = 13),
+ makeUpdate(4L, a, e, feeBase = MilliSatoshi(0), 0, minHtlc = MilliSatoshi(0), maxHtlc = None, cltvDelta = 12),
+ makeUpdate(2L, b, c, feeBase = MilliSatoshi(1), 0, minHtlc = MilliSatoshi(0), maxHtlc = None, cltvDelta = 500),
+ makeUpdate(3L, c, d, feeBase = MilliSatoshi(1), 0, minHtlc = MilliSatoshi(0), maxHtlc = None, cltvDelta = 500),
+ makeUpdate(7L, e, c, feeBase = MilliSatoshi(2), 0, minHtlc = MilliSatoshi(0), maxHtlc = None, cltvDelta = 12)
).toMap
val eclair = new EclairImpl(kit)
@@ -188,15 +182,15 @@ class EclairImplSpec extends TestKit(ActorSystem("mySystem")) with fixture.FunSu
val fallBackAddressRaw = "muhtvdmsnbQEPFuEmxcChX58fGvXaaUoVt"
val eclair = new EclairImpl(kit)
- eclair.receive("some desc", Some(123L), Some(456), Some(fallBackAddressRaw), None)
+ eclair.receive("some desc", Some(MilliSatoshi(123L)), Some(456), Some(fallBackAddressRaw), None)
val receive = paymentHandler.expectMsgType[ReceivePayment]
- assert(receive.amountMsat_opt == Some(MilliSatoshi(123L)))
+ assert(receive.amount_opt == Some(MilliSatoshi(123L)))
assert(receive.expirySeconds_opt == Some(456))
assert(receive.fallbackAddress == Some(fallBackAddressRaw))
// try with wrong address format
- assertThrows[IllegalArgumentException](eclair.receive("some desc", Some(123L), Some(456), Some("wassa wassa"), None))
+ assertThrows[IllegalArgumentException](eclair.receive("some desc", Some(MilliSatoshi(123L)), Some(456), Some("wassa wassa"), None))
}
test("passing a payment_preimage to /createinvoice should result in an invoice with payment_hash=H(payment_preimage)") { fixture =>
@@ -206,7 +200,7 @@ class EclairImplSpec extends TestKit(ActorSystem("mySystem")) with fixture.FunSu
val eclair = new EclairImpl(kitWithPaymentHandler)
val paymentPreimage = randomBytes32
- val fResp = eclair.receive(description = "some desc", amountMsat_opt = None, expire_opt = None, fallbackAddress_opt = None, paymentPreimage_opt = Some(paymentPreimage))
+ val fResp = eclair.receive(description = "some desc", amount_opt = None, expire_opt = None, fallbackAddress_opt = None, paymentPreimage_opt = Some(paymentPreimage))
awaitCond({
fResp.value match {
case Some(Success(pr)) => pr.paymentHash == Crypto.sha256(paymentPreimage)
@@ -252,12 +246,12 @@ class EclairImplSpec extends TestKit(ActorSystem("mySystem")) with fixture.FunSu
val route = Seq(PublicKey(hex"030bb6a5e0c6b203c7e2180fb78c7ba4bdce46126761d8201b91ddac089cdecc87"))
val eclair = new EclairImpl(kit)
- eclair.sendToRoute(route, 1234, ByteVector32.One, 123)
+ eclair.sendToRoute(route, MilliSatoshi(1234), ByteVector32.One, 123)
val send = paymentInitiator.expectMsgType[SendPaymentToRoute]
assert(send.hops == route)
- assert(send.amountMsat == 1234)
+ assert(send.amount == MilliSatoshi(1234))
assert(send.finalCltvExpiry == 123)
assert(send.paymentHash == ByteVector32.One)
}
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 3f5e0b3744..9c340e5a8e 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/TestConstants.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/TestConstants.scala
@@ -19,7 +19,7 @@ package fr.acinq.eclair
import java.sql.{Connection, DriverManager}
import fr.acinq.bitcoin.Crypto.PrivateKey
-import fr.acinq.bitcoin.{Block, ByteVector32, Script}
+import fr.acinq.bitcoin.{Block, ByteVector32, Satoshi, Script}
import fr.acinq.eclair.NodeParams.BITCOIND
import fr.acinq.eclair.blockchain.fee.{FeeEstimator, FeeTargets, FeeratesPerKw, OnChainFeeConf}
import fr.acinq.eclair.crypto.LocalKeyManager
@@ -36,8 +36,8 @@ import scala.concurrent.duration._
*/
object TestConstants {
- val fundingSatoshis = 1000000L
- val pushMsat = 200000000L
+ val fundingSatoshis = Satoshi(1000000L)
+ val pushMsat = MilliSatoshi(200000000L)
val feeratePerKw = 10000L
val emptyOnionPacket = wire.OnionRoutingPacket(0, ByteVector.fill(33)(0), ByteVector.fill(1300)(0), ByteVector32.Zeroes)
@@ -70,7 +70,7 @@ object TestConstants {
globalFeatures = ByteVector.empty,
localFeatures = ByteVector(0),
overrideFeatures = Map.empty,
- dustLimitSatoshis = 1100,
+ dustLimit = Satoshi(1100),
onChainFeeConf = OnChainFeeConf(
feeTargets = FeeTargets(6, 2, 2, 6),
feeEstimator = new TestFeeEstimator,
@@ -81,11 +81,11 @@ object TestConstants {
maxAcceptedHtlcs = 100,
expiryDeltaBlocks = 144,
fulfillSafetyBeforeTimeoutBlocks = 6,
- htlcMinimumMsat = 0,
+ htlcMinimum = MilliSatoshi(0),
minDepthBlocks = 3,
toRemoteDelayBlocks = 144,
maxToLocalDelayBlocks = 1000,
- feeBaseMsat = 546000,
+ feeBase = MilliSatoshi(546000),
feeProportionalMillionth = 10,
reserveToFundingRatio = 0.01, // note: not used (overridden below)
maxReserveToFundingRatio = 0.05,
@@ -101,12 +101,12 @@ object TestConstants {
channelFlags = 1,
watcherType = BITCOIND,
paymentRequestExpiry = 1 hour,
- minFundingSatoshis = 1000L,
+ minFundingSatoshis = Satoshi(1000L),
routerConf = RouterConf(
randomizeRouteSelection = false,
channelExcludeDuration = 60 seconds,
routerBroadcastInterval = 5 seconds,
- searchMaxFeeBaseSat = 21,
+ searchMaxFeeBase = Satoshi(21),
searchMaxFeePct = 0.03,
searchMaxCltv = 2016,
searchMaxRouteLength = 20,
@@ -124,7 +124,7 @@ object TestConstants {
defaultFinalScriptPubKey = Script.write(Script.pay2wpkh(PrivateKey(randomBytes32).publicKey)),
isFunder = true,
fundingSatoshis).copy(
- channelReserveSatoshis = 10000 // Bob will need to keep that much satoshis as direct payment
+ channelReserve = Satoshi(10000) // Bob will need to keep that much satoshis as direct payment
)
}
@@ -140,7 +140,7 @@ object TestConstants {
globalFeatures = ByteVector.empty,
localFeatures = ByteVector.empty, // no announcement
overrideFeatures = Map.empty,
- dustLimitSatoshis = 1000,
+ dustLimit = Satoshi(1000),
onChainFeeConf = OnChainFeeConf(
feeTargets = FeeTargets(6, 2, 2, 6),
feeEstimator = new TestFeeEstimator,
@@ -151,11 +151,11 @@ object TestConstants {
maxAcceptedHtlcs = 30,
expiryDeltaBlocks = 144,
fulfillSafetyBeforeTimeoutBlocks = 6,
- htlcMinimumMsat = 1000,
+ htlcMinimum = MilliSatoshi(1000),
minDepthBlocks = 3,
toRemoteDelayBlocks = 144,
maxToLocalDelayBlocks = 1000,
- feeBaseMsat = 546000,
+ feeBase = MilliSatoshi(546000),
feeProportionalMillionth = 10,
reserveToFundingRatio = 0.01, // note: not used (overridden below)
maxReserveToFundingRatio = 0.05,
@@ -171,12 +171,12 @@ object TestConstants {
channelFlags = 1,
watcherType = BITCOIND,
paymentRequestExpiry = 1 hour,
- minFundingSatoshis = 1000L,
+ minFundingSatoshis = Satoshi(1000L),
routerConf = RouterConf(
randomizeRouteSelection = false,
channelExcludeDuration = 60 seconds,
routerBroadcastInterval = 5 seconds,
- searchMaxFeeBaseSat = 21,
+ searchMaxFeeBase = Satoshi(21),
searchMaxFeePct = 0.03,
searchMaxCltv = 2016,
searchMaxRouteLength = 20,
@@ -194,7 +194,7 @@ object TestConstants {
defaultFinalScriptPubKey = Script.write(Script.pay2wpkh(PrivateKey(randomBytes32).publicKey)),
isFunder = false,
fundingSatoshis).copy(
- channelReserveSatoshis = 20000 // Alice will need to keep that much satoshis as direct payment
+ channelReserve = Satoshi(20000) // Alice will need to keep that much satoshis as direct payment
)
}
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/api/ApiServiceSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/api/ApiServiceSpec.scala
index 4c3f5d9e9d..87fbffeefe 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/api/ApiServiceSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/api/ApiServiceSpec.scala
@@ -27,7 +27,7 @@ import akka.http.scaladsl.testkit.{RouteTestTimeout, ScalatestRouteTest, WSProbe
import akka.stream.ActorMaterializer
import akka.util.Timeout
import fr.acinq.bitcoin.Crypto.PublicKey
-import fr.acinq.bitcoin.{ByteVector32, MilliSatoshi}
+import fr.acinq.bitcoin.{ByteVector32, Satoshi}
import fr.acinq.eclair.TestConstants._
import fr.acinq.eclair._
import fr.acinq.eclair.io.NodeURI
@@ -39,6 +39,7 @@ import org.json4s.jackson.Serialization
import org.mockito.scalatest.IdiomaticMockito
import org.scalatest.{FunSuite, Matchers}
import scodec.bits._
+
import scala.concurrent.Future
import scala.concurrent.duration._
import scala.io.Source
@@ -147,8 +148,8 @@ class ApiServiceSpec extends FunSuite with ScalatestRouteTest with IdiomaticMock
val eclair = mock[Eclair]
val mockService = new MockService(eclair)
eclair.usableBalances()(any[Timeout]) returns Future.successful(List(
- UsableBalances(canSendMsat = 100000000, canReceiveMsat = 20000000, shortChannelId = ShortChannelId(1), remoteNodeId = TestConstants.Alice.keyManager.nodeKey.publicKey, isPublic = true),
- UsableBalances(canSendMsat = 400000000, canReceiveMsat = 30000000, shortChannelId = ShortChannelId(2), remoteNodeId = TestConstants.Alice.keyManager.nodeKey.publicKey, isPublic = false)
+ UsableBalances(canSend = MilliSatoshi(100000000), canReceive = MilliSatoshi(20000000), shortChannelId = ShortChannelId(1), remoteNodeId = TestConstants.Alice.keyManager.nodeKey.publicKey, isPublic = true),
+ UsableBalances(canSend = MilliSatoshi(400000000), canReceive = MilliSatoshi(30000000), shortChannelId = ShortChannelId(2), remoteNodeId = TestConstants.Alice.keyManager.nodeKey.publicKey, isPublic = false)
))
Post("/usablebalances") ~>
@@ -269,7 +270,7 @@ class ApiServiceSpec extends FunSuite with ScalatestRouteTest with IdiomaticMock
check {
assert(handled)
assert(status == OK)
- eclair.send(any, 1258000, any, any, any, any, any, any)(any[Timeout]).wasCalled(once)
+ eclair.send(any, MilliSatoshi(1258000), any, any, any, any, any, any)(any[Timeout]).wasCalled(once)
}
@@ -279,7 +280,7 @@ class ApiServiceSpec extends FunSuite with ScalatestRouteTest with IdiomaticMock
check {
assert(handled)
assert(status == OK)
- eclair.send(any, 123, any, any, any, any, Some(112233), Some(2.34))(any[Timeout]).wasCalled(once)
+ eclair.send(any, MilliSatoshi(123), any, any, any, any, Some(Satoshi(112233)), Some(2.34))(any[Timeout]).wasCalled(once)
}
}
@@ -311,7 +312,7 @@ class ApiServiceSpec extends FunSuite with ScalatestRouteTest with IdiomaticMock
val jsonNodes = serialization.write(expectedRoute)
val eclair = mock[Eclair]
- eclair.sendToRoute(any[List[PublicKey]], anyLong, any[ByteVector32], anyLong)(any[Timeout]) returns Future.successful(paymentUUID)
+ eclair.sendToRoute(any[List[PublicKey]], any[MilliSatoshi], any[ByteVector32], anyLong)(any[Timeout]) returns Future.successful(paymentUUID)
val mockService = new MockService(eclair)
Post("/sendtoroute", FormData("route" -> jsonNodes, "amountMsat" -> "1234", "paymentHash" -> ByteVector32.Zeroes.toHex, "finalCltvExpiry" -> "190").toEntity) ~>
@@ -322,7 +323,7 @@ class ApiServiceSpec extends FunSuite with ScalatestRouteTest with IdiomaticMock
assert(handled)
assert(status == OK)
assert(entityAs[String] == "\""+rawUUID+"\"")
- eclair.sendToRoute(expectedRoute, 1234, ByteVector32.Zeroes, 190)(any[Timeout]).wasCalled(once)
+ eclair.sendToRoute(expectedRoute, MilliSatoshi(1234), ByteVector32.Zeroes, 190)(any[Timeout]).wasCalled(once)
}
// this test uses CSV encoded route
@@ -334,7 +335,7 @@ class ApiServiceSpec extends FunSuite with ScalatestRouteTest with IdiomaticMock
assert(handled)
assert(status == OK)
assert(entityAs[String] == "\""+rawUUID+"\"")
- eclair.sendToRoute(expectedRoute, 1234, ByteVector32.One, 190)(any[Timeout]).wasCalled(once)
+ eclair.sendToRoute(expectedRoute, MilliSatoshi(1234), ByteVector32.One, 190)(any[Timeout]).wasCalled(once)
}
}
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/api/JsonSerializersSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/api/JsonSerializersSpec.scala
index 4313c853e6..38a6b6d7cc 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/api/JsonSerializersSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/api/JsonSerializersSpec.scala
@@ -19,7 +19,7 @@ package fr.acinq.eclair.api
import java.net.InetAddress
import java.util.UUID
-import fr.acinq.bitcoin.{ByteVector32, MilliSatoshi, OutPoint, Transaction}
+import fr.acinq.bitcoin.{ByteVector32, OutPoint, Transaction}
import fr.acinq.eclair._
import fr.acinq.eclair.payment.{PaymentRequest, PaymentSettlingOnChain}
import fr.acinq.eclair.api.JsonSupport.CustomTypeHints
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/bitcoind/BitcoinCoreWalletSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/bitcoind/BitcoinCoreWalletSpec.scala
index 3af10b6426..50fb3666ef 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/bitcoind/BitcoinCoreWalletSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/bitcoind/BitcoinCoreWalletSpec.scala
@@ -257,7 +257,7 @@ class BitcoinCoreWalletSpec extends TestKit(ActorSystem("test")) with BitcoindSe
val tx1 = Transaction.read(signedTx1)
// let's then generate another tx that double spends the first one
val inputs = tx1.txIn.map(txIn => Map("txid" -> txIn.outPoint.txid.toString, "vout" -> txIn.outPoint.index)).toArray
- bitcoinClient.invoke("createrawtransaction", inputs, Map(address -> tx1.txOut.map(_.amount.toLong).sum * 1.0 / 1e8)).pipeTo(sender.ref)
+ bitcoinClient.invoke("createrawtransaction", inputs, Map(address -> tx1.txOut.map(_.amount).sum.toLong * 1.0 / 1e8)).pipeTo(sender.ref)
val JString(unsignedtx2) = sender.expectMsgType[JValue]
bitcoinClient.invoke("signrawtransactionwithwallet", unsignedtx2).pipeTo(sender.ref)
val JString(signedTx2) = sender.expectMsgType[JValue] \ "hex"
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/channel/FuzzySpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/channel/FuzzySpec.scala
index d44d98dc94..188ceada39 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/channel/FuzzySpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/channel/FuzzySpec.scala
@@ -22,7 +22,7 @@ import java.util.concurrent.CountDownLatch
import akka.actor.{Actor, ActorLogging, ActorRef, Props, Status}
import akka.testkit.{TestFSMRef, TestProbe}
import fr.acinq.bitcoin.Crypto.PublicKey
-import fr.acinq.bitcoin.{ByteVector32, MilliSatoshi}
+import fr.acinq.bitcoin.{ByteVector32}
import fr.acinq.eclair.TestConstants.{Alice, Bob}
import fr.acinq.eclair._
import fr.acinq.eclair.blockchain._
@@ -93,7 +93,7 @@ class FuzzySpec extends TestkitBaseClass with StateTestsHelperMethods with Loggi
def buildCmdAdd(paymentHash: ByteVector32, dest: PublicKey) = {
// allow overpaying (no more than 2 times the required amount)
- val amount = requiredAmount + Random.nextInt(requiredAmount)
+ val amount = MilliSatoshi(requiredAmount + Random.nextInt(requiredAmount))
val expiry = Globals.blockCount.get().toInt + Channel.MIN_CLTV_EXPIRY + 1
PaymentLifecycle.buildCommand(UUID.randomUUID(), amount, expiry, paymentHash, Hop(null, dest, null) :: Nil)._1
}
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/channel/ThroughputSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/channel/ThroughputSpec.scala
index 9ff1329b8e..08aa1f88d6 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/channel/ThroughputSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/channel/ThroughputSpec.scala
@@ -51,7 +51,7 @@ class ThroughputSpec extends FunSuite {
case ('add, tgt: ActorRef) =>
val r = randomBytes32
val h = Crypto.sha256(r)
- tgt ! CMD_ADD_HTLC(1, h, 1, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
+ tgt ! CMD_ADD_HTLC(MilliSatoshi(1), h, 1, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
context.become(run(h2r + (h -> r)))
case ('sig, tgt: ActorRef) => tgt ! CMD_SIGN
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/StateTestsHelperMethods.scala b/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/StateTestsHelperMethods.scala
index ac21eeba31..e614c054d7 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/StateTestsHelperMethods.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/StateTestsHelperMethods.scala
@@ -20,6 +20,7 @@ import java.util.UUID
import akka.testkit.{TestFSMRef, TestKitBase, TestProbe}
import fr.acinq.bitcoin.{ByteVector32, Crypto}
+import fr.acinq.eclair
import fr.acinq.eclair.TestConstants.{Alice, Bob, TestFeeEstimator}
import fr.acinq.eclair.blockchain._
import fr.acinq.eclair.blockchain.fee.FeeTargets
@@ -29,6 +30,7 @@ import fr.acinq.eclair.payment.PaymentLifecycle
import fr.acinq.eclair.router.Hop
import fr.acinq.eclair.wire._
import fr.acinq.eclair.{Globals, NodeParams, TestConstants, randomBytes32}
+import fr.acinq.eclair._
/**
* Created by PM on 23/08/2016.
@@ -66,7 +68,7 @@ trait StateTestsHelperMethods extends TestKitBase {
tags: Set[String] = Set.empty): Unit = {
import setup._
val channelFlags = if (tags.contains("channels_public")) ChannelFlags.AnnounceChannel else ChannelFlags.Empty
- val pushMsat = if (tags.contains("no_push_msat")) 0 else TestConstants.pushMsat
+ val pushMsat = if (tags.contains("no_push_msat")) MilliSatoshi(0) else TestConstants.pushMsat
val (aliceParams, bobParams) = (Alice.channelParams, Bob.channelParams)
val aliceInit = Init(aliceParams.globalFeatures, aliceParams.localFeatures)
val bobInit = Init(bobParams.globalFeatures, bobParams.localFeatures)
@@ -98,19 +100,19 @@ trait StateTestsHelperMethods extends TestKitBase {
bob2blockchain.expectMsgType[WatchConfirmed] // deeply buried
awaitCond(alice.stateName == NORMAL)
awaitCond(bob.stateName == NORMAL)
- assert(bob.stateData.asInstanceOf[DATA_NORMAL].commitments.availableBalanceForSendMsat == math.max(pushMsat - TestConstants.Alice.channelParams.channelReserveSatoshis * 1000, 0))
+ assert(bob.stateData.asInstanceOf[DATA_NORMAL].commitments.availableBalanceForSend == maxOf(pushMsat - TestConstants.Alice.channelParams.channelReserve.toMilliSatoshi, MilliSatoshi(0)))
// x2 because alice and bob share the same relayer
channelUpdateListener.expectMsgType[LocalChannelUpdate]
channelUpdateListener.expectMsgType[LocalChannelUpdate]
}
- def addHtlc(amountMsat: Int, s: TestFSMRef[State, Data, Channel], r: TestFSMRef[State, Data, Channel], s2r: TestProbe, r2s: TestProbe): (ByteVector32, UpdateAddHtlc) = {
+ def addHtlc(amount: MilliSatoshi, s: TestFSMRef[State, Data, Channel], r: TestFSMRef[State, Data, Channel], s2r: TestProbe, r2s: TestProbe): (ByteVector32, UpdateAddHtlc) = {
val R: ByteVector32 = randomBytes32
val H: ByteVector32 = Crypto.sha256(R)
val sender = TestProbe()
val receiverPubkey = r.underlyingActor.nodeParams.nodeId
val expiry = 400144
- val cmd = PaymentLifecycle.buildCommand(UUID.randomUUID, amountMsat, expiry, H, Hop(null, receiverPubkey, null) :: Nil)._1.copy(commit = false)
+ val cmd = PaymentLifecycle.buildCommand(UUID.randomUUID, amount, expiry, H, Hop(null, receiverPubkey, null) :: Nil)._1.copy(commit = false)
sender.send(s, cmd)
sender.expectMsg("ok")
val htlc = s2r.expectMsgType[UpdateAddHtlc]
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/a/WaitForAcceptChannelStateSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/a/WaitForAcceptChannelStateSpec.scala
index b71fd9de45..980384bc58 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/a/WaitForAcceptChannelStateSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/a/WaitForAcceptChannelStateSpec.scala
@@ -83,7 +83,7 @@ class WaitForAcceptChannelStateSpec extends TestkitBaseClass with StateTestsHelp
import f._
val accept = bob2alice.expectMsgType[AcceptChannel]
// we don't want their dust limit to be below 546
- val lowDustLimitSatoshis = 545
+ val lowDustLimitSatoshis = Satoshi(545)
alice ! accept.copy(dustLimitSatoshis = lowDustLimitSatoshis)
val error = alice2bob.expectMsgType[Error]
assert(error === Error(accept.temporaryChannelId, DustLimitTooSmall(accept.temporaryChannelId, lowDustLimitSatoshis, Channel.MIN_DUSTLIMIT).getMessage))
@@ -104,7 +104,7 @@ class WaitForAcceptChannelStateSpec extends TestkitBaseClass with StateTestsHelp
import f._
val accept = bob2alice.expectMsgType[AcceptChannel]
// 30% is huge, recommended ratio is 1%
- val reserveTooHigh = (0.3 * TestConstants.fundingSatoshis).toLong
+ val reserveTooHigh = Satoshi((0.3 * TestConstants.fundingSatoshis.toLong).toLong)
alice ! accept.copy(channelReserveSatoshis = reserveTooHigh)
val error = alice2bob.expectMsgType[Error]
assert(error === Error(accept.temporaryChannelId, ChannelReserveTooHigh(accept.temporaryChannelId, reserveTooHigh, 0.3, 0.05).getMessage))
@@ -114,7 +114,7 @@ class WaitForAcceptChannelStateSpec extends TestkitBaseClass with StateTestsHelp
test("recv AcceptChannel (reserve below dust limit)") { f =>
import f._
val accept = bob2alice.expectMsgType[AcceptChannel]
- val reserveTooSmall = accept.dustLimitSatoshis - 1
+ val reserveTooSmall = accept.dustLimitSatoshis - Satoshi(1)
alice ! accept.copy(channelReserveSatoshis = reserveTooSmall)
val error = alice2bob.expectMsgType[Error]
assert(error === Error(accept.temporaryChannelId, DustLimitTooLarge(accept.temporaryChannelId, accept.dustLimitSatoshis, reserveTooSmall).getMessage))
@@ -125,7 +125,7 @@ class WaitForAcceptChannelStateSpec extends TestkitBaseClass with StateTestsHelp
import f._
val accept = bob2alice.expectMsgType[AcceptChannel]
val open = alice.stateData.asInstanceOf[DATA_WAIT_FOR_ACCEPT_CHANNEL].lastSent
- val reserveTooSmall = open.dustLimitSatoshis - 1
+ val reserveTooSmall = open.dustLimitSatoshis - Satoshi(1)
alice ! accept.copy(channelReserveSatoshis = reserveTooSmall)
val error = alice2bob.expectMsgType[Error]
assert(error === Error(accept.temporaryChannelId, ChannelReserveBelowOurDustLimit(accept.temporaryChannelId, reserveTooSmall, open.dustLimitSatoshis).getMessage))
@@ -136,7 +136,7 @@ class WaitForAcceptChannelStateSpec extends TestkitBaseClass with StateTestsHelp
import f._
val accept = bob2alice.expectMsgType[AcceptChannel]
val open = alice.stateData.asInstanceOf[DATA_WAIT_FOR_ACCEPT_CHANNEL].lastSent
- val dustTooBig = open.channelReserveSatoshis + 1
+ val dustTooBig = open.channelReserveSatoshis + Satoshi(1)
alice ! accept.copy(dustLimitSatoshis = dustTooBig)
val error = alice2bob.expectMsgType[Error]
assert(error === Error(accept.temporaryChannelId, DustLimitAboveOurChannelReserve(accept.temporaryChannelId, dustTooBig, open.channelReserveSatoshis).getMessage))
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/a/WaitForOpenChannelStateSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/a/WaitForOpenChannelStateSpec.scala
index 6b74dfd654..549ee6f692 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/a/WaitForOpenChannelStateSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/a/WaitForOpenChannelStateSpec.scala
@@ -17,12 +17,12 @@
package fr.acinq.eclair.channel.states.a
import akka.testkit.{TestFSMRef, TestProbe}
-import fr.acinq.bitcoin.{Block, ByteVector32}
+import fr.acinq.bitcoin.{Block, ByteVector32, Satoshi}
import fr.acinq.eclair.TestConstants.{Alice, Bob}
import fr.acinq.eclair.channel._
import fr.acinq.eclair.channel.states.StateTestsHelperMethods
import fr.acinq.eclair.wire.{Error, Init, OpenChannel}
-import fr.acinq.eclair.{TestConstants, TestkitBaseClass}
+import fr.acinq.eclair.{MilliSatoshi, TestConstants, TestkitBaseClass, ToMilliSatoshiConversion}
import org.scalatest.Outcome
import scala.concurrent.duration._
@@ -69,20 +69,20 @@ class WaitForOpenChannelStateSpec extends TestkitBaseClass with StateTestsHelper
test("recv OpenChannel (funding too low)") { f =>
import f._
val open = alice2bob.expectMsgType[OpenChannel]
- val lowFundingMsat = 100
- bob ! open.copy(fundingSatoshis = lowFundingMsat)
+ val lowFunding = Satoshi(100)
+ bob ! open.copy(fundingSatoshis = lowFunding)
val error = bob2alice.expectMsgType[Error]
- assert(error === Error(open.temporaryChannelId, InvalidFundingAmount(open.temporaryChannelId, lowFundingMsat, Bob.nodeParams.minFundingSatoshis, Channel.MAX_FUNDING_SATOSHIS).getMessage))
+ assert(error === Error(open.temporaryChannelId, InvalidFundingAmount(open.temporaryChannelId, lowFunding, Bob.nodeParams.minFundingSatoshis, Channel.MAX_FUNDING).getMessage))
awaitCond(bob.stateName == CLOSED)
}
test("recv OpenChannel (funding too high)") { f =>
import f._
val open = alice2bob.expectMsgType[OpenChannel]
- val highFundingMsat = 100000000
+ val highFundingMsat = Satoshi(100000000)
bob ! open.copy(fundingSatoshis = highFundingMsat)
val error = bob2alice.expectMsgType[Error]
- assert(error === Error(open.temporaryChannelId, InvalidFundingAmount(open.temporaryChannelId, highFundingMsat, Bob.nodeParams.minFundingSatoshis, Channel.MAX_FUNDING_SATOSHIS).getMessage))
+ assert(error.toAscii === Error(open.temporaryChannelId, InvalidFundingAmount(open.temporaryChannelId, highFundingMsat, Bob.nodeParams.minFundingSatoshis, Channel.MAX_FUNDING).getMessage).toAscii)
awaitCond(bob.stateName == CLOSED)
}
@@ -99,10 +99,10 @@ class WaitForOpenChannelStateSpec extends TestkitBaseClass with StateTestsHelper
test("recv OpenChannel (invalid push_msat)") { f =>
import f._
val open = alice2bob.expectMsgType[OpenChannel]
- val invalidPushMsat = 100000000000L
+ val invalidPushMsat = MilliSatoshi(100000000000L)
bob ! open.copy(pushMsat = invalidPushMsat)
val error = bob2alice.expectMsgType[Error]
- assert(error === Error(open.temporaryChannelId, InvalidPushAmount(open.temporaryChannelId, invalidPushMsat, 1000 * open.fundingSatoshis).getMessage))
+ assert(error === Error(open.temporaryChannelId, InvalidPushAmount(open.temporaryChannelId, invalidPushMsat, open.fundingSatoshis.toMilliSatoshi).getMessage))
awaitCond(bob.stateName == CLOSED)
}
@@ -120,7 +120,7 @@ class WaitForOpenChannelStateSpec extends TestkitBaseClass with StateTestsHelper
import f._
val open = alice2bob.expectMsgType[OpenChannel]
// 30% is huge, recommended ratio is 1%
- val reserveTooHigh = (0.3 * TestConstants.fundingSatoshis).toLong
+ val reserveTooHigh = Satoshi((0.3 * TestConstants.fundingSatoshis.toLong).toLong)
bob ! open.copy(channelReserveSatoshis = reserveTooHigh)
val error = bob2alice.expectMsgType[Error]
assert(error === Error(open.temporaryChannelId, ChannelReserveTooHigh(open.temporaryChannelId, reserveTooHigh, 0.3, 0.05).getMessage))
@@ -155,7 +155,7 @@ class WaitForOpenChannelStateSpec extends TestkitBaseClass with StateTestsHelper
test("recv OpenChannel (reserve below dust)") { f =>
import f._
val open = alice2bob.expectMsgType[OpenChannel]
- val reserveTooSmall = open.dustLimitSatoshis - 1
+ val reserveTooSmall = open.dustLimitSatoshis - Satoshi(1)
bob ! open.copy(channelReserveSatoshis = reserveTooSmall)
val error = bob2alice.expectMsgType[Error]
// we check that the error uses the temporary channel id
@@ -166,12 +166,12 @@ class WaitForOpenChannelStateSpec extends TestkitBaseClass with StateTestsHelper
test("recv OpenChannel (toLocal + toRemote below reserve)") { f =>
import f._
val open = alice2bob.expectMsgType[OpenChannel]
- val fundingSatoshis = open.channelReserveSatoshis + 499
+ val fundingSatoshis = open.channelReserveSatoshis.toLong + 499
val pushMsat = 500 * 1000
- bob ! open.copy(fundingSatoshis = fundingSatoshis, pushMsat = pushMsat)
+ bob ! open.copy(fundingSatoshis = Satoshi(fundingSatoshis), pushMsat = MilliSatoshi(pushMsat))
val error = bob2alice.expectMsgType[Error]
// we check that the error uses the temporary channel id
- assert(error === Error(open.temporaryChannelId, ChannelReserveNotMet(open.temporaryChannelId, 500 * 1000, (open.channelReserveSatoshis - 1) * 1000, open.channelReserveSatoshis).getMessage))
+ assert(error === Error(open.temporaryChannelId, ChannelReserveNotMet(open.temporaryChannelId, Satoshi(500).toMilliSatoshi, (open.channelReserveSatoshis - Satoshi(1)).toMilliSatoshi, open.channelReserveSatoshis).getMessage))
awaitCond(bob.stateName == CLOSED)
}
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/b/WaitForFundingCreatedStateSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/b/WaitForFundingCreatedStateSpec.scala
index 3bc38c87cf..9a88921c3d 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/b/WaitForFundingCreatedStateSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/b/WaitForFundingCreatedStateSpec.scala
@@ -17,14 +17,14 @@
package fr.acinq.eclair.channel.states.b
import akka.testkit.{TestFSMRef, TestProbe}
-import fr.acinq.bitcoin.ByteVector32
+import fr.acinq.bitcoin.{ByteVector32, Satoshi}
import fr.acinq.eclair.TestConstants.{Alice, Bob}
import fr.acinq.eclair.blockchain._
import fr.acinq.eclair.channel._
import fr.acinq.eclair.channel.states.StateTestsHelperMethods
import fr.acinq.eclair.transactions.Transactions
import fr.acinq.eclair.wire._
-import fr.acinq.eclair.{TestConstants, TestkitBaseClass}
+import fr.acinq.eclair.{MilliSatoshi, TestConstants, TestkitBaseClass}
import org.scalatest.{Outcome, Tag}
import scala.concurrent.duration._
@@ -41,7 +41,7 @@ class WaitForFundingCreatedStateSpec extends TestkitBaseClass with StateTestsHel
val setup = init()
import setup._
val (fundingSatoshis, pushMsat) = if (test.tags.contains("funder_below_reserve")) {
- (1000100L, 1000000000L) // toRemote = 100 satoshis
+ (Satoshi(1000100L), MilliSatoshi(1000000000L)) // toRemote = 100 satoshis
} else {
(TestConstants.fundingSatoshis, TestConstants.pushMsat)
}
@@ -71,13 +71,13 @@ class WaitForFundingCreatedStateSpec extends TestkitBaseClass with StateTestsHel
test("recv FundingCreated (funder can't pay fees)", Tag("funder_below_reserve")) { f =>
import f._
- val fees = Transactions.commitWeight * TestConstants.feeratePerKw / 1000
- val reserve = Bob.channelParams.channelReserveSatoshis
- val missing = 100 - fees - reserve
+ val fees = Satoshi(Transactions.commitWeight * TestConstants.feeratePerKw / 1000)
+ val reserve = Bob.channelParams.channelReserve
+ val missing = Satoshi(100) - fees - reserve
val fundingCreated = alice2bob.expectMsgType[FundingCreated]
alice2bob.forward(bob)
val error = bob2alice.expectMsgType[Error]
- assert(error === Error(fundingCreated.temporaryChannelId, s"can't pay the fee: missingSatoshis=${-1 * missing} reserveSatoshis=$reserve feesSatoshis=$fees"))
+ assert(error === Error(fundingCreated.temporaryChannelId, s"can't pay the fee: missing=${-missing} reserve=$reserve fees=$fees"))
awaitCond(bob.stateName == CLOSED)
}
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 e327d9cad6..2300d25e05 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
@@ -23,6 +23,7 @@ import akka.actor.Status.Failure
import akka.testkit.TestProbe
import fr.acinq.bitcoin.Crypto.PrivateKey
import fr.acinq.bitcoin.{ByteVector32, ByteVector64, Crypto, Satoshi, ScriptFlags, Transaction}
+import fr.acinq.eclair._
import fr.acinq.eclair.TestConstants.{Alice, Bob, TestFeeEstimator}
import fr.acinq.eclair.UInt64.Conversions._
import fr.acinq.eclair.blockchain._
@@ -69,7 +70,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
val initialState = alice.stateData.asInstanceOf[DATA_NORMAL]
val sender = TestProbe()
val h = randomBytes32
- val add = CMD_ADD_HTLC(50000000, h, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
+ val add = CMD_ADD_HTLC(MilliSatoshi(50000000), h, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
sender.send(alice, add)
sender.expectMsg("ok")
val htlc = alice2bob.expectMsgType[UpdateAddHtlc]
@@ -87,7 +88,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
val sender = TestProbe()
val h = randomBytes32
for (i <- 0 until 10) {
- sender.send(alice, CMD_ADD_HTLC(50000000, h, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID())))
+ sender.send(alice, CMD_ADD_HTLC(MilliSatoshi(50000000), h, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID())))
sender.expectMsg("ok")
val htlc = alice2bob.expectMsgType[UpdateAddHtlc]
assert(htlc.id == i && htlc.paymentHash == h)
@@ -99,8 +100,8 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
val initialState = alice.stateData.asInstanceOf[DATA_NORMAL]
val sender = TestProbe()
val h = randomBytes32
- val originHtlc = UpdateAddHtlc(channelId = randomBytes32, id = 5656, amountMsat = 50000000, cltvExpiry = 400144, paymentHash = h, onionRoutingPacket = TestConstants.emptyOnionPacket)
- val cmd = CMD_ADD_HTLC(originHtlc.amountMsat - 10000, h, originHtlc.cltvExpiry - 7, TestConstants.emptyOnionPacket, upstream = Right(originHtlc))
+ val originHtlc = UpdateAddHtlc(channelId = randomBytes32, id = 5656, amountMsat = MilliSatoshi(50000000), cltvExpiry = 400144, paymentHash = h, onionRoutingPacket = TestConstants.emptyOnionPacket)
+ val cmd = CMD_ADD_HTLC(originHtlc.amountMsat - MilliSatoshi(10000), h, originHtlc.cltvExpiry - 7, TestConstants.emptyOnionPacket, upstream = Right(originHtlc))
sender.send(alice, cmd)
sender.expectMsg("ok")
val htlc = alice2bob.expectMsgType[UpdateAddHtlc]
@@ -119,7 +120,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
val initialState = alice.stateData.asInstanceOf[DATA_NORMAL]
val currentBlockCount = Globals.blockCount.get
val expiryTooSmall = currentBlockCount + 3
- val add = CMD_ADD_HTLC(500000000, randomBytes32, expiryTooSmall, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
+ val add = CMD_ADD_HTLC(MilliSatoshi(500000000), randomBytes32, expiryTooSmall, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
sender.send(alice, add)
val error = ExpiryTooSmall(channelId(alice), currentBlockCount + Channel.MIN_CLTV_EXPIRY, expiryTooSmall, currentBlockCount)
sender.expectMsg(Failure(AddHtlcFailed(channelId(alice), add.paymentHash, error, Local(add.upstream.left.get, Some(sender.ref)), Some(initialState.channelUpdate), Some(add))))
@@ -132,7 +133,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
val initialState = alice.stateData.asInstanceOf[DATA_NORMAL]
val currentBlockCount = Globals.blockCount.get
val expiryTooBig = currentBlockCount + Channel.MAX_CLTV_EXPIRY + 1
- val add = CMD_ADD_HTLC(500000000, randomBytes32, expiryTooBig, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
+ val add = CMD_ADD_HTLC(MilliSatoshi(500000000), randomBytes32, expiryTooBig, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
sender.send(alice, add)
val error = ExpiryTooBig(channelId(alice), maximum = currentBlockCount + Channel.MAX_CLTV_EXPIRY, actual = expiryTooBig, blockCount = currentBlockCount)
sender.expectMsg(Failure(AddHtlcFailed(channelId(alice), add.paymentHash, error, Local(add.upstream.left.get, Some(sender.ref)), Some(initialState.channelUpdate), Some(add))))
@@ -143,9 +144,9 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
import f._
val sender = TestProbe()
val initialState = alice.stateData.asInstanceOf[DATA_NORMAL]
- val add = CMD_ADD_HTLC(50, randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
+ val add = CMD_ADD_HTLC(MilliSatoshi(50), randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
sender.send(alice, add)
- val error = HtlcValueTooSmall(channelId(alice), 1000, 50)
+ val error = HtlcValueTooSmall(channelId(alice), MilliSatoshi(1000), MilliSatoshi(50))
sender.expectMsg(Failure(AddHtlcFailed(channelId(alice), add.paymentHash, error, Local(add.upstream.left.get, Some(sender.ref)), Some(initialState.channelUpdate), Some(add))))
alice2bob.expectNoMsg(200 millis)
}
@@ -154,9 +155,9 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
import f._
val sender = TestProbe()
val initialState = alice.stateData.asInstanceOf[DATA_NORMAL]
- val add = CMD_ADD_HTLC(Int.MaxValue, randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
+ val add = CMD_ADD_HTLC(MilliSatoshi(Int.MaxValue), randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
sender.send(alice, add)
- val error = InsufficientFunds(channelId(alice), amountMsat = Int.MaxValue, missingSatoshis = 1376443, reserveSatoshis = 20000, feesSatoshis = 8960)
+ val error = InsufficientFunds(channelId(alice), amount = MilliSatoshi(Int.MaxValue), missing = Satoshi(1376443), reserve = Satoshi(20000), fees = Satoshi(8960))
sender.expectMsg(Failure(AddHtlcFailed(channelId(alice), add.paymentHash, error, Local(add.upstream.left.get, Some(sender.ref)), Some(initialState.channelUpdate), Some(add))))
alice2bob.expectNoMsg(200 millis)
}
@@ -165,18 +166,18 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
import f._
val sender = TestProbe()
val initialState = alice.stateData.asInstanceOf[DATA_NORMAL]
- sender.send(alice, CMD_ADD_HTLC(500000000, randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID())))
+ sender.send(alice, CMD_ADD_HTLC(MilliSatoshi(500000000), randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID())))
sender.expectMsg("ok")
alice2bob.expectMsgType[UpdateAddHtlc]
- sender.send(alice, CMD_ADD_HTLC(200000000, randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID())))
+ sender.send(alice, CMD_ADD_HTLC(MilliSatoshi(200000000), randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID())))
sender.expectMsg("ok")
alice2bob.expectMsgType[UpdateAddHtlc]
- sender.send(alice, CMD_ADD_HTLC(67600000, randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID())))
+ sender.send(alice, CMD_ADD_HTLC(MilliSatoshi(67600000), randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID())))
sender.expectMsg("ok")
alice2bob.expectMsgType[UpdateAddHtlc]
- val add = CMD_ADD_HTLC(1000000, randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
+ val add = CMD_ADD_HTLC(MilliSatoshi(1000000), randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
sender.send(alice, add)
- val error = InsufficientFunds(channelId(alice), amountMsat = 1000000, missingSatoshis = 1000, reserveSatoshis = 20000, feesSatoshis = 12400)
+ val error = InsufficientFunds(channelId(alice), amount = MilliSatoshi(1000000), missing = Satoshi(1000), reserve = Satoshi(20000), fees = Satoshi(12400))
sender.expectMsg(Failure(AddHtlcFailed(channelId(alice), add.paymentHash, error, Local(add.upstream.left.get, Some(sender.ref)), Some(initialState.channelUpdate), Some(add))))
alice2bob.expectNoMsg(200 millis)
}
@@ -185,15 +186,15 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
import f._
val sender = TestProbe()
val initialState = alice.stateData.asInstanceOf[DATA_NORMAL]
- sender.send(alice, CMD_ADD_HTLC(300000000, randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID())))
+ sender.send(alice, CMD_ADD_HTLC(MilliSatoshi(300000000), randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID())))
sender.expectMsg("ok")
alice2bob.expectMsgType[UpdateAddHtlc]
- sender.send(alice, CMD_ADD_HTLC(300000000, randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID())))
+ sender.send(alice, CMD_ADD_HTLC(MilliSatoshi(300000000), randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID())))
sender.expectMsg("ok")
alice2bob.expectMsgType[UpdateAddHtlc]
- val add = CMD_ADD_HTLC(500000000, randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
+ val add = CMD_ADD_HTLC(MilliSatoshi(500000000), randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
sender.send(alice, add)
- val error = InsufficientFunds(channelId(alice), amountMsat = 500000000, missingSatoshis = 332400, reserveSatoshis = 20000, feesSatoshis = 12400)
+ val error = InsufficientFunds(channelId(alice), amount = MilliSatoshi(500000000), missing = Satoshi(332400), reserve = Satoshi(20000), fees = Satoshi(12400))
sender.expectMsg(Failure(AddHtlcFailed(channelId(alice), add.paymentHash, error, Local(add.upstream.left.get, Some(sender.ref)), Some(initialState.channelUpdate), Some(add))))
alice2bob.expectNoMsg(200 millis)
}
@@ -202,7 +203,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
import f._
val sender = TestProbe()
val initialState = bob.stateData.asInstanceOf[DATA_NORMAL]
- val add = CMD_ADD_HTLC(151000000, randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
+ val add = CMD_ADD_HTLC(MilliSatoshi(151000000), randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
sender.send(bob, add)
val error = HtlcValueTooHighInFlight(channelId(bob), maximum = 150000000, actual = 151000000)
sender.expectMsg(Failure(AddHtlcFailed(channelId(bob), add.paymentHash, error, Local(add.upstream.left.get, Some(sender.ref)), Some(initialState.channelUpdate), Some(add))))
@@ -215,11 +216,11 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
val initialState = alice.stateData.asInstanceOf[DATA_NORMAL]
// Bob accepts a maximum of 30 htlcs
for (i <- 0 until 30) {
- sender.send(alice, CMD_ADD_HTLC(10000000, randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID())))
+ sender.send(alice, CMD_ADD_HTLC(MilliSatoshi(10000000), randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID())))
sender.expectMsg("ok")
alice2bob.expectMsgType[UpdateAddHtlc]
}
- val add = CMD_ADD_HTLC(10000000, randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
+ val add = CMD_ADD_HTLC(MilliSatoshi(10000000), randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
sender.send(alice, add)
val error = TooManyAcceptedHtlcs(channelId(alice), maximum = 30)
sender.expectMsg(Failure(AddHtlcFailed(channelId(alice), add.paymentHash, error, Local(add.upstream.left.get, Some(sender.ref)), Some(initialState.channelUpdate), Some(add))))
@@ -230,7 +231,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
import f._
val sender = TestProbe()
val initialState = alice.stateData.asInstanceOf[DATA_NORMAL]
- val add1 = CMD_ADD_HTLC(TestConstants.fundingSatoshis * 2 / 3 * 1000, randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
+ val add1 = CMD_ADD_HTLC(TestConstants.fundingSatoshis.toMilliSatoshi * 2 / 3, randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
sender.send(alice, add1)
sender.expectMsg("ok")
alice2bob.expectMsgType[UpdateAddHtlc]
@@ -238,9 +239,9 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
sender.expectMsg("ok")
alice2bob.expectMsgType[CommitSig]
// this is over channel-capacity
- val add2 = CMD_ADD_HTLC(TestConstants.fundingSatoshis * 2 / 3 * 1000, randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
+ val add2 = CMD_ADD_HTLC(TestConstants.fundingSatoshis.toMilliSatoshi * 2 / 3, randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
sender.send(alice, add2)
- val error = InsufficientFunds(channelId(alice), add2.amountMsat, 564012, 20000, 10680)
+ val error = InsufficientFunds(channelId(alice), add2.amount, Satoshi(564013), Satoshi(20000), Satoshi(10680))
sender.expectMsg(Failure(AddHtlcFailed(channelId(alice), add2.paymentHash, error, Local(add2.upstream.left.get, Some(sender.ref)), Some(initialState.channelUpdate), Some(add2))))
alice2bob.expectNoMsg(200 millis)
}
@@ -255,7 +256,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
awaitCond(alice.stateData.asInstanceOf[DATA_NORMAL].localShutdown.isDefined && alice.stateData.asInstanceOf[DATA_NORMAL].remoteShutdown.isEmpty)
// actual test starts here
- val add = CMD_ADD_HTLC(500000000, randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
+ val add = CMD_ADD_HTLC(MilliSatoshi(500000000), randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
sender.send(alice, add)
val error = NoMoreHtlcsClosingInProgress(channelId(alice))
sender.expectMsg(Failure(AddHtlcFailed(channelId(alice), add.paymentHash, error, Local(add.upstream.left.get, Some(sender.ref)), Some(initialState.channelUpdate), Some(add))))
@@ -267,14 +268,14 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
val sender = TestProbe()
val initialState = alice.stateData.asInstanceOf[DATA_NORMAL]
// let's make alice send an htlc
- val add1 = CMD_ADD_HTLC(500000000, randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
+ val add1 = CMD_ADD_HTLC(MilliSatoshi(500000000), randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
sender.send(alice, add1)
sender.expectMsg("ok")
// at the same time bob initiates a closing
sender.send(bob, CMD_CLOSE(None))
sender.expectMsg("ok")
// this command will be received by alice right after having received the shutdown
- val add2 = CMD_ADD_HTLC(100000000, randomBytes32, 300000, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
+ val add2 = CMD_ADD_HTLC(MilliSatoshi(100000000), randomBytes32, 300000, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
// messages cross
alice2bob.expectMsgType[UpdateAddHtlc]
alice2bob.forward(bob)
@@ -288,7 +289,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv UpdateAddHtlc") { f =>
import f._
val initialData = bob.stateData.asInstanceOf[DATA_NORMAL]
- val htlc = UpdateAddHtlc(ByteVector32.Zeroes, 0, 150000, randomBytes32, 400144, TestConstants.emptyOnionPacket)
+ val htlc = UpdateAddHtlc(ByteVector32.Zeroes, 0, MilliSatoshi(150000), randomBytes32, 400144, TestConstants.emptyOnionPacket)
bob ! htlc
awaitCond(bob.stateData == initialData.copy(commitments = initialData.commitments.copy(remoteChanges = initialData.commitments.remoteChanges.copy(proposed = initialData.commitments.remoteChanges.proposed :+ htlc), remoteNextHtlcId = 1)))
// bob won't forward the add before it is cross-signed
@@ -298,7 +299,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv UpdateAddHtlc (unexpected id)") { f =>
import f._
val tx = bob.stateData.asInstanceOf[DATA_NORMAL].commitments.localCommit.publishableTxs.commitTx.tx
- val htlc = UpdateAddHtlc(ByteVector32.Zeroes, 42, 150000, randomBytes32, 400144, TestConstants.emptyOnionPacket)
+ val htlc = UpdateAddHtlc(ByteVector32.Zeroes, 42, MilliSatoshi(150000), randomBytes32, 400144, TestConstants.emptyOnionPacket)
bob ! htlc.copy(id = 0)
bob ! htlc.copy(id = 1)
bob ! htlc.copy(id = 2)
@@ -315,10 +316,10 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv UpdateAddHtlc (value too small)") { f =>
import f._
val tx = bob.stateData.asInstanceOf[DATA_NORMAL].commitments.localCommit.publishableTxs.commitTx.tx
- val htlc = UpdateAddHtlc(ByteVector32.Zeroes, 0, 150, randomBytes32, cltvExpiry = 400144, TestConstants.emptyOnionPacket)
+ val htlc = UpdateAddHtlc(ByteVector32.Zeroes, 0, MilliSatoshi(150), randomBytes32, cltvExpiry = 400144, TestConstants.emptyOnionPacket)
alice2bob.forward(bob, htlc)
val error = bob2alice.expectMsgType[Error]
- assert(new String(error.data.toArray) === HtlcValueTooSmall(channelId(bob), minimum = 1000, actual = 150).getMessage)
+ assert(new String(error.data.toArray) === HtlcValueTooSmall(channelId(bob), minimum = MilliSatoshi(1000), actual = MilliSatoshi(150)).getMessage)
awaitCond(bob.stateName == CLOSING)
// channel should be advertised as down
assert(channelUpdateListener.expectMsgType[LocalChannelDown].channelId === bob.stateData.asInstanceOf[DATA_CLOSING].channelId)
@@ -330,10 +331,10 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv UpdateAddHtlc (insufficient funds)") { f =>
import f._
val tx = bob.stateData.asInstanceOf[DATA_NORMAL].commitments.localCommit.publishableTxs.commitTx.tx
- val htlc = UpdateAddHtlc(ByteVector32.Zeroes, 0, Long.MaxValue, randomBytes32, 400144, TestConstants.emptyOnionPacket)
+ val htlc = UpdateAddHtlc(ByteVector32.Zeroes, 0, MilliSatoshi(Long.MaxValue), randomBytes32, 400144, TestConstants.emptyOnionPacket)
alice2bob.forward(bob, htlc)
val error = bob2alice.expectMsgType[Error]
- assert(new String(error.data.toArray) === InsufficientFunds(channelId(bob), amountMsat = Long.MaxValue, missingSatoshis = 9223372036083735L, reserveSatoshis = 20000, feesSatoshis = 8960).getMessage)
+ assert(new String(error.data.toArray) === InsufficientFunds(channelId(bob), amount = MilliSatoshi(Long.MaxValue), missing = Satoshi(9223372036083735L), reserve = Satoshi(20000), fees = Satoshi(8960)).getMessage)
awaitCond(bob.stateName == CLOSING)
// channel should be advertised as down
assert(channelUpdateListener.expectMsgType[LocalChannelDown].channelId === bob.stateData.asInstanceOf[DATA_CLOSING].channelId)
@@ -345,12 +346,12 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv UpdateAddHtlc (insufficient funds w/ pending htlcs 1/2)") { f =>
import f._
val tx = bob.stateData.asInstanceOf[DATA_NORMAL].commitments.localCommit.publishableTxs.commitTx.tx
- alice2bob.forward(bob, UpdateAddHtlc(ByteVector32.Zeroes, 0, 400000000, randomBytes32, 400144, TestConstants.emptyOnionPacket))
- alice2bob.forward(bob, UpdateAddHtlc(ByteVector32.Zeroes, 1, 200000000, randomBytes32, 400144, TestConstants.emptyOnionPacket))
- alice2bob.forward(bob, UpdateAddHtlc(ByteVector32.Zeroes, 2, 167600000, randomBytes32, 400144, TestConstants.emptyOnionPacket))
- alice2bob.forward(bob, UpdateAddHtlc(ByteVector32.Zeroes, 3, 10000000, randomBytes32, 400144, TestConstants.emptyOnionPacket))
+ alice2bob.forward(bob, UpdateAddHtlc(ByteVector32.Zeroes, 0, MilliSatoshi(400000000), randomBytes32, 400144, TestConstants.emptyOnionPacket))
+ alice2bob.forward(bob, UpdateAddHtlc(ByteVector32.Zeroes, 1, MilliSatoshi(200000000), randomBytes32, 400144, TestConstants.emptyOnionPacket))
+ alice2bob.forward(bob, UpdateAddHtlc(ByteVector32.Zeroes, 2, MilliSatoshi(167600000), randomBytes32, 400144, TestConstants.emptyOnionPacket))
+ alice2bob.forward(bob, UpdateAddHtlc(ByteVector32.Zeroes, 3, MilliSatoshi(10000000), randomBytes32, 400144, TestConstants.emptyOnionPacket))
val error = bob2alice.expectMsgType[Error]
- assert(new String(error.data.toArray) === InsufficientFunds(channelId(bob), amountMsat = 10000000, missingSatoshis = 11720, reserveSatoshis = 20000, feesSatoshis = 14120).getMessage)
+ assert(new String(error.data.toArray) === InsufficientFunds(channelId(bob), amount = MilliSatoshi(10000000), missing = Satoshi(11720), reserve = Satoshi(20000), fees = Satoshi(14120)).getMessage)
awaitCond(bob.stateName == CLOSING)
// channel should be advertised as down
assert(channelUpdateListener.expectMsgType[LocalChannelDown].channelId === bob.stateData.asInstanceOf[DATA_CLOSING].channelId)
@@ -362,11 +363,11 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv UpdateAddHtlc (insufficient funds w/ pending htlcs 2/2)") { f =>
import f._
val tx = bob.stateData.asInstanceOf[DATA_NORMAL].commitments.localCommit.publishableTxs.commitTx.tx
- alice2bob.forward(bob, UpdateAddHtlc(ByteVector32.Zeroes, 0, 300000000, randomBytes32, 400144, TestConstants.emptyOnionPacket))
- alice2bob.forward(bob, UpdateAddHtlc(ByteVector32.Zeroes, 1, 300000000, randomBytes32, 400144, TestConstants.emptyOnionPacket))
- alice2bob.forward(bob, UpdateAddHtlc(ByteVector32.Zeroes, 2, 500000000, randomBytes32, 400144, TestConstants.emptyOnionPacket))
+ alice2bob.forward(bob, UpdateAddHtlc(ByteVector32.Zeroes, 0, MilliSatoshi(300000000), randomBytes32, 400144, TestConstants.emptyOnionPacket))
+ alice2bob.forward(bob, UpdateAddHtlc(ByteVector32.Zeroes, 1, MilliSatoshi(300000000), randomBytes32, 400144, TestConstants.emptyOnionPacket))
+ alice2bob.forward(bob, UpdateAddHtlc(ByteVector32.Zeroes, 2, MilliSatoshi(500000000), randomBytes32, 400144, TestConstants.emptyOnionPacket))
val error = bob2alice.expectMsgType[Error]
- assert(new String(error.data.toArray) === InsufficientFunds(channelId(bob), amountMsat = 500000000, missingSatoshis = 332400, reserveSatoshis = 20000, feesSatoshis = 12400).getMessage)
+ assert(new String(error.data.toArray) === InsufficientFunds(channelId(bob), amount = MilliSatoshi(500000000), missing = Satoshi(332400), reserve = Satoshi(20000), fees = Satoshi(12400)).getMessage)
awaitCond(bob.stateName == CLOSING)
// channel should be advertised as down
assert(channelUpdateListener.expectMsgType[LocalChannelDown].channelId === bob.stateData.asInstanceOf[DATA_CLOSING].channelId)
@@ -378,7 +379,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv UpdateAddHtlc (over max inflight htlc value)") { f =>
import f._
val tx = alice.stateData.asInstanceOf[DATA_NORMAL].commitments.localCommit.publishableTxs.commitTx.tx
- alice2bob.forward(alice, UpdateAddHtlc(ByteVector32.Zeroes, 0, 151000000, randomBytes32, 400144, TestConstants.emptyOnionPacket))
+ alice2bob.forward(alice, UpdateAddHtlc(ByteVector32.Zeroes, 0, MilliSatoshi(151000000), randomBytes32, 400144, TestConstants.emptyOnionPacket))
val error = alice2bob.expectMsgType[Error]
assert(new String(error.data.toArray) === HtlcValueTooHighInFlight(channelId(alice), maximum = 150000000, actual = 151000000).getMessage)
awaitCond(alice.stateName == CLOSING)
@@ -394,9 +395,9 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
val tx = bob.stateData.asInstanceOf[DATA_NORMAL].commitments.localCommit.publishableTxs.commitTx.tx
// Bob accepts a maximum of 30 htlcs
for (i <- 0 until 30) {
- alice2bob.forward(bob, UpdateAddHtlc(ByteVector32.Zeroes, i, 1000000, randomBytes32, 400144, TestConstants.emptyOnionPacket))
+ alice2bob.forward(bob, UpdateAddHtlc(ByteVector32.Zeroes, i, MilliSatoshi(1000000), randomBytes32, 400144, TestConstants.emptyOnionPacket))
}
- alice2bob.forward(bob, UpdateAddHtlc(ByteVector32.Zeroes, 30, 1000000, randomBytes32, 400144, TestConstants.emptyOnionPacket))
+ alice2bob.forward(bob, UpdateAddHtlc(ByteVector32.Zeroes, 30, MilliSatoshi(1000000), randomBytes32, 400144, TestConstants.emptyOnionPacket))
val error = bob2alice.expectMsgType[Error]
assert(new String(error.data.toArray) === TooManyAcceptedHtlcs(channelId(bob), maximum = 30).getMessage)
awaitCond(bob.stateName == CLOSING)
@@ -410,7 +411,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv CMD_SIGN") { f =>
import f._
val sender = TestProbe()
- val (r, htlc) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (r, htlc) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
sender.send(alice, CMD_SIGN)
sender.expectMsg("ok")
val commitSig = alice2bob.expectMsgType[CommitSig]
@@ -421,7 +422,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv CMD_SIGN (two identical htlcs in each direction)") { f =>
import f._
val sender = TestProbe()
- val add = CMD_ADD_HTLC(10000000, randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
+ val add = CMD_ADD_HTLC(MilliSatoshi(10000000), randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
sender.send(alice, add)
sender.expectMsg("ok")
alice2bob.expectMsgType[UpdateAddHtlc]
@@ -453,34 +454,34 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
import f._
val sender = TestProbe()
// for the test to be really useful we have constraint on parameters
- assert(Alice.nodeParams.dustLimitSatoshis > Bob.nodeParams.dustLimitSatoshis)
+ assert(Alice.nodeParams.dustLimit > Bob.nodeParams.dustLimit)
// we're gonna exchange two htlcs in each direction, the goal is to have bob's commitment have 4 htlcs, and alice's
// commitment only have 3. We will then check that alice indeed persisted 4 htlcs, and bob only 3.
- val aliceMinReceive = Alice.nodeParams.dustLimitSatoshis + weight2fee(TestConstants.feeratePerKw, htlcSuccessWeight).toLong
- val aliceMinOffer = Alice.nodeParams.dustLimitSatoshis + weight2fee(TestConstants.feeratePerKw, htlcTimeoutWeight).toLong
- val bobMinReceive = Bob.nodeParams.dustLimitSatoshis + weight2fee(TestConstants.feeratePerKw, htlcSuccessWeight).toLong
- val bobMinOffer = Bob.nodeParams.dustLimitSatoshis + weight2fee(TestConstants.feeratePerKw, htlcTimeoutWeight).toLong
- val a2b_1 = bobMinReceive + 10 // will be in alice and bob tx
- val a2b_2 = bobMinReceive + 20 // will be in alice and bob tx
- val b2a_1 = aliceMinReceive + 10 // will be in alice and bob tx
- val b2a_2 = bobMinOffer + 10 // will be only be in bob tx
+ val aliceMinReceive = Alice.nodeParams.dustLimit + weight2fee(TestConstants.feeratePerKw, htlcSuccessWeight)
+ val aliceMinOffer = Alice.nodeParams.dustLimit + weight2fee(TestConstants.feeratePerKw, htlcTimeoutWeight)
+ val bobMinReceive = Bob.nodeParams.dustLimit + weight2fee(TestConstants.feeratePerKw, htlcSuccessWeight)
+ val bobMinOffer = Bob.nodeParams.dustLimit + weight2fee(TestConstants.feeratePerKw, htlcTimeoutWeight)
+ val a2b_1 = bobMinReceive + Satoshi(10) // will be in alice and bob tx
+ val a2b_2 = bobMinReceive + Satoshi(20) // will be in alice and bob tx
+ val b2a_1 = aliceMinReceive + Satoshi(10) // will be in alice and bob tx
+ val b2a_2 = bobMinOffer + Satoshi(10) // will be only be in bob tx
assert(a2b_1 > aliceMinOffer && a2b_1 > bobMinReceive)
assert(a2b_2 > aliceMinOffer && a2b_2 > bobMinReceive)
assert(b2a_1 > aliceMinReceive && b2a_1 > bobMinOffer)
assert(b2a_2 < aliceMinReceive && b2a_2 > bobMinOffer)
- sender.send(alice, CMD_ADD_HTLC(a2b_1 * 1000, randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID())))
+ sender.send(alice, CMD_ADD_HTLC(a2b_1.toMilliSatoshi, randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID())))
sender.expectMsg("ok")
alice2bob.expectMsgType[UpdateAddHtlc]
alice2bob.forward(bob)
- sender.send(alice, CMD_ADD_HTLC(a2b_2 * 1000, randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID())))
+ sender.send(alice, CMD_ADD_HTLC(a2b_2.toMilliSatoshi, randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID())))
sender.expectMsg("ok")
alice2bob.expectMsgType[UpdateAddHtlc]
alice2bob.forward(bob)
- sender.send(bob, CMD_ADD_HTLC(b2a_1 * 1000, randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID())))
+ sender.send(bob, CMD_ADD_HTLC(b2a_1.toMilliSatoshi, randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID())))
sender.expectMsg("ok")
bob2alice.expectMsgType[UpdateAddHtlc]
bob2alice.forward(alice)
- sender.send(bob, CMD_ADD_HTLC(b2a_2 * 1000, randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID())))
+ sender.send(bob, CMD_ADD_HTLC(b2a_2.toMilliSatoshi, randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID())))
sender.expectMsg("ok")
bob2alice.expectMsgType[UpdateAddHtlc]
bob2alice.forward(alice)
@@ -495,16 +496,16 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
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 =>
import f._
val sender = TestProbe()
- val add = CMD_ADD_HTLC(10000000, randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
+ val add = CMD_ADD_HTLC(MilliSatoshi(10000000), randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
val epsilons = List(3, 1, 5, 7, 6) // unordered on purpose
val htlcCount = epsilons.size
for (i <- epsilons) {
- sender.send(alice, add.copy(amountMsat = add.amountMsat + i * 1000))
+ sender.send(alice, add.copy(amount = MilliSatoshi(add.amount.toLong + i * 1000)))
sender.expectMsg("ok")
alice2bob.expectMsgType[UpdateAddHtlc]
alice2bob.forward(bob)
@@ -532,7 +533,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv CMD_SIGN (while waiting for RevokeAndAck (no pending changes)") { f =>
import f._
val sender = TestProbe()
- val (r, htlc) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (r, htlc) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
awaitCond(alice.stateData.asInstanceOf[DATA_NORMAL].commitments.remoteNextCommitInfo.isRight)
sender.send(alice, CMD_SIGN)
sender.expectMsg("ok")
@@ -550,7 +551,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv CMD_SIGN (while waiting for RevokeAndAck (with pending changes)") { f =>
import f._
val sender = TestProbe()
- val (r1, htlc1) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (r1, htlc1) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
awaitCond(alice.stateData.asInstanceOf[DATA_NORMAL].commitments.remoteNextCommitInfo.isRight)
sender.send(alice, CMD_SIGN)
sender.expectMsg("ok")
@@ -560,7 +561,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
assert(waitForRevocation.reSignAsap === false)
// actual test starts here
- val (r2, htlc2) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (r2, htlc2) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
sender.send(alice, CMD_SIGN)
sender.expectNoMsg(300 millis)
assert(alice.stateData.asInstanceOf[DATA_NORMAL].commitments.remoteNextCommitInfo === Left(waitForRevocation.copy(reSignAsap = true)))
@@ -572,7 +573,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
// channel starts with all funds on alice's side, so channel will be initially disabled on bob's side
assert(Announcements.isEnabled(bob.stateData.asInstanceOf[DATA_NORMAL].channelUpdate.channelFlags) === false)
// alice will send enough funds to bob to make it go above reserve
- val (r, htlc) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (r, htlc) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
crossSign(alice, bob, alice2bob, bob2alice)
sender.send(bob, CMD_FULFILL_HTLC(htlc.id, r))
sender.expectMsg("ok")
@@ -596,7 +597,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
import f._
val sender = TestProbe()
- val (r, htlc) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (r, htlc) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
val initialState = bob.stateData.asInstanceOf[DATA_NORMAL]
sender.send(alice, CMD_SIGN)
@@ -612,7 +613,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
awaitCond(bob.stateData.asInstanceOf[DATA_NORMAL].commitments.localCommit.spec.htlcs.exists(h => h.add.id == htlc.id && h.direction == IN))
assert(bob.stateData.asInstanceOf[DATA_NORMAL].commitments.localCommit.publishableTxs.htlcTxsAndSigs.size == 1)
- assert(bob.stateData.asInstanceOf[DATA_NORMAL].commitments.localCommit.spec.toLocalMsat == initialState.commitments.localCommit.spec.toLocalMsat)
+ assert(bob.stateData.asInstanceOf[DATA_NORMAL].commitments.localCommit.spec.toLocal == initialState.commitments.localCommit.spec.toLocal)
assert(bob.stateData.asInstanceOf[DATA_NORMAL].commitments.remoteChanges.acked.size == 0)
assert(bob.stateData.asInstanceOf[DATA_NORMAL].commitments.remoteChanges.signed.size == 1)
}
@@ -621,7 +622,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
import f._
val sender = TestProbe()
- val (r, htlc) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (r, htlc) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
val initialState = bob.stateData.asInstanceOf[DATA_NORMAL]
sender.send(alice, CMD_SIGN)
@@ -637,26 +638,26 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
awaitCond(alice.stateData.asInstanceOf[DATA_NORMAL].commitments.localCommit.spec.htlcs.exists(h => h.add.id == htlc.id && h.direction == OUT))
assert(alice.stateData.asInstanceOf[DATA_NORMAL].commitments.localCommit.publishableTxs.htlcTxsAndSigs.size == 1)
- assert(bob.stateData.asInstanceOf[DATA_NORMAL].commitments.localCommit.spec.toLocalMsat == initialState.commitments.localCommit.spec.toLocalMsat)
+ assert(bob.stateData.asInstanceOf[DATA_NORMAL].commitments.localCommit.spec.toLocal == initialState.commitments.localCommit.spec.toLocal)
}
test("recv CommitSig (multiple htlcs in both directions)") { f =>
import f._
val sender = TestProbe()
- val (r1, htlc1) = addHtlc(50000000, alice, bob, alice2bob, bob2alice) // a->b (regular)
+ val (r1, htlc1) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice) // a->b (regular)
- val (r2, htlc2) = addHtlc(8000000, alice, bob, alice2bob, bob2alice) // a->b (regular)
+ val (r2, htlc2) = addHtlc(MilliSatoshi(8000000), alice, bob, alice2bob, bob2alice) // a->b (regular)
- val (r3, htlc3) = addHtlc(300000, bob, alice, bob2alice, alice2bob) // b->a (dust)
+ val (r3, htlc3) = addHtlc(MilliSatoshi(300000), bob, alice, bob2alice, alice2bob) // b->a (dust)
- val (r4, htlc4) = addHtlc(1000000, alice, bob, alice2bob, bob2alice) // a->b (regular)
+ val (r4, htlc4) = addHtlc(MilliSatoshi(1000000), alice, bob, alice2bob, bob2alice) // a->b (regular)
- val (r5, htlc5) = addHtlc(50000000, bob, alice, bob2alice, alice2bob) // b->a (regular)
+ val (r5, htlc5) = addHtlc(MilliSatoshi(50000000), bob, alice, bob2alice, alice2bob) // b->a (regular)
- val (r6, htlc6) = addHtlc(500000, alice, bob, alice2bob, bob2alice) // a->b (dust)
+ val (r6, htlc6) = addHtlc(MilliSatoshi(500000), alice, bob, alice2bob, bob2alice) // a->b (dust)
- val (r7, htlc7) = addHtlc(4000000, bob, alice, bob2alice, alice2bob) // b->a (regular)
+ val (r7, htlc7) = addHtlc(MilliSatoshi(4000000), bob, alice, bob2alice, alice2bob) // b->a (regular)
sender.send(alice, CMD_SIGN)
sender.expectMsg("ok")
@@ -698,12 +699,12 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
val r = randomBytes32
val h = Crypto.sha256(r)
- sender.send(alice, CMD_ADD_HTLC(50000000, h, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID())))
+ sender.send(alice, CMD_ADD_HTLC(MilliSatoshi(50000000), h, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID())))
sender.expectMsg("ok")
val htlc1 = alice2bob.expectMsgType[UpdateAddHtlc]
alice2bob.forward(bob)
- sender.send(alice, CMD_ADD_HTLC(50000000, h, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID())))
+ sender.send(alice, CMD_ADD_HTLC(MilliSatoshi(50000000), h, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID())))
sender.expectMsg("ok")
val htlc2 = alice2bob.expectMsgType[UpdateAddHtlc]
alice2bob.forward(bob)
@@ -714,7 +715,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
crossSign(alice, bob, alice2bob, bob2alice)
awaitCond(bob.stateData.asInstanceOf[DATA_NORMAL].commitments.localCommit.spec.htlcs.exists(h => h.add.id == htlc1.id && h.direction == IN))
assert(bob.stateData.asInstanceOf[DATA_NORMAL].commitments.localCommit.publishableTxs.htlcTxsAndSigs.size == 2)
- assert(bob.stateData.asInstanceOf[DATA_NORMAL].commitments.localCommit.spec.toLocalMsat == initialState.commitments.localCommit.spec.toLocalMsat)
+ assert(bob.stateData.asInstanceOf[DATA_NORMAL].commitments.localCommit.spec.toLocal == initialState.commitments.localCommit.spec.toLocal)
assert(bob.stateData.asInstanceOf[DATA_NORMAL].commitments.localCommit.publishableTxs.commitTx.tx.txOut.count(_.amount == Satoshi(50000)) == 2)
}
@@ -737,7 +738,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv CommitSig (invalid signature)") { f =>
import f._
val sender = TestProbe()
- val (r, htlc) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (r, htlc) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
val tx = bob.stateData.asInstanceOf[DATA_NORMAL].commitments.localCommit.publishableTxs.commitTx.tx
// actual test begins
@@ -754,7 +755,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
import f._
val sender = TestProbe()
- val (r, htlc) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (r, htlc) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
val tx = bob.stateData.asInstanceOf[DATA_NORMAL].commitments.localCommit.publishableTxs.commitTx.tx
sender.send(alice, CMD_SIGN)
@@ -775,7 +776,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
import f._
val sender = TestProbe()
- val (r, htlc) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (r, htlc) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
val tx = bob.stateData.asInstanceOf[DATA_NORMAL].commitments.localCommit.publishableTxs.commitTx.tx
sender.send(alice, CMD_SIGN)
@@ -796,7 +797,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv RevokeAndAck (one htlc sent)") { f =>
import f._
val sender = TestProbe()
- val (r, htlc) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (r, htlc) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
sender.send(alice, CMD_SIGN)
sender.expectMsg("ok")
@@ -814,7 +815,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv RevokeAndAck (one htlc received)") { f =>
import f._
val sender = TestProbe()
- val (_, htlc) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (_, htlc) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
sender.send(alice, CMD_SIGN)
sender.expectMsg("ok")
@@ -843,19 +844,19 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv RevokeAndAck (multiple htlcs in both directions)") { f =>
import f._
val sender = TestProbe()
- val (r1, htlc1) = addHtlc(50000000, alice, bob, alice2bob, bob2alice) // a->b (regular)
+ val (r1, htlc1) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice) // a->b (regular)
- val (r2, htlc2) = addHtlc(8000000, alice, bob, alice2bob, bob2alice) // a->b (regular)
+ val (r2, htlc2) = addHtlc(MilliSatoshi(8000000), alice, bob, alice2bob, bob2alice) // a->b (regular)
- val (r3, htlc3) = addHtlc(300000, bob, alice, bob2alice, alice2bob) // b->a (dust)
+ val (r3, htlc3) = addHtlc(MilliSatoshi(300000), bob, alice, bob2alice, alice2bob) // b->a (dust)
- val (r4, htlc4) = addHtlc(1000000, alice, bob, alice2bob, bob2alice) // a->b (regular)
+ val (r4, htlc4) = addHtlc(MilliSatoshi(1000000), alice, bob, alice2bob, bob2alice) // a->b (regular)
- val (r5, htlc5) = addHtlc(50000000, bob, alice, bob2alice, alice2bob) // b->a (regular)
+ val (r5, htlc5) = addHtlc(MilliSatoshi(50000000), bob, alice, bob2alice, alice2bob) // b->a (regular)
- val (r6, htlc6) = addHtlc(500000, alice, bob, alice2bob, bob2alice) // a->b (dust)
+ val (r6, htlc6) = addHtlc(MilliSatoshi(500000), alice, bob, alice2bob, bob2alice) // a->b (dust)
- val (r7, htlc7) = addHtlc(4000000, bob, alice, bob2alice, alice2bob) // b->a (regular)
+ val (r7, htlc7) = addHtlc(MilliSatoshi(4000000), bob, alice, bob2alice, alice2bob) // b->a (regular)
sender.send(alice, CMD_SIGN)
sender.expectMsg("ok")
@@ -880,13 +881,13 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv RevokeAndAck (with reSignAsap=true)") { f =>
import f._
val sender = TestProbe()
- val (r1, htlc1) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (r1, htlc1) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
awaitCond(alice.stateData.asInstanceOf[DATA_NORMAL].commitments.remoteNextCommitInfo.isRight)
sender.send(alice, CMD_SIGN)
sender.expectMsg("ok")
alice2bob.expectMsgType[CommitSig]
alice2bob.forward(bob)
- val (r2, htlc2) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (r2, htlc2) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
sender.send(alice, CMD_SIGN)
sender.expectNoMsg(300 millis)
assert(alice.stateData.asInstanceOf[DATA_NORMAL].commitments.remoteNextCommitInfo.left.toOption.get.reSignAsap === true)
@@ -901,7 +902,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
import f._
val tx = alice.stateData.asInstanceOf[DATA_NORMAL].commitments.localCommit.publishableTxs.commitTx.tx
val sender = TestProbe()
- val (r, htlc) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (r, htlc) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
sender.send(alice, CMD_SIGN)
sender.expectMsg("ok")
@@ -938,7 +939,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv RevokeAndAck (forward UpdateFailHtlc)") { f =>
import f._
val sender = TestProbe()
- val (_, htlc) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (_, htlc) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
crossSign(alice, bob, alice2bob, bob2alice)
sender.send(bob, CMD_FAIL_HTLC(htlc.id, Right(PermanentChannelFailure)))
sender.expectMsg("ok")
@@ -967,7 +968,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv RevokeAndAck (forward UpdateFailMalformedHtlc)") { f =>
import f._
val sender = TestProbe()
- val (_, htlc) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (_, htlc) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
crossSign(alice, bob, alice2bob, bob2alice)
sender.send(bob, CMD_FAIL_MALFORMED_HTLC(htlc.id, Sphinx.PaymentPacket.hash(htlc.onionRoutingPacket), FailureMessageCodecs.BADONION))
sender.expectMsg("ok")
@@ -996,7 +997,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv RevocationTimeout") { f =>
import f._
val sender = TestProbe()
- val (r, htlc) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (r, htlc) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
sender.send(alice, CMD_SIGN)
sender.expectMsg("ok")
@@ -1013,7 +1014,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv CMD_FULFILL_HTLC") { f =>
import f._
val sender = TestProbe()
- val (r, htlc) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (r, htlc) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
crossSign(alice, bob, alice2bob, bob2alice)
// actual test begins
@@ -1040,7 +1041,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv CMD_FULFILL_HTLC (invalid preimage)") { f =>
import f._
val sender = TestProbe()
- val (r, htlc) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (r, htlc) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
crossSign(alice, bob, alice2bob, bob2alice)
// actual test begins
@@ -1063,7 +1064,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv UpdateFulfillHtlc") { f =>
import f._
val sender = TestProbe()
- val (r, htlc) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (r, htlc) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
crossSign(alice, bob, alice2bob, bob2alice)
sender.send(bob, CMD_FULFILL_HTLC(htlc.id, r))
sender.expectMsg("ok")
@@ -1083,7 +1084,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv UpdateFulfillHtlc (sender has not signed htlc)") { f =>
import f._
val sender = TestProbe()
- val (r, htlc) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (r, htlc) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
sender.send(alice, CMD_SIGN)
sender.expectMsg("ok")
alice2bob.expectMsgType[CommitSig]
@@ -1117,7 +1118,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv UpdateFulfillHtlc (invalid preimage)") { f =>
import f._
val sender = TestProbe()
- val (r, htlc) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (r, htlc) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
crossSign(alice, bob, alice2bob, bob2alice)
relayerB.expectMsgType[ForwardAdd]
val tx = alice.stateData.asInstanceOf[DATA_NORMAL].commitments.localCommit.publishableTxs.commitTx.tx
@@ -1138,7 +1139,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv CMD_FAIL_HTLC") { f =>
import f._
val sender = TestProbe()
- val (r, htlc) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (r, htlc) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
crossSign(alice, bob, alice2bob, bob2alice)
// actual test begins
@@ -1176,7 +1177,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv CMD_FAIL_MALFORMED_HTLC") { f =>
import f._
val sender = TestProbe()
- val (r, htlc) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (r, htlc) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
crossSign(alice, bob, alice2bob, bob2alice)
// actual test begins
@@ -1221,7 +1222,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv UpdateFailHtlc") { f =>
import f._
val sender = TestProbe()
- val (_, htlc) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (_, htlc) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
crossSign(alice, bob, alice2bob, bob2alice)
sender.send(bob, CMD_FAIL_HTLC(htlc.id, Right(PermanentChannelFailure)))
sender.expectMsg("ok")
@@ -1241,7 +1242,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
val sender = TestProbe()
// Alice sends an HTLC to Bob, which they both sign
- val (_, htlc) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (_, htlc) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
crossSign(alice, bob, alice2bob, bob2alice)
// Bob fails the HTLC because he cannot parse it
val initialState = alice.stateData.asInstanceOf[DATA_NORMAL]
@@ -1268,7 +1269,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv UpdateFailMalformedHtlc (invalid failure_code)") { f =>
import f._
val sender = TestProbe()
- val (r, htlc) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (r, htlc) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
crossSign(alice, bob, alice2bob, bob2alice)
// actual test begins
@@ -1288,7 +1289,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv UpdateFailHtlc (sender has not signed htlc)") { f =>
import f._
val sender = TestProbe()
- val (r, htlc) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (r, htlc) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
sender.send(alice, CMD_SIGN)
sender.expectMsg("ok")
alice2bob.expectMsgType[CommitSig]
@@ -1396,7 +1397,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
bob.feeEstimator.setFeerate(FeeratesPerKw.single(fee.feeratePerKw))
sender.send(bob, fee)
val error = bob2alice.expectMsgType[Error]
- assert(new String(error.data.toArray) === CannotAffordFees(channelId(bob), missingSatoshis = 71620000L, reserveSatoshis = 20000L, feesSatoshis = 72400000L).getMessage)
+ assert(new String(error.data.toArray) === CannotAffordFees(channelId(bob), missing = Satoshi(71620000L), reserve = Satoshi(20000L), fees = Satoshi(72400000L)).getMessage)
awaitCond(bob.stateName == CLOSING)
// channel should be advertised as down
assert(channelUpdateListener.expectMsgType[LocalChannelDown].channelId === bob.stateData.asInstanceOf[DATA_CLOSING].channelId)
@@ -1446,7 +1447,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv CMD_UPDATE_RELAY_FEE ") { f =>
import f._
val sender = TestProbe()
- val newFeeBaseMsat = TestConstants.Alice.nodeParams.feeBaseMsat * 2
+ val newFeeBaseMsat = TestConstants.Alice.nodeParams.feeBase * 2
val newFeeProportionalMillionth = TestConstants.Alice.nodeParams.feeProportionalMillionth * 2
sender.send(alice, CMD_UPDATE_RELAY_FEE(newFeeBaseMsat, newFeeProportionalMillionth))
sender.expectMsg("ok")
@@ -1471,7 +1472,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv CMD_CLOSE (with unacked sent htlcs)") { f =>
import f._
val sender = TestProbe()
- val (r, htlc) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (r, htlc) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
sender.send(alice, CMD_CLOSE(None))
sender.expectMsg(Failure(CannotCloseWithUnsignedOutgoingHtlcs(channelId(bob))))
}
@@ -1486,7 +1487,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv CMD_CLOSE (with signed sent htlcs)") { f =>
import f._
val sender = TestProbe()
- val (r, htlc) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (r, htlc) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
crossSign(alice, bob, alice2bob, bob2alice)
sender.send(alice, CMD_CLOSE(None))
sender.expectMsg("ok")
@@ -1511,7 +1512,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv CMD_CLOSE (while waiting for a RevokeAndAck)") { f =>
import f._
val sender = TestProbe()
- val (r, htlc) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (r, htlc) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
sender.send(alice, CMD_SIGN)
sender.expectMsg("ok")
alice2bob.expectMsgType[CommitSig]
@@ -1536,7 +1537,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv Shutdown (with unacked sent htlcs)") { f =>
import f._
val sender = TestProbe()
- val (r, htlc) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (r, htlc) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
sender.send(bob, CMD_CLOSE(None))
bob2alice.expectMsgType[Shutdown]
// actual test begins
@@ -1557,7 +1558,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv Shutdown (with unacked received htlcs)") { f =>
import f._
val sender = TestProbe()
- val (r, htlc) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (r, htlc) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
// actual test begins
sender.send(bob, Shutdown(ByteVector32.Zeroes, TestConstants.Alice.channelParams.defaultFinalScriptPubKey))
bob2alice.expectMsgType[Error]
@@ -1581,7 +1582,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv Shutdown (with invalid final script and signed htlcs, in response to a Shutdown)") { f =>
import f._
val sender = TestProbe()
- val (r, htlc) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (r, htlc) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
crossSign(alice, bob, alice2bob, bob2alice)
sender.send(bob, CMD_CLOSE(None))
bob2alice.expectMsgType[Shutdown]
@@ -1597,7 +1598,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv Shutdown (with signed htlcs)") { f =>
import f._
val sender = TestProbe()
- val (r, htlc) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (r, htlc) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
crossSign(alice, bob, alice2bob, bob2alice)
// actual test begins
@@ -1609,7 +1610,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv Shutdown (while waiting for a RevokeAndAck)") { f =>
import f._
val sender = TestProbe()
- val (r, htlc) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (r, htlc) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
sender.send(alice, CMD_SIGN)
sender.expectMsg("ok")
alice2bob.expectMsgType[CommitSig]
@@ -1628,14 +1629,14 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
sender.send(bob, CMD_CLOSE(None))
bob2alice.expectMsgType[Shutdown]
// this is just so we have something to sign
- val (r, htlc) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (r, htlc) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
// now we can sign
sender.send(alice, CMD_SIGN)
sender.expectMsg("ok")
alice2bob.expectMsgType[CommitSig]
alice2bob.forward(bob)
// adding an outgoing pending htlc
- val (r1, htlc1) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (r1, htlc1) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
// actual test begins
// alice eventually gets bob's shutdown
bob2alice.forward(alice)
@@ -1665,7 +1666,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv CurrentBlockCount (no htlc timed out)") { f =>
import f._
val sender = TestProbe()
- val (r, htlc) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (r, htlc) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
crossSign(alice, bob, alice2bob, bob2alice)
// actual test begins
@@ -1677,7 +1678,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv CurrentBlockCount (an htlc timed out)") { f =>
import f._
val sender = TestProbe()
- val (r, htlc) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (r, htlc) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
crossSign(alice, bob, alice2bob, bob2alice)
// actual test begins
@@ -1696,7 +1697,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv CurrentBlockCount (fulfilled signed htlc ignored by upstream peer)") { f =>
import f._
val sender = TestProbe()
- val (r, htlc) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (r, htlc) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
crossSign(alice, bob, alice2bob, bob2alice)
val listener = TestProbe()
@@ -1731,7 +1732,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv CurrentBlockCount (fulfilled proposed htlc ignored by upstream peer)") { f =>
import f._
val sender = TestProbe()
- val (r, htlc) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (r, htlc) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
crossSign(alice, bob, alice2bob, bob2alice)
val listener = TestProbe()
@@ -1766,7 +1767,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv CurrentBlockCount (fulfilled proposed htlc acked but not committed by upstream peer)") { f =>
import f._
val sender = TestProbe()
- val (r, htlc) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (r, htlc) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
crossSign(alice, bob, alice2bob, bob2alice)
val listener = TestProbe()
@@ -1844,11 +1845,11 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
import f._
val sender = TestProbe()
- val (ra1, htlca1) = addHtlc(250000000, alice, bob, alice2bob, bob2alice)
- val (ra2, htlca2) = addHtlc(100000000, alice, bob, alice2bob, bob2alice)
- val (ra3, htlca3) = addHtlc(10000, alice, bob, alice2bob, bob2alice)
- val (rb1, htlcb1) = addHtlc(50000000, bob, alice, bob2alice, alice2bob)
- val (rb2, htlcb2) = addHtlc(55000000, bob, alice, bob2alice, alice2bob)
+ val (ra1, htlca1) = addHtlc(MilliSatoshi(250000000), alice, bob, alice2bob, bob2alice)
+ val (ra2, htlca2) = addHtlc(MilliSatoshi(100000000), alice, bob, alice2bob, bob2alice)
+ val (ra3, htlca3) = addHtlc(MilliSatoshi(10000), alice, bob, alice2bob, bob2alice)
+ val (rb1, htlcb1) = addHtlc(MilliSatoshi(50000000), bob, alice, bob2alice, alice2bob)
+ val (rb2, htlcb2) = addHtlc(MilliSatoshi(55000000), bob, alice, bob2alice, alice2bob)
crossSign(alice, bob, alice2bob, bob2alice)
fulfillHtlc(1, ra2, bob, alice, bob2alice, alice2bob)
fulfillHtlc(0, rb1, alice, bob, alice2bob, bob2alice)
@@ -1896,8 +1897,8 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
// assert the feerate of the claim main is what we expect
val expectedFeeRate = alice.feeEstimator.getFeeratePerKw(alice.feeTargets.claimMainBlockTarget)
- val expectedFee = Transactions.weight2fee(expectedFeeRate, Transactions.claimP2WPKHOutputWeight).toLong
- val claimFee = claimMain.txIn.map(in => bobCommitTx.txOut(in.outPoint.index.toInt).amount.toLong).sum - claimMain.txOut.map(_.amount.toLong).sum
+ val expectedFee = Transactions.weight2fee(expectedFeeRate, Transactions.claimP2WPKHOutputWeight)
+ val claimFee = claimMain.txIn.map(in => bobCommitTx.txOut(in.outPoint.index.toInt).amount).sum - claimMain.txOut.map(_.amount).sum
assert(claimFee == expectedFee)
}
@@ -1905,11 +1906,11 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
import f._
val sender = TestProbe()
- val (ra1, htlca1) = addHtlc(250000000, alice, bob, alice2bob, bob2alice)
- val (ra2, htlca2) = addHtlc(100000000, alice, bob, alice2bob, bob2alice)
- val (ra3, htlca3) = addHtlc(10000, alice, bob, alice2bob, bob2alice)
- val (rb1, htlcb1) = addHtlc(50000000, bob, alice, bob2alice, alice2bob)
- val (rb2, htlcb2) = addHtlc(55000000, bob, alice, bob2alice, alice2bob)
+ val (ra1, htlca1) = addHtlc(MilliSatoshi(250000000), alice, bob, alice2bob, bob2alice)
+ val (ra2, htlca2) = addHtlc(MilliSatoshi(100000000), alice, bob, alice2bob, bob2alice)
+ val (ra3, htlca3) = addHtlc(MilliSatoshi(10000), alice, bob, alice2bob, bob2alice)
+ val (rb1, htlcb1) = addHtlc(MilliSatoshi(50000000), bob, alice, bob2alice, alice2bob)
+ val (rb2, htlcb2) = addHtlc(MilliSatoshi(55000000), bob, alice, bob2alice, alice2bob)
crossSign(alice, bob, alice2bob, bob2alice)
fulfillHtlc(1, ra2, bob, alice, bob2alice, alice2bob)
fulfillHtlc(0, rb1, alice, bob, alice2bob, bob2alice)
@@ -1971,7 +1972,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
// bob = 200 000
def send(): Transaction = {
// alice sends 8 000 sat
- val (r, htlc) = addHtlc(10000000, alice, bob, alice2bob, bob2alice)
+ val (r, htlc) = addHtlc(MilliSatoshi(10000000), alice, bob, alice2bob, bob2alice)
crossSign(alice, bob, alice2bob, bob2alice)
bob.stateData.asInstanceOf[DATA_NORMAL].commitments.localCommit.publishableTxs.commitTx.tx
@@ -2030,7 +2031,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
// alice = 800 000
// bob = 200 000
- val add = CMD_ADD_HTLC(10000000, randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
+ val add = CMD_ADD_HTLC(MilliSatoshi(10000000), randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
sender.send(alice, add)
sender.expectMsg("ok")
alice2bob.expectMsgType[UpdateAddHtlc]
@@ -2078,11 +2079,11 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv Error") { f =>
import f._
- val (ra1, htlca1) = addHtlc(250000000, alice, bob, alice2bob, bob2alice)
- val (ra2, htlca2) = addHtlc(100000000, alice, bob, alice2bob, bob2alice)
- val (ra3, htlca3) = addHtlc(10000, alice, bob, alice2bob, bob2alice)
- val (rb1, htlcb1) = addHtlc(50000000, bob, alice, bob2alice, alice2bob)
- val (rb2, htlcb2) = addHtlc(55000000, bob, alice, bob2alice, alice2bob)
+ val (ra1, htlca1) = addHtlc(MilliSatoshi(250000000), alice, bob, alice2bob, bob2alice)
+ val (ra2, htlca2) = addHtlc(MilliSatoshi(100000000), alice, bob, alice2bob, bob2alice)
+ val (ra3, htlca3) = addHtlc(MilliSatoshi(10000), alice, bob, alice2bob, bob2alice)
+ val (rb1, htlcb1) = addHtlc(MilliSatoshi(50000000), bob, alice, bob2alice, alice2bob)
+ val (rb2, htlcb2) = addHtlc(MilliSatoshi(55000000), bob, alice, bob2alice, alice2bob)
crossSign(alice, bob, alice2bob, bob2alice)
fulfillHtlc(1, ra2, bob, alice, bob2alice, alice2bob)
fulfillHtlc(0, rb1, alice, bob, alice2bob, bob2alice)
@@ -2299,8 +2300,8 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
sender.send(alice, WatchEventConfirmed(BITCOIN_FUNDING_DEEPLYBURIED, 400000, 42, null))
val update1a = alice2bob.expectMsgType[ChannelUpdate]
assert(Announcements.isEnabled(update1a.channelFlags) == true)
- val (_, htlc1) = addHtlc(10000, alice, bob, alice2bob, bob2alice)
- val (_, htlc2) = addHtlc(10000, alice, bob, alice2bob, bob2alice)
+ val (_, htlc1) = addHtlc(MilliSatoshi(10000), alice, bob, alice2bob, bob2alice)
+ val (_, htlc2) = addHtlc(MilliSatoshi(10000), alice, bob, alice2bob, bob2alice)
val aliceData = alice.stateData.asInstanceOf[DATA_NORMAL]
assert(aliceData.commitments.localChanges.proposed.size == 2)
@@ -2343,8 +2344,8 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
val update1a = channelUpdateListener.expectMsgType[LocalChannelUpdate]
val update1b = channelUpdateListener.expectMsgType[LocalChannelUpdate]
assert(Announcements.isEnabled(update1a.channelUpdate.channelFlags) == true)
- val (_, htlc1) = addHtlc(10000, alice, bob, alice2bob, bob2alice)
- val (_, htlc2) = addHtlc(10000, alice, bob, alice2bob, bob2alice)
+ val (_, htlc1) = addHtlc(MilliSatoshi(10000), alice, bob, alice2bob, bob2alice)
+ val (_, htlc2) = addHtlc(MilliSatoshi(10000), alice, bob, alice2bob, bob2alice)
val aliceData = alice.stateData.asInstanceOf[DATA_NORMAL]
assert(aliceData.commitments.localChanges.proposed.size == 2)
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/e/OfflineStateSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/e/OfflineStateSpec.scala
index 866a3346f6..916b54c184 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/e/OfflineStateSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/e/OfflineStateSpec.scala
@@ -31,7 +31,7 @@ import fr.acinq.eclair.payment.CommandBuffer.CommandSend
import fr.acinq.eclair.router.Announcements
import fr.acinq.eclair.transactions.Transactions.HtlcSuccessTx
import fr.acinq.eclair.wire._
-import fr.acinq.eclair.{TestConstants, TestkitBaseClass, randomBytes32}
+import fr.acinq.eclair.{MilliSatoshi, TestConstants, TestkitBaseClass, randomBytes32}
import org.scalatest.Outcome
import scala.concurrent.duration._
@@ -66,7 +66,7 @@ class OfflineStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
import f._
val sender = TestProbe()
- sender.send(alice, CMD_ADD_HTLC(1000000, ByteVector32.Zeroes, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID())))
+ sender.send(alice, CMD_ADD_HTLC(MilliSatoshi(1000000), ByteVector32.Zeroes, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID())))
val ab_add_0 = alice2bob.expectMsgType[UpdateAddHtlc]
// add ->b
alice2bob.forward(bob)
@@ -143,7 +143,7 @@ class OfflineStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
import f._
val sender = TestProbe()
- sender.send(alice, CMD_ADD_HTLC(1000000, randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID())))
+ sender.send(alice, CMD_ADD_HTLC(MilliSatoshi(1000000), randomBytes32, 400144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID())))
val ab_add_0 = alice2bob.expectMsgType[UpdateAddHtlc]
// add ->b
alice2bob.forward(bob, ab_add_0)
@@ -204,11 +204,11 @@ class OfflineStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
import f._
val sender = TestProbe()
- val (ra1, htlca1) = addHtlc(250000000, alice, bob, alice2bob, bob2alice)
+ val (ra1, htlca1) = addHtlc(MilliSatoshi(250000000), alice, bob, alice2bob, bob2alice)
crossSign(alice, bob, alice2bob, bob2alice)
- val (ra2, htlca2) = addHtlc(100000000, alice, bob, alice2bob, bob2alice)
+ val (ra2, htlca2) = addHtlc(MilliSatoshi(100000000), alice, bob, alice2bob, bob2alice)
crossSign(alice, bob, alice2bob, bob2alice)
- val (ra3, htlca3) = addHtlc(10000, alice, bob, alice2bob, bob2alice)
+ val (ra3, htlca3) = addHtlc(MilliSatoshi(10000), alice, bob, alice2bob, bob2alice)
crossSign(alice, bob, alice2bob, bob2alice)
val oldStateData = alice.stateData
fulfillHtlc(htlca1.id, ra1, bob, alice, bob2alice, alice2bob)
@@ -261,7 +261,7 @@ class OfflineStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
// we start by storing the current state
val oldStateData = alice.stateData
// then we add an htlc and sign it
- addHtlc(250000000, alice, bob, alice2bob, bob2alice)
+ addHtlc(MilliSatoshi(250000000), alice, bob, alice2bob, bob2alice)
sender.send(alice, CMD_SIGN)
sender.expectMsg("ok")
alice2bob.expectMsgType[CommitSig]
@@ -347,7 +347,7 @@ class OfflineStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
channelUpdateListener.expectNoMsg(300 millis)
// we make alice update here relay fee
- sender.send(alice, CMD_UPDATE_RELAY_FEE(4200, 123456))
+ sender.send(alice, CMD_UPDATE_RELAY_FEE(MilliSatoshi(4200), 123456))
sender.expectMsg("ok")
// alice doesn't broadcast the new channel_update yet
@@ -365,7 +365,7 @@ class OfflineStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
// then alice reaches NORMAL state, and after a delay she broadcasts the channel_update
val channelUpdate = channelUpdateListener.expectMsgType[LocalChannelUpdate](20 seconds).channelUpdate
- assert(channelUpdate.feeBaseMsat === 4200)
+ assert(channelUpdate.feeBaseMsat === MilliSatoshi(4200))
assert(channelUpdate.feeProportionalMillionths === 123456)
assert(Announcements.isEnabled(channelUpdate.channelFlags))
@@ -387,7 +387,7 @@ class OfflineStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
channelUpdateListener.expectNoMsg(300 millis)
// we attempt to send a payment
- sender.send(alice, CMD_ADD_HTLC(4200, randomBytes32, 123456, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID())))
+ sender.send(alice, CMD_ADD_HTLC(MilliSatoshi(4200), randomBytes32, 123456, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID())))
val failure = sender.expectMsgType[Status.Failure]
val AddHtlcFailed(_, _, ChannelUnavailable(_), _, _, _) = failure.cause
@@ -401,7 +401,7 @@ class OfflineStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
val sender = TestProbe()
val register = TestProbe()
val commandBuffer = TestActorRef(new CommandBuffer(bob.underlyingActor.nodeParams, register.ref))
- val (r, htlc) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (r, htlc) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
crossSign(alice, bob, alice2bob, bob2alice)
val listener = TestProbe()
@@ -442,7 +442,7 @@ class OfflineStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
val sender = TestProbe()
val register = TestProbe()
val commandBuffer = TestActorRef(new CommandBuffer(bob.underlyingActor.nodeParams, register.ref))
- val (_, htlc) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (_, htlc) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
crossSign(alice, bob, alice2bob, bob2alice)
sender.send(alice, INPUT_DISCONNECTED)
@@ -452,7 +452,7 @@ class OfflineStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
// We simulate a pending failure on that HTLC.
// Even if we get close to expiring upstream we shouldn't close the channel, because we have nothing to lose.
- sender.send(commandBuffer, CommandSend(htlc.channelId, htlc.id, CMD_FAIL_HTLC(htlc.id, Right(IncorrectOrUnknownPaymentDetails(0)))))
+ sender.send(commandBuffer, CommandSend(htlc.channelId, htlc.id, CMD_FAIL_HTLC(htlc.id, Right(IncorrectOrUnknownPaymentDetails(MilliSatoshi(0))))))
sender.send(bob, CurrentBlockCount(htlc.cltvExpiry - bob.underlyingActor.nodeParams.fulfillSafetyBeforeTimeoutBlocks))
bob2blockchain.expectNoMsg(250 millis)
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/f/ShutdownStateSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/f/ShutdownStateSpec.scala
index 760efbe3f6..0ca1582caa 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/f/ShutdownStateSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/f/ShutdownStateSpec.scala
@@ -30,7 +30,7 @@ import fr.acinq.eclair.channel.states.StateTestsHelperMethods
import fr.acinq.eclair.payment._
import fr.acinq.eclair.router.Hop
import fr.acinq.eclair.wire.{CommitSig, Error, FailureMessageCodecs, PermanentChannelFailure, RevokeAndAck, Shutdown, UpdateAddHtlc, UpdateFailHtlc, UpdateFailMalformedHtlc, UpdateFee, UpdateFulfillHtlc}
-import fr.acinq.eclair.{Globals, TestConstants, TestkitBaseClass, randomBytes32}
+import fr.acinq.eclair.{Globals, MilliSatoshi, TestConstants, TestkitBaseClass, randomBytes32}
import org.scalatest.{Outcome, Tag}
import scodec.bits.ByteVector
@@ -55,7 +55,7 @@ class ShutdownStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
val sender = TestProbe()
// alice sends an HTLC to bob
val h1 = Crypto.sha256(r1)
- val amount1 = 300000000
+ val amount1 = MilliSatoshi(300000000)
val expiry1 = 400144
val cmd1 = PaymentLifecycle.buildCommand(UUID.randomUUID, amount1, expiry1, h1, Hop(null, TestConstants.Bob.nodeParams.nodeId, null) :: Nil)._1.copy(commit = false)
sender.send(alice, cmd1)
@@ -65,7 +65,7 @@ class ShutdownStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
awaitCond(bob.stateData.asInstanceOf[DATA_NORMAL].commitments.remoteChanges.proposed == htlc1 :: Nil)
// alice sends another HTLC to bob
val h2 = Crypto.sha256(r2)
- val amount2 = 200000000
+ val amount2 = MilliSatoshi(200000000)
val expiry2 = 400144
val cmd2 = PaymentLifecycle.buildCommand(UUID.randomUUID, amount2, expiry2, h2, Hop(null, TestConstants.Bob.nodeParams.nodeId, null) :: Nil)._1.copy(commit = false)
sender.send(alice, cmd2)
@@ -104,7 +104,7 @@ class ShutdownStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv CMD_ADD_HTLC") { f =>
import f._
val sender = TestProbe()
- val add = CMD_ADD_HTLC(500000000, r1, cltvExpiry = 300000, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
+ val add = CMD_ADD_HTLC(MilliSatoshi(500000000), r1, cltvExpiry = 300000, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
sender.send(alice, add)
val error = ChannelUnavailable(channelId(alice))
sender.expectMsg(Failure(AddHtlcFailed(channelId(alice), add.paymentHash, error, Local(add.upstream.left.get, Some(sender.ref)), None, Some(add))))
@@ -585,7 +585,7 @@ class ShutdownStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
bob.feeEstimator.setFeerate(FeeratesPerKw.single(fee.feeratePerKw))
sender.send(bob, fee)
val error = bob2alice.expectMsgType[Error]
- assert(new String(error.data.toArray) === CannotAffordFees(channelId(bob), missingSatoshis = 72120000L, reserveSatoshis = 20000L, feesSatoshis = 72400000L).getMessage)
+ assert(new String(error.data.toArray) === CannotAffordFees(channelId(bob), missing = Satoshi(72120000L), reserve = Satoshi(20000L), fees = Satoshi(72400000L)).getMessage)
awaitCond(bob.stateName == CLOSING)
bob2blockchain.expectMsg(PublishAsap(tx)) // commit tx
//bob2blockchain.expectMsgType[PublishAsap] // main delayed (removed because of the high fees)
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/g/NegotiatingStateSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/g/NegotiatingStateSpec.scala
index 3b798fe887..f5c5a59cd4 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/g/NegotiatingStateSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/g/NegotiatingStateSpec.scala
@@ -30,7 +30,7 @@ import fr.acinq.eclair.channel._
import fr.acinq.eclair.channel.states.StateTestsHelperMethods
import fr.acinq.eclair.payment.Local
import fr.acinq.eclair.wire.{ClosingSigned, Error, Shutdown}
-import fr.acinq.eclair.{Globals, TestConstants, TestkitBaseClass}
+import fr.acinq.eclair.{Globals, MilliSatoshi, TestConstants, TestkitBaseClass}
import org.scalatest.{Outcome, Tag}
import scodec.bits.ByteVector
@@ -85,7 +85,7 @@ class NegotiatingStateSpec extends TestkitBaseClass with StateTestsHelperMethods
import f._
alice2bob.expectMsgType[ClosingSigned]
val sender = TestProbe()
- val add = CMD_ADD_HTLC(500000000, ByteVector32(ByteVector.fill(32)(1)), cltvExpiry = 300000, onion = TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
+ val add = CMD_ADD_HTLC(MilliSatoshi(5000000000L), ByteVector32(ByteVector.fill(32)(1)), cltvExpiry = 300000, onion = TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
sender.send(alice, add)
val error = ChannelUnavailable(channelId(alice))
sender.expectMsg(Failure(AddHtlcFailed(channelId(alice), add.paymentHash, error, Local(add.upstream.left.get, Some(sender.ref)), None, Some(add))))
@@ -111,7 +111,7 @@ class NegotiatingStateSpec extends TestkitBaseClass with StateTestsHelperMethods
private def testFeeConverge(f: FixtureParam) = {
import f._
- var aliceCloseFee, bobCloseFee = 0L
+ var aliceCloseFee, bobCloseFee = Satoshi(0)
do {
aliceCloseFee = alice2bob.expectMsgType[ClosingSigned].feeSatoshis
alice2bob.forward(bob)
@@ -135,9 +135,9 @@ class NegotiatingStateSpec extends TestkitBaseClass with StateTestsHelperMethods
val aliceCloseSig = alice2bob.expectMsgType[ClosingSigned]
val sender = TestProbe()
val tx = bob.stateData.asInstanceOf[DATA_NEGOTIATING].commitments.localCommit.publishableTxs.commitTx.tx
- sender.send(bob, aliceCloseSig.copy(feeSatoshis = 99000)) // sig doesn't matter, it is checked later
+ sender.send(bob, aliceCloseSig.copy(feeSatoshis = Satoshi(99000))) // sig doesn't matter, it is checked later
val error = bob2alice.expectMsgType[Error]
- assert(new String(error.data.toArray).startsWith("invalid close fee: fee_satoshis=99000"))
+ assert(new String(error.data.toArray).startsWith("invalid close fee: fee_satoshis=Satoshi(99000)"))
bob2blockchain.expectMsg(PublishAsap(tx))
bob2blockchain.expectMsgType[PublishAsap]
bob2blockchain.expectMsgType[WatchConfirmed]
@@ -158,7 +158,7 @@ class NegotiatingStateSpec extends TestkitBaseClass with StateTestsHelperMethods
test("recv BITCOIN_FUNDING_SPENT (counterparty's mutual close)") { f =>
import f._
- var aliceCloseFee, bobCloseFee = 0L
+ var aliceCloseFee, bobCloseFee = Satoshi(0)
do {
aliceCloseFee = alice2bob.expectMsgType[ClosingSigned].feeSatoshis
alice2bob.forward(bob)
@@ -193,7 +193,7 @@ class NegotiatingStateSpec extends TestkitBaseClass with StateTestsHelperMethods
// at this point alice and bob have not yet converged on closing fees, but bob decides to publish a mutual close with one of the previous sigs
val d = bob.stateData.asInstanceOf[DATA_NEGOTIATING]
implicit val log: LoggingAdapter = bob.underlyingActor.implicitLog
- val Success(bobClosingTx) = Closing.checkClosingSignature(Bob.keyManager, d.commitments, d.localShutdown.scriptPubKey, d.remoteShutdown.scriptPubKey, Satoshi(aliceClose1.feeSatoshis), aliceClose1.signature)
+ val Success(bobClosingTx) = Closing.checkClosingSignature(Bob.keyManager, d.commitments, d.localShutdown.scriptPubKey, d.remoteShutdown.scriptPubKey, aliceClose1.feeSatoshis, aliceClose1.signature)
alice ! WatchEventSpent(BITCOIN_FUNDING_SPENT, bobClosingTx)
alice2blockchain.expectMsgType[PublishAsap]
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/h/ClosingStateSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/h/ClosingStateSpec.scala
index b4715a7110..8cff5d868f 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/h/ClosingStateSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/h/ClosingStateSpec.scala
@@ -22,7 +22,7 @@ import akka.actor.Status
import akka.actor.Status.Failure
import akka.testkit.{TestFSMRef, TestProbe}
import com.typesafe.sslconfig.util.NoopLogger
-import fr.acinq.bitcoin.{ByteVector32, OutPoint, ScriptFlags, Transaction, TxIn}
+import fr.acinq.bitcoin.{ByteVector32, OutPoint, Satoshi, ScriptFlags, Transaction, TxIn}
import fr.acinq.eclair.TestConstants.{Alice, Bob, TestFeeEstimator}
import fr.acinq.eclair.blockchain._
import fr.acinq.eclair.blockchain.fee.FeeratesPerKw
@@ -33,7 +33,7 @@ import fr.acinq.eclair.channel.{Data, State, _}
import fr.acinq.eclair.payment._
import fr.acinq.eclair.transactions.{Scripts, Transactions}
import fr.acinq.eclair.wire._
-import fr.acinq.eclair.{Globals, TestConstants, TestkitBaseClass, randomBytes32}
+import fr.acinq.eclair.{Globals, MilliSatoshi, TestConstants, TestkitBaseClass, randomBytes32}
import org.scalatest.{Outcome, Tag}
import scodec.bits.ByteVector
@@ -89,7 +89,7 @@ class ClosingStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
within(30 seconds) {
reachNormal(setup)
val bobCommitTxes: List[PublishableTxs] = (for (amt <- List(100000000, 200000000, 300000000)) yield {
- val (r, htlc) = addHtlc(amt, alice, bob, alice2bob, bob2alice)
+ val (r, htlc) = addHtlc(MilliSatoshi(amt), alice, bob, alice2bob, bob2alice)
crossSign(alice, bob, alice2bob, bob2alice)
relayerB.expectMsgType[ForwardAdd]
val bobCommitTx1 = bob.stateData.asInstanceOf[DATA_NORMAL].commitments.localCommit.publishableTxs
@@ -124,7 +124,7 @@ class ClosingStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
bob2alice.expectMsgType[Shutdown]
bob2alice.forward(alice)
// agreeing on a closing fee
- var aliceCloseFee, bobCloseFee = 0L
+ var aliceCloseFee, bobCloseFee = Satoshi(0)
do {
aliceCloseFee = alice2bob.expectMsgType[ClosingSigned].feeSatoshis
alice2bob.forward(bob)
@@ -157,7 +157,7 @@ class ClosingStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
val mutualClosingFeeRate = alice.feeEstimator.getFeeratePerKw(alice.feeTargets.mutualCloseBlockTarget)
val expectedFirstProposedFee = Closing.firstClosingFee(aliceData.commitments, aliceData.localShutdown.scriptPubKey, aliceData.remoteShutdown.scriptPubKey, mutualClosingFeeRate)(akka.event.NoLogging)
assert(alice.feeTargets.mutualCloseBlockTarget == 2 && mutualClosingFeeRate == 250)
- assert(closing.feeSatoshis == expectedFirstProposedFee.amount)
+ assert(closing.feeSatoshis == expectedFirstProposedFee)
}
test("recv BITCOIN_FUNDING_PUBLISH_FAILED", Tag("funding_unconfirmed")) { f =>
@@ -301,7 +301,7 @@ class ClosingStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
// actual test starts here
val sender = TestProbe()
- val add = CMD_ADD_HTLC(500000000, ByteVector32(ByteVector.fill(32)(1)), cltvExpiry = 300000, onion = TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
+ val add = CMD_ADD_HTLC(MilliSatoshi(500000000), ByteVector32(ByteVector.fill(32)(1)), cltvExpiry = 300000, onion = TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
sender.send(alice, add)
val error = ChannelUnavailable(channelId(alice))
sender.expectMsg(Failure(AddHtlcFailed(channelId(alice), add.paymentHash, error, Local(add.upstream.left.get, Some(sender.ref)), None, Some(add))))
@@ -380,7 +380,7 @@ class ClosingStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("recv BITCOIN_OUTPUT_SPENT") { f =>
import f._
// alice sends an htlc to bob
- val (ra1, htlca1) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (ra1, htlca1) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
crossSign(alice, bob, alice2bob, bob2alice)
relayerB.expectMsgType[ForwardAdd]
// an error occurs and alice publishes her commit tx
@@ -420,7 +420,7 @@ class ClosingStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
system.eventStream.subscribe(listener.ref, classOf[LocalCommitConfirmed])
system.eventStream.subscribe(listener.ref, classOf[PaymentSettlingOnChain])
// alice sends an htlc to bob
- val (ra1, htlca1) = addHtlc(50000000, alice, bob, alice2bob, bob2alice)
+ val (ra1, htlca1) = addHtlc(MilliSatoshi(50000000), alice, bob, alice2bob, bob2alice)
crossSign(alice, bob, alice2bob, bob2alice)
// an error occurs and alice publishes her commit tx
val aliceCommitTx = alice.stateData.asInstanceOf[DATA_NORMAL].commitments.localCommit.publishableTxs.commitTx.tx
@@ -454,7 +454,7 @@ class ClosingStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
system.eventStream.subscribe(listener.ref, classOf[PaymentSettlingOnChain])
val aliceCommitTx = alice.stateData.asInstanceOf[DATA_NORMAL].commitments.localCommit.publishableTxs.commitTx.tx
// alice sends an htlc
- val (r, htlc) = addHtlc(4200000, alice, bob, alice2bob, bob2alice)
+ val (r, htlc) = addHtlc(MilliSatoshi(4200000), alice, bob, alice2bob, bob2alice)
// and signs it (but bob doesn't sign it)
sender.send(alice, CMD_SIGN)
sender.expectMsg("ok")
@@ -485,7 +485,7 @@ class ClosingStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
system.eventStream.subscribe(listener.ref, classOf[PaymentSettlingOnChain])
val bobCommitTx = bob.stateData.asInstanceOf[DATA_NORMAL].commitments.localCommit.publishableTxs.commitTx.tx
// alice sends an htlc
- val (r, htlc) = addHtlc(4200000, alice, bob, alice2bob, bob2alice)
+ val (r, htlc) = addHtlc(MilliSatoshi(4200000), alice, bob, alice2bob, bob2alice)
// and signs it (but bob doesn't sign it)
sender.send(alice, CMD_SIGN)
sender.expectMsg("ok")
@@ -546,7 +546,7 @@ class ClosingStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
import f._
val sender = TestProbe()
val oldStateData = alice.stateData
- val (ra1, htlca1) = addHtlc(25000000, alice, bob, alice2bob, bob2alice)
+ val (ra1, htlca1) = addHtlc(MilliSatoshi(25000000), alice, bob, alice2bob, bob2alice)
crossSign(alice, bob, alice2bob, bob2alice)
fulfillHtlc(htlca1.id, ra1, bob, alice, bob2alice, alice2bob)
crossSign(bob, alice, bob2alice, alice2bob)
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/db/SqliteAuditDbSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/db/SqliteAuditDbSpec.scala
index 282841c3cc..8892bf3adc 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/db/SqliteAuditDbSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/db/SqliteAuditDbSpec.scala
@@ -18,14 +18,14 @@ package fr.acinq.eclair.db
import java.util.UUID
-import fr.acinq.bitcoin.{MilliSatoshi, Satoshi, Transaction}
+import fr.acinq.bitcoin.{Satoshi, Transaction}
import fr.acinq.eclair.channel.Channel.{LocalError, RemoteError}
import fr.acinq.eclair.channel.{AvailableBalanceChanged, ChannelErrorOccured, NetworkFeePaid}
import fr.acinq.eclair.db.sqlite.SqliteAuditDb
import fr.acinq.eclair.db.sqlite.SqliteUtils.{getVersion, using}
-import fr.acinq.eclair.payment.{PaymentReceived, PaymentRelayed, PaymentSent}
import fr.acinq.eclair.wire.{ChannelCodecs, ChannelCodecsSpec}
import fr.acinq.eclair._
+import fr.acinq.eclair.payment.{PaymentReceived, PaymentRelayed, PaymentSent}
import org.scalatest.FunSuite
import concurrent.duration._
@@ -50,8 +50,8 @@ class SqliteAuditDbSpec extends FunSuite {
val e4 = NetworkFeePaid(null, randomKey.publicKey, randomBytes32, Transaction(0, Seq.empty, Seq.empty, 0), Satoshi(42), "mutual")
val e5 = PaymentSent(ChannelCodecs.UNKNOWN_UUID, MilliSatoshi(42000), MilliSatoshi(1000), randomBytes32, randomBytes32, randomBytes32, timestamp = 0)
val e6 = PaymentSent(ChannelCodecs.UNKNOWN_UUID, MilliSatoshi(42000), MilliSatoshi(1000), randomBytes32, randomBytes32, randomBytes32, timestamp = (Platform.currentTime.milliseconds + 10.minutes).toMillis)
- val e7 = AvailableBalanceChanged(null, randomBytes32, ShortChannelId(500000, 42, 1), 456123000, ChannelCodecsSpec.commitments)
- val e8 = ChannelLifecycleEvent(randomBytes32, randomKey.publicKey, 456123000, true, false, "mutual")
+ val e7 = AvailableBalanceChanged(null, randomBytes32, ShortChannelId(500000, 42, 1), MilliSatoshi(456123000), ChannelCodecsSpec.commitments)
+ val e8 = ChannelLifecycleEvent(randomBytes32, randomKey.publicKey, Satoshi(456123000), true, false, "mutual")
val e9 = ChannelErrorOccured(null, randomBytes32, randomKey.publicKey, null, LocalError(new RuntimeException("oops")), true)
val e10 = ChannelErrorOccured(null, randomBytes32, randomKey.publicKey, null, RemoteError(wire.Error(randomBytes32, "remote oops")), true)
@@ -97,9 +97,9 @@ class SqliteAuditDbSpec extends FunSuite {
db.add(NetworkFeePaid(null, n3, c3, Transaction(0, Seq.empty, Seq.empty, 0), Satoshi(400), "funding"))
assert(db.stats.toSet === Set(
- Stats(channelId = c1, avgPaymentAmountSatoshi = 42, paymentCount = 3, relayFeeSatoshi = 4, networkFeeSatoshi = 100),
- Stats(channelId = c2, avgPaymentAmountSatoshi = 40, paymentCount = 1, relayFeeSatoshi = 2, networkFeeSatoshi = 500),
- Stats(channelId = c3, avgPaymentAmountSatoshi = 0, paymentCount = 0, relayFeeSatoshi = 0, networkFeeSatoshi = 400)
+ Stats(channelId = c1, avgPaymentAmount = Satoshi(42), paymentCount = 3, relayFee = Satoshi(4), networkFee = Satoshi(100)),
+ Stats(channelId = c2, avgPaymentAmount = Satoshi(40), paymentCount = 1, relayFee = Satoshi(2), networkFee = Satoshi(500)),
+ Stats(channelId = c3, avgPaymentAmount = Satoshi(0), paymentCount = 0, relayFee = Satoshi(0), networkFee = Satoshi(400))
))
}
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/db/SqliteNetworkDbSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/db/SqliteNetworkDbSpec.scala
index 201cff789a..a721c4d557 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/db/SqliteNetworkDbSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/db/SqliteNetworkDbSpec.scala
@@ -20,7 +20,7 @@ import fr.acinq.bitcoin.{Block, Crypto, Satoshi}
import fr.acinq.eclair.db.sqlite.SqliteNetworkDb
import fr.acinq.eclair.router.Announcements
import fr.acinq.eclair.wire.{Color, NodeAddress, Tor2}
-import fr.acinq.eclair.{ShortChannelId, TestConstants, randomBytes32, randomKey}
+import fr.acinq.eclair.{MilliSatoshi, ShortChannelId, TestConstants, randomBytes32, randomKey}
import org.scalatest.FunSuite
import org.sqlite.SQLiteException
@@ -85,9 +85,9 @@ class SqliteNetworkDbSpec extends FunSuite {
db.removeChannel(channel_2.shortChannelId)
assert(db.listChannels().toSet === Set((channel_1, (txid_1, capacity)), (channel_3, (txid_3, capacity))))
- val channel_update_1 = Announcements.makeChannelUpdate(Block.RegtestGenesisBlock.hash, randomKey, randomKey.publicKey, ShortChannelId(42), 5, 7000000, 50000, 100, 500000000L, true)
- val channel_update_2 = Announcements.makeChannelUpdate(Block.RegtestGenesisBlock.hash, randomKey, randomKey.publicKey, ShortChannelId(43), 5, 7000000, 50000, 100, 500000000L, true)
- val channel_update_3 = Announcements.makeChannelUpdate(Block.RegtestGenesisBlock.hash, randomKey, randomKey.publicKey, ShortChannelId(44), 5, 7000000, 50000, 100, 500000000L, true)
+ val channel_update_1 = Announcements.makeChannelUpdate(Block.RegtestGenesisBlock.hash, randomKey, randomKey.publicKey, ShortChannelId(42), 5, MilliSatoshi(7000000), MilliSatoshi(50000), 100, MilliSatoshi(500000000L), true)
+ val channel_update_2 = Announcements.makeChannelUpdate(Block.RegtestGenesisBlock.hash, randomKey, randomKey.publicKey, ShortChannelId(43), 5, MilliSatoshi(7000000), MilliSatoshi(50000), 100, MilliSatoshi(500000000L), true)
+ val channel_update_3 = Announcements.makeChannelUpdate(Block.RegtestGenesisBlock.hash, randomKey, randomKey.publicKey, ShortChannelId(44), 5, MilliSatoshi(7000000), MilliSatoshi(50000), 100, MilliSatoshi(500000000L), true)
assert(db.listChannelUpdates().toSet === Set.empty)
db.addChannelUpdate(channel_update_1)
@@ -110,7 +110,7 @@ class SqliteNetworkDbSpec extends FunSuite {
val capacity = Satoshi(10000)
val channels = shortChannelIds.map(id => Announcements.makeChannelAnnouncement(Block.RegtestGenesisBlock.hash, id, pub, pub, pub, pub, sig, sig, sig, sig))
- val template = Announcements.makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv, pub, ShortChannelId(42), 5, 7000000, 50000, 100, 500000000L, true)
+ val template = Announcements.makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv, pub, ShortChannelId(42), 5, MilliSatoshi(7000000), MilliSatoshi(50000), 100, MilliSatoshi(500000000L), true)
val updates = shortChannelIds.map(id => template.copy(shortChannelId = id))
val txid = randomBytes32
channels.foreach(ca => db.addChannel(ca, txid, capacity))
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/db/SqlitePaymentsDbSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/db/SqlitePaymentsDbSpec.scala
index b8eec4b784..86abf94cf0 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/db/SqlitePaymentsDbSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/db/SqlitePaymentsDbSpec.scala
@@ -17,17 +17,19 @@
package fr.acinq.eclair.db
import java.util.UUID
+
import fr.acinq.eclair.db.sqlite.SqliteUtils._
-import fr.acinq.bitcoin.{Block, ByteVector32, MilliSatoshi}
+import fr.acinq.bitcoin.{Block, ByteVector32}
import fr.acinq.eclair.TestConstants.Bob
-import fr.acinq.eclair.{TestConstants, payment}
+import fr.acinq.eclair.{MilliSatoshi, TestConstants, payment, randomBytes32}
import fr.acinq.eclair.db.sqlite.SqlitePaymentsDb
import fr.acinq.eclair.payment.PaymentRequest
import org.scalatest.FunSuite
import scodec.bits._
-import fr.acinq.eclair.randomBytes32
+
import scala.compat.Platform
import OutgoingPaymentStatus._
+
import concurrent.duration._
class SqlitePaymentsDbSpec extends FunSuite {
@@ -51,12 +53,12 @@ class SqlitePaymentsDbSpec extends FunSuite {
assert(getVersion(statement, "payments", 1) == 1) // version 1 is deployed now
}
- val oldReceivedPayment = IncomingPayment(ByteVector32(hex"0f059ef9b55bb70cc09069ee4df854bf0fab650eee6f2b87ba26d1ad08ab114f"), 123, 1233322)
+ val oldReceivedPayment = IncomingPayment(ByteVector32(hex"0f059ef9b55bb70cc09069ee4df854bf0fab650eee6f2b87ba26d1ad08ab114f"), MilliSatoshi(123), 1233322)
// insert old type record
using(connection.prepareStatement("INSERT INTO payments VALUES (?, ?, ?)")) { statement =>
statement.setBytes(1, oldReceivedPayment.paymentHash.toArray)
- statement.setLong(2, oldReceivedPayment.amountMsat)
+ statement.setLong(2, oldReceivedPayment.amount.toLong)
statement.setLong(3, oldReceivedPayment.receivedAt)
statement.executeUpdate()
}
@@ -71,9 +73,9 @@ class SqlitePaymentsDbSpec extends FunSuite {
assert(preMigrationDb.getIncomingPayment(oldReceivedPayment.paymentHash).isEmpty)
// add a few rows
- val ps1 = OutgoingPayment(id = UUID.randomUUID(), paymentHash = ByteVector32(hex"0f059ef9b55bb70cc09069ee4df854bf0fab650eee6f2b87ba26d1ad08ab114f"), None, amountMsat = 12345, createdAt = 12345, None, PENDING)
+ val ps1 = OutgoingPayment(id = UUID.randomUUID(), paymentHash = ByteVector32(hex"0f059ef9b55bb70cc09069ee4df854bf0fab650eee6f2b87ba26d1ad08ab114f"), None, amount = MilliSatoshi(12345), createdAt = 12345, None, PENDING)
val i1 = PaymentRequest.read("lnbc10u1pw2t4phpp5ezwm2gdccydhnphfyepklc0wjkxhz0r4tctg9paunh2lxgeqhcmsdqlxycrqvpqwdshgueqvfjhggr0dcsry7qcqzpgfa4ecv7447p9t5hkujy9qgrxvkkf396p9zar9p87rv2htmeuunkhydl40r64n5s2k0u7uelzc8twxmp37nkcch6m0wg5tvvx69yjz8qpk94qf3")
- val pr1 = IncomingPayment(i1.paymentHash, 12345678, 1513871928275L)
+ val pr1 = IncomingPayment(i1.paymentHash, MilliSatoshi(12345678), 1513871928275L)
preMigrationDb.addPaymentRequest(i1, ByteVector32.Zeroes)
preMigrationDb.addIncomingPayment(pr1)
@@ -99,7 +101,7 @@ class SqlitePaymentsDbSpec extends FunSuite {
val db = new SqlitePaymentsDb(sqlite)
// can't receive a payment without an invoice associated with it
- assertThrows[IllegalArgumentException](db.addIncomingPayment(IncomingPayment(ByteVector32(hex"6e7e8018f05e169cf1d99e77dc22cb372d09f10b6a81f1eae410718c56cad188"), 12345678, 1513871928275L)))
+ assertThrows[IllegalArgumentException](db.addIncomingPayment(IncomingPayment(ByteVector32(hex"6e7e8018f05e169cf1d99e77dc22cb372d09f10b6a81f1eae410718c56cad188"), MilliSatoshi(12345678), 1513871928275L)))
val i1 = PaymentRequest.read("lnbc5450n1pw2t4qdpp5vcrf6ylgpettyng4ac3vujsk0zpc25cj0q3zp7l7w44zvxmpzh8qdzz2pshjmt9de6zqen0wgsr2dp4ypcxj7r9d3ejqct5ypekzar0wd5xjuewwpkxzcm99cxqzjccqp2rzjqtspxelp67qc5l56p6999wkatsexzhs826xmupyhk6j8lxl038t27z9tsqqqgpgqqqqqqqlgqqqqqzsqpcz8z8hmy8g3ecunle4n3edn3zg2rly8g4klsk5md736vaqqy3ktxs30ht34rkfkqaffzxmjphvd0637dk2lp6skah2hq09z6lrjna3xqp3d4vyd")
val i2 = PaymentRequest.read("lnbc10u1pw2t4phpp5ezwm2gdccydhnphfyepklc0wjkxhz0r4tctg9paunh2lxgeqhcmsdqlxycrqvpqwdshgueqvfjhggr0dcsry7qcqzpgfa4ecv7447p9t5hkujy9qgrxvkkf396p9zar9p87rv2htmeuunkhydl40r64n5s2k0u7uelzc8twxmp37nkcch6m0wg5tvvx69yjz8qpk94qf3")
@@ -107,8 +109,8 @@ class SqlitePaymentsDbSpec extends FunSuite {
db.addPaymentRequest(i1, ByteVector32.Zeroes)
db.addPaymentRequest(i2, ByteVector32.Zeroes)
- val p1 = IncomingPayment(i1.paymentHash, 12345678, 1513871928275L)
- val p2 = IncomingPayment(i2.paymentHash, 12345678, 1513871928275L)
+ val p1 = IncomingPayment(i1.paymentHash, MilliSatoshi(12345678), 1513871928275L)
+ val p2 = IncomingPayment(i2.paymentHash, MilliSatoshi(12345678), 1513871928275L)
assert(db.listIncomingPayments() === Nil)
db.addIncomingPayment(p1)
db.addIncomingPayment(p2)
@@ -121,8 +123,8 @@ class SqlitePaymentsDbSpec extends FunSuite {
val db = new SqlitePaymentsDb(TestConstants.sqliteInMemory())
- val s1 = OutgoingPayment(id = UUID.randomUUID(), paymentHash = ByteVector32(hex"0f059ef9b55bb70cc09069ee4df854bf0fab650eee6f2b87ba26d1ad08ab114f"), None, amountMsat = 12345, createdAt = 12345, None, PENDING)
- val s2 = OutgoingPayment(id = UUID.randomUUID(), paymentHash = ByteVector32(hex"08d47d5f7164d4b696e8f6b62a03094d4f1c65f16e9d7b11c4a98854707e55cf"), None, amountMsat = 12345, createdAt = 12345, None, PENDING)
+ val s1 = OutgoingPayment(id = UUID.randomUUID(), paymentHash = ByteVector32(hex"0f059ef9b55bb70cc09069ee4df854bf0fab650eee6f2b87ba26d1ad08ab114f"), None, amount = MilliSatoshi(12345), createdAt = 12345, None, PENDING)
+ val s2 = OutgoingPayment(id = UUID.randomUUID(), paymentHash = ByteVector32(hex"08d47d5f7164d4b696e8f6b62a03094d4f1c65f16e9d7b11c4a98854707e55cf"), None, amount = MilliSatoshi(12345), createdAt = 12345, None, PENDING)
assert(db.listOutgoingPayments().isEmpty)
db.addOutgoingPayment(s1)
@@ -135,7 +137,7 @@ class SqlitePaymentsDbSpec extends FunSuite {
assert(db.getOutgoingPayments(s2.paymentHash) === Seq(s2))
assert(db.getOutgoingPayments(ByteVector32.Zeroes) === Seq.empty)
- val s3 = s2.copy(id = UUID.randomUUID(), amountMsat = 88776655)
+ val s3 = s2.copy(id = UUID.randomUUID(), amount = MilliSatoshi(88776655))
db.addOutgoingPayment(s3)
db.updateOutgoingPayment(s3.id, FAILED)
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/integration/IntegrationSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/integration/IntegrationSpec.scala
index 8b2c2e79da..0f9857d006 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/integration/IntegrationSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/integration/IntegrationSpec.scala
@@ -24,13 +24,14 @@ import akka.testkit.{TestKit, TestProbe}
import com.google.common.net.HostAndPort
import com.typesafe.config.{Config, ConfigFactory}
import fr.acinq.bitcoin.Crypto.PrivateKey
-import fr.acinq.bitcoin.{Base58, Base58Check, Bech32, Block, ByteVector32, Crypto, MilliSatoshi, OP_0, OP_CHECKSIG, OP_DUP, OP_EQUAL, OP_EQUALVERIFY, OP_HASH160, OP_PUSHDATA, Satoshi, Script, ScriptFlags, Transaction}
+import fr.acinq.bitcoin.{Base58, Base58Check, Bech32, Block, ByteVector32, Crypto, OP_0, OP_CHECKSIG, OP_DUP, OP_EQUAL, OP_EQUALVERIFY, OP_HASH160, OP_PUSHDATA, Satoshi, Script, ScriptFlags, Transaction}
import fr.acinq.eclair.blockchain.bitcoind.BitcoindService
import fr.acinq.eclair.blockchain.bitcoind.rpc.ExtendedBitcoinClient
import fr.acinq.eclair.blockchain.{Watch, WatchConfirmed}
import fr.acinq.eclair.channel.Channel.{BroadcastChannelUpdate, PeriodicRefresh}
import fr.acinq.eclair.channel.Register.{Forward, ForwardShortId}
import fr.acinq.eclair.channel._
+import fr.acinq.eclair._
import fr.acinq.eclair.crypto.Sphinx.DecryptedFailurePacket
import fr.acinq.eclair.io.Peer.{Disconnect, PeerRoutingMessage}
import fr.acinq.eclair.io.{NodeURI, Peer}
@@ -65,7 +66,7 @@ class IntegrationSpec extends TestKit(ActorSystem("test")) with BitcoindService
// we override the default because these test were designed to use cost-optimized routes
val integrationTestRouteParams = Some(RouteParams(
randomize = false,
- maxFeeBaseMsat = Long.MaxValue,
+ maxFeeBase = MilliSatoshi(Long.MaxValue),
maxFeePct = Double.MaxValue,
routeMaxCltv = Int.MaxValue,
routeMaxLength = ROUTE_MAX_LENGTH,
@@ -263,7 +264,7 @@ class IntegrationSpec extends TestKit(ActorSystem("test")) with BitcoindService
val pr = sender.expectMsgType[PaymentRequest]
// then we make the actual payment
sender.send(nodes("A").paymentInitiator,
- SendPayment(amountMsat.amount, pr.paymentHash, nodes("D").nodeParams.nodeId, routeParams = integrationTestRouteParams, maxAttempts = 1))
+ SendPayment(amountMsat, pr.paymentHash, nodes("D").nodeParams.nodeId, routeParams = integrationTestRouteParams, maxAttempts = 1))
val paymentId = sender.expectMsgType[UUID](5 seconds)
val ps = sender.expectMsgType[PaymentSucceeded](5 seconds)
assert(ps.id == paymentId)
@@ -279,7 +280,7 @@ class IntegrationSpec extends TestKit(ActorSystem("test")) with BitcoindService
sender.send(nodes("B").register, ForwardShortId(shortIdBC, CMD_GETINFO))
val commitmentBC = sender.expectMsgType[RES_GETINFO].data.asInstanceOf[DATA_NORMAL].commitments
// we then forge a new channel_update for B-C...
- val channelUpdateBC = Announcements.makeChannelUpdate(Block.RegtestGenesisBlock.hash, nodes("B").nodeParams.privateKey, nodes("C").nodeParams.nodeId, shortIdBC, nodes("B").nodeParams.expiryDeltaBlocks + 1, nodes("C").nodeParams.htlcMinimumMsat, nodes("B").nodeParams.feeBaseMsat, nodes("B").nodeParams.feeProportionalMillionth, 500000000L)
+ val channelUpdateBC = Announcements.makeChannelUpdate(Block.RegtestGenesisBlock.hash, nodes("B").nodeParams.privateKey, nodes("C").nodeParams.nodeId, shortIdBC, nodes("B").nodeParams.expiryDeltaBlocks + 1, nodes("C").nodeParams.htlcMinimum, nodes("B").nodeParams.feeBase, nodes("B").nodeParams.feeProportionalMillionth, MilliSatoshi(500000000L))
// ...and notify B's relayer
sender.send(nodes("B").relayer, LocalChannelUpdate(system.deadLetters, commitmentBC.channelId, shortIdBC, commitmentBC.remoteParams.nodeId, None, channelUpdateBC, commitmentBC))
// we retrieve a payment hash from D
@@ -287,7 +288,7 @@ class IntegrationSpec extends TestKit(ActorSystem("test")) with BitcoindService
sender.send(nodes("D").paymentHandler, ReceivePayment(Some(amountMsat), "1 coffee"))
val pr = sender.expectMsgType[PaymentRequest]
// then we make the actual payment, do not randomize the route to make sure we route through node B
- val sendReq = SendPayment(amountMsat.amount, pr.paymentHash, nodes("D").nodeParams.nodeId, routeParams = integrationTestRouteParams, maxAttempts = 5)
+ val sendReq = SendPayment(amountMsat, pr.paymentHash, nodes("D").nodeParams.nodeId, routeParams = integrationTestRouteParams, maxAttempts = 5)
sender.send(nodes("A").paymentInitiator, sendReq)
// A will receive an error from B that include the updated channel update, then will retry the payment
val paymentId = sender.expectMsgType[UUID](5 seconds)
@@ -325,7 +326,7 @@ class IntegrationSpec extends TestKit(ActorSystem("test")) with BitcoindService
sender.send(nodes("D").paymentHandler, ReceivePayment(Some(amountMsat), "1 coffee"))
val pr = sender.expectMsgType[PaymentRequest]
// then we make the payment (B-C has a smaller capacity than A-B and C-D)
- val sendReq = SendPayment(amountMsat.amount, pr.paymentHash, nodes("D").nodeParams.nodeId, routeParams = integrationTestRouteParams, maxAttempts = 5)
+ val sendReq = SendPayment(amountMsat, pr.paymentHash, nodes("D").nodeParams.nodeId, routeParams = integrationTestRouteParams, maxAttempts = 5)
sender.send(nodes("A").paymentInitiator, sendReq)
// A will first receive an error from C, then retry and route around C: A->B->E->C->D
sender.expectMsgType[UUID](5 seconds)
@@ -334,7 +335,7 @@ class IntegrationSpec extends TestKit(ActorSystem("test")) with BitcoindService
test("send an HTLC A->D with an unknown payment hash") {
val sender = TestProbe()
- val pr = SendPayment(100000000L, randomBytes32, nodes("D").nodeParams.nodeId, routeParams = integrationTestRouteParams, maxAttempts = 5)
+ val pr = SendPayment(MilliSatoshi(100000000L), randomBytes32, nodes("D").nodeParams.nodeId, routeParams = integrationTestRouteParams, maxAttempts = 5)
sender.send(nodes("A").paymentInitiator, pr)
// A will receive an error from D and won't retry
@@ -343,7 +344,7 @@ class IntegrationSpec extends TestKit(ActorSystem("test")) with BitcoindService
assert(failed.id == paymentId)
assert(failed.paymentHash === pr.paymentHash)
assert(failed.failures.size === 1)
- assert(failed.failures.head.asInstanceOf[RemoteFailure].e === DecryptedFailurePacket(nodes("D").nodeParams.nodeId, IncorrectOrUnknownPaymentDetails(100000000L)))
+ assert(failed.failures.head.asInstanceOf[RemoteFailure].e === DecryptedFailurePacket(nodes("D").nodeParams.nodeId, IncorrectOrUnknownPaymentDetails(MilliSatoshi(100000000L))))
}
test("send an HTLC A->D with a lower amount than requested") {
@@ -354,7 +355,7 @@ class IntegrationSpec extends TestKit(ActorSystem("test")) with BitcoindService
val pr = sender.expectMsgType[PaymentRequest]
// A send payment of only 1 mBTC
- val sendReq = SendPayment(100000000L, pr.paymentHash, nodes("D").nodeParams.nodeId, routeParams = integrationTestRouteParams, maxAttempts = 5)
+ val sendReq = SendPayment(MilliSatoshi(100000000L), pr.paymentHash, nodes("D").nodeParams.nodeId, routeParams = integrationTestRouteParams, maxAttempts = 5)
sender.send(nodes("A").paymentInitiator, sendReq)
// A will first receive an IncorrectPaymentAmount error from D
@@ -363,7 +364,7 @@ class IntegrationSpec extends TestKit(ActorSystem("test")) with BitcoindService
assert(failed.id == paymentId)
assert(failed.paymentHash === pr.paymentHash)
assert(failed.failures.size === 1)
- assert(failed.failures.head.asInstanceOf[RemoteFailure].e === DecryptedFailurePacket(nodes("D").nodeParams.nodeId, IncorrectOrUnknownPaymentDetails(100000000L)))
+ assert(failed.failures.head.asInstanceOf[RemoteFailure].e === DecryptedFailurePacket(nodes("D").nodeParams.nodeId, IncorrectOrUnknownPaymentDetails(MilliSatoshi(100000000L))))
}
test("send an HTLC A->D with too much overpayment") {
@@ -374,7 +375,7 @@ class IntegrationSpec extends TestKit(ActorSystem("test")) with BitcoindService
val pr = sender.expectMsgType[PaymentRequest]
// A send payment of 6 mBTC
- val sendReq = SendPayment(600000000L, pr.paymentHash, nodes("D").nodeParams.nodeId, routeParams = integrationTestRouteParams, maxAttempts = 5)
+ val sendReq = SendPayment(MilliSatoshi(600000000L), pr.paymentHash, nodes("D").nodeParams.nodeId, routeParams = integrationTestRouteParams, maxAttempts = 5)
sender.send(nodes("A").paymentInitiator, sendReq)
// A will first receive an IncorrectPaymentAmount error from D
@@ -383,7 +384,7 @@ class IntegrationSpec extends TestKit(ActorSystem("test")) with BitcoindService
assert(paymentId == failed.id)
assert(failed.paymentHash === pr.paymentHash)
assert(failed.failures.size === 1)
- assert(failed.failures.head.asInstanceOf[RemoteFailure].e === DecryptedFailurePacket(nodes("D").nodeParams.nodeId, IncorrectOrUnknownPaymentDetails(600000000L)))
+ assert(failed.failures.head.asInstanceOf[RemoteFailure].e === DecryptedFailurePacket(nodes("D").nodeParams.nodeId, IncorrectOrUnknownPaymentDetails(MilliSatoshi(600000000L))))
}
test("send an HTLC A->D with a reasonable overpayment") {
@@ -394,7 +395,7 @@ class IntegrationSpec extends TestKit(ActorSystem("test")) with BitcoindService
val pr = sender.expectMsgType[PaymentRequest]
// A send payment of 3 mBTC, more than asked but it should still be accepted
- val sendReq = SendPayment(300000000L, pr.paymentHash, nodes("D").nodeParams.nodeId, routeParams = integrationTestRouteParams, maxAttempts = 5)
+ val sendReq = SendPayment(MilliSatoshi(300000000L), pr.paymentHash, nodes("D").nodeParams.nodeId, routeParams = integrationTestRouteParams, maxAttempts = 5)
sender.send(nodes("A").paymentInitiator, sendReq)
sender.expectMsgType[UUID]
}
@@ -407,7 +408,7 @@ class IntegrationSpec extends TestKit(ActorSystem("test")) with BitcoindService
sender.send(nodes("D").paymentHandler, ReceivePayment(Some(amountMsat), "1 payment"))
val pr = sender.expectMsgType[PaymentRequest]
- val sendReq = SendPayment(amountMsat.amount, pr.paymentHash, nodes("D").nodeParams.nodeId, routeParams = integrationTestRouteParams, maxAttempts = 5)
+ val sendReq = SendPayment(amountMsat, pr.paymentHash, nodes("D").nodeParams.nodeId, routeParams = integrationTestRouteParams, maxAttempts = 5)
sender.send(nodes("A").paymentInitiator, sendReq)
sender.expectMsgType[UUID]
sender.expectMsgType[PaymentSucceeded] // the payment FSM will also reply to the sender after the payment is completed
@@ -423,7 +424,7 @@ class IntegrationSpec extends TestKit(ActorSystem("test")) with BitcoindService
// the payment is requesting to use a capacity-optimized route which will select node G even though it's a bit more expensive
sender.send(nodes("A").paymentInitiator,
- SendPayment(amountMsat.amount, pr.paymentHash, nodes("C").nodeParams.nodeId, maxAttempts = 1, routeParams = integrationTestRouteParams.map(_.copy(ratios = Some(WeightRatios(0, 0, 1))))))
+ SendPayment(amountMsat, pr.paymentHash, nodes("C").nodeParams.nodeId, maxAttempts = 1, routeParams = integrationTestRouteParams.map(_.copy(ratios = Some(WeightRatios(0, 0, 1))))))
sender.expectMsgType[UUID](max = 60 seconds)
awaitCond({
@@ -467,7 +468,7 @@ class IntegrationSpec extends TestKit(ActorSystem("test")) with BitcoindService
val preimage = randomBytes32
val paymentHash = Crypto.sha256(preimage)
// A sends a payment to F
- val paymentReq = SendPayment(100000000L, paymentHash, nodes("F1").nodeParams.nodeId, maxAttempts = 1, routeParams = integrationTestRouteParams)
+ val paymentReq = SendPayment(MilliSatoshi(100000000L), paymentHash, nodes("F1").nodeParams.nodeId, maxAttempts = 1, routeParams = integrationTestRouteParams)
val paymentSender = TestProbe()
paymentSender.send(nodes("A").paymentInitiator, paymentReq)
paymentSender.expectMsgType[UUID](30 seconds)
@@ -547,7 +548,7 @@ class IntegrationSpec extends TestKit(ActorSystem("test")) with BitcoindService
val preimage = randomBytes32
val paymentHash = Crypto.sha256(preimage)
// A sends a payment to F
- val paymentReq = SendPayment(100000000L, paymentHash, nodes("F2").nodeParams.nodeId, maxAttempts = 1, routeParams = integrationTestRouteParams)
+ val paymentReq = SendPayment(MilliSatoshi(100000000L), paymentHash, nodes("F2").nodeParams.nodeId, maxAttempts = 1, routeParams = integrationTestRouteParams)
val paymentSender = TestProbe()
paymentSender.send(nodes("A").paymentInitiator, paymentReq)
paymentSender.expectMsgType[UUID](30 seconds)
@@ -624,7 +625,7 @@ class IntegrationSpec extends TestKit(ActorSystem("test")) with BitcoindService
val preimage: ByteVector = randomBytes32
val paymentHash = Crypto.sha256(preimage)
// A sends a payment to F
- val paymentReq = SendPayment(100000000L, paymentHash, nodes("F3").nodeParams.nodeId, maxAttempts = 1, routeParams = integrationTestRouteParams)
+ val paymentReq = SendPayment(MilliSatoshi(100000000L), paymentHash, nodes("F3").nodeParams.nodeId, maxAttempts = 1, routeParams = integrationTestRouteParams)
val paymentSender = TestProbe()
paymentSender.send(nodes("A").paymentInitiator, paymentReq)
val paymentId = paymentSender.expectMsgType[UUID]
@@ -686,7 +687,7 @@ class IntegrationSpec extends TestKit(ActorSystem("test")) with BitcoindService
val preimage: ByteVector = randomBytes32
val paymentHash = Crypto.sha256(preimage)
// A sends a payment to F
- val paymentReq = SendPayment(100000000L, paymentHash, nodes("F4").nodeParams.nodeId, maxAttempts = 1, routeParams = integrationTestRouteParams)
+ val paymentReq = SendPayment(MilliSatoshi(100000000L), paymentHash, nodes("F4").nodeParams.nodeId, maxAttempts = 1, routeParams = integrationTestRouteParams)
val paymentSender = TestProbe()
paymentSender.send(nodes("A").paymentInitiator, paymentReq)
val paymentId = paymentSender.expectMsgType[UUID](30 seconds)
@@ -760,7 +761,7 @@ class IntegrationSpec extends TestKit(ActorSystem("test")) with BitcoindService
val amountMsat = MilliSatoshi(300000000L)
sender.send(paymentHandlerF, ReceivePayment(Some(amountMsat), "1 coffee"))
val pr = sender.expectMsgType[PaymentRequest]
- val sendReq = SendPayment(300000000L, pr.paymentHash, pr.nodeId, routeParams = integrationTestRouteParams, maxAttempts = 1)
+ val sendReq = SendPayment(MilliSatoshi(300000000L), pr.paymentHash, pr.nodeId, routeParams = integrationTestRouteParams, maxAttempts = 1)
sender.send(nodes("A").paymentInitiator, sendReq)
val paymentId = sender.expectMsgType[UUID]
// we forward the htlc to the payment handler
@@ -771,8 +772,8 @@ class IntegrationSpec extends TestKit(ActorSystem("test")) with BitcoindService
sender.expectMsgType[PaymentSucceeded].id === paymentId
// we now send a few htlcs C->F and F->C in order to obtain a commitments with multiple htlcs
- def send(amountMsat: Long, paymentHandler: ActorRef, paymentInitiator: ActorRef) = {
- sender.send(paymentHandler, ReceivePayment(Some(MilliSatoshi(amountMsat)), "1 coffee"))
+ def send(amountMsat: MilliSatoshi, paymentHandler: ActorRef, paymentInitiator: ActorRef) = {
+ sender.send(paymentHandler, ReceivePayment(Some(amountMsat), "1 coffee"))
val pr = sender.expectMsgType[PaymentRequest]
val sendReq = SendPayment(amountMsat, pr.paymentHash, pr.nodeId, routeParams = integrationTestRouteParams, maxAttempts = 1)
sender.send(paymentInitiator, sendReq)
@@ -780,19 +781,19 @@ class IntegrationSpec extends TestKit(ActorSystem("test")) with BitcoindService
}
val buffer = TestProbe()
- send(100000000, paymentHandlerF, nodes("C").paymentInitiator) // will be left pending
+ send(MilliSatoshi(100000000), paymentHandlerF, nodes("C").paymentInitiator) // will be left pending
forwardHandlerF.expectMsgType[UpdateAddHtlc]
forwardHandlerF.forward(buffer.ref)
sigListener.expectMsgType[ChannelSignatureReceived]
- send(110000000, paymentHandlerF, nodes("C").paymentInitiator) // will be left pending
+ send(MilliSatoshi(110000000), paymentHandlerF, nodes("C").paymentInitiator) // will be left pending
forwardHandlerF.expectMsgType[UpdateAddHtlc]
forwardHandlerF.forward(buffer.ref)
sigListener.expectMsgType[ChannelSignatureReceived]
- send(120000000, paymentHandlerC, nodes("F5").paymentInitiator)
+ send(MilliSatoshi(120000000), paymentHandlerC, nodes("F5").paymentInitiator)
forwardHandlerC.expectMsgType[UpdateAddHtlc]
forwardHandlerC.forward(buffer.ref)
sigListener.expectMsgType[ChannelSignatureReceived]
- send(130000000, paymentHandlerC, nodes("F5").paymentInitiator)
+ send(MilliSatoshi(130000000), paymentHandlerC, nodes("F5").paymentInitiator)
forwardHandlerC.expectMsgType[UpdateAddHtlc]
forwardHandlerC.forward(buffer.ref)
val commitmentsF = sigListener.expectMsgType[ChannelSignatureReceived].commitments
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/interop/rustytests/RustyTestsSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/interop/rustytests/RustyTestsSpec.scala
index 6697116750..9a0fbfde08 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/interop/rustytests/RustyTestsSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/interop/rustytests/RustyTestsSpec.scala
@@ -21,14 +21,14 @@ import java.util.concurrent.{CountDownLatch, TimeUnit}
import akka.actor.{ActorRef, ActorSystem, Props}
import akka.testkit.{TestFSMRef, TestKit, TestProbe}
-import fr.acinq.bitcoin.ByteVector32
+import fr.acinq.bitcoin.{ByteVector32, Satoshi}
import fr.acinq.eclair.TestConstants.{Alice, Bob, TestFeeEstimator}
import fr.acinq.eclair.blockchain._
import fr.acinq.eclair.blockchain.fee.FeeratesPerKw
import fr.acinq.eclair.channel._
import fr.acinq.eclair.payment.NoopPaymentHandler
import fr.acinq.eclair.wire.Init
-import fr.acinq.eclair.{Globals, TestUtils}
+import fr.acinq.eclair.{Globals, MilliSatoshi, TestUtils}
import org.scalatest.{BeforeAndAfterAll, Matchers, Outcome, fixture}
import scala.concurrent.duration._
@@ -60,7 +60,7 @@ class RustyTestsSpec extends TestKit(ActorSystem("test")) with Matchers with fix
val bobInit = Init(Bob.channelParams.globalFeatures, Bob.channelParams.localFeatures)
// alice and bob will both have 1 000 000 sat
feeEstimator.setFeerate(FeeratesPerKw.single(10000))
- alice ! INPUT_INIT_FUNDER(ByteVector32.Zeroes, 2000000, 1000000000, feeEstimator.getFeeratePerKw(target = 2), feeEstimator.getFeeratePerKw(target = 6), Alice.channelParams, pipe, bobInit, ChannelFlags.Empty)
+ alice ! INPUT_INIT_FUNDER(ByteVector32.Zeroes, Satoshi(2000000), MilliSatoshi(1000000000), feeEstimator.getFeeratePerKw(target = 2), feeEstimator.getFeeratePerKw(target = 6), Alice.channelParams, pipe, bobInit, ChannelFlags.Empty)
bob ! INPUT_INIT_FUNDEE(ByteVector32.Zeroes, Bob.channelParams, pipe, aliceInit)
pipe ! (alice, bob)
within(30 seconds) {
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/interop/rustytests/SynchronizationPipe.scala b/eclair-core/src/test/scala/fr/acinq/eclair/interop/rustytests/SynchronizationPipe.scala
index 2c72623576..1a2f5eabe6 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/interop/rustytests/SynchronizationPipe.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/interop/rustytests/SynchronizationPipe.scala
@@ -22,7 +22,7 @@ import java.util.concurrent.CountDownLatch
import akka.actor.{Actor, ActorLogging, ActorRef, Stash}
import fr.acinq.bitcoin.ByteVector32
-import fr.acinq.eclair.{TestConstants, TestUtils}
+import fr.acinq.eclair.{MilliSatoshi, TestConstants, TestUtils}
import fr.acinq.eclair.channel._
import fr.acinq.eclair.transactions.{IN, OUT}
@@ -57,7 +57,7 @@ class SynchronizationPipe(latch: CountDownLatch) extends Actor with ActorLogging
script match {
case offer(x, amount, rhash) :: rest =>
- resolve(x) ! CMD_ADD_HTLC(amount.toInt, ByteVector32.fromValidHex(rhash), 144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
+ resolve(x) ! CMD_ADD_HTLC(MilliSatoshi(amount.toInt), ByteVector32.fromValidHex(rhash), 144, TestConstants.emptyOnionPacket, upstream = Left(UUID.randomUUID()))
exec(rest, a, b)
case fulfill(x, id, r) :: rest =>
resolve(x) ! CMD_FULFILL_HTLC(id.toInt, ByteVector32.fromValidHex(r))
@@ -134,15 +134,15 @@ class SynchronizationPipe(latch: CountDownLatch) extends Actor with ActorLogging
s" Commit ${d.commitments.localCommit.index}:",
s" Offered htlcs: ${localCommit.spec.htlcs.filter(_.direction == OUT).map(h => (h.add.id, h.add.amountMsat)).mkString(" ")}",
s" Received htlcs: ${localCommit.spec.htlcs.filter(_.direction == IN).map(h => (h.add.id, h.add.amountMsat)).mkString(" ")}",
- s" Balance us: ${localCommit.spec.toLocalMsat}",
- s" Balance them: ${localCommit.spec.toRemoteMsat}",
+ s" Balance us: ${localCommit.spec.toLocal}",
+ s" Balance them: ${localCommit.spec.toRemote}",
s" Fee rate: ${localCommit.spec.feeratePerKw}",
"REMOTE COMMITS:",
s" Commit ${remoteCommit.index}:",
s" Offered htlcs: ${remoteCommit.spec.htlcs.filter(_.direction == OUT).map(h => (h.add.id, h.add.amountMsat)).mkString(" ")}",
s" Received htlcs: ${remoteCommit.spec.htlcs.filter(_.direction == IN).map(h => (h.add.id, h.add.amountMsat)).mkString(" ")}",
- s" Balance us: ${remoteCommit.spec.toLocalMsat}",
- s" Balance them: ${remoteCommit.spec.toRemoteMsat}",
+ s" Balance us: ${remoteCommit.spec.toLocal}",
+ s" Balance them: ${remoteCommit.spec.toRemote}",
s" Fee rate: ${remoteCommit.spec.feeratePerKw}")
.foreach(s => {
fout.write(rtrim(s))
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/io/HtlcReaperSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/io/HtlcReaperSpec.scala
index 4378f5cf1d..57debf6a86 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/io/HtlcReaperSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/io/HtlcReaperSpec.scala
@@ -18,6 +18,7 @@ package fr.acinq.eclair.io
import akka.actor.{ActorSystem, Props}
import akka.testkit.{TestKit, TestProbe}
+import fr.acinq.eclair.MilliSatoshi
import fr.acinq.eclair.channel._
import fr.acinq.eclair.{TestConstants, randomBytes32}
import fr.acinq.eclair.wire.{ChannelCodecsSpec, TemporaryNodeFailure, UpdateAddHtlc}
@@ -36,11 +37,11 @@ class HtlcReaperSpec extends TestKit(ActorSystem("test")) with FunSuiteLike {
val data = ChannelCodecsSpec.normal
// assuming that data has incoming htlcs 0 and 1, we don't care about the amount/payment_hash/onion fields
- val add0 = UpdateAddHtlc(data.channelId, 0, 20000, randomBytes32, 100, TestConstants.emptyOnionPacket)
- val add1 = UpdateAddHtlc(data.channelId, 1, 30000, randomBytes32, 100, TestConstants.emptyOnionPacket)
+ val add0 = UpdateAddHtlc(data.channelId, 0, MilliSatoshi(20000), randomBytes32, 100, TestConstants.emptyOnionPacket)
+ val add1 = UpdateAddHtlc(data.channelId, 1, MilliSatoshi(30000), randomBytes32, 100, TestConstants.emptyOnionPacket)
// unrelated htlc
- val add99 = UpdateAddHtlc(randomBytes32, 0, 12345678, randomBytes32, 100, TestConstants.emptyOnionPacket)
+ val add99 = UpdateAddHtlc(randomBytes32, 0, MilliSatoshi(12345678), randomBytes32, 100, TestConstants.emptyOnionPacket)
val brokenHtlcs = Seq(add0, add1, add99)
val brokenHtlcKiller = system.actorOf(Props[HtlcReaper], name = "htlc-reaper")
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/io/PeerSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/io/PeerSpec.scala
index 76fd945de6..d53d86ddba 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/io/PeerSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/io/PeerSpec.scala
@@ -22,7 +22,7 @@ import akka.actor.FSM.{CurrentState, SubscribeTransitionCallBack, Transition}
import akka.actor.{ActorRef, PoisonPill}
import akka.testkit.{TestFSMRef, TestProbe}
import fr.acinq.bitcoin.Crypto.PublicKey
-import fr.acinq.bitcoin.{MilliSatoshi, Satoshi}
+import fr.acinq.bitcoin.{Satoshi}
import fr.acinq.eclair.TestConstants._
import fr.acinq.eclair._
import fr.acinq.eclair.blockchain.{EclairWallet, TestWallet}
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/payment/ChannelSelectionSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/payment/ChannelSelectionSpec.scala
index ccc65efe0b..71027c5e10 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/payment/ChannelSelectionSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/payment/ChannelSelectionSpec.scala
@@ -22,7 +22,7 @@ import fr.acinq.eclair.channel.{CMD_ADD_HTLC, CMD_FAIL_HTLC}
import fr.acinq.eclair.payment.Relayer.{OutgoingChannel, RelayFailure, RelayPayload, RelaySuccess}
import fr.acinq.eclair.router.Announcements
import fr.acinq.eclair.wire._
-import fr.acinq.eclair.{ShortChannelId, TestConstants, randomBytes32, randomKey}
+import fr.acinq.eclair.{MilliSatoshi, ShortChannelId, TestConstants, randomBytes32, randomKey}
import fr.acinq.eclair.payment.HtlcGenerationSpec.makeCommitments
import org.scalatest.FunSuite
@@ -33,17 +33,17 @@ class ChannelSelectionSpec extends FunSuite {
/**
* This is just a simplified helper function with random values for fields we are not using here
*/
- def dummyUpdate(shortChannelId: ShortChannelId, cltvExpiryDelta: Int, htlcMinimumMsat: Long, feeBaseMsat: Long, feeProportionalMillionths: Long, htlcMaximumMsat: Long, enable: Boolean = true) =
- Announcements.makeChannelUpdate(Block.RegtestGenesisBlock.hash, randomKey, randomKey.publicKey, shortChannelId, cltvExpiryDelta, htlcMinimumMsat, feeBaseMsat, feeProportionalMillionths, htlcMaximumMsat, enable)
+ def dummyUpdate(shortChannelId: ShortChannelId, cltvExpiryDelta: Int, htlcMinimumMsat: MilliSatoshi, feeBaseMsat: Long, feeProportionalMillionths: Long, htlcMaximumMsat: Long, enable: Boolean = true) =
+ Announcements.makeChannelUpdate(Block.RegtestGenesisBlock.hash, randomKey, randomKey.publicKey, shortChannelId, cltvExpiryDelta, htlcMinimumMsat, MilliSatoshi(feeBaseMsat), feeProportionalMillionths, MilliSatoshi(htlcMaximumMsat), enable)
test("convert to CMD_FAIL_HTLC/CMD_ADD_HTLC") {
val relayPayload = RelayPayload(
- add = UpdateAddHtlc(randomBytes32, 42, 1000000, randomBytes32, 70, TestConstants.emptyOnionPacket),
- payload = PerHopPayload(ShortChannelId(12345), amtToForward = 998900, outgoingCltvValue = 60),
+ add = UpdateAddHtlc(randomBytes32, 42, MilliSatoshi(1000000), randomBytes32, 70, TestConstants.emptyOnionPacket),
+ payload = PerHopPayload(ShortChannelId(12345), amtToForward = MilliSatoshi(998900), outgoingCltvValue = 60),
nextPacket = TestConstants.emptyOnionPacket // just a placeholder
)
- val channelUpdate = dummyUpdate(ShortChannelId(12345), 10, 100, 1000, 100, 10000000, true)
+ val channelUpdate = dummyUpdate(ShortChannelId(12345), 10, MilliSatoshi(100), 1000, 100, 10000000, true)
implicit val log = akka.event.NoLogging
@@ -55,36 +55,36 @@ class ChannelSelectionSpec extends FunSuite {
val channelUpdate_disabled = channelUpdate.copy(channelFlags = Announcements.makeChannelFlags(true, enable = false))
assert(Relayer.relayOrFail(relayPayload, Some(channelUpdate_disabled)) === RelayFailure(CMD_FAIL_HTLC(relayPayload.add.id, Right(ChannelDisabled(channelUpdate_disabled.messageFlags, channelUpdate_disabled.channelFlags, channelUpdate_disabled)), commit = true)))
// amount too low
- val relayPayload_toolow = relayPayload.copy(payload = relayPayload.payload.copy(amtToForward = 99))
+ val relayPayload_toolow = relayPayload.copy(payload = relayPayload.payload.copy(amtToForward = MilliSatoshi(99)))
assert(Relayer.relayOrFail(relayPayload_toolow, Some(channelUpdate)) === RelayFailure(CMD_FAIL_HTLC(relayPayload.add.id, Right(AmountBelowMinimum(relayPayload_toolow.payload.amtToForward, channelUpdate)), commit = true)))
// incorrect cltv expiry
val relayPayload_incorrectcltv = relayPayload.copy(payload = relayPayload.payload.copy(outgoingCltvValue = 42))
assert(Relayer.relayOrFail(relayPayload_incorrectcltv, Some(channelUpdate)) === RelayFailure(CMD_FAIL_HTLC(relayPayload.add.id, Right(IncorrectCltvExpiry(relayPayload_incorrectcltv.payload.outgoingCltvValue, channelUpdate)), commit = true)))
// insufficient fee
- val relayPayload_insufficientfee = relayPayload.copy(payload = relayPayload.payload.copy(amtToForward = 998910))
+ val relayPayload_insufficientfee = relayPayload.copy(payload = relayPayload.payload.copy(amtToForward = MilliSatoshi(998910)))
assert(Relayer.relayOrFail(relayPayload_insufficientfee, Some(channelUpdate)) === RelayFailure(CMD_FAIL_HTLC(relayPayload.add.id, Right(FeeInsufficient(relayPayload_insufficientfee.add.amountMsat, channelUpdate)), commit = true)))
// note that a generous fee is ok!
- val relayPayload_highfee = relayPayload.copy(payload = relayPayload.payload.copy(amtToForward = 900000))
+ val relayPayload_highfee = relayPayload.copy(payload = relayPayload.payload.copy(amtToForward = MilliSatoshi(900000)))
assert(Relayer.relayOrFail(relayPayload_highfee, Some(channelUpdate)) === RelaySuccess(ShortChannelId(12345), CMD_ADD_HTLC(relayPayload_highfee.payload.amtToForward, relayPayload_highfee.add.paymentHash, relayPayload_highfee.payload.outgoingCltvValue, relayPayload_highfee.nextPacket, upstream = Right(relayPayload.add), commit = true)))
}
test("channel selection") {
val relayPayload = RelayPayload(
- add = UpdateAddHtlc(randomBytes32, 42, 1000000, randomBytes32, 70, TestConstants.emptyOnionPacket),
- payload = PerHopPayload(ShortChannelId(12345), amtToForward = 998900, outgoingCltvValue = 60),
+ add = UpdateAddHtlc(randomBytes32, 42, MilliSatoshi(1000000), randomBytes32, 70, TestConstants.emptyOnionPacket),
+ payload = PerHopPayload(ShortChannelId(12345), amtToForward = MilliSatoshi(998900), outgoingCltvValue = 60),
nextPacket = TestConstants.emptyOnionPacket // just a placeholder
)
val (a, b) = (randomKey.publicKey, randomKey.publicKey)
- val channelUpdate = dummyUpdate(ShortChannelId(12345), 10, 100, 1000, 100, 10000000, true)
+ val channelUpdate = dummyUpdate(ShortChannelId(12345), 10, MilliSatoshi(100), 1000, 100, 10000000, true)
val channelUpdates = Map(
- ShortChannelId(11111) -> OutgoingChannel(a, channelUpdate, makeCommitments(ByteVector32.Zeroes, 100000000)),
- ShortChannelId(12345) -> OutgoingChannel(a, channelUpdate, makeCommitments(ByteVector32.Zeroes, 20000000)),
- ShortChannelId(22222) -> OutgoingChannel(a, channelUpdate, makeCommitments(ByteVector32.Zeroes, 10000000)),
- ShortChannelId(33333) -> OutgoingChannel(a, channelUpdate, makeCommitments(ByteVector32.Zeroes, 100000)),
- ShortChannelId(44444) -> OutgoingChannel(b, channelUpdate, makeCommitments(ByteVector32.Zeroes, 1000000))
+ ShortChannelId(11111) -> OutgoingChannel(a, channelUpdate, makeCommitments(ByteVector32.Zeroes, MilliSatoshi(100000000))),
+ ShortChannelId(12345) -> OutgoingChannel(a, channelUpdate, makeCommitments(ByteVector32.Zeroes, MilliSatoshi(20000000))),
+ ShortChannelId(22222) -> OutgoingChannel(a, channelUpdate, makeCommitments(ByteVector32.Zeroes, MilliSatoshi(10000000))),
+ ShortChannelId(33333) -> OutgoingChannel(a, channelUpdate, makeCommitments(ByteVector32.Zeroes, MilliSatoshi(100000))),
+ ShortChannelId(44444) -> OutgoingChannel(b, channelUpdate, makeCommitments(ByteVector32.Zeroes, MilliSatoshi(1000000)))
)
val node2channels = new mutable.HashMap[PublicKey, mutable.Set[ShortChannelId]] with mutable.MultiMap[PublicKey, ShortChannelId]
@@ -104,11 +104,11 @@ class ChannelSelectionSpec extends FunSuite {
// all the suitable channels have been tried
assert(Relayer.selectPreferredChannel(relayPayload, channelUpdates, node2channels, Seq(ShortChannelId(22222), ShortChannelId(12345), ShortChannelId(11111))) === None)
// higher amount payment (have to increased incoming htlc amount for fees to be sufficient)
- assert(Relayer.selectPreferredChannel(relayPayload.modify(_.add.amountMsat).setTo(60000000).modify(_.payload.amtToForward).setTo(50000000), channelUpdates, node2channels, Seq.empty) === Some(ShortChannelId(11111)))
+ assert(Relayer.selectPreferredChannel(relayPayload.modify(_.add.amountMsat).setTo(MilliSatoshi(60000000)).modify(_.payload.amtToForward).setTo(MilliSatoshi(50000000)), channelUpdates, node2channels, Seq.empty) === Some(ShortChannelId(11111)))
// lower amount payment
- assert(Relayer.selectPreferredChannel(relayPayload.modify(_.payload.amtToForward).setTo(1000), channelUpdates, node2channels, Seq.empty) === Some(ShortChannelId(33333)))
+ assert(Relayer.selectPreferredChannel(relayPayload.modify(_.payload.amtToForward).setTo(MilliSatoshi(1000)), channelUpdates, node2channels, Seq.empty) === Some(ShortChannelId(33333)))
// payment too high, no suitable channel found
- assert(Relayer.selectPreferredChannel(relayPayload.modify(_.payload.amtToForward).setTo(1000000000), channelUpdates, node2channels, Seq.empty) === Some(ShortChannelId(12345)))
+ assert(Relayer.selectPreferredChannel(relayPayload.modify(_.payload.amtToForward).setTo(MilliSatoshi(1000000000)), channelUpdates, node2channels, Seq.empty) === Some(ShortChannelId(12345)))
// invalid cltv expiry, no suitable channel, we keep the requested one
assert(Relayer.selectPreferredChannel(relayPayload.modify(_.payload.outgoingCltvValue).setTo(40), channelUpdates, node2channels, Seq.empty) === Some(ShortChannelId(12345)))
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/payment/HtlcGenerationSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/payment/HtlcGenerationSpec.scala
index 9114a8e418..02252bc923 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/payment/HtlcGenerationSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/payment/HtlcGenerationSpec.scala
@@ -20,13 +20,14 @@ import java.util.UUID
import fr.acinq.bitcoin.DeterministicWallet.ExtendedPrivateKey
import fr.acinq.bitcoin.{Block, ByteVector32, Crypto, DeterministicWallet}
+import fr.acinq.eclair.maxOf
import fr.acinq.eclair.channel.{Channel, ChannelVersion, Commitments}
import fr.acinq.eclair.crypto.Sphinx
import fr.acinq.eclair.crypto.Sphinx.{DecryptedPacket, PacketAndSecrets}
import fr.acinq.eclair.payment.PaymentLifecycle._
import fr.acinq.eclair.router.Hop
import fr.acinq.eclair.wire.{ChannelUpdate, OnionCodecs, PerHopPayload}
-import fr.acinq.eclair.{ShortChannelId, TestConstants, nodeFee, randomBytes32}
+import fr.acinq.eclair.{MilliSatoshi, ShortChannelId, TestConstants, nodeFee, randomBytes32}
import org.scalatest.FunSuite
import scodec.bits.ByteVector
@@ -37,9 +38,9 @@ import scodec.bits.ByteVector
class HtlcGenerationSpec extends FunSuite {
test("compute fees") {
- val feeBaseMsat = 150000L
+ val feeBaseMsat = MilliSatoshi(150000L)
val feeProportionalMillionth = 4L
- val htlcAmountMsat = 42000000
+ val htlcAmountMsat = MilliSatoshi(42000000)
// spec: fee-base-msat + htlc-amount-msat * fee-proportional-millionths / 1000000
val ref = feeBaseMsat + htlcAmountMsat * feeProportionalMillionth / 1000000
val fee = nodeFee(feeBaseMsat, feeProportionalMillionth, htlcAmountMsat)
@@ -98,7 +99,7 @@ class HtlcGenerationSpec extends FunSuite {
val (add, _) = buildCommand(UUID.randomUUID, finalAmountMsat, finalExpiry, paymentHash, hops)
- assert(add.amountMsat > finalAmountMsat)
+ assert(add.amount > finalAmountMsat)
assert(add.cltvExpiry === finalExpiry + channelUpdate_de.cltvExpiryDelta + channelUpdate_cd.cltvExpiryDelta + channelUpdate_bc.cltvExpiryDelta)
assert(add.paymentHash === paymentHash)
assert(add.onion.payload.length === Sphinx.PaymentPacket.PayloadLength)
@@ -132,7 +133,7 @@ class HtlcGenerationSpec extends FunSuite {
test("build a command with no hops") {
val (add, _) = buildCommand(UUID.randomUUID(), finalAmountMsat, finalExpiry, paymentHash, hops.take(1))
- assert(add.amountMsat === finalAmountMsat)
+ assert(add.amount === finalAmountMsat)
assert(add.cltvExpiry === finalExpiry)
assert(add.paymentHash === paymentHash)
assert(add.onion.payload.length === Sphinx.PaymentPacket.PayloadLength)
@@ -149,10 +150,10 @@ class HtlcGenerationSpec extends FunSuite {
object HtlcGenerationSpec {
- def makeCommitments(channelId: ByteVector32, availableBalanceForSend: Long = 50000000L, availableBalanceForReceive: Long = 50000000L) =
+ def makeCommitments(channelId: ByteVector32, testAvailableBalanceForSend: MilliSatoshi = MilliSatoshi(50000000L), testAvailableBalanceForReceive: MilliSatoshi = MilliSatoshi(50000000L)) =
new Commitments(ChannelVersion.STANDARD, null, null, 0.toByte, null, null, null, null, 0, 0, Map.empty, null, null, null, channelId) {
- override lazy val availableBalanceForSendMsat: Long = availableBalanceForSend.max(0)
- override lazy val availableBalanceForReceiveMsat: Long = availableBalanceForReceive.max(0)
+ override lazy val availableBalanceForSend: MilliSatoshi = maxOf(testAvailableBalanceForSend, MilliSatoshi(0))
+ override lazy val availableBalanceForReceive: MilliSatoshi = maxOf(testAvailableBalanceForReceive, MilliSatoshi(0))
}
def randomExtendedPrivateKey: ExtendedPrivateKey = DeterministicWallet.generate(randomBytes32)
@@ -160,11 +161,11 @@ object HtlcGenerationSpec {
val (priv_a, priv_b, priv_c, priv_d, priv_e) = (TestConstants.Alice.keyManager.nodeKey, TestConstants.Bob.keyManager.nodeKey, randomExtendedPrivateKey, randomExtendedPrivateKey, randomExtendedPrivateKey)
val (a, b, c, d, e) = (priv_a.publicKey, priv_b.publicKey, priv_c.publicKey, priv_d.publicKey, priv_e.publicKey)
val sig = Crypto.sign(Crypto.sha256(ByteVector.empty), priv_a.privateKey)
- val defaultChannelUpdate = ChannelUpdate(sig, Block.RegtestGenesisBlock.hash, ShortChannelId(0), 0, 1, 0, 0, 42000, 0, 0, Some(500000000L))
- val channelUpdate_ab = defaultChannelUpdate.copy(shortChannelId = ShortChannelId(1), cltvExpiryDelta = 4, feeBaseMsat = 642000, feeProportionalMillionths = 7)
- val channelUpdate_bc = defaultChannelUpdate.copy(shortChannelId = ShortChannelId(2), cltvExpiryDelta = 5, feeBaseMsat = 153000, feeProportionalMillionths = 4)
- val channelUpdate_cd = defaultChannelUpdate.copy(shortChannelId = ShortChannelId(3), cltvExpiryDelta = 10, feeBaseMsat = 60000, feeProportionalMillionths = 1)
- val channelUpdate_de = defaultChannelUpdate.copy(shortChannelId = ShortChannelId(4), cltvExpiryDelta = 7, feeBaseMsat = 766000, feeProportionalMillionths = 10)
+ val defaultChannelUpdate = ChannelUpdate(sig, Block.RegtestGenesisBlock.hash, ShortChannelId(0), 0, 1, 0, 0, MilliSatoshi(42000), MilliSatoshi(0), 0, Some(MilliSatoshi(500000000L)))
+ val channelUpdate_ab = defaultChannelUpdate.copy(shortChannelId = ShortChannelId(1), cltvExpiryDelta = 4, feeBaseMsat = MilliSatoshi(642000), feeProportionalMillionths = 7)
+ val channelUpdate_bc = defaultChannelUpdate.copy(shortChannelId = ShortChannelId(2), cltvExpiryDelta = 5, feeBaseMsat = MilliSatoshi(153000), feeProportionalMillionths = 4)
+ val channelUpdate_cd = defaultChannelUpdate.copy(shortChannelId = ShortChannelId(3), cltvExpiryDelta = 10, feeBaseMsat = MilliSatoshi(60000), feeProportionalMillionths = 1)
+ val channelUpdate_de = defaultChannelUpdate.copy(shortChannelId = ShortChannelId(4), cltvExpiryDelta = 7, feeBaseMsat = MilliSatoshi(766000), feeProportionalMillionths = 10)
// simple route a -> b -> c -> d -> e
@@ -174,7 +175,7 @@ object HtlcGenerationSpec {
Hop(c, d, channelUpdate_cd) ::
Hop(d, e, channelUpdate_de) :: Nil
- val finalAmountMsat = 42000000L
+ val finalAmountMsat = MilliSatoshi(42000000L)
val currentBlockCount = 420000
val finalExpiry = currentBlockCount + Channel.MIN_CLTV_EXPIRY
val paymentPreimage = randomBytes32
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/payment/PaymentHandlerSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/payment/PaymentHandlerSpec.scala
index 3915d24895..4a1b21f452 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/payment/PaymentHandlerSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/payment/PaymentHandlerSpec.scala
@@ -19,13 +19,13 @@ package fr.acinq.eclair.payment
import akka.actor.Status.Failure
import akka.actor.ActorSystem
import akka.testkit.{TestActorRef, TestKit, TestProbe}
-import fr.acinq.bitcoin.{ByteVector32, MilliSatoshi}
+import fr.acinq.bitcoin.ByteVector32
import fr.acinq.eclair.TestConstants.Alice
import fr.acinq.eclair.channel.{CMD_FAIL_HTLC, CMD_FULFILL_HTLC}
import fr.acinq.eclair.payment.PaymentLifecycle.ReceivePayment
import fr.acinq.eclair.payment.PaymentRequest.ExtraHop
import fr.acinq.eclair.wire.{FinalExpiryTooSoon, UpdateAddHtlc}
-import fr.acinq.eclair.{Globals, ShortChannelId, TestConstants, randomKey}
+import fr.acinq.eclair.{Globals, MilliSatoshi, ShortChannelId, TestConstants, randomKey}
import org.scalatest.FunSuiteLike
import scodec.bits.ByteVector
@@ -54,7 +54,7 @@ class PaymentHandlerSpec extends TestKit(ActorSystem("test")) with FunSuiteLike
assert(nodeParams.db.payments.getPendingPaymentRequestAndPreimage(pr.paymentHash).isDefined)
assert(!nodeParams.db.payments.getPendingPaymentRequestAndPreimage(pr.paymentHash).get._2.isExpired)
- val add = UpdateAddHtlc(ByteVector32(ByteVector.fill(32)(1)), 0, amountMsat.amount, pr.paymentHash, expiry, TestConstants.emptyOnionPacket)
+ val add = UpdateAddHtlc(ByteVector32(ByteVector.fill(32)(1)), 0, amountMsat, pr.paymentHash, expiry, TestConstants.emptyOnionPacket)
sender.send(handler, add)
sender.expectMsgType[CMD_FULFILL_HTLC]
@@ -68,7 +68,7 @@ class PaymentHandlerSpec extends TestKit(ActorSystem("test")) with FunSuiteLike
val pr = sender.expectMsgType[PaymentRequest]
assert(nodeParams.db.payments.getIncomingPayment(pr.paymentHash).isEmpty)
- val add = UpdateAddHtlc(ByteVector32(ByteVector.fill(32)(1)), 0, amountMsat.amount, pr.paymentHash, expiry, TestConstants.emptyOnionPacket)
+ val add = UpdateAddHtlc(ByteVector32(ByteVector.fill(32)(1)), 0, amountMsat, pr.paymentHash, expiry, TestConstants.emptyOnionPacket)
sender.send(handler, add)
sender.expectMsgType[CMD_FULFILL_HTLC]
val paymentRelayed = eventListener.expectMsgType[PaymentReceived]
@@ -81,7 +81,7 @@ class PaymentHandlerSpec extends TestKit(ActorSystem("test")) with FunSuiteLike
val pr = sender.expectMsgType[PaymentRequest]
assert(nodeParams.db.payments.getIncomingPayment(pr.paymentHash).isEmpty)
- val add = UpdateAddHtlc(ByteVector32(ByteVector.fill(32)(1)), 0, amountMsat.amount, pr.paymentHash, cltvExpiry = Globals.blockCount.get() + 3, TestConstants.emptyOnionPacket)
+ val add = UpdateAddHtlc(ByteVector32(ByteVector.fill(32)(1)), 0, amountMsat, pr.paymentHash, cltvExpiry = Globals.blockCount.get() + 3, TestConstants.emptyOnionPacket)
sender.send(handler, add)
assert(sender.expectMsgType[CMD_FAIL_HTLC].reason == Right(FinalExpiryTooSoon))
eventListener.expectNoMsg(300 milliseconds)
@@ -164,7 +164,7 @@ class PaymentHandlerSpec extends TestKit(ActorSystem("test")) with FunSuiteLike
sender.send(handler, ReceivePayment(Some(amountMsat), "some desc", expirySeconds_opt = Some(0)))
val pr = sender.expectMsgType[PaymentRequest]
- val add = UpdateAddHtlc(ByteVector32(ByteVector.fill(32)(1)), 0, amountMsat.amount, pr.paymentHash, expiry, TestConstants.emptyOnionPacket)
+ val add = UpdateAddHtlc(ByteVector32(ByteVector.fill(32)(1)), 0, amountMsat, pr.paymentHash, expiry, TestConstants.emptyOnionPacket)
sender.send(handler, add)
sender.expectMsgType[CMD_FAIL_HTLC]
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/payment/PaymentLifecycleSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/payment/PaymentLifecycleSpec.scala
index 79192309bf..9d178c0819 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/payment/PaymentLifecycleSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/payment/PaymentLifecycleSpec.scala
@@ -22,7 +22,7 @@ import akka.actor.FSM.{CurrentState, SubscribeTransitionCallBack, Transition}
import akka.actor.Status
import akka.testkit.{TestFSMRef, TestProbe}
import fr.acinq.bitcoin.Script.{pay2wsh, write}
-import fr.acinq.bitcoin.{Block, ByteVector32, MilliSatoshi, Satoshi, Transaction, TxOut}
+import fr.acinq.bitcoin.{Block, ByteVector32, Satoshi, Transaction, TxOut}
import fr.acinq.eclair.blockchain.{UtxoStatus, ValidateRequest, ValidateResult, WatchSpentBasic}
import fr.acinq.eclair.channel.Register.ForwardShortId
import fr.acinq.eclair.channel.{AddHtlcFailed, ChannelUnavailable}
@@ -42,7 +42,7 @@ import fr.acinq.eclair._
class PaymentLifecycleSpec extends BaseRouterSpec {
- val defaultAmountMsat = 142000000L
+ val defaultAmountMsat = MilliSatoshi(142000000L)
test("send to route") { fixture =>
import fixture._
@@ -109,7 +109,7 @@ class PaymentLifecycleSpec extends BaseRouterSpec {
paymentFSM ! SubscribeTransitionCallBack(monitor.ref)
val CurrentState(_, WAITING_FOR_REQUEST) = monitor.expectMsgClass(classOf[CurrentState[_]])
- val request = SendPayment(defaultAmountMsat, randomBytes32, d, routeParams = Some(RouteParams(randomize = false, maxFeeBaseMsat = 100, maxFeePct = 0.0, routeMaxLength = 20, routeMaxCltv = 2016, ratios = None)), maxAttempts = 5)
+ val request = SendPayment(defaultAmountMsat, randomBytes32, d, routeParams = Some(RouteParams(randomize = false, maxFeeBase = MilliSatoshi(100), maxFeePct = 0.0, routeMaxLength = 20, routeMaxCltv = 2016, ratios = None)), maxAttempts = 5)
sender.send(paymentFSM, request)
val Transition(_, WAITING_FOR_REQUEST, WAITING_FOR_ROUTE) = monitor.expectMsgClass(classOf[Transition[_]])
@@ -389,9 +389,9 @@ class PaymentLifecycleSpec extends BaseRouterSpec {
sender.send(paymentFSM, UpdateFulfillHtlc(ByteVector32.Zeroes, 0, defaultPaymentHash))
val paymentOK = sender.expectMsgType[PaymentSucceeded]
- val PaymentSent(_, MilliSatoshi(request.amountMsat), fee, request.paymentHash, paymentOK.paymentPreimage, _, _) = eventListener.expectMsgType[PaymentSent]
+ val PaymentSent(_, request.amount, fee, request.paymentHash, paymentOK.paymentPreimage, _, _) = eventListener.expectMsgType[PaymentSent]
assert(fee > MilliSatoshi(0))
- assert(fee === MilliSatoshi(paymentOK.amountMsat - request.amountMsat))
+ assert(fee === paymentOK.amount - request.amount)
awaitCond(paymentDb.getOutgoingPayment(id).exists(_.status == OutgoingPaymentStatus.SUCCEEDED))
}
@@ -409,8 +409,8 @@ class PaymentLifecycleSpec extends BaseRouterSpec {
val ann_g = makeNodeAnnouncement(priv_g, "node-G", Color(-30, 10, -50), Nil)
val channelId_bg = ShortChannelId(420000, 5, 0)
val chan_bg = channelAnnouncement(channelId_bg, priv_b, priv_g, priv_funding_b, priv_funding_g)
- val channelUpdate_bg = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv_b, g, channelId_bg, cltvExpiryDelta = 9, htlcMinimumMsat = 0, feeBaseMsat = 0, feeProportionalMillionths = 0, htlcMaximumMsat = 500000000L)
- val channelUpdate_gb = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv_g, b, channelId_bg, cltvExpiryDelta = 9, htlcMinimumMsat = 0, feeBaseMsat = 10, feeProportionalMillionths = 8, htlcMaximumMsat = 500000000L)
+ val channelUpdate_bg = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv_b, g, channelId_bg, cltvExpiryDelta = 9, htlcMinimumMsat = MilliSatoshi(0), feeBaseMsat = MilliSatoshi(0), feeProportionalMillionths = 0, htlcMaximumMsat = MilliSatoshi(500000000L))
+ val channelUpdate_gb = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv_g, b, channelId_bg, cltvExpiryDelta = 9, htlcMinimumMsat = MilliSatoshi(0), feeBaseMsat = MilliSatoshi(10), feeProportionalMillionths = 8, htlcMaximumMsat = MilliSatoshi(500000000L))
assert(Router.getDesc(channelUpdate_bg, chan_bg) === ChannelDesc(chan_bg.shortChannelId, priv_b.publicKey, priv_g.publicKey))
router ! PeerRoutingMessage(null, remoteNodeId, chan_bg)
router ! PeerRoutingMessage(null, remoteNodeId, ann_g)
@@ -441,13 +441,13 @@ class PaymentLifecycleSpec extends BaseRouterSpec {
sender.send(paymentFSM, UpdateFulfillHtlc(ByteVector32.Zeroes, 0, defaultPaymentHash))
val paymentOK = sender.expectMsgType[PaymentSucceeded]
- val PaymentSent(_, MilliSatoshi(request.amountMsat), fee, request.paymentHash, paymentOK.paymentPreimage, _, _) = eventListener.expectMsgType[PaymentSent]
+ val PaymentSent(_, request.amount, fee, request.paymentHash, paymentOK.paymentPreimage, _, _) = eventListener.expectMsgType[PaymentSent]
// during the route computation the fees were treated as if they were 1msat but when sending the onion we actually put zero
// NB: A -> B doesn't pay fees because it's our direct neighbor
// NB: B -> G doesn't asks for fees at all
assert(fee === MilliSatoshi(0))
- assert(fee === MilliSatoshi(paymentOK.amountMsat - request.amountMsat))
+ assert(fee === paymentOK.amount - request.amount)
}
test("filter errors properly") { _ =>
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/payment/PaymentRequestSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/payment/PaymentRequestSpec.scala
index f67bd0e074..19706bcac9 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/payment/PaymentRequestSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/payment/PaymentRequestSpec.scala
@@ -17,14 +17,15 @@
package fr.acinq.eclair.payment
import java.nio.ByteOrder
-
import fr.acinq.bitcoin.Crypto.{PrivateKey, PublicKey}
-import fr.acinq.bitcoin.{Block, Btc, ByteVector32, Crypto, MilliBtc, MilliSatoshi, Protocol, Satoshi}
-import fr.acinq.eclair.ShortChannelId
+import fr.acinq.bitcoin.{Block, Btc, ByteVector32, Crypto, MilliBtc, Protocol, Satoshi}
+import fr.acinq.bitcoin._
+import fr.acinq.eclair.{MilliSatoshi, ShortChannelId}
import fr.acinq.eclair.payment.PaymentRequest._
import org.scalatest.FunSuite
import scodec.DecodeResult
import scodec.bits._
+import fr.acinq.eclair._
/**
* Created by fabrice on 15/05/17.
@@ -42,13 +43,13 @@ class PaymentRequestSpec extends FunSuite {
assert('p' === Amount.unit(MilliSatoshi(99)))
assert('n' === Amount.unit(MilliSatoshi(100)))
assert('p' === Amount.unit(MilliSatoshi(101)))
- assert('n' === Amount.unit(Satoshi(1)))
- assert('u' === Amount.unit(Satoshi(100)))
- assert('n' === Amount.unit(Satoshi(101)))
- assert('u' === Amount.unit(Satoshi(1155400)))
- assert('m' === Amount.unit(MilliBtc(1)))
- assert('m' === Amount.unit(MilliBtc(10)))
- assert('m' === Amount.unit(Btc(1)))
+ assert('n' === Amount.unit(Satoshi(1).toMilliSatoshi))
+ assert('u' === Amount.unit(Satoshi(100).toMilliSatoshi))
+ assert('n' === Amount.unit(Satoshi(101).toMilliSatoshi))
+ assert('u' === Amount.unit(Satoshi(1155400).toMilliSatoshi))
+ assert('m' === Amount.unit(millibtc2satoshi(MilliBtc(1)).toMilliSatoshi))
+ assert('m' === Amount.unit(millibtc2satoshi(MilliBtc(10)).toMilliSatoshi))
+ assert('m' === Amount.unit(btc2satoshi(Btc(1)).toMilliSatoshi))
}
test("check that we can still decode non-minimal amount encoding") {
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/payment/RelayerSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/payment/RelayerSpec.scala
index c6f6a27d41..97db737ee4 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/payment/RelayerSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/payment/RelayerSpec.scala
@@ -20,13 +20,13 @@ import java.util.UUID
import akka.actor.{ActorRef, Status}
import akka.testkit.TestProbe
-import fr.acinq.bitcoin.{ByteVector32, MilliSatoshi}
+import fr.acinq.bitcoin.{ByteVector32, Satoshi}
import fr.acinq.eclair.channel._
import fr.acinq.eclair.crypto.Sphinx
import fr.acinq.eclair.payment.PaymentLifecycle.buildCommand
import fr.acinq.eclair.router.Announcements
import fr.acinq.eclair.wire._
-import fr.acinq.eclair.{ShortChannelId, TestConstants, TestkitBaseClass, UInt64, randomBytes32}
+import fr.acinq.eclair.{MilliSatoshi, ShortChannelId, TestConstants, TestkitBaseClass, UInt64, randomBytes32}
import org.scalatest.Outcome
import scodec.bits.ByteVector
@@ -63,7 +63,7 @@ class RelayerSpec extends TestkitBaseClass {
// we use this to build a valid onion
val (cmd, _) = buildCommand(UUID.randomUUID(), finalAmountMsat, finalExpiry, paymentHash, hops)
// and then manually build an htlc
- val add_ab = UpdateAddHtlc(channelId = channelId_ab, id = 123456, cmd.amountMsat, cmd.paymentHash, cmd.cltvExpiry, cmd.onion)
+ val add_ab = UpdateAddHtlc(channelId = channelId_ab, id = 123456, cmd.amount, cmd.paymentHash, cmd.cltvExpiry, cmd.onion)
relayer ! LocalChannelUpdate(null, channelId_bc, channelUpdate_bc.shortChannelId, c, None, channelUpdate_bc, makeCommitments(channelId_bc))
sender.send(relayer, ForwardAdd(add_ab))
@@ -83,14 +83,14 @@ class RelayerSpec extends TestkitBaseClass {
// we use this to build a valid onion
val (cmd, _) = buildCommand(UUID.randomUUID(), finalAmountMsat, finalExpiry, paymentHash, hops)
// and then manually build an htlc
- val add_ab = UpdateAddHtlc(channelId = channelId_ab, id = 123456, cmd.amountMsat, cmd.paymentHash, cmd.cltvExpiry, cmd.onion)
+ val add_ab = UpdateAddHtlc(channelId = channelId_ab, id = 123456, cmd.amount, cmd.paymentHash, cmd.cltvExpiry, cmd.onion)
// we tell the relayer about channel B-C
relayer ! LocalChannelUpdate(null, channelId_bc, channelUpdate_bc.shortChannelId, c, None, channelUpdate_bc, makeCommitments(channelId_bc))
// this is another channel B-C, with less balance (it will be preferred)
val (channelId_bc_1, channelUpdate_bc_1) = (randomBytes32, channelUpdate_bc.copy(shortChannelId = ShortChannelId("500000x1x1")))
- relayer ! LocalChannelUpdate(null, channelId_bc_1, channelUpdate_bc_1.shortChannelId, c, None, channelUpdate_bc_1, makeCommitments(channelId_bc_1, 49000000L))
+ relayer ! LocalChannelUpdate(null, channelId_bc_1, channelUpdate_bc_1.shortChannelId, c, None, channelUpdate_bc_1, makeCommitments(channelId_bc_1, MilliSatoshi(49000000L)))
sender.send(relayer, ForwardAdd(add_ab))
@@ -100,7 +100,7 @@ class RelayerSpec extends TestkitBaseClass {
assert(fwd1.message.upstream === Right(add_ab))
// channel returns an error
- val origin = Relayed(channelId_ab, originHtlcId = 42, amountMsatIn = 1100000, amountMsatOut = 1000000)
+ val origin = Relayed(channelId_ab, originHtlcId = 42, amountIn = MilliSatoshi(1100000), amountOut = MilliSatoshi(1000000))
sender.send(relayer, Status.Failure(AddHtlcFailed(channelId_bc_1, paymentHash, HtlcValueTooHighInFlight(channelId_bc_1, UInt64(1000000000L), UInt64(1516977616L)), origin, Some(channelUpdate_bc_1), originalCommand = Some(fwd1.message))))
// second try
@@ -128,7 +128,7 @@ class RelayerSpec extends TestkitBaseClass {
// we use this to build a valid onion
val (cmd, _) = buildCommand(UUID.randomUUID(), finalAmountMsat, finalExpiry, paymentHash, hops)
// and then manually build an htlc
- val add_ab = UpdateAddHtlc(channelId = channelId_ab, id = 123456, cmd.amountMsat, cmd.paymentHash, cmd.cltvExpiry, cmd.onion)
+ val add_ab = UpdateAddHtlc(channelId = channelId_ab, id = 123456, cmd.amount, cmd.paymentHash, cmd.cltvExpiry, cmd.onion)
sender.send(relayer, ForwardAdd(add_ab))
@@ -148,7 +148,7 @@ class RelayerSpec extends TestkitBaseClass {
// we use this to build a valid onion
val (cmd, _) = buildCommand(UUID.randomUUID(), finalAmountMsat, finalExpiry, paymentHash, hops)
// and then manually build an htlc
- val add_ab = UpdateAddHtlc(channelId = channelId_ab, id = 123456, cmd.amountMsat, cmd.paymentHash, cmd.cltvExpiry, cmd.onion)
+ val add_ab = UpdateAddHtlc(channelId = channelId_ab, id = 123456, cmd.amount, cmd.paymentHash, cmd.cltvExpiry, cmd.onion)
relayer ! LocalChannelUpdate(null, channelId_bc, channelUpdate_bc.shortChannelId, c, None, channelUpdate_bc, makeCommitments(channelId_bc))
sender.send(relayer, ForwardAdd(add_ab))
@@ -174,7 +174,7 @@ class RelayerSpec extends TestkitBaseClass {
// check that payments are sent properly
val (cmd, _) = buildCommand(UUID.randomUUID(), finalAmountMsat, finalExpiry, paymentHash, hops)
- val add_ab = UpdateAddHtlc(channelId = channelId_ab, id = 123456, cmd.amountMsat, cmd.paymentHash, cmd.cltvExpiry, cmd.onion)
+ val add_ab = UpdateAddHtlc(channelId = channelId_ab, id = 123456, cmd.amount, cmd.paymentHash, cmd.cltvExpiry, cmd.onion)
relayer ! LocalChannelUpdate(null, channelId_bc, channelUpdate_bc.shortChannelId, c, None, channelUpdate_bc, makeCommitments(channelId_bc))
sender.send(relayer, ForwardAdd(add_ab))
@@ -190,7 +190,7 @@ class RelayerSpec extends TestkitBaseClass {
relayer ! LocalChannelDown(sender.ref, channelId = channelId_bc, shortChannelId = channelUpdate_bc.shortChannelId, remoteNodeId = TestConstants.Bob.nodeParams.nodeId)
val (cmd1, _) = buildCommand(UUID.randomUUID(), finalAmountMsat, finalExpiry, randomBytes32, hops)
- val add_ab1 = UpdateAddHtlc(channelId = channelId_ab, id = 123456, cmd1.amountMsat, cmd1.paymentHash, cmd1.cltvExpiry, cmd1.onion)
+ val add_ab1 = UpdateAddHtlc(channelId = channelId_ab, id = 123456, cmd1.amount, cmd1.paymentHash, cmd1.cltvExpiry, cmd1.onion)
sender.send(relayer, ForwardAdd(add_ab1))
val fail = register.expectMsgType[Register.Forward[CMD_FAIL_HTLC]].message
@@ -208,7 +208,7 @@ class RelayerSpec extends TestkitBaseClass {
// we use this to build a valid onion
val (cmd, _) = buildCommand(UUID.randomUUID(), finalAmountMsat, finalExpiry, paymentHash, hops)
// and then manually build an htlc
- val add_ab = UpdateAddHtlc(channelId = channelId_ab, id = 123456, cmd.amountMsat, cmd.paymentHash, cmd.cltvExpiry, cmd.onion)
+ val add_ab = UpdateAddHtlc(channelId = channelId_ab, id = 123456, cmd.amount, cmd.paymentHash, cmd.cltvExpiry, cmd.onion)
val channelUpdate_bc_disabled = channelUpdate_bc.copy(channelFlags = Announcements.makeChannelFlags(Announcements.isNode1(channelUpdate_bc.channelFlags), enable = false))
relayer ! LocalChannelUpdate(null, channelId_bc, channelUpdate_bc.shortChannelId, c, None, channelUpdate_bc_disabled, makeCommitments(channelId_bc))
@@ -229,7 +229,7 @@ class RelayerSpec extends TestkitBaseClass {
// we use this to build a valid onion
val (cmd, _) = buildCommand(UUID.randomUUID(), finalAmountMsat, finalExpiry, paymentHash, hops)
// and then manually build an htlc with an invalid onion (hmac)
- val add_ab = UpdateAddHtlc(channelId = channelId_ab, id = 123456, cmd.amountMsat, cmd.paymentHash, cmd.cltvExpiry, cmd.onion.copy(hmac = cmd.onion.hmac.reverse))
+ val add_ab = UpdateAddHtlc(channelId = channelId_ab, id = 123456, cmd.amount, cmd.paymentHash, cmd.cltvExpiry, cmd.onion.copy(hmac = cmd.onion.hmac.reverse))
relayer ! LocalChannelUpdate(null, channelId_bc, channelUpdate_bc.shortChannelId, c, None, channelUpdate_bc, makeCommitments(channelId_bc))
sender.send(relayer, ForwardAdd(add_ab))
@@ -248,16 +248,16 @@ class RelayerSpec extends TestkitBaseClass {
val sender = TestProbe()
// we use this to build a valid onion
- val (cmd, _) = buildCommand(UUID.randomUUID(), channelUpdate_bc.htlcMinimumMsat - 1, finalExpiry, paymentHash, hops.map(hop => hop.copy(lastUpdate = hop.lastUpdate.copy(feeBaseMsat = 0, feeProportionalMillionths = 0))))
+ val (cmd, _) = buildCommand(UUID.randomUUID(), channelUpdate_bc.htlcMinimumMsat - MilliSatoshi(1), finalExpiry, paymentHash, hops.map(hop => hop.copy(lastUpdate = hop.lastUpdate.copy(feeBaseMsat = MilliSatoshi(0), feeProportionalMillionths = 0))))
// and then manually build an htlc
- val add_ab = UpdateAddHtlc(channelId = channelId_ab, id = 123456, cmd.amountMsat, cmd.paymentHash, cmd.cltvExpiry, cmd.onion)
+ val add_ab = UpdateAddHtlc(channelId = channelId_ab, id = 123456, cmd.amount, cmd.paymentHash, cmd.cltvExpiry, cmd.onion)
relayer ! LocalChannelUpdate(null, channelId_bc, channelUpdate_bc.shortChannelId, c, None, channelUpdate_bc, makeCommitments(channelId_bc))
sender.send(relayer, ForwardAdd(add_ab))
val fail = register.expectMsgType[Register.Forward[CMD_FAIL_HTLC]].message
assert(fail.id === add_ab.id)
- assert(fail.reason == Right(AmountBelowMinimum(cmd.amountMsat, channelUpdate_bc)))
+ assert(fail.reason == Right(AmountBelowMinimum(cmd.amount, channelUpdate_bc)))
register.expectNoMsg(100 millis)
paymentHandler.expectNoMsg(100 millis)
@@ -270,7 +270,7 @@ class RelayerSpec extends TestkitBaseClass {
val hops1 = hops.updated(1, hops(1).copy(lastUpdate = hops(1).lastUpdate.copy(cltvExpiryDelta = 0)))
val (cmd, _) = buildCommand(UUID.randomUUID(), finalAmountMsat, finalExpiry, paymentHash, hops1)
// and then manually build an htlc
- val add_ab = UpdateAddHtlc(channelId = channelId_ab, id = 123456, cmd.amountMsat, cmd.paymentHash, cmd.cltvExpiry, cmd.onion)
+ val add_ab = UpdateAddHtlc(channelId = channelId_ab, id = 123456, cmd.amount, cmd.paymentHash, cmd.cltvExpiry, cmd.onion)
relayer ! LocalChannelUpdate(null, channelId_bc, channelUpdate_bc.shortChannelId, c, None, channelUpdate_bc, makeCommitments(channelId_bc))
sender.send(relayer, ForwardAdd(add_ab))
@@ -290,7 +290,7 @@ class RelayerSpec extends TestkitBaseClass {
val hops1 = hops.updated(1, hops(1).copy(lastUpdate = hops(1).lastUpdate.copy(feeBaseMsat = hops(1).lastUpdate.feeBaseMsat / 2)))
val (cmd, _) = buildCommand(UUID.randomUUID(), finalAmountMsat, finalExpiry, paymentHash, hops1)
// and then manually build an htlc
- val add_ab = UpdateAddHtlc(channelId = channelId_ab, id = 123456, cmd.amountMsat, cmd.paymentHash, cmd.cltvExpiry, cmd.onion)
+ val add_ab = UpdateAddHtlc(channelId = channelId_ab, id = 123456, cmd.amount, cmd.paymentHash, cmd.cltvExpiry, cmd.onion)
relayer ! LocalChannelUpdate(null, channelId_bc, channelUpdate_bc.shortChannelId, c, None, channelUpdate_bc, makeCommitments(channelId_bc))
sender.send(relayer, ForwardAdd(add_ab))
@@ -311,7 +311,7 @@ class RelayerSpec extends TestkitBaseClass {
val hops1 = hops.head :: Nil
val (cmd, _) = buildCommand(UUID.randomUUID(), finalAmountMsat, finalExpiry, paymentHash, hops1)
// and then manually build an htlc with a wrong expiry
- val add_ab = UpdateAddHtlc(channelId = channelId_ab, id = 123456, cmd.amountMsat - 1, cmd.paymentHash, cmd.cltvExpiry, cmd.onion)
+ val add_ab = UpdateAddHtlc(channelId = channelId_ab, id = 123456, cmd.amount - MilliSatoshi(1), cmd.paymentHash, cmd.cltvExpiry, cmd.onion)
relayer ! LocalChannelUpdate(null, channelId_bc, channelUpdate_bc.shortChannelId, c, None, channelUpdate_bc, makeCommitments(channelId_bc))
sender.send(relayer, ForwardAdd(add_ab))
@@ -332,7 +332,7 @@ class RelayerSpec extends TestkitBaseClass {
val hops1 = hops.head :: Nil
val (cmd, _) = buildCommand(UUID.randomUUID(), finalAmountMsat, finalExpiry, paymentHash, hops1)
// and then manually build an htlc with a wrong expiry
- val add_ab = UpdateAddHtlc(channelId = channelId_ab, id = 123456, cmd.amountMsat, cmd.paymentHash, cmd.cltvExpiry - 1, cmd.onion)
+ val add_ab = UpdateAddHtlc(channelId = channelId_ab, id = 123456, cmd.amount, cmd.paymentHash, cmd.cltvExpiry - 1, cmd.onion)
relayer ! LocalChannelUpdate(null, channelId_bc, channelUpdate_bc.shortChannelId, c, None, channelUpdate_bc, makeCommitments(channelId_bc))
sender.send(relayer, ForwardAdd(add_ab))
@@ -350,7 +350,7 @@ class RelayerSpec extends TestkitBaseClass {
val sender = TestProbe()
val paymentHash = randomBytes32
- val origin = Relayed(channelId_ab, originHtlcId = 42, amountMsatIn = 1100000, amountMsatOut = 1000000)
+ val origin = Relayed(channelId_ab, originHtlcId = 42, amountIn = MilliSatoshi(1100000), amountOut = MilliSatoshi(1000000))
sender.send(relayer, Status.Failure(AddHtlcFailed(channelId_bc, paymentHash, ExpiryTooSmall(channelId_bc, 100, 0, 0), origin, Some(channelUpdate_bc), None)))
assert(register.expectMsgType[Register.Forward[CMD_FAIL_HTLC]].message.reason === Right(ExpiryTooSoon(channelUpdate_bc)))
@@ -358,7 +358,7 @@ class RelayerSpec extends TestkitBaseClass {
sender.send(relayer, Status.Failure(AddHtlcFailed(channelId_bc, paymentHash, ExpiryTooBig(channelId_bc, 100, 200, 0), origin, Some(channelUpdate_bc), None)))
assert(register.expectMsgType[Register.Forward[CMD_FAIL_HTLC]].message.reason === Right(ExpiryTooFar))
- sender.send(relayer, Status.Failure(AddHtlcFailed(channelId_bc, paymentHash, InsufficientFunds(channelId_bc, origin.amountMsatOut, 100, 0, 0), origin, Some(channelUpdate_bc), None)))
+ sender.send(relayer, Status.Failure(AddHtlcFailed(channelId_bc, paymentHash, InsufficientFunds(channelId_bc, origin.amountOut, Satoshi(100), Satoshi(0), Satoshi(0)), origin, Some(channelUpdate_bc), None)))
assert(register.expectMsgType[Register.Forward[CMD_FAIL_HTLC]].message.reason === Right(TemporaryChannelFailure(channelUpdate_bc)))
val channelUpdate_bc_disabled = channelUpdate_bc.copy(channelFlags = 2)
@@ -383,9 +383,9 @@ class RelayerSpec extends TestkitBaseClass {
system.eventStream.subscribe(eventListener.ref, classOf[PaymentEvent])
// we build a fake htlc for the downstream channel
- val add_bc = UpdateAddHtlc(channelId = channelId_bc, id = 72, amountMsat = 10000000L, paymentHash = ByteVector32.Zeroes, cltvExpiry = 4200, onionRoutingPacket = TestConstants.emptyOnionPacket)
+ val add_bc = UpdateAddHtlc(channelId = channelId_bc, id = 72, amountMsat = MilliSatoshi(10000000L), paymentHash = ByteVector32.Zeroes, cltvExpiry = 4200, onionRoutingPacket = TestConstants.emptyOnionPacket)
val fulfill_ba = UpdateFulfillHtlc(channelId = channelId_bc, id = 42, paymentPreimage = ByteVector32.Zeroes)
- val origin = Relayed(channelId_ab, 150, 11000000L, 10000000L)
+ val origin = Relayed(channelId_ab, 150, MilliSatoshi(11000000L), MilliSatoshi(10000000L))
sender.send(relayer, ForwardFulfill(fulfill_ba, origin, add_bc))
val fwd = register.expectMsgType[Register.Forward[CMD_FULFILL_HTLC]]
@@ -393,7 +393,7 @@ class RelayerSpec extends TestkitBaseClass {
assert(fwd.message.id === origin.originHtlcId)
val paymentRelayed = eventListener.expectMsgType[PaymentRelayed]
- assert(paymentRelayed.copy(timestamp = 0) === PaymentRelayed(MilliSatoshi(origin.amountMsatIn), MilliSatoshi(origin.amountMsatOut), add_bc.paymentHash, channelId_ab, channelId_bc, timestamp = 0))
+ assert(paymentRelayed.copy(timestamp = 0) === PaymentRelayed(origin.amountIn, origin.amountOut, add_bc.paymentHash, channelId_ab, channelId_bc, timestamp = 0))
}
test("relay an htlc-fail") { f =>
@@ -401,9 +401,9 @@ class RelayerSpec extends TestkitBaseClass {
val sender = TestProbe()
// we build a fake htlc for the downstream channel
- val add_bc = UpdateAddHtlc(channelId = channelId_bc, id = 72, amountMsat = 10000000L, paymentHash = ByteVector32.Zeroes, cltvExpiry = 4200, onionRoutingPacket = TestConstants.emptyOnionPacket)
+ val add_bc = UpdateAddHtlc(channelId = channelId_bc, id = 72, amountMsat = MilliSatoshi(10000000L), paymentHash = ByteVector32.Zeroes, cltvExpiry = 4200, onionRoutingPacket = TestConstants.emptyOnionPacket)
val fail_ba = UpdateFailHtlc(channelId = channelId_bc, id = 42, reason = Sphinx.FailurePacket.create(ByteVector32(ByteVector.fill(32)(1)), TemporaryChannelFailure(channelUpdate_cd)))
- val origin = Relayed(channelId_ab, 150, 11000000L, 10000000L)
+ val origin = Relayed(channelId_ab, 150, MilliSatoshi(11000000L), MilliSatoshi(10000000L))
sender.send(relayer, ForwardFail(fail_ba, origin, add_bc))
val fwd = register.expectMsgType[Register.Forward[CMD_FAIL_HTLC]]
@@ -414,31 +414,31 @@ class RelayerSpec extends TestkitBaseClass {
test("get usable balances") { f =>
import f._
val sender = TestProbe()
- relayer ! LocalChannelUpdate(null, channelId_ab, channelUpdate_ab.shortChannelId, a, None, channelUpdate_ab, makeCommitments(channelId_ab, -2000, 300000))
- relayer ! LocalChannelUpdate(null, channelId_bc, channelUpdate_bc.shortChannelId, c, None, channelUpdate_bc, makeCommitments(channelId_bc, 400000, -5000))
+ relayer ! LocalChannelUpdate(null, channelId_ab, channelUpdate_ab.shortChannelId, a, None, channelUpdate_ab, makeCommitments(channelId_ab, MilliSatoshi(-2000), MilliSatoshi(300000)))
+ relayer ! LocalChannelUpdate(null, channelId_bc, channelUpdate_bc.shortChannelId, c, None, channelUpdate_bc, makeCommitments(channelId_bc, MilliSatoshi(400000), MilliSatoshi(-5000)))
sender.send(relayer, GetUsableBalances)
val usableBalances1 = sender.expectMsgType[Iterable[UsableBalances]]
assert(usableBalances1.size === 2)
- assert(usableBalances1.head.canSendMsat === 0 && usableBalances1.head.canReceiveMsat === 300000 && usableBalances1.head.shortChannelId == channelUpdate_ab.shortChannelId)
- assert(usableBalances1.last.canReceiveMsat === 0 && usableBalances1.last.canSendMsat === 400000 && usableBalances1.last.shortChannelId == channelUpdate_bc.shortChannelId)
+ assert(usableBalances1.head.canSend === MilliSatoshi(0) && usableBalances1.head.canReceive === MilliSatoshi(300000) && usableBalances1.head.shortChannelId == channelUpdate_ab.shortChannelId)
+ assert(usableBalances1.last.canReceive === MilliSatoshi(0) && usableBalances1.last.canSend === MilliSatoshi(400000) && usableBalances1.last.shortChannelId == channelUpdate_bc.shortChannelId)
- relayer ! AvailableBalanceChanged(null, channelId_bc, channelUpdate_bc.shortChannelId, 0, makeCommitments(channelId_bc, 200000, 500000))
+ relayer ! AvailableBalanceChanged(null, channelId_bc, channelUpdate_bc.shortChannelId, MilliSatoshi(0), makeCommitments(channelId_bc, MilliSatoshi(200000), MilliSatoshi(500000)))
sender.send(relayer, GetUsableBalances)
val usableBalances2 = sender.expectMsgType[Iterable[UsableBalances]]
- assert(usableBalances2.last.canReceiveMsat === 500000 && usableBalances2.last.canSendMsat === 200000)
+ assert(usableBalances2.last.canReceive === MilliSatoshi(500000) && usableBalances2.last.canSend === MilliSatoshi(200000))
- relayer ! AvailableBalanceChanged(null, channelId_ab, channelUpdate_ab.shortChannelId, 0, makeCommitments(channelId_ab, 100000, 200000))
+ relayer ! AvailableBalanceChanged(null, channelId_ab, channelUpdate_ab.shortChannelId, MilliSatoshi(0), makeCommitments(channelId_ab, MilliSatoshi(100000), MilliSatoshi(200000)))
relayer ! LocalChannelDown(null, channelId_bc, channelUpdate_bc.shortChannelId, c)
sender.send(relayer, GetUsableBalances)
val usableBalances3 = sender.expectMsgType[Iterable[UsableBalances]]
- assert(usableBalances3.size === 1 && usableBalances3.head.canSendMsat === 100000)
+ assert(usableBalances3.size === 1 && usableBalances3.head.canSend === MilliSatoshi(100000))
- relayer ! LocalChannelUpdate(null, channelId_ab, channelUpdate_ab.shortChannelId, a, None, channelUpdate_ab.copy(channelFlags = 2), makeCommitments(channelId_ab, 100000, 200000))
+ relayer ! LocalChannelUpdate(null, channelId_ab, channelUpdate_ab.shortChannelId, a, None, channelUpdate_ab.copy(channelFlags = 2), makeCommitments(channelId_ab, MilliSatoshi(100000), MilliSatoshi(200000)))
sender.send(relayer, GetUsableBalances)
val usableBalances4 = sender.expectMsgType[Iterable[UsableBalances]]
assert(usableBalances4.isEmpty)
- relayer ! LocalChannelUpdate(null, channelId_ab, channelUpdate_ab.shortChannelId, a, None, channelUpdate_ab, makeCommitments(channelId_ab, 100000, 200000))
+ relayer ! LocalChannelUpdate(null, channelId_ab, channelUpdate_ab.shortChannelId, a, None, channelUpdate_ab, makeCommitments(channelId_ab, MilliSatoshi(100000), MilliSatoshi(200000)))
sender.send(relayer, GetUsableBalances)
val usableBalances5 = sender.expectMsgType[Iterable[UsableBalances]]
assert(usableBalances5.size === 1)
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/router/AnnouncementsBatchValidationSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/router/AnnouncementsBatchValidationSpec.scala
index 0667d2a7bd..a3c29fda8e 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/router/AnnouncementsBatchValidationSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/router/AnnouncementsBatchValidationSpec.scala
@@ -27,10 +27,9 @@ import fr.acinq.eclair.blockchain.bitcoind.BitcoinCoreWallet
import fr.acinq.eclair.blockchain.bitcoind.rpc.{BasicBitcoinJsonRPCClient, ExtendedBitcoinClient}
import fr.acinq.eclair.transactions.Scripts
import fr.acinq.eclair.wire.{ChannelAnnouncement, ChannelUpdate}
-import fr.acinq.eclair.{ShortChannelId, randomKey}
+import fr.acinq.eclair.{MilliSatoshi, ShortChannelId, randomKey}
import org.scalatest.FunSuite
import scodec.bits.ByteVector
-
import scala.concurrent.duration._
import scala.concurrent.{Await, ExecutionContext}
@@ -104,6 +103,6 @@ object AnnouncementsBatchValidationSpec {
}
def makeChannelUpdate(c: SimulatedChannel, shortChannelId: ShortChannelId): ChannelUpdate =
- Announcements.makeChannelUpdate(Block.RegtestGenesisBlock.hash, c.node1Key, c.node2Key.publicKey, shortChannelId, 10, 1000, 10, 100, 500000000L)
+ Announcements.makeChannelUpdate(Block.RegtestGenesisBlock.hash, c.node1Key, c.node2Key.publicKey, shortChannelId, 10, MilliSatoshi(1000), MilliSatoshi(10), 100, MilliSatoshi(500000000L))
}
\ No newline at end of file
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/router/AnnouncementsSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/router/AnnouncementsSpec.scala
index d64bfab29f..41b5c722f1 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/router/AnnouncementsSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/router/AnnouncementsSpec.scala
@@ -16,7 +16,7 @@
package fr.acinq.eclair.router
-import fr.acinq.bitcoin.Block
+import fr.acinq.bitcoin.{Block}
import fr.acinq.bitcoin.Crypto.{PrivateKey, PublicKey}
import fr.acinq.eclair.TestConstants.Alice
import fr.acinq.eclair._
@@ -55,7 +55,7 @@ class AnnouncementsSpec extends FunSuite {
}
test("create valid signed channel update announcement") {
- val ann = makeChannelUpdate(Block.RegtestGenesisBlock.hash, Alice.nodeParams.privateKey, randomKey.publicKey, ShortChannelId(45561L), Alice.nodeParams.expiryDeltaBlocks, Alice.nodeParams.htlcMinimumMsat, Alice.nodeParams.feeBaseMsat, Alice.nodeParams.feeProportionalMillionth, 500000000L)
+ val ann = makeChannelUpdate(Block.RegtestGenesisBlock.hash, Alice.nodeParams.privateKey, randomKey.publicKey, ShortChannelId(45561L), Alice.nodeParams.expiryDeltaBlocks, Alice.nodeParams.htlcMinimum, Alice.nodeParams.feeBase, Alice.nodeParams.feeProportionalMillionth, MilliSatoshi(500000000L))
assert(checkSig(ann, Alice.nodeParams.nodeId))
assert(checkSig(ann, randomKey.publicKey) === false)
}
@@ -66,10 +66,10 @@ class AnnouncementsSpec extends FunSuite {
// NB: node1 < node2 (public keys)
assert(isNode1(node1_priv.publicKey, node2_priv.publicKey))
assert(!isNode1(node2_priv.publicKey, node1_priv.publicKey))
- val channelUpdate1 = makeChannelUpdate(Block.RegtestGenesisBlock.hash, node1_priv, node2_priv.publicKey, ShortChannelId(0), 0, 0, 0, 0, 500000000L, enable = true)
- val channelUpdate1_disabled = makeChannelUpdate(Block.RegtestGenesisBlock.hash, node1_priv, node2_priv.publicKey, ShortChannelId(0), 0, 0, 0, 0, 500000000L, enable = false)
- val channelUpdate2 = makeChannelUpdate(Block.RegtestGenesisBlock.hash, node2_priv, node1_priv.publicKey, ShortChannelId(0), 0, 0, 0, 0, 500000000L, enable = true)
- val channelUpdate2_disabled = makeChannelUpdate(Block.RegtestGenesisBlock.hash, node2_priv, node1_priv.publicKey, ShortChannelId(0), 0, 0, 0, 0, 500000000L, enable = false)
+ val channelUpdate1 = makeChannelUpdate(Block.RegtestGenesisBlock.hash, node1_priv, node2_priv.publicKey, ShortChannelId(0), 0, MilliSatoshi(0), MilliSatoshi(0), 0, MilliSatoshi(500000000L), enable = true)
+ val channelUpdate1_disabled = makeChannelUpdate(Block.RegtestGenesisBlock.hash, node1_priv, node2_priv.publicKey, ShortChannelId(0), 0, MilliSatoshi(0), MilliSatoshi(0), 0, MilliSatoshi(500000000L), enable = false)
+ val channelUpdate2 = makeChannelUpdate(Block.RegtestGenesisBlock.hash, node2_priv, node1_priv.publicKey, ShortChannelId(0), 0, MilliSatoshi(0), MilliSatoshi(0), 0, MilliSatoshi(500000000L), enable = true)
+ val channelUpdate2_disabled = makeChannelUpdate(Block.RegtestGenesisBlock.hash, node2_priv, node1_priv.publicKey, ShortChannelId(0), 0, MilliSatoshi(0), MilliSatoshi(0), 0, MilliSatoshi(500000000L), enable = false)
assert(channelUpdate1.channelFlags == 0) // ....00
assert(channelUpdate1_disabled.channelFlags == 2) // ....10
assert(channelUpdate2.channelFlags == 1) // ....01
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/router/BaseRouterSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/router/BaseRouterSpec.scala
index fc63698bb1..4acdc1db69 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/router/BaseRouterSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/router/BaseRouterSpec.scala
@@ -78,14 +78,14 @@ abstract class BaseRouterSpec extends TestkitBaseClass {
val chan_cd = channelAnnouncement(channelId_cd, priv_c, priv_d, priv_funding_c, priv_funding_d)
val chan_ef = channelAnnouncement(channelId_ef, priv_e, priv_f, priv_funding_e, priv_funding_f)
- val channelUpdate_ab = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv_a, b, channelId_ab, cltvExpiryDelta = 7, htlcMinimumMsat = 0, feeBaseMsat = 10, feeProportionalMillionths = 10, htlcMaximumMsat = 500000000L)
- val channelUpdate_ba = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv_b, a, channelId_ab, cltvExpiryDelta = 7, htlcMinimumMsat = 0, feeBaseMsat = 10, feeProportionalMillionths = 10, htlcMaximumMsat = 500000000L)
- val channelUpdate_bc = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv_b, c, channelId_bc, cltvExpiryDelta = 5, htlcMinimumMsat = 0, feeBaseMsat = 10, feeProportionalMillionths = 1, htlcMaximumMsat = 500000000L)
- val channelUpdate_cb = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv_c, b, channelId_bc, cltvExpiryDelta = 5, htlcMinimumMsat = 0, feeBaseMsat = 10, feeProportionalMillionths = 1, htlcMaximumMsat = 500000000L)
- val channelUpdate_cd = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv_c, d, channelId_cd, cltvExpiryDelta = 3, htlcMinimumMsat = 0, feeBaseMsat = 10, feeProportionalMillionths = 4, htlcMaximumMsat = 500000000L)
- val channelUpdate_dc = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv_d, c, channelId_cd, cltvExpiryDelta = 3, htlcMinimumMsat = 0, feeBaseMsat = 10, feeProportionalMillionths = 4, htlcMaximumMsat = 500000000L)
- val channelUpdate_ef = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv_e, f, channelId_ef, cltvExpiryDelta = 9, htlcMinimumMsat = 0, feeBaseMsat = 10, feeProportionalMillionths = 8, htlcMaximumMsat = 500000000L)
- val channelUpdate_fe = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv_f, e, channelId_ef, cltvExpiryDelta = 9, htlcMinimumMsat = 0, feeBaseMsat = 10, feeProportionalMillionths = 8, htlcMaximumMsat = 500000000L)
+ val channelUpdate_ab = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv_a, b, channelId_ab, cltvExpiryDelta = 7, htlcMinimumMsat = MilliSatoshi(0), feeBaseMsat = MilliSatoshi(10), feeProportionalMillionths = 10, htlcMaximumMsat = MilliSatoshi(500000000L))
+ val channelUpdate_ba = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv_b, a, channelId_ab, cltvExpiryDelta = 7, htlcMinimumMsat = MilliSatoshi(0), feeBaseMsat = MilliSatoshi(10), feeProportionalMillionths = 10, htlcMaximumMsat = MilliSatoshi(500000000L))
+ val channelUpdate_bc = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv_b, c, channelId_bc, cltvExpiryDelta = 5, htlcMinimumMsat = MilliSatoshi(0), feeBaseMsat = MilliSatoshi(10), feeProportionalMillionths = 1, htlcMaximumMsat = MilliSatoshi(500000000L))
+ val channelUpdate_cb = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv_c, b, channelId_bc, cltvExpiryDelta = 5, htlcMinimumMsat = MilliSatoshi(0), feeBaseMsat = MilliSatoshi(10), feeProportionalMillionths = 1, htlcMaximumMsat = MilliSatoshi(500000000L))
+ val channelUpdate_cd = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv_c, d, channelId_cd, cltvExpiryDelta = 3, htlcMinimumMsat = MilliSatoshi(0), feeBaseMsat = MilliSatoshi(10), feeProportionalMillionths = 4, htlcMaximumMsat = MilliSatoshi(500000000L))
+ val channelUpdate_dc = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv_d, c, channelId_cd, cltvExpiryDelta = 3, htlcMinimumMsat = MilliSatoshi(0), feeBaseMsat = MilliSatoshi(10), feeProportionalMillionths = 4, htlcMaximumMsat = MilliSatoshi(500000000L))
+ val channelUpdate_ef = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv_e, f, channelId_ef, cltvExpiryDelta = 9, htlcMinimumMsat = MilliSatoshi(0), feeBaseMsat = MilliSatoshi(10), feeProportionalMillionths = 8, htlcMaximumMsat = MilliSatoshi(500000000L))
+ val channelUpdate_fe = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv_f, e, channelId_ef, cltvExpiryDelta = 9, htlcMinimumMsat = MilliSatoshi(0), feeBaseMsat = MilliSatoshi(10), feeProportionalMillionths = 8, htlcMaximumMsat = MilliSatoshi(500000000L))
override def withFixture(test: OneArgTest): Outcome = {
// the network will be a --(1)--> b ---(2)--> c --(3)--> d and e --(4)--> f (we are a)
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/router/GraphSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/router/GraphSpec.scala
index 85c0e2ce82..9730365850 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/router/GraphSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/router/GraphSpec.scala
@@ -17,7 +17,7 @@
package fr.acinq.eclair.router
import fr.acinq.bitcoin.Crypto.PublicKey
-import fr.acinq.eclair.ShortChannelId
+import fr.acinq.eclair.{MilliSatoshi, ShortChannelId}
import fr.acinq.eclair.router.Graph.GraphStructure.{DirectedGraph, GraphEdge}
import fr.acinq.eclair.router.RouteCalculationSpec._
import fr.acinq.eclair.wire.ChannelUpdate
@@ -46,12 +46,12 @@ class GraphSpec extends FunSuite {
def makeTestGraph() = {
val updates = Seq(
- makeUpdate(1L, a, b, 0, 0),
- makeUpdate(2L, b, c, 0, 0),
- makeUpdate(3L, a, d, 0, 0),
- makeUpdate(4L, d, c, 0, 0),
- makeUpdate(5L, c, e, 0, 0),
- makeUpdate(6L, b, e, 0, 0)
+ makeUpdate(1L, a, b, MilliSatoshi(0), 0),
+ makeUpdate(2L, b, c, MilliSatoshi(0), 0),
+ makeUpdate(3L, a, d, MilliSatoshi(0), 0),
+ makeUpdate(4L, d, c, MilliSatoshi(0), 0),
+ makeUpdate(5L, c, e, MilliSatoshi(0), 0),
+ makeUpdate(6L, b, e, MilliSatoshi(0), 0)
)
DirectedGraph.makeGraph(updates.toMap)
@@ -72,11 +72,11 @@ class GraphSpec extends FunSuite {
assert(otherGraph.vertexSet().size === 5)
// add some edges to the graph
- val (descAB, updateAB) = makeUpdate(1L, a, b, 0, 0)
- val (descBC, updateBC) = makeUpdate(2L, b, c, 0, 0)
- val (descAD, updateAD) = makeUpdate(3L, a, d, 0, 0)
- val (descDC, updateDC) = makeUpdate(4L, d, c, 0, 0)
- val (descCE, updateCE) = makeUpdate(5L, c, e, 0, 0)
+ val (descAB, updateAB) = makeUpdate(1L, a, b, MilliSatoshi(0), 0)
+ val (descBC, updateBC) = makeUpdate(2L, b, c, MilliSatoshi(0), 0)
+ val (descAD, updateAD) = makeUpdate(3L, a, d, MilliSatoshi(0), 0)
+ val (descDC, updateDC) = makeUpdate(4L, d, c, MilliSatoshi(0), 0)
+ val (descCE, updateCE) = makeUpdate(5L, c, e, MilliSatoshi(0), 0)
val graphWithEdges = graph
.addEdge(descAB, updateAB)
@@ -98,12 +98,12 @@ class GraphSpec extends FunSuite {
test("instantiate a graph adding edges only") {
- val edgeAB = edgeFromDesc(makeUpdate(1L, a, b, 0, 0))
- val (descBC, updateBC) = makeUpdate(2L, b, c, 0, 0)
- val (descAD, updateAD) = makeUpdate(3L, a, d, 0, 0)
- val (descDC, updateDC) = makeUpdate(4L, d, c, 0, 0)
- val (descCE, updateCE) = makeUpdate(5L, c, e, 0, 0)
- val (descBE, updateBE) = makeUpdate(6L, b, e, 0, 0)
+ val edgeAB = edgeFromDesc(makeUpdate(1L, a, b, MilliSatoshi(0), 0))
+ val (descBC, updateBC) = makeUpdate(2L, b, c, MilliSatoshi(0), 0)
+ val (descAD, updateAD) = makeUpdate(3L, a, d, MilliSatoshi(0), 0)
+ val (descDC, updateDC) = makeUpdate(4L, d, c, MilliSatoshi(0), 0)
+ val (descCE, updateCE) = makeUpdate(5L, c, e, MilliSatoshi(0), 0)
+ val (descBE, updateBE) = makeUpdate(6L, b, e, MilliSatoshi(0), 0)
val graph = DirectedGraph(edgeAB)
.addEdge(descAD, updateAD)
@@ -121,10 +121,10 @@ class GraphSpec extends FunSuite {
test("containsEdge should return true if the graph contains that edge, false otherwise") {
val updates = Seq(
- makeUpdate(1L, a, b, 0, 0),
- makeUpdate(2L, b, c, 0, 0),
- makeUpdate(3L, c, d, 0, 0),
- makeUpdate(4L, d, e, 0, 0)
+ makeUpdate(1L, a, b, MilliSatoshi(0), 0),
+ makeUpdate(2L, b, c, MilliSatoshi(0), 0),
+ makeUpdate(3L, c, d, MilliSatoshi(0), 0),
+ makeUpdate(4L, d, e, MilliSatoshi(0), 0)
)
val graph = DirectedGraph().addEdges(updates)
@@ -144,10 +144,10 @@ class GraphSpec extends FunSuite {
val graph = makeTestGraph()
- val (descBE, _) = makeUpdate(6L, b, e, 0, 0)
- val (descCE, _) = makeUpdate(5L, c, e, 0, 0)
- val (descAD, _) = makeUpdate(3L, a, d, 0, 0)
- val (descDC, _) = makeUpdate(4L, d, c, 0, 0)
+ val (descBE, _) = makeUpdate(6L, b, e, MilliSatoshi(0), 0)
+ val (descCE, _) = makeUpdate(5L, c, e, MilliSatoshi(0), 0)
+ val (descAD, _) = makeUpdate(3L, a, d, MilliSatoshi(0), 0)
+ val (descDC, _) = makeUpdate(4L, d, c, MilliSatoshi(0), 0)
assert(graph.edgeSet().size === 6)
@@ -168,8 +168,8 @@ class GraphSpec extends FunSuite {
// contains an edge A --> B
val updates = Seq(
- makeUpdate(1L, a, b, 0, 0),
- makeUpdate(2L, b, c, 0, 0)
+ makeUpdate(1L, a, b, MilliSatoshi(0), 0),
+ makeUpdate(2L, b, c, MilliSatoshi(0), 0)
)
val graph = DirectedGraph().addEdges(updates)
@@ -199,19 +199,19 @@ class GraphSpec extends FunSuite {
assert(graph.edgesOf(a).size == 2)
//now add a new edge a -> b but with a different channel update and a different ShortChannelId
- val newEdgeForNewChannel = edgeFromDesc(makeUpdate(15L, a, b, 20, 0))
+ val newEdgeForNewChannel = edgeFromDesc(makeUpdate(15L, a, b, MilliSatoshi(20), 0))
val mutatedGraph = graph.addEdge(newEdgeForNewChannel)
assert(mutatedGraph.edgesOf(a).size == 3)
//if the ShortChannelId is the same we replace the edge and the update, this edge have an update with a different 'feeBaseMsat'
- val edgeForTheSameChannel = edgeFromDesc(makeUpdate(15L, a, b, 30, 0))
+ val edgeForTheSameChannel = edgeFromDesc(makeUpdate(15L, a, b, MilliSatoshi(30), 0))
val mutatedGraph2 = mutatedGraph.addEdge(edgeForTheSameChannel)
assert(mutatedGraph2.edgesOf(a).size == 3) // A --> B , A --> B , A --> D
assert(mutatedGraph2.getEdgesBetween(a, b).size === 2)
- assert(mutatedGraph2.getEdge(edgeForTheSameChannel).get.update.feeBaseMsat === 30)
+ assert(mutatedGraph2.getEdge(edgeForTheSameChannel).get.update.feeBaseMsat === MilliSatoshi(30))
}
test("remove a vertex with incoming edges and check those edges are removed too") {
@@ -234,11 +234,11 @@ class GraphSpec extends FunSuite {
def edgeFromDesc(tuple: (ChannelDesc, ChannelUpdate)): GraphEdge = GraphEdge(tuple._1, tuple._2)
def descFromNodes(shortChannelId: Long, a: PublicKey, b: PublicKey): ChannelDesc = {
- makeUpdate(shortChannelId, a, b, 0, 0)._1
+ makeUpdate(shortChannelId, a, b, MilliSatoshi(0), 0)._1
}
def edgeFromNodes(shortChannelId: Long, a: PublicKey, b: PublicKey): GraphEdge = {
- edgeFromDesc(makeUpdate(shortChannelId, a, b, 0, 0))
+ edgeFromDesc(makeUpdate(shortChannelId, a, b, MilliSatoshi(0), 0))
}
}
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/router/RouteCalculationSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/router/RouteCalculationSpec.scala
index c09fd82df1..c4930b0bdd 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/router/RouteCalculationSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/router/RouteCalculationSpec.scala
@@ -24,7 +24,7 @@ import fr.acinq.eclair.router.Graph.GraphStructure.{DirectedGraph, GraphEdge}
import fr.acinq.eclair.router.Graph.{RichWeight, WeightRatios}
import fr.acinq.eclair.transactions.Transactions
import fr.acinq.eclair.wire._
-import fr.acinq.eclair.{Globals, ShortChannelId, randomKey}
+import fr.acinq.eclair.{Globals, MilliSatoshi, ShortChannelId, randomKey}
import org.scalatest.FunSuite
import scodec.bits._
@@ -43,10 +43,10 @@ class RouteCalculationSpec extends FunSuite {
test("calculate simple route") {
val updates = List(
- makeUpdate(1L, a, b, 1, 10, cltvDelta = 1),
- makeUpdate(2L, b, c, 1, 10, cltvDelta = 1),
- makeUpdate(3L, c, d, 1, 10, cltvDelta = 1),
- makeUpdate(4L, d, e, 1, 10, cltvDelta = 1)
+ makeUpdate(1L, a, b, MilliSatoshi(1), 10, cltvDelta = 1),
+ makeUpdate(2L, b, c, MilliSatoshi(1), 10, cltvDelta = 1),
+ makeUpdate(3L, c, d, MilliSatoshi(1), 10, cltvDelta = 1),
+ makeUpdate(4L, d, e, MilliSatoshi(1), 10, cltvDelta = 1)
).toMap
val g = makeGraph(updates)
@@ -75,43 +75,43 @@ class RouteCalculationSpec extends FunSuite {
// cost(AE) = 10007 -> A is source, shortest path found
// cost(AB) = 10009
- val amountMsat = 10000
- val expectedCost = 10007
+ val amount = MilliSatoshi(10000)
+ val expectedCost = MilliSatoshi(10007)
val updates = List(
- makeUpdate(1L, a, b, feeBaseMsat = 1, feeProportionalMillionth = 200, minHtlcMsat = 0),
- makeUpdate(4L, a, e, feeBaseMsat = 1, feeProportionalMillionth = 200, minHtlcMsat = 0),
- makeUpdate(2L, b, c, feeBaseMsat = 1, feeProportionalMillionth = 300, minHtlcMsat = 0),
- makeUpdate(3L, c, d, feeBaseMsat = 1, feeProportionalMillionth = 400, minHtlcMsat = 0),
- makeUpdate(5L, e, f, feeBaseMsat = 1, feeProportionalMillionth = 400, minHtlcMsat = 0),
- makeUpdate(6L, f, d, feeBaseMsat = 1, feeProportionalMillionth = 100, minHtlcMsat = 0)
+ makeUpdate(1L, a, b, feeBase = MilliSatoshi(1), feeProportionalMillionth = 200, minHtlc = MilliSatoshi(0)),
+ makeUpdate(4L, a, e, feeBase = MilliSatoshi(1), feeProportionalMillionth = 200, minHtlc = MilliSatoshi(0)),
+ makeUpdate(2L, b, c, feeBase = MilliSatoshi(1), feeProportionalMillionth = 300, minHtlc = MilliSatoshi(0)),
+ makeUpdate(3L, c, d, feeBase = MilliSatoshi(1), feeProportionalMillionth = 400, minHtlc = MilliSatoshi(0)),
+ makeUpdate(5L, e, f, feeBase = MilliSatoshi(1), feeProportionalMillionth = 400, minHtlc = MilliSatoshi(0)),
+ makeUpdate(6L, f, d, feeBase = MilliSatoshi(1), feeProportionalMillionth = 100, minHtlc = MilliSatoshi(0))
).toMap
val graph = makeGraph(updates)
- val Success(route) = Router.findRoute(graph, a, d, amountMsat, numRoutes = 1, routeParams = DEFAULT_ROUTE_PARAMS)
+ val Success(route) = Router.findRoute(graph, a, d, amount, numRoutes = 1, routeParams = DEFAULT_ROUTE_PARAMS)
- val totalCost = Graph.pathWeight(hops2Edges(route), amountMsat, false, 0, None).cost
+ val totalCost = Graph.pathWeight(hops2Edges(route), amount, false, 0, None).cost
assert(hops2Ids(route) === 4 :: 5 :: 6 :: Nil)
assert(totalCost === expectedCost)
// now channel 5 could route the amount (10000) but not the amount + fees (10007)
- val (desc, update) = makeUpdate(5L, e, f, feeBaseMsat = 1, feeProportionalMillionth = 400, minHtlcMsat = 0, maxHtlcMsat = Some(10005L))
+ val (desc, update) = makeUpdate(5L, e, f, feeBase = MilliSatoshi(1), feeProportionalMillionth = 400, minHtlc = MilliSatoshi(0), maxHtlc = Some(MilliSatoshi(10005L)))
val graph1 = graph.addEdge(desc, update)
- val Success(route1) = Router.findRoute(graph1, a, d, amountMsat, numRoutes = 1, routeParams = DEFAULT_ROUTE_PARAMS)
+ val Success(route1) = Router.findRoute(graph1, a, d, amount, numRoutes = 1, routeParams = DEFAULT_ROUTE_PARAMS)
assert(hops2Ids(route1) === 1 :: 2 :: 3 :: Nil)
}
test("calculate route considering the direct channel pays no fees") {
val updates = List(
- makeUpdate(1L, a, b, 5, 0), // a -> b
- makeUpdate(2L, a, d, 15, 0), // a -> d this goes a bit closer to the target and asks for higher fees but is a direct channel
- makeUpdate(3L, b, c, 5, 0), // b -> c
- makeUpdate(4L, c, d, 5, 0), // c -> d
- makeUpdate(5L, d, e, 5, 0) // d -> e
+ makeUpdate(1L, a, b, MilliSatoshi(5), 0), // a -> b
+ makeUpdate(2L, a, d, MilliSatoshi(15), 0), // a -> d this goes a bit closer to the target and asks for higher fees but is a direct channel
+ makeUpdate(3L, b, c, MilliSatoshi(5), 0), // b -> c
+ makeUpdate(4L, c, d, MilliSatoshi(5), 0), // c -> d
+ makeUpdate(5L, d, e, MilliSatoshi(5), 0) // d -> e
).toMap
val g = makeGraph(updates)
@@ -123,10 +123,10 @@ class RouteCalculationSpec extends FunSuite {
test("calculate simple route (add and remove edges") {
val updates = List(
- makeUpdate(1L, a, b, 0, 0),
- makeUpdate(2L, b, c, 0, 0),
- makeUpdate(3L, c, d, 0, 0),
- makeUpdate(4L, d, e, 0, 0)
+ makeUpdate(1L, a, b, MilliSatoshi(0), 0),
+ makeUpdate(2L, b, c, MilliSatoshi(0), 0),
+ makeUpdate(3L, c, d, MilliSatoshi(0), 0),
+ makeUpdate(4L, d, e, MilliSatoshi(0), 0)
).toMap
val g = makeGraph(updates)
@@ -149,10 +149,10 @@ class RouteCalculationSpec extends FunSuite {
)
val updates = List(
- makeUpdate(1L, f, g, 0, 0),
- makeUpdate(2L, g, h, 0, 0),
- makeUpdate(3L, h, i, 0, 0),
- makeUpdate(4L, f, h, 50, 0) // more expensive
+ makeUpdate(1L, f, g, MilliSatoshi(0), 0),
+ makeUpdate(2L, g, h, MilliSatoshi(0), 0),
+ makeUpdate(3L, h, i, MilliSatoshi(0), 0),
+ makeUpdate(4L, f, h, MilliSatoshi(50), 0) // more expensive
).toMap
val graph = makeGraph(updates)
@@ -172,10 +172,10 @@ class RouteCalculationSpec extends FunSuite {
)
val updates = List(
- makeUpdate(1L, f, g, 0, 0),
- makeUpdate(4L, f, i, 50, 0), // our starting node F has a direct channel with I
- makeUpdate(2L, g, h, 0, 0),
- makeUpdate(3L, h, i, 0, 0)
+ makeUpdate(1L, f, g, MilliSatoshi(0), 0),
+ makeUpdate(4L, f, i, MilliSatoshi(50), 0), // our starting node F has a direct channel with I
+ makeUpdate(2L, g, h, MilliSatoshi(0), 0),
+ makeUpdate(3L, h, i, MilliSatoshi(0), 0)
).toMap
val graph = makeGraph(updates)
@@ -193,10 +193,10 @@ class RouteCalculationSpec extends FunSuite {
)
val updates = List(
- makeUpdate(1L, f, g, 1, 0),
+ makeUpdate(1L, f, g, MilliSatoshi(1), 0),
// the maximum htlc allowed by this channel is only 50msat greater than what we're sending
- makeUpdate(2L, g, h, 1, 0, maxHtlcMsat = Some(DEFAULT_AMOUNT_MSAT + 50)),
- makeUpdate(3L, h, i, 1, 0)
+ makeUpdate(2L, g, h, MilliSatoshi(1), 0, maxHtlc = Some(DEFAULT_AMOUNT_MSAT + MilliSatoshi(50))),
+ makeUpdate(3L, h, i, MilliSatoshi(1), 0)
).toMap
val graph = makeGraph(updates)
@@ -214,10 +214,10 @@ class RouteCalculationSpec extends FunSuite {
)
val updates = List(
- makeUpdate(1L, f, g, 1, 0),
+ makeUpdate(1L, f, g, MilliSatoshi(1), 0),
// this channel requires a minimum amount that is larger than what we are sending
- makeUpdate(2L, g, h, 1, 0, minHtlcMsat = DEFAULT_AMOUNT_MSAT + 50),
- makeUpdate(3L, h, i, 1, 0)
+ makeUpdate(2L, g, h, MilliSatoshi(1), 0, minHtlc = DEFAULT_AMOUNT_MSAT + MilliSatoshi(50)),
+ makeUpdate(3L, h, i, MilliSatoshi(1), 0)
).toMap
val graph = makeGraph(updates)
@@ -236,10 +236,10 @@ class RouteCalculationSpec extends FunSuite {
)
val updates = List(
- makeUpdate(1L, f, g, 0, 0),
- makeUpdate(2L, g, h, 5, 5), // expensive g -> h channel
- makeUpdate(6L, g, h, 0, 0), // cheap g -> h channel
- makeUpdate(3L, h, i, 0, 0)
+ makeUpdate(1L, f, g, MilliSatoshi(0), 0),
+ makeUpdate(2L, g, h, MilliSatoshi(5), 5), // expensive g -> h channel
+ makeUpdate(6L, g, h, MilliSatoshi(0), 0), // cheap g -> h channel
+ makeUpdate(3L, h, i, MilliSatoshi(0), 0)
).toMap
val graph = makeGraph(updates)
@@ -251,11 +251,11 @@ class RouteCalculationSpec extends FunSuite {
test("calculate longer but cheaper route") {
val updates = List(
- makeUpdate(1L, a, b, 0, 0),
- makeUpdate(2L, b, c, 0, 0),
- makeUpdate(3L, c, d, 0, 0),
- makeUpdate(4L, d, e, 0, 0),
- makeUpdate(5L, b, e, 10, 10)
+ makeUpdate(1L, a, b, MilliSatoshi(0), 0),
+ makeUpdate(2L, b, c, MilliSatoshi(0), 0),
+ makeUpdate(3L, c, d, MilliSatoshi(0), 0),
+ makeUpdate(4L, d, e, MilliSatoshi(0), 0),
+ makeUpdate(5L, b, e, MilliSatoshi(10), 10)
).toMap
val g = makeGraph(updates)
@@ -267,8 +267,8 @@ class RouteCalculationSpec extends FunSuite {
test("no local channels") {
val updates = List(
- makeUpdate(2L, b, c, 0, 0),
- makeUpdate(4L, d, e, 0, 0)
+ makeUpdate(2L, b, c, MilliSatoshi(0), 0),
+ makeUpdate(4L, d, e, MilliSatoshi(0), 0)
).toMap
val g = makeGraph(updates)
@@ -280,9 +280,9 @@ class RouteCalculationSpec extends FunSuite {
test("route not found") {
val updates = List(
- makeUpdate(1L, a, b, 0, 0),
- makeUpdate(2L, b, c, 0, 0),
- makeUpdate(4L, d, e, 0, 0)
+ makeUpdate(1L, a, b, MilliSatoshi(0), 0),
+ makeUpdate(2L, b, c, MilliSatoshi(0), 0),
+ makeUpdate(4L, d, e, MilliSatoshi(0), 0)
).toMap
val g = makeGraph(updates)
@@ -294,8 +294,8 @@ class RouteCalculationSpec extends FunSuite {
test("route not found (source OR target node not connected)") {
val updates = List(
- makeUpdate(2L, b, c, 0, 0),
- makeUpdate(4L, c, d, 0, 0)
+ makeUpdate(2L, b, c, MilliSatoshi(0), 0),
+ makeUpdate(4L, c, d, MilliSatoshi(0), 0)
).toMap
val g = makeGraph(updates).addVertex(a).addVertex(e)
@@ -310,15 +310,15 @@ class RouteCalculationSpec extends FunSuite {
val lowAmount = DEFAULT_AMOUNT_MSAT / 10
val updatesHi = List(
- makeUpdate(1L, a, b, 0, 0),
- makeUpdate(2L, b, c, 0, 0, maxHtlcMsat = Some(DEFAULT_AMOUNT_MSAT)),
- makeUpdate(3L, c, d, 0, 0)
+ makeUpdate(1L, a, b, MilliSatoshi(0), 0),
+ makeUpdate(2L, b, c, MilliSatoshi(0), 0, maxHtlc = Some(DEFAULT_AMOUNT_MSAT)),
+ makeUpdate(3L, c, d, MilliSatoshi(0), 0)
).toMap
val updatesLo = List(
- makeUpdate(1L, a, b, 0, 0),
- makeUpdate(2L, b, c, 0, 0, minHtlcMsat = DEFAULT_AMOUNT_MSAT),
- makeUpdate(3L, c, d, 0, 0)
+ makeUpdate(1L, a, b, MilliSatoshi(0), 0),
+ makeUpdate(2L, b, c, MilliSatoshi(0), 0, minHtlc = DEFAULT_AMOUNT_MSAT),
+ makeUpdate(3L, c, d, MilliSatoshi(0), 0)
).toMap
val g = makeGraph(updatesHi)
@@ -331,9 +331,9 @@ class RouteCalculationSpec extends FunSuite {
test("route to self") {
val updates = List(
- makeUpdate(1L, a, b, 0, 0),
- makeUpdate(2L, b, c, 0, 0),
- makeUpdate(3L, c, d, 0, 0)
+ makeUpdate(1L, a, b, MilliSatoshi(0), 0),
+ makeUpdate(2L, b, c, MilliSatoshi(0), 0),
+ makeUpdate(3L, c, d, MilliSatoshi(0), 0)
).toMap
val g = makeGraph(updates)
@@ -345,10 +345,10 @@ class RouteCalculationSpec extends FunSuite {
test("route to immediate neighbor") {
val updates = List(
- makeUpdate(1L, a, b, 0, 0),
- makeUpdate(2L, b, c, 0, 0),
- makeUpdate(3L, c, d, 0, 0),
- makeUpdate(4L, d, e, 0, 0)
+ makeUpdate(1L, a, b, MilliSatoshi(0), 0),
+ makeUpdate(2L, b, c, MilliSatoshi(0), 0),
+ makeUpdate(3L, c, d, MilliSatoshi(0), 0),
+ makeUpdate(4L, d, e, MilliSatoshi(0), 0)
).toMap
val g = makeGraph(updates)
@@ -359,10 +359,10 @@ class RouteCalculationSpec extends FunSuite {
test("directed graph") {
val updates = List(
- makeUpdate(1L, a, b, 0, 0),
- makeUpdate(2L, b, c, 0, 0),
- makeUpdate(3L, c, d, 0, 0),
- makeUpdate(4L, d, e, 0, 0)
+ makeUpdate(1L, a, b, MilliSatoshi(0), 0),
+ makeUpdate(2L, b, c, MilliSatoshi(0), 0),
+ makeUpdate(3L, c, d, MilliSatoshi(0), 0),
+ makeUpdate(4L, d, e, MilliSatoshi(0), 0)
).toMap
// a->e works, e->a fails
@@ -380,14 +380,14 @@ class RouteCalculationSpec extends FunSuite {
val DUMMY_SIG = Transactions.PlaceHolderSig
- val uab = ChannelUpdate(DUMMY_SIG, Block.RegtestGenesisBlock.hash, ShortChannelId(1L), 0L, 0, 0, 1, 42, 2500, 140, None)
- val uba = ChannelUpdate(DUMMY_SIG, Block.RegtestGenesisBlock.hash, ShortChannelId(1L), 1L, 0, 1, 1, 43, 2501, 141, None)
- val ubc = ChannelUpdate(DUMMY_SIG, Block.RegtestGenesisBlock.hash, ShortChannelId(2L), 1L, 0, 0, 1, 44, 2502, 142, None)
- val ucb = ChannelUpdate(DUMMY_SIG, Block.RegtestGenesisBlock.hash, ShortChannelId(2L), 1L, 0, 1, 1, 45, 2503, 143, None)
- val ucd = ChannelUpdate(DUMMY_SIG, Block.RegtestGenesisBlock.hash, ShortChannelId(3L), 1L, 1, 0, 1, 46, 2504, 144, Some(500000000L))
- val udc = ChannelUpdate(DUMMY_SIG, Block.RegtestGenesisBlock.hash, ShortChannelId(3L), 1L, 0, 1, 1, 47, 2505, 145, None)
- val ude = ChannelUpdate(DUMMY_SIG, Block.RegtestGenesisBlock.hash, ShortChannelId(4L), 1L, 0, 0, 1, 48, 2506, 146, None)
- val ued = ChannelUpdate(DUMMY_SIG, Block.RegtestGenesisBlock.hash, ShortChannelId(4L), 1L, 0, 1, 1, 49, 2507, 147, None)
+ val uab = ChannelUpdate(DUMMY_SIG, Block.RegtestGenesisBlock.hash, ShortChannelId(1L), 0L, 0, 0, 1, MilliSatoshi(42), MilliSatoshi(2500), 140, None)
+ val uba = ChannelUpdate(DUMMY_SIG, Block.RegtestGenesisBlock.hash, ShortChannelId(1L), 1L, 0, 1, 1, MilliSatoshi(43), MilliSatoshi(2501), 141, None)
+ val ubc = ChannelUpdate(DUMMY_SIG, Block.RegtestGenesisBlock.hash, ShortChannelId(2L), 1L, 0, 0, 1, MilliSatoshi(44), MilliSatoshi(2502), 142, None)
+ val ucb = ChannelUpdate(DUMMY_SIG, Block.RegtestGenesisBlock.hash, ShortChannelId(2L), 1L, 0, 1, 1, MilliSatoshi(45), MilliSatoshi(2503), 143, None)
+ val ucd = ChannelUpdate(DUMMY_SIG, Block.RegtestGenesisBlock.hash, ShortChannelId(3L), 1L, 1, 0, 1, MilliSatoshi(46), MilliSatoshi(2504), 144, Some(MilliSatoshi(500000000L)))
+ val udc = ChannelUpdate(DUMMY_SIG, Block.RegtestGenesisBlock.hash, ShortChannelId(3L), 1L, 0, 1, 1, MilliSatoshi(47), MilliSatoshi(2505), 145, None)
+ val ude = ChannelUpdate(DUMMY_SIG, Block.RegtestGenesisBlock.hash, ShortChannelId(4L), 1L, 0, 0, 1, MilliSatoshi(48), MilliSatoshi(2506), 146, None)
+ val ued = ChannelUpdate(DUMMY_SIG, Block.RegtestGenesisBlock.hash, ShortChannelId(4L), 1L, 0, 1, 1, MilliSatoshi(49), MilliSatoshi(2507), 147, None)
val updates = Map(
ChannelDesc(ShortChannelId(1L), a, b) -> uab,
@@ -434,10 +434,10 @@ class RouteCalculationSpec extends FunSuite {
test("blacklist routes") {
val updates = List(
- makeUpdate(1L, a, b, 0, 0),
- makeUpdate(2L, b, c, 0, 0),
- makeUpdate(3L, c, d, 0, 0),
- makeUpdate(4L, d, e, 0, 0)
+ makeUpdate(1L, a, b, MilliSatoshi(0), 0),
+ makeUpdate(2L, b, c, MilliSatoshi(0), 0),
+ makeUpdate(3L, c, d, MilliSatoshi(0), 0),
+ makeUpdate(4L, d, e, MilliSatoshi(0), 0)
).toMap
val g = makeGraph(updates)
@@ -446,7 +446,7 @@ class RouteCalculationSpec extends FunSuite {
assert(route1.map(hops2Ids) === Failure(RouteNotFound))
// verify that we left the graph untouched
- assert(g.containsEdge(makeUpdate(3L, c, d, 0, 0)._1)) // c -> d
+ assert(g.containsEdge(makeUpdate(3L, c, d, MilliSatoshi(0), 0)._1)) // c -> d
assert(g.containsVertex(c))
assert(g.containsVertex(d))
@@ -457,9 +457,9 @@ class RouteCalculationSpec extends FunSuite {
test("route to a destination that is not in the graph (with assisted routes)") {
val updates = List(
- makeUpdate(1L, a, b, 10, 10),
- makeUpdate(2L, b, c, 10, 10),
- makeUpdate(3L, c, d, 10, 10)
+ makeUpdate(1L, a, b, MilliSatoshi(10), 10),
+ makeUpdate(2L, b, c, MilliSatoshi(10), 10),
+ makeUpdate(3L, c, d, MilliSatoshi(10), 10)
).toMap
val g = makeGraph(updates)
@@ -468,7 +468,7 @@ class RouteCalculationSpec extends FunSuite {
assert(route.map(hops2Ids) === Failure(RouteNotFound))
// now we add the missing edge to reach the destination
- val (extraDesc, extraUpdate) = makeUpdate(4L, d, e, 5, 5)
+ val (extraDesc, extraUpdate) = makeUpdate(4L, d, e, MilliSatoshi(5), 5)
val extraGraphEdges = Set(GraphEdge(extraDesc, extraUpdate))
val route1 = Router.findRoute(g, a, e, DEFAULT_AMOUNT_MSAT, numRoutes = 1, extraEdges = extraGraphEdges, routeParams = DEFAULT_ROUTE_PARAMS)
@@ -478,25 +478,25 @@ class RouteCalculationSpec extends FunSuite {
test("verify that extra hops takes precedence over known channels") {
val updates = List(
- makeUpdate(1L, a, b, 10, 10),
- makeUpdate(2L, b, c, 10, 10),
- makeUpdate(3L, c, d, 10, 10),
- makeUpdate(4L, d, e, 10, 10)
+ makeUpdate(1L, a, b, MilliSatoshi(10), 10),
+ makeUpdate(2L, b, c, MilliSatoshi(10), 10),
+ makeUpdate(3L, c, d, MilliSatoshi(10), 10),
+ makeUpdate(4L, d, e, MilliSatoshi(10), 10)
).toMap
val g = makeGraph(updates)
val route1 = Router.findRoute(g, a, e, DEFAULT_AMOUNT_MSAT, numRoutes = 1, routeParams = DEFAULT_ROUTE_PARAMS)
assert(route1.map(hops2Ids) === Success(1 :: 2 :: 3 :: 4 :: Nil))
- assert(route1.get(1).lastUpdate.feeBaseMsat == 10)
+ assert(route1.get(1).lastUpdate.feeBaseMsat == MilliSatoshi(10))
- val (extraDesc, extraUpdate) = makeUpdate(2L, b, c, 5, 5)
+ val (extraDesc, extraUpdate) = makeUpdate(2L, b, c, MilliSatoshi(5), 5)
val extraGraphEdges = Set(GraphEdge(extraDesc, extraUpdate))
val route2 = Router.findRoute(g, a, e, DEFAULT_AMOUNT_MSAT, numRoutes = 1, extraEdges = extraGraphEdges, routeParams = DEFAULT_ROUTE_PARAMS)
assert(route2.map(hops2Ids) === Success(1 :: 2 :: 3 :: 4 :: Nil))
- assert(route2.get(1).lastUpdate.feeBaseMsat == 5)
+ assert(route2.get(1).lastUpdate.feeBaseMsat == MilliSatoshi(5))
}
test("compute ignored channels") {
@@ -519,15 +519,15 @@ class RouteCalculationSpec extends FunSuite {
)
val updates = List(
- makeUpdate(1L, a, b, 10, 10),
- makeUpdate(2L, b, c, 10, 10),
- makeUpdate(2L, c, b, 10, 10),
- makeUpdate(3L, c, d, 10, 10),
- makeUpdate(4L, d, e, 10, 10),
- makeUpdate(5L, f, g, 10, 10),
- makeUpdate(6L, f, h, 10, 10),
- makeUpdate(7L, h, i, 10, 10),
- makeUpdate(8L, i, j, 10, 10)
+ makeUpdate(1L, a, b, MilliSatoshi(10), 10),
+ makeUpdate(2L, b, c, MilliSatoshi(10), 10),
+ makeUpdate(2L, c, b, MilliSatoshi(10), 10),
+ makeUpdate(3L, c, d, MilliSatoshi(10), 10),
+ makeUpdate(4L, d, e, MilliSatoshi(10), 10),
+ makeUpdate(5L, f, g, MilliSatoshi(10), 10),
+ makeUpdate(6L, f, h, MilliSatoshi(10), 10),
+ makeUpdate(7L, h, i, MilliSatoshi(10), 10),
+ makeUpdate(8L, i, j, MilliSatoshi(10), 10)
).toMap
val ignored = Router.getIgnoredChannelDesc(updates, ignoreNodes = Set(c, j, randomKey.publicKey))
@@ -547,7 +547,7 @@ class RouteCalculationSpec extends FunSuite {
val updates = nodes
.zip(nodes.drop(1)) // (0, 1) :: (1, 2) :: ...
.zipWithIndex // ((0, 1), 0) :: ((1, 2), 1) :: ...
- .map { case ((na, nb), index) => makeUpdate(index, na, nb, 5, 0) }
+ .map { case ((na, nb), index) => makeUpdate(index, na, nb, MilliSatoshi(5), 0) }
.toMap
val g = makeGraph(updates)
@@ -565,10 +565,10 @@ class RouteCalculationSpec extends FunSuite {
val updates = nodes
.zip(nodes.drop(1)) // (0, 1) :: (1, 2) :: ...
.zipWithIndex // ((0, 1), 0) :: ((1, 2), 1) :: ...
- .map { case ((na, nb), index) => makeUpdate(index, na, nb, 1, 0) }
+ .map { case ((na, nb), index) => makeUpdate(index, na, nb, MilliSatoshi(1), 0) }
.toMap
- val updates2 = updates + makeUpdate(99, nodes(2), nodes(48), 1000, 0) // expensive shorter route
+ val updates2 = updates + makeUpdate(99, nodes(2), nodes(48), MilliSatoshi(1000), 0) // expensive shorter route
val g = makeGraph(updates2)
@@ -581,12 +581,12 @@ class RouteCalculationSpec extends FunSuite {
val f = randomKey.publicKey
val g = makeGraph(List(
- makeUpdate(1, a, b, feeBaseMsat = 1, 0, minHtlcMsat = 0, maxHtlcMsat = None, cltvDelta = 50),
- makeUpdate(2, b, c, feeBaseMsat = 1, 0, minHtlcMsat = 0, maxHtlcMsat = None, cltvDelta = 50),
- makeUpdate(3, c, d, feeBaseMsat = 1, 0, minHtlcMsat = 0, maxHtlcMsat = None, cltvDelta = 50),
- makeUpdate(4, a, e, feeBaseMsat = 1, 0, minHtlcMsat = 0, maxHtlcMsat = None, cltvDelta = 9),
- makeUpdate(5, e, f, feeBaseMsat = 5, 0, minHtlcMsat = 0, maxHtlcMsat = None, cltvDelta = 9),
- makeUpdate(6, f, d, feeBaseMsat = 5, 0, minHtlcMsat = 0, maxHtlcMsat = None, cltvDelta = 9)
+ makeUpdate(1, a, b, feeBase = MilliSatoshi(1), 0, minHtlc = MilliSatoshi(0), maxHtlc = None, cltvDelta = 50),
+ makeUpdate(2, b, c, feeBase = MilliSatoshi(1), 0, minHtlc = MilliSatoshi(0), maxHtlc = None, cltvDelta = 50),
+ makeUpdate(3, c, d, feeBase = MilliSatoshi(1), 0, minHtlc = MilliSatoshi(0), maxHtlc = None, cltvDelta = 50),
+ makeUpdate(4, a, e, feeBase = MilliSatoshi(1), 0, minHtlc = MilliSatoshi(0), maxHtlc = None, cltvDelta = 9),
+ makeUpdate(5, e, f, feeBase = MilliSatoshi(5), 0, minHtlc = MilliSatoshi(0), maxHtlc = None, cltvDelta = 9),
+ makeUpdate(6, f, d, feeBase = MilliSatoshi(5), 0, minHtlc = MilliSatoshi(0), maxHtlc = None, cltvDelta = 9)
).toMap)
val route = Router.findRoute(g, a, d, DEFAULT_AMOUNT_MSAT, numRoutes = 1, routeParams = DEFAULT_ROUTE_PARAMS.copy(routeMaxCltv = 28))
@@ -598,12 +598,12 @@ class RouteCalculationSpec extends FunSuite {
val f = randomKey.publicKey
val g = makeGraph(List(
- makeUpdate(1, a, b, feeBaseMsat = 1, 0, minHtlcMsat = 0, maxHtlcMsat = None, cltvDelta = 9),
- makeUpdate(2, b, c, feeBaseMsat = 1, 0, minHtlcMsat = 0, maxHtlcMsat = None, cltvDelta = 9),
- makeUpdate(3, c, d, feeBaseMsat = 1, 0, minHtlcMsat = 0, maxHtlcMsat = None, cltvDelta = 9),
- makeUpdate(4, d, e, feeBaseMsat = 1, 0, minHtlcMsat = 0, maxHtlcMsat = None, cltvDelta = 9),
- makeUpdate(5, e, f, feeBaseMsat = 5, 0, minHtlcMsat = 0, maxHtlcMsat = None, cltvDelta = 9),
- makeUpdate(6, b, f, feeBaseMsat = 5, 0, minHtlcMsat = 0, maxHtlcMsat = None, cltvDelta = 9)
+ makeUpdate(1, a, b, feeBase = MilliSatoshi(1), 0, minHtlc = MilliSatoshi(0), maxHtlc = None, cltvDelta = 9),
+ makeUpdate(2, b, c, feeBase = MilliSatoshi(1), 0, minHtlc = MilliSatoshi(0), maxHtlc = None, cltvDelta = 9),
+ makeUpdate(3, c, d, feeBase = MilliSatoshi(1), 0, minHtlc = MilliSatoshi(0), maxHtlc = None, cltvDelta = 9),
+ makeUpdate(4, d, e, feeBase = MilliSatoshi(1), 0, minHtlc = MilliSatoshi(0), maxHtlc = None, cltvDelta = 9),
+ makeUpdate(5, e, f, feeBase = MilliSatoshi(5), 0, minHtlc = MilliSatoshi(0), maxHtlc = None, cltvDelta = 9),
+ makeUpdate(6, b, f, feeBase = MilliSatoshi(5), 0, minHtlc = MilliSatoshi(0), maxHtlc = None, cltvDelta = 9)
).toMap)
val route = Router.findRoute(g, a, f, DEFAULT_AMOUNT_MSAT, numRoutes = 1, routeParams = DEFAULT_ROUTE_PARAMS.copy(routeMaxLength = 3))
@@ -613,11 +613,11 @@ class RouteCalculationSpec extends FunSuite {
test("ignore loops") {
val updates = List(
- makeUpdate(1L, a, b, 10, 10),
- makeUpdate(2L, b, c, 10, 10),
- makeUpdate(3L, c, a, 10, 10),
- makeUpdate(4L, c, d, 10, 10),
- makeUpdate(5L, d, e, 10, 10)
+ makeUpdate(1L, a, b, MilliSatoshi(10), 10),
+ makeUpdate(2L, b, c, MilliSatoshi(10), 10),
+ makeUpdate(3L, c, a, MilliSatoshi(10), 10),
+ makeUpdate(4L, c, d, MilliSatoshi(10), 10),
+ makeUpdate(5L, d, e, MilliSatoshi(10), 10)
).toMap
val g = makeGraph(updates)
@@ -630,13 +630,13 @@ class RouteCalculationSpec extends FunSuite {
// the graph contains a possible 0-cost path that goes back on its steps ( e -> f, f -> e )
val updates = List(
- makeUpdate(1L, a, b, 10, 10), // a -> b
- makeUpdate(2L, b, c, 10, 10),
- makeUpdate(4L, c, d, 10, 10),
- makeUpdate(3L, b, e, 0, 0), // b -> e
- makeUpdate(6L, e, f, 0, 0), // e -> f
- makeUpdate(6L, f, e, 0, 0), // e <- f
- makeUpdate(5L, e, d, 0, 0) // e -> d
+ makeUpdate(1L, a, b, MilliSatoshi(10), 10), // a -> b
+ makeUpdate(2L, b, c, MilliSatoshi(10), 10),
+ makeUpdate(4L, c, d, MilliSatoshi(10), 10),
+ makeUpdate(3L, b, e, MilliSatoshi(0), 0), // b -> e
+ makeUpdate(6L, e, f, MilliSatoshi(0), 0), // e -> f
+ makeUpdate(6L, f, e, MilliSatoshi(0), 0), // e <- f
+ makeUpdate(5L, e, d, MilliSatoshi(0), 0) // e -> d
).toMap
val g = makeGraph(updates)
@@ -671,13 +671,13 @@ class RouteCalculationSpec extends FunSuite {
val edges = Seq(
- makeUpdate(1L, d, a, 1, 0),
- makeUpdate(2L, d, e, 1, 0),
- makeUpdate(3L, a, e, 1, 0),
- makeUpdate(4L, e, b, 1, 0),
- makeUpdate(5L, e, f, 1, 0),
- makeUpdate(6L, b, c, 1, 0),
- makeUpdate(7L, c, f, 1, 0)
+ makeUpdate(1L, d, a, MilliSatoshi(1), 0),
+ makeUpdate(2L, d, e, MilliSatoshi(1), 0),
+ makeUpdate(3L, a, e, MilliSatoshi(1), 0),
+ makeUpdate(4L, e, b, MilliSatoshi(1), 0),
+ makeUpdate(5L, e, f, MilliSatoshi(1), 0),
+ makeUpdate(6L, b, c, MilliSatoshi(1), 0),
+ makeUpdate(7L, c, f, MilliSatoshi(1), 0)
).toMap
val graph = DirectedGraph.makeGraph(edges)
@@ -703,15 +703,15 @@ class RouteCalculationSpec extends FunSuite {
val edges = Seq(
- makeUpdate(10L, c, e, 2, 0),
- makeUpdate(20L, c, d, 3, 0),
- makeUpdate(30L, d, f, 4, 5), // D- > F has a higher cost to distinguish it from the 2nd cheapest route
- makeUpdate(40L, e, d, 1, 0),
- makeUpdate(50L, e, f, 2, 0),
- makeUpdate(60L, e, g, 3, 0),
- makeUpdate(70L, f, g, 2, 0),
- makeUpdate(80L, f, h, 1, 0),
- makeUpdate(90L, g, h, 2, 0)
+ makeUpdate(10L, c, e, MilliSatoshi(2), 0),
+ makeUpdate(20L, c, d, MilliSatoshi(3), 0),
+ makeUpdate(30L, d, f, MilliSatoshi(4), 5), // D- > F has a higher cost to distinguish it from the 2nd cheapest route
+ makeUpdate(40L, e, d, MilliSatoshi(1), 0),
+ makeUpdate(50L, e, f, MilliSatoshi(2), 0),
+ makeUpdate(60L, e, g, MilliSatoshi(3), 0),
+ makeUpdate(70L, f, g, MilliSatoshi(2), 0),
+ makeUpdate(80L, f, h, MilliSatoshi(1), 0),
+ makeUpdate(90L, g, h, MilliSatoshi(2), 0)
)
val graph = DirectedGraph().addEdges(edges)
@@ -732,19 +732,19 @@ class RouteCalculationSpec extends FunSuite {
// simple graph with only 2 possible paths from A to F
val edges = Seq(
- makeUpdate(1L, a, b, 1, 0),
- makeUpdate(1L, b, a, 1, 0),
- makeUpdate(2L, b, c, 1, 0),
- makeUpdate(2L, c, b, 1, 0),
- makeUpdate(3L, c, f, 1, 0),
- makeUpdate(3L, f, c, 1, 0),
- makeUpdate(4L, c, d, 1, 0),
- makeUpdate(4L, d, c, 1, 0),
- makeUpdate(41L, d, c, 1, 0), // there is more than one D -> C channel
- makeUpdate(5L, d, e, 1, 0),
- makeUpdate(5L, e, d, 1, 0),
- makeUpdate(6L, e, f, 1, 0),
- makeUpdate(6L, f, e, 1, 0)
+ makeUpdate(1L, a, b, MilliSatoshi(1), 0),
+ makeUpdate(1L, b, a, MilliSatoshi(1), 0),
+ makeUpdate(2L, b, c, MilliSatoshi(1), 0),
+ makeUpdate(2L, c, b, MilliSatoshi(1), 0),
+ makeUpdate(3L, c, f, MilliSatoshi(1), 0),
+ makeUpdate(3L, f, c, MilliSatoshi(1), 0),
+ makeUpdate(4L, c, d, MilliSatoshi(1), 0),
+ makeUpdate(4L, d, c, MilliSatoshi(1), 0),
+ makeUpdate(41L, d, c, MilliSatoshi(1), 0), // there is more than one D -> C channel
+ makeUpdate(5L, d, e, MilliSatoshi(1), 0),
+ makeUpdate(5L, e, d, MilliSatoshi(1), 0),
+ makeUpdate(6L, e, f, MilliSatoshi(1), 0),
+ makeUpdate(6L, f, e, MilliSatoshi(1), 0)
)
val graph = DirectedGraph().addEdges(edges)
@@ -759,19 +759,19 @@ class RouteCalculationSpec extends FunSuite {
test("select a random route below the requested fee") {
- val strictFeeParams = DEFAULT_ROUTE_PARAMS.copy(maxFeeBaseMsat = 7, maxFeePct = 0)
+ val strictFeeParams = DEFAULT_ROUTE_PARAMS.copy(maxFeeBase = MilliSatoshi(7), maxFeePct = 0)
// A -> B -> C -> D has total cost of 10000005
// A -> E -> C -> D has total cost of 11080003 !!
// A -> E -> F -> D has total cost of 10000006
val g = makeGraph(List(
- makeUpdate(1L, a, b, feeBaseMsat = 1, 0),
- makeUpdate(4L, a, e, feeBaseMsat = 1, 0),
- makeUpdate(2L, b, c, feeBaseMsat = 2, 0),
- makeUpdate(3L, c, d, feeBaseMsat = 3, 0),
- makeUpdate(5L, e, f, feeBaseMsat = 3, 0),
- makeUpdate(6L, f, d, feeBaseMsat = 3, 0),
- makeUpdate(7L, e, c, feeBaseMsat = 9, 0)
+ makeUpdate(1L, a, b, feeBase = MilliSatoshi(1), 0),
+ makeUpdate(4L, a, e, feeBase = MilliSatoshi(1), 0),
+ makeUpdate(2L, b, c, feeBase = MilliSatoshi(2), 0),
+ makeUpdate(3L, c, d, feeBase = MilliSatoshi(3), 0),
+ makeUpdate(5L, e, f, feeBase = MilliSatoshi(3), 0),
+ makeUpdate(6L, f, d, feeBase = MilliSatoshi(3), 0),
+ makeUpdate(7L, e, c, feeBase = MilliSatoshi(9), 0)
).toMap)
(for {_ <- 0 to 10} yield Router.findRoute(g, a, d, DEFAULT_AMOUNT_MSAT, numRoutes = 3, routeParams = strictFeeParams)).map {
@@ -781,25 +781,25 @@ class RouteCalculationSpec extends FunSuite {
val routeCost = Graph.pathWeight(hops2Edges(someRoute), DEFAULT_AMOUNT_MSAT, isPartial = false, 0, None).cost - DEFAULT_AMOUNT_MSAT
// over the three routes we could only get the 2 cheapest because the third is too expensive (over 7msat of fees)
- assert(routeCost == 5 || routeCost == 6)
+ assert(routeCost == MilliSatoshi(5) || routeCost == MilliSatoshi(6))
}
}
test("Use weight ratios to when computing the edge weight") {
- val largeCapacity = 8000000000L
+ val largeCapacity = MilliSatoshi(8000000000L)
// A -> B -> C -> D is 'fee optimized', lower fees route (totFees = 2, totCltv = 4000)
// A -> E -> F -> D is 'timeout optimized', lower CLTV route (totFees = 3, totCltv = 18)
// A -> E -> C -> D is 'capacity optimized', more recent channel/larger capacity route
val updates = List(
- makeUpdate(1L, a, b, feeBaseMsat = 0, 0, minHtlcMsat = 0, maxHtlcMsat = None, cltvDelta = 13),
- makeUpdate(4L, a, e, feeBaseMsat = 0, 0, minHtlcMsat = 0, maxHtlcMsat = None, cltvDelta = 12),
- makeUpdate(2L, b, c, feeBaseMsat = 1, 0, minHtlcMsat = 0, maxHtlcMsat = None, cltvDelta = 500),
- makeUpdate(3L, c, d, feeBaseMsat = 1, 0, minHtlcMsat = 0, maxHtlcMsat = None, cltvDelta = 500),
- makeUpdate(5L, e, f, feeBaseMsat = 2, 0, minHtlcMsat = 0, maxHtlcMsat = None, cltvDelta = 9),
- makeUpdate(6L, f, d, feeBaseMsat = 2, 0, minHtlcMsat = 0, maxHtlcMsat = None, cltvDelta = 9),
- makeUpdate(7L, e, c, feeBaseMsat = 2, 0, minHtlcMsat = 0, maxHtlcMsat = Some(largeCapacity), cltvDelta = 12)
+ makeUpdate(1L, a, b, feeBase = MilliSatoshi(0), 0, minHtlc = MilliSatoshi(0), maxHtlc = None, cltvDelta = 13),
+ makeUpdate(4L, a, e, feeBase = MilliSatoshi(0), 0, minHtlc = MilliSatoshi(0), maxHtlc = None, cltvDelta = 12),
+ makeUpdate(2L, b, c, feeBase = MilliSatoshi(1), 0, minHtlc = MilliSatoshi(0), maxHtlc = None, cltvDelta = 500),
+ makeUpdate(3L, c, d, feeBase = MilliSatoshi(1), 0, minHtlc = MilliSatoshi(0), maxHtlc = None, cltvDelta = 500),
+ makeUpdate(5L, e, f, feeBase = MilliSatoshi(2), 0, minHtlc = MilliSatoshi(0), maxHtlc = None, cltvDelta = 9),
+ makeUpdate(6L, f, d, feeBase = MilliSatoshi(2), 0, minHtlc = MilliSatoshi(0), maxHtlc = None, cltvDelta = 9),
+ makeUpdate(7L, e, c, feeBase = MilliSatoshi(2), 0, minHtlc = MilliSatoshi(0), maxHtlc = Some(largeCapacity), cltvDelta = 12)
).toMap
val g = makeGraph(updates)
@@ -829,12 +829,12 @@ class RouteCalculationSpec extends FunSuite {
val currentBlockHeight = 554000
val g = makeGraph(List(
- makeUpdateShort(ShortChannelId(s"${currentBlockHeight}x0x1"), a, b, feeBaseMsat = 1, 0, minHtlcMsat = 0, maxHtlcMsat = None, cltvDelta = 144),
- makeUpdateShort(ShortChannelId(s"${currentBlockHeight}x0x4"), a, e, feeBaseMsat = 1, 0, minHtlcMsat = 0, maxHtlcMsat = None, cltvDelta = 144),
- makeUpdateShort(ShortChannelId(s"${currentBlockHeight - 3000}x0x2"), b, c, feeBaseMsat = 1, 0, minHtlcMsat = 0, maxHtlcMsat = None, cltvDelta = 144), // younger channel
- makeUpdateShort(ShortChannelId(s"${currentBlockHeight - 3000}x0x3"), c, d, feeBaseMsat = 1, 0, minHtlcMsat = 0, maxHtlcMsat = None, cltvDelta = 144),
- makeUpdateShort(ShortChannelId(s"${currentBlockHeight}x0x5"), e, f, feeBaseMsat = 1, 0, minHtlcMsat = 0, maxHtlcMsat = None, cltvDelta = 144),
- makeUpdateShort(ShortChannelId(s"${currentBlockHeight}x0x6"), f, d, feeBaseMsat = 1, 0, minHtlcMsat = 0, maxHtlcMsat = None, cltvDelta = 144)
+ makeUpdateShort(ShortChannelId(s"${currentBlockHeight}x0x1"), a, b, feeBase = MilliSatoshi(1), 0, minHtlc = MilliSatoshi(0), maxHtlc = None, cltvDelta = 144),
+ makeUpdateShort(ShortChannelId(s"${currentBlockHeight}x0x4"), a, e, feeBase = MilliSatoshi(1), 0, minHtlc = MilliSatoshi(0), maxHtlc = None, cltvDelta = 144),
+ makeUpdateShort(ShortChannelId(s"${currentBlockHeight - 3000}x0x2"), b, c, feeBase = MilliSatoshi(1), 0, minHtlc = MilliSatoshi(0), maxHtlc = None, cltvDelta = 144), // younger channel
+ makeUpdateShort(ShortChannelId(s"${currentBlockHeight - 3000}x0x3"), c, d, feeBase = MilliSatoshi(1), 0, minHtlc = MilliSatoshi(0), maxHtlc = None, cltvDelta = 144),
+ makeUpdateShort(ShortChannelId(s"${currentBlockHeight}x0x5"), e, f, feeBase = MilliSatoshi(1), 0, minHtlc = MilliSatoshi(0), maxHtlc = None, cltvDelta = 144),
+ makeUpdateShort(ShortChannelId(s"${currentBlockHeight}x0x6"), f, d, feeBase = MilliSatoshi(1), 0, minHtlc = MilliSatoshi(0), maxHtlc = None, cltvDelta = 144)
).toMap)
Globals.blockCount.set(currentBlockHeight)
@@ -851,12 +851,12 @@ class RouteCalculationSpec extends FunSuite {
test("prefer a route with a smaller total CLTV if fees and score are the same") {
val g = makeGraph(List(
- makeUpdateShort(ShortChannelId(s"0x0x1"), a, b, feeBaseMsat = 1, 0, minHtlcMsat = 0, maxHtlcMsat = None, cltvDelta = 12),
- makeUpdateShort(ShortChannelId(s"0x0x4"), a, e, feeBaseMsat = 1, 0, minHtlcMsat = 0, maxHtlcMsat = None, cltvDelta = 12),
- makeUpdateShort(ShortChannelId(s"0x0x2"), b, c, feeBaseMsat = 1, 0, minHtlcMsat = 0, maxHtlcMsat = None, cltvDelta = 10), // smaller CLTV
- makeUpdateShort(ShortChannelId(s"0x0x3"), c, d, feeBaseMsat = 1, 0, minHtlcMsat = 0, maxHtlcMsat = None, cltvDelta = 12),
- makeUpdateShort(ShortChannelId(s"0x0x5"), e, f, feeBaseMsat = 1, 0, minHtlcMsat = 0, maxHtlcMsat = None, cltvDelta = 12),
- makeUpdateShort(ShortChannelId(s"0x0x6"), f, d, feeBaseMsat = 1, 0, minHtlcMsat = 0, maxHtlcMsat = None, cltvDelta = 12)
+ makeUpdateShort(ShortChannelId(s"0x0x1"), a, b, feeBase = MilliSatoshi(1), 0, minHtlc = MilliSatoshi(0), maxHtlc = None, cltvDelta = 12),
+ makeUpdateShort(ShortChannelId(s"0x0x4"), a, e, feeBase = MilliSatoshi(1), 0, minHtlc = MilliSatoshi(0), maxHtlc = None, cltvDelta = 12),
+ makeUpdateShort(ShortChannelId(s"0x0x2"), b, c, feeBase = MilliSatoshi(1), 0, minHtlc = MilliSatoshi(0), maxHtlc = None, cltvDelta = 10), // smaller CLTV
+ makeUpdateShort(ShortChannelId(s"0x0x3"), c, d, feeBase = MilliSatoshi(1), 0, minHtlc = MilliSatoshi(0), maxHtlc = None, cltvDelta = 12),
+ makeUpdateShort(ShortChannelId(s"0x0x5"), e, f, feeBase = MilliSatoshi(1), 0, minHtlc = MilliSatoshi(0), maxHtlc = None, cltvDelta = 12),
+ makeUpdateShort(ShortChannelId(s"0x0x6"), f, d, feeBase = MilliSatoshi(1), 0, minHtlc = MilliSatoshi(0), maxHtlc = None, cltvDelta = 12)
).toMap)
@@ -875,12 +875,12 @@ class RouteCalculationSpec extends FunSuite {
// A -> B -> C -> D is cheaper but has a total CLTV > 2016!
// A -> E -> F -> D is more expensive but has a total CLTV < 2016
val g = makeGraph(List(
- makeUpdateShort(ShortChannelId(s"0x0x1"), a, b, feeBaseMsat = 1, 0, minHtlcMsat = 0, maxHtlcMsat = None, cltvDelta = 144),
- makeUpdateShort(ShortChannelId(s"0x0x4"), a, e, feeBaseMsat = 1, 0, minHtlcMsat = 0, maxHtlcMsat = None, cltvDelta = 144),
- makeUpdateShort(ShortChannelId(s"0x0x2"), b, c, feeBaseMsat = 1, 0, minHtlcMsat = 0, maxHtlcMsat = None, cltvDelta = 1000),
- makeUpdateShort(ShortChannelId(s"0x0x3"), c, d, feeBaseMsat = 1, 0, minHtlcMsat = 0, maxHtlcMsat = None, cltvDelta = 900),
- makeUpdateShort(ShortChannelId(s"0x0x5"), e, f, feeBaseMsat = 10, 0, minHtlcMsat = 0, maxHtlcMsat = None, cltvDelta = 144),
- makeUpdateShort(ShortChannelId(s"0x0x6"), f, d, feeBaseMsat = 10, 0, minHtlcMsat = 0, maxHtlcMsat = None, cltvDelta = 144)
+ makeUpdateShort(ShortChannelId(s"0x0x1"), a, b, feeBase = MilliSatoshi(1), 0, minHtlc = MilliSatoshi(0), maxHtlc = None, cltvDelta = 144),
+ makeUpdateShort(ShortChannelId(s"0x0x4"), a, e, feeBase = MilliSatoshi(1), 0, minHtlc = MilliSatoshi(0), maxHtlc = None, cltvDelta = 144),
+ makeUpdateShort(ShortChannelId(s"0x0x2"), b, c, feeBase = MilliSatoshi(1), 0, minHtlc = MilliSatoshi(0), maxHtlc = None, cltvDelta = 1000),
+ makeUpdateShort(ShortChannelId(s"0x0x3"), c, d, feeBase = MilliSatoshi(1), 0, minHtlc = MilliSatoshi(0), maxHtlc = None, cltvDelta = 900),
+ makeUpdateShort(ShortChannelId(s"0x0x5"), e, f, feeBase = MilliSatoshi(1), 0, minHtlc = MilliSatoshi(0), maxHtlc = None, cltvDelta = 144),
+ makeUpdateShort(ShortChannelId(s"0x0x6"), f, d, feeBase = MilliSatoshi(1), 0, minHtlc = MilliSatoshi(0), maxHtlc = None, cltvDelta = 144)
).toMap)
val Success(routeScoreOptimized) = Router.findRoute(g, a, d, DEFAULT_AMOUNT_MSAT / 2, numRoutes = 1, routeParams = DEFAULT_ROUTE_PARAMS.copy(ratios = Some(WeightRatios(
@@ -897,22 +897,22 @@ class RouteCalculationSpec extends FunSuite {
// This test have a channel (542280x2156x0) that according to heuristics is very convenient but actually useless to reach the target,
// then if the cost function is not monotonic the path-finding breaks because the result path contains a loop.
val updates = List(
- ChannelDesc(ShortChannelId("565643x1216x0"), PublicKey(hex"03864ef025fde8fb587d989186ce6a4a186895ee44a926bfc370e2c366597a3f8f"), PublicKey(hex"024655b768ef40951b20053a5c4b951606d4d86085d51238f2c67c7dec29c792ca")) -> ChannelUpdate(ByteVector64.Zeroes, ByteVector32.Zeroes, ShortChannelId("565643x1216x0"), 0, 1.toByte, 1.toByte, 144, htlcMinimumMsat = 0, feeBaseMsat = 1000, 100, Some(15000000000L)),
- ChannelDesc(ShortChannelId("565643x1216x0"), PublicKey(hex"024655b768ef40951b20053a5c4b951606d4d86085d51238f2c67c7dec29c792ca"), PublicKey(hex"03864ef025fde8fb587d989186ce6a4a186895ee44a926bfc370e2c366597a3f8f")) -> ChannelUpdate(ByteVector64.Zeroes, ByteVector32.Zeroes, ShortChannelId("565643x1216x0"), 0, 1.toByte, 0.toByte, 14, htlcMinimumMsat = 1, 1000, 10, Some(4294967295L)),
- ChannelDesc(ShortChannelId("542280x2156x0"), PublicKey(hex"03864ef025fde8fb587d989186ce6a4a186895ee44a926bfc370e2c366597a3f8f"), PublicKey(hex"03cb7983dc247f9f81a0fa2dfa3ce1c255365f7279c8dd143e086ca333df10e278")) -> ChannelUpdate(ByteVector64.Zeroes, ByteVector32.Zeroes, ShortChannelId("542280x2156x0"), 0, 1.toByte, 1.toByte, 144, htlcMinimumMsat = 1000, feeBaseMsat = 1000, 100, Some(16777000000L)),
- ChannelDesc(ShortChannelId("542280x2156x0"), PublicKey(hex"03cb7983dc247f9f81a0fa2dfa3ce1c255365f7279c8dd143e086ca333df10e278"), PublicKey(hex"03864ef025fde8fb587d989186ce6a4a186895ee44a926bfc370e2c366597a3f8f")) -> ChannelUpdate(ByteVector64.Zeroes, ByteVector32.Zeroes, ShortChannelId("542280x2156x0"), 0, 1.toByte, 0.toByte, 144, htlcMinimumMsat = 1, 667, 1, Some(16777000000L)),
- ChannelDesc(ShortChannelId("565779x2711x0"), PublicKey(hex"03864ef025fde8fb587d989186ce6a4a186895ee44a926bfc370e2c366597a3f8f"), PublicKey(hex"036d65409c41ab7380a43448f257809e7496b52bf92057c09c4f300cbd61c50d96")) -> ChannelUpdate(ByteVector64.Zeroes, ByteVector32.Zeroes, ShortChannelId("565779x2711x0"), 0, 1.toByte, 3.toByte, 144, htlcMinimumMsat = 1, 1000, 100, Some(230000000L)),
- ChannelDesc(ShortChannelId("565779x2711x0"), PublicKey(hex"036d65409c41ab7380a43448f257809e7496b52bf92057c09c4f300cbd61c50d96"), PublicKey(hex"03864ef025fde8fb587d989186ce6a4a186895ee44a926bfc370e2c366597a3f8f")) -> ChannelUpdate(ByteVector64.Zeroes, ByteVector32.Zeroes, ShortChannelId("565779x2711x0"), 0, 1.toByte, 0.toByte, 144, htlcMinimumMsat = 1, 1000, 100, Some(230000000L))
+ ChannelDesc(ShortChannelId("565643x1216x0"), PublicKey(hex"03864ef025fde8fb587d989186ce6a4a186895ee44a926bfc370e2c366597a3f8f"), PublicKey(hex"024655b768ef40951b20053a5c4b951606d4d86085d51238f2c67c7dec29c792ca")) -> ChannelUpdate(ByteVector64.Zeroes, ByteVector32.Zeroes, ShortChannelId("565643x1216x0"), 0, 1.toByte, 1.toByte, 144, htlcMinimumMsat = MilliSatoshi(0), feeBaseMsat = MilliSatoshi(1000), 100, Some(MilliSatoshi(15000000000L))),
+ ChannelDesc(ShortChannelId("565643x1216x0"), PublicKey(hex"024655b768ef40951b20053a5c4b951606d4d86085d51238f2c67c7dec29c792ca"), PublicKey(hex"03864ef025fde8fb587d989186ce6a4a186895ee44a926bfc370e2c366597a3f8f")) -> ChannelUpdate(ByteVector64.Zeroes, ByteVector32.Zeroes, ShortChannelId("565643x1216x0"), 0, 1.toByte, 0.toByte, 14, htlcMinimumMsat = MilliSatoshi(1), MilliSatoshi(1000), 10, Some(MilliSatoshi(4294967295L))),
+ ChannelDesc(ShortChannelId("542280x2156x0"), PublicKey(hex"03864ef025fde8fb587d989186ce6a4a186895ee44a926bfc370e2c366597a3f8f"), PublicKey(hex"03cb7983dc247f9f81a0fa2dfa3ce1c255365f7279c8dd143e086ca333df10e278")) -> ChannelUpdate(ByteVector64.Zeroes, ByteVector32.Zeroes, ShortChannelId("542280x2156x0"), 0, 1.toByte, 1.toByte, 144, htlcMinimumMsat = MilliSatoshi(1000), feeBaseMsat = MilliSatoshi(1000), 100, Some(MilliSatoshi(16777000000L))),
+ ChannelDesc(ShortChannelId("542280x2156x0"), PublicKey(hex"03cb7983dc247f9f81a0fa2dfa3ce1c255365f7279c8dd143e086ca333df10e278"), PublicKey(hex"03864ef025fde8fb587d989186ce6a4a186895ee44a926bfc370e2c366597a3f8f")) -> ChannelUpdate(ByteVector64.Zeroes, ByteVector32.Zeroes, ShortChannelId("542280x2156x0"), 0, 1.toByte, 0.toByte, 144, htlcMinimumMsat = MilliSatoshi(1), MilliSatoshi(667), 1, Some(MilliSatoshi(16777000000L))),
+ ChannelDesc(ShortChannelId("565779x2711x0"), PublicKey(hex"03864ef025fde8fb587d989186ce6a4a186895ee44a926bfc370e2c366597a3f8f"), PublicKey(hex"036d65409c41ab7380a43448f257809e7496b52bf92057c09c4f300cbd61c50d96")) -> ChannelUpdate(ByteVector64.Zeroes, ByteVector32.Zeroes, ShortChannelId("565779x2711x0"), 0, 1.toByte, 3.toByte, 144, htlcMinimumMsat = MilliSatoshi(1), MilliSatoshi(1000), 100, Some(MilliSatoshi(230000000L))),
+ ChannelDesc(ShortChannelId("565779x2711x0"), PublicKey(hex"036d65409c41ab7380a43448f257809e7496b52bf92057c09c4f300cbd61c50d96"), PublicKey(hex"03864ef025fde8fb587d989186ce6a4a186895ee44a926bfc370e2c366597a3f8f")) -> ChannelUpdate(ByteVector64.Zeroes, ByteVector32.Zeroes, ShortChannelId("565779x2711x0"), 0, 1.toByte, 0.toByte, 144, htlcMinimumMsat = MilliSatoshi(1), MilliSatoshi(1000), 100, Some(MilliSatoshi(230000000L)))
).toMap
val g = DirectedGraph.makeGraph(updates)
- val params = RouteParams(randomize = false, maxFeeBaseMsat = 21000, maxFeePct = 0.03, routeMaxCltv = 1008, routeMaxLength = 6, ratios = Some(
+ val params = RouteParams(randomize = false, maxFeeBase = MilliSatoshi(21000), maxFeePct = 0.03, routeMaxCltv = 1008, routeMaxLength = 6, ratios = Some(
WeightRatios(cltvDeltaFactor = 0.15, ageFactor = 0.35, capacityFactor = 0.5)
))
val thisNode = PublicKey(hex"036d65409c41ab7380a43448f257809e7496b52bf92057c09c4f300cbd61c50d96")
val targetNode = PublicKey(hex"024655b768ef40951b20053a5c4b951606d4d86085d51238f2c67c7dec29c792ca")
- val amount = 351000
+ val amount = MilliSatoshi(351000)
Globals.blockCount.set(567634) // simulate mainnet block for heuristic
val Success(route) = Router.findRoute(g, thisNode, targetNode, amount, 1, Set.empty, Set.empty, params)
@@ -927,9 +927,9 @@ object RouteCalculationSpec {
val noopBoundaries = { _: RichWeight => true }
- val DEFAULT_AMOUNT_MSAT = 10000000
+ val DEFAULT_AMOUNT_MSAT = MilliSatoshi(10000000)
- val DEFAULT_ROUTE_PARAMS = RouteParams(randomize = false, maxFeeBaseMsat = 21000, maxFeePct = 0.03, routeMaxCltv = 2016, routeMaxLength = 6, ratios = None)
+ val DEFAULT_ROUTE_PARAMS = RouteParams(randomize = false, maxFeeBase = MilliSatoshi(21000), maxFeePct = 0.03, routeMaxCltv = 2016, routeMaxLength = 6, ratios = None)
val DUMMY_SIG = Transactions.PlaceHolderSig
@@ -938,26 +938,26 @@ object RouteCalculationSpec {
ChannelAnnouncement(DUMMY_SIG, DUMMY_SIG, DUMMY_SIG, DUMMY_SIG, ByteVector.empty, Block.RegtestGenesisBlock.hash, ShortChannelId(shortChannelId), nodeId1, nodeId2, randomKey.publicKey, randomKey.publicKey)
}
- def makeUpdate(shortChannelId: Long, nodeId1: PublicKey, nodeId2: PublicKey, feeBaseMsat: Int, feeProportionalMillionth: Int, minHtlcMsat: Long = DEFAULT_AMOUNT_MSAT, maxHtlcMsat: Option[Long] = None, cltvDelta: Int = 0): (ChannelDesc, ChannelUpdate) = {
- makeUpdateShort(ShortChannelId(shortChannelId), nodeId1, nodeId2, feeBaseMsat, feeProportionalMillionth, minHtlcMsat, maxHtlcMsat, cltvDelta)
+ def makeUpdate(shortChannelId: Long, nodeId1: PublicKey, nodeId2: PublicKey, feeBase: MilliSatoshi, feeProportionalMillionth: Int, minHtlc: MilliSatoshi = DEFAULT_AMOUNT_MSAT, maxHtlc: Option[MilliSatoshi] = None, cltvDelta: Int = 0): (ChannelDesc, ChannelUpdate) = {
+ makeUpdateShort(ShortChannelId(shortChannelId), nodeId1, nodeId2, feeBase, feeProportionalMillionth, minHtlc, maxHtlc, cltvDelta)
}
- def makeUpdateShort(shortChannelId: ShortChannelId, nodeId1: PublicKey, nodeId2: PublicKey, feeBaseMsat: Int, feeProportionalMillionth: Int, minHtlcMsat: Long = DEFAULT_AMOUNT_MSAT, maxHtlcMsat: Option[Long] = None, cltvDelta: Int = 0): (ChannelDesc, ChannelUpdate) =
+ def makeUpdateShort(shortChannelId: ShortChannelId, nodeId1: PublicKey, nodeId2: PublicKey, feeBase: MilliSatoshi, feeProportionalMillionth: Int, minHtlc: MilliSatoshi = DEFAULT_AMOUNT_MSAT, maxHtlc: Option[MilliSatoshi] = None, cltvDelta: Int = 0): (ChannelDesc, ChannelUpdate) =
ChannelDesc(shortChannelId, nodeId1, nodeId2) -> ChannelUpdate(
signature = DUMMY_SIG,
chainHash = Block.RegtestGenesisBlock.hash,
shortChannelId = shortChannelId,
timestamp = 0L,
- messageFlags = maxHtlcMsat match {
+ messageFlags = maxHtlc match {
case Some(_) => 1
case None => 0
},
channelFlags = 0,
cltvExpiryDelta = cltvDelta,
- htlcMinimumMsat = minHtlcMsat,
- feeBaseMsat = feeBaseMsat,
+ htlcMinimumMsat = minHtlc,
+ feeBaseMsat = feeBase,
feeProportionalMillionths = feeProportionalMillionth,
- htlcMaximumMsat = maxHtlcMsat
+ htlcMaximumMsat = maxHtlc
)
def makeGraph(updates: Map[ChannelDesc, ChannelUpdate]) = DirectedGraph.makeGraph(updates)
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/router/RouterSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/router/RouterSpec.scala
index 5be5540eee..c5bc27ba6b 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/router/RouterSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/router/RouterSpec.scala
@@ -30,7 +30,7 @@ import fr.acinq.eclair.router.Announcements.makeChannelUpdate
import fr.acinq.eclair.router.RouteCalculationSpec.DEFAULT_AMOUNT_MSAT
import fr.acinq.eclair.transactions.Scripts
import fr.acinq.eclair.wire.QueryShortChannelIds
-import fr.acinq.eclair.{Globals, ShortChannelId, randomKey}
+import fr.acinq.eclair.{Globals, MilliSatoshi, ShortChannelId, randomKey}
import scodec.bits._
import scala.collection.SortedSet
@@ -52,21 +52,21 @@ class RouterSpec extends BaseRouterSpec {
val channelId_ac = ShortChannelId(420000, 5, 0)
val chan_ac = channelAnnouncement(channelId_ac, priv_a, priv_c, priv_funding_a, priv_funding_c)
- val update_ac = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv_a, c, channelId_ac, cltvExpiryDelta = 7, 0, feeBaseMsat = 766000, feeProportionalMillionths = 10, 500000000L)
+ val update_ac = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv_a, c, channelId_ac, cltvExpiryDelta = 7, MilliSatoshi(0), feeBaseMsat = MilliSatoshi(766000), feeProportionalMillionths = 10, MilliSatoshi(500000000L))
// a-x will not be found
val priv_x = randomKey
val chan_ax = channelAnnouncement(ShortChannelId(42001), priv_a, priv_x, priv_funding_a, randomKey)
- val update_ax = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv_a, priv_x.publicKey, chan_ax.shortChannelId, cltvExpiryDelta = 7, 0, feeBaseMsat = 766000, feeProportionalMillionths = 10, 500000000L)
+ val update_ax = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv_a, priv_x.publicKey, chan_ax.shortChannelId, cltvExpiryDelta = 7, MilliSatoshi(0), feeBaseMsat = MilliSatoshi(766000), feeProportionalMillionths = 10, MilliSatoshi(500000000L))
// a-y will have an invalid script
val priv_y = randomKey
val priv_funding_y = randomKey
val chan_ay = channelAnnouncement(ShortChannelId(42002), priv_a, priv_y, priv_funding_a, priv_funding_y)
- val update_ay = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv_a, priv_y.publicKey, chan_ay.shortChannelId, cltvExpiryDelta = 7, 0, feeBaseMsat = 766000, feeProportionalMillionths = 10, 500000000L)
+ val update_ay = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv_a, priv_y.publicKey, chan_ay.shortChannelId, cltvExpiryDelta = 7, MilliSatoshi(0), feeBaseMsat = MilliSatoshi(766000), feeProportionalMillionths = 10, MilliSatoshi(500000000L))
// a-z will be spent
val priv_z = randomKey
val priv_funding_z = randomKey
val chan_az = channelAnnouncement(ShortChannelId(42003), priv_a, priv_z, priv_funding_a, priv_funding_z)
- val update_az = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv_a, priv_z.publicKey, chan_az.shortChannelId, cltvExpiryDelta = 7, 0, feeBaseMsat = 766000, feeProportionalMillionths = 10, 500000000L)
+ val update_az = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv_a, priv_z.publicKey, chan_az.shortChannelId, cltvExpiryDelta = 7, MilliSatoshi(0), feeBaseMsat = MilliSatoshi(766000), feeProportionalMillionths = 10, MilliSatoshi(500000000L))
router ! PeerRoutingMessage(null, remoteNodeId, chan_ac)
router ! PeerRoutingMessage(null, remoteNodeId, chan_ax)
@@ -201,7 +201,7 @@ class RouterSpec extends BaseRouterSpec {
assert(res.hops.map(_.nodeId).toList === a :: b :: c :: Nil)
assert(res.hops.last.nextNodeId === d)
- val channelUpdate_cd1 = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv_c, d, channelId_cd, cltvExpiryDelta = 3, 0, feeBaseMsat = 153000, feeProportionalMillionths = 4, htlcMaximumMsat = 500000000L, enable = false)
+ val channelUpdate_cd1 = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv_c, d, channelId_cd, cltvExpiryDelta = 3, MilliSatoshi(0), feeBaseMsat = MilliSatoshi(153000), feeProportionalMillionths = 4, htlcMaximumMsat = MilliSatoshi(500000000L), enable = false)
sender.send(router, PeerRoutingMessage(null, remoteNodeId, channelUpdate_cd1))
sender.expectMsg(TransportHandler.ReadAck(channelUpdate_cd1))
sender.send(router, RouteRequest(a, d, DEFAULT_AMOUNT_MSAT, routeParams = relaxedRouteParams))
@@ -257,7 +257,7 @@ class RouterSpec extends BaseRouterSpec {
val channelId = ShortChannelId(blockHeight, 5, 0)
val announcement = channelAnnouncement(channelId, priv_a, priv_c, priv_funding_a, priv_funding_c)
val timestamp = (Platform.currentTime.milliseconds - 14.days - 1.day).toSeconds
- val update = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv_a, c, channelId, cltvExpiryDelta = 7, htlcMinimumMsat = 0, feeBaseMsat = 766000, feeProportionalMillionths = 10, htlcMaximumMsat = 5, timestamp = timestamp)
+ val update = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv_a, c, channelId, cltvExpiryDelta = 7, htlcMinimumMsat = MilliSatoshi(0), feeBaseMsat = MilliSatoshi(766000), feeProportionalMillionths = 10, htlcMaximumMsat = MilliSatoshi(5), timestamp = timestamp)
val probe = TestProbe()
probe.ignoreMsg { case _: TransportHandler.ReadAck => true }
probe.send(router, PeerRoutingMessage(null, remoteNodeId, announcement))
@@ -271,7 +271,7 @@ class RouterSpec extends BaseRouterSpec {
val state = sender.expectMsgType[RoutingState]
- val update1 = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv_a, c, channelId, cltvExpiryDelta = 7, htlcMinimumMsat = 0, feeBaseMsat = 766000, feeProportionalMillionths = 10, htlcMaximumMsat = 500000000L, timestamp = Platform.currentTime.millisecond.toSeconds)
+ val update1 = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv_a, c, channelId, cltvExpiryDelta = 7, htlcMinimumMsat = MilliSatoshi(0), feeBaseMsat = MilliSatoshi(766000), feeProportionalMillionths = 10, htlcMaximumMsat = MilliSatoshi(500000000L), timestamp = Platform.currentTime.millisecond.toSeconds)
// we want to make sure that transport receives the query
val transport = TestProbe()
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/router/RoutingSyncSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/router/RoutingSyncSpec.scala
index 1c4d851b65..34905e88ae 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/router/RoutingSyncSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/router/RoutingSyncSpec.scala
@@ -18,7 +18,7 @@ package fr.acinq.eclair.router
import akka.actor.ActorSystem
import akka.testkit.{TestFSMRef, TestKit, TestProbe}
-import fr.acinq.bitcoin.Block
+import fr.acinq.bitcoin.{Block}
import fr.acinq.eclair.TestConstants.{Alice, Bob}
import fr.acinq.eclair._
import fr.acinq.eclair.crypto.TransportHandler
@@ -132,8 +132,8 @@ object RoutingSyncSpec {
val (priv_a, priv_b, priv_funding_a, priv_funding_b) = (randomKey, randomKey, randomKey, randomKey)
val channelAnn_ab = channelAnnouncement(shortChannelId, priv_a, priv_b, priv_funding_a, priv_funding_b)
val TxCoordinates(blockHeight, _, _) = ShortChannelId.coordinates(shortChannelId)
- val channelUpdate_ab = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv_a, priv_b.publicKey, shortChannelId, cltvExpiryDelta = 7, 0, feeBaseMsat = 766000, feeProportionalMillionths = 10, 500000000L, timestamp = blockHeight)
- val channelUpdate_ba = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv_b, priv_a.publicKey, shortChannelId, cltvExpiryDelta = 7, 0, feeBaseMsat = 766000, feeProportionalMillionths = 10, 500000000L, timestamp = blockHeight)
+ val channelUpdate_ab = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv_a, priv_b.publicKey, shortChannelId, cltvExpiryDelta = 7, MilliSatoshi(0), feeBaseMsat = MilliSatoshi(766000), feeProportionalMillionths = 10, MilliSatoshi(500000000L), timestamp = blockHeight)
+ val channelUpdate_ba = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv_b, priv_a.publicKey, shortChannelId, cltvExpiryDelta = 7, MilliSatoshi(0), feeBaseMsat = MilliSatoshi(766000), feeProportionalMillionths = 10, MilliSatoshi(500000000L), timestamp = blockHeight)
val nodeAnnouncement_a = makeNodeAnnouncement(priv_a, "a", Color(0, 0, 0), List())
val nodeAnnouncement_b = makeNodeAnnouncement(priv_b, "b", Color(0, 0, 0), List())
(channelAnn_ab, channelUpdate_ab, channelUpdate_ba, nodeAnnouncement_a, nodeAnnouncement_b)
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/transactions/CommitmentSpecSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/transactions/CommitmentSpecSpec.scala
index 1b95b50856..3df953ab0b 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/transactions/CommitmentSpecSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/transactions/CommitmentSpecSpec.scala
@@ -17,53 +17,53 @@
package fr.acinq.eclair.transactions
import fr.acinq.bitcoin.{ByteVector32, Crypto}
-import fr.acinq.eclair.{TestConstants, randomBytes32}
+import fr.acinq.eclair.{MilliSatoshi, TestConstants, randomBytes32}
import fr.acinq.eclair.wire.{UpdateAddHtlc, UpdateFailHtlc, UpdateFulfillHtlc}
import org.scalatest.FunSuite
class CommitmentSpecSpec extends FunSuite {
test("add, fulfill and fail htlcs from the sender side") {
- val spec = CommitmentSpec(htlcs = Set(), feeratePerKw = 1000, toLocalMsat = 5000 * 1000, toRemoteMsat = 0)
+ val spec = CommitmentSpec(htlcs = Set(), feeratePerKw = 1000, toLocal = MilliSatoshi(5000000), toRemote = MilliSatoshi(0))
val R = randomBytes32
val H = Crypto.sha256(R)
- val add1 = UpdateAddHtlc(ByteVector32.Zeroes, 1, 2000 * 1000, H, 400, TestConstants.emptyOnionPacket)
+ val add1 = UpdateAddHtlc(ByteVector32.Zeroes, 1, MilliSatoshi(2000 * 1000), H, 400, TestConstants.emptyOnionPacket)
val spec1 = CommitmentSpec.reduce(spec, add1 :: Nil, Nil)
- assert(spec1 === spec.copy(htlcs = Set(DirectedHtlc(OUT, add1)), toLocalMsat = 3000 * 1000))
+ assert(spec1 === spec.copy(htlcs = Set(DirectedHtlc(OUT, add1)), toLocal = MilliSatoshi(3000000)))
- val add2 = UpdateAddHtlc(ByteVector32.Zeroes, 2, 1000 * 1000, H, 400, TestConstants.emptyOnionPacket)
+ val add2 = UpdateAddHtlc(ByteVector32.Zeroes, 2, MilliSatoshi(1000 * 1000), H, 400, TestConstants.emptyOnionPacket)
val spec2 = CommitmentSpec.reduce(spec1, add2 :: Nil, Nil)
- assert(spec2 === spec1.copy(htlcs = Set(DirectedHtlc(OUT, add1), DirectedHtlc(OUT, add2)), toLocalMsat = 2000 * 1000))
+ assert(spec2 === spec1.copy(htlcs = Set(DirectedHtlc(OUT, add1), DirectedHtlc(OUT, add2)), toLocal = MilliSatoshi(2000000)))
val ful1 = UpdateFulfillHtlc(ByteVector32.Zeroes, add1.id, R)
val spec3 = CommitmentSpec.reduce(spec2, Nil, ful1 :: Nil)
- assert(spec3 === spec2.copy(htlcs = Set(DirectedHtlc(OUT, add2)), toRemoteMsat = 2000 * 1000))
+ assert(spec3 === spec2.copy(htlcs = Set(DirectedHtlc(OUT, add2)), toRemote = MilliSatoshi(2000000)))
val fail1 = UpdateFailHtlc(ByteVector32.Zeroes, add2.id, R)
val spec4 = CommitmentSpec.reduce(spec3, Nil, fail1 :: Nil)
- assert(spec4 === spec3.copy(htlcs = Set(), toLocalMsat = 3000 * 1000))
+ assert(spec4 === spec3.copy(htlcs = Set(), toLocal = MilliSatoshi(3000000)))
}
test("add, fulfill and fail htlcs from the receiver side") {
- val spec = CommitmentSpec(htlcs = Set(), feeratePerKw = 1000, toLocalMsat = 0, toRemoteMsat = 5000 * 1000)
+ val spec = CommitmentSpec(htlcs = Set(), feeratePerKw = 1000, toLocal = MilliSatoshi(0), toRemote = MilliSatoshi(5000 * 1000))
val R = randomBytes32
val H = Crypto.sha256(R)
- val add1 = UpdateAddHtlc(ByteVector32.Zeroes, 1, 2000 * 1000, H, 400, TestConstants.emptyOnionPacket)
+ val add1 = UpdateAddHtlc(ByteVector32.Zeroes, 1, MilliSatoshi(2000 * 1000), H, 400, TestConstants.emptyOnionPacket)
val spec1 = CommitmentSpec.reduce(spec, Nil, add1 :: Nil)
- assert(spec1 === spec.copy(htlcs = Set(DirectedHtlc(IN, add1)), toRemoteMsat = 3000 * 1000))
+ assert(spec1 === spec.copy(htlcs = Set(DirectedHtlc(IN, add1)), toRemote = MilliSatoshi(3000 * 1000)))
- val add2 = UpdateAddHtlc(ByteVector32.Zeroes, 2, 1000 * 1000, H, 400, TestConstants.emptyOnionPacket)
+ val add2 = UpdateAddHtlc(ByteVector32.Zeroes, 2, MilliSatoshi(1000 * 1000), H, 400, TestConstants.emptyOnionPacket)
val spec2 = CommitmentSpec.reduce(spec1, Nil, add2 :: Nil)
- assert(spec2 === spec1.copy(htlcs = Set(DirectedHtlc(IN, add1), DirectedHtlc(IN, add2)), toRemoteMsat = 2000 * 1000))
+ assert(spec2 === spec1.copy(htlcs = Set(DirectedHtlc(IN, add1), DirectedHtlc(IN, add2)), toRemote = MilliSatoshi(2000 * 1000)))
val ful1 = UpdateFulfillHtlc(ByteVector32.Zeroes, add1.id, R)
val spec3 = CommitmentSpec.reduce(spec2, ful1 :: Nil, Nil)
- assert(spec3 === spec2.copy(htlcs = Set(DirectedHtlc(IN, add2)), toLocalMsat = 2000 * 1000))
+ assert(spec3 === spec2.copy(htlcs = Set(DirectedHtlc(IN, add2)), toLocal = MilliSatoshi(2000 * 1000)))
val fail1 = UpdateFailHtlc(ByteVector32.Zeroes, add2.id, R)
val spec4 = CommitmentSpec.reduce(spec3, fail1 :: Nil, Nil)
- assert(spec4 === spec3.copy(htlcs = Set(), toRemoteMsat = 3000 * 1000))
+ assert(spec4 === spec3.copy(htlcs = Set(), toRemote = MilliSatoshi(3000 * 1000)))
}
}
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/transactions/TestVectorsSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/transactions/TestVectorsSpec.scala
index 013d70b8fb..d52e1f13cc 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/transactions/TestVectorsSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/transactions/TestVectorsSpec.scala
@@ -17,8 +17,9 @@
package fr.acinq.eclair.transactions
import fr.acinq.bitcoin.Crypto.{PrivateKey, PublicKey}
-import fr.acinq.bitcoin._
-import fr.acinq.eclair.TestConstants
+import fr.acinq.bitcoin
+import fr.acinq.bitcoin.{ByteVector32, Crypto, Satoshi, Script, ScriptFlags, Transaction}
+import fr.acinq.eclair.{MilliSatoshi, TestConstants}
import fr.acinq.eclair.channel.Helpers.Funding
import fr.acinq.eclair.crypto.Generators
import fr.acinq.eclair.transactions.Transactions.{HtlcSuccessTx, HtlcTimeoutTx, TransactionWithInputInfo}
@@ -154,11 +155,11 @@ class TestVectorsSpec extends FunSuite with Logging {
)
val htlcs = Seq(
- DirectedHtlc(IN, UpdateAddHtlc(ByteVector32.Zeroes, 0, MilliSatoshi(1000000).amount, Crypto.sha256(paymentPreimages(0)), 500, TestConstants.emptyOnionPacket)),
- DirectedHtlc(IN, UpdateAddHtlc(ByteVector32.Zeroes, 0, MilliSatoshi(2000000).amount, Crypto.sha256(paymentPreimages(1)), 501, TestConstants.emptyOnionPacket)),
- DirectedHtlc(OUT, UpdateAddHtlc(ByteVector32.Zeroes, 0, MilliSatoshi(2000000).amount, Crypto.sha256(paymentPreimages(2)), 502, TestConstants.emptyOnionPacket)),
- DirectedHtlc(OUT, UpdateAddHtlc(ByteVector32.Zeroes, 0, MilliSatoshi(3000000).amount, Crypto.sha256(paymentPreimages(3)), 503, TestConstants.emptyOnionPacket)),
- DirectedHtlc(IN, UpdateAddHtlc(ByteVector32.Zeroes, 0, MilliSatoshi(4000000).amount, Crypto.sha256(paymentPreimages(4)), 504, TestConstants.emptyOnionPacket))
+ DirectedHtlc(IN, UpdateAddHtlc(ByteVector32.Zeroes, 0, MilliSatoshi(1000000), Crypto.sha256(paymentPreimages(0)), 500, TestConstants.emptyOnionPacket)),
+ DirectedHtlc(IN, UpdateAddHtlc(ByteVector32.Zeroes, 0, MilliSatoshi(2000000), Crypto.sha256(paymentPreimages(1)), 501, TestConstants.emptyOnionPacket)),
+ DirectedHtlc(OUT, UpdateAddHtlc(ByteVector32.Zeroes, 0, MilliSatoshi(2000000), Crypto.sha256(paymentPreimages(2)), 502, TestConstants.emptyOnionPacket)),
+ DirectedHtlc(OUT, UpdateAddHtlc(ByteVector32.Zeroes, 0, MilliSatoshi(3000000), Crypto.sha256(paymentPreimages(3)), 503, TestConstants.emptyOnionPacket)),
+ DirectedHtlc(IN, UpdateAddHtlc(ByteVector32.Zeroes, 0, MilliSatoshi(4000000), Crypto.sha256(paymentPreimages(4)), 504, TestConstants.emptyOnionPacket))
)
val htlcScripts = htlcs.map(htlc => htlc.direction match {
case OUT => Scripts.htlcOffered(Local.payment_privkey.publicKey, Remote.payment_privkey.publicKey, Local.revocation_pubkey, Crypto.ripemd160(htlc.add.paymentHash))
@@ -178,8 +179,8 @@ class TestVectorsSpec extends FunSuite with Logging {
}
def run(spec: CommitmentSpec) = {
- logger.info(s"to_local_msat: ${spec.toLocalMsat}")
- logger.info(s"to_remote_msat: ${spec.toRemoteMsat}")
+ logger.info(s"to_local_msat: ${spec.toLocal}")
+ logger.info(s"to_remote_msat: ${spec.toRemote}")
logger.info(s"local_feerate_per_kw: ${spec.feeratePerKw}")
val commitTx = {
@@ -286,7 +287,7 @@ class TestVectorsSpec extends FunSuite with Logging {
test("simple commitment tx with no HTLCs") {
val name = "simple commitment tx with no HTLCs"
logger.info(s"name: $name")
- val spec = CommitmentSpec(htlcs = Set.empty, feeratePerKw = 15000, toLocalMsat = 7000000000L, toRemoteMsat = 3000000000L)
+ val spec = CommitmentSpec(htlcs = Set.empty, feeratePerKw = 15000, toLocal = MilliSatoshi(7000000000L), toRemote = MilliSatoshi(3000000000L))
val (commitTx, htlcTxs) = run(spec)
assert(commitTx.tx.txOut.length == 2)
@@ -297,7 +298,7 @@ class TestVectorsSpec extends FunSuite with Logging {
test("commitment tx with all 5 htlcs untrimmed (minimum feerate)") {
val name = "commitment tx with all 5 htlcs untrimmed (minimum feerate)"
logger.info(s"name: $name")
- val spec = CommitmentSpec(htlcs = htlcs.toSet, feeratePerKw = 0, toLocalMsat = 6988000000L, toRemoteMsat = 3000000000L)
+ val spec = CommitmentSpec(htlcs = htlcs.toSet, feeratePerKw = 0, toLocal = MilliSatoshi(6988000000L), toRemote = MilliSatoshi(3000000000L))
val (commitTx, htlcTxs) = run(spec)
assert(commitTx.tx.txOut.length == 7)
@@ -308,7 +309,7 @@ class TestVectorsSpec extends FunSuite with Logging {
val name = "commitment tx with 7 outputs untrimmed (maximum feerate)"
logger.info(s"name: $name")
val feeratePerKw = 454999 / Transactions.htlcSuccessWeight
- val spec = CommitmentSpec(htlcs = htlcs.toSet, feeratePerKw = feeratePerKw, toLocalMsat = 6988000000L, toRemoteMsat = 3000000000L)
+ val spec = CommitmentSpec(htlcs = htlcs.toSet, feeratePerKw = feeratePerKw, toLocal = MilliSatoshi(6988000000L), toRemote = MilliSatoshi(3000000000L))
val (commitTx, htlcTxs) = run(spec)
assert(commitTx.tx.txOut.length == 7)
@@ -322,7 +323,7 @@ class TestVectorsSpec extends FunSuite with Logging {
val name = "commitment tx with 6 outputs untrimmed (minimum feerate)"
logger.info(s"name: $name")
val feeratePerKw = 454999 / Transactions.htlcSuccessWeight
- val spec = CommitmentSpec(htlcs = htlcs.toSet, feeratePerKw = feeratePerKw + 1, toLocalMsat = 6988000000L, toRemoteMsat = 3000000000L)
+ val spec = CommitmentSpec(htlcs = htlcs.toSet, feeratePerKw = feeratePerKw + 1, toLocal = MilliSatoshi(6988000000L), toRemote = MilliSatoshi(3000000000L))
val (commitTx, htlcTxs) = run(spec)
assert(commitTx.tx.txOut.length == 6)
@@ -336,7 +337,7 @@ class TestVectorsSpec extends FunSuite with Logging {
val name = "commitment tx with 6 outputs untrimmed (maximum feerate)"
logger.info(s"name: $name")
val feeratePerKw = 1454999 / Transactions.htlcSuccessWeight
- val spec = CommitmentSpec(htlcs = htlcs.toSet, feeratePerKw = feeratePerKw, toLocalMsat = 6988000000L, toRemoteMsat = 3000000000L)
+ val spec = CommitmentSpec(htlcs = htlcs.toSet, feeratePerKw = feeratePerKw, toLocal = MilliSatoshi(6988000000L), toRemote = MilliSatoshi(3000000000L))
val (commitTx, htlcTxs) = run(spec)
assert(commitTx.tx.txOut.length == 6)
@@ -350,7 +351,7 @@ class TestVectorsSpec extends FunSuite with Logging {
val name = "commitment tx with 5 outputs untrimmed (minimum feerate)"
logger.info(s"name: $name")
val feeratePerKw = 1454999 / Transactions.htlcSuccessWeight
- val spec = CommitmentSpec(htlcs = htlcs.toSet, feeratePerKw = feeratePerKw + 1, toLocalMsat = 6988000000L, toRemoteMsat = 3000000000L)
+ val spec = CommitmentSpec(htlcs = htlcs.toSet, feeratePerKw = feeratePerKw + 1, toLocal = MilliSatoshi(6988000000L), toRemote = MilliSatoshi(3000000000L))
val (commitTx, htlcTxs) = run(spec)
assert(commitTx.tx.txOut.length == 5)
@@ -364,7 +365,7 @@ class TestVectorsSpec extends FunSuite with Logging {
val name = "commitment tx with 5 outputs untrimmed (maximum feerate)"
logger.info(s"name: $name")
val feeratePerKw = 1454999 / Transactions.htlcTimeoutWeight
- val spec = CommitmentSpec(htlcs = htlcs.toSet, feeratePerKw = feeratePerKw, toLocalMsat = 6988000000L, toRemoteMsat = 3000000000L)
+ val spec = CommitmentSpec(htlcs = htlcs.toSet, feeratePerKw = feeratePerKw, toLocal = MilliSatoshi(6988000000L), toRemote = MilliSatoshi(3000000000L))
val (commitTx, htlcTxs) = run(spec)
assert(commitTx.tx.txOut.length == 5)
@@ -378,7 +379,7 @@ class TestVectorsSpec extends FunSuite with Logging {
val name = "commitment tx with 4 outputs untrimmed (minimum feerate)"
logger.info(s"name: $name")
val feeratePerKw = 1454999 / Transactions.htlcTimeoutWeight
- val spec = CommitmentSpec(htlcs = htlcs.toSet, feeratePerKw = feeratePerKw + 1, toLocalMsat = 6988000000L, toRemoteMsat = 3000000000L)
+ val spec = CommitmentSpec(htlcs = htlcs.toSet, feeratePerKw = feeratePerKw + 1, toLocal = MilliSatoshi(6988000000L), toRemote = MilliSatoshi(3000000000L))
val (commitTx, htlcTxs) = run(spec)
assert(commitTx.tx.txOut.length == 4)
@@ -392,7 +393,7 @@ class TestVectorsSpec extends FunSuite with Logging {
val name = "commitment tx with 4 outputs untrimmed (maximum feerate)"
logger.info(s"name: $name")
val feeratePerKw = 2454999 / Transactions.htlcTimeoutWeight
- val spec = CommitmentSpec(htlcs = htlcs.toSet, feeratePerKw = feeratePerKw, toLocalMsat = 6988000000L, toRemoteMsat = 3000000000L)
+ val spec = CommitmentSpec(htlcs = htlcs.toSet, feeratePerKw = feeratePerKw, toLocal = MilliSatoshi(6988000000L), toRemote = MilliSatoshi(3000000000L))
val (commitTx, htlcTxs) = run(spec)
assert(commitTx.tx.txOut.length == 4)
@@ -406,7 +407,7 @@ class TestVectorsSpec extends FunSuite with Logging {
val name = "commitment tx with 3 outputs untrimmed (minimum feerate)"
logger.info(s"name: $name")
val feeratePerKw = 2454999 / Transactions.htlcTimeoutWeight
- val spec = CommitmentSpec(htlcs = htlcs.toSet, feeratePerKw = feeratePerKw + 1, toLocalMsat = 6988000000L, toRemoteMsat = 3000000000L)
+ val spec = CommitmentSpec(htlcs = htlcs.toSet, feeratePerKw = feeratePerKw + 1, toLocal = MilliSatoshi(6988000000L), toRemote = MilliSatoshi(3000000000L))
val (commitTx, htlcTxs) = run(spec)
assert(commitTx.tx.txOut.length == 3)
@@ -420,7 +421,7 @@ class TestVectorsSpec extends FunSuite with Logging {
val name = "commitment tx with 3 outputs untrimmed (maximum feerate)"
logger.info(s"name: $name")
val feeratePerKw = 3454999 / Transactions.htlcSuccessWeight
- val spec = CommitmentSpec(htlcs = htlcs.toSet, feeratePerKw = feeratePerKw, toLocalMsat = 6988000000L, toRemoteMsat = 3000000000L)
+ val spec = CommitmentSpec(htlcs = htlcs.toSet, feeratePerKw = feeratePerKw, toLocal = MilliSatoshi(6988000000L), toRemote = MilliSatoshi(3000000000L))
val (commitTx, htlcTxs) = run(spec)
assert(commitTx.tx.txOut.length == 3)
@@ -434,7 +435,7 @@ class TestVectorsSpec extends FunSuite with Logging {
val name = "commitment tx with 2 outputs untrimmed (minimum feerate)"
logger.info(s"name: $name")
val feeratePerKw = 3454999 / Transactions.htlcSuccessWeight
- val spec = CommitmentSpec(htlcs = htlcs.toSet, feeratePerKw = feeratePerKw + 1, toLocalMsat = 6988000000L, toRemoteMsat = 3000000000L)
+ val spec = CommitmentSpec(htlcs = htlcs.toSet, feeratePerKw = feeratePerKw + 1, toLocal = MilliSatoshi(6988000000L), toRemote = MilliSatoshi(3000000000L))
val (commitTx, htlcTxs) = run(spec)
assert(commitTx.tx.txOut.length == 2)
@@ -447,7 +448,7 @@ class TestVectorsSpec extends FunSuite with Logging {
test("commitment tx with 2 outputs untrimmed (maximum feerate)") {
val name = "commitment tx with 2 outputs untrimmed (maximum feerate)"
logger.info(s"name: $name")
- val spec = CommitmentSpec(htlcs = htlcs.toSet, feeratePerKw = 9651180, toLocalMsat = 6988000000L, toRemoteMsat = 3000000000L)
+ val spec = CommitmentSpec(htlcs = htlcs.toSet, feeratePerKw = 9651180, toLocal = MilliSatoshi(6988000000L), toRemote = MilliSatoshi(3000000000L))
val (commitTx, htlcTxs) = run(spec)
assert(commitTx.tx.txOut.length == 2)
@@ -460,7 +461,7 @@ class TestVectorsSpec extends FunSuite with Logging {
test("commitment tx with 1 output untrimmed (minimum feerate)") {
val name = "commitment tx with 1 output untrimmed (minimum feerate)"
logger.info(s"name: $name")
- val spec = CommitmentSpec(htlcs = htlcs.toSet, feeratePerKw = 9651181, toLocalMsat = 6988000000L, toRemoteMsat = 3000000000L)
+ val spec = CommitmentSpec(htlcs = htlcs.toSet, feeratePerKw = 9651181, toLocal = MilliSatoshi(6988000000L), toRemote = MilliSatoshi(3000000000L))
val (commitTx, htlcTxs) = run(spec)
assert(commitTx.tx.txOut.length == 1)
@@ -473,7 +474,7 @@ class TestVectorsSpec extends FunSuite with Logging {
test("commitment tx with fee greater than funder amount") {
val name = "commitment tx with fee greater than funder amount"
logger.info(s"name: $name")
- val spec = CommitmentSpec(htlcs = htlcs.toSet, feeratePerKw = 9651936, toLocalMsat = 6988000000L, toRemoteMsat = 3000000000L)
+ val spec = CommitmentSpec(htlcs = htlcs.toSet, feeratePerKw = 9651936, toLocal = MilliSatoshi(6988000000L), toRemote = MilliSatoshi(3000000000L))
val (commitTx, htlcTxs) = run(spec)
assert(commitTx.tx.txOut.length == 1)
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/transactions/TransactionsSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/transactions/TransactionsSpec.scala
index f3819c8bc8..e323788552 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/transactions/TransactionsSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/transactions/TransactionsSpec.scala
@@ -20,9 +20,10 @@ import java.nio.ByteOrder
import fr.acinq.bitcoin.Crypto.{PrivateKey, ripemd160, sha256}
import fr.acinq.bitcoin.Script.{pay2wpkh, pay2wsh, write}
-import fr.acinq.bitcoin._
+import fr.acinq.bitcoin.{Btc, ByteVector32, Crypto, MilliBtc, Protocol, Satoshi, Script, Transaction, TxOut, millibtc2satoshi}
import fr.acinq.eclair.channel.Helpers.Funding
-import fr.acinq.eclair.{TestConstants, randomBytes32}
+import fr.acinq.eclair.{MilliSatoshi, TestConstants, randomBytes32}
+import fr.acinq.eclair._
import fr.acinq.eclair.transactions.Scripts.{htlcOffered, htlcReceived, toLocalDelayed}
import fr.acinq.eclair.transactions.Transactions.{addSigs, _}
import fr.acinq.eclair.wire.UpdateAddHtlc
@@ -63,12 +64,12 @@ class TransactionsSpec extends FunSuite with Logging {
test("compute fees") {
// see BOLT #3 specs
val htlcs = Set(
- DirectedHtlc(OUT, UpdateAddHtlc(ByteVector32.Zeroes, 0, MilliSatoshi(5000000).amount, ByteVector32.Zeroes, 552, TestConstants.emptyOnionPacket)),
- DirectedHtlc(OUT, UpdateAddHtlc(ByteVector32.Zeroes, 0, MilliSatoshi(1000000).amount, ByteVector32.Zeroes, 553, TestConstants.emptyOnionPacket)),
- DirectedHtlc(IN, UpdateAddHtlc(ByteVector32.Zeroes, 0, MilliSatoshi(7000000).amount, ByteVector32.Zeroes, 550, TestConstants.emptyOnionPacket)),
- DirectedHtlc(IN, UpdateAddHtlc(ByteVector32.Zeroes, 0, MilliSatoshi(800000).amount, ByteVector32.Zeroes, 551, TestConstants.emptyOnionPacket))
+ DirectedHtlc(OUT, UpdateAddHtlc(ByteVector32.Zeroes, 0, MilliSatoshi(5000000), ByteVector32.Zeroes, 552, TestConstants.emptyOnionPacket)),
+ DirectedHtlc(OUT, UpdateAddHtlc(ByteVector32.Zeroes, 0, MilliSatoshi(1000000), ByteVector32.Zeroes, 553, TestConstants.emptyOnionPacket)),
+ DirectedHtlc(IN, UpdateAddHtlc(ByteVector32.Zeroes, 0, MilliSatoshi(7000000), ByteVector32.Zeroes, 550, TestConstants.emptyOnionPacket)),
+ DirectedHtlc(IN, UpdateAddHtlc(ByteVector32.Zeroes, 0, MilliSatoshi(800000), ByteVector32.Zeroes, 551, TestConstants.emptyOnionPacket))
)
- val spec = CommitmentSpec(htlcs, feeratePerKw = 5000, toLocalMsat = 0, toRemoteMsat = 0)
+ val spec = CommitmentSpec(htlcs, feeratePerKw = 5000, toLocal = MilliSatoshi(0), toRemote = MilliSatoshi(0))
val fee = Transactions.commitTxFee(Satoshi(546), spec)
assert(fee == Satoshi(5340))
}
@@ -125,10 +126,10 @@ class TransactionsSpec extends FunSuite with Logging {
// HtlcPenaltyTx
// first we create a fake commitTx tx, containing only the output that will be spent by the ClaimHtlcSuccessTx
val paymentPreimage = randomBytes32
- val htlc = UpdateAddHtlc(ByteVector32.Zeroes, 0, Satoshi(20000).amount * 1000, sha256(paymentPreimage), cltvExpiry = 400144, TestConstants.emptyOnionPacket)
+ val htlc = UpdateAddHtlc(ByteVector32.Zeroes, 0, MilliSatoshi(20000 * 1000), sha256(paymentPreimage), cltvExpiry = 400144, TestConstants.emptyOnionPacket)
val redeemScript = htlcReceived(localHtlcPriv.publicKey, remoteHtlcPriv.publicKey, localRevocationPriv.publicKey, ripemd160(htlc.paymentHash), htlc.cltvExpiry)
val pubKeyScript = write(pay2wsh(redeemScript))
- val commitTx = Transaction(version = 0, txIn = Nil, txOut = TxOut(Satoshi(htlc.amountMsat / 1000), pubKeyScript) :: Nil, lockTime = 0)
+ val commitTx = Transaction(version = 0, txIn = Nil, txOut = TxOut(htlc.amountMsat.truncateToSatoshi, pubKeyScript) :: Nil, lockTime = 0)
val htlcPenaltyTx = makeHtlcPenaltyTx(commitTx, outputsAlreadyUsed = Set.empty, Script.write(redeemScript), localDustLimit, finalPubKeyScript, feeratePerKw)
// we use dummy signatures to compute the weight
val weight = Transaction.weight(addSigs(htlcPenaltyTx, PlaceHolderSig, localRevocationPriv.publicKey).tx)
@@ -140,9 +141,9 @@ class TransactionsSpec extends FunSuite with Logging {
// ClaimHtlcSuccessTx
// first we create a fake commitTx tx, containing only the output that will be spent by the ClaimHtlcSuccessTx
val paymentPreimage = randomBytes32
- val htlc = UpdateAddHtlc(ByteVector32.Zeroes, 0, Satoshi(20000).amount * 1000, sha256(paymentPreimage), cltvExpiry = 400144, TestConstants.emptyOnionPacket)
+ val htlc = UpdateAddHtlc(ByteVector32.Zeroes, 0, MilliSatoshi(20000 * 1000), sha256(paymentPreimage), cltvExpiry = 400144, TestConstants.emptyOnionPacket)
val pubKeyScript = write(pay2wsh(htlcOffered(localHtlcPriv.publicKey, remoteHtlcPriv.publicKey, localRevocationPriv.publicKey, ripemd160(htlc.paymentHash))))
- val commitTx = Transaction(version = 0, txIn = Nil, txOut = TxOut(Satoshi(htlc.amountMsat / 1000), pubKeyScript) :: Nil, lockTime = 0)
+ val commitTx = Transaction(version = 0, txIn = Nil, txOut = TxOut(htlc.amountMsat.truncateToSatoshi, pubKeyScript) :: Nil, lockTime = 0)
val claimHtlcSuccessTx = makeClaimHtlcSuccessTx(commitTx, outputsAlreadyUsed = Set.empty, localDustLimit, remoteHtlcPriv.publicKey, localHtlcPriv.publicKey, localRevocationPriv.publicKey, finalPubKeyScript, htlc, feeratePerKw)
// we use dummy signatures to compute the weight
val weight = Transaction.weight(addSigs(claimHtlcSuccessTx, PlaceHolderSig, paymentPreimage).tx)
@@ -154,9 +155,9 @@ class TransactionsSpec extends FunSuite with Logging {
// ClaimHtlcTimeoutTx
// first we create a fake commitTx tx, containing only the output that will be spent by the ClaimHtlcSuccessTx
val paymentPreimage = randomBytes32
- val htlc = UpdateAddHtlc(ByteVector32.Zeroes, 0, Satoshi(20000).amount * 1000, sha256(paymentPreimage), cltvExpiry = 400144, TestConstants.emptyOnionPacket)
+ val htlc = UpdateAddHtlc(ByteVector32.Zeroes, 0, MilliSatoshi(20000 * 1000), sha256(paymentPreimage), cltvExpiry = 400144, TestConstants.emptyOnionPacket)
val pubKeyScript = write(pay2wsh(htlcReceived(localHtlcPriv.publicKey, remoteHtlcPriv.publicKey, localRevocationPriv.publicKey, ripemd160(htlc.paymentHash), htlc.cltvExpiry)))
- val commitTx = Transaction(version = 0, txIn = Nil, txOut = TxOut(Satoshi(htlc.amountMsat / 1000), pubKeyScript) :: Nil, lockTime = 0)
+ val commitTx = Transaction(version = 0, txIn = Nil, txOut = TxOut(htlc.amountMsat.truncateToSatoshi, pubKeyScript) :: Nil, lockTime = 0)
val claimClaimHtlcTimeoutTx = makeClaimHtlcTimeoutTx(commitTx, outputsAlreadyUsed = Set.empty, localDustLimit, remoteHtlcPriv.publicKey, localHtlcPriv.publicKey, localRevocationPriv.publicKey, finalPubKeyScript, htlc, feeratePerKw)
// we use dummy signatures to compute the weight
val weight = Transaction.weight(addSigs(claimClaimHtlcTimeoutTx, PlaceHolderSig).tx)
@@ -183,14 +184,14 @@ class TransactionsSpec extends FunSuite with Logging {
// htlc1 and htlc2 are regular IN/OUT htlcs
val paymentPreimage1 = randomBytes32
- val htlc1 = UpdateAddHtlc(ByteVector32.Zeroes, 0, millibtc2satoshi(MilliBtc(100)).amount * 1000, sha256(paymentPreimage1), 300, TestConstants.emptyOnionPacket)
+ val htlc1 = UpdateAddHtlc(ByteVector32.Zeroes, 0, MilliBtc(100).toMilliSatoshi, sha256(paymentPreimage1), 300, TestConstants.emptyOnionPacket)
val paymentPreimage2 = randomBytes32
- val htlc2 = UpdateAddHtlc(ByteVector32.Zeroes, 1, millibtc2satoshi(MilliBtc(200)).amount * 1000, sha256(paymentPreimage2), 300, TestConstants.emptyOnionPacket)
+ val htlc2 = UpdateAddHtlc(ByteVector32.Zeroes, 1, MilliBtc(200).toMilliSatoshi, sha256(paymentPreimage2), 300, TestConstants.emptyOnionPacket)
// htlc3 and htlc4 are dust htlcs IN/OUT htlcs, with an amount large enough to be included in the commit tx, but too small to be claimed at 2nd stage
val paymentPreimage3 = randomBytes32
- val htlc3 = UpdateAddHtlc(ByteVector32.Zeroes, 2, (localDustLimit + weight2fee(feeratePerKw, htlcTimeoutWeight)).amount * 1000, sha256(paymentPreimage3), 300, TestConstants.emptyOnionPacket)
+ val htlc3 = UpdateAddHtlc(ByteVector32.Zeroes, 2, (localDustLimit + weight2fee(feeratePerKw, htlcTimeoutWeight)).toMilliSatoshi, sha256(paymentPreimage3), 300, TestConstants.emptyOnionPacket)
val paymentPreimage4 = randomBytes32
- val htlc4 = UpdateAddHtlc(ByteVector32.Zeroes, 3, (localDustLimit + weight2fee(feeratePerKw, htlcSuccessWeight)).amount * 1000, sha256(paymentPreimage4), 300, TestConstants.emptyOnionPacket)
+ val htlc4 = UpdateAddHtlc(ByteVector32.Zeroes, 3, (localDustLimit + weight2fee(feeratePerKw, htlcSuccessWeight)).toMilliSatoshi, sha256(paymentPreimage4), 300, TestConstants.emptyOnionPacket)
val spec = CommitmentSpec(
htlcs = Set(
DirectedHtlc(OUT, htlc1),
@@ -199,8 +200,8 @@ class TransactionsSpec extends FunSuite with Logging {
DirectedHtlc(IN, htlc4)
),
feeratePerKw = feeratePerKw,
- toLocalMsat = millibtc2satoshi(MilliBtc(400)).amount * 1000,
- toRemoteMsat = millibtc2satoshi(MilliBtc(300)).amount * 1000)
+ toLocal = millibtc2satoshi(MilliBtc(400)).toMilliSatoshi,
+ toRemote = millibtc2satoshi(MilliBtc(300)).toMilliSatoshi)
val commitTxNumber = 0x404142434445L
val commitTx = {
@@ -320,7 +321,7 @@ class TransactionsSpec extends FunSuite with Logging {
}
def htlc(direction: Direction, amount: Satoshi): DirectedHtlc =
- DirectedHtlc(direction, UpdateAddHtlc(ByteVector32.Zeroes, 0, amount.amount * 1000, ByteVector32.Zeroes, 144, TestConstants.emptyOnionPacket))
+ DirectedHtlc(direction, UpdateAddHtlc(ByteVector32.Zeroes, 0, amount.toMilliSatoshi, ByteVector32.Zeroes, 144, TestConstants.emptyOnionPacket))
test("BOLT 2 fee tests") {
@@ -353,7 +354,7 @@ class TransactionsSpec extends FunSuite with Logging {
case "received" => htlc(IN, Satoshi(amount.toLong))
}
}).toSet
- TestSetup(name, dustLimit, CommitmentSpec(htlcs = htlcs, feeratePerKw = feerate_per_kw.toLong, toLocalMsat = to_local_msat.toLong, toRemoteMsat = to_remote_msat.toLong), Satoshi(fee.toLong))
+ TestSetup(name, dustLimit, CommitmentSpec(htlcs = htlcs, feeratePerKw = feerate_per_kw.toLong, toLocal = MilliSatoshi(to_local_msat.toLong), toRemote = MilliSatoshi(to_remote_msat.toLong)), Satoshi(fee.toLong))
})
// simple non-reg test making sure we are not missing tests
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/wire/ChannelCodecsSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/wire/ChannelCodecsSpec.scala
index 81f6e6e0d6..c5a0af0449 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/wire/ChannelCodecsSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/wire/ChannelCodecsSpec.scala
@@ -21,7 +21,7 @@ import java.util.UUID
import akka.actor.ActorSystem
import fr.acinq.bitcoin.Crypto.PrivateKey
import fr.acinq.bitcoin.DeterministicWallet.KeyPath
-import fr.acinq.bitcoin.{Block, ByteVector32, Crypto, DeterministicWallet, MilliSatoshi, OutPoint, Satoshi, Transaction}
+import fr.acinq.bitcoin.{Block, ByteVector32, Crypto, DeterministicWallet, OutPoint, Satoshi, Transaction}
import fr.acinq.eclair._
import fr.acinq.eclair.api.JsonSupport
import fr.acinq.eclair.channel.Helpers.Funding
@@ -84,10 +84,10 @@ class ChannelCodecsSpec extends FunSuite {
val o = LocalParams(
nodeId = randomKey.publicKey,
channelKeyPath = DeterministicWallet.KeyPath(Seq(42L)),
- dustLimitSatoshis = Random.nextInt(Int.MaxValue),
+ dustLimit = Satoshi(Random.nextInt(Int.MaxValue)),
maxHtlcValueInFlightMsat = UInt64(Random.nextInt(Int.MaxValue)),
- channelReserveSatoshis = Random.nextInt(Int.MaxValue),
- htlcMinimumMsat = Random.nextInt(Int.MaxValue),
+ channelReserve = Satoshi(Random.nextInt(Int.MaxValue)),
+ htlcMinimum = MilliSatoshi(Random.nextInt(Int.MaxValue)),
toSelfDelay = Random.nextInt(Short.MaxValue),
maxAcceptedHtlcs = Random.nextInt(Short.MaxValue),
defaultFinalScriptPubKey = randomBytes(10 + Random.nextInt(200)),
@@ -102,10 +102,10 @@ class ChannelCodecsSpec extends FunSuite {
test("encode/decode remoteparams") {
val o = RemoteParams(
nodeId = randomKey.publicKey,
- dustLimitSatoshis = Random.nextInt(Int.MaxValue),
+ dustLimit = Satoshi(Random.nextInt(Int.MaxValue)),
maxHtlcValueInFlightMsat = UInt64(Random.nextInt(Int.MaxValue)),
- channelReserveSatoshis = Random.nextInt(Int.MaxValue),
- htlcMinimumMsat = Random.nextInt(Int.MaxValue),
+ channelReserve = Satoshi(Random.nextInt(Int.MaxValue)),
+ htlcMinimum = MilliSatoshi(Random.nextInt(Int.MaxValue)),
toSelfDelay = Random.nextInt(Short.MaxValue),
maxAcceptedHtlcs = Random.nextInt(Short.MaxValue),
fundingPubKey = randomKey.publicKey,
@@ -129,7 +129,7 @@ class ChannelCodecsSpec extends FunSuite {
val add = UpdateAddHtlc(
channelId = randomBytes32,
id = Random.nextInt(Int.MaxValue),
- amountMsat = Random.nextInt(Int.MaxValue),
+ amountMsat = MilliSatoshi(Random.nextInt(Int.MaxValue)),
cltvExpiry = Random.nextInt(Int.MaxValue),
paymentHash = randomBytes32,
onionRoutingPacket = TestConstants.emptyOnionPacket)
@@ -143,14 +143,14 @@ class ChannelCodecsSpec extends FunSuite {
val add1 = UpdateAddHtlc(
channelId = randomBytes32,
id = Random.nextInt(Int.MaxValue),
- amountMsat = Random.nextInt(Int.MaxValue),
+ amountMsat = MilliSatoshi(Random.nextInt(Int.MaxValue)),
cltvExpiry = Random.nextInt(Int.MaxValue),
paymentHash = randomBytes32,
onionRoutingPacket = TestConstants.emptyOnionPacket)
val add2 = UpdateAddHtlc(
channelId = randomBytes32,
id = Random.nextInt(Int.MaxValue),
- amountMsat = Random.nextInt(Int.MaxValue),
+ amountMsat = MilliSatoshi(Random.nextInt(Int.MaxValue)),
cltvExpiry = Random.nextInt(Int.MaxValue),
paymentHash = randomBytes32,
onionRoutingPacket = TestConstants.emptyOnionPacket)
@@ -161,8 +161,8 @@ class ChannelCodecsSpec extends FunSuite {
val o = CommitmentSpec(
htlcs = Set(htlc1, htlc2),
feeratePerKw = Random.nextInt(Int.MaxValue),
- toLocalMsat = Random.nextInt(Int.MaxValue),
- toRemoteMsat = Random.nextInt(Int.MaxValue)
+ toLocal = MilliSatoshi(Random.nextInt(Int.MaxValue)),
+ toRemote = MilliSatoshi(Random.nextInt(Int.MaxValue))
)
val encoded = commitmentSpecCodec.encode(o).require
val decoded = commitmentSpecCodec.decode(encoded).require
@@ -173,17 +173,17 @@ class ChannelCodecsSpec extends FunSuite {
val id = UUID.randomUUID()
assert(originCodec.decodeValue(originCodec.encode(Local(id, Some(ActorSystem("system").deadLetters))).require).require === Local(id, None))
// TODO: add backward compatibility check
- val relayed = Relayed(randomBytes32, 4324, 12000000L, 11000000L)
+ val relayed = Relayed(randomBytes32, 4324, MilliSatoshi(12000000L), MilliSatoshi(11000000L))
assert(originCodec.decodeValue(originCodec.encode(relayed).require).require === relayed)
}
test("encode/decode map of origins") {
val map = Map(
1L -> Local(UUID.randomUUID(), None),
- 42L -> Relayed(randomBytes32, 4324, 12000000L, 11000000L),
- 130L -> Relayed(randomBytes32, -45, 13000000L, 12000000L),
- 1000L -> Relayed(randomBytes32, 10, 14000000L, 13000000L),
- -32L -> Relayed(randomBytes32, 54, 15000000L, 14000000L),
+ 42L -> Relayed(randomBytes32, 4324, MilliSatoshi(12000000L), MilliSatoshi(11000000L)),
+ 130L -> Relayed(randomBytes32, -45, MilliSatoshi(13000000L), MilliSatoshi(12000000L)),
+ 1000L -> Relayed(randomBytes32, 10, MilliSatoshi(14000000L), MilliSatoshi(13000000L)),
+ -32L -> Relayed(randomBytes32, 54, MilliSatoshi(15000000L), MilliSatoshi(14000000L)),
-4L -> Local(UUID.randomUUID(), None))
assert(originsMapCodec.decodeValue(originsMapCodec.encode(map).require).require === map)
}
@@ -313,8 +313,24 @@ class ChannelCodecsSpec extends FunSuite {
// and we decode with the new codec
val newnormal = stateDataCodec.decode(newbin.bits).require.value
// finally we check that the actual data is the same as before (we just remove the new json field)
- val oldjson = Serialization.write(oldnormal)(JsonSupport.formats).replace(""","unknownFields":""""", "").replace(""""channelVersion":"00000000000000000000000000000000",""", "")
- val newjson = Serialization.write(newnormal)(JsonSupport.formats).replace(""","unknownFields":""""", "").replace(""""channelVersion":"00000000000000000000000000000000",""", "")
+ val oldjson = Serialization.write(oldnormal)(JsonSupport.formats)
+ .replace(""","unknownFields":""""", "")
+ .replace(""""channelVersion":"00000000000000000000000000000000",""", "")
+ .replace(""""dustLimit"""", """"dustLimitSatoshis"""")
+ .replace(""""channelReserve"""", """"channelReserveSatoshis"""")
+ .replace(""""htlcMinimum"""", """"htlcMinimumMsat"""")
+ .replace(""""toLocal"""", """"toLocalMsat"""")
+ .replace(""""toRemote"""", """"toRemoteMsat"""")
+
+ val newjson = Serialization.write(newnormal)(JsonSupport.formats)
+ .replace(""","unknownFields":""""", "")
+ .replace(""""channelVersion":"00000000000000000000000000000000",""", "")
+ .replace(""""dustLimit"""", """"dustLimitSatoshis"""")
+ .replace(""""channelReserve"""", """"channelReserveSatoshis"""")
+ .replace(""""htlcMinimum"""", """"htlcMinimumMsat"""")
+ .replace(""""toLocal"""", """"toLocalMsat"""")
+ .replace(""""toRemote"""", """"toRemoteMsat"""")
+
assert(oldjson === refjson)
assert(newjson === refjson)
}
@@ -328,10 +344,10 @@ object ChannelCodecsSpec {
val localParams = LocalParams(
keyManager.nodeId,
channelKeyPath = DeterministicWallet.KeyPath(Seq(42L)),
- dustLimitSatoshis = Satoshi(546).toLong,
+ dustLimit = Satoshi(546),
maxHtlcValueInFlightMsat = UInt64(50000000),
- channelReserveSatoshis = 10000,
- htlcMinimumMsat = 10000,
+ channelReserve = Satoshi(10000),
+ htlcMinimum = MilliSatoshi(10000),
toSelfDelay = 144,
maxAcceptedHtlcs = 50,
defaultFinalScriptPubKey = ByteVector.empty,
@@ -341,10 +357,10 @@ object ChannelCodecsSpec {
val remoteParams = RemoteParams(
nodeId = randomKey.publicKey,
- dustLimitSatoshis = Satoshi(546).toLong,
+ dustLimit = Satoshi(546),
maxHtlcValueInFlightMsat = UInt64(5000000),
- channelReserveSatoshis = 10000,
- htlcMinimumMsat = 5000,
+ channelReserve = Satoshi(10000),
+ htlcMinimum = MilliSatoshi(5000),
toSelfDelay = 144,
maxAcceptedHtlcs = 50,
fundingPubKey = PrivateKey(ByteVector32(ByteVector.fill(32)(1)) :+ 1.toByte).publicKey,
@@ -364,27 +380,27 @@ object ChannelCodecsSpec {
)
val htlcs = Seq(
- DirectedHtlc(IN, UpdateAddHtlc(ByteVector32.Zeroes, 0, MilliSatoshi(1000000).amount, Crypto.sha256(paymentPreimages(0)), 500, TestConstants.emptyOnionPacket)),
- DirectedHtlc(IN, UpdateAddHtlc(ByteVector32.Zeroes, 1, MilliSatoshi(2000000).amount, Crypto.sha256(paymentPreimages(1)), 501, TestConstants.emptyOnionPacket)),
- DirectedHtlc(OUT, UpdateAddHtlc(ByteVector32.Zeroes, 30, MilliSatoshi(2000000).amount, Crypto.sha256(paymentPreimages(2)), 502, TestConstants.emptyOnionPacket)),
- DirectedHtlc(OUT, UpdateAddHtlc(ByteVector32.Zeroes, 31, MilliSatoshi(3000000).amount, Crypto.sha256(paymentPreimages(3)), 503, TestConstants.emptyOnionPacket)),
- DirectedHtlc(IN, UpdateAddHtlc(ByteVector32.Zeroes, 2, MilliSatoshi(4000000).amount, Crypto.sha256(paymentPreimages(4)), 504, TestConstants.emptyOnionPacket))
+ DirectedHtlc(IN, UpdateAddHtlc(ByteVector32.Zeroes, 0, MilliSatoshi(1000000), Crypto.sha256(paymentPreimages(0)), 500, TestConstants.emptyOnionPacket)),
+ DirectedHtlc(IN, UpdateAddHtlc(ByteVector32.Zeroes, 1, MilliSatoshi(2000000), Crypto.sha256(paymentPreimages(1)), 501, TestConstants.emptyOnionPacket)),
+ DirectedHtlc(OUT, UpdateAddHtlc(ByteVector32.Zeroes, 30, MilliSatoshi(2000000), Crypto.sha256(paymentPreimages(2)), 502, TestConstants.emptyOnionPacket)),
+ DirectedHtlc(OUT, UpdateAddHtlc(ByteVector32.Zeroes, 31, MilliSatoshi(3000000), Crypto.sha256(paymentPreimages(3)), 503, TestConstants.emptyOnionPacket)),
+ DirectedHtlc(IN, UpdateAddHtlc(ByteVector32.Zeroes, 2, MilliSatoshi(4000000), Crypto.sha256(paymentPreimages(4)), 504, TestConstants.emptyOnionPacket))
)
val fundingTx = Transaction.read("0200000001adbb20ea41a8423ea937e76e8151636bf6093b70eaff942930d20576600521fd000000006b48304502210090587b6201e166ad6af0227d3036a9454223d49a1f11839c1a362184340ef0240220577f7cd5cca78719405cbf1de7414ac027f0239ef6e214c90fcaab0454d84b3b012103535b32d5eb0a6ed0982a0479bbadc9868d9836f6ba94dd5a63be16d875069184ffffffff028096980000000000220020c015c4a6be010e21657068fc2e6a9d02b27ebe4d490a25846f7237f104d1a3cd20256d29010000001600143ca33c2e4446f4a305f23c80df8ad1afdcf652f900000000")
val fundingAmount = fundingTx.txOut(0).amount
val commitmentInput = Funding.makeFundingInputInfo(fundingTx.hash, 0, fundingAmount, keyManager.fundingPublicKey(localParams.channelKeyPath).publicKey, remoteParams.fundingPubKey)
- val localCommit = LocalCommit(0, CommitmentSpec(htlcs.toSet, 1500, 50000000, 70000000), PublishableTxs(CommitTx(commitmentInput, Transaction(2, Nil, Nil, 0)), Nil))
- val remoteCommit = RemoteCommit(0, CommitmentSpec(htlcs.map(htlc => htlc.copy(direction = htlc.direction.opposite)).toSet, 1500, 50000, 700000), ByteVector32(hex"0303030303030303030303030303030303030303030303030303030303030303"), PrivateKey(ByteVector.fill(32)(4)).publicKey)
+ val localCommit = LocalCommit(0, CommitmentSpec(htlcs.toSet, 1500, MilliSatoshi(50000000), MilliSatoshi(70000000)), PublishableTxs(CommitTx(commitmentInput, Transaction(2, Nil, Nil, 0)), Nil))
+ val remoteCommit = RemoteCommit(0, CommitmentSpec(htlcs.map(htlc => htlc.copy(direction = htlc.direction.opposite)).toSet, 1500, MilliSatoshi(50000), MilliSatoshi(700000)), ByteVector32(hex"0303030303030303030303030303030303030303030303030303030303030303"), PrivateKey(ByteVector.fill(32)(4)).publicKey)
val commitments = Commitments(ChannelVersion.STANDARD, localParams, remoteParams, channelFlags = 0x01.toByte, localCommit, remoteCommit, LocalChanges(Nil, Nil, Nil), RemoteChanges(Nil, Nil, Nil),
localNextHtlcId = 32L,
remoteNextHtlcId = 4L,
- originChannels = Map(42L -> Local(UUID.randomUUID, None), 15000L -> Relayed(ByteVector32(ByteVector.fill(32)(42)), 43, 11000000L, 10000000L)),
+ originChannels = Map(42L -> Local(UUID.randomUUID, None), 15000L -> Relayed(ByteVector32(ByteVector.fill(32)(42)), 43, MilliSatoshi(11000000L), MilliSatoshi(10000000L))),
remoteNextCommitInfo = Right(randomKey.publicKey),
commitInput = commitmentInput, remotePerCommitmentSecrets = ShaChain.init, channelId = ByteVector32.Zeroes)
- val channelUpdate = Announcements.makeChannelUpdate(ByteVector32(ByteVector.fill(32)(1)), randomKey, randomKey.publicKey, ShortChannelId(142553), 42, 15, 575, 53, Channel.MAX_FUNDING_SATOSHIS * 1000L)
+ val channelUpdate = Announcements.makeChannelUpdate(ByteVector32(ByteVector.fill(32)(1)), randomKey, randomKey.publicKey, ShortChannelId(142553), 42, MilliSatoshi(15), MilliSatoshi(575), 53, Channel.MAX_FUNDING.toMilliSatoshi)
val normal = DATA_NORMAL(commitments, ShortChannelId(42), true, None, channelUpdate, None, None)
}
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/wire/FailureMessageCodecsSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/wire/FailureMessageCodecsSpec.scala
index 3b3ecd7a61..7f1f2ef22f 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/wire/FailureMessageCodecsSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/wire/FailureMessageCodecsSpec.scala
@@ -18,7 +18,7 @@ package fr.acinq.eclair.wire
import fr.acinq.bitcoin.{Block, ByteVector32, ByteVector64}
import fr.acinq.eclair.crypto.Hmac256
-import fr.acinq.eclair.{ShortChannelId, randomBytes32, randomBytes64}
+import fr.acinq.eclair.{MilliSatoshi, ShortChannelId, randomBytes32, randomBytes64}
import fr.acinq.eclair.wire.FailureMessageCodecs._
import org.scalatest.FunSuite
import scodec.bits._
@@ -36,8 +36,8 @@ class FailureMessageCodecsSpec extends FunSuite {
cltvExpiryDelta = 100,
messageFlags = 0,
channelFlags = 1,
- htlcMinimumMsat = 1000,
- feeBaseMsat = 12,
+ htlcMinimumMsat = MilliSatoshi(1000),
+ feeBaseMsat = MilliSatoshi(12),
feeProportionalMillionths = 76,
htlcMaximumMsat = None)
@@ -46,8 +46,8 @@ class FailureMessageCodecsSpec extends FunSuite {
InvalidRealm :: TemporaryNodeFailure :: PermanentNodeFailure :: RequiredNodeFeatureMissing ::
InvalidOnionVersion(randomBytes32) :: InvalidOnionHmac(randomBytes32) :: InvalidOnionKey(randomBytes32) :: InvalidOnionPayload(randomBytes32) ::
TemporaryChannelFailure(channelUpdate) :: PermanentChannelFailure :: RequiredChannelFeatureMissing :: UnknownNextPeer ::
- AmountBelowMinimum(123456, channelUpdate) :: FeeInsufficient(546463, channelUpdate) :: IncorrectCltvExpiry(1211, channelUpdate) :: ExpiryTooSoon(channelUpdate) ::
- IncorrectOrUnknownPaymentDetails(123456L) :: IncorrectPaymentAmount :: FinalExpiryTooSoon :: FinalIncorrectCltvExpiry(1234) :: ChannelDisabled(0, 1, channelUpdate) :: ExpiryTooFar :: Nil
+ AmountBelowMinimum(MilliSatoshi(123456), channelUpdate) :: FeeInsufficient(MilliSatoshi(546463), channelUpdate) :: IncorrectCltvExpiry(1211, channelUpdate) :: ExpiryTooSoon(channelUpdate) ::
+ IncorrectOrUnknownPaymentDetails(MilliSatoshi(123456L)) :: IncorrectPaymentAmount :: FinalExpiryTooSoon :: FinalIncorrectCltvExpiry(1234) :: ChannelDisabled(0, 1, channelUpdate) :: ExpiryTooFar :: Nil
msgs.foreach {
msg => {
@@ -75,7 +75,7 @@ class FailureMessageCodecsSpec extends FunSuite {
val codec = failureOnionCodec(Hmac256(ByteVector32.Zeroes))
val testCases = Map(
InvalidOnionKey(ByteVector32(hex"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a")) -> hex"41a824e2d630111669fa3e52b600a518f369691909b4e89205dc624ee17ed2c1 0022 c006 2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a 00de 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
- IncorrectOrUnknownPaymentDetails(42) -> hex"ba6e122b2941619e2106e8437bf525356ffc8439ac3b2245f68546e298a08cc6 000a 400f 000000000000002a 00f6 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+ IncorrectOrUnknownPaymentDetails(MilliSatoshi(42)) -> hex"ba6e122b2941619e2106e8437bf525356ffc8439ac3b2245f68546e298a08cc6 000a 400f 000000000000002a 00f6 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
)
for ((expected, bin) <- testCases) {
@@ -112,7 +112,7 @@ class FailureMessageCodecsSpec extends FunSuite {
test("support encoding of channel_update with/without type in failure messages") {
val tmp_channel_failure_notype = hex"10070080cc3e80149073ed487c76e48e9622bf980f78267b8a34a3f61921f2d8fce6063b08e74f34a073a13f2097337e4915bb4c001f3b5c4d81e9524ed575e1f45782196fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d619000000000008260500041300005b91b52f0003000e00000000000003e80000000100000001"
val tmp_channel_failure_withtype = hex"100700820102cc3e80149073ed487c76e48e9622bf980f78267b8a34a3f61921f2d8fce6063b08e74f34a073a13f2097337e4915bb4c001f3b5c4d81e9524ed575e1f45782196fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d619000000000008260500041300005b91b52f0003000e00000000000003e80000000100000001"
- val ref = TemporaryChannelFailure(ChannelUpdate(ByteVector64(hex"cc3e80149073ed487c76e48e9622bf980f78267b8a34a3f61921f2d8fce6063b08e74f34a073a13f2097337e4915bb4c001f3b5c4d81e9524ed575e1f4578219"), Block.LivenetGenesisBlock.hash, ShortChannelId(0x826050004130000L), 1536275759, 0, 3, 14, 1000, 1, 1, None))
+ val ref = TemporaryChannelFailure(ChannelUpdate(ByteVector64(hex"cc3e80149073ed487c76e48e9622bf980f78267b8a34a3f61921f2d8fce6063b08e74f34a073a13f2097337e4915bb4c001f3b5c4d81e9524ed575e1f4578219"), Block.LivenetGenesisBlock.hash, ShortChannelId(0x826050004130000L), 1536275759, 0, 3, 14, MilliSatoshi(1000), MilliSatoshi(1), 1, None))
val u = failureMessageCodec.decode(tmp_channel_failure_notype.toBitVector).require.value
assert(u === ref)
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/wire/LightningMessageCodecsSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/wire/LightningMessageCodecsSpec.scala
index ff2c26b5a2..90edaabaee 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/wire/LightningMessageCodecsSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/wire/LightningMessageCodecsSpec.scala
@@ -19,7 +19,7 @@ package fr.acinq.eclair.wire
import java.net.{Inet4Address, InetAddress}
import fr.acinq.bitcoin.Crypto.{PrivateKey, PublicKey}
-import fr.acinq.bitcoin.{Block, ByteVector32, ByteVector64}
+import fr.acinq.bitcoin.{Block, ByteVector32, ByteVector64, Satoshi}
import fr.acinq.eclair._
import fr.acinq.eclair.router.Announcements
import fr.acinq.eclair.wire.LightningMessageCodecs._
@@ -52,15 +52,15 @@ class LightningMessageCodecsSpec extends FunSuite {
}
test("encode/decode all channel messages") {
- val open = OpenChannel(randomBytes32, randomBytes32, 3, 4, 5, UInt64(6), 7, 8, 9, 10, 11, publicKey(1), point(2), point(3), point(4), point(5), point(6), 0.toByte)
- val accept = AcceptChannel(randomBytes32, 3, UInt64(4), 5, 6, 7, 8, 9, publicKey(1), point(2), point(3), point(4), point(5), point(6))
+ val open = OpenChannel(randomBytes32, randomBytes32, Satoshi(3), MilliSatoshi(4), Satoshi(5), UInt64(6), Satoshi(7), MilliSatoshi(8), 9, 10, 11, publicKey(1), point(2), point(3), point(4), point(5), point(6), 0.toByte)
+ val accept = AcceptChannel(randomBytes32, Satoshi(3), UInt64(4), Satoshi(5), MilliSatoshi(6), 7, 8, 9, publicKey(1), point(2), point(3), point(4), point(5), point(6))
val funding_created = FundingCreated(randomBytes32, bin32(0), 3, randomBytes64)
val funding_signed = FundingSigned(randomBytes32, randomBytes64)
val funding_locked = FundingLocked(randomBytes32, point(2))
val update_fee = UpdateFee(randomBytes32, 2)
val shutdown = Shutdown(randomBytes32, bin(47, 0))
- val closing_signed = ClosingSigned(randomBytes32, 2, randomBytes64)
- val update_add_htlc = UpdateAddHtlc(randomBytes32, 2, 3, bin32(0), 4, TestConstants.emptyOnionPacket)
+ val closing_signed = ClosingSigned(randomBytes32, Satoshi(2), randomBytes64)
+ val update_add_htlc = UpdateAddHtlc(randomBytes32, 2, MilliSatoshi(3), bin32(0), 4, TestConstants.emptyOnionPacket)
val update_fulfill_htlc = UpdateFulfillHtlc(randomBytes32, 2, bin32(0))
val update_fail_htlc = UpdateFailHtlc(randomBytes32, 2, bin(154, 0))
val update_fail_malformed_htlc = UpdateFailMalformedHtlc(randomBytes32, 2, randomBytes32, 1111)
@@ -68,7 +68,7 @@ class LightningMessageCodecsSpec extends FunSuite {
val revoke_and_ack = RevokeAndAck(randomBytes32, scalar(0), point(1))
val channel_announcement = ChannelAnnouncement(randomBytes64, randomBytes64, randomBytes64, randomBytes64, bin(7, 9), Block.RegtestGenesisBlock.hash, ShortChannelId(1), randomKey.publicKey, randomKey.publicKey, randomKey.publicKey, randomKey.publicKey)
val node_announcement = NodeAnnouncement(randomBytes64, bin(1, 2), 1, randomKey.publicKey, Color(100.toByte, 200.toByte, 300.toByte), "node-alias", IPv4(InetAddress.getByAddress(Array[Byte](192.toByte, 168.toByte, 1.toByte, 42.toByte)).asInstanceOf[Inet4Address], 42000) :: Nil)
- val channel_update = ChannelUpdate(randomBytes64, Block.RegtestGenesisBlock.hash, ShortChannelId(1), 2, 42, 0, 3, 4, 5, 6, None)
+ val channel_update = ChannelUpdate(randomBytes64, Block.RegtestGenesisBlock.hash, ShortChannelId(1), 2, 42, 0, 3, MilliSatoshi(4), MilliSatoshi(5), 6, None)
val announcement_signatures = AnnouncementSignatures(randomBytes32, ShortChannelId(42), randomBytes64, randomBytes64)
val gossip_timestamp_filter = GossipTimestampFilter(Block.RegtestGenesisBlock.blockId, 100000, 1500)
val query_short_channel_id = QueryShortChannelIds(Block.RegtestGenesisBlock.blockId, randomBytes(7515))
@@ -96,7 +96,7 @@ class LightningMessageCodecsSpec extends FunSuite {
// this was generated by c-lightning
val bin = hex"010258fff7d0e987e2cdd560e3bb5a046b4efe7b26c969c2f51da1dceec7bcb8ae1b634790503d5290c1a6c51d681cf8f4211d27ed33a257dcc1102862571bf1792306226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f0005a100000200005bc75919010100060000000000000001000000010000000a000000003a699d00"
val update = lightningMessageCodec.decode(bin.bits).require.value.asInstanceOf[ChannelUpdate]
- assert(update === ChannelUpdate(ByteVector64(hex"58fff7d0e987e2cdd560e3bb5a046b4efe7b26c969c2f51da1dceec7bcb8ae1b634790503d5290c1a6c51d681cf8f4211d27ed33a257dcc1102862571bf17923"), ByteVector32(hex"06226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f"), ShortChannelId(0x5a10000020000L), 1539791129, 1, 1, 6, 1, 1, 10, Some(980000000L)))
+ assert(update === ChannelUpdate(ByteVector64(hex"58fff7d0e987e2cdd560e3bb5a046b4efe7b26c969c2f51da1dceec7bcb8ae1b634790503d5290c1a6c51d681cf8f4211d27ed33a257dcc1102862571bf17923"), ByteVector32(hex"06226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f"), ShortChannelId(0x5a10000020000L), 1539791129, 1, 1, 6, MilliSatoshi(1), MilliSatoshi(1), 10, Some(MilliSatoshi(980000000L))))
val nodeId = PublicKey(hex"03370c9bac836e557eb4f017fe8f9cc047f44db39c1c4e410ff0f7be142b817ae4")
assert(Announcements.checkSig(update, nodeId))
val bin2 = ByteVector(lightningMessageCodec.encode(update).require.toByteArray)
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/wire/OnionCodecsSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/wire/OnionCodecsSpec.scala
index 763a9ce42a..bf236ed7b7 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/wire/OnionCodecsSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/wire/OnionCodecsSpec.scala
@@ -17,7 +17,7 @@
package fr.acinq.eclair.wire
import fr.acinq.bitcoin.ByteVector32
-import fr.acinq.eclair.ShortChannelId
+import fr.acinq.eclair.{MilliSatoshi, ShortChannelId}
import fr.acinq.eclair.wire.OnionCodecs._
import org.scalatest.FunSuite
import scodec.bits.HexStringSyntax
@@ -40,7 +40,7 @@ class OnionCodecsSpec extends FunSuite {
}
test("encode/decode per-hop payload") {
- val payload = PerHopPayload(shortChannelId = ShortChannelId(42), amtToForward = 142000, outgoingCltvValue = 500000)
+ val payload = PerHopPayload(shortChannelId = ShortChannelId(42), amtToForward = MilliSatoshi(142000), outgoingCltvValue = 500000)
val bin = perHopPayloadCodec.encode(payload).require
assert(bin.toByteVector.size === 33)
val payload1 = perHopPayloadCodec.decode(bin).require.value
diff --git a/eclair-node-gui/src/main/scala/fr/acinq/eclair/gui/GUIUpdater.scala b/eclair-node-gui/src/main/scala/fr/acinq/eclair/gui/GUIUpdater.scala
index ed96e755f0..1f955e9d4b 100644
--- a/eclair-node-gui/src/main/scala/fr/acinq/eclair/gui/GUIUpdater.scala
+++ b/eclair-node-gui/src/main/scala/fr/acinq/eclair/gui/GUIUpdater.scala
@@ -21,7 +21,7 @@ import java.time.LocalDateTime
import akka.actor.{Actor, ActorLogging, ActorRef, Terminated}
import fr.acinq.bitcoin.Crypto.PublicKey
import fr.acinq.bitcoin._
-import fr.acinq.eclair.CoinUtils
+import fr.acinq.eclair.{CoinUtils, MilliSatoshi}
import fr.acinq.eclair.blockchain.bitcoind.zmq.ZMQActor.{ZMQConnected, ZMQDisconnected}
import fr.acinq.eclair.blockchain.electrum.ElectrumClient.{ElectrumDisconnected, ElectrumReady}
import fr.acinq.eclair.channel._
@@ -187,11 +187,11 @@ class GUIUpdater(mainController: MainController) extends Actor with ActorLogging
val c = mainController.networkChannelsMap.get(channelUpdate.shortChannelId)
if (Announcements.isNode1(channelUpdate.channelFlags)) {
c.isNode1Enabled = Some(Announcements.isEnabled(channelUpdate.channelFlags))
- c.feeBaseMsatNode1_opt = Some(channelUpdate.feeBaseMsat)
+ c.feeBaseMsatNode1_opt = Some(channelUpdate.feeBaseMsat.toLong)
c.feeProportionalMillionthsNode1_opt = Some(channelUpdate.feeProportionalMillionths)
} else {
c.isNode2Enabled = Some(Announcements.isEnabled(channelUpdate.channelFlags))
- c.feeBaseMsatNode2_opt = Some(channelUpdate.feeBaseMsat)
+ c.feeBaseMsatNode2_opt = Some(channelUpdate.feeBaseMsat.toLong)
c.feeProportionalMillionthsNode2_opt = Some(channelUpdate.feeProportionalMillionths)
}
mainController.networkChannelsMap.put(channelUpdate.shortChannelId, c)
@@ -200,7 +200,7 @@ class GUIUpdater(mainController: MainController) extends Actor with ActorLogging
}
case p: PaymentSucceeded =>
- val message = CoinUtils.formatAmountInUnit(MilliSatoshi(p.amountMsat), FxApp.getUnit, withUnit = true)
+ val message = CoinUtils.formatAmountInUnit(p.amount, FxApp.getUnit, withUnit = true)
mainController.handlers.notification("Payment Sent", message, NOTIFICATION_SUCCESS)
case p: PaymentFailed =>
diff --git a/eclair-node-gui/src/main/scala/fr/acinq/eclair/gui/Handlers.scala b/eclair-node-gui/src/main/scala/fr/acinq/eclair/gui/Handlers.scala
index 80e286051b..54765f834a 100644
--- a/eclair-node-gui/src/main/scala/fr/acinq/eclair/gui/Handlers.scala
+++ b/eclair-node-gui/src/main/scala/fr/acinq/eclair/gui/Handlers.scala
@@ -20,7 +20,7 @@ import java.util.UUID
import akka.pattern.{AskTimeoutException, ask}
import akka.util.Timeout
-import fr.acinq.bitcoin.MilliSatoshi
+import fr.acinq.eclair.MilliSatoshi
import fr.acinq.eclair._
import fr.acinq.eclair.gui.controllers._
import fr.acinq.eclair.io.{NodeURI, Peer}
@@ -88,8 +88,8 @@ class Handlers(fKit: Future[Kit])(implicit ec: ExecutionContext = ExecutionConte
(for {
kit <- fKit
sendPayment = req.minFinalCltvExpiry match {
- case None => SendPayment(amountMsat, req.paymentHash, req.nodeId, req.routingInfo, maxAttempts = kit.nodeParams.maxPaymentAttempts)
- case Some(minFinalCltvExpiry) => SendPayment(amountMsat, req.paymentHash, req.nodeId, req.routingInfo, finalCltvExpiry = minFinalCltvExpiry, maxAttempts = kit.nodeParams.maxPaymentAttempts)
+ case None => SendPayment(MilliSatoshi(amountMsat), req.paymentHash, req.nodeId, req.routingInfo, maxAttempts = kit.nodeParams.maxPaymentAttempts)
+ case Some(minFinalCltvExpiry) => SendPayment(MilliSatoshi(amountMsat), req.paymentHash, req.nodeId, req.routingInfo, finalCltvExpiry = minFinalCltvExpiry, maxAttempts = kit.nodeParams.maxPaymentAttempts)
}
res <- (kit.paymentInitiator ? sendPayment).mapTo[UUID]
} yield res).recover {
diff --git a/eclair-node-gui/src/main/scala/fr/acinq/eclair/gui/controllers/ChannelPaneController.scala b/eclair-node-gui/src/main/scala/fr/acinq/eclair/gui/controllers/ChannelPaneController.scala
index 13e9be2d83..c4691f0148 100644
--- a/eclair-node-gui/src/main/scala/fr/acinq/eclair/gui/controllers/ChannelPaneController.scala
+++ b/eclair-node-gui/src/main/scala/fr/acinq/eclair/gui/controllers/ChannelPaneController.scala
@@ -18,7 +18,7 @@ package fr.acinq.eclair.gui.controllers
import akka.actor.ActorRef
import com.google.common.base.Strings
-import fr.acinq.bitcoin.MilliSatoshi
+import fr.acinq.eclair.MilliSatoshi
import fr.acinq.eclair.CoinUtils
import fr.acinq.eclair.channel.{CMD_CLOSE, CMD_FORCECLOSE, Commitments}
import fr.acinq.eclair.gui.FxApp
@@ -129,12 +129,12 @@ class ChannelPaneController(val channelRef: ActorRef, val peerNodeId: String) ex
}
def updateBalance(commitments: Commitments) {
- balance = MilliSatoshi(commitments.localCommit.spec.toLocalMsat)
- capacity = MilliSatoshi(commitments.localCommit.spec.totalFunds)
+ balance = commitments.localCommit.spec.toLocal
+ capacity = commitments.localCommit.spec.totalFunds
}
def refreshBalance(): Unit = {
- amountUs.setText(s"${CoinUtils.formatAmountInUnit(balance, FxApp.getUnit)} / ${CoinUtils.formatAmountInUnit(capacity, FxApp.getUnit, withUnit = true)}")
+ amountUs.setText(s"${CoinUtils.formatAmountInUnit(balance, FxApp.getUnit, false)} / ${CoinUtils.formatAmountInUnit(capacity, FxApp.getUnit, withUnit = true)}")
balanceBar.setProgress(balance.amount.toDouble / capacity.amount)
}
diff --git a/eclair-node-gui/src/main/scala/fr/acinq/eclair/gui/controllers/MainController.scala b/eclair-node-gui/src/main/scala/fr/acinq/eclair/gui/controllers/MainController.scala
index 1a8707be1c..60626148c8 100644
--- a/eclair-node-gui/src/main/scala/fr/acinq/eclair/gui/controllers/MainController.scala
+++ b/eclair-node-gui/src/main/scala/fr/acinq/eclair/gui/controllers/MainController.scala
@@ -23,14 +23,14 @@ import java.util.Locale
import com.google.common.net.HostAndPort
import fr.acinq.bitcoin.Crypto.PublicKey
-import fr.acinq.bitcoin.{MilliSatoshi, Satoshi}
+import fr.acinq.bitcoin.Satoshi
import fr.acinq.eclair.NodeParams.{BITCOIND, ELECTRUM}
import fr.acinq.eclair.gui.stages._
import fr.acinq.eclair.gui.utils.{ContextMenuUtils, CopyAction, IndexedObservableList}
import fr.acinq.eclair.gui.{FxApp, Handlers}
import fr.acinq.eclair.payment.{PaymentEvent, PaymentReceived, PaymentRelayed, PaymentSent}
import fr.acinq.eclair.wire.{ChannelAnnouncement, NodeAnnouncement}
-import fr.acinq.eclair.{CoinUtils, Setup, ShortChannelId}
+import fr.acinq.eclair.{CoinUtils, MilliSatoshi, Setup, ShortChannelId}
import grizzled.slf4j.Logging
import javafx.animation.{FadeTransition, ParallelTransition, SequentialTransition, TranslateTransition}
import javafx.application.{HostServices, Platform}
diff --git a/eclair-node-gui/src/main/scala/fr/acinq/eclair/gui/controllers/OpenChannelController.scala b/eclair-node-gui/src/main/scala/fr/acinq/eclair/gui/controllers/OpenChannelController.scala
index 9f6560553e..361ba9337a 100644
--- a/eclair-node-gui/src/main/scala/fr/acinq/eclair/gui/controllers/OpenChannelController.scala
+++ b/eclair-node-gui/src/main/scala/fr/acinq/eclair/gui/controllers/OpenChannelController.scala
@@ -19,12 +19,13 @@ package fr.acinq.eclair.gui.controllers
import java.lang.Boolean
import com.google.common.base.Strings
-import fr.acinq.bitcoin.{Satoshi, _}
+import fr.acinq.bitcoin.Satoshi
+import fr.acinq.eclair._
import fr.acinq.eclair.channel.{Channel, ChannelFlags}
import fr.acinq.eclair.gui.utils.Constants
import fr.acinq.eclair.gui.{FxApp, Handlers}
import fr.acinq.eclair.io.{NodeURI, Peer}
-import fr.acinq.eclair.{CoinUtils, Globals}
+import fr.acinq.eclair.{CoinUtils, Globals, MilliSatoshi}
import grizzled.slf4j.Logging
import javafx.beans.value.{ChangeListener, ObservableValue}
import javafx.event.ActionEvent
@@ -79,8 +80,8 @@ class OpenChannelController(val handlers: Handlers, val stage: Stage) extends Lo
fundingSatError.setText("Capacity must be greater than 0")
case Success(capacitySat) if capacitySat.amount < 50000 =>
fundingSatError.setText("Capacity is low and the channel may not be able to open")
- case Success(capacitySat) if capacitySat.amount >= Channel.MAX_FUNDING_SATOSHIS =>
- fundingSatError.setText(s"Capacity must be less than ${CoinUtils.formatAmountInUnit(Satoshi(Channel.MAX_FUNDING_SATOSHIS), FxApp.getUnit, withUnit = true)}")
+ case Success(capacitySat) if capacitySat >= Channel.MAX_FUNDING =>
+ fundingSatError.setText(s"Capacity must be less than ${CoinUtils.formatAmountInUnit(Channel.MAX_FUNDING, FxApp.getUnit, withUnit = true)}")
case Success(_) => fundingSatError.setText("")
case _ => fundingSatError.setText("Capacity is not valid")
}
@@ -100,9 +101,9 @@ class OpenChannelController(val handlers: Handlers, val stage: Stage) extends Lo
Try(if (Strings.isNullOrEmpty(feerateField.getText())) None else Some(feerateField.getText().toLong))) match {
case (Success(capacitySat), _, _) if capacitySat.amount <= 0 =>
fundingSatError.setText("Capacity must be greater than 0")
- case (Success(capacitySat), _, _) if capacitySat.amount >= Channel.MAX_FUNDING_SATOSHIS =>
- fundingSatError.setText(s"Capacity must be less than ${CoinUtils.formatAmountInUnit(Satoshi(Channel.MAX_FUNDING_SATOSHIS), FxApp.getUnit, withUnit = true)}")
- case (Success(capacitySat), Success(pushMsat), _) if pushMsat > satoshi2millisatoshi(capacitySat).amount =>
+ case (Success(capacitySat), _, _) if capacitySat >= Channel.MAX_FUNDING =>
+ fundingSatError.setText(s"Capacity must be less than ${CoinUtils.formatAmountInUnit(Channel.MAX_FUNDING, FxApp.getUnit, withUnit = true)}")
+ case (Success(capacitySat), Success(pushMsat), _) if pushMsat > capacitySat.toMilliSatoshi.toLong =>
pushMsatError.setText("Push must be less or equal to capacity")
case (Success(_), Success(pushMsat), _) if pushMsat < 0 =>
pushMsatError.setText("Push must be positive")
diff --git a/eclair-node-gui/src/main/scala/fr/acinq/eclair/gui/controllers/ReceivePaymentController.scala b/eclair-node-gui/src/main/scala/fr/acinq/eclair/gui/controllers/ReceivePaymentController.scala
index b0ad2fe916..2abe281afb 100644
--- a/eclair-node-gui/src/main/scala/fr/acinq/eclair/gui/controllers/ReceivePaymentController.scala
+++ b/eclair-node-gui/src/main/scala/fr/acinq/eclair/gui/controllers/ReceivePaymentController.scala
@@ -24,7 +24,7 @@ import javafx.scene.image.{ImageView, WritableImage}
import javafx.scene.layout.GridPane
import javafx.stage.Stage
-import fr.acinq.bitcoin.MilliSatoshi
+import fr.acinq.eclair.MilliSatoshi
import fr.acinq.eclair.CoinUtils
import fr.acinq.eclair.gui.{FxApp, Handlers}
import fr.acinq.eclair.gui.utils._
diff --git a/pom.xml b/pom.xml
index ed1e45b218..e5aa8bbc1d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -68,7 +68,7 @@
2.4.20
10.0.11
1.3.9
- 0.13
+ 0.14
24.0-android