From 0a462282d728e3add6013501d6039ad26c3fdd25 Mon Sep 17 00:00:00 2001 From: sstone Date: Thu, 22 Aug 2024 19:41:26 +0200 Subject: [PATCH] Use bitcoin-kmp 0.20.0 Includes support for testnet4. --- build.gradle.kts | 2 +- .../fr/acinq/lightning/channel/Helpers.kt | 2 +- .../acinq/lightning/channel/InteractiveTx.kt | 2 +- .../states/LegacyWaitForFundingConfirmed.kt | 2 +- .../fr/acinq/lightning/crypto/KeyManager.kt | 29 ++++++++-------- .../acinq/lightning/crypto/LocalKeyManager.kt | 19 +++++------ .../acinq/lightning/json/JsonSerializers.kt | 3 +- .../acinq/lightning/payment/Bolt11Invoice.kt | 3 +- .../lightning/transactions/SwapInProtocol.kt | 8 ++--- .../lightning/transactions/Transactions.kt | 6 ++-- .../electrum/SwapInWalletTestsCommon.kt | 4 +-- .../lightning/channel/HelpersTestsCommon.kt | 10 +++--- .../crypto/LocalKeyManagerTestsCommon.kt | 8 ++--- .../payment/Bolt12InvoiceTestsCommon.kt | 6 ++-- .../tests/bitcoind/BitcoindService.kt | 33 ++++++++----------- .../lightning/wire/InitTlvTestsCommon.kt | 2 +- .../wire/LightningCodecsTestsCommon.kt | 4 +-- .../lightning/wire/OfferTypesTestsCommon.kt | 4 +-- 18 files changed, 71 insertions(+), 76 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index fd44398f0..ead4d1bcc 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -27,7 +27,7 @@ val currentOs = org.gradle.internal.os.OperatingSystem.current() kotlin { - val bitcoinKmpVersion = "0.19.0" // when upgrading bitcoin-kmp, keep secpJniJvmVersion in sync! + val bitcoinKmpVersion = "0.20.0" // when upgrading bitcoin-kmp, keep secpJniJvmVersion in sync! val secpJniJvmVersion = "0.15.0" val serializationVersion = "1.6.2" diff --git a/src/commonMain/kotlin/fr/acinq/lightning/channel/Helpers.kt b/src/commonMain/kotlin/fr/acinq/lightning/channel/Helpers.kt index c37a4e884..585991d54 100644 --- a/src/commonMain/kotlin/fr/acinq/lightning/channel/Helpers.kt +++ b/src/commonMain/kotlin/fr/acinq/lightning/channel/Helpers.kt @@ -779,7 +779,7 @@ object Helpers { val sig = Transactions.sign(it, channelKeys.revocationKey.deriveForRevocation(revokedCommitPublished.remotePerCommitmentSecret)) val signedTx = Transactions.addSigs(it, sig) // we need to make sure that the tx is indeed valid - when (runTrying { Transaction.correctlySpends(signedTx.tx, listOf(htlcTx), ScriptFlags.STANDARD_SCRIPT_VERIFY_FLAGS) }) { + when (runTrying { signedTx.tx.correctlySpends(listOf(htlcTx), ScriptFlags.STANDARD_SCRIPT_VERIFY_FLAGS) }) { is Try.Success -> signedTx is Try.Failure -> null } diff --git a/src/commonMain/kotlin/fr/acinq/lightning/channel/InteractiveTx.kt b/src/commonMain/kotlin/fr/acinq/lightning/channel/InteractiveTx.kt index 5074949ee..d077dc252 100644 --- a/src/commonMain/kotlin/fr/acinq/lightning/channel/InteractiveTx.kt +++ b/src/commonMain/kotlin/fr/acinq/lightning/channel/InteractiveTx.kt @@ -534,7 +534,7 @@ data class PartiallySignedSharedTransaction(override val tx: SharedTransaction, } } val fullySignedTx = FullySignedSharedTransaction(tx, localSigs, remoteSigs, sharedSigs) - return when (runTrying { Transaction.correctlySpends(fullySignedTx.signedTx, tx.spentOutputs, ScriptFlags.STANDARD_SCRIPT_VERIFY_FLAGS) }) { + return when (runTrying { fullySignedTx.signedTx.correctlySpends(tx.spentOutputs, ScriptFlags.STANDARD_SCRIPT_VERIFY_FLAGS) }) { is Try.Success -> fullySignedTx is Try.Failure -> null } diff --git a/src/commonMain/kotlin/fr/acinq/lightning/channel/states/LegacyWaitForFundingConfirmed.kt b/src/commonMain/kotlin/fr/acinq/lightning/channel/states/LegacyWaitForFundingConfirmed.kt index d98cbe403..9d32ce837 100644 --- a/src/commonMain/kotlin/fr/acinq/lightning/channel/states/LegacyWaitForFundingConfirmed.kt +++ b/src/commonMain/kotlin/fr/acinq/lightning/channel/states/LegacyWaitForFundingConfirmed.kt @@ -39,7 +39,7 @@ data class LegacyWaitForFundingConfirmed( when (cmd.watch) { is WatchEventConfirmed -> { val result = runTrying { - Transaction.correctlySpends(commitments.latest.localCommit.publishableTxs.commitTx.tx, listOf(cmd.watch.tx), ScriptFlags.STANDARD_SCRIPT_VERIFY_FLAGS) + commitments.latest.localCommit.publishableTxs.commitTx.tx.correctlySpends(listOf(cmd.watch.tx), ScriptFlags.STANDARD_SCRIPT_VERIFY_FLAGS) } if (result is Try.Failure) { logger.error { "funding tx verification failed: ${result.error}" } diff --git a/src/commonMain/kotlin/fr/acinq/lightning/crypto/KeyManager.kt b/src/commonMain/kotlin/fr/acinq/lightning/crypto/KeyManager.kt index 6ffe4847e..0a1767f8d 100644 --- a/src/commonMain/kotlin/fr/acinq/lightning/crypto/KeyManager.kt +++ b/src/commonMain/kotlin/fr/acinq/lightning/crypto/KeyManager.kt @@ -75,18 +75,17 @@ interface KeyManager { private val master: DeterministicWallet.ExtendedPrivateKey, val account: Long ) { - private val xpriv = DeterministicWallet.derivePrivateKey(master, bip84BasePath(chain) / hardened(account)) + private val xpriv = master.derivePrivateKey(bip84BasePath(chain) / hardened(account)) - val xpub: String = DeterministicWallet.encode( - input = DeterministicWallet.publicKey(xpriv), + val xpub: String = xpriv.extendedPublicKey.encode( prefix = when (chain) { - Chain.Testnet, Chain.Regtest, Chain.Signet -> DeterministicWallet.vpub + Chain.Testnet4, Chain.Testnet3, Chain.Regtest, Chain.Signet -> DeterministicWallet.vpub Chain.Mainnet -> DeterministicWallet.zpub } ) fun privateKey(addressIndex: Long): PrivateKey { - return DeterministicWallet.derivePrivateKey(xpriv, KeyPath.empty / 0 / addressIndex).privateKey + return xpriv.derivePrivateKey(KeyPath.empty / 0 / addressIndex).privateKey } fun pubkeyScript(addressIndex: Long): ByteVector { @@ -102,7 +101,7 @@ interface KeyManager { companion object { fun bip84BasePath(chain: Chain) = when (chain) { - Chain.Regtest, Chain.Testnet, Chain.Signet -> KeyPath.empty / hardened(84) / hardened(1) + Chain.Testnet4, Chain.Testnet3, Chain.Regtest, Chain.Signet -> KeyPath.empty / hardened(84) / hardened(1) Chain.Mainnet -> KeyPath.empty / hardened(84) / hardened(0) } } @@ -121,18 +120,18 @@ interface KeyManager { val remoteServerPublicKey: PublicKey, val refundDelay: Int = DefaultSwapInParams.RefundDelay ) { - private val userExtendedPrivateKey: DeterministicWallet.ExtendedPrivateKey = DeterministicWallet.derivePrivateKey(master, swapInUserKeyPath(chain)) - private val userRefundExtendedPrivateKey: DeterministicWallet.ExtendedPrivateKey = DeterministicWallet.derivePrivateKey(master, swapInUserRefundKeyPath(chain)) + private val userExtendedPrivateKey: DeterministicWallet.ExtendedPrivateKey = master.derivePrivateKey(swapInUserKeyPath(chain)) + private val userRefundExtendedPrivateKey: DeterministicWallet.ExtendedPrivateKey = master.derivePrivateKey(swapInUserRefundKeyPath(chain)) val userPrivateKey: PrivateKey = userExtendedPrivateKey.privateKey val userPublicKey: PublicKey = userPrivateKey.publicKey() - private val localServerExtendedPrivateKey: DeterministicWallet.ExtendedPrivateKey = DeterministicWallet.derivePrivateKey(master, swapInLocalServerKeyPath(chain)) - fun localServerPrivateKey(remoteNodeId: PublicKey): PrivateKey = DeterministicWallet.derivePrivateKey(localServerExtendedPrivateKey, perUserPath(remoteNodeId)).privateKey + private val localServerExtendedPrivateKey: DeterministicWallet.ExtendedPrivateKey = master.derivePrivateKey(swapInLocalServerKeyPath(chain)) + fun localServerPrivateKey(remoteNodeId: PublicKey): PrivateKey = localServerExtendedPrivateKey.derivePrivateKey(perUserPath(remoteNodeId)).privateKey // legacy p2wsh-based swap-in protocol, with a fixed on-chain address val legacySwapInProtocol = SwapInProtocolLegacy(userPublicKey, remoteServerPublicKey, refundDelay) - val legacyDescriptor = SwapInProtocolLegacy.descriptor(chain, DeterministicWallet.publicKey(master), DeterministicWallet.publicKey(userExtendedPrivateKey), remoteServerPublicKey, refundDelay) + val legacyDescriptor = SwapInProtocolLegacy.descriptor(chain, master.extendedPublicKey, userExtendedPrivateKey.extendedPublicKey, remoteServerPublicKey, refundDelay) fun signSwapInputUserLegacy(fundingTx: Transaction, index: Int, parentTxOuts: List): ByteVector64 { return legacySwapInProtocol.signSwapInputUser(fundingTx, index, parentTxOuts[fundingTx.txIn[index].outPoint.index.toInt()], userPrivateKey) @@ -152,7 +151,7 @@ interface KeyManager { * @return the swap-in protocol that matches the input public key script */ fun getSwapInProtocol(addressIndex: Int): SwapInProtocol { - val userRefundPrivateKey: PrivateKey = DeterministicWallet.derivePrivateKey(userRefundExtendedPrivateKey, addressIndex.toLong()).privateKey + val userRefundPrivateKey: PrivateKey = userRefundExtendedPrivateKey.derivePrivateKey(addressIndex.toLong()).privateKey val userRefundPublicKey: PublicKey = userRefundPrivateKey.publicKey() return SwapInProtocol(userPublicKey, remoteServerPublicKey, userRefundPublicKey, refundDelay) } @@ -189,7 +188,7 @@ interface KeyManager { tx.updateWitness(inputIndex, legacySwapInProtocol.witnessRefund(sig)) } else -> { - val userRefundPrivateKey: PrivateKey = DeterministicWallet.derivePrivateKey(userRefundExtendedPrivateKey, addressIndex.toLong()).privateKey + val userRefundPrivateKey: PrivateKey = userRefundExtendedPrivateKey.derivePrivateKey(addressIndex.toLong()).privateKey val swapInProtocol = getSwapInProtocol(addressIndex) val sig = swapInProtocol.signSwapInputRefund(tx, inputIndex, utxos.map { it.txOut }, userRefundPrivateKey) tx.updateWitness(inputIndex, swapInProtocol.witnessRefund(sig)) @@ -237,7 +236,7 @@ interface KeyManager { companion object { private fun swapInKeyBasePath(chain: Chain) = when (chain) { - Chain.Regtest, Chain.Testnet, Chain.Signet -> KeyPath.empty / hardened(51) / hardened(0) + Chain.Testnet4, Chain.Testnet3, Chain.Regtest, Chain.Signet -> KeyPath.empty / hardened(51) / hardened(0) Chain.Mainnet -> KeyPath.empty / hardened(52) / hardened(0) } @@ -248,7 +247,7 @@ interface KeyManager { fun swapInUserRefundKeyPath(chain: Chain) = swapInKeyBasePath(chain) / hardened(2) / 0L fun encodedSwapInUserKeyPath(chain: Chain) = when (chain) { - Chain.Regtest, Chain.Testnet, Chain.Signet -> "51h/0h/0h" + Chain.Testnet4, Chain.Testnet3, Chain.Regtest, Chain.Signet -> "51h/0h/0h" Chain.Mainnet -> "52h/0h/0h" } diff --git a/src/commonMain/kotlin/fr/acinq/lightning/crypto/LocalKeyManager.kt b/src/commonMain/kotlin/fr/acinq/lightning/crypto/LocalKeyManager.kt index 989a9c8e4..4d627303e 100644 --- a/src/commonMain/kotlin/fr/acinq/lightning/crypto/LocalKeyManager.kt +++ b/src/commonMain/kotlin/fr/acinq/lightning/crypto/LocalKeyManager.kt @@ -1,7 +1,6 @@ package fr.acinq.lightning.crypto import fr.acinq.bitcoin.* -import fr.acinq.bitcoin.DeterministicWallet.derivePrivateKey import fr.acinq.bitcoin.DeterministicWallet.hardened import fr.acinq.bitcoin.crypto.Pack import fr.acinq.lightning.Lightning.secureRandom @@ -38,8 +37,8 @@ data class LocalKeyManager(val seed: ByteVector, val chain: Chain, val remoteSwa private val master = DeterministicWallet.generate(seed) override val nodeKeys: KeyManager.NodeKeys = KeyManager.NodeKeys( - legacyNodeKey = @Suppress("DEPRECATION") derivePrivateKey(master, eclairNodeKeyBasePath(chain)), - nodeKey = derivePrivateKey(master, nodeKeyBasePath(chain)), + legacyNodeKey = @Suppress("DEPRECATION") master.derivePrivateKey(eclairNodeKeyBasePath(chain)), + nodeKey = master.derivePrivateKey(nodeKeyBasePath(chain)), ) override val finalOnChainWallet: KeyManager.Bip84OnChainKeys = KeyManager.Bip84OnChainKeys(chain, master, account = 0) @@ -50,7 +49,7 @@ data class LocalKeyManager(val seed: ByteVector, val chain: Chain, val remoteSwa else -> DeterministicWallet.tpub } require(prefix == expectedPrefix) { "unexpected swap-in xpub prefix $prefix (expected $expectedPrefix)" } - val remoteSwapInPublicKey = DeterministicWallet.derivePublicKey(xpub, KeyManager.SwapInOnChainKeys.perUserPath(nodeKeys.nodeKey.publicKey)).publicKey + val remoteSwapInPublicKey = xpub.derivePublicKey(KeyManager.SwapInOnChainKeys.perUserPath(nodeKeys.nodeKey.publicKey)).publicKey KeyManager.SwapInOnChainKeys(chain, master, remoteSwapInPublicKey) } @@ -60,9 +59,9 @@ data class LocalKeyManager(val seed: ByteVector, val chain: Chain, val remoteSwa * This method offers direct access to the master key derivation. It should only be used for some advanced usage * like (LNURL-auth, data encryption). */ - fun derivePrivateKey(keyPath: KeyPath): DeterministicWallet.ExtendedPrivateKey = derivePrivateKey(master, keyPath) + fun derivePrivateKey(keyPath: KeyPath): DeterministicWallet.ExtendedPrivateKey = master.derivePrivateKey(keyPath) - fun privateKey(keyPath: KeyPath): PrivateKey = derivePrivateKey(master, keyPath).privateKey + fun privateKey(keyPath: KeyPath): PrivateKey = master.derivePrivateKey(keyPath).privateKey override fun newFundingKeyPath(isInitiator: Boolean): KeyPath { val last = hardened(if (isInitiator) 1 else 0) @@ -72,7 +71,7 @@ data class LocalKeyManager(val seed: ByteVector, val chain: Chain, val remoteSwa override fun channelKeys(fundingKeyPath: KeyPath): KeyManager.ChannelKeys { // We use a different funding key for each splice, with a derivation based on the fundingTxIndex. - val fundingKey: (Long) -> PrivateKey = { index -> derivePrivateKey(master, channelKeyBasePath / fundingKeyPath / hardened(index)).privateKey } + val fundingKey: (Long) -> PrivateKey = { index -> master.derivePrivateKey(channelKeyBasePath / fundingKeyPath / hardened(index)).privateKey } // We use the initial funding pubkey to compute the channel key path, and we use the recovery process even // in the normal case, which guarantees it works all the time. val initialFundingPubkey = fundingKey(0).publicKey() @@ -150,19 +149,19 @@ data class LocalKeyManager(val seed: ByteVector, val chain: Chain, val remoteSwa } fun channelKeyBasePath(chain: Chain) = when (chain) { - Chain.Regtest, Chain.Testnet, Chain.Signet -> KeyPath.empty / hardened(48) / hardened(1) + Chain.Testnet4, Chain.Testnet3, Chain.Regtest, Chain.Signet -> KeyPath.empty / hardened(48) / hardened(1) Chain.Mainnet -> KeyPath.empty / hardened(50) / hardened(1) } /** Path for node keys generated by eclair-core */ @Deprecated("used for backward-compat with eclair-core", replaceWith = ReplaceWith("nodeKeyBasePath(chain)")) fun eclairNodeKeyBasePath(chain: Chain) = when (chain) { - Chain.Regtest, Chain.Testnet, Chain.Signet -> KeyPath.empty / hardened(46) / hardened(0) + Chain.Testnet4, Chain.Testnet3, Chain.Regtest, Chain.Signet -> KeyPath.empty / hardened(46) / hardened(0) Chain.Mainnet -> KeyPath.empty / hardened(47) / hardened(0) } fun nodeKeyBasePath(chain: Chain) = when (chain) { - Chain.Regtest, Chain.Testnet, Chain.Signet -> KeyPath.empty / hardened(48) / hardened(0) + Chain.Testnet4, Chain.Testnet3, Chain.Regtest, Chain.Signet -> KeyPath.empty / hardened(48) / hardened(0) Chain.Mainnet -> KeyPath.empty / hardened(50) / hardened(0) } } diff --git a/src/commonMain/kotlin/fr/acinq/lightning/json/JsonSerializers.kt b/src/commonMain/kotlin/fr/acinq/lightning/json/JsonSerializers.kt index d4b963a5e..21ac144a0 100644 --- a/src/commonMain/kotlin/fr/acinq/lightning/json/JsonSerializers.kt +++ b/src/commonMain/kotlin/fr/acinq/lightning/json/JsonSerializers.kt @@ -673,7 +673,8 @@ object JsonSerializers { chain = when { o.chains.isEmpty() -> Chain.Mainnet.name o.chains.contains(Chain.Mainnet.chainHash) && o.chains.size == 1 -> Chain.Mainnet.name - o.chains.contains(Chain.Testnet.chainHash) && o.chains.size == 1 -> Chain.Testnet.name + o.chains.contains(Chain.Testnet3.chainHash) && o.chains.size == 1 -> Chain.Testnet3.name + o.chains.contains(Chain.Testnet4.chainHash) && o.chains.size == 1 -> Chain.Testnet4.name o.chains.contains(Chain.Regtest.chainHash) && o.chains.size == 1 -> Chain.Regtest.name else -> "unknown" }.lowercase(), diff --git a/src/commonMain/kotlin/fr/acinq/lightning/payment/Bolt11Invoice.kt b/src/commonMain/kotlin/fr/acinq/lightning/payment/Bolt11Invoice.kt index 413bb5080..b0cebd6ee 100644 --- a/src/commonMain/kotlin/fr/acinq/lightning/payment/Bolt11Invoice.kt +++ b/src/commonMain/kotlin/fr/acinq/lightning/payment/Bolt11Invoice.kt @@ -110,7 +110,8 @@ data class Bolt11Invoice( private val prefixes = mapOf( Chain.Regtest to "lnbcrt", - Chain.Testnet to "lntb", + Chain.Testnet3 to "lntb", + Chain.Testnet4 to "lntb", Chain.Mainnet to "lnbc" ) diff --git a/src/commonMain/kotlin/fr/acinq/lightning/transactions/SwapInProtocol.kt b/src/commonMain/kotlin/fr/acinq/lightning/transactions/SwapInProtocol.kt index 64175a7ea..3fc751630 100644 --- a/src/commonMain/kotlin/fr/acinq/lightning/transactions/SwapInProtocol.kt +++ b/src/commonMain/kotlin/fr/acinq/lightning/transactions/SwapInProtocol.kt @@ -20,7 +20,7 @@ data class SwapInProtocol(val userPublicKey: PublicKey, val serverPublicKey: Pub // The script path contains a refund script, generated from this policy: and_v(v:pk(user),older(refundDelay)). // It does not depend upon the user's or server's key, just the user's refund key and the refund delay. private val refundScript = listOf(OP_PUSHDATA(userRefundKey.xOnly()), OP_CHECKSIGVERIFY, OP_PUSHDATA(Script.encodeNumber(refundDelay)), OP_CHECKSEQUENCEVERIFY) - private val scriptTree = ScriptTree.Leaf(0, refundScript) + private val scriptTree = ScriptTree.Leaf(refundScript) val pubkeyScript: List = Script.pay2tr(internalPublicKey, scriptTree) val serializedPubkeyScript = Script.write(pubkeyScript).byteVector() @@ -46,7 +46,7 @@ data class SwapInProtocol(val userPublicKey: PublicKey, val serverPublicKey: Pub fun signSwapInputRefund(fundingTx: Transaction, index: Int, parentTxOuts: List, userPrivateKey: PrivateKey): ByteVector64 { require(userPrivateKey.publicKey() == userRefundKey) { "refund private key does not match expected public key: are you using the user key instead of the refund key?" } - return Transaction.signInputTaprootScriptPath(userPrivateKey, fundingTx, index, parentTxOuts, SigHash.SIGHASH_DEFAULT, scriptTree.hash()) + return fundingTx.signInputTaprootScriptPath(userPrivateKey, index, parentTxOuts, SigHash.SIGHASH_DEFAULT, scriptTree.hash()) } fun signSwapInputServer(fundingTx: Transaction, index: Int, parentTxOuts: List, serverPrivateKey: PrivateKey, privateNonce: SecretNonce, userNonce: IndividualNonce, serverNonce: IndividualNonce): Either { @@ -62,7 +62,7 @@ data class SwapInProtocol(val userPublicKey: PublicKey, val serverPublicKey: Pub Chain.Mainnet -> DeterministicWallet.xprv else -> DeterministicWallet.tprv } - val xpriv = DeterministicWallet.encode(masterRefundKey, prefix) + val xpriv = masterRefundKey.encode(prefix) val desc = "tr(${internalPubKey.value},and_v(v:pk($xpriv/*),older($refundDelay)))" val checksum = Descriptor.checksum(desc) return "$desc#$checksum" @@ -74,7 +74,7 @@ data class SwapInProtocol(val userPublicKey: PublicKey, val serverPublicKey: Pub Chain.Mainnet -> DeterministicWallet.xpub else -> DeterministicWallet.tpub } - val xpub = DeterministicWallet.encode(masterRefundKey, prefix) + val xpub = masterRefundKey.encode(prefix) val desc = "tr(${internalPubKey.value},and_v(v:pk($xpub/*),older($refundDelay)))" val checksum = Descriptor.checksum(desc) return "$desc#$checksum" diff --git a/src/commonMain/kotlin/fr/acinq/lightning/transactions/Transactions.kt b/src/commonMain/kotlin/fr/acinq/lightning/transactions/Transactions.kt index b826695a4..cce8aa158 100644 --- a/src/commonMain/kotlin/fr/acinq/lightning/transactions/Transactions.kt +++ b/src/commonMain/kotlin/fr/acinq/lightning/transactions/Transactions.kt @@ -801,7 +801,7 @@ object Transactions { .also { check(Scripts.der(it, SigHash.SIGHASH_ALL).size() == 72) { "Should be 72 bytes but is ${Scripts.der(it, SigHash.SIGHASH_ALL).size()} bytes" } } fun sign(tx: Transaction, inputIndex: Int, redeemScript: ByteArray, amount: Satoshi, key: PrivateKey, sigHash: Int = SigHash.SIGHASH_ALL): ByteVector64 { - val sigDER = Transaction.signInput(tx, inputIndex, redeemScript, sigHash, amount, SigVersion.SIGVERSION_WITNESS_V0, key) + val sigDER = tx.signInput(inputIndex, redeemScript, sigHash, amount, SigVersion.SIGVERSION_WITNESS_V0, key) return Crypto.der2compact(sigDER) } @@ -873,11 +873,11 @@ object Transactions { } fun checkSpendable(txinfo: TransactionWithInputInfo): Try = runTrying { - Transaction.correctlySpends(txinfo.tx, mapOf(txinfo.tx.txIn.first().outPoint to txinfo.input.txOut), ScriptFlags.STANDARD_SCRIPT_VERIFY_FLAGS) + txinfo.tx.correctlySpends(mapOf(txinfo.tx.txIn.first().outPoint to txinfo.input.txOut), ScriptFlags.STANDARD_SCRIPT_VERIFY_FLAGS) } fun checkSig(txinfo: TransactionWithInputInfo, sig: ByteVector64, pubKey: PublicKey, sigHash: Int = SigHash.SIGHASH_ALL): Boolean { - val data = Transaction.hashForSigning(txinfo.tx, 0, txinfo.input.redeemScript.toByteArray(), sigHash, txinfo.input.txOut.amount, SigVersion.SIGVERSION_WITNESS_V0) + val data = txinfo.tx.hashForSigning(0, txinfo.input.redeemScript.toByteArray(), sigHash, txinfo.input.txOut.amount, SigVersion.SIGVERSION_WITNESS_V0) return Crypto.verifySignature(data, sig, pubKey) } } diff --git a/src/commonTest/kotlin/fr/acinq/lightning/blockchain/electrum/SwapInWalletTestsCommon.kt b/src/commonTest/kotlin/fr/acinq/lightning/blockchain/electrum/SwapInWalletTestsCommon.kt index 5fabac943..e173de91f 100644 --- a/src/commonTest/kotlin/fr/acinq/lightning/blockchain/electrum/SwapInWalletTestsCommon.kt +++ b/src/commonTest/kotlin/fr/acinq/lightning/blockchain/electrum/SwapInWalletTestsCommon.kt @@ -18,9 +18,9 @@ class SwapInWalletTestsCommon : LightningTestSuite() { @Test fun `swap-in wallet test`() = runSuspendTest(timeout = 15.seconds) { val mnemonics = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".split(" ") - val keyManager = LocalKeyManager(MnemonicCode.toSeed(mnemonics, "").toByteVector(), Chain.Testnet, TestConstants.aliceSwapInServerXpub) + val keyManager = LocalKeyManager(MnemonicCode.toSeed(mnemonics, "").toByteVector(), Chain.Testnet3, TestConstants.aliceSwapInServerXpub) val client = connectToTestnetServer() - val wallet = SwapInWallet(Chain.Testnet, keyManager.swapInOnChainWallet, client, this, loggerFactory) + val wallet = SwapInWallet(Chain.Testnet3, keyManager.swapInOnChainWallet, client, this, loggerFactory) // addresses 0 to 3 have funds on them, the current address is the 4th assertEquals(4, wallet.swapInAddressFlow.filterNotNull().first().second) diff --git a/src/commonTest/kotlin/fr/acinq/lightning/channel/HelpersTestsCommon.kt b/src/commonTest/kotlin/fr/acinq/lightning/channel/HelpersTestsCommon.kt index 1ebc2f2e1..dae11c3c3 100644 --- a/src/commonTest/kotlin/fr/acinq/lightning/channel/HelpersTestsCommon.kt +++ b/src/commonTest/kotlin/fr/acinq/lightning/channel/HelpersTestsCommon.kt @@ -23,7 +23,7 @@ class HelpersTestsCommon : LightningTestSuite() { fun address(script: List, chainHash: BlockHash) = Bitcoin.addressFromPublicKeyScript(chainHash, Script.write(script)).right - listOf(Block.LivenetGenesisBlock.hash, Block.TestnetGenesisBlock.hash, Block.RegtestGenesisBlock.hash).forEach { + listOf(Block.LivenetGenesisBlock.hash, Block.Testnet3GenesisBlock.hash, Block.RegtestGenesisBlock.hash).forEach { assertEquals(address(Script.pay2pkh(pub), it), computeP2PkhAddress(pub, it)) assertEquals(address(Script.pay2wpkh(pub), it), computeP2WpkhAddress(pub, it)) assertEquals(address(Script.pay2sh(Script.pay2wpkh(pub)), it), computeP2ShOfP2WpkhAddress(pub, it)) @@ -34,10 +34,10 @@ class HelpersTestsCommon : LightningTestSuite() { } listOf( - Triple("0014d0b19277b0f76c9512f26d77573fd31a8fd15fc7", Block.TestnetGenesisBlock.hash, "tb1q6zceyaas7akf2yhjd4m4w07nr28azh78gw79kk"), - Triple("00203287047df2aa7aade3f394790a9c9d6f9235943f48a012e8a9f2c3300ca4f2d1", Block.TestnetGenesisBlock.hash, "tb1qx2rsgl0j4fa2mclnj3us48yad7frt9plfzsp969f7tpnqr9y7tgsyprxej"), - Triple("76a914b17deefe2feab87fef7221cf806bb8ca61f00fa188ac", Block.TestnetGenesisBlock.hash, "mwhSm2SHhRhd19KZyaQLgJyAtCLnkbzWbf"), - Triple("a914d3cf9d04f4ecc36df8207b300e46bc6775fc84c087", Block.TestnetGenesisBlock.hash, "2NCZBGzKadAnLv1ijAqhrKavMuqvxqu18yY"), + Triple("0014d0b19277b0f76c9512f26d77573fd31a8fd15fc7", Block.Testnet3GenesisBlock.hash, "tb1q6zceyaas7akf2yhjd4m4w07nr28azh78gw79kk"), + Triple("00203287047df2aa7aade3f394790a9c9d6f9235943f48a012e8a9f2c3300ca4f2d1", Block.Testnet3GenesisBlock.hash, "tb1qx2rsgl0j4fa2mclnj3us48yad7frt9plfzsp969f7tpnqr9y7tgsyprxej"), + Triple("76a914b17deefe2feab87fef7221cf806bb8ca61f00fa188ac", Block.Testnet3GenesisBlock.hash, "mwhSm2SHhRhd19KZyaQLgJyAtCLnkbzWbf"), + Triple("a914d3cf9d04f4ecc36df8207b300e46bc6775fc84c087", Block.Testnet3GenesisBlock.hash, "2NCZBGzKadAnLv1ijAqhrKavMuqvxqu18yY"), Triple("00145cb882efd643b7d63ae133e4d5e88e10bd5a20d7", Block.LivenetGenesisBlock.hash, "bc1qtjug9m7kgwmavwhpx0jdt6ywzz745gxhxwyn8u"), Triple("00208c2865c87ffd33fc5d698c7df9cf2d0fb39d93103c637a06dea32c848ebc3e1d", Block.LivenetGenesisBlock.hash, "bc1q3s5xtjrll5elchtf337lnnedp7eemycs833h5pk75vkgfr4u8cws3ytg02"), Triple("76a914536ffa992491508dca0354e52f32a3a7a679a53a88ac", Block.LivenetGenesisBlock.hash, "18cBEMRxXHqzWWCxZNtU91F5sbUNKhL5PX"), diff --git a/src/commonTest/kotlin/fr/acinq/lightning/crypto/LocalKeyManagerTestsCommon.kt b/src/commonTest/kotlin/fr/acinq/lightning/crypto/LocalKeyManagerTestsCommon.kt index 1d245a177..0af52f8cd 100644 --- a/src/commonTest/kotlin/fr/acinq/lightning/crypto/LocalKeyManagerTestsCommon.kt +++ b/src/commonTest/kotlin/fr/acinq/lightning/crypto/LocalKeyManagerTestsCommon.kt @@ -167,7 +167,7 @@ class LocalKeyManagerTestsCommon : LightningTestSuite() { // reference data was generated from electrum 4.1.5 val mnemonics = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".split(" ") val seed = MnemonicCode.toSeed(mnemonics, "").toByteVector() - val keyManager = LocalKeyManager(seed, Chain.Testnet, TestConstants.aliceSwapInServerXpub) + val keyManager = LocalKeyManager(seed, Chain.Testnet3, TestConstants.aliceSwapInServerXpub) assertEquals(keyManager.finalOnChainWallet.privateKey(addressIndex = 0L).toBase58(Base58.Prefix.SecretKeyTestnet), "cTGhosGriPpuGA586jemcuH9pE9spwUmneMBmYYzrQEbY92DJrbo") assertEquals(keyManager.finalOnChainWallet.privateKey(addressIndex = 1L).toBase58(Base58.Prefix.SecretKeyTestnet), "cQFUndrpAyMaE3HAsjMCXiT94MzfsABCREat1x7Qe3Mtq9KihD4V") assertEquals(keyManager.finalOnChainWallet.xpub, "vpub5Y6cjg78GGuNLsaPhmYsiw4gYX3HoQiRBiSwDaBXKUafCt9bNwWQiitDk5VZ5BVxYnQdwoTyXSs2JHRPAgjAvtbBrf8ZhDYe2jWAqvZVnsc") @@ -218,7 +218,7 @@ class LocalKeyManagerTestsCommon : LightningTestSuite() { val chain = Chain.Regtest val userPublicKey = PrivateKey.fromHex("0101010101010101010101010101010101010101010101010101010101010101").publicKey() val remoteServerPublicKey = PrivateKey.fromHex("0202020202020202020202020202020202020202020202020202020202020202").publicKey() - val userRefundExtendedPrivateKey = DeterministicWallet.derivePrivateKey(master, KeyManager.SwapInOnChainKeys.swapInUserRefundKeyPath(chain)) + val userRefundExtendedPrivateKey = master.derivePrivateKey(KeyManager.SwapInOnChainKeys.swapInUserRefundKeyPath(chain)) val refundDelay = 2590 assertEquals( "tr(1fc559d9c96c5953895d3150e64ebf3dd696a0b08e758650b48ff6251d7e60d1,and_v(v:pk(tprv8hWm2EfcAbMerYoXeHA9w6faUqXdiQeWfSxxWpzh3Yc1FAjB2vv1sbBNY1dX3HraotvBAEeY2hzz1X4vc3SC516K1ebBvLYrkA6LstQdbNX/*),older(2590)))#90ftphf9", @@ -226,11 +226,11 @@ class LocalKeyManagerTestsCommon : LightningTestSuite() { ) assertEquals( "tr(1fc559d9c96c5953895d3150e64ebf3dd696a0b08e758650b48ff6251d7e60d1,and_v(v:pk(tpubDECoAehrJy3Kk1qKXvpkLWKh3s3ZsjqREkZjoM2zTpQQ5eywfKjc45oEi8GMq1mpWxM2kg79Lp5DzznQKGRE15btY327vgLcLbfZLrgAWrv/*),older(2590)))#xmhrglc6", - SwapInProtocol.publicDescriptor(chain, userPublicKey, remoteServerPublicKey, refundDelay, DeterministicWallet.publicKey(userRefundExtendedPrivateKey)) + SwapInProtocol.publicDescriptor(chain, userPublicKey, remoteServerPublicKey, refundDelay, userRefundExtendedPrivateKey.extendedPublicKey) ) } companion object { - val dummyExtendedPubkey = DeterministicWallet.publicKey(DeterministicWallet.generate(ByteVector("deadbeef"))) + val dummyExtendedPubkey = DeterministicWallet.generate(ByteVector("deadbeef")).extendedPublicKey } } diff --git a/src/commonTest/kotlin/fr/acinq/lightning/payment/Bolt12InvoiceTestsCommon.kt b/src/commonTest/kotlin/fr/acinq/lightning/payment/Bolt12InvoiceTestsCommon.kt index 5e059d3fa..598f1b9e8 100644 --- a/src/commonTest/kotlin/fr/acinq/lightning/payment/Bolt12InvoiceTestsCommon.kt +++ b/src/commonTest/kotlin/fr/acinq/lightning/payment/Bolt12InvoiceTestsCommon.kt @@ -333,7 +333,7 @@ class Bolt12InvoiceTestsCommon : LightningTestSuite() { @Test fun `encode decode invoice with many fields`() { - val chain = Block.TestnetGenesisBlock.hash + val chain = Block.Testnet3GenesisBlock.hash val amount = 123456.msat val description = "invoice with many fields" val features = Features.empty @@ -484,7 +484,7 @@ class Bolt12InvoiceTestsCommon : LightningTestSuite() { val preimage = ByteVector32.fromValidHex("99221825b86576e94391b179902be8b22c7cfa7c3d14aec6ae86657dfd9bd2a8") val offer = Offer( TlvStream( - OfferChains(listOf(Block.TestnetGenesisBlock.hash)), + OfferChains(listOf(Block.Testnet3GenesisBlock.hash)), OfferAmount(100000.msat), OfferDescription("offer with quantity"), OfferIssuer("alice@bigshop.com"), @@ -495,7 +495,7 @@ class Bolt12InvoiceTestsCommon : LightningTestSuite() { val encodedOffer = "lno1qgsyxjtl6luzd9t3pr62xr7eemp6awnejusgf6gw45q75vcfqqqqqqqgqvqcdgq2zdhkven9wgs8w6t5dqs8zatpde6xjarezggkzmrfvdj5qcnfvaeksmms9e3k7mg5qgp7s93pqvn6l4vemgezdarq3wt2kpp0u4vt74vzz8futen7ej97n93jypp57" assertEquals(offer.toString(), encodedOffer) assertEquals(Offer.decode(encodedOffer).get(), offer) - val request = InvoiceRequest(offer, 7200000.msat, 72, Features.empty, payerKey, null, Block.TestnetGenesisBlock.hash) + val request = InvoiceRequest(offer, 7200000.msat, 72, Features.empty, payerKey, null, Block.Testnet3GenesisBlock.hash) // Invoice request generation is not reproducible because we add randomness in the first TLV. val encodedRequest = "lnr1qqs8lqvnh3kg9uj003lxlxyj8hthymgq4p9ms0ag0ryx5uw8gsuus4gzypp5jl7hlqnf2ugg7j3slkwwcwht57vhyzzwjr4dq84rxzgqqqqqqzqrqxr2qzsndanxvetjypmkjargypch2ctww35hg7gjz9skc6trv4qxy6t8wd5x7upwvdhk69qzq05pvggry7hatxw6xgn0gcytj64sgtl9tzl4tqs360z7vlkv305evv3qgd84qgzrf9la07pxj4cs3a9rplvuasawhfuewgyyay826q02xvysqqqqqpfqxmwaqptqzjzcyyp8cmgrl28nvm3wlqqheha0t570rgaszg7mzvvzvwmx9s92nmyujk0sgpef8dt57nygu3dnfhglymt6mnle6j8s28rler8wv3zygen07v4ddfplc9qs7nkdzwcelm2rs552slkpv45xxng65ne6y4dlq2764gqv" val decodedRequest = InvoiceRequest.decode(encodedRequest).get() diff --git a/src/commonTest/kotlin/fr/acinq/lightning/tests/bitcoind/BitcoindService.kt b/src/commonTest/kotlin/fr/acinq/lightning/tests/bitcoind/BitcoindService.kt index fa0596d4d..8f9a2fcd2 100644 --- a/src/commonTest/kotlin/fr/acinq/lightning/tests/bitcoind/BitcoindService.kt +++ b/src/commonTest/kotlin/fr/acinq/lightning/tests/bitcoind/BitcoindService.kt @@ -88,17 +88,16 @@ object BitcoindService { lockTime = 0 ) - val sig = Transaction.signInput( - tmp, + val sig = tmp.signInput( 0, Script.pay2pkh(publicKey), - SigHash.SIGHASH_ALL, + SIGHASH_ALL, tx.txOut[outputIndex].amount, SigVersion.SIGVERSION_WITNESS_V0, privateKey ).byteVector() val signedTx = tmp.updateWitness(0, ScriptWitness(listOf(sig, publicKey.value))) - Transaction.correctlySpends(signedTx, listOf(tx), ScriptFlags.STANDARD_SCRIPT_VERIFY_FLAGS) + signedTx.correctlySpends(listOf(tx), ScriptFlags.STANDARD_SCRIPT_VERIFY_FLAGS) signedTx } @@ -111,17 +110,16 @@ object BitcoindService { lockTime = 0 ) - val sig = Transaction.signInput( - tmp, + val sig = tmp.signInput( 0, Script.pay2pkh(publicKey), - SigHash.SIGHASH_ALL, + SIGHASH_ALL, tx1.txOut.first().amount, SigVersion.SIGVERSION_WITNESS_V0, privateKey ).byteVector() val signedTx = tmp.updateWitness(0, ScriptWitness(listOf(sig, publicKey.value))) - Transaction.correctlySpends(signedTx, listOf(tx1), ScriptFlags.STANDARD_SCRIPT_VERIFY_FLAGS) + signedTx.correctlySpends(listOf(tx1), ScriptFlags.STANDARD_SCRIPT_VERIFY_FLAGS) signedTx } @@ -151,17 +149,16 @@ object BitcoindService { lockTime = 200 ) - val sig = Transaction.signInput( - tmp, + val sig = tmp.signInput( 0, Script.pay2pkh(publicKey), - SigHash.SIGHASH_ALL, + SIGHASH_ALL, tx.txOut[outputIndex].amount, SigVersion.SIGVERSION_WITNESS_V0, privateKey ).byteVector() val signedTx = tmp.updateWitness(0, ScriptWitness(listOf(sig, publicKey.value))) - Transaction.correctlySpends(signedTx, listOf(tx), ScriptFlags.STANDARD_SCRIPT_VERIFY_FLAGS) + signedTx.correctlySpends(listOf(tx), ScriptFlags.STANDARD_SCRIPT_VERIFY_FLAGS) signedTx } @@ -180,17 +177,16 @@ object BitcoindService { lockTime = 175 ) - val sig = Transaction.signInput( - tmp, + val sig = tmp.signInput( 0, Script.pay2pkh(publicKey), - SigHash.SIGHASH_ALL, + SIGHASH_ALL, tx1.txOut.first().amount, SigVersion.SIGVERSION_WITNESS_V0, privateKey ).byteVector() val signedTx = tmp.updateWitness(0, ScriptWitness(listOf(sig, publicKey.value))) - Transaction.correctlySpends(signedTx, listOf(tx1), ScriptFlags.STANDARD_SCRIPT_VERIFY_FLAGS) + signedTx.correctlySpends(listOf(tx1), ScriptFlags.STANDARD_SCRIPT_VERIFY_FLAGS) signedTx } @@ -217,8 +213,7 @@ object BitcoindService { lockTime = lockTime ) - val sig = Transaction.signInput( - unsigned, + val sig = unsigned.signInput( 0, Script.pay2pkh(publicKey), SIGHASH_ALL, @@ -228,7 +223,7 @@ object BitcoindService { ).toByteVector() val signedTx = unsigned.updateWitness(0, ScriptWitness(listOf(sig, publicKey.value))) - Transaction.correctlySpends(signedTx, listOf(parentTx), ScriptFlags.STANDARD_SCRIPT_VERIFY_FLAGS) + signedTx.correctlySpends(listOf(parentTx), ScriptFlags.STANDARD_SCRIPT_VERIFY_FLAGS) return signedTx } } diff --git a/src/commonTest/kotlin/fr/acinq/lightning/wire/InitTlvTestsCommon.kt b/src/commonTest/kotlin/fr/acinq/lightning/wire/InitTlvTestsCommon.kt index 65969b79b..31628877e 100644 --- a/src/commonTest/kotlin/fr/acinq/lightning/wire/InitTlvTestsCommon.kt +++ b/src/commonTest/kotlin/fr/acinq/lightning/wire/InitTlvTestsCommon.kt @@ -12,7 +12,7 @@ import kotlin.test.assertTrue class InitTlvTestsCommon : LightningTestSuite() { @Test fun `legacy phoenix TLV`() { - val keyManager = LocalKeyManager(MnemonicCode.toSeed("sock able evoke work output half bamboo energy simple fiber unhappy afford", passphrase = "").byteVector(), Chain.Testnet, TestConstants.aliceSwapInServerXpub) + val keyManager = LocalKeyManager(MnemonicCode.toSeed("sock able evoke work output half bamboo energy simple fiber unhappy afford", passphrase = "").byteVector(), Chain.Testnet3, TestConstants.aliceSwapInServerXpub) val testCases = listOf( Pair( first = keyManager.nodeKeys.legacyNodeKey.publicKey, diff --git a/src/commonTest/kotlin/fr/acinq/lightning/wire/LightningCodecsTestsCommon.kt b/src/commonTest/kotlin/fr/acinq/lightning/wire/LightningCodecsTestsCommon.kt index 1c9706096..d869d0ba4 100644 --- a/src/commonTest/kotlin/fr/acinq/lightning/wire/LightningCodecsTestsCommon.kt +++ b/src/commonTest/kotlin/fr/acinq/lightning/wire/LightningCodecsTestsCommon.kt @@ -881,13 +881,13 @@ class LightningCodecsTestsCommon : LightningTestSuite() { val encoded = "lno1qgsyxjtl6luzd9t3pr62xr7eemp6awnejusgf6gw45q75vcfqqqqqqqgqyeq5ym0venx2u3qwa5hg6pqw96kzmn5d968jys3v9kxjcm9gp3xjemndphhqtnrdak3gqqkyypsmuhrtwfzm85mht4a3vcp0yrlgua3u3m5uqpc6kf7nqjz6v70qwg" val offer = Offer.decode(encoded).get() - val msg = DNSAddressRequest(Chain.Testnet.chainHash, offer, "en") + val msg = DNSAddressRequest(Chain.Testnet3.chainHash, offer, "en") assertEquals(msg, LightningMessage.decode(LightningMessage.encode(msg))) } @Test fun `encode and decode dns address response`() { - val msg = DNSAddressResponse(Chain.Testnet.chainHash, "foo@bar.baz") + val msg = DNSAddressResponse(Chain.Testnet3.chainHash, "foo@bar.baz") assertEquals(msg, LightningMessage.decode(LightningMessage.encode(msg))) } } \ No newline at end of file diff --git a/src/commonTest/kotlin/fr/acinq/lightning/wire/OfferTypesTestsCommon.kt b/src/commonTest/kotlin/fr/acinq/lightning/wire/OfferTypesTestsCommon.kt index b92dba500..2580ddeef 100644 --- a/src/commonTest/kotlin/fr/acinq/lightning/wire/OfferTypesTestsCommon.kt +++ b/src/commonTest/kotlin/fr/acinq/lightning/wire/OfferTypesTestsCommon.kt @@ -69,7 +69,7 @@ class OfferTypesTestsCommon : LightningTestSuite() { fun `offer with amount and quantity`() { val offer = Offer( TlvStream( - OfferChains(listOf(Block.TestnetGenesisBlock.hash)), + OfferChains(listOf(Block.Testnet3GenesisBlock.hash)), OfferAmount(50.msat), OfferDescription("offer with quantity"), OfferIssuer("alice@bigshop.com"), @@ -162,7 +162,7 @@ class OfferTypesTestsCommon : LightningTestSuite() { val withDefaultChain = signInvoiceRequest(request.copy(records = TlvStream(request.records.records + InvoiceRequestChain(Block.LivenetGenesisBlock.hash))), payerKey) assertTrue(withDefaultChain.isValid()) assertEquals(offer, withDefaultChain.offer) - val otherChain = signInvoiceRequest(request.copy(records = TlvStream(request.records.records + InvoiceRequestChain(Block.TestnetGenesisBlock.hash))), payerKey) + val otherChain = signInvoiceRequest(request.copy(records = TlvStream(request.records.records + InvoiceRequestChain(Block.Testnet3GenesisBlock.hash))), payerKey) assertFalse(otherChain.isValid()) }