Skip to content

Commit b6b3701

Browse files
committed
Tests: use kotlinx-io to read resource files
1 parent d633793 commit b6b3701

File tree

16 files changed

+101
-110
lines changed

16 files changed

+101
-110
lines changed

build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ kotlin {
5959
dependencies {
6060
implementation(kotlin("test-common"))
6161
implementation(kotlin("test-annotations-common"))
62-
implementation("org.kodein.memory:klio-files:0.12.0")
63-
api("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.0")
62+
implementation("org.jetbrains.kotlinx:kotlinx-io-core:0.5.4")
63+
api("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3")
6464
}
6565
}
6666

src/commonTest/kotlin/fr/acinq/bitcoin/BlockTestsCommon.kt

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,11 @@
1616

1717
package fr.acinq.bitcoin
1818

19-
import fr.acinq.bitcoin.reference.TransactionTestsCommon
2019
import fr.acinq.secp256k1.Hex
21-
import org.kodein.memory.file.openReadableFile
22-
import org.kodein.memory.file.resolve
23-
import org.kodein.memory.use
2420
import kotlin.test.*
2521

2622
class BlockTestsCommon {
27-
private val blockData = run {
28-
val file = TransactionTestsCommon.resourcesDir().resolve("block1.dat")
29-
file.openReadableFile().use {
30-
val len = it.size
31-
// workaround for a bug in kotlin memory file where dstOffset cannot be 0 but is still ignored...
32-
val buffer = ByteArray(len)
33-
it.readBytes(buffer, 0, buffer.size)
34-
buffer
35-
}
36-
}
23+
private val blockData = TestHelpers.readResourceAsByteArray("block1.dat")
3724

3825
@Test
3926
fun `read blocks`() {

src/commonTest/kotlin/fr/acinq/bitcoin/CryptoTestsCommon.kt

Lines changed: 26 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,12 @@
1616

1717
package fr.acinq.bitcoin
1818

19-
import fr.acinq.bitcoin.reference.TransactionTestsCommon
2019
import fr.acinq.secp256k1.Hex
2120
import fr.acinq.secp256k1.Secp256k1
22-
import org.kodein.memory.file.openReadableFile
23-
import org.kodein.memory.file.resolve
24-
import org.kodein.memory.text.readLine
25-
import org.kodein.memory.use
21+
import kotlinx.io.buffered
22+
import kotlinx.io.files.Path
23+
import kotlinx.io.files.SystemFileSystem
24+
import kotlinx.io.readLine
2625
import kotlin.random.Random
2726
import kotlin.test.*
2827

@@ -207,7 +206,6 @@ class CryptoTestsCommon {
207206
val publicKey = privateKey.publicKey()
208207
val shared = Crypto.ecdh(privateKey, publicKey)
209208
assertEquals("56bc84cffc7db1ca04046fc04ec8f84232c340be789bc4779d221fe8b978af06", Hex.encode(shared))
210-
211209
val random = Random
212210
val privateKey1 = PrivateKey(random.nextBytes(32))
213211
val privateKey2 = PrivateKey(random.nextBytes(32))
@@ -257,29 +255,28 @@ class CryptoTestsCommon {
257255
var pub: PublicKey? = null
258256
var sig: ByteVector? = null
259257
var recid: Int
260-
val file = TransactionTestsCommon.resourcesDir().resolve("recid.txt")
261-
file.openReadableFile().use {
262-
while (true) {
263-
val line = it.readLine() ?: return
264-
val values = line.split(" = ")
265-
val lhs = values[0]
266-
val rhs = values[1]
267-
when (lhs) {
268-
"privkey" -> priv = PrivateKey(ByteVector(rhs).toByteArray())
269-
"message" -> message = ByteVector(rhs)
270-
"pubkey" -> pub = PublicKey(ByteVector(rhs))
271-
"sig" -> sig = run {
272-
val reversed = ByteVector(rhs).take(64)
273-
ByteVector((reversed.take(32).reversed() + reversed.takeRight(32).reversed()).toByteArray())
274-
}
275-
"recid" -> {
276-
recid = rhs.toInt()
277-
assertEquals(priv!!.publicKey(), pub)
278-
val sig1 = Crypto.sign(message!!.toByteArray(), priv!!)
279-
assertEquals(sig1, sig)
280-
val pub1 = Crypto.recoverPublicKey(sig1, message!!.toByteArray(), recid)
281-
assertEquals(pub1, pub)
282-
}
258+
val source = SystemFileSystem.source(Path(TestHelpers.resourcesPath, "recid.txt")).buffered()
259+
while (true) {
260+
val line = source.readLine() ?: return
261+
val values = line.split(" = ")
262+
val lhs = values[0]
263+
val rhs = values[1]
264+
when (lhs) {
265+
"privkey" -> priv = PrivateKey(ByteVector(rhs).toByteArray())
266+
"message" -> message = ByteVector(rhs)
267+
"pubkey" -> pub = PublicKey(ByteVector(rhs))
268+
"sig" -> sig = run {
269+
val reversed = ByteVector(rhs).take(64)
270+
ByteVector((reversed.take(32).reversed() + reversed.takeRight(32).reversed()).toByteArray())
271+
}
272+
273+
"recid" -> {
274+
recid = rhs.toInt()
275+
assertEquals(priv!!.publicKey(), pub)
276+
val sig1 = Crypto.sign(message!!.toByteArray(), priv)
277+
assertEquals(sig1, sig)
278+
val pub1 = Crypto.recoverPublicKey(sig1, message.toByteArray(), recid)
279+
assertEquals(pub1, pub)
283280
}
284281
}
285282
}

src/commonTest/kotlin/fr/acinq/bitcoin/MnemonicCodeTestsCommon.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ package fr.acinq.bitcoin
1818

1919
import fr.acinq.bitcoin.MnemonicCode.toMnemonics
2020
import fr.acinq.bitcoin.MnemonicCode.toSeed
21-
import fr.acinq.bitcoin.reference.TransactionTestsCommon
2221
import fr.acinq.secp256k1.Hex
2322
import kotlinx.serialization.json.jsonArray
2423
import kotlinx.serialization.json.jsonObject
@@ -42,7 +41,7 @@ class MnemonicCodeTestsCommon {
4241

4342
@Test
4443
fun `reference tests`() {
45-
val tests = TransactionTestsCommon.readData("bip39_vectors.json")
44+
val tests = TestHelpers.readResourceAsJson("bip39_vectors.json")
4645

4746
tests.jsonObject["english"]!!.jsonArray.map {
4847
val raw = it.jsonArray[0].jsonPrimitive.content

src/commonTest/kotlin/fr/acinq/bitcoin/TaprootTestsCommon.kt

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,8 @@ import fr.acinq.bitcoin.Bech32.hrp
1919
import fr.acinq.bitcoin.Bitcoin.addressToPublicKeyScript
2020
import fr.acinq.bitcoin.Transaction.Companion.hashForSigningSchnorr
2121
import fr.acinq.bitcoin.io.ByteArrayInput
22-
import fr.acinq.bitcoin.io.ByteArrayOutput
23-
import fr.acinq.bitcoin.reference.TransactionTestsCommon.Companion.resourcesDir
2422
import fr.acinq.secp256k1.Hex
2523
import fr.acinq.secp256k1.Secp256k1
26-
import org.kodein.memory.file.openReadableFile
27-
import org.kodein.memory.file.resolve
2824
import kotlin.test.*
2925

3026
class TaprootTestsCommon {
@@ -356,10 +352,7 @@ class TaprootTestsCommon {
356352
@Test
357353
fun `parse and validate huge transaction`() {
358354
// this is the tx that broke btcd/lnd
359-
val file = resourcesDir().resolve("7393096d97bfee8660f4100ffd61874d62f9a65de9fb6acf740c4c386990ef73.bin").openReadableFile()
360-
val buffer = ByteArray(file.size)
361-
file.readBytes(buffer, 0, buffer.size)
362-
file.close()
355+
val buffer = TestHelpers.readResourceAsByteArray("7393096d97bfee8660f4100ffd61874d62f9a65de9fb6acf740c4c386990ef73.bin")
363356
val tx = Transaction.read(buffer)
364357
assertEquals(1001, tx.txIn[0].witness.stack.size)
365358
val parentTx = Transaction.read(
@@ -408,10 +401,7 @@ class TaprootTestsCommon {
408401

409402
@Test
410403
fun `parse and validate large ordinals transaction`() {
411-
val file = resourcesDir().resolve("b5a7e05f28d00e4a791759ad7b6bd6799d856693293ceeaad9b0bb93c8851f7f.bin").openReadableFile()
412-
val buffer = ByteArray(file.size)
413-
file.readBytes(buffer, 0, buffer.size)
414-
file.close()
404+
val buffer = TestHelpers.readResourceAsByteArray("b5a7e05f28d00e4a791759ad7b6bd6799d856693293ceeaad9b0bb93c8851f7f.bin")
415405
val tx = Transaction.read(buffer)
416406
val parentTx = Transaction.read(
417407
"0100000000010273721ae5e7d59775f7104670fc8f74e9dee6fe57de47a2ebc14c95cafe4241050000000000fdffffff73721ae5e7d59775f7104670fc8f74e9dee6fe57de47a2ebc14c95cafe4241050100000000fdffffff025459f00200000000225120ca991d5bfbc6840c7568146e305f9eb67d8650948b1f929e941659b2649195941ea50c000000000022512051bf94b8b1d63574a47847d5fdccf2c90953189fa0220cf8f2d6284cf60e5f820140a844d30c2231d6e9c370b094200004475f21545efbd548a6f374ea956e2eea51d62d7048350130bc2fca3a5517ffe34d9e02d150ac58aba2920c88acb3cfc7fe014089d904d0be731c542ef9fe623b19502483348b1b6e0c9058e31c5ebd755070a27aa7dea288b839e2853da70607ea35851394f887e71c1ed58f15bf661969aa5900000000"
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package fr.acinq.bitcoin
2+
3+
import kotlinx.io.buffered
4+
import kotlinx.io.files.Path
5+
import kotlinx.io.files.SystemFileSystem
6+
import kotlinx.io.readByteArray
7+
import kotlinx.io.readString
8+
import kotlinx.serialization.json.Json
9+
import kotlinx.serialization.json.JsonElement
10+
11+
object TestHelpers {
12+
val resourcesPath = Path(readEnvironmentVariable("TEST_RESOURCES_PATH")?: "src/commonTest/resources")
13+
14+
fun readResourceAsJson(filename: String): JsonElement {
15+
val raw = SystemFileSystem.source(Path(resourcesPath, filename)).buffered().readString()
16+
val format = Json { ignoreUnknownKeys = true }
17+
return format.parseToJsonElement(raw)
18+
}
19+
20+
21+
fun readResourceAsByteArray(filename: String): ByteArray {
22+
return SystemFileSystem.source(Path(resourcesPath, filename)).buffered().readByteArray()
23+
}
24+
}
25+
26+
expect fun readEnvironmentVariable(name: String): String?

src/commonTest/kotlin/fr/acinq/bitcoin/crypto/musig2/Musig2TestsCommon.kt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import kotlin.test.*
1010
class Musig2TestsCommon {
1111
@Test
1212
fun `aggregate public keys`() {
13-
val tests = TransactionTestsCommon.readData("musig2/key_agg_vectors.json")
13+
val tests = TestHelpers.readResourceAsJson("musig2/key_agg_vectors.json")
1414
val pubkeys = tests.jsonObject["pubkeys"]!!.jsonArray.map { PublicKey(ByteVector(it.jsonPrimitive.content)) }
1515
val tweaks = tests.jsonObject["tweaks"]!!.jsonArray.map { ByteVector32.fromValidHex(it.jsonPrimitive.content) }
1616

@@ -58,7 +58,7 @@ class Musig2TestsCommon {
5858

5959
@Test
6060
fun `generate secret nonce`() {
61-
val tests = TransactionTestsCommon.readData("musig2/nonce_gen_vectors.json")
61+
val tests = TestHelpers.readResourceAsJson("musig2/nonce_gen_vectors.json")
6262
tests.jsonObject["test_cases"]!!.jsonArray.forEach {
6363
val randprime = ByteVector32.fromValidHex(it.jsonObject["rand_"]!!.jsonPrimitive.content)
6464
val sk = it.jsonObject["sk"]?.jsonPrimitive?.contentOrNull?.let { PrivateKey.fromHex(it) }
@@ -85,7 +85,7 @@ class Musig2TestsCommon {
8585

8686
@Test
8787
fun `aggregate nonces`() {
88-
val tests = TransactionTestsCommon.readData("musig2/nonce_agg_vectors.json")
88+
val tests = TestHelpers.readResourceAsJson("musig2/nonce_agg_vectors.json")
8989
val nonces = tests.jsonObject["pnonces"]!!.jsonArray.map { IndividualNonce(it.jsonPrimitive.content) }
9090
tests.jsonObject["valid_test_cases"]!!.jsonArray.forEach {
9191
val nonceIndices = it.jsonObject["pnonce_indices"]!!.jsonArray.map { it.jsonPrimitive.int }
@@ -102,7 +102,7 @@ class Musig2TestsCommon {
102102

103103
@Test
104104
fun sign() {
105-
val tests = TransactionTestsCommon.readData("musig2/sign_verify_vectors.json")
105+
val tests = TestHelpers.readResourceAsJson("musig2/sign_verify_vectors.json")
106106
val sk = PrivateKey.fromHex(tests.jsonObject["sk"]!!.jsonPrimitive.content)
107107
val pubkeys = tests.jsonObject["pubkeys"]!!.jsonArray.map { PublicKey(ByteVector(it.jsonPrimitive.content)) }
108108
val secnonces = tests.jsonObject["secnonces"]!!.jsonArray.map { deserializeSecretNonce(it.jsonPrimitive.content) }
@@ -148,7 +148,7 @@ class Musig2TestsCommon {
148148

149149
@Test
150150
fun `aggregate signatures`() {
151-
val tests = TransactionTestsCommon.readData("musig2/sig_agg_vectors.json")
151+
val tests = TestHelpers.readResourceAsJson("musig2/sig_agg_vectors.json")
152152
val pubkeys = tests.jsonObject["pubkeys"]!!.jsonArray.map { PublicKey(ByteVector(it.jsonPrimitive.content)) }
153153
val pnonces = tests.jsonObject["pnonces"]!!.jsonArray.map { IndividualNonce(it.jsonPrimitive.content) }
154154
val tweaks = tests.jsonObject["tweaks"]!!.jsonArray.map { ByteVector32.fromValidHex(it.jsonPrimitive.content) }
@@ -193,7 +193,7 @@ class Musig2TestsCommon {
193193

194194
@Test
195195
fun `tweak tests`() {
196-
val tests = TransactionTestsCommon.readData("musig2/tweak_vectors.json")
196+
val tests = TestHelpers.readResourceAsJson("musig2/tweak_vectors.json")
197197
val sk = PrivateKey.fromHex(tests.jsonObject["sk"]!!.jsonPrimitive.content)
198198
val pubkeys = tests.jsonObject["pubkeys"]!!.jsonArray.map { PublicKey(ByteVector(it.jsonPrimitive.content)) }
199199
val pnonces = tests.jsonObject["pnonces"]!!.jsonArray.map { IndividualNonce(it.jsonPrimitive.content) }

src/commonTest/kotlin/fr/acinq/bitcoin/reference/BIP341TestsCommon.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import kotlin.test.assertNotNull
2525
class BIP341TestsCommon {
2626
@Test
2727
fun `BIP341 reference tests -- key path spending`() {
28-
val tests = TransactionTestsCommon.readData("data/bip341_wallet_vectors.json").jsonObject["keyPathSpending"]!!
28+
val tests = TestHelpers.readResourceAsJson("data/bip341_wallet_vectors.json").jsonObject["keyPathSpending"]!!
2929
tests.jsonArray.forEach { it ->
3030
val fullySignedTx = Transaction.read(it.jsonObject["auxiliary"]!!.jsonObject["fullySignedTx"]!!.jsonPrimitive.content)
3131
val rawUnsignedTx = Transaction.read(it.jsonObject["given"]!!.jsonObject["rawUnsignedTx"]!!.jsonPrimitive.content)
@@ -78,7 +78,7 @@ class BIP341TestsCommon {
7878

7979
@Test
8080
fun `BIP341 reference tests -- script path spending`() {
81-
val tests = TransactionTestsCommon.readData("data/bip341_wallet_vectors.json").jsonObject["scriptPubKey"]!!
81+
val tests = TestHelpers.readResourceAsJson("data/bip341_wallet_vectors.json").jsonObject["scriptPubKey"]!!
8282
tests.jsonArray.forEach { it ->
8383
val given = it.jsonObject["given"]!!.jsonObject
8484
val internalPubkey = XonlyPublicKey(ByteVector32.fromValidHex(given["internalPubkey"]!!.jsonPrimitive.content))

src/commonTest/kotlin/fr/acinq/bitcoin/reference/Base58ReferenceTestsCommon.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package fr.acinq.bitcoin.reference
1818

1919
import fr.acinq.bitcoin.Base58
2020
import fr.acinq.bitcoin.Base58Check
21+
import fr.acinq.bitcoin.TestHelpers
2122
import fr.acinq.secp256k1.Hex
2223
import kotlinx.serialization.json.boolean
2324
import kotlinx.serialization.json.jsonArray
@@ -29,7 +30,7 @@ import kotlin.test.assertEquals
2930
class Base58ReferenceTestsCommon {
3031
@Test
3132
fun `reference encode-decode test`() {
32-
val tests = TransactionTestsCommon.readData("data/base58_encode_decode.json")
33+
val tests = TestHelpers.readResourceAsJson("data/base58_encode_decode.json")
3334
tests.jsonArray.filter { it.jsonArray.size == 2 }.map { it.jsonArray }.forEach {
3435
val hex = it[0].jsonPrimitive.content
3536
val expected = it[1].jsonPrimitive.content
@@ -41,7 +42,7 @@ class Base58ReferenceTestsCommon {
4142

4243
@Test
4344
fun `reference valid keys test`() {
44-
val tests = TransactionTestsCommon.readData("data/base58_keys_valid.json")
45+
val tests = TestHelpers.readResourceAsJson("data/base58_keys_valid.json")
4546
tests.jsonArray.forEach {
4647
val base58: String = it.jsonArray[0].jsonPrimitive.content
4748
val (version, data) = Base58Check.decode(base58)

src/commonTest/kotlin/fr/acinq/bitcoin/reference/KeyEncodingTestsCommon.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import kotlin.test.assertTrue
2929
class KeyEncodingTestsCommon {
3030
@Test
3131
fun `valid keys`() {
32-
val tests = TransactionTestsCommon.readData("data/key_io_valid.json")
32+
val tests = TestHelpers.readResourceAsJson("data/key_io_valid.json")
3333
tests.jsonArray.filter { it.jsonArray.size == 3 }.map { it.jsonArray }.forEach {
3434
var encoded: String = it[0].jsonPrimitive.content
3535
val hex: String = it[1].jsonPrimitive.content
@@ -94,7 +94,7 @@ class KeyEncodingTestsCommon {
9494

9595
@Test
9696
fun `invalid keys`() {
97-
val tests = TransactionTestsCommon.readData("data/key_io_invalid.json")
97+
val tests = TestHelpers.readResourceAsJson("data/key_io_invalid.json")
9898
tests.jsonArray.forEach {
9999
val value = it.jsonArray[0].jsonPrimitive.content
100100
assertTrue(!isValidBase58(value))

0 commit comments

Comments
 (0)