docs: public void receiveMessage(Protos.TwoWayChannelMessage msg) {
          lock.lock();
          try {
              checkState(connectionOpen);
              if (channelSettling)
                  return;
              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 (SignatureDecodeException 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();
          }
      }