Search in sources :

Example 41 with Address

use of org.aion.base.type.Address in project aion by aionnetwork.

the class AbstractTxPool method updateAccPoolState.

protected void updateAccPoolState() {
    // iterate tx by account
    List<Address> clearAddr = new ArrayList<>();
    for (Entry<Address, AccountState> e : this.accountView.entrySet()) {
        AccountState as = e.getValue();
        if (as.isDirty()) {
            if (as.getMap().isEmpty()) {
                this.poolStateView.remove(e.getKey());
                clearAddr.add(e.getKey());
            } else {
                // checking AccountState given by account
                List<PoolState> psl = this.poolStateView.get(e.getKey());
                if (psl == null) {
                    psl = new LinkedList<>();
                }
                List<PoolState> newPoolState = new LinkedList<>();
                // Checking new tx has been include into old pools.
                BigInteger txNonceStart = as.getFirstNonce();
                if (txNonceStart != null) {
                    if (LOG.isTraceEnabled()) {
                        LOG.trace("AbstractTxPool.updateAccPoolState fn [{}]", txNonceStart.toString());
                    }
                    for (PoolState ps : psl) {
                        // check the previous txn status in the old PoolState
                        if (isClean(ps, as) && ps.firstNonce.equals(txNonceStart) && ps.combo == SEQUENTAILTXNCOUNT_MAX) {
                            ps.resetInFeePool();
                            newPoolState.add(ps);
                            if (LOG.isTraceEnabled()) {
                                LOG.trace("AbstractTxPool.updateAccPoolState add fn [{}]", ps.firstNonce.toString());
                            }
                            txNonceStart = txNonceStart.add(BigInteger.valueOf(SEQUENTAILTXNCOUNT_MAX));
                        } else {
                            // remove old poolState in the feeMap
                            Map<ByteArrayWrapper, TxDependList<ByteArrayWrapper>> txDp = this.feeView.get(ps.getFee());
                            if (txDp != null) {
                                if (e.getValue().getMap().get(ps.firstNonce) != null) {
                                    txDp.remove(e.getValue().getMap().get(ps.firstNonce).getKey());
                                }
                                if (LOG.isTraceEnabled()) {
                                    LOG.trace("AbstractTxPool.updateAccPoolState remove fn [{}]", ps.firstNonce.toString());
                                }
                                if (txDp.isEmpty()) {
                                    this.feeView.remove(ps.getFee());
                                }
                            }
                        }
                    }
                }
                int cnt = 0;
                BigInteger fee = BigInteger.ZERO;
                BigInteger totalFee = BigInteger.ZERO;
                for (Entry<BigInteger, SimpleEntry<ByteArrayWrapper, BigInteger>> en : as.getMap().entrySet()) {
                    if (LOG.isTraceEnabled()) {
                        LOG.trace("AbstractTxPool.updateAccPoolState mapsize[{}] nonce:[{}] cnt[{}] txNonceStart[{}]", as.getMap().size(), en.getKey().toString(), cnt, txNonceStart.toString());
                    }
                    if (en.getKey().equals(txNonceStart != null ? txNonceStart.add(BigInteger.valueOf(cnt)) : null)) {
                        if (en.getValue().getValue().compareTo(fee) > -1) {
                            fee = en.getValue().getValue();
                            totalFee = totalFee.add(fee);
                            if (++cnt == SEQUENTAILTXNCOUNT_MAX) {
                                if (LOG.isTraceEnabled()) {
                                    LOG.trace("AbstractTxPool.updateAccPoolState case1 - nonce:[{}] totalFee:[{}] cnt:[{}]", txNonceStart, totalFee.toString(), cnt);
                                }
                                newPoolState.add(new PoolState(txNonceStart, totalFee.divide(BigInteger.valueOf(cnt)), cnt));
                                txNonceStart = en.getKey().add(BigInteger.ONE);
                                totalFee = BigInteger.ZERO;
                                fee = BigInteger.ZERO;
                                cnt = 0;
                            }
                        } else {
                            if (LOG.isTraceEnabled()) {
                                LOG.trace("AbstractTxPool.updateAccPoolState case2 - nonce:[{}] totalFee:[{}] cnt:[{}]", txNonceStart, totalFee.toString(), cnt);
                            }
                            newPoolState.add(new PoolState(txNonceStart, totalFee.divide(BigInteger.valueOf(cnt)), cnt));
                            // next PoolState
                            txNonceStart = en.getKey();
                            fee = en.getValue().getValue();
                            totalFee = fee;
                            cnt = 1;
                        }
                    }
                }
                if (totalFee.signum() == 1) {
                    if (LOG.isTraceEnabled()) {
                        LOG.trace("AbstractTxPool.updateAccPoolState case3 - nonce:[{}] totalFee:[{}] cnt:[{}] bw:[{}]", txNonceStart, totalFee.toString(), cnt, e.getKey().toString());
                    }
                    newPoolState.add(new PoolState(txNonceStart, totalFee.divide(BigInteger.valueOf(cnt)), cnt));
                }
                this.poolStateView.put(e.getKey(), newPoolState);
                if (LOG.isTraceEnabled()) {
                    this.poolStateView.forEach((k, v) -> v.forEach(l -> {
                        LOG.trace("AbstractTxPool.updateAccPoolState - the first nonce of the poolState list:[{}]", l.firstNonce);
                    }));
                }
                as.sorted();
            }
        }
    }
    if (!clearAddr.isEmpty()) {
        clearAddr.forEach(addr -> {
            this.accountView.remove(addr);
            this.bestNonce.remove(addr);
        });
    }
}
Also used : AionLoggerFactory(org.aion.log.AionLoggerFactory) java.util(java.util) Logger(org.slf4j.Logger) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Address(org.aion.base.type.Address) ITransaction(org.aion.base.type.ITransaction) AtomicLong(java.util.concurrent.atomic.AtomicLong) LogEnum(org.aion.log.LogEnum) Entry(java.util.Map.Entry) ByteArrayWrapper(org.aion.base.util.ByteArrayWrapper) BigInteger(java.math.BigInteger) ByteUtils(org.spongycastle.pqc.math.linearalgebra.ByteUtils) SimpleEntry(java.util.AbstractMap.SimpleEntry) Address(org.aion.base.type.Address) SimpleEntry(java.util.AbstractMap.SimpleEntry) ByteArrayWrapper(org.aion.base.util.ByteArrayWrapper) BigInteger(java.math.BigInteger)

Example 42 with Address

use of org.aion.base.type.Address in project aion by aionnetwork.

the class AbstractTxPool method sortTxn.

protected void sortTxn() {
    Map<Address, Map<BigInteger, SimpleEntry<ByteArrayWrapper, BigInteger>>> accMap = new ConcurrentHashMap<>();
    SortedMap<Long, LinkedHashSet<ByteArrayWrapper>> timeMap = Collections.synchronizedSortedMap(new TreeMap<>());
    // Map<ITransaction, Long> updatedTx = new HashMap<>();
    this.mainMap.entrySet().parallelStream().forEach(e -> {
        TXState ts = e.getValue();
        if (ts.sorted()) {
            return;
        }
        ITransaction tx = ts.getTx();
        // Gen temp timeMap
        long timestamp = tx.getTimeStampBI().longValue() / multiplyM;
        Map<BigInteger, SimpleEntry<ByteArrayWrapper, BigInteger>> nonceMap;
        ITransaction replacedTx = null;
        synchronized (accMap) {
            if (accMap.get(tx.getFrom()) != null) {
                nonceMap = accMap.get(tx.getFrom());
            } else {
                nonceMap = Collections.synchronizedSortedMap(new TreeMap<>());
            }
            // considering refactor later
            BigInteger nonce = tx.getNonceBI();
            BigInteger nrgCharge = BigInteger.valueOf(tx.getNrgPrice()).multiply(BigInteger.valueOf(tx.getNrgConsume()));
            if (LOG.isTraceEnabled()) {
                LOG.trace("AbstractTxPool.sortTxn Put tx into nonceMap: nonce:[{}] ts:[{}] nrgCharge:[{}]", nonce, ByteUtils.toHexString(e.getKey().getData()), nrgCharge.toString());
            }
            // considering same nonce tx, only put the latest tx.
            // if (nonceMap.get(nonce) != null) {
            // try {
            // if (this.mainMap.get(nonceMap.get(nonce).getKey()).getTx().getTimeStampBI().compareTo(tx.getTimeStampBI()) < 1) {
            // replacedTx = this.mainMap.get(nonceMap.get(nonce).getKey()).getTx();
            // updatedTx.put(replacedTx, timestamp);
            // nonceMap.put(nonce, new SimpleEntry<>(e.getKey(), nrgCharge));
            // 
            // }
            // } catch (Exception ex) {
            // LOG.error( "AbsTxPool.sortTxn {} [{}]", ex.toString(), tx.toString());
            // }
            // } else {
            nonceMap.put(nonce, new SimpleEntry<>(e.getKey(), nrgCharge));
            if (LOG.isTraceEnabled()) {
                LOG.trace("AbstractTxPool.sortTxn Put tx into accMap: acc:[{}] mapsize[{}] ", tx.getFrom().toString(), nonceMap.size());
            }
            accMap.put(tx.getFrom(), nonceMap);
        }
        LinkedHashSet<ByteArrayWrapper> lhs;
        synchronized (timeMap) {
            if (timeMap.get(timestamp) != null) {
                lhs = timeMap.get(timestamp);
            } else {
                lhs = new LinkedHashSet<>();
            }
            lhs.add(e.getKey());
            if (LOG.isTraceEnabled()) {
                LOG.trace("AbstractTxPool.sortTxn Put txHash into timeMap: ts:[{}] size:[{}]", timestamp, lhs.size());
            }
            timeMap.put(timestamp, lhs);
        // if (replacedTx != null) {
        // long t = new BigInteger(replacedTx.getTimeStamp()).longValue()/multiplyM;
        // if (timeMap.get(t) != null) {
        // timeMap.get(t).remove(ByteArrayWrapper.wrap(replacedTx.getHash()));
        // }
        // }
        }
        ts.setSorted();
    });
    if (!accMap.isEmpty()) {
        timeMap.entrySet().parallelStream().forEach(e -> {
            if (this.timeView.get(e.getKey()) == null) {
                this.timeView.put(e.getKey(), e.getValue());
            } else {
                Set<ByteArrayWrapper> lhs = this.getTimeView().get(e.getKey());
                lhs.addAll(e.getValue());
                this.timeView.put(e.getKey(), (LinkedHashSet<ByteArrayWrapper>) lhs);
            }
        });
        accMap.entrySet().parallelStream().forEach(e -> {
            this.accountView.computeIfAbsent(e.getKey(), k -> new AccountState());
            this.accountView.get(e.getKey()).updateMap(e.getValue());
        });
        updateAccPoolState();
        updateFeeMap();
    }
}
Also used : Address(org.aion.base.type.Address) SimpleEntry(java.util.AbstractMap.SimpleEntry) ITransaction(org.aion.base.type.ITransaction) ByteArrayWrapper(org.aion.base.util.ByteArrayWrapper) AtomicLong(java.util.concurrent.atomic.AtomicLong) BigInteger(java.math.BigInteger) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap)

Example 43 with Address

use of org.aion.base.type.Address in project aion by aionnetwork.

the class TxnPoolTest method feemapTest.

@Test
public void feemapTest() {
    Properties config = new Properties();
    config.put("txn-timeout", "10");
    TxPoolA0<ITransaction> tp = new TxPoolA0<>(config);
    List<ITransaction> txnl = new ArrayList<>();
    int cnt = 100;
    byte[] nonce = new byte[Long.BYTES];
    for (int i = 0; i < cnt; i++) {
        nonce[Long.BYTES - 1] = 1;
        Address addr = Address.wrap(key2.get(i).getAddress());
        ITransaction txn = new AionTransaction(nonce, addr, Address.wrap("0000000000000000000000000000000000000000000000000000000000000001"), ByteUtils.fromHexString("1"), ByteUtils.fromHexString("1"), 10000L, 1L);
        ((AionTransaction) txn).sign(key.get(0));
        txn.setNrgConsume(i + 1);
        txnl.add(txn);
    }
    tp.add(txnl);
    assertTrue(tp.size() == cnt);
    // sort the inserted txs
    tp.snapshot();
    List<BigInteger> nl = tp.getFeeList();
    long val = 100;
    for (int i = 0; i < cnt; i++) {
        assertTrue(nl.get(i).compareTo(BigInteger.valueOf(val--)) == 0);
    }
}
Also used : Address(org.aion.base.type.Address) ITransaction(org.aion.base.type.ITransaction) AionTransaction(org.aion.zero.types.AionTransaction) TxPoolA0(org.aion.txpool.zero.TxPoolA0) BigInteger(java.math.BigInteger) Test(org.junit.Test)

Example 44 with Address

use of org.aion.base.type.Address in project aion by aionnetwork.

the class TxnPoolTest method benchmarkSnapshot.

@Test
public /* 100K new transactions in pool around 1200ms (cold-call)
     */
void benchmarkSnapshot() {
    Properties config = new Properties();
    config.put("txn-timeout", "100");
    TxPoolA0<ITransaction> tp = new TxPoolA0<>(config);
    List<ITransaction> txnl = new ArrayList<>();
    int cnt = 10000;
    for (ECKey aKey1 : key) {
        Address acc = Address.wrap(aKey1.getAddress());
        for (int i = 0; i < cnt; i++) {
            ITransaction txn = new AionTransaction(BigInteger.valueOf(i).toByteArray(), acc, Address.wrap("0000000000000000000000000000000000000000000000000000000000000001"), ByteUtils.fromHexString("1"), ByteUtils.fromHexString("1"), 10000L, 1L);
            ((AionTransaction) txn).sign(aKey1);
            txn.setNrgConsume(100L);
            txnl.add(txn);
        }
    }
    tp.add(txnl);
    assertTrue(tp.size() == cnt * key.size());
    // sort the inserted txs
    long start = System.currentTimeMillis();
    tp.snapshot();
    System.out.println("time spent: " + (System.currentTimeMillis() - start) + " ms.");
    for (ECKey aKey : key) {
        List<BigInteger> nl = tp.getNonceList(Address.wrap(aKey.getAddress()));
        for (int i = 0; i < cnt; i++) {
            assertTrue(nl.get(i).equals(BigInteger.valueOf(i)));
        }
    }
}
Also used : Address(org.aion.base.type.Address) ITransaction(org.aion.base.type.ITransaction) ECKey(org.aion.crypto.ECKey) AionTransaction(org.aion.zero.types.AionTransaction) TxPoolA0(org.aion.txpool.zero.TxPoolA0) BigInteger(java.math.BigInteger) Test(org.junit.Test)

Example 45 with Address

use of org.aion.base.type.Address in project aion by aionnetwork.

the class TxnPoolTest method benchmarkSnapshot3.

@Test
public /* 1M new transactions with 10000 accounts (100 txs per account)in pool snapshot around 10s (cold-call)
       gen new txns 55s (spent a lot of time to sign tx)
       put txns into pool 2.5s
       snapshot txn 5s
     */
void benchmarkSnapshot3() {
    Properties config = new Properties();
    config.put("txn-timeout", "100");
    TxPoolA0<ITransaction> tp = new TxPoolA0<>(config);
    List<ITransaction> txnl = new ArrayList<>();
    int cnt = 100;
    System.out.println("Gen new transactions --");
    long start = System.currentTimeMillis();
    for (ECKey aKey21 : key2) {
        Address acc = Address.wrap(aKey21.getAddress());
        for (int i = 0; i < cnt; i++) {
            ITransaction txn = new AionTransaction(BigInteger.valueOf(i).toByteArray(), acc, Address.wrap("0000000000000000000000000000000000000000000000000000000000000001"), ByteUtils.fromHexString("1"), ByteUtils.fromHexString("1"), 10000L, 1L);
            ((AionTransaction) txn).sign(aKey21);
            txn.setNrgConsume(100L);
            txnl.add(txn);
        }
    }
    System.out.println("time spent: " + (System.currentTimeMillis() - start) + " ms.");
    System.out.println("Adding transactions into pool--");
    start = System.currentTimeMillis();
    tp.add(txnl);
    System.out.println("time spent: " + (System.currentTimeMillis() - start) + " ms.");
    assertTrue(tp.size() == cnt * key2.size());
    // sort the inserted txs
    System.out.println("Snapshoting --");
    start = System.currentTimeMillis();
    tp.snapshot();
    System.out.println("time spent: " + (System.currentTimeMillis() - start) + " ms.");
    for (ECKey aKey2 : key2) {
        List<BigInteger> nl = tp.getNonceList(Address.wrap(aKey2.getAddress()));
        for (int i = 0; i < cnt; i++) {
            assertTrue(nl.get(i).equals(BigInteger.valueOf(i)));
        }
    }
}
Also used : Address(org.aion.base.type.Address) ITransaction(org.aion.base.type.ITransaction) ECKey(org.aion.crypto.ECKey) AionTransaction(org.aion.zero.types.AionTransaction) TxPoolA0(org.aion.txpool.zero.TxPoolA0) BigInteger(java.math.BigInteger) Test(org.junit.Test)

Aggregations

Address (org.aion.base.type.Address)61 Test (org.junit.Test)34 BigInteger (java.math.BigInteger)29 AionTransaction (org.aion.zero.types.AionTransaction)23 ITransaction (org.aion.base.type.ITransaction)14 ECKey (org.aion.crypto.ECKey)13 DataWord (org.aion.mcf.vm.types.DataWord)11 AionRepositoryImpl (org.aion.zero.impl.db.AionRepositoryImpl)10 TxPoolA0 (org.aion.txpool.zero.TxPoolA0)9 IRepositoryCache (org.aion.base.db.IRepositoryCache)8 HashMap (java.util.HashMap)6 ByteArrayWrapper (org.aion.base.util.ByteArrayWrapper)5 ByteUtil.toHexString (org.aion.base.util.ByteUtil.toHexString)5 AccountState (org.aion.mcf.core.AccountState)5 AionBlock (org.aion.zero.impl.types.AionBlock)5 ArrayList (java.util.ArrayList)4 ImportResult (org.aion.mcf.core.ImportResult)4 IByteArrayKeyValueDatabase (org.aion.base.db.IByteArrayKeyValueDatabase)3 IRepository (org.aion.base.db.IRepository)3 AionContractDetailsImpl (org.aion.zero.db.AionContractDetailsImpl)3