Skip to content

Commit

Permalink
Merge pull request #2740 from alvasw/verify_and_unpack_bitcoind_to_re…
Browse files Browse the repository at this point in the history
…sources

Verify and unpack bitcoind to resources
  • Loading branch information
HenrikJannsen authored Sep 3, 2024
2 parents b2233ef + fe47ad7 commit 5dbafbb
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 0 deletions.
1 change: 1 addition & 0 deletions build-logic/bitcoin-core-binaries/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ gradlePlugin {

dependencies {
implementation(project(":gradle-tasks"))
implementation(libs.google.guava)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package bisq.gradle.bitcoin_core

import bisq.gradle.tasks.PerPlatformUrlProvider

class BitcoinCoreBinaryUrlProvider(private val version: String) : PerPlatformUrlProvider {
override val urlPrefix: String
get() = "https://bitcoincore.org/bin/bitcoin-core-$version/bitcoin-$version-"

override val LINUX_X86_64_URL: String
get() = "x86_64-linux-gnu.tar.gz"

override val MACOS_X86_64_URL: String
get() = "x86_64-apple-darwin.tar.gz"

override val MACOS_ARM_64_URL: String
get() = "arm64-apple-darwin.tar.gz"

override val WIN_X86_64_URL: String
get() = "win64.zip"
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
package bisq.gradle.bitcoin_core

import bisq.gradle.tasks.PgpFingerprint
import bisq.gradle.tasks.download.DownloadTaskFactory
import bisq.gradle.tasks.download.SignedBinaryDownloader
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.Copy
import org.gradle.api.tasks.TaskProvider
import org.gradle.kotlin.dsl.create
import org.gradle.kotlin.dsl.register


class BitcoinCorePlugin : Plugin<Project> {
Expand Down Expand Up @@ -58,6 +63,51 @@ class BitcoinCorePlugin : Plugin<Project> {
)
)
hashFileDownloader.registerTasks()

val binaryDownloadUrl: Provider<String> = extension.version.map { BitcoinCoreBinaryUrlProvider(it).url }
val downloadTaskFactory = DownloadTaskFactory(project, DOWNLOADS_DIR)
val binaryDownloadTask = downloadTaskFactory
.registerDownloadTask("downloadBitcoinCore", binaryDownloadUrl)

val bitcoinCoreHashVerificationTask: TaskProvider<HashVerificationTask> =
project.tasks.register<HashVerificationTask>("verifyBitcoinCore") {
inputFile.set(binaryDownloadTask.flatMap { it.outputFile })
sha256File.set(hashFileDownloader.verifySignatureTask.flatMap { it.fileToVerify })
resultFile.set(project.layout.buildDirectory.file("${DOWNLOADS_DIR}/bitcoin_core.sha256.result"))
}

val unpackBitcoinCoreArchiveTask: TaskProvider<Copy> =
project.tasks.register<Copy>("unpackBitcoinCoreArchive") {
dependsOn(bitcoinCoreHashVerificationTask)

val inputFile = bitcoinCoreHashVerificationTask.flatMap { it.inputFile }
val sourceFile = inputFile.map {
if (it.asFile.name.endsWith(".tar.gz")) {
project.tarTree(it.asFile.absolutePath)
} else {
project.zipTree(it.asFile.absolutePath)
}
}
from(sourceFile)

into(project.layout.buildDirectory.dir("${DOWNLOADS_DIR}/extracted"))
}

val copyBitcoinCoreToResourcesTask: TaskProvider<Copy> =
project.tasks.register<Copy>("copyBitcoinCoreToResources") {
dependsOn(unpackBitcoinCoreArchiveTask)
val sourceDirectory = extension.version.map { version ->
project.layout.buildDirectory.dir("${DOWNLOADS_DIR}/extracted/bitcoin-$version/bin/")
}
from(sourceDirectory)
include("bitcoind*")
into(project.layout.buildDirectory.dir("generated/src/main/resources"))
}

val processResourcesTask = project.tasks.named("processResources")
processResourcesTask.configure {
dependsOn(copyBitcoinCoreToResourcesTask)
}
}

private fun filenameAndFingerprint(filename: String, fingerprint: String) =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package bisq.gradle.bitcoin_core

import com.google.common.hash.Hashing
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction

abstract class HashVerificationTask : DefaultTask() {
@get:InputFile
abstract val inputFile: RegularFileProperty

@get:InputFile
abstract val sha256File: RegularFileProperty

@get:OutputFile
abstract val resultFile: RegularFileProperty

@TaskAction
fun verify() {
val input = inputFile.get().asFile.readBytes()
val hash: String = Hashing.sha256()
.hashBytes(input)
.toString()

val expectedHash = getExpectedHash()
if (hash != expectedHash) {
throw GradleException(
"Hash verification failed for `${inputFile.get().asFile.absolutePath}`. " +
"Expected: `$expectedHash, Actual: `$hash`"
)
}

resultFile.get().asFile.writeText(hash)
}

private fun getExpectedHash(): String {
val inputFileName = inputFile.get().asFile.name
for (line in sha256File.get().asFile.readLines()) {
if (line.endsWith(inputFileName)) {
// '<sha256hash> filename.tar.gz'
return line.split(" ").first()
}
}

throw GradleException("Couldn't find expected hash for `$inputFile`.")
}
}

0 comments on commit 5dbafbb

Please sign in to comment.