@Test public void oneTx() throws Exception { // Check basic tx serialization. Coin v1 = COIN; Transaction t1 = createFakeTx(params, v1, myAddress); t1.getConfidence().markBroadcastBy(new PeerAddress(InetAddress.getByName("1.2.3.4"))); t1.getConfidence().markBroadcastBy(new PeerAddress(InetAddress.getByName("5.6.7.8"))); t1.getConfidence().setSource(TransactionConfidence.Source.NETWORK); myWallet.receivePending(t1, null); Wallet wallet1 = roundTrip(myWallet); assertEquals(1, wallet1.getTransactions(true).size()); assertEquals(v1, wallet1.getBalance(Wallet.BalanceType.ESTIMATED)); Transaction t1copy = wallet1.getTransaction(t1.getHash()); assertArrayEquals(t1.bitcoinSerialize(), t1copy.bitcoinSerialize()); assertEquals(2, t1copy.getConfidence().numBroadcastPeers()); assertEquals(TransactionConfidence.Source.NETWORK, t1copy.getConfidence().getSource()); Protos.Wallet walletProto = new WalletProtobufSerializer().walletToProto(myWallet); assertEquals(Protos.Key.Type.ORIGINAL, walletProto.getKey(0).getType()); assertEquals(0, walletProto.getExtensionCount()); assertEquals(1, walletProto.getTransactionCount()); assertEquals(6, walletProto.getKeyCount()); Protos.Transaction t1p = walletProto.getTransaction(0); assertEquals(0, t1p.getBlockHashCount()); assertArrayEquals(t1.getHash().getBytes(), t1p.getHash().toByteArray()); assertEquals(Protos.Transaction.Pool.PENDING, t1p.getPool()); assertFalse(t1p.hasLockTime()); assertFalse(t1p.getTransactionInput(0).hasSequence()); assertArrayEquals( t1.getInputs().get(0).getOutpoint().getHash().getBytes(), t1p.getTransactionInput(0).getTransactionOutPointHash().toByteArray()); assertEquals(0, t1p.getTransactionInput(0).getTransactionOutPointIndex()); assertEquals(t1p.getTransactionOutput(0).getValue(), v1.value); }
@Test public void testRoundTripNormalWallet() throws Exception { Wallet wallet1 = roundTrip(myWallet); assertEquals(0, wallet1.getTransactions(true).size()); assertEquals(Coin.ZERO, wallet1.getBalance()); assertArrayEquals( myKey.getPubKey(), wallet1.findKeyFromPubHash(myKey.getPubKeyHash()).getPubKey()); assertArrayEquals( myKey.getPrivKeyBytes(), wallet1.findKeyFromPubHash(myKey.getPubKeyHash()).getPrivKeyBytes()); assertEquals( myKey.getCreationTimeSeconds(), wallet1.findKeyFromPubHash(myKey.getPubKeyHash()).getCreationTimeSeconds()); }
@Test public void doubleSpend() throws Exception { // Check that we can serialize double spends correctly, as this is a slightly tricky case. FakeTxBuilder.DoubleSpends doubleSpends = FakeTxBuilder.createFakeDoubleSpendTxns(params, myAddress); // t1 spends to our wallet. myWallet.receivePending(doubleSpends.t1, null); // t2 rolls back t1 and spends somewhere else. myWallet.receiveFromBlock(doubleSpends.t2, null, BlockChain.NewBlockType.BEST_CHAIN, 0); Wallet wallet1 = roundTrip(myWallet); assertEquals(1, wallet1.getTransactions(true).size()); Transaction t1 = wallet1.getTransaction(doubleSpends.t1.getHash()); assertEquals(ConfidenceType.DEAD, t1.getConfidence().getConfidenceType()); assertEquals(Coin.ZERO, wallet1.getBalance()); // TODO: Wallet should store overriding transactions even if they are not wallet-relevant. // assertEquals(doubleSpends.t2, t1.getConfidence().getOverridingTransaction()); }
@Test public void empty() throws Exception { // Check the base case of a wallet with one key and no transactions. Wallet wallet1 = roundTrip(myWallet); assertEquals(0, wallet1.getTransactions(true).size()); assertEquals(Coin.ZERO, wallet1.getBalance()); assertArrayEquals( myKey.getPubKey(), wallet1.findKeyFromPubHash(myKey.getPubKeyHash()).getPubKey()); assertArrayEquals( myKey.getPrivKeyBytes(), wallet1.findKeyFromPubHash(myKey.getPubKeyHash()).getPrivKeyBytes()); assertEquals( myKey.getCreationTimeSeconds(), wallet1.findKeyFromPubHash(myKey.getPubKeyHash()).getCreationTimeSeconds()); assertEquals(mScriptCreationTime, wallet1.getWatchedScripts().get(0).getCreationTimeSeconds()); assertEquals(1, wallet1.getWatchedScripts().size()); assertEquals( ScriptBuilder.createOutputScript(myWatchedKey.toAddress(params)), wallet1.getWatchedScripts().get(0)); assertEquals(WALLET_DESCRIPTION, wallet1.getDescription()); }
@Test public void testRoundTripMarriedWallet() throws Exception { // create 2-of-2 married wallet myWallet = new Wallet(params); final DeterministicKeyChain partnerChain = new DeterministicKeyChain(new SecureRandom()); DeterministicKey partnerKey = DeterministicKey.deserializeB58( null, partnerChain.getWatchingKey().serializePubB58(params), params); MarriedKeyChain chain = MarriedKeyChain.builder() .random(new SecureRandom()) .followingKeys(partnerKey) .threshold(2) .build(); myWallet.addAndActivateHDChain(chain); myAddress = myWallet.currentAddress(KeyChain.KeyPurpose.RECEIVE_FUNDS); Wallet wallet1 = roundTrip(myWallet); assertEquals(0, wallet1.getTransactions(true).size()); assertEquals(Coin.ZERO, wallet1.getBalance()); assertEquals(2, wallet1.getActiveKeyChain().getSigsRequiredToSpend()); assertEquals(myAddress, wallet1.currentAddress(KeyChain.KeyPurpose.RECEIVE_FUNDS)); }
/** * function that updates debit/credit/balance/price in fiat and Transaction History table * * @param services */ private void updateWalletsSummary(List<WalletService> services) { Coin totalDebit = Coin.ZERO; Coin totalCredit = Coin.ZERO; Coin totalBalance = Coin.ZERO; double priceInFiat = 0.00d; String confidence = ""; // update debit/credit/balance and price in fiat List<TransactionWrapper> transactions = new ArrayList<>(); for (WalletService service : services) { try { Wallet wallet = service.getWallet(); totalBalance = totalBalance.add(wallet.getBalance()); for (Transaction trx : wallet.getTransactionsByTime()) { if (trx.getConfidence().equals(TransactionConfidence.ConfidenceType.DEAD)) continue; Coin amount = trx.getValue(wallet); if (amount.isPositive()) { totalCredit = totalCredit.add(amount); } else { totalDebit = totalDebit.add(amount); } transactions.add(new TransactionWrapper(trx, wallet, amount)); } } catch (Exception e) { logger.error("Unable to update wallet details"); } } pnlDashboardStats.setTotalBalance(MonetaryFormat.BTC.noCode().format(totalBalance).toString()); // pnlDashboardStats.setTotalDebit(MonetaryFormat.BTC.noCode().format(totalDebit).toString()); // pnlDashboardStats.setTotalCredit(MonetaryFormat.BTC.noCode().format(totalCredit).toString()); priceInFiat = Double.valueOf(MonetaryFormat.BTC.noCode().format(totalBalance).toString()); priceInFiat *= BitcoinCurrencyRateApi.get().getCurrentRateValue(); pnlDashboardStats.setPriceInFiat( String.format("%.2f", priceInFiat), "", ConfigManager.config().getSelectedCurrency()); pnlDashboardStats.setExchangeRate( ConfigManager.config().getSelectedCurrency(), String.format("%.2f", BitcoinCurrencyRateApi.get().getCurrentRateValue())); Collections.sort( transactions, new Comparator<TransactionWrapper>() { @Override public int compare(TransactionWrapper o1, TransactionWrapper o2) { return o2.getTransaction() .getUpdateTime() .compareTo(o1.getTransaction().getUpdateTime()); } }); // update Transaction History table DefaultTableModel model = (DefaultTableModel) tblTransactions.getModel(); model.setRowCount(0); for (TransactionWrapper wrapper : transactions) { Transaction transaction = wrapper.getTransaction(); if (transaction.getConfidence().getDepthInBlocks() > 6) confidence = "<html>6<sup>+</sup></html>"; else confidence = transaction.getConfidence().getDepthInBlocks() + ""; Coin amount = wrapper.getAmount(); Coin fee = transaction.getFee(); String amountString = MonetaryFormat.BTC.noCode().format(amount).toString(); String feeString = fee != null ? MonetaryFormat.BTC.noCode().format(fee).toString() : "0.00"; Address from = transaction.getInput(0).getFromAddress(); Address to = transaction .getOutput(0) .getAddressFromP2PKHScript(wrapper.getWallet().getNetworkParameters()); boolean credit = amount.isPositive(); model.addRow( new Object[] { Utils.formatTransactionDate(transaction.getUpdateTime()), from, to, credit ? "Credit" : "Debit", amountString, feeString, "", confidence }); } Coin balanceAfter = Coin.ZERO; for (int index = transactions.size() - 1; index >= 0; index--) { balanceAfter = balanceAfter.add(Coin.parseCoin((String) model.getValueAt(index, 4))); model.setValueAt(MonetaryFormat.BTC.noCode().format(balanceAfter).toString(), index, 6); } }