private void multisigContractPropogated( Protos.ProvideContract providedContract, Sha256Hash contractHash) { lock.lock(); try { if (!connectionOpen || channelSettling) return; state.storeChannelInWallet(PaymentChannelServer.this); try { receiveUpdatePaymentMessage(providedContract.getInitialPayment(), false /* no ack msg */); } catch (VerificationException e) { log.error("Initial payment failed to verify", e); error( e.getMessage(), Protos.Error.ErrorCode.BAD_TRANSACTION, CloseReason.REMOTE_SENT_INVALID_MESSAGE); return; } catch (ValueOutOfRangeException e) { log.error("Initial payment value was out of range", e); error( e.getMessage(), Protos.Error.ErrorCode.BAD_TRANSACTION, CloseReason.REMOTE_SENT_INVALID_MESSAGE); return; } catch (InsufficientMoneyException e) { // This shouldn't happen because the server shouldn't allow itself to get into this // situation in the // first place, by specifying a min up front payment. log.error( "Tried to settle channel and could not afford the fees whilst updating payment", e); error( e.getMessage(), Protos.Error.ErrorCode.BAD_TRANSACTION, CloseReason.REMOTE_SENT_INVALID_MESSAGE); return; } conn.sendToClient( Protos.TwoWayChannelMessage.newBuilder() .setType(Protos.TwoWayChannelMessage.MessageType.CHANNEL_OPEN) .build()); step = InitStep.CHANNEL_OPEN; conn.channelOpen(contractHash); } finally { lock.unlock(); } }
/** * Called when a message is received from the client. Processes the given message and generates * events based on its content. */ public void receiveMessage(Protos.TwoWayChannelMessage msg) { lock.lock(); try { checkState(connectionOpen); if (channelSettling) return; // If we generate an error, we set errorBuilder and closeReason and break, otherwise we return Protos.Error.Builder errorBuilder; CloseReason closeReason; try { switch (msg.getType()) { case CLIENT_VERSION: receiveVersionMessage(msg); return; case PROVIDE_REFUND: receiveRefundMessage(msg); return; case PROVIDE_CONTRACT: receiveContractMessage(msg); return; case UPDATE_PAYMENT: checkState(step == InitStep.CHANNEL_OPEN && msg.hasUpdatePayment()); receiveUpdatePaymentMessage(msg.getUpdatePayment(), true); return; case CLOSE: receiveCloseMessage(); return; case ERROR: checkState(msg.hasError()); log.error( "Client sent ERROR {} with explanation {}", msg.getError().getCode().name(), msg.getError().hasExplanation() ? msg.getError().getExplanation() : ""); conn.destroyConnection(CloseReason.REMOTE_SENT_ERROR); return; default: final String errorText = "Got unknown message type or type that doesn't apply to servers."; error( errorText, Protos.Error.ErrorCode.SYNTAX_ERROR, CloseReason.REMOTE_SENT_INVALID_MESSAGE); } } catch (VerificationException e) { log.error("Caught verification exception handling message from client", e); error( e.getMessage(), Protos.Error.ErrorCode.BAD_TRANSACTION, CloseReason.REMOTE_SENT_INVALID_MESSAGE); } catch (ValueOutOfRangeException e) { log.error("Caught value out of range exception handling message from client", e); error( e.getMessage(), Protos.Error.ErrorCode.BAD_TRANSACTION, CloseReason.REMOTE_SENT_INVALID_MESSAGE); } catch (InsufficientMoneyException e) { log.error("Caught insufficient money exception handling message from client", e); error( e.getMessage(), Protos.Error.ErrorCode.BAD_TRANSACTION, CloseReason.REMOTE_SENT_INVALID_MESSAGE); } catch (IllegalStateException e) { log.error("Caught illegal state exception handling message from client", e); error( e.getMessage(), Protos.Error.ErrorCode.SYNTAX_ERROR, CloseReason.REMOTE_SENT_INVALID_MESSAGE); } } finally { lock.unlock(); } }