@Override public void run() { try { try { List<Transaction> transactionList = new ArrayList<>(); int curTime = Convert.getEpochTime(); for (TransactionImpl transaction : nonBroadcastedTransactions.values()) { if (TransactionDb.hasTransaction(transaction.getId()) || transaction.getExpiration() < curTime) { nonBroadcastedTransactions.remove(transaction.getId()); } else if (transaction.getTimestamp() < curTime - 30) { transactionList.add(transaction); } } if (transactionList.size() > 0) { Peers.sendToSomePeers(transactionList); } } catch (Exception e) { Logger.logDebugMessage("Error in transaction re-broadcasting thread", e); } } catch (Throwable t) { Logger.logMessage("CRITICAL ERROR. PLEASE REPORT TO THE DEVELOPERS.\n" + t.toString()); t.printStackTrace(); System.exit(1); } }
@Override public boolean hasTransactionByFullHash(String fullHash) { return TransactionDb.hasTransactionByFullHash(Convert.parseHexString(fullHash)); }
@Override public boolean hasTransaction(long transactionId) { return TransactionDb.hasTransaction(transactionId); }
@Override public TransactionImpl getTransactionByFullHash(String fullHash) { return TransactionDb.findTransactionByFullHash(Convert.parseHexString(fullHash)); }
@Override public TransactionImpl getTransaction(long transactionId) { return TransactionDb.findTransaction(transactionId); }
private List<Transaction> processTransactions( List<TransactionImpl> transactions, final boolean sendToPeers) { List<Transaction> sendToPeersTransactions = new ArrayList<>(); List<Transaction> addedUnconfirmedTransactions = new ArrayList<>(); List<Transaction> addedDoubleSpendingTransactions = new ArrayList<>(); for (TransactionImpl transaction : transactions) { try { int curTime = Convert.getEpochTime(); if (transaction.getTimestamp() > curTime + 15 || transaction.getExpiration() < curTime || transaction.getDeadline() > 1440) { continue; } synchronized (BlockchainImpl.getInstance()) { Long id = transaction.getId(); if (TransactionDb.hasTransaction(id) || unconfirmedTransactions.containsKey(id) || !transaction.verify()) { continue; } if (transactionHashes.containsKey(transaction.getHash()) || unconfirmedTransactionHashes.containsKey(transaction.getHash())) { continue; } if (transaction.applyUnconfirmed()) { if (sendToPeers) { if (nonBroadcastedTransactions.containsKey(id)) { Logger.logDebugMessage( "Received back transaction " + transaction.getStringId() + " that we generated, will not forward to peers"); nonBroadcastedTransactions.remove(id); } else { sendToPeersTransactions.add(transaction); } } unconfirmedTransactions.put(id, transaction); unconfirmedTransactionHashes.put(transaction.getHash(), transaction); addedUnconfirmedTransactions.add(transaction); } else { addedDoubleSpendingTransactions.add(transaction); } } } catch (RuntimeException e) { Logger.logMessage("Error processing transaction", e); } } if (sendToPeersTransactions.size() > 0) { Peers.sendToSomePeers(sendToPeersTransactions); } if (addedUnconfirmedTransactions.size() > 0) { transactionListeners.notify( addedUnconfirmedTransactions, Event.ADDED_UNCONFIRMED_TRANSACTIONS); } if (addedDoubleSpendingTransactions.size() > 0) { transactionListeners.notify( addedDoubleSpendingTransactions, Event.ADDED_DOUBLESPENDING_TRANSACTIONS); } return addedUnconfirmedTransactions; }