From 63fdb63a8cbb4c1283972a568780b527eee6f031 Mon Sep 17 00:00:00 2001 From: Sean Gilligan Date: Mon, 19 Jan 2026 09:28:19 -0800 Subject: [PATCH 1/6] BaseUtils: remove unnecessary package qualifier --- core/src/main/java/org/bitcoinj/core/internal/BaseUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/org/bitcoinj/core/internal/BaseUtils.java b/core/src/main/java/org/bitcoinj/core/internal/BaseUtils.java index a3d71adc774..02409382269 100644 --- a/core/src/main/java/org/bitcoinj/core/internal/BaseUtils.java +++ b/core/src/main/java/org/bitcoinj/core/internal/BaseUtils.java @@ -55,7 +55,7 @@ public static byte[] base32Decode(String string) { string = sb.toString(); } - return org.bouncycastle.util.encoders.Base32.decode(string); + return Base32.decode(string); } catch (Exception e) { throw new IllegalArgumentException("Invalid Base32 input", e); } From afff6a967c83284683ba5cc339a60b4069622e9e Mon Sep 17 00:00:00 2001 From: Sean Gilligan Date: Mon, 19 Jan 2026 09:29:25 -0800 Subject: [PATCH 2/6] BaseUtils: narrow catch to `DecoderException` from `Exception` --- core/src/main/java/org/bitcoinj/core/internal/BaseUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/org/bitcoinj/core/internal/BaseUtils.java b/core/src/main/java/org/bitcoinj/core/internal/BaseUtils.java index 02409382269..59323d96f59 100644 --- a/core/src/main/java/org/bitcoinj/core/internal/BaseUtils.java +++ b/core/src/main/java/org/bitcoinj/core/internal/BaseUtils.java @@ -56,7 +56,7 @@ public static byte[] base32Decode(String string) { } return Base32.decode(string); - } catch (Exception e) { + } catch (DecoderException e) { throw new IllegalArgumentException("Invalid Base32 input", e); } } From 5ecdf74f7adb803ecc927320b1a881b1befcc383 Mon Sep 17 00:00:00 2001 From: Sean Gilligan Date: Mon, 19 Jan 2026 09:30:10 -0800 Subject: [PATCH 3/6] BaseUtils: remove non-throwing code from try block --- .../org/bitcoinj/core/internal/BaseUtils.java | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/core/src/main/java/org/bitcoinj/core/internal/BaseUtils.java b/core/src/main/java/org/bitcoinj/core/internal/BaseUtils.java index 59323d96f59..4d18e7acfa2 100644 --- a/core/src/main/java/org/bitcoinj/core/internal/BaseUtils.java +++ b/core/src/main/java/org/bitcoinj/core/internal/BaseUtils.java @@ -43,18 +43,17 @@ public static String base32Encode(byte[] bytes) { * Replaces: BaseEncoding.base32().omitPadding().lowerCase().decode(string) */ public static byte[] base32Decode(String string) { - try { - string = string.toUpperCase(Locale.ROOT); - - int padding = (8 - (string.length() % 8)) % 8; - if (padding != 0) { - StringBuilder sb = new StringBuilder(string); - for (int i = 0; i < padding; i++) { - sb.append('='); - } - string = sb.toString(); - } + string = string.toUpperCase(Locale.ROOT); + int padding = (8 - (string.length() % 8)) % 8; + if (padding != 0) { + StringBuilder sb = new StringBuilder(string); + for (int i = 0; i < padding; i++) { + sb.append('='); + } + string = sb.toString(); + } + try { return Base32.decode(string); } catch (DecoderException e) { throw new IllegalArgumentException("Invalid Base32 input", e); From fe7fff9bd3a67006745a77fdd09f851bbb0ee9dc Mon Sep 17 00:00:00 2001 From: Sean Gilligan Date: Mon, 19 Jan 2026 11:27:12 -0800 Subject: [PATCH 4/6] BaseUtils: extract helper method `pad()` from `base32Decode()` --- .../java/org/bitcoinj/core/internal/BaseUtils.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/org/bitcoinj/core/internal/BaseUtils.java b/core/src/main/java/org/bitcoinj/core/internal/BaseUtils.java index 4d18e7acfa2..08c64796035 100644 --- a/core/src/main/java/org/bitcoinj/core/internal/BaseUtils.java +++ b/core/src/main/java/org/bitcoinj/core/internal/BaseUtils.java @@ -44,7 +44,15 @@ public static String base32Encode(byte[] bytes) { */ public static byte[] base32Decode(String string) { string = string.toUpperCase(Locale.ROOT); + string = pad(string); + try { + return Base32.decode(string); + } catch (DecoderException e) { + throw new IllegalArgumentException("Invalid Base32 input", e); + } + } + private static String pad(String string) { int padding = (8 - (string.length() % 8)) % 8; if (padding != 0) { StringBuilder sb = new StringBuilder(string); @@ -53,10 +61,6 @@ public static byte[] base32Decode(String string) { } string = sb.toString(); } - try { - return Base32.decode(string); - } catch (DecoderException e) { - throw new IllegalArgumentException("Invalid Base32 input", e); - } + return string; } } From d285609e0cedc6ef50ab2b143837f717722420c7 Mon Sep 17 00:00:00 2001 From: Sean Gilligan Date: Mon, 19 Jan 2026 11:33:13 -0800 Subject: [PATCH 5/6] BaseUtils: don't mutate `string` parameter Use an effectively final local and nested function calling to eliminate the mutation. --- core/src/main/java/org/bitcoinj/core/internal/BaseUtils.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/bitcoinj/core/internal/BaseUtils.java b/core/src/main/java/org/bitcoinj/core/internal/BaseUtils.java index 08c64796035..f80135b1850 100644 --- a/core/src/main/java/org/bitcoinj/core/internal/BaseUtils.java +++ b/core/src/main/java/org/bitcoinj/core/internal/BaseUtils.java @@ -43,10 +43,9 @@ public static String base32Encode(byte[] bytes) { * Replaces: BaseEncoding.base32().omitPadding().lowerCase().decode(string) */ public static byte[] base32Decode(String string) { - string = string.toUpperCase(Locale.ROOT); - string = pad(string); + String uppercasePadded = pad(string.toUpperCase(Locale.ROOT)); try { - return Base32.decode(string); + return Base32.decode(uppercasePadded); } catch (DecoderException e) { throw new IllegalArgumentException("Invalid Base32 input", e); } From 06463219504a050c24e3df9ca7f0ae3e6b9362e2 Mon Sep 17 00:00:00 2001 From: nadavramon <159230565+nadavramon@users.noreply.github.com> Date: Sat, 10 Jan 2026 17:48:46 +0200 Subject: [PATCH 6/6] TransactionInputTest, ECKeyTest.java, ScriptPatternTest, ScriptTest, DeterministicKeyChainTest, WalletTest: replace usage of Guava `Lists.newArrayList()` with JDK `Arrays.asList()` --- .../bitcoinj/core/TransactionInputTest.java | 4 +-- .../java/org/bitcoinj/crypto/ECKeyTest.java | 3 +-- .../bitcoinj/script/ScriptPatternTest.java | 3 +-- .../java/org/bitcoinj/script/ScriptTest.java | 3 +-- .../wallet/DeterministicKeyChainTest.java | 4 +-- .../java/org/bitcoinj/wallet/WalletTest.java | 25 +++++++++---------- 6 files changed, 19 insertions(+), 23 deletions(-) diff --git a/core/src/test/java/org/bitcoinj/core/TransactionInputTest.java b/core/src/test/java/org/bitcoinj/core/TransactionInputTest.java index 74245f9b124..96a8c2c504f 100644 --- a/core/src/test/java/org/bitcoinj/core/TransactionInputTest.java +++ b/core/src/test/java/org/bitcoinj/core/TransactionInputTest.java @@ -16,7 +16,6 @@ package org.bitcoinj.core; -import com.google.common.collect.Lists; import junitparams.JUnitParamsRunner; import junitparams.Parameters; import org.bitcoinj.base.Address; @@ -37,6 +36,7 @@ import java.nio.Buffer; import java.nio.ByteBuffer; +import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.Random; @@ -106,7 +106,7 @@ public Network network() { @Override public List getOpenTransactionOutputs(List addresses) throws UTXOProviderException { - return Lists.newArrayList(utxo); + return Arrays.asList(utxo); } @Override diff --git a/core/src/test/java/org/bitcoinj/crypto/ECKeyTest.java b/core/src/test/java/org/bitcoinj/crypto/ECKeyTest.java index d460cf8afc5..21f6c3faf82 100644 --- a/core/src/test/java/org/bitcoinj/crypto/ECKeyTest.java +++ b/core/src/test/java/org/bitcoinj/crypto/ECKeyTest.java @@ -17,7 +17,6 @@ package org.bitcoinj.crypto; -import com.google.common.collect.Lists; import org.bitcoinj.base.Address; import org.bitcoinj.base.LegacyAddress; import org.bitcoinj.base.ScriptType; @@ -323,7 +322,7 @@ public void findRecoveryId() { ECKey.ECDSASignature sig = key.sign(hash); key = ECKey.fromPublicOnly(key); - List possibleRecIds = Lists.newArrayList((byte) 0, (byte) 1, (byte) 2, (byte) 3); + List possibleRecIds = Arrays.asList((byte) 0, (byte) 1, (byte) 2, (byte) 3); byte recId = key.findRecoveryId(hash, sig); assertTrue(possibleRecIds.contains(recId)); } diff --git a/core/src/test/java/org/bitcoinj/script/ScriptPatternTest.java b/core/src/test/java/org/bitcoinj/script/ScriptPatternTest.java index 24dbd13f09e..6370f9712fe 100644 --- a/core/src/test/java/org/bitcoinj/script/ScriptPatternTest.java +++ b/core/src/test/java/org/bitcoinj/script/ScriptPatternTest.java @@ -18,7 +18,6 @@ package org.bitcoinj.script; -import com.google.common.collect.Lists; import org.bitcoinj.base.Sha256Hash; import org.bitcoinj.base.internal.ByteUtils; import org.bitcoinj.crypto.DumpedPrivateKey; @@ -35,7 +34,7 @@ import static org.junit.Assert.assertTrue; public class ScriptPatternTest { - private List keys = Lists.newArrayList(ECKey.random(), ECKey.random(), ECKey.random()); + private List keys = Arrays.asList(ECKey.random(), ECKey.random(), ECKey.random()); @Test public void testCreateP2PKHOutputScript() { diff --git a/core/src/test/java/org/bitcoinj/script/ScriptTest.java b/core/src/test/java/org/bitcoinj/script/ScriptTest.java index fe1b11768ee..d1e5e05f481 100644 --- a/core/src/test/java/org/bitcoinj/script/ScriptTest.java +++ b/core/src/test/java/org/bitcoinj/script/ScriptTest.java @@ -28,7 +28,6 @@ import com.fasterxml.jackson.databind.ObjectWriter; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.google.common.collect.Lists; import org.bitcoinj.base.BitcoinNetwork; import org.bitcoinj.base.ScriptType; import org.bitcoinj.base.internal.ByteUtils; @@ -116,7 +115,7 @@ public void testScriptPubKey() { @Test public void testMultiSig() { - List keys = Lists.newArrayList(ECKey.random(), ECKey.random(), ECKey.random()); + List keys = Arrays.asList(ECKey.random(), ECKey.random(), ECKey.random()); assertTrue(ScriptPattern.isSentToMultisig(ScriptBuilder.createMultiSigOutputScript(2, keys))); Script script = ScriptBuilder.createMultiSigOutputScript(3, keys); assertTrue(ScriptPattern.isSentToMultisig(script)); diff --git a/core/src/test/java/org/bitcoinj/wallet/DeterministicKeyChainTest.java b/core/src/test/java/org/bitcoinj/wallet/DeterministicKeyChainTest.java index c67c5dea5e7..4dcd4f37f22 100644 --- a/core/src/test/java/org/bitcoinj/wallet/DeterministicKeyChainTest.java +++ b/core/src/test/java/org/bitcoinj/wallet/DeterministicKeyChainTest.java @@ -17,7 +17,6 @@ package org.bitcoinj.wallet; -import com.google.common.collect.Lists; import org.bitcoinj.base.Network; import org.bitcoinj.base.ScriptType; import org.bitcoinj.base.Address; @@ -50,6 +49,7 @@ import java.security.SecureRandom; import java.time.Instant; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Objects; @@ -375,7 +375,7 @@ public void encryption() throws UnreadableWalletException { // Round-trip to ensure de/serialization works and that we can store two chains and they both deserialize. List serialized = encChain.serializeToProtobuf(); - List doubled = Lists.newArrayListWithExpectedSize(serialized.size() * 2); + List doubled = new ArrayList<>(serialized.size() * 2); doubled.addAll(serialized); doubled.addAll(serialized); final List chains = DeterministicKeyChain.fromProtobuf(doubled, encChain.getKeyCrypter()); diff --git a/core/src/test/java/org/bitcoinj/wallet/WalletTest.java b/core/src/test/java/org/bitcoinj/wallet/WalletTest.java index 7730494f735..8a321f28c3e 100644 --- a/core/src/test/java/org/bitcoinj/wallet/WalletTest.java +++ b/core/src/test/java/org/bitcoinj/wallet/WalletTest.java @@ -17,7 +17,6 @@ package org.bitcoinj.wallet; -import com.google.common.collect.Lists; import junitparams.JUnitParamsRunner; import junitparams.Parameters; import org.bitcoinj.base.BitcoinNetwork; @@ -1019,8 +1018,8 @@ public void doubleSpendWeCreate() throws Exception { FakeTxBuilder.BlockPair blockPair2 = createFakeBlock(blockStore, blockPair0.storedBlock, 2, txA1, txB1); wallet.receiveFromBlock(txA1, blockPair2.storedBlock, AbstractBlockChain.NewBlockType.SIDE_CHAIN, 0); wallet.receiveFromBlock(txB1, blockPair2.storedBlock, AbstractBlockChain.NewBlockType.SIDE_CHAIN, 1); - wallet.reorganize(blockPair0.storedBlock, Lists.newArrayList(blockPair1.storedBlock), - Lists.newArrayList(blockPair2.storedBlock)); + wallet.reorganize(blockPair0.storedBlock, Arrays.asList(blockPair1.storedBlock), + Arrays.asList(blockPair2.storedBlock)); assertSpent(txA1); assertDead(txA2); assertDead(txA3); @@ -1036,8 +1035,8 @@ public void doubleSpendWeCreate() throws Exception { wallet.receiveFromBlock(txA1, blockPair3.storedBlock, AbstractBlockChain.NewBlockType.SIDE_CHAIN, 0); wallet.receiveFromBlock(txB1, blockPair3.storedBlock, AbstractBlockChain.NewBlockType.SIDE_CHAIN, 1); wallet.receiveFromBlock(txC1, blockPair3.storedBlock, AbstractBlockChain.NewBlockType.SIDE_CHAIN, 2); - wallet.reorganize(blockPair0.storedBlock, Lists.newArrayList(blockPair2.storedBlock), - Lists.newArrayList(blockPair3.storedBlock)); + wallet.reorganize(blockPair0.storedBlock, Arrays.asList(blockPair2.storedBlock), + Arrays.asList(blockPair3.storedBlock)); assertSpent(txA1); assertDead(txA2); assertDead(txA3); @@ -1051,8 +1050,8 @@ public void doubleSpendWeCreate() throws Exception { // A reorg: previous block "replaced" by new block containing txB1 FakeTxBuilder.BlockPair blockPair4 = createFakeBlock(blockStore, blockPair0.storedBlock, 2, txB1); wallet.receiveFromBlock(txB1, blockPair4.storedBlock, AbstractBlockChain.NewBlockType.SIDE_CHAIN, 0); - wallet.reorganize(blockPair0.storedBlock, Lists.newArrayList(blockPair3.storedBlock), - Lists.newArrayList(blockPair4.storedBlock)); + wallet.reorganize(blockPair0.storedBlock, Arrays.asList(blockPair3.storedBlock), + Arrays.asList(blockPair4.storedBlock)); assertPending(txA1); assertDead(txA2); assertDead(txA3); @@ -1066,8 +1065,8 @@ public void doubleSpendWeCreate() throws Exception { // A reorg: previous block "replaced" by new block containing txA2 FakeTxBuilder.BlockPair blockPair5 = createFakeBlock(blockStore, blockPair0.storedBlock, 2, txA2); wallet.receiveFromBlock(txA2, blockPair5.storedBlock, AbstractBlockChain.NewBlockType.SIDE_CHAIN, 0); - wallet.reorganize(blockPair0.storedBlock, Lists.newArrayList(blockPair4.storedBlock), - Lists.newArrayList(blockPair5.storedBlock)); + wallet.reorganize(blockPair0.storedBlock, Arrays.asList(blockPair4.storedBlock), + Arrays.asList(blockPair5.storedBlock)); assertDead(txA1); assertUnspent(txA2); assertDead(txA3); @@ -1080,8 +1079,8 @@ public void doubleSpendWeCreate() throws Exception { // A reorg: previous block "replaced" by new empty block FakeTxBuilder.BlockPair blockPair6 = createFakeBlock(blockStore, blockPair0.storedBlock, 2); - wallet.reorganize(blockPair0.storedBlock, Lists.newArrayList(blockPair5.storedBlock), - Lists.newArrayList(blockPair6.storedBlock)); + wallet.reorganize(blockPair0.storedBlock, Arrays.asList(blockPair5.storedBlock), + Arrays.asList(blockPair6.storedBlock)); assertDead(txA1); assertPending(txA2); assertDead(txA3); @@ -1124,8 +1123,8 @@ public void doubleSpendWeReceive() { // A reorg: previous block "replaced" by new block containing doubleSpends.t2 FakeTxBuilder.BlockPair blockPair2 = createFakeBlock(blockStore, blockPair0.storedBlock, 2, doubleSpends.t2); wallet.receiveFromBlock(doubleSpends.t2, blockPair2.storedBlock, AbstractBlockChain.NewBlockType.SIDE_CHAIN, 0); - wallet.reorganize(blockPair0.storedBlock, Lists.newArrayList(blockPair1.storedBlock), - Lists.newArrayList(blockPair2.storedBlock)); + wallet.reorganize(blockPair0.storedBlock, Arrays.asList(blockPair1.storedBlock), + Arrays.asList(blockPair2.storedBlock)); assertDead(doubleSpends.t1); assertSpent(doubleSpends.t2); assertDead(t1b);