Search in sources :

Example 1 with PooledTransaction

use of org.aion.base.PooledTransaction in project aion by aionnetwork.

the class AionPendingStateImpl method addPendingTransactions.

/**
 * Tries to add the given transactions to the PendingState
 *
 * @param transactions, the list of AionTransactions to be added
 * @return a list of TxResponses of the same size as the input param transactions The entries in
 *     the returned list of responses correspond one-to-one with the input txs
 */
private List<TxResponse> addPendingTransactions(List<AionTransaction> transactions) {
    List<AionTransaction> newPending = new ArrayList<>();
    List<AionTransaction> newLargeNonceTx = new ArrayList<>();
    List<TxResponse> txResponses = new ArrayList<>();
    int fetchLimit = calculateTxFetchNumberLimit();
    for (AionTransaction tx : transactions) {
        TxResponse response;
        if (pendingTxCache.isInCache(tx.getSenderAddress(), tx.getNonceBI())) {
            response = TxResponse.ALREADY_CACHED;
        } else {
            BigInteger bestPendingStateNonce = bestPendingStateNonce(tx.getSenderAddress());
            int cmp = tx.getNonceBI().compareTo(bestPendingStateNonce);
            boolean isFutureNonce = (cmp > 0);
            boolean isBestPendingNonce = (cmp == 0);
            boolean isSealed = (tx.getNonceBI().compareTo(bestRepoNonce(tx.getSenderAddress())) < 0);
            if (isFutureNonce) {
                response = processTxToCachePool(tx, false, newLargeNonceTx);
            } else if (isBestPendingNonce) {
                if (txPool.isFull()) {
                    response = processTxToCachePool(tx, true, newLargeNonceTx);
                } else {
                    response = processTxToTxPool(tx, fetchLimit, newPending);
                }
            } else if (isSealed) {
                response = TxResponse.ALREADY_SEALED;
            } else {
                // This case happens when this tx was received before, but never sealed,
                // typically because of low energy
                TxResponse implResponse = addPendingTransactionInner(tx);
                if (implResponse.equals(TxResponse.REPAID)) {
                    newPending.add(tx);
                    response = TxResponse.REPAID;
                    addPendingTxToBackupDatabase(tx);
                    PooledTransaction ptx = txPool.getDroppedPoolTx();
                    if (ptx != null) {
                        fireDroppedTx(ptx.tx, TxResponse.REPAYTX_LOWPRICE.getMessage());
                    }
                } else {
                    response = implResponse;
                }
            }
        }
        txResponses.add(response);
        LOGGER_TX.debug("add tx [{}], result:[{}]", tx, response.getMessage());
    }
    LOGGER_TX.info("Wire transaction list added: total: {}, newPending: {}, cached: {}, txPool size: {}", transactions.size(), newPending, newLargeNonceTx.size(), txPool.size());
    executeCallback(newPending, newLargeNonceTx);
    return txResponses;
}
Also used : ArrayList(java.util.ArrayList) BigInteger(java.math.BigInteger) AionTransaction(org.aion.base.AionTransaction) PooledTransaction(org.aion.base.PooledTransaction) TxResponse(org.aion.zero.impl.types.TxResponse)

Example 2 with PooledTransaction

use of org.aion.base.PooledTransaction in project aion by aionnetwork.

the class AionPendingStateImpl method clearOutdated.

private void clearOutdated(final long blockNumber) {
    List<PooledTransaction> clearedTxFromTxPool = txPool.clearOutDateTransaction();
    for (PooledTransaction pTx : clearedTxFromTxPool) {
        removeBackupDBPendingTx(pTx.tx.getTransactionHash());
        fireTxUpdate(createDroppedReceipt(pTx.tx, "Tx was not included into last " + txPool.transactionTimeout + " seconds"), PendingTransactionState.DROPPED, currentBestBlock.get());
    }
    List<AionTransaction> clearedTxFromCache = pendingTxCache.pollRemovedTransactionForPoolBackup();
    for (AionTransaction tx : clearedTxFromCache) {
        removeBackupDBCachedTx(tx.getTransactionHash());
        fireTxUpdate(createDroppedReceipt(tx, "Tx was not included into last " + PendingTxCacheV1.CACHE_TIMEOUT + " seconds"), PendingTransactionState.DROPPED, currentBestBlock.get());
    }
    LOGGER_TX.info("clearOutdated block#[{}] tx#[{}]", blockNumber, clearedTxFromTxPool.size() + clearedTxFromCache.size());
}
Also used : PooledTransaction(org.aion.base.PooledTransaction) AionTransaction(org.aion.base.AionTransaction)

Example 3 with PooledTransaction

use of org.aion.base.PooledTransaction in project aion by aionnetwork.

the class TxPoolV1 method remove.

/**
 * @implNote remove transactions into the pool.
 * @param tx pool transactions
 * @return the transactions has been removed from the pool.
 */
public List<PooledTransaction> remove(List<PooledTransaction> tx) {
    Objects.requireNonNull(tx);
    lock.lock();
    try {
        List<PooledTransaction> removedTx = new ArrayList<>();
        for (PooledTransaction pTx : tx) {
            ByteArrayWrapper txHash = ByteArrayWrapper.wrap(pTx.tx.getTransactionHash());
            PooledTransaction removedPoolTx = poolRemove(txHash);
            if (removedPoolTx != null) {
                removedTx.add(removedPoolTx);
            }
        }
        return removedTx;
    } finally {
        lock.unlock();
    }
}
Also used : ByteArrayWrapper(org.aion.util.types.ByteArrayWrapper) ArrayList(java.util.ArrayList) PooledTransaction(org.aion.base.PooledTransaction)

Example 4 with PooledTransaction

use of org.aion.base.PooledTransaction in project aion by aionnetwork.

the class TxPoolV1 method add.

/**
 * @implNote add transactions into the pool. If the transaction has the same account nonce and
 *     the new transaction has higher energy price. The pool will remove the old transaction and
 *     update to the new one.
 * @param list pool transactions
 * @return the transactions has been added into the pool.
 */
public List<PooledTransaction> add(List<PooledTransaction> list) {
    Objects.requireNonNull(list);
    if (list.isEmpty()) {
        return Collections.emptyList();
    }
    lock.lock();
    try {
        List<PooledTransaction> addedTransactions = new ArrayList<>();
        for (PooledTransaction poolTx : list) {
            if (poolTransactions.size() == maxPoolSize) {
                LOG_TXPOOL.warn("txPool is full. No transaction has been added!");
                return addedTransactions;
            }
            ByteArrayWrapper repayOldTx = checkRepayTransaction(poolTx.tx);
            ByteArrayWrapper poolTxHash = ByteArrayWrapper.wrap(poolTx.tx.getTransactionHash());
            if (repayOldTx != null) {
                if (repayOldTx.equals(poolTxHash)) {
                    LOG_TXPOOL.debug("skip adding the tx [{}] because it's not a valid repay transaction.", poolTx.tx);
                    continue;
                } else {
                    LOG_TXPOOL.debug("repay tx found! Remove original tx");
                    droppedPoolTx = poolRemove(repayOldTx);
                }
            }
            poolAdd(poolTxHash, poolTx);
            addedTransactions.add(poolTx);
        }
        return addedTransactions;
    } finally {
        lock.unlock();
    }
}
Also used : ByteArrayWrapper(org.aion.util.types.ByteArrayWrapper) ArrayList(java.util.ArrayList) PooledTransaction(org.aion.base.PooledTransaction)

Example 5 with PooledTransaction

use of org.aion.base.PooledTransaction in project aion by aionnetwork.

the class TxnPoolV1BenchmarkTest method benchmarkSnapshot2.

@Test
public void benchmarkSnapshot2() {
    Properties config = new Properties();
    config.put(TXPOOL_PROPERTY.PROP_TX_TIMEOUT, "100");
    config.put(TXPOOL_PROPERTY.PROP_POOL_SIZE_MAX, "10100");
    TxPoolV1 tp = new TxPoolV1(config);
    List<PooledTransaction> txnl = new ArrayList<>();
    int cnt = 1000;
    for (ECKey aKey2 : key) {
        for (int i = 0; i < cnt; i++) {
            AionTransaction txn = AionTransaction.create(aKey2, BigInteger.valueOf(i).toByteArray(), AddressUtils.wrapAddress("0000000000000000000000000000000000000000000000000000000000000001"), ByteUtils.fromHexString("1"), ByteUtils.fromHexString("1"), Constant.MIN_ENERGY_CONSUME, 1L, TransactionTypes.DEFAULT, null);
            PooledTransaction pooledTx = new PooledTransaction(txn, Constant.MIN_ENERGY_CONSUME);
            txnl.add(pooledTx);
        }
    }
    tp.add(txnl);
    Assert.assertEquals(tp.size(), cnt * key.size());
    // sort the inserted txs
    long start = System.currentTimeMillis();
    tp.snapshot();
    System.out.println("time spent: " + (System.currentTimeMillis() - start) + " ms.");
    int cnt2 = 10;
    txnl.clear();
    for (ECKey aKey1 : key) {
        for (int i = 0; i < cnt2; i++) {
            AionTransaction txn = AionTransaction.create(aKey1, BigInteger.valueOf(cnt + i).toByteArray(), AddressUtils.wrapAddress("0000000000000000000000000000000000000000000000000000000000000001"), ByteUtils.fromHexString("1"), ByteUtils.fromHexString("1"), Constant.MIN_ENERGY_CONSUME, 1L, TransactionTypes.DEFAULT, null);
            PooledTransaction pooledTx = new PooledTransaction(txn, Constant.MIN_ENERGY_CONSUME);
            txnl.add(pooledTx);
        }
    }
    tp.add(txnl);
    Assert.assertEquals(tp.size(), (cnt + cnt2) * key.size());
    start = System.currentTimeMillis();
    tp.snapshot();
    System.out.println("2nd time spent: " + (System.currentTimeMillis() - start) + " ms.");
    for (ECKey aKey : key) {
        List<BigInteger> nl = tp.getNonceList(new AionAddress(aKey.getAddress()));
        for (int i = 0; i < cnt + cnt2; i++) {
            Assert.assertEquals(nl.get(i), BigInteger.valueOf(i));
        }
    }
}
Also used : AionAddress(org.aion.types.AionAddress) ArrayList(java.util.ArrayList) BigInteger(java.math.BigInteger) PooledTransaction(org.aion.base.PooledTransaction) ECKey(org.aion.crypto.ECKey) AionTransaction(org.aion.base.AionTransaction) Properties(java.util.Properties) Test(org.junit.Test)

Aggregations

PooledTransaction (org.aion.base.PooledTransaction)55 ArrayList (java.util.ArrayList)40 Properties (java.util.Properties)40 AionTransaction (org.aion.base.AionTransaction)40 Test (org.junit.Test)40 BigInteger (java.math.BigInteger)16 AionAddress (org.aion.types.AionAddress)16 ByteArrayWrapper (org.aion.util.types.ByteArrayWrapper)11 HashMap (java.util.HashMap)5 ECKey (org.aion.crypto.ECKey)5 AionTxExecSummary (org.aion.base.AionTxExecSummary)3 List (java.util.List)2 AionTxReceipt (org.aion.base.AionTxReceipt)2 HashSet (java.util.HashSet)1 LinkedHashSet (java.util.LinkedHashSet)1 Map (java.util.Map)1 SortedMap (java.util.SortedMap)1 Stack (java.util.Stack)1 TreeMap (java.util.TreeMap)1 Block (org.aion.zero.impl.types.Block)1