3
0
mirror of https://github.com/Qortal/altcoinj.git synced 2025-02-07 14:54:15 +00:00

Payment channels: bump protocol version.

The protocol gained a PAYMENT_ACK message and now requires a min payment up front. Thus, it is incompatible with previous versions.
This commit is contained in:
Mike Hearn 2013-11-13 18:30:14 +01:00
parent fc70f7362d
commit 9c35501662
3 changed files with 16 additions and 19 deletions

View File

@ -243,7 +243,7 @@ public class PaymentChannelClient implements IPaymentChannelClient {
checkState(step == InitStep.WAITING_FOR_VERSION_NEGOTIATION && msg.hasServerVersion()); checkState(step == InitStep.WAITING_FOR_VERSION_NEGOTIATION && msg.hasServerVersion());
// Server might send back a major version lower than our own if they want to fallback to a // Server might send back a major version lower than our own if they want to fallback to a
// lower version. We can't handle that, so we just close the channel. // lower version. We can't handle that, so we just close the channel.
if (msg.getServerVersion().getMajor() != 0) { if (msg.getServerVersion().getMajor() != 1) {
errorBuilder = Protos.Error.newBuilder() errorBuilder = Protos.Error.newBuilder()
.setCode(Protos.Error.ErrorCode.NO_ACCEPTABLE_VERSION); .setCode(Protos.Error.ErrorCode.NO_ACCEPTABLE_VERSION);
closeReason = CloseReason.NO_ACCEPTABLE_VERSION; closeReason = CloseReason.NO_ACCEPTABLE_VERSION;
@ -399,7 +399,7 @@ public class PaymentChannelClient implements IPaymentChannelClient {
step = InitStep.WAITING_FOR_VERSION_NEGOTIATION; step = InitStep.WAITING_FOR_VERSION_NEGOTIATION;
Protos.ClientVersion.Builder versionNegotiationBuilder = Protos.ClientVersion.newBuilder() Protos.ClientVersion.Builder versionNegotiationBuilder = Protos.ClientVersion.newBuilder()
.setMajor(0).setMinor(1); .setMajor(1).setMinor(0);
if (storedChannel != null) { if (storedChannel != null) {
versionNegotiationBuilder.setPreviousChannelContractHash(ByteString.copyFrom(storedChannel.contract.getHash().getBytes())); versionNegotiationBuilder.setPreviousChannelContractHash(ByteString.copyFrom(storedChannel.contract.getHash().getBytes()));

View File

@ -169,8 +169,15 @@ public class PaymentChannelServer {
@GuardedBy("lock") @GuardedBy("lock")
private void receiveVersionMessage(Protos.TwoWayChannelMessage msg) throws VerificationException { private void receiveVersionMessage(Protos.TwoWayChannelMessage msg) throws VerificationException {
checkState(step == InitStep.WAITING_ON_CLIENT_VERSION && msg.hasClientVersion());
if (msg.getClientVersion().getMajor() != 1) {
error("This server needs protocol v1", Protos.Error.ErrorCode.NO_ACCEPTABLE_VERSION,
CloseReason.NO_ACCEPTABLE_VERSION);
return;
}
Protos.ServerVersion.Builder versionNegotiationBuilder = Protos.ServerVersion.newBuilder() Protos.ServerVersion.Builder versionNegotiationBuilder = Protos.ServerVersion.newBuilder()
.setMajor(0).setMinor(1); .setMajor(1).setMinor(0);
conn.sendToClient(Protos.TwoWayChannelMessage.newBuilder() conn.sendToClient(Protos.TwoWayChannelMessage.newBuilder()
.setType(Protos.TwoWayChannelMessage.MessageType.SERVER_VERSION) .setType(Protos.TwoWayChannelMessage.MessageType.SERVER_VERSION)
.setServerVersion(versionNegotiationBuilder) .setServerVersion(versionNegotiationBuilder)
@ -333,14 +340,6 @@ public class PaymentChannelServer {
try { try {
switch (msg.getType()) { switch (msg.getType()) {
case CLIENT_VERSION: case CLIENT_VERSION:
checkState(step == InitStep.WAITING_ON_CLIENT_VERSION && msg.hasClientVersion());
if (msg.getClientVersion().getMajor() != 0) {
errorBuilder = Protos.Error.newBuilder()
.setCode(Protos.Error.ErrorCode.NO_ACCEPTABLE_VERSION);
closeReason = CloseReason.NO_ACCEPTABLE_VERSION;
break;
}
receiveVersionMessage(msg); receiveVersionMessage(msg);
return; return;
case PROVIDE_REFUND: case PROVIDE_REFUND:
@ -363,11 +362,8 @@ public class PaymentChannelServer {
conn.destroyConnection(CloseReason.REMOTE_SENT_ERROR); conn.destroyConnection(CloseReason.REMOTE_SENT_ERROR);
return; return;
default: default:
log.error("Got unknown message type or type that doesn't apply to servers."); final String errorText = "Got unknown message type or type that doesn't apply to servers.";
errorBuilder = Protos.Error.newBuilder() error(errorText, Protos.Error.ErrorCode.SYNTAX_ERROR, CloseReason.REMOTE_SENT_INVALID_MESSAGE);
.setCode(Protos.Error.ErrorCode.SYNTAX_ERROR);
closeReason = CloseReason.REMOTE_SENT_INVALID_MESSAGE;
break;
} }
} catch (VerificationException e) { } catch (VerificationException e) {
log.error("Caught verification exception handling message from client", e); log.error("Caught verification exception handling message from client", e);
@ -385,6 +381,7 @@ public class PaymentChannelServer {
} }
private void error(String message, Protos.Error.ErrorCode errorCode, CloseReason closeReason) { private void error(String message, Protos.Error.ErrorCode errorCode, CloseReason closeReason) {
log.error(message);
Protos.Error.Builder errorBuilder; Protos.Error.Builder errorBuilder;
errorBuilder = Protos.Error.newBuilder() errorBuilder = Protos.Error.newBuilder()
.setCode(errorCode) .setCode(errorCode)

View File

@ -319,7 +319,7 @@ public class ChannelConnectionTest extends TestWithWallet {
.setType(MessageType.CLIENT_VERSION) .setType(MessageType.CLIENT_VERSION)
.setClientVersion(Protos.ClientVersion.newBuilder() .setClientVersion(Protos.ClientVersion.newBuilder()
.setPreviousChannelContractHash(ByteString.copyFrom(Sha256Hash.create(new byte[]{0x03}).getBytes())) .setPreviousChannelContractHash(ByteString.copyFrom(Sha256Hash.create(new byte[]{0x03}).getBytes()))
.setMajor(0).setMinor(42)) .setMajor(1).setMinor(42))
.build()); .build());
pair.serverRecorder.checkNextMsg(MessageType.SERVER_VERSION); pair.serverRecorder.checkNextMsg(MessageType.SERVER_VERSION);
pair.serverRecorder.checkNextMsg(MessageType.INITIATE); pair.serverRecorder.checkNextMsg(MessageType.INITIATE);
@ -380,7 +380,7 @@ public class ChannelConnectionTest extends TestWithWallet {
.setType(MessageType.CLIENT_VERSION) .setType(MessageType.CLIENT_VERSION)
.setClientVersion(Protos.ClientVersion.newBuilder() .setClientVersion(Protos.ClientVersion.newBuilder()
.setPreviousChannelContractHash(ByteString.copyFrom(contractHash.getBytes())) .setPreviousChannelContractHash(ByteString.copyFrom(contractHash.getBytes()))
.setMajor(0).setMinor(42)) .setMajor(1).setMinor(42))
.build()); .build());
// We get the usual resume sequence. // We get the usual resume sequence.
pair.serverRecorder.checkNextMsg(MessageType.SERVER_VERSION); pair.serverRecorder.checkNextMsg(MessageType.SERVER_VERSION);
@ -440,7 +440,7 @@ public class ChannelConnectionTest extends TestWithWallet {
.setType(MessageType.CLIENT_VERSION) .setType(MessageType.CLIENT_VERSION)
.setClientVersion(Protos.ClientVersion.newBuilder() .setClientVersion(Protos.ClientVersion.newBuilder()
.setPreviousChannelContractHash(ByteString.copyFrom(new byte[]{0x00, 0x01})) .setPreviousChannelContractHash(ByteString.copyFrom(new byte[]{0x00, 0x01}))
.setMajor(0).setMinor(42)) .setMajor(1).setMinor(42))
.build()); .build());
srv.serverRecorder.checkNextMsg(MessageType.SERVER_VERSION); srv.serverRecorder.checkNextMsg(MessageType.SERVER_VERSION);