From e73c1cf45c50a2ca4134be9cd780d66c39b9288a Mon Sep 17 00:00:00 2001
From: Bastien Teinturier <31281497+t-bast@users.noreply.github.com>
Date: Thu, 23 Nov 2023 16:04:31 +0100
Subject: [PATCH] Use typed TxId (#2742)
And explicitly encode/decode as a `tx_hash` for lightning messages.
---
.../main/scala/fr/acinq/eclair/Eclair.scala | 12 +-
.../scala/fr/acinq/eclair/NodeParams.scala | 10 +-
.../main/scala/fr/acinq/eclair/Setup.scala | 7 +-
.../acinq/eclair/balance/BalanceActor.scala | 10 +-
.../acinq/eclair/balance/CheckBalance.scala | 12 +-
.../eclair/blockchain/BlockchainEvents.scala | 4 +-
.../eclair/blockchain/OnChainWallet.scala | 14 +--
.../blockchain/bitcoind/ZmqWatcher.scala | 38 +++---
.../rpc/BasicBitcoinJsonRPCClient.scala | 8 +-
.../bitcoind/rpc/BitcoinCoreClient.scala | 111 +++++++++---------
.../blockchain/bitcoind/zmq/ZMQActor.scala | 8 +-
.../watchdogs/BlockchainWatchdog.scala | 4 +-
.../blockchain/watchdogs/ExplorerApi.scala | 14 +--
.../blockchain/watchdogs/HeadersOverDns.scala | 6 +-
.../fr/acinq/eclair/channel/ChannelData.scala | 6 +-
.../eclair/channel/ChannelExceptions.scala | 24 ++--
.../fr/acinq/eclair/channel/Commitments.scala | 16 +--
.../fr/acinq/eclair/channel/Helpers.scala | 10 +-
.../fr/acinq/eclair/channel/fsm/Channel.scala | 22 ++--
.../channel/fsm/ChannelOpenSingleFunded.scala | 16 +--
.../channel/fsm/CommonFundingHandlers.scala | 7 +-
.../channel/fsm/DualFundingHandlers.scala | 2 +-
.../channel/fund/InteractiveTxBuilder.scala | 10 +-
.../channel/publish/MempoolTxMonitor.scala | 8 +-
.../eclair/channel/publish/TxPublisher.scala | 6 +-
.../channel/publish/TxTimeLocksMonitor.scala | 6 +-
.../acinq/eclair/crypto/WeakEntropyPool.scala | 8 +-
.../keymanager/LocalChannelKeyManager.scala | 6 +-
.../keymanager/LocalNodeKeyManager.scala | 6 +-
.../keymanager/LocalOnChainKeyManager.scala | 43 ++++---
.../fr/acinq/eclair/db/DualDatabases.scala | 6 +-
.../scala/fr/acinq/eclair/db/NetworkDb.scala | 4 +-
.../fr/acinq/eclair/db/pg/PgAuditDb.scala | 4 +-
.../fr/acinq/eclair/db/pg/PgNetworkDb.scala | 8 +-
.../eclair/db/sqlite/SqliteAuditDb.scala | 4 +-
.../eclair/db/sqlite/SqliteNetworkDb.scala | 8 +-
.../main/scala/fr/acinq/eclair/io/Peer.scala | 4 +-
.../fr/acinq/eclair/io/PeerConnection.scala | 8 +-
.../acinq/eclair/json/JsonSerializers.scala | 52 ++++++--
.../main/scala/fr/acinq/eclair/package.scala | 8 +-
.../acinq/eclair/payment/Bolt11Invoice.scala | 4 +-
.../acinq/eclair/payment/Bolt12Invoice.scala | 4 +-
.../eclair/payment/send/OfferPayment.scala | 4 +-
.../remote/EclairInternalsSerializer.scala | 4 +-
.../acinq/eclair/router/Announcements.scala | 12 +-
.../scala/fr/acinq/eclair/router/Router.scala | 8 +-
.../scala/fr/acinq/eclair/router/Sync.scala | 4 +-
.../fr/acinq/eclair/router/Validation.scala | 10 +-
.../acinq/eclair/transactions/Scripts.scala | 4 +-
.../channel/version0/ChannelCodecs0.scala | 14 +--
.../channel/version0/ChannelTypes0.scala | 14 +--
.../channel/version1/ChannelCodecs1.scala | 8 +-
.../channel/version2/ChannelCodecs2.scala | 2 +-
.../channel/version3/ChannelCodecs3.scala | 2 +-
.../channel/version4/ChannelCodecs4.scala | 2 +-
.../eclair/wire/protocol/ChannelTlv.scala | 6 +-
.../eclair/wire/protocol/CommonCodecs.scala | 9 +-
.../wire/protocol/InteractiveTxTlv.scala | 8 +-
.../protocol/LightningMessageCodecs.scala | 26 ++--
.../wire/protocol/LightningMessageTypes.scala | 38 +++---
.../eclair/wire/protocol/OfferCodecs.scala | 6 +-
.../eclair/wire/protocol/OfferTypes.scala | 20 ++--
.../wire/protocol/SetupAndControlTlv.scala | 6 +-
.../funder/data.json | 2 +-
.../fr/acinq/eclair/EclairImplSpec.scala | 8 +-
.../scala/fr/acinq/eclair/PackageSpec.scala | 18 +--
.../acinq/eclair/TestBitcoinCoreClient.scala | 12 +-
.../scala/fr/acinq/eclair/TestUtils.scala | 6 +-
.../eclair/balance/CheckBalanceSpec.scala | 7 +-
.../blockchain/DummyOnChainWallet.scala | 37 +++---
.../bitcoind/BitcoinCoreClientSpec.scala | 19 +--
.../blockchain/bitcoind/ZmqWatcherSpec.scala | 31 ++---
.../eclair/channel/CommitmentsSpec.scala | 10 +-
.../fr/acinq/eclair/channel/HelpersSpec.scala | 2 +-
.../channel/InteractiveTxBuilderSpec.scala | 17 +--
.../publish/FinalTxPublisherSpec.scala | 4 +-
.../publish/MempoolTxMonitorSpec.scala | 11 +-
.../publish/ReplaceableTxFunderSpec.scala | 25 ++--
.../publish/ReplaceableTxPublisherSpec.scala | 4 +-
.../channel/publish/TxPublisherSpec.scala | 33 +++---
...aitForOpenDualFundedChannelStateSpec.scala | 4 +-
.../b/WaitForDualFundingSignedStateSpec.scala | 11 +-
.../states/e/NormalSplicesStateSpec.scala | 50 ++++----
.../channel/states/e/NormalStateSpec.scala | 2 +-
.../channel/states/h/ClosingStateSpec.scala | 11 +-
.../LocalOnChainKeyManagerSpec.scala | 2 +-
.../fr/acinq/eclair/db/AuditDbSpec.scala | 4 +-
.../fr/acinq/eclair/db/NetworkDbSpec.scala | 25 ++--
.../fr/acinq/eclair/db/PaymentsDbSpec.scala | 2 +-
.../integration/ChannelIntegrationSpec.scala | 4 +-
.../basic/fixtures/MinimalNodeFixture.scala | 8 +-
.../io/PendingChannelsRateLimiterSpec.scala | 12 +-
.../eclair/json/JsonSerializersSpec.scala | 32 ++---
.../eclair/payment/Bolt11InvoiceSpec.scala | 4 +-
.../eclair/payment/Bolt12InvoiceSpec.scala | 14 +--
.../eclair/payment/PaymentPacketSpec.scala | 3 +-
.../router/ChannelRangeQueriesSpec.scala | 6 +-
.../eclair/router/RouteCalculationSpec.scala | 22 ++--
.../acinq/eclair/router/RoutingSyncSpec.scala | 4 +-
.../eclair/testutils/PimpTestProbe.scala | 10 +-
.../eclair/transactions/TestVectorsSpec.scala | 2 +-
.../transactions/TransactionsSpec.scala | 31 ++---
.../internal/channel/ChannelCodecsSpec.scala | 8 +-
.../channel/version1/ChannelCodecs1Spec.scala | 15 +--
.../channel/version2/ChannelCodecs2Spec.scala | 11 +-
.../channel/version4/ChannelCodecs4Spec.scala | 7 +-
.../protocol/ExtendedQueriesCodecsSpec.scala | 18 +--
.../protocol/LightningMessageCodecsSpec.scala | 82 ++++++-------
.../eclair/wire/protocol/OfferTypesSpec.scala | 4 +-
.../fr/acinq/eclair/router/FrontRouter.scala | 7 +-
.../api/serde/FormParamExtractors.scala | 4 +-
.../fr/acinq/eclair/api/ApiServiceSpec.scala | 20 ++--
pom.xml | 2 +-
113 files changed, 757 insertions(+), 705 deletions(-)
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 86c0ec0162..e015c773ac 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/Eclair.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/Eclair.scala
@@ -24,7 +24,7 @@ import akka.pattern._
import akka.util.Timeout
import com.softwaremill.quicklens.ModifyPimp
import fr.acinq.bitcoin.scalacompat.Crypto.PublicKey
-import fr.acinq.bitcoin.scalacompat.{ByteVector32, ByteVector64, Crypto, OutPoint, Satoshi, Script, addressToPublicKeyScript}
+import fr.acinq.bitcoin.scalacompat.{BlockHash, ByteVector32, ByteVector64, Crypto, OutPoint, Satoshi, Script, TxId, addressToPublicKeyScript}
import fr.acinq.eclair.ApiTypes.ChannelNotFound
import fr.acinq.eclair.balance.CheckBalance.GlobalBalance
import fr.acinq.eclair.balance.{BalanceActor, ChannelsListener}
@@ -58,7 +58,7 @@ import java.util.UUID
import scala.concurrent.duration._
import scala.concurrent.{ExecutionContext, Future, Promise}
-case class GetInfoResponse(version: String, nodeId: PublicKey, alias: String, color: String, features: Features[Feature], chainHash: ByteVector32, network: String, blockHeight: Int, publicAddresses: Seq[NodeAddress], onionAddress: Option[NodeAddress], instanceId: String)
+case class GetInfoResponse(version: String, nodeId: PublicKey, alias: String, color: String, features: Features[Feature], chainHash: BlockHash, network: String, blockHeight: Int, publicAddresses: Seq[NodeAddress], onionAddress: Option[NodeAddress], instanceId: String)
case class AuditResponse(sent: Seq[PaymentSent], received: Seq[PaymentReceived], relayed: Seq[PaymentRelayed])
@@ -131,9 +131,9 @@ trait Eclair {
def sentInfo(id: PaymentIdentifier)(implicit timeout: Timeout): Future[Seq[OutgoingPayment]]
- def sendOnChain(address: String, amount: Satoshi, confirmationTargetOrFeerate: Either[Long, FeeratePerByte]): Future[ByteVector32]
+ def sendOnChain(address: String, amount: Satoshi, confirmationTargetOrFeerate: Either[Long, FeeratePerByte]): Future[TxId]
- def cpfpBumpFees(targetFeeratePerByte: FeeratePerByte, outpoints: Set[OutPoint]): Future[ByteVector32]
+ def cpfpBumpFees(targetFeeratePerByte: FeeratePerByte, outpoints: Set[OutPoint]): Future[TxId]
def findRoute(targetNodeId: PublicKey, amount: MilliSatoshi, pathFindingExperimentName_opt: Option[String], extraEdges: Seq[Invoice.ExtraEdge] = Seq.empty, includeLocalChannelCost: Boolean = false, ignoreNodeIds: Seq[PublicKey] = Seq.empty, ignoreShortChannelIds: Seq[ShortChannelId] = Seq.empty, maxFee_opt: Option[MilliSatoshi] = None)(implicit timeout: Timeout): Future[RouteResponse]
@@ -357,7 +357,7 @@ class EclairImpl(appKit: Kit) extends Eclair with Logging {
}
}
- override def sendOnChain(address: String, amount: Satoshi, confirmationTargetOrFeerate: Either[Long, FeeratePerByte]): Future[ByteVector32] = {
+ override def sendOnChain(address: String, amount: Satoshi, confirmationTargetOrFeerate: Either[Long, FeeratePerByte]): Future[TxId] = {
val feeRate = confirmationTargetOrFeerate match {
case Left(blocks) =>
if (blocks < 3) appKit.nodeParams.currentFeerates.fast
@@ -375,7 +375,7 @@ class EclairImpl(appKit: Kit) extends Eclair with Logging {
}
}
- override def cpfpBumpFees(targetFeeratePerByte: FeeratePerByte, outpoints: Set[OutPoint]): Future[ByteVector32] = {
+ override def cpfpBumpFees(targetFeeratePerByte: FeeratePerByte, outpoints: Set[OutPoint]): Future[TxId] = {
appKit.wallet match {
case w: BitcoinCoreClient => w.cpfp(outpoints, FeeratePerKw(targetFeeratePerByte)).map(_.txid)
case _ => Future.failed(new IllegalArgumentException("this call is only available with a bitcoin core backend"))
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 94cca6734d..90e108e96c 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/NodeParams.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/NodeParams.scala
@@ -18,7 +18,7 @@ package fr.acinq.eclair
import com.typesafe.config.{Config, ConfigFactory, ConfigValueType}
import fr.acinq.bitcoin.scalacompat.Crypto.PublicKey
-import fr.acinq.bitcoin.scalacompat.{Block, ByteVector32, Crypto, Satoshi}
+import fr.acinq.bitcoin.scalacompat.{Block, BlockHash, Crypto, Satoshi}
import fr.acinq.eclair.Setup.Seeds
import fr.acinq.eclair.blockchain.fee._
import fr.acinq.eclair.channel.ChannelFlags
@@ -73,7 +73,7 @@ case class NodeParams(nodeKeyManager: NodeKeyManager,
autoReconnect: Boolean,
initialRandomReconnectDelay: FiniteDuration,
maxReconnectInterval: FiniteDuration,
- chainHash: ByteVector32,
+ chainHash: BlockHash,
invoiceExpiry: FiniteDuration,
multiPartPaymentExpiry: FiniteDuration,
peerConnectionConf: PeerConnection.Conf,
@@ -184,16 +184,16 @@ object NodeParams extends Logging {
Seeds(nodeSeed, channelSeed)
}
- private val chain2Hash: Map[String, ByteVector32] = Map(
+ private val chain2Hash: Map[String, BlockHash] = Map(
"regtest" -> Block.RegtestGenesisBlock.hash,
"testnet" -> Block.TestnetGenesisBlock.hash,
"signet" -> Block.SignetGenesisBlock.hash,
"mainnet" -> Block.LivenetGenesisBlock.hash
)
- def hashFromChain(chain: String): ByteVector32 = chain2Hash.getOrElse(chain, throw new RuntimeException(s"invalid chain '$chain'"))
+ def hashFromChain(chain: String): BlockHash = chain2Hash.getOrElse(chain, throw new RuntimeException(s"invalid chain '$chain'"))
- def chainFromHash(chainHash: ByteVector32): String = chain2Hash.map(_.swap).getOrElse(chainHash, throw new RuntimeException(s"invalid chainHash '$chainHash'"))
+ def chainFromHash(chainHash: BlockHash): String = chain2Hash.map(_.swap).getOrElse(chainHash, throw new RuntimeException(s"invalid chainHash '$chainHash'"))
def parseSocks5ProxyParams(config: Config): Option[Socks5ProxyParams] = {
if (config.getBoolean("socks5.enabled")) {
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/Setup.scala b/eclair-core/src/main/scala/fr/acinq/eclair/Setup.scala
index d04a5105f5..ab04b5f70b 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/Setup.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/Setup.scala
@@ -23,7 +23,7 @@ import akka.actor.{ActorRef, ActorSystem, Props, SupervisorStrategy, typed}
import akka.pattern.after
import akka.util.Timeout
import fr.acinq.bitcoin.scalacompat.Crypto.PublicKey
-import fr.acinq.bitcoin.scalacompat.{Block, ByteVector32, Satoshi}
+import fr.acinq.bitcoin.scalacompat.{Block, BlockHash, BlockId, ByteVector32, Satoshi}
import fr.acinq.eclair.Setup.Seeds
import fr.acinq.eclair.balance.{BalanceActor, ChannelsListener}
import fr.acinq.eclair.blockchain._
@@ -134,7 +134,7 @@ class Setup(val datadir: File,
case "password" => BitcoinJsonRPCAuthMethod.UserPassword(config.getString("bitcoind.rpcuser"), config.getString("bitcoind.rpcpassword"))
}
- case class BitcoinStatus(version: Int, chainHash: ByteVector32, initialBlockDownload: Boolean, verificationProgress: Double, blockCount: Long, headerCount: Long, unspentAddresses: List[String])
+ case class BitcoinStatus(version: Int, chainHash: BlockHash, initialBlockDownload: Boolean, verificationProgress: Double, blockCount: Long, headerCount: Long, unspentAddresses: List[String])
def getBitcoinStatus(bitcoinClient: BasicBitcoinJsonRPCClient): Future[BitcoinStatus] = for {
json <- bitcoinClient.invoke("getblockchaininfo").recover { case e => throw BitcoinRPCConnectionException(e) }
@@ -147,7 +147,8 @@ class Setup(val datadir: File,
ibd = (json \ "initialblockdownload").extract[Boolean]
blocks = (json \ "blocks").extract[Long]
headers = (json \ "headers").extract[Long]
- chainHash <- bitcoinClient.invoke("getblockhash", 0).map(_.extract[String]).map(s => ByteVector32.fromValidHex(s)).map(_.reverse)
+ // NB: bitcoind confusingly returns the blockId instead of the blockHash.
+ chainHash <- bitcoinClient.invoke("getblockhash", 0).map(_.extract[String]).map(s => BlockId(ByteVector32.fromValidHex(s))).map(BlockHash(_))
bitcoinVersion <- bitcoinClient.invoke("getnetworkinfo").map(json => json \ "version").map(_.extract[Int])
unspentAddresses <- bitcoinClient.invoke("listunspent").recover { _ => if (wallet.isEmpty && wallets.length > 1) throw BitcoinDefaultWalletException(wallets) else throw BitcoinWalletNotLoadedException(wallet.getOrElse(""), wallets) }
.collect { case JArray(values) =>
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/balance/BalanceActor.scala b/eclair-core/src/main/scala/fr/acinq/eclair/balance/BalanceActor.scala
index 3924d70f34..f63d77ec51 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/balance/BalanceActor.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/balance/BalanceActor.scala
@@ -3,7 +3,7 @@ package fr.acinq.eclair.balance
import akka.actor.typed.eventstream.EventStream
import akka.actor.typed.scaladsl.{ActorContext, Behaviors}
import akka.actor.typed.{ActorRef, Behavior}
-import fr.acinq.bitcoin.scalacompat.{ByteVector32, SatoshiLong}
+import fr.acinq.bitcoin.scalacompat.{ByteVector32, SatoshiLong, TxId}
import fr.acinq.eclair.NotificationsLogger
import fr.acinq.eclair.NotificationsLogger.NotifyNodeOperator
import fr.acinq.eclair.balance.BalanceActor._
@@ -40,11 +40,11 @@ object BalanceActor {
}
}
- final case class UtxoInfo(utxos: Seq[Utxo], ancestorCount: Map[ByteVector32, Long])
+ final case class UtxoInfo(utxos: Seq[Utxo], ancestorCount: Map[TxId, Long])
def checkUtxos(bitcoinClient: BitcoinCoreClient)(implicit ec: ExecutionContext): Future[UtxoInfo] = {
- def getUnconfirmedAncestorCount(utxo: Utxo): Future[(ByteVector32, Long)] = bitcoinClient.rpcClient.invoke("getmempoolentry", utxo.txid).map(json => {
+ def getUnconfirmedAncestorCount(utxo: Utxo): Future[(TxId, Long)] = bitcoinClient.rpcClient.invoke("getmempoolentry", utxo.txid).map(json => {
val JInt(ancestorCount) = json \ "ancestorcount"
(utxo.txid, ancestorCount.toLong)
}).recover {
@@ -55,7 +55,7 @@ object BalanceActor {
(utxo.txid, 0)
}
- def getUnconfirmedAncestorCountMap(utxos: Seq[Utxo]): Future[Map[ByteVector32, Long]] = Future.sequence(utxos.filter(_.confirmations == 0).map(getUnconfirmedAncestorCount)).map(_.toMap)
+ def getUnconfirmedAncestorCountMap(utxos: Seq[Utxo]): Future[Map[TxId, Long]] = Future.sequence(utxos.filter(_.confirmations == 0).map(getUnconfirmedAncestorCount)).map(_.toMap)
for {
utxos <- bitcoinClient.listUnspent()
@@ -134,7 +134,7 @@ private class BalanceActor(context: ActorContext[Command],
Behaviors.same
case WrappedUtxoInfo(res) =>
res match {
- case Success(UtxoInfo(utxos: Seq[Utxo], ancestorCount: Map[ByteVector32, Long])) =>
+ case Success(UtxoInfo(utxos, ancestorCount)) =>
val filteredByStatus: Map[String, Seq[Utxo]] = Map(
Monitoring.Tags.UtxoStatuses.Confirmed -> utxos.filter(utxo => utxo.confirmations > 0),
// We cannot create chains of unconfirmed transactions with more than 25 elements, so we ignore such utxos.
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/balance/CheckBalance.scala b/eclair-core/src/main/scala/fr/acinq/eclair/balance/CheckBalance.scala
index 4c2f725587..2b3dd9e407 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/balance/CheckBalance.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/balance/CheckBalance.scala
@@ -1,7 +1,7 @@
package fr.acinq.eclair.balance
import com.softwaremill.quicklens._
-import fr.acinq.bitcoin.scalacompat.{Btc, ByteVector32, Satoshi, SatoshiLong, Script}
+import fr.acinq.bitcoin.scalacompat.{Btc, ByteVector32, Satoshi, SatoshiLong, Script, TxId}
import fr.acinq.eclair.blockchain.bitcoind.rpc.BitcoinCoreClient
import fr.acinq.eclair.channel.Helpers.Closing
import fr.acinq.eclair.channel.Helpers.Closing.{CurrentRemoteClose, LocalClose, NextRemoteClose, RemoteClose}
@@ -51,11 +51,11 @@ object CheckBalance {
* That's why we keep track of the id of each transaction that pays us any amount. It allows us to double check from
* bitcoin core and remove any published transaction.
*/
- case class PossiblyPublishedMainBalance(toLocal: Map[ByteVector32, Btc] = Map.empty) {
+ case class PossiblyPublishedMainBalance(toLocal: Map[TxId, Btc] = Map.empty) {
val total: Btc = toLocal.values.map(_.toSatoshi).sum
}
- case class PossiblyPublishedMainAndHtlcBalance(toLocal: Map[ByteVector32, Btc] = Map.empty, htlcs: Map[ByteVector32, Btc] = Map.empty, htlcsUnpublished: Btc = 0.sat) {
+ case class PossiblyPublishedMainAndHtlcBalance(toLocal: Map[TxId, Btc] = Map.empty, htlcs: Map[TxId, Btc] = Map.empty, htlcsUnpublished: Btc = 0.sat) {
val totalToLocal: Btc = toLocal.values.map(_.toSatoshi).sum
val totalHtlcs: Btc = htlcs.values.map(_.toSatoshi).sum
val total: Btc = totalToLocal + totalHtlcs + htlcsUnpublished
@@ -153,7 +153,7 @@ object CheckBalance {
val finalScriptPubKey = Script.write(Script.pay2wpkh(c.params.localParams.walletStaticPaymentBasepoint.get))
Transactions.findPubKeyScriptIndex(remoteCommitPublished.commitTx, finalScriptPubKey) match {
case Right(outputIndex) => Map(remoteCommitPublished.commitTx.txid -> remoteCommitPublished.commitTx.txOut(outputIndex).amount.toBtc)
- case _ => Map.empty[ByteVector32, Btc] // either we don't have an output (below dust), or we have used a non-default pubkey script
+ case _ => Map.empty[TxId, Btc] // either we don't have an output (below dust), or we have used a non-default pubkey script
}
} else {
remoteCommitPublished.claimMainOutputTx.toSeq.map(c => c.tx.txid -> c.tx.txOut.head.amount.toBtc).toMap
@@ -258,13 +258,13 @@ object CheckBalance {
*/
def prunePublishedTransactions(br: OffChainBalance, bitcoinClient: BitcoinCoreClient)(implicit ec: ExecutionContext): Future[OffChainBalance] = {
for {
- txs: Iterable[Option[(ByteVector32, Int)]] <- Future.sequence((br.closing.localCloseBalance.toLocal.keys ++
+ txs: Iterable[Option[(TxId, Int)]] <- Future.sequence((br.closing.localCloseBalance.toLocal.keys ++
br.closing.localCloseBalance.htlcs.keys ++
br.closing.remoteCloseBalance.toLocal.keys ++
br.closing.remoteCloseBalance.htlcs.keys ++
br.closing.mutualCloseBalance.toLocal.keys)
.map(txid => bitcoinClient.getTxConfirmations(txid).map(_ map { confirmations => txid -> confirmations })))
- txMap: Map[ByteVector32, Int] = txs.flatten.toMap
+ txMap: Map[TxId, Int] = txs.flatten.toMap
} yield {
br
.modifyAll(
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/BlockchainEvents.scala b/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/BlockchainEvents.scala
index 03d815948b..f65769062a 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/BlockchainEvents.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/BlockchainEvents.scala
@@ -16,7 +16,7 @@
package fr.acinq.eclair.blockchain
-import fr.acinq.bitcoin.scalacompat.{ByteVector32, Transaction}
+import fr.acinq.bitcoin.scalacompat.{BlockId, Transaction}
import fr.acinq.eclair.BlockHeight
import fr.acinq.eclair.blockchain.fee.FeeratesPerKw
@@ -26,7 +26,7 @@ import fr.acinq.eclair.blockchain.fee.FeeratesPerKw
sealed trait BlockchainEvent
-case class NewBlock(blockHash: ByteVector32) extends BlockchainEvent
+case class NewBlock(blockId: BlockId) extends BlockchainEvent
case class NewTransaction(tx: Transaction) extends BlockchainEvent
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/OnChainWallet.scala b/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/OnChainWallet.scala
index bc2ac328b5..dc9c1a0f6f 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/OnChainWallet.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/OnChainWallet.scala
@@ -18,7 +18,7 @@ package fr.acinq.eclair.blockchain
import fr.acinq.bitcoin.psbt.Psbt
import fr.acinq.bitcoin.scalacompat.Crypto.PublicKey
-import fr.acinq.bitcoin.scalacompat.{ByteVector32, OutPoint, Satoshi, Transaction}
+import fr.acinq.bitcoin.scalacompat.{OutPoint, Satoshi, Transaction, TxId}
import fr.acinq.eclair.blockchain.fee.FeeratePerKw
import scodec.bits.ByteVector
@@ -52,7 +52,7 @@ trait OnChainChannelFunder {
* Publish a transaction on the bitcoin network.
* This method must be idempotent: if the tx was already published, it must return a success.
*/
- def publishTransaction(tx: Transaction)(implicit ec: ExecutionContext): Future[ByteVector32]
+ def publishTransaction(tx: Transaction)(implicit ec: ExecutionContext): Future[TxId]
/** Create a fully signed channel funding transaction with the provided pubkeyScript. */
def makeFundingTx(pubkeyScript: ByteVector, amount: Satoshi, feeRate: FeeratePerKw)(implicit ec: ExecutionContext): Future[MakeFundingTxResponse]
@@ -70,10 +70,10 @@ trait OnChainChannelFunder {
def commit(tx: Transaction)(implicit ec: ExecutionContext): Future[Boolean]
/** Return the transaction if it exists, either in the blockchain or in the mempool. */
- def getTransaction(txId: ByteVector32)(implicit ec: ExecutionContext): Future[Transaction]
+ def getTransaction(txId: TxId)(implicit ec: ExecutionContext): Future[Transaction]
/** Get the number of confirmations of a given transaction. */
- def getTxConfirmations(txid: ByteVector32)(implicit ec: ExecutionContext): Future[Option[Int]]
+ def getTxConfirmations(txId: TxId)(implicit ec: ExecutionContext): Future[Option[Int]]
/** Rollback a transaction that we failed to commit: this probably translates to "release locks on utxos". */
def rollback(tx: Transaction)(implicit ec: ExecutionContext): Future[Boolean]
@@ -139,9 +139,9 @@ object OnChainWallet {
/** Transaction with all available witnesses. */
val partiallySignedTx: Transaction = {
- var tx = psbt.getGlobal.getTx
- for (i <- 0 until psbt.getInputs.size()) {
- Option(psbt.getInputs.get(i).getScriptWitness).foreach { witness =>
+ var tx = psbt.global.tx
+ for (i <- 0 until psbt.inputs.size()) {
+ Option(psbt.inputs.get(i).getScriptWitness).foreach { witness =>
tx = tx.updateWitness(i, witness)
}
}
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/bitcoind/ZmqWatcher.scala b/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/bitcoind/ZmqWatcher.scala
index a70885a8bb..2ec66eaf1d 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/bitcoind/ZmqWatcher.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/bitcoind/ZmqWatcher.scala
@@ -61,14 +61,14 @@ object ZmqWatcher {
private case class GetBlockCountFailed(t: Throwable) extends Command
private case class CheckBlockHeight(current: BlockHeight) extends Command
private case class PublishBlockHeight(current: BlockHeight) extends Command
- private case class ProcessNewBlock(blockHash: ByteVector32) extends Command
+ private case class ProcessNewBlock(blockId: BlockId) extends Command
private case class ProcessNewTransaction(tx: Transaction) extends Command
final case class ValidateRequest(replyTo: ActorRef[ValidateResult], ann: ChannelAnnouncement) extends Command
final case class ValidateResult(c: ChannelAnnouncement, fundingTx: Either[Throwable, (Transaction, UtxoStatus)])
- final case class GetTxWithMeta(replyTo: ActorRef[GetTxWithMetaResponse], txid: ByteVector32) extends Command
- final case class GetTxWithMetaResponse(txid: ByteVector32, tx_opt: Option[Transaction], lastBlockTimestamp: TimestampSecond)
+ final case class GetTxWithMeta(replyTo: ActorRef[GetTxWithMetaResponse], txid: TxId) extends Command
+ final case class GetTxWithMetaResponse(txid: TxId, tx_opt: Option[Transaction], lastBlockTimestamp: TimestampSecond)
sealed trait UtxoStatus
object UtxoStatus {
@@ -79,7 +79,7 @@ object ZmqWatcher {
/** Watch for confirmation of a given transaction. */
sealed trait WatchConfirmed[T <: WatchConfirmedTriggered] extends Watch[T] {
/** TxId of the transaction to watch. */
- def txId: ByteVector32
+ def txId: TxId
/** Number of confirmations. */
def minDepth: Long
}
@@ -93,14 +93,14 @@ object ZmqWatcher {
*/
sealed trait WatchSpent[T <: WatchSpentTriggered] extends Watch[T] {
/** TxId of the outpoint to watch. */
- def txId: ByteVector32
+ def txId: TxId
/** Index of the outpoint to watch. */
def outputIndex: Int
/**
* TxIds of potential spending transactions; most of the time we know the txs, and it allows for optimizations.
* This argument can safely be ignored by watcher implementations.
*/
- def hints: Set[ByteVector32]
+ def hints: Set[TxId]
}
/**
@@ -112,7 +112,7 @@ object ZmqWatcher {
*/
sealed trait WatchSpentBasic[T <: WatchSpentBasicTriggered] extends Watch[T] {
/** TxId of the outpoint to watch. */
- def txId: ByteVector32
+ def txId: TxId
/** Index of the outpoint to watch. */
def outputIndex: Int
}
@@ -136,32 +136,32 @@ object ZmqWatcher {
/** This event is sent when a [[WatchSpentBasic]] condition is met. */
sealed trait WatchSpentBasicTriggered extends WatchTriggered
- case class WatchExternalChannelSpent(replyTo: ActorRef[WatchExternalChannelSpentTriggered], txId: ByteVector32, outputIndex: Int, shortChannelId: RealShortChannelId) extends WatchSpentBasic[WatchExternalChannelSpentTriggered]
+ case class WatchExternalChannelSpent(replyTo: ActorRef[WatchExternalChannelSpentTriggered], txId: TxId, outputIndex: Int, shortChannelId: RealShortChannelId) extends WatchSpentBasic[WatchExternalChannelSpentTriggered]
case class WatchExternalChannelSpentTriggered(shortChannelId: RealShortChannelId) extends WatchSpentBasicTriggered
- case class WatchFundingSpent(replyTo: ActorRef[WatchFundingSpentTriggered], txId: ByteVector32, outputIndex: Int, hints: Set[ByteVector32]) extends WatchSpent[WatchFundingSpentTriggered]
+ case class WatchFundingSpent(replyTo: ActorRef[WatchFundingSpentTriggered], txId: TxId, outputIndex: Int, hints: Set[TxId]) extends WatchSpent[WatchFundingSpentTriggered]
case class WatchFundingSpentTriggered(spendingTx: Transaction) extends WatchSpentTriggered
- case class WatchOutputSpent(replyTo: ActorRef[WatchOutputSpentTriggered], txId: ByteVector32, outputIndex: Int, hints: Set[ByteVector32]) extends WatchSpent[WatchOutputSpentTriggered]
+ case class WatchOutputSpent(replyTo: ActorRef[WatchOutputSpentTriggered], txId: TxId, outputIndex: Int, hints: Set[TxId]) extends WatchSpent[WatchOutputSpentTriggered]
case class WatchOutputSpentTriggered(spendingTx: Transaction) extends WatchSpentTriggered
/** Waiting for a wallet transaction to be published guarantees that bitcoind won't double-spend it in the future, unless we explicitly call abandontransaction. */
- case class WatchPublished(replyTo: ActorRef[WatchPublishedTriggered], txId: ByteVector32) extends Watch[WatchPublishedTriggered]
+ case class WatchPublished(replyTo: ActorRef[WatchPublishedTriggered], txId: TxId) extends Watch[WatchPublishedTriggered]
case class WatchPublishedTriggered(tx: Transaction) extends WatchTriggered
- case class WatchFundingConfirmed(replyTo: ActorRef[WatchFundingConfirmedTriggered], txId: ByteVector32, minDepth: Long) extends WatchConfirmed[WatchFundingConfirmedTriggered]
+ case class WatchFundingConfirmed(replyTo: ActorRef[WatchFundingConfirmedTriggered], txId: TxId, minDepth: Long) extends WatchConfirmed[WatchFundingConfirmedTriggered]
case class WatchFundingConfirmedTriggered(blockHeight: BlockHeight, txIndex: Int, tx: Transaction) extends WatchConfirmedTriggered
- case class WatchFundingDeeplyBuried(replyTo: ActorRef[WatchFundingDeeplyBuriedTriggered], txId: ByteVector32, minDepth: Long) extends WatchConfirmed[WatchFundingDeeplyBuriedTriggered]
+ case class WatchFundingDeeplyBuried(replyTo: ActorRef[WatchFundingDeeplyBuriedTriggered], txId: TxId, minDepth: Long) extends WatchConfirmed[WatchFundingDeeplyBuriedTriggered]
case class WatchFundingDeeplyBuriedTriggered(blockHeight: BlockHeight, txIndex: Int, tx: Transaction) extends WatchConfirmedTriggered
- case class WatchTxConfirmed(replyTo: ActorRef[WatchTxConfirmedTriggered], txId: ByteVector32, minDepth: Long) extends WatchConfirmed[WatchTxConfirmedTriggered]
+ case class WatchTxConfirmed(replyTo: ActorRef[WatchTxConfirmedTriggered], txId: TxId, minDepth: Long) extends WatchConfirmed[WatchTxConfirmedTriggered]
case class WatchTxConfirmedTriggered(blockHeight: BlockHeight, txIndex: Int, tx: Transaction) extends WatchConfirmedTriggered
- case class WatchParentTxConfirmed(replyTo: ActorRef[WatchParentTxConfirmedTriggered], txId: ByteVector32, minDepth: Long) extends WatchConfirmed[WatchParentTxConfirmedTriggered]
+ case class WatchParentTxConfirmed(replyTo: ActorRef[WatchParentTxConfirmedTriggered], txId: TxId, minDepth: Long) extends WatchConfirmed[WatchParentTxConfirmedTriggered]
case class WatchParentTxConfirmedTriggered(blockHeight: BlockHeight, txIndex: Int, tx: Transaction) extends WatchConfirmedTriggered
- case class WatchAlternativeCommitTxConfirmed(replyTo: ActorRef[WatchAlternativeCommitTxConfirmedTriggered], txId: ByteVector32, minDepth: Long) extends WatchConfirmed[WatchAlternativeCommitTxConfirmedTriggered]
+ case class WatchAlternativeCommitTxConfirmed(replyTo: ActorRef[WatchAlternativeCommitTxConfirmedTriggered], txId: TxId, minDepth: Long) extends WatchConfirmed[WatchAlternativeCommitTxConfirmedTriggered]
case class WatchAlternativeCommitTxConfirmedTriggered(blockHeight: BlockHeight, txIndex: Int, tx: Transaction) extends WatchConfirmedTriggered
private sealed trait AddWatchResult
@@ -171,7 +171,7 @@ object ZmqWatcher {
def apply(nodeParams: NodeParams, blockCount: AtomicLong, client: BitcoinCoreClient): Behavior[Command] =
Behaviors.setup { context =>
- context.system.eventStream ! EventStream.Subscribe(context.messageAdapter[NewBlock](b => ProcessNewBlock(b.blockHash)))
+ context.system.eventStream ! EventStream.Subscribe(context.messageAdapter[NewBlock](b => ProcessNewBlock(b.blockId)))
context.system.eventStream ! EventStream.Subscribe(context.messageAdapter[NewTransaction](t => ProcessNewTransaction(t.tx)))
Behaviors.withTimers { timers =>
// we initialize block count
@@ -184,8 +184,8 @@ object ZmqWatcher {
private def utxo(w: GenericWatch): Option[OutPoint] = {
w match {
- case w: WatchSpent[_] => Some(OutPoint(w.txId.reverse, w.outputIndex))
- case w: WatchSpentBasic[_] => Some(OutPoint(w.txId.reverse, w.outputIndex))
+ case w: WatchSpent[_] => Some(OutPoint(w.txId, w.outputIndex))
+ case w: WatchSpentBasic[_] => Some(OutPoint(w.txId, w.outputIndex))
case _ => None
}
}
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/bitcoind/rpc/BasicBitcoinJsonRPCClient.scala b/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/bitcoind/rpc/BasicBitcoinJsonRPCClient.scala
index 30c7d342d8..4c05b98036 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/bitcoind/rpc/BasicBitcoinJsonRPCClient.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/bitcoind/rpc/BasicBitcoinJsonRPCClient.scala
@@ -18,7 +18,7 @@ package fr.acinq.eclair.blockchain.bitcoind.rpc
import fr.acinq.eclair.KamonExt
import fr.acinq.eclair.blockchain.Monitoring.{Metrics, Tags}
-import fr.acinq.eclair.json.{ByteVector32KmpSerializer, ByteVector32Serializer}
+import fr.acinq.eclair.json._
import org.json4s.JsonAST.JValue
import org.json4s.jackson.{JacksonSerialization, Serialization}
import org.json4s.{DefaultFormats, Formats}
@@ -34,7 +34,11 @@ import scala.util.{Failure, Success, Try}
class BasicBitcoinJsonRPCClient(rpcAuthMethod: BitcoinJsonRPCAuthMethod, host: String = "127.0.0.1", port: Int = 8332, ssl: Boolean = false, override val wallet: Option[String] = None)(implicit sb: SttpBackend[Future, _]) extends BitcoinJsonRPCClient {
- implicit val formats: Formats = DefaultFormats.withBigDecimal + ByteVector32Serializer + ByteVector32KmpSerializer
+ implicit val formats: Formats = DefaultFormats.withBigDecimal +
+ ByteVector32Serializer + ByteVector32KmpSerializer +
+ TxIdSerializer + TxIdKmpSerializer +
+ BlockHashSerializer + BlockHashKmpSerializer +
+ BlockIdSerializer + BlockIdKmpSerializer
private val scheme = if (ssl) "https" else "http"
private val serviceUri = wallet match {
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/bitcoind/rpc/BitcoinCoreClient.scala b/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/bitcoind/rpc/BitcoinCoreClient.scala
index e049611ec7..376a160e72 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/bitcoind/rpc/BitcoinCoreClient.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/bitcoind/rpc/BitcoinCoreClient.scala
@@ -64,15 +64,15 @@ class BitcoinCoreClient(val rpcClient: BitcoinJsonRPCClient, val onChainKeyManag
//------------------------- TRANSACTIONS -------------------------//
- def getTransaction(txid: ByteVector32)(implicit ec: ExecutionContext): Future[Transaction] =
+ def getTransaction(txid: TxId)(implicit ec: ExecutionContext): Future[Transaction] =
getRawTransaction(txid).map(raw => Transaction.read(raw))
- private def getRawTransaction(txid: ByteVector32)(implicit ec: ExecutionContext): Future[String] =
+ private def getRawTransaction(txid: TxId)(implicit ec: ExecutionContext): Future[String] =
rpcClient.invoke("getrawtransaction", txid).collect {
case JString(raw) => raw
}
- def getTransactionMeta(txid: ByteVector32)(implicit ec: ExecutionContext): Future[GetTxWithMetaResponse] =
+ def getTransactionMeta(txid: TxId)(implicit ec: ExecutionContext): Future[GetTxWithMetaResponse] =
for {
tx_opt <- getTransaction(txid).map(Some(_)).recover { case _ => None }
blockchainInfo <- rpcClient.invoke("getblockchaininfo")
@@ -80,7 +80,7 @@ class BitcoinCoreClient(val rpcClient: BitcoinJsonRPCClient, val onChainKeyManag
} yield GetTxWithMetaResponse(txid, tx_opt, TimestampSecond(timestamp.toLong))
/** Get the number of confirmations of a given transaction. */
- def getTxConfirmations(txid: ByteVector32)(implicit ec: ExecutionContext): Future[Option[Int]] =
+ def getTxConfirmations(txid: TxId)(implicit ec: ExecutionContext): Future[Option[Int]] =
rpcClient.invoke("getrawtransaction", txid, 1 /* verbose output is needed to get the number of confirmations */)
.map(json => Some((json \ "confirmations").extractOrElse[Int](0)))
.recover {
@@ -88,9 +88,9 @@ class BitcoinCoreClient(val rpcClient: BitcoinJsonRPCClient, val onChainKeyManag
}
/** Get the hash of the block containing a given transaction. */
- private def getTxBlockHash(txid: ByteVector32)(implicit ec: ExecutionContext): Future[Option[ByteVector32]] =
+ private def getTxBlockId(txid: TxId)(implicit ec: ExecutionContext): Future[Option[BlockId]] =
rpcClient.invoke("getrawtransaction", txid, 1 /* verbose output is needed to get the block hash */)
- .map(json => (json \ "blockhash").extractOpt[String].map(ByteVector32.fromValidHex))
+ .map(json => (json \ "blockhash").extractOpt[String].map(b => BlockId(ByteVector32.fromValidHex(b))))
.recover {
case t: JsonRPCError if t.error.code == -5 => None // Invalid or non-wallet transaction id (code: -5)
}
@@ -99,13 +99,13 @@ class BitcoinCoreClient(val rpcClient: BitcoinJsonRPCClient, val onChainKeyManag
* @return a Future[height, index] where height is the height of the block where this transaction was published, and
* index is the index of the transaction in that block.
*/
- def getTransactionShortId(txid: ByteVector32)(implicit ec: ExecutionContext): Future[(BlockHeight, Int)] =
+ def getTransactionShortId(txid: TxId)(implicit ec: ExecutionContext): Future[(BlockHeight, Int)] =
for {
- Some(blockHash) <- getTxBlockHash(txid)
- json <- rpcClient.invoke("getblock", blockHash)
+ Some(blockId) <- getTxBlockId(txid)
+ json <- rpcClient.invoke("getblock", blockId)
JInt(height) = json \ "height"
JArray(txs) = json \ "tx"
- index = txs.indexOf(JString(txid.toHex))
+ index = txs.indexOf(JString(txid.value.toHex))
} yield (BlockHeight(height.toInt), index)
/**
@@ -115,7 +115,7 @@ class BitcoinCoreClient(val rpcClient: BitcoinJsonRPCClient, val onChainKeyManag
* (not in the blockchain nor in the mempool) but could reappear later and be spendable at that point. If you want to
* ensure that an output is not spendable anymore, you should use [[isTransactionOutputSpent]].
*/
- def isTransactionOutputSpendable(txid: ByteVector32, outputIndex: Int, includeMempool: Boolean)(implicit ec: ExecutionContext): Future[Boolean] =
+ def isTransactionOutputSpendable(txid: TxId, outputIndex: Int, includeMempool: Boolean)(implicit ec: ExecutionContext): Future[Boolean] =
for {
json <- rpcClient.invoke("gettxout", txid, outputIndex, includeMempool)
} yield json != JNull
@@ -124,7 +124,7 @@ class BitcoinCoreClient(val rpcClient: BitcoinJsonRPCClient, val onChainKeyManag
* Return true if this output has already been spent by a confirmed transaction.
* Note that a reorg may invalidate the result of this function and make a spent output spendable again.
*/
- private def isTransactionOutputSpent(txid: ByteVector32, outputIndex: Int)(implicit ec: ExecutionContext): Future[Boolean] = {
+ private def isTransactionOutputSpent(txid: TxId, outputIndex: Int)(implicit ec: ExecutionContext): Future[Boolean] = {
getTxConfirmations(txid).flatMap {
case Some(confirmations) if confirmations > 0 =>
// There is an important limitation when using isTransactionOutputSpendable: if it returns false, it can mean a
@@ -170,9 +170,9 @@ class BitcoinCoreClient(val rpcClient: BitcoinJsonRPCClient, val onChainKeyManag
} yield doubleSpent
/** Search for mempool transaction spending a given output. */
- def lookForMempoolSpendingTx(txid: ByteVector32, outputIndex: Int)(implicit ec: ExecutionContext): Future[Transaction] = {
+ def lookForMempoolSpendingTx(txid: TxId, outputIndex: Int)(implicit ec: ExecutionContext): Future[Transaction] = {
rpcClient.invoke("gettxspendingprevout", Seq(OutpointArg(txid, outputIndex))).collect {
- case JArray(results) => results.flatMap(result => (result \ "spendingtxid").extractOpt[String].map(ByteVector32.fromValidHex))
+ case JArray(results) => results.flatMap(result => (result \ "spendingtxid").extractOpt[String].map(TxId.fromValidHex))
}.flatMap { spendingTxIds =>
spendingTxIds.headOption match {
case Some(spendingTxId) => getTransaction(spendingTxId)
@@ -186,31 +186,28 @@ class BitcoinCoreClient(val rpcClient: BitcoinJsonRPCClient, val onChainKeyManag
* It isn't useful to look at the whole blockchain history: if the transaction was confirmed long ago, an attacker
* will have already claimed all possible outputs and there's nothing we can do about it.
*
- * @param blockhash_opt hash of a block *after* the output has been spent. If not provided, we will use the blockchain tip.
+ * @param blockHash_opt hash of a block *after* the output has been spent. If not provided, we will use the blockchain tip.
* @param txid id of the transaction output that has been spent.
* @param outputIndex index of the transaction output that has been spent.
* @param limit maximum number of previous blocks to scan.
* @return the transaction spending the given output.
*/
- def lookForSpendingTx(blockhash_opt: Option[ByteVector32], txid: ByteVector32, outputIndex: Int, limit: Int)(implicit ec: ExecutionContext): Future[Transaction] = {
- lookForSpendingTx(blockhash_opt.map(KotlinUtils.scala2kmp), KotlinUtils.scala2kmp(txid), outputIndex, limit)
- }
-
- def lookForSpendingTx(blockhash_opt: Option[fr.acinq.bitcoin.ByteVector32], txid: fr.acinq.bitcoin.ByteVector32, outputIndex: Int, limit: Int)(implicit ec: ExecutionContext): Future[Transaction] =
+ def lookForSpendingTx(blockHash_opt: Option[BlockHash], txid: TxId, outputIndex: Int, limit: Int)(implicit ec: ExecutionContext): Future[Transaction] = {
for {
- blockhash <- blockhash_opt match {
- case Some(b) => Future.successful(b)
- case None => rpcClient.invoke("getbestblockhash").collect { case JString(b) => ByteVector32.fromValidHex(b) }
+ blockId <- blockHash_opt match {
+ case Some(blockHash) => Future.successful(BlockId(blockHash))
+ // NB: bitcoind confusingly returns the blockId instead of the blockHash.
+ case None => rpcClient.invoke("getbestblockhash").collect { case JString(blockId) => BlockId(ByteVector32.fromValidHex(blockId)) }
}
// with a verbosity of 0, getblock returns the raw serialized block
- block <- rpcClient.invoke("getblock", blockhash, 0).collect { case JString(b) => Block.read(b) }
- prevblockhash = block.header.hashPreviousBlock.reversed()
- res <- block.tx.asScala.find(tx => tx.txIn.asScala.exists(i => i.outPoint.txid == txid && i.outPoint.index == outputIndex)) match {
+ block <- rpcClient.invoke("getblock", blockId, 0).collect { case JString(b) => Block.read(b) }
+ res <- block.tx.asScala.find(tx => tx.txIn.asScala.exists(i => i.outPoint.txid == KotlinUtils.scala2kmp(txid) && i.outPoint.index == outputIndex)) match {
case Some(tx) => Future.successful(KotlinUtils.kmp2scala(tx))
- case None if limit > 0 => lookForSpendingTx(Some(prevblockhash), txid, outputIndex, limit - 1)
+ case None if limit > 0 => lookForSpendingTx(Some(KotlinUtils.kmp2scala(block.header.hashPreviousBlock)), txid, outputIndex, limit - 1)
case None => Future.failed(new RuntimeException(s"couldn't find tx spending $txid:$outputIndex in the blockchain"))
}
} yield res
+ }
def listTransactions(count: Int, skip: Int)(implicit ec: ExecutionContext): Future[List[WalletTx]] = rpcClient.invoke("listtransactions", "*", count, skip).map {
case JArray(txs) => txs.map(tx => {
@@ -222,14 +219,14 @@ class BitcoinCoreClient(val rpcClient: BitcoinJsonRPCClient, val onChainKeyManag
case _ => Satoshi(0)
}
val JInt(confirmations) = tx \ "confirmations"
- // while transactions are still in the mempool, block hash will no be included
- val blockHash = tx \ "blockhash" match {
- case JString(blockHash) => ByteVector32.fromValidHex(blockHash)
- case _ => ByteVector32.Zeroes
+ // while transactions are still in the mempool, blockId will not be included
+ val blockId_opt = tx \ "blockhash" match {
+ case JString(blockId) => Some(BlockId(ByteVector32.fromValidHex(blockId)))
+ case _ => None
}
val JString(txid) = tx \ "txid"
val JInt(timestamp) = tx \ "time"
- WalletTx(address, toSatoshi(amount), fee, blockHash, confirmations.toLong, ByteVector32.fromValidHex(txid), timestamp.toLong)
+ WalletTx(address, toSatoshi(amount), fee, blockId_opt, confirmations.toLong, TxId.fromValidHex(txid), timestamp.toLong)
}).reverse
case _ => Nil
}
@@ -409,9 +406,9 @@ class BitcoinCoreClient(val rpcClient: BitcoinJsonRPCClient, val onChainKeyManag
}
/** Recursively fetch unconfirmed parents and return the complete unconfirmed ancestors tree. */
- def getMempoolPackage(leaves: Set[ByteVector32])(implicit ec: ExecutionContext): Future[Map[ByteVector32, MempoolTx]] = getMempoolPackage(leaves, Map.empty)
+ def getMempoolPackage(leaves: Set[TxId])(implicit ec: ExecutionContext): Future[Map[TxId, MempoolTx]] = getMempoolPackage(leaves, Map.empty)
- private def getMempoolPackage(leaves: Set[ByteVector32], current: Map[ByteVector32, MempoolTx])(implicit ec: ExecutionContext): Future[Map[ByteVector32, MempoolTx]] = {
+ private def getMempoolPackage(leaves: Set[TxId], current: Map[TxId, MempoolTx])(implicit ec: ExecutionContext): Future[Map[TxId, MempoolTx]] = {
Future.sequence(leaves.map(txid => getMempoolTx(txid))).flatMap(txs => {
val current2 = current.concat(txs.map(tx => tx.txid -> tx))
val remainingParents = txs.flatMap(_.unconfirmedParents) -- current2.keySet
@@ -468,9 +465,9 @@ class BitcoinCoreClient(val rpcClient: BitcoinJsonRPCClient, val onChainKeyManag
*
* @return the transaction id (txid)
*/
- def publishTransaction(tx: Transaction)(implicit ec: ExecutionContext): Future[ByteVector32] =
+ def publishTransaction(tx: Transaction)(implicit ec: ExecutionContext): Future[TxId] =
rpcClient.invoke("sendrawtransaction", tx.toString()).collect {
- case JString(txid) => ByteVector32.fromValidHex(txid)
+ case JString(txid) => TxId.fromValidHex(txid)
}.recoverWith {
case JsonRPCError(Error(-27, _)) =>
// "transaction already in block chain (code: -27)"
@@ -485,7 +482,7 @@ class BitcoinCoreClient(val rpcClient: BitcoinJsonRPCClient, val onChainKeyManag
* This method can be used to replace "stuck" or evicted transactions.
* It only works on transactions which are not included in a block and are not currently in the mempool.
*/
- def abandonTransaction(txId: ByteVector32)(implicit ec: ExecutionContext): Future[Boolean] = {
+ def abandonTransaction(txId: TxId)(implicit ec: ExecutionContext): Future[Boolean] = {
rpcClient.invoke("abandontransaction", txId).map(_ => true).recover(_ => false)
}
@@ -495,7 +492,7 @@ class BitcoinCoreClient(val rpcClient: BitcoinJsonRPCClient, val onChainKeyManag
case JArray(locks) => locks.map(item => {
val JString(txid) = item \ "txid"
val JInt(vout) = item \ "vout"
- OutPoint(ByteVector32.fromValidHex(txid).reverse, vout.toInt)
+ OutPoint(TxId.fromValidHex(txid), vout.toInt)
}).toSet
}
}
@@ -544,9 +541,7 @@ class BitcoinCoreClient(val rpcClient: BitcoinJsonRPCClient, val onChainKeyManag
// and that the address and public key match
onChainKeyManager_opt match {
case Some(keyManager) =>
- // TODO: bitcoin-kmp doesn't accept 'h' for hardened indexes, we should fix this.
- val keyPath1 = keyPath.replace('h', '\'')
- val computed = keyManager.derivePublicKey(DeterministicWallet.KeyPath(keyPath1))
+ val computed = keyManager.derivePublicKey(DeterministicWallet.KeyPath(keyPath))
if (computed != (extracted, address)) return Future.failed(new RuntimeException("cannot recompute pubkey generated by bitcoin core"))
case None => ()
}
@@ -583,7 +578,7 @@ class BitcoinCoreClient(val rpcClient: BitcoinJsonRPCClient, val onChainKeyManag
* @param feeratePerKw fee rate
* @return the txid of the sending tx.
*/
- def sendToPubkeyScript(pubkeyScript: ByteVector, amount: Satoshi, feeratePerKw: FeeratePerKw)(implicit ec: ExecutionContext): Future[ByteVector32] = {
+ def sendToPubkeyScript(pubkeyScript: ByteVector, amount: Satoshi, feeratePerKw: FeeratePerKw)(implicit ec: ExecutionContext): Future[TxId] = {
import KotlinUtils._
val theirOutput = TxOut(amount, pubkeyScript)
@@ -603,10 +598,10 @@ class BitcoinCoreClient(val rpcClient: BitcoinJsonRPCClient, val onChainKeyManag
} yield txid
}
- def sendToPubkeyScript(pubkeyScript: Seq[ScriptElt], amount: Satoshi, feeratePerKw: FeeratePerKw)(implicit ec: ExecutionContext): Future[ByteVector32] = sendToPubkeyScript(Script.write(pubkeyScript), amount, feeratePerKw)
+ def sendToPubkeyScript(pubkeyScript: Seq[ScriptElt], amount: Satoshi, feeratePerKw: FeeratePerKw)(implicit ec: ExecutionContext): Future[TxId] = sendToPubkeyScript(Script.write(pubkeyScript), amount, feeratePerKw)
/** Calls Bitcoin Core's sendtoaddress RPC call directly. Will fail if wallet is using an external signer. */
- def sendToAddress(address: String, amount: Satoshi, confirmationTarget: Long)(implicit ec: ExecutionContext): Future[ByteVector32] = {
+ def sendToAddress(address: String, amount: Satoshi, confirmationTarget: Long)(implicit ec: ExecutionContext): Future[TxId] = {
rpcClient.invoke(
"sendtoaddress",
address,
@@ -616,7 +611,7 @@ class BitcoinCoreClient(val rpcClient: BitcoinJsonRPCClient, val onChainKeyManag
false, // subtractfeefromamount
true, // replaceable
confirmationTarget).collect {
- case JString(txid) => ByteVector32.fromValidHex(txid)
+ case JString(txid) => TxId.fromValidHex(txid)
}
}
@@ -624,12 +619,12 @@ class BitcoinCoreClient(val rpcClient: BitcoinJsonRPCClient, val onChainKeyManag
def getMempool()(implicit ec: ExecutionContext): Future[Seq[Transaction]] =
for {
- txids <- rpcClient.invoke("getrawmempool").map(json => json.extract[List[String]].map(ByteVector32.fromValidHex))
+ txids <- rpcClient.invoke("getrawmempool").map(json => json.extract[List[String]].map(TxId.fromValidHex))
// NB: if a transaction is evicted before we've called getTransaction, we need to ignore it instead of failing.
txs <- Future.sequence(txids.map(getTransaction(_).map(Some(_)).recover { case _ => None }))
} yield txs.flatten
- def getMempoolTx(txid: ByteVector32)(implicit ec: ExecutionContext): Future[MempoolTx] = {
+ def getMempoolTx(txid: TxId)(implicit ec: ExecutionContext): Future[MempoolTx] = {
rpcClient.invoke("getmempoolentry", txid).map(json => {
val JInt(vsize) = json \ "vsize"
val JInt(weight) = json \ "weight"
@@ -639,7 +634,7 @@ class BitcoinCoreClient(val rpcClient: BitcoinJsonRPCClient, val onChainKeyManag
val JDecimal(ancestorFees) = json \ "fees" \ "ancestor"
val JDecimal(descendantFees) = json \ "fees" \ "descendant"
val JBool(replaceable) = json \ "bip125-replaceable"
- val unconfirmedParents = (json \ "depends").extract[List[String]].map(ByteVector32.fromValidHex).toSet
+ val unconfirmedParents = (json \ "depends").extract[List[String]].map(TxId.fromValidHex).toSet
// NB: bitcoind counts the transaction itself as its own ancestor and descendant, which is confusing: we fix that by decrementing these counters.
MempoolTx(txid, vsize.toLong, weight.toLong, replaceable, toSatoshi(fees), ancestorCount.toInt - 1, toSatoshi(ancestorFees), descendantCount.toInt - 1, toSatoshi(descendantFees), unconfirmedParents)
})
@@ -662,11 +657,11 @@ class BitcoinCoreClient(val rpcClient: BitcoinJsonRPCClient, val onChainKeyManag
def validate(c: ChannelAnnouncement)(implicit ec: ExecutionContext): Future[ValidateResult] = {
val TxCoordinates(blockHeight, txIndex, outputIndex) = coordinates(c.shortChannelId)
for {
- blockHash <- rpcClient.invoke("getblockhash", blockHeight.toInt).map(_.extractOpt[String].map(ByteVector32.fromValidHex).getOrElse(ByteVector32.Zeroes))
- txid: ByteVector32 <- rpcClient.invoke("getblock", blockHash).map(json => Try {
+ blockId <- rpcClient.invoke("getblockhash", blockHeight.toInt).map(_.extractOpt[String].map(b => BlockId(ByteVector32.fromValidHex(b))).getOrElse(BlockId(ByteVector32.Zeroes)))
+ txid <- rpcClient.invoke("getblock", blockId).map(json => Try {
val JArray(txs) = json \ "tx"
- ByteVector32.fromValidHex(txs(txIndex).extract[String])
- }.getOrElse(ByteVector32.Zeroes))
+ TxId.fromValidHex(txs(txIndex).extract[String])
+ }.getOrElse(TxId(ByteVector32.Zeroes)))
tx <- getRawTransaction(txid)
unspent <- isTransactionOutputSpendable(txid, outputIndex, includeMempool = true)
fundingTxStatus <- if (unspent) {
@@ -690,7 +685,7 @@ class BitcoinCoreClient(val rpcClient: BitcoinJsonRPCClient, val onChainKeyManag
case JString(label) => Some(label)
case _ => None
}
- Utxo(ByteVector32.fromValidHex(txid), (amount.doubleValue * 1000).millibtc, confirmations.toLong, safe, label)
+ Utxo(TxId.fromValidHex(txid), (amount.doubleValue * 1000).millibtc, confirmations.toLong, safe, label)
})
}
@@ -705,7 +700,7 @@ object BitcoinCoreClient {
case class InputWeight(txid: String, vout: Long, weight: Long)
object InputWeight {
- def apply(outPoint: OutPoint, weight: Long): InputWeight = InputWeight(outPoint.txid.toHex, outPoint.index, weight)
+ def apply(outPoint: OutPoint, weight: Long): InputWeight = InputWeight(outPoint.txid.value.toHex, outPoint.index, weight)
}
case class FundTransactionOptions(feeRate: BigDecimal, replaceable: Boolean, lockUnspents: Boolean, changePosition: Option[Int], input_weights: Option[Seq[InputWeight]])
@@ -744,14 +739,14 @@ object BitcoinCoreClient {
* @param descendantFees transactions fees for the package consisting of this transaction and its unconfirmed children (without its unconfirmed parents).
* @param unconfirmedParents unconfirmed transactions used as inputs for this transaction.
*/
- case class MempoolTx(txid: ByteVector32, vsize: Long, weight: Long, replaceable: Boolean, fees: Satoshi, ancestorCount: Int, ancestorFees: Satoshi, descendantCount: Int, descendantFees: Satoshi, unconfirmedParents: Set[ByteVector32])
+ case class MempoolTx(txid: TxId, vsize: Long, weight: Long, replaceable: Boolean, fees: Satoshi, ancestorCount: Int, ancestorFees: Satoshi, descendantCount: Int, descendantFees: Satoshi, unconfirmedParents: Set[TxId])
- case class WalletTx(address: String, amount: Satoshi, fees: Satoshi, blockHash: ByteVector32, confirmations: Long, txid: ByteVector32, timestamp: Long)
+ case class WalletTx(address: String, amount: Satoshi, fees: Satoshi, blockId_opt: Option[BlockId], confirmations: Long, txid: TxId, timestamp: Long)
/** Outpoint used as RPC argument. */
- case class OutpointArg(txid: ByteVector32, vout: Long)
+ case class OutpointArg(txid: TxId, vout: Long)
- case class Utxo(txid: ByteVector32, amount: MilliBtc, confirmations: Long, safe: Boolean, label_opt: Option[String])
+ case class Utxo(txid: TxId, amount: MilliBtc, confirmations: Long, safe: Boolean, label_opt: Option[String])
def toSatoshi(btcAmount: BigDecimal): Satoshi = Satoshi(btcAmount.bigDecimal.scaleByPowerOfTen(8).longValue)
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/bitcoind/zmq/ZMQActor.scala b/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/bitcoind/zmq/ZMQActor.scala
index fe8384d6e9..22dc3cc35e 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/bitcoind/zmq/ZMQActor.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/bitcoind/zmq/ZMQActor.scala
@@ -18,7 +18,7 @@ package fr.acinq.eclair.blockchain.bitcoind.zmq
import akka.Done
import akka.actor.{Actor, ActorLogging}
-import fr.acinq.bitcoin.scalacompat.{ByteVector32, Transaction}
+import fr.acinq.bitcoin.scalacompat.{BlockId, ByteVector32, Transaction}
import fr.acinq.eclair.blockchain.{NewBlock, NewTransaction}
import org.zeromq.ZMQ.Event
import org.zeromq.{SocketType, ZContext, ZMQ, ZMsg}
@@ -92,9 +92,9 @@ class ZMQActor(address: String, topic: String, connected: Option[Promise[Done]]
case msg: ZMsg => msg.popString() match {
case "hashblock" =>
- val blockHash = ByteVector32(ByteVector(msg.pop().getData))
- log.debug("received blockhash={}", blockHash)
- context.system.eventStream.publish(NewBlock(blockHash))
+ val blockId = BlockId(ByteVector32(ByteVector(msg.pop().getData)))
+ log.debug("received blockId={}", blockId)
+ context.system.eventStream.publish(NewBlock(blockId))
case "rawtx" =>
val tx = Transaction.read(msg.pop().getData)
log.debug("received txid={}", tx.txid)
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/watchdogs/BlockchainWatchdog.scala b/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/watchdogs/BlockchainWatchdog.scala
index 2bf8728a85..3c6ea6510b 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/watchdogs/BlockchainWatchdog.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/watchdogs/BlockchainWatchdog.scala
@@ -104,10 +104,10 @@ object BlockchainWatchdog {
case CheckLatestHeaders(blockHeight) =>
val id = UUID.randomUUID()
if (headersOverDnsEnabled) {
- context.spawn(HeadersOverDns(nodeParams.chainHash, blockHeight), s"${HeadersOverDns.Source}-${blockHeight}-$id") ! HeadersOverDns.CheckLatestHeaders(context.self)
+ context.spawn(HeadersOverDns(nodeParams.chainHash, blockHeight), s"${HeadersOverDns.Source}-$blockHeight-$id") ! HeadersOverDns.CheckLatestHeaders(context.self)
}
explorers.foreach { explorer =>
- context.spawn(ExplorerApi(nodeParams.chainHash, blockHeight, explorer), s"${explorer.name}-${blockHeight}-$id") ! ExplorerApi.CheckLatestHeaders(context.self)
+ context.spawn(ExplorerApi(nodeParams.chainHash, blockHeight, explorer), s"${explorer.name}-$blockHeight-$id") ! ExplorerApi.CheckLatestHeaders(context.self)
}
Behaviors.same
case headers@LatestHeaders(blockHeight, blockHeaders, source) =>
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/watchdogs/ExplorerApi.scala b/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/watchdogs/ExplorerApi.scala
index 0e3d747721..e9971d620a 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/watchdogs/ExplorerApi.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/watchdogs/ExplorerApi.scala
@@ -21,7 +21,7 @@ import akka.actor.typed.scaladsl.{ActorContext, Behaviors}
import akka.actor.typed.{ActorRef, Behavior}
import akka.pattern.after
import fr.acinq.bitcoin.BlockHeader
-import fr.acinq.bitcoin.scalacompat.{Block, ByteVector32}
+import fr.acinq.bitcoin.scalacompat.{Block, BlockHash, BlockId, ByteVector32}
import fr.acinq.eclair.blockchain.watchdogs.BlockchainWatchdog.{BlockHeaderAt, LatestHeaders}
import fr.acinq.eclair.blockchain.watchdogs.Monitoring.{Metrics, Tags}
import fr.acinq.eclair.tor.Socks5ProxyParams
@@ -56,7 +56,7 @@ object ExplorerApi {
/** Explorer friendly-name. */
def name: String
/** Map from chainHash to explorer API URI. */
- def baseUris: Map[ByteVector32, Uri]
+ def baseUris: Map[BlockHash, Uri]
/** Fetch latest headers from the explorer. */
def getLatestHeaders(baseUri: Uri, currentBlockHeight: BlockHeight)(implicit context: ActorContext[Command]): Future[LatestHeaders]
// @formatter:on
@@ -69,7 +69,7 @@ object ExplorerApi {
private case class WrappedFailure(e: Throwable) extends Command
// @formatter:on
- def apply(chainHash: ByteVector32, currentBlockHeight: BlockHeight, explorer: Explorer): Behavior[Command] = {
+ def apply(chainHash: BlockHash, currentBlockHeight: BlockHeight, explorer: Explorer): Behavior[Command] = {
Behaviors.setup { context =>
Behaviors.receiveMessage {
case CheckLatestHeaders(replyTo) =>
@@ -164,9 +164,9 @@ object ExplorerApi {
val JString(time) = block \ "time"
val JInt(bits) = block \ "bits"
val JInt(nonce) = block \ "nonce"
- val previousBlockHash = (block \ "prev_block").extractOpt[String].map(ByteVector32.fromValidHex(_).reverse).getOrElse(ByteVector32.Zeroes)
+ val previousBlockId = (block \ "prev_block").extractOpt[String].map(h => BlockId(ByteVector32.fromValidHex(h))).getOrElse(BlockId(ByteVector32.Zeroes))
val merkleRoot = (block \ "mrkl_root").extractOpt[String].map(ByteVector32.fromValidHex(_).reverse).getOrElse(ByteVector32.Zeroes)
- val header = new BlockHeader(version.toLong, previousBlockHash, merkleRoot, OffsetDateTime.parse(time).toEpochSecond, bits.toLong, nonce.toLong)
+ val header = new BlockHeader(version.toLong, BlockHash(previousBlockId), merkleRoot, OffsetDateTime.parse(time).toEpochSecond, bits.toLong, nonce.toLong)
Seq(BlockHeaderAt(BlockHeight(height.toLong), header))
})
} yield header
@@ -193,9 +193,9 @@ object ExplorerApi {
val JInt(time) = block \ "timestamp"
val JInt(bits) = block \ "bits"
val JInt(nonce) = block \ "nonce"
- val previousBlockHash = (block \ "previousblockhash").extractOpt[String].map(ByteVector32.fromValidHex(_).reverse).getOrElse(ByteVector32.Zeroes)
+ val previousBlockId = (block \ "previousblockhash").extractOpt[String].map(h => BlockId(ByteVector32.fromValidHex(h))).getOrElse(BlockId(ByteVector32.Zeroes))
val merkleRoot = (block \ "merkle_root").extractOpt[String].map(ByteVector32.fromValidHex(_).reverse).getOrElse(ByteVector32.Zeroes)
- val header = new BlockHeader(version.toLong, previousBlockHash, merkleRoot, time.toLong, bits.toLong, nonce.toLong)
+ val header = new BlockHeader(version.toLong, BlockHash(previousBlockId), merkleRoot, time.toLong, bits.toLong, nonce.toLong)
BlockHeaderAt(BlockHeight(height.toLong), header)
}))
.map(headers => LatestHeaders(currentBlockHeight, headers.filter(_.blockHeight >= currentBlockHeight).toSet, name))
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/watchdogs/HeadersOverDns.scala b/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/watchdogs/HeadersOverDns.scala
index d65ab84670..dcfae33a19 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/watchdogs/HeadersOverDns.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/watchdogs/HeadersOverDns.scala
@@ -22,8 +22,8 @@ import akka.actor.typed.scaladsl.adapter.TypedActorRefOps
import akka.actor.typed.{ActorRef, Behavior}
import akka.io.dns.{AAAARecord, DnsProtocol}
import akka.io.{Dns, IO}
-import fr.acinq.bitcoin.scalacompat.{Block, ByteVector32}
import fr.acinq.bitcoin.BlockHeader
+import fr.acinq.bitcoin.scalacompat.{Block, BlockHash}
import fr.acinq.eclair.BlockHeight
import fr.acinq.eclair.blockchain.watchdogs.BlockchainWatchdog.BlockHeaderAt
import fr.acinq.eclair.blockchain.watchdogs.Monitoring.{Metrics, Tags}
@@ -46,7 +46,7 @@ object HeadersOverDns {
private case class WrappedDnsFailed(cause: Throwable) extends Command
// @formatter:on
- def apply(chainHash: ByteVector32, currentBlockHeight: BlockHeight): Behavior[Command] = {
+ def apply(chainHash: BlockHash, currentBlockHeight: BlockHeight): Behavior[Command] = {
Behaviors.setup { context =>
val dnsAdapters = {
context.messageAdapter[DnsProtocol.Resolved](WrappedDnsResolved)
@@ -87,7 +87,7 @@ object HeadersOverDns {
stopOrCollect(replyTo, currentBlockHeight, received1, remaining - 1)
case WrappedDnsFailed(ex) =>
- context.log.warn("bitcoinheaders.net failed to resolve: {}", ex)
+ context.log.warn(s"bitcoinheaders.net failed to resolve: $ex")
stopOrCollect(replyTo, currentBlockHeight, received, remaining - 1)
case _ => Behaviors.unhandled
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/channel/ChannelData.scala b/eclair-core/src/main/scala/fr/acinq/eclair/channel/ChannelData.scala
index 9b946c5092..18163fce05 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/channel/ChannelData.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/channel/ChannelData.scala
@@ -18,7 +18,7 @@ package fr.acinq.eclair.channel
import akka.actor.{ActorRef, PossiblyHarmful, typed}
import fr.acinq.bitcoin.scalacompat.Crypto.PublicKey
-import fr.acinq.bitcoin.scalacompat.{ByteVector32, DeterministicWallet, OutPoint, Satoshi, SatoshiLong, Transaction, TxOut}
+import fr.acinq.bitcoin.scalacompat.{ByteVector32, DeterministicWallet, OutPoint, Satoshi, SatoshiLong, Transaction, TxId, TxOut}
import fr.acinq.eclair.blockchain.fee.{ConfirmationTarget, FeeratePerKw}
import fr.acinq.eclair.channel.LocalFundingStatus.DualFundedUnconfirmedFundingTx
import fr.acinq.eclair.channel.fund.InteractiveTxBuilder._
@@ -263,8 +263,8 @@ object HtlcResult {
final case class RES_ADD_SETTLED[+O <: Origin, +R <: HtlcResult](origin: O, htlc: UpdateAddHtlc, result: R) extends CommandSuccess[CMD_ADD_HTLC]
/** other specific responses */
-final case class RES_BUMP_FUNDING_FEE(rbfIndex: Int, fundingTxId: ByteVector32, fee: Satoshi) extends CommandSuccess[CMD_BUMP_FUNDING_FEE]
-final case class RES_SPLICE(fundingTxIndex: Long, fundingTxId: ByteVector32, capacity: Satoshi, balance: MilliSatoshi) extends CommandSuccess[CMD_SPLICE]
+final case class RES_BUMP_FUNDING_FEE(rbfIndex: Int, fundingTxId: TxId, fee: Satoshi) extends CommandSuccess[CMD_BUMP_FUNDING_FEE]
+final case class RES_SPLICE(fundingTxIndex: Long, fundingTxId: TxId, capacity: Satoshi, balance: MilliSatoshi) extends CommandSuccess[CMD_SPLICE]
final case class RES_GET_CHANNEL_STATE(state: ChannelState) extends CommandSuccess[CMD_GET_CHANNEL_STATE]
final case class RES_GET_CHANNEL_DATA[+D <: ChannelData](data: D) extends CommandSuccess[CMD_GET_CHANNEL_DATA]
final case class RES_GET_CHANNEL_INFO(nodeId: PublicKey, channelId: ByteVector32, channel: ActorRef, state: ChannelState, data: ChannelData) extends CommandSuccess[CMD_GET_CHANNEL_INFO]
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 54407e9863..cea5739003 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
@@ -16,7 +16,7 @@
package fr.acinq.eclair.channel
-import fr.acinq.bitcoin.scalacompat.{ByteVector32, Satoshi, Transaction}
+import fr.acinq.bitcoin.scalacompat.{BlockHash, ByteVector32, Satoshi, Transaction, TxId}
import fr.acinq.eclair.blockchain.fee.FeeratePerKw
import fr.acinq.eclair.wire.protocol
import fr.acinq.eclair.wire.protocol.{AnnouncementSignatures, InteractiveTxMessage, UpdateAddHtlc}
@@ -36,7 +36,7 @@ case class RemoteError(e: protocol.Error) extends ChannelError
class ChannelException(val channelId: ByteVector32, message: String) extends RuntimeException(message)
// @formatter:off
-case class InvalidChainHash (override val channelId: ByteVector32, local: ByteVector32, remote: ByteVector32) extends ChannelException(channelId, s"invalid chainHash (local=$local remote=$remote)")
+case class InvalidChainHash (override val channelId: ByteVector32, local: BlockHash, remote: BlockHash) extends ChannelException(channelId, s"invalid chainHash (local=$local remote=$remote)")
case class FundingAmountTooLow (override val channelId: ByteVector32, fundingAmount: Satoshi, min: Satoshi) extends ChannelException(channelId, s"invalid funding_amount=$fundingAmount (min=$min)")
case class FundingAmountTooHigh (override val channelId: ByteVector32, fundingAmount: Satoshi, max: Satoshi) extends ChannelException(channelId, s"invalid funding_amount=$fundingAmount (max=$max)")
case class InvalidFundingBalances (override val channelId: ByteVector32, fundingAmount: Satoshi, localBalance: MilliSatoshi, remoteBalance: MilliSatoshi) extends ChannelException(channelId, s"invalid balances funding_amount=$fundingAmount local=$localBalance remote=$remoteBalance")
@@ -56,10 +56,10 @@ case class InvalidFundingTx (override val channelId: Byte
case class InvalidSerialId (override val channelId: ByteVector32, serialId: UInt64) extends ChannelException(channelId, s"invalid serial_id=${serialId.toByteVector.toHex}")
case class DuplicateSerialId (override val channelId: ByteVector32, serialId: UInt64) extends ChannelException(channelId, s"duplicate serial_id=${serialId.toByteVector.toHex}")
case class UnknownSerialId (override val channelId: ByteVector32, serialId: UInt64) extends ChannelException(channelId, s"unknown serial_id=${serialId.toByteVector.toHex}")
-case class DuplicateInput (override val channelId: ByteVector32, serialId: UInt64, previousTxId: ByteVector32, previousTxOutput: Long) extends ChannelException(channelId, s"duplicate input $previousTxId:$previousTxOutput (serial_id=${serialId.toByteVector.toHex})")
-case class InputOutOfBounds (override val channelId: ByteVector32, serialId: UInt64, previousTxId: ByteVector32, previousTxOutput: Long) extends ChannelException(channelId, s"invalid input $previousTxId:$previousTxOutput (serial_id=${serialId.toByteVector.toHex})")
-case class NonReplaceableInput (override val channelId: ByteVector32, serialId: UInt64, previousTxId: ByteVector32, previousTxOutput: Long, sequence: Long) extends ChannelException(channelId, s"$previousTxId:$previousTxOutput is not replaceable (serial_id=${serialId.toByteVector.toHex}, nSequence=$sequence)")
-case class NonSegwitInput (override val channelId: ByteVector32, serialId: UInt64, previousTxId: ByteVector32, previousTxOutput: Long) extends ChannelException(channelId, s"$previousTxId:$previousTxOutput is not a native segwit input (serial_id=${serialId.toByteVector.toHex})")
+case class DuplicateInput (override val channelId: ByteVector32, serialId: UInt64, previousTxId: TxId, previousTxOutput: Long) extends ChannelException(channelId, s"duplicate input $previousTxId:$previousTxOutput (serial_id=${serialId.toByteVector.toHex})")
+case class InputOutOfBounds (override val channelId: ByteVector32, serialId: UInt64, previousTxId: TxId, previousTxOutput: Long) extends ChannelException(channelId, s"invalid input $previousTxId:$previousTxOutput (serial_id=${serialId.toByteVector.toHex})")
+case class NonReplaceableInput (override val channelId: ByteVector32, serialId: UInt64, previousTxId: TxId, previousTxOutput: Long, sequence: Long) extends ChannelException(channelId, s"$previousTxId:$previousTxOutput is not replaceable (serial_id=${serialId.toByteVector.toHex}, nSequence=$sequence)")
+case class NonSegwitInput (override val channelId: ByteVector32, serialId: UInt64, previousTxId: TxId, previousTxOutput: Long) extends ChannelException(channelId, s"$previousTxId:$previousTxOutput is not a native segwit input (serial_id=${serialId.toByteVector.toHex})")
case class PreviousTxMissing (override val channelId: ByteVector32, serialId: UInt64) extends ChannelException(channelId, s"previous tx missing from tx_add_input (serial_id=${serialId.toByteVector.toHex})")
case class InvalidSharedInput (override val channelId: ByteVector32, serialId: UInt64) extends ChannelException(channelId, s"invalid shared tx_add_input (serial_id=${serialId.toByteVector.toHex})")
case class OutputBelowDust (override val channelId: ByteVector32, serialId: UInt64, amount: Satoshi, dustLimit: Satoshi) extends ChannelException(channelId, s"invalid output amount=$amount below dust=$dustLimit (serial_id=${serialId.toByteVector.toHex})")
@@ -75,7 +75,7 @@ case class DualFundingAborted (override val channelId: Byte
case class UnexpectedInteractiveTxMessage (override val channelId: ByteVector32, msg: InteractiveTxMessage) extends ChannelException(channelId, s"unexpected interactive-tx message (${msg.getClass.getSimpleName})")
case class UnexpectedFundingSignatures (override val channelId: ByteVector32) extends ChannelException(channelId, "unexpected funding signatures (tx_signatures)")
case class InvalidFundingFeerate (override val channelId: ByteVector32, targetFeerate: FeeratePerKw, actualFeerate: FeeratePerKw) extends ChannelException(channelId, s"invalid funding feerate: target=$targetFeerate actual=$actualFeerate")
-case class InvalidFundingSignature (override val channelId: ByteVector32, txId_opt: Option[ByteVector32]) extends ChannelException(channelId, s"invalid funding signature: txId=${txId_opt.map(_.toHex).getOrElse("n/a")}")
+case class InvalidFundingSignature (override val channelId: ByteVector32, txId_opt: Option[TxId]) extends ChannelException(channelId, s"invalid funding signature: txId=${txId_opt.map(_.toString()).getOrElse("n/a")}")
case class InvalidRbfFeerate (override val channelId: ByteVector32, proposed: FeeratePerKw, expected: FeeratePerKw) extends ChannelException(channelId, s"invalid rbf attempt: the feerate must be at least $expected, you proposed $proposed")
case class InvalidSpliceRequest (override val channelId: ByteVector32) extends ChannelException(channelId, "invalid splice request")
case class InvalidRbfAlreadyInProgress (override val channelId: ByteVector32) extends ChannelException(channelId, "invalid rbf attempt: the current rbf attempt must be completed or aborted first")
@@ -98,17 +98,17 @@ case class InvalidFinalScript (override val channelId: Byte
case class MissingUpfrontShutdownScript (override val channelId: ByteVector32) extends ChannelException(channelId, "missing upfront shutdown script")
case class FundingTxTimedout (override val channelId: ByteVector32) extends ChannelException(channelId, "funding tx timed out")
case class FundingTxDoubleSpent (override val channelId: ByteVector32) extends ChannelException(channelId, "funding tx double spent")
-case class FundingTxSpent (override val channelId: ByteVector32, spendingTxId: ByteVector32) extends ChannelException(channelId, s"funding tx has been spent by txId=$spendingTxId")
+case class FundingTxSpent (override val channelId: ByteVector32, spendingTxId: TxId) extends ChannelException(channelId, s"funding tx has been spent by txId=$spendingTxId")
case class HtlcsTimedoutDownstream (override val channelId: ByteVector32, htlcs: Set[UpdateAddHtlc]) extends ChannelException(channelId, s"one or more htlcs timed out downstream: ids=${htlcs.take(10).map(_.id).mkString(",")}") // we only display the first 10 ids
case class HtlcsWillTimeoutUpstream (override val channelId: ByteVector32, htlcs: Set[UpdateAddHtlc]) extends ChannelException(channelId, s"one or more htlcs that should be fulfilled are close to timing out upstream: ids=${htlcs.take(10).map(_.id).mkString}") // we only display the first 10 ids
case class HtlcOverriddenByLocalCommit (override val channelId: ByteVector32, htlc: UpdateAddHtlc) extends ChannelException(channelId, s"htlc ${htlc.id} was overridden by local commit")
case class FeerateTooSmall (override val channelId: ByteVector32, remoteFeeratePerKw: FeeratePerKw) extends ChannelException(channelId, s"remote fee rate is too small: remoteFeeratePerKw=${remoteFeeratePerKw.toLong}")
case class FeerateTooDifferent (override val channelId: ByteVector32, localFeeratePerKw: FeeratePerKw, remoteFeeratePerKw: FeeratePerKw) extends ChannelException(channelId, s"local/remote feerates are too different: remoteFeeratePerKw=${remoteFeeratePerKw.toLong} localFeeratePerKw=${localFeeratePerKw.toLong}")
case class InvalidAnnouncementSignatures (override val channelId: ByteVector32, annSigs: AnnouncementSignatures) extends ChannelException(channelId, s"invalid announcement signatures: $annSigs")
-case class InvalidCommitmentSignature (override val channelId: ByteVector32, fundingTxId: ByteVector32, fundingTxIndex: Long, unsignedCommitTx: Transaction) extends ChannelException(channelId, s"invalid commitment signature: fundingTxId=$fundingTxId fundingTxIndex=$fundingTxIndex commitTxId=${unsignedCommitTx.txid} commitTx=$unsignedCommitTx")
-case class InvalidHtlcSignature (override val channelId: ByteVector32, txId: ByteVector32) extends ChannelException(channelId, s"invalid htlc signature: txId=$txId")
-case class InvalidCloseSignature (override val channelId: ByteVector32, txId: ByteVector32) extends ChannelException(channelId, s"invalid close signature: txId=$txId")
-case class InvalidCloseAmountBelowDust (override val channelId: ByteVector32, txId: ByteVector32) extends ChannelException(channelId, s"invalid closing tx: some outputs are below dust: txId=$txId")
+case class InvalidCommitmentSignature (override val channelId: ByteVector32, fundingTxId: TxId, fundingTxIndex: Long, unsignedCommitTx: Transaction) extends ChannelException(channelId, s"invalid commitment signature: fundingTxId=$fundingTxId fundingTxIndex=$fundingTxIndex commitTxId=${unsignedCommitTx.txid} commitTx=$unsignedCommitTx")
+case class InvalidHtlcSignature (override val channelId: ByteVector32, txId: TxId) extends ChannelException(channelId, s"invalid htlc signature: txId=$txId")
+case class InvalidCloseSignature (override val channelId: ByteVector32, txId: TxId) extends ChannelException(channelId, s"invalid close signature: txId=$txId")
+case class InvalidCloseAmountBelowDust (override val channelId: ByteVector32, txId: TxId) extends ChannelException(channelId, s"invalid closing tx: some outputs are below dust: txId=$txId")
case class CommitSigCountMismatch (override val channelId: ByteVector32, expected: Int, actual: Int) extends ChannelException(channelId, s"commit sig count mismatch: expected=$expected actual=$actual")
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")
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 78ae2d6625..6df8ed5fda 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
@@ -3,7 +3,7 @@ package fr.acinq.eclair.channel
import akka.event.LoggingAdapter
import com.softwaremill.quicklens.ModifyPimp
import fr.acinq.bitcoin.scalacompat.Crypto.{PrivateKey, PublicKey}
-import fr.acinq.bitcoin.scalacompat.{ByteVector32, ByteVector64, Crypto, Satoshi, SatoshiLong, Script, Transaction}
+import fr.acinq.bitcoin.scalacompat.{ByteVector32, ByteVector64, Crypto, Satoshi, SatoshiLong, Script, Transaction, TxId}
import fr.acinq.eclair.blockchain.fee.{FeeratePerByte, FeeratePerKw, FeeratesPerKw, OnChainFeeConf}
import fr.acinq.eclair.channel.Helpers.Closing
import fr.acinq.eclair.channel.Monitoring.{Metrics, Tags}
@@ -225,7 +225,7 @@ case class CommitTxAndRemoteSig(commitTx: CommitTx, remoteSig: ByteVector64)
case class LocalCommit(index: Long, spec: CommitmentSpec, commitTxAndRemoteSig: CommitTxAndRemoteSig, htlcTxsAndRemoteSigs: List[HtlcTxAndRemoteSig])
object LocalCommit {
- def fromCommitSig(keyManager: ChannelKeyManager, params: ChannelParams, fundingTxId: ByteVector32,
+ def fromCommitSig(keyManager: ChannelKeyManager, params: ChannelParams, fundingTxId: TxId,
fundingTxIndex: Long, remoteFundingPubKey: PublicKey, commitInput: InputInfo,
commit: CommitSig, localCommitIndex: Long, spec: CommitmentSpec, localPerCommitmentPoint: PublicKey): Either[ChannelException, LocalCommit] = {
val (localCommitTx, htlcTxs) = Commitment.makeLocalTxs(keyManager, params.channelConfig, params.channelFeatures, localCommitIndex, params.localParams, params.remoteParams, fundingTxIndex, remoteFundingPubKey, commitInput, localPerCommitmentPoint, spec)
@@ -249,7 +249,7 @@ object LocalCommit {
}
/** The remote commitment maps to a commitment transaction that only our peer can sign and broadcast. */
-case class RemoteCommit(index: Long, spec: CommitmentSpec, txid: ByteVector32, remotePerCommitmentPoint: PublicKey) {
+case class RemoteCommit(index: Long, spec: CommitmentSpec, txid: TxId, remotePerCommitmentPoint: PublicKey) {
def sign(keyManager: ChannelKeyManager, params: ChannelParams, fundingTxIndex: Long, remoteFundingPubKey: PublicKey, commitInput: InputInfo): CommitSig = {
val (remoteCommitTx, htlcTxs) = Commitment.makeRemoteTxs(keyManager, params.channelConfig, params.channelFeatures, index, params.localParams, params.remoteParams, fundingTxIndex, remoteFundingPubKey, commitInput, remotePerCommitmentPoint, spec)
val sig = keyManager.sign(remoteCommitTx, keyManager.fundingPublicKey(params.localParams.fundingKeyPath, fundingTxIndex), TxOwner.Remote, params.commitmentFormat)
@@ -276,7 +276,7 @@ case class Commitment(fundingTxIndex: Long,
localFundingStatus: LocalFundingStatus, remoteFundingStatus: RemoteFundingStatus,
localCommit: LocalCommit, remoteCommit: RemoteCommit, nextRemoteCommit_opt: Option[NextRemoteCommit]) {
val commitInput: InputInfo = localCommit.commitTxAndRemoteSig.commitTx.input
- val fundingTxId: ByteVector32 = commitInput.outPoint.txid
+ val fundingTxId: TxId = commitInput.outPoint.txid
val capacity: Satoshi = commitInput.txOut.amount
/** Channel reserve that applies to our funds. */
@@ -1148,7 +1148,7 @@ case class Commitments(params: ChannelParams,
params.channelFeatures.hasFeature(Features.DualFunding) && commitSig.batchSize == 1 && latestRemoteSig == commitSig.signature
}
- def localFundingSigs(fundingTxId: ByteVector32): Option[TxSignatures] = {
+ def localFundingSigs(fundingTxId: TxId): Option[TxSignatures] = {
all.find(_.fundingTxId == fundingTxId).flatMap(_.localFundingStatus.localSigs_opt)
}
@@ -1158,7 +1158,7 @@ case class Commitments(params: ChannelParams,
* @param updateMethod This method is tricky: it passes the fundingTxIndex of the commitment corresponding to the
* fundingTxId, because in the remote case we may update several commitments.
*/
- private def updateFundingStatus(fundingTxId: ByteVector32, updateMethod: Long => PartialFunction[Commitment, Commitment])(implicit log: LoggingAdapter): Either[Commitments, (Commitments, Commitment)] = {
+ private def updateFundingStatus(fundingTxId: TxId, updateMethod: Long => PartialFunction[Commitment, Commitment])(implicit log: LoggingAdapter): Either[Commitments, (Commitments, Commitment)] = {
all.find(_.fundingTxId == fundingTxId) match {
case Some(commitment) =>
val commitments1 = copy(
@@ -1174,7 +1174,7 @@ case class Commitments(params: ChannelParams,
}
}
- def updateLocalFundingStatus(fundingTxId: ByteVector32, status: LocalFundingStatus)(implicit log: LoggingAdapter): Either[Commitments, (Commitments, Commitment)] =
+ def updateLocalFundingStatus(fundingTxId: TxId, status: LocalFundingStatus)(implicit log: LoggingAdapter): Either[Commitments, (Commitments, Commitment)] =
updateFundingStatus(fundingTxId, _ => {
case c if c.fundingTxId == fundingTxId =>
log.info(s"setting localFundingStatus=${status.getClass.getSimpleName} for fundingTxId=${c.fundingTxId} fundingTxIndex=${c.fundingTxIndex}")
@@ -1182,7 +1182,7 @@ case class Commitments(params: ChannelParams,
case c => c
})
- def updateRemoteFundingStatus(fundingTxId: ByteVector32)(implicit log: LoggingAdapter): Either[Commitments, (Commitments, Commitment)] =
+ def updateRemoteFundingStatus(fundingTxId: TxId)(implicit log: LoggingAdapter): Either[Commitments, (Commitments, Commitment)] =
updateFundingStatus(fundingTxId, fundingTxIndex => {
// all funding older than this one are considered locked
case c if c.fundingTxId == fundingTxId || c.fundingTxIndex < fundingTxIndex =>
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 348be40c6e..52567887f8 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
@@ -352,7 +352,7 @@ object Helpers {
object Funding {
- def makeFundingInputInfo(fundingTxId: ByteVector32, fundingTxOutputIndex: Int, fundingSatoshis: Satoshi, fundingPubkey1: PublicKey, fundingPubkey2: PublicKey): InputInfo = {
+ def makeFundingInputInfo(fundingTxId: TxId, fundingTxOutputIndex: Int, fundingSatoshis: Satoshi, fundingPubkey1: PublicKey, fundingPubkey2: PublicKey): InputInfo = {
val fundingScript = multiSig2of2(fundingPubkey1, fundingPubkey2)
val fundingTxOut = TxOut(fundingSatoshis, pay2wsh(fundingScript))
InputInfo(OutPoint(fundingTxId, fundingTxOutputIndex), fundingTxOut, write(fundingScript))
@@ -368,7 +368,7 @@ object Helpers {
localFundingAmount: Satoshi, remoteFundingAmount: Satoshi,
localPushAmount: MilliSatoshi, remotePushAmount: MilliSatoshi,
commitTxFeerate: FeeratePerKw,
- fundingTxHash: ByteVector32, fundingTxOutputIndex: Int,
+ fundingTxId: TxId, fundingTxOutputIndex: Int,
remoteFundingPubKey: PublicKey,
remoteFirstPerCommitmentPoint: PublicKey): Either[ChannelException, (CommitmentSpec, CommitTx, CommitmentSpec, CommitTx)] = {
makeCommitTxs(keyManager, params,
@@ -378,7 +378,7 @@ object Helpers {
localHtlcs = Set.empty,
commitTxFeerate,
fundingTxIndex = 0,
- fundingTxHash, fundingTxOutputIndex,
+ fundingTxId, fundingTxOutputIndex,
remoteFundingPubKey = remoteFundingPubKey, remotePerCommitmentPoint = remoteFirstPerCommitmentPoint,
localCommitmentIndex = 0, remoteCommitmentIndex = 0).map {
case (localSpec, localCommit, remoteSpec, remoteCommit, _) => (localSpec, localCommit, remoteSpec, remoteCommit)
@@ -396,7 +396,7 @@ object Helpers {
localHtlcs: Set[DirectedHtlc],
commitTxFeerate: FeeratePerKw,
fundingTxIndex: Long,
- fundingTxHash: ByteVector32, fundingTxOutputIndex: Int,
+ fundingTxId: TxId, fundingTxOutputIndex: Int,
remoteFundingPubKey: PublicKey,
remotePerCommitmentPoint: PublicKey,
localCommitmentIndex: Long, remoteCommitmentIndex: Long): Either[ChannelException, (CommitmentSpec, CommitTx, CommitmentSpec, CommitTx, Seq[HtlcTx])] = {
@@ -418,7 +418,7 @@ object Helpers {
val fundingPubKey = keyManager.fundingPublicKey(localParams.fundingKeyPath, fundingTxIndex)
val channelKeyPath = keyManager.keyPath(localParams, channelConfig)
- val commitmentInput = makeFundingInputInfo(fundingTxHash, fundingTxOutputIndex, fundingAmount, fundingPubKey.publicKey, remoteFundingPubKey)
+ val commitmentInput = makeFundingInputInfo(fundingTxId, fundingTxOutputIndex, fundingAmount, fundingPubKey.publicKey, remoteFundingPubKey)
val localPerCommitmentPoint = keyManager.commitmentPoint(channelKeyPath, localCommitmentIndex)
val (localCommitTx, _) = Commitment.makeLocalTxs(keyManager, channelConfig, channelFeatures, localCommitmentIndex, localParams, remoteParams, fundingTxIndex, remoteFundingPubKey, commitmentInput, localPerCommitmentPoint, localSpec)
val (remoteCommitTx, htlcTxs) = Commitment.makeRemoteTxs(keyManager, channelConfig, channelFeatures, remoteCommitmentIndex, localParams, remoteParams, fundingTxIndex, remoteFundingPubKey, commitmentInput, remotePerCommitmentPoint, remoteSpec)
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/Channel.scala b/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/Channel.scala
index 44cb81c11b..1dfcfa3a1a 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/Channel.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/Channel.scala
@@ -21,7 +21,7 @@ import akka.actor.typed.scaladsl.adapter.{ClassicActorContextOps, actorRefAdapte
import akka.actor.{Actor, ActorContext, ActorRef, FSM, OneForOneStrategy, PossiblyHarmful, Props, SupervisorStrategy, typed}
import akka.event.Logging.MDC
import fr.acinq.bitcoin.scalacompat.Crypto.{PrivateKey, PublicKey}
-import fr.acinq.bitcoin.scalacompat.{ByteVector32, Satoshi, SatoshiLong, Transaction}
+import fr.acinq.bitcoin.scalacompat.{ByteVector32, Satoshi, SatoshiLong, Transaction, TxId}
import fr.acinq.eclair.Logs.LogCategory
import fr.acinq.eclair._
import fr.acinq.eclair.blockchain.OnChainWallet.MakeFundingTxResponse
@@ -161,7 +161,7 @@ object Channel {
private[channel] sealed trait BitcoinEvent extends PossiblyHarmful
private[channel] case object BITCOIN_FUNDING_PUBLISH_FAILED extends BitcoinEvent
private[channel] case object BITCOIN_FUNDING_TIMEOUT extends BitcoinEvent
- private[channel] case class BITCOIN_FUNDING_DOUBLE_SPENT(fundingTxIds: Set[ByteVector32]) extends BitcoinEvent
+ private[channel] case class BITCOIN_FUNDING_DOUBLE_SPENT(fundingTxIds: Set[TxId]) extends BitcoinEvent
// @formatter:on
case object TickChannelOpenTimeout
@@ -1135,7 +1135,7 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
watchFundingConfirmed(w.tx.txid, Some(nodeParams.channelConf.minDepthBlocks), delay_opt = None)
maybeEmitEventsPostSplice(d.shortIds, d.commitments, commitments1)
maybeUpdateMaxHtlcAmount(d.channelUpdate.htlcMaximumMsat, commitments1)
- stay() using d.copy(commitments = commitments1) storing() sending SpliceLocked(d.channelId, w.tx.hash)
+ stay() using d.copy(commitments = commitments1) storing() sending SpliceLocked(d.channelId, w.tx.txid)
case Left(_) => stay()
}
@@ -1144,7 +1144,7 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
case Right((commitments1, commitment)) =>
val toSend = if (d.commitments.all.exists(c => c.fundingTxId == commitment.fundingTxId && c.localFundingStatus.isInstanceOf[LocalFundingStatus.NotLocked])) {
// this commitment just moved from NotLocked to Locked
- Some(SpliceLocked(d.channelId, w.tx.hash))
+ Some(SpliceLocked(d.channelId, w.tx.txid))
} else {
// this was a zero-conf splice and we already sent our splice_locked
None
@@ -1156,7 +1156,7 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
}
case Event(msg: SpliceLocked, d: DATA_NORMAL) =>
- d.commitments.updateRemoteFundingStatus(msg.fundingTxid) match {
+ d.commitments.updateRemoteFundingStatus(msg.fundingTxId) match {
case Right((commitments1, _)) =>
maybeEmitEventsPostSplice(d.shortIds, d.commitments, commitments1)
maybeUpdateMaxHtlcAmount(d.channelUpdate.htlcMaximumMsat, commitments1)
@@ -1808,7 +1808,7 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
activeConnection = r
val channelKeyPath = keyManager.keyPath(d.channelParams.localParams, d.channelParams.channelConfig)
val myFirstPerCommitmentPoint = keyManager.commitmentPoint(channelKeyPath, 0)
- val nextFundingTlv: Set[ChannelReestablishTlv] = Set(ChannelReestablishTlv.NextFundingTlv(d.signingSession.fundingTx.txId.reverse))
+ val nextFundingTlv: Set[ChannelReestablishTlv] = Set(ChannelReestablishTlv.NextFundingTlv(d.signingSession.fundingTx.txId))
val channelReestablish = ChannelReestablish(
channelId = d.channelId,
nextLocalCommitmentNumber = 1,
@@ -1828,16 +1828,16 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
val myCurrentPerCommitmentPoint = keyManager.commitmentPoint(channelKeyPath, d.commitments.localCommitIndex)
val rbfTlv: Set[ChannelReestablishTlv] = d match {
case d: DATA_WAIT_FOR_DUAL_FUNDING_CONFIRMED => d.rbfStatus match {
- case RbfStatus.RbfWaitingForSigs(status) => Set(ChannelReestablishTlv.NextFundingTlv(status.fundingTx.txId.reverse))
+ case RbfStatus.RbfWaitingForSigs(status) => Set(ChannelReestablishTlv.NextFundingTlv(status.fundingTx.txId))
case _ => d.latestFundingTx.sharedTx match {
- case _: InteractiveTxBuilder.PartiallySignedSharedTransaction => Set(ChannelReestablishTlv.NextFundingTlv(d.latestFundingTx.sharedTx.txId.reverse))
+ case _: InteractiveTxBuilder.PartiallySignedSharedTransaction => Set(ChannelReestablishTlv.NextFundingTlv(d.latestFundingTx.sharedTx.txId))
case _: InteractiveTxBuilder.FullySignedSharedTransaction => Set.empty
}
}
case d: DATA_NORMAL => d.spliceStatus match {
- case SpliceStatus.SpliceWaitingForSigs(status) => Set(ChannelReestablishTlv.NextFundingTlv(status.fundingTx.txId.reverse))
+ case SpliceStatus.SpliceWaitingForSigs(status) => Set(ChannelReestablishTlv.NextFundingTlv(status.fundingTx.txId))
case _ => d.commitments.latest.localFundingStatus match {
- case LocalFundingStatus.DualFundedUnconfirmedFundingTx(fundingTx: PartiallySignedSharedTransaction, _, _) => Set(ChannelReestablishTlv.NextFundingTlv(fundingTx.txId.reverse))
+ case LocalFundingStatus.DualFundedUnconfirmedFundingTx(fundingTx: PartiallySignedSharedTransaction, _, _) => Set(ChannelReestablishTlv.NextFundingTlv(fundingTx.txId))
case _ => Set.empty
}
}
@@ -1991,7 +1991,7 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
.filter(c => c.fundingTxIndex > 0) // only consider splice txs
.collectFirst { case c if c.localFundingStatus.isInstanceOf[LocalFundingStatus.Locked] =>
log.debug("re-sending splice_locked for fundingTxId={}", c.fundingTxId)
- SpliceLocked(d.channelId, c.fundingTxId.reverse)
+ SpliceLocked(d.channelId, c.fundingTxId)
}
sendQueue = sendQueue ++ spliceLocked
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/ChannelOpenSingleFunded.scala b/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/ChannelOpenSingleFunded.scala
index f1b085e89e..e9990229ef 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/ChannelOpenSingleFunded.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/ChannelOpenSingleFunded.scala
@@ -19,7 +19,7 @@ package fr.acinq.eclair.channel.fsm
import akka.actor.Status
import akka.actor.typed.scaladsl.adapter.actorRefAdapter
import akka.pattern.pipe
-import fr.acinq.bitcoin.scalacompat.{SatoshiLong, Script}
+import fr.acinq.bitcoin.scalacompat.{SatoshiLong, Script, TxHash}
import fr.acinq.eclair.blockchain.OnChainWallet.MakeFundingTxResponse
import fr.acinq.eclair.blockchain.bitcoind.ZmqWatcher._
import fr.acinq.eclair.channel.Helpers.Funding
@@ -212,7 +212,7 @@ trait ChannelOpenSingleFunded extends SingleFundingHandlers with ErrorHandlers {
case Event(MakeFundingTxResponse(fundingTx, fundingTxOutputIndex, fundingTxFee), d@DATA_WAIT_FOR_FUNDING_INTERNAL(params, fundingAmount, pushMsat, commitTxFeerate, remoteFundingPubKey, remoteFirstPerCommitmentPoint, replyTo)) =>
val temporaryChannelId = params.channelId
// let's create the first commitment tx that spends the yet uncommitted funding tx
- Funding.makeFirstCommitTxs(keyManager, params, localFundingAmount = fundingAmount, remoteFundingAmount = 0 sat, localPushAmount = pushMsat, remotePushAmount = 0 msat, commitTxFeerate, fundingTx.hash, fundingTxOutputIndex, remoteFundingPubKey = remoteFundingPubKey, remoteFirstPerCommitmentPoint = remoteFirstPerCommitmentPoint) match {
+ Funding.makeFirstCommitTxs(keyManager, params, localFundingAmount = fundingAmount, remoteFundingAmount = 0 sat, localPushAmount = pushMsat, remotePushAmount = 0 msat, commitTxFeerate, fundingTx.txid, fundingTxOutputIndex, remoteFundingPubKey = remoteFundingPubKey, remoteFirstPerCommitmentPoint = remoteFirstPerCommitmentPoint) match {
case Left(ex) => handleLocalError(ex, d, None)
case Right((localSpec, localCommitTx, remoteSpec, remoteCommitTx)) =>
require(fundingTx.txOut(fundingTxOutputIndex).publicKeyScript == localCommitTx.input.txOut.publicKeyScript, s"pubkey script mismatch!")
@@ -220,11 +220,11 @@ trait ChannelOpenSingleFunded extends SingleFundingHandlers with ErrorHandlers {
// signature of their initial commitment tx that pays remote pushMsat
val fundingCreated = FundingCreated(
temporaryChannelId = temporaryChannelId,
- fundingTxHash = fundingTx.hash,
+ fundingTxId = fundingTx.txid,
fundingOutputIndex = fundingTxOutputIndex,
signature = localSigOfRemoteTx
)
- val channelId = toLongId(fundingTx.hash, fundingTxOutputIndex)
+ val channelId = toLongId(fundingTx.txid, fundingTxOutputIndex)
val params1 = params.copy(channelId = channelId)
peer ! ChannelIdAssigned(self, remoteNodeId, temporaryChannelId, channelId) // we notify the peer asap so it knows how to route messages
txPublisher ! SetChannelId(remoteNodeId, channelId)
@@ -256,10 +256,10 @@ trait ChannelOpenSingleFunded extends SingleFundingHandlers with ErrorHandlers {
})
when(WAIT_FOR_FUNDING_CREATED)(handleExceptions {
- case Event(FundingCreated(_, fundingTxHash, fundingTxOutputIndex, remoteSig, _), d@DATA_WAIT_FOR_FUNDING_CREATED(params, fundingAmount, pushMsat, commitTxFeerate, remoteFundingPubKey, remoteFirstPerCommitmentPoint)) =>
+ case Event(FundingCreated(_, fundingTxId, fundingTxOutputIndex, remoteSig, _), d@DATA_WAIT_FOR_FUNDING_CREATED(params, fundingAmount, pushMsat, commitTxFeerate, remoteFundingPubKey, remoteFirstPerCommitmentPoint)) =>
val temporaryChannelId = params.channelId
// they fund the channel with their funding tx, so the money is theirs (but we are paid pushMsat)
- Funding.makeFirstCommitTxs(keyManager, params, localFundingAmount = 0 sat, remoteFundingAmount = fundingAmount, localPushAmount = 0 msat, remotePushAmount = pushMsat, commitTxFeerate, fundingTxHash, fundingTxOutputIndex, remoteFundingPubKey = remoteFundingPubKey, remoteFirstPerCommitmentPoint = remoteFirstPerCommitmentPoint) match {
+ Funding.makeFirstCommitTxs(keyManager, params, localFundingAmount = 0 sat, remoteFundingAmount = fundingAmount, localPushAmount = 0 msat, remotePushAmount = pushMsat, commitTxFeerate, fundingTxId, fundingTxOutputIndex, remoteFundingPubKey = remoteFundingPubKey, remoteFirstPerCommitmentPoint = remoteFirstPerCommitmentPoint) match {
case Left(ex) => handleLocalError(ex, d, None)
case Right((localSpec, localCommitTx, remoteSpec, remoteCommitTx)) =>
// check remote signature validity
@@ -267,10 +267,10 @@ trait ChannelOpenSingleFunded extends SingleFundingHandlers with ErrorHandlers {
val localSigOfLocalTx = keyManager.sign(localCommitTx, fundingPubKey, TxOwner.Local, params.commitmentFormat)
val signedLocalCommitTx = Transactions.addSigs(localCommitTx, fundingPubKey.publicKey, remoteFundingPubKey, localSigOfLocalTx, remoteSig)
Transactions.checkSpendable(signedLocalCommitTx) match {
- case Failure(_) => handleLocalError(InvalidCommitmentSignature(temporaryChannelId, fundingTxHash.reverse, fundingTxIndex = 0, localCommitTx.tx), d, None)
+ case Failure(_) => handleLocalError(InvalidCommitmentSignature(temporaryChannelId, fundingTxId, fundingTxIndex = 0, localCommitTx.tx), d, None)
case Success(_) =>
val localSigOfRemoteTx = keyManager.sign(remoteCommitTx, fundingPubKey, TxOwner.Remote, params.commitmentFormat)
- val channelId = toLongId(fundingTxHash, fundingTxOutputIndex)
+ val channelId = toLongId(fundingTxId, fundingTxOutputIndex)
val fundingSigned = FundingSigned(
channelId = channelId,
signature = localSigOfRemoteTx
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/CommonFundingHandlers.scala b/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/CommonFundingHandlers.scala
index 612afbfced..f846e44a06 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/CommonFundingHandlers.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/CommonFundingHandlers.scala
@@ -19,14 +19,13 @@ package fr.acinq.eclair.channel.fsm
import akka.actor.typed.scaladsl.adapter.{TypedActorRefOps, actorRefAdapter}
import com.softwaremill.quicklens.ModifyPimp
import fr.acinq.bitcoin.ScriptFlags
-import fr.acinq.bitcoin.scalacompat.{ByteVector32, Transaction}
+import fr.acinq.bitcoin.scalacompat.{ByteVector32, Transaction, TxId}
import fr.acinq.eclair.ShortChannelId
import fr.acinq.eclair.blockchain.bitcoind.ZmqWatcher._
import fr.acinq.eclair.channel.Helpers.getRelayFees
import fr.acinq.eclair.channel.LocalFundingStatus.{ConfirmedFundingTx, DualFundedUnconfirmedFundingTx, SingleFundedUnconfirmedFundingTx}
import fr.acinq.eclair.channel._
import fr.acinq.eclair.channel.fsm.Channel.{ANNOUNCEMENTS_MINCONF, BroadcastChannelUpdate, PeriodicRefresh, REFRESH_CHANNEL_UPDATE_INTERVAL}
-import fr.acinq.eclair.router.Announcements
import fr.acinq.eclair.wire.protocol.{AnnouncementSignatures, ChannelReady, ChannelReadyTlv, TlvStream}
import scala.concurrent.duration.{DurationInt, FiniteDuration}
@@ -43,7 +42,7 @@ trait CommonFundingHandlers extends CommonHandlers {
/**
* @param delay_opt optional delay to reduce herd effect at startup.
*/
- def watchFundingSpent(commitment: Commitment, additionalKnownSpendingTxs: Set[ByteVector32], delay_opt: Option[FiniteDuration]): Unit = {
+ def watchFundingSpent(commitment: Commitment, additionalKnownSpendingTxs: Set[TxId], delay_opt: Option[FiniteDuration]): Unit = {
val knownSpendingTxs = Set(commitment.localCommit.commitTxAndRemoteSig.commitTx.tx.txid, commitment.remoteCommit.txid) ++ commitment.nextRemoteCommit_opt.map(_.commit.txid).toSet ++ additionalKnownSpendingTxs
val watch = WatchFundingSpent(self, commitment.commitInput.outPoint.txid, commitment.commitInput.outPoint.index.toInt, knownSpendingTxs)
delay_opt match {
@@ -55,7 +54,7 @@ trait CommonFundingHandlers extends CommonHandlers {
/**
* @param delay_opt optional delay to reduce herd effect at startup.
*/
- def watchFundingConfirmed(fundingTxId: ByteVector32, minDepth_opt: Option[Long], delay_opt: Option[FiniteDuration]): Unit = {
+ def watchFundingConfirmed(fundingTxId: TxId, minDepth_opt: Option[Long], delay_opt: Option[FiniteDuration]): Unit = {
val watch = minDepth_opt match {
case Some(fundingMinDepth) => WatchFundingConfirmed(self, fundingTxId, fundingMinDepth)
// When using 0-conf, we make sure that the transaction was successfully published, otherwise there is a risk
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/DualFundingHandlers.scala b/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/DualFundingHandlers.scala
index 98c277bf6e..a974563976 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/DualFundingHandlers.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/DualFundingHandlers.scala
@@ -17,6 +17,7 @@
package fr.acinq.eclair.channel.fsm
import fr.acinq.bitcoin.scalacompat.{Transaction, TxIn}
+import fr.acinq.eclair.NotificationsLogger
import fr.acinq.eclair.NotificationsLogger.NotifyNodeOperator
import fr.acinq.eclair.blockchain.CurrentBlockHeight
import fr.acinq.eclair.channel.Helpers.Closing
@@ -26,7 +27,6 @@ import fr.acinq.eclair.channel.fsm.Channel.BITCOIN_FUNDING_DOUBLE_SPENT
import fr.acinq.eclair.channel.fund.InteractiveTxBuilder._
import fr.acinq.eclair.channel.fund.{InteractiveTxBuilder, InteractiveTxSigningSession}
import fr.acinq.eclair.wire.protocol.{ChannelReady, Error}
-import fr.acinq.eclair.{Features, NotificationsLogger}
import scala.concurrent.Future
import scala.util.{Failure, Success}
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/channel/fund/InteractiveTxBuilder.scala b/eclair-core/src/main/scala/fr/acinq/eclair/channel/fund/InteractiveTxBuilder.scala
index f26c79051a..be551c75a7 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/channel/fund/InteractiveTxBuilder.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/channel/fund/InteractiveTxBuilder.scala
@@ -22,7 +22,7 @@ import akka.event.LoggingAdapter
import fr.acinq.bitcoin.ScriptFlags
import fr.acinq.bitcoin.psbt.Psbt
import fr.acinq.bitcoin.scalacompat.Crypto.PublicKey
-import fr.acinq.bitcoin.scalacompat.{ByteVector32, ByteVector64, LexicographicalOrdering, OutPoint, Satoshi, SatoshiLong, Script, ScriptWitness, Transaction, TxIn, TxOut}
+import fr.acinq.bitcoin.scalacompat.{ByteVector32, ByteVector64, LexicographicalOrdering, OutPoint, Satoshi, SatoshiLong, Script, ScriptWitness, Transaction, TxId, TxIn, TxOut}
import fr.acinq.eclair.blockchain.OnChainChannelFunder
import fr.acinq.eclair.blockchain.fee.FeeratePerKw
import fr.acinq.eclair.channel.Helpers.Closing.MutualClose
@@ -308,13 +308,13 @@ object InteractiveTxBuilder {
// @formatter:off
sealed trait SignedSharedTransaction {
- def txId: ByteVector32
+ def txId: TxId
def tx: SharedTransaction
def localSigs: TxSignatures
def signedTx_opt: Option[Transaction]
}
case class PartiallySignedSharedTransaction(tx: SharedTransaction, localSigs: TxSignatures) extends SignedSharedTransaction {
- override val txId: ByteVector32 = tx.buildUnsignedTx().txid
+ override val txId: TxId = tx.buildUnsignedTx().txid
override val signedTx_opt: Option[Transaction] = None
}
case class FullySignedSharedTransaction(tx: SharedTransaction, localSigs: TxSignatures, remoteSigs: TxSignatures, sharedSigs_opt: Option[ScriptWitness]) extends SignedSharedTransaction {
@@ -330,7 +330,7 @@ object InteractiveTxBuilder {
val outputs = (Seq(sharedTxOut) ++ localTxOut ++ remoteTxOut).sortBy(_._1).map(_._2)
Transaction(2, inputs, outputs, lockTime)
}
- override val txId: ByteVector32 = signedTx.txid
+ override val txId: TxId = signedTx.txid
override val signedTx_opt: Option[Transaction] = Some(signedTx)
val feerate: FeeratePerKw = Transactions.fee2rate(tx.fees, signedTx.weight())
}
@@ -746,7 +746,7 @@ private class InteractiveTxBuilder(replyTo: ActorRef[InteractiveTxBuilder.Respon
localHtlcs = purpose.localHtlcs,
purpose.commitTxFeerate,
fundingTxIndex = purpose.fundingTxIndex,
- fundingTx.hash, fundingOutputIndex,
+ fundingTx.txid, fundingOutputIndex,
remotePerCommitmentPoint = purpose.remotePerCommitmentPoint, remoteFundingPubKey = fundingParams.remoteFundingPubKey,
localCommitmentIndex = purpose.localCommitIndex, remoteCommitmentIndex = purpose.remoteCommitIndex) match {
case Left(cause) =>
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/channel/publish/MempoolTxMonitor.scala b/eclair-core/src/main/scala/fr/acinq/eclair/channel/publish/MempoolTxMonitor.scala
index def4647af3..4346645507 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/channel/publish/MempoolTxMonitor.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/channel/publish/MempoolTxMonitor.scala
@@ -19,7 +19,7 @@ package fr.acinq.eclair.channel.publish
import akka.actor.typed.eventstream.EventStream
import akka.actor.typed.scaladsl.{ActorContext, Behaviors, TimerScheduler}
import akka.actor.typed.{ActorRef, Behavior}
-import fr.acinq.bitcoin.scalacompat.{ByteVector32, OutPoint, Satoshi, Transaction}
+import fr.acinq.bitcoin.scalacompat.{ByteVector32, OutPoint, Satoshi, Transaction, TxId}
import fr.acinq.eclair.blockchain.CurrentBlockHeight
import fr.acinq.eclair.blockchain.bitcoind.rpc.BitcoinCoreClient
import fr.acinq.eclair.channel.publish.TxPublisher.{TxPublishContext, TxRejectedReason}
@@ -59,14 +59,14 @@ object MempoolTxMonitor {
sealed trait TxResult
sealed trait IntermediateTxResult extends TxResult
/** The transaction is still unconfirmed and available in the mempool. */
- case class TxInMempool(txid: ByteVector32, blockHeight: BlockHeight, parentConfirmed: Boolean) extends IntermediateTxResult
+ case class TxInMempool(txid: TxId, blockHeight: BlockHeight, parentConfirmed: Boolean) extends IntermediateTxResult
/** The transaction is confirmed, but hasn't reached min depth yet, we should wait for more confirmations. */
- case class TxRecentlyConfirmed(txid: ByteVector32, confirmations: Int) extends IntermediateTxResult
+ case class TxRecentlyConfirmed(txid: TxId, confirmations: Int) extends IntermediateTxResult
sealed trait FinalTxResult extends TxResult
/** The transaction is confirmed and has reached min depth. */
case class TxDeeplyBuried(tx: Transaction) extends FinalTxResult
/** The transaction has been evicted from the mempool. */
- case class TxRejected(txid: ByteVector32, reason: TxPublisher.TxRejectedReason) extends FinalTxResult
+ case class TxRejected(txid: TxId, reason: TxPublisher.TxRejectedReason) extends FinalTxResult
// @formatter:on
def apply(nodeParams: NodeParams, bitcoinClient: BitcoinCoreClient, txPublishContext: TxPublishContext): Behavior[Command] = {
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/channel/publish/TxPublisher.scala b/eclair-core/src/main/scala/fr/acinq/eclair/channel/publish/TxPublisher.scala
index 178afe1d8b..6903519824 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/channel/publish/TxPublisher.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/channel/publish/TxPublisher.scala
@@ -20,7 +20,7 @@ import akka.actor.typed.eventstream.EventStream
import akka.actor.typed.scaladsl.{ActorContext, Behaviors, TimerScheduler}
import akka.actor.typed.{ActorRef, Behavior}
import fr.acinq.bitcoin.scalacompat.Crypto.PublicKey
-import fr.acinq.bitcoin.scalacompat.{ByteVector32, OutPoint, Satoshi, Transaction}
+import fr.acinq.bitcoin.scalacompat.{ByteVector32, OutPoint, Satoshi, Transaction, TxId}
import fr.acinq.eclair.blockchain.CurrentBlockHeight
import fr.acinq.eclair.blockchain.bitcoind.ZmqWatcher
import fr.acinq.eclair.blockchain.bitcoind.rpc.BitcoinCoreClient
@@ -84,9 +84,9 @@ object TxPublisher {
* @param fee the fee that we're actually paying: it must be set to the mining fee, unless our peer is paying it (in
* which case it must be set to zero here).
*/
- case class PublishFinalTx(tx: Transaction, input: OutPoint, desc: String, fee: Satoshi, parentTx_opt: Option[ByteVector32]) extends PublishTx
+ case class PublishFinalTx(tx: Transaction, input: OutPoint, desc: String, fee: Satoshi, parentTx_opt: Option[TxId]) extends PublishTx
object PublishFinalTx {
- def apply(txInfo: TransactionWithInputInfo, fee: Satoshi, parentTx_opt: Option[ByteVector32]): PublishFinalTx = PublishFinalTx(txInfo.tx, txInfo.input.outPoint, txInfo.desc, fee, parentTx_opt)
+ def apply(txInfo: TransactionWithInputInfo, fee: Satoshi, parentTx_opt: Option[TxId]): PublishFinalTx = PublishFinalTx(txInfo.tx, txInfo.input.outPoint, txInfo.desc, fee, parentTx_opt)
}
/** Publish an unsigned transaction that can be RBF-ed. */
case class PublishReplaceableTx(txInfo: ReplaceableTransactionWithInputInfo, commitment: FullCommitment) extends PublishTx {
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/channel/publish/TxTimeLocksMonitor.scala b/eclair-core/src/main/scala/fr/acinq/eclair/channel/publish/TxTimeLocksMonitor.scala
index d8d5db1d3f..96976260b9 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/channel/publish/TxTimeLocksMonitor.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/channel/publish/TxTimeLocksMonitor.scala
@@ -19,7 +19,7 @@ package fr.acinq.eclair.channel.publish
import akka.actor.typed.eventstream.EventStream
import akka.actor.typed.scaladsl.{ActorContext, Behaviors, TimerScheduler}
import akka.actor.typed.{ActorRef, Behavior}
-import fr.acinq.bitcoin.scalacompat.{ByteVector32, Transaction}
+import fr.acinq.bitcoin.scalacompat.{Transaction, TxId}
import fr.acinq.eclair.blockchain.CurrentBlockHeight
import fr.acinq.eclair.blockchain.bitcoind.ZmqWatcher
import fr.acinq.eclair.blockchain.bitcoind.ZmqWatcher.{WatchParentTxConfirmed, WatchParentTxConfirmedTriggered}
@@ -47,7 +47,7 @@ object TxTimeLocksMonitor {
case class CheckTx(replyTo: ActorRef[TimeLocksOk], tx: Transaction, desc: String) extends Command
final case class WrappedCurrentBlockHeight(currentBlockHeight: BlockHeight) extends Command
private case object CheckRelativeTimeLock extends Command
- private case class ParentTxConfirmed(parentTxId: ByteVector32) extends Command
+ private case class ParentTxConfirmed(parentTxId: TxId) extends Command
// @formatter:on
def apply(nodeParams: NodeParams, watcher: ActorRef[ZmqWatcher.Command], txPublishContext: TxPublishContext): Behavior[Command] = {
@@ -112,7 +112,7 @@ private class TxTimeLocksMonitor(nodeParams: NodeParams,
}
}
- def waitForParentsToConfirm(parentTxIds: Set[ByteVector32]): Behavior[Command] = {
+ def waitForParentsToConfirm(parentTxIds: Set[TxId]): Behavior[Command] = {
Behaviors.receiveMessagePartial {
case ParentTxConfirmed(parentTxId) =>
log.debug("parent tx of {} has been confirmed (parent txid={})", cmd.desc, parentTxId)
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/crypto/WeakEntropyPool.scala b/eclair-core/src/main/scala/fr/acinq/eclair/crypto/WeakEntropyPool.scala
index 9cadda404b..7f588cf692 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/crypto/WeakEntropyPool.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/crypto/WeakEntropyPool.scala
@@ -20,7 +20,7 @@ import akka.actor.typed.Behavior
import akka.actor.typed.eventstream.EventStream
import akka.actor.typed.scaladsl.Behaviors
import fr.acinq.bitcoin.scalacompat.Crypto.PublicKey
-import fr.acinq.bitcoin.scalacompat.{ByteVector32, ByteVector64, Crypto}
+import fr.acinq.bitcoin.scalacompat.{BlockId, ByteVector32, ByteVector64, Crypto}
import fr.acinq.eclair.TimestampMilli
import fr.acinq.eclair.blockchain.NewBlock
import fr.acinq.eclair.channel.ChannelSignatureReceived
@@ -47,7 +47,7 @@ object WeakEntropyPool {
// @formatter:off
sealed trait Command
private case object FlushEntropy extends Command
- private case class WrappedNewBlock(blockHash: ByteVector32) extends Command
+ private case class WrappedNewBlock(blockId: BlockId) extends Command
private case class WrappedPaymentRelayed(paymentHash: ByteVector32, relayedAt: TimestampMilli) extends Command
private case class WrappedPeerConnected(nodeId: PublicKey) extends Command
private case class WrappedChannelSignature(wtxid: ByteVector32) extends Command
@@ -56,7 +56,7 @@ object WeakEntropyPool {
def apply(collector: EntropyCollector): Behavior[Command] = {
Behaviors.setup { context =>
- context.system.eventStream ! EventStream.Subscribe(context.messageAdapter[NewBlock](e => WrappedNewBlock(e.blockHash)))
+ context.system.eventStream ! EventStream.Subscribe(context.messageAdapter[NewBlock](e => WrappedNewBlock(e.blockId)))
context.system.eventStream ! EventStream.Subscribe(context.messageAdapter[ChannelPaymentRelayed](e => WrappedPaymentRelayed(e.paymentHash, e.timestamp)))
context.system.eventStream ! EventStream.Subscribe(context.messageAdapter[PeerConnected](e => WrappedPeerConnected(e.nodeId)))
context.system.eventStream ! EventStream.Subscribe(context.messageAdapter[NodeUpdated](e => WrappedNodeUpdated(e.ann.signature)))
@@ -79,7 +79,7 @@ object WeakEntropyPool {
Behaviors.same
}
- case WrappedNewBlock(blockHash) => collecting(collector, collect(entropy_opt, blockHash ++ ByteVector.fromLong(System.currentTimeMillis())))
+ case WrappedNewBlock(blockHash) => collecting(collector, collect(entropy_opt, blockHash.value ++ ByteVector.fromLong(System.currentTimeMillis())))
case WrappedPaymentRelayed(paymentHash, relayedAt) => collecting(collector, collect(entropy_opt, paymentHash ++ ByteVector.fromLong(relayedAt.toLong)))
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/crypto/keymanager/LocalChannelKeyManager.scala b/eclair-core/src/main/scala/fr/acinq/eclair/crypto/keymanager/LocalChannelKeyManager.scala
index a0140c245d..ab04e54b48 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/crypto/keymanager/LocalChannelKeyManager.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/crypto/keymanager/LocalChannelKeyManager.scala
@@ -19,7 +19,7 @@ package fr.acinq.eclair.crypto.keymanager
import com.google.common.cache.{CacheBuilder, CacheLoader, LoadingCache}
import fr.acinq.bitcoin.scalacompat.Crypto.{PrivateKey, PublicKey}
import fr.acinq.bitcoin.scalacompat.DeterministicWallet._
-import fr.acinq.bitcoin.scalacompat.{Block, ByteVector32, ByteVector64, Crypto, DeterministicWallet}
+import fr.acinq.bitcoin.scalacompat.{Block, BlockHash, ByteVector32, ByteVector64, Crypto, DeterministicWallet}
import fr.acinq.eclair.crypto.Generators
import fr.acinq.eclair.crypto.Monitoring.{Metrics, Tags}
import fr.acinq.eclair.router.Announcements
@@ -31,7 +31,7 @@ import kamon.tag.TagSet
import scodec.bits.ByteVector
object LocalChannelKeyManager {
- def keyBasePath(chainHash: ByteVector32): List[Long] = (chainHash: @unchecked) match {
+ def keyBasePath(chainHash: BlockHash): List[Long] = (chainHash: @unchecked) match {
case Block.RegtestGenesisBlock.hash | Block.TestnetGenesisBlock.hash | Block.SignetGenesisBlock.hash => DeterministicWallet.hardened(46) :: DeterministicWallet.hardened(1) :: Nil
case Block.LivenetGenesisBlock.hash => DeterministicWallet.hardened(47) :: DeterministicWallet.hardened(1) :: Nil
}
@@ -56,7 +56,7 @@ object LocalChannelKeyManager {
*
* @param seed seed from which the channel keys will be derived
*/
-class LocalChannelKeyManager(seed: ByteVector, chainHash: ByteVector32) extends ChannelKeyManager with Logging {
+class LocalChannelKeyManager(seed: ByteVector, chainHash: BlockHash) extends ChannelKeyManager with Logging {
private val master = DeterministicWallet.generate(seed)
private val privateKeys: LoadingCache[KeyPath, ExtendedPrivateKey] = CacheBuilder.newBuilder()
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/crypto/keymanager/LocalNodeKeyManager.scala b/eclair-core/src/main/scala/fr/acinq/eclair/crypto/keymanager/LocalNodeKeyManager.scala
index 484554deff..a0cfc018ca 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/crypto/keymanager/LocalNodeKeyManager.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/crypto/keymanager/LocalNodeKeyManager.scala
@@ -18,7 +18,7 @@ package fr.acinq.eclair.crypto.keymanager
import fr.acinq.bitcoin.scalacompat.Crypto.{PrivateKey, PublicKey}
import fr.acinq.bitcoin.scalacompat.DeterministicWallet.ExtendedPrivateKey
-import fr.acinq.bitcoin.scalacompat.{Block, ByteVector32, ByteVector64, Crypto, DeterministicWallet}
+import fr.acinq.bitcoin.scalacompat.{Block, BlockHash, ByteVector32, ByteVector64, Crypto, DeterministicWallet}
import fr.acinq.eclair.router.Announcements
import grizzled.slf4j.Logging
import scodec.bits.ByteVector
@@ -27,7 +27,7 @@ object LocalNodeKeyManager {
// WARNING: if you change this path, you will change your node id even if the seed remains the same!!!
// Note that the node path and the above channel path are on different branches so even if the
// node key is compromised there is no way to retrieve the wallet keys
- def keyBasePath(chainHash: ByteVector32): List[Long] = (chainHash: @unchecked) match {
+ def keyBasePath(chainHash: BlockHash): List[Long] = (chainHash: @unchecked) match {
case Block.RegtestGenesisBlock.hash | Block.TestnetGenesisBlock.hash | Block.SignetGenesisBlock.hash => DeterministicWallet.hardened(46) :: DeterministicWallet.hardened(0) :: Nil
case Block.LivenetGenesisBlock.hash => DeterministicWallet.hardened(47) :: DeterministicWallet.hardened(0) :: Nil
}
@@ -39,7 +39,7 @@ object LocalNodeKeyManager {
*
* @param seed seed from which the node key will be derived
*/
-class LocalNodeKeyManager(seed: ByteVector, chainHash: ByteVector32) extends NodeKeyManager with Logging {
+class LocalNodeKeyManager(seed: ByteVector, chainHash: BlockHash) extends NodeKeyManager with Logging {
private val master = DeterministicWallet.generate(seed)
override val nodeKey: ExtendedPrivateKey = DeterministicWallet.derivePrivateKey(master, LocalNodeKeyManager.keyBasePath(chainHash))
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/crypto/keymanager/LocalOnChainKeyManager.scala b/eclair-core/src/main/scala/fr/acinq/eclair/crypto/keymanager/LocalOnChainKeyManager.scala
index af21bfd9cf..0aa38d8194 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/crypto/keymanager/LocalOnChainKeyManager.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/crypto/keymanager/LocalOnChainKeyManager.scala
@@ -19,7 +19,7 @@ package fr.acinq.eclair.crypto.keymanager
import com.typesafe.config.ConfigFactory
import fr.acinq.bitcoin.psbt.{Psbt, UpdateFailure}
import fr.acinq.bitcoin.scalacompat.DeterministicWallet._
-import fr.acinq.bitcoin.scalacompat.{Block, ByteVector32, Crypto, DeterministicWallet, MnemonicCode, Satoshi, Script, computeBIP84Address}
+import fr.acinq.bitcoin.scalacompat.{Block, BlockHash, Crypto, DeterministicWallet, MnemonicCode, Satoshi, Script, computeBIP84Address}
import fr.acinq.eclair.TimestampSecond
import fr.acinq.eclair.blockchain.bitcoind.rpc.BitcoinCoreClient.{Descriptor, Descriptors}
import grizzled.slf4j.Logging
@@ -38,7 +38,7 @@ object LocalOnChainKeyManager extends Logging {
* @param chainHash chain we're on
* @return a LocalOnChainKeyManager instance if a configuration file exists
*/
- def load(datadir: File, chainHash: ByteVector32): Option[LocalOnChainKeyManager] = {
+ def load(datadir: File, chainHash: BlockHash): Option[LocalOnChainKeyManager] = {
// we use a specific file instead of adding values to eclair's configuration file because it is available everywhere
// in the code through the actor system's settings and we'd like to restrict access to the on-chain wallet seed
val file = new File(datadir, "eclair-signer.conf")
@@ -63,7 +63,7 @@ object LocalOnChainKeyManager extends Logging {
* Eclair is in charge of signing transactions.
* This is an advanced feature particularly suited when Eclair runs in a secure runtime.
*/
-class LocalOnChainKeyManager(override val walletName: String, seed: ByteVector, val walletTimestamp: TimestampSecond, chainHash: ByteVector32) extends OnChainKeyManager with Logging {
+class LocalOnChainKeyManager(override val walletName: String, seed: ByteVector, val walletTimestamp: TimestampSecond, chainHash: BlockHash) extends OnChainKeyManager with Logging {
// Master key derived from our seed. We use it to generate a BIP84 wallet that can be used:
// - to generate a watch-only wallet with any BIP84-compatible bitcoin wallet
@@ -72,10 +72,10 @@ class LocalOnChainKeyManager(override val walletName: String, seed: ByteVector,
private val master = DeterministicWallet.generate(seed)
private val fingerprint = DeterministicWallet.fingerprint(master) & 0xFFFFFFFFL
private val fingerPrintHex = String.format("%8s", fingerprint.toHexString).replace(' ', '0')
- // Root BIP32 on-chain path: we use BIP84 (p2wpkh) paths: m/84'/{0'/1'}
+ // Root BIP32 on-chain path: we use BIP84 (p2wpkh) paths: m/84h/{0h/1h}
private val rootPath = chainHash match {
- case Block.RegtestGenesisBlock.hash | Block.TestnetGenesisBlock.hash | Block.SignetGenesisBlock.hash => "84'/1'"
- case Block.LivenetGenesisBlock.hash => "84'/0'"
+ case Block.RegtestGenesisBlock.hash | Block.TestnetGenesisBlock.hash | Block.SignetGenesisBlock.hash => "84h/1h"
+ case Block.LivenetGenesisBlock.hash => "84h/0h"
case _ => throw new IllegalArgumentException(s"invalid chain hash $chainHash")
}
private val rootKey = DeterministicWallet.derivePrivateKey(master, KeyPath(rootPath))
@@ -86,7 +86,7 @@ class LocalOnChainKeyManager(override val walletName: String, seed: ByteVector,
case Block.LivenetGenesisBlock.hash => zpub
case _ => throw new IllegalArgumentException(s"invalid chain hash $chainHash")
}
- // master pubkey for account 0 is m/84'/{0'/1'}/0'
+ // master pubkey for account 0 is m/84h/{0h/1h}/0h
val accountPub = DeterministicWallet.publicKey(DeterministicWallet.derivePrivateKey(rootKey, hardened(account)))
DeterministicWallet.encode(accountPub, prefix)
}
@@ -98,16 +98,15 @@ class LocalOnChainKeyManager(override val walletName: String, seed: ByteVector,
}
override def descriptors(account: Long): Descriptors = {
- // TODO: we should use 'h' everywhere once bitcoin-kmp supports it.
- val keyPath = s"$rootPath/$account'".replace('\'', 'h')
+ val keyPath = s"$rootPath/${account}h"
val prefix = chainHash match {
case Block.LivenetGenesisBlock.hash => xpub
case _ => tpub
}
val accountPub = DeterministicWallet.publicKey(DeterministicWallet.derivePrivateKey(rootKey, hardened(account)))
// descriptors for account 0 are:
- // 84'/{0'/1'}/0'/0/* for main addresses
- // 84'/{0'/1'}/0'/1/* for change addresses
+ // 84h/{0h/1h}/0h/0/* for main addresses
+ // 84h/{0h/1h}/0h/1/* for change addresses
val receiveDesc = s"wpkh([$fingerPrintHex/$keyPath]${encode(accountPub, prefix)}/0/*)"
val changeDesc = s"wpkh([$fingerPrintHex/$keyPath]${encode(accountPub, prefix)}/1/*)"
Descriptors(wallet_name = walletName, descriptors = List(
@@ -120,7 +119,7 @@ class LocalOnChainKeyManager(override val walletName: String, seed: ByteVector,
for {
spent <- spentAmount(psbt, ourInputs)
change <- changeAmount(psbt, ourOutputs)
- _ = logger.debug(s"signing txid=${psbt.getGlobal.getTx.txid} fees=${psbt.computeFees()} spent=$spent change=$change")
+ _ = logger.debug(s"signing txid=${psbt.global.tx.txid} fees=${psbt.computeFees()} spent=$spent change=$change")
_ <- Try {
ourOutputs.foreach(i => require(isOurOutput(psbt, i), s"could not verify output $i: bitcoin core may be malicious"))
}
@@ -142,22 +141,22 @@ class LocalOnChainKeyManager(override val walletName: String, seed: ByteVector,
private def changeAmount(psbt: Psbt, ourOutputs: Seq[Int]): Try[Satoshi] = Try {
ourOutputs.map(i => {
- require(psbt.getGlobal.getTx.txOut.size() > i, s"output $i is missing from psbt: bitcoin core may be malicious")
- fr.acinq.bitcoin.scalacompat.KotlinUtils.kmp2scala(psbt.getGlobal.getTx.txOut.get(i).amount)
+ require(psbt.global.tx.txOut.size() > i, s"output $i is missing from psbt: bitcoin core may be malicious")
+ fr.acinq.bitcoin.scalacompat.KotlinUtils.kmp2scala(psbt.global.tx.txOut.get(i).amount)
}).sum
}
/** Check that an output belongs to us (i.e. we can recompute its public key from its bip32 path). */
private def isOurOutput(psbt: Psbt, outputIndex: Int): Boolean = {
import fr.acinq.bitcoin.scalacompat.KotlinUtils._
- if (psbt.getOutputs.size() <= outputIndex || psbt.getGlobal.getTx.txOut.size() <= outputIndex) {
+ if (psbt.outputs.size() <= outputIndex || psbt.global.tx.txOut.size() <= outputIndex) {
return false
}
- val output = psbt.getOutputs.get(outputIndex)
- val txOut = psbt.getGlobal.getTx.txOut.get(outputIndex)
+ val output = psbt.outputs.get(outputIndex)
+ val txOut = psbt.global.tx.txOut.get(outputIndex)
output.getDerivationPaths.asScala.headOption match {
case Some((pub, keypath)) =>
- val (expectedPubKey, _) = derivePublicKey(KeyPath(keypath.getKeyPath.path.asScala.toSeq.map(_.longValue())))
+ val (expectedPubKey, _) = derivePublicKey(KeyPath(keypath.keyPath.path.asScala.toSeq.map(_.longValue())))
val expectedScript = Script.write(Script.pay2wpkh(expectedPubKey))
if (expectedPubKey != kmp2scala(pub)) {
logger.warn(s"public key mismatch (expected=$expectedPubKey, actual=$pub): bitcoin core may be malicious")
@@ -187,8 +186,8 @@ class LocalOnChainKeyManager(override val walletName: String, seed: ByteVector,
// We check that these fields are consistent and match the outpoint that is spent in the PSBT.
// This prevents attacks where Bitcoin Core would lie about the amount being spent and make us pay very high fees.
require(input.getNonWitnessUtxo != null, "non-witness utxo is missing: bitcoin core may be malicious")
- require(input.getNonWitnessUtxo.txid == psbt.getGlobal.getTx.txIn.get(pos).outPoint.txid, "utxo txid mismatch: bitcoin core may be malicious")
- require(input.getNonWitnessUtxo.txOut.get(psbt.getGlobal.getTx.txIn.get(pos).outPoint.index.toInt) == input.getWitnessUtxo, "utxo mismatch: bitcoin core may be malicious")
+ require(input.getNonWitnessUtxo.txid == psbt.global.tx.txIn.get(pos).outPoint.txid, "utxo txid mismatch: bitcoin core may be malicious")
+ require(input.getNonWitnessUtxo.txOut.get(psbt.global.tx.txIn.get(pos).outPoint.index.toInt) == input.getWitnessUtxo, "utxo mismatch: bitcoin core may be malicious")
// We must use SIGHASH_ALL, otherwise we would be vulnerable to "signature reuse" attacks.
// When unspecified, the sighash used will be SIGHASH_ALL.
@@ -197,13 +196,13 @@ class LocalOnChainKeyManager(override val walletName: String, seed: ByteVector,
// Check that we're signing a p2wpkh input and that the keypath is provided and correct.
require(input.getDerivationPaths.size() == 1, "bip32 derivation path is missing: bitcoin core may be malicious")
val (pub, keypath) = input.getDerivationPaths.asScala.toSeq.head
- val priv = fr.acinq.bitcoin.DeterministicWallet.derivePrivateKey(master.priv, keypath.getKeyPath).getPrivateKey
+ val priv = fr.acinq.bitcoin.DeterministicWallet.derivePrivateKey(master.priv, keypath.keyPath).getPrivateKey
require(priv.publicKey() == pub, s"derived public key doesn't match (expected=$pub actual=${priv.publicKey()}): bitcoin core may be malicious")
val expectedScript = ByteVector(Script.write(Script.pay2wpkh(pub)))
require(kmp2scala(input.getWitnessUtxo.publicKeyScript) == expectedScript, s"script mismatch (expected=$expectedScript, actual=${input.getWitnessUtxo.publicKeyScript}): bitcoin core may be malicious")
// Update the input with the right script for a p2wpkh input, which is a *p2pkh* script, then sign and finalize.
- val updated: Either[UpdateFailure, Psbt] = psbt.updateWitnessInput(psbt.getGlobal.getTx.txIn.get(pos).outPoint, input.getWitnessUtxo, null, Script.pay2pkh(pub), SigHash.SIGHASH_ALL, input.getDerivationPaths)
+ val updated: Either[UpdateFailure, Psbt] = psbt.updateWitnessInput(psbt.global.tx.txIn.get(pos).outPoint, input.getWitnessUtxo, null, Script.pay2pkh(pub), SigHash.SIGHASH_ALL, input.getDerivationPaths)
val signed = updated.flatMap(_.sign(priv, pos))
val finalized = signed.flatMap(s => {
require(s.getSig.last.toInt == SigHash.SIGHASH_ALL, "signature must end with SIGHASH_ALL")
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/db/DualDatabases.scala b/eclair-core/src/main/scala/fr/acinq/eclair/db/DualDatabases.scala
index baa6e62fcb..66370177c4 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/db/DualDatabases.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/db/DualDatabases.scala
@@ -2,7 +2,7 @@ package fr.acinq.eclair.db
import com.google.common.util.concurrent.ThreadFactoryBuilder
import fr.acinq.bitcoin.scalacompat.Crypto.PublicKey
-import fr.acinq.bitcoin.scalacompat.{ByteVector32, Crypto, Satoshi}
+import fr.acinq.bitcoin.scalacompat.{ByteVector32, Crypto, Satoshi, TxId}
import fr.acinq.eclair.channel._
import fr.acinq.eclair.db.Databases.{FileBackup, PostgresDatabases, SqliteDatabases}
import fr.acinq.eclair.db.DbEventHandler.ChannelEvent
@@ -11,7 +11,7 @@ import fr.acinq.eclair.payment._
import fr.acinq.eclair.payment.relay.Relayer.RelayFees
import fr.acinq.eclair.router.Router
import fr.acinq.eclair.wire.protocol.{ChannelAnnouncement, ChannelUpdate, NodeAddress, NodeAnnouncement}
-import fr.acinq.eclair.{CltvExpiry, MilliSatoshi, Paginated, RealShortChannelId, ShortChannelId, TimestampMilli, TimestampSecond}
+import fr.acinq.eclair.{CltvExpiry, MilliSatoshi, Paginated, RealShortChannelId, ShortChannelId, TimestampMilli}
import grizzled.slf4j.Logging
import java.io.File
@@ -99,7 +99,7 @@ case class DualNetworkDb(primary: NetworkDb, secondary: NetworkDb) extends Netwo
primary.listNodes()
}
- override def addChannel(c: ChannelAnnouncement, txid: ByteVector32, capacity: Satoshi): Unit = {
+ override def addChannel(c: ChannelAnnouncement, txid: TxId, capacity: Satoshi): Unit = {
runAsync(secondary.addChannel(c, txid, capacity))
primary.addChannel(c, txid, capacity)
}
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/db/NetworkDb.scala b/eclair-core/src/main/scala/fr/acinq/eclair/db/NetworkDb.scala
index 83fa20e341..e8d589ca34 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/db/NetworkDb.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/db/NetworkDb.scala
@@ -17,7 +17,7 @@
package fr.acinq.eclair.db
import fr.acinq.bitcoin.scalacompat.Crypto.PublicKey
-import fr.acinq.bitcoin.scalacompat.{ByteVector32, Satoshi}
+import fr.acinq.bitcoin.scalacompat.{Satoshi, TxId}
import fr.acinq.eclair.router.Router.PublicChannel
import fr.acinq.eclair.wire.protocol.{ChannelAnnouncement, ChannelUpdate, NodeAnnouncement}
import fr.acinq.eclair.{RealShortChannelId, ShortChannelId}
@@ -36,7 +36,7 @@ trait NetworkDb {
def listNodes(): Seq[NodeAnnouncement]
- def addChannel(c: ChannelAnnouncement, txid: ByteVector32, capacity: Satoshi): Unit
+ def addChannel(c: ChannelAnnouncement, txid: TxId, capacity: Satoshi): Unit
def updateChannel(u: ChannelUpdate): Unit
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/db/pg/PgAuditDb.scala b/eclair-core/src/main/scala/fr/acinq/eclair/db/pg/PgAuditDb.scala
index 1e8ce962f5..6547012952 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/db/pg/PgAuditDb.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/db/pg/PgAuditDb.scala
@@ -259,7 +259,7 @@ class PgAuditDb(implicit ds: DataSource) extends AuditDb with Logging {
override def add(e: TransactionPublished): Unit = withMetrics("audit/add-transaction-published", DbBackends.Postgres) {
inTransaction { pg =>
using(pg.prepareStatement("INSERT INTO audit.transactions_published VALUES (?, ?, ?, ?, ?, ?) ON CONFLICT DO NOTHING")) { statement =>
- statement.setString(1, e.tx.txid.toHex)
+ statement.setString(1, e.tx.txid.value.toHex)
statement.setString(2, e.channelId.toHex)
statement.setString(3, e.remoteNodeId.value.toHex)
statement.setLong(4, e.miningFee.toLong)
@@ -273,7 +273,7 @@ class PgAuditDb(implicit ds: DataSource) extends AuditDb with Logging {
override def add(e: TransactionConfirmed): Unit = withMetrics("audit/add-transaction-confirmed", DbBackends.Postgres) {
inTransaction { pg =>
using(pg.prepareStatement("INSERT INTO audit.transactions_confirmed VALUES (?, ?, ?, ?) ON CONFLICT DO NOTHING")) { statement =>
- statement.setString(1, e.tx.txid.toHex)
+ statement.setString(1, e.tx.txid.value.toHex)
statement.setString(2, e.channelId.toHex)
statement.setString(3, e.remoteNodeId.value.toHex)
statement.setTimestamp(4, Timestamp.from(Instant.now()))
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/db/pg/PgNetworkDb.scala b/eclair-core/src/main/scala/fr/acinq/eclair/db/pg/PgNetworkDb.scala
index 1319f6dd1e..10d1250e17 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/db/pg/PgNetworkDb.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/db/pg/PgNetworkDb.scala
@@ -16,7 +16,7 @@
package fr.acinq.eclair.db.pg
-import fr.acinq.bitcoin.scalacompat.{ByteVector32, Crypto, Satoshi}
+import fr.acinq.bitcoin.scalacompat.{Crypto, Satoshi, TxId}
import fr.acinq.eclair.db.Monitoring.Metrics.withMetrics
import fr.acinq.eclair.db.Monitoring.Tags.DbBackends
import fr.acinq.eclair.db.NetworkDb
@@ -182,12 +182,12 @@ class PgNetworkDb(implicit ds: DataSource) extends NetworkDb with Logging {
}
}
- override def addChannel(c: ChannelAnnouncement, txid: ByteVector32, capacity: Satoshi): Unit = withMetrics("network/add-channel", DbBackends.Postgres) {
+ override def addChannel(c: ChannelAnnouncement, txid: TxId, capacity: Satoshi): Unit = withMetrics("network/add-channel", DbBackends.Postgres) {
inTransaction { pg =>
using(pg.prepareStatement("INSERT INTO network.public_channels (short_channel_id, txid, channel_announcement, capacity_sat, channel_announcement_json) VALUES (?, ?, ?, ?, ?::JSONB) ON CONFLICT DO NOTHING")) {
statement =>
statement.setLong(1, c.shortChannelId.toLong)
- statement.setString(2, txid.toHex)
+ statement.setString(2, txid.value.toHex)
statement.setBytes(3, channelAnnouncementCodec.encode(c).require.toByteArray)
statement.setLong(4, capacity.toLong)
statement.setString(5, serialization.write(c))
@@ -211,7 +211,7 @@ class PgNetworkDb(implicit ds: DataSource) extends NetworkDb with Logging {
private def parseChannel(rs: ResultSet): PublicChannel = {
val ann = channelAnnouncementCodec.decode(rs.getBitVectorOpt("channel_announcement").get).require.value
- val txId = ByteVector32.fromValidHex(rs.getString("txid"))
+ val txId = TxId.fromValidHex(rs.getString("txid"))
val capacity = rs.getLong("capacity_sat")
val channel_update_1_opt = rs.getBitVectorOpt("channel_update_1").map(channelUpdateCodec.decode(_).require.value)
val channel_update_2_opt = rs.getBitVectorOpt("channel_update_2").map(channelUpdateCodec.decode(_).require.value)
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 4262a52358..f0decc63de 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
@@ -246,7 +246,7 @@ class SqliteAuditDb(val sqlite: Connection) extends AuditDb with Logging {
override def add(e: TransactionPublished): Unit = withMetrics("audit/add-transaction-published", DbBackends.Sqlite) {
using(sqlite.prepareStatement("INSERT OR IGNORE INTO transactions_published VALUES (?, ?, ?, ?, ?, ?)")) { statement =>
- statement.setBytes(1, e.tx.txid.toArray)
+ statement.setBytes(1, e.tx.txid.value.toArray)
statement.setBytes(2, e.channelId.toArray)
statement.setBytes(3, e.remoteNodeId.value.toArray)
statement.setLong(4, e.miningFee.toLong)
@@ -258,7 +258,7 @@ class SqliteAuditDb(val sqlite: Connection) extends AuditDb with Logging {
override def add(e: TransactionConfirmed): Unit = withMetrics("audit/add-transaction-confirmed", DbBackends.Sqlite) {
using(sqlite.prepareStatement("INSERT OR IGNORE INTO transactions_confirmed VALUES (?, ?, ?, ?)")) { statement =>
- statement.setBytes(1, e.tx.txid.toArray)
+ statement.setBytes(1, e.tx.txid.value.toArray)
statement.setBytes(2, e.channelId.toArray)
statement.setBytes(3, e.remoteNodeId.value.toArray)
statement.setLong(4, TimestampMilli.now().toLong)
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/db/sqlite/SqliteNetworkDb.scala b/eclair-core/src/main/scala/fr/acinq/eclair/db/sqlite/SqliteNetworkDb.scala
index 77002b5697..67bad8a2c7 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/db/sqlite/SqliteNetworkDb.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/db/sqlite/SqliteNetworkDb.scala
@@ -16,7 +16,7 @@
package fr.acinq.eclair.db.sqlite
-import fr.acinq.bitcoin.scalacompat.{ByteVector32, Crypto, Satoshi}
+import fr.acinq.bitcoin.scalacompat.{Crypto, Satoshi, TxId}
import fr.acinq.eclair.db.Monitoring.Metrics.withMetrics
import fr.acinq.eclair.db.Monitoring.Tags.DbBackends
import fr.acinq.eclair.db.NetworkDb
@@ -115,10 +115,10 @@ class SqliteNetworkDb(val sqlite: Connection) extends NetworkDb with Logging {
}
}
- override def addChannel(c: ChannelAnnouncement, txid: ByteVector32, capacity: Satoshi): Unit = withMetrics("network/add-channel", DbBackends.Sqlite) {
+ override def addChannel(c: ChannelAnnouncement, txid: TxId, capacity: Satoshi): Unit = withMetrics("network/add-channel", DbBackends.Sqlite) {
using(sqlite.prepareStatement("INSERT OR IGNORE INTO channels VALUES (?, ?, ?, ?, NULL, NULL)")) { statement =>
statement.setLong(1, c.shortChannelId.toLong)
- statement.setString(2, txid.toHex)
+ statement.setString(2, txid.value.toHex)
statement.setBytes(3, channelAnnouncementCodec.encode(c).require.toByteArray)
statement.setLong(4, capacity.toLong)
statement.executeUpdate()
@@ -136,7 +136,7 @@ class SqliteNetworkDb(val sqlite: Connection) extends NetworkDb with Logging {
private def parseChannel(rs: ResultSet): PublicChannel = {
val ann = channelAnnouncementCodec.decode(rs.getBitVectorOpt("channel_announcement").get).require.value
- val txId = ByteVector32.fromValidHex(rs.getString("txid"))
+ val txId = TxId.fromValidHex(rs.getString("txid"))
val capacity = rs.getLong("capacity_sat")
val channel_update_1_opt = rs.getBitVectorOpt("channel_update_1").map(channelUpdateCodec.decode(_).require.value)
val channel_update_2_opt = rs.getBitVectorOpt("channel_update_2").map(channelUpdateCodec.decode(_).require.value)
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 7f2cc36a2f..63993e5291 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
@@ -23,7 +23,7 @@ import akka.event.Logging.MDC
import akka.event.{BusLogging, DiagnosticLoggingAdapter}
import akka.util.Timeout
import fr.acinq.bitcoin.scalacompat.Crypto.PublicKey
-import fr.acinq.bitcoin.scalacompat.{ByteVector32, Satoshi, SatoshiLong}
+import fr.acinq.bitcoin.scalacompat.{ByteVector32, Satoshi, SatoshiLong, TxId}
import fr.acinq.eclair.Logs.LogCategory
import fr.acinq.eclair.NotificationsLogger.NotifyNodeOperator
import fr.acinq.eclair._
@@ -526,7 +526,7 @@ object Peer {
* double-spend the funding transaction. Callers must wait for on-chain confirmations if they want guarantees that
* the channel has been opened.
*/
- case class Created(channelId: ByteVector32, fundingTxId: ByteVector32, fee: Satoshi) extends OpenChannelResponse { override def toString = s"created channel $channelId with fundingTxId=$fundingTxId and fees=$fee" }
+ case class Created(channelId: ByteVector32, fundingTxId: TxId, fee: Satoshi) extends OpenChannelResponse { override def toString = s"created channel $channelId with fundingTxId=$fundingTxId and fees=$fee" }
case class Rejected(reason: String) extends OpenChannelResponse { override def toString = reason }
case object Cancelled extends OpenChannelResponse { override def toString = "channel creation cancelled" }
case object Disconnected extends OpenChannelResponse { override def toString = "disconnected" }
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/io/PeerConnection.scala b/eclair-core/src/main/scala/fr/acinq/eclair/io/PeerConnection.scala
index e52417c008..e0f2edc4e9 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/io/PeerConnection.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/io/PeerConnection.scala
@@ -18,7 +18,7 @@ package fr.acinq.eclair.io
import akka.actor.{ActorRef, FSM, OneForOneStrategy, PoisonPill, Props, Stash, SupervisorStrategy, Terminated}
import akka.event.Logging.MDC
-import fr.acinq.bitcoin.scalacompat.ByteVector32
+import fr.acinq.bitcoin.scalacompat.{BlockHash, ByteVector32}
import fr.acinq.bitcoin.scalacompat.Crypto.PublicKey
import fr.acinq.eclair.Logs.LogCategory
import fr.acinq.eclair.crypto.Noise.KeyPair
@@ -555,8 +555,8 @@ object PeerConnection {
case object Nothing extends Data
case class AuthenticatingData(pendingAuth: PendingAuth, transport: ActorRef, isPersistent: Boolean) extends Data with HasTransport
case class BeforeInitData(remoteNodeId: PublicKey, pendingAuth: PendingAuth, transport: ActorRef, isPersistent: Boolean) extends Data with HasTransport
- case class InitializingData(chainHash: ByteVector32, pendingAuth: PendingAuth, remoteNodeId: PublicKey, transport: ActorRef, peer: ActorRef, localInit: protocol.Init, doSync: Boolean, isPersistent: Boolean) extends Data with HasTransport
- case class ConnectedData(chainHash: ByteVector32, remoteNodeId: PublicKey, transport: ActorRef, peer: ActorRef, localInit: protocol.Init, remoteInit: protocol.Init, rebroadcastDelay: FiniteDuration, gossipTimestampFilter: Option[GossipTimestampFilter] = None, behavior: Behavior = Behavior(), expectedPong_opt: Option[ExpectedPong] = None, isPersistent: Boolean) extends Data with HasTransport
+ case class InitializingData(chainHash: BlockHash, pendingAuth: PendingAuth, remoteNodeId: PublicKey, transport: ActorRef, peer: ActorRef, localInit: protocol.Init, doSync: Boolean, isPersistent: Boolean) extends Data with HasTransport
+ case class ConnectedData(chainHash: BlockHash, remoteNodeId: PublicKey, transport: ActorRef, peer: ActorRef, localInit: protocol.Init, remoteInit: protocol.Init, rebroadcastDelay: FiniteDuration, gossipTimestampFilter: Option[GossipTimestampFilter] = None, behavior: Behavior = Behavior(), expectedPong_opt: Option[ExpectedPong] = None, isPersistent: Boolean) extends Data with HasTransport
case class ExpectedPong(ping: Ping, timestamp: TimestampMilli = TimestampMilli.now())
case class PingTimeout(ping: Ping)
@@ -572,7 +572,7 @@ object PeerConnection {
def outgoing: Boolean = remoteNodeId_opt.isDefined // if this is an outgoing connection, we know the node id in advance
}
case class Authenticated(peerConnection: ActorRef, remoteNodeId: PublicKey, outgoing: Boolean) extends RemoteTypes
- case class InitializeConnection(peer: ActorRef, chainHash: ByteVector32, features: Features[InitFeature], doSync: Boolean) extends RemoteTypes
+ case class InitializeConnection(peer: ActorRef, chainHash: BlockHash, features: Features[InitFeature], doSync: Boolean) extends RemoteTypes
case class ConnectionReady(peerConnection: ActorRef, remoteNodeId: PublicKey, address: NodeAddress, outgoing: Boolean, localInit: protocol.Init, remoteInit: protocol.Init) extends RemoteTypes
sealed trait ConnectionResult extends RemoteTypes
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/json/JsonSerializers.scala b/eclair-core/src/main/scala/fr/acinq/eclair/json/JsonSerializers.scala
index c093cdd575..9a0d6e4a2b 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/json/JsonSerializers.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/json/JsonSerializers.scala
@@ -19,7 +19,7 @@ package fr.acinq.eclair.json
import com.google.common.net.HostAndPort
import fr.acinq.bitcoin.scalacompat.Crypto.{PrivateKey, PublicKey}
import fr.acinq.bitcoin.scalacompat.DeterministicWallet.KeyPath
-import fr.acinq.bitcoin.scalacompat.{Btc, ByteVector32, ByteVector64, OutPoint, Satoshi, Transaction}
+import fr.acinq.bitcoin.scalacompat.{BlockHash, BlockId, Btc, ByteVector32, ByteVector64, OutPoint, Satoshi, Transaction, TxId}
import fr.acinq.eclair.balance.CheckBalance.{CorrectedOnChainBalance, GlobalBalance, OffChainBalance}
import fr.acinq.eclair.blockchain.fee.{ConfirmationTarget, FeeratePerKw}
import fr.acinq.eclair.channel._
@@ -118,6 +118,34 @@ object ByteVector32KmpSerializer extends MinimalSerializer({
case x: fr.acinq.bitcoin.ByteVector32 => JString(x.toHex)
})
+object TxIdSerializer extends MinimalSerializer({
+ case x: TxId => JString(x.value.toHex)
+})
+
+object TxIdKeySerializer extends MinimalKeySerializer({
+ case x: TxId => x.value.toHex
+})
+
+object TxIdKmpSerializer extends MinimalSerializer({
+ case x: fr.acinq.bitcoin.TxId => JString(x.value.toHex)
+})
+
+object BlockIdSerializer extends MinimalSerializer({
+ case x: BlockId => JString(x.value.toHex)
+})
+
+object BlockIdKmpSerializer extends MinimalSerializer({
+ case x: fr.acinq.bitcoin.BlockId => JString(x.value.toHex)
+})
+
+object BlockHashSerializer extends MinimalSerializer({
+ case x: BlockHash => JString(x.value.toHex)
+})
+
+object BlockHashKmpSerializer extends MinimalSerializer({
+ case x: fr.acinq.bitcoin.BlockHash => JString(x.value.toHex)
+})
+
object ByteVector64Serializer extends MinimalSerializer({
case x: ByteVector64 => JString(x.toHex)
})
@@ -217,7 +245,7 @@ object CommandResponseSerializer extends MinimalSerializer({
object TransactionSerializer extends MinimalSerializer({
case x: Transaction => JObject(List(
- JField("txid", JString(x.txid.toHex)),
+ JField("txid", JString(x.txid.value.toHex)),
JField("tx", JString(x.toString()))
))
})
@@ -228,34 +256,34 @@ object KeyPathSerializer extends MinimalSerializer({
object TransactionWithInputInfoSerializer extends MinimalSerializer({
case x: HtlcSuccessTx => JObject(List(
- JField("txid", JString(x.tx.txid.toHex)),
+ JField("txid", JString(x.tx.txid.value.toHex)),
JField("tx", JString(x.tx.toString())),
JField("paymentHash", JString(x.paymentHash.toString())),
JField("htlcId", JLong(x.htlcId)),
JField("confirmBeforeBlock", JLong(x.confirmationTarget.confirmBefore.toLong))
))
case x: HtlcTimeoutTx => JObject(List(
- JField("txid", JString(x.tx.txid.toHex)),
+ JField("txid", JString(x.tx.txid.value.toHex)),
JField("tx", JString(x.tx.toString())),
JField("htlcId", JLong(x.htlcId)),
JField("confirmBeforeBlock", JLong(x.confirmationTarget.confirmBefore.toLong))
))
case x: ClaimHtlcSuccessTx => JObject(List(
- JField("txid", JString(x.tx.txid.toHex)),
+ JField("txid", JString(x.tx.txid.value.toHex)),
JField("tx", JString(x.tx.toString())),
JField("paymentHash", JString(x.paymentHash.toString())),
JField("htlcId", JLong(x.htlcId)),
JField("confirmBeforeBlock", JLong(x.confirmationTarget.confirmBefore.toLong))
))
case x: ClaimHtlcTx => JObject(List(
- JField("txid", JString(x.tx.txid.toHex)),
+ JField("txid", JString(x.tx.txid.value.toHex)),
JField("tx", JString(x.tx.toString())),
JField("htlcId", JLong(x.htlcId)),
JField("confirmBeforeBlock", JLong(x.confirmationTarget.confirmBefore.toLong))
))
case x: ClosingTx =>
val txFields = List(
- JField("txid", JString(x.tx.txid.toHex)),
+ JField("txid", JString(x.tx.txid.value.toHex)),
JField("tx", JString(x.tx.toString()))
)
x.toLocalOutput match {
@@ -269,7 +297,7 @@ object TransactionWithInputInfoSerializer extends MinimalSerializer({
case None => JObject(txFields)
}
case x: ReplaceableTransactionWithInputInfo => JObject(List(
- JField("txid", JString(x.tx.txid.toHex)),
+ JField("txid", JString(x.tx.txid.value.toHex)),
JField("tx", JString(x.tx.toString())),
x.confirmationTarget match {
case ConfirmationTarget.Absolute(confirmBefore) => JField("confirmBeforeBlock", JLong(confirmBefore.toLong))
@@ -278,7 +306,7 @@ object TransactionWithInputInfoSerializer extends MinimalSerializer({
))
case x: TransactionWithInputInfo => JObject(List(
- JField("txid", JString(x.tx.txid.toHex)),
+ JField("txid", JString(x.tx.txid.value.toHex)),
JField("tx", JString(x.tx.toString()))
))
})
@@ -528,7 +556,7 @@ object ShortIdsSerializer extends ConvertClassSerializer[ShortIds](s => ShortIds
// @formatter:on
// @formatter:off
-private case class FundingTxStatusJson(status: String, txid: Option[ByteVector32])
+private case class FundingTxStatusJson(status: String, txid: Option[TxId])
object FundingTxStatusSerializer extends ConvertClassSerializer[LocalFundingStatus]({
case s: LocalFundingStatus.UnconfirmedFundingTx => FundingTxStatusJson("unconfirmed", s.signedTx_opt.map(_.txid))
case s: LocalFundingStatus.ConfirmedFundingTx => FundingTxStatusJson("confirmed", s.signedTx_opt.map(_.txid))
@@ -634,6 +662,9 @@ object JsonSerializers {
TypedActorRefSerializer +
ByteVectorSerializer +
ByteVector32Serializer +
+ TxIdSerializer +
+ BlockIdSerializer +
+ BlockHashSerializer +
ByteVector64Serializer +
ChannelEventSerializer +
UInt64Serializer +
@@ -676,6 +707,7 @@ object JsonSerializers {
JavaUUIDSerializer +
OriginSerializer +
ByteVector32KeySerializer +
+ TxIdKeySerializer +
GlobalBalanceSerializer +
PeerInfoSerializer +
PaymentFailedSummarySerializer +
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 648d1f37f7..3f0f470f76 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/package.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/package.scala
@@ -16,7 +16,6 @@
package fr.acinq
-import fr.acinq.bitcoin.Bitcoin
import fr.acinq.bitcoin.scalacompat.Crypto.PrivateKey
import fr.acinq.bitcoin.scalacompat.KotlinUtils._
import fr.acinq.bitcoin.scalacompat._
@@ -25,8 +24,6 @@ import fr.acinq.eclair.payment.relay.Relayer.RelayFees
import scodec.Attempt
import scodec.bits.{BitVector, ByteVector}
-import scala.jdk.CollectionConverters.CollectionHasAsScala
-
package object eclair {
val randomGen = new StrongRandom()
@@ -45,8 +42,9 @@ package object eclair {
def randomLong(): Long = randomGen.nextLong()
- def toLongId(fundingTxHash: ByteVector32, fundingOutputIndex: Int): ByteVector32 = {
- require(fundingOutputIndex < 65536, "fundingOutputIndex must not be greater than FFFF")
+ def toLongId(fundingTxId: TxId, fundingOutputIndex: Int): ByteVector32 = {
+ require(fundingOutputIndex < 65536, "fundingOutputIndex must not be greater than 0xFFFF")
+ val fundingTxHash = TxHash(fundingTxId).value
val channelId = ByteVector32(fundingTxHash.take(30) :+ (fundingTxHash(30) ^ (fundingOutputIndex >> 8)).toByte :+ (fundingTxHash(31) ^ fundingOutputIndex).toByte)
channelId
}
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/payment/Bolt11Invoice.scala b/eclair-core/src/main/scala/fr/acinq/eclair/payment/Bolt11Invoice.scala
index 027f217f9e..04896da44c 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/payment/Bolt11Invoice.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/payment/Bolt11Invoice.scala
@@ -17,7 +17,7 @@
package fr.acinq.eclair.payment
import fr.acinq.bitcoin.scalacompat.Crypto.{PrivateKey, PublicKey}
-import fr.acinq.bitcoin.scalacompat.{Block, ByteVector32, ByteVector64, Crypto}
+import fr.acinq.bitcoin.scalacompat.{Block, BlockHash, ByteVector32, ByteVector64, Crypto}
import fr.acinq.bitcoin.{Base58, Base58Check, Bech32}
import fr.acinq.eclair.{Bolt11Feature, CltvExpiryDelta, Feature, FeatureSupport, Features, InvoiceFeature, MilliSatoshi, MilliSatoshiLong, ShortChannelId, TimestampSecond, randomBytes32}
import scodec.bits.{BitVector, ByteOrdering, ByteVector}
@@ -144,7 +144,7 @@ object Bolt11Invoice {
val defaultFeatures: Features[Bolt11Feature] = Features((Features.VariableLengthOnion, FeatureSupport.Mandatory), (Features.PaymentSecret, FeatureSupport.Mandatory))
- def apply(chainHash: ByteVector32,
+ def apply(chainHash: BlockHash,
amount: Option[MilliSatoshi],
paymentHash: ByteVector32,
privateKey: PrivateKey,
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/payment/Bolt12Invoice.scala b/eclair-core/src/main/scala/fr/acinq/eclair/payment/Bolt12Invoice.scala
index 5963479bc4..e65811560c 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/payment/Bolt12Invoice.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/payment/Bolt12Invoice.scala
@@ -18,7 +18,7 @@ package fr.acinq.eclair.payment
import fr.acinq.bitcoin.Bech32
import fr.acinq.bitcoin.scalacompat.Crypto.{PrivateKey, PublicKey}
-import fr.acinq.bitcoin.scalacompat.{ByteVector32, ByteVector64, Crypto}
+import fr.acinq.bitcoin.scalacompat.{BlockHash, ByteVector32, ByteVector64, Crypto}
import fr.acinq.eclair.crypto.Sphinx
import fr.acinq.eclair.crypto.Sphinx.RouteBlinding.BlindedRoute
import fr.acinq.eclair.wire.protocol.OfferTypes._
@@ -191,7 +191,7 @@ object MinimalBolt12Invoice {
val hrp = "lndi"
def apply(offer: Offer,
- chain: ByteVector32,
+ chain: BlockHash,
amount: MilliSatoshi,
quantity: Long,
paymentHash: ByteVector32,
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/payment/send/OfferPayment.scala b/eclair-core/src/main/scala/fr/acinq/eclair/payment/send/OfferPayment.scala
index 2fc19f0703..8dc23a4db9 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/payment/send/OfferPayment.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/payment/send/OfferPayment.scala
@@ -19,7 +19,7 @@ package fr.acinq.eclair.payment.send
import akka.actor.typed.Behavior
import akka.actor.typed.scaladsl.{ActorContext, Behaviors}
import akka.actor.{ActorRef, typed}
-import fr.acinq.bitcoin.scalacompat.ByteVector32
+import fr.acinq.bitcoin.scalacompat.BlockHash
import fr.acinq.bitcoin.scalacompat.Crypto.{PrivateKey, PublicKey}
import fr.acinq.eclair.crypto.Sphinx.RouteBlinding.BlindedRoute
import fr.acinq.eclair.message.Postman.{OnionMessageResponse, SendMessage}
@@ -40,7 +40,7 @@ object OfferPayment {
case class UnsupportedFeatures(features: Features[InvoiceFeature]) extends Failure
- case class UnsupportedChains(chains: Seq[ByteVector32]) extends Failure
+ case class UnsupportedChains(chains: Seq[BlockHash]) extends Failure
case class ExpiredOffer(expiryDate: TimestampSecond) extends Failure
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/remote/EclairInternalsSerializer.scala b/eclair-core/src/main/scala/fr/acinq/eclair/remote/EclairInternalsSerializer.scala
index 01b634a0f4..4fb6e472cb 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/remote/EclairInternalsSerializer.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/remote/EclairInternalsSerializer.scala
@@ -149,7 +149,7 @@ object EclairInternalsSerializer {
def initializeConnectionCodec(system: ExtendedActorSystem): Codec[PeerConnection.InitializeConnection] = (
("peer" | actorRefCodec(system)) ::
- ("chainHash" | bytes32) ::
+ ("chainHash" | blockHash) ::
("features" | variableSizeBytes(uint16, initFeaturesCodec)) ::
("doSync" | bool(8))).as[PeerConnection.InitializeConnection]
@@ -164,7 +164,7 @@ object EclairInternalsSerializer {
val optionQueryChannelRangeTlv: Codec[Option[QueryChannelRangeTlv]] = variableSizeBytes(uint16, optional(bool(8), variableSizeBytesLong(varintoverflow, queryFlagsCodec.upcast[QueryChannelRangeTlv])))
def sendChannelQueryCodec(system: ExtendedActorSystem): Codec[SendChannelQuery] = (
- ("chainsHash" | bytes32) ::
+ ("chainHash" | blockHash) ::
("remoteNodeId" | publicKey) ::
("to" | actorRefCodec(system)) ::
("replacePrevious" | bool(8)) ::
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 fe11bf8c6d..b1c4f99639 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
@@ -17,7 +17,7 @@
package fr.acinq.eclair.router
import fr.acinq.bitcoin.scalacompat.Crypto.{PrivateKey, PublicKey, sha256, verifySignature}
-import fr.acinq.bitcoin.scalacompat.{ByteVector32, ByteVector64, Crypto, LexicographicalOrdering}
+import fr.acinq.bitcoin.scalacompat.{BlockHash, ByteVector64, Crypto, LexicographicalOrdering}
import fr.acinq.eclair.wire.protocol._
import fr.acinq.eclair.{CltvExpiryDelta, Feature, Features, MilliSatoshi, NodeFeature, RealShortChannelId, ShortChannelId, TimestampSecond, TimestampSecondLong, serializationResult}
import scodec.bits.ByteVector
@@ -28,16 +28,16 @@ import shapeless.HNil
*/
object Announcements {
- def channelAnnouncementWitnessEncode(chainHash: ByteVector32, shortChannelId: RealShortChannelId, nodeId1: PublicKey, nodeId2: PublicKey, bitcoinKey1: PublicKey, bitcoinKey2: PublicKey, features: Features[Feature], tlvStream: TlvStream[ChannelAnnouncementTlv]): ByteVector =
+ def channelAnnouncementWitnessEncode(chainHash: BlockHash, shortChannelId: RealShortChannelId, nodeId1: PublicKey, nodeId2: PublicKey, bitcoinKey1: PublicKey, bitcoinKey2: PublicKey, features: Features[Feature], tlvStream: TlvStream[ChannelAnnouncementTlv]): ByteVector =
sha256(sha256(serializationResult(LightningMessageCodecs.channelAnnouncementWitnessCodec.encode(features :: chainHash :: shortChannelId :: nodeId1 :: nodeId2 :: bitcoinKey1 :: bitcoinKey2 :: tlvStream :: HNil))))
def nodeAnnouncementWitnessEncode(timestamp: TimestampSecond, nodeId: PublicKey, rgbColor: Color, alias: String, features: Features[Feature], addresses: List[NodeAddress], tlvStream: TlvStream[NodeAnnouncementTlv]): ByteVector =
sha256(sha256(serializationResult(LightningMessageCodecs.nodeAnnouncementWitnessCodec.encode(features :: timestamp :: nodeId :: rgbColor :: alias :: addresses :: tlvStream :: HNil))))
- def channelUpdateWitnessEncode(chainHash: ByteVector32, shortChannelId: ShortChannelId, timestamp: TimestampSecond, messageFlags: ChannelUpdate.MessageFlags, channelFlags: ChannelUpdate.ChannelFlags, cltvExpiryDelta: CltvExpiryDelta, htlcMinimumMsat: MilliSatoshi, feeBaseMsat: MilliSatoshi, feeProportionalMillionths: Long, htlcMaximumMsat: MilliSatoshi, tlvStream: TlvStream[ChannelUpdateTlv]): ByteVector =
+ def channelUpdateWitnessEncode(chainHash: BlockHash, shortChannelId: ShortChannelId, timestamp: TimestampSecond, messageFlags: ChannelUpdate.MessageFlags, channelFlags: ChannelUpdate.ChannelFlags, cltvExpiryDelta: CltvExpiryDelta, htlcMinimumMsat: MilliSatoshi, feeBaseMsat: MilliSatoshi, feeProportionalMillionths: Long, htlcMaximumMsat: MilliSatoshi, tlvStream: TlvStream[ChannelUpdateTlv]): ByteVector =
sha256(sha256(serializationResult(LightningMessageCodecs.channelUpdateWitnessCodec.encode(chainHash :: shortChannelId :: timestamp :: messageFlags :: channelFlags :: cltvExpiryDelta :: htlcMinimumMsat :: feeBaseMsat :: feeProportionalMillionths :: htlcMaximumMsat :: tlvStream :: HNil))))
- def generateChannelAnnouncementWitness(chainHash: ByteVector32, shortChannelId: RealShortChannelId, localNodeId: PublicKey, remoteNodeId: PublicKey, localFundingKey: PublicKey, remoteFundingKey: PublicKey, features: Features[Feature]): ByteVector =
+ def generateChannelAnnouncementWitness(chainHash: BlockHash, shortChannelId: RealShortChannelId, localNodeId: PublicKey, remoteNodeId: PublicKey, localFundingKey: PublicKey, remoteFundingKey: PublicKey, features: Features[Feature]): ByteVector =
if (isNode1(localNodeId, remoteNodeId)) {
channelAnnouncementWitnessEncode(chainHash, shortChannelId, localNodeId, remoteNodeId, localFundingKey, remoteFundingKey, features, TlvStream.empty)
} else {
@@ -46,7 +46,7 @@ object Announcements {
def signChannelAnnouncement(witness: ByteVector, key: PrivateKey): ByteVector64 = Crypto.sign(witness, key)
- def makeChannelAnnouncement(chainHash: ByteVector32, shortChannelId: RealShortChannelId, localNodeId: PublicKey, remoteNodeId: PublicKey, localFundingKey: PublicKey, remoteFundingKey: PublicKey, localNodeSignature: ByteVector64, remoteNodeSignature: ByteVector64, localBitcoinSignature: ByteVector64, remoteBitcoinSignature: ByteVector64): ChannelAnnouncement = {
+ def makeChannelAnnouncement(chainHash: BlockHash, shortChannelId: RealShortChannelId, localNodeId: PublicKey, remoteNodeId: PublicKey, localFundingKey: PublicKey, remoteFundingKey: PublicKey, localNodeSignature: ByteVector64, remoteNodeSignature: ByteVector64, localBitcoinSignature: ByteVector64, remoteBitcoinSignature: ByteVector64): ChannelAnnouncement = {
val (nodeId1, nodeId2, bitcoinKey1, bitcoinKey2, nodeSignature1, nodeSignature2, bitcoinSignature1, bitcoinSignature2) =
if (isNode1(localNodeId, remoteNodeId)) {
(localNodeId, remoteNodeId, localFundingKey, remoteFundingKey, localNodeSignature, remoteNodeSignature, localBitcoinSignature, remoteBitcoinSignature)
@@ -118,7 +118,7 @@ object Announcements {
u1.htlcMinimumMsat == u2.htlcMinimumMsat &&
u1.htlcMaximumMsat == u2.htlcMaximumMsat
- def makeChannelUpdate(chainHash: ByteVector32, nodeSecret: PrivateKey, remoteNodeId: PublicKey, shortChannelId: ShortChannelId, cltvExpiryDelta: CltvExpiryDelta, htlcMinimumMsat: MilliSatoshi, feeBaseMsat: MilliSatoshi, feeProportionalMillionths: Long, htlcMaximumMsat: MilliSatoshi, isPrivate: Boolean = false, enable: Boolean = true, timestamp: TimestampSecond = TimestampSecond.now()): ChannelUpdate = {
+ def makeChannelUpdate(chainHash: BlockHash, nodeSecret: PrivateKey, remoteNodeId: PublicKey, shortChannelId: ShortChannelId, cltvExpiryDelta: CltvExpiryDelta, htlcMinimumMsat: MilliSatoshi, feeBaseMsat: MilliSatoshi, feeProportionalMillionths: Long, htlcMaximumMsat: MilliSatoshi, isPrivate: Boolean = false, enable: Boolean = true, timestamp: TimestampSecond = TimestampSecond.now()): ChannelUpdate = {
val messageFlags = ChannelUpdate.MessageFlags(isPrivate)
val channelFlags = ChannelUpdate.ChannelFlags(isNode1 = isNode1(nodeSecret.publicKey, remoteNodeId), isEnabled = enable)
val witness = channelUpdateWitnessEncode(chainHash, shortChannelId, timestamp, messageFlags, channelFlags, cltvExpiryDelta, htlcMinimumMsat, feeBaseMsat, feeProportionalMillionths, htlcMaximumMsat, TlvStream.empty)
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 304bb6285c..9077c3e39e 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
@@ -22,7 +22,7 @@ import akka.actor.{Actor, ActorLogging, ActorRef, Cancellable, Props, Terminated
import akka.event.DiagnosticLoggingAdapter
import akka.event.Logging.MDC
import fr.acinq.bitcoin.scalacompat.Crypto.PublicKey
-import fr.acinq.bitcoin.scalacompat.{ByteVector32, Satoshi}
+import fr.acinq.bitcoin.scalacompat.{BlockHash, ByteVector32, Satoshi, TxId}
import fr.acinq.eclair.Logs.LogCategory
import fr.acinq.eclair._
import fr.acinq.eclair.blockchain.bitcoind.ZmqWatcher
@@ -89,7 +89,7 @@ class Router(val nodeParams: NodeParams, watcher: typed.ActorRef[ZmqWatcher.Comm
// watch the funding tx of all these channels
// note: some of them may already have been spent, in that case we will receive the watch event immediately
(channels.values ++ pruned.values).foreach { pc =>
- val txid = pc.fundingTxid
+ val txid = pc.fundingTxId
val outputIndex = ShortChannelId.coordinates(pc.ann.shortChannelId).outputIndex
// avoid herd effect at startup because watch-spent are intensive in terms of rpc calls to bitcoind
context.system.scheduler.scheduleOnce(Random.nextLong(nodeParams.routerConf.watchSpentWindow.toSeconds).seconds) {
@@ -395,7 +395,7 @@ object Router {
def updateBalances(commitments: Commitments): KnownChannel
def applyChannelUpdate(update: Either[LocalChannelUpdate, RemoteChannelUpdate]): KnownChannel
}
- case class PublicChannel(ann: ChannelAnnouncement, fundingTxid: ByteVector32, capacity: Satoshi, update_1_opt: Option[ChannelUpdate], update_2_opt: Option[ChannelUpdate], meta_opt: Option[ChannelMeta]) extends KnownChannel {
+ case class PublicChannel(ann: ChannelAnnouncement, fundingTxId: TxId, capacity: Satoshi, update_1_opt: Option[ChannelUpdate], update_2_opt: Option[ChannelUpdate], meta_opt: Option[ChannelMeta]) extends KnownChannel {
update_1_opt.foreach(u => assert(u.channelFlags.isNode1))
update_2_opt.foreach(u => assert(!u.channelFlags.isNode1))
@@ -689,7 +689,7 @@ object Router {
// @formatter:on
// @formatter:off
- case class SendChannelQuery(chainHash: ByteVector32, remoteNodeId: PublicKey, to: ActorRef, replacePrevious: Boolean, flags_opt: Option[QueryChannelRangeTlv]) extends RemoteTypes
+ case class SendChannelQuery(chainHash: BlockHash, remoteNodeId: PublicKey, to: ActorRef, replacePrevious: Boolean, flags_opt: Option[QueryChannelRangeTlv]) extends RemoteTypes
case object GetRoutingState
case class RoutingState(channels: Iterable[PublicChannel], nodes: Iterable[NodeAnnouncement])
case object GetRoutingStateStreaming extends RemoteTypes
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/router/Sync.scala b/eclair-core/src/main/scala/fr/acinq/eclair/router/Sync.scala
index f10a627c42..51e88e6d64 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/router/Sync.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/router/Sync.scala
@@ -18,7 +18,7 @@ package fr.acinq.eclair.router
import akka.actor.{ActorContext, ActorRef}
import akka.event.LoggingAdapter
-import fr.acinq.bitcoin.scalacompat.ByteVector32
+import fr.acinq.bitcoin.scalacompat.BlockHash
import fr.acinq.bitcoin.scalacompat.Crypto.PublicKey
import fr.acinq.eclair.crypto.TransportHandler
import fr.acinq.eclair.router.Monitoring.{Metrics, Tags}
@@ -481,7 +481,7 @@ object Sync {
* @param channels channels map
* @return a ReplyChannelRange object
*/
- def buildReplyChannelRange(chunk: ShortChannelIdsChunk, syncComplete: Boolean, chainHash: ByteVector32, defaultEncoding: EncodingType, queryFlags_opt: Option[QueryChannelRangeTlv.QueryFlags], channels: SortedMap[RealShortChannelId, PublicChannel]): ReplyChannelRange = {
+ def buildReplyChannelRange(chunk: ShortChannelIdsChunk, syncComplete: Boolean, chainHash: BlockHash, defaultEncoding: EncodingType, queryFlags_opt: Option[QueryChannelRangeTlv.QueryFlags], channels: SortedMap[RealShortChannelId, PublicChannel]): ReplyChannelRange = {
val encoding = if (chunk.shortChannelIds.isEmpty) EncodingType.UNCOMPRESSED else defaultEncoding
val (timestamps, checksums) = queryFlags_opt match {
case Some(extension) if extension.wantChecksums | extension.wantTimestamps =>
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/router/Validation.scala b/eclair-core/src/main/scala/fr/acinq/eclair/router/Validation.scala
index 25feb8c0e6..8924edf7c3 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/router/Validation.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/router/Validation.scala
@@ -21,7 +21,7 @@ import akka.actor.{ActorContext, ActorRef, typed}
import akka.event.{DiagnosticLoggingAdapter, LoggingAdapter}
import fr.acinq.bitcoin.scalacompat.Crypto.PublicKey
import fr.acinq.bitcoin.scalacompat.Script.{pay2wsh, write}
-import fr.acinq.bitcoin.scalacompat.{ByteVector32, Satoshi}
+import fr.acinq.bitcoin.scalacompat.{Satoshi, TxId}
import fr.acinq.eclair.ShortChannelId.outputIndex
import fr.acinq.eclair.blockchain.bitcoind.ZmqWatcher
import fr.acinq.eclair.blockchain.bitcoind.ZmqWatcher.{UtxoStatus, ValidateRequest, ValidateResult, WatchExternalChannelSpent}
@@ -156,15 +156,15 @@ object Validation {
}
}
- private def addPublicChannel(d: Data, nodeParams: NodeParams, watcher: typed.ActorRef[ZmqWatcher.Command], ann: ChannelAnnouncement, fundingTxid: ByteVector32, capacity: Satoshi, privChan_opt: Option[PrivateChannel])(implicit ctx: ActorContext, log: DiagnosticLoggingAdapter): Data = {
+ private def addPublicChannel(d: Data, nodeParams: NodeParams, watcher: typed.ActorRef[ZmqWatcher.Command], ann: ChannelAnnouncement, fundingTxId: TxId, capacity: Satoshi, privChan_opt: Option[PrivateChannel])(implicit ctx: ActorContext, log: DiagnosticLoggingAdapter): Data = {
implicit val sender: ActorRef = ctx.self // necessary to preserve origin when sending messages to other actors
val fundingOutputIndex = outputIndex(ann.shortChannelId)
- watcher ! WatchExternalChannelSpent(ctx.self, fundingTxid, fundingOutputIndex, ann.shortChannelId)
+ watcher ! WatchExternalChannelSpent(ctx.self, fundingTxId, fundingOutputIndex, ann.shortChannelId)
ctx.system.eventStream.publish(ChannelsDiscovered(SingleChannelDiscovered(ann, capacity, None, None) :: Nil))
- nodeParams.db.network.addChannel(ann, fundingTxid, capacity)
+ nodeParams.db.network.addChannel(ann, fundingTxId, capacity)
val pubChan = PublicChannel(
ann = ann,
- fundingTxid = fundingTxid,
+ fundingTxId = fundingTxId,
capacity = capacity,
update_1_opt = privChan_opt.flatMap(_.update_1_opt),
update_2_opt = privChan_opt.flatMap(_.update_2_opt),
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/transactions/Scripts.scala b/eclair-core/src/main/scala/fr/acinq/eclair/transactions/Scripts.scala
index 30d1a537aa..8e256eb4dd 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/transactions/Scripts.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/transactions/Scripts.scala
@@ -108,11 +108,11 @@ object Scripts {
/**
* @return the number of confirmations of each parent before which the given transaction can be published.
*/
- def csvTimeouts(tx: Transaction): Map[ByteVector32, Long] = {
+ def csvTimeouts(tx: Transaction): Map[TxId, Long] = {
if (tx.version < 2) {
Map.empty
} else {
- tx.txIn.foldLeft(Map.empty[ByteVector32, Long]) { case (current, txIn) =>
+ tx.txIn.foldLeft(Map.empty[TxId, Long]) { case (current, txIn) =>
val csvTimeout = sequenceToBlockHeight(txIn.sequence)
if (csvTimeout > 0) {
val maxCsvTimeout = math.max(csvTimeout, current.getOrElse(txIn.outPoint.txid, 0L))
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version0/ChannelCodecs0.scala b/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version0/ChannelCodecs0.scala
index 628f8e2843..ddf1ededb5 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version0/ChannelCodecs0.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version0/ChannelCodecs0.scala
@@ -17,8 +17,8 @@
package fr.acinq.eclair.wire.internal.channel.version0
import com.softwaremill.quicklens.{ModifyPimp, QuicklensAt}
-import fr.acinq.bitcoin.scalacompat.DeterministicWallet.{ExtendedPrivateKey, KeyPath}
-import fr.acinq.bitcoin.scalacompat.{ByteVector32, ByteVector64, Crypto, OutPoint, Transaction, TxOut}
+import fr.acinq.bitcoin.scalacompat.DeterministicWallet.KeyPath
+import fr.acinq.bitcoin.scalacompat.{ByteVector32, ByteVector64, Crypto, OutPoint, Transaction, TxId, TxOut}
import fr.acinq.eclair.blockchain.fee.ConfirmationTarget
import fr.acinq.eclair.channel.LocalFundingStatus.SingleFundedUnconfirmedFundingTx
import fr.acinq.eclair.channel._
@@ -172,7 +172,7 @@ private[channel] object ChannelCodecs0 {
val remoteCommitCodec: Codec[RemoteCommit] = (
("index" | uint64overflow) ::
("spec" | commitmentSpecCodec) ::
- ("txid" | bytes32) ::
+ ("txid" | txId) ::
("remotePerCommitmentPoint" | publicKey)).as[RemoteCommit].decodeOnly
val updateFulfillHtlcCodec: Codec[UpdateFulfillHtlc] = (
@@ -260,10 +260,10 @@ private[channel] object ChannelCodecs0 {
(wire: BitVector) => originsListCodec.decode(wire).map(_.map(_.toMap))
)
- val spentListCodec: Codec[List[(OutPoint, ByteVector32)]] = listOfN(uint16, outPointCodec ~ bytes32)
+ val spentListCodec: Codec[List[(OutPoint, TxId)]] = listOfN(uint16, outPointCodec ~ txId)
- val spentMapCodec: Codec[Map[OutPoint, ByteVector32]] = Codec[Map[OutPoint, ByteVector32]](
- (map: Map[OutPoint, ByteVector32]) => spentListCodec.encode(map.toList),
+ val spentMapCodec: Codec[Map[OutPoint, TxId]] = Codec[Map[OutPoint, TxId]](
+ (map: Map[OutPoint, TxId]) => spentListCodec.encode(map.toList),
(wire: BitVector) => spentListCodec.decode(wire).map(_.map(_.toMap))
)
@@ -335,7 +335,7 @@ private[channel] object ChannelCodecs0 {
val fundingCreatedCodec: Codec[FundingCreated] = (
("temporaryChannelId" | bytes32) ::
- ("fundingTxid" | bytes32) ::
+ ("fundingTxHash" | txIdAsHash) ::
("fundingOutputIndex" | uint16) ::
("signature" | bytes64) ::
("tlvStream" | provide(TlvStream.empty[FundingCreatedTlv]))).as[FundingCreated]
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version0/ChannelTypes0.scala b/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version0/ChannelTypes0.scala
index 6a87cad47c..4d3d4bab63 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version0/ChannelTypes0.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version0/ChannelTypes0.scala
@@ -18,7 +18,7 @@ package fr.acinq.eclair.wire.internal.channel.version0
import com.softwaremill.quicklens._
import fr.acinq.bitcoin.scalacompat.Crypto.PublicKey
-import fr.acinq.bitcoin.scalacompat.{ByteVector32, ByteVector64, Crypto, OP_CHECKMULTISIG, OP_PUSHDATA, OutPoint, Satoshi, Script, ScriptWitness, Transaction, TxOut}
+import fr.acinq.bitcoin.scalacompat.{ByteVector32, ByteVector64, Crypto, OP_CHECKMULTISIG, OP_PUSHDATA, OutPoint, Satoshi, Script, ScriptWitness, Transaction, TxId, TxOut}
import fr.acinq.eclair.blockchain.fee.ConfirmationTarget
import fr.acinq.eclair.channel._
import fr.acinq.eclair.crypto.ShaChain
@@ -51,10 +51,10 @@ private[channel] object ChannelTypes0 {
InputInfo(input, parentTx.txOut(input.index.toInt), Nil)
}
- case class LocalCommitPublished(commitTx: Transaction, claimMainDelayedOutputTx: Option[Transaction], htlcSuccessTxs: List[Transaction], htlcTimeoutTxs: List[Transaction], claimHtlcDelayedTxs: List[Transaction], irrevocablySpent: Map[OutPoint, ByteVector32]) {
+ case class LocalCommitPublished(commitTx: Transaction, claimMainDelayedOutputTx: Option[Transaction], htlcSuccessTxs: List[Transaction], htlcTimeoutTxs: List[Transaction], claimHtlcDelayedTxs: List[Transaction], irrevocablySpent: Map[OutPoint, TxId]) {
def migrate(): channel.LocalCommitPublished = {
val htlcTxs = htlcSuccessTxs ++ htlcTimeoutTxs
- val knownTxs: Map[ByteVector32, Transaction] = (commitTx :: claimMainDelayedOutputTx.toList ::: htlcTxs ::: claimHtlcDelayedTxs).map(tx => tx.txid -> tx).toMap
+ val knownTxs: Map[TxId, Transaction] = (commitTx :: claimMainDelayedOutputTx.toList ::: htlcTxs ::: claimHtlcDelayedTxs).map(tx => tx.txid -> tx).toMap
// NB: irrevocablySpent may contain transactions that belong to our peer: we will drop them in this migration but
// the channel will put a watch at start-up which will make us fetch the spending transaction.
val irrevocablySpentNew = irrevocablySpent.collect { case (outpoint, txid) if knownTxs.contains(txid) => (outpoint, knownTxs(txid)) }
@@ -71,10 +71,10 @@ private[channel] object ChannelTypes0 {
}
}
- case class RemoteCommitPublished(commitTx: Transaction, claimMainOutputTx: Option[Transaction], claimHtlcSuccessTxs: List[Transaction], claimHtlcTimeoutTxs: List[Transaction], irrevocablySpent: Map[OutPoint, ByteVector32]) {
+ case class RemoteCommitPublished(commitTx: Transaction, claimMainOutputTx: Option[Transaction], claimHtlcSuccessTxs: List[Transaction], claimHtlcTimeoutTxs: List[Transaction], irrevocablySpent: Map[OutPoint, TxId]) {
def migrate(): channel.RemoteCommitPublished = {
val claimHtlcTxs = claimHtlcSuccessTxs ::: claimHtlcTimeoutTxs
- val knownTxs: Map[ByteVector32, Transaction] = (commitTx :: claimMainOutputTx.toList ::: claimHtlcTxs).map(tx => tx.txid -> tx).toMap
+ val knownTxs: Map[TxId, Transaction] = (commitTx :: claimMainOutputTx.toList ::: claimHtlcTxs).map(tx => tx.txid -> tx).toMap
// NB: irrevocablySpent may contain transactions that belong to our peer: we will drop them in this migration but
// the channel will put a watch at start-up which will make us fetch the spending transaction.
val irrevocablySpentNew = irrevocablySpent.collect { case (outpoint, txid) if knownTxs.contains(txid) => (outpoint, knownTxs(txid)) }
@@ -86,9 +86,9 @@ private[channel] object ChannelTypes0 {
}
}
- case class RevokedCommitPublished(commitTx: Transaction, claimMainOutputTx: Option[Transaction], mainPenaltyTx: Option[Transaction], htlcPenaltyTxs: List[Transaction], claimHtlcDelayedPenaltyTxs: List[Transaction], irrevocablySpent: Map[OutPoint, ByteVector32]) {
+ case class RevokedCommitPublished(commitTx: Transaction, claimMainOutputTx: Option[Transaction], mainPenaltyTx: Option[Transaction], htlcPenaltyTxs: List[Transaction], claimHtlcDelayedPenaltyTxs: List[Transaction], irrevocablySpent: Map[OutPoint, TxId]) {
def migrate(): channel.RevokedCommitPublished = {
- val knownTxs: Map[ByteVector32, Transaction] = (commitTx :: claimMainOutputTx.toList ::: mainPenaltyTx.toList ::: htlcPenaltyTxs ::: claimHtlcDelayedPenaltyTxs).map(tx => tx.txid -> tx).toMap
+ val knownTxs: Map[TxId, Transaction] = (commitTx :: claimMainOutputTx.toList ::: mainPenaltyTx.toList ::: htlcPenaltyTxs ::: claimHtlcDelayedPenaltyTxs).map(tx => tx.txid -> tx).toMap
// NB: irrevocablySpent may contain transactions that belong to our peer: we will drop them in this migration but
// the channel will put a watch at start-up which will make us fetch the spending transaction.
val irrevocablySpentNew = irrevocablySpent.collect { case (outpoint, txid) if knownTxs.contains(txid) => (outpoint, knownTxs(txid)) }
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version1/ChannelCodecs1.scala b/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version1/ChannelCodecs1.scala
index d765c9b082..9525aa4d7e 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version1/ChannelCodecs1.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version1/ChannelCodecs1.scala
@@ -17,8 +17,8 @@
package fr.acinq.eclair.wire.internal.channel.version1
import com.softwaremill.quicklens.{ModifyPimp, QuicklensAt}
-import fr.acinq.bitcoin.scalacompat.DeterministicWallet.{ExtendedPrivateKey, KeyPath}
-import fr.acinq.bitcoin.scalacompat.{ByteVector32, OutPoint, Transaction, TxOut}
+import fr.acinq.bitcoin.scalacompat.DeterministicWallet.KeyPath
+import fr.acinq.bitcoin.scalacompat.{OutPoint, Transaction, TxId, TxOut}
import fr.acinq.eclair.blockchain.fee.ConfirmationTarget
import fr.acinq.eclair.channel.LocalFundingStatus.SingleFundedUnconfirmedFundingTx
import fr.acinq.eclair.channel._
@@ -135,7 +135,7 @@ private[channel] object ChannelCodecs1 {
val remoteCommitCodec: Codec[RemoteCommit] = (
("index" | uint64overflow) ::
("spec" | commitmentSpecCodec) ::
- ("txid" | bytes32) ::
+ ("txid" | txId) ::
("remotePerCommitmentPoint" | publicKey)).as[RemoteCommit]
val updateMessageCodec: Codec[UpdateMessage] = lengthDelimited(lightningMessageCodec.narrow[UpdateMessage](f => Attempt.successful(f.asInstanceOf[UpdateMessage]), g => g))
@@ -181,7 +181,7 @@ private[channel] object ChannelCodecs1 {
val originsMapCodec: Codec[Map[Long, Origin]] = mapCodec(int64, originCodec)
- val spentMapCodec: Codec[Map[OutPoint, ByteVector32]] = mapCodec(outPointCodec, bytes32)
+ val spentMapCodec: Codec[Map[OutPoint, TxId]] = mapCodec(outPointCodec, txId)
val commitmentsCodec: Codec[Commitments] = (
("channelVersion" | channelVersionCodec) >>:~ { channelVersion =>
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version2/ChannelCodecs2.scala b/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version2/ChannelCodecs2.scala
index ccfb9b757f..f26c0adf76 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version2/ChannelCodecs2.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version2/ChannelCodecs2.scala
@@ -162,7 +162,7 @@ private[channel] object ChannelCodecs2 {
val remoteCommitCodec: Codec[RemoteCommit] = (
("index" | uint64overflow) ::
("spec" | commitmentSpecCodec) ::
- ("txid" | bytes32) ::
+ ("txid" | txId) ::
("remotePerCommitmentPoint" | publicKey)).as[RemoteCommit]
val updateMessageCodec: Codec[UpdateMessage] = lengthDelimited(lightningMessageCodec.narrow[UpdateMessage](f => Attempt.successful(f.asInstanceOf[UpdateMessage]), g => g))
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version3/ChannelCodecs3.scala b/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version3/ChannelCodecs3.scala
index caaef720c3..f9f2309839 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version3/ChannelCodecs3.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version3/ChannelCodecs3.scala
@@ -214,7 +214,7 @@ private[channel] object ChannelCodecs3 {
val remoteCommitCodec: Codec[RemoteCommit] = (
("index" | uint64overflow) ::
("spec" | commitmentSpecCodec) ::
- ("txid" | bytes32) ::
+ ("txid" | txId) ::
("remotePerCommitmentPoint" | publicKey)).as[RemoteCommit]
val updateMessageCodec: Codec[UpdateMessage] = lengthDelimited(lightningMessageCodec.narrow[UpdateMessage](f => Attempt.successful(f.asInstanceOf[UpdateMessage]), g => g))
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version4/ChannelCodecs4.scala b/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version4/ChannelCodecs4.scala
index fd301d0208..f742dd9388 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version4/ChannelCodecs4.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version4/ChannelCodecs4.scala
@@ -395,7 +395,7 @@ private[channel] object ChannelCodecs4 {
private def remoteCommitCodec(commitmentSpecCodec: Codec[CommitmentSpec]): Codec[RemoteCommit] = (
("index" | uint64overflow) ::
("spec" | commitmentSpecCodec) ::
- ("txid" | bytes32) ::
+ ("txid" | txId) ::
("remotePerCommitmentPoint" | publicKey)).as[RemoteCommit]
private def nextRemoteCommitCodec(commitmentSpecCodec: Codec[CommitmentSpec]): Codec[NextRemoteCommit] = (
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/wire/protocol/ChannelTlv.scala b/eclair-core/src/main/scala/fr/acinq/eclair/wire/protocol/ChannelTlv.scala
index c3299374fa..a0cbfc3773 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/wire/protocol/ChannelTlv.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/wire/protocol/ChannelTlv.scala
@@ -16,7 +16,7 @@
package fr.acinq.eclair.wire.protocol
-import fr.acinq.bitcoin.scalacompat.{ByteVector32, Satoshi}
+import fr.acinq.bitcoin.scalacompat.{Satoshi, TxId}
import fr.acinq.eclair.channel.{ChannelType, ChannelTypes}
import fr.acinq.eclair.wire.protocol.CommonCodecs._
import fr.acinq.eclair.wire.protocol.TlvCodecs.{tlvField, tlvStream, tmillisatoshi}
@@ -165,10 +165,10 @@ sealed trait ChannelReestablishTlv extends Tlv
object ChannelReestablishTlv {
- case class NextFundingTlv(txHash: ByteVector32) extends ChannelReestablishTlv
+ case class NextFundingTlv(txId: TxId) extends ChannelReestablishTlv
object NextFundingTlv {
- val codec: Codec[NextFundingTlv] = tlvField("funding_tx_hash" | bytes32)
+ val codec: Codec[NextFundingTlv] = tlvField(txIdAsHash)
}
val channelReestablishTlvCodec: Codec[TlvStream[ChannelReestablishTlv]] = tlvStream(discriminated[ChannelReestablishTlv].by(varint)
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/wire/protocol/CommonCodecs.scala b/eclair-core/src/main/scala/fr/acinq/eclair/wire/protocol/CommonCodecs.scala
index d96d8c4131..e86e8da2bc 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/wire/protocol/CommonCodecs.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/wire/protocol/CommonCodecs.scala
@@ -17,7 +17,7 @@
package fr.acinq.eclair.wire.protocol
import fr.acinq.bitcoin.scalacompat.Crypto.{PrivateKey, PublicKey}
-import fr.acinq.bitcoin.scalacompat.{ByteVector32, ByteVector64, Satoshi, Transaction}
+import fr.acinq.bitcoin.scalacompat.{BlockHash, ByteVector32, ByteVector64, Satoshi, Transaction, TxHash, TxId}
import fr.acinq.eclair.blockchain.fee.FeeratePerKw
import fr.acinq.eclair.channel.{ChannelFlags, RealScidStatus, ShortIds}
import fr.acinq.eclair.crypto.Mac32
@@ -107,6 +107,13 @@ object CommonCodecs {
val sha256: Codec[ByteVector32] = bytes32
+ val blockHash: Codec[BlockHash] = bytes32.as[BlockHash]
+
+ val txId: Codec[TxId] = bytes32.as[TxId]
+
+ /** In lightning messages, transaction IDs are usually encoded as a tx_hash, which reverses the endianness. */
+ val txIdAsHash: Codec[TxId] = bytes32.xmap(b => TxId(TxHash(b)), txId => TxHash(txId).value)
+
val varsizebinarydata: Codec[ByteVector] = variableSizeBytes(uint16, bytes)
val listofsignatures: Codec[List[ByteVector64]] = listOfN(uint16, bytes64)
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/wire/protocol/InteractiveTxTlv.scala b/eclair-core/src/main/scala/fr/acinq/eclair/wire/protocol/InteractiveTxTlv.scala
index 37be256afd..d0c8352509 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/wire/protocol/InteractiveTxTlv.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/wire/protocol/InteractiveTxTlv.scala
@@ -16,9 +16,9 @@
package fr.acinq.eclair.wire.protocol
-import fr.acinq.bitcoin.scalacompat.{ByteVector32, ByteVector64, Satoshi}
+import fr.acinq.bitcoin.scalacompat.{ByteVector64, Satoshi, TxId}
import fr.acinq.eclair.UInt64
-import fr.acinq.eclair.wire.protocol.CommonCodecs.{bytes32, bytes64, satoshiSigned, varint}
+import fr.acinq.eclair.wire.protocol.CommonCodecs.{bytes64, satoshiSigned, txIdAsHash, varint}
import fr.acinq.eclair.wire.protocol.TlvCodecs.{tlvField, tlvStream}
import scodec.Codec
import scodec.codecs.discriminated
@@ -31,11 +31,11 @@ sealed trait TxAddInputTlv extends Tlv
object TxAddInputTlv {
/** When doing a splice, the initiator must provide the previous funding txId instead of the whole transaction. */
- case class SharedInputTxId(txid: ByteVector32) extends TxAddInputTlv
+ case class SharedInputTxId(txId: TxId) extends TxAddInputTlv
val txAddInputTlvCodec: Codec[TlvStream[TxAddInputTlv]] = tlvStream(discriminated[TxAddInputTlv].by(varint)
// Note that we actually encode as a tx_hash to be consistent with other lightning messages.
- .typecase(UInt64(1105), tlvField(bytes32.xmap(txId => txId.reverse, (txHash: ByteVector32) => txHash.reverse).as[SharedInputTxId]))
+ .typecase(UInt64(1105), tlvField(txIdAsHash.as[SharedInputTxId]))
)
}
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/wire/protocol/LightningMessageCodecs.scala b/eclair-core/src/main/scala/fr/acinq/eclair/wire/protocol/LightningMessageCodecs.scala
index 35f9269fcc..f7790558a0 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/wire/protocol/LightningMessageCodecs.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/wire/protocol/LightningMessageCodecs.scala
@@ -69,7 +69,7 @@ object LightningMessageCodecs {
("tlvStream" | ChannelReestablishTlv.channelReestablishTlvCodec)).as[ChannelReestablish]
val openChannelCodec: Codec[OpenChannel] = (
- ("chainHash" | bytes32) ::
+ ("chainHash" | blockHash) ::
("temporaryChannelId" | bytes32) ::
("fundingSatoshis" | satoshi) ::
("pushMsat" | millisatoshi) ::
@@ -90,7 +90,7 @@ object LightningMessageCodecs {
("tlvStream" | OpenChannelTlv.openTlvCodec)).as[OpenChannel]
val openDualFundedChannelCodec: Codec[OpenDualFundedChannel] = (
- ("chainHash" | bytes32) ::
+ ("chainHash" | blockHash) ::
("temporaryChannelId" | bytes32) ::
("fundingFeerate" | feeratePerKw) ::
("commitmentFeerate" | feeratePerKw) ::
@@ -148,7 +148,7 @@ object LightningMessageCodecs {
val fundingCreatedCodec: Codec[FundingCreated] = (
("temporaryChannelId" | bytes32) ::
- ("fundingTxid" | bytes32) ::
+ ("fundingTxHash" | txIdAsHash) ::
("fundingOutputIndex" | uint16) ::
("signature" | bytes64) ::
("tlvStream" | FundingCreatedTlv.fundingCreatedTlvCodec)).as[FundingCreated]
@@ -197,7 +197,7 @@ object LightningMessageCodecs {
val txSignaturesCodec: Codec[TxSignatures] = (
("channelId" | bytes32) ::
- ("txHash" | sha256) ::
+ ("txHash" | txIdAsHash) ::
("witnesses" | witnessesCodec) ::
("tlvStream" | TxSignaturesTlv.txSignaturesTlvCodec)).as[TxSignatures]
@@ -281,7 +281,7 @@ object LightningMessageCodecs {
val channelAnnouncementWitnessCodec =
("features" | lengthPrefixedFeaturesCodec) ::
- ("chainHash" | bytes32) ::
+ ("chainHash" | blockHash) ::
("shortChannelId" | realshortchannelid) ::
("nodeId1" | publicKey) ::
("nodeId2" | publicKey) ::
@@ -317,7 +317,7 @@ object LightningMessageCodecs {
val channelFlagsCodec = ("channelFlags" | (ignore(6) :: reverseBool :: reverseBool)).as[ChannelUpdate.ChannelFlags]
val channelUpdateChecksumCodec =
- ("chainHash" | bytes32) ::
+ ("chainHash" | blockHash) ::
("shortChannelId" | shortchannelid) ::
messageFlagsCodec ::
channelFlagsCodec ::
@@ -328,7 +328,7 @@ object LightningMessageCodecs {
("htlcMaximumMsat" | millisatoshi)
val channelUpdateWitnessCodec =
- ("chainHash" | bytes32) ::
+ ("chainHash" | blockHash) ::
("shortChannelId" | shortchannelid) ::
("timestamp" | timestampSecond) ::
messageFlagsCodec ::
@@ -355,23 +355,23 @@ object LightningMessageCodecs {
}((provide[EncodingType](EncodingType.COMPRESSED_ZLIB) :: zlib(list(realshortchannelid))).as[EncodedShortChannelIds])
val queryShortChannelIdsCodec: Codec[QueryShortChannelIds] = (
- ("chainHash" | bytes32) ::
+ ("chainHash" | blockHash) ::
("shortChannelIds" | variableSizeBytes(uint16, encodedShortChannelIdsCodec)) ::
("tlvStream" | QueryShortChannelIdsTlv.codec)).as[QueryShortChannelIds]
val replyShortChannelIdsEndCodec: Codec[ReplyShortChannelIdsEnd] = (
- ("chainHash" | bytes32) ::
+ ("chainHash" | blockHash) ::
("complete" | byte) ::
("tlvStream" | ReplyShortChannelIdsEndTlv.replyShortChannelIdsEndTlvCodec)).as[ReplyShortChannelIdsEnd]
val queryChannelRangeCodec: Codec[QueryChannelRange] = (
- ("chainHash" | bytes32) ::
+ ("chainHash" | blockHash) ::
("firstBlock" | blockHeight) ::
("numberOfBlocks" | uint32) ::
("tlvStream" | QueryChannelRangeTlv.codec)).as[QueryChannelRange]
val replyChannelRangeCodec: Codec[ReplyChannelRange] = (
- ("chainHash" | bytes32) ::
+ ("chainHash" | blockHash) ::
("firstBlock" | blockHeight) ::
("numberOfBlocks" | uint32) ::
("complete" | byte) ::
@@ -379,7 +379,7 @@ object LightningMessageCodecs {
("tlvStream" | ReplyChannelRangeTlv.codec)).as[ReplyChannelRange]
val gossipTimestampFilterCodec: Codec[GossipTimestampFilter] = (
- ("chainHash" | bytes32) ::
+ ("chainHash" | blockHash) ::
("firstTimestamp" | timestampSecond) ::
("timestampRange" | uint32) ::
("tlvStream" | GossipTimestampFilterTlv.gossipTimestampFilterTlvCodec)).as[GossipTimestampFilter]
@@ -418,7 +418,7 @@ object LightningMessageCodecs {
val spliceLockedCodec: Codec[SpliceLocked] = (
("channelId" | bytes32) ::
- ("fundingTxid" | bytes32) ::
+ ("fundingTxHash" | txIdAsHash) ::
("tlvStream" | SpliceLockedTlv.spliceLockedTlvCodec)).as[SpliceLocked]
val stfuCodec: Codec[Stfu] = (
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/wire/protocol/LightningMessageTypes.scala b/eclair-core/src/main/scala/fr/acinq/eclair/wire/protocol/LightningMessageTypes.scala
index 6f6f932ba7..cc1cabbf78 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/wire/protocol/LightningMessageTypes.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/wire/protocol/LightningMessageTypes.scala
@@ -19,7 +19,7 @@ package fr.acinq.eclair.wire.protocol
import com.google.common.base.Charsets
import com.google.common.net.InetAddresses
import fr.acinq.bitcoin.scalacompat.Crypto.{PrivateKey, PublicKey}
-import fr.acinq.bitcoin.scalacompat.{ByteVector32, ByteVector64, OutPoint, Satoshi, SatoshiLong, ScriptWitness, Transaction}
+import fr.acinq.bitcoin.scalacompat.{BlockHash, ByteVector32, ByteVector64, OutPoint, Satoshi, SatoshiLong, ScriptWitness, Transaction, TxId}
import fr.acinq.eclair.blockchain.fee.FeeratePerKw
import fr.acinq.eclair.channel.{ChannelFlags, ChannelType}
import fr.acinq.eclair.payment.relay.Relayer
@@ -47,7 +47,7 @@ sealed trait AnnouncementMessage extends RoutingMessage // <- not in the spec
sealed trait HasTimestamp extends LightningMessage { def timestamp: TimestampSecond }
sealed trait HasTemporaryChannelId extends LightningMessage { def temporaryChannelId: ByteVector32 } // <- not in the spec
sealed trait HasChannelId extends LightningMessage { def channelId: ByteVector32 } // <- not in the spec
-sealed trait HasChainHash extends LightningMessage { def chainHash: ByteVector32 } // <- not in the spec
+sealed trait HasChainHash extends LightningMessage { def chainHash: BlockHash } // <- not in the spec
sealed trait HasSerialId extends LightningMessage { def serialId: UInt64 } // <- not in the spec
sealed trait ForbiddenMessageDuringSplice extends LightningMessage // <- not in the spec
sealed trait UpdateMessage extends HtlcMessage with ForbiddenMessageDuringSplice // <- not in the spec
@@ -89,7 +89,7 @@ case class TxAddInput(channelId: ByteVector32,
previousTxOutput: Long,
sequence: Long,
tlvStream: TlvStream[TxAddInputTlv] = TlvStream.empty) extends InteractiveTxConstructionMessage with HasChannelId with HasSerialId {
- val sharedInput_opt: Option[OutPoint] = tlvStream.get[TxAddInputTlv.SharedInputTxId].map(i => OutPoint(i.txid.reverse, previousTxOutput))
+ val sharedInput_opt: Option[OutPoint] = tlvStream.get[TxAddInputTlv.SharedInputTxId].map(i => OutPoint(i.txId, previousTxOutput))
}
object TxAddInput {
@@ -116,16 +116,15 @@ case class TxComplete(channelId: ByteVector32,
tlvStream: TlvStream[TxCompleteTlv] = TlvStream.empty) extends InteractiveTxConstructionMessage with HasChannelId
case class TxSignatures(channelId: ByteVector32,
- txHash: ByteVector32,
+ txId: TxId,
witnesses: Seq[ScriptWitness],
tlvStream: TlvStream[TxSignaturesTlv] = TlvStream.empty) extends InteractiveTxMessage with HasChannelId {
- val txId: ByteVector32 = txHash.reverse
val previousFundingTxSig_opt: Option[ByteVector64] = tlvStream.get[TxSignaturesTlv.PreviousFundingTxSig].map(_.sig)
}
object TxSignatures {
def apply(channelId: ByteVector32, tx: Transaction, witnesses: Seq[ScriptWitness], previousFundingSig_opt: Option[ByteVector64]): TxSignatures = {
- TxSignatures(channelId, tx.hash, witnesses, TlvStream(previousFundingSig_opt.map(TxSignaturesTlv.PreviousFundingTxSig).toSet[TxSignaturesTlv]))
+ TxSignatures(channelId, tx.txid, witnesses, TlvStream(previousFundingSig_opt.map(TxSignaturesTlv.PreviousFundingTxSig).toSet[TxSignaturesTlv]))
}
}
@@ -167,10 +166,10 @@ case class ChannelReestablish(channelId: ByteVector32,
yourLastPerCommitmentSecret: PrivateKey,
myCurrentPerCommitmentPoint: PublicKey,
tlvStream: TlvStream[ChannelReestablishTlv] = TlvStream.empty) extends ChannelMessage with HasChannelId {
- val nextFundingTxId_opt: Option[ByteVector32] = tlvStream.get[ChannelReestablishTlv.NextFundingTlv].map(_.txHash.reverse)
+ val nextFundingTxId_opt: Option[TxId] = tlvStream.get[ChannelReestablishTlv.NextFundingTlv].map(_.txId)
}
-case class OpenChannel(chainHash: ByteVector32,
+case class OpenChannel(chainHash: BlockHash,
temporaryChannelId: ByteVector32,
fundingSatoshis: Satoshi,
pushMsat: MilliSatoshi,
@@ -213,7 +212,7 @@ case class AcceptChannel(temporaryChannelId: ByteVector32,
}
// NB: this message is named open_channel2 in the specification.
-case class OpenDualFundedChannel(chainHash: ByteVector32,
+case class OpenDualFundedChannel(chainHash: BlockHash,
temporaryChannelId: ByteVector32,
fundingFeerate: FeeratePerKw,
commitmentFeerate: FeeratePerKw,
@@ -263,7 +262,7 @@ case class AcceptDualFundedChannel(temporaryChannelId: ByteVector32,
}
case class FundingCreated(temporaryChannelId: ByteVector32,
- fundingTxHash: ByteVector32,
+ fundingTxId: TxId,
fundingOutputIndex: Int,
signature: ByteVector64,
tlvStream: TlvStream[FundingCreatedTlv] = TlvStream.empty) extends ChannelMessage with HasTemporaryChannelId
@@ -319,9 +318,8 @@ object SpliceAck {
}
case class SpliceLocked(channelId: ByteVector32,
- fundingTxHash: ByteVector32,
+ fundingTxId: TxId,
tlvStream: TlvStream[SpliceLockedTlv] = TlvStream.empty) extends ChannelMessage with HasChannelId {
- val fundingTxid: ByteVector32 = fundingTxHash.reverse
}
case class Shutdown(channelId: ByteVector32,
@@ -401,7 +399,7 @@ case class ChannelAnnouncement(nodeSignature1: ByteVector64,
bitcoinSignature1: ByteVector64,
bitcoinSignature2: ByteVector64,
features: Features[Feature],
- chainHash: ByteVector32,
+ chainHash: BlockHash,
shortChannelId: RealShortChannelId,
nodeId1: PublicKey,
nodeId2: PublicKey,
@@ -489,7 +487,7 @@ case class NodeAnnouncement(signature: ByteVector64,
}
case class ChannelUpdate(signature: ByteVector64,
- chainHash: ByteVector32,
+ chainHash: BlockHash,
shortChannelId: ShortChannelId,
timestamp: TimestampSecond,
messageFlags: ChannelUpdate.MessageFlags,
@@ -531,23 +529,23 @@ case class EncodedShortChannelIds(encoding: EncodingType, array: List[RealShortC
override def toString: String = s"EncodedShortChannelIds($encoding,${array.headOption.getOrElse("")}->${array.lastOption.getOrElse("")} size=${array.size})"
}
-case class QueryShortChannelIds(chainHash: ByteVector32, shortChannelIds: EncodedShortChannelIds, tlvStream: TlvStream[QueryShortChannelIdsTlv] = TlvStream.empty) extends RoutingMessage with HasChainHash {
+case class QueryShortChannelIds(chainHash: BlockHash, shortChannelIds: EncodedShortChannelIds, tlvStream: TlvStream[QueryShortChannelIdsTlv] = TlvStream.empty) extends RoutingMessage with HasChainHash {
val queryFlags_opt: Option[QueryShortChannelIdsTlv.EncodedQueryFlags] = tlvStream.get[QueryShortChannelIdsTlv.EncodedQueryFlags]
}
-case class ReplyShortChannelIdsEnd(chainHash: ByteVector32, complete: Byte, tlvStream: TlvStream[ReplyShortChannelIdsEndTlv] = TlvStream.empty) extends RoutingMessage with HasChainHash
+case class ReplyShortChannelIdsEnd(chainHash: BlockHash, complete: Byte, tlvStream: TlvStream[ReplyShortChannelIdsEndTlv] = TlvStream.empty) extends RoutingMessage with HasChainHash
-case class QueryChannelRange(chainHash: ByteVector32, firstBlock: BlockHeight, numberOfBlocks: Long, tlvStream: TlvStream[QueryChannelRangeTlv] = TlvStream.empty) extends RoutingMessage {
+case class QueryChannelRange(chainHash: BlockHash, firstBlock: BlockHeight, numberOfBlocks: Long, tlvStream: TlvStream[QueryChannelRangeTlv] = TlvStream.empty) extends RoutingMessage with HasChainHash {
val queryFlags_opt: Option[QueryChannelRangeTlv.QueryFlags] = tlvStream.get[QueryChannelRangeTlv.QueryFlags]
}
-case class ReplyChannelRange(chainHash: ByteVector32, firstBlock: BlockHeight, numberOfBlocks: Long, syncComplete: Byte, shortChannelIds: EncodedShortChannelIds, tlvStream: TlvStream[ReplyChannelRangeTlv] = TlvStream.empty) extends RoutingMessage {
+case class ReplyChannelRange(chainHash: BlockHash, firstBlock: BlockHeight, numberOfBlocks: Long, syncComplete: Byte, shortChannelIds: EncodedShortChannelIds, tlvStream: TlvStream[ReplyChannelRangeTlv] = TlvStream.empty) extends RoutingMessage with HasChainHash {
val timestamps_opt: Option[ReplyChannelRangeTlv.EncodedTimestamps] = tlvStream.get[ReplyChannelRangeTlv.EncodedTimestamps]
val checksums_opt: Option[ReplyChannelRangeTlv.EncodedChecksums] = tlvStream.get[ReplyChannelRangeTlv.EncodedChecksums]
}
object ReplyChannelRange {
- def apply(chainHash: ByteVector32,
+ def apply(chainHash: BlockHash,
firstBlock: BlockHeight,
numberOfBlocks: Long,
syncComplete: Byte,
@@ -560,7 +558,7 @@ object ReplyChannelRange {
}
}
-case class GossipTimestampFilter(chainHash: ByteVector32, firstTimestamp: TimestampSecond, timestampRange: Long, tlvStream: TlvStream[GossipTimestampFilterTlv] = TlvStream.empty) extends RoutingMessage with HasChainHash
+case class GossipTimestampFilter(chainHash: BlockHash, firstTimestamp: TimestampSecond, timestampRange: Long, tlvStream: TlvStream[GossipTimestampFilterTlv] = TlvStream.empty) extends RoutingMessage with HasChainHash
case class OnionMessage(blindingKey: PublicKey, onionRoutingPacket: OnionRoutingPacket, tlvStream: TlvStream[OnionMessageTlv] = TlvStream.empty) extends LightningMessage
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/wire/protocol/OfferCodecs.scala b/eclair-core/src/main/scala/fr/acinq/eclair/wire/protocol/OfferCodecs.scala
index 913036f8ac..f8d8a6abae 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/wire/protocol/OfferCodecs.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/wire/protocol/OfferCodecs.scala
@@ -16,7 +16,7 @@
package fr.acinq.eclair.wire.protocol
-import fr.acinq.bitcoin.scalacompat.ByteVector32
+import fr.acinq.bitcoin.scalacompat.BlockHash
import fr.acinq.eclair.crypto.Sphinx.RouteBlinding.{BlindedNode, BlindedRoute}
import fr.acinq.eclair.wire.protocol.CommonCodecs._
import fr.acinq.eclair.wire.protocol.OfferTypes.{InvoiceRequestChain, InvoiceRequestPayerNote, InvoiceRequestQuantity, _}
@@ -26,7 +26,7 @@ import scodec.{Attempt, Codec, Err}
import scodec.codecs._
object OfferCodecs {
- private val offerChains: Codec[OfferChains] = tlvField(list(bytes32).xmap[Seq[ByteVector32]](_.toSeq, _.toList))
+ private val offerChains: Codec[OfferChains] = tlvField(list(blockHash).xmap[Seq[BlockHash]](_.toSeq, _.toList))
private val offerMetadata: Codec[OfferMetadata] = tlvField(bytes)
@@ -91,7 +91,7 @@ object OfferCodecs {
private val invoiceRequestMetadata: Codec[InvoiceRequestMetadata] = tlvField(bytes)
- private val invoiceRequestChain: Codec[InvoiceRequestChain] = tlvField(bytes32)
+ private val invoiceRequestChain: Codec[InvoiceRequestChain] = tlvField(blockHash)
private val invoiceRequestAmount: Codec[InvoiceRequestAmount] = tlvField(tmillisatoshi)
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/wire/protocol/OfferTypes.scala b/eclair-core/src/main/scala/fr/acinq/eclair/wire/protocol/OfferTypes.scala
index 6d49408b96..3d7fa51479 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/wire/protocol/OfferTypes.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/wire/protocol/OfferTypes.scala
@@ -18,12 +18,12 @@ package fr.acinq.eclair.wire.protocol
import fr.acinq.bitcoin.Bech32
import fr.acinq.bitcoin.scalacompat.Crypto.{PrivateKey, PublicKey, XonlyPublicKey}
-import fr.acinq.bitcoin.scalacompat.{Block, ByteVector32, ByteVector64, Crypto, LexicographicalOrdering}
+import fr.acinq.bitcoin.scalacompat.{Block, BlockHash, ByteVector32, ByteVector64, Crypto, LexicographicalOrdering}
import fr.acinq.eclair.crypto.Sphinx.RouteBlinding.{BlindedNode, BlindedRoute}
import fr.acinq.eclair.wire.protocol.CommonCodecs.varint
import fr.acinq.eclair.wire.protocol.OnionRoutingCodecs.{ForbiddenTlv, InvalidTlvPayload, MissingRequiredTlv}
import fr.acinq.eclair.wire.protocol.TlvCodecs.genericTlv
-import fr.acinq.eclair.{Bolt12Feature, CltvExpiryDelta, Feature, Features, MilliSatoshi, RealShortChannelId, ShortChannelId, TimestampSecond, UInt64, nodeFee, randomBytes32}
+import fr.acinq.eclair.{Bolt12Feature, CltvExpiryDelta, Feature, Features, MilliSatoshi, RealShortChannelId, TimestampSecond, UInt64, nodeFee, randomBytes32}
import scodec.Codec
import scodec.bits.ByteVector
import scodec.codecs.vector
@@ -61,7 +61,7 @@ object OfferTypes {
/**
* Chains for which the offer is valid. If empty, bitcoin mainnet is implied.
*/
- case class OfferChains(chains: Seq[ByteVector32]) extends OfferTlv
+ case class OfferChains(chains: Seq[BlockHash]) extends OfferTlv
/**
* Data from the offer creator to themselves, for instance a signature that authenticates the offer so that they don't need to store the offer.
@@ -125,7 +125,7 @@ object OfferTypes {
/**
* If `OfferChains` is present, this specifies which chain is going to be used to pay.
*/
- case class InvoiceRequestChain(hash: ByteVector32) extends InvoiceRequestTlv
+ case class InvoiceRequestChain(hash: BlockHash) extends InvoiceRequestTlv
/**
* Amount that the sender is going to send.
@@ -216,11 +216,11 @@ object OfferTypes {
case class Signature(signature: ByteVector64) extends InvoiceRequestTlv with InvoiceTlv
def filterOfferFields(tlvs: TlvStream[InvoiceRequestTlv]): TlvStream[OfferTlv] =
- // Offer TLVs are in the range (0, 80).
+ // Offer TLVs are in the range (0, 80).
TlvStream[OfferTlv](tlvs.records.collect { case tlv: OfferTlv => tlv }, tlvs.unknown.filter(_.tag < UInt64(80)))
def filterInvoiceRequestFields(tlvs: TlvStream[InvoiceTlv]): TlvStream[InvoiceRequestTlv] =
- // Invoice request TLVs are in the range [0, 160): invoice request metadata (tag 0), offer TLVs, and additional invoice request TLVs in the range [80, 160).
+ // Invoice request TLVs are in the range [0, 160): invoice request metadata (tag 0), offer TLVs, and additional invoice request TLVs in the range [80, 160).
TlvStream[InvoiceRequestTlv](tlvs.records.collect { case tlv: InvoiceRequestTlv => tlv }, tlvs.unknown.filter(_.tag < UInt64(160)))
case class ErroneousField(tag: Long) extends InvoiceErrorTlv
@@ -230,7 +230,7 @@ object OfferTypes {
case class Error(message: String) extends InvoiceErrorTlv
case class Offer(records: TlvStream[OfferTlv]) {
- val chains: Seq[ByteVector32] = records.get[OfferChains].map(_.chains).getOrElse(Seq(Block.LivenetGenesisBlock.hash))
+ val chains: Seq[BlockHash] = records.get[OfferChains].map(_.chains).getOrElse(Seq(Block.LivenetGenesisBlock.hash))
val metadata: Option[ByteVector] = records.get[OfferMetadata].map(_.data)
val currency: Option[String] = records.get[OfferCurrency].map(_.iso4217)
val amount: Option[MilliSatoshi] = currency match {
@@ -271,7 +271,7 @@ object OfferTypes {
description: String,
nodeId: PublicKey,
features: Features[Bolt12Feature],
- chain: ByteVector32,
+ chain: BlockHash,
additionalTlvs: Set[OfferTlv] = Set.empty,
customTlvs: Set[GenericTlv] = Set.empty): Offer = {
val tlvs: Set[OfferTlv] = Set(
@@ -310,7 +310,7 @@ object OfferTypes {
val offer: Offer = Offer.validate(filterOfferFields(records)).toOption.get
val metadata: ByteVector = records.get[InvoiceRequestMetadata].get.data
- val chain: ByteVector32 = records.get[InvoiceRequestChain].map(_.hash).getOrElse(Block.LivenetGenesisBlock.hash)
+ val chain: BlockHash = records.get[InvoiceRequestChain].map(_.hash).getOrElse(Block.LivenetGenesisBlock.hash)
val amount: Option[MilliSatoshi] = records.get[InvoiceRequestAmount].map(_.amount)
val features: Features[Bolt12Feature] = records.get[InvoiceRequestFeatures].map(_.features.bolt12Features()).getOrElse(Features.empty)
val quantity_opt: Option[Long] = records.get[InvoiceRequestQuantity].map(_.quantity)
@@ -367,7 +367,7 @@ object OfferTypes {
quantity: Long,
features: Features[Bolt12Feature],
payerKey: PrivateKey,
- chain: ByteVector32,
+ chain: BlockHash,
additionalTlvs: Set[InvoiceRequestTlv] = Set.empty,
customTlvs: Set[GenericTlv] = Set.empty): InvoiceRequest = {
require(offer.chains.contains(chain))
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/wire/protocol/SetupAndControlTlv.scala b/eclair-core/src/main/scala/fr/acinq/eclair/wire/protocol/SetupAndControlTlv.scala
index 6824b14674..6938381cb9 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/wire/protocol/SetupAndControlTlv.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/wire/protocol/SetupAndControlTlv.scala
@@ -16,7 +16,7 @@
package fr.acinq.eclair.wire.protocol
-import fr.acinq.bitcoin.scalacompat.ByteVector32
+import fr.acinq.bitcoin.scalacompat.BlockHash
import fr.acinq.eclair.UInt64
import fr.acinq.eclair.wire.protocol.CommonCodecs._
import fr.acinq.eclair.wire.protocol.TlvCodecs.{tlvField, tlvStream}
@@ -33,7 +33,7 @@ sealed trait InitTlv extends Tlv
object InitTlv {
/** The chains the node is interested in. */
- case class Networks(chainHashes: List[ByteVector32]) extends InitTlv
+ case class Networks(chainHashes: List[BlockHash]) extends InitTlv
/**
* When receiving an incoming connection, we can send back the public address our peer is connecting from.
@@ -47,7 +47,7 @@ object InitTlvCodecs {
import InitTlv._
- private val networks: Codec[Networks] = tlvField(list(bytes32))
+ private val networks: Codec[Networks] = tlvField(list(blockHash))
private val remoteAddress: Codec[RemoteAddress] = tlvField(nodeaddress)
val initTlvCodec = tlvStream(discriminated[InitTlv].by(varint)
diff --git a/eclair-core/src/test/resources/nonreg/codecs/030000-DATA_WAIT_FOR_FUNDING_CONFIRMED/funder/data.json b/eclair-core/src/test/resources/nonreg/codecs/030000-DATA_WAIT_FOR_FUNDING_CONFIRMED/funder/data.json
index c11f0debbb..7b02159dde 100644
--- a/eclair-core/src/test/resources/nonreg/codecs/030000-DATA_WAIT_FOR_FUNDING_CONFIRMED/funder/data.json
+++ b/eclair-core/src/test/resources/nonreg/codecs/030000-DATA_WAIT_FOR_FUNDING_CONFIRMED/funder/data.json
@@ -120,7 +120,7 @@
"waitingSince" : 400000,
"lastSent" : {
"temporaryChannelId" : "0000000000000000000000000000000000000000000000000000000000000000",
- "fundingTxHash" : "e917adc681383fe00f779c6144a1bd91135ba2c9862ad1bc5aa8a14d37bae3f4",
+ "fundingTxId" : "f4e3ba374da1a85abcd12a86c9a25b1391bda144619c770fe03f3881c6ad17e9",
"fundingOutputIndex" : 0,
"signature" : "bd55d8660f54a1be6e123e2ed9cd6669d90b830d99dc6f9addd9ae65c447ea6b657e2fe39841f66c1d6a2fc80ad59e6f3d9bfaf177f4e95a579f0683bf3e9790",
"tlvStream" : { }
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 e25d69f682..57acb2891a 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/EclairImplSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/EclairImplSpec.scala
@@ -22,7 +22,7 @@ import akka.pattern.pipe
import akka.testkit.TestProbe
import akka.util.Timeout
import fr.acinq.bitcoin.scalacompat.Crypto.{PrivateKey, PublicKey}
-import fr.acinq.bitcoin.scalacompat.{Block, ByteVector32, ByteVector64, Crypto, SatoshiLong}
+import fr.acinq.bitcoin.scalacompat.{Block, ByteVector32, ByteVector64, Crypto, SatoshiLong, TxId}
import fr.acinq.eclair.ApiTypes.{ChannelIdentifier, ChannelNotFound}
import fr.acinq.eclair.TestConstants._
import fr.acinq.eclair.blockchain.DummyOnChainWallet
@@ -235,7 +235,7 @@ class EclairImplSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with I
(ann_cd, makeUpdateShort(ShortChannelId(3L), c, d, feeBase = 1 msat, 0, minHtlc = 0 msat, maxHtlc = None, cltvDelta = CltvExpiryDelta(500))),
(ann_ec, makeUpdateShort(ShortChannelId(7L), e, c, feeBase = 2 msat, 0, minHtlc = 0 msat, maxHtlc = None, cltvDelta = CltvExpiryDelta(12)))
).map { case (ann, update) =>
- update.shortChannelId -> PublicChannel(ann, ByteVector32.Zeroes, 100 sat, Some(update.copy(channelFlags = ChannelUpdate.ChannelFlags.DUMMY)), None, None)
+ update.shortChannelId -> PublicChannel(ann, TxId(ByteVector32.Zeroes), 100 sat, Some(update.copy(channelFlags = ChannelUpdate.ChannelFlags.DUMMY)), None, None)
}: _*)
val eclair = new EclairImpl(kit)
@@ -361,8 +361,8 @@ class EclairImplSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with I
val channel1 = Announcements.makeChannelAnnouncement(Block.RegtestGenesisBlock.hash, RealShortChannelId(1), a, b, a, b, ByteVector64.Zeroes, ByteVector64.Zeroes, ByteVector64.Zeroes, ByteVector64.Zeroes)
val channel2 = Announcements.makeChannelAnnouncement(Block.RegtestGenesisBlock.hash, RealShortChannelId(2), b, c, b, c, ByteVector64.Zeroes, ByteVector64.Zeroes, ByteVector64.Zeroes, ByteVector64.Zeroes)
val publicChannels = SortedMap(
- channel1.shortChannelId -> PublicChannel(channel1, ByteVector32.Zeroes, 100_000 sat, None, None, None),
- channel2.shortChannelId -> PublicChannel(channel2, ByteVector32.Zeroes, 150_000 sat, None, None, None),
+ channel1.shortChannelId -> PublicChannel(channel1, TxId(ByteVector32.Zeroes), 100_000 sat, None, None, None),
+ channel2.shortChannelId -> PublicChannel(channel2, TxId(ByteVector32.Zeroes), 150_000 sat, None, None, None),
)
val (channelId3, shortIds3) = (randomBytes32(), ShortIds(RealScidStatus.Unknown, Alias(13), None))
val (channelId4, shortIds4) = (randomBytes32(), ShortIds(RealScidStatus.Final(RealShortChannelId(4)), Alias(14), None))
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/PackageSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/PackageSpec.scala
index dcdd7d9154..f41f552986 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/PackageSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/PackageSpec.scala
@@ -17,7 +17,7 @@
package fr.acinq.eclair
import fr.acinq.bitcoin.scalacompat.Crypto.PrivateKey
-import fr.acinq.bitcoin.scalacompat.{Block, ByteVector32, Crypto, Script, addressToPublicKeyScript}
+import fr.acinq.bitcoin.scalacompat.{Block, ByteVector32, Crypto, Script, TxHash, TxId, addressToPublicKeyScript}
import fr.acinq.bitcoin.{Base58, Base58Check, Bech32}
import org.scalatest.funsuite.AnyFunSuite
import scodec.bits._
@@ -32,13 +32,15 @@ class PackageSpec extends AnyFunSuite {
implicit def byteVector322array(input: ByteVector32): Array[Byte] = input.toArray
test("compute long channel id") {
- val data = ((hex"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 0, hex"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF") ::
- (hex"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 1, hex"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE") ::
- (hex"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000", 2, hex"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0002") ::
- (hex"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00F0", 0x0F00, hex"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0FF0") :: Nil)
- .map(x => (ByteVector32(x._1), x._2, ByteVector32(x._3)))
-
- data.foreach(x => assert(toLongId(ByteVector32(x._1), x._2) == x._3))
+ case class TestCase(fundingTxId: TxId, fundingOutputIndex: Int, expected: ByteVector32)
+
+ val testCases = Seq(
+ TestCase(TxId.fromValidHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), 0, ByteVector32.fromValidHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")),
+ TestCase(TxId.fromValidHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), 1, ByteVector32.fromValidHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE")),
+ TestCase(TxId.fromValidHex("0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), 2, ByteVector32.fromValidHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0002")),
+ TestCase(TxId.fromValidHex("F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), 0x0f00, ByteVector32.fromValidHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0FF0")),
+ )
+ testCases.foreach(t => assert(toLongId(t.fundingTxId, t.fundingOutputIndex) == t.expected))
}
test("decode base58 addresses") {
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/TestBitcoinCoreClient.scala b/eclair-core/src/test/scala/fr/acinq/eclair/TestBitcoinCoreClient.scala
index 25d7ee41bd..0cb8057a76 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/TestBitcoinCoreClient.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/TestBitcoinCoreClient.scala
@@ -17,7 +17,7 @@
package fr.acinq.eclair
import akka.actor.ActorSystem
-import fr.acinq.bitcoin.scalacompat.{ByteVector32, Transaction}
+import fr.acinq.bitcoin.scalacompat.{BlockId, Transaction, TxId}
import fr.acinq.eclair.blockchain._
import fr.acinq.eclair.blockchain.bitcoind.rpc.BitcoinJsonRPCAuthMethod.UserPassword
import fr.acinq.eclair.blockchain.bitcoind.rpc.{BasicBitcoinJsonRPCClient, BitcoinCoreClient}
@@ -32,17 +32,17 @@ class TestBitcoinCoreClient()(implicit system: ActorSystem) extends BitcoinCoreC
import scala.concurrent.ExecutionContext.Implicits.global
- system.scheduler.scheduleWithFixedDelay(100 milliseconds, 100 milliseconds)(() => system.eventStream.publish(NewBlock(randomBytes32())))
+ system.scheduler.scheduleWithFixedDelay(100 milliseconds, 100 milliseconds)(() => system.eventStream.publish(NewBlock(BlockId(randomBytes32()))))
- override def publishTransaction(tx: Transaction)(implicit ec: ExecutionContext): Future[ByteVector32] = {
+ override def publishTransaction(tx: Transaction)(implicit ec: ExecutionContext): Future[TxId] = {
system.eventStream.publish(NewTransaction(tx))
Future.successful(tx.txid)
}
- override def getTxConfirmations(txId: ByteVector32)(implicit ec: ExecutionContext): Future[Option[Int]] = Future.successful(Some(10))
+ override def getTxConfirmations(txId: TxId)(implicit ec: ExecutionContext): Future[Option[Int]] = Future.successful(Some(10))
- override def getTransaction(txId: ByteVector32)(implicit ec: ExecutionContext): Future[Transaction] = Future.failed(new RuntimeException("not implemented"))
+ override def getTransaction(txId: TxId)(implicit ec: ExecutionContext): Future[Transaction] = Future.failed(new RuntimeException("not implemented"))
- override def getTransactionShortId(txId: ByteVector32)(implicit ec: ExecutionContext): Future[(BlockHeight, Int)] = Future.successful((BlockHeight(400000), 42))
+ override def getTransactionShortId(txId: TxId)(implicit ec: ExecutionContext): Future[(BlockHeight, Int)] = Future.successful((BlockHeight(400000), 42))
}
\ No newline at end of file
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/TestUtils.scala b/eclair-core/src/test/scala/fr/acinq/eclair/TestUtils.scala
index c8012d440b..8a81b24965 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/TestUtils.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/TestUtils.scala
@@ -19,17 +19,17 @@ package fr.acinq.eclair
import akka.actor.{ActorRef, ActorSystem}
import akka.event.{DiagnosticLoggingAdapter, EventStream}
import akka.testkit.{TestActor, TestProbe}
+import fr.acinq.bitcoin.scalacompat.TxId
import fr.acinq.eclair.channel.fsm.Channel
import fr.acinq.eclair.io.Peer
import fr.acinq.eclair.wire.protocol.LightningMessage
import org.scalatest.concurrent.Eventually.eventually
-import org.scalatest.concurrent.PatienceConfiguration
import java.io.File
import java.net.ServerSocket
import java.nio.file.Files
import java.util.UUID
-import scala.concurrent.duration.{DurationInt, FiniteDuration}
+import scala.concurrent.duration.FiniteDuration
object TestUtils {
@@ -110,4 +110,6 @@ object TestUtils {
def waitFor(duration: FiniteDuration): Unit = Thread.sleep(duration.toMillis)
+ def randomTxId(): TxId = TxId(randomBytes32())
+
}
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/balance/CheckBalanceSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/balance/CheckBalanceSpec.scala
index 54a8c05e1e..b66fc6d7b1 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/balance/CheckBalanceSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/balance/CheckBalanceSpec.scala
@@ -2,7 +2,8 @@ package fr.acinq.eclair.balance
import akka.pattern.pipe
import akka.testkit.TestProbe
-import fr.acinq.bitcoin.scalacompat.{ByteVector32, SatoshiLong}
+import fr.acinq.bitcoin.scalacompat.{ByteVector32, SatoshiLong, TxId}
+import fr.acinq.eclair.TestUtils.randomTxId
import fr.acinq.eclair.balance.CheckBalance.{ClosingBalance, MainAndHtlcBalance, OffChainBalance, PossiblyPublishedMainAndHtlcBalance, PossiblyPublishedMainBalance}
import fr.acinq.eclair.blockchain.bitcoind.ZmqWatcher.{apply => _, _}
import fr.acinq.eclair.blockchain.bitcoind.rpc.BitcoinCoreClient
@@ -250,12 +251,12 @@ class CheckBalanceSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with
}
test("tx pruning") { () =>
- val txids = (for (_ <- 0 until 20) yield randomBytes32()).toList
+ val txids = (for (_ <- 0 until 20) yield randomTxId()).toList
val knownTxids = Set(txids(1), txids(3), txids(4), txids(6), txids(9), txids(12), txids(13))
val bitcoinClient = new BitcoinCoreClient(null) {
/** Get the number of confirmations of a given transaction. */
- override def getTxConfirmations(txid: ByteVector32)(implicit ec: ExecutionContext): Future[Option[Int]] =
+ override def getTxConfirmations(txid: TxId)(implicit ec: ExecutionContext): Future[Option[Int]] =
Future.successful(if (knownTxids.contains(txid)) Some(42) else None)
}
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/DummyOnChainWallet.scala b/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/DummyOnChainWallet.scala
index 8caca5b45b..4e02548273 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/DummyOnChainWallet.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/DummyOnChainWallet.scala
@@ -19,13 +19,14 @@ package fr.acinq.eclair.blockchain
import fr.acinq.bitcoin.TxIn.SEQUENCE_FINAL
import fr.acinq.bitcoin.psbt.Psbt
import fr.acinq.bitcoin.scalacompat.Crypto.PublicKey
-import fr.acinq.bitcoin.scalacompat.{ByteVector32, Crypto, OutPoint, Satoshi, SatoshiLong, Script, Transaction, TxIn, TxOut}
+import fr.acinq.bitcoin.scalacompat.{Crypto, OutPoint, Satoshi, SatoshiLong, Script, Transaction, TxId, TxIn, TxOut}
import fr.acinq.bitcoin.{Bech32, SigHash, SigVersion}
+import fr.acinq.eclair.TestUtils.randomTxId
import fr.acinq.eclair.blockchain.OnChainWallet.{FundTransactionResponse, MakeFundingTxResponse, OnChainBalance, ProcessPsbtResponse}
import fr.acinq.eclair.blockchain.bitcoind.BitcoindService.SignTransactionResponse
import fr.acinq.eclair.blockchain.fee.FeeratePerKw
+import fr.acinq.eclair.randomKey
import fr.acinq.eclair.transactions.Transactions
-import fr.acinq.eclair.{randomBytes32, randomKey}
import scodec.bits._
import scala.concurrent.{ExecutionContext, Future, Promise}
@@ -38,8 +39,8 @@ class DummyOnChainWallet extends OnChainWallet with OnchainPubkeyCache {
import DummyOnChainWallet._
- val funded = collection.concurrent.TrieMap.empty[ByteVector32, Transaction]
- val published = collection.concurrent.TrieMap.empty[ByteVector32, Transaction]
+ val funded = collection.concurrent.TrieMap.empty[TxId, Transaction]
+ val published = collection.concurrent.TrieMap.empty[TxId, Transaction]
var rolledback = Set.empty[Transaction]
override def onChainBalance()(implicit ec: ExecutionContext): Future[OnChainBalance] = Future.successful(OnChainBalance(1105 sat, 561 sat))
@@ -55,7 +56,7 @@ class DummyOnChainWallet extends OnChainWallet with OnchainPubkeyCache {
override def signPsbt(psbt: Psbt, ourInputs: Seq[Int], ourOutputs: Seq[Int])(implicit ec: ExecutionContext): Future[ProcessPsbtResponse] = Future.successful(ProcessPsbtResponse(psbt, complete = true))
- override def publishTransaction(tx: Transaction)(implicit ec: ExecutionContext): Future[ByteVector32] = {
+ override def publishTransaction(tx: Transaction)(implicit ec: ExecutionContext): Future[TxId] = {
published += (tx.txid -> tx)
Future.successful(tx.txid)
}
@@ -68,9 +69,9 @@ class DummyOnChainWallet extends OnChainWallet with OnchainPubkeyCache {
override def commit(tx: Transaction)(implicit ec: ExecutionContext): Future[Boolean] = publishTransaction(tx).map(_ => true)
- override def getTransaction(txId: ByteVector32)(implicit ec: ExecutionContext): Future[Transaction] = Future.failed(new RuntimeException("transaction not found"))
+ override def getTransaction(txId: TxId)(implicit ec: ExecutionContext): Future[Transaction] = Future.failed(new RuntimeException("transaction not found"))
- override def getTxConfirmations(txid: ByteVector32)(implicit ec: ExecutionContext): Future[Option[Int]] = Future.failed(new RuntimeException("transaction not found"))
+ override def getTxConfirmations(txid: TxId)(implicit ec: ExecutionContext): Future[Option[Int]] = Future.failed(new RuntimeException("transaction not found"))
override def rollback(tx: Transaction)(implicit ec: ExecutionContext): Future[Boolean] = {
rolledback = rolledback + tx
@@ -87,7 +88,7 @@ class NoOpOnChainWallet extends OnChainWallet with OnchainPubkeyCache {
import DummyOnChainWallet._
var rolledback = Seq.empty[Transaction]
- var doubleSpent = Set.empty[ByteVector32]
+ var doubleSpent = Set.empty[TxId]
override def onChainBalance()(implicit ec: ExecutionContext): Future[OnChainBalance] = Future.successful(OnChainBalance(1105 sat, 561 sat))
@@ -99,15 +100,15 @@ class NoOpOnChainWallet extends OnChainWallet with OnchainPubkeyCache {
override def signPsbt(psbt: Psbt, ourInputs: Seq[Int], ourOutputs: Seq[Int])(implicit ec: ExecutionContext): Future[ProcessPsbtResponse] = Promise().future // will never be completed
- override def publishTransaction(tx: Transaction)(implicit ec: ExecutionContext): Future[ByteVector32] = Future.successful(tx.txid)
+ override def publishTransaction(tx: Transaction)(implicit ec: ExecutionContext): Future[TxId] = Future.successful(tx.txid)
override def makeFundingTx(pubkeyScript: ByteVector, amount: Satoshi, feeRatePerKw: FeeratePerKw)(implicit ec: ExecutionContext): Future[MakeFundingTxResponse] = Promise().future // will never be completed
override def commit(tx: Transaction)(implicit ec: ExecutionContext): Future[Boolean] = Future.successful(true)
- override def getTransaction(txId: ByteVector32)(implicit ec: ExecutionContext): Future[Transaction] = Promise().future // will never be completed
+ override def getTransaction(txId: TxId)(implicit ec: ExecutionContext): Future[Transaction] = Promise().future // will never be completed
- override def getTxConfirmations(txid: ByteVector32)(implicit ec: ExecutionContext): Future[Option[Int]] = Promise().future // will never be completed
+ override def getTxConfirmations(txid: TxId)(implicit ec: ExecutionContext): Future[Option[Int]] = Promise().future // will never be completed
override def rollback(tx: Transaction)(implicit ec: ExecutionContext): Future[Boolean] = {
rolledback = rolledback :+ tx
@@ -125,7 +126,7 @@ class SingleKeyOnChainWallet extends OnChainWallet with OnchainPubkeyCache {
// We create a new dummy input transaction for every funding request.
var inputs = Seq.empty[Transaction]
var rolledback = Seq.empty[Transaction]
- var doubleSpent = Set.empty[ByteVector32]
+ var doubleSpent = Set.empty[TxId]
override def onChainBalance()(implicit ec: ExecutionContext): Future[OnChainBalance] = Future.successful(OnChainBalance(1105 sat, 561 sat))
@@ -138,7 +139,7 @@ class SingleKeyOnChainWallet extends OnChainWallet with OnchainPubkeyCache {
val amountOut = tx.txOut.map(_.amount).sum
// We add a single input to reach the desired feerate.
val inputAmount = amountOut + 100_000.sat
- val inputTx = Transaction(2, Seq(TxIn(OutPoint(randomBytes32(), 1), Nil, 0)), Seq(TxOut(inputAmount, Script.pay2wpkh(pubkey))), 0)
+ val inputTx = Transaction(2, Seq(TxIn(OutPoint(randomTxId(), 1), Nil, 0)), Seq(TxOut(inputAmount, Script.pay2wpkh(pubkey))), 0)
inputs = inputs :+ inputTx
val dummyWitness = Script.witnessPay2wpkh(pubkey, ByteVector.fill(73)(0))
val dummySignedTx = tx.copy(
@@ -166,7 +167,7 @@ class SingleKeyOnChainWallet extends OnChainWallet with OnchainPubkeyCache {
Future.successful(SignTransactionResponse(signedTx, complete))
}
- override def publishTransaction(tx: Transaction)(implicit ec: ExecutionContext): Future[ByteVector32] = {
+ override def publishTransaction(tx: Transaction)(implicit ec: ExecutionContext): Future[TxId] = {
inputs = inputs :+ tx
Future.successful(tx.txid)
}
@@ -174,7 +175,7 @@ class SingleKeyOnChainWallet extends OnChainWallet with OnchainPubkeyCache {
override def signPsbt(psbt: Psbt, ourInputs: Seq[Int], ourOutputs: Seq[Int])(implicit ec: ExecutionContext): Future[ProcessPsbtResponse] = {
import fr.acinq.bitcoin.scalacompat.KotlinUtils._
- val tx: Transaction = psbt.getGlobal.getTx
+ val tx: Transaction = psbt.global.tx
val signedPsbt = tx.txIn.zipWithIndex.foldLeft(new Psbt(tx)) {
case (currentPsbt, (txIn, index)) => inputs.find(_.txid == txIn.outPoint.txid) match {
case Some(inputTx) =>
@@ -198,14 +199,14 @@ class SingleKeyOnChainWallet extends OnChainWallet with OnchainPubkeyCache {
override def commit(tx: Transaction)(implicit ec: ExecutionContext): Future[Boolean] = Future.successful(true)
- override def getTransaction(txId: ByteVector32)(implicit ec: ExecutionContext): Future[Transaction] = synchronized {
+ override def getTransaction(txId: TxId)(implicit ec: ExecutionContext): Future[Transaction] = synchronized {
inputs.find(_.txid == txId) match {
case Some(tx) => Future.successful(tx)
case None => Future.failed(new RuntimeException(s"txid=$txId not found"))
}
}
- override def getTxConfirmations(txid: ByteVector32)(implicit ec: ExecutionContext): Future[Option[Int]] = Future.successful(None)
+ override def getTxConfirmations(txid: TxId)(implicit ec: ExecutionContext): Future[Option[Int]] = Future.successful(None)
override def rollback(tx: Transaction)(implicit ec: ExecutionContext): Future[Boolean] = {
rolledback = rolledback :+ tx
@@ -225,7 +226,7 @@ object DummyOnChainWallet {
def makeDummyFundingTx(pubkeyScript: ByteVector, amount: Satoshi): MakeFundingTxResponse = {
val fundingTx = Transaction(
version = 2,
- txIn = TxIn(OutPoint(ByteVector32(ByteVector.fill(32)(1)), 42), signatureScript = Nil, sequence = SEQUENCE_FINAL) :: Nil,
+ txIn = TxIn(OutPoint(TxId.fromValidHex("0101010101010101010101010101010101010101010101010101010101010101"), 42), signatureScript = Nil, sequence = SEQUENCE_FINAL) :: Nil,
txOut = TxOut(amount, pubkeyScript) :: Nil,
lockTime = 0
)
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/bitcoind/BitcoinCoreClientSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/bitcoind/BitcoinCoreClientSpec.scala
index 6d0312782c..2ad2874949 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/bitcoind/BitcoinCoreClientSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/bitcoind/BitcoinCoreClientSpec.scala
@@ -22,8 +22,9 @@ import akka.testkit.TestProbe
import fr.acinq.bitcoin
import fr.acinq.bitcoin.psbt.{Psbt, UpdateFailure}
import fr.acinq.bitcoin.scalacompat.Crypto.PublicKey
-import fr.acinq.bitcoin.scalacompat.{Block, Btc, BtcDouble, ByteVector32, Crypto, DeterministicWallet, MilliBtcDouble, MnemonicCode, OP_DROP, OP_PUSHDATA, OutPoint, Satoshi, SatoshiLong, Script, ScriptWitness, Transaction, TxIn, TxOut, addressFromPublicKeyScript, addressToPublicKeyScript, computeBIP84Address, computeP2PkhAddress, computeP2WpkhAddress}
+import fr.acinq.bitcoin.scalacompat.{Block, Btc, BtcDouble, ByteVector32, Crypto, DeterministicWallet, MilliBtcDouble, MnemonicCode, OP_DROP, OP_PUSHDATA, OutPoint, Satoshi, SatoshiLong, Script, ScriptWitness, Transaction, TxId, TxIn, TxOut, addressFromPublicKeyScript, addressToPublicKeyScript, computeBIP84Address, computeP2PkhAddress, computeP2WpkhAddress}
import fr.acinq.bitcoin.{Bech32, SigHash, SigVersion}
+import fr.acinq.eclair.TestUtils.randomTxId
import fr.acinq.eclair.blockchain.OnChainWallet.{FundTransactionResponse, MakeFundingTxResponse, OnChainBalance, ProcessPsbtResponse}
import fr.acinq.eclair.blockchain.WatcherSpec.{createSpendManyP2WPKH, createSpendP2WPKH}
import fr.acinq.eclair.blockchain.bitcoind.BitcoindService.{BitcoinReq, SignTransactionResponse}
@@ -198,7 +199,7 @@ class BitcoinCoreClientSpec extends TestKitBaseClass with BitcoindService with A
walletExternalFunds.getReceiveAddress().pipeTo(sender.ref)
val walletAddress = sender.expectMsgType[String]
defaultWallet.sendToPubkeyScript(Script.write(addressToPublicKeyScript(Block.RegtestGenesisBlock.hash, walletAddress).toOption.get), amount, FeeratePerKw(FeeratePerByte(3.sat))).pipeTo(sender.ref)
- sender.expectMsgType[ByteVector32]
+ sender.expectMsgType[TxId]
})
// We receive more funds on an address that does not belong to our wallet.
@@ -664,7 +665,7 @@ class BitcoinCoreClientSpec extends TestKitBaseClass with BitcoindService with A
val nonWalletWitness = ScriptWitness(Seq(nonWalletSig, nonWalletKey.publicKey.value))
val txWithSignedNonWalletInput = txWithNonWalletInput.updateWitness(0, nonWalletWitness)
val psbt = new Psbt(txWithSignedNonWalletInput)
- val updated: Either[UpdateFailure, Psbt] = psbt.updateWitnessInput(psbt.getGlobal.getTx.txIn.get(0).outPoint, txToRemote.txOut(0), null, fr.acinq.bitcoin.Script.pay2pkh(nonWalletKey.publicKey), SigHash.SIGHASH_ALL, psbt.getInput(0).getDerivationPaths)
+ val updated: Either[UpdateFailure, Psbt] = psbt.updateWitnessInput(psbt.global.tx.txIn.get(0).outPoint, txToRemote.txOut(0), null, fr.acinq.bitcoin.Script.pay2pkh(nonWalletKey.publicKey), SigHash.SIGHASH_ALL, psbt.getInput(0).getDerivationPaths)
val Right(psbt1) = updated.flatMap(_.finalizeWitnessInput(0, nonWalletWitness))
bitcoinClient.signPsbt(psbt1, txWithSignedNonWalletInput.txIn.indices.tail, Nil).pipeTo(sender.ref)
val signTxResponse2 = sender.expectMsgType[ProcessPsbtResponse]
@@ -696,7 +697,7 @@ class BitcoinCoreClientSpec extends TestKitBaseClass with BitcoindService with A
val nonWalletWitness = ScriptWitness(Seq(nonWalletSig, nonWalletKey.publicKey.value))
val txWithSignedUnconfirmedInput = txWithUnconfirmedInput.updateWitness(0, nonWalletWitness)
val psbt = new Psbt(txWithSignedUnconfirmedInput)
- val Right(psbt1) = psbt.updateWitnessInput(psbt.getGlobal.getTx.txIn.get(0).outPoint, unconfirmedTx.txOut(0), null, fr.acinq.bitcoin.Script.pay2pkh(nonWalletKey.publicKey), SigHash.SIGHASH_ALL, psbt.getInput(0).getDerivationPaths)
+ val Right(psbt1) = psbt.updateWitnessInput(psbt.global.tx.txIn.get(0).outPoint, unconfirmedTx.txOut(0), null, fr.acinq.bitcoin.Script.pay2pkh(nonWalletKey.publicKey), SigHash.SIGHASH_ALL, psbt.getInput(0).getDerivationPaths)
.flatMap(_.finalizeWitnessInput(0, nonWalletWitness))
bitcoinClient.signPsbt(psbt1, txWithSignedUnconfirmedInput.txIn.indices.tail, Nil).pipeTo(sender.ref)
assert(sender.expectMsgType[ProcessPsbtResponse].complete)
@@ -733,7 +734,7 @@ class BitcoinCoreClientSpec extends TestKitBaseClass with BitcoindService with A
val spendingTx = {
val address = getNewAddress(sender)
val pos = if (changePos == 0) 1 else 0
- bitcoinrpcclient.invoke("createrawtransaction", Array(Map("txid" -> tx.txid.toHex, "vout" -> pos)), Map(address -> 5.999)).pipeTo(sender.ref)
+ bitcoinrpcclient.invoke("createrawtransaction", Array(Map("txid" -> tx.txid.value.toHex, "vout" -> pos)), Map(address -> 5.999)).pipeTo(sender.ref)
val JString(unsignedTxStr) = sender.expectMsgType[JValue]
val unsignedTx = Transaction.read(unsignedTxStr)
val sig = Transaction.signInput(unsignedTx, 0, Script.pay2pkh(priv.publicKey), bitcoin.SigHash.SIGHASH_ALL, 6.btc.toSatoshi, bitcoin.SigVersion.SIGVERSION_WITNESS_V0, priv)
@@ -1026,7 +1027,7 @@ class BitcoinCoreClientSpec extends TestKitBaseClass with BitcoindService with A
signTxResponse.tx
}
- def getMempoolTx(txid: ByteVector32): MempoolTx = {
+ def getMempoolTx(txid: TxId): MempoolTx = {
val probe = TestProbe()
bitcoinClient.getMempoolTx(txid).pipeTo(probe.ref)
probe.expectMsgType[MempoolTx]
@@ -1090,7 +1091,7 @@ class BitcoinCoreClientSpec extends TestKitBaseClass with BitcoindService with A
test("cannot bump transaction fees (unknown transaction)") {
val sender = TestProbe()
val bitcoinClient = makeBitcoinCoreClient()
- bitcoinClient.cpfp(Set(OutPoint(randomBytes32(), 0), OutPoint(randomBytes32(), 3)), FeeratePerKw(1500 sat)).pipeTo(sender.ref)
+ bitcoinClient.cpfp(Set(OutPoint(randomTxId(), 0), OutPoint(randomTxId(), 3)), FeeratePerKw(1500 sat)).pipeTo(sender.ref)
val failure = sender.expectMsgType[Failure]
assert(failure.cause.getMessage.contains("some transactions could not be found"))
}
@@ -1328,7 +1329,7 @@ class BitcoinCoreClientSpec extends TestKitBaseClass with BitcoindService with A
val pubKey = randomKey().publicKey
val legacyAddress = computeP2PkhAddress(pubKey, Block.RegtestGenesisBlock.hash)
bitcoinClient.sendToPubkeyScript(addressToPublicKeyScript(Block.RegtestGenesisBlock.hash, legacyAddress).toOption.get, 150_000 sat, FeeratePerKw(FeeratePerByte(3.sat))).pipeTo(sender.ref)
- val txId = sender.expectMsgType[ByteVector32]
+ val txId = sender.expectMsgType[TxId]
bitcoinClient.getTransaction(txId).pipeTo(sender.ref)
val tx = sender.expectMsgType[Transaction]
// We have a change output.
@@ -1468,7 +1469,7 @@ class BitcoinCoreClientWithEclairSignerSpec extends BitcoinCoreClientSpec {
assert(error.cause.getMessage.contains("Private keys are disabled for this wallet"))
wallet.sendToPubkeyScript(addressToPublicKeyScript(Block.RegtestGenesisBlock.hash, address).toOption.get, 50_000.sat, FeeratePerKw(FeeratePerByte(5.sat))).pipeTo(sender.ref)
- sender.expectMsgType[ByteVector32]
+ sender.expectMsgType[TxId]
}
}
}
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/bitcoind/ZmqWatcherSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/bitcoind/ZmqWatcherSpec.scala
index 1584316b1f..ff13d282a1 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/bitcoind/ZmqWatcherSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/bitcoind/ZmqWatcherSpec.scala
@@ -21,7 +21,8 @@ import akka.actor.typed.scaladsl.adapter.{ClassicActorSystemOps, TypedActorRefOp
import akka.actor.{ActorRef, Props, typed}
import akka.pattern.pipe
import akka.testkit.TestProbe
-import fr.acinq.bitcoin.scalacompat.{Block, Btc, MilliBtcDouble, OutPoint, SatoshiLong, Script, Transaction, TxOut}
+import fr.acinq.bitcoin.scalacompat.{Block, Btc, MilliBtcDouble, OutPoint, SatoshiLong, Script, Transaction, TxId, TxOut}
+import fr.acinq.eclair.TestUtils.randomTxId
import fr.acinq.eclair.blockchain.OnChainWallet.{FundTransactionResponse, MakeFundingTxResponse}
import fr.acinq.eclair.blockchain.WatcherSpec._
import fr.acinq.eclair.blockchain.bitcoind.BitcoindService.SignTransactionResponse
@@ -31,7 +32,7 @@ import fr.acinq.eclair.blockchain.bitcoind.rpc.BitcoinCoreClient.FundTransaction
import fr.acinq.eclair.blockchain.bitcoind.zmq.ZMQActor
import fr.acinq.eclair.blockchain.fee.FeeratePerKw
import fr.acinq.eclair.blockchain.{CurrentBlockHeight, NewTransaction}
-import fr.acinq.eclair.{BlockHeight, RealShortChannelId, TestConstants, TestKitBaseClass, randomBytes32, randomKey}
+import fr.acinq.eclair.{BlockHeight, RealShortChannelId, TestConstants, TestKitBaseClass, randomKey}
import grizzled.slf4j.Logging
import org.scalatest.BeforeAndAfterAll
import org.scalatest.funsuite.AnyFunSuiteLike
@@ -104,14 +105,14 @@ class ZmqWatcherSpec extends TestKitBaseClass with AnyFunSuiteLike with Bitcoind
test("add/remove watches from/to utxo map") {
val m0 = Map.empty[OutPoint, Set[Watch[_ <: WatchTriggered]]]
- val txid = randomBytes32()
+ val txid = randomTxId()
val outputIndex = 42
- val utxo = OutPoint(txid.reverse, outputIndex)
+ val utxo = OutPoint(txid, outputIndex)
val w1 = WatchFundingSpent(TestProbe().ref, txid, outputIndex, hints = Set.empty)
val w2 = WatchFundingSpent(TestProbe().ref, txid, outputIndex, hints = Set.empty)
val w3 = WatchExternalChannelSpent(TestProbe().ref, txid, outputIndex, RealShortChannelId(1))
- val w4 = WatchExternalChannelSpent(TestProbe().ref, randomBytes32(), 5, RealShortChannelId(1))
+ val w4 = WatchExternalChannelSpent(TestProbe().ref, randomTxId(), 5, RealShortChannelId(1))
val w5 = WatchFundingConfirmed(TestProbe().ref, txid, 3)
// we test as if the collection was immutable
@@ -122,17 +123,17 @@ class ZmqWatcherSpec extends TestKitBaseClass with AnyFunSuiteLike with Bitcoind
val m3 = addWatchedUtxos(m2, w3)
assert(m3.keySet == Set(utxo) && m3(utxo).size == 3)
val m4 = addWatchedUtxos(m3, w4)
- assert(m4.keySet == Set(utxo, OutPoint(w4.txId.reverse, w4.outputIndex)) && m3(utxo).size == 3)
+ assert(m4.keySet == Set(utxo, OutPoint(w4.txId, w4.outputIndex)) && m3(utxo).size == 3)
val m5 = addWatchedUtxos(m4, w5)
- assert(m5.keySet == Set(utxo, OutPoint(w4.txId.reverse, w4.outputIndex)) && m5(utxo).size == 3)
+ assert(m5.keySet == Set(utxo, OutPoint(w4.txId, w4.outputIndex)) && m5(utxo).size == 3)
val m6 = removeWatchedUtxos(m5, w3)
- assert(m6.keySet == Set(utxo, OutPoint(w4.txId.reverse, w4.outputIndex)) && m6(utxo).size == 2)
+ assert(m6.keySet == Set(utxo, OutPoint(w4.txId, w4.outputIndex)) && m6(utxo).size == 2)
val m7 = removeWatchedUtxos(m6, w3)
- assert(m7.keySet == Set(utxo, OutPoint(w4.txId.reverse, w4.outputIndex)) && m7(utxo).size == 2)
+ assert(m7.keySet == Set(utxo, OutPoint(w4.txId, w4.outputIndex)) && m7(utxo).size == 2)
val m8 = removeWatchedUtxos(m7, w2)
- assert(m8.keySet == Set(utxo, OutPoint(w4.txId.reverse, w4.outputIndex)) && m8(utxo).size == 1)
+ assert(m8.keySet == Set(utxo, OutPoint(w4.txId, w4.outputIndex)) && m8(utxo).size == 1)
val m9 = removeWatchedUtxos(m8, w1)
- assert(m9.keySet == Set(OutPoint(w4.txId.reverse, w4.outputIndex)))
+ assert(m9.keySet == Set(OutPoint(w4.txId, w4.outputIndex)))
val m10 = removeWatchedUtxos(m9, w4)
assert(m10.isEmpty)
}
@@ -281,7 +282,7 @@ class ZmqWatcherSpec extends TestKitBaseClass with AnyFunSuiteLike with Bitcoind
watcher ! StopWatching(probe.ref)
// We should still find tx2 if the provided hint is wrong
- watcher ! WatchOutputSpent(probe.ref, tx1.txid, 0, Set(randomBytes32()))
+ watcher ! WatchOutputSpent(probe.ref, tx1.txid, 0, Set(randomTxId()))
probe.fishForMessage() { case m: WatchOutputSpentTriggered => m.spendingTx.txid == tx2.txid }
watcher ! StopWatching(probe.ref)
@@ -359,11 +360,11 @@ class ZmqWatcherSpec extends TestKitBaseClass with AnyFunSuiteLike with Bitcoind
val actor1 = TestProbe()
val actor2 = TestProbe()
- val txid = randomBytes32()
+ val txid = randomTxId()
watcher ! WatchFundingConfirmed(actor1.ref, txid, 2)
watcher ! WatchFundingConfirmed(actor1.ref, txid, 3)
watcher ! WatchFundingDeeplyBuried(actor1.ref, txid, 3)
- watcher ! WatchFundingConfirmed(actor1.ref, txid.reverse, 3)
+ watcher ! WatchFundingConfirmed(actor1.ref, TxId(txid.value.reverse), 3)
watcher ! WatchOutputSpent(actor1.ref, txid, 0, Set.empty)
watcher ! WatchOutputSpent(actor1.ref, txid, 1, Set.empty)
watcher ! ListWatches(actor1.ref)
@@ -372,7 +373,7 @@ class ZmqWatcherSpec extends TestKitBaseClass with AnyFunSuiteLike with Bitcoind
watcher ! WatchFundingConfirmed(actor2.ref, txid, 2)
watcher ! WatchFundingDeeplyBuried(actor2.ref, txid, 3)
- watcher ! WatchFundingConfirmed(actor2.ref, txid.reverse, 3)
+ watcher ! WatchFundingConfirmed(actor2.ref, TxId(txid.value.reverse), 3)
watcher ! WatchOutputSpent(actor2.ref, txid, 0, Set.empty)
watcher ! WatchOutputSpent(actor2.ref, txid, 1, Set.empty)
watcher ! ListWatches(actor2.ref)
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/channel/CommitmentsSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/channel/CommitmentsSpec.scala
index fb0f5be56d..4ec9b9a026 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/channel/CommitmentsSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/channel/CommitmentsSpec.scala
@@ -18,6 +18,7 @@ package fr.acinq.eclair.channel
import fr.acinq.bitcoin.scalacompat.Crypto.PublicKey
import fr.acinq.bitcoin.scalacompat.{Block, ByteVector32, ByteVector64, DeterministicWallet, Satoshi, SatoshiLong, Transaction}
+import fr.acinq.eclair.TestUtils.randomTxId
import fr.acinq.eclair._
import fr.acinq.eclair.blockchain.fee._
import fr.acinq.eclair.channel.Helpers.Funding
@@ -30,7 +31,6 @@ import fr.acinq.eclair.wire.protocol.{IncorrectOrUnknownPaymentDetails, UpdateAd
import org.scalatest.funsuite.FixtureAnyFunSuiteLike
import org.scalatest.{Outcome, Tag}
-import java.util.concurrent.atomic.AtomicReference
import scala.concurrent.duration._
import scala.util.Random
@@ -489,9 +489,9 @@ object CommitmentsSpec {
val localParams = LocalParams(randomKey().publicKey, DeterministicWallet.KeyPath(Seq(42L)), dustLimit, Long.MaxValue.msat, Some(channelReserve), 1 msat, CltvExpiryDelta(144), 50, isInitiator, None, None, Features.empty)
val remoteParams = RemoteParams(randomKey().publicKey, dustLimit, UInt64.MaxValue, Some(channelReserve), 1 msat, CltvExpiryDelta(144), 50, randomKey().publicKey, randomKey().publicKey, randomKey().publicKey, randomKey().publicKey, Features.empty, None)
val remoteFundingPubKey = randomKey().publicKey
- val commitmentInput = Funding.makeFundingInputInfo(randomBytes32(), 0, (toLocal + toRemote).truncateToSatoshi, randomKey().publicKey, remoteFundingPubKey)
+ val commitmentInput = Funding.makeFundingInputInfo(randomTxId(), 0, (toLocal + toRemote).truncateToSatoshi, randomKey().publicKey, remoteFundingPubKey)
val localCommit = LocalCommit(0, CommitmentSpec(Set.empty, feeRatePerKw, toLocal, toRemote), CommitTxAndRemoteSig(CommitTx(commitmentInput, Transaction(2, Nil, Nil, 0)), ByteVector64.Zeroes), Nil)
- val remoteCommit = RemoteCommit(0, CommitmentSpec(Set.empty, feeRatePerKw, toRemote, toLocal), randomBytes32(), randomKey().publicKey)
+ val remoteCommit = RemoteCommit(0, CommitmentSpec(Set.empty, feeRatePerKw, toRemote, toLocal), randomTxId(), randomKey().publicKey)
Commitments(
ChannelParams(randomBytes32(), ChannelConfig.standard, ChannelFeatures(), localParams, remoteParams, ChannelFlags(announceChannel = announceChannel)),
CommitmentChanges(LocalChanges(Nil, Nil, Nil), RemoteChanges(Nil, Nil, Nil), localNextHtlcId = 1, remoteNextHtlcId = 1),
@@ -508,9 +508,9 @@ object CommitmentsSpec {
val localParams = LocalParams(localNodeId, DeterministicWallet.KeyPath(Seq(42L)), 0 sat, Long.MaxValue.msat, Some(channelReserve), 1 msat, CltvExpiryDelta(144), 50, isInitiator = true, None, None, Features.empty)
val remoteParams = RemoteParams(remoteNodeId, 0 sat, UInt64.MaxValue, Some(channelReserve), 1 msat, CltvExpiryDelta(144), 50, randomKey().publicKey, randomKey().publicKey, randomKey().publicKey, randomKey().publicKey, Features.empty, None)
val remoteFundingPubKey = randomKey().publicKey
- val commitmentInput = Funding.makeFundingInputInfo(randomBytes32(), 0, (toLocal + toRemote).truncateToSatoshi, randomKey().publicKey, remoteFundingPubKey)
+ val commitmentInput = Funding.makeFundingInputInfo(randomTxId(), 0, (toLocal + toRemote).truncateToSatoshi, randomKey().publicKey, remoteFundingPubKey)
val localCommit = LocalCommit(0, CommitmentSpec(Set.empty, FeeratePerKw(0 sat), toLocal, toRemote), CommitTxAndRemoteSig(CommitTx(commitmentInput, Transaction(2, Nil, Nil, 0)), ByteVector64.Zeroes), Nil)
- val remoteCommit = RemoteCommit(0, CommitmentSpec(Set.empty, FeeratePerKw(0 sat), toRemote, toLocal), randomBytes32(), randomKey().publicKey)
+ val remoteCommit = RemoteCommit(0, CommitmentSpec(Set.empty, FeeratePerKw(0 sat), toRemote, toLocal), randomTxId(), randomKey().publicKey)
Commitments(
ChannelParams(randomBytes32(), ChannelConfig.standard, ChannelFeatures(), localParams, remoteParams, ChannelFlags(announceChannel = announceChannel)),
CommitmentChanges(LocalChanges(Nil, Nil, Nil), RemoteChanges(Nil, Nil, Nil), localNextHtlcId = 1, remoteNextHtlcId = 1),
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/channel/HelpersSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/channel/HelpersSpec.scala
index cf63e02387..3203b581dd 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/channel/HelpersSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/channel/HelpersSpec.scala
@@ -228,7 +228,7 @@ class HelpersSpec extends TestKitBaseClass with AnyFunSuiteLike with ChannelStat
)
def toClosingTx(txOut: Seq[TxOut]): ClosingTx = {
- ClosingTx(InputInfo(OutPoint(ByteVector32.Zeroes, 0), TxOut(1000 sat, Nil), Nil), Transaction(2, Nil, txOut, 0), None)
+ ClosingTx(InputInfo(OutPoint(TxId(ByteVector32.Zeroes), 0), TxOut(1000 sat, Nil), Nil), Transaction(2, Nil, txOut, 0), None)
}
assert(Closing.MutualClose.checkClosingDustAmounts(toClosingTx(allOutputsAboveDust)))
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/channel/InteractiveTxBuilderSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/channel/InteractiveTxBuilderSpec.scala
index 6a6f779675..2573fa7d96 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/channel/InteractiveTxBuilderSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/channel/InteractiveTxBuilderSpec.scala
@@ -23,7 +23,8 @@ import akka.testkit.TestProbe
import com.softwaremill.quicklens.{ModifyPimp, QuicklensAt}
import fr.acinq.bitcoin.psbt.Psbt
import fr.acinq.bitcoin.scalacompat.Crypto.PublicKey
-import fr.acinq.bitcoin.scalacompat.{Block, ByteVector32, ByteVector64, OP_1, OutPoint, Satoshi, SatoshiLong, Script, ScriptWitness, Transaction, TxOut, addressToPublicKeyScript}
+import fr.acinq.bitcoin.scalacompat.{Block, ByteVector32, ByteVector64, OP_1, OutPoint, Satoshi, SatoshiLong, Script, ScriptWitness, Transaction, TxHash, TxId, TxOut, addressToPublicKeyScript}
+import fr.acinq.eclair.TestUtils.randomTxId
import fr.acinq.eclair.blockchain.OnChainWallet.{FundTransactionResponse, ProcessPsbtResponse}
import fr.acinq.eclair.blockchain.bitcoind.BitcoindService
import fr.acinq.eclair.blockchain.bitcoind.rpc.BitcoinCoreClient.{MempoolTx, Utxo}
@@ -70,7 +71,7 @@ class InteractiveTxBuilderSpec extends TestKitBaseClass with AnyFunSuiteLike wit
txid <- client.publishTransaction(signed.finalTx_opt.toOption.get)
} yield txid
f.pipeTo(probe.ref)
- probe.expectMsgType[ByteVector32]
+ probe.expectMsgType[TxId]
}
private def createInput(channelId: ByteVector32, serialId: UInt64, amount: Satoshi): TxAddInput = {
@@ -105,7 +106,7 @@ class InteractiveTxBuilderSpec extends TestKitBaseClass with AnyFunSuiteLike wit
val fundingPubkeyScript: ByteVector = Script.write(Script.pay2wsh(Scripts.multiSig2of2(fundingParamsB.remoteFundingPubKey, fundingParamsA.remoteFundingPubKey)))
def dummySharedInputB(amount: Satoshi): SharedFundingInput = {
- val inputInfo = InputInfo(OutPoint(randomBytes32(), 3), TxOut(amount, fundingPubkeyScript), Nil)
+ val inputInfo = InputInfo(OutPoint(randomTxId(), 3), TxOut(amount, fundingPubkeyScript), Nil)
val fundingTxIndex = fundingParamsA.sharedInput_opt match {
case Some(input: Multisig2of2Input) => input.fundingTxIndex + 1
case _ => 0
@@ -1034,7 +1035,7 @@ class InteractiveTxBuilderSpec extends TestKitBaseClass with AnyFunSuiteLike wit
val Right(signedTx) = probe.expectMsgType[ProcessPsbtResponse].finalTx_opt
assert(Transaction.write(signedTx).length >= 65_000)
minerWallet.publishTransaction(signedTx).pipeTo(probe.ref)
- probe.expectMsgType[ByteVector32]
+ probe.expectMsgType[TxId]
}
generateBlocks(1)
@@ -1805,7 +1806,7 @@ class InteractiveTxBuilderSpec extends TestKitBaseClass with AnyFunSuiteLike wit
val probe = TestProbe()
walletB.getP2wpkhPubkey().pipeTo(probe.ref)
walletB.sendToPubkeyScript(Script.write(Script.pay2wpkh(probe.expectMsgType[PublicKey])), 75_000 sat, FeeratePerKw(FeeratePerByte(1.sat))).pipeTo(probe.ref)
- probe.expectMsgType[ByteVector32]
+ probe.expectMsgType[TxId]
alice ! Start(alice2bob.ref)
bob ! Start(bob2alice.ref)
@@ -1841,7 +1842,7 @@ class InteractiveTxBuilderSpec extends TestKitBaseClass with AnyFunSuiteLike wit
val probe = TestProbe()
walletB.getReceiveAddress().pipeTo(probe.ref)
walletB.sendToAddress(probe.expectMsgType[String], 75_000 sat, 1).pipeTo(probe.ref)
- probe.expectMsgType[ByteVector32]
+ probe.expectMsgType[TxId]
alice ! Start(alice2bob.ref)
bob ! Start(bob2alice.ref)
@@ -2335,7 +2336,7 @@ class InteractiveTxBuilderSpec extends TestKitBaseClass with AnyFunSuiteLike wit
bob ! Start(probe.ref)
// Alice --- tx_add_input --> Bob
// The input doesn't include the previous transaction but is not the shared input.
- val nonSharedInput = TxAddInput(params.channelId, UInt64(0), OutPoint(randomBytes32(), 7), 0)
+ val nonSharedInput = TxAddInput(params.channelId, UInt64(0), OutPoint(randomTxId(), 7), 0)
bob ! ReceiveMessage(nonSharedInput)
assert(probe.expectMsgType[RemoteFailure].cause == PreviousTxMissing(params.channelId, UInt64(0)))
}
@@ -2438,7 +2439,7 @@ class InteractiveTxBuilderSpec extends TestKitBaseClass with AnyFunSuiteLike wit
probe.expectMsg(txA1.txId)
// we modify remote's input in previous txs, it won't be double spent
- val fakeTxB2 = txB1.modify(_.tx.remoteInputs.at(0).outPoint.hash).setTo(randomBytes32())
+ val fakeTxB2 = txB1.modify(_.tx.remoteInputs.at(0).outPoint.hash).setTo(TxHash(randomBytes32()))
val aliceRbf = fixtureParams.spawnTxBuilderRbfAlice(aliceParams.copy(targetFeerate = FeeratePerKw(10_000 sat)), commitmentA1, Seq(txA1), walletA)
val bobRbf = fixtureParams.spawnTxBuilderRbfBob(bobParams.copy(targetFeerate = FeeratePerKw(10_000 sat)), commitmentB1, Seq(txB1, fakeTxB2), walletB)
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/channel/publish/FinalTxPublisherSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/channel/publish/FinalTxPublisherSpec.scala
index fb4df104f1..8d8d59f9b8 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/channel/publish/FinalTxPublisherSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/channel/publish/FinalTxPublisherSpec.scala
@@ -20,7 +20,7 @@ import akka.actor.typed.ActorRef
import akka.actor.typed.scaladsl.adapter.{ClassicActorSystemOps, TypedActorRefOps, actorRefAdapter}
import akka.pattern.pipe
import akka.testkit.TestProbe
-import fr.acinq.bitcoin.scalacompat.{ByteVector32, SatoshiLong, Transaction}
+import fr.acinq.bitcoin.scalacompat.{SatoshiLong, Transaction, TxId}
import fr.acinq.eclair.blockchain.CurrentBlockHeight
import fr.acinq.eclair.blockchain.WatcherSpec.createSpendP2WPKH
import fr.acinq.eclair.blockchain.bitcoind.BitcoindService
@@ -63,7 +63,7 @@ class FinalTxPublisherSpec extends TestKitBaseClass with AnyFunSuiteLike with Bi
probe.expectMsgType[Seq[Transaction]]
}
- def waitTxInMempool(bitcoinClient: BitcoinCoreClient, txId: ByteVector32, probe: TestProbe): Unit = {
+ def waitTxInMempool(bitcoinClient: BitcoinCoreClient, txId: TxId, probe: TestProbe): Unit = {
awaitCond(getMempool(bitcoinClient, probe).exists(_.txid == txId))
}
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/channel/publish/MempoolTxMonitorSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/channel/publish/MempoolTxMonitorSpec.scala
index e3d9409788..36722db8be 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/channel/publish/MempoolTxMonitorSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/channel/publish/MempoolTxMonitorSpec.scala
@@ -21,7 +21,8 @@ import akka.actor.typed.scaladsl.adapter.{ClassicActorSystemOps, actorRefAdapter
import akka.pattern.pipe
import akka.testkit.TestProbe
import fr.acinq.bitcoin.scalacompat.Crypto.PrivateKey
-import fr.acinq.bitcoin.scalacompat.{ByteVector32, OutPoint, SatoshiLong, Transaction, TxIn}
+import fr.acinq.bitcoin.scalacompat.{OutPoint, SatoshiLong, Transaction, TxId, TxIn}
+import fr.acinq.eclair.TestUtils.randomTxId
import fr.acinq.eclair.blockchain.WatcherSpec.{createSpendManyP2WPKH, createSpendP2WPKH}
import fr.acinq.eclair.blockchain.bitcoind.BitcoindService
import fr.acinq.eclair.blockchain.bitcoind.rpc.BitcoinCoreClient
@@ -29,7 +30,7 @@ import fr.acinq.eclair.channel.publish.MempoolTxMonitor._
import fr.acinq.eclair.channel.publish.TxPublisher.TxPublishContext
import fr.acinq.eclair.channel.publish.TxPublisher.TxRejectedReason._
import fr.acinq.eclair.channel.{TransactionConfirmed, TransactionPublished}
-import fr.acinq.eclair.{TestConstants, TestKitBaseClass, randomBytes32, randomKey}
+import fr.acinq.eclair.{TestConstants, TestKitBaseClass, randomKey}
import org.scalatest.BeforeAndAfterAll
import org.scalatest.funsuite.AnyFunSuiteLike
@@ -69,7 +70,7 @@ class MempoolTxMonitorSpec extends TestKitBaseClass with AnyFunSuiteLike with Bi
probe.expectMsgType[Seq[Transaction]]
}
- def waitTxInMempool(bitcoinClient: BitcoinCoreClient, txId: ByteVector32, probe: TestProbe): Unit = {
+ def waitTxInMempool(bitcoinClient: BitcoinCoreClient, txId: TxId, probe: TestProbe): Unit = {
awaitCond(getMempool(bitcoinClient, probe).exists(_.txid == txId))
}
@@ -165,7 +166,7 @@ class MempoolTxMonitorSpec extends TestKitBaseClass with AnyFunSuiteLike with Bi
import f._
val tx = createSpendP2WPKH(parentTx, priv, priv.publicKey, 5_000 sat, 0, 0)
- val txUnknownInput = tx.copy(txIn = tx.txIn ++ Seq(TxIn(OutPoint(randomBytes32(), 13), Nil, 0)))
+ val txUnknownInput = tx.copy(txIn = tx.txIn ++ Seq(TxIn(OutPoint(randomTxId(), 13), Nil, 0)))
monitor ! Publish(probe.ref, txUnknownInput, txUnknownInput.txIn.head.outPoint, "test-tx", 10 sat)
probe.expectMsg(TxRejected(txUnknownInput.txid, InputGone))
}
@@ -178,7 +179,7 @@ class MempoolTxMonitorSpec extends TestKitBaseClass with AnyFunSuiteLike with Bi
generateBlocks(1)
val tx = createSpendP2WPKH(parentTx, priv, priv.publicKey, 5_000 sat, 0, 0)
- val txUnknownInput = tx.copy(txIn = tx.txIn ++ Seq(TxIn(OutPoint(randomBytes32(), 13), Nil, 0)))
+ val txUnknownInput = tx.copy(txIn = tx.txIn ++ Seq(TxIn(OutPoint(randomTxId(), 13), Nil, 0)))
monitor ! Publish(probe.ref, txUnknownInput, txUnknownInput.txIn.head.outPoint, "test-tx", 10 sat)
probe.expectMsg(TxRejected(txUnknownInput.txid, InputGone))
}
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/channel/publish/ReplaceableTxFunderSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/channel/publish/ReplaceableTxFunderSpec.scala
index e65a69e154..ff7591e67a 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/channel/publish/ReplaceableTxFunderSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/channel/publish/ReplaceableTxFunderSpec.scala
@@ -16,7 +16,8 @@
package fr.acinq.eclair.channel.publish
-import fr.acinq.bitcoin.scalacompat.{ByteVector32, Crypto, OutPoint, SatoshiLong, Script, Transaction, TxIn, TxOut}
+import fr.acinq.bitcoin.scalacompat.{ByteVector32, Crypto, OutPoint, SatoshiLong, Script, Transaction, TxId, TxIn, TxOut}
+import fr.acinq.eclair.TestUtils.randomTxId
import fr.acinq.eclair.blockchain.fee.{ConfirmationTarget, FeeratePerKw}
import fr.acinq.eclair.channel.Helpers.Funding
import fr.acinq.eclair.channel.publish.ReplaceableTxFunder.AdjustPreviousTxOutputResult.{AddWalletInputs, TxOutputAdjusted}
@@ -38,7 +39,7 @@ class ReplaceableTxFunderSpec extends TestKitBaseClass with AnyFunSuiteLike {
private def createAnchorTx(): (CommitTx, ClaimLocalAnchorOutputTx) = {
val anchorScript = Scripts.anchor(PlaceHolderPubKey)
- val commitInput = Funding.makeFundingInputInfo(randomBytes32(), 1, 500 sat, PlaceHolderPubKey, PlaceHolderPubKey)
+ val commitInput = Funding.makeFundingInputInfo(randomTxId(), 1, 500 sat, PlaceHolderPubKey, PlaceHolderPubKey)
val commitTx = Transaction(
2,
Seq(TxIn(commitInput.outPoint, commitInput.redeemScript, 0, Scripts.witness2of2(PlaceHolderSig, PlaceHolderSig, PlaceHolderPubKey, PlaceHolderPubKey))),
@@ -60,7 +61,7 @@ class ReplaceableTxFunderSpec extends TestKitBaseClass with AnyFunSuiteLike {
val htlcTimeoutScript = Scripts.htlcOffered(PlaceHolderPubKey, PlaceHolderPubKey, PlaceHolderPubKey, randomBytes32(), ZeroFeeHtlcTxAnchorOutputsCommitmentFormat)
val commitTx = Transaction(
2,
- Seq(TxIn(OutPoint(randomBytes32(), 1), Script.write(Script.pay2wpkh(PlaceHolderPubKey)), 0, Script.witnessPay2wpkh(PlaceHolderPubKey, PlaceHolderSig))),
+ Seq(TxIn(OutPoint(randomTxId(), 1), Script.write(Script.pay2wpkh(PlaceHolderPubKey)), 0, Script.witnessPay2wpkh(PlaceHolderPubKey, PlaceHolderSig))),
Seq(TxOut(5000 sat, Script.pay2wsh(htlcSuccessScript)), TxOut(4000 sat, Script.pay2wsh(htlcTimeoutScript))),
0
)
@@ -86,15 +87,15 @@ class ReplaceableTxFunderSpec extends TestKitBaseClass with AnyFunSuiteLike {
val htlcSuccessScript = Scripts.htlcReceived(PlaceHolderPubKey, PlaceHolderPubKey, PlaceHolderPubKey, paymentHash, CltvExpiry(0), ZeroFeeHtlcTxAnchorOutputsCommitmentFormat)
val htlcTimeoutScript = Scripts.htlcOffered(PlaceHolderPubKey, PlaceHolderPubKey, PlaceHolderPubKey, randomBytes32(), ZeroFeeHtlcTxAnchorOutputsCommitmentFormat)
val claimHtlcSuccess = ClaimHtlcSuccessWithWitnessData(ClaimHtlcSuccessTx(
- InputInfo(OutPoint(ByteVector32.Zeroes, 3), TxOut(5000 sat, Script.pay2wsh(htlcSuccessScript)), htlcSuccessScript),
- Transaction(2, Seq(TxIn(OutPoint(ByteVector32.Zeroes, 3), ByteVector.empty, 0)), Seq(TxOut(5000 sat, Script.pay2wpkh(PlaceHolderPubKey))), 0),
+ InputInfo(OutPoint(TxId(ByteVector32.Zeroes), 3), TxOut(5000 sat, Script.pay2wsh(htlcSuccessScript)), htlcSuccessScript),
+ Transaction(2, Seq(TxIn(OutPoint(TxId(ByteVector32.Zeroes), 3), ByteVector.empty, 0)), Seq(TxOut(5000 sat, Script.pay2wpkh(PlaceHolderPubKey))), 0),
paymentHash,
5,
ConfirmationTarget.Absolute(BlockHeight(0))
), preimage)
val claimHtlcTimeout = ClaimHtlcTimeoutWithWitnessData(ClaimHtlcTimeoutTx(
- InputInfo(OutPoint(ByteVector32.Zeroes, 7), TxOut(5000 sat, Script.pay2wsh(htlcTimeoutScript)), htlcTimeoutScript),
- Transaction(2, Seq(TxIn(OutPoint(ByteVector32.Zeroes, 7), ByteVector.empty, 0)), Seq(TxOut(5000 sat, Script.pay2wpkh(PlaceHolderPubKey))), 0),
+ InputInfo(OutPoint(TxId(ByteVector32.Zeroes), 7), TxOut(5000 sat, Script.pay2wsh(htlcTimeoutScript)), htlcTimeoutScript),
+ Transaction(2, Seq(TxIn(OutPoint(TxId(ByteVector32.Zeroes), 7), ByteVector.empty, 0)), Seq(TxOut(5000 sat, Script.pay2wpkh(PlaceHolderPubKey))), 0),
7,
ConfirmationTarget.Absolute(BlockHeight(0))
))
@@ -133,8 +134,8 @@ class ReplaceableTxFunderSpec extends TestKitBaseClass with AnyFunSuiteLike {
txIn = Seq(
initialAnchorTx.tx.txIn.head,
// The previous funding attempt added two wallet inputs:
- TxIn(OutPoint(randomBytes32(), 3), ByteVector.empty, 0, Script.witnessPay2wpkh(PlaceHolderPubKey, PlaceHolderSig)),
- TxIn(OutPoint(randomBytes32(), 1), ByteVector.empty, 0, Script.witnessPay2wpkh(PlaceHolderPubKey, PlaceHolderSig))
+ TxIn(OutPoint(randomTxId(), 3), ByteVector.empty, 0, Script.witnessPay2wpkh(PlaceHolderPubKey, PlaceHolderSig)),
+ TxIn(OutPoint(randomTxId(), 1), ByteVector.empty, 0, Script.witnessPay2wpkh(PlaceHolderPubKey, PlaceHolderSig))
),
// And a change output:
txOut = Seq(TxOut(5000 sat, Script.pay2wpkh(PlaceHolderPubKey)))
@@ -173,9 +174,9 @@ class ReplaceableTxFunderSpec extends TestKitBaseClass with AnyFunSuiteLike {
txIn = Seq(
initialHtlcTx.txInfo.tx.txIn.head,
// The previous funding attempt added three wallet inputs:
- TxIn(OutPoint(randomBytes32(), 3), ByteVector.empty, 0, Script.witnessPay2wpkh(PlaceHolderPubKey, PlaceHolderSig)),
- TxIn(OutPoint(randomBytes32(), 1), ByteVector.empty, 0, Script.witnessPay2wpkh(PlaceHolderPubKey, PlaceHolderSig)),
- TxIn(OutPoint(randomBytes32(), 5), ByteVector.empty, 0, Script.witnessPay2wpkh(PlaceHolderPubKey, PlaceHolderSig))
+ TxIn(OutPoint(randomTxId(), 3), ByteVector.empty, 0, Script.witnessPay2wpkh(PlaceHolderPubKey, PlaceHolderSig)),
+ TxIn(OutPoint(randomTxId(), 1), ByteVector.empty, 0, Script.witnessPay2wpkh(PlaceHolderPubKey, PlaceHolderSig)),
+ TxIn(OutPoint(randomTxId(), 5), ByteVector.empty, 0, Script.witnessPay2wpkh(PlaceHolderPubKey, PlaceHolderSig))
),
txOut = Seq(
initialHtlcTx.txInfo.tx.txOut.head,
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/channel/publish/ReplaceableTxPublisherSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/channel/publish/ReplaceableTxPublisherSpec.scala
index 60b06dd0bf..de7327fa87 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/channel/publish/ReplaceableTxPublisherSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/channel/publish/ReplaceableTxPublisherSpec.scala
@@ -22,7 +22,7 @@ import akka.pattern.pipe
import akka.testkit.{TestFSMRef, TestProbe}
import com.softwaremill.quicklens.ModifyPimp
import fr.acinq.bitcoin.scalacompat.Crypto.PublicKey
-import fr.acinq.bitcoin.scalacompat.{Block, BtcAmount, ByteVector32, MilliBtcDouble, MnemonicCode, OutPoint, SatoshiLong, Transaction}
+import fr.acinq.bitcoin.scalacompat.{Block, BtcAmount, MilliBtcDouble, MnemonicCode, OutPoint, SatoshiLong, Transaction, TxId}
import fr.acinq.eclair.NotificationsLogger.NotifyNodeOperator
import fr.acinq.eclair.blockchain.bitcoind.BitcoindService
import fr.acinq.eclair.blockchain.bitcoind.ZmqWatcher._
@@ -114,7 +114,7 @@ class ReplaceableTxPublisherSpec extends TestKitBaseClass with AnyFunSuiteLike w
})
}
- def isInMempool(txid: ByteVector32): Boolean = {
+ def isInMempool(txid: TxId): Boolean = {
getMempool().exists(_.txid == txid)
}
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/channel/publish/TxPublisherSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/channel/publish/TxPublisherSpec.scala
index 7e6fa660c1..2e2cbf577d 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/channel/publish/TxPublisherSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/channel/publish/TxPublisherSpec.scala
@@ -21,6 +21,7 @@ import akka.actor.typed.scaladsl.ActorContext
import akka.actor.typed.scaladsl.adapter.{ClassicActorSystemOps, TypedActorRefOps, actorRefAdapter}
import akka.testkit.TestProbe
import fr.acinq.bitcoin.scalacompat.{OutPoint, SatoshiLong, Transaction, TxIn, TxOut}
+import fr.acinq.eclair.TestUtils.randomTxId
import fr.acinq.eclair.blockchain.CurrentBlockHeight
import fr.acinq.eclair.blockchain.fee.{ConfirmationPriority, ConfirmationTarget}
import fr.acinq.eclair.channel.publish
@@ -72,7 +73,7 @@ class TxPublisherSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike {
test("publish final tx") { f =>
import f._
- val tx = Transaction(2, TxIn(OutPoint(randomBytes32(), 1), Nil, 0) :: Nil, Nil, 0)
+ val tx = Transaction(2, TxIn(OutPoint(randomTxId(), 1), Nil, 0) :: Nil, Nil, 0)
val cmd = PublishFinalTx(tx, tx.txIn.head.outPoint, "final-tx", 5 sat, None)
txPublisher ! cmd
val child = factory.expectMsgType[FinalTxPublisherSpawned].actor
@@ -82,7 +83,7 @@ class TxPublisherSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike {
test("publish final tx duplicate") { f =>
import f._
- val input = OutPoint(randomBytes32(), 1)
+ val input = OutPoint(randomTxId(), 1)
val tx1 = Transaction(2, TxIn(input, Nil, 0) :: Nil, Nil, 0)
val cmd1 = PublishFinalTx(tx1, input, "final-tx", 10 sat, None)
txPublisher ! cmd1
@@ -93,7 +94,7 @@ class TxPublisherSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike {
factory.expectNoMessage(100 millis)
// But a different tx spending the same main input is allowed:
- val tx2 = tx1.copy(txIn = tx1.txIn ++ Seq(TxIn(OutPoint(randomBytes32(), 0), Nil, 0)))
+ val tx2 = tx1.copy(txIn = tx1.txIn ++ Seq(TxIn(OutPoint(randomTxId(), 0), Nil, 0)))
val cmd2 = PublishFinalTx(tx2, input, "another-final-tx", 0 sat, None)
txPublisher ! cmd2
factory.expectMsgType[FinalTxPublisherSpawned]
@@ -103,7 +104,7 @@ class TxPublisherSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike {
import f._
val confirmBefore = ConfirmationTarget.Absolute(nodeParams.currentBlockHeight + 12)
- val input = OutPoint(randomBytes32(), 3)
+ val input = OutPoint(randomTxId(), 3)
val cmd = PublishReplaceableTx(ClaimLocalAnchorOutputTx(InputInfo(input, TxOut(25_000 sat, Nil), Nil), Transaction(2, TxIn(input, Nil, 0) :: Nil, Nil, 0), confirmBefore), null)
txPublisher ! cmd
val child = factory.expectMsgType[ReplaceableTxPublisherSpawned].actor
@@ -115,7 +116,7 @@ class TxPublisherSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike {
import f._
val confirmBefore = nodeParams.currentBlockHeight + 12
- val input = OutPoint(randomBytes32(), 3)
+ val input = OutPoint(randomTxId(), 3)
val anchorTx = ClaimLocalAnchorOutputTx(InputInfo(input, TxOut(25_000 sat, Nil), Nil), Transaction(2, TxIn(input, Nil, 0) :: Nil, Nil, 0), ConfirmationTarget.Priority(ConfirmationPriority.Medium))
val cmd = PublishReplaceableTx(anchorTx, null)
txPublisher ! cmd
@@ -161,14 +162,14 @@ class TxPublisherSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike {
test("stop publishing attempts when transaction confirms") { f =>
import f._
- val input = OutPoint(randomBytes32(), 3)
+ val input = OutPoint(randomTxId(), 3)
val tx1 = Transaction(2, TxIn(input, Nil, 0) :: Nil, Nil, 0)
val cmd1 = PublishFinalTx(tx1, input, "final-tx-1", 5 sat, None)
txPublisher ! cmd1
val attempt1 = factory.expectMsgType[FinalTxPublisherSpawned].actor
attempt1.expectMsgType[FinalTxPublisher.Publish]
- val tx2 = Transaction(2, TxIn(input, Nil, 0) :: TxIn(OutPoint(randomBytes32(), 0), Nil, 3) :: Nil, Nil, 0)
+ val tx2 = Transaction(2, TxIn(input, Nil, 0) :: TxIn(OutPoint(randomTxId(), 0), Nil, 3) :: Nil, Nil, 0)
val cmd2 = PublishFinalTx(tx2, input, "final-tx-2", 15 sat, None)
txPublisher ! cmd2
val attempt2 = factory.expectMsgType[FinalTxPublisherSpawned].actor
@@ -189,7 +190,7 @@ class TxPublisherSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike {
test("publishing attempt fails (wallet input gone)") { f =>
import f._
- val input = OutPoint(randomBytes32(), 3)
+ val input = OutPoint(randomTxId(), 3)
val tx1 = Transaction(2, TxIn(input, Nil, 0) :: Nil, Nil, 0)
val cmd1 = PublishFinalTx(tx1, input, "final-tx-1", 0 sat, None)
txPublisher ! cmd1
@@ -213,7 +214,7 @@ class TxPublisherSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike {
test("publishing attempt fails (main input gone)") { f =>
import f._
- val input = OutPoint(randomBytes32(), 3)
+ val input = OutPoint(randomTxId(), 3)
val tx = Transaction(2, TxIn(input, Nil, 0) :: Nil, Nil, 0)
val cmd = PublishFinalTx(tx, input, "final-tx", 0 sat, None)
txPublisher ! cmd
@@ -234,7 +235,7 @@ class TxPublisherSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike {
import f._
val target = nodeParams.currentBlockHeight + 12
- val input = OutPoint(randomBytes32(), 7)
+ val input = OutPoint(randomTxId(), 7)
val paymentHash = randomBytes32()
val cmd = PublishReplaceableTx(HtlcSuccessTx(InputInfo(input, TxOut(25_000 sat, Nil), Nil), Transaction(2, TxIn(input, Nil, 0) :: Nil, Nil, 0), paymentHash, 3, ConfirmationTarget.Absolute(target)), null)
txPublisher ! cmd
@@ -254,13 +255,13 @@ class TxPublisherSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike {
test("publishing attempt fails (transaction skipped)") { f =>
import f._
- val tx1 = Transaction(2, TxIn(OutPoint(randomBytes32(), 1), Nil, 0) :: Nil, Nil, 0)
+ val tx1 = Transaction(2, TxIn(OutPoint(randomTxId(), 1), Nil, 0) :: Nil, Nil, 0)
val cmd1 = PublishFinalTx(tx1, tx1.txIn.head.outPoint, "final-tx-1", 0 sat, None)
txPublisher ! cmd1
val attempt1 = factory.expectMsgType[FinalTxPublisherSpawned]
attempt1.actor.expectMsgType[FinalTxPublisher.Publish]
- val tx2 = Transaction(2, TxIn(OutPoint(randomBytes32(), 0), Nil, 0) :: Nil, Nil, 0)
+ val tx2 = Transaction(2, TxIn(OutPoint(randomTxId(), 0), Nil, 0) :: Nil, Nil, 0)
val cmd2 = PublishFinalTx(tx2, tx2.txIn.head.outPoint, "final-tx-2", 5 sat, None)
txPublisher ! cmd2
val attempt2 = factory.expectMsgType[FinalTxPublisherSpawned]
@@ -281,7 +282,7 @@ class TxPublisherSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike {
test("publishing attempt fails (unconfirmed conflicting raw transaction)") { f =>
import f._
- val tx = Transaction(2, TxIn(OutPoint(randomBytes32(), 1), Nil, 0) :: Nil, Nil, 0)
+ val tx = Transaction(2, TxIn(OutPoint(randomTxId(), 1), Nil, 0) :: Nil, Nil, 0)
val cmd = PublishFinalTx(tx, tx.txIn.head.outPoint, "final-tx", 5 sat, None)
txPublisher ! cmd
val attempt = factory.expectMsgType[FinalTxPublisherSpawned]
@@ -298,7 +299,7 @@ class TxPublisherSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike {
test("publishing attempt fails (unconfirmed conflicting replaceable transaction)") { f =>
import f._
- val input = OutPoint(randomBytes32(), 7)
+ val input = OutPoint(randomTxId(), 7)
val paymentHash = randomBytes32()
val cmd = PublishReplaceableTx(HtlcSuccessTx(InputInfo(input, TxOut(25_000 sat, Nil), Nil), Transaction(2, TxIn(input, Nil, 0) :: Nil, Nil, 0), paymentHash, 3, ConfirmationTarget.Absolute(nodeParams.currentBlockHeight)), null)
txPublisher ! cmd
@@ -318,7 +319,7 @@ class TxPublisherSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike {
test("publishing attempt fails (confirmed conflicting transaction)") { f =>
import f._
- val tx = Transaction(2, TxIn(OutPoint(randomBytes32(), 1), Nil, 0) :: Nil, Nil, 0)
+ val tx = Transaction(2, TxIn(OutPoint(randomTxId(), 1), Nil, 0) :: Nil, Nil, 0)
val cmd = PublishFinalTx(tx, tx.txIn.head.outPoint, "final-tx", 5 sat, None)
txPublisher ! cmd
val attempt = factory.expectMsgType[FinalTxPublisherSpawned]
@@ -335,7 +336,7 @@ class TxPublisherSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike {
test("publishing attempt fails (unknown failure)") { f =>
import f._
- val tx = Transaction(2, TxIn(OutPoint(randomBytes32(), 1), Nil, 0) :: Nil, Nil, 0)
+ val tx = Transaction(2, TxIn(OutPoint(randomTxId(), 1), Nil, 0) :: Nil, Nil, 0)
val cmd = PublishFinalTx(tx, tx.txIn.head.outPoint, "final-tx", 5 sat, None)
txPublisher ! cmd
val attempt = factory.expectMsgType[FinalTxPublisherSpawned]
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/a/WaitForOpenDualFundedChannelStateSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/a/WaitForOpenDualFundedChannelStateSpec.scala
index daf3595304..038892db9e 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/a/WaitForOpenDualFundedChannelStateSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/a/WaitForOpenDualFundedChannelStateSpec.scala
@@ -18,7 +18,7 @@ package fr.acinq.eclair.channel.states.a
import akka.actor.typed.scaladsl.adapter.ClassicActorRefOps
import akka.testkit.{TestFSMRef, TestProbe}
-import fr.acinq.bitcoin.scalacompat.{Block, ByteVector32, SatoshiLong}
+import fr.acinq.bitcoin.scalacompat.{Block, BlockHash, ByteVector32, SatoshiLong}
import fr.acinq.eclair.TestConstants.{Alice, Bob}
import fr.acinq.eclair.channel._
import fr.acinq.eclair.channel.fsm.Channel
@@ -120,7 +120,7 @@ class WaitForOpenDualFundedChannelStateSpec extends TestKitBaseClass with Fixtur
test("recv OpenDualFundedChannel (invalid chain)", Tag(ChannelStateTestsTags.DualFunding), Tag(ChannelStateTestsTags.AnchorOutputsZeroFeeHtlcTxs)) { f =>
import f._
val open = alice2bob.expectMsgType[OpenDualFundedChannel]
- val chain = randomBytes32()
+ val chain = BlockHash(randomBytes32())
bob ! open.copy(chainHash = chain)
val error = bob2alice.expectMsgType[Error]
assert(error == Error(open.temporaryChannelId, InvalidChainHash(open.temporaryChannelId, Block.RegtestGenesisBlock.hash, chain).getMessage))
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/b/WaitForDualFundingSignedStateSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/b/WaitForDualFundingSignedStateSpec.scala
index 62a6a152be..de8b70043f 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/b/WaitForDualFundingSignedStateSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/b/WaitForDualFundingSignedStateSpec.scala
@@ -18,7 +18,8 @@ package fr.acinq.eclair.channel.states.b
import akka.actor.typed.scaladsl.adapter.ClassicActorRefOps
import akka.testkit.{TestFSMRef, TestProbe}
-import fr.acinq.bitcoin.scalacompat.{ByteVector32, ByteVector64, SatoshiLong}
+import fr.acinq.bitcoin.scalacompat.{ByteVector32, ByteVector64, SatoshiLong, TxId}
+import fr.acinq.eclair.TestUtils.randomTxId
import fr.acinq.eclair.blockchain.SingleKeyOnChainWallet
import fr.acinq.eclair.blockchain.bitcoind.ZmqWatcher.{WatchFundingConfirmed, WatchPublished}
import fr.acinq.eclair.blockchain.fee.FeeratePerKw
@@ -29,7 +30,7 @@ import fr.acinq.eclair.channel.publish.TxPublisher
import fr.acinq.eclair.channel.states.{ChannelStateTestsBase, ChannelStateTestsTags}
import fr.acinq.eclair.io.Peer.OpenChannelResponse
import fr.acinq.eclair.wire.protocol._
-import fr.acinq.eclair.{Features, MilliSatoshiLong, TestConstants, TestKitBaseClass, ToMilliSatoshiConversion, randomBytes32}
+import fr.acinq.eclair.{Features, MilliSatoshiLong, TestConstants, TestKitBaseClass, ToMilliSatoshiConversion}
import org.scalatest.funsuite.FixtureAnyFunSuiteLike
import org.scalatest.{Outcome, Tag}
@@ -219,14 +220,14 @@ class WaitForDualFundingSignedStateSpec extends TestKitBaseClass with FixtureAny
val bobSigs = bob2alice.expectMsgType[TxSignatures]
bob2blockchain.expectMsgType[WatchFundingConfirmed]
- bob2alice.forward(alice, bobSigs.copy(txHash = randomBytes32(), witnesses = Nil))
+ bob2alice.forward(alice, bobSigs.copy(txId = randomTxId(), witnesses = Nil))
alice2bob.expectMsgType[Error]
awaitCond(wallet.rolledback.size == 1)
aliceListener.expectMsgType[ChannelAborted]
awaitCond(alice.stateName == CLOSED)
// Bob has sent his signatures already, so he cannot close the channel yet.
- alice2bob.forward(bob, TxSignatures(channelId(alice), randomBytes32(), Nil))
+ alice2bob.forward(bob, TxSignatures(channelId(alice), randomTxId(), Nil))
bob2alice.expectMsgType[Error]
bob2blockchain.expectNoMessage(100 millis)
assert(bob.stateName == WAIT_FOR_DUAL_FUNDING_CONFIRMED)
@@ -390,7 +391,7 @@ class WaitForDualFundingSignedStateSpec extends TestKitBaseClass with FixtureAny
assert(listener.expectMsgType[TransactionPublished].tx.txid == fundingTxId)
}
- private def reconnect(f: FixtureParam, fundingTxId: ByteVector32): Unit = {
+ private def reconnect(f: FixtureParam, fundingTxId: TxId): Unit = {
import f._
val listener = TestProbe()
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/e/NormalSplicesStateSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/e/NormalSplicesStateSpec.scala
index a78aa78959..5705a2a1d8 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/e/NormalSplicesStateSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/e/NormalSplicesStateSpec.scala
@@ -653,10 +653,10 @@ class NormalSplicesStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLik
// splice 1 confirms
alice ! WatchFundingConfirmedTriggered(BlockHeight(400000), 42, fundingTx1)
- alice2bob.expectMsgTypeHaving[SpliceLocked](_.fundingTxid == fundingTx1.txid)
+ alice2bob.expectMsgTypeHaving[SpliceLocked](_.fundingTxId == fundingTx1.txid)
alice2bob.forward(bob)
bob ! WatchFundingConfirmedTriggered(BlockHeight(400000), 42, fundingTx1)
- bob2alice.expectMsgTypeHaving[SpliceLocked](_.fundingTxid == fundingTx1.txid)
+ bob2alice.expectMsgTypeHaving[SpliceLocked](_.fundingTxId == fundingTx1.txid)
bob2alice.forward(alice)
alice2blockchain.expectWatchFundingSpent(fundingTx1.txid, Some(Set(fundingTx2.txid, commitAlice1.txid, commitBob1.txid)))
bob2blockchain.expectWatchFundingSpent(fundingTx1.txid, Some(Set(fundingTx2.txid, commitAlice1.txid, commitBob1.txid)))
@@ -665,10 +665,10 @@ class NormalSplicesStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLik
// splice 2 confirms
alice ! WatchFundingConfirmedTriggered(BlockHeight(400000), 42, fundingTx2)
- alice2bob.expectMsgTypeHaving[SpliceLocked](_.fundingTxid == fundingTx2.txid)
+ alice2bob.expectMsgTypeHaving[SpliceLocked](_.fundingTxId == fundingTx2.txid)
alice2bob.forward(bob)
bob ! WatchFundingConfirmedTriggered(BlockHeight(400000), 42, fundingTx2)
- bob2alice.expectMsgTypeHaving[SpliceLocked](_.fundingTxid == fundingTx2.txid)
+ bob2alice.expectMsgTypeHaving[SpliceLocked](_.fundingTxId == fundingTx2.txid)
bob2alice.forward(alice)
alice2blockchain.expectWatchFundingSpent(fundingTx2.txid, Some(Set(commitAlice2.txid, commitBob2.txid)))
bob2blockchain.expectWatchFundingSpent(fundingTx2.txid, Some(Set(commitAlice2.txid, commitBob2.txid)))
@@ -689,9 +689,9 @@ class NormalSplicesStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLik
bob2blockchain.expectWatchFundingConfirmed(fundingTx1.txid)
bob2blockchain.expectNoMessage(100 millis)
- assert(alice2bob.expectMsgType[SpliceLocked].fundingTxid == fundingTx1.txid)
+ assert(alice2bob.expectMsgType[SpliceLocked].fundingTxId == fundingTx1.txid)
alice2bob.forward(bob)
- assert(bob2alice.expectMsgType[SpliceLocked].fundingTxid == fundingTx1.txid)
+ assert(bob2alice.expectMsgType[SpliceLocked].fundingTxId == fundingTx1.txid)
bob2alice.forward(alice)
awaitCond(alice.stateData.asInstanceOf[DATA_NORMAL].commitments.active.size == 1)
@@ -709,10 +709,10 @@ class NormalSplicesStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLik
// splice 2 confirms
alice ! WatchFundingConfirmedTriggered(BlockHeight(400000), 42, fundingTx2)
- alice2bob.expectMsgTypeHaving[SpliceLocked](_.fundingTxid == fundingTx2.txid)
+ alice2bob.expectMsgTypeHaving[SpliceLocked](_.fundingTxId == fundingTx2.txid)
alice2bob.forward(bob)
bob ! WatchFundingConfirmedTriggered(BlockHeight(400000), 42, fundingTx2)
- bob2alice.expectMsgTypeHaving[SpliceLocked](_.fundingTxid == fundingTx2.txid)
+ bob2alice.expectMsgTypeHaving[SpliceLocked](_.fundingTxId == fundingTx2.txid)
bob2alice.forward(alice)
alice2blockchain.expectWatchFundingSpent(fundingTx2.txid, Some(Set(commitAlice2.txid, commitBob2.txid)))
bob2blockchain.expectWatchFundingSpent(fundingTx2.txid, Some(Set(commitAlice2.txid, commitBob2.txid)))
@@ -737,10 +737,10 @@ class NormalSplicesStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLik
// splice 1 confirms on alice, splice 2 confirms on bob
alice ! WatchFundingConfirmedTriggered(BlockHeight(400000), 42, fundingTx1)
- alice2bob.expectMsgTypeHaving[SpliceLocked](_.fundingTxid == fundingTx1.txid)
+ alice2bob.expectMsgTypeHaving[SpliceLocked](_.fundingTxId == fundingTx1.txid)
alice2bob.forward(bob)
bob ! WatchFundingConfirmedTriggered(BlockHeight(400000), 42, fundingTx2)
- bob2alice.expectMsgTypeHaving[SpliceLocked](_.fundingTxid == fundingTx2.txid)
+ bob2alice.expectMsgTypeHaving[SpliceLocked](_.fundingTxId == fundingTx2.txid)
bob2alice.forward(alice)
alice2blockchain.expectWatchFundingSpent(fundingTx1.txid)
bob2blockchain.expectWatchFundingSpent(fundingTx2.txid)
@@ -751,7 +751,7 @@ class NormalSplicesStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLik
// splice 2 confirms on bob, splice 1 confirms on alice
alice ! WatchFundingConfirmedTriggered(BlockHeight(400000), 42, fundingTx2)
- alice2bob.expectMsgTypeHaving[SpliceLocked](_.fundingTxid == fundingTx2.txid)
+ alice2bob.expectMsgTypeHaving[SpliceLocked](_.fundingTxId == fundingTx2.txid)
alice2bob.forward(bob)
bob ! WatchFundingConfirmedTriggered(BlockHeight(400000), 42, fundingTx1)
bob2alice.expectNoMessage(100 millis)
@@ -1236,7 +1236,7 @@ class NormalSplicesStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLik
awaitCond(bob.stateData.asInstanceOf[DATA_NORMAL].spliceStatus == SpliceStatus.NoSplice)
val spliceTx = alice.stateData.asInstanceOf[DATA_NORMAL].commitments.latest.localFundingStatus.signedTx_opt.get
alice ! WatchPublishedTriggered(spliceTx)
- assert(alice2bob.expectMsgType[SpliceLocked].fundingTxid == spliceTxId) // Bob doesn't receive Alice's splice_locked
+ assert(alice2bob.expectMsgType[SpliceLocked].fundingTxId == spliceTxId) // Bob doesn't receive Alice's splice_locked
disconnect(f)
val (channelReestablishAlice, channelReestablishBob) = reconnect(f, interceptFundingDeeplyBuried = false)
@@ -1248,7 +1248,7 @@ class NormalSplicesStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLik
alice2bob.expectMsgType[TxSignatures]
alice2bob.forward(bob)
- assert(alice2bob.expectMsgType[SpliceLocked].fundingTxid == spliceTx.txid)
+ assert(alice2bob.expectMsgType[SpliceLocked].fundingTxId == spliceTx.txid)
alice2bob.forward(bob)
bob2alice.expectNoMessage(100 millis)
bob ! WatchFundingConfirmedTriggered(BlockHeight(42), 0, spliceTx)
@@ -1343,58 +1343,58 @@ class NormalSplicesStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLik
// splice 1 confirms on alice's side
watchConfirmed1a.replyTo ! WatchFundingConfirmedTriggered(BlockHeight(400000), 42, fundingTx1)
- assert(alice2bob.expectMsgType[SpliceLocked].fundingTxid == fundingTx1.txid)
+ assert(alice2bob.expectMsgType[SpliceLocked].fundingTxId == fundingTx1.txid)
alice2bob.forward(bob)
alice2blockchain.expectMsgType[WatchFundingSpent]
disconnect(f)
reconnect(f)
- assert(alice2bob.expectMsgType[SpliceLocked].fundingTxid == fundingTx1.txid)
+ assert(alice2bob.expectMsgType[SpliceLocked].fundingTxId == fundingTx1.txid)
alice2bob.forward(bob)
// splice 2 confirms on alice's side
watchConfirmed2a.replyTo ! WatchFundingConfirmedTriggered(BlockHeight(400000), 42, fundingTx2)
- assert(alice2bob.expectMsgType[SpliceLocked].fundingTxid == fundingTx2.txid)
+ assert(alice2bob.expectMsgType[SpliceLocked].fundingTxId == fundingTx2.txid)
alice2bob.forward(bob)
alice2blockchain.expectMsgType[WatchFundingSpent]
disconnect(f)
reconnect(f)
- assert(alice2bob.expectMsgType[SpliceLocked].fundingTxid == fundingTx2.txid)
+ assert(alice2bob.expectMsgType[SpliceLocked].fundingTxId == fundingTx2.txid)
alice2bob.forward(bob)
alice2bob.expectNoMessage(100 millis)
bob2alice.expectNoMessage(100 millis)
// splice 1 confirms on bob's side
watchConfirmed1b.replyTo ! WatchFundingConfirmedTriggered(BlockHeight(400000), 42, fundingTx1)
- assert(bob2alice.expectMsgType[SpliceLocked].fundingTxid == fundingTx1.txid)
+ assert(bob2alice.expectMsgType[SpliceLocked].fundingTxId == fundingTx1.txid)
bob2alice.forward(alice)
bob2blockchain.expectMsgType[WatchFundingSpent]
disconnect(f)
reconnect(f)
- assert(alice2bob.expectMsgType[SpliceLocked].fundingTxid == fundingTx2.txid)
+ assert(alice2bob.expectMsgType[SpliceLocked].fundingTxId == fundingTx2.txid)
alice2bob.forward(bob)
- assert(bob2alice.expectMsgType[SpliceLocked].fundingTxid == fundingTx1.txid)
+ assert(bob2alice.expectMsgType[SpliceLocked].fundingTxId == fundingTx1.txid)
bob2alice.forward(alice)
alice2bob.expectNoMessage(100 millis)
bob2alice.expectNoMessage(100 millis)
// splice 2 confirms on bob's side
watchConfirmed2b.replyTo ! WatchFundingConfirmedTriggered(BlockHeight(400000), 42, fundingTx2)
- assert(bob2alice.expectMsgType[SpliceLocked].fundingTxid == fundingTx2.txid)
+ assert(bob2alice.expectMsgType[SpliceLocked].fundingTxId == fundingTx2.txid)
bob2blockchain.expectMsgType[WatchFundingSpent]
// NB: we disconnect *before* transmitting the splice_confirmed to alice
disconnect(f)
reconnect(f)
- assert(alice2bob.expectMsgType[SpliceLocked].fundingTxid == fundingTx2.txid)
+ assert(alice2bob.expectMsgType[SpliceLocked].fundingTxId == fundingTx2.txid)
alice2bob.forward(bob)
- assert(bob2alice.expectMsgType[SpliceLocked].fundingTxid == fundingTx2.txid)
+ assert(bob2alice.expectMsgType[SpliceLocked].fundingTxId == fundingTx2.txid)
// this time alice received the splice_confirmed for funding tx 2
bob2alice.forward(alice)
alice2bob.expectNoMessage(100 millis)
@@ -1403,9 +1403,9 @@ class NormalSplicesStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLik
disconnect(f)
reconnect(f)
- assert(alice2bob.expectMsgType[SpliceLocked].fundingTxid == fundingTx2.txid)
+ assert(alice2bob.expectMsgType[SpliceLocked].fundingTxId == fundingTx2.txid)
alice2bob.forward(bob)
- assert(bob2alice.expectMsgType[SpliceLocked].fundingTxid == fundingTx2.txid)
+ assert(bob2alice.expectMsgType[SpliceLocked].fundingTxId == fundingTx2.txid)
bob2alice.forward(alice)
alice2bob.expectNoMessage(100 millis)
bob2alice.expectNoMessage(100 millis)
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 037782e285..d49bda0d51 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
@@ -3476,7 +3476,7 @@ class NormalStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with
alice2blockchain.expectMsgType[WatchOutputSpent], // htlc 3
alice2blockchain.expectMsgType[WatchOutputSpent], // htlc 4
alice2blockchain.expectMsgType[WatchOutputSpent], // local anchor
- ).map(w => OutPoint(w.txId.reverse, w.outputIndex)).toSet
+ ).map(w => OutPoint(w.txId, w.outputIndex)).toSet
val localCommitPublished = alice.stateData.asInstanceOf[DATA_CLOSING].localCommitPublished.get
assert(watchedOutputs == localCommitPublished.htlcTxs.keySet + localAnchor.txInfo.input.outPoint)
alice2blockchain.expectNoMessage(1 second)
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 3360ee233b..0f8fc3c752 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
@@ -21,6 +21,7 @@ import akka.testkit.{TestFSMRef, TestProbe}
import fr.acinq.bitcoin.ScriptFlags
import fr.acinq.bitcoin.scalacompat.Crypto.PrivateKey
import fr.acinq.bitcoin.scalacompat.{ByteVector32, ByteVector64, Crypto, OutPoint, SatoshiLong, Script, Transaction, TxIn, TxOut}
+import fr.acinq.eclair.TestUtils.randomTxId
import fr.acinq.eclair.blockchain.bitcoind.ZmqWatcher._
import fr.acinq.eclair.blockchain.fee.{ConfirmationPriority, ConfirmationTarget, FeeratePerKw, FeeratesPerKw}
import fr.acinq.eclair.channel._
@@ -380,14 +381,14 @@ class ClosingStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with
channelUpdateListener.expectMsgType[LocalChannelDown]
// scenario 1: bob claims the htlc output from the commit tx using its preimage
- val claimHtlcSuccessFromCommitTx = Transaction(version = 0, txIn = TxIn(outPoint = OutPoint(randomBytes32(), 0), signatureScript = ByteVector.empty, sequence = 0, witness = Scripts.witnessClaimHtlcSuccessFromCommitTx(Transactions.PlaceHolderSig, ra1, ByteVector.fill(130)(33))) :: Nil, txOut = Nil, lockTime = 0)
+ val claimHtlcSuccessFromCommitTx = Transaction(version = 0, txIn = TxIn(outPoint = OutPoint(randomTxId(), 0), signatureScript = ByteVector.empty, sequence = 0, witness = Scripts.witnessClaimHtlcSuccessFromCommitTx(Transactions.PlaceHolderSig, ra1, ByteVector.fill(130)(33))) :: Nil, txOut = Nil, lockTime = 0)
alice ! WatchOutputSpentTriggered(claimHtlcSuccessFromCommitTx)
val fulfill1 = alice2relayer.expectMsgType[RES_ADD_SETTLED[Origin, HtlcResult.OnChainFulfill]]
assert(fulfill1.htlc == htlca1)
assert(fulfill1.result.paymentPreimage == ra1)
// scenario 2: bob claims the htlc output from his own commit tx using its preimage (let's assume both parties had published their commitment tx)
- val claimHtlcSuccessTx = Transaction(version = 0, txIn = TxIn(outPoint = OutPoint(randomBytes32(), 0), signatureScript = ByteVector.empty, sequence = 0, witness = Scripts.witnessHtlcSuccess(Transactions.PlaceHolderSig, Transactions.PlaceHolderSig, ra1, ByteVector.fill(130)(33), Transactions.DefaultCommitmentFormat)) :: Nil, txOut = Nil, lockTime = 0)
+ val claimHtlcSuccessTx = Transaction(version = 0, txIn = TxIn(outPoint = OutPoint(randomTxId(), 0), signatureScript = ByteVector.empty, sequence = 0, witness = Scripts.witnessHtlcSuccess(Transactions.PlaceHolderSig, Transactions.PlaceHolderSig, ra1, ByteVector.fill(130)(33), Transactions.DefaultCommitmentFormat)) :: Nil, txOut = Nil, lockTime = 0)
alice ! WatchOutputSpentTriggered(claimHtlcSuccessTx)
val fulfill2 = alice2relayer.expectMsgType[RES_ADD_SETTLED[Origin, HtlcResult.OnChainFulfill]]
assert(fulfill2.htlc == htlca1)
@@ -1584,7 +1585,7 @@ class ClosingStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with
alice2blockchain.expectNoMessage(1 second)
// bob RBFs his htlc-success with a different transaction
- val bobHtlcSuccessTx2 = bobHtlcSuccessTx1.tx.copy(txIn = TxIn(OutPoint(randomBytes32(), 0), Nil, 0) +: bobHtlcSuccessTx1.tx.txIn)
+ val bobHtlcSuccessTx2 = bobHtlcSuccessTx1.tx.copy(txIn = TxIn(OutPoint(randomTxId(), 0), Nil, 0) +: bobHtlcSuccessTx1.tx.txIn)
assert(bobHtlcSuccessTx2.txid !== bobHtlcSuccessTx1.tx.txid)
alice ! WatchOutputSpentTriggered(bobHtlcSuccessTx2)
awaitCond(alice.stateData.asInstanceOf[DATA_CLOSING].revokedCommitPublished.head.claimHtlcDelayedPenaltyTxs.size == 3)
@@ -1670,7 +1671,7 @@ class ClosingStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with
val bobHtlcTx = Transaction(
2,
Seq(
- TxIn(OutPoint(randomBytes32(), 4), Nil, 1), // utxo used for fee bumping
+ TxIn(OutPoint(randomTxId(), 4), Nil, 1), // utxo used for fee bumping
bobHtlcTxs(0).tx.txIn.head,
bobHtlcTxs(1).tx.txIn.head,
bobHtlcTxs(2).tx.txIn.head,
@@ -1706,7 +1707,7 @@ class ClosingStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with
alice2blockchain.expectMsgType[WatchOutputSpent],
alice2blockchain.expectMsgType[WatchOutputSpent],
alice2blockchain.expectMsgType[WatchOutputSpent]
- ).map(w => OutPoint(w.txId.reverse, w.outputIndex)).toSet
+ ).map(w => OutPoint(w.txId, w.outputIndex)).toSet
assert(watchedOutpoints == spentOutpoints)
alice2blockchain.expectNoMessage(1 second)
}
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/crypto/keymanager/LocalOnChainKeyManagerSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/crypto/keymanager/LocalOnChainKeyManagerSpec.scala
index b550e452ea..9a4d4303f6 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/crypto/keymanager/LocalOnChainKeyManagerSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/crypto/keymanager/LocalOnChainKeyManagerSpec.scala
@@ -21,7 +21,7 @@ class LocalOnChainKeyManagerSpec extends AnyFunSuite {
Base64.getDecoder.decode("cHNidP8BAHECAAAAAfZo4nGIyTg77MFmEBkQH1Au3Jl8vzB2WWQGGz/MbyssAAAAAAD9////ArAHPgUAAAAAFgAU6j9yVvLg66Zu3GM/xHbmXT0yvyiAlpgAAAAAABYAFODscQh3N7lmDYyV5yrHpGL2Zd4JAAAAAAABAH0CAAAAAaNdmqUNlziIjSaif3JUcvJWdyF0U5bYq13NMe+LbaBZAAAAAAD9////AjSp1gUAAAAAFgAUjfFMfBg8ulo/874n3+0ode7ka0BAQg8AAAAAACIAIPUn/XU17DfnvDkj8gn2twG3jtr2Z7sthy9K2MPTdYkaAAAAAAEBHzSp1gUAAAAAFgAUjfFMfBg8ulo/874n3+0ode7ka0AiBgM+PDdyxsVisa66SyBxiUvhEam8lEP64yujvVsEcGaqIxgPCfOBVAAAgAEAAIAAAACAAQAAAAMAAAAAIgIDWmAhb/sCV9+HjwFpPuy2TyEBi/Y11wrEHZUihe3N80EYDwnzgVQAAIABAACAAAAAgAEAAAAFAAAAAAA=")
).getRight
- val Success(psbt1) = onChainKeyManager.sign(psbt, psbt.getInputs.toArray().indices, Seq(0))
+ val Success(psbt1) = onChainKeyManager.sign(psbt, psbt.inputs.toArray().indices, Seq(0))
val tx = psbt1.extract()
assert(tx.isRight)
}
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/db/AuditDbSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/db/AuditDbSpec.scala
index 4736d09bcd..1948d4f2e0 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/db/AuditDbSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/db/AuditDbSpec.scala
@@ -17,7 +17,7 @@
package fr.acinq.eclair.db
import fr.acinq.bitcoin.scalacompat.Crypto.{PrivateKey, PublicKey}
-import fr.acinq.bitcoin.scalacompat.{ByteVector32, SatoshiLong, Script, Transaction, TxOut}
+import fr.acinq.bitcoin.scalacompat.{Block, ByteVector32, SatoshiLong, Script, Transaction, TxOut}
import fr.acinq.eclair.TestDatabases.{TestPgDatabases, TestSqliteDatabases, migrationCheck}
import fr.acinq.eclair._
import fr.acinq.eclair.channel.Helpers.Closing.MutualClose
@@ -865,7 +865,7 @@ class AuditDbSpec extends AnyFunSuite {
val channelId = randomBytes32()
val scid = ShortChannelId(123)
val remoteNodeId = randomKey().publicKey
- val u = Announcements.makeChannelUpdate(randomBytes32(), randomKey(), remoteNodeId, scid, CltvExpiryDelta(56), 2000 msat, 1000 msat, 999, 1000000000 msat)
+ val u = Announcements.makeChannelUpdate(Block.RegtestGenesisBlock.hash, randomKey(), remoteNodeId, scid, CltvExpiryDelta(56), 2000 msat, 1000 msat, 999, 1000000000 msat)
dbs.audit.addChannelUpdate(ChannelUpdateParametersChanged(null, channelId, remoteNodeId, u))
}
}
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/db/NetworkDbSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/db/NetworkDbSpec.scala
index 5bc11f6096..59ac04db5f 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/db/NetworkDbSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/db/NetworkDbSpec.scala
@@ -17,10 +17,11 @@
package fr.acinq.eclair.db
import fr.acinq.bitcoin.scalacompat.Crypto.{PrivateKey, PublicKey}
-import fr.acinq.bitcoin.scalacompat.{Block, ByteVector32, ByteVector64, Crypto, Satoshi, SatoshiLong}
+import fr.acinq.bitcoin.scalacompat.{Block, ByteVector32, ByteVector64, Crypto, Satoshi, SatoshiLong, TxId}
import fr.acinq.eclair.FeatureSupport.Optional
import fr.acinq.eclair.Features.VariableLengthOnion
import fr.acinq.eclair.TestDatabases._
+import fr.acinq.eclair.TestUtils.randomTxId
import fr.acinq.eclair.db.jdbc.JdbcUtils.using
import fr.acinq.eclair.db.pg.PgNetworkDb
import fr.acinq.eclair.db.sqlite.SqliteNetworkDb
@@ -86,7 +87,7 @@ class NetworkDbSpec extends AnyFunSuite {
val db = dbs.network
val sig = ByteVector64.Zeroes
val c = Announcements.makeChannelAnnouncement(Block.RegtestGenesisBlock.hash, RealShortChannelId(42), randomKey().publicKey, randomKey().publicKey, randomKey().publicKey, randomKey().publicKey, sig, sig, sig, sig)
- val txid = ByteVector32.fromValidHex("0001" * 16)
+ val txid = TxId.fromValidHex("0001" * 16)
db.addChannel(c, txid, Satoshi(42))
assert(db.listChannels() == SortedMap(c.shortChannelId -> PublicChannel(c, txid, Satoshi(42), None, None, None)))
}
@@ -112,9 +113,9 @@ class NetworkDbSpec extends AnyFunSuite {
val channel_2 = Announcements.makeChannelAnnouncement(Block.RegtestGenesisBlock.hash, RealShortChannelId(43), a.publicKey, c.publicKey, randomKey().publicKey, randomKey().publicKey, sig, sig, sig, sig)
val channel_3 = Announcements.makeChannelAnnouncement(Block.RegtestGenesisBlock.hash, RealShortChannelId(44), b.publicKey, c.publicKey, randomKey().publicKey, randomKey().publicKey, sig, sig, sig, sig)
- val txid_1 = randomBytes32()
- val txid_2 = randomBytes32()
- val txid_3 = randomBytes32()
+ val txid_1 = randomTxId()
+ val txid_2 = randomTxId()
+ val txid_3 = randomTxId()
val capacity = 10000 sat
assert(db.listChannels().toSet == Set.empty)
@@ -137,9 +138,9 @@ class NetworkDbSpec extends AnyFunSuite {
channel_3.shortChannelId -> PublicChannel(channel_3, txid_3, capacity, None, None, None))
)
- val channel_update_1 = Announcements.makeChannelUpdate(Block.RegtestGenesisBlock.hash, a, b.publicKey, ShortChannelId(42), CltvExpiryDelta(5), 7000000 msat, 50000 msat, 100, 500000000L msat, true)
- val channel_update_2 = Announcements.makeChannelUpdate(Block.RegtestGenesisBlock.hash, b, a.publicKey, ShortChannelId(42), CltvExpiryDelta(5), 7000000 msat, 50000 msat, 100, 500000000L msat, true)
- val channel_update_3 = Announcements.makeChannelUpdate(Block.RegtestGenesisBlock.hash, b, c.publicKey, ShortChannelId(44), CltvExpiryDelta(5), 7000000 msat, 50000 msat, 100, 500000000L msat, true)
+ val channel_update_1 = Announcements.makeChannelUpdate(Block.RegtestGenesisBlock.hash, a, b.publicKey, ShortChannelId(42), CltvExpiryDelta(5), 7000000 msat, 50000 msat, 100, 500000000L msat, isPrivate = true)
+ val channel_update_2 = Announcements.makeChannelUpdate(Block.RegtestGenesisBlock.hash, b, a.publicKey, ShortChannelId(42), CltvExpiryDelta(5), 7000000 msat, 50000 msat, 100, 500000000L msat, isPrivate = true)
+ val channel_update_3 = Announcements.makeChannelUpdate(Block.RegtestGenesisBlock.hash, b, c.publicKey, ShortChannelId(44), CltvExpiryDelta(5), 7000000 msat, 50000 msat, 100, 500000000L msat, isPrivate = true)
db.updateChannel(channel_update_1)
db.updateChannel(channel_update_1) // duplicate is ignored
@@ -214,9 +215,9 @@ class NetworkDbSpec extends AnyFunSuite {
val capacity = 10000 sat
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), CltvExpiryDelta(5), 7000000 msat, 50000 msat, 100, 500000000L msat, true)
+ val template = Announcements.makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv, pub, ShortChannelId(42), CltvExpiryDelta(5), 7000000 msat, 50000 msat, 100, 500000000L msat, isPrivate = true)
val updates = shortChannelIds.map(id => template.copy(shortChannelId = id))
- val txid = randomBytes32()
+ val txid = randomTxId()
channels.foreach(ca => db.addChannel(ca, txid, capacity))
updates.foreach(u => db.updateChannel(u))
assert(db.listChannels().keySet == channels.map(_.shortChannelId).toSet)
@@ -391,7 +392,7 @@ object NetworkDbSpec {
data: Array[Byte])
case class ChannelTestCase(shortChannelId: ShortChannelId,
- txid: ByteVector32,
+ txid: TxId,
channel: ChannelAnnouncement,
channel_data: Array[Byte],
capacity: Satoshi,
@@ -425,7 +426,7 @@ object NetworkDbSpec {
val channel_update_2_data = channel_update_2_opt.map(channelUpdateCodec.encode(_).require.toByteArray)
ChannelTestCase(
shortChannelId = channel.shortChannelId,
- txid = randomBytes32(),
+ txid = randomTxId(),
channel = channel,
channel_data = channel_data,
capacity = Random.nextInt(100_000).sat,
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/db/PaymentsDbSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/db/PaymentsDbSpec.scala
index 1eddf80102..7dc515d3fd 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/db/PaymentsDbSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/db/PaymentsDbSpec.scala
@@ -793,7 +793,7 @@ class PaymentsDbSpec extends AnyFunSuite {
object PaymentsDbSpec {
val (alicePriv, bobPriv, carolPriv, davePriv) = (randomKey(), randomKey(), randomKey(), randomKey())
val (alice, bob, carol, dave) = (alicePriv.publicKey, bobPriv.publicKey, carolPriv.publicKey, davePriv.publicKey)
- val hop_ab = ChannelHop(ShortChannelId(42), alice, bob, HopRelayParams.FromAnnouncement(ChannelUpdate(randomBytes64(), randomBytes32(), ShortChannelId(42), 1 unixsec, ChannelUpdate.MessageFlags(dontForward = false), ChannelUpdate.ChannelFlags.DUMMY, CltvExpiryDelta(12), 1 msat, 1 msat, 1, 500_000_000 msat)))
+ val hop_ab = ChannelHop(ShortChannelId(42), alice, bob, HopRelayParams.FromAnnouncement(ChannelUpdate(randomBytes64(), Block.RegtestGenesisBlock.hash, ShortChannelId(42), 1 unixsec, ChannelUpdate.MessageFlags(dontForward = false), ChannelUpdate.ChannelFlags.DUMMY, CltvExpiryDelta(12), 1 msat, 1 msat, 1, 500_000_000 msat)))
val hop_bc = NodeHop(bob, carol, CltvExpiryDelta(14), 1 msat)
val (preimage1, preimage2, preimage3, preimage4) = (randomBytes32(), randomBytes32(), randomBytes32(), randomBytes32())
val (paymentHash1, paymentHash2, paymentHash3, paymentHash4) = (Crypto.sha256(preimage1), Crypto.sha256(preimage2), Crypto.sha256(preimage3), Crypto.sha256(preimage4))
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/integration/ChannelIntegrationSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/integration/ChannelIntegrationSpec.scala
index a4ffde4a09..f7985710f1 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/integration/ChannelIntegrationSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/integration/ChannelIntegrationSpec.scala
@@ -23,7 +23,7 @@ import akka.testkit.TestProbe
import com.typesafe.config.ConfigFactory
import fr.acinq.bitcoin.ScriptFlags
import fr.acinq.bitcoin.scalacompat.Crypto.PublicKey
-import fr.acinq.bitcoin.scalacompat.{Block, BtcDouble, ByteVector32, Crypto, OutPoint, SatoshiLong, Script, Transaction, computeBIP84Address}
+import fr.acinq.bitcoin.scalacompat.{Block, BtcDouble, ByteVector32, Crypto, OutPoint, SatoshiLong, Script, Transaction, TxId, computeBIP84Address}
import fr.acinq.eclair.blockchain.bitcoind.BitcoindService.BitcoinReq
import fr.acinq.eclair.blockchain.bitcoind.rpc.BitcoinCoreClient
import fr.acinq.eclair.channel._
@@ -70,7 +70,7 @@ abstract class ChannelIntegrationSpec extends IntegrationSpec {
}
/** Wait for the given transaction to be either in the mempool or confirmed. */
- def waitForTxBroadcastOrConfirmed(txid: ByteVector32, bitcoinClient: BitcoinCoreClient, sender: TestProbe): Unit = {
+ def waitForTxBroadcastOrConfirmed(txid: TxId, bitcoinClient: BitcoinCoreClient, sender: TestProbe): Unit = {
awaitCond({
bitcoinClient.getMempool().pipeTo(sender.ref)
val inMempool = sender.expectMsgType[Seq[Transaction]].exists(_.txid == txid)
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/integration/basic/fixtures/MinimalNodeFixture.scala b/eclair-core/src/test/scala/fr/acinq/eclair/integration/basic/fixtures/MinimalNodeFixture.scala
index 76c642cc1f..accf5fc6b5 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/integration/basic/fixtures/MinimalNodeFixture.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/integration/basic/fixtures/MinimalNodeFixture.scala
@@ -8,7 +8,7 @@ import akka.testkit.{TestActor, TestProbe}
import com.softwaremill.quicklens.ModifyPimp
import com.typesafe.config.ConfigFactory
import fr.acinq.bitcoin.scalacompat.Crypto.PublicKey
-import fr.acinq.bitcoin.scalacompat.{Block, ByteVector32, Satoshi, SatoshiLong, Transaction}
+import fr.acinq.bitcoin.scalacompat.{Block, ByteVector32, Satoshi, SatoshiLong, Transaction, TxId}
import fr.acinq.eclair.ShortChannelId.txIndex
import fr.acinq.eclair.blockchain.DummyOnChainWallet
import fr.acinq.eclair.blockchain.bitcoind.ZmqWatcher
@@ -273,9 +273,9 @@ object MinimalNodeFixture extends Assertions with Eventually with IntegrationPat
* Computes a deterministic [[RealShortChannelId]] based on a txid. We need this so that watchers can verify
* transactions in a independent and stateless fashion, since there is no actual blockchain in those tests.
*/
- def deterministicShortId(txId: ByteVector32): RealShortChannelId = {
- val blockHeight = txId.take(3).toInt(signed = false)
- val txIndex = txId.takeRight(2).toInt(signed = false)
+ def deterministicShortId(txId: TxId): RealShortChannelId = {
+ val blockHeight = txId.value.take(3).toInt(signed = false)
+ val txIndex = txId.value.takeRight(2).toInt(signed = false)
val outputIndex = 0 // funding txs created by the dummy wallet used in tests only have one output
RealShortChannelId(BlockHeight(blockHeight), txIndex, outputIndex)
}
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/io/PendingChannelsRateLimiterSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/io/PendingChannelsRateLimiterSpec.scala
index be351aa5da..4647913fa2 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/io/PendingChannelsRateLimiterSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/io/PendingChannelsRateLimiterSpec.scala
@@ -20,7 +20,7 @@ import akka.actor.testkit.typed.scaladsl.{ScalaTestWithActorTestKit, TestProbe}
import akka.actor.typed.eventstream.EventStream.Publish
import com.typesafe.config.ConfigFactory
import fr.acinq.bitcoin.scalacompat.Crypto.PublicKey
-import fr.acinq.bitcoin.scalacompat.{ByteVector32, SatoshiLong, Transaction, TxOut}
+import fr.acinq.bitcoin.scalacompat.{ByteVector32, SatoshiLong, Transaction, TxId, TxOut}
import fr.acinq.eclair.channel._
import fr.acinq.eclair.io.PendingChannelsRateLimiter.filterPendingChannels
import fr.acinq.eclair.router.Router
@@ -74,11 +74,11 @@ class PendingChannelsRateLimiterSpec extends ScalaTestWithActorTestKit(ConfigFac
val tx = Transaction.read("010000000110f01d4a4228ef959681feb1465c2010d0135be88fd598135b2e09d5413bf6f1000000006a473044022074658623424cebdac8290488b76f893cfb17765b7a3805e773e6770b7b17200102202892cfa9dda662d5eac394ba36fcfd1ea6c0b8bb3230ab96220731967bbdb90101210372d437866d9e4ead3d362b01b615d24cc0d5152c740d51e3c55fb53f6d335d82ffffffff01408b0700000000001976a914678db9a7caa2aca887af1177eda6f3d0f702df0d88ac00000000")
val closingTx = ClosingTx(InputInfo(tx.txIn.head.outPoint, TxOut(10_000 sat, Nil), Nil), tx, None)
val channelsOnWhitelistAtLimit: Seq[PersistentChannelData] = Seq(
- DATA_WAIT_FOR_FUNDING_CONFIRMED(commitments(peerOnWhitelistAtLimit, randomBytes32()), BlockHeight(0), None, Left(FundingCreated(randomBytes32(), ByteVector32.Zeroes, 3, randomBytes64()))),
+ DATA_WAIT_FOR_FUNDING_CONFIRMED(commitments(peerOnWhitelistAtLimit, randomBytes32()), BlockHeight(0), None, Left(FundingCreated(randomBytes32(), TxId(ByteVector32.Zeroes), 3, randomBytes64()))),
DATA_WAIT_FOR_CHANNEL_READY(commitments(peerOnWhitelistAtLimit, randomBytes32()), ShortIds(RealScidStatus.Unknown, ShortChannelId.generateLocalAlias(), None)),
)
val channelsAtLimit1 = Seq(
- DATA_WAIT_FOR_FUNDING_CONFIRMED(commitments(peerAtLimit1, channelIdAtLimit1), BlockHeight(0), None, Left(FundingCreated(channelIdAtLimit1, ByteVector32.Zeroes, 3, randomBytes64()))),
+ DATA_WAIT_FOR_FUNDING_CONFIRMED(commitments(peerAtLimit1, channelIdAtLimit1), BlockHeight(0), None, Left(FundingCreated(channelIdAtLimit1, TxId(ByteVector32.Zeroes), 3, randomBytes64()))),
DATA_WAIT_FOR_CHANNEL_READY(commitments(peerAtLimit1, randomBytes32()), ShortIds(RealScidStatus.Unknown, ShortChannelId.generateLocalAlias(), None)),
)
val channelsAtLimit2 = Seq(
@@ -86,7 +86,7 @@ class PendingChannelsRateLimiterSpec extends ScalaTestWithActorTestKit(ConfigFac
DATA_WAIT_FOR_DUAL_FUNDING_READY(commitments(peerAtLimit2, randomBytes32()), ShortIds(RealScidStatus.Unknown, ShortChannelId.generateLocalAlias(), None)),
)
val channelsBelowLimit1 = Seq(
- DATA_WAIT_FOR_FUNDING_CONFIRMED(commitments(peerBelowLimit1, channelIdBelowLimit1), BlockHeight(0), None, Left(FundingCreated(channelIdBelowLimit1, ByteVector32.Zeroes, 3, randomBytes64()))),
+ DATA_WAIT_FOR_FUNDING_CONFIRMED(commitments(peerBelowLimit1, channelIdBelowLimit1), BlockHeight(0), None, Left(FundingCreated(channelIdBelowLimit1, TxId(ByteVector32.Zeroes), 3, randomBytes64()))),
)
val channelsBelowLimit2 = Seq(
DATA_WAIT_FOR_DUAL_FUNDING_READY(commitments(peerBelowLimit2, channelIdBelowLimit2), ShortIds(RealScidStatus.Unknown, ShortChannelId.generateLocalAlias(), None)),
@@ -99,7 +99,7 @@ class PendingChannelsRateLimiterSpec extends ScalaTestWithActorTestKit(ConfigFac
DATA_NORMAL(commitments(privatePeer2, randomBytes32()), ShortIds(RealScidStatus.Unknown, ShortChannelId.generateLocalAlias(), None), None, null, None, None, None, SpliceStatus.NoSplice),
)
val initiatorChannels = Seq(
- DATA_WAIT_FOR_FUNDING_CONFIRMED(commitments(peerBelowLimit1, randomBytes32(), isInitiator = true), BlockHeight(0), None, Left(FundingCreated(channelIdAtLimit1, ByteVector32.Zeroes, 3, randomBytes64()))),
+ DATA_WAIT_FOR_FUNDING_CONFIRMED(commitments(peerBelowLimit1, randomBytes32(), isInitiator = true), BlockHeight(0), None, Left(FundingCreated(channelIdAtLimit1, TxId(ByteVector32.Zeroes), 3, randomBytes64()))),
DATA_WAIT_FOR_CHANNEL_READY(commitments(peerBelowLimit1, randomBytes32(), isInitiator = true), ShortIds(RealScidStatus.Unknown, ShortChannelId.generateLocalAlias(), None)),
DATA_WAIT_FOR_DUAL_FUNDING_CONFIRMED(commitments(peerAtLimit1, randomBytes32(), isInitiator = true), 0 msat, 0 msat, BlockHeight(0), BlockHeight(0), RbfStatus.NoRbf, None),
DATA_WAIT_FOR_DUAL_FUNDING_READY(commitments(peerAtLimit1, randomBytes32(), isInitiator = true), ShortIds(RealScidStatus.Unknown, ShortChannelId.generateLocalAlias(), None)),
@@ -319,7 +319,7 @@ class PendingChannelsRateLimiterSpec extends ScalaTestWithActorTestKit(ConfigFac
DATA_WAIT_FOR_DUAL_FUNDING_READY(commitments(randomKey().publicKey, randomBytes32()), ShortIds(RealScidStatus.Unknown, ShortChannelId.generateLocalAlias(), None)),
DATA_NORMAL(commitments(randomKey().publicKey, randomBytes32()), ShortIds(RealScidStatus.Unknown, ShortChannelId.generateLocalAlias(), None), None, null, None, None, None, SpliceStatus.NoSplice),
DATA_SHUTDOWN(commitments(randomKey().publicKey, randomBytes32()), Shutdown(randomBytes32(), ByteVector.empty), Shutdown(randomBytes32(), ByteVector.empty), None),
- DATA_WAIT_FOR_FUNDING_CONFIRMED(commitments(randomKey().publicKey, randomBytes32()), BlockHeight(0), None, Left(FundingCreated(randomBytes32(), ByteVector32.Zeroes, 3, randomBytes64()))),
+ DATA_WAIT_FOR_FUNDING_CONFIRMED(commitments(randomKey().publicKey, randomBytes32()), BlockHeight(0), None, Left(FundingCreated(randomBytes32(), TxId(ByteVector32.Zeroes), 3, randomBytes64()))),
)
val limiter = testKit.spawn(PendingChannelsRateLimiter(nodeParams, router.ref, channels))
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/json/JsonSerializersSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/json/JsonSerializersSpec.scala
index d85d26e696..90ff1ecde8 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/json/JsonSerializersSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/json/JsonSerializersSpec.scala
@@ -19,7 +19,7 @@ package fr.acinq.eclair.json
import akka.actor.ActorRef
import akka.testkit.TestProbe
import fr.acinq.bitcoin.scalacompat.Crypto.{PrivateKey, PublicKey}
-import fr.acinq.bitcoin.scalacompat.{Block, Btc, ByteVector32, ByteVector64, DeterministicWallet, OutPoint, Satoshi, SatoshiLong, Transaction, TxOut}
+import fr.acinq.bitcoin.scalacompat.{Block, Btc, ByteVector32, ByteVector64, DeterministicWallet, OutPoint, Satoshi, SatoshiLong, Transaction, TxHash, TxId, TxOut}
import fr.acinq.eclair._
import fr.acinq.eclair.balance.CheckBalance
import fr.acinq.eclair.balance.CheckBalance.{ClosingBalance, GlobalBalance, MainAndHtlcBalance, PossiblyPublishedMainAndHtlcBalance, PossiblyPublishedMainBalance}
@@ -44,8 +44,8 @@ import java.util.UUID
class JsonSerializersSpec extends TestKitBaseClass with AnyFunSuiteLike with Matchers {
test("deserialize Map[OutPoint, ByteVector]") {
- val output1 = OutPoint(ByteVector32(hex"11418a2d282a40461966e4f578e1fdf633ad15c1b7fb3e771d14361127233be1"), 0)
- val output2 = OutPoint(ByteVector32(hex"3d62bd4f71dc63798418e59efbc7532380c900b5e79db3a5521374b161dd0e33"), 1)
+ val output1 = OutPoint(TxHash.fromValidHex("11418a2d282a40461966e4f578e1fdf633ad15c1b7fb3e771d14361127233be1"), 0)
+ val output2 = OutPoint(TxHash.fromValidHex("3d62bd4f71dc63798418e59efbc7532380c900b5e79db3a5521374b161dd0e33"), 1)
val map = Map(
output1 -> hex"dead",
output2 -> hex"beef"
@@ -63,8 +63,8 @@ class JsonSerializersSpec extends TestKitBaseClass with AnyFunSuiteLike with Mat
}
test("deserialize Map[OutPoint, Transaction]") {
- val output1 = OutPoint(ByteVector32(hex"11418a2d282a40461966e4f578e1fdf633ad15c1b7fb3e771d14361127233be1"), 0)
- val output2 = OutPoint(ByteVector32(hex"3d62bd4f71dc63798418e59efbc7532380c900b5e79db3a5521374b161dd0e33"), 1)
+ val output1 = OutPoint(TxHash.fromValidHex("11418a2d282a40461966e4f578e1fdf633ad15c1b7fb3e771d14361127233be1"), 0)
+ val output2 = OutPoint(TxHash.fromValidHex("3d62bd4f71dc63798418e59efbc7532380c900b5e79db3a5521374b161dd0e33"), 1)
val map = Map(
output1 -> Transaction.read("0200000001c8a8934fb38a44b969528252bc37be66ee166c7897c57384d1e561449e110c93010000006b483045022100dc6c50f445ed53d2fb41067fdcb25686fe79492d90e6e5db43235726ace247210220773d35228af0800c257970bee9cf75175d75217de09a8ecd83521befd040c4ca012102082b751372fe7e3b012534afe0bb8d1f2f09c724b1a10a813ce704e5b9c217ccfdffffff0247ba2300000000001976a914f97a7641228e6b17d4b0b08252ae75bd62a95fe788ace3de24000000000017a914a9fefd4b9a9282a1d7a17d2f14ac7d1eb88141d287f7d50800"),
output2 -> Transaction.read("0200000001adbb20ea41a8423ea937e76e8151636bf6093b70eaff942930d20576600521fd000000006b48304502210090587b6201e166ad6af0227d3036a9454223d49a1f11839c1a362184340ef0240220577f7cd5cca78719405cbf1de7414ac027f0239ef6e214c90fcaab0454d84b3b012103535b32d5eb0a6ed0982a0479bbadc9868d9836f6ba94dd5a63be16d875069184ffffffff028096980000000000220020c015c4a6be010e21657068fc2e6a9d02b27ebe4d490a25846f7237f104d1a3cd20256d29010000001600143ca33c2e4446f4a305f23c80df8ad1afdcf652f900000000")
@@ -121,9 +121,9 @@ class JsonSerializersSpec extends TestKitBaseClass with AnyFunSuiteLike with Mat
val dummyBytes32 = ByteVector32(hex"0202020202020202020202020202020202020202020202020202020202020202")
val localParams = LocalParams(dummyPublicKey, DeterministicWallet.KeyPath(Seq(42L)), 546 sat, Long.MaxValue.msat, Some(1000 sat), 1 msat, CltvExpiryDelta(144), 50, isInitiator = true, None, None, Features.empty)
val remoteParams = RemoteParams(dummyPublicKey, 546 sat, UInt64.MaxValue, Some(1000 sat), 1 msat, CltvExpiryDelta(144), 50, dummyPublicKey, dummyPublicKey, dummyPublicKey, dummyPublicKey, Features.empty, None)
- val commitmentInput = Funding.makeFundingInputInfo(dummyBytes32, 0, 150_000 sat, dummyPublicKey, dummyPublicKey)
+ val commitmentInput = Funding.makeFundingInputInfo(TxId(dummyBytes32), 0, 150_000 sat, dummyPublicKey, dummyPublicKey)
val localCommit = LocalCommit(0, CommitmentSpec(Set.empty, FeeratePerKw(2500 sat), 100_000_000 msat, 50_000_000 msat), CommitTxAndRemoteSig(CommitTx(commitmentInput, Transaction(2, Nil, Nil, 0)), ByteVector64.Zeroes), Nil)
- val remoteCommit = RemoteCommit(0, CommitmentSpec(Set.empty, FeeratePerKw(2500 sat), 50_000_000 msat, 100_000_000 msat), dummyBytes32, dummyPublicKey)
+ val remoteCommit = RemoteCommit(0, CommitmentSpec(Set.empty, FeeratePerKw(2500 sat), 50_000_000 msat, 100_000_000 msat), TxId(dummyBytes32), dummyPublicKey)
val channelInfo = RES_GET_CHANNEL_INFO(
PublicKey(hex"0270685ca81a8e4d4d01beec5781f4cc924684072ae52c507f8ebe9daf0caaab7b"),
ByteVector32(hex"345b2b05ec046ffe0c14d3b61838c79980713ad1cf8ae7a45c172ce90c9c0b9f"),
@@ -276,7 +276,7 @@ class JsonSerializersSpec extends TestKitBaseClass with AnyFunSuiteLike with Mat
test("InputInfo serialization") {
val inputInfo = InputInfo(
- outPoint = OutPoint(ByteVector32(hex"345b2b05ec046ffe0c14d3b61838c79980713ad1cf8ae7a45c172ce90c9c0b9f"), 42),
+ outPoint = OutPoint(TxHash.fromValidHex("345b2b05ec046ffe0c14d3b61838c79980713ad1cf8ae7a45c172ce90c9c0b9f"), 42),
txOut = TxOut(456651 sat, hex"3c7a66997c681a3de1bae56438abeee4fc50a16554725a430ade1dc8db6bdd76704d45c6151c4051d710cf487e63"),
redeemScript = hex"00dc6c50f445ed53d2fb41067fdcb25686fe79492d90e6e5db43235726ace247210220773"
)
@@ -331,11 +331,11 @@ class JsonSerializersSpec extends TestKitBaseClass with AnyFunSuiteLike with Mat
htlcs = Btc(0.05)
), closing = ClosingBalance(
localCloseBalance = PossiblyPublishedMainAndHtlcBalance(
- toLocal = Map(ByteVector32(hex"4d176ad844c363bed59edf81962b008faa6194c3b3757ffcd26ba60f95716db2") -> Btc(0.1)),
- htlcs = Map(ByteVector32(hex"94b70cec5a98d67d17c6e3de5c7697f8a6cab4f698df91e633ce35efa3574d71") -> Btc(0.03), ByteVector32(hex"a844edd41ce8503864f3c95d89d850b177a09d7d35e950a7d27c14abb63adb13") -> Btc(0.06)),
+ toLocal = Map(TxId.fromValidHex("4d176ad844c363bed59edf81962b008faa6194c3b3757ffcd26ba60f95716db2") -> Btc(0.1)),
+ htlcs = Map(TxId.fromValidHex("94b70cec5a98d67d17c6e3de5c7697f8a6cab4f698df91e633ce35efa3574d71") -> Btc(0.03), TxId.fromValidHex("a844edd41ce8503864f3c95d89d850b177a09d7d35e950a7d27c14abb63adb13") -> Btc(0.06)),
htlcsUnpublished = Btc(0.01)),
mutualCloseBalance = PossiblyPublishedMainBalance(
- toLocal = Map(ByteVector32(hex"7e3b012534afe0bb8d1f2f09c724b1a10a813ce704e5b9c217ccfdffffff0247") -> Btc(0.1)))
+ toLocal = Map(TxId.fromValidHex("7e3b012534afe0bb8d1f2f09c724b1a10a813ce704e5b9c217ccfdffffff0247") -> Btc(0.1)))
))
)
JsonSerializers.serialization.write(gb)(JsonSerializers.formats) shouldBe """{"total":1.0,"onChain":{"confirmed":0.4,"unconfirmed":0.05},"offChain":{"waitForFundingConfirmed":0.0,"waitForChannelReady":0.0,"normal":{"toLocal":0.2,"htlcs":0.05},"shutdown":{"toLocal":0.0,"htlcs":0.0},"negotiating":0.0,"closing":{"localCloseBalance":{"toLocal":{"4d176ad844c363bed59edf81962b008faa6194c3b3757ffcd26ba60f95716db2":0.1},"htlcs":{"94b70cec5a98d67d17c6e3de5c7697f8a6cab4f698df91e633ce35efa3574d71":0.03,"a844edd41ce8503864f3c95d89d850b177a09d7d35e950a7d27c14abb63adb13":0.06},"htlcsUnpublished":0.01},"remoteCloseBalance":{"toLocal":{},"htlcs":{},"htlcsUnpublished":0.0},"mutualCloseBalance":{"toLocal":{"7e3b012534afe0bb8d1f2f09c724b1a10a813ce704e5b9c217ccfdffffff0247":0.1}},"unknownCloseBalance":{"toLocal":0.0,"htlcs":0.0}},"waitForPublishFutureCommitment":0.0}}"""
@@ -353,13 +353,13 @@ class JsonSerializersSpec extends TestKitBaseClass with AnyFunSuiteLike with Mat
test("TransactionWithInputInfo serializer") {
// the input info is ignored when serializing to JSON
- val dummyInputInfo = InputInfo(OutPoint(ByteVector32.Zeroes, 0), TxOut(Satoshi(0), Nil), Nil)
+ val dummyInputInfo = InputInfo(OutPoint(TxId(ByteVector32.Zeroes), 0), TxOut(Satoshi(0), Nil), Nil)
val htlcSuccessTx = Transaction.read("0200000001c8a8934fb38a44b969528252bc37be66ee166c7897c57384d1e561449e110c93010000006b483045022100dc6c50f445ed53d2fb41067fdcb25686fe79492d90e6e5db43235726ace247210220773d35228af0800c257970bee9cf75175d75217de09a8ecd83521befd040c4ca012102082b751372fe7e3b012534afe0bb8d1f2f09c724b1a10a813ce704e5b9c217ccfdffffff0247ba2300000000001976a914f97a7641228e6b17d4b0b08252ae75bd62a95fe788ace3de24000000000017a914a9fefd4b9a9282a1d7a17d2f14ac7d1eb88141d287f7d50800")
val htlcSuccessTxInfo = HtlcSuccessTx(dummyInputInfo, htlcSuccessTx, ByteVector32.One, 3, ConfirmationTarget.Absolute(BlockHeight(1105)))
val htlcSuccessJson =
s"""{
- | "txid": "${htlcSuccessTx.txid.toHex}",
+ | "txid": "${htlcSuccessTx.txid.value.toHex}",
| "tx": "0200000001c8a8934fb38a44b969528252bc37be66ee166c7897c57384d1e561449e110c93010000006b483045022100dc6c50f445ed53d2fb41067fdcb25686fe79492d90e6e5db43235726ace247210220773d35228af0800c257970bee9cf75175d75217de09a8ecd83521befd040c4ca012102082b751372fe7e3b012534afe0bb8d1f2f09c724b1a10a813ce704e5b9c217ccfdffffff0247ba2300000000001976a914f97a7641228e6b17d4b0b08252ae75bd62a95fe788ace3de24000000000017a914a9fefd4b9a9282a1d7a17d2f14ac7d1eb88141d287f7d50800",
| "paymentHash": "0100000000000000000000000000000000000000000000000000000000000000",
| "htlcId": 3,
@@ -372,7 +372,7 @@ class JsonSerializersSpec extends TestKitBaseClass with AnyFunSuiteLike with Mat
val claimHtlcTimeoutTxInfo = ClaimHtlcTimeoutTx(dummyInputInfo, claimHtlcTimeoutTx, 2, ConfirmationTarget.Absolute(BlockHeight(144)))
val claimHtlcTimeoutJson =
s"""{
- | "txid": "${claimHtlcTimeoutTx.txid.toHex}",
+ | "txid": "${claimHtlcTimeoutTx.txid.value.toHex}",
| "tx": "010000000110f01d4a4228ef959681feb1465c2010d0135be88fd598135b2e09d5413bf6f1000000006a473044022074658623424cebdac8290488b76f893cfb17765b7a3805e773e6770b7b17200102202892cfa9dda662d5eac394ba36fcfd1ea6c0b8bb3230ab96220731967bbdb90101210372d437866d9e4ead3d362b01b615d24cc0d5152c740d51e3c55fb53f6d335d82ffffffff01408b0700000000001976a914678db9a7caa2aca887af1177eda6f3d0f702df0d88ac00000000",
| "htlcId": 2,
| "confirmBeforeBlock": 144
@@ -384,7 +384,7 @@ class JsonSerializersSpec extends TestKitBaseClass with AnyFunSuiteLike with Mat
val closingTxWithLocalOutput = ClosingTx(dummyInputInfo, closingTx, Some(OutputInfo(1, Satoshi(15000), hex"deadbeef")))
val closingTxWithLocalOutputJson =
s"""{
- | "txid": "${closingTx.txid.toHex}",
+ | "txid": "${closingTx.txid.value.toHex}",
| "tx": "0100000001be43e9788523ed4de0b24a007a90009bc25e667ddac0e9ee83049be03e220138000000006b483045022100f74dd6ad3e6a00201d266a0ed860a6379c6e68b473970423f3fc8a15caa1ea0f022065b4852c9da230d9e036df743cb743601ca5229e1cb610efdd99769513f2a2260121020636de7755830fb4a3f136e97ecc6c58941611957ba0364f01beae164b945b2fffffffff0150f80c000000000017a9146809053148799a10480eada3d56d15edf4a648c88700000000",
| "toLocalOutput": {
| "index": 1,
@@ -398,7 +398,7 @@ class JsonSerializersSpec extends TestKitBaseClass with AnyFunSuiteLike with Mat
val closingTxWithoutLocalOutput = ClosingTx(dummyInputInfo, closingTx, None)
val closingTxWithoutLocalOutputJson =
s"""{
- | "txid": "${closingTx.txid.toHex}",
+ | "txid": "${closingTx.txid.value.toHex}",
| "tx": "0100000001be43e9788523ed4de0b24a007a90009bc25e667ddac0e9ee83049be03e220138000000006b483045022100f74dd6ad3e6a00201d266a0ed860a6379c6e68b473970423f3fc8a15caa1ea0f022065b4852c9da230d9e036df743cb743601ca5229e1cb610efdd99769513f2a2260121020636de7755830fb4a3f136e97ecc6c58941611957ba0364f01beae164b945b2fffffffff0150f80c000000000017a9146809053148799a10480eada3d56d15edf4a648c88700000000"
|}
""".stripMargin
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/payment/Bolt11InvoiceSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/payment/Bolt11InvoiceSpec.scala
index bcd9777caf..48d2feb33e 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/payment/Bolt11InvoiceSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/payment/Bolt11InvoiceSpec.scala
@@ -17,7 +17,7 @@
package fr.acinq.eclair.payment
import fr.acinq.bitcoin.scalacompat.Crypto.{PrivateKey, PublicKey}
-import fr.acinq.bitcoin.scalacompat.{Block, BtcDouble, ByteVector32, Crypto, MilliBtcDouble, SatoshiLong}
+import fr.acinq.bitcoin.scalacompat.{Block, BlockHash, BtcDouble, ByteVector32, Crypto, MilliBtcDouble, SatoshiLong}
import fr.acinq.eclair.FeatureSupport.{Mandatory, Optional}
import fr.acinq.eclair.Features.{PaymentMetadata, PaymentSecret, _}
import fr.acinq.eclair.payment.Bolt11Invoice._
@@ -43,7 +43,7 @@ class Bolt11InvoiceSpec extends AnyFunSuite {
assert(nodeId == PublicKey(hex"03e7156ae33b0a208d0744199163177e909e80176e55d97a2f221ede0f934dd9ad"))
// Copy of Bolt11Invoice.apply that doesn't strip unknown features
- def createInvoiceUnsafe(chainHash: ByteVector32,
+ def createInvoiceUnsafe(chainHash: BlockHash,
amount: Option[MilliSatoshi],
paymentHash: ByteVector32,
privateKey: PrivateKey,
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/payment/Bolt12InvoiceSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/payment/Bolt12InvoiceSpec.scala
index b9538c7ab5..537b5a9ba1 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/payment/Bolt12InvoiceSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/payment/Bolt12InvoiceSpec.scala
@@ -18,7 +18,7 @@ package fr.acinq.eclair.payment
import fr.acinq.bitcoin.Bech32
import fr.acinq.bitcoin.scalacompat.Crypto.{PrivateKey, PublicKey}
-import fr.acinq.bitcoin.scalacompat.{Block, ByteVector32}
+import fr.acinq.bitcoin.scalacompat.{Block, BlockHash, ByteVector32}
import fr.acinq.eclair.FeatureSupport.{Mandatory, Optional}
import fr.acinq.eclair.Features.{BasicMultiPartPayment, VariableLengthOnion}
import fr.acinq.eclair.crypto.Sphinx
@@ -55,7 +55,7 @@ class Bolt12InvoiceSpec extends AnyFunSuite {
}
test("check invoice signature") {
- val (nodeKey, payerKey, chain) = (randomKey(), randomKey(), randomBytes32())
+ val (nodeKey, payerKey, chain) = (randomKey(), randomKey(), BlockHash(randomBytes32()))
val offer = Offer(Some(10000 msat), "test offer", nodeKey.publicKey, Features.empty, chain)
val request = InvoiceRequest(offer, 11000 msat, 1, Features.empty, payerKey, chain)
val invoice = Bolt12Invoice(request, randomBytes32(), nodeKey, 300 seconds, Features.empty, Seq(createPaymentBlindedRoute(nodeKey.publicKey)))
@@ -72,7 +72,7 @@ class Bolt12InvoiceSpec extends AnyFunSuite {
}
test("check invoice signature with unknown field from invoice request") {
- val (nodeKey, payerKey, chain) = (randomKey(), randomKey(), randomBytes32())
+ val (nodeKey, payerKey, chain) = (randomKey(), randomKey(), BlockHash(randomBytes32()))
val offer = Offer(Some(10000 msat), "test offer", nodeKey.publicKey, Features.empty, chain)
val basicRequest = InvoiceRequest(offer, 11000 msat, 1, Features.empty, payerKey, chain)
val requestWithUnknownTlv = basicRequest.copy(records = TlvStream(basicRequest.records.records, Set(GenericTlv(UInt64(87), hex"0404"))))
@@ -83,7 +83,7 @@ class Bolt12InvoiceSpec extends AnyFunSuite {
}
test("check that invoice matches offer") {
- val (nodeKey, payerKey, chain) = (randomKey(), randomKey(), randomBytes32())
+ val (nodeKey, payerKey, chain) = (randomKey(), randomKey(), BlockHash(randomBytes32()))
val offer = Offer(Some(10000 msat), "test offer", nodeKey.publicKey, Features.empty, chain)
val request = InvoiceRequest(offer, 11000 msat, 1, Features.empty, payerKey, chain)
val invoice = Bolt12Invoice(request, randomBytes32(), nodeKey, 300 seconds, Features.empty, Seq(createPaymentBlindedRoute(nodeKey.publicKey)))
@@ -104,7 +104,7 @@ class Bolt12InvoiceSpec extends AnyFunSuite {
}
test("check that invoice matches invoice request") {
- val (nodeKey, payerKey, chain) = (randomKey(), randomKey(), randomBytes32())
+ val (nodeKey, payerKey, chain) = (randomKey(), randomKey(), BlockHash(randomBytes32()))
val offer = Offer(Some(15000 msat), "test offer", nodeKey.publicKey, Features.empty, chain)
val request = InvoiceRequest(offer, 15000 msat, 1, Features.empty, payerKey, chain)
assert(request.quantity_opt.isEmpty) // when paying for a single item, the quantity field must not be present
@@ -145,7 +145,7 @@ class Bolt12InvoiceSpec extends AnyFunSuite {
}
test("check invoice expiry") {
- val (nodeKey, payerKey, chain) = (randomKey(), randomKey(), randomBytes32())
+ val (nodeKey, payerKey, chain) = (randomKey(), randomKey(), BlockHash(randomBytes32()))
val offer = Offer(Some(5000 msat), "test offer", nodeKey.publicKey, Features.empty, chain)
val request = InvoiceRequest(offer, 5000 msat, 1, Features.empty, payerKey, chain)
val invoice = Bolt12Invoice(request, randomBytes32(), nodeKey, 300 seconds, Features.empty, Seq(createPaymentBlindedRoute(nodeKey.publicKey)))
@@ -251,7 +251,7 @@ class Bolt12InvoiceSpec extends AnyFunSuite {
assert(codedDecoded.paymentHash == paymentHash)
assert(codedDecoded.relativeExpiry == relativeExpiry.seconds)
assert(codedDecoded.fallbacks.contains(fallbacks))
- assert(codedDecoded.records.unknown.toSet == Set(GenericTlv(UInt64(121), hex"010203"), GenericTlv(UInt64(313), hex"baba")))
+ assert(codedDecoded.records.unknown == Set(GenericTlv(UInt64(121), hex"010203"), GenericTlv(UInt64(313), hex"baba")))
}
test("minimal tip") {
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/payment/PaymentPacketSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/payment/PaymentPacketSpec.scala
index 128b360929..88515aadd8 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/payment/PaymentPacketSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/payment/PaymentPacketSpec.scala
@@ -21,6 +21,7 @@ import fr.acinq.bitcoin.scalacompat.DeterministicWallet.ExtendedPrivateKey
import fr.acinq.bitcoin.scalacompat.{Block, ByteVector32, Crypto, DeterministicWallet, OutPoint, Satoshi, SatoshiLong, TxOut}
import fr.acinq.eclair.FeatureSupport.{Mandatory, Optional}
import fr.acinq.eclair.Features._
+import fr.acinq.eclair.TestUtils.randomTxId
import fr.acinq.eclair.channel._
import fr.acinq.eclair.channel.fsm.Channel
import fr.acinq.eclair.crypto.{ShaChain, Sphinx}
@@ -704,7 +705,7 @@ object PaymentPacketSpec {
val channelReserve = testCapacity * 0.01
val localParams = LocalParams(null, null, null, Long.MaxValue.msat, Some(channelReserve), null, null, 0, isInitiator = true, None, None, null)
val remoteParams = RemoteParams(randomKey().publicKey, null, UInt64.MaxValue, Some(channelReserve), null, null, maxAcceptedHtlcs = 0, null, null, null, null, null, None)
- val commitInput = InputInfo(OutPoint(randomBytes32(), 1), TxOut(testCapacity, Nil), Nil)
+ val commitInput = InputInfo(OutPoint(randomTxId(), 1), TxOut(testCapacity, Nil), Nil)
val localCommit = LocalCommit(0, null, CommitTxAndRemoteSig(Transactions.CommitTx(commitInput, null), null), Nil)
val remoteCommit = RemoteCommit(0, null, null, randomKey().publicKey)
val localChanges = LocalChanges(Nil, Nil, Nil)
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/router/ChannelRangeQueriesSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/router/ChannelRangeQueriesSpec.scala
index 5e3d622ddb..5917e752f4 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/router/ChannelRangeQueriesSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/router/ChannelRangeQueriesSpec.scala
@@ -16,7 +16,7 @@
package fr.acinq.eclair.router
-import fr.acinq.bitcoin.scalacompat.{Block, ByteVector32, SatoshiLong}
+import fr.acinq.bitcoin.scalacompat.{Block, ByteVector32, SatoshiLong, TxId}
import fr.acinq.eclair.RealShortChannelId
import fr.acinq.eclair.router.Router.{ChannelMeta, PublicChannel}
import fr.acinq.eclair.router.Sync._
@@ -103,8 +103,8 @@ class ChannelRangeQueriesSpec extends AnyFunSuite {
val ef = RouteCalculationSpec.makeChannel(167514L, e, f)
val channels = SortedMap(
- ab.shortChannelId -> PublicChannel(ab, ByteVector32.Zeroes, 0 sat, Some(uab1), Some(uab2), Some(ChannelMeta(1000 msat, 400 msat))),
- cd.shortChannelId -> PublicChannel(cd, ByteVector32.Zeroes, 0 sat, Some(ucd1), None, None)
+ ab.shortChannelId -> PublicChannel(ab, TxId(ByteVector32.Zeroes), 0 sat, Some(uab1), Some(uab2), Some(ChannelMeta(1000 msat, 400 msat))),
+ cd.shortChannelId -> PublicChannel(cd, TxId(ByteVector32.Zeroes), 0 sat, Some(ucd1), None, None)
)
assert(getChannelDigestInfo(channels)(ab.shortChannelId) == (Timestamps(now, now), Checksums(3352963162L, 2581904122L)))
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 81cfc6c036..edec7c97a9 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
@@ -18,7 +18,7 @@ package fr.acinq.eclair.router
import com.softwaremill.quicklens.ModifyPimp
import fr.acinq.bitcoin.scalacompat.Crypto.PublicKey
-import fr.acinq.bitcoin.scalacompat.{Block, ByteVector32, ByteVector64, Satoshi, SatoshiLong}
+import fr.acinq.bitcoin.scalacompat.{Block, ByteVector32, ByteVector64, Satoshi, SatoshiLong, TxId}
import fr.acinq.eclair.payment.relay.Relayer.RelayFees
import fr.acinq.eclair.router.Announcements.makeNodeAnnouncement
import fr.acinq.eclair.router.BaseRouterSpec.channelHopFromUpdate
@@ -554,7 +554,7 @@ class RouteCalculationSpec extends AnyFunSuite with ParallelTestExecution {
val publicChannels = channels.map { case (shortChannelId, announcement) =>
val HopRelayParams.FromAnnouncement(update) = edges.find(_.desc.shortChannelId == shortChannelId).get.params
val (update_1_opt, update_2_opt) = if (update.channelFlags.isNode1) (Some(update), None) else (None, Some(update))
- val pc = PublicChannel(announcement, ByteVector32.Zeroes, Satoshi(1000), update_1_opt, update_2_opt, None)
+ val pc = PublicChannel(announcement, TxId(ByteVector32.Zeroes), Satoshi(1000), update_1_opt, update_2_opt, None)
(shortChannelId, pc)
}
@@ -903,26 +903,26 @@ class RouteCalculationSpec extends AnyFunSuite with ParallelTestExecution {
val updates = SortedMap(
RealShortChannelId(BlockHeight(565643), 1216, 0) -> PublicChannel(
ann = makeChannel(ShortChannelId.fromCoordinates("565643x1216x0").success.value.toLong, PublicKey(hex"03864ef025fde8fb587d989186ce6a4a186895ee44a926bfc370e2c366597a3f8f"), PublicKey(hex"024655b768ef40951b20053a5c4b951606d4d86085d51238f2c67c7dec29c792ca")),
- fundingTxid = ByteVector32.Zeroes,
+ fundingTxId = TxId(ByteVector32.Zeroes),
capacity = DEFAULT_CAPACITY,
- update_1_opt = Some(ChannelUpdate(ByteVector64.Zeroes, ByteVector32.Zeroes, ShortChannelId.fromCoordinates("565643x1216x0").success.value, 0 unixsec, ChannelUpdate.MessageFlags(dontForward = false), ChannelUpdate.ChannelFlags.DUMMY, CltvExpiryDelta(14), htlcMinimumMsat = 1 msat, feeBaseMsat = 1000 msat, 10, 4_294_967_295L msat)),
- update_2_opt = Some(ChannelUpdate(ByteVector64.Zeroes, ByteVector32.Zeroes, ShortChannelId.fromCoordinates("565643x1216x0").success.value, 0 unixsec, ChannelUpdate.MessageFlags(dontForward = false), ChannelUpdate.ChannelFlags(isEnabled = true, isNode1 = false), CltvExpiryDelta(144), htlcMinimumMsat = 0 msat, feeBaseMsat = 1000 msat, 100, 15_000_000_000L msat)),
+ update_1_opt = Some(ChannelUpdate(ByteVector64.Zeroes, Block.RegtestGenesisBlock.hash, ShortChannelId.fromCoordinates("565643x1216x0").success.value, 0 unixsec, ChannelUpdate.MessageFlags(dontForward = false), ChannelUpdate.ChannelFlags.DUMMY, CltvExpiryDelta(14), htlcMinimumMsat = 1 msat, feeBaseMsat = 1000 msat, 10, 4_294_967_295L msat)),
+ update_2_opt = Some(ChannelUpdate(ByteVector64.Zeroes, Block.RegtestGenesisBlock.hash, ShortChannelId.fromCoordinates("565643x1216x0").success.value, 0 unixsec, ChannelUpdate.MessageFlags(dontForward = false), ChannelUpdate.ChannelFlags(isEnabled = true, isNode1 = false), CltvExpiryDelta(144), htlcMinimumMsat = 0 msat, feeBaseMsat = 1000 msat, 100, 15_000_000_000L msat)),
meta_opt = None
),
RealShortChannelId(BlockHeight(542280), 2156, 0) -> PublicChannel(
ann = makeChannel(ShortChannelId.fromCoordinates("542280x2156x0").success.value.toLong, PublicKey(hex"03864ef025fde8fb587d989186ce6a4a186895ee44a926bfc370e2c366597a3f8f"), PublicKey(hex"03cb7983dc247f9f81a0fa2dfa3ce1c255365f7279c8dd143e086ca333df10e278")),
- fundingTxid = ByteVector32.Zeroes,
+ fundingTxId = TxId(ByteVector32.Zeroes),
capacity = DEFAULT_CAPACITY,
- update_1_opt = Some(ChannelUpdate(ByteVector64.Zeroes, ByteVector32.Zeroes, ShortChannelId.fromCoordinates("542280x2156x0").success.value, 0 unixsec, ChannelUpdate.MessageFlags(dontForward = false), ChannelUpdate.ChannelFlags.DUMMY, CltvExpiryDelta(144), htlcMinimumMsat = 1000 msat, feeBaseMsat = 1000 msat, 100, 16_777_000_000L msat)),
- update_2_opt = Some(ChannelUpdate(ByteVector64.Zeroes, ByteVector32.Zeroes, ShortChannelId.fromCoordinates("542280x2156x0").success.value, 0 unixsec, ChannelUpdate.MessageFlags(dontForward = false), ChannelUpdate.ChannelFlags(isEnabled = true, isNode1 = false), CltvExpiryDelta(144), htlcMinimumMsat = 1 msat, feeBaseMsat = 667 msat, 1, 16_777_000_000L msat)),
+ update_1_opt = Some(ChannelUpdate(ByteVector64.Zeroes, Block.RegtestGenesisBlock.hash, ShortChannelId.fromCoordinates("542280x2156x0").success.value, 0 unixsec, ChannelUpdate.MessageFlags(dontForward = false), ChannelUpdate.ChannelFlags.DUMMY, CltvExpiryDelta(144), htlcMinimumMsat = 1000 msat, feeBaseMsat = 1000 msat, 100, 16_777_000_000L msat)),
+ update_2_opt = Some(ChannelUpdate(ByteVector64.Zeroes, Block.RegtestGenesisBlock.hash, ShortChannelId.fromCoordinates("542280x2156x0").success.value, 0 unixsec, ChannelUpdate.MessageFlags(dontForward = false), ChannelUpdate.ChannelFlags(isEnabled = true, isNode1 = false), CltvExpiryDelta(144), htlcMinimumMsat = 1 msat, feeBaseMsat = 667 msat, 1, 16_777_000_000L msat)),
meta_opt = None
),
RealShortChannelId(BlockHeight(565779), 2711, 0) -> PublicChannel(
ann = makeChannel(ShortChannelId.fromCoordinates("565779x2711x0").success.value.toLong, PublicKey(hex"036d65409c41ab7380a43448f257809e7496b52bf92057c09c4f300cbd61c50d96"), PublicKey(hex"03864ef025fde8fb587d989186ce6a4a186895ee44a926bfc370e2c366597a3f8f")),
- fundingTxid = ByteVector32.Zeroes,
+ fundingTxId = TxId(ByteVector32.Zeroes),
capacity = DEFAULT_CAPACITY,
- update_1_opt = Some(ChannelUpdate(ByteVector64.Zeroes, ByteVector32.Zeroes, ShortChannelId.fromCoordinates("565779x2711x0").success.value, 0 unixsec, ChannelUpdate.MessageFlags(dontForward = false), ChannelUpdate.ChannelFlags.DUMMY, CltvExpiryDelta(144), htlcMinimumMsat = 1 msat, feeBaseMsat = 1000 msat, 100, 230_000_000L msat)),
- update_2_opt = Some(ChannelUpdate(ByteVector64.Zeroes, ByteVector32.Zeroes, ShortChannelId.fromCoordinates("565779x2711x0").success.value, 0 unixsec, ChannelUpdate.MessageFlags(dontForward = false), ChannelUpdate.ChannelFlags(isEnabled = false, isNode1 = false), CltvExpiryDelta(144), htlcMinimumMsat = 1 msat, feeBaseMsat = 1000 msat, 100, 230_000_000L msat)),
+ update_1_opt = Some(ChannelUpdate(ByteVector64.Zeroes, Block.RegtestGenesisBlock.hash, ShortChannelId.fromCoordinates("565779x2711x0").success.value, 0 unixsec, ChannelUpdate.MessageFlags(dontForward = false), ChannelUpdate.ChannelFlags.DUMMY, CltvExpiryDelta(144), htlcMinimumMsat = 1 msat, feeBaseMsat = 1000 msat, 100, 230_000_000L msat)),
+ update_2_opt = Some(ChannelUpdate(ByteVector64.Zeroes, Block.RegtestGenesisBlock.hash, ShortChannelId.fromCoordinates("565779x2711x0").success.value, 0 unixsec, ChannelUpdate.MessageFlags(dontForward = false), ChannelUpdate.ChannelFlags(isEnabled = false, isNode1 = false), CltvExpiryDelta(144), htlcMinimumMsat = 1 msat, feeBaseMsat = 1000 msat, 100, 230_000_000L msat)),
meta_opt = None
)
)
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 44945a534a..0744953488 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
@@ -20,7 +20,7 @@ import akka.actor.typed.scaladsl.adapter.actorRefAdapter
import akka.actor.{Actor, Props}
import akka.testkit.{TestFSMRef, TestProbe}
import fr.acinq.bitcoin.scalacompat.Crypto.{PrivateKey, PublicKey}
-import fr.acinq.bitcoin.scalacompat.{Block, ByteVector32, Satoshi, Script, Transaction, TxIn, TxOut}
+import fr.acinq.bitcoin.scalacompat.{Block, ByteVector32, Satoshi, Script, Transaction, TxId, TxIn, TxOut}
import fr.acinq.eclair.TestConstants.{Alice, Bob}
import fr.acinq.eclair.RealShortChannelId
import fr.acinq.eclair._
@@ -355,7 +355,7 @@ object RoutingSyncSpec {
val channelUpdate_21 = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv2, priv1.publicKey, shortChannelId, cltvExpiryDelta = CltvExpiryDelta(7), 0 msat, feeBaseMsat = 766000 msat, feeProportionalMillionths = 10, 500000000L msat, timestamp = timestamp)
val nodeAnnouncement_1 = makeNodeAnnouncement(priv1, "a", Color(0, 0, 0), List(), TestConstants.Bob.nodeParams.features.nodeAnnouncementFeatures())
val nodeAnnouncement_2 = makeNodeAnnouncement(priv2, "b", Color(0, 0, 0), List(), Features.empty)
- val publicChannel = PublicChannel(channelAnn_12, ByteVector32.Zeroes, Satoshi(0), Some(channelUpdate_12), Some(channelUpdate_21), None)
+ val publicChannel = PublicChannel(channelAnn_12, TxId(ByteVector32.Zeroes), Satoshi(0), Some(channelUpdate_12), Some(channelUpdate_21), None)
(publicChannel, nodeAnnouncement_1, nodeAnnouncement_2)
}
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/testutils/PimpTestProbe.scala b/eclair-core/src/test/scala/fr/acinq/eclair/testutils/PimpTestProbe.scala
index aa547661db..be46dc636a 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/testutils/PimpTestProbe.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/testutils/PimpTestProbe.scala
@@ -1,7 +1,7 @@
package fr.acinq.eclair.testutils
import akka.testkit.TestProbe
-import fr.acinq.bitcoin.scalacompat.{ByteVector32, Satoshi}
+import fr.acinq.bitcoin.scalacompat.{Satoshi, TxId}
import fr.acinq.eclair.MilliSatoshi
import fr.acinq.eclair.blockchain.bitcoind.ZmqWatcher.{WatchFundingConfirmed, WatchFundingSpent, WatchPublished, WatchTxConfirmed}
import fr.acinq.eclair.channel.AvailableBalanceChanged
@@ -22,19 +22,19 @@ case class PimpTestProbe(probe: TestProbe) extends Assertions {
msg
}
- def expectWatchFundingSpent(txid: ByteVector32, hints_opt: Option[Set[ByteVector32]] = None): WatchFundingSpent =
+ def expectWatchFundingSpent(txid: TxId, hints_opt: Option[Set[TxId]] = None): WatchFundingSpent =
expectMsgTypeHaving[WatchFundingSpent](w => {
assert(w.txId == txid, "txid")
hints_opt.foreach(hints => assert(hints == w.hints))
})
- def expectWatchFundingConfirmed(txid: ByteVector32): WatchFundingConfirmed =
+ def expectWatchFundingConfirmed(txid: TxId): WatchFundingConfirmed =
expectMsgTypeHaving[WatchFundingConfirmed](w => assert(w.txId == txid, "txid"))
- def expectWatchTxConfirmed(txid: ByteVector32): WatchTxConfirmed =
+ def expectWatchTxConfirmed(txid: TxId): WatchTxConfirmed =
expectMsgTypeHaving[WatchTxConfirmed](w => assert(w.txId == txid, "txid"))
- def expectWatchPublished(txid: ByteVector32): WatchPublished =
+ def expectWatchPublished(txid: TxId): WatchPublished =
expectMsgTypeHaving[WatchPublished](w => assert(w.txId == txid, "txid"))
def expectAvailableBalanceChanged(balance: MilliSatoshi, capacity: Satoshi): AvailableBalanceChanged =
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 367a70e249..8f05b07488 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
@@ -124,7 +124,7 @@ trait TestVectorsSpec extends AnyFunSuite with Logging {
val fundingAmount = fundingTx.txOut(0).amount
logger.info(s"# funding-tx: $fundingTx}")
- val commitmentInput = Funding.makeFundingInputInfo(fundingTx.hash, 0, fundingAmount, Local.funding_pubkey, Remote.funding_pubkey)
+ val commitmentInput = Funding.makeFundingInputInfo(fundingTx.txid, 0, fundingAmount, Local.funding_pubkey, Remote.funding_pubkey)
val obscured_tx_number = Transactions.obscuredCommitTxNumber(42, isInitiator = true, Local.payment_basepoint, Remote.payment_basepoint)
assert(obscured_tx_number == (0x2bb038521914L ^ 42L))
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 3dfcae02ea..09264cca83 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
@@ -19,7 +19,8 @@ package fr.acinq.eclair.transactions
import fr.acinq.bitcoin.SigHash._
import fr.acinq.bitcoin.scalacompat.Crypto.{PrivateKey, ripemd160, sha256}
import fr.acinq.bitcoin.scalacompat.Script.{pay2wpkh, pay2wsh, write}
-import fr.acinq.bitcoin.scalacompat.{Btc, ByteVector32, Crypto, MilliBtc, MilliBtcDouble, OutPoint, Protocol, Satoshi, SatoshiLong, Script, ScriptWitness, Transaction, TxIn, TxOut, millibtc2satoshi}
+import fr.acinq.bitcoin.scalacompat.{Block, Btc, ByteVector32, Crypto, MilliBtc, MilliBtcDouble, OutPoint, Protocol, Satoshi, SatoshiLong, Script, ScriptWitness, Transaction, TxId, TxIn, TxOut, millibtc2satoshi}
+import fr.acinq.eclair.TestUtils.randomTxId
import fr.acinq.eclair._
import fr.acinq.eclair.blockchain.fee.{ConfirmationTarget, FeeratePerKw}
import fr.acinq.eclair.channel.Helpers.Funding
@@ -50,21 +51,21 @@ class TransactionsSpec extends AnyFunSuite with Logging {
val localHtlcPriv = PrivateKey(randomBytes32())
val remoteHtlcPriv = PrivateKey(randomBytes32())
val finalPubKeyScript = Script.write(Script.pay2wpkh(PrivateKey(randomBytes32()).publicKey))
- val commitInput = Funding.makeFundingInputInfo(randomBytes32(), 0, Btc(1), localFundingPriv.publicKey, remoteFundingPriv.publicKey)
+ val commitInput = Funding.makeFundingInputInfo(randomTxId(), 0, Btc(1), localFundingPriv.publicKey, remoteFundingPriv.publicKey)
val toLocalDelay = CltvExpiryDelta(144)
val localDustLimit = Satoshi(546)
val feeratePerKw = FeeratePerKw(22000 sat)
test("extract csv and cltv timeouts") {
- val parentTxId1 = randomBytes32()
- val parentTxId2 = randomBytes32()
- val parentTxId3 = randomBytes32()
+ val parentTxId1 = randomTxId()
+ val parentTxId2 = randomTxId()
+ val parentTxId3 = randomTxId()
val txIn = Seq(
- TxIn(OutPoint(parentTxId1.reverse, 3), Nil, 3),
- TxIn(OutPoint(parentTxId2.reverse, 1), Nil, 4),
- TxIn(OutPoint(parentTxId3.reverse, 0), Nil, 5),
- TxIn(OutPoint(randomBytes32(), 4), Nil, 0),
- TxIn(OutPoint(parentTxId1.reverse, 2), Nil, 5),
+ TxIn(OutPoint(parentTxId1, 3), Nil, 3),
+ TxIn(OutPoint(parentTxId2, 1), Nil, 4),
+ TxIn(OutPoint(parentTxId3, 0), Nil, 5),
+ TxIn(OutPoint(randomTxId(), 4), Nil, 0),
+ TxIn(OutPoint(parentTxId1, 2), Nil, 5),
)
val tx = Transaction(2, txIn, Nil, 10)
val expected = Map(
@@ -205,7 +206,7 @@ class TransactionsSpec extends AnyFunSuite with Logging {
// we use dummy signatures to compute the weight
val p2wpkhWitness = ScriptWitness(Seq(Scripts.der(PlaceHolderSig), PlaceHolderPubKey.value))
val claimAnchorOutputTxWithFees = claimAnchorOutputTx.copy(tx = claimAnchorOutputTx.tx.copy(
- txIn = claimAnchorOutputTx.tx.txIn :+ TxIn(OutPoint(randomBytes32(), 3), ByteVector.empty, 0, p2wpkhWitness),
+ txIn = claimAnchorOutputTx.tx.txIn :+ TxIn(OutPoint(randomTxId(), 3), ByteVector.empty, 0, p2wpkhWitness),
txOut = Seq(TxOut(1500 sat, Script.pay2wpkh(randomKey().publicKey)))
))
val signedTx = addSigs(claimAnchorOutputTxWithFees, PlaceHolderSig).tx
@@ -256,7 +257,7 @@ class TransactionsSpec extends AnyFunSuite with Logging {
test("generate valid commitment and htlc transactions (default commitment format)") {
val finalPubKeyScript = Script.write(Script.pay2wpkh(PrivateKey(randomBytes32()).publicKey))
- val commitInput = Funding.makeFundingInputInfo(randomBytes32(), 0, Btc(1), localFundingPriv.publicKey, remoteFundingPriv.publicKey)
+ val commitInput = Funding.makeFundingInputInfo(randomTxId(), 0, Btc(1), localFundingPriv.publicKey, remoteFundingPriv.publicKey)
// htlc1 and htlc2 are regular IN/OUT htlcs
val paymentPreimage1 = randomBytes32()
@@ -487,7 +488,7 @@ class TransactionsSpec extends AnyFunSuite with Logging {
test("generate valid commitment and htlc transactions (anchor outputs)") {
val finalPubKeyScript = Script.write(Script.pay2wpkh(PrivateKey(randomBytes32()).publicKey))
- val commitInput = Funding.makeFundingInputInfo(randomBytes32(), 0, Btc(1), localFundingPriv.publicKey, remoteFundingPriv.publicKey)
+ val commitInput = Funding.makeFundingInputInfo(randomTxId(), 0, Btc(1), localFundingPriv.publicKey, remoteFundingPriv.publicKey)
// htlc1, htlc2a and htlc2b are regular IN/OUT htlcs
val paymentPreimage1 = randomBytes32()
@@ -751,7 +752,7 @@ class TransactionsSpec extends AnyFunSuite with Logging {
val remotePaymentPriv = PrivateKey(hex"a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6")
val localHtlcPriv = PrivateKey(hex"a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7")
val remoteHtlcPriv = PrivateKey(hex"a8a8a8a8a8a8a8a8a8a8a8a8a8a8a8a8a8a8a8a8a8a8a8a8a8a8a8a8a8a8a8a8")
- val commitInput = Funding.makeFundingInputInfo(ByteVector32(hex"a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0"), 0, Btc(1), localFundingPriv.publicKey, remoteFundingPriv.publicKey)
+ val commitInput = Funding.makeFundingInputInfo(TxId.fromValidHex("a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0"), 0, Btc(1), localFundingPriv.publicKey, remoteFundingPriv.publicKey)
// htlc1 and htlc2 are two regular incoming HTLCs with different amounts.
// htlc2 and htlc3 have the same amounts and should be sorted according to their scriptPubKey
@@ -811,7 +812,7 @@ class TransactionsSpec extends AnyFunSuite with Logging {
}
test("find our output in closing tx") {
- val commitInput = Funding.makeFundingInputInfo(randomBytes32(), 0, Btc(1), localFundingPriv.publicKey, remoteFundingPriv.publicKey)
+ val commitInput = Funding.makeFundingInputInfo(randomTxId(), 0, Btc(1), localFundingPriv.publicKey, remoteFundingPriv.publicKey)
val localPubKeyScript = Script.write(Script.pay2wpkh(PrivateKey(randomBytes32()).publicKey))
val remotePubKeyScript = Script.write(Script.pay2wpkh(PrivateKey(randomBytes32()).publicKey))
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/wire/internal/channel/ChannelCodecsSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/wire/internal/channel/ChannelCodecsSpec.scala
index 1814d3b31e..cde6a80a7d 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/wire/internal/channel/ChannelCodecsSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/wire/internal/channel/ChannelCodecsSpec.scala
@@ -17,7 +17,7 @@
package fr.acinq.eclair.wire.internal.channel
import fr.acinq.bitcoin.scalacompat.Crypto.PrivateKey
-import fr.acinq.bitcoin.scalacompat.{Block, ByteVector32, ByteVector64, Crypto, DeterministicWallet, Satoshi, SatoshiLong, Transaction, TxIn}
+import fr.acinq.bitcoin.scalacompat.{Block, BlockHash, ByteVector32, ByteVector64, Crypto, DeterministicWallet, Satoshi, SatoshiLong, Transaction, TxId, TxIn}
import fr.acinq.eclair._
import fr.acinq.eclair.blockchain.fee.FeeratePerKw
import fr.acinq.eclair.channel.Helpers.Funding
@@ -300,12 +300,12 @@ object ChannelCodecsSpec {
val normal: DATA_NORMAL = makeChannelDataNormal(htlcs, Map(42L -> Origin.LocalCold(UUID.randomUUID), 15000L -> Origin.ChannelRelayedCold(ByteVector32(ByteVector.fill(32)(42)), 43, 11000000 msat, 10000000 msat)))
def makeChannelDataNormal(htlcs: Seq[DirectedHtlc], origins: Map[Long, Origin]): DATA_NORMAL = {
- val channelUpdate = Announcements.makeChannelUpdate(ByteVector32(ByteVector.fill(32)(1)), randomKey(), randomKey().publicKey, ShortChannelId(142553), CltvExpiryDelta(42), 15 msat, 575 msat, 53, Channel.MAX_FUNDING_WITHOUT_WUMBO.toMilliSatoshi)
+ val channelUpdate = Announcements.makeChannelUpdate(BlockHash(ByteVector32(ByteVector.fill(32)(1))), randomKey(), randomKey().publicKey, ShortChannelId(142553), CltvExpiryDelta(42), 15 msat, 575 msat, 53, Channel.MAX_FUNDING_WITHOUT_WUMBO.toMilliSatoshi)
val fundingTx = Transaction.read("0200000001adbb20ea41a8423ea937e76e8151636bf6093b70eaff942930d20576600521fd000000006b48304502210090587b6201e166ad6af0227d3036a9454223d49a1f11839c1a362184340ef0240220577f7cd5cca78719405cbf1de7414ac027f0239ef6e214c90fcaab0454d84b3b012103535b32d5eb0a6ed0982a0479bbadc9868d9836f6ba94dd5a63be16d875069184ffffffff028096980000000000220020c015c4a6be010e21657068fc2e6a9d02b27ebe4d490a25846f7237f104d1a3cd20256d29010000001600143ca33c2e4446f4a305f23c80df8ad1afdcf652f900000000")
val fundingAmount = fundingTx.txOut.head.amount
val fundingTxIndex = 0
val remoteFundingPubKey = PrivateKey(ByteVector32(ByteVector.fill(32)(1)) :+ 1.toByte).publicKey
- val commitmentInput = Funding.makeFundingInputInfo(fundingTx.hash, 0, fundingAmount, channelKeyManager.fundingPublicKey(localParams.fundingKeyPath, fundingTxIndex).publicKey, remoteFundingPubKey)
+ val commitmentInput = Funding.makeFundingInputInfo(fundingTx.txid, 0, fundingAmount, channelKeyManager.fundingPublicKey(localParams.fundingKeyPath, fundingTxIndex).publicKey, remoteFundingPubKey)
val remoteSig = ByteVector64(hex"2148d2d4aac8c793eb82d31bcf22d4db707b9fd7eee1b89b4b1444c9e19ab7172bab8c3d997d29163fa0cb255c75afb8ade13617ad1350c1515e9be4a222a04d")
val commitTx = Transaction(
version = 2,
@@ -318,7 +318,7 @@ object ChannelCodecsSpec {
lockTime = 0
)
val localCommit = LocalCommit(0, CommitmentSpec(htlcs.toSet, FeeratePerKw(1500 sat), 50000000 msat, 70000000 msat), CommitTxAndRemoteSig(CommitTx(commitmentInput, commitTx), remoteSig), Nil)
- val remoteCommit = RemoteCommit(0, CommitmentSpec(htlcs.map(_.opposite).toSet, FeeratePerKw(1500 sat), 50000 msat, 700000 msat), ByteVector32(hex"0303030303030303030303030303030303030303030303030303030303030303"), PrivateKey(ByteVector.fill(32)(4)).publicKey)
+ val remoteCommit = RemoteCommit(0, CommitmentSpec(htlcs.map(_.opposite).toSet, FeeratePerKw(1500 sat), 50000 msat, 700000 msat), TxId.fromValidHex("0303030303030303030303030303030303030303030303030303030303030303"), PrivateKey(ByteVector.fill(32)(4)).publicKey)
val channelId = htlcs.headOption.map(_.add.channelId).getOrElse(ByteVector32.Zeroes)
val channelFlags = ChannelFlags.Public
val commitments = Commitments(
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/wire/internal/channel/version1/ChannelCodecs1Spec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/wire/internal/channel/version1/ChannelCodecs1Spec.scala
index c7fecf052a..e7f775ba4d 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/wire/internal/channel/version1/ChannelCodecs1Spec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/wire/internal/channel/version1/ChannelCodecs1Spec.scala
@@ -3,14 +3,15 @@ package fr.acinq.eclair.wire.internal.channel.version1
import akka.actor.ActorSystem
import akka.testkit.TestProbe
import fr.acinq.bitcoin.scalacompat.DeterministicWallet.KeyPath
-import fr.acinq.bitcoin.scalacompat.{OutPoint, Satoshi, SatoshiLong}
+import fr.acinq.bitcoin.scalacompat.{OutPoint, SatoshiLong}
+import fr.acinq.eclair.TestUtils.randomTxId
import fr.acinq.eclair.blockchain.fee.FeeratePerKw
-import fr.acinq.eclair.channel.{Origin, RemoteParams}
+import fr.acinq.eclair.channel.Origin
import fr.acinq.eclair.transactions.{CommitmentSpec, DirectedHtlc, IncomingHtlc, OutgoingHtlc}
import fr.acinq.eclair.wire.internal.channel.version0.ChannelTypes0.ChannelVersion
import fr.acinq.eclair.wire.internal.channel.version1.ChannelCodecs1.Codecs._
import fr.acinq.eclair.wire.protocol.UpdateAddHtlc
-import fr.acinq.eclair.{CltvExpiry, CltvExpiryDelta, MilliSatoshi, MilliSatoshiLong, TestConstants, UInt64, randomBytes32, randomKey}
+import fr.acinq.eclair.{CltvExpiry, MilliSatoshi, MilliSatoshiLong, TestConstants, randomBytes32}
import org.scalatest.funsuite.AnyFunSuite
import scodec.bits._
import scodec.{Attempt, DecodeResult}
@@ -154,10 +155,10 @@ class ChannelCodecs1Spec extends AnyFunSuite {
test("encode/decode map of spending txes") {
val map = Map(
- OutPoint(randomBytes32(), 42) -> randomBytes32(),
- OutPoint(randomBytes32(), 14502) -> randomBytes32(),
- OutPoint(randomBytes32(), 0) -> randomBytes32(),
- OutPoint(randomBytes32(), 454513) -> randomBytes32()
+ OutPoint(randomTxId(), 42) -> randomTxId(),
+ OutPoint(randomTxId(), 14502) -> randomTxId(),
+ OutPoint(randomTxId(), 0) -> randomTxId(),
+ OutPoint(randomTxId(), 454513) -> randomTxId()
)
assert(spentMapCodec.decodeValue(spentMapCodec.encode(map).require).require == map)
}
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/wire/internal/channel/version2/ChannelCodecs2Spec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/wire/internal/channel/version2/ChannelCodecs2Spec.scala
index fb065d51f0..3aa76a4714 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/wire/internal/channel/version2/ChannelCodecs2Spec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/wire/internal/channel/version2/ChannelCodecs2Spec.scala
@@ -1,10 +1,11 @@
package fr.acinq.eclair.wire.internal.channel.version2
import fr.acinq.bitcoin.scalacompat.{ByteVector64, OutPoint, Transaction}
+import fr.acinq.eclair.Features
+import fr.acinq.eclair.TestUtils.randomTxId
import fr.acinq.eclair.channel.{ChannelConfig, ChannelDataWithCommitments, ChannelFeatures, HtlcTxAndRemoteSig}
import fr.acinq.eclair.wire.internal.channel.version2.ChannelCodecs2.Codecs._
import fr.acinq.eclair.wire.internal.channel.version2.ChannelCodecs2.channelDataCodec
-import fr.acinq.eclair.{Features, randomBytes32}
import org.scalatest.funsuite.AnyFunSuite
import scodec.bits.HexStringSyntax
@@ -15,10 +16,10 @@ class ChannelCodecs2Spec extends AnyFunSuite {
test("encode/decode map of spending txs") {
val map = Map(
- OutPoint(randomBytes32(), 42) -> Transaction.read("020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219701000000000000000001d0070000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100d5275b3619953cb0c3b5aa577f04bc512380e60fa551762ce3d7a1bb7401cff9022037237ab0dac3fe100cde094e82e2bed9ba0ed1bb40154b48e56aa70f259e608b01483045022100c89172099507ff50f4c925e6c5150e871fb6e83dd73ff9fbb72f6ce829a9633f02203a63821d9162e99f9be712a68f9e589483994feae2661e4546cd5b6cec007be501008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a914b43e1b38138a41b37f7cd9a1d274bc63e3a9b5d188ac6868f6010000"),
- OutPoint(randomBytes32(), 14502) -> Transaction.read("02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b80094a010000000000002200202b1b5854183c12d3316565972c4668929d314d81c5dcdbb21cb45fe8a9a8114f4a01000000000000220020e9e86e4823faa62e222ebc858a226636856158f07e69898da3b0d1af0ddb3994e80300000000000022002010f88bf09e56f14fb4543fd26e47b0db50ea5de9cf3fc46434792471082621aed0070000000000002200203e68115ae0b15b8de75b6c6bc9af5ac9f01391544e0870dae443a1e8fe7837ead007000000000000220020fe0598d74fee2205cc3672e6e6647706b4f3099713b4661b62482c3addd04a5eb80b000000000000220020f96d0334feb64a4f40eb272031d07afcb038db56aa57446d60308c9f8ccadef9a00f000000000000220020ce6e751274836ff59622a0d1e07f8831d80bd6730bd48581398bfadd2bb8da9ac0c62d0000000000220020f3394e1e619b0eca1f91be2fb5ab4dfc59ba5b84ebe014ad1d43a564d012994a4c9e6a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0400483045022100cf8f902751006923e4062f5dbf55f8475bef08f4b5ac060d219bbff6c1a4431b02206006c515754ffc1f4f263004f61082e1fe4241449629da9096b0679e7e30972201473044022076a51aed1bd085487a7023f2ca8a87544a60a5b7277805b614b6ff7d36f1a44c02207ffac246b6572f3b4c9a7867ffa97c203500eebbf14659df78cfa0fadea22a6401475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220"),
- OutPoint(randomBytes32(), 0) -> Transaction.read("02000000000101b8cefef62ea66f5178b9361b2371be0759cbc8c689bcfa7a8e6746d497ec221a040000000001000000010a060000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e050047304402203c3a699fb80a38112aafd73d6e3a9b7d40bc2c3ed8b7fbc182a20f43b215172202204e71821b984d1af52c4b8e2cd4c572578c12a965866130c2345f61e4c2d3fef48347304402205bcfa92f83c69289a412b0b6dd4f2a0fe0b0fc2d45bd74706e963257a09ea24902203783e47883e60b86240e877fcbf33d50b1742f65bc93b3162d1be26583b367ee012001010101010101010101010101010101010101010101010101010101010101018d76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a9144b6b2e5444c2639cc0fb7bcea5afba3f3cdce23988527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f501b175ac6851b2756800000000"),
- OutPoint(randomBytes32(), 454513) -> Transaction.read("02000000000101ab84ff284f162cfbfef241f853b47d4368d171f9e2a1445160cd591c4c7d882b00000000000000000001e8030000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100d9e29616b8f3959f1d3d7f7ce893ffedcdc407717d0de8e37d808c91d3a7c50d022078c3033f6d00095c8720a4bc943c1b45727818c082e4e3ddbc6d3116435b624b014730440220636de5682ef0c5b61f124ec74e8aa2461a69777521d6998295dcea36bc3338110220165285594b23c50b28b82df200234566628a27bcd17f7f14404bd865354eb3ce012000000000000000000000000000000000000000000000000000000000000000008a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc688527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f401b175ac686800000000")
+ OutPoint(randomTxId(), 42) -> Transaction.read("020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219701000000000000000001d0070000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100d5275b3619953cb0c3b5aa577f04bc512380e60fa551762ce3d7a1bb7401cff9022037237ab0dac3fe100cde094e82e2bed9ba0ed1bb40154b48e56aa70f259e608b01483045022100c89172099507ff50f4c925e6c5150e871fb6e83dd73ff9fbb72f6ce829a9633f02203a63821d9162e99f9be712a68f9e589483994feae2661e4546cd5b6cec007be501008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a914b43e1b38138a41b37f7cd9a1d274bc63e3a9b5d188ac6868f6010000"),
+ OutPoint(randomTxId(), 14502) -> Transaction.read("02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b80094a010000000000002200202b1b5854183c12d3316565972c4668929d314d81c5dcdbb21cb45fe8a9a8114f4a01000000000000220020e9e86e4823faa62e222ebc858a226636856158f07e69898da3b0d1af0ddb3994e80300000000000022002010f88bf09e56f14fb4543fd26e47b0db50ea5de9cf3fc46434792471082621aed0070000000000002200203e68115ae0b15b8de75b6c6bc9af5ac9f01391544e0870dae443a1e8fe7837ead007000000000000220020fe0598d74fee2205cc3672e6e6647706b4f3099713b4661b62482c3addd04a5eb80b000000000000220020f96d0334feb64a4f40eb272031d07afcb038db56aa57446d60308c9f8ccadef9a00f000000000000220020ce6e751274836ff59622a0d1e07f8831d80bd6730bd48581398bfadd2bb8da9ac0c62d0000000000220020f3394e1e619b0eca1f91be2fb5ab4dfc59ba5b84ebe014ad1d43a564d012994a4c9e6a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0400483045022100cf8f902751006923e4062f5dbf55f8475bef08f4b5ac060d219bbff6c1a4431b02206006c515754ffc1f4f263004f61082e1fe4241449629da9096b0679e7e30972201473044022076a51aed1bd085487a7023f2ca8a87544a60a5b7277805b614b6ff7d36f1a44c02207ffac246b6572f3b4c9a7867ffa97c203500eebbf14659df78cfa0fadea22a6401475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220"),
+ OutPoint(randomTxId(), 0) -> Transaction.read("02000000000101b8cefef62ea66f5178b9361b2371be0759cbc8c689bcfa7a8e6746d497ec221a040000000001000000010a060000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e050047304402203c3a699fb80a38112aafd73d6e3a9b7d40bc2c3ed8b7fbc182a20f43b215172202204e71821b984d1af52c4b8e2cd4c572578c12a965866130c2345f61e4c2d3fef48347304402205bcfa92f83c69289a412b0b6dd4f2a0fe0b0fc2d45bd74706e963257a09ea24902203783e47883e60b86240e877fcbf33d50b1742f65bc93b3162d1be26583b367ee012001010101010101010101010101010101010101010101010101010101010101018d76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a9144b6b2e5444c2639cc0fb7bcea5afba3f3cdce23988527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f501b175ac6851b2756800000000"),
+ OutPoint(randomTxId(), 454513) -> Transaction.read("02000000000101ab84ff284f162cfbfef241f853b47d4368d171f9e2a1445160cd591c4c7d882b00000000000000000001e8030000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100d9e29616b8f3959f1d3d7f7ce893ffedcdc407717d0de8e37d808c91d3a7c50d022078c3033f6d00095c8720a4bc943c1b45727818c082e4e3ddbc6d3116435b624b014730440220636de5682ef0c5b61f124ec74e8aa2461a69777521d6998295dcea36bc3338110220165285594b23c50b28b82df200234566628a27bcd17f7f14404bd865354eb3ce012000000000000000000000000000000000000000000000000000000000000000008a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc688527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f401b175ac686800000000")
)
assert(spentMapCodec.decodeValue(spentMapCodec.encode(map).require).require == map)
}
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/wire/internal/channel/version4/ChannelCodecs4Spec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/wire/internal/channel/version4/ChannelCodecs4Spec.scala
index 4eb7d3cf65..f4e8700965 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/wire/internal/channel/version4/ChannelCodecs4Spec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/wire/internal/channel/version4/ChannelCodecs4Spec.scala
@@ -4,6 +4,7 @@ import com.softwaremill.quicklens.ModifyPimp
import fr.acinq.bitcoin.scalacompat.{DeterministicWallet, OutPoint, Satoshi, SatoshiLong, Script, Transaction, TxIn, TxOut}
import fr.acinq.eclair.FeatureSupport.{Mandatory, Optional}
import fr.acinq.eclair.Features.{ChannelRangeQueries, PaymentSecret, VariableLengthOnion}
+import fr.acinq.eclair.TestUtils.randomTxId
import fr.acinq.eclair.blockchain.fee.FeeratePerKw
import fr.acinq.eclair.channel._
import fr.acinq.eclair.channel.fund.InteractiveTxBuilder.{InteractiveTxParams, PartiallySignedSharedTransaction, RequireConfirmedInputs, SharedTransaction}
@@ -120,7 +121,7 @@ class ChannelCodecs4Spec extends AnyFunSuite {
test("encode/decode rbf status") {
val channelId = randomBytes32()
- val fundingInput = InputInfo(OutPoint(randomBytes32(), 3), TxOut(175_000 sat, Script.pay2wpkh(randomKey().publicKey)), Nil)
+ val fundingInput = InputInfo(OutPoint(randomTxId(), 3), TxOut(175_000 sat, Script.pay2wpkh(randomKey().publicKey)), Nil)
val fundingTx = SharedTransaction(
sharedInput_opt = None,
sharedOutput = InteractiveTxBuilder.Output.Shared(UInt64(8), ByteVector.empty, 100_000_600 msat, 74_000_400 msat, 0 msat),
@@ -135,9 +136,9 @@ class ChannelCodecs4Spec extends AnyFunSuite {
val waitingForSigs = InteractiveTxSigningSession.WaitingForSigs(
InteractiveTxParams(channelId, isInitiator = true, 100_000 sat, 75_000 sat, None, randomKey().publicKey, Nil, 0, 330 sat, FeeratePerKw(500 sat), RequireConfirmedInputs(forLocal = false, forRemote = false)),
fundingTxIndex = 0,
- PartiallySignedSharedTransaction(fundingTx, TxSignatures(channelId, randomBytes32(), Nil)),
+ PartiallySignedSharedTransaction(fundingTx, TxSignatures(channelId, randomTxId(), Nil)),
Left(UnsignedLocalCommit(0, CommitmentSpec(Set.empty, FeeratePerKw(1000 sat), 100_000_000 msat, 75_000_000 msat), commitTx, Nil)),
- RemoteCommit(0, CommitmentSpec(Set.empty, FeeratePerKw(1000 sat), 75_000_000 msat, 100_000_000 msat), randomBytes32(), randomKey().publicKey)
+ RemoteCommit(0, CommitmentSpec(Set.empty, FeeratePerKw(1000 sat), 75_000_000 msat, 100_000_000 msat), randomTxId(), randomKey().publicKey)
)
val testCases = Map(
RbfStatus.NoRbf -> RbfStatus.NoRbf,
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/wire/protocol/ExtendedQueriesCodecsSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/wire/protocol/ExtendedQueriesCodecsSpec.scala
index ae6fe2caea..d9e07d944c 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/wire/protocol/ExtendedQueriesCodecsSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/wire/protocol/ExtendedQueriesCodecsSpec.scala
@@ -16,7 +16,7 @@
package fr.acinq.eclair.wire.protocol
-import fr.acinq.bitcoin.scalacompat.{Block, ByteVector32, ByteVector64}
+import fr.acinq.bitcoin.scalacompat.{Block, BlockHash, ByteVector32, ByteVector64}
import fr.acinq.eclair.router.Sync
import fr.acinq.eclair.wire.protocol.LightningMessageCodecs._
import fr.acinq.eclair.wire.protocol.ReplyChannelRangeTlv._
@@ -65,7 +65,7 @@ class ExtendedQueriesCodecsSpec extends AnyFunSuite {
test("encode query_short_channel_ids (no optional data)") {
val query_short_channel_id = QueryShortChannelIds(
- Block.RegtestGenesisBlock.blockId,
+ Block.RegtestGenesisBlock.hash,
EncodedShortChannelIds(EncodingType.UNCOMPRESSED, List(RealShortChannelId(142), RealShortChannelId(15465), RealShortChannelId(4564676))),
TlvStream.empty)
@@ -76,7 +76,7 @@ class ExtendedQueriesCodecsSpec extends AnyFunSuite {
test("encode query_short_channel_ids (with optional data)") {
val query_short_channel_id = QueryShortChannelIds(
- Block.RegtestGenesisBlock.blockId,
+ Block.RegtestGenesisBlock.hash,
EncodedShortChannelIds(EncodingType.UNCOMPRESSED, List(RealShortChannelId(142), RealShortChannelId(15465), RealShortChannelId(4564676))),
TlvStream(QueryShortChannelIdsTlv.EncodedQueryFlags(EncodingType.UNCOMPRESSED, List(1.toByte, 2.toByte, 3.toByte, 4.toByte, 5.toByte))))
@@ -87,7 +87,7 @@ class ExtendedQueriesCodecsSpec extends AnyFunSuite {
test("encode query_short_channel_ids (with optional data including unknown data)") {
val query_short_channel_id = QueryShortChannelIds(
- Block.RegtestGenesisBlock.blockId,
+ Block.RegtestGenesisBlock.hash,
EncodedShortChannelIds(EncodingType.UNCOMPRESSED, List(RealShortChannelId(142), RealShortChannelId(15465), RealShortChannelId(4564676))),
TlvStream(
Set[QueryShortChannelIdsTlv](QueryShortChannelIdsTlv.EncodedQueryFlags(EncodingType.UNCOMPRESSED, List(1.toByte, 2.toByte, 3.toByte, 4.toByte, 5.toByte))),
@@ -102,7 +102,7 @@ class ExtendedQueriesCodecsSpec extends AnyFunSuite {
test("encode reply_channel_range (no optional data)") {
val replyChannelRange = ReplyChannelRange(
- Block.RegtestGenesisBlock.blockId,
+ Block.RegtestGenesisBlock.hash,
BlockHeight(1), 100,
1.toByte,
EncodedShortChannelIds(EncodingType.UNCOMPRESSED, List(RealShortChannelId(142), RealShortChannelId(15465), RealShortChannelId(4564676))),
@@ -115,7 +115,7 @@ class ExtendedQueriesCodecsSpec extends AnyFunSuite {
test("encode reply_channel_range (with optional timestamps)") {
val replyChannelRange = ReplyChannelRange(
- Block.RegtestGenesisBlock.blockId,
+ Block.RegtestGenesisBlock.hash,
BlockHeight(1), 100,
1.toByte,
EncodedShortChannelIds(EncodingType.UNCOMPRESSED, List(RealShortChannelId(142), RealShortChannelId(15465), RealShortChannelId(4564676))),
@@ -129,7 +129,7 @@ class ExtendedQueriesCodecsSpec extends AnyFunSuite {
test("encode reply_channel_range (with optional timestamps, checksums, and unknown data)") {
val replyChannelRange = ReplyChannelRange(
- Block.RegtestGenesisBlock.blockId,
+ Block.RegtestGenesisBlock.hash,
BlockHeight(1), 100,
1.toByte,
EncodedShortChannelIds(EncodingType.UNCOMPRESSED, List(RealShortChannelId(142), RealShortChannelId(15465), RealShortChannelId(4564676))),
@@ -149,7 +149,7 @@ class ExtendedQueriesCodecsSpec extends AnyFunSuite {
test("compute checksums correctly") {
val update = ChannelUpdate(
- chainHash = ByteVector32.fromValidHex("06226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f"),
+ chainHash = BlockHash(ByteVector32.fromValidHex("06226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f")),
signature = ByteVector64.fromValidHex("76df7e70c63cc2b63ef1c062b99c6d934a80ef2fd4dae9e1d86d277f47674af3255a97fa52ade7f129263f591ed784996eba6383135896cc117a438c80293282"),
shortChannelId = ShortChannelId.fromCoordinates("103x1x0").success.value,
timestamp = TimestampSecond(1565587763L),
@@ -170,7 +170,7 @@ class ExtendedQueriesCodecsSpec extends AnyFunSuite {
test("compute checksums correctly (cln test)") {
val update = ChannelUpdate(
- chainHash = ByteVector32.fromValidHex("06226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f"),
+ chainHash = BlockHash(ByteVector32.fromValidHex("06226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f")),
signature = ByteVector64.fromValidHex("06737e9e18d3e4d0ab4066ccaecdcc10e648c5f1c5413f1610747e0d463fa7fa39c1b02ea2fd694275ecfefe4fe9631f24afd182ab75b805e16cd550941f858c"),
shortChannelId = ShortChannelId.fromCoordinates("109x1x0").success.value,
timestamp = TimestampSecond(1565587765L),
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/wire/protocol/LightningMessageCodecsSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/wire/protocol/LightningMessageCodecsSpec.scala
index cc634f6b37..d768752b16 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/wire/protocol/LightningMessageCodecsSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/wire/protocol/LightningMessageCodecsSpec.scala
@@ -18,9 +18,10 @@ package fr.acinq.eclair.wire.protocol
import com.google.common.base.Charsets
import fr.acinq.bitcoin.scalacompat.Crypto.{PrivateKey, PublicKey}
-import fr.acinq.bitcoin.scalacompat.{Block, ByteVector32, ByteVector64, OutPoint, SatoshiLong, ScriptWitness, Transaction}
+import fr.acinq.bitcoin.scalacompat.{Block, BlockHash, ByteVector32, ByteVector64, OutPoint, SatoshiLong, ScriptWitness, Transaction, TxId}
import fr.acinq.eclair.FeatureSupport.Optional
import fr.acinq.eclair.Features.DataLossProtect
+import fr.acinq.eclair.TestUtils.randomTxId
import fr.acinq.eclair._
import fr.acinq.eclair.blockchain.fee.FeeratePerKw
import fr.acinq.eclair.channel.{ChannelFlags, ChannelTypes}
@@ -54,9 +55,9 @@ class LightningMessageCodecsSpec extends AnyFunSuite {
def publicKey(fill: Byte) = PrivateKey(ByteVector.fill(32)(fill)).publicKey
test("encode/decode init message") {
- case class TestCase(encoded: ByteVector, rawFeatures: ByteVector, networks: List[ByteVector32], address: Option[IPAddress], valid: Boolean, reEncoded: Option[ByteVector] = None)
- val chainHash1 = ByteVector32(hex"0101010101010101010101010101010101010101010101010101010101010101")
- val chainHash2 = ByteVector32(hex"0202020202020202020202020202020202020202020202020202020202020202")
+ case class TestCase(encoded: ByteVector, rawFeatures: ByteVector, networks: List[BlockHash], address: Option[IPAddress], valid: Boolean, reEncoded: Option[ByteVector] = None)
+ val chainHash1 = BlockHash(ByteVector32(hex"0101010101010101010101010101010101010101010101010101010101010101"))
+ val chainHash2 = BlockHash(ByteVector32(hex"0202020202020202020202020202020202020202020202020202020202020202"))
val remoteAddress1 = IPv4(InetAddress.getByAddress(Array[Byte](140.toByte, 82.toByte, 121.toByte, 3.toByte)).asInstanceOf[Inet4Address], 9735)
val remoteAddress2 = IPv6(InetAddress.getByAddress(hex"b643 8bb1 c1f9 0556 487c 0acb 2ba3 3cc2".toArray).asInstanceOf[Inet6Address], 9736)
val testCases = Seq(
@@ -123,7 +124,7 @@ class LightningMessageCodecsSpec extends AnyFunSuite {
val signature = randomBytes64()
val key = randomKey()
val point = randomKey().publicKey
- val txHash = randomBytes32()
+ val txId = randomTxId()
val randomData = randomBytes(42)
val tlvTag = UInt64(hex"47010000")
@@ -133,7 +134,7 @@ class LightningMessageCodecsSpec extends AnyFunSuite {
hex"0023" ++ channelId ++ signature ++ hex"fe47010000 07 cccccccccccccc" -> FundingSigned(channelId, signature, TlvStream[FundingSignedTlv](Set.empty[FundingSignedTlv], Set(GenericTlv(tlvTag, hex"cccccccccccccc")))),
hex"0088" ++ channelId ++ hex"0001020304050607 0809aabbccddeeff" ++ key.value ++ point.value -> ChannelReestablish(channelId, 0x01020304050607L, 0x0809aabbccddeeffL, key, point),
- hex"0088" ++ channelId ++ hex"0001020304050607 0809aabbccddeeff" ++ key.value ++ point.value ++ hex"00 20" ++ txHash.bytes -> ChannelReestablish(channelId, 0x01020304050607L, 0x0809aabbccddeeffL, key, point, TlvStream(ChannelReestablishTlv.NextFundingTlv(txHash))),
+ hex"0088" ++ channelId ++ hex"0001020304050607 0809aabbccddeeff" ++ key.value ++ point.value ++ hex"00 20" ++ txId.value.reverse -> ChannelReestablish(channelId, 0x01020304050607L, 0x0809aabbccddeeffL, key, point, TlvStream(ChannelReestablishTlv.NextFundingTlv(txId))),
hex"0088" ++ channelId ++ hex"0001020304050607 0809aabbccddeeff" ++ key.value ++ point.value ++ hex"fe47010000 00" -> ChannelReestablish(channelId, 0x01020304050607L, 0x0809aabbccddeeffL, key, point, TlvStream[ChannelReestablishTlv](Set.empty[ChannelReestablishTlv], Set(GenericTlv(tlvTag, ByteVector.empty)))),
hex"0088" ++ channelId ++ hex"0001020304050607 0809aabbccddeeff" ++ key.value ++ point.value ++ hex"fe47010000 07 bbbbbbbbbbbbbb" -> ChannelReestablish(channelId, 0x01020304050607L, 0x0809aabbccddeeffL, key, point, TlvStream[ChannelReestablishTlv](Set.empty[ChannelReestablishTlv], Set(GenericTlv(tlvTag, hex"bbbbbbbbbbbbbb")))),
@@ -214,7 +215,7 @@ class LightningMessageCodecsSpec extends AnyFunSuite {
}
test("encode/decode open_channel") {
- val defaultOpen = OpenChannel(ByteVector32.Zeroes, ByteVector32.Zeroes, 1 sat, 1 msat, 1 sat, UInt64(1), 1 sat, 1 msat, FeeratePerKw(1 sat), CltvExpiryDelta(1), 1, publicKey(1), point(2), point(3), point(4), point(5), point(6), ChannelFlags.Private)
+ val defaultOpen = OpenChannel(BlockHash(ByteVector32.Zeroes), ByteVector32.Zeroes, 1 sat, 1 msat, 1 sat, UInt64(1), 1 sat, 1 msat, FeeratePerKw(1 sat), CltvExpiryDelta(1), 1, publicKey(1), point(2), point(3), point(4), point(5), point(6), ChannelFlags.Private)
// Legacy encoding that omits the upfront_shutdown_script and trailing tlv stream.
// To allow extending all messages with TLV streams, the upfront_shutdown_script was moved to a TLV stream extension
// in https://github.com/lightningnetwork/lightning-rfc/pull/714 and made mandatory when including a TLV stream.
@@ -286,7 +287,7 @@ class LightningMessageCodecsSpec extends AnyFunSuite {
}
test("encode/decode open_channel (dual funding)") {
- val defaultOpen = OpenDualFundedChannel(ByteVector32.Zeroes, ByteVector32.One, FeeratePerKw(5000 sat), FeeratePerKw(4000 sat), 250_000 sat, 500 sat, UInt64(50_000), 15 msat, CltvExpiryDelta(144), 483, 650_000, publicKey(1), publicKey(2), publicKey(3), publicKey(4), publicKey(5), publicKey(6), publicKey(7), ChannelFlags(true))
+ val defaultOpen = OpenDualFundedChannel(BlockHash(ByteVector32.Zeroes), ByteVector32.One, FeeratePerKw(5000 sat), FeeratePerKw(4000 sat), 250_000 sat, 500 sat, UInt64(50_000), 15 msat, CltvExpiryDelta(144), 483, 650_000, publicKey(1), publicKey(2), publicKey(3), publicKey(4), publicKey(5), publicKey(6), publicKey(7), ChannelFlags(true))
val defaultEncoded = hex"0040 0000000000000000000000000000000000000000000000000000000000000000 0100000000000000000000000000000000000000000000000000000000000000 00001388 00000fa0 000000000003d090 00000000000001f4 000000000000c350 000000000000000f 0090 01e3 0009eb10 031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f 024d4b6cd1361032ca9bd2aeb9d900aa4d45d9ead80ac9423374c451a7254d0766 02531fe6068134503d2723133227c867ac8fa6c83c537e9a44c3c5bdbdcb1fe337 03462779ad4aad39514614751a71085f2f10e1c7a593e4e030efb5b8721ce55b0b 0362c0a046dacce86ddd0343c6d3c7c79c2208ba0d9c9cf24a6d046d21d21f90f7 03f006a18d5653c4edf5391ff23a61f03ff83d237e880ee61187fa9f379a028e0a 02989c0b76cb563971fdc9bef31ec06c3560f3249d6ee9e5d83c57625596e05f6f 01"
val testCases = Seq(
defaultOpen -> defaultEncoded,
@@ -304,7 +305,7 @@ class LightningMessageCodecsSpec extends AnyFunSuite {
}
test("decode open_channel with unknown channel flags (dual funding)") {
- val defaultOpen = OpenDualFundedChannel(ByteVector32.Zeroes, ByteVector32.One, FeeratePerKw(5000 sat), FeeratePerKw(4000 sat), 250_000 sat, 500 sat, UInt64(50_000), 15 msat, CltvExpiryDelta(144), 483, 650_000, publicKey(1), publicKey(2), publicKey(3), publicKey(4), publicKey(5), publicKey(6), publicKey(7), ChannelFlags(true))
+ val defaultOpen = OpenDualFundedChannel(BlockHash(ByteVector32.Zeroes), ByteVector32.One, FeeratePerKw(5000 sat), FeeratePerKw(4000 sat), 250_000 sat, 500 sat, UInt64(50_000), 15 msat, CltvExpiryDelta(144), 483, 650_000, publicKey(1), publicKey(2), publicKey(3), publicKey(4), publicKey(5), publicKey(6), publicKey(7), ChannelFlags(true))
val defaultEncodedWithoutFlags = hex"0040 0000000000000000000000000000000000000000000000000000000000000000 0100000000000000000000000000000000000000000000000000000000000000 00001388 00000fa0 000000000003d090 00000000000001f4 000000000000c350 000000000000000f 0090 01e3 0009eb10 031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f 024d4b6cd1361032ca9bd2aeb9d900aa4d45d9ead80ac9423374c451a7254d0766 02531fe6068134503d2723133227c867ac8fa6c83c537e9a44c3c5bdbdcb1fe337 03462779ad4aad39514614751a71085f2f10e1c7a593e4e030efb5b8721ce55b0b 0362c0a046dacce86ddd0343c6d3c7c79c2208ba0d9c9cf24a6d046d21d21f90f7 03f006a18d5653c4edf5391ff23a61f03ff83d237e880ee61187fa9f379a028e0a 02989c0b76cb563971fdc9bef31ec06c3560f3249d6ee9e5d83c57625596e05f6f"
val testCases = Seq(
defaultEncodedWithoutFlags ++ hex"00" -> ChannelFlags(false),
@@ -382,9 +383,9 @@ class LightningMessageCodecsSpec extends AnyFunSuite {
test("encode/decode all channel messages") {
val unknownTlv = GenericTlv(UInt64(5), ByteVector.fromValidHex("deadbeef"))
val msgs = List(
- OpenChannel(randomBytes32(), randomBytes32(), 3 sat, 4 msat, 5 sat, UInt64(6), 7 sat, 8 msat, FeeratePerKw(9 sat), CltvExpiryDelta(10), 11, publicKey(1), point(2), point(3), point(4), point(5), point(6), ChannelFlags.Private),
+ OpenChannel(BlockHash(randomBytes32()), randomBytes32(), 3 sat, 4 msat, 5 sat, UInt64(6), 7 sat, 8 msat, FeeratePerKw(9 sat), CltvExpiryDelta(10), 11, publicKey(1), point(2), point(3), point(4), point(5), point(6), ChannelFlags.Private),
AcceptChannel(randomBytes32(), 3 sat, UInt64(4), 5 sat, 6 msat, 7, CltvExpiryDelta(8), 9, publicKey(1), point(2), point(3), point(4), point(5), point(6)),
- FundingCreated(randomBytes32(), bin32(0), 3, randomBytes64()),
+ FundingCreated(randomBytes32(), TxId(ByteVector32.Zeroes), 3, randomBytes64()),
FundingSigned(randomBytes32(), randomBytes64()),
ChannelReady(randomBytes32(), point(2)),
ChannelReady(randomBytes32(), point(2), TlvStream(ChannelReadyTlv.ShortChannelIdTlv(Alias(123456)))),
@@ -401,13 +402,13 @@ class LightningMessageCodecsSpec extends AnyFunSuite {
NodeAnnouncement(randomBytes64(), Features(DataLossProtect -> Optional), 1 unixsec, 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),
ChannelUpdate(randomBytes64(), Block.RegtestGenesisBlock.hash, ShortChannelId(1), 2 unixsec, ChannelUpdate.MessageFlags(dontForward = false), ChannelUpdate.ChannelFlags.DUMMY, CltvExpiryDelta(3), 4 msat, 5 msat, 6, 25_000_000 msat),
AnnouncementSignatures(randomBytes32(), RealShortChannelId(42), randomBytes64(), randomBytes64()),
- GossipTimestampFilter(Block.RegtestGenesisBlock.blockId, 100000 unixsec, 1500),
- QueryShortChannelIds(Block.RegtestGenesisBlock.blockId, EncodedShortChannelIds(EncodingType.UNCOMPRESSED, List(RealShortChannelId(142), RealShortChannelId(15465), RealShortChannelId(4564676))), TlvStream.empty),
- QueryChannelRange(Block.RegtestGenesisBlock.blockId,
+ GossipTimestampFilter(Block.RegtestGenesisBlock.hash, 100000 unixsec, 1500),
+ QueryShortChannelIds(Block.RegtestGenesisBlock.hash, EncodedShortChannelIds(EncodingType.UNCOMPRESSED, List(RealShortChannelId(142), RealShortChannelId(15465), RealShortChannelId(4564676))), TlvStream.empty),
+ QueryChannelRange(Block.RegtestGenesisBlock.hash,
BlockHeight(100000),
1500,
TlvStream(Set[QueryChannelRangeTlv](QueryChannelRangeTlv.QueryFlags(QueryChannelRangeTlv.QueryFlags.WANT_ALL)), Set(unknownTlv))),
- ReplyChannelRange(Block.RegtestGenesisBlock.blockId,
+ ReplyChannelRange(Block.RegtestGenesisBlock.hash,
BlockHeight(100000), 1500, 1,
EncodedShortChannelIds(EncodingType.UNCOMPRESSED, List(RealShortChannelId(142), RealShortChannelId(15465), RealShortChannelId(4564676))),
TlvStream(
@@ -442,13 +443,13 @@ class LightningMessageCodecsSpec extends AnyFunSuite {
test("non-reg encoding type") {
val refs = Map(
hex"01050f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206001900000000000000008e0000000000003c69000000000045a6c4"
- -> QueryShortChannelIds(Block.RegtestGenesisBlock.blockId, EncodedShortChannelIds(EncodingType.UNCOMPRESSED, List(RealShortChannelId(142), RealShortChannelId(15465), RealShortChannelId(4564676))), TlvStream.empty),
+ -> QueryShortChannelIds(Block.RegtestGenesisBlock.hash, EncodedShortChannelIds(EncodingType.UNCOMPRESSED, List(RealShortChannelId(142), RealShortChannelId(15465), RealShortChannelId(4564676))), TlvStream.empty),
hex"01050f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206001601789c636000833e08659309a65c971d0100126e02e3"
- -> QueryShortChannelIds(Block.RegtestGenesisBlock.blockId, EncodedShortChannelIds(EncodingType.COMPRESSED_ZLIB, List(RealShortChannelId(142), RealShortChannelId(15465), RealShortChannelId(4564676))), TlvStream.empty),
+ -> QueryShortChannelIds(Block.RegtestGenesisBlock.hash, EncodedShortChannelIds(EncodingType.COMPRESSED_ZLIB, List(RealShortChannelId(142), RealShortChannelId(15465), RealShortChannelId(4564676))), TlvStream.empty),
hex"01050f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206001900000000000000008e0000000000003c69000000000045a6c4010400010204"
- -> QueryShortChannelIds(Block.RegtestGenesisBlock.blockId, EncodedShortChannelIds(EncodingType.UNCOMPRESSED, List(RealShortChannelId(142), RealShortChannelId(15465), RealShortChannelId(4564676))), TlvStream(QueryShortChannelIdsTlv.EncodedQueryFlags(EncodingType.UNCOMPRESSED, List(1, 2, 4)))),
+ -> QueryShortChannelIds(Block.RegtestGenesisBlock.hash, EncodedShortChannelIds(EncodingType.UNCOMPRESSED, List(RealShortChannelId(142), RealShortChannelId(15465), RealShortChannelId(4564676))), TlvStream(QueryShortChannelIdsTlv.EncodedQueryFlags(EncodingType.UNCOMPRESSED, List(1, 2, 4)))),
hex"01050f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206001601789c636000833e08659309a65c971d0100126e02e3010c01789c6364620100000e0008"
- -> QueryShortChannelIds(Block.RegtestGenesisBlock.blockId, EncodedShortChannelIds(EncodingType.COMPRESSED_ZLIB, List(RealShortChannelId(142), RealShortChannelId(15465), RealShortChannelId(4564676))), TlvStream(QueryShortChannelIdsTlv.EncodedQueryFlags(EncodingType.COMPRESSED_ZLIB, List(1, 2, 4))))
+ -> QueryShortChannelIds(Block.RegtestGenesisBlock.hash, EncodedShortChannelIds(EncodingType.COMPRESSED_ZLIB, List(RealShortChannelId(142), RealShortChannelId(15465), RealShortChannelId(4564676))), TlvStream(QueryShortChannelIdsTlv.EncodedQueryFlags(EncodingType.COMPRESSED_ZLIB, List(1, 2, 4))))
)
refs.forall {
@@ -460,39 +461,38 @@ class LightningMessageCodecsSpec extends AnyFunSuite {
case class TestItem(msg: Any, hex: String)
test("test vectors for extended channel queries ") {
-
val refs = Map(
- QueryChannelRange(Block.RegtestGenesisBlock.blockId, BlockHeight(100000), 1500, TlvStream.empty) ->
- hex"01070f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206000186a0000005dc",
- QueryChannelRange(Block.RegtestGenesisBlock.blockId,
+ QueryChannelRange(Block.RegtestGenesisBlock.hash, BlockHeight(100000), 1500, TlvStream.empty) ->
+ hex"010706226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f000186a0000005dc",
+ QueryChannelRange(Block.RegtestGenesisBlock.hash,
BlockHeight(35000),
100,
TlvStream(QueryChannelRangeTlv.QueryFlags(QueryChannelRangeTlv.QueryFlags.WANT_ALL))) ->
- hex"01070f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206000088b800000064010103",
- ReplyChannelRange(Block.RegtestGenesisBlock.blockId, BlockHeight(756230), 1500, 1,
+ hex"010706226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f000088b800000064010103",
+ ReplyChannelRange(Block.RegtestGenesisBlock.hash, BlockHeight(756230), 1500, 1,
EncodedShortChannelIds(EncodingType.UNCOMPRESSED, List(RealShortChannelId(142), RealShortChannelId(15465), RealShortChannelId(4564676))), None, None) ->
- hex"01080f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206000b8a06000005dc01001900000000000000008e0000000000003c69000000000045a6c4",
- ReplyChannelRange(Block.RegtestGenesisBlock.blockId, BlockHeight(1600), 110, 1,
+ hex"010806226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f000b8a06000005dc01001900000000000000008e0000000000003c69000000000045a6c4",
+ ReplyChannelRange(Block.RegtestGenesisBlock.hash, BlockHeight(1600), 110, 1,
EncodedShortChannelIds(EncodingType.COMPRESSED_ZLIB, List(RealShortChannelId(142), RealShortChannelId(15465), RealShortChannelId(265462))), None, None) ->
- hex"01080f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206000006400000006e01001601789c636000833e08659309a65878be010010a9023a",
- ReplyChannelRange(Block.RegtestGenesisBlock.blockId, BlockHeight(122334), 1500, 1,
+ hex"010806226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f000006400000006e01001601789c636000833e08659309a65878be010010a9023a",
+ ReplyChannelRange(Block.RegtestGenesisBlock.hash, BlockHeight(122334), 1500, 1,
EncodedShortChannelIds(EncodingType.UNCOMPRESSED, List(RealShortChannelId(12355), RealShortChannelId(489686), RealShortChannelId(4645313))),
Some(EncodedTimestamps(EncodingType.UNCOMPRESSED, List(Timestamps(164545 unixsec, 948165 unixsec), Timestamps(489645 unixsec, 4786864 unixsec), Timestamps(46456 unixsec, 9788415 unixsec)))),
Some(EncodedChecksums(List(Checksums(1111, 2222), Checksums(3333, 4444), Checksums(5555, 6666))))) ->
- hex"01080f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e22060001ddde000005dc01001900000000000000304300000000000778d6000000000046e1c1011900000282c1000e77c5000778ad00490ab00000b57800955bff031800000457000008ae00000d050000115c000015b300001a0a",
- ReplyChannelRange(Block.RegtestGenesisBlock.blockId, BlockHeight(122334), 1500, 1,
+ hex"010806226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f0001ddde000005dc01001900000000000000304300000000000778d6000000000046e1c1011900000282c1000e77c5000778ad00490ab00000b57800955bff031800000457000008ae00000d050000115c000015b300001a0a",
+ ReplyChannelRange(Block.RegtestGenesisBlock.hash, BlockHeight(122334), 1500, 1,
EncodedShortChannelIds(EncodingType.COMPRESSED_ZLIB, List(RealShortChannelId(12355), RealShortChannelId(489686), RealShortChannelId(4645313))),
Some(EncodedTimestamps(EncodingType.COMPRESSED_ZLIB, List(Timestamps(164545 unixsec, 948165 unixsec), Timestamps(489645 unixsec, 4786864 unixsec), Timestamps(46456 unixsec, 9788415 unixsec)))),
Some(EncodedChecksums(List(Checksums(1111, 2222), Checksums(3333, 4444), Checksums(5555, 6666))))) ->
- hex"01080f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e22060001ddde000005dc01001801789c63600001036730c55e710d4cbb3d3c080017c303b1012201789c63606a3ac8c0577e9481bd622d8327d7060686ad150c53a3ff0300554707db031800000457000008ae00000d050000115c000015b300001a0a",
- QueryShortChannelIds(Block.RegtestGenesisBlock.blockId, EncodedShortChannelIds(EncodingType.UNCOMPRESSED, List(RealShortChannelId(142), RealShortChannelId(15465), RealShortChannelId(4564676))), TlvStream.empty) ->
- hex"01050f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206001900000000000000008e0000000000003c69000000000045a6c4",
- QueryShortChannelIds(Block.RegtestGenesisBlock.blockId, EncodedShortChannelIds(EncodingType.COMPRESSED_ZLIB, List(RealShortChannelId(4564), RealShortChannelId(178622), RealShortChannelId(4564676))), TlvStream.empty) ->
- hex"01050f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206001801789c63600001c12b608a69e73e30edbaec0800203b040e",
- QueryShortChannelIds(Block.RegtestGenesisBlock.blockId, EncodedShortChannelIds(EncodingType.UNCOMPRESSED, List(RealShortChannelId(12232), RealShortChannelId(15556), RealShortChannelId(4564676))), TlvStream(QueryShortChannelIdsTlv.EncodedQueryFlags(EncodingType.COMPRESSED_ZLIB, List(1, 2, 4)))) ->
- hex"01050f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e22060019000000000000002fc80000000000003cc4000000000045a6c4010c01789c6364620100000e0008",
- QueryShortChannelIds(Block.RegtestGenesisBlock.blockId, EncodedShortChannelIds(EncodingType.COMPRESSED_ZLIB, List(RealShortChannelId(14200), RealShortChannelId(46645), RealShortChannelId(4564676))), TlvStream(QueryShortChannelIdsTlv.EncodedQueryFlags(EncodingType.COMPRESSED_ZLIB, List(1, 2, 4)))) ->
- hex"01050f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206001801789c63600001f30a30c5b0cd144cb92e3b020017c6034a010c01789c6364620100000e0008"
+ hex"010806226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f0001ddde000005dc01001801789c63600001036730c55e710d4cbb3d3c080017c303b1012201789c63606a3ac8c0577e9481bd622d8327d7060686ad150c53a3ff0300554707db031800000457000008ae00000d050000115c000015b300001a0a",
+ QueryShortChannelIds(Block.RegtestGenesisBlock.hash, EncodedShortChannelIds(EncodingType.UNCOMPRESSED, List(RealShortChannelId(142), RealShortChannelId(15465), RealShortChannelId(4564676))), TlvStream.empty) ->
+ hex"010506226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f001900000000000000008e0000000000003c69000000000045a6c4",
+ QueryShortChannelIds(Block.RegtestGenesisBlock.hash, EncodedShortChannelIds(EncodingType.COMPRESSED_ZLIB, List(RealShortChannelId(4564), RealShortChannelId(178622), RealShortChannelId(4564676))), TlvStream.empty) ->
+ hex"010506226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f001801789c63600001c12b608a69e73e30edbaec0800203b040e",
+ QueryShortChannelIds(Block.RegtestGenesisBlock.hash, EncodedShortChannelIds(EncodingType.UNCOMPRESSED, List(RealShortChannelId(12232), RealShortChannelId(15556), RealShortChannelId(4564676))), TlvStream(QueryShortChannelIdsTlv.EncodedQueryFlags(EncodingType.COMPRESSED_ZLIB, List(1, 2, 4)))) ->
+ hex"010506226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f0019000000000000002fc80000000000003cc4000000000045a6c4010c01789c6364620100000e0008",
+ QueryShortChannelIds(Block.RegtestGenesisBlock.hash, EncodedShortChannelIds(EncodingType.COMPRESSED_ZLIB, List(RealShortChannelId(14200), RealShortChannelId(46645), RealShortChannelId(4564676))), TlvStream(QueryShortChannelIdsTlv.EncodedQueryFlags(EncodingType.COMPRESSED_ZLIB, List(1, 2, 4)))) ->
+ hex"010506226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f001801789c63600001f30a30c5b0cd144cb92e3b020017c6034a010c01789c6364620100000e0008"
)
val items = refs.map { case (obj, refbin) =>
@@ -555,7 +555,7 @@ class LightningMessageCodecsSpec extends AnyFunSuite {
// 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 unixsec, ChannelUpdate.MessageFlags(dontForward = false), ChannelUpdate.ChannelFlags(isEnabled = true, isNode1 = false), CltvExpiryDelta(6), 1 msat, 1 msat, 10, 980_000_000 msat))
+ assert(update == ChannelUpdate(ByteVector64(hex"58fff7d0e987e2cdd560e3bb5a046b4efe7b26c969c2f51da1dceec7bcb8ae1b634790503d5290c1a6c51d681cf8f4211d27ed33a257dcc1102862571bf17923"), BlockHash(ByteVector32(hex"06226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f")), ShortChannelId(0x5a10000020000L), 1539791129 unixsec, ChannelUpdate.MessageFlags(dontForward = false), ChannelUpdate.ChannelFlags(isEnabled = true, isNode1 = false), CltvExpiryDelta(6), 1 msat, 1 msat, 10, 980_000_000 msat))
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/protocol/OfferTypesSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/wire/protocol/OfferTypesSpec.scala
index 2a9cba1c1b..623a54c384 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/wire/protocol/OfferTypesSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/wire/protocol/OfferTypesSpec.scala
@@ -18,7 +18,7 @@ package fr.acinq.eclair.wire.protocol
import fr.acinq.bitcoin.Bech32
import fr.acinq.bitcoin.scalacompat.Crypto.{PrivateKey, PublicKey}
-import fr.acinq.bitcoin.scalacompat.{Block, ByteVector32}
+import fr.acinq.bitcoin.scalacompat.{Block, BlockHash, ByteVector32}
import fr.acinq.eclair.FeatureSupport.{Mandatory, Optional}
import fr.acinq.eclair.Features.BasicMultiPartPayment
import fr.acinq.eclair.crypto.Sphinx.RouteBlinding.{BlindedNode, BlindedRoute}
@@ -145,7 +145,7 @@ class OfferTypesSpec extends AnyFunSuite {
assert(!otherChain.isValid)
}
{
- val (chain1, chain2) = (randomBytes32(), randomBytes32())
+ val (chain1, chain2) = (BlockHash(randomBytes32()), BlockHash(randomBytes32()))
val offer = Offer(TlvStream(OfferChains(Seq(chain1, chain2)), OfferAmount(100 msat), OfferDescription("offer with chains"), OfferNodeId(randomKey().publicKey)))
val payerKey = randomKey()
val request1 = InvoiceRequest(offer, 100 msat, 1, Features.empty, payerKey, chain1)
diff --git a/eclair-front/src/main/scala/fr/acinq/eclair/router/FrontRouter.scala b/eclair-front/src/main/scala/fr/acinq/eclair/router/FrontRouter.scala
index 676a2eef66..87e16e93e8 100644
--- a/eclair-front/src/main/scala/fr/acinq/eclair/router/FrontRouter.scala
+++ b/eclair-front/src/main/scala/fr/acinq/eclair/router/FrontRouter.scala
@@ -20,15 +20,14 @@ import akka.Done
import akka.actor.{ActorRef, Props}
import akka.event.Logging.MDC
import akka.event.LoggingAdapter
-import fr.acinq.bitcoin.scalacompat.ByteVector32
import fr.acinq.bitcoin.scalacompat.Crypto.PublicKey
+import fr.acinq.bitcoin.scalacompat.{ByteVector32, TxId}
import fr.acinq.eclair.Logs.LogCategory
-import fr.acinq.eclair.RealShortChannelId
import fr.acinq.eclair.crypto.TransportHandler
import fr.acinq.eclair.io.Peer.PeerRoutingMessage
import fr.acinq.eclair.router.Router._
import fr.acinq.eclair.wire.protocol._
-import fr.acinq.eclair.{FSMDiagnosticActorLogging, Logs, ShortChannelId, getSimpleClassName}
+import fr.acinq.eclair.{FSMDiagnosticActorLogging, Logs, RealShortChannelId, getSimpleClassName}
import kamon.Kamon
import kamon.metric.Counter
@@ -265,7 +264,7 @@ object FrontRouter {
case ChannelsDiscovered(channels) =>
log.debug("adding {} channels", channels.size)
val channels1 = channels.foldLeft(SortedMap.empty[RealShortChannelId, PublicChannel]) {
- case (channels, sc) => channels + (sc.ann.shortChannelId -> PublicChannel(sc.ann, ByteVector32.Zeroes, sc.capacity, sc.u1_opt, sc.u2_opt, None))
+ case (channels, sc) => channels + (sc.ann.shortChannelId -> PublicChannel(sc.ann, TxId(ByteVector32.Zeroes), sc.capacity, sc.u1_opt, sc.u2_opt, None))
}
val d1 = d.copy(channels = d.channels ++ channels1)
if (doRebroadcast) {
diff --git a/eclair-node/src/main/scala/fr/acinq/eclair/api/serde/FormParamExtractors.scala b/eclair-node/src/main/scala/fr/acinq/eclair/api/serde/FormParamExtractors.scala
index 035a33ea62..1c934fa1aa 100644
--- a/eclair-node/src/main/scala/fr/acinq/eclair/api/serde/FormParamExtractors.scala
+++ b/eclair-node/src/main/scala/fr/acinq/eclair/api/serde/FormParamExtractors.scala
@@ -19,7 +19,7 @@ package fr.acinq.eclair.api.serde
import akka.http.scaladsl.unmarshalling.Unmarshaller
import akka.util.Timeout
import fr.acinq.bitcoin.scalacompat.Crypto.PublicKey
-import fr.acinq.bitcoin.scalacompat.{ByteVector32, OutPoint, Satoshi}
+import fr.acinq.bitcoin.scalacompat.{ByteVector32, OutPoint, Satoshi, TxId}
import fr.acinq.eclair.api.directives.RouteFormat
import fr.acinq.eclair.api.serde.JsonSupport._
import fr.acinq.eclair.blockchain.fee.{ConfirmationPriority, FeeratePerByte}
@@ -67,7 +67,7 @@ object FormParamExtractors {
implicit val outPointListUnmarshaller: Unmarshaller[String, List[OutPoint]] = listUnmarshaller(outPoint => {
val parts = outPoint.split(":")
- OutPoint(ByteVector32.fromValidHex(parts.head).reverse, parts.last.toLong)
+ OutPoint(TxId.fromValidHex(parts.head), parts.last.toLong)
})
implicit val base64DataUnmarshaller: Unmarshaller[String, ByteVector] = Unmarshaller.strict { str => ByteVector.fromValidBase64(str) }
diff --git a/eclair-node/src/test/scala/fr/acinq/eclair/api/ApiServiceSpec.scala b/eclair-node/src/test/scala/fr/acinq/eclair/api/ApiServiceSpec.scala
index 63398d02c4..a0abe0744c 100644
--- a/eclair-node/src/test/scala/fr/acinq/eclair/api/ApiServiceSpec.scala
+++ b/eclair-node/src/test/scala/fr/acinq/eclair/api/ApiServiceSpec.scala
@@ -25,7 +25,7 @@ import akka.http.scaladsl.testkit.{RouteTestTimeout, ScalatestRouteTest, WSProbe
import akka.util.Timeout
import de.heikoseeberger.akkahttpjson4s.Json4sSupport
import fr.acinq.bitcoin.scalacompat.Crypto.{PrivateKey, PublicKey}
-import fr.acinq.bitcoin.scalacompat.{Block, ByteVector32, ByteVector64, OutPoint, SatoshiLong}
+import fr.acinq.bitcoin.scalacompat.{Block, BlockHash, ByteVector32, ByteVector64, OutPoint, SatoshiLong, TxId}
import fr.acinq.eclair.ApiTypes.ChannelIdentifier
import fr.acinq.eclair.FeatureSupport.{Mandatory, Optional}
import fr.acinq.eclair.Features.{ChannelRangeQueriesExtended, DataLossProtect}
@@ -250,7 +250,7 @@ class ApiServiceSpec extends AnyFunSuite with ScalatestRouteTest with IdiomaticM
features = Features(DataLossProtect -> Mandatory, ChannelRangeQueriesExtended -> Optional),
nodeId = aliceNodeId,
alias = "alice",
- chainHash = ByteVector32(hex"06226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f"),
+ chainHash = BlockHash(ByteVector32(hex"06226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f")),
network = "regtest",
blockHeight = 9999,
publicAddresses = NodeAddress.fromParts("127.0.0.1", 9731).get :: Nil,
@@ -274,7 +274,7 @@ class ApiServiceSpec extends AnyFunSuite with ScalatestRouteTest with IdiomaticM
test("'open' channels") {
val nodeId = PublicKey(hex"030bb6a5e0c6b203c7e2180fb78c7ba4bdce46126761d8201b91ddac089cdecc87")
val channelId = ByteVector32(hex"56d7d6eda04d80138270c49709f1eadb5ab4939e5061309ccdacdb98ce637d0e")
- val fundingTxId = ByteVector32(hex"a86b3f93c1b2ea3f221159869d6f556cae1ba2622cc8c7eb71c7f4f64e0fbca4")
+ val fundingTxId = TxId.fromValidHex("a86b3f93c1b2ea3f221159869d6f556cae1ba2622cc8c7eb71c7f4f64e0fbca4")
val eclair = mock[Eclair]
eclair.open(any, any, any, any, any, any, any)(any[Timeout]) returns Future.successful(OpenChannelResponse.Created(channelId, fundingTxId, 100 sat))
@@ -311,7 +311,7 @@ class ApiServiceSpec extends AnyFunSuite with ScalatestRouteTest with IdiomaticM
test("'open' channels with standard channelType") {
val nodeId = PublicKey(hex"030bb6a5e0c6b203c7e2180fb78c7ba4bdce46126761d8201b91ddac089cdecc87")
val channelId = ByteVector32(hex"56d7d6eda04d80138270c49709f1eadb5ab4939e5061309ccdacdb98ce637d0e")
- val fundingTxId = ByteVector32(hex"a86b3f93c1b2ea3f221159869d6f556cae1ba2622cc8c7eb71c7f4f64e0fbca4")
+ val fundingTxId = TxId.fromValidHex("a86b3f93c1b2ea3f221159869d6f556cae1ba2622cc8c7eb71c7f4f64e0fbca4")
val eclair = mock[Eclair]
eclair.open(any, any, any, any, any, any, any)(any[Timeout]) returns Future.successful(OpenChannelResponse.Created(channelId, fundingTxId, 0 sat))
@@ -332,7 +332,7 @@ class ApiServiceSpec extends AnyFunSuite with ScalatestRouteTest with IdiomaticM
test("'open' channels with static_remotekey channelType") {
val nodeId = PublicKey(hex"030bb6a5e0c6b203c7e2180fb78c7ba4bdce46126761d8201b91ddac089cdecc87")
val channelId = ByteVector32(hex"56d7d6eda04d80138270c49709f1eadb5ab4939e5061309ccdacdb98ce637d0e")
- val fundingTxId = ByteVector32(hex"a86b3f93c1b2ea3f221159869d6f556cae1ba2622cc8c7eb71c7f4f64e0fbca4")
+ val fundingTxId = TxId.fromValidHex("a86b3f93c1b2ea3f221159869d6f556cae1ba2622cc8c7eb71c7f4f64e0fbca4")
val eclair = mock[Eclair]
eclair.open(any, any, any, any, any, any, any)(any[Timeout]) returns Future.successful(OpenChannelResponse.Created(channelId, fundingTxId, 1 sat))
@@ -353,7 +353,7 @@ class ApiServiceSpec extends AnyFunSuite with ScalatestRouteTest with IdiomaticM
test("'open' channels with anchor_outputs channelType") {
val nodeId = PublicKey(hex"030bb6a5e0c6b203c7e2180fb78c7ba4bdce46126761d8201b91ddac089cdecc87")
val channelId = ByteVector32(hex"56d7d6eda04d80138270c49709f1eadb5ab4939e5061309ccdacdb98ce637d0e")
- val fundingTxId = ByteVector32(hex"a86b3f93c1b2ea3f221159869d6f556cae1ba2622cc8c7eb71c7f4f64e0fbca4")
+ val fundingTxId = TxId.fromValidHex("a86b3f93c1b2ea3f221159869d6f556cae1ba2622cc8c7eb71c7f4f64e0fbca4")
val eclair = mock[Eclair]
eclair.open(any, any, any, any, any, any, any)(any[Timeout]) returns Future.successful(OpenChannelResponse.Created(channelId, fundingTxId, 500 sat))
@@ -575,9 +575,9 @@ class ApiServiceSpec extends AnyFunSuite with ScalatestRouteTest with IdiomaticM
test("'cpfpbumpfees'") {
val eclair = mock[Eclair]
- eclair.cpfpBumpFees(any, any) returns Future.successful(randomBytes32())
+ eclair.cpfpBumpFees(any, any) returns Future.successful(TxId(randomBytes32()))
val mockService = new MockService(eclair)
- val (txId1, txId2) = (randomBytes32(), randomBytes32())
+ val (txId1, txId2) = (TxId(randomBytes32()), TxId(randomBytes32()))
Post("/cpfpbumpfees", FormData("targetFeerateSatByte" -> "10", "outpoints" -> s"$txId1:2,$txId2:0,$txId1:13").toEntity) ~>
addCredentials(BasicHttpCredentials("", mockApi().password)) ~>
@@ -585,7 +585,7 @@ class ApiServiceSpec extends AnyFunSuite with ScalatestRouteTest with IdiomaticM
check {
assert(handled)
assert(status == OK)
- eclair.cpfpBumpFees(FeeratePerByte(10 sat), Set(OutPoint(txId1.reverse, 2), OutPoint(txId1.reverse, 13), OutPoint(txId2.reverse, 0))).wasCalled(once)
+ eclair.cpfpBumpFees(FeeratePerByte(10 sat), Set(OutPoint(txId1, 2), OutPoint(txId1, 13), OutPoint(txId2, 0))).wasCalled(once)
}
Post("/cpfpbumpfees", FormData("targetFeerateSatByte" -> "10").toEntity) ~>
@@ -1032,7 +1032,7 @@ class ApiServiceSpec extends AnyFunSuite with ScalatestRouteTest with IdiomaticM
val mockChannelUpdate1 = ChannelUpdate(
signature = ByteVector64.fromValidHex("92cf3f12e161391986eb2cd7106ddab41a23c734f8f1ed120fb64f4b91f98f690ecf930388e62965f8aefbf1adafcd25a572669a125396dcfb83615208754679"),
- chainHash = ByteVector32.fromValidHex("024b7b3626554c44dcc2454ee3812458bfa68d9fced466edfab470844cb7ffe2"),
+ chainHash = BlockHash(ByteVector32.fromValidHex("024b7b3626554c44dcc2454ee3812458bfa68d9fced466edfab470844cb7ffe2")),
shortChannelId = RealShortChannelId(BlockHeight(1), 2, 3),
timestamp = 0 unixsec,
messageFlags = ChannelUpdate.MessageFlags(dontForward = false),
diff --git a/pom.xml b/pom.xml
index 41c47eea01..15e3349167 100644
--- a/pom.xml
+++ b/pom.xml
@@ -72,7 +72,7 @@
2.6.20
10.2.7
3.8.16
- 0.29
+ 0.30
32.1.1-jre
2.6.3