diff --git a/.github/workflows/release-blake2b.yml b/.github/workflows/release-blake2b.yml index fa828cc28daa..8652b7746055 100644 --- a/.github/workflows/release-blake2b.yml +++ b/.github/workflows/release-blake2b.yml @@ -1,9 +1,11 @@ name: Release BLAKE2b # Builds the reproducible Ubuntu amd64 and arm64 tarballs for a -# vX.Y.Z-blake2b.N tag and drafts its GitHub release with an unsigned -# SHA256SUMS. The release captain rebuilds, signs SHA256SUMS with their own -# key, uploads the .asc and publishes the draft by hand. +# vX.Y.Z-blake2b.N tag and drafts its GitHub release with unsigned +# SHA256SUMS manifests, one for amd64 and one for arm64. The release captain +# rebuilds, signs only the manifests whose tarballs they rebuilt, uploads the +# .asc files, deletes any manifest left unsigned with its tarballs, and +# publishes the draft by hand. on: push: tags: @@ -121,7 +123,7 @@ jobs: sudo docker run --rm -v "$(pwd)":/build "ubuntu:$distribution" bash -c "\ apt-get update && \ apt-get install -y debootstrap && \ - debootstrap $distribution /build/$distribution" + debootstrap --keyring=/usr/share/keyrings/ubuntu-archive-keyring.gpg $distribution /build/$distribution" sudo tar -C "$distribution" -c . | docker import - "$distribution" docker build -t "cl-repro-$distribution$suffix" - < "contrib/reprobuild/Dockerfile.$distribution" @@ -166,8 +168,15 @@ jobs: echo "::error::Expected exactly 6 tarballs for $VERSION, found: $(ls)" exit 1 fi - LC_ALL=C sha256sum "$@" > SHA256SUMS-"$VERSION" - cat SHA256SUMS-"$VERSION" + # One manifest per architecture, so a signer signs only what they + # rebuilt. + LC_ALL=C sha256sum clightning-"$VERSION"-*-amd64.tar.xz > SHA256SUMS-"$VERSION" + LC_ALL=C sha256sum clightning-"$VERSION"-*-arm64.tar.xz > SHA256SUMS-"$VERSION"-arm64 + if [ "$(wc -l < SHA256SUMS-"$VERSION")" -ne 3 ] || [ "$(wc -l < SHA256SUMS-"$VERSION"-arm64)" -ne 3 ]; then + echo "::error::Expected 3 amd64 and 3 arm64 tarballs for $VERSION" + exit 1 + fi + cat SHA256SUMS-"$VERSION" SHA256SUMS-"$VERSION"-arm64 cp ../contrib/keys/privkeyio.txt privkeyio-signing-key.asc - name: Upload release files @@ -212,4 +221,5 @@ jobs: fi cd release gh release create "$VERSION" --draft --verify-tag --title "$VERSION" --notes "" \ - clightning-"$VERSION"-*.tar.xz SHA256SUMS-"$VERSION" privkeyio-signing-key.asc + clightning-"$VERSION"-*.tar.xz SHA256SUMS-"$VERSION" SHA256SUMS-"$VERSION"-arm64 \ + privkeyio-signing-key.asc diff --git a/README.md b/README.md index 6a474f990c83..eabc78be7d97 100644 --- a/README.md +++ b/README.md @@ -38,16 +38,28 @@ git clone https://github.com/privkeyio/lightning.git ## Releases -Published under [Releases](https://github.com/privkeyio/lightning/releases) with signed checksum files covering every artifact: +Published under [Releases](https://github.com/privkeyio/lightning/releases) with signed checksum files, one for amd64 (`SHA256SUMS-`) and one for arm64 (`SHA256SUMS--arm64`). Releases up to `v26.06.9-blake2b.9` have a single `SHA256SUMS-` covering both. For amd64: ```bash gpg --import privkeyio-signing-key.asc -gpg --verify SHA256SUMS-*.asc SHA256SUMS-* -sha256sum -c SHA256SUMS-* --ignore-missing +gpg --verify SHA256SUMS-.asc SHA256SUMS- +sha256sum -c SHA256SUMS- --ignore-missing ``` +For arm64, use `SHA256SUMS--arm64` and its `.asc` the same way. A manifest without an `.asc` is not published. + The signing key is `A47D 99B6 DB0D 715D 40C5 9A20 23AE 8A8E A7E2 4E38`. From `v26.06.9-blake2b.8` on, releases are signed by its subkey `1004 97C5 8727 107D 9B9D A0FA F160 CC14 F64F 8EF8`. +A manifest is only signed by someone who rebuilt every tarball it lists and got the same hashes. To rebuild a release yourself, download and verify its manifest as above into the repository root, check out its tag and run: + +```bash +ROOTLESS=1 contrib/cl-repro.sh +tools/build-release.sh --without-zip --force-version --force-mtime bin-Ubuntu +(cd release && sha256sum -c --ignore-missing ../SHA256SUMS-) +``` + +`` is the tag's commit date in UTC, from `TZ=UTC git log -1 --format=%cd --date=format-local:%Y-%m-%d `. Drop `ROOTLESS=1` on rootful Docker. `v26.06.9-blake2b.8` and `v26.06.9-blake2b.9` predate the pinned builder images, so build their images from `blake2b-unified` before checking out the tag. For arm64, add `PLATFORM=linux/arm64` on an amd64 host, build `bin-Ubuntu-jammy-arm64 bin-Ubuntu-noble-arm64 bin-Ubuntu-resolute-arm64`, and check `release-arm64/` against `SHA256SUMS--arm64`, or the single manifest for releases up to `v26.06.9-blake2b.9`. + For StartOS, the packaged build lives at [privkeyio/cln-startos](https://github.com/privkeyio/cln-startos). --- diff --git a/SECURITY.md b/SECURITY.md index dd7e32ea1e55..ec13ac9596d3 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -52,3 +52,5 @@ gpg --import privkeyio-signing-key.asc gpg --verify SHA256SUMS-.asc SHA256SUMS- sha256sum -c --ignore-missing SHA256SUMS- ``` + +arm64 tarballs have their own manifest, `SHA256SUMS--arm64`, verified the same way. Releases up to `v26.06.9-blake2b.9` have a single `SHA256SUMS-` covering both. diff --git a/contrib/cl-repro.sh b/contrib/cl-repro.sh index 5e8ee36930c0..ee735b4a4e20 100755 --- a/contrib/cl-repro.sh +++ b/contrib/cl-repro.sh @@ -7,25 +7,61 @@ # It automates the process described here: # https://docs.corelightning.org/docs/repro#build-environment-setup # https://docs.corelightning.org/docs/repro#builder-image-setup +# +# ROOTLESS=1 builds without root, for rootless Docker. PLATFORM=linux/arm64 +# builds the arm64 images on an amd64 host, under qemu-user emulation. + +set -e # Assuming script will be used from the root of lightning directory LIGHTNING_DIR=$PWD # Remove '/contrib' from the end if it exists LIGHTNING_DIR=$(echo "$LIGHTNING_DIR" | sed 's|/contrib$||') echo "Lightning Directory: $LIGHTNING_DIR" +# The base image steps delete $LIGHTNING_DIR/ as root. +if [ ! -f "$LIGHTNING_DIR"/contrib/cl-repro.sh ]; then + echo "Run this from the root of the lightning repository" >&2 + exit 1 +fi + +SUDO=sudo +NODEV="" +if [ -n "$ROOTLESS" ]; then + SUDO="" + # A rootless container cannot create device nodes, so skip debootstrap's + # device setup: docker provides /dev when the image runs. Packages are + # still checked against the signed Release file. + NODEV="sed -i -e 's/^check_sane_mount () {/check_sane_mount () { return 0;/' -e 's/^setup_devices () {/setup_devices () { return 0;/' /usr/share/debootstrap/functions &&" +fi +PLAT="" +case "$PLATFORM" in + "") ;; + linux/amd64|linux/arm64) PLAT="--platform $PLATFORM" ;; + *) echo "Unsupported PLATFORM $PLATFORM: use linux/amd64 or linux/arm64" >&2; exit 1 ;; +esac + +# arm64 images are suffixed so both architectures can coexist, and so the +# bin-Ubuntu--arm64 targets resolve. amd64 keeps its bare name. +SUFFIX="" +case "${PLATFORM:-$(uname -m)}" in + linux/arm64|aarch64|arm64) SUFFIX="-arm64" ;; +esac +ROOTFS=$(mktemp -d) for v in jammy noble resolute; do echo "Building base image for $v" - sudo docker run -v "$LIGHTNING_DIR":/build ubuntu:$v \ - bash -c "apt-get update && apt-get install -y debootstrap && debootstrap $v /build/$v" - sudo tar -C $v -c . | sudo docker import - $v + # shellcheck disable=SC2086 + $SUDO docker run --rm $PLAT -v "$LIGHTNING_DIR":/build ubuntu:$v \ + bash -c "rm -rf /build/$v && apt-get update && apt-get install -y debootstrap && $NODEV debootstrap --keyring=/usr/share/keyrings/ubuntu-archive-keyring.gpg $v /build/$v" + # shellcheck disable=SC2086 + $SUDO docker run --rm $PLAT -v "$LIGHTNING_DIR":/build -v "$ROOTFS":/out ubuntu:$v tar -C /build/$v -cf /out/$v.tar . + # shellcheck disable=SC2086 + $SUDO docker import $PLAT "$ROOTFS/$v.tar" $v + $SUDO rm -f "$ROOTFS/$v.tar" echo "$v release:" - sudo docker run ubuntu:$v cat /etc/lsb-release + $SUDO docker run --rm $v cat /etc/lsb-release echo "Building CL repro $v:" - # arm64 images are suffixed so both architectures can coexist, and so the - # bin-Ubuntu--arm64 targets resolve. amd64 keeps its bare name. - SUFFIX="" - [ "$(dpkg --print-architecture)" = arm64 ] && SUFFIX="-arm64" - # shellcheck disable=SC2024 - sudo docker build --no-cache -t cl-repro-$v$SUFFIX - < "$LIGHTNING_DIR"/contrib/reprobuild/Dockerfile.$v + # shellcheck disable=SC2024,SC2086 + $SUDO docker build $PLAT --no-cache -t cl-repro-$v$SUFFIX - < "$LIGHTNING_DIR"/contrib/reprobuild/Dockerfile.$v done +rmdir "$ROOTFS" diff --git a/contrib/reprobuild/Dockerfile.jammy b/contrib/reprobuild/Dockerfile.jammy index ca6478c5f8cc..52eea872f9b8 100644 --- a/contrib/reprobuild/Dockerfile.jammy +++ b/contrib/reprobuild/Dockerfile.jammy @@ -6,6 +6,9 @@ ENV SOURCE_DATE_EPOCH=1672531200 ENV RUST_PROFILE=release ENV PATH=/root/.pyenv/shims:/root/.pyenv/bin:/root/.cargo/bin:/root/.local/bin:$PATH ENV PROTOC_VERSION=29.4 +ENV PYENV_COMMIT=c7eaf99f36d04ddc1b9a9b4faca3b7bf9a296041 +ENV UV_VERSION=0.13.5 +ENV RUST_VERSION=1.85.1 RUN sed -i '/updates/d' /etc/apt/sources.list && \ sed -i '/security/d' /etc/apt/sources.list @@ -32,6 +35,7 @@ RUN apt-get update && \ zip \ && cd /tmp \ && wget https://github.com/kristapsdz/lowdown/archive/refs/tags/VERSION_1_0_2.tar.gz \ + && echo "049b7883874f8a8e528dc7c4ed7b27cf7ceeb9ecf8fe71c3a8d51d574fddf84b VERSION_1_0_2.tar.gz" | sha256sum -c \ && tar -xzf VERSION_1_0_2.tar.gz \ && cd lowdown-VERSION_1_0_2 \ && ./configure \ @@ -48,6 +52,7 @@ RUN chown root:root /usr/libexec/sudo/sudoers.so # Install Python3.10 (more reproducible than relying on python3-setuptools) RUN git clone https://github.com/pyenv/pyenv.git /root/.pyenv && \ + git -C /root/.pyenv checkout --detach ${PYENV_COMMIT} && \ apt-get install -y --no-install-recommends \ libbz2-dev \ libffi-dev \ @@ -58,21 +63,42 @@ RUN git clone https://github.com/pyenv/pyenv.git /root/.pyenv && \ pyenv install 3.10.0 && \ pyenv global 3.10.0 -RUN wget -qO- https://astral.sh/uv/install.sh | sh +# Downloads below are checked against pinned hashes. uv's match the +# .sha256 files published beside them, so they only detect a change since +# pinning, as protoc's and lowdown's do. Rust's match its signed +# channel-rust-${RUST_VERSION}.toml. +RUN cd /tmp/ && \ + case "$(dpkg --print-architecture)" in \ + arm64) UV_ARCH=aarch64 UV_SHA256=4bb69cf95ed13f23713bb7bc09f241896ea0c75b7c557e615a20604b82f9c403 ;; \ + *) UV_ARCH=x86_64 UV_SHA256=f68d291c75783122dad58ab77def0e13f3233f358731db5d6d7e8715603b928f ;; \ + esac && \ + wget https://github.com/astral-sh/uv/releases/download/${UV_VERSION}/uv-${UV_ARCH}-unknown-linux-gnu.tar.gz && \ + echo "${UV_SHA256} uv-${UV_ARCH}-unknown-linux-gnu.tar.gz" | sha256sum -c && \ + tar -xzf uv-${UV_ARCH}-unknown-linux-gnu.tar.gz && \ + mkdir -p /root/.local/bin && \ + mv uv-${UV_ARCH}-unknown-linux-gnu/uv uv-${UV_ARCH}-unknown-linux-gnu/uvx /root/.local/bin/ && \ + rm -rf uv-${UV_ARCH}-unknown-linux-gnu* -RUN wget https://sh.rustup.rs -O rustup-install.sh && \ - bash rustup-install.sh --default-toolchain none --quiet -y && \ - rm rustup-install.sh && \ - /root/.cargo/bin/rustup install 1.85 +RUN cd /tmp/ && \ + case "$(dpkg --print-architecture)" in \ + arm64) RUST_ARCH=aarch64 RUST_SHA256=6945d648b19f62052ee619b05e79e8ab8a2e18b5d5310c6c0899d552669ee61b ;; \ + *) RUST_ARCH=x86_64 RUST_SHA256=912c76f602f5f630138fca2388b2688c2c1aabcf823d71890b2b9155f743792e ;; \ + esac && \ + wget https://static.rust-lang.org/dist/rust-${RUST_VERSION}-${RUST_ARCH}-unknown-linux-gnu.tar.xz && \ + echo "${RUST_SHA256} rust-${RUST_VERSION}-${RUST_ARCH}-unknown-linux-gnu.tar.xz" | sha256sum -c && \ + tar -xJf rust-${RUST_VERSION}-${RUST_ARCH}-unknown-linux-gnu.tar.xz && \ + rust-${RUST_VERSION}-${RUST_ARCH}-unknown-linux-gnu/install.sh --prefix=/usr/local && \ + rm -rf rust-${RUST_VERSION}-${RUST_ARCH}-unknown-linux-gnu* # Download protoc manually, it is in the update repos which we # disabled above, so `apt-get` can't find it anymore. RUN cd /tmp/ && \ case "$(dpkg --print-architecture)" in \ - arm64) PROTOC_ARCH=aarch_64 ;; \ - *) PROTOC_ARCH=x86_64 ;; \ + arm64) PROTOC_ARCH=aarch_64 PROTOC_SHA256=c219a9213a8fa26bc9f644e36e7d756a5b8a7c8a629b60f9d0d1248e59d2fa31 ;; \ + *) PROTOC_ARCH=x86_64 PROTOC_SHA256=3074ee900792fa7bf06ab56bd14af83048016cac08abf2a2ae34aaa571a9c110 ;; \ esac && \ wget https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOC_VERSION}/protoc-${PROTOC_VERSION}-linux-${PROTOC_ARCH}.zip && \ + echo "${PROTOC_SHA256} protoc-${PROTOC_VERSION}-linux-${PROTOC_ARCH}.zip" | sha256sum -c && \ unzip protoc-${PROTOC_VERSION}-linux-${PROTOC_ARCH}.zip && \ mv bin/protoc /usr/local/bin && \ rm -rf include bin protoc-${PROTOC_VERSION}-linux-${PROTOC_ARCH}.zip diff --git a/contrib/reprobuild/Dockerfile.noble b/contrib/reprobuild/Dockerfile.noble index ee64a30e283b..9f8646d3c06c 100644 --- a/contrib/reprobuild/Dockerfile.noble +++ b/contrib/reprobuild/Dockerfile.noble @@ -6,6 +6,9 @@ ENV SOURCE_DATE_EPOCH=1672531200 ENV RUST_PROFILE=release ENV PATH=/root/.pyenv/shims:/root/.pyenv/bin:/root/.cargo/bin:/root/.local/bin:$PATH ENV PROTOC_VERSION=29.4 +ENV PYENV_COMMIT=c7eaf99f36d04ddc1b9a9b4faca3b7bf9a296041 +ENV UV_VERSION=0.13.5 +ENV RUST_VERSION=1.85.1 RUN sed -i '/updates/d' /etc/apt/sources.list && \ sed -i '/security/d' /etc/apt/sources.list && \ @@ -39,6 +42,7 @@ RUN git config --global --add safe.directory /repo/.git # Install Python3.10 (more reproducible than relying on python3-setuptools) RUN git clone https://github.com/pyenv/pyenv.git /root/.pyenv && \ + git -C /root/.pyenv checkout --detach ${PYENV_COMMIT} && \ apt-get install -y --no-install-recommends \ libbz2-dev \ libffi-dev \ @@ -48,21 +52,42 @@ RUN git clone https://github.com/pyenv/pyenv.git /root/.pyenv && \ pyenv install 3.10.0 && \ pyenv global 3.10.0 -RUN wget -qO- https://astral.sh/uv/install.sh | sh +# Downloads below are checked against pinned hashes. uv's match the +# .sha256 files published beside them, so they only detect a change since +# pinning, as protoc's and lowdown's do. Rust's match its signed +# channel-rust-${RUST_VERSION}.toml. +RUN cd /tmp/ && \ + case "$(dpkg --print-architecture)" in \ + arm64) UV_ARCH=aarch64 UV_SHA256=4bb69cf95ed13f23713bb7bc09f241896ea0c75b7c557e615a20604b82f9c403 ;; \ + *) UV_ARCH=x86_64 UV_SHA256=f68d291c75783122dad58ab77def0e13f3233f358731db5d6d7e8715603b928f ;; \ + esac && \ + wget https://github.com/astral-sh/uv/releases/download/${UV_VERSION}/uv-${UV_ARCH}-unknown-linux-gnu.tar.gz && \ + echo "${UV_SHA256} uv-${UV_ARCH}-unknown-linux-gnu.tar.gz" | sha256sum -c && \ + tar -xzf uv-${UV_ARCH}-unknown-linux-gnu.tar.gz && \ + mkdir -p /root/.local/bin && \ + mv uv-${UV_ARCH}-unknown-linux-gnu/uv uv-${UV_ARCH}-unknown-linux-gnu/uvx /root/.local/bin/ && \ + rm -rf uv-${UV_ARCH}-unknown-linux-gnu* -RUN wget https://sh.rustup.rs -O rustup-install.sh && \ - bash rustup-install.sh --default-toolchain none --quiet -y && \ - rm rustup-install.sh && \ - /root/.cargo/bin/rustup install 1.85 +RUN cd /tmp/ && \ + case "$(dpkg --print-architecture)" in \ + arm64) RUST_ARCH=aarch64 RUST_SHA256=6945d648b19f62052ee619b05e79e8ab8a2e18b5d5310c6c0899d552669ee61b ;; \ + *) RUST_ARCH=x86_64 RUST_SHA256=912c76f602f5f630138fca2388b2688c2c1aabcf823d71890b2b9155f743792e ;; \ + esac && \ + wget https://static.rust-lang.org/dist/rust-${RUST_VERSION}-${RUST_ARCH}-unknown-linux-gnu.tar.xz && \ + echo "${RUST_SHA256} rust-${RUST_VERSION}-${RUST_ARCH}-unknown-linux-gnu.tar.xz" | sha256sum -c && \ + tar -xJf rust-${RUST_VERSION}-${RUST_ARCH}-unknown-linux-gnu.tar.xz && \ + rust-${RUST_VERSION}-${RUST_ARCH}-unknown-linux-gnu/install.sh --prefix=/usr/local && \ + rm -rf rust-${RUST_VERSION}-${RUST_ARCH}-unknown-linux-gnu* # Download protoc manually, it is in the update repos which we # disabled above, so `apt-get` can't find it anymore. RUN cd /tmp/ && \ case "$(dpkg --print-architecture)" in \ - arm64) PROTOC_ARCH=aarch_64 ;; \ - *) PROTOC_ARCH=x86_64 ;; \ + arm64) PROTOC_ARCH=aarch_64 PROTOC_SHA256=c219a9213a8fa26bc9f644e36e7d756a5b8a7c8a629b60f9d0d1248e59d2fa31 ;; \ + *) PROTOC_ARCH=x86_64 PROTOC_SHA256=3074ee900792fa7bf06ab56bd14af83048016cac08abf2a2ae34aaa571a9c110 ;; \ esac && \ wget https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOC_VERSION}/protoc-${PROTOC_VERSION}-linux-${PROTOC_ARCH}.zip && \ + echo "${PROTOC_SHA256} protoc-${PROTOC_VERSION}-linux-${PROTOC_ARCH}.zip" | sha256sum -c && \ unzip protoc-${PROTOC_VERSION}-linux-${PROTOC_ARCH}.zip && \ mv bin/protoc /usr/local/bin && \ rm -rf include bin protoc-${PROTOC_VERSION}-linux-${PROTOC_ARCH}.zip diff --git a/contrib/reprobuild/Dockerfile.resolute b/contrib/reprobuild/Dockerfile.resolute index 092e7d6dddf1..55f14cfdb8bc 100644 --- a/contrib/reprobuild/Dockerfile.resolute +++ b/contrib/reprobuild/Dockerfile.resolute @@ -6,6 +6,9 @@ ENV SOURCE_DATE_EPOCH=1672531200 ENV RUST_PROFILE=release ENV PATH=/root/.pyenv/shims:/root/.pyenv/bin:/root/.cargo/bin:/root/.local/bin:$PATH ENV PROTOC_VERSION=29.4 +ENV PYENV_COMMIT=c7eaf99f36d04ddc1b9a9b4faca3b7bf9a296041 +ENV UV_VERSION=0.13.5 +ENV RUST_VERSION=1.85.1 RUN sed -i '/updates/d' /etc/apt/sources.list && \ sed -i '/security/d' /etc/apt/sources.list && \ @@ -39,6 +42,7 @@ RUN git config --global --add safe.directory /repo/.git # Install Python3.10 (more reproducible than relying on python3-setuptools) RUN git clone https://github.com/pyenv/pyenv.git /root/.pyenv && \ + git -C /root/.pyenv checkout --detach ${PYENV_COMMIT} && \ apt-get install -y --no-install-recommends \ libbz2-dev \ libffi-dev \ @@ -48,21 +52,42 @@ RUN git clone https://github.com/pyenv/pyenv.git /root/.pyenv && \ pyenv install 3.10.0 && \ pyenv global 3.10.0 -RUN wget -qO- https://astral.sh/uv/install.sh | sh +# Downloads below are checked against pinned hashes. uv's match the +# .sha256 files published beside them, so they only detect a change since +# pinning, as protoc's and lowdown's do. Rust's match its signed +# channel-rust-${RUST_VERSION}.toml. +RUN cd /tmp/ && \ + case "$(dpkg --print-architecture)" in \ + arm64) UV_ARCH=aarch64 UV_SHA256=4bb69cf95ed13f23713bb7bc09f241896ea0c75b7c557e615a20604b82f9c403 ;; \ + *) UV_ARCH=x86_64 UV_SHA256=f68d291c75783122dad58ab77def0e13f3233f358731db5d6d7e8715603b928f ;; \ + esac && \ + wget https://github.com/astral-sh/uv/releases/download/${UV_VERSION}/uv-${UV_ARCH}-unknown-linux-gnu.tar.gz && \ + echo "${UV_SHA256} uv-${UV_ARCH}-unknown-linux-gnu.tar.gz" | sha256sum -c && \ + tar -xzf uv-${UV_ARCH}-unknown-linux-gnu.tar.gz && \ + mkdir -p /root/.local/bin && \ + mv uv-${UV_ARCH}-unknown-linux-gnu/uv uv-${UV_ARCH}-unknown-linux-gnu/uvx /root/.local/bin/ && \ + rm -rf uv-${UV_ARCH}-unknown-linux-gnu* -RUN wget https://sh.rustup.rs -O rustup-install.sh && \ - bash rustup-install.sh --default-toolchain none --quiet -y && \ - rm rustup-install.sh && \ - /root/.cargo/bin/rustup install 1.85 +RUN cd /tmp/ && \ + case "$(dpkg --print-architecture)" in \ + arm64) RUST_ARCH=aarch64 RUST_SHA256=6945d648b19f62052ee619b05e79e8ab8a2e18b5d5310c6c0899d552669ee61b ;; \ + *) RUST_ARCH=x86_64 RUST_SHA256=912c76f602f5f630138fca2388b2688c2c1aabcf823d71890b2b9155f743792e ;; \ + esac && \ + wget https://static.rust-lang.org/dist/rust-${RUST_VERSION}-${RUST_ARCH}-unknown-linux-gnu.tar.xz && \ + echo "${RUST_SHA256} rust-${RUST_VERSION}-${RUST_ARCH}-unknown-linux-gnu.tar.xz" | sha256sum -c && \ + tar -xJf rust-${RUST_VERSION}-${RUST_ARCH}-unknown-linux-gnu.tar.xz && \ + rust-${RUST_VERSION}-${RUST_ARCH}-unknown-linux-gnu/install.sh --prefix=/usr/local && \ + rm -rf rust-${RUST_VERSION}-${RUST_ARCH}-unknown-linux-gnu* # Download protoc manually, it is in the update repos which we # disabled above, so `apt-get` can't find it anymore. RUN cd /tmp/ && \ case "$(dpkg --print-architecture)" in \ - arm64) PROTOC_ARCH=aarch_64 ;; \ - *) PROTOC_ARCH=x86_64 ;; \ + arm64) PROTOC_ARCH=aarch_64 PROTOC_SHA256=c219a9213a8fa26bc9f644e36e7d756a5b8a7c8a629b60f9d0d1248e59d2fa31 ;; \ + *) PROTOC_ARCH=x86_64 PROTOC_SHA256=3074ee900792fa7bf06ab56bd14af83048016cac08abf2a2ae34aaa571a9c110 ;; \ esac && \ wget https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOC_VERSION}/protoc-${PROTOC_VERSION}-linux-${PROTOC_ARCH}.zip && \ + echo "${PROTOC_SHA256} protoc-${PROTOC_VERSION}-linux-${PROTOC_ARCH}.zip" | sha256sum -c && \ unzip protoc-${PROTOC_VERSION}-linux-${PROTOC_ARCH}.zip && \ mv bin/protoc /usr/local/bin && \ rm -rf include bin protoc-${PROTOC_VERSION}-linux-${PROTOC_ARCH}.zip diff --git a/doc/contribute-to-core-lightning/security-policy.md b/doc/contribute-to-core-lightning/security-policy.md index 6e0d28d3837c..5114d2703b97 100644 --- a/doc/contribute-to-core-lightning/security-policy.md +++ b/doc/contribute-to-core-lightning/security-policy.md @@ -58,3 +58,5 @@ gpg --import privkeyio-signing-key.asc gpg --verify SHA256SUMS-.asc SHA256SUMS- sha256sum -c --ignore-missing SHA256SUMS- ``` + +arm64 tarballs have their own manifest, `SHA256SUMS--arm64`, verified the same way. Releases up to `v26.06.9-blake2b.9` have a single `SHA256SUMS-` covering both. diff --git a/doc/getting-started/advanced-setup/repro.md b/doc/getting-started/advanced-setup/repro.md index 5116ad570056..1a49a7d2ea5a 100644 --- a/doc/getting-started/advanced-setup/repro.md +++ b/doc/getting-started/advanced-setup/repro.md @@ -28,6 +28,8 @@ The build environments are a set of docker images that are created directly from The script `contrib/cl-repro.sh` covers below `Base image creation` and `Builder image setup` steps. You can skip these steps by simply running the `contrib/cl-repro.sh` script. +With rootless Docker, run `ROOTLESS=1 contrib/cl-repro.sh`. A rootless container cannot create device nodes, so this skips debootstrap's device setup; Docker provides `/dev` when the image runs, and packages are still checked against Ubuntu's signed `Release` file. To build the arm64 images on an amd64 host under qemu-user emulation (with `qemu-aarch64` registered in binfmt_misc with the `F` flag), add `PLATFORM=linux/arm64`. Both produce the same tarballs as the default path. + ## Base image creation Depending on the distribution that we want to build for the instructions to create a base image can vary. In the following sections we discuss the specific instructions for each distribution, whereas the instructions are identical again once we have the base image. diff --git a/tests/test_closing.py b/tests/test_closing.py index 06928c6a6053..52aac82dc4ab 100644 --- a/tests/test_closing.py +++ b/tests/test_closing.py @@ -2558,6 +2558,10 @@ def test_onchain_middleman_fulfill_after_fail(node_factory, bitcoind): partid=1, groupid=1) l3.daemon.wait_for_log('holding htlc {}'.format(rhash)) + # A block between the two gives them different deadlines. + bitcoind.generate_block(1) + sync_blockheight(bitcoind, [l1, l2, l3]) + # And it fails this one. l1.rpc.sendpay(l1.single_route(l3.info['id'], amt2), rhash, amount_msat=amt1 + amt2, @@ -2578,9 +2582,12 @@ def test_onchain_middleman_fulfill_after_fail(node_factory, bitcoind): # Now l3 learns the preimage, and spends what it's owed. l3.rpc.releasehtlc(preimage) - _, txid, _ = l3.wait_for_onchaind_tx('OUR_HTLC_SUCCESS_TX', - 'OUR_UNILATERAL/THEIR_HTLC') - bitcoind.generate_block(1, wait_for_mempool=[txid]) + l3.wait_for_onchaind_tx('OUR_HTLC_SUCCESS_TX', + 'OUR_UNILATERAL/THEIR_HTLC') + # Both HTLC claims spend l3's only wallet UTXO, and their deadlines + # differ, so only the higher-feerate one stays in the mempool. Either + # reveals the preimage. + bitcoind.generate_block(1, wait_for_mempool=1) l2.daemon.wait_for_log('THEIR_UNILATERAL/OUR_HTLC gave us preimage') # Both payments must succeed, including the one l3 said it failed. diff --git a/tools/repro-build.armv7.sh b/tools/repro-build.armv7.sh index 5c3b789abfb1..8a3d26c29eab 100755 --- a/tools/repro-build.armv7.sh +++ b/tools/repro-build.armv7.sh @@ -291,8 +291,15 @@ sha256sum -c /tmp/SHASUMS # shellcheck disable=SC2046 $INST $(cut -c66- < /tmp/SHASUMS) +# The hash is for the RUST_VERSION pinned in contrib/reprobuild/Dockerfile.*, +# so bump both together. RUST_TARGET=armv7-unknown-linux-gnueabihf -rustup target add "$RUST_TARGET" +RUST_STD=rust-std-${RUST_VERSION}-${RUST_TARGET} +wget -q -O "/tmp/$RUST_STD.tar.xz" "https://static.rust-lang.org/dist/$RUST_STD.tar.xz" +echo "994c3c192dd312e422ba0008bf97b3f121692658658390882558d34d29927d45 /tmp/$RUST_STD.tar.xz" | sha256sum -c +tar -C /tmp -xJf "/tmp/$RUST_STD.tar.xz" +"/tmp/$RUST_STD/install.sh" --prefix=/usr/local +rm -rf "/tmp/$RUST_STD" "/tmp/$RUST_STD.tar.xz" CARGO_BUILD_TARGET=$RUST_TARGET CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_LINKER=arm-linux-gnueabihf-gcc export CARGO_BUILD_TARGET CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_LINKER