mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-02-07 14:54:15 +00:00
Some small protocol fixes. Correct serialization of version and address messages.
Also require the height of the best chain to be specified when setting up a NetworkConnection. This API is getting too complicated and will be simplified soon. For now these fixes resolve a bug whereby the peer would not send us new blocks discovered during a session (as it thought we already had them).
This commit is contained in:
parent
84dcfecb5d
commit
86d7b15f8c
@ -61,12 +61,15 @@ public class NetworkConnection {
|
|||||||
/**
|
/**
|
||||||
* Connect to the given IP address using the port specified as part of the network parameters. Once construction
|
* Connect to the given IP address using the port specified as part of the network parameters. Once construction
|
||||||
* is complete a functioning network channel is set up and running.
|
* is complete a functioning network channel is set up and running.
|
||||||
|
*
|
||||||
* @param remoteIp IP address to connect to. IPv6 is not currently supported by BitCoin.
|
* @param remoteIp IP address to connect to. IPv6 is not currently supported by BitCoin.
|
||||||
* @param params Defines which network to connect to and details of the protocol.
|
* @param params Defines which network to connect to and details of the protocol.
|
||||||
|
* @param bestHeight How many blocks are in our best chain
|
||||||
* @throws IOException if there is a network related failure.
|
* @throws IOException if there is a network related failure.
|
||||||
* @throws ProtocolException if the version negotiation failed.
|
* @throws ProtocolException if the version negotiation failed.
|
||||||
*/
|
*/
|
||||||
public NetworkConnection(InetAddress remoteIp, NetworkParameters params) throws IOException, ProtocolException {
|
public NetworkConnection(InetAddress remoteIp, NetworkParameters params, int bestHeight)
|
||||||
|
throws IOException, ProtocolException {
|
||||||
this.params = params;
|
this.params = params;
|
||||||
this.remoteIp = remoteIp;
|
this.remoteIp = remoteIp;
|
||||||
socket = new Socket(remoteIp, params.port);
|
socket = new Socket(remoteIp, params.port);
|
||||||
@ -75,7 +78,7 @@ public class NetworkConnection {
|
|||||||
|
|
||||||
// Announce ourselves. This has to come first to connect to clients beyond v0.30.20.2 which wait to hear
|
// Announce ourselves. This has to come first to connect to clients beyond v0.30.20.2 which wait to hear
|
||||||
// from us until they send their version message back.
|
// from us until they send their version message back.
|
||||||
writeMessage(MSG_VERSION, new VersionMessage(params));
|
writeMessage(MSG_VERSION, new VersionMessage(params, bestHeight));
|
||||||
// When connecting, the remote peer sends us a version message with various bits of
|
// When connecting, the remote peer sends us a version message with various bits of
|
||||||
// useful data in it. We need to know the peer protocol version before we can talk to it.
|
// useful data in it. We need to know the peer protocol version before we can talk to it.
|
||||||
versionMessage = (VersionMessage) readMessage();
|
versionMessage = (VersionMessage) readMessage();
|
||||||
|
@ -42,15 +42,18 @@ public class PeerAddress extends Message {
|
|||||||
super(params, payload, offset, protocolVersion);
|
super(params, payload, offset, protocolVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PeerAddress(InetAddress addr, int port) {
|
public PeerAddress(InetAddress addr, int port, int protocolVersion) {
|
||||||
this.addr = addr;
|
this.addr = addr;
|
||||||
this.port = port;
|
this.port = port;
|
||||||
|
this.protocolVersion = protocolVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bitcoinSerializeToStream(OutputStream stream) throws IOException {
|
public void bitcoinSerializeToStream(OutputStream stream) throws IOException {
|
||||||
|
if (protocolVersion >= 31402) {
|
||||||
int secs = (int)(new Date().getTime() / 1000);
|
int secs = (int)(new Date().getTime() / 1000);
|
||||||
uint32ToByteStreamLE(secs, stream);
|
uint32ToByteStreamLE(secs, stream);
|
||||||
uint64ToByteStreamLE(BigInteger.ZERO, stream);
|
}
|
||||||
|
uint64ToByteStreamLE(BigInteger.ZERO, stream); // nServices.
|
||||||
// Java does not provide any utility to map an IPv4 address into IPv6 space, so we have to do it by hand.
|
// Java does not provide any utility to map an IPv4 address into IPv6 space, so we have to do it by hand.
|
||||||
byte[] ipBytes = addr.getAddress();
|
byte[] ipBytes = addr.getAddress();
|
||||||
if (ipBytes.length == 4) {
|
if (ipBytes.length == 4) {
|
||||||
|
@ -18,7 +18,6 @@ package com.google.bitcoin.core;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
|
|
||||||
@ -52,7 +51,7 @@ public class VersionMessage extends Message {
|
|||||||
super(params, msg, 0);
|
super(params, msg, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public VersionMessage(NetworkParameters params) {
|
public VersionMessage(NetworkParameters params, int newBestHeight) {
|
||||||
super(params);
|
super(params);
|
||||||
clientVersion = NetworkParameters.PROTOCOL_VERSION;
|
clientVersion = NetworkParameters.PROTOCOL_VERSION;
|
||||||
localServices = 0;
|
localServices = 0;
|
||||||
@ -60,13 +59,13 @@ public class VersionMessage extends Message {
|
|||||||
// Note that the official client doesn't do anything with these, and finding out your own external IP address
|
// Note that the official client doesn't do anything with these, and finding out your own external IP address
|
||||||
// is kind of tricky anyway, so we just put nonsense here for now.
|
// is kind of tricky anyway, so we just put nonsense here for now.
|
||||||
try {
|
try {
|
||||||
myAddr = new PeerAddress(InetAddress.getLocalHost(), params.port);
|
myAddr = new PeerAddress(InetAddress.getLocalHost(), params.port, 0);
|
||||||
theirAddr = new PeerAddress(InetAddress.getLocalHost(), params.port);
|
theirAddr = new PeerAddress(InetAddress.getLocalHost(), params.port, 0);
|
||||||
} catch (UnknownHostException e) {
|
} catch (UnknownHostException e) {
|
||||||
throw new RuntimeException(e); // Cannot happen.
|
throw new RuntimeException(e); // Cannot happen.
|
||||||
}
|
}
|
||||||
subVer = "BitCoinJ 0.1.99";
|
subVer = "BitCoinJ 0.2";
|
||||||
bestHeight = 0;
|
bestHeight = newBestHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -92,8 +91,9 @@ public class VersionMessage extends Message {
|
|||||||
public void bitcoinSerializeToStream(OutputStream buf) throws IOException {
|
public void bitcoinSerializeToStream(OutputStream buf) throws IOException {
|
||||||
Utils.uint32ToByteStreamLE(clientVersion, buf);
|
Utils.uint32ToByteStreamLE(clientVersion, buf);
|
||||||
Utils.uint32ToByteStreamLE(localServices, buf);
|
Utils.uint32ToByteStreamLE(localServices, buf);
|
||||||
Utils.uint32ToByteStreamLE(time >> 32, buf);
|
Utils.uint32ToByteStreamLE(localServices >> 32, buf);
|
||||||
Utils.uint32ToByteStreamLE(time, buf);
|
Utils.uint32ToByteStreamLE(time, buf);
|
||||||
|
Utils.uint32ToByteStreamLE(time >> 32, buf);
|
||||||
try {
|
try {
|
||||||
// My address.
|
// My address.
|
||||||
myAddr.bitcoinSerializeToStream(buf);
|
myAddr.bitcoinSerializeToStream(buf);
|
||||||
|
@ -31,11 +31,13 @@ import java.util.concurrent.TimeUnit;
|
|||||||
*/
|
*/
|
||||||
public class PingService {
|
public class PingService {
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
final NetworkParameters params = NetworkParameters.prodNet();
|
boolean testNet = args.length > 0 && args[0].equalsIgnoreCase("testnet");
|
||||||
|
final NetworkParameters params = testNet ? NetworkParameters.testNet() : NetworkParameters.prodNet();
|
||||||
|
String filePrefix = testNet ? "pingservice-testnet" : "pingservice-prodnet";
|
||||||
|
|
||||||
// Try to read the wallet from storage, create a new one if not possible.
|
// Try to read the wallet from storage, create a new one if not possible.
|
||||||
Wallet wallet;
|
Wallet wallet;
|
||||||
final File walletFile = new File("pingservice.wallet");
|
final File walletFile = new File(filePrefix + ".wallet");
|
||||||
try {
|
try {
|
||||||
wallet = Wallet.loadFromFile(walletFile);
|
wallet = Wallet.loadFromFile(walletFile);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@ -48,11 +50,12 @@ public class PingService {
|
|||||||
|
|
||||||
// Load the block chain, if there is one stored locally.
|
// Load the block chain, if there is one stored locally.
|
||||||
System.out.println("Reading block store from disk");
|
System.out.println("Reading block store from disk");
|
||||||
BlockStore blockStore = new DiskBlockStore(params, new File("pingservice.blockchain"));
|
BlockStore blockStore = new DiskBlockStore(params, new File(filePrefix + ".blockchain"));
|
||||||
|
|
||||||
// Connect to the localhost node.
|
// Connect to the localhost node.
|
||||||
System.out.println("Connecting ...");
|
System.out.println("Connecting ...");
|
||||||
NetworkConnection conn = new NetworkConnection(InetAddress.getLocalHost(), params);
|
NetworkConnection conn = new NetworkConnection(InetAddress.getLocalHost(), params,
|
||||||
|
blockStore.getChainHead().getHeight());
|
||||||
BlockChain chain = new BlockChain(params, wallet, blockStore);
|
BlockChain chain = new BlockChain(params, wallet, blockStore);
|
||||||
final Peer peer = new Peer(params, conn, chain);
|
final Peer peer = new Peer(params, conn, chain);
|
||||||
peer.start();
|
peer.start();
|
||||||
@ -61,7 +64,7 @@ public class PingService {
|
|||||||
wallet.addEventListener(new WalletEventListener() {
|
wallet.addEventListener(new WalletEventListener() {
|
||||||
public void onCoinsReceived(Wallet w, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
public void onCoinsReceived(Wallet w, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
||||||
// Running on a peer thread.
|
// Running on a peer thread.
|
||||||
|
assert !newBalance.equals(BigInteger.ZERO);
|
||||||
// It's impossible to pick one specific identity that you receive coins from in BitCoin as there
|
// It's impossible to pick one specific identity that you receive coins from in BitCoin as there
|
||||||
// could be inputs from many addresses. So instead we just pick the first and assume they were all
|
// could be inputs from many addresses. So instead we just pick the first and assume they were all
|
||||||
// owned by the same person.
|
// owned by the same person.
|
||||||
|
@ -46,7 +46,7 @@ public class PrivateKeys {
|
|||||||
wallet.addKey(key);
|
wallet.addKey(key);
|
||||||
|
|
||||||
// Find the transactions that involve those coins.
|
// Find the transactions that involve those coins.
|
||||||
NetworkConnection conn = new NetworkConnection(InetAddress.getLocalHost(), params);
|
NetworkConnection conn = new NetworkConnection(InetAddress.getLocalHost(), params, 0);
|
||||||
BlockChain chain = new BlockChain(params, wallet, new MemoryBlockStore(params));
|
BlockChain chain = new BlockChain(params, wallet, new MemoryBlockStore(params));
|
||||||
Peer peer = new Peer(params, conn, chain);
|
Peer peer = new Peer(params, conn, chain);
|
||||||
peer.start();
|
peer.start();
|
||||||
|
Loading…
Reference in New Issue
Block a user