mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-02-12 10:15:52 +00:00
Add relayTxesBeforeFilter flag to VersionMessage, PROTOCOL_VERSION
This adds a relayTxesBeforeFilter flag to VersionMessage, bringing it in line with PROTOCOL_VERSION 70001, and bumps the PROTOCOL_VERSION accordingly.
This commit is contained in:
parent
a0c25aed28
commit
a5f9c3381b
@ -472,6 +472,10 @@ public abstract class Message implements Serializable {
|
||||
throw new RuntimeException(e); // Cannot happen, UTF-8 is always supported.
|
||||
}
|
||||
}
|
||||
|
||||
boolean hasMoreBytes() {
|
||||
return cursor < bytes.length;
|
||||
}
|
||||
|
||||
public static class LazyParseException extends RuntimeException {
|
||||
private static final long serialVersionUID = 6971943053112975594L;
|
||||
|
@ -41,7 +41,7 @@ public class NetworkParameters implements Serializable {
|
||||
/**
|
||||
* The protocol version this library implements.
|
||||
*/
|
||||
public static final int PROTOCOL_VERSION = 60001;
|
||||
public static final int PROTOCOL_VERSION = 70001;
|
||||
|
||||
/**
|
||||
* The alert signing key originally owned by Satoshi, and now passed on to Gavin along with a few others.
|
||||
|
@ -119,10 +119,11 @@ public class Peer {
|
||||
|
||||
/**
|
||||
* Construct a peer that reads/writes from the given chain. Automatically creates a VersionMessage for you from the
|
||||
* given software name/version strings, which should be something like "MySimpleTool", "1.0"
|
||||
* given software name/version strings, which should be something like "MySimpleTool", "1.0" and which will tell the
|
||||
* remote node to relay transaction inv messages before it has received a filter.
|
||||
*/
|
||||
public Peer(NetworkParameters params, AbstractBlockChain blockChain, String thisSoftwareName, String thisSoftwareVersion) {
|
||||
this(params, blockChain, new VersionMessage(params, blockChain.getBestChainHeight()));
|
||||
this(params, blockChain, new VersionMessage(params, blockChain.getBestChainHeight(), true));
|
||||
this.versionMessage.appendToSubVer(thisSoftwareName, thisSoftwareVersion, null);
|
||||
}
|
||||
|
||||
|
@ -187,7 +187,8 @@ public class PeerGroup extends AbstractIdleService {
|
||||
this.maxConnections = 0;
|
||||
|
||||
int height = chain == null ? 0 : chain.getBestChainHeight();
|
||||
this.versionMessage = new VersionMessage(params, height);
|
||||
// We never request that the remote node wait for a bloom filter yet, as we have no wallets
|
||||
this.versionMessage = new VersionMessage(params, height, true);
|
||||
|
||||
memoryPool = new MemoryPool();
|
||||
|
||||
@ -346,10 +347,21 @@ public class PeerGroup extends AbstractIdleService {
|
||||
* @param version
|
||||
*/
|
||||
public void setUserAgent(String name, String version, String comments) {
|
||||
VersionMessage ver = new VersionMessage(params, 0);
|
||||
//TODO Check that height is needed here (it wasnt, but it should be, no?)
|
||||
int height = chain == null ? 0 : chain.getBestChainHeight();
|
||||
VersionMessage ver = new VersionMessage(params, height, false);
|
||||
updateVersionMessageRelayTxesBeforeFilter(ver);
|
||||
ver.appendToSubVer(name, version, comments);
|
||||
setVersionMessage(ver);
|
||||
}
|
||||
|
||||
// Updates the relayTxesBeforeFilter flag of ver
|
||||
private synchronized void updateVersionMessageRelayTxesBeforeFilter(VersionMessage ver) {
|
||||
// We will provide the remote node with a bloom filter (ie they shouldn't relay yet)
|
||||
// iff chain == null || !chain.shouldVerifyTransactions() and a wallet is added
|
||||
// Note that the default here means that no tx invs will be received if no wallet is ever added
|
||||
ver.relayTxesBeforeFilter = chain != null && chain.shouldVerifyTransactions() && wallets.size() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets information that identifies this software to remote nodes. This is a convenience wrapper for creating
|
||||
@ -535,6 +547,7 @@ public class PeerGroup extends AbstractIdleService {
|
||||
}
|
||||
});
|
||||
recalculateFastCatchupAndFilter();
|
||||
updateVersionMessageRelayTxesBeforeFilter(getVersionMessage());
|
||||
}
|
||||
|
||||
private synchronized void recalculateFastCatchupAndFilter() {
|
||||
|
@ -67,6 +67,10 @@ public class VersionMessage extends Message {
|
||||
* How many blocks are in the chain, according to the other side.
|
||||
*/
|
||||
public long bestHeight;
|
||||
/**
|
||||
* Whether or not to relay tx invs before a filter is received
|
||||
*/
|
||||
public boolean relayTxesBeforeFilter;
|
||||
|
||||
public VersionMessage(NetworkParameters params, byte[] msg) throws ProtocolException {
|
||||
super(params, msg, 0);
|
||||
@ -75,8 +79,13 @@ public class VersionMessage extends Message {
|
||||
// It doesn't really make sense to ever lazily parse a version message or to retain the backing bytes.
|
||||
// If you're receiving this on the wire you need to check the protocol version and it will never need to be sent
|
||||
// back down the wire.
|
||||
|
||||
|
||||
/** Equivalent to VersionMessage(params, newBestHeight, true) */
|
||||
public VersionMessage(NetworkParameters params, int newBestHeight) {
|
||||
this(params, newBestHeight, true);
|
||||
}
|
||||
|
||||
public VersionMessage(NetworkParameters params, int newBestHeight, boolean relayTxesBeforeFilter) {
|
||||
super(params);
|
||||
clientVersion = NetworkParameters.PROTOCOL_VERSION;
|
||||
localServices = 0;
|
||||
@ -94,8 +103,9 @@ public class VersionMessage extends Message {
|
||||
}
|
||||
subVer = "/BitCoinJ:0.7-SNAPSHOT/";
|
||||
bestHeight = newBestHeight;
|
||||
this.relayTxesBeforeFilter = relayTxesBeforeFilter;
|
||||
|
||||
length = 84;
|
||||
length = 85;
|
||||
if (protocolVersion > 31402)
|
||||
length += 8;
|
||||
length += subVer == null ? 1 : VarInt.sizeOf(subVer.length()) + subVer.length();
|
||||
@ -123,11 +133,25 @@ public class VersionMessage extends Message {
|
||||
// We don't care about the localhost nonce. It's used to detect connecting back to yourself in cases where
|
||||
// there are NATs and proxies in the way. However we don't listen for inbound connections so it's irrelevant.
|
||||
readUint64();
|
||||
// string subVer (currently "")
|
||||
subVer = readStr();
|
||||
// int bestHeight (size of known block chain).
|
||||
bestHeight = readUint32();
|
||||
length = cursor - offset;
|
||||
try {
|
||||
// Initialize default values for flags which may not be sent by old nodes
|
||||
subVer = "";
|
||||
bestHeight = 0;
|
||||
relayTxesBeforeFilter = true;
|
||||
if (!hasMoreBytes())
|
||||
return;
|
||||
// string subVer (currently "")
|
||||
subVer = readStr();
|
||||
if (!hasMoreBytes())
|
||||
return;
|
||||
// int bestHeight (size of known block chain).
|
||||
bestHeight = readUint32();
|
||||
if (!hasMoreBytes())
|
||||
return;
|
||||
relayTxesBeforeFilter = readBytes(1)[0] != 0;
|
||||
} finally {
|
||||
length = cursor - offset;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -158,6 +182,7 @@ public class VersionMessage extends Message {
|
||||
buf.write(subVerBytes);
|
||||
// Size of known block chain.
|
||||
Utils.uint32ToByteStreamLE(bestHeight, buf);
|
||||
buf.write(relayTxesBeforeFilter ? 1 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -178,7 +203,8 @@ public class VersionMessage extends Message {
|
||||
other.time == time &&
|
||||
other.subVer.equals(subVer) &&
|
||||
other.myAddr.equals(myAddr) &&
|
||||
other.theirAddr.equals(theirAddr);
|
||||
other.theirAddr.equals(theirAddr) &&
|
||||
other.relayTxesBeforeFilter == relayTxesBeforeFilter;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -199,7 +225,7 @@ public class VersionMessage extends Message {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (int) bestHeight ^ clientVersion ^ (int) localServices ^ (int) time ^ subVer.hashCode() ^ myAddr.hashCode()
|
||||
^ theirAddr.hashCode();
|
||||
^ theirAddr.hashCode() * (relayTxesBeforeFilter ? 1 : 2);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
@ -212,11 +238,12 @@ public class VersionMessage extends Message {
|
||||
sb.append("their addr: ").append(theirAddr).append("\n");
|
||||
sb.append("sub version: ").append(subVer).append("\n");
|
||||
sb.append("best height: ").append(bestHeight).append("\n");
|
||||
sb.append("delay tx relay: ").append(relayTxesBeforeFilter).append("\n");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public VersionMessage duplicate() {
|
||||
VersionMessage v = new VersionMessage(params, (int) bestHeight);
|
||||
VersionMessage v = new VersionMessage(params, (int) bestHeight, relayTxesBeforeFilter);
|
||||
v.clientVersion = clientVersion;
|
||||
v.localServices = localServices;
|
||||
v.time = time;
|
||||
|
@ -55,9 +55,9 @@ public class BitcoinSerializerTest {
|
||||
public void testVersion() throws Exception {
|
||||
BitcoinSerializer bs = new BitcoinSerializer(NetworkParameters.prodNet(), false);
|
||||
// the actual data from https://en.bitcoin.it/wiki/Protocol_specification#version
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(Hex.decode("f9beb4d976657273696f6e0000000000550000009" +
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(Hex.decode("f9beb4d976657273696f6e0000000000560000009" +
|
||||
"c7c00000100000000000000e615104d00000000010000000000000000000000000000000000ffff0a000001daf6010000" +
|
||||
"000000000000000000000000000000ffff0a000002208ddd9d202c3ab457130055810100"));
|
||||
"000000000000000000000000000000ffff0a000002208ddd9d202c3ab45713005581010000"));
|
||||
VersionMessage vm = (VersionMessage)bs.deserialize(bais);
|
||||
assertEquals(31900, vm.clientVersion);
|
||||
assertEquals(1292899814L, vm.time);
|
||||
|
@ -102,10 +102,6 @@ public class MockNetworkConnection implements NetworkConnection {
|
||||
this.versionMessage = msg;
|
||||
}
|
||||
|
||||
public void setVersionMessageForHeight(NetworkParameters params, int chainHeight) {
|
||||
versionMessage = new VersionMessage(params, chainHeight);
|
||||
}
|
||||
|
||||
public VersionMessage getVersionMessage() {
|
||||
if (versionMessage == null) throw new RuntimeException("Need to call setVersionMessage first");
|
||||
return versionMessage;
|
||||
|
@ -0,0 +1,34 @@
|
||||
package com.google.bitcoin.core;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
public class VersionMessageTest {
|
||||
@Test
|
||||
// Test that we can decode version messages which miss data which some old nodes may not include
|
||||
public void testDecode() throws Exception {
|
||||
NetworkParameters params = NetworkParameters.unitTests();
|
||||
|
||||
VersionMessage ver = new VersionMessage(params, Hex.decode("71110100000000000000000048e5e95000000000000000000000000000000000000000000000ffff7f000001479d000000000000000000000000000000000000ffff7f000001479d0000000000000000172f426974436f696e4a3a302e372d534e415053484f542f0004000000"));
|
||||
assertTrue(!ver.relayTxesBeforeFilter);
|
||||
assertTrue(ver.bestHeight == 1024);
|
||||
assertTrue(ver.subVer.equals("/BitCoinJ:0.7-SNAPSHOT/"));
|
||||
|
||||
ver = new VersionMessage(params, Hex.decode("71110100000000000000000048e5e95000000000000000000000000000000000000000000000ffff7f000001479d000000000000000000000000000000000000ffff7f000001479d0000000000000000172f426974436f696e4a3a302e372d534e415053484f542f00040000"));
|
||||
assertTrue(ver.relayTxesBeforeFilter);
|
||||
assertTrue(ver.bestHeight == 1024);
|
||||
assertTrue(ver.subVer.equals("/BitCoinJ:0.7-SNAPSHOT/"));
|
||||
|
||||
ver = new VersionMessage(params, Hex.decode("71110100000000000000000048e5e95000000000000000000000000000000000000000000000ffff7f000001479d000000000000000000000000000000000000ffff7f000001479d0000000000000000172f426974436f696e4a3a302e372d534e415053484f542f"));
|
||||
assertTrue(ver.relayTxesBeforeFilter);
|
||||
assertTrue(ver.bestHeight == 0);
|
||||
assertTrue(ver.subVer.equals("/BitCoinJ:0.7-SNAPSHOT/"));
|
||||
|
||||
ver = new VersionMessage(params, Hex.decode("71110100000000000000000048e5e95000000000000000000000000000000000000000000000ffff7f000001479d000000000000000000000000000000000000ffff7f000001479d0000000000000000"));
|
||||
assertTrue(ver.relayTxesBeforeFilter);
|
||||
assertTrue(ver.bestHeight == 0);
|
||||
assertTrue(ver.subVer.equals(""));
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user