private static void sendTransactionsToListener(
     StoredBlock block,
     NewBlockType blockType,
     BlockChainListener listener,
     int relativityOffset,
     List<Transaction> transactions,
     boolean clone,
     Set<Sha256Hash> falsePositives)
     throws VerificationException {
   for (Transaction tx : transactions) {
     try {
       if (listener.isTransactionRelevant(tx)) {
         falsePositives.remove(tx.getHash());
         if (clone) tx = new Transaction(tx.params, tx.bitcoinSerialize());
         listener.receiveFromBlock(tx, block, blockType, relativityOffset++);
       }
     } catch (ScriptException e) {
       // We don't want scripts we don't understand to break the block chain so just note that this
       // tx was
       // not scanned here and continue.
       log.warn("Failed to parse a script: " + e.toString());
     } catch (ProtocolException e) {
       // Failed to duplicate tx, should never happen.
       throw new RuntimeException(e);
     }
   }
 }
 @VisibleForTesting
 synchronized void doStoreChannelInWallet(Sha256Hash id) {
   StoredPaymentChannelClientStates channels =
       (StoredPaymentChannelClientStates)
           wallet.getExtensions().get(StoredPaymentChannelClientStates.EXTENSION_ID);
   checkNotNull(
       channels,
       "You have not added the StoredPaymentChannelClientStates extension to the wallet.");
   checkState(channels.getChannel(id, multisigContract.getHash()) == null);
   storedChannel =
       new StoredClientChannel(id, multisigContract, refundTx, myKey, valueToMe, refundFees, true);
   channels.putChannel(storedChannel);
   wallet.addOrUpdateExtension(channels);
 }
  /**
   * Stores this channel's state in the wallet as a part of a {@link
   * StoredPaymentChannelServerStates} wallet extension and keeps it up-to-date each time payment is
   * incremented. This will be automatically removed when a call to {@link
   * PaymentChannelServerState#close()} completes successfully. A channel may only be stored after
   * it has fully opened (ie state == State.READY).
   *
   * @param connectedHandler Optional {@link PaymentChannelServer} object that manages this object.
   *     This will set the appropriate pointer in the newly created {@link StoredServerChannel}
   *     before it is committed to wallet. If set, closing the state object will propagate the close
   *     to the handler which can then do a TCP disconnect.
   */
  public synchronized void storeChannelInWallet(@Nullable PaymentChannelServer connectedHandler) {
    checkState(state == State.READY);
    if (storedServerChannel != null) return;

    log.info("Storing state with contract hash {}.", multisigContract.getHash());
    StoredPaymentChannelServerStates channels =
        (StoredPaymentChannelServerStates)
            wallet.addOrGetExistingExtension(
                new StoredPaymentChannelServerStates(wallet, broadcaster));
    storedServerChannel =
        new StoredServerChannel(
            this,
            multisigContract,
            clientOutput,
            refundTransactionUnlockTimeSecs,
            serverKey,
            bestValueToMe,
            bestValueSignature);
    if (connectedHandler != null)
      checkState(
          storedServerChannel.setConnectedHandler(connectedHandler, false) == connectedHandler);
    channels.putChannel(storedServerChannel);
  }
  /**
   * Called when the client provides us with a new signature and wishes to increment total payment
   * by size. Verifies the provided signature and only updates values if everything checks out. If
   * the new refundSize is not the lowest we have seen, it is simply ignored.
   *
   * @param refundSize How many satoshis of the original contract are refunded to the client (the
   *     rest are ours)
   * @param signatureBytes The new signature spending the multi-sig contract to a new payment
   *     transaction
   * @throws VerificationException If the signature does not verify or size is out of range (incl
   *     being rejected by the network as dust).
   * @return true if there is more value left on the channel, false if it is now fully used up.
   */
  public synchronized boolean incrementPayment(Coin refundSize, byte[] signatureBytes)
      throws VerificationException, ValueOutOfRangeException, InsufficientMoneyException {
    checkState(state == State.READY);
    checkNotNull(refundSize);
    checkNotNull(signatureBytes);
    TransactionSignature signature = TransactionSignature.decodeFromBitcoin(signatureBytes, true);
    // We allow snapping to zero for the payment amount because it's treated specially later, but
    // not less than
    // the dust level because that would prevent the transaction from being relayed/mined.
    final boolean fullyUsedUp = refundSize.equals(Coin.ZERO);
    if (refundSize.compareTo(clientOutput.getMinNonDustValue()) < 0 && !fullyUsedUp)
      throw new ValueOutOfRangeException(
          "Attempt to refund negative value or value too small to be accepted by the network");
    Coin newValueToMe = totalValue.subtract(refundSize);
    if (newValueToMe.signum() < 0)
      throw new ValueOutOfRangeException("Attempt to refund more than the contract allows.");
    if (newValueToMe.compareTo(bestValueToMe) < 0)
      throw new ValueOutOfRangeException("Attempt to roll back payment on the channel.");

    // Get the wallet's copy of the multisigContract (ie with confidence information), if this is
    // null, the wallet
    // was not connected to the peergroup when the contract was broadcast (which may cause issues
    // down the road, and
    // disables our double-spend check next)
    Transaction walletContract = wallet.getTransaction(multisigContract.getHash());
    checkNotNull(
        walletContract,
        "Wallet did not contain multisig contract {} after state was marked READY",
        multisigContract.getHash());

    // Note that we check for DEAD state here, but this test is essentially useless in production
    // because we will
    // miss most double-spends due to bloom filtering right now anyway. This will eventually fixed
    // by network-wide
    // double-spend notifications, so we just wait instead of attempting to add all dependant
    // outpoints to our bloom
    // filters (and probably missing lots of edge-cases).
    if (walletContract.getConfidence().getConfidenceType()
        == TransactionConfidence.ConfidenceType.DEAD) {
      close();
      throw new VerificationException("Multisig contract was double-spent");
    }

    Transaction.SigHash mode;
    // If the client doesn't want anything back, they shouldn't sign any outputs at all.
    if (fullyUsedUp) mode = Transaction.SigHash.NONE;
    else mode = Transaction.SigHash.SINGLE;

    if (signature.sigHashMode() != mode || !signature.anyoneCanPay())
      throw new VerificationException(
          "New payment signature was not signed with the right SIGHASH flags.");

    Wallet.SendRequest req = makeUnsignedChannelContract(newValueToMe);
    // Now check the signature is correct.
    // Note that the client must sign with SIGHASH_{SINGLE/NONE} | SIGHASH_ANYONECANPAY to allow us
    // to add additional
    // inputs (in case we need to add significant fee, or something...) and any outputs we want to
    // pay to.
    Sha256Hash sighash = req.tx.hashForSignature(0, multisigScript, mode, true);

    if (!clientKey.verify(sighash, signature))
      throw new VerificationException("Signature does not verify on tx\n" + req.tx);
    bestValueToMe = newValueToMe;
    bestValueSignature = signatureBytes;
    updateChannelInWallet();
    return !fullyUsedUp;
  }