/**
  * Updates the outputs on the payment contract transaction and re-signs it. The state must be
  * READY in order to call this method. The signature that is returned should be sent to the server
  * so it has the ability to broadcast the best seen payment when the channel closes or times out.
  *
  * <p>The returned signature is over the payment transaction, which we never have a valid copy of
  * and thus there is no accessor for it on this object.
  *
  * <p>To spend the whole channel increment by {@link PaymentChannelClientState#getTotalValue()} -
  * {@link PaymentChannelClientState#getValueRefunded()}
  *
  * @param size How many satoshis to increment the payment by (note: not the new total).
  * @throws ValueOutOfRangeException If size is negative or the channel does not have sufficient
  *     money in it to complete this payment.
  */
 public synchronized IncrementedPayment incrementPaymentBy(Coin size)
     throws ValueOutOfRangeException {
   checkState(state == State.READY);
   checkNotExpired();
   checkNotNull(size); // Validity of size will be checked by makeUnsignedChannelContract.
   if (size.signum() < 0) throw new ValueOutOfRangeException("Tried to decrement payment");
   Coin newValueToMe = valueToMe.subtract(size);
   if (newValueToMe.compareTo(Transaction.MIN_NONDUST_OUTPUT) < 0 && newValueToMe.signum() > 0) {
     log.info(
         "New value being sent back as change was smaller than minimum nondust output, sending all");
     size = valueToMe;
     newValueToMe = Coin.ZERO;
   }
   if (newValueToMe.signum() < 0)
     throw new ValueOutOfRangeException(
         "Channel has too little money to pay " + size + " satoshis");
   Transaction tx = makeUnsignedChannelContract(newValueToMe);
   log.info("Signing new payment tx {}", tx);
   Transaction.SigHash mode;
   // If we spent all the money we put into this channel, we (by definition) don't care what the
   // outputs are, so
   // we sign with SIGHASH_NONE to let the server do what it wants.
   if (newValueToMe.equals(Coin.ZERO)) mode = Transaction.SigHash.NONE;
   else mode = Transaction.SigHash.SINGLE;
   TransactionSignature sig = tx.calculateSignature(0, myKey, multisigScript, mode, true);
   valueToMe = newValueToMe;
   updateChannelInWallet();
   IncrementedPayment payment = new IncrementedPayment();
   payment.signature = sig;
   payment.amount = size;
   return payment;
 }
 /**
  * When the servers signature for the refund transaction is received, call this to verify it and
  * sign the complete refund ourselves.
  *
  * <p>If this does not throw an exception, we are secure against the loss of funds and can safely
  * provide the server with the multi-sig contract to lock in the agreement. In this case, both the
  * multisig contract and the refund transaction are automatically committed to wallet so that it
  * can handle broadcasting the refund transaction at the appropriate time if necessary.
  */
 public synchronized void provideRefundSignature(byte[] theirSignature)
     throws VerificationException {
   checkNotNull(theirSignature);
   checkState(state == State.WAITING_FOR_SIGNED_REFUND);
   TransactionSignature theirSig = TransactionSignature.decodeFromBitcoin(theirSignature, true);
   if (theirSig.sigHashMode() != Transaction.SigHash.NONE || !theirSig.anyoneCanPay())
     throw new VerificationException("Refund signature was not SIGHASH_NONE|SIGHASH_ANYONECANPAY");
   // Sign the refund transaction ourselves.
   final TransactionOutput multisigContractOutput = multisigContract.getOutput(0);
   try {
     multisigScript = multisigContractOutput.getScriptPubKey();
   } catch (ScriptException e) {
     throw new RuntimeException(e); // Cannot happen: we built this ourselves.
   }
   TransactionSignature ourSignature =
       refundTx.calculateSignature(0, myKey, multisigScript, Transaction.SigHash.ALL, false);
   // Insert the signatures.
   Script scriptSig = ScriptBuilder.createMultiSigInputScript(ourSignature, theirSig);
   log.info("Refund scriptSig: {}", scriptSig);
   log.info("Multi-sig contract scriptPubKey: {}", multisigScript);
   TransactionInput refundInput = refundTx.getInput(0);
   refundInput.setScriptSig(scriptSig);
   refundInput.verify(multisigContractOutput);
   state = State.SAVE_STATE_IN_WALLET;
 }
 // Signs the first input of the transaction which must spend the multisig contract.
 private void signMultisigInput(
     Transaction tx, Transaction.SigHash hashType, boolean anyoneCanPay) {
   TransactionSignature signature =
       tx.calculateSignature(0, serverKey, multisigScript, hashType, anyoneCanPay);
   byte[] mySig = signature.encodeToBitcoin();
   Script scriptSig =
       ScriptBuilder.createMultiSigInputScriptBytes(ImmutableList.of(bestValueSignature, mySig));
   tx.getInput(0).setScriptSig(scriptSig);
 }
  /**
   * 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();
  }