services: add bitcoin-core
authoralex <[email protected]>
Wed, 20 Aug 2025 06:13:29 +0000 (23:13 -0700)
committeralex <[email protected]>
Sun, 24 Aug 2025 02:58:27 +0000 (19:58 -0700)
infiniteadaptability/services/bitcoin-core.scm [new file with mode: 0644]

diff --git a/infiniteadaptability/services/bitcoin-core.scm b/infiniteadaptability/services/bitcoin-core.scm
new file mode 100644 (file)
index 0000000..d319b02
--- /dev/null
@@ -0,0 +1,115 @@
+(define-module (infiniteadaptability services bitcoin-core)
+  #:use-module (gnu)
+  #:use-module (gnu packages finance)
+  #:use-module (gnu services)
+  #:use-module (gnu services shepherd)
+  #:use-module (guix gexp)
+  #:use-module (guix records)
+  #:export (bitcoin-core-configuration bitcoin-core-service-type))
+
+(define-record-type* <bitcoin-core-configuration> bitcoin-core-configuration
+                     make-bitcoin-core-configuration
+  bitcoin-core-configuration?
+
+  (user bitcoin-core-configuration-user ;string
+        (default "bitcoin"))
+
+  (bitcoin bitcoin-core-configuration-bitcoin ;file-like
+           (default bitcoin-core))
+
+  (datadir bitcoin-core-configuration-datadir ;string
+           (default "/home/bitcoin/.bitcoin"))
+
+  (extra-content bitcoin-core-configuration-extra-content ;string
+                 (default "")))
+
+(define (bitcoin-core-config-file config)
+  "Return the bitcoin-core configureation file corresponding to CONFIG."
+  (computed-file "bitcoin.conf"
+                 #~(begin
+                     (call-with-output-file #$output
+                       (lambda (port)
+                         (format port "datadir=~a\n"
+                                 #$(bitcoin-core-configuration-datadir config))
+                         (format port "~a\n"
+                                 #$(bitcoin-core-configuration-extra-content
+                                    config)))))))
+
+(define (bitcoin-core-accounts config)
+  "Return the accounts needed for service for CONFIG."
+  (define %username
+    (bitcoin-core-configuration-user config))
+
+  (list (user-group
+          (name %username))
+        (user-account
+          (name %username)
+          (group %username)
+          (home-directory (string-append "/home/" %username)))))
+
+(define (bitcoin-core-activation config)
+  "Return the activation GEXP for CONFIG."
+  (with-imported-modules '((guix build utils))
+                         #~(begin
+                             (use-modules (guix build utils))
+                             (define %user
+                               (getpw #$(bitcoin-core-configuration-user
+                                         config)))
+
+                             (let* ((homedir (passwd:dir %user))
+                                    (datadir #$(bitcoin-core-configuration-datadir
+                                                config)))
+                               
+                               ;; This is important if the datadir is inside the user's directory
+                               (mkdir-p homedir)
+                               (chown homedir
+                                      (passwd:uid %user)
+                                      (passwd:gid %user))
+
+                               (mkdir-p datadir)
+                               (chown datadir
+                                      (passwd:uid %user)
+                                      (passwd:gid %user))))))
+
+(define (bitcoin-core-service config)
+  "Return a <bitcoin-core-service> for bitcoin with CONFIG."
+
+  (define pid-file
+    (string-append (bitcoin-core-configuration-datadir config) "/bitcoind.pid"))
+
+  (define config-file
+    (bitcoin-core-config-file config))
+
+  (define bitcoind-command
+    #~(list (string-append #$(bitcoin-core-configuration-bitcoin config)
+                           "/bin/bitcoind")
+            (string-append "-conf="
+                           #$config-file)
+            (string-append "-pid="
+                           #$pid-file) "-daemon"))
+
+  (list (shepherd-service (documentation "bitcoin core service")
+                          (provision '(bitcoin-core))
+                          (requirement '(user-processes networking))
+                          (start #~(make-forkexec-constructor #$bitcoind-command
+                                                              #:pid-file #$pid-file
+                                                              #:user "bitcoin"
+                                                              #:group
+                                                              "bitcoin"
+                                                              #:directory
+                                                              "/home/bitcoin"))
+
+                          (stop #~(make-kill-destructor SIGINT
+                                                        #:grace-period 600)))))
+
+(define bitcoin-core-service-type
+  (service-type (name 'bitcoin-core)
+                (description "Bitcoin Core Daemon")
+                (default-value (bitcoin-core-configuration))
+                (extensions (list (service-extension
+                                   shepherd-root-service-type
+                                   bitcoin-core-service)
+                                  (service-extension activation-service-type
+                                                     bitcoin-core-activation)
+                                  (service-extension account-service-type
+                                                     bitcoin-core-accounts)))))