1
0
mirror of https://github.com/ACINQ/eclair.git synced 2024-11-19 01:43:22 +01:00

Use bitcoin-lib 0.34 (#2905)

* Use bitcoin-lib 0.34

Includes support for testnet4.
This commit is contained in:
Fabrice Drouin 2024-09-10 17:52:10 +02:00 committed by GitHub
parent d726ca19fc
commit 1ff5697267
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
24 changed files with 128 additions and 95 deletions

View File

@ -188,7 +188,9 @@ object NodeParams extends Logging {
private val chain2Hash: Map[String, BlockHash] = Map( private val chain2Hash: Map[String, BlockHash] = Map(
"regtest" -> Block.RegtestGenesisBlock.hash, "regtest" -> Block.RegtestGenesisBlock.hash,
"testnet" -> Block.TestnetGenesisBlock.hash, "testnet" -> Block.Testnet3GenesisBlock.hash,
"testnet3" -> Block.Testnet3GenesisBlock.hash,
"testnet4" -> Block.Testnet4GenesisBlock.hash,
"signet" -> Block.SignetGenesisBlock.hash, "signet" -> Block.SignetGenesisBlock.hash,
"mainnet" -> Block.LivenetGenesisBlock.hash "mainnet" -> Block.LivenetGenesisBlock.hash
) )

View File

@ -159,6 +159,7 @@ class Setup(val datadir: File,
_ <- chain match { _ <- chain match {
case "mainnet" => bitcoinClient.invoke("getrawtransaction", "2157b554dcfda405233906e461ee593875ae4b1b97615872db6a25130ecc1dd6") // coinbase of #500000 case "mainnet" => bitcoinClient.invoke("getrawtransaction", "2157b554dcfda405233906e461ee593875ae4b1b97615872db6a25130ecc1dd6") // coinbase of #500000
case "testnet" => bitcoinClient.invoke("getrawtransaction", "8f38a0dd41dc0ae7509081e262d791f8d53ed6f884323796d5ec7b0966dd3825") // coinbase of #1500000 case "testnet" => bitcoinClient.invoke("getrawtransaction", "8f38a0dd41dc0ae7509081e262d791f8d53ed6f884323796d5ec7b0966dd3825") // coinbase of #1500000
case "testnet4" => bitcoinClient.invoke("getrawtransaction", "5c50d460b3b98ea0c70baa0f50d1f0cc6ffa553788b4a7e23918bcdd558828fa") // coinbase of #40000
case "signet" => bitcoinClient.invoke("getrawtransaction", "ff1027486b628b2d160859205a3401fb2ee379b43527153b0b50a92c17ee7955") // coinbase of #5000 case "signet" => bitcoinClient.invoke("getrawtransaction", "ff1027486b628b2d160859205a3401fb2ee379b43527153b0b50a92c17ee7955") // coinbase of #5000
case "regtest" => Future.successful(()) case "regtest" => Future.successful(())
} }

View File

@ -118,7 +118,7 @@ object ExplorerApi {
case class BlockcypherExplorer()(implicit val sb: SttpBackend[Future, _]) extends Explorer { case class BlockcypherExplorer()(implicit val sb: SttpBackend[Future, _]) extends Explorer {
override val name = "blockcypher.com" override val name = "blockcypher.com"
override val baseUris = Map( override val baseUris = Map(
Block.TestnetGenesisBlock.hash -> uri"https://api.blockcypher.com/v1/btc/test3", Block.Testnet3GenesisBlock.hash -> uri"https://api.blockcypher.com/v1/btc/test3",
Block.LivenetGenesisBlock.hash -> uri"https://api.blockcypher.com/v1/btc/main" Block.LivenetGenesisBlock.hash -> uri"https://api.blockcypher.com/v1/btc/main"
) )
@ -208,12 +208,12 @@ object ExplorerApi {
override val name = "blockstream.info" override val name = "blockstream.info"
override val baseUris = if (useTorEndpoints) { override val baseUris = if (useTorEndpoints) {
Map( Map(
Block.TestnetGenesisBlock.hash -> uri"http://explorerzydxu5ecjrkwceayqybizmpjjznk5izmitf2modhcusuqlid.onion/testnet/api", Block.Testnet3GenesisBlock.hash -> uri"http://explorerzydxu5ecjrkwceayqybizmpjjznk5izmitf2modhcusuqlid.onion/testnet/api",
Block.LivenetGenesisBlock.hash -> uri"http://explorerzydxu5ecjrkwceayqybizmpjjznk5izmitf2modhcusuqlid.onion/api" Block.LivenetGenesisBlock.hash -> uri"http://explorerzydxu5ecjrkwceayqybizmpjjznk5izmitf2modhcusuqlid.onion/api"
) )
} else { } else {
Map( Map(
Block.TestnetGenesisBlock.hash -> uri"https://blockstream.info/testnet/api", Block.Testnet3GenesisBlock.hash -> uri"https://blockstream.info/testnet/api",
Block.LivenetGenesisBlock.hash -> uri"https://blockstream.info/api" Block.LivenetGenesisBlock.hash -> uri"https://blockstream.info/api"
) )
} }
@ -224,13 +224,15 @@ object ExplorerApi {
override val name = "mempool.space" override val name = "mempool.space"
override val baseUris = if (useTorEndpoints) { override val baseUris = if (useTorEndpoints) {
Map( Map(
Block.TestnetGenesisBlock.hash -> uri"http://mempoolhqx4isw62xs7abwphsq7ldayuidyx2v2oethdhhj6mlo2r6ad.onion/testnet/api", Block.Testnet4GenesisBlock.hash -> uri"http://mempoolhqx4isw62xs7abwphsq7ldayuidyx2v2oethdhhj6mlo2r6ad.onion/testnet4/api",
Block.Testnet3GenesisBlock.hash -> uri"http://mempoolhqx4isw62xs7abwphsq7ldayuidyx2v2oethdhhj6mlo2r6ad.onion/testnet/api",
Block.LivenetGenesisBlock.hash -> uri"http://mempoolhqx4isw62xs7abwphsq7ldayuidyx2v2oethdhhj6mlo2r6ad.onion/api", Block.LivenetGenesisBlock.hash -> uri"http://mempoolhqx4isw62xs7abwphsq7ldayuidyx2v2oethdhhj6mlo2r6ad.onion/api",
Block.SignetGenesisBlock.hash -> uri"http://mempoolhqx4isw62xs7abwphsq7ldayuidyx2v2oethdhhj6mlo2r6ad.onion/signet/api" Block.SignetGenesisBlock.hash -> uri"http://mempoolhqx4isw62xs7abwphsq7ldayuidyx2v2oethdhhj6mlo2r6ad.onion/signet/api"
) )
} else { } else {
Map( Map(
Block.TestnetGenesisBlock.hash -> uri"https://mempool.space/testnet/api", Block.Testnet4GenesisBlock.hash -> uri"https://mempool.space/testnet4/api",
Block.Testnet3GenesisBlock.hash -> uri"https://mempool.space/testnet/api",
Block.LivenetGenesisBlock.hash -> uri"https://mempool.space/api", Block.LivenetGenesisBlock.hash -> uri"https://mempool.space/api",
Block.SignetGenesisBlock.hash -> uri"https://mempool.space/signet/api" Block.SignetGenesisBlock.hash -> uri"https://mempool.space/signet/api"
) )

View File

@ -359,8 +359,17 @@ private class ReplaceableTxFunder(nodeParams: NodeParams,
// We create a PSBT with the non-wallet input already signed: // We create a PSBT with the non-wallet input already signed:
val psbt = new Psbt(locallySignedTx.txInfo.tx) val psbt = new Psbt(locallySignedTx.txInfo.tx)
.updateWitnessInput(locallySignedTx.txInfo.input.outPoint, locallySignedTx.txInfo.input.txOut, null, fr.acinq.bitcoin.Script.parse(locallySignedTx.txInfo.input.redeemScript), fr.acinq.bitcoin.SigHash.SIGHASH_ALL, java.util.Map.of()) .updateWitnessInput(
.flatMap(_.finalizeWitnessInput(0, locallySignedTx.txInfo.tx.txIn.head.witness)) locallySignedTx.txInfo.input.outPoint,
locallySignedTx.txInfo.input.txOut,
null,
fr.acinq.bitcoin.Script.parse(locallySignedTx.txInfo.input.redeemScript),
fr.acinq.bitcoin.SigHash.SIGHASH_ALL,
java.util.Map.of(),
null,
null,
java.util.Map.of()
).flatMap(_.finalizeWitnessInput(0, locallySignedTx.txInfo.tx.txIn.head.witness))
psbt match { psbt match {
case Left(failure) => case Left(failure) =>
log.error(s"cannot sign ${cmd.desc}: $failure") log.error(s"cannot sign ${cmd.desc}: $failure")

View File

@ -32,7 +32,7 @@ import scodec.bits.ByteVector
object LocalChannelKeyManager { object LocalChannelKeyManager {
def keyBasePath(chainHash: BlockHash): 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.RegtestGenesisBlock.hash | Block.Testnet4GenesisBlock.hash | Block.Testnet3GenesisBlock.hash | Block.SignetGenesisBlock.hash => DeterministicWallet.hardened(46) :: DeterministicWallet.hardened(1) :: Nil
case Block.LivenetGenesisBlock.hash => DeterministicWallet.hardened(47) :: DeterministicWallet.hardened(1) :: Nil case Block.LivenetGenesisBlock.hash => DeterministicWallet.hardened(47) :: DeterministicWallet.hardened(1) :: Nil
} }
} }

View File

@ -28,7 +28,7 @@ object LocalNodeKeyManager {
// Note that the node path and the above channel path are on different branches so even if the // 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 // node key is compromised there is no way to retrieve the wallet keys
def keyBasePath(chainHash: BlockHash): 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.RegtestGenesisBlock.hash | Block.Testnet3GenesisBlock.hash | Block.Testnet4GenesisBlock.hash | Block.SignetGenesisBlock.hash => DeterministicWallet.hardened(46) :: DeterministicWallet.hardened(0) :: Nil
case Block.LivenetGenesisBlock.hash => DeterministicWallet.hardened(47) :: DeterministicWallet.hardened(0) :: Nil case Block.LivenetGenesisBlock.hash => DeterministicWallet.hardened(47) :: DeterministicWallet.hardened(0) :: Nil
} }
} }

View File

@ -74,7 +74,7 @@ class LocalOnChainKeyManager(override val walletName: String, seed: ByteVector,
private val fingerPrintHex = String.format("%8s", fingerprint.toHexString).replace(' ', '0') private val fingerPrintHex = String.format("%8s", fingerprint.toHexString).replace(' ', '0')
// Root BIP32 on-chain path: we use BIP84 (p2wpkh) paths: m/84h/{0h/1h} // Root BIP32 on-chain path: we use BIP84 (p2wpkh) paths: m/84h/{0h/1h}
private val rootPath = chainHash match { private val rootPath = chainHash match {
case Block.RegtestGenesisBlock.hash | Block.TestnetGenesisBlock.hash | Block.SignetGenesisBlock.hash => "84h/1h" case Block.RegtestGenesisBlock.hash | Block.Testnet3GenesisBlock.hash | Block.Testnet4GenesisBlock.hash | Block.SignetGenesisBlock.hash => "84h/1h"
case Block.LivenetGenesisBlock.hash => "84h/0h" case Block.LivenetGenesisBlock.hash => "84h/0h"
case _ => throw new IllegalArgumentException(s"invalid chain hash $chainHash") case _ => throw new IllegalArgumentException(s"invalid chain hash $chainHash")
} }
@ -82,7 +82,7 @@ class LocalOnChainKeyManager(override val walletName: String, seed: ByteVector,
override def masterPubKey(account: Long): String = { override def masterPubKey(account: Long): String = {
val prefix = chainHash match { val prefix = chainHash match {
case Block.RegtestGenesisBlock.hash | Block.TestnetGenesisBlock.hash | Block.SignetGenesisBlock.hash => vpub case Block.RegtestGenesisBlock.hash | Block.Testnet3GenesisBlock.hash | Block.Testnet4GenesisBlock.hash | Block.SignetGenesisBlock.hash => vpub
case Block.LivenetGenesisBlock.hash => zpub case Block.LivenetGenesisBlock.hash => zpub
case _ => throw new IllegalArgumentException(s"invalid chain hash $chainHash") case _ => throw new IllegalArgumentException(s"invalid chain hash $chainHash")
} }
@ -202,7 +202,16 @@ class LocalOnChainKeyManager(override val walletName: String, seed: ByteVector,
require(kmp2scala(input.getWitnessUtxo.publicKeyScript) == expectedScript, s"script mismatch (expected=$expectedScript, actual=${input.getWitnessUtxo.publicKeyScript}): bitcoin core may be malicious") 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. // 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.global.tx.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,
null,
null,
java.util.Map.of())
val signed = updated.flatMap(_.sign(priv, pos)) val signed = updated.flatMap(_.sign(priv, pos))
val finalized = signed.flatMap(s => { val finalized = signed.flatMap(s => {
require(s.getSig.last.toInt == SigHash.SIGHASH_ALL, "signature must end with SIGHASH_ALL") require(s.getSig.last.toInt == SigHash.SIGHASH_ALL, "signature must end with SIGHASH_ALL")

View File

@ -138,7 +138,8 @@ object Bolt11Invoice {
val prefixes = Map( val prefixes = Map(
Block.RegtestGenesisBlock.hash -> "lnbcrt", Block.RegtestGenesisBlock.hash -> "lnbcrt",
Block.SignetGenesisBlock.hash -> "lntbs", Block.SignetGenesisBlock.hash -> "lntbs",
Block.TestnetGenesisBlock.hash -> "lntb", Block.Testnet3GenesisBlock.hash -> "lntb",
Block.Testnet4GenesisBlock.hash -> "lntb",
Block.LivenetGenesisBlock.hash -> "lnbc" Block.LivenetGenesisBlock.hash -> "lnbc"
) )
@ -531,7 +532,7 @@ object Bolt11Invoice {
val lowercaseInput = input.toLowerCase val lowercaseInput = input.toLowerCase
val separatorIndex = lowercaseInput.lastIndexOf('1') val separatorIndex = lowercaseInput.lastIndexOf('1')
val hrp = lowercaseInput.take(separatorIndex) val hrp = lowercaseInput.take(separatorIndex)
val prefix: String = prefixes.values.find(prefix => hrp.startsWith(prefix)).getOrElse(throw new RuntimeException("unknown prefix")) val prefix: String = prefixes.values.toSeq.sortBy(_.length).findLast(prefix => hrp.startsWith(prefix)).getOrElse(throw new RuntimeException("unknown prefix"))
val data = string2Bits(lowercaseInput.slice(separatorIndex + 1, lowercaseInput.length - 6)) // 6 == checksum size val data = string2Bits(lowercaseInput.slice(separatorIndex + 1, lowercaseInput.length - 6)) // 6 == checksum size
val bolt11Data = Codecs.bolt11DataCodec.decode(data).require.value val bolt11Data = Codecs.bolt11DataCodec.decode(data).require.value
val signature = ByteVector64(bolt11Data.signature.take(64)) val signature = ByteVector64(bolt11Data.signature.take(64))

View File

@ -50,16 +50,16 @@ class PackageSpec extends AnyFunSuite {
// p2pkh // p2pkh
// valid chain // valid chain
assert(addressToPublicKeyScript(Block.TestnetGenesisBlock.hash, Base58Check.encode(Base58.Prefix.PubkeyAddressTestnet, pub.hash160)) == Right(Script.pay2pkh(pub))) assert(addressToPublicKeyScript(Block.Testnet3GenesisBlock.hash, Base58Check.encode(Base58.Prefix.PubkeyAddressTestnet, pub.hash160)) == Right(Script.pay2pkh(pub)))
assert(addressToPublicKeyScript(Block.TestnetGenesisBlock.hash, Base58Check.encode(Base58.Prefix.PubkeyAddressTestnet, pub.hash160)) == Right(Script.pay2pkh(pub))) assert(addressToPublicKeyScript(Block.Testnet3GenesisBlock.hash, Base58Check.encode(Base58.Prefix.PubkeyAddressTestnet, pub.hash160)) == Right(Script.pay2pkh(pub)))
assert(addressToPublicKeyScript(Block.TestnetGenesisBlock.hash, Base58Check.encode(Base58.Prefix.PubkeyAddressTestnet, pub.hash160)) == Right(Script.pay2pkh(pub))) assert(addressToPublicKeyScript(Block.Testnet3GenesisBlock.hash, Base58Check.encode(Base58.Prefix.PubkeyAddressTestnet, pub.hash160)) == Right(Script.pay2pkh(pub)))
assert(addressToPublicKeyScript(Block.LivenetGenesisBlock.hash, Base58Check.encode(Base58.Prefix.PubkeyAddress, pub.hash160)) == Right(Script.pay2pkh(pub))) assert(addressToPublicKeyScript(Block.LivenetGenesisBlock.hash, Base58Check.encode(Base58.Prefix.PubkeyAddress, pub.hash160)) == Right(Script.pay2pkh(pub)))
// wrong chain // wrong chain
val Left(failure) = addressToPublicKeyScript(Block.TestnetGenesisBlock.hash, Base58Check.encode(Base58.Prefix.PubkeyAddress, pub.hash160)) val Left(failure) = addressToPublicKeyScript(Block.Testnet3GenesisBlock.hash, Base58Check.encode(Base58.Prefix.PubkeyAddress, pub.hash160))
assert(failure.isInstanceOf[ChainHashMismatch]) assert(failure.isInstanceOf[ChainHashMismatch])
assert(addressToPublicKeyScript(Block.TestnetGenesisBlock.hash, Base58Check.encode(Base58.Prefix.PubkeyAddress, pub.hash160)).isLeft) assert(addressToPublicKeyScript(Block.Testnet3GenesisBlock.hash, Base58Check.encode(Base58.Prefix.PubkeyAddress, pub.hash160)).isLeft)
assert(addressToPublicKeyScript(Block.RegtestGenesisBlock.hash, Base58Check.encode(Base58.Prefix.PubkeyAddress, pub.hash160)).isLeft) assert(addressToPublicKeyScript(Block.RegtestGenesisBlock.hash, Base58Check.encode(Base58.Prefix.PubkeyAddress, pub.hash160)).isLeft)
assert(addressToPublicKeyScript(Block.SignetGenesisBlock.hash, Base58Check.encode(Base58.Prefix.PubkeyAddress, pub.hash160)).isLeft) assert(addressToPublicKeyScript(Block.SignetGenesisBlock.hash, Base58Check.encode(Base58.Prefix.PubkeyAddress, pub.hash160)).isLeft)
@ -67,14 +67,14 @@ class PackageSpec extends AnyFunSuite {
val script = Script.write(Script.pay2wpkh(pub)) val script = Script.write(Script.pay2wpkh(pub))
// valid chain // valid chain
assert(addressToPublicKeyScript(Block.TestnetGenesisBlock.hash, Base58Check.encode(Base58.Prefix.ScriptAddressTestnet, Crypto.hash160(script))) == Right(Script.pay2sh(script))) assert(addressToPublicKeyScript(Block.Testnet3GenesisBlock.hash, Base58Check.encode(Base58.Prefix.ScriptAddressTestnet, Crypto.hash160(script))) == Right(Script.pay2sh(script)))
assert(addressToPublicKeyScript(Block.RegtestGenesisBlock.hash, Base58Check.encode(Base58.Prefix.ScriptAddressTestnet, Crypto.hash160(script))) == Right(Script.pay2sh(script))) assert(addressToPublicKeyScript(Block.RegtestGenesisBlock.hash, Base58Check.encode(Base58.Prefix.ScriptAddressTestnet, Crypto.hash160(script))) == Right(Script.pay2sh(script)))
assert(addressToPublicKeyScript(Block.SignetGenesisBlock.hash, Base58Check.encode(Base58.Prefix.ScriptAddressTestnet, Crypto.hash160(script))) == Right(Script.pay2sh(script))) assert(addressToPublicKeyScript(Block.SignetGenesisBlock.hash, Base58Check.encode(Base58.Prefix.ScriptAddressTestnet, Crypto.hash160(script))) == Right(Script.pay2sh(script)))
assert(addressToPublicKeyScript(Block.LivenetGenesisBlock.hash, Base58Check.encode(Base58.Prefix.ScriptAddress, Crypto.hash160(script))) == Right(Script.pay2sh(script))) assert(addressToPublicKeyScript(Block.LivenetGenesisBlock.hash, Base58Check.encode(Base58.Prefix.ScriptAddress, Crypto.hash160(script))) == Right(Script.pay2sh(script)))
// wrong chain // wrong chain
assert(addressToPublicKeyScript(Block.LivenetGenesisBlock.hash, Base58Check.encode(Base58.Prefix.ScriptAddressTestnet, Crypto.hash160(script))).isLeft) assert(addressToPublicKeyScript(Block.LivenetGenesisBlock.hash, Base58Check.encode(Base58.Prefix.ScriptAddressTestnet, Crypto.hash160(script))).isLeft)
assert(addressToPublicKeyScript(Block.TestnetGenesisBlock.hash, Base58Check.encode(Base58.Prefix.ScriptAddress, Crypto.hash160(script))).isLeft) assert(addressToPublicKeyScript(Block.Testnet3GenesisBlock.hash, Base58Check.encode(Base58.Prefix.ScriptAddress, Crypto.hash160(script))).isLeft)
assert(addressToPublicKeyScript(Block.RegtestGenesisBlock.hash, Base58Check.encode(Base58.Prefix.ScriptAddress, Crypto.hash160(script))).isLeft) assert(addressToPublicKeyScript(Block.RegtestGenesisBlock.hash, Base58Check.encode(Base58.Prefix.ScriptAddress, Crypto.hash160(script))).isLeft)
assert(addressToPublicKeyScript(Block.SignetGenesisBlock.hash, Base58Check.encode(Base58.Prefix.ScriptAddress, Crypto.hash160(script))).isLeft) assert(addressToPublicKeyScript(Block.SignetGenesisBlock.hash, Base58Check.encode(Base58.Prefix.ScriptAddress, Crypto.hash160(script))).isLeft)
} }
@ -85,19 +85,19 @@ class PackageSpec extends AnyFunSuite {
// p2wpkh // p2wpkh
assert(addressToPublicKeyScript(Block.LivenetGenesisBlock.hash, Bech32.encodeWitnessAddress("bc", 0, pub.hash160)) == Right(Script.pay2wpkh(pub))) assert(addressToPublicKeyScript(Block.LivenetGenesisBlock.hash, Bech32.encodeWitnessAddress("bc", 0, pub.hash160)) == Right(Script.pay2wpkh(pub)))
assert(addressToPublicKeyScript(Block.TestnetGenesisBlock.hash, Bech32.encodeWitnessAddress("tb", 0, pub.hash160)) == Right(Script.pay2wpkh(pub))) assert(addressToPublicKeyScript(Block.Testnet3GenesisBlock.hash, Bech32.encodeWitnessAddress("tb", 0, pub.hash160)) == Right(Script.pay2wpkh(pub)))
assert(addressToPublicKeyScript(Block.RegtestGenesisBlock.hash, Bech32.encodeWitnessAddress("bcrt", 0, pub.hash160)) == Right(Script.pay2wpkh(pub))) assert(addressToPublicKeyScript(Block.RegtestGenesisBlock.hash, Bech32.encodeWitnessAddress("bcrt", 0, pub.hash160)) == Right(Script.pay2wpkh(pub)))
assert(addressToPublicKeyScript(Block.SignetGenesisBlock.hash, Bech32.encodeWitnessAddress("tb", 0, pub.hash160)) == Right(Script.pay2wpkh(pub))) assert(addressToPublicKeyScript(Block.SignetGenesisBlock.hash, Bech32.encodeWitnessAddress("tb", 0, pub.hash160)) == Right(Script.pay2wpkh(pub)))
// wrong chain // wrong chain
assert(addressToPublicKeyScript(Block.TestnetGenesisBlock.hash, Bech32.encodeWitnessAddress("bc", 0, pub.hash160)).isLeft) assert(addressToPublicKeyScript(Block.Testnet3GenesisBlock.hash, Bech32.encodeWitnessAddress("bc", 0, pub.hash160)).isLeft)
assert(addressToPublicKeyScript(Block.LivenetGenesisBlock.hash, Bech32.encodeWitnessAddress("tb", 0, pub.hash160)).isLeft) assert(addressToPublicKeyScript(Block.LivenetGenesisBlock.hash, Bech32.encodeWitnessAddress("tb", 0, pub.hash160)).isLeft)
assert(addressToPublicKeyScript(Block.LivenetGenesisBlock.hash, Bech32.encodeWitnessAddress("bcrt", 0, pub.hash160)).isLeft) assert(addressToPublicKeyScript(Block.LivenetGenesisBlock.hash, Bech32.encodeWitnessAddress("bcrt", 0, pub.hash160)).isLeft)
assert(addressToPublicKeyScript(Block.LivenetGenesisBlock.hash, Bech32.encodeWitnessAddress("tb", 0, pub.hash160)).isLeft) assert(addressToPublicKeyScript(Block.LivenetGenesisBlock.hash, Bech32.encodeWitnessAddress("tb", 0, pub.hash160)).isLeft)
val script = Script.write(Script.pay2wpkh(pub)) val script = Script.write(Script.pay2wpkh(pub))
assert(addressToPublicKeyScript(Block.LivenetGenesisBlock.hash, Bech32.encodeWitnessAddress("bc", 0, Crypto.sha256(script))) == Right(Script.pay2wsh(script))) assert(addressToPublicKeyScript(Block.LivenetGenesisBlock.hash, Bech32.encodeWitnessAddress("bc", 0, Crypto.sha256(script))) == Right(Script.pay2wsh(script)))
assert(addressToPublicKeyScript(Block.TestnetGenesisBlock.hash, Bech32.encodeWitnessAddress("tb", 0, Crypto.sha256(script))) == Right(Script.pay2wsh(script))) assert(addressToPublicKeyScript(Block.Testnet3GenesisBlock.hash, Bech32.encodeWitnessAddress("tb", 0, Crypto.sha256(script))) == Right(Script.pay2wsh(script)))
assert(addressToPublicKeyScript(Block.RegtestGenesisBlock.hash, Bech32.encodeWitnessAddress("bcrt", 0, Crypto.sha256(script))) == Right(Script.pay2wsh(script))) assert(addressToPublicKeyScript(Block.RegtestGenesisBlock.hash, Bech32.encodeWitnessAddress("bcrt", 0, Crypto.sha256(script))) == Right(Script.pay2wsh(script)))
assert(addressToPublicKeyScript(Block.SignetGenesisBlock.hash, Bech32.encodeWitnessAddress("tb", 0, Crypto.sha256(script))) == Right(Script.pay2wsh(script))) assert(addressToPublicKeyScript(Block.SignetGenesisBlock.hash, Bech32.encodeWitnessAddress("tb", 0, Crypto.sha256(script))) == Right(Script.pay2wsh(script)))
} }

View File

@ -39,8 +39,8 @@ class StartupSpec extends AnyFunSuite {
def makeNodeParamsWithDefaults(conf: Config): NodeParams = { def makeNodeParamsWithDefaults(conf: Config): NodeParams = {
val blockCount = new AtomicLong(0) val blockCount = new AtomicLong(0)
val feerates = new AtomicReference(FeeratesPerKw.single(feeratePerKw)) val feerates = new AtomicReference(FeeratesPerKw.single(feeratePerKw))
val nodeKeyManager = new LocalNodeKeyManager(randomBytes32(), chainHash = Block.TestnetGenesisBlock.hash) val nodeKeyManager = new LocalNodeKeyManager(randomBytes32(), chainHash = Block.Testnet3GenesisBlock.hash)
val channelKeyManager = new LocalChannelKeyManager(randomBytes32(), chainHash = Block.TestnetGenesisBlock.hash) val channelKeyManager = new LocalChannelKeyManager(randomBytes32(), chainHash = Block.Testnet3GenesisBlock.hash)
val db = TestDatabases.inMemoryDb() val db = TestDatabases.inMemoryDb()
NodeParams.makeNodeParams(conf, UUID.fromString("01234567-0123-4567-89ab-0123456789ab"), nodeKeyManager, channelKeyManager, None, None, db, blockCount, feerates) NodeParams.makeNodeParams(conf, UUID.fromString("01234567-0123-4567-89ab-0123456789ab"), nodeKeyManager, channelKeyManager, None, None, db, blockCount, feerates)
} }

View File

@ -204,7 +204,16 @@ class SingleKeyOnChainWallet extends OnChainWallet with OnchainPubkeyCache {
case (currentPsbt, (txIn, index)) => inputs.find(_.txid == txIn.outPoint.txid) match { case (currentPsbt, (txIn, index)) => inputs.find(_.txid == txIn.outPoint.txid) match {
case Some(inputTx) => case Some(inputTx) =>
val sig = Transaction.signInput(tx, index, Script.pay2pkh(pubkey), SigHash.SIGHASH_ALL, inputTx.txOut.head.amount, SigVersion.SIGVERSION_WITNESS_V0, privkey) val sig = Transaction.signInput(tx, index, Script.pay2pkh(pubkey), SigHash.SIGHASH_ALL, inputTx.txOut.head.amount, SigVersion.SIGVERSION_WITNESS_V0, privkey)
val updated = currentPsbt.updateWitnessInput(txIn.outPoint, inputTx.txOut(txIn.outPoint.index.toInt), null, Script.pay2pkh(pubkey).map(scala2kmp).asJava, null, java.util.Map.of()).getRight val updated = currentPsbt.updateWitnessInput(
txIn.outPoint,
inputTx.txOut(txIn.outPoint.index.toInt),
null,
Script.pay2pkh(pubkey).map(scala2kmp).asJava,
null,
java.util.Map.of(),
null,
null,
java.util.Map.of()).getRight
updated.finalizeWitnessInput(txIn.outPoint, Script.witnessPay2wpkh(pubkey, sig)).getRight updated.finalizeWitnessInput(txIn.outPoint, Script.witnessPay2wpkh(pubkey, sig)).getRight
case None => currentPsbt case None => currentPsbt
} }

View File

@ -254,7 +254,7 @@ class BitcoinCoreClientSpec extends TestKitBaseClass with BitcoindService with A
// We sign our external input. // We sign our external input.
val externalSig = Transaction.signInput(fundedTx2.tx, 0, inputScript1, SigHash.SIGHASH_ALL, 250_000 sat, SigVersion.SIGVERSION_WITNESS_V0, alicePriv) val externalSig = Transaction.signInput(fundedTx2.tx, 0, inputScript1, SigHash.SIGHASH_ALL, 250_000 sat, SigVersion.SIGVERSION_WITNESS_V0, alicePriv)
val psbt = new Psbt(fundedTx2.tx) val psbt = new Psbt(fundedTx2.tx)
.updateWitnessInput(outpoint1, txOut1, null, null, null, java.util.Map.of()).getRight .updateWitnessInput(outpoint1, txOut1, null, null, null, java.util.Map.of(), null, null, java.util.Map.of()).getRight
.finalizeWitnessInput(0, Script.witnessMultiSigMofN(Seq(alicePriv, bobPriv).map(_.publicKey), Seq(externalSig))).getRight .finalizeWitnessInput(0, Script.witnessMultiSigMofN(Seq(alicePriv, bobPriv).map(_.publicKey), Seq(externalSig))).getRight
// And let bitcoind sign the wallet input. // And let bitcoind sign the wallet input.
walletExternalFunds.signPsbt(psbt, fundedTx2.tx.txIn.indices, Nil).pipeTo(sender.ref) walletExternalFunds.signPsbt(psbt, fundedTx2.tx.txIn.indices, Nil).pipeTo(sender.ref)
@ -284,7 +284,7 @@ class BitcoinCoreClientSpec extends TestKitBaseClass with BitcoindService with A
// We sign our external input. // We sign our external input.
val externalSig = Transaction.signInput(fundedTx.tx, 0, inputScript2, SigHash.SIGHASH_ALL, 300_000 sat, SigVersion.SIGVERSION_WITNESS_V0, alicePriv) val externalSig = Transaction.signInput(fundedTx.tx, 0, inputScript2, SigHash.SIGHASH_ALL, 300_000 sat, SigVersion.SIGVERSION_WITNESS_V0, alicePriv)
val psbt = new Psbt(fundedTx.tx) val psbt = new Psbt(fundedTx.tx)
.updateWitnessInput(externalOutpoint, tx2.txOut(0), null, null, null, java.util.Map.of()).getRight .updateWitnessInput(externalOutpoint, tx2.txOut(0), null, null, null, java.util.Map.of(), null, null, java.util.Map.of()).getRight
.finalizeWitnessInput(0, Script.witnessMultiSigMofN(Seq(alicePriv, carolPriv).map(_.publicKey), Seq(externalSig))).getRight .finalizeWitnessInput(0, Script.witnessMultiSigMofN(Seq(alicePriv, carolPriv).map(_.publicKey), Seq(externalSig))).getRight
// bitcoind signs the wallet input. // bitcoind signs the wallet input.
walletExternalFunds.signPsbt(psbt, fundedTx.tx.txIn.indices, Nil).pipeTo(sender.ref) walletExternalFunds.signPsbt(psbt, fundedTx.tx.txIn.indices, Nil).pipeTo(sender.ref)
@ -320,7 +320,7 @@ class BitcoinCoreClientSpec extends TestKitBaseClass with BitcoindService with A
// We sign our external input. // We sign our external input.
val externalSig = Transaction.signInput(fundedTx.tx, 0, inputScript2, SigHash.SIGHASH_ALL, 300_000 sat, SigVersion.SIGVERSION_WITNESS_V0, alicePriv) val externalSig = Transaction.signInput(fundedTx.tx, 0, inputScript2, SigHash.SIGHASH_ALL, 300_000 sat, SigVersion.SIGVERSION_WITNESS_V0, alicePriv)
val psbt = new Psbt(fundedTx.tx) val psbt = new Psbt(fundedTx.tx)
.updateWitnessInput(OutPoint(tx2, 0), tx2.txOut(0), null, null, null, java.util.Map.of()).getRight .updateWitnessInput(OutPoint(tx2, 0), tx2.txOut(0), null, null, null, java.util.Map.of(), null, null, java.util.Map.of()).getRight
.finalizeWitnessInput(0, Script.witnessMultiSigMofN(Seq(alicePriv, carolPriv).map(_.publicKey), Seq(externalSig))).getRight .finalizeWitnessInput(0, Script.witnessMultiSigMofN(Seq(alicePriv, carolPriv).map(_.publicKey), Seq(externalSig))).getRight
// bitcoind signs the wallet input. // bitcoind signs the wallet input.
walletExternalFunds.signPsbt(psbt, fundedTx.tx.txIn.indices, Nil).pipeTo(sender.ref) walletExternalFunds.signPsbt(psbt, fundedTx.tx.txIn.indices, Nil).pipeTo(sender.ref)
@ -816,7 +816,7 @@ class BitcoinCoreClientSpec extends TestKitBaseClass with BitcoindService with A
val nonWalletWitness = ScriptWitness(Seq(nonWalletSig, nonWalletKey.publicKey.value)) val nonWalletWitness = ScriptWitness(Seq(nonWalletSig, nonWalletKey.publicKey.value))
val txWithSignedNonWalletInput = txWithNonWalletInput.updateWitness(0, nonWalletWitness) val txWithSignedNonWalletInput = txWithNonWalletInput.updateWitness(0, nonWalletWitness)
val psbt = new Psbt(txWithSignedNonWalletInput) val psbt = new Psbt(txWithSignedNonWalletInput)
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 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, null, null, java.util.Map.of())
val Right(psbt1) = updated.flatMap(_.finalizeWitnessInput(0, nonWalletWitness)) val Right(psbt1) = updated.flatMap(_.finalizeWitnessInput(0, nonWalletWitness))
bitcoinClient.signPsbt(psbt1, txWithSignedNonWalletInput.txIn.indices.tail, Nil).pipeTo(sender.ref) bitcoinClient.signPsbt(psbt1, txWithSignedNonWalletInput.txIn.indices.tail, Nil).pipeTo(sender.ref)
val signTxResponse2 = sender.expectMsgType[ProcessPsbtResponse] val signTxResponse2 = sender.expectMsgType[ProcessPsbtResponse]
@ -848,7 +848,7 @@ class BitcoinCoreClientSpec extends TestKitBaseClass with BitcoindService with A
val nonWalletWitness = ScriptWitness(Seq(nonWalletSig, nonWalletKey.publicKey.value)) val nonWalletWitness = ScriptWitness(Seq(nonWalletSig, nonWalletKey.publicKey.value))
val txWithSignedUnconfirmedInput = txWithUnconfirmedInput.updateWitness(0, nonWalletWitness) val txWithSignedUnconfirmedInput = txWithUnconfirmedInput.updateWitness(0, nonWalletWitness)
val psbt = new Psbt(txWithSignedUnconfirmedInput) val psbt = new Psbt(txWithSignedUnconfirmedInput)
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) 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, null, null, java.util.Map.of())
.flatMap(_.finalizeWitnessInput(0, nonWalletWitness)) .flatMap(_.finalizeWitnessInput(0, nonWalletWitness))
bitcoinClient.signPsbt(psbt1, txWithSignedUnconfirmedInput.txIn.indices.tail, Nil).pipeTo(sender.ref) bitcoinClient.signPsbt(psbt1, txWithSignedUnconfirmedInput.txIn.indices.tail, Nil).pipeTo(sender.ref)
assert(sender.expectMsgType[ProcessPsbtResponse].complete) assert(sender.expectMsgType[ProcessPsbtResponse].complete)
@ -1521,7 +1521,7 @@ class BitcoinCoreClientSpec extends TestKitBaseClass with BitcoindService with A
val txOut = Seq(TxOut(outputAmount, Script.pay2wpkh(randomKey().publicKey))) val txOut = Seq(TxOut(outputAmount, Script.pay2wpkh(randomKey().publicKey)))
var psbt = new Psbt(Transaction(2, txIn, txOut, 0)) var psbt = new Psbt(Transaction(2, txIn, txOut, 0))
(fromInput until toInput).foreach { i => (fromInput until toInput).foreach { i =>
psbt = psbt.updateWitnessInput(OutPoint(parentTx, i), parentTx.txOut(i), null, null, null, psbt.getInput(i - fromInput).getDerivationPaths).getRight psbt = psbt.updateWitnessInput(OutPoint(parentTx, i), parentTx.txOut(i), null, null, null, psbt.getInput(i - fromInput).getDerivationPaths, null, null, java.util.Map.of()).getRight
psbt = psbt.finalizeWitnessInput(i - fromInput, ScriptWitness(Seq(ByteVector(1), bigInputScript))).getRight psbt = psbt.finalizeWitnessInput(i - fromInput, ScriptWitness(Seq(ByteVector(1), bigInputScript))).getRight
} }
val signedTx: Transaction = psbt.extract().getRight val signedTx: Transaction = psbt.extract().getRight

View File

@ -34,10 +34,10 @@ class BlockchainWatchdogSpec extends ScalaTestWithActorTestKit(ConfigFactory.loa
// blockcypher.com is very flaky - it either imposes rate limits or requires captcha // blockcypher.com is very flaky - it either imposes rate limits or requires captcha
// but sometimes it works. If want to check whether you're lucky uncomment these lines: // but sometimes it works. If want to check whether you're lucky uncomment these lines:
// val nodeParamsLivenet = TestConstants.Alice.nodeParams.copy(chainHash = Block.LivenetGenesisBlock.hash) // val nodeParamsLivenet = TestConstants.Alice.nodeParams.copy(chainHash = Block.LivenetGenesisBlock.hash)
// val nodeParamsTestnet = TestConstants.Alice.nodeParams.copy(chainHash = Block.TestnetGenesisBlock.hash) // val nodeParamsTestnet = TestConstants.Alice.nodeParams.copy(chainHash = Block.Testnet3GenesisBlock.hash)
// and comment these: // and comment these:
val nodeParamsLivenet = removeBlockcypher(TestConstants.Alice.nodeParams.copy(chainHash = Block.LivenetGenesisBlock.hash)) val nodeParamsLivenet = removeBlockcypher(TestConstants.Alice.nodeParams.copy(chainHash = Block.LivenetGenesisBlock.hash))
val nodeParamsTestnet = removeBlockcypher(TestConstants.Alice.nodeParams.copy(chainHash = Block.TestnetGenesisBlock.hash)) val nodeParamsTestnet = removeBlockcypher(TestConstants.Alice.nodeParams.copy(chainHash = Block.Testnet3GenesisBlock.hash))
val nodeParamsSignet = removeBlockcypher(TestConstants.Alice.nodeParams.copy(chainHash = Block.SignetGenesisBlock.hash)) val nodeParamsSignet = removeBlockcypher(TestConstants.Alice.nodeParams.copy(chainHash = Block.SignetGenesisBlock.hash))

View File

@ -57,7 +57,7 @@ class HeadersOverDnsSpec extends ScalaTestWithActorTestKit(ConfigFactory.load("a
} }
test("ignore testnet requests", TestTags.ExternalApi) { test("ignore testnet requests", TestTags.ExternalApi) {
val headersOverDns = testKit.spawn(HeadersOverDns(Block.TestnetGenesisBlock.hash, BlockHeight(500000))) val headersOverDns = testKit.spawn(HeadersOverDns(Block.Testnet3GenesisBlock.hash, BlockHeight(500000)))
val sender = testKit.createTestProbe[LatestHeaders]() val sender = testKit.createTestProbe[LatestHeaders]()
headersOverDns ! CheckLatestHeaders(sender.ref) headersOverDns ! CheckLatestHeaders(sender.ref)
sender.expectNoMessage(1 second) sender.expectNoMessage(1 second)

View File

@ -34,8 +34,8 @@ class LocalChannelKeyManagerSpec extends AnyFunSuite {
test("generate the same secrets from the same seed") { test("generate the same secrets from the same seed") {
// data was generated with eclair 0.3 // data was generated with eclair 0.3
val seed = hex"17b086b228025fa8f4416324b6ba2ec36e68570ae2fc3d392520969f2a9d0c1501" val seed = hex"17b086b228025fa8f4416324b6ba2ec36e68570ae2fc3d392520969f2a9d0c1501"
val nodeKeyManager = new LocalNodeKeyManager(seed, Block.TestnetGenesisBlock.hash) val nodeKeyManager = new LocalNodeKeyManager(seed, Block.Testnet3GenesisBlock.hash)
val channelKeyManager = new LocalChannelKeyManager(seed, Block.TestnetGenesisBlock.hash) val channelKeyManager = new LocalChannelKeyManager(seed, Block.Testnet3GenesisBlock.hash)
assert(nodeKeyManager.nodeId == PublicKey(hex"02a051267759c3a149e3e72372f4e0c4054ba597ebfd0eda78a2273023667205ee")) assert(nodeKeyManager.nodeId == PublicKey(hex"02a051267759c3a149e3e72372f4e0c4054ba597ebfd0eda78a2273023667205ee"))
val keyPath = KeyPath("m/1'/2'/3'/4'") val keyPath = KeyPath("m/1'/2'/3'/4'")
assert(channelKeyManager.commitmentSecret(keyPath, 0L).value == ByteVector32.fromValidHex("fa7a8c2fc62642f7a9a19ea0bfad14d39a430f3c9899c185dcecc61c8077891e")) assert(channelKeyManager.commitmentSecret(keyPath, 0L).value == ByteVector32.fromValidHex("fa7a8c2fc62642f7a9a19ea0bfad14d39a430f3c9899c185dcecc61c8077891e"))
@ -64,7 +64,7 @@ class LocalChannelKeyManagerSpec extends AnyFunSuite {
test("test vectors (testnet, funder)") { test("test vectors (testnet, funder)") {
val seed = ByteVector.fromValidHex("17b086b228025fa8f4416324b6ba2ec36e68570ae2fc3d392520969f2a9d0c1501") val seed = ByteVector.fromValidHex("17b086b228025fa8f4416324b6ba2ec36e68570ae2fc3d392520969f2a9d0c1501")
val channelKeyManager = new LocalChannelKeyManager(seed, Block.TestnetGenesisBlock.hash) val channelKeyManager = new LocalChannelKeyManager(seed, Block.Testnet3GenesisBlock.hash)
val fundingKeyPath = makefundingKeyPath(hex"be4fa97c62b9f88437a3be577b31eb48f2165c7bc252194a15ff92d995778cfb", isInitiator = true) val fundingKeyPath = makefundingKeyPath(hex"be4fa97c62b9f88437a3be577b31eb48f2165c7bc252194a15ff92d995778cfb", isInitiator = true)
val fundingPub = channelKeyManager.fundingPublicKey(fundingKeyPath, fundingTxIndex = 0) val fundingPub = channelKeyManager.fundingPublicKey(fundingKeyPath, fundingTxIndex = 0)
@ -81,7 +81,7 @@ class LocalChannelKeyManagerSpec extends AnyFunSuite {
test("test vectors (testnet, fundee)") { test("test vectors (testnet, fundee)") {
val seed = ByteVector.fromValidHex("aeb3e9b5642cd4523e9e09164047f60adb413633549c3c6189192921311894d501") val seed = ByteVector.fromValidHex("aeb3e9b5642cd4523e9e09164047f60adb413633549c3c6189192921311894d501")
val channelKeyManager = new LocalChannelKeyManager(seed, Block.TestnetGenesisBlock.hash) val channelKeyManager = new LocalChannelKeyManager(seed, Block.Testnet3GenesisBlock.hash)
val fundingKeyPath = makefundingKeyPath(hex"06535806c1aa73971ec4877a5e2e684fa636136c073810f190b63eefc58ca488", isInitiator = false) val fundingKeyPath = makefundingKeyPath(hex"06535806c1aa73971ec4877a5e2e684fa636136c073810f190b63eefc58ca488", isInitiator = false)
val fundingPub = channelKeyManager.fundingPublicKey(fundingKeyPath, fundingTxIndex = 0) val fundingPub = channelKeyManager.fundingPublicKey(fundingKeyPath, fundingTxIndex = 0)

View File

@ -33,15 +33,15 @@ class LocalNodeKeyManagerSpec extends AnyFunSuite {
// if this test breaks it means that we will generate a different node id from // if this test breaks it means that we will generate a different node id from
// the same seed, which could be a problem during an upgrade // the same seed, which could be a problem during an upgrade
val seed = hex"17b086b228025fa8f4416324b6ba2ec36e68570ae2fc3d392520969f2a9d0c1501" val seed = hex"17b086b228025fa8f4416324b6ba2ec36e68570ae2fc3d392520969f2a9d0c1501"
val nodeKeyManager = new LocalNodeKeyManager(seed, Block.TestnetGenesisBlock.hash) val nodeKeyManager = new LocalNodeKeyManager(seed, Block.Testnet3GenesisBlock.hash)
assert(nodeKeyManager.nodeId == PublicKey(hex"02a051267759c3a149e3e72372f4e0c4054ba597ebfd0eda78a2273023667205ee")) assert(nodeKeyManager.nodeId == PublicKey(hex"02a051267759c3a149e3e72372f4e0c4054ba597ebfd0eda78a2273023667205ee"))
} }
test("generate different node ids from the same seed on different chains") { test("generate different node ids from the same seed on different chains") {
val seed = hex"17b086b228025fa8f4416324b6ba2ec36e68570ae2fc3d392520969f2a9d0c1501" val seed = hex"17b086b228025fa8f4416324b6ba2ec36e68570ae2fc3d392520969f2a9d0c1501"
val nodeKeyManager1 = new LocalNodeKeyManager(seed, Block.TestnetGenesisBlock.hash) val nodeKeyManager1 = new LocalNodeKeyManager(seed, Block.Testnet3GenesisBlock.hash)
val nodeKeyManager2 = new LocalNodeKeyManager(seed, Block.LivenetGenesisBlock.hash) val nodeKeyManager2 = new LocalNodeKeyManager(seed, Block.LivenetGenesisBlock.hash)
val channelKeyManager1 = new LocalChannelKeyManager(seed, Block.TestnetGenesisBlock.hash) val channelKeyManager1 = new LocalChannelKeyManager(seed, Block.Testnet3GenesisBlock.hash)
val channelKeyManager2 = new LocalChannelKeyManager(seed, Block.LivenetGenesisBlock.hash) val channelKeyManager2 = new LocalChannelKeyManager(seed, Block.LivenetGenesisBlock.hash)
assert(nodeKeyManager1.nodeId != nodeKeyManager2.nodeId) assert(nodeKeyManager1.nodeId != nodeKeyManager2.nodeId)
val keyPath = KeyPath(1L :: Nil) val keyPath = KeyPath(1L :: Nil)

View File

@ -15,7 +15,7 @@ class LocalOnChainKeyManagerSpec extends AnyFunSuite {
test("sign psbt (non-reg test)") { test("sign psbt (non-reg test)") {
val entropy = ByteVector.fromValidHex("01" * 32) val entropy = ByteVector.fromValidHex("01" * 32)
val seed = MnemonicCode.toSeed(MnemonicCode.toMnemonics(entropy), "") val seed = MnemonicCode.toSeed(MnemonicCode.toMnemonics(entropy), "")
val onChainKeyManager = new LocalOnChainKeyManager("eclair", seed, TimestampSecond.now(), Block.TestnetGenesisBlock.hash) val onChainKeyManager = new LocalOnChainKeyManager("eclair", seed, TimestampSecond.now(), Block.Testnet3GenesisBlock.hash)
// data generated by bitcoin core on regtest // data generated by bitcoin core on regtest
val psbt = Psbt.read( val psbt = Psbt.read(
Base64.getDecoder.decode("cHNidP8BAHECAAAAAfZo4nGIyTg77MFmEBkQH1Au3Jl8vzB2WWQGGz/MbyssAAAAAAD9////ArAHPgUAAAAAFgAU6j9yVvLg66Zu3GM/xHbmXT0yvyiAlpgAAAAAABYAFODscQh3N7lmDYyV5yrHpGL2Zd4JAAAAAAABAH0CAAAAAaNdmqUNlziIjSaif3JUcvJWdyF0U5bYq13NMe+LbaBZAAAAAAD9////AjSp1gUAAAAAFgAUjfFMfBg8ulo/874n3+0ode7ka0BAQg8AAAAAACIAIPUn/XU17DfnvDkj8gn2twG3jtr2Z7sthy9K2MPTdYkaAAAAAAEBHzSp1gUAAAAAFgAUjfFMfBg8ulo/874n3+0ode7ka0AiBgM+PDdyxsVisa66SyBxiUvhEam8lEP64yujvVsEcGaqIxgPCfOBVAAAgAEAAIAAAACAAQAAAAMAAAAAIgIDWmAhb/sCV9+HjwFpPuy2TyEBi/Y11wrEHZUihe3N80EYDwnzgVQAAIABAACAAAAAgAEAAAAFAAAAAAA=") Base64.getDecoder.decode("cHNidP8BAHECAAAAAfZo4nGIyTg77MFmEBkQH1Au3Jl8vzB2WWQGGz/MbyssAAAAAAD9////ArAHPgUAAAAAFgAU6j9yVvLg66Zu3GM/xHbmXT0yvyiAlpgAAAAAABYAFODscQh3N7lmDYyV5yrHpGL2Zd4JAAAAAAABAH0CAAAAAaNdmqUNlziIjSaif3JUcvJWdyF0U5bYq13NMe+LbaBZAAAAAAD9////AjSp1gUAAAAAFgAUjfFMfBg8ulo/874n3+0ode7ka0BAQg8AAAAAACIAIPUn/XU17DfnvDkj8gn2twG3jtr2Z7sthy9K2MPTdYkaAAAAAAEBHzSp1gUAAAAAFgAUjfFMfBg8ulo/874n3+0ode7ka0AiBgM+PDdyxsVisa66SyBxiUvhEam8lEP64yujvVsEcGaqIxgPCfOBVAAAgAEAAIAAAACAAQAAAAMAAAAAIgIDWmAhb/sCV9+HjwFpPuy2TyEBi/Y11wrEHZUihe3N80EYDwnzgVQAAIABAACAAAAAgAEAAAAFAAAAAAA=")
@ -30,7 +30,7 @@ class LocalOnChainKeyManagerSpec extends AnyFunSuite {
import fr.acinq.bitcoin.scalacompat.KotlinUtils._ import fr.acinq.bitcoin.scalacompat.KotlinUtils._
val seed = ByteVector.fromValidHex("01" * 32) val seed = ByteVector.fromValidHex("01" * 32)
val onChainKeyManager = new LocalOnChainKeyManager("eclair", seed, TimestampSecond.now(), Block.TestnetGenesisBlock.hash) val onChainKeyManager = new LocalOnChainKeyManager("eclair", seed, TimestampSecond.now(), Block.Testnet3GenesisBlock.hash)
// create a watch-only BIP84 wallet from our key manager xpub // create a watch-only BIP84 wallet from our key manager xpub
val (_, accountPub) = DeterministicWallet.ExtendedPublicKey.decode(onChainKeyManager.masterPubKey(0)) val (_, accountPub) = DeterministicWallet.ExtendedPublicKey.decode(onChainKeyManager.masterPubKey(0))
@ -54,13 +54,13 @@ class LocalOnChainKeyManagerSpec extends AnyFunSuite {
txOut = TxOut(Satoshi(1000_000), Script.pay2wpkh(getPublicKey(0))) :: Nil, lockTime = 0) txOut = TxOut(Satoshi(1000_000), Script.pay2wpkh(getPublicKey(0))) :: Nil, lockTime = 0)
val Right(psbt) = for { val Right(psbt) = for {
p0 <- new Psbt(tx).updateWitnessInput(OutPoint(utxos(0), 0), utxos(0).txOut(0), null, Script.pay2pkh(getPublicKey(0)).map(scala2kmp).asJava, null, java.util.Map.of(getPublicKey(0), bip32paths(0))) p0 <- new Psbt(tx).updateWitnessInput(OutPoint(utxos(0), 0), utxos(0).txOut(0), null, Script.pay2pkh(getPublicKey(0)).map(scala2kmp).asJava, null, java.util.Map.of(getPublicKey(0), bip32paths(0)), null, null, java.util.Map.of())
p1 <- p0.updateWitnessInput(OutPoint(utxos(1), 0), utxos(1).txOut(0), null, Script.pay2pkh(getPublicKey(1)).map(scala2kmp).asJava, null, java.util.Map.of(getPublicKey(1), bip32paths(1))) p1 <- p0.updateWitnessInput(OutPoint(utxos(1), 0), utxos(1).txOut(0), null, Script.pay2pkh(getPublicKey(1)).map(scala2kmp).asJava, null, java.util.Map.of(getPublicKey(1), bip32paths(1)), null, null, java.util.Map.of())
p2 <- p1.updateWitnessInput(OutPoint(utxos(2), 0), utxos(2).txOut(0), null, Script.pay2pkh(getPublicKey(2)).map(scala2kmp).asJava, null, java.util.Map.of(getPublicKey(2), bip32paths(2))) p2 <- p1.updateWitnessInput(OutPoint(utxos(2), 0), utxos(2).txOut(0), null, Script.pay2pkh(getPublicKey(2)).map(scala2kmp).asJava, null, java.util.Map.of(getPublicKey(2), bip32paths(2)), null, null, java.util.Map.of())
p3 <- p2.updateNonWitnessInput(utxos(0), 0, null, null, java.util.Map.of()) p3 <- p2.updateNonWitnessInput(utxos(0), 0, null, null, java.util.Map.of())
p4 <- p3.updateNonWitnessInput(utxos(1), 0, null, null, java.util.Map.of()) p4 <- p3.updateNonWitnessInput(utxos(1), 0, null, null, java.util.Map.of())
p5 <- p4.updateNonWitnessInput(utxos(2), 0, null, null, java.util.Map.of()) p5 <- p4.updateNonWitnessInput(utxos(2), 0, null, null, java.util.Map.of())
p6 <- p5.updateWitnessOutput(0, null, null, java.util.Map.of(getPublicKey(0), bip32paths(0))) p6 <- p5.updateWitnessOutput(0, null, null, java.util.Map.of(getPublicKey(0), bip32paths(0)), null, java.util.Map.of())
} yield p6 } yield p6
{ {
@ -78,38 +78,38 @@ class LocalOnChainKeyManagerSpec extends AnyFunSuite {
} }
{ {
// provide a wrong derivation path for the first input // provide a wrong derivation path for the first input
val updated = psbt.updateWitnessInput(OutPoint(utxos(0), 0), utxos(0).txOut(0), null, Script.pay2pkh(getPublicKey(0)).map(scala2kmp).asJava, null, java.util.Map.of(getPublicKey(0), bip32paths(2))).getRight // wrong bip32 path val updated = psbt.updateWitnessInput(OutPoint(utxos(0), 0), utxos(0).txOut(0), null, Script.pay2pkh(getPublicKey(0)).map(scala2kmp).asJava, null, java.util.Map.of(getPublicKey(0), bip32paths(2)), null, null, java.util.Map.of()).getRight // wrong bip32 path
val Failure(error) = onChainKeyManager.sign(updated, Seq(0, 1, 2), Seq(0)) val Failure(error) = onChainKeyManager.sign(updated, Seq(0, 1, 2), Seq(0))
assert(error.getMessage.contains("derived public key doesn't match")) assert(error.getMessage.contains("derived public key doesn't match"))
} }
{ {
// provide a wrong derivation path for the first output // provide a wrong derivation path for the first output
val updated = psbt.updateWitnessOutput(0, null, null, java.util.Map.of(getPublicKey(0), bip32paths(1))).getRight // wrong path val updated = psbt.updateWitnessOutput(0, null, null, java.util.Map.of(getPublicKey(0), bip32paths(1)), null, java.util.Map.of()).getRight // wrong path
val Failure(error) = onChainKeyManager.sign(updated, Seq(0, 1, 2), Seq(0)) val Failure(error) = onChainKeyManager.sign(updated, Seq(0, 1, 2), Seq(0))
assert(error.getMessage.contains("could not verify output 0")) assert(error.getMessage.contains("could not verify output 0"))
} }
{ {
// lie about the amount being spent // lie about the amount being spent
val updated = psbt.updateWitnessInput(OutPoint(utxos(0), 0), utxos(0).txOut(0).copy(amount = Satoshi(10)), null, Script.pay2pkh(getPublicKey(0)).map(scala2kmp).asJava, null, java.util.Map.of(getPublicKey(0), bip32paths(0))).getRight val updated = psbt.updateWitnessInput(OutPoint(utxos(0), 0), utxos(0).txOut(0).copy(amount = Satoshi(10)), null, Script.pay2pkh(getPublicKey(0)).map(scala2kmp).asJava, null, java.util.Map.of(getPublicKey(0), bip32paths(0)), null, null, java.util.Map.of()).getRight
val Failure(error) = onChainKeyManager.sign(updated, Seq(0, 1, 2), Seq(0)) val Failure(error) = onChainKeyManager.sign(updated, Seq(0, 1, 2), Seq(0))
assert(error.getMessage.contains("utxo mismatch")) assert(error.getMessage.contains("utxo mismatch"))
} }
{ {
// do not provide non-witness utxo for utxo #2 // do not provide non-witness utxo for utxo #2
val Right(psbt) = for { val Right(psbt) = for {
p0 <- new Psbt(tx).updateWitnessInput(OutPoint(utxos(0), 0), utxos(0).txOut(0), null, Script.pay2pkh(getPublicKey(0)).map(scala2kmp).asJava, null, java.util.Map.of(getPublicKey(0), bip32paths(0))) p0 <- new Psbt(tx).updateWitnessInput(OutPoint(utxos(0), 0), utxos(0).txOut(0), null, Script.pay2pkh(getPublicKey(0)).map(scala2kmp).asJava, null, java.util.Map.of(getPublicKey(0), bip32paths(0)), null, null, java.util.Map.of())
p1 <- p0.updateWitnessInput(OutPoint(utxos(1), 0), utxos(1).txOut(0), null, Script.pay2pkh(getPublicKey(1)).map(scala2kmp).asJava, null, java.util.Map.of(getPublicKey(1), bip32paths(1))) p1 <- p0.updateWitnessInput(OutPoint(utxos(1), 0), utxos(1).txOut(0), null, Script.pay2pkh(getPublicKey(1)).map(scala2kmp).asJava, null, java.util.Map.of(getPublicKey(1), bip32paths(1)), null, null, java.util.Map.of())
p2 <- p1.updateWitnessInput(OutPoint(utxos(2), 0), utxos(2).txOut(0), null, Script.pay2pkh(getPublicKey(2)).map(scala2kmp).asJava, null, java.util.Map.of(getPublicKey(2), bip32paths(2))) p2 <- p1.updateWitnessInput(OutPoint(utxos(2), 0), utxos(2).txOut(0), null, Script.pay2pkh(getPublicKey(2)).map(scala2kmp).asJava, null, java.util.Map.of(getPublicKey(2), bip32paths(2)), null, null, java.util.Map.of())
p3 <- p2.updateNonWitnessInput(utxos(0), 0, null, null, java.util.Map.of()) p3 <- p2.updateNonWitnessInput(utxos(0), 0, null, null, java.util.Map.of())
p4 <- p3.updateNonWitnessInput(utxos(1), 0, null, null, java.util.Map.of()) p4 <- p3.updateNonWitnessInput(utxos(1), 0, null, null, java.util.Map.of())
p5 <- p4.updateWitnessOutput(0, null, null, java.util.Map.of(getPublicKey(0), bip32paths(0))) p5 <- p4.updateWitnessOutput(0, null, null, java.util.Map.of(getPublicKey(0), bip32paths(0)), null, java.util.Map.of())
} yield p5 } yield p5
val Failure(error) = onChainKeyManager.sign(psbt, Seq(0, 1, 2), Seq(0)) val Failure(error) = onChainKeyManager.sign(psbt, Seq(0, 1, 2), Seq(0))
assert(error.getMessage.contains("non-witness utxo is missing")) assert(error.getMessage.contains("non-witness utxo is missing"))
} }
{ {
// use sighash type != SIGHASH_ALL // use sighash type != SIGHASH_ALL
val updated = psbt.updateWitnessInput(OutPoint(utxos(0), 0), utxos(0).txOut(0), null, Script.pay2pkh(getPublicKey(0)).map(scala2kmp).asJava, SigHash.SIGHASH_SINGLE, java.util.Map.of(getPublicKey(0), bip32paths(0))).getRight val updated = psbt.updateWitnessInput(OutPoint(utxos(0), 0), utxos(0).txOut(0), null, Script.pay2pkh(getPublicKey(0)).map(scala2kmp).asJava, SigHash.SIGHASH_SINGLE, java.util.Map.of(getPublicKey(0), bip32paths(0)), null, null, java.util.Map.of()).getRight
val Failure(error) = onChainKeyManager.sign(updated, Seq(0, 1, 2), Seq(0)) val Failure(error) = onChainKeyManager.sign(updated, Seq(0, 1, 2), Seq(0))
assert(error.getMessage.contains("input sighash must be SIGHASH_ALL")) assert(error.getMessage.contains("input sighash must be SIGHASH_ALL"))
} }

View File

@ -81,7 +81,7 @@ class PaymentsDbSpec extends AnyFunSuite {
// add a few rows // add a few rows
val ps1 = OutgoingPayment(UUID.randomUUID(), UUID.randomUUID(), None, paymentHash1, PaymentType.Standard, 12345 msat, 12345 msat, alice, 1000 unixms, None, None, OutgoingPaymentStatus.Pending) val ps1 = OutgoingPayment(UUID.randomUUID(), UUID.randomUUID(), None, paymentHash1, PaymentType.Standard, 12345 msat, 12345 msat, alice, 1000 unixms, None, None, OutgoingPaymentStatus.Pending)
val i1 = Bolt11Invoice(Block.TestnetGenesisBlock.hash, Some(500 msat), paymentHash1, davePriv, Left("Some invoice"), CltvExpiryDelta(18), expirySeconds = None, timestamp = 1 unixsec) val i1 = Bolt11Invoice(Block.Testnet3GenesisBlock.hash, Some(500 msat), paymentHash1, davePriv, Left("Some invoice"), CltvExpiryDelta(18), expirySeconds = None, timestamp = 1 unixsec)
val pr1 = IncomingStandardPayment(i1, preimage1, PaymentType.Standard, i1.createdAt.toTimestampMilli, IncomingPaymentStatus.Received(550 msat, 1100 unixms)) val pr1 = IncomingStandardPayment(i1, preimage1, PaymentType.Standard, i1.createdAt.toTimestampMilli, IncomingPaymentStatus.Received(550 msat, 1100 unixms))
db.addOutgoingPayment(ps1) db.addOutgoingPayment(ps1)
@ -104,9 +104,9 @@ class PaymentsDbSpec extends AnyFunSuite {
val ps1 = OutgoingPayment(id1, id1, None, randomBytes32(), PaymentType.Standard, 561 msat, 561 msat, PrivateKey(ByteVector32.One).publicKey, 1000 unixms, None, None, OutgoingPaymentStatus.Pending) val ps1 = OutgoingPayment(id1, id1, None, randomBytes32(), PaymentType.Standard, 561 msat, 561 msat, PrivateKey(ByteVector32.One).publicKey, 1000 unixms, None, None, OutgoingPaymentStatus.Pending)
val ps2 = OutgoingPayment(id2, id2, None, randomBytes32(), PaymentType.Standard, 1105 msat, 1105 msat, PrivateKey(ByteVector32.One).publicKey, 1010 unixms, None, None, OutgoingPaymentStatus.Failed(Nil, 1050 unixms)) val ps2 = OutgoingPayment(id2, id2, None, randomBytes32(), PaymentType.Standard, 1105 msat, 1105 msat, PrivateKey(ByteVector32.One).publicKey, 1010 unixms, None, None, OutgoingPaymentStatus.Failed(Nil, 1050 unixms))
val ps3 = OutgoingPayment(id3, id3, None, paymentHash1, PaymentType.Standard, 1729 msat, 1729 msat, PrivateKey(ByteVector32.One).publicKey, 1040 unixms, None, None, OutgoingPaymentStatus.Succeeded(preimage1, 0 msat, Nil, 1060 unixms)) val ps3 = OutgoingPayment(id3, id3, None, paymentHash1, PaymentType.Standard, 1729 msat, 1729 msat, PrivateKey(ByteVector32.One).publicKey, 1040 unixms, None, None, OutgoingPaymentStatus.Succeeded(preimage1, 0 msat, Nil, 1060 unixms))
val i1 = Bolt11Invoice(Block.TestnetGenesisBlock.hash, Some(12345678 msat), paymentHash1, davePriv, Left("Some invoice"), CltvExpiryDelta(18), expirySeconds = None, timestamp = 1 unixsec) val i1 = Bolt11Invoice(Block.Testnet3GenesisBlock.hash, Some(12345678 msat), paymentHash1, davePriv, Left("Some invoice"), CltvExpiryDelta(18), expirySeconds = None, timestamp = 1 unixsec)
val pr1 = IncomingStandardPayment(i1, preimage1, PaymentType.Standard, i1.createdAt.toTimestampMilli, IncomingPaymentStatus.Received(12345678 msat, 1090 unixms)) val pr1 = IncomingStandardPayment(i1, preimage1, PaymentType.Standard, i1.createdAt.toTimestampMilli, IncomingPaymentStatus.Received(12345678 msat, 1090 unixms))
val i2 = Bolt11Invoice(Block.TestnetGenesisBlock.hash, Some(12345678 msat), paymentHash2, carolPriv, Left("Another invoice"), CltvExpiryDelta(18), expirySeconds = Some(30), timestamp = 1 unixsec) val i2 = Bolt11Invoice(Block.Testnet3GenesisBlock.hash, Some(12345678 msat), paymentHash2, carolPriv, Left("Another invoice"), CltvExpiryDelta(18), expirySeconds = Some(30), timestamp = 1 unixsec)
val pr2 = IncomingStandardPayment(i2, preimage2, PaymentType.Standard, i2.createdAt.toTimestampMilli, IncomingPaymentStatus.Expired) val pr2 = IncomingStandardPayment(i2, preimage2, PaymentType.Standard, i2.createdAt.toTimestampMilli, IncomingPaymentStatus.Expired)
migrationCheck( migrationCheck(
@ -190,7 +190,7 @@ class PaymentsDbSpec extends AnyFunSuite {
assert(db.getIncomingPayment(i2.paymentHash).contains(pr2)) assert(db.getIncomingPayment(i2.paymentHash).contains(pr2))
assert(db.listOutgoingPayments(1 unixms, 2000 unixms) == Seq(ps1, ps2, ps3)) assert(db.listOutgoingPayments(1 unixms, 2000 unixms) == Seq(ps1, ps2, ps3))
val i3 = Bolt11Invoice(Block.TestnetGenesisBlock.hash, Some(561 msat), paymentHash3, alicePriv, Left("invoice #3"), CltvExpiryDelta(18), expirySeconds = Some(30)) val i3 = Bolt11Invoice(Block.Testnet3GenesisBlock.hash, Some(561 msat), paymentHash3, alicePriv, Left("invoice #3"), CltvExpiryDelta(18), expirySeconds = Some(30))
val pr3 = IncomingStandardPayment(i3, preimage3, PaymentType.Standard, i3.createdAt.toTimestampMilli, IncomingPaymentStatus.Pending) val pr3 = IncomingStandardPayment(i3, preimage3, PaymentType.Standard, i3.createdAt.toTimestampMilli, IncomingPaymentStatus.Pending)
db.addIncomingPayment(i3, pr3.paymentPreimage) db.addIncomingPayment(i3, pr3.paymentPreimage)
@ -215,7 +215,7 @@ class PaymentsDbSpec extends AnyFunSuite {
// Test data // Test data
val (id1, id2, id3) = (UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID()) val (id1, id2, id3) = (UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID())
val parentId = UUID.randomUUID() val parentId = UUID.randomUUID()
val invoice1 = Bolt11Invoice(Block.TestnetGenesisBlock.hash, Some(2834 msat), paymentHash1, bobPriv, Left("invoice #1"), CltvExpiryDelta(18), expirySeconds = Some(30)) val invoice1 = Bolt11Invoice(Block.Testnet3GenesisBlock.hash, Some(2834 msat), paymentHash1, bobPriv, Left("invoice #1"), CltvExpiryDelta(18), expirySeconds = Some(30))
val ps1 = OutgoingPayment(id1, id1, Some("42"), randomBytes32(), PaymentType.Standard, 561 msat, 561 msat, alice, 1000 unixms, None, None, OutgoingPaymentStatus.Failed(Seq(FailureSummary(FailureType.REMOTE, "no candy for you", List(HopSummary(hop_ab), HopSummary(hop_bc)), Some(bob))), 1020 unixms)) val ps1 = OutgoingPayment(id1, id1, Some("42"), randomBytes32(), PaymentType.Standard, 561 msat, 561 msat, alice, 1000 unixms, None, None, OutgoingPaymentStatus.Failed(Seq(FailureSummary(FailureType.REMOTE, "no candy for you", List(HopSummary(hop_ab), HopSummary(hop_bc)), Some(bob))), 1020 unixms))
val ps2 = OutgoingPayment(id2, parentId, Some("42"), paymentHash1, PaymentType.Standard, 1105 msat, 1105 msat, bob, 1010 unixms, Some(invoice1), None, OutgoingPaymentStatus.Pending) val ps2 = OutgoingPayment(id2, parentId, Some("42"), paymentHash1, PaymentType.Standard, 1105 msat, 1105 msat, bob, 1010 unixms, Some(invoice1), None, OutgoingPaymentStatus.Pending)
val ps3 = OutgoingPayment(id3, parentId, None, paymentHash1, PaymentType.Standard, 1729 msat, 1729 msat, bob, 1040 unixms, None, None, OutgoingPaymentStatus.Succeeded(preimage1, 10 msat, Seq(HopSummary(hop_ab), HopSummary(hop_bc)), 1060 unixms)) val ps3 = OutgoingPayment(id3, parentId, None, paymentHash1, PaymentType.Standard, 1729 msat, 1729 msat, bob, 1040 unixms, None, None, OutgoingPaymentStatus.Succeeded(preimage1, 10 msat, Seq(HopSummary(hop_ab), HopSummary(hop_bc)), 1060 unixms))
@ -295,9 +295,9 @@ class PaymentsDbSpec extends AnyFunSuite {
test("migrate sqlite payments db v4 -> current") { test("migrate sqlite payments db v4 -> current") {
val dbs = TestSqliteDatabases() val dbs = TestSqliteDatabases()
val now = TimestampSecond.now() val now = TimestampSecond.now()
val pendingInvoice = Bolt11Invoice(Block.TestnetGenesisBlock.hash, Some(2500 msat), paymentHash1, bobPriv, Left("invoice #1"), CltvExpiryDelta(18), timestamp = now, expirySeconds = Some(30)) val pendingInvoice = Bolt11Invoice(Block.Testnet3GenesisBlock.hash, Some(2500 msat), paymentHash1, bobPriv, Left("invoice #1"), CltvExpiryDelta(18), timestamp = now, expirySeconds = Some(30))
val pending = IncomingStandardPayment(pendingInvoice, preimage1, PaymentType.Standard, pendingInvoice.createdAt.toTimestampMilli, IncomingPaymentStatus.Pending) val pending = IncomingStandardPayment(pendingInvoice, preimage1, PaymentType.Standard, pendingInvoice.createdAt.toTimestampMilli, IncomingPaymentStatus.Pending)
val paidInvoice = Bolt11Invoice(Block.TestnetGenesisBlock.hash, Some(10_000 msat), paymentHash2, bobPriv, Left("invoice #2"), CltvExpiryDelta(12), timestamp = 250 unixsec, expirySeconds = Some(60)) val paidInvoice = Bolt11Invoice(Block.Testnet3GenesisBlock.hash, Some(10_000 msat), paymentHash2, bobPriv, Left("invoice #2"), CltvExpiryDelta(12), timestamp = 250 unixsec, expirySeconds = Some(60))
val paid = IncomingStandardPayment(paidInvoice, preimage2, PaymentType.Standard, paidInvoice.createdAt.toTimestampMilli, IncomingPaymentStatus.Received(11_000 msat, 300.unixsec.toTimestampMilli)) val paid = IncomingStandardPayment(paidInvoice, preimage2, PaymentType.Standard, paidInvoice.createdAt.toTimestampMilli, IncomingPaymentStatus.Received(11_000 msat, 300.unixsec.toTimestampMilli))
migrationCheck( migrationCheck(
@ -427,9 +427,9 @@ class PaymentsDbSpec extends AnyFunSuite {
val ps1 = OutgoingPayment(id1, id1, None, randomBytes32(), PaymentType.Standard, 561 msat, 561 msat, PrivateKey(ByteVector32.One).publicKey, TimestampMilli(Instant.parse("2021-01-01T10:15:30.00Z").toEpochMilli), None, None, OutgoingPaymentStatus.Pending) val ps1 = OutgoingPayment(id1, id1, None, randomBytes32(), PaymentType.Standard, 561 msat, 561 msat, PrivateKey(ByteVector32.One).publicKey, TimestampMilli(Instant.parse("2021-01-01T10:15:30.00Z").toEpochMilli), None, None, OutgoingPaymentStatus.Pending)
val ps2 = OutgoingPayment(id2, id2, None, randomBytes32(), PaymentType.Standard, 1105 msat, 1105 msat, PrivateKey(ByteVector32.One).publicKey, TimestampMilli(Instant.parse("2020-05-14T13:47:21.00Z").toEpochMilli), None, None, OutgoingPaymentStatus.Failed(Nil, TimestampMilli(Instant.parse("2021-05-15T04:12:40.00Z").toEpochMilli))) val ps2 = OutgoingPayment(id2, id2, None, randomBytes32(), PaymentType.Standard, 1105 msat, 1105 msat, PrivateKey(ByteVector32.One).publicKey, TimestampMilli(Instant.parse("2020-05-14T13:47:21.00Z").toEpochMilli), None, None, OutgoingPaymentStatus.Failed(Nil, TimestampMilli(Instant.parse("2021-05-15T04:12:40.00Z").toEpochMilli)))
val ps3 = OutgoingPayment(id3, id3, None, paymentHash1, PaymentType.Standard, 1729 msat, 1729 msat, PrivateKey(ByteVector32.One).publicKey, TimestampMilli(Instant.parse("2021-01-28T09:12:05.00Z").toEpochMilli), None, None, OutgoingPaymentStatus.Succeeded(preimage1, 0 msat, Nil, TimestampMilli.now())) val ps3 = OutgoingPayment(id3, id3, None, paymentHash1, PaymentType.Standard, 1729 msat, 1729 msat, PrivateKey(ByteVector32.One).publicKey, TimestampMilli(Instant.parse("2021-01-28T09:12:05.00Z").toEpochMilli), None, None, OutgoingPaymentStatus.Succeeded(preimage1, 0 msat, Nil, TimestampMilli.now()))
val i1 = Bolt11Invoice(Block.TestnetGenesisBlock.hash, Some(12345678 msat), paymentHash1, davePriv, Left("Some invoice"), CltvExpiryDelta(18), expirySeconds = None, timestamp = TimestampSecond.now()) val i1 = Bolt11Invoice(Block.Testnet3GenesisBlock.hash, Some(12345678 msat), paymentHash1, davePriv, Left("Some invoice"), CltvExpiryDelta(18), expirySeconds = None, timestamp = TimestampSecond.now())
val pr1 = IncomingStandardPayment(i1, preimage1, PaymentType.Standard, i1.createdAt.toTimestampMilli, IncomingPaymentStatus.Received(12345678 msat, TimestampMilli.now())) val pr1 = IncomingStandardPayment(i1, preimage1, PaymentType.Standard, i1.createdAt.toTimestampMilli, IncomingPaymentStatus.Received(12345678 msat, TimestampMilli.now()))
val i2 = Bolt11Invoice(Block.TestnetGenesisBlock.hash, Some(12345678 msat), paymentHash2, carolPriv, Left("Another invoice"), CltvExpiryDelta(18), expirySeconds = Some(24 * 3600), timestamp = TimestampSecond(Instant.parse("2020-12-30T10:00:55.00Z").getEpochSecond)) val i2 = Bolt11Invoice(Block.Testnet3GenesisBlock.hash, Some(12345678 msat), paymentHash2, carolPriv, Left("Another invoice"), CltvExpiryDelta(18), expirySeconds = Some(24 * 3600), timestamp = TimestampSecond(Instant.parse("2020-12-30T10:00:55.00Z").getEpochSecond))
val pr2 = IncomingStandardPayment(i2, preimage2, PaymentType.Standard, i2.createdAt.toTimestampMilli, IncomingPaymentStatus.Expired) val pr2 = IncomingStandardPayment(i2, preimage2, PaymentType.Standard, i2.createdAt.toTimestampMilli, IncomingPaymentStatus.Expired)
migrationCheck( migrationCheck(
@ -523,9 +523,9 @@ class PaymentsDbSpec extends AnyFunSuite {
test("migrate postgres payments db v6 -> current") { test("migrate postgres payments db v6 -> current") {
val dbs = TestPgDatabases() val dbs = TestPgDatabases()
val now = TimestampSecond.now() val now = TimestampSecond.now()
val pendingInvoice = Bolt11Invoice(Block.TestnetGenesisBlock.hash, Some(2500 msat), paymentHash1, bobPriv, Left("invoice #1"), CltvExpiryDelta(18), timestamp = now, expirySeconds = Some(30)) val pendingInvoice = Bolt11Invoice(Block.Testnet3GenesisBlock.hash, Some(2500 msat), paymentHash1, bobPriv, Left("invoice #1"), CltvExpiryDelta(18), timestamp = now, expirySeconds = Some(30))
val pending = IncomingStandardPayment(pendingInvoice, preimage1, PaymentType.Standard, pendingInvoice.createdAt.toTimestampMilli, IncomingPaymentStatus.Pending) val pending = IncomingStandardPayment(pendingInvoice, preimage1, PaymentType.Standard, pendingInvoice.createdAt.toTimestampMilli, IncomingPaymentStatus.Pending)
val paidInvoice = Bolt11Invoice(Block.TestnetGenesisBlock.hash, Some(10_000 msat), paymentHash2, bobPriv, Left("invoice #2"), CltvExpiryDelta(12), timestamp = 250 unixsec, expirySeconds = Some(60)) val paidInvoice = Bolt11Invoice(Block.Testnet3GenesisBlock.hash, Some(10_000 msat), paymentHash2, bobPriv, Left("invoice #2"), CltvExpiryDelta(12), timestamp = 250 unixsec, expirySeconds = Some(60))
val paid = IncomingStandardPayment(paidInvoice, preimage2, PaymentType.Standard, paidInvoice.createdAt.toTimestampMilli, IncomingPaymentStatus.Received(11_000 msat, 300.unixsec.toTimestampMilli)) val paid = IncomingStandardPayment(paidInvoice, preimage2, PaymentType.Standard, paidInvoice.createdAt.toTimestampMilli, IncomingPaymentStatus.Received(11_000 msat, 300.unixsec.toTimestampMilli))
migrationCheck( migrationCheck(
@ -653,21 +653,21 @@ class PaymentsDbSpec extends AnyFunSuite {
assert(!db.receiveIncomingPayment(unknownPaymentHash, 12345678 msat)) assert(!db.receiveIncomingPayment(unknownPaymentHash, 12345678 msat))
assert(db.getIncomingPayment(unknownPaymentHash).isEmpty) assert(db.getIncomingPayment(unknownPaymentHash).isEmpty)
val expiredInvoice1 = Bolt11Invoice(Block.TestnetGenesisBlock.hash, Some(561 msat), randomBytes32(), alicePriv, Left("invoice #1"), CltvExpiryDelta(18), timestamp = 1 unixsec) val expiredInvoice1 = Bolt11Invoice(Block.Testnet3GenesisBlock.hash, Some(561 msat), randomBytes32(), alicePriv, Left("invoice #1"), CltvExpiryDelta(18), timestamp = 1 unixsec)
val expiredInvoice2 = Bolt11Invoice(Block.TestnetGenesisBlock.hash, Some(1105 msat), randomBytes32(), bobPriv, Left("invoice #2"), CltvExpiryDelta(18), timestamp = 2 unixsec, expirySeconds = Some(30)) val expiredInvoice2 = Bolt11Invoice(Block.Testnet3GenesisBlock.hash, Some(1105 msat), randomBytes32(), bobPriv, Left("invoice #2"), CltvExpiryDelta(18), timestamp = 2 unixsec, expirySeconds = Some(30))
val expiredPayment1 = IncomingStandardPayment(expiredInvoice1, randomBytes32(), PaymentType.Standard, expiredInvoice1.createdAt.toTimestampMilli, IncomingPaymentStatus.Expired) val expiredPayment1 = IncomingStandardPayment(expiredInvoice1, randomBytes32(), PaymentType.Standard, expiredInvoice1.createdAt.toTimestampMilli, IncomingPaymentStatus.Expired)
val expiredPayment2 = IncomingStandardPayment(expiredInvoice2, randomBytes32(), PaymentType.Standard, expiredInvoice2.createdAt.toTimestampMilli, IncomingPaymentStatus.Expired) val expiredPayment2 = IncomingStandardPayment(expiredInvoice2, randomBytes32(), PaymentType.Standard, expiredInvoice2.createdAt.toTimestampMilli, IncomingPaymentStatus.Expired)
val pendingInvoice1 = Bolt11Invoice(Block.TestnetGenesisBlock.hash, Some(561 msat), randomBytes32(), alicePriv, Left("invoice #4"), CltvExpiryDelta(18), timestamp = TimestampSecond.now() - 10.seconds) val pendingInvoice1 = Bolt11Invoice(Block.Testnet3GenesisBlock.hash, Some(561 msat), randomBytes32(), alicePriv, Left("invoice #4"), CltvExpiryDelta(18), timestamp = TimestampSecond.now() - 10.seconds)
val pendingInvoice2 = Bolt11Invoice(Block.TestnetGenesisBlock.hash, Some(1105 msat), randomBytes32(), bobPriv, Left("invoice #5"), CltvExpiryDelta(18), expirySeconds = Some(30), timestamp = TimestampSecond.now() - 9.seconds) val pendingInvoice2 = Bolt11Invoice(Block.Testnet3GenesisBlock.hash, Some(1105 msat), randomBytes32(), bobPriv, Left("invoice #5"), CltvExpiryDelta(18), expirySeconds = Some(30), timestamp = TimestampSecond.now() - 9.seconds)
val pendingPayment1 = IncomingStandardPayment(pendingInvoice1, randomBytes32(), PaymentType.Standard, pendingInvoice1.createdAt.toTimestampMilli, IncomingPaymentStatus.Pending) val pendingPayment1 = IncomingStandardPayment(pendingInvoice1, randomBytes32(), PaymentType.Standard, pendingInvoice1.createdAt.toTimestampMilli, IncomingPaymentStatus.Pending)
val pendingPayment2 = IncomingStandardPayment(pendingInvoice2, randomBytes32(), PaymentType.SwapIn, pendingInvoice2.createdAt.toTimestampMilli, IncomingPaymentStatus.Pending) val pendingPayment2 = IncomingStandardPayment(pendingInvoice2, randomBytes32(), PaymentType.SwapIn, pendingInvoice2.createdAt.toTimestampMilli, IncomingPaymentStatus.Pending)
val paidInvoice1 = Bolt11Invoice(Block.TestnetGenesisBlock.hash, Some(561 msat), randomBytes32(), alicePriv, Left("invoice #7"), CltvExpiryDelta(18), timestamp = TimestampSecond.now() - 5.seconds) val paidInvoice1 = Bolt11Invoice(Block.Testnet3GenesisBlock.hash, Some(561 msat), randomBytes32(), alicePriv, Left("invoice #7"), CltvExpiryDelta(18), timestamp = TimestampSecond.now() - 5.seconds)
val paidInvoice2 = Bolt11Invoice(Block.TestnetGenesisBlock.hash, Some(1105 msat), randomBytes32(), bobPriv, Left("invoice #8"), CltvExpiryDelta(18), expirySeconds = Some(60), timestamp = TimestampSecond.now() - 4.seconds) val paidInvoice2 = Bolt11Invoice(Block.Testnet3GenesisBlock.hash, Some(1105 msat), randomBytes32(), bobPriv, Left("invoice #8"), CltvExpiryDelta(18), expirySeconds = Some(60), timestamp = TimestampSecond.now() - 4.seconds)
val nodeId = randomKey().publicKey val nodeId = randomKey().publicKey
val offer = Offer(None, Some("offer"), nodeId, Features.empty, Block.TestnetGenesisBlock.hash) val offer = Offer(None, Some("offer"), nodeId, Features.empty, Block.Testnet3GenesisBlock.hash)
val paidInvoice3 = MinimalBolt12Invoice(offer, Block.TestnetGenesisBlock.hash, 1729 msat, 1, randomBytes32(), randomKey().publicKey, TimestampSecond.now() - 3.seconds) val paidInvoice3 = MinimalBolt12Invoice(offer, Block.Testnet3GenesisBlock.hash, 1729 msat, 1, randomBytes32(), randomKey().publicKey, TimestampSecond.now() - 3.seconds)
val receivedAt1 = TimestampMilli.now() + 1.milli val receivedAt1 = TimestampMilli.now() + 1.milli
val receivedAt2 = TimestampMilli.now() + 2.milli val receivedAt2 = TimestampMilli.now() + 2.milli
val receivedAt3 = TimestampMilli.now() + 3.milli val receivedAt3 = TimestampMilli.now() + 3.milli
@ -731,7 +731,7 @@ class PaymentsDbSpec extends AnyFunSuite {
val db = dbs.payments val db = dbs.payments
val parentId = UUID.randomUUID() val parentId = UUID.randomUUID()
val i1 = Bolt11Invoice(Block.TestnetGenesisBlock.hash, Some(123 msat), paymentHash1, davePriv, Left("Some invoice"), CltvExpiryDelta(18), expirySeconds = None, timestamp = 0 unixsec) val i1 = Bolt11Invoice(Block.Testnet3GenesisBlock.hash, Some(123 msat), paymentHash1, davePriv, Left("Some invoice"), CltvExpiryDelta(18), expirySeconds = None, timestamp = 0 unixsec)
val payerKey = randomKey() val payerKey = randomKey()
val i2 = createBolt12Invoice(789 msat, payerKey, carolPriv, randomBytes32()) val i2 = createBolt12Invoice(789 msat, payerKey, carolPriv, randomBytes32())
val s1 = OutgoingPayment(UUID.randomUUID(), parentId, None, paymentHash1, PaymentType.Standard, 123 msat, 600 msat, dave, 100 unixms, Some(i1), None, OutgoingPaymentStatus.Pending) val s1 = OutgoingPayment(UUID.randomUUID(), parentId, None, paymentHash1, PaymentType.Standard, 123 msat, 600 msat, dave, 100 unixms, Some(i1), None, OutgoingPaymentStatus.Pending)
@ -800,8 +800,8 @@ object PaymentsDbSpec {
val (paymentHash1, paymentHash2, paymentHash3, paymentHash4) = (Crypto.sha256(preimage1), Crypto.sha256(preimage2), Crypto.sha256(preimage3), Crypto.sha256(preimage4)) val (paymentHash1, paymentHash2, paymentHash3, paymentHash4) = (Crypto.sha256(preimage1), Crypto.sha256(preimage2), Crypto.sha256(preimage3), Crypto.sha256(preimage4))
def createBolt12Invoice(amount: MilliSatoshi, payerKey: PrivateKey, recipientKey: PrivateKey, preimage: ByteVector32): Bolt12Invoice = { def createBolt12Invoice(amount: MilliSatoshi, payerKey: PrivateKey, recipientKey: PrivateKey, preimage: ByteVector32): Bolt12Invoice = {
val offer = Offer(Some(amount), Some("some offer"), recipientKey.publicKey, Features.empty, Block.TestnetGenesisBlock.hash) val offer = Offer(Some(amount), Some("some offer"), recipientKey.publicKey, Features.empty, Block.Testnet3GenesisBlock.hash)
val invoiceRequest = InvoiceRequest(offer, 789 msat, 1, Features.empty, payerKey, Block.TestnetGenesisBlock.hash) val invoiceRequest = InvoiceRequest(offer, 789 msat, 1, Features.empty, payerKey, Block.Testnet3GenesisBlock.hash)
val dummyRoute = PaymentBlindedRoute(RouteBlinding.create(randomKey(), Seq(randomKey().publicKey), Seq(randomBytes(100))).route, PaymentInfo(0 msat, 0, CltvExpiryDelta(0), 0 msat, 0 msat, Features.empty)) val dummyRoute = PaymentBlindedRoute(RouteBlinding.create(randomKey(), Seq(randomKey().publicKey), Seq(randomBytes(100))).route, PaymentInfo(0 msat, 0, CltvExpiryDelta(0), 0 msat, 0 msat, Features.empty))
Bolt12Invoice(invoiceRequest, preimage, recipientKey, 1 hour, Features.empty, Seq(dummyRoute)) Bolt12Invoice(invoiceRequest, preimage, recipientKey, 1 hour, Features.empty, Seq(dummyRoute))
} }

View File

@ -210,7 +210,7 @@ class Bolt12InvoiceSpec extends AnyFunSuite {
} }
test("encode/decode invoice with many fields") { test("encode/decode invoice with many fields") {
val chain = Block.TestnetGenesisBlock.hash val chain = Block.Testnet3GenesisBlock.hash
val amount = 123456 msat val amount = 123456 msat
val description = "invoice with many fields" val description = "invoice with many fields"
val features = Features.empty val features = Features.empty
@ -337,7 +337,7 @@ class Bolt12InvoiceSpec extends AnyFunSuite {
assert(payerKey.publicKey == PublicKey(hex"027c6d03fa8f366e2ef8017cdfaf5d3cf1a3b0123db1318263b662c0aa9ec9c959")) assert(payerKey.publicKey == PublicKey(hex"027c6d03fa8f366e2ef8017cdfaf5d3cf1a3b0123db1318263b662c0aa9ec9c959"))
val preimage = ByteVector32(hex"99221825b86576e94391b179902be8b22c7cfa7c3d14aec6ae86657dfd9bd2a8") val preimage = ByteVector32(hex"99221825b86576e94391b179902be8b22c7cfa7c3d14aec6ae86657dfd9bd2a8")
val offer = Offer(TlvStream[OfferTlv]( val offer = Offer(TlvStream[OfferTlv](
OfferChains(Seq(Block.TestnetGenesisBlock.hash)), OfferChains(Seq(Block.Testnet3GenesisBlock.hash)),
OfferAmount(100000 msat), OfferAmount(100000 msat),
OfferDescription("offer with quantity"), OfferDescription("offer with quantity"),
OfferIssuer("alice@bigshop.com"), OfferIssuer("alice@bigshop.com"),
@ -346,7 +346,7 @@ class Bolt12InvoiceSpec extends AnyFunSuite {
val encodedOffer = "lno1qgsyxjtl6luzd9t3pr62xr7eemp6awnejusgf6gw45q75vcfqqqqqqqgqvqcdgq2zdhkven9wgs8w6t5dqs8zatpde6xjarezggkzmrfvdj5qcnfvaeksmms9e3k7mg5qgp7s93pqvn6l4vemgezdarq3wt2kpp0u4vt74vzz8futen7ej97n93jypp57" val encodedOffer = "lno1qgsyxjtl6luzd9t3pr62xr7eemp6awnejusgf6gw45q75vcfqqqqqqqgqvqcdgq2zdhkven9wgs8w6t5dqs8zatpde6xjarezggkzmrfvdj5qcnfvaeksmms9e3k7mg5qgp7s93pqvn6l4vemgezdarq3wt2kpp0u4vt74vzz8futen7ej97n93jypp57"
assert(offer.toString == encodedOffer) assert(offer.toString == encodedOffer)
assert(Offer.decode(encodedOffer).get == offer) assert(Offer.decode(encodedOffer).get == offer)
val request = InvoiceRequest(offer, 7200000 msat, 72, Features.empty, payerKey, Block.TestnetGenesisBlock.hash) val request = InvoiceRequest(offer, 7200000 msat, 72, Features.empty, payerKey, Block.Testnet3GenesisBlock.hash)
// Invoice request generation is not reproducible because we add randomness in the first TLV. // Invoice request generation is not reproducible because we add randomness in the first TLV.
val encodedRequest = "lnr1qqs8lqvnh3kg9uj003lxlxyj8hthymgq4p9ms0ag0ryx5uw8gsuus4gzypp5jl7hlqnf2ugg7j3slkwwcwht57vhyzzwjr4dq84rxzgqqqqqqzqrqxr2qzsndanxvetjypmkjargypch2ctww35hg7gjz9skc6trv4qxy6t8wd5x7upwvdhk69qzq05pvggry7hatxw6xgn0gcytj64sgtl9tzl4tqs360z7vlkv305evv3qgd84qgzrf9la07pxj4cs3a9rplvuasawhfuewgyyay826q02xvysqqqqqpfqxmwaqptqzjzcyyp8cmgrl28nvm3wlqqheha0t570rgaszg7mzvvzvwmx9s92nmyujk0sgpef8dt57nygu3dnfhglymt6mnle6j8s28rler8wv3zygen07v4ddfplc9qs7nkdzwcelm2rs552slkpv45xxng65ne6y4dlq2764gqv" val encodedRequest = "lnr1qqs8lqvnh3kg9uj003lxlxyj8hthymgq4p9ms0ag0ryx5uw8gsuus4gzypp5jl7hlqnf2ugg7j3slkwwcwht57vhyzzwjr4dq84rxzgqqqqqqzqrqxr2qzsndanxvetjypmkjargypch2ctww35hg7gjz9skc6trv4qxy6t8wd5x7upwvdhk69qzq05pvggry7hatxw6xgn0gcytj64sgtl9tzl4tqs360z7vlkv305evv3qgd84qgzrf9la07pxj4cs3a9rplvuasawhfuewgyyay826q02xvysqqqqqpfqxmwaqptqzjzcyyp8cmgrl28nvm3wlqqheha0t570rgaszg7mzvvzvwmx9s92nmyujk0sgpef8dt57nygu3dnfhglymt6mnle6j8s28rler8wv3zygen07v4ddfplc9qs7nkdzwcelm2rs552slkpv45xxng65ne6y4dlq2764gqv"
val decodedRequest = InvoiceRequest.decode(encodedRequest).get val decodedRequest = InvoiceRequest.decode(encodedRequest).get

View File

@ -810,7 +810,7 @@ class MultiPartHandlerSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike
assert(nodeParams.db.payments.getIncomingPayment(paymentHash).isEmpty) assert(nodeParams.db.payments.getIncomingPayment(paymentHash).isEmpty)
val add = UpdateAddHtlc(ByteVector32.One, 0, 1000 msat, paymentHash, defaultExpiry, TestConstants.emptyOnionPacket, None, 1.0) val add = UpdateAddHtlc(ByteVector32.One, 0, 1000 msat, paymentHash, defaultExpiry, TestConstants.emptyOnionPacket, None, 1.0)
val invoice = Bolt11Invoice(Block.TestnetGenesisBlock.hash, None, paymentHash, randomKey(), Left("dummy"), CltvExpiryDelta(12)) val invoice = Bolt11Invoice(Block.Testnet3GenesisBlock.hash, None, paymentHash, randomKey(), Left("dummy"), CltvExpiryDelta(12))
val incomingPayment = IncomingStandardPayment(invoice, paymentPreimage, PaymentType.Standard, invoice.createdAt.toTimestampMilli, IncomingPaymentStatus.Pending) val incomingPayment = IncomingStandardPayment(invoice, paymentPreimage, PaymentType.Standard, invoice.createdAt.toTimestampMilli, IncomingPaymentStatus.Pending)
val fulfill = DoFulfill(incomingPayment, MultiPartPaymentFSM.MultiPartPaymentSucceeded(paymentHash, Queue(HtlcPart(1000 msat, add)))) val fulfill = DoFulfill(incomingPayment, MultiPartPaymentFSM.MultiPartPaymentSucceeded(paymentHash, Queue(HtlcPart(1000 msat, add))))
sender.send(handlerWithoutMpp, fulfill) sender.send(handlerWithoutMpp, fulfill)

View File

@ -158,7 +158,7 @@ class PostRestartHtlcCleanerSpec extends TestKitBaseClass with FixtureAnyFunSuit
val preimage = randomBytes32() val preimage = randomBytes32()
val paymentHash = Crypto.sha256(preimage) val paymentHash = Crypto.sha256(preimage)
val invoice = Bolt11Invoice(Block.TestnetGenesisBlock.hash, Some(500 msat), paymentHash, TestConstants.Bob.nodeKeyManager.nodeKey.privateKey, Left("Some invoice"), CltvExpiryDelta(18)) val invoice = Bolt11Invoice(Block.Testnet3GenesisBlock.hash, Some(500 msat), paymentHash, TestConstants.Bob.nodeKeyManager.nodeKey.privateKey, Left("Some invoice"), CltvExpiryDelta(18))
nodeParams.db.payments.addIncomingPayment(invoice, preimage) nodeParams.db.payments.addIncomingPayment(invoice, preimage)
nodeParams.db.payments.receiveIncomingPayment(paymentHash, 5000 msat) nodeParams.db.payments.receiveIncomingPayment(paymentHash, 5000 msat)

View File

@ -39,19 +39,19 @@ class InvoicePurgerSpec extends ScalaTestWithActorTestKit(ConfigFactory.load("ap
val count = 10 val count = 10
// create expired invoices // create expired invoices
val expiredInvoices = Seq.fill(count)(Bolt11Invoice(Block.TestnetGenesisBlock.hash, Some(100 msat), randomBytes32(), alicePriv, Left("expired invoice"), CltvExpiryDelta(18), val expiredInvoices = Seq.fill(count)(Bolt11Invoice(Block.Testnet3GenesisBlock.hash, Some(100 msat), randomBytes32(), alicePriv, Left("expired invoice"), CltvExpiryDelta(18),
timestamp = 1 unixsec)) timestamp = 1 unixsec))
val expiredPayments = expiredInvoices.map(invoice => IncomingStandardPayment(invoice, randomBytes32(), PaymentType.Standard, invoice.createdAt.toTimestampMilli, IncomingPaymentStatus.Expired)) val expiredPayments = expiredInvoices.map(invoice => IncomingStandardPayment(invoice, randomBytes32(), PaymentType.Standard, invoice.createdAt.toTimestampMilli, IncomingPaymentStatus.Expired))
expiredPayments.foreach(payment => db.addIncomingPayment(payment.invoice, payment.paymentPreimage)) expiredPayments.foreach(payment => db.addIncomingPayment(payment.invoice, payment.paymentPreimage))
// create pending invoices // create pending invoices
val pendingInvoices = Seq.fill(count)(Bolt11Invoice(Block.TestnetGenesisBlock.hash, Some(100 msat), randomBytes32(), alicePriv, Left("pending invoice"), CltvExpiryDelta(18))) val pendingInvoices = Seq.fill(count)(Bolt11Invoice(Block.Testnet3GenesisBlock.hash, Some(100 msat), randomBytes32(), alicePriv, Left("pending invoice"), CltvExpiryDelta(18)))
val pendingPayments = pendingInvoices.map(invoice => IncomingStandardPayment(invoice, randomBytes32(), PaymentType.Standard, invoice.createdAt.toTimestampMilli, IncomingPaymentStatus.Pending)) val pendingPayments = pendingInvoices.map(invoice => IncomingStandardPayment(invoice, randomBytes32(), PaymentType.Standard, invoice.createdAt.toTimestampMilli, IncomingPaymentStatus.Pending))
pendingPayments.foreach(payment => db.addIncomingPayment(payment.invoice, payment.paymentPreimage)) pendingPayments.foreach(payment => db.addIncomingPayment(payment.invoice, payment.paymentPreimage))
// create paid invoices // create paid invoices
val receivedAt = TimestampMilli.now() + 1.milli val receivedAt = TimestampMilli.now() + 1.milli
val paidInvoices = Seq.fill(count)(Bolt11Invoice(Block.TestnetGenesisBlock.hash, Some(100 msat), randomBytes32(), alicePriv, Left("paid invoice"), CltvExpiryDelta(18))) val paidInvoices = Seq.fill(count)(Bolt11Invoice(Block.Testnet3GenesisBlock.hash, Some(100 msat), randomBytes32(), alicePriv, Left("paid invoice"), CltvExpiryDelta(18)))
val paidPayments = paidInvoices.map(invoice => IncomingStandardPayment(invoice, randomBytes32(), PaymentType.Standard, invoice.createdAt.toTimestampMilli, IncomingPaymentStatus.Received(100 msat, receivedAt))) val paidPayments = paidInvoices.map(invoice => IncomingStandardPayment(invoice, randomBytes32(), PaymentType.Standard, invoice.createdAt.toTimestampMilli, IncomingPaymentStatus.Received(100 msat, receivedAt)))
paidPayments.foreach(payment => { paidPayments.foreach(payment => {
db.addIncomingPayment(payment.invoice, payment.paymentPreimage) db.addIncomingPayment(payment.invoice, payment.paymentPreimage)
@ -86,13 +86,13 @@ class InvoicePurgerSpec extends ScalaTestWithActorTestKit(ConfigFactory.load("ap
val interval = 5 seconds val interval = 5 seconds
// add an expired invoice from before the 15 days look back period // add an expired invoice from before the 15 days look back period
val expiredInvoice1 = Bolt11Invoice(Block.TestnetGenesisBlock.hash, Some(100 msat), randomBytes32(), alicePriv, Left("expired invoice2"), CltvExpiryDelta(18), val expiredInvoice1 = Bolt11Invoice(Block.Testnet3GenesisBlock.hash, Some(100 msat), randomBytes32(), alicePriv, Left("expired invoice2"), CltvExpiryDelta(18),
timestamp = 5 unixsec) timestamp = 5 unixsec)
val expiredPayment1 = IncomingStandardPayment(expiredInvoice1, randomBytes32(), PaymentType.Standard, expiredInvoice1.createdAt.toTimestampMilli, IncomingPaymentStatus.Expired) val expiredPayment1 = IncomingStandardPayment(expiredInvoice1, randomBytes32(), PaymentType.Standard, expiredInvoice1.createdAt.toTimestampMilli, IncomingPaymentStatus.Expired)
db.addIncomingPayment(expiredPayment1.invoice, expiredPayment1.paymentPreimage) db.addIncomingPayment(expiredPayment1.invoice, expiredPayment1.paymentPreimage)
// add an expired invoice from after the 15 day look back period // add an expired invoice from after the 15 day look back period
val expiredInvoice2 = Bolt11Invoice(Block.TestnetGenesisBlock.hash, Some(100 msat), randomBytes32(), alicePriv, Left("expired invoice2"), CltvExpiryDelta(18), val expiredInvoice2 = Bolt11Invoice(Block.Testnet3GenesisBlock.hash, Some(100 msat), randomBytes32(), alicePriv, Left("expired invoice2"), CltvExpiryDelta(18),
timestamp = TimestampSecond.now() - 10.days) timestamp = TimestampSecond.now() - 10.days)
val expiredPayment2 = IncomingStandardPayment(expiredInvoice2, randomBytes32(), PaymentType.Standard, expiredInvoice2.createdAt.toTimestampMilli, IncomingPaymentStatus.Expired) val expiredPayment2 = IncomingStandardPayment(expiredInvoice2, randomBytes32(), PaymentType.Standard, expiredInvoice2.createdAt.toTimestampMilli, IncomingPaymentStatus.Expired)
db.addIncomingPayment(expiredPayment2.invoice, expiredPayment2.paymentPreimage) db.addIncomingPayment(expiredPayment2.invoice, expiredPayment2.paymentPreimage)
@ -108,13 +108,13 @@ class InvoicePurgerSpec extends ScalaTestWithActorTestKit(ConfigFactory.load("ap
assert(db.listExpiredIncomingPayments(0 unixms, TimestampMilli.now(), None).isEmpty) assert(db.listExpiredIncomingPayments(0 unixms, TimestampMilli.now(), None).isEmpty)
// add an expired invoice from before the 15 days look back period // add an expired invoice from before the 15 days look back period
val expiredInvoice3 = Bolt11Invoice(Block.TestnetGenesisBlock.hash, Some(100 msat), randomBytes32(), alicePriv, Left("expired invoice3"), CltvExpiryDelta(18), val expiredInvoice3 = Bolt11Invoice(Block.Testnet3GenesisBlock.hash, Some(100 msat), randomBytes32(), alicePriv, Left("expired invoice3"), CltvExpiryDelta(18),
timestamp = 5 unixsec) timestamp = 5 unixsec)
val expiredPayment3 = IncomingStandardPayment(expiredInvoice3, randomBytes32(), PaymentType.Standard, expiredInvoice3.createdAt.toTimestampMilli, IncomingPaymentStatus.Expired) val expiredPayment3 = IncomingStandardPayment(expiredInvoice3, randomBytes32(), PaymentType.Standard, expiredInvoice3.createdAt.toTimestampMilli, IncomingPaymentStatus.Expired)
db.addIncomingPayment(expiredPayment3.invoice, expiredPayment3.paymentPreimage) db.addIncomingPayment(expiredPayment3.invoice, expiredPayment3.paymentPreimage)
// add another expired invoice from after the 15 day look back period // add another expired invoice from after the 15 day look back period
val expiredInvoice4 = Bolt11Invoice(Block.TestnetGenesisBlock.hash, Some(100 msat), randomBytes32(), alicePriv, Left("expired invoice4"), CltvExpiryDelta(18), val expiredInvoice4 = Bolt11Invoice(Block.Testnet3GenesisBlock.hash, Some(100 msat), randomBytes32(), alicePriv, Left("expired invoice4"), CltvExpiryDelta(18),
timestamp = TimestampSecond.now() - 10.days) timestamp = TimestampSecond.now() - 10.days)
val expiredPayment4 = IncomingStandardPayment(expiredInvoice4, randomBytes32(), PaymentType.Standard, expiredInvoice4.createdAt.toTimestampMilli, IncomingPaymentStatus.Expired) val expiredPayment4 = IncomingStandardPayment(expiredInvoice4, randomBytes32(), PaymentType.Standard, expiredInvoice4.createdAt.toTimestampMilli, IncomingPaymentStatus.Expired)
db.addIncomingPayment(expiredPayment4.invoice, expiredPayment4.paymentPreimage) db.addIncomingPayment(expiredPayment4.invoice, expiredPayment4.paymentPreimage)

View File

@ -64,7 +64,7 @@ class OfferTypesSpec extends AnyFunSuite {
test("offer with amount and quantity") { test("offer with amount and quantity") {
val offer = Offer(TlvStream[OfferTlv]( val offer = Offer(TlvStream[OfferTlv](
OfferChains(Seq(Block.TestnetGenesisBlock.hash)), OfferChains(Seq(Block.Testnet3GenesisBlock.hash)),
OfferAmount(50 msat), OfferAmount(50 msat),
OfferDescription("offer with quantity"), OfferDescription("offer with quantity"),
OfferIssuer("alice@bigshop.com"), OfferIssuer("alice@bigshop.com"),
@ -144,7 +144,7 @@ class OfferTypesSpec extends AnyFunSuite {
val withDefaultChain = signInvoiceRequest(request.copy(records = TlvStream(request.records.records ++ Seq(InvoiceRequestChain(Block.LivenetGenesisBlock.hash)))), payerKey) val withDefaultChain = signInvoiceRequest(request.copy(records = TlvStream(request.records.records ++ Seq(InvoiceRequestChain(Block.LivenetGenesisBlock.hash)))), payerKey)
assert(withDefaultChain.isValid) assert(withDefaultChain.isValid)
assert(withDefaultChain.offer == offer) assert(withDefaultChain.offer == offer)
val otherChain = signInvoiceRequest(request.copy(records = TlvStream(request.records.records ++ Seq(InvoiceRequestChain(Block.TestnetGenesisBlock.hash)))), payerKey) val otherChain = signInvoiceRequest(request.copy(records = TlvStream(request.records.records ++ Seq(InvoiceRequestChain(Block.Testnet3GenesisBlock.hash)))), payerKey)
assert(!otherChain.isValid) assert(!otherChain.isValid)
} }
{ {

View File

@ -72,7 +72,7 @@
<akka.version>2.6.20</akka.version> <akka.version>2.6.20</akka.version>
<akka.http.version>10.2.7</akka.http.version> <akka.http.version>10.2.7</akka.http.version>
<sttp.version>3.8.16</sttp.version> <sttp.version>3.8.16</sttp.version>
<bitcoinlib.version>0.33</bitcoinlib.version> <bitcoinlib.version>0.34</bitcoinlib.version>
<guava.version>32.1.1-jre</guava.version> <guava.version>32.1.1-jre</guava.version>
<kamon.version>2.7.3</kamon.version> <kamon.version>2.7.3</kamon.version>
</properties> </properties>