Payment channels: Don't swallow ValueOutOfRangeException during initiate.

It indicates an empty wallet and should be propagated to the channel open future or the client user, so they know they have insufficient money.
This commit is contained in:
Mike Hearn 2013-09-17 16:31:56 +02:00
parent d4786acb14
commit 9bc91ec2e5
3 changed files with 31 additions and 9 deletions

View File

@ -201,7 +201,7 @@ public class PaymentChannelClient {
* Called when a message is received from the server. Processes the given message and generates events based on its
* content.
*/
public void receiveMessage(Protos.TwoWayChannelMessage msg) {
public void receiveMessage(Protos.TwoWayChannelMessage msg) throws ValueOutOfRangeException {
lock.lock();
try {
checkState(connectionOpen);
@ -274,12 +274,6 @@ public class PaymentChannelClient {
.setCode(Protos.Error.ErrorCode.BAD_TRANSACTION)
.setExplanation(e.getMessage());
closeReason = CloseReason.REMOTE_SENT_INVALID_MESSAGE;
} catch (ValueOutOfRangeException e) {
log.error("Caught value out of range exception handling message from server", e);
errorBuilder = Protos.Error.newBuilder()
.setCode(Protos.Error.ErrorCode.BAD_TRANSACTION)
.setExplanation(e.getMessage());
closeReason = CloseReason.REMOTE_SENT_INVALID_MESSAGE;
} catch (IllegalStateException e) {
log.error("Caught illegal state exception handling message from server", e);
errorBuilder = Protos.Error.newBuilder()

View File

@ -88,8 +88,13 @@ public class PaymentChannelClientConnection {
wireParser = new ProtobufParser<Protos.TwoWayChannelMessage>(new ProtobufParser.Listener<Protos.TwoWayChannelMessage>() {
@Override
public void messageReceived(ProtobufParser handler, Protos.TwoWayChannelMessage msg) {
channelClient.receiveMessage(msg);
}
try {
channelClient.receiveMessage(msg);
} catch (ValueOutOfRangeException e) {
// We should only get this exception during INITIATE, so channelOpen wasn't called yet.
channelOpenFuture.setException(e);
}
}
@Override
public void connectionOpen(ProtobufParser handler) {

View File

@ -504,6 +504,29 @@ public class ChannelConnectionTest extends TestWithWallet {
assertEquals(myValue, refund.getOutput(0).getValue());
}
@Test
public void testEmptyWallet() throws Exception {
Wallet emptyWallet = new Wallet(params);
emptyWallet.addKey(new ECKey());
ChannelTestUtils.RecordingPair pair = ChannelTestUtils.makeRecorders(serverWallet, mockBroadcaster);
PaymentChannelServer server = pair.server;
PaymentChannelClient client = new PaymentChannelClient(emptyWallet, myKey, Utils.COIN, Sha256Hash.ZERO_HASH, pair.clientRecorder);
client.connectionOpen();
server.connectionOpen();
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.CLIENT_VERSION));
client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.SERVER_VERSION));
try {
client.receiveMessage(Protos.TwoWayChannelMessage.newBuilder()
.setInitiate(Protos.Initiate.newBuilder().setExpireTimeSecs(Utils.now().getTime() / 1000)
.setMinAcceptedChannelSize(Utils.CENT.longValue())
.setMultisigKey(ByteString.copyFrom(new ECKey().getPubKey())))
.setType(MessageType.INITIATE).build());
fail();
} catch (ValueOutOfRangeException expected) {
// This should be thrown.
}
}
@Test
public void testClientResumeNothing() throws Exception {
ChannelTestUtils.RecordingPair pair = ChannelTestUtils.makeRecorders(serverWallet, mockBroadcaster);