diff --git a/core/src/main/java/org/bitcoinj/core/PeerAddress.java b/core/src/main/java/org/bitcoinj/core/PeerAddress.java
index 825ddb3b355..8adfede0991 100644
--- a/core/src/main/java/org/bitcoinj/core/PeerAddress.java
+++ b/core/src/main/java/org/bitcoinj/core/PeerAddress.java
@@ -46,7 +46,7 @@
* A PeerAddress holds an IP address and port number representing the network location of
* a peer in the Bitcoin P2P network. It exists primarily for serialization purposes.
*
- * Instances of this class are not safe for use by multiple threads.
+ * This class is immutable and thread-safe.
*/
public class PeerAddress {
@Nullable
diff --git a/core/src/main/java/org/bitcoinj/core/Transaction.java b/core/src/main/java/org/bitcoinj/core/Transaction.java
index 1705f7d0cbb..cf48b06b647 100644
--- a/core/src/main/java/org/bitcoinj/core/Transaction.java
+++ b/core/src/main/java/org/bitcoinj/core/Transaction.java
@@ -18,7 +18,6 @@
package org.bitcoinj.core;
import com.google.common.base.MoreObjects;
-import com.google.common.math.IntMath;
import org.bitcoinj.base.Address;
import org.bitcoinj.base.Coin;
import org.bitcoinj.base.Network;
@@ -151,6 +150,22 @@ private static int sortableBlockHeight(Transaction tx) {
*/
public static final Coin DEFAULT_TX_FEE = Coin.valueOf(100_000); // 1 mBTC
+ /**
+ * The scale factor for Witness data in Segregated Witness transactions.
+ * @see BIP 141
+ */
+ public static final int WITNESS_SCALE_FACTOR = 4;
+
+ /**
+ * Virtual transaction size is defined as Transaction weight / 4 (rounded up to the next integer).
+ * @param weight the transaction weight
+ * @return the virtual transaction size
+ * @see BIP 141
+ */
+ public static int calculateVirtualTransactionSize(int weight) {
+ return (weight + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR; // round up
+ }
+
private final int protocolVersion;
// These are bitcoin serialized.
@@ -397,7 +412,7 @@ public int getWeight() {
public int getVsize() {
if (!hasWitnesses())
return this.messageSize();
- return IntMath.divide(getWeight(), 4, RoundingMode.CEILING); // round up
+ return calculateVirtualTransactionSize(getWeight());
}
diff --git a/core/src/main/java/org/bitcoinj/core/TransactionConfidence.java b/core/src/main/java/org/bitcoinj/core/TransactionConfidence.java
index 358900b8d17..15400bc30a2 100644
--- a/core/src/main/java/org/bitcoinj/core/TransactionConfidence.java
+++ b/core/src/main/java/org/bitcoinj/core/TransactionConfidence.java
@@ -18,7 +18,6 @@
package org.bitcoinj.core;
import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.Iterators;
import org.bitcoinj.base.Sha256Hash;
import org.bitcoinj.base.internal.TimeUtils;
import org.bitcoinj.utils.ListenerRegistration;
@@ -328,9 +327,7 @@ public int numBroadcastPeers() {
* Returns a snapshot of {@link PeerAddress}es that announced the transaction.
*/
public Set getBroadcastBy() {
- Set broadcastBySet = new HashSet<>();
- Iterators.addAll(broadcastBySet, broadcastBy.listIterator());
- return broadcastBySet;
+ return Collections.unmodifiableSet(new HashSet<>(broadcastBy));
}
/** Returns true if the given address has been seen via markBroadcastBy() */
diff --git a/core/src/main/java/org/bitcoinj/crypto/DeterministicKey.java b/core/src/main/java/org/bitcoinj/crypto/DeterministicKey.java
index 1f7345beb09..6ba81818c0f 100644
--- a/core/src/main/java/org/bitcoinj/crypto/DeterministicKey.java
+++ b/core/src/main/java/org/bitcoinj/crypto/DeterministicKey.java
@@ -720,17 +720,6 @@ public void clearCreationTime() {
super.clearCreationTime();
}
- /** @deprecated use {@link #setCreationTime(Instant)} */
- @Deprecated
- public void setCreationTimeSeconds(long creationTimeSecs) {
- if (creationTimeSecs > 0)
- setCreationTime(Instant.ofEpochSecond(creationTimeSecs));
- else if (creationTimeSecs == 0)
- clearCreationTime();
- else
- throw new IllegalArgumentException("Cannot set creation time to negative value: " + creationTimeSecs);
- }
-
/**
* Verifies equality of all fields but NOT the parent pointer (thus the same key derived in two separate hierarchy
* objects will equal each other.
diff --git a/core/src/main/java/org/bitcoinj/crypto/ECKey.java b/core/src/main/java/org/bitcoinj/crypto/ECKey.java
index d13a6b7e16a..b35fa65cca8 100644
--- a/core/src/main/java/org/bitcoinj/crypto/ECKey.java
+++ b/core/src/main/java/org/bitcoinj/crypto/ECKey.java
@@ -1130,17 +1130,6 @@ public void clearCreationTime() {
this.creationTime = null;
}
- /** @deprecated use {@link #setCreationTime(Instant)} */
- @Deprecated
- public void setCreationTimeSeconds(long creationTimeSecs) {
- if (creationTimeSecs > 0)
- setCreationTime(Instant.ofEpochSecond(creationTimeSecs));
- else if (creationTimeSecs == 0)
- clearCreationTime();
- else
- throw new IllegalArgumentException("Cannot set creation time to negative value: " + creationTimeSecs);
- }
-
/**
* Create an encrypted private key with the keyCrypter and the AES key supplied.
* This method returns a new encrypted key and leaves the original unchanged.
diff --git a/core/src/main/java/org/bitcoinj/wallet/Wallet.java b/core/src/main/java/org/bitcoinj/wallet/Wallet.java
index 8796c34fc65..55b25a2e07b 100644
--- a/core/src/main/java/org/bitcoinj/wallet/Wallet.java
+++ b/core/src/main/java/org/bitcoinj/wallet/Wallet.java
@@ -19,7 +19,6 @@
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ArrayListMultimap;
-import com.google.common.math.IntMath;
import com.google.protobuf.ByteString;
import org.bitcoinj.core.internal.GuardedBy;
import org.bitcoinj.base.BitcoinNetwork;
@@ -5367,8 +5366,7 @@ private int estimateVirtualBytesForSigning(Script script) {
} else if (ScriptPattern.isP2WPKH(script)) {
ECKey key = findKeyFromPubKeyHash(ScriptPattern.extractHashFromP2WH(script), ScriptType.P2WPKH);
Objects.requireNonNull(key, "Coin selection includes unspendable outputs");
- return IntMath.divide(script.getNumberOfBytesRequiredToSpend(key, null), 4,
- RoundingMode.CEILING); // round up
+ return Transaction.calculateVirtualTransactionSize(script.getNumberOfBytesRequiredToSpend(key, null));
} else if (ScriptPattern.isP2SH(script)) {
Script redeemScript = findRedeemDataFromScriptHash(ScriptPattern.extractHashFromP2SH(script)).redeemScript;
Objects.requireNonNull(redeemScript, "Coin selection includes unspendable outputs");
diff --git a/core/src/test/java/org/bitcoinj/core/BitcoinSerializerTest.java b/core/src/test/java/org/bitcoinj/core/BitcoinSerializerTest.java
index e8ccaafe263..c3e83a7d5cd 100644
--- a/core/src/test/java/org/bitcoinj/core/BitcoinSerializerTest.java
+++ b/core/src/test/java/org/bitcoinj/core/BitcoinSerializerTest.java
@@ -17,7 +17,6 @@
package org.bitcoinj.core;
-import com.google.common.io.BaseEncoding;
import org.bitcoinj.base.internal.ByteUtils;
import org.bitcoinj.base.internal.TimeUtils;
import org.bitcoinj.params.MainNetParams;
@@ -40,12 +39,11 @@
import static org.junit.Assert.assertTrue;
public class BitcoinSerializerTest {
- private static final BaseEncoding HEX = BaseEncoding.base16().lowerCase();
private static final NetworkParameters MAINNET = MainNetParams.get();
private static final byte[] ADDRESS_MESSAGE_BYTES = ByteUtils.parseHex("f9beb4d96164647200000000000000001f000000" +
"ed52399b01e215104d010000000000000000000000000000000000ffff0a000001208d");
- private static final byte[] TRANSACTION_MESSAGE_BYTES = HEX.withSeparator(" ", 2).decode(
+ private static final byte[] TRANSACTION_MESSAGE_BYTES = ByteUtils.parseHex((
"f9 be b4 d9 74 78 00 00 00 00 00 00 00 00 00 00" +
"02 01 00 00 e2 93 cd be 01 00 00 00 01 6d bd db" +
"08 5b 1d 8a f7 51 84 f0 bc 01 fa d5 8d 12 66 e9" +
@@ -63,7 +61,7 @@ public class BitcoinSerializerTest {
"cd 1c be a6 e7 45 8a 7a ba d5 12 a9 d9 ea 1a fb" +
"22 5e 88 ac 80 fa e9 c7 00 00 00 00 19 76 a9 14" +
"0e ab 5b ea 43 6a 04 84 cf ab 12 48 5e fd a0 b7" +
- "8b 4e cc 52 88 ac 00 00 00 00");
+ "8b 4e cc 52 88 ac 00 00 00 00").replaceAll("\\s", ""));
@Test
public void testAddr() throws Exception {
diff --git a/core/src/test/java/org/bitcoinj/core/SendHeadersMessageTest.java b/core/src/test/java/org/bitcoinj/core/SendHeadersMessageTest.java
index eafac639de0..e7cba189735 100644
--- a/core/src/test/java/org/bitcoinj/core/SendHeadersMessageTest.java
+++ b/core/src/test/java/org/bitcoinj/core/SendHeadersMessageTest.java
@@ -16,8 +16,8 @@
package org.bitcoinj.core;
-import com.google.common.io.BaseEncoding;
import org.bitcoinj.base.BitcoinNetwork;
+import org.bitcoinj.base.internal.ByteUtils;
import org.junit.Test;
import java.nio.ByteBuffer;
@@ -25,12 +25,11 @@
import static org.junit.Assert.assertTrue;
public class SendHeadersMessageTest {
- private static final BaseEncoding HEX = BaseEncoding.base16().lowerCase();
@Test
public void decodeAndEncode() throws Exception {
- byte[] message = HEX
- .decode("00000000fabfb5da73656e646865616465727300000000005df6e0e2fabfb5da70696e670000000000000000080000009a"
+ byte[] message = ByteUtils.parseHex(
+ "00000000fabfb5da73656e646865616465727300000000005df6e0e2fabfb5da70696e670000000000000000080000009a"
+ "65b9cc9840c9729e4502b200000000000000000000000000000d000000000000000000000000000000000000000000000000007ad82"
+ "872c28ac782102f5361746f7368693a302e31342e312fe41d000001fabfb5da76657261636b000000000000000000005df6e0e2fabf"
+ "b5da616c65727400000000000000a80000001bf9aaea60010000000000000000000000ffffff7f00000000ffffff7ffeffff7f01fff"
diff --git a/core/src/test/java/org/bitcoinj/wallet/BasicKeyChainTest.java b/core/src/test/java/org/bitcoinj/wallet/BasicKeyChainTest.java
index fb1cac93927..507c41e0b9e 100644
--- a/core/src/test/java/org/bitcoinj/wallet/BasicKeyChainTest.java
+++ b/core/src/test/java/org/bitcoinj/wallet/BasicKeyChainTest.java
@@ -32,7 +32,6 @@
import java.time.Duration;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -74,7 +73,7 @@ public void importKeys() {
final ECKey key1 = ECKey.random();
TimeUtils.rollMockClock(Duration.ofDays(1));
final ECKey key2 = ECKey.random();
- final ArrayList keys = Lists.newArrayList(key1, key2);
+ final List keys = Lists.newArrayList(key1, key2);
// Import two keys, check the event is correct.
assertEquals(2, chain.importKeys(keys));
@@ -84,11 +83,11 @@ public void importKeys() {
assertEquals(now, chain.earliestKeyCreationTime());
// Check we ignore duplicates.
final ECKey newKey = ECKey.random();
- keys.add(newKey);
- assertEquals(1, chain.importKeys(keys));
+ final List keys2 = Lists.newArrayList(key1, key2, newKey);
+ assertEquals(1, chain.importKeys(keys2));
assertTrue(onKeysAddedRan.getAndSet(false));
assertEquals(newKey, onKeysAdded.getAndSet(null).get(0));
- assertEquals(0, chain.importKeys(keys));
+ assertEquals(0, chain.importKeys(keys2));
assertFalse(onKeysAddedRan.getAndSet(false));
assertNull(onKeysAdded.get());
@@ -126,14 +125,14 @@ public void checkPasswordNoKeys() {
@Test(expected = IllegalStateException.class)
public void checkPasswordNotEncrypted() {
- final ArrayList keys = Lists.newArrayList(ECKey.random(), ECKey.random());
+ final List keys = Lists.newArrayList(ECKey.random(), ECKey.random());
chain.importKeys(keys);
chain.checkPassword("test");
}
@Test(expected = IllegalStateException.class)
public void doubleEncryptFails() {
- final ArrayList keys = Lists.newArrayList(ECKey.random(), ECKey.random());
+ final List keys = Lists.newArrayList(ECKey.random(), ECKey.random());
chain.importKeys(keys);
chain = chain.toEncrypted("foo");
chain.toEncrypted("foo");