From debbugs-submit-bounces@debbugs.gnu.org Sat Feb 01 23:36:52 2025 Received: (at submit) by debbugs.gnu.org; 2 Feb 2025 04:36:52 +0000 Received: from localhost ([127.0.0.1]:60829 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1teRiy-0000Pj-Is for submit@debbugs.gnu.org; Sat, 01 Feb 2025 23:36:52 -0500 Received: from lists.gnu.org ([2001:470:142::17]:42778) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1teRiu-0000PG-UG for submit@debbugs.gnu.org; Sat, 01 Feb 2025 23:36:46 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1teRim-0008RG-AS for guix-patches@gnu.org; Sat, 01 Feb 2025 23:36:38 -0500 Received: from mail.cock.li ([37.120.193.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1teRij-0004Pa-9E; Sat, 01 Feb 2025 23:36:36 -0500 From: Justin Veilleux DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=cock.li; s=mail; t=1738470981; bh=5Q0RW10RU5uqiGJSRmQDM3Hh5kLzVVnDcv6iOhOcuNA=; h=From:To:Subject:Date:From; b=ZEv2ot7vENOAVLHr5FvGSjP9gYuZKqp79o4HebjaNmOA8e7hJ/1gVeYFtManEf3yl +u675+C/JvT3GWjjVIxjVUIimDr1HIfL3o2333Q503BjcMYszqg8vWmgXzZbIN0kdF cPhAlxae5SVBMWrAPUSKuFr4/w7theNS9E+Xle6Nixt5duHidRK0WkOmstI7jXoE9j 27X2yBoK3mE3UKC2vGWjCDI+gHMlRkP3knD45m/rb3Ill9nFST/+VWE+vV+qGlOj4f 7F6EOrOk0D9OQ8Ad8t54h+ZIT5IPsSLwqZTSGLIaSUv0AvDh615UkTL2Iy4eBFi0+V 1yZZJ6wz3zShw== To: guix-patches@gnu.org, ludo@gnu.org Subject: [PATCH] distribute NARs through IPFS. Date: Sat, 01 Feb 2025 23:36:18 -0500 Message-ID: <875xltklod.fsf@cock.li> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Received-SPF: pass client-ip=37.120.193.124; envelope-from=terramorpha@cock.li; helo=mail.cock.li X-Spam_score_int: 12 X-Spam_score: 1.2 X-Spam_bar: + X-Spam_report: (1.2 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_PBL=3.335, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-Spam-Score: 0.9 (/) X-Debbugs-Envelope-To: submit X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.1 (/) --=-=-= Content-Type: text/plain Hello everyone. I think Distributed substitute distribution has been on many people's radar for a time. However, from what I understood of the discussion at https://issues.guix.gnu.org/33899 (which has been stagnant for many years), actually achieving this is complicated because of the lack of a good way to encode into IPFS store items in a way that correctly deduplicates identical files (giving them the same hash) and works well with the rest of the IPFS ecosystem. Solving this problem is hard and until a spec for UnixFSv2 is created and implemented in the main IPFS implementations, making perfect use of all the IPFS features will be harder and require a lot of effort. However, I would really like to have distributed substitutes, even if it is done through a less-than optimal mechanism, and I feel like (I might be wrong) that is a common sentiment. The attached patch series adds to the `guix publish` daemon an option `--ipfs-api` which, when present, makes it publish through ipfs each compressed nar file it creates, and adds a corresponding entry in the narinfo through the URL: ipfs://Qm... property. on the `guix substitute` side, an `ipfs-fetch` function is also added to download nars through a local gateway. This means that the new URL: ipfs:Qm... fields can now be exploited as easily as the regular nar/lzip/... urls. These changes don't exploit every advantage of IPFS delivery (deduplication, "true decentralization", etc), but enable a non-trivial use-case: many machines on a local network can now distribute amongst themselves substitutes (thus reducing the total needed bandwidth) transparently. WDYT? --=-=-= Content-Type: text/x-patch; charset=utf-8 Content-Disposition: attachment; filename=0001-gnu-substitute-Add-support-for-downloading-nars-over.patch Content-Transfer-Encoding: quoted-printable >From 07bf18b20faa86375d2eb80a49a6a6b36ad294f9 Mon Sep 17 00:00:00 2001 Message-ID: <07bf18b20faa86375d2eb80a49a6a6b36ad294f9.1738470881.git.terram= orpha@cock.li> From: terramorpha Date: Sat, 1 Feb 2025 20:13:47 -0500 Subject: [PATCH 1/4] gnu: substitute: Add support for downloading nars over ipfs. Change-Id: Ia8e7779a65ba07e980586793dc159e06a9da0a66 --- guix/build/download.scm | 26 ++++++++++++++++++++++++++ guix/ipfs.scm | 4 +++- guix/scripts/substitute.scm | 15 ++++++++++++++- 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/guix/build/download.scm b/guix/build/download.scm index 74b7486b7b..7e59aecd3d 100644 --- a/guix/build/download.scm +++ b/guix/build/download.scm @@ -3,6 +3,7 @@ ;;; Copyright =C2=A9 2015 Mark H Weaver ;;; Copyright =C2=A9 2017 Tobias Geerinckx-Rice ;;; Copyright =C2=A9 2021 Timothy Sample +;;; Copyright =C2=A9 2025 Justin Veilleux ;;; ;;; This file is part of GNU Guix. ;;; @@ -29,6 +30,7 @@ (define-module (guix build download) #:use-module (guix build utils) #:use-module (guix progress) #:use-module (guix memoization) + #:use-module (guix ipfs) #:use-module (rnrs io ports) #:use-module (rnrs bytevectors) #:use-module (srfi srfi-1) @@ -46,6 +48,7 @@ (define-module (guix build download) open-socket-for-uri open-connection-for-uri http-fetch + ipfs-fetch %x509-certificate-directory close-connection resolve-uri-reference @@ -614,6 +617,29 @@ (define* (http-fetch uri #:key timeout (verify-certifi= cate? #t)) (error "download failed" (uri->string uri) code (response-reason-phrase resp)))))) =20 +(define (ipfs-fetch uri) + "Return an input port containing the data at URI (which is expected to be +ipfs://hash), and the expected number of bytes available or #f." + (unless (eq? (uri-scheme uri) 'ipfs) + (error "scheme is not ipfs")) + + (let ((hash (uri-host uri))) + (let-values (((response port) + (http-post (string-append (%ipfs-base-url) + "/api/v0/cat?arg=3D" hash) + #:streaming? #t + ;; Always pass "Connection: close". + #:keep-alive? #f + #:headers `((connection close))))) + (let ((content-length-header (assoc-ref (response-headers response) + 'x-content-length))) + (case (response-code response) + ((200) + (values port (and content-length-header (string->number content-= length-header)))) + (else + (error "ipfs download failed" (uri->string uri) + (response-code response) (response-reason-phrase response= )))))))) + (define-syntax-rule (false-if-exception* body ...) "Like `false-if-exception', but print the exception on the error port." diff --git a/guix/ipfs.scm b/guix/ipfs.scm index 3c25f2a499..43e7dfb2f2 100644 --- a/guix/ipfs.scm +++ b/guix/ipfs.scm @@ -49,7 +49,9 @@ (define-module (guix ipfs) =20 (define %ipfs-base-url ;; URL of the IPFS gateway. - (make-parameter "http://localhost:5001")) + (make-parameter + (or (getenv "GUIX_IPFS_API") + "http://localhost:5001"))) =20 (define* (call url decode #:optional (method http-post) #:key body (false-if-404? #t) (headers '())) diff --git a/guix/scripts/substitute.scm b/guix/scripts/substitute.scm index ab18104e0a..66b6911515 100755 --- a/guix/scripts/substitute.scm +++ b/guix/scripts/substitute.scm @@ -3,6 +3,7 @@ ;;; Copyright =C2=A9 2014 Nikita Karetnikov ;;; Copyright =C2=A9 2018 Kyle Meyer ;;; Copyright =C2=A9 2020 Christopher Baines +;;; Copyright =C2=A9 2025 Justin Veilleux ;;; ;;; This file is part of GNU Guix. ;;; @@ -62,11 +63,13 @@ (define-module (guix scripts substitute) #:use-module (srfi srfi-71) #:use-module (web uri) #:use-module (guix http-client) + #:use-module (guix ipfs) #:export (%allow-unauthenticated-substitutes? %reply-file-descriptor =20 substitute-urls - guix-substitute)) + guix-substitute + download-nar)) =20 ;;; Comment: ;;; @@ -504,6 +507,16 @@ (define* (download-nar narinfo destination #:port port #:keep-alive? #t #:buffered? #f)))) + ((ipfs) + (let ((hash (uri-host uri))) + (if fetch-timeout + (with-timeout %fetch-timeout + (begin + (warning (G_ "while fetching ~a: ipfs is somewhat slow~= %") + (uri->string uri)) + (warning (G_ "try `--no-substitutes' if the problem per= sists~%"))) + (ipfs-fetch uri)) + (ipfs-fetch uri)))) (else (raise (formatted-message base-commit: 0550c4191fae3b3b00b8bb9faba8a2fe2ad0d188 --=20 2.47.1 --=-=-= Content-Type: text/x-patch; charset=utf-8 Content-Disposition: attachment; filename=0002-gnu-publish-Add-support-for-distributing-nars-throug.patch Content-Transfer-Encoding: quoted-printable >From efb9fc07bc797553da8b900ac6b0593119420a8c Mon Sep 17 00:00:00 2001 Message-ID: In-Reply-To: <07bf18b20faa86375d2eb80a49a6a6b36ad294f9.1738470881.git.terra= morpha@cock.li> References: <07bf18b20faa86375d2eb80a49a6a6b36ad294f9.1738470881.git.terram= orpha@cock.li> From: terramorpha Date: Sat, 1 Feb 2025 22:06:11 -0500 Subject: [PATCH 2/4] gnu: publish: Add support for distributing nars through ipfs. Change-Id: I0702114aeb91f19a89c6093095c39d21607373fc --- guix/scripts/publish.scm | 68 ++++++++++++++++++++++++++++++++-------- 1 file changed, 55 insertions(+), 13 deletions(-) diff --git a/guix/scripts/publish.scm b/guix/scripts/publish.scm index a000c559a7..425c880e83 100644 --- a/guix/scripts/publish.scm +++ b/guix/scripts/publish.scm @@ -5,6 +5,7 @@ ;;; Copyright =C2=A9 2020 Maxim Cournoyer ;;; Copyright =C2=A9 2021 Simon Tournier ;;; Copyright =C2=A9 2021, 2022 Mathieu Othacehe +;;; Copyright =C2=A9 2025 Justin Veilleux ;;; ;;; This file is part of GNU Guix. ;;; @@ -66,6 +67,7 @@ (define-module (guix scripts publish) #:use-module ((guix build utils) #:select (dump-port mkdir-p find-files)) #:use-module ((guix build syscalls) #:select (set-thread-name)) + #:use-module ((guix ipfs) #:prefix ipfs:) #:export (%default-gzip-compression =20 %public-key @@ -93,6 +95,8 @@ (define (show-help) compress archives with METHOD at LEVEL")) (display (G_ " -c, --cache=3DDIRECTORY cache published items to DIRECTORY")) + (display (G_ " + --ipfs-api=3DURL if present, publish nar to ipfs through the api= at URL")) (display (G_ " --cache-bypass-threshold=3DSIZE serve store items below SIZE even when not cached= ")) @@ -245,7 +249,10 @@ (define %options (lambda (opt name arg result) ;; If port unspecified, use default Guile REPL port. (let ((port (and arg (string->number* arg)))) - (alist-cons 'repl (or port 37146) result)))))) + (alist-cons 'repl (or port 37146) result)))) + (option '("ipfs-api") #t #f + (lambda (opt name arg result) + (alist-cons 'ipfs-api arg result))))) =20 (define %default-options `((port . 8080) @@ -303,7 +310,8 @@ (define* (store-item->recutils store-item #:key (nar-path "nar") (compression %no-compression) - file-size) + file-size + ipfs-hashes) "Return the 'Compression' and 'URL' fields of the narinfo for STORE-ITEM, with COMPRESSION, starting at NAR-PATH." (let ((url (encode-and-join-uri-path @@ -319,7 +327,11 @@ (define* (store-item->recutils store-item =20 (define* (narinfo-string store store-path #:key (compressions (list %no-compression)) - (nar-path "nar") (file-sizes '())) + (nar-path "nar") + ;; ((compression-method . file-size) ...) + (file-sizes '()) + ;; ((compression-method . hash) ...) + (ipfs-hashes '())) "Generate a narinfo key/value string for STORE-PATH; an exception is rai= sed if STORE-PATH is invalid. Produce a URL that corresponds to COMPRESSION. = The narinfo is signed with KEY. NAR-PATH specifies the prefix for nar URLs. @@ -363,12 +375,26 @@ (define* (narinfo-string store store-path ;; narinfo without having to resign them. (map (lambda (compression) (let ((size (assoc-ref file-sizes - compression))) - (store-item->recutils store-path - #:file-size size - #:nar-path nar-path - #:compression - compression))) + compression)) + (ipfs-hash (assoc-ref ipfs-hashes + compression))) + (string-append + (store-item->recutils store-path + #:file-size size + #:nar-path nar-path + #:compression + compression) + + (if ipfs-hash + (format #f + "URL: ~a +Compression: ~a +FileSize: ~a +" + (string-append "ipfs://" ipfs-hash) + (compression-type compression) + size) + "")))) compressions)))) =20 ;; Custom header to indicate that baking is in progress. @@ -645,8 +671,21 @@ (define* (bake-narinfo+nar cache item (cons compression (stat:size stat))))) =20 (let ((compression (actual-compressions item compressions))) - - (for-each (cut compress-nar cache item <>) compressions) + (define ipfs-hashes '()) + + (for-each + (lambda (compression) + (compress-nar cache item compression) + (when (ipfs:%ipfs-base-url) + (let* ((place (nar-cache-file cache item #:compression compressio= n)) + ;; In the future, we might want to use the api equivalent = of + ;; the (experimental) --nocopy flag, which "interns" the f= ile + ;; without duplicating it in the ipfs store. + (ipfs-thing (ipfs:add-file place)) + (hash (ipfs:content-hash ipfs-thing))) + (set! ipfs-hashes (alist-cons compression hash + ipfs-hashes))))) + compressions) =20 (match compressions ((main others ...) @@ -662,7 +701,8 @@ (define* (bake-narinfo+nar cache item (display (narinfo-string store item #:nar-path nar-path #:compressions compressions - #:file-sizes sizes) + #:file-sizes sizes + #:ipfs-hashes ipfs-hashes) port))) =20 ;; Make the cached narinfo world-readable, contrary to what @@ -1277,7 +1317,8 @@ (define-command (guix-publish . args) ;; Read the key right away so that (1) we fail early on if we c= an't ;; access them, and (2) we can then drop privileges. (public-key (read-file-sexp (assoc-ref opts 'public-key-file))) - (private-key (read-file-sexp (assoc-ref opts 'private-key-file)= ))) + (private-key (read-file-sexp (assoc-ref opts 'private-key-file)= )) + (ipfs-api (assoc-ref opts 'ipfs-api))) =20 (when user ;; Now that we've read the key material and opened the socket, we = can @@ -1290,6 +1331,7 @@ (define-command (guix-publish . args) =20 (parameterize ((%public-key public-key) (%private-key private-key) + (ipfs:%ipfs-base-url ipfs-api) (cache-bypass-threshold (or (assoc-ref opts 'cache-bypass-threshold) (cache-bypass-threshold)))) --=20 2.47.1 --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0003-doc-publish-Add-documentation-for-the-ipfs-api-argum.patch >From 80934014c6f603347996f90f2b915ebdb6b224e7 Mon Sep 17 00:00:00 2001 Message-ID: <80934014c6f603347996f90f2b915ebdb6b224e7.1738470881.git.terramorpha@cock.li> In-Reply-To: <07bf18b20faa86375d2eb80a49a6a6b36ad294f9.1738470881.git.terramorpha@cock.li> References: <07bf18b20faa86375d2eb80a49a6a6b36ad294f9.1738470881.git.terramorpha@cock.li> From: terramorpha Date: Sat, 1 Feb 2025 22:16:29 -0500 Subject: [PATCH 3/4] doc: publish: Add documentation for the --ipfs-api argument. --- doc/guix.texi | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/doc/guix.texi b/doc/guix.texi index bb5f29277f..fe1b3c08d9 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -104,7 +104,7 @@ Copyright @copyright{} 2022 Aleksandr Vityazev@* Copyright @copyright{} 2022 Philip M@sup{c}Grath@* Copyright @copyright{} 2022 Karl Hallsby@* -Copyright @copyright{} 2022 Justin Veilleux@* +Copyright @copyright{} 2022, 2025 Justin Veilleux@* Copyright @copyright{} 2022 Reily Siegel@* Copyright @copyright{} 2022 Simon Streit@* Copyright @copyright{} 2022 (@* @@ -16198,6 +16198,10 @@ Invoking guix publish service discovery (DNS-SD), currently @i{via} Guile-Avahi (@pxref{Top,,, guile-avahi, Using Avahi in Guile Scheme Programs}). +When the @option{--ipfs-api=URL} argument is passed and caching is +enabled, the server will also make its substitutes available through the +@uref{https://ipfs.io,IPFS} daemon available at the given url. + The general syntax is: @example -- 2.47.1 --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0004-services-guix-publish-Expose-and-document-the-ipfs-a.patch >From f71fb156b6b217cea0a181db13d88ccce69f0b5d Mon Sep 17 00:00:00 2001 Message-ID: In-Reply-To: <07bf18b20faa86375d2eb80a49a6a6b36ad294f9.1738470881.git.terramorpha@cock.li> References: <07bf18b20faa86375d2eb80a49a6a6b36ad294f9.1738470881.git.terramorpha@cock.li> From: terramorpha Date: Sat, 1 Feb 2025 22:41:28 -0500 Subject: [PATCH 4/4] services: guix-publish: Expose and document the --ipfs-api argument. Change-Id: Iecabcc79b11a263fd77b25e51ce9d02fcb3aeddc --- doc/guix.texi | 4 ++++ gnu/services/base.scm | 7 ++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/doc/guix.texi b/doc/guix.texi index fe1b3c08d9..ccd7b7d73f 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -20352,6 +20352,10 @@ Base Services When true, advertise the service on the local network @i{via} the DNS-SD protocol, using Avahi. +@item @code{ipfs-api} (default: @code{#f}) +The url to an IPFS node api, when present (and @code{cache} has a +value), publish the compressed NARs on the ipfs network. + This allows neighboring Guix devices with discovery on (see @code{guix-configuration} above) to discover this @command{guix publish} instance and to automatically download substitutes from it. diff --git a/gnu/services/base.scm b/gnu/services/base.scm index 7331c030d7..f8c586d189 100644 --- a/gnu/services/base.scm +++ b/gnu/services/base.scm @@ -2252,6 +2252,8 @@ (define-record-type* (default "localhost")) (advertise? guix-publish-advertise? ;boolean (default #f)) + (ipfs-api guix-publish-ipfs-api ;string to a url + (default #f)) (compression guix-publish-configuration-compression (thunked) (default (default-compression this-record))) @@ -2291,7 +2293,7 @@ (define (guix-publish-shepherd-service config) (match-record config (guix port host nar-path cache workers ttl negative-ttl - cache-bypass-threshold advertise?) + cache-bypass-threshold advertise? ipfs-api) (let ((command #~(list #$(file-append guix "/bin/guix") "publish" "-u" "guix-publish" "-p" #$(number->string port) @@ -2301,6 +2303,9 @@ (define (guix-publish-shepherd-service config) #$@(if advertise? #~("--advertise") #~()) + #$@(if ipfs-api + #~((string-append "--ipfs-api=" ipfs-api)) + #~()) #$@(if workers #~((string-append "--workers=" #$(number->string -- 2.47.1 --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Wed Feb 05 01:22:28 2025 Received: (at 76003) by debbugs.gnu.org; 5 Feb 2025 06:22:28 +0000 Received: from localhost ([127.0.0.1]:47986 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tfYns-0003go-5w for submit@debbugs.gnu.org; Wed, 05 Feb 2025 01:22:28 -0500 Received: from mail-pj1-x102f.google.com ([2607:f8b0:4864:20::102f]:59474) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.84_2) (envelope-from ) id 1tfYno-0003gV-1H for 76003@debbugs.gnu.org; Wed, 05 Feb 2025 01:22:27 -0500 Received: by mail-pj1-x102f.google.com with SMTP id 98e67ed59e1d1-2f9c69aefdbso2517716a91.2 for <76003@debbugs.gnu.org>; Tue, 04 Feb 2025 22:22:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1738736538; x=1739341338; darn=debbugs.gnu.org; h=mime-version:user-agent:message-id:date:references:in-reply-to :subject:cc:to:from:from:to:cc:subject:date:message-id:reply-to; bh=/DBBGMcFjoN18g+Wq7GgD0JFjnqpZSzv3TIbYbiAKr4=; b=j8Kx/V6+RbjwSfiy2I1xHpbsldb42FBDmQ1oKysDXi1Op33Gn03MKNvik8MvtvfVM1 Mfvb6l5KYTjLNOsVpa9gZpFsxqYtSsBy/0jJUkB7ss/klzXwNIgRU0RmEUWeCrjeV3rv 0WM5nKsotcjlhRcEcQ4FoBu2D2asezc4akFsKIoh+iZGLG1Sbq7UfcNKDSaQcKsg6aR8 Gs6NEj/HsubRZNtOI3U7WrItnJQgW0swCHBcBGm7LKQd+qrJX9f76v2X+2UZ4925rg/1 QgqAg7jj+qRwScRQjO23A5v629WFQR8aZO6prRcs6R3RG8xfI3uVNXZIfkXsNe4Wfm5n DQmQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1738736538; x=1739341338; h=mime-version:user-agent:message-id:date:references:in-reply-to :subject:cc:to:from:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=/DBBGMcFjoN18g+Wq7GgD0JFjnqpZSzv3TIbYbiAKr4=; b=g+GZz9ACXaxXT5HvEL/vKosHuiRJ11RmyIfq3LRGpoenI/N5YaJU3y+vFYnEvQkeE1 JGHJfLiuRqJxpFPsZPFaHsVxMoXjnlG3NAqJ8aGi507A0yKrX46cforigE+2nwJiK+h0 qjqSKSZIjXB+RhS3nnqQ9tx9afeSE6r7SJvzEj7vaPAByUtBSCdPeWM7r85ORGilwz+W 3a2t3vMV80zNL5DXKk1AmnS2BoJZNCuDQCH/cIhSvTu1p+07GfNJRsmkZ2Dv948NgCTm AgzV8bwHDjrV692NbRbGtQDmLuZ/21DtATtkIpnsNBP3xFhwSK6pwvNBZKPKC1HDLE7B ucxg== X-Gm-Message-State: AOJu0YwRHeUla5okb30e8HtFgKbr5goDErKPNrQmx0FTw4Qzda71jKmg 8gyAwquYiQwzWE7Et+sXwaMXtP/TfHN5r6WI+nTcTUAMsM3JTO8/ X-Gm-Gg: ASbGncvaHCCn451OIzotIvVRpzEUraZ571iX+RvXxLlgkrGgOPCerAqfxWzEDt2sPpK JW06P5UcpBA0CmGHinXDG9HUi33+aSOtn3pxdA3tVQg2wHT6TMGXRH1OOv+M78E8Kb/wYw69f87 8iNukZTWcnQwZBRRKR0NOvQGYckQhh3IjfnS4xx/KzlW7GYgw9FozbFbqe5j/XjgDyD1PIeqcGi FY83tWwfXSGWc/Tu+kMeYQpHN6hLBDdANLAjKgLRF7ZVkxL0tqh/YJW0J6zYnZkqVNRrCoOK9hx 1XrpiX8obIjN X-Google-Smtp-Source: AGHT+IHC83Vtgeu7DWsrK7yzZHW3FjnuFX9SDHMfIim68YnOorWQbCE1wRGRMEhMbfkn6pNoa+PY/Q== X-Received: by 2002:a17:90b:1e46:b0:2ee:d193:f3d5 with SMTP id 98e67ed59e1d1-2f9e074b291mr2746637a91.7.1738736537617; Tue, 04 Feb 2025 22:22:17 -0800 (PST) Received: from terra ([2405:6586:be0:0:c8ff:1707:9b9:af89]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-21de31edd95sm107540695ad.40.2025.02.04.22.22.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Feb 2025 22:22:17 -0800 (PST) From: Maxim Cournoyer To: Justin Veilleux Subject: Re: bug#76003: [PATCH] distribute NARs through IPFS. In-Reply-To: <875xltklod.fsf@cock.li> (Justin Veilleux's message of "Sat, 01 Feb 2025 23:36:18 -0500") References: <875xltklod.fsf@cock.li> Date: Wed, 05 Feb 2025 15:22:05 +0900 Message-ID: <87msf09aia.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 76003 Cc: ludo@gnu.org, 76003@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Hi, Justin Veilleux writes: [...] > These changes don't exploit every advantage of IPFS delivery > (deduplication, "true decentralization", etc), but enable a non-trivial > use-case: many machines on a local network can now distribute amongst > themselves substitutes (thus reducing the total needed bandwidth) > transparently. Note that this is already possible via mdns discovery of substitute servers advertising themselves via mDNS/DNS-SD (that's the '--advertise?' option of guix-publish, coupled with the '--discover' option of guix-daemon). -- Thanks, Maxim