ProtocolVersion: move to top-level class from NetworkParameters

* Rename `getBitcoinProtocolVersion()` to `intValue()`
* Deprecate `NetworkParameters.getProtocolVersionNum()`. This eliminates
  what seems to be an unnecessary level of indirection.
* Add tests.

This will also help eliminate a dependency on `NetworkParameters` in some places.
This commit is contained in:
Sean Gilligan 2023-04-09 13:18:31 -07:00 committed by Andreas Schildbach
parent 414bcf8b6c
commit 4b9981015c
16 changed files with 169 additions and 59 deletions

View file

@ -86,7 +86,7 @@ public class BitcoinSerializer extends MessageSerializer {
* @param params networkParams used to create Messages instances and determining packetMagic
*/
public BitcoinSerializer(NetworkParameters params) {
this(params, params.getProtocolVersionNum(NetworkParameters.ProtocolVersion.CURRENT));
this(params, ProtocolVersion.CURRENT.intValue());
}
/**

View file

@ -135,7 +135,7 @@ public class Block extends Message {
/** Special case constructor, used for the genesis node, cloneAsHeader and unit tests. */
Block(long setVersion) {
super(new DummySerializer(NetworkParameters.ProtocolVersion.CURRENT.getBitcoinProtocolVersion()));
super(new DummySerializer(ProtocolVersion.CURRENT.intValue()));
// Set up a few basic things. We are not complete after this though.
version = setVersion;
difficultyTarget = 0x1d07fff8L;
@ -149,7 +149,7 @@ public class Block extends Message {
* @throws ProtocolException
*/
public Block(ByteBuffer payload) throws ProtocolException {
super(payload, new DummySerializer(NetworkParameters.ProtocolVersion.CURRENT.getBitcoinProtocolVersion()));
super(payload, new DummySerializer(ProtocolVersion.CURRENT.intValue()));
}
/**

View file

@ -550,26 +550,11 @@ public abstract class NetworkParameters {
return verifyFlags;
}
public abstract int getProtocolVersionNum(final ProtocolVersion version);
public static enum ProtocolVersion {
MINIMUM(70000),
/**
* @deprecated use {@link ProtocolVersion#intValue()}
*/
@Deprecated
PONG(60001),
BLOOM_FILTER(70001), // BIP37
BLOOM_FILTER_BIP111(70011), // BIP111
WITNESS_VERSION(70012),
FEEFILTER(70013), // BIP133
CURRENT(70013);
private final int bitcoinProtocol;
ProtocolVersion(final int bitcoinProtocol) {
this.bitcoinProtocol = bitcoinProtocol;
}
public int getBitcoinProtocolVersion() {
return bitcoinProtocol;
}
public int getProtocolVersionNum(final ProtocolVersion version) {
return version.intValue();
}
}

View file

@ -245,7 +245,7 @@ public class Peer extends PeerSocketHandler {
this.getAddrFutures = new LinkedList<>();
this.fastCatchupTime = params.getGenesisBlock().time();
this.pendingPings = new CopyOnWriteArrayList<>();
this.vMinProtocolVersion = params.getProtocolVersionNum(NetworkParameters.ProtocolVersion.MINIMUM);
this.vMinProtocolVersion = ProtocolVersion.MINIMUM.intValue();
this.wallets = new CopyOnWriteArrayList<>();
this.context = Context.get();
@ -1817,8 +1817,8 @@ public class Peer extends PeerSocketHandler {
*/
private boolean isBloomFilteringSupported(VersionMessage version) {
int clientVersion = version.clientVersion();
if (clientVersion >= params.getProtocolVersionNum(NetworkParameters.ProtocolVersion.BLOOM_FILTER)
&& clientVersion < params.getProtocolVersionNum(NetworkParameters.ProtocolVersion.BLOOM_FILTER_BIP111))
if (clientVersion >= ProtocolVersion.BLOOM_FILTER.intValue()
&& clientVersion < ProtocolVersion.BLOOM_FILTER_BIP111.intValue())
return true;
if (version.services().has(Services.NODE_BLOOM))
return true;

View file

@ -475,7 +475,7 @@ public class PeerGroup implements TransactionBroadcaster {
peerDiscoverers = new CopyOnWriteArraySet<>();
runningBroadcasts = Collections.synchronizedSet(new HashSet<TransactionBroadcast>());
bloomFilterMerger = new FilterMerger(DEFAULT_BLOOM_FILTER_FP_RATE);
vMinRequiredProtocolVersion = params.getProtocolVersionNum(NetworkParameters.ProtocolVersion.BLOOM_FILTER);
vMinRequiredProtocolVersion = ProtocolVersion.BLOOM_FILTER.intValue();
}
private CountDownLatch executorStartupLatch = new CountDownLatch(1);
@ -2379,7 +2379,7 @@ public class PeerGroup implements TransactionBroadcaster {
// Only select peers that announce the minimum protocol and services and that we think is fully synchronized.
List<Peer> candidates = new LinkedList<>();
int highestPriority = Integer.MIN_VALUE;
final int MINIMUM_VERSION = params.getProtocolVersionNum(NetworkParameters.ProtocolVersion.WITNESS_VERSION);
final int MINIMUM_VERSION = ProtocolVersion.WITNESS_VERSION.intValue();
for (Peer peer : peers) {
final VersionMessage versionMessage = peer.getPeerVersionMessage();
if (versionMessage.clientVersion < MINIMUM_VERSION)

View file

@ -0,0 +1,51 @@
/*
* 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.
*/
package org.bitcoinj.core;
/**
* Define important versions of the Bitcoin Protocol
*/
public enum ProtocolVersion {
MINIMUM(70000),
@Deprecated
PONG(60001),
BLOOM_FILTER(70001), // BIP37
BLOOM_FILTER_BIP111(70011), // BIP111
WITNESS_VERSION(70012),
FEEFILTER(70013), // BIP133
CURRENT(70013);
private final int bitcoinProtocol;
ProtocolVersion(final int bitcoinProtocol) {
this.bitcoinProtocol = bitcoinProtocol;
}
/**
* @return protocol version as an integer value
*/
public int intValue() {
return bitcoinProtocol;
}
/**
* @deprecated Use {@link #intValue()}
*/
@Deprecated
public int getBitcoinProtocolVersion() {
return intValue();
}
}

View file

@ -71,7 +71,7 @@ import java.util.TreeMap;
import static org.bitcoinj.base.internal.Preconditions.checkArgument;
import static org.bitcoinj.base.internal.Preconditions.checkState;
import static org.bitcoinj.core.NetworkParameters.ProtocolVersion.WITNESS_VERSION;
import static org.bitcoinj.core.ProtocolVersion.WITNESS_VERSION;
import static org.bitcoinj.base.internal.ByteUtils.writeInt32LE;
import static org.bitcoinj.base.internal.ByteUtils.writeInt64LE;
@ -243,7 +243,7 @@ public class Transaction extends Message {
}
public Transaction() {
super(new DummySerializer(NetworkParameters.ProtocolVersion.CURRENT.getBitcoinProtocolVersion()));
super(new DummySerializer(ProtocolVersion.CURRENT.intValue()));
version = 1;
inputs = new ArrayList<>();
outputs = new ArrayList<>();
@ -255,7 +255,7 @@ public class Transaction extends Message {
* Creates a transaction from the given serialized bytes, eg, from a block or a tx network message.
*/
public Transaction(ByteBuffer payload) throws ProtocolException {
super(payload, new DummySerializer(NetworkParameters.ProtocolVersion.CURRENT.getBitcoinProtocolVersion()));
super(payload, new DummySerializer(ProtocolVersion.CURRENT.intValue()));
// inputs/outputs will be created in parse()
}
@ -295,7 +295,7 @@ public class Transaction extends Message {
*/
private static boolean allowWitness(int protocolVersion) {
return (protocolVersion & SERIALIZE_TRANSACTION_NO_WITNESS) == 0
&& protocolVersion >= WITNESS_VERSION.getBitcoinProtocolVersion();
&& protocolVersion >= WITNESS_VERSION.intValue();
}
/**

View file

@ -100,7 +100,7 @@ public class VersionMessage extends Message {
* @param bestHeight our best height to announce
*/
public VersionMessage(NetworkParameters params, int bestHeight) {
this.clientVersion = params.getProtocolVersionNum(NetworkParameters.ProtocolVersion.CURRENT);
this.clientVersion = ProtocolVersion.CURRENT.intValue();
this.localServices = Services.none();
this.time = TimeUtils.currentTime().truncatedTo(ChronoUnit.SECONDS);
// Note that the Bitcoin Core doesn't do anything with these, and finding out your own external IP address
@ -147,7 +147,7 @@ public class VersionMessage extends Message {
@Override
protected void parse(ByteBuffer payload) throws BufferUnderflowException, ProtocolException {
clientVersion = (int) ByteUtils.readUint32(payload);
check(clientVersion >= NetworkParameters.ProtocolVersion.MINIMUM.getBitcoinProtocolVersion(),
check(clientVersion >= ProtocolVersion.MINIMUM.intValue(),
ProtocolException::new);
localServices = Services.read(payload);
time = Instant.ofEpochSecond(ByteUtils.readInt64(payload));
@ -163,7 +163,7 @@ public class VersionMessage extends Message {
// int bestHeight (size of known block chain).
bestHeight = ByteUtils.readUint32(payload);
relayTxesBeforeFilter =
clientVersion >= NetworkParameters.ProtocolVersion.BLOOM_FILTER.getBitcoinProtocolVersion() ?
clientVersion >= ProtocolVersion.BLOOM_FILTER.intValue() ?
payload.get() != 0 :
true;
}

View file

@ -26,6 +26,7 @@ import org.bitcoinj.core.Block;
import org.bitcoinj.base.Coin;
import org.bitcoinj.core.NetworkParameters;
import org.bitcoinj.base.Sha256Hash;
import org.bitcoinj.core.ProtocolVersion;
import org.bitcoinj.core.StoredBlock;
import org.bitcoinj.core.VerificationException;
import org.bitcoinj.protocols.payments.PaymentProtocol;
@ -247,11 +248,6 @@ public abstract class BitcoinNetworkParams extends NetworkParameters {
return new MonetaryFormat();
}
@Override
public int getProtocolVersionNum(final ProtocolVersion version) {
return version.getBitcoinProtocolVersion();
}
@Override
public BitcoinSerializer getSerializer() {
return new BitcoinSerializer(this);

View file

@ -77,9 +77,4 @@ public class MockAltNetworkParams extends NetworkParameters {
public BitcoinSerializer getSerializer() {
return null;
}
@Override
public int getProtocolVersionNum(ProtocolVersion version) {
return 0;
}
}

View file

@ -57,9 +57,7 @@ public class CheckpointManagerTest {
public void canReadTextualStream() throws IOException {
expect(params.getId()).andReturn("org/bitcoinj/core/checkpointmanagertest/validTextualFormat");
expect(params.getSerializer()).andReturn(
new BitcoinSerializer(params, NetworkParameters.ProtocolVersion.CURRENT.getBitcoinProtocolVersion()));
expect(params.getProtocolVersionNum(NetworkParameters.ProtocolVersion.CURRENT))
.andReturn(NetworkParameters.ProtocolVersion.CURRENT.getBitcoinProtocolVersion());
new BitcoinSerializer(params, ProtocolVersion.CURRENT.intValue()));
replay(params);
new CheckpointManager(params, null);
}

View file

@ -0,0 +1,33 @@
/*
* 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.
*/
package org.bitcoinj.core;
import org.bitcoinj.base.BitcoinNetwork;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
/**
* Test NetworkParameters
*/
public class NetworkParametersTest {
@Test
public void deprecatedMembers() {
NetworkParameters params = NetworkParameters.of(BitcoinNetwork.MAINNET);
assertEquals(70000, params.getProtocolVersionNum(ProtocolVersion.MINIMUM));
}
}

View file

@ -0,0 +1,52 @@
/*
* 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.
*/
package org.bitcoinj.core;
import junitparams.JUnitParamsRunner;
import junitparams.Parameters;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
/**
* Test ProtocolVersion
*/
@RunWith(JUnitParamsRunner.class)
public class ProtocolVersionTest {
@Test
@Parameters(method = "allInstances")
public void testValues(ProtocolVersion instance) {
assertTrue(instance.intValue() > 0);
}
@Test
@Parameters(method = "allInstances")
public void deprecatedMembers(ProtocolVersion instance) {
assertEquals(instance.intValue(), instance.getBitcoinProtocolVersion());
}
@Test
public void deprecatedInstance() {
assertEquals(60001, ProtocolVersion.PONG.intValue());
}
private ProtocolVersion[] allInstances() {
return ProtocolVersion.values();
}
}

View file

@ -79,7 +79,7 @@ public class VersionMessageTest {
assertEquals(1234, ver2.bestHeight);
assertEquals(Instant.ofEpochSecond(23456), ver2.time);
assertEquals("/bitcoinj/", ver2.subVer);
assertEquals(NetworkParameters.ProtocolVersion.CURRENT.getBitcoinProtocolVersion(), ver2.clientVersion);
assertEquals(ProtocolVersion.CURRENT.intValue(), ver2.clientVersion);
assertEquals(1, ver2.localServices.bits());
assertEquals("1.2.3.4", ver2.fromAddr.getAddr().getHostAddress());
assertEquals(3888, ver2.fromAddr.getPort());
@ -100,7 +100,7 @@ public class VersionMessageTest {
assertEquals(1234, ver2.bestHeight);
assertEquals(Instant.ofEpochSecond(23456), ver2.time);
assertEquals("/bitcoinj/", ver2.subVer);
assertEquals(NetworkParameters.ProtocolVersion.CURRENT.getBitcoinProtocolVersion(), ver2.clientVersion);
assertEquals(ProtocolVersion.CURRENT.intValue(), ver2.clientVersion);
assertEquals(1, ver2.localServices.bits());
assertEquals("2001:db8:85a3:0:0:8a2e:370:7334", ver2.fromAddr.getAddr().getHostAddress());
assertEquals(3888, ver2.fromAddr.getPort());

View file

@ -457,7 +457,7 @@ public class PeerGroupTest extends TestWithPeerGroup {
peerGroup.start();
peerGroup.setPingIntervalMsec(0);
VersionMessage versionMessage = new VersionMessage(UNITTEST, 2);
versionMessage.clientVersion = NetworkParameters.ProtocolVersion.BLOOM_FILTER.getBitcoinProtocolVersion();
versionMessage.clientVersion = ProtocolVersion.BLOOM_FILTER.intValue();
versionMessage.localServices = Services.of(Services.NODE_NETWORK);
connectPeer(1, versionMessage);
peerGroup.waitForPeers(1).get();
@ -469,7 +469,7 @@ public class PeerGroupTest extends TestWithPeerGroup {
peerGroup.start();
peerGroup.setPingIntervalMsec(100);
VersionMessage versionMessage = new VersionMessage(UNITTEST, 2);
versionMessage.clientVersion = NetworkParameters.ProtocolVersion.BLOOM_FILTER.getBitcoinProtocolVersion();
versionMessage.clientVersion = ProtocolVersion.BLOOM_FILTER.intValue();
versionMessage.localServices = Services.of(Services.NODE_NETWORK);
InboundMessageQueuer p1 = connectPeer(1, versionMessage);
Ping ping = (Ping) waitForOutbound(p1);
@ -486,10 +486,10 @@ public class PeerGroupTest extends TestWithPeerGroup {
public void downloadPeerSelection() throws Exception {
peerGroup.start();
VersionMessage v1 = new VersionMessage(UNITTEST, 2);
v1.clientVersion = NetworkParameters.ProtocolVersion.WITNESS_VERSION.getBitcoinProtocolVersion();
v1.clientVersion = ProtocolVersion.WITNESS_VERSION.intValue();
v1.localServices = Services.of(Services.NODE_NETWORK | Services.NODE_BLOOM | Services.NODE_WITNESS);
VersionMessage v2 = new VersionMessage(UNITTEST, 4);
v2.clientVersion = NetworkParameters.ProtocolVersion.WITNESS_VERSION.getBitcoinProtocolVersion();
v2.clientVersion = ProtocolVersion.WITNESS_VERSION.intValue();
v2.localServices = Services.of(Services.NODE_NETWORK | Services.NODE_BLOOM | Services.NODE_WITNESS);
assertNull(peerGroup.getDownloadPeer());
@ -705,8 +705,8 @@ public class PeerGroupTest extends TestWithPeerGroup {
@Test
public void waitForPeersOfVersion() throws Exception {
final int bip37ver = UNITTEST.getProtocolVersionNum(NetworkParameters.ProtocolVersion.BLOOM_FILTER);
final int bip111ver = UNITTEST.getProtocolVersionNum(NetworkParameters.ProtocolVersion.BLOOM_FILTER_BIP111);
final int bip37ver = ProtocolVersion.BLOOM_FILTER.intValue();
final int bip111ver = ProtocolVersion.BLOOM_FILTER_BIP111.intValue();
CompletableFuture<List<Peer>> future = peerGroup.waitForPeersOfVersion(2, bip111ver);

View file

@ -21,9 +21,9 @@ import com.google.common.util.concurrent.MoreExecutors;
import org.bitcoinj.base.internal.TimeUtils;
import org.bitcoinj.core.BloomFilter;
import org.bitcoinj.core.MemoryPoolMessage;
import org.bitcoinj.core.NetworkParameters;
import org.bitcoinj.core.Peer;
import org.bitcoinj.core.PeerGroup;
import org.bitcoinj.core.ProtocolVersion;
import org.bitcoinj.core.SendAddrV2Message;
import org.bitcoinj.core.Services;
import org.bitcoinj.core.VersionAck;
@ -82,7 +82,7 @@ public class TestWithPeerGroup extends TestWithNetworkConnections {
remoteVersionMessage.localServices =
Services.of(Services.NODE_NETWORK | Services.NODE_BLOOM | Services.NODE_WITNESS);
remoteVersionMessage.clientVersion =
NetworkParameters.ProtocolVersion.WITNESS_VERSION.getBitcoinProtocolVersion();
ProtocolVersion.WITNESS_VERSION.intValue();
blockJobs = false;
initPeerGroup();
}