use of org.aion.evtmgr.impl.evt.EventTx in project aion by aionnetwork.
the class AionPendingStateImpl method processBest.
@Override
public synchronized void processBest(AionBlock newBlock, List receipts) {
synchronized (txPool) {
if (getBestBlock() != null && !getBestBlock().isParentOf(newBlock)) {
// need to switch the state to another fork
IAionBlock commonAncestor = findCommonAncestor(getBestBlock(), newBlock);
if (LOG.isDebugEnabled()) {
LOG.debug("New best block from another fork: " + newBlock.getShortDescr() + ", old best: " + getBestBlock().getShortDescr() + ", ancestor: " + commonAncestor.getShortDescr());
}
// first return back the transactions from forked blocks
IAionBlock rollback = getBestBlock();
while (!rollback.isEqual(commonAncestor)) {
List<AionTransaction> atl = rollback.getTransactionsList();
if (!atl.isEmpty()) {
this.txPool.add(atl);
}
rollback = blockchain.getBlockByHash(rollback.getParentHash());
}
// rollback the state snapshot to the ancestor
pendingState = repository.getSnapshotTo(commonAncestor.getStateRoot()).startTracking();
// next process blocks from new fork
IAionBlock main = newBlock;
List<IAionBlock> mainFork = new ArrayList<>();
while (!main.isEqual(commonAncestor)) {
mainFork.add(main);
main = blockchain.getBlockByHash(main.getParentHash());
}
// processing blocks from ancestor to new block
for (int i = mainFork.size() - 1; i >= 0; i--) {
processBestInternal(mainFork.get(i), null);
}
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("PendingStateImpl.processBest: " + newBlock.getShortDescr());
}
processBestInternal(newBlock, receipts);
}
best = newBlock;
if (LOG.isTraceEnabled()) {
LOG.trace("PendingStateImpl.processBest: updateState");
}
updateState(best);
if (LOG.isTraceEnabled()) {
LOG.trace("PendingStateImpl.processBest: txPool.updateBlkNrgLimit");
}
txPool.updateBlkNrgLimit(best.getNrgLimit());
if (LOG.isTraceEnabled()) {
LOG.trace("PendingStateImpl.processBest: flushCachePendingTx");
}
flushCachePendingTx();
IEvent evtChange = new EventTx(EventTx.CALLBACK.PENDINGTXSTATECHANGE0);
this.evtMgr.newEvent(evtChange);
}
}
use of org.aion.evtmgr.impl.evt.EventTx in project aion by aionnetwork.
the class AionPendingStateImpl method addPendingTransactions.
@Override
public synchronized List<AionTransaction> addPendingTransactions(List<AionTransaction> transactions) {
int unknownTx = 0;
List<AionTransaction> newPending = new ArrayList<>();
// Map<Address, BigInteger> dbNonce = new HashMap<>();
for (AionTransaction tx : transactions) {
BigInteger txNonce = new BigInteger(1, tx.getNonce());
BigInteger bestNonce = bestNonce(tx.getFrom());
if (txNonce.compareTo(bestNonce) > 0) {
addToTxCache(tx);
LOG.debug("Adding transaction to cache: from = {}, nonce = {}", tx.getFrom(), txNonce);
} else if (txNonce.equals(bestNonce)) {
Map<BigInteger, AionTransaction> cache = pendingTxCache.geCacheTx(tx.getFrom());
do {
if (addNewTxIfNotExist(tx)) {
unknownTx++;
if (addPendingTransactionImpl(tx, txNonce)) {
newPending.add(tx);
} else {
break;
}
}
txNonce = txNonce.add(BigInteger.ONE);
} while (cache != null && (tx = cache.get(txNonce)) != null);
}
/* else {
// check repay tx
if (dbNonce.get(tx.getFrom()) == null) {
dbNonce.put(tx.getFrom(), this.repository.getNonce(tx.getFrom()));
}
if (dbNonce.get(tx.getFrom()).compareTo(txNonce) < 1) {
if (addNewTxIfNotExist(tx)) {
unknownTx++;
if (addPendingTransactionImpl(tx, txNonce)) {
newPending.add(tx);
}
}
}
} */
}
if (LOG.isDebugEnabled()) {
LOG.debug("Wire transaction list added: total: {}, new: {}, valid (added to pending): {} (current #of known txs: {})", transactions.size(), unknownTx, newPending, receivedTxs.size());
}
if (!newPending.isEmpty()) {
IEvent evtRecv = new EventTx(EventTx.CALLBACK.PENDINGTXRECEIVED0);
evtRecv.setFuncArgs(Collections.singletonList(newPending));
this.evtMgr.newEvent(evtRecv);
IEvent evtChange = new EventTx(EventTx.CALLBACK.PENDINGTXSTATECHANGE0);
this.evtMgr.newEvent(evtChange);
}
// Broadcast new pending transactions
AionImpl.inst().broadcastTransactions(newPending);
return newPending;
}
use of org.aion.evtmgr.impl.evt.EventTx in project aion by aionnetwork.
the class EventExecuteServiceTest method testEES.
@Test
public void testEES() {
eventExecuteService.setFilter(getFilter());
eventExecuteService.add(new EventDummy());
eventExecuteService.add(new EventTx(EventTx.CALLBACK.PENDINGTXSTATECHANGE0));
eventExecuteService.add(new EventBlock(EventBlock.CALLBACK.ONBLOCK0));
eventExecuteService.add(new EventMiner(EventMiner.CALLBACK.MININGSTARTED));
eventExecuteService.add(new EventConsensus(EventConsensus.CALLBACK.ON_SYNC_DONE));
eventExecuteService.take();
eventExecuteService.take();
eventExecuteService.take();
eventExecuteService.take();
eventExecuteService.take();
}
use of org.aion.evtmgr.impl.evt.EventTx in project aion by aionnetwork.
the class AionPendingStateImpl method fireTxUpdate.
private void fireTxUpdate(AionTxReceipt txReceipt, PendingTransactionState state, IAionBlock block) {
if (LOG.isDebugEnabled()) {
LOG.debug(String.format("PendingTransactionUpdate: (Tot: %3s) %12s : %s %8s %s [%s]", getPendingTxSize(), state, txReceipt.getTransaction().getFrom().toString().substring(0, 8), ByteUtil.byteArrayToLong(txReceipt.getTransaction().getNonce()), block.getShortDescr(), txReceipt.getError()));
}
IEvent evt = new EventTx(EventTx.CALLBACK.PENDINGTXUPDATE0);
List<Object> args = new ArrayList<>();
args.add(txReceipt);
args.add(state.getValue());
args.add(block);
evt.setFuncArgs(args);
this.evtMgr.newEvent(evt);
}
Aggregations