/**
   * Called when the client provides the refund transaction. The refund transaction must have one
   * input from the multisig contract (that we don't have yet) and one output that the client
   * creates to themselves. This object will later be modified when we start getting paid.
   *
   * @param refundTx The refund transaction, this object will be mutated when payment is
   *     incremented.
   * @param clientMultiSigPubKey The client's pubkey which is required for the multisig output
   * @return Our signature that makes the refund transaction valid
   * @throws VerificationException If the transaction isnt valid or did not meet the requirements of
   *     a refund transaction.
   */
  public synchronized byte[] provideRefundTransaction(
      Transaction refundTx, byte[] clientMultiSigPubKey) throws VerificationException {
    checkNotNull(refundTx);
    checkNotNull(clientMultiSigPubKey);
    checkState(state == State.WAITING_FOR_REFUND_TRANSACTION);
    log.info("Provided with refund transaction: {}", refundTx);
    // Do a few very basic syntax sanity checks.
    refundTx.verify();
    // Verify that the refund transaction has a single input (that we can fill to sign the multisig
    // output).
    if (refundTx.getInputs().size() != 1)
      throw new VerificationException("Refund transaction does not have exactly one input");
    // Verify that the refund transaction has a time lock on it and a sequence number of zero.
    if (refundTx.getInput(0).getSequenceNumber() != 0)
      throw new VerificationException("Refund transaction's input's sequence number is non-0");
    if (refundTx.getLockTime() < minExpireTime)
      throw new VerificationException("Refund transaction has a lock time too soon");
    // Verify the transaction has one output (we don't care about its contents, its up to the
    // client)
    // Note that because we sign with SIGHASH_NONE|SIGHASH_ANYOENCANPAY the client can later add
    // more outputs and
    // inputs, but we will need only one output later to create the paying transactions
    if (refundTx.getOutputs().size() != 1)
      throw new VerificationException("Refund transaction does not have exactly one output");

    refundTransactionUnlockTimeSecs = refundTx.getLockTime();

    // Sign the refund tx with the scriptPubKey and return the signature. We don't have the spending
    // transaction
    // so do the steps individually.
    clientKey = ECKey.fromPublicOnly(clientMultiSigPubKey);
    Script multisigPubKey =
        ScriptBuilder.createMultiSigOutputScript(2, ImmutableList.of(clientKey, serverKey));
    // We are really only signing the fact that the transaction has a proper lock time and don't
    // care about anything
    // else, so we sign SIGHASH_NONE and SIGHASH_ANYONECANPAY.
    TransactionSignature sig =
        refundTx.calculateSignature(0, serverKey, multisigPubKey, Transaction.SigHash.NONE, true);
    log.info("Signed refund transaction.");
    this.clientOutput = refundTx.getOutput(0);
    state = State.WAITING_FOR_MULTISIG_CONTRACT;
    return sig.encodeToBitcoin();
  }
 PaymentChannelClientState(StoredClientChannel storedClientChannel, Wallet wallet)
     throws VerificationException {
   // The PaymentChannelClientConnection handles storedClientChannel.active and ensures we aren't
   // resuming channels
   this.wallet = checkNotNull(wallet);
   this.multisigContract = checkNotNull(storedClientChannel.contract);
   this.multisigScript = multisigContract.getOutput(0).getScriptPubKey();
   this.refundTx = checkNotNull(storedClientChannel.refund);
   this.refundFees = checkNotNull(storedClientChannel.refundFees);
   this.expiryTime = refundTx.getLockTime();
   this.myKey = checkNotNull(storedClientChannel.myKey);
   this.serverMultisigKey = null;
   this.totalValue = multisigContract.getOutput(0).getValue();
   this.valueToMe = checkNotNull(storedClientChannel.valueToMe);
   this.storedChannel = storedClientChannel;
   this.state = State.READY;
   initWalletListeners();
 }