Java 类org.bitcoinj.core.InsufficientMoneyException 实例源码

项目:bitnym    文件:BitNymWallet.java   
public void generateGenesisTransaction(int lockTime) {
    Transaction genesisTx;
    try {
        //generate genesis transaction if our proof is empty
        if(pm.getValidationPath().size() == 0 && wallet.getBalance(BalanceType.AVAILABLE).isGreaterThan(PSNYMVALUE)) {
            genesisTx = tg.generateGenesisTransaction(pm, walletFile, lockTime);
            //TODO register listener before sending tx out, to avoid missing a confidence change
            genesisTx.getConfidence().addEventListener(new Listener() {

                @Override
                public void onConfidenceChanged(TransactionConfidence arg0,
                        ChangeReason arg1) {
                    if (arg0.getConfidenceType() != TransactionConfidence.ConfidenceType.BUILDING) {
                        return;
                    }
                    if(arg0.getDepthInBlocks() == 1) {
                        //enough confidence, write proof message to the file system
                        System.out.println("depth of genesis tx is now 1, consider ready for usage");
                    }
                }
            });
        }
    } catch (InsufficientMoneyException e) {
        e.printStackTrace();
    }
}
项目:cryptwallet    文件:WalletTest.java   
@Test
public void lowerThanDefaultFee() throws InsufficientMoneyException {
    int feeFactor = 10;
    Coin fee = Transaction.DEFAULT_TX_FEE.divide(feeFactor);
    receiveATransactionAmount(wallet, myAddress, Coin.COIN);
    SendRequest req = SendRequest.to(myAddress, Coin.CENT);
    req.feePerKb = fee;
    wallet.completeTx(req);
    assertEquals(Coin.valueOf(11350).divide(feeFactor), req.tx.getFee());
    wallet.commitTx(req.tx);
    SendRequest emptyReq = SendRequest.emptyWallet(myAddress);
    emptyReq.feePerKb = fee;
    emptyReq.ensureMinRequiredFee = true;
    emptyReq.emptyWallet = true;
    emptyReq.coinSelector = AllowUnconfirmedCoinSelector.get();
    wallet.completeTx(emptyReq);
    assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, emptyReq.tx.getFee());
    wallet.commitTx(emptyReq.tx);
}
项目:cryptwallet    文件:WalletTest.java   
@Test
public void higherThanDefaultFee() throws InsufficientMoneyException {
    int feeFactor = 10;
    Coin fee = Transaction.DEFAULT_TX_FEE.multiply(feeFactor);
    receiveATransactionAmount(wallet, myAddress, Coin.COIN);
    SendRequest req = SendRequest.to(myAddress, Coin.CENT);
    req.feePerKb = fee;
    wallet.completeTx(req);
    assertEquals(Coin.valueOf(11350).multiply(feeFactor), req.tx.getFee());
    wallet.commitTx(req.tx);
    SendRequest emptyReq = SendRequest.emptyWallet(myAddress);
    emptyReq.feePerKb = fee;
    emptyReq.emptyWallet = true;
    emptyReq.coinSelector = AllowUnconfirmedCoinSelector.get();
    wallet.completeTx(emptyReq);
    assertEquals(Coin.valueOf(171000), emptyReq.tx.getFee());
    wallet.commitTx(emptyReq.tx);
}
项目:Shufflepuff    文件:BitcoinCrypto.java   
public String sendOffline(String destinationAddress, long amountSatoshis) throws InsufficientMoneyException {
   Address addressj;
   try {
      addressj = new Address(params, destinationAddress);
   } catch (AddressFormatException e) {
      e.printStackTrace();
      throw new RuntimeException(e);
   }
   Coin amount = Coin.valueOf(amountSatoshis);
   // create a SendRequest of amount to destinationAddress
   Wallet.SendRequest sendRequest = Wallet.SendRequest.to(addressj, amount);
   // set dynamic fee
   sendRequest.feePerKb = getRecommendedFee();
   // complete & sign tx
   kit.wallet().completeTx(sendRequest);
   kit.wallet().signTransaction(sendRequest);
   // return tx bytes as hex encoded String
   return Hex.encodeHexString(sendRequest.tx.bitcoinSerialize());
}
项目:speciebox    文件:WalletController.java   
private void listenForCoinsAndRetry(final Coin value, final Address toAddress){
       // Wait until the we have enough balance and display a notice.
       ListenableFuture<Coin> balanceFuture = SPECIEBOX.wallet().getBalanceFuture(value, BalanceType.AVAILABLE);
       FutureCallback<Coin> retry = new FutureCallback<Coin>() {
           public void onSuccess(Coin balance) {
               System.out.println("coins arrived and the wallet now has enough balance");
               try {
                Wallet.SendResult result = SPECIEBOX.wallet().sendCoins(SPECIEBOX.peerGroup(), toAddress, value);
                System.out.println("Info: COINS RESENT. Transaction hash: " + result.tx.getHashAsString());
            } catch (InsufficientMoneyException e) {
                e.printStackTrace();
                System.out.println("Still not enough coins in your wallet, missing " + e.missing.getValue() + " satoshis.");
            }
           }
           public void onFailure(Throwable t) {
               System.out.println("something went wrong");
           }
       };
       Futures.addCallback(balanceFuture, retry);
}
项目:speciebox    文件:WalletController2.java   
private void listenForCoinsAndRetry(final Coin value, final Address toAddress){
       // Wait until the we have enough balance and display a notice.
       ListenableFuture<Coin> balanceFuture = SPECIEBOX.wallet().getBalanceFuture(value, BalanceType.AVAILABLE);
       FutureCallback<Coin> retry = new FutureCallback<Coin>() {
           public void onSuccess(Coin balance) {
               System.out.println("coins arrived and the wallet now has enough balance");
               try {
                Wallet.SendResult result = SPECIEBOX.wallet().sendCoins(SPECIEBOX.peerGroup(), toAddress, value);
                System.out.println("Info: COINS RESENT. Transaction hash: " + result.tx.getHashAsString());
            } catch (InsufficientMoneyException e) {
                e.printStackTrace();
                System.out.println("Still not enough coins in your wallet, missing " + e.missing.getValue() + " satoshis.");
            }
           }
           public void onFailure(Throwable t) {
               System.out.println("something went wrong");
           }
       };
       Futures.addCallback(balanceFuture, retry);
}
项目:dashj    文件:WalletTest.java   
@Test
public void lowerThanDefaultFee() throws InsufficientMoneyException {
    int feeFactor = 10;
    Coin fee = Transaction.DEFAULT_TX_FEE.divide(feeFactor);
    receiveATransactionAmount(wallet, myAddress, Coin.COIN);
    SendRequest req = SendRequest.to(myAddress, Coin.CENT);
    req.feePerKb = fee;
    wallet.completeTx(req);
    assertEquals(Coin.valueOf(2270).divide(feeFactor), req.tx.getFee());
    wallet.commitTx(req.tx);
    SendRequest emptyReq = SendRequest.emptyWallet(myAddress);
    emptyReq.feePerKb = fee;
    emptyReq.ensureMinRequiredFee = true;
    emptyReq.emptyWallet = true;
    emptyReq.coinSelector = AllowUnconfirmedCoinSelector.get();
    wallet.completeTx(emptyReq);
    assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, emptyReq.tx.getFee());
    wallet.commitTx(emptyReq.tx);
}
项目:dashj    文件:WalletTest.java   
@Test
public void higherThanDefaultFee() throws InsufficientMoneyException {
    int feeFactor = 10;
    Coin fee = Transaction.DEFAULT_TX_FEE.multiply(feeFactor);
    receiveATransactionAmount(wallet, myAddress, Coin.COIN);
    SendRequest req = SendRequest.to(myAddress, Coin.CENT);
    req.feePerKb = fee;
    wallet.completeTx(req);
    assertEquals(Coin.valueOf(2270).multiply(feeFactor), req.tx.getFee());
    wallet.commitTx(req.tx);
    SendRequest emptyReq = SendRequest.emptyWallet(myAddress);
    emptyReq.feePerKb = fee;
    emptyReq.emptyWallet = true;
    emptyReq.coinSelector = AllowUnconfirmedCoinSelector.get();
    wallet.completeTx(emptyReq);
    assertEquals(Coin.valueOf(34200), emptyReq.tx.getFee());
    wallet.commitTx(emptyReq.tx);
}
项目:2FactorWallet    文件:Main.java   
public static void main(String[] args) throws BlockStoreException, UnknownHostException, InsufficientMoneyException {
    ConsoleAppender appender = new ConsoleAppender(
            new PatternLayout(PatternLayout.TTCC_CONVERSION_PATTERN), ConsoleAppender.SYSTEM_OUT);
    appender.setThreshold(Level.INFO);
    Logger.getRootLogger().addAppender(appender);
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            final JFrame frame = new JFrame("MainWindow");
            final MainWindow mainWindow = new MainWindow();
            frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
            frame.addWindowListener(new WindowAdapter() {
                @Override
                public void windowClosing(WindowEvent e) {
                    mainWindow.onClose();
                    frame.dispose();
                }
            });
            frame.setContentPane(mainWindow.panel1);
            frame.pack();
            //frame.setIconImage(Toolkit.getDefaultToolkit().getImage(getClass().getResource("/de/uni_bonn/bit/wallet_logo.png")));
            frame.setTitle("2Factor Wallet");
            frame.setVisible(true);
            mainWindow.startup();
        }
    });
}
项目:bitcoinj    文件:WalletTest.java   
@Test
public void lowerThanDefaultFee() throws InsufficientMoneyException {
    int feeFactor = 10;
    Coin fee = Transaction.DEFAULT_TX_FEE.divide(feeFactor);
    receiveATransactionAmount(wallet, myAddress, Coin.COIN);
    SendRequest req = SendRequest.to(myAddress, Coin.CENT);
    req.feePerKb = fee;
    wallet.completeTx(req);
    assertEquals(Coin.valueOf(22700).divide(feeFactor), req.tx.getFee());
    wallet.commitTx(req.tx);
    SendRequest emptyReq = SendRequest.emptyWallet(myAddress);
    emptyReq.feePerKb = fee;
    emptyReq.ensureMinRequiredFee = true;
    emptyReq.emptyWallet = true;
    emptyReq.coinSelector = AllowUnconfirmedCoinSelector.get();
    wallet.completeTx(emptyReq);
    assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, emptyReq.tx.getFee());
    wallet.commitTx(emptyReq.tx);
}
项目:bitcoinj    文件:WalletTest.java   
@Test
public void higherThanDefaultFee() throws InsufficientMoneyException {
    int feeFactor = 10;
    Coin fee = Transaction.DEFAULT_TX_FEE.multiply(feeFactor);
    receiveATransactionAmount(wallet, myAddress, Coin.COIN);
    SendRequest req = SendRequest.to(myAddress, Coin.CENT);
    req.feePerKb = fee;
    wallet.completeTx(req);
    assertEquals(Coin.valueOf(22700).multiply(feeFactor), req.tx.getFee());
    wallet.commitTx(req.tx);
    SendRequest emptyReq = SendRequest.emptyWallet(myAddress);
    emptyReq.feePerKb = fee;
    emptyReq.emptyWallet = true;
    emptyReq.coinSelector = AllowUnconfirmedCoinSelector.get();
    wallet.completeTx(emptyReq);
    assertEquals(Coin.valueOf(342000), emptyReq.tx.getFee());
    wallet.commitTx(emptyReq.tx);
}
项目:FJSTSeniorProjectSpring2017    文件:WalletController.java   
/** Sends Bitcoin to the specified bitcoin address.
 * @author Francis Fasola
 * @param address String representation of the public address.
 * @param amount The amount of Bitcoin to send.
 * @throws InsufficientMoneyException Not enough money.
 * @throws ExecutionException Error during execution.
 * @throws InterruptedException Error during execution. */
@SuppressWarnings("deprecation")
public void sendBitcoin(String address, String amount) 
            throws InsufficientMoneyException, ExecutionException, InterruptedException {
    Address destinationAddress = Address.fromBase58(params, address);
    SendRequest request = SendRequest.to(destinationAddress, Coin.parseCoin(amount));
    SendResult result = wallet.sendCoins(request);
    result.broadcastComplete.addListener(() -> {
        System.out.println("Coins were sent. Transaction hash: " + result.tx.getHashAsString());
    }, MoreExecutors.sameThreadExecutor());
}
项目:xwallet    文件:BitcoinSendAction.java   
/**
 *
 * @param callbacks
 */
@Override
public void execute(final CoinActionCallback<CurrencyCoin>... callbacks) {
    this._callbacks = callbacks;
    this._bitcoin.getWalletManager().wallet().addCoinsSentEventListener(this);

    Coin balance = _bitcoin.getWalletManager().wallet().getBalance();
    Coin amountCoin = Coin.parseCoin(_amount);

    Address addr = Address.fromBase58(_bitcoin.getWalletManager().wallet().getParams(), _address);
    SendRequest sendRequest = SendRequest.to(addr, amountCoin);

    Coin feeCoin = BitcoinManager.CalculateFeeTxSizeBytes(sendRequest.tx, sendRequest.feePerKb.getValue());

    long balValue = balance.getValue();
    long amountValue = amountCoin.getValue();
    long txFeeValue = feeCoin.getValue();

    if (amountValue + txFeeValue > balValue) {
        amountCoin = Coin.valueOf(balValue - txFeeValue);
        sendRequest = SendRequest.to(addr, amountCoin);
    }

    try {
        _bitcoin.getWalletManager().wallet().sendCoins(sendRequest);
    } catch (InsufficientMoneyException e) {

        for (CoinActionCallback<CurrencyCoin> callback : _callbacks) {
            callback.onError(_bitcoin);
        }
        e.printStackTrace();
    }
}
项目:bitnym    文件:TransactionGenerator.java   
public void sendBroadcastAnnouncement(BroadcastAnnouncement ba, File f, ProofMessage pm, int lockTime) throws InsufficientMoneyException {
    //build transaction
    Transaction tx = new Transaction(params);

    Script s = ba.buildScript();
    System.out.println("Script size is " + s.SIG_SIZE);
    //System.out.println(s.getScriptType());
    ECKey psnymKey = new ECKey();
    long unixTime = System.currentTimeMillis() / 1000L;
    //TODO use bitcoin nets median time
    tx.setLockTime(CLTVScriptPair.currentBitcoinBIP113Time(bc)-1);
    CLTVScriptPair sp = new CLTVScriptPair(psnymKey, CLTVScriptPair.currentBitcoinBIP113Time(bc)+lockTime);
    w.importKey(psnymKey);
    tx.addOutput(new TransactionOutput(params, tx, pm.getLastTransactionOutput().getValue().subtract(estimateBroadcastFee()), sp.getPubKeyScript().getProgram()));
    tx.addOutput(Coin.ZERO, s);
    tx.addInput(pm.getLastTransactionOutput());
    tx.getInput(0).setSequenceNumber(3); //the concrete value doesn't matter, this is just for cltv
    tx.getInput(0).setScriptSig(pm.getScriptPair().calculateSigScript(tx, 0, w));

    try {
        w.commitTx(tx);
        w.saveToFile(f);
    } catch (IOException e1) {
        e1.printStackTrace();
    }

    TransactionBroadcast broadcast = pg.broadcastTransaction(tx);
    pm.addTransaction(tx, 0, sp);
    pm.writeToFile();
    System.out.println("save broadcast announcement to file");



}
项目:bitnym    文件:BitNymWallet.java   
public void sendBroadcastAnnouncement(int lockTime) {
    try {
        System.out.println("sendBroadcastAnnouncement");
        //if(pm.isEmpty() || pm.getLastTransaction().getConfidence().getDepthInBlocks() == 0) {
        if(pm.isEmpty()) { //|| !pm.getLastTransaction().getConfidence().getConfidenceType().equals(TransactionConfidence.ConfidenceType.BUILDING)) {
            return;
        } else {
            tg.sendBroadcastAnnouncement(new BroadcastAnnouncement(ptp.getIdentifier().getTorAddress(), pm.getLastTransactionOutput().getValue().getValue(), 10), walletFile, pm, lockTime);
        }
    } catch (InsufficientMoneyException e) {
        e.printStackTrace();
    }
}
项目:cryptwallet    文件:WalletTest.java   
@Test(expected = InsufficientMoneyException.class)
public void watchingScriptsConfirmed() throws Exception {
    Address watchedAddress = new ECKey().toAddress(PARAMS);
    wallet.addWatchedAddress(watchedAddress);
    sendMoneyToWallet(BlockChain.NewBlockType.BEST_CHAIN, CENT, watchedAddress);
    assertEquals(CENT, wallet.getBalance());

    // We can't spend watched balances
    wallet.createSend(OTHER_ADDRESS, CENT);
}
项目:cryptwallet    文件:WalletTest.java   
@Test
public void importAndEncrypt() throws InsufficientMoneyException {
    Wallet encryptedWallet = new Wallet(PARAMS);
    encryptedWallet.encrypt(PASSWORD1);

    final ECKey key = new ECKey();
    encryptedWallet.importKeysAndEncrypt(ImmutableList.of(key), PASSWORD1);
    assertEquals(1, encryptedWallet.getImportedKeys().size());
    assertEquals(key.getPubKeyPoint(), encryptedWallet.getImportedKeys().get(0).getPubKeyPoint());
    sendMoneyToWallet(encryptedWallet, AbstractBlockChain.NewBlockType.BEST_CHAIN, Coin.COIN, key.toAddress(PARAMS));
    assertEquals(Coin.COIN, encryptedWallet.getBalance());
    SendRequest req = SendRequest.emptyWallet(OTHER_ADDRESS);
    req.aesKey = checkNotNull(encryptedWallet.getKeyCrypter()).deriveKey(PASSWORD1);
    encryptedWallet.sendCoinsOffline(req);
}
项目:cryptwallet    文件:WalletTest.java   
@Test(expected = Wallet.DustySendRequested.class)
public void sendDustTest() throws InsufficientMoneyException {
    // Tests sending dust, should throw DustySendRequested.
    Transaction tx = new Transaction(PARAMS);
    tx.addOutput(Transaction.MIN_NONDUST_OUTPUT.subtract(SATOSHI), OTHER_ADDRESS);
    SendRequest request = SendRequest.forTx(tx);
    request.ensureMinRequiredFee = true;
    wallet.completeTx(request);
}
项目:cryptwallet    文件:WalletTest.java   
@Test
public void sendCoinsWithBroadcasterTest() throws InsufficientMoneyException {
    ECKey key = ECKey.fromPrivate(BigInteger.TEN);
    receiveATransactionAmount(wallet, myAddress, Coin.COIN);
    MockTransactionBroadcaster broadcaster = new MockTransactionBroadcaster(wallet);
    wallet.setTransactionBroadcaster(broadcaster);
    SendRequest req = SendRequest.to(OTHER_ADDRESS.getParameters(), key, Coin.CENT);
    wallet.sendCoins(req);
}
项目:lbry-android    文件:BitWalletBase.java   
/**
 * Given a spend request containing an incomplete transaction, makes it valid by adding outputs and signed inputs
 * according to the instructions in the request. The transaction in the request is modified by this method.
 *
 * @param req a BitSendRequest that contains the incomplete transaction and details for how to make it valid.
 * @throws WalletAccountException if the request could not be completed due to not enough balance.
 * @throws IllegalArgumentException if you try and complete the same SendRequest twice
 */
public void completeTransaction(BitSendRequest req) throws WalletAccountException {
    lock.lock();
    try {
        transactionCreator.completeTx(req);
    } catch (InsufficientMoneyException e) {
        throw new WalletAccountException(e);
    } finally {
        lock.unlock();
    }
}
项目:exchange    文件:EmptyWalletWindow.java   
private void doEmptyWallet2(KeyParameter aesKey) {
    emptyWalletButton.setDisable(true);
    openOfferManager.removeAllOpenOffers(() -> {
        try {
            walletService.emptyWallet(addressInputTextField.getText(),
                    aesKey,
                    () -> {
                        closeButton.setText(Res.get("shared.close"));
                        balanceTextField.setText(formatter.formatCoinWithCode(walletService.getAvailableBalance()));
                        emptyWalletButton.setDisable(true);
                        log.debug("wallet empty successful");
                        onClose(() -> UserThread.runAfter(() -> new Popup<>()
                                .feedback(Res.get("emptyWalletWindow.sent.success"))
                                .show(), Transitions.DEFAULT_DURATION, TimeUnit.MILLISECONDS));
                        doClose();
                    },
                    (errorMessage) -> {
                        emptyWalletButton.setDisable(false);
                        log.debug("wallet empty failed " + errorMessage);
                    });
        } catch (InsufficientMoneyException | AddressFormatException e1) {
            e1.printStackTrace();
            log.error(e1.getMessage());
            emptyWalletButton.setDisable(false);
        }
    });
}
项目:exchange    文件:TradeManager.java   
public void onWithdrawRequest(String toAddress, Coin amount, Coin fee, KeyParameter aesKey,
                              Trade trade, ResultHandler resultHandler, FaultHandler faultHandler) {
    String fromAddress = btcWalletService.getOrCreateAddressEntry(trade.getId(),
            AddressEntry.Context.TRADE_PAYOUT).getAddressString();
    FutureCallback<Transaction> callback = new FutureCallback<Transaction>() {
        @Override
        public void onSuccess(@javax.annotation.Nullable Transaction transaction) {
            if (transaction != null) {
                log.debug("onWithdraw onSuccess tx ID:" + transaction.getHashAsString());
                addTradeToClosedTrades(trade);
                trade.setState(Trade.State.WITHDRAW_COMPLETED);
                resultHandler.handleResult();
            }
        }

        @Override
        public void onFailure(@NotNull Throwable t) {
            t.printStackTrace();
            log.error(t.getMessage());
            faultHandler.handleFault("An exception occurred at requestWithdraw (onFailure).", t);
        }
    };
    try {
        btcWalletService.sendFunds(fromAddress, toAddress, amount, fee, aesKey, AddressEntry.Context.TRADE_PAYOUT, callback);
    } catch (AddressFormatException | InsufficientMoneyException | AddressEntryException e) {
        e.printStackTrace();
        log.error(e.getMessage());
        faultHandler.handleFault("An exception occurred at requestWithdraw.", e);
    }
}
项目:dashj    文件:WalletTest.java   
@Test(expected = InsufficientMoneyException.class)
public void watchingScriptsConfirmed() throws Exception {
    Address watchedAddress = new ECKey().toAddress(PARAMS);
    wallet.addWatchedAddress(watchedAddress);
    sendMoneyToWallet(BlockChain.NewBlockType.BEST_CHAIN, CENT, watchedAddress);
    assertEquals(CENT, wallet.getBalance());

    // We can't spend watched balances
    wallet.createSend(OTHER_ADDRESS, CENT);
}
项目:dashj    文件:WalletTest.java   
@Test
public void importAndEncrypt() throws InsufficientMoneyException {
    Wallet encryptedWallet = new Wallet(PARAMS);
    encryptedWallet.encrypt(PASSWORD1);

    final ECKey key = new ECKey();
    encryptedWallet.importKeysAndEncrypt(ImmutableList.of(key), PASSWORD1);
    assertEquals(1, encryptedWallet.getImportedKeys().size());
    assertEquals(key.getPubKeyPoint(), encryptedWallet.getImportedKeys().get(0).getPubKeyPoint());
    sendMoneyToWallet(encryptedWallet, AbstractBlockChain.NewBlockType.BEST_CHAIN, Coin.COIN, key.toAddress(PARAMS));
    assertEquals(Coin.COIN, encryptedWallet.getBalance());
    SendRequest req = SendRequest.emptyWallet(OTHER_ADDRESS);
    req.aesKey = checkNotNull(encryptedWallet.getKeyCrypter()).deriveKey(PASSWORD1);
    encryptedWallet.sendCoinsOffline(req);
}
项目:dashj    文件:WalletTest.java   
@Test(expected = Wallet.DustySendRequested.class)
public void sendDustTest() throws InsufficientMoneyException {
    // Tests sending dust, should throw DustySendRequested.
    Transaction tx = new Transaction(PARAMS);
    tx.addOutput(Transaction.MIN_NONDUST_OUTPUT.subtract(SATOSHI), OTHER_ADDRESS);
    SendRequest request = SendRequest.forTx(tx);
    request.ensureMinRequiredFee = true;
    wallet.completeTx(request);
}
项目:dashj    文件:WalletTest.java   
@Test
public void sendCoinsWithBroadcasterTest() throws InsufficientMoneyException {
    ECKey key = ECKey.fromPrivate(BigInteger.TEN);
    receiveATransactionAmount(wallet, myAddress, Coin.COIN);
    MockTransactionBroadcaster broadcaster = new MockTransactionBroadcaster(wallet);
    wallet.setTransactionBroadcaster(broadcaster);
    SendRequest req = SendRequest.to(OTHER_ADDRESS.getParameters(), key, Coin.CENT);
    wallet.sendCoins(req);
}
项目:bitcoinj    文件:WalletTest.java   
@Test(expected = InsufficientMoneyException.class)
public void watchingScriptsConfirmed() throws Exception {
    Address watchedAddress = new ECKey().toAddress(PARAMS);
    wallet.addWatchedAddress(watchedAddress);
    sendMoneyToWallet(BlockChain.NewBlockType.BEST_CHAIN, CENT, watchedAddress);
    assertEquals(CENT, wallet.getBalance());

    // We can't spend watched balances
    wallet.createSend(OTHER_ADDRESS, CENT);
}
项目:bitcoinj    文件:WalletTest.java   
@Test
public void importAndEncrypt() throws InsufficientMoneyException {
    Wallet encryptedWallet = new Wallet(PARAMS);
    encryptedWallet.encrypt(PASSWORD1);

    final ECKey key = new ECKey();
    encryptedWallet.importKeysAndEncrypt(ImmutableList.of(key), PASSWORD1);
    assertEquals(1, encryptedWallet.getImportedKeys().size());
    assertEquals(key.getPubKeyPoint(), encryptedWallet.getImportedKeys().get(0).getPubKeyPoint());
    sendMoneyToWallet(encryptedWallet, AbstractBlockChain.NewBlockType.BEST_CHAIN, Coin.COIN, key.toAddress(PARAMS));
    assertEquals(Coin.COIN, encryptedWallet.getBalance());
    SendRequest req = SendRequest.emptyWallet(OTHER_ADDRESS);
    req.aesKey = checkNotNull(encryptedWallet.getKeyCrypter()).deriveKey(PASSWORD1);
    encryptedWallet.sendCoinsOffline(req);
}
项目:bitcoinj    文件:WalletTest.java   
@Test(expected = Wallet.DustySendRequested.class)
public void sendDustTest() throws InsufficientMoneyException {
    // Tests sending dust, should throw DustySendRequested.
    Transaction tx = new Transaction(PARAMS);
    tx.addOutput(Transaction.MIN_NONDUST_OUTPUT.subtract(SATOSHI), OTHER_ADDRESS);
    SendRequest request = SendRequest.forTx(tx);
    request.ensureMinRequiredFee = true;
    wallet.completeTx(request);
}
项目:bitcoinj    文件:WalletTest.java   
@Test
public void sendCoinsWithBroadcasterTest() throws InsufficientMoneyException {
    ECKey key = ECKey.fromPrivate(BigInteger.TEN);
    receiveATransactionAmount(wallet, myAddress, Coin.COIN);
    MockTransactionBroadcaster broadcaster = new MockTransactionBroadcaster(wallet);
    wallet.setTransactionBroadcaster(broadcaster);
    SendRequest req = SendRequest.to(OTHER_ADDRESS.getParameters(), key, Coin.CENT);
    wallet.sendCoins(req);
}
项目:okwallet    文件:Wallet.java   
/**
 * <p>Sends coins according to the given request, via the given {@link TransactionBroadcaster}.</p>
 *
 * <p>The returned object provides both the transaction, and a future that can be used to learn when the broadcast
 * is complete. Complete means, if the PeerGroup is limited to only one connection, when it was written out to
 * the socket. Otherwise when the transaction is written out and we heard it back from a different peer.</p>
 *
 * <p>Note that the sending transaction is committed to the wallet immediately, not when the transaction is
 * successfully broadcast. This means that even if the network hasn't heard about your transaction you won't be
 * able to spend those same coins again.</p>
 *
 * @param broadcaster the target to use for broadcast.
 * @param request the SendRequest that describes what to do, get one using static methods on SendRequest itself.
 * @return An object containing the transaction that was created, and a future for the broadcast of it.
 * @throws InsufficientMoneyException if the request could not be completed due to not enough balance.
 * @throws IllegalArgumentException if you try and complete the same SendRequest twice
 * @throws DustySendRequested if the resultant transaction would violate the dust rules.
 * @throws CouldNotAdjustDownwards if emptying the wallet was requested and the output can't be shrunk for fees without violating a protocol rule.
 * @throws ExceededMaxTransactionSize if the resultant transaction is too big for Bitcoin to process.
 * @throws MultipleOpReturnRequested if there is more than one OP_RETURN output for the resultant transaction.
 */
public SendResult sendCoins(TransactionBroadcaster broadcaster, SendRequest request) throws InsufficientMoneyException {
    // Should not be locked here, as we're going to call into the broadcaster and that might want to hold its
    // own lock. sendCoinsOffline handles everything that needs to be locked.
    checkState(!lock.isHeldByCurrentThread());

    // Commit the TX to the wallet immediately so the spent coins won't be reused.
    // TODO: We should probably allow the request to specify tx commit only after the network has accepted it.
    Transaction tx = sendCoinsOffline(request);
    SendResult result = new SendResult();
    result.tx = tx;
    // The tx has been committed to the pending pool by this point (via sendCoinsOffline -> commitTx), so it has
    // a txConfidenceListener registered. Once the tx is broadcast the peers will update the memory pool with the
    // count of seen peers, the memory pool will update the transaction confidence object, that will invoke the
    // txConfidenceListener which will in turn invoke the wallets event listener onTransactionConfidenceChanged
    // method.
    result.broadcast = broadcaster.broadcastTransaction(tx);
    result.broadcastComplete = result.broadcast.future();
    return result;
}
项目:cryptwallet    文件:Wallet.java   
/**
 * <p>Sends coins according to the given request, via the given {@link TransactionBroadcaster}.</p>
 *
 * <p>The returned object provides both the transaction, and a future that can be used to learn when the broadcast
 * is complete. Complete means, if the PeerGroup is limited to only one connection, when it was written out to
 * the socket. Otherwise when the transaction is written out and we heard it back from a different peer.</p>
 *
 * <p>Note that the sending transaction is committed to the wallet immediately, not when the transaction is
 * successfully broadcast. This means that even if the network hasn't heard about your transaction you won't be
 * able to spend those same coins again.</p>
 *
 * @param broadcaster the target to use for broadcast.
 * @param request the SendRequest that describes what to do, get one using static methods on SendRequest itself.
 * @return An object containing the transaction that was created, and a future for the broadcast of it.
 * @throws InsufficientMoneyException if the request could not be completed due to not enough balance.
 * @throws IllegalArgumentException if you try and complete the same SendRequest twice
 * @throws DustySendRequested if the resultant transaction would violate the dust rules.
 * @throws CouldNotAdjustDownwards if emptying the wallet was requested and the output can't be shrunk for fees without violating a protocol rule.
 * @throws ExceededMaxTransactionSize if the resultant transaction is too big for Bitcoin to process.
 * @throws MultipleOpReturnRequested if there is more than one OP_RETURN output for the resultant transaction.
 */
public SendResult sendCoins(TransactionBroadcaster broadcaster, SendRequest request) throws InsufficientMoneyException {
    // Should not be locked here, as we're going to call into the broadcaster and that might want to hold its
    // own lock. sendCoinsOffline handles everything that needs to be locked.
    checkState(!lock.isHeldByCurrentThread());

    // Commit the TX to the wallet immediately so the spent coins won't be reused.
    // TODO: We should probably allow the request to specify tx commit only after the network has accepted it.
    Transaction tx = sendCoinsOffline(request);
    SendResult result = new SendResult();
    result.tx = tx;
    // The tx has been committed to the pending pool by this point (via sendCoinsOffline -> commitTx), so it has
    // a txConfidenceListener registered. Once the tx is broadcast the peers will update the memory pool with the
    // count of seen peers, the memory pool will update the transaction confidence object, that will invoke the
    // txConfidenceListener which will in turn invoke the wallets event listener onTransactionConfidenceChanged
    // method.
    result.broadcast = broadcaster.broadcastTransaction(tx);
    result.broadcastComplete = result.broadcast.future();
    return result;
}
项目:cryptwallet    文件:WalletTest.java   
@Test(expected = java.lang.IllegalStateException.class)
public void sendCoinsNoBroadcasterTest() throws InsufficientMoneyException {
    ECKey key = ECKey.fromPrivate(BigInteger.TEN);
    SendRequest req = SendRequest.to(OTHER_ADDRESS.getParameters(), key, SATOSHI.multiply(12));
    wallet.sendCoins(req);
}
项目:namecoinj    文件:PaymentChannelClientConnection.java   
/**
 * Attempts to open a new connection to and open a payment channel with the given host and port, blocking until the
 * connection is open.  The server is requested to keep the channel open for {@param timeWindow}
 * seconds. If the server proposes a longer time the channel will be closed.
 *
 * @param server The host/port pair where the server is listening.
 * @param timeoutSeconds The connection timeout and read timeout during initialization. This should be large enough
 *                       to accommodate ECDSA signature operations and network latency.
 * @param wallet The wallet which will be paid from, and where completed transactions will be committed.
 *               Must already have a {@link StoredPaymentChannelClientStates} object in its extensions set.
 * @param myKey A freshly generated keypair used for the multisig contract and refund output.
 * @param maxValue The maximum value this channel is allowed to request
 * @param serverId A unique ID which is used to attempt reopening of an existing channel.
 *                 This must be unique to the server, and, if your application is exposing payment channels to some
 *                 API, this should also probably encompass some caller UID to avoid applications opening channels
 *                 which were created by others.
 * @param timeWindow The time in seconds, relative to now, on how long this channel should be kept open.
 *
 * @throws IOException if there's an issue using the network.
 * @throws ValueOutOfRangeException if the balance of wallet is lower than maxValue.
 */
public PaymentChannelClientConnection(InetSocketAddress server, int timeoutSeconds, Wallet wallet, ECKey myKey,
                                      Coin maxValue, String serverId, final long timeWindow) throws IOException, ValueOutOfRangeException {
    // Glue the object which vends/ingests protobuf messages in order to manage state to the network object which
    // reads/writes them to the wire in length prefixed form.
    channelClient = new PaymentChannelClient(wallet, myKey, maxValue, Sha256Hash.create(serverId.getBytes()), timeWindow,
          new PaymentChannelClient.ClientConnection() {
        @Override
        public void sendToServer(Protos.TwoWayChannelMessage msg) {
            wireParser.write(msg);
        }

        @Override
        public void destroyConnection(PaymentChannelCloseException.CloseReason reason) {
            channelOpenFuture.setException(new PaymentChannelCloseException("Payment channel client requested that the connection be closed: " + reason, reason));
            wireParser.closeConnection();
        }

        @Override
        public boolean acceptExpireTime(long expireTime) {
            return expireTime <= (timeWindow + Utils.currentTimeSeconds() + 60);  // One extra minute to compensate for time skew and latency
        }

        @Override
        public void channelOpen(boolean wasInitiated) {
            wireParser.setSocketTimeout(0);
            // Inform the API user that we're done and ready to roll.
            channelOpenFuture.set(PaymentChannelClientConnection.this);
        }
    });

    // And glue back in the opposite direction - network to the channelClient.
    wireParser = new ProtobufParser<Protos.TwoWayChannelMessage>(new ProtobufParser.Listener<Protos.TwoWayChannelMessage>() {
        @Override
        public void messageReceived(ProtobufParser<Protos.TwoWayChannelMessage> handler, Protos.TwoWayChannelMessage msg) {
            try {
                channelClient.receiveMessage(msg);
            } catch (InsufficientMoneyException e) {
                // We should only get this exception during INITIATE, so channelOpen wasn't called yet.
                channelOpenFuture.setException(e);
            }
        }

        @Override
        public void connectionOpen(ProtobufParser<Protos.TwoWayChannelMessage> handler) {
            channelClient.connectionOpen();
        }

        @Override
        public void connectionClosed(ProtobufParser<Protos.TwoWayChannelMessage> handler) {
            channelClient.connectionClosed();
            channelOpenFuture.setException(new PaymentChannelCloseException("The TCP socket died",
                    PaymentChannelCloseException.CloseReason.CONNECTION_CLOSED));
        }
    }, Protos.TwoWayChannelMessage.getDefaultInstance(), Short.MAX_VALUE, timeoutSeconds*1000);

    // Initiate the outbound network connection. We don't need to keep this around. The wireParser object will handle
    // things from here on out.
    new NioClient(server, wireParser, timeoutSeconds * 1000);
}
项目:CoinJoin    文件:PaymentChannelClientConnection.java   
/**
 * Attempts to open a new connection to and open a payment channel with the given host and port, blocking until the
 * connection is open.  The server is requested to keep the channel open for {@param timeWindow}
 * seconds. If the server proposes a longer time the channel will be closed.
 *
 * @param server The host/port pair where the server is listening.
 * @param timeoutSeconds The connection timeout and read timeout during initialization. This should be large enough
 *                       to accommodate ECDSA signature operations and network latency.
 * @param wallet The wallet which will be paid from, and where completed transactions will be committed.
 *               Must already have a {@link StoredPaymentChannelClientStates} object in its extensions set.
 * @param myKey A freshly generated keypair used for the multisig contract and refund output.
 * @param maxValue The maximum value this channel is allowed to request
 * @param serverId A unique ID which is used to attempt reopening of an existing channel.
 *                 This must be unique to the server, and, if your application is exposing payment channels to some
 *                 API, this should also probably encompass some caller UID to avoid applications opening channels
 *                 which were created by others.
 * @param timeWindow The time in seconds, relative to now, on how long this channel should be kept open.
 *
 * @throws IOException if there's an issue using the network.
 * @throws ValueOutOfRangeException if the balance of wallet is lower than maxValue.
 */
public PaymentChannelClientConnection(InetSocketAddress server, int timeoutSeconds, Wallet wallet, ECKey myKey,
                                      Coin maxValue, String serverId, final long timeWindow) throws IOException, ValueOutOfRangeException {
    // Glue the object which vends/ingests protobuf messages in order to manage state to the network object which
    // reads/writes them to the wire in length prefixed form.
    channelClient = new PaymentChannelClient(wallet, myKey, maxValue, Sha256Hash.create(serverId.getBytes()), timeWindow,
          new PaymentChannelClient.ClientConnection() {
        @Override
        public void sendToServer(Protos.TwoWayChannelMessage msg) {
            wireParser.write(msg);
        }

        @Override
        public void destroyConnection(PaymentChannelCloseException.CloseReason reason) {
            channelOpenFuture.setException(new PaymentChannelCloseException("Payment channel client requested that the connection be closed: " + reason, reason));
            wireParser.closeConnection();
        }

        @Override
        public boolean acceptExpireTime(long expireTime) {
            return expireTime <= (timeWindow + Utils.currentTimeSeconds() + 60);  // One extra minute to compensate for time skew and latency
        }

        @Override
        public void channelOpen(boolean wasInitiated) {
            wireParser.setSocketTimeout(0);
            // Inform the API user that we're done and ready to roll.
            channelOpenFuture.set(PaymentChannelClientConnection.this);
        }
    });

    // And glue back in the opposite direction - network to the channelClient.
    wireParser = new ProtobufParser<Protos.TwoWayChannelMessage>(new ProtobufParser.Listener<Protos.TwoWayChannelMessage>() {
        @Override
        public void messageReceived(ProtobufParser<Protos.TwoWayChannelMessage> handler, Protos.TwoWayChannelMessage msg) {
            try {
                channelClient.receiveMessage(msg);
            } catch (InsufficientMoneyException e) {
                // We should only get this exception during INITIATE, so channelOpen wasn't called yet.
                channelOpenFuture.setException(e);
            }
        }

        @Override
        public void connectionOpen(ProtobufParser<Protos.TwoWayChannelMessage> handler) {
            channelClient.connectionOpen();
        }

        @Override
        public void connectionClosed(ProtobufParser<Protos.TwoWayChannelMessage> handler) {
            channelClient.connectionClosed();
            channelOpenFuture.setException(new PaymentChannelCloseException("The TCP socket died",
                    PaymentChannelCloseException.CloseReason.CONNECTION_CLOSED));
        }
    }, Protos.TwoWayChannelMessage.getDefaultInstance(), Short.MAX_VALUE, timeoutSeconds*1000);

    // Initiate the outbound network connection. We don't need to keep this around. The wireParser object will handle
    // things from here on out.
    new NioClient(server, wireParser, timeoutSeconds * 1000);
}
项目:coinblesk-server    文件:MicropaymentService.java   
@Transactional(isolation = Isolation.SERIALIZABLE)
public PayoutResponse payOutVirtualBalance(ECKey accountOwner, String addressAsString) throws UserNotFoundException,
    InsufficientMoneyException, IOException, BusinessException, InsufficientFunds {
    final Address toAddress = Address.fromBase58(appConfig.getNetworkParameters(), addressAsString);

    final Account account = accountService.getByClientPublicKey(accountOwner.getPubKey());
    if (account == null)
        throw new UserNotFoundException(accountOwner.getPublicKeyAsHex());

    final Coin virtualBalance = Coin.valueOf(account.virtualBalance());
    if (!virtualBalance.isPositive())
        throw new InsufficientFunds();

    final Coin potValue = getMicroPaymentPotValue();
    LOG.info("Micropot value is {}", potValue);
    if (potValue.isLessThan(virtualBalance)) {
        eventService.warn(MICRO_PAYMENT_POT_EXHAUSTED, "Not enough coin in pot. " + virtualBalance + " needed " +
        "but only " + potValue + " available.");
        return new PayoutResponse();
    }

    Address changeAddress = appConfig.getMicroPaymentPotPrivKey().toAddress(appConfig.getNetworkParameters());

    // Estimate fee by creating a send request
    final Coin feePer1000Bytes = Coin.valueOf(feeService.fee() * 1000);
    SendRequest estimateRequest = SendRequest.to(toAddress, virtualBalance);
    estimateRequest.feePerKb = feePer1000Bytes;
    estimateRequest.changeAddress = changeAddress;
    walletService.getWallet().completeTx(estimateRequest);
    final Coin requiredFee = estimateRequest.tx.getFee();

    // Make actual request which subtracts fee from virtual balance
    final Coin coinSendToUser = virtualBalance.minus(requiredFee);
    SendRequest actualRequest = SendRequest.to(toAddress, coinSendToUser);
    actualRequest.feePerKb = feePer1000Bytes;
    actualRequest.changeAddress = changeAddress;
    Wallet.SendResult sendResult =  walletService.getWallet().sendCoins(actualRequest);

    // At this point we must consider the coins to be gone, even in case of failure as it has been transmitted
    // to the broadcaster.
    account.virtualBalance(0L);
    accountRepository.save(account);

    // Wait for actual broadcast to succeed
    Transaction broadcastedTx;
    try {
        broadcastedTx = sendResult.broadcastComplete.get();
    } catch (InterruptedException | ExecutionException e) {
        eventService.error(EventType.MICRO_PAYMENT_PAYOUT_ERROR, "Could not broadcast payout request "
            + "for account " + accountOwner.getPublicKeyAsHex() + ". Transaction: "
            + DTOUtils.toHex(sendResult.tx.bitcoinSerialize()) + " Reason:" + e.toString());
        e.printStackTrace();
        return new PayoutResponse();
    }

    PayoutResponse response = new PayoutResponse();
    response.transaction = DTOUtils.toHex(broadcastedTx.bitcoinSerialize());
    response.valuePaidOut = coinSendToUser.getValue();
    return response;
}
项目:exchange    文件:CreateOfferDataModel.java   
public void estimateTxSize() {
    txFeeFromFeeService = feeService.getTxFee(feeTxSize);
    Address fundingAddress = btcWalletService.getOrCreateAddressEntry(AddressEntry.Context.AVAILABLE).getAddress();
    Address reservedForTradeAddress = btcWalletService.getOrCreateAddressEntry(offerId, AddressEntry.Context.RESERVED_FOR_TRADE).getAddress();
    Address changeAddress = btcWalletService.getOrCreateAddressEntry(AddressEntry.Context.AVAILABLE).getAddress();

    Coin reservedFundsForOffer = getSecurityDeposit();
    if (!isBuyOffer())
        reservedFundsForOffer = reservedFundsForOffer.add(amount.get());

    checkNotNull(user.getAcceptedArbitrators(), "user.getAcceptedArbitrators() must not be null");
    checkArgument(!user.getAcceptedArbitrators().isEmpty(), "user.getAcceptedArbitrators() must not be empty");
    String dummyArbitratorAddress = user.getAcceptedArbitrators().get(0).getBtcAddress();
    try {
        log.info("We create a dummy tx to see if our estimated size is in the accepted range. feeTxSize={}," +
                        " txFee based on feeTxSize: {}, recommended txFee is {} sat/byte",
                feeTxSize, txFeeFromFeeService.toFriendlyString(), feeService.getTxFeePerByte());
        Transaction tradeFeeTx = tradeWalletService.estimateBtcTradingFeeTxSize(
                fundingAddress,
                reservedForTradeAddress,
                changeAddress,
                reservedFundsForOffer,
                true,
                getMakerFee(),
                txFeeFromFeeService,
                dummyArbitratorAddress);

        final int txSize = tradeFeeTx.bitcoinSerialize().length;
        // use feeTxSizeEstimationRecursionCounter to avoid risk for endless loop
        if (txSize > feeTxSize * 1.2 && feeTxSizeEstimationRecursionCounter < 10) {
            feeTxSizeEstimationRecursionCounter++;
            log.info("txSize is {} bytes but feeTxSize used for txFee calculation was {} bytes. We try again with an " +
                    "adjusted txFee to reach the target tx fee.", txSize, feeTxSize);
            feeTxSize = txSize;
            txFeeFromFeeService = feeService.getTxFee(feeTxSize);
            // lets try again with the adjusted txSize and fee.
            estimateTxSize();
        } else {
            log.info("feeTxSize {} bytes", feeTxSize);
            log.info("txFee based on estimated size: {}, recommended txFee is {} sat/byte",
                    txFeeFromFeeService.toFriendlyString(), feeService.getTxFeePerByte());
        }
    } catch (InsufficientMoneyException e) {
        // If we need to fund from an external wallet we can assume we only have 1 input (260 bytes).
        log.warn("We cannot do the fee estimation because there are not enough funds in the wallet. This is expected " +
                "if the user pays from an external wallet. In that case we use an estimated tx size of 260 bytes.");
        feeTxSize = 260;
        txFeeFromFeeService = feeService.getTxFee(feeTxSize);
        log.info("feeTxSize {} bytes", feeTxSize);
        log.info("txFee based on estimated size: {}, recommended txFee is {} sat/byte",
                txFeeFromFeeService.toFriendlyString(), feeService.getTxFeePerByte());
    }
}
项目:exchange    文件:TakeOfferDataModel.java   
public void estimateTxSize() {
    Address fundingAddress = btcWalletService.getOrCreateAddressEntry(AddressEntry.Context.AVAILABLE).getAddress();
    int txSize = 0;
    if (btcWalletService.getBalance(Wallet.BalanceType.AVAILABLE).isPositive()) {
        txFeeFromFeeService = getTxFeeBySize(feeTxSize);

        Address reservedForTradeAddress = btcWalletService.getOrCreateAddressEntry(offer.getId(), AddressEntry.Context.RESERVED_FOR_TRADE).getAddress();
        Address changeAddress = btcWalletService.getOrCreateAddressEntry(AddressEntry.Context.AVAILABLE).getAddress();

        Coin reservedFundsForOffer = getSecurityDeposit().add(txFeeFromFeeService).add(txFeeFromFeeService);
        if (isBuyOffer())
            reservedFundsForOffer = reservedFundsForOffer.add(amount.get());

        checkNotNull(user.getAcceptedArbitrators(), "user.getAcceptedArbitrators() must not be null");
        checkArgument(!user.getAcceptedArbitrators().isEmpty(), "user.getAcceptedArbitrators() must not be empty");
        String dummyArbitratorAddress = user.getAcceptedArbitrators().get(0).getBtcAddress();
        try {
            log.debug("We create a dummy tx to see if our estimated size is in the accepted range. feeTxSize={}," +
                            " txFee based on feeTxSize: {}, recommended txFee is {} sat/byte",
                    feeTxSize, txFeeFromFeeService.toFriendlyString(), feeService.getTxFeePerByte());
            Transaction tradeFeeTx = tradeWalletService.estimateBtcTradingFeeTxSize(
                    fundingAddress,
                    reservedForTradeAddress,
                    changeAddress,
                    reservedFundsForOffer,
                    true,
                    getTakerFee(),
                    txFeeFromFeeService,
                    dummyArbitratorAddress);

            txSize = tradeFeeTx.bitcoinSerialize().length;
            // use feeTxSizeEstimationRecursionCounter to avoid risk for endless loop
            // We use the tx size for the trade fee tx as target for the fees.
            // The deposit and payout txs are determined +/- 1 output but the trade fee tx can have either 1 or many inputs
            // so we need to make sure the trade fee tx gets the correct fee to not get stuck.
            // We use a 20% tolerance frm out default 320 byte size (typical for deposit and payout) and only if we get a
            // larger size we increase the fee. Worst case is that we overpay for the other follow up txs, but better than
            // use a too low fee and get stuck.
            if (txSize > feeTxSize * 1.2 && feeTxSizeEstimationRecursionCounter < 10) {
                feeTxSizeEstimationRecursionCounter++;
                log.info("txSize is {} bytes but feeTxSize used for txFee calculation was {} bytes. We try again with an " +
                        "adjusted txFee to reach the target tx fee.", txSize, feeTxSize);

                feeTxSize = txSize;
                txFeeFromFeeService = getTxFeeBySize(txSize);

                // lets try again with the adjusted txSize and fee.
                estimateTxSize();
            } else {
                // We are done with estimation iterations
                if (feeTxSizeEstimationRecursionCounter < 10)
                    log.info("Fee estimation completed:\n" +
                                    "txFee based on estimated size of {} bytes. Average tx size = {} bytes. Actual tx size = {} bytes. TxFee is {} ({} sat/byte)",
                            feeTxSize, getAverageSize(feeTxSize), txSize, txFeeFromFeeService.toFriendlyString(), feeService.getTxFeePerByte());
                else
                    log.warn("We could not estimate the fee as the feeTxSizeEstimationRecursionCounter exceeded our limit of 10 recursions.\n" +
                                    "txFee based on estimated size of {} bytes. Average tx size = {} bytes. Actual tx size = {} bytes. " +
                                    "TxFee is {} ({} sat/byte)",
                            feeTxSize, getAverageSize(feeTxSize), txSize, txFeeFromFeeService.toFriendlyString(), feeService.getTxFeePerByte());
            }
        } catch (InsufficientMoneyException e) {
            log.info("We cannot complete the fee estimation because there are not enough funds in the wallet.\n" +
                            "This is expected if the user has not sufficient funds yet.\n" +
                            "In that case we use the latest estimated tx size or the default if none has been calculated yet.\n" +
                            "txFee based on estimated size of {} bytes. Average tx size = {} bytes. Actual tx size = {} bytes. TxFee is {} ({} sat/byte)",
                    feeTxSize, getAverageSize(feeTxSize), txSize, txFeeFromFeeService.toFriendlyString(), feeService.getTxFeePerByte());
        }
    } else {
        feeTxSize = 320;
        txFeeFromFeeService = getTxFeeBySize(feeTxSize);
        log.info("We cannot do the fee estimation because there are no funds in the wallet.\nThis is expected " +
                        "if the user has not funded his wallet yet.\n" +
                        "In that case we use an estimated tx size of 320 bytes.\n" +
                        "txFee based on estimated size of {} bytes. Average tx size = {} bytes. Actual tx size = {} bytes. TxFee is {} ({} sat/byte)",
                feeTxSize, getAverageSize(feeTxSize), txSize, txFeeFromFeeService.toFriendlyString(), feeService.getTxFeePerByte());
    }
}
项目:dashj    文件:WalletTest.java   
@Test(expected = java.lang.IllegalStateException.class)
public void sendCoinsNoBroadcasterTest() throws InsufficientMoneyException {
    ECKey key = ECKey.fromPrivate(BigInteger.TEN);
    SendRequest req = SendRequest.to(OTHER_ADDRESS.getParameters(), key, SATOSHI.multiply(12));
    wallet.sendCoins(req);
}
项目:bitcoinj    文件:Wallet.java   
/**
 * <p>Sends coins according to the given request, via the given {@link TransactionBroadcaster}.</p>
 *
 * <p>The returned object provides both the transaction, and a future that can be used to learn when the broadcast
 * is complete. Complete means, if the PeerGroup is limited to only one connection, when it was written out to
 * the socket. Otherwise when the transaction is written out and we heard it back from a different peer.</p>
 *
 * <p>Note that the sending transaction is committed to the wallet immediately, not when the transaction is
 * successfully broadcast. This means that even if the network hasn't heard about your transaction you won't be
 * able to spend those same coins again.</p>
 *
 * @param broadcaster the target to use for broadcast.
 * @param request the SendRequest that describes what to do, get one using static methods on SendRequest itself.
 * @return An object containing the transaction that was created, and a future for the broadcast of it.
 * @throws InsufficientMoneyException if the request could not be completed due to not enough balance.
 * @throws IllegalArgumentException if you try and complete the same SendRequest twice
 * @throws DustySendRequested if the resultant transaction would violate the dust rules.
 * @throws CouldNotAdjustDownwards if emptying the wallet was requested and the output can't be shrunk for fees without violating a protocol rule.
 * @throws ExceededMaxTransactionSize if the resultant transaction is too big for Bitcoin to process.
 * @throws MultipleOpReturnRequested if there is more than one OP_RETURN output for the resultant transaction.
 */
public SendResult sendCoins(TransactionBroadcaster broadcaster, SendRequest request) throws InsufficientMoneyException {
    // Should not be locked here, as we're going to call into the broadcaster and that might want to hold its
    // own lock. sendCoinsOffline handles everything that needs to be locked.
    checkState(!lock.isHeldByCurrentThread());

    // Commit the TX to the wallet immediately so the spent coins won't be reused.
    // TODO: We should probably allow the request to specify tx commit only after the network has accepted it.
    Transaction tx = sendCoinsOffline(request);
    SendResult result = new SendResult();
    result.tx = tx;
    // The tx has been committed to the pending pool by this point (via sendCoinsOffline -> commitTx), so it has
    // a txConfidenceListener registered. Once the tx is broadcast the peers will update the memory pool with the
    // count of seen peers, the memory pool will update the transaction confidence object, that will invoke the
    // txConfidenceListener which will in turn invoke the wallets event listener onTransactionConfidenceChanged
    // method.
    result.broadcast = broadcaster.broadcastTransaction(tx);
    result.broadcastComplete = result.broadcast.future();
    return result;
}