From 4cc9e34add68f72b2c042417fb6cea03d2f4eeea Mon Sep 17 00:00:00 2001 From: Sean Gilligan Date: Mon, 16 Mar 2026 17:19:15 -0700 Subject: [PATCH 1/4] package-info.java: add missing package-info to package `o.b.tools` --- .../java/org/bitcoinj/tools/package-info.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 tools/src/main/java/org/bitcoinj/tools/package-info.java diff --git a/tools/src/main/java/org/bitcoinj/tools/package-info.java b/tools/src/main/java/org/bitcoinj/tools/package-info.java new file mode 100644 index 00000000000..03a6eca014e --- /dev/null +++ b/tools/src/main/java/org/bitcoinj/tools/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright by the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * bitcoinj tool utility applications. + */ +package org.bitcoinj.tools; From a57588233bee1c7470f6285551d6b47ce8fc9443 Mon Sep 17 00:00:00 2001 From: Sean Gilligan Date: Mon, 16 Mar 2026 17:22:38 -0700 Subject: [PATCH 2/4] BuildCheckpoints, TestFeeLevel: annotate nullable fields --- tools/src/main/java/org/bitcoinj/tools/BuildCheckpoints.java | 5 +++-- tools/src/main/java/org/bitcoinj/tools/TestFeeLevel.java | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/tools/src/main/java/org/bitcoinj/tools/BuildCheckpoints.java b/tools/src/main/java/org/bitcoinj/tools/BuildCheckpoints.java index df3d9e6b7d4..55d16418eaf 100644 --- a/tools/src/main/java/org/bitcoinj/tools/BuildCheckpoints.java +++ b/tools/src/main/java/org/bitcoinj/tools/BuildCheckpoints.java @@ -32,6 +32,7 @@ import org.bitcoinj.store.MemoryBlockStore; import org.bitcoinj.utils.BriefLogFormatter; import org.bitcoinj.utils.Threading; +import org.jspecify.annotations.Nullable; import picocli.CommandLine; import java.io.File; @@ -66,7 +67,7 @@ public class BuildCheckpoints implements Callable { @CommandLine.Option(names = "--net", description = "Which network to connect to. Valid values: ${COMPLETION-CANDIDATES}. Default: ${DEFAULT-VALUE}") private BitcoinNetwork net = BitcoinNetwork.MAINNET; @CommandLine.Option(names = "--peer", description = "IP address/domain name for connection instead of localhost.") - private String peer = null; + @Nullable private String peer = null; @CommandLine.Option(names = "--days", description = "How many days to keep as a safety margin. Checkpointing will be done up to this many days ago.") private int days = 7; @CommandLine.Option(names = "--verbose", description = "Enables logging.") @@ -74,7 +75,7 @@ public class BuildCheckpoints implements Callable { @CommandLine.Option(names = "--help", usageHelp = true, description = "Displays program options.") private boolean help; - private static NetworkParameters params; + private static @Nullable NetworkParameters params; public static void main(String[] args) throws Exception { int exitCode = new CommandLine(new BuildCheckpoints()).execute(args); diff --git a/tools/src/main/java/org/bitcoinj/tools/TestFeeLevel.java b/tools/src/main/java/org/bitcoinj/tools/TestFeeLevel.java index fa00fce9a09..4bc7157e56a 100644 --- a/tools/src/main/java/org/bitcoinj/tools/TestFeeLevel.java +++ b/tools/src/main/java/org/bitcoinj/tools/TestFeeLevel.java @@ -26,6 +26,7 @@ import org.bitcoinj.wallet.KeyChainGroupStructure; import org.bitcoinj.wallet.SendRequest; import org.bitcoinj.wallet.Wallet; +import org.jspecify.annotations.Nullable; import java.io.File; import java.util.concurrent.ExecutionException; @@ -36,7 +37,7 @@ public class TestFeeLevel { private static final int NUM_OUTPUTS = 2; - private static WalletAppKit kit; + private static @Nullable WalletAppKit kit; public static void main(String[] args) throws Exception { BriefLogFormatter.initWithSilentBitcoinJ(); From e07aa5283b3deb29127307a63ca3c6cc9671f765 Mon Sep 17 00:00:00 2001 From: Sean Gilligan Date: Mon, 16 Mar 2026 17:25:22 -0700 Subject: [PATCH 3/4] BuildCheckpoints, TestFeeLevel: make implicit nullability assumptions explicit --- tools/src/main/java/org/bitcoinj/tools/BuildCheckpoints.java | 5 +++++ tools/src/main/java/org/bitcoinj/tools/TestFeeLevel.java | 2 ++ 2 files changed, 7 insertions(+) diff --git a/tools/src/main/java/org/bitcoinj/tools/BuildCheckpoints.java b/tools/src/main/java/org/bitcoinj/tools/BuildCheckpoints.java index 55d16418eaf..9f65bcd9ac4 100644 --- a/tools/src/main/java/org/bitcoinj/tools/BuildCheckpoints.java +++ b/tools/src/main/java/org/bitcoinj/tools/BuildCheckpoints.java @@ -51,6 +51,7 @@ import java.time.temporal.ChronoUnit; import java.util.Base64; import java.util.List; +import java.util.Objects; import java.util.TreeMap; import java.util.concurrent.Callable; import java.util.concurrent.Future; @@ -91,6 +92,7 @@ public Integer call() throws Exception { final String suffix; params = NetworkParameters.of(net); + Objects.requireNonNull(params); Context.propagate(new Context()); switch (net) { @@ -157,6 +159,7 @@ public Integer call() throws Exception { System.out.println("Checkpointing up to " + TimeUtils.dateTimeFormat(timeAgo)); chain.addNewBestBlockListener(Threading.SAME_THREAD, block -> { + Objects.requireNonNull(params); int height = block.getHeight(); if (height % params.getInterval() == 0 && timeAgo.isAfter(block.getHeader().time())) { System.out.println(String.format("Checkpointing block %s at height %d, time %s", @@ -211,6 +214,7 @@ private static void writeTextualCheckpoints(TreeMap checkp } private static void sanityCheck(File file, int expectedSize) throws IOException { + Objects.requireNonNull(params); FileInputStream fis = new FileInputStream(file); CheckpointManager manager; try { @@ -240,6 +244,7 @@ private static void sanityCheck(File file, int expectedSize) throws IOException } private static void startPeerGroup(PeerGroup peerGroup, InetAddress ipAddress) { + Objects.requireNonNull(params); final PeerAddress peerAddress = PeerAddress.simple(ipAddress, params.getPort()); System.out.println("Connecting to " + peerAddress + "..."); peerGroup.addAddress(peerAddress); diff --git a/tools/src/main/java/org/bitcoinj/tools/TestFeeLevel.java b/tools/src/main/java/org/bitcoinj/tools/TestFeeLevel.java index 4bc7157e56a..3302a431f92 100644 --- a/tools/src/main/java/org/bitcoinj/tools/TestFeeLevel.java +++ b/tools/src/main/java/org/bitcoinj/tools/TestFeeLevel.java @@ -29,6 +29,7 @@ import org.jspecify.annotations.Nullable; import java.io.File; +import java.util.Objects; import java.util.concurrent.ExecutionException; /** @@ -61,6 +62,7 @@ public static void main(String[] args) throws Exception { } private static void go(Coin feeRateToTest, int numOutputs) throws InterruptedException, ExecutionException, InsufficientMoneyException { + Objects.requireNonNull(kit); System.out.println("Wallet has " + kit.wallet().getBalance().toFriendlyString() + "; current receive address is " + kit.wallet().currentReceiveAddress()); From b753a6e2209e5c6232024e920379a6aa44e86c42 Mon Sep 17 00:00:00 2001 From: Sean Gilligan Date: Mon, 16 Mar 2026 17:26:29 -0700 Subject: [PATCH 4/4] package-info.java: declare nullness expectations for package `o.b.tools` --- tools/src/main/java/org/bitcoinj/tools/package-info.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/src/main/java/org/bitcoinj/tools/package-info.java b/tools/src/main/java/org/bitcoinj/tools/package-info.java index 03a6eca014e..2f1ff2d79c1 100644 --- a/tools/src/main/java/org/bitcoinj/tools/package-info.java +++ b/tools/src/main/java/org/bitcoinj/tools/package-info.java @@ -17,4 +17,7 @@ /** * bitcoinj tool utility applications. */ +@NullMarked package org.bitcoinj.tools; + +import org.jspecify.annotations.NullMarked;